* Following tve's guidelines to submit the changes for query-ip, I think.
pull/326/head
dannybackx 8 years ago committed by Thorsten von Eicken
parent fa5bafbced
commit 6bdfaf933e
  1. 13
      Makefile
  2. 10
      cmd/cmd.h
  3. 218
      cmd/handlers.c
  4. 112
      esp-link/cgiwifi.c
  5. 6
      esp-link/cgiwifi.h
  6. 2
      esp-link/mqtt_client.c
  7. 1
      serial/serbridge.c
  8. 1
      socket/socket.c

@ -189,7 +189,8 @@ endif
TRAVIS_BRANCH?=$(shell git symbolic-ref --short HEAD --quiet)
# Use git describe to get the latest version tag, commits since then, sha and dirty flag, this
# results is something like "v1.2.0-13-ab6cedf-dirty"
VERSION := $(shell (git describe --tags --match 'v*' --long --dirty || echo "no-tag") | sed -re 's/(\.0)?-/./')
NO_TAG ?= "no-tag"
VERSION := $(shell (git describe --tags --match 'v*' --long --dirty || echo $(NO_TAG)) | sed -re 's/(\.0)?-/./')
# If not on master then insert the branch name
ifneq ($(TRAVIS_BRANCH),master)
ifneq ($(findstring V%,$(TRAVIS_BRANCH)),)
@ -519,3 +520,13 @@ ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes")
endif
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))
depend:
makedepend -p${BUILD_BASE}/ -Y -- $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) -I${XTENSA_TOOLS_ROOT}../xtensa-lx106-elf/include -I${XTENSA_TOOLS_ROOT}../lib/gcc/xtensa-lx106-elf/4.8.2/include -- */*.c
# Rebuild version at least at every Makefile change
${BUILD_BASE}/esp-link/main.o: Makefile
# DO NOT DELETE

@ -42,11 +42,14 @@ typedef enum {
CMD_CB_ADD,
CMD_CB_EVENTS,
CMD_GET_TIME, // get current time in seconds since the unix epoch
CMD_GET_WIFI_INFO, // query ip address info
CMD_SET_WIFI_INFO, // set ip address info
CMD_MQTT_SETUP = 10, // set-up callbacks
CMD_MQTT_PUBLISH, // publish a message
CMD_MQTT_SUBSCRIBE, // subscribe to a topic
CMD_MQTT_LWT, // set the last-will-topic and messge
CMD_MQTT_GET_CLIENTID,
CMD_REST_SETUP = 20, // set-up callbacks
CMD_REST_REQUEST, // do REST request
@ -58,6 +61,13 @@ typedef enum {
CMD_SOCKET_SETUP = 40, // set-up callbacks
CMD_SOCKET_SEND, // send data over UDP socket
CMD_WIFI_GET_APCOUNT = 50, // Query the number of networks / Access Points known
CMD_WIFI_GET_APNAME, // Query the name (SSID) of an Access Point (AP)
CMD_WIFI_SELECT_SSID, // Connect to a specific network
CMD_WIFI_SIGNAL_STRENGTH, // Query RSSI
CMD_WIFI_GET_SSID, // Query SSID currently connected to
CMD_WIFI_START_SCAN, // Trigger a scan (takes a long time)
} CmdName;
typedef void (*cmdfunc_t)(CmdPacket *cmd);

@ -17,6 +17,10 @@
#ifdef SOCKET
#include <socket.h>
#endif
#include <ip_addr.h>
#include "esp-link/cgi.h"
#include "config.h"
#ifdef CMD_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
@ -28,8 +32,19 @@ static void cmdNull(CmdPacket *cmd);
static void cmdSync(CmdPacket *cmd);
static void cmdWifiStatus(CmdPacket *cmd);
static void cmdGetTime(CmdPacket *cmd);
static void cmdGetWifiInfo(CmdPacket *cmd);
// static void cmdSetWifiInfo(CmdPacket *cmd);
static void cmdAddCallback(CmdPacket *cmd);
static void cmdWifiGetApCount(CmdPacket *cmd);
static void cmdWifiGetApName(CmdPacket *cmd);
static void cmdWifiSelectSSID(CmdPacket *cmd);
static void cmdWifiSignalStrength(CmdPacket *cmd);
static void cmdWifiQuerySSID(CmdPacket *cmd);
static void cmdWifiStartScan(CmdPacket *cmd);
void cmdMqttGetClientId(CmdPacket *cmd);
// keep track of last status sent to uC so we can notify it when it changes
static uint8_t lastWifiStatus = wifiIsDisconnected;
// keep track of whether we have registered our cb handler with the wifi subsystem
@ -44,11 +59,22 @@ const CmdList commands[] = {
{CMD_WIFI_STATUS, "WIFI_STATUS", cmdWifiStatus},
{CMD_CB_ADD, "ADD_CB", cmdAddCallback},
{CMD_GET_TIME, "GET_TIME", cmdGetTime},
{CMD_GET_WIFI_INFO, "GET_WIFI_INFO", cmdGetWifiInfo},
// {CMD_SET_WIFI_INFO, "SET_WIFI_INFO", cmdSetWifiInfo},
{CMD_WIFI_GET_APCOUNT, "WIFI_GET_APCOUNT", cmdWifiGetApCount},
{CMD_WIFI_GET_APNAME, "WIFI_GET_APNAME", cmdWifiGetApName},
{CMD_WIFI_SELECT_SSID, "WIFI_SELECT_SSID", cmdWifiSelectSSID},
{CMD_WIFI_SIGNAL_STRENGTH, "WIFI_SIGNAL_STRENGTH", cmdWifiSignalStrength},
{CMD_WIFI_GET_SSID, "WIFI_GET_SSID", cmdWifiQuerySSID},
{CMD_WIFI_START_SCAN, "WIFI_START_SCAN", cmdWifiStartScan},
#ifdef MQTT
{CMD_MQTT_SETUP, "MQTT_SETUP", MQTTCMD_Setup},
{CMD_MQTT_PUBLISH, "MQTT_PUB", MQTTCMD_Publish},
{CMD_MQTT_SUBSCRIBE , "MQTT_SUB", MQTTCMD_Subscribe},
{CMD_MQTT_LWT, "MQTT_LWT", MQTTCMD_Lwt},
{CMD_MQTT_GET_CLIENTID,"MQTT_CLIENTID", cmdMqttGetClientId},
#endif
#ifdef REST
{CMD_REST_SETUP, "REST_SETUP", REST_Setup},
@ -72,7 +98,7 @@ CmdCallback callbacks[MAX_CALLBACKS]; // cleared in cmdSync
uint32_t ICACHE_FLASH_ATTR
cmdAddCb(char* name, uint32_t cb) {
for (uint8_t i = 0; i < MAX_CALLBACKS; i++) {
//os_printf("cmdAddCb: index %d name=%s cb=%p\n", i, callbacks[i].name,
//DBG("cmdAddCb: index %d name=%s cb=%p\n", i, callbacks[i].name,
// (void *)callbacks[i].callback);
// find existing callback or add to the end
if (os_strncmp(callbacks[i].name, name, CMD_CBNLEN) == 0 || callbacks[i].name[0] == '\0') {
@ -89,7 +115,7 @@ cmdAddCb(char* name, uint32_t cb) {
CmdCallback* ICACHE_FLASH_ATTR
cmdGetCbByName(char* name) {
for (uint8_t i = 0; i < MAX_CALLBACKS; i++) {
//os_printf("cmdGetCbByName: index %d name=%s cb=%p\n", i, callbacks[i].name,
//DBG("cmdGetCbByName: index %d name=%s cb=%p\n", i, callbacks[i].name,
// (void *)callbacks[i].callback);
// if callback doesn't exist or it's null
if (os_strncmp(callbacks[i].name, name, CMD_CBNLEN) == 0) {
@ -97,7 +123,7 @@ cmdGetCbByName(char* name) {
return &callbacks[i];
}
}
os_printf("cmdGetCbByName: cb %s not found\n", name);
DBG("cmdGetCbByName: cb %s not found\n", name);
return 0;
}
@ -178,6 +204,33 @@ cmdGetTime(CmdPacket *cmd) {
return;
}
// Command handler for IP information
static void ICACHE_FLASH_ATTR
cmdGetWifiInfo(CmdPacket *cmd) {
CmdRequest req;
cmdRequest(&req, cmd);
if(cmd->argc != 0 || cmd->value == 0) {
cmdResponseStart(CMD_RESP_V, 0, 0);
cmdResponseEnd();
return;
}
uint32_t callback = req.cmd->value;
struct ip_info info;
wifi_get_ip_info(0, &info);
uint8_t mac[6];
wifi_get_macaddr(0, mac);
cmdResponseStart(CMD_RESP_CB, callback, 4);
cmdResponseBody(&info.ip.addr, sizeof(info.ip.addr));
cmdResponseBody(&info.netmask.addr, sizeof(info.netmask.addr));
cmdResponseBody(&info.gw.addr, sizeof(info.gw.addr));
cmdResponseBody(mac, sizeof(mac));
cmdResponseEnd();
}
// Command handler to add a callback to the named-callbacks list, this is for a callback to the uC
static void ICACHE_FLASH_ATTR
cmdAddCallback(CmdPacket *cmd) {
@ -197,3 +250,162 @@ cmdAddCallback(CmdPacket *cmd) {
cmdAddCb(name, cmd->value); // save the sensor callback
}
// Query the number of wifi access points
static void ICACHE_FLASH_ATTR cmdWifiGetApCount(CmdPacket *cmd) {
int n = wifiGetApCount();
DBG("WifiGetApCount : %d\n", n);
cmdResponseStart(CMD_RESP_V, n, 0);
cmdResponseEnd();
}
// Query the name of a wifi access point
static void ICACHE_FLASH_ATTR cmdWifiGetApName(CmdPacket *cmd) {
CmdRequest req;
cmdRequest(&req, cmd);
int argc = cmdGetArgc(&req);
DBG("cmdWifiGetApName: argc %d\n", argc);
if (argc != 1)
return;
uint16_t i;
cmdPopArg(&req, (uint8_t*)&i, 2);
uint32_t callback = req.cmd->value;
char myssid[33];
wifiGetApName(i, myssid);
myssid[32] = '\0';
DBG("wifiGetApName(%d) -> {%s}\n", i, myssid);
cmdResponseStart(CMD_RESP_CB, callback, 1);
cmdResponseBody(myssid, strlen(myssid)+1);
cmdResponseEnd();
}
/*
* Select a wireless network.
* This can be called in two ways :
* - with a pair of strings (SSID, password)
* - with a number and a string (index into network array, password)
*/
static void ICACHE_FLASH_ATTR cmdWifiSelectSSID(CmdPacket *cmd) {
CmdRequest req;
cmdRequest(&req, cmd);
int argc = cmdGetArgc(&req);
char *ssid, *pass;
if (argc != 2)
return;
int len = cmdArgLen(&req);
if (len == 1) {
// Assume this is the index
uint8_t ix;
cmdPopArg(&req, &ix, 1);
len = cmdArgLen(&req);
pass = (char *)os_malloc(len+1);
cmdPopArg(&req, pass, len);
pass[len] = 0;
DBG("SelectSSID(%d,%s)", ix, pass);
char myssid[33];
wifiGetApName(ix, myssid);
myssid[32] = '\0';
connectToNetwork(myssid, pass);
} else {
ssid = os_malloc(len+1);
cmdPopArg(&req, ssid, len);
ssid[len] = 0;
len = cmdArgLen(&req);
pass = (char *)os_malloc(len+2);
cmdPopArg(&req, pass, len);
pass[len] = 0;
DBG("SelectSSID(%s,%s)", ssid, pass);
connectToNetwork(ssid, pass);
}
}
#if 0
/*
* Once we're attached to some wireless network, choose not to pick up address from
* DHCP or so but set our own.
*/
static void ICACHE_FLASH_ATTR cmdSetWifiInfo(CmdPacket *cmd) {
DBG("SetWifiInfo()\n");
}
#endif
static void ICACHE_FLASH_ATTR cmdWifiSignalStrength(CmdPacket *cmd) {
CmdRequest req;
cmdRequest(&req, cmd);
int argc = cmdGetArgc(&req);
if (argc != 1) {
DBG("cmdWifiSignalStrength: argc %d\n", argc);
return;
}
char x;
cmdPopArg(&req, (uint8_t*)&x, 1);
int i = x;
DBG("cmdWifiSignalStrength: argc %d, ", argc);
DBG("i %d\n", i);
int rssi = wifiSignalStrength(i);
cmdResponseStart(CMD_RESP_V, rssi, 0);
cmdResponseEnd();
}
//
static void ICACHE_FLASH_ATTR cmdWifiQuerySSID(CmdPacket *cmd) {
CmdRequest req;
cmdRequest(&req, cmd);
uint32_t callback = req.cmd->value;
struct station_config conf;
bool res = wifi_station_get_config(&conf);
if (res) {
// #warning handle me
} else {
}
DBG("QuerySSID : %s\n", conf.ssid);
cmdResponseStart(CMD_RESP_CB, callback, 1);
cmdResponseBody(conf.ssid, strlen((char *)conf.ssid)+1);
cmdResponseEnd();
}
// Start scanning, API interface
static void ICACHE_FLASH_ATTR cmdWifiStartScan(CmdPacket *cmd) {
// call a function that belongs in esp-link/cgiwifi.c due to variable access
wifiStartScan();
}
// Command handler for MQTT information
void ICACHE_FLASH_ATTR cmdMqttGetClientId(CmdPacket *cmd) {
CmdRequest req;
cmdRequest(&req, cmd);
if(cmd->argc != 0 || cmd->value == 0) {
cmdResponseStart(CMD_RESP_V, 0, 0);
cmdResponseEnd();
return;
}
uint32_t callback = req.cmd->value;
cmdResponseStart(CMD_RESP_CB, callback, 1);
cmdResponseBody(flashConfig.mqtt_clientid, strlen(flashConfig.mqtt_clientid)+1);
cmdResponseEnd();
os_printf("MqttGetClientId : %s\n", flashConfig.mqtt_clientid);
}

