From 6fa34aa104997a7f3a01c0f12f87beb619a40242 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Tue, 11 May 2010 14:12:02 +0000 Subject: [PATCH] Implemented the mute control over AT+CMUT (may not fit the hardware) --- src/callbacks.c | 11 +++++++++++ src/callbacks.h | 1 + src/gsm.c | 31 +++++++++++++++++++++++++++++++ src/gsm.h | 12 ++++++++++++ src/modem.c | 28 ++++++++++++++++++++++++++++ src/modem.h | 2 ++ src/phone.c | 16 ++++++++++++++++ src/phone.h | 1 + 8 files changed, 102 insertions(+) diff --git a/src/callbacks.c b/src/callbacks.c index db141d1..414c81a 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -105,6 +105,17 @@ void on_phone_call_hangup(gpointer data) } +/* on_phone_call_mute */ +void on_phone_call_mute(GtkWidget * widget, gpointer data) +{ + Phone * phone = data; + gboolean mute; + + mute = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + phone_call_mute(phone, mute); +} + + /* on_phone_call_reject */ void on_phone_call_reject(gpointer data) { diff --git a/src/callbacks.h b/src/callbacks.h index a1995b7..e164014 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -30,6 +30,7 @@ GdkFilterReturn on_phone_filter(GdkXEvent * xevent, GdkEvent * event, void on_phone_call_answer(gpointer data); void on_phone_call_close(gpointer data); void on_phone_call_hangup(gpointer data); +void on_phone_call_mute(GtkWidget * widget, gpointer data); void on_phone_call_reject(gpointer data); /* code */ diff --git a/src/gsm.c b/src/gsm.c index 18b2ac2..adf9d5f 100644 --- a/src/gsm.c +++ b/src/gsm.c @@ -173,6 +173,7 @@ static int _gsm_trigger_cmgl(GSM * gsm, char const * result); static int _gsm_trigger_cmgr(GSM * gsm, char const * result); static int _gsm_trigger_cmgs(GSM * gsm, char const * result); static int _gsm_trigger_cmti(GSM * gsm, char const * result); +static int _gsm_trigger_cmut(GSM * gsm, char const * result); static int _gsm_trigger_connect(GSM * gsm, char const * result, gboolean * answered); static int _gsm_trigger_cops(GSM * gsm, char const * result); @@ -208,6 +209,7 @@ static GSMTrigger _gsm_triggers[] = GSM_TRIGGER("+CMGR: ", cmgr), GSM_TRIGGER("+CMGS: ", cmgs), GSM_TRIGGER("+CMTI: ", cmti), + GSM_TRIGGER("+CMUT: ", cmut), GSM_TRIGGER("CONNECT", connect), GSM_TRIGGER("+COPS: ", cops), GSM_TRIGGER("+CPAS: ", cpas), @@ -396,6 +398,13 @@ int gsm_set_line_presentation(GSM * gsm, int set) } +/* gsm_set_mute */ +int gsm_set_mute(GSM * gsm, int mute) +{ + return gsm_modem_set_mute(gsm->modem, (mute != 0) ? TRUE : FALSE); +} + + /* gsm_set_operator_format */ int gsm_set_operator_format(GSM * gsm, GSMOperatorFormat format) { @@ -559,6 +568,9 @@ int gsm_event(GSM * gsm, GSMEventType type, ...) case GSM_EVENT_TYPE_MESSAGE_SENT: event->message_sent.mr = va_arg(ap, unsigned int); break; + case GSM_EVENT_TYPE_MUTE: + event->mute.mute = va_arg(ap, unsigned int); + break; case GSM_EVENT_TYPE_OPERATOR: event->operator.mode = va_arg(ap, GSMOperatorMode); event->operator.format = va_arg(ap, GSMOperatorFormat); @@ -654,6 +666,13 @@ int gsm_is_functional(GSM * gsm) } +/* gsm_is_mute */ +int gsm_is_mute(GSM * gsm) +{ + return gsm_modem_is_mute(gsm->modem); +} + + /* gsm_is_phone_active */ int gsm_is_phone_active(GSM * gsm) { @@ -1308,6 +1327,18 @@ static int _gsm_trigger_cmti(GSM * gsm, char const * result) } +/* gsm_trigger_cmut */ +static int _gsm_trigger_cmut(GSM * gsm, char const * result) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, result); +#endif + if(sscanf(result, "%u", &gsm->event.mute.mute) != 1) + return 1; + return _gsm_event_send(gsm, GSM_EVENT_TYPE_MUTE); +} + + /* gsm_trigger_connect */ static int _gsm_trigger_connect(GSM * gsm, char const * result, gboolean * answered) diff --git a/src/gsm.h b/src/gsm.h index 8b0adc3..f5bd470 100644 --- a/src/gsm.h +++ b/src/gsm.h @@ -56,6 +56,7 @@ typedef enum _GSMEventType GSM_EVENT_TYPE_MESSAGE, GSM_EVENT_TYPE_MESSAGE_LIST, GSM_EVENT_TYPE_MESSAGE_SENT, + GSM_EVENT_TYPE_MUTE, GSM_EVENT_TYPE_OPERATOR, GSM_EVENT_TYPE_PHONE_ACTIVITY, GSM_EVENT_TYPE_REGISTRATION, @@ -78,6 +79,7 @@ typedef enum _GSMError GSM_ERROR_MESSAGE_FETCH_FAILED, GSM_ERROR_MESSAGE_LIST_FAILED, GSM_ERROR_MESSAGE_SEND_FAILED, + GSM_ERROR_MUTE_FAILED, GSM_ERROR_NO_ANSWER, GSM_ERROR_NO_CARRIER, GSM_ERROR_NO_DIALTONE, @@ -253,6 +255,13 @@ typedef union _GSMEvent unsigned int mr; } message_sent; + /* GSM_EVENT_TYPE_MUTE */ + struct + { + GSMEventType type; + unsigned int mute; + } mute; + /* GSM_EVENT_TYPE_OPERATOR */ struct { @@ -310,6 +319,7 @@ int gsm_set_call_presentation(GSM * gsm, int set); 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); +int gsm_set_mute(GSM * gsm, int mute); int gsm_set_operator_format(GSM * gsm, GSMOperatorFormat format); int gsm_set_operator_mode(GSM * gsm, GSMOperatorMode mode); int gsm_set_registration_report(GSM * gsm, GSMRegistrationReport report); @@ -336,12 +346,14 @@ int gsm_fetch_contact_list(GSM * gsm); int gsm_fetch_contacts(GSM * gsm, unsigned int start, unsigned int end); int gsm_fetch_message_list(GSM * gsm, GSMMessageList list); int gsm_fetch_message(GSM * gsm, unsigned int index); +int gsm_fetch_mute(GSM * gsm); 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_mute(GSM * gsm); int gsm_is_phone_active(GSM * gsm); int gsm_is_pin_needed(GSM * gsm); int gsm_is_pin_valid(GSM * gsm); diff --git a/src/modem.c b/src/modem.c index 752c227..62aee9f 100644 --- a/src/modem.c +++ b/src/modem.c @@ -352,6 +352,15 @@ int gsm_modem_is_functional(GSMModem * gsmm) } +/* gsm_modem_is_mute */ +int gsm_modem_is_mute(GSMModem * gsmm) +{ + char const cmd[] = "AT+CMUT?"; + + return (gsm_queue(gsmm->gsm, cmd) != NULL) ? 0 : 1; +} + + /* gsm_modem_is_phone_active */ int gsm_modem_is_phone_active(GSMModem * gsmm) { @@ -632,6 +641,25 @@ int gsm_modem_set_message_format(GSMModem * gsmm, GSMMessageFormat format) } +/* gsm_modem_set_mute */ +static void _modem_set_mute_callback(GSM * gsm); + +int gsm_modem_set_mute(GSMModem * gsmm, gboolean mute) +{ + char cmd[] = "AT+CMUT=X"; + + cmd[8] = mute ? '1' : '0'; + return gsm_queue_full(gsmm->gsm, GSM_PRIORITY_NORMAL, cmd, + GSM_ERROR_MUTE_FAILED, _modem_set_mute_callback); +} + +static void _modem_set_mute_callback(GSM * gsm) +{ + /* did it really work? */ + gsm_is_mute(gsm); +} + + /* gsm_modem_set_operator_format */ int gsm_modem_set_operator_format(GSMModem * gsmm, GSMOperatorFormat format) { diff --git a/src/modem.h b/src/modem.h index aa9ed38..2093480 100644 --- a/src/modem.h +++ b/src/modem.h @@ -63,6 +63,7 @@ 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_mute(GSMModem * gsmm); int gsm_modem_is_phone_active(GSMModem * gsmm); int gsm_modem_is_pin_needed(GSMModem * gsmm); int gsm_modem_is_pin_valid(GSMModem * gsmm); @@ -80,6 +81,7 @@ int gsm_modem_set_extended_ring_reports(GSMModem * gsmm, gboolean extended); int gsm_modem_set_line_presentation(GSMModem * gsmm, gboolean set); int gsm_modem_set_functional(GSMModem * gsmm, gboolean functional); int gsm_modem_set_message_format(GSMModem * gsmm, GSMMessageFormat format); +int gsm_modem_set_mute(GSMModem * gsmm, gboolean mute); int gsm_modem_set_operator_format(GSMModem * gsmm, GSMOperatorFormat format); int gsm_modem_set_operator_mode(GSMModem * gsmm, GSMOperatorMode mode); int gsm_modem_set_registration_report(GSMModem * gsmm, diff --git a/src/phone.c b/src/phone.c index fb1ac3f..519e3ac 100644 --- a/src/phone.c +++ b/src/phone.c @@ -346,6 +346,13 @@ void phone_call_hangup(Phone * phone) } +/* phone_call_mute */ +void phone_call_mute(Phone * phone, gboolean mute) +{ + gsm_set_mute(phone->gsm, mute ? 1 : 0); +} + + /* phone_call_reject */ void phone_call_reject(Phone * phone) { @@ -675,6 +682,8 @@ void phone_show_call(Phone * phone, gboolean show, ...) gtk_image_new_from_icon_name( "audio-input-microphone", GTK_ICON_SIZE_BUTTON)); + g_signal_connect(G_OBJECT(phone->ca_mute), "toggled", + G_CALLBACK(on_phone_call_mute), phone); gtk_box_pack_start(GTK_BOX(vbox), phone->ca_mute, FALSE, TRUE, 0); gtk_container_add(GTK_CONTAINER(phone->ca_window), vbox); @@ -893,6 +902,7 @@ static struct { "Messages sent", _gsm_fetch_message_list_sent }, { "Messages unread", _gsm_fetch_message_list_unread }, { "Messages unsent", _gsm_fetch_message_list_unsent }, + { "Mute", gsm_is_mute }, { "Operator", gsm_fetch_operator }, { "Phone active", gsm_is_phone_active }, { "Phone functional", gsm_is_functional }, @@ -1844,6 +1854,12 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) _phone_info(phone, phone->wr_window, _("Message sent"), NULL); return 0; + case GSM_EVENT_TYPE_MUTE: + if(phone->ca_window != NULL) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON( + phone->ca_mute), + event->mute.mute); + return 0; case GSM_EVENT_TYPE_OPERATOR: _phone_set_operator(phone, event->operator.operator); return 0; diff --git a/src/phone.h b/src/phone.h index 908f4ef..129b63d 100644 --- a/src/phone.h +++ b/src/phone.h @@ -77,6 +77,7 @@ void phone_show_write(Phone * phone, gboolean show); /* calls */ void phone_call_answer(Phone * phone); void phone_call_hangup(Phone * phone); +void phone_call_mute(Phone * phone, gboolean mute); void phone_call_reject(Phone * phone); /* code */