Hi Frédéric, On 04/07/2011 11:33 AM, Frédéric Danis wrote: > --- > src/emulator.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- > src/voicecall.c | 17 +++++++++++- > 2 files changed, 88 insertions(+), 3 deletions(-) > > diff --git a/src/emulator.c b/src/emulator.c > index f1ccfb3..7559d07 100644 > --- a/src/emulator.c > +++ b/src/emulator.c > @@ -29,6 +29,7 @@ > #include > > #include "ofono.h" > +#include "common.h" > #include "gatserver.h" > #include "gatppp.h" > > @@ -52,6 +53,13 @@ struct ofono_emulator { > gboolean events_ind; > GSList *indicators; > guint ring; > + struct ofono_call *incoming; > + gboolean clip; > + /* > + * '+CLIP: "+",' or '+CCWA: "+",' + phone number > + * + phone type on 3 digits max + terminating null > + */ > + char incoming_str[OFONO_MAX_PHONE_NUMBER_LENGTH + 14 + 1]; You can probably get rid of incoming_str and incoming if you use __ofono_voicecall_find_call_with_type... > }; > > struct indicator { > @@ -200,6 +208,24 @@ static struct indicator *find_indicator(struct ofono_emulator *em, > return NULL; > } > > +static void notify_ring(struct ofono_emulator *em) > +{ > + const char *phone; > + > + g_at_server_send_unsolicited(em->server, "RING"); > + > + if (em->incoming && > + em->incoming->clip_validity == CLIP_VALIDITY_VALID && > + em->incoming_str[0] == '\0') { > + phone = phone_number_to_string(&em->incoming->phone_number); > + sprintf(em->incoming_str, "+CLIP: \"%s\",%d", phone, > + em->incoming->phone_number.type); > + } > + > + if (em->clip && em->incoming_str[0] != '\0') > + g_at_server_send_unsolicited(em->server, em->incoming_str); Keep this simple, I really wouldn't try to optimize a strcpy operation. > +} > + > static gboolean ring_cb(gpointer user_data) > { > struct ofono_emulator *em = user_data; > @@ -211,7 +237,7 @@ static gboolean ring_cb(gpointer user_data) > call_ind = find_indicator(em, OFONO_EMULATOR_IND_CALL, NULL); > > if (call_ind->value == OFONO_EMULATOR_CALL_INACTIVE) > - g_at_server_send_unsolicited(em->server, "RING"); > + notify_ring(em); > > return TRUE; > } > @@ -426,6 +452,42 @@ fail: > } > } > > +static void clip_cb(GAtServer *server, GAtServerRequestType type, > + GAtResult *result, gpointer user_data) > +{ > + struct ofono_emulator *em = user_data; > + GAtResultIter iter; > + int val; > + > + if (em->slc == FALSE) > + goto fail; > + > + switch (type) { > + case G_AT_SERVER_REQUEST_TYPE_SET: > + g_at_result_iter_init(&iter, result); > + g_at_result_iter_next(&iter, ""); > + > + if (!g_at_result_iter_next_number(&iter, &val)) > + goto fail; > + > + if (val != 0 && val != 1) > + goto fail; > + > + /* check this is last parameter */ > + if (g_at_result_iter_skip_next(&iter)) > + goto fail; > + > + em->clip = val; > + > + g_at_server_send_final(server, G_AT_SERVER_RESULT_OK); > + break; > + > + default: > +fail: > + g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR); > + }; > +} > + > static void emulator_add_indicator(struct ofono_emulator *em, const char* name, > int min, int max, int dflt) > { > @@ -511,6 +573,7 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd) > g_at_server_register(em->server, "+BRSF", brsf_cb, em, NULL); > g_at_server_register(em->server, "+CIND", cind_cb, em, NULL); > g_at_server_register(em->server, "+CMER", cmer_cb, em, NULL); > + g_at_server_register(em->server, "+CLIP", clip_cb, em, NULL); > } > > __ofono_atom_register(em->atom, emulator_unregister); > @@ -554,6 +617,7 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem, > /* TODO: Check real local features */ > em->l_features = 32; > em->events_mode = 3; /* default mode is forwarding events */ > + em->incoming_str[0] = '\0'; > > em->atom = __ofono_modem_add_atom_offline(modem, atom_t, > emulator_remove, em); > @@ -763,5 +827,13 @@ void ofono_emulator_set_indicator(struct ofono_emulator *em, > } else if (value != OFONO_EMULATOR_CALLSETUP_INCOMING && em->ring) { > g_source_remove(em->ring); > em->ring = 0; > + em->incoming = NULL; > + em->incoming_str[0] = '\0'; > } > } > + > +void ofono_emulator_incoming_call(struct ofono_emulator *em, > + struct ofono_call *call) > +{ > + em->incoming = call; > +} > diff --git a/src/voicecall.c b/src/voicecall.c > index a3ea6de..8e68243 100644 > --- a/src/voicecall.c > +++ b/src/voicecall.c > @@ -714,6 +714,13 @@ static void emulator_callheld_status_cb(struct ofono_atom *atom, void *data) > GPOINTER_TO_INT(data)); > } > > +static void emulator_incoming_cb(struct ofono_atom *atom, void *data) > +{ > + struct ofono_emulator *em = __ofono_atom_get_data(atom); > + > + ofono_emulator_incoming_call(em, data); > +} > + > static void notify_emulator_call_status(struct ofono_voicecall *vc) > { > struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom); > @@ -726,6 +733,7 @@ static void notify_emulator_call_status(struct ofono_voicecall *vc) > gboolean waiting = FALSE; > GSList *l; > struct voicecall *v; > + struct ofono_call *caller = NULL; > > for (l = vc->call_list; l; l = l->next) { > v = l->data; > @@ -749,10 +757,12 @@ static void notify_emulator_call_status(struct ofono_voicecall *vc) > > case CALL_STATUS_INCOMING: > incoming = TRUE; > + caller = v->call; > break; > > case CALL_STATUS_WAITING: > waiting = TRUE; > + caller = v->call; > break; > } > } > @@ -765,9 +775,12 @@ static void notify_emulator_call_status(struct ofono_voicecall *vc) > emulator_call_status_cb, > GINT_TO_POINTER(status)); > > - if (incoming || waiting) > + if (incoming || waiting) { > status = OFONO_EMULATOR_CALLSETUP_INCOMING; > - else if (dialing) > + __ofono_modem_foreach_registered_atom(modem, > + OFONO_ATOM_TYPE_EMULATOR_HFP, > + emulator_incoming_cb, caller); > + } else if (dialing) > status = OFONO_EMULATOR_CALLSETUP_OUTGOING; > else if (alerting) > status = OFONO_EMULATOR_CALLSETUP_ALERTING; Regards, -Denis