@ -13,6 +13,7 @@ Cgi/template routines for the /wifi url.
* ----------------------------------------------------------------------------
*/
#include <esp8266.h>
#include "cgiwifi.h"
#include "cgi.h"
@ -34,7 +35,7 @@ bool mdns_started = false;
// ===== wifi status change callbacks
static WifiStateChangeCb wifi_state_change_cb[4];
// Temp store for new staion config
// Temp store for new station config
struct station_config stconf;
// Temp store for new ap config
@ -226,25 +227,13 @@ static void ICACHE_FLASH_ATTR scanStartCb(void *arg) {
wifi_station_scan(NULL, wifiScanDoneCb);
}
static int ICACHE_FLASH_ATTR cgiWiFiStartScan(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200);
if (!cgiWifiAps.scanInProgress) {
cgiWifiAps.scanInProgress = 1;
os_timer_disarm(&scanTimer);
os_timer_setfn(&scanTimer, scanStartCb, NULL);
os_timer_arm(&scanTimer, 200, 0);
}
return HTTPD_CGI_DONE;
}
static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
char buff[1460];
const int chunk = 1460/64; // ssid is up to 32 chars
int len = 0;
os_printf("GET scan: cgiData=%d noAps=%d\n", (int)connData->cgiData, cgiWifiAps.noAps);
DBG("GET scan: cgiData=%d noAps=%d\n", (int)connData->cgiData, cgiWifiAps.noAps);
// handle continuation call, connData->cgiData-1 is the position in the scan results where we
// we need to continue sending from (using -1 'cause 0 means it's the first call)
@ -284,6 +273,27 @@ static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) {
return HTTPD_CGI_MORE;
}
// Start scanning, without parameters
void ICACHE_FLASH_ATTR wifiStartScan() {
if (!cgiWifiAps.scanInProgress) {
cgiWifiAps.scanInProgress = 1;
os_timer_disarm(&scanTimer);
os_timer_setfn(&scanTimer, scanStartCb, NULL);
os_timer_arm(&scanTimer, 200, 0);
}
}
// Start scanning, web interface
int ICACHE_FLASH_ATTR cgiWiFiStartScan(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200);
// Don't duplicate code, reuse the function above.
wifiStartScan();
return HTTPD_CGI_DONE;
}
int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
if (connData->requestType == HTTPD_METHOD_GET) {
return cgiWiFiGetScan(connData);
@ -361,6 +371,18 @@ static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
os_timer_arm(&resetTimer, 4*RESET_TIMEOUT, 0);
}
// Kick off connection to some network
void ICACHE_FLASH_ATTR connectToNetwork(char *ssid, char *pass) {
os_strncpy((char*)stconf.ssid, ssid, 32);
os_strncpy((char*)stconf.password, pass, 64);
DBG("Wifi try to connect to AP %s pw %s\n", ssid, pass);
// Schedule disconnect/connect
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, reassTimerCb, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
}
// This cgi uses the routines above to connect to a specific access point with the
// given ESSID using the given password.
int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
@ -380,14 +402,8 @@ int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
if (el > 0 && pl >= 0) {
//Set to 0 if you want to disable the actual reconnecting bit
os_strncpy((char*)stconf.ssid, essid, 32);
os_strncpy((char*)stconf.password, passwd, 64);
DBG("Wifi try to connect to AP %s pw %s\n", essid, passwd);
//Schedule disconnect/connect
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, reassTimerCb, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
connectToNetwork(essid, passwd);
jsonHeader(connData, 200);
} else {
jsonHeader(connData, 400);
@ -425,12 +441,12 @@ static bool ICACHE_FLASH_ATTR parse_ip(char *buff, ip_addr_t *ip_ptr) {
static void ICACHE_FLASH_ATTR debugIP() {
struct ip_info info;
if (wifi_get_ip_info(0, &info)) {
os_printf("\"ip\": \"%d.%d.%d.%d\"\n", IP2STR(&info.ip.addr));
os_printf("\"netmask\": \"%d.%d.%d.%d\"\n", IP2STR(&info.netmask.addr));
os_printf("\"gateway\": \"%d.%d.%d.%d\"\n", IP2STR(&info.gw.addr));
os_printf("\"hostname\": \"%s\"\n", wifi_station_get_hostname());
DBG("\"ip\": \"%d.%d.%d.%d\"\n", IP2STR(&info.ip.addr));
DBG("\"netmask\": \"%d.%d.%d.%d\"\n", IP2STR(&info.netmask.addr));
DBG("\"gateway\": \"%d.%d.%d.%d\"\n", IP2STR(&info.gw.addr));
DBG("\"hostname\": \"%s\"\n", wifi_station_get_hostname());
} else {
os_printf("\"ip\": \"-none-\"\n");
DBG("\"ip\": \"-none-\"\n");
}
}
#endif
@ -562,7 +578,7 @@ int ICACHE_FLASH_ATTR cgiApSettingsChange(HttpdConnData *connData) {
if (checkString(buff) && len>7 && len<=64) {
// String preprocessing done in client side, wifiap.js line 31
os_memcpy(apconf.password, buff, len);
os_printf("Setting AP password len=%d\n", len);
DBG("Setting AP password len=%d\n", len);
} else if (len != 0) {
jsonHeader(connData, 400);
httpdSend(connData, "PASSWORD not valid or out of range", -1);
@ -578,18 +594,18 @@ int ICACHE_FLASH_ATTR cgiApSettingsChange(HttpdConnData *connData) {
apconf.authmode = value;
} else {
// If out of range set by default
os_printf("Forcing AP authmode to WPA_WPA2_PSK\n");
DBG("Forcing AP authmode to WPA_WPA2_PSK\n");
apconf.authmode = 4;
}
} else {
// Valid password but wrong auth mode, default 4
os_printf("Forcing AP authmode to WPA_WPA2_PSK\n");
DBG("Forcing AP authmode to WPA_WPA2_PSK\n");
apconf.authmode = 4;
}
} else {
apconf.authmode = 0;
}
os_printf("Setting AP authmode=%d\n", apconf.authmode);
DBG("Setting AP authmode=%d\n", apconf.authmode);
// Set max connection number
len=httpdFindArg(connData->getArgs, "ap_maxconn", buff, sizeof(buff));
if(len>0){
@ -945,3 +961,37 @@ void ICACHE_FLASH_ATTR wifiInit() {
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
}
// Access functions for cgiWifiAps : query the number of entries in the table
int ICACHE_FLASH_ATTR wifiGetApCount() {
if (cgiWifiAps.scanInProgress)
return 0;
return cgiWifiAps.noAps;
}
// Access functions for cgiWifiAps : returns the name of a network, i is the index into the array, return stored in memory pointed to by ptr.
ICACHE_FLASH_ATTR void wifiGetApName(int i, char *ptr) {
if (i < 0)
return;
if (i >= cgiWifiAps.noAps)
return;
if (ptr != 0)
strncpy(ptr, cgiWifiAps.apData[i]->ssid, 32);
DBG("AP %s\n", cgiWifiAps.apData[i]->ssid);
}
// Access functions for cgiWifiAps : returns the signal strength of network (i is index into array). Return current network strength for negative i.
ICACHE_FLASH_ATTR int wifiSignalStrength(int i) {
sint8 rssi;
if (i < 0 || i == 255)
rssi = wifi_station_get_rssi(); // Current network's signal strength
else if (i >= cgiWifiAps.noAps)
rssi = 0; // FIX ME
else
rssi = cgiWifiAps.apData[i]->rssi; // Signal strength of any known network
return rssi;
}

@ -24,4 +24,10 @@ int checkString(char *str);
extern uint8_t wifiState;
extern bool mdns_started;
int wifiGetApCount();
void wifiGetApName(int, char *);
int wifiSignalStrength(int);
void connectToNetwork(char *, char *);
void wifiStartScan();
#endif

@ -4,6 +4,7 @@
#include "config.h"
#include "mqtt.h"
#ifdef MQTTCLIENT_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
@ -113,5 +114,4 @@ void ICACHE_FLASH_ATTR
mqtt_client_on_data(MqttDataCallback dataCb) {
data_cb = dataCb;
}
#endif // MQTT

@ -9,7 +9,6 @@
#include "config.h"
#include "console.h"
#include "slip.h"
#include "cmd.h"
#ifdef SYSLOG
#include "syslog.h"
#else

@ -7,7 +7,6 @@
#include "c_types.h"
#include "ip_addr.h"
#include "socket.h"
#include "cmd.h"
#define SOCK_DBG

Loading…
Cancel
Save