3 * neard - Near Field Communication manager
5 * Copyright (C) 2012 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <sys/socket.h>
31 #include <linux/socket.h>
32 #include <linux/nfc.h>
34 #include <near/plugin.h>
36 #include <near/types.h>
37 #include <near/adapter.h>
38 #include <near/device.h>
39 #include <near/ndef.h>
44 #define SNEP_VERSION 0x10
47 #define SNEP_REQ_CONTINUE 0x00
48 #define SNEP_REQ_GET 0x01
49 #define SNEP_REQ_PUT 0x02
50 #define SNEP_REQ_REJECT 0x7f
53 #define SNEP_RESP_CONTINUE 0x80
54 #define SNEP_RESP_SUCCESS 0x81
55 #define SNEP_RESP_NOT_FOUND 0xc0
56 #define SNEP_RESP_EXCESS 0xc1
57 #define SNEP_RESP_BAD_REQ 0xc2
58 #define SNEP_RESP_NOT_IMPL 0xe0
59 #define SNEP_RESP_VERSION 0xe1
60 #define SNEP_RESP_REJECT 0xff
62 #define SNEP_REQ_PUT_HEADER_LENGTH 6
63 #define SNEP_REQ_GET_HEADER_LENGTH 10
64 /* TODO: Right now it is dummy, need to get correct value
65 * from lower layers */
66 #define SNEP_REQ_MAX_FRAGMENT_LENGTH 128
68 struct p2p_snep_data {
71 uint32_t nfc_data_length;
72 uint32_t nfc_data_current_length;
73 uint8_t *nfc_data_ptr;
76 gboolean respond_continue;
80 struct snep_fragment {
85 struct p2p_snep_put_req_data {
95 struct p2p_snep_req_frame {
100 } __attribute__((packed));
102 struct p2p_snep_resp_frame {
107 } __attribute__((packed));
109 static GHashTable *snep_client_hash = NULL;
111 static void free_snep_client(gpointer data)
113 struct p2p_snep_data *snep_data = data;
115 g_free(snep_data->nfc_data);
119 static void snep_response_noinfo(int client_fd, uint8_t response)
121 struct p2p_snep_resp_frame resp;
123 DBG("Response 0x%x", response);
125 resp.version = SNEP_VERSION;
126 resp.response = response;
129 send(client_fd, &resp, sizeof(resp), 0);
132 static void snep_close(int client_fd, int err)
134 struct p2p_snep_data *snep_data;
138 snep_data = g_hash_table_lookup(snep_client_hash,
139 GINT_TO_POINTER(client_fd));
140 if (snep_data == NULL)
143 snep_data->cb(snep_data->adapter_idx, snep_data->target_idx, err);
145 g_hash_table_remove(snep_client_hash, GINT_TO_POINTER(client_fd));
148 static void snep_response_with_info(int client_fd, uint8_t response,
149 uint8_t *data, int length)
151 struct p2p_snep_resp_frame *resp;
153 DBG("Response with info 0x%x (len:%d)", response, length);
155 resp = g_try_malloc0(sizeof(struct p2p_snep_resp_frame) + length);
157 DBG("Memory allocation error");
162 resp->version = SNEP_VERSION;
163 resp->response = response;
164 resp->length = GUINT32_TO_BE(length);
165 memcpy(resp->info, data, length);
167 send(client_fd, resp, sizeof(struct p2p_snep_resp_frame) + length, 0);
173 * snep_parse_handover_record
175 * The hr frame should be here BUT:
176 * The first 4 bytes are the Max Allowed Length
178 * - Because of an Android's BUGs:
179 * - the Hr frame is not correct; a Hr record
180 * is embedded in a ... Hr record !!! The author
181 * used 'Hr' instead of 'cr'
182 * - The OOB block is badly written:
183 * - the payload ID should be the same in the 'ac' record
184 * and the OOB record.
185 * - The OOB data length bytes must be swapped (Big endian to Little E.)
187 * The hack fixes the first issue (bluetooth.c fixes the second) !
189 static void snep_parse_handover_record(int client_fd, uint8_t *ndef,
190 uint32_t nfc_data_length)
193 struct near_ndef_message *msg;
199 * Bugfix Android: Fix 'cr' instead of 'Hr'
200 * Bug is in Google:HandoverManager.java:645
202 if (strncmp((char *)(ndef + 9), "Hr", 2) == 0)
205 /* Parse the incoming frame */
206 records = near_ndef_parse(ndef, nfc_data_length);
209 * If we received a Hr, we must build a Hs and send it.
210 * If the frame is a Hs, nothing more to do (SNEP REPLY is SUCCESS and
211 * the pairing is done in near_ndef_parse()
213 if (strncmp((char *)(ndef + 3), "Hr", 2) == 0) {
214 msg = near_ndef_prepare_handover_record("Hs", records->data,
215 NEAR_CARRIER_BLUETOOTH);
217 near_info("Send SNEP / Hs frame");
218 snep_response_with_info(client_fd, SNEP_RESP_SUCCESS,
219 msg->data, msg->length);
224 near_ndef_records_free(records);
229 static near_bool_t snep_read_ndef(int client_fd,
230 struct p2p_snep_data *snep_data)
232 int bytes_recv, remaining_bytes;
233 struct near_device *device;
238 remaining_bytes = snep_data->nfc_data_length -
239 snep_data->nfc_data_current_length;
241 DBG("Remaining bytes %d", remaining_bytes);
243 bytes_recv = recv(client_fd, snep_data->nfc_data_ptr, remaining_bytes,
245 if (bytes_recv < 0) {
246 near_error("%d %s", bytes_recv, strerror(errno));
248 /* Some more data should show up */
255 DBG("Received %d bytes", bytes_recv);
257 snep_data->nfc_data_current_length += bytes_recv;
258 snep_data->nfc_data_ptr += bytes_recv;
260 if (snep_data->nfc_data_length != snep_data->nfc_data_current_length) {
261 if (snep_data->respond_continue == FALSE) {
263 snep_data->respond_continue = TRUE;
264 snep_response_noinfo(client_fd, SNEP_RESP_CONTINUE);
270 if (snep_data->request_code == SNEP_REQ_GET) {
272 * This goes against the SNEP specification:
273 * "The default server SHALL NOT accept Get requests." but
274 * the first Android Handover implementation (Jelly Bean)
275 * does Handover through SNEP via GET frames...Since Android
276 * seems popular these days, we'd better support that spec
279 * Parse the Hr and send a Hs
280 * Max allowed size in the first 4 bytes
282 snep_parse_handover_record(client_fd, snep_data->nfc_data + 4,
283 snep_data->nfc_data_length - 4);
285 snep_response_noinfo(client_fd, SNEP_RESP_SUCCESS);
286 if (near_device_add_data(snep_data->adapter_idx,
287 snep_data->target_idx,
289 snep_data->nfc_data_length) < 0)
292 device = near_device_get_device(snep_data->adapter_idx,
293 snep_data->target_idx);
297 records = near_ndef_parse(snep_data->nfc_data,
298 snep_data->nfc_data_length);
299 near_device_add_records(device, records, snep_data->cb, 0);
303 g_hash_table_remove(snep_client_hash, GINT_TO_POINTER(client_fd));
308 static near_bool_t snep_read(int client_fd,
309 uint32_t adapter_idx, uint32_t target_idx,
312 struct p2p_snep_data *snep_data;
313 struct p2p_snep_req_frame frame;
315 uint32_t ndef_length;
319 snep_data = g_hash_table_lookup(snep_client_hash,
320 GINT_TO_POINTER(client_fd));
323 * We already got something from this client, we should try
324 * to continue reading.
326 if (snep_data != NULL)
327 return snep_read_ndef(client_fd, snep_data);
329 /* TODO Try with PEEK */
330 bytes_recv = recv(client_fd, &frame, sizeof(frame), 0);
331 if (bytes_recv < 0) {
332 near_error("Could not read SNEP frame %d", bytes_recv);
336 ndef_length = GINT_FROM_BE(frame.length);
338 DBG("Allocating SNEP data %d", ndef_length);
340 snep_data = g_try_malloc0(sizeof(struct p2p_snep_data));
341 if (snep_data == NULL)
344 snep_data->nfc_data = g_try_malloc0(ndef_length + TLV_SIZE);
345 if (snep_data->nfc_data == NULL) {
350 snep_data->nfc_data_length = ndef_length;
351 snep_data->nfc_data_ptr = snep_data->nfc_data;
352 snep_data->adapter_idx = adapter_idx;
353 snep_data->target_idx = target_idx;
354 snep_data->respond_continue = FALSE;
357 g_hash_table_insert(snep_client_hash,
358 GINT_TO_POINTER(client_fd), snep_data);
360 snep_data->request_code = frame.request;
362 DBG("Request 0x%x", frame.request);
364 switch (frame.request) {
365 case SNEP_REQ_CONTINUE:
366 near_error("Unsupported SNEP request code");
367 snep_response_noinfo(client_fd, SNEP_RESP_NOT_IMPL);
371 return snep_read_ndef(client_fd, snep_data);
377 static void free_snep_fragment(gpointer data)
379 struct snep_fragment *fragment = data;
381 if (fragment != NULL)
382 g_free(fragment->data);
388 static void free_snep_push_data(gpointer userdata, int status)
390 struct p2p_snep_put_req_data *data;
394 data = (struct p2p_snep_put_req_data *) userdata;
399 data->cb(data->adapter_idx, data->target_idx, status);
402 g_source_remove(data->watch);
404 g_slist_free_full(data->fragments, free_snep_fragment);
408 static int snep_send_fragment(struct p2p_snep_put_req_data *req)
410 struct snep_fragment *fragment;
415 if (req == NULL || req->fragments == NULL ||
416 g_slist_length(req->fragments) == 0)
419 fragment = req->fragments->data;
421 err = send(req->fd, fragment->data, fragment->len, 0);
423 req->fragments = g_slist_remove(req->fragments, fragment);
424 g_free(fragment->data);
430 static int snep_push_response(struct p2p_snep_put_req_data *req)
432 struct p2p_snep_resp_frame frame;
439 bytes_recv = recv(req->fd, &frame, sizeof(frame), 0);
440 if (bytes_recv < 0) {
441 near_error("Could not read SNEP frame %d", bytes_recv);
445 /* Check frame length */
446 frame.length = g_ntohl(frame.length);
448 DBG("Response 0x%x", frame.response);
450 switch (frame.response) {
451 case SNEP_RESP_CONTINUE:
452 while (g_slist_length(req->fragments) != 0) {
453 err = snep_send_fragment(req);
458 return frame.response;
460 case SNEP_RESP_SUCCESS:
461 if (frame.length == 0)
464 /* Get the incoming data */
465 ndef_len = frame.length;
466 ndef = g_try_malloc0(ndef_len);
470 bytes_recv = recv(req->fd, ndef, ndef_len, 0);
471 if (bytes_recv < 0) {
472 near_error("Could not read SNEP frame %d", bytes_recv);
476 /* Not enough bytes */
480 if (strncmp((char *)(ndef + 3), "Hs", 2) == 0)
481 snep_parse_handover_record(req->fd, ndef, ndef_len);
491 static gboolean snep_push_event(GIOChannel *channel,
492 GIOCondition condition, gpointer data)
496 DBG("condition 0x%x", condition);
498 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
500 near_error("Error with SNEP channel");
502 free_snep_push_data(data, -1);
507 err = snep_push_response(data);
509 free_snep_push_data(data, err);
517 static int snep_push_prepare_fragments(struct p2p_snep_put_req_data *req,
518 struct near_ndef_message *ndef)
520 struct snep_fragment *fragment;
521 uint32_t max_fragment_len;
525 max_fragment_len = SNEP_REQ_MAX_FRAGMENT_LENGTH;
527 while (ndef->offset < ndef->length) {
529 fragment = g_try_malloc0(sizeof(struct snep_fragment));
530 if (fragment == NULL)
533 if (max_fragment_len <= (ndef->length - ndef->offset))
534 fragment->len = max_fragment_len;
536 fragment->len = ndef->length - ndef->offset;
538 fragment->data = g_try_malloc0(fragment->len);
539 if (fragment->data == NULL) {
544 memcpy(fragment->data, ndef->data + ndef->offset,
546 ndef->offset += fragment->len;
547 req->fragments = g_slist_append(req->fragments, fragment);
553 static int snep_push(int fd, uint32_t adapter_idx, uint32_t target_idx,
554 struct near_ndef_message *ndef,
555 near_device_io_cb cb)
557 struct p2p_snep_put_req_data *req;
558 struct p2p_snep_req_frame header;
559 struct snep_fragment *fragment;
560 uint32_t max_fragment_len;
562 gboolean fragmenting;
564 int snep_req_header_length, snep_additional_length;
568 req = g_try_malloc0(sizeof(struct p2p_snep_put_req_data));
574 channel = g_io_channel_unix_new(fd);
575 g_io_channel_set_close_on_unref(channel, TRUE);
578 req->adapter_idx = adapter_idx;
579 req->target_idx = target_idx;
582 req->watch = g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_NVAL |
583 G_IO_ERR, snep_push_event,
586 max_fragment_len = SNEP_REQ_MAX_FRAGMENT_LENGTH;
587 header.version = SNEP_VERSION;
589 /* Check if Hr or Hs for Handover over SNEP */
590 if (*(char *)(ndef->data + 3) == 'H') {
591 header.request = SNEP_REQ_GET; /* Get for android */
592 snep_req_header_length = SNEP_REQ_GET_HEADER_LENGTH;
593 snep_additional_length = 4; /* 4 Acceptable Length */
595 header.request = SNEP_REQ_PUT;
596 snep_req_header_length = SNEP_REQ_PUT_HEADER_LENGTH;
597 snep_additional_length = 0;
600 header.length = GUINT32_TO_BE(ndef->length + snep_additional_length);
602 fragment = g_try_malloc0(sizeof(struct snep_fragment));
603 if (fragment == NULL) {
608 if (max_fragment_len >= (ndef->length + snep_req_header_length)) {
609 fragment->len = ndef->length + snep_req_header_length;
612 fragment->len = max_fragment_len;
616 fragment->data = g_try_malloc0(fragment->len);
617 if (fragment->data == NULL) {
623 /* Header to data - common header */
624 memcpy(fragment->data, (uint8_t *)&header, SNEP_REQ_PUT_HEADER_LENGTH);
626 /* if GET, we add the Acceptable length */
627 if (header.request == SNEP_REQ_GET)
628 *(uint32_t *)(fragment->data + SNEP_REQ_PUT_HEADER_LENGTH) =
629 GUINT32_TO_BE(snep_req_header_length);
631 if (fragmenting == TRUE) {
632 memcpy(fragment->data + snep_req_header_length, ndef->data,
633 max_fragment_len - snep_req_header_length);
634 ndef->offset = max_fragment_len - snep_req_header_length;
636 err = snep_push_prepare_fragments(req, ndef);
638 g_free(fragment->data);
644 memcpy(fragment->data + snep_req_header_length,
645 ndef->data, ndef->length);
648 err = send(fd, fragment->data, fragment->len, 0);
650 near_error("Sending failed %d", err);
651 g_free(fragment->data);
657 g_free(fragment->data);
663 free_snep_push_data(req, err);
668 struct near_p2p_driver snep_driver = {
670 .service_name = NEAR_DEVICE_SN_SNEP,
671 .fallback_service_name = NEAR_DEVICE_SN_NPP,
679 snep_client_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
680 NULL, free_snep_client);
682 return near_p2p_register(&snep_driver);
687 near_p2p_unregister(&snep_driver);
689 g_hash_table_destroy(snep_client_hash);
690 snep_client_hash = NULL;