int MQTTPublish(Client* c, const char* topicName, MQTTMessage* message)
{
    int rc = FAILURE;
    Timer timer; 
    MQTTString topic = MQTTString_initializer;
    topic.cstring = (char *)topicName;
    int len = 0;
	
    InitTimer(&timer); 
    countdown_ms(&timer, c->command_timeout_ms);
    
    if (!c->isconnected)
        goto exit;

    if (message->qos == QOS1 || message->qos == QOS2)
        message->id = getNextPacketId(c);
    
    len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id, 
              topic, (unsigned char*)message->payload, message->payloadlen);
    if (len <= 0)
        goto exit;
    if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the publish packet
        goto exit; // there was a problem
    
    if (message->qos == QOS1)
    {
        if (waitfor(c, PUBACK, &timer) == PUBACK)
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
                rc = FAILURE;
        }
        else
            rc = FAILURE;
    }
    else if (message->qos == QOS2)
    {
        if (waitfor(c, PUBCOMP, &timer) == PUBCOMP)
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
                rc = FAILURE;
        }
        else
            rc = FAILURE;
    }
    
exit:

    DeInitTimer(&timer); //STM: added this line
    return rc;
}
int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message)
{
	int rc = FAILURE;
	Timer timer;
	MQTTString topic = MQTTString_initializer;
	topic.cstring = (char *)topicName;
	int len = 0;

#if defined(MQTT_TASK)
	FreeRTOS_MutexLock(&c->mutex);
#endif
	if (!c->isconnected)
		goto exit;

	TimerInit(&timer);
	TimerCountdownMS(&timer, c->command_timeout_ms);

	if (message->qos == QOS1 || message->qos == QOS2)
		message->id = getNextPacketId(c);

	len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id,
	                            topic, (unsigned char*)message->payload, message->payloadlen);
	if (len <= 0)
		goto exit;
	if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
		goto exit; // there was a problem

	if (message->qos == QOS1) {
		if (waitfor(c, PUBACK, &timer) == PUBACK) {
			unsigned short mypacketid;
			unsigned char dup, type;
			if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
				rc = FAILURE;
		} else
			rc = FAILURE;
	} else if (message->qos == QOS2) {
		if (waitfor(c, PUBCOMP, &timer) == PUBCOMP) {
			unsigned short mypacketid;
			unsigned char dup, type;
			if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
				rc = FAILURE;
		} else
			rc = FAILURE;
	}

exit:
#if defined(MQTT_TASK)
	FreeRTOS_MutexUnlock(&c->mutex);
#endif
	return rc;
}
int mqtt_publish(mqtt_client_t *c, char* topicstr, mqtt_msg_t *msg)
{
    int rc = -1;
    MQTTString topic = MQTTString_initializer;
    int len;
    int pktype;

    topic.cstring = topicstr;

    len = MQTTSerialize_publish(c->wbuf, c->wbuflen,
                                                   msg->dup, msg->qos, msg->retained, msg->id,
                                                   topic, msg->payload, msg->payloadlen);
    if (len <= 0)
        goto exit;

    if ((rc = mqtt_write(c->sockfd, c->wbuf, len)) <= 0)
        goto exit;

    pktype = MQTTPacket_read(c->rbuf, c->rbuflen, c->getfn);

    if (msg->qos == 1)
    {
        if (pktype == PUBACK)
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->rbuf, c->rbuflen) != 1)
                rc = -1;
        }
        else
            rc = -1;
    }
    else if (msg->qos == 2)
    {
        if (pktype == PUBCOMP)
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->rbuf, c->rbuflen) != 1)
                rc = -1;
        }
        else
            rc = -1;
    }

exit:
    return rc;
}
Example #4
0
static int mqttClient_processPubAck(mqttClient_t* clientData)
{
  int32_t rc = LE_OK;
  uint16_t packetId;
  uint8_t dup;
  uint8_t type;

  LE_DEBUG("---> UNSUBACK");
  LE_ASSERT(clientData);

  rc = le_timer_Stop(clientData->session.cmdTimer);
  if (rc)
  {
    LE_ERROR("le_timer_Stop() failed(%d)", rc);
    goto cleanup;
  }

  rc = MQTTDeserialize_ack(&type, &dup, &packetId, clientData->session.rx.buf, sizeof(clientData->session.rx.buf));
  if (rc != 1)
  {
    LE_ERROR("MQTTDeserialize_ack() failed");
    rc = LE_BAD_PARAMETER;
    goto cleanup;
  }
  else if (clientData->session.nextPacketId != packetId)
  {
    LE_ERROR("invalid packet ID(%u != %u)", clientData->session.nextPacketId, packetId);
    rc = LE_BAD_PARAMETER;
    goto cleanup;
  }

cleanup:
  return rc;
}
/**
  * Deserializes the supplied (wire) buffer into unsuback data
  * @param packetid returned integer - the MQTT packet identifier
  * @param buf the raw buffer data, of the correct length determined by the remaining length field
  * @param buflen the length in bytes of the data in the supplied buffer
  * @return error code.  1 is success, 0 is failure
  */
