B4R Question Use of ESP8266 WiFi.BSSID in inline code

bdunkleysmith

Active Member
Licensed User
Longtime User
Just like I have used the following inline code incorporating WiFi.mode(WIFI_STA) to turn off the ESP8266 access point:

B4X:
Private Sub AppStart
    Serial1.Initialize(115200)

    RunNative("SetSTA", Null)    'Turn off AP mode

End Sub

#if C
void SetSTA(B4R::Object* o) {
   WiFi.mode(WIFI_STA);
}
#end if


I would like to use WiFi.BSSID or WiFi.BSSIDstr to retrieve the current BSSID so I can confirm which access point I am connected to after using the wifi.Connect3 command.

I have tried the following, but obviously there is a syntax error:

B4X:
Sub Process_Globals

    Private MAC() As Byte

End Sub

Private Sub AppStart
    Serial1.Initialize(115200)

    RunNative("GetMAC", Null)    'Get BSSID of AP connected to

End Sub

#if C
void GetMAC(B4R::Object* o) {
      b4r_main::_mac = WiFi.BSSID;
}
#end if

In what form do I need to declare the MAC variable and use it in the inline code to retrieve WiFi.BSSID (or WiFi.BSSIDstr)?
 

bdunkleysmith

Active Member
Licensed User
Longtime User
Thanks @thetahsk, that's one thread I didn't come across using the search function, but that gets the station MAC address whereas I want the MAC address of the AP to which the station is connected.

Referring to Kolban’s book on the ESP8266, the referenced code uses this function:

WiFi.macAddress (page 181)
Get the station interface MAC address.
uint_t *macAddress(uint8_t *mac)
String macAddress()

whereas I want to use this function:

WiFi.BSSID (page 179)
Retrieve the current BSSID.
uint8_t BSSID()
uint8_t *BSSID(uint8_t networkItem)

to as it says, "Retrieve the current BSSID".

Here is another reference to the use of WiFi.BSSID, but I don't know how that translates to B4R incline code.

So I'll have to modify the code using trial and error unless someone else can point me in the right direction to use the WiFi.BSSID function in the inline code.
 
Last edited:
Upvote 0

thetahsk

Active Member
Licensed User
Longtime User
Thanks @thetahsk, that's one thread I didn't come across using the search function, but that gets the station MAC address whereas I want the MAC address of the AP to which the station is connected.
...

something like this but it's untestet

B4X:
#if C
  #include <ESP8266WiFi.h>
  void getMac(B4R::Object* u) {
  WiFi.BSSID((Byte*)b4r_main::_macarray->data);
  }
#end if
 
Last edited:
Upvote 0

bdunkleysmith

Active Member
Licensed User
Longtime User
Thanks @thetahsk, but unfortunately the suggested code throws a couple of errors:

B4X:
Sub Process_Globals

    Private Macarray(6) As Byte

End Sub

#if C
  #include <ESP8266WiFi.h>
  void getMac(B4R::Object* u) {
  WiFi.BSSID((Byte*)b4r_main::_macarray->data);
  }
#end if

C:\Users\Public\DOCUME~1\Bryon\SCOREB~1\Arduino\Arduino\PI628D~1\Objects\bin\sketch\b4r_main.cpp: In function 'void getMac(B4R::Object*)':
b4r_main.cpp:89:46: error: invalid conversion from 'Byte* {aka unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive]
WiFi.BSSID((Byte*)b4r_main::_macarray->data);
^
In file included from C:\Users\Bryon\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266WiFi\src/ESP8266WiFi.h:36:0,
from C:\Users\Public\DOCUME~1\Bryon\SCOREB~1\Arduino\Arduino\PI628D~1\Objects\bin\sketch\rESP8266WiFi.h:7,
from C:\Users\Public\DOCUME~1\Bryon\SCOREB~1\Arduino\Arduino\PI628D~1\Objects\bin\sketch\B4RDefines.h:29,
from C:\Users\Public\DOCUME~1\Bryon\SCOREB~1\Arduino\Arduino\PI628D~1\Objects\bin\sketch\b4r_main.cpp:1:
C:\Users\Bryon\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266WiFi\src/ESP8266WiFiScan.h:49:19: error: initializing argument 1 of 'uint8_t* ESP8266WiFiScanClass::BSSID(uint8_t)' [-fpermissive]
uint8_t * BSSID(uint8_t networkItem);
^
exit status 1
exit status 1

I don't believe WiFi.BSSID() or the string variant WiFi.BSSIDstr() requires an argument, with this code successfully printing the AP MAC address in the log:

B4X:
#if C
  #include <ESP8266WiFi.h>
  void getMac(B4R::Object* u) {
  Serial.print("Connected AP MAC address is: ");
  Serial.println(WiFi.BSSIDstr());
  }
#end if

Log output:
Connected AP MAC address is: 10:AA:43:A6:3A:AF

But I can't work out the syntax to return the output of WiFi.BSSIDstr() or preferably WiFi.BSSID() to the B4R code.

I tried the following, but as per below an error is thrown:

B4X:
Sub Process_Globals

    Private Macstring() As Byte

End Sub

#if C
  #include <ESP8266WiFi.h>
  void getMac(B4R::Object* u) {
  Serial.print("Connected AP MAC address is: ");
  Serial.println(WiFi.BSSIDstr());
  b4r_main::_macstring = WiFi.BSSIDstr();
  }
#end if

C:\Users\Public\DOCUME~1\Bryon\SCOREB~1\Arduino\Arduino\PI628D~1\Objects\bin\sketch\b4r_main.cpp: In function 'void getMac(B4R::Object*)':
b4r_main.cpp:94:24: error: cannot convert 'String' to 'B4R::Array*' in assignment
b4r_main::_macstring = WiFi.BSSIDstr();
^
Using library LiquidCrystal at version 1.0.7 in folder: C:\Program Files (x86)\Arduino\libraries\LiquidCrystal
Using library ESP8266WiFi at version 1.0 in folder: C:\Users\Bryon\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266WiFi
exit status 1

