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;
}
int mqtt_subscribe(mqtt_client_t *c, char* topicstr, int qos)
{
    MQTTString topic = MQTTString_initializer;
    int msgid = 1;
    int len;
    int rc = -1;

    topic.cstring = topicstr;
    len = MQTTSerialize_subscribe(c->wbuf, c->wbuflen, 0, msgid, 1, &topic, &qos);
    if (len <= 0)
        goto exit;

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

    if (MQTTPacket_read(c->rbuf, c->rbuflen, c->getfn) == SUBACK)
    {
        unsigned short submsgid;
        int subcount;
        int granted_qos;

        rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, c->rbuf, c->rbuflen);
        if (granted_qos != 0)
        {
            DEBUG("granted qos != 0, %d\n", granted_qos);
            rc = -1;
        }
        else
        {
            rc = 0;
        }
    }
    else
    {
        rc = -1;
    }

exit:
    return rc;
}
int mqtt_connect(mqtt_client_t *c, MQTTPacket_connectData *data)
{
    int rc = -1;
    int len;

    len = MQTTSerialize_connect(c->wbuf, c->wbuflen, data);
    if (len <= 0)
        goto exit;

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

    rc = MQTTPacket_read(c->rbuf, c->rbuflen, c->getfn);
    if (rc < 0)
        goto exit;

    if (rc == CONNACK)
    {
        unsigned char sessionPresent, connack_rc;

        if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->rbuf, c->rbuflen) == 1)
        {
            rc = connack_rc;
        }
        else
        {
            rc = -1;
        }
    }
    else
        rc = -1;

exit:
    return rc;
}
示例#4
0
文件: MQTT.c 项目: Zhang-Jia/WiFiMCU
/**
  * @brief  向服务器订阅一个消息,该函数会因为TCP接收数据函数而阻塞
  * @param  pTopic 消息主题,传入
  * @param  pMessage 消息内容,传出
  * @retval 小于0表示订阅消息失败
  */
int mqtt_subscrib(char *pTopic,char *pMessage)
{
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	int rc = 0;
	unsigned char buf[200];
	int buflen = sizeof(buf);
	int msgid = 1;
	MQTTString topicString = MQTTString_initializer;
	int req_qos = 0;

	int len = 0;
	rc = transport_open();
	if(rc < 0){
    printf("transport_open error\n\r");
		return rc;
  }

	data.clientID.cstring = "";
	data.keepAliveInterval = 5;//服务器保持连接时间,超过该时间后,服务器会主动断开连接,单位为秒
	data.cleansession = 1;
	data.username.cstring = "";
	data.password.cstring = "";

	len = MQTTSerialize_connect(buf, buflen, &data);
	rc = transport_sendPacketBuffer(buf, len);
  if(rc != len){
    printf("connect transport_sendPacketBuffer error\n\r");
    goto exit;
  }
	/* wait for connack */
	if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK)
	{
		unsigned char sessionPresent, connack_rc;

		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
		{
			printf("Unable to connect, return code %d\n\r", connack_rc);
			goto exit;
		}
	}else{
    printf("MQTTPacket_read error\n\r");
		goto exit;
  }

	/* subscribe */
	topicString.cstring = pTopic;
	len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);

	rc = transport_sendPacketBuffer(buf, len);
  if(rc != len){
    printf("connect transport_sendPacketBuffer error\n\r");
    goto exit;
  }
	if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) 	/* wait for suback */
	{
		unsigned short submsgid;
		int subcount;
		int granted_qos;

		rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
		if (granted_qos != 0)
		{
			printf("granted qos != 0, %d\n\r", granted_qos);
			goto exit;
		}
	}
	else
		goto exit;

	/* loop getting msgs on subscribed topic */
	topicString.cstring = pTopic;
  memset(buf,0,buflen);
  //transport_getdata接收数据会阻塞,除非服务器断开连接后才返回
  if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH){
    unsigned char dup;
    int qos;
    unsigned char retained;
    unsigned short msgid;
    int payloadlen_in;
    unsigned char* payload_in;
    MQTTString receivedTopic;

    rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
        &payload_in, &payloadlen_in, buf, buflen);
    printf("message arrived %d: %s\n\r", payloadlen_in, payload_in);
    strcpy(pMessage,(const char *)payload_in);
  }
  printf("disconnecting\n\r");
  len = MQTTSerialize_disconnect(buf, buflen);
  rc = transport_sendPacketBuffer(buf, len);