int ICACHE_FLASH_ATTR MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen)
{
	unsigned char type = 0;
	unsigned char dup = 0;
	int rc = 0;

	FUNC_ENTRY;
	rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);
	if (type == UNSUBACK)
		rc = 1;
	FUNC_EXIT_RC(rc);
	return rc;
}
Example #6
0
static int mqttClient_processPubRec(mqttClient_t* clientData)
{
  int32_t rc = LE_OK;
  uint16_t packetId;
  uint8_t dup;
  uint8_t type;

  LE_DEBUG("---> PUBREC");
  LE_ASSERT(clientData);

  if (MQTTDeserialize_ack(&type, &dup, &packetId, clientData->session.rx.buf, sizeof(clientData->session.rx.buf)) != 1)
  {
    LE_ERROR("MQTTDeserialize_ack() failed");
    rc = LE_BAD_PARAMETER;
    goto cleanup;
  }
  else if (clientData->session.nextPacketId != packetId)
  {
    LE_ERROR("invalid packet ID(%u != %u)", clientData->session.nextPacketId, packetId);
    rc = LE_BAD_PARAMETER;
    goto cleanup;
  }

  int len = MQTTSerialize_ack(clientData->session.tx.buf, sizeof(clientData->session.tx.buf), PUBREL, 0, packetId);
  if (len <= 0)
  {
    LE_ERROR("MQTTSerialize_ack() failed(%d)", len);
    rc = LE_BAD_PARAMETER;
    goto cleanup;
  }

  LE_DEBUG("<--- PUBREL");
  rc = mqttClient_write(clientData, len);
  if (rc) 
  {
    LE_ERROR("mqttClient_write() failed(%d)", rc);
    goto cleanup;
  }

cleanup:
  return rc;
}
Example #7
0
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
	int index = 0;
	int rem_length = 0;
	MQTTHeader header = {0};
	int strindex = 0;

	header.byte = buf[index++];
	index += MQTTPacket_decodeBuf(&buf[index], &rem_length);

	switch (header.bits.type)
	{
	case CONNECT:
	{
		MQTTPacket_connectData data;
		int rc;
		if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)
			strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);
	}
	break;
	case PUBLISH:
	{
		unsigned char dup, retained, *payload;
		uint64_t packetid;
		int qos, payloadlen;
		MQTTString topicName = MQTTString_initializer;
		if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
				&payload, &payloadlen, buf, buflen) == 1)
			strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
					topicName, payload, payloadlen);
	}
	break;
	case PUBACK:
	case PUBREC:
	case PUBREL:
	case PUBCOMP:
	{
		unsigned char packettype, dup;
		uint64_t packetid;
		if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
			strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
	}
	break;
	case SUBSCRIBE:
	{
		unsigned char dup;
		uint64_t packetid;
		int maxcount = 1, count = 0;
		MQTTString topicFilters[1];
		int requestedQoSs[1];
		if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
				topicFilters, requestedQoSs, buf, buflen) == 1)
			strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
	}
	break;
	case UNSUBSCRIBE:
	{
		unsigned char dup;
		uint64_t packetid;
		int maxcount = 1, count = 0;
		MQTTString topicFilters[1];
		if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
			strindex =  MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
	}
	break;
	case PINGREQ:
	case PINGRESP:
	case DISCONNECT:
		strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
		break;
	}
	strbuf[strbuflen] = '\0';
	return strbuf;
}
Example #8
0
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
	int index = 0;
	int rem_length = 0;
	MQTTHeader header = {0};
	int strindex = 0;

	header.byte = buf[index++];
	index += MQTTPacket_decodeBuf(&buf[index], &rem_length);

	switch (header.bits.type)
	{
	case CONNACK:
	{
		unsigned char sessionPresent, connack_rc;
		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
			strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
	}
	break;
	case PUBLISH:
	{
		unsigned char dup, retained, *payload;
		uint64_t packetid;
		int qos, payloadlen;
		MQTTString topicName = MQTTString_initializer;
		if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
				&payload, &payloadlen, buf, buflen) == 1)
			strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
					topicName, payload, payloadlen);
	}
	break;
	case PUBACK:
	case PUBREC:
	case PUBREL:
	case PUBCOMP:
	{
		unsigned char packettype, dup;
		uint64_t packetid;
		if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
			strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
	}
	break;
	case SUBACK:
	{
		uint64_t packetid;
		int maxcount = 1, count = 0;
		int grantedQoSs[1];
		if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
			strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
	}
	break;
	case UNSUBACK:
	{
		uint64_t packetid;
		if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
			strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
	}
	break;
	case PINGREQ:
	case PINGRESP:
	case DISCONNECT:
		strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
		break;
	}
	return strbuf;
}
int cycle(Client* c, Timer* timer)
{
    // read the socket, see what work is due
    unsigned short packet_type = readPacket(c, timer);
    
    int len = 0,
        rc = SUCCESS;

    switch (packet_type)
    {
        case CONNACK:
        case PUBACK:
        case SUBACK:
            break;
        case PUBLISH:
        {
            MQTTString topicName;
            MQTTMessage msg;
            if (MQTTDeserialize_publish((unsigned char*)&msg.dup, (int*)&msg.qos, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName,
               (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
                goto exit;
            deliverMessage(c, &topicName, &msg);
            if (msg.qos != QOS0)
            {
                if (msg.qos == QOS1)
                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
                else if (msg.qos == QOS2)
                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
                if (len <= 0)
                    rc = FAILURE;
                   else
                       rc = sendPacket(c, len, timer);
                if (rc == FAILURE)
                    goto exit; // there was a problem
            }
            break;
        }
        case PUBREC:
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
                rc = FAILURE;
            else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
                rc = FAILURE;
            else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet
                rc = FAILURE; // there was a problem
            if (rc == FAILURE)
                goto exit; // there was a problem
            break;
        }
        case PUBCOMP:
            break;
        case PINGRESP:
				{
						INFO("<--PINGRESP");
						c->ping_outstanding = 0;
						countdown(&c->ping_timer, c->keepAliveInterval);
            break;
				}
    }
    rc = keepalive(c);
exit:
    if (rc == SUCCESS)
        rc = packet_type;
    return rc;
}
Example #10
0
int cycle(MQTTClient *c, Timer *timer)
{
    int len = 0,
        rc = SUCCESS;

    int packet_type = readPacket(c, timer);     /* read the socket, see what work is due */

    switch (packet_type) {
    default:
        /* no more data to read, unrecoverable. Or read packet fails due to unexpected network error */
        rc = packet_type;
        goto exit;

    case 0: /* timed out reading packet */
        break;

    case CONNACK:
    case PUBACK:
    case SUBACK:
    case UNSUBACK:
        break;

    case PUBLISH: {
        MQTTString topicName;
        MQTTMessage msg;
        int intQoS;
        msg.payloadlen = 0; /* this is a size_t, but deserialize publish sets this as int */

        if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
                                    (unsigned char **)&msg.payload, (int *)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1) {
            goto exit;
        }

        msg.qos = (enum QoS)intQoS;
        deliverMessage(c, &topicName, &msg);

        if (msg.qos != QOS0) {
            if (msg.qos == QOS1) {
                len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
            } else if (msg.qos == QOS2) {
                len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
            }

            if (len <= 0) {
                rc = FAILURE;
            } else {
                rc = sendPacket(c, len, timer);
            }

            if (rc == FAILURE) {
                goto exit;    // there was a problem
            }
        }

        break;
    }

    case PUBREC:
    case PUBREL: {
        unsigned short mypacketid;
        unsigned char dup, type;

        if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) {
            rc = FAILURE;
        } else if ((len = MQTTSerialize_ack(c->buf, c->buf_size,
                                            (packet_type == PUBREC) ? PUBREL : PUBCOMP, 0, mypacketid)) <= 0) {
            rc = FAILURE;
        } else if ((rc = sendPacket(c, len, timer)) != SUCCESS) { // send the PUBREL packet
            rc = FAILURE;    // there was a problem
        }

        if (rc == FAILURE) {
            goto exit;    // there was a problem
        }

        break;
    }

    case PUBCOMP:
        break;

    case PINGRESP:
        c->ping_outstanding = 0;
        break;
    }

    if (keepalive(c) != SUCCESS) {
        //check only keepalive FAILURE status so that previous FAILURE status can be considered as FAULT
        rc = FAILURE;
    }

exit:

    if (rc == SUCCESS) {
        rc = packet_type;
    } else if (c->isconnected) {
        MQTTCloseSession(c);
    }

    return rc;
}
Example #11
0
int cycle( Client* c, Timer* timer )
{
    // read the socket, see what work is due
    unsigned short packet_type = readPacket( c, timer );
    int len = 0;
    int rc = MQTT_SUCCESS;

    WPRINT_APP_INFO( ("Packet Type %d\n", packet_type) );

    switch ( packet_type )
    {
        case CONNACK:
        case PUBACK:
        case SUBACK:
            break;
        case PUBLISH:
        {
            MQTTString topicName;
            MQTTMessage msg;

            if ( MQTTDeserialize_publish( (unsigned char*) &msg.dup, (int*) &msg.qos, (unsigned char*) &msg.retained, (unsigned short*) &msg.id, &topicName, (unsigned char**) &msg.payload, (int*) &msg.payloadlen, c->readbuf, c->readbuf_size ) != 1 )
            {
                goto exit;
            }

            deliverMessage( c, &topicName, &msg );
            if ( msg.qos != QOS0 )
            {
                if ( msg.qos == QOS1 )
                {
                    len = MQTTSerialize_ack( c->buf, c->buf_size, PUBACK, 0, msg.id );
                }
                else if ( msg.qos == QOS2 )
                {
                    len = MQTTSerialize_ack( c->buf, c->buf_size, PUBREC, 0, msg.id );
                }
                if ( len <= 0 )
                {
                    rc = MQTT_FAILURE;
                }
                else
                {
                    rc = sendPacket( c, len, timer );
                }

                if ( rc == MQTT_FAILURE )
                {
                    goto exit;
                    // there was a problem
                }
            }
            break;
        }
        case PUBREC:
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if ( MQTTDeserialize_ack( &type, &dup, &mypacketid, c->readbuf, c->readbuf_size ) != 1 )
            {
                rc = MQTT_FAILURE;
            }
            else if ( ( len = MQTTSerialize_ack( c->buf, c->buf_size, PUBREL, 0, mypacketid ) ) <= 0 )
            {
                rc = MQTT_FAILURE;
            }
            else if ( ( rc = sendPacket( c, len, timer ) ) != MQTT_SUCCESS ) // send the PUBREL packet
            {
                rc = MQTT_FAILURE; // there was a problem
            }

            if ( rc == MQTT_FAILURE )
            {
                goto exit;
                // there was a problem
            }

            break;
        }
        case PUBCOMP:
            break;
        case PINGRESP:
            c->ping_outstanding = 0;
            break;
    }

    keepalive( c );

    exit: if ( rc == MQTT_SUCCESS )
    {
        rc = packet_type;
    }

    return rc;
}
Example #12
0
int cycle(Client* c, Timer* timer)
{
    // read the socket, see what work is due
    int read_status;
    unsigned short packet_type;
    read_status = readPacket(c, timer);
    packet_type = (unsigned short )read_status;

    if(read_status == SOCKET_CLOSED)
    {
    	MQTTReConnect(c);
    	goto exit;
    }
    int len = 0,
        rc = SUCCESS;
    switch (packet_type)
    {
        case CONNACK:
        {
			{
				unsigned char connack_rc = 255;
				char sessionPresent = 0;
				if (MQTTDeserialize_connack((unsigned char*)&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1)
				{
					c->isconnected = 1;
					//开cloud灯
					system(SET_LIGHT_CLOUD);

					log_printf(LOG_NOTICE, "[MqttConnected]: recv connack\n");
					//subtopics and pubtopics init
					sprintf(&subtopics[0][0], "%s%s", SUBTOPIC_PRE1, gateway_info.did);
					sprintf(&subtopics[1][0], "%s%s", SUBTOPIC_PRE2, gateway_info.productkey);
					sprintf(&subtopics[2][0], "%s%s/#", SUBTOPIC_PRE3, gateway_info.did);

					sprintf(&pubtopics[0][0], "%s%s", PUBTOPIC_PRE1, gateway_info.did);
					sprintf(&pubtopics[1][0], "%s%s", PUBTOPIC_PRE2, gateway_info.did);
					sprintf(&pubtopics[2][0], "%s%s/#", PUBTOPIC_PRE3, gateway_info.did);

					rc = MQTTSubscribe(c, subtopics[c->suborder], 0, mh[c->suborder]); //for test
					log_printf(LOG_NOTICE, "Subscribing to %s\n", subtopics[c->suborder]);
					c->suborder++;
				}
			}
        }
        	break;
        case PUBACK:
        	break;
        case SUBACK:
        {
			int count = 0, grantedQoS = -1;
			unsigned short mypacketid;
			if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1)
				rc = grantedQoS; // 0, 1, 2 or 0x80
			if (rc != 0x80)
			{
				if(c->suborder <subscribe_over)
				{
					rc = MQTTSubscribe(c, subtopics[c->suborder], 0, mh[c->suborder]);
					log_printf(LOG_NOTICE, "Subscribing to %s\n",subtopics[c->suborder]);
					c->suborder++;
				}

//				int i;
//				for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
//				{
//					if (c->messageHandlers[i].topicFilter == 0)
//					{
//						c->messageHandlers[i].topicFilter = mytopics[i];
//						c->messageHandlers[i].fp = mh[i];
//						rc = 0;
//						break;
//					}
//				}
			}
			else
			{
				log_printf(LOG_ERROR, "SUCACK FAILED\n");
				//TODO: error handle
			}
        }
        	break;
        case PUBLISH:
        {
            if(c->suborder != subscribe_over)
            {
            	log_printf(LOG_ERROR, "[REC_MSG] rece publish msg but subcribe not over\n");
            	//TODO: error
            }
            MQTTString topicName = MQTTString_initializer;
            MQTTMessage msg;
            if (MQTTDeserialize_publish((unsigned char*)&msg.dup, (int*)&msg.qos, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName,
               (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
                goto exit;
            deliverMessage(c, &topicName, &msg);
//            MQTTPublish(c, "applerespond", &msg); //add by yaly for test
            if (msg.qos != QOS0)
            {
                if (msg.qos == QOS1)
                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
                else if (msg.qos == QOS2)
                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
                if (len <= 0)
                    rc = FAILURE;
                   else
                       rc = sendPacket_ev(c, len);
                if (rc == FAILURE)
                    goto exit;
            }
        }
        	break;
        case PUBREC:
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
                rc = FAILURE;
            else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
                rc = FAILURE;
            else if ((rc = sendPacket_ev(c, len)) != SUCCESS) // send the PUBREL packet
                rc = FAILURE;
            if (rc == FAILURE)
                goto exit;
            break;
        }
        break;
        case PUBCOMP:
            break;
        case PINGRESP:
        	log_printf(LOG_NOTICE, "[MqttPingResp]\n");
            c->ping_outstanding = 0;
            break;
    }
//    keepalive(c); //modify by yanly
exit:
    if (rc == SUCCESS)
        rc = packet_type;
    return rc;
}
/*


	success -> 
  		return packet type
  	fail->
		return FAIL

*/
int cycle(MQTTClient* c, Timer* timer)
{
	int packet_type = readPacket(c, timer);
	int len = 0;
	int rc = SUCCESS;

	if (FAILURE == packet_type) {
		packet_type = NOPACKET;
		goto exit;
	}
	printf("received %s\n", MQTTPacket_names[packet_type]);

	switch (packet_type)
	{
		case CONNACK:
		case PUBACK:
		case SUBACK:
			break;
		case PUBLISH:
		{
			MQTTString topicName;
			MQTTMessage msg;
			int intQoS;
			if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
					(unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
				goto exit;

			msg.qos = (enum QoS)intQoS;
			//deliverMessage(c, &topicName, &msg);

			if (msg.qos != QOS0) {
				if (msg.qos == QOS1)
					len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
				else if (msg.qos == QOS2)
					len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);

				if (len <= 0)
					rc = FAILURE;
				else
					rc = sendPacket(c, len, timer);

				if (rc == FAILURE)
					goto exit; // there was a problem
			}
			deliverMessage(c, &topicName, &msg);

			break;
		}
		case PUBREC:
		{
			unsigned short mypacketid;
			unsigned char dup, type;
			if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
				rc = FAILURE;
			else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
				rc = FAILURE;
			else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet
				rc = FAILURE; // there was a problem
			if (rc == FAILURE)
				goto exit; // there was a problem
			break;
		}
		case PUBCOMP:
			break;
		case PINGRESP:
			c->ping_outstanding = 0;
			//c->keepAliveFailCount = 0;
			break;
		case PUBREL:
		{
			unsigned short mypacketid;
			unsigned char dup, type;
			if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
				rc = FAILURE;
			else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBCOMP, 0, mypacketid)) <= 0)
				rc = FAILURE;
			else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBCOMP packet
				rc = FAILURE; // there was a problem
			if (rc == FAILURE)
				goto exit; // there was a problem
			break;
		}
	}

