diff --git a/examples/ilopicaapp/ilopmain.c b/examples/ilopicaapp/ilopmain.c index baecf10..4d50de9 100644 --- a/examples/ilopicaapp/ilopmain.c +++ b/examples/ilopicaapp/ilopmain.c @@ -1,127 +1,149 @@ -/** - ****************************************************************************** - * @file ilopmain.c - * @author QQ Ding - * @version V1.0.0 - * @date 3-Sept-2018 - * @brief ILOP Service Main function - ****************************************************************************** - * - * Copyright (c) 2009-2018 MXCHIP Co.,Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - ****************************************************************************** - */ - -#include "alicloud_ilop.h" -#include "mx_common.h" -#include "mx_debug.h" - -#include "emh_api.h" -#include "main.h" -#include "mx_cli.h" -#include "mx_hal.h" - -const char thing[] = "{\"schema\":\"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json\",\"profile\":{\"productKey\":\"a1MeLuIJPYL\"},\"services\":[{\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":true,\"callType\":\"async\",\"desc\":\"属性设置\"},{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"identifier\":\"get\",\"inputData\":[\"LightSwitch\",\"ColorTemperature\",\"NightLightSwitch\",\"WorkMode\",\"RGBColor\"],\"method\":\"thing.service.property.get\",\"name\":\"get\",\"required\":true,\"callType\":\"async\",\"desc\":\"属性获取\"},{\"outputData\":[],\"identifier\":\"TimeReset\",\"inputData\":[{\"identifier\":\"TimeReset\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"TimeReset\"}],\"method\":\"thing.service.TimeReset\",\"name\":\"设备校时服务\",\"required\":false,\"callType\":\"async\"}],\"properties\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\",\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\",\"accessMode\":\"rw\",\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"属性上报\"},{\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{\"0\":\"恢复正常\"},\"type\":\"enum\"},\"name\":\"故障代码\"}],\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":\"故障上报\",\"type\":\"error\",\"required\":true}]}"; - -static int awss_start = 0; -static int awss_press = 0; -static int reset = 0; - -const emh_ilop_config_t ilop_config = { - .tsl_thing = thing, - .tsl_len = strlen(thing), - .dm = EMH_ARG_ILOP_DM_ICA_BY_LOCAL, -}; - -const ilop_device_key_t device_key = { - .product_key = "a1MeLuIJPYL", - .product_secret = "SegyIuWW6xBQGuIc", - .device_name = "aQI0eEM5g2nlSr2njD0x", - .device_secret = "o7EZShzl6z8F3xq8qF3vN9P7HFGslRAV", -}; - -static void user_tast_loop(void) -{ - if (awss_start == 1) { - ilop_awss_start(); - awss_start = 0; - } - if (awss_press == 1) { - ilop_awss_press(); - awss_press = 0; - } - if (reset == 1) { - ilop_restore(); - reset = 0; - } -} - -#ifdef MX_CLI_ENABLE -static void handle_aws_cmd(char* pwbuf, int blen, int argc, char** argv) -{ - if (argc != 2) - return; - - if (strcmp(argv[1], "start") == 0) { - awss_start = 1; - } else if (strcmp(argv[1], "press") == 0) { - awss_press = 1; - } -} - -static void handle_reset_cmd(char* pwbuf, int blen, int argc, char** argv) -{ - reset = 1; -} - -static struct cli_command ilopcmds[] = { - { "aws", "aws [start|press]", handle_aws_cmd }, - { "reset", "clean wifi module and ilop service", handle_reset_cmd }, -}; -#endif - -void ilop_main(void) -{ - mx_status err = kNoErr; - - /* System initialization, ticker, stdio */ - mx_hal_ms_ticker_init(); - mx_hal_stdio_init(); - -#ifdef MX_CLI_ENABLE - cli_register_commands(ilopcmds, sizeof(ilopcmds) / sizeof(struct cli_command)); -#endif - - /* ILOP service initialization */ - err = ilop_init(&ilop_config); - if (err != kNoErr) - app_log("ilop init err"); - - /* Set the ILOP three tuple. If the module is pre burned, delete the function */ - ilop_set_device_key(&device_key); - - /* database initialization */ - ilop_ica_attr_init(ILOP_HANDLE_ATTR_MAX); - - property_register(); - service_register(); - event_register(); - - while (1) { - ilop_runloop(); - user_tast_loop(); - event_task_loop(); - } -} +/** + ****************************************************************************** + * @file ilopmain.c + * @author QQ Ding + * @version V1.0.0 + * @date 3-Sept-2018 + * @brief ILOP Service Main function + ****************************************************************************** + * + * Copyright (c) 2009-2018 MXCHIP Co.,Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************** + */ + +#include "alicloud_ilop.h" +#include "mx_common.h" +#include "mx_debug.h" + +#include "emh_api.h" +#include "main.h" +#include "mx_cli.h" +#include "mx_hal.h" + +#ifdef USE_DOMAIN_GLOBAL +const char thing[] = "{\"schema\":\"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json\",\"profile\":{\"productKey\":\"a1MeLuIJPYL\"},\"services\":[{\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":true,\"callType\":\"async\",\"desc\":\"属性设置\"},{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"identifier\":\"get\",\"inputData\":[\"LightSwitch\",\"ColorTemperature\",\"NightLightSwitch\",\"WorkMode\",\"RGBColor\"],\"method\":\"thing.service.property.get\",\"name\":\"get\",\"required\":true,\"callType\":\"async\",\"desc\":\"属性获取\"},{\"outputData\":[],\"identifier\":\"TimeReset\",\"inputData\":[{\"identifier\":\"TimeReset\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"TimeReset\"}],\"method\":\"thing.service.TimeReset\",\"name\":\"设备校时服务\",\"required\":false,\"callType\":\"async\"}],\"properties\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\",\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\",\"accessMode\":\"rw\",\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"属性上报\"},{\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{\"0\":\"恢复正常\"},\"type\":\"enum\"},\"name\":\"故障代码\"}],\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":\"故障上报\",\"type\":\"error\",\"required\":true}]}"; + +static int awss_start = 0; +static int awss_press = 0; +static int reset = 0; + +const emh_ilop_config_t ilop_config = { + .tsl_thing = thing, + .tsl_len = strlen(thing), + .dm = EMH_ARG_ILOP_DM_ICA_BY_LOCAL, + .domain = EMH_ARG_ILOP_DOMAIN_SINGAPORE, +}; + +const ilop_device_key_t device_key = { + .product_key = "a1JjSehcuht", + .product_secret = "K2l3CXzeiRgaaCEt", + .device_name = "light_g", + .device_secret = "gCk4yIDdXce7mdSrhJbpZyC9z3PiqjfB", +}; +#else +const char thing[] = "{\"schema\":\"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json\",\"profile\":{\"productKey\":\"a1MeLuIJPYL\"},\"services\":[{\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":true,\"callType\":\"async\",\"desc\":\"属性设置\"},{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"identifier\":\"get\",\"inputData\":[\"LightSwitch\",\"ColorTemperature\",\"NightLightSwitch\",\"WorkMode\",\"RGBColor\"],\"method\":\"thing.service.property.get\",\"name\":\"get\",\"required\":true,\"callType\":\"async\",\"desc\":\"属性获取\"},{\"outputData\":[],\"identifier\":\"TimeReset\",\"inputData\":[{\"identifier\":\"TimeReset\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"TimeReset\"}],\"method\":\"thing.service.TimeReset\",\"name\":\"设备校时服务\",\"required\":false,\"callType\":\"async\"}],\"properties\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\",\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\",\"accessMode\":\"rw\",\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"}],\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"属性上报\"},{\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{\"0\":\"恢复正常\"},\"type\":\"enum\"},\"name\":\"故障代码\"}],\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":\"故障上报\",\"type\":\"error\",\"required\":true}]}"; + +static int awss_start = 0; +static int awss_press = 0; +static int reset = 0; + +const emh_ilop_config_t ilop_config = { + .tsl_thing = thing, + .tsl_len = strlen(thing), + .dm = EMH_ARG_ILOP_DM_ICA_BY_LOCAL, + .domain = EMH_ARG_ILOP_DOMAIN_SHANGHAI, +}; + +const ilop_device_key_t device_key = { + .product_key = "a1MeLuIJPYL", + .product_secret = "SegyIuWW6xBQGuIc", + .device_name = "aQI0eEM5g2nlSr2njD0x", + .device_secret = "o7EZShzl6z8F3xq8qF3vN9P7HFGslRAV", +}; +#endif +static void user_tast_loop(void) +{ + if (awss_start == 1) { + ilop_awss_start(); + awss_start = 0; + } + if (awss_press == 1) { + ilop_awss_press(); + awss_press = 0; + } + if (reset == 1) { + ilop_restore(); + reset = 0; + } +} + +#ifdef MX_CLI_ENABLE +static void handle_aws_cmd(char* pwbuf, int blen, int argc, char** argv) +{ + if (argc != 2) + return; + + if (strcmp(argv[1], "start") == 0) { + awss_start = 1; + } else if (strcmp(argv[1], "press") == 0) { + awss_press = 1; + } +} + +static void handle_reset_cmd(char* pwbuf, int blen, int argc, char** argv) +{ + reset = 1; +} + +static struct cli_command ilopcmds[] = { + { "aws", "aws [start|press]", handle_aws_cmd }, + { "reset", "clean wifi module and ilop service", handle_reset_cmd }, +}; +#endif + +void ilop_main(void) +{ + mx_status err = kNoErr; + + /* System initialization, ticker, stdio */ + mx_hal_ms_ticker_init(); + mx_hal_stdio_init(); + +#ifdef MX_CLI_ENABLE + cli_register_commands(ilopcmds, sizeof(ilopcmds) / sizeof(struct cli_command)); +#endif + + /* ILOP service initialization */ + err = ilop_init(&ilop_config); + if (err != kNoErr) + app_log("ilop init err"); + + /* Set the ILOP three tuple. If the module is pre burned, delete the function */ + ilop_set_device_key(&device_key); + + /* database initialization */ + ilop_ica_attr_init(ILOP_HANDLE_ATTR_MAX); + + property_register(); + service_register(); + event_register(); + + while (1) { + ilop_runloop(); + user_tast_loop(); + event_task_loop(); + } +} diff --git a/examples/iloprawapp/ilopmain.c b/examples/iloprawapp/ilopmain.c index bb6cae3..f923174 100644 --- a/examples/iloprawapp/ilopmain.c +++ b/examples/iloprawapp/ilopmain.c @@ -1,104 +1,105 @@ -#include "alicloud_ilop.h" -#include "emh_api.h" -#include "main.h" -#include "mx_cli.h" -#include "mx_common.h" -#include "mx_debug.h" -#include "mx_hal.h" - -static int awss_start = 0; -static int awss_press = 0; -static int reset = 0; - -const emh_ilop_config_t ilop_config = { - .tls_thing = NULL, - .tls_len = 0, - .dm = EMH_ARG_ILOP_DM_RAW, -}; - -const ilop_device_key_t device_key = { - .product_key = "b1CcQqrXoVR", - .product_secret = "yOrZrmtDcHLgVOJc", - .device_name = "sPhDWW7vvaSyUfNBOvM9", - .device_secret = "R90glnJXJNAUsKGSRRudMdlhyvA12OEM", -}; - -static void awss_tast_loop(void) -{ - if (awss_start == 1) { - ilop_awss_start(); - awss_start = 0; - } - if (awss_press == 1) { - ilop_awss_press(); - awss_press = 0; - } - if( reset == 1 ) - { - ilop_restore(); - reset = 0; - } -} - -#ifdef MX_CLI_ENABLE -static void handle_aws_cmd(char* pwbuf, int blen, int argc, char** argv) -{ - if (argc != 2) - return; - - if (strcmp(argv[1], "start") == 0) { - awss_start = 1; - } else if (strcmp(argv[1], "press") == 0) { - awss_press = 1; - } -} - -static void handle_reset_cmd(char* pwbuf, int blen, int argc, char** argv) -{ - reset = 1; -} - -static struct cli_command ilopcmds[] = { - { "aws", "aws [start|press]", handle_aws_cmd }, - { "reset", "clean wifi module and ilop service", handle_reset_cmd }, -}; -#endif - -void ilop_main(void) -{ - mx_status err = kNoErr; - - /* System initialization, ticker, stdio */ - mx_hal_ms_ticker_init(); - mx_hal_stdio_init(); - -#ifdef MX_CLI_ENABLE - cli_register_commands(ilopcmds, sizeof(ilopcmds) / sizeof(struct cli_command)); -#endif - - /* ILOP service initialization */ - err = ilop_init(&ilop_config); - if (err != kNoErr) - app_log("ilop init err"); - - /* Set the ILOP three tuple. If the module is pre burned, delete the function */ - ilop_set_device_key(&device_key); - - /* database initialization */ - ilop_raw_attr_init(ATTR_TYPE_PROPERTY, ILOP_PROPERTY_MAX); - ilop_raw_attr_init(ATTR_TYPE_EVENT, ILOP_EVENT_MAX); - ilop_raw_attr_init(ATTR_TYPE_SERVICE, ILOP_SERVICE_MAX); - - event_register(); - property_register_light(); - property_register_wifi(); - service_register(); - - while (1) { - ilop_runloop(); - awss_tast_loop(); - event_task_loop(); - } - - return; -} +#include "alicloud_ilop.h" +#include "emh_api.h" +#include "main.h" +#include "mx_cli.h" +#include "mx_common.h" +#include "mx_debug.h" +#include "mx_hal.h" + +static int awss_start = 0; +static int awss_press = 0; +static int reset = 0; + +const emh_ilop_config_t ilop_config = { + .tsl_thing = NULL, + .tsl_len = 0, + .dm = EMH_ARG_ILOP_DM_RAW, + .domain = EMH_ARG_ILOP_DOMAIN_SHANGHAI, +}; + +const ilop_device_key_t device_key = { + .product_key = "b1CcQqrXoVR", + .product_secret = "yOrZrmtDcHLgVOJc", + .device_name = "sPhDWW7vvaSyUfNBOvM9", + .device_secret = "R90glnJXJNAUsKGSRRudMdlhyvA12OEM", +}; + +static void awss_tast_loop(void) +{ + if (awss_start == 1) { + ilop_awss_start(); + awss_start = 0; + } + if (awss_press == 1) { + ilop_awss_press(); + awss_press = 0; + } + if( reset == 1 ) + { + ilop_restore(); + reset = 0; + } +} + +#ifdef MX_CLI_ENABLE +static void handle_aws_cmd(char* pwbuf, int blen, int argc, char** argv) +{ + if (argc != 2) + return; + + if (strcmp(argv[1], "start") == 0) { + awss_start = 1; + } else if (strcmp(argv[1], "press") == 0) { + awss_press = 1; + } +} + +static void handle_reset_cmd(char* pwbuf, int blen, int argc, char** argv) +{ + reset = 1; +} + +static struct cli_command ilopcmds[] = { + { "aws", "aws [start|press]", handle_aws_cmd }, + { "reset", "clean wifi module and ilop service", handle_reset_cmd }, +}; +#endif + +void ilop_main(void) +{ + mx_status err = kNoErr; + + /* System initialization, ticker, stdio */ + mx_hal_ms_ticker_init(); + mx_hal_stdio_init(); + +#ifdef MX_CLI_ENABLE + cli_register_commands(ilopcmds, sizeof(ilopcmds) / sizeof(struct cli_command)); +#endif + + /* ILOP service initialization */ + err = ilop_init(&ilop_config); + if (err != kNoErr) + app_log("ilop init err"); + + /* Set the ILOP three tuple. If the module is pre burned, delete the function */ + ilop_set_device_key(&device_key); + + /* database initialization */ + ilop_raw_attr_init(ATTR_TYPE_PROPERTY, ILOP_PROPERTY_MAX); + ilop_raw_attr_init(ATTR_TYPE_EVENT, ILOP_EVENT_MAX); + ilop_raw_attr_init(ATTR_TYPE_SERVICE, ILOP_SERVICE_MAX); + + event_register(); + property_register_light(); + property_register_wifi(); + service_register(); + + while (1) { + ilop_runloop(); + awss_tast_loop(); + event_task_loop(); + } + + return; +} diff --git a/src/alicloud_ilop/raw_protocol.c b/src/alicloud_ilop/raw_protocol.c index f7cca00..9a3f140 100644 --- a/src/alicloud_ilop/raw_protocol.c +++ b/src/alicloud_ilop/raw_protocol.c @@ -1,617 +1,618 @@ -/** - ****************************************************************************** - * @file raw_protocol.c - * @author QQ Ding - * @version V1.0.0 - * @date 3-Step-2018 - * @brief AliCloud ILOP service functions and raw data parser - ****************************************************************************** - * - * Copyright (c) 2009-2018 MXCHIP Co.,Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - ****************************************************************************** - */ - -#include "raw_protocol.h" -#include "alicloud_ilop.h" - -/****************************************************************************** - * Macros - ******************************************************************************/ - -#define MAX_ATTR 20 /**< attribute max value */ - -/****************************************************************************** - * Type Definitions - ******************************************************************************/ - -typedef struct _ilop_raw_attr_t { - const struct ilop_raw_attr_t* attr_db[MAX_ATTR]; - int changed_handle[MAX_ATTR]; - int num_handles; -} ilop_raw_context_t; - -/****************************************************************************** - * Variable Definitions - ******************************************************************************/ - -static ilop_raw_context_t property_db; -static ilop_raw_context_t event_db; -static ilop_raw_context_t service_db; -static uint32_t seed_id = 0; - -/****************************************************************************** - * Function Definitions - ******************************************************************************/ - -/* Computation and verification */ -static uint8_t cal_checksum(uint8_t* buffer, uint16_t length) -{ - int32_t i; - uint8_t check_sum = 0; - - for (i = 0; i < length; i++) { - check_sum += buffer[i]; - } - - return check_sum; -} - -static uint32_t get_seed_id(void) -{ - if (seed_id == 0xFFFFFFFF) - seed_id = 0; - - return seed_id++; -} - -/* Protocol header initialization */ -static void protFrameHeadInit(data_buffer_t* buff, uint8_t cmd) -{ - uint8_t check_sum; - raw_protocol_head_t* head = (raw_protocol_head_t*)buff->buffer; - - /* Requiring the use of big endian mode transmission */ - head->head = RAW_PROTOCOL_HEAD; - head->ver = RAW_PROTOCOL_VER; - head->cmd = cmd; - head->length = hton16(buff->length - 2); - check_sum = cal_checksum(buff->buffer, buff->length); - buff->buffer[buff->length++] = check_sum; /* write check sum */ -} - -static uint32_t protocol_value_handler(const struct ilop_raw_attr_t* attr, uint8_t* addr, uint32_t length) -{ - uint16_t size = 0; - ilop_att_val_t value; - - switch (attr->type_id) { - case TYPE_ID_BOOL: { - size = 1; - value.boolValue = *addr; - break; - } - - case TYPE_ID_INT8: { - size = 1; - value.int8Value = *addr; - break; - } - case TYPE_ID_UINT8: { - size = 1; - value.uint8Value = *addr; - break; - } - - case TYPE_ID_INT16: { - size = 2; - value.int16Value = (uint16_t)*addr; - value.int16Value = ntoh16(value.int16Value); - break; - } - - case TYPE_ID_UINT16: { - size = 2; - value.uint16Value = (uint16_t)*addr; - value.uint16Value = ntoh16(value.uint16Value); - break; - } - - case TYPE_ID_INT32: { - size = 4; - value.int32Value = (int32_t)*addr; - value.int32Value = ntoh32(value.int32Value); - break; - } - - case TYPE_ID_UINT32: { - size = 4; - value.uint32Value = (uint32_t)*addr; - value.uint32Value = ntoh32(value.uint32Value); - break; - } - - case TYPE_ID_FLOAT32: { - size = 4; - value.floatValue = (float)*addr; - value.floatValue = ntoh32(value.floatValue); - break; - } - - /*8 byte*/ - case TYPE_ID_DATE: - case TYPE_ID_UINT64: { - size = 8; - value.uint64Value = (uint64_t)*addr; - value.uint64Value = ntoh64(value.uint64Value); - break; - } - - case TYPE_ID_INT64: { - size = 8; - value.int64Value = (uint64_t)*addr; - value.int64Value = ntoh64(value.int64Value); - break; - } - - case TYPE_ID_FLOAT64: { - size = 8; - value.doubleValue = (uint64_t)*addr; - value.doubleValue = ntoh64(value.doubleValue); - break; - } - - /*string*/ - case TYPE_ID_STRING: { - size = hton16(*((uint16_t*)addr)); - value.stringValue = (char*)(addr + sizeof(size)); - break; - } - - default: { - size = length; - value.dataValue = (uint8_t*)(addr); - break; - } - } - - if (attr->write_func != NULL) { - attr->write_func(value, size); - if (attr->type_id == TYPE_ID_STRING) { - size += sizeof(size); - } - } - - return size; -} - -static uint32_t protocol_service_handler(const struct ilop_raw_attr_t* attr, uint8_t* addr, uint32_t size) -{ - ilop_att_val_t value; - - if (attr->write_func != NULL) { - value.dataValue = addr; - attr->write_func(value, size); - } - return size; -} - -static int get_property_thing_index(uint8_t attr_id, uint8_t type_id) -{ - int i, handle = 0; - - for (i = 0; i < property_db.num_handles; i++) { - if (property_db.attr_db[i] == NULL) - continue; - handle = property_db.attr_db[i]->index; - - if ((property_db.attr_db[handle]->attr_id == attr_id) && ((property_db.attr_db[handle]->type_id == type_id))) { - ilop_log("find property index:%d", handle); - return handle; - } - } - - return -1; -} - -static int get_service_thing_index(uint8_t attr_id) -{ - int i, handle = 0; - - ilop_log("search attr_id:%d", attr_id); - - for (i = 0; i < service_db.num_handles; i++) { - if (service_db.attr_db[i] == NULL) - continue; - handle = service_db.attr_db[i]->index; - - if (service_db.attr_db[handle]->attr_id == attr_id) { - ilop_log("find service index:%d", handle); - return handle; - } - } - - return -1; -} - -/* Processing SET requests issued under cloud */ -static mx_status protocol_method_handler(uint8_t method, uint8_t* data, uint16_t length) -{ - int32_t offset = 0, index = -1, ret = 0; - raw_body_format_t* elem; - - while ((length - offset) > 0) { - if (method == RAW_METHOD_SET) { - elem = (raw_body_format_t*)(data + offset); - index = get_property_thing_index(elem->attr_id, elem->type_id); - if (index < 0) { - ilop_log("attr_id or type_id err"); - return kGeneralErr; - } - - offset += sizeof(raw_body_format_t) - 1; - ret = protocol_value_handler(property_db.attr_db[index], &elem->value, length - 2); - } else if (method == RAW_METHOD_SERVICE) { - uint8_t attr_id = *data; - index = get_service_thing_index(attr_id); - if (index < 0) { - ilop_log("attr_id err"); - return kGeneralErr; - } - offset += 1; - ret = protocol_service_handler(service_db.attr_db[index], data + offset, length - 1); - } - if (ret == kUnsupportedErr) - return kNotReadableErr; - offset += ret; - } - - return kNoErr; -} - -/* Handling data transmitted by server side */ -static mx_status protocol_payloa_handler(uint8_t* data, uint16_t length) -{ - raw_payload_data_head_t* payload = (raw_payload_data_head_t*)data; - - switch (payload->method) { - /* Method of active sending from server side */ - // case RAW_METHOD_GET: - // protGetMethodHandler(&payload->data, length - sizeof(raw_payload_data_head_t) + 1); - // break; - - case RAW_METHOD_SET: - ilop_log("raw method set"); - protocol_method_handler(RAW_METHOD_SET, &payload->data, length - sizeof(raw_payload_data_head_t) + 1); - break; - - case RAW_METHOD_SERVICE: - ilop_log("raw method service"); - protocol_method_handler(RAW_METHOD_SERVICE, &payload->data, length - sizeof(raw_payload_data_head_t) + 1); - break; - - default: - ilop_wlog("Method(%d) not support\n", payload->method); - return kParamErr; - } - - return kNoErr; -} - -/* Processing protocol frames */ -mx_status raw_protocol_format_handler(uint8_t* data, uint32_t length) -{ - raw_protocol_head_t* head = (raw_protocol_head_t*)data; - uint8_t cmd = head->cmd; - - switch (cmd) { - case RAW_DOWN_DATA: - ilop_log("raw down data len:%d", ntoh16(head->length)); - protocol_payloa_handler(data + RAW_PROTOCOL_REGION_HEAD_LEN, - ntoh16(head->length) - RAW_PROTOCOL_REGION_LENGTH_FIXED); - break; - - default: - ilop_wlog("Cmd %02x not support\n", cmd); - break; - } - - return kNoErr; -} - -static void protocol_add_body(const struct ilop_raw_attr_t* attr, data_buffer_t* buf) -{ - ilop_att_val_t value; - uint32_t len; - - ilop_log("add body attr_id:%d", attr->attr_id); - - raw_body_format_t* body = (raw_body_format_t*)(buf->buffer + buf->length); - body->attr_id = attr->attr_id; - body->type_id = attr->type_id; - buf->length += sizeof(raw_body_format_t) - 1; - - attr->read_func(&value, &len); - - switch (attr->type_id) { - /*1 byte*/ - case TYPE_ID_BOOL: - case TYPE_ID_INT8: - case TYPE_ID_UINT8: - body->value = value.boolValue; - buf->length += 1; - break; - - /*2 byte*/ - case TYPE_ID_INT16: - case TYPE_ID_UINT16: { - uint16_t* p = (uint16_t*)&body->value; - *p = hton16(value.uint16Value); - buf->length += 2; - break; - } - - /*4 byte*/ - case TYPE_ID_INT32: - case TYPE_ID_UINT32: { - uint32_t* p = (uint32_t*)&body->value; - *p = hton32(value.uint32Value); - buf->length += 4; - break; - } - - case TYPE_ID_FLOAT32: { - float* p = (float*)&body->value; - *p = hton32(value.floatValue); - buf->length += 4; - break; - } - - /*8 byte*/ - case TYPE_ID_DATE: - case TYPE_ID_INT64: - case TYPE_ID_UINT64: { - uint64_t* p = (uint64_t*)&body->value; - *p = hton64(value.uint64Value); - buf->length += 4; - break; - } - - case TYPE_ID_FLOAT64: { - double* p = (double*)&body->value; - *p = hton32(value.doubleValue); - buf->length += 4; - break; - } - - /*string*/ - case TYPE_ID_STRING: { - uint8_t* p; - uint16_t* value_len = (uint16_t*)&body->value; - *value_len = hton16(len); - p = &body->value + sizeof(*value_len); - memcpy(p, value.stringValue, len); - buf->length += (len + 2); - break; - } - - default: { - uint8_t* p; - p = &body->value; - memcpy(p, value.dataValue, len); - buf->length += len; - ilop_log("default"); - break; - } - } -} - -/*To process the report attribute, it must be called in the ilop_runloop function.*/ -void ilop_raw_indicate_local_property(void) -{ - int i; - mx_status err = kNoErr; - - if ((property_db.num_handles == 0)) - return; - - for (i = 0; i < property_db.num_handles; i++) { - if (property_db.changed_handle[i] != ILOP_INVALID_HANDLE) - break; - } - if (i >= property_db.num_handles) - return; - - ilop_log("local property"); - - int handle; - - data_buffer_t data_buff; - memset(&data_buff, 0x00, sizeof(data_buffer_t)); - - data_buff.length = RAW_PROTOCOL_REGION_HEAD_LEN; - - raw_payload_data_head_t* payload = (raw_payload_data_head_t*)(data_buff.buffer + RAW_PROTOCOL_REGION_HEAD_LEN); - payload->method = RAW_METHOD_GET; - payload->id = hton32(get_seed_id()); - - data_buff.length += sizeof(raw_payload_data_head_t) - 1; - - for (i = 0; i < property_db.num_handles; i++) { - if (property_db.changed_handle[i] == ILOP_INVALID_HANDLE) - continue; - - handle = property_db.changed_handle[i]; - - if (property_db.attr_db[handle]->read_func == NULL) - continue; - - protocol_add_body(property_db.attr_db[handle], &data_buff); - } - - protFrameHeadInit(&data_buff, RAW_UP_DATA); - - printf("\r\n"); - for (int i = 0; i < data_buff.length; i++) { - printf("%02X", data_buff.buffer[i]); - } - printf("\r\n"); - - err = emh_ilop_send_raw_to_cloud(data_buff.buffer, data_buff.length); - require_noerr(err, exit); - - for (i = 0; i < property_db.num_handles; i++) { - property_db.changed_handle[i] = ILOP_INVALID_HANDLE; - } - -exit: - return; -} - -/*To process the report events, it must be called in the ilop_runloop function*/ -void ilop_raw_indicate_local_event(void) -{ - mx_status err = kNoErr; - int i, handle = 0; - - if (event_db.num_handles == 0) - return; - - for (i = 0; i < event_db.num_handles; i++) { - if (event_db.changed_handle[i] != ILOP_INVALID_HANDLE) { - handle = event_db.changed_handle[i]; - break; - } - } - if (i >= event_db.num_handles) - return; - - ilop_log("local event"); - - data_buffer_t data_buff; - memset(&data_buff, 0x00, sizeof(data_buffer_t)); - - data_buff.length = RAW_PROTOCOL_REGION_HEAD_LEN; - - raw_payload_data_head_t* payload = (raw_payload_data_head_t*)(data_buff.buffer + RAW_PROTOCOL_REGION_HEAD_LEN); - payload->method = RAW_METHOD_EVENT; - payload->id = hton32(get_seed_id()); - - data_buff.length += sizeof(raw_payload_data_head_t) - 1; - - if (event_db.attr_db[handle]->read_func == NULL) - goto exit; - - protocol_add_body(event_db.attr_db[handle], &data_buff); - - protFrameHeadInit(&data_buff, RAW_UP_DATA); - - printf("\r\n"); - for (int i = 0; i < data_buff.length; i++) { - printf("%02X", data_buff.buffer[i]); - } - printf("\r\n"); - - err = emh_ilop_send_raw_to_cloud(data_buff.buffer, data_buff.length); - require_noerr(err, exit); - - event_db.changed_handle[handle] = ILOP_INVALID_HANDLE; - -exit: - return; -} - -mx_status ilop_raw_attr_init(attr_type_t attr_type, uint8_t attr_num_handls) -{ - int i; - - for (i = 0; i < MAX_ATTR; i++) { - if (attr_type == ATTR_TYPE_PROPERTY) { - property_db.attr_db[i] = NULL; - } else if (attr_type == ATTR_TYPE_EVENT) { - event_db.attr_db[i] = NULL; - } else if (attr_type == ATTR_TYPE_SERVICE) { - service_db.attr_db[i] = NULL; - } - } - - for (i = 0; i < MAX_ATTR; i++) { - if (attr_type == ATTR_TYPE_PROPERTY) { - property_db.changed_handle[i] = ILOP_INVALID_HANDLE; - } else if (attr_type == ATTR_TYPE_EVENT) { - event_db.changed_handle[i] = ILOP_INVALID_HANDLE; - } else if (attr_type == ATTR_TYPE_SERVICE) { - service_db.changed_handle[i] = ILOP_INVALID_HANDLE; - } - } - - if (attr_type == ATTR_TYPE_PROPERTY) { - property_db.num_handles = attr_num_handls; - } else if (attr_type == ATTR_TYPE_EVENT) { - event_db.num_handles = attr_num_handls; - } else if (attr_type == ATTR_TYPE_SERVICE) { - service_db.num_handles = attr_num_handls; - } - - return kNoErr; -} - -mx_status ilop_raw_attr_register(attr_type_t attr_type, const struct ilop_raw_attr_t* attr) -{ - int handle = 0; - - if (attr_type == ATTR_TYPE_PROPERTY) { - if (property_db.num_handles > MAX_ATTR) - return kRangeErr; - - handle = attr->index; - property_db.attr_db[handle] = attr; - } else if (attr_type == ATTR_TYPE_EVENT) { - if (event_db.num_handles > MAX_ATTR) - return kRangeErr; - - handle = attr->index; - event_db.attr_db[handle] = attr; - } else if (attr_type == ATTR_TYPE_SERVICE) { - if (service_db.num_handles > MAX_ATTR) - return kRangeErr; - - handle = attr->index; - service_db.attr_db[handle] = attr; - } - - return kNoErr; -} - -void ilop_raw_attr_indicate_by_handle(attr_type_t attr_type, int handle) -{ - if (attr_type == ATTR_TYPE_PROPERTY) { - if (property_db.attr_db[handle] == NULL) - return; - if (property_db.attr_db[handle]->index == handle) { - if (property_db.changed_handle[handle] == handle) - return; - property_db.changed_handle[handle] = handle; - } - } else if (attr_type == ATTR_TYPE_EVENT) { - if (event_db.attr_db[handle] == NULL) - return; - if (event_db.attr_db[handle]->index == handle) { - if (event_db.changed_handle[handle] == handle) - return; - event_db.changed_handle[handle] = handle; - } - } -} +/** + ****************************************************************************** + * @file raw_protocol.c + * @author QQ Ding + * @version V1.0.0 + * @date 3-Step-2018 + * @brief AliCloud ILOP service functions and raw data parser + ****************************************************************************** + * + * Copyright (c) 2009-2018 MXCHIP Co.,Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************** + */ + +#include "raw_protocol.h" +#include "alicloud_ilop.h" + +/****************************************************************************** + * Macros + ******************************************************************************/ + +#define MAX_ATTR 20 /**< attribute max value */ + +/****************************************************************************** + * Type Definitions + ******************************************************************************/ + +typedef struct _ilop_raw_attr_t { + const struct ilop_raw_attr_t* attr_db[MAX_ATTR]; + int changed_handle[MAX_ATTR]; + int num_handles; +} ilop_raw_context_t; + +/****************************************************************************** + * Variable Definitions + ******************************************************************************/ + +static ilop_raw_context_t property_db; +static ilop_raw_context_t event_db; +static ilop_raw_context_t service_db; +static uint32_t seed_id = 0; + +/****************************************************************************** + * Function Definitions + ******************************************************************************/ + +/* Computation and verification */ +static uint8_t cal_checksum(uint8_t* buffer, uint16_t length) +{ + int32_t i; + uint8_t check_sum = 0; + + for (i = 0; i < length; i++) { + check_sum += buffer[i]; + } + + return check_sum; +} + +static uint32_t get_seed_id(void) +{ + if (seed_id == 0xFFFFFFFF) + seed_id = 0; + + return seed_id++; +} + +/* Protocol header initialization */ +static void protFrameHeadInit(data_buffer_t* buff, uint8_t cmd) +{ + uint8_t check_sum; + raw_protocol_head_t* head = (raw_protocol_head_t*)buff->buffer; + + /* Requiring the use of big endian mode transmission */ + head->head = RAW_PROTOCOL_HEAD; + head->ver = RAW_PROTOCOL_VER; + head->cmd = cmd; + head->length = hton16(buff->length - 2); + check_sum = cal_checksum(buff->buffer, buff->length); + buff->buffer[buff->length++] = check_sum; /* write check sum */ +} + +static uint32_t protocol_value_handler(const struct ilop_raw_attr_t* attr, uint8_t* addr, uint32_t length) +{ + uint16_t size = 0; + ilop_att_val_t value; + + switch (attr->type_id) { + case TYPE_ID_BOOL: { + size = 1; + value.boolValue = *addr; + break; + } + + case TYPE_ID_INT8: { + size = 1; + value.int8Value = *addr; + break; + } + case TYPE_ID_UINT8: { + size = 1; + value.uint8Value = *addr; + break; + } + + case TYPE_ID_INT16: { + size = 2; + value.int16Value = (uint16_t)*addr; + value.int16Value = ntoh16(value.int16Value); + break; + } + + case TYPE_ID_UINT16: { + size = 2; + value.uint16Value = (uint16_t)*addr; + value.uint16Value = ntoh16(value.uint16Value); + break; + } + + case TYPE_ID_INT32: { + size = 4; + value.int32Value = (int32_t)*addr; + value.int32Value = ntoh32(value.int32Value); + break; + } + + case TYPE_ID_UINT32: { + size = 4; + value.uint32Value = (uint32_t)*addr; + value.uint32Value = ntoh32(value.uint32Value); + break; + } + + case TYPE_ID_FLOAT32: { + size = 4; + value.floatValue = (float)*addr; + value.floatValue = ntoh32(value.floatValue); + break; + } + + /*8 byte*/ + case TYPE_ID_DATE: + case TYPE_ID_UINT64: { + size = 8; + value.uint64Value = (uint64_t)*addr; + value.uint64Value = ntoh64(value.uint64Value); + break; + } + + case TYPE_ID_INT64: { + size = 8; + value.int64Value = (uint64_t)*addr; + value.int64Value = ntoh64(value.int64Value); + break; + } + + case TYPE_ID_FLOAT64: { + size = 8; + value.doubleValue = (uint64_t)*addr; + value.doubleValue = ntoh64(value.doubleValue); + break; + } + + /*string*/ + case TYPE_ID_STRING: { + size = hton16(*((uint16_t*)addr)); + value.stringValue = (char*)(addr + sizeof(size)); + break; + } + + default: { + size = length; + value.dataValue = (uint8_t*)(addr); + break; + } + } + + if (attr->write_func != NULL) { + attr->write_func(value, size); + if (attr->type_id == TYPE_ID_STRING) { + size += sizeof(size); + } + } + + return size; +} + +static uint32_t protocol_service_handler(const struct ilop_raw_attr_t* attr, uint8_t* addr, uint32_t size) +{ + ilop_att_val_t value; + + if (attr->write_func != NULL) { + value.dataValue = addr; + attr->write_func(value, size); + } + return size; +} + +static int get_property_thing_index(uint8_t attr_id, uint8_t type_id) +{ + int i, handle = 0; + + for (i = 0; i < property_db.num_handles; i++) { + if (property_db.attr_db[i] == NULL) + continue; + handle = property_db.attr_db[i]->index; + + if ((property_db.attr_db[handle]->attr_id == attr_id) && ((property_db.attr_db[handle]->type_id == type_id))) { + ilop_log("find property index:%d", handle); + return handle; + } + } + + return -1; +} + +static int get_service_thing_index(uint8_t attr_id) +{ + int i, handle = 0; + + ilop_log("search attr_id:%d", attr_id); + + for (i = 0; i < service_db.num_handles; i++) { + if (service_db.attr_db[i] == NULL) + continue; + handle = service_db.attr_db[i]->index; + + if (service_db.attr_db[handle]->attr_id == attr_id) { + ilop_log("find service index:%d", handle); + return handle; + } + } + + return -1; +} + +/* Processing SET requests issued under cloud */ +static mx_status protocol_method_handler(uint8_t method, uint8_t* data, uint16_t length) +{ + int32_t offset = 0, index = -1, ret = 0; + raw_body_format_t* elem; + + while ((length - offset) > 0) { + if (method == RAW_METHOD_SET) { + elem = (raw_body_format_t*)(data + offset); + index = get_property_thing_index(elem->attr_id, elem->type_id); + if (index < 0) { + ilop_log("attr_id or type_id err"); + return kGeneralErr; + } + + offset += sizeof(raw_body_format_t) - 1; + ret = protocol_value_handler(property_db.attr_db[index], &elem->value, length - 2); + } else if (method == RAW_METHOD_SERVICE) { + uint8_t attr_id = *data; + index = get_service_thing_index(attr_id); + if (index < 0) { + ilop_log("attr_id err"); + return kGeneralErr; + } + offset += 1; + ret = protocol_service_handler(service_db.attr_db[index], data + offset, length - 1); + } + if (ret == kUnsupportedErr) + return kNotReadableErr; + offset += ret; + } + + return kNoErr; +} + +/* Handling data transmitted by server side */ +static mx_status protocol_payloa_handler(uint8_t* data, uint16_t length) +{ + raw_payload_data_head_t* payload = (raw_payload_data_head_t*)data; + + switch (payload->method) { + /* Method of active sending from server side */ + // case RAW_METHOD_GET: + // protGetMethodHandler(&payload->data, length - sizeof(raw_payload_data_head_t) + 1); + // break; + + case RAW_METHOD_SET: + ilop_log("raw method set"); + protocol_method_handler(RAW_METHOD_SET, &payload->data, length - sizeof(raw_payload_data_head_t) + 1); + break; + + case RAW_METHOD_SERVICE: + ilop_log("raw method service"); + protocol_method_handler(RAW_METHOD_SERVICE, &payload->data, length - sizeof(raw_payload_data_head_t) + 1); + break; + + default: + ilop_log("Method(%d) not support\n", payload->method); + return kParamErr; + } + + return kNoErr; +} + +/* Processing protocol frames */ +mx_status raw_protocol_format_handler(uint8_t* data, uint32_t length) +{ + raw_protocol_head_t* head = (raw_protocol_head_t*)data; + uint8_t cmd = head->cmd; + + switch (cmd) { + case RAW_DOWN_DATA: + ilop_log("raw down data len:%d", ntoh16(head->length)); + protocol_payloa_handler(data + RAW_PROTOCOL_REGION_HEAD_LEN, + ntoh16(head->length) - RAW_PROTOCOL_REGION_LENGTH_FIXED); + break; + + default: + ilop_log("Cmd %02x not support\n", cmd); + break; + } + + return kNoErr; +} + +static void protocol_add_body(const struct ilop_raw_attr_t* attr, data_buffer_t* buf) +{ + ilop_att_val_t value; + uint32_t len; + + ilop_log("add body attr_id:%d", attr->attr_id); + + raw_body_format_t* body = (raw_body_format_t*)(buf->buffer + buf->length); + body->attr_id = attr->attr_id; + body->type_id = attr->type_id; + buf->length += sizeof(raw_body_format_t) - 1; + + attr->read_func(&value, &len); + + switch (attr->type_id) { + /*1 byte*/ + case TYPE_ID_BOOL: + case TYPE_ID_INT8: + case TYPE_ID_UINT8: + body->value = value.boolValue; + buf->length += 1; + break; + + /*2 byte*/ + case TYPE_ID_INT16: + case TYPE_ID_UINT16: { + uint16_t* p = (uint16_t*)&body->value; + *p = hton16(value.uint16Value); + buf->length += 2; + break; + } + + /*4 byte*/ + case TYPE_ID_INT32: + case TYPE_ID_UINT32: { + uint32_t* p = (uint32_t*)&body->value; + *p = hton32(value.uint32Value); + buf->length += 4; + break; + } + + case TYPE_ID_FLOAT32: { + float* p = (float*)&body->value; + *p = hton32(value.floatValue); + buf->length += 4; + break; + } + + /*8 byte*/ + case TYPE_ID_DATE: + case TYPE_ID_INT64: + case TYPE_ID_UINT64: { + uint64_t* p = (uint64_t*)&body->value; + *p = hton64(value.uint64Value); + buf->length += 4; + break; + } + + case TYPE_ID_FLOAT64: { + double* p = (double*)&body->value; + *p = hton32(value.doubleValue); + buf->length += 4; + break; + } + + /*string*/ + case TYPE_ID_STRING: { + uint8_t* p; + uint16_t* value_len = (uint16_t*)&body->value; + *value_len = hton16(len); + p = &body->value + sizeof(*value_len); + memcpy(p, value.stringValue, len); + buf->length += (len + 2); + break; + } + + default: { + uint8_t* p; + p = &body->value; + memcpy(p, value.dataValue, len); + buf->length += len; + ilop_log("default"); + break; + } + } +} + +/*To process the report attribute, it must be called in the ilop_runloop function.*/ +void ilop_raw_indicate_local_property(void) +{ + int i; + mx_status err = kNoErr; + + if ((property_db.num_handles == 0)) + return; + + for (i = 0; i < property_db.num_handles; i++) { + if (property_db.changed_handle[i] != ILOP_INVALID_HANDLE) + break; + } + if (i >= property_db.num_handles) + return; + + ilop_log("local property"); + + int handle; + + data_buffer_t data_buff; + memset(&data_buff, 0x00, sizeof(data_buffer_t)); + + data_buff.length = RAW_PROTOCOL_REGION_HEAD_LEN; + + raw_payload_data_head_t* payload = (raw_payload_data_head_t*)(data_buff.buffer + RAW_PROTOCOL_REGION_HEAD_LEN); + payload->method = RAW_METHOD_GET; + payload->id = hton32(get_seed_id()); + + data_buff.length += sizeof(raw_payload_data_head_t) - 1; + + for (i = 0; i < property_db.num_handles; i++) { + if (property_db.changed_handle[i] == ILOP_INVALID_HANDLE) + continue; + + handle = property_db.changed_handle[i]; + + if (property_db.attr_db[handle]->read_func == NULL) + continue; + + protocol_add_body(property_db.attr_db[handle], &data_buff); + } + + protFrameHeadInit(&data_buff, RAW_UP_DATA); + + printf("\r\n"); + for (int i = 0; i < data_buff.length; i++) { + printf("%02X", data_buff.buffer[i]); + } + printf("\r\n"); + + err = emh_ilop_send_raw_to_cloud(data_buff.buffer, data_buff.length); + require_noerr(err, exit); + + for (i = 0; i < property_db.num_handles; i++) { + property_db.changed_handle[i] = ILOP_INVALID_HANDLE; + } + +exit: + return; +} + +/*To process the report events, it must be called in the ilop_runloop function*/ +void ilop_raw_indicate_local_event(void) +{ + mx_status err = kNoErr; + int i, handle = 0; + + if (event_db.num_handles == 0) + return; + + for (i = 0; i < event_db.num_handles; i++) { + if (event_db.changed_handle[i] != ILOP_INVALID_HANDLE) { + handle = event_db.changed_handle[i]; + break; + } + } + if (i >= event_db.num_handles) + return; + + ilop_log("local event"); + + data_buffer_t data_buff; + memset(&data_buff, 0x00, sizeof(data_buffer_t)); + + data_buff.length = RAW_PROTOCOL_REGION_HEAD_LEN; + + raw_payload_data_head_t* payload = (raw_payload_data_head_t*)(data_buff.buffer + RAW_PROTOCOL_REGION_HEAD_LEN); + payload->method = RAW_METHOD_EVENT; + payload->id = hton32(get_seed_id()); + + data_buff.length += sizeof(raw_payload_data_head_t) - 1; + + if (event_db.attr_db[handle]->read_func == NULL) + goto exit; + + protocol_add_body(event_db.attr_db[handle], &data_buff); + + protFrameHeadInit(&data_buff, RAW_UP_DATA); + + printf("\r\n"); + for (int i = 0; i < data_buff.length; i++) { + printf("%02X", data_buff.buffer[i]); + } + printf("\r\n"); + + err = emh_ilop_send_raw_to_cloud(data_buff.buffer, data_buff.length); + require_noerr(err, exit); + + event_db.changed_handle[handle] = ILOP_INVALID_HANDLE; + +exit: + return; +} + +mx_status ilop_raw_attr_init(attr_type_t attr_type, uint8_t attr_num_handls) +{ + int i; + + for (i = 0; i < MAX_ATTR; i++) { + if (attr_type == ATTR_TYPE_PROPERTY) { + property_db.attr_db[i] = NULL; + } else if (attr_type == ATTR_TYPE_EVENT) { + event_db.attr_db[i] = NULL; + } else if (attr_type == ATTR_TYPE_SERVICE) { + service_db.attr_db[i] = NULL; + } + } + + for (i = 0; i < MAX_ATTR; i++) { + if (attr_type == ATTR_TYPE_PROPERTY) { + property_db.changed_handle[i] = ILOP_INVALID_HANDLE; + } else if (attr_type == ATTR_TYPE_EVENT) { + event_db.changed_handle[i] = ILOP_INVALID_HANDLE; + } else if (attr_type == ATTR_TYPE_SERVICE) { + service_db.changed_handle[i] = ILOP_INVALID_HANDLE; + } + } + + if (attr_type == ATTR_TYPE_PROPERTY) { + property_db.num_handles = attr_num_handls; + } else if (attr_type == ATTR_TYPE_EVENT) { + event_db.num_handles = attr_num_handls; + } else if (attr_type == ATTR_TYPE_SERVICE) { + service_db.num_handles = attr_num_handls; + } + + return kNoErr; +} + +mx_status ilop_raw_attr_register(attr_type_t attr_type, const struct ilop_raw_attr_t* attr) +{ + int handle = 0; + + if (attr_type == ATTR_TYPE_PROPERTY) { + if (property_db.num_handles > MAX_ATTR) + return kRangeErr; + + handle = attr->index; + property_db.attr_db[handle] = attr; + } else if (attr_type == ATTR_TYPE_EVENT) { + if (event_db.num_handles > MAX_ATTR) + return kRangeErr; + + handle = attr->index; + event_db.attr_db[handle] = attr; + } else if (attr_type == ATTR_TYPE_SERVICE) { + if (service_db.num_handles > MAX_ATTR) + return kRangeErr; + + handle = attr->index; + service_db.attr_db[handle] = attr; + } + + return kNoErr; +} + +void ilop_raw_attr_indicate_by_handle(attr_type_t attr_type, int handle) +{ + if (attr_type == ATTR_TYPE_PROPERTY) { + if (property_db.attr_db[handle] == NULL) + return; + if (property_db.attr_db[handle]->index == handle) { + if (property_db.changed_handle[handle] == handle) + return; + property_db.changed_handle[handle] = handle; + } + } else if (attr_type == ATTR_TYPE_EVENT) { + if (event_db.attr_db[handle] == NULL) + return; + if (event_db.attr_db[handle]->index == handle) { + if (event_db.changed_handle[handle] == handle) + return; + event_db.changed_handle[handle] = handle; + } + } +} + diff --git a/src/helper/emhost/emh_api.h b/src/helper/emhost/emh_api.h index 4654056..db6b49d 100644 --- a/src/helper/emhost/emh_api.h +++ b/src/helper/emhost/emh_api.h @@ -271,6 +271,7 @@ typedef struct { const char* tsl_thing; /**< TSL model defined by Alibaba cloud platform(json string). if dm=EMH_ARG_ILOP_DM_RAW, tls_thing=NULL */ uint32_t tsl_len; /**< The JSON string length of the TSL model. if dm=EMH_ARG_ILOP_DM_RAW, tls_len=0 */ emh_arg_ilop_dm_t dm; /**< The method to access the TLS, raw , local, cloud.*/ + emh_arg_ilop_domain_t domain; /**< specify the could server domain */ } emh_ilop_config_t; /** diff --git a/src/helper/emhost/emh_arg.c b/src/helper/emhost/emh_arg.c index 6ae88bb..fc264ac 100644 --- a/src/helper/emhost/emh_arg.c +++ b/src/helper/emhost/emh_arg.c @@ -101,6 +101,16 @@ const char* EMH_ARG_ILOP_DM[] = [EMH_ARG_ILOP_DM_MAX] = "\0", }; +const char* EMH_ARG_ILOP_DOMAIN[] = +{ + [EMH_ARG_ILOP_DOMAIN_SHANGHAI] = "0", + [EMH_ARG_ILOP_DOMAIN_SINGAPORE] = "1", + [EMH_ARG_ILOP_DOMAIN_JAPAN] = "2", + [EMH_ARG_ILOP_DOMAIN_AMERICA] = "3", + [EMH_ARG_ILOP_DOMAIN_GERMANY] = "4", + [EMH_ARG_ILOP_DOMAIN_MAX] = "\0", +}; + const char* EMH_ARG_ILOP_CONFIG[] = { [EMH_ARG_ILOP_CONFIG_NONE] = "NONE", diff --git a/src/helper/emhost/emh_arg.h b/src/helper/emhost/emh_arg.h index e276cd0..0165a2d 100644 --- a/src/helper/emhost/emh_arg.h +++ b/src/helper/emhost/emh_arg.h @@ -124,6 +124,17 @@ enum{ typedef uint8_t emh_arg_ilop_dm_t; extern const char* EMH_ARG_ILOP_DM[]; +enum{ + EMH_ARG_ILOP_DOMAIN_SHANGHAI, + EMH_ARG_ILOP_DOMAIN_SINGAPORE, + EMH_ARG_ILOP_DOMAIN_JAPAN, + EMH_ARG_ILOP_DOMAIN_AMERICA, + EMH_ARG_ILOP_DOMAIN_GERMANY, + EMH_ARG_ILOP_DOMAIN_MAX, +}; +typedef uint8_t emh_arg_ilop_domain_t; +extern const char* EMH_ARG_ILOP_DOMAIN[]; + enum{ EMH_ARG_ILOP_CONFIG_NONE, EMH_ARG_ILOP_CONFIG_TLS, diff --git a/src/helper/emhost/emh_ilop.c b/src/helper/emhost/emh_ilop.c index ed5846c..3e7cc00 100644 --- a/src/helper/emhost/emh_ilop.c +++ b/src/helper/emhost/emh_ilop.c @@ -1,295 +1,313 @@ -/** - ****************************************************************************** - * @file emh_ilop.c - * @author QQ Ding - * @version V1.0.0 - * @date 3-Sept-2018 - * @brief Alicloud ILOP service AT commands API - ****************************************************************************** - * - * Copyright (c) 2009-2018 MXCHIP Co.,Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - * - ****************************************************************************** - */ - - -#include -#include - -#include "emh_api.h" -#include "ATCmdParser/ATCmdParser.h" - - - -/****************************************************************************** - * Function Definitions - ******************************************************************************/ -// MX_WEAK void emh_ev_ilop_connection(emh_arg_ilop_conn_t conn) -// { -// printf("conn=%d\r\n", conn); -// return; -// } - -// MX_WEAK void emh_ev_ilop_set_local_attr(emh_ilop_msg *msg) -// { -// if( msg->format == EMH_ARG_ILOP_FORMAT_ICA){ -// printf("msg=%s\r\n", msg->data); -// } -// return; -// } - -mx_status emh_ilop_config( emh_ilop_config_t *config, bool force ) -{ - if( config == NULL ) return kParamErr; - - char arg[10]; - - if( config->dm == EMH_ARG_ILOP_DM_ICA_BY_LOCAL ) - { - if( config->tsl_thing == NULL ) - return kParamErr; - } - - //check data format - if (!(ATCmdParser_send("AT+ILOPDM?") - && ATCmdParser_recv("+ILOPDM:%10[^\r]\r\n",arg) - && ATCmdParser_recv("OK\r\n"))) { - return kReadErr; - } - - //if dm value different, we need to be set - if( emh_arg_for_arg( EMH_ARG_ILOP_DM, arg) != config->dm ) - { - if ( !(ATCmdParser_send("AT+ILOPDM=%s", emh_arg_for_type(EMH_ARG_ILOP_DM, config->dm)) - && ATCmdParser_recv("OK\r\n"))) { - return kReadErr; - } - } - - //if dm value is raw, we shuold check tls setting - if( config->dm == EMH_ARG_ILOP_DM_ICA_BY_LOCAL ) - { - //check tls setting - if ( !(ATCmdParser_send("AT+ILOPCONFIG?") - && ATCmdParser_recv("+ILOPCONFIG:%10[^\r]\r\n",arg) - && ATCmdParser_recv("OK\r\n"))) { - return kReadErr; - } - - if( (force == true) || (emh_arg_for_arg( EMH_ARG_ILOP_CONFIG, arg ) != EMH_ARG_ILOP_CONFIG_TLS) ) - { - if( emh_ilop_set_tsl( config->tsl_thing, config->tsl_len ) != kNoErr) - return kWriteErr; - } - } - return kNoErr; -} - -mx_status emh_ilop_set_tsl( const char* tsl_thing, uint32_t tls_len ) -{ - int id_count=0, last = 0, i=0; - last = (tls_len%4096 == 0) ? 0 : 1; - id_count = tls_len/4096 + last; - - if ( !(ATCmdParser_send("AT+ILOPTSLPRE=%d,%d", tls_len, id_count) - && ATCmdParser_recv("OK\r\n"))) { - return kReadErr; - } - - for( i=0; i") - && ATCmdParser_write((char *)tsl_thing + (i*4096) , 4096) == 4096 - && ATCmdParser_recv("OK\r\n") - )) { - return kReadErr; - } - } - - if( last ) - { - if ( !(ATCmdParser_send("AT+ILOPTSL=%d", i) - && ATCmdParser_recv(">") - && ATCmdParser_write((char *)tsl_thing + (i*4096) , tls_len -i*4096) == (tls_len -i*4096) - && ATCmdParser_recv("OK\r\n") - )) { - return kReadErr; - } - } - - return kNoErr; -} - -mx_status emh_ilop_set_key( const char *pk, const char *ps, const char *ds, const char *dn ) -{ - if (ATCmdParser_send("AT+ILOPSET=%s,%s,%s,%s", pk, ps, ds, dn) - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - return kGeneralErr; -} - -mx_status emh_ilop_get_key( char pk[EMH_ILOP_PRODUCT_KEY_MAXLEN], char ps[EMH_ILOP_PRODUCT_SECRET_MAXLEN], char ds[EMH_ILOP_DEVICE_SECRET_MAXLEN], char dn[EMH_ILOP_DEVICE_NAME_MAXLEN] ) -{ - char args[200], *arg_list[5]; - - if (!(ATCmdParser_send("AT+ILOPSET?") - && ATCmdParser_recv("+ILOPSET:%200[^\r]\r\n",args) - && ATCmdParser_recv("OK\r\n"))) { - return kReadErr; - } - - if (4 != ATCmdParser_analyse_args(args, arg_list, 4)) { - return kMalformedErr; - } - - strncpy( pk, arg_list[0], EMH_ILOP_PRODUCT_KEY_MAXLEN ); - strncpy( ps, arg_list[1], EMH_ILOP_PRODUCT_SECRET_MAXLEN ); - strncpy( ds, arg_list[2], EMH_ILOP_DEVICE_SECRET_MAXLEN ); - strncpy( dn, arg_list[3], EMH_ILOP_DEVICE_NAME_MAXLEN ); - - return kNoErr; -} - -mx_status emh_ilop_awss_start( void ) -{ - if (ATCmdParser_send("AT+ILOPAWSSTART") - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - return kGeneralErr; -} - -mx_status emh_ilop_awss_press( void ) -{ - if (ATCmdParser_send("AT+ILOPAWSPRESS") - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - return kGeneralErr; -} - -mx_status emh_ilop_service_start( void ) -{ - if (ATCmdParser_send("AT+ILOPSTART") - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - return kGeneralErr; -} - -emh_arg_ilop_status_t emh_ilop_get_stauts( void ) -{ - char arg[20]; - - if (!(ATCmdParser_send("AT+ILOPSTATUS?") - && ATCmdParser_recv("+ILOPSTATUS:%20[^\r]\r\n",arg) - && ATCmdParser_recv("OK\r\n"))) { - return EMH_ARG_ERR; - } - - return emh_arg_for_arg( EMH_ARG_ILOP_STATUS, arg); -} - -mx_status emh_ilop_unbind( void ) -{ - if (ATCmdParser_send("AT+ILOPRESET") - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - return kGeneralErr; -} - -mx_status emh_ilop_service_stop( void ) -{ - if (ATCmdParser_send("AT+ILOPSTOP") - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - return kGeneralErr; -} - -mx_status emh_ilop_send_ica_to_cloud( const char *type, char *attr ) -{ - if (ATCmdParser_send("AT+ILOPSENDICA=%s,%s", type, attr) - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - - return kGeneralErr; -} - -mx_status emh_ilop_send_raw_to_cloud( uint8_t *data, uint32_t len ) -{ - if (ATCmdParser_send("AT+ILOPSENDRAW=%d", len) - && ATCmdParser_recv(">") - && ATCmdParser_write((char *)data, len) == len - && ATCmdParser_recv("OK\r\n")) { - return kNoErr; - } - return kGeneralErr; -} - -void emh_ilop_event_handler(void) -{ - mx_status err = kNoErr; - char arg1[10], arg2[256]; - emh_arg_ilop_conn_t conn; - emh_ilop_msg msg; - - require_action(ATCmdParser_recv("%10[^,],", arg1), exit, err = kMalformedErr); - - emh_arg_ilop_ev_t event = emh_arg_for_arg(EMH_ARG_ILOP_EV, arg1); - require_action(event != EMH_ARG_ERR, exit, err = kMalformedErr); - - /* ILOP Server connection event */ - if (event == EMH_ARG_ILOP_EV_ILOP) { - require_action(ATCmdParser_recv("%20[^\r]\r\n", arg2), exit, err = kMalformedErr); - conn = emh_arg_for_arg(EMH_ARG_ILOP_CONN, arg2); - require_action(conn != EMH_ARG_ERR, exit, err = kMalformedErr); - emh_ev_ilop_connection(conn); - } - /* ALINK server === ICA value===> device */ - else if(event == EMH_ARG_ILOP_EV_SETICA) - { - require_action(ATCmdParser_recv("%256[^\r]\r\n", arg2), exit, err = kMalformedErr); - msg.format = EMH_ARG_ILOP_FORMAT_ICA; - msg.data = (uint8_t *)&arg2; - msg.len = strlen(arg2); - emh_ev_ilop_set_local_attr( &msg ); - } - /* ALINK server === RAW value===> device */ - else if(event == EMH_ARG_ILOP_EV_SETRAW) - { - /* Read package data */ - int32_t count; - require_action(ATCmdParser_recv("%d,", &count), exit, err = kMalformedErr); - - uint8_t *data = malloc(count); - require_action(data, exit, err = kNoMemoryErr); - require_action(ATCmdParser_read((char *)data, count) == count, exit, err = kTimeoutErr); - - msg.data = data; - msg.format = EMH_ARG_ILOP_FORMAT_RAW; - msg.len = count; - emh_ev_ilop_set_local_attr(&msg); - free(data); - } - -exit: - if (err == kMalformedErr) emh_ev_unknown(); - return; -} +/** + ****************************************************************************** + * @file emh_ilop.c + * @author QQ Ding + * @version V1.0.0 + * @date 3-Sept-2018 + * @brief Alicloud ILOP service AT commands API + ****************************************************************************** + * + * Copyright (c) 2009-2018 MXCHIP Co.,Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************** + */ + + +#include +#include + +#include "emh_api.h" +#include "ATCmdParser/ATCmdParser.h" + + + +/****************************************************************************** + * Function Definitions + ******************************************************************************/ +// MX_WEAK void emh_ev_ilop_connection(emh_arg_ilop_conn_t conn) +// { +// printf("conn=%d\r\n", conn); +// return; +// } + +// MX_WEAK void emh_ev_ilop_set_local_attr(emh_ilop_msg *msg) +// { +// if( msg->format == EMH_ARG_ILOP_FORMAT_ICA){ +// printf("msg=%s\r\n", msg->data); +// } +// return; +// } + +mx_status emh_ilop_config( emh_ilop_config_t *config, bool force ) +{ + if( config == NULL ) return kParamErr; + + char arg[10]; + + if( config->dm == EMH_ARG_ILOP_DM_ICA_BY_LOCAL ) + { + if( config->tsl_thing == NULL ) + return kParamErr; + } + + + //check domain + if (!(ATCmdParser_send("AT+ILOPDOMAIN?") + && ATCmdParser_recv("+ILOPDOMAIN:%10[^\r]\r\n",arg) + && ATCmdParser_recv("OK\r\n"))) { + return kReadErr; + } + + //if dm value different, we need to be set + if( emh_arg_for_arg( EMH_ARG_ILOP_DOMAIN, arg) != config->domain ) + { + if ( !(ATCmdParser_send("AT+ILOPDOMAIN=%s", emh_arg_for_type(EMH_ARG_ILOP_DOMAIN, config->domain)) + && ATCmdParser_recv("OK\r\n"))) { + return kReadErr; + } + } + + + //check data format + if (!(ATCmdParser_send("AT+ILOPDM?") + && ATCmdParser_recv("+ILOPDM:%10[^\r]\r\n",arg) + && ATCmdParser_recv("OK\r\n"))) { + return kReadErr; + } + + //if dm value different, we need to be set + if( emh_arg_for_arg( EMH_ARG_ILOP_DM, arg) != config->dm ) + { + if ( !(ATCmdParser_send("AT+ILOPDM=%s", emh_arg_for_type(EMH_ARG_ILOP_DM, config->dm)) + && ATCmdParser_recv("OK\r\n"))) { + return kReadErr; + } + } + + //if dm value is raw, we shuold check tls setting + if( config->dm == EMH_ARG_ILOP_DM_ICA_BY_LOCAL ) + { + //check tls setting + if ( !(ATCmdParser_send("AT+ILOPCONFIG?") + && ATCmdParser_recv("+ILOPCONFIG:%10[^\r]\r\n",arg) + && ATCmdParser_recv("OK\r\n"))) { + return kReadErr; + } + + if( (force == true) || (emh_arg_for_arg( EMH_ARG_ILOP_CONFIG, arg ) != EMH_ARG_ILOP_CONFIG_TLS) ) + { + if( emh_ilop_set_tsl( config->tsl_thing, config->tsl_len ) != kNoErr) + return kWriteErr; + } + } + return kNoErr; +} + +mx_status emh_ilop_set_tsl( const char* tsl_thing, uint32_t tls_len ) +{ + int id_count=0, last = 0, i=0; + last = (tls_len%4096 == 0) ? 0 : 1; + id_count = tls_len/4096 + last; + + if ( !(ATCmdParser_send("AT+ILOPTSLPRE=%d,%d", tls_len, id_count) + && ATCmdParser_recv("OK\r\n"))) { + return kReadErr; + } + + for( i=0; i") + && ATCmdParser_write((char *)tsl_thing + (i*4096) , 4096) == 4096 + && ATCmdParser_recv("OK\r\n") + )) { + return kReadErr; + } + } + + if( last ) + { + if ( !(ATCmdParser_send("AT+ILOPTSL=%d", i) + && ATCmdParser_recv(">") + && ATCmdParser_write((char *)tsl_thing + (i*4096) , tls_len -i*4096) == (tls_len -i*4096) + && ATCmdParser_recv("OK\r\n") + )) { + return kReadErr; + } + } + + return kNoErr; +} + +mx_status emh_ilop_set_key( const char *pk, const char *ps, const char *ds, const char *dn ) +{ + if (ATCmdParser_send("AT+ILOPSET=%s,%s,%s,%s", pk, ps, ds, dn) + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + return kGeneralErr; +} + +mx_status emh_ilop_get_key( char pk[EMH_ILOP_PRODUCT_KEY_MAXLEN], char ps[EMH_ILOP_PRODUCT_SECRET_MAXLEN], char ds[EMH_ILOP_DEVICE_SECRET_MAXLEN], char dn[EMH_ILOP_DEVICE_NAME_MAXLEN] ) +{ + char args[200], *arg_list[5]; + + if (!(ATCmdParser_send("AT+ILOPSET?") + && ATCmdParser_recv("+ILOPSET:%200[^\r]\r\n",args) + && ATCmdParser_recv("OK\r\n"))) { + return kReadErr; + } + + if (4 != ATCmdParser_analyse_args(args, arg_list, 4)) { + return kMalformedErr; + } + + strncpy( pk, arg_list[0], EMH_ILOP_PRODUCT_KEY_MAXLEN ); + strncpy( ps, arg_list[1], EMH_ILOP_PRODUCT_SECRET_MAXLEN ); + strncpy( ds, arg_list[2], EMH_ILOP_DEVICE_SECRET_MAXLEN ); + strncpy( dn, arg_list[3], EMH_ILOP_DEVICE_NAME_MAXLEN ); + + return kNoErr; +} + +mx_status emh_ilop_awss_start( void ) +{ + if (ATCmdParser_send("AT+ILOPAWSSTART") + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + return kGeneralErr; +} + +mx_status emh_ilop_awss_press( void ) +{ + if (ATCmdParser_send("AT+ILOPAWSPRESS") + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + return kGeneralErr; +} + +mx_status emh_ilop_service_start( void ) +{ + if (ATCmdParser_send("AT+ILOPSTART") + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + return kGeneralErr; +} + +emh_arg_ilop_status_t emh_ilop_get_stauts( void ) +{ + char arg[20]; + + if (!(ATCmdParser_send("AT+ILOPSTATUS?") + && ATCmdParser_recv("+ILOPSTATUS:%20[^\r]\r\n",arg) + && ATCmdParser_recv("OK\r\n"))) { + return EMH_ARG_ERR; + } + + return emh_arg_for_arg( EMH_ARG_ILOP_STATUS, arg); +} + +mx_status emh_ilop_unbind( void ) +{ + if (ATCmdParser_send("AT+ILOPRESET") + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + return kGeneralErr; +} + +mx_status emh_ilop_service_stop( void ) +{ + if (ATCmdParser_send("AT+ILOPSTOP") + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + return kGeneralErr; +} + +mx_status emh_ilop_send_ica_to_cloud( const char *type, char *attr ) +{ + if (ATCmdParser_send("AT+ILOPSENDICA=%s,%s", type, attr) + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + + return kGeneralErr; +} + +mx_status emh_ilop_send_raw_to_cloud( uint8_t *data, uint32_t len ) +{ + if (ATCmdParser_send("AT+ILOPSENDRAW=%d", len) + && ATCmdParser_recv(">") + && ATCmdParser_write((char *)data, len) == len + && ATCmdParser_recv("OK\r\n")) { + return kNoErr; + } + return kGeneralErr; +} + +void emh_ilop_event_handler(void) +{ + mx_status err = kNoErr; + char arg1[10], arg2[256]; + emh_arg_ilop_conn_t conn; + emh_ilop_msg msg; + + require_action(ATCmdParser_recv("%10[^,],", arg1), exit, err = kMalformedErr); + + emh_arg_ilop_ev_t event = emh_arg_for_arg(EMH_ARG_ILOP_EV, arg1); + require_action(event != EMH_ARG_ERR, exit, err = kMalformedErr); + + /* ILOP Server connection event */ + if (event == EMH_ARG_ILOP_EV_ILOP) { + require_action(ATCmdParser_recv("%20[^\r]\r\n", arg2), exit, err = kMalformedErr); + conn = emh_arg_for_arg(EMH_ARG_ILOP_CONN, arg2); + require_action(conn != EMH_ARG_ERR, exit, err = kMalformedErr); + emh_ev_ilop_connection(conn); + } + /* ALINK server === ICA value===> device */ + else if(event == EMH_ARG_ILOP_EV_SETICA) + { + require_action(ATCmdParser_recv("%256[^\r]\r\n", arg2), exit, err = kMalformedErr); + msg.format = EMH_ARG_ILOP_FORMAT_ICA; + msg.data = (uint8_t *)&arg2; + msg.len = strlen(arg2); + emh_ev_ilop_set_local_attr( &msg ); + } + /* ALINK server === RAW value===> device */ + else if(event == EMH_ARG_ILOP_EV_SETRAW) + { + /* Read package data */ + int32_t count; + require_action(ATCmdParser_recv("%d,", &count), exit, err = kMalformedErr); + + uint8_t *data = malloc(count); + require_action(data, exit, err = kNoMemoryErr); + require_action(ATCmdParser_read((char *)data, count) == count, exit, err = kTimeoutErr); + + msg.data = data; + msg.format = EMH_ARG_ILOP_FORMAT_RAW; + msg.len = count; + emh_ev_ilop_set_local_attr(&msg); + free(data); + } + +exit: + if (err == kMalformedErr) emh_ev_unknown(); + return; +}