fix:修改UDP通讯中,取电变化上报机制
1、问题点:当RCU网络状态异常的情况下,网络还处于协商状态下,还未进入正常通讯环节时,取电变化不会进行判断。这会导致取电变化上报与实际产生取电状态时间点对不上。 2、将BLV_C1F_Module代码上传至Gitea,之前代码修改记录请查看 .\BasicCode\Readme.txt
This commit is contained in:
119
BasicCode/Drive/MQTT/MQTT_SRC/MQTTConnect.h
Normal file
119
BasicCode/Drive/MQTT/MQTT_SRC/MQTTConnect.h
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef MQTTCONNECT_H_
|
||||
#define MQTTCONNECT_H_
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned char all; /**< all connect flags */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int username : 1; /**< 3.1 user name */
|
||||
unsigned int password : 1; /**< 3.1 password */
|
||||
unsigned int willRetain : 1; /**< will retain setting */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
unsigned int will : 1; /**< will flag */
|
||||
unsigned int cleansession : 1; /**< clean session flag */
|
||||
unsigned int : 1; /**< unused */
|
||||
} bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
unsigned int : 1; /**< unused */
|
||||
unsigned int cleansession : 1; /**< cleansession flag */
|
||||
unsigned int will : 1; /**< will flag */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
unsigned int willRetain : 1; /**< will retain setting */
|
||||
unsigned int password : 1; /**< 3.1 password */
|
||||
unsigned int username : 1; /**< 3.1 user name */
|
||||
} bits;
|
||||
#endif
|
||||
} MQTTConnectFlags; /**< connect flags byte */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Defines the MQTT "Last Will and Testament" (LWT) settings for
|
||||
* the connect packet.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** The eyecatcher for this structure. must be MQTW. */
|
||||
char struct_id[4];
|
||||
/** The version number of this structure. Must be 0 */
|
||||
int struct_version;
|
||||
/** The LWT topic to which the LWT message will be published. */
|
||||
MQTTString topicName;
|
||||
/** The LWT payload. */
|
||||
MQTTString message;
|
||||
/**
|
||||
* The retained flag for the LWT message (see MQTTAsync_message.retained).
|
||||
*/
|
||||
unsigned char retained;
|
||||
/**
|
||||
* The quality of service setting for the LWT message (see
|
||||
* MQTTAsync_message.qos and @ref qos).
|
||||
*/
|
||||
char qos;
|
||||
} MQTTPacket_willOptions;
|
||||
|
||||
|
||||
#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 }
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/** The eyecatcher for this structure. must be MQTC. */
|
||||
char struct_id[4];
|
||||
/** The version number of this structure. Must be 0 */
|
||||
int struct_version;
|
||||
/** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1
|
||||
*/
|
||||
unsigned char MQTTVersion;
|
||||
MQTTString clientID;
|
||||
unsigned short keepAliveInterval;
|
||||
unsigned char cleansession;
|
||||
unsigned char willFlag;
|
||||
MQTTPacket_willOptions will;
|
||||
MQTTString username;
|
||||
MQTTString password;
|
||||
} MQTTPacket_connectData;
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned char all; /**< all connack flags */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int reserved : 7; /**< unused */
|
||||
unsigned int sessionpresent : 1; /**< session present flag */
|
||||
} bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
unsigned int sessionpresent : 1; /**< session present flag */
|
||||
unsigned int reserved: 7; /**< unused */
|
||||
} bits;
|
||||
#endif
|
||||
} MQTTConnackFlags; /**< connack flags byte */
|
||||
|
||||
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
|
||||
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
|
||||
|
||||
DLLExport int MQTTSerialize_connect(unsigned char* buf , int buflen, MQTTPacket_connectData* options);
|
||||
DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent);
|
||||
DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen);
|
||||
|
||||
DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen);
|
||||
DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen);
|
||||
|
||||
#endif /* MQTTCONNECT_H_ */
|
||||
200
BasicCode/Drive/MQTT/MQTT_SRC/MQTTConnectClient.c
Normal file
200
BasicCode/Drive/MQTT/MQTT_SRC/MQTTConnectClient.c
Normal file
@@ -0,0 +1,200 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Determines the length of the MQTT connect packet that would be produced using the supplied connect options.
|
||||
* @param options the options to be used to build the connect packet
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_connectLength(MQTTPacket_connectData* options)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
|
||||
if (options->MQTTVersion == 3)
|
||||
len = 12; /* variable depending on MQTT or MQIsdp */
|
||||
else if (options->MQTTVersion == 4)
|
||||
len = 10;
|
||||
|
||||
len += MQTTstrlen(options->clientID)+2;
|
||||
if (options->willFlag)
|
||||
len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2;
|
||||
if (options->username.cstring || options->username.lenstring.data)
|
||||
len += MQTTstrlen(options->username)+2;
|
||||
if (options->password.cstring || options->password.lenstring.data)
|
||||
len += MQTTstrlen(options->password)+2;
|
||||
|
||||
FUNC_EXIT_RC(len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the connect options into the buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param len the length in bytes of the supplied buffer
|
||||
* @param options the options to be used to build the connect packet
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options)
|
||||
{
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
MQTTConnectFlags flags = {0};
|
||||
int len = 0;
|
||||
int rc = -1;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
printf("exit\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.byte = 0;
|
||||
header.bits.type = CONNECT;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, len); /* write remaining length */
|
||||
|
||||
if (options->MQTTVersion == 4)
|
||||
{
|
||||
writeCString(&ptr, "MQTT");
|
||||
writeChar(&ptr, (char) 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeCString(&ptr, "MQIsdp");
|
||||
writeChar(&ptr, (char) 3);
|
||||
}
|
||||
|
||||
flags.all = 0;
|
||||
flags.bits.cleansession = options->cleansession;
|
||||
flags.bits.will = (options->willFlag) ? 1 : 0;
|
||||
if (flags.bits.will)
|
||||
{
|
||||
flags.bits.willQoS = options->will.qos;
|
||||
flags.bits.willRetain = options->will.retained;
|
||||
}
|
||||
|
||||
if (options->username.cstring || options->username.lenstring.data)
|
||||
flags.bits.username = 1;
|
||||
if (options->password.cstring || options->password.lenstring.data)
|
||||
flags.bits.password = 1;
|
||||
|
||||
writeChar(&ptr, flags.all);
|
||||
writeInt(&ptr, options->keepAliveInterval);
|
||||
writeMQTTString(&ptr, options->clientID);
|
||||
if (options->willFlag)
|
||||
{
|
||||
writeMQTTString(&ptr, options->will.topicName);
|
||||
writeMQTTString(&ptr, options->will.message);
|
||||
}
|
||||
if (flags.bits.username)
|
||||
writeMQTTString(&ptr, options->username);
|
||||
if (flags.bits.password)
|
||||
writeMQTTString(&ptr, options->password);
|
||||
|
||||
rc = ptr - buf;
|
||||
|
||||
exit: FUNC_EXIT_RC(rc);
|
||||
printf("rc=%d\n",rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into connack data - return code
|
||||
* @param sessionPresent the session present flag returned (only for MQTT 3.1.1)
|
||||
* @param connack_rc returned integer value of the connack return code
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param len the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen)
|
||||
{
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen;
|
||||
MQTTConnackFlags flags = {0};
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != CONNACK)
|
||||
goto exit;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
if (enddata - curdata < 2)
|
||||
goto exit;
|
||||
|
||||
flags.all = readChar(&curdata);
|
||||
*sessionPresent = flags.bits.sessionpresent;
|
||||
*connack_rc = readChar(&curdata);
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a 0-length packet into the supplied buffer, ready for writing to a socket
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
|
||||
* @param packettype the message type
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype)
|
||||
{
|
||||
MQTTHeader header = {0};
|
||||
int rc = -1;
|
||||
unsigned char *ptr = buf;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (buflen < 2)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
header.byte = 0;
|
||||
header.bits.type = packettype;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_disconnect(unsigned char* buf, int buflen)
|
||||
{
|
||||
return MQTTSerialize_zero(buf, buflen, DISCONNECT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_pingreq(unsigned char* buf, int buflen)
|
||||
{
|
||||
return MQTTSerialize_zero(buf, buflen, PINGREQ);
|
||||
}
|
||||
91
BasicCode/Drive/MQTT/MQTT_SRC/MQTTDeserializePublish.c
Normal file
91
BasicCode/Drive/MQTT/MQTT_SRC/MQTTDeserializePublish.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
#include <string.h>
|
||||
|
||||
#define min(a, b) ((a < b) ? 1 : 0)
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into publish data
|
||||
* @param dup returned integer - the MQTT dup flag
|
||||
* @param qos returned integer - the MQTT QoS value
|
||||
* @param retained returned integer - the MQTT retained flag
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param topicName returned MQTTString - the MQTT topic in the publish
|
||||
* @param payload returned byte buffer - the MQTT publish payload
|
||||
* @param payloadlen returned integer - the length of the MQTT payload
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success
|
||||
*/
|
||||
int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
|
||||
unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen)
|
||||
{
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != PUBLISH)
|
||||
goto exit;
|
||||
*dup = header.bits.dup;
|
||||
*qos = header.bits.qos;
|
||||
*retained = header.bits.retain;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
|
||||
if (!readMQTTLenString(topicName, &curdata, enddata) ||
|
||||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
|
||||
goto exit;
|
||||
|
||||
if (*qos > 0)
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
*payloadlen = enddata - curdata;
|
||||
*payload = curdata;
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into an ack
|
||||
* @param packettype returned integer - the MQTT packet type
|
||||
* @param dup returned integer - the MQTT dup flag
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen)
|
||||
{
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
*dup = header.bits.dup;
|
||||
*packettype = header.bits.type;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
|
||||
if (enddata - curdata < 2)
|
||||
goto exit;
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
246
BasicCode/Drive/MQTT/MQTT_SRC/MQTTFormat.c
Normal file
246
BasicCode/Drive/MQTT/MQTT_SRC/MQTTFormat.c
Normal file
@@ -0,0 +1,246 @@
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
const char* MQTTPacket_names[] =
|
||||
{
|
||||
"RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
|
||||
"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
|
||||
"PINGREQ", "PINGRESP", "DISCONNECT"
|
||||
};
|
||||
|
||||
|
||||
const char* MQTTPacket_getName(unsigned short packetid)
|
||||
{
|
||||
return MQTTPacket_names[packetid];
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)
|
||||
{
|
||||
int strindex = 0;
|
||||
|
||||
strindex = snprintf(strbuf, strbuflen,
|
||||
"CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
|
||||
(int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
|
||||
(int)data->cleansession, data->keepAliveInterval);
|
||||
if (data->willFlag)
|
||||
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
|
||||
", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
|
||||
data->will.qos, data->will.retained,
|
||||
data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
|
||||
data->will.message.lenstring.len, data->will.message.lenstring.data);
|
||||
if (data->username.lenstring.data && data->username.lenstring.len > 0)
|
||||
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
|
||||
", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
|
||||
if (data->password.lenstring.data && data->password.lenstring.len > 0)
|
||||
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
|
||||
", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)
|
||||
{
|
||||
int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
|
||||
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)
|
||||
{
|
||||
int strindex = snprintf(strbuf, strbuflen,
|
||||
"PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
|
||||
dup, qos, retained, packetid,
|
||||
(topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
|
||||
payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
|
||||
{
|
||||
int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
|
||||
if (dup)
|
||||
strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
|
||||
return strindex;
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
|
||||
MQTTString topicFilters[], int requestedQoSs[])
|
||||
{
|
||||
return snprintf(strbuf, strbuflen,
|
||||
"SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
|
||||
dup, packetid, count,
|
||||
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
|
||||
requestedQoSs[0]);
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)
|
||||
{
|
||||
return snprintf(strbuf, strbuflen,
|
||||
"SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
|
||||
}
|
||||
|
||||
|
||||
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[])
|
||||
{
|
||||
return snprintf(strbuf, strbuflen,
|
||||
"UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
|
||||
dup, packetid, count,
|
||||
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
|
||||
}
|
||||
|
||||
|
||||
#if defined(MQTT_CLIENT)
|
||||
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
|
||||
{
|
||||
int index = 0;
|
||||
int rem_length = 0;
|
||||
MQTTHeader header = {0};
|
||||
int strindex = 0;
|
||||
|
||||
header.byte = buf[index++];
|
||||
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
|
||||
|
||||
switch (header.bits.type)
|
||||
{
|
||||
|
||||
case CONNACK:
|
||||
{
|
||||
unsigned char sessionPresent, connack_rc;
|
||||
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
|
||||
}
|
||||
break;
|
||||
case PUBLISH:
|
||||
{
|
||||
unsigned char dup, retained, *payload;
|
||||
unsigned short packetid;
|
||||
int qos, payloadlen;
|
||||
MQTTString topicName = MQTTString_initializer;
|
||||
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
|
||||
&payload, &payloadlen, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
|
||||
topicName, payload, payloadlen);
|
||||
}
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
{
|
||||
unsigned char packettype, dup;
|
||||
unsigned short packetid;
|
||||
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
|
||||
}
|
||||
break;
|
||||
case SUBACK:
|
||||
{
|
||||
unsigned short packetid;
|
||||
int maxcount = 1, count = 0;
|
||||
int grantedQoSs[1];
|
||||
if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
|
||||
}
|
||||
break;
|
||||
case UNSUBACK:
|
||||
{
|
||||
unsigned short packetid;
|
||||
if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
|
||||
}
|
||||
break;
|
||||
case PINGREQ:
|
||||
case PINGRESP:
|
||||
case DISCONNECT:
|
||||
strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
|
||||
break;
|
||||
}
|
||||
return strbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MQTT_SERVER)
|
||||
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
|
||||
{
|
||||
int index = 0;
|
||||
int rem_length = 0;
|
||||
MQTTHeader header = {0};
|
||||
int strindex = 0;
|
||||
|
||||
header.byte = buf[index++];
|
||||
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
|
||||
|
||||
switch (header.bits.type)
|
||||
{
|
||||
case CONNECT:
|
||||
{
|
||||
MQTTPacket_connectData data;
|
||||
int rc;
|
||||
if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)
|
||||
strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);
|
||||
}
|
||||
break;
|
||||
case PUBLISH:
|
||||
{
|
||||
unsigned char dup, retained, *payload;
|
||||
unsigned short packetid;
|
||||
int qos, payloadlen;
|
||||
MQTTString topicName = MQTTString_initializer;
|
||||
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
|
||||
&payload, &payloadlen, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
|
||||
topicName, payload, payloadlen);
|
||||
}
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
{
|
||||
unsigned char packettype, dup;
|
||||
unsigned short packetid;
|
||||
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
|
||||
}
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
{
|
||||
unsigned char dup;
|
||||
unsigned short packetid;
|
||||
int maxcount = 1, count = 0;
|
||||
MQTTString topicFilters[1];
|
||||
int requestedQoSs[1];
|
||||
if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
|
||||
topicFilters, requestedQoSs, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
|
||||
}
|
||||
break;
|
||||
case UNSUBSCRIBE:
|
||||
{
|
||||
unsigned char dup;
|
||||
unsigned short packetid;
|
||||
int maxcount = 1, count = 0;
|
||||
MQTTString topicFilters[1];
|
||||
if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
|
||||
strindex = MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
|
||||
}
|
||||
break;
|
||||
case PINGREQ:
|
||||
case PINGRESP:
|
||||
case DISCONNECT:
|
||||
strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
|
||||
break;
|
||||
}
|
||||
strbuf[strbuflen] = '\0';
|
||||
return strbuf;
|
||||
}
|
||||
#endif
|
||||
21
BasicCode/Drive/MQTT/MQTT_SRC/MQTTFormat.h
Normal file
21
BasicCode/Drive/MQTT/MQTT_SRC/MQTTFormat.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#if !defined(MQTTFORMAT_H)
|
||||
#define MQTTFORMAT_H
|
||||
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
const char* MQTTPacket_getName(unsigned short packetid);
|
||||
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data);
|
||||
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent);
|
||||
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
|
||||
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen);
|
||||
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid);
|
||||
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
|
||||
MQTTString topicFilters[], int requestedQoSs[]);
|
||||
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs);
|
||||
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[]);
|
||||
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
|
||||
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
|
||||
|
||||
#endif
|
||||
396
BasicCode/Drive/MQTT/MQTT_SRC/MQTTPacket.c
Normal file
396
BasicCode/Drive/MQTT/MQTT_SRC/MQTTPacket.c
Normal file
@@ -0,0 +1,396 @@
|
||||
#include "StackTrace.h"
|
||||
#include "MQTTPacket.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Encodes the message length according to the MQTT algorithm
|
||||
* @param buf the buffer into which the encoded data is written
|
||||
* @param length the length to be encoded
|
||||
* @return the number of bytes written to buffer
|
||||
*/
|
||||
int MQTTPacket_encode(unsigned char* buf, int length)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
do
|
||||
{
|
||||
char d = length % 128;
|
||||
length /= 128;
|
||||
/* if there are more digits to encode, set the top bit of this digit */
|
||||
if (length > 0)
|
||||
d |= 0x80;
|
||||
buf[rc++] = d;
|
||||
} while (length > 0);
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decodes the message length according to the MQTT algorithm
|
||||
* @param getcharfn pointer to function to read the next character from the data source
|
||||
* @param value the decoded length returned
|
||||
* @return the number of bytes read from the socket
|
||||
*/
|
||||
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value)
|
||||
{
|
||||
unsigned char c;
|
||||
int multiplier = 1;
|
||||
int len = 0;
|
||||
#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
|
||||
|
||||
FUNC_ENTRY;
|
||||
*value = 0;
|
||||
do
|
||||
{
|
||||
int rc = MQTTPACKET_READ_ERROR;
|
||||
|
||||
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
|
||||
{
|
||||
rc = MQTTPACKET_READ_ERROR; /* bad data */
|
||||
goto exit;
|
||||
}
|
||||
rc = (*getcharfn)(&c, 1);
|
||||
if (rc != 1)
|
||||
goto exit;
|
||||
*value += (c & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((c & 128) != 0);
|
||||
exit:
|
||||
FUNC_EXIT_RC(len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
int MQTTPacket_len(int rem_len)
|
||||
{
|
||||
rem_len += 1; /* header byte */
|
||||
|
||||
/* now remaining_length field */
|
||||
if (rem_len < 128)
|
||||
rem_len += 1;
|
||||
else if (rem_len < 16384)
|
||||
rem_len += 2;
|
||||
else if (rem_len < 2097151)
|
||||
rem_len += 3;
|
||||
else
|
||||
rem_len += 4;
|
||||
return rem_len;
|
||||
}
|
||||
|
||||
|
||||
static unsigned char* bufptr;
|
||||
|
||||
int bufchar(unsigned char* c, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
*c = *bufptr++;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int MQTTPacket_decodeBuf(unsigned char* buf, int* value)
|
||||
{
|
||||
bufptr = buf;
|
||||
return MQTTPacket_decode(bufchar, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates an integer from two bytes read from the input buffer
|
||||
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
|
||||
* @return the integer value calculated
|
||||
*/
|
||||
int readInt(unsigned char** pptr)
|
||||
{
|
||||
unsigned char* ptr = *pptr;
|
||||
int len = 256*(*ptr) + (*(ptr+1));
|
||||
*pptr += 2;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads one character from the input buffer.
|
||||
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
|
||||
* @return the character read
|
||||
*/
|
||||
char readChar(unsigned char** pptr)
|
||||
{
|
||||
char c = **pptr;
|
||||
(*pptr)++;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes one character to an output buffer.
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param c the character to write
|
||||
*/
|
||||
void writeChar(unsigned char** pptr, char c)
|
||||
{
|
||||
**pptr = c;
|
||||
(*pptr)++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes an integer as 2 bytes to an output buffer.
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param anInt the integer to write
|
||||
*/
|
||||
void writeInt(unsigned char** pptr, int anInt)
|
||||
{
|
||||
**pptr = (unsigned char)(anInt / 256);
|
||||
(*pptr)++;
|
||||
**pptr = (unsigned char)(anInt % 256);
|
||||
(*pptr)++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes a "UTF" string to an output buffer. Converts C string to length-delimited.
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param string the C string to write
|
||||
*/
|
||||
void writeCString(unsigned char** pptr, const char* string)
|
||||
{
|
||||
int len = strlen(string);
|
||||
writeInt(pptr, len);
|
||||
memcpy(*pptr, string, len);
|
||||
*pptr += len;
|
||||
}
|
||||
|
||||
|
||||
int getLenStringLen(char* ptr)
|
||||
{
|
||||
int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring)
|
||||
{
|
||||
if (mqttstring.lenstring.len > 0)
|
||||
{
|
||||
writeInt(pptr, mqttstring.lenstring.len);
|
||||
memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);
|
||||
*pptr += mqttstring.lenstring.len;
|
||||
}
|
||||
else if (mqttstring.cstring)
|
||||
writeCString(pptr, mqttstring.cstring);
|
||||
else
|
||||
writeInt(pptr, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mqttstring the MQTTString structure into which the data is to be read
|
||||
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
|
||||
* @param enddata pointer to the end of the data: do not read beyond
|
||||
* @return 1 if successful, 0 if not
|
||||
*/
|
||||
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
/* the first two bytes are the length of the string */
|
||||
if (enddata - (*pptr) > 1) /* enough length to read the integer? */
|
||||
{
|
||||
//printf("pptr:%p, *pptr:%p", pptr, *pptr);
|
||||
mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */
|
||||
if (&(*pptr)[mqttstring->lenstring.len] <= enddata)
|
||||
{
|
||||
mqttstring->lenstring.data = (char*)*pptr;
|
||||
*pptr += mqttstring->lenstring.len;
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
mqttstring->cstring = NULL;
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string
|
||||
* @param mqttstring the string to return the length of
|
||||
* @return the length of the string
|
||||
*/
|
||||
int MQTTstrlen(MQTTString mqttstring)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (mqttstring.cstring)
|
||||
rc = strlen(mqttstring.cstring);
|
||||
else
|
||||
rc = mqttstring.lenstring.len;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares an MQTTString to a C string
|
||||
* @param a the MQTTString to compare
|
||||
* @param bptr the C string to compare
|
||||
* @return boolean - equal or not
|
||||
*/
|
||||
int MQTTPacket_equals(MQTTString* a, char* bptr)
|
||||
{
|
||||
int alen = 0,
|
||||
blen = 0;
|
||||
char *aptr;
|
||||
|
||||
if (a->cstring)
|
||||
{
|
||||
aptr = a->cstring;
|
||||
alen = strlen(a->cstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
aptr = a->lenstring.data;
|
||||
alen = a->lenstring.len;
|
||||
}
|
||||
blen = strlen(bptr);
|
||||
|
||||
return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to read packet data from some source into a buffer
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param getfn pointer to a function which will read any number of bytes from the needed source
|
||||
* @return integer MQTT packet type, or -1 on error
|
||||
* @note the whole message must fit into the caller's buffer
|
||||
*/
|
||||
int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int))
|
||||
{
|
||||
int rc = -1;
|
||||
MQTTHeader header = {0};
|
||||
int len = 0;
|
||||
int rem_len = 0;
|
||||
|
||||
/* 1. read the header byte. This has the packet type in it */
|
||||
if ((*getfn)(buf, 1) != 1)
|
||||
goto exit;
|
||||
|
||||
len = 1;
|
||||
/* 2. read the remaining length. This is variable in itself */
|
||||
MQTTPacket_decode(getfn, &rem_len);
|
||||
len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */
|
||||
|
||||
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
|
||||
if((rem_len + len) > buflen)
|
||||
goto exit;
|
||||
if (rem_len && ((*getfn)(buf + len, rem_len) != rem_len))
|
||||
goto exit;
|
||||
|
||||
header.byte = buf[0];
|
||||
rc = header.bits.type;
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message length according to the MQTT algorithm, non-blocking
|
||||
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
|
||||
* @param value the decoded length returned
|
||||
* @return integer the number of bytes read from the socket, 0 for call again, or -1 on error
|
||||
*/
|
||||
static int MQTTPacket_decodenb(MQTTTransport *trp)
|
||||
{
|
||||
unsigned char c;
|
||||
int rc = MQTTPACKET_READ_ERROR;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if(trp->len == 0){ /* initialize on first call */
|
||||
trp->multiplier = 1;
|
||||
trp->rem_len = 0;
|
||||
}
|
||||
do {
|
||||
int frc;
|
||||
if (trp->len >= MAX_NO_OF_REMAINING_LENGTH_BYTES)
|
||||
goto exit;
|
||||
if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)
|
||||
goto exit;
|
||||
if (frc == 0){
|
||||
rc = 0;
|
||||
goto exit;
|
||||
}
|
||||
++(trp->len);
|
||||
trp->rem_len += (c & 127) * trp->multiplier;
|
||||
trp->multiplier *= 128;
|
||||
} while ((c & 128) != 0);
|
||||
rc = trp->len;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to read packet data from some source into a buffer, non-blocking
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
|
||||
* @return integer MQTT packet type, 0 for call again, or -1 on error
|
||||
* @note the whole message must fit into the caller's buffer
|
||||
*/
|
||||
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp)
|
||||
{
|
||||
int rc = -1, frc;
|
||||
MQTTHeader header = {0};
|
||||
|
||||
switch(trp->state){
|
||||
default:
|
||||
trp->state = 0;
|
||||
/*FALLTHROUGH*/
|
||||
case 0:
|
||||
/* read the header byte. This has the packet type in it */
|
||||
if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)
|
||||
goto exit;
|
||||
if (frc == 0)
|
||||
return 0;
|
||||
trp->len = 0;
|
||||
++trp->state;
|
||||
/*FALLTHROUGH*/
|
||||
/* read the remaining length. This is variable in itself */
|
||||
case 1:
|
||||
if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
|
||||
goto exit;
|
||||
if(frc == 0)
|
||||
return 0;
|
||||
trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */
|
||||
if((trp->rem_len + trp->len) > buflen)
|
||||
goto exit;
|
||||
++trp->state;
|
||||
/*FALLTHROUGH*/
|
||||
case 2:
|
||||
if(trp->rem_len){
|
||||
/* read the rest of the buffer using a callback to supply the rest of the data */
|
||||
if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)
|
||||
goto exit;
|
||||
if (frc == 0)
|
||||
return 0;
|
||||
trp->rem_len -= frc;
|
||||
trp->len += frc;
|
||||
if(trp->rem_len)
|
||||
return 0;
|
||||
}
|
||||
header.byte = buf[0];
|
||||
rc = header.bits.type;
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
trp->state = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
124
BasicCode/Drive/MQTT/MQTT_SRC/MQTTPacket.h
Normal file
124
BasicCode/Drive/MQTT/MQTT_SRC/MQTTPacket.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef MQTTPACKET_H_
|
||||
#define MQTTPACKET_H_
|
||||
|
||||
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(WIN32_DLL) || defined(WIN64_DLL)
|
||||
#define DLLImport __declspec(dllimport)
|
||||
#define DLLExport __declspec(dllexport)
|
||||
#elif defined(LINUX_SO)
|
||||
#define DLLImport extern
|
||||
#define DLLExport __attribute__ ((visibility ("default")))
|
||||
#else
|
||||
#define DLLImport
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
|
||||
#define FLAG_CONNACK 0X02
|
||||
#define FLAG_PUBLISH 0X03
|
||||
#define FLAG_PUBACK 0X04
|
||||
#define FLAG_SUBACK 0X09
|
||||
#define FLAG_UNSUBACK 0X0b
|
||||
#define FLAG_PINGACK 0X0d
|
||||
|
||||
enum errors
|
||||
{
|
||||
MQTTPACKET_BUFFER_TOO_SHORT = -2,
|
||||
MQTTPACKET_READ_ERROR = -1,
|
||||
MQTTPACKET_READ_COMPLETE
|
||||
};
|
||||
|
||||
enum msgTypes
|
||||
{
|
||||
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
|
||||
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
|
||||
PINGREQ, PINGRESP, DISCONNECT
|
||||
};
|
||||
|
||||
/**
|
||||
* Bitfields for the MQTT header byte.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
unsigned char byte; /**< the whole byte */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
unsigned int dup : 1; /**< DUP flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
unsigned int retain : 1; /**< retained flag bit */
|
||||
} bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
unsigned int retain : 1; /**< retained flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
unsigned int dup : 1; /**< DUP flag bit */
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
} bits;
|
||||
#endif
|
||||
} MQTTHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int len;
|
||||
char* data;
|
||||
} MQTTLenString;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* cstring;
|
||||
MQTTLenString lenstring;
|
||||
} MQTTString;
|
||||
|
||||
#define MQTTString_initializer {NULL, {0, NULL}}
|
||||
|
||||
int MQTTstrlen(MQTTString mqttstring);
|
||||
|
||||
#include "MQTTConnect.h"
|
||||
#include "MQTTPublish.h"
|
||||
#include "MQTTSubscribe.h"
|
||||
#include "MQTTUnsubscribe.h"
|
||||
#include "MQTTFormat.h"
|
||||
|
||||
DLLExport int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid);
|
||||
DLLExport int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen);
|
||||
|
||||
int MQTTPacket_len(int rem_len);
|
||||
DLLExport int MQTTPacket_equals(MQTTString* a, char* b);
|
||||
|
||||
DLLExport int MQTTPacket_encode(unsigned char* buf, int length);
|
||||
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value);
|
||||
int MQTTPacket_decodeBuf(unsigned char* buf, int* value);
|
||||
|
||||
int readInt(unsigned char** pptr);
|
||||
char readChar(unsigned char** pptr);
|
||||
void writeChar(unsigned char** pptr, char c);
|
||||
void writeInt(unsigned char** pptr, int anInt);
|
||||
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata);
|
||||
void writeCString(unsigned char** pptr, const char* string);
|
||||
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring);
|
||||
|
||||
DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int));
|
||||
|
||||
typedef struct {
|
||||
int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */
|
||||
void *sck; /* pointer to whatever the system may use to identify the transport */
|
||||
int multiplier;
|
||||
int rem_len;
|
||||
int len;
|
||||
char state;
|
||||
}MQTTTransport;
|
||||
|
||||
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp);
|
||||
|
||||
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* MQTTPACKET_H_ */
|
||||
21
BasicCode/Drive/MQTT/MQTT_SRC/MQTTPublish.h
Normal file
21
BasicCode/Drive/MQTT/MQTT_SRC/MQTTPublish.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef MQTTPUBLISH_H_
|
||||
#define MQTTPUBLISH_H_
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
|
||||
MQTTString topicName, unsigned char* payload, int payloadlen);
|
||||
|
||||
DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
|
||||
unsigned char** payload, int* payloadlen, unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid);
|
||||
DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid);
|
||||
DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid);
|
||||
|
||||
#endif /* MQTTPUBLISH_H_ */
|
||||
152
BasicCode/Drive/MQTT/MQTT_SRC/MQTTSerializePublish.c
Normal file
152
BasicCode/Drive/MQTT/MQTT_SRC/MQTTSerializePublish.c
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/**
|
||||
* Determines the length of the MQTT publish packet that would be produced using the supplied parameters
|
||||
* @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
|
||||
* @param topicName the topic name to be used in the publish
|
||||
* @param payloadlen the length of the payload to be sent
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
len += 2 + MQTTstrlen(topicName) + payloadlen;
|
||||
if (qos > 0)
|
||||
len += 2; /* packetid */
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied publish data into the supplied buffer, ready for sending
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param qos integer - the MQTT QoS value
|
||||
* @param retained integer - the MQTT retained flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @param topicName MQTTString - the MQTT topic in the publish
|
||||
* @param payload byte buffer - the MQTT publish payload
|
||||
* @param payloadlen integer - the length of the MQTT payload
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
|
||||
MQTTString topicName, unsigned char* payload, int payloadlen)
|
||||
{
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
int rem_len = 0;
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.bits.type = PUBLISH;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = qos;
|
||||
header.bits.retain = retained;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
|
||||
|
||||
writeMQTTString(&ptr, topicName);
|
||||
|
||||
if (qos > 0)
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
memcpy(ptr, payload, payloadlen);
|
||||
ptr += payloadlen;
|
||||
|
||||
rc = ptr - buf;
|
||||
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the ack packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param type the MQTT packet type
|
||||
* @param dup the MQTT dup flag
|
||||
* @param packetid the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
|
||||
{
|
||||
MQTTHeader header = {0};
|
||||
int rc = 0;
|
||||
unsigned char *ptr = buf;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (buflen < 4)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
header.bits.type = packettype;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = (packettype == PUBREL) ? 1 : 0;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
|
||||
writeInt(&ptr, packetid);
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a puback packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid)
|
||||
{
|
||||
return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a pubrel packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)
|
||||
{
|
||||
return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a pubrel packet into the supplied buffer.
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied buffer
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @return serialized length, or error if 0
|
||||
*/
|
||||
int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)
|
||||
{
|
||||
return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);
|
||||
}
|
||||
|
||||
|
||||
22
BasicCode/Drive/MQTT/MQTT_SRC/MQTTSubscribe.h
Normal file
22
BasicCode/Drive/MQTT/MQTT_SRC/MQTTSubscribe.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef MQTTSUBSCRIBE_H_
|
||||
#define MQTTSUBSCRIBE_H_
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[], int requestedQoSs[]);
|
||||
|
||||
DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid,
|
||||
int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs);
|
||||
|
||||
DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len);
|
||||
|
||||
|
||||
#endif /* MQTTSUBSCRIBE_H_ */
|
||||
121
BasicCode/Drive/MQTT/MQTT_SRC/MQTTSubscribeClient.c
Normal file
121
BasicCode/Drive/MQTT/MQTT_SRC/MQTTSubscribeClient.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters
|
||||
* @param count the number of topic filter strings in topicFilters
|
||||
* @param topicFilters the array of topic filter strings to be used in the publish
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[])
|
||||
{
|
||||
int i;
|
||||
int len = 2; /* packetid */
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied subscribe data into the supplied buffer, ready for sending
|
||||
* @param buf the buffer into which the packet will be serialized
|
||||
* @param buflen the length in bytes of the supplied bufferr
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @param count - number of members in the topicFilters and reqQos arrays
|
||||
* @param topicFilters - array of topic filter names
|
||||
* @param requestedQoSs - array of requested QoS
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count,
|
||||
MQTTString topicFilters[], int requestedQoSs[])
|
||||
{
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
int rem_len = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.byte = 0;
|
||||
header.bits.type = SUBSCRIBE;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = 1;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
|
||||
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
writeMQTTString(&ptr, topicFilters[i]);
|
||||
writeChar(&ptr, requestedQoSs[i]);
|
||||
}
|
||||
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into suback data
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param maxcount - the maximum number of members allowed in the grantedQoSs array
|
||||
* @param count returned integer - number of members in the grantedQoSs array
|
||||
* @param grantedQoSs returned array of integers - the granted qualities of service
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen)
|
||||
{
|
||||
MQTTHeader header = {0};
|
||||
unsigned char* curdata = buf;
|
||||
unsigned char* enddata = NULL;
|
||||
int rc = 0;
|
||||
int mylen;
|
||||
|
||||
FUNC_ENTRY;
|
||||
header.byte = readChar(&curdata);
|
||||
if (header.bits.type != SUBACK)
|
||||
goto exit;
|
||||
|
||||
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
|
||||
enddata = curdata + mylen;
|
||||
if (enddata - curdata < 2)
|
||||
goto exit;
|
||||
|
||||
*packetid = readInt(&curdata);
|
||||
|
||||
*count = 0;
|
||||
while (curdata < enddata)
|
||||
{
|
||||
if (*count > maxcount)
|
||||
{
|
||||
rc = -1;
|
||||
goto exit;
|
||||
}
|
||||
grantedQoSs[(*count)++] = readChar(&curdata);
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
21
BasicCode/Drive/MQTT/MQTT_SRC/MQTTUnsubscribe.h
Normal file
21
BasicCode/Drive/MQTT/MQTT_SRC/MQTTUnsubscribe.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef MQTTUNSUBSCRIBE_H_
|
||||
#define MQTTUNSUBSCRIBE_H_
|
||||
|
||||
#if !defined(DLLImport)
|
||||
#define DLLImport
|
||||
#endif
|
||||
#if !defined(DLLExport)
|
||||
#define DLLExport
|
||||
#endif
|
||||
|
||||
DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[]);
|
||||
|
||||
DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[],
|
||||
unsigned char* buf, int len);
|
||||
|
||||
DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid);
|
||||
|
||||
DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len);
|
||||
|
||||
#endif /* MQTTUNSUBSCRIBE_H_ */
|
||||
90
BasicCode/Drive/MQTT/MQTT_SRC/MQTTUnsubscribeClient.c
Normal file
90
BasicCode/Drive/MQTT/MQTT_SRC/MQTTUnsubscribeClient.c
Normal file
@@ -0,0 +1,90 @@
|
||||
#include "MQTTPacket.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters
|
||||
* @param count the number of topic filter strings in topicFilters
|
||||
* @param topicFilters the array of topic filter strings to be used in the publish
|
||||
* @return the length of buffer needed to contain the serialized version of the packet
|
||||
*/
|
||||
int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[])
|
||||
{
|
||||
int i;
|
||||
int len = 2; /* packetid */
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the supplied unsubscribe data into the supplied buffer, ready for sending
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @param dup integer - the MQTT dup flag
|
||||
* @param packetid integer - the MQTT packet identifier
|
||||
* @param count - number of members in the topicFilters array
|
||||
* @param topicFilters - array of topic filter names
|
||||
* @return the length of the serialized data. <= 0 indicates error
|
||||
*/
|
||||
int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
|
||||
int count, MQTTString topicFilters[])
|
||||
{
|
||||
unsigned char *ptr = buf;
|
||||
MQTTHeader header = {0};
|
||||
int rem_len = 0;
|
||||
int rc = -1;
|
||||
int i = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen)
|
||||
{
|
||||
rc = MQTTPACKET_BUFFER_TOO_SHORT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
header.byte = 0;
|
||||
header.bits.type = UNSUBSCRIBE;
|
||||
header.bits.dup = dup;
|
||||
header.bits.qos = 1;
|
||||
writeChar(&ptr, header.byte); /* write header */
|
||||
|
||||
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
|
||||
|
||||
writeInt(&ptr, packetid);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
writeMQTTString(&ptr, topicFilters[i]);
|
||||
|
||||
rc = ptr - buf;
|
||||
exit:
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes the supplied (wire) buffer into unsuback data
|
||||
* @param packetid returned integer - the MQTT packet identifier
|
||||
* @param buf the raw buffer data, of the correct length determined by the remaining length field
|
||||
* @param buflen the length in bytes of the data in the supplied buffer
|
||||
* @return error code. 1 is success, 0 is failure
|
||||
*/
|
||||
int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen)
|
||||
{
|
||||
unsigned char type = 0;
|
||||
unsigned char dup = 0;
|
||||
int rc = 0;
|
||||
|
||||
FUNC_ENTRY;
|
||||
rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);
|
||||
if (type == UNSUBACK)
|
||||
rc = 1;
|
||||
FUNC_EXIT_RC(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
61
BasicCode/Drive/MQTT/MQTT_SRC/StackTrace.h
Normal file
61
BasicCode/Drive/MQTT/MQTT_SRC/StackTrace.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef STACKTRACE_H_
|
||||
#define STACKTRACE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#define NOSTACKTRACE 1
|
||||
|
||||
#if defined(NOSTACKTRACE)
|
||||
#define FUNC_ENTRY
|
||||
#define FUNC_ENTRY_NOLOG
|
||||
#define FUNC_ENTRY_MED
|
||||
#define FUNC_ENTRY_MAX
|
||||
#define FUNC_EXIT
|
||||
#define FUNC_EXIT_NOLOG
|
||||
#define FUNC_EXIT_MED
|
||||
#define FUNC_EXIT_MAX
|
||||
#define FUNC_EXIT_RC(x)
|
||||
#define FUNC_EXIT_MED_RC(x)
|
||||
#define FUNC_EXIT_MAX_RC(x)
|
||||
|
||||
#else
|
||||
|
||||
#if defined(WIN32)
|
||||
#define inline __inline
|
||||
#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)
|
||||
#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)
|
||||
#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)
|
||||
#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)
|
||||
#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)
|
||||
#else
|
||||
#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)
|
||||
#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)
|
||||
#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)
|
||||
#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)
|
||||
#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)
|
||||
#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)
|
||||
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)
|
||||
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)
|
||||
|
||||
void StackTrace_entry(const char* name, int line, int trace);
|
||||
void StackTrace_exit(const char* name, int line, void* return_value, int trace);
|
||||
|
||||
void StackTrace_printStack(FILE* dest);
|
||||
char* StackTrace_get(unsigned long);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* STACKTRACE_H_ */
|
||||
292
BasicCode/Drive/MQTT/aLiYun.c
Normal file
292
BasicCode/Drive/MQTT/aLiYun.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/***
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
**/
|
||||
#include "aLiYun.h"
|
||||
#include "utils_hmac.h"
|
||||
#include "DBG.h"
|
||||
#include "PC_DeviceTest_Fun.h"
|
||||
#include "flash.h"
|
||||
|
||||
#if MQTT_EN
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ALiYun_Default_Parameter_Get 2022-09-03
|
||||
* Description : <20><>ʼ<EFBFBD><CABC>Ĭ<EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD>
|
||||
* Input : aliyun_info
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void ALiYun_Default_Parameter_Get(ALIYUN_INFO* aliyun_info)
|
||||
{
|
||||
UINT8 mactostr[12]; //mac<61><63>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint8_t j=0;
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
{
|
||||
mactostr[j]=(MACAddr[i]>>4)&0x0F;
|
||||
mactostr[j+1]=MACAddr[i]&0x0F;
|
||||
|
||||
if(mactostr[j] <= 9)
|
||||
{
|
||||
mactostr[j] += 0x30;
|
||||
}
|
||||
else if((mactostr[j] >= 10) && (mactostr[j] <= 15))
|
||||
{
|
||||
mactostr[j] += 0x37;
|
||||
}
|
||||
|
||||
if(mactostr[j+1] <= 9)
|
||||
{
|
||||
mactostr[j+1] += 0x30;
|
||||
}
|
||||
else if((mactostr[j+1] >= 10) && (mactostr[j+1] <= 15))
|
||||
{
|
||||
mactostr[j+1] += 0x37;
|
||||
}
|
||||
|
||||
j+=2;
|
||||
}
|
||||
|
||||
memcpy(aliyun_info->productKey,DEF_PRODUCTKEY,12);
|
||||
memcpy(aliyun_info->publish,DEF_ALIY_PUBLISH,12);
|
||||
memcpy(aliyun_info->sublish,DEF_ALIY_SUBLISH,9);
|
||||
aliyun_info->mqtt_data.keepAliveInterval=120;
|
||||
memcpy(aliyun_info->deviceName,mactostr,12);
|
||||
Flash_Read((UINT8*)aliyun_info->deviceSecret ,33, FLASH_MCU_MQTT_START_ADDRESS+FLASH_MQTTINFO_DeviceSecret_OFFSET);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ALiYun_Machine_Init
|
||||
* Description : һ<><D2BB>һ<EFBFBD>ܷ<EFBFBD>ʽ<EFBFBD><CABD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* Input : ProductKey<65><79>ProductKey
|
||||
* deviceName: <20>豸<EFBFBD><E8B1B8>
|
||||
* DeviceSecret: <20>豸<EFBFBD><E8B1B8>Կ
|
||||
sublish: <20><><EFBFBD>ĵ<EFBFBD>ַ
|
||||
keepAliveInterval<61><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
* Output : None
|
||||
* Return : <20>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD>˴<EFBFBD><CBB4>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴɹ<C6B3><C9B9><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ɹ<EFBFBD>
|
||||
*******************************************************************************/
|
||||
UINT8 ALiYun_Machine_Init(MQTT_INFO* Mqtt_info, char* ProductKey, char* deviceName, char* DeviceSecret, char* sublish, int keepAliveInterval)
|
||||
{
|
||||
if(Mqtt_info == NULL || ProductKey == NULL || deviceName == NULL || sublish == NULL || DeviceSecret == NULL) return 1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
UINT8 domain_name_len = strlen(ALIYUN_DOMAIN) + strlen(ProductKey) +1;
|
||||
UINT8 clientID_len = strlen(ALIYUN_CLIENT_ID) + strlen(deviceName) +1;
|
||||
UINT8 userName_len = strlen(ProductKey) + strlen(deviceName) + 2;
|
||||
UINT8 passWord_len = 40+1;
|
||||
UINT8 sublish_len = strlen(sublish) + strlen(ProductKey) + strlen(deviceName) + 5;
|
||||
int msg_len = strlen(CLIENT_ID_KEY) + strlen(deviceName) + strlen(DEVICE_NAME_KEY) \
|
||||
+ strlen(deviceName) + strlen(PRODUCTKEY_KEY) + strlen(ProductKey) + 1;
|
||||
|
||||
char* domain_name = malloc(domain_name_len); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ProductKey + <20>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><D7BA>
|
||||
if(domain_name == NULL) return 4; //<2F>ڴ治<DAB4><E6B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
char* clientID = malloc(clientID_len); //<2F><><EFBFBD><EFBFBD>clientID <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD>豸<EFBFBD><E8B1B8> + <20>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><D7BA>
|
||||
if(clientID == NULL)
|
||||
{
|
||||
free(domain_name);
|
||||
return 4; //<2F>ڴ治<DAB4><E6B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
char* userName = malloc(userName_len); //<2F><><EFBFBD><EFBFBD>userName <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD>豸<EFBFBD><E8B1B8> + & + ProductKey<65><79>
|
||||
if(userName == NULL)
|
||||
{
|
||||
free(domain_name);
|
||||
free(clientID);
|
||||
return 4; //<2F>ڴ治<DAB4><E6B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
char* passWord = malloc(passWord_len); //<2F><><EFBFBD><EFBFBD> hmacsha1 password
|
||||
if(passWord == NULL)
|
||||
{
|
||||
free(domain_name);
|
||||
free(clientID);
|
||||
free(userName);
|
||||
return 4; //<2F>ڴ治<DAB4><E6B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
char* msg = malloc(msg_len); //<2F><><EFBFBD><EFBFBD> hmacsha1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>Ե<EFBFBD>ֵ
|
||||
if(msg == NULL)
|
||||
{
|
||||
free(domain_name);
|
||||
free(clientID);
|
||||
free(userName);
|
||||
free(passWord);
|
||||
return 4; //<2F>ڴ治<DAB4><E6B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
char* sublish_str = malloc(sublish_len); //<2F><><EFBFBD><EFBFBD> <20><><EFBFBD>ĵ<EFBFBD>ַ
|
||||
if(sublish_str == NULL)
|
||||
{
|
||||
free(domain_name);
|
||||
free(clientID);
|
||||
free(userName);
|
||||
free(passWord);
|
||||
free(msg);
|
||||
return 4; //<2F>ڴ治<DAB4><E6B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
memset(domain_name, 0, domain_name_len);
|
||||
memset(clientID, 0, clientID_len);
|
||||
memset(userName, 0, userName_len);
|
||||
memset(passWord, 0, passWord_len);
|
||||
memset(msg, 0, msg_len);
|
||||
memset(sublish_str, 0, sublish_len);
|
||||
|
||||
sprintf(domain_name, "%s%s", ProductKey, ALIYUN_DOMAIN); //ƴ<><C6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
sprintf(clientID, "%s%s", deviceName, ALIYUN_CLIENT_ID); //ƴ<><C6B4>clientID
|
||||
sprintf(userName, "%s&%s", deviceName, ProductKey); //ƴ<><C6B4>userName
|
||||
sprintf(msg, "%s%s%s%s%s%s", CLIENT_ID_KEY, deviceName, DEVICE_NAME_KEY, deviceName, PRODUCTKEY_KEY, ProductKey); //ƴ<><C6B4>hmacsha1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>Ե<EFBFBD>ֵ
|
||||
sprintf(sublish_str, "/%s/%s/%s", ProductKey, deviceName, sublish); //ƴ<>Ӷ<EFBFBD><D3B6>ĵ<EFBFBD>ַ
|
||||
|
||||
PRINT("domain_name:%s\n", domain_name);
|
||||
PRINT("clientID:%s\n", clientID);
|
||||
PRINT("userName:%s\n", userName);
|
||||
|
||||
PRINT("msg:%s\n", msg);
|
||||
|
||||
utils_hmac_sha1(msg, strlen(msg), passWord, DeviceSecret, strlen(DeviceSecret)); //<2F><><EFBFBD><EFBFBD>password
|
||||
|
||||
PRINT("passWord:%s\n", passWord);
|
||||
|
||||
free(msg);
|
||||
|
||||
return MQTT_Init(Mqtt_info, domain_name, NULL, clientID, userName, passWord, sublish_str, keepAliveInterval);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ALIYUN_Flash_Parameter_Init
|
||||
* Description : <20><>flash<73><68>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* Input : Mqtt_info
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
UINT8 ALIYUN_Flash_Parameter_Init(MQTT_INFO* Mqtt_info)
|
||||
{
|
||||
if(Mqtt_info == NULL) return 1;
|
||||
char* publish = NULL;
|
||||
ALIYUN_INFO aliyun_info;
|
||||
ALIYUN_INFO aliyun_temp;
|
||||
UINT8 ret = 0;
|
||||
UINT16 keepAlive = 0;
|
||||
|
||||
memset(&aliyun_info, 0x00, sizeof(ALIYUN_INFO));
|
||||
Flash_Read((UINT8*)&aliyun_temp ,sizeof(ALIYUN_INFO)-4, FLASH_MCU_MQTT_START_ADDRESS);
|
||||
|
||||
// Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_keepAliveInterval:%d", aliyun_temp.mqtt_data.keepAliveInterval);
|
||||
// Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_sublish:%s", aliyun_temp.sublish);
|
||||
// Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_temp_temp_temp_publish:%s", aliyun_temp.publish);
|
||||
// Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_temp_productKey:%s", aliyun_temp.productKey);
|
||||
// Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_temp_deviceName:%s", aliyun_temp.deviceName);
|
||||
// Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_deviceSecret:%s\n", aliyun_temp.deviceSecret);
|
||||
|
||||
if(memcmp(aliyun_info.deviceName,aliyun_temp.deviceName,sizeof(aliyun_info.deviceName))!=0
|
||||
||memcmp(aliyun_info.productKey,aliyun_temp.productKey,sizeof(aliyun_info.productKey))!=0
|
||||
||memcmp(aliyun_info.publish,aliyun_temp.publish,sizeof(aliyun_info.publish))!=0
|
||||
||memcmp(aliyun_info.sublish,aliyun_temp.sublish,sizeof(aliyun_info.sublish))!=0
|
||||
||memcmp(&aliyun_info.mqtt_data.keepAliveInterval,&aliyun_temp.mqtt_data.keepAliveInterval,sizeof(aliyun_info.mqtt_data.keepAliveInterval))!=0
|
||||
)
|
||||
{
|
||||
memcpy(&aliyun_info,&aliyun_temp,sizeof(ALIYUN_INFO)); //flash<73>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>㣬<EFBFBD><E3A3AC>ʹ<EFBFBD><CAB9>flash<73>еIJ<D0B5><C4B2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD><C6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>Ĭ<EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
||||
}
|
||||
else
|
||||
{
|
||||
ALiYun_Default_Parameter_Get(&aliyun_info);
|
||||
}
|
||||
|
||||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"keepAliveInterval:%d", aliyun_info.mqtt_data.keepAliveInterval);
|
||||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"sublish:%s", aliyun_info.sublish);
|
||||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"publish:%s", aliyun_info.publish);
|
||||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"productKey:%s", aliyun_info.productKey);
|
||||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"deviceName:%s", aliyun_info.deviceName);
|
||||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"deviceSecret:%s", aliyun_info.deviceSecret);
|
||||
|
||||
if(aliyun_info.mqtt_data.keepAliveInterval < 0xFFFF)
|
||||
{
|
||||
keepAlive = aliyun_info.mqtt_data.keepAliveInterval;
|
||||
}
|
||||
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>ʹ<EFBFBD><CAB9>Ĭ<EFBFBD><C4AC>ֵ
|
||||
{
|
||||
keepAlive = 120;
|
||||
}
|
||||
|
||||
if(aliyun_info.sublish[0] != 0xFF && aliyun_info.sublish[0] != 0x00)
|
||||
{
|
||||
|
||||
}
|
||||
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
ret = 3;
|
||||
goto reault;
|
||||
}
|
||||
|
||||
if(aliyun_info.productKey[0] != 0xFF && aliyun_info.productKey[0] != 0x00)
|
||||
{
|
||||
|
||||
}
|
||||
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
ret = 3;
|
||||
goto reault;
|
||||
}
|
||||
|
||||
if((aliyun_info.deviceName[0] != 0xFF) && (aliyun_info.deviceName[0] != 0x00) && (0x0C == strlen((char *)aliyun_info.deviceName)))
|
||||
{
|
||||
|
||||
}
|
||||
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
ret = 3;
|
||||
goto reault;
|
||||
}
|
||||
|
||||
if(aliyun_info.deviceSecret[0] != 0xFF && aliyun_info.deviceSecret[0] != 0x00)
|
||||
{
|
||||
|
||||
}
|
||||
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
ret = 3;
|
||||
goto reault;
|
||||
}
|
||||
|
||||
if(aliyun_info.publish[0] != 0xFF && aliyun_info.publish[0] != 0x00)
|
||||
{
|
||||
UINT8 len = strlen((char*)aliyun_info.publish) + strlen((char*)aliyun_info.productKey) + strlen((char*)aliyun_info.deviceName) + 5;
|
||||
publish = malloc(len);
|
||||
if(publish == NULL)
|
||||
{
|
||||
ret = 4;
|
||||
goto reault;
|
||||
}
|
||||
memset(publish, 0, len);
|
||||
sprintf(publish, "/%s/%s/%s", (char*)aliyun_info.productKey, (char*)aliyun_info.deviceName, (char*)aliyun_info.publish); //ƴ<>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
|
||||
if(Mqtt_info->pub_topic)
|
||||
{
|
||||
free(Mqtt_info->pub_topic);
|
||||
}
|
||||
Mqtt_info->pub_topic = publish;
|
||||
}
|
||||
|
||||
reault:
|
||||
switch(ret)
|
||||
{
|
||||
case 0: //<2F><EFBFBD><DEB4><EFBFBD>
|
||||
case 4: //publish<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
|
||||
return ALiYun_Machine_Init(Mqtt_info, (char*)aliyun_info.productKey, (char*)aliyun_info.deviceName, (char*)aliyun_info.deviceSecret,
|
||||
(char*)aliyun_info.sublish, keepAlive); //<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
default: //<2F>д<EFBFBD><D0B4><EFBFBD>
|
||||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"ALIYUN_Flash_Parameter err, Clear ALIYUN_Flash");
|
||||
memset(&aliyun_info, 0x00, sizeof(ALIYUN_INFO)); //<2F><>0
|
||||
Flash_Write((uint8_t *)&aliyun_info,sizeof(ALIYUN_INFO) ,FLASH_MCU_MQTT_START_ADDRESS); //<2F><><EFBFBD><EFBFBD>
|
||||
if(publish) free(publish);
|
||||
return ret;
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
77
BasicCode/Drive/MQTT/aLiYun.h
Normal file
77
BasicCode/Drive/MQTT/aLiYun.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef _ALIYUN_H
|
||||
#define _ALIYUN_H
|
||||
|
||||
#include "mqtt.h"
|
||||
|
||||
|
||||
#define ALIYUN_DOMAIN ".iot-as-mqtt.cn-shanghai.aliyuncs.com" //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD>
|
||||
#define ALIYUN_CLIENT_ID "|securemode=3,signmethod=hmacsha1|" //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ClientID<49>̶<EFBFBD><CCB6><EFBFBD>
|
||||
#define ALIYUN_CLIENT_ID2 "|securemode=3,signmethod=hmacsha1,timestamp=789|"
|
||||
|
||||
#define CLIENT_ID_KEY "clientId"
|
||||
#define DEVICE_NAME_KEY "deviceName"
|
||||
#define PRODUCTKEY_KEY "productKey"
|
||||
|
||||
#define NET485_PRODUCTKEY "a12hZXRHLLY"
|
||||
#define NET485_DEVICE_NAME "NET485_1"
|
||||
#define NET485_DEVICE_SECRET "804be6c043218f8c6a70175278aeca78"
|
||||
|
||||
#define NET485_DEVICE2_NAME "NET485_2"
|
||||
#define NET485_DEVICE2_SECRET "590301f6291563957d96a329df8a6254"
|
||||
|
||||
#define NET485_PUBLISH "/a12hZXRHLLY/NET485_1/user/post"
|
||||
#define NET485_SUBLISH "/a12hZXRHLLY/NET485_1/user/get"
|
||||
|
||||
#define NET485_PUBLISH2 "/a12hZXRHLLY/NET485_2/user/post"
|
||||
#define NET485_SUBLISH2 "/a12hZXRHLLY/NET485_2/user/get"
|
||||
|
||||
#define FRG_PRODUCTKEY "a1STn6qUB4r"
|
||||
#define FRG_DEVICE_NAME "34D0B8108D15"
|
||||
#define FRG_DEVICE_SECRET "xlRTX2JSU10Bqp9ldgf4gP79euLGVDxT"
|
||||
|
||||
#define FRG_PUBLISH_ALIY "user/update"
|
||||
#define FRG_PUBLISH "/a1STn6qUB4r/34D0B8108D15/user/update"
|
||||
#define FRG_SUBLISH "/a1STn6qUB4r/34D0B8108D15/user/get"
|
||||
|
||||
|
||||
#define DEF_PRODUCTKEY "a1STn6qUB4r"
|
||||
#define DEF_ALIY_PUBLISH "user/update"
|
||||
#define DEF_ALIY_SUBLISH "user/get"
|
||||
#define DEF_ALIY_KEEPALIVE 120
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>*/
|
||||
UINT8 productKey[12]; //productKey
|
||||
UINT8 deviceName[65]; //<2F>豸<EFBFBD><E8B1B8>
|
||||
UINT8 deviceSecret[33]; //<2F>豸<EFBFBD><E8B1B8>Կ
|
||||
UINT8 publish[65]; //<2F><><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>MQTT<54><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><D7BA><EFBFBD>ɳ<EFBFBD><C9B3><EFBFBD>ƴ<EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>mqtt<74><74>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><D6B7>
|
||||
UINT8 sublish[65]; //<2F><><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6>ĵ<EFBFBD>ַ
|
||||
|
||||
/*MQTT<54><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
MQTT_DATA mqtt_data;
|
||||
|
||||
}ALIYUN_INFO;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
|
||||
UINT8 ALiYun_Machine_Init(MQTT_INFO* Mqtt_info, char* ProductKey, char* deviceName, char* DeviceSecret, char* sublish, int keepAliveInterval);
|
||||
UINT8 ALIYUN_Flash_Parameter_Init(MQTT_INFO* Mqtt_info);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1135
BasicCode/Drive/MQTT/mqtt.c
Normal file
1135
BasicCode/Drive/MQTT/mqtt.c
Normal file
File diff suppressed because it is too large
Load Diff
166
BasicCode/Drive/MQTT/mqtt.h
Normal file
166
BasicCode/Drive/MQTT/mqtt.h
Normal file
@@ -0,0 +1,166 @@
|
||||
#ifndef _MQTT_H
|
||||
#define _MQTT_H
|
||||
|
||||
#include "CH57x_common.h" //CH57X <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD>
|
||||
#include "MQTTPacket.H"
|
||||
#include "net.h"
|
||||
#include "check_fun.h"
|
||||
#include "SRAM_Variable_Address.h"
|
||||
#include "BLV_Dev_Action.h"
|
||||
|
||||
#ifndef MQTT_EN
|
||||
#define MQTT_EN 1
|
||||
#endif
|
||||
|
||||
#define USER_NAME "34D0B8108D15&a1STn6qUB4r"
|
||||
#define PASSWORD "d9c0248ec19854b56d7bb79c30e34c54d68875a6"
|
||||
#define DOMAIN_NAME "a1STn6qUB4r.iot-as-mqtt.cn-shanghai.aliyuncs.com"
|
||||
#define CLIENT_ID "34D0B8108D15|securemode=3,signmethod=hmacsha1|"
|
||||
|
||||
#define SUB_TOPIC "sub_topic"
|
||||
#define PUB_TOPIC "pub_topic"
|
||||
|
||||
#define SRAM_MQTT_RECEIVE_START 0x030000 //MQTT<54><54><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ
|
||||
#define SRAM_MQTT_RECEIVE_END 0x030FFF //MQTT<54><54><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
#define SRAM_MQTT_RECEIVE_LEN 0x400 //MQTT<54><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>泤<EFBFBD><E6B3A4>
|
||||
|
||||
|
||||
#define CmdID_LEN 4
|
||||
#define DeviceID_LEN 6
|
||||
#define UTCTime_LEN 6
|
||||
|
||||
#define CMD_HEAD_ERROR 0x00 //ָ<><D6B8>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
|
||||
#define CMD_SUCCESS 0x01 //ִ<>гɹ<D0B3>
|
||||
#define CMD_CRC_ERROR 0x02 //CRC<52><43>֤ʧ<D6A4><CAA7>
|
||||
#define CMD_DEC_ERROR 0x03 //<2F><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
|
||||
#define CMD_DEV_NO 0xe1 //<2F>豸δ<E8B1B8><CEB4><EFBFBD><EFBFBD>
|
||||
|
||||
#define SRAM_MQTT_DEVICE_LIST_START 0x031000
|
||||
#define SRAM_MQTT_DEVICE_LIST_END 0x0313FF
|
||||
|
||||
#define Struct_CFG_Dev_Freego_Name_Len 20 //<2F><><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define Struct_CFG_Dev_Freego_Map_LEN 24 //<2F><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD>ṹ<EFBFBD>峤<EFBFBD><E5B3A4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>02
|
||||
#define CFG_Dev_Freego_Map_MAX 40 //֧<>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8> <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>tcp<63><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1K<31><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define HtolCpy(pdata, datau32) {pdata[0] = (datau32>>24)&0x000000ff;pdata[1] = (datau32>>16)&0x000000ff; \
|
||||
pdata[2] = (datau32>>8)&0x000000ff;pdata[3] = (datau32>>0)&0x000000ff;pdata[4] = ((SysTick_1ms%1000)>>8); \
|
||||
pdata[5] = (SysTick_1ms%1000);}//<2F><>u32<33><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڴ<D6BD><DAB4><EFBFBD><EFBFBD><EFBFBD>pdata
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CMD_PKT,
|
||||
CMDID_PKT,
|
||||
DEVICE_ID_PKT = 5,
|
||||
UTC_PKT = 11,
|
||||
PRAM_PKT = 17,
|
||||
}FREEG_PKT_E;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 init_flag:1; /* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>־λ */
|
||||
UINT8 con_flag:1; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MQTT<54><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ */
|
||||
UINT8 pub_flag:1; /* <20>ѷ<EFBFBD><D1B7><EFBFBD><EFBFBD>Ự<EFBFBD><E1BBB0>Ϣ<EFBFBD><CFA2>־λ */
|
||||
UINT8 sub_flag:1; /* <20>Ѷ<EFBFBD><D1B6>ĻỰ<C4BB><E1BBB0>־λ */
|
||||
UINT8 tout_flag:1; /* <20><>ʱ<EFBFBD><CAB1>־λ */
|
||||
UINT8 domain_dns:1; //mqtt<74><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
UINT8 reconnect:2; //<2F><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
UINT8 dns_en:1; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
UINT8 mqtt_socket:7; //<2F><><EFBFBD><EFBFBD>mqtt <20><EFBFBD><D7BD><EFBFBD>
|
||||
|
||||
UINT16 packetid; /* <20><>ID */
|
||||
|
||||
UINT8 MyBuf[RECE_BUF_LEN]; /* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||
|
||||
UINT8 des_ip[4]; //Ŀ<><C4BF>ip
|
||||
uint16_t keepAliveInterval; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
UINT32 sour_port; //Դ<>˿<EFBFBD>
|
||||
|
||||
char* domain_name; //<2F><><EFBFBD><EFBFBD>
|
||||
char* clientID; //clientID
|
||||
char *username; /* <20>û<EFBFBD><C3BB><EFBFBD> */
|
||||
char *password; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD> */
|
||||
char *sub_topic; /* <20><><EFBFBD>ĵĻỰ<C4BB><E1BBB0><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD>գ<EFBFBD>Ӧ<EFBFBD>뷢<EFBFBD><EBB7A2><EFBFBD>ĻỰ<C4BB><E1BBB0><EFBFBD><EFBFBD>ͬ */
|
||||
char *pub_topic; /* <20><><EFBFBD><EFBFBD><EFBFBD>ĻỰ*/
|
||||
|
||||
UINT32 Sram_read_addr; //MQTT<54><54><EFBFBD>մ<EFBFBD><D5B4><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
UINT32 Sram_write_addr; //MQTT<54><54><EFBFBD>յ<EFBFBD>ַ
|
||||
|
||||
uint8_t mqtt_sta; //2023-03-17
|
||||
uint32_t wait_cot; //2023-03-17
|
||||
uint8_t mqtt_cfail_num; //2023-03-17
|
||||
|
||||
}MQTT_INFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 publish[65]; //<2F><><EFBFBD><EFBFBD><EFBFBD>Ự<EFBFBD><E1BBB0>
|
||||
|
||||
UINT8 sublish[65]; //<2F><><EFBFBD>ĻỰ<C4BB><E1BBB0>
|
||||
|
||||
}MQTT_THEME; //mqtt<74><74><EFBFBD><EFBFBD>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MQTT_THEME mqtt_theme; //<2F><><EFBFBD><EFBFBD>
|
||||
|
||||
UINT8 domain_name[65]; //<2F><><EFBFBD><EFBFBD>
|
||||
|
||||
UINT8 clientID[65]; //clientID
|
||||
|
||||
UINT8 username[65]; /* <20>û<EFBFBD><C3BB><EFBFBD> */
|
||||
|
||||
UINT8 password[65]; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD> */
|
||||
|
||||
}MQTT_BASIC_INFO; //mqtt<74><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t keepAliveInterval; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
|
||||
MQTT_BASIC_INFO* mqtt_basic_info; //mqtt<74><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
}MQTT_DATA;
|
||||
|
||||
|
||||
//typedef struct CFG_Freego_Map_Add* CFG_Freego_Map_AddP; //<2F><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD>ָ<EFBFBD><D6B8> <20>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD>С<EFBFBD><D0A1>18<31><38><EFBFBD>ֽ<EFBFBD>
|
||||
typedef struct CFG_Freego_Map_Add
|
||||
{
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ*/
|
||||
uint8_t ServerDevType; //u8<75><38><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>豸<EFBFBD><E8B1B8>485<38>豸
|
||||
uint8_t ServerDevAddr; //u8<75><38><EFBFBD>豸<EFBFBD><E8B1B8>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>豸<EFBFBD><E8B1B8>ַĬ<D6B7><C4AC>Ϊ0<CEAA><30>485<38>豸<EFBFBD><E8B1B8>ַ<EFBFBD><D6B7>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>Ӧ<EFBFBD>豸<EFBFBD><E8B1B8>ʵ<EFBFBD>ʵ<EFBFBD>ַ
|
||||
uint16_t FreegoDevOutputLoop; //<2F><>·<EFBFBD><C2B7>ַ <20>dz<EFBFBD><C7B3><EFBFBD> <20><><EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>㣻 <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
|
||||
// uint8_t DevLoopAddr[4]; //<2F>豸<EFBFBD><E8B1B8>·<EFBFBD><C2B7>ַ <20>ֱ<EFBFBD><D6B1><EFBFBD>Ӧ<EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD> <20>豸<EFBFBD><E8B1B8>ַ <20><>·<EFBFBD><C2B7>ַL <20><>·<EFBFBD><C2B7>ַH
|
||||
uint8_t DevLoopName[20]; //<2F>豸<EFBFBD><E8B1B8>·<EFBFBD><C2B7>ַ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>
|
||||
|
||||
}__attribute__ ((__packed__))Struct_CFG_Freego_Map_Add; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><E1B9B9>
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#if MQTT_EN
|
||||
extern MQTT_INFO mqtt_info;
|
||||
//extern MQTT_INFO mqtt_info2;
|
||||
#endif
|
||||
|
||||
UINT8 Transport_Open(MQTT_INFO* Mqtt_info, UINT8* des_ip, UINT32 sour_port);
|
||||
UINT8 Transport_Close(UINT8 S);
|
||||
//void MQTT_Connect(UINT8 S, char *username,char *password);
|
||||
void MQTT_Connect(UINT8 S, char* clientID, char *username, char *password, int keepAliveInterval);
|
||||
void MQTT_Subscribe(UINT8 S, char *topic);
|
||||
void MQTT_Unsubscribe(UINT8 S, char *topic);
|
||||
//void MQTT_Publish(UINT8 S, char *topic, char *payload);
|
||||
void MQTT_Publish(UINT8 S, char *topic, UINT8 *payload, int payloadlen, int qos);
|
||||
void MQTT_Pingreq(UINT8 S);
|
||||
void MQTT_Disconnect(UINT8 S);
|
||||
void CH57xNET_CreatTcpSocket(void);
|
||||
|
||||
UINT8 MQTT_Init(MQTT_INFO* Mqtt_info, char* domain_name, UINT8* des_ip, char* clientID, char *username, char *password, char* sublish, int keepAliveInterval);
|
||||
UINT8 MQTT_Flash_Parameter_Init(MQTT_INFO* Mqtt_info);
|
||||
|
||||
void MQTT_SET_SUB_Topic(MQTT_INFO* Mqtt_info, char* topic);
|
||||
void MQTT_SET_PUB_Topic(MQTT_INFO* Mqtt_info, char* topic);
|
||||
void MQTT_Receive_Processing(void);
|
||||
#endif
|
||||
162
BasicCode/Drive/MQTT/utils_hmac.c
Normal file
162
BasicCode/Drive/MQTT/utils_hmac.c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include "utils_hmac.h"
|
||||
#include "utils_md5.h"
|
||||
#include "utils_sha1.h"
|
||||
|
||||
#define KEY_IOPAD_SIZE 64
|
||||
#define MD5_DIGEST_SIZE 16
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
//const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/*-------------------------------------------------*/
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hmacmd5<64><35><EFBFBD><EFBFBD> */
|
||||
/*<2A><><EFBFBD><EFBFBD>Ѱ<EFBFBD>ҵĿ<D2B5>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD> */
|
||||
/*-------------------------------------------------*/
|
||||
void utils_hmac_md5(const char *msg, int msg_len, char *digest, const char *key, int key_len)
|
||||
{
|
||||
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
|
||||
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
|
||||
unsigned char out[MD5_DIGEST_SIZE];
|
||||
int i;
|
||||
iot_md5_context context;
|
||||
|
||||
if((NULL == msg) || (NULL == digest) || (NULL == key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(key_len > KEY_IOPAD_SIZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* start out by storing key in pads */
|
||||
memset(k_ipad, 0, sizeof(k_ipad));
|
||||
memset(k_opad, 0, sizeof(k_opad));
|
||||
memcpy(k_ipad, key, key_len);
|
||||
memcpy(k_opad, key, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
/* perform inner MD5 */
|
||||
utils_md5_init(&context); /* init context for 1st pass */
|
||||
utils_md5_starts(&context); /* setup context for 1st pass */
|
||||
utils_md5_update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
|
||||
utils_md5_update(&context, (unsigned char *) msg, msg_len); /* then text of datagram */
|
||||
utils_md5_finish(&context, out); /* finish up 1st pass */
|
||||
|
||||
/* perform outer MD5 */
|
||||
utils_md5_init(&context); /* init context for 2nd pass */
|
||||
utils_md5_starts(&context); /* setup context for 2nd pass */
|
||||
utils_md5_update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
|
||||
utils_md5_update(&context, out, MD5_DIGEST_SIZE); /* then results of 1st hash */
|
||||
utils_md5_finish(&context, out); /* finish up 2nd pass */
|
||||
|
||||
for (i = 0; i < MD5_DIGEST_SIZE; ++i) {
|
||||
digest[i * 2] = utils_hb2hex(out[i] >> 4);
|
||||
digest[i * 2 + 1] = utils_hb2hex(out[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*/
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hmacsha1<61><31><EFBFBD><EFBFBD> */
|
||||
/*<2A><><EFBFBD><EFBFBD>Ѱ<EFBFBD>ҵĿ<D2B5>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD> */
|
||||
/*-------------------------------------------------*/
|
||||
void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len)
|
||||
{
|
||||
iot_sha1_context context;
|
||||
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
|
||||
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
|
||||
unsigned char out[SHA1_DIGEST_SIZE];
|
||||
int i;
|
||||
|
||||
if((NULL == msg) || (NULL == digest) || (NULL == key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(key_len > KEY_IOPAD_SIZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* start out by storing key in pads */
|
||||
memset(k_ipad, 0, sizeof(k_ipad));
|
||||
memset(k_opad, 0, sizeof(k_opad));
|
||||
memcpy(k_ipad, key, key_len);
|
||||
memcpy(k_opad, key, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
/* perform inner SHA */
|
||||
utils_sha1_init(&context); /* init context for 1st pass */
|
||||
utils_sha1_starts(&context); /* setup context for 1st pass */
|
||||
utils_sha1_update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
|
||||
utils_sha1_update(&context, (unsigned char *) msg, msg_len); /* then text of datagram */
|
||||
utils_sha1_finish(&context, out); /* finish up 1st pass */
|
||||
|
||||
/* perform outer SHA */
|
||||
utils_sha1_init(&context); /* init context for 2nd pass */
|
||||
utils_sha1_starts(&context); /* setup context for 2nd pass */
|
||||
utils_sha1_update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
|
||||
utils_sha1_update(&context, out, SHA1_DIGEST_SIZE); /* then results of 1st hash */
|
||||
utils_sha1_finish(&context, out); /* finish up 2nd pass */
|
||||
|
||||
for (i = 0; i < SHA1_DIGEST_SIZE; ++i) {
|
||||
digest[i * 2] = utils_hb2hex(out[i] >> 4);
|
||||
digest[i * 2 + 1] = utils_hb2hex(out[i]);
|
||||
}
|
||||
}
|
||||
|
||||
///*-------------------------------------------------*/
|
||||
///*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>base64<36><34><EFBFBD><EFBFBD> */
|
||||
///*<2A><><EFBFBD><EFBFBD>Ѱ<EFBFBD>ҵĿ<D2B5>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD> */
|
||||
///*-------------------------------------------------*/
|
||||
//int base64_decode( const char * base64, unsigned char * bindata )
|
||||
//{
|
||||
// int i, j;
|
||||
// unsigned char k;
|
||||
// unsigned char temp[4];
|
||||
// for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )
|
||||
// {
|
||||
// memset( temp, 0xFF, sizeof(temp) );
|
||||
// for ( k = 0 ; k < 64 ; k ++ )
|
||||
// {
|
||||
// if ( base64char[k] == base64[i] )
|
||||
// temp[0]= k;
|
||||
// }
|
||||
// for ( k = 0 ; k < 64 ; k ++ )
|
||||
// {
|
||||
// if ( base64char[k] == base64[i+1] )
|
||||
// temp[1]= k;
|
||||
// }
|
||||
// for ( k = 0 ; k < 64 ; k ++ )
|
||||
// {
|
||||
// if ( base64char[k] == base64[i+2] )
|
||||
// temp[2]= k;
|
||||
// }
|
||||
// for ( k = 0 ; k < 64 ; k ++ )
|
||||
// {
|
||||
// if ( base64char[k] == base64[i+3] )
|
||||
// temp[3]= k;
|
||||
// }
|
||||
|
||||
// bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
|
||||
// ((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
|
||||
// if ( base64[i+2] == '=' )
|
||||
// break;
|
||||
|
||||
// bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
|
||||
// ((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
|
||||
// if ( base64[i+3] == '=' )
|
||||
// break;
|
||||
|
||||
// bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
|
||||
// ((unsigned char)(temp[3]&0x3F));
|
||||
// }
|
||||
// return j;
|
||||
//}
|
||||
14
BasicCode/Drive/MQTT/utils_hmac.h
Normal file
14
BasicCode/Drive/MQTT/utils_hmac.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef UTILS_HMAC_H_
|
||||
#define UTILS_HMAC_H_
|
||||
|
||||
#include "stdio.h"
|
||||
#include "stdint.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
void utils_hmac_md5(const char *msg, int msg_len, char *digest, const char *key, int key_len);
|
||||
void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len);
|
||||
//int base64_decode( const char * base64, unsigned char * bindata );
|
||||
|
||||
#endif
|
||||
|
||||
291
BasicCode/Drive/MQTT/utils_md5.c
Normal file
291
BasicCode/Drive/MQTT/utils_md5.c
Normal file
@@ -0,0 +1,291 @@
|
||||
#include "utils_md5.h"
|
||||
|
||||
#define MD5_DIGEST_SIZE 16
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void _utils_md5_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = v;
|
||||
while (n--) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
#ifndef IOT_MD5_GET_UINT32_LE
|
||||
#define IOT_MD5_GET_UINT32_LE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef IOT_MD5_PUT_UINT32_LE
|
||||
#define IOT_MD5_PUT_UINT32_LE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void utils_md5_init(iot_md5_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(iot_md5_context));
|
||||
}
|
||||
|
||||
void utils_md5_free(iot_md5_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_utils_md5_zeroize(ctx, sizeof(iot_md5_context));
|
||||
}
|
||||
|
||||
void utils_md5_clone(iot_md5_context *dst,
|
||||
const iot_md5_context *src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 context setup
|
||||
*/
|
||||
void utils_md5_starts(iot_md5_context *ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void utils_md5_process(iot_md5_context *ctx, const unsigned char data[64])
|
||||
{
|
||||
uint32_t X[16], A, B, C, D;
|
||||
|
||||
IOT_MD5_GET_UINT32_LE(X[ 0], data, 0);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 1], data, 4);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 2], data, 8);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 3], data, 12);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 4], data, 16);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 5], data, 20);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 6], data, 24);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 7], data, 28);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 8], data, 32);
|
||||
IOT_MD5_GET_UINT32_LE(X[ 9], data, 36);
|
||||
IOT_MD5_GET_UINT32_LE(X[10], data, 40);
|
||||
IOT_MD5_GET_UINT32_LE(X[11], data, 44);
|
||||
IOT_MD5_GET_UINT32_LE(X[12], data, 48);
|
||||
IOT_MD5_GET_UINT32_LE(X[13], data, 52);
|
||||
IOT_MD5_GET_UINT32_LE(X[14], data, 56);
|
||||
IOT_MD5_GET_UINT32_LE(X[15], data, 60);
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define P(a,b,c,d,k,s,t) \
|
||||
{ \
|
||||
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
P(A, B, C, D, 0, 7, 0xD76AA478);
|
||||
P(D, A, B, C, 1, 12, 0xE8C7B756);
|
||||
P(C, D, A, B, 2, 17, 0x242070DB);
|
||||
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
|
||||
P(A, B, C, D, 4, 7, 0xF57C0FAF);
|
||||
P(D, A, B, C, 5, 12, 0x4787C62A);
|
||||
P(C, D, A, B, 6, 17, 0xA8304613);
|
||||
P(B, C, D, A, 7, 22, 0xFD469501);
|
||||
P(A, B, C, D, 8, 7, 0x698098D8);
|
||||
P(D, A, B, C, 9, 12, 0x8B44F7AF);
|
||||
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
|
||||
P(B, C, D, A, 11, 22, 0x895CD7BE);
|
||||
P(A, B, C, D, 12, 7, 0x6B901122);
|
||||
P(D, A, B, C, 13, 12, 0xFD987193);
|
||||
P(C, D, A, B, 14, 17, 0xA679438E);
|
||||
P(B, C, D, A, 15, 22, 0x49B40821);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (y ^ (z & (x ^ y)))
|
||||
|
||||
P(A, B, C, D, 1, 5, 0xF61E2562);
|
||||
P(D, A, B, C, 6, 9, 0xC040B340);
|
||||
P(C, D, A, B, 11, 14, 0x265E5A51);
|
||||
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
|
||||
P(A, B, C, D, 5, 5, 0xD62F105D);
|
||||
P(D, A, B, C, 10, 9, 0x02441453);
|
||||
P(C, D, A, B, 15, 14, 0xD8A1E681);
|
||||
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
|
||||
P(A, B, C, D, 9, 5, 0x21E1CDE6);
|
||||
P(D, A, B, C, 14, 9, 0xC33707D6);
|
||||
P(C, D, A, B, 3, 14, 0xF4D50D87);
|
||||
P(B, C, D, A, 8, 20, 0x455A14ED);
|
||||
P(A, B, C, D, 13, 5, 0xA9E3E905);
|
||||
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
|
||||
P(C, D, A, B, 7, 14, 0x676F02D9);
|
||||
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
|
||||
P(A, B, C, D, 5, 4, 0xFFFA3942);
|
||||
P(D, A, B, C, 8, 11, 0x8771F681);
|
||||
P(C, D, A, B, 11, 16, 0x6D9D6122);
|
||||
P(B, C, D, A, 14, 23, 0xFDE5380C);
|
||||
P(A, B, C, D, 1, 4, 0xA4BEEA44);
|
||||
P(D, A, B, C, 4, 11, 0x4BDECFA9);
|
||||
P(C, D, A, B, 7, 16, 0xF6BB4B60);
|
||||
P(B, C, D, A, 10, 23, 0xBEBFBC70);
|
||||
P(A, B, C, D, 13, 4, 0x289B7EC6);
|
||||
P(D, A, B, C, 0, 11, 0xEAA127FA);
|
||||
P(C, D, A, B, 3, 16, 0xD4EF3085);
|
||||
P(B, C, D, A, 6, 23, 0x04881D05);
|
||||
P(A, B, C, D, 9, 4, 0xD9D4D039);
|
||||
P(D, A, B, C, 12, 11, 0xE6DB99E5);
|
||||
P(C, D, A, B, 15, 16, 0x1FA27CF8);
|
||||
P(B, C, D, A, 2, 23, 0xC4AC5665);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (y ^ (x | ~z))
|
||||
|
||||
P(A, B, C, D, 0, 6, 0xF4292244);
|
||||
P(D, A, B, C, 7, 10, 0x432AFF97);
|
||||
P(C, D, A, B, 14, 15, 0xAB9423A7);
|
||||
P(B, C, D, A, 5, 21, 0xFC93A039);
|
||||
P(A, B, C, D, 12, 6, 0x655B59C3);
|
||||
P(D, A, B, C, 3, 10, 0x8F0CCC92);
|
||||
P(C, D, A, B, 10, 15, 0xFFEFF47D);
|
||||
P(B, C, D, A, 1, 21, 0x85845DD1);
|
||||
P(A, B, C, D, 8, 6, 0x6FA87E4F);
|
||||
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
|
||||
P(C, D, A, B, 6, 15, 0xA3014314);
|
||||
P(B, C, D, A, 13, 21, 0x4E0811A1);
|
||||
P(A, B, C, D, 4, 6, 0xF7537E82);
|
||||
P(D, A, B, C, 11, 10, 0xBD3AF235);
|
||||
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
|
||||
P(B, C, D, A, 9, 21, 0xEB86D391);
|
||||
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 process buffer
|
||||
*/
|
||||
void utils_md5_update(iot_md5_context *ctx, const unsigned char *input, size_t ilen)
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if (ilen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < (uint32_t) ilen) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
if (left && ilen >= fill) {
|
||||
memcpy((void *)(ctx->buffer + left), input, fill);
|
||||
utils_md5_process(ctx, ctx->buffer);
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (ilen >= 64) {
|
||||
utils_md5_process(ctx, input);
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if (ilen > 0) {
|
||||
memcpy((void *)(ctx->buffer + left), input, ilen);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char iot_md5_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* MD5 final digest
|
||||
*/
|
||||
void utils_md5_finish(iot_md5_context *ctx, unsigned char output[16])
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = (ctx->total[0] >> 29)
|
||||
| (ctx->total[1] << 3);
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
IOT_MD5_PUT_UINT32_LE(low, msglen, 0);
|
||||
IOT_MD5_PUT_UINT32_LE(high, msglen, 4);
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
utils_md5_update(ctx, iot_md5_padding, padn);
|
||||
utils_md5_update(ctx, msglen, 8);
|
||||
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[0], output, 0);
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[1], output, 4);
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[2], output, 8);
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[3], output, 12);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* output = MD5( input buffer )
|
||||
*/
|
||||
void utils_md5(const unsigned char *input, size_t ilen, unsigned char output[16])
|
||||
{
|
||||
iot_md5_context ctx;
|
||||
|
||||
utils_md5_init(&ctx);
|
||||
utils_md5_starts(&ctx);
|
||||
utils_md5_update(&ctx, input, ilen);
|
||||
utils_md5_finish(&ctx, output);
|
||||
utils_md5_free(&ctx);
|
||||
}
|
||||
|
||||
int8_t utils_hb2hex(uint8_t hb)
|
||||
{
|
||||
hb = hb & 0xF;
|
||||
return (int8_t)(hb < 10 ? '0' + hb : hb - 10 + 'a');
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
80
BasicCode/Drive/MQTT/utils_md5.h
Normal file
80
BasicCode/Drive/MQTT/utils_md5.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef UTILS_MD5_H_
|
||||
#define UTILS_MD5_H_
|
||||
|
||||
#include "stdio.h"
|
||||
#include "stdint.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[4]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
} iot_md5_context;
|
||||
|
||||
|
||||
/**
|
||||
* @brief <20><>ʼ<EFBFBD><CABC>MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param ctx MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
*/
|
||||
void utils_md5_init(iot_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param ctx MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
*/
|
||||
void utils_md5_free(iot_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param dst Ŀ<><C4BF>MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param src ԴMD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void utils_md5_clone(iot_md5_context *dst,
|
||||
const iot_md5_context *src);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param ctx MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
*/
|
||||
void utils_md5_starts(iot_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief MD5<44><35><EFBFBD>̻<EFBFBD><CCBB><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param ctx MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
* @param input <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param ilen <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
*/
|
||||
void utils_md5_update(iot_md5_context *ctx, const unsigned char *input, size_t ilen);
|
||||
|
||||
/**
|
||||
* @brief MD5<44><35><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param ctx MD5<44><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
* @param output MD5У<35><D0A3><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
|
||||
*/
|
||||
void utils_md5_finish(iot_md5_context *ctx, unsigned char output[16]);
|
||||
|
||||
/* <20>ڲ<EFBFBD>ʹ<EFBFBD><CAB9> */
|
||||
void utils_md5_process(iot_md5_context *ctx, const unsigned char data[64]);
|
||||
|
||||
/**
|
||||
* @brief Output = MD5( input buffer )
|
||||
*
|
||||
* @param input <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param ilen <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
* @param output MD5У<35><D0A3><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
|
||||
*/
|
||||
void utils_md5(const unsigned char *input, size_t ilen, unsigned char output[16]);
|
||||
|
||||
|
||||
int8_t utils_hb2hex(uint8_t hb);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
316
BasicCode/Drive/MQTT/utils_sha1.c
Normal file
316
BasicCode/Drive/MQTT/utils_sha1.c
Normal file
@@ -0,0 +1,316 @@
|
||||
#include "utils_sha1.h"
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void utils_sha1_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = v;
|
||||
while (n--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef IOT_SHA1_GET_UINT32_BE
|
||||
#define IOT_SHA1_GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef IOT_SHA1_PUT_UINT32_BE
|
||||
#define IOT_SHA1_PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void utils_sha1_init(iot_sha1_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(iot_sha1_context));
|
||||
}
|
||||
|
||||
void utils_sha1_free(iot_sha1_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
utils_sha1_zeroize(ctx, sizeof(iot_sha1_context));
|
||||
}
|
||||
|
||||
void utils_sha1_clone(iot_sha1_context *dst,
|
||||
const iot_sha1_context *src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
void utils_sha1_starts(iot_sha1_context *ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64])
|
||||
{
|
||||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 0], data, 0);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 1], data, 4);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 2], data, 8);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 3], data, 12);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 4], data, 16);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 5], data, 20);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 6], data, 24);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 7], data, 28);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 8], data, 32);
|
||||
IOT_SHA1_GET_UINT32_BE(W[ 9], data, 36);
|
||||
IOT_SHA1_GET_UINT32_BE(W[10], data, 40);
|
||||
IOT_SHA1_GET_UINT32_BE(W[11], data, 44);
|
||||
IOT_SHA1_GET_UINT32_BE(W[12], data, 48);
|
||||
IOT_SHA1_GET_UINT32_BE(W[13], data, 52);
|
||||
IOT_SHA1_GET_UINT32_BE(W[14], data, 56);
|
||||
IOT_SHA1_GET_UINT32_BE(W[15], data, 60);
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
|
||||
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
|
||||
( W[t & 0x0F] = S(temp,1) ) \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,x) \
|
||||
{ \
|
||||
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define K 0x5A827999
|
||||
|
||||
P(A, B, C, D, E, W[0]);
|
||||
P(E, A, B, C, D, W[1]);
|
||||
P(D, E, A, B, C, W[2]);
|
||||
P(C, D, E, A, B, W[3]);
|
||||
P(B, C, D, E, A, W[4]);
|
||||
P(A, B, C, D, E, W[5]);
|
||||
P(E, A, B, C, D, W[6]);
|
||||
P(D, E, A, B, C, W[7]);
|
||||
P(C, D, E, A, B, W[8]);
|
||||
P(B, C, D, E, A, W[9]);
|
||||
P(A, B, C, D, E, W[10]);
|
||||
P(E, A, B, C, D, W[11]);
|
||||
P(D, E, A, B, C, W[12]);
|
||||
P(C, D, E, A, B, W[13]);
|
||||
P(B, C, D, E, A, W[14]);
|
||||
P(A, B, C, D, E, W[15]);
|
||||
P(E, A, B, C, D, R(16));
|
||||
P(D, E, A, B, C, R(17));
|
||||
P(C, D, E, A, B, R(18));
|
||||
P(B, C, D, E, A, R(19));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0x6ED9EBA1
|
||||
|
||||
P(A, B, C, D, E, R(20));
|
||||
P(E, A, B, C, D, R(21));
|
||||
P(D, E, A, B, C, R(22));
|
||||
P(C, D, E, A, B, R(23));
|
||||
P(B, C, D, E, A, R(24));
|
||||
P(A, B, C, D, E, R(25));
|
||||
P(E, A, B, C, D, R(26));
|
||||
P(D, E, A, B, C, R(27));
|
||||
P(C, D, E, A, B, R(28));
|
||||
P(B, C, D, E, A, R(29));
|
||||
P(A, B, C, D, E, R(30));
|
||||
P(E, A, B, C, D, R(31));
|
||||
P(D, E, A, B, C, R(32));
|
||||
P(C, D, E, A, B, R(33));
|
||||
P(B, C, D, E, A, R(34));
|
||||
P(A, B, C, D, E, R(35));
|
||||
P(E, A, B, C, D, R(36));
|
||||
P(D, E, A, B, C, R(37));
|
||||
P(C, D, E, A, B, R(38));
|
||||
P(B, C, D, E, A, R(39));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define K 0x8F1BBCDC
|
||||
|
||||
P(A, B, C, D, E, R(40));
|
||||
P(E, A, B, C, D, R(41));
|
||||
P(D, E, A, B, C, R(42));
|
||||
P(C, D, E, A, B, R(43));
|
||||
P(B, C, D, E, A, R(44));
|
||||
P(A, B, C, D, E, R(45));
|
||||
P(E, A, B, C, D, R(46));
|
||||
P(D, E, A, B, C, R(47));
|
||||
P(C, D, E, A, B, R(48));
|
||||
P(B, C, D, E, A, R(49));
|
||||
P(A, B, C, D, E, R(50));
|
||||
P(E, A, B, C, D, R(51));
|
||||
P(D, E, A, B, C, R(52));
|
||||
P(C, D, E, A, B, R(53));
|
||||
P(B, C, D, E, A, R(54));
|
||||
P(A, B, C, D, E, R(55));
|
||||
P(E, A, B, C, D, R(56));
|
||||
P(D, E, A, B, C, R(57));
|
||||
P(C, D, E, A, B, R(58));
|
||||
P(B, C, D, E, A, R(59));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0xCA62C1D6
|
||||
|
||||
P(A, B, C, D, E, R(60));
|
||||
P(E, A, B, C, D, R(61));
|
||||
P(D, E, A, B, C, R(62));
|
||||
P(C, D, E, A, B, R(63));
|
||||
P(B, C, D, E, A, R(64));
|
||||
P(A, B, C, D, E, R(65));
|
||||
P(E, A, B, C, D, R(66));
|
||||
P(D, E, A, B, C, R(67));
|
||||
P(C, D, E, A, B, R(68));
|
||||
P(B, C, D, E, A, R(69));
|
||||
P(A, B, C, D, E, R(70));
|
||||
P(E, A, B, C, D, R(71));
|
||||
P(D, E, A, B, C, R(72));
|
||||
P(C, D, E, A, B, R(73));
|
||||
P(B, C, D, E, A, R(74));
|
||||
P(A, B, C, D, E, R(75));
|
||||
P(E, A, B, C, D, R(76));
|
||||
P(D, E, A, B, C, R(77));
|
||||
P(C, D, E, A, B, R(78));
|
||||
P(B, C, D, E, A, R(79));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen)
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if (ilen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < (uint32_t) ilen) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
if (left && ilen >= fill) {
|
||||
memcpy((void *)(ctx->buffer + left), input, fill);
|
||||
utils_sha1_process(ctx, ctx->buffer);
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (ilen >= 64) {
|
||||
utils_sha1_process(ctx, input);
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if (ilen > 0) {
|
||||
memcpy((void *)(ctx->buffer + left), input, ilen);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char iot_sha1_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20])
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = (ctx->total[0] >> 29)
|
||||
| (ctx->total[1] << 3);
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
IOT_SHA1_PUT_UINT32_BE(high, msglen, 0);
|
||||
IOT_SHA1_PUT_UINT32_BE(low, msglen, 4);
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
utils_sha1_update(ctx, iot_sha1_padding, padn);
|
||||
utils_sha1_update(ctx, msglen, 8);
|
||||
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[0], output, 0);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[1], output, 4);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[2], output, 8);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[3], output, 12);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[4], output, 16);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* output = SHA-1( input buffer )
|
||||
*/
|
||||
void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20])
|
||||
{
|
||||
iot_sha1_context ctx;
|
||||
|
||||
utils_sha1_init(&ctx);
|
||||
utils_sha1_starts(&ctx);
|
||||
utils_sha1_update(&ctx, input, ilen);
|
||||
utils_sha1_finish(&ctx, output);
|
||||
utils_sha1_free(&ctx);
|
||||
}
|
||||
78
BasicCode/Drive/MQTT/utils_sha1.h
Normal file
78
BasicCode/Drive/MQTT/utils_sha1.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef UTILS_SHA1_H_
|
||||
#define UTILS_SHA1_H_
|
||||
|
||||
#include "stdio.h"
|
||||
#include "stdint.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
} iot_sha1_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be initialized
|
||||
*/
|
||||
void utils_sha1_init(iot_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be cleared
|
||||
*/
|
||||
void utils_sha1_free(iot_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-1 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void utils_sha1_clone(iot_sha1_context *dst,
|
||||
const iot_sha1_context *src);
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void utils_sha1_starts(iot_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process buffer
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief SHA-1 final digest
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20]);
|
||||
|
||||
/* Internal use */
|
||||
void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64]);
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-1( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20]);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user