客户端通过广播发送信息,模组端的应用程序获取广播信息,解析信息修改相应的配置文件
烧写完固件后,模组默认ip为192.168.0.200,默认mac地址为"A8:C3:15:00:00:00",默认device_id为"JS00000000000000"。需要修改mac地址、设备序列号后模组才能使用。
mac地址、device_id不支持批量修改。
Request Body:
{
"magic_value": "AABB5555", # 幻数
"msg_type": "client", # "client":搜索软件请求消息,"board":板卡回复消息
"msg_cmd": "set_mac_id", # 修改mac地址
# 参数
"mac": "A8:C3:15:00:00:15",
"device_id": "JS01229110000900"
}
Response Body:
{
"magic_value": "AABB5555",
"msg_type": "board",
"msg_cmd": "set_mac_id",
# 返回结果
"result": "ok" # "ok":修改成功 "fail":修改失败
}
mac地址、device_id分别存储于/mnt/data/cfg/eth_cfg.cfg、/mnt/data/cfg/device_id。
客户端通过设备搜索接口获取到所有在线模组的mac地址后,即可通过mac修改相关模组ip。
模组收到消息后解析,mac与板卡mac地址相同时才进行ip设置,不同时忽略该消息。
Request Body:
{
"magic_value": "AABB5555", # 幻数
"msg_type": "client", # "client":搜索软件请求消息,"board":板卡回复消息
"msg_cmd": "set_ip", # 修改ip
# 参数
"mac": "A8:C3:15:00:00:15", # 待修改模组的mac地址
"ip": "192.168.0.11" # 待修改模组的ip
}
Response Body:
{
"magic_value": "AABB5555",
"msg_type": "board",
"msg_cmd": "set_ip",
# 返回结果
"result": "ok" # "ok":设置成功
}
class CDevManager
{
class CDevManager
{
public:
CDevManager();
~CDevManager();
int Start();
int Stop();
int SetCameraHdl(void *hdl);
static int NotifyPtpCfg(PTP_CFG &cfg);
static int NotifyNtpCfg(NTP_CFG &cfg);
static int NotifySyslogCfg(SYSLOG_CFG &cfg);
static void RebootEnable();//重启板卡
static void NotifyUpdateBegin();
static void NotifyUpdateDone();
static void ResetSensorEnable();//重新配置sensor
static int GetSensorStatus();//获取sensor重启状态
private:
void DevSearchThrFunc();//设备搜索线程
void DevManageThrFunc();//设备管理线程:重启、NTP、重配sensor
void DevBurnMAC_IP_Func(); //burn MAC、devID、IP
void broadcast_dev_info();
void MAC_dev_info(const char *m,const char *d);
void SetIP_dev_info(const char *IP);
protected:
thread* m_pDevSearchThr;
thread* m_pDevManageThr;
thread* m_pImgProcThread;
thread* m_pDevBurnmacThr;
thread* m_PDevSetIPThr;
};
#include <iostream>
#include<fstream>
int SaveEthMacCfg(EthCfg *eth_cfg);
int deviceId(string *device_id);
void CDevManager::DevBurnMAC_IP_Func()
{
int sock_serv;
int res;
struct sockaddr_in servaddr;
struct sockaddr_in cliaddr;
socklen_t clilen;
int recv;
int enable = 1;
int maxFd = 0;
fd_set fds;
struct timeval TimeoutVal;
char data[BROADCAST_BUF_SIZE];
json_t *json_body;
json_t *value = nullptr;
const char *magic_value = nullptr;
const char *msg_type = nullptr;
const char *mac_value = nullptr;
const char *device_id = nullptr;
const char *msg_ip = nullptr;
const char *msg_cmd = nullptr;
sock_serv = socket(AF_INET,SOCK_DGRAM,0);
if(sock_serv < 0) {
perror("socket()");
}
EthCfg eth_cfg = CConfigParser::GetInstance()->GetEthCfg();
setsockopt(sock_serv, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(BROADCAST_REQUEST_PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
res = bind(sock_serv,(struct sockaddr *)&servaddr,sizeof(servaddr));
if(res < 0) {
perror("bind()");
}
while(1)
{
if (!m_nRunning) {
CTimeUtils::msSleep(5000);
continue;
}
FD_ZERO(&fds);
FD_SET(sock_serv, &fds);
if(maxFd<=sock_serv)
maxFd = sock_serv;
TimeoutVal.tv_sec = 2;
TimeoutVal.tv_usec = 0;
res = select(maxFd + 1, &fds, NULL, NULL, &TimeoutVal);
switch (res)
{
case -1: break;
case 0: break;
default:
if(FD_ISSET(sock_serv, &fds))
{
clilen = sizeof(cliaddr);
memset(&data, 0, BROADCAST_BUF_SIZE);
recv = recvfrom(sock_serv, &data, BROADCAST_BUF_SIZE, 0, (struct sockaddr *)&cliaddr, &clilen);
if(recv <= 0)
continue;
json_body = json_loads(data, 0, NULL);
if(json_is_object(json_body)) {
value = json_object_get(json_body, "msg_cmd");
if(json_is_string(value)) {
msg_cmd = json_string_value(value);
}
value = json_object_get(json_body, "magic_value");
if(json_is_string(value)) {
magic_value = json_string_value(value);
}
value = json_object_get(json_body, "msg_type");
if(json_is_string(value)) {
msg_type = json_string_value(value);
}
value = json_object_get(json_body, "mac");
if(json_is_string(value)) {
mac_value = json_string_value(value);
}
value = json_object_get(json_body, "device_id");
if(json_is_string(value)) {
device_id = json_string_value(value);
}
value = json_object_get(json_body,"ip");
if(json_is_string(value)){
msg_ip = json_string_value(value);
}
}
printf("msg_cmd:%s,magic_value:%s,msg_type:%s,mac:%s,device_id:%s,IP:%s,eth_cfg.mac:%s\n",msg_cmd,magic_value,msg_type,mac_value,device_id,msg_ip,eth_cfg.Mac);
if(0==strcmp(magic_value, BROADCAST_REQUEST_MAGIC) && 0==strcmp(msg_type,"client")) {
if(0==strcmp(msg_cmd, "set_mac_id")){
printf("begin into burnMac\n");
MAC_dev_info(mac_value,device_id);
printf("finish burnMac\n");
}else if(0==strcmp(msg_cmd, "set_ip") && 0==strcmp(mac_value,eth_cfg.Mac)){
printf("begin SetIP\n");
SetIP_dev_info(msg_ip);
printf("finish SetIP\n");
}
}
json_decref(json_body);
}
break;
}
}
close(sock_serv);
}
void CDevManager::MAC_dev_info(const char *m, const char *d)
{
string device_id;
const char *mac_value;
mac_value = m;
device_id = d;
EthCfg eth_cfg = CConfigParser::GetInstance()->GetEthCfg();
strcpy(eth_cfg.Mac,mac_value);
SaveEthMacCfg(ð_cfg);
printf("hello MAC_dev_info\n");
deviceId(&device_id);
}
int SaveEthMacCfg(EthCfg *eth_cfg)
{
json_t *object;
object = json_object();
json_object_set_new(object, "ip", json_string(eth_cfg->IP));
json_object_set_new(object, "gateway", json_string(eth_cfg->gateway));
json_object_set_new(object, "submask", json_string(eth_cfg->submask));
json_object_set_new(object, "dns1", json_string(eth_cfg->dns1));
json_object_set_new(object, "dns2", json_string(eth_cfg->dns2));
json_object_set_new(object, "mac", json_string(eth_cfg->Mac));
string MAC_CFG = gOptions.GetJsonCfgPath() + ETH_CFG_FILE_PATH;
printf("SaveMAC:%s,path:%s\n",eth_cfg->Mac,MAC_CFG.c_str());
json_dump_file(object, MAC_CFG.c_str(), JSON_PRESERVE_ORDER);
json_decref(object);
return 0;
}
int deviceId(string *device_id)
{
using namespace std;
string devId;
devId = *device_id;
printf("devId:%s\n",devId.c_str());
ofstream ofs;
ofs.open("/mnt/data/cfg/device_id", ios::out);
ofs << devId << endl;
ofs.close();
return 0;
}
void CDevManager::SetIP_dev_info(const char *IP)
{
int ret=0;
EthCfg eth_cfg = CConfigParser::GetInstance()->GetEthCfg();
printf("getIP is:%s\n",IP);
strcpy(eth_cfg.IP,IP);
ret = CConfigParser::GetInstance()->SetEthCfg(eth_cfg);
printf("hello SetIP:%s\n",eth_cfg.IP);
//使用固定参数
#if 0
strcpy(eth_cfg.IP,"192.168.12.215");
ret = CConfigParser::GetInstance()->SetEthCfg(eth_cfg);
printf("hello SetIP:%s\n",eth_cfg.IP);
#endif
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <string.h>
#include "jansson.h"
#define BROADCAST_REQUEST_PORT 20555
#define BROADCAST_REQUEST_MAGIC 0xAABB5555
#define BROADCAST_RESP_PORT 21555
#define BROADCAST_RESP_MAGIC 0xBBAA5555
//设备信息
typedef struct tagDEVICE_INFO
{
char device_id[32];
char device_name[32];//可修改
char soft_version[32];
}DEVICE_INFO;
//网络设置
typedef struct tagETH_CFG
{
char ip[16];
char gateway[16];//可修改
char submask[16];
char dns1[16];
char dns2[16];
char mac[18];
}ETH_CFG;
//自动发现设备通信协议
typedef struct tagDEV_SEARCH_REQUEST
{
unsigned int magic_value;
unsigned int msg_type;//0-搜索软件发出 1-板卡回复消息
}DEV_SEARCH_REQUEST;
int main(void)
{
int sock_cli;
struct sockaddr_in cliaddr;
int res;
int recv;
socklen_t clilen;
int enable = 1;
sock_cli = socket(AF_INET,SOCK_DGRAM,0);
if(sock_cli < 0)
{
perror("socket()");
return -1;
}
//允许发送广播数据
setsockopt(sock_cli,SOL_SOCKET,SO_BROADCAST,&enable,sizeof(enable));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(BROADCAST_REQUEST_PORT);
inet_pton(AF_INET, "255.255.255.255", &cliaddr.sin_addr);
json_t *objectmsg;
char *result;
objectmsg = json_object();
json_object_set_new (objectmsg, "msg_cmd", json_string("set_mac_id"));
json_object_set_new (objectmsg, "magic_value", json_string("AABB5555"));
json_object_set_new (objectmsg, "msg_type", json_string("client"));
json_object_set_new (objectmsg, "mac", json_string("A1:C1:10:00:00:10"));
json_object_set_new (objectmsg, "device_id", json_string("JS01229110000666"));
//json_object_set_new (objectmsg, "ip", json_string("192.168.12.214"));
result = json_dumps(objectmsg, JSON_PRESERVE_ORDER);
printf("result=%s %ld\n",result, strlen(result));
{
res = sendto(sock_cli, result, strlen(result), 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
if(res < 0)
{
perror("sendto()");
return -1;
}
}
close(sock_cli);
return 0;
}