/** * Process an incoming publish packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePublishes(void* pack, int sock, Clients* client) { Publish* publish = (Publish*)pack; char* clientid = NULL; int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; if (client == NULL) clientid = INTERNAL_CLIENTID; /* this is an internal client */ else { clientid = client->clientID; Log(LOG_PROTOCOL, 11, NULL, sock, clientid, publish->msgId, publish->header.bits.qos, publish->header.bits.retain); } #if defined(MQTTS) rc = Protocol_handlePublishes(publish, sock, client, clientid, 0); #else rc = Protocol_handlePublishes(publish, sock, client, clientid); #endif FUNC_EXIT_RC(rc); return rc; }
int MQTTSProtocol_handlePublishes(void* pack, int sock, char* clientAddr, Clients* client) { int rc = 0; char* topicName = NULL, *expandedPreDefinedTopicName = NULL; MQTTS_Publish* pub = NULL; FUNC_ENTRY; pub = (MQTTS_Publish*)pack; Log(LOG_PROTOCOL, 55, NULL, sock, clientAddr, client ? client->clientID : "", pub->msgId, pub->flags.QoS, pub->flags.retain); // Normal - registered topic if (pub->flags.topicIdType == MQTTS_TOPIC_TYPE_NORMAL && client != NULL && pub->topicId != 0) { /* copy the topic name as it will be freed later */ char* name = MQTTSProtocol_getRegisteredTopicName(client, pub->topicId); if (name) { topicName = malloc(strlen(name) + 1); strcpy(topicName, name); } } // Pre-defined topics else if (pub->flags.topicIdType == MQTTS_TOPIC_TYPE_PREDEFINED && client != NULL && pub->topicId != 0) { /* copy the topic name as it will be freed later */ char *origPreDefinedTopicName = MQTTSProtocol_getPreDefinedTopicName(client, pub->topicId) ; if (origPreDefinedTopicName) { expandedPreDefinedTopicName = MQTTSProtocol_replaceTopicNamePlaceholders(client, origPreDefinedTopicName) ; } // If original and expanded predef topic names are same, use expanded // while it is already a copy of orig name if (strcmp(origPreDefinedTopicName, expandedPreDefinedTopicName) == 0) { topicName = expandedPreDefinedTopicName ; } else { topicName = malloc(strlen(origPreDefinedTopicName)+1); strcpy(topicName, origPreDefinedTopicName); } } // Short topic names else if (pub->flags.topicIdType == MQTTS_TOPIC_TYPE_SHORT && pub->shortTopic != NULL) { topicName = pub->shortTopic; pub->shortTopic = NULL; /* will be freed in Protocol_handlePublishes */ } // If topic name not found send PubAck with Rejected - Invalid topic ID if (topicName == NULL) { rc = MQTTSPacket_send_puback(client, pub->topicId , pub->msgId, MQTTS_RC_REJECTED_INVALID_TOPIC_ID); } else { Publish* publish = malloc(sizeof(Publish)); publish->header.bits.type = PUBLISH; publish->header.bits.qos = pub->flags.QoS; publish->header.bits.retain = pub->flags.retain; publish->header.bits.dup = pub->flags.dup; publish->msgId = pub->msgId; publish->payload = pub->data; publish->payloadlen = pub->dataLen; publish->topic = topicName; rc = Protocol_handlePublishes(publish, sock, client, client ? client->clientID : clientAddr, pub->topicId); // If predefined topic Id and predefined topic name contains [ClientId] // publish message to expanded topic name too. if ( pub->flags.topicIdType == MQTTS_TOPIC_TYPE_PREDEFINED && topicName != expandedPreDefinedTopicName) { publish = malloc(sizeof(Publish)); publish->header.bits.type = PUBLISH; publish->header.bits.qos = pub->flags.QoS; publish->header.bits.retain = pub->flags.retain; publish->header.bits.dup = pub->flags.dup; publish->msgId = pub->msgId; publish->payload = pub->data; publish->payloadlen = pub->dataLen; publish->topic = expandedPreDefinedTopicName; rc = Protocol_handlePublishes(publish, sock, client, client ? client->clientID : clientAddr, pub->topicId); } } if (client != NULL) time( &(client->lastContact) ); MQTTSPacket_free_packet(pack); FUNC_EXIT_RC(rc); return rc; }