Skip to content

Instantly share code, notes, and snippets.

@Thalhammer
Created July 10, 2019 13:52
Show Gist options
  • Save Thalhammer/b60ccbe7d8777debd2ce43796791ce17 to your computer and use it in GitHub Desktop.
Save Thalhammer/b60ccbe7d8777debd2ce43796791ce17 to your computer and use it in GitHub Desktop.
MQTTS Simcom
#include <stdlib.h>
#include <stdbool.h>
#include "qapi/qapi_types.h"
#include "qapi/qapi.h"
#include "qapi/qapi_status.h"
#include "qapi/qapi_tlmm.h"
#include "qapi/qapi_timer.h"
#include "qapi/qapi_socket.h"
#include "qapi/qapi_ns_utils.h"
#include "qapi/qapi_dnsc.h"
#include "qapi/qapi_mqtt.h"
#include "util/debug.h"
#include "util/trace.h"
#include "util/netmgr.h"
#include "util/htons.h"
#include "util/boot_cfg.h"
#include "stdio.h"
#include "txm_module.h"
#include "../../config.h"
#define TRACE_TAG "main"
// Uncomment what is needed, a maximum of 8 is supported by qapi.
static uint16_t ssl_ciphers[] = {
//QAPI_NET_TLS_PSK_WITH_RC4_128_SHA,
//QAPI_NET_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
//QAPI_NET_TLS_PSK_WITH_AES_128_CBC_SHA,
//QAPI_NET_TLS_PSK_WITH_AES_256_CBC_SHA,
//QAPI_NET_TLS_PSK_WITH_AES_128_GCM_SHA256,
//QAPI_NET_TLS_PSK_WITH_AES_256_GCM_SHA384,
//QAPI_NET_TLS_PSK_WITH_AES_128_CBC_SHA256,
//QAPI_NET_TLS_PSK_WITH_AES_256_CBC_SHA384,
//QAPI_NET_TLS_RSA_WITH_AES_128_CBC_SHA,
QAPI_NET_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
QAPI_NET_TLS_RSA_WITH_AES_256_CBC_SHA,
//QAPI_NET_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
//QAPI_NET_TLS_RSA_WITH_AES_128_CBC_SHA256,
QAPI_NET_TLS_RSA_WITH_AES_256_CBC_SHA256,
//QAPI_NET_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
//QAPI_NET_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
//QAPI_NET_TLS_RSA_WITH_AES_128_GCM_SHA256,
QAPI_NET_TLS_RSA_WITH_AES_256_GCM_SHA384,
QAPI_NET_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
QAPI_NET_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
//QAPI_NET_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
//QAPI_NET_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
//QAPI_NET_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
//QAPI_NET_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
//QAPI_NET_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
//QAPI_NET_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
//QAPI_NET_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
QAPI_NET_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
//QAPI_NET_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
//QAPI_NET_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
//QAPI_NET_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
//QAPI_NET_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
//QAPI_NET_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
//QAPI_NET_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
//QAPI_NET_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
QAPI_NET_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
//QAPI_NET_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
//QAPI_NET_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
//QAPI_NET_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
//QAPI_NET_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
//QAPI_NET_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
//QAPI_NET_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
//QAPI_NET_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
//QAPI_NET_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
//QAPI_NET_TLS_RSA_WITH_AES_128_CCM,
//QAPI_NET_TLS_RSA_WITH_AES_256_CCM,
//QAPI_NET_TLS_DHE_RSA_WITH_AES_128_CCM,
//QAPI_NET_TLS_DHE_RSA_WITH_AES_256_CCM,
//QAPI_NET_TLS_RSA_WITH_AES_128_CCM_8,
//QAPI_NET_TLS_RSA_WITH_AES_256_CCM_8,
//QAPI_NET_TLS_DHE_RSA_WITH_AES_128_CCM_8,
//QAPI_NET_TLS_DHE_RSA_WITH_AES_256_CCM_8,
//QAPI_NET_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
//QAPI_NET_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
//QAPI_NET_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
};
static qapi_Net_MQTT_Hndl_t mqtt_client;
static void mqtt_msgcb(qapi_Net_MQTT_Hndl_t mqtt, int32_t reason, const uint8_t* topic, int32_t topic_length,
const uint8_t* msg, int32_t msg_length, int32_t qos, const void* sid) {
(void)reason;
(void)topic;
(void)topic_length;
(void)qos;
(void)sid;
char reply[128];
memset(reply, 0, 128);
memcpy(reply, "Reply ", 6);
msg_length = msg_length > 121 ? 121 : msg_length;
memcpy(&reply[6], msg, msg_length);
TRACE("sending reply: %s\r\n", reply);
int res = qapi_Net_MQTT_Publish(mqtt, "test/reply", reply, msg_length + 6, 1, false);
if(res != QAPI_OK) TRACE("failed to publish reply: %d\r\n", res);
}
static void mqtt_concb(qapi_Net_MQTT_Hndl_t mqtt, int32_t reason) {
(void)reason;
TRACE("connected to mqtt\r\n");
int res = qapi_Net_MQTT_Subscribe(mqtt, "test/echo", 1);
if(res != QAPI_OK) TRACE("failed to subscribe to topic\r\n");
}
const uint8_t sharkSslCAList[600] =
{
0x00, 0x00, 0x00, 0x01, 0x52, 0x65, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x00, 0x00, 0x00, 0x10,
0x30, 0x82, 0x02, 0x44, 0x30, 0x82, 0x01, 0xE9, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01,
0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81, 0x88, 0x31,
0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1C, 0x30, 0x1A,
0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x13, 0x52, 0x65, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65,
0x20, 0x4C, 0x6F, 0x67, 0x69, 0x63, 0x20, 0x4C, 0x4C, 0x43, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03,
0x55, 0x04, 0x0B, 0x13, 0x08, 0x53, 0x68, 0x61, 0x72, 0x6B, 0x53, 0x53, 0x4C, 0x31, 0x20, 0x30,
0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x52, 0x65, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D,
0x65, 0x20, 0x4C, 0x6F, 0x67, 0x69, 0x63, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31,
0x26, 0x30, 0x24, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x17,
0x67, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x72, 0x65, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x65, 0x6C, 0x6F,
0x67, 0x69, 0x63, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x33, 0x31, 0x30, 0x30,
0x34, 0x30, 0x38, 0x35, 0x38, 0x35, 0x38, 0x5A, 0x17, 0x0D, 0x32, 0x33, 0x31, 0x30, 0x30, 0x32,
0x30, 0x38, 0x35, 0x38, 0x35, 0x38, 0x5A, 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A,
0x13, 0x13, 0x52, 0x65, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x4C, 0x6F, 0x67, 0x69,
0x63, 0x20, 0x4C, 0x4C, 0x43, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x08,
0x53, 0x68, 0x61, 0x72, 0x6B, 0x53, 0x53, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04,
0x03, 0x13, 0x17, 0x52, 0x65, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x4C, 0x6F, 0x67,
0x69, 0x63, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x26, 0x30, 0x24, 0x06, 0x09,
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x17, 0x67, 0x69, 0x6E, 0x66, 0x6F,
0x40, 0x72, 0x65, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x65, 0x6C, 0x6F, 0x67, 0x69, 0x63, 0x2E, 0x63,
0x6F, 0x6D, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06,
0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x47, 0x98, 0xE9,
0x49, 0x01, 0x08, 0x89, 0x4F, 0x5E, 0x73, 0x78, 0x90, 0x37, 0x79, 0x2E, 0x58, 0x19, 0xBB, 0xEB,
0x9C, 0xAA, 0x39, 0x89, 0x43, 0x9F, 0xE0, 0x95, 0x6F, 0x5E, 0xF6, 0x1D, 0x17, 0x1F, 0x70, 0x94,
0xC1, 0x7D, 0x42, 0xD8, 0x61, 0xFF, 0x5F, 0x9A, 0xF8, 0x46, 0x65, 0x95, 0x8B, 0x50, 0xF3, 0x4B,
0x2B, 0x61, 0x3E, 0xDC, 0x18, 0x49, 0xA5, 0x8C, 0x4E, 0x6E, 0x7D, 0x2A, 0x6A, 0xA3, 0x42, 0x30,
0x40, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01,
0x06, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01,
0x01, 0xFF, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x03, 0x58, 0xA1,
0xBE, 0x4F, 0xDC, 0x8F, 0xA1, 0x1F, 0xBB, 0xBC, 0xA1, 0xAA, 0xE6, 0x3E, 0xC0, 0xDB, 0x56, 0x1F,
0x18, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x49, 0x00,
0x30, 0x46, 0x02, 0x21, 0x00, 0xDC, 0x5C, 0xD7, 0x3D, 0x33, 0x0F, 0xC8, 0x8E, 0x2E, 0x2E, 0x56,
0xC7, 0xAB, 0x61, 0x36, 0x3F, 0xC1, 0x0E, 0x7A, 0xAC, 0xB3, 0xE5, 0x09, 0x40, 0xD4, 0xF7, 0xA1,
0x01, 0xC8, 0x82, 0x51, 0x1D, 0x02, 0x21, 0x00, 0xE8, 0x27, 0x6E, 0x5D, 0x41, 0x08, 0x94, 0x0D,
0x35, 0xA8, 0xD9, 0xFB, 0xE0, 0x8B, 0x61, 0x6F, 0xB1, 0xC6, 0xC7, 0x9C, 0x09, 0xA2, 0x44, 0xAD,
0xF1, 0xE6, 0x60, 0x45, 0xB0, 0xAC, 0x4A, 0x5A
};
static void constate_changed(netmgr_constate_t s) {
if(s == NETMGR_connected) {
TRACE("connected to the internet\r\n");
qapi_Net_MQTT_Config_t config;
const char* addr;
char buf[16];
memset(&config, 0x00, sizeof(config));
config.remote.sa_family = AF_INET;
int res = qapi_Net_DNSc_Reshost(MQTT_HOST, &config.remote);
if(res != 0) TRACE("DNS Request failed: %d\r\n", res);
else {
addr = inet_ntop(config.remote.sa_family, &config.remote.sa_data, buf, 50);
if(addr != NULL) {
TRACE("connecting to: %s\r\n", addr);
config.local.sa_family = AF_INET;
config.remote.sa_port = htons(8883);
config.nonblocking_connect = true;
memcpy(config.client_id, MQTT_CLIENTID, sizeof(MQTT_CLIENTID) - 1);
config.client_id_len = 5;
config.keepalive_duration = 30;
config.clean_session = 1;
config.username = MQTT_USER;
config.username_len = strlen((const char*)config.username);
config.password = MQTT_PASS;
config.password_len = strlen((const char*)config.password);
config.ssl_cfg.protocol = QAPI_NET_SSL_PROTOCOL_TLS_1_2;
for(uint32_t i=0; i<sizeof(ssl_ciphers)/sizeof(ssl_ciphers[0]) && i < 8;i++) {
config.ssl_cfg.cipher[i] = ssl_ciphers[i];
}
config.ssl_cfg.sni_Name = MQTT_HOST;
config.ssl_cfg.sni_Name_Size = strlen(MQTT_HOST);
memcpy(config.ssl_cfg.verify.match_Name, config.ssl_cfg.sni_Name, config.ssl_cfg.sni_Name_Size);
config.ssl_cfg.verify.domain = TX_TRUE;
config.ssl_cfg.verify.time_Validity = TX_FALSE; // Can't use this until I figure out how to set rtc time....
config.ssl_cfg.verify.send_Alert = true;
config.ssl_cfg.max_Frag_Len = 512;
config.ca_list = sharkSslCAList;
config.cert = sharkSslCAList;
res = qapi_Net_MQTT_Connect(mqtt_client, &config);
if(res == QAPI_OK) TRACE("connected mqtt client\r\n");
else TRACE("failed to connect mqtt client\r\n");
} else {
TRACE("failed to resolve host\r\n");
}
}
} else TRACE("failed to connect to network\r\n");
}
int dam_app_start(void)
{
//if(boot_cfg() != 0) return TX_SUCCESS;
if(debug_init() != 0) return TX_SUCCESS;
if(sizeof(ssl_ciphers)/sizeof(ssl_ciphers[0]) > 8)
TRACE("WARNING: ssl_ciphers > 8, only the first 8 will get used.");
TRACE("starting network\r\n");
if(netmgr_init() != 0) {
TRACE("failed to init network manager\r\n");
return TX_SUCCESS;
}
netmgr_set_autoreconnect(true);
netmgr_set_constate_cb(constate_changed);
TRACE("connecting to network\r\n");
if(netmgr_connect(APN, USER, PASS) != 0) {
TRACE("failed to start connecting to network\r\n");
return TX_SUCCESS;
}
TRACE("initiating mqtt\r\n");
int res = qapi_Net_MQTT_New(&mqtt_client);
if(res != QAPI_OK) TRACE("failed to create mqtt client\r\n");
res = qapi_Net_MQTT_Set_Connect_Callback(mqtt_client, mqtt_concb);
if(res != QAPI_OK) TRACE("failed to set mqtt callback\r\n");
res = qapi_Net_MQTT_Set_Message_Callback(mqtt_client, mqtt_msgcb);
if(res != QAPI_OK) TRACE("failed to set mqtt callback\r\n");
TRACE("init done\r\n");
return TX_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment