往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)
✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?
✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~
✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?
✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
✏️ 记录一场鸿蒙开发岗位面试经历~
✏️ 持续更新中……
(一)前言
之前已经介绍了nstackx_device.c中用到的设备信息结构体以及在头文件中声明的功能函数。 nstackx_device(一) 下面对函数定义进行具体标注。
(二)函数功能详解
声明三个静态变量,保存设备信息、设备网络接口信息与网络类型
static DeviceInfo g_localDeviceInfo; //设备信息
static NetworkInterfaceInfo g_interfaceList[NSTACKX_MAX_INTERFACE_NUM]; //设备网络接口信息
static char g_networkType[NETWORKTYPE_LENGTH] = {0}; //网络类型
清除本地数据信息
void ClearLocalData(void)
{
//清除本地设备信息,每项设置为0
memset_s(&g_localDeviceInfo, sizeof(g_localDeviceInfo), 0, sizeof(g_localDeviceInfo));
//清除本地设备网络接口信息
memset_s(&g_interfaceList, sizeof(g_interfaceList), 0, sizeof(g_interfaceList));
//清除网络类型
memset_s(g_networkType, sizeof(g_networkType), 0, sizeof(g_networkType));
}
下面几个函数都是获取本地数据信息: 函数功能:获取本地设备网络接口信息
static const NetworkInterfaceInfo *GetLocalInterface(void)
{
/* Ethernet have higher priority */
//网络为以太网,返回相应以太网接口信息
if (g_interfaceList[NSTACKX_ETH_INDEX].ip.s_addr) {
return &g_interfaceList[NSTACKX_ETH_INDEX];
}
//无线网,返回无线相应接口信息
if (g_interfaceList[NSTACKX_WLAN_INDEX].ip.s_addr) {
return &g_interfaceList[NSTACKX_WLAN_INDEX];
}
return NULL;
}
函数功能:获取本地IP 函数参数: ip: 用来保存获取的ip信息
static void GetLocalIp(struct in_addr *ip)
{
//获取本地接口
const NetworkInterfaceInfo *ifInfo = GetLocalInterface();
if (ifInfo != NULL) {
//将ip地址复制到参数ip中
(void)memcpy_s(ip, sizeof(struct in_addr),
&ifInfo->ip, sizeof(struct in_addr));
} else {
//不是以太网或者无线网,IP设置为0
(void)memset_s(ip, sizeof(struct in_addr), 0, sizeof(struct in_addr));
}
}
函数功能:获取ip的点分十进制表示 函数参数: ipstring:用来保存点分十进制的ip length: 指定分配内存的大小 函数返回:成功返回0,否则返回-1
int GetLocalIpString(char *ipString, size_t length)
{
struct in_addr ip;
//获取本地ip
GetLocalIp(&ip);
if (ip.s_addr == 0) {
return NSTACKX_EFAILED;
}
//二进制转为点分十进制 ip-->ipstring ,length指定分配内存的大小
if (inet_ntop(AF_INET, &ip, ipString, length) == NULL) {
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
函数功能: 获取本地设备信息
const DeviceInfo *GetLocalDeviceInfo(void)
{
return &g_localDeviceInfo;
}
函数功能:更新本地网络接口 函数参数: interfaceInfo: 新接口信息 函数返回值: 成功返回0,否则返回非零
int UpdateLocalNetworkInterface(const NetworkInterfaceInfo *interfaceInfo)
{
int ret;
uint32_t i;
struct in_addr preIp, newIp; //旧ip与新ip
if (interfaceInfo == NULL) {
return NSTACKX_EINVAL;
}
GetLocalIp(&preIp); //得到旧的iP
//找到要更新的接口
for (i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
//如果找到对应的接口,且接口为以太网或者无线网接口
if (NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[i].name)
&& (i == NSTACKX_ETH_INDEX || i == NSTACKX_WLAN_INDEX)) {
//用参数interfaceInfo中的IP对本地接口列表中相应的接口ip更新
ret = memcpy_s(&g_interfaceList[i].ip, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr));
if (ret != EOK) {
return NSTACKX_EINVAL;
}
break;
}
}
//如果i==最大接口数目,代表接口列表中没有名为interfaceInfo->name的接口
if (i == NSTACKX_MAX_INTERFACE_NUM) {
return NSTACKX_EINVAL;
}
GetLocalIp(&newIp); //得到更新后的ip
//新ip等于旧ip
if (newIp.s_addr == preIp.s_addr) {
return NSTACKX_EOK;
}
//
if (interfaceInfo->ip.s_addr == 0) {
//g_networkType不等于interfaceInfo->name且g_networkType不为空
if (strcmp(g_networkType, interfaceInfo->name) != 0 && strcmp(g_networkType, "") != 0) {
return NSTACKX_EOK;
}
} else {
//更新网络类型
ret = strncpy_s(g_networkType, sizeof(g_networkType), interfaceInfo->name, strlen(interfaceInfo->name));
if (ret != EOK) {
return NSTACKX_EFAILED;
}
}
return NSTACKX_EOK;
}
配置本地设备信息,通过一个本地设备信息结构体NSTACKX_LocalDeviceInfo来配置g_localDeviceInfo。 函数功能:配置本地设备信息 函数参数: localDeviceInfo: 用来配置g_localDeviceInfo 函数返回值: 成功返回0,否则返回非零
int ConfigureLocalDeviceInfo(const NSTACKX_LocalDeviceInfo *localDeviceInfo)
{
//设备id
char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
//二进制网络字节序IP地址
struct in_addr ipAddr;
//网络接口信息
NetworkInterfaceInfo interfaceInfo;
//
(void)memset_s(&interfaceInfo, sizeof(interfaceInfo), 0, sizeof(interfaceInfo));
(void)memcpy_s(deviceId, sizeof(deviceId), g_localDeviceInfo.deviceId, sizeof(deviceId));
//如果字符串的复制没有成功
if (strcpy_s(g_localDeviceInfo.deviceId, sizeof(g_localDeviceInfo.deviceId), localDeviceInfo->deviceId) != EOK) {
//进行一般内存的复制
if (memcpy_s(g_localDeviceInfo.deviceId, sizeof(g_localDeviceInfo.deviceId),
deviceId, sizeof(deviceId)) != EOK) {
}
return NSTACKX_EINVAL;
}
//将点分十进制地址转为二进制网络字节序的IP地址,并将网络名复制到接口信息name中
if ((inet_pton(AF_INET, localDeviceInfo->networkIpAddr, &ipAddr) == 1) &&
(strcpy_s(interfaceInfo.name, sizeof(interfaceInfo.name), localDeviceInfo->networkName) == EOK)) {
interfaceInfo.ip = ipAddr; //将网络字节序ip地址赋值给接口信息中的ip
UpdateLocalNetworkInterface(&interfaceInfo); //用得到的interfaceInfo更新本地设备接口信息
}
//如果配置设备信息中的设备名中为空,或者配置设备名时错误
if (strlen(localDeviceInfo->name) == 0 || (strncpy_s(g_localDeviceInfo.deviceName,
sizeof(g_localDeviceInfo.deviceName), localDeviceInfo->name, NSTACKX_MAX_DEVICE_NAME_LEN - 1) != EOK)) {
//使用默认设备名
(void)strcpy_s(g_localDeviceInfo.deviceName, sizeof(g_localDeviceInfo.deviceName), NSTACKX_DEFAULT_DEVICE_NAME);
}
//配置设备版本信息
if (strcpy_s(g_localDeviceInfo.version, sizeof(g_localDeviceInfo.version), localDeviceInfo->version) != EOK) {
return NSTACKX_EINVAL;
}
//设置设备类型
g_localDeviceInfo.deviceType = localDeviceInfo->deviceType;
return NSTACKX_EOK;
}
最后就是对设备功能和服务数据的注册 函数功能:注册设备功能 函数参数: capabilityBitmapNum:功能位图数量 capabilityBitmap : 用于设置g_localDeviceInfo中capabilityBitmap功能位图 函数返回值: 成功返回0,否则非零
int RegisterCapability(uint32_t capabilityBitmapNum, const uint32_t capabilityBitmap[])
{
//为g_localDeviceInfo中capabilityBitmap分配空间并初始化为0
(void)memset_s(g_localDeviceInfo.capabilityBitmap, sizeof(g_localDeviceInfo.capabilityBitmap),
0, sizeof(g_localDeviceInfo.capabilityBitmap));
//如果capabilityBitmapNum不为0
if (capabilityBitmapNum) {
//将所有功能位图复制到g_localDeviceInfo.capabilityBitmap
if (memcpy_s(g_localDeviceInfo.capabilityBitmap, sizeof(g_localDeviceInfo.capabilityBitmap),
capabilityBitmap, sizeof(uint32_t) * capabilityBitmapNum) != EOK) {
return NSTACKX_EFAILED;
}
}
//更新g_localDeviceInfo.capabilityBitmapNum
g_localDeviceInfo.capabilityBitmapNum = capabilityBitmapNum;
return NSTACKX_EOK;
}
函数功能: 注册服务数据 函数参数: serviceData:服务数据 length: 数据长度 函数返回值: 成功返回0,否则返回非零
int RegisterServiceData(const char* serviceData, int length)
{
//服务数据为空
if (serviceData == NULL) {
return NSTACKX_EINVAL;
}
//分配存储服务数据的空间,并初始化为0
(void)memset_s(g_localDeviceInfo.serviceData, sizeof(g_localDeviceInfo.serviceData),
0, sizeof(g_localDeviceInfo.serviceData));
//将服务数据复制到设备信息服务数据属性中
if (strcpy_s(g_localDeviceInfo.serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, serviceData) != EOK) {
return NSTACKX_EFAILED;
}
(void)length;
return NSTACKX_EOK;
}