diff --git a/cmd/cmd.h b/cmd/cmd.h index 3b4e8ab..85032df 100644 --- a/cmd/cmd.h +++ b/cmd/cmd.h @@ -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, /* */ + CMD_WIFI_GET_APNAME, + CMD_WIFI_SELECT_SSID, + 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); diff --git a/cmd/handlers.c b/cmd/handlers.c index c191091..1be8b6e 100644 --- a/cmd/handlers.c +++ b/cmd/handlers.c @@ -17,6 +17,7 @@ #ifdef SOCKET #include #endif +#include #ifdef CMD_DBG #define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0) @@ -28,8 +29,17 @@ 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); + +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 +54,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}, @@ -178,6 +199,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 +245,114 @@ 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(); + os_printf("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); + os_printf("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'; + os_printf("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+2); + cmdPopArg(&req, pass, len); + pass[len] = 0; + + os_printf("SelectSSID(%d,%s)", ix, pass); + + char myssid[33]; + wifiGetApName(ix, myssid); + myssid[32] = '\0'; + connectToNetwork(myssid, pass); + } else { + ssid = os_malloc(len+2); + cmdPopArg(&req, ssid, len); + ssid[len] = 0; + + len = cmdArgLen(&req); + pass = (char *)os_malloc(len+2); + cmdPopArg(&req, pass, len); + pass[len] = 0; + + os_printf("SelectSSID(%s,%s)", ssid, pass); + connectToNetwork(ssid, pass); + } +} + +/* + * 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) { + os_printf("SetWifiInfo()\n"); +} + +static void ICACHE_FLASH_ATTR cmdWifiSignalStrength(CmdPacket *cmd) { + CmdRequest req; + + cmdRequest(&req, cmd); + + int argc = cmdGetArgc(&req); + if (argc != 1) { + os_printf("cmdWifiSignalStrength: argc %d\n", argc); + return; + } + + char x; + cmdPopArg(&req, (uint8_t*)&x, 1); + int i = x; + os_printf("cmdWifiSignalStrength: argc %d, ", argc); + os_printf("i %d\n", i); + + int rssi = wifiSignalStrength(i); + + cmdResponseStart(CMD_RESP_V, rssi, 0); + cmdResponseEnd(); +} diff --git a/esp-link/cgiwifi.c b/esp-link/cgiwifi.c index 987cb89..5078249 100644 --- a/esp-link/cgiwifi.c +++ b/esp-link/cgiwifi.c @@ -226,6 +226,7 @@ static void ICACHE_FLASH_ATTR scanStartCb(void *arg) { wifi_station_scan(NULL, wifiScanDoneCb); } +// Start scanning, web interface static int ICACHE_FLASH_ATTR cgiWiFiStartScan(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. jsonHeader(connData, 200); @@ -238,6 +239,16 @@ static int ICACHE_FLASH_ATTR cgiWiFiStartScan(HttpdConnData *connData) { return HTTPD_CGI_DONE; } +// Start scanning, API interface +void ICACHE_FLASH_ATTR cmdWifiStartScan(CmdPacket *cmd) { + if (!cgiWifiAps.scanInProgress) { + cgiWifiAps.scanInProgress = 1; + os_timer_disarm(&scanTimer); + os_timer_setfn(&scanTimer, scanStartCb, NULL); + os_timer_arm(&scanTimer, 200, 0); + } +} + static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. char buff[1460]; @@ -361,6 +372,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 +403,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); @@ -945,3 +962,58 @@ void ICACHE_FLASH_ATTR wifiInit() { os_timer_setfn(&resetTimer, resetTimerCb, NULL); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); } + +// Access functions for cgiWifiAps +int ICACHE_FLASH_ATTR wifiGetApCount() { + if (cgiWifiAps.scanInProgress) + return 0; + return cgiWifiAps.noAps; +} + +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); + + os_printf("AP %s\n", cgiWifiAps.apData[i]->ssid); +} + +// This may not belong here : called from cmd/handlers.c +// But it's good to have similar functionality close to each other. +// This performs functions similar to cgiWiFiConnect() +int ICACHE_FLASH_ATTR wifiConnect(char *ssid, char *pass) { +// Danny + return 0; +} + +ICACHE_FLASH_ATTR int wifiSignalStrength(int i) { + sint8 rssi; + + if (i < 0) + 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; +} + +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); + + os_printf("QuerySSID : %s\n", conf.ssid); + + cmdResponseStart(CMD_RESP_CB, callback, 1); + cmdResponseBody(conf.ssid, strlen((char *)conf.ssid)+1); + cmdResponseEnd(); +} diff --git a/esp-link/cgiwifi.h b/esp-link/cgiwifi.h index 667f27d..bf5d803 100644 --- a/esp-link/cgiwifi.h +++ b/esp-link/cgiwifi.h @@ -24,4 +24,11 @@ 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 cmdWifiQuerySSID(CmdPacket *cmd); +void cmdWifiStartScan(CmdPacket *cmd); + #endif diff --git a/esp-link/mqtt_client.c b/esp-link/mqtt_client.c index a9c1902..39325d7 100644 --- a/esp-link/mqtt_client.c +++ b/esp-link/mqtt_client.c @@ -114,4 +114,23 @@ mqtt_client_on_data(MqttDataCallback dataCb) { data_cb = dataCb; } +// 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); +} #endif // MQTT