支持BLE设备接入“腾讯连连”小程序
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
|
||||
demo_dir_prefix = 'qcloud-iot-ble-'
|
||||
script_path = os.path.split(os.path.realpath(__file__))[0]
|
||||
sdk_path = os.path.join(script_path, '..', '..')
|
||||
|
||||
|
||||
def extract_nrf2832(dest_dir):
|
||||
print('extract code for nrf52832 start, dest dir %s' % dest_dir)
|
||||
if os.path.exists(dest_dir):
|
||||
shutil.rmtree(dest_dir)
|
||||
shutil.copytree(os.path.join(sdk_path, 'samples', 'nrf52832'), dest_dir)
|
||||
|
||||
new_sdk_path = os.path.join(dest_dir, 'qcloud_iot_explorer_ble')
|
||||
shutil.copytree(os.path.join(sdk_path, 'inc'), os.path.join(new_sdk_path, 'inc'))
|
||||
shutil.copytree(os.path.join(sdk_path, 'src'), os.path.join(new_sdk_path, 'src'))
|
||||
print('extract code success')
|
||||
pass
|
||||
|
||||
|
||||
def extract_esp32(dest_dir):
|
||||
print('extract code for esp32, dest dir %s' % dest_dir)
|
||||
if os.path.exists(dest_dir):
|
||||
shutil.rmtree(dest_dir)
|
||||
shutil.copytree(os.path.join(sdk_path, 'samples', 'esp32'), dest_dir)
|
||||
|
||||
new_sdk_path = os.path.join(dest_dir, 'components', 'qcloud_llsync')
|
||||
shutil.copytree(os.path.join(sdk_path, 'inc'), os.path.join(new_sdk_path, 'inc'))
|
||||
shutil.copytree(os.path.join(sdk_path, 'src'), os.path.join(new_sdk_path, 'src'))
|
||||
|
||||
print('extract code success')
|
||||
pass
|
||||
|
||||
|
||||
def extract_lifesense(dest_dir):
|
||||
print('extract code for lifesense, dest dir %s' % dest_dir)
|
||||
if os.path.exists(dest_dir):
|
||||
shutil.rmtree(dest_dir)
|
||||
shutil.copytree(os.path.join(sdk_path, 'samples', 'lifesense'), dest_dir)
|
||||
|
||||
new_sdk_path = os.path.join(dest_dir, 'qcloud_iot_explorer_ble')
|
||||
shutil.copytree(os.path.join(sdk_path, 'inc'), os.path.join(new_sdk_path, 'inc'))
|
||||
shutil.copytree(os.path.join(sdk_path, 'src'), os.path.join(new_sdk_path, 'src'))
|
||||
|
||||
print('extract code success')
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print('\nUsage: python3 %s <platform> [dest dir]' % sys.argv[0])
|
||||
print('\nDefinitions:')
|
||||
print('<platform>\t%s' % 'Device type. The following are allowed: nrf52832, esp32, lefesense')
|
||||
print('[dest dir]\t%s %s\n' % ('Where the code stored. Default path: ', script_path))
|
||||
else:
|
||||
if len(sys.argv) == 2:
|
||||
dest_dir = os.path.join(script_path, demo_dir_prefix + sys.argv[1])
|
||||
else:
|
||||
dest_dir = os.path.join(sys.argv[2], demo_dir_prefix + sys.argv[1])
|
||||
|
||||
if 'nrf52832' == sys.argv[1]:
|
||||
extract_nrf2832(dest_dir)
|
||||
elif 'esp32' == sys.argv[1]:
|
||||
extract_esp32(dest_dir)
|
||||
elif 'lifesense' == sys.argv[1]:
|
||||
extract_lifesense(dest_dir)
|
||||
else:
|
||||
print('Unknow platform %s, extract failed' % sys.argv[1])
|
||||
pass
|
@@ -0,0 +1,109 @@
|
||||
# 文件统一定义
|
||||
[FILE]
|
||||
COPYRIGHT = /*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
NAME_PREFIX = ble_qiot_template
|
||||
MACRO_PREFIX = BLE_QIOT_
|
||||
ENUM_PREFIX = BLE_QIOT_
|
||||
|
||||
# json文本内健定义
|
||||
[JSON]
|
||||
VERSION = version
|
||||
PROPERTY = properties
|
||||
MODE = mode
|
||||
EVENT = events
|
||||
TYPE = type
|
||||
PARAMS = params
|
||||
ACTION = actions
|
||||
INPUT = input
|
||||
OUTPUT = output
|
||||
ID = id
|
||||
DEFINE = define
|
||||
MAPPING = mapping
|
||||
UNIT = unit
|
||||
BOOL = bool
|
||||
ENUM = enum
|
||||
STRING = string
|
||||
FLOAT = float
|
||||
INT = int
|
||||
TIME = timestamp
|
||||
|
||||
# 数据类型定义
|
||||
# 左侧数值表示实际数值,默认从0开始枚举
|
||||
# BUTT表示最大值
|
||||
[DATA_TYPE]
|
||||
0 = BOOL
|
||||
1 = INT
|
||||
2 = STRING
|
||||
3 = FLOAT
|
||||
4 = ENUM
|
||||
5 = TIME
|
||||
6 = BUTT
|
||||
|
||||
# 消息类型定义
|
||||
# 左侧数值表示实际数值,默认从0开始枚举
|
||||
# BUTT表示最大值
|
||||
[MSG_TYPE]
|
||||
0 = PROPERTY
|
||||
1 = EVENT
|
||||
2 = ACTION
|
||||
3 = BUTT
|
||||
|
||||
# Property 读写属性定义
|
||||
# 左侧数值表示实际数值,默认从0开始枚举
|
||||
# BUTT表示最大值
|
||||
[PROPERTY_AUTH]
|
||||
0 = RW
|
||||
1 = READ
|
||||
2 = BUTT
|
||||
|
||||
# 数据功能,请求 or 回复
|
||||
# 左侧数值表示实际数值,默认从0开始枚举
|
||||
# BUTT表示最大值
|
||||
[EFFECT]
|
||||
0= REQUEST
|
||||
1 = REPLY
|
||||
2 = BUTT
|
||||
|
||||
# Reply消息结果定义
|
||||
# 左侧数值表示实际数值,默认从0开始枚举
|
||||
# BUTT表示最大值
|
||||
[REPLY]
|
||||
0 = SUCCESS
|
||||
1 = FAIL
|
||||
2 = DATA_ERR
|
||||
3 = BUTT
|
||||
|
||||
# 服务端向设备端下发消息类型定义
|
||||
# 左侧数值表示实际数值,默认从0开始枚举
|
||||
# BUTT表示最大值
|
||||
[DATA_DOWN]
|
||||
0 = REPORT_REPLY
|
||||
1 = CONTROL
|
||||
2 = GET_STATUS_REPLY
|
||||
3 = ACTION
|
||||
4 = EVENT_REPLY
|
||||
|
||||
# 设备端向服务端上报消息类型定义
|
||||
# 左侧数值表示实际数值,默认从0开始枚举
|
||||
# BUTT表示最大值
|
||||
[EVENT_UP]
|
||||
0 = PROPERTY_REPORT
|
||||
1 = CONTROL_REPLY
|
||||
2 = GET_STATUS
|
||||
3 = EVENT_POST
|
||||
4 = ACTION_REPLY
|
||||
5 = BIND_SIGN_RET
|
||||
6 = CONN_SIGN_RET
|
||||
7 = UNBIND_SIGN_RET
|
||||
8 = REPORT_MTU
|
||||
9 = BUTT
|
@@ -0,0 +1,60 @@
|
||||
## 介绍
|
||||
使用`python`脚本将后台生成的`json`格式的数据模版文件转为`c`代码文件。
|
||||
极大的减少了用户的开发工作,同时保证了终端设备,网关设备上数据定义的一致性。
|
||||
请使用`python3`解释器运行。
|
||||
|
||||
## 目录结构
|
||||
```c
|
||||
interpret_json_dt
|
||||
├─config # 配置文件目录
|
||||
│ └─dt.conf # INI配置文件
|
||||
├─src # 脚本文件目录
|
||||
│ ├─dt_fixed_content # 固定代码文件目录
|
||||
│ │ └─dt_ble_action # ble action部分固定代码
|
||||
│ │ └─dt_ble_event # ble event部分固定代码
|
||||
│ │ └─dt_ble_property # ble proerty部分固定代码
|
||||
│ │ └─dt_ble_prototype # ble 函数原型
|
||||
│ │ └─dt_gateway_action # gateway action部分固定代码
|
||||
│ │ └─dt_gateway_event # gateway event部分固定代码
|
||||
│ │ └─dt_gateway_property # gateway property部分固定代码
|
||||
│ │ └─dt_gateway_prototype # gateway 函数原型
|
||||
│ ├─interpret_dt_ble.py # 转换json脚本生成ble sdk代码
|
||||
│ ├─interpret_dt_gateway.py # 转换json脚本生成网关代码
|
||||
│ ├─example.json # 示例文件
|
||||
```
|
||||
|
||||
## 代码生成原理
|
||||
采取`动态生成 + 固定写入`的方式来生成代码。
|
||||
* 动态生成:通过脚本解析`json`文件,将数据模版转换为对应的代码
|
||||
* 固定写入:数据模版的操作函数是固定不变的,从静态文件读取写入,达到简化脚本的目的
|
||||
|
||||
### 头文件生成
|
||||
1. 按照`LLSync协议`定义写入公共定义,包括数据类型定义,消息类型定义等
|
||||
2. 解析`json`文件,将字符串`id`转换为枚举类型`id`
|
||||
3. 将每个`id`对应的值根据其类型进行转换
|
||||
* 对于枚举类型,将其枚举值转换为枚举类型
|
||||
* 对于整数类型或浮点数类型,将其最大值,最小值,起始值,步进转换为宏定义
|
||||
* 对于字符串类型,将其最大长度,最小长度转换为宏定义
|
||||
4. 写入不同数据类型的结构体定义
|
||||
5. 写入不同数据类型的函数声明,函数声明从`dt_gateway_prototype`中读
|
||||
|
||||
### BLE C文件生成
|
||||
1. 解析`json`文件,根据`id`生成其操作函数,**操作函数需要用户按照需求实现**
|
||||
2. 解析`json`文件,生成数据模版的结构数组
|
||||
3. 读取静态文件,写入固定操作函数
|
||||
|
||||
### 网关C文件生成
|
||||
1. 解析`json`文件,生成数据模版的结构数组
|
||||
2. 读取静态文件,写入固定操作函数
|
||||
|
||||
## 使用方法
|
||||
### BLE SDK
|
||||
1. 从物联网平台下载数据模版`json`文件
|
||||
2. 执行`python3 interpret_dt_ble.py <your_json_file>`来生成对应的数据模版文件
|
||||
3. 按照数据特性实现`ble_qiot_template.c`中的操作函数
|
||||
4. 将生成文件拷贝到`data_template`目录编译即可
|
||||
|
||||
### 网关
|
||||
1. 从物联网平台下载数据模版`json`文件
|
||||
2. 执行`python3 interpret_dt_gateway.py <your_json_file>`来生成对应的数据模版文件
|
||||
3. 将生成文件拷贝SDK编译即可。
|
@@ -0,0 +1,96 @@
|
||||
uint8_t ble_action_get_intput_type_by_id(uint8_t action_id, uint8_t input_id)
|
||||
{
|
||||
if (action_id >= BLE_QIOT_ACTION_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid action id %d", action_id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
if (input_id >= sg_ble_event_array[action_id].array_size) {
|
||||
ble_qiot_log_e("invalid input id %d", input_id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
|
||||
return sg_ble_action_array[action_id].input_type_array[input_id];
|
||||
}
|
||||
|
||||
uint8_t ble_action_get_output_type_by_id(uint8_t action_id, uint8_t output_id)
|
||||
{
|
||||
if (action_id >= BLE_QIOT_ACTION_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid action id %d", action_id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
if (output_id >= sg_ble_event_array[action_id].array_size) {
|
||||
ble_qiot_log_e("invalid output id %d", output_id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
|
||||
return sg_ble_action_array[action_id].output_type_array[output_id];
|
||||
}
|
||||
|
||||
int ble_action_get_input_id_size(uint8_t action_id)
|
||||
{
|
||||
if (action_id >= BLE_QIOT_ACTION_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid action id %d", action_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sg_ble_action_array[action_id].input_id_size;
|
||||
}
|
||||
|
||||
int ble_action_get_output_id_size(uint8_t action_id)
|
||||
{
|
||||
if (action_id >= BLE_QIOT_ACTION_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid action id %d", action_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sg_ble_action_array[action_id].output_id_size;
|
||||
}
|
||||
|
||||
int ble_action_user_handle_input_param(uint8_t action_id, e_ble_tlv *input_param_array, uint8_t input_array_size, uint8_t *output_id_array)
|
||||
{
|
||||
if (action_id >= BLE_QIOT_ACTION_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid action id %d", action_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL != sg_ble_action_array[action_id].input_cb) {
|
||||
if (0 != sg_ble_action_array[action_id].input_cb(input_param_array, input_array_size, output_id_array)) {
|
||||
ble_qiot_log_e("input handle error");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_action_user_handle_output_param(uint8_t action_id, uint8_t output_id, char *buf, uint16_t buf_len)
|
||||
{
|
||||
int ret_len = 0;
|
||||
|
||||
if (action_id >= BLE_QIOT_ACTION_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid action id %d", action_id);
|
||||
return -1;
|
||||
}
|
||||
if (NULL == sg_ble_action_array[action_id].output_cb){
|
||||
ble_qiot_log_e("invalid callback, action id %d", action_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ble_check_space_enough_by_type(sg_ble_action_array[action_id].output_type_array[output_id], buf_len)) {
|
||||
ble_qiot_log_e("not enough space get data, action id %d, output id %d", action_id, output_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret_len = sg_ble_action_array[action_id].output_cb(output_id, buf, buf_len);
|
||||
if (ret_len < 0) {
|
||||
ble_qiot_log_e("get action data failed, action id %d, output id %d", action_id, output_id);
|
||||
return -1;
|
||||
}else {
|
||||
if (ble_check_ret_value_by_type(sg_ble_action_array[action_id].output_type_array[output_id], buf_len, ret_len)){
|
||||
return ret_len;
|
||||
}else{
|
||||
ble_qiot_log_e("action data length invalid, action id %d, output id %d", action_id, output_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
int ble_event_get_id_array_size(uint8_t event_id)
|
||||
{
|
||||
if (event_id >= BLE_QIOT_EVENT_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid event id %d", event_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sg_ble_event_array[event_id].array_size;
|
||||
}
|
||||
|
||||
uint8_t ble_event_get_param_id_type(uint8_t event_id, uint8_t param_id)
|
||||
{
|
||||
if (event_id >= BLE_QIOT_EVENT_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid event id %d", event_id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
if (param_id >= sg_ble_event_array[event_id].array_size) {
|
||||
ble_qiot_log_e("invalid param id %d", param_id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
|
||||
return sg_ble_event_array[event_id].event_array[param_id].type;
|
||||
}
|
||||
|
||||
int ble_event_get_data_by_id(uint8_t event_id, uint8_t param_id, char *out_buf, uint16_t buf_len)
|
||||
{
|
||||
int ret_len = 0;
|
||||
|
||||
if (event_id >= BLE_QIOT_EVENT_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid event id %d", event_id);
|
||||
return -1;
|
||||
}
|
||||
if (param_id >= sg_ble_event_array[event_id].array_size) {
|
||||
ble_qiot_log_e("invalid param id %d", param_id);
|
||||
return -1;
|
||||
}
|
||||
if (NULL == sg_ble_event_array[event_id].event_array[param_id].get_cb) {
|
||||
ble_qiot_log_e("invalid callback, event id %d, param id %d", event_id, param_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ble_check_space_enough_by_type(sg_ble_event_array[event_id].event_array[param_id].type, buf_len)) {
|
||||
ble_qiot_log_e("not enough space get data, event id %d, param id %d", event_id, param_id);
|
||||
return -1;
|
||||
}
|
||||
ret_len = sg_ble_event_array[event_id].event_array[param_id].get_cb(out_buf, buf_len);
|
||||
if (ret_len < 0) {
|
||||
ble_qiot_log_e("get event data failed, event id %d, param id %d", event_id, param_id);
|
||||
return -1;
|
||||
}else {
|
||||
if (ble_check_ret_value_by_type(sg_ble_event_array[event_id].event_array[param_id].type, buf_len, ret_len)){
|
||||
return ret_len;
|
||||
}else{
|
||||
ble_qiot_log_e("evnet data length invalid, event id %d, param id %d", event_id, param_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ble_user_event_reply_handle(uint8_t event_id, uint8_t result)
|
||||
{
|
||||
ble_qiot_log_d("event id %d, reply result %d", event_id, result);
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
static bool ble_check_space_enough_by_type(uint8_t type, uint16_t left_size)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case BLE_QIOT_DATA_TYPE_BOOL:
|
||||
return left_size >= sizeof(uint8_t);
|
||||
case BLE_QIOT_DATA_TYPE_INT:
|
||||
case BLE_QIOT_DATA_TYPE_FLOAT:
|
||||
case BLE_QIOT_DATA_TYPE_TIME:
|
||||
return left_size >= sizeof(uint32_t);
|
||||
case BLE_QIOT_DATA_TYPE_ENUM:
|
||||
return left_size >= sizeof(uint16_t);
|
||||
default:
|
||||
// string length is unknow, default true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t ble_check_ret_value_by_type(uint8_t type, uint16_t buf_len, uint16_t ret_val)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case BLE_QIOT_DATA_TYPE_BOOL:
|
||||
return ret_val <= sizeof(uint8_t);
|
||||
case BLE_QIOT_DATA_TYPE_INT:
|
||||
case BLE_QIOT_DATA_TYPE_FLOAT:
|
||||
case BLE_QIOT_DATA_TYPE_TIME:
|
||||
return ret_val <= sizeof(uint32_t);
|
||||
case BLE_QIOT_DATA_TYPE_ENUM:
|
||||
return ret_val <= sizeof(uint16_t);
|
||||
default:
|
||||
// string length is unknow, default true
|
||||
return ret_val <= buf_len;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ble_get_property_type_by_id(uint8_t id)
|
||||
{
|
||||
if (id >= BLE_QIOT_PROPERTY_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid property id %d", id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
return sg_ble_property_array[id].type;
|
||||
}
|
||||
|
||||
int ble_user_property_set_data(const e_ble_tlv *tlv)
|
||||
{
|
||||
POINTER_SANITY_CHECK(tlv, BLE_QIOT_RS_ERR_PARA);
|
||||
if (tlv->id >= BLE_QIOT_PROPERTY_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid property id %d", tlv->id);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
if (NULL != sg_ble_property_array[tlv->id].set_cb) {
|
||||
if (0 != sg_ble_property_array[tlv->id].set_cb(tlv->val, tlv->len)) {
|
||||
ble_qiot_log_e("set property id %d failed", tlv->id);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}else {
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
}
|
||||
ble_qiot_log_e("invalid set callback, id %d", tlv->id);
|
||||
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
int ble_user_property_get_data_by_id(uint8_t id, char *buf, uint16_t buf_len)
|
||||
{
|
||||
int ret_len = 0;
|
||||
|
||||
POINTER_SANITY_CHECK(buf, BLE_QIOT_RS_ERR_PARA);
|
||||
if (id >= BLE_QIOT_PROPERTY_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid property id %d", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL != sg_ble_property_array[id].get_cb) {
|
||||
if (!ble_check_space_enough_by_type(sg_ble_property_array[id].type, buf_len)) {
|
||||
ble_qiot_log_e("not enough space get property id %d data", id);
|
||||
return -1;
|
||||
}
|
||||
ret_len = sg_ble_property_array[id].get_cb(buf, buf_len);
|
||||
if (ret_len < 0) {
|
||||
ble_qiot_log_e("get property id %d data failed", id);
|
||||
return -1;
|
||||
}else {
|
||||
if (ble_check_ret_value_by_type(sg_ble_property_array[id].type, buf_len, ret_len)){
|
||||
return ret_len;
|
||||
}else{
|
||||
ble_qiot_log_e("property id %d length invalid", id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ble_qiot_log_e("invalid callback, property id %d", id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_user_property_report_reply_handle(uint8_t result)
|
||||
{
|
||||
ble_qiot_log_d("report reply result %d", result);
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
// property module
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
uint8_t ble_get_property_type_by_id(uint8_t id);
|
||||
int ble_user_property_set_data(const e_ble_tlv *tlv);
|
||||
int ble_user_property_get_data_by_id(uint8_t id, char *buf, uint16_t buf_len);
|
||||
int ble_user_property_report_reply_handle(uint8_t result);
|
||||
#endif
|
||||
|
||||
// event module
|
||||
#ifdef BLE_QIOT_INCLUDE_EVENT
|
||||
int ble_event_get_id_array_size(uint8_t event_id);
|
||||
uint8_t ble_event_get_param_id_type(uint8_t event_id, uint8_t param_id);
|
||||
int ble_event_get_data_by_id(uint8_t event_id, uint8_t param_id, char *out_buf, uint16_t buf_len);
|
||||
int ble_user_event_reply_handle(uint8_t event_id, uint8_t result);
|
||||
#endif
|
||||
|
||||
// action module
|
||||
#ifdef BLE_QIOT_INCLUDE_ACTION
|
||||
uint8_t ble_action_get_intput_type_by_id(uint8_t action_id, uint8_t input_id);
|
||||
uint8_t ble_action_get_output_type_by_id(uint8_t action_id, uint8_t output_id);
|
||||
int ble_action_get_input_id_size(uint8_t action_id);
|
||||
int ble_action_get_output_id_size(uint8_t action_id);
|
||||
int ble_action_user_handle_input_param(uint8_t action_id, e_ble_tlv *input_param_array, uint8_t input_array_size, uint8_t *output_id_array);
|
||||
int ble_action_user_handle_output_param(uint8_t action_id, uint8_t output_id, char *buf, uint16_t buf_len);
|
||||
#endif
|
@@ -0,0 +1,607 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
import configparser
|
||||
|
||||
script_path = os.path.split(os.path.realpath(__file__))[0]
|
||||
dt_config = configparser.ConfigParser()
|
||||
|
||||
|
||||
def _dt_get_config_from_file():
|
||||
config_file = open(os.path.join(script_path, '..', 'config', 'dt.conf'), 'r', encoding='UTF-8')
|
||||
config_content = config_file.read()
|
||||
config_file.close()
|
||||
dt_config.read_string(config_content)
|
||||
pass
|
||||
|
||||
|
||||
def _dt_get_json_from_file(filenmae):
|
||||
_dt_get_config_from_file()
|
||||
json_file = open(filenmae, 'r', encoding='UTF-8')
|
||||
file_content = json_file.read()
|
||||
json_file.close()
|
||||
return json.loads(file_content)
|
||||
|
||||
|
||||
def _dt_write_newline_to_file(write_fd, write_buf):
|
||||
write_fd.writelines(write_buf + '\n')
|
||||
pass
|
||||
|
||||
|
||||
def _dt_write_macro_to_file(write_fd, macro, macro_val):
|
||||
write_fd.writelines('#define\t%-40s\t%-32s\n' % (dt_config['FILE']['MACRO_PREFIX'] +
|
||||
macro.upper(), macro_val.upper()))
|
||||
pass
|
||||
|
||||
|
||||
def _dt_write_enum_to_file(write_fd, enum_comments, enum_prefix, enum_suffix_list, enum_value_list=None):
|
||||
init_flag = True
|
||||
write_fd.writelines('\n' + enum_comments + '\n')
|
||||
write_fd.writelines('enum {\n')
|
||||
|
||||
if enum_value_list == None:
|
||||
for enum_suffix in enum_suffix_list:
|
||||
if init_flag:
|
||||
write_fd.writelines('\t' + dt_config['FILE']['ENUM_PREFIX'] +
|
||||
(enum_prefix + '_' + enum_suffix).upper() + ' = 0,\n')
|
||||
init_flag = False
|
||||
else:
|
||||
write_fd.writelines('\t' + dt_config['FILE']['ENUM_PREFIX'] +
|
||||
(enum_prefix + '_' + enum_suffix).upper() + ',\n')
|
||||
else:
|
||||
for idx, enum_suffix in enumerate(enum_suffix_list):
|
||||
write_fd.writelines('\t' + dt_config['FILE']['ENUM_PREFIX'] +
|
||||
(enum_prefix + '_' + enum_suffix).upper() + ' = %s,\n' % enum_value_list[idx])
|
||||
|
||||
write_fd.writelines('};\n')
|
||||
pass
|
||||
|
||||
|
||||
def _dt_get_enum_list_from_conf(conf_data):
|
||||
return [v for k, v in conf_data.items()]
|
||||
|
||||
|
||||
def _dt_get_enum_list_from_ids(property_json):
|
||||
id_list = [value.get('id') for value in property_json]
|
||||
id_list.append('BUTT')
|
||||
return id_list
|
||||
|
||||
|
||||
def _dt_get_enum_list_from_mapping(mapping):
|
||||
new_list = sorted(mapping.keys())
|
||||
enum_prefix = [mapping[key] for key in new_list]
|
||||
enum_prefix.append('BUTT')
|
||||
enum_val = [key for key in new_list]
|
||||
enum_val.append(str(int(new_list[-1]) + 1))
|
||||
|
||||
return [enum_prefix, enum_val]
|
||||
|
||||
|
||||
def _dt_not_exist(dt_data):
|
||||
if not dt_data:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def _dt_write_public_header(write_fd):
|
||||
_dt_write_enum_to_file(write_fd, '// data type in template, corresponding to type in json file',
|
||||
dt_config['DATA_TYPE'].name,
|
||||
_dt_get_enum_list_from_conf(dt_config['DATA_TYPE']))
|
||||
_dt_write_enum_to_file(write_fd, '// message type, reference data template ', dt_config['MSG_TYPE'].name,
|
||||
_dt_get_enum_list_from_conf(dt_config['MSG_TYPE']))
|
||||
_dt_write_enum_to_file(write_fd, '// define property authority, not used', dt_config['PROPERTY_AUTH'].name,
|
||||
_dt_get_enum_list_from_conf(dt_config['PROPERTY_AUTH']))
|
||||
_dt_write_enum_to_file(write_fd, '// define reply result', dt_config['REPLY'].name,
|
||||
_dt_get_enum_list_from_conf(dt_config['REPLY']))
|
||||
_dt_write_enum_to_file(write_fd, '// define message flow direction', dt_config['EFFECT'].name,
|
||||
_dt_get_enum_list_from_conf(dt_config['EFFECT']))
|
||||
_dt_write_enum_to_file(write_fd, '// define message type that from server to device', dt_config['DATA_DOWN'].name,
|
||||
_dt_get_enum_list_from_conf(dt_config['DATA_DOWN']))
|
||||
_dt_write_enum_to_file(write_fd, '// define message type that from device to server', dt_config['EVENT_UP'].name,
|
||||
_dt_get_enum_list_from_conf(dt_config['EVENT_UP']))
|
||||
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// msg header define, bit 7-6 is msg type, bit 5 means request or reply, bit 4 - 0 is id')
|
||||
_dt_write_macro_to_file(write_fd, 'PARSE_MSG_HEAD_TYPE(_c)', '(((_c) & 0xFF) >> 6)')
|
||||
_dt_write_macro_to_file(write_fd, 'PARSE_MSG_HEAD_EFFECT(_c)',
|
||||
'((((_c) & 0xFF) & 0x20) ? BLE_QIOT_EFFECT_REPLY : BLE_QIOT_EFFECT_REQUEST)')
|
||||
_dt_write_macro_to_file(write_fd, 'PARSE_MSG_HEAD_ID(_c)', '((_c) & 0x1F)')
|
||||
_dt_write_macro_to_file(write_fd, 'PACKAGE_MSG_HEAD(_type, _reply, _id)',
|
||||
'(((_type) << 6) | (((_reply) == BLE_QIOT_EFFECT_REPLY) << 5) | ((_id) & 0x1F))')
|
||||
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// tlv header define, bit 7 - 5 is type, bit 4 - 0 depends on type of data template')
|
||||
_dt_write_macro_to_file(write_fd, 'PARSE_TLV_HEAD_TYPE(_c)', '(((_c) & 0xFF) >> 5)')
|
||||
_dt_write_macro_to_file(write_fd, 'PARSE_TLV_HEAD_ID(_c)', '((_c) & 0x1F)')
|
||||
_dt_write_macro_to_file(write_fd, 'PACKAGE_TLV_HEAD(_type, _id)', '(((_type) << 5) | ((_id) & 0x1F))\n')
|
||||
|
||||
_dt_write_newline_to_file(write_fd, '\n// define tlv struct')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef struct{'
|
||||
'\n\tuint8_t type;'
|
||||
'\n\tuint8_t id;'
|
||||
'\n\tuint16_t len;'
|
||||
'\n\tchar *val;'
|
||||
'\n}e_ble_tlv;')
|
||||
pass
|
||||
|
||||
|
||||
def _dt_trans_property_json_to_h_file(write_fd, _proterty_data):
|
||||
if _dt_not_exist(_proterty_data):
|
||||
return
|
||||
|
||||
_dt_write_macro_to_file(write_fd, 'INCLUDE_PROPERTY', '')
|
||||
# all property id define, the tail of macro name corresponding to property id in json file
|
||||
_dt_write_enum_to_file(write_fd, '// define property id', 'PROPERTY_ID', _dt_get_enum_list_from_ids(_proterty_data))
|
||||
|
||||
# define property id values, including size, length, limit ...
|
||||
for property_id in _proterty_data:
|
||||
if property_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['ENUM']:
|
||||
enum_prefix, enum_val = _dt_get_enum_list_from_mapping(
|
||||
property_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['MAPPING']])
|
||||
_dt_write_enum_to_file(write_fd, '// define property %s enum' % property_id[dt_config['JSON']['ID']],
|
||||
'PROPERTY_' + property_id[dt_config['JSON']['ID']], enum_prefix, enum_val)
|
||||
elif property_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['INT'] or \
|
||||
property_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['FLOAT']:
|
||||
_dt_write_newline_to_file(write_fd, '\n// define %s attributes' % property_id[dt_config['JSON']['ID']])
|
||||
for k, v in property_id[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE'] and k != dt_config['JSON']['UNIT']:
|
||||
_dt_write_macro_to_file(write_fd, 'PROPERTY_' + property_id[dt_config['JSON']['ID']] + '_' + k,
|
||||
'(' + v + ')')
|
||||
elif property_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['STRING']:
|
||||
_dt_write_newline_to_file(write_fd, '\n// define %s length limit' % property_id[dt_config['JSON']['ID']])
|
||||
for k, v in property_id[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE']:
|
||||
_dt_write_macro_to_file(write_fd,
|
||||
'PROPERTY_' + property_id[dt_config['JSON']['ID']] + '_LEN_' + k,
|
||||
'(' + v + ')')
|
||||
else:
|
||||
pass
|
||||
# define prototype of callback function
|
||||
_dt_write_newline_to_file(write_fd, '\n// define property set handle return 0 if success, other is error\n'
|
||||
'// sdk call the function that inform the server data to the device')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef int (*property_set_cb)(const char *data, uint16_t len);')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// define property get handle. return the data length obtained, -1 is error, 0 is no data\n'
|
||||
'// sdk call the function fetch user data and send to the server, the data should wrapped by user '
|
||||
'adn skd just transmit')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef int (*property_get_cb)(char *buf, uint16_t buf_len);')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// each property have a struct ble_property_t, make up a array named sg_ble_property_array')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef struct{'
|
||||
'\n\tproperty_set_cb set_cb;\t//set callback'
|
||||
'\n\tproperty_get_cb get_cb;\t//get callback'
|
||||
'\n\tuint8_t authority;\t//property authority'
|
||||
'\n\tuint8_t type;\t//data type'
|
||||
'\n}ble_property_t;')
|
||||
pass
|
||||
|
||||
|
||||
def _dt_trans_event_json_to_h_file(write_fd, _event_data):
|
||||
if _dt_not_exist(_event_data):
|
||||
return
|
||||
|
||||
_dt_write_macro_to_file(write_fd, 'INCLUDE_EVENT', '')
|
||||
# define event id
|
||||
_dt_write_enum_to_file(write_fd, '// define event id', 'EVENT_ID', _dt_get_enum_list_from_ids(_event_data))
|
||||
|
||||
for event in _event_data:
|
||||
# define param id of event
|
||||
_dt_write_enum_to_file(write_fd, '// define param id for event %s' % event.get(dt_config['JSON']['ID']),
|
||||
'EVENT_' + event.get(dt_config['JSON']['ID']) + '_PARAM_ID',
|
||||
_dt_get_enum_list_from_ids(event.get(dt_config['JSON']['PARAMS'])))
|
||||
# define param value of event
|
||||
for param in event.get('params'):
|
||||
if param[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['ENUM']:
|
||||
enum_prefix, enum_val = _dt_get_enum_list_from_mapping(param[dt_config['JSON']['DEFINE']]['mapping'])
|
||||
_dt_write_enum_to_file(write_fd, '// define enum for param %s' % param[dt_config['JSON']['ID']],
|
||||
'EVEMT_' + event.get(dt_config['JSON']['ID']) + '_' + param[
|
||||
dt_config['JSON']['ID']],
|
||||
enum_prefix, enum_val)
|
||||
elif param[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['INT'] or \
|
||||
param[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['FLOAT']:
|
||||
_dt_write_newline_to_file(write_fd, '\n// define param %s attributes' % param[dt_config['JSON']['ID']])
|
||||
for k, v in param[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE'] and k != dt_config['JSON']['UNIT']:
|
||||
_dt_write_macro_to_file(write_fd,
|
||||
'EVENT_' + event.get(dt_config['JSON']['ID']) + '_' + param[
|
||||
dt_config['JSON']['ID']] + '_' + k,
|
||||
'(' + v + ')')
|
||||
elif param[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['STRING']:
|
||||
_dt_write_newline_to_file(write_fd, '\n// define range for param %s' % param[dt_config['JSON']['ID']])
|
||||
for k, v in param[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE']:
|
||||
_dt_write_macro_to_file(write_fd,
|
||||
'EVENT_' + event.get(dt_config['JSON']['ID']) + '_' + param[
|
||||
dt_config['JSON']['ID']] + '_LEN_' + k,
|
||||
'(' + v + ')')
|
||||
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// define event get handle. return the data length obtained, -1 is error, 0 is no data\n'
|
||||
'// sdk call the function fetch user data and send to the server, the data should wrapped by user '
|
||||
'adn skd just transmit')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef int (*event_get_cb)(char *buf, uint16_t buf_len);')
|
||||
_dt_write_newline_to_file(write_fd, '\n// each param have a struct ble_event_param, make up a array for the event')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef struct{'
|
||||
'\n\tevent_get_cb get_cb;\t//get param data callback'
|
||||
'\n\tuint8_t type;\t//param type'
|
||||
'\n}ble_event_param;')
|
||||
_dt_write_newline_to_file(write_fd, '\n// a array named sg_ble_event_array is composed by all the event array')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef struct{'
|
||||
'\n\tble_event_param *event_array;\t//array of params data'
|
||||
'\n\tuint8_t array_size;\t//array size'
|
||||
'\n}ble_event_t;')
|
||||
pass
|
||||
|
||||
|
||||
def _dt_trans_action_json_to_h_file(write_fd, _action_data):
|
||||
if _dt_not_exist(_action_data):
|
||||
return
|
||||
|
||||
_dt_write_macro_to_file(write_fd, 'INCLUDE_ACTION', '')
|
||||
# define action id
|
||||
_dt_write_enum_to_file(write_fd, '// define action id', 'ACTION_ID', _dt_get_enum_list_from_ids(_action_data))
|
||||
max_input_id, max_output_id = 0, 0
|
||||
for action in _action_data:
|
||||
# define action input id
|
||||
_dt_write_enum_to_file(write_fd, '// define input id for action %s' % action.get(dt_config['JSON']['ID']),
|
||||
'ACTION_' + action.get(dt_config['JSON']['ID']) + '_INPUT_ID',
|
||||
_dt_get_enum_list_from_ids(action.get(dt_config['JSON']['INPUT'])))
|
||||
_dt_write_enum_to_file(write_fd, '// define output id for action %s' % action.get(dt_config['JSON']['ID']),
|
||||
'ACTION_' + action.get(dt_config['JSON']['ID']) + '_OUTPUT_ID',
|
||||
_dt_get_enum_list_from_ids(action.get(dt_config['JSON']['OUTPUT'])))
|
||||
max_input_id = max(len(_dt_get_enum_list_from_ids(action.get(dt_config['JSON']['INPUT']))), max_input_id)
|
||||
max_output_id = max(len(_dt_get_enum_list_from_ids(action.get(dt_config['JSON']['OUTPUT']))), max_output_id)
|
||||
# define input id values
|
||||
for input_id in action.get('input'):
|
||||
if input_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['ENUM']:
|
||||
enum_prefix, enum_val = _dt_get_enum_list_from_mapping(
|
||||
input_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['MAPPING']])
|
||||
_dt_write_enum_to_file(write_fd, '// define enum for input id %s' % input_id[dt_config['JSON']['ID']],
|
||||
'ACTION_INPUT_' + action.get(dt_config['JSON']['ID']) + '_' + input_id[
|
||||
dt_config['JSON']['ID']],
|
||||
enum_prefix, enum_val)
|
||||
elif input_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['INT'] or \
|
||||
input_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['FLOAT']:
|
||||
for k, v in input_id[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE'] and k != dt_config['JSON']['UNIT']:
|
||||
_dt_write_macro_to_file(write_fd,
|
||||
'ACTION_INPUT_' + action.get(dt_config['JSON']['ID']) + '_' + input_id[
|
||||
dt_config['JSON']['ID']] + '_' + k,
|
||||
'(' + v + ')')
|
||||
elif input_id[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['STRING']:
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// define input id %s attributes' % input_id[dt_config['JSON']['ID']])
|
||||
for k, v in input_id[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE']:
|
||||
_dt_write_macro_to_file(write_fd,
|
||||
'ACTION_OUTPUT_' + action.get(dt_config['JSON']['ID']) + '_' + input_id[
|
||||
dt_config['JSON']['ID']] + '_LEN_' + k,
|
||||
'(' + v + ')')
|
||||
else:
|
||||
pass
|
||||
for output in action.get('output'):
|
||||
if output[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['ENUM']:
|
||||
enum_prefix, enum_val = _dt_get_enum_list_from_mapping(
|
||||
output[dt_config['JSON']['DEFINE']][dt_config['JSON']['MAPPING']])
|
||||
_dt_write_enum_to_file(write_fd, '// define enum for output id %s' % output[dt_config['JSON']['ID']],
|
||||
'ACTION_OUTPUT_' + action.get(dt_config['JSON']['ID']) + '_' + output[
|
||||
dt_config['JSON']['ID']],
|
||||
enum_prefix, enum_val)
|
||||
elif output[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['INT'] or \
|
||||
output[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['FLOAT']:
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// define output id %s attributes' % output[dt_config['JSON']['ID']])
|
||||
for k, v in output[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE'] and k != dt_config['JSON']['UNIT']:
|
||||
_dt_write_macro_to_file(write_fd,
|
||||
'ACTION_OUTPUT_' + action.get(dt_config['JSON']['ID']) + '_' + output[
|
||||
dt_config['JSON']['ID']] + '_' + k,
|
||||
'(' + v + ')')
|
||||
elif output[dt_config['JSON']['DEFINE']][dt_config['JSON']['TYPE']] == dt_config['JSON']['STRING']:
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// define output id %s attributes' % output[dt_config['JSON']['ID']])
|
||||
for k, v in output[dt_config['JSON']['DEFINE']].items():
|
||||
if v != '' and k != dt_config['JSON']['TYPE']:
|
||||
_dt_write_macro_to_file(write_fd,
|
||||
'ACTION_OUTPUT_' + action.get(dt_config['JSON']['ID']) + '_' + output[
|
||||
dt_config['JSON']['ID']] + '_LEN_' + k,
|
||||
'(' + v + ')')
|
||||
_dt_write_newline_to_file(write_fd, '\n// define max input id and output id in all of input id and output id above')
|
||||
_dt_write_macro_to_file(write_fd, 'ACTION_INPUT_ID_BUTT', str(max_input_id - 1))
|
||||
_dt_write_macro_to_file(write_fd, 'ACTION_OUTPUT_ID_BUTT', str(max_output_id - 1))
|
||||
_dt_write_newline_to_file(write_fd, '\n// define action input handle, return 0 is success, other is error.\n'
|
||||
'// input_param_array carry the data from server, include input id, data length ,data val\n'
|
||||
'// input_array_size means how many input id\n'
|
||||
'// output_id_array filling with output id numbers that need obtained, sdk will traverse it and call the action_output_handle to obtained data')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'typedef int (*action_input_handle)(e_ble_tlv *input_param_array, uint8_t input_array_size, uint8_t *output_id_array);')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// define action output handle, return length of the data, 0 is no data, -1 is error\n'
|
||||
'// output_id means which id data should be obtained')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'typedef int (*action_output_handle)(uint8_t output_id, char *buf, uint16_t buf_len);')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\n// each action have a struct ble_action_t, make up a array named sg_ble_action_array')
|
||||
_dt_write_newline_to_file(write_fd, 'typedef struct{'
|
||||
'\n\taction_input_handle input_cb;\t//handle input data'
|
||||
'\n\taction_output_handle output_cb;\t// get output data in the callback'
|
||||
'\n\tuint8_t *input_type_array;\t//type array for input id'
|
||||
'\n\tuint8_t *output_type_array;\t//type array for output id'
|
||||
'\n\tuint8_t input_id_size;\t//numbers of input id'
|
||||
'\n\tuint8_t output_id_size;\t//numbers of output id'
|
||||
'\n}ble_action_t;')
|
||||
pass
|
||||
|
||||
|
||||
def _dt_write_function_prototype(write_fd):
|
||||
file_fd = open(os.path.join(script_path, 'dt_fixed_content', 'dt_ble_prototype'), 'r', encoding='UTF-8')
|
||||
file_content = file_fd.read()
|
||||
file_fd.close()
|
||||
_dt_write_newline_to_file(write_fd, file_content)
|
||||
pass
|
||||
|
||||
|
||||
def _dt_generate_header_file(_json_data):
|
||||
h_file = open(dt_config['FILE']['NAME_PREFIX'] + '.h', 'w', encoding='UTF-8')
|
||||
|
||||
_dt_write_newline_to_file(h_file, dt_config['FILE']['COPYRIGHT'])
|
||||
_dt_write_newline_to_file(h_file, '#ifndef ' + dt_config['FILE']['NAME_PREFIX'].upper() + '_H_')
|
||||
_dt_write_newline_to_file(h_file, '#define ' + dt_config['FILE']['NAME_PREFIX'].upper() + '_H_')
|
||||
_dt_write_newline_to_file(h_file, '#ifdef __cplusplus\n' + 'extern "C"{\n#endif\n')
|
||||
|
||||
_dt_write_newline_to_file(h_file, '#include <stdint.h>\n')
|
||||
|
||||
_dt_write_public_header(h_file)
|
||||
_dt_trans_property_json_to_h_file(h_file, _json_data.get(dt_config['JSON']['PROPERTY']))
|
||||
_dt_trans_event_json_to_h_file(h_file, _json_data.get(dt_config['JSON']['EVENT']))
|
||||
_dt_trans_action_json_to_h_file(h_file, _json_data.get(dt_config['JSON']['ACTION']))
|
||||
_dt_write_function_prototype(h_file)
|
||||
|
||||
_dt_write_newline_to_file(h_file, '\n' + '#ifdef __cplusplus' + '\n' + '}' + '\n' + '#endif')
|
||||
_dt_write_newline_to_file(h_file, '#endif ' + '//' + (dt_config['FILE']['NAME_PREFIX']).upper() + '_H_')
|
||||
|
||||
h_file.close()
|
||||
pass
|
||||
|
||||
|
||||
def _dt_get_property_function_name(property_id):
|
||||
return 'ble_property_' + property_id.lower() + '_get'
|
||||
|
||||
|
||||
def _dt_set_property_function_name(property_id):
|
||||
return 'ble_property_' + property_id.lower() + '_set'
|
||||
|
||||
|
||||
def _dt_get_property_mode(mode):
|
||||
if mode == 'rw':
|
||||
return 'BLE_QIOT_PROPERTY_AUTH_RW'
|
||||
elif mode == 'r':
|
||||
return 'BLE_QIOT_PROPERTY_AUTH_READ'
|
||||
else:
|
||||
print("invalid property mode")
|
||||
pass
|
||||
|
||||
|
||||
def _dt_get_type_by_str(type_str):
|
||||
if type_str == dt_config['JSON']['BOOL']:
|
||||
return 'BLE_QIOT_DATA_TYPE_BOOL'
|
||||
elif type_str == dt_config['JSON']['INT']:
|
||||
return 'BLE_QIOT_DATA_TYPE_INT'
|
||||
elif type_str == dt_config['JSON']['STRING']:
|
||||
return 'BLE_QIOT_DATA_TYPE_STRING'
|
||||
elif type_str == dt_config['JSON']['FLOAT']:
|
||||
return 'BLE_QIOT_DATA_TYPE_FLOAT'
|
||||
elif type_str == dt_config['JSON']['ENUM']:
|
||||
return 'BLE_QIOT_DATA_TYPE_ENUM'
|
||||
elif type_str == dt_config['JSON']['TIME']:
|
||||
return 'BLE_QIOT_DATA_TYPE_TIME'
|
||||
else:
|
||||
print('invalid type string')
|
||||
pass
|
||||
|
||||
|
||||
def _dt_get_ret_val_by_type(data_type):
|
||||
if data_type == dt_config['JSON']['STRING']:
|
||||
return 'buf_len'
|
||||
elif data_type == dt_config['JSON']['INT']:
|
||||
return 'sizeof(uint32_t)'
|
||||
elif data_type == dt_config['JSON']['ENUM']:
|
||||
return 'sizeof(uint16_t)'
|
||||
elif data_type == dt_config['JSON']['BOOL']:
|
||||
return 'sizeof(uint8_t)'
|
||||
elif data_type == dt_config['JSON']['FLOAT']:
|
||||
return 'sizeof(float)'
|
||||
elif data_type == dt_config['JSON']['TIME']:
|
||||
return 'sizeof(uint32_t)'
|
||||
else:
|
||||
print('invalid data type')
|
||||
|
||||
|
||||
def _dt_get_function_param_by_type(data_type):
|
||||
return '(char *data, uint16_t buf_len)'
|
||||
|
||||
|
||||
def _dt_trans_property_json_to_c_file(write_fd, _proterty_data):
|
||||
if _dt_not_exist(_proterty_data):
|
||||
return
|
||||
|
||||
# define property set/get function
|
||||
for property_id in _proterty_data:
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'static int ' + _dt_set_property_function_name(
|
||||
property_id.get(dt_config['JSON']['ID'])) +
|
||||
'(const char *data, uint16_t len)\n{\n\treturn 0;\n}\n')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'static int ' + _dt_get_property_function_name(
|
||||
property_id.get(dt_config['JSON']['ID'])) +
|
||||
'%s\n{\n\treturn %s;\n}\n' %
|
||||
(_dt_get_function_param_by_type(
|
||||
property_id.get(dt_config['JSON']['DEFINE']).get(dt_config['JSON']['TYPE'])),
|
||||
_dt_get_ret_val_by_type(
|
||||
property_id.get(dt_config['JSON']['DEFINE']).get(dt_config['JSON']['TYPE']))))
|
||||
|
||||
# define property array
|
||||
_dt_write_newline_to_file(write_fd, 'static ble_property_t sg_ble_property_array[BLE_QIOT_PROPERTY_ID_BUTT] = {')
|
||||
for property_id in _proterty_data:
|
||||
_dt_write_newline_to_file(write_fd, '\t{%-30s %-30s %-20s %-20s},' %
|
||||
(_dt_set_property_function_name(property_id.get(dt_config['JSON']['ID'])) + ',',
|
||||
_dt_get_property_function_name(property_id.get(dt_config['JSON']['ID'])) + ',',
|
||||
_dt_get_property_mode(property_id.get(dt_config['JSON']['MODE'])) + ',',
|
||||
_dt_get_type_by_str(
|
||||
property_id.get(dt_config['JSON']['DEFINE']).get(dt_config['JSON']['TYPE']))
|
||||
))
|
||||
_dt_write_newline_to_file(write_fd, '};\n')
|
||||
|
||||
dt_property_file = open(os.path.join(script_path, 'dt_fixed_content', 'dt_ble_property'), 'r', encoding='UTF-8')
|
||||
dt_property_content = dt_property_file.read()
|
||||
dt_property_file.close()
|
||||
# write operation to file
|
||||
_dt_write_newline_to_file(write_fd, dt_property_content)
|
||||
pass
|
||||
|
||||
|
||||
def _dt_trans_event_json_to_c_file(write_fd, _evnet_data):
|
||||
if _dt_not_exist(_evnet_data):
|
||||
return
|
||||
|
||||
for event in _evnet_data:
|
||||
# define event get function
|
||||
for param in event.get('params'):
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'static int ' + 'ble_event_get_' + event.get(dt_config['JSON']['ID']).lower() +
|
||||
'_' + param.get(dt_config['JSON']['ID']).lower() + '%s\n{\n\treturn %s;\n}\n' %
|
||||
(_dt_get_function_param_by_type(
|
||||
param.get(dt_config['JSON']['DEFINE']).get(dt_config['JSON']['TYPE'])),
|
||||
_dt_get_ret_val_by_type(
|
||||
param.get(dt_config['JSON']['DEFINE']).get(dt_config['JSON']['TYPE']))))
|
||||
# define param array
|
||||
_dt_write_newline_to_file(write_fd, 'static ble_event_param sg_ble_event_%s_array[%s] = {' %
|
||||
(event.get(dt_config['JSON']['ID']).lower(),
|
||||
dt_config['FILE']['ENUM_PREFIX'] + 'EVENT_' +
|
||||
event.get(dt_config['JSON']['ID']).upper() + '_PARAM_ID_BUTT'))
|
||||
for param in event.get('params'):
|
||||
_dt_write_newline_to_file(write_fd, '\t{%-32s %-20s},' % (
|
||||
'ble_event_get_' + event.get(dt_config['JSON']['ID']).lower() + '_' + param.get(
|
||||
dt_config['JSON']['ID']).lower() + ', ',
|
||||
_dt_get_type_by_str(param.get(dt_config['JSON']['DEFINE']).get(dt_config['JSON']['TYPE']))))
|
||||
_dt_write_newline_to_file(write_fd, '};\n')
|
||||
|
||||
# define event array
|
||||
_dt_write_newline_to_file(write_fd, 'static ble_event_t sg_ble_event_array[BLE_QIOT_EVENT_ID_BUTT] = {')
|
||||
for event in _evnet_data:
|
||||
_dt_write_newline_to_file(write_fd, '\t{%-32s %-32s},' % (
|
||||
'sg_ble_event_' + event.get(dt_config['JSON']['ID']).lower() + '_array,',
|
||||
'sizeof(sg_ble_event_' + event.get(dt_config['JSON']['ID']).lower() + '_array) / sizeof(ble_event_param)'))
|
||||
_dt_write_newline_to_file(write_fd, '};\n')
|
||||
|
||||
dt_event_file = open(os.path.join(script_path, 'dt_fixed_content', 'dt_ble_event'), 'r', encoding='UTF-8')
|
||||
dt_event_content = dt_event_file.read()
|
||||
dt_event_file.close()
|
||||
# write operation to file
|
||||
_dt_write_newline_to_file(write_fd, dt_event_content)
|
||||
pass
|
||||
|
||||
|
||||
def _dt_trans_action_json_to_c_file(write_fd, _action_data):
|
||||
if _dt_not_exist(_action_data):
|
||||
return
|
||||
|
||||
for idx, action in enumerate(_action_data):
|
||||
# define action input and output callback
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'static int ' + 'ble_action_handle_' + action.get(
|
||||
dt_config['JSON']['ID']).lower() + '_input_cb' +
|
||||
'(e_ble_tlv *input_param_array, uint8_t input_array_size, uint8_t *output_id_array)\n'
|
||||
'{\n\treturn 0;\n}\n')
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'static int ' + 'ble_action_handle_' + action.get(
|
||||
dt_config['JSON']['ID']).lower() + '_output_cb' +
|
||||
'(uint8_t output_id, char *buf, uint16_t buf_len)\n'
|
||||
'{\n\treturn buf_len;\n}\n')
|
||||
# define type array of input id
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'static uint8_t ' + 'sg_ble_action_%s_input_type_array[%s] = {' %
|
||||
(action.get(dt_config['JSON']['ID']).lower(),
|
||||
dt_config['FILE']['ENUM_PREFIX'] + 'ACTION_' +
|
||||
action.get(dt_config['JSON']['ID']).upper() + '_INPUT_ID_BUTT'))
|
||||
for input_id in action.get('input'):
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\t' + _dt_get_type_by_str(input_id.get(dt_config['JSON']['DEFINE']).get(
|
||||
dt_config['JSON']['TYPE'])) + ',')
|
||||
_dt_write_newline_to_file(write_fd, '};\n')
|
||||
|
||||
# define type array of output id
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'static uint8_t ' + 'sg_ble_action_%s_output_type_array[%s] = {' % (
|
||||
action.get(dt_config['JSON']['ID']).lower(),
|
||||
dt_config['FILE']['ENUM_PREFIX'] + 'ACTION_' + action.get(
|
||||
dt_config['JSON']['ID']).upper() + '_OUTPUT_ID_BUTT'))
|
||||
for input_id in action.get('output'):
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\t' + _dt_get_type_by_str(input_id.get(dt_config['JSON']['DEFINE']).get(
|
||||
dt_config['JSON']['TYPE'])) + ',')
|
||||
_dt_write_newline_to_file(write_fd, '};\n')
|
||||
|
||||
# define action array
|
||||
_dt_write_newline_to_file(write_fd, 'static ble_action_t ' + 'sg_ble_action_array[BLE_QIOT_ACTION_ID_BUTT] = {')
|
||||
for action in _action_data:
|
||||
_dt_write_newline_to_file(write_fd,
|
||||
'\t{ble_action_handle_%s_input_cb, ble_action_handle_%s_output_cb, \n'
|
||||
'\t\tsg_ble_action_%s_input_type_array, sg_ble_action_%s_output_type_array, \n'
|
||||
'\t\tsizeof(sg_ble_action_%s_input_type_array) / sizeof(uint8_t), \n'
|
||||
'\t\tsizeof(sg_ble_action_%s_output_type_array) / sizeof(uint8_t)},' %
|
||||
(action.get(dt_config['JSON']['ID']).lower(),
|
||||
action.get(dt_config['JSON']['ID']).lower(),
|
||||
action.get(dt_config['JSON']['ID']).lower(),
|
||||
action.get(dt_config['JSON']['ID']).lower(),
|
||||
action.get(dt_config['JSON']['ID']).lower(),
|
||||
action.get(dt_config['JSON']['ID']).lower()))
|
||||
_dt_write_newline_to_file(write_fd, '};\n')
|
||||
|
||||
dt_action_file = open(os.path.join(script_path, 'dt_fixed_content', 'dt_ble_action'), 'r', encoding='UTF-8')
|
||||
dt_action_content = dt_action_file.read()
|
||||
dt_action_file.close()
|
||||
# write operation to file
|
||||
_dt_write_newline_to_file(write_fd, dt_action_content)
|
||||
pass
|
||||
|
||||
|
||||
def _dt_generate_c_file(_json_data):
|
||||
c_file = open(dt_config['FILE']['NAME_PREFIX'] + '.c', 'w', encoding='UTF-8')
|
||||
|
||||
_dt_write_newline_to_file(c_file, dt_config['FILE']['COPYRIGHT'])
|
||||
_dt_write_newline_to_file(c_file, '#ifdef __cplusplus\nextern "C" {\n#endif\n')
|
||||
|
||||
_dt_write_newline_to_file(c_file, '#include "ble_qiot_template.h"\n')
|
||||
_dt_write_newline_to_file(c_file, '#include <stdio.h>')
|
||||
_dt_write_newline_to_file(c_file, '#include <stdbool.h>')
|
||||
_dt_write_newline_to_file(c_file, '#include <string.h>\n')
|
||||
_dt_write_newline_to_file(c_file, '#include "ble_qiot_export.h"')
|
||||
_dt_write_newline_to_file(c_file, '#include "ble_qiot_common.h"')
|
||||
_dt_write_newline_to_file(c_file, '#include "ble_qiot_param_check.h"\n')
|
||||
|
||||
_dt_trans_property_json_to_c_file(c_file, _json_data.get(dt_config['JSON']['PROPERTY']))
|
||||
_dt_trans_event_json_to_c_file(c_file, _json_data.get(dt_config['JSON']['EVENT']))
|
||||
_dt_trans_action_json_to_c_file(c_file, _json_data.get(dt_config['JSON']['ACTION']))
|
||||
_dt_write_newline_to_file(c_file, '\n#ifdef __cplusplus\n}\n#endif')
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
print('Usage: python3 %s <json_file>' % sys.argv[0])
|
||||
else:
|
||||
print("reading json file start")
|
||||
json_data = _dt_get_json_from_file(sys.argv[1])
|
||||
print("reading json file end")
|
||||
|
||||
print("generate header file start")
|
||||
_dt_generate_header_file(json_data)
|
||||
print("generate header file end")
|
||||
print("generate source file start")
|
||||
_dt_generate_c_file(json_data)
|
||||
print("generate source file end")
|
||||
pass
|
Reference in New Issue
Block a user