Pārlūkot izejas kodu

开发dhcp功能

vothin 2 gadi atpakaļ
vecāks
revīzija
0a958f3102

+ 140 - 1
jni/logic/statusbar.cc

@@ -2,6 +2,7 @@
 #include "uart/ProtocolSender.h"
 #include "utils/TimeHelper.h"
 #include "net/NetManager.h"
+#include "net/DhcpClient.h"
 #include "manager/LanguageManager.h"
 
 #include "core/utilities.h"
@@ -13,7 +14,6 @@
 #include "net/tcp_client.h"
 #include <sys/reboot.h>
 
-#define ETHERNETMANAGER		NETMANAGER->getEthernetManager()
 /*
  *此文件由GUI工具生成
  *文件功能:用于处理用户的逻辑相应代码
@@ -44,8 +44,84 @@
  */
 
 
+#define ETHERNETMANAGER		NETMANAGER->getEthernetManager()
+#define WIFIMANAGER			NETMANAGER->getWifiManager()
+
 #define SYS_RESTART 10	// 重启
 
+static net::DhcpClient _s_wifi_dhcp_client;
+static net::DhcpClient _s_eth_dhcp_client;
+
+static bool _start_wifi_dhcp_client() {
+	// 静态ip模式不做处理
+	if (!WIFIMANAGER->isAutoMode()) {
+		return false;
+	}
+
+	if (!WIFIMANAGER->isConnected()) {
+		return false;
+	}
+
+	char ip[32], gw[32];
+	if (!WIFIMANAGER->getConfigureInfo(ip, NULL, gw, NULL, NULL)) {
+		return false;
+	}
+
+	return _s_wifi_dhcp_client.start(ip, WIFIMANAGER->getMacAddr(), gw);
+}
+
+static void _stop_wifi_dhcp_client() {
+	_s_wifi_dhcp_client.stop();
+}
+
+static bool _start_eth_dhcp_client() {
+	// 静态ip模式不做处理
+	if (!ETHERNETMANAGER->isAutoMode()) {
+		LOGD("以太网静态");
+		return false;
+	}
+
+	if (!ETHERNETMANAGER->isConnected()) {
+		LOGD("以太网连接状态");
+		return false;
+	}
+
+	char ip[32], gw[32];
+	if (!ETHERNETMANAGER->getConfigureInfo(ip, NULL, gw, NULL, NULL)) {
+		return false;
+	}
+
+	LOGD("正在重新请求dhcp");
+	return _s_eth_dhcp_client.start(ip, ETHERNETMANAGER->getMacAddr(), gw);
+}
+
+static void _stop_eth_dhcp_client() {
+	_s_eth_dhcp_client.stop();
+}
+
+static void _dhcp_lease_cb(dhcp_lease_type_e type, void *data) {
+	LOGD("_dhcp_lease_cb type %d\n", type);
+
+	switch (type) {
+	case E_DHCP_LEASE_TYPE_SUCCESS:
+		LOGD("DHCP连接成功");
+		break;
+
+	case E_DHCP_LEASE_TYPE_FAIL:
+		LOGD("DHCP连接失败,重连");
+		_start_eth_dhcp_client();
+		break;
+
+	case E_DHCP_LEASE_TYPE_TIMEOUT:
+		// 续租超时,可以断开再重连尝试
+		LOGD("DHCP连接超时,断开重连");
+		_stop_eth_dhcp_client();
+		_start_eth_dhcp_client();
+		break;
+	}
+}
+
+
 
 void NavibarSetPartName(const std::string& partName){
 	mPartNamePtr->setText(partName);
@@ -163,6 +239,54 @@ void isTimeScale(char* timeStr) {
 	}
 }
 
