18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "remote_call.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/bufprint.h" 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h" 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sysdeps.h" 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "gsm.h" 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/android.h" 18cc330d4169441727fecf1da08aee806fc021c4e2David 'Digit' Turner#include "android/sockets.h" 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DEBUG 1 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 1 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D_ACTIVE VERBOSE_CHECK(modem) 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D_ACTIVE DEBUG 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 1 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define S_ACTIVE VERBOSE_CHECK(socket) 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define S_ACTIVE DEBUG 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <stdio.h> 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D(...) do { if (D_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0) 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define S(...) do { if (S_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0) 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define D(...) ((void)0) 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define S(...) ((void)0) 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** By convention, remote numbers are the console ports, i.e. 5554, 5556, etc... 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REMOTE_NUMBER_BASE 5554 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REMOTE_NUMBER_MAX 16 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REMOTE_NUMBER_MAX_CHARS 4 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REMOTE_CONSOLE_PORT 5554 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_number_from_port( int port ) 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (port & 1) /* must be even */ 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project port = (port - REMOTE_CONSOLE_PORT) >> 1; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((unsigned)port >= REMOTE_NUMBER_MAX) 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return REMOTE_NUMBER_BASE + port*2; 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_number_to_port( int number ) 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (number & 1) /* must be even */ 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project number = (number - REMOTE_NUMBER_BASE) >> 1; 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((unsigned)number >= REMOTE_NUMBER_MAX) 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return REMOTE_CONSOLE_PORT + number*2; 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_number_string_to_port( const char* number ) 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* end; 81a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin long num; 824e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner const char* temp = number; 83a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin int len; 84a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin 85a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin len = strlen(number); 86a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin if (len > 0 && number[len-1] == ';') 87a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin len--; 88a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin if (len == 11 && !memcmp(number, PHONE_PREFIX, 7)) 89a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin temp += 7; 90a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin num = strtol( temp, &end, 10 ); 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (end == NULL || *end || (int)num != num ) 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return remote_number_to_port( (int)num ); 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** REMOTE CALL OBJECTS 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct RemoteCallRec { 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct RemoteCallRec* next; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct RemoteCallRec** pref; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCallType type; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int to_port; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int from_port; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel; 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteResultFunc result_func; 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* result_opaque; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char quitting; 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* the output buffer */ 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* buff; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int buff_pos; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int buff_len; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int buff_size; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buff0[32]; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} RemoteCallRec, *RemoteCall; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_done( RemoteCall call ) 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->pref[0] = call->next; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->next = NULL; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->pref = &call->next; 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call->buff && call->buff != call->buff0) { 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(call->buff); 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff = call->buff0; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_size = (int) sizeof(call->buff0); 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( call->channel ) { 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_close( call->channel ); 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->channel = NULL; 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_pos = 0; 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_len = 0; 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_free( RemoteCall call ) 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call) { 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_done( call ); 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(call); 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void remote_call_event( void* opaque, int events ); /* forward */ 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic RemoteCall 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_alloc( RemoteCallType type, int to_port, int from_port ) 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCall rcall = calloc( sizeof(*rcall), 1 ); 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int from_num = remote_number_from_port(from_port); 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rcall != NULL) { 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *p, *end; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->pref = &rcall->next; 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->type = type; 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->to_port = to_port; 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->from_port = from_port; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->buff = rcall->buff0; 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->buff_size = sizeof(rcall->buff0); 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->buff_pos = 0; 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = rcall->buff; 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project end = p + rcall->buff_size; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (type) { 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case REMOTE_CALL_DIAL: 179a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin p = bufprint(p, end, "gsm call " PHONE_PREFIX "%d\n", from_num ); 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case REMOTE_CALL_BUSY: 183a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin p = bufprint(p, end, "gsm busy " PHONE_PREFIX "%d\n", from_num); 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case REMOTE_CALL_HOLD: 187a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin p = bufprint(p, end, "gsm hold " PHONE_PREFIX "%d\n", from_num); 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case REMOTE_CALL_ACCEPT: 191a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin p = bufprint(p, end, "gsm accept " PHONE_PREFIX "%d\n", from_num); 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case REMOTE_CALL_HANGUP: 195a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin p = bufprint(p, end, "gsm cancel " PHONE_PREFIX "%d\n", from_num ); 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p >= end) { 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: buffer too short\n", __FUNCTION__ ); 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_free(rcall); 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->buff_len = p - rcall->buff; 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rcall->channel = sys_channel_create_tcp_client( "localhost", to_port ); 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rcall->channel == NULL) { 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: could not create channel to port %d\n", __FUNCTION__, to_port); 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_free(rcall); 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_on( rcall->channel, SYS_EVENT_WRITE, remote_call_event, rcall ); 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return rcall; 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_set_sms_pdu( RemoteCall call, 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsPDU pdu ) 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *p, *end; 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int msg2len; 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project msg2len = 32 + smspdu_to_hex( pdu, NULL, 0 ); 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (msg2len > call->buff_size) { 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* old_buff = call->buff == call->buff0 ? NULL : call->buff; 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* new_buff = realloc( old_buff, msg2len ); 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (new_buff == NULL) { 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: not enough memory to alloc %d bytes", __FUNCTION__, msg2len); 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff = new_buff; 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_size = msg2len; 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = call->buff; 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project end = p + call->buff_size; 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint(p, end, "sms pdu "); 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p += smspdu_to_hex( pdu, p, end-p ); 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *p++ = '\n'; 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *p = 0; 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_len = p - call->buff; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_pos = 0; 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_add( RemoteCall call, 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCall *plist ) 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCall first = *plist; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->next = first; 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->pref = plist; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (first) 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project first->pref = &call->next; 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_event( void* opaque, int events ) 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCall call = opaque; 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("%s: called for call (%d,%d), events=%02x\n", __FUNCTION__, 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->from_port, call->to_port, events); 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (events & SYS_EVENT_READ) { 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* simply drain the channel */ 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char temp[32]; 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n = sys_channel_read( call->channel, temp, sizeof(temp) ); 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n <= 0) { 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* remote emulator probably quitted */ 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project //S("%s: emulator %d quitted with %d: %s\n", __FUNCTION__, call->to_port, errno, errno_str); 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_free( call ); 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (events & SYS_EVENT_WRITE) { 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (S_ACTIVE) { 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("%s: call (%d,%d) sending %d bytes '", __FUNCTION__, 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->from_port, call->to_port, call->buff_len - call->buff_pos ); 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = call->buff_pos; nn < call->buff_len; nn++) { 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c = call->buff[nn]; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c < 32) { 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c == '\n') 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("\\n"); 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c == '\t') 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("\\t"); 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c == '\r') 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("\\r"); 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("\\x%02x", c); 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("%c", c); 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("'\n"); 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = sys_channel_write( call->channel, 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff + call->buff_pos, 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_len - call->buff_pos ); 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n <= 0) { 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* remote emulator probably quitted */ 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("%s: emulator %d quitted unexpectedly with error %d: %s\n", 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, call->to_port, errno, errno_str); 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call->result_func) 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->result_func( call->result_opaque, 0 ); 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_free( call ); 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_pos += n; 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call->buff_pos >= call->buff_len) { 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* cool, we sent everything */ 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project S("%s: finished sending data to %d\n", __FUNCTION__, call->to_port); 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!call->quitting) { 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->quitting = 1; 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sprintf( call->buff, "quit\n" ); 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_len = strlen(call->buff); 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->buff_pos = 0; 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->quitting = 0; 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call->result_func) 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->result_func( call->result_opaque, 1 ); 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_on( call->channel, SYS_EVENT_READ, remote_call_event, call ); 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic RemoteCall _the_remote_calls; 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_from_number( const char* from ) 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* end; 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project long num = strtol( from, &end, 10 ); 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (end == NULL || *end) 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((unsigned)(num - REMOTE_NUMBER_BASE) >= REMOTE_NUMBER_MAX) 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (int) num; 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic RemoteCall 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_generic( RemoteCallType type, const char* to_number, int from_port ) 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int to_port = remote_number_string_to_port(to_number); 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCall call; 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( remote_number_from_port(from_port) < 0 ) { 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: from_port value %d is not valid", __FUNCTION__, from_port); 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( to_port < 0 ) { 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: phone number '%s' is not decimal or remote", __FUNCTION__, to_number); 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (to_port == from_port) { 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: trying to call self\n", __FUNCTION__); 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call = remote_call_alloc( type, to_port, from_port ); 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call == NULL) { 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_add( call, &_the_remote_calls ); 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D("%s: adding new call from port %d to port %d\n", __FUNCTION__, from_port, to_port); 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return call; 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_dial( const char* number, 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int from, 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteResultFunc result_func, 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* result_opaque ) 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCall call = remote_call_generic( REMOTE_CALL_DIAL, number, from ); 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call != NULL) { 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->result_func = result_func; 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call->result_opaque = result_opaque; 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return call ? 0 : -1; 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_other( const char* to_number, int from_port, RemoteCallType type ) 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_generic( type, to_number, from_port ); 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* call this function to send a SMS to a remote emulator */ 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_sms( const char* number, 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int from, 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SmsPDU pdu ) 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RemoteCall call = remote_call_generic( REMOTE_CALL_SMS, number, from ); 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call == NULL) 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (call != NULL) { 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( remote_call_set_sms_pdu( call, pdu ) < 0 ) { 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_free(call); 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return call ? 0 : -1; 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectremote_call_cancel( const char* to_number, int from_port ) 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remote_call_generic( REMOTE_CALL_HANGUP, to_number, from_port ); 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 440