版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tiantao2012/article/details/86759593
Lwm2m对应的client的cmake如下:
#从这里可以build的是Lwm2m的client
project (lwm2mclient C)
#关掉DTS
option(DTLS "Enable DTLS" OFF)
include(${CMAKE_CURRENT_LIST_DIR}/../../core/wakaama.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../shared/shared.cmake)
add_definitions(-DLWM2M_CLIENT_MODE -DLWM2M_BOOTSTRAP -DLWM2M_SUPPORT_JSON) add_definitions(${SHARED_DEFINITIONS} ${WAKAAMA_DEFINITIONS})
include_directories (${WAKAAMA_SOURCES_DIR} ${SHARED_INCLUDE_DIRS})
#client 包含的所有头文件如下:
SET(SOURCES ${CMAKE_CURRENT_LIST_DIR}/lwm2mclient.c
${CMAKE_CURRENT_LIST_DIR}/lwm2mclient.h
${CMAKE_CURRENT_LIST_DIR}/system_api.c
${CMAKE_CURRENT_LIST_DIR}/object_security.c
${CMAKE_CURRENT_LIST_DIR}/object_server.c
${CMAKE_CURRENT_LIST_DIR}/object_device.c
${CMAKE_CURRENT_LIST_DIR}/object_firmware.c
${CMAKE_CURRENT_LIST_DIR}/object_location.c
${CMAKE_CURRENT_LIST_DIR}/object_connectivity_moni.c
${CMAKE_CURRENT_LIST_DIR}/object_connectivity_stat.c
${CMAKE_CURRENT_LIST_DIR}/object_access_control.c
${CMAKE_CURRENT_LIST_DIR}/test_object.c
)
#这个工程是编译成一个可执行的文件
add_executable(${PROJECT_NAME} ${SOURCES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES})
从上面的分析可知,client的入口函数在lwm2mclient.c 中的main函数,其处理流程和server端的流程
基本类似,都是建立一个socket,然后在一个死循环中监听socket通信,处理package
有一点不同是在client的main函数中注册了很多object的处理函数
objArray[1] = get_server_object(serverId, "U", lifetime, false);
if (NULL == objArray[1])
{
fprintf(stderr, "Failed to create server object\r\n");
return -1;
}
这里的OBJ_COUNT 等于9 也就是说最多支持9中object
#define OBJ_COUNT 9
lwm2m_object_t * objArray[OBJ_COUNT];
我们举个例子看看object 都干了啥
lwm2m_object_t * get_server_object(int serverId,
const char* binding,
int lifetime,
bool storing)
{
lwm2m_object_t * serverObj;
#首先申请一个结构体
serverObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != serverObj)
{
server_instance_t * serverInstance;
memset(serverObj, 0, sizeof(lwm2m_object_t));
serverObj->objID = 1;
// Manually create an hardcoded server
serverInstance = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
if (NULL == serverInstance)
{
lwm2m_free(serverObj);
return NULL;
}
#初始化这个结构体成员变量
memset(serverInstance, 0, sizeof(server_instance_t));
serverInstance->instanceId = 0;
serverInstance->shortServerId = serverId;
serverInstance->lifetime = lifetime;
serverInstance->storing = storing;
memcpy (serverInstance->binding, binding, strlen(binding)+1);
serverObj->instanceList = LWM2M_LIST_ADD(serverObj->instanceList, serverInstance);
#重点是这里的几个回调函数
serverObj->readFunc = prv_server_read;
serverObj->discoverFunc = prv_server_discover;
serverObj->writeFunc = prv_server_write;
serverObj->createFunc = prv_server_create;
serverObj->deleteFunc = prv_server_delete;
serverObj->executeFunc = prv_server_execute;
}
return serverObj;
}
可见所以的object关键就是一组不动听的read/writer/create等回调函数
这样当clinet处理package的时候就会调用
lwm2m_handle_packet->handle_request->handle_request->object_checkReadable->observe_setParameters->object_checkReadable
uint8_t object_checkReadable(lwm2m_context_t * contextP,
lwm2m_uri_t * uriP,
lwm2m_attributes_t * attrP)
{
#最终读取每个object注册时候的回调函数
result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP);
if (result == COAP_205_CONTENT)
{
if (attrP->toSet & ATTR_FLAG_NUMERIC)
{
switch (dataP->type)
{
case LWM2M_TYPE_INTEGER:
case LWM2M_TYPE_FLOAT:
break;
default:
result = COAP_405_METHOD_NOT_ALLOWED;
}
}
}
}