+namespace {
+
+// 以太网状态监听
+class EthernetConnStateListener : public EthernetManager::IEthernetConnStateListener {
+public:
+	virtual void handleEthernetConnState(EEthConnState state)  {
+		LOGD("[net] handleEthernetConnState state: %d\n", state);
+
+		switch (state) {
+		case E_ETH_CONNECTED:
+			LOGD("以太网连接");
+			_start_eth_dhcp_client();
+			break;
+
+		case E_ETH_DISCONNECTED:
+			LOGD("以太网断开");
+			_stop_eth_dhcp_client();
+			break;
+
+		default:
+			break;
+		}
+	}
+};
+
+// wifi状态监听
+class WifiListener: public WifiManager::IWifiListener {
+public:
+	virtual void handleWifiConnect(E_WIFI_CONNECT event, int args) {
+		LOGD("[net] handleWifiConnect event: %d\n", event);
+
+		switch (event) {
+		case E_WIFI_CONNECT_CONNECTED:
+			_start_wifi_dhcp_client();
+			break;
+
+		case E_WIFI_CONNECT_DISCONNECT:
+			_stop_wifi_dhcp_client();
+			break;
+
+		default:
+			break;
+		}
+	}
+};
+
+}
+
 
 /**
  * 注册定时器
@@ -197,6 +321,10 @@ static void updateUI_time() {
 	isTimeScale(timeStr2);
 }
 
+
+static EthernetConnStateListener _s_eth_state_listener;
+static WifiListener _s_wifi_listener;
+
 /**
  * 当界面构造时触发
  */
