neard: Add nfctool native application
[platform/upstream/neard.git] / tools / snep-send.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <errno.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <sys/time.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9
10 #include <linux/socket.h>
11 #include <linux/nfc.h>
12
13 #include <near/types.h>
14 #include <near/ndef.h>
15
16 #include "../src/near.h"
17
18 /* HACK HACK */
19 #ifndef AF_NFC
20 #define AF_NFC 39
21 #endif
22
23 #define SNEP_VERSION     0x10
24
25 /* Request codes */
26 #define SNEP_REQ_CONTINUE 0x00
27 #define SNEP_REQ_GET      0x01
28 #define SNEP_REQ_PUT      0x02
29 #define SNEP_REQ_REJECT   0x7f
30
31 /* Response codes */
32 #define SNEP_RESP_CONTINUE  0x80
33 #define SNEP_RESP_SUCCESS   0x81
34 #define SNEP_RESP_NOT_FOUND 0xc0
35 #define SNEP_RESP_EXCESS    0xc1
36 #define SNEP_RESP_BAD_REQ   0xc2
37 #define SNEP_RESP_NOT_IMPL  0xe0
38 #define SNEP_RESP_VERSION   0xe1
39 #define SNEP_RESP_REJECT    0xff
40
41 struct p2p_snep_req_frame {
42         uint8_t version;
43         uint8_t request;
44         uint32_t length;
45         uint8_t ndef[];
46 } __attribute__((packed));
47
48 int main(int argc, char *argv[])
49 {
50         int fd, len;
51         struct near_ndef_message *ndef;
52         int adapter_idx, target_idx;
53         struct sockaddr_nfc_llcp addr;
54         struct p2p_snep_req_frame *frame;
55         size_t frame_length;
56
57         if (argc < 3) {
58                 printf("Usage: %s <adapter index> <target index>\n", argv[0]);
59                 exit(0);
60         }
61
62         adapter_idx = atoi(argv[1]);
63         target_idx = atoi(argv[2]);
64
65         fd =  socket(AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP);
66         if (fd < 0)
67                 return -1;
68
69         memset(&addr, 0, sizeof(struct sockaddr_nfc_llcp));
70         addr.sa_family = AF_NFC;
71         addr.dev_idx = adapter_idx;
72         addr.target_idx = target_idx;
73         addr.nfc_protocol = NFC_PROTO_NFC_DEP;
74         addr.service_name_len = strlen("urn:nfc:sn:snep");
75         strcpy(addr.service_name, "urn:nfc:sn:snep");
76
77         if (connect(fd, (struct sockaddr *)&addr,
78                     sizeof(struct sockaddr_nfc_llcp)) < 0) {
79                 near_error("Connect error %s\n", strerror(errno));
80                 return -1;
81         }
82         
83         ndef = near_ndef_prepare_text_record("UTF-8", "en", "Hello world");
84         if (ndef == NULL) {
85                 close(fd);
86                 near_error("Could not build NDEF");
87                 return -1;
88         }
89
90         frame_length = sizeof(struct p2p_snep_req_frame) + ndef->length;
91         frame = g_try_malloc0(frame_length);
92         if (frame == NULL) {
93                 close(fd);
94                 near_error("Could not allocate SNEP frame");
95                 return -1;
96         }
97
98         frame->version = SNEP_VERSION;
99         frame->request = SNEP_REQ_PUT;
100         frame->length = GUINT_TO_BE(ndef->length);
101
102         memcpy(frame->ndef, ndef->data, ndef->length);
103
104         len = send(fd, (uint8_t *)frame, frame_length, 0);
105         if (len < 0) {
106                 near_error("Could not send text NDEF %s\n", strerror(errno));
107
108                 g_free(frame);
109                 close(fd);
110
111                 return -1;
112         }
113
114         DBG("Sent %d bytes", len);
115
116         g_free(frame);
117         close(fd);
118
119         return 0;
120 }