Phonebook functions for BlueZ
Hello,
I have analyzed the data traffic of my car handsfree set and implemented the functions for the phonebook retrieval via the CPBR and CPBS commands. In addition, I added a telephony driver for the FSO middleware with which I tested the new functions using a Parrot CK3100 car kit and a Jabra ear plug using version 4.61 of BlueZ. The other telephony drivers just have empty functions that reject the new commands in order not to break the APIs.
Attached is the patch file for the git repository.
Felix Huber
Quoted 1 line
From
a1e5b0d81b36242ac1a4c7362dd5146395bd7f1fMon Sep 17 00:00:00 2001
From: Felix Huber <[email protected]>
Date: Fri, 26 Feb 2010 12:15:31 +0100
Subject: [PATCH] Added support for HFP phonebook functions and FSO middleware
--- audio/headset.c | 80 +++ audio/telephony-dummy.c | 11 + audio/telephony-fso.c | 1411 +++++++++++++++++++++++++++++++++++++++++++++++ audio/telephony-maemo.c | 10 + audio/telephony-ofono.c | 11 + audio/telephony.h | 12 + 6 files changed, 1535 insertions(+), 0 deletions(-) create mode 100644 audio/telephony-fso.c
audio/headset.c +80 -0
@@ -1154,6 +1154,84 @@ static int voice_dial(struct audio_device *device, const char *buf)return 0 ; } +int get_ATtype (const char *buf,int *offset) +{ +const char *ATquery ="=?" , *ATcheck ="?" , *ATset ="=" ; + +if (!strncmp (buf, ATquery,2 )) { + *offset =2 ; +return (ATQUERY ); + }else if (!strncmp (buf, ATcheck,1 )) { + *offset =1 ; +return (ATCHECK ); + }else if (!strncmp (buf, ATset,1 )) { + *offset =1 ; +return (ATSET ); + }else { + *offset =0 ; +return (ATNONE ); + } +} + + +int telephony_phonebook_storage_rsp (void *telephony_device,cme_error_t err) +{ +return telephony_generic_rsp (telephony_device, err); +} + +int telephony_phonebook_storage_ind (void *telephony_device,const char *storagelist) +{ +struct audio_device *device = telephony_device; +struct headset *hs = device->headset; + +headset_send (hs,"\r\n+CPBS: %s \r\n" , storagelist); + +return 0 ; +} + +static int phonebook_storage (struct audio_device *device,const char *buf) +{ +int ATtype, offset; + +if (strlen (buf) <8 ) { +return -EINVAL ; + } + + ATtype =get_ATtype (&buf[7 ], &offset); +telephony_phonebook_storage_req (device, &buf[7 +offset], ATtype); + +return 0 ; +} + +int telephony_phonebook_read_rsp (void *telephony_device,cme_error_t err) +{ +return telephony_generic_rsp (telephony_device, err); +} + +int telephony_phonebook_read_ind (void *telephony_device,const char *entrylist) +{ +struct audio_device *device = telephony_device; +struct headset *hs = device->headset; + +headset_send (hs,"\r\n+CPBR: %s\r\n" , entrylist); + +return 0 ; +} + +static int phonebook_read (struct audio_device *device,const char *buf) +{ +int ATtype, offset; + +if (strlen (buf) <8 ) { +return -EINVAL ; + } + ATtype =get_ATtype (&buf[7 ], &offset); +telephony_phonebook_read_req (device, &buf[7 +offset], ATtype); + +return 0 ; +} + +static struct event event_callbacks[] = { {"ATA" , answer_call }, {"ATD" , dial_number },
@@ -1175,6 +1253,8 @@ static struct event event_callbacks[] = { { "AT+COPS", operator_selection }, { "AT+NREC", nr_and_ec }, { "AT+BVRA", voice_dial }, + { "AT+CPBS", phonebook_storage }, + { "AT+CPBR", phonebook_read }, { 0 } };
audio/telephony-dummy.c +11 -0
@@ -225,6 +225,17 @@ void telephony_key_press_req(void *telephony_device, const char *keys)telephony_key_press_rsp (telephony_device,CME_ERROR_NONE ); } +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_read_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_phonebook_storage_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +/* D-Bus method handlers */ static DBusMessage *outgoing_call (DBusConnection *conn,DBusMessage *msg,void *data)
audio/telephony-fso.c new file +1411 -0
1,411 lines not on this page · raw message
audio/telephony-maemo.c +10 -0
@@ -922,6 +922,16 @@ void telephony_voice_dial_req(void *telephony_device, gboolean enable)telephony_voice_dial_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); } +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_read_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_phonebook_storage_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} +static void handle_incoming_call (DBusMessage *msg) {const char *number, *call_path;
audio/telephony-ofono.c +11 -0
@@ -387,6 +387,17 @@ void telephony_key_press_req(void *telephony_device, const char *keys)telephony_key_press_rsp (telephony_device,CME_ERROR_NONE ); } +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_read_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_phonebook_storage_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_voice_dial_req (void *telephony_device,gboolean enable) { debug("telephony-ofono: got %s voice dial request",
audio/telephony.h +12 -0
@@ -127,6 +127,12 @@ typedef enum { CME_ERROR_NETWORK_NOT_ALLOWED = 32, } cme_error_t; +/* AT command types */ +#define ATNONE 0 +#define ATQUERY 1 +#define ATCHECK 2 +#define ATSET 3 +struct indicator {const char *desc;const char *range;
@@ -157,6 +163,8 @@ void telephony_call_hold_req(void *telephony_device, const char *cmd);void telephony_nr_and_ec_req (void *telephony_device,gboolean enable);void telephony_voice_dial_req (void *telephony_device,gboolean enable);void telephony_key_press_req (void *telephony_device,const char *keys); +void telephony_phonebook_storage_req (void *telephony_device,const char *storage,int ATtype); +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int ATtype);/* AG responses to HF requests. These are implemented by headset.c */ int telephony_event_reporting_rsp (void *telephony_device,cme_error_t err);
@@ -173,6 +181,8 @@ int telephony_call_hold_rsp(void *telephony_device, cme_error_t err);int telephony_nr_and_ec_rsp (void *telephony_device,cme_error_t err);int telephony_voice_dial_rsp (void *telephony_device,cme_error_t err);int telephony_key_press_rsp (void *telephony_device,cme_error_t err); +int telephony_phonebook_storage_rsp (void *telephony_device,cme_error_t err); +int telephony_phonebook_read_rsp (void *telephony_device,cme_error_t err);/* Event indications by AG. These are implemented by headset.c */ int telephony_event_ind (int index);
@@ -188,6 +198,8 @@ int telephony_subscriber_number_ind(const char *number, int type, int service);int telephony_call_waiting_ind (const char *number,int type);int telephony_operator_selection_ind (int mode,const char *oper); +int telephony_phonebook_storage_ind (void *device,const char *storagelist); +int telephony_phonebook_read_ind (void *device,const char *entrylist);/* Helper function for quick indicator updates */ static inline int telephony_update_indicator(struct indicator *indicators,
Signature · 1 line
1.6.4.2
Hi Felix,
Quoted 9 lines · Felix Huber
I have analyzed the data traffic of my car handsfree set and implemented the functions for the phonebook retrieval via the CPBR and CPBS commands. In addition, I added a telephony driver for the FSO middleware with which I tested the new functions using a Parrot CK3100 car kit and a Jabra ear plug using version 4.61 of BlueZ. The other telephony drivers just have empty functions that reject the new commands in order not to break the APIs.
Attached is the patch file for the git repository.
Thanks for this contribution! In general the patch looks quite ok, however before pushing this upstream there are a some coding style issues that'd need to be fixed:
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1159
Quoted 3 lines
audio/headset.c +3
-0+int get_ATtype (const char *buf,int *offset) +{ +const char *ATquery ="=?" , *ATcheck ="?" , *ATset ="=" ;
We usually don't use capital letters in any variable or function names. Pre-processor defines are an exception. So use something like get_at_type, at_query, etc. Also, since get_ATtype is only used within headset.c you have to declare it static.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1163
Quoted 3 lines
audio/headset.c +3
-0+if (!strncmp (buf, ATquery,2 )) { + *offset =2 ; +return (ATQUERY );
No () around the value given to return;
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1176
Quoted 13 lines
audio/headset.c +13
-0+ }else if (!strncmp (buf, ATcheck,1 )) { + *offset =1 ; +return (ATCHECK ); + }else if (!strncmp (buf, ATset,1 )) { + *offset =1 ; +return (ATSET ); + }else { + *offset =0 ; +return (ATNONE ); + } +} + +
There shouldn't at any point be the need to have more than one empty line in the code, so please remove the other.
Quoted 1 line
+int
telephony_phonebook_storage_ind(void *telephony_device, const char *storagelist)
This line looks like it's longer than 80 columns. Please split it to two.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1187
Quoted 1 line
audio/headset.c +1
-0+headset_send (hs,"\r\n+CPBS: %s \r\n" , storagelist);
Why is there a space before the "\r\n"?
Review
Quoted 1 line
(quoted diff) +1
-0+ int ATtype, offset;
Again the capital letter thing.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1198
Quoted 3 lines
audio/headset.c +3
-0+if (strlen (buf) <8 ) { +return -EINVAL ; + }
No braces for single-line scopes.
Review
Quoted 1 line
(quoted diff) +1
-0+ ATtype = get_ATtype(&buf[7], &offset);
No capital letters.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1198
Quoted 3 lines
audio/headset.c +3
-0+if (strlen (buf) <8 ) { +return -EINVAL ; + }
No braces.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1234
Quoted 7 lines
audio/headset.c +7
-0+ ATtype =get_ATtype (&buf[7 ], &offset); +telephony_phonebook_read_req (device, &buf[7 +offset], ATtype); + +return 0 ; +} + +
Unnecessary extra empty line.
Quoted 1 line
+void
telephony_phonebook_read_req(void *telephony_device, const char *readindex, int ATtype)
Looks like a > 80 column line.
Quoted 1 line
+void
telephony_phonebook_storage_req(void *telephony_device, const char *readindex, int ATtype)
Same issue.
audio/telephony-dummy.c void telephony_key_press_req(void *telephony_device, const char *keys) · line 238
Quoted 5 lines
audio/telephony-dummy.c +5
-0+{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +
Extra empty line again.
audio/telephony-fso.c line 97
Quoted 2 lines
audio/telephony-fso.c new file +2
-0+char *fso_categories[NUM_CATEGORIES ] = {"contacts" ,"emergency" ,"fixed" ,"dialed" ,"received" ,"missed" ,"own" }; +char *gsm_categories[NUM_CATEGORIES ] = {"\"SM\"" ,"\"EN\"" ,"\"FD\"" ,"\"DC\"" ,"\"RC\"" ,"\"MC\"" ,"\"ON\"" };
Probably you could split these to fit within 80 columns.
audio/telephony-fso.c line 143
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+static struct { + uint8_t status; // act 'GSM' + uint32_t cell_id; // cid '51FD' + uint32_t operator_code; // code '26203' + uint16_t lac; // lac '233b'
We don't use C++ style comments. So please change to /* .. */. Also, there's an extra space at the end of the "lac" line.
audio/telephony-fso.c line 159
Quoted 12 lines
audio/telephony-fso.c new file +12
-0+} net = { + .status = NETWORK_REG_STATUS_UNREGISTERED, + .cell_id = 0, + .operator_code = 0, + .lac = 0, + .mode = NULL, + .operator_name = NULL, + .registration = NULL, + .signals_bar = 0, +}; + +
Extra empty line.
audio/telephony-fso.c line 194
Quoted 9 lines
audio/telephony-fso.c new file +9
-0+static void vc_free (struct voice_call *vc) +{ +if (!vc) +return ; +g_free (vc->number); +g_free (vc); +} + +
Extra empty line.
audio/telephony-fso.c line 266
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+static int find_category (char **phonebooks,const char *category) +{ +int i; +for (i=0 ; i <NUM_CATEGORIES ; i++) {
Space before and after '='.
audio/telephony-fso.c line 267
Quoted 1 line
audio/telephony-fso.c new file +1
-0+if (!strcmp (phonebooks[i], category))
The convention has usually been to use == 0 in the case of strcmp for readability.
audio/telephony-fso.c line 272
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+return i; + } +return -1 ; + +}
Why the empty line after the return statement? I'd put it after the for-loop for consistency with the rest of the code base.
Review
Quoted 2 lines
(quoted diff) +2
-0+ +
Extra empty line.
audio/telephony-fso.c line 316
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+static int send_method_call (const char *dest,const char *path, +const char *interface,const char *method, +DBusPendingCallNotifyFunction cb, +void *user_data,int type, ...)
Since this and many other functions are shared with (or actually copied from) telephony-maemo.c would it make sense to put them to some shared c-file (it's fine if this is a separate commit later).
audio/telephony-fso.c line 364
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+if ((vc =find_vc_with_status (CALL_STATUS_ACTIVE ))) { + }else if ((vc =find_vc_with_status (CALL_STATUS_DIALING ))) { + }else if ((vc =find_vc_with_status (CALL_STATUS_INCOMING ))) { + }
The purpose of this construction isn't imediately clear imo. Wouldn't something like doing specific NULL checks after each find() call be more readable? I.e.
vc = find(...);
if (vc == NULL)
vc = find(...); if (vc == NULL) vc = find(...);
Alternatively creating something like find_active_call() which would match any of those states could also make the code a bit more readable.
audio/telephony-fso.c line 379
Quoted 7 lines
audio/telephony-fso.c new file +7
-0+ ret =send_method_call (FSO_BUS_NAME ,FSO_MODEM_OBJ_PATH , +FSO_GSMC_INTERFACE , +"Release" ,NULL ,NULL , +DBUS_TYPE_INT32 , &vc->call_index, +DBUS_TYPE_INVALID ); + +
Extra empty line.
audio/telephony-fso.c line 413
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+void telephony_dial_number_req (void *telephony_device,const char *number) +{ +const char *clir, *callType ="voice" ;
No capital letters in variable names.
audio/telephony-fso.c line 427
Quoted 10 lines
audio/telephony-fso.c new file +10
-0+#if 0 +if (!strncmp (number,"*31#" ,4 )) { + number +=4 ; + clir ="enabled" ; + }else if (!strncmp (number,"#31#" ,4 )) { + number +=4 ; + clir ="disabled" ; + }else + clir ="default" ; +#endif
Is this really code that you think can be enabled later? If not I'd just remove it instead of having it commented out.
audio/telephony-fso.c line 454
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+ ret =send_method_call (FSO_BUS_NAME ,FSO_MODEM_OBJ_PATH , +FSO_GSMC_INTERFACE , +"SendDtmf" ,NULL ,NULL , +DBUS_TYPE_STRING , &tone_string, +DBUS_TYPE_INVALID );
Looks like the indentation is somehow screwed up in the first continuation line. In general the rule for indenting continuation lines
is: same indentation for all continuation lines, at least two tabs more than the first line and as much as possible as long as the lines stay less than 80 columns.
audio/telephony-fso.c line 533
Quoted 7 lines
audio/telephony-fso.c new file +7
-0+if (vc =find_vc_with_status (CALL_STATUS_INCOMING )) { + cmd = act; + }else if (vc =find_vc_with_status (CALL_STATUS_ACTIVE )) { + cmd = rel; + }else if (vc =find_vc_with_status (CALL_STATUS_DIALING )) { + cmd = rel; + }
No braces for one-line scopes.
audio/telephony-fso.c line 544
Quoted 11 lines
audio/telephony-fso.c new file +11
-0+if (cmd) { + err =send_method_call (FSO_BUS_NAME ,FSO_MODEM_OBJ_PATH , +FSO_GSMC_INTERFACE , + cmd,NULL ,NULL , +DBUS_TYPE_INT32 , &vc->call_index, +DBUS_TYPE_INVALID ); + } +if (err <0 ) +telephony_key_press_rsp (telephony_device,CME_ERROR_AG_FAILURE ); +else +telephony_key_press_rsp (telephony_device,CME_ERROR_NONE );
Shouldn't it be an error if cmd is NULL? In general doing initializations upon declaration, especially for error variables, should be avoided. Would e.g. having a final "else err = -EINVAL" at the end of the else/else if statement make sense (which would allow removing the initialzation of err to 0?
Also the indentation of the second if-statments else line is with spaces instead of tabs.
Quoted 1 line
+void
telephony_phonebook_read_req(void *telephony_device, const char *readindex, int ATtype)
Looks like a possibly grater than 80 columns line.
audio/telephony-dummy.c void telephony_key_press_req(void *telephony_device, const char *keys) · line 238
Quoted 6 lines
audio/telephony-dummy.c +6
-0+void telephony_phonebook_storage_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +
Extra empty line.
audio/telephony-fso.c line 582
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+if (!dbus_message_get_args (reply,NULL , +DBUS_TYPE_STRING , &name, +DBUS_TYPE_STRING , &number, +DBUS_TYPE_INVALID ))
Extra space at the end of the last line.
audio/telephony-fso.c line 594
Quoted 10 lines
audio/telephony-fso.c new file +10
-0+if (number_type == &subscriber_number) { +g_free (subscriber_number); + subscriber_number =g_strdup (number); + } + +done: +dbus_message_unref (reply); +} + +
Extra empty line.
audio/telephony-fso.c line 600
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+static void retrieve_phonebook_reply (DBusPendingCall *call,void *user_data) +{ +DBusError err; +DBusMessage *reply; +DBusMessageIter iter, array; +int ret =0 ;
Instead of initializing ret upon declaration (and btw, we use "err" instead of "ret" usually) you could set it to 0 right before the done label.
point:
audio/telephony-fso.c line 637
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+if ((index >= phonebook_info.first) && (index <= phonebook_info.last)) { + info =g_strdup_printf ("%d,\"%s\",,\"%s\"" , index, number, name); +telephony_phonebook_read_ind (phonebook_info.telephony_device, info);
Looks like possibly grater than 80 columns lines.
audio/telephony-fso.c line 648
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+if (ret) +telephony_phonebook_read_rsp (phonebook_info.telephony_device,CME_ERROR_AG_FAILURE ); +else +telephony_phonebook_read_rsp (phonebook_info.telephony_device,CME_ERROR_NONE );
Same here.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1181
Quoted 4 lines
audio/headset.c +4
-0+} + + +
Two extra empty lines.
audio/telephony-fso.c line 658
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+static void get_phonebook_info_reply (DBusPendingCall *call,void *user_data) +{ +DBusError err; +DBusMessage *reply; +DBusMessageIter iter, iter_entry, array; +int ret =0 ;
s/ret/err/ and try to rethink how the initialization upon declaration could be avoided.
audio/telephony-fso.c line 659
Quoted 1 line
audio/telephony-fso.c new file +1
-0+int min_index=-1 , max_index =-1 , number_length =-1 , name_length =-1 ;
Missing spaces before and after '='.
audio/telephony-fso.c line 713
Quoted 9 lines
audio/telephony-fso.c new file +9
-0+if (g_str_equal (property,"min_index" )) { +dbus_message_iter_get_basic (&sub, &min_index); + }else if (g_str_equal (property,"max_index" )) { +dbus_message_iter_get_basic (&sub, &max_index); + }else if (g_str_equal (property,"number_length" )) { +dbus_message_iter_get_basic (&sub, &number_length); + }else if (g_str_equal (property,"name_length" )) { +dbus_message_iter_get_basic (&sub, &name_length); + }
No braces for one-line scopes.
audio/telephony-fso.c line 648
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+if (ret) +telephony_phonebook_read_rsp (phonebook_info.telephony_device,CME_ERROR_AG_FAILURE ); +else +telephony_phonebook_read_rsp (phonebook_info.telephony_device,CME_ERROR_NONE );
Possibly longer than 80-column lines.
+ g_free(str);
audio/telephony-fso.c line 766
Quoted 9 lines
audio/telephony-fso.c new file +9
-0+telephony_phonebook_storage_rsp (phonebook_info.telephony_device,CME_ERROR_NONE ); + +done: +dbus_message_unref (reply); + +} + + +
Two unnecessary extra empty lines.
Review
Quoted 1 line
(quoted diff) +1
-0+ int ret = 0;
Same thing as already mentioned.
audio/telephony-fso.c line 799
Quoted 2 lines
audio/telephony-fso.c new file +2
-0+ gstr =g_string_new ("(" ); +for (i=0 ; i< n_s; i++) {
Missing spaces before and after '=', before '<'. Can you come up with a more descriptive name for the n_s variable please?
audio/telephony-fso.c line 808
Quoted 9 lines
audio/telephony-fso.c new file +9
-0+ index =find_category (fso_categories, s[i]); +if (index !=-1 ) { +debug ("GSM %d: %s" , index, gsm_categories[index]); +if (i ==0 ) +g_string_append_printf (gstr,"%s" , gsm_categories[index]); +else +g_string_append_printf (gstr,",%s" , gsm_categories[index]); + } + }
Looks like some lines go beyone 80-colums. You can avoid this by doing
if (index == -1)
continue;
which also (imho) makes the code more readable.
audio/telephony-fso.c line 648
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+done: +dbus_message_unref (reply); +if (ret) +telephony_phonebook_read_rsp (phonebook_info.telephony_device,CME_ERROR_AG_FAILURE ); +else +telephony_phonebook_read_rsp (phonebook_info.telephony_device,CME_ERROR_NONE );
Looks like greater than 80-column lines again.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1181
Quoted 4 lines
audio/headset.c +4
-0+} + + +
Two extra empty lines.
Quoted 1 line
+void
telephony_phonebook_storage_req(void *telephony_device, const char *storage, int ATtype)
Greater than 80-column line. No capital letters in variable names.
audio/telephony-fso.c line 827
Quoted 1 line
audio/telephony-fso.c new file +1
-0+int ret=0 , index;
s/ret/err/, rethink how the initialization upon declaration could be avoided (not to mention the missing spaces before and after '=').
audio/telephony-fso.c line 839
Quoted 7 lines
audio/telephony-fso.c new file +7
-0+switch (ATtype) { +case ATQUERY :// =? + ret =send_method_call (FSO_BUS_NAME ,FSO_MODEM_OBJ_PATH , +FSO_SIM_INTERFACE , +"ListPhonebooks" , + list_phonebooks_reply,NULL , +DBUS_TYPE_INVALID );
No C++ comments, the spit continuation lines need more indentation (at least two more than the original line).
audio/telephony-fso.c line 852
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+case ATSET :// = +debug ("Phonebook request to be %s" , storage); + index =find_category (gsm_categories, storage); +debug ("Phonebook found at %d" , index);
No space between debug and (
audio/telephony-fso.c line 857
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+if (index ==-1 ) + ret =-1 ; +else { + phonebook_info.category = index; +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NONE );
Looks like greater than 80-column line.
audio/telephony-fso.c line 863
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+ } +break ; +default : + ret =-1 ; + } +
Redundant tab-character on this empty line.
audio/telephony-fso.c line 865
Quoted 2 lines
audio/telephony-fso.c new file +2
-0+if (ret <0 ) +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_AG_FAILURE );
Greater than 80-column line.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1176
Quoted 3 lines
audio/headset.c +3
-0+} + +
Unnecessary empty line.
Quoted 1 line
+void
telephony_phonebook_read_req(void *telephony_device, const char *readindex, int ATtype)
Greater than 80 column line.
audio/telephony-fso.c line 872
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+{ +int size, ret=0 ; +debug ("telephony-fso: got pbook read request: %s" , readindex);
Empty line after variable declarations. s/ret/err/. Rethink initialization upon declaration. Missing space before and after '='
Review
Quoted 2 lines
(quoted diff) +2
-0+ switch (ATtype) { + case ATQUERY: // =?
No C++ comments.
audio/telephony-fso.c line 883
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+ ret =send_method_call (FSO_BUS_NAME ,FSO_MODEM_OBJ_PATH , +FSO_SIM_INTERFACE , +"GetPhonebookInfo" , + get_phonebook_info_reply,NULL , +DBUS_TYPE_STRING , &fso_categories[phonebook_info.category], +DBUS_TYPE_INVALID );
Incorrect indentation (e.g. first continuation line seems not to be indented at all from the original line)
audio/telephony-fso.c line 891
Quoted 1 line
audio/telephony-fso.c new file +1
-0+ phonebook_info.first=-1 , phonebook_info.last=-1 ;
Missing spaces before and after '='.
audio/telephony-fso.c line 894
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+sscanf (readindex,"%d,%d" , &phonebook_info.first, &phonebook_info.last); +if (phonebook_info.first ==-1 ) +break ;
Probably you'd also want to check for sscanf return value (i.e. == 2). Maybe that's the only thing you should check for and not try to initialize these variables here since you already do that in the beginning of telephony-fso.c where you define the phonebook_info struct?
audio/telephony-fso.c line 896
Quoted 2 lines
audio/telephony-fso.c new file +2
-0+ +if (phonebook_info.last ==-1 ) phonebook_info.last = phonebook_info.first;
Break this into two lines.
Quoted 12 lines
audio/telephony-fso.c new file +12
-0+ + ret =send_method_call (FSO_BUS_NAME ,FSO_MODEM_OBJ_PATH , +FSO_SIM_INTERFACE , +"RetrievePhonebook" , + retrieve_phonebook_reply,NULL , +DBUS_TYPE_STRING , &fso_categories[phonebook_info.category], +DBUS_TYPE_INT32 , &phonebook_info.first, +DBUS_TYPE_INT32 , &phonebook_info.last, +DBUS_TYPE_INVALID ); +break ; + +default :
audio/telephony-fso.c line 918
Quoted 10 lines
audio/telephony-fso.c new file +10
-0+ ret =-1 ; + } + +if (ret <0 ) +telephony_phonebook_read_rsp (telephony_device,CME_ERROR_AG_FAILURE ); + +} + + +
Unnecessary empty line at the end of the function and two unnecessary empty lines after it.
Quoted 1 line
+static void
parse_gsmcall_property(const char *property, DBusMessageIter sub, struct voice_call *vc)
Too long line.
audio/telephony-fso.c line 934
Quoted 12 lines
audio/telephony-fso.c new file +12
-0+if (g_str_equal (property,"direction" )) { +dbus_message_iter_get_basic (&sub, &direction); + }else if (g_str_equal (property,"peer" )) { +dbus_message_iter_get_basic (&sub, &peer); + vc->number =g_strdup (peer); + }else if (g_str_equal (property,"reason" )) { +dbus_message_iter_get_basic (&sub, &reason); + }else if (g_str_equal (property,"auxstatus" )) { +dbus_message_iter_get_basic (&sub, &auxstatus); + }else if (g_str_equal (property,"line" )) { +dbus_message_iter_get_basic (&sub, &line); + }
No braces for one-line scopes.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1176
Quoted 3 lines
audio/headset.c +3
-0+} + +
Unnecessary empty line.
audio/telephony-fso.c line 959
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_STRING ) { +error ("Unexpected signature in gsmcall PropertyChanged signal" ); +return TRUE; + }
Incorrect indentation and no braces needed for one-line scope.
audio/telephony-fso.c line 965
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+dbus_message_iter_get_basic (&iter, &status); + +debug ("**** gsmProp Changed id:%d status: %s" , call_index, status); + +
Unnecessary empty line.
audio/telephony-fso.c line 970
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+ vc =find_vc (call_index); +if (!vc) { + vc = g_new0(struct voice_call, 1); +if (!vc) +return TRUE;
g_new0 is guaranteed to succeed or else it will call abort() so the NULL check is redundant.
audio/telephony-fso.c line 973
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+ vc->call_index = call_index; + calls =g_slist_append (calls, vc); + }
Looks like some incorrect indentation is going on here (since the ending brace has the same indentation as the preceeding lines.
audio/telephony-fso.c line 1001
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+if (dbus_message_iter_get_arg_type (&iter_property) + !=DBUS_TYPE_STRING ) { +error ("Unexpected signature in gsmcallPropertyChanged signal" ); +return TRUE; + }
Incorrect indentation for the split if-line. The continuation line should be indented by at least two tabs to clearly separate it from the actual branch code.
audio/telephony-fso.c line 962
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+return TRUE; +} + + + +
Three unnecessary empty lines.
audio/headset.c static int voice_dial(struct audio_device *device, const char *buf) · line 1176
Quoted 3 lines
audio/headset.c +3
-0+} + +
Unnecessary empty line.
Review
Quoted 1 line
(quoted diff) +1
-0+ /* ARRAY -> ENTRY -> VARIANT*/
Space before */
audio/telephony-fso.c line 1142
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+dbus_message_iter_recurse (&iter_property, &sub); + +parse_registration_property (property, sub); + +dbus_message_iter_next (&iter_entry);
Incorrect indentation for the last line.
audio/telephony-fso.c line 590
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+ } + +done:
Redundant tab character on the empty line.
audio/telephony-fso.c line 955
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+return TRUE; +} + +
Unnecessary empty line.
audio/telephony-fso.c line 594
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+done: +dbus_message_unref (reply); +} + +
Unnecessary empty line.
audio/telephony-fso.c line 1180
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+static gboolean handle_registration_property_changed (DBusConnection *conn, +DBusMessage *msg,void *data) +{ +return (handle_registration_property (msg)); +}
No () needed around the value given to return.
audio/telephony-fso.c line 608
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+if (reply_check_error (&err, reply)) { + goto done; + }
No braces for one-line scope (though I realize this one is probably inherited from telephony-maemo.c which I'm responsible for :)
audio/telephony.h typedef enum { · line 134
Quoted 11 lines
audio/telephony.h +5
-0@@ -127,6 +127,12 @@ typedef enum {CME_ERROR_NETWORK_NOT_ALLOWED =32 , } cme_error_t; +/* AT command types */ +#define ATNONE 0 +#define ATQUERY 1 +#define ATCHECK 2 +#define ATSET 3
These should probably be an enum and have some namespacing (e.g. AT_TYPE_). To be consistent with the AT command spec terminology (I've been looking at 3GPP TS 07.07) it should be s/QUERY/TEST/ and s/CHECK/READ/.
There were probably other issues in the patch that I missed but it'd be nice if you could fix the already mentioned problems first and then I'll take a second look.
Johan
Hi Johan,
attached is the beautified version of the patch. I have deleted all the comments referring to space, tabs, extra parenthesis and empty lines since there are silenty fixed. I have a script that should take care of that (at least I thought I had). The rest of the remarks are those where I need feedback, discussion etc...
One more word of warning: Some People seem to have started to use this patch on the OpenMoko. In order to use it, you MUST update a few files of the FSO framework. Look at my commits at the framework git.
Am Montag, den 01.03.2010, 16:20 -0300 schrieb Johan Hedberg:
Quoted 17 lines
Hi Felix,
Quoted 9 lines · Felix Huber
I have analyzed the data traffic of my car handsfree set and implemented the functions for the phonebook retrieval via the CPBR and CPBS commands. In addition, I added a telephony driver for the FSO middleware with which I tested the new functions using a Parrot CK3100 car kit and a Jabra ear plug using version 4.61 of BlueZ. The other telephony drivers just have empty functions that reject the new commands in order not to break the APIs.
Attached is the patch file for the git repository.
Thanks for this contribution! In general the patch looks quite ok, however before pushing this upstream there are a some coding style issues that'd need to be fixed:
Quoted 7 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+int get_ATtype(const char *buf, int *offset) +{ + const char *ATquery = "=?", *ATcheck ="?", *ATset = "=";We usually don't use capital letters in any variable or function names. Pre-processor defines are an exception. So use something like
get_at_type,at_query, etc.
Well usually, but since AT in this case is a proper name, I found it very confusing to read it like the prepostion "at" or even a spelled-out @-sign. I added an underscore for better indication of what it is.
Quoted 2 lines
Also, since
get_ATtypeis only used withinheadset.cyou have to declare it static.
done
Quoted 4 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+char *fso_categories[NUM_CATEGORIES] = {"contacts", "emergency", "fixed", "dialed", "received", "missed", "own"}; +char *gsm_categories[NUM_CATEGORIES] = {"\"SM\"", "\"EN\"", "\"FD\"","\"DC\"", "\"RC\"", "\"MC\"", "\"ON\""};Probably you could split these to fit within 80 columns.
Done, but now we loose the one-to-one correspondance.
Quoted 5 lines
Review
Quoted 1 line
(quoted diff) +1
-0+ if (!strcmp(phonebooks[i], category))The convention has usually been to use == 0 in the case of strcmp for readability.
Not quite, as it seems: I looked at the other files and they also used the ! (including one commited by you :) ). So I chose the logical not, which also frees one from having to handle 0 vs. NULL.
Quoted 8 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+static int send_method_call(const char *dest, const char *path, + const char *interface, const char *method, + DBusPendingCallNotifyFunction cb, + void *user_data, int type, ...)Since this and many other functions are shared with (or actually copied from)
telephony-maemo.cwould it make sense to put them to some shared c-file (it's fine if this is a separate commit later).
Agreed, but since not all telefony-* files use it, it will create dead code unless we put those functions into a lib.
Quoted 10 lines
Review
Quoted 5 lines
(quoted diff) +4
-0+ if ((vc = find_vc_with_status(CALL_STATUS_ACTIVE))) { + } else if ((vc = find_vc_with_status(CALL_STATUS_DIALING))) { + } else if ((vc = find_vc_with_status(CALL_STATUS_INCOMING))) { + }The purpose of this construction isn't imediately clear imo. Wouldn't something like doing specific NULL checks after each
find()call be more readable? I.e.
Well, to me it was clear that these are nested calls until a valid vc is found. But anyway, I copied this from telephony-ofono and tried to stay close to the original code for better re-recognition. So either both should be changed or none but not be strict only on new code, since this makes copy-and-paste ineffective.
Quoted 6 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+void telephony_dial_number_req(void *telephony_device, const char *number) +{ + const char *clir, *callType = "voice";No capital letters in variable names.
Done
Quoted 5 lines
Quoted 5 lines
(quoted diff) +5
-0+#if 0 + if (!strncmp(number, "*31#", 4)) { + number += 4; + clir = "enabled"; + } else if (!strncmp(number, "#31#", 4)) {
Quoted 9 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ number += 4; + clir = "disabled"; + } else + clir = "default"; +#endifIs this really code that you think can be enabled later? If not I'd just remove it instead of having it commented out.
Yes, it is needed. My car kit (and maybe others) have a menu to activate this, but the current FSO API cannot handle it yet. Since this driver needs to be update anyhow once the opimd is final, I left it in so it cannot get forgotten to be reenabled.
Quoted 9 lines
Quoted 9 lines
(quoted diff) +9
-0+ if (cmd) { + err = send_method_call(FSO_BUS_NAME, FSO_MODEM_OBJ_PATH, + FSO_GSMC_INTERFACE, + cmd, NULL, NULL, + DBUS_TYPE_INT32, &vc->call_index, + DBUS_TYPE_INVALID); + } + if (err < 0) + telephony_key_press_rsp(telephony_device, CME_ERROR_AG_FAILURE);
Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ else + telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);Shouldn't it be an error if cmd is NULL? In general doing initializations upon declaration, especially for error variables, should be avoided. Would e.g. having a final "else err =
-EINVAL" at the end of the else/else if statement make sense (which would allow removing the initialzation of err to 0?
No no, beware! It can happen that the other side of the phone call just hung up before the key press or that a nasty user presses a key when nothing is going on. In this case, the press is silenty ignored instead of confusing some headsets with an unexpected failure.
Quoted 10 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+static void retrieve_phonebook_reply(DBusPendingCall *call, void *user_data) +{ + DBusError err; + DBusMessage *reply; + DBusMessageIter iter, array; + int ret = 0;Instead of initializing ret upon declaration (and btw, we use "err" instead of "ret" usually) you could set it to 0 right before the done label.
Again, I checked with the other telephony files: they use ret for their codes and err for DBus error. So I stayed consistent with the names.
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ gstr = g_string_new("("); + for (i=0; i< n_s; i++) {Missing spaces before and after '=', before '<'. Can you come up with a more descriptive name for the
n_svariable please?
What about num_strings? This is my feeling only, since I copied this from the DBus tutorial.
Quoted 6 lines
Looks like some lines go beyone 80-colums. You can avoid this by doing
if (index == -1)
continue;which also (imho) makes the code more readable.
Done
Quoted 8 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+ sscanf(readindex, "%d,%d", &phonebook_info.first, &phonebook_info.last); + if (phonebook_info.first == -1) + break;Probably you'd also want to check for sscanf return value (i.e. == 2). Maybe that's the only thing you should check for and not try to initialize these variables here since you already do that in the beginning of
telephony-fso.cwhere you define thephonebook_infostruct?
Nope, the arguments are optional and both 0,1 or two conversions can happen, so the return of sscanf serves nothing in this case.
Quoted 3 lines
Break this into two lines.
Done
Quoted 6 lines
Quoted 6 lines
(quoted diff) +6
-0+ if (g_str_equal(property, "direction")) { + dbus_message_iter_get_basic(&sub, &direction); + } else if (g_str_equal(property, "peer")) { + dbus_message_iter_get_basic(&sub, &peer); + vc->number = g_strdup(peer); + } else if (g_str_equal(property, "reason")) {
Quoted 8 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ dbus_message_iter_get_basic(&sub, &reason); + } else if (g_str_equal(property, "auxstatus")) { + dbus_message_iter_get_basic(&sub, &auxstatus); + } else if (g_str_equal(property, "line")) { + dbus_message_iter_get_basic(&sub, &line); + }No braces for one-line scopes.
Well, here we have a conflict: The kernel style guide says that if one of the blocks has braces the other one should also have, even if it is a single line.
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ vc = find_vc(call_index); + if (!vc) { + vc = g_new0(struct voice_call, 1); + if (!vc) + return TRUE;
g_new0is guaranteed to succeed or else it will callabort()so the NULL check is redundant.
What a nice feature, done.
Quoted 9 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+} + +Unnecessary empty line.
Review
Quoted 1 line
(quoted diff) +1
-0+ /* ARRAY -> ENTRY -> VARIANT*/Space before */
Done, copy and paste telephony-ofono.c -> should be fixed there too.
Quoted 7 lines
Review
Quoted 4 lines
(quoted diff) +3
-0+ if (reply_check_error(&err, reply)) { + goto done; + }No braces for one-line scope (though I realize this one is probably inherited from
telephony-maemo.cwhich I'm responsible for :)
Nope, unfortunately, you are not guilty. My code (and done).
Quoted 7 lines
Quoted 7 lines
audio/telephony.h +0
-0@@ -127,6 +127,12 @@ typedef enum { CME_ERROR_NETWORK_NOT_ALLOWED = 32, } cme_error_t;
Quoted 8 lines
audio/telephony.h typedef enum { · line 134
Quoted 5 lines
audio/telephony.h +5
-0+/* AT command types */ +#define ATNONE 0 +#define ATQUERY 1 +#define ATCHECK 2 +#define ATSET 3These should probably be an enum and have some namespacing (e.g.
AT_TYPE_).
Again, in order to be consistent with the existing codes, I looked at what the other files do. I adopted the use of the Call parameters, like CALL_STATUS_ACTIVE. These are all #defines
Quoted 3 lines
To be consistent with the AT command spec terminology (I've
been looking at 3GPP TS 07.07) it should be s/QUERY/TEST/ and s/CHECK/READ/.
Done (I don't have a copy of the spec)
Felix
Quoted 1 line
From
8c30b90811b307dc42d5003347902b121d4fa7d9Mon Sep 17 00:00:00 2001
From: Felix Huber <[email protected]>
Date: Sun, 7 Mar 2010 18:07:47 +0100
Subject: [PATCH] Added support for HFP phonebook functions and FSO middleware
--- audio/headset.c | 265 ++++++---- audio/telephony-dummy.c | 11 + audio/telephony-fso.c | 1412 +++++++++++++++++++++++++++++++++++++++++++++++ audio/telephony-maemo.c | 10 + audio/telephony-ofono.c | 11 + audio/telephony.h | 12 + 6 files changed, 1615 insertions(+), 106 deletions(-) create mode 100644 audio/telephony-fso.c
audio/headset.c +159 -106
@@ -128,25 +128,6 @@ struct pending_connect {uint16_t svclass; }; -struct headset_slc { -char buf[BUF_SIZE ]; -int data_start; -int data_length; - -gboolean cli_active; -gboolean cme_enabled; -gboolean cwa_enabled; -gboolean pending_ring; -gboolean inband_ring; -gboolean nrec; -gboolean nrec_req; - -int sp_gain; -int mic_gain; - -unsigned int hf_features; -}; -struct headset {uint32_t hsp_handle;uint32_t hfp_handle;
@@ -163,14 +144,28 @@ struct headset {guint dc_timer; +char buf[BUF_SIZE ]; +int data_start; +int data_length; +gboolean hfp_active;gboolean search_hfp; +gboolean cli_active; +gboolean cme_enabled; +gboolean cwa_enabled; +gboolean pending_ring; +gboolean inband_ring; +gboolean nrec; +gboolean nrec_req;headset_state_t state;struct pending_connect *pending; +int sp_gain; +int mic_gain; + +unsigned int hf_features;headset_lock_t lock; -struct headset_slc *slc; };struct event {
@@ -343,15 +338,14 @@ static int headset_send(struct headset *hs, char *format, ...)static int supported_features (struct audio_device *device,const char *buf) {struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;int err;if (strlen (buf) <9 )return -EINVAL ; - slc->hf_features =strtoul (&buf[8 ],NULL ,10 ); + hs->hf_features =strtoul (&buf[8 ],NULL ,10 ); -print_hf_features (slc->hf_features); +print_hf_features (hs->hf_features); err =headset_send (hs,"\r\n+BRSF: %u\r\n" , ag.features);if (err <0 )
@@ -540,12 +534,10 @@ static void send_foreach_headset(GSList *devices,static int cli_cmp (struct headset *hs) { -struct headset_slc *slc = hs->slc; -if (!hs->hfp_active)return -1 ; -if (slc->cli_active) +if (hs->cli_active)return 0 ;else return -1 ;
@@ -568,7 +560,6 @@ static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)int sk;struct audio_device *dev = user_data;struct headset *hs = dev->headset; -struct headset_slc *slc = hs->slc;struct pending_connect *p = hs->pending;if (err) {
@@ -608,12 +599,12 @@ static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)headset_set_state (dev,HEADSET_STATE_PLAYING ); -if (slc->pending_ring) { +if (hs->pending_ring) {ring_timer_cb (NULL ); ag.ring_timer =g_timeout_add_seconds (RING_INTERVAL , ring_timer_cb,NULL ); - slc->pending_ring = FALSE; + hs->pending_ring = FALSE; } }
@@ -693,10 +684,9 @@ static void hfp_slc_complete(struct audio_device *dev)static int telephony_generic_rsp (struct audio_device *device,cme_error_t err) {struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;if (err !=CME_ERROR_NONE ) { -if (slc->cme_enabled) +if (hs->cme_enabled)return headset_send (hs,"\r\n+CME ERROR: %d\r\n" , err);else return headset_send (hs,"\r\nERROR\r\n" );
@@ -709,7 +699,6 @@ int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err) {struct audio_device *device = telephony_device;struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;int ret;if (err !=CME_ERROR_NONE )
@@ -722,7 +711,7 @@ int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err)if (hs->state !=HEADSET_STATE_CONNECTING )return 0 ; -if (slc->hf_features &HF_FEATURE_CALL_WAITING_AND_3WAY && +if (hs->hf_features &HF_FEATURE_CALL_WAITING_AND_3WAY && ag.features &AG_FEATURE_THREE_WAY_CALLING )return 0 ;
@@ -876,12 +865,11 @@ static int terminate_call(struct audio_device *device, const char *buf)static int cli_notification (struct audio_device *device,const char *buf) {struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;if (strlen (buf) <9 )return -EINVAL ; - slc->cli_active = buf[8 ] =='1' ? TRUE : FALSE; + hs->cli_active = buf[8 ] =='1' ? TRUE : FALSE;return headset_send (hs,"\r\nOK\r\n" ); }
@@ -949,7 +937,6 @@ static int dial_number(struct audio_device *device, const char *buf)static int signal_gain_setting (struct audio_device *device,const char *buf) {struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;const char *property;const char *name;dbus_uint16_t gain;
@@ -968,18 +955,18 @@ static int signal_gain_setting(struct audio_device *device, const char *buf)switch (buf[5 ]) {case HEADSET_GAIN_SPEAKER : -if (slc->sp_gain == gain) +if (hs->sp_gain == gain) goto ok; name ="SpeakerGainChanged" ; property ="SpeakerGain" ; - slc->sp_gain = gain; + hs->sp_gain = gain;break ;case HEADSET_GAIN_MICROPHONE : -if (slc->mic_gain == gain) +if (hs->mic_gain == gain) goto ok; name ="MicrophoneGainChanged" ; property ="MicrophoneGain" ; - slc->mic_gain = gain; + hs->mic_gain = gain;break ;default :error ("Unknown gain setting" );
@@ -1043,16 +1030,15 @@ static int list_current_calls(struct audio_device *device, const char *buf)static int extended_errors (struct audio_device *device,const char *buf) {struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;if (strlen (buf) <9 )return -EINVAL ;if (buf[8 ] =='1' ) { - slc->cme_enabled = TRUE; + hs->cme_enabled = TRUE;debug ("CME errors enabled for headset %p" , hs); }else { - slc->cme_enabled = FALSE; + hs->cme_enabled = FALSE;debug ("CME errors disabled for headset %p" , hs); }
@@ -1062,16 +1048,15 @@ static int extended_errors(struct audio_device *device, const char *buf)static int call_waiting_notify (struct audio_device *device,const char *buf) {struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;if (strlen (buf) <9 )return -EINVAL ;if (buf[8 ] =='1' ) { - slc->cwa_enabled = TRUE; + hs->cwa_enabled = TRUE;debug ("Call waiting notification enabled for headset %p" , hs); }else { - slc->cwa_enabled = FALSE; + hs->cwa_enabled = FALSE;debug ("Call waiting notification disabled for headset %p" , hs); }
@@ -1092,10 +1077,9 @@ int telephony_nr_and_ec_rsp(void *telephony_device, cme_error_t err) {struct audio_device *device = telephony_device;struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;if (err ==CME_ERROR_NONE ) - slc->nrec = hs->slc->nrec_req; + hs->nrec = hs->nrec_req;return telephony_generic_rsp (telephony_device, err); }
@@ -1139,17 +1123,16 @@ static int operator_selection(struct audio_device *device, const char *buf)static int nr_and_ec (struct audio_device *device,const char *buf) {struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;if (strlen (buf) <9 )return -EINVAL ;if (buf[8 ] =='0' ) - slc->nrec_req = FALSE; + hs->nrec_req = FALSE;else - slc->nrec_req = TRUE; + hs->nrec_req = TRUE; -telephony_nr_and_ec_req (device, slc->nrec_req); +telephony_nr_and_ec_req (device, hs->nrec_req);return 0 ; }
@@ -1171,6 +1154,82 @@ static int voice_dial(struct audio_device *device, const char *buf)return 0 ; } +static int get_AT_type (const char *buf,int *offset) +{ +const char *AT_test ="=?" , *AT_read ="?" , *AT_set ="=" ; + +if (!strncmp (buf, AT_test,2 )) { + *offset =2 ; +return AT_TEST ; + }else if (!strncmp (buf, AT_read,1 )) { + *offset =1 ; +return AT_READ ; + }else if (!strncmp (buf, AT_set,1 )) { + *offset =1 ; +return AT_SET ; + }else { + *offset =0 ; +return AT_NONE ; + } +} + +int telephony_phonebook_storage_rsp (void *telephony_device,cme_error_t err) +{ +return telephony_generic_rsp (telephony_device, err); +} + +int telephony_phonebook_storage_ind (void *telephony_device, +const char *storagelist) +{ +struct audio_device *device = telephony_device; +struct headset *hs = device->headset; + +headset_send (hs,"\r\n+CPBS: %s\r\n" , storagelist); + +return 0 ; +} + +static int phonebook_storage (struct audio_device *device,const char *buf) +{ +int AT_type, offset; + +if (strlen (buf) <8 ) +return -EINVAL ; + + AT_type =get_AT_type (&buf[7 ], &offset); +telephony_phonebook_storage_req (device, &buf[7 +offset], AT_type); + +return 0 ; +} + +int telephony_phonebook_read_rsp (void *telephony_device,cme_error_t err) +{ +return telephony_generic_rsp (telephony_device, err); +} + +int telephony_phonebook_read_ind (void *telephony_device,const char *entrylist) +{ +struct audio_device *device = telephony_device; +struct headset *hs = device->headset; + +headset_send (hs,"\r\n+CPBR: %s\r\n" , entrylist); + +return 0 ; +} + +static int phonebook_read (struct audio_device *device,const char *buf) +{ +int AT_type, offset; + +if (strlen (buf) <8 ) +return -EINVAL ; + + AT_type =get_AT_type (&buf[7 ], &offset); +telephony_phonebook_read_req (device, &buf[7 +offset], AT_type); + +return 0 ; +} +static struct event event_callbacks[] = { {"ATA" , answer_call }, {"ATD" , dial_number },
@@ -1192,6 +1251,8 @@ static struct event event_callbacks[] = { { "AT+COPS", operator_selection }, { "AT+NREC", nr_and_ec }, { "AT+BVRA", voice_dial }, + { "AT+CPBS", phonebook_storage }, + { "AT+CPBR", phonebook_read }, { 0 } };
@@ -1231,7 +1292,6 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, struct audio_device *device) {struct headset *hs; -struct headset_slc *slc;unsigned char buf[BUF_SIZE ];gsize bytes_read =0 ;gsize free_space;
@@ -1240,7 +1300,6 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond,return FALSE; hs = device->headset; - slc = hs->slc;if (cond & (G_IO_ERR |G_IO_HUP )) {debug ("ERR or HUP on RFCOMM socket" );
@@ -1251,8 +1310,7 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, &bytes_read) != G_IO_ERROR_NONE)return TRUE; - free_space =sizeof (slc->buf) - slc->data_start - - slc->data_length -1 ; + free_space =sizeof (hs->buf) - hs->data_start - hs->data_length -1 ;if (free_space < bytes_read) {/* Very likely that the HS is sending us garbage so
@@ -1261,45 +1319,45 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, goto failed; } -memcpy (&slc->buf[slc->data_start], buf, bytes_read); - slc->data_length += bytes_read; +memcpy (&hs->buf[hs->data_start], buf, bytes_read); + hs->data_length += bytes_read;/* Make sure the data is null terminated so we can use string * functions */ - slc->buf[slc->data_start + slc->data_length] ='\0' ; + hs->buf[hs->data_start + hs->data_length] ='\0' ; -while (slc->data_length >0 ) { +while (hs->data_length >0 ) {char *cr;int err;off_t cmd_len; - cr =strchr (&slc->buf[slc->data_start],'\r' ); + cr =strchr (&hs->buf[hs->data_start],'\r' );if (!cr)break ; - cmd_len =1 + (off_t ) cr - (off_t) &slc->buf[slc->data_start]; + cmd_len =1 + (off_t ) cr - (off_t) &hs->buf[hs->data_start]; *cr ='\0' ;if (cmd_len >1 ) - err =handle_event (device, &slc->buf[slc->data_start]); + err =handle_event (device, &hs->buf[hs->data_start]);else /* Silently skip empty commands */ err =0 ;if (err == -EINVAL ) {error ("Badly formated or unrecognized command: %s" , - &slc->buf[slc->data_start]); + &hs->buf[hs->data_start]); err =headset_send (hs,"\r\nERROR\r\n" ); }else if (err <0 )error ("Error handling command %s: %s (%d)" , - &slc->buf[slc->data_start], + &hs->buf[hs->data_start],strerror (-err), -err); - slc->data_start += cmd_len; - slc->data_length -= cmd_len; + hs->data_start += cmd_len; + hs->data_length -= cmd_len; -if (!slc->data_length) - slc->data_start =0 ; +if (!hs->data_length) + hs->data_start =0 ; }return TRUE;
@@ -1357,9 +1415,6 @@ void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)debug ("%s: Connected to %s" , dev->path, hs_address); - hs->slc = g_new0(struct headset_slc, 1); - hs->slc->nrec = TRUE; -/* In HFP mode wait for Service Level Connection */ if (hs->hfp_active)return ;
@@ -1834,11 +1889,10 @@ static DBusMessage *hs_get_speaker_gain(DBusConnection *conn, {struct audio_device *device = data;struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;DBusMessage *reply;dbus_uint16_t gain; -if (hs->state <HEADSET_STATE_CONNECTED ) +if (hs->state <HEADSET_STATE_CONNECTED || hs->sp_gain <0 )return g_dbus_create_error (msg,ERROR_INTERFACE ".NotAvailable" ,"Operation not Available" );
@@ -1846,7 +1900,7 @@ static DBusMessage *hs_get_speaker_gain(DBusConnection *conn,if (!reply)return NULL ; - gain = (dbus_uint16_t ) slc->sp_gain; + gain = (dbus_uint16_t ) hs->sp_gain;dbus_message_append_args (reply,DBUS_TYPE_UINT16 , &gain,DBUS_TYPE_INVALID );
@@ -1860,11 +1914,10 @@ static DBusMessage *hs_get_mic_gain(DBusConnection *conn, {struct audio_device *device = data;struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;DBusMessage *reply;dbus_uint16_t gain; -if (hs->state <HEADSET_STATE_CONNECTED || slc ==NULL ) +if (hs->state <HEADSET_STATE_CONNECTED || hs->mic_gain <0 )return g_dbus_create_error (msg,ERROR_INTERFACE ".NotAvailable" ,"Operation not Available" );
@@ -1872,7 +1925,7 @@ static DBusMessage *hs_get_mic_gain(DBusConnection *conn,if (!reply)return NULL ; - gain = (dbus_uint16_t ) slc->mic_gain; + gain = (dbus_uint16_t ) hs->mic_gain;dbus_message_append_args (reply,DBUS_TYPE_UINT16 , &gain,DBUS_TYPE_INVALID );
@@ -1887,7 +1940,6 @@ static DBusMessage *hs_set_gain(DBusConnection *conn, {struct audio_device *device = data;struct headset *hs = device->headset; -struct headset_slc *slc = hs->slc;DBusMessage *reply;int err;
@@ -1917,14 +1969,14 @@ static DBusMessage *hs_set_gain(DBusConnection *conn, done:if (type ==HEADSET_GAIN_SPEAKER ) { - slc->sp_gain = gain; + hs->sp_gain = gain;g_dbus_emit_signal (conn, device->path,AUDIO_HEADSET_INTERFACE ,"SpeakerGainChanged" ,DBUS_TYPE_UINT16 , &gain,DBUS_TYPE_INVALID ); }else { - slc->mic_gain = gain; + hs->mic_gain = gain; g_dbus_emit_signal(conn, device->path, AUDIO_HEADSET_INTERFACE, "MicrophoneGainChanged",
@@ -2001,13 +2053,11 @@ static DBusMessage *hs_get_properties(DBusConnection *conn,/* SpeakerGain */ dict_append_entry (&dict,"SpeakerGain" , -DBUS_TYPE_UINT16 , - &device->headset->slc->sp_gain); +DBUS_TYPE_UINT16 , &device->headset->sp_gain);/* MicrophoneGain */ dict_append_entry (&dict,"MicrophoneGain" , -DBUS_TYPE_UINT16 , - &device->headset->slc->mic_gain); +DBUS_TYPE_UINT16 , &device->headset->mic_gain); done:dbus_message_iter_close_container (&iter, &dict);
@@ -2146,8 +2196,10 @@ static int headset_close_rfcomm(struct audio_device *dev) hs->rfcomm =NULL ; } -g_free (hs->slc); - hs->slc =NULL ; + hs->data_start =0 ; + hs->data_length =0 ; + + hs->nrec = TRUE;return 0 ; }
@@ -2202,7 +2254,12 @@ struct headset *headset_init(struct audio_device *dev, uint16_t svc, hs = g_new0(struct headset, 1); hs->rfcomm_ch =-1 ; + hs->sp_gain =-1 ; + hs->mic_gain =-1 ; hs->search_hfp =server_is_enabled (&dev->src,HANDSFREE_SVCLASS_ID ); + hs->hfp_active = FALSE; + hs->cli_active = FALSE; + hs->nrec = TRUE; record =btd_device_get_record (dev->btd_dev, uuidstr);if (!record)
@@ -2445,19 +2502,18 @@ int headset_connect_rfcomm(struct audio_device *dev, GIOChannel *io)int headset_connect_sco (struct audio_device *dev,GIOChannel *io) {struct headset *hs = dev->headset; -struct headset_slc *slc = hs->slc;if (hs->sco)return -EISCONN ; hs->sco =g_io_channel_ref (io); -if (slc->pending_ring) { +if (hs->pending_ring) {ring_timer_cb (NULL ); ag.ring_timer =g_timeout_add_seconds (RING_INTERVAL , ring_timer_cb,NULL ); - slc->pending_ring = FALSE; + hs->pending_ring = FALSE; }return 0 ;
@@ -2476,7 +2532,6 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,void headset_set_state (struct audio_device *dev,headset_state_t state) {struct headset *hs = dev->headset; -struct headset_slc *slc = hs->slc;gboolean value;const char *state_str;headset_state_t old_state = hs->state;
@@ -2522,9 +2577,9 @@ void headset_set_state(struct audio_device *dev, headset_state_t state) DBUS_TYPE_STRING, &state_str);if (hs->state < state) {if (ag.features &AG_FEATURE_INBAND_RINGTONE ) - slc->inband_ring = TRUE; + hs->inband_ring = TRUE;else - slc->inband_ring = FALSE; + hs->inband_ring = FALSE; g_dbus_emit_signal(dev->conn, dev->path, AUDIO_HEADSET_INTERFACE, "Connected",
@@ -2569,10 +2624,10 @@ void headset_set_state(struct audio_device *dev, headset_state_t state)AUDIO_HEADSET_INTERFACE ,"Playing" , DBUS_TYPE_BOOLEAN, &value); -if (slc->sp_gain >=0 ) -headset_send (hs,"\r\n+VGS=%u\r\n" , slc->sp_gain); -if (slc->mic_gain >=0 ) -headset_send (hs,"\r\n+VGM=%u\r\n" , slc->mic_gain); +if (hs->sp_gain >=0 ) +headset_send (hs,"\r\n+VGS=%u\r\n" , hs->sp_gain); +if (hs->mic_gain >=0 ) +headset_send (hs,"\r\n+VGM=%u\r\n" , hs->mic_gain);break ; }
@@ -2681,7 +2736,7 @@ gboolean headset_get_nrec(struct audio_device *dev) {struct headset *hs = dev->headset; -return hs->slc->nrec; +return hs->nrec; }gboolean headset_get_sco_hci (struct audio_device *dev)
@@ -2738,7 +2793,6 @@ int telephony_incoming_call_ind(const char *number, int type) {struct audio_device *dev;struct headset *hs; -struct headset_slc *slc;if (!active_devices)return -ENODEV ;
@@ -2746,7 +2800,6 @@ int telephony_incoming_call_ind(const char *number, int type)/* Get the latest connected device */ dev = active_devices->data; hs = dev->headset; - slc = hs->slc;if (ag.ring_timer) {debug ("telephony_incoming_call_ind: already calling" );
@@ -2755,16 +2808,16 @@ int telephony_incoming_call_ind(const char *number, int type)/* With HSP 1.2 the RING messages should *not* be sent if inband * ringtone is being used */ -if (!hs->hfp_active && slc->inband_ring) +if (!hs->hfp_active && hs->inband_ring)return 0 ;g_free (ag.number); ag.number =g_strdup (number); ag.number_type = type; -if (slc->inband_ring && hs->hfp_active && +if (hs->inband_ring && hs->hfp_active && hs->state !=HEADSET_STATE_PLAYING ) { - slc->pending_ring = TRUE; + hs->pending_ring = TRUE;return 0 ; }
@@ -2790,10 +2843,10 @@ int telephony_calling_stopped_ind(void)/* In case SCO isn't fully up yet */ dev = active_devices->data; -if (!dev->headset->slc->pending_ring && !ag.ring_timer) +if (!dev->headset->pending_ring && !ag.ring_timer)return -EINVAL ; - dev->headset->slc->pending_ring = FALSE; + dev->headset->pending_ring = FALSE;return 0 ; }
@@ -2851,7 +2904,7 @@ static int cwa_cmp(struct headset *hs)if (!hs->hfp_active)return -1 ; -if (hs->slc->cwa_enabled) +if (hs->cwa_enabled)return 0 ;else return -1 ;
audio/telephony-dummy.c +11 -0
@@ -225,6 +225,17 @@ void telephony_key_press_req(void *telephony_device, const char *keys)telephony_key_press_rsp (telephony_device,CME_ERROR_NONE ); } +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_read_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_phonebook_storage_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +/* D-Bus method handlers */ static DBusMessage *outgoing_call (DBusConnection *conn,DBusMessage *msg,void *data)
audio/telephony-fso.c new file +1412 -0
1,412 lines not on this page · raw message
audio/telephony-maemo.c +10 -0
@@ -922,6 +922,16 @@ void telephony_voice_dial_req(void *telephony_device, gboolean enable)telephony_voice_dial_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); } +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_read_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_phonebook_storage_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} +static void handle_incoming_call (DBusMessage *msg) {const char *number, *call_path;
audio/telephony-ofono.c +11 -0
@@ -387,6 +387,17 @@ void telephony_key_press_req(void *telephony_device, const char *keys)telephony_key_press_rsp (telephony_device,CME_ERROR_NONE ); } +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_read_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_phonebook_storage_req (void *telephony_device,const char *readindex,int ATtype) +{ +telephony_phonebook_storage_rsp (telephony_device,CME_ERROR_NOT_SUPPORTED ); +} + +void telephony_voice_dial_req (void *telephony_device,gboolean enable) { debug("telephony-ofono: got %s voice dial request",
audio/telephony.h +12 -0
@@ -127,6 +127,12 @@ typedef enum { CME_ERROR_NETWORK_NOT_ALLOWED = 32, } cme_error_t; +/* AT command types */ +#define AT_NONE 0 +#define AT_TEST 1 +#define AT_READ 2 +#define AT_SET 3 +struct indicator {const char *desc;const char *range;
@@ -157,6 +163,8 @@ void telephony_call_hold_req(void *telephony_device, const char *cmd);void telephony_nr_and_ec_req (void *telephony_device,gboolean enable);void telephony_voice_dial_req (void *telephony_device,gboolean enable);void telephony_key_press_req (void *telephony_device,const char *keys); +void telephony_phonebook_storage_req (void *telephony_device,const char *storage,int AT_type); +void telephony_phonebook_read_req (void *telephony_device,const char *readindex,int AT_type);/* AG responses to HF requests. These are implemented by headset.c */ int telephony_event_reporting_rsp (void *telephony_device,cme_error_t err);
@@ -173,6 +181,8 @@ int telephony_call_hold_rsp(void *telephony_device, cme_error_t err);int telephony_nr_and_ec_rsp (void *telephony_device,cme_error_t err);int telephony_voice_dial_rsp (void *telephony_device,cme_error_t err);int telephony_key_press_rsp (void *telephony_device,cme_error_t err); +int telephony_phonebook_storage_rsp (void *telephony_device,cme_error_t err); +int telephony_phonebook_read_rsp (void *telephony_device,cme_error_t err);/* Event indications by AG. These are implemented by headset.c */ int telephony_event_ind (int index);
@@ -188,6 +198,8 @@ int telephony_subscriber_number_ind(const char *number, int type, int service);int telephony_call_waiting_ind (const char *number,int type);int telephony_operator_selection_ind (int mode,const char *oper); +int telephony_phonebook_storage_ind (void *device,const char *storagelist); +int telephony_phonebook_read_ind (void *device,const char *entrylist);/* Helper function for quick indicator updates */ static inline int telephony_update_indicator(struct indicator *indicators,
Signature · 1 line
1.6.4.2
Hi Felix,
Quoted 10 lines · Felix Huber
Quoted 7 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+int get_ATtype(const char *buf, int *offset) +{ + const char *ATquery = "=?", *ATcheck ="?", *ATset = "=";We usually don't use capital letters in any variable or function names. Pre-processor defines are an exception. So use something like
get_at_type,at_query, etc.Well usually, but since AT in this case is a proper name, I found it very confusing to read it like the prepostion "at" or even a spelled-out @-sign. I added an underscore for better indication of what it is.
I understand your point, but this is simply the way the coding style is. Even if I would accept it (which I wont) it'd ultimately get rejected by Marcel.
Quoted 5 lines
Quoted 4 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+char *fso_categories[NUM_CATEGORIES] = {"contacts", "emergency", "fixed", "dialed", "received", "missed", "own"}; +char *gsm_categories[NUM_CATEGORIES] = {"\"SM\"", "\"EN\"", "\"FD\"","\"DC\"", "\"RC\"", "\"MC\"", "\"ON\""};Probably you could split these to fit within 80 columns.
Done, but now we loose the one-to-one correspondance.
Ah, I missed that relationship between the two lists. If this one-to-one correspondance is so important, why not create a simple struct with two const char* members and have just one list? Then you'd have the definition as something like:
struct category categories[] = {
{ "contacts", "\"SM\"" },
{ "emergency", "\"EN\"" },
...
{ NULL, NULL }
};Quoted 8 lines
Quoted 5 lines
audio/telephony-fso.c line 268
Quoted 1 line
audio/telephony-fso.c new file +1
-0+if (!strcmp (phonebooks[i], category))The convention has usually been to use == 0 in the case of strcmp for readability.
Not quite, as it seems: I looked at the other files and they also used the ! (including one commited by you :) ). So I chose the logical not, which also frees one from having to handle 0 vs. NULL.
BlueZ is unfortunately full of many such inconsistencies in the code:
jh@jh-x301~/src/bluez{master}$ git grep '!.*cmp('|wc -l
183
jh@jh-x301~/src/bluez{master}$ git grep 'cmp(.*== 0'|wc -l
111But you're right in that the '!' form seems to be more frequent (those regexps might have some false positives though). IMHO since the test in question is a positive one ("if A is equal to B, then...") the negation sign in the statement is at least initially counterintuitive. You might also want to consider using g_str_equal which is quite popular througout the code base (I got 102 hits) or g_strcmp0 in the case that there is risk that one of the inputs could be NULL.
Quoted 9 lines
Quoted 9 lines
audio/telephony-fso.c line 363
Quoted 4 lines
audio/telephony-fso.c new file +4
-0+if ((vc =find_vc_with_status (CALL_STATUS_ACTIVE ))) { + }else if ((vc =find_vc_with_status (CALL_STATUS_DIALING ))) { + }else if ((vc =find_vc_with_status (CALL_STATUS_INCOMING ))) { + }The purpose of this construction isn't imediately clear imo. Wouldn't something like doing specific NULL checks after each
find()call be more readable? I.e.
Quoted 5 lines
Well, to me it was clear that these are nested calls until a valid vc is found. But anyway, I copied this from telephony-ofono and tried to stay close to the original code for better re-recognition. So either both should be changed or none but not be strict only on new code, since this makes copy-and-paste ineffective.
Ok, so let's just leave it as it is for now.
Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+#if 0 +if (!strncmp (number,"*31#" ,4 )) { + number +=4 ; + clir ="enabled" ; + }else if (!strncmp (number,"#31#" ,4 )) {Quoted 9 lines
audio/telephony-fso.c line 425
Quoted 5 lines
audio/telephony-fso.c new file +5
-0+ number +=4 ; + clir = "disabled"; + }else + clir ="default" ; +#endif Is this really code that you think can be enabled later? If not I'd just remove it instead of having it commented out.
Quoted 4 lines
Yes, it is needed. My car kit (and maybe others) have a menu to activate this, but the current FSO API cannot handle it yet. Since this driver needs to be update anyhow once the opimd is final, I left it in so it cannot get forgotten to be reenabled.
Alright, so it's fine then.
Quoted 17 lines
Quoted 9 lines
Quoted 9 lines
audio/telephony-fso.c new file +9
-0+if (cmd) { + err =send_method_call (FSO_BUS_NAME ,FSO_MODEM_OBJ_PATH , +FSO_GSMC_INTERFACE , + cmd,NULL ,NULL , +DBUS_TYPE_INT32 , &vc->call_index, +DBUS_TYPE_INVALID ); + } +if (err <0 ) +telephony_key_press_rsp (telephony_device,CME_ERROR_AG_FAILURE );Quoted 8 lines
audio/telephony-fso.c line 542
Quoted 2 lines
audio/telephony-fso.c new file +2
-0+else +telephony_key_press_rsp (telephony_device,CME_ERROR_NONE );Shouldn't it be an error if cmd is NULL? In general doing initializations upon declaration, especially for error variables, should be avoided. Would e.g. having a final "else err =
-EINVAL" at the end of the else/else if statement make sense (which would allow removing the initialzation of err to 0?
Quoted 4 lines
No no, beware! It can happen that the other side of the phone call just hung up before the key press or that a nasty user presses a key when nothing is going on. In this case, the press is silenty ignored instead of confusing some headsets with an unexpected failure.
Right. Do fix the braces usage for the single-line though. You might want to consider getting rid of the act and rel variables completely and just assign directly the string to cmd (or if it bothers you to have the same string twice for ACTIVE and DIALING create #defines for them.
Quoted 10 lines
Quoted 10 lines
audio/telephony-fso.c
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+static void retrieve_phonebook_reply (DBusPendingCall *call,void *user_data) +{ +DBusError err; +DBusMessage *reply; +DBusMessageIter iter, array; +int ret =0 ;Instead of initializing ret upon declaration (and btw, we use "err" instead of "ret" usually) you could set it to 0 right before the done label.
Quoted 2 lines
Again, I checked with the other telephony files: they use ret for their codes and err for DBus error. So I stayed consistent with the names.
I guess this is yet another example of BlueZ internal inconsistency then. However, I know that Marcel prefers err and we should strive to use it in all new code.
Quoted 7 lines
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ gstr = g_string_new("("); + for (i=0; i< n_s; i++) {Missing spaces before and after '=', before '<'. Can you come up with a more descriptive name for the
n_svariable please?What about
num_strings? This is my feeling only, since I copied this from the DBus tutorial.
num_strings is certianly more descriptive than the current name and I can't come up with anything better right now, so let's just go with it.
Quoted 10 lines
Quoted 8 lines
audio/telephony-fso.c line 899
Quoted 3 lines
audio/telephony-fso.c new file +3
-0+sscanf (readindex,"%d,%d" , &phonebook_info.first, &phonebook_info.last); +if (phonebook_info.first ==-1 ) +break ;Probably you'd also want to check for sscanf return value (i.e. == 2). Maybe that's the only thing you should check for and not try to initialize these variables here since you already do that in the beginning of
telephony-fso.cwhere you define thephonebook_infostruct?Nope, the arguments are optional and both 0,1 or two conversions can happen, so the return of sscanf serves nothing in this case.
Ok.
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+if (g_str_equal (property,"direction" )) { +dbus_message_iter_get_basic (&sub, &direction); + }else if (g_str_equal (property,"peer" )) { +dbus_message_iter_get_basic (&sub, &peer); + vc->number =g_strdup (peer); + }else if (g_str_equal (property,"reason" )) {Quoted 8 lines
audio/telephony-fso.c line 940
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+dbus_message_iter_get_basic (&sub, &reason); + }else if (g_str_equal (property,"auxstatus" )) { +dbus_message_iter_get_basic (&sub, &auxstatus); + }else if (g_str_equal (property,"line" )) { +dbus_message_iter_get_basic (&sub, &line); + }No braces for one-line scopes.
Quoted 3 lines
Well, here we have a conflict: The kernel style guide says that if one of the blocks has braces the other one should also have, even if it is a single line.
Yesh, I noticed the same thing when checking the kernel coding style guidelines. Most of BlueZ code is in conflict with the kernel coding style in this respect, so I think we'd need some comment from Marcel on what exactly he wants the BlueZ style to be (might be that I've already discussed this a long time ago with him but I can't remember the outcome right now).
Quoted 4 lines
Quoted 3 lines
audio/telephony-fso.c line 665
Quoted 1 line
audio/telephony-fso.c new file +1
-0+/* ARRAY -> ENTRY -> VARIANT*/ Space before */
Done, copy and paste
telephony-ofono.c-> should be fixed there too.
Alright. I just pushed a fix for telephony-ofono.c.
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
audio/telephony.h +0
-0@@ -127,6 +127,12 @@ typedef enum { CME_ERROR_NETWORK_NOT_ALLOWED = 32, } cme_error_t;Quoted 8 lines
audio/telephony.h typedef enum { · line 134
Quoted 5 lines
audio/telephony.h +5
-0+/* AT command types */ +#define ATNONE 0 +#define ATQUERY 1 +#define ATCHECK 2 +#define ATSET 3These should probably be an enum and have some namespacing (e.g.
AT_TYPE_).
Quoted 3 lines
Again, in order to be consistent with the existing codes, I looked at what the other files do. I adopted the use of the Call parameters, like
CALL_STATUS_ACTIVE. These are all #defines
Right. So AT_* should be enough then (as you've done).
Johan
Marcel Holtmann
maintainerHi Johan,
Quoted 18 lines
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+if (g_str_equal (property,"direction" )) { +dbus_message_iter_get_basic (&sub, &direction); + }else if (g_str_equal (property,"peer" )) { +dbus_message_iter_get_basic (&sub, &peer); + vc->number =g_strdup (peer); + }else if (g_str_equal (property,"reason" )) {Quoted 8 lines
audio/telephony-fso.c line 940
Quoted 6 lines
audio/telephony-fso.c new file +6
-0+dbus_message_iter_get_basic (&sub, &reason); + }else if (g_str_equal (property,"auxstatus" )) { +dbus_message_iter_get_basic (&sub, &auxstatus); + }else if (g_str_equal (property,"line" )) { +dbus_message_iter_get_basic (&sub, &line); + }No braces for one-line scopes.
Quoted 3 lines
Well, here we have a conflict: The kernel style guide says that if one of the blocks has braces the other one should also have, even if it is a single line.
Quoted 6 lines
Yesh, I noticed the same thing when checking the kernel coding style guidelines. Most of BlueZ code is in conflict with the kernel coding style in this respect, so I think we'd need some comment from Marcel on what exactly he wants the BlueZ style to be (might be that I've already discussed this a long time ago with him but I can't remember the outcome right now).
there is not real rule here that can be followed and will be true in all cases. As long as the code is easy to read and understand it is fine. It goes more like this: If the else statement is by itself then don't bother with braces around it. Even if the if needs braces. If you have multiple else if then the braces are actually a good idea. I would almost go that far for complex ones like the one above using braces would make it less error prone if you change something later. Even if the compiler actually does warn you these days.
Use your own personal judgment here. However if the reviewing the code make my brain hurt, then you did it wrong ;)
Regards
Marcel
Quoted 2 lines · On Mon, 08 Mar 2010 21:27:21 -0800 Marcel Holtmann <[email protected]> wrote:
Use your own personal judgment here. However if the reviewing the code make my brain hurt, then you did it wrong ;)
Now all one needs to invent is a "Marcel's-brain-hurt-O-meter" :-P
Have fun,
seife
Signature · 4 lines
Stefan Seyfried "Any ideas, John?" "Well, surrounding them's out."
Marcel Holtmann
maintainerHi Stefan,
Quoted 4 lines
Quoted 2 lines
Use your own personal judgment here. However if the reviewing the code make my brain hurt, then you did it wrong ;)
Now all one needs to invent is a "Marcel's-brain-hurt-O-meter" :-P
if you get one of these, send me one ;)
Regards
Marcel