bluetooth: Extend mime_type with bluetooth properties
authorOlivier Guiter <olivier.guiter@linux.intel.com>
Mon, 22 Oct 2012 13:52:54 +0000 (15:52 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Wed, 24 Oct 2012 15:51:34 +0000 (17:51 +0200)
To comply with handover specs, if the incoming Hr OOB doesn't include
SP hash/randomizer keys, the reply (Hs) should not include such
information. So we store it to the cfg mime_type.

src/bluetooth.c
src/ndef.c
src/near.h

index 9600b2f..63e76da 100644 (file)
@@ -527,7 +527,7 @@ static int bt_refresh_adapter_props(DBusConnection *conn, void *user_data)
 
 /* Parse and fill the bluetooth oob information block */
 static void bt_parse_eir(uint8_t *eir_data, uint16_t eir_data_len,
-                                               struct near_oob_data *oob)
+                               struct near_oob_data *oob, uint16_t *props)
 {
        char *tmp;
        uint16_t len = 0;
@@ -571,22 +571,28 @@ static void bt_parse_eir(uint8_t *eir_data, uint16_t eir_data_len,
                case EIR_CLASS_OF_DEVICE:
                        tmp = g_strdup_printf("%02X%02X%02X",
                                        *data, *(data + 1), *(data + 2));
-                       if (tmp != NULL)
+                       if (tmp != NULL) {
                                oob->class_of_device = strtol(tmp, NULL, 16);
+                               *props |= OOB_PROPS_COD;
+                       }
                        g_free(tmp);
                        break;
 
                case EIR_SP_HASH:
                        oob->spair_hash = g_try_malloc0(OOB_SP_SIZE);
-                       if (oob->spair_hash)
+                       if (oob->spair_hash) {
                                memcpy(oob->spair_hash, data, OOB_SP_SIZE);
+                               *props |= OOB_PROPS_SP_HASH;
+                       }
                        break;
 
                case EIR_SP_RANDOMIZER:
                        oob->spair_randomizer = g_try_malloc0(OOB_SP_SIZE);
-                       if (oob->spair_randomizer)
+                       if (oob->spair_randomizer) {
                                memcpy(oob->spair_randomizer,
                                                data, OOB_SP_SIZE);
+                               *props |= OOB_PROPS_SP_RANDOM;
+                       }
                        break;
 
                case EIR_SECURITY_MGR_FLAGS:
@@ -613,9 +619,11 @@ static void bt_parse_eir(uint8_t *eir_data, uint16_t eir_data_len,
  * to determine the record data structure.
  * Some specifications are proprietary (eg. "short mode")
  * and are not fully documented.
+ * mime_properties is a bitmask and should reflect the fields found in
+ * the incoming oob.
  */
 int __near_bluetooth_parse_oob_record(uint8_t version, uint8_t *bt_data,
-               near_bool_t pair)
+                               uint16_t *mime_properties, near_bool_t pair)
 {
        struct near_oob_data *oob;
        uint16_t bt_oob_data_size;
@@ -653,7 +661,8 @@ int __near_bluetooth_parse_oob_record(uint8_t version, uint8_t *bt_data,
                bt_oob_data_size -= BT_ADDRESS_SIZE ;
 
                if (bt_oob_data_size)
-                       bt_parse_eir(ptr, bt_oob_data_size, oob);
+                       bt_parse_eir(ptr, bt_oob_data_size, oob,
+                                                       mime_properties);
        } else if (version == BT_MIME_V2_0) {
                marker = *ptr++;        /* could be '$' */
 
@@ -778,8 +787,11 @@ done:
 /*
  * External API to get bt properties
  * Prepare a "real" oob datas block
+ * mime_props is a bitmask we use to add or not specific fields in the
+ * oob frame (e.g.: OOB keys)
  * */
-uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len)
+uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len,
+                                               uint16_t mime_props)
 {
        uint8_t *bt_oob_block = NULL;
        uint16_t bt_oob_block_size = 0;
@@ -799,10 +811,13 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len)
        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 */
-                       EIR_HEADER_LEN + OOB_SP_SIZE +  /* oob hash */
-                       EIR_HEADER_LEN + OOB_SP_SIZE;   /* oob random */
+                       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 */
@@ -842,6 +857,10 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len)
        /* 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,
                                        hash, random) == OOB_SP_SIZE) {
                bt_oob_block_size += 2 * (OOB_SP_SIZE + EIR_HEADER_LEN);
@@ -862,6 +881,7 @@ uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len)
                }
        }
 
+out:
        *(uint16_t *)bt_oob_block = bt_oob_block_size ;
        *bt_data_len = bt_oob_block_size;
 
index 9168cd1..68d2c19 100644 (file)
@@ -140,6 +140,11 @@ struct near_ndef_sp_payload {
 
 struct near_ndef_mime_payload {
        char *type;
+
+       struct {
+               uint8_t carrier_type;
+               uint16_t properties;    /* e.g.: NO_PAIRING_KEY */
+       } handover;
 };
 
 enum carrier_power_state {
@@ -1370,11 +1375,15 @@ parse_mime_type(struct near_ndef_record *record,
 
        DBG("MIME Type  '%s' action: %d", mime->type, action);
        if (strcmp(mime->type, BT_MIME_STRING_2_1) == 0) {
+               mime->handover.carrier_type = NEAR_CARRIER_BLUETOOTH;
                err = __near_bluetooth_parse_oob_record(BT_MIME_V2_1,
-                               &ndef_data[offset], action);
+                               &ndef_data[offset], &mime->handover.properties,
+                               action);
        } else if (strcmp(mime->type, BT_MIME_STRING_2_0) == 0) {
+               mime->handover.carrier_type = NEAR_CARRIER_BLUETOOTH;
                err = __near_bluetooth_parse_oob_record(BT_MIME_V2_0,
-                               &ndef_data[offset], action);
+                               &ndef_data[offset], &mime->handover.properties,
+                               action);
        }
 
        if (err < 0) {
@@ -1676,6 +1685,46 @@ fail:
 }
 
 /*
+ * Walk thru the cfgs list and set the carriers bitfield
+ */
+static uint8_t near_get_carriers_list(struct near_ndef_record *record)
+{
+       struct near_ndef_ho_payload *ho = record->ho;
+       uint8_t carriers;
+       int i;
+
+       carriers = 0;
+
+       for (i = 0; i < ho->number_of_cfg_payloads; i++) {
+               struct near_ndef_mime_payload *rec = ho->cfg_payloads[i];
+
+               carriers |= rec->handover.carrier_type;
+       }
+
+       return carriers;
+}
+
+/*
+ * Walk thru the cfgs list and get the properties corresponding
+ * to the carrier bit.
+ */
+static uint16_t near_get_carrier_properties(struct near_ndef_record *record,
+                                               uint8_t carrier_bit)
+{
+       struct near_ndef_ho_payload *ho = record->ho;
+       int i;
+
+       for (i = 0; i < ho->number_of_cfg_payloads; i++) {
+               struct near_ndef_mime_payload *rec = ho->cfg_payloads[i];
+
+               if ((rec->handover.carrier_type & carrier_bit) != 0)
+                       return rec->handover.properties;
+       }
+
+       return OOB_PROPS_EMPTY;
+}
+
+/*
  * @brief Prepare Handover select record with mandatory fields.
  *
  * TODO: only mime (BT) are supported now... Wifi will come soon...
@@ -1692,6 +1741,7 @@ struct near_ndef_message *near_ndef_prepare_handover_record(char* type_name,
        struct near_ndef_message *ac_msg = NULL;
        struct near_ndef_message *cr_msg = NULL;
        struct near_ndef_message *bt_msg = NULL;
+       uint16_t props;
        uint16_t collision;
        uint8_t hs_length;
        char cdr = '0';                 /* Carrier data reference */
