From 8a14175357879aec0b8d26bc381da681e41a89c6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 31 Oct 2012 12:22:21 +0100 Subject: [PATCH] Use handover agent for Bluetooth data If detected BlueZ is not version 4 handover agent is used for bluetooth data handling. --- include/ndef.h | 9 ++++-- plugins/handover.c | 25 +++-------------- plugins/nfctype3.c | 2 +- plugins/nfctype4.c | 2 +- plugins/snep.c | 35 ++++++++++-------------- src/ndef.c | 80 +++++++++++++++++++++++++++++++++++++----------------- src/near.h | 2 +- src/tlv.c | 2 +- 8 files changed, 84 insertions(+), 73 deletions(-) diff --git a/include/ndef.h b/include/ndef.h index fdc5006..cbcf0b0 100644 --- a/include/ndef.h +++ b/include/ndef.h @@ -25,6 +25,7 @@ #include struct near_ndef_record; +struct bt_data; struct near_ndef_message { size_t length; @@ -43,7 +44,8 @@ int near_ndef_count_records(uint8_t *ndef_in, size_t ndef_in_length, int near_ndef_record_length(uint8_t *ndef_in, size_t ndef_in_length); -GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length); +GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length, + struct near_ndef_message **reply); void near_ndef_records_free(GList *records); @@ -54,8 +56,9 @@ struct near_ndef_message *near_ndef_prepare_uri_record(uint8_t identifier, uint32_t field_length, uint8_t *field); struct near_ndef_message *near_ndef_prepare_handover_record(char* type_name, - struct near_ndef_record *record, - uint8_t carriers); + struct near_ndef_record *record, + uint8_t carriers, + struct bt_data *remote); struct near_ndef_message * near_ndef_prepare_smartposter_record(uint8_t uri_identifier, diff --git a/plugins/handover.c b/plugins/handover.c index b4dd148..9ef3dbd 100644 --- a/plugins/handover.c +++ b/plugins/handover.c @@ -112,7 +112,7 @@ static int handover_ndef_parse(int client_fd, struct hr_ndef *ndef) { int err; GList *records; - struct near_ndef_message *msg; + struct near_ndef_message *msg = NULL; DBG(""); @@ -123,30 +123,15 @@ static int handover_ndef_parse(int client_fd, struct hr_ndef *ndef) } /* call the global parse function */ - records = near_ndef_parse_msg(ndef->ndef, ndef->cur_ptr); + records = near_ndef_parse_msg(ndef->ndef, ndef->cur_ptr, &msg); if (records == NULL) { err = -ENOMEM; goto fail; } - /* - * If we receive a request, we should reply with a Hs but - * if the initial frame is Hs (it means we initiated the - * exchange with a Hr), so we have to do some actions (e.g.: - * pairing with bluetooth) - */ - if (strncmp((char *) (ndef->ndef + FRAME_TYPE_OFFSET), "Hr", 2) == 0) { - /* - * The first entry on the record list is the Hr record. - * We build the Hs based on it. - */ - msg = near_ndef_prepare_handover_record("Hs", records->data, - NEAR_CARRIER_UNKNOWN); - if (msg == NULL) { - err = -EINVAL; - goto fail; - } + near_ndef_records_free(records); + if (msg) { near_info("Send Hs frame"); err = send(client_fd, msg->data, msg->length, MSG_DONTWAIT); @@ -156,8 +141,6 @@ static int handover_ndef_parse(int client_fd, struct hr_ndef *ndef) err = 0; } - near_ndef_records_free(records); - return err; fail: diff --git a/plugins/nfctype3.c b/plugins/nfctype3.c index 279053d..5f96685 100644 --- a/plugins/nfctype3.c +++ b/plugins/nfctype3.c @@ -246,7 +246,7 @@ static int data_recv(uint8_t *resp, int length, void *data) tag->current_block = 0; DBG("Done reading %zd bytes at %p", data_length, nfc_data); - records = near_ndef_parse_msg(nfc_data, data_length); + records = near_ndef_parse_msg(nfc_data, data_length, NULL); near_tag_add_records(tag->tag, records, tag->cb, 0); g_free(tag); diff --git a/plugins/nfctype4.c b/plugins/nfctype4.c index e6662b2..538630a 100644 --- a/plugins/nfctype4.c +++ b/plugins/nfctype4.c @@ -329,7 +329,7 @@ static int data_read_cb(uint8_t *resp, int length, void *data) DBG("Done reading"); - records = near_ndef_parse_msg(nfc_data, data_length); + records = near_ndef_parse_msg(nfc_data, data_length, NULL); near_tag_add_records(cookie->tag, records, cookie->cb, 0); return t4_cookie_release(0, cookie); diff --git a/plugins/snep.c b/plugins/snep.c index 59954c3..9395530 100644 --- a/plugins/snep.c +++ b/plugins/snep.c @@ -190,7 +190,7 @@ static void snep_parse_handover_record(int client_fd, uint8_t *ndef, uint32_t nfc_data_length) { GList *records; - struct near_ndef_message *msg; + struct near_ndef_message *msg = NULL; if (ndef == NULL) return; @@ -203,27 +203,22 @@ static void snep_parse_handover_record(int client_fd, uint8_t *ndef, *(ndef + 9) = 'c'; /* Parse the incoming frame */ - records = near_ndef_parse_msg(ndef, nfc_data_length); - - /* - * If we received a Hr, we must build a Hs and send it. - * If the frame is a Hs, nothing more to do (SNEP REPLY is SUCCESS and - * the pairing is done in near_ndef_parse_msg() - * */ - if (strncmp((char *)(ndef + 3), "Hr", 2) == 0) { - msg = near_ndef_prepare_handover_record("Hs", records->data, - NEAR_CARRIER_BLUETOOTH); - - near_info("Send SNEP / Hs frame"); - snep_response_with_info(client_fd, SNEP_RESP_SUCCESS, - msg->data, msg->length); - g_free(msg->data); - g_free(msg); - } + records = near_ndef_parse_msg(ndef, nfc_data_length, &msg); + if (records == NULL) + return; near_ndef_records_free(records); - return; + if (!msg) + return; + + near_info("Send SNEP / Hs frame"); + + snep_response_with_info(client_fd, SNEP_RESP_SUCCESS, msg->data, + msg->length); + + g_free(msg->data); + g_free(msg); } static near_bool_t snep_read_ndef(int client_fd, @@ -295,7 +290,7 @@ static near_bool_t snep_read_ndef(int client_fd, goto out; records = near_ndef_parse_msg(snep_data->nfc_data, - snep_data->nfc_data_length); + snep_data->nfc_data_length, NULL); near_device_add_records(device, records, snep_data->cb, 0); } diff --git a/src/ndef.c b/src/ndef.c index 00c944b..aeb4273 100644 --- a/src/ndef.c +++ b/src/ndef.c @@ -1358,9 +1358,9 @@ fail: } static struct near_ndef_mime_payload * -parse_mime_type(struct near_ndef_record *record, - uint8_t *ndef_data, size_t ndef_length, size_t offset, - uint32_t payload_length, near_bool_t action) +parse_mime_type(struct near_ndef_record *record, uint8_t *ndef_data, + size_t ndef_length, size_t offset, uint32_t payload_length, + near_bool_t action, struct near_ndef_message **reply) { struct near_ndef_mime_payload *mime = NULL; int err = 0; @@ -1392,10 +1392,28 @@ parse_mime_type(struct near_ndef_record *record, memcpy(data.data, ndef_data + offset, data.size); } - if (data.size > 0 && __near_bluez_is_legacy()) + if (data.size == 0) + goto done; + + if (__near_bluez_is_legacy()) { err = __near_bluetooth_parse_oob_record(&data, &mime->handover.properties, action); + if (err == 0 && reply != NULL) + *reply = near_ndef_prepare_handover_record("Hs", + record, NEAR_CARRIER_BLUETOOTH, NULL); + } else { + if (action) + err = __near_agent_handover_push_data(&data); + else if (reply != NULL) + *reply = near_ndef_prepare_handover_record("Hs", + record, NEAR_CARRIER_BLUETOOTH, &data); + } + /* check if requested reply message was created successfully */ + if (reply != NULL && *reply == NULL) + err = -ENOMEM; + +done: if (err < 0) { DBG("Parsing mime error %d", err); g_free(mime->type); @@ -1764,15 +1782,14 @@ static uint16_t near_get_carrier_properties(struct near_ndef_record *record, */ struct near_ndef_message *near_ndef_prepare_handover_record(char* type_name, struct near_ndef_record *record, - uint8_t carriers) - + uint8_t carriers, + struct bt_data *remote) { - struct bt_data *data = NULL; + struct bt_data *local = NULL; struct near_ndef_message *hs_msg = NULL; 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; near_bool_t mb, me; @@ -1814,20 +1831,22 @@ struct near_ndef_message *near_ndef_prepare_handover_record(char* type_name, goto fail; if (carriers & NEAR_CARRIER_BLUETOOTH) { - if (__near_bluez_is_legacy() == FALSE) - goto fail; - - /* Retrieve the bluetooth settings */ - props = near_get_carrier_properties(record, + if (__near_bluez_is_legacy()) { + /* Retrieve the bluetooth settings */ + uint16_t props = near_get_carrier_properties(record, NEAR_CARRIER_BLUETOOTH); - data = __near_bluetooth_local_get_properties(props); - if (data == NULL) { + local = __near_bluetooth_local_get_properties(props); + } else { + local = __near_agent_handover_request_data(remote); + } + + if (local == NULL) { near_error("Getting Bluetooth OOB data failed"); goto fail; } - bt_msg = near_ndef_prepare_bt_message(data->data, data->size, + bt_msg = near_ndef_prepare_bt_message(local->data, local->size, cdr, 1); if (bt_msg == NULL) goto fail; @@ -1924,7 +1943,7 @@ struct near_ndef_message *near_ndef_prepare_handover_record(char* type_name, g_free(bt_msg); } - g_free(data); + g_free(local); DBG("Hs NDEF done"); @@ -1953,7 +1972,7 @@ fail: g_free(bt_msg); } - g_free(data); + g_free(local); return NULL; } @@ -2016,7 +2035,7 @@ fail: */ static struct near_ndef_ho_payload *parse_ho_payload(enum record_type rec_type, uint8_t *payload, uint32_t ho_length, size_t frame_length, - uint8_t ho_mb, uint8_t ho_me) + uint8_t ho_mb, uint8_t ho_me, struct near_ndef_message **reply) { struct near_ndef_ho_payload *ho_payload = NULL; struct near_ndef_ac_payload *ac = NULL; @@ -2111,9 +2130,16 @@ static struct near_ndef_ho_payload *parse_ho_payload(enum record_type rec_type, else bt_pair = FALSE; + /* HO payload for reply creation */ + trec->ho = ho_payload; + mime = parse_mime_type(trec, payload, frame_length, - offset, trec->header->payload_len, - bt_pair); + offset, + trec->header->payload_len, + bt_pair, reply); + + trec->ho = NULL; + if (mime == NULL) goto fail; @@ -2212,13 +2238,16 @@ int __near_ndef_record_register(struct near_ndef_record *record, char *path) /** * @brief Parse message represented by bytes block +GList *near_ndef_parse(uint8_t *ndef_data, size_t ndef_length, + struct near_ndef_message **reply) * * @param[in] ndef_data pointer on data representing ndef message * @param[in] ndef_length size of ndef_data * @param[out] records list, contains all the records * from parsed message */ -GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length) +GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length, + struct near_ndef_message **reply) { GList *records; uint8_t p_mb = 0, p_me = 0, *record_start; @@ -2280,7 +2309,8 @@ GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length) ndef_data + offset, record->header->payload_len, ndef_length - offset, - record->header->mb, record->header->me); + record->header->mb, record->header->me, + reply); if (record->ho == NULL) goto fail; @@ -2320,7 +2350,7 @@ GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length) record->mime = parse_mime_type(record, ndef_data, ndef_length, offset, record->header->payload_len, - TRUE); + TRUE, reply); if (record->mime == NULL) @@ -2912,7 +2942,7 @@ static struct near_ndef_message *build_ho_record(DBusMessage *msg) goto fail; record->ho->ac_payloads[0] = build_ho_local_ac_record(); - return near_ndef_prepare_handover_record("Hr", record, carrier); + return near_ndef_prepare_handover_record("Hr", record, carrier, NULL); fail: free_ho_payload(record->ho); diff --git a/src/near.h b/src/near.h index 0d3d708..0e7a3a6 100644 --- a/src/near.h +++ b/src/near.h @@ -184,7 +184,7 @@ struct bt_data { uint8_t data[UINT8_MAX]; }; -gboolean __near_bluez_is_legacy(void); +near_bool_t __near_bluez_is_legacy(void); int __near_bluetooth_init(void); void __near_bluetooth_cleanup(void); diff --git a/src/tlv.c b/src/tlv.c index d16ddb0..21044d9 100644 --- a/src/tlv.c +++ b/src/tlv.c @@ -93,7 +93,7 @@ GList *near_tlv_parse(uint8_t *tlv, size_t tlv_length) DBG("NDEF found %d bytes long", near_tlv_length(tlv)); records = near_ndef_parse_msg(near_tlv_data(tlv), - near_tlv_length(tlv)); + near_tlv_length(tlv), NULL); break; case TLV_END: -- 2.7.4