int MQTTSProtocol_handleSubscribes(void* pack, int sock, char* clientAddr, Clients* client) { int rc = 0; MQTTS_Subscribe* sub = (MQTTS_Subscribe*)pack; int isnew; int topicId = 0; char* topicName = NULL , *preDefinedTopicName = NULL; FUNC_ENTRY; Log(LOG_PROTOCOL, 67, NULL, sock, clientAddr, client ? client->clientID : "", sub->msgId, (sub->flags.QoS == 3) ? -1: sub->flags.QoS, sub->flags.topicIdType); // NORMAL (topic name is in subscribe packet) or SHORT topic name if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_NORMAL || sub->flags.topicIdType == MQTTS_TOPIC_TYPE_SHORT) { topicName = sub->topicName; sub->topicName = NULL; } // Pre-defined topic else if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_PREDEFINED && client != NULL && sub->topicId != 0) { char *name = MQTTSProtocol_getPreRegisteredTopicName(client, sub->topicId) ; if (name) { preDefinedTopicName = MQTTSProtocol_replaceTopicNamePlaceholders(client , name ) ; } topicName = preDefinedTopicName ; topicId = sub->topicId; } // If topic name not found send SubAck with Rejected - Invalid topic ID if (topicName == NULL) rc = MQTTSPacket_send_subAck(client, sub, 0, sub->flags.QoS, MQTTS_RC_REJECTED_INVALID_TOPIC_ID); else { if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_NORMAL && !Topics_hasWildcards(topicName)) { char* regTopicName = malloc(strlen(topicName)+1); strcpy(regTopicName, topicName); topicId = (MQTTSProtocol_registerTopic(client, regTopicName))->id; } isnew = SubscriptionEngines_subscribe(bstate->se, client->clientID, topicName, sub->flags.QoS, client->noLocal, (client->cleansession == 0), PRIORITY_NORMAL); if ( (rc = MQTTSPacket_send_subAck(client, sub, topicId, sub->flags.QoS, MQTTS_RC_ACCEPTED)) == 0) if ((client->noLocal == 0) || isnew) MQTTProtocol_processRetaineds(client, topicName,sub->flags.QoS, PRIORITY_NORMAL); } time( &(client->lastContact) ); MQTTSPacket_free_packet(pack); if (preDefinedTopicName) free (preDefinedTopicName); 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; }