OSDN Git Service

android/client: Add GATT complex type parsing
authorJerzy Kasenberg <jerzy.kasenberg@tieto.com>
Thu, 31 Oct 2013 10:45:12 +0000 (11:45 +0100)
committerJohan Hedberg <johan.hedberg@intel.com>
Thu, 31 Oct 2013 14:01:06 +0000 (16:01 +0200)
This patch adds code to parse: UUID, service ID, characteristic ID,
and general hex string filed.

android/client/if-gatt.c

index b3b2637..2a4437a 100644 (file)
@@ -136,10 +136,79 @@ static char *gatt_uuid_t2str(const bt_uuid_t *uuid, char *buf)
  */
 static void scan_field(const char *str, int len, uint8_t *out, int out_size)
 {
+       int i;
+
+       memset(out, 0, out_size);
+       if (out_size * 2 > len + 1)
+               out_size = (len + 1) / 2;
+
+       for (i = 0; i < out_size && len > 0; ++i) {
+               len -= 2;
+               if (len >= 0)
+                       sscanf(str + len, "%02hhx", &out[i]);
+               else
+                       sscanf(str, "%1hhx", &out[i]);
+       }
 }
 
+/* Like strchr but with upper limit instead of 0 terminated string */
+static const char *strchrlimit(const char *p, const char *e, int c)
+{
+       while (p < e && *p != (char) c)
+               ++p;
+
+       return p < e ? p : NULL;
+}
+
+/*
+ * converts string to uuid
+ * it accepts uuid in following forms:
+ *     123
+ *     0000123
+ *     0000123-0014-1234-0000-000056789abc
+ *     0000123001412340000000056789abc
+ *     123-14-1234-0-56789abc
+ */
 static void gatt_str2bt_uuid_t(const char *str, int len, bt_uuid_t *uuid)
 {
+       int dash_cnt = 0;
+       int dashes[6] = {-1}; /* indexes of '-' or \0 */
+       static uint8_t filed_offset[] = { 16, 12, 10, 8, 6, 0 };
+       const char *p = str;
+       const char *e;
+       int i;
+
+       e = str + ((len >= 0) ? len : (int) strlen(str));
+
+       while (p != NULL && dash_cnt < 5) {
+               const char *f = strchrlimit(p, e, '-');
+
+               if (f != NULL)
+                       dashes[++dash_cnt] = f++ - str;
+               p = f;
+       }
+
+       /* get index of \0 to dashes table */
+       if (dash_cnt < 5)
+               dashes[++dash_cnt] = e - str;
+
+       memcpy(uuid, GATT_BASE_UUID, sizeof(bt_uuid_t));
+
+       /* whole uuid in one string without dashes */
+       if (dash_cnt == 1 && dashes[1] > 8) {
+               if (dashes[1] > 32)
+                       dashes[1] = 32;
+               scan_field(str, dashes[1],
+                               &uuid->uu[16 - (dashes[1] + 1) / 2],
+                               (dashes[1] + 1) / 2);
+       } else {
+               for (i = 0; i < dash_cnt; ++i) {
+                       scan_field(str + dashes[i] + 1,
+                                       dashes[i + 1] - dashes[i] - 1,
+                                       &uuid->uu[filed_offset[i + 1]],
+                                       filed_offset[i] - filed_offset[i + 1]);
+               }
+       }
 }
 
 /* char_id formating function */
@@ -155,6 +224,26 @@ static char *btgatt_char_id_t2str(const btgatt_char_id_t *char_id, char *buf)
 /* Parse btgatt_char_id_t */
 static void str2btgatt_char_id_t(const char *buf, btgatt_char_id_t *char_id)
 {
+       const char *e;
+
+       memcpy(&char_id->uuid, &GATT_BASE_UUID, sizeof(bt_uuid_t));
+       char_id->inst_id = 0;
+
+       if (*buf == '{')
+               buf++;
+       e = strpbrk(buf, " ,}");
+       if (e == NULL)
+               e = buf + strlen(buf);
+
+       gatt_str2bt_uuid_t(buf, e - buf, &char_id->uuid);
+       if (*e == ',') {
+               buf = e + 1;
+               e = strpbrk(buf, " ,}");
+               if (e == NULL)
+                       e = buf + strlen(buf);
+               if (buf < e)
+                       char_id->inst_id = atoi(buf);
+       }
 }
 
 /* service_id formating function */
@@ -170,6 +259,36 @@ static char *btgatt_srvc_id_t2str(const btgatt_srvc_id_t *srvc_id, char *buf)
 /* Parse btgatt_srvc_id_t */
 static void str2btgatt_srvc_id_t(const char *buf, btgatt_srvc_id_t *srvc_id)
 {
+       const char *e;
+
+       memcpy(&srvc_id->id.uuid, &GATT_BASE_UUID, sizeof(bt_uuid_t));
+       srvc_id->id.inst_id = 0;
+       srvc_id->is_primary = 1;
+
+       if (*buf == '{')
+               buf++;
+       e = strpbrk(buf, " ,}");
+       if (e == NULL)
+               e = buf + strlen(buf);
+
+       gatt_str2bt_uuid_t(buf, e - buf, &srvc_id->id.uuid);
+       if (*e == ',') {
+               buf = e + 1;
+               e = strpbrk(buf, " ,}");
+               if (e == NULL)
+                       e = buf + strlen(buf);
+               if (buf < e)
+                       srvc_id->id.inst_id = atoi(buf);
+       }
+
+       if (*e == ',') {
+               buf = e + 1;
+               e = strpbrk(buf, " ,}");
+               if (e == NULL)
+                       e = buf + strlen(buf);
+               if (buf < e)
+                       srvc_id->is_primary = atoi(buf);
+       }
 }
 
 /* Converts array of uint8_t to string representation */