xref: /OK3568_Linux_fs/external/rk_pcba_test/echo_discovery.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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