Mergine master back into priv to continue work/debugging
Signed-off-by: A.M. Rowsell <amrowsell@frozenelectronics.ca>
This commit is contained in:
commit
045e438b6e
9 changed files with 44 additions and 141 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -9,4 +9,5 @@ mqtt
|
|||
\#*\#
|
||||
.\#*
|
||||
pcap/
|
||||
docs/
|
||||
docs/latex/
|
||||
docs/man/
|
14
.gitlab-ci.yml
Normal file
14
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
# This file is a template, and might need editing before it works on your project.
|
||||
# Full project: https://gitlab.com/pages/doxygen
|
||||
image: alpine
|
||||
|
||||
pages:
|
||||
script:
|
||||
- apk update && apk add doxygen graphviz
|
||||
- doxygen Doxyfile
|
||||
- mv docs/html/ public/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- master
|
2
Doxyfile
2
Doxyfile
|
@ -51,7 +51,7 @@ PROJECT_BRIEF = "MQTT library for ESP8266"
|
|||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||
# the logo to the output directory.
|
||||
|
||||
PROJECT_LOGO = /home/amr/Pictures/284737-cute-food/png/fortune-cookie_small.png
|
||||
PROJECT_LOGO = fortune-cookie_small.png
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||
# into which the generated documentation will be written. If a relative path is
|
||||
|
|
4
Makefile
4
Makefile
|
@ -23,7 +23,3 @@ flash: $(P)-0x00000.bin
|
|||
|
||||
clean:
|
||||
rm -f $(P) $(OBJ) $(P)-0x00000.bin $(P)-0x10000.bin *~
|
||||
|
||||
library:
|
||||
$(CC) -c -fPIC $(CFLAGS) $(P).c -o $(P).o
|
||||
$(AR) rcs lib$(P).a $(P).o
|
||||
|
|
133
README.md
133
README.md
|
@ -7,135 +7,4 @@ 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.
|
||||
|
||||
## API Structures
|
||||
|
||||
```
|
||||
typedef struct {
|
||||
uint8_t ip[4];
|
||||
uint32_t port;
|
||||
uint32_t localPort;
|
||||
uint8_t *client_id;
|
||||
uint32_t client_id_len;
|
||||
uint8_t *topic_name;
|
||||
uint32_t topic_name_len;
|
||||
uint8_t qos_level;
|
||||
uint8_t *username;
|
||||
uint32_t username_len;
|
||||
uint8_t *password;
|
||||
uint32_t password_len;
|
||||
char valid_connection;
|
||||
struct espconn *activeConnection;
|
||||
} mqtt_session_t;
|
||||
```
|
||||
|
||||
This is the main structure that contains all the information about the connection to the server. The IP address, port, client\_id, topic\_name, username, and password are all specified here by the end user. localPort is set by the API, and qos\_level should be set to 0. *activeConnection will point to the espconn struct that represents the TCP connection to the server. The end-user shouldn't need to touch anything in this struct.
|
||||
|
||||
## API Functions
|
||||
|
||||
### `LOCAL uint8_t ICACHE_FLASH_ATTR mqtt_send(mqtt_session_t *session, uint8_t *data, uint32_t len, mqtt_message_type msgType);`
|
||||
|
||||
This is the only function that needs to be called by the user. You pass the `mqtt_session_t` that you have created with all the fields filled in, you pass `*data` if you are publishing (NULL otherwise), len which is the length of `*data` (again, only if publishing, 0 otherwise), and then the message type you want to send, which is one of these enums:
|
||||
|
||||
```
|
||||
typedef enum mqtt_message_enum
|
||||
{
|
||||
MQTT_MSG_TYPE_CONNECT = 1,
|
||||
MQTT_MSG_TYPE_CONNACK = 2,
|
||||
MQTT_MSG_TYPE_PUBLISH = 3,
|
||||
MQTT_MSG_TYPE_PUBACK = 4,
|
||||
MQTT_MSG_TYPE_PUBREC = 5,
|
||||
MQTT_MSG_TYPE_PUBREL = 6,
|
||||
MQTT_MSG_TYPE_PUBCOMP = 7,
|
||||
MQTT_MSG_TYPE_SUBSCRIBE = 8,
|
||||
MQTT_MSG_TYPE_SUBACK = 9,
|
||||
MQTT_MSG_TYPE_UNSUBSCRIBE = 10,
|
||||
MQTT_MSG_TYPE_UNSUBACK = 11,
|
||||
MQTT_MSG_TYPE_PINGREQ = 12,
|
||||
MQTT_MSG_TYPE_PINGRESP = 13,
|
||||
MQTT_MSG_TYPE_DISCONNECT = 14
|
||||
} mqtt_message_type;
|
||||
```
|
||||
|
||||
Obviously, the user will only be choosing CONNECT, PUBLISH, SUBSCRIBE, UNSUBSCRIBE, PINGREQ and DISCONNECT. The rest are messages from the broker back to the client. If you send an incorrect message type, nothing will happen, and no TCP packets will be sent to the broker.
|
||||
|
||||
Due to a strange bug with the way pointers to strings are passed between functions, all the fields in the `mqtt_session_t` need to be allocated and have their contents memcpy'd. They also need to be in hex format. This is a pain in the butt, so there is an included Python 3 script to create the arrays for you. Running it is as simple as the following:
|
||||
|
||||
```
|
||||
$ chmod +x strtoarr.py
|
||||
$ ./strtoarr.py MyUsername username
|
||||
static const char username[10] = { 0x4d, 0x79, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65 };
|
||||
static const uint8_t username_len = 10;
|
||||
```
|
||||
|
||||
Then copy and paste the result into your code. Allocate the correct amount of memory, then copy and pass the pointer into the struct:
|
||||
|
||||
```
|
||||
static const char username[10] = { 0x4d, 0x79, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65 };
|
||||
static const uint8_t username_len = 10;
|
||||
pGlobalSession->username_len = username_len;
|
||||
pGlobalSession->username = os_zalloc(sizeof(uint8_t) * pGlobalSession->username_len);
|
||||
os_memcpy(pGlobalSession->username, testUser, pGlobalSession->username_len);
|
||||
```
|
||||
|
||||
Slightly more complex than just passing the address of a char array, but until I can figure out why the ESP8266 butchers strings that are passed by reference, this is how it has to be.
|
||||
|
||||
A very basic, fully working example that doesn't do anything but establish a connection might look like this:
|
||||
|
||||
```
|
||||
LOCAL mqtt_session_t globalSession;
|
||||
LOCAL mqtt_session_t *pGlobalSession = &globalSession;
|
||||
char ssid[32] = "WirelessAP";
|
||||
char passkey[64] = "myAPpassword";
|
||||
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
|
||||
|
||||
// testUser = MrAureliusR
|
||||
static const char testUser[11] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52 };
|
||||
static const uint8_t testUser_len = 11;
|
||||
// testPass = test
|
||||
static const char testPass[4] = { 0x74, 0x65, 0x73, 0x74 };
|
||||
static const uint8_t testPass_len = 4;
|
||||
// testTopic = test
|
||||
static const char testTopic[4] = { 0x74, 0x65, 0x73, 0x74 };
|
||||
static const uint8_t testTopic_len = 4;
|
||||
// clientID = FRZN0 (this can be anything you like, under 21 characters)
|
||||
static const char clientID[5] = { 0x46, 0x52, 0x5a, 0x4e, 0x30 };
|
||||
static const uint8_t clientID_len = 5;
|
||||
pGlobalSession->port = 1883; // mqtt port
|
||||
static const char esp_tcp_server_ip[4] = {8, 8, 8, 8}; // the IP address of the server you want to connect to
|
||||
|
||||
// copy all these into their proper locations
|
||||
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);
|
||||
```
|
||||
|
||||
After this, you can set up a task or timer to actually call mqtt_send with the pointer to mqtt_session_t and the MQTT_MSG_TYPE_CONNECT. A connect function might look like this:
|
||||
|
||||
```
|
||||
LOCAL void ICACHE_FLASH_ATTR con(void *arg) {
|
||||
mqtt_session_t *pSession = (mqtt_session_t *)arg;
|
||||
tcp_connect(pSession); // establish tcp connection
|
||||
os_delay_us(60000);
|
||||
// a future version of the API won't require a delay here
|
||||
// if you are having problems, try adding more os_delay_us(60000); here. Sometimes the TCP
|
||||
// connection takes longer to start
|
||||
mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_CONNECT);
|
||||
}
|
||||
```
|
||||
The documentation has now been turned into Doxygen documentation. You can view the latest documentation [here](https://mraureliusr.gitlab.io/mqtt-esp8266/index.html)
|
||||
|
|
BIN
fortune-cookie_small.png
Normal file
BIN
fortune-cookie_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
2
mqtt.h
2
mqtt.h
|
@ -100,7 +100,7 @@ void ICACHE_FLASH_ATTR reconnected_callback(void *arg, sint8 err);
|
|||
/**
|
||||
* A callback function which is called when TCP connection is successful.
|
||||
* @param *arg A pointer to void, which needs to be cast to espconn *pConn
|
||||
* @returns Void
|
||||
* @return Void
|
||||
*
|
||||
* This function is called once the TCP connection to the server is completed. This allows us to register the callbacks for received and sent data, as well as enable TCP keepalive and set validConnection in mqtt_session_t to 1 to show the connection has been successful.
|
||||
*/
|
||||
|
|
|
@ -1,3 +1,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/. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "os_type.h"
|
||||
#include "osapi.h"
|
||||
|
@ -5,7 +9,7 @@
|
|||
#include "gpio.h"
|
||||
#include "onewire.h"
|
||||
|
||||
#define OWBUS BIT5
|
||||
#define OWBUS BIT5 /**< This define determines which pin is used */
|
||||
|
||||
sint8 ICACHE_FLASH_ATTR reset(void) {
|
||||
uint32_t time;
|
||||
|
@ -20,7 +24,7 @@ sint8 ICACHE_FLASH_ATTR reset(void) {
|
|||
// give a 480uS pause so the next onewire event doesn't get trampled
|
||||
time = system_get_time() + 480;
|
||||
while(system_get_time() < time);
|
||||
|
||||
|
||||
if(!presence) {
|
||||
return 1;
|
||||
} else {
|
||||
|
|
19
onewire.h
19
onewire.h
|
@ -1,7 +1,16 @@
|
|||
/* 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 "os_type.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief This is the header file for the one-wire library
|
||||
*/
|
||||
|
||||
/**
|
||||
* @struct oneWire_t
|
||||
* Structure that holds all the information about onewire connections, including the 64-bit ROM address for each device and some buffer memory to read out the scratchpad
|
||||
|
@ -29,5 +38,15 @@ typedef enum {
|
|||
E2_RECALL = 0xB8
|
||||
} ds18b20_cmds;
|
||||
|
||||
/**
|
||||
* Function sends a reset pulse on the one-wire bus and checks for a presence pulse
|
||||
* @return 0 if no presence, 1 if presence
|
||||
*/
|
||||
sint8 ICACHE_FLASH_ATTR reset(void);
|
||||
|
||||
/**
|
||||
* Function which handles all one-wire communication besides the reset sequence.
|
||||
* @param owDev A pointer to the oneWire_t variable for this device
|
||||
* @param cmd One of the commands from ds18b20_cmds
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR transact(oneWire_t *owDev, ds18b20_cmds cmd);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue