Yalgaar mBed SDK for real-time messaging
Fork of MQTT by
Diff: yalgaar_api.cpp
- 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