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 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; }
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 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 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 " PHONE_PREFIX "%d\n", from_num ); break; case REMOTE_CALL_BUSY: p = bufprint(p, end, "gsm busy " PHONE_PREFIX "%d\n", from_num); break; case REMOTE_CALL_HOLD: p = bufprint(p, end, "gsm hold " PHONE_PREFIX "%d\n", from_num); break; case REMOTE_CALL_ACCEPT: p = bufprint(p, end, "gsm accept " PHONE_PREFIX "%d\n", from_num); break; case REMOTE_CALL_HANGUP: p = bufprint(p, end, "gsm cancel " PHONE_PREFIX "%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; }