Compare commits

...

11 commits

Author SHA1 Message Date
a84326db7f
Re-formatted code and made some small changes to behaviour.
At some point this repo might get updated to MQTT v5. I have to
carefully read the standard and see what has changed.
2024-05-06 08:02:52 -04:00
54ec66b345
Cleaned up strtoarr.py 2019-04-15 23:40:34 -04:00
59b1b748ff
Fixed compile-time warnings 2019-04-11 17:08:12 -04:00
fdac75a728 Merge branch 'revert-dc724a2c' into 'master'
Revert "Merged updates from dev branch into master"

See merge request mraureliusr/mqtt-esp8266!2
2019-04-07 14:14:27 +00:00
0aac8d5b66 Revert "Merged updates from dev branch into master"
This reverts commit dc724a2c96
2019-04-07 14:14:27 +00:00
dc724a2c96
Merged updates from dev branch into master
Signed-off-by: A.M. Rowsell <amrowsell@frozenelectronics.ca>
2019-04-06 09:52:45 -04:00
7c5dfae57b
Updated formatting with astyle -A14 -S
Signed-off-by: A.M. Rowsell <amrowsell@frozenelectronics.ca>
2019-03-04 12:58:17 -05:00
3de8cc9ed7
merged master back into priv 2019-02-27 02:42:14 -05:00
d0b019edff
Updated to v0.3.2 2019-02-27 02:40:10 -05:00
70973a0b14
Added DHT prototypes.
Added the beginning of the DHT code which will likely be used
in part 4 of the tutorial series.

Signed-off-by: A.M. Rowsell <amrowsell@frozenelectronics.ca>
2019-02-27 02:31:42 -05:00
8acff6e880
Updated to v0.3.1
Renamed mqtt_send to mqttSend to better follow my usual naming
convention. Made a few other small changes, including disabling
the debug macro by default. Just uncomment to add it again.

This is the version that will be used with the first release
of Part 3 of the SDK tutorials on hackaday.io.

Signed-off-by: A.M. Rowsell <amrowsell@frozenelectronics.ca>
2019-02-27 02:28:00 -05:00
12 changed files with 693 additions and 632 deletions

1
.gitignore vendored
View file

@ -11,3 +11,4 @@ mqtt
pcap/
docs/latex/
docs/man/
.vscode

View file

@ -38,7 +38,7 @@ PROJECT_NAME = mqtt-esp8266
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v0.2
PROJECT_NUMBER = v0.3.2
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View file

