Skip to content

Getting IP address of device connected to SoftAP #2100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mkeyno opened this issue Jun 6, 2016 · 16 comments
Closed

Getting IP address of device connected to SoftAP #2100

mkeyno opened this issue Jun 6, 2016 · 16 comments

Comments

@mkeyno
Copy link

mkeyno commented Jun 6, 2016

hi,
I'm trying to get IP address of each device that has been connected to AP mode ESP, I use the following code but the code just reveal any connection that been made or disconnected , it there any way that find device IP as soon as get any connection to AP ESP

`void WiFiEvent(WiFiEvent_t event) {
//Serial.printf("[WiFi-event] event: %d\n", event);

switch(event) 

{
case WIFI_EVENT_STAMODE_CONNECTED:
Serial.println("[ST]WiFi just connected"); break;
case WIFI_EVENT_STAMODE_DISCONNECTED:
Serial.println("[ST]WiFi lost connection"); break;
case WIFI_EVENT_STAMODE_AUTHMODE_CHANGE:
Serial.println("[ST]WiFi mode changed"); break;
case WIFI_EVENT_STAMODE_GOT_IP:
Serial.print("[ST]WiFi connected, IP=");Serial.println(WiFi.localIP()); break;
case WIFI_EVENT_STAMODE_DHCP_TIMEOUT:
Serial.println("[ST]WiFi DHCP TIMEOUT"); break;
case WIFI_EVENT_SOFTAPMODE_STACONNECTED:
{
WiFiClient client = server.client();
Serial.print("[AP] new clinet, IP=");Serial.println(client.remoteIP());
}
break;
case WIFI_EVENT_SOFTAPMODE_STADISCONNECTED:
Serial.println("[AP]client disconnected"); break;
case WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED:
Serial.println("[AP]err on recieved request"); break;
}
}`

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@igrr
Copy link
Member

igrr commented Jun 6, 2016

This will not work. WIFI_EVENT_SOFTAPMODE_STACONNECTED indicates that the client is connected to SoftAP, not to your web server. server.client will not return anything useful at the point when WIFI_EVENT_SOFTAPMODE_STACONNECTED event arrives.

@igrr igrr changed the title WiFiEvent not shows any device IP which is connected Getting IP address of device connected to SoftAP Jun 6, 2016
@mkeyno
Copy link
Author

mkeyno commented Jun 6, 2016

so how to get the IP address as soon as received any connection to my AP ESP module ?, I intend register each device information as it connected

another question
how many wifi node can connected to AP ESP module ? is it related to max client that ESP concurrently can server ?

@igrr
Copy link
Member

igrr commented Jun 7, 2016

Short answer, you can't (with the current version). Currently event handlers registered via onEvent do not receive event data. This is something i'm currently working on.
Regarding the maximum number of clients, it is 5.

@mkeyno
Copy link
Author

mkeyno commented Jun 7, 2016

how about the MAC address? , I've noticed when I enable Serial.setDebugOutput(true); ,I could see the mac address of connected device
any way do you have any suggestion for getting the information from any connected device?
please correct me ,
maximum concurrently 5 wifi connection
or maximum concurrently 5 HTTP client request
my best thanks for all time you spend here

@igrr
Copy link
Member

igrr commented Jun 7, 2016

As I said, currently you can't get information about clients connected to WiFi using Arduino APIs.
You will be able to get MAC address of client connected to WiFi, once this is implemented.

You can also get client's IP address as soon as the client connects to HTTP server.

Esp8266WebServer library does not handle concurrent connections. You may want to check me-no-dev's asynchronous http server library if you need to handle multiple clients concurrently.

@mkeyno
Copy link
Author

mkeyno commented Jun 7, 2016

not very concurrently. actually I have plan to set one ESP as AP and others(5 to 10 ) as Stations , which are periodically send data to the AP module , I don't know what strategy should follow ? do you think your Esp8266WebServer can handle such a Server -Clients net

@tibfox
Copy link

tibfox commented Aug 4, 2016

@mkeyno I have the same plan right now and I am thinking about a solution too. Without a MAC or IP of the clients, there is currently no chance to implement a reliable solution.
an unsecure but possible way would be, sending the ip or mac within the message itself. hmm

looking forward :)

@onkie
Copy link

onkie commented Aug 5, 2016

ESP8266: Simple Ping, is that a solution for your problem? Visit my website:
http://www.kendziorra.nl/arduino/93-esp8266-simple-pingpong and
http://www.kendziorra.nl/8
It also works in AP mode. Each device must have a static IP.
AP-mode DEMO:
doPing() start
Ping IP: 192.168.4.1, ESP8266 WSserver
ping recv: bytes = 32, time = 6ms
ping recv: bytes = 32, time = 2ms
ping recv: bytes = 32, time = 2ms
ping finished
Ping IP: 192.168.4.2, ESP8266 WSslave
ping recv: bytes = 32, time = 210ms
ping recv: bytes = 32, time = 26ms
ping recv: bytes = 32, time = 2ms
ping finished
Ping IP: 192.168.4.3, dummy IP
No Pong (device OFFline)
No Pong (device OFFline)
No Pong (device OFFline)
ping finished

Modify/add in the download (IP and names as example):
===== MODIFY ======
const uint8_t ipCount = 3; // number of IP addresses in pingIp[2][n] array
const char* pingIp[2][ipCount] = {{"192.168.4.1", "192.168.4.2", "192.168.4.3"},
{"ESP8266 WSserver", "ESP8266 WSslave", "dummy IP"}};
===== ADD ======
const IPAddress local_IP( 192, 168, 4, 4); // static IP
const IPAddress gateway_IP(192, 168, 4, 1); // gateway IP
const IPAddress subnet_IP( 255, 255, 255, 0); // standard subnet
===== ADD in setup ======
WiFi.config(local_IP, gateway_IP, subnet_IP); // we use a static IP address

@mkeyno
Copy link
Author

mkeyno commented Aug 6, 2016

thanks @onkie although I couldn't find any code form your page or the links you provided, however I was wondering what would be your approach to get IP of connected devices? is it in setup or loop function or tied to wifievent handler ?

@onkie
Copy link

onkie commented Aug 6, 2016

I am not on Github but i have my own website.
Github links are to github…. pages you must copy by links and paste in the web browser to get the right pages.
http://www.kendziorra.nl/arduino/93
http://www.kendziorra.nl/8

@onkie
Copy link

onkie commented Aug 6, 2016

Please note!
Default max_connection in AP mode is 4 connections at the same time. You can change this in:
C:\Users\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\libraries\ESP8266WiFi\src\ESP8266WiFiAP.cpp
Search for "conf.max_connection = 4;" and change the value (after a esp8266 packages update: repeat this before (re)compile the firmware)
On reset of a slave/client the connection is still alive in the AP-Server, after reconnecting then the old connection will be lost.
So at least: max_connection = <number off AP-mode-slaves/clients> + 1

@miclooking
Copy link

Short answer, you can't (with the current version). Currently event handlers registered via onEvent do not receive event data. This is something i'm currently working on.

Can you please tell me when event data will be available?
I would like to use the WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED and get the corresponding MAC address.
Thank you very much.

@wwwmshdir
Copy link

Hello.
i have a same problem and solve it by:
/////////////////////////////////////////////////////////////////////////
// By Mr Mojtaba Rahsepar From IRAN.
// Web: www.MSHD.ir
/////////////////////////////////////////////////////////////////////////

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <MyMoma.h>

#include "ESP8266WiFiGeneric.h"
#include "ESP8266WiFiAP.h"

extern "C" {
#include "c_types.h"
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
}

int NeedRefresh=0;
int TotalTry=0;

/* Set these to your desired credentials. */
const char *ssid = "demo";
const char *password = "12345678";

