From 3c8cb8276275df385da14da228f5ce8c4a80d739 Mon Sep 17 00:00:00 2001 From: sw-iot-neeravparasar Date: Mon, 1 Jan 2024 02:07:11 +0530 Subject: [PATCH 1/3] Twin Implementaion --- iotconnect-sdk/include/iotconnect.h | 4 ++ .../nrf-layer-lib/include/iotconnect_mqtt.h | 3 ++ .../nrf-layer-lib/src/iotconnect_mqtt.c | 24 ++++++---- iotconnect-sdk/src/iotconnect.c | 46 ++++++++++++++++++- samples/iotc-basic/src/main.c | 25 +++++++++- samples/iotc-sensors-gps/src/main.c | 25 +++++++++- 6 files changed, 116 insertions(+), 11 deletions(-) diff --git a/iotconnect-sdk/include/iotconnect.h b/iotconnect-sdk/include/iotconnect.h index b007130..dcd9674 100644 --- a/iotconnect-sdk/include/iotconnect.h +++ b/iotconnect-sdk/include/iotconnect.h @@ -29,14 +29,18 @@ typedef enum { typedef void (*IotConnectStatusCallback)(IotconnectConnectionStatus data); + + typedef struct { char *env; // Environment name. Contact your representative for details. char *cpid; // Settings -> Company Profile. char *duid; // Name of the device. IotclOtaCallback ota_cb; // callback for OTA events. IotclCommandCallback cmd_cb; // callback for command events. + IotcltwinrecivCallback twin_msg_rciv; IotclMessageCallback msg_cb; // callback for ALL messages, including the specific ones like cmd or ota callback. IotConnectStatusCallback status_cb; // callback for connection status + } IotconnectClientConfig; diff --git a/iotconnect-sdk/nrf-layer-lib/include/iotconnect_mqtt.h b/iotconnect-sdk/nrf-layer-lib/include/iotconnect_mqtt.h index 71f892c..0b33f8e 100644 --- a/iotconnect-sdk/nrf-layer-lib/include/iotconnect_mqtt.h +++ b/iotconnect-sdk/nrf-layer-lib/include/iotconnect_mqtt.h @@ -18,10 +18,13 @@ extern "C" { typedef void (*IotconnectMqttOnDataCallback)(const uint8_t *data, size_t len, const char *topic); +typedef void (*IotconnectMqttTwinDataCallback)(const uint8_t *data, size_t len, const char *topic); + typedef struct { int tls_verify; // NONE = 0, OPTIONAL = 1, REQUIRED = 2 const char *env; // Environment name. Contact your representative for details. Same as telemetry config. IotconnectMqttOnDataCallback data_cb; // callback for OTA events. + IotconnectMqttTwinDataCallback twin_cb;//callback twin event. IotConnectStatusCallback status_cb; // callback for command events. } IotconnectMqttConfig; diff --git a/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c b/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c index 7f49773..bae6cf0 100644 --- a/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c +++ b/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c @@ -325,11 +325,19 @@ static void mqtt_evt_handler(struct mqtt_client *const c, printk("MQTT PUBLISH result=%d len=%d\n", evt->result, p->message.payload.len); err = get_event_payload(c, p->message.payload.len); if (err >= 0) { - - if (config->data_cb) { - config->data_cb(payload_buf, p->message.payload.len, p->message.topic.topic.utf8); + if(! strncmp(p->message.topic.topic.utf8,"$iothub/twin/res/",17)){ + if (config->twin_cb) { + config->twin_cb(payload_buf, p->message.payload.len, p->message.topic.topic.utf8); + } else { + printk("Error: no mqtt twin_cb configured\n"); + } + } else{ + if (config->data_cb) { + config->data_cb(payload_buf, p->message.payload.len, p->message.topic.topic.utf8); } else { - printk("Error: no mqtt data_cb configured\n"); + printk("Error: no mqtt data_cb configured\n"); + } + } } else { @@ -434,22 +442,22 @@ bool iotc_nrf_mqtt_init(IotconnectMqttConfig *c, IotclSyncResponse *sr) { config = c; if (!client_init()) { - return false; + return -1; } err = mqtt_connect(&client); if (err != 0) { printk("ERROR: mqtt_connect %d\n", err); - return false; + return -2; } err = fds_init(&client); if (err != 0) { printk("ERROR: fds_init %d\n", err); - return false; + return -3; } - return true; + return 1; } diff --git a/iotconnect-sdk/src/iotconnect.c b/iotconnect-sdk/src/iotconnect.c index 3dfb88e..0bbcad4 100644 --- a/iotconnect-sdk/src/iotconnect.c +++ b/iotconnect-sdk/src/iotconnect.c @@ -37,6 +37,12 @@ static IotconnectMqttConfig mqtt_config = {0}; static char send_buf[MAXLINE + 1]; static bool sdk_initialized = false; +char* const twinPropertyPubTopic ="$iothub/twin/PATCH/properties/reported/?$rid=1"; +char* const twinPropertySubTopic ="$iothub/twin/PATCH/properties/desired/#"; +char* const twinResponsePubTopic ="$iothub/twin/GET/?$rid=0"; +char* const twinResponseSubTopic ="$iothub/twin/res/#"; + + static void dump_response(const char *message, IotconnectNrfHttpResponse *response) { printk("%s", message); if (response->raw_response) { @@ -182,7 +188,20 @@ void iotc_on_mqtt_data(const uint8_t *data, size_t len, const char *topic) { str[len] = 0; printk("event>>> %s\n", str); if (!iotcl_process_event(str)) { - printk("Error encountered while processing %s\n", str); + printk("Error encountered while processing command ::%s\n", str); + } + free(str); +} + +void iotc_twin_mqtt_data(const uint8_t *data, size_t len, const char *topic) { + (void) topic; // ignore topic for now + char *str = malloc(len + 1); + char *SMS; + memcpy(str, data, len); + str[len] = 0; + printk("event>>> %s\n", str); + if (!twin_event(str)) { + printk("Error encountered while processing Twin ::%s\n", str); } free(str); } @@ -208,6 +227,29 @@ void iotconnect_sdk_send_packet(const char *data) { } } +void iotconnect_sdk_send_twin_update_packet(const char *data) { + if (0 != iotc_nrf_mqtt_publish(&client, twinPropertyPubTopi, MQTT_QOS_0_AT_MOST_ONCE, data, strlen(data))) { + printk("\n\t Device_twin_Data Publish failure"); + } +} + +//This will UpdateTwin property to IoTConnect +void UpdateTwin(char *key,char *value){ + char *Twin_Json_Data; + cJSON *root; + root = cJSON_CreateObject(); + + cJSON_AddStringToObject(root, key, value); + Twin_Json_Data = cJSON_PrintUnformatted(root); + + printk("json format of Twin_Json_Data = %s",Twin_Json_Data); + iotconnect_sdk_send_twin_update_packet(Twin_Json_Data); + + cJSON_Delete(root); + free(Twin_Json_Data); +} + + static void on_message_intercept(IotclEventData data, IotConnectEventType type) { switch (type) { case ON_FORCE_SYNC: @@ -289,6 +331,7 @@ int iotconnect_sdk_init() { lib_config.telemetry.dtg = sync_response->dtg;; lib_config.event_functions.ota_cb = config.ota_cb; lib_config.event_functions.cmd_cb = config.cmd_cb; + lib_config.event_functions.twin_msg_rciv = config.twin_msg_rciv; // intercept internal processing and forward to client lib_config.event_functions.msg_cb = on_message_intercept; @@ -301,6 +344,7 @@ int iotconnect_sdk_init() { } mqtt_config.tls_verify = CONFIG_PEER_VERIFY; mqtt_config.data_cb = iotc_on_mqtt_data; + mqtt_config.twin_cb = iotc_twin_mqtt_data; mqtt_config.status_cb = on_iotconnect_status; if (!iotc_nrf_mqtt_init(&mqtt_config, sync_response)) { diff --git a/samples/iotc-basic/src/main.c b/samples/iotc-basic/src/main.c index d0d839f..619c403 100644 --- a/samples/iotc-basic/src/main.c +++ b/samples/iotc-basic/src/main.c @@ -19,7 +19,7 @@ #include "led_pwm.h" #else #define ui_leds_init() -#define ui_led_set_rgb(a,b,c) (void) (a,b,c) +#define ui_led_set_rgb(a,b,c) #endif #include #include @@ -189,6 +189,28 @@ static void on_ota(IotclEventData data) { } } +static void TwinUpdateCallback(IotclEventData payload) +{ + + TwinStrings* result = getTwinStrings(payload); + + /* + Type : Public Method "updateTwin()" + Usage : Upate the twin reported property + Output : + Input : "key" and "value" as below + // String key = "<< Desired property key >>"; // Desired proeprty key received from Twin callback message + // String value = "<< Desired Property value >>"; // Value of respective desired property + */ + UpdateTwin(result->key,result->value); + + // Don't forget to free the allocated memory + free(result); + +} + + + static void on_command(IotclEventData data) { const char *command = iotcl_clone_command(data); if (NULL != command) { @@ -663,6 +685,7 @@ void main(void) { config->cmd_cb = on_command; config->ota_cb = on_ota; config->status_cb = on_connection_status; + config->twin_msg_rciv = TwinUpdateCallback; #pragma clang diagnostic push #pragma ide diagnostic ignored "EndlessLoop" diff --git a/samples/iotc-sensors-gps/src/main.c b/samples/iotc-sensors-gps/src/main.c index 57d6986..2f66b87 100644 --- a/samples/iotc-sensors-gps/src/main.c +++ b/samples/iotc-sensors-gps/src/main.c @@ -24,7 +24,7 @@ #include "buzzer.h" #else #define ui_leds_init() -#define ui_led_set_rgb(a,b,c) (void) (a,b,c) +#define ui_led_set_rgb(a,b,c) #define ui_buzzer_init() #endif #include "iotconnect.h" @@ -212,6 +212,26 @@ static void on_ota(IotclEventData data) { } } +static void TwinUpdateCallback(IotclEventData payload) +{ + + TwinStrings* result = getTwinStrings(payload); + + /* + Type : Public Method "updateTwin()" + Usage : Upate the twin reported property + Output : + Input : "key" and "value" as below + // String key = "<< Desired property key >>"; // Desired proeprty key received from Twin callback message + // String value = "<< Desired Property value >>"; // Value of respective desired property + */ + UpdateTwin(result->key,result->value); + + // Don't forget to free the allocated memory + free(result); + +} + static void on_command(IotclEventData data) { char *command = iotcl_clone_command(data); if (NULL != command) { @@ -223,6 +243,7 @@ static void on_command(IotclEventData data) { } } + static void on_connection_status(IotconnectConnectionStatus status) { // Add your own status handling switch (status) { @@ -917,6 +938,8 @@ void main(void) { config->cmd_cb = on_command; config->ota_cb = on_ota; config->status_cb = on_connection_status; + config->twin_msg_rciv = TwinUpdateCallback; + #pragma clang diagnostic push #pragma ide diagnostic ignored "EndlessLoop" From 95f769b48698d9b008a0207d5b3f9d398273449c Mon Sep 17 00:00:00 2001 From: sw-iot-neeravparasar Date: Mon, 1 Jan 2024 19:04:09 +0530 Subject: [PATCH 2/3] iot-c-lib-patch twin update --- scripts/setup-iotc-c-lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup-iotc-c-lib.sh b/scripts/setup-iotc-c-lib.sh index 219e684..dd00f3b 100755 --- a/scripts/setup-iotc-c-lib.sh +++ b/scripts/setup-iotc-c-lib.sh @@ -2,6 +2,6 @@ set -e -git clone --depth 1 --branch v2.0.0 git://github.com/Avnet/iotc-c-lib.git +git clone --depth 1 --branch iotc-c-lib-patch https://github.com/avnet-iotconnect/iotc-c-lib.git test -d iotc-c-lib cp -f common/iotc-c-lib-overlay/CMakeLists.txt iotc-c-lib/ From 2e1de91e2c0518b1d6b3767504b08939b5b282e7 Mon Sep 17 00:00:00 2001 From: sw-iot-neeravparasar Date: Tue, 9 Jan 2024 17:05:58 +0530 Subject: [PATCH 3/3] STD format for twin --- iotconnect-sdk/include/iotconnect.h | 2 +- iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c | 6 +++--- iotconnect-sdk/src/iotconnect.c | 8 ++++---- samples/iotc-basic/src/main.c | 12 ++++++------ samples/iotc-sensors-gps/src/main.c | 12 ++++++------ 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/iotconnect-sdk/include/iotconnect.h b/iotconnect-sdk/include/iotconnect.h index dcd9674..dfd268d 100644 --- a/iotconnect-sdk/include/iotconnect.h +++ b/iotconnect-sdk/include/iotconnect.h @@ -37,7 +37,7 @@ typedef struct { char *duid; // Name of the device. IotclOtaCallback ota_cb; // callback for OTA events. IotclCommandCallback cmd_cb; // callback for command events. - IotcltwinrecivCallback twin_msg_rciv; + IotcltwinrecivCallback twin_msg_cb; IotclMessageCallback msg_cb; // callback for ALL messages, including the specific ones like cmd or ota callback. IotConnectStatusCallback status_cb; // callback for connection status diff --git a/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c b/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c index bae6cf0..fc6d544 100644 --- a/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c +++ b/iotconnect-sdk/nrf-layer-lib/src/iotconnect_mqtt.c @@ -331,12 +331,12 @@ static void mqtt_evt_handler(struct mqtt_client *const c, } else { printk("Error: no mqtt twin_cb configured\n"); } - } else{ + } else { if (config->data_cb) { config->data_cb(payload_buf, p->message.payload.len, p->message.topic.topic.utf8); - } else { + } else { printk("Error: no mqtt data_cb configured\n"); - } + } } diff --git a/iotconnect-sdk/src/iotconnect.c b/iotconnect-sdk/src/iotconnect.c index 0bbcad4..8267e72 100644 --- a/iotconnect-sdk/src/iotconnect.c +++ b/iotconnect-sdk/src/iotconnect.c @@ -200,7 +200,7 @@ void iotc_twin_mqtt_data(const uint8_t *data, size_t len, const char *topic) { memcpy(str, data, len); str[len] = 0; printk("event>>> %s\n", str); - if (!twin_event(str)) { + if (!iotcl_process_twin_event(str)) { printk("Error encountered while processing Twin ::%s\n", str); } free(str); @@ -233,8 +233,8 @@ void iotconnect_sdk_send_twin_update_packet(const char *data) { } } -//This will UpdateTwin property to IoTConnect -void UpdateTwin(char *key,char *value){ +//This will iotconnect_update_twin property to IoTConnect +void iotconnect_update_twin(char *key,char *value){ char *Twin_Json_Data; cJSON *root; root = cJSON_CreateObject(); @@ -331,7 +331,7 @@ int iotconnect_sdk_init() { lib_config.telemetry.dtg = sync_response->dtg;; lib_config.event_functions.ota_cb = config.ota_cb; lib_config.event_functions.cmd_cb = config.cmd_cb; - lib_config.event_functions.twin_msg_rciv = config.twin_msg_rciv; + lib_config.event_functions.twin_msg_cb = config.twin_msg_cb; // intercept internal processing and forward to client lib_config.event_functions.msg_cb = on_message_intercept; diff --git a/samples/iotc-basic/src/main.c b/samples/iotc-basic/src/main.c index 619c403..0667378 100644 --- a/samples/iotc-basic/src/main.c +++ b/samples/iotc-basic/src/main.c @@ -19,7 +19,7 @@ #include "led_pwm.h" #else #define ui_leds_init() -#define ui_led_set_rgb(a,b,c) +#define ui_led_set_rgb(a,b,c) (void) (a,b,c) #endif #include #include @@ -189,20 +189,20 @@ static void on_ota(IotclEventData data) { } } -static void TwinUpdateCallback(IotclEventData payload) +static void on_twin_command(IotclEventData payload) { - TwinStrings* result = getTwinStrings(payload); + TwinStrings *result = iotcl_get_twin_key_and_value(payload); /* - Type : Public Method "updateTwin()" + Type : Public Method "iotconnect_update_twin()" Usage : Upate the twin reported property Output : Input : "key" and "value" as below // String key = "<< Desired property key >>"; // Desired proeprty key received from Twin callback message // String value = "<< Desired Property value >>"; // Value of respective desired property */ - UpdateTwin(result->key,result->value); + iotconnect_update_twin(result->key,result->value); // Don't forget to free the allocated memory free(result); @@ -685,7 +685,7 @@ void main(void) { config->cmd_cb = on_command; config->ota_cb = on_ota; config->status_cb = on_connection_status; - config->twin_msg_rciv = TwinUpdateCallback; + config->twin_msg_cb = on_twin_command; #pragma clang diagnostic push #pragma ide diagnostic ignored "EndlessLoop" diff --git a/samples/iotc-sensors-gps/src/main.c b/samples/iotc-sensors-gps/src/main.c index 2f66b87..f054bd7 100644 --- a/samples/iotc-sensors-gps/src/main.c +++ b/samples/iotc-sensors-gps/src/main.c @@ -24,7 +24,7 @@ #include "buzzer.h" #else #define ui_leds_init() -#define ui_led_set_rgb(a,b,c) +#define ui_led_set_rgb(a,b,c) (void) (a,b,c) #define ui_buzzer_init() #endif #include "iotconnect.h" @@ -212,20 +212,20 @@ static void on_ota(IotclEventData data) { } } -static void TwinUpdateCallback(IotclEventData payload) +static void on_twin_command(IotclEventData payload) { - TwinStrings* result = getTwinStrings(payload); + TwinStrings *result = iotcl_get_twin_key_and_value(payload); /* - Type : Public Method "updateTwin()" + Type : Public Method "iotconnect_update_twin()" Usage : Upate the twin reported property Output : Input : "key" and "value" as below // String key = "<< Desired property key >>"; // Desired proeprty key received from Twin callback message // String value = "<< Desired Property value >>"; // Value of respective desired property */ - UpdateTwin(result->key,result->value); + iotconnect_update_twin(result->key,result->value); // Don't forget to free the allocated memory free(result); @@ -938,7 +938,7 @@ void main(void) { config->cmd_cb = on_command; config->ota_cb = on_ota; config->status_cb = on_connection_status; - config->twin_msg_rciv = TwinUpdateCallback; + config->twin_msg_cb = on_twin_command; #pragma clang diagnostic push