From 5fb92d31893bbb94418065b4b2612576713d818c Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 8 May 2010 03:07:47 +0000 Subject: [PATCH] Obtaining the functionality status before really using the phone --- src/gsm.c | 29 ++++++++++++++++++++++++++--- src/gsm.h | 2 ++ src/modem.c | 9 +++++++++ src/modem.h | 1 + src/phone.c | 32 ++++++++++++++++++++++---------- 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/gsm.c b/src/gsm.c index 5ca8a15..6822259 100644 --- a/src/gsm.c +++ b/src/gsm.c @@ -161,6 +161,7 @@ static void _gsm_queue_pop(GSM * gsm); static int _gsm_queue_push(GSM * gsm); /* triggers */ +static int _gsm_trigger_cfun(GSM * gsm, char const * result); static int _gsm_trigger_cgmm(GSM * gsm, char const * result); static int _gsm_trigger_cme_error(GSM * gsm, char const * result, gboolean * answered); @@ -180,6 +181,7 @@ static GSMTrigger _gsm_triggers[] = #define GSM_TRIGGER(trigger, callback) \ { trigger, sizeof(trigger) - 1, \ (GSMTriggerCallback)_gsm_trigger_ ## callback } + GSM_TRIGGER("+CFUN: ", cfun), GSM_TRIGGER("+CGMM: ", cgmm), GSM_TRIGGER("+CME ERROR: ", cme_error), GSM_TRIGGER("+CMS ERROR: ", cms_error), @@ -541,6 +543,14 @@ int gsm_fetch_signal_level(GSM * gsm) } +/* queries */ +/* gsm_is_functional */ +int gsm_is_functional(GSM * gsm) +{ + return gsm_modem_is_functional(gsm->modem); +} + + /* gsm_is_pin_needed */ int gsm_is_pin_needed(GSM * gsm) { @@ -946,6 +956,20 @@ static int _gsm_queue_push(GSM * gsm) /* triggers */ +/* gsm_trigger_cfun */ +static int _gsm_trigger_cfun(GSM * gsm, char const * result) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, result); +#endif + if(sscanf(result, "%u", &gsm->event.functional.functional) != 1) + /* XXX nicer message */ + return gsm_event(gsm, GSM_EVENT_TYPE_ERROR, + GSM_ERROR_FUNCTIONAL_FAILED, result); + return _gsm_event_send(gsm, GSM_EVENT_TYPE_FUNCTIONAL); +} + + /* gsm_trigger_cgmm */ static int _gsm_trigger_cgmm(GSM * gsm, char const * result) { @@ -1107,9 +1131,8 @@ static int _gsm_trigger_cpin(GSM * gsm, char const * result) if(strcmp(result, "SIM PIN") == 0) return gsm_event(gsm, GSM_EVENT_TYPE_ERROR, GSM_ERROR_SIM_PIN_REQUIRED, NULL); - else - /* XXX nicer message */ - return gsm_event(gsm, GSM_EVENT_TYPE_ERROR, result); + /* XXX nicer message */ + return gsm_event(gsm, GSM_EVENT_TYPE_ERROR, GSM_ERROR_UNKNOWN, result); } diff --git a/src/gsm.h b/src/gsm.h index b5d9752..0ca4770 100644 --- a/src/gsm.h +++ b/src/gsm.h @@ -255,6 +255,8 @@ int gsm_fetch_operator(GSM * gsm); int gsm_fetch_registration(GSM * gsm); int gsm_fetch_signal_level(GSM * gsm); +/* queries */ +int gsm_is_functional(GSM * gsm); int gsm_is_pin_needed(GSM * gsm); int gsm_is_registered(GSM * gsm); diff --git a/src/modem.c b/src/modem.c index 840ecad..7226326 100644 --- a/src/modem.c +++ b/src/modem.c @@ -282,6 +282,15 @@ int gsm_modem_get_signal_level(GSMModem * gsmm) } +/* gsm_modem_is_functional */ +int gsm_modem_is_functional(GSMModem * gsmm) +{ + char const cmd[] = "AT+CFUN?"; + + return (gsm_queue(gsmm->gsm, cmd) != NULL) ? 0 : 1; +} + + /* gsm_modem_is_pin_needed */ int gsm_modem_is_pin_needed(GSMModem * gsmm) { diff --git a/src/modem.h b/src/modem.h index 49f7ec2..5290ff1 100644 --- a/src/modem.h +++ b/src/modem.h @@ -59,6 +59,7 @@ int gsm_modem_get_operator(GSMModem * gsmm); int gsm_modem_get_registration(GSMModem * gsmm); 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_registered(GSMModem * gsmm); diff --git a/src/phone.c b/src/phone.c index c7cf6f9..19fe54c 100644 --- a/src/phone.c +++ b/src/phone.c @@ -47,6 +47,7 @@ typedef enum _PhoneTrack { PHONE_TRACK_CODE_ENTERED = 0, PHONE_TRACK_CONTACT_LIST, + PHONE_TRACK_FUNCTIONAL, PHONE_TRACK_MESSAGE_LIST, PHONE_TRACK_MESSAGE_SENT, PHONE_TRACK_REGISTRATION, @@ -1104,11 +1105,9 @@ static void _signal_level_set_image(Phone * phone, PhoneSignal signal) /* phone_set_status */ static void _phone_set_status(Phone * phone, GSMStatus status) { - GSMRegistrationReport report; char const * operator = NULL; gboolean track_registration = TRUE; - report = GSM_REGISTRATION_REPORT_ENABLE_UNSOLLICITED_WITH_LOCATION; switch(status) { case GSM_STATUS_UNKNOWN: @@ -1128,12 +1127,7 @@ static void _phone_set_status(Phone * phone, GSMStatus status) case GSM_STATUS_READY: track_registration = FALSE; operator = _("SIM ready..."); - gsm_set_functional(phone->gsm, TRUE); - gsm_set_operator_mode(phone->gsm, - GSM_OPERATOR_MODE_AUTOMATIC); - gsm_set_registration_report(phone->gsm, report); - _phone_track(phone, PHONE_TRACK_CONTACT_LIST, TRUE); - _phone_track(phone, PHONE_TRACK_MESSAGE_LIST, TRUE); + gsm_is_functional(phone->gsm); break; case GSM_STATUS_REGISTERED_HOME: case GSM_STATUS_REGISTERED_ROAMING: @@ -1184,10 +1178,12 @@ static void _on_sim_pin_valid_response(GtkWidget * widget, gint response, static int _phone_gsm_event(GSMEvent * event, gpointer data) { Phone * phone = data; + GSMRegistrationReport report; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d)\n", __func__, event->type); #endif + report = GSM_REGISTRATION_REPORT_ENABLE_UNSOLLICITED_WITH_LOCATION; switch(event->type) { case GSM_EVENT_TYPE_ERROR: @@ -1202,7 +1198,16 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) event->contact_list.end); return 0; case GSM_EVENT_TYPE_FUNCTIONAL: - /* FIXME implement */ + if(event->functional.functional != 1) + { + gsm_set_functional(phone->gsm, TRUE); + return 0; + } + gsm_set_operator_mode(phone->gsm, + GSM_OPERATOR_MODE_AUTOMATIC); + gsm_set_registration_report(phone->gsm, report); + _phone_track(phone, PHONE_TRACK_CONTACT_LIST, TRUE); + _phone_track(phone, PHONE_TRACK_MESSAGE_LIST, TRUE); return 0; case GSM_EVENT_TYPE_INCOMING_CALL: /* FIXME implement */ @@ -1258,12 +1263,14 @@ static int _gsm_event_error(Phone * phone, GSMEvent * event) phone_code_clear(phone); break; case GSM_ERROR_CONTACT_FETCH_FAILED: - case GSM_ERROR_FUNCTIONAL_FAILED: case GSM_ERROR_MESSAGE_FETCH_FAILED: break; /* ignore these errors */ case GSM_ERROR_CONTACT_LIST_FAILED: _phone_track(phone, PHONE_TRACK_CONTACT_LIST, TRUE); break; + case GSM_ERROR_FUNCTIONAL_FAILED: + _phone_track(phone, PHONE_TRACK_FUNCTIONAL, TRUE); + break; case GSM_ERROR_MESSAGE_LIST_FAILED: _phone_track(phone, PHONE_TRACK_MESSAGE_LIST, TRUE); break; @@ -1303,6 +1310,11 @@ static gboolean _phone_timeout_track(gpointer data) _phone_track(phone, PHONE_TRACK_CONTACT_LIST, FALSE); gsm_fetch_contact_list(phone->gsm); } + if(phone->tracks[PHONE_TRACK_FUNCTIONAL]) + { + _phone_track(phone, PHONE_TRACK_FUNCTIONAL, FALSE); + gsm_is_functional(phone->gsm); + } if(phone->tracks[PHONE_TRACK_MESSAGE_LIST]) { _phone_track(phone, PHONE_TRACK_MESSAGE_LIST, FALSE);