From b9197def5502255e1fe330dc0e8d6b83f5120889 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 9 May 2010 18:34:24 +0000 Subject: [PATCH] Implemented call presentation (partly tested) --- src/gsm.c | 34 ++++++++++++++++++++++++++++++---- src/gsm.h | 9 +++++++++ src/modem.c | 10 ++++++++++ src/modem.h | 1 + src/phone.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/gsm.c b/src/gsm.c index 2c88764..e893831 100644 --- a/src/gsm.c +++ b/src/gsm.c @@ -163,6 +163,7 @@ static int _gsm_trigger_busy(GSM * gsm, char const * result, gboolean * answered); static int _gsm_trigger_cfun(GSM * gsm, char const * result); static int _gsm_trigger_cgmm(GSM * gsm, char const * result); +static int _gsm_trigger_clip(GSM * gsm, char const * result); static int _gsm_trigger_cme_error(GSM * gsm, char const * result, gboolean * answered); static int _gsm_trigger_cms_error(GSM * gsm, char const * result); @@ -192,6 +193,7 @@ static GSMTrigger _gsm_triggers[] = GSM_TRIGGER("BUSY", busy), GSM_TRIGGER("+CFUN: ", cfun), GSM_TRIGGER("+CGMM: ", cgmm), + GSM_TRIGGER("+CLIP: ", clip), GSM_TRIGGER("+CME ERROR: ", cme_error), GSM_TRIGGER("+CMS ERROR: ", cms_error), GSM_TRIGGER("+CMGL: ", cmgl), @@ -456,12 +458,18 @@ int gsm_event(GSM * gsm, GSMEventType type, ...) { case GSM_EVENT_TYPE_ERROR: event->error.error = va_arg(ap, GSMError); - event->error.message = va_arg(ap, char *); + event->error.message = va_arg(ap, char const *); + break; + case GSM_EVENT_TYPE_CALL_PRESENTATION: + event->call_presentation.number = va_arg(ap, + char const *); + event->call_presentation.format = 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 *); - event->contact.number = va_arg(ap, char *); + event->contact.name = va_arg(ap, char const *); + event->contact.number = va_arg(ap, char const *); break; case GSM_EVENT_TYPE_CONTACT_LIST: event->contact_list.start = va_arg(ap, unsigned int); @@ -484,7 +492,7 @@ int gsm_event(GSM * gsm, GSMEventType type, ...) case GSM_EVENT_TYPE_OPERATOR: event->operator.mode = va_arg(ap, GSMOperatorMode); event->operator.format = va_arg(ap, GSMOperatorFormat); - event->operator.operator = va_arg(ap, char *); + event->operator.operator = va_arg(ap, char const *); event->operator.lai = va_arg(ap, unsigned int); break; case GSM_EVENT_TYPE_REGISTRATION: @@ -804,6 +812,7 @@ static int _parse_do(GSM * gsm, size_t * i) /* XXX should probably not be set by us */ gsm_modem_set_extended_errors(gsm->modem, TRUE); gsm_modem_set_extended_ring_reports(gsm->modem, TRUE); + gsm_modem_set_call_presentation(gsm->modem, TRUE); gsm_modem_get_model(gsm->modem); _gsm_event_set_status(gsm, GSM_STATUS_INITIALIZED); _gsm_queue_push(gsm); @@ -1021,6 +1030,22 @@ static int _gsm_trigger_cgmm(GSM * gsm, char const * result) } +/* gsm_trigger_clip */ +static int _gsm_trigger_clip(GSM * gsm, char const * result) +{ + char number[32]; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, result); +#endif + if(sscanf(result, "\"%31[^\"]\", %u", number, + &gsm->event.call_presentation.format) != 2) + return 1; /* XXX report error? */ + gsm->event.call_presentation.number = number; + return _gsm_event_send(gsm, GSM_EVENT_TYPE_CALL_PRESENTATION); +} + + /* gsm_trigger_cme_error */ static int _gsm_trigger_cme_error(GSM * gsm, char const * result, gboolean * answered) @@ -1165,6 +1190,7 @@ static int _gsm_trigger_cpbr(GSM * gsm, char const * result) snprintf(name, sizeof(name), "%s", p); g_free(p); } + /* XXX convert to _gsm_event_send() */ return gsm_event(gsm, GSM_EVENT_TYPE_CONTACT, index, name, number); } diff --git a/src/gsm.h b/src/gsm.h index 4ec6da6..94693b4 100644 --- a/src/gsm.h +++ b/src/gsm.h @@ -38,6 +38,7 @@ typedef void (*GSMCommandCallback)(GSM * gsm); typedef enum _GSMEventType { GSM_EVENT_TYPE_ERROR = 0, + GSM_EVENT_TYPE_CALL_PRESENTATION, GSM_EVENT_TYPE_CONTACT, GSM_EVENT_TYPE_CONTACT_LIST, GSM_EVENT_TYPE_FUNCTIONAL, @@ -147,6 +148,14 @@ typedef union _GSMEvent char const * message; } error; + /* GSM_EVENT_TYPE_CALL_PRESENTATION */ + struct + { + GSMEventType type; + char const * number; + unsigned int format; + } call_presentation; + /* GSM_EVENT_TYPE_CONTACT */ struct { diff --git a/src/modem.c b/src/modem.c index fd6a082..8e99202 100644 --- a/src/modem.c +++ b/src/modem.c @@ -477,6 +477,16 @@ char * _text_to_sept(char const * text) } +/* gsm_modem_set_call_presentation */ +int gsm_modem_set_call_presentation(GSMModem * gsmm, gboolean set) +{ + char cmd[] = "AT+CLIP=X"; + + cmd[8] = set ? '1' : '0'; + return (gsm_queue(gsmm->gsm, cmd) != NULL) ? 0 : 1; +} + + /* gsm_modem_set_echo */ int gsm_modem_set_echo(GSMModem * gsmm, gboolean echo) { diff --git a/src/modem.h b/src/modem.h index 654959a..8cc9276 100644 --- a/src/modem.h +++ b/src/modem.h @@ -68,6 +68,7 @@ int gsm_modem_reset(GSMModem * gsmm); 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_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 2a6f8fd..98ea519 100644 --- a/src/phone.c +++ b/src/phone.c @@ -73,6 +73,8 @@ struct _Phone /* call */ GtkWidget * ca_window; + GtkWidget * ca_name; + GtkWidget * ca_number; GtkWidget * ca_answer; GtkWidget * ca_hangup; GtkWidget * ca_image; @@ -427,7 +429,7 @@ int phone_dialer_append(Phone * phone, char character) if((character < '0' || character > '9') && character != '*' && character != '+' && character != '#') return 1; /* ignore the error */ - /* FIXME ask GSM if in a call; if yes, send DTMF */ + /* FIXME if in a call send DTMF instead */ text = gtk_entry_get_text(GTK_ENTRY(phone->di_entry)); len = strlen(text); if((p = malloc(len + 2)) == NULL) @@ -442,12 +444,13 @@ int phone_dialer_append(Phone * phone, char character) /* phone_dialer_call */ void phone_dialer_call(Phone * phone, char const * number) { + /* FIXME check if it's either a name or number */ if(number == NULL) number = gtk_entry_get_text(GTK_ENTRY(phone->di_entry)); if(number[0] == '\0') number = NULL; /* call the last number dialled */ gsm_call(phone->gsm, GSM_CALL_TYPE_VOICE, number); - phone_show_call(phone, TRUE, PHONE_CALL_OUTGOING); + phone_show_call(phone, TRUE, PHONE_CALL_OUTGOING, " ", number); } @@ -483,6 +486,8 @@ void phone_show_call(Phone * phone, gboolean show, ...) { va_list ap; PhoneCall call; + char const * name = NULL; + char const * number = NULL; GtkWidget * vbox; GtkWidget * hbox; @@ -494,6 +499,11 @@ void phone_show_call(Phone * phone, gboolean show, ...) } va_start(ap, show); call = va_arg(ap, PhoneCall); + if(call == PHONE_CALL_INCOMING || call == PHONE_CALL_OUTGOING) + { + name = va_arg(ap, char const *); + number = va_arg(ap, char const *); + } va_end(ap); if(phone->ca_window == NULL) { @@ -506,6 +516,14 @@ void phone_show_call(Phone * phone, gboolean show, ...) #endif vbox = gtk_vbox_new(FALSE, 4); gtk_container_set_border_width(GTK_CONTAINER(vbox), 4); + /* party */ + phone->ca_name = gtk_label_new(NULL); + gtk_widget_modify_font(phone->ca_name, phone->bold); + gtk_box_pack_start(GTK_BOX(vbox), phone->ca_name, FALSE, TRUE, + 0); + phone->ca_number = gtk_label_new(NULL); + gtk_box_pack_start(GTK_BOX(vbox), phone->ca_number, FALSE, TRUE, + 0); /* buttons */ /* answer */ phone->ca_answer = _phone_create_button("call-start", @@ -564,6 +582,20 @@ void phone_show_call(Phone * phone, gboolean show, ...) gtk_container_add(GTK_CONTAINER(phone->ca_window), vbox); } phone_show_dialer(phone, FALSE); + if(name != NULL) + { + if(name[0] == '\0') + /* XXX look it up if we have the number */ + name = _("Unknown contact"); + gtk_label_set_text(GTK_LABEL(phone->ca_name), name); + } + if(number != NULL) + { + if(number[0] == '\0') + /* XXX look it up if we have the name */ + number = _("Unknown number"); + gtk_label_set_text(GTK_LABEL(phone->ca_number), number); + } gtk_widget_show_all(phone->ca_window); switch(call) { @@ -1382,6 +1414,11 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) { case GSM_EVENT_TYPE_ERROR: return _gsm_event_error(phone, event); + case GSM_EVENT_TYPE_CALL_PRESENTATION: + /* FIXME convert number, the contact is automatic */ + phone_show_call(phone, TRUE, PHONE_CALL_INCOMING, "", + event->call_presentation.number); + return 0; case GSM_EVENT_TYPE_CONTACT: phone_contacts_add(phone, event->contact.index, event->contact.name, @@ -1404,7 +1441,8 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) _phone_track(phone, PHONE_TRACK_MESSAGE_LIST, TRUE); return 0; case GSM_EVENT_TYPE_INCOMING_CALL: - phone_show_call(phone, TRUE, PHONE_CALL_INCOMING); + phone_show_call(phone, TRUE, PHONE_CALL_INCOMING, "", + ""); return 0; case GSM_EVENT_TYPE_MESSAGE_LIST: _phone_fetch_messages(phone, event->message_list.start,