/** * Send a new command to the modem. * * @param cmd - Pointer to the command * @param eol - Optional EOL char * @param timeout - Timeout of the operation in milliseconds. */ static void gprs_command_timeout(gprs_t * gprs,const char * cmd,u8_t eol,u32_t timeout) { #if GPRS_COMMAND_DELAY u32_t delay = sys_now() - gprs->commandTime; #endif gprs->sentCommand = cmd; #if GPRS_COMMAND_DELAY if (delay < GPRS_COMMAND_DELAY) { delay = GPRS_COMMAND_DELAY - delay; timeout += delay; TIMEOUT(timeout); modem_set_state(gprs,MODEM_STATE_NONE); //LWIP_DEBUGF(GPRS_DEBUG,("gprs_command_timeout: Delayed %lu milliseconds\n",delay)); TIMEOUT1(delay); gprs->delayedCommand = cmd; gprs->delayedEol = eol; } else { TIMEOUT(timeout); modem_set_state(gprs,MODEM_STATE_ECHO); gprs_raw_send(gprs,cmd,eol); } #else TIMEOUT(timeout); modem_set_state(gprs,MODEM_STATE_ECHO); gprs_raw_send(gprs,cmd,eol); #endif }
/** * Callback function for delayed command. * * Called when the delay between 2 command expire. */ static void gprs_command_delayed(void *arg) { //LWIP_DEBUGF(GPRS_DEBUG,("gprs_command_delayed: timeout\n")); gprs_t * gprs = (gprs_t *)arg; gprs_raw_send(gprs,gprs->delayedCommand,gprs->delayedEol); modem_set_state(gprs,MODEM_STATE_ECHO); }
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) { switch_channel_t *channel; private_t *tech_pvt; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_ANSWER: t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_CONNECTED); modem_set_state(tech_pvt->modem, MODEM_STATE_CONNECTED); mod_spandsp_indicate_data(session, SWITCH_FALSE, SWITCH_TRUE); break; case SWITCH_MESSAGE_INDICATE_PROGRESS: t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_CONNECTED); modem_set_state(tech_pvt->modem, MODEM_STATE_CONNECTED); mod_spandsp_indicate_data(session, SWITCH_FALSE, SWITCH_TRUE); break; case SWITCH_MESSAGE_INDICATE_RINGING: break; case SWITCH_MESSAGE_INDICATE_BRIDGE: mod_spandsp_indicate_data(session, SWITCH_FALSE, SWITCH_TRUE); break; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: mod_spandsp_indicate_data(session, SWITCH_FALSE, SWITCH_TRUE); break; default: break; } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_destroy(switch_core_session_t *session) { //switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; //channel = switch_core_session_get_channel(session); //switch_assert(channel != NULL); if ((tech_pvt = switch_core_session_get_private(session))) { switch_core_timer_destroy(&tech_pvt->timer); if (tech_pvt->modem) { *tech_pvt->modem->uuid_str = '\0'; *tech_pvt->modem->digits = '\0'; modem_set_state(tech_pvt->modem, MODEM_STATE_ONHOOK); tech_pvt->modem = NULL; } } return SWITCH_STATUS_SUCCESS; }
static modem_t *acquire_modem(int index) { modem_t *modem = NULL; switch_time_t now = switch_time_now(); int64_t idle_debounce = 2000000; switch_mutex_lock(globals.mutex); if (index > -1 && index < globals.SOFT_MAX_MODEMS) { modem = &globals.MODEM_POOL[index]; } else { int x; for(x = 0; x < globals.SOFT_MAX_MODEMS; x++) { if (globals.MODEM_POOL[x].state == MODEM_STATE_ONHOOK && (now - globals.MODEM_POOL[x].last_event) > idle_debounce) { modem = &globals.MODEM_POOL[x]; break; } } } if (modem && (modem->state != MODEM_STATE_ONHOOK || (now - modem->last_event) < idle_debounce)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Modem %s In Use!\n", modem->devlink); modem = NULL; } if (modem) { modem_set_state(modem, MODEM_STATE_ACQUIRED); modem->last_event = switch_time_now(); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Modems Available!\n"); } switch_mutex_unlock(globals.mutex); return modem; }
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) { char name[128]; switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; if ((*new_session = switch_core_session_request(modem_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { private_t *tech_pvt; switch_channel_t *channel; switch_caller_profile_t *caller_profile; char *dest = switch_core_session_strdup(*new_session, outbound_profile->destination_number); char *modem_id_string = NULL; char *number = NULL; int modem_id = 0; modem_t *modem = NULL; if ((modem_id_string = dest)) { if ((number = strchr(modem_id_string, '/'))) { *number++ = '\0'; } } if (zstr(modem_id_string) || zstr(number)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Invalid dial string.\n"); cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT; goto fail; } if (!strcasecmp(modem_id_string, "a")) { modem_id = -1; } else { modem_id = atoi(modem_id_string); } if (!(modem = acquire_modem(modem_id))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Cannot find a modem.\n"); cause = SWITCH_CAUSE_USER_BUSY; goto fail; } switch_core_session_add_stream(*new_session, NULL); if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) { channel = switch_core_session_get_channel(*new_session); switch_snprintf(name, sizeof(name), "modem/%d/%s", modem->slot, number); switch_channel_set_name(channel, name); if (tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS) { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; goto fail; } switch_set_string(modem->digits, number); tech_attach(tech_pvt, modem); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(new_session); cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; goto fail; } if (outbound_profile) { caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); caller_profile->source = switch_core_strdup(caller_profile->pool, "mod_spandsp"); switch_channel_set_caller_profile(channel, caller_profile); tech_pvt->caller_profile = caller_profile; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Doh! no caller profile\n"); cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; goto fail; } switch_channel_set_state(channel, CS_INIT); return SWITCH_CAUSE_SUCCESS; fail: if (new_session) { switch_core_session_destroy(new_session); } if (modem) { modem_set_state(modem, MODEM_STATE_ONHOOK); } } return cause; }
int modem_close(modem_t *modem) { int r = 0; switch_status_t was_running = switch_test_flag(modem, MODEM_FLAG_RUNNING); switch_clear_flag(modem, MODEM_FLAG_RUNNING); #ifndef WIN32 if (modem->master > -1) { shutdown(modem->master, 2); close(modem->master); modem->master = -1; #else if (modem->master) { SetEvent(modem->threadAbort); CloseHandle(modem->threadAbort); CloseHandle(modem->master); modem->master = 0; #endif r++; } if (modem->slave > -1) { shutdown(modem->slave, 2); close(modem->slave); modem->slave = -1; r++; } if (modem->t31_state) { t31_free(modem->t31_state); modem->t31_state = NULL; } unlink(modem->devlink); if (was_running) { switch_mutex_lock(globals.mutex); globals.REF_COUNT--; switch_mutex_unlock(globals.mutex); } return r; } switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handler) { switch_status_t status = SWITCH_STATUS_SUCCESS; #ifdef WIN32 COMMTIMEOUTS timeouts={0}; #endif memset(modem, 0, sizeof(*modem)); modem->master = -1; modem->slave = -1; /* windows will have to try something like: http://com0com.cvs.sourceforge.net/viewvc/com0com/com0com/ReadMe.txt?revision=RELEASED */ #if USE_OPENPTY if (openpty(&modem->master, &modem->slave, NULL, NULL, NULL)) { if (modem->master < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to initialize pty\n"); status = SWITCH_STATUS_FALSE; goto end; } modem->stty = ttyname(modem->slave); #else #if WIN32 modem->slot = 4+globals.NEXT_ID++; /* need work here we start at COM4 for now*/ snprintf(modem->devlink, sizeof(modem->devlink), "COM%d", modem->slot); modem->master = CreateFile(modem->devlink, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if(modem->master==INVALID_HANDLE_VALUE) { status = SWITCH_STATUS_FALSE; if(GetLastError()==ERROR_FILE_NOT_FOUND) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: Serial port does not exist\n"); goto end; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: Serial port open error\n"); goto end; } #elif !defined(HAVE_POSIX_OPENPT) modem->master = open("/dev/ptmx", O_RDWR); #else modem->master = posix_openpt(O_RDWR | O_NOCTTY); #endif #ifndef WIN32 if (modem->master < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to initialize UNIX98 master pty\n"); } if (grantpt(modem->master) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to grant access to slave pty\n"); } if (unlockpt(modem->master) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to unlock slave pty\n"); } modem->stty = ptsname(modem->master); if (modem->stty == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to obtain slave pty filename\n"); } modem->slave = open(modem->stty, O_RDWR); if (modem->slave < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to open slave pty %s\n", modem->stty); } #endif #ifdef SOLARIS ioctl(modem->slave, I_PUSH, "ptem"); /* push ptem */ ioctl(modem->slave, I_PUSH, "ldterm"); /* push ldterm*/ #endif #endif #ifndef WIN32 modem->slot = globals.NEXT_ID++; snprintf(modem->devlink, sizeof(modem->devlink), "/dev/FS%d", modem->slot); unlink(modem->devlink); if (symlink(modem->stty, modem->devlink)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to create %s symbolic link\n", modem->devlink); modem_close(modem); status = SWITCH_STATUS_FALSE; goto end; } if (fcntl(modem->master, F_SETFL, fcntl(modem->master, F_GETFL, 0) | O_NONBLOCK)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot set up non-blocking read on %s\n", ttyname(modem->master)); modem_close(modem); status = SWITCH_STATUS_FALSE; goto end; } #else timeouts.ReadIntervalTimeout=50; timeouts.ReadTotalTimeoutConstant=50; timeouts.ReadTotalTimeoutMultiplier=10; timeouts.WriteTotalTimeoutConstant=50; timeouts.WriteTotalTimeoutMultiplier=10; SetCommMask(modem->master, EV_RXCHAR); if(!SetCommTimeouts(modem->master, &timeouts)){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot set up non-blocking read on %s\n", modem->devlink); modem_close(modem); status = SWITCH_STATUS_FALSE; goto end; } modem->threadAbort = CreateEvent(NULL, TRUE, FALSE, NULL); #endif if (!(modem->t31_state = t31_init(NULL, t31_at_tx_handler, modem, t31_call_control_handler, modem, NULL, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot initialize the T.31 modem\n"); modem_close(modem); status = SWITCH_STATUS_FALSE; goto end; } if (spandsp_globals.modem_verbose) { span_log_set_message_handler(&modem->t31_state->logging, spanfax_log_message, NULL); span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v17_rx.logging, spanfax_log_message, NULL); span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v29_rx.logging, spanfax_log_message, NULL); span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v27ter_rx.logging, spanfax_log_message, NULL); modem->t31_state->logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW; modem->t31_state->audio.modems.fast_modems.v17_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW; modem->t31_state->audio.modems.fast_modems.v29_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW; modem->t31_state->audio.modems.fast_modems.v27ter_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW; } modem->control_handler = control_handler; modem->flags = 0; switch_set_flag(modem, MODEM_FLAG_RUNNING); switch_mutex_init(&modem->mutex, SWITCH_MUTEX_NESTED, globals.pool); switch_mutex_init(&modem->cond_mutex, SWITCH_MUTEX_NESTED, globals.pool); switch_thread_cond_create(&modem->cond, globals.pool); modem_set_state(modem, MODEM_STATE_INIT); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Modem [%s]->[%s] Ready\n", modem->devlink, modem->stty); switch_mutex_lock(globals.mutex); globals.REF_COUNT++; switch_mutex_unlock(globals.mutex); end: return status; } static switch_endpoint_interface_t *modem_endpoint_interface = NULL; struct private_object { switch_mutex_t *mutex; switch_core_session_t *session; switch_channel_t *channel; switch_codec_t read_codec; switch_codec_t write_codec; switch_frame_t read_frame; unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; switch_timer_t timer; modem_t *modem; switch_caller_profile_t *caller_profile; int dead; }; typedef struct private_object private_t; static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); static switch_status_t channel_on_soft_execute(switch_core_session_t *session); static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); /* State methods they get called when the state changes to the specific state returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. */ static switch_status_t channel_on_init(switch_core_session_t *session) { switch_channel_t *channel; private_t *tech_pvt = NULL; int to_ticks = 60, ring_ticks = 10, rt = ring_ticks; int rest = 500000; tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { #ifndef WIN32 int tioflags; #endif char call_time[16]; char call_date[16]; switch_size_t retsize; switch_time_exp_t tm; switch_time_exp_lt(&tm, switch_micro_time_now()); switch_strftime(call_date, &retsize, sizeof(call_date), "%m%d", &tm); switch_strftime(call_time, &retsize, sizeof(call_time), "%H%M", &tm); #ifndef WIN32 ioctl(tech_pvt->modem->slave, TIOCMGET, &tioflags); tioflags |= TIOCM_RI; ioctl(tech_pvt->modem->slave, TIOCMSET, &tioflags); #endif at_reset_call_info(&tech_pvt->modem->t31_state->at_state); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "DATE", call_date); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "TIME", call_time); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "NAME", tech_pvt->caller_profile->caller_id_name); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "NMBR", tech_pvt->caller_profile->caller_id_number); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "ANID", tech_pvt->caller_profile->ani); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "USER", tech_pvt->caller_profile->username); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "CDID", tech_pvt->caller_profile->context); at_set_call_info(&tech_pvt->modem->t31_state->at_state, "NDID", tech_pvt->caller_profile->destination_number); modem_set_state(tech_pvt->modem, MODEM_STATE_RINGING); t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_ALERTING); while(to_ticks > 0 && switch_channel_up(channel) && modem_get_state(tech_pvt->modem) == MODEM_STATE_RINGING) { if (--rt <= 0) { t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_ALERTING); rt = ring_ticks; } switch_yield(rest); to_ticks--; } if (to_ticks < 1 || modem_get_state(tech_pvt->modem) != MODEM_STATE_ANSWERED) { t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_NO_ANSWER); switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER); } else { t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_ANSWERED); modem_set_state(tech_pvt->modem, MODEM_STATE_CONNECTED); switch_channel_mark_answered(channel); } } switch_channel_set_state(channel, CS_ROUTING); return SWITCH_STATUS_SUCCESS; }
static int control_handler(modem_t *modem, const char *num, int op) { switch_core_session_t *session = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Control Handler op:%d state:[%s] %s\n", op, modem_state2name(modem_get_state(modem)), modem->devlink); switch (op) { case AT_MODEM_CONTROL_ANSWER: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - Answering\n", modem->devlink, modem_state2name(modem_get_state(modem))); modem_set_state(modem, MODEM_STATE_ANSWERED); break; case AT_MODEM_CONTROL_CALL: { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - Dialing '%s'\n", modem->devlink, modem_state2name(modem_get_state(modem)), num); modem_set_state(modem, MODEM_STATE_DIALING); switch_clear_flag(modem, MODEM_FLAG_XOFF); wake_modem_thread(modem); switch_set_string(modem->digits, num); if (create_session(&session, modem) != SWITCH_STATUS_SUCCESS) { t31_call_event(modem->t31_state, AT_CALL_EVENT_HANGUP); } else { switch_core_session_thread_launch(session); } } break; case AT_MODEM_CONTROL_OFFHOOK: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - Going off hook\n", modem->devlink, modem_state2name(modem_get_state(modem))); modem_set_state(modem, MODEM_STATE_OFFHOOK); break; case AT_MODEM_CONTROL_ONHOOK: case AT_MODEM_CONTROL_HANGUP: { if (modem_get_state(modem) != MODEM_STATE_RINGING) { int set_state = 1; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - Hanging up\n", modem->devlink, modem_state2name(modem_get_state(modem))); switch_clear_flag(modem, MODEM_FLAG_XOFF); wake_modem_thread(modem); modem_set_state(modem, MODEM_STATE_HANGUP); if (!zstr(modem->uuid_str)) { switch_core_session_t *session; if ((session = switch_core_session_force_locate(modem->uuid_str))) { switch_channel_t *channel = switch_core_session_get_channel(session); if (switch_channel_up(channel)) { switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); set_state = 0; } switch_core_session_rwunlock(session); } } if (set_state) { modem_set_state(modem, MODEM_STATE_ONHOOK); } } } break; case AT_MODEM_CONTROL_DTR: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - DTR %d\n", modem->devlink, modem_state2name(modem_get_state(modem)), (int) (intptr_t) num); break; case AT_MODEM_CONTROL_RTS: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - RTS %d\n", modem->devlink, modem_state2name(modem_get_state(modem)), (int) (intptr_t) num); break; case AT_MODEM_CONTROL_CTS: { u_char x[1]; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Modem %s [%s] - CTS %s\n", modem->devlink, modem_state2name(modem_get_state(modem)), (int) (intptr_t) num ? "XON" : "XOFF"); if (num) { x[0] = 0x11; t31_at_tx_handler(&modem->t31_state->at_state, modem, x, 1); switch_clear_flag(modem, MODEM_FLAG_XOFF); wake_modem_thread(modem); } else { x[0] = 0x13; t31_at_tx_handler(&modem->t31_state->at_state, modem, x, 1); switch_set_flag(modem, MODEM_FLAG_XOFF); } } break; case AT_MODEM_CONTROL_CAR: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - CAR %d\n", modem->devlink, modem_state2name(modem_get_state(modem)), (int) (intptr_t) num); break; case AT_MODEM_CONTROL_RNG: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - RNG %d\n", modem->devlink, modem_state2name(modem_get_state(modem)), (int) (intptr_t) num); break; case AT_MODEM_CONTROL_DSR: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - DSR %d\n", modem->devlink, modem_state2name(modem_get_state(modem)), (int) (intptr_t) num); break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Modem %s [%s] - operation %d\n", modem->devlink, modem_state2name(modem_get_state(modem)), op); break; } /*endswitch*/ return 0; }
/** * Check reply from the modem. * * @return 0 - No valid reply received * @return 1 - OK received * @return 2 - Error received. */ static int modem_check_reply(gprs_t * gprs,const u8_t *data,u32_t length,void (*callback)(gprs_t * gprs,const char *reply)) { u8_t c; int reply = MODEM_REPLY_NONE; while (length-- > 0 && reply == MODEM_REPLY_NONE) { c = *data++; switch (gprs->modem) { default: case MODEM_STATE_NONE: break; case MODEM_STATE_ECHO: if (gprs->sentCommand[gprs->modemCount] == c) { if (gprs->sentCommand[++gprs->modemCount] < 32) { modem_set_state(gprs,MODEM_STATE_WAITEOL); } } else { gprs->modemCount = 0; } break; case MODEM_STATE_WAITEOL: if (c < 32) { //LWIP_DEBUGF(GPRS_DEBUG,("Modem_check_reply: echo received\n")); modem_set_state(gprs,MODEM_STATE_REPLY); } break; case MODEM_STATE_REPLY: if (c < 32) { if (gprs->modemCount > 0) { gprs->replyBuffer[gprs->modemCount] = 0; LWIP_DEBUGF(MODEM_DEBUG,("gprs: Modem reply '%s'\n",gprs->replyBuffer)); gprs->modemCount = 0; if (!strcmp(gprs->replyBuffer,"OK")) { #if GPRS_COMMAND_DELAY > 0 gprs->commandTime = sys_now(); #endif //LWIP_DEBUGF(MODEM_DEBUG,("modem_check_reply: OK received\n")); reply = MODEM_REPLY_OK; } else if(!strncmp(gprs->replyBuffer,"ERROR",5)) { #if GPRS_COMMAND_DELAY > 0 gprs->commandTime = sys_now(); #endif LWIP_DEBUGF(MODEM_DEBUG,("gprs: Modem reply ERROR ERROR received\n")); reply = MODEM_REPLY_ERROR; } else { if (callback != 0) { (*callback)(gprs,gprs->replyBuffer); } } } } else { if (gprs->modemCount < sizeof(gprs->replyBuffer) - 1) { gprs->replyBuffer[gprs->modemCount++] = c; } else { LWIP_DEBUGF(GPRS_DEBUG,("gprs: GPRS_REPLY_BUFFER_SIZE too short")); } } break; } } return reply; }