本文共 3814 字,大约阅读时间需要 12 分钟。
Lwm2m对应的client的cmake如下:#从这里可以build的是Lwm2m的clientproject (lwm2mclient C)#关掉DTSoption(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 9lwm2m_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_checkReadableuint8_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; } } }}
转载地址:http://kvnmi.baihongyu.com/