|
|
/**
|
* Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
|
* author: WuQiang <xianlee.wu@rock-chips.com>
|
*
|
* This software is licensed under the terms of the GNU General Public
|
* License version 2, as published by the Free Software Foundation, and
|
* may be copied, distributed, and modified under those terms.
|
*
|
* This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
*/
|
|
#include "stdio.h"
|
#include "stdlib.h"
|
#include "stdint.h"
|
#include "string.h"
|
#include "fcntl.h"
|
#include "sys/file.h"
|
#include "sys/ioctl.h"
|
#include "time.h"
|
#include "malloc.h"
|
#include "unistd.h"
|
#include "net/if.h"
|
#include "arpa/inet.h"
|
#include "sys/socket.h"
|
|
// vendor parameter
|
#define VENDOR_REQ_TAG 0x56524551
|
#define VENDOR_READ_IO _IOW('v', 0x01, unsigned int)
|
#define VENDOR_WRITE_IO _IOW('v', 0x02, unsigned int)
|
|
#define VENDOR_SN_ID 1
|
#define VENDOR_WIFI_MAC_ID 2
|
#define VENDOR_LAN_MAC_ID 3
|
#define VENDOR_BLUETOOTH_ID 4
|
#define VENDOR_STREAM_ID 14
|
#define VENDOR_PROTOCOL_ID 15
|
|
#define UDPPORT 18888
|
#define FWK_MSG_UID_LEN 20
|
#define FWK_MSG_CMD_LEN 128
|
#define FWK_MSG_IP_MAX_LEN 16
|
#define FWK_MSG_MAC_MAX_LEN 18
|
|
/* Storage parameter */
|
#define VENDOR_PARAMETER_ID 5
|
/* Change the id when flash firmware */
|
#define VENDOR_FW_UPDATE_ID 6
|
|
#define VENDOR_DATA_SIZE (3 * 1024) // 3k
|
#define VENDOR_DATA_PROTOCOL_SIZE (384) /* 64*6=384 byte */
|
|
#define VERDOR_DEVICE "/dev/vendor_storage"
|
|
typedef struct _RK_VERDOR_REQ {
|
uint32_t tag;
|
uint16_t id;
|
uint16_t len;
|
uint8_t data[VENDOR_DATA_SIZE];
|
} RK_VERDOR_REQ;
|
|
typedef struct _RK_VERDOR_PROTOCOL_REQ {
|
uint32_t tag;
|
uint16_t id;
|
uint16_t len;
|
uint8_t data[VENDOR_DATA_PROTOCOL_SIZE];
|
} RK_VERDOR_PROTOCOL_REQ;
|
|
static int rk_parameter_read_uid(int sys_fd, char *iotc_uid, int len);
|
static int parameter_read_protocol_uid(char iotc_uid[FWK_MSG_UID_LEN+1]);
|
static void broadcast_service();
|
|
int main()
|
{
|
printf("starting device discovery service!\n");
|
|
broadcast_service();
|
|
printf("discovery service crashed!\n");
|
|
return 0;
|
}
|
|
int rk_parameter_read_uid(int sys_fd, char *iotc_uid, int len)
|
{
|
RK_VERDOR_PROTOCOL_REQ req;
|
|
if (sys_fd < 0) {
|
printf("_read_uid: error with sys_fd < 0\n");
|
return -1;
|
}
|
req.tag = VENDOR_REQ_TAG;
|
req.id = VENDOR_SN_ID;
|
req.len = 512;
|
if (ioctl(sys_fd, VENDOR_READ_IO, &req)) {
|
printf("_read_uid:VENDOR_SN_ID fail\n");
|
return -1;
|
}
|
/* rknand_print_hex_data("vendor read:", (uint32_t*)&req, req.len + 8); **/
|
if (req.len > len) {
|
printf("_read_uid:%d force to %d\n", req.len, len);
|
req.len = len;
|
}
|
memcpy(iotc_uid, req.data, req.len);
|
|
return req.len;
|
}
|
|
int parameter_read_protocol_uid(char iotc_uid[FWK_MSG_UID_LEN+1])
|
{
|
int sys_fd = -1;
|
int ret = -1;
|
|
printf("read_uid: enter...\n");
|
sys_fd = open(VERDOR_DEVICE, O_RDWR, 0);
|
if (sys_fd < 0) {
|
printf("read_uid: error with sys_fd < 0\n");
|
return ret;
|
}
|
memset(iotc_uid, 0, FWK_MSG_UID_LEN + 1);
|
ret = rk_parameter_read_uid(sys_fd, &iotc_uid[0], FWK_MSG_UID_LEN);
|
close(sys_fd);
|
printf("read_uid: success with uid=%s\n", iotc_uid);
|
|
return ret;
|
}
|
|
|
static void broadcast_service()
|
{
|
socklen_t addr_len = 0;
|
struct sockaddr_in server_addr;
|
struct ifreq ifr;
|
char buf[64];
|
char local_addr[FWK_MSG_IP_MAX_LEN];
|
char local_mac[FWK_MSG_MAC_MAX_LEN];
|
char cmd_info[FWK_MSG_CMD_LEN];
|
char uid[FWK_MSG_UID_LEN + 1];
|
int broadcast_fd = -1;
|
int opt = -1;
|
|
broadcast_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
if (broadcast_fd < 0) {
|
perror("broadcast_thread : socket");
|
goto stop_broadcast;
|
}
|
printf("broadcast_thread socketfd = %d\n", broadcast_fd);
|
|
strcpy(ifr.ifr_name, "rndis0");
|
|
memset(local_addr, 0, FWK_MSG_IP_MAX_LEN);
|
memset(local_mac, 0, FWK_MSG_MAC_MAX_LEN);
|
|
// get rndis ethernet interface ip address
|
while (ioctl(broadcast_fd, SIOCGIFADDR, &ifr) < 0) {
|
sleep(1);
|
}
|
snprintf(local_addr, FWK_MSG_IP_MAX_LEN, "%s",
|
inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
|
|
// get rndis ethernet interface mac address
|
while (ioctl(broadcast_fd, SIOCGIFHWADDR, &ifr) < 0) {
|
sleep(1);
|
}
|
snprintf(local_mac, FWK_MSG_MAC_MAX_LEN, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
|
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
|
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
|
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
|
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
|
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
|
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
|
|
printf("Discovery:got device net info!\n");
|
|
memset(&server_addr, 0, sizeof(server_addr));
|
server_addr.sin_family = AF_INET;
|
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
server_addr.sin_port = htons(UDPPORT);
|
addr_len = sizeof(server_addr);
|
|
if (setsockopt(broadcast_fd, SOL_SOCKET, SO_BROADCAST, (char *)&opt,
|
sizeof(opt)) < 0) {
|
perror("broadcast setsockopt SO_BROADCAST");
|
goto stop_broadcast;
|
}
|
if (setsockopt(broadcast_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
|
sizeof(opt)) < 0) {
|
perror("broadcast setsockopt SO_REUSEADDR");
|
goto stop_broadcast;
|
}
|
|
if (bind(broadcast_fd, (struct sockaddr *)&server_addr, addr_len) < 0) {
|
perror("broadcast bind");
|
goto stop_broadcast;
|
}
|
|
while (1) {
|
memset(buf, 0, sizeof(buf));
|
memset(uid, 0, sizeof(uid));
|
memset(cmd_info, 0, sizeof(cmd_info));
|
|
|
fprintf(stderr,"=========function is: %s line is : %d=============\n",__func__,__LINE__);
|
if (recvfrom(broadcast_fd, buf, 64, 0,
|
(struct sockaddr *)&server_addr, &addr_len) < 0) {
|
perror("broadcast recvfrom");
|
continue;
|
}
|
|
printf("broadcast: from: %s port: %d > %s\n",
|
inet_ntoa(server_addr.sin_addr),
|
ntohs(server_addr.sin_port), buf);
|
|
if (strcmp("CMD_DISCOVER", buf) == 0) {
|
|
if ((parameter_read_protocol_uid(uid)) < 0) {
|
printf("Discover:read uid failed!\n");
|
}
|
|
uid[FWK_MSG_UID_LEN] = '\0';
|
|
snprintf(cmd_info, FWK_MSG_CMD_LEN,
|
"{\"UID\":\"%s\","
|
"\"IP\":\"%s\","
|
"\"MAC\":\"%s\","
|
"\"DEVICENAME\":\"%s\"}",
|
uid,
|
local_addr,
|
local_mac,
|
"ECHO");
|
|
printf("sendto: %s port: %d > %s\n",
|
inet_ntoa(server_addr.sin_addr),
|
ntohs(server_addr.sin_port), cmd_info);
|
if (sendto(broadcast_fd, cmd_info, strlen(cmd_info),
|
0, (struct sockaddr *)&server_addr, addr_len) < 0) {
|
perror("broadcast_thread recvfrom");
|
goto stop_broadcast;
|
}
|
}
|
}
|
|
stop_broadcast:
|
printf("stop broadcast !\n");
|
if (broadcast_fd >= 0) {
|
shutdown(broadcast_fd, 2);
|
close(broadcast_fd);
|
broadcast_fd = -1;
|
}
|
}
|