static int MqttSample_HandleSocket(struct MqttSampleContext *ctx, uint32_t events) { struct epoll_event evt[1]; evt->data.fd = ctx->mqttfd; evt->events = EPOLLIN; if(events & EPOLLIN) { while(1) { int err; err = Mqtt_RecvPkt(ctx->mqttctx); if(MQTTERR_ENDOFFILE == err) { printf("The connection is disconnected.\n"); close(ctx->mqttfd); epoll_ctl(ctx->epfd, EPOLL_CTL_DEL, ctx->mqttfd, NULL); ctx->mqttfd = -1; return 0; } if(MQTTERR_IO == err) { if((EAGAIN == errno) || (EWOULDBLOCK == errno)) { break; } printf("Send TCP data error: %s.\n", strerror(errno)); return -1; } if(MQTTERR_NOERROR != err) { printf("Mqtt_RecvPkt error is %d.\n", err); return -1; } } } if(events & EPOLLOUT) { if(-1 != ctx->sendedbytes) { int bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, ctx->sendedbytes); if(bytes < 0) { return -1; } else { ctx->sendedbytes += bytes; if(ctx->sendedbytes == ctx->mqttbuf->buffered_bytes) { MqttBuffer_Reset(ctx->mqttbuf); ctx->sendedbytes = -1; } else { evt->events |= EPOLLOUT; } } } } epoll_ctl(ctx->epfd, EPOLL_CTL_MOD, ctx->mqttfd, evt); return 0; }
/** * @brief 设备主动断开MQTT连接 * @param ctx:上下文变量 * @retval ret:0,成功,<0 失败 **/ static int MqttSample_CmdDisconnect(struct MqttSampleContext *ctx) { int err; printf("%s %d\n", __func__, __LINE__); err = Mqtt_PackDisconnectPkt(ctx->mqttbuf); if(MQTTERR_NOERROR != err) { printf("Critical bug: failed to pack the disconnect packet.\n"); return -1; } Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 1; }
static int MqttSample_HandleStdin(struct MqttSampleContext *ctx, uint32_t events) { const int buf_size = 1024; int bytes, i, ret = 0; char buf[buf_size]; if(-1 != ctx->sendedbytes) { printf("There are something to be send, please wait a moment to retry.\n"); return 0; } bytes = read(STDIN_FILENO, buf, buf_size); buf[bytes - 1] = 0; for(i = 0; i < sizeof(commands) / sizeof(*commands); ++i) { if(strcmp(commands[i].cmd, buf) == 0) { if((ret = commands[i].func(ctx)) < 0) { return -1; } break; } } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); if(bytes < 0) { printf("Failed to send the packet to the server.\n"); return -1; } else if(bytes != ctx->mqttbuf->buffered_bytes) { struct epoll_event evt[1]; ctx->sendedbytes = bytes; printf("There are some data not sended(%d bytes).\n", ctx->mqttbuf->buffered_bytes - bytes); evt->data.fd = ctx->mqttfd; evt->events = EPOLLIN | EPOLLOUT | EPOLLONESHOT | EPOLLET; epoll_ctl(ctx->epfd, EPOLL_CTL_MOD, ctx->mqttfd, evt); return 0; } MqttBuffer_Reset(ctx->mqttbuf); if(ret > 0) { close(ctx->mqttfd); epoll_ctl(ctx->epfd, EPOLL_CTL_DEL, ctx->mqttfd, NULL); ctx->mqttfd = -1; } return 0; }
/** * @brief 发送MQTT Ping报文 * @param ctx:上下文变量 * @retval ret:0,成功,<0 失败 **/ static int MqttSample_CmdPing(struct MqttSampleContext *ctx) { int err; int bytes = 0; printf("%s %d\n", __func__, __LINE__); err = Mqtt_PackPingReqPkt(ctx->mqttbuf); if(MQTTERR_NOERROR != err) { printf("Critical bug: failed to pack the ping request packet.err=%d\n", err); return -1; } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 0; }
static int MqttSample_CmdCmdRet(struct MqttSampleContext *ctx) { int err; int bytes = 0; printf("%s %d\n", __func__, __LINE__); err = Mqtt_PackCmdRetPkt(ctx->mqttbuf, 1, ctx->cmdid, "dkdkkxiiii", 11, 0); if(MQTTERR_NOERROR != err) { printf("Critical bug: failed to pack the cmd ret packet.\n"); return -1; } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 0; }
/** * @brief 发送MQTT Connet报文,登录鉴权 * @param ctx:上下文变量 * @retval ret:0,成功,<0 失败 **/ static int MqttSample_CmdConnect(struct MqttSampleContext *ctx) { int err; int bytes = 0; printf("%s %d\n", __func__, __LINE__); err = Mqtt_PackConnectPkt(ctx->mqttbuf, 0, ctx->devid, 1, "WillTopic", "will message-test", 17, MQTT_QOS_LEVEL0, 0, ctx->proid, ctx->apikey, strlen(ctx->apikey)); if(MQTTERR_NOERROR != err) { printf("Failed to pack the MQTT CONNECT PACKET, errcode is %d.\n", err); return -1; } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 0; }
/** * @brief 设备取消订阅,TOPIC是TOPIC_TO_UNSUB * @param ctx:上下文变量 * @retval ret:0,成功,<0 失败 **/ static int MqttSample_CmdUnsubscribe(struct MqttSampleContext *ctx) { int err; int bytes = 0; printf("%s %d\n", __func__, __LINE__); err = Mqtt_PackUnsubscribePkt(ctx->mqttbuf, PACK_FALG_UNSUB, TOPIC_TO_UNSUB); if(err != MQTTERR_NOERROR) { printf("Critical bug: failed to pack the unsubscribe packet.\n"); return -1; } err = Mqtt_AppendUnsubscribeTopic(ctx->mqttbuf, TOPIC_TO_UNSUB); if(err != MQTTERR_NOERROR) { printf("Critical bug: failed to append the topic to the " "unsubscribe packet.\n"); return -1; } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 0; }
/** * @brief 设备订阅报文,TOPIC是TOPIC_TO_SUB * @param ctx:上下文变量 * @retval ret:0,成功,<0 失败 **/ static int MqttSample_CmdSubscribe(struct MqttSampleContext *ctx) { int err; int bytes = 0; printf("%s %d\n", __func__, __LINE__); err = Mqtt_PackSubscribePkt(ctx->mqttbuf, 1, TOPIC_TO_SUB, MQTT_QOS_LEVEL1); if(err != MQTTERR_NOERROR) { printf("Critical bug: failed to pack the subscribe packet.\n"); return -1; } printf("%s %d\n", __func__, __LINE__); /* err = Mqtt_AppendSubscribeTopic(ctx->mqttbuf, "433223/Bs04OCJioNgpmvjRphRak15j7Z8=/25267/test-2", MQTT_QOS_LEVEL2); */ if(err != MQTTERR_NOERROR) { printf("Critical bug: failed to append the topic to the " "subscribe packet.\n"); return -1; } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 0; }
/** * @brief 周期性发布数据,这里是测试代码,发布温湿度和一个状态信息,三个数据流轮流发布 * @param ctx:上下文变量 * @param cause:发布原因,TIMEOUT,定时发送,EVENT则是由设备事件触发 * @retval ret:0,成功,<0 失败 **/ static int MqttSample_CmdPublishNormal(struct MqttSampleContext *ctx, uint8_t cause) { int err = 0, ir_index = 0; int bytes = 0; struct MqttExtent *ext; unsigned char dis[3][64] = {"未知初始状态", "设备在位", "设备离位"}; static unsigned char count = 0; int64_t ts = 0; //no time uint16_t temprature[1], rh[1]; if(ctx->publish_state != 0) { printf("publsh busy\n"); return -1; } ctx->publish_state = 1; printf("%s %d,count=%d,cause=%d\n", __func__, __LINE__, count, cause); // ts = (int64_t)time(NULL) * 1000; SHT2x_MeasureHM(SHT20_Measurement_RH_HM, temprature); mDelay(1500); SHT2x_MeasureHM(SHT20_Measurement_T_HM, rh); if((count == 0) || (cause == EVENT)) { //no time if(cause == TIME_OUT) { ir_state = !ir_state; } if(ir_state == 0xff) { ir_index = 0; } if(ir_state == 0x1) { ir_index = 1; } if(ir_state == 0) { ir_index = 2; } if(count != 2) { count++; } //append data; String printf("pub state\n"); err |= Mqtt_PackDataPointStartNormal(ctx->mqttbuf, (char *)(DS_TO_PUBLISH), 1, MQTT_QOS_LEVEL2, 0, 1); ext = MqttBuffer_AllocExtent(ctx->mqttbuf, 1 + strlen(dis[ir_index])); if(!ext) { return MQTTERR_OUTOFMEMORY; } ext->payload[0] = 0x84;; memcpy(&ext->payload[1], dis[ir_index], strlen(dis[ir_index])); MqttBuffer_AppendExtent(ctx->mqttbuf, ext); } else if(count == 1) { printf("pub temprature\n"); err |= Mqtt_PackDataPointStartNormal(ctx->mqttbuf, (char *)(DS_TO_PUBLISH_T), 1, MQTT_QOS_LEVEL2, 0, 1); //append data; int32 ext = MqttBuffer_AllocExtent(ctx->mqttbuf, 1 + sizeof(int)); if(!ext) { return MQTTERR_OUTOFMEMORY; } ext->payload[0] = 0x81; ext->payload[1] = 0; ext->payload[2] = 0; ext->payload[3] = 0; ext->payload[4] = temprature[0]; MqttBuffer_AppendExtent(ctx->mqttbuf, ext); count++; } else if(count == 2) { printf("rh\n"); err |= Mqtt_PackDataPointStartNormal(ctx->mqttbuf, (char *)(DS_TO_PUBLISH_RH), 1, MQTT_QOS_LEVEL2, 0, 1); //append data; int32 ext = MqttBuffer_AllocExtent(ctx->mqttbuf, 1 + sizeof(int)); if(!ext) { return MQTTERR_OUTOFMEMORY; } ext->payload[0] = 0x81;; ext->payload[1] = 0; ext->payload[2] = 0; ext->payload[3] = 0; ext->payload[4] = rh[0]; MqttBuffer_AppendExtent(ctx->mqttbuf, ext); count = 0; } if(err) { printf("Failed to pack data point package.err=%d\n", err); return -1; } err = Mqtt_AppendLength(ctx->mqttbuf, ext->len); if(MQTTERR_NOERROR != err) { return err; } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 0; }
/** * @brief 周期性发布数据,暂时没有使用,因为采用JSON发布,前端暂时不支持Json显示,但可以正常发布 * @param ctx:上下文变量 * @retval ret:0,成功,<0 失败 **/ static int MqttSample_CmdPublish(struct MqttSampleContext *ctx) { uint8_t cause = 0; //only for test int err = 0; int bytes = 0; static unsigned char count = 0; int64_t ts = 0; //no time uint16_t temprature[1], rh[1]; printf("%s %d,count=%d,cause=%d\n", __func__, __LINE__, count, cause); // ts = (int64_t)time(NULL) * 1000; SHT2x_MeasureHM(SHT20_Measurement_RH_HM, temprature); mDelay(1500); SHT2x_MeasureHM(SHT20_Measurement_T_HM, rh); err |= Mqtt_PackDataPointStart(ctx->mqttbuf, 1, MQTT_QOS_LEVEL2, 0, 1); if((count == 0) || (cause == EVENT)) { err |= Mqtt_AppendDPStartObject(ctx->mqttbuf, DS_TO_PUBLISH, ts); if(cause == TIME_OUT) { ir_state = !ir_state; } if(ir_state == 0x1) { err |= Mqtt_AppendDPSubvalueString(ctx->mqttbuf, DS_TO_PUBLISH, "设备在位"); } else if(ir_state == 0) { err |= Mqtt_AppendDPSubvalueString(ctx->mqttbuf, DS_TO_PUBLISH, "设备离位"); } else { err |= Mqtt_AppendDPSubvalueString(ctx->mqttbuf, DS_TO_PUBLISH, "未知初始状态"); } if(count != 2) { count++; } } else if(count == 1) { err |= Mqtt_AppendDPStartObject(ctx->mqttbuf, DS_TO_PUBLISH_T, ts); err |= Mqtt_AppendDPSubvalueInt(ctx->mqttbuf, DS_TO_PUBLISH_T, temprature[0]); count++; } else if(count == 2) { err |= Mqtt_AppendDPStartObject(ctx->mqttbuf, DS_TO_PUBLISH_RH, ts); err |= Mqtt_AppendDPSubvalueInt(ctx->mqttbuf, DS_TO_PUBLISH_RH, rh[0]); count = 0; } err |= Mqtt_AppendDPFinishObject(ctx->mqttbuf); err |= Mqtt_PackDataPointFinish(ctx->mqttbuf); if(err) { printf("Failed to pack data point package.err=%d\n", err); return -1; } bytes = Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0); MqttBuffer_Reset(ctx->mqttbuf); return 0; }