本帖最后由 小熊派开源社区 于 2020-2-27 08:48 编辑
1. LiteOS OC COAP 抽象组件
概述
为了适应各种各样的使用coap接入华为OC的模式,特采用该层次接口,对上提供应用所需的接口,对下允许接入方式的灵活适配。 OC COAP AL的api接口声明在中,使用相关的接口需要包含该头文件。
配置并连接
对接服务器的所有信息保存在结构体oc_coap_al.h 中,如下: 其中boot_mode是对接模式,对应华为平台的两种模式:
- typedef enum
- {
- en_oc_boot_strap_mode_factory = 0,
- en_oc_boot_strap_mode_client_initialize,
- en_oc_boot_strap_mode_sequence,
- }en_oc_boot_strap_mode_t;
复制代码
app_server参数是服务器信息,定义如下:
- typedef struct
- {
- char *ep_id; ///< endpoint identifier, which could be recognized by the server
- char *address; ///< server address,maybe domain name
- char *port; ///< server port
- char *psk_id; ///< server encode by psk, if not set NULL here
- char *psk;
- int psk_len;
- }oc_server_t;
复制代码
参数说明如下: - ep_id:设备标识符
- address:服务器地址
- port:服务器端口
- psk_id:DTLS使用,不使用的话设置为NULL
rcv_func是回调函数的函数指针,当设备接收到coap消息后回调:
- typedef int (*fn_oc_coap_msg_deal)(void *msg, int len);
复制代码
在配置结构体完成之后,调用配置函数进行配置并连接,API如下:
- /**
- * [url=home.php?mod=space&uid=2666770]@Brief[/url] the application use this function to configure the coap agent
- * @param[in] param, refer to tag_oc_coap_config
- * [url=home.php?mod=space&uid=1141835]@Return[/url] oc coap handle else NULL failed
- */
- void *oc_coap_config(oc_config_param_t *param);
复制代码
函数参数很清楚,将存放对接信息的结构体指针传入即可,API的返回值是oc coap handle指针,后续使用。
数据上报
连接成功之后,因为平台部署了编解码插件,直接向华为云平台上报二进制数据即可,oc_coap提供的API如下:
- /**
- * @brief the application use this function to send the message to the cdp
- * @param[in] hanlde:the coap handle returned by oc_coap_config
- * @param[in] report:the message to report
- *
- * @return 0 success while <0 failed
- */
- int oc_coap_report(void *handle,char *msg,int len);
复制代码
命令接收当OC平台发布该主题数据时,oc_coap组件会拉起接收回调函数将数据保存,进而用户解析接收到的数据即可。 oc_coap组件自动初始化在SDK目录中的IoT_LINK_1.0.0iot_linklink_main.c中可以看到自动初始化函数:
2. 配置准备
Makefile配置
因为本次实验用到的组件较多: - AT框架
- ESP8266设备驱动
- 串口驱动框架
- SAL组件
- coap组件
- oc_coap组件
这些实验代码全部编译下来,有350KB,而小熊派开发板所使用的主控芯片STM32L431RCT6的 Flash 仅有256KB,会导致编译器无法链接出可执行文件,所以要在makefile中修改优化选项,修改为-Os参数,即最大限度的优化代码尺寸,并去掉-g参数,即代码只能下载运行,无法调试,如图:
ESP8266设备配置在工程目录中的OS_CONFIG/iot_link_config.h文件中,配置ESP8266设备的波特率和设备名称: SDK:C:UsersAdministrator.icodesdkIoT_LINK_1.0.0(其中Administrator是实验电脑的用户名)。 在SDK目录中的<iot_linknetworktcpipesp8266_socketesp8266_socket_imp.c文件中,配置连接信息: 在 Demo 文件夹下创建cloud_test_demo文件夹,在其中创建oc_coap_demo.c文件。 编写以下代码:
- #include
- #include
- #include
- #include
- #define cn_endpoint_id "654654654"
- #define cn_app_server "49.4.85.232"
- #define cn_app_port "5683"
- #define cn_app_light 0
- #define cn_app_ledcmd 1
- #pragma pack(1)
- typedef struct
- {
- int8_t msgid;
- uint16_t intensity;
- }app_light_intensity_t;
- typedef struct
- {
- int8_t msgid;
- char led[3];
- }app_led_cmd_t;
- #pragma pack()
- #define cn_app_rcv_buf_len 128
- static int8_t s_rcv_buffer[cn_app_rcv_buf_len];
- static int s_rcv_datalen;
- static osal_semp_t s_rcv_sync;
- static void *s_coap_handle = NULL;
- static int app_msg_deal(void *msg, int len)
- {
- int ret = -1;
- if(len <= cn_app_rcv_buf_len)
- {
- memcpy(s_rcv_buffer,msg,len);
- s_rcv_datalen = len;
- osal_semp_post(s_rcv_sync);
- ret = 0;
- }
- return ret;
- }
- static int app_cmd_task_entry()
- {
- int ret = -1;
- app_led_cmd_t *led_cmd;
- int8_t msgid;
- while(1)
- {
- if(osal_semp_pend(s_rcv_sync,cn_osal_timeout_forever))
- {
- msgid = s_rcv_buffer[0];
- switch (msgid)
- {
- case cn_app_ledcmd:
- led_cmd = (app_led_cmd_t *)s_rcv_buffer;
- printf("LEDCMD:msgid:%d msg:%s nr",led_cmd->msgid, led_cmd->led);
- if (led_cmd->led[0] == 'o' && led_cmd->led[1] == 'n')
- {
- printf("--------------- LED ON! --------------------rn");
- }
- else if (led_cmd->led[0] == 'o' && led_cmd->led[1] == 'f' && led_cmd->led[2] == 'f')
- {
- printf("--------------- LED OFF! --------------------rn");
- }
- else
- {
- }
- break;
- default:
- break;
- }
- }
- }
- return ret;
- }
- static int app_report_task_entry()
- {
- int ret = -1;
- int lux = 0;
- oc_config_param_t oc_param;
- app_light_intensity_t light;
- memset(&oc_param,0,sizeof(oc_param));
- oc_param.app_server.address = cn_app_server;
- oc_param.app_server.port = cn_app_port;
- oc_param.app_server.ep_id = cn_endpoint_id;
- oc_param.boot_mode = en_oc_boot_strap_mode_factory;
- oc_param.rcv_func = app_msg_deal;
- s_coap_handle = oc_coap_config(&oc_param);
- if(NULL != s_coap_handle)
- {
- while(1)
- {
- lux++;
- lux= lux%10000;
- printf("lux is %d!rn",lux);
- light.msgid = cn_app_light;
- light.intensity = htons(lux);
- oc_coap_report(s_coap_handle,(char *)&light,sizeof(light));
- osal_task_sleep(5*1000);
- }
- }
- return ret;
- }
- int standard_app_demo_main()
- {
- osal_semp_create(&s_rcv_sync,1,0);
- osal_task_create("app_report",app_report_task_entry,NULL,0x1000,NULL,2);
- osal_task_create("app_command",app_cmd_task_entry,NULL,0x1000,NULL,3);
- return 0;
- }
复制代码
添加路径在user_demo.mk中添加如下:
- #example for oc_coap_demo
- ifeq ($(CONFIG_USER_DEMO), "oc_coap_demo")
- user_demo_src = ${wildcard $(TOP_DIR)/targets/STM32L431_BearPi/Demos/cloud_test_demo/oc_coap_demo.c}
- endif
复制代码
添加位置如下:
配置.sdkconfig
上报数据实验结果编译,下载,在云端的实验现象如下:
在本地的实验现象如下:
命令下发实验结果
在云端下发“on”命令:
在串口助手中可以看到:
下发“off”命令:
在串口助手中可以看到:
0
|
|
|
|