mirror of https://github.com/jeelabs/esp-link.git
commit
5d03ac55aa
@ -0,0 +1,111 @@ |
||||
// Copyright 2015 by Thorsten von Eicken, see LICENSE.txt
|
||||
// // TCP Client settings
|
||||
|
||||
#include <esp8266.h> |
||||
#include "cgi.h" |
||||
#include "config.h" |
||||
#include "cgimqtt.h" |
||||
|
||||
// Cgi to return MQTT settings
|
||||
int ICACHE_FLASH_ATTR cgiMqttGet(HttpdConnData *connData) { |
||||
char buff[2048]; |
||||
int len; |
||||
|
||||
if (connData->conn==NULL) return HTTPD_CGI_DONE; |
||||
|
||||
len = os_sprintf(buff, "{ " |
||||
"\"slip-enable\":%d, " |
||||
"\"mqtt-enable\":%d, " |
||||
"\"mqtt-status-enable\":%d, " |
||||
"\"mqtt-port\":%d, " |
||||
"\"mqtt-host\":\"%s\", " |
||||
"\"mqtt-client-id\":\"%s\", " |
||||
"\"mqtt-username\":\"%s\", " |
||||
"\"mqtt-password\":\"%s\", " |
||||
"\"mqtt-status-topic\":\"%s\", " |
||||
"\"mqtt-state\":\"%s\" }", |
||||
flashConfig.slip_enable, flashConfig.mqtt_enable, flashConfig.mqtt_status_enable, |
||||
flashConfig.mqtt_port, flashConfig.mqtt_hostname, flashConfig.mqtt_client, |
||||
flashConfig.mqtt_username, flashConfig.mqtt_password, |
||||
flashConfig.mqtt_status_topic, "connected"); |
||||
|
||||
jsonHeader(connData, 200); |
||||
httpdSend(connData, buff, len); |
||||
return HTTPD_CGI_DONE; |
||||
} |
||||
|
||||
// Cgi to change choice of pin assignments
|
||||
int ICACHE_FLASH_ATTR cgiMqttSet(HttpdConnData *connData) { |
||||
if (connData->conn==NULL) return HTTPD_CGI_DONE; |
||||
|
||||
// handle MQTT server settings
|
||||
int mqtt_server = 0; // accumulator for changes/errors
|
||||
mqtt_server |= getStringArg(connData, "mqtt-host", |
||||
flashConfig.mqtt_hostname, sizeof(flashConfig.mqtt_hostname)); |
||||
if (mqtt_server < 0) return HTTPD_CGI_DONE; |
||||
mqtt_server |= getStringArg(connData, "mqtt-client-id", |
||||
flashConfig.mqtt_client, sizeof(flashConfig.mqtt_client)); |
||||
if (mqtt_server < 0) return HTTPD_CGI_DONE; |
||||
mqtt_server |= getStringArg(connData, "mqtt-username", |
||||
flashConfig.mqtt_username, sizeof(flashConfig.mqtt_username)); |
||||
if (mqtt_server < 0) return HTTPD_CGI_DONE; |
||||
mqtt_server |= getStringArg(connData, "mqtt-password", |
||||
flashConfig.mqtt_password, sizeof(flashConfig.mqtt_password)); |
||||
if (mqtt_server < 0) return HTTPD_CGI_DONE; |
||||
mqtt_server |= getBoolArg(connData, "mqtt-enable", |
||||
&flashConfig.mqtt_enable); |
||||
|
||||
// handle mqtt port
|
||||
char buff[16]; |
||||
if (httpdFindArg(connData->getArgs, "mqtt-port", buff, sizeof(buff)) > 0) { |
||||
int32_t port = atoi(buff); |
||||
if (port > 0 && port < 65536) { |
||||
flashConfig.mqtt_port = port; |
||||
mqtt_server |= 1; |
||||
} else { |
||||
errorResponse(connData, 400, "Invalid MQTT port"); |
||||
return HTTPD_CGI_DONE; |
||||
} |
||||
} |
||||
|
||||
// if server setting changed, we need to "make it so"
|
||||
if (mqtt_server) { |
||||
os_printf("MQTT server settings changed, enable=%d\n", flashConfig.mqtt_enable); |
||||
// TODO
|
||||
} |
||||
|
||||
// no action required if mqtt status settings change, they just get picked up at the
|
||||
// next status tick
|
||||
if (getBoolArg(connData, "mqtt-status-enable", &flashConfig.mqtt_status_enable) < 0) |
||||
return HTTPD_CGI_DONE; |
||||
if (getStringArg(connData, "mqtt-status-topic", |
||||
flashConfig.mqtt_status_topic, sizeof(flashConfig.mqtt_status_topic)) < 0) |
||||
return HTTPD_CGI_DONE; |
||||
|
||||
// if SLIP-enable is toggled it gets picked-up immediately by the parser
|
||||
int slip_update = getBoolArg(connData, "slip-enable", &flashConfig.slip_enable); |
||||
if (slip_update < 0) return HTTPD_CGI_DONE; |
||||
if (slip_update > 0) os_printf("SLIP-enable changed: %d\n", flashConfig.slip_enable); |
||||
|
||||
os_printf("Saving config\n"); |
||||
if (configSave()) { |
||||
httpdStartResponse(connData, 200); |
||||
httpdEndHeaders(connData); |
||||
} else { |
||||
httpdStartResponse(connData, 500); |
||||
httpdEndHeaders(connData); |
||||
httpdSend(connData, "Failed to save config", -1); |
||||
} |
||||
return HTTPD_CGI_DONE; |
||||
} |
||||
|
||||
int ICACHE_FLASH_ATTR cgiMqtt(HttpdConnData *connData) { |
||||
if (connData->requestType == HTTPD_METHOD_GET) { |
||||
return cgiMqttGet(connData); |
||||
} else if (connData->requestType == HTTPD_METHOD_POST) { |
||||
return cgiMqttSet(connData); |
||||
} else { |
||||
jsonHeader(connData, 404); |
||||
return HTTPD_CGI_DONE; |
||||
} |
||||
} |
@ -0,0 +1,8 @@ |
||||
#ifndef CGIMQTT_H |
||||
#define CGIMQTT_H |
||||
|
||||
#include "httpd.h" |
||||
|
||||
int cgiMqtt(HttpdConnData *connData); |
||||
|
||||
#endif |
@ -0,0 +1,99 @@ |
||||
<div id="main"> |
||||
<div class="header"> |
||||
<h1>REST & MQTT</h1> |
||||
</div> |
||||
|
||||
<div class="content"> |
||||
<div class="pure-g"> |
||||
<div class="pure-u-1"><div class="card"> |
||||
<p>The REST & MQTT support uses the SLIP protocol over the serial port to enable |
||||
the attached microcontroller to initiate outbound connections. |
||||
The REST support lets the uC initiate simple HTTP requests while the MQTT support |
||||
lets it communicate with an MQTT server bidirectionally at QoS 0 thru 2.</p> |
||||
<p>The MQTT support is in the form of a built-in client that connects to a server |
||||
using parameters set below and stored in esp-link's flash settings. This allows |
||||
esp-link to take care of connection parameters and disconnect/reconnect operations.</p> |
||||
<p>The MQTT client also supports sending periodic status messages about esp-link itself, |
||||
including Wifi RSSI, and free heap memory.</p> |
||||
<div class="form-horizontal"> |
||||
<input type="checkbox" name="slip-enable"/> |
||||
<label>Enable SLIP on serial port</label> |
||||
</div> |
||||
</div></div> |
||||
</div> |
||||
<div class="pure-g"> |
||||
<div class="pure-u-1 pure-u-md-1-2"> |
||||
<div class="card"> |
||||
<h1>MQTT |
||||
<div id="mqtt-spinner" class="spinner spinner-small"></div> |
||||
</h1> |
||||
<form action="#" id="mqtt-form" class="pure-form" hidden> |
||||
<div class="form-horizontal"> |
||||
<input type="checkbox" name="mqtt-enable"/> |
||||
<label>Enable MQTT client</label> |
||||
</div> |
||||
<div class="form-horizontal"> |
||||
<label>MQTT client state: </label> |
||||
<b id="mqtt-state"></b> |
||||
</div> |
||||
<br> |
||||
<legend>MQTT server settings</legend> |
||||
<div class="pure-form-stacked"> |
||||
<label>Server hostname/ip</label> |
||||
<input type="text" name="mqtt-host"/> |
||||
<label>Server port/ip</label> |
||||
<input type="text" name="mqtt-port"/> |
||||
<label>Client ID</label> |
||||
<input type="text" name="mqtt-client-id"/> |
||||
<label>Username</label> |
||||
<input type="text" name="mqtt-username"/> |
||||
<label>Password</label> |
||||
<input type="password" name="mqtt-password"/> |
||||
</div> |
||||
<button id="mqtt-button" type="submit" class="pure-button button-primary"> |
||||
Update server settings! |
||||
</button> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
<div class="pure-u-1 pure-u-md-1-2"> |
||||
<div class="card"> |
||||
<h1>Status reporting |
||||
<div id="mqtt-status-spinner" class="spinner spinner-small"></div> |
||||
</h1> |
||||
<form action="#" id="mqtt-status-form" class="pure-form" hidden> |
||||
<div class="form-horizontal"> |
||||
<input type="checkbox" name="mqtt-status-enable"/> |
||||
<label>Enable status reporting via MQTT</label> |
||||
</div> |
||||
<br> |
||||
<legend>Status reporting settings</legend> |
||||
<div class="pure-form-stacked"> |
||||
<label>Topic prefix</label> |
||||
<input type="text" name="mqtt-status-topic"/> |
||||
Suffixes: rssi, heap-free, ... |
||||
</div> |
||||
<button id="mqtt-status-button" type="submit" class="pure-button button-primary"> |
||||
Update status settings! |
||||
</button> |
||||
</form> |
||||
</div> |
||||
<div class="card"> |
||||
<h1>REST</h1> |
||||
<p>REST requests are enabled as soon as SLIP is enabled. |
||||
There are no REST-specific settings.</p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<script type="text/javascript"> |
||||
onLoad(function() { |
||||
fetchMqtt(); |
||||
bnd($("#mqtt-form"), "submit", changeMqtt); |
||||
bnd($("#mqtt-status-form"), "submit", changeMqttStatus); |
||||
}); |
||||
</script> |
||||
</body></html> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,64 @@ |
||||
// Copyright 2015 by Thorsten von Eicken, see LICENSE.txt
|
||||
|
||||
#include <esp8266.h> |
||||
#include "pktbuf.h" |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
PktBuf_Print(PktBuf *buf) { |
||||
os_printf("PktBuf:"); |
||||
for (int i=-16; i<0; i++) |
||||
os_printf(" %02X", ((uint8_t*)buf)[i]); |
||||
os_printf(" %p", buf); |
||||
for (int i=0; i<16; i++) |
||||
os_printf(" %02X", ((uint8_t*)buf)[i]); |
||||
os_printf("\n"); |
||||
os_printf("PktBuf: next=%p len=0x%04x\n", |
||||
((void**)buf)[-4], ((uint16_t*)buf)[-6]); |
||||
} |
||||
|
||||
|
||||
PktBuf * ICACHE_FLASH_ATTR |
||||
PktBuf_New(uint16_t length) { |
||||
PktBuf *buf = os_zalloc(length+sizeof(PktBuf)); |
||||
buf->next = NULL; |
||||
buf->filled = 0; |
||||
//os_printf("PktBuf_New: %p l=%d->%d d=%p\n",
|
||||
// buf, length, length+sizeof(PktBuf), buf->data);
|
||||
return buf; |
||||
} |
||||
|
||||
PktBuf * ICACHE_FLASH_ATTR |
||||
PktBuf_Push(PktBuf *headBuf, PktBuf *buf) { |
||||
if (headBuf == NULL) { |
||||
//os_printf("PktBuf_Push: %p\n", buf);
|
||||
return buf; |
||||
} |
||||
PktBuf *h = headBuf; |
||||
while (h->next != NULL) h = h->next; |
||||
h->next = buf; |
||||
//os_printf("PktBuf_Push: %p->..->%p\n", headBuf, buf);
|
||||
return headBuf; |
||||
} |
||||
|
||||
PktBuf * ICACHE_FLASH_ATTR |
||||
PktBuf_Unshift(PktBuf *headBuf, PktBuf *buf) { |
||||
buf->next = headBuf; |
||||
//os_printf("PktBuf_Unshift: %p->%p\n", buf, buf->next);
|
||||
return buf; |
||||
} |
||||
|
||||
PktBuf * ICACHE_FLASH_ATTR |
||||
PktBuf_Shift(PktBuf *headBuf) { |
||||
PktBuf *buf = headBuf->next; |
||||
headBuf->next = NULL; |
||||
//os_printf("PktBuf_Shift: (%p)->%p\n", headBuf, buf);
|
||||
return buf; |
||||
} |
||||
|
||||
PktBuf * ICACHE_FLASH_ATTR |
||||
PktBuf_ShiftFree(PktBuf *headBuf) { |
||||
PktBuf *buf = headBuf->next; |
||||
//os_printf("PktBuf_ShiftFree: (%p)->%p\n", headBuf, buf);
|
||||
os_free(headBuf); |
||||
return buf; |
||||
} |
@ -0,0 +1,29 @@ |
||||
// Copyright 2015 by Thorsten von Eicken, see LICENSE.txt
|
||||
|
||||
#ifndef PKTBUF_H |
||||
#define PKTBUF_H |
||||
|
||||
typedef struct PktBuf { |
||||
struct PktBuf *next; // next buffer in chain
|
||||
uint16_t filled; // number of bytes filled in buffer
|
||||
uint8_t data[0]; // data in buffer
|
||||
} PktBuf; |
||||
|
||||
// Allocate a new packet buffer of given length
|
||||
PktBuf *PktBuf_New(uint16_t length); |
||||
|
||||
// Append a buffer to the end of a packet buffer queue, returns new head
|
||||
PktBuf *PktBuf_Push(PktBuf *headBuf, PktBuf *buf); |
||||
|
||||
// Prepend a buffer to the beginning of a packet buffer queue, return new head
|
||||
PktBuf * PktBuf_Unshift(PktBuf *headBuf, PktBuf *buf); |
||||
|
||||
// Shift first buffer off queue, returns new head (not shifted buffer!)
|
||||
PktBuf *PktBuf_Shift(PktBuf *headBuf); |
||||
|
||||
// Shift first buffer off queue, free it, return new head
|
||||
PktBuf *PktBuf_ShiftFree(PktBuf *headBuf); |
||||
|
||||
void PktBuf_Print(PktBuf *buf); |
||||
|
||||
#endif |
@ -1,86 +0,0 @@ |
||||
#include "proto.h" |
||||
|
||||
int8_t ICACHE_FLASH_ATTR
|
||||
PROTO_Init(PROTO_PARSER* parser, PROTO_PARSE_CALLBACK* completeCallback, uint8_t* buf, uint16_t bufSize) { |
||||
parser->buf = buf; |
||||
parser->bufSize = bufSize; |
||||
parser->dataLen = 0; |
||||
parser->callback = completeCallback; |
||||
parser->isEsc = 0; |
||||
return 0; |
||||
} |
||||
|
||||
int8_t ICACHE_FLASH_ATTR
|
||||
PROTO_ParseByte(PROTO_PARSER* parser, uint8_t value) { |
||||
switch (value) { |
||||
case 0x7D: |
||||
parser->isEsc = 1; |
||||
break; |
||||
|
||||
case 0x7E: |
||||
parser->dataLen = 0; |
||||
parser->isEsc = 0; |
||||
parser->isBegin = 1; |
||||
break; |
||||
|
||||
case 0x7F: |
||||
if (parser->callback != NULL) |
||||
parser->callback(); |
||||
parser->isBegin = 0; |
||||
return 0; |
||||
break; |
||||
|
||||
default: |
||||
if (parser->isBegin == 0) break; |
||||
|
||||
if (parser->isEsc) { |
||||
value ^= 0x20; |
||||
parser->isEsc = 0; |
||||
} |
||||
|
||||
if (parser->dataLen < parser->bufSize) |
||||
parser->buf[parser->dataLen++] = value; |
||||
|
||||
break; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
int16_t ICACHE_FLASH_ATTR
|
||||
PROTO_ParseRb(RINGBUF* rb, uint8_t* bufOut, uint16_t* len, uint16_t maxBufLen) { |
||||
uint8_t c; |
||||
|
||||
PROTO_PARSER proto; |
||||
PROTO_Init(&proto, NULL, bufOut, maxBufLen); |
||||
while (RINGBUF_Get(rb, &c) == 0) { |
||||
if (PROTO_ParseByte(&proto, c) == 0) { |
||||
*len = proto.dataLen; |
||||
return 0; |
||||
} |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
int16_t ICACHE_FLASH_ATTR
|
||||
PROTO_AddRb(RINGBUF* rb, const uint8_t* packet, int16_t len) { |
||||
uint16_t i = 2; |
||||
if (RINGBUF_Put(rb, 0x7E) == -1) return -1; |
||||
while (len--) { |
||||
switch (*packet) { |
||||
case 0x7D: |
||||
case 0x7E: |
||||
case 0x7F: |
||||
if (RINGBUF_Put(rb, 0x7D) == -1) return -1; |
||||
if (RINGBUF_Put(rb, *packet++ ^ 0x20) == -1) return -1; |
||||
i += 2; |
||||
break; |
||||
default: |
||||
if (RINGBUF_Put(rb, *packet++) == -1) return -1; |
||||
i++; |
||||
break; |
||||
} |
||||
} |
||||
if (RINGBUF_Put(rb, 0x7F) == -1) return -1; |
||||
|
||||
return i; |
||||
} |
@ -1,21 +0,0 @@ |
||||
#ifndef _PROTO_H_ |
||||
#define _PROTO_H_ |
||||
#include <esp8266.h> |
||||
#include "ringbuf.h" |
||||
|
||||
typedef void (PROTO_PARSE_CALLBACK)(); |
||||
|
||||
typedef struct { |
||||
uint8_t* buf; |
||||
uint16_t bufSize; |
||||
uint16_t dataLen; |
||||
uint8_t isEsc; |
||||
uint8_t isBegin; |
||||
PROTO_PARSE_CALLBACK* callback; |
||||
} PROTO_PARSER; |
||||
|
||||
int8_t PROTO_Init(PROTO_PARSER* parser, PROTO_PARSE_CALLBACK* completeCallback, uint8_t* buf, uint16_t bufSize); |
||||
int16_t PROTO_AddRb(RINGBUF* rb, const uint8_t* packet, int16_t len); |
||||
int8_t PROTO_ParseByte(PROTO_PARSER* parser, uint8_t value); |
||||
int16_t PROTO_ParseRb(RINGBUF* rb, uint8_t* bufOut, uint16_t* len, uint16_t maxBufLen); |
||||
#endif |
@ -1,53 +0,0 @@ |
||||
/* str_queue.c
|
||||
* |
||||
* Copyright (c) 2014-2015, Tuan PM <tuanpm at live dot com> |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Redis nor the names of its contributors may be used |
||||
* to endorse or promote products derived from this software without |
||||
* specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
#include "queue.h" |
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
QUEUE_Init(QUEUE* queue, int bufferSize) { |
||||
queue->buf = (uint8_t*)os_zalloc(bufferSize); |
||||
RINGBUF_Init(&queue->rb, queue->buf, bufferSize); |
||||
} |
||||
|
||||
int32_t ICACHE_FLASH_ATTR
|
||||
QUEUE_Puts(QUEUE* queue, uint8_t* buffer, uint16_t len) { |
||||
return PROTO_AddRb(&queue->rb, buffer, len); |
||||
} |
||||
|
||||
int32_t ICACHE_FLASH_ATTR
|
||||
QUEUE_Gets(QUEUE* queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen) { |
||||
return PROTO_ParseRb(&queue->rb, buffer, len, maxLen); |
||||
} |
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
QUEUE_IsEmpty(QUEUE* queue) { |
||||
if (queue->rb.fill_cnt <= 0) |
||||
return TRUE; |
||||
return FALSE; |
||||
} |
@ -1,46 +0,0 @@ |
||||
/* str_queue.h --
|
||||
* |
||||
* Copyright (c) 2014-2015, Tuan PM <tuanpm at live dot com> |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Redis nor the names of its contributors may be used |
||||
* to endorse or promote products derived from this software without |
||||
* specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#ifndef USER_QUEUE_H_ |
||||
#define USER_QUEUE_H_ |
||||
#include <esp8266.h> |
||||
#include "proto.h" |
||||
#include "ringbuf.h" |
||||
|
||||
typedef struct { |
||||
uint8_t* buf; |
||||
RINGBUF rb; |
||||
} QUEUE; |
||||
|
||||
void QUEUE_Init(QUEUE* queue, int bufferSize); |
||||
int32_t QUEUE_Puts(QUEUE* queue, uint8_t* buffer, uint16_t len); |
||||
int32_t QUEUE_Gets(QUEUE* queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen); |
||||
bool QUEUE_IsEmpty(QUEUE* queue); |
||||
#endif /* USER_QUEUE_H_ */ |
@ -1,63 +0,0 @@ |
||||
#include "ringbuf.h" |
||||
|
||||
/**
|
||||
* \brief init a RINGBUF object |
||||
* \param r pointer to a RINGBUF object |
||||
* \param buf pointer to a byte array |
||||
* \param size size of buf |
||||
* \return 0 if successfull, otherwise failed |
||||
*/ |
||||
int16_t ICACHE_FLASH_ATTR
|
||||
RINGBUF_Init(RINGBUF* r, uint8_t* buf, int32_t size) { |
||||
if (r == NULL || buf == NULL || size < 2) return -1; |
||||
|
||||
r->p_o = r->p_r = r->p_w = buf; |
||||
r->fill_cnt = 0; |
||||
r->size = size; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* \brief put a character into ring buffer |
||||
* \param r pointer to a ringbuf object |
||||
* \param c character to be put |
||||
* \return 0 if successfull, otherwise failed |
||||
*/ |
||||
int16_t ICACHE_FLASH_ATTR
|
||||
RINGBUF_Put(RINGBUF* r, uint8_t c) { |
||||
if (r->fill_cnt >= r->size)return -1; // ring buffer is full, this should be atomic operation
|
||||
|
||||
|
||||
r->fill_cnt++; // increase filled slots count, this should be atomic operation
|
||||
|
||||
|
||||
*r->p_w++ = c; // put character into buffer
|
||||
|
||||
if (r->p_w >= r->p_o + r->size) // rollback if write pointer go pass
|
||||
r->p_w = r->p_o; // the physical boundary
|
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* \brief get a character from ring buffer |
||||
* \param r pointer to a ringbuf object |
||||
* \param c read character |
||||
* \return 0 if successfull, otherwise failed |
||||
*/ |
||||
int16_t ICACHE_FLASH_ATTR
|
||||
RINGBUF_Get(RINGBUF* r, uint8_t* c) { |
||||
if (r->fill_cnt <= 0)return -1; // ring buffer is empty, this should be atomic operation
|
||||
|
||||
|
||||
r->fill_cnt--; // decrease filled slots count
|
||||
|
||||
|
||||
*c = *r->p_r++; // get the character out
|
||||
|
||||
if (r->p_r >= r->p_o + r->size) // rollback if write pointer go pass
|
||||
r->p_r = r->p_o; // the physical boundary
|
||||
|
||||
return 0; |
||||
} |
@ -1,17 +0,0 @@ |
||||
#ifndef _RING_BUF_H_ |
||||
#define _RING_BUF_H_ |
||||
|
||||
#include <esp8266.h> |
||||
|
||||
typedef struct { |
||||
uint8_t* p_o; /**< Original pointer */ |
||||
uint8_t* volatile p_r; /**< Read pointer */ |
||||
uint8_t* volatile p_w; /**< Write pointer */ |
||||
volatile int32_t fill_cnt; /**< Number of filled slots */ |
||||
int32_t size; /**< Buffer size */ |
||||
} RINGBUF; |
||||
|
||||
int16_t RINGBUF_Init(RINGBUF* r, uint8_t* buf, int32_t size); |
||||
int16_t RINGBUF_Put(RINGBUF* r, uint8_t c); |
||||
int16_t RINGBUF_Get(RINGBUF* r, uint8_t* c); |
||||
#endif |
@ -0,0 +1,6 @@ |
||||
#ifndef SLIP_H |
||||
#define SLIP_H |
||||
|
||||
void slip_parse_buf(char *buf, short length); |
||||
|
||||
#endif |
@ -1,70 +1,87 @@ |
||||
#include <esp8266.h> |
||||
//#include <mqtt.h>
|
||||
//#include <cgiwifi.h>
|
||||
#include "cgiwifi.h" |
||||
#include "mqtt.h" |
||||
|
||||
//MQTT_Client mqttClient;
|
||||
//
|
||||
//void ICACHE_FLASH_ATTR
|
||||
//mqttConnectedCb(uint32_t *args) {
|
||||
MQTT_Client mqttClient; |
||||
|
||||
static ETSTimer mqttTimer; |
||||
|
||||
static int once = 0; |
||||
static void ICACHE_FLASH_ATTR mqttTimerCb(void *arg) { |
||||
if (once++ > 0) return; |
||||
MQTT_Init(&mqttClient, "h.voneicken.com", 1883, 0, 2, "test1", "", "", 10, 1); |
||||
MQTT_Connect(&mqttClient); |
||||
MQTT_Subscribe(&mqttClient, "system/time", 0); |
||||
} |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
wifiStateChangeCb(uint8_t status) |
||||
{ |
||||
if (status == wifiGotIP) { |
||||
os_timer_disarm(&mqttTimer); |
||||
os_timer_setfn(&mqttTimer, mqttTimerCb, NULL); |
||||
os_timer_arm(&mqttTimer, 15000, 0); |
||||
} |
||||
} |
||||
|
||||
|
||||
// initialize the custom stuff that goes beyond esp-link
|
||||
void app_init() { |
||||
wifiAddStateChangeCb(wifiStateChangeCb); |
||||
} |
||||
|
||||
|
||||
#if 0 |
||||
MQTT_Client mqttClient; |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
mqttConnectedCb(uint32_t *args) { |
||||
MQTT_Client* client = (MQTT_Client*)args; |
||||
MQTT_Publish(client, "announce/all", "Hello World!", 0, 0); |
||||
} |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
mqttDisconnectedCb(uint32_t *args) { |
||||
// MQTT_Client* client = (MQTT_Client*)args;
|
||||
// MQTT_Publish(client, "announce/all", "Hello World!", 0, 0);
|
||||
//}
|
||||
//
|
||||
//void ICACHE_FLASH_ATTR
|
||||
//mqttDisconnectedCb(uint32_t *args) {
|
||||
//// MQTT_Client* client = (MQTT_Client*)args;
|
||||
// os_printf("MQTT Disconnected\n");
|
||||
//}
|
||||
//
|
||||
//void ICACHE_FLASH_ATTR
|
||||
//mqttTcpDisconnectedCb(uint32_t *args) {
|
||||
//// MQTT_Client* client = (MQTT_Client*)args;
|
||||
// os_printf("MQTT TCP Disconnected\n");
|
||||
//}
|
||||
//
|
||||
//void ICACHE_FLASH_ATTR
|
||||
//mqttPublishedCb(uint32_t *args) {
|
||||
//// MQTT_Client* client = (MQTT_Client*)args;
|
||||
// os_printf("MQTT Published\n");
|
||||
//}
|
||||
//
|
||||
//void ICACHE_FLASH_ATTR
|
||||
//mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) {
|
||||
// char *topicBuf = (char*)os_zalloc(topic_len + 1);
|
||||
// char *dataBuf = (char*)os_zalloc(data_len + 1);
|
||||
//
|
||||
//// MQTT_Client* client = (MQTT_Client*)args;
|
||||
//
|
||||
// os_memcpy(topicBuf, topic, topic_len);
|
||||
// topicBuf[topic_len] = 0;
|
||||
//
|
||||
// os_memcpy(dataBuf, data, data_len);
|
||||
// dataBuf[data_len] = 0;
|
||||
//
|
||||
// os_printf("Receive topic: %s, data: %s\n", topicBuf, dataBuf);
|
||||
// os_free(topicBuf);
|
||||
// os_free(dataBuf);
|
||||
//}
|
||||
//
|
||||
//void ICACHE_FLASH_ATTR
|
||||
//wifiStateChangeCb(uint8_t status)
|
||||
//{
|
||||
// if (status == wifiGotIP && mqttClient.connState != TCP_CONNECTING){
|
||||
// MQTT_Connect(&mqttClient);
|
||||
// }
|
||||
// else if (status == wifiIsDisconnected && mqttClient.connState == TCP_CONNECTING){
|
||||
// MQTT_Disconnect(&mqttClient);
|
||||
// }
|
||||
//}
|
||||
|
||||
void init() { |
||||
// wifiAddStateChangeCb(wifiStateChangeCb);
|
||||
// MQTT_InitConnection(&mqttClient, MQTT_HOST, MQTT_PORT, MQTT_SECURITY);
|
||||
// MQTT_InitClient(&mqttClient, MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, MQTT_KEEPALIVE, MQTT_CLSESSION);
|
||||
// MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0);
|
||||
// MQTT_OnConnected(&mqttClient, mqttConnectedCb);
|
||||
// MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);
|
||||
// MQTT_OnDisconnected(&mqttClient, mqttTcpDisconnectedCb);
|
||||
// MQTT_OnPublished(&mqttClient, mqttPublishedCb);
|
||||
// MQTT_OnData(&mqttClient, mqttDataCb);
|
||||
os_printf("MQTT Disconnected\n"); |
||||
} |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
mqttTcpDisconnectedCb(uint32_t *args) { |
||||
// MQTT_Client* client = (MQTT_Client*)args;
|
||||
os_printf("MQTT TCP Disconnected\n"); |
||||
} |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
mqttPublishedCb(uint32_t *args) { |
||||
// MQTT_Client* client = (MQTT_Client*)args;
|
||||
os_printf("MQTT Published\n"); |
||||
} |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) { |
||||
char *topicBuf = (char*)os_zalloc(topic_len + 1); |
||||
char *dataBuf = (char*)os_zalloc(data_len + 1); |
||||
|
||||
// MQTT_Client* client = (MQTT_Client*)args;
|
||||
|
||||
os_memcpy(topicBuf, topic, topic_len); |
||||
topicBuf[topic_len] = 0; |
||||
|
||||
os_memcpy(dataBuf, data, data_len); |
||||
dataBuf[data_len] = 0; |
||||
|
||||
os_printf("Receive topic: %s, data: %s\n", topicBuf, dataBuf); |
||||
os_free(topicBuf); |
||||
os_free(dataBuf); |
||||
} |
||||
|
||||
MQTT_InitConnection(&mqttClient, MQTT_HOST, MQTT_PORT, MQTT_SECURITY); |
||||
MQTT_InitClient(&mqttClient, MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, MQTT_KEEPALIVE, MQTT_CLSESSION); |
||||
MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); |
||||
MQTT_OnConnected(&mqttClient, mqttConnectedCb); |
||||
MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb); |
||||
MQTT_OnDisconnected(&mqttClient, mqttTcpDisconnectedCb); |
||||
MQTT_OnPublished(&mqttClient, mqttPublishedCb); |
||||
MQTT_OnData(&mqttClient, mqttDataCb); |
||||
#endif |
||||
|
Loading…
Reference in new issue