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; }
/** * @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; }
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; }
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; }
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; }