@@ -212,6 +340,17 @@ static void onUI_init(){
 	updateNetState();
 
 	tcpStatus();
+
+    //Tips :添加 UI初始化的显示代码到这里,如:mText1Ptr->setText("123");
+	ETHERNETMANAGER->addEthernetConnStateListener(&_s_eth_state_listener);
+	WIFIMANAGER->addWifiListener(&_s_wifi_listener);
+
+	_s_wifi_dhcp_client.set_lease_cb(_dhcp_lease_cb);
+	_s_eth_dhcp_client.set_lease_cb(_dhcp_lease_cb);
+
+	// 这里也检测网络是否连接上 (有可能启动前网络已经连接触发不到回调),启动dhcp租赁检测,之后都是根据网络的连接断开执行相应的操作
+	_start_wifi_dhcp_client();
+	_start_eth_dhcp_client();
 }
 
 /*

+ 549 - 0
jni/net/DhcpClient.cpp

@@ -0,0 +1,549 @@
+/*
+ * DhcpClient.cpp
+ *
+ *  Created on: Mar 25, 2023
+ *      Author: ZKSWE Develop Team
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <poll.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <linux/udp.h>
+#include <linux/if_packet.h>
+#include <linux/if_ether.h>
+#include "DhcpClient.h"
+#include "utils/Log.h"
+
+namespace net {
+
+#define PORT_BOOTP_SERVER 67
+#define PORT_BOOTP_CLIENT 68
+
+#define OP_BOOTREQUEST 1
+#define OP_BOOTREPLY   2
+
+#define FLAGS_BROADCAST 0x8000
+
+#define HTYPE_ETHER    1
+
+#define DHCP_MSG_FIXED_SIZE 236
+
+/* first four bytes of options are a cookie to indicate that
+** the payload are DHCP options as opposed to some other BOOTP
+** extension.
+*/
+#define OPT_COOKIE1          0x63
+#define OPT_COOKIE2          0x82
+#define OPT_COOKIE3          0x53
+#define OPT_COOKIE4          0x63
+
+/* BOOTP/DHCP options - see RFC 2132 */
+#define OPT_PAD              0
+
+#define OPT_SUBNET_MASK      1     /* 4 <ipaddr> */
+#define OPT_TIME_OFFSET      2     /* 4 <seconds> */
+#define OPT_GATEWAY          3     /* 4*n <ipaddr> * n */
+#define OPT_DNS              6     /* 4*n <ipaddr> * n */
+#define OPT_HOST_NAME        12
+#define OPT_DOMAIN_NAME      15    /* n <domainnamestring> */
+#define OPT_BROADCAST_ADDR   28    /* 4 <ipaddr> */
+
+#define OPT_REQUESTED_IP     50    /* 4 <ipaddr> */
+#define OPT_LEASE_TIME       51    /* 4 <seconds> */
+#define OPT_MESSAGE_TYPE     53    /* 1 <msgtype> */
+#define OPT_SERVER_ID        54    /* 4 <ipaddr> */
+#define OPT_PARAMETER_LIST   55    /* n <optcode> * n */
+#define OPT_MESSAGE          56    /* n <errorstring> */
+#define OPT_CLASS_ID         60    /* n <opaque> */
+#define OPT_CLIENT_ID        61    /* n <opaque> */
+#define OPT_END              255
+
+/* DHCP message types */
+#define DHCPDISCOVER         1
+#define DHCPOFFER            2
+#define DHCPREQUEST          3
+#define DHCPDECLINE          4
+#define DHCPACK              5
+#define DHCPNAK              6
+#define DHCPRELEASE          7
+#define DHCPINFORM           8
+
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    long int _rc;                          \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
+
+typedef struct {
+	uint8_t op;           /* BOOTREQUEST / BOOTREPLY    */
+	uint8_t htype;        /* hw addr type               */
+	uint8_t hlen;         /* hw addr len                */
+	uint8_t hops;         /* client set to 0            */
+
+	uint32_t xid;         /* transaction id             */
+
+	uint16_t secs;        /* seconds since start of acq */
+	uint16_t flags;
+
+	uint32_t ciaddr;      /* client IP addr             */
+	uint32_t yiaddr;      /* your (client) IP addr      */
+	uint32_t siaddr;      /* ip addr of next server     */
+						  /* (DHCPOFFER and DHCPACK)    */
+	uint32_t giaddr;      /* relay agent IP addr        */
+
+	uint8_t chaddr[16];  /* client hw addr             */
+	char sname[64];      /* asciiz server hostname     */
+	char file[128];      /* asciiz boot file name      */
+
+	uint8_t options[312];  /* optional parameters        */
+} dhcp_msg;
+
+typedef struct {
+	uint32_t type;
+
+	uint32_t ipaddr;
+	uint32_t gateway;
+	uint32_t prefixLength;
+
+	uint32_t dns1;
+	uint32_t dns2;
+
+	uint32_t saddr;
+	uint32_t lease;
+} dhcp_info;
+
+static bool _s_verbose = true;
+
+static uint32_t get_sec() {
+	struct timespec ts;
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+	return ts.tv_sec;
+}
+
+static int mask_to_prelen(in_addr_t mask) {
+	int len = 0;
+	uint32_t m = (uint32_t) ntohl(mask);
+	while (m & 0x80000000) {
+		len++;
+		m = m << 1;
+	}
+	return len;
+}
+
+static void macaddr_to_hwaddr(const char *macaddr, uint8_t hwaddr[6]) {
+	sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
+			hwaddr, hwaddr + 1, hwaddr + 2, hwaddr + 3, hwaddr + 4, hwaddr + 5);
+}
+
+static uint8_t *init_dhcp_msg(dhcp_msg *msg, int type, uint8_t *hwaddr, uint32_t xid) {
+	uint8_t *x;
+
+	memset(msg, 0, sizeof(dhcp_msg));
+
+	msg->op = OP_BOOTREQUEST;
+	msg->htype = HTYPE_ETHER;
+	msg->hlen = 6;
+	msg->hops = 0;
+	msg->xid = xid;
+
+	memcpy(msg->chaddr, hwaddr, 6);
+
+	x = msg->options;
+
+	*x++ = OPT_COOKIE1;
+	*x++ = OPT_COOKIE2;
+	*x++ = OPT_COOKIE3;
+	*x++ = OPT_COOKIE4;
+
+	*x++ = OPT_MESSAGE_TYPE;
+	*x++ = 1;
+	*x++ = type;
+
+	return x;
+}
+
+static int init_dhcp_renew_msg(dhcp_msg *msg, uint8_t *hwaddr, uint32_t xid,
+						uint32_t ipaddr, uint32_t saddr) {
+	uint8_t *x;
+
+	x = init_dhcp_msg(msg, DHCPREQUEST, hwaddr, xid);
+
+	msg->ciaddr = ipaddr;
+
+	*x++ = OPT_CLIENT_ID;
+	*x++ = 7;
+	*x++ = HTYPE_ETHER;
+	memcpy(x, hwaddr, 6);
+	x += 6;
+
+	*x++ = OPT_PARAMETER_LIST;
+	*x++ = 4;
+	*x++ = OPT_SUBNET_MASK;
+	*x++ = OPT_GATEWAY;
+	*x++ = OPT_DNS;
+	*x++ = OPT_BROADCAST_ADDR;
+
+	*x++ = OPT_REQUESTED_IP;
+	*x++ = 4;
+	memcpy(x, &ipaddr, 4);
+	x += 4;
+
+	*x++ = OPT_SERVER_ID;
+	*x++ = 4;
+	memcpy(x, &saddr, 4);
+	x += 4;
+
+	*x++ = OPT_END;
+
+	return DHCP_MSG_FIXED_SIZE + (x - msg->options);
+}
+
+static const char *dhcp_type_to_name(uint32_t type) {
+	switch (type) {
+	case DHCPDISCOVER: return "discover";
+	case DHCPOFFER:    return "offer";
+	case DHCPREQUEST:  return "request";
+	case DHCPDECLINE:  return "decline";
+	case DHCPACK:      return "ack";
+	case DHCPNAK:      return "nak";
+	case DHCPRELEASE:  return "release";
+	case DHCPINFORM:   return "inform";
+	default:           return "???";
+	}
+}
+
+static void dump_dhcp_info(dhcp_info *info) {
+	char addr[20], gway[20], dns[20];
+	LOGD("[dhcp] %s (%d) ---\n", dhcp_type_to_name(info->type), info->type);
+	inet_ntop(AF_INET, &info->ipaddr, addr, sizeof(addr));
+	inet_ntop(AF_INET, &info->gateway, gway, sizeof(gway));
+	LOGD("[dhcp] ip %s gw %s prefixLength %d\n", addr, gway, info->prefixLength);
+	if (info->dns1) LOGD("[dhcp] dns1: %s\n", inet_ntop(AF_INET, &info->dns1, dns, sizeof(dns)));
+	if (info->dns2) LOGD("[dhcp] dns2: %s\n", inet_ntop(AF_INET, &info->dns2, dns, sizeof(dns)));
+	LOGD("[dhcp] server %s, lease %d seconds\n", inet_ntop(AF_INET, &info->saddr, addr, sizeof(addr)), info->lease);
+}
+
+static int decode_dhcp_msg(dhcp_msg *msg, int len, dhcp_info *info) {
+	uint8_t *x;
+	uint32_t opt;
+	int optlen;
+
+	memset(info, 0, sizeof(dhcp_info));
+	if (len < (DHCP_MSG_FIXED_SIZE + 4)) return -1;
+
+	len -= (DHCP_MSG_FIXED_SIZE + 4);
+
+	if (msg->options[0] != OPT_COOKIE1) return -1;
+	if (msg->options[1] != OPT_COOKIE2) return -1;
+	if (msg->options[2] != OPT_COOKIE3) return -1;
+	if (msg->options[3] != OPT_COOKIE4) return -1;
+
+	x = msg->options + 4;
+
+	while (len > 2) {
+		opt = *x++;
+		if (opt == OPT_PAD) {
+			len--;
+			continue;
+		}
+		if (opt == OPT_END) {
+			break;
+		}
+		optlen = *x++;
+		len -= 2;
+		if (optlen > len) {
+			break;
+		}
+		switch(opt) {
+		case OPT_SUBNET_MASK:
+			if (optlen >= 4) {
+				in_addr_t mask;
+				memcpy(&mask, x, 4);
+				info->prefixLength = mask_to_prelen(mask);
+			}
+			break;
+		case OPT_GATEWAY:
+			if (optlen >= 4) memcpy(&info->gateway, x, 4);
+			break;
+		case OPT_DNS:
+			if (optlen >= 4) memcpy(&info->dns1, x + 0, 4);
+			if (optlen >= 8) memcpy(&info->dns2, x + 4, 4);
+			break;
+		case OPT_LEASE_TIME:
+			if (optlen >= 4) {
+				memcpy(&info->lease, x, 4);
+				info->lease = ntohl(info->lease);
+			}
+			break;
+		case OPT_SERVER_ID:
+			if (optlen >= 4) memcpy(&info->saddr, x, 4);
+			break;
+		case OPT_MESSAGE_TYPE:
+			info->type = *x;
+			break;
+		default:
+			break;
+		}
+		x += optlen;
+		len -= optlen;
+	}
+
+	info->ipaddr = msg->yiaddr;
+
+	return 0;
+}
+
+static bool is_valid_reply(dhcp_msg *msg, dhcp_msg *reply, int sz) {
+	if (sz < DHCP_MSG_FIXED_SIZE) {
+		if (_s_verbose) {
+			LOGD("netcfg: Wrong size %d != %d\n", sz, DHCP_MSG_FIXED_SIZE);
+		}
+		return false;
+	}
+	if (reply->op != OP_BOOTREPLY) {
+		if (_s_verbose) {
+			LOGD("netcfg: Wrong Op %d != %d\n", reply->op, OP_BOOTREPLY);
+		}
+		return false;
+	}
+	if (reply->xid != msg->xid) {
+		if (_s_verbose) {
+			LOGD("netcfg: Wrong Xid 0x%x != 0x%x\n", ntohl(reply->xid), ntohl(msg->xid));
+		}
+		return false;
+	}
+	if (reply->htype != msg->htype) {
+		if (_s_verbose) {
+			LOGD("netcfg: Wrong Htype %d != %d\n", reply->htype, msg->htype);
+		}
+		return false;
+	}
+	if (reply->hlen != msg->hlen) {
+		if (_s_verbose) {
+			LOGD("netcfg: Wrong Hlen %d != %d\n", reply->hlen, msg->hlen);
+		}
+		return false;
+	}
+	if (memcmp(msg->chaddr, reply->chaddr, msg->hlen)) {
+		if (_s_verbose) {
+			LOGD("netcfg: Wrong chaddr %x != %x\n", *(reply->chaddr),*(msg->chaddr));
+		}
+		return false;
+	}
+	return true;
+}
+
+
+DhcpClient::DhcpClient() : lease_cb_(NULL), record_time_(0), lease_(0), record_lease_(0) {
+	wakeup_[0] = wakeup_[1] = -1;
+}
+
+DhcpClient::~DhcpClient() {
+	stop();
+}
+
+void DhcpClient::set_lease_cb(dhcp_lease_cb cb) {
+	lease_cb_ = cb;
+}
+
+bool DhcpClient::start(const char *ip, const char *macaddr, const char *gateway) {
+	if (isRunning()) {
+		return true;
+	}
+
+	if (pipe(wakeup_) < 0) {
+		LOGE("[dhcp] create pipe fail\n");
+		return false;
+	}
+
+	ip_ = ip;
+	macaddr_ = macaddr;
+	gateway_ = gateway;
+	record_time_ = get_sec();
+	lease_ = 60 * 60;    // 1 hour
+	record_lease_ = 0;
+
+	LOGD("开始请求dhcp,ip == %s", ip);
+	return run("renew");
+}
+
+void DhcpClient::stop() {
+	LOGD("[dhcp] stop +++\n");
+	LOGD("正在断开dhcp,ip == %s", ip_.c_str());
+
+	if (wakeup_[1] >= 0) {
+		TEMP_FAILURE_RETRY(write(wakeup_[1], "W", 1));
+	}
+
+	requestExitAndWait();
+
+	if (wakeup_[0] >= 0) {
+		close(wakeup_[0]);
+		wakeup_[0] = -1;
+	}
+	if (wakeup_[1] >= 0) {
+		close(wakeup_[1]);
+		wakeup_[1] = -1;
+	}
+	LOGD("[dhcp] stop ---\n");
+}
+
+bool DhcpClient::threadLoop() {
+	uint32_t lease1_2 = lease_ / 2;    // 1/2
+	uint32_t lease7_8 = lease_ - lease_ / 8;  // 7/8
+	uint32_t past_time = get_sec() - record_time_;
+	bool need_renew = false;
+
+//	LOGD("lease_ %d\n", lease_);
+//	LOGD("lease1_2 %d\n", lease1_2);
+//	LOGD("lease7_8 %d\n", lease7_8);
+//	LOGD("past_time %d\n", past_time);
+
+	if (past_time > lease_) {
+		LOGE("[dhcp] lease time out\n");
+		if (lease_cb_) {
+			lease_cb_(E_DHCP_LEASE_TYPE_TIMEOUT, this);
+		}
+		return false;
+	} else if (past_time > lease7_8) {
+		if (record_lease_ < lease7_8) {
+			record_lease_ = lease7_8;
+			need_renew = true;
+		}
+	} else if (past_time > lease1_2) {
+		if (record_lease_ < lease1_2) {
+			record_lease_ = lease1_2;
+			need_renew = true;
+		}
+	}
+
+	if (need_renew) {
+		bool ret = false;
+		for (int i = 0; i < 3; ++i) {
+			if (renew()) {
+				ret = true;
+				break;
+			}
+
+			sleep(100);
+		}
+
+		if (ret) {
+			record_lease_ = 0;
+			record_time_ = get_sec();
+			LOGD("[dhcp] lease ok\n");
+			if (lease_cb_) {
+				lease_cb_(E_DHCP_LEASE_TYPE_SUCCESS, this);
+			}
+		} else {
+			LOGE("[dhcp] lease err\n");
+			if (lease_cb_) {
+				lease_cb_(E_DHCP_LEASE_TYPE_FAIL, this);
+			}
+		}
+	}
+
+	struct pollfd ufd = { wakeup_[0], POLLIN, 0 };
+	poll(&ufd, 1, 3000);
+
+	return true;
+}
+
+bool DhcpClient::renew() {
+	int s = -1;
+	sockaddr_in saddr;
+	socklen_t saddr_len;
+	sockaddr_in caddr;
+	socklen_t caddr_len;
+	struct timeval tv_out;
+	uint8_t hwaddr[6];
+	dhcp_msg renew_msg;
+	dhcp_msg recv_msg;
+	ssize_t renew_len;
+	ssize_t recv_len;
+	dhcp_info di;
+	bool ret = false;
+
+	s = socket(AF_INET, SOCK_DGRAM, 0);
+	if (s < 0) {
+		LOGE("[dhcp] create socket err\n");
+		return false;
+	}
+
+	saddr_len = sizeof(struct sockaddr_in);
+	memset(&saddr, 0, saddr_len);
+	saddr.sin_family = AF_INET;
+	saddr.sin_port = htons(PORT_BOOTP_SERVER);
+	saddr.sin_addr.s_addr = inet_addr(gateway_.c_str());
+
+	caddr_len = sizeof(struct sockaddr_in);
+	memset(&caddr, 0, caddr_len);
+	caddr.sin_family = AF_INET;
+	caddr.sin_port = htons(PORT_BOOTP_CLIENT);
+	caddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+	if (bind(s, (sockaddr *) &caddr, caddr_len) < 0) {
+		LOGE("[dhcp] bind err\n");
+		goto END;
+	}
+
+	tv_out.tv_sec = 2;    // 等待2秒
+	tv_out.tv_usec = 0;
+	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out)) < 0) {
+		LOGE("[dhcp] setsockopt err\n");
+		goto END;
+	}
+
+	macaddr_to_hwaddr(macaddr_.c_str(), hwaddr);
+	renew_len = init_dhcp_renew_msg(&renew_msg, hwaddr, get_sec(), inet_addr(ip_.c_str()), inet_addr(gateway_.c_str()));
+	if (sendto(s, &renew_msg, renew_len, 0, (struct sockaddr *) &saddr, saddr_len) < 0) {
+		LOGE("[dhcp] sendto err\n");
+		goto END;
+	}
+
+	recv_len = recvfrom(s, &recv_msg, sizeof(recv_msg), 0, (struct sockaddr *) &saddr, &saddr_len);
+	if (recv_len < 0) {
+		LOGE("[dhcp] recvfrom err\n");
+		goto END;
+	}
+
+	LOGD("[dhcp] recv len %d\n", recv_len);
+	if (!is_valid_reply(&renew_msg, &recv_msg, recv_len)) {
+		goto END;
+	}
+
+	if (decode_dhcp_msg(&recv_msg, recv_len, &di) == -1) {
+		LOGE("[dhcp] decode msg err\n");
+		goto END;
+	}
+
+	dump_dhcp_info(&di);
+
+	if (di.type != DHCPACK) {
+		goto END;
+	}
+
+	lease_ = di.lease;
+	ret = true;
+
+END:
+	close(s);
+
+	return ret;
+}
+
+}