exit:

	if (FAILURE == keepalive(c)) {
		rc = FAILURE;
	}

	if (rc == SUCCESS)
		rc = packet_type;

	return rc;
}
Example #14
0
int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message)
{
    int rc = MQTT_FAILURE;
    Timer timer;   
    MQTTString topic = MQTTString_initializer;
    topic.cstring = (char *)topicName;
    int len = 0;

	platform_mutex_lock(&c->mutex);
	if (!c->isconnected)
		goto exit;

    platform_timer_init(&timer);
    platform_timer_countdown(&timer, c->command_timeout_ms);

    if (message->qos == QOS1 || message->qos == QOS2)
        message->id = getNextPacketId(c);
    
    len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id, 
              topic, (unsigned char*)message->payload, message->payloadlen);
    if (len <= 0)
        goto exit;
    if ((rc = sendPacket(c, len, &timer)) != MQTT_SUCCESS) // send the subscribe packet
    {
        goto exit; // there was a problem
    }

    if (message->qos == QOS1)
    {
        if (waitfor(c, PUBACK, &timer) == PUBACK)
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
            {
                platform_printf("failed to deserialize ACK\n");
                rc = MQTT_FAILURE;
            }
        }
        else
        {
            rc = MQTT_CONNECTION_LOST;
        }
    }
    else if (message->qos == QOS2)
    {
        if (waitfor(c, PUBCOMP, &timer) == PUBCOMP)
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
                rc = MQTT_FAILURE;
        }
        else 
        {
            rc = MQTT_CONNECTION_LOST;
		}
    }
    
