C++应程序实现修改设备IP地址、MAC、设备ID功能

应用程序实现目的

客户端通过广播发送信息,模组端的应用程序获取广播信息,解析信息修改相应的配置文件

功能需求

1. 烧写mac地址、设备序列号

烧写完固件后,模组默认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。

2.修改ip地址

客户端通过设备搜索接口获取到所有在线模组的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":设置成功
}

功能实现

Manager.h头文件-定义私有类成员函数

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;

	

};

Manager.cpp函数主体

添加头文件、函数声明

#include <iostream>

#include<fstream>

int SaveEthMacCfg(EthCfg *eth_cfg);
int deviceId(string *device_id);

DevBurnMAC_IP_Func()函数主题

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);


}
MAC_dev_info回调函数
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(&eth_cfg);
	printf("hello MAC_dev_info\n");
                 
	deviceId(&device_id);
}

保存MAC地址SaveEthMacCfg函数实现

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;
}

修改设备Id功能deviceId函数实现

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;
}

修改IP功能SetIP_dev_info函数实现

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值