From 379d8a6b735c3419a8250a3488d2f3642c320c2e Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Wed, 2 Nov 2011 17:32:00 +0000 Subject: [PATCH] The "sofia" plug-in is beginning to be usable --- po/fr.po | 52 +++++++++--------- src/modems/sofia.c | 129 ++++++++++++++++++++++++++++++++------------- src/phone.c | 28 ++++++---- 3 files changed, 136 insertions(+), 73 deletions(-) diff --git a/po/fr.po b/po/fr.po index 94ec831..4088bd0 100644 --- a/po/fr.po +++ b/po/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Phone 0.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-02 02:39+0100\n" +"POT-Creation-Date: 2011-11-02 18:30+0100\n" "PO-Revision-Date: 2010-04-24 02:07+0200\n" "Last-Translator: Pierre Pronchery \n" "Language-Team: DeforaOS development (French) \n" @@ -47,7 +47,7 @@ msgstr "Brouillons" msgid "Trash" msgstr "Corbeille" -#: ../src/phone.c:507 ../src/phone.c:2631 +#: ../src/phone.c:507 ../src/phone.c:2632 msgid "System preferences" msgstr "Préférences système" @@ -226,7 +226,7 @@ msgstr "nouveaux messages" msgid "new message" msgstr "nouveau message" -#: ../src/phone.c:2499 ../src/phone.c:3439 ../src/phone.c:3443 +#: ../src/phone.c:2499 ../src/phone.c:3449 ../src/phone.c:3453 msgid "Information" msgstr "Information" @@ -242,98 +242,98 @@ msgstr "_Vue" msgid "_Read" msgstr "_Lire" -#: ../src/phone.c:2685 +#: ../src/phone.c:2694 msgid "Open file..." msgstr "Ouvrir fichier..." -#: ../src/phone.c:2858 +#: ../src/phone.c:2868 msgid "Write message" msgstr "Écrire un message" -#: ../src/phone.c:2864 +#: ../src/phone.c:2874 msgid "Send" msgstr "Envoyer" -#: ../src/phone.c:2870 +#: ../src/phone.c:2880 msgid "Attach" msgstr "Joindre" -#: ../src/phone.c:2986 +#: ../src/phone.c:2996 msgid "Attach file..." msgstr "Joindre un fichier..." -#: ../src/phone.c:3058 +#: ../src/phone.c:3068 #, c-format msgid "%d message%s, %d/%d characters" msgstr "%d message%s, %d/%d caractères" -#: ../src/phone.c:3059 +#: ../src/phone.c:3069 msgid "s" msgstr "s" -#: ../src/phone.c:3123 +#: ../src/phone.c:3133 msgid "Sending message..." msgstr "Envoi du message..." -#: ../src/phone.c:3158 +#: ../src/phone.c:3168 msgid "Outgoing" msgstr "Sortant" -#: ../src/phone.c:3344 +#: ../src/phone.c:3354 msgid "Operation in progress..." msgstr "Opération en cours..." -#: ../src/phone.c:3384 ../src/phone.c:3388 +#: ../src/phone.c:3394 ../src/phone.c:3398 msgid "Question" msgstr "Question" -#: ../src/phone.c:3408 ../src/phone.c:3412 +#: ../src/phone.c:3418 ../src/phone.c:3422 msgid "Error" msgstr "Erreur" -#: ../src/phone.c:3641 +#: ../src/phone.c:3651 msgid "Name: " msgstr "Nom: " -#: ../src/phone.c:3650 +#: ../src/phone.c:3660 msgid "Number: " msgstr "Numéro: " -#: ../src/phone.c:3666 +#: ../src/phone.c:3676 msgid "New contact" msgstr "Nouveau contact" -#: ../src/phone.c:3668 +#: ../src/phone.c:3678 msgid "Edit contact: " msgstr "Modifier contact: " -#: ../src/phone.c:3695 +#: ../src/phone.c:3705 msgid "The name cannot be empty" msgstr "Le nom ne peut être vide" -#: ../src/phone.c:3700 +#: ../src/phone.c:3710 msgid "The number cannot be empty" msgstr "Le numéro ne peut être vide" -#: ../src/phone.c:3834 +#: ../src/phone.c:3844 msgid "Message sent" msgstr "Message envoyé" -#: ../src/phone.c:3860 +#: ../src/phone.c:3870 #, c-format msgid "Wrong %s" msgstr "Mauvais %s" -#: ../src/phone.c:3869 +#: ../src/phone.c:3879 #, c-format msgid "%s is valid" msgstr "%s valide" -#: ../src/phone.c:3935 +#: ../src/phone.c:3945 msgid "Raw data (not shown)" msgstr "Données brutes (non affichées)" -#: ../src/phone.c:3971 +#: ../src/phone.c:3981 msgid "Message deleted" msgstr "Message effacé" diff --git a/src/modems/sofia.c b/src/modems/sofia.c index 4d261dc..5a87e13 100644 --- a/src/modems/sofia.c +++ b/src/modems/sofia.c @@ -40,21 +40,29 @@ typedef struct _Sofia typedef enum _SofiaConfig { - SOFIA_CONFIG_REGISTRAR = 0, - SOFIA_CONFIG_USERNAME, - SOFIA_CONFIG_PROXY + SOFIA_CONFIG_USERNAME = 0, + SOFIA_CONFIG_FULLNAME, + SOFIA_CONFIG_REGISTRAR_HOSTNAME = 3, + SOFIA_CONFIG_REGISTRAR_USERNAME, + SOFIA_CONFIG_REGISTRAR_PASSWORD, + SOFIA_CONFIG_PROXY_HOSTNAME = 7 } SofiaConfig; -#define SOFIA_CONFIG_LAST SOFIA_CONFIG_PROXY +#define SOFIA_CONFIG_LAST SOFIA_CONFIG_PROXY_HOSTNAME #define SOFIA_CONFIG_COUNT (SOFIA_CONFIG_LAST + 1) /* variables */ static ModemConfig _sofia_config[SOFIA_CONFIG_COUNT + 1] = { - { "registrar", "Registrar", MCT_STRING, NULL }, - { "username", "Username", MCT_STRING, NULL }, - { "proxy", "Proxy", MCT_STRING, NULL }, - { NULL, NULL, MCT_NONE, NULL }, + { "username", "Username", MCT_STRING, NULL }, + { "fullname", "Full name", MCT_STRING, NULL }, + { "", "Registrar", MCT_NONE, NULL }, + { "registrar_hostname", "Hostname", MCT_STRING, NULL }, + { "registrar_username", "Username", MCT_STRING, NULL }, + { "registrar_password", "Password", MCT_STRING, NULL }, + { "", "Proxy", MCT_NONE, NULL }, + { "proxy_hostname", "Hostname", MCT_STRING, NULL }, + { NULL, NULL, MCT_NONE, NULL }, }; @@ -134,10 +142,14 @@ static int _sofia_destroy(ModemPlugin * modem) /* sofia_start */ static int _sofia_start(ModemPlugin * modem, unsigned int retry) { + ModemPluginHelper * helper = modem->helper; Sofia * sofia = modem->priv; - char const * registrar = modem->config[SOFIA_CONFIG_REGISTRAR].value; - char const * proxy = modem->config[SOFIA_CONFIG_PROXY].value; char const * username = modem->config[SOFIA_CONFIG_USERNAME].value; + char const * fullname = modem->config[SOFIA_CONFIG_FULLNAME].value; + url_string_t us; + char const * s; + url_t * url; + sip_from_t * from; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); @@ -145,17 +157,35 @@ static int _sofia_start(ModemPlugin * modem, unsigned int retry) if(sofia->nua != NULL) /* already started */ return 0; if((sofia->nua = nua_create(sofia->root, _sofia_callback, modem, - TAG_NULL())) == NULL) + TAG_END())) == NULL) return -1; - nua_set_params(sofia->nua, NUTAG_REGISTRAR(registrar), - NUTAG_PROXY(proxy), TAG_NULL()); - sofia->handle = nua_handle(sofia->nua, modem, TAG_NULL()); - nua_register(sofia->handle, NUTAG_M_USERNAME(username), TAG_NULL()); + /* registrar */ + s = modem->config[SOFIA_CONFIG_REGISTRAR_HOSTNAME].value; + url = url_make(sofia->home, s); + nua_set_params(sofia->nua, NUTAG_REGISTRAR(url), TAG_END()); + s = modem->config[SOFIA_CONFIG_REGISTRAR_USERNAME].value; + /* XXX url_make() doesn't prefix with the protocol */ + snprintf(us.us_str, sizeof(us.us_str), "%s%s", "sip:", s); + url = url_make(sofia->home, us.us_str); + us.us_url[0] = *url; + from = sip_from_create(sofia->home, &us); + /* proxy */ + s = modem->config[SOFIA_CONFIG_PROXY_HOSTNAME].value; + url = url_make(sofia->home, s); + nua_set_params(sofia->nua, NUTAG_PROXY(url), TAG_END()); + if((sofia->handle = nua_handle(sofia->nua, modem, TAG_END())) == NULL) + return -helper->error(helper->modem, + "Cannot create operation handle", 1); + nua_register(sofia->handle, NUTAG_M_USERNAME(username), + NUTAG_M_DISPLAY(fullname), SIPTAG_FROM(from), + TAG_END()); return 0; } /* sofia_stop */ +static void _stop_handle(nua_handle_t ** handle); + static int _sofia_stop(ModemPlugin * modem) { Sofia * sofia = modem->priv; @@ -163,9 +193,7 @@ static int _sofia_stop(ModemPlugin * modem) #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif - if(sofia->handle != NULL) - nua_handle_destroy(sofia->handle); - sofia->handle = NULL; + _stop_handle(&sofia->handle); if(sofia->nua != NULL) { nua_shutdown(sofia->nua); @@ -176,6 +204,14 @@ static int _sofia_stop(ModemPlugin * modem) return 0; } +static void _stop_handle(nua_handle_t ** handle) +{ + if(*handle == NULL) + return; + nua_handle_destroy(*handle); + *handle = NULL; +} + /* sofia_request */ static int _request_call(ModemPlugin * modem, ModemRequest * request); @@ -201,37 +237,36 @@ static int _request_call(ModemPlugin * modem, ModemRequest * request) { Sofia * sofia = modem->priv; url_t * url; - struct { nua_handle_t * handle; } * op; + url_string_t us; sip_to_t * to; + if(sofia->handle == NULL || nua_handle_has_active_call(sofia->handle)) + /* FIXME report error, keep track, allow multiple */ + return -1; if((url = url_make(sofia->home, request->call.number)) == NULL) return -1; - if((op = su_zalloc(sofia->home, sizeof(*op))) == NULL) - return -1; /* XXX free url? */ - if((to = sip_to_create(NULL, url)) == NULL) - return -1; /* XXX free url and op? */ - to->a_display = "Private"; /* XXX look it up */ - if((op->handle = nua_handle(sofia->nua, op, SIPTAG_TO(to), TAG_END())) - == NULL) - return -modem->helper->error(modem->helper->modem, - "Cannot create operation handle", 1); - nua_invite(op->handle, /* other tags as needed ... */ TAG_END()); - /* XXX free url and op? */ + us.us_url[0] = *url; + if((to = sip_to_create(NULL, &us)) == NULL) + return -1; /* XXX free url */ + to->a_display = request->call.number; + nua_invite(sofia->handle, SIPTAG_TO(to), TAG_END()); + /* FIXME free url? more? */ return 0; } static int _request_message_send(ModemPlugin * modem, ModemRequest * request) { Sofia * sofia = modem->priv; - struct { nua_handle_t * handle; } * op; + url_string_t us; - if((op = su_zalloc(sofia->home, sizeof(*op))) == NULL) - return -1; /* XXX free url? */ - if((op->handle = nua_handle(sofia->nua, op, NUTAG_URL( - request->message_send.number), - TAG_END())) == NULL) + if(sofia->handle == NULL) + /* FIXME report error */ return -1; - nua_message(op->handle, SIPTAG_CONTENT_TYPE_STR("text/plain"), + snprintf(us.us_str, sizeof(us.us_str), "%s%s", "sip:", + request->message_send.number); + nua_message(sofia->handle, + NUTAG_URL(&us), + SIPTAG_CONTENT_TYPE_STR("text/plain"), SIPTAG_PAYLOAD_STR(request->message_send.content), TAG_END()); return 0; @@ -265,13 +300,31 @@ static void _sofia_callback(nua_event_t event, int status, char const * phrase, /* FIXME report event */ fprintf(stderr, "i_state %03d %s\n", status, phrase); break; + case nua_i_terminated: + memset(&mevent, 0, sizeof(mevent)); + mevent.type = MODEM_EVENT_TYPE_CALL; + /* FIXME also remember the other fields */ + mevent.call.status = MODEM_CALL_STATUS_NONE; + modem->helper->event(modem->helper->modem, &mevent); + break; case nua_r_invite: + memset(&mevent, 0, sizeof(mevent)); + mevent.type = MODEM_EVENT_TYPE_CALL; + mevent.call.call_type = MODEM_CALL_TYPE_VOICE; + mevent.call.direction = MODEM_CALL_DIRECTION_OUTGOING; if(status == 200) + { + mevent.call.status = MODEM_CALL_STATUS_RINGING; nua_ack(nh, TAG_END()); + } else + { + mevent.call.status = MODEM_CALL_STATUS_NONE; /* FIXME report error */ fprintf(stderr, "r_invite %03d %s\n", status, phrase); + } + modem->helper->event(modem->helper->modem, &mevent); break; case nua_r_message: /* FIXME report event */ @@ -285,7 +338,7 @@ static void _sofia_callback(nua_event_t event, int status, char const * phrase, if(status == 200) mevent.registration.status = MODEM_REGISTRATION_STATUS_REGISTERED; - else if(status == 405) + else if(status == 401 || status == 405) mevent.registration.status = MODEM_REGISTRATION_STATUS_DENIED; else if(status >= 400 && status <= 499) diff --git a/src/phone.c b/src/phone.c index f090534..dea491f 100644 --- a/src/phone.c +++ b/src/phone.c @@ -2600,10 +2600,11 @@ static void _system_on_ok(gpointer data); void phone_show_system(Phone * phone, gboolean show) { + GtkSizeGroup * group; GtkWidget * vbox; GtkWidget * widget; GtkWidget * bbox; - GtkSizeGroup * group; + GtkWidget * vbox2; ModemConfig * config; size_t i; @@ -2633,13 +2634,21 @@ void phone_show_system(Phone * phone, gboolean show) G_CALLBACK(_system_on_closex), phone); vbox = gtk_vbox_new(FALSE, 4); config = modem_get_config(phone->modem); + vbox2 = vbox; for(i = 0; config != NULL && config[i].name != NULL; i++) - { - widget = _system_widget(phone, &config[i], group); - if(widget == NULL) - continue; - gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0); - } + if(config[i].type == MCT_NONE) + { + widget = gtk_frame_new(config[i].title); + gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, + 0); + vbox2 = gtk_vbox_new(FALSE, 4); + gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4); + gtk_container_add(GTK_CONTAINER(widget), vbox2); + } + else if((widget = _system_widget(phone, &config[i], group)) + != NULL) + gtk_box_pack_start(GTK_BOX(vbox2), widget, FALSE, TRUE, + 0); bbox = gtk_hbutton_box_new(); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); gtk_box_set_spacing(GTK_BOX(bbox), 4); @@ -2667,7 +2676,7 @@ static GtkWidget * _system_widget(Phone * phone, ModemConfig * config, switch(config->type) { - case MCT_NONE: /* XXX should not happen */ + case MCT_NONE: /* should not happen */ break; case MCT_BOOLEAN: widget = gtk_check_button_new_with_label(config->title); @@ -2686,8 +2695,9 @@ static GtkWidget * _system_widget(Phone * phone, ModemConfig * config, GTK_FILE_CHOOSER_ACTION_OPEN); gtk_box_pack_start(GTK_BOX(ret), widget, TRUE, TRUE, 0); break; - case MCT_STRING: case MCT_UINT32: + /* FIXME really implement */ + case MCT_STRING: ret = gtk_hbox_new(FALSE, 4); label = string_new_append(config->title, ": ", NULL); widget = gtk_label_new(label);