Need to get SSID from NVMEM[SOLVED]

Hi All,

I am trying to display the wifi signal strength ie bars with or without a wifi connection for my configured SSID. I have been able to modify WiFi.RSSI() no problem to get all the local SSIDs and strengths I just need to retrieve the single SSID I have saved from nvmem. If I use WiFi.SSID() I can only see the SSID if a connection has been obtained. I am assuming I need to use nvmem_read()

Can anyone point me in the right direction?

Any help would be very appreciated. Thanks.

Hi @HardWater

You are not going to be able to use WiFi.RSSI() directly but you can modify that code (enclosed below) to meet your needs. You might also want to read the TI CC3000 documentation on wlan_ioctl_get_scan_results.

There is an outer loop with a timeout value and an inner loop that goes through the 16 possible RSSI values, looking for the one that has an SSID that matches the current SSID. The data is returned by the TI CC3000 in an array structure (wlan_scan_results_table) with a new value returned every time you call wlan_ioctl_get_scan_results and the return value is not zero, which means you hit the end.

The SSID is in the return value in array locations 12 to 42 (max) so you can see the code copies wlan_scan_results_table into wlan_scan_results_ssid. If the SSID matches ip_config.uaSSID, then that is our current network. This is the part you need to change to just use or copy all the SSIDs and RSSIs.

int8_t WiFiClass::RSSI()
{
	_functionStart = millis();
	_returnValue = 0;
	while ((millis() - _functionStart) < 1000)
	{
		_loopCount = 0;
		while (_loopCount++ < 16)
		{
			unsigned char wlan_scan_results_table[50];
			char wlan_scan_results_ssid[32];
			if(wlan_ioctl_get_scan_results(0, wlan_scan_results_table) != 0) return(1);
			for (int i = 12; i <= 43; i++)
			{
				int arrayPos = i - 12;
				wlan_scan_results_ssid[arrayPos] = wlan_scan_results_table[i];
			}
                       // modify here to test for your network SSID string
			if (*wlan_scan_results_ssid == *ip_config.uaSSID) _returnValue = ((wlan_scan_results_table[8] >> 1) - 127);
			if (wlan_scan_results_table[0] == 0) break;
		}
		if (_returnValue != 0) return(_returnValue);
	}
	return(2);
}
1 Like

@HardWater we watch the forum almost every other second so reducing the bump and pinging might be better…

I recall the deep update copying wifi credentials from the cc3000 and applying it back after the update.

@bko got to it already :slight_smile:

Hi @bko Thanks for the reply Yes I have already played with the inner workings of WiFi.RSSI() it works great the problem I have is I only want to know the strength of the 1 SSID that I am configured for, I will only ever have 1 set of credentials with my design. So I need to extract from NVMEM that 1 SSID to be used for comparison when stepping through the scan table so I can return that result. And I need to get that ssid weather or not I have established or can establish a connection. The point being I really need to be able to show that the signal strength is below an acceptable level when I cannot connect.

Hi @HardWater

So I did put a comment in the code where the comparison of the SSIDs happens. You need to change that.

Have you seen the doc on EEPROM?

http://docs.particle.io/photon/firmware/#other-functions-eeprom

You will need to write your SSID in the emulated EEPROM with a stand-alone program and the reprogram your core with the SSID reading program.

Ok, I think I just realized what is confusing here: The SSIDs and passwords written into the TI CC3000 are write-only for security reasons. You cannot read that data back out of the WiFi chip, but there was some code put in to save them away and read them back out. It is not documented, but you can see the code here:

https://github.com/spark/firmware/blob/master/src/spark_wlan.cpp

2 Likes

Thank you so much @bko

With the following I was able to capture the ssid and save it to memory right after is came in via smart_config so I can read it later on for my wifi strength meter.

void eepromWriteSSID(char * buffer,unsigned int chCnt)
   {
   int i = -1;
   do
      {
      i++;
      EEPROM.write(i,(char) buffer[i]);
      } while (i < chCnt);
   EEPROM.write(i,0);
   }

void saveSSID()
   {
   unsigned int ssidLen;
   unsigned char *ssidPtr;
   extern unsigned char profileArray[];

   // read the received data from fileID #13 and parse it according to the followings:
   // 1) SSID LEN - not encrypted
   // 2) SSID - not encrypted
   // 3) KEY LEN - not encrypted. always 32 bytes long
   // 4) Security type - not encrypted
   // 5) KEY - encrypted together with true key length as the first byte in KEY
   //       to elaborate, there are two corner cases:
   //              1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length
   //              2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31
   if(SMART_CONFIG_PROFILE_SIZE != nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray))
      {
      return;
      }

   ssidPtr = &profileArray[1];

   ssidLen = profileArray[0];
   eepromWriteSSID((char *)ssidPtr,ssidLen);
   }