1726 lines
64 KiB
C
1726 lines
64 KiB
C
|
/****************************************************************************
|
||
|
*
|
||
|
* Copy right: 2017-, Copyrigths of EigenComm Ltd.
|
||
|
* File name: ctw_mqtt.c
|
||
|
* Description: EC618 CTWING http access source file
|
||
|
* History: Rev1.0 2022-2-15
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include "osasys.h"
|
||
|
#include "networkmgr.h"
|
||
|
#include "ps_event_callback.h"
|
||
|
#include "ps_lib_api.h"
|
||
|
#include "slpman.h"
|
||
|
#include DEBUG_LOG_HEADER_FILE
|
||
|
#include "at_util.h"
|
||
|
#include "MQTTClient.h"
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
#include "mqtttls.h"
|
||
|
#endif
|
||
|
//#include "MQTTConnect.h"
|
||
|
#include "ctw_mqtt.h"
|
||
|
#include "at_ctwing_task.h"
|
||
|
|
||
|
#define MQTT_REG_TASK_STACK_SIZE (1024*6)
|
||
|
#define MQTT_REG_RECV_TASK_STACK_SIZE (1024*6)
|
||
|
#define MQTT_REG_SEND_BUF_SIZE (1024)
|
||
|
#define MQTT_REG_READ_BUF_SIZE (1024)
|
||
|
#define MQTT_REG_AUTH_BUF_SIZE (256)
|
||
|
#define MQTT_REG_AUTH_CLIENT_SIZE (64)
|
||
|
#define MQTT_REG_AUTH_USERNAME_SIZE (256)
|
||
|
#define MQTT_REG_AUTH_PWD_SIZE (72)
|
||
|
|
||
|
#define MQTT_REG_KEEPALIVE_RETRY_MAX 3
|
||
|
|
||
|
#define MQTT_CONTTYPE "application/json"
|
||
|
#define CTW_MQTT_FOTA_TOPIC "/ota/upgrade"
|
||
|
#define CTW_MQTT_FOTA_PROGRESS_TOPIC "/ota/progress"
|
||
|
#define CTW_MQTT_FOTA_ACK_TOPIC "/ota/inform"
|
||
|
#define CTW_MQTT_FOTA_URL_MAX_LEN (256)
|
||
|
#define CTW_MQTT_FOTA_ACK_MAX_LEN (300)
|
||
|
|
||
|
#define CTW_MQTT_MACHINESTATE(S) \
|
||
|
((S) == MQTT_INIT_STATE ? "MQTT_INIT_STATE" : \
|
||
|
((S) == MQTT_IPREADY_STATE ? "MQTT_IPREADY_STATE" : \
|
||
|
((S) == MQTT_REG_STATE ? "MQTT_REG_STATE" : \
|
||
|
((S) == MQTT_KEEP_ONLINE_STATE ? "MQTT_KEEP_ONLINE_STATE" : \
|
||
|
"Unknown"))))
|
||
|
|
||
|
|
||
|
static MWNvmCfgCtwMqttParam* pCtwMqttParam = NULL;
|
||
|
static UINT8 ctwMqttSlpHandler = 0xff;
|
||
|
static ctwMqttStateMachine_t ctwMqttStaMachine = MQTT_INIT_STATE;
|
||
|
UINT32 ctwMqttStatusFlag = MQTT_CTW_SEND_TASK_NOT_CREATE;
|
||
|
UINT32 ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_NOT_CREATE;
|
||
|
UINT32 ctwMqttReconnectStatusFlag = 0;
|
||
|
char* pCtwMqttFotaUrl = NULL;
|
||
|
|
||
|
static ctwMqttRegContext_t gCtwMqttContext = {0};
|
||
|
int gCtwMqttKeepaliveRetryTime = 0;
|
||
|
osMessageQueueId_t ctwMqttMsgQueue = NULL;
|
||
|
extern MWNvmCfgCtwMqttParam *ctwGetMqttParam;
|
||
|
#ifdef FEATURE_HTTPC_ENABLE
|
||
|
#include "at_http_task.h"
|
||
|
extern httpAtContext_t gHttpAtCxt;
|
||
|
extern uint16_t ctwMqttReqHandle;
|
||
|
extern void httpClearAtContext(httpAtContext_t* atContext);
|
||
|
extern void httpSleepVote(HTTPSleep_e sleep);
|
||
|
extern CmsRetId httpSendReq();
|
||
|
#endif
|
||
|
|
||
|
void ctwMqttContextConfig(ctwMqttRegContext_t *ctwMqttContext)
|
||
|
{
|
||
|
MQTTPacket_connectData mqttConnectData = MQTTPacket_connectData_initializer;
|
||
|
|
||
|
ctwMqttContext->mqttClient = mallocEc(sizeof(MQTTClient));
|
||
|
memset(ctwMqttContext->mqttClient, 0, sizeof(MQTTClient));
|
||
|
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
ctwMqttContext->mqttsClient = mallocEc(sizeof(mqttsClientContext));
|
||
|
memset(ctwMqttContext->mqttsClient, 0, sizeof(mqttsClientContext));
|
||
|
ctwMqttContext->mqttsClient->timeout_s = 5;
|
||
|
ctwMqttContext->mqttsClient->timeout_r = 20;
|
||
|
#endif
|
||
|
|
||
|
ctwMqttContext->mqttNetwork = mallocEc(sizeof(Network));
|
||
|
memset(ctwMqttContext->mqttNetwork, 0, sizeof(Network));
|
||
|
|
||
|
ctwMqttContext->mqttSendBuf = mallocEc(MQTT_REG_SEND_BUF_SIZE);
|
||
|
memset(ctwMqttContext->mqttSendBuf, 0, MQTT_REG_SEND_BUF_SIZE);
|
||
|
ctwMqttContext->mqttReadBuf = mallocEc(MQTT_REG_READ_BUF_SIZE);
|
||
|
memset(ctwMqttContext->mqttReadBuf, 0, MQTT_REG_READ_BUF_SIZE);
|
||
|
|
||
|
ctwMqttContext->mqttUri = mallocEc(MQTT_REG_URI_MAX_LEN);
|
||
|
memset(ctwMqttContext->mqttUri, 0, MQTT_REG_URI_MAX_LEN);
|
||
|
|
||
|
memcpy(&ctwMqttContext->mqttConnectData, &mqttConnectData, sizeof(mqttConnectData));
|
||
|
|
||
|
//get pCtwMqttParamn for keepAlive
|
||
|
ctwMqttContext->mqttConnectData.keepAliveInterval = pCtwMqttParam->keepAlive;
|
||
|
ctwMqttContext->mqttClient->command_timeout_ms = 3000;
|
||
|
|
||
|
ctwMqttContext->mqttRegParam = mallocEc(sizeof(ctwMqttRegParam_t));
|
||
|
memset(ctwMqttContext->mqttRegParam, 0, sizeof(ctwMqttRegParam_t));
|
||
|
|
||
|
}
|
||
|
|
||
|
void ctwMqttContextDelete(ctwMqttRegContext_t *ctwMqttContext)
|
||
|
{
|
||
|
if(ctwMqttContext->mqttRegParam != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttRegParam);
|
||
|
ctwMqttContext->mqttRegParam = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttUri != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttUri);
|
||
|
ctwMqttContext->mqttUri = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttSendBuf != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttSendBuf);
|
||
|
ctwMqttContext->mqttSendBuf = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttReadBuf != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttReadBuf);
|
||
|
ctwMqttContext->mqttReadBuf = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttClient != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttClient);
|
||
|
ctwMqttContext->mqttClient = NULL;
|
||
|
}
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
if(ctwMqttContext->mqttsClient != NULL)
|
||
|
{
|
||
|
if(ctwMqttContext->mqttsClient->ssl != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttsClient->ssl);
|
||
|
ctwMqttContext->mqttsClient->ssl = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttsClient->caCert != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttsClient->caCert);
|
||
|
ctwMqttContext->mqttsClient->caCert = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttsClient->clientCert != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttsClient->clientCert);
|
||
|
ctwMqttContext->mqttsClient->clientCert = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttsClient->clientPk != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttsClient->clientPk);
|
||
|
ctwMqttContext->mqttsClient->clientPk = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttsClient->psk_key != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttsClient->psk_key);
|
||
|
ctwMqttContext->mqttsClient->psk_key = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttsClient->psk_identity != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttsClient->psk_identity);
|
||
|
ctwMqttContext->mqttsClient->psk_identity = NULL;
|
||
|
}
|
||
|
freeEc(ctwMqttContext->mqttsClient);
|
||
|
ctwMqttContext->mqttsClient = NULL;
|
||
|
}
|
||
|
#endif
|
||
|
if(ctwMqttContext->mqttNetwork != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttNetwork);
|
||
|
ctwMqttContext->mqttNetwork = NULL;
|
||
|
}
|
||
|
|
||
|
if(ctwMqttContext->mqttConnectData.clientID.cstring != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttConnectData.clientID.cstring);
|
||
|
ctwMqttContext->mqttConnectData.clientID.cstring = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttConnectData.username.cstring != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttConnectData.username.cstring);
|
||
|
ctwMqttContext->mqttConnectData.username.cstring = NULL;
|
||
|
}
|
||
|
if(ctwMqttContext->mqttConnectData.password.cstring != NULL)
|
||
|
{
|
||
|
freeEc(ctwMqttContext->mqttConnectData.password.cstring);
|
||
|
ctwMqttContext->mqttConnectData.password.cstring = NULL;
|
||
|
}
|
||
|
ctwMqttContext->port = 0;
|
||
|
}
|
||
|
|
||
|
int ctwMqttClose(ctwMqttRegContext_t* mqttContext)
|
||
|
{
|
||
|
ctwMqttRegContext_t* mqttNewContext = mqttContext;
|
||
|
|
||
|
if(mqttContext->mqttsFlag == 0)
|
||
|
{
|
||
|
mqttNewContext->mqttNetwork->disconnect(mqttNewContext->mqttNetwork);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
mqttSslClose(mqttContext->mqttsClient);
|
||
|
#endif
|
||
|
}
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
|
||
|
int ctwMqttDisconnect(ctwMqttRegContext_t *mqttContext)
|
||
|
{
|
||
|
int rc = SUCCESS;
|
||
|
Timer timer; // we might wait for incomplete incoming publishes to complete
|
||
|
int len = 0;
|
||
|
|
||
|
TimerInit(&timer);
|
||
|
TimerCountdownMS(&timer, mqttContext->mqttClient->command_timeout_ms);
|
||
|
|
||
|
len = MQTTSerialize_disconnect(mqttContext->mqttClient->buf, mqttContext->mqttClient->buf_size);
|
||
|
if (len > 0)
|
||
|
rc = ctwMqttSendPacket(mqttContext, len, &timer, 0, false); // send the disconnect packet
|
||
|
//mqttCloseSession(c);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttKeepalive(ctwMqttRegContext_t *mqttContext)
|
||
|
{
|
||
|
int rc = SUCCESS;
|
||
|
|
||
|
if (mqttContext->mqttClient->keepAliveInterval == 0)
|
||
|
goto exit;
|
||
|
|
||
|
if (TimerIsExpired(&mqttContext->mqttClient->last_sent) || TimerIsExpired(&mqttContext->mqttClient->last_received))
|
||
|
{
|
||
|
if (mqttContext->mqttClient->ping_outstanding)
|
||
|
rc = FAILURE; /* PINGRESP not received in keepalive interval */
|
||
|
else
|
||
|
{
|
||
|
Timer timer;
|
||
|
TimerInit(&timer);
|
||
|
TimerCountdownMS(&timer, 1000);
|
||
|
int len = MQTTSerialize_pingreq(mqttContext->mqttClient->buf, mqttContext->mqttClient->buf_size);
|
||
|
if (len > 0 && (rc = ctwMqttSendPacket(mqttContext, len, &timer, 0, false)) == SUCCESS) // send the ping packet
|
||
|
mqttContext->mqttClient->ping_outstanding = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
static void ctwMqttNewMessageData(MessageData* md, MQTTString* aTopicName, MQTTMessage* aMessage) {
|
||
|
md->topicName = aTopicName;
|
||
|
md->message = aMessage;
|
||
|
}
|
||
|
|
||
|
static char ctwMqttIsTopicMatched(char* topicFilter, MQTTString* topicName)
|
||
|
{
|
||
|
char* curf = topicFilter;
|
||
|
char* curn = topicName->lenstring.data;
|
||
|
char* curn_end = curn + topicName->lenstring.len;
|
||
|
|
||
|
while (*curf && curn < curn_end)
|
||
|
{
|
||
|
if (*curn == '/' && *curf != '/')
|
||
|
break;
|
||
|
if (*curf != '+' && *curf != '#' && *curf != *curn)
|
||
|
break;
|
||
|
if (*curf == '+')
|
||
|
{ // skip until we meet the next separator, or end of string
|
||
|
char* nextpos = curn + 1;
|
||
|
while (nextpos < curn_end && *nextpos != '/')
|
||
|
nextpos = ++curn + 1;
|
||
|
}
|
||
|
else if (*curf == '#')
|
||
|
curn = curn_end - 1; // skip until end of string
|
||
|
curf++;
|
||
|
curn++;
|
||
|
};
|
||
|
|
||
|
return (curn == curn_end) && (*curf == '\0');
|
||
|
}
|
||
|
|
||
|
int ctwMqttDeliverMessage(MQTTClient* c, MQTTString* topicName, MQTTMessage* message)
|
||
|
{
|
||
|
int i;
|
||
|
int rc = FAILURE;
|
||
|
|
||
|
// we have to find the right message handler - indexed by topic
|
||
|
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
|
||
|
{
|
||
|
if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) ||
|
||
|
ctwMqttIsTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName)))
|
||
|
{
|
||
|
if (c->messageHandlers[i].fp != NULL)
|
||
|
{
|
||
|
MessageData md;
|
||
|
ctwMqttNewMessageData(&md, topicName, message);
|
||
|
c->messageHandlers[i].fp(&md);
|
||
|
rc = SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (rc == FAILURE && c->defaultMessageHandler != NULL)
|
||
|
{
|
||
|
MessageData md;
|
||
|
ctwMqttNewMessageData(&md, topicName, message);
|
||
|
c->defaultMessageHandler(&md);
|
||
|
rc = SUCCESS;
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
|
||
|
void ctwMqttDefaultMessageArrived(MessageData* data)
|
||
|
{
|
||
|
int primSize;
|
||
|
//ctwMqttRegContext_t *mqttContext = &gCtwMqttContext;
|
||
|
ctwMqttMessage mqtt_msg;
|
||
|
int mqtt_topic_len = 0;
|
||
|
int mqtt_payload_len = 0;
|
||
|
char *payloadPtrStartTemp = NULL;
|
||
|
char *payloadPtrEndTemp = NULL;
|
||
|
int payloadLenTemp = 0;
|
||
|
//MWNvmCfgCtwMqttParam ctwMqttParam = {0};
|
||
|
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, mqtt_task_0, P_SIG, ".........MQTT_messageArrived is:%s", data->message->payload);
|
||
|
memset(&mqtt_msg, 0, sizeof(mqtt_msg));
|
||
|
mqtt_msg.msg_id = data->message->id;
|
||
|
|
||
|
if(data->topicName->lenstring.data != NULL)
|
||
|
{
|
||
|
if(memcmp(data->topicName->lenstring.data, CTW_MQTT_FOTA_TOPIC, strlen(CTW_MQTT_FOTA_TOPIC)) == 0)
|
||
|
{
|
||
|
payloadPtrStartTemp = strstr((char*)data->message->payload, "taskId\":");
|
||
|
if(payloadPtrStartTemp != NULL)
|
||
|
{
|
||
|
gCtwMqttContext.fotaFlag = 1;
|
||
|
}
|
||
|
}
|
||
|
mqtt_topic_len = data->topicName->lenstring.len+1;
|
||
|
mqtt_msg.mqtt_topic = mallocEc(mqtt_topic_len);
|
||
|
memset(mqtt_msg.mqtt_topic, 0, mqtt_topic_len);
|
||
|
memcpy(mqtt_msg.mqtt_topic, data->topicName->lenstring.data, (mqtt_topic_len-1));
|
||
|
mqtt_msg.mqtt_topic_len = data->topicName->lenstring.len;
|
||
|
memset(data->topicName->lenstring.data, 0, (mqtt_topic_len-1));
|
||
|
}
|
||
|
|
||
|
primSize = sizeof(mqtt_msg);
|
||
|
if((gCtwMqttContext.fotaFlag == 1)&&(data->message->payload != NULL))
|
||
|
{
|
||
|
mqtt_msg.fota_cmd = MQTT_FOTA_STAT_START;
|
||
|
mqtt_msg.fota_percent = 1;
|
||
|
mqtt_msg.fota_ret = 1;
|
||
|
//mwNvmCfgGetCtwMqttParam(&ctwMqttParam);
|
||
|
//memcpy(pCtwMqttParam, &ctwMqttParam, sizeof(ctwMqttParam));
|
||
|
|
||
|
//pCtwMqttParam->fotaFlag = 1;
|
||
|
memset(pCtwMqttParam->fotaTaskId, 0, MID_WARE_CTW_MQTT_FOTA_TASK_ID);
|
||
|
memset(pCtwMqttParam->fotaVersion, 0, MID_WARE_CTW_MQTT_FOTA_VER_LEN);
|
||
|
memset(pCtwMqttParam->fotaToken, 0, MID_WARE_CTW_MQTT_FOTA_TOKEN_LEN);
|
||
|
memset(pCtwMqttParam->fotaModule, 0, MID_WARE_CTW_MQTT_FOTA_MODULE_LEN);
|
||
|
|
||
|
payloadPtrStartTemp = strstr((char*)data->message->payload, "taskId\":");
|
||
|
if(payloadPtrStartTemp != NULL)
|
||
|
{
|
||
|
payloadPtrStartTemp = payloadPtrStartTemp + strlen("taskId\":");
|
||
|
payloadPtrEndTemp = strstr(payloadPtrStartTemp, ",\"");
|
||
|
payloadLenTemp = payloadPtrEndTemp - payloadPtrStartTemp;
|
||
|
memcpy(pCtwMqttParam->fotaTaskId, payloadPtrStartTemp, payloadLenTemp);
|
||
|
|
||
|
payloadPtrStartTemp = strstr((char*)data->message->payload, "version\":\"");
|
||
|
payloadPtrStartTemp = payloadPtrStartTemp + strlen("version\":\"");
|
||
|
payloadPtrEndTemp = strstr(payloadPtrStartTemp, "\",");
|
||
|
payloadLenTemp = payloadPtrEndTemp - payloadPtrStartTemp;
|
||
|
memcpy(pCtwMqttParam->fotaVersion, payloadPtrStartTemp, payloadLenTemp);
|
||
|
|
||
|
payloadPtrStartTemp = strstr((char*)data->message->payload, "token\":\"");
|
||
|
payloadPtrStartTemp = payloadPtrStartTemp + strlen("token\":\"");
|
||
|
payloadPtrEndTemp = strstr(payloadPtrStartTemp, "\",");
|
||
|
payloadLenTemp = payloadPtrEndTemp - payloadPtrStartTemp;
|
||
|
memcpy(pCtwMqttParam->fotaToken, payloadPtrStartTemp, payloadLenTemp);
|
||
|
|
||
|
payloadPtrStartTemp = strstr((char*)data->message->payload, "module\":\"");
|
||
|
payloadPtrStartTemp = payloadPtrStartTemp + strlen("module\":\"");
|
||
|
payloadPtrEndTemp = strstr(payloadPtrStartTemp, "\",");
|
||
|
payloadLenTemp = payloadPtrEndTemp - payloadPtrStartTemp;
|
||
|
memcpy(pCtwMqttParam->fotaModule, payloadPtrStartTemp, payloadLenTemp);
|
||
|
|
||
|
pCtwMqttFotaUrl = mallocEc(CTW_MQTT_FOTA_URL_MAX_LEN);
|
||
|
memset(pCtwMqttFotaUrl, 0, CTW_MQTT_FOTA_URL_MAX_LEN);
|
||
|
payloadPtrStartTemp = strstr((char*)data->message->payload, "url\":\"");
|
||
|
payloadPtrStartTemp = payloadPtrStartTemp + strlen("url\":\"");
|
||
|
payloadPtrEndTemp = strstr(payloadPtrStartTemp, "\",");
|
||
|
payloadLenTemp = payloadPtrEndTemp - payloadPtrStartTemp;
|
||
|
memcpy(pCtwMqttFotaUrl, payloadPtrStartTemp, payloadLenTemp);
|
||
|
|
||
|
mwNvmCfgSetAndSaveCtwMqttParam(pCtwMqttParam);
|
||
|
|
||
|
#ifdef FEATURE_HTTPC_ENABLE
|
||
|
httpClearAtContext(&gHttpAtCxt);
|
||
|
gHttpAtCxt.reqhandle = ctwMqttReqHandle;
|
||
|
gHttpAtCxt.isFota = TRUE;
|
||
|
gHttpAtCxt.dlUrcRag = 100;
|
||
|
gHttpAtCxt.method = 0;
|
||
|
httpCreateClientContext(&gHttpAtCxt);
|
||
|
|
||
|
if(gHttpAtCxt.url != NULL)
|
||
|
{
|
||
|
freeEc(gHttpAtCxt.url);
|
||
|
gHttpAtCxt.url = NULL;
|
||
|
}
|
||
|
gHttpAtCxt.url = mallocEc(CTW_MQTT_FOTA_URL_MAX_LEN);
|
||
|
|
||
|
memset(gHttpAtCxt.url, 0, CTW_MQTT_FOTA_URL_MAX_LEN);
|
||
|
snprintf(gHttpAtCxt.url, CTW_MQTT_FOTA_URL_MAX_LEN, "%s&deviceId=%s&accessToken=%s", pCtwMqttFotaUrl, pCtwMqttParam->clientId, pCtwMqttParam->fotaToken);
|
||
|
httpSleepVote(HTTP_DIS_SLEEP);
|
||
|
gHttpAtCxt.reqStat = HTTP_REQ_HANDLE;
|
||
|
httpSendReq();//send fota download request
|
||
|
#endif
|
||
|
}
|
||
|
if(data->message->payload != NULL)
|
||
|
{
|
||
|
mqtt_payload_len = data->message->payloadlen+1;
|
||
|
mqtt_msg.mqtt_payload = mallocEc(mqtt_payload_len);
|
||
|
memset(mqtt_msg.mqtt_payload, 0, mqtt_payload_len);
|
||
|
memcpy(mqtt_msg.mqtt_payload, data->message->payload, (mqtt_payload_len-1));
|
||
|
mqtt_msg.mqtt_payload_len = data->message->payloadlen;
|
||
|
memset(data->message->payload, 0, (mqtt_payload_len-1));
|
||
|
}
|
||
|
|
||
|
applSendCmsInd(BROADCAST_IND_HANDLER, APPL_CTW, APPL_CTW_MQTT_FOTA_IND, primSize, (void *)&mqtt_msg);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
applSendCmsInd(BROADCAST_IND_HANDLER, APPL_CTW, APPL_CTW_MQTT_DL_IND, primSize, (void *)&mqtt_msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ctwMqttClientInit(ctwMqttRegContext_t *mqttContext, Network* network, unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
mqttContext->mqttClient->ipstack = network;
|
||
|
|
||
|
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
|
||
|
{
|
||
|
mqttContext->mqttClient->messageHandlers[i].topicFilter = 0;
|
||
|
}
|
||
|
mqttContext->mqttClient->buf = sendbuf;
|
||
|
mqttContext->mqttClient->buf_size = sendbuf_size;
|
||
|
mqttContext->mqttClient->readbuf = readbuf;
|
||
|
mqttContext->mqttClient->readbuf_size = readbuf_size;
|
||
|
mqttContext->mqttClient->isconnected = 0;
|
||
|
mqttContext->mqttClient->cleansession = 0;
|
||
|
mqttContext->mqttClient->ping_outstanding = 0;
|
||
|
mqttContext->mqttClient->defaultMessageHandler = ctwMqttDefaultMessageArrived;
|
||
|
mqttContext->mqttClient->next_packetid = 1;
|
||
|
mqttContext->mqttClient->keepAliveInterval = pCtwMqttParam->keepAlive;
|
||
|
TimerInit(&mqttContext->mqttClient->last_sent);
|
||
|
TimerInit(&mqttContext->mqttClient->last_received);
|
||
|
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
mqttContext->mqttsClient->sendBuf = sendbuf;
|
||
|
mqttContext->mqttsClient->sendBufSize = sendbuf_size;
|
||
|
mqttContext->mqttsClient->readBuf = readbuf;
|
||
|
mqttContext->mqttsClient->readBufSize = readbuf_size;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static INT32 ctwMqttPSUrcCallback(PsEventID eventID, void *param, UINT32 paramLen)
|
||
|
{
|
||
|
NmAtiNetInfoInd *netif = NULL;
|
||
|
CmiSimImsiStr *imsi = NULL;
|
||
|
|
||
|
switch(eventID)
|
||
|
{
|
||
|
case PS_URC_ID_SIM_READY:
|
||
|
{
|
||
|
imsi = (CmiSimImsiStr *)param;
|
||
|
memcpy(gCtwMqttContext.mqttRegParam->imsi, imsi->contents, imsi->length);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case PS_URC_ID_PS_NETINFO:
|
||
|
{
|
||
|
netif = (NmAtiNetInfoInd *)param;
|
||
|
if ((netif->netifInfo.netStatus == NM_NETIF_ACTIVATED)&&((netif->netifInfo.ipType == NM_NET_TYPE_IPV4)||(netif->netifInfo.ipType == NM_NET_TYPE_IPV6)||(netif->netifInfo.ipType == NM_NET_TYPE_IPV4V6)))
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttPSUrcCallback_2_1, P_INFO, "PSIF network active change ctwMqttStaMachine to MQTT_IPREADY_STATE");
|
||
|
ctwMqttStaMachine = MQTT_IPREADY_STATE;
|
||
|
}
|
||
|
else if (netif->netifInfo.netStatus == NM_NETIF_OOS)
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttPSUrcCallback_2_2, P_INFO, "PSIF network OOS");
|
||
|
}
|
||
|
else if (netif->netifInfo.netStatus == NM_NO_NETIF_OR_DEACTIVATED ||
|
||
|
netif->netifInfo.netStatus == NM_NO_NETIF_NOT_DIAL)
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttPSUrcCallback_2_3, P_INFO, "PSIF network deactive");
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void ctwMqttCheckIfNeedExit(UINT8 forceExit)
|
||
|
{
|
||
|
UINT8 cfun = 0xff;
|
||
|
UINT8 i = 0;
|
||
|
|
||
|
if(forceExit == 1)
|
||
|
{
|
||
|
cfun = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
appGetCFUN(&cfun);
|
||
|
}
|
||
|
|
||
|
if(cfun == 0)
|
||
|
{
|
||
|
if(ctwMqttRecvStatusFlag == MQTT_CTW_RECV_TASK_CREATE)
|
||
|
{
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_NOT_CREATE;
|
||
|
}
|
||
|
|
||
|
for(i=0; i<20; i++)
|
||
|
{
|
||
|
if((ctwMqttRecvStatusFlag == MQTT_CTW_RECV_TASK_DELETE) || (forceExit == 1))
|
||
|
{
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_NOT_CREATE;
|
||
|
|
||
|
if((ctwMqttStatusFlag == MQTT_CTW_SEND_TASK_CREATE)||(forceExit == 1))
|
||
|
{
|
||
|
ctwMqttContextDelete(&gCtwMqttContext);
|
||
|
deregisterPSEventCallback((psEventCallback_t)ctwMqttPSUrcCallback);
|
||
|
slpManPlatVoteEnableSleep(ctwMqttSlpHandler, SLP_SLP2_STATE);
|
||
|
ctwMqttStatusFlag = MQTT_CTW_SEND_TASK_NOT_CREATE;
|
||
|
|
||
|
if(pCtwMqttParam != NULL)
|
||
|
{
|
||
|
freeEc(pCtwMqttParam);
|
||
|
pCtwMqttParam = NULL;
|
||
|
ctwGetMqttParam = NULL;
|
||
|
}
|
||
|
if(ctwMqttMsgQueue != NULL)
|
||
|
{
|
||
|
osMessageQueueDelete(ctwMqttMsgQueue);
|
||
|
ctwMqttMsgQueue = NULL;
|
||
|
}
|
||
|
osThreadExit();
|
||
|
}
|
||
|
}
|
||
|
osDelay(500);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ctwMqttGetInvariPara()
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttGetInvariPara_1, P_INFO, "get imei and iccid");
|
||
|
OsaGetImeiNumSync(gCtwMqttContext.mqttRegParam->imei);
|
||
|
appGetIccidNumSync(gCtwMqttContext.mqttRegParam->iccid);
|
||
|
}
|
||
|
|
||
|
static void ctwMqttGetVariPara()
|
||
|
{
|
||
|
UeExtStatusInfo statusInfo;
|
||
|
CmsRetId ret = CMS_RET_SUCC;
|
||
|
|
||
|
ret = appGetUeExtStatusInfoSync(UE_EXT_STATUS_PHY, &statusInfo);
|
||
|
if(ret == CMS_RET_SUCC)
|
||
|
{
|
||
|
gCtwMqttContext.mqttRegParam->phyCellId = statusInfo.phyStatus.phyCellId;
|
||
|
gCtwMqttContext.mqttRegParam->rsrp = statusInfo.phyStatus.sRsrp/100;
|
||
|
gCtwMqttContext.mqttRegParam->snr = statusInfo.phyStatus.snr;
|
||
|
gCtwMqttContext.mqttRegParam->txPower = statusInfo.phyStatus.txPower;
|
||
|
}
|
||
|
//ctwMqttCalcSign(gCtwMqttContext.mqttRegParam->signature, &(gCtwMqttContext.mqttRegParam->timestamp), gCtwMqttContext.mqttRegParam->masterKey);
|
||
|
}
|
||
|
|
||
|
void ctwMqttCalcSign(char* outSign, uint32_t* outTimestamp, char* masterKey)
|
||
|
{
|
||
|
utc_timer_value_t* timeUtc = NULL;
|
||
|
char input[55] = {0};
|
||
|
uint8_t output[32] = {0};
|
||
|
timeUtc = OsaSystemTimeReadUtc();
|
||
|
if(timeUtc != NULL){
|
||
|
*outTimestamp = timeUtc->UTCsecs;
|
||
|
}
|
||
|
|
||
|
snprintf(input,55,"eigencomm%s%d000", masterKey, *outTimestamp);
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttCalcSign_1, P_INFO, "input str=%s", input);
|
||
|
atSha256((unsigned char *)input, 54, output);
|
||
|
cmsHexToLowHexStr(outSign, 65, output, 32);
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttCalcSign_2, P_INFO, "signature=%s", outSign);
|
||
|
}
|
||
|
|
||
|
|
||
|
int ctwMqttDecodePacket(ctwMqttRegContext_t *mqttContext, int* value, int timeout)
|
||
|
{
|
||
|
unsigned char i;
|
||
|
int multiplier = 1;
|
||
|
int len = 0;
|
||
|
const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
|
||
|
|
||
|
*value = 0;
|
||
|
do
|
||
|
{
|
||
|
int rc = MQTTPACKET_READ_ERROR;
|
||
|
|
||
|
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
|
||
|
{
|
||
|
rc = MQTTPACKET_READ_ERROR; /* bad data */
|
||
|
goto exit;
|
||
|
}
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
|
||
|
if(mqttContext->mqttsFlag == 0)
|
||
|
{
|
||
|
rc = mqttContext->mqttClient->ipstack->mqttread(mqttContext->mqttClient->ipstack, &i, 1, timeout);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = mqttSslRead(mqttContext->mqttsClient, &i, 1, timeout);
|
||
|
}
|
||
|
#else
|
||
|
rc = mqttContext->mqttClient->ipstack->mqttread(mqttContext->mqttClient->ipstack, &i, 1, timeout);
|
||
|
#endif
|
||
|
if (rc != 1)
|
||
|
goto exit;
|
||
|
*value += (i & 127) * multiplier;
|
||
|
multiplier *= 128;
|
||
|
} while ((i & 128) != 0);
|
||
|
|
||
|
exit:
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
int ctwMqttReadPacket(ctwMqttRegContext_t *mqttContext, Timer* timer)
|
||
|
{
|
||
|
MQTTHeader header = {0};
|
||
|
int len = 0;
|
||
|
int rem_len = 0;
|
||
|
int rc = 0;
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_read, P_INFO, 0, "...mqttReadPacket..");
|
||
|
|
||
|
if(mqttContext->mqttClient == NULL)
|
||
|
{
|
||
|
rc = -2;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
if(mqttContext->mqttsFlag != 0)
|
||
|
{
|
||
|
if(mqttContext->mqttsClient == NULL)
|
||
|
{
|
||
|
rc = -2;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls0, P_INFO, 0, "...mqttReadPacket..0.");
|
||
|
/* 1. read the header byte. This has the packet type in it */
|
||
|
rc = mqttSslRead(mqttContext->mqttsClient, mqttContext->mqttsClient->readBuf, 1, TimerLeftMS(timer));
|
||
|
if (rc != 1)
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
len = 1;
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls1, P_INFO, 0, "...mqttReadPacket..1.");
|
||
|
/* 2. read the remaining length. This is variable in itself */
|
||
|
ctwMqttDecodePacket(mqttContext, &rem_len, TimerLeftMS(timer));
|
||
|
len += MQTTPacket_encode(mqttContext->mqttsClient->readBuf + 1, rem_len); /* put the original remaining length back into the buffer */
|
||
|
|
||
|
if (rem_len > (mqttContext->mqttsClient->readBufSize - len))
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls202, P_INFO, 0, "...mqttReadPacket..202.");
|
||
|
rc = BUFFER_OVERFLOW;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls2, P_INFO, 0, "...mqttReadPacket..2.");
|
||
|
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
|
||
|
if (rem_len > 0 && (mqttSslRead(mqttContext->mqttsClient, mqttContext->mqttsClient->readBuf + len, rem_len, TimerLeftMS(timer)) != rem_len))
|
||
|
{
|
||
|
rc = 0;
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls200, P_INFO, 0, "...mqttReadPacket..200.");
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
header.byte = mqttContext->mqttsClient->readBuf[0];
|
||
|
rc = header.bits.type;
|
||
|
if (mqttContext->mqttClient->keepAliveInterval > 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls201, P_INFO, 0, "...mqttReadPacket..201.");
|
||
|
TimerCountdown(&mqttContext->mqttClient->last_received, mqttContext->mqttClient->keepAliveInterval); // record the fact that we have successfully received a packet
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
/* 1. read the header byte. This has the packet type in it */
|
||
|
rc = mqttContext->mqttClient->ipstack->mqttread(mqttContext->mqttClient->ipstack, mqttContext->mqttClient->readbuf, 1, TimerLeftMS(timer));
|
||
|
if (rc != 1)
|
||
|
goto exit;
|
||
|
|
||
|
len = 1;
|
||
|
/* 2. read the remaining length. This is variable in itself */
|
||
|
ctwMqttDecodePacket(mqttContext, &rem_len, TimerLeftMS(timer));
|
||
|
len += MQTTPacket_encode(mqttContext->mqttClient->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */
|
||
|
|
||
|
if (rem_len > (mqttContext->mqttClient->readbuf_size - len))
|
||
|
{
|
||
|
rc = BUFFER_OVERFLOW;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
|
||
|
if (rem_len > 0 && (mqttContext->mqttClient->ipstack->mqttread(mqttContext->mqttClient->ipstack, mqttContext->mqttClient->readbuf + len, rem_len, TimerLeftMS(timer)) != rem_len)) {
|
||
|
rc = 0;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
header.byte = mqttContext->mqttClient->readbuf[0];
|
||
|
rc = header.bits.type;
|
||
|
if (mqttContext->mqttClient->keepAliveInterval > 0)
|
||
|
{
|
||
|
TimerCountdown(&mqttContext->mqttClient->last_received, mqttContext->mqttClient->keepAliveInterval); // record the fact that we have successfully received a packet
|
||
|
}
|
||
|
}
|
||
|
exit:
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttSendPacket(ctwMqttRegContext_t *mqttContext, int length, Timer* timer, int rai, bool exceptdata)
|
||
|
{
|
||
|
int rc = FAILURE,
|
||
|
sent = 0;
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, ctwMqttSendPacket0, P_INFO, 0, "...mqttSendPacket..len=%d.", length);
|
||
|
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
if(mqttContext->mqttsFlag != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls3, P_INFO, 0, "...mqttSendPacket..0.");
|
||
|
//mqttContext->mqttsClient->ssl->sslContext.rai = rai;
|
||
|
rc = mqttSslSend(mqttContext->mqttsClient, &mqttContext->mqttsClient->sendBuf[sent], length);
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_tls4, P_INFO, 1, "...mqttSendPacket..=%d.", rc);
|
||
|
TimerCountdown(&mqttContext->mqttClient->last_sent, (mqttContext->mqttClient->keepAliveInterval-2)); // record the fact that we have successfully sent the packet
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
while (sent < length && !TimerIsExpired(timer))
|
||
|
{
|
||
|
#ifdef MQTT_RAI_OPTIMIZE
|
||
|
rc = mqttContext->mqttClient->ipstack->mqttwrite(mqttContext->mqttClient->ipstack, &mqttContext->mqttClient->buf[sent], length, TimerLeftMS(timer), rai, exceptdata);
|
||
|
#else
|
||
|
rc = mqttContext->mqttClient->ipstack->mqttwrite(mqttContext->mqttClient->ipstack, &mqttContext->mqttClient->buf[sent], length, TimerLeftMS(timer));
|
||
|
#endif
|
||
|
|
||
|
if (rc < 0) // there was an error writing the data
|
||
|
break;
|
||
|
sent += rc;
|
||
|
}
|
||
|
if (sent == length)
|
||
|
{
|
||
|
TimerCountdown(&mqttContext->mqttClient->last_sent, (mqttContext->mqttClient->keepAliveInterval-2)); // record the fact that we have successfully sent the packet
|
||
|
rc = SUCCESS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = FAILURE;
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, ctwMqttSendPacket1, P_INFO, 0, "...mqttSendPacket..rc=%d.", rc);
|
||
|
return rc;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int ctwMqttPublish(ctwMqttRegContext_t *mqttContext, int msgID, const char* topicName, MQTTMessage* message, int rai, bool exceptdata)
|
||
|
{
|
||
|
int rc = FAILURE;
|
||
|
Timer timer;
|
||
|
MQTTString topic = MQTTString_initializer;
|
||
|
topic.cstring = (char *)topicName;
|
||
|
int len = 0;
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_88, P_INFO, 1, "..mqttPublish.len.%d",message->payloadlen);
|
||
|
|
||
|
TimerInit(&timer);
|
||
|
TimerCountdownMS(&timer, mqttContext->mqttClient->command_timeout_ms);
|
||
|
|
||
|
if (message->qos == QOS1 || message->qos == QOS2)
|
||
|
//message->id = mqttGetNextPacketId(c);
|
||
|
message->id = msgID;
|
||
|
|
||
|
len = MQTTSerialize_publish(mqttContext->mqttClient->buf, mqttContext->mqttClient->buf_size, 0, message->qos, message->retained, message->id,
|
||
|
topic, (unsigned char*)message->payload, message->payloadlen);
|
||
|
if (len <= 0)
|
||
|
goto exit;
|
||
|
|
||
|
if ((rc = ctwMqttSendPacket(mqttContext, len, &timer, rai, exceptdata)) != SUCCESS) // send the subscribe packet
|
||
|
goto exit; // there was a problem
|
||
|
|
||
|
exit:
|
||
|
if (rc == FAILURE)
|
||
|
;//MQTTCloseSession(c);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttConnectWithResults(ctwMqttRegContext_t *mqttContext, MQTTPacket_connectData* options, MQTTConnackData* data)
|
||
|
{
|
||
|
Timer connect_timer;
|
||
|
int rc = FAILURE;
|
||
|
MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
|
||
|
int len = 0;
|
||
|
|
||
|
TimerInit(&connect_timer);
|
||
|
TimerCountdownMS(&connect_timer, mqttContext->mqttClient->command_timeout_ms);
|
||
|
|
||
|
if (options == 0)
|
||
|
options = &default_options; /* set default options if none were supplied */
|
||
|
|
||
|
mqttContext->mqttClient->keepAliveInterval = options->keepAliveInterval;
|
||
|
mqttContext->mqttClient->cleansession = options->cleansession;
|
||
|
TimerCountdown(&mqttContext->mqttClient->last_received, mqttContext->mqttClient->keepAliveInterval);
|
||
|
if ((len = MQTTSerialize_connect(mqttContext->mqttClient->buf, mqttContext->mqttClient->buf_size, options)) <= 0)
|
||
|
goto exit;
|
||
|
if ((rc = ctwMqttSendPacket(mqttContext, len, &connect_timer, 0, false)) != SUCCESS) // send the connect packet
|
||
|
goto exit; // there was a problem
|
||
|
exit:
|
||
|
if (rc == SUCCESS)
|
||
|
{
|
||
|
mqttContext->mqttClient->isconnected = 1;
|
||
|
mqttContext->mqttClient->ping_outstanding = 0;
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttConnect(ctwMqttRegContext_t *mqttContext, MQTTPacket_connectData* options)
|
||
|
{
|
||
|
MQTTConnackData data;
|
||
|
return ctwMqttConnectWithResults(mqttContext, options, &data);
|
||
|
}
|
||
|
|
||
|
int ctwMqttReconnectTcp(void *context)
|
||
|
{
|
||
|
int rc = -1;
|
||
|
ctwMqttRegContext_t *mqttContext = (ctwMqttRegContext_t *)context;
|
||
|
int socket_stat = -1;
|
||
|
int socket_err = -1;
|
||
|
|
||
|
socket_stat = sock_get_errno(mqttContext->mqttClient->ipstack->my_socket);
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_89, P_INFO, 1, "...get socket stat..socket_stat=%d..", socket_stat);
|
||
|
|
||
|
{
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_90, P_INFO, 1, "...start tcp disconnect ..");
|
||
|
rc = mqttContext->mqttClient->ipstack->disconnect(mqttContext->mqttClient->ipstack);
|
||
|
if(rc != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_91, P_INFO, 1, "...tcp disconnect fail!!!.rc=%d..", rc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
{
|
||
|
socket_err = socket_error_is_fatal(socket_stat);
|
||
|
//if(socket_err == 1)
|
||
|
{
|
||
|
//ec_socket_delete_flag = 0xff;
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_92, P_INFO, 1, "...tcp disconnect ok!!!....%d.",socket_err);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_93, P_INFO, 1, "...start tcp connect ...");
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_95, P_INFO, 1, "...tcp connect ok...");
|
||
|
mqttContext->mqttClient->isconnected = 0;
|
||
|
|
||
|
if(mqttContext->mqttsFlag == 0)
|
||
|
{
|
||
|
if((rc = NetworkConnectTimeout(mqttContext->mqttClient->ipstack, mqttContext->mqttUri, mqttContext->port, MQTT_SEND_TIMEOUT, MQTT_RECV_TIMEOUT)) == 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_96, P_INFO, 1, "...start mqtt connect ..");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_97, P_INFO, 1, "...tcp reconnect fail!!!...\r\n");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
mqttContext->mqttsClient->isMqtts = 1;
|
||
|
mqttContext->mqttsClient->ciphersuite[0] = 0xFFFF;
|
||
|
if((rc = mqttSslConn_new(mqttContext->mqttsClient, mqttContext->mqttUri)) == 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_98, P_INFO, 1, "...start mqtt connect ..");
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttReconnect(void *context)
|
||
|
{
|
||
|
int rc = -1;
|
||
|
ctwMqttRegContext_t *mqttContext = (ctwMqttRegContext_t *)context;
|
||
|
int socket_stat = -1;
|
||
|
|
||
|
socket_stat = sock_get_errno(mqttContext->mqttClient->ipstack->my_socket);
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_1, P_INFO, 1, "...get socket stat..socket_stat=%d..", socket_stat);
|
||
|
|
||
|
{
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_2, P_INFO, 1, "...start tcp disconnect ..");
|
||
|
rc = mqttContext->mqttClient->ipstack->disconnect(mqttContext->mqttClient->ipstack);
|
||
|
if(rc != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_3, P_INFO, 1, "...tcp disconnect fail!!!.rc=%d..", rc);
|
||
|
}
|
||
|
}
|
||
|
//vTaskDelay(10000);
|
||
|
{
|
||
|
//socket_stat = sock_get_errno(c->ipstack->my_socket);
|
||
|
//ECOMM_TRACE(UNILOG_CTWING, mqtt_task_10, P_INFO, 1, "...get socket stat..socket_stat=%d..", socket_stat);
|
||
|
//socket_err = socket_error_is_fatal(socket_stat);
|
||
|
//if(socket_err == 1)
|
||
|
{
|
||
|
//ec_socket_delete_flag = 0xff;
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_11, P_INFO, 1, "...tcp disconnect ok!!!...");
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_12, P_INFO, 1, "...start tcp connect ...");
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_14, P_INFO, 1, "...tcp connect ok...");
|
||
|
mqttContext->mqttClient->isconnected = 0;
|
||
|
if((rc = NetworkConnectTimeout(mqttContext->mqttClient->ipstack, mqttContext->mqttUri, mqttContext->port, MQTT_SEND_TIMEOUT, MQTT_RECV_TIMEOUT)) < 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_15, P_INFO, 1, "...tcp reconnect fail!!!...\r\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_16, P_INFO, 1, "...start mqtt connect ..");
|
||
|
|
||
|
if ((rc = ctwMqttConnect(mqttContext, &mqttContext->mqttConnectData)) != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_17, P_INFO, 1, "...mqtt reconnect fial!!!...");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_18, P_INFO, 1, "...mqtt reconnect ok!!!...");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttConnectClient(ctwMqttRegContext_t *mqttContext)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
|
||
|
ctwMqttRegContext_t *mqttNewContext = mqttContext;
|
||
|
|
||
|
if((ret = ctwMqttConnect(mqttNewContext, &mqttNewContext->mqttConnectData)) != 0)
|
||
|
{
|
||
|
ctwMqttReconnectTcp(mqttNewContext);
|
||
|
if((ret = ctwMqttConnect(mqttNewContext, &mqttNewContext->mqttConnectData)) != 0)
|
||
|
{
|
||
|
mqttNewContext->mqttClient->ping_outstanding = 1;
|
||
|
mqttNewContext->mqttNetwork->disconnect(mqttNewContext->mqttNetwork);
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_28, P_INFO, 1, "...mqtt connect fail!!!...\r\n");
|
||
|
return 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_29hh, P_INFO, 1, "...mqtt connect ok!!!...\r\n");
|
||
|
ret = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_task_29, P_INFO, 1, "...mqtt connect ok!!!...\r\n");
|
||
|
ret = 0;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
int ctwMqttKeepaliveCheck(ctwMqttRegContext_t* context)
|
||
|
{
|
||
|
int rc = 0;
|
||
|
|
||
|
//check if curr ticks > last_sent.xTimeOut.xTimeOnEntering + last_sent.xTicksToWait
|
||
|
//check if curr ticks > last_received.xTimeOut.xTimeOnEntering + last_received.xTicksToWait
|
||
|
if (TimerIsExpired(&context->mqttClient->last_sent) || TimerIsExpired(&context->mqttClient->last_received))
|
||
|
{
|
||
|
if (context->mqttClient->ping_outstanding)
|
||
|
{
|
||
|
gCtwMqttKeepaliveRetryTime++;
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_32, P_ERROR, 1, "...mqtt keep alive ping resp timeout...");
|
||
|
rc = FAILURE; /* PINGRESP not received in keepalive interval */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttCycle(ctwMqttRegContext_t* context, Timer* timer)
|
||
|
{
|
||
|
int rc = 0;
|
||
|
MQTTSubackData data;
|
||
|
MQTTConnackData connData;
|
||
|
unsigned short mypacketid;
|
||
|
unsigned char dup, type;
|
||
|
int count = 0;
|
||
|
int socket_stat = -1;
|
||
|
int socket_err = -1;
|
||
|
int mqttQos = 0;
|
||
|
ctwCmdMsg_t ctwMsg;
|
||
|
|
||
|
int packet_type = ctwMqttReadPacket(context, timer); /* read the socket, see what work is due */
|
||
|
|
||
|
data.grantedQoS = QOS0;
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_33, P_INFO, 1, "...mqtt readPacket packet_type=%d...",packet_type);
|
||
|
|
||
|
switch (packet_type)
|
||
|
{
|
||
|
case -2:
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_NOT_CREATE;
|
||
|
goto exit;
|
||
|
case -1:
|
||
|
case 0: /* timed out reading packet */
|
||
|
default:
|
||
|
{
|
||
|
/* no more data to read, unrecoverable. Or read packet fails due to unexpected network error */
|
||
|
socket_stat = sock_get_errno(context->mqttClient->ipstack->my_socket);
|
||
|
socket_err = socket_error_is_fatal(socket_stat);
|
||
|
if(socket_err == 1)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_34, P_INFO, 1, ".....now, need reconnect mqtt server, when read packet...err=%d....",socket_stat);
|
||
|
|
||
|
{
|
||
|
memset(&ctwMsg, 0, sizeof(ctwCmdMsg_t));
|
||
|
ctwMsg.cmd_type = CTW_MQTT_RECONNECT_COMMAND;
|
||
|
|
||
|
osMessageQueuePut(ctwMqttMsgQueue, &ctwMsg, 0, 1000);
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_RECONNECT;
|
||
|
}
|
||
|
rc = 0;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CONNACK:
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_101, P_INFO, 0, ".....now, recv connack.......");
|
||
|
if (MQTTDeserialize_connack(&connData.sessionPresent, &connData.rc, context->mqttClient->readbuf, context->mqttClient->readbuf_size) != 1)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_102hh, P_INFO, 0, ".....send mqtt conn packet fail.......");
|
||
|
rc = FAILURE;
|
||
|
}
|
||
|
/* send result to at task */
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_102, P_INFO, 0, ".....send mqtt conn packet ok.......");
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case PUBACK:
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_35, P_INFO, 0, ".....now, recv puback.......");
|
||
|
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, context->mqttClient->readbuf, context->mqttClient->readbuf_size) != 1)
|
||
|
{
|
||
|
rc = FAILURE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SUBACK:
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_37, P_INFO, 0, ".....now, recv suback.......");
|
||
|
mqttQos = (int)data.grantedQoS;
|
||
|
if (MQTTDeserialize_suback(&mypacketid, 1, &count, (int*)&mqttQos, context->mqttClient->readbuf, context->mqttClient->readbuf_size) == 1)
|
||
|
{
|
||
|
if (data.grantedQoS != 0x80)
|
||
|
{
|
||
|
//rc = MQTTSetMessageHandler(context->mqttClient, context->sub_topic, context->mqttClient->defaultMessageHandler);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = FAILURE;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case UNSUBACK:
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_39, P_INFO, 0, ".....now, recv unsuback.......");
|
||
|
// should be the same as the packetid above
|
||
|
if (MQTTDeserialize_unsuback(&mypacketid, context->mqttClient->readbuf, context->mqttClient->readbuf_size) == 1)
|
||
|
{
|
||
|
/* remove the subscription message handler associated with this topic, if there is one */
|
||
|
//MQTTSetMessageHandler(context->mqttClient, context->unsub_topic, NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = FAILURE;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case PUBLISH:
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_40, P_INFO, 0, ".....now, recv publish.......");
|
||
|
MQTTString topicName;
|
||
|
MQTTMessage msg;
|
||
|
int intQoS;
|
||
|
|
||
|
msg.payloadlen = 0; /* this is a size_t, but deserialize publish sets this as int */
|
||
|
memset(&topicName, 0, sizeof(topicName));
|
||
|
|
||
|
if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
|
||
|
(unsigned char**)&msg.payload, (int*)&msg.payloadlen, context->mqttClient->readbuf, context->mqttClient->readbuf_size) != 1)
|
||
|
goto exit;
|
||
|
msg.qos = (enum QoS)intQoS;
|
||
|
if (msg.qos == QOS1)
|
||
|
{
|
||
|
/* send pub msg to mqtt send task*/
|
||
|
ctwMqttDeliverMessage(context->mqttClient, &topicName, &msg);
|
||
|
memset(&ctwMsg, 0, sizeof(ctwCmdMsg_t));
|
||
|
ctwMsg.cmd_type = CTW_MQTT_PUBLISH_ACK;
|
||
|
ctwMsg.ackMode = PUBACK;
|
||
|
ctwMsg.Qos = QOS1;
|
||
|
ctwMsg.msgId = msg.id;
|
||
|
|
||
|
osMessageQueuePut(ctwMqttMsgQueue, &ctwMsg, 0, 1000);
|
||
|
rc = 0;
|
||
|
}
|
||
|
else if (msg.qos == QOS2)
|
||
|
{
|
||
|
/* send pub msg to mqtt send task*/
|
||
|
ctwMqttDeliverMessage(context->mqttClient, &topicName, &msg);
|
||
|
memset(&ctwMsg, 0, sizeof(ctwCmdMsg_t));
|
||
|
ctwMsg.cmd_type = CTW_MQTT_PUBLISH_REC;
|
||
|
ctwMsg.ackMode = PUBREC;
|
||
|
ctwMsg.Qos = QOS2;
|
||
|
|
||
|
osMessageQueuePut(ctwMqttMsgQueue, &ctwMsg, 0, 1000);
|
||
|
rc = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ctwMqttDeliverMessage(context->mqttClient, &topicName, &msg);
|
||
|
rc = 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case PUBREC:
|
||
|
case PUBREL:
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_41, P_INFO, 0, ".....now, recv pubrec or pubrel.......");
|
||
|
|
||
|
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, context->mqttClient->readbuf, context->mqttClient->readbuf_size) != 1)
|
||
|
{
|
||
|
rc = FAILURE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* send msg to mqtt send task*/
|
||
|
if(PUBREC == packet_type)
|
||
|
{
|
||
|
}
|
||
|
else if(PUBREL == packet_type)
|
||
|
{
|
||
|
}
|
||
|
rc = 0;
|
||
|
}
|
||
|
|
||
|
if (rc == FAILURE)
|
||
|
{
|
||
|
goto exit; // there was a problem
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case PUBCOMP:
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_42, P_INFO, 0, ".....now, recv pubcomp.......");
|
||
|
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, context->mqttClient->readbuf, context->mqttClient->readbuf_size) != 1)
|
||
|
{
|
||
|
rc = FAILURE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case PINGRESP:
|
||
|
{
|
||
|
context->mqttClient->ping_outstanding = 0;
|
||
|
gCtwMqttKeepaliveRetryTime = 0;
|
||
|
/* delete keepalive timer */
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_44, P_INFO, 1, ".....mqtt recv keeplive ack ok.......");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(socket_err == 1)
|
||
|
{
|
||
|
rc = -1;
|
||
|
socket_err = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc = ctwMqttKeepaliveCheck(context);
|
||
|
}
|
||
|
|
||
|
if(rc == 0)
|
||
|
{
|
||
|
/* not need send keepalive packet */
|
||
|
}
|
||
|
else if(rc == 1)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_45, P_INFO, 0, ".....now, need keepalive.......");
|
||
|
/* need send keepalive packet, send keepalive msg to send task */
|
||
|
memset(&ctwMsg, 0, sizeof(ctwCmdMsg_t));
|
||
|
ctwMsg.cmd_type = CTW_MQTT_KEEPALIVE_COMMAND;
|
||
|
|
||
|
osMessageQueuePut(ctwMqttMsgQueue, &ctwMsg, 0, 1000);
|
||
|
rc = 0;
|
||
|
}
|
||
|
else if(rc == FAILURE)
|
||
|
{
|
||
|
/* keepalive fail */
|
||
|
int socket_stat = 0;
|
||
|
|
||
|
socket_stat = sock_get_errno(context->mqttClient->ipstack->my_socket);
|
||
|
if((socket_stat == MQTT_ERR_ABRT)||(socket_stat == MQTT_ERR_RST)||(socket_stat == MQTT_ERR_CLSD)||(socket_stat == MQTT_ERR_BADE))
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_46, P_INFO, 0, ".....err, now, need reconnect.......");
|
||
|
/* send reconnect msg to send task */
|
||
|
memset(&ctwMsg, 0, sizeof(ctwCmdMsg_t));
|
||
|
ctwMsg.cmd_type = CTW_MQTT_RECONNECT_COMMAND;
|
||
|
|
||
|
osMessageQueuePut(ctwMqttMsgQueue, &ctwMsg, 0, 1000);
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_RECONNECT;
|
||
|
rc = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(gCtwMqttKeepaliveRetryTime > MQTT_REG_KEEPALIVE_RETRY_MAX)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_47, P_INFO, 0, ".....now, need reconnect.......");
|
||
|
/* send reconnect msg to send task */
|
||
|
gCtwMqttKeepaliveRetryTime = 0;
|
||
|
memset(&ctwMsg, 0, sizeof(ctwCmdMsg_t));
|
||
|
ctwMsg.cmd_type = CTW_MQTT_RECONNECT_COMMAND;
|
||
|
|
||
|
osMessageQueuePut(ctwMqttMsgQueue, &ctwMsg, 0, 1000);
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_RECONNECT;
|
||
|
rc = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_CTWING, mqtt_msg_48, P_INFO, 0, ".....return err, now, need keepalive.......");
|
||
|
/* send keepalive msg to send task */
|
||
|
MQTTSerialize_pingreq(context->mqttClient->buf, context->mqttClient->buf_size);
|
||
|
memset(&ctwMsg, 0, sizeof(ctwCmdMsg_t));
|
||
|
ctwMsg.cmd_type = CTW_MQTT_KEEPALIVE_COMMAND;
|
||
|
|
||
|
osMessageQueuePut(ctwMqttMsgQueue, &ctwMsg, 0, 1000);
|
||
|
rc = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
if (rc == 0)
|
||
|
{
|
||
|
rc = packet_type;
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int ctwMqttYield(ctwMqttRegContext_t* context, int timeout_ms)
|
||
|
{
|
||
|
int rc = 0;
|
||
|
Timer timer;
|
||
|
|
||
|
TimerInit(&timer);
|
||
|
TimerCountdownMS(&timer, timeout_ms);
|
||
|
|
||
|
do
|
||
|
{
|
||
|
if (ctwMqttCycle(context, &timer) < 0)
|
||
|
{
|
||
|
rc = FAILURE;
|
||
|
break;
|
||
|
}
|
||
|
} while (!TimerIsExpired(&timer));
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
uint8_t ctwMqttAuthReg(ctwMqttRegContext_t* pMqttClient, MWNvmCfgCtwMqttParam* pCtwMqttParam, ctwMqttRegParam_t* pRegParam)
|
||
|
{
|
||
|
UINT32 result = MQTT_CTW_OK;
|
||
|
CHAR rsrp[32] = {0};
|
||
|
CHAR snr[32] = {0};
|
||
|
CHAR txPower[32] = {0};
|
||
|
CHAR phyCellId[32] = {0};
|
||
|
|
||
|
MWNvmCfgCtwMqttParam ctwMqttParam = {0};
|
||
|
mwNvmCfgGetCtwMqttParam(&ctwMqttParam);
|
||
|
|
||
|
MWNvmCfgCtwParamCfg ctwParamCfg = {0};
|
||
|
mwNvmCfgGetCtwParamConfig(&ctwParamCfg);
|
||
|
|
||
|
memset(gCtwMqttContext.mqttSendBuf, 0, MQTT_REG_SEND_BUF_SIZE);
|
||
|
|
||
|
if(gCtwMqttContext.mqttConnectData.clientID.cstring == NULL)
|
||
|
{
|
||
|
gCtwMqttContext.mqttConnectData.clientID.cstring = mallocEc(MQTT_REG_AUTH_CLIENT_SIZE);
|
||
|
}
|
||
|
if(gCtwMqttContext.mqttConnectData.username.cstring == NULL)
|
||
|
{
|
||
|
gCtwMqttContext.mqttConnectData.username.cstring = mallocEc(MQTT_REG_AUTH_USERNAME_SIZE);
|
||
|
}
|
||
|
if(gCtwMqttContext.mqttConnectData.password.cstring == NULL)
|
||
|
{
|
||
|
gCtwMqttContext.mqttConnectData.password.cstring = mallocEc(MQTT_REG_AUTH_PWD_SIZE);
|
||
|
}
|
||
|
|
||
|
memset(gCtwMqttContext.mqttConnectData.clientID.cstring, 0, MQTT_REG_AUTH_CLIENT_SIZE);
|
||
|
memset(gCtwMqttContext.mqttConnectData.username.cstring, 0, MQTT_REG_AUTH_USERNAME_SIZE);
|
||
|
memset(gCtwMqttContext.mqttConnectData.password.cstring, 0, MQTT_REG_AUTH_PWD_SIZE);
|
||
|
|
||
|
memcpy(gCtwMqttContext.mqttConnectData.clientID.cstring, ctwMqttParam.clientId, strlen(ctwMqttParam.clientId));
|
||
|
memcpy(gCtwMqttContext.mqttConnectData.password.cstring, ctwMqttParam.password, strlen(ctwMqttParam.password));
|
||
|
|
||
|
atDataToDecString((UINT8 *)rsrp, 32, (INT64)(pRegParam->rsrp));
|
||
|
atDataToDecString((UINT8 *)snr, 32, (INT64)(pRegParam->snr));
|
||
|
atDataToDecString((UINT8 *)txPower, 32, (INT64)(pRegParam->txPower));
|
||
|
atDataToDecString((UINT8 *)phyCellId, 32, (INT64)(pRegParam->phyCellId));
|
||
|
|
||
|
snprintf(gCtwMqttContext.mqttConnectData.username.cstring, MQTT_REG_AUTH_USERNAME_SIZE,
|
||
|
"%02d%s%02d%s%02d%s%02d%s%02d%s%02d%s%02d%s%02d%s%02d%s%02d%s",
|
||
|
strlen(ctwParamCfg.module),ctwParamCfg.module, strlen(ctwParamCfg.chipType),ctwParamCfg.chipType, strlen(ctwParamCfg.softVersion),ctwParamCfg.softVersion,
|
||
|
strlen(pRegParam->imei),pRegParam->imei, strlen(pRegParam->iccid),pRegParam->iccid, strlen(pRegParam->imsi),pRegParam->imsi, strlen(rsrp),rsrp,
|
||
|
strlen(snr),snr, strlen(txPower),txPower, strlen(phyCellId),phyCellId);
|
||
|
|
||
|
ctwMqttConnectClient(&gCtwMqttContext);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
#define MQTT_REG_SEND_RECVTASK_START
|
||
|
|
||
|
void ctwMqttRegisterRecvTask(void *argument)
|
||
|
{
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_CREATE;
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
ctwMqttYield(&gCtwMqttContext, 2000);
|
||
|
|
||
|
if(ctwMqttRecvStatusFlag == MQTT_CTW_RECV_TASK_NOT_CREATE)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(ctwMqttRecvStatusFlag == MQTT_CTW_RECV_TASK_RECONNECT)
|
||
|
{
|
||
|
ctwMqttReconnectStatusFlag = 0x1;
|
||
|
break;
|
||
|
}
|
||
|
osDelay(100);
|
||
|
}
|
||
|
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_DELETE;
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
void ctwMqttStartRegisterRecvTask(void)
|
||
|
{
|
||
|
osThreadAttr_t task_attr;
|
||
|
|
||
|
memset(&task_attr, 0, sizeof(task_attr));
|
||
|
task_attr.name = "mtCtwRecv";
|
||
|
task_attr.stack_size = MQTT_REG_RECV_TASK_STACK_SIZE;
|
||
|
task_attr.priority = osPriorityNormal;
|
||
|
#ifdef TYPE_EC718M
|
||
|
task_attr.reserved = osThreadDynamicStackAlloc;
|
||
|
#endif
|
||
|
|
||
|
osThreadNew(ctwMqttRegisterRecvTask, NULL,&task_attr);
|
||
|
}
|
||
|
|
||
|
static void ctwMqttRegisterSendTask(void *arg)
|
||
|
{
|
||
|
UINT32 result = 0xff;
|
||
|
UINT32 ret = 0xff;
|
||
|
UINT32 retry = 0;
|
||
|
ctwCmdMsg_t msg;
|
||
|
//ctwCnfCmdMsg_t cnfMsg;
|
||
|
//int primSize = sizeof(cnfMsg);
|
||
|
char logbuf[64] = {0};
|
||
|
int len = 0;
|
||
|
int i = 0;
|
||
|
Timer timer;
|
||
|
NmAtiNetifInfo netInfo;
|
||
|
|
||
|
ctwMqttContextConfig(&gCtwMqttContext);
|
||
|
gCtwMqttContext.mqttsFlag = pCtwMqttParam->mqttsFlag;
|
||
|
if(ctwMqttMsgQueue == NULL)
|
||
|
{
|
||
|
ctwMqttMsgQueue = osMessageQueueNew(16, sizeof(ctwCmdMsg_t), NULL);
|
||
|
}
|
||
|
ctwMqttStatusFlag = MQTT_CTW_SEND_TASK_CREATE;
|
||
|
ctwMqttStaMachine = MQTT_INIT_STATE;
|
||
|
|
||
|
while (ctwMqttStatusFlag)
|
||
|
{
|
||
|
snprintf(logbuf,64,"%s",CTW_MQTT_MACHINESTATE(ctwMqttStaMachine));
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttRegisterTask_0, P_INFO, "handle ctwMqttStaMachine:%s", (uint8_t *)logbuf);
|
||
|
|
||
|
switch(ctwMqttStaMachine)
|
||
|
{
|
||
|
case MQTT_INIT_STATE:
|
||
|
osDelay(500/portTICK_PERIOD_MS);
|
||
|
if(CTW_MQTT_RECONNECT_COMMAND != msg.cmd_type)
|
||
|
{
|
||
|
osMessageQueueReset(ctwMqttMsgQueue);
|
||
|
}
|
||
|
ctwMqttCheckIfNeedExit(0);
|
||
|
|
||
|
appGetNetInfoSync(0, &netInfo);
|
||
|
if((netInfo.netStatus == NM_NETIF_ACTIVATED)&&((netInfo.ipType == NM_NET_TYPE_IPV4)||(netInfo.ipType == NM_NET_TYPE_IPV6)||(netInfo.ipType == NM_NET_TYPE_IPV4V6)))
|
||
|
{
|
||
|
ctwMqttStaMachine = MQTT_IPREADY_STATE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MQTT_IPREADY_STATE:
|
||
|
ctwMqttGetInvariPara();
|
||
|
ctwMqttCheckIfNeedExit(0);
|
||
|
ctwMqttStaMachine = MQTT_REG_STATE;
|
||
|
break;
|
||
|
|
||
|
case MQTT_REG_STATE: //to regisater
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttRegisterTask_1, P_INFO, "read variable parameters and send register mqtt request");
|
||
|
ctwMqttGetVariPara();
|
||
|
NetworkInit(gCtwMqttContext.mqttNetwork);
|
||
|
ctwMqttClientInit(&gCtwMqttContext, gCtwMqttContext.mqttNetwork, (unsigned char *)gCtwMqttContext.mqttSendBuf, MQTT_REG_SEND_BUF_SIZE, (unsigned char *)gCtwMqttContext.mqttReadBuf, MQTT_REG_READ_BUF_SIZE);
|
||
|
memcpy(gCtwMqttContext.mqttRegParam->host, gCtwMqttContext.mqttUri, MQTT_REG_URI_MAX_LEN);
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_1_1, P_INFO, "host:%s", gCtwMqttContext.mqttUri);
|
||
|
|
||
|
if(pCtwMqttParam->mqttsFlag == 0)
|
||
|
{
|
||
|
strcpy(gCtwMqttContext.mqttUri, pCtwMqttParam->uri);
|
||
|
gCtwMqttContext.port = pCtwMqttParam->port;
|
||
|
|
||
|
if((ret = NetworkConnectTimeout(gCtwMqttContext.mqttNetwork, gCtwMqttContext.mqttUri, gCtwMqttContext.port, 3000, 3000)) == 0)
|
||
|
{
|
||
|
result = MQTT_CTW_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#ifdef FEATURE_MQTT_TLS_ENABLE
|
||
|
strcpy(gCtwMqttContext.mqttUri, pCtwMqttParam->uri);
|
||
|
|
||
|
gCtwMqttContext.mqttsClient->isMqtts = 1;
|
||
|
gCtwMqttContext.mqttsClient->ciphersuite[0] = 0xFFFF;
|
||
|
gCtwMqttContext.mqttsClient->port = pCtwMqttParam->port;
|
||
|
|
||
|
if((ret = mqttSslConn_new(gCtwMqttContext.mqttsClient, gCtwMqttContext.mqttUri)) == 0)
|
||
|
{
|
||
|
result = MQTT_CTW_OK;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (result == MQTT_CTW_OK)
|
||
|
{
|
||
|
ctwMqttStartRegisterRecvTask();
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_1_3, P_INFO, "mqttConnect ok");
|
||
|
result = ctwMqttAuthReg(&gCtwMqttContext, pCtwMqttParam, gCtwMqttContext.mqttRegParam);
|
||
|
if(result == MQTT_CTW_OK)
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_2, P_INFO, "auth reg success goto KEEP ONLINE state");
|
||
|
pCtwMqttParam->autoRegStatus = 1; //register ok
|
||
|
mwNvmCfgSetAndSaveCtwMqttParam(pCtwMqttParam);
|
||
|
ctwMqttStaMachine = MQTT_KEEP_ONLINE_STATE;
|
||
|
//osDelay(590000/portTICK_PERIOD_MS);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(retry < 3)
|
||
|
{
|
||
|
retry++;
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_3, P_INFO, "connect ctwing failed try again after 1 min");
|
||
|
osDelay(60000/portTICK_PERIOD_MS);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_3_1, P_INFO, "connect fail exit task");
|
||
|
pCtwMqttParam->autoRegStatus = 0; //register fail
|
||
|
mwNvmCfgSetAndSaveCtwMqttParam(pCtwMqttParam);
|
||
|
ctwMqttStatusFlag = MQTT_CTW_SEND_TASK_NOT_CREATE;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case MQTT_KEEP_ONLINE_STATE:
|
||
|
memset(&msg, 0, sizeof(msg));
|
||
|
osMessageQueueGet(ctwMqttMsgQueue, &msg, 0, osWaitForever);
|
||
|
|
||
|
MQTTMessage message = {0};
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_5, P_INFO, "cmd state %d", msg.cmd_type);
|
||
|
switch(msg.cmd_type)
|
||
|
{
|
||
|
case CTW_MQTT_SEND_COMMAND:
|
||
|
memset(gCtwMqttContext.mqttSendBuf, 0, MQTT_REG_SEND_BUF_SIZE);
|
||
|
message.payload = msg.data;
|
||
|
message.payloadlen = msg.datalen;
|
||
|
message.qos = msg.Qos;
|
||
|
if(msg.fotaFlag == 1)
|
||
|
{
|
||
|
//to add fota param;
|
||
|
gCtwMqttContext.fotaFlag = 1;
|
||
|
}
|
||
|
ret = ctwMqttPublish(&gCtwMqttContext, 0, msg.topic, &message, 1, false);
|
||
|
|
||
|
if(msg.topic != NULL)
|
||
|
{
|
||
|
freeEc(msg.topic);
|
||
|
msg.topic = NULL;
|
||
|
}
|
||
|
if(msg.data != NULL)
|
||
|
{
|
||
|
freeEc(msg.data);
|
||
|
msg.data = NULL;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CTW_MQTT_FOTA_UPDATA_COMMAND:
|
||
|
memset(gCtwMqttContext.mqttSendBuf, 0, MQTT_REG_SEND_BUF_SIZE);
|
||
|
message.payload = mallocEc(CTW_MQTT_FOTA_ACK_MAX_LEN);
|
||
|
memset(message.payload, 0, CTW_MQTT_FOTA_ACK_MAX_LEN);
|
||
|
snprintf(message.payload, CTW_MQTT_FOTA_ACK_MAX_LEN, "{\"taskId\":%s,\"params\":{\"step\":100,\"desc\":\"ok\",\"module\":\"%s\"}}", pCtwMqttParam->fotaTaskId, pCtwMqttParam->fotaModule);
|
||
|
message.payloadlen = strlen(message.payload);
|
||
|
message.qos = 1;
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_fota, P_INFO, "payload.. %s", message.payload);
|
||
|
ret = ctwMqttPublish(&gCtwMqttContext, 0, CTW_MQTT_FOTA_PROGRESS_TOPIC, &message, 1, false);
|
||
|
|
||
|
memset(gCtwMqttContext.mqttSendBuf, 0, MQTT_REG_SEND_BUF_SIZE);
|
||
|
message.payload = mallocEc(CTW_MQTT_FOTA_ACK_MAX_LEN);
|
||
|
memset(message.payload, 0, CTW_MQTT_FOTA_ACK_MAX_LEN);
|
||
|
snprintf(message.payload, CTW_MQTT_FOTA_ACK_MAX_LEN, "{\"taskId\":%s,\"params\":{\"version\":\"%s\",\"module\":\"%s\"}}", pCtwMqttParam->fotaTaskId, pCtwMqttParam->fotaVersion, pCtwMqttParam->fotaModule);
|
||
|
message.payloadlen = strlen(message.payload);
|
||
|
message.qos = 1;
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_fota1, P_INFO, "payload.. %s", message.payload);
|
||
|
ret = ctwMqttPublish(&gCtwMqttContext, 0, CTW_MQTT_FOTA_ACK_TOPIC, &message, 1, false);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CTW_MQTT_DEREG_COMMAND:
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_dereg, P_INFO, "start dereg.. recvStatus=%d..sendStatus=%d",ctwMqttRecvStatusFlag,ctwMqttStatusFlag);
|
||
|
if(ctwMqttRecvStatusFlag == MQTT_CTW_RECV_TASK_CREATE)
|
||
|
{
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_NOT_CREATE;
|
||
|
}
|
||
|
|
||
|
if(ctwMqttRecvStatusFlag == MQTT_CTW_RECV_TASK_RECONNECT)
|
||
|
{
|
||
|
//osMessageQueueReset(ctwMqttMsgQueue);
|
||
|
ctwMqttRecvStatusFlag = MQTT_CTW_RECV_TASK_NOT_CREATE;
|
||
|
}
|
||
|
|
||
|
for(i=0; i<20; i++)
|
||
|
{
|
||
|
if(ctwMqttRecvStatusFlag == MQTT_CTW_RECV_TASK_DELETE)
|
||
|
{
|
||
|
ret = ctwMqttDisconnect(&gCtwMqttContext);
|
||
|
//if(ret == SUCCESS)
|
||
|
{
|
||
|
ret = ctwMqttClose(&gCtwMqttContext);
|
||
|
if(ret == SUCCESS)
|
||
|
{
|
||
|
ctwMqttStatusFlag = MQTT_CTW_SEND_TASK_NOT_CREATE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
osDelay(500);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CTW_MQTT_KEEPALIVE_COMMAND:
|
||
|
ret = ctwMqttKeepalive(&gCtwMqttContext);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CTW_MQTT_RECONNECT_COMMAND:
|
||
|
for(i=0; i<10; i++)
|
||
|
{
|
||
|
if(ctwMqttReconnectStatusFlag == 1)
|
||
|
{
|
||
|
ctwMqttReconnectStatusFlag = 0;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
osDelay(500);
|
||
|
}
|
||
|
}
|
||
|
ret = ctwMqttDisconnect(&gCtwMqttContext);
|
||
|
//if(ret == SUCCESS)
|
||
|
{
|
||
|
ret = ctwMqttClose(&gCtwMqttContext);
|
||
|
}
|
||
|
ctwMqttStaMachine = MQTT_INIT_STATE;
|
||
|
break;
|
||
|
|
||
|
case CTW_MQTT_PUBLISH_ACK:
|
||
|
len = MQTTSerialize_ack(gCtwMqttContext.mqttClient->buf, gCtwMqttContext.mqttClient->buf_size, msg.ackMode, 0, msg.msgId);
|
||
|
TimerInit(&timer);
|
||
|
TimerCountdownMS(&timer, 2000);
|
||
|
|
||
|
ret = ctwMqttSendPacket(&gCtwMqttContext, len, &timer, 0, false);
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_6, P_INFO, "unknown state %d", msg.cmd_type);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStatusTask_7, P_INFO, "unknown state exit status task");
|
||
|
ctwMqttStatusFlag = MQTT_CTW_SEND_TASK_NOT_CREATE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ctwMqttCheckIfNeedExit(1);
|
||
|
}
|
||
|
|
||
|
static void ctwMqttStartRegisterTask()
|
||
|
{
|
||
|
osThreadAttr_t task_attr;
|
||
|
memset(&task_attr,0,sizeof(task_attr));
|
||
|
task_attr.name = "mtCtw";
|
||
|
task_attr.stack_size = MQTT_REG_TASK_STACK_SIZE;
|
||
|
task_attr.priority = osPriorityNormal1;
|
||
|
#ifdef TYPE_EC718M
|
||
|
task_attr.reserved = osThreadDynamicStackAlloc;
|
||
|
#endif
|
||
|
|
||
|
ctwMqttStatusFlag = MQTT_CTW_SEND_TASK_CREATE;
|
||
|
ECPLAT_PRINTF(UNILOG_CTWING, ctwMqttStartStatusTask_1, P_INFO, "start mqtt status task");
|
||
|
|
||
|
osThreadNew(ctwMqttRegisterSendTask, NULL, &task_attr);
|
||
|
}
|
||
|
#define MQTT_REG_SEND_RECVTASK_END
|
||
|
|
||
|
void ctwMqttRegisterInit(MWNvmCfgCtwMqttParam* ctwMqttParam)
|
||
|
{
|
||
|
slpManApplyPlatVoteHandle("CTW_MQTT",&ctwMqttSlpHandler);
|
||
|
|
||
|
slpManPlatVoteDisableSleep(ctwMqttSlpHandler, SLP_SLP2_STATE);
|
||
|
//ctwMqttCheckIfNeedExit();
|
||
|
registerPSEventCallback(PS_GROUP_ALL_MASK, ctwMqttPSUrcCallback);
|
||
|
pCtwMqttParam = ctwMqttParam;
|
||
|
configASSERT(pCtwMqttParam != NULL);
|
||
|
|
||
|
ctwMqttStartRegisterTask();
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|