bluetooth: Move name at the end of EIR
authorSzymon Janc <szymon.janc@tieto.com>
Wed, 31 Oct 2012 11:22:18 +0000 (12:22 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Wed, 14 Nov 2012 10:35:44 +0000 (11:35 +0100)
This will make sure that hash and randomizer are send even when name is
long. Also limit name to not exceed maximum sensible EIR length of 255
bytes. If name would not fit use EIR_NAME_SHORT data type for it.

src/bluetooth.c

index bb85c90..62d8aac 100644 (file)
@@ -62,6 +62,7 @@
 #define BT_ADDRESS_SIZE                6
 #define COD_SIZE               3
 #define OOB_SP_SIZE            16
+#define EIR_SIZE_MAX           255
 
 #define get_unaligned(ptr)                     \
 ({                                             \
@@ -795,7 +796,6 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len,
 {
        uint8_t *bt_oob_block = NULL;
        uint16_t bt_oob_block_size = 0;
-       int max_block_size;
        uint8_t offset;
 
        char hash[OOB_SP_SIZE];
@@ -807,22 +807,10 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len,
                goto fail;
        }
 
-       /* Prepare the BT block */
-       max_block_size = sizeof(uint16_t) +             /* stored oob size */
-                       BT_ADDRESS_SIZE +
-                       EIR_HEADER_LEN + bt_def_oob_data.bt_name_len +
-                       EIR_HEADER_LEN + COD_SIZE;      /* class */
-
-       /* Should we add oob pairing keys ?*/
-       if (mime_props & OOB_PROPS_SP) {
-               max_block_size += (EIR_HEADER_LEN + OOB_SP_SIZE + /* oob hash */
-                               EIR_HEADER_LEN + OOB_SP_SIZE); /* oob random */
-       }
-
        bt_oob_block_size = sizeof(uint16_t)    /* stored oob size */
                        + BT_ADDRESS_SIZE;      /* device address */
 
-       bt_oob_block = g_try_malloc0(max_block_size);
+       bt_oob_block = g_try_malloc0(EIR_SIZE_MAX);
        if (bt_oob_block == NULL)
                goto fail;
        offset = sizeof(uint16_t); /* Skip size...will be filled later */
@@ -831,19 +819,6 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len,
        memcpy(bt_oob_block + offset, bt_def_oob_data.bd_addr, BT_ADDRESS_SIZE);
        offset += BT_ADDRESS_SIZE;
 
-       /* bt name */
-       if (bt_def_oob_data.bt_name != NULL) {
-               bt_oob_block_size += (bt_def_oob_data.bt_name_len +
-                                                               EIR_HEADER_LEN);
-
-               bt_oob_block[offset++] = bt_def_oob_data.bt_name_len +
-                                                               EIR_SIZE_LEN;
-               bt_oob_block[offset++] = EIR_NAME_COMPLETE; /* EIR data type */
-               memcpy(bt_oob_block + offset, bt_def_oob_data.bt_name,
-                                       bt_def_oob_data.bt_name_len);
-               offset += bt_def_oob_data.bt_name_len;
-       }
-
        /* CoD */
        bt_oob_block_size += COD_SIZE +  EIR_HEADER_LEN;
 
@@ -854,14 +829,13 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len,
                        (uint8_t *)&bt_def_oob_data.class_of_device, COD_SIZE);
        offset += COD_SIZE;
 
-       /* The following data are generated dynamically
-        * so we have to read the local oob data
-        * */
-       /* Should we add oob pairing keys */
-       if ((mime_props & OOB_PROPS_SP) == 0)
-               goto out;
-
-       if (bt_sync_oob_readlocaldata(bt_conn, bt_def_oob_data.def_adapter,
+       /*
+        * The following data are generated dynamically so we have to read the
+        * local oob data. Only add OOB pairing keys if needed.
+        */
+       if ((mime_props & OOB_PROPS_SP) != 0 &&
+                       bt_sync_oob_readlocaldata(bt_conn,
+                                       bt_def_oob_data.def_adapter,
                                        hash, random) == OOB_SP_SIZE) {
                bt_oob_block_size += 2 * (OOB_SP_SIZE + EIR_HEADER_LEN);
 
@@ -881,7 +855,31 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len,
                }
        }
 
-out:
+       /* bt name */
+       if (bt_def_oob_data.bt_name != NULL) {
+               int name_len;
+
+               bt_oob_block_size += EIR_HEADER_LEN;
+
+               if (bt_oob_block_size + bt_def_oob_data.bt_name_len
+                               > EIR_SIZE_MAX) {
+                       name_len = EIR_SIZE_MAX - bt_oob_block_size;
+                       bt_oob_block[offset++] = name_len + EIR_SIZE_LEN;
+                       /* EIR data type */
+                       bt_oob_block[offset++] = EIR_NAME_SHORT;
+               } else {
+                       name_len = bt_def_oob_data.bt_name_len;
+                       bt_oob_block[offset++] = name_len + EIR_SIZE_LEN;
+                       /* EIR data type */
+                       bt_oob_block[offset++] = EIR_NAME_COMPLETE;
+               }
+
+               bt_oob_block_size += name_len;
+               memcpy(bt_oob_block + offset, bt_def_oob_data.bt_name,
+                                                               name_len);
+               offset += name_len;
+       }
+
        *(uint16_t *)bt_oob_block = bt_oob_block_size ;
        *bt_data_len = bt_oob_block_size;