支持BLE设备接入“腾讯连连”小程序

This commit is contained in:
zekwang
2020-12-01 20:11:07 +08:00
parent 2a06226767
commit a6ff5bb42b
151 changed files with 47376 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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编译即可。

View File

@@ -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;
}
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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