Lwm2m的client分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
            }
        }
    }

}

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/86759593
M2M