exit:
	transport_close();
  return rc;
}
示例#5
0
int main()
{
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	int rc = 0;
	char buf[200];
	int buflen = sizeof(buf);
	int msgid = 1;
	MQTTString topicString = MQTTString_initializer;
	int req_qos = 0;
	char* payload = "mypayload";
	int payloadlen = strlen(payload);
	int len = 0;

	signal(SIGINT, cfinish);
	signal(SIGTERM, cfinish);

	rc = Socket_new("127.0.0.1", 1883, &mysock);

	data.clientID.cstring = "me";
	data.keepAliveInterval = 20;
	data.cleansession = 1;
	data.username.cstring = "testuser";
	data.password.cstring = "testpassword";

	struct timeval tv;
	tv.tv_sec = 1;  /* 1 second Timeout */
	tv.tv_usec = 0;  
	setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));

	len = MQTTSerialize_connect(buf, buflen, &data);
	rc = write(mysock, buf, len);

	/* wait for connack */
	if (MQTTPacket_read(buf, buflen, getdata) == CONNACK)
	{
		int connack_rc;

		if (MQTTDeserialize_connack(&connack_rc, buf, buflen) != 1 || connack_rc != 0)
		{
			printf("Unable to connect, return code %d\n", connack_rc);
			goto exit;
		}
	}
	else
		goto exit;

	/* subscribe */
	topicString.cstring = "substopic";
	len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);

	rc = write(mysock, buf, len);
	if (MQTTPacket_read(buf, buflen, getdata) == SUBACK) 	/* wait for suback */
	{
		int submsgid;
		int subcount;
		int granted_qos;

		rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
		if (granted_qos != 0)
		{
			printf("granted qos != 0, %d\n", granted_qos);
			goto exit;
		}
	}
	else
		goto exit;

	topicString.cstring = "pubtopic";
	while (!toStop)
	{
		if (MQTTPacket_read(buf, buflen, getdata) == PUBLISH)
		{
			int dup;
			int qos;
			int retained;
			int msgid;
			int payloadlen_in;
			char* payload_in;
			int rc;
			MQTTString receivedTopic;

			rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
					&payload_in, &payloadlen_in, buf, buflen);
			printf("message arrived %.*s\n", payloadlen_in, payload_in);
		}

		printf("publishing reading\n");
		len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, payload, payloadlen);
		rc = write(mysock, buf, len);
	}

	printf("disconnecting\n");
	len = MQTTSerialize_disconnect(buf, buflen);
	rc = write(mysock, buf, len);

exit:
	rc = shutdown(mysock, SHUT_WR);
	rc = recv(mysock, NULL, 0, 0);
	rc = close(mysock);

	return 0;
}
示例#6
0
int main(int argc, char *argv[])
{
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	int rc = 0;
	int mysock = 0;
	unsigned char buf[200];
	int buflen = sizeof(buf);
	int msgid = 1;
	MQTTString topicString = MQTTString_initializer;
	int req_qos = 0;
	char* payload = "mypayload";
	int payloadlen = strlen(payload);
	int len = 0;
	char *host = "m2m.eclipse.org";
	int port = 1883;
	MQTTTransport mytransport;

	stop_init();
	if (argc > 1)
		host = argv[1];

	if (argc > 2)
		port = atoi(argv[2]);

	mysock = transport_open(host, port);
	if(mysock < 0)
		return mysock;

	printf("Sending to hostname %s port %d\n", host, port);

	mytransport.sck = &mysock;
	mytransport.getfn = transport_getdatanb;
	mytransport.state = 0;
	data.clientID.cstring = "me";
	data.keepAliveInterval = 20;
	data.cleansession = 1;
	data.username.cstring = "testuser";
	data.password.cstring = "testpassword";

	len = MQTTSerialize_connect(buf, buflen, &data);
	rc = transport_sendPacketBuffer(mysock, buf, len);

	/* wait for connack */
	if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK)
	{
		unsigned char sessionPresent, connack_rc;

		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
		{
			printf("Unable to connect, return code %d\n", connack_rc);
			goto exit;
		}
	}
	else
		goto exit;

	/* subscribe */
	topicString.cstring = "substopic";
	len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);

	rc = transport_sendPacketBuffer(mysock, buf, len);
	do {
		int frc;
		if ((frc=MQTTPacket_readnb(buf, buflen, &mytransport)) == SUBACK) /* wait for suback */
		{
			unsigned short submsgid;
			int subcount;
			int granted_qos;

			rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
			if (granted_qos != 0)
			{
				printf("granted qos != 0, %d\n", granted_qos);
				goto exit;
			}
			break;
		}
		else if (frc == -1)
			goto exit;
	} while (1); /* handle timeouts here */
	/* loop getting msgs on subscribed topic */
	topicString.cstring = "pubtopic";
	while (!toStop)
	{
		/* handle timeouts */
		if (MQTTPacket_readnb(buf, buflen, &mytransport) == PUBLISH)
		{
			unsigned char dup;
			int qos;
			unsigned char retained;
			unsigned short msgid;
			int payloadlen_in;
			unsigned char* payload_in;
			int rc;
			MQTTString receivedTopic;

			rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
					&payload_in, &payloadlen_in, buf, buflen);
			printf("message arrived %.*s\n", payloadlen_in, payload_in);
			printf("publishing reading\n");
			len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen);
			rc = transport_sendPacketBuffer(mysock, buf, len);
		}
	}

	printf("disconnecting\n");
	len = MQTTSerialize_disconnect(buf, buflen);
	rc = transport_sendPacketBuffer(mysock, buf, len);

