SDK framework based on sddc protocol_ sdk_ Lib parsing
Previously, when porting libsddc library, I felt that the official demo was too inefficient ( ̄.  ̄). I was tired of copying and pasting code, and wrote a BUG, and the other copied code cracked, so I wrote an sddc_sdk_lib library to make sddc access devices faster and more effective. This paper mainly explains the structure of this library and the new device quickly uses sddc to access Spirit 1 through this library, so as to become an intelligent device. ヽ(・ ω・ ´メ)
For the introduction of SDDC protocol, please refer to: It unifies the introduction of cross vendor discovery and control DDC protocol used in WiFi and ZigBee upper layer
Current sddc_sdk_lib supports three platforms, namely, MS-RTOS for Yihui information release, which proposes sddc protocol, ESP platform of Anxin based on FreeRTOS, and Arduino platform, which is popular recently (this is a good thing. After getting used to Arduino, I don't want to use the traditional platform at all), as usual The secret treasure house of inspiration desktop .
SDDC structure and definition of various equipment
In SDDC_ SDK_ In lib. H, the overall structure of SDDC is described as follows:
/********************************************************************************************************* SDDC Overall structure description *********************************************************************************************************/ typedef struct { char *token; DEV_INFO *devinfo; IO_DEV_REGINFO *io_dev_reg; int io_dev_reg_num; NUM_DEV_REGINFO *num_dev_reg; int num_dev_reg_num; DEV_STATE_GET *state_get_reg; int state_get_reg_num; DIS_DEV_REGINFO *dis_dev_reg; int dis_dev_num; } SDDC_CONFIG_INFO;
Where dev_ The content in info is the information reported to Spirit 1 through SDDC, such as device name, device type, description, etc
/********************************************************************************************************* SDDC Description of equipment information involved in information reporting *********************************************************************************************************/ typedef struct { char *name; char *type; sddc_bool_t excl; char *desc; char *model; char *vendor; } DEV_INFO;
IO_DEV_REGINFO,NUM_DEV_REGINFO,DIS_DEV_REGINFO is the description of IO type, digital type and display type equipment, including object name and corresponding Set function;
/********************************************************************************************************* SDDC The registration structure of IO devices inside *********************************************************************************************************/ typedef struct { char *objname; Io_Set IO_Fun; } IO_DEV_REGINFO; /********************************************************************************************************* SDDC The registration structure of digital equipment inside *********************************************************************************************************/ typedef struct { char *objname; Num_Set Num_Fun; } NUM_DEV_REGINFO; /********************************************************************************************************* SDDC It displays the registration structure of class devices *********************************************************************************************************/ typedef struct { char *objname; Dis_Set Dis_Fun; } DIS_DEV_REGINFO;
DEV_STATE_GET is the set of get functions for all device objects;
/********************************************************************************************************* SDDC Result query class function registration structure *********************************************************************************************************/ #define DEV_IO_TYPE 0 #define DEV_NUM_TYPE 1 #define DEV_DISPLAY_TYPE 2 typedef struct { char *objname; int type; STATE_GET state_fun; } DEV_STATE_GET;
SDDC protocol and extended structure implementation function
stay It unifies the introduction of cross vendor discovery and control DDC protocol used in WiFi and ZigBee upper layer This article introduces the specific protocol flow, following the official libsddc demo in SDDC_SDK_lib.c is about the implementation function of SDDC communication protocol, in which the connection related functions don't need to pay much attention. The main one is sddc_on_message_lib function, which is the entry of business communication with Spirit 1. Match get or set according to the method field in the message, and then call the corresponding processing function. Combined with the overall structure of SDDC, it can be seen that all types of devices share the same get interface, and the set interface has different processing functions according to different device types, In fact, the SDDC in the official demo_ on_ The message function abstracts all the messages that may be received, thus eliminating the steps of writing and parsing messages.
Super awesome, super convenient, isn't it? Next, let's accept the extended structure and use of the SDK:
/********************************************************************************************************* ** Function name: sddc_on_message_lib ** Function Description: callback function for processing messages received by SDDC protocol ** Input: SDDC structure ** uid ID of the message sent ** message Received message ** len packet length ** Output: 0: processing failed, 1: Processing succeeded ** Global variables: ** Calling module: None *********************************************************************************************************/ static sddc_bool_t sddc_on_message_lib(sddc_t *sddc, const uint8_t *uid, const char *message, uint32_t len) { cJSON *root = cJSON_Parse(message); cJSON *Json_method; uint8_t uimethod =DDC_METHOD_VALIDE; Json_method = cJSON_GetObjectItem(root, "method"); if (NULL == Json_method) { return SDDC_FALSE; } if (cJSON_IsString(Json_method)) { if (strcmp(Json_method->valuestring,"set") == 0) { uimethod = DDC_METHOD_SET; } else if (strcmp(Json_method->valuestring,"get") == 0) { uimethod = DDC_METHOD_GET; } else { return SDDC_FALSE; } } else { return SDDC_FALSE; } if (uimethod == DDC_METHOD_VALIDE) { return SDDC_FALSE; } if (uimethod == DDC_METHOD_SET) { int i; /* * The digital quantity and display quantity shall be queried and set first to prevent the switching quantity from being the enabling of the equipment */ for (i=0; i<G_config->num_dev_reg_num; i++) { object_Number_Set(root, G_config->num_dev_reg->objname, G_config->num_dev_reg->Num_Fun); } for (i=0; i<G_config->dis_dev_num; i++) { object_Display_Set(root, G_config->dis_dev_reg->objname, G_config->dis_dev_reg->Dis_Fun); } for (i=0; i<G_config->io_dev_reg_num; i++) { object_IO_Set(root, G_config->io_dev_reg->objname, G_config->io_dev_reg->IO_Fun); } } else if (uimethod == DDC_METHOD_GET) { object_get(sddc, uid, root, G_config->state_get_reg, G_config->state_get_reg_num); } else { return SDDC_FALSE; } return SDDC_TRUE; }
The library also provides an interface for actively reporting messages, as follows. Note that the format of input parameters should comply with the specification (key! Knock the blackboard!
):
/********************************************************************************************************* ** Function name: object_report ** Function Description: a reporting interface encapsulated for external users ** Input: reportlist the content list reported in the format of {obj:"LED1","LED2","TMP"} ** Output: 0: processing failed, 1: Processing succeeded ** Global variables: ** Calling module: None *********************************************************************************************************/ int object_report(cJSON *reportlist) { if (NULL == G_sddc) { return SDDC_FALSE; } return object_get(G_sddc, NULL, reportlist, G_config->state_get_reg, G_config->state_get_reg_num); }
This function can be used to quickly implement the input parameters of a standard active reporting message interface:
/* * Active data reporting function */ static void report_sensor() { int sensorValue = 0; cJSON *value; cJSON *root; // char *msg; value = cJSON_CreateArray(); root = cJSON_CreateObject(); sddc_return_if_fail(value); sddc_return_if_fail(root); // Generate required parameters in format cJSON_AddItemToArray(value, cJSON_CreateString("Report data 1 ")); // The string here should correspond to the string in the system object state acquisition registration structure // cJSON_AddItemToArray(value, cJSON_CreateString("submit data 2")); / / add as many as you need to submit cJSON_AddItemToObject(root, "obj", value); // Send data to EdgerOS // msg = cJSON_Print(root); // printf("trigger escalation:% s\n",msg); object_report(root); cJSON_Delete(value); cJSON_free(msg); }
Fast access using DEMO
Next, let's teach you how to quickly use this SDK to develop access devices (✪ ω ✪).
First, define the contents of dev_info completed by the device, and then define different types of objects required by the device, either a device has only one object or a complex device corresponds to multiple objects. According to these, the construction of various types of objects and the registration of set and get functions are completed.
/********************************************************************************************************* Information definition of the current device *********************************************************************************************************/ DEV_INFO dev_info = { .name = "InfraredSensor", // Device name, which is the name you search for when you add a device .type = "device", // Equipment type. The application side needs to distinguish equipment types through this .excl = SDDC_FALSE, .desc = "Infrared sensor based on nodemcu", .model = "1", .vendor = "inspiration-desktop", // Your name }; /********************************************************************************************************* IO Device object setting function and processing method registration *********************************************************************************************************/ IO_DEV_REGINFO io_dev[] = { // Register IO(string type) message set processing function {"attr1", NULL}, {"attr2", NULL}, }; /********************************************************************************************************* Registration of object function and processing method of digital quantity equipment *********************************************************************************************************/ NUM_DEV_REGINFO num_dev[] = { // Register the message set processing function of digital quantity (int,float, etc.) {"attr1", NULL}, {"attr2", NULL}, }; /********************************************************************************************************* Display device object function and processing method registration *********************************************************************************************************/ DIS_DEV_REGINFO dis_dev[] = { // Register the message set processing function of the display device (screen, etc.) {"attr1", NULL}, {"attr2", NULL}, }; /********************************************************************************************************* System object status get registration *********************************************************************************************************/ DEV_STATE_GET dev_state_get_reg[] = { {"attr1", DEV_IO_TYPE, gpio_dev_state_get}, // Register get handler {"attr2", DEV_IO_TYPE, gpio_dev_state_get}, // Register get handler }; /********************************************************************************************************* System registration object aggregation *********************************************************************************************************/ SDDC_CONFIG_INFO sys_cfg = { .token = "12345678", .devinfo = &dev_info, .io_dev_reg = io_dev, .io_dev_reg_num = MS_ARRAY_SIZE(io_dev), .num_dev_reg = num_dev, .num_dev_reg_num = MS_ARRAY_SIZE(num_dev), .state_get_reg = dev_state_get_reg, .state_get_reg_num = MS_ARRAY_SIZE(dev_state_get_reg), .dis_dev_reg = dis_dev, .dis_dev_num = MS_ARRAY_SIZE(dis_dev), };
As for the relevant set, get functions and initialization operations, different implementations need to be completed according to different devices. Then, execute sddc_lib_main in the main function with sys_cfg as a parameter to start SDDC and complete the relevant configuration. The following is the main function code on the Anxin platform based on FreeRTOS:
int app_main (int argc, char **argv) { ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(example_connect()); gpio_dev_init(); while (1) { sddc_lib_main(&sys_cfg); } return (0); }
For the Arduino platform, because the main function structure is divided into setup() and loop(), part of the code can not be invoked in the library, the specific code is as follows:
void setup() { byte mac[6]; uart_dev_init(); // Start WiFi and connect to the network WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Get and print IP address Serial.println(""); Serial.println("WiFi connected"); Serial.print("'ip :"); Serial.print(WiFi.localIP()); Serial.println("' to connect"); // Clear the state of the key state machine button.reset(); // Create a key scanning thread, long press the IO0 key, and the ESP32 will enter the SmartConfig mode after releasing it sddc_printf("Press and hold the key to enter Smartconfig...\n"); button.attachLongPressStop(esp_io0_key_task); xTaskCreate(esp_tick_task, "button_tick", ESP_TASK_STACK_SIZE, NULL, ESP_TASK_PRIO, NULL); // sddc protocol initialization sddc_lib_main(&sys_cfg); // Obtain and print the mac address of the network card WiFi.macAddress(mac); sddc_printf("MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]); // Use the network card mac address to set the device unique ID UID sddc_set_uid(G_sddc, mac); } void loop() { // Run SDDC protocol cycle while (1) { sddc_printf("SDDC running...\n"); sddc_run(G_sddc); sddc_printf("SDDC quit!\n"); } // Destroy SDDC protocol sddc_destroy(G_sddc); }
This article is only for personal learning and use. If there are errors, please correct them ˙ ᗜ ˙ ) Thank you, boss!