mirror of https://github.com/jeelabs/esp-link.git
Merge branch 'master' of https://github.com/jeelabs/esp-link into jeelabs-master
Conflicts: esp-link/cgi.c include/user_config.h mqtt/mqtt.h user/user_main.cpull/47/head
commit
33f9ede084
@ -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 <esp8266.h> |
||||||
//#include <mqtt.h>
|
#include "cgiwifi.h" |
||||||
//#include <cgiwifi.h>
|
#include "mqtt.h" |
||||||
|
|
||||||
//MQTT_Client mqttClient;
|
MQTT_Client mqttClient; |
||||||
//
|
|
||||||
//void ICACHE_FLASH_ATTR
|
static ETSTimer mqttTimer; |
||||||
//mqttConnectedCb(uint32_t *args) {
|
|
||||||
|
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_Client* client = (MQTT_Client*)args;
|
||||||
// MQTT_Publish(client, "announce/all", "Hello World!", 0, 0);
|
os_printf("MQTT Disconnected\n"); |
||||||
//}
|
|
||||||
//
|
|
||||||
//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);
|
|
||||||
} |
} |
||||||
|
|
||||||
|
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