@ -8,3 +8,5 @@ While working on a series of tutorials for Hackaday, I realized MQTT would be th
At this point, it's a bit messy. It still needs a lot of work. This documentation will help me keep everything organized and easy-to-use.
The documentation has now been turned into Doxygen documentation. You can view the latest documentation [here](https://mraureliusr.gitlab.io/mqtt-esp8266/index.html)
Make sure to check out the corresponding hackaday.io project!

27
dht.c Normal file
View file

@ -0,0 +1,27 @@
#include <stdint.h>
#include "user_interface.h"
#include "os_type.h"
#include "osapi.h"
#include "gpio.h"
#include "dht.h"
#define DHTBus BIT4
LOCAL uint8_t ICACHE_FLASH_ATTR getBitNum(uint32_t bit) {
uint32_t localBit = bit;
for(uint8_t i = 0; i <= 16; i++) {
localBit >>= i;
if(bit & 0x01) {
return i;
}
}
return -1; // if we reached this spot we received a bad number
}
void ICACHE_FLASH_ATTR setupDHT(void) {
gpio_output_set(0, DHTBus, 0, DHTBus); // set up DHTBus as active low output
ETS_GPIO_INTR_ATTACH(func, NULL);
}
void ICACHE_FLASH_ATTR getDHTData(void) {
}

4
dht.h Normal file
View file

@ -0,0 +1,4 @@
#include "os_type.h"
void ICACHE_FLASH_ATTR setupDHT(uint8_t pin);
void ICACHE_FLASH_ATTR getDHTData(uint8_t pin);

62
main.c
View file

@ -13,64 +13,79 @@ os_timer_t tcpTimer;
os_timer_t pingTimer;
os_timer_t pubTimer;
LOCAL void ICACHE_FLASH_ATTR con(void *arg) {
void ICACHE_FLASH_ATTR con(void *arg) {
#ifdef DEBUG
os_printf("Entered con!\n");
#endif
mqtt_session_t *pSession = (mqtt_session_t *)arg;
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_CONNECT);
mqttSend(pSession, NULL, 0, MQTT_MSG_TYPE_CONNECT);
os_timer_disarm(&pingTimer);
os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg);
os_timer_arm(&pingTimer, 1000, 0);
}
LOCAL void ICACHE_FLASH_ATTR pubuint(void *arg) {
void ICACHE_FLASH_ATTR pubuint(void *arg) {
#ifdef DEBUG
os_printf("Entered pubuint!\n");
#endif
mqtt_session_t *pSession = (mqtt_session_t *)arg;
uint8_t *data = (uint8_t *)(pSession->userData);
char *dataStr = os_zalloc(20 * sizeof(char));
intToStr(*data, dataStr, 4);
int32_t dataLen = os_strlen(dataStr);
mqtt_send(pSession, (uint8_t *)dataStr, dataLen, MQTT_MSG_TYPE_PUBLISH);
mqttSend(pSession, (uint8_t *)dataStr, dataLen, MQTT_MSG_TYPE_PUBLISH);
os_timer_disarm(&pingTimer);
os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg);
os_timer_arm(&pingTimer, 1000, 0);
}
LOCAL void ICACHE_FLASH_ATTR pubfloat(void *arg) {
void ICACHE_FLASH_ATTR pubfloat(void *arg) {
#ifdef DEBUG
os_printf("Entered pubfloat!\n");
#endif
mqtt_session_t *pSession = (mqtt_session_t *)arg;
float *data = (float *)(pSession->userData);
char *dataStr = os_zalloc(20 * sizeof(char));
ftoa(*data, dataStr, 2);
int32_t dataLen = os_strlen(dataStr);
#ifdef DEBUG
os_printf("Encoded string: %s\tString length: %d\n", dataStr, dataLen);
mqtt_send(pSession, (uint8_t *)dataStr, dataLen, MQTT_MSG_TYPE_PUBLISH);
#endif
mqttSend(pSession, (uint8_t *)dataStr, dataLen, MQTT_MSG_TYPE_PUBLISH);
os_timer_disarm(&pingTimer);
os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg);
os_timer_arm(&pingTimer, 1000, 0);
}
LOCAL void ICACHE_FLASH_ATTR ping(void *arg) {
void ICACHE_FLASH_ATTR ping(void *arg) {
#ifdef DEBUG
os_printf("Entered ping!\n");
#endif
mqtt_session_t *pSession = (mqtt_session_t *)arg;
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_PINGREQ);
mqttSend(pSession, NULL, 0, MQTT_MSG_TYPE_PINGREQ);
os_timer_disarm(&pingTimer);
os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg);
os_timer_arm(&pingTimer, 1000, 0);
}
LOCAL void ICACHE_FLASH_ATTR sub(void *arg) {
void ICACHE_FLASH_ATTR sub(void *arg) {
#ifdef DEBUG
os_printf("Entered sub!\n");
#endif
mqtt_session_t *pSession = (mqtt_session_t *)arg;
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_SUBSCRIBE);
mqttSend(pSession, NULL, 0, MQTT_MSG_TYPE_SUBSCRIBE);
}
LOCAL void ICACHE_FLASH_ATTR discon(void *arg) {
void ICACHE_FLASH_ATTR discon(void *arg) {
#ifdef DEBUG
os_printf("Entered discon!\n");
#endif
mqtt_session_t *pSession = (mqtt_session_t *)arg;
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_DISCONNECT);
mqttSend(pSession, NULL, 0, MQTT_MSG_TYPE_DISCONNECT);
os_timer_disarm(&pingTimer);
os_timer_disarm(&pubTimer);
}
LOCAL void ICACHE_FLASH_ATTR dataLog(void *arg) {
@ -79,6 +94,7 @@ LOCAL void ICACHE_FLASH_ATTR dataLog(void *arg) {
oneWire_t *pDS18 = &DS18;
uint16_t temp = 0;
sint32 time = 0;
pDS18->temperature = 0;
reset();
transact(pDS18, SKIP_ROM);
@ -88,44 +104,51 @@ LOCAL void ICACHE_FLASH_ATTR dataLog(void *arg) {
reset();
transact(pDS18, SKIP_ROM);
transact(pDS18, SCRATCH_READ);
//os_printf("\nReceived onewire data: %x %x\n", pDS18->scratchpad[0], pDS18->scratchpad[1]);
#ifdef DEBUG
os_printf("\nReceived onewire data: %x %x\n", pDS18->scratchpad[0], pDS18->scratchpad[1]);
#endif
temp = ((uint16_t)pDS18->scratchpad[1] << 8) | pDS18->scratchpad[0];
pDS18->temperature += (temp >> 4) + ((temp & 0x0F) * 0.0625);
pSession->userData = (void *)&pDS18->temperature;
#ifdef DEBUG
os_printf("\nTemperature is: %d.%02d\n", (int)pDS18->temperature, (int)(pDS18->temperature * 100) % 100);
#endif
pubfloat(pSession); // publish the temperature
//discon(pSession);
return;
}
void ICACHE_FLASH_ATTR user_init() {
//uint8_t wifiStatus;
LOCAL mqtt_session_t globalSession;
LOCAL mqtt_session_t *pGlobalSession = &globalSession;
char ssid[32] = "yourwifissid";
char passkey[64] = "yourwifipass";
struct station_config stationConf;
gpio_init(); // init gpio so we can use the LED
uart_div_modify(0, UART_CLK_FREQ / 115200); // set UART to 115200
gpio_init(); // init gpio so we can use the LED & onewire bus
uart_div_modify(0, UART_CLK_FREQ / 921600); // set UART to 921600
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
// Adafruit IO is at 52.5.238.97
// use strtoarr.py to generate these
static const char ioUser[11] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52 }; // MrAureliusR
static const uint8_t ioUser_len = 11;
static const char ioKey[32] = { }; // use strtoarr.py to generate these
static const uint8_t ioKey_len = 32;
static const char ioTopic[27] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x74, 0x6f, 0x70, 0x69, 0x63 }; // MrAureliusR/feeds/testtopic
static const uint8_t ioTopic_len = 27;
/* static const char ioTopic[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 ioTopic_len = 37; */
static const char clientID[5] = { 0x46, 0x52, 0x5a, 0x4e, 0x30 }; // FRZN0
static const uint8_t clientID_len = 5;
pGlobalSession->port = 1883; // mqtt port
static const char adafruitIO_ip[4] = {52, 5, 238, 97};
// copy all the above info into our mqtt_session_t
os_memcpy(pGlobalSession->ip, adafruitIO_ip, 4);
pGlobalSession->username_len = ioUser_len;
pGlobalSession->username = os_zalloc(sizeof(uint8_t) * pGlobalSession->username_len);
@ -140,6 +163,7 @@ void ICACHE_FLASH_ATTR user_init() {
pGlobalSession->client_id = os_zalloc(sizeof(uint8_t) * pGlobalSession->client_id_len);
os_memcpy(pGlobalSession->client_id, clientID, pGlobalSession->client_id_len);
// set up all the timers to connect and log data
os_timer_setfn(&tcpTimer, (os_timer_func_t *)tcpConnect, pGlobalSession);
os_timer_arm(&tcpTimer, 12000, 0);
os_timer_setfn(&pingTimer, (os_timer_func_t *)con, pGlobalSession);

12
main.h
View file

@ -8,11 +8,11 @@ void reverse(char *str, int len);
int intToStr(int x, char str[], int d);
void ftoa(float n, char *res, int afterpoint);
LOCAL void ICACHE_FLASH_ATTR con(void *arg);
LOCAL void ICACHE_FLASH_ATTR pubuint(void *arg);
LOCAL void ICACHE_FLASH_ATTR pubfloat(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);
void ICACHE_FLASH_ATTR con(void *arg);
void ICACHE_FLASH_ATTR pubuint(void *arg);
void ICACHE_FLASH_ATTR pubfloat(void *arg);
void ICACHE_FLASH_ATTR sub(void *arg);
void ICACHE_FLASH_ATTR ping(void *arg);
void ICACHE_FLASH_ATTR discon(void *arg);
void ICACHE_FLASH_ATTR user_init();

63
mqtt.c
View file

@ -28,26 +28,23 @@ static os_timer_t MQTT_KeepAliveTimer;
static os_timer_t waitForWifiTimer;
// reverses a string 'str' of length 'len'
void reverse(char *str, int len)
{
void reverse(char *str, int len) {
int i=0, j=len-1, temp;
while (i<j)
{
while (i<j) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
i++; j--;
i++;
j--;
}
}
// Converts a given integer x to string str[]. d is the number
// of digits required in output. If d is more than the number
// of digits in x, then 0s are added at the beginning.
int intToStr(int x, char str[], int d)
{
// Converts a given integer x to string str[]. d is the number
// of digits required in output. If d is more than the number
// of digits in x, then 0s are added at the beginning.
int intToStr(int x, char str[], int d) {
int i = 0;
while (x)
{
while (x) {
str[i++] = (x%10) + '0';
x = x/10;
}
@ -63,8 +60,7 @@ int intToStr(int x, char str[], int d)
}
// Converts a floating point number to string.
void ftoa(float n, char *res, int afterpoint)
{
void ftoa(float n, char *res, int afterpoint) {
// Extract integer part
int ipart = (int)n;
@ -75,8 +71,7 @@ void ftoa(float n, char *res, int afterpoint)
int i = intToStr(ipart, res, 0);
// check for display option after point
if (afterpoint != 0)
{
if (afterpoint != 0) {
res[i] = '.'; // add dot
// Get the value of fraction part upto given no.
@ -89,7 +84,10 @@ void ftoa(float n, char *res, int afterpoint)
}
void ICACHE_FLASH_ATTR data_sent_callback(void *arg) {
#ifdef DEBUG
os_printf("Data sent!\n");
#endif
return;
}
void ICACHE_FLASH_ATTR data_recv_callback(void *arg, char *pdata, unsigned short len) {
@ -190,8 +188,9 @@ void ICACHE_FLASH_ATTR reconnected_callback(void *arg, sint8 err) {
void ICACHE_FLASH_ATTR disconnected_callback(void *arg) {
os_printf("Disconnected\n");
os_timer_disarm(&pubTimer);
os_timer_disarm(&pingTimer);
/* These timers should be disarmed by the userspace code */
/* os_timer_disarm(&pubTimer); */
/* os_timer_disarm(&pingTimer); */
}
uint8_t ICACHE_FLASH_ATTR tcpConnect(void *arg) {
@ -203,7 +202,6 @@ uint8_t ICACHE_FLASH_ATTR tcpConnect(void *arg) {
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
@ -218,13 +216,16 @@ uint8_t ICACHE_FLASH_ATTR tcpConnect(void *arg) {
conn.proto.tcp->remote_port = session->port;
conn.state = ESPCONN_NONE;
os_memcpy(conn.proto.tcp->remote_ip, session->ip, 4);
#ifdef DEBUG
os_printf("About to register callbacks\n");
#endif
// 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);
#ifdef DEBUG
os_printf("About to connect\n");
#endif
//make the connection
if(espconn_connect(&conn) == 0) {
os_printf("Connection successful\n");
@ -236,8 +237,7 @@ uint8_t ICACHE_FLASH_ATTR tcpConnect(void *arg) {
os_printf("About to return from TCP connect\n");
#endif
return 0;
}
else {
} else {
// set timer to try again
os_timer_setfn(&waitForWifiTimer, (os_timer_func_t *)tcpConnect, session);
os_timer_arm(&waitForWifiTimer, 1000, 0);
@ -266,14 +266,14 @@ uint8_t ICACHE_FLASH_ATTR *encodeLength(uint32_t trueLength) {
void ICACHE_FLASH_ATTR pingAlive(void *arg) {
mqtt_session_t *pSession = (mqtt_session_t *)arg;
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_PINGREQ);
mqttSend(pSession, NULL, 0, MQTT_MSG_TYPE_PINGREQ);
}
uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint32_t len, mqtt_message_type msgType) {
uint8_t ICACHE_FLASH_ATTR mqttSend(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");
os_printf("Entering mqttSend!\n");
#endif
LOCAL mqtt_packet_t packet;
LOCAL mqtt_packet_t *pPacket = &packet;
@ -374,7 +374,6 @@ uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint
// 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
@ -401,10 +400,9 @@ uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint
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
case MQTT_MSG_TYPE_PINGREQ:
// PINGREQ and DISCONNECT have no varHeader or payload, it's just two bytes
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
@ -420,6 +418,7 @@ uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint
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;
@ -436,6 +435,12 @@ uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint
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 {
/* If we send a disconnect packet, we must close the connection ourselves,
per MQTT standard 3.14.4 */
espconn_disconnect(session->activeConnection);
os_timer_disarm(&MQTT_KeepAliveTimer); // ensure the keepalive timer is disarmed
return 0;
}
} else {
os_printf("No wifi! Narf!\n");

9
mqtt.h
View file

@ -26,10 +26,9 @@
* @typedef
* This is the enum for message types.
*
* This enum was taken from the NodeMCU mqtt headers. Credit is given to "zeroday" of nodemcu.com. This enum gives us both easily readable names for each message type, but also the correct value for each type. These are used in mqtt_send() to construct the correct packet type.
* This enum was taken from the NodeMCU mqtt headers. Credit is given to "zeroday" of nodemcu.com. This enum gives us both easily readable names for each message type, but also the correct value for each type. These are used in mqttSend() to construct the correct packet type.
*/
typedef enum mqtt_message_enum
{
typedef enum mqtt_message_enum {
MQTT_MSG_TYPE_CONNECT = 1,
MQTT_MSG_TYPE_CONNACK = 2,
MQTT_MSG_TYPE_PUBLISH = 3,
@ -135,7 +134,7 @@ uint8_t ICACHE_FLASH_ATTR *encodeLength(uint32_t trueLength);
* @param session a pointer to the active mqtt_session_t
* @param data a pointer to the data to be published; only applied to MQTT_MSG_TYPE_PUBLISH
* @param len the length of the above data
* @param msgType the type of message to be send, one of the mqtt_message_type
* @param msgType the type of message to be sent, one of the mqtt_message_type
* @return -1 in case of error, 0 otherwise
*/
uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint32_t len, mqtt_message_type msgType);
uint8_t ICACHE_FLASH_ATTR mqttSend(mqtt_session_t *session, uint8_t *data, uint32_t len, mqtt_message_type msgType);

7
strtoarr.py Executable file → Normal file
View file

@ -3,7 +3,7 @@
# 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/.
#!/usr/bin/python3
##
# @file
# @brief File to create string arrays
@ -19,7 +19,7 @@
import sys
import os
inString = str(sys.argv[1]);
inString = str(sys.argv[1])
print("static const char {0}[{1}] = {{ ".format(sys.argv[2], len(inString)), end='')
for letter in inString[:-1]:
@ -27,6 +27,5 @@ for letter in inString[:-1]:
print("{0:#x}, ".format(p), end='')
p = ord(inString[-1])
print("{0:#x} ".format(int(p)), end='')
print("}; // " + inString)
print("{0:#x} ".format(int(p)) + "}; // " + inString)
print("static const uint8_t {0}_len = {1};".format(sys.argv[2], len(inString)))