bluetooth: add CIND and CIEV support in HFP AG
v2 cover bluetooth: add CIND and CIEV support in HFP AG
Add indicator support in emulator atom
Add CIND and CIEV support for HFP AG
Frédéric Danis (3):
emulator: add indicator support API
emulator: add support of indicators
emulator: add CIND support
include/emulator.h | 11 +++++ src/emulator.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/network.c | 74 ++++++++++++++++++++++++++++++- 3 files changed, 208 insertions(+), 1 deletions(-)
PATCH v2 1/3 emulator: add indicator support API
--- include/emulator.h | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
include/emulator.h +11 -0
@@ -28,6 +28,14 @@ extern "C" {#include <ofono/types.h> +#define OFONO_EMULATOR_IND_BATTERY "battchg" +#define OFONO_EMULATOR_IND_CALL "call" +#define OFONO_EMULATOR_IND_CALLHELD "callheld" +#define OFONO_EMULATOR_IND_CALLSETUP "callsetup" +#define OFONO_EMULATOR_IND_ROAMING "roam" +#define OFONO_EMULATOR_IND_SERVICE "service" +#define OFONO_EMULATOR_IND_SIGNAL "signal" +struct ofono_emulator ;struct ofono_emulator_request ;
@@ -82,6 +90,9 @@ const char *ofono_emulator_request_get_raw(struct ofono_emulator_request *req);enum ofono_emulator_request_type ofono_emulator_request_get_type (struct ofono_emulator_request *req); +void ofono_emulator_set_indicator (struct ofono_emulator *em, +const char *name,int value); + #ifdef __cplusplus }#endif
Signature · 1 line
1.7.1
PATCH v2 2/3 emulator: add support of indicators
In reply to Frédéric Danis--- src/emulator.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/network.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 1 deletions(-)
src/emulator.c +68 -0
@@ -24,6 +24,7 @@#endif #include <stdio.h> +#include <string.h> #include <glib.h>
@@ -42,8 +43,17 @@ struct ofono_emulator {GAtServer *server;GAtPPP *ppp;guint source; +GSList *indicators; }; +struct indicator { +const char *name; +int value; +int min; +int max; +}; + +static void emulator_debug (const char *str,void *data) {ofono_info ("%s: %s\n" , (char *)data, str);
@@ -163,6 +173,25 @@ error:g_at_server_send_final (em->server,G_AT_SERVER_RESULT_ERROR ); } +static void emulator_add_indicator (struct ofono_emulator *em,const char * name, +int min,int max,int dflt) +{ +struct indicator *ind; + + ind = g_try_new0(struct indicator, 1); +if (ind ==NULL ) { +ofono_error ("Unable to allocate indicator structure" ); +return ; + } + + ind->name = name; + ind->min = min; + ind->max = max; + ind->value = dflt; + + em->indicators =g_slist_append (em->indicators, ind); +} +static void emulator_unregister (struct ofono_atom *atom) {struct ofono_emulator *em =__ofono_atom_get_data (atom);
@@ -174,6 +203,10 @@ static void emulator_unregister(struct ofono_atom *atom) em->source =0 ; } +g_slist_foreach (em->indicators, (GFunc ) g_free,NULL ); +g_slist_free (em->indicators); + em->indicators =NULL ; +g_at_server_unref (em->server); em->server =NULL ; }
@@ -199,6 +232,13 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)g_at_server_set_disconnect_function (em->server, emulator_disconnect, em); +if (em->type ==OFONO_EMULATOR_TYPE_HFP ) { +emulator_add_indicator (em,OFONO_EMULATOR_IND_SERVICE ,0 ,1 ,0 ); +emulator_add_indicator (em,OFONO_EMULATOR_IND_SIGNAL ,0 ,5 ,0 ); +emulator_add_indicator (em,OFONO_EMULATOR_IND_ROAMING ,0 ,1 ,0 ); +emulator_add_indicator (em,OFONO_EMULATOR_IND_BATTERY ,0 ,5 ,5 ); + } +__ofono_atom_register (em->atom, emulator_unregister);if (em->type ==OFONO_EMULATOR_TYPE_DUN )
@@ -397,3 +437,31 @@ enum ofono_emulator_request_type ofono_emulator_request_get_type( {return req->type; } + +void ofono_emulator_set_indicator (struct ofono_emulator *em, +const char *name,int value) +{ +GSList *l; +int i; +char buf[20 ]; + + i =1 ; +for (l = em->indicators; l; l = l->next) { +struct indicator *ind = l->data; + +if (!strcmp (ind->name, name)) { +if ((ind->value == value) || (value < ind->min) + || (value > ind->max)) +return ; + + ind->value = value; + +sprintf (buf,"+CIEV: %d,%d" , i, ind->value); +g_at_server_send_info (em->server, buf, TRUE); + +break ; + } + + i++; + } +}
src/network.c +73 -1
133 lines not on this page · raw message
Signature · 1 line
1.7.1
Re: [PATCH 2/3] emulator: add support of indicators
Hi Frédéric,
Quoted 18 lines · Frédéric Danis
--- src/emulator.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/network.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 1 deletions(-)src/emulator.c +1
-0@@ -24,6 +24,7 @@#endif #include <stdio.h> +#include <string.h> #include <glib.h>
src/emulator.c struct ofono_emulator { · line 46
Quoted 4 lines
src/emulator.c +1
-0@@ -42,8 +43,17 @@ struct ofono_emulator {GAtServer *server;GAtPPP *ppp;guint source; +GSList *indicators;
Let us use a GHashtable here
src/emulator.c struct ofono_emulator { · line 50
Quoted 4 lines
src/emulator.c +2
-0}; +struct indicator { +const char *name;
You can't actually do this safely, you should be strduping the string.
src/emulator.c struct ofono_emulator { · line 56
Quoted 6 lines
src/emulator.c +6
-0+int value; +int min; +int max; +}; + +
Why the double newline?
Quoted 152 lines
src/emulator.c +58
-0static void emulator_debug (const char *str,void *data) {ofono_info ("%s: %s\n" , (char *)data, str);@@ -163,6 +173,25 @@ error:g_at_server_send_final (em->server,G_AT_SERVER_RESULT_ERROR ); } +static void emulator_add_indicator (struct ofono_emulator *em,const char * name, +int min,int max,int dflt) +{ +struct indicator *ind; + + ind = g_try_new0(struct indicator, 1); +if (ind ==NULL ) { +ofono_error ("Unable to allocate indicator structure" ); +return ; + } + + ind->name = name; + ind->min = min; + ind->max = max; + ind->value = dflt; + + em->indicators =g_slist_append (em->indicators, ind); +} +static void emulator_unregister (struct ofono_atom *atom) {struct ofono_emulator *em =__ofono_atom_get_data (atom);@@ -174,6 +203,10 @@ static void emulator_unregister(struct ofono_atom *atom) em->source =0 ; } +g_slist_foreach (em->indicators, (GFunc ) g_free,NULL ); +g_slist_free (em->indicators); + em->indicators =NULL ; +g_at_server_unref (em->server); em->server =NULL ; }@@ -199,6 +232,13 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)g_at_server_set_disconnect_function (em->server, emulator_disconnect, em); +if (em->type ==OFONO_EMULATOR_TYPE_HFP ) { +emulator_add_indicator (em,OFONO_EMULATOR_IND_SERVICE ,0 ,1 ,0 ); +emulator_add_indicator (em,OFONO_EMULATOR_IND_SIGNAL ,0 ,5 ,0 ); +emulator_add_indicator (em,OFONO_EMULATOR_IND_ROAMING ,0 ,1 ,0 ); +emulator_add_indicator (em,OFONO_EMULATOR_IND_BATTERY ,0 ,5 ,5 ); + } +__ofono_atom_register (em->atom, emulator_unregister);if (em->type ==OFONO_EMULATOR_TYPE_DUN )@@ -397,3 +437,31 @@ enum ofono_emulator_request_type ofono_emulator_request_get_type( {return req->type; } + +void ofono_emulator_set_indicator (struct ofono_emulator *em, +const char *name,int value) +{ +GSList *l; +int i; +char buf[20 ]; + + i =1 ; +for (l = em->indicators; l; l = l->next) { +struct indicator *ind = l->data; + +if (!strcmp (ind->name, name)) { +if ((ind->value == value) || (value < ind->min) + || (value > ind->max)) +return ; + + ind->value = value; + +sprintf (buf,"+CIEV: %d,%d" , i, ind->value); +g_at_server_send_info (em->server, buf, TRUE); + +break ; + } + + i++; + } +}src/network.c +30
-1@@ -36,6 +36,7 @@#include "simutil.h" #include "util.h" #include "storage.h" +#include "emulator.h" #define NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN 0x1#define NETWORK_REGISTRATION_FLAG_ROAMING_SHOW_SPN 0x2@@ -82,6 +83,7 @@ struct ofono_netreg {const struct ofono_netreg_driver *driver;void *driver_data;struct ofono_atom *atom; +unsigned int hfp_watch; };struct network_operator_data {@@ -1287,15 +1289,42 @@ static void signal_strength_callback(const struct ofono_error *error,ofono_netreg_strength_notify (netreg, strength); } +static void notify_emulator_status (struct ofono_atom *atom,void *data) +{ +struct ofono_emulator *em =__ofono_atom_get_data (atom); + +switch (GPOINTER_TO_INT (data)) { +case NETWORK_REGISTRATION_STATUS_REGISTERED : +ofono_emulator_set_indicator (em,OFONO_EMULATOR_IND_SERVICE ,1 ); +ofono_emulator_set_indicator (em,OFONO_EMULATOR_IND_ROAMING ,0 ); +break ; +case NETWORK_REGISTRATION_STATUS_ROAMING : +ofono_emulator_set_indicator (em,OFONO_EMULATOR_IND_SERVICE ,1 ); +ofono_emulator_set_indicator (em,OFONO_EMULATOR_IND_ROAMING ,1 ); +break ; +default : +ofono_emulator_set_indicator (em,OFONO_EMULATOR_IND_SERVICE ,0 ); +ofono_emulator_set_indicator (em,OFONO_EMULATOR_IND_ROAMING ,0 ); + } +} +void ofono_netreg_status_notify (struct ofono_netreg *netreg,int status,int lac,int ci,int tech) {if (netreg ==NULL )return ; -if (netreg->status != status) +if (netreg->status != status) { +struct ofono_modem *modem; +set_registration_status (netreg, status); + modem =__ofono_atom_get_modem (netreg->atom); +__ofono_modem_foreach_atom (modem,OFONO_ATOM_TYPE_EMULATOR_HFP , + notify_emulator_status, +GINT_TO_POINTER (netreg->status)); + } +if (netreg->location != lac)set_registration_location (netreg, lac);@@ -1375,9 +1404,18 @@ static void init_registration_status(const struct ofono_error *error, }
src/network.c static void init_registration_status(const struct ofono_error *error, · line 1414
Quoted 10 lines
src/network.c +8
-0} +static void notify_emulator_strength (struct ofono_atom *atom,void *data) +{ +struct ofono_emulator *em =__ofono_atom_get_data (atom); + +ofono_emulator_set_indicator (em,OFONO_EMULATOR_IND_SIGNAL , + (GPOINTER_TO_INT (data) +20 ) /21 ); +} +
Please note that strength can actually be negative (e.g. unknown) so you should handle this case.
Also, the scale seems assymetric to me. Shouldn't you do something like:
value = strength > 0 ? (strength - 1) / 20 + 1 : 0?
Quoted 59 lines
src/network.c +31
-0void ofono_netreg_strength_notify (struct ofono_netreg *netreg,int strength) {DBusConnection *conn =ofono_dbus_get_connection (); +struct ofono_modem *modem;if (netreg->signal_strength == strength)return ;@@ -1401,6 +1439,11 @@ void ofono_netreg_strength_notify(struct ofono_netreg *netreg, int strength)"Strength" ,DBUS_TYPE_BYTE , &strength); } + + modem =__ofono_atom_get_modem (netreg->atom); +__ofono_modem_foreach_atom (modem,OFONO_ATOM_TYPE_EMULATOR_HFP , + notify_emulator_strength, +GINT_TO_POINTER (netreg->signal_strength)); } static void sim_opl_read_cb(int ok, int length, int record,@@ -1656,6 +1699,14 @@ static void netreg_unregister(struct ofono_atom *atom)const char *path =__ofono_atom_get_path (atom);GSList *l; +__ofono_modem_foreach_atom (modem,OFONO_ATOM_TYPE_EMULATOR_HFP , + notify_emulator_status, +GINT_TO_POINTER (0 )); +__ofono_modem_foreach_atom (modem,OFONO_ATOM_TYPE_EMULATOR_HFP , + notify_emulator_strength,GINT_TO_POINTER (0 )); + +__ofono_modem_remove_atom_watch (modem, netreg->hfp_watch); +__ofono_watchlist_free (netreg->status_watches); netreg->status_watches =NULL ;@@ -1837,6 +1888,23 @@ static void sim_spn_spdi_changed(int id, void *userdata) sim_spn_read_cb, netreg); } +static void emulator_hfp_watch (struct ofono_atom *atom, +enum ofono_atom_watch_condition cond, +void *data) +{ +struct ofono_netreg *netreg = data; +struct ofono_modem *modem =__ofono_atom_get_modem (netreg->atom); + +if (cond ==OFONO_ATOM_WATCH_CONDITION_REGISTERED ) { +__ofono_modem_foreach_atom (modem,OFONO_ATOM_TYPE_EMULATOR_HFP , + notify_emulator_status, +GINT_TO_POINTER (netreg->status)); +__ofono_modem_foreach_atom (modem,OFONO_ATOM_TYPE_EMULATOR_HFP , + notify_emulator_strength, +GINT_TO_POINTER (netreg->signal_strength)); + } +} +void ofono_netreg_register (struct ofono_netreg *netreg) {DBusConnection *conn =ofono_dbus_get_connection ();
src/network.c void ofono_netreg_register(struct ofono_netreg *netreg) · line 1971
Quoted 10 lines
src/network.c +4
-0@@ -1894,6 +1962,10 @@ void ofono_netreg_register(struct ofono_netreg *netreg) }__ofono_atom_register (netreg->atom, netreg_unregister); + + netreg->hfp_watch =__ofono_modem_add_atom_watch (modem, +OFONO_ATOM_TYPE_EMULATOR_HFP , + emulator_hfp_watch, netreg,NULL ); }void ofono_netreg_remove (struct ofono_netreg *netreg)
Otherwise looks good.
Regards,
-Denis
PATCH v2 3/3 emulator: add CIND support
In reply to Frédéric Danis--- src/emulator.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 56 insertions(+), 0 deletions(-)
src/emulator.c +56 -0
@@ -51,6 +51,7 @@ struct indicator {int value;int min;int max; +char separator; };
@@ -173,6 +174,58 @@ error:g_at_server_send_final (em->server,G_AT_SERVER_RESULT_ERROR ); } +static void cind_cb (GAtServer *server,GAtServerRequestType type, +GAtResult *result,gpointer user_data) +{ +struct ofono_emulator *em = user_data; +GSList *l = em->indicators; +struct indicator *ind = l->data; +GString *gstr; +char *buf; + +switch (type) { +case G_AT_SERVER_REQUEST_TYPE_QUERY : + gstr =g_string_new ("+CIND: " ); +g_string_append_printf (gstr,"%d" , ind->value); + + l = l->next; +while (l) { + ind = l->data; +g_string_append_printf (gstr,",%d" , ind->value); + l = l->next; + } + buf =g_string_free (gstr, FALSE); + +g_at_server_send_info (em->server, buf, FALSE); +g_free (buf); +g_at_server_send_final (server,G_AT_SERVER_RESULT_OK ); +break ; + +case G_AT_SERVER_REQUEST_TYPE_SUPPORT : + gstr =g_string_new ("+CIND: " ); +g_string_append_printf (gstr,"(\"%s\",(%d%c%d))" , + ind->name, ind->min, ind->separator, ind->max); + + l = l->next; +while (l) { + ind = l->data; +g_string_append_printf (gstr,",(\"%s\",(%d%c%d))" , + ind->name, ind->min, ind->separator, ind->max); + l = l->next; + } + buf =g_string_free (gstr, FALSE); + +g_at_server_send_info (server, buf, FALSE); +g_free (buf); +g_at_server_send_final (server,G_AT_SERVER_RESULT_OK ); +break ; + +default : +g_at_server_send_final (server,G_AT_SERVER_RESULT_ERROR ); +break ; + } +} +static void emulator_add_indicator (struct ofono_emulator *em,const char * name,int min,int max,int dflt) {
@@ -188,6 +241,7 @@ static void emulator_add_indicator(struct ofono_emulator *em, const char* name, ind->min = min; ind->max = max; ind->value = dflt; + ind->separator = ((max - min) ==1 ) ?',' :'-' ; em->indicators =g_slist_append (em->indicators, ind); }
@@ -237,6 +291,8 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)emulator_add_indicator (em,OFONO_EMULATOR_IND_SIGNAL ,0 ,5 ,0 );emulator_add_indicator (em,OFONO_EMULATOR_IND_ROAMING ,0 ,1 ,0 );emulator_add_indicator (em,OFONO_EMULATOR_IND_BATTERY ,0 ,5 ,5 ); + +g_at_server_register (em->server,"+CIND" , cind_cb, em,NULL ); }__ofono_atom_register (em->atom, emulator_unregister);
Signature · 1 line
1.7.1
Re: [PATCH 3/3] emulator: add CIND support
Hi Frédéric,
Quoted 18 lines · Frédéric Danis
--- src/emulator.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 56 insertions(+), 0 deletions(-)src/emulator.c +1
-0@@ -51,6 +51,7 @@ struct indicator {int value;int min;int max; +char separator; };@@ -173,6 +174,58 @@ error:g_at_server_send_final (em->server,G_AT_SERVER_RESULT_ERROR );
src/emulator.c error: · line 184
Quoted 10 lines
src/emulator.c +8
-0} +static void cind_cb (GAtServer *server,GAtServerRequestType type, +GAtResult *result,gpointer user_data) +{ +struct ofono_emulator *em = user_data; +GSList *l = em->indicators; +struct indicator *ind = l->data; +GString *gstr; +char *buf;
I prefer we do a simple pre-calculation of the space required. If it helps the implementation, limit the min and max values to something reasonable, e.g. 0-999.
src/emulator.c error: · line 191
Quoted 7 lines
src/emulator.c +7
-0+ +switch (type) { +case G_AT_SERVER_REQUEST_TYPE_QUERY : + gstr =g_string_new ("+CIND: " ); +g_string_append_printf (gstr,"%d" , ind->value); + + l = l->next;
doc/coding-style.txt M1.
src/emulator.c error: · line 192
Quoted 1 line
src/emulator.c +1
-0+while (l) {
These style loops look more compact using a for loop, e.g.:
for (l = em->indicators; l; l = l->next) {
...
}src/emulator.c error: · line 197
Quoted 5 lines
src/emulator.c +5
-0+ ind = l->data; +g_string_append_printf (gstr,",%d" , ind->value); + l = l->next; + } + buf =g_string_free (gstr, FALSE);
doc/coding-style.txt M1
src/emulator.c error: · line 207
Quoted 10 lines
src/emulator.c +10
-0+ +g_at_server_send_info (em->server, buf, FALSE); +g_free (buf); +g_at_server_send_final (server,G_AT_SERVER_RESULT_OK ); +break ; + +case G_AT_SERVER_REQUEST_TYPE_SUPPORT : + gstr =g_string_new ("+CIND: " ); +g_string_append_printf (gstr,"(\"%s\",(%d%c%d))" , + ind->name, ind->min, ind->separator, ind->max);
doc/coding-style.txt M4
Quoted 25 lines
src/emulator.c +21
-0+ + l = l->next; +while (l) { + ind = l->data; +g_string_append_printf (gstr,",(\"%s\",(%d%c%d))" , + ind->name, ind->min, ind->separator, ind->max); + l = l->next; + } + buf =g_string_free (gstr, FALSE); + +g_at_server_send_info (server, buf, FALSE); +g_free (buf); +g_at_server_send_final (server,G_AT_SERVER_RESULT_OK ); +break ; + +default : +g_at_server_send_final (server,G_AT_SERVER_RESULT_ERROR ); +break ; + } +} +static void emulator_add_indicator (struct ofono_emulator *em,const char * name,int min,int max,int dflt) {
src/emulator.c static void emulator_add_indicator(struct ofono_emulator *em, const char* name, · line 244
Quoted 4 lines
src/emulator.c +1
-0@@ -188,6 +241,7 @@ static void emulator_add_indicator(struct ofono_emulator *em, const char* name, ind->min = min; ind->max = max; ind->value = dflt; + ind->separator = ((max - min) ==1 ) ?',' :'-' ;
I prefer you do this magic inside cind_cb and avoid storing it inside the indicator structure.
src/emulator.c void ofono_emulator_register(struct ofono_emulator *em, int fd) · line 298
Quoted 12 lines
src/emulator.c +2
-0em->indicators =g_slist_append (em->indicators, ind); }@@ -237,6 +291,8 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)emulator_add_indicator (em,OFONO_EMULATOR_IND_SIGNAL ,0 ,5 ,0 );emulator_add_indicator (em,OFONO_EMULATOR_IND_ROAMING ,0 ,1 ,0 );emulator_add_indicator (em,OFONO_EMULATOR_IND_BATTERY ,0 ,5 ,5 ); + +g_at_server_register (em->server,"+CIND" , cind_cb, em,NULL ); }__ofono_atom_register (em->atom, emulator_unregister);
Regards,
-Denis