exit:
	platform_mutex_unlock(&c->mutex);
    return rc;
}
Example #15
0
int cycle(MQTTClient* c, Timer* timer)
{
    Timer t;
    platform_timer_init(&t);

    int len = 0, packet_type, rc = MQTT_SUCCESS;

    // read the socket, see what work is due
    if ((packet_type = readPacket(c, timer)) == MQTT_CONNECTION_LOST)
	{
		rc = MQTT_CONNECTION_LOST;
		goto exit;
	}
    
    switch (packet_type)
    {
        case CONNACK:
        case PUBACK:
        case SUBACK:
            break;
        case PUBLISH:
        {
            MQTTString topicName;
            MQTTMessage msg = {0};
            int intQoS;
            if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
               (unsigned char**)&msg.payload, &msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
                goto exit;
            msg.qos = (enum QoS)intQoS;
            deliverMessage(c, &topicName, &msg);
            if (msg.qos != QOS0)
            {
                if (msg.qos == QOS1)
                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
                else if (msg.qos == QOS2)
                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
                if (len <= 0)
                    rc = MQTT_FAILURE;
                else
                {
                    platform_timer_countdown(&t, c->command_timeout_ms);
                    rc = sendPacket(c, len, &t);
                }
                if (rc == MQTT_FAILURE)
                    goto exit; // there was a problem
            }
            break;
        }
        case PUBREC:
        {
            unsigned short mypacketid;
            unsigned char dup, type;
            platform_timer_countdown(&t, c->command_timeout_ms);
            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
                rc = MQTT_FAILURE;
            else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
                rc = MQTT_FAILURE;
            else if ((rc = sendPacket(c, len, &t)) != MQTT_SUCCESS) // send the PUBREL packet
                rc = MQTT_FAILURE; // there was a problem
            if (rc == MQTT_FAILURE)
                goto exit; // there was a problem
            break;
        }
        case PUBCOMP:
            break;
        case PINGRESP:
            c->ping_outstanding = 0;
            platform_printf("received ping response\n");
            break;
    }

    keepalive(c);

    if (c->ping_outstanding && platform_timer_isexpired(&c->pingresp_timer))
    {
        c->ping_outstanding = 0;
		platform_printf("ping response was not received within keepalive timeout of %d\n", 
                c->keepAliveInterval);
        rc = MQTT_CONNECTION_LOST;
    }

exit:
	if (rc == MQTT_SUCCESS)
		rc = packet_type;

	return rc;
}