# 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亿个设备连接到物联网上,在多个操作系统和平台上提供安全可靠的设备发现和连接。


### CoAP协议
CoAP(Constrained Application Protocol)是一种在物联网世界的类web协议,它的详细规范定义在 RFC 7252。CoAP名字翻译来就是“受限应用协议”,顾名思义,使用在资源受限的物联网设备上。
#### CoAP协议的抽象层次

#### 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握手流程

### 证书
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,如下图所示:



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小时