diff options
-rw-r--r-- | src/bluetooth.c | 40 | ||||
-rw-r--r-- | src/ndef.c | 64 | ||||
-rw-r--r-- | src/near.h | 14 |
3 files changed, 103 insertions, 15 deletions
diff --git a/src/bluetooth.c b/src/bluetooth.c index 9600b2f..63e76da 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -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; @@ -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; @@ -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, |