# ocf **Repository Path**: oneos-ability/ocf ## Basic Information - **Project Name**: ocf - **Description**: Open Connectivity Foundation - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-08-29 - **Last Updated**: 2024-03-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OCF-V2.2.0 - [OCF-V2.2.0](#ocf-v220) - [简介](#简介) - [CoAP协议](#coap协议) - [CoAP协议的抽象层次](#coap协议的抽象层次) - [CoAP协议的特点](#coap协议的特点) - [DTLS协议](#dtls协议) - [DTLS握手流程](#dtls握手流程) - [证书](#证书) - [OCF重要数据结构](#ocf重要数据结构) - [OCF server参数](#ocf-server参数) - [OCF server资源参数](#ocf-server资源参数) - [OCF server API](#ocf-server-api) - [oc_init_platform](#oc_init_platform) - [oc_add_device](#oc_add_device) - [oc_new_resource](#oc_new_resource) - [oc_resource_bind_resource_type](#oc_resource_bind_resource_type) - [oc_resource_set_discoverable](#oc_resource_set_discoverable) - [oc_resource_set_periodic_observable](#oc_resource_set_periodic_observable) - [oc_resource_set_request_handler](#oc_resource_set_request_handler) - [oc_add_resource](#oc_add_resource) - [oc_main_init](#oc_main_init) - [oc_main_poll](#oc_main_poll) - [oc_main_shutdown](#oc_main_shutdown) - [OCF配置选项](#ocf配置选项) - [OCF配置入口](#ocf配置入口) - [OCF配置参数说明](#ocf配置参数说明) - [OCF示例](#ocf示例) - [简单的demo:light ocf server](#简单的demolight-ocf-server) - [STM32H743开发板OCF工程配置步骤](#stm32h743开发板ocf工程配置步骤) ## 简介 OCF(Open Connectivity Foundation)致力于通过提供标准的通信平台、桥接规范、开放源码实现和允许设备通信的认证程序来确保消费者、企业和工业的安全互操作性,而不需要考虑操作系统、服务提供商、传输技术或生态系统。参与OCF的都是行业领先公司,成员包括英特尔、微软、高通和海尔等,相信安全可靠的设备发现和连接是实现物联网的基础组件。OCF的理想是将未来250亿个设备连接到物联网上,在多个操作系统和平台上提供安全可靠的设备发现和连接。 ![ocf1](./images/ocf1.png) ![ocf2](./images/ocf2.png) ### CoAP协议 CoAP(Constrained Application Protocol)是一种在物联网世界的类web协议,它的详细规范定义在 RFC 7252。CoAP名字翻译来就是“受限应用协议”,顾名思义,使用在资源受限的物联网设备上。 #### CoAP协议的抽象层次 ![coap](./images/coap.png) #### CoAP协议的特点 1.满足资源受限的网络需求。 2.无状态HTTP映射,可以通过HTTP代理实现访问CoAP资源,或者在CoAP智商构建HTTP接口。 3.使用UDP实现可靠IP单播和最大努力IP多播。 4.异步消息交换 5.很小的消息头载荷及解析复杂度。 6.支持URI和内容类型(Content-type). 7.支持代理和缓存. 8.内建资源发现. 9.可以使用DTLS作为安全加密层。 10.资源消耗低,所需RAM和ROM资源均小于10KB。 11.其双层(事务层,请求/响应层)处理方式可支持异步通信. 12.支持观察模式。 13.支持块传输 ### DTLS协议 DTLS(Datagram Transport Layer Security)即数据包传输层安全性协议。TLS不能用来保证UDP上传输的数据的安全,因此Datagram TLS试图在现存的TLS协议架构上提出扩展,使之支持UDP,即成为TLS的一个支持数据包传输的版本。 #### DTLS握手流程 ![dtls](./images/dtls.png) ### 证书 OCF通过DLTS保证通信数据安全,支持PKI和NOPKI两种模式 PKI模式通过证书进行认证,临时证书有效期为1个月,测试时生成临时证书方法为在linux或者windows命令行下执行以下命令(下面命令需要设备有curl和python命令,且python版本为3.X): ``` cd components\ocf\port\pki\ .\pki.sh ``` 上面命令生成的pki_certs.zip.h替换源码中的thirdparty/ocf/iotivity-lite-2.2.0/include/pki_certs.h ## OCF重要数据结构 ### OCF server参数 ```c typedef struct { int (*init)(void); //应用初始化回调 void (*signal_event_loop)(void); #ifdef OC_SERVER void (*register_resources)(void); //ocf server注册资源回调 #endif /* OC_SERVER */ #ifdef OC_CLIENT void (*requests_entry)(void); //ocf client注册接口回调 #endif /* OC_CLIENT */ } oc_handler_t; ``` ### OCF server资源参数 ```c struct oc_resource_s { struct oc_resource_s *next; size_t device; oc_string_t name; //资源名称 oc_string_t uri; //访问资源的uri oc_string_array_t types; //资源ocf类型 oc_interface_mask_t interfaces; //资源接口权限 oc_interface_mask_t default_interface; //资源接口默认权限 oc_resource_properties_t properties; oc_request_handler_t get_handler; //资源GET方法回调 oc_request_handler_t put_handler; //资源PUT方法回调 oc_request_handler_t post_handler; //资源POST方法回调 oc_request_handler_t delete_handler; //资源DELETE方法回调 oc_properties_cb_t get_properties; oc_properties_cb_t set_properties; double tag_pos_rel[3]; oc_pos_description_t tag_pos_desc; oc_enum_t tag_func_desc; uint8_t num_observers; #ifdef OC_COLLECTIONS uint8_t num_links; #endif /* OC_COLLECTIONS */ uint16_t observe_period_seconds; //观察时间间隔 }; ``` ## OCF server API | 接口 | 说明 | | ----------------------------------- | ----------------------------- | | oc_init_platform | 初始化设备硬件平台信息 | | oc_add_device | 添加设备信息 | | oc_new_resource | 新建一个设备资源 | | oc_resource_bind_resource_type | 绑定资源类型 | | oc_resource_bind_resource_interface | 绑定资源接口权限 | | oc_resource_set_discoverable | 设置资源可被发现 | | oc_resource_set_periodic_observable | 设置资源可被观察 | | oc_resource_set_request_handler | 设置资源URI访问回调 | | oc_add_resource | 添加资源到设备 | | oc_main_init | 初始化ocf主程序 | | oc_main_poll | 启动ocf poll任务,处理ocf消息 | | oc_main_shutdown | 关闭ocf主程序 | ### oc_init_platform 设备平台初始化接口,该函数主要初始化设备硬件平台相关信息。 ```c int oc_init_platform(const char *mfg_name, oc_init_platform_cb_t init_platform_cb, void *data); ``` | 参数 | 说明 | | ---------------- | -------------- | | mfg_name | 平台名称 | | init_platform_cb | 平台初始化回调 | | data | 平台初始化参数 | | **返回** | **说明** | | 0 | 执行成功 | | 其他 | 执行失败 | ### oc_add_device 添加ocf设备信息。 ```c int oc_add_device(const char *uri, const char *rt, const char *name, const char *spec_version, const char *data_model_version, oc_add_device_cb_t add_device_cb, void *data); ``` | 参数 | 说明 | | ------------------ | ------------ | | uri | 设备uri | | rt | 设备ocf标准 | | name | 设备名称 | | spec_version | ocf版本 | | data_model_version | 数据模型版本 | | add_device_cb | 添加设备回调 | | data | 设备信息 | | **返回** | **说明** | | 0 | 执行成功 | | 其他 | 执行失败 | ### oc_new_resource 创建设备资源。 ```c oc_resource_t *oc_new_resource(const char *name, const char *uri, uint8_t num_resource_types, size_t device); ``` | 参数 | 说明 | | ------------------ | ------------------ | | name | 资源名称 | | uri | 资源的uri | | num_resource_types | 资源类型 | | device | 添加资源的设备序号 | | **返回** | **说明** | | 非NULL | 执行成功 | | NULL | 执行失败 | ### oc_resource_bind_resource_type 绑定资源ocf类型。 ```c void oc_resource_bind_resource_type(oc_resource_t *resource, const char *type); ``` | 参数 | 说明 | | -------- | --------------------------------- | | resource | 资源信息,通过oc_new_resource创建 | | type | 资源在ocf的标准类型 | | **返回** | **说明** | | void | | ### oc_resource_set_discoverable 设置资源是否允许被发现。 ```c void oc_resource_set_discoverable(oc_resource_t *resource, bool state); ``` | 参数 | 说明 | | -------- | --------------------------------- | | resource | 资源信息,通过oc_new_resource创建 | | state | 是否允许被发现 | | **返回** | **说明** | | void | | ### oc_resource_set_periodic_observable 设置资源观察时间间隔。 ```c void oc_resource_set_periodic_observable(oc_resource_t *resource, uint16_t seconds) ``` | 参数 | 说明 | | -------- | --------------------------------- | | resource | 资源信息,通过oc_new_resource创建 | | seconds | 间隔时间 | | **返回** | **说明** | | void | | ### oc_resource_set_request_handler 设置资源请求操作回调。 ```c void oc_resource_set_request_handler(oc_resource_t *resource, oc_method_t method, oc_request_callback_t callback, void *user_data); ``` | 参数 | 说明 | | --------- | --------------------------------- | | resource | 资源信息,通过oc_new_resource创建 | | method | 请求方法 | | callback | 请求回调 | | user_data | 用户信息 | | **返回** | **说明** | | void | | ### oc_add_resource 添加资源到设备。 ```c bool oc_add_resource(oc_resource_t *resource); ``` | 参数 | 说明 | | -------- | --------------------------------- | | resource | 资源信息,通过oc_new_resource创建 | | **返回** | **说明** | | true | 执行成功 | | false | 执行失败 | ### oc_main_init ocf server初始化。 ```c int oc_main_init(const oc_handler_t *handler); ``` | 参数 | 说明 | | -------- | ------------------- | | handler | 参考OCF server参数 | | **返回** | **说明** | | 0 | 执行成功 | | 其他 | 执行失败 | ### oc_main_poll 执行ocf server poll处理消息。 ```c oc_clock_time_t oc_main_poll(void); ``` | 参数 | 说明 | | ------------------ | -------- | | void | | | **返回** | **说明** | | 到下一个事件的时间 | | ### oc_main_shutdown ocf server关闭。 ```c void oc_main_shutdown(void); ``` | 参数 | 说明 | | -------- | -------- | | void | | | **返回** | **说明** | | void | | ## OCF配置选项 使用OCF需要通过Menuconfig的图形化工具进行配置选择,配置的路径如下所示: ``` (Top) → Thirdparty→ Iotivity OneOS Configuration [*] Iotivity: OCF Iotivity library ocf device type (ocf air conditioner) ---> [*] Iotivity: OCF ipv4 support [*] Iotivity: OCF debug [*] Iotivity: OCF server [ ] Iotivity: OCF client [*] Iotivity: OCF security [*] Iotivity: OCF dynamic allocation [ ] Iotivity: OCF PKI [*] Iotivity: OCF use oneos 2.0 [ ] Iotivity: OCF use custom ram [ ] Iotivity: OCF use gui ``` ### OCF配置入口 ``` (Top) → Thirdparty→ Iotivity ``` ### OCF配置参数说明 Iotivity: OCF Iotivity library:启用ocf ocf device type:选择ocf示例设备类型 Iotivity: OCF ipv4 support:ipv4,默认打开 Iotivity: OCF debug:debug开关 Iotivity: OCF server:选择ocf以server模式启动 Iotivity: OCF client:选择ocf以client模式启动(暂不支持) Iotivity: OCF security:启动ocf安全模块 Iotivity: OCF dynamic allocation:动态内存,默认打开 Iotivity: OCF PKI:PKI开关 Iotivity: OCF use oneos 2.0:支持oneos 2.0 Iotivity: OCF use custom ram:用户自定义ram相关接口 Iotivity: OCF use gui:GUI开关(暂不支持) ## OCF示例 ### 简单的demo:light ocf server ```c static void post_light(oc_request_t *request, oc_interface_mask_t iface_mask, void *user_data) { (void)iface_mask; (void)user_data; PRINT("POST_light:\n"); oc_rep_t *rep = request->request_payload; while (rep != NULL) { PRINT("key: %s ", oc_string(rep->name)); switch (rep->type) { case OC_REP_BOOL: state = rep->value.boolean; PRINT("value: %d\n", state); set_led(); break; case OC_REP_INT: power = (int)rep->value.integer; PRINT("value: %d\n", power); break; case OC_REP_STRING: oc_free_string(&name); oc_new_string(&name, oc_string(rep->value.string), oc_string_len(rep->value.string)); break; default: oc_send_response(request, OC_STATUS_BAD_REQUEST); return; } rep = rep->next; } oc_send_response(request, OC_STATUS_CHANGED); } static void put_light(oc_request_t *request, oc_interface_mask_t iface_mask, void *user_data) { post_light(request, iface_mask, user_data); } static void get_light(oc_request_t *request, oc_interface_mask_t iface_mask, void *user_data) { (void)user_data; ++power; PRINT("GET_light:\n"); oc_rep_start_root_object(); switch (iface_mask) { case OC_IF_BASELINE: oc_process_baseline_interface(request->resource); case OC_IF_RW: oc_rep_set_boolean(root, state, state); oc_rep_set_int(root, power, power); oc_rep_set_text_string(root, name, oc_string(name)); break; default: break; } oc_rep_end_root_object(); oc_send_response(request, OC_STATUS_OK); } static int app_init(void) { int ret = oc_init_platform("Intel", NULL, NULL); ret |= oc_add_device("/oic/d", "oic.d.light", "Sword's Lamp", "ocf.1.0.0", "ocf.res.1.0.0", NULL, NULL); oc_new_string(&name, "Sword's Light", 12); return ret; } static void signal_event_loop(void) { os_sem_post(&block); } static void register_resources(void) { oc_resource_t *res = oc_new_resource(NULL, "/a/light", 2, 0); oc_resource_bind_resource_type(res, "core.light"); oc_resource_bind_resource_type(res, "core.brightlight"); oc_resource_bind_resource_interface(res, OC_IF_RW); oc_resource_set_default_interface(res, OC_IF_RW); oc_resource_set_discoverable(res, true); oc_resource_set_periodic_observable(res, 1); oc_resource_set_request_handler(res, OC_GET, get_light, NULL); oc_resource_set_request_handler(res, OC_PUT, put_light, NULL); oc_resource_set_request_handler(res, OC_POST, post_light, NULL); oc_add_resource(res); } void ocf_server_init(void) { oc_set_max_app_data_size(0x4000); // signal(SIGINT, handle_signal); static const oc_handler_t handler = { .init = app_init, .signal_event_loop = signal_event_loop, .register_resources = register_resources }; os_sem_init(&block, "ocf_sem", 0, 1); #ifdef OC_STORAGE oc_storage_config(""); #endif /* OC_STORAGE */ if (oc_main_init(&handler) < 0) return; int wait_tick; while (true) { next_tick = oc_main_poll(); if (next_tick == 0) wait_tick = OS_WAIT_FOREVER; else { now_tick = oc_clock_time(); wait_tick = next_tick - now_tick; if (wait_tick < 0) wait_tick = OS_WAIT_FOREVER; } os_sem_wait(&block, wait_tick); } oc_main_shutdown(); } ``` ### STM32H743开发板OCF工程配置步骤 基于ONEOS 2.0的stm32h743-atk-apollo标准模板进行OCF工程menuconfig配置 1.(Top) → Drivers→ SPI下关闭全部SPI选项 2.(Top) → Drivers→ Sensors下关闭全部sensor选项 3.(Top) → Drivers→ Serials下将串口的RX buffer size设置为8192,其他不变 4.(Top) → Drivers→ HAL下关闭eth 5.(Top) → Components→ Network→ TCP/IP→ LwIP下关闭lwip 6.(Top) → Components→ Network→ Socket下打开Enable BSD socket API选项 7.(Top) → Components→ Network→ Molink下打开Enable IoT modules support 8.(Top) → Components→ Network→ Molink→ Enable IoT modules support → Module→ WiFi Modules Support→ ESP8266 → ESP8266 Config下进行ESP8266配置,除了Enable ESP8266 Module IPV6 Operates和Enable ESP8266 Module Hardware Control Operates之外,其他的选项全部打开,串口设置为uart3,ssid和passwd设置为自己用的wifi,其他选项用默认值 9.(Top) → Thirdparty→ Iotivity下打开Iotivity: OCF Iotivity library选项,ocf device type选择air conditioner,后面的依次选中 Iotivity: OCF ipv4 support Iotivity: OCF debug Iotivity: OCF server Iotivity: OCF security Iotivity: OCF dynamic allocation Iotivity: OCF use oneos 2.0 10.(Top) → Components→ Dlog→ Enable dlog → The log global output level.下设置dlog日志级别为Warning 11.(Top) → Thirdparty→ Easyflash下关闭easyflash 12.打开\stm32h743-atk-apollo\board\CubeMX_Config\CubeMX_Config.ioc文件进行串口配置,依次打开USART3,配置引脚PB10, PB11,勾选终端,打开DMA,配置rx,如下图所示: ![cubemx1](./images/cubemx1.png) ![cubemx2](./images/cubemx2.png) ![cubemx3](./images/cubemx3.png) 13.保存并退出menuconfig,执行scons --ide=mdk5生成keil工程 14.打开keil工程,点击option按钮,进入工程option配置页,打开C/C++选项卡,勾选GNU extensions,将编译优化等级改为-O3,如果使用的ST-LINK,还需打开Debug选项卡,选择ST-Link Debugger,然后进入settings,打开Flash Download选项卡,点击下方的add按钮,添加flash,flash选择STM32H7x_2048即可,保存退出option 15.打开stm32h743-atk-apollo模板下board/ports/fal_cfg.c文件,修改分区配置为 ```c static const fal_part_info_t fal_part_info[] = { /* part, flash, addr, size, lock */ { "app", "onchip_flash", 0x00000000, 0x001C0000, FAL_PART_INFO_FLAGS_UNLOCKED}, { "ocf_data", "onchip_flash", 0x001C0000, 0x00040000, FAL_PART_INFO_FLAGS_UNLOCKED} }; ``` 16.编译工程,下载固件 17.OCF服务会自启动,任务名为ocf_server 【备注】: 1.每次执行scons --ide=mdk5生成工程后,需要重新执行第9步,也可以将第9步改动到keil工程template里面,这样就无需每次都去修改 2.esp8266模组需要使用特定的固件版本:AT version:2.1.0.0-dev,SDK version:v3.3-rc1-64-gfaae0a99,Bin version:2.0.0(WROOM-02) 3.执行pki用例前需要设置rtc时间,需要注意这里的时间为格林威治时间,具体值为:当前北京时间 - 8小时