@@ -1701,6 +1751,10 @@ struct near_ndef_message *near_ndef_prepare_handover_record(char* type_name,
 
        collision = record->ho->collision_record;
 
+       /* Walk the cfg list to get the carriers */
+       if (carriers == NEAR_CARRIER_UNKNOWN)
+               carriers = near_get_carriers_list(record);
+
        /*
         * Prepare records to be added
         * now prepare the cr message: MB=1 ME=0
@@ -1721,7 +1775,11 @@ struct near_ndef_message *near_ndef_prepare_handover_record(char* type_name,
 
        if (carriers & NEAR_CARRIER_BLUETOOTH) {
                /* Retrieve the bluetooth settings */
-               oob_data = __near_bluetooth_local_get_properties(&oob_size);
+               props = near_get_carrier_properties(record,
+                                                       NEAR_CARRIER_BLUETOOTH);
+
+               oob_data = __near_bluetooth_local_get_properties(&oob_size,
+                                                                       props);
                if (oob_data == NULL) {
                        near_error("Getting Bluetooth OOB data failed");
                        goto fail;
index b3eae4c..94d011d 100644 (file)
@@ -168,13 +168,23 @@ void __near_plugin_cleanup(void);
 #define BT_MIME_V2_1           1
 #define BT_MIME_STRING_2_0     "nokia.com:bt"
 #define BT_MIME_STRING_2_1     "application/vnd.bluetooth.ep.oob"
+#define WIFI_MIME_STRING       "application/vnd.wfa.wsc"
+
+/* Mime specific properties */
+#define OOB_PROPS_EMPTY                0x00
+#define OOB_PROPS_SP_HASH      0x01
+#define OOB_PROPS_SP_RANDOM    0x02
+#define OOB_PROPS_SHORT_NAME   0x04
+#define OOB_PROPS_COD          0x08
+#define OOB_PROPS_SP           (OOB_PROPS_SP_HASH | OOB_PROPS_SP_RANDOM)
 
 int __near_bluetooth_init(void);
 void __near_bluetooth_cleanup(void);
 int __near_bluetooth_parse_oob_record(uint8_t version, uint8_t *bt_data,
-                                                       near_bool_t pair);
+                                       uint16_t *properties, near_bool_t pair);
 int __near_bluetooth_pair(void *data);
-uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len);
+uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len,
+                                                       uint16_t mime_props);
 
 void __near_agent_ndef_parse_records(GList *records);
 int __near_agent_ndef_register(const char *sender, const char *path,