in WiFiConfigurationViaNfc/src/M24SR/M24SR.c [413:582]
static int M24SR_ProcessNDEFMessage(uint8_t* buffer, uint16_t length, struct M24SR_WifiConfig *wifiConfig)
{
buffer += 2; // Bytes 0+1 = length of full Message.
unsigned int idLengthOffset = 0;
struct NDEFMSGHDR* pHdr = (struct NDEFMSGHDR*)buffer;
// pull out bit fields
bool mb = (pHdr->tnf & 0x80) != 0;
bool me = (pHdr->tnf & 0x40) != 0;
bool cf = (pHdr->tnf & 0x20) != 0;
bool sr = (pHdr->tnf & 0x10) != 0;
bool il = (pHdr->tnf & 0x8) != 0;
uint8_t tnf = (pHdr->tnf & 0x7);
if (mb && me) // only one record.
{
Log_Debug("One NDEF Record\n");
}
else
{
Log_Debug("Error: Only single NDEF record supported.\n");
return -1;
}
if (sr)
{
Log_Debug("Short Record <= 255 bytes\n");
}
else
{
Log_Debug("ERROR: Only short NDEF records are supported\n");
return -1;
}
if (il)
{
Log_Debug("Record contains ID Length\n");
idLengthOffset = 1;
}
if (tnf & 0x02)
{
Log_Debug("Record contains MIME type\n");
}
else
{
Log_Debug("ERROR: Only MIME type is supported\n");
return -1;
}
if (!cf)
{
Log_Debug("Record is not chunked\n");
}
else
{
Log_Debug("ERROR: Chunked record not supported\n");
return -1;
}
Log_Debug("Type Length %d (0x%02x)\n", pHdr->typeLength, pHdr->typeLength);
Log_Debug("Payload Length %d (0x%02x)\n", pHdr->payloadLength, pHdr->payloadLength);
Log_Debug("ID Length %d (0x%02x)\n", idLengthOffset, idLengthOffset);
if (strncmp("application/vnd.wfa.wsc", &buffer[sizeof(NDEFMSGHDR) + idLengthOffset], pHdr->typeLength) == 0)
{
Log_Debug("WiFi MIME type confirmed\n");
}
else
{
Log_Debug("ERROR: Not WiFi NDEF Record\n");
return -1;
}
#ifdef ENABLE_VERBOSE_DEBUG_OUTPUT
Log_Debug("NDEF Message Payload:\n");
DumpBuffer(&buffer[sizeof(NDEFMSGHDR) + pHdr->typeLength], pHdr->payloadLength);
#endif
// Now walk the NDEF Record tags.
// three are needed...
// 0x1045 SSID
// 0x1027 Network Key
// 0x1003 Authentication Type(needs to map to Azure Sphere types)
uint8_t* ptr = &buffer[sizeof(NDEFMSGHDR) + idLengthOffset + pHdr->typeLength + 1]; // point to first record.
size_t bufferOffset = 0; // offset into the NDEFMSGHDR buffer.
uint16_t content16t = 0;
bool haveSSID = false;
bool haveAUTHTYPE = false;
bool haveNETWORKKEY = false;
wifiConfig->wifiConfigSecurityType = WifiConfig_Security_Open;
memset(wifiConfig->networkKeyString, 0x00, 32);
memset(wifiConfig->ssidString, 0x00, 32);
struct NDEFRECORD ndefRecord;
while (bufferOffset <= (size_t)pHdr->payloadLength)
{
struct NDEFRECORD* pRecord = (struct NDEFRECORD*)&ptr[bufferOffset];
SwapNDEFRecordItems(pRecord, &ndefRecord);
bufferOffset += sizeof(NDEFRECORD); // skip past type and length.
Log_Debug("recordType: 0x%02x\n", ndefRecord.recordType);
// Records are defined as 2 byte ID, 2 byte size, then content
switch (ndefRecord.recordType) {
case WIFI_CREDENTIAL: // skip
Log_Debug("WIFI_CREDENTIAL\n");
break;
case WIFI_NETWORKINDEX: // skip size and content
Log_Debug("WIFI_NETWORKINDEX\n");
bufferOffset += ndefRecord.recordLength;
break;
case WIFI_SSID:
Log_Debug("SSID\n");
if (ndefRecord.recordLength > 0)
{
haveSSID = true;
memcpy(wifiConfig->ssidString, &ptr[bufferOffset], ndefRecord.recordLength);
bufferOffset += ndefRecord.recordLength;
}
break;
case WIFI_AUTHTYPE: // two bytes
Log_Debug("AUTHTYPE\n");
content16t= (uint16_t)((ptr[bufferOffset] << 8) + (ptr[bufferOffset + 1] & 0x00ff));
bufferOffset += 2;
wifiConfig->wifiConfigSecurityType=MapAuthType(content16t);
Log_Debug("AuthType: 0x%02x\n", wifiConfig->wifiConfigSecurityType);
haveAUTHTYPE = true;
break;
case WIFI_ENCRYPTIONTYPE:
Log_Debug("WIFI_ENCRYPTIONTYPE\n");
bufferOffset += ndefRecord.recordLength;
break;
case WIFI_NETWORKKEY:
Log_Debug("WIFI_NETWORKKEY\n");
if (ndefRecord.recordLength > 0)
{
haveNETWORKKEY = true;
memcpy(wifiConfig->networkKeyString, &ptr[bufferOffset], ndefRecord.recordLength);
bufferOffset += ndefRecord.recordLength;
}
break;
case WIFI_MACADDRESS:
bufferOffset += ndefRecord.recordLength;
break;
default:
break;
}
}
if (!haveSSID || !haveAUTHTYPE || !haveNETWORKKEY)
{
Log_Debug("Error: missing ssid, auth type, or network key\n");
return -1;
}
Log_Debug("SSID : %s\n",wifiConfig->ssidString);
Log_Debug("Network Key: %s\n", wifiConfig->networkKeyString);
return 0;
}