ESP8266WebServer server(80);
bool MomaDHCPInfoReady();

bool MomaDHCPInfoReady()
{
unsigned char softap_stations_cnt;
struct station_info *stat_info;
int i=0;

softap_stations_cnt = wifi_softap_get_station_num(); // Count of stations which are connected to ESP8266 soft-AP
stat_info = wifi_softap_get_station_info();
while (stat_info != NULL)
{
stat_info = STAILQ_NEXT(stat_info, next);
i++;
}
return (i==softap_stations_cnt);
}

void showinfo()
{
unsigned char softap_stations_cnt;
struct station_info *stat_info;
struct ip_addr *ipaddr;
//uint32 uintaddress;
uint8 mac[6];
IPAddress ip;
String s;
int i=0;

softap_stations_cnt = wifi_softap_get_station_num(); // Count of stations which are connected to ESP8266 soft-AP
stat_info = wifi_softap_get_station_info();
//Serial.write(softap_stations_cnt);
while (stat_info != NULL)
{
ipaddr = &stat_info->ip;
ip=ipaddr->addr;
mac[0]=stat_info->bssid[0];
mac[1]=stat_info->bssid[1];
mac[2]=stat_info->bssid[2];
mac[3]=stat_info->bssid[3];
mac[4]=stat_info->bssid[4];
mac[5]=stat_info->bssid[5];
// &stat_info->bssid
//uintaddress = IPaddress->addr;
s=String(i)+" IP:"+ip.toString();
/*
s+=" Mac:"+String(mac[0],HEX);
s+="-"+String(mac[1],HEX);
s+="-"+String(mac[2],HEX);
s+="-"+String(mac[3],HEX);
s+="-"+String(mac[4],HEX);
s+="-"+String(mac[5],HEX);
/
s+=" Mac:"+MomaMacToStr(&mac[0],"-");
Serial.println(s);
stat_info = STAILQ_NEXT(stat_info, next);
i++;
}
/

int i = 1;
struct station_info *stat_info;
stat_info = wifi_softap_get_station_info();
while (stat_info != NULL) {
Serial.write("Station #");
Serial.write(i);
Serial.write(" : ");
Serial.write(stat_info->bssid[0]);
Serial.write(stat_info->bssid[1]);
Serial.write(stat_info->bssid[2]);
Serial.write(stat_info->bssid[3]);
Serial.write(stat_info->bssid[4]);
Serial.write(stat_info->bssid[5]);
Serial.write("\n");
i++;
stat_info = STAILQ_NEXT(stat_info, next);
}
*/
}

void handleRoot() {
String s;
IPAddress ip;
WiFiClient wc;
wc=server.client();
ip=wc.remoteIP();
s=ip2str(ip)+" Mac: "+MomaGetMacOfIPInDHCP(ip,"-");
server.send(200, "text/html", "

You are connected at "+s+"

");
}

void WiFiEvent(WiFiEvent_t event) {
static int i=0;

struct station_info *stat_info;

switch(event) 
{

/*
case WIFI_EVENT_ANY:
Serial.println("WIFI_EVENT_ANY");
break;
case WIFI_EVENT_MODE_CHANGE:
Serial.println("WIFI_EVENT_MODE_CHANGE");
break;
case WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED:
Serial.println("WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED");
break;
*/
case WIFI_EVENT_SOFTAPMODE_STACONNECTED:
Serial.println("WIFI_EVENT_SOFTAPMODE_STACONNECTED");
//Serial.printf("%d [WiFi-event] event: %d ", i++,event);
//Serial.print("IP address: ");
//Serial.println(WiFi.localIP());
//Serial.println(WiFi.macAddress());
//Serial.println(WiFi.softAPmacAddress());
//Serial.println(WiFi.softAPgetStationNum());

        //wifi_softap_dhcps_stop();

        NeedRefresh=1;
        //showinfo();
        break;
        case WIFI_EVENT_SOFTAPMODE_STADISCONNECTED:
        Serial.println("WIFI_EVENT_SOFTAPMODE_STADISCONNECTED");
        //Serial.printf("%d  [WiFi-event] event: %d    ", i++,event);
        //Serial.print("IP address: ");
        //Serial.println(WiFi.localIP());
        //Serial.println(WiFi.macAddress());
        //Serial.println(WiFi.softAPmacAddress());
        //Serial.println(WiFi.softAPgetStationNum());
        //wifi_softap_dhcps_start();
        //showinfo();
        NeedRefresh=1;
        break;

/*
case WIFI_EVENT_STAMODE_AUTHMODE_CHANGE:
Serial.println("WIFI_EVENT_STAMODE_AUTHMODE_CHANGE");
break;
case WIFI_EVENT_STAMODE_CONNECTED:
Serial.println("WIFI_EVENT_STAMODE_CONNECTED");
break;
case WIFI_EVENT_STAMODE_DHCP_TIMEOUT:
Serial.println("WIFI_EVENT_STAMODE_DHCP_TIMEOUT");
break;
case WIFI_EVENT_STAMODE_DISCONNECTED:
Serial.println("WIFI_EVENT_STAMODE_DISCONNECTED");
break;
case WIFI_EVENT_STAMODE_GOT_IP:
Serial.println("WIFI_EVENT_STAMODE_GOT_IP");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
break;
*/
}
}

void setup() {
delay(1000);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
/* You can remove the password parameter if you want the AP to be open. */
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);

IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
WiFi.onEvent(WiFiEvent,WIFI_EVENT_ANY); 

}
void loop() {
server.handleClient();
//showinfo();
//delay(1000);
if (NeedRefresh==1)
{
if (MomaDHCPInfoReady())
{
showinfo();
NeedRefresh=0;
Serial.println("================ "+String(TotalTry)+" ================");
TotalTry=0;
}
else
{
delay(100);
TotalTry++;
};
};
}

@wwwmshdir
Copy link

Hello . i used Arduino for program.
in Setup() Function used it:

void setup() {
.................
WiFi.onEvent(WiFiEvent,WIFI_EVENT_ANY);
}

and used this function:

void WiFiEvent(WiFiEvent_t event) {
switch(event)
{
case WIFI_EVENT_SOFTAPMODE_STACONNECTED:
NeedRefresh=1;
break;
case WIFI_EVENT_SOFTAPMODE_STADISCONNECTED:
NeedRefresh=1;
break;
}
}

and used this variabel in global section:

int NeedRefresh=0;

and in Loop() function:

void loop() {
server.handleClient();
//showinfo();
//delay(1000);
if (NeedRefresh==1)
{
if (MomaDHCPInfoReady())
{
showinfo();
NeedRefresh=0;
Serial.println("================ "+String(TotalTry)+" ================");
TotalTry=0;
}
else
{
delay(100);
TotalTry++;
};
};
}

and used this:

void showinfo()
{
unsigned char softap_stations_cnt;
struct station_info *stat_info;
struct ip_addr *ipaddr;
//uint32 uintaddress;
uint8 mac[6];
IPAddress ip;
String s;
int i=0;

softap_stations_cnt = wifi_softap_get_station_num(); // Count of stations which are connected to ESP8266 soft-AP
stat_info = wifi_softap_get_station_info();
//Serial.write(softap_stations_cnt);
while (stat_info != NULL)
{
ipaddr = &stat_info->ip;
ip=ipaddr->addr;
mac[0]=stat_info->bssid[0];
mac[1]=stat_info->bssid[1];
mac[2]=stat_info->bssid[2];
mac[3]=stat_info->bssid[3];
mac[4]=stat_info->bssid[4];
mac[5]=stat_info->bssid[5];
// &stat_info->bssid
//uintaddress = IPaddress->addr;
s=String(i)+" IP:"+ip.toString();
/*
s+=" Mac:"+String(mac[0],HEX);
s+="-"+String(mac[1],HEX);
s+="-"+String(mac[2],HEX);
s+="-"+String(mac[3],HEX);
s+="-"+String(mac[4],HEX);
s+="-"+String(mac[5],HEX);
/
s+=" Mac:"+MomaMacToStr(&mac[0],"-");
Serial.println(s);
stat_info = STAILQ_NEXT(stat_info, next);
i++;
}
/

int i = 1;
struct station_info *stat_info;
stat_info = wifi_softap_get_station_info();
while (stat_info != NULL) {
Serial.write("Station #");
Serial.write(i);
Serial.write(" : ");
Serial.write(stat_info->bssid[0]);
Serial.write(stat_info->bssid[1]);
Serial.write(stat_info->bssid[2]);
Serial.write(stat_info->bssid[3]);
Serial.write(stat_info->bssid[4]);
Serial.write(stat_info->bssid[5]);
Serial.write("\n");
i++;
stat_info = STAILQ_NEXT(stat_info, next);
}
*/
}

and used this:

bool MomaDHCPInfoReady()
{
unsigned char softap_stations_cnt;
struct station_info *stat_info;
int i=0;

softap_stations_cnt = wifi_softap_get_station_num(); // Count of stations which are connected to ESP8266 soft-AP
stat_info = wifi_softap_get_station_info();
while (stat_info != NULL)
{
stat_info = STAILQ_NEXT(stat_info, next);
i++;
}
return (i==softap_stations_cnt);
}

....
Have Nice Time.
Good By

@thedub2001
Copy link

Hello!
I've written a little sketch which shows the use of the new WiFi events and gives the IP address of freshly SOFT_AP connected devices (tested on ESP8266 v12-F) :

#include <ESP8266WiFi.h>
// include plain C library
extern "C" {
#include "user_interface.h"
}

#define YOUR_WIFI_SSID "******-******"
#define YOUR_WIFI_PASSWD "******-******"

boolean waitingDHCP=false;
char last_mac[18];

// Manage incoming device connection on ESP access point
void onNewStation(WiFiEventSoftAPModeStationConnected sta_info) {
  Serial.println("New Station :");
  sprintf(last_mac,"%02X:%02X:%02X:%02X:%02X:%02X", MAC2STR(sta_info.mac));
  Serial.printf("MAC address : %s\n",last_mac);
  Serial.printf("Id : %d\n", sta_info.aid);
  waitingDHCP=true;
}

void setup() { 

  static WiFiEventHandler e1;

  Serial.begin(115200);
  Serial.println();
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(YOUR_WIFI_SSID, YOUR_WIFI_PASSWD);

  // Event subscription
  e1 = WiFi.onSoftAPModeStationConnected(onNewStation);
}

void loop() {

  if (waitingDHCP) {
    String cb;
    if (deviceIP(last_mac,cb)) {
      Serial.println("Ip address :");
      Serial.println(cb); //do something
    } else {
      Serial.println("Problem during ip address request :");
      Serial.println(cb); //do something else
    }
  }

  delay(2000);
}

boolean deviceIP(char* mac_device, String &cb) {

  struct station_info *station_list = wifi_softap_get_station_info();

  while (station_list != NULL) {
    char station_mac[18] = {0}; sprintf(station_mac, "%02X:%02X:%02X:%02X:%02X:%02X", MAC2STR(station_list->bssid));
    String station_ip = IPAddress((&station_list->ip)->addr).toString();

    if (strcmp(mac_device,station_mac)==0) {
      waitingDHCP=false;
      cb = station_ip;
      return true;
    } 

    station_list = STAILQ_NEXT(station_list, next);
  }

  wifi_softap_free_station_info();
  cb = "DHCP not ready or bad MAC address";
  return false;
}

@devyte
Copy link
Collaborator

devyte commented Oct 17, 2017

Closing as resolved.

@devyte devyte closed this as completed Oct 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants