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>
33 #include <near/nfc_copy.h>
34 #include <near/plugin.h>
35 #include <near/types.h>
36 #include <near/adapter.h>
37 #include <near/device.h>
38 #include <near/ndef.h>
40 #include <near/snep.h>
44 struct snep_fragment {
49 struct p2p_snep_put_req_data {
59 struct p2p_snep_req_frame {
64 } __attribute__((packed));
66 struct p2p_snep_resp_frame {
71 } __attribute__((packed));
73 static GHashTable *snep_client_hash;
75 /* Callback: free snep data */
76 static void free_snep_core_client(gpointer data)
78 struct p2p_snep_data *snep_data = data;
82 g_free(snep_data->nfc_data);
86 /* Send a short response code */
87 void near_snep_core_response_noinfo(int client_fd, uint8_t response)
89 struct p2p_snep_resp_frame resp;
91 DBG("Response 0x%x", response);
93 resp.version = NEAR_SNEP_VERSION;
94 resp.response = response;
97 send(client_fd, &resp, sizeof(resp), 0);
101 * near_snep_core_parse_handover_record
103 * The hr frame should be here BUT:
104 * The first 4 bytes are the Max Allowed Length
106 * - Because of an Android's BUGs:
107 * - the Hr frame is not correct; a Hr record
108 * is embedded in a ... Hr record !!! The author
109 * used 'Hr' instead of 'cr'
110 * - The OOB block is badly written:
111 * - the payload ID should be the same in the 'ac' record
112 * and the OOB record.
113 * - The OOB data length bytes must be swapped (Big endian to Little E.)
115 * The hack fixes the first issue (bluetooth.c fixes the second) !
117 void near_snep_core_parse_handover_record(int client_fd, uint8_t *ndef,
118 uint32_t nfc_data_length)
121 struct near_ndef_message *msg = NULL;
127 * Bugfix Android: Fix 'cr' instead of 'Hr'
128 * Bug is in Google:HandoverManager.java:645
130 if (nfc_data_length > 9 && strncmp((char *)(ndef + 9), "Hr", 2) == 0) {
131 DBG("Android 4.1.1 found !!!");
135 /* Parse the incoming frame */
136 records = near_ndef_parse_msg(ndef, nfc_data_length, &msg);
140 near_ndef_records_free(records);
145 near_info("Send SNEP / Hs frame");
147 near_snep_core_response_with_info(client_fd, NEAR_SNEP_RESP_SUCCESS,
148 msg->data, msg->length);
155 * This code will read the ndef message.
157 * ==0 if not more bytes
158 * >0 if there's still some data to read
160 static int snep_core_read_ndef(int client_fd,
161 struct p2p_snep_data *snep_data)
163 int bytes_recv, remaining_bytes;
167 remaining_bytes = snep_data->nfc_data_length -
168 snep_data->nfc_data_current_length;
170 bytes_recv = recv(client_fd, snep_data->nfc_data_ptr, remaining_bytes,
172 if (bytes_recv < 0) {
173 near_error("%d %s", bytes_recv, strerror(errno));
175 /* Some more data should show up */
177 return EAGAIN; /* Positive !!*/
182 snep_data->nfc_data_current_length += bytes_recv;
183 snep_data->nfc_data_ptr += bytes_recv;
185 /* Is the read complete ? */
186 if (snep_data->nfc_data_length == snep_data->nfc_data_current_length)
189 if (!snep_data->respond_continue) {
190 snep_data->respond_continue = TRUE;
191 near_snep_core_response_noinfo(client_fd, NEAR_SNEP_RESP_CONTINUE);
197 g_hash_table_remove(snep_client_hash, GINT_TO_POINTER(client_fd));
199 return -errno; /* Negative on error */
202 static void free_snep_core_fragment(gpointer data)
204 struct snep_fragment *fragment = data;
207 g_free(fragment->data);
213 static void free_snep_core_push_data(gpointer userdata, int status)
215 struct p2p_snep_put_req_data *data;
222 data = (struct p2p_snep_put_req_data *) userdata;
227 data->cb(data->adapter_idx, data->target_idx, status);
230 g_source_remove(data->watch);
232 g_slist_free_full(data->fragments, free_snep_core_fragment);
236 static int snep_core_send_fragment(struct p2p_snep_put_req_data *req)
238 struct snep_fragment *fragment;
243 if (!req || !req->fragments ||
244 g_slist_length(req->fragments) == 0)
247 fragment = req->fragments->data;
249 err = send(req->fd, fragment->data, fragment->len, 0);
251 req->fragments = g_slist_remove(req->fragments, fragment);
252 g_free(fragment->data);
258 static int snep_core_push_response(struct p2p_snep_put_req_data *req)
260 struct p2p_snep_resp_frame frame;
267 bytes_recv = recv(req->fd, &frame, sizeof(frame), 0);
268 if (bytes_recv < 0) {
269 near_error("Read SNEP frame error %d %s", bytes_recv,
274 /* Check frame length */
275 frame.length = g_ntohl(frame.length);
277 DBG("Response 0x%x %p", frame.response, &frame);
278 switch (frame.response) {
279 case NEAR_SNEP_RESP_CONTINUE:
280 while (g_slist_length(req->fragments) != 0) {
281 err = snep_core_send_fragment(req);
286 return frame.response;
288 case NEAR_SNEP_RESP_SUCCESS:
289 if (frame.length == 0)
292 /* Get the incoming data */
293 ndef_len = frame.length;
294 ndef = g_try_malloc0(ndef_len);
298 bytes_recv = recv(req->fd, ndef, ndef_len, 0);
299 if (bytes_recv < 0) {
300 near_error("Read SNEP frame error: %d %s", bytes_recv,
305 /* Not enough bytes */
309 if (strncmp((char *)(ndef + 3), "Hs", 2) == 0)
310 near_snep_core_parse_handover_record(req->fd, ndef,
321 static gboolean snep_core_push_event(GIOChannel *channel,
322 GIOCondition condition, gpointer data)
326 DBG("push_event condition 0x%x", condition);
328 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
330 near_error("Error with SNEP channel");
332 free_snep_core_push_data(data, -1);
337 err = snep_core_push_response(data);
339 free_snep_core_push_data(data, err);
347 static int snep_core_push_prepare_fragments(struct p2p_snep_put_req_data *req,
348 struct near_ndef_message *ndef)
350 struct snep_fragment *fragment;
351 uint32_t max_fragment_len;
355 max_fragment_len = NEAR_SNEP_REQ_MAX_FRAGMENT_LENGTH;
357 while (ndef->offset < ndef->length) {
359 fragment = g_try_malloc0(sizeof(struct snep_fragment));
363 if (max_fragment_len <= (ndef->length - ndef->offset))
364 fragment->len = max_fragment_len;
366 fragment->len = ndef->length - ndef->offset;
368 fragment->data = g_try_malloc0(fragment->len);
369 if (!fragment->data) {
374 memcpy(fragment->data, ndef->data + ndef->offset,
376 ndef->offset += fragment->len;
377 req->fragments = g_slist_append(req->fragments, fragment);
383 static bool snep_core_process_request(int client_fd,
384 struct p2p_snep_data *snep_data,
385 near_server_io req_get,
386 near_server_io req_put)
391 DBG("request %d", snep_data->request);
393 /* Now, we process the request code */
394 switch (snep_data->request) {
395 case NEAR_SNEP_REQ_PUT:
396 DBG("NEAR_SNEP_REQ_PUT");
398 ret = (*req_put)(client_fd, snep_data);
400 near_snep_core_response_noinfo(client_fd,
401 NEAR_SNEP_RESP_NOT_IMPL);
406 g_hash_table_remove(snep_client_hash,
407 GINT_TO_POINTER(client_fd));
410 case NEAR_SNEP_REQ_GET:
411 DBG("NEAR_SNEP_REQ_GET");
413 ret = (*req_get)(client_fd, snep_data);
415 near_snep_core_response_noinfo(client_fd,
416 NEAR_SNEP_RESP_NOT_IMPL);
420 /* If there's some fragments, don't delete before the CONT */
421 if (!snep_data->req) {
424 g_hash_table_remove(snep_client_hash,
425 GINT_TO_POINTER(client_fd));
429 case NEAR_SNEP_REQ_REJECT:
430 DBG("NEAR_SNEP_REQ_REJECT");
431 if (!snep_data->req->fragments) {
432 near_error("error: NEAR_SNEP_REQ_REJECT but no fragment");
439 g_slist_free_full(snep_data->req->fragments,
440 free_snep_core_fragment);
441 g_slist_free(snep_data->req->fragments);
443 g_hash_table_remove(snep_client_hash,
444 GINT_TO_POINTER(client_fd));
448 case NEAR_SNEP_REQ_CONTINUE:
450 * NEAR_SNEP_REQ_CONTINUE indicates that we have to send the
451 * remaining fragments...
454 if (!snep_data->req) {
459 DBG("NEAR_SNEP_REQ_CONTINUE");
460 if (!snep_data->req->fragments) {
461 near_error("error: NEAR_SNEP_REQ_CONTINUE but no fragment");
466 /* Send fragments, one after the other (no ack expected) */
467 while (g_slist_length(snep_data->req->fragments) != 0) {
468 err = snep_core_send_fragment(snep_data->req);
478 /* No more fragment to send, clean memory */
479 g_slist_free_full(snep_data->req->fragments,
480 free_snep_core_fragment);
481 g_slist_free(snep_data->req->fragments);
483 g_hash_table_remove(snep_client_hash,
484 GINT_TO_POINTER(client_fd));
489 near_error("Unsupported SNEP request code");
498 * SNEP Core: read function
499 * This function handles SNEP REQUEST codes:
500 * GET, PUT and CONTINUE (REJECT is not handled).
502 * We read the first 6 bytes (the header) and check
503 * - the read size ( should be 6 )
504 * - the version (on MAJOR)
506 * Then, we check snep_data. If it exists, it means that we are in
507 * a fragment/continue situation (a 1st fragment was sent, and we
508 * expect a CONTINUE for the remaining bytes).
509 * If there's no existing snep_data, we create a new one and read the
510 * missing bytes (llcp removes fragmentation issues)
513 bool near_snep_core_read(int client_fd,
514 uint32_t adapter_idx, uint32_t target_idx,
516 near_server_io req_get,
517 near_server_io req_put,
520 struct p2p_snep_data *snep_data;
521 struct p2p_snep_req_frame frame;
523 uint32_t ndef_length;
527 /* Check previous/pending snep_data */
528 snep_data = g_hash_table_lookup(snep_client_hash,
529 GINT_TO_POINTER(client_fd));
532 * If snep data is already there, and there are more bytes to read
533 * we just go ahead and read more fragments from the client.
536 snep_data->nfc_data_length !=
537 snep_data->nfc_data_current_length) {
538 ret = snep_core_read_ndef(client_fd, snep_data);
542 goto process_request;
546 * We already got something from this client, we should try
547 * to continue reading.
549 /* TODO Try with PEEK */
550 bytes_recv = recv(client_fd, &frame, sizeof(frame), 0);
551 if (bytes_recv < 0) {
552 near_error("Read error SNEP %d %s", bytes_recv,
557 /* Check frame size */
558 if (bytes_recv != sizeof(frame)) {
559 near_error("Bad frame size: %d", bytes_recv);
563 /* If major is different, send UNSUPPORTED VERSION */
564 if (NEAR_SNEP_MAJOR(frame.version) != NEAR_SNEP_MAJOR(NEAR_SNEP_VERSION)) {
565 near_error("Unsupported version (%d)", frame.version);
566 near_snep_core_response_noinfo(client_fd, NEAR_SNEP_RESP_VERSION);
571 * This is a fragmentation SNEP operation since we have pending
572 * frames. But the ndef length and the current data length are
573 * identical. So this is a CONTINUE for a fragmented GET, and
574 * we should just process a CONTINUE frame and send the fragments
575 * back to the client. This will be done from snep_core_process_request().
578 snep_data->request = frame.request;
579 goto process_request;
582 /* This is a new request from the client */
583 snep_data = g_try_malloc0(sizeof(struct p2p_snep_data));
587 /* the whole frame length */
588 ndef_length = GINT_FROM_BE(frame.length);
590 snep_data->nfc_data = g_try_malloc0(ndef_length + TLV_SIZE);
591 if (!snep_data->nfc_data) {
596 /* fill the struct */
597 snep_data->nfc_data_length = ndef_length;
598 snep_data->nfc_data_ptr = snep_data->nfc_data;
599 snep_data->adapter_idx = adapter_idx;
600 snep_data->target_idx = target_idx;
601 snep_data->request = frame.request;
602 snep_data->respond_continue = FALSE;
605 /* Add to the client hash table */
606 g_hash_table_insert(snep_client_hash,
607 GINT_TO_POINTER(client_fd), snep_data);
609 if (ndef_length > 0) {
610 if ((frame.request == NEAR_SNEP_REQ_GET) ||
611 (frame.request == NEAR_SNEP_REQ_PUT)) {
612 /* We should read the missing bytes */
613 ret = snep_core_read_ndef(client_fd, snep_data);
620 return snep_core_process_request(client_fd, snep_data,
626 * send a response frame with some datas. If the frame is too long, we
627 * have to fragment the frame, using snep fragmentation protocol.
631 * > 0 if there's still some fragments
634 static int near_snep_core_response(int fd, struct p2p_snep_put_req_data *req,
635 uint8_t resp_code, struct near_ndef_message *ndef)
637 struct p2p_snep_req_frame header;
638 struct snep_fragment *fragment;
639 uint32_t max_fragment_len;
642 int snep_req_header_length, snep_additional_length;
644 DBG("resp: 0x%02X", resp_code);
646 max_fragment_len = NEAR_SNEP_REQ_MAX_FRAGMENT_LENGTH;
647 header.version = NEAR_SNEP_VERSION;
649 if (resp_code == NEAR_SNEP_REQ_GET) { /* Get for android */
650 snep_req_header_length = NEAR_SNEP_REQ_GET_HEADER_LENGTH;
651 snep_additional_length = 4; /* 4 Acceptable Length */
653 snep_req_header_length = NEAR_SNEP_REQ_PUT_HEADER_LENGTH;
654 snep_additional_length = 0;
657 header.length = GUINT32_TO_BE(ndef->length + snep_additional_length);
658 header.request = resp_code;
660 fragment = g_try_malloc0(sizeof(struct snep_fragment));
667 if (max_fragment_len >= (ndef->length + snep_req_header_length)) {
668 fragment->len = ndef->length + snep_req_header_length;
671 fragment->len = max_fragment_len;
675 fragment->data = g_try_malloc0(fragment->len);
676 if (!fragment->data) {
682 /* Header to data - common header */
683 memcpy(fragment->data, (uint8_t *)&header, NEAR_SNEP_REQ_PUT_HEADER_LENGTH);
685 /* if GET, we add the Acceptable length */
686 if (header.request == NEAR_SNEP_REQ_GET)
687 near_put_be32(snep_req_header_length,
688 fragment->data + NEAR_SNEP_REQ_PUT_HEADER_LENGTH);
691 memcpy(fragment->data + snep_req_header_length, ndef->data,
692 max_fragment_len - snep_req_header_length);
693 ndef->offset = max_fragment_len - snep_req_header_length;
695 err = snep_core_push_prepare_fragments(req, ndef);
697 g_free(fragment->data);
702 memcpy(fragment->data + snep_req_header_length,
703 ndef->data, ndef->length);
706 err = send(fd, fragment->data, fragment->len, 0);
708 near_error("Sending failed %d", err);
709 g_free(fragment->data);
714 g_free(fragment->data);
721 free_snep_core_push_data(req, err);
726 void near_snep_core_response_with_info(int client_fd, uint8_t response,
727 uint8_t *data, int length)
729 struct p2p_snep_data *snep_data;
730 struct p2p_snep_put_req_data *req;
731 struct near_ndef_message *ndef;
733 DBG("Response with info 0x%x (len:%d)", response, length);
738 /* get the snep data */
739 snep_data = g_hash_table_lookup(snep_client_hash,
740 GINT_TO_POINTER(client_fd));
742 DBG("snep_data not found");
746 /* Prepare the ndef struct */
747 ndef = g_try_malloc0(sizeof(struct near_ndef_message));
751 ndef->data = g_try_malloc0(length);
759 ndef->length = length;
761 memcpy(ndef->data, data, length);
765 /* Now prepare req struct */
766 req = g_try_malloc0(sizeof(struct p2p_snep_put_req_data));
770 /* Prepare the callback */
771 snep_data->req = req;
774 req->adapter_idx = snep_data->adapter_idx;
775 req->target_idx = snep_data->target_idx;
776 req->cb = snep_data->cb;
779 near_snep_core_response(client_fd, req, response, ndef);
782 /* If no fragment, free mem */
784 if (req->fragments == 0) {
786 snep_data->req = NULL;
795 /* SNEP Core: on P2P push */
796 int near_snep_core_push(int fd, uint32_t adapter_idx, uint32_t target_idx,
797 struct near_ndef_message *ndef,
798 near_device_io_cb cb,
801 struct p2p_snep_put_req_data *req;
808 req = g_try_malloc0(sizeof(struct p2p_snep_put_req_data));
814 channel = g_io_channel_unix_new(fd);
815 g_io_channel_set_close_on_unref(channel, TRUE);
818 req->adapter_idx = adapter_idx;
819 req->target_idx = target_idx;
822 req->watch = g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_NVAL |
823 G_IO_ERR, snep_core_push_event,
826 /* Check if Hr or Hs for Handover over SNEP */
827 if (*(char *)(ndef->data + 3) == 'H')
828 resp_code = NEAR_SNEP_REQ_GET; /* Get for android */
830 resp_code = NEAR_SNEP_REQ_PUT;
832 return near_snep_core_response(fd, req, resp_code, ndef);
835 free_snep_core_push_data(req, err);
841 /* SNEP core functions: close */
842 void near_snep_core_close(int client_fd, int err, gpointer data)
844 struct p2p_snep_data *snep_data;
848 snep_data = g_hash_table_lookup(snep_client_hash,
849 GINT_TO_POINTER(client_fd));
853 snep_data->cb(snep_data->adapter_idx, snep_data->target_idx, err);
855 g_hash_table_remove(snep_client_hash, GINT_TO_POINTER(client_fd));
858 int __near_snep_core_init(void)
860 snep_client_hash = g_hash_table_new_full(g_direct_hash,
861 g_direct_equal, NULL,
862 free_snep_core_client);
867 void __near_snep_core_cleanup(void)
869 g_hash_table_destroy(snep_client_hash);
870 snep_client_hash = NULL;