aboutsummaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:35 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:35 -0800
commitf721e3ac031f892af46f255a47d7f54a91317b30 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /telephony
parentbae1bc39312d5019bd9a5b8d840a529213a69a17 (diff)
downloadexternal_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.zip
external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.gz
external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'telephony')
-rw-r--r--telephony/Jamfile13
-rw-r--r--telephony/android_modem.c1870
-rw-r--r--telephony/android_modem.h137
-rw-r--r--telephony/gsm.c1220
-rw-r--r--telephony/gsm.h196
-rw-r--r--telephony/modem_driver.c148
-rw-r--r--telephony/modem_driver.h29
-rw-r--r--telephony/remote_call.c430
-rw-r--r--telephony/remote_call.h55
-rw-r--r--telephony/sim_card.c439
-rw-r--r--telephony/sim_card.h54
-rw-r--r--telephony/simulator.c195
-rw-r--r--telephony/sms.c1655
-rw-r--r--telephony/sms.h117
-rw-r--r--telephony/sysdeps.h80
-rw-r--r--telephony/sysdeps_posix.c645
-rw-r--r--telephony/sysdeps_qemu.c376
-rw-r--r--telephony/test1.c49
-rw-r--r--telephony/test2.c215
19 files changed, 0 insertions, 7923 deletions
diff --git a/telephony/Jamfile b/telephony/Jamfile
deleted file mode 100644
index 0f2b7b9..0000000
--- a/telephony/Jamfile
+++ /dev/null
@@ -1,13 +0,0 @@
-Main telephony : telephony.c ;
-
-Library sysdeps : sysdeps_posix.c ;
-Library android_modem : android_modem.c sim_card.c ;
-
-for prog in test1 test2 {
- Main $(prog) : $(prog).c ;
- LinkLibraries $(prog) : sysdeps ;
-}
-
-Main simulator : simulator.c ;
-LinkLibraries simulator : sysdeps android_modem ;
-
diff --git a/telephony/android_modem.c b/telephony/android_modem.c
deleted file mode 100644
index 79e93b2..0000000
--- a/telephony/android_modem.c
+++ /dev/null
@@ -1,1870 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/android.h"
-#include "android_modem.h"
-#include "android/utils/debug.h"
-#include "android/utils/timezone.h"
-#include "android/utils/system.h"
-#include "sim_card.h"
-#include "sysdeps.h"
-#include <memory.h>
-#include <stdarg.h>
-#include <time.h>
-#include <assert.h>
-#include <stdio.h>
-#include "sms.h"
-#include "remote_call.h"
-
-#define DEBUG 1
-
-#if 1
-# define D_ACTIVE VERBOSE_CHECK(modem)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if 1
-# define R_ACTIVE VERBOSE_CHECK(radio)
-#else
-# define R_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(...) do { if (D_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-# define R(...) do { if (R_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-#else
-# define D(...) ((void)0)
-# define R(...) ((void)0)
-#endif
-
-#define CALL_DELAY_DIAL 1000
-#define CALL_DELAY_ALERT 1000
-
-/* the Android GSM stack checks that the operator's name has changed
- * when roaming is on. If not, it will not update the Roaming status icon
- *
- * this means that we need to emulate two distinct operators:
- * - the first one for the 'home' registration state, must also correspond
- * to the emulated user's IMEI
- *
- * - the second one for the 'roaming' registration state, must have a
- * different name and MCC/MNC
- */
-
-#define OPERATOR_HOME_INDEX 0
-#define OPERATOR_HOME_MCC 310
-#define OPERATOR_HOME_MNC 260
-#define OPERATOR_HOME_NAME "Android"
-#define OPERATOR_HOME_MCCMNC STRINGIFY(OPERATOR_HOME_MCC) \
- STRINGIFY(OPERATOR_HOME_MNC)
-
-#define OPERATOR_ROAMING_INDEX 1
-#define OPERATOR_ROAMING_MCC 310
-#define OPERATOR_ROAMING_MNC 295
-#define OPERATOR_ROAMING_NAME "TelKila"
-#define OPERATOR_ROAMING_MCCMNC STRINGIFY(OPERATOR_ROAMING_MCC) \
- STRINGIFY(OPERATOR_ROAMING_MNC)
-
-#if DEBUG
-static const char* quote( const char* line )
-{
- static char temp[1024];
- const char* hexdigits = "0123456789abcdef";
- char* p = temp;
- int c;
-
- while ((c = *line++) != 0) {
- c &= 255;
- if (c >= 32 && c < 127) {
- *p++ = c;
- }
- else if (c == '\r') {
- memcpy( p, "<CR>", 4 );
- p += 4;
- }
- else if (c == '\n') {
- memcpy( p, "<LF>", 4 );strcat( p, "<LF>" );
- p += 4;
- }
- else {
- p[0] = '\\';
- p[1] = 'x';
- p[2] = hexdigits[ (c) >> 4 ];
- p[3] = hexdigits[ (c) & 15 ];
- p += 4;
- }
- }
- *p = 0;
- return temp;
-}
-#endif
-
-extern AGprsNetworkType
-android_parse_network_type( const char* speed )
-{
- const struct { const char* name; AGprsNetworkType type; } types[] = {
- { "gprs", A_GPRS_NETWORK_GPRS },
- { "edge", A_GPRS_NETWORK_EDGE },
- { "umts", A_GPRS_NETWORK_UMTS },
- { "hsdpa", A_GPRS_NETWORK_UMTS }, /* not handled yet by Android GSM framework */
- { "full", A_GPRS_NETWORK_UMTS },
- { NULL, 0 }
- };
- int nn;
-
- for (nn = 0; types[nn].name; nn++) {
- if ( !strcmp(speed, types[nn].name) )
- return types[nn].type;
- }
- /* not found, be conservative */
- return A_GPRS_NETWORK_GPRS;
-}
-
-/* 'mode' for +CREG/+CGREG commands */
-typedef enum {
- A_REGISTRATION_UNSOL_DISABLED = 0,
- A_REGISTRATION_UNSOL_ENABLED = 1,
- A_REGISTRATION_UNSOL_ENABLED_FULL = 2
-} ARegistrationUnsolMode;
-
-/* Operator selection mode, see +COPS commands */
-typedef enum {
- A_SELECTION_AUTOMATIC,
- A_SELECTION_MANUAL,
- A_SELECTION_DEREGISTRATION,
- A_SELECTION_SET_FORMAT,
- A_SELECTION_MANUAL_AUTOMATIC
-} AOperatorSelection;
-
-/* Operator status, see +COPS commands */
-typedef enum {
- A_STATUS_UNKNOWN = 0,
- A_STATUS_AVAILABLE,
- A_STATUS_CURRENT,
- A_STATUS_DENIED
-} AOperatorStatus;
-
-typedef struct {
- AOperatorStatus status;
- char name[3][16];
-} AOperatorRec, *AOperator;
-
-typedef struct AVoiceCallRec {
- ACallRec call;
- SysTimer timer;
- AModem modem;
- char is_remote;
-} AVoiceCallRec, *AVoiceCall;
-
-#define MAX_OPERATORS 4
-
-typedef enum {
- A_DATA_IP = 0,
- A_DATA_PPP
-} ADataType;
-
-#define A_DATA_APN_SIZE 32
-
-typedef struct {
- int id;
- int active;
- ADataType type;
- char apn[ A_DATA_APN_SIZE ];
-
-} ADataContextRec, *ADataContext;
-
-/* the spec says that there can only be a max of 4 contexts */
-#define MAX_DATA_CONTEXTS 4
-#define MAX_CALLS 4
-
-#define A_MODEM_SELF_SIZE 3
-
-typedef struct AModemRec_
-{
- /* Radio state */
- ARadioState radio_state;
- int area_code;
- int cell_id;
- int base_port;
-
- /* SMS */
- int wait_sms;
-
- /* SIM card */
- ASimCard sim;
-
- /* voice and data network registration */
- ARegistrationUnsolMode voice_mode;
- ARegistrationState voice_state;
- ARegistrationUnsolMode data_mode;
- ARegistrationState data_state;
- AGprsNetworkType data_network;
-
- /* operator names */
- AOperatorSelection oper_selection_mode;
- ANameIndex oper_name_index;
- int oper_index;
- int oper_count;
- AOperatorRec operators[ MAX_OPERATORS ];
-
- /* data connection contexts */
- ADataContextRec data_contexts[ MAX_DATA_CONTEXTS ];
-
- /* active calls */
- AVoiceCallRec calls[ MAX_CALLS ];
- int call_count;
-
- /* unsolicited callback */ /* XXX: TODO: use this */
- AModemUnsolFunc unsol_func;
- void* unsol_opaque;
-
- SmsReceiver sms_receiver;
-
- int out_size;
- char out_buff[1024];
-
-} AModemRec;
-
-
-static void
-amodem_unsol( AModem modem, const char* format, ... )
-{
- if (modem->unsol_func) {
- va_list args;
- va_start(args, format);
- vsnprintf( modem->out_buff, sizeof(modem->out_buff), format, args );
- va_end(args);
-
- modem->unsol_func( modem->unsol_opaque, modem->out_buff );
- }
-}
-
-void
-amodem_receive_sms( AModem modem, SmsPDU sms )
-{
-#define SMS_UNSOL_HEADER "+CMT: 0\r\n"
-
- if (modem->unsol_func) {
- int len, max;
- char* p;
-
- strcpy( modem->out_buff, SMS_UNSOL_HEADER );
- p = modem->out_buff + (sizeof(SMS_UNSOL_HEADER)-1);
- max = sizeof(modem->out_buff) - 3 - (sizeof(SMS_UNSOL_HEADER)-1);
- len = smspdu_to_hex( sms, p, max );
- if (len > max) /* too long */
- return;
- p[len] = '\r';
- p[len+1] = '\n';
- p[len+2] = 0;
-
- R( "SMS>> %s\n", p );
-
- modem->unsol_func( modem->unsol_opaque, modem->out_buff );
- }
-}
-
-static const char*
-amodem_printf( AModem modem, const char* format, ... )
-{
- va_list args;
- va_start(args, format);
- vsnprintf( modem->out_buff, sizeof(modem->out_buff), format, args );
- va_end(args);
-
- return modem->out_buff;
-}
-
-static void
-amodem_begin_line( AModem modem )
-{
- modem->out_size = 0;
-}
-
-static void
-amodem_add_line( AModem modem, const char* format, ... )
-{
- va_list args;
- va_start(args, format);
- modem->out_size += vsnprintf( modem->out_buff + modem->out_size,
- sizeof(modem->out_buff) - modem->out_size,
- format, args );
- va_end(args);
-}
-
-static const char*
-amodem_end_line( AModem modem )
-{
- modem->out_buff[ modem->out_size ] = 0;
- return modem->out_buff;
-}
-
-static void
-amodem_reset( AModem modem )
-{
- modem->radio_state = A_RADIO_STATE_OFF;
- modem->wait_sms = 0;
-
- modem->oper_name_index = 2;
- modem->oper_selection_mode = A_SELECTION_AUTOMATIC;
- modem->oper_index = 0;
- modem->oper_count = 2;
-
- modem->area_code = -1;
- modem->cell_id = -1;
-
- strcpy( modem->operators[0].name[0], OPERATOR_HOME_NAME );
- strcpy( modem->operators[0].name[1], OPERATOR_HOME_NAME );
- strcpy( modem->operators[0].name[2], OPERATOR_HOME_MCCMNC );
-
- modem->operators[0].status = A_STATUS_AVAILABLE;
-
- strcpy( modem->operators[1].name[0], OPERATOR_ROAMING_NAME );
- strcpy( modem->operators[1].name[1], OPERATOR_ROAMING_NAME );
- strcpy( modem->operators[1].name[2], OPERATOR_ROAMING_MCCMNC );
-
- modem->operators[1].status = A_STATUS_AVAILABLE;
-
- modem->voice_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- modem->voice_state = A_REGISTRATION_HOME;
- modem->data_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- modem->data_state = A_REGISTRATION_HOME;
- modem->data_network = A_GPRS_NETWORK_UMTS;
-}
-
-static AModemRec _android_modem[1];
-
-AModem
-amodem_create( int base_port, AModemUnsolFunc unsol_func, void* unsol_opaque )
-{
- AModem modem = _android_modem;
-
- amodem_reset( modem );
- modem->base_port = base_port;
- modem->unsol_func = unsol_func;
- modem->unsol_opaque = unsol_opaque;
-
- modem->sim = asimcard_create();
-
- return modem;
-}
-
-void
-amodem_destroy( AModem modem )
-{
- asimcard_destroy( modem->sim );
- modem->sim = NULL;
-}
-
-
-static int
-amodem_has_network( AModem modem )
-{
- return !(modem->radio_state == A_RADIO_STATE_OFF ||
- modem->oper_index < 0 ||
- modem->oper_index >= modem->oper_count ||
- modem->oper_selection_mode == A_SELECTION_DEREGISTRATION );
-}
-
-
-ARadioState
-amodem_get_radio_state( AModem modem )
-{
- return modem->radio_state;
-}
-
-void
-amodem_set_radio_state( AModem modem, ARadioState state )
-{
- modem->radio_state = state;
-}
-
-ASimCard
-amodem_get_sim( AModem modem )
-{
- return modem->sim;
-}
-
-ARegistrationState
-amodem_get_voice_registration( AModem modem )
-{
- return modem->voice_state;
-}
-
-void
-amodem_set_voice_registration( AModem modem, ARegistrationState state )
-{
- modem->voice_state = state;
-
- if (state == A_REGISTRATION_HOME)
- modem->oper_index = OPERATOR_HOME_INDEX;
- else if (state == A_REGISTRATION_ROAMING)
- modem->oper_index = OPERATOR_ROAMING_INDEX;
-
- switch (modem->voice_mode) {
- case A_REGISTRATION_UNSOL_ENABLED:
- amodem_unsol( modem, "+CREG: %d,%d\r",
- modem->voice_mode, modem->voice_state );
- break;
-
- case A_REGISTRATION_UNSOL_ENABLED_FULL:
- amodem_unsol( modem, "+CREG: %d,%d, \"%04x\", \"%04x\"\r",
- modem->voice_mode, modem->voice_state,
- modem->area_code, modem->cell_id );
- break;
- default:
- ;
- }
-}
-
-ARegistrationState
-amodem_get_data_registration( AModem modem )
-{
- return modem->data_state;
-}
-
-void
-amodem_set_data_registration( AModem modem, ARegistrationState state )
-{
- modem->data_state = state;
-
- switch (modem->data_mode) {
- case A_REGISTRATION_UNSOL_ENABLED:
- amodem_unsol( modem, "+CGREG: %d,%d\r",
- modem->data_mode, modem->data_state );
- break;
-
- case A_REGISTRATION_UNSOL_ENABLED_FULL:
- amodem_unsol( modem, "+CGREG: %d,%d,\"%04x\",\"%04x\",\"%04x\"\r",
- modem->data_mode, modem->data_state,
- modem->area_code, modem->cell_id,
- modem->data_network );
- break;
-
- default:
- ;
- }
-}
-
-void
-amodem_set_data_network_type( AModem modem, AGprsNetworkType type )
-{
- modem->data_network = type;
- amodem_set_data_registration( modem, modem->data_state );
-}
-
-int
-amodem_get_operator_name ( AModem modem, ANameIndex index, char* buffer, int buffer_size )
-{
- AOperator oper;
- int len;
-
- if ( (unsigned)modem->oper_index >= (unsigned)modem->oper_count ||
- (unsigned)index > 2 )
- return 0;
-
- oper = modem->operators + modem->oper_index;
- len = strlen(oper->name[index]) + 1;
-
- if (buffer_size > len)
- buffer_size = len;
-
- if (buffer_size > 0) {
- memcpy( buffer, oper->name[index], buffer_size-1 );
- buffer[buffer_size] = 0;
- }
- return len;
-}
-
-/* reset one operator name from a user-provided buffer, set buffer_size to -1 for zero-terminated strings */
-void
-amodem_set_operator_name( AModem modem, ANameIndex index, const char* buffer, int buffer_size )
-{
- AOperator oper;
- int avail;
-
- if ( (unsigned)modem->oper_index >= (unsigned)modem->oper_count ||
- (unsigned)index > 2 )
- return;
-
- oper = modem->operators + modem->oper_index;
-
- avail = sizeof(oper->name[0]);
- if (buffer_size < 0)
- buffer_size = strlen(buffer);
- if (buffer_size > avail-1)
- buffer_size = avail-1;
- memcpy( oper->name[index], buffer, buffer_size );
- oper->name[index][buffer_size] = 0;
-}
-
-/** CALLS
- **/
-int
-amodem_get_call_count( AModem modem )
-{
- return modem->call_count;
-}
-
-ACall
-amodem_get_call( AModem modem, int index )
-{
- if ((unsigned)index >= (unsigned)modem->call_count)
- return NULL;
-
- return &modem->calls[index].call;
-}
-
-static AVoiceCall
-amodem_alloc_call( AModem modem )
-{
- AVoiceCall call = NULL;
- int count = modem->call_count;
-
- if (count < MAX_CALLS) {
- int id;
-
- /* find a valid id for this call */
- for (id = 0; id < modem->call_count; id++) {
- int found = 0;
- int nn;
- for (nn = 0; nn < count; nn++) {
- if ( modem->calls[nn].call.id == (id+1) ) {
- found = 1;
- break;
- }
- }
- if (!found)
- break;
- }
- call = modem->calls + count;
- call->call.id = id + 1;
- call->modem = modem;
-
- modem->call_count += 1;
- }
- return call;
-}
-
-
-static void
-amodem_free_call( AModem modem, AVoiceCall call )
-{
- int nn;
-
- if (call->timer) {
- sys_timer_destroy( call->timer );
- call->timer = NULL;
- }
-
- if (call->is_remote) {
- remote_call_cancel( call->call.number, modem->base_port );
- call->is_remote = 0;
- }
-
- for (nn = 0; nn < modem->call_count; nn++) {
- if ( modem->calls + nn == call )
- break;
- }
- assert( nn < modem->call_count );
-
- memmove( modem->calls + nn,
- modem->calls + nn + 1,
- (modem->call_count - 1 - nn)*sizeof(*call) );
-
- modem->call_count -= 1;
-}
-
-
-static AVoiceCall
-amodem_find_call( AModem modem, int id )
-{
- int nn;
-
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall call = modem->calls + nn;
- if (call->call.id == id)
- return call;
- }
- return NULL;
-}
-
-static void
-amodem_send_calls_update( AModem modem )
-{
- /* despite its name, this really tells the system that the call
- * state has changed */
- amodem_unsol( modem, "RING\r" );
-}
-
-
-int
-amodem_add_inbound_call( AModem modem, const char* number )
-{
- AVoiceCall vcall = amodem_alloc_call( modem );
- ACall call = &vcall->call;
- int len;
-
- if (call == NULL)
- return -1;
-
- call->dir = A_CALL_INBOUND;
- call->state = A_CALL_INCOMING;
- call->mode = A_CALL_VOICE;
- call->multi = 0;
-
- vcall->is_remote = (remote_number_string_to_port(number) > 0);
-
- len = strlen(number);
- if (len >= sizeof(call->number))
- len = sizeof(call->number)-1;
-
- memcpy( call->number, number, len );
- call->number[len] = 0;
-
- amodem_send_calls_update( modem );
- return 0;
-}
-
-ACall
-amodem_find_call_by_number( AModem modem, const char* number )
-{
- AVoiceCall vcall = modem->calls;
- AVoiceCall vend = vcall + modem->call_count;
-
- if (!number)
- return NULL;
-
- for ( ; vcall < vend; vcall++ )
- if ( !strcmp(vcall->call.number, number) )
- return &vcall->call;
-
- return NULL;
-}
-
-
-static void
-acall_set_state( AVoiceCall call, ACallState state )
-{
- if (state != call->call.state)
- {
- if (call->is_remote)
- {
- const char* number = call->call.number;
- int port = call->modem->base_port;
-
- switch (state) {
- case A_CALL_HELD:
- remote_call_other( number, port, REMOTE_CALL_HOLD );
- break;
-
- case A_CALL_ACTIVE:
- remote_call_other( number, port, REMOTE_CALL_ACCEPT );
- break;
-
- default: ;
- }
- }
- call->call.state = state;
- }
-}
-
-
-int
-amodem_update_call( AModem modem, const char* fromNumber, ACallState state )
-{
- AVoiceCall vcall = (AVoiceCall) amodem_find_call_by_number(modem, fromNumber);
-
- if (vcall == NULL)
- return -1;
-
- acall_set_state( vcall, state );
- amodem_send_calls_update(modem);
- return 0;
-}
-
-
-int
-amodem_disconnect_call( AModem modem, const char* number )
-{
- AVoiceCall vcall = (AVoiceCall) amodem_find_call_by_number(modem, number);
-
- if (!vcall)
- return -1;
-
- amodem_free_call( modem, vcall );
- amodem_send_calls_update(modem);
- return 0;
-}
-
-/** COMMAND HANDLERS
- **/
-
-static const char*
-unknownCommand( const char* cmd, AModem modem )
-{
- modem=modem;
- fprintf(stderr, ">>> unknown command '%s'\n", cmd );
- return "ERROR: unknown command\r";
-}
-
-static const char*
-handleRadioPower( const char* cmd, AModem modem )
-{
- if ( !strcmp( cmd, "+CFUN=0" ) )
- {
- /* turn radio off */
- modem->radio_state = A_RADIO_STATE_OFF;
- }
- else if ( !strcmp( cmd, "+CFUN=1" ) )
- {
- /* turn radio on */
- modem->radio_state = A_RADIO_STATE_ON;
- }
- return NULL;
-}
-
-static const char*
-handleRadioPowerReq( const char* cmd, AModem modem )
-{
- if (modem->radio_state != A_RADIO_STATE_OFF)
- return "+CFUN=1";
- else
- return "+CFUN=0";
-}
-
-static const char*
-handleSIMStatusReq( const char* cmd, AModem modem )
-{
- const char* answer = NULL;
-
- switch (asimcard_get_status(modem->sim)) {
- case A_SIM_STATUS_ABSENT: answer = "+CPIN: ABSENT"; break;
- case A_SIM_STATUS_READY: answer = "+CPIN: READY"; break;
- case A_SIM_STATUS_NOT_READY: answer = "+CMERROR: NOT READY"; break;
- case A_SIM_STATUS_PIN: answer = "+CPIN: SIM PIN"; break;
- case A_SIM_STATUS_PUK: answer = "+CPIN: SIM PUK"; break;
- case A_SIM_STATUS_NETWORK_PERSONALIZATION: answer = "+CPIN: PH-NET PIN"; break;
- default:
- answer = "ERROR: internal error";
- }
- return answer;
-}
-
-static const char*
-handleNetworkRegistration( const char* cmd, AModem modem )
-{
- if ( !memcmp( cmd, "+CREG", 5 ) ) {
- cmd += 5;
- if (cmd[0] == '?') {
- return amodem_printf( modem, "+CREG: %d,%d, \"%04x\", \"%04x\"",
- modem->voice_mode, modem->voice_state,
- modem->area_code, modem->cell_id );
- } else if (cmd[0] == '=') {
- switch (cmd[1]) {
- case '0':
- modem->voice_mode = A_REGISTRATION_UNSOL_DISABLED;
- break;
-
- case '1':
- modem->voice_mode = A_REGISTRATION_UNSOL_ENABLED;
- break;
-
- case '2':
- modem->voice_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- break;
-
- case '?':
- return "+CREG: (0-2)";
-
- default:
- return "ERROR: BAD COMMAND";
- }
- } else {
- assert( 0 && "unreachable" );
- }
- } else if ( !memcmp( cmd, "+CGREG", 6 ) ) {
- cmd += 6;
- if (cmd[0] == '?') {\
- return amodem_printf( modem, "+CGREG: %d,%d,\"%04x\",\"%04x\",\"%04x\"",
- modem->data_mode, modem->data_state,
- modem->area_code, modem->cell_id,
- modem->data_network );
- } else if (cmd[0] == '=') {
- switch (cmd[1]) {
- case '0':
- modem->data_mode = A_REGISTRATION_UNSOL_DISABLED;
- break;
-
- case '1':
- modem->data_mode = A_REGISTRATION_UNSOL_ENABLED;
- break;
-
- case '2':
- modem->data_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- break;
-
- case '?':
- return "+CGREG: (0-2)";
-
- default:
- return "ERROR: BAD COMMAND";
- }
- } else {
- assert( 0 && "unreachable" );
- }
- }
- return NULL;
-}
-
-static const char*
-handleSetDialTone( const char* cmd, AModem modem )
-{
- /* XXX: TODO */
- return NULL;
-}
-
-static const char*
-handleDeleteSMSonSIM( const char* cmd, AModem modem )
-{
- /* XXX: TODO */
- return NULL;
-}
-
-static const char*
-handleSIM_IO( const char* cmd, AModem modem )
-{
- return asimcard_io( modem->sim, cmd );
-}
-
-
-static const char*
-handleOperatorSelection( const char* cmd, AModem modem )
-{
- assert( !memcmp( "+COPS", cmd, 5 ) );
- cmd += 5;
- if (cmd[0] == '?') { /* ask for current operator */
- AOperator oper = &modem->operators[ modem->oper_index ];
-
- if ( !amodem_has_network( modem ) )
- {
- /* this error code means "no network" */
- return amodem_printf( modem, "+CME ERROR: 30" );
- }
-
- oper = &modem->operators[ modem->oper_index ];
-
- if ( modem->oper_name_index == 2 )
- return amodem_printf( modem, "+COPS: %d,2,%s",
- modem->oper_selection_mode,
- oper->name[2] );
-
- return amodem_printf( modem, "+COPS: %d,%d,\"%s\"",
- modem->oper_selection_mode,
- modem->oper_name_index,
- oper->name[ modem->oper_name_index ] );
- }
- else if (cmd[0] == '=' && cmd[1] == '?') { /* ask for all available operators */
- const char* comma = "+COPS: ";
- int nn;
- amodem_begin_line( modem );
- for (nn = 0; nn < modem->oper_count; nn++) {
- AOperator oper = &modem->operators[nn];
- amodem_add_line( modem, "%s(%d,\"%s\",\"%s\",\"%s\")", comma,
- oper->status, oper->name[0], oper->name[1], oper->name[2] );
- comma = ", ";
- }
- return amodem_end_line( modem );
- }
- else if (cmd[0] == '=') {
- switch (cmd[1]) {
- case '0':
- modem->oper_selection_mode = A_SELECTION_AUTOMATIC;
- return NULL;
-
- case '1':
- {
- int format, nn, len, found = -1;
-
- if (cmd[2] != ',')
- goto BadCommand;
- format = cmd[3] - '0';
- if ( (unsigned)format > 2 )
- goto BadCommand;
- if (cmd[4] != ',')
- goto BadCommand;
- cmd += 5;
- len = strlen(cmd);
- if (*cmd == '"') {
- cmd++;
- len -= 2;
- }
- if (len <= 0)
- goto BadCommand;
-
- for (nn = 0; nn < modem->oper_count; nn++) {
- AOperator oper = modem->operators + nn;
- char* name = oper->name[ format ];
-
- if ( !memcpy( name, cmd, len ) && name[len] == 0 ) {
- found = nn;
- break;
- }
- }
-
- if (found < 0) {
- /* Selection failed */
- return "+CME ERROR: 529";
- } else if (modem->operators[found].status == A_STATUS_DENIED) {
- /* network not allowed */
- return "+CME ERROR: 32";
- }
- modem->oper_index = found;
-
- /* set the voice and data registration states to home or roaming
- * depending on the operator index
- */
- if (found == OPERATOR_HOME_INDEX) {
- modem->voice_state = A_REGISTRATION_HOME;
- modem->data_state = A_REGISTRATION_HOME;
- } else if (found == OPERATOR_ROAMING_INDEX) {
- modem->voice_state = A_REGISTRATION_ROAMING;
- modem->data_state = A_REGISTRATION_ROAMING;
- }
- return NULL;
- }
-
- case '2':
- modem->oper_selection_mode = A_SELECTION_DEREGISTRATION;
- return NULL;
-
- case '3':
- {
- int format;
-
- if (cmd[2] != ',')
- goto BadCommand;
-
- format = cmd[3] - '0';
- if ( (unsigned)format > 2 )
- goto BadCommand;
-
- modem->oper_name_index = format;
- return NULL;
- }
- default:
- ;
- }
- }
-BadCommand:
- return unknownCommand(cmd,modem);
-}
-
-static const char*
-handleRequestOperator( const char* cmd, AModem modem )
-{
- AOperator oper;
- cmd=cmd;
-
- if ( !amodem_has_network(modem) )
- return "+CME ERROR: 30";
-
- oper = modem->operators + modem->oper_index;
- modem->oper_name_index = 2;
- return amodem_printf( modem, "+COPS: 0,0,\"%s\"\r"
- "+COPS: 0,1,\"%s\"\r"
- "+COPS: 0,2,\"%s\"",
- oper->name[0], oper->name[1], oper->name[2] );
-}
-
-static const char*
-handleSendSMStoSIM( const char* cmd, AModem modem )
-{
- /* XXX: TODO */
- return "ERROR: unimplemented";
-}
-
-static const char*
-handleSendSMS( const char* cmd, AModem modem )
-{
- modem->wait_sms = 1;
- return "> ";
-}
-
-#if 0
-static void
-sms_address_dump( SmsAddress address, FILE* out )
-{
- int nn, len = address->len;
-
- if (address->toa == 0x91) {
- fprintf( out, "+" );
- }
- for (nn = 0; nn < len; nn += 2)
- {
- static const char dialdigits[16] = "0123456789*#,N%";
- int c = address->data[nn/2];
-
- fprintf( out, "%c", dialdigits[c & 0xf] );
- if (nn+1 >= len)
- break;
-
- fprintf( out, "%c", dialdigits[(c >> 4) & 0xf] );
- }
-}
-
-static void
-smspdu_dump( SmsPDU pdu, FILE* out )
-{
- SmsAddressRec address;
- unsigned char temp[256];
- int len;
-
- if (pdu == NULL) {
- fprintf( out, "SMS PDU is (null)\n" );
- return;
- }
-
- fprintf( out, "SMS PDU type: " );
- switch (smspdu_get_type(pdu)) {
- case SMS_PDU_DELIVER: fprintf(out, "DELIVER"); break;
- case SMS_PDU_SUBMIT: fprintf(out, "SUBMIT"); break;
- case SMS_PDU_STATUS_REPORT: fprintf(out, "STATUS_REPORT"); break;
- default: fprintf(out, "UNKNOWN");
- }
- fprintf( out, "\n sender: " );
- if (smspdu_get_sender_address(pdu, &address) < 0)
- fprintf( out, "(N/A)" );
- else
- sms_address_dump(&address, out);
- fprintf( out, "\n receiver: " );
- if (smspdu_get_receiver_address(pdu, &address) < 0)
- fprintf(out, "(N/A)");
- else
- sms_address_dump(&address, out);
- fprintf( out, "\n text: " );
- len = smspdu_get_text_message( pdu, temp, sizeof(temp)-1 );
- if (len > sizeof(temp)-1 )
- len = sizeof(temp)-1;
- fprintf( out, "'%.*s'\n", len, temp );
-}
-#endif
-
-static const char*
-handleSendSMSText( const char* cmd, AModem modem )
-{
-#if 1
- SmsAddressRec address;
- char number[16];
- int numlen;
- int len = strlen(cmd);
- SmsPDU pdu;
-
- /* get rid of trailing escape */
- if (len > 0 && cmd[len-1] == 0x1a)
- len -= 1;
-
- pdu = smspdu_create_from_hex( cmd, len );
- if (pdu == NULL) {
- D("%s: invalid SMS PDU ?: '%s'\n", __FUNCTION__, cmd);
- return "+CMS ERROR: INVALID SMS PDU";
- }
- if (smspdu_get_receiver_address(pdu, &address) < 0) {
- D("%s: could not get SMS receiver address from '%s'\n",
- __FUNCTION__, cmd);
- return "+CMS ERROR: BAD SMS RECEIVER ADDRESS";
- }
-
- do {
- int index;
-
- numlen = sms_address_to_str( &address, number, sizeof(number) );
- if (numlen > sizeof(number)-1)
- break;
-
- number[numlen] = 0;
- if ( remote_number_string_to_port( number ) < 0 )
- break;
-
- if (modem->sms_receiver == NULL) {
- modem->sms_receiver = sms_receiver_create();
- if (modem->sms_receiver == NULL) {
- D( "%s: could not create SMS receiver\n", __FUNCTION__ );
- break;
- }
- }
-
- index = sms_receiver_add_submit_pdu( modem->sms_receiver, pdu );
- if (index < 0) {
- D( "%s: could not add submit PDU\n", __FUNCTION__ );
- break;
- }
- /* the PDU is now owned by the receiver */
- pdu = NULL;
-
- if (index > 0) {
- SmsAddressRec from[1];
- char temp[10];
- SmsPDU* deliver;
- int nn;
-
- sprintf( temp, "%d", modem->base_port );
- sms_address_from_str( from, temp, strlen(temp) );
-
- deliver = sms_receiver_create_deliver( modem->sms_receiver, index, from );
- if (deliver == NULL) {
- D( "%s: could not create deliver PDUs for SMS index %d\n",
- __FUNCTION__, index );
- break;
- }
-
- for (nn = 0; deliver[nn] != NULL; nn++) {
- if ( remote_call_sms( number, modem->base_port, deliver[nn] ) < 0 ) {
- D( "%s: could not send SMS PDU to remote emulator\n",
- __FUNCTION__ );
- break;
- }
- }
-
- smspdu_free_list(deliver);
- }
-
- } while (0);
-
- if (pdu != NULL)
- smspdu_free(pdu);
-
-#elif 1
- SmsAddressRec address;
- char number[16];
- int numlen;
- int len = strlen(cmd);
- SmsPDU pdu;
-
- /* get rid of trailing escape */
- if (len > 0 && cmd[len-1] == 0x1a)
- len -= 1;
-
- pdu = smspdu_create_from_hex( cmd, len );
- if (pdu == NULL) {
- D("%s: invalid SMS PDU ?: '%s'\n", __FUNCTION__, cmd);
- return "+CMS ERROR: INVALID SMS PDU";
- }
- if (smspdu_get_receiver_address(pdu, &address) < 0) {
- D("%s: could not get SMS receiver address from '%s'\n",
- __FUNCTION__, cmd);
- return "+CMS ERROR: BAD SMS RECEIVER ADDRESS";
- }
- do {
- numlen = sms_address_to_str( &address, number, sizeof(number) );
- if (numlen > sizeof(number)-1)
- break;
-
- number[numlen] = 0;
- if ( remote_number_string_to_port( number ) < 0 )
- break;
-
- if ( remote_call_sms( number, modem->base_port, pdu ) < 0 )
- {
- D("%s: could not send SMS PDU to remote emulator\n",
- __FUNCTION__);
- return "+CMS ERROR: NO EMULATOR RECEIVER";
- }
- } while (0);
-#else
- fprintf(stderr, "SMS<< %s\n", cmd);
- SmsPDU pdu = smspdu_create_from_hex( cmd, strlen(cmd) );
- if (pdu == NULL) {
- fprintf(stderr, "invalid SMS PDU ?: '%s'\n", cmd);
- } else {
- smspdu_dump(pdu, stderr);
- }
-#endif
- return "+CMGS: 0\rOK\r";
-}
-
-static const char*
-handleChangeOrEnterPIN( const char* cmd, AModem modem )
-{
- assert( !memcmp( cmd, "+CPIN=", 6 ) );
- cmd += 6;
-
- switch (asimcard_get_status(modem->sim)) {
- case A_SIM_STATUS_ABSENT:
- return "+CME ERROR: SIM ABSENT";
-
- case A_SIM_STATUS_NOT_READY:
- return "+CME ERROR: SIM NOT READY";
-
- case A_SIM_STATUS_READY:
- /* this may be a request to change the PIN */
- {
- if (strlen(cmd) == 9 && cmd[4] == ',') {
- char pin[5];
- memcpy( pin, cmd, 4 ); pin[4] = 0;
-
- if ( !asimcard_check_pin( modem->sim, pin ) )
- return "+CME ERROR: BAD PIN";
-
- memcpy( pin, cmd+5, 4 );
- asimcard_set_pin( modem->sim, pin );
- return "+CPIN: READY";
- }
- }
- break;
-
- case A_SIM_STATUS_PIN: /* waiting for PIN */
- if ( asimcard_check_pin( modem->sim, cmd ) )
- return "+CPIN: READY";
- else
- return "+CME ERROR: BAD PIN";
-
- case A_SIM_STATUS_PUK:
- if (strlen(cmd) == 9 && cmd[4] == ',') {
- char puk[5];
- memcpy( puk, cmd, 4 );
- puk[4] = 0;
- if ( asimcard_check_puk( modem->sim, puk, cmd+5 ) )
- return "+CPIN: READY";
- else
- return "+CME ERROR: BAD PUK";
- }
- return "+CME ERROR: BAD PUK";
-
- default:
- return "+CPIN: PH-NET PIN";
- }
-
- return "+CME ERROR: BAD FORMAT";
-}
-
-
-static const char*
-handleListCurrentCalls( const char* cmd, AModem modem )
-{
- int nn;
- amodem_begin_line( modem );
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode == A_CALL_VOICE)
- amodem_add_line( modem, "+CLCC: %d,%d,%d,%d,%d,\"%s\",%d\r\n",
- call->id, call->dir, call->state, call->mode,
- call->multi, call->number, 129 );
- }
- return amodem_end_line( modem );
-}
-
-/* retrieve the current time and zone in a format suitable
- * for %CTZV: unsolicited message
- * "yy/mm/dd,hh:mm:ss(+/-)tz"
- * mm is 0-based
- * tz is in number of quarter-hours
- *
- * it seems reference-ril doesn't parse the comma (,) as anything else than a token
- * separator, so use a column (:) instead, the Java parsing code won't see a difference
- *
- */
-static const char*
-handleEndOfInit( const char* cmd, AModem modem )
-{
- time_t now = time(NULL);
- struct tm utc, local;
- long e_local, e_utc;
- long tzdiff;
- char tzname[64];
-
- tzset();
-
- utc = *gmtime( &now );
- local = *localtime( &now );
-
- e_local = local.tm_min + 60*(local.tm_hour + 24*local.tm_yday);
- e_utc = utc.tm_min + 60*(utc.tm_hour + 24*utc.tm_yday);
-
- if ( utc.tm_year < local.tm_year )
- e_local += 24*60;
- else if ( utc.tm_year > local.tm_year )
- e_utc += 24*60;
-
- tzdiff = e_local - e_utc; /* timezone offset in minutes */
-
- /* retrieve a zoneinfo-compatible name for the host timezone
- */
- {
- char* end = tzname + sizeof(tzname);
- char* p = bufprint_zoneinfo_timezone( tzname, end );
- if (p >= end)
- strcpy(tzname, "Unknown/Unknown");
-
- /* now replace every / in the timezone name by a "!"
- * that's because the code that reads the CTZV line is
- * dumb and treats a / as a field separator...
- */
- p = tzname;
- while (1) {
- p = strchr(p, '/');
- if (p == NULL)
- break;
- *p = '!';
- p += 1;
- }
- }
-
- /* as a special extension, we append the name of the host's time zone to the
- * string returned with %CTZ. the system should contain special code to detect
- * and deal with this case (since it normally relied on the operator's country code
- * which is hard to simulate on a general-purpose computer
- */
- return amodem_printf( modem, "%%CTZV: %02d/%02d/%02d:%02d:%02d:%02d%c%d:%d:%s",
- (utc.tm_year + 1900) % 100, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec,
- (tzdiff >= 0) ? '+' : '-', (tzdiff >= 0 ? tzdiff : -tzdiff) / 15,
- (local.tm_isdst > 0),
- tzname );
-}
-
-
-static const char*
-handleListPDPContexts( const char* cmd, AModem modem )
-{
- int nn;
- assert( !memcmp( cmd, "+CGACT?", 7 ) );
- amodem_begin_line( modem );
- for (nn = 0; nn < MAX_DATA_CONTEXTS; nn++) {
- ADataContext data = modem->data_contexts + nn;
- if (!data->active)
- continue;
- amodem_add_line( modem, "+CGACT: %d,%d\r", data->id, data->active );
- }
- return amodem_end_line( modem );
-}
-
-static const char*
-handleDefinePDPContext( const char* cmd, AModem modem )
-{
- assert( !memcmp( cmd, "+CGDCONT=", 9 ) );
- cmd += 9;
- if (cmd[0] == '?') {
- int nn;
- amodem_begin_line(modem);
- for (nn = 0; nn < MAX_DATA_CONTEXTS; nn++) {
- ADataContext data = modem->data_contexts + nn;
- if (!data->active)
- continue;
- amodem_add_line( modem, "+CGDCONT: %d,%s,\"%s\",,0,0\r\n",
- data->id,
- data->type == A_DATA_IP ? "IP" : "PPP",
- data->apn );
- }
- return amodem_end_line(modem);
- } else {
- /* template is +CGDCONT=<id>,"<type>","<apn>",,0,0 */
- int id = cmd[0] - '1';
- ADataType type;
- char apn[32];
- ADataContext data;
-
- if ((unsigned)id > 3)
- goto BadCommand;
-
- if ( !memcmp( cmd+1, ",\"IP\",\"", 7 ) ) {
- type = A_DATA_IP;
- cmd += 8;
- } else if ( !memcmp( cmd+1, ",\"PPP\",\"", 8 ) ) {
- type = A_DATA_PPP;
- cmd += 9;
- } else
- goto BadCommand;
-
- {
- const char* p = strchr( cmd, '"' );
- int len;
- if (p == NULL)
- goto BadCommand;
- len = (int)( p - cmd );
- if (len > sizeof(apn)-1 )
- len = sizeof(apn)-1;
- memcpy( apn, cmd, len );
- apn[len] = 0;
- }
-
- data = modem->data_contexts + id;
-
- data->id = id + 1;
- data->active = 1;
- data->type = type;
- memcpy( data->apn, apn, sizeof(data->apn) );
- }
- return NULL;
-BadCommand:
- return "ERROR: BAD COMMAND";
-}
-
-
-static const char*
-handleStartPDPContext( const char* cmd, AModem modem )
-{
- /* XXX: TODO: handle PDP start appropriately */
- /* for the moment, always return success */
-#if 0
- AVoiceCall vcall = amodem_alloc_call( modem );
- ACall call = (ACall) vcall;
- if (call == NULL) {
- return "ERROR: TOO MANY CALLS";
- }
- call->id = 1;
- call->dir = A_CALL_OUTBOUND;
- /* XXX: it would be better to delay this */
- call->state = A_CALL_ACTIVE;
- call->mode = A_CALL_DATA;
- call->multi = 0;
- strcpy( call->number, "012345" );
-#endif
- return NULL;
-}
-
-
-static void
-remote_voice_call_event( void* _vcall, int success )
-{
- AVoiceCall vcall = _vcall;
- AModem modem = vcall->modem;
-
- /* NOTE: success only means we could send the "gsm in new" command
- * to the remote emulator, nothing more */
-
- if (!success) {
- /* aargh, the remote emulator probably quitted at that point */
- amodem_free_call(modem, vcall);
- amodem_send_calls_update(modem);
- }
-}
-
-
-static void
-voice_call_event( void* _vcall )
-{
- AVoiceCall vcall = _vcall;
- ACall call = &vcall->call;
-
- switch (call->state) {
- case A_CALL_DIALING:
- call->state = A_CALL_ALERTING;
-
- if (vcall->is_remote) {
- if ( remote_call_dial( call->number,
- vcall->modem->base_port,
- remote_voice_call_event, vcall ) < 0 )
- {
- /* we could not connect, probably because the corresponding
- * emulator is not running, so simply destroy this call.
- * XXX: should we send some sort of message to indicate BAD NUMBER ? */
- /* it seems the Android code simply waits for changes in the list */
- amodem_free_call( vcall->modem, vcall );
- }
- } else {
- /* this is not a remote emulator number, so just simulate
- * a small ringing delay */
- sys_timer_set( vcall->timer, sys_time_ms() + CALL_DELAY_ALERT,
- voice_call_event, vcall );
- }
- break;
-
- case A_CALL_ALERTING:
- call->state = A_CALL_ACTIVE;
- break;
-
- default:
- assert( 0 && "unreachable event call state" );
- }
- amodem_send_calls_update(vcall->modem);
-}
-
-
-static const char*
-handleDial( const char* cmd, AModem modem )
-{
- AVoiceCall vcall = amodem_alloc_call( modem );
- ACall call = &vcall->call;
- int len;
-
- if (call == NULL)
- return "ERROR: TOO MANY CALLS";
-
- assert( cmd[0] == 'D' );
- call->dir = A_CALL_OUTBOUND;
- call->state = A_CALL_DIALING;
- call->mode = A_CALL_VOICE;
- call->multi = 0;
-
- cmd += 1;
- len = strlen(cmd);
- if (len > 0 && cmd[len-1] == ';')
- len--;
- if (len >= sizeof(call->number))
- len = sizeof(call->number)-1;
-
- memcpy( call->number, cmd, len );
- call->number[len] = 0;
-
- vcall->is_remote = (remote_number_string_to_port(call->number) > 0);
-
- vcall->timer = sys_timer_create();
- sys_timer_set( vcall->timer, sys_time_ms() + CALL_DELAY_DIAL,
- voice_call_event, vcall );
-
- return NULL;
-}
-
-
-static const char*
-handleAnswer( const char* cmd, AModem modem )
-{
- int nn;
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
-
- if (cmd[0] == 'A') {
- if (call->state == A_CALL_INCOMING) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- }
- else if (call->state == A_CALL_ACTIVE) {
- acall_set_state( vcall, A_CALL_HELD );
- }
- } else if (cmd[0] == 'H') {
- /* ATH: hangup, since user is busy */
- if (call->state == A_CALL_INCOMING) {
- amodem_free_call( modem, vcall );
- break;
- }
- }
- }
- return NULL;
-}
-
-static const char*
-handleHangup( const char* cmd, AModem modem )
-{
- if ( !memcmp(cmd, "+CHLD=", 6) ) {
- int nn;
- cmd += 6;
- switch (cmd[0]) {
- case '0': /* release all held, and set busy for waiting calls */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_HELD ||
- call->state == A_CALL_WAITING ||
- call->state == A_CALL_INCOMING) {
- amodem_free_call(modem, vcall);
- nn--;
- }
- }
- break;
-
- case '1':
- if (cmd[1] == 0) { /* release all active, accept held one */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_ACTIVE) {
- amodem_free_call(modem, vcall);
- nn--;
- }
- else if (call->state == A_CALL_HELD ||
- call->state == A_CALL_WAITING) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- }
- }
- } else { /* release specific call */
- int id = cmd[1] - '0';
- AVoiceCall vcall = amodem_find_call( modem, id );
- if (vcall != NULL)
- amodem_free_call( modem, vcall );
- }
- break;
-
- case '2':
- if (cmd[1] == 0) { /* place all active on hold, accept held or waiting one */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_ACTIVE) {
- acall_set_state( vcall, A_CALL_HELD );
- }
- else if (call->state == A_CALL_HELD ||
- call->state == A_CALL_WAITING) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- }
- }
- } else { /* place all active on hold, except a specific one */
- int id = cmd[1] - '0';
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_ACTIVE && call->id != id) {
- acall_set_state( vcall, A_CALL_HELD );
- }
- }
- }
- break;
-
- case '3': /* add a held call to the conversation */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_HELD) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- break;
- }
- }
- break;
-
- case '4': /* connect the two calls */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_HELD) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- break;
- }
- }
- break;
- }
- }
- else
- return "ERROR: BAD COMMAND";
-
- return NULL;
-}
-
-
-/* a function used to deal with a non-trivial request */
-typedef const char* (*ResponseHandler)(const char* cmd, AModem modem);
-
-static const struct {
- const char* cmd; /* command coming from libreference-ril.so, if first
- character is '!', then the rest is a prefix only */
-
- const char* answer; /* default answer, NULL if needs specific handling or
- if OK is good enough */
-
- ResponseHandler handler; /* specific handler, ignored if 'answer' is not NULL,
- NULL if OK is good enough */
-} sDefaultResponses[] =
-{
- /* see onRadioPowerOn() */
- { "%CPHS=1", NULL, NULL },
- { "%CTZV=1", NULL, NULL },
-
- /* see onSIMReady() */
- { "+CSMS=1", "+CSMS: 1, 1, 1", NULL },
- { "+CNMI=1,2,2,1,1", NULL, NULL },
-
- /* see requestRadioPower() */
- { "+CFUN=0", NULL, handleRadioPower },
- { "+CFUN=1", NULL, handleRadioPower },
-
- /* see requestOrSendPDPContextList() */
- { "+CGACT?", "", handleListPDPContexts },
-
- /* see requestOperator() */
- { "+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?", NULL, handleRequestOperator },
-
- /* see requestQueryNetworkSelectionMode() */
- { "!+COPS", NULL, handleOperatorSelection },
-
- /* see requestGetCurrentCalls() */
- { "+CLCC", NULL, handleListCurrentCalls },
-
- /* see requestWriteSmsToSim() */
- { "!+CMGW=", NULL, handleSendSMStoSIM },
-
- /* see requestHangup() */
- { "!+CHLD=", NULL, handleHangup },
-
- /* see requestSignalStrength() */
- { "+CSQ", "+CSQ: 7,99", NULL }, /* XXX: TODO: implement variable signal strength and error rates */
-
- /* see requestRegistrationState() */
- { "!+CREG", NULL, handleNetworkRegistration },
- { "!+CGREG", NULL, handleNetworkRegistration },
-
- /* see requestSendSMS() */
- { "!+CMGS=", NULL, handleSendSMS },
-
- /* see requestSetupDefaultPDP() */
- { "%CPRIM=\"GMM\",\"CONFIG MULTISLOT_CLASS=<10>\"", NULL, NULL },
- { "%DATA=2,\"UART\",1,,\"SER\",\"UART\",0", NULL, NULL },
-
- { "!+CGDCONT=", NULL, handleDefinePDPContext },
-
- { "+CGQREQ=1", NULL, NULL },
- { "+CGQMIN=1", NULL, NULL },
- { "+CGEREP=1,0", NULL, NULL },
- { "+CGACT=1,0", NULL, NULL },
- { "D*99***1#", NULL, handleStartPDPContext },
-
- /* see requestDial() */
- { "!D", NULL, handleDial }, /* the code says that success/error is ignored, the call state will
- be polled through +CLCC instead */
-
- /* see requestSMSAcknowledge() */
- { "+CNMA=1", NULL, NULL },
- { "+CNMA=2", NULL, NULL },
-
- /* see requestSIM_IO() */
- { "!+CRSM=", NULL, handleSIM_IO },
-
- /* see onRequest() */
- { "+CHLD=0", NULL, handleHangup },
- { "+CHLD=1", NULL, handleHangup },
- { "+CHLD=2", NULL, handleHangup },
- { "+CHLD=3", NULL, handleHangup },
- { "A", NULL, handleAnswer }, /* answer the call */
- { "H", NULL, handleAnswer }, /* user is busy */
- { "!+VTS=", NULL, handleSetDialTone },
- { "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL }, /* request internation subscriber identification number */
- { "+CGSN", "000000000000000", NULL }, /* request model version */
- { "+CUSD=2",NULL, NULL }, /* Cancel USSD */
- { "+COPS=0", NULL, handleOperatorSelection }, /* set network selection to automatic */
- { "!+CMGD=", NULL, handleDeleteSMSonSIM }, /* delete SMS on SIM */
- { "!+CPIN=", NULL, handleChangeOrEnterPIN },
-
- /* see getSIMStatus() */
- { "+CPIN?", NULL, handleSIMStatusReq },
- { "+CNMI?", "+CNMI: 1,2,2,1,1", NULL },
-
- /* see isRadioOn() */
- { "+CFUN?", NULL, handleRadioPowerReq },
-
- /* see initializeCallback() */
- { "E0Q0V1", NULL, NULL },
- { "S0=0", NULL, NULL },
- { "+CMEE=1", NULL, NULL },
- { "+CREG=2", NULL, handleNetworkRegistration },
- { "+CREG=1", NULL, handleNetworkRegistration },
- { "+CGREG=1", NULL, handleNetworkRegistration },
- { "+CCWA=1", NULL, NULL },
- { "+CMOD=0", NULL, NULL },
- { "+CMUT=0", NULL, NULL },
- { "+CSSN=0,1", NULL, NULL },
- { "+COLP=0", NULL, NULL },
- { "+CSCS=\"HEX\"", NULL, NULL },
- { "+CUSD=1", NULL, NULL },
- { "+CGEREP=1,0", NULL, NULL },
- { "+CMGF=0", NULL, handleEndOfInit }, /* now is a goof time to send the current tme and timezone */
- { "%CPI=3", NULL, NULL },
- { "%CSTAT=1", NULL, NULL },
-
- /* end of list */
- {NULL, NULL, NULL}
-};
-
-
-#define REPLY(str) do { const char* s = (str); R(">> %s\n", quote(s)); return s; } while (0)
-
-const char* amodem_send( AModem modem, const char* cmd )
-{
- const char* answer;
-
- if ( modem->wait_sms != 0 ) {
- modem->wait_sms = 0;
- R( "SMS<< %s\n", quote(cmd) );
- answer = handleSendSMSText( cmd, modem );
- REPLY(answer);
- }
-
- /* everything that doesn't start with 'AT' is not a command, right ? */
- if ( cmd[0] != 'A' || cmd[1] != 'T' || cmd[2] == 0 ) {
- /* R( "-- %s\n", quote(cmd) ); */
- return NULL;
- }
- R( "<< %s\n", quote(cmd) );
-
- cmd += 2;
-
- /* TODO: implement command handling */
- {
- int nn, found = 0;
-
- for (nn = 0; ; nn++) {
- const char* scmd = sDefaultResponses[nn].cmd;
-
- if (!scmd) /* end of list */
- break;
-
- if (scmd[0] == '!') { /* prefix match */
- int len = strlen(++scmd);
-
- if ( !memcmp( scmd, cmd, len ) ) {
- found = 1;
- break;
- }
- } else { /* full match */
- if ( !strcmp( scmd, cmd ) ) {
- found = 1;
- break;
- }
- }
- }
-
- if ( !found )
- {
- D( "** UNSUPPORTED COMMAND **\n" );
- REPLY( "ERROR: UNSUPPORTED" );
- }
- else
- {
- const char* answer = sDefaultResponses[nn].answer;
- ResponseHandler handler = sDefaultResponses[nn].handler;
-
- if ( answer != NULL ) {
- REPLY( amodem_printf( modem, "%s\rOK", answer ) );
- }
-
- if (handler == NULL) {
- REPLY( "OK" );
- }
-
- answer = handler( cmd, modem );
- if (answer == NULL)
- REPLY( "OK" );
-
- if ( !memcmp( answer, "> ", 2 ) ||
- !memcmp( answer, "ERROR", 5 ) ||
- !memcmp( answer, "+CME ERROR", 6 ) )
- {
- REPLY( answer );
- }
-
- if (answer != modem->out_buff)
- REPLY( amodem_printf( modem, "%s\rOK", answer ) );
-
- strcat( modem->out_buff, "\rOK" );
- REPLY( answer );
- }
- }
-}
diff --git a/telephony/android_modem.h b/telephony/android_modem.h
deleted file mode 100644
index 80d22c5..0000000
--- a/telephony/android_modem.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_modem_h_
-#define _android_modem_h_
-
-#include "sim_card.h"
-#include "sms.h"
-
-/** MODEM OBJECT
- **/
-typedef struct AModemRec_* AModem;
-
-/* a function used by the modem to send unsolicited messages to the channel controller */
-typedef void (*AModemUnsolFunc)( void* opaque, const char* message );
-
-extern AModem amodem_create( int base_port, AModemUnsolFunc unsol_func, void* unsol_opaque );
-extern void amodem_destroy( AModem modem );
-
-/* send a command to the modem */
-extern const char* amodem_send( AModem modem, const char* cmd );
-
-/* simulate the receipt on an incoming SMS message */
-extern void amodem_receive_sms( AModem modem, SmsPDU pdu );
-
-/** RADIO STATE
- **/
-typedef enum {
- A_RADIO_STATE_OFF = 0, /* Radio explictly powered off (eg CFUN=0) */
- A_RADIO_STATE_ON, /* Radio on */
-} ARadioState;
-
-extern ARadioState amodem_get_radio_state( AModem modem );
-extern void amodem_set_radio_state( AModem modem, ARadioState state );
-
-/** SIM CARD STATUS
- **/
-extern ASimCard amodem_get_sim( AModem modem );
-
-/** VOICE AND DATA NETWORK REGISTRATION
- **/
-
-/* 'stat' for +CREG/+CGREG commands */
-typedef enum {
- A_REGISTRATION_UNREGISTERED = 0,
- A_REGISTRATION_HOME = 1,
- A_REGISTRATION_SEARCHING,
- A_REGISTRATION_DENIED,
- A_REGISTRATION_UNKNOWN,
- A_REGISTRATION_ROAMING
-} ARegistrationState;
-
-typedef enum {
- A_GPRS_NETWORK_UNKNOWN = 0,
- A_GPRS_NETWORK_GPRS,
- A_GPRS_NETWORK_EDGE,
- A_GPRS_NETWORK_UMTS
-} AGprsNetworkType;
-
-extern ARegistrationState amodem_get_voice_registration( AModem modem );
-extern void amodem_set_voice_registration( AModem modem, ARegistrationState state );
-
-extern ARegistrationState amodem_get_data_registration( AModem modem );
-extern void amodem_set_data_registration( AModem modem, ARegistrationState state );
-extern void amodem_set_data_network_type( AModem modem, AGprsNetworkType type );
-
-extern AGprsNetworkType android_parse_network_type( const char* speed );
-
-
-/** OPERATOR NAMES
- **/
-typedef enum {
- A_NAME_LONG = 0,
- A_NAME_SHORT,
- A_NAME_NUMERIC,
- A_NAME_MAX /* don't remove */
-} ANameIndex;
-
-/* retrieve operator name into user-provided buffer. returns number of writes written, including terminating zero */
-extern int amodem_get_operator_name ( AModem modem, ANameIndex index, char* buffer, int buffer_size );
-
-/* reset one operator name from a user-provided buffer, set buffer_size to -1 for zero-terminated strings */
-extern void amodem_set_operator_name( AModem modem, ANameIndex index, const char* buffer, int buffer_size );
-
-/** CALL STATES
- **/
-
-typedef enum {
- A_CALL_OUTBOUND = 0,
- A_CALL_INBOUND = 1,
-} ACallDir;
-
-typedef enum {
- A_CALL_ACTIVE = 0,
- A_CALL_HELD,
- A_CALL_DIALING,
- A_CALL_ALERTING,
- A_CALL_INCOMING,
- A_CALL_WAITING
-} ACallState;
-
-typedef enum {
- A_CALL_VOICE = 0,
- A_CALL_DATA,
- A_CALL_FAX,
- A_CALL_UNKNOWN = 9
-} ACallMode;
-
-#define A_CALL_NUMBER_MAX_SIZE 16
-
-typedef struct {
- int id;
- ACallDir dir;
- ACallState state;
- ACallMode mode;
- int multi;
- char number[ A_CALL_NUMBER_MAX_SIZE+1 ];
-} ACallRec, *ACall;
-
-extern int amodem_get_call_count( AModem modem );
-extern ACall amodem_get_call( AModem modem, int index );
-extern ACall amodem_find_call_by_number( AModem modem, const char* number );
-extern int amodem_add_inbound_call( AModem modem, const char* number );
-extern int amodem_update_call( AModem modem, const char* number, ACallState state );
-extern int amodem_disconnect_call( AModem modem, const char* number );
-
-/**/
-
-#endif /* _android_modem_h_ */
diff --git a/telephony/gsm.c b/telephony/gsm.c
deleted file mode 100644
index b55578d..0000000
--- a/telephony/gsm.c
+++ /dev/null
@@ -1,1220 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "gsm.h"
-#include <stdlib.h>
-#include <string.h>
-
-/** UTILITIES
- **/
-byte_t
-gsm_int_to_bcdi( int value )
-{
- return (byte_t)((value / 10) | ((value % 10) << 4));
-}
-
-int
-gsm_int_from_bcdi( byte_t val )
-{
- int ret = 0;
-
- if ((val & 0xf0) <= 0x90)
- ret = (val >> 4);
-
- if ((val & 0x0f) <= 0x90)
- ret |= (val % 0xf)*10;
-
- return ret;
-}
-
-#if 0
-static int
-gsm_bcdi_to_ascii( cbytes_t bcd, int bcdlen, bytes_t dst )
-{
- static byte_t bcdichars[14] = "0123456789*#,N";
-
- int result = 0;
- int shift = 0;
-
- while (bcdlen > 0) {
- int c = (bcd[0] >> shift) & 0xf;
-
- if (c == 0xf && bcdlen == 1)
- break;
-
- if (c < 14) {
- if (dst) dst[result] = bcdichars[c];
- result += 1;
- }
- bcdlen --;
- shift += 4;
- if (shift == 8) {
- bcd++;
- shift = 0;
- }
- }
- return result;
-}
-#endif
-
-#if 0
-static int
-gsm_bcdi_from_ascii( cbytes_t ascii, int asciilen, bytes_t dst )
-{
- cbytes_t end = ascii + asciilen;
- int result = 0;
- int phase = 0x01;
-
- while (ascii < end) {
- int c = *ascii++;
-
- if (c == '*')
- c = 11;
- else if (c == '#')
- c = 12;
- else if (c == ',')
- c = 13;
- else if (c == 'N')
- c = 14;
- else {
- c -= '0';
- if ((unsigned)c >= 10)
- break;
- }
- phase = (phase << 4) | c;
- if (phase & 0x100) {
- if (dst) dst[result] = (byte_t) phase;
- result += 1;
- phase = 0x01;
- }
- }
- if (phase != 0x01) {
- if (dst) dst[result] = (byte_t)( phase | 0xf0 );
- result += 1;
- }
- return result;
-}
-#endif
-
-int
-gsm_hexchar_to_int( char c )
-{
- if ((unsigned)(c - '0') < 10)
- return c - '0';
- if ((unsigned)(c - 'a') < 6)
- return 10 + (c - 'a');
- if ((unsigned)(c - 'A') < 6)
- return 10 + (c - 'A');
- return -1;
-}
-
-int
-gsm_hexchar_to_int0( char c )
-{
- int ret = gsm_hexchar_to_int(c);
-
- return (ret < 0) ? 0 : ret;
-}
-
-int
-gsm_hex2_to_byte( const char* hex )
-{
- int hi = gsm_hexchar_to_int(hex[0]);
- int lo = gsm_hexchar_to_int(hex[1]);
-
- if (hi < 0 || lo < 0)
- return -1;
-
- return ( (hi << 4) | lo );
-}
-
-int
-gsm_hex4_to_short( const char* hex )
-{
- int hi = gsm_hex2_to_byte(hex);
- int lo = gsm_hex2_to_byte(hex+2);
-
- if (hi < 0 || lo < 0)
- return -1;
-
- return ((hi << 8) | lo);
-}
-
-int
-gsm_hex2_to_byte0( const char* hex )
-{
- int hi = gsm_hexchar_to_int0(hex[0]);
- int lo = gsm_hexchar_to_int0(hex[1]);
-
- return (byte_t)( (hi << 4) | lo );
-}
-
-void
-gsm_hex_from_byte( char* hex, int val )
-{
- static const char hexdigits[] = "0123456789abcdef";
-
- hex[0] = hexdigits[(val >> 4) & 15];
- hex[1] = hexdigits[val & 15];
-}
-
-void
-gsm_hex_from_short( char* hex, int val )
-{
- gsm_hex_from_byte( hex, (val >> 8) );
- gsm_hex_from_byte( hex+2, val );
-}
-
-
-
-/** HEX
- **/
-void
-gsm_hex_to_bytes0( cbytes_t hex, int hexlen, bytes_t dst )
-{
- int nn;
-
- for (nn = 0; nn < hexlen/2; nn++ ) {
- dst[nn] = (byte_t) gsm_hex2_to_byte0( (const char*)hex+2*nn );
- }
- if (hexlen & 1) {
- dst[nn] = gsm_hexchar_to_int0( hex[2*nn] ) << 4;
- }
-}
-
-int
-gsm_hex_to_bytes( cbytes_t hex, int hexlen, bytes_t dst )
-{
- int nn;
-
- if (hexlen & 1) /* must be even */
- return -1;
-
- for (nn = 0; nn < hexlen/2; nn++ ) {
- int c = gsm_hex2_to_byte( (const char*)hex+2*nn );
- if (c < 0) return -1;
- dst[nn] = (byte_t) c;
- }
- return hexlen/2;
-}
-
-void
-gsm_hex_from_bytes( char* hex, cbytes_t src, int srclen )
-{
- int nn;
-
- for (nn = 0; nn < srclen; nn++) {
- gsm_hex_from_byte( hex + 2*nn, src[nn] );
- }
-}
-
-/** ROPES
- **/
-
-void
-gsm_rope_init( GsmRope rope )
-{
- rope->data = NULL;
- rope->pos = 0;
- rope->max = 0;
- rope->error = 0;
-}
-
-void
-gsm_rope_init_alloc( GsmRope rope, int count )
-{
- rope->data = rope->data0;
- rope->pos = 0;
- rope->max = sizeof(rope->data0);
- rope->error = 0;
-
- if (count > 0) {
- rope->data = calloc( count, 1 );
- rope->max = count;
-
- if (rope->data == NULL) {
- rope->error = 1;
- rope->max = 0;
- }
- }
-}
-
-int
-gsm_rope_done( GsmRope rope )
-{
- int result = rope->error;
-
- if (rope->data && rope->data != rope->data0)
- free(rope->data);
-
- rope->data = NULL;
- rope->pos = 0;
- rope->max = 0;
- rope->error = 0;
-
- return result;
-}
-
-
-bytes_t
-gsm_rope_done_acquire( GsmRope rope, int *psize )
-{
- bytes_t result = rope->data;
-
- *psize = rope->pos;
- if (result == rope->data0) {
- result = malloc( rope->pos );
- if (result != NULL)
- memcpy( result, rope->data, rope->pos );
- }
- return result;
-}
-
-
-int
-gsm_rope_ensure( GsmRope rope, int new_count )
-{
- if (rope->data != NULL) {
- int old_max = rope->max;
- bytes_t old_data = rope->data == rope->data0 ? NULL : rope->data;
- int new_max = old_max;
- bytes_t new_data;
-
- while (new_max < new_count) {
- new_max += (new_max >> 1) + 4;
- }
- new_data = realloc( old_data, new_max );
- if (new_data == NULL) {
- rope->error = 1;
- return -1;
- }
- rope->data = new_data;
- rope->max = new_max;
- } else {
- rope->max = new_count;
- }
- return 0;
-}
-
-static int
-gsm_rope_can_grow( GsmRope rope, int count )
-{
- if (!rope->data || rope->error)
- return 0;
-
- if (rope->pos + count > rope->max)
- {
- if (rope->data == NULL)
- rope->max = rope->pos + count;
-
- else if (rope->error ||
- gsm_rope_ensure( rope, rope->pos + count ) < 0)
- return 0;
- }
- return 1;
-}
-
-void
-gsm_rope_add_c( GsmRope rope, char c )
-{
- if (gsm_rope_can_grow(rope, 1)) {
- rope->data[ rope->pos ] = (byte_t) c;
- }
- rope->pos += 1;
-}
-
-void
-gsm_rope_add( GsmRope rope, const void* buf, int buflen )
-{
- if (gsm_rope_can_grow(rope, buflen)) {
- memcpy( rope->data + rope->pos, (const char*)buf, buflen );
- }
- rope->pos += buflen;
-}
-
-void*
-gsm_rope_reserve( GsmRope rope, int count )
-{
- void* result = NULL;
-
- if (gsm_rope_can_grow(rope, count))
- {
- if (rope->data != NULL)
- result = rope->data + rope->pos;
- }
- rope->pos += count;
-
- return result;
-}
-
-/* skip a given number of Unicode characters in a utf-8 byte string */
-cbytes_t
-utf8_skip( cbytes_t utf8,
- cbytes_t utf8end,
- int count)
-{
- cbytes_t p = utf8;
- cbytes_t end = utf8end;
-
- for ( ; count > 0; count-- ) {
- int c;
-
- if (p >= end)
- break;
-
- c = *p++;
- if (c > 128) {
- while (p < end && (p[0] & 0xc0) == 0x80)
- p++;
- }
- }
- return p;
-}
-
-
-static __inline__ int
-utf8_next( cbytes_t *pp, cbytes_t end )
-{
- cbytes_t p = *pp;
- int result = -1;
-
- if (p < end) {
- int c= *p++;
- if (c >= 128) {
- if ((c & 0xe0) == 0xc0)
- c &= 0x1f;
- else if ((c & 0xf0) == 0xe0)
- c &= 0x0f;
- else
- c &= 0x07;
-
- while (p < end && (p[0] & 0xc0) == 0x80) {
- c = (c << 6) | (p[0] & 0x3f);
- p ++;
- }
- }
- result = c;
- *pp = p;
- }
- return result;
-}
-
-
-__inline__ int
-utf8_write( bytes_t utf8, int offset, int v )
-{
- int result;
-
- if (v < 128) {
- result = 1;
- if (utf8)
- utf8[offset] = (byte_t) v;
- } else if (v < 0x800) {
- result = 2;
- if (utf8) {
- utf8[offset+0] = (byte_t)( 0xc0 | (v >> 6) );
- utf8[offset+1] = (byte_t)( 0x80 | (v & 0x3f) );
- }
- } else if (v < 0x10000) {
- result = 3;
- if (utf8) {
- utf8[offset+0] = (byte_t)( 0xe0 | (v >> 12) );
- utf8[offset+1] = (byte_t)( 0x80 | ((v >> 6) & 0x3f) );
- utf8[offset+2] = (byte_t)( 0x80 | (v & 0x3f) );
- }
- } else {
- result = 4;
- if (utf8) {
- utf8[offset+0] = (byte_t)( 0xf0 | ((v >> 18) & 0x7) );
- utf8[offset+1] = (byte_t)( 0x80 | ((v >> 12) & 0x3f) );
- utf8[offset+2] = (byte_t)( 0x80 | ((v >> 6) & 0x3f) );
- utf8[offset+3] = (byte_t)( 0x80 | (v & 0x3f) );
- }
- }
- return result;
-}
-
-static __inline__ int
-ucs2_write( bytes_t ucs2, int offset, int v )
-{
- if (ucs2) {
- ucs2[offset+0] = (byte_t) (v >> 8);
- ucs2[offset+1] = (byte_t) (v);
- }
- return 2;
-}
-
-int
-utf8_check( cbytes_t p, int utf8len )
-{
- cbytes_t end = p + utf8len;
- int result = 0;
-
- if (p) {
- while (p < end) {
- int c = *p++;
- if (c >= 128) {
- int len;
- if ((c & 0xe0) == 0xc0) {
- len = 1;
- }
- else if ((c & 0xf0) == 0xe0) {
- len = 2;
- }
- else if ((c & 0xf8) == 0xf0) {
- len = 3;
- }
- else
- goto Exit; /* malformed utf-8 */
-
- if (p+len > end) /* string too short */
- goto Exit;
-
- for ( ; len > 0; len--, p++ ) {
- if ((p[0] & 0xc0) != 0x80)
- goto Exit;
- }
- }
- }
- result = 1;
- }
-Exit:
- return result;
-}
-
-/** UCS2 to UTF8
- **/
-
-/* convert a UCS2 string into a UTF8 byte string, assumes 'buf' is correctly sized */
-int
-ucs2_to_utf8( cbytes_t ucs2,
- int ucs2len,
- bytes_t buf )
-{
- int nn;
- int result = 0;
-
- for (nn = 0; nn < ucs2len; ucs2 += 2, nn++) {
- int c= (ucs2[0] << 8) | ucs2[1];
- result += utf8_write(buf, result, c);
- }
- return result;
-}
-
-/* count the number of UCS2 chars contained in a utf8 byte string */
-int
-utf8_to_ucs2( cbytes_t utf8,
- int utf8len,
- bytes_t ucs2 )
-{
- cbytes_t p = utf8;
- cbytes_t end = p + utf8len;
- int result = 0;
-
- while (p < end) {
- int c = utf8_next(&p, end);
-
- if (c < 0)
- break;
-
- result += ucs2_write(ucs2, result, c);
- }
- return result/2;
-}
-
-
-
-/** GSM ALPHABET
- **/
-
-#define GSM_7BITS_ESCAPE 0x1b
-#define GSM_7BITS_UNKNOWN 0
-
-static const unsigned short gsm7bits_to_unicode[128] = {
- '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec, 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
-0x394, '_',0x3a6,0x393,0x39b,0x3a9,0x3a0,0x3a8,0x3a3,0x398,0x39e, 0, 0xc6, 0xe6, 0xdf, 0xc9,
- ' ', '!', '"', '#', 0xa4, '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
- 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0xc4, 0xd6,0x147, 0xdc, 0xa7,
- 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0,
-};
-
-static const unsigned short gsm7bits_extend_to_unicode[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\f', 0, 0, 0, 0, 0,
- 0, 0, 0, 0, '^', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, '{', '}', 0, 0, 0, 0, 0,'\\',
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '[', '~', ']', 0,
- '|', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,0x20ac, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-
-static int
-unichar_to_gsm7( int unicode )
-{
- int nn;
- for (nn = 0; nn < 128; nn++) {
- if (gsm7bits_to_unicode[nn] == unicode) {
- return nn;
- }
- }
- return -1;
-}
-
-static int
-unichar_to_gsm7_extend( int unichar )
-{
- int nn;
- for (nn = 0; nn < 128; nn++) {
- if (gsm7bits_extend_to_unicode[nn] == unichar) {
- return nn;
- }
- }
- return -1;
-}
-
-
-/* return the number of septets needed to encode a unicode charcode */
-static int
-unichar_to_gsm7_count( int unicode )
-{
- int nn;
-
- nn = unichar_to_gsm7(unicode);
- if (nn >= 0)
- return 1;
-
- nn = unichar_to_gsm7_extend(unicode);
- if (nn >= 0)
- return 2;
-
- return 0;
-}
-
-
-cbytes_t
-utf8_skip_gsm7( cbytes_t utf8, cbytes_t utf8end, int gsm7len )
-{
- cbytes_t p = utf8;
- cbytes_t end = utf8end;
-
- while (gsm7len >0) {
- cbytes_t q = p;
- int c = utf8_next( &q, end );
- int len;
-
- if (c < 0)
- break;
-
- len = unichar_to_gsm7_count( c );
- if (len == 0) /* unknown chars are replaced by spaces */
- len = 1;
-
- if (len > gsm7len)
- break;
-
- gsm7len -= len;
- p = q;
- }
- return p;
-}
-
-
-int
-utf8_check_gsm7( cbytes_t utf8,
- int utf8len )
-{
- cbytes_t utf8end = utf8 + utf8len;
-
- while (utf8 < utf8end) {
- int c = utf8_next( &utf8, utf8end );
- if (unichar_to_gsm7_count(c) == 0)
- return 0;
- }
- return 1;
-}
-
-
-int
-utf8_from_gsm7( cbytes_t src,
- int septet_offset,
- int septet_count,
- bytes_t utf8 )
-{
- int shift = (septet_offset & 7);
- int escaped = 0;
- int result = 0;
-
- src += (septet_offset >> 3);
- for ( ; septet_count > 0; septet_count-- )
- {
- int c = (src[0] >> shift) & 0x7f;
- int v;
-
- if (shift > 1) {
- c = ((src[1] << (8-shift)) | c) & 0x7f;
- }
-
- if (escaped) {
- v = gsm7bits_extend_to_unicode[c];
- } else if (c == GSM_7BITS_ESCAPE) {
- escaped = 1;
- goto NextSeptet;
- } else {
- v = gsm7bits_to_unicode[c];
- }
-
- result += utf8_write( utf8, result, v );
-
- NextSeptet:
- shift += 7;
- if (shift >= 8) {
- shift -= 8;
- src += 1;
- }
- }
- return result;
-}
-
-
-int
-utf8_from_gsm8( cbytes_t src, int count, bytes_t utf8 )
-{
- int result = 0;
- int escaped = 0;
-
-
- for ( ; count > 0; count-- )
- {
- int c = *src++;
-
- if (c == 0xff)
- break;
-
- if (c == GSM_7BITS_ESCAPE) {
- if (escaped) { /* two escape characters => one space */
- c = 0x20;
- escaped = 0;
- } else {
- escaped = 1;
- continue;
- }
- }
- else
- {
- if (c >= 0x80) {
- c = 0x20;
- escaped = 0;
- } else if (escaped) {
- c = gsm7bits_extend_to_unicode[c];
- } else
- c = gsm7bits_to_unicode[c];
- }
-
- result += utf8_write( utf8, result, c );
- }
- return result;
-}
-
-/* convert a GSM 7-bit message into a unicode character array
- * the 'dst' array must contain at least 160 chars. the function
- * returns the number of characters decoded
- *
- * assumes the 'dst' array has at least septet_count items, returns the
- * number of unichars really written
- */
-int
-ucs2_from_gsm7( bytes_t ucs2,
- cbytes_t src,
- int septet_offset,
- int septet_count )
-{
- const unsigned char* p = src + (septet_offset >> 3);
- int shift = (septet_offset & 7);
- int escaped = 0;
- int result = 0;
-
- for ( ; septet_count > 0; septet_count-- )
- {
- unsigned val = (p[0] >> shift) & 0x7f;
-
- if (shift > 1)
- val = (val | (p[1] << (8-shift))) & 0x7f;
-
- if (escaped) {
- int c = gsm7bits_to_unicode[val];
-
- result += ucs2_write(ucs2, result, c);
- escaped = 0;
- }
- else if (val == GSM_7BITS_ESCAPE) {
- escaped = 1;
- }
- else {
- val = gsm7bits_extend_to_unicode[val];
- if (val == 0)
- val = 0x20;
-
- result += ucs2_write( ucs2, result, val );
- }
- }
- return result/2;
-}
-
-
-/* count the number of septets required to write a utf8 string */
-static int
-utf8_to_gsm7_count( cbytes_t utf8, int utf8len )
-{
- cbytes_t utf8end = utf8 + utf8len;
- int result = 0;
-
- while ( utf8 < utf8end ) {
- int len;
- int c = utf8_next( &utf8, utf8end );
-
- if (c < 0)
- break;
-
- len = unichar_to_gsm7_count(c);
- if (len == 0) /* replace non-representables with space */
- len = 1;
-
- result += len;
- }
- return result;
-}
-
-typedef struct {
- bytes_t dst;
- unsigned pad;
- int bits;
- int offset;
-} BWriterRec, *BWriter;
-
-static void
-bwriter_init( BWriter writer, bytes_t dst, int start )
-{
- int shift = start & 7;
-
- writer->dst = dst + (start >> 3);
- writer->pad = 0;
- writer->bits = shift;
- writer->offset = start;
-
- if (shift > 0) {
- writer->pad = writer->dst[0] & ~(0xFF << shift);
- }
-}
-
-static void
-bwriter_add7( BWriter writer, unsigned value )
-{
- writer->pad |= (unsigned)(value << writer->bits);
- writer->bits += 7;
- if (writer->bits >= 8) {
- writer->dst[0] = (byte_t)writer->pad;
- writer->bits -= 8;
- writer->pad >>= 8;
- writer->dst += 1;
- }
- writer->offset += 7;
-}
-
-static int
-bwriter_done( BWriter writer )
-{
- if (writer->bits > 0) {
- writer->dst[0] = (byte_t)writer->pad;
- writer->pad = 0;
- writer->bits = 0;
- writer->dst += 1;
- }
- return writer->offset;
-}
-
-/* convert a utf8 string to a gsm7 byte string - return the number of septets written */
-int
-utf8_to_gsm7( cbytes_t utf8, int utf8len, bytes_t dst, int offset )
-{
- const unsigned char* utf8end = utf8 + utf8len;
- BWriterRec writer[1];
-
- if (dst == NULL)
- return utf8_to_gsm7_count(utf8, utf8len);
-
- bwriter_init( writer, dst, offset );
- while ( utf8 < utf8end ) {
- int c = utf8_next( &utf8, utf8end );
- int nn;
-
- if (c < 0)
- break;
-
- nn = unichar_to_gsm7(c);
- if (nn >= 0) {
- bwriter_add7( writer, nn );
- continue;
- }
-
- nn = unichar_to_gsm7_extend(c);
- if (nn >= 0) {
- bwriter_add7( writer, GSM_7BITS_ESCAPE );
- bwriter_add7( writer, nn );
- continue;
- }
-
- /* unknown => replaced by space */
- bwriter_add7( writer, 0x20 );
- }
- return bwriter_done( writer );
-}
-
-
-int
-utf8_to_gsm8( cbytes_t utf8, int utf8len, bytes_t dst )
-{
- const unsigned char* utf8end = utf8 + utf8len;
- int result = 0;
-
- while ( utf8 < utf8end ) {
- int c = utf8_next( &utf8, utf8end );
- int nn;
-
- if (c < 0)
- break;
-
- nn = unichar_to_gsm7(c);
- if (nn >= 0) {
- if (dst)
- dst[result] = (byte_t)nn;
- result += 1;
- continue;
- }
-
- nn = unichar_to_gsm7_extend(c);
- if (nn >= 0) {
- if (dst) {
- dst[result+0] = (byte_t) GSM_7BITS_ESCAPE;
- dst[result+1] = (byte_t) nn;
- }
- result += 2;
- continue;
- }
-
- /* unknown => space */
- if (dst)
- dst[result] = 0x20;
- result += 1;
- }
- return result;
-}
-
-
-int
-ucs2_to_gsm7( cbytes_t ucs2, int ucs2len, bytes_t dst, int offset )
-{
- const unsigned char* ucs2end = ucs2 + ucs2len*2;
- BWriterRec writer[1];
-
- bwriter_init( writer, dst, offset );
- while ( ucs2 < ucs2end ) {
- int c = *ucs2++;
- int nn;
-
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_to_unicode[nn] == c ) {
- bwriter_add7( writer, nn );
- goto NextUnicode;
- }
- }
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_extend_to_unicode[nn] == c ) {
- bwriter_add7( writer, GSM_7BITS_ESCAPE );
- bwriter_add7( writer, nn );
- goto NextUnicode;
- }
- }
-
- /* unknown */
- bwriter_add7( writer, 0x20 );
-
- NextUnicode:
- ;
- }
- return bwriter_done( writer );
-}
-
-
-int
-ucs2_to_gsm8( cbytes_t ucs2, int ucs2len, bytes_t dst )
-{
- const unsigned char* ucs2end = ucs2 + ucs2len*2;
- bytes_t dst0 = dst;
-
- while ( ucs2 < ucs2end ) {
- int c = *ucs2++;
- int nn;
-
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_to_unicode[nn] == c ) {
- *dst++ = (byte_t)nn;
- goto NextUnicode;
- }
- }
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_extend_to_unicode[nn] == c ) {
- dst[0] = (byte_t) GSM_7BITS_ESCAPE;
- dst[1] = (byte_t) nn;
- dst += 2;
- goto NextUnicode;
- }
- }
-
- /* unknown */
- *dst++ = 0x20;
-
- NextUnicode:
- ;
- }
- return (dst - dst0);
-}
-
-int
-gsm_bcdnum_to_ascii( cbytes_t bcd, int count, bytes_t dst )
-{
- int result = 0;
- int shift = 0;
-
- while (count > 0) {
- int c = (bcd[0] >> shift) & 0xf;
-
- if (c == 15 && count == 1) /* ignore trailing 0xf */
- break;
-
- if (c >= 14)
- c = 0;
-
- if (dst) dst[result] = "0123456789*#,N"[c];
- result += 1;
-
- shift += 4;
- if (shift == 8) {
- shift = 0;
- bcd += 1;
- }
- }
- return result;
-}
-
-
-int
-gsm_bcdnum_from_ascii( cbytes_t ascii, int asciilen, bytes_t dst )
-{
- cbytes_t end = ascii + asciilen;
- int result = 0;
- int phase = 0x01;
-
- while (ascii < end) {
- int c = *ascii++;
-
- if (c == '*')
- c = 10;
- else if (c == '#')
- c = 11;
- else if (c == ',')
- c = 12;
- else if (c == 'N')
- c = 13;
- else {
- c -= '0';
- if ((unsigned)c >= 10U)
- return -1;
- }
- phase = (phase << 4) | c;
- result += 1;
- if (phase & 0x100) {
- if (dst) dst[result/2] = (byte_t) phase;
- phase = 0x01;
- }
- }
-
- if (result & 1) {
- if (dst) dst[result/2] = (byte_t)(phase | 0xf0);
- }
- return result;
-}
-
-/** ADN: Abbreviated Dialing Number
- **/
-
-#define ADN_FOOTER_SIZE 14
-#define ADN_OFFSET_NUMBER_LENGTH 0
-#define ADN_OFFSET_TON_NPI 1
-#define ADN_OFFSET_NUMBER_START 2
-#define ADN_OFFSET_NUMBER_END 11
-#define ADN_OFFSET_CAPABILITY_ID 12
-#define ADN_OFFSET_EXTENSION_ID 13
-
-/* see 10.5.1 of 3GPP 51.011 */
-static int
-sim_adn_alpha_to_utf8( cbytes_t alpha, cbytes_t end, bytes_t dst )
-{
- int result = 0;
-
- /* ignore trailing 0xff */
- while (alpha < end && end[-1] == 0xff)
- end--;
-
- if (alpha >= end)
- return 0;
-
- if (alpha[0] == 0x80) { /* UCS/2 source encoding */
- alpha += 1;
- result = ucs2_to_utf8( alpha, (end-alpha)/2, dst );
- }
- else
- {
- int is_ucs2 = 0;
- int len = 0, base = 0;
-
- if (alpha+3 <= end && alpha[0] == 0x81) {
- is_ucs2 = 1;
- len = alpha[1];
- base = alpha[2] << 7;
- alpha += 3;
- if (len > end-alpha)
- len = end-alpha;
- } else if (alpha+4 <= end && alpha[0] == 0x82) {
- is_ucs2 = 1;
- len = alpha[1];
- base = (alpha[2] << 8) | alpha[3];
- alpha += 4;
- if (len > end-alpha)
- len = end-alpha;
- }
-
- if (is_ucs2) {
- end = alpha + len;
- while (alpha < end) {
- int c = alpha[0];
- if (c >= 0x80) {
- result += utf8_write(dst, result, base + (c & 0x7f));
- alpha += 1;
- } else {
- /* GSM character set */
- int count;
- for (count = 0; alpha+count < end && alpha[count] < 128; count++)
- ;
- result += utf8_from_gsm8(alpha, count, (dst ? dst+result : NULL));
- alpha += count;
- }
- }
- }
- else {
- result = utf8_from_gsm8(alpha, end-alpha, dst);
- }
- }
- return result;
-}
-
-#if 0
-static int
-sim_adn_alpha_from_utf8( cbytes_t utf8, int utf8len, bytes_t dst )
-{
- int result = 0;
-
- if (utf8_check_gsm7(utf8, utf8len)) {
- /* GSM 7-bit compatible, encode directly as 8-bit string */
- result = utf8_to_gsm8(utf8, utf8len, dst);
- } else {
- /* otherwise, simply try UCS-2 encoding, nothing more serious at the moment */
- if (dst) {
- dst[0] = 0x80;
- }
- result = 1 + utf8_to_ucs2(utf8, utf8len, dst ? (dst+1) : NULL)*2;
- }
- return result;
-}
-#endif
-
-int
-sim_adn_record_from_bytes( SimAdnRecord rec, cbytes_t data, int len )
-{
- cbytes_t end = data + len;
- cbytes_t footer = end - ADN_FOOTER_SIZE;
- int num_len;
-
- rec->adn.alpha[0] = 0;
- rec->adn.number[0] = 0;
- rec->ext_record = 0xff;
-
- if (len < ADN_FOOTER_SIZE)
- return -1;
-
- /* alpha is optional */
- if (len > ADN_FOOTER_SIZE) {
- cbytes_t dataend = data + len - ADN_FOOTER_SIZE;
- int count = sim_adn_alpha_to_utf8(data, dataend, NULL);
-
- if (count > sizeof(rec->adn.alpha)-1) /* too long */
- return -1;
-
- sim_adn_alpha_to_utf8(data, dataend, rec->adn.alpha);
- rec->adn.alpha[count] = 0;
- }
-
- num_len = footer[ADN_OFFSET_NUMBER_LENGTH];
- if (num_len > 11)
- return -1;
-
- /* decode TON and number to ASCII, NOTE: this is lossy !! */
- {
- int ton = footer[ADN_OFFSET_TON_NPI];
- bytes_t number = (bytes_t) rec->adn.number;
- int len = sizeof(rec->adn.number)-1;
- int count;
-
- if (ton != 0x81 && ton != 0x91)
- return -1;
-
- if (ton == 0x91) {
- *number++ = '+';
- len -= 1;
- }
-
- count = gsm_bcdnum_to_ascii( footer + ADN_OFFSET_NUMBER_START,
- num_len*2, number );
- number[count] = 0;
- }
- return 0;
-}
-
-int
-sim_adn_record_to_bytes( SimAdnRecord rec, bytes_t data, int datalen )
-{
- bytes_t end = data + datalen;
- bytes_t footer = end - ADN_FOOTER_SIZE;
- int ton = 0x81;
- cbytes_t number = (cbytes_t) rec->adn.number;
-
- if (number[0] == '+') {
- ton = 0x91;
- number += 1;
- }
- footer[0] = (strlen((const char*)number)+1)/2 + 1;
- /* XXXX: TODO */
- return 0;
-}
diff --git a/telephony/gsm.h b/telephony/gsm.h
deleted file mode 100644
index f799dea..0000000
--- a/telephony/gsm.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_gsm_h
-#define _android_gsm_h
-
-/** USEFUL TYPES
- **/
-
-typedef unsigned char byte_t;
-typedef byte_t* bytes_t;
-typedef const byte_t* cbytes_t;
-
-/** BCD
- **/
-
-/* convert a 8-bit value into the corresponding nibble-bcd byte */
-extern byte_t gsm_int_to_bcdi( int value );
-
-/* convert a nibble-bcd byte into an int, invalid nibbles are silently converted to 0 */
-extern int gsm_int_from_bcdi( byte_t value );
-
-/** HEX
- **/
-
-/* try to convert a hex string into a byte string, assumes 'dst' is properly sized, and hexlen is even.
- * returns the number of bytes on exit, or -1 in case of badly formatted data */
-extern int gsm_hex_to_bytes ( cbytes_t hex, int hexlen, bytes_t dst );
-
-/* convert a hex string into a byte string, assumes 'dst' is properly sized, and hexlen is even.
- * no checks are performed */
-extern void gsm_hex_to_bytes0 ( cbytes_t hex, int hexlen, bytes_t dst );
-
-/* convert a byte string into a hex string, assumes 'hex' is properly sized */
-extern void gsm_hex_from_bytes( char* hex, cbytes_t src, int srclen );
-
-/* convert a hexchar to an int, returns -1 on error */
-extern int gsm_hexchar_to_int( char c );
-
-/* convert a hexchar to an int, returns 0 on error */
-extern int gsm_hexchar_to_int0( char c );
-
-/* convert a 2-char hex value into an int, returns -1 on error */
-extern int gsm_hex2_to_byte( const char* hex );
-
-/* convert a 2-char hex value into an int, returns 0 on error */
-extern int gsm_hex2_to_byte0( const char* hex );
-
-/* convert a 4-char hex value into an int, returns -1 on error */
-extern int gsm_hex4_to_short( const char* hex );
-
-/* convert a 4-char hex value into an int, returns 0 on error */
-extern int gsm_hex4_to_short0( const char* hex );
-
-/* write a byte to a 2-byte hex string */
-extern void gsm_hex_from_byte( char* hex, int val );
-
-extern void gsm_hex_from_short( char* hex, int val );
-
-/** UTF-8 and GSM Alphabet
- **/
-
-/* check that a given utf8 string is well-formed, returns 1 on success, 0 otherwise */
-extern int utf8_check( cbytes_t utf8, int utf8len );
-
-/* check that all characters in a given utf8 string can be encoded into the GSM alphabet.
- returns 1 if TRUE, 0 otherwise */
-extern int utf8_check_gsm7( cbytes_t utf8, int utf8len );
-
-/* try to skip enough utf8 characters to generate gsm7len GSM septets */
-extern cbytes_t utf8_skip_gsm7( cbytes_t utf8, cbytes_t utf8end, int gsm7len );
-
-/* convert a utf-8 string into a GSM septet string, assumes 'dst' is NULL or is properly sized,
- and that all characters are representable. 'offset' is the starting bit offset in 'dst'.
- non-representable characters are replaced by spaces.
- returns the number of septets, */
-extern int utf8_to_gsm7( cbytes_t utf8, int utf8len, bytes_t dst, int offset );
-
-/* convert a utf8 string into an array of 8-bit unpacked GSM septets,
- * assumes 'dst' is NULL or is properly sized, returns the number of GSM bytes */
-extern int utf8_to_gsm8( cbytes_t utf8, int utf8len, bytes_t dst );
-
-/* convert a GSM septets string into a utf-8 byte string. assumes that 'utf8' is NULL or properly
- sized. 'offset' is the starting bit offset in 'src', 'count' is the number of input septets.
- return the number of utf8 bytes. */
-extern int utf8_from_gsm7( cbytes_t src, int offset, int count, bytes_t utf8 );
-
-/* convert an unpacked 8-bit GSM septets string into a utf-8 byte string. assumes that 'utf8'
- is NULL or properly sized. 'count' is the number of input bytes.
- returns the number of utf8 bytes */
-extern int utf8_from_gsm8( cbytes_t src, int count, bytes_t utf8 );
-
-
-/** UCS-2 and GSM Alphabet
- **
- ** Note that here, 'ucs2' really refers to non-aligned UCS2-BE, as used by the GSM standard
- **/
-
-/* check that all characters in a given ucs2 string can be encoded into the GSM alphabet.
- returns 1 if TRUE, 0 otherwise */
-extern int ucs2_check_gsm7( cbytes_t ucs2, int ucs2len );
-
-/* convert a ucs2 string into a GSM septet string, assumes 'dst' is NULL or properly sized,
- 'offset' is the starting bit offset in 'dst'. non-representable characters are replaced
- by spaces. returns the number of septets */
-extern int ucs2_to_gsm7( cbytes_t ucs2, int ucs2len, bytes_t dst, int offset );
-
-/* convert a ucs2 string into a GSM septet string, assumes 'dst' is NULL or properly sized,
- non-representable characters are replaced by spaces. returns the number of bytes */
-extern int ucs2_to_gsm8( cbytes_t ucs2, int ucs2len, bytes_t dst );
-
-/* convert a GSM septets string into a ucs2 string. assumes that 'ucs2' is NULL or
- properly sized. 'offset' is the starting bit offset in 'src', 'count' is the number
- of input septets. return the number of ucs2 characters (not bytes) */
-extern int ucs2_from_gsm7( bytes_t ucs2, cbytes_t src, int offset, int count );
-
-/* convert an 8-bit unpacked GSM septets string into a ucs2 string. assumes that 'ucs2'
- is NULL or properly sized. 'count' is the number of input septets. return the number
- of ucs2 characters (not bytes) */
-extern int ucs2_from_gsm8( bytes_t ucs2, cbytes_t src, int count );
-
-
-/** UCS2 to/from UTF8
- **/
-
-/* convert a ucs2 string into a utf8 byte string, assumes 'utf8' NULL or properly sized.
- returns the number of utf8 bytes*/
-extern int ucs2_to_utf8( cbytes_t ucs2, int ucs2len, bytes_t utf8 );
-
-/* convert a utf8 byte string into a ucs2 string, assumes 'ucs2' NULL or properly sized.
- returns the number of ucs2 chars */
-extern int utf8_to_ucs2( cbytes_t utf8, int utf8len, bytes_t ucs2 );
-
-/* try to skip a given number of characters in a utf-8 byte string, return new position */
-extern cbytes_t utf8_skip( cbytes_t utf8, cbytes_t utf8end, int count);
-
-/** Dial Numbers: TON byte + 'count' bcd numbers
- **/
-
-/* convert a bcd-coded GSM dial number into an ASCII string (not zero-terminated)
- assumes 'dst' is NULL or properly sized, returns 0 in case of success, -1 in case of error.
- 'num_digits' is the number of digits, not input bytes. a trailing 0xf0 is ignored automatically
- return the number of ASCII chars */
-extern int gsm_bcdnum_to_ascii ( cbytes_t bcd, int num_digits, bytes_t dst );
-
-/* convert an ASCII dial-number into a bcd-coded string, returns the number of 4-bit nibbles written, */
-extern int gsm_bcdnum_from_ascii( cbytes_t ascii, int asciilen, bytes_t dst );
-
-/** ADN: Abbreviated Dialing Numbers
- **/
-#define SIM_ADN_MAX_ALPHA 20 /* maximum number of characters in ADN alpha tag */
-#define SIM_ADN_MAX_NUMBER 20 /* maximum digits in ADN number */
-
-typedef struct {
- byte_t alpha [ SIM_ADN_MAX_ALPHA*3+1 ]; /* alpha tag in zero-terminated utf-8 */
- char number[ SIM_ADN_MAX_NUMBER+1 ]; /* dialing number in zero-terminated ASCII */
-}
-SimAdnRec, *SimAdn;
-
-typedef struct {
- SimAdnRec adn;
- byte_t ext_record; /* 0 or 0xFF means no extension */
-}
-SimAdnRecordRec, *SimAdnRecord;
-
-extern int sim_adn_record_from_bytes( SimAdnRecord rec, cbytes_t data, int datalen );
-extern int sim_adn_record_to_bytes ( SimAdnRecord rec, bytes_t data, int datalen );
-
-/** ROPES
- **/
-
-typedef struct {
- bytes_t data;
- int max;
- int pos;
- int error;
- unsigned char data0[16];
-} GsmRopeRec, *GsmRope;
-
-extern void gsm_rope_init( GsmRope rope );
-extern void gsm_rope_init_alloc( GsmRope rope, int alloc );
-extern int gsm_rope_done( GsmRope rope );
-extern bytes_t gsm_rope_done_acquire( GsmRope rope, int *psize );
-extern void gsm_rope_add_c( GsmRope rope, char c );
-extern void gsm_rope_add( GsmRope rope, const void* str, int len );
-extern void* gsm_rope_reserve( GsmRope rope, int len );
-
-#endif /* _android_gsm_h */
diff --git a/telephony/modem_driver.c b/telephony/modem_driver.c
deleted file mode 100644
index 99bbe6c..0000000
--- a/telephony/modem_driver.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-/* implement the modem character device for Android within the QEMU event loop.
- * it communicates through a serial port with "rild" (Radio Interface Layer Daemon)
- * on the emulated device.
- */
-#include "modem_driver.h"
-#include "qemu-char.h"
-
-#define xxDEBUG
-
-#ifdef DEBUG
-# include <stdio.h>
-# define D(...) ( fprintf( stderr, __VA_ARGS__ ) )
-#else
-# define D(...) ((void)0)
-#endif
-
-AModem android_modem;
-CharDriverState* android_modem_cs;
-
-typedef struct {
- CharDriverState* cs;
- AModem modem;
- char in_buff[ 1024 ];
- int in_pos;
- int in_sms;
-} ModemDriver;
-
-/* send unsollicited messages to the device */
-static void
-modem_driver_unsol( void* _md, const char* message)
-{
- ModemDriver* md = _md;
- int len = strlen(message);
-
- qemu_chr_write(md->cs, (const uint8_t*)message, len);
-}
-
-static int
-modem_driver_can_read( void* _md )
-{
- ModemDriver* md = _md;
- int ret = sizeof(md->in_buff) - md->in_pos;
-
- return ret;
-}
-
-/* despite its name, this function is called when the device writes to the modem */
-static void
-modem_driver_read( void* _md, const uint8_t* src, int len )
-{
- ModemDriver* md = _md;
- const uint8_t* end = src + len;
- int nn;
-
- D( "%s: reading %d from %p bytes:", __FUNCTION__, len, src );
- for (nn = 0; nn < len; nn++) {
- int c = src[nn];
- if (c >= 32 && c < 127)
- D( "%c", c );
- else if (c == '\n')
- D( "<LF>" );
- else if (c == '\r')
- D( "<CR>" );
- else
- D( "\\x%02x", c );
- }
- D( "\n" );
-
- for ( ; src < end; src++ ) {
- char c = src[0];
-
- if (md->in_sms) {
- if (c != 26)
- goto AppendChar;
-
- md->in_buff[ md->in_pos ] = c;
- md->in_pos++;
- md->in_sms = 0;
- c = '\n';
- }
-
- if (c == '\n' || c == '\r') {
- const char* answer;
-
- if (md->in_pos == 0) /* skip empty lines */
- continue;
-
- md->in_buff[ md->in_pos ] = 0;
- md->in_pos = 0;
-
- D( "%s: << %s\n", __FUNCTION__, md->in_buff );
- answer = amodem_send(android_modem, md->in_buff);
- if (answer != NULL) {
- D( "%s: >> %s\n", __FUNCTION__, answer );
- len = strlen(answer);
- if (len == 2 && answer[0] == '>' && answer[1] == ' ')
- md->in_sms = 1;
-
- qemu_chr_write(md->cs, (const uint8_t*)answer, len);
- qemu_chr_write(md->cs, (const uint8_t*)"\r", 1);
- } else
- D( "%s: -- NO ANSWER\n", __FUNCTION__ );
-
- continue;
- }
- AppendChar:
- md->in_buff[ md->in_pos++ ] = c;
- if (md->in_pos == sizeof(md->in_buff)) {
- /* input is too long !! */
- md->in_pos = 0;
- }
- }
- D( "%s: done\n", __FUNCTION__ );
-}
-
-
-static void
-modem_driver_init( int base_port, ModemDriver* dm, CharDriverState* cs )
-{
- dm->cs = cs;
- dm->in_pos = 0;
- dm->in_sms = 0;
- dm->modem = amodem_create( base_port, modem_driver_unsol, dm );
-
- qemu_chr_add_handlers( cs, modem_driver_can_read, modem_driver_read, NULL, dm );
-}
-
-
-void android_modem_init( int base_port )
-{
- static ModemDriver modem_driver[1];
-
- if (android_modem_cs != NULL) {
- modem_driver_init( base_port, modem_driver, android_modem_cs );
- android_modem = modem_driver->modem;
- }
-}
diff --git a/telephony/modem_driver.h b/telephony/modem_driver.h
deleted file mode 100644
index d03010f..0000000
--- a/telephony/modem_driver.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _modem_driver_h
-#define _modem_driver_h
-
-#include "android_modem.h"
-#include "qemu-common.h"
-
-/** in telephony/modem_driver.c */
-/* this is the internal character driver used to communicate with the
- * emulated GSM modem. see qemu_chr_open() in vl.c */
-extern CharDriverState* android_modem_cs;
-
-/* the emulated GSM modem itself */
-extern AModem android_modem;
-
-/* must be called before the VM runs if there is a modem to emulate */
-extern void android_modem_init( int base_port );
-
-#endif /* _modem_driver_h */
diff --git a/telephony/remote_call.c b/telephony/remote_call.c
deleted file mode 100644
index 927e11d..0000000
--- a/telephony/remote_call.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "remote_call.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/debug.h"
-#include "sysdeps.h"
-#include "gsm.h"
-#include "android/android.h"
-#include "sockets.h"
-#include <stdlib.h>
-
-#define DEBUG 1
-
-#if 1
-# define D_ACTIVE VERBOSE_CHECK(modem)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if 1
-# define S_ACTIVE VERBOSE_CHECK(socket)
-#else
-# define S_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# include <stdio.h>
-# define D(...) do { if (D_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-# define S(...) do { if (S_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-#else
-# define D(...) ((void)0)
-# define S(...) ((void)0)
-#endif
-
-/** By convention, remote numbers are the console ports, i.e. 5554, 5556, etc...
- **/
-#define REMOTE_NUMBER_BASE 5554
-#define REMOTE_NUMBER_MAX 16
-#define REMOTE_NUMBER_MAX_CHARS 4
-#define REMOTE_CONSOLE_PORT 5554
-
-int
-remote_number_from_port( int port )
-{
- if (port & 1) /* must be even */
- return -1;
-
- port = (port - REMOTE_CONSOLE_PORT) >> 1;
- if ((unsigned)port >= REMOTE_NUMBER_MAX)
- return -1;
-
- return REMOTE_NUMBER_BASE + port*2;
-}
-
-int
-remote_number_to_port( int number )
-{
- if (number & 1) /* must be even */
- return -1;
-
- number = (number - REMOTE_NUMBER_BASE) >> 1;
- if ((unsigned)number >= REMOTE_NUMBER_MAX)
- return -1;
-
- return REMOTE_CONSOLE_PORT + number*2;
-}
-
-int
-remote_number_string_to_port( const char* number )
-{
- char* end;
- long num = strtol( number, &end, 10 );
-
- if (end == NULL || *end || (int)num != num )
- return -1;
-
- return remote_number_to_port( (int)num );
-}
-
-/** REMOTE CALL OBJECTS
- **/
-
-typedef struct RemoteCallRec {
- struct RemoteCallRec* next;
- struct RemoteCallRec** pref;
- RemoteCallType type;
- int to_port;
- int from_port;
- SysChannel channel;
- RemoteResultFunc result_func;
- void* result_opaque;
-
- char quitting;
-
- /* the output buffer */
- char* buff;
- int buff_pos;
- int buff_len;
- int buff_size;
- char buff0[32];
-
-} RemoteCallRec, *RemoteCall;
-
-static void
-remote_call_done( RemoteCall call )
-{
- call->pref[0] = call->next;
- call->next = NULL;
- call->pref = &call->next;
-
- if (call->buff && call->buff != call->buff0) {
- free(call->buff);
- call->buff = call->buff0;
- call->buff_size = (int) sizeof(call->buff0);
- }
-
- if ( call->channel ) {
- sys_channel_close( call->channel );
- call->channel = NULL;
- }
-
- call->buff_pos = 0;
- call->buff_len = 0;
-}
-
-
-static void
-remote_call_free( RemoteCall call )
-{
- if (call) {
- remote_call_done( call );
- free(call);
- }
-}
-
-
-static void remote_call_event( void* opaque, int events ); /* forward */
-
-static RemoteCall
-remote_call_alloc( RemoteCallType type, int to_port, int from_port )
-{
- RemoteCall rcall = calloc( sizeof(*rcall), 1 );
- int from_num = remote_number_from_port(from_port);
-
- if (rcall != NULL) {
- char *p, *end;
-
- rcall->pref = &rcall->next;
- rcall->type = type;
- rcall->to_port = to_port;
- rcall->from_port = from_port;
- rcall->buff = rcall->buff0;
- rcall->buff_size = sizeof(rcall->buff0);
- rcall->buff_pos = 0;
-
- p = rcall->buff;
- end = p + rcall->buff_size;
-
- switch (type) {
- case REMOTE_CALL_DIAL:
- p = bufprint(p, end, "gsm call %d\n", from_num );
- break;
-
- case REMOTE_CALL_BUSY:
- p = bufprint(p, end, "gsm busy %d\n", from_num);
- break;
-
- case REMOTE_CALL_HOLD:
- p = bufprint(p, end, "gsm hold %d\n", from_num);
- break;
-
- case REMOTE_CALL_ACCEPT:
- p = bufprint(p, end, "gsm accept %d\n", from_num);
- break;
-
- case REMOTE_CALL_HANGUP:
- p = bufprint(p, end, "gsm cancel %d\n", from_num );
- break;
-
- default:
- ;
- }
- if (p >= end) {
- D("%s: buffer too short\n", __FUNCTION__ );
- remote_call_free(rcall);
- return NULL;
- }
-
- rcall->buff_len = p - rcall->buff;
-
- rcall->channel = sys_channel_create_tcp_client( "localhost", to_port );
- if (rcall->channel == NULL) {
- D("%s: could not create channel to port %d\n", __FUNCTION__, to_port);
- remote_call_free(rcall);
- return NULL;
- }
-
- sys_channel_on( rcall->channel, SYS_EVENT_WRITE, remote_call_event, rcall );
- }
- return rcall;
-}
-
-
-static int
-remote_call_set_sms_pdu( RemoteCall call,
- SmsPDU pdu )
-{
- char *p, *end;
- int msg2len;
-
- msg2len = 32 + smspdu_to_hex( pdu, NULL, 0 );
- if (msg2len > call->buff_size) {
- char* old_buff = call->buff == call->buff0 ? NULL : call->buff;
- char* new_buff = realloc( old_buff, msg2len );
- if (new_buff == NULL) {
- D("%s: not enough memory to alloc %d bytes", __FUNCTION__, msg2len);
- return -1;
- }
- call->buff = new_buff;
- call->buff_size = msg2len;
- }
-
- p = call->buff;
- end = p + call->buff_size;
-
- p = bufprint(p, end, "sms pdu ");
- p += smspdu_to_hex( pdu, p, end-p );
- *p++ = '\n';
- *p = 0;
-
- call->buff_len = p - call->buff;
- call->buff_pos = 0;
- return 0;
-}
-
-
-static void
-remote_call_add( RemoteCall call,
- RemoteCall *plist )
-{
- RemoteCall first = *plist;
-
- call->next = first;
- call->pref = plist;
-
- if (first)
- first->pref = &call->next;
-}
-
-static void
-remote_call_event( void* opaque, int events )
-{
- RemoteCall call = opaque;
-
- S("%s: called for call (%d,%d), events=%02x\n", __FUNCTION__,
- call->from_port, call->to_port, events);
-
- if (events & SYS_EVENT_READ) {
- /* simply drain the channel */
- char temp[32];
- int n = sys_channel_read( call->channel, temp, sizeof(temp) );
- if (n <= 0) {
- /* remote emulator probably quitted */
- //S("%s: emulator %d quitted with %d: %s\n", __FUNCTION__, call->to_port, errno, errno_str);
- remote_call_free( call );
- return;
- }
- }
-
- if (events & SYS_EVENT_WRITE) {
- int n;
-
- if (S_ACTIVE) {
- int nn;
- S("%s: call (%d,%d) sending %d bytes '", __FUNCTION__,
- call->from_port, call->to_port, call->buff_len - call->buff_pos );
- for (nn = call->buff_pos; nn < call->buff_len; nn++) {
- int c = call->buff[nn];
- if (c < 32) {
- if (c == '\n')
- S("\\n");
- else if (c == '\t')
- S("\\t");
- else if (c == '\r')
- S("\\r");
- else
- S("\\x%02x", c);
- } else
- S("%c", c);
- }
- S("'\n");
- }
-
- n = sys_channel_write( call->channel,
- call->buff + call->buff_pos,
- call->buff_len - call->buff_pos );
- if (n <= 0) {
- /* remote emulator probably quitted */
- S("%s: emulator %d quitted unexpectedly with error %d: %s\n",
- __FUNCTION__, call->to_port, errno, errno_str);
- if (call->result_func)
- call->result_func( call->result_opaque, 0 );
- remote_call_free( call );
- return;
- }
- call->buff_pos += n;
-
- if (call->buff_pos >= call->buff_len) {
- /* cool, we sent everything */
- S("%s: finished sending data to %d\n", __FUNCTION__, call->to_port);
- if (!call->quitting) {
- call->quitting = 1;
- sprintf( call->buff, "quit\n" );
- call->buff_len = strlen(call->buff);
- call->buff_pos = 0;
- } else {
- call->quitting = 0;
- if (call->result_func)
- call->result_func( call->result_opaque, 1 );
-
- sys_channel_on( call->channel, SYS_EVENT_READ, remote_call_event, call );
- }
- }
- }
-}
-
-static RemoteCall _the_remote_calls;
-
-#if 0
-static int
-remote_from_number( const char* from )
-{
- char* end;
- long num = strtol( from, &end, 10 );
-
- if (end == NULL || *end)
- return -1;
-
- if ((unsigned)(num - REMOTE_NUMBER_BASE) >= REMOTE_NUMBER_MAX)
- return -1;
-
- return (int) num;
-}
-#endif
-
-static RemoteCall
-remote_call_generic( RemoteCallType type, const char* to_number, int from_port )
-{
- int to_port = remote_number_string_to_port(to_number);
- RemoteCall call;
-
- if ( remote_number_from_port(from_port) < 0 ) {
- D("%s: from_port value %d is not valid", __FUNCTION__, from_port);
- return NULL;
- }
- if ( to_port < 0 ) {
- D("%s: phone number '%s' is not decimal or remote", __FUNCTION__, to_number);
- return NULL;
- }
- if (to_port == from_port) {
- D("%s: trying to call self\n", __FUNCTION__);
- return NULL;
- }
- call = remote_call_alloc( type, to_port, from_port );
- if (call == NULL) {
- return NULL;
- }
- remote_call_add( call, &_the_remote_calls );
- D("%s: adding new call from port %d to port %d\n", __FUNCTION__, from_port, to_port);
- return call;
-}
-
-
-int
-remote_call_dial( const char* number,
- int from,
- RemoteResultFunc result_func,
- void* result_opaque )
-{
- RemoteCall call = remote_call_generic( REMOTE_CALL_DIAL, number, from );
-
- if (call != NULL) {
- call->result_func = result_func;
- call->result_opaque = result_opaque;
- }
- return call ? 0 : -1;
-}
-
-
-void
-remote_call_other( const char* to_number, int from_port, RemoteCallType type )
-{
- remote_call_generic( type, to_number, from_port );
-}
-
-/* call this function to send a SMS to a remote emulator */
-int
-remote_call_sms( const char* number,
- int from,
- SmsPDU pdu )
-{
- RemoteCall call = remote_call_generic( REMOTE_CALL_SMS, number, from );
-
- if (call == NULL)
- return -1;
-
- if (call != NULL) {
- if ( remote_call_set_sms_pdu( call, pdu ) < 0 ) {
- remote_call_free(call);
- return -1;
- }
- }
- return call ? 0 : -1;
-}
-
-
-void
-remote_call_cancel( const char* to_number, int from_port )
-{
- remote_call_generic( REMOTE_CALL_HANGUP, to_number, from_port );
-}
diff --git a/telephony/remote_call.h b/telephony/remote_call.h
deleted file mode 100644
index c6891b8..0000000
--- a/telephony/remote_call.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _REMOTE_CALL_H
-#define _REMOTE_CALL_H
-
-#include "sms.h"
-
-/* convert a base console port into a remote phone number, -1 on error */
-extern int remote_number_from_port( int port );
-
-/* convert a remote phone number into a remote console port, -1 on error */
-extern int remote_number_to_port( int number );
-
-extern int remote_number_string_to_port( const char* number );
-
-typedef void (*RemoteResultFunc)( void* opaque, int success );
-
-typedef enum {
- REMOTE_CALL_DIAL = 0,
- REMOTE_CALL_BUSY,
- REMOTE_CALL_HANGUP,
- REMOTE_CALL_HOLD,
- REMOTE_CALL_ACCEPT,
- REMOTE_CALL_SMS
-} RemoteCallType;
-
-/* call this function when you need to dial a remote voice call.
- * this will try to connect to a remote emulator. the result function
- * is called to indicate success or failure after some time.
- *
- * returns 0 if the number is to a remote phone, or -1 otherwise
- */
-extern int remote_call_dial( const char* to_number,
- int from_port,
- RemoteResultFunc result_func,
- void* result_opaque );
-
-/* call this function to send a SMS to a remote emulator */
-extern int remote_call_sms( const char* number, int from_port, SmsPDU pdu );
-
-/* call this function to indicate that you're busy to a remote caller */
-extern void remote_call_other( const char* to_number, int from_port, RemoteCallType type );
-
-extern void remote_call_cancel( const char* to_number, int from_port );
-
-#endif /* _REMOTE_CALL_H */
diff --git a/telephony/sim_card.c b/telephony/sim_card.c
deleted file mode 100644
index a5a3249..0000000
--- a/telephony/sim_card.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sim_card.h"
-#include <string.h>
-#include <assert.h>
-
-/* set ENABLE_DYNAMIC_RECORDS to 1 to enable dynamic records
- * for now, this is an experimental feature that needs more testing
- */
-#define ENABLE_DYNAMIC_RECORDS 0
-
-#define A_SIM_PIN_SIZE 4
-#define A_SIM_PUK_SIZE 8
-
-typedef struct ASimCardRec_ {
- ASimStatus status;
- char pin[ A_SIM_PIN_SIZE+1 ];
- char puk[ A_SIM_PUK_SIZE+1 ];
- int pin_retries;
-
- char out_buff[ 256 ];
- int out_size;
-
-} ASimCardRec;
-
-static ASimCardRec _s_card[1];
-
-ASimCard
-asimcard_create( void )
-{
- ASimCard card = _s_card;
- card->status = A_SIM_STATUS_READY;
- card->pin_retries = 0;
- strncpy( card->pin, "0000", sizeof(card->pin) );
- strncpy( card->puk, "12345678", sizeof(card->puk) );
- return card;
-}
-
-void
-asimcard_destroy( ASimCard card )
-{
- /* nothing really */
- card=card;
-}
-
-static __inline__ int
-asimcard_ready( ASimCard card )
-{
- return card->status == A_SIM_STATUS_READY;
-}
-
-ASimStatus
-asimcard_get_status( ASimCard sim )
-{
- return sim->status;
-}
-
-void
-asimcard_set_status( ASimCard sim, ASimStatus status )
-{
- sim->status = status;
-}
-
-const char*
-asimcard_get_pin( ASimCard sim )
-{
- return sim->pin;
-}
-
-const char*
-asimcard_get_puk( ASimCard sim )
-{
- return sim->puk;
-}
-
-void
-asimcard_set_pin( ASimCard sim, const char* pin )
-{
- strncpy( sim->pin, pin, A_SIM_PIN_SIZE );
- sim->pin_retries = 0;
-}
-
-void
-asimcard_set_puk( ASimCard sim, const char* puk )
-{
- strncpy( sim->puk, puk, A_SIM_PUK_SIZE );
- sim->pin_retries = 0;
-}
-
-
-int
-asimcard_check_pin( ASimCard sim, const char* pin )
-{
- if (sim->status != A_SIM_STATUS_PIN &&
- sim->status != A_SIM_STATUS_READY )
- return 0;
-
- if ( !strcmp( sim->pin, pin ) ) {
- sim->status = A_SIM_STATUS_READY;
- sim->pin_retries = 0;
- return 1;
- }
-
- if (sim->status != A_SIM_STATUS_READY) {
- if (++sim->pin_retries == 3)
- sim->status = A_SIM_STATUS_PUK;
- }
- return 0;
-}
-
-
-int
-asimcard_check_puk( ASimCard sim, const char* puk, const char* pin )
-{
- if (sim->status != A_SIM_STATUS_PUK)
- return 0;
-
- if ( !strcmp( sim->puk, puk ) ) {
- strncpy( sim->puk, puk, A_SIM_PUK_SIZE );
- strncpy( sim->pin, pin, A_SIM_PIN_SIZE );
- sim->status = A_SIM_STATUS_READY;
- sim->pin_retries = 0;
- return 1;
- }
-
- if ( ++sim->pin_retries == 6 ) {
- sim->status = A_SIM_STATUS_ABSENT;
- }
- return 0;
-}
-
-typedef enum {
- SIM_FILE_DM = 0,
- SIM_FILE_DF,
- SIM_FILE_EF_DEDICATED,
- SIM_FILE_EF_LINEAR,
- SIM_FILE_EF_CYCLIC
-} SimFileType;
-
-typedef enum {
- SIM_FILE_READ_ONLY = (1 << 0),
- SIM_FILE_NEED_PIN = (1 << 1),
-} SimFileFlags;
-
-/* descriptor for a known SIM File */
-#define SIM_FILE_HEAD \
- SimFileType type; \
- unsigned short id; \
- unsigned short flags;
-
-typedef struct {
- SIM_FILE_HEAD
-} SimFileAnyRec, *SimFileAny;
-
-typedef struct {
- SIM_FILE_HEAD
- cbytes_t data;
- int length;
-} SimFileEFDedicatedRec, *SimFileEFDedicated;
-
-typedef struct {
- SIM_FILE_HEAD
- byte_t rec_count;
- byte_t rec_len;
- cbytes_t records;
-} SimFileEFLinearRec, *SimFileEFLinear;
-
-typedef SimFileEFLinearRec SimFileEFCyclicRec;
-typedef SimFileEFCyclicRec* SimFileEFCyclic;
-
-typedef union {
- SimFileAnyRec any;
- SimFileEFDedicatedRec dedicated;
- SimFileEFLinearRec linear;
- SimFileEFCyclicRec cyclic;
-} SimFileRec, *SimFile;
-
-
-#if ENABLE_DYNAMIC_RECORDS
-/* convert a SIM File descriptor into an ASCII string,
- assumes 'dst' is NULL or properly sized.
- return the number of chars, or -1 on error */
-static int
-sim_file_to_hex( SimFile file, bytes_t dst )
-{
- SimFileType type = file->any.type;
- int result = 0;
-
- /* see 9.2.1 in TS 51.011 */
- switch (type) {
- case SIM_FILE_EF_DEDICATED:
- case SIM_FILE_EF_LINEAR:
- case SIM_FILE_EF_CYCLIC:
- {
- if (dst) {
- int file_size, perm;
-
- memcpy(dst, "0000", 4); /* bytes 1-2 are RFU */
- dst += 4;
-
- /* bytes 3-4 are the file size */
- if (type == SIM_FILE_EF_DEDICATED)
- file_size = file->dedicated.length;
- else
- file_size = file->linear.rec_count * file->linear.rec_len;
-
- gsm_hex_from_short( dst, file_size );
- dst += 4;
-
- /* bytes 5-6 are the file id */
- gsm_hex_from_short( dst, file->any.id );
- dst += 4;
-
- /* byte 7 is the file type - always EF, i.e. 0x04 */
- dst[0] = '0';
- dst[1] = '4';
- dst += 2;
-
- /* byte 8 is RFU, except bit 7 for cyclic files, which indicates
- that INCREASE is allowed. Since we don't support this yet... */
- dst[0] = '0';
- dst[1] = '0';
- dst += 2;
-
- /* byte 9-11 are access conditions */
- if (file->any.flags & SIM_FILE_READ_ONLY) {
- if (file->any.flags & SIM_FILE_NEED_PIN)
- perm = 0x1a;
- else
- perm = 0x0a;
- } else {
- if (file->any.flags & SIM_FILE_NEED_PIN)
- perm = 0x11;
- else
- perm = 0x00;
- }
- gsm_hex_from_byte(dst, perm);
- memcpy( dst+2, "a0aa", 4 );
- dst += 6;
-
- /* byte 12 is file status, we don't support invalidation */
- dst[0] = '0';
- dst[1] = '0';
- dst += 2;
-
- /* byte 13 is length of the following data, always 2 */
- dst[0] = '0';
- dst[1] = '2';
- dst += 2;
-
- /* byte 14 is struct of EF */
- dst[0] = '0';
- if (type == SIM_FILE_EF_DEDICATED)
- dst[1] = '0';
- else if (type == SIM_FILE_EF_LINEAR)
- dst[1] = '1';
- else
- dst[1] = '3';
-
- /* byte 15 is lenght of record, or 0 */
- if (type == SIM_FILE_EF_DEDICATED) {
- dst[0] = '0';
- dst[1] = '0';
- } else
- gsm_hex_from_byte( dst, file->linear.rec_len );
- }
- result = 30;
- }
- break;
-
- default:
- result = -1;
- }
- return result;
-}
-
-
-static const byte_t _const_spn_cphs[20] = {
- 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-static const byte_t _const_voicemail_cphs[1] = {
- 0x55
-};
-
-static const byte_t _const_iccid[10] = {
- 0x98, 0x10, 0x14, 0x30, 0x12, 0x11, 0x81, 0x15, 0x70, 0x02
-};
-
-static const byte_t _const_cff_cphs[1] = {
- 0x55
-};
-
-static SimFileEFDedicatedRec _const_files_dedicated[] =
-{
- { SIM_FILE_EF_DEDICATED, 0x6f14, SIM_FILE_READ_ONLY | SIM_FILE_NEED_PIN,
- _const_spn_cphs, sizeof(_const_spn_cphs) },
-
- { SIM_FILE_EF_DEDICATED, 0x6f11, SIM_FILE_NEED_PIN,
- _const_voicemail_cphs, sizeof(_const_voicemail_cphs) },
-
- { SIM_FILE_EF_DEDICATED, 0x2fe2, SIM_FILE_READ_ONLY,
- _const_iccid, sizeof(_const_iccid) },
-
- { SIM_FILE_EF_DEDICATED, 0x6f13, SIM_FILE_NEED_PIN,
- _const_cff_cphs, sizeof(_const_cff_cphs) },
-
- { 0, 0, 0, NULL, 0 } /* end of list */
-};
-#endif /* ENABLE_DYNAMIC_RECORDS */
-
-const char*
-asimcard_io( ASimCard sim, const char* cmd )
-{
- int nn;
-#if ENABLE_DYNAMIC_RECORDS
- int command, id, p1, p2, p3;
-#endif
- static const struct { const char* cmd; const char* answer; } answers[] =
- {
- { "+CRSM=192,28436,0,0,15", "+CRSM: 144,0,000000146f1404001aa0aa01020000" },
- { "+CRSM=176,28436,0,0,20", "+CRSM: 144,0,416e64726f6964ffffffffffffffffffffffffff" },
-
- { "+CRSM=192,28433,0,0,15", "+CRSM: 144,0,000000016f11040011a0aa01020000" },
- { "+CRSM=176,28433,0,0,1", "+CRSM: 144,0,55" },
-
- { "+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000a2fe204000fa0aa01020000" },
- { "+CRSM=176,12258,0,0,10", "+CRSM: 144,0,98101430121181157002" },
-
- { "+CRSM=192,28435,0,0,15", "+CRSM: 144,0,000000016f13040011a0aa01020000" },
- { "+CRSM=176,28435,0,0,1", "+CRSM: 144,0,55" },
-
- { "+CRSM=192,28472,0,0,15", "+CRSM: 144,0,0000000f6f3804001aa0aa01020000" },
- { "+CRSM=176,28472,0,0,15", "+CRSM: 144,0,ff30ffff3c003c03000c0000f03f00" },
-
- { "+CRSM=192,28617,0,0,15", "+CRSM: 144,0,000000086fc9040011a0aa01020104" },
- { "+CRSM=178,28617,1,4,4", "+CRSM: 144,0,01000000" },
-
- { "+CRSM=192,28618,0,0,15", "+CRSM: 144,0,0000000a6fca040011a0aa01020105" },
- { "+CRSM=178,28618,1,4,5", "+CRSM: 144,0,0000000000" },
-
- { "+CRSM=192,28589,0,0,15", "+CRSM: 144,0,000000046fad04000aa0aa01020000" },
- { "+CRSM=176,28589,0,0,4", "+CRSM: 144,0,00000003" },
-
- { "+CRSM=192,28438,0,0,15", "+CRSM: 144,0,000000026f1604001aa0aa01020000" },
- { "+CRSM=176,28438,0,0,2", "+CRSM: 144,0,0233" },
-
- { "+CRSM=192,28486,0,0,15", "+CRSM: 148,4" },
- { "+CRSM=192,28621,0,0,15", "+CRSM: 148,4" },
-
- { "+CRSM=192,28613,0,0,15", "+CRSM: 144,0,000000f06fc504000aa0aa01020118" },
- { "+CRSM=178,28613,1,4,24", "+CRSM: 144,0,43058441aa890affffffffffffffffffffffffffffffffff" },
-
- { "+CRSM=192,28480,0,0,15", "+CRSM: 144,0,000000806f40040011a0aa01020120" },
- { "+CRSM=178,28480,1,4,32", "+CRSM: 144,0,ffffffffffffffffffffffffffffffffffff07815155258131f5ffffffffffff" },
-
- { "+CRSM=192,28615,0,0,15", "+CRSM: 144,0,000000406fc7040011a0aa01020120" },
- { "+CRSM=178,28615,1,4,32", "+CRSM: 144,0,566f6963656d61696cffffffffffffffffff07915155125740f9ffffffffffff" },
-
- { NULL, NULL }
- };
-
- assert( memcmp( cmd, "+CRSM=", 6 ) == 0 );
-
-#if ENABLE_DYNAMIC_RECORDS
- if ( sscanf(cmd, "+CRSM=%d,%d,%d,%d,%d", &command, &id, &p1, &p2, &p3) == 5 ) {
- switch (command) {
- case A_SIM_CMD_GET_RESPONSE:
- {
- const SimFileEFDedicatedRec* file = _const_files_dedicated;
-
- assert(p1 == 0 && p2 == 0 && p3 == 15);
-
- for ( ; file->id != 0; file++ ) {
- if (file->id == id) {
- int count;
- char* out = sim->out_buff;
- strcpy( out, "+CRSM: 144,0," );
- out += strlen(out);
- count = sim_file_to_hex( (SimFile) file, out );
- if (count < 0)
- return "ERROR: INTERNAL SIM ERROR";
- out[count] = 0;
- return sim->out_buff;
- }
- }
- break;
- }
-
- case A_SIM_CMD_READ_BINARY:
- {
- const SimFileEFDedicatedRec* file = _const_files_dedicated;
-
- assert(p1 == 0 && p2 == 0);
-
- for ( ; file->id != 0; file++ ) {
- if (file->id == id) {
- char* out = sim->out_buff;
-
- if (p3 > file->length)
- return "ERROR: BINARY LENGTH IS TOO LONG";
-
- strcpy( out, "+CRSM: 144,0," );
- out += strlen(out);
- gsm_hex_from_bytes( out, file->data, p3 );
- out[p3*2] = 0;
- return sim->out_buff;
- }
- }
- break;
- }
-
- case A_SIM_CMD_READ_RECORD:
- break;
-
- default:
- return "ERROR: UNSUPPORTED SIM COMMAND";
- }
- }
-#endif
-
- for (nn = 0; answers[nn].cmd != NULL; nn++) {
- if ( !strcmp( answers[nn].cmd, cmd ) ) {
- return answers[nn].answer;
- }
- }
- return "ERROR: BAD COMMAND";
-}
-
diff --git a/telephony/sim_card.h b/telephony/sim_card.h
deleted file mode 100644
index af78237..0000000
--- a/telephony/sim_card.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_sim_card_h
-#define _android_sim_card_h
-
-#include "gsm.h"
-
-typedef struct ASimCardRec_* ASimCard;
-
-extern ASimCard asimcard_create( void );
-extern void asimcard_destroy( ASimCard sim );
-
-typedef enum {
- A_SIM_STATUS_ABSENT = 0,
- A_SIM_STATUS_NOT_READY,
- A_SIM_STATUS_READY,
- A_SIM_STATUS_PIN,
- A_SIM_STATUS_PUK,
- A_SIM_STATUS_NETWORK_PERSONALIZATION
-} ASimStatus;
-
-extern ASimStatus asimcard_get_status( ASimCard sim );
-extern void asimcard_set_status( ASimCard sim, ASimStatus status );
-
-extern const char* asimcard_get_pin( ASimCard sim );
-extern const char* asimcard_get_puk( ASimCard sim );
-extern void asimcard_set_pin( ASimCard sim, const char* pin );
-extern void asimcard_set_puk( ASimCard sim, const char* puk );
-
-extern int asimcard_check_pin( ASimCard sim, const char* pin );
-extern int asimcard_check_puk( ASimCard sim, const char* puk, const char* pin );
-
-/* Restricted SIM Access command, as defined by 8.18 of 3GPP 27.007 */
-typedef enum {
- A_SIM_CMD_READ_BINARY = 176,
- A_SIM_CMD_READ_RECORD = 178,
- A_SIM_CMD_GET_RESPONSE = 192,
- A_SIM_CMD_UPDATE_BINARY = 214,
- A_SIM_CMD_UPDATE_RECORD = 220,
- A_SIM_CMD_STATUS = 242
-} ASimCommand;
-
-extern const char* asimcard_io( ASimCard sim, const char* cmd );
-
-#endif /* _android_sim_card_h */
diff --git a/telephony/simulator.c b/telephony/simulator.c
deleted file mode 100644
index 43f267a..0000000
--- a/telephony/simulator.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android_modem.h"
-#include "sysdeps.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-#define DEFAULT_PORT 6703
-
-static AModem modem;
-
-typedef struct {
- SysChannel channel;
- char in_buff[ 128 ];
- int in_pos;
-
- char out_buff[ 128 ];
- int out_pos;
- int out_size;
-} ClientRec, *Client;
-
-static Client
-client_alloc( SysChannel channel )
-{
- Client client = calloc( sizeof(*client), 1 );
-
- client->channel = channel;
- return client;
-}
-
-static void
-client_free( Client client )
-{
- sys_channel_close( client->channel );
- client->channel = NULL;
- free( client );
-}
-
-static void
-client_append( Client client, const char* str, int len );
-
-static void
-dump_line( const char* line, const char* prefix )
-{
- if (prefix)
- printf( "%s", prefix );
-
- for ( ; *line; line++ ) {
- int c = line[0];
-
- if (c >= 32 && c < 127)
- printf( "%c", c );
- else if (c == '\r')
- printf( "<CR>" );
- else if (c == '\n')
- printf( "<LF>" );
- else
- printf( "\\x%02x", c );
- }
- printf( "\n" );
-}
-
-static void
-client_handle_line( Client client, const char* cmd )
-{
- const char* answer;
-
- dump_line( cmd, "<< " );
- answer = amodem_send( modem, cmd );
- if (answer == NULL) /* not an AT command, ignored */ {
- printf( "-- NO ANSWER\n" );
- return;
- }
-
- dump_line( answer, ">> " );
- client_append( client, answer, -1 );
- client_append( client, "\r", 1 );
-}
-
-static void
-client_handler( void* _client, int events )
-{
- Client client = _client;
-
- if (events & SYS_EVENT_READ) {
- int ret;
- /* read into buffer, one character at a time */
- ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- if (client->in_buff[client->in_pos] == '\r' ||
- client->in_buff[client->in_pos] == '\n' ) {
- const char* cmd = client->in_buff;
- client->in_buff[client->in_pos] = 0;
-
- if (client->in_pos > 0) {
- client_handle_line( client, cmd );
- client->in_pos = 0;
- }
- } else
- client->in_pos += 1;
- }
-
- if (events & SYS_EVENT_WRITE) {
- int ret;
- /* write from output buffer, one char at a time */
- ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- client->out_pos += 1;
- if (client->out_pos == client->out_size) {
- client->out_size = 0;
- client->out_pos = 0;
- /* we don't need to write */
- sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client );
- }
- }
- return;
-
-ExitClient:
- printf( "client %p exiting\n", client );
- client_free( client );
-}
-
-
-static void
-client_append( Client client, const char* str, int len )
-{
- int avail;
-
- if (len < 0)
- len = strlen(str);
-
- avail = sizeof(client->out_buff) - client->out_size;
- if (len > avail)
- len = avail;
-
- memcpy( client->out_buff + client->out_size, str, len );
- if (client->out_size == 0) {
- sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client );
- }
- client->out_size += len;
-}
-
-
-static void
-accept_func( void* _server, int events )
-{
- SysChannel server = _server;
- SysChannel handler;
- Client client;
-
- printf( "connection accepted for server channel, getting handler socket\n" );
- handler = sys_channel_create_tcp_handler( server );
- client = client_alloc( handler );
- printf( "got one. created client %p\n", client );
-
- events=events;
- sys_channel_on( handler, SYS_EVENT_READ, client_handler, client );
-}
-
-
-int main( void )
-{
- int port = DEFAULT_PORT;
- SysChannel server;
-
- sys_main_init();
- modem = amodem_create( NULL, NULL );
-
- server = sys_channel_create_tcp_server( port );
- printf( "GSM simulator listening on local port %d\n", port );
-
- sys_channel_on( server, SYS_EVENT_READ, accept_func, server );
- sys_main_loop();
- printf( "GSM simulator exiting\n" );
- return 0;
-}
diff --git a/telephony/sms.c b/telephony/sms.c
deleted file mode 100644
index 448eab4..0000000
--- a/telephony/sms.c
+++ /dev/null
@@ -1,1655 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sms.h"
-#include "gsm.h"
-#include <memory.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#define DEBUG 1
-
-#if 1
-# include "android/utils/debug.h"
-# define D_ACTIVE VERBOSE_CHECK(modem)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(...) VERBOSE_PRINT(modem,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-/* maximum number of data bytes in a SMS data message */
-#define MAX_USER_DATA_BYTES 140
-
-/* maximum number of 7-bit septets in a SMS text message */
-#define MAX_USER_DATA_SEPTETS 160
-
-/* size of the user data header in bytes */
-#define USER_DATA_HEADER_SIZE 6
-
-/** MESSAGE TEXT
- **/
-int
-sms_utf8_from_message_str( const char* str, int strlen, unsigned char* utf8, int utf8len )
-{
- cbytes_t p = (cbytes_t)str;
- cbytes_t end = p + strlen;
- int count = 0;
- int escaped = 0;
-
- while (p < end)
- {
- int c = p[0];
-
- /* read the value from the string */
- p += 1;
- if (c >= 128) {
- if ((c & 0xe0) == 0xc0)
- c &= 0x1f;
- else if ((c & 0xf0) == 0xe0)
- c &= 0x0f;
- else
- c &= 0x07;
- p++;
- while (p < end && (p[0] & 0xc0) == 0x80) {
- c = (c << 6) | (p[0] & 0x3f);
- p++;
- }
- }
- if (escaped) {
- switch (c) {
- case '\\':
- break;
- case 'n': /* \n is line feed */
- c = 10;
- break;
-
- case 'x': /* \xNN, where NN is a 2-digit hexadecimal value */
- if (p+2 > end)
- return -1;
- c = gsm_hex2_to_byte( (const char*)p );
- if (c < 0)
- return -1;
- p += 2;
- break;
-
- case 'u': /* \uNNNN where NNNN is a 4-digiti hexadecimal value */
- if (p + 4 > end)
- return -1;
- c = gsm_hex4_to_short( (const char*)p );
- if (c < 0)
- return -1;
- p += 4;
- break;
-
- default: /* invalid escape, return -1 */
- return -1;
- }
- escaped = 0;
- }
- else if (c == '\\')
- {
- escaped = 1;
- continue;
- }
-
- /* now, try to write it to the destination */
- if (c < 128) {
- if (count < utf8len)
- utf8[count] = (byte_t) c;
- count += 1;
- }
- else if (c < 0x800) {
- if (count < utf8len)
- utf8[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f));
- if (count+1 < utf8len)
- utf8[count+1] = (byte_t)(0x80 | (c & 0x3f));
- count += 2;
- }
- else {
- if (count < utf8len)
- utf8[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf));
- if (count+1 < utf8len)
- utf8[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f));
- if (count+2 < utf8len)
- utf8[count+2] = (byte_t)(0x80 | (c & 0x3f));
- count += 3;
- }
- }
-
- if (escaped) /* bad final escape */
- return -1;
-
- return count;
-}
-
-/* to convert utf-8 to a message string, we only need to deal with control characters
- * and that's it */
-int sms_utf8_to_message_str( const unsigned char* utf8, int utf8len, char* str, int strlen )
-{
- cbytes_t p = utf8;
- cbytes_t end = p + utf8len;
- int count = 0;
-
- while (p < end)
- {
- int c = p[0];
- int escape = 0;
-
- /* read the value from the string */
- p += 1;
- if (c >= 128) {
- if ((c & 0xe0) == 0xc0)
- c &= 0x1f;
- else if ((c & 0xf0) == 0xe0)
- c &= 0x0f;
- else
- c &= 0x07;
- p++;
- while (p < end && (p[0] & 0xc0) == 0x80) {
- c = (c << 6) | (p[0] & 0x3f);
- p++;
- }
- }
-
- if (c < ' ') {
- escape = 1;
- if (c == '\n') {
- c = 'n';
- escape = 2;
- }
- }
- else if (c == '\\')
- escape = 2;
-
- switch (escape) {
- case 0:
- if (c < 128) {
- if (count < strlen)
- str[count] = (char) c;
- count += 1;
- }
- else if (c < 0x800) {
- if (count < strlen)
- str[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f));
- if (count+1 < strlen)
- str[count+1] = (byte_t)(0x80 | (c & 0x3f));
- count += 2;
- }
- else {
- if (count < strlen)
- str[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf));
- if (count+1 < strlen)
- str[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f));
- if (count+2 < strlen)
- str[count+2] = (byte_t)(0x80 | (c & 0x3f));
- count += 3;
- }
- break;
-
- case 1:
- if (count+3 < strlen) {
- str[count+0] = '\\';
- str[count+1] = 'x';
- gsm_hex_from_byte(str + count + 2, c);
- }
- count += 4;
- break;
-
- default:
- if (count+2 < strlen) {
- str[count+0] = '\\';
- str[count+1] = (char) c;
- }
- count += 2;
- }
- }
- return count;
-}
-
-
-/** TIMESTAMPS
- **/
-void
-sms_timestamp_now( SmsTimeStamp stamp )
-{
- time_t now_time = time(NULL);
- struct tm gm = *(gmtime(&now_time));
- struct tm local = *(localtime(&now_time));
- int tzdiff = 0;
-
- stamp->data[0] = gsm_int_to_bcdi( local.tm_year % 100 );
- stamp->data[1] = gsm_int_to_bcdi( local.tm_mon+1 );
- stamp->data[2] = gsm_int_to_bcdi( local.tm_mday );
- stamp->data[3] = gsm_int_to_bcdi( local.tm_hour );
- stamp->data[4] = gsm_int_to_bcdi( local.tm_min );
- stamp->data[5] = gsm_int_to_bcdi( local.tm_sec );
-
- tzdiff = (local.tm_hour*4 + local.tm_min/15) - (gm.tm_hour*4 + gm.tm_min/15);
- if (local.tm_yday > gm.tm_yday)
- tzdiff += 24*4;
- else if (local.tm_yday < gm.tm_yday)
- tzdiff -= 24*4;
-
- stamp->data[6] = gsm_int_to_bcdi( tzdiff >= 0 ? tzdiff : -tzdiff );
- if (tzdiff < 0)
- stamp->data[6] |= 0x08;
-}
-
-int
-sms_timestamp_to_tm( SmsTimeStamp stamp, struct tm* tm )
-{
- int tzdiff;
-
- tm->tm_year = gsm_int_from_bcdi( stamp->data[0] );
- if (tm->tm_year < 50)
- tm->tm_year += 100;
- tm->tm_mon = gsm_int_from_bcdi( stamp->data[1] ) -1;
- tm->tm_mday = gsm_int_from_bcdi( stamp->data[2] );
- tm->tm_hour = gsm_int_from_bcdi( stamp->data[3] );
- tm->tm_min = gsm_int_from_bcdi( stamp->data[4] );
- tm->tm_sec = gsm_int_from_bcdi( stamp->data[5] );
-
- tm->tm_isdst = -1;
-
- tzdiff = gsm_int_from_bcdi( stamp->data[6] & 0xf7 );
- if (stamp->data[6] & 0x8)
- tzdiff = -tzdiff;
-
- return tzdiff;
-}
-
-static void
-gsm_rope_add_timestamp( GsmRope rope, const SmsTimeStampRec* ts )
-{
- gsm_rope_add( rope, ts->data, 7 );
-}
-
-
-/** SMS ADDRESSES
- **/
-
-int
-sms_address_from_str( SmsAddress address, const char* src, int srclen )
-{
- const char* end = src + srclen;
- int shift = 0, len = 0;
- bytes_t data = address->data;
-
- address->len = 0;
- address->toa = 0x81;
-
- if (src >= end)
- return -1;
-
- if ( src[0] == '+' ) {
- address->toa = 0x91;
- if (++src == end)
- goto Fail;
- }
-
- memset( address->data, 0, sizeof(address->data) );
-
- shift = 0;
-
- while (src < end) {
- int c = *src++ - '0';
-
- if ( (unsigned)c >= 10 ||
- data >= address->data + sizeof(address->data) )
- goto Fail;
-
- data[0] |= c << shift;
- len += 1;
- shift += 4;
- if (shift == 8) {
- shift = 0;
- data += 1;
- }
- }
- if (shift != 0)
- data[0] |= 0xf0;
-
- address->len = len;
- return 0;
-
-Fail:
- return -1;
-}
-
-int
-sms_address_to_str( SmsAddress address, char* str, int strlen )
-{
- static const char dialdigits[16] = "0123456789*#,N%";
- int n, count = 0;
-
- if (address->toa == 0x91) {
- if (count < strlen)
- str[count] = '+';
- count++;
- }
- for (n = 0; n < address->len; n += 2)
- {
- int c = address->data[n/2];
-
- if (count < strlen)
- str[count] = dialdigits[c & 0xf];
- count += 1;
-
- if (n+1 > address->len)
- break;
-
- if (count < strlen)
- str[count] = dialdigits[(c >> 4) & 0xf];
- count += 1;
- }
- return count;
-}
-
-int
-sms_address_from_bytes( SmsAddress address, const unsigned char* buf, int buflen )
-{
- int len = sizeof(address->data), num_digits;
-
- if (buflen < 2)
- return -1;
-
- address->len = num_digits = buf[0];
- address->toa = buf[1];
-
- len = (num_digits+1)/2;
- if ( len > sizeof(address->data) )
- return -1;
-
- memcpy( address->data, buf+2, len );
- return 0;
-}
-
-int
-sms_address_to_bytes( SmsAddress address, unsigned char* buf, int bufsize )
-{
- int len = (address->len + 1)/2 + 2;
-
- if (buf == NULL)
- bufsize = 0;
-
- if (bufsize < 1) goto Exit;
- buf[0] = address->len;
-
- if (bufsize < 2) goto Exit;
- buf[1] = address->toa;
-
- buf += 2;
- bufsize -= 2;
- if (bufsize > len-2)
- bufsize = len - 2;
-
- memcpy( buf, address->data, bufsize );
-Exit:
- return len;
-}
-
-int
-sms_address_from_hex ( SmsAddress address, const char* hex, int hexlen )
-{
- const char* hexend = hex + hexlen;
- int nn, len, num_digits;
-
- if (hexlen < 4)
- return -1;
-
- address->len = num_digits = gsm_hex2_to_byte( hex );
- address->toa = gsm_hex2_to_byte( hex+2 );
- hex += 4;
-
- len = (num_digits + 1)/2;
- if (hex + len*2 > hexend)
- return -1;
-
- for ( nn = 0; nn < len; nn++ )
- address->data[nn] = gsm_hex2_to_byte( hex + nn*2 );
-
- return 0;
-}
-
-int
-sms_address_to_hex ( SmsAddress address, char* hex, int hexlen )
-{
- int len = (address->len + 1)/2 + 2;
- int nn;
-
- if (hex == NULL)
- hexlen = 0;
-
- if (hexlen < 2) goto Exit;
- gsm_hex_from_byte( hex, address->len );
- if (hexlen < 4) goto Exit;
- gsm_hex_from_byte( hex+2, address->toa );
- hex += 4;
- hexlen -= 4;
- if ( hexlen > 2*(len - 2) )
- hexlen = (len - 2)/2;
-
- for ( nn = 0; nn < hexlen; nn += 2 )
- gsm_hex_from_byte( hex+nn, address->data[nn/2] );
-
-Exit:
- return len*2;
-}
-
-static void
-gsm_rope_add_address( GsmRope rope, const SmsAddressRec* addr )
-{
- gsm_rope_add_c( rope, addr->len );
- gsm_rope_add_c( rope, addr->toa );
- gsm_rope_add( rope, addr->data, (addr->len+1)/2 );
- if (addr->len & 1) {
- if (!rope->error && rope->data != NULL)
- rope->data[ rope->pos-1 ] |= 0xf0;
- }
-}
-
-static int
-sms_address_eq( const SmsAddressRec* addr1, const SmsAddressRec* addr2 )
-{
- if ( addr1->toa != addr2->toa ||
- addr1->len != addr2->len )
- return 0;
-
- return ( !memcmp( addr1->data, addr2->data, addr1->len ) );
-}
-
-/** SMS PARSER
- **/
-static int
-sms_get_byte( cbytes_t *pcur, cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int result = -1;
-
- if (cur < end) {
- result = cur[0];
- *pcur = cur + 1;
- }
- return result;
-}
-
-/* parse a service center address, returns -1 in case of error */
-static int
-sms_get_sc_address( cbytes_t *pcur,
- cbytes_t end,
- SmsAddress address )
-{
- cbytes_t cur = *pcur;
- int result = -1;
-
- if (cur < end) {
- int len = cur[0];
- int dlen, adjust = 0;
-
- cur += 1;
-
- if (len == 0) { /* empty address */
- address->len = 0;
- address->toa = 0x00;
- result = 0;
- goto Exit;
- }
-
- if (cur + len > end) {
- goto Exit;
- }
-
- address->toa = *cur++;
- len -= 1;
- result = 0;
-
- for (dlen = 0; dlen < len; dlen+=1)
- {
- int c = cur[dlen];
- int v;
-
- adjust = 0;
- if (dlen >= sizeof(address->data)) {
- result = -1;
- break;
- }
-
- v = (c & 0xf);
- if (v >= 0xe)
- break;
-
- adjust = 1;
- address->data[dlen] = (byte_t) c;
-
- v = (c >> 4) & 0xf;
- if (v >= 0xe) {
- break;
- }
- }
- address->len = 2*dlen + adjust;
- }
-Exit:
- if (!result)
- *pcur = cur;
-
- return result;
-}
-
-static int
-sms_skip_sc_address( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int len;
-
- if (cur >= end)
- goto Exit;
-
- len = cur[0];
- cur += 1 + len;
- if (cur > end)
- goto Exit;
-
- *pcur = cur;
- result = 0;
-Exit:
- return result;
-}
-
-/* parse a sender/receiver address, returns -1 in case of error */
-static int
-sms_get_address( cbytes_t *pcur,
- cbytes_t end,
- SmsAddress address )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int len, dlen;
-
- if (cur >= end)
- goto Exit;
-
- dlen = *cur++;
-
- if (dlen == 0) {
- address->len = 0;
- address->toa = 0;
- result = 0;
- goto Exit;
- }
-
- if (cur + 1 + (dlen+1)/2 > end)
- goto Exit;
-
- address->len = dlen;
- address->toa = *cur++;
-
- len = (dlen + 1)/2;
- if (len > sizeof(address->data))
- goto Exit;
-
- memcpy( address->data, cur, len );
- cur += len;
- result = 0;
-
-Exit:
- if (!result)
- *pcur = cur;
-
- return result;
-}
-
-static int
-sms_skip_address( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int dlen;
-
- if (cur + 2 > end)
- goto Exit;
-
- dlen = cur[0];
- cur += 2 + (dlen + 1)/2;
- if (cur > end)
- goto Exit;
-
- result = 0;
-Exit:
- return result;
-}
-
-/* parse a service center timestamp */
-static int
-sms_get_timestamp( cbytes_t *pcur,
- cbytes_t end,
- SmsTimeStamp ts )
-{
- cbytes_t cur = *pcur;
-
- if (cur + 7 > end)
- return -1;
-
- memcpy( ts->data, cur, 7 );
- *pcur = cur + 7;
- return 0;
-}
-
-static int
-sms_skip_timestamp( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
-
- if (cur + 7 > end)
- return -1;
-
- *pcur = cur + 7;
- return 0;
-}
-
-
-static int
-sms_skip_validity_period( cbytes_t *pcur,
- cbytes_t end,
- int mtiByte )
-{
- cbytes_t cur = *pcur;
-
- switch ((mtiByte >> 3) & 3) {
- case 1: /* relative format */
- cur += 1;
- break;
-
- case 2: /* enhanced format */
- case 3: /* absolute format */
- cur += 7;
- }
- if (cur > end)
- return -1;
-
- *pcur = cur;
- return 0;
-}
-
-/** SMS PDU
- **/
-
-typedef struct SmsPDURec {
- bytes_t base;
- bytes_t end;
- bytes_t tpdu;
-} SmsPDURec;
-
-void
-smspdu_free( SmsPDU pdu )
-{
- if (pdu) {
- free( pdu->base );
- pdu->base = NULL;
- pdu->end = NULL;
- pdu->tpdu = NULL;
- }
-}
-
-SmsPduType
-smspdu_get_type( SmsPDU pdu )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte(&data, end);
-
- switch (mtiByte & 3) {
- case 0: return SMS_PDU_DELIVER;
- case 1: return SMS_PDU_SUBMIT;
- case 2: return SMS_PDU_STATUS_REPORT;
- default: return SMS_PDU_INVALID;
- }
-}
-
-int
-smspdu_get_sender_address( SmsPDU pdu, SmsAddress address )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte(&data, end);
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER; */
- return sms_get_sc_address( &data, end, address );
-
- default: return -1;
- }
-}
-
-int
-smspdu_get_sc_timestamp( SmsPDU pdu, SmsTimeStamp ts )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER */
- {
- SmsAddressRec address;
-
- if ( sms_get_sc_address( &data, end, &address ) < 0 )
- return -1;
-
- data += 2; /* skip protocol identifer + coding scheme */
-
- return sms_get_timestamp( &data, end, ts );
- }
-
- default: return -1;
- }
-}
-
-int
-smspdu_get_receiver_address( SmsPDU pdu, SmsAddress address )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- switch (mtiByte & 3) {
- case 1: /* SMS_PDU_SUBMIT */
- {
- data += 1; /* skip message reference */
- return sms_get_address( &data, end, address );
- }
-
- default: return -1;
- }
-}
-
-typedef enum {
- SMS_CODING_SCHEME_UNKNOWN = 0,
- SMS_CODING_SCHEME_GSM7,
- SMS_CODING_SCHEME_UCS2
-
-} SmsCodingScheme;
-
-/* see TS 23.038 Section 5 for details */
-static SmsCodingScheme
-sms_get_coding_scheme( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int dataCoding;
-
- if (cur >= end)
- return SMS_CODING_SCHEME_UNKNOWN;
-
- dataCoding = *cur++;
- *pcur = cur;
-
- switch (dataCoding >> 4) {
- case 0x00:
- case 0x02:
- case 0x03:
- return SMS_CODING_SCHEME_GSM7;
-
- case 0x01:
- if (dataCoding == 0x10) return SMS_CODING_SCHEME_GSM7;
- if (dataCoding == 0x11) return SMS_CODING_SCHEME_UCS2;
- break;
-
- case 0x04: case 0x05: case 0x06: case 0x07:
- if (dataCoding & 0x20) return SMS_CODING_SCHEME_UNKNOWN; /* compressed 7-bits */
- if (((dataCoding >> 2) & 3) == 0) return SMS_CODING_SCHEME_GSM7;
- if (((dataCoding >> 2) & 3) == 2) return SMS_CODING_SCHEME_UCS2;
- break;
-
- case 0xF:
- if (!(dataCoding & 4)) return SMS_CODING_SCHEME_GSM7;
- break;
- }
- return SMS_CODING_SCHEME_UNKNOWN;
-}
-
-
-/* see TS 23.040 section 9.2.3.24 for details */
-static int
-sms_get_text_utf8( cbytes_t *pcur,
- cbytes_t end,
- int hasUDH,
- SmsCodingScheme coding,
- GsmRope rope )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int len;
-
- if (cur >= end)
- goto Exit;
-
- len = *cur++;
-
- /* skip user data header if any */
- if ( hasUDH )
- {
- int hlen;
-
- if (cur >= end)
- goto Exit;
-
- hlen = *cur++;
- if (cur + hlen > end)
- goto Exit;
-
- cur += hlen;
-
- if (coding == SMS_CODING_SCHEME_GSM7)
- len -= 2*(hlen+1);
- else
- len -= hlen+1;
-
- if (len < 0)
- goto Exit;
- }
-
- /* switch the user data header if any */
- if (coding == SMS_CODING_SCHEME_GSM7)
- {
- int count = utf8_from_gsm7( cur, 0, len, NULL );
-
- if (rope != NULL)
- {
- bytes_t dst = gsm_rope_reserve( rope, count );
- if (dst != NULL)
- utf8_from_gsm7( cur, 0, len, dst );
- }
- cur += (len+1)/2;
- }
- else if (coding == SMS_CODING_SCHEME_UCS2)
- {
- int count = ucs2_to_utf8( cur, len/2, NULL );
-
- if (rope != NULL)
- {
- bytes_t dst = gsm_rope_reserve( rope, count );
- if (dst != NULL)
- ucs2_to_utf8( cur, len/2, dst );
- }
- cur += len;
- }
- result = 0;
-
-Exit:
- if (!result)
- *pcur = cur;
-
- return result;
-}
-
-/* get the message embedded in a SMS PDU as a utf8 byte array, returns the length of the message in bytes */
-/* or -1 in case of error */
-int
-smspdu_get_text_message( SmsPDU pdu, unsigned char* utf8, int utf8len )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER */
- {
- SmsAddressRec address;
- SmsTimeStampRec timestamp;
- SmsCodingScheme coding;
- GsmRopeRec rope[1];
- int result;
-
- if ( sms_get_sc_address( &data, end, &address ) < 0 )
- goto Fail;
-
- data += 1; /* skip protocol identifier */
- coding = sms_get_coding_scheme( &data, end );
- if (coding == SMS_CODING_SCHEME_UNKNOWN)
- goto Fail;
-
- if ( sms_get_timestamp( &data, end, &timestamp ) < 0 )
- goto Fail;
-
- if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 )
- goto Fail;
-
- result = rope->pos;
- if (utf8len > result)
- utf8len = result;
-
- if (utf8len > 0)
- memcpy( utf8, rope->data, utf8len );
-
- gsm_rope_done( rope );
- return result;
- }
-
- case 1: /* SMS_PDU_SUBMIT */
- {
- SmsAddressRec address;
- SmsCodingScheme coding;
- GsmRopeRec rope[1];
- int result;
-
- data += 1; /* message reference */
-
- if ( sms_get_address( &data, end, &address ) < 0 )
- goto Fail;
-
- data += 1; /* skip protocol identifier */
- coding = sms_get_coding_scheme( &data, end );
- if (coding == SMS_CODING_SCHEME_UNKNOWN)
- goto Fail;
-
- gsm_rope_init_alloc( rope, 0 );
- if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 ) {
- gsm_rope_done( rope );
- goto Fail;
- }
-
- result = rope->pos;
- if (utf8len > result)
- utf8len = result;
-
- if (utf8len > 0)
- memcpy( utf8, rope->data, utf8len );
-
- gsm_rope_done( rope );
- return result;
- }
- }
-Fail:
- return -1;
-}
-
-static cbytes_t
-smspdu_get_user_data_ref( SmsPDU pdu )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
- int len;
-
- /* if there is no user-data-header, there is no message reference here */
- if ((mtiByte & 0x40) == 0)
- goto Fail;
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER */
- if ( sms_skip_address( &data, end ) < 0 )
- goto Fail;
-
- data += 2; /* skip protocol identifier + coding scheme */
-
- if ( sms_skip_timestamp( &data, end ) < 0 )
- goto Fail;
-
- break;
-
- case 1: /* SMS_PDU_SUBMIT */
- data += 1; /* skip message reference */
-
- if ( sms_skip_address( &data, end ) < 0 )
- goto Fail;
-
- data += 2; /* protocol identifier + oding schene */
- if ( sms_skip_validity_period( &data, end, mtiByte ) < 0 )
- goto Fail;
-
- break;
-
- default:
- goto Fail;
- }
-
- /* skip user-data length */
- if (data+1 >= end)
- goto Fail;
-
- len = data[1];
- data += 2;
-
- while (len >= 2 && data + 2 <= end) {
- int htype = data[0];
- int hlen = data[1];
-
- if (htype == 00 && hlen == 3 && data + 5 <= end) {
- return data + 2;
- }
-
- data += hlen;
- len -= hlen - 2;
- }
-Fail:
- return NULL;
-}
-
-int
-smspdu_get_ref( SmsPDU pdu )
-{
- cbytes_t user_ref = smspdu_get_user_data_ref( pdu );
-
- if (user_ref != NULL)
- {
- return user_ref[0];
- }
- else
- {
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- if ((mtiByte & 3) == 1) {
- /* try to extract directly the reference for a SMS-SUBMIT */
- if (data < end)
- return data[0];
- }
- }
- return -1;
-}
-
-int
-smspdu_get_max_index( SmsPDU pdu )
-{
- cbytes_t user_ref = smspdu_get_user_data_ref( pdu );
-
- if (user_ref != NULL) {
- return user_ref[1];
- } else {
- return 1;
- }
-}
-
-int
-smspdu_get_cur_index( SmsPDU pdu )
-{
- cbytes_t user_ref = smspdu_get_user_data_ref( pdu );
-
- if (user_ref != NULL) {
- return user_ref[2] - 1;
- } else {
- return 0;
- }
-}
-
-
-static void
-gsm_rope_add_sms_user_header( GsmRope rope,
- int ref_number,
- int pdu_count,
- int pdu_index )
-{
- gsm_rope_add_c( rope, 0x05 ); /* total header length == 5 bytes */
- gsm_rope_add_c( rope, 0x00 ); /* element id: concatenated message reference number */
- gsm_rope_add_c( rope, 0x03 ); /* element len: 3 bytes */
- gsm_rope_add_c( rope, (byte_t)ref_number ); /* reference number */
- gsm_rope_add_c( rope, (byte_t)pdu_count ); /* max pdu index */
- gsm_rope_add_c( rope, (byte_t)pdu_index+1 ); /* current pdu index */
-}
-
-/* write a SMS-DELIVER PDU into a rope */
-static void
-gsm_rope_add_sms_deliver_pdu( GsmRope rope,
- cbytes_t utf8,
- int utf8len,
- int use_gsm7,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp,
- int ref_num,
- int pdu_count,
- int pdu_index)
-{
- int coding;
- int mtiByte = 0x20; /* message type - SMS DELIVER */
-
- if (pdu_count > 1)
- mtiByte |= 0x40; /* user data header indicator */
-
- gsm_rope_add_c( rope, 0 ); /* no SC Address */
- gsm_rope_add_c( rope, mtiByte ); /* message type - SMS-DELIVER */
- gsm_rope_add_address( rope, sender_address );
- gsm_rope_add_c( rope, 0 ); /* protocol identifier */
-
- /* data coding scheme - GSM 7 bits / no class - or - 16-bit UCS2 / class 1 */
- coding = (use_gsm7 ? 0x00 : 0x09);
-
- gsm_rope_add_c( rope, coding ); /* data coding scheme */
- gsm_rope_add_timestamp( rope, timestamp ); /* service center timestamp */
-
- if (use_gsm7) {
- bytes_t dst;
- int count = utf8_to_gsm7( utf8, utf8len, NULL, 0 );
- int pad = 0;
-
- assert( count <= MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE );
-
- if (pdu_count > 1)
- {
- int headerBits = 6*8; /* 6 is size of header in bytes */
- int headerSeptets = headerBits / 7;
- if (headerBits % 7 > 0)
- headerSeptets += 1;
-
- pad = headerSeptets*7 - headerBits;
-
- gsm_rope_add_c( rope, count + headerSeptets );
- gsm_rope_add_sms_user_header(rope, ref_num, pdu_count, pdu_index);
- }
- else
- gsm_rope_add_c( rope, count );
-
- count = (count*7+pad+7)/8; /* convert to byte count */
-
- dst = gsm_rope_reserve( rope, count );
- if (dst != NULL) {
- utf8_to_gsm7( utf8, utf8len, dst, pad );
- }
- } else {
- bytes_t dst;
- int count = utf8_to_ucs2( utf8, utf8len, NULL );
-
- assert( count*2 <= MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE );
-
- if (pdu_count > 1)
- {
- gsm_rope_add_c( rope, count*2 + 6 );
- gsm_rope_add_sms_user_header( rope, ref_num, pdu_count, pdu_index );
- }
- else
- gsm_rope_add_c( rope, count*2 );
-
- gsm_rope_add_c( rope, count*2 );
- dst = gsm_rope_reserve( rope, count*2 );
- if (dst != NULL) {
- utf8_to_ucs2( utf8, utf8len, dst );
- }
- }
-}
-
-
-static SmsPDU
-smspdu_create_deliver( cbytes_t utf8,
- int utf8len,
- int use_gsm7,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp,
- int ref_num,
- int pdu_count,
- int pdu_index )
-{
- SmsPDU p;
- GsmRopeRec rope[1];
- int size;
-
- p = calloc( sizeof(*p), 1 );
- if (!p) goto Exit;
-
- gsm_rope_init( rope );
- gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7,
- sender_address, timestamp,
- ref_num, pdu_count, pdu_index);
- if (rope->error)
- goto Fail;
-
- gsm_rope_init_alloc( rope, rope->pos );
-
- gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7,
- sender_address, timestamp,
- ref_num, pdu_count, pdu_index );
-
- p->base = gsm_rope_done_acquire( rope, &size );
- if (p->base == NULL)
- goto Fail;
-
- p->end = p->base + size;
- p->tpdu = p->base + 1;
-Exit:
- return p;
-
-Fail:
- free(p);
- return NULL;
-}
-
-
-void
-smspdu_free_list( SmsPDU* pdus )
-{
- if (pdus) {
- int nn;
- for (nn = 0; pdus[nn] != NULL; nn++)
- smspdu_free( pdus[nn] );
-
- free( pdus );
- }
-}
-
-
-
-SmsPDU*
-smspdu_create_deliver_utf8( const unsigned char* utf8,
- int utf8len,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp )
-{
- SmsTimeStampRec ts0;
- int use_gsm7;
- int count, block;
- int num_pdus = 0;
- int leftover = 0;
- SmsPDU* list = NULL;
-
- static unsigned char ref_num = 0;
-
- if (timestamp == NULL) {
- sms_timestamp_now( &ts0 );
- timestamp = &ts0;
- }
-
- /* can we encode the message with the GSM 7-bit alphabet ? */
- use_gsm7 = utf8_check_gsm7( utf8, utf8len );
-
- /* count the number of SMS PDUs we'll need */
- block = MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE;
-
- if (use_gsm7) {
- count = utf8_to_gsm7( utf8, utf8len, NULL, 0 );
- } else {
- count = utf8_to_ucs2( utf8, utf8len, NULL );
- block = MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE;
- }
-
- num_pdus = count / block;
- leftover = count - num_pdus*block;
- if (leftover > 0)
- num_pdus += 1;
-
- list = calloc( sizeof(SmsPDU*), num_pdus + 1 );
- if (list == NULL)
- return NULL;
-
- /* now create each SMS PDU */
- {
- cbytes_t src = utf8;
- cbytes_t src_end = utf8 + utf8len;
- int nn;
-
- for (nn = 0; nn < num_pdus; nn++)
- {
- int skip = block;
- cbytes_t src_next;
-
- if (leftover > 0 && nn == num_pdus-1)
- skip = leftover;
-
- src_next = utf8_skip_gsm7( src, src_end, skip );
-
- list[nn] = smspdu_create_deliver( src, src_next - src, use_gsm7, sender_address, timestamp,
- ref_num, num_pdus, nn );
- if (list[nn] == NULL)
- goto Fail;
-
- src = src_next;
- }
- }
-
- ref_num++;
- return list;
-
-Fail:
- smspdu_free_list(list);
- return NULL;
-}
-
-
-SmsPDU
-smspdu_create_from_hex( const char* hex, int hexlen )
-{
- SmsPDU p;
- cbytes_t data;
-
- p = calloc( sizeof(*p), 1 );
- if (!p) goto Exit;
-
- p->base = malloc( (hexlen+1)/2 );
- if (p->base == NULL) {
- free(p);
- p = NULL;
- goto Exit;
- }
-
- if ( gsm_hex_to_bytes( (cbytes_t)hex, hexlen, p->base ) < 0 )
- goto Fail;
-
- p->end = p->base + (hexlen+1)/2;
-
- data = p->base;
- if ( sms_skip_sc_address( &data, p->end ) < 0 )
- goto Fail;
-
- p->tpdu = (bytes_t) data;
-
-Exit:
- return p;
-
-Fail:
- free(p->base);
- free(p);
- return NULL;
-}
-
-int
-smspdu_to_hex( SmsPDU pdu, char* hex, int hexlen )
-{
- int result = (pdu->end - pdu->base)*2;
- int nn;
-
- if (hexlen > result)
- hexlen = result;
-
- for (nn = 0; nn*2 < hexlen; nn++) {
- gsm_hex_from_byte( &hex[nn*2], pdu->base[nn] );
- }
- return result;
-}
-
-
-/** SMS SUBMIT RECEIVER
- ** collects one or more SMS-SUBMIT PDUs to generate a single message to deliver
- **/
-
-typedef struct SmsFragmentRec {
- struct SmsFragmentRec* next;
- SmsAddressRec from[1];
- byte_t ref;
- byte_t max;
- byte_t count;
- int index;
- SmsPDU* pdus;
-
-} SmsFragmentRec, *SmsFragment;
-
-
-typedef struct SmsReceiverRec {
- int last;
- SmsFragment fragments;
-
-} SmsReceiverRec;
-
-
-static void
-sms_fragment_free( SmsFragment frag )
-{
- int nn;
-
- for (nn = 0; nn < frag->max; nn++) {
- if (frag->pdus[nn] != NULL) {
- smspdu_free( frag->pdus[nn] );
- frag->pdus[nn] = NULL;
- }
- }
- frag->pdus = NULL;
- frag->count = 0;
- frag->max = 0;
- frag->index = 0;
- free( frag );
-}
-
-static SmsFragment
-sms_fragment_alloc( SmsReceiver rec, const SmsAddressRec* from, int ref, int max )
-{
- SmsFragment frag = calloc(sizeof(*frag) + max*sizeof(SmsPDU), 1 );
-
- if (frag != NULL) {
- frag->from[0] = from[0];
- frag->ref = ref;
- frag->max = max;
- frag->pdus = (SmsPDU*)(frag + 1);
- frag->index = ++rec->last;
- }
- return frag;
-}
-
-
-
-SmsReceiver sms_receiver_create( void )
-{
- SmsReceiver rec = calloc(sizeof(*rec),1);
- return rec;
-}
-
-void
-sms_receiver_destroy( SmsReceiver rec )
-{
- while (rec->fragments) {
- SmsFragment frag = rec->fragments;
- rec->fragments = frag->next;
- sms_fragment_free(frag);
- }
-}
-
-static SmsFragment*
-sms_receiver_find_p( SmsReceiver rec, const SmsAddressRec* from, int ref )
-{
- SmsFragment* pnode = &rec->fragments;
- SmsFragment node;
-
- for (;;) {
- node = *pnode;
- if (node == NULL)
- break;
- if (node->ref == ref && sms_address_eq( node->from, from ))
- break;
- pnode = &node->next;
- }
- return pnode;
-}
-
-static SmsFragment*
-sms_receiver_find_index_p( SmsReceiver rec, int index )
-{
- SmsFragment* pnode = &rec->fragments;
- SmsFragment node;
-
- for (;;) {
- node = *pnode;
- if (node == NULL)
- break;
- if (node->index == index)
- break;
- pnode = &node->next;
- }
- return pnode;
-}
-
-int
-sms_receiver_add_submit_pdu( SmsReceiver rec, SmsPDU submit_pdu )
-{
- SmsAddressRec from[1];
- int ref, max, cur;
- SmsFragment* pnode;
- SmsFragment frag;
-
- if ( smspdu_get_receiver_address( submit_pdu, from ) < 0 ) {
- D( "%s: could not extract receiver address\n", __FUNCTION__ );
- return -1;
- }
-
- ref = smspdu_get_ref( submit_pdu );
- if (ref < 0) {
- D( "%s: could not extract message reference from pdu\n", __FUNCTION__ );
- return -1;
- }
- max = smspdu_get_max_index( submit_pdu );
- if (max < 0) {
- D( "%s: invalid max fragment value: %d should be >= 1\n",
- __FUNCTION__, max );
- return -1;
- }
- pnode = sms_receiver_find_p( rec, from, ref );
- frag = *pnode;
- if (frag == NULL) {
- frag = sms_fragment_alloc( rec, from, ref, max );
- if (frag == NULL) {
- D("%s: not enough memory to allocate new fragment\n", __FUNCTION__ );
- return -1;
- }
- if (D_ACTIVE) {
- char tmp[32];
- int len;
-
- len = sms_address_to_str( from, tmp, sizeof(tmp) );
- if (len < 0) {
- strcpy( tmp, "<unknown>" );
- len = strlen(tmp);
- }
- D("%s: created SMS index %d, from %.*s, ref %d, max %d\n", __FUNCTION__,
- frag->index, len, tmp, frag->ref, frag->max);
- }
- *pnode = frag;
- }
-
- cur = smspdu_get_cur_index( submit_pdu );
- if (cur < 0) {
- D("%s: SMS fragment index is too small: %d should be >= 1\n", __FUNCTION__, cur+1 );
- return -1;
- }
- if (cur >= max) {
- D("%s: SMS fragment index is too large (%d >= %d)\n", __FUNCTION__, cur, max);
- return -1;
- }
- if ( frag->pdus[cur] != NULL ) {
- D("%s: receiving duplicate SMS fragment for %d/%d, ref=%d, discarding old one\n",
- __FUNCTION__, cur+1, max, ref);
- smspdu_free( frag->pdus[cur] );
- frag->count -= 1;
- }
- frag->pdus[cur] = submit_pdu;
- frag->count += 1;
-
- if (frag->count >= frag->max) {
- /* yes, we received all fragments for this SMS */
- D( "%s: SMS index %d, received all %d fragments\n", __FUNCTION__, frag->index, frag->count );
- return frag->index;
- }
- else {
- /* still waiting for more */
- D( "%s: SMS index %d, received %d/%d, waiting for %d more\n", __FUNCTION__,
- frag->index, cur+1, max, frag->max - frag->count );
- return 0;
- }
-}
-
-
-int
-sms_receiver_get_text_message( SmsReceiver rec, int index, bytes_t utf8, int utf8len )
-{
- SmsFragment* pnode = sms_receiver_find_index_p( rec, index );
- SmsFragment frag = *pnode;
- int nn, total;
-
- if (frag == NULL) {
- D( "%s: invalid SMS index %d\n", __FUNCTION__, index );
- return -1;
- }
- if (frag->count != frag->max) {
- D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__,
- frag->index, frag->max - frag->count );
- return -1;
- }
- /* get the size of all combined text */
- total = 0;
- for ( nn = 0; nn < frag->count; nn++ ) {
- int partial;
- if (utf8 && utf8len > 0) {
- partial = smspdu_get_text_message( frag->pdus[nn], utf8, utf8len );
- utf8 += partial;
- utf8len -= partial;
- } else {
- partial = smspdu_get_text_message( frag->pdus[nn], NULL, 0 );
- }
- total += partial;
- }
- return total;
-}
-
-
-static void
-sms_receiver_remove( SmsReceiver rec, int index )
-{
- SmsFragment* pnode = sms_receiver_find_index_p( rec, index );
- SmsFragment frag = *pnode;
- if (frag != NULL) {
- *pnode = frag->next;
- sms_fragment_free(frag);
- }
-}
-
-
-SmsPDU*
-sms_receiver_create_deliver( SmsReceiver rec, int index, const SmsAddressRec* from )
-{
- SmsPDU* result = NULL;
- SmsFragment* pnode = sms_receiver_find_index_p( rec, index );
- SmsFragment frag = *pnode;
- SmsTimeStampRec now[1];
- int nn, total;
- bytes_t utf8;
- int utf8len;
-
- if (frag == NULL) {
- D( "%s: invalid SMS index %d\n", __FUNCTION__, index );
- return NULL;
- }
- if (frag->count != frag->max) {
- D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__,
- frag->index, frag->max - frag->count );
- return NULL;
- }
-
- /* get the combined text message */
- utf8len = sms_receiver_get_text_message( rec, index, NULL, 0 );
- if (utf8len < 0)
- goto Exit;
-
- utf8 = malloc( utf8len + 1 );
- if (utf8 == NULL) {
- D( "%s: not enough memory to allocate %d bytes\n",
- __FUNCTION__, utf8len+1 );
- goto Exit;
- }
-
- total = 0;
- for ( nn = 0; nn < frag->count; nn++ ) {
- total += smspdu_get_text_message( frag->pdus[nn], utf8 + total, utf8len - total );
- }
-
- sms_timestamp_now( now );
-
- result = smspdu_create_deliver_utf8( utf8, utf8len, from, now );
-
- free(utf8);
-
-Exit:
- sms_receiver_remove( rec, index );
- return result;
-}
-
diff --git a/telephony/sms.h b/telephony/sms.h
deleted file mode 100644
index 7059ee3..0000000
--- a/telephony/sms.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_sms_h
-#define _android_sms_h
-
-#include <time.h>
-
-/** MESSAGE TEXT
- **/
-/* convert a quoted message text into a utf8 string. Note: you can use 'str' as the destination buffer
- * with the current implementation. always return the number of utf8 bytes corresponding to the original
- * message string, even if utf8 is NULL and utf8len is 0
- */
-extern int sms_utf8_from_message_str( const char* str, int strlen, unsigned char* utf8, int utf8len );
-
-/* the equivalent in the opposite direction
- */
-extern int sms_utf8_to_message_str( const unsigned char* utf8, int utf8len, char* str, int strlen );
-
-/** TIMESTAMPS
- **/
-
-/* An SMS timestamp structure */
-typedef struct {
- unsigned char data[7];
-} SmsTimeStampRec, *SmsTimeStamp;
-
-extern void sms_timestamp_now( SmsTimeStamp stamp );
-extern int sms_timestamp_to_tm( SmsTimeStamp stamp, struct tm* tm );
-
-/** SMS ADDRESSES
- **/
-
-#define SMS_ADDRESS_MAX_SIZE 16
-
-typedef struct {
- unsigned char len;
- unsigned char toa;
- unsigned char data[ SMS_ADDRESS_MAX_SIZE ];
-} SmsAddressRec, *SmsAddress;
-
-extern int sms_address_from_str( SmsAddress address, const char* src, int srclen );
-extern int sms_address_to_str( SmsAddress address, char* src, int srclen );
-
-extern int sms_address_from_bytes( SmsAddress address, const unsigned char* buf, int buflen );
-extern int sms_address_to_bytes ( SmsAddress address, unsigned char* buf, int bufsize );
-extern int sms_address_from_hex ( SmsAddress address, const char* hex, int hexlen );
-extern int sms_address_to_hex ( SmsAddress address, char* hex, int hexsize );
-
-/** SMS PROTOCOL DATA UNITS
- **/
-
-typedef struct SmsPDURec* SmsPDU;
-
-extern SmsPDU* smspdu_create_deliver_utf8( const unsigned char* utf8,
- int utf8len,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp );
-
-extern void smspdu_free_list( SmsPDU* pdus );
-
-extern SmsPDU smspdu_create_from_hex( const char* hex, int hexlen );
-
-extern int smspdu_to_hex( SmsPDU pdu, char* hex, int hexsize );
-
-/* free a given SMS PDU */
-extern void smspdu_free( SmsPDU pdu );
-
-typedef enum {
- SMS_PDU_INVALID = 0,
- SMS_PDU_DELIVER,
- SMS_PDU_SUBMIT,
- SMS_PDU_STATUS_REPORT
-} SmsPduType;
-
-extern SmsPduType smspdu_get_type( SmsPDU pdu );
-
-/* retrieve the sender address of a SMS-DELIVER pdu, returns -1 otherwise */
-extern int smspdu_get_sender_address( SmsPDU pdu, SmsAddress address );
-
-/* retrieve the service center timestamp of a SMS-DELIVER pdu, return -1 otherwise */
-extern int smspdu_get_sc_timestamp( SmsPDU pdu, SmsTimeStamp timestamp );
-
-/* retrieve the receiver address of a SMS-SUBMIT pdu, return -1 otherwise */
-extern int smspdu_get_receiver_address( SmsPDU pdu, SmsAddress address );
-
-extern int smspdu_get_ref ( SmsPDU pdu );
-extern int smspdu_get_max_index( SmsPDU pdu );
-extern int smspdu_get_cur_index( SmsPDU pdu );
-
-/* get the message embedded in a SMS PDU as a utf8 byte array, returns the length of the message in bytes */
-/* or -1 in case of error */
-extern int smspdu_get_text_message( SmsPDU pdu, unsigned char* utf8, int utf8len );
-
-/** SMS SUBMIT RECEIVER
- ** collects one or more SMS-SUBMIT PDUs to generate a single message to deliver
- **/
-
-typedef struct SmsReceiverRec *SmsReceiver;
-
-extern SmsReceiver sms_receiver_create( void );
-extern void sms_receiver_destroy( SmsReceiver rec );
-
-extern int sms_receiver_add_submit_pdu( SmsReceiver rec, SmsPDU submit_pdu );
-extern int sms_receiver_get_text_message( SmsReceiver rec, int index, unsigned char* utf8, int utf8len );
-extern SmsPDU* sms_receiver_create_deliver( SmsReceiver rec, int index, const SmsAddressRec* from );
-
-#endif /* _android_sms_h */
diff --git a/telephony/sysdeps.h b/telephony/sysdeps.h
deleted file mode 100644
index 19ca8d3..0000000
--- a/telephony/sysdeps.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef __sysdeps_h__
-#define __sysdeps_h__
-
-/* system-dependent platform abstraction used by the emulated GSM modem
- */
-
-/* to be called before anything else */
-
-extern void sys_main_init( void );
-
-/** callbacks
- **/
-typedef void (*SysCallback)( void* opaque );
-
-/** events
- **/
-enum {
- SYS_EVENT_READ = 0x01,
- SYS_EVENT_WRITE = 0x02,
- SYS_EVENT_ERROR = 0x04,
- SYS_EVENT_ALL = 0x07
-};
-
-/** channels
- **/
-typedef struct SysChannelRec_* SysChannel;
-
-typedef void (*SysChannelCallback)( void* opaque, int event_flags );
-
-/* XXX: TODO: channel creation functions */
-extern SysChannel sys_channel_create_tcp_server( int port );
-extern SysChannel sys_channel_create_tcp_handler( SysChannel server_channel );
-extern SysChannel sys_channel_create_tcp_client( const char* hostname, int port );
-extern int sys_channel_set_non_block( SysChannel channel );
-
-extern void sys_channel_on( SysChannel channel,
- int event_flags,
- SysChannelCallback event_callback,
- void* event_opaqe );
-
-extern int sys_channel_read( SysChannel channel, void* buffer, int size );
-
-extern int sys_channel_write( SysChannel channel, const void* buffer, int size );
-
-extern void sys_channel_close( SysChannel channel );
-
-
-/** time measurement
- **/
-typedef long long SysTime;
-
-extern SysTime sys_time_now( void );
-
-/** timers
- **/
-typedef struct SysTimerRec_* SysTimer;
-
-extern SysTimer sys_timer_create( void );
-extern void sys_timer_set( SysTimer timer, SysTime when, SysCallback callback, void* opaque );
-extern void sys_timer_unset( SysTimer timer );
-extern void sys_timer_destroy( SysTimer timer );
-
-extern long long sys_time_ms( void );
-
-/** main loop (may return immediately on some platform)
- **/
-extern int sys_main_loop( void );
-
-#endif /* __sysdeps_h__ */
diff --git a/telephony/sysdeps_posix.c b/telephony/sysdeps_posix.c
deleted file mode 100644
index 8c5eb12..0000000
--- a/telephony/sysdeps_posix.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sysdeps.h"
-#include <assert.h>
-#include <unistd.h>
-#include <sys/select.h>
-#include <errno.h>
-#include <memory.h>
-#include <stdio.h>
-#ifndef HAVE_WINSOCK
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#endif
-
-/** QUEUE
- **/
-#define SYS_MAX_QUEUE 16
-
-typedef struct {
- int start;
- int end;
- void* pending[ SYS_MAX_QUEUE ];
-}
-SysQueueRec, *SysQueue;
-
-static void
-sys_queue_reset( SysQueue queue )
-{
- queue->start = queue->end = 0;
-}
-
-static void
-sys_queue_add( SysQueue queue, void* item )
-{
- assert( queue->end - queue->start < SYS_MAX_QUEUE );
- assert( queue->start == 0 );
- assert( item != NULL );
- queue->pending[ queue->end++ ] = item;
-}
-
-#if 0
-static void
-sys_queue_remove( SysQueue queue, void* item )
-{
- int nn, count;
- assert( queue->end > queue->start );
- assert( item != NULL );
- count = queue->end - queue->start;
- for ( nn = queue->start; count > 0; ++nn, --count ) {
- if ( queue->pending[nn] == item ) {
- queue->pending[nn] = queue->pending[nn+count-1];
- queue->end -= 1;
- break;
- }
- }
- assert( 0 && "sys_queue_remove: item not found" );
-}
-#endif
-
-static void*
-sys_queue_get( SysQueue queue )
-{
- if (queue->end > queue->start) {
- return queue->pending[ queue->start++ ];
- }
- return NULL;
-}
-
-/** CHANNELS
- **/
-typedef struct SysChannelRec_ {
- SysChannel next;
- int fd;
- char active;
- char pending;
- char closed;
- int wanted;
- int ready;
- SysChannelCallback callback;
- void* opaque;
-} SysChannelRec;
-
-
-/*** channel allocation ***/
-#define SYS_EVENT_MAX 3
-#define SYS_MAX_CHANNELS 16
-
-static SysChannelRec _s_channels0[ SYS_MAX_CHANNELS ];
-static SysChannel _s_free_channels;
-
-static SysChannel
-sys_channel_alloc( void )
-{
- SysChannel channel = _s_free_channels;
- assert( channel != NULL && "out of free channels" );
- _s_free_channels = channel->next;
- channel->next = NULL;
- channel->active = 0;
- channel->closed = 0;
- channel->pending = 0;
- channel->wanted = 0;
- return channel;
-}
-
-static void
-sys_channel_free( SysChannel channel )
-{
- if (channel->fd >= 0) {
-#ifdef _WIN32
- shutdown( channel->fd, SD_BOTH );
-#else
- shutdown( channel->fd, SHUT_RDWR );
-#endif
- close(channel->fd);
- channel->fd = -1;
- }
- channel->wanted = 0;
- channel->ready = 0;
- channel->callback = NULL;
-
- channel->next = _s_free_channels;
- _s_free_channels = channel;
-}
-
-
-/* list of active channels */
-static SysChannel _s_channels;
-
-/* used by select to wait on channel events */
-static fd_set _s_fdsets[SYS_EVENT_MAX];
-static int _s_maxfd;
-
-static void
-sys_channel_deactivate( SysChannel channel )
-{
- assert( channel->active != 0 );
- SysChannel *pnode = &_s_channels;
- for (;;) {
- SysChannel node = *pnode;
- assert( node != NULL );
- if (node == channel)
- break;
- pnode = &node->next;
- }
- *pnode = channel->next;
- channel->next = NULL;
- channel->active = 0;
-}
-
-static void
-sys_channel_activate( SysChannel channel )
-{
- assert( channel->active == 0 );
- channel->next = _s_channels;
- _s_channels = channel;
- channel->active = 1;
- if (channel->fd > _s_maxfd)
- _s_maxfd = channel->fd;
-}
-
-
-/* queue of pending channels */
-static SysQueueRec _s_pending_channels[1];
-
-
-static void
-sys_init_channels( void )
-{
- int nn;
-
- for (nn = 0; nn < SYS_MAX_CHANNELS-1; nn++)
- _s_channels0[nn].next = &_s_channels0[nn+1];
- _s_free_channels = &_s_channels0[0];
-
- for (nn = 0; nn < SYS_EVENT_MAX; nn++)
- FD_ZERO( &_s_fdsets[nn] );
-
- _s_maxfd = -1;
-
- sys_queue_reset( _s_pending_channels );
-}
-
-
-void
-sys_channel_on( SysChannel channel,
- int events,
- SysChannelCallback callback,
- void* opaque )
-{
- int adds = events & ~channel->wanted;
- int removes = channel->wanted & ~events;
-
- channel->wanted = events;
- channel->callback = callback;
- channel->opaque = opaque;
-
- /* update global fdsets */
- if (adds) {
- int ee;
- for (ee = 0; ee < SYS_EVENT_MAX; ee++)
- if (adds & (1 << ee))
- FD_SET( channel->fd, &_s_fdsets[ee] );
- }
- if (removes) {
- int ee;
- for (ee = 0; ee < SYS_EVENT_MAX; ee++)
- if (removes & (1 << ee))
- FD_CLR( channel->fd, &_s_fdsets[ee] );
- }
- if (events && !channel->active) {
- sys_channel_activate( channel );
- }
- else if (!events && channel->active) {
- sys_channel_deactivate( channel );
- }
-}
-
-int
-sys_channel_read( SysChannel channel, void* buffer, int size )
-{
- char* buff = buffer;
- int count = 0;
-
- assert( !channel->closed );
-
- while (size > 0) {
- int len = read(channel->fd, buff, size);
- if (len < 0) {
- if (errno == EINTR)
- continue;
- if (count == 0)
- count = -1;
- break;
- }
- buff += len;
- size -= len;
- count += len;
- }
- return count;
-}
-
-
-int
-sys_channel_write( SysChannel channel, const void* buffer, int size )
-{
- const char* buff = buffer;
- int count = 0;
-
- assert( !channel->closed );
-
- while (size > 0) {
- int len = write(channel->fd, buff, size);
- if (len < 0) {
- if (errno == EINTR)
- continue;
- if (count == 0)
- count = -1;
- break;
- }
- buff += len;
- size -= len;
- count += len;
- }
- return count;
-}
-
-
-void
-sys_channel_close( SysChannel channel )
-{
- if (channel->active) {
- sys_channel_on( channel, 0, NULL, NULL );
- }
-
- if (channel->pending) {
- /* we can't free the channel right now because it */
- /* is in the pending list, set a flag */
- channel->closed = 1;
- return;
- }
-
- if (!channel->closed) {
- channel->closed = 1;
- }
-
- sys_channel_free( channel );
-}
-
-/** time measurement
- **/
-SysTime sys_time_ms( void )
-{
- struct timeval tv;
- gettimeofday( &tv, NULL );
- return (SysTime)(tv.tv_usec / 1000) + (SysTime)tv.tv_sec * 1000;
-}
-
-/** timers
- **/
-typedef struct SysTimerRec_
-{
- SysTimer next;
- SysTime when;
- SysCallback callback;
- void* opaque;
-} SysTimerRec;
-
-#define SYS_MAX_TIMERS 16
-
-static SysTimerRec _s_timers0[ SYS_MAX_TIMERS ];
-static SysTimer _s_free_timers;
-static SysTimer _s_timers;
-
-static SysQueueRec _s_pending_timers[1];
-
-
-static void
-sys_init_timers( void )
-{
- int nn;
- for (nn = 0; nn < SYS_MAX_TIMERS-1; nn++) {
- _s_timers0[nn].next = & _s_timers0[nn+1];
- }
- _s_free_timers = &_s_timers0[0];
-
- sys_queue_reset( _s_pending_timers );
-}
-
-
-SysTimer sys_timer_create( void )
-{
- SysTimer timer = _s_free_timers;
- assert( timer != NULL && "too many timers allocated" );
- _s_free_timers = timer->next;
- timer->next = NULL;
- return timer;
-}
-
-
-void sys_timer_unset( SysTimer timer )
-{
- if (timer->callback != NULL) {
- SysTimer *pnode, node;
- pnode = &_s_timers;
- for (;;) {
- node = *pnode;
- if (node == NULL)
- break;
- if (node == timer) {
- *pnode = node->next;
- break;
- }
- pnode = &node->next;
- }
- timer->next = NULL;
- timer->callback = NULL;
- timer->opaque = NULL;
- }
-}
-
-
-void sys_timer_set( SysTimer timer,
- SysTime when,
- SysCallback callback,
- void* opaque )
-{
- if (timer->callback != NULL)
- sys_timer_unset(timer);
-
- if (callback != NULL) {
- SysTime now = sys_time_ms();
-
- if (now >= when) {
- callback( opaque );
- } else {
- SysTimer *pnode, node;
- pnode = &_s_timers;
- for (;;) {
- node = *pnode;
- if (node == NULL || node->when >= when) {
- break;
- }
- pnode = &node->next;
- }
- timer->next = *pnode;
- *pnode = timer;
- timer->when = when;
- timer->callback = callback;
- timer->opaque = opaque;
- }
- }
-}
-
-
-void sys_timer_destroy( SysTimer timer )
-{
- assert( timer != NULL && "sys_timer_destroy: bad argument" );
- if (timer->callback != NULL)
- sys_timer_unset(timer);
-
- timer->next = _s_free_timers;
- _s_free_timers = timer;
-}
-
-
-static void
-sys_single_loop( void )
-{
- fd_set rfd, wfd, efd;
- struct timeval timeout_tv, *timeout = NULL;
- int n;
-
- memcpy(&rfd, &_s_fdsets[0], sizeof(fd_set));
- memcpy(&wfd, &_s_fdsets[1], sizeof(fd_set));
- memcpy(&efd, &_s_fdsets[2], sizeof(fd_set));
-
- if ( _s_timers != NULL ) {
- SysTime now = sys_time_ms();
- SysTimer first = _s_timers;
-
- timeout = &timeout_tv;
- if (first->when <= now) {
- timeout->tv_sec = 0;
- timeout->tv_usec = 0;
- } else {
- SysTime diff = first->when - now;
- timeout->tv_sec = diff / 1000;
- timeout->tv_usec = (diff - timeout->tv_sec*1000) * 1000;
- }
- }
-
- n = select( _s_maxfd+1, &rfd, &wfd, &efd, timeout);
- if(n < 0) {
- if(errno == EINTR) return;
- perror("select");
- return;
- }
-
- /* enqueue pending channels */
- {
- int i;
-
- sys_queue_reset( _s_pending_channels );
- for(i = 0; (i <= _s_maxfd) && (n > 0); i++)
- {
- int events = 0;
-
- if(FD_ISSET(i, &rfd)) events |= SYS_EVENT_READ;
- if(FD_ISSET(i, &wfd)) events |= SYS_EVENT_WRITE;
- if(FD_ISSET(i, &efd)) events |= SYS_EVENT_ERROR;
-
- if (events) {
- SysChannel channel;
-
- n--;
- for (channel = _s_channels; channel; channel = channel->next)
- {
- if (channel->fd != i)
- continue;
-
- channel->ready = events;
- channel->pending = 1;
- sys_queue_add( _s_pending_channels, channel );
- break;
- }
- }
- }
- }
-
- /* enqueue pending timers */
- {
- SysTimer timer = _s_timers;
- SysTime now = sys_time_ms();
-
- sys_queue_reset( _s_pending_timers );
- while (timer != NULL)
- {
- if (timer->when > now)
- break;
-
- sys_queue_add( _s_pending_timers, timer );
- _s_timers = timer = timer->next;
- }
- }
-}
-
-void sys_main_init( void )
-{
- sys_init_channels();
- sys_init_timers();
-}
-
-
-int sys_main_loop( void )
-{
- for (;;) {
- SysTimer timer;
- SysChannel channel;
-
- /* exit if we have nothing to do */
- if (_s_channels == NULL && _s_timers == NULL)
- break;
-
- sys_single_loop();
-
- while ((timer = sys_queue_get( _s_pending_timers )) != NULL) {
- timer->callback( timer->opaque );
- }
-
- while ((channel = sys_queue_get( _s_pending_channels )) != NULL) {
- int events;
-
- channel->pending = 0;
- if (channel->closed) {
- /* the channel was closed by a previous callback */
- sys_channel_close(channel);
- }
- events = channel->ready;
- channel->ready = 0;
- channel->callback( channel->opaque, events );
- }
- }
- return 0;
-}
-
-
-
-
-SysChannel
-sys_channel_create_tcp_server( int port )
-{
- SysChannel channel;
- int on = 1;
- const int BACKLOG = 4;
-
- channel = sys_channel_alloc();
- if (-1==(channel->fd=socket(AF_INET, SOCK_STREAM, 0))) {
- perror("socket");
- sys_channel_free( channel );
- return NULL;
- }
-
- /* Enable address re-use for server mode */
- if ( -1==setsockopt( channel->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) )) {
- perror("setsockopt(SO_REUSEADDR)");
- }
-
- {
- struct sockaddr_in servname;
- long in_addr = INADDR_ANY;
-
- servname.sin_family = AF_INET;
- servname.sin_port = htons(port);
-
- servname.sin_addr.s_addr=in_addr;
-
- if (-1==bind(channel->fd, (struct sockaddr*)&servname, sizeof(servname))) {
- perror("bind");
- sys_channel_close(channel);
- return NULL;
- }
-
- /* Listen but don't accept */
- if ( listen(channel->fd, BACKLOG) < 0 ) {
- perror("listen");
- sys_channel_close(channel);
- return NULL;
- }
- }
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_handler( SysChannel server_channel )
-{
- int on = 1;
- SysChannel channel = sys_channel_alloc();
-
- channel->fd = accept( server_channel->fd, NULL, 0 );
- if (channel->fd < 0) {
- perror( "accept" );
- sys_channel_free( channel );
- return NULL;
- }
-
- /* set to non-blocking and disable TCP Nagle algorithm */
- fcntl(channel->fd, F_SETFL, O_NONBLOCK);
- setsockopt(channel->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_client( const char* hostname, int port )
-{
- struct hostent* hp;
- struct sockaddr_in addr;
- SysChannel channel = sys_channel_alloc();
- int on = 1;
-
- hp = gethostbyname(hostname);
- if(hp == 0) {
- fprintf(stderr, "unknown host: %s\n", hostname);
- sys_channel_free(channel);
- return NULL;
- };
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = hp->h_addrtype;
- addr.sin_port = htons(port);
- memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
-
- channel->fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
- if(channel->fd < 0) {
- sys_channel_free(channel);
- return NULL;
- }
-
- if(connect( channel->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror( "connect" );
- sys_channel_free(channel);
- return NULL;
- }
-
- /* set to non-blocking and disable Nagle algorithm */
- fcntl(channel->fd, F_SETFL, O_NONBLOCK);
- setsockopt( channel->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on) );
- return channel;
-}
-
diff --git a/telephony/sysdeps_qemu.c b/telephony/sysdeps_qemu.c
deleted file mode 100644
index ec0b3f5..0000000
--- a/telephony/sysdeps_qemu.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sockets.h"
-#include "sysdeps.h"
-#include "qemu-timer.h"
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#endif
-
-#define DEBUG 1
-
-#define D_ACTIVE DEBUG
-
-#if DEBUG
-#define D(...) do { if (D_ACTIVE) fprintf(stderr, __VA_ARGS__); } while (0)
-#else
-#define D(...) ((void)0)
-#endif
-
-/** TIME
- **/
-
-SysTime
-sys_time_ms( void )
-{
- return qemu_get_clock( rt_clock );
-}
-
-/** TIMERS
- **/
-
-typedef struct SysTimerRec_ {
- QEMUTimer* timer;
- QEMUTimerCB* callback;
- void* opaque;
- SysTimer next;
-} SysTimerRec;
-
-#define MAX_TIMERS 32
-
-static SysTimerRec _s_timers0[ MAX_TIMERS ];
-static SysTimer _s_free_timers;
-
-static void
-sys_init_timers( void )
-{
- int nn;
- for (nn = 0; nn < MAX_TIMERS-1; nn++)
- _s_timers0[nn].next = _s_timers0 + (nn+1);
-
- _s_free_timers = _s_timers0;
-}
-
-static SysTimer
-sys_timer_alloc( void )
-{
- SysTimer timer = _s_free_timers;
-
- if (timer != NULL) {
- _s_free_timers = timer->next;
- timer->next = NULL;
- timer->timer = NULL;
- }
- return timer;
-}
-
-
-static void
-sys_timer_free( SysTimer timer )
-{
- if (timer->timer) {
- qemu_del_timer( timer->timer );
- qemu_free_timer( timer->timer );
- timer->timer = NULL;
- }
- timer->next = _s_free_timers;
- _s_free_timers = timer;
-}
-
-
-SysTimer sys_timer_create( void )
-{
- SysTimer timer = sys_timer_alloc();
- return timer;
-}
-
-void
-sys_timer_set( SysTimer timer, SysTime when, SysCallback _callback, void* opaque )
-{
- QEMUTimerCB* callback = (QEMUTimerCB*)_callback;
-
- if (callback == NULL) { /* unsetting the timer */
- if (timer->timer) {
- qemu_del_timer( timer->timer );
- qemu_free_timer( timer->timer );
- timer->timer = NULL;
- }
- timer->callback = callback;
- timer->opaque = NULL;
- return;
- }
-
- if ( timer->timer ) {
- if ( timer->callback == callback && timer->opaque == opaque )
- goto ReuseTimer;
-
- /* need to replace the timer */
- qemu_free_timer( timer->timer );
- }
-
- timer->timer = qemu_new_timer( rt_clock, callback, opaque );
- timer->callback = callback;
- timer->opaque = opaque;
-
-ReuseTimer:
- qemu_mod_timer( timer->timer, when );
-}
-
-void
-sys_timer_unset( SysTimer timer )
-{
- if (timer->timer) {
- qemu_del_timer( timer->timer );
- }
-}
-
-void
-sys_timer_destroy( SysTimer timer )
-{
- sys_timer_free( timer );
-}
-
-
-/** CHANNELS
- **/
-
-typedef struct SysChannelRec_ {
- int fd;
- SysChannelCallback callback;
- void* opaque;
- SysChannel next;
-} SysChannelRec;
-
-#define MAX_CHANNELS 16
-
-static SysChannelRec _s_channels0[ MAX_CHANNELS ];
-static SysChannel _s_free_channels;
-
-static void
-sys_init_channels( void )
-{
- int nn;
-
- for ( nn = 0; nn < MAX_CHANNELS-1; nn++ ) {
- _s_channels0[nn].next = _s_channels0 + (nn+1);
- }
- _s_free_channels = _s_channels0;
-}
-
-static SysChannel
-sys_channel_alloc( )
-{
- SysChannel channel = _s_free_channels;
- if (channel != NULL) {
- _s_free_channels = channel->next;
- channel->next = NULL;
- channel->fd = -1;
- channel->callback = NULL;
- channel->opaque = NULL;
- }
- return channel;
-}
-
-static void
-sys_channel_free( SysChannel channel )
-{
- if (channel->fd >= 0) {
- socket_close( channel->fd );
- channel->fd = -1;
- }
- channel->next = _s_free_channels;
- _s_free_channels = channel;
-}
-
-
-static void
-sys_channel_read_handler( void* _channel )
-{
- SysChannel channel = _channel;
- D( "%s: read event for channel %p:%d\n", __FUNCTION__,
- channel, channel->fd );
- channel->callback( channel->opaque, SYS_EVENT_READ );
-}
-
-static void
-sys_channel_write_handler( void* _channel )
-{
- SysChannel channel = _channel;
- D( "%s: write event for channel %p:%d\n", __FUNCTION__, channel, channel->fd );
- channel->callback( channel->opaque, SYS_EVENT_WRITE );
-}
-
-void
-sys_channel_on( SysChannel channel,
- int events,
- SysChannelCallback event_callback,
- void* event_opaque )
-{
- IOHandler* read_handler = NULL;
- IOHandler* write_handler = NULL;
-
- if (events & SYS_EVENT_READ) {
- read_handler = sys_channel_read_handler;
- }
- if (events & SYS_EVENT_WRITE) {
- write_handler = sys_channel_write_handler;
- }
- channel->callback = event_callback;
- channel->opaque = event_opaque;
- qemu_set_fd_handler( channel->fd, read_handler, write_handler, channel );
-}
-
-int
-sys_channel_read( SysChannel channel, void* buffer, int size )
-{
- int len = size;
- char* buf = (char*) buffer;
-
- while (len > 0) {
- int ret = socket_recv(channel->fd, buf, len);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK)
- break;
- D( "%s: after reading %d bytes, recv() returned error %d: %s\n",
- __FUNCTION__, size - len, errno, errno_str);
- return -1;
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- return size - len;
-}
-
-
-int
-sys_channel_write( SysChannel channel, const void* buffer, int size )
-{
- int len = size;
- const char* buf = (const char*) buffer;
-
- while (len > 0) {
- int ret = socket_send(channel->fd, buf, len);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK)
- break;
- D( "%s: send() returned error %d: %s\n",
- __FUNCTION__, errno, errno_str);
- return -1;
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- return size - len;
-}
-
-void sys_channel_close( SysChannel channel )
-{
- qemu_set_fd_handler( channel->fd, NULL, NULL, NULL );
- sys_channel_free( channel );
-}
-
-void sys_main_init( void )
-{
- sys_init_channels();
- sys_init_timers();
-}
-
-
-int sys_main_loop( void )
-{
- /* no looping, qemu has its own event loop */
- return 0;
-}
-
-
-
-
-SysChannel
-sys_channel_create_tcp_server( int port )
-{
- SysChannel channel = sys_channel_alloc();
-
- channel->fd = socket_anyaddr_server( port, SOCKET_STREAM );
- if (channel->fd < 0) {
- D( "%s: failed to created network socket on TCP:%d\n",
- __FUNCTION__, port );
- sys_channel_free( channel );
- return NULL;
- }
-
- D( "%s: server channel %p:%d now listening on port %d\n",
- __FUNCTION__, channel, channel->fd, port );
-
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_handler( SysChannel server_channel )
-{
- SysChannel channel = sys_channel_alloc();
-
- D( "%s: creating handler from server channel %p:%d\n", __FUNCTION__,
- server_channel, server_channel->fd );
-
- channel->fd = socket_accept_any( server_channel->fd );
- if (channel->fd < 0) {
- perror( "accept" );
- sys_channel_free( channel );
- return NULL;
- }
-
- /* disable Nagle algorithm */
- socket_set_nodelay( channel->fd );
-
- D( "%s: handler %p:%d created from server %p:%d\n", __FUNCTION__,
- server_channel, server_channel->fd, channel, channel->fd );
-
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_client( const char* hostname, int port )
-{
- SysChannel channel = sys_channel_alloc();
-
- channel->fd = socket_network_client( hostname, port, SOCKET_STREAM );
- if (channel->fd < 0) {
- sys_channel_free(channel);
- return NULL;
- };
-
- /* set to non-blocking and disable Nagle algorithm */
- socket_set_nonblock( channel->fd );
- socket_set_nodelay( channel->fd );
-
- return channel;
-}
-
diff --git a/telephony/test1.c b/telephony/test1.c
deleted file mode 100644
index 52701b9..0000000
--- a/telephony/test1.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sysdeps.h"
-#include <stdio.h>
-
-#define MAX_COUNTER 10
-
-static int counter = 0;
-
-static void
-timer_func( void* _timer )
-{
- SysTimer timer = _timer;
- SysTime now = sys_time_ms();
-
- ++counter;
- printf( "tick %d/%d a %.2fs\n", counter, MAX_COUNTER, now/1000. );
- if (counter < MAX_COUNTER)
- sys_timer_set( timer, now + 2000, timer_func, timer );
- else
- sys_timer_destroy( timer );
-}
-
-
-int main( void )
-{
- SysTimer timer;
-
- /* initialize event subsystem */
- sys_main_init();
-
- /* create timer and register it */
- timer = sys_timer_create();
- sys_timer_set( timer, sys_time_ms() + 1000, timer_func, timer );
-
- printf("entering event loop\n");
- sys_main_loop();
- printf("exiting event loop\n" );
- return 0;
-}
diff --git a/telephony/test2.c b/telephony/test2.c
deleted file mode 100644
index a0cd66f..0000000
--- a/telephony/test2.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sysdeps.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#define PORT 8000
-#define MAX_COUNTER 30
-#define INITIAL_DELAY 1000
-#define DELAY 5000
-
-static int counter = 0;
-
-static void
-timer_func( void* _timer )
-{
- SysTimer timer = _timer;
- SysTime now = sys_time_ms();
-
- ++counter;
- printf( "tick %d/%d a %.2fs\n", counter, MAX_COUNTER, now/1000. );
- if (counter < MAX_COUNTER)
- sys_timer_set( timer, now + DELAY, timer_func, timer );
- else
- sys_timer_destroy( timer );
-}
-
-typedef struct {
- SysChannel channel;
- char in_buff[ 128 ];
- int in_pos;
-
- char out_buff[ 128 ];
- int out_pos;
- int out_size;
-} ClientRec, *Client;
-
-static Client
-client_alloc( SysChannel channel )
-{
- Client client = calloc( sizeof(*client), 1 );
-
- client->channel = channel;
- return client;
-}
-
-static void
-client_free( Client client )
-{
- sys_channel_close( client->channel );
- client->channel = NULL;
- free( client );
-}
-
-static void
-client_append( Client client, const char* str, int len );
-
-static void
-client_handle_line( Client client, const char* cmd )
-{
- char temp[256];
- int nn, mm = 0;
-
- for (nn = 0; cmd[nn] != 0; nn++) {
- int c = cmd[nn];
- if (c >= 32 && c <= 127)
- temp[mm++] = c;
- else if (c == '\n') {
- strcat( temp+mm, "<LF>" );
- mm += 4;
- }
- else if (c == '\r') {
- strcat( temp+mm, "<CR>" );
- mm += 4;
- }
- else {
- sprintf( temp+mm, "\\x%02x", c );
- mm += strlen( temp+mm );
- }
- }
- temp[mm] = 0;
- printf( "%p: << %s\n", client, temp );
-
- if ( !strcmp( cmd, "quit" ) ) {
- printf( "client %p quitting\n", client );
- client_free( client );
- return;
- }
- client_append( client, "type 'quit' to quit\n", -1 );
-}
-
-static void
-client_handler( void* _client, int events )
-{
- Client client = _client;
-
- if (events & SYS_EVENT_READ) {
- int ret;
- /* read into buffer, one character at a time */
- ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- if (client->in_buff[client->in_pos] == '\r' ||
- client->in_buff[client->in_pos] == '\n' ) {
- const char* cmd = client->in_buff;
- client->in_buff[client->in_pos] = 0;
-
- /* eat leading cr and lf, maybe left-overs from previous line */
- while (*cmd == '\r' || *cmd =='\n')
- cmd++;
-
- client_handle_line( client, cmd );
- client->in_pos = 0;
- } else
- client->in_pos += 1;
- }
-
- if (events & SYS_EVENT_WRITE) {
- int ret;
- /* write from output buffer, one char at a time */
- ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- client->out_pos += 1;
- if (client->out_pos == client->out_size) {
- client->out_size = 0;
- client->out_pos = 0;
- /* we don't need to write */
- sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client );
- }
- }
- return;
-
-ExitClient:
- printf( "client %p exiting\n", client );
- client_free( client );
-}
-
-static void
-client_append( Client client, const char* str, int len )
-{
- int avail;
-
- if (len < 0)
- len = strlen(str);
-
- avail = sizeof(client->out_buff) - client->out_size;
- if (len > avail)
- len = avail;
-
- memcpy( client->out_buff + client->out_size, str, len );
- if (client->out_size == 0) {
- sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client );
- }
- client->out_size += len;
-}
-
-
-static void
-accept_func( void* _server, int events )
-{
- SysChannel server = _server;
- SysChannel handler;
- Client client;
-
- printf( "connection accepted for server channel, getting handler socket\n" );
- handler = sys_channel_create_tcp_handler( server );
- printf( "got one. creating client\n" );
- client = client_alloc( handler );
-
- events=events;
- sys_channel_on( handler, SYS_EVENT_READ, client_handler, client );
- client_append( client, "Welcome !\n", -1 );
-}
-
-
-int main( void )
-{
- SysTimer timer;
- SysChannel server_channel;
-
- /* initialize event subsystem */
- sys_main_init();
-
- /* create timer and register it */
- timer = sys_timer_create();
- sys_timer_set( timer, sys_time_ms() + INITIAL_DELAY, timer_func, timer );
-
- server_channel = sys_channel_create_tcp_server( PORT );
- printf( "listening on port %d with %p\n", PORT, server_channel );
-
- sys_channel_on( server_channel, SYS_EVENT_READ, accept_func, server_channel );
-
- printf("entering event loop\n");
- sys_main_loop();
- printf("exiting event loop\n" );
- return 0;
-}