Since this is my first "quasi-professional" project that I actually want others to use, I wanted there to be decent quality documentation for all the functions and structs that the end user would need to use. I had tried Doxygen before but never had much luck, mostly because I didn't bother to put in the effort to read the documentation closely. So this time around I did, and the output so far looks quite good and has a lot of detail about the functions, and the two typedef structs that are key to everything working. Added code to check if wifi is connected before allowing the TCP connection to be attempted. Similar code for mqtt_connect, checking if we have a valid TCP connection to the server. Waiting for wifi uses a new global timer. These changes affected the indentation of huge chunks of the code, as they got wrapped in ifs. We now take advantage of the void *reverse pointer in the espconn struct to point to the mqtt_session_t that is active. This is a nice touch that Espressif added, so you can access arbitrary data from within callbacks. This will allow us to (soon) have user callbacks to deal with MQTT messages. Also added license notices to all the source code files.
471 lines
20 KiB
C
471 lines
20 KiB
C
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
#include <stdint.h>
|
|
#include "user_interface.h"
|
|
#include "ets_sys.h"
|
|
#include "osapi.h"
|
|
#include "mem.h"
|
|
#include "gpio.h"
|
|
#include "espconn.h"
|
|
#include "os_type.h"
|
|
#include "mqtt.h"
|
|
|
|
/* Functions we will need to implement:
|
|
* Send -- will handle all sending of all packets
|
|
* Connect -- set up TCP connection and parameters
|
|
* Publish -- send message to server
|
|
* Subscribe -- we probably won't need this
|
|
* We just want to connect, and publish info. We don't care about
|
|
* security or QoS in this basic implementation.
|
|
*/
|
|
|
|
#ifdef DEBUG
|
|
static os_timer_t oneTimer;
|
|
static os_timer_t testTimer;
|
|
#endif
|
|
static os_timer_t MQTT_KeepAliveTimer;
|
|
static os_timer_t waitForWifiTimer;
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR data_sent_callback(void *arg) {
|
|
os_printf("Data sent!\n");
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR data_recv_callback(void *arg, char *pdata, unsigned short len) {
|
|
struct espconn *pConn = arg;
|
|
mqtt_session_t *session = pConn->reverse;
|
|
// deal with received data
|
|
#ifdef DEBUG
|
|
os_printf("Received data of length %d -- %s \r\n", len, pdata);
|
|
os_printf("Hex dump: ");
|
|
for(int i = 0; i < len; i++) {
|
|
os_printf("(%d): %x ", i, pdata[i]);
|
|
}
|
|
os_printf("\n");
|
|
#endif
|
|
mqtt_message_type msgType = ((mqtt_message_type)pdata[0] >> 4) & 0x0F;
|
|
switch(msgType) {
|
|
case MQTT_MSG_TYPE_CONNACK:
|
|
os_printf("CONNACK recieved...\n");
|
|
switch(pdata[3]) {
|
|
case 0:
|
|
os_printf("Connection accepted.\n");
|
|
break;
|
|
case 1:
|
|
os_printf("Connection refused -- incorrect protocol version.\n");
|
|
break;
|
|
case 2:
|
|
os_printf("Connection refused -- illegal identifier.\n");
|
|
break;
|
|
case 3:
|
|
os_printf("Connection refused -- broker offline or not available.\n");
|
|
break;
|
|
case 4:
|
|
os_printf("Connection refused -- bad username or password.\n");
|
|
break;
|
|
case 5:
|
|
os_printf("Connection refused -- not authorized.\n");
|
|
break;
|
|
default:
|
|
os_printf("Connection refused -- illegal CONNACK return code.\n");
|
|
break;
|
|
}
|
|
break;
|
|
case MQTT_MSG_TYPE_PUBLISH:
|
|
os_printf("Application message from server: %s\n", &pdata[3]); // probably incorrect
|
|
break;
|
|
case MQTT_MSG_TYPE_SUBACK:
|
|
os_printf("Subscription acknowledged\n");
|
|
break;
|
|
case MQTT_MSG_TYPE_UNSUBACK:
|
|
os_printf("Unsubscription acknowledged\n");
|
|
break;
|
|
case MQTT_MSG_TYPE_PINGRESP:
|
|
os_printf("Pong!\n");
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR connected_callback(void *arg) {
|
|
struct espconn *pConn = arg;
|
|
mqtt_session_t *pSession = pConn->reverse;
|
|
#ifdef DEBUG
|
|
os_printf("Connected callback\n");
|
|
#endif
|
|
espconn_regist_recvcb(pConn, (espconn_recv_callback)data_recv_callback);
|
|
espconn_regist_sentcb(pConn, (espconn_sent_callback)data_sent_callback);
|
|
// enable keepalive
|
|
espconn_set_opt(pConn, ESPCONN_KEEPALIVE);
|
|
pSession->validConnection = 1;
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR reconnected_callback(void *arg, sint8 err) {
|
|
os_printf("Reconnected?\n");
|
|
os_printf("Error code: %d\n", err);
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR disconnected_callback(void *arg) {
|
|
os_printf("Disconnected\n");
|
|
}
|
|
|
|
LOCAL uint8_t ICACHE_FLASH_ATTR tcpConnect(void *arg) {
|
|
os_timer_disarm(&waitForWifiTimer);
|
|
struct ip_info ipConfig;
|
|
mqtt_session_t *session = arg;
|
|
wifi_get_ip_info(STATION_IF, &ipConfig);
|
|
if (wifi_station_get_connect_status() == STATION_GOT_IP && ipConfig.ip.addr != 0) {
|
|
struct ip_info ipConfig;
|
|
|
|
LOCAL struct espconn conn;
|
|
LOCAL struct _esp_tcp tcp_s;
|
|
conn.reverse = arg;
|
|
os_printf("Everything looks good!\n");
|
|
#ifdef DEBUG
|
|
os_printf("Entered tcpConnect\n");
|
|
#endif
|
|
wifi_get_ip_info(STATION_IF, &ipConfig);
|
|
// set up basic TCP connection parameters
|
|
#ifdef DEBUG
|
|
os_printf("about to set up TCP params\n");
|
|
#endif
|
|
conn.proto.tcp = &tcp_s;
|
|
conn.type = ESPCONN_TCP;
|
|
conn.proto.tcp->local_port = espconn_port();
|
|
conn.proto.tcp->remote_port = session->port;
|
|
conn.state = ESPCONN_NONE;
|
|
os_memcpy(conn.proto.tcp->remote_ip, session->ip, 4);
|
|
|
|
os_printf("About to register callbacks\n");
|
|
// register callbacks
|
|
espconn_regist_connectcb(&conn, (espconn_connect_callback)connected_callback);
|
|
espconn_regist_reconcb(&conn, (espconn_reconnect_callback)reconnected_callback);
|
|
espconn_regist_disconcb(&conn, (espconn_connect_callback)disconnected_callback);
|
|
os_printf("About to connect\n");
|
|
//make the connection
|
|
if(espconn_connect(&conn) == 0) {
|
|
os_printf("Connection successful\n");
|
|
} else {
|
|
os_printf("Connection error\n");
|
|
}
|
|
session->activeConnection = &conn;
|
|
#ifdef DEBUG
|
|
os_printf("About to return from TCP connect\n");
|
|
#endif
|
|
return 0;
|
|
}
|
|
else {
|
|
// set timer to try again
|
|
os_timer_setfn(&waitForWifiTimer, (os_timer_func_t *)tcpConnect, session);
|
|
os_timer_arm(&waitForWifiTimer, 1000, 0);
|
|
}
|
|
}
|
|
|
|
|
|
LOCAL uint8_t ICACHE_FLASH_ATTR *encodeLength(uint32_t trueLength) {
|
|
uint8_t *encodedByte = os_zalloc(sizeof(uint8_t) * 5); // can't be more than 5 bytes
|
|
uint8_t numBytes = 1;
|
|
do {
|
|
encodedByte[numBytes] = trueLength % 128;
|
|
trueLength /= 128;
|
|
if(trueLength > 0) {
|
|
encodedByte[numBytes] |= 128;
|
|
}
|
|
numBytes++;
|
|
} while(trueLength > 0);
|
|
encodedByte[0] = numBytes - 1;
|
|
|
|
return encodedByte;
|
|
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR pingAlive(void *arg) {
|
|
mqtt_session_t *pSession = (mqtt_session_t *)arg;
|
|
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_PINGREQ);
|
|
}
|
|
|
|
LOCAL uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint32_t len, mqtt_message_type msgType) {
|
|
if(session->validConnection == 1) {
|
|
os_timer_disarm(&MQTT_KeepAliveTimer); // disable timer if we are called
|
|
#ifdef DEBUG
|
|
os_printf("Entering mqtt_send!\n");
|
|
#endif
|
|
LOCAL mqtt_packet_t packet;
|
|
LOCAL mqtt_packet_t *pPacket = &packet;
|
|
uint8_t *fullPacket;
|
|
uint8_t *remaining_len_encoded;
|
|
switch(msgType) {
|
|
case MQTT_MSG_TYPE_CONNECT: {
|
|
const uint8_t varDefaults[10] = { 0x00, 0x04, 0x4D, 0x51, 0x54, 0x54, 0x04, 0xC2, 0x00, 0x32 }; // variable header is always the same for Connect
|
|
pPacket->fixedHeader = (uint8_t *)os_zalloc(sizeof(uint8_t) * 5); // fixed header cannot be longer than 5
|
|
pPacket->fixedHeader[0] = ((uint8_t)msgType << 4) & 0xF0; // make sure lower 4 are clear
|
|
// prepare variable header
|
|
pPacket->varHeader = (uint8_t *)os_zalloc(sizeof(uint8_t) * 10); // 10 bytes for connect
|
|
os_memcpy(pPacket->varHeader, varDefaults, 10); // copy defaults
|
|
pPacket->varHeader_len = 10;
|
|
// prepare payload
|
|
uint32_t offset = 0; // keep track of how many bytes we have copied
|
|
uint32_t maxPayloadLength = session->client_id_len + session->username_len + session->password_len + 12; // length info can only take a maximum of 12 bytes
|
|
pPacket->payload = (uint8_t *)os_zalloc(sizeof(uint8_t) * maxPayloadLength);
|
|
// copy client id to payload: 2 bytes for size, then client id.
|
|
// insert a 0
|
|
os_memset(pPacket->payload + offset, 0, 1); // MSB is always 0
|
|
offset += 1;
|
|
os_memcpy(pPacket->payload + offset, &session->client_id_len, 1); // LSB is length of string
|
|
offset += 1;
|
|
os_memcpy(pPacket->payload + offset, session->client_id, session->client_id_len); // and copy string
|
|
offset += session->client_id_len;
|
|
// copy username to payload: same as client id, 2 bytes for size, then username
|
|
// insert a 0
|
|
os_memset(pPacket->payload + offset, 0, 1);
|
|
offset += 1;
|
|
os_memcpy(pPacket->payload + offset, &session->username_len, 1);
|
|
offset += 1;
|
|
os_memcpy(pPacket->payload + offset, session->username, session->username_len);
|
|
offset += session->username_len;
|
|
// Password: same as username and client id, 2 bytes for size, then password
|
|
// insert a 0
|
|
os_memset(pPacket->payload + offset, 0, 1);
|
|
offset += 1;
|
|
os_memcpy(pPacket->payload + offset, &session->password_len, 1);
|
|
offset += 1;
|
|
os_memcpy(pPacket->payload + offset, session->password, session->password_len);
|
|
offset += session->password_len;
|
|
pPacket->payload_len = offset; // the length of the payload is the same as our offset
|
|
#ifdef DEBUG
|
|
os_printf("Total offset: %d\n", offset);
|
|
#endif
|
|
// the remaining length is the size of the packet, minus the first byte and the bytes taken by the remaining length bytes themselves
|
|
// they are encoded per the MQTT spec, section 2.2.3
|
|
// the first byte returned by encodeLength is the number of bytes to follow, as it can be anywhere from 1 to 4 bytes to encode the length
|
|
remaining_len_encoded = encodeLength((uint32_t)(pPacket->varHeader_len + pPacket->payload_len));
|
|
os_memcpy(pPacket->fixedHeader + 1, remaining_len_encoded + 1, remaining_len_encoded[0]);
|
|
pPacket->fixedHeader_len = remaining_len_encoded[0] + 1; // fixed header length is the number of bytes used to encode the remaining length, plus 1 for the fixed CONNECT byte
|
|
// the full length is the length of the varHeader, payload, and fixedHeader
|
|
pPacket->length = (pPacket->varHeader_len + pPacket->payload_len + pPacket->fixedHeader_len);
|
|
#ifdef DEBUG
|
|
os_printf("Packet length: %d\n", pPacket->length);
|
|
#endif
|
|
// construct packet data
|
|
fullPacket = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->length);
|
|
os_memcpy(fullPacket, pPacket->fixedHeader, pPacket->fixedHeader_len);
|
|
os_memcpy(fullPacket + pPacket->fixedHeader_len, pPacket->varHeader, pPacket->varHeader_len);
|
|
os_memcpy(fullPacket + pPacket->fixedHeader_len + pPacket->varHeader_len, pPacket->payload, pPacket->payload_len);
|
|
break;
|
|
}
|
|
case MQTT_MSG_TYPE_PUBLISH: {
|
|
// prepare for publish
|
|
pPacket->fixedHeader = (uint8_t *)os_zalloc(sizeof(uint8_t) * 5);
|
|
pPacket->fixedHeader[0] = (MQTT_MSG_TYPE_PUBLISH << 4) & 0xF0; // clear lower 4 bits, we don't need DUP, QOS or RETAIN
|
|
|
|
// variable header
|
|
// A PUBLISH Packet MUST NOT contain a Packet Identifier if its QoS value is set to 0 [MQTT-2.3.1-5].
|
|
pPacket->varHeader_len = session->topic_name_len + 2; // we have no packet identifier, as we are QOS 0
|
|
pPacket->varHeader = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->varHeader_len);
|
|
os_memset(pPacket->varHeader, 0, 1);
|
|
os_memcpy(pPacket->varHeader + 1, &session->topic_name_len, 1);
|
|
os_memcpy(pPacket->varHeader + 2, session->topic_name, session->topic_name_len);
|
|
|
|
//payload
|
|
pPacket->payload_len = len;
|
|
pPacket->payload = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->payload_len);
|
|
os_memcpy(pPacket->payload, data, pPacket->payload_len);
|
|
// calculate remaining length for fixed header
|
|
remaining_len_encoded = encodeLength((uint32_t)(pPacket->varHeader_len + pPacket->payload_len));
|
|
os_memcpy(pPacket->fixedHeader + 1, remaining_len_encoded + 1, remaining_len_encoded[0]);
|
|
pPacket->fixedHeader_len = remaining_len_encoded[0] + 1; // fixed header length is the number of bytes used to encode the remaining length, plus 1 for the fixed CONNECT byte
|
|
// the full length is the length of the varHeader, payload, and fixedHeader
|
|
pPacket->length = (pPacket->varHeader_len + pPacket->payload_len + pPacket->fixedHeader_len);
|
|
os_printf("Packet length: %d\n", pPacket->length);
|
|
// construct packet data
|
|
fullPacket = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->length);
|
|
os_memcpy(fullPacket, pPacket->fixedHeader, pPacket->fixedHeader_len);
|
|
os_memcpy(fullPacket + pPacket->fixedHeader_len, pPacket->varHeader, pPacket->varHeader_len);
|
|
os_memcpy(fullPacket + pPacket->fixedHeader_len + pPacket->varHeader_len, pPacket->payload, pPacket->payload_len);
|
|
break;
|
|
}
|
|
case MQTT_MSG_TYPE_SUBSCRIBE:
|
|
case MQTT_MSG_TYPE_UNSUBSCRIBE:
|
|
// prepare for subscribe
|
|
pPacket->fixedHeader = (uint8_t *)os_zalloc(sizeof(uint8_t) * 5);
|
|
pPacket->fixedHeader[0] = ((msgType << 4) & 0xF0) | 0x02;
|
|
|
|
pPacket->varHeader_len = 2;
|
|
pPacket->varHeader = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->varHeader_len);
|
|
os_memset(pPacket->varHeader, 0, 2); // set packet ID to 0
|
|
|
|
uint8_t extraByte = (msgType == MQTT_MSG_TYPE_SUBSCRIBE) ? 3 : 2;
|
|
pPacket->payload_len = session->topic_name_len + extraByte;
|
|
pPacket->payload = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->payload_len);
|
|
pPacket->payload[1] = session->topic_name_len % 0xFF;
|
|
pPacket->payload[0] = session->topic_name_len / 0xFF;
|
|
os_memcpy(pPacket->payload + 2, session->topic_name, session->topic_name_len); // copy topic name
|
|
if(msgType == MQTT_MSG_TYPE_SUBSCRIBE) pPacket->payload[session->topic_name_len+2] = 0;
|
|
|
|
// calculate remaining length for fixed header
|
|
remaining_len_encoded = encodeLength((uint32_t)(pPacket->varHeader_len + pPacket->payload_len));
|
|
os_memcpy(pPacket->fixedHeader + 1, remaining_len_encoded + 1, remaining_len_encoded[0]);
|
|
pPacket->fixedHeader_len = remaining_len_encoded[0] + 1; // fixed header length is the number of bytes used to encode the remaining length, plus 1 for the fixed CONNECT byte
|
|
// the full length is the length of the varHeader, payload, and fixedHeader
|
|
pPacket->length = (pPacket->varHeader_len + pPacket->payload_len + pPacket->fixedHeader_len);
|
|
os_printf("Packet length: %d\n", pPacket->length);
|
|
// construct packet data
|
|
fullPacket = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->length);
|
|
os_memcpy(fullPacket, pPacket->fixedHeader, pPacket->fixedHeader_len);
|
|
os_memcpy(fullPacket + pPacket->fixedHeader_len, pPacket->varHeader, pPacket->varHeader_len);
|
|
os_memcpy(fullPacket + pPacket->fixedHeader_len + pPacket->varHeader_len, pPacket->payload, pPacket->payload_len);
|
|
|
|
break;
|
|
case MQTT_MSG_TYPE_PINGREQ:
|
|
case MQTT_MSG_TYPE_DISCONNECT:
|
|
// PINGREQ has no varHeader or payload, it's just two bytes
|
|
// 0xC0 0x00
|
|
pPacket->fixedHeader = (uint8_t *)os_zalloc(sizeof(uint8_t) * 2);
|
|
pPacket->fixedHeader[0] = (msgType << 4) & 0xF0; // bottom nibble must be clear
|
|
pPacket->fixedHeader[1] = 0; // remaining length is zero
|
|
pPacket->fixedHeader_len = 2;
|
|
pPacket->length = pPacket->fixedHeader_len;
|
|
// In order to avoid undefined behaviour, we must allocate
|
|
// something to varHeader and payload, as they get passed
|
|
// to free() at the end of this function
|
|
pPacket->varHeader = (uint8_t *)os_zalloc(1);
|
|
pPacket->payload = (uint8_t *)os_zalloc(1);
|
|
// copy the fixedHeader to fullPacket, and we're done!
|
|
fullPacket = (uint8_t *)os_zalloc(sizeof(uint8_t) * pPacket->length);
|
|
os_memcpy(fullPacket, pPacket->fixedHeader, pPacket->fixedHeader_len);
|
|
break;
|
|
default:
|
|
// something has gone wrong
|
|
os_printf("Attempt to send incorrect packet type: %d", (uint8_t)msgType);
|
|
return -1;
|
|
}
|
|
#ifdef DEBUG
|
|
os_printf("About to send MQTT command type: %d...\n", (uint8_t)msgType);
|
|
#endif
|
|
espconn_send(session->activeConnection, fullPacket, pPacket->length);
|
|
os_free(fullPacket);
|
|
os_free(pPacket->fixedHeader);
|
|
os_free(pPacket->varHeader);
|
|
os_free(pPacket->payload);
|
|
// set up keepalive timer
|
|
if(msgType != MQTT_MSG_TYPE_DISCONNECT) {
|
|
os_timer_setfn(&MQTT_KeepAliveTimer, (os_timer_func_t *)pingAlive, session);
|
|
os_timer_arm(&MQTT_KeepAliveTimer, 30000, 0);
|
|
}
|
|
} else {
|
|
os_printf("No wifi! Narf!\n");
|
|
}
|
|
}
|
|
|
|
|
|
/*********************************************/
|
|
/* EVERYTHING FROM HERE DOWN IS SIMPLY */
|
|
/* SIMULATING WHAT A USER WOULD DO WITH THIS */
|
|
/* API. IT'S NOT PART OF THE LIBRARY. */
|
|
/* IT'S JUST HERE FOR TESTING. */
|
|
/*********************************************/
|
|
#ifdef DEBUG
|
|
LOCAL void ICACHE_FLASH_ATTR con(void *arg);
|
|
LOCAL void ICACHE_FLASH_ATTR pub(void *arg);
|
|
LOCAL void ICACHE_FLASH_ATTR sub(void *arg);
|
|
LOCAL void ICACHE_FLASH_ATTR ping(void *arg);
|
|
LOCAL void ICACHE_FLASH_ATTR discon(void *arg);
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR con(void *arg) {
|
|
os_printf("Entered con!\n");
|
|
mqtt_session_t *pSession = (mqtt_session_t *)arg;
|
|
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_CONNECT);
|
|
|
|
os_timer_disarm(&oneTimer);
|
|
os_timer_setfn(&oneTimer, (os_timer_func_t *)sub, arg);
|
|
os_timer_arm(&oneTimer, 200, 0);
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR pub(void *arg) {
|
|
os_printf("Entered pub!\n");
|
|
mqtt_session_t *pSession = (mqtt_session_t *)arg;
|
|
uint8_t data[] = "2.718281828459045";
|
|
uint32_t dataLen = os_strlen(data);
|
|
mqtt_send(pSession, &data[0], dataLen, MQTT_MSG_TYPE_PUBLISH);
|
|
os_timer_disarm(&oneTimer);
|
|
os_timer_setfn(&oneTimer, (os_timer_func_t *)ping, arg);
|
|
os_timer_arm(&oneTimer, 200, 0);
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR ping(void *arg) {
|
|
os_printf("Entered ping!\n");
|
|
mqtt_session_t *pSession = (mqtt_session_t *)arg;
|
|
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_PINGREQ);
|
|
os_timer_disarm(&oneTimer);
|
|
os_timer_setfn(&oneTimer, (os_timer_func_t *)sub, arg);
|
|
os_timer_arm(&oneTimer, 200, 0);
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR sub(void *arg) {
|
|
os_printf("Entered sub!\n");
|
|
mqtt_session_t *pSession = (mqtt_session_t *)arg;
|
|
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_SUBSCRIBE);
|
|
|
|
}
|
|
|
|
LOCAL void ICACHE_FLASH_ATTR discon(void *arg) {
|
|
os_printf("Entered discon!\n");
|
|
mqtt_session_t *pSession = (mqtt_session_t *)arg;
|
|
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_DISCONNECT);
|
|
os_timer_disarm(&oneTimer);
|
|
}
|
|
|
|
void ICACHE_FLASH_ATTR user_init() {
|
|
uint8_t wifiStatus;
|
|
LOCAL mqtt_session_t globalSession;
|
|
LOCAL mqtt_session_t *pGlobalSession = &globalSession;
|
|
char ssid[32] = "Kwangmyong";
|
|
char passkey[64] = "vqmfg55020";
|
|
struct station_config stationConf;
|
|
gpio_init(); // init gpio so we can use the LED
|
|
wifi_status_led_install(0, PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); // set GPIO0 as status LED
|
|
stationConf.bssid_set = 0;
|
|
os_memcpy(&stationConf.ssid, ssid, 32); // copy the ssid and passkey into the station_config struct
|
|
os_memcpy(&stationConf.password, passkey, 64);
|
|
wifi_set_opmode_current(0x01); //station mode
|
|
wifi_station_set_config_current(&stationConf); // tell it about our config, this auto-connects us as well
|
|
|
|
// prepare the TCP/MQTT connection stuff
|
|
// test server is at 51.15.65.206
|
|
// Adafruit IO is at 52.5.238.97
|
|
|
|
static const char testUser[11] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52 };
|
|
static const uint8_t testUser_len = 11;
|
|
static const char testPass[32] = { 0x63, 0x61, 0x62, 0x31, 0x39, 0x36, 0x36, 0x34, 0x31, 0x66, 0x33, 0x63, 0x34, 0x34, 0x36, 0x32, 0x61, 0x35, 0x30, 0x39, 0x64, 0x62, 0x64, 0x31, 0x34, 0x61, 0x30, 0x61, 0x66, 0x36, 0x64, 0x32 };
|
|
static const uint8_t testPass_len = 32;
|
|
//static const char testPass[4] = { 0x74, 0x65, 0x73, 0x74 };
|
|
//static const uint8_t testPass_len = 4;
|
|
static const char testTopic[37] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x62, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x62, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x74, 0x65, 0x6d, 0x70 };
|
|
static const uint8_t testTopic_len = 37;
|
|
//static const char testTopic[4] = { 0x74, 0x65, 0x73, 0x74 };
|
|
//static const uint8_t testTopic_len = 4;
|
|
static const char clientID[5] = { 0x46, 0x5a, 0x5a, 0x4e, 0x30 };
|
|
static const uint8_t clientID_len = 5;
|
|
pGlobalSession->port = 1883; // mqtt port
|
|
static const char esp_tcp_server_ip[4] = {52, 5, 238, 97};
|
|
os_memcpy(pGlobalSession->ip, esp_tcp_server_ip, 4);
|
|
pGlobalSession->username_len = testUser_len;
|
|
pGlobalSession->username = os_zalloc(sizeof(uint8_t) * pGlobalSession->username_len);
|
|
os_memcpy(pGlobalSession->username, testUser, pGlobalSession->username_len);
|
|
pGlobalSession->password_len = testPass_len;
|
|
pGlobalSession->password = os_zalloc(sizeof(uint8_t) * pGlobalSession->password_len);
|
|
os_memcpy(pGlobalSession->password, testPass, pGlobalSession->password_len);
|
|
pGlobalSession->topic_name_len = testTopic_len;
|
|
pGlobalSession->topic_name = os_zalloc(sizeof(uint8_t) * pGlobalSession->topic_name_len);
|
|
os_memcpy(pGlobalSession->topic_name, testTopic, pGlobalSession->topic_name_len);
|
|
pGlobalSession->client_id_len = clientID_len;
|
|
pGlobalSession->client_id = os_zalloc(sizeof(uint8_t) * pGlobalSession->client_id_len);
|
|
os_memcpy(pGlobalSession->client_id, clientID, pGlobalSession->client_id_len);
|
|
|
|
os_timer_setfn(&oneTimer, (os_timer_func_t *)tcpConnect, pGlobalSession);
|
|
os_timer_arm(&oneTimer, 15000, 0);
|
|
os_timer_setfn(&testTimer, (os_timer_func_t *)con, pGlobalSession);
|
|
os_timer_arm(&testTimer, 16000, 0);
|
|
}
|
|
#endif
|