1
2
3 /**
4 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
5 * author: WuQiang <xianlee.wu@rock-chips.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
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.
15 */
16
17 #include "stdio.h"
18 #include "stdlib.h"
19 #include "stdint.h"
20 #include "string.h"
21 #include "fcntl.h"
22 #include "sys/file.h"
23 #include "sys/ioctl.h"
24 #include "time.h"
25 #include "malloc.h"
26 #include "unistd.h"
27 #include "net/if.h"
28 #include "arpa/inet.h"
29 #include "sys/socket.h"
30
31 // vendor parameter
32 #define VENDOR_REQ_TAG 0x56524551
33 #define VENDOR_READ_IO _IOW('v', 0x01, unsigned int)
34 #define VENDOR_WRITE_IO _IOW('v', 0x02, unsigned int)
35
36 #define VENDOR_SN_ID 1
37 #define VENDOR_WIFI_MAC_ID 2
38 #define VENDOR_LAN_MAC_ID 3
39 #define VENDOR_BLUETOOTH_ID 4
40 #define VENDOR_STREAM_ID 14
41 #define VENDOR_PROTOCOL_ID 15
42
43 #define UDPPORT 18888
44 #define FWK_MSG_UID_LEN 20
45 #define FWK_MSG_CMD_LEN 128
46 #define FWK_MSG_IP_MAX_LEN 16
47 #define FWK_MSG_MAC_MAX_LEN 18
48
49 /* Storage parameter */
50 #define VENDOR_PARAMETER_ID 5
51 /* Change the id when flash firmware */
52 #define VENDOR_FW_UPDATE_ID 6
53
54 #define VENDOR_DATA_SIZE (3 * 1024) // 3k
55 #define VENDOR_DATA_PROTOCOL_SIZE (384) /* 64*6=384 byte */
56
57 #define VERDOR_DEVICE "/dev/vendor_storage"
58
59 typedef struct _RK_VERDOR_REQ {
60 uint32_t tag;
61 uint16_t id;
62 uint16_t len;
63 uint8_t data[VENDOR_DATA_SIZE];
64 } RK_VERDOR_REQ;
65
66 typedef struct _RK_VERDOR_PROTOCOL_REQ {
67 uint32_t tag;
68 uint16_t id;
69 uint16_t len;
70 uint8_t data[VENDOR_DATA_PROTOCOL_SIZE];
71 } RK_VERDOR_PROTOCOL_REQ;
72
73 static int rk_parameter_read_uid(int sys_fd, char *iotc_uid, int len);
74 static int parameter_read_protocol_uid(char iotc_uid[FWK_MSG_UID_LEN+1]);
75 static void broadcast_service();
76
main()77 int main()
78 {
79 printf("starting device discovery service!\n");
80
81 broadcast_service();
82
83 printf("discovery service crashed!\n");
84
85 return 0;
86 }
87
rk_parameter_read_uid(int sys_fd,char * iotc_uid,int len)88 int rk_parameter_read_uid(int sys_fd, char *iotc_uid, int len)
89 {
90 RK_VERDOR_PROTOCOL_REQ req;
91
92 if (sys_fd < 0) {
93 printf("_read_uid: error with sys_fd < 0\n");
94 return -1;
95 }
96 req.tag = VENDOR_REQ_TAG;
97 req.id = VENDOR_SN_ID;
98 req.len = 512;
99 if (ioctl(sys_fd, VENDOR_READ_IO, &req)) {
100 printf("_read_uid:VENDOR_SN_ID fail\n");
101 return -1;
102 }
103 /* rknand_print_hex_data("vendor read:", (uint32_t*)&req, req.len + 8); **/
104 if (req.len > len) {
105 printf("_read_uid:%d force to %d\n", req.len, len);
106 req.len = len;
107 }
108 memcpy(iotc_uid, req.data, req.len);
109
110 return req.len;
111 }
112
parameter_read_protocol_uid(char iotc_uid[FWK_MSG_UID_LEN+1])113 int parameter_read_protocol_uid(char iotc_uid[FWK_MSG_UID_LEN+1])
114 {
115 int sys_fd = -1;
116 int ret = -1;
117
118 printf("read_uid: enter...\n");
119 sys_fd = open(VERDOR_DEVICE, O_RDWR, 0);
120 if (sys_fd < 0) {
121 printf("read_uid: error with sys_fd < 0\n");
122 return ret;
123 }
124 memset(iotc_uid, 0, FWK_MSG_UID_LEN + 1);
125 ret = rk_parameter_read_uid(sys_fd, &iotc_uid[0], FWK_MSG_UID_LEN);
126 close(sys_fd);
127 printf("read_uid: success with uid=%s\n", iotc_uid);
128
129 return ret;
130 }
131
132
broadcast_service()133 static void broadcast_service()
134 {
135 socklen_t addr_len = 0;
136 struct sockaddr_in server_addr;
137 struct ifreq ifr;
138 char buf[64];
139 char local_addr[FWK_MSG_IP_MAX_LEN];
140 char local_mac[FWK_MSG_MAC_MAX_LEN];
141 char cmd_info[FWK_MSG_CMD_LEN];
142 char uid[FWK_MSG_UID_LEN + 1];
143 int broadcast_fd = -1;
144 int opt = -1;
145
146 broadcast_fd = socket(AF_INET, SOCK_DGRAM, 0);
147 if (broadcast_fd < 0) {
148 perror("broadcast_thread : socket");
149 goto stop_broadcast;
150 }
151 printf("broadcast_thread socketfd = %d\n", broadcast_fd);
152
153 strcpy(ifr.ifr_name, "rndis0");
154
155 memset(local_addr, 0, FWK_MSG_IP_MAX_LEN);
156 memset(local_mac, 0, FWK_MSG_MAC_MAX_LEN);
157
158 // get rndis ethernet interface ip address
159 while (ioctl(broadcast_fd, SIOCGIFADDR, &ifr) < 0) {
160 sleep(1);
161 }
162 snprintf(local_addr, FWK_MSG_IP_MAX_LEN, "%s",
163 inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
164
165 // get rndis ethernet interface mac address
166 while (ioctl(broadcast_fd, SIOCGIFHWADDR, &ifr) < 0) {
167 sleep(1);
168 }
169 snprintf(local_mac, FWK_MSG_MAC_MAX_LEN, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
170 (unsigned char)ifr.ifr_hwaddr.sa_data[0],
171 (unsigned char)ifr.ifr_hwaddr.sa_data[1],
172 (unsigned char)ifr.ifr_hwaddr.sa_data[2],
173 (unsigned char)ifr.ifr_hwaddr.sa_data[3],
174 (unsigned char)ifr.ifr_hwaddr.sa_data[4],
175 (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
176
177 printf("Discovery:got device net info!\n");
178
179 memset(&server_addr, 0, sizeof(server_addr));
180 server_addr.sin_family = AF_INET;
181 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
182 server_addr.sin_port = htons(UDPPORT);
183 addr_len = sizeof(server_addr);
184
185 if (setsockopt(broadcast_fd, SOL_SOCKET, SO_BROADCAST, (char *)&opt,
186 sizeof(opt)) < 0) {
187 perror("broadcast setsockopt SO_BROADCAST");
188 goto stop_broadcast;
189 }
190 if (setsockopt(broadcast_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
191 sizeof(opt)) < 0) {
192 perror("broadcast setsockopt SO_REUSEADDR");
193 goto stop_broadcast;
194 }
195
196 if (bind(broadcast_fd, (struct sockaddr *)&server_addr, addr_len) < 0) {
197 perror("broadcast bind");
198 goto stop_broadcast;
199 }
200
201 while (1) {
202 memset(buf, 0, sizeof(buf));
203 memset(uid, 0, sizeof(uid));
204 memset(cmd_info, 0, sizeof(cmd_info));
205
206
207 fprintf(stderr,"=========function is: %s line is : %d=============\n",__func__,__LINE__);
208 if (recvfrom(broadcast_fd, buf, 64, 0,
209 (struct sockaddr *)&server_addr, &addr_len) < 0) {
210 perror("broadcast recvfrom");
211 continue;
212 }
213
214 printf("broadcast: from: %s port: %d > %s\n",
215 inet_ntoa(server_addr.sin_addr),
216 ntohs(server_addr.sin_port), buf);
217
218 if (strcmp("CMD_DISCOVER", buf) == 0) {
219
220 if ((parameter_read_protocol_uid(uid)) < 0) {
221 printf("Discover:read uid failed!\n");
222 }
223
224 uid[FWK_MSG_UID_LEN] = '\0';
225
226 snprintf(cmd_info, FWK_MSG_CMD_LEN,
227 "{\"UID\":\"%s\","
228 "\"IP\":\"%s\","
229 "\"MAC\":\"%s\","
230 "\"DEVICENAME\":\"%s\"}",
231 uid,
232 local_addr,
233 local_mac,
234 "ECHO");
235
236 printf("sendto: %s port: %d > %s\n",
237 inet_ntoa(server_addr.sin_addr),
238 ntohs(server_addr.sin_port), cmd_info);
239 if (sendto(broadcast_fd, cmd_info, strlen(cmd_info),
240 0, (struct sockaddr *)&server_addr, addr_len) < 0) {
241 perror("broadcast_thread recvfrom");
242 goto stop_broadcast;
243 }
244 }
245 }
246
247 stop_broadcast:
248 printf("stop broadcast !\n");
249 if (broadcast_fd >= 0) {
250 shutdown(broadcast_fd, 2);
251 close(broadcast_fd);
252 broadcast_fd = -1;
253 }
254 }
255