diff --git a/src/gsm.c b/src/gsm.c index d5603ee..836d02b 100644 --- a/src/gsm.c +++ b/src/gsm.c @@ -377,11 +377,11 @@ int gsm_set_call_presentation(GSM * gsm, int set) } -/* gsm_set_call_waiting */ -int gsm_set_call_waiting(GSM * gsm, int unsollicited, int mode) +/* gsm_set_call_waiting_control */ +int gsm_set_call_waiting_control(GSM * gsm, int unsollicited) { - return gsm_modem_set_call_waiting(gsm->modem, (unsollicited != 0) ? TRUE - : FALSE, (mode != 0) ? TRUE : FALSE); + return gsm_modem_set_call_waiting_control(gsm->modem, + (unsollicited != 0) ? TRUE : FALSE); } @@ -549,6 +549,10 @@ int gsm_event(GSM * gsm, GSMEventType type, ...) event->call_presentation.format = va_arg(ap, unsigned int); break; + case GSM_EVENT_TYPE_CALL_WAITING: + event->call_waiting_control.unsollicited = va_arg(ap, + unsigned int); + break; case GSM_EVENT_TYPE_CONTACT: event->contact.index = va_arg(ap, unsigned int); event->contact.name = va_arg(ap, char const *); @@ -684,10 +688,10 @@ int gsm_is_alive(GSM * gsm) } -/* gsm_is_call_waiting */ -int gsm_is_call_waiting(GSM * gsm) +/* gsm_is_call_waiting_control */ +int gsm_is_call_waiting_control(GSM * gsm) { - return gsm_modem_is_call_waiting(gsm->modem); + return gsm_modem_is_call_waiting_control(gsm->modem); } @@ -1160,8 +1164,11 @@ static int _gsm_trigger_ccwa(GSM * gsm, char const * result) #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, result); #endif - /* FIXME implement */ - return 1; + if(sscanf(result, "%u", &gsm->event.call_waiting_control.unsollicited) + == 1) + return _gsm_event_send(gsm, GSM_EVENT_TYPE_CALL_WAITING); + return gsm_event(gsm, GSM_EVENT_TYPE_ERROR, + GSM_ERROR_CALL_WAITING_FAILED, result); } diff --git a/src/gsm.h b/src/gsm.h index 4239436..0526fa1 100644 --- a/src/gsm.h +++ b/src/gsm.h @@ -48,6 +48,7 @@ typedef enum _GSMEventType GSM_EVENT_TYPE_ERROR = 0, GSM_EVENT_TYPE_BATTERY_CHARGE, GSM_EVENT_TYPE_CALL_PRESENTATION, + GSM_EVENT_TYPE_CALL_WAITING, GSM_EVENT_TYPE_CONTACT, GSM_EVENT_TYPE_CONTACT_LIST, GSM_EVENT_TYPE_FUNCTIONAL, @@ -198,6 +199,13 @@ typedef union _GSMEvent unsigned int format; } call_presentation; + /* GSM_EVENT_TYPE_CALL_WAITING_CONTROL */ + struct + { + GSMEventType type; + unsigned int unsollicited; + } call_waiting_control; + /* GSM_EVENT_TYPE_CONTACT */ struct { @@ -317,7 +325,7 @@ void gsm_set_callback(GSM * gsm, GSMCallback callback, gpointer data); unsigned int gsm_get_retry(GSM * gsm); int gsm_set_call_presentation(GSM * gsm, int set); -int gsm_set_call_waiting(GSM * gsm, int unsollicited, int mode); +int gsm_set_call_waiting_control(GSM * gsm, int unsollicited); int gsm_set_extended_ring_reports(GSM * gsm, int extended); int gsm_set_functional(GSM * gsm, int functional); int gsm_set_line_presentation(GSM * gsm, int set); @@ -355,7 +363,7 @@ int gsm_fetch_signal_level(GSM * gsm); /* queries */ int gsm_is_alive(GSM * gsm); -int gsm_is_call_waiting(GSM * gsm); +int gsm_is_call_waiting_control(GSM * gsm); int gsm_is_functional(GSM * gsm); int gsm_is_mute(GSM * gsm); int gsm_is_phone_active(GSM * gsm); diff --git a/src/modem.c b/src/modem.c index 7137202..c631104 100644 --- a/src/modem.c +++ b/src/modem.c @@ -351,10 +351,10 @@ int gsm_modem_is_alive(GSMModem * gsmm) } -/* gsm_modem_is_call_waiting */ -int gsm_modem_is_call_waiting(GSMModem * gsmm) +/* gsm_modem_is_call_waiting_control */ +int gsm_modem_is_call_waiting_control(GSMModem * gsmm) { - char const cmd[] = "AT+CCWA"; + char const cmd[] = "AT+CCWA?"; return (gsm_queue(gsmm->gsm, cmd) != NULL) ? 0 : 1; } @@ -581,25 +581,23 @@ int gsm_modem_set_call_presentation(GSMModem * gsmm, gboolean set) } -/* gsm_modem_set_call_waiting */ -static void _modem_set_call_waiting_callback(GSM * gsm); +/* gsm_modem_set_call_waiting_control */ +static void _modem_set_call_waiting_control_callback(GSM * gsm); -int gsm_modem_set_call_waiting(GSMModem * gsmm, gboolean unsollicited, - gboolean mode) +int gsm_modem_set_call_waiting_control(GSMModem * gsmm, gboolean unsollicited) { - char cmd[] = "AT+CCWA=X,X"; + char cmd[] = "AT+CCWA=X"; cmd[8] = unsollicited ? '1' : '0'; - cmd[10] = mode ? '1' : '0'; return gsm_queue_full(gsmm->gsm, GSM_PRIORITY_NORMAL, cmd, GSM_ERROR_CALL_WAITING_FAILED, - _modem_set_call_waiting_callback); + _modem_set_call_waiting_control_callback); } -static void _modem_set_call_waiting_callback(GSM * gsm) +static void _modem_set_call_waiting_control_callback(GSM * gsm) { /* did it really work? */ - gsm_is_call_waiting(gsm); + gsm_is_call_waiting_control(gsm); } diff --git a/src/modem.h b/src/modem.h index f7ab2d3..7c97c26 100644 --- a/src/modem.h +++ b/src/modem.h @@ -63,7 +63,7 @@ int gsm_modem_get_registration(GSMModem * gsmm); int gsm_modem_get_signal_level(GSMModem * gsmm); int gsm_modem_is_alive(GSMModem * gsmm); -int gsm_modem_is_call_waiting(GSMModem * gsmm); +int gsm_modem_is_call_waiting_control(GSMModem * gsmm); int gsm_modem_is_functional(GSMModem * gsmm); int gsm_modem_is_mute(GSMModem * gsmm); int gsm_modem_is_phone_active(GSMModem * gsmm); @@ -77,8 +77,7 @@ int gsm_modem_send_message(GSMModem * gsmm, char const * number, char const * text); int gsm_modem_set_call_presentation(GSMModem * gsmm, gboolean set); -int gsm_modem_set_call_waiting(GSMModem * gsmm, gboolean unsollicited, - gboolean mode); +int gsm_modem_set_call_waiting_control(GSMModem * gsmm, gboolean unsollicited); int gsm_modem_set_echo(GSMModem * gsmm, gboolean echo); int gsm_modem_set_extended_errors(GSMModem * gsmm, gboolean extended); int gsm_modem_set_extended_ring_reports(GSMModem * gsmm, gboolean extended); diff --git a/src/phone.c b/src/phone.c index a831086..2b2c68e 100644 --- a/src/phone.c +++ b/src/phone.c @@ -1206,6 +1206,7 @@ static struct { "Alive", gsm_is_alive }, { "Answer call", gsm_call_answer }, { "Battery charge", gsm_fetch_battery_charge }, + { "Call waiting control", gsm_is_call_waiting_control }, { "Contact list", gsm_fetch_contact_list }, { "Disable phone", _gsm_set_functional_disable }, { "Enable phone", _gsm_set_functional_enable }, @@ -2200,6 +2201,10 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) phone_show_call(phone, TRUE, PHONE_CALL_INCOMING, "", event->call_presentation.number); return 0; + case GSM_EVENT_TYPE_CALL_WAITING: + if(event->call_waiting_control.unsollicited == 0) + gsm_set_call_waiting_control(phone->gsm, TRUE); + return 0; case GSM_EVENT_TYPE_CONTACT: phone_contacts_set(phone, event->contact.index, event->contact.name, @@ -2216,14 +2221,13 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) return 0; } gsm_set_call_presentation(phone->gsm, TRUE); - /* FIXME sometimes this fails (check it first) */ - gsm_set_call_waiting(phone->gsm, TRUE, TRUE); gsm_set_extended_ring_reports(phone->gsm, TRUE); gsm_set_operator_mode(phone->gsm, GSM_OPERATOR_MODE_AUTOMATIC); gsm_set_registration_report(phone->gsm, report); gsm_set_supplementary_service_notifications(phone->gsm, TRUE, TRUE); + gsm_is_call_waiting_control(phone->gsm); gsm_is_phone_active(phone->gsm); #ifndef DEBUG _phone_track(phone, PHONE_TRACK_CONTACT_LIST, TRUE);