doubao_chat/lib/net/dui/dui_iot_mqtt.c

293 lines
7.4 KiB
C

#include <string.h>
#include <time.h>
#include "mbedtls/base64.h"
#include "iot_rsa.h"
#include "iot_mqtt.h"
#ifdef DUI_MEMHEAP_DEBUG
#include "mem_leak_test.h"
#endif
#define xerror printf
#define xinfo printf
#define DUI_MQTT_QOS QOS0
static iot_mqtt_t *g_iot_mqtt = NULL;
static void mqtt_msg_callback(MessageData *md)
{
if ((NULL == md)
|| (NULL == md->message)
|| (NULL == md->message->payload)
|| (0 == md->message->payloadlen)) {
xerror("Input parameters are invalid !\n");
return;
}
if (g_iot_mqtt->msg_callback != NULL && g_iot_mqtt->param != NULL) {
g_iot_mqtt->msg_callback(g_iot_mqtt->param, md->message->payload, md->message->payloadlen);
memset(md->message->payload, 0, md->message->payloadlen);
}
}
static char *rsa_encrypt(const char *src)
{
char *ciphertext = (char *)malloc(256);
if (ciphertext == NULL) {
return NULL;
}
memset(ciphertext, 0, 256);
speech_rsa_encrypt(src, strlen(src), ciphertext);
return ciphertext;
}
static time_t get_timestamp(void)
{
#if 1
return time(NULL);
#else
struct timeval ntp_time;
struct tm *time = NULL;
if (sntp_get_time(NULL, &ntp_time) == 0) {
time = localtime(&ntp_time.tv_sec);
LOG_D("ntp timer tv_sec %d\n", ntp_time.tv_sec);
LOG_D("<sntp> %u-%02u-%02u %02u:%02u:%02u %02u\n",
time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec, time->tm_wday);
}
return ntp_time.tv_sec;
#endif
}
static int get_RSA_base64_password(const char *username, char *password)
{
char temp[256];
size_t len = 0;
time_t timestamp = get_timestamp();
sprintf(temp, "%s###%ld", username, timestamp);
xinfo("%s", temp);
char *rsa = rsa_encrypt(temp);
if (rsa != NULL) {
if (mbedtls_base64_encode((unsigned char *)password, 256, &len,
(const unsigned char *)rsa, 128) != 0) {
xerror("mbedtls_base64_encode failed\n");
free(rsa);
rsa = NULL;
return -1;
} else {
free(rsa);
rsa = NULL;
return 0;
}
} else {
xerror("rsa_encrypt_test failed\n");
return -1;
}
}
static int sock_cb_func(enum sock_api_msg_type type, void *priv)
{
iot_mqtt_t *iot_mqtt = (iot_mqtt_t *)priv;
if (iot_mqtt->exit_flag) {
return -1;
}
return 0;
}
int dui_iot_mqtt_connect(iot_mqtt_t *iot_mqtt)
{
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
NewNetwork(&iot_mqtt->network);
SetNetworkCb(&iot_mqtt->network, sock_cb_func, iot_mqtt);
if (0 != ConnectNetwork(&iot_mqtt->network, iot_mqtt->server, iot_mqtt->port)) {
iot_mqtt->network.disconnect(&iot_mqtt->network);
xerror("ConnectNetwork failed\n");
return -1;
}
SetNetworkRecvTimeout(&iot_mqtt->network, 1000);
iot_mqtt->network_connected = true;
MQTTClient(
&iot_mqtt->client,
&iot_mqtt->network,
2000,
iot_mqtt->send_buffer,
MQTT_PROC_BUF_SIZE,
iot_mqtt->recv_buffer,
MQTT_PROC_BUF_SIZE);
char password[256] = {0};
get_RSA_base64_password(iot_mqtt->deviceid, password);
data.MQTTVersion = 4;
data.clientID.cstring = iot_mqtt->clientid;
data.username.cstring = iot_mqtt->deviceid;
data.password.cstring = password;
data.keepAliveInterval = 30;
data.cleansession = 1;
data.willFlag = 1;
char will_topic[128] = {0};
sprintf(will_topic, "%s_will", iot_mqtt->topic);
char will_message[256] = {0};
sprintf(will_message, "{\"name\":\"toy\",\"userid\":\"%s\",\"deviceid\":\"%s\",\"data\":{},\"do\":\"will\"}",
"", iot_mqtt->deviceid);
data.will.topicName.cstring = will_topic;
data.will.message.cstring = will_message;
xinfo("clientID: %s\n", data.clientID.cstring);
xinfo("username: %s\n", data.username.cstring);
xinfo("password: %s\n", data.password.cstring);
if (0 != MQTTConnect(&iot_mqtt->client, &data)) {
xerror("MQTTConnect failed\n");
return -1;
}
iot_mqtt->client_connected = true;
if (0 != MQTTSubscribe(&iot_mqtt->client, iot_mqtt->deviceid, DUI_MQTT_QOS, mqtt_msg_callback)) {
xerror("MQTTSubscribe failed\n");
return -1;
}
xinfo("MQTTConnect success\n");
return 0;
}
void dui_iot_mqtt_disconnect(iot_mqtt_t *iot_mqtt)
{
if (true == iot_mqtt->client_connected) {
iot_mqtt->client_connected = false;
MQTTDisconnect(&iot_mqtt->client);
}
if (true == iot_mqtt->network_connected) {
iot_mqtt->network_connected = false;
iot_mqtt->network.disconnect(&iot_mqtt->network);
}
}
int dui_iot_mqtt_send(iot_mqtt_t *iot_mqtt, void *buf, int size)
{
MQTTMessage message;
if (NULL == iot_mqtt || NULL == buf || size == 0) {
return 0;
}
message.id = 0;
message.qos = DUI_MQTT_QOS;
message.retained = false;
message.dup = false;
message.payload = buf;
message.payloadlen = size;
if (0 != MQTTPublish(&iot_mqtt->client, iot_mqtt->topic, &message)) {
xerror("MQTT msg publish failed!\n");
return -1;
}
return 0;
}
int dui_iot_mqtt_yield(iot_mqtt_t *iot_mqtt)
{
return MQTTYield(&iot_mqtt->client, 1000);
}
int dui_iot_register_callback(iot_mqtt_t *iot_mqtt,
void (*msg_callback)(void *, void *, int),
void *param)
{
if (iot_mqtt == NULL || msg_callback == NULL || param == NULL) {
return -1;
}
iot_mqtt->param = param;
iot_mqtt->msg_callback = msg_callback;
return 0;
}
int dui_iot_mqtt_init(iot_mqtt_t *iot_mqtt, const char *srv, int port, const char *topic, const char *deviceid)
{
if (iot_mqtt == NULL || srv == NULL || topic == NULL || deviceid == NULL) {
return -1;
}
iot_mqtt->server = (char *)malloc(strlen(srv) + 1);
if (iot_mqtt->server == NULL) {
goto err_exit;
}
strcpy(iot_mqtt->server, srv);
iot_mqtt->port = port;
iot_mqtt->topic = (char *)malloc(strlen(topic) + 1);
if (iot_mqtt->topic == NULL) {
goto err_exit;
}
strcpy(iot_mqtt->topic, topic);
iot_mqtt->deviceid = (char *)malloc(strlen(deviceid) + 1);
if (iot_mqtt->deviceid == NULL) {
goto err_exit;
}
strcpy(iot_mqtt->deviceid, deviceid);
iot_mqtt->clientid = (char *)malloc(strlen(deviceid) + 4);
if (iot_mqtt->clientid == NULL) {
goto err_exit;
}
sprintf(iot_mqtt->clientid, "CID%s", deviceid);
iot_mqtt->network_connected = false;
iot_mqtt->client_connected = false;
iot_mqtt->param = NULL;
iot_mqtt->msg_callback = NULL;
g_iot_mqtt = iot_mqtt;
return 0;
err_exit:
dui_iot_mqtt_deinit(iot_mqtt);
return -1;
}
void dui_iot_mqtt_deinit(iot_mqtt_t *iot_mqtt)
{
if (iot_mqtt->server) {
free(iot_mqtt->server);
iot_mqtt->server = NULL;
}
if (iot_mqtt->topic) {
free(iot_mqtt->topic);
iot_mqtt->topic = NULL;
}
if (iot_mqtt->deviceid) {
free(iot_mqtt->deviceid);
iot_mqtt->deviceid = NULL;
}
if (iot_mqtt->clientid) {
free(iot_mqtt->clientid);
iot_mqtt->clientid = NULL;
}
iot_mqtt->param = NULL;
iot_mqtt->msg_callback = NULL;
g_iot_mqtt = NULL;
}