and also tried the following, but as per below an error is thrown:

B4X:
Sub Process_Globals

    Private Macarray(6) As Byte

End Sub

#if C
  #include <ESP8266WiFi.h>
  void getMac(B4R::Object* u) {
  Serial.print("Connected AP MAC address is: ");
  Serial.println(WiFi.BSSIDstr());
  b4r_main::_macarray = WiFi.BSSID();
  }
#end if

C:\Users\Public\DOCUME~1\Bryon\SCOREB~1\Arduino\Arduino\PI628D~1\Objects\bin\sketch\b4r_main.cpp: In function 'void getMac(B4R::Object*)':
b4r_main.cpp:95:23: error: cannot convert 'uint8_t* {aka unsigned char*}' to 'B4R::Array*' in assignment
b4r_main::_macarray = WiFi.BSSID();
^
Using library LiquidCrystal at version 1.0.7 in folder: C:\Program Files (x86)\Arduino\libraries\LiquidCrystal
Using library ESP8266WiFi at version 1.0 in folder: C:\Users\Bryon\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266WiFi
exit status 1


I'm well out of my depth with this, but it would be of great value I believe because it would enable confirmation that the ESP8266 has connected to the targetted access point when using the wifi.Connect3 command and so I hope someone can point me in the right direction to be able to return the result of WiFi.BSSID() to B4R from the inline code.
 
Upvote 0

bdunkleysmith

Active Member
Licensed User
Longtime User
Well after getting type mismatch errors for the many variants of code I've tried, this achieves what I've been after, but I'm sure the BSSID array must be able to be returned as a whole rather than in bytes as I have had to do to make it work.

B4X:
Sub Process_Globals

    Private MacArray(6) As Byte
    Private M1,M2,M3,M4,M5,M6 As Byte

End Sub

Sub ConnectToNetwork

        RunNative("getMac", Null)
        bc.ArrayCopy(Array As Byte(M1,M2,M3,M4,M5,M6),MacArray)       
        Log("MAC address from AP: ", bc.HexFromBytes(MacArray))

End Sub

#if C
  #include <ESP8266WiFi.h>
    uint8_t* MACAP_array;
    void getMac(B4R::Object* u) {
    Serial.print("Connected AP MAC address is: ");
    Serial.println(WiFi.BSSIDstr());
    MACAP_array = WiFi.BSSID();
    b4r_main::_m1 = MACAP_array[0];
    b4r_main::_m2 = MACAP_array[1];
    b4r_main::_m3 = MACAP_array[2];
    b4r_main::_m4 = MACAP_array[3];
    b4r_main::_m5 = MACAP_array[4];
    b4r_main::_m6 = MACAP_array[5];
  }
#end if

The log output is:

MAC address string from AP: 10AA43A63AAF

which is as I expected by way of independent examination of my router (access point).

It seems my problem in returning the data as a whole is that I cannot declare an array in B4R to match the output of WiFi.BSSID() which I can handle in the inline code with either uint8_t* MACAP_array or Byte* MACAP_array.
 
Upvote 0

bdunkleysmith

Active Member
Licensed User
Longtime User
So my final inline code was:

B4X:
Sub Process_Globals

    Private MacArray(6) As Byte

End Sub

Sub ConnectToNetwork

        RunNative("getMac", Null) 
        Log("MAC address from AP: ", bc.HexFromBytes(MacArray))

End Sub

#if C
  #include <ESP8266WiFi.h>
    void getMac(B4R::Object* u) {
    b4r_main::_macarray->data = WiFi.BSSID();
  }
#end if

However I thought retrieval of the BSSID of the access point to which the ESP8266 is connected would be a useful addition to the ESP8266extras library and so you can find that updated library here: ESP8266extras Library.
 
Last edited:
Upvote 0

thetahsk

Active Member
Licensed User
Longtime User
using the internal structures you can also check this.

B4X:
void GetMacMac(B4R::Object* u)  {
        byte* mac=WiFi.BSSID();
        for (byte i = 0; i < 6; i++) {
         ((byte*)b4r_main::_macarray->data)[i] =mac[i];
        }
 
Last edited:
Upvote 0

ivan.tellez

Active Member
Licensed User
Longtime User
I really dont know C, but, I copy and paste some things in the B4RESP8266extras Lib and is working. For the AP, you can use something like the GetMacAddress3 to parse the byte array, or use the BSSIDstr funtion.

B4X:
B4RString* B4RESP8266extras::StringToB4R(String* o) {
        PrintToMemory pm;
        B4RString* s = B4RString::PrintableToString(NULL);
        pm.print(*o);
        StackMemory::buffer[StackMemory::cp++] = 0;
        return s;
    }


    B4RString* B4RESP8266extras::GetMacAddress2() {
        String s = WiFi.macAddress();
        return StringToB4R(&s);
    }

   
    B4RString* B4RESP8266extras::GetMacAddress3() {
       
        byte mac[6];

        WiFi.macAddress(mac);
        String cMac = "";
        for (int i = 0; i < 6; ++i) {
        if (mac[i]<0x10) {cMac += "0";}
        cMac += String(mac[i],HEX);
        if(i<5)
        cMac += ""; // put : or - if you want byte delimiters
        }
        cMac.toUpperCase();
       
        return StringToB4R(&cMac);
    }
   
    B4RString* B4RESP8266extras::GetBSSID() {
        String s = WiFi.BSSIDstr();
        return StringToB4R(&s);
    }
 
Last edited:
Upvote 0
Top