//接口状态
typedef enum {
STATUS_UP,
STATUS_DOWN
} InterfaceStatus
//接口信息
typedef struct {
char ip[NSTACKX_MAX_IP_STRING_LEN]
InterfaceStatus status
int flag
} InterfaceInfo
/*
函数功能: 获取网络接口信息
函数参数:
fd: 接口文件描述符
interfaceName: 接口名
length: 接口名长度
info: 用来保存获得到的接口信息
函数过程:
1. 检查各个参数
2. 声明 ifreq 结构体 ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的
3. 调用ioctl 获取 本地网络接口信息,接口是否处于活动状态且准备好传输数据 ,如果是 接口状态就是上传 那么info状态就是上传,否则接口就在下载
4. 调用ioctl 获取接口IP地址
5. 将ip地址以点分十进制复制到info中
*/
void GetInterfaceInfo(int fd, const char* interfaceName, int length, InterfaceInfo *info)
{
if (fd < 0 || info == NULL || interfaceName == NULL) {
return
}
struct ifreq ifr
/*
struct ifreq {
char ifr_name[IFNAMSIZ]
union
{ (IP地址,广播地址,子网掩码,MAC号,MTU等)
struct sockaddr ifru_addr
struct sockaddr ifru_dstaddr
struct sockaddr ifru_broadaddr
struct sockaddr ifru_netmask
struct sockaddr ifru_hwaddr
short int ifru_flags
int ifru_ivalue
int ifru_mtu
struct ifmap ifru_map
char ifru_slave[IFNAMSIZ]
char ifru_newname[IFNAMSIZ]
__caddr_t ifru_data
} ifr_ifru
}
memset_s(&ifr, sizeof(struct ifreq), 0, sizeof(struct ifreq))
//将接口名拷贝到ifreq
int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), interfaceName, length)
if (ret != EOK) {
SOFTBUS_PRINT("[DISCOVERY] CoapGetWifiIp ifr.ifr_name cpy fail\n")
return
}
//ioctl 获取本地网络接口信息
if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
return
}
//接口是否处于活动状态且准备好传输数据 ,如果是 接口状态就是上传
if ((unsigned short int)ifr.ifr_flags & IFF_UP) {
info->status = STATUS_UP
} else {
//否则接口就在下载
info->status = STATUS_DOWN
info->ip[0] = '\0'
info->flag = 1
return
}
memset_s(&ifr, sizeof(struct ifreq), 0, sizeof(struct ifreq))
ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), interfaceName, length)
if (ret != EOK) {
SOFTBUS_PRINT("[DISCOVERY] CoapGetWifiIp ifr.ifr_name cpy fail\n")
return
}
//获取接口IP地址
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
return
}
//将ip地址以点分十进制复制到info中
ret = strcpy_s(info->ip, sizeof(info->ip),
inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr))
if (ret != EOK) {
SOFTBUS_PRINT("[DISCOVERY] CoapGetWifiIp cpy fail\n")
}
info->flag = 1
return
}
void CoapGetWifiIp(char *ip, int length)
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
return;
}
InterfaceInfo info = {0};
GetInterfaceInfo(fd, ETH, strlen(ETH) + 1, &info);
if (!info.flag) {
memset_s(&info, sizeof(info), 0, sizeof(info));
GetInterfaceInfo(fd, WLAN, strlen(WLAN) + 1, &info);
}
if (!info.flag) {
close(fd);
return;
}
if (strcpy_s(ip, length, info.ip) != EOK) {
SOFTBUS_PRINT("[DISCOVERY]copy ip to dst failed.\n");
}
close(fd);
}
/*
函数功能: 创建监听线程
函数返回值:成功返回1,否则返回非零
详细:
1.设置终端设备标志
2. 如果g_coapTaskId不为0,那么表示监听线程之前就创建好
3. 设置线程属性
4. 创建线程
*/
int CreateCoapListenThread(void)
{
g_terminalFlag = 1
if (g_coapTaskId != NULL) {
return NSTACKX_EOK
}
osThreadAttr_t attr
attr.name = "coap_listen_task"
attr.attr_bits = 0U
attr.cb_mem = NULL
attr.cb_size = 0U
attr.stack_mem = NULL
attr.stack_size = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE
attr.priority = osPriorityNormal4
g_coapTaskId = osThreadNew((osThreadFunc_t)CoapReadHandle, NULL, &attr)
if (g_coapTaskId == NULL) {
g_terminalFlag = 0
SOFTBUS_PRINT("[DISCOVERY] create task fail\n")
return NSTACKX_EFAILED
}
if (g_coapTaskId != -1) {
return NSTACKX_EOK
}
ThreadAttr attr = {"coap_listen_task", 0x800, 20, 0, 0}
int error = CreateThread((Runnable)CoapReadHandle, NULL, &attr, (unsigned int *)&g_coapTaskId)
if (error != 0) {
g_terminalFlag = 0
SOFTBUS_PRINT("[DISCOVERY] create task fail\n")
return NSTACKX_EFAILED
}
return NSTACKX_EOK
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。
`欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案)
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
void ExitCoapListenThread(void)
{
g_terminalFlag = 0;
#if defined(__LITEOS_M__) || defined(__LITEOS_RISCV__)
if (g_coapTaskId != NULL) {
if (osThreadTerminate(g_coapTaskId) != 0) {
SOFTBUS_PRINT("[DISCOVERY] ExitCoapListenThread pthread_join fail\n");
return;
}
}
#else
if (g_coapTaskId != -1) {
int ret = pthread_join((pthread_t)g_coapTaskId, NULL);
if (ret != 0) {
SOFTBUS_PRINT("[DISCOVERY] ExitCoapListenThread pthread_join fail\n");
return;
}
}
#endif
}
int CoapInitDiscovery(void)
{
int ret = CoapInitSocket();
if (ret != NSTACKX_EOK) {
SOFTBUS_PRINT("[DISCOVERY] Init socket fail\n");
return ret;
}
ret = CoapInitWifiEvent();
if (ret != NSTACKX_EOK) {
SOFTBUS_PRINT("[DISCOVERY] Init wifi event fail\n");
return ret;
}
#if defined(__LITEOS_A__)
ret = CreateQueryIpThread();
if (ret != NSTACKX_EOK) {
SOFTBUS_PRINT("[DISCOVERY] Init query Ip fail\n");
return ret;
}
#endif
if (CreateMsgQueThread() != NSTACKX_EOK) {
return NSTACKX_EFAILED;
}
return CreateCoapListenThread();
}
int CoapDeinitDiscovery(void)
{
ExitCoapListenThread();
int rtn = CoapDeinitWifiEvent();
if (rtn != NSTACKX_EOK) {
return NSTACKX_EFAILED;
}
#if defined(__LITEOS_A__)
ExitQueryIpThread();
#endif
CoapDeinitSocket();
return NSTACKX_EOK;
}
int CheckIpIsValid(const char *ip, int length)
{
if (ip == NULL || length < IP_MIN_LEN || length > IP_MAX_LEN) {
return -1;
}
if (strcmp(ip, "0.0.0.0") == 0) {
return -1;
}
int pos = length - 1;
if (ip[pos] == '1' && ip[pos - 1] == '.') {
return -1;
}
return 0;
}
void CoapGetIp(char *ip, int length, int finite)
{
if (ip == NULL || length != NSTACKX_MAX_IP_STRING_LEN) {
return;
}
g_queryIpFlag = 1;
int count = finite ? GET_IP_TIMES : GET_IP_INFINITE;
while (g_queryIpFlag) {
CoapGetWifiIp(ip, length);
if (CheckIpIsValid(ip, strlen(ip)) == 0) {
break;
}
if (count == 0) {
break;
}
count--;
usleep(TEN_MS);
}
return;
}