exit:
	transport_close(mysock);

	return 0;
}
static void *mqtt_sub_thread(void *param)
{
    MQTTPacket_connectData condata = MQTTPacket_connectData_initializer;
    int pktype, rc, len;
    int failcnt = 0;
    unsigned char wbuf[64];
    unsigned char rbuf[64];

    DEBUG("sub thread start\n");

    _csub.wbuf = wbuf;
    _csub.wbuflen = sizeof(wbuf);
    _csub.rbuf = rbuf;
    _csub.rbuflen = sizeof(rbuf);
    _csub.getfn = sub_read;

    if ((_csub.sockfd = mqtt_netconnect(HOSTNAME, HOSTPORT)) < 0)
    {
        DEBUG("sub netconnect fail\n");

        return 0;
    }

    DEBUG("sub connect to: %s %d\n", HOSTNAME, HOSTPORT);

    condata.clientID.cstring = "mqttsub";
    condata.keepAliveInterval = KEEPALIVE_INTERVAL;
    condata.cleansession = 1;
    condata.username.cstring = USERNAME;
    condata.password.cstring = PASSWORD;

    rc = mqtt_connect(&_csub, &condata);
    if (rc < 0)
        goto exit;

    DEBUG("sub connect ok\n");

    rc = mqtt_subscribe(&_csub, TOPIC, 0);
    if (rc < 0)
        goto exit;

    DEBUG("sub topic: %s\n", TOPIC);

    mqtt_ping_start(&_csub.sockfd);

    while (1)
    {
        pktype = MQTTPacket_read(_csub.rbuf, _csub.rbuflen, sub_read);

        switch (pktype)
        {
        case CONNACK:
        case PUBACK:
        case SUBACK:
            break;
        case PUBLISH:
        {
            MQTTString topic;
            mqtt_msg_t msg;

            if (MQTTDeserialize_publish(&msg.dup, &msg.qos, &msg.retained, &msg.id, &topic,
                                                         &msg.payload, &msg.payloadlen, _csub.rbuf, _csub.rbuflen) != 1)
                goto exit;

            msgprocess(&topic, &msg);

            if (msg.qos != 0)
            {
                if (msg.qos == 1)
                    len = MQTTSerialize_ack(_csub.wbuf, _csub.wbuflen, PUBACK, 0, msg.id);
                else if (msg.qos == 2)
                    len = MQTTSerialize_ack(_csub.wbuf, _csub.wbuflen, PUBREC, 0, msg.id);

                if (len <= 0)
                    rc = -1;
                else
                    rc = mqtt_write(_csub.sockfd, _csub.wbuf, len);

                if (rc == -1)
                    goto exit;
            }
        }
        break;
        case PUBCOMP:
            break;
        case PINGRESP:
            failcnt = 0;
            break;
        case -1:
            if (++failcnt > KEEPALIVE_INTERVAL)
            {
                /*  */
                goto exit;
            }
            break;
        }
    }
    /*  */
    mqtt_disconnect(&_csub);

exit:
    mqtt_netdisconnect(&_csub.sockfd);
    DEBUG("sub thread exit\n");

    return 0;
}
示例#8
0
static void mqttClient_socketFdEventHandler(int sockFd, short events)
{
  mqttClient_t* clientData = le_fdMonitor_GetContextPtr();
  int rc = LE_OK;

  LE_ASSERT(clientData);

  LE_DEBUG("events(0x%08x)", events);
  if (events & POLLOUT)
  {
    le_fdMonitor_Disable(clientData->session.sockFdMonitor, POLLOUT);

    if ((clientData->session.sock != MQTT_CLIENT_INVALID_SOCKET) && !clientData->session.isConnected)
    {
      LE_INFO("connected(%s:%d)", clientData->session.config.brokerUrl, clientData->session.config.portNumber);
      rc = le_timer_Stop(clientData->session.connTimer);
      if (rc)
      {
        LE_ERROR("le_timer_Stop() failed(%d)", rc);
        goto cleanup;
      }

      MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
      data.willFlag = 0;
      data.MQTTVersion = MQTT_CLIENT_MQTT_VERSION;

      LE_INFO("deviceId('%s'), pwd('%s')", clientData->deviceId, clientData->session.secret);
      if (strlen(clientData->deviceId) > 0)
      {
        data.clientID.cstring = clientData->deviceId;
        data.username.cstring = clientData->deviceId;
        data.password.cstring = clientData->session.secret;
      }

      data.keepAliveInterval = clientData->session.config.keepAlive;
      data.cleansession = 1;

      rc = mqttClient_sendConnect(clientData, &data);
      if (rc)
      {
        LE_ERROR("mqttClient_sendConnect() failed(%d)", rc);
        goto cleanup;
      }
    }
    else if (clientData->session.tx.bytesLeft)
    {
      rc = mqttClient_write(clientData, 0);
      if (rc)
      {
        LE_ERROR("mqttClient_write() failed(%d)", rc);
        goto cleanup;
      }
    }
  }
  else if (events & POLLIN)
  {
    uint16_t packetType = MQTTPacket_read(clientData->session.rx.buf, sizeof(clientData->session.rx.buf), mqttClient_read);    
    LE_DEBUG("packet type(%d)", packetType);
    switch (packetType)
    {
    case CONNACK:
      rc = mqttClient_processConnAck(clientData);
      if (rc)
      {
        LE_ERROR("mqttClient_processConnAck() failed(%d)", rc);
        goto cleanup;
      }

      break;

    case PUBACK:
      rc = mqttClient_processPubAck(clientData);
      if (rc)
      {
        LE_ERROR("mqttClient_processPubAck() failed(%d)", rc);
        goto cleanup;
      }

      break;

    case SUBACK:
      rc = mqttClient_processSubAck(clientData);
      if (rc)
      {
        LE_ERROR("mqttClient_processSubAck() failed(%d)", rc);
        goto cleanup;
      }

      break;

    case UNSUBACK:
      rc = mqttClient_processUnSubAck(clientData);
      if (rc)
      {
        LE_ERROR("mqttClient_processUnSubAck() failed(%d)", rc);
        goto cleanup;
      }

      break;

    case PUBLISH:
      rc = mqttClient_processPublish(clientData);
      if (rc)
      {
        LE_ERROR("mqttClient_processPublish() failed(%d)", rc);
        goto cleanup;
      }

      break;
    
    case PUBREC:
      rc = mqttClient_processPubRec(clientData);
      if (rc)
      {
        LE_ERROR("mqttClient_processPubRec() failed(%d)", rc);
        goto cleanup;
      }
  
      break;
    
    case PUBCOMP:
      rc = mqttClient_processPubComp(clientData);
      if (rc)
      {
        LE_ERROR("mqttClient_processPubComp() failed(%d)", rc);
        goto cleanup;
      }

      break;

    case PINGRESP:
      mqttClient_processPingResp(clientData);
      break;

    default:
      LE_ERROR("unknown packet type(%u)", packetType);
      break;
    }

    clientData->session.cmdRetries = 0;
  }

cleanup:
  return;
}