int send__real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup) { struct mosquitto__packet *packet = NULL; int packetlen; int rc; assert(mosq); assert(topic); packetlen = 2+strlen(topic) + payloadlen; if(qos > 0) packetlen += 2; /* For message id */ packet = mosquitto__calloc(1, sizeof(struct mosquitto__packet)); if(!packet) return MOSQ_ERR_NOMEM; packet->mid = mid; packet->command = PUBLISH | ((dup&0x1)<<3) | (qos<<1) | retain; packet->remaining_length = packetlen; rc = packet__alloc(packet); if(rc){ mosquitto__free(packet); return rc; } /* Variable header (topic string) */ packet__write_string(packet, topic, strlen(topic)); if(qos > 0){ packet__write_uint16(packet, mid); } /* Payload */ if(payloadlen){ packet__write_bytes(packet, payload, payloadlen); } return packet__queue(mosq, packet); }
/* This tests writing a UTF-8 String to an incoming packet. */ static void TEST_string_write(void) { uint8_t payload[100]; struct mosquitto__packet packet; memset(&packet, 0, sizeof(struct mosquitto__packet)); memset(payload, 0, 100); packet.payload = payload; packet.packet_length = 100; packet__write_string(&packet, "first test", strlen("first test")); packet__write_string(&packet, "second test", strlen("second test")); CU_ASSERT_EQUAL(packet.pos, 2+10+2+11); CU_ASSERT_EQUAL(payload[0], 0); CU_ASSERT_EQUAL(payload[1], 10); CU_ASSERT_NSTRING_EQUAL(payload+2, "first test", 10); CU_ASSERT_EQUAL(payload[2+10+0], 0); CU_ASSERT_EQUAL(payload[2+10+1], 11); CU_ASSERT_NSTRING_EQUAL(payload+2+10+2, "second test", 11); }
int send__unsubscribe(struct mosquitto *mosq, int *mid, int topic_count, char *const *const topic, const mosquitto_property *properties) { /* FIXME - only deals with a single topic */ struct mosquitto__packet *packet = NULL; uint32_t packetlen; uint16_t local_mid; int rc; int proplen, varbytes; int i; assert(mosq); assert(topic); packet = mosquitto__calloc(1, sizeof(struct mosquitto__packet)); if(!packet) return MOSQ_ERR_NOMEM; packetlen = 2; for(i=0; i<topic_count; i++){ packetlen += 2+strlen(topic[i]); } if(mosq->protocol == mosq_p_mqtt5){ proplen = property__get_length_all(properties); varbytes = packet__varint_bytes(proplen); packetlen += proplen + varbytes; } packet->command = CMD_UNSUBSCRIBE | (1<<1); packet->remaining_length = packetlen; rc = packet__alloc(packet); if(rc){ mosquitto__free(packet); return rc; } /* Variable header */ local_mid = mosquitto__mid_generate(mosq); if(mid) *mid = (int)local_mid; packet__write_uint16(packet, local_mid); if(mosq->protocol == mosq_p_mqtt5){ /* We don't use User Property yet. */ property__write_all(packet, properties, true); } /* Payload */ for(i=0; i<topic_count; i++){ packet__write_string(packet, topic[i], strlen(topic[i])); } #ifdef WITH_BROKER # ifdef WITH_BRIDGE for(i=0; i<topic_count; i++){ log__printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic[i]); } # endif #else for(i=0; i<topic_count; i++){ log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic[i]); } #endif return packet__queue(mosq, packet); }