+ 52 - 0
jni/net/DhcpClient.h

@@ -0,0 +1,52 @@
+/*
+ * DhcpClient.h
+ *
+ *  Created on: Mar 25, 2023
+ *      Author: ZKSWE Develop Team
+ */
+
+#ifndef _NET_DHCP_CLIENT_H_
+#define _NET_DHCP_CLIENT_H_
+
+#include <stdint.h>
+#include <string>
+#include "system/Thread.h"
+
+typedef enum {
+	E_DHCP_LEASE_TYPE_SUCCESS,
+	E_DHCP_LEASE_TYPE_FAIL,
+	E_DHCP_LEASE_TYPE_TIMEOUT
+} dhcp_lease_type_e;
+
+typedef void (*dhcp_lease_cb)(dhcp_lease_type_e type, void *data);
+
+namespace net {
+
+class DhcpClient : public Thread {
+public:
+	DhcpClient();
+	virtual ~DhcpClient();
+
+	void set_lease_cb(dhcp_lease_cb cb);
+	bool start(const char *ip, const char *macaddr, const char *gateway);
+	void stop();
+
+protected:
+	bool threadLoop();
+	bool renew();
+
+private:
+	std::string ip_;
+	std::string macaddr_;
+	std::string gateway_;
+	dhcp_lease_cb lease_cb_;
+	uint32_t record_time_;
+	uint32_t lease_;
+	uint32_t record_lease_;
+	int wakeup_[2];
+
+};
+
+}
+
+#endif /* _NET_DHCP_CLIENT_H_ */

+ 2 - 2
jni/service/BusinessConfig.h

@@ -52,8 +52,8 @@
 #define STORE_ROOM_CALL_BED "room_call_bed"
 #define SIGNAL_TYPE "TCP" //TCP,SIP
 
-static std::string version = "v1.0.21";
-static int versionNo = 21;
+static std::string version = "v1.0.22";
+static int versionNo = 22;
 static std::string serverIP = "172.28.100.100";
 static std::string tcpIP = "172.28.100.100";
 static int serverHttpPort = 8006;

BIN
libs/armeabi/libzkgui.so


BIN
obj/activity/DeviceUpdateActivity.o


BIN
obj/activity/callActivity.o


BIN
obj/activity/mainActivity.o


BIN
obj/activity/sipTestActivity.o


BIN
obj/activity/startActivity.o


BIN
obj/activity/statusbar.o


BIN
obj/activity/ui3Activity.o


BIN
obj/activity/warnActivity.o


BIN
obj/core/update_assistant.o


BIN
obj/net/DhcpClient.o


BIN
obj/net/tcp_client.o


BIN
obj/service/BusinessConfig.o


BIN
obj/service/time.o