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

View File

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

View File

@ -169,7 +169,7 @@ int gsm_modem_call_last(GSMModem * gsmm, GSMCallType calltype)
/* gsm_modem_enter_sim_pin */ /* 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) 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)) 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; return 1;
} }
len = sizeof(cmd) + 1 + strlen(code) + 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; 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); /* did it really work? */
/* do we need another PIN code? */ gsm_is_pin_valid(gsm);
gsm_is_pin_needed(gsm);
} }
@ -209,7 +209,8 @@ int gsm_modem_get_contact_list(GSMModem * gsmm)
{ {
char const cmd[] = "AT+CPBR=?"; 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=?"; 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"; 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 */ /* gsm_modem_is_registered */
int gsm_modem_is_registered(GSMModem * gsmm) 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); gsm_command_set_priority(gsmc, GSM_PRIORITY_HIGHEST);
if((gsmc = gsm_command_new(buf2)) != NULL if((gsmc = gsm_command_new(buf2)) != NULL
/* XXX if this fails we're stuck in PDU mode */ /* 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_command_set_error(gsmc,
GSM_ERROR_MESSAGE_SEND_FAILED); GSM_ERROR_MESSAGE_SEND_FAILED);
@ -486,12 +507,22 @@ int gsm_modem_set_extended_ring_reports(GSMModem * gsmm, gboolean extended)
/* gsm_modem_set_functional */ /* gsm_modem_set_functional */
static void _modem_set_functional_callback(GSM * gsm);
int gsm_modem_set_functional(GSMModem * gsmm, gboolean functional) int gsm_modem_set_functional(GSMModem * gsmm, gboolean functional)
{ {
char cmd[] = "AT+CFUN=X"; char cmd[] = "AT+CFUN=X";
cmd[8] = functional ? '1' : '0'; 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_functional(GSMModem * gsmm);
int gsm_modem_is_pin_needed(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_is_registered(GSMModem * gsmm);
int gsm_modem_reset(GSMModem * gsmm); int gsm_modem_reset(GSMModem * gsmm);

View File

@ -333,6 +333,8 @@ void phone_code_enter(Phone * phone)
/* phone_code_clear */ /* phone_code_clear */
void phone_code_clear(Phone * phone) 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) if(phone->en_window != NULL)
gtk_entry_set_text(GTK_ENTRY(phone->en_entry), ""); 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); event->signal_level.level);
return 0; return 0;
case GSM_EVENT_TYPE_SIM_PIN_VALID: case GSM_EVENT_TYPE_SIM_PIN_VALID:
_phone_track(phone, PHONE_TRACK_CODE_ENTERED, FALSE); phone_code_clear(phone);
phone->en_progress = _phone_progress_delete(
phone->en_progress);
_phone_info(phone, phone->en_window, _phone_info(phone, phone->en_window,
_("SIM PIN is valid"), _("SIM PIN is valid"),
G_CALLBACK(_on_sim_pin_valid_response)); 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); phone_show_code(phone, TRUE, PHONE_CODE_SIM_PIN);
break; break;
case GSM_ERROR_SIM_PIN_WRONG: 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_code_clear(phone);
_phone_error(phone->en_window, _("Wrong SIM PIN code"));
break; break;
case GSM_ERROR_CONTACT_FETCH_FAILED: case GSM_ERROR_CONTACT_FETCH_FAILED:
case GSM_ERROR_MESSAGE_FETCH_FAILED: case GSM_ERROR_MESSAGE_FETCH_FAILED: