MESSAGE_HANDLE MESSAGE_QUEUE_front(MESSAGE_QUEUE_HANDLE handle) { MESSAGE_HANDLE result; if (handle == NULL) { /*Codes_SRS_MESSAGE_QUEUE_17_019: [ MESSAGE_QUEUE_front shall return NULL if handle is NULL. ]*/ LogError("invalid argument handle (NULL)."); result = NULL; } else { /*Codes_SRS_MESSAGE_QUEUE_17_020: [ MESSAGE_QUEUE_front shall return NULL if the message queue is empty. ]*/ if (DList_IsListEmpty((PDLIST_ENTRY)&(handle->queue_head))) { result = NULL; } else { /*Codes_SRS_MESSAGE_QUEUE_17_021: [ On a non-empty queue, MESSAGE_QUEUE_front shall return the first remaining element that was pushed onto the message queue. ]*/ MESSAGE_QUEUE_STORAGE* entry = (MESSAGE_QUEUE_STORAGE*)DList_RemoveHeadList((PDLIST_ENTRY)&(handle->queue_head)); result = entry->message; /*Codes_SRS_MESSAGE_QUEUE_17_022: [ The content of the message queue shall not be changed after calling MESSAGE_QUEUE_front. ]*/ DList_InsertHeadList((PDLIST_ENTRY)&(handle->queue_head), (PDLIST_ENTRY)entry); } } return result; }
MQTTAPI_RESULT MQTTAPI_PublishMessage(MQTTAPI_HANDLE instance, const char* topicName, const MQTTAPI_Message* msg, void* context) { MQTTAPI_RESULT result; PMQTTTAPI_HANDLE_DATA mqttApiHandleData = (PMQTTTAPI_HANDLE_DATA)instance; /* Codes_SRS_MQTTAPI_04_038: [If any of the parameter is NULL, MQTTAPI_PublishMessage shall return MQTTAPI_INVALID_ARG.] */ if (instance == NULL) { LogError("Invalid Argument. instance can't be null.\r\n"); result = MQTTAPI_INVALID_ARG; } /* Codes_SRS_MQTTAPI_04_038: [If any of the parameter is NULL, MQTTAPI_PublishMessage shall return MQTTAPI_INVALID_ARG.] */ else if (topicName == NULL || strlen(topicName) <= 0) { LogError("Invalid Argument. topicName can't be null or empty.\r\n"); result = MQTTAPI_INVALID_ARG; } /* Codes_SRS_MQTTAPI_04_038: [If any of the parameter is NULL, MQTTAPI_PublishMessage shall return MQTTAPI_INVALID_ARG.] */ else if (msg == NULL) { LogError("Invalid Argument. msg can't be null.\r\n"); result = MQTTAPI_INVALID_ARG; } /* Codes_SRS_MQTTAPI_04_059: [If DeliveryCompleted callback is not set publishMessage shall return MQTTAPI_ERROR.] */ else if (mqttApiHandleData->dcCallback == NULL) { LogError("Error Sending data, missind Delivery Completed callback to be set.\r\n"); result = MQTTAPI_ERROR; } else { MQTTAPI_MESSAGE_SEND_LIST* mqttApiMessageEntryList; /* Codes_SRS_MQTTAPI_04_039: [MQTTAPI_PublishMessage shall create structure needed to send a message to the topic described by the topicName parameter.] */ if ((mqttApiMessageEntryList = (MQTTAPI_MESSAGE_SEND_LIST*)malloc(sizeof(MQTTAPI_MESSAGE_SEND_LIST))) == NULL) { LogError("Memmory Allocation failure to create mqttApi Message.\r\n"); result = MQTTAPI_ERROR; } else if ((mqttApiMessageEntryList->topicName = STRING_construct(topicName)) == NULL) { LogError("Could not create topicName String.\r\n"); free(mqttApiMessageEntryList); result = MQTTAPI_ERROR; } else { MQTTClient_message *pubmsg = (MQTTClient_message *)malloc(sizeof(MQTTClient_message)); if (pubmsg == NULL) { LogError("Memory Allocation Failure to create MQTTClient_message.\r\n"); STRING_delete(mqttApiMessageEntryList->topicName); free(mqttApiMessageEntryList); result = MQTTAPI_ERROR; } else { pubmsg->struct_id[0] = 'M'; pubmsg->struct_id[1] = 'Q'; pubmsg->struct_id[2] = 'T'; pubmsg->struct_id[3] = 'M'; pubmsg->struct_version = 0; pubmsg->qos = SENDMESSAGEQOS; pubmsg->retained = 0; pubmsg->dup = 0; pubmsg->msgid = 0; pubmsg->payloadlen = msg->payloadlen; /* Codes_SRS_MQTTAPI_04_043: [MQTTAPI_PublishMessage shall clone MQTTAPI_Message so the user can free it after calling publishMessage.] */ if ((pubmsg->payload = malloc(msg->payloadlen)) == NULL) { LogError("Memory Allocation Failure to create MQTTClient_message.\r\n"); free(pubmsg); STRING_delete(mqttApiMessageEntryList->topicName); free(mqttApiMessageEntryList); result = MQTTAPI_ERROR; } else { (void)memcpy(pubmsg->payload, msg->payload, msg->payloadlen); /* Codes_SRS_MQTTAPI_04_058: [If context is not NULL it shall be stored and passed to the user when received callback function is called.] */ mqttApiMessageEntryList->context = context; mqttApiMessageEntryList->messageToSend = pubmsg; DList_InsertHeadList(&(mqttApiHandleData->messagesToSend), &(mqttApiMessageEntryList->entry)); /* Codes_SRS_MQTTAPI_04_048: [If the message was correctly queued (on it’s on a queue on underlying library) MQTTAPI_PublishMessage shall return MQTTAPI_OK.] */ result = MQTTAPI_OK; } } } } return result; }
/* Codes_SRS_MQTTAPI_04_006: [The MQTTAPI_Message parameter contains the structure for the received message, with message payload.] */ static int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { MQTTAPI_MESSAGE_RECEIVED_LIST* mqttAPIMessgeEntryList; int result; PMQTTTAPI_HANDLE_DATA mqttApiHandleData = (PMQTTTAPI_HANDLE_DATA)context; (void)(topicLen, topicName); if (mqttApiHandleData == NULL) { LogError("Context parameter cannot be null. Ignoring message \r\n"); result = 1; } else if (mqttApiHandleData->maCallBack == NULL) { /* Codes_SRS_MQTTAPI_04_061: [If maCallBack is not set, MQTTAPI_MessageArrived shall return 0 to ignore received messages.] */ result = 1; } else if (message == NULL) { LogError("message parameter cannot be null. Returning error, so it can be sent again.\r\n"); result = 0; } else if ((mqttAPIMessgeEntryList = (MQTTAPI_MESSAGE_RECEIVED_LIST*)malloc(sizeof(MQTTAPI_MESSAGE_RECEIVED_LIST))) == NULL) { LogError("Memory Allocation Failure for MQTTAPI_Message entry list.\r\n"); result = 0; } else if ((mqttAPIMessgeEntryList->messageReceived = (MQTTAPI_Message*)malloc(sizeof(MQTTAPI_Message))) == NULL) { LogError("Memory Allocation Failure for MQTTAPI_Message.\r\n"); free(mqttAPIMessgeEntryList); result = 0; } else { mqttAPIMessgeEntryList->messageReceived->payloadlen = message->payloadlen; if ((mqttAPIMessgeEntryList->messageReceived->payload = (unsigned char*)malloc(mqttAPIMessgeEntryList->messageReceived->payloadlen)) == NULL) { LogError("Memory allocation error.\r\n"); free(mqttAPIMessgeEntryList->messageReceived); free(mqttAPIMessgeEntryList); result = 0; } else { (void)memcpy(mqttAPIMessgeEntryList->messageReceived->payload, message->payload, message->payloadlen); if (Lock(mqttApiHandleData->LockHandle) == LOCK_OK) { DList_InsertHeadList(&(mqttApiHandleData->messagesReceived), &(mqttAPIMessgeEntryList->entry)); Unlock(mqttApiHandleData->LockHandle); result = 1; } else { LogError("Problem Aquiring Lock to add message received on the list.\r\n"); free(mqttAPIMessgeEntryList->messageReceived->payload); free(mqttAPIMessgeEntryList->messageReceived); free(mqttAPIMessgeEntryList); result = 0; } } } //We just free the MQTTClient Message if it was succesfully received, otherwise MQTTClient will call this with a corrupted message. if (message != NULL && result == 1) { MQTTClient_freeMessage(&message); } return result; }