Yalgaar mBed SDK for real-time messaging

Dependents:   YalgaarSDK

Fork of MQTT by Joerg Wende

Revision:
1:c233cee7c15b
Child:
4:013cbaaeda50
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yalgaar_api.cpp	Fri Mar 10 13:11:49 2017 +0000
@@ -0,0 +1,451 @@
+/** @fileName <yalgaar_api>
+ *  @brief - <Yalgaar SDK APIS>
+ *
+ *  @Version:V:01:00:000
+ *
+ *
+ * @Copyright:
+ * Copyright (c) 2010 System Level Solution (India) pvt.ltd. Corporation.  All rights reserved.
+ *
+ * License: Free License for Yalgaar Users
+ * Disclaimer:
+ * SLS MAKES NO REPRESENTATION, WARRANTY, OR CONDITION OF ANY KIND, EXPRESS,
+ * IMPLIED, STATUTORY, OR OTHERWISE OR IN ANY COMMUNICATION WITH YOU, INCLUDING,
+ * BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY
+ * QUALITY, FITNESS FOR ANY PARTICULAR PURPOSE, NONINFRINGEMENT, AND THEIR
+ * EQUIVALENTS.
+ */
+#include "yalgaar_api.h"
+
+Serial pc2(USBTX, USBRX, 115200);
+
+void (* connection_main_Callback)(char *);
+void (* yalgaar_presence_message_recv)(char *);
+void (* yalgaar_error_message)(char *error);
+void (* yalgaar_new_message)(char * message);
+void parse_subscribe_message(char*,char*, unsigned int);
+void subscribe_callback_handler(char*,char*, unsigned int);
+
+char uuid_general[YALGAAR_MAX_UUID_STR_COUNT];
+char gclient_key[YALGAAR_CLIENT_KEY_MAX_LENGTH];
+
+const char *YALGAAR_ERROR_LIST[]= {
+    "ClientId should not be null.",
+    "Invalid ClientId.",
+    "Invalid ClientKey.ClientKey is not registered. ",
+    "Invalid Uuid.Only alpha numeric,hyphens,@,underscore allowed and maximum length must be 50.",
+    "ClientKey is not active.",
+    "SSL is not enable.",
+    "The maximum connection limit has been reached.",
+    "Invalid subscribe channel.",
+    "Invalid subscribe channel.ClientKey does not match.",
+    "Multiple subscribe channels are not allowed. Multiplexing is not enable.",
+    "Invalid subscribe channel.Only alpha numeric,hyphens,@,underscore allowed and maximum length must be 50.",
+    "Storage is not enable.",
+    "Presence is not enable.",
+    "Entered history channel has not been subscribed.",
+    "Message can not be null.",
+    "Invalid publish channel.",
+    "Invalid publish channel.ClientKey does not match.",
+    "Message count exceeds maximum limit.",
+    "Message size exceeds maximum limit.",
+    "Invalid publish channel.Only alpha numeric,hyphens,@,underscore allowed and maximum length must be 50.",
+    "Invalid UnSubscribe channel.",
+    "Invalid UnSubscribe channel.ClientKey does not match.",
+    "Invalid UnSubscribe channel.Only alpha numeric,hyphens,@,underscore allowed and maximum length must be 50."
+};
+
+/**********************************************************************************
+ *   @name                      : yalgaar_error_t yalgaar_wrapper_validate_string(const char * str)
+ *   @param const char * str    : char pointer str parameter contains string which have to validate.
+ *   @return yalgaar_error_t                : function returns error id.
+ *   @brief                     : validate the uuid for proper alpha numeric value(as per defined).
+ **********************************************************************************/
+Yalgaar_Error_t yalgaar_wrapper_validate_string(const char * str)
+{
+    char a = strlen(str);
+    int i = 0;
+
+    if(a > YALGAAR_MAX_CHANNEL_NAME_LENGTH) {
+        return INVL_STRING;
+    }
+    for(i=0; i<a; i++) {
+        if (0x3f < str[i]) {
+            if(str[i] < 0x5b) {
+                continue;
+            }
+        }
+        if(0x30 <=str[i]) {
+            if(str[i] <= 0x39) {
+                continue;
+            }
+        }
+        if(0x61 <=str[i]) {
+            if(str[i] <= 0x7a) {
+                continue;
+            }
+        }
+        if(str[i] == 0x5f) {
+            continue;
+        }
+        if(str[i] == 0x2d) {
+            continue;
+        }
+        return INVL_STRING;
+    }
+
+    return SUCCESS;
+}
+/**********************************************************************************
+ *   @name                  : static char *rand_string(char *str, size_t size)
+ *   @param  char *str      : str is used to store generated random string for UUID.
+ *   @param size_t size : size is used into string generation for random string length.
+ *   @return void           :
+ *   @brief                 : generate random string for dynamic UUID for topic string creation.
+ **********************************************************************************/
+void rand_string(char *str, size_t size)
+{
+    const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK";
+    if (size) {
+        size_t n;
+        --size;
+        for (n = 0; n < size; n++) {
+            int key = rand() % (int) (sizeof charset - 1);
+            str[n] = charset[key];
+        }
+        str[size] = '\0';
+    }
+}
+/**********************************************************************************
+*   @name                  : char* rand_string_alloc(size_t size)
+*   @param size_t size     : size parameter is used to malloc size for random string.
+*   @return char *         : returns generaed random string pointer.
+*   @brief                 : memory allocate for variable to store rand string.
+**********************************************************************************/
+char* rand_string_alloc(size_t size)
+{
+    char *s = (char *)malloc(size + 1);
+    if (s) {
+        rand_string(s, size);
+    }
+    return s;
+}
+
+/**********************************************************************************
+ *   @name                  : void enum_to_message(yalgaar_error_t *error_msg,unsigned char *errorString)
+ *   @param  error_msg      : error_msg is int parameter for error message enum.
+ *   @param  errorString    : errorString is char pointer, error string copy from YALGAAR_ERROR_LIST & stored into errorString
+ *   @return void           :
+ *   @brief                 : convert error Id(enum) to error message and set into char pointer.
+ **********************************************************************************/
+void yalgaar::enum_to_message(int error_msg,char *errorString)
+{
+    if(error_msg==CLIENT_NULL) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[0],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==CLIENT_NOT_VALID) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[1],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==CLIENT_KEY_NOT_REG) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[2],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==UUID_NOT_VALID) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[3],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==CLIENT_KEY_NOT_ACTIVE) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[4],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==SSL_NOT_ENABLE) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[5],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==CONNECTION_LIMIT_EXCEED) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[6],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==SUBCRIPTION_NOT_VALID) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[7],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==SUBCRIPTION_CLIENT_KEY_NOT_MATCH) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[8],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==MULTIPLE_SUBCRIBES_NOT_ALLOWED) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[9],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==SUBCRIBE_CHANNEL_LENGTH_EXCEED) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[10],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==STORAGE_NOT_ENABLE) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[11],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==PRESENCE_NOT_ENABLE) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[12],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==HISTORY_CHANNEL_NOT_SUBCRIBE) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[13],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==MESSAGE_NOT_NULL) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[14],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==PUBLISH_CHANNEL_NOT_VALID) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[15],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==PUBLISH_CLIENT_KEY_NOT_MATCH) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[16],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==MESSAGE_CNT_EXCEED) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[17],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==MESSAGE_SIZE_EXCEED) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[18],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==MESSAGE_LENGTH_EXCEED) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[19],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==UNSUBSCRIBE_CHANNEL_NOT_VALID) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[20],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==UNSUBSCRIBE_CLIENT_KEY_NOT_MATCH) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[21],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else if(error_msg==UNSUBSCRIBE_CHANNEL_LENGTH_EXCEED) {
+        strncpy(errorString,YALGAAR_ERROR_LIST[22],YALGAAR_ERROR_MESSAGE_LENGTH);
+    } else {
+        strcpy(errorString,"Undefined Error");
+    }
+    return;
+}
+/**********************************************************************************
+ *   @name                      : void parse_subscribe_message(char* topic, char* payload, unsigned int length)
+ *   @param char * topic        : topicName parameter have received message topic name.
+ *   @param unsigned int length : payload_len parameter have Received message payload length.
+ *   @param uint8_t* payload    : payload * have row data of received message for parsing
+ *   @return void               : .
+ *   @brief                     : filter message using subscribe message for specific message.
+ **********************************************************************************/
+void parse_subscribe_message(char* topic, char* payload, unsigned int length)
+{
+    char temppayload[length];
+    char * start_string =NULL;
+    memset(temppayload,0,length);
+    for (int i=0; i<length; i++) {
+        temppayload[i] = payload[i];
+    }
+    start_string = strstr(temppayload,"isPresence");
+    if(start_string != NULL) {
+        yalgaar_presence_message_recv(payload);
+    } else {
+        yalgaar_new_message(payload);
+    }
+
+}
+/**********************************************************************************
+ *   @name                                  : void subscribe_callback_handler(char* topic, char* payload, unsigned int length)
+ *   @param char* topic                     : subscribe topic for yalgaar
+ *   @param uint8_t* payload                : Payload of recieve message
+ *   @param unsigned int length             : length of recieve mesaage
+ *   @return void                           :
+ *   @brief                                 : this function will called when any message received on specific subscribed topic.
+ **********************************************************************************/
+void subscribe_callback_handler(char* topic, char* payload, unsigned int length)
+{
+    parse_subscribe_message(topic,payload,length);
+}
+
+/**********************************************************************************
+ *   @name                                          : Yalgaar_Error_t yalgaar::yalgaar_connect(const char* id,void(*connectionCallback)( int,char * ))
+ *   @param char *clientKey                         : clientkey contains the yalgaar server clientKey for all SDK.
+ *   @param void(*connectionCallback)( int,char* )  : connectionCallback is a function pointer of connect callback function.
+ *   @return Yalgaar_Error_t                        : contains the success or failure status of connection.
+ *   @brief                                         : This function is called before any other function of this SDK for init the mosquitto library and it will get connected to the yalgaar server.
+ **********************************************************************************/
+Yalgaar_Error_t yalgaar::yalgaar_connect(const char* clientKey,const char *uuid,void(*connectionCallback)(char * ))
+{
+    char clientID[YALGAAR_CLIENT_DEFAULT_STRING_LEN];
+    bool ret;
+
+    //UUID Validation
+    if(clientKey == NULL || clientKey == "") {
+        return CLIENT_NULL;
+    }
+    if(uuid == NULL || uuid == "") {
+        uuid = rand_string_alloc(YALGAAR_MAX_UUID_STR_COUNT);
+        strncpy(uuid_general,uuid,sizeof(uuid_general));
+    } else {
+        if(yalgaar_wrapper_validate_string(uuid) != SUCCESS) {
+            return UUID_NOT_VALID;
+        }
+
+        strncpy(uuid_general,uuid,sizeof(uuid_general));
+    }
+    sprintf(clientID,"%s/%s",clientKey,uuid_general);
+    connection_main_Callback=connectionCallback;
+    snprintf(gclient_key,sizeof(gclient_key),"%s",(char *)clientKey);
+    ret=connect(clientID);
+        wait(2.0f); 
+    connection_state(ret);
+    if (ret == 1)
+        return SUCCESS;
+    else
+        return FAILURE;
+}
+
+/**********************************************************************************
+ *   @name                      : Yalgaar_Error_t yalgaar_publish(const char *topic,char *payload)
+ *   @param const char *topic   : channel name to publish on specific topic
+ *   @param char *payload       : message string to publish
+ *   @return Yalgaar_Error_t    : it will return success or failure status of publish message.
+ *   @brief                     : this function is called to publish any message to specific topic.
+ **********************************************************************************/
+Yalgaar_Error_t yalgaar::yalgaar_publish(const char* topic, char* payload)
+{
+    char publish_channel[128]= {0};
+    if(topic == NULL || topic == "") {
+        return MESSAGE_LENGTH_EXCEED;
+    }
+    if(yalgaar_wrapper_validate_string(topic) != SUCCESS) {
+        return SUBCRIBE_CHANNEL_LENGTH_EXCEED;
+    } else {
+        if(payload=="" || payload==NULL) {
+            return MESSAGE_NOT_NULL;
+        }
+    }
+    sprintf(publish_channel,"%s/%s",gclient_key,topic);
+    if(publish(publish_channel,payload) == SUCCESS) {
+        return SUCCESS;
+    } else {
+        return FAILURE;
+    }
+}
+/**********************************************************************************
+ *   @name                                                      : Yalgaar_Error_t yalgaar::yalgaar_subscribe(char * subscribe_channel,void(* sub_mesg_callback)(void *),void(*presence_mesg_callback)(void *), void(*error_msg_callback)(void *))
+ *   @param char * subscribe_channel                            : topic name of subscription
+ *   @param void(* sub_mesg_callback)(void *)                   : function pointer of normal message receive callback function
+ *   @param void(*presence_mesg_callback)(struct presence_t *)  : function pointer of presence message callback function
+ *   @param void(*error_msg_callback)(void *)                   : function pointer of error message callback function
+ *   @return Yalgaar_Error_t                                    : it will return success or failure status of subscription.
+ *   @brief                                                     : this function will use to subscribe specific topic with clientID. set callback_function for each message type.
+ **********************************************************************************/
+Yalgaar_Error_t yalgaar::yalgaar_subscribe(char * subscribe_channel,void(* sub_mesg_callback)(char *),void(*presence_mesg_callback)(char *), void(*error_msg_callback)(char *))
+{
+    char sub_channel[YALGAAR_MAX_CHANNEL_NAME_LENGTH];
+    if (subscribe_channel == NULL || subscribe_channel == "") {
+        return SUBCRIPTION_NOT_VALID;
+    }
+    if(yalgaar_wrapper_validate_string(subscribe_channel) != SUCCESS) {
+        return SUBCRIBE_CHANNEL_LENGTH_EXCEED;
+    } else {
+        if(presence_mesg_callback != NULL)
+            yalgaar_presence_message_recv=presence_mesg_callback;
+        yalgaar_new_message=sub_mesg_callback;
+        yalgaar_error_message=error_msg_callback;
+        setCallback(subscribe_callback_handler);
+        sprintf(sub_channel,"%s/%s",gclient_key,subscribe_channel);
+        if(subscribe(sub_channel) == SUCCESS)
+            return SUCCESS;
+        else
+            return FAILURE;
+    }
+}
+
+/**********************************************************************************
+ *   @name                                                      : Yalgaar_Error_t yalgaar::yalgaar_subscribes(uint8_t **subscribe_channel,void(* sub_mesg_callback)(void *),void(*presence_mesg_callback)(void *), void(*error_msg_callback)(void *))
+ *   @param uint8_t * subscribe_channel                         : topic name of subscription
+ *   @param void(* sub_mesg_callback)(void *)                   : function pointer of normal message receive callback function
+ *   @param void(*presence_mesg_callback)(struct presence_t *)  : function pointer of presense message callback funcation
+ *   @param void(*error_msg_callback)(void *)                   : function pointer of error message callback function
+ *   @return Yalgaar_Error_t                                    : it will return success or failure status of subscription.
+ *   @brief                                                     : this function will use to subscribe specific topic with clientID. set callback_function for each message type.
+ **********************************************************************************/
+Yalgaar_Error_t yalgaar::yalgaar_subscribes(char **subscribe_channel,void(* sub_mesg_callback)(char *),void(*presence_mesg_callback)(char *), void(*error_msg_callback)(char *))
+{
+    unsigned int iterator=0;
+    Yalgaar_Error_t ret;
+    bool sub_ret;
+    char sub_channel[YALGAAR_MAX_CHANNEL_NAME_LENGTH];
+    if(presence_mesg_callback != NULL)
+        yalgaar_presence_message_recv=presence_mesg_callback;
+    yalgaar_new_message=sub_mesg_callback;
+    yalgaar_error_message=error_msg_callback;
+    setCallback(subscribe_callback_handler);
+    for(iterator=0; subscribe_channel[iterator]!= '\0' ; iterator++) {
+        if (subscribe_channel[iterator] == NULL || subscribe_channel[iterator] == "") {
+            return SUBCRIBE_CHANNEL_LENGTH_EXCEED;
+        }
+        if(yalgaar_wrapper_validate_string(subscribe_channel[iterator]) != SUCCESS) {
+            ret = SUBCRIBE_CHANNEL_LENGTH_EXCEED;
+            return ret;
+        } else {
+            memset(sub_channel,0,sizeof(sub_channel));
+            sprintf(sub_channel,"%s/%s",gclient_key,subscribe_channel[iterator]);
+            sub_ret = subscribe(sub_channel);
+        }
+    }
+    if(sub_ret)
+        return SUCCESS;
+    else
+        return FAILURE;
+}
+
+/**********************************************************************************
+ *   @name                      : Yalgaar_Error_t yalgaar::yalgaar_unsubscribe(const char* topic)
+ *   @param const char* topic   : channel name for unsubscribe specific topic/channel.
+ *   @return Yalgaar_Error_t    : it will return success or failure status of unsubscribe method.
+ *   @brief                     : this function is used to unsubscribe already subscribe topic.
+ **********************************************************************************/
+Yalgaar_Error_t yalgaar::yalgaar_unsubscribe(const char* channel)
+{
+
+    char sub_channel[YALGAAR_MAX_CHANNEL_NAME_LENGTH];
+    if(channel == NULL || channel == "") {
+        return UNSUBSCRIBE_CHANNEL_LENGTH_EXCEED;
+    }
+    if(yalgaar_wrapper_validate_string(channel) != SUCCESS) {
+        return SUBCRIBE_CHANNEL_LENGTH_EXCEED;
+    } else {
+        sprintf(sub_channel,"%s/%s",gclient_key,channel);
+        if(unsubscribe(sub_channel) == SUCCESS)
+            return SUCCESS;
+        else
+            return FAILURE;
+    }
+
+}
+/**********************************************************************************
+ *   @name                      : int yalgaar::connection_state()
+ *   @return int                : it will return retrun of connect reurn code
+ *   @brief                     : this function is used to check state of connection state
+ **********************************************************************************/
+void yalgaar::connection_state(bool ret)
+{
+    int error_code;
+    char err_message[YALGAAR_ERROR_MESSAGE_LENGTH]= {0};
+    if (ret == SUCCESS) {
+        connection_main_Callback("Connection success full");
+    } else {
+        error_code = mqtt_state();
+        enum_to_message(error_code,err_message);
+        connection_main_Callback(err_message);
+    }
+
+}
+/**********************************************************************************
+ *   @name                      : boolean yalgaar::yalgaar_loop()
+ *   @return boolean            : it will return success or failure status
+ *   @brief                     : this function is used to continue to connection
+ **********************************************************************************/
+void yalgaar::yalgaar_loop()
+{
+    char err_message[YALGAAR_ERROR_MESSAGE_LENGTH]= {0};
+    loop();
+    if (pubsub_error_code >=108 && pubsub_error_code <= 111 ) {
+        enum_to_message(pubsub_error_code,err_message);
+        yalgaar_error_message(err_message);
+        pubsub_error_code = 0;
+    }
+    if (pubsub_error_code >=121 && pubsub_error_code <= 123 ) {
+        enum_to_message(pubsub_error_code,err_message);
+        yalgaar_error_message(err_message);
+        pubsub_error_code = 0;
+    }
+    if(pubsub_error_code >=115 && pubsub_error_code <= 120 ) {
+        enum_to_message(pubsub_error_code,err_message);
+        connection_main_Callback(err_message);
+        pubsub_error_code = 0;
+    }
+}
+/**********************************************************************************
+ *   @name                      : boolean yalgaar::is_connected()
+ *   @return boolean            : it will return success or failure status
+ *   @brief                     : this function is used to cjheck yalgaar is connect or not
+ **********************************************************************************/
+bool yalgaar::yalgaar_connected()
+{
+    return connected();
+}
+/**********************************************************************************
+ *   @name                      : void yalgaar::yalgaar_disconnect()
+ *   @return Void               :
+ *   @brief                     : this function is used to disconnect from yalgaar
+ **********************************************************************************/
+void yalgaar::yalgaar_disconnect()
+{
+    connection_main_Callback("Client Successfully disconneted");
+    return disconnect();
+}
\ No newline at end of file