📌往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)
①📖 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?
②📖嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~
③📖 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?
④📖 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
⑤📖 记录一场鸿蒙开发岗位面试经历~
⑥📖 持续更新中……
前言
上篇coap_service.c代码中基本上每个接口函数都调用了nstackx_common.c中的接口,最终nstackx_common.c中的接口函数再调用coap_discover.c中的接口函数。所以coap_service.c中的接口函数是对外提供的顶层接口,分析过程也是从顶层宏观调用到下层实现细节。
nstackx_common.c分析
首先,初始过程中有三种状态:初始化开始,初始化进行中,初始化完成。
enum {
NSTACKX_INIT_STATE_START = 0,
NSTACKX_INIT_STATE_ONGOING,
NSTACKX_INIT_STATE_DONE,
};
其中使用一个8位无符号数来表示初始化过程中状态的变化static uint8_t g_nstackInitState = NSTACKX_INIT_STATE_START;
初始化函数NSTACKX_Init
/*
函数功能: 为coao发现前期初始化
函数参数: 无
函数返回值: 成功或者已经初始化返回0,否则返回非零
详细:
1.首先设置初始化状态为初始化正在进行
2.调用cJSON_InitHooks为cJSON提供malloc, realloc和free函数(使用默认malloc,free)
3.调用CoapInitDiscovery,初始化coap发现的参数和结构(coap socket g_serverFd message id,coap wifi 事件,消息队列线程,coap监听线程)
4.上述过程成功之后,要将初始状态设置初始化完成,否则就需要调用NSTACKX_Deinit恢复为原始状态
*/
int NSTACKX_Init()
{
int ret;
if (g_nstackInitState != NSTACKX_INIT_STATE_START) {
return NSTACKX_EOK;
}
g_nstackInitState = NSTACKX_INIT_STATE_ONGOING;
//为cJSON提供malloc, realloc和free函数
cJSON_InitHooks(NULL);
ret = CoapInitDiscovery();
if (ret != NSTACKX_EOK) {
goto L_ERR_INIT;
}
g_nstackInitState = NSTACKX_INIT_STATE_DONE;
return NSTACKX_EOK;
//如果上述一步出错那么就需要恢复为原始状态
L_ERR_INIT:
ret = NSTACKX_Deinit();
if (ret != NSTACKX_EOK) {
SOFTBUS_PRINT("[DISCOVERY] deinit fail\n");
}
return NSTACKX_EFAILED;
}
反初始化NSTACKX_Deinit
/*
函数功能: 反初始化,释放各种资源和数据
函数参数: 无
函数返回值:成功返回0,否则返回非零
详细:
1. 首先先判断初始状态g_nstackInitState,如果为NSTACKX_INIT_STATE_START,表示根本没有初始化过
2. 调用CoapDeinitDiscovery,释放Coap发现所分配的资源和数据(关闭coap监听线程,销毁wifi事件,释放socket套接字)
3. 清除本地信息(本地设备信息,网络接口信息,网络类型)
4. 最后所有资源数据释放之后,将初始化状态设置为原始状态NSTACKX_INIT_STATE_START
*/
int NSTACKX_Deinit(void)
{
if (g_nstackInitState == NSTACKX_INIT_STATE_START) {
return NSTACKX_EOK;
}
int ret = CoapDeinitDiscovery();
if (ret != NSTACKX_EOK) {
return ret;
}
ClearLocalData();
g_nstackInitState = NSTACKX_INIT_STATE_START;
return NSTACKX_EOK;
}
/*
函数功能: 注册设备
函数参数:
1.localDeviceInfo: 本地设备信息
2. deviceHash : 设备hash
函数返回值: 成功返回0,否则非零
详细:
1. 判断是否已经初始化完毕了
2、 判断本地设备信息是否为空
3、 使用localDeviceInfo配置本地设备信息g_localDeviceInfo
4、 设置设备Hash
*/
int NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash)
{
//如果还没初始化完成
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
return NSTACKX_EFAILED;
}
//本地设备信息为空
if (localDeviceInfo == NULL) {
return NSTACKX_EINVAL;
}
//配置本地设备信息
if (ConfigureLocalDeviceInfo(localDeviceInfo) != NSTACKX_EOK) {
return NSTACKX_EINVAL;
}
//设置设备的哈希值
SetDeviceHash(deviceHash);
return NSTACKX_EOK;
}
/*
函数功能: 初始化之后需要去设置设备功能
函数参数:
1.capabilityBitmapNum : 功能数量
2. capabilityBitmap : 保存了功能位图
函数返回值: 成功返回0,否则返回非零
详细 :
1. 判断是否已经初始化完毕了
2. 判断功能数量是否大于设备所可以拥有的最大功能数量
3. 调用RegisterCapability,去设置设备功能
*/
int NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, const uint32_t capabilityBitmap[])
{
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
return NSTACKX_EFAILED;
}
if (capabilityBitmapNum > NSTACKX_MAX_CAPABILITY_NUM) {
return NSTACKX_EINVAL;
}
if (RegisterCapability(capabilityBitmapNum, capabilityBitmap) != NSTACKX_EOK) {
return NSTACKX_EINVAL;
}
return NSTACKX_EOK;
}
/*
函数功能:设置设备服务数据
函数参数:
serviceData: 服务数据
函数返回值: 成功返回0,否则返回非零
详细:
1. 检查服务数据是否为空
2. 检查设备是否已经初始化完毕
3. 检查服务数据长度是否大于最大服务数据长度
4. 调用RegisterServiceData,设置g_localDeviceInfo中的serviceData
*/
int NSTACKX_RegisterServiceData(const char* serviceData)
{
if (serviceData == NULL) {
return NSTACKX_EINVAL;
}
//如果设备初始化过了
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
return NSTACKX_EFAILED;
}
//服务数据长度
unsigned int serviceLen = strlen(serviceData);
if (serviceLen >= NSTACKX_MAX_SERVICE_DATA_LEN) {
return NSTACKX_EINVAL;
}
if (RegisterServiceData(serviceData, serviceLen + 1) != NSTACKX_EOK) {
return NSTACKX_EINVAL;
}
return NSTACKX_EOK;
}