Re-inject the current command on timeout and then ensure the operation worked

This commit is contained in:
Pierre Pronchery 2010-05-08 13:03:58 +00:00
parent 9372ef637e
commit e3c993c66e
5 changed files with 70 additions and 24 deletions

View File

@ -424,7 +424,7 @@ int gsm_call_hangup(GSM * gsm)
int gsm_enter_sim_pin(GSM * gsm, char const * code)
{
if(code == NULL)
return gsm_modem_is_pin_needed(gsm->modem);
return gsm_modem_is_pin_valid(gsm->modem);
return gsm_modem_enter_sim_pin(gsm->modem, code);
}
@ -558,6 +558,13 @@ int gsm_is_pin_needed(GSM * gsm)
}
/* gsm_is_pin_valid */
int gsm_is_pin_valid(GSM * gsm)
{
return gsm_modem_is_pin_valid(gsm->modem);
}
/* gsm_is_registered */
int gsm_is_registered(GSM * gsm)
{
@ -828,8 +835,10 @@ static int _gsm_parse_line(GSM * gsm, char const * line, gboolean * answered)
gsmc = g_slist_nth_data(gsm->queue, 0);
if(strcmp(line, "OK") == 0)
{
/* XXX the trigger may not have been called (if any) */
if(answered != NULL)
*answered = TRUE;
/* XXX call it only if we were really answered? */
if(gsmc != NULL && (callback = gsm_command_get_callback(gsmc))
!= NULL)
callback(gsm);
@ -1327,7 +1336,9 @@ static gboolean _reset_settle(gpointer data)
static gboolean _on_timeout(gpointer data)
{
GSM * gsm = data;
char const noop[] = "AT\r\n";
GSMCommand * gsmc;
char const * cmd;
size_t len;
char * p;
#ifdef DEBUG
@ -1338,12 +1349,17 @@ static gboolean _on_timeout(gpointer data)
/* check if the write handler is still running */
if(gsm->channel == NULL || gsm->wr_source != 0)
return FALSE;
/* inject the noop */
if((p = realloc(gsm->wr_buf, sizeof(noop) - 1)) == NULL)
if(gsm->queue == NULL || (gsmc = gsm->queue->data) == NULL)
return FALSE;
if((cmd = gsm_command_get_command(gsmc)) == NULL)
return FALSE;
len = strlen(cmd);
/* re-inject the command */
if((p = realloc(gsm->wr_buf, len)) == NULL)
return FALSE;
gsm->wr_buf = p;
memcpy(p, noop, sizeof(noop) - 1);
gsm->wr_buf_cnt = sizeof(noop) - 1;
memcpy(p, cmd, len);
gsm->wr_buf_cnt = len;
gsm->wr_source = g_io_add_watch(gsm->channel, G_IO_OUT,
_on_watch_can_write, gsm);
return FALSE;

View File

@ -258,6 +258,7 @@ int gsm_fetch_signal_level(GSM * gsm);
/* queries */
int gsm_is_functional(GSM * gsm);
int gsm_is_pin_needed(GSM * gsm);
int gsm_is_pin_valid(GSM * gsm);
int gsm_is_registered(GSM * gsm);
/* queue management */

View File

@ -169,7 +169,7 @@ int gsm_modem_call_last(GSMModem * gsmm, GSMCallType calltype)
/* gsm_modem_enter_sim_pin */
void _modem_enter_sim_pin_callback(GSM * gsm);
static void _modem_enter_sim_pin_callback(GSM * gsm);
int gsm_modem_enter_sim_pin(GSMModem * gsmm, char const * code)
{
@ -180,7 +180,8 @@ int gsm_modem_enter_sim_pin(GSMModem * gsmm, char const * code)
if(!_is_code(code))
{
gsm_event(gsmm->gsm, GSM_EVENT_TYPE_ERROR, GSM_ERROR_SIM_PIN_WRONG);
gsm_event(gsmm->gsm, GSM_EVENT_TYPE_ERROR,
GSM_ERROR_SIM_PIN_WRONG);
return 1;
}
len = sizeof(cmd) + 1 + strlen(code) + 1;
@ -196,11 +197,10 @@ int gsm_modem_enter_sim_pin(GSMModem * gsmm, char const * code)
return ret;
}
void _modem_enter_sim_pin_callback(GSM * gsm)
static void _modem_enter_sim_pin_callback(GSM * gsm)
{
gsm_event(gsm, GSM_EVENT_TYPE_SIM_PIN_VALID);
/* do we need another PIN code? */
gsm_is_pin_needed(gsm);
/* did it really work? */
gsm_is_pin_valid(gsm);
}
@ -209,7 +209,8 @@ int gsm_modem_get_contact_list(GSMModem * gsmm)
{
char const cmd[] = "AT+CPBR=?";
return gsm_queue_with_error(gsmm->gsm, cmd, GSM_ERROR_CONTACT_LIST_FAILED);
return gsm_queue_with_error(gsmm->gsm, cmd,
GSM_ERROR_CONTACT_LIST_FAILED);
}
@ -230,7 +231,8 @@ int gsm_modem_get_message_list(GSMModem * gsmm)
{
char const cmd[] = "AT+CMGL=?";
return gsm_queue_with_error(gsmm->gsm, cmd, GSM_ERROR_MESSAGE_LIST_FAILED);
return gsm_queue_with_error(gsmm->gsm, cmd,
GSM_ERROR_MESSAGE_LIST_FAILED);
}
@ -278,7 +280,8 @@ int gsm_modem_get_signal_level(GSMModem * gsmm)
{
char const cmd[] = "AT+CSQ";
return gsm_queue_with_error(gsmm->gsm, cmd, GSM_ERROR_SIGNAL_LEVEL_FAILED);
return gsm_queue_with_error(gsmm->gsm, cmd,
GSM_ERROR_SIGNAL_LEVEL_FAILED);
}
@ -300,6 +303,23 @@ int gsm_modem_is_pin_needed(GSMModem * gsmm)
}
/* gsm_modem_is_pin_valid */
static void _modem_is_pin_valid_callback(GSM * gsm);
int gsm_modem_is_pin_valid(GSMModem * gsmm)
{
char const cmd[] = "AT+CPIN?";
return gsm_queue_full(gsmm->gsm, GSM_PRIORITY_NORMAL, cmd,
GSM_ERROR_SIM_PIN_WRONG, _modem_is_pin_valid_callback);
}
static void _modem_is_pin_valid_callback(GSM * gsm)
{
gsm_event(gsm, GSM_EVENT_TYPE_SIM_PIN_VALID);
}
/* gsm_modem_is_registered */
int gsm_modem_is_registered(GSMModem * gsmm)
{
@ -375,7 +395,8 @@ int gsm_modem_send_message(GSMModem * gsmm, char const * number,
gsm_command_set_priority(gsmc, GSM_PRIORITY_HIGHEST);
if((gsmc = gsm_command_new(buf2)) != NULL
/* XXX if this fails we're stuck in PDU mode */
&& (ret = gsm_queue_command(gsmm->gsm, gsmc)) == 0)
&& (ret = gsm_queue_command(gsmm->gsm, gsmc))
== 0)
{
gsm_command_set_error(gsmc,
GSM_ERROR_MESSAGE_SEND_FAILED);
@ -486,12 +507,22 @@ int gsm_modem_set_extended_ring_reports(GSMModem * gsmm, gboolean extended)
/* gsm_modem_set_functional */
static void _modem_set_functional_callback(GSM * gsm);
int gsm_modem_set_functional(GSMModem * gsmm, gboolean functional)
{
char cmd[] = "AT+CFUN=X";
cmd[8] = functional ? '1' : '0';
return gsm_queue_with_error(gsmm->gsm, cmd, GSM_ERROR_FUNCTIONAL_FAILED);
return gsm_queue_full(gsmm->gsm, GSM_PRIORITY_NORMAL, cmd,
GSM_ERROR_FUNCTIONAL_FAILED,
_modem_set_functional_callback);
}
static void _modem_set_functional_callback(GSM * gsm)
{
/* did it really work? */
gsm_is_functional(gsm);
}

View File

@ -61,6 +61,7 @@ int gsm_modem_get_signal_level(GSMModem * gsmm);
int gsm_modem_is_functional(GSMModem * gsmm);
int gsm_modem_is_pin_needed(GSMModem * gsmm);
int gsm_modem_is_pin_valid(GSMModem * gsmm);
int gsm_modem_is_registered(GSMModem * gsmm);
int gsm_modem_reset(GSMModem * gsmm);

View File

@ -333,6 +333,8 @@ void phone_code_enter(Phone * phone)
/* phone_code_clear */
void phone_code_clear(Phone * phone)
{
_phone_track(phone, PHONE_TRACK_CODE_ENTERED, FALSE);
phone->en_progress = _phone_progress_delete(phone->en_progress);
if(phone->en_window != NULL)
gtk_entry_set_text(GTK_ENTRY(phone->en_entry), "");
}
@ -1231,9 +1233,7 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data)
event->signal_level.level);
return 0;
case GSM_EVENT_TYPE_SIM_PIN_VALID:
_phone_track(phone, PHONE_TRACK_CODE_ENTERED, FALSE);
phone->en_progress = _phone_progress_delete(
phone->en_progress);
phone_code_clear(phone);
_phone_info(phone, phone->en_window,
_("SIM PIN is valid"),
G_CALLBACK(_on_sim_pin_valid_response));
@ -1254,11 +1254,8 @@ static int _gsm_event_error(Phone * phone, GSMEvent * event)
phone_show_code(phone, TRUE, PHONE_CODE_SIM_PIN);
break;
case GSM_ERROR_SIM_PIN_WRONG:
_phone_track(phone, PHONE_TRACK_CODE_ENTERED, FALSE);
phone->en_progress = _phone_progress_delete(
phone->en_progress);
_phone_error(phone->en_window, _("Wrong SIM PIN code"));
phone_code_clear(phone);
_phone_error(phone->en_window, _("Wrong SIM PIN code"));
break;
case GSM_ERROR_CONTACT_FETCH_FAILED:
case GSM_ERROR_MESSAGE_FETCH_FAILED: