Decoding HC-05 MAC address
This commit is contained in:
parent
dfa60eb491
commit
a7348fdbf5
|
@ -159,6 +159,7 @@ long lastTemperatureTime; // used to moderate DS18B20 access
|
||||||
int DS18B20holdoff = 2;
|
int DS18B20holdoff = 2;
|
||||||
|
|
||||||
int BoardRevision = 0;
|
int BoardRevision = 0;
|
||||||
|
bool bTestBTModule = false;
|
||||||
|
|
||||||
unsigned long lastAnimationTime; // used to sequence updates to LCD for animation
|
unsigned long lastAnimationTime; // used to sequence updates to LCD for animation
|
||||||
|
|
||||||
|
@ -1149,6 +1150,11 @@ void checkDebugCommands()
|
||||||
|
|
||||||
char rxVal = DebugPort.read();
|
char rxVal = DebugPort.read();
|
||||||
|
|
||||||
|
if(bTestBTModule) {
|
||||||
|
bTestBTModule = Bluetooth.test(rxVal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rxVal = toLowerCase(rxVal);
|
rxVal = toLowerCase(rxVal);
|
||||||
|
|
||||||
#ifdef PROTOCOL_INVESTIGATION
|
#ifdef PROTOCOL_INVESTIGATION
|
||||||
|
@ -1251,6 +1257,10 @@ void checkDebugCommands()
|
||||||
else if(rxVal == ('h' & 0x1f)) { // CTRL-H hourmeter reset
|
else if(rxVal == ('h' & 0x1f)) { // CTRL-H hourmeter reset
|
||||||
pHourMeter->resetHard();
|
pHourMeter->resetHard();
|
||||||
}
|
}
|
||||||
|
else if(rxVal == ('b' & 0x1f)) { // CTRL-B Tst Mdoe: bluetooth module route
|
||||||
|
bTestBTModule = !bTestBTModule;
|
||||||
|
Bluetooth.test(bTestBTModule ? 0xff : 0x00); // special enter or leave BT test commands
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef PROTOCOL_INVESTIGATION
|
#ifdef PROTOCOL_INVESTIGATION
|
||||||
if(bSendVal) {
|
if(bSendVal) {
|
||||||
|
|
|
@ -45,6 +45,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
virtual bool isConnected() { return false; };
|
virtual bool isConnected() { return false; };
|
||||||
|
virtual const char* getMAC() const { return "unknown"; };
|
||||||
|
virtual bool test(char) { return false; }; // returns true whilst test mode is active
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CBluetoothAbstract& getBluetoothClient();
|
extern CBluetoothAbstract& getBluetoothClient();
|
||||||
|
|
|
@ -40,6 +40,8 @@ CBluetoothHC05::CBluetoothHC05(int keyPin, int sensePin)
|
||||||
// attach to the SENSE line from the HC-05 module
|
// attach to the SENSE line from the HC-05 module
|
||||||
// this line goes high when a BT client is connected :-)
|
// this line goes high when a BT client is connected :-)
|
||||||
pinMode(_sensePin, INPUT);
|
pinMode(_sensePin, INPUT);
|
||||||
|
_bTest = false;
|
||||||
|
strcpy(_MAC, "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,6 +129,17 @@ CBluetoothHC05::begin()
|
||||||
else {
|
else {
|
||||||
DebugPort.println("OK");
|
DebugPort.println("OK");
|
||||||
}
|
}
|
||||||
|
DebugPort.print(" Getting MAC address...");
|
||||||
|
int len = 32;
|
||||||
|
char response[32];
|
||||||
|
if(!ATResponse("AT+ADDR?\r\n", "+ADDR:", response, len)) {
|
||||||
|
DebugPort.println("FAILED");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DebugPort.println("OK");
|
||||||
|
decodeMACresponse(response, len);
|
||||||
|
DebugPort.print(" "); DebugPort.println(_MAC);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
DebugPort.print(" Lowering power consumption...");
|
DebugPort.print(" Lowering power consumption...");
|
||||||
if(!ATCommand("AT+SNIFF=40,20,1,8\r\n")) {
|
if(!ATCommand("AT+SNIFF=40,20,1,8\r\n")) {
|
||||||
|
@ -165,9 +178,14 @@ CBluetoothHC05::check()
|
||||||
// check for data coming back over Bluetooth
|
// check for data coming back over Bluetooth
|
||||||
if(HC05_SerialPort.available()) { // serial rx data is available
|
if(HC05_SerialPort.available()) { // serial rx data is available
|
||||||
char rxVal = HC05_SerialPort.read();
|
char rxVal = HC05_SerialPort.read();
|
||||||
|
if(_bTest) {
|
||||||
|
DebugPort.print(rxVal);
|
||||||
|
}
|
||||||
|
else {
|
||||||
collectRxData(rxVal);
|
collectRxData(rxVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CBluetoothHC05::isConnected()
|
CBluetoothHC05::isConnected()
|
||||||
|
@ -178,7 +196,7 @@ CBluetoothHC05::isConnected()
|
||||||
void
|
void
|
||||||
CBluetoothHC05::send(const char* Str)
|
CBluetoothHC05::send(const char* Str)
|
||||||
{
|
{
|
||||||
if(isConnected()) {
|
if(isConnected() && !_bTest) {
|
||||||
HC05_SerialPort.print(Str);
|
HC05_SerialPort.print(Str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -197,14 +215,35 @@ CBluetoothHC05::openSerial(int baudrate)
|
||||||
bool
|
bool
|
||||||
CBluetoothHC05::ATCommand(const char* cmd)
|
CBluetoothHC05::ATCommand(const char* cmd)
|
||||||
{
|
{
|
||||||
|
if(!_bTest) {
|
||||||
flush(); // ensure response is for *this* command!
|
flush(); // ensure response is for *this* command!
|
||||||
HC05_SerialPort.print(cmd);
|
HC05_SerialPort.print(cmd);
|
||||||
char RxBuffer[16];
|
char RxBuffer[16];
|
||||||
memset(RxBuffer, 0, 16);
|
memset(RxBuffer, 0, 16);
|
||||||
int read = HC05_SerialPort.readBytesUntil('\n', RxBuffer, 16); // \n is not included in returned string!
|
int read = HC05_SerialPort.readBytesUntil('\n', RxBuffer, 32); // \n is not included in returned string!
|
||||||
if((read == 3) && (0 == strcmp(RxBuffer, "OK\r")) ) {
|
if((read == 3) && (0 == strcmp(RxBuffer, "OK\r")) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected function, to perform Hayes commands with HC-05
|
||||||
|
bool
|
||||||
|
CBluetoothHC05::ATResponse(const char* cmd, const char* respHdr, char* response, int& len)
|
||||||
|
{
|
||||||
|
if(!_bTest) {
|
||||||
|
flush(); // ensure response is for *this* command!
|
||||||
|
HC05_SerialPort.print(cmd);
|
||||||
|
memset(response, 0, len);
|
||||||
|
int read = HC05_SerialPort.readBytesUntil('\n', response, len); // \n is not included in returned string!
|
||||||
|
// DebugPort.print(response); DebugPort.print(" ? "); DebugPort.println(respHdr);
|
||||||
|
if(0 == strncmp(response, respHdr, strlen(respHdr))) {
|
||||||
|
len = read;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,3 +266,109 @@ CBluetoothHC05::flush()
|
||||||
while(HC05_SerialPort.available())
|
while(HC05_SerialPort.available())
|
||||||
HC05_SerialPort.read();
|
HC05_SerialPort.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CBluetoothHC05::test(char val)
|
||||||
|
{
|
||||||
|
if(!val) {
|
||||||
|
_bTest = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_bTest = true;
|
||||||
|
if(val == 0xff) { // special entry command
|
||||||
|
DebugPort.println("ENTERING Test Bluetooth mode");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(val == ('b' & 0x1f)) { // CTRL-B - leave bluetooth test mode
|
||||||
|
DebugPort.println("LEAVING Test Bluetooth mode");
|
||||||
|
digitalWrite(_keyPin, LOW); // request HC-05 module to enter command mode
|
||||||
|
openSerial(9600);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(val == ('c' & 0x1f)) { // CTRL-C - data mode
|
||||||
|
DebugPort.println("Test Bluetooth COMMAND mode");
|
||||||
|
digitalWrite(_keyPin, HIGH); // request HC-05 module to enter command mode
|
||||||
|
openSerial(9600);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(val == ('d' & 0x1f)) { // CTRL-D - data mode
|
||||||
|
DebugPort.println("Test Bluetooth DATA mode");
|
||||||
|
digitalWrite(_keyPin, LOW); // request HC-05 module to enter command mode
|
||||||
|
openSerial(9600);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
HC05_SerialPort.write(val);
|
||||||
|
}
|
||||||
|
return _bTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CBluetoothHC05::decodeMACresponse(char* pResponse, int len)
|
||||||
|
{
|
||||||
|
// decode ADDR response from a HC-05
|
||||||
|
// NOTE:
|
||||||
|
// the full complement of digits may not be sent!
|
||||||
|
// leading zeroes are suppressed, digits are grouped by colons.
|
||||||
|
//
|
||||||
|
// eg, HC-05 response: +ADDR:18:e5:449a7
|
||||||
|
//
|
||||||
|
// 00:18:e5:04:49:a7 is how we'd normally expect to present it!
|
||||||
|
|
||||||
|
char stage[16];
|
||||||
|
char MACdecode[16];
|
||||||
|
memset(MACdecode, 0, 16);
|
||||||
|
char* pDecode = MACdecode; // extract and build digits into MACdecode using this ptr
|
||||||
|
char* pStage = stage;
|
||||||
|
int hexCount = 0;
|
||||||
|
|
||||||
|
for (int i = 6; i <= len; i++) { // skip initial response header
|
||||||
|
if (pResponse[i] == ':' || i == len) {
|
||||||
|
if (hexCount & 0x01) { // leading zeros are suppressed in response, replace them!
|
||||||
|
*pDecode++ = '0';
|
||||||
|
}
|
||||||
|
pStage = stage;
|
||||||
|
while (hexCount) {
|
||||||
|
*pDecode++ = *pStage++;
|
||||||
|
hexCount--;
|
||||||
|
}
|
||||||
|
pStage = stage;
|
||||||
|
}
|
||||||
|
if (isxdigit(pResponse[i])) {
|
||||||
|
*pStage++ = pResponse[i];;
|
||||||
|
hexCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ideally 12 characters in MAC digit sequence..
|
||||||
|
int deficit = 12 - strlen(MACdecode);
|
||||||
|
if (deficit > 0) {
|
||||||
|
// not enough, shuffle to rear
|
||||||
|
char* pSrc = &MACdecode[strlen(MACdecode) - 1];
|
||||||
|
char* pDest = &MACdecode[11];
|
||||||
|
int loop = strlen(MACdecode);
|
||||||
|
// move from back forward
|
||||||
|
while (loop--) {
|
||||||
|
*pDest-- = *pSrc--;
|
||||||
|
}
|
||||||
|
// now insert 0's at start
|
||||||
|
pDest = MACdecode;
|
||||||
|
while (deficit--) {
|
||||||
|
*pDest++ = '0';
|
||||||
|
}
|
||||||
|
deficit = 0;
|
||||||
|
}
|
||||||
|
if (deficit < 0) { // more than 12 digits! - WHOA!
|
||||||
|
strcpy(_MAC, "unknown");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// build final colon separated MAC address
|
||||||
|
char* pDest = _MAC;
|
||||||
|
char* pSrc = MACdecode;
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
*pDest++ = *pSrc++;
|
||||||
|
*pDest++ = *pSrc++;
|
||||||
|
*pDest++ = ':';
|
||||||
|
}
|
||||||
|
*--pDest = 0; // step back and replace last colon with the null terminator!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,16 +38,22 @@ static HardwareSerial& HC05_SerialPort(Serial2);
|
||||||
|
|
||||||
class CBluetoothHC05 : public CBluetoothAbstract {
|
class CBluetoothHC05 : public CBluetoothAbstract {
|
||||||
bool ATCommand(const char* str);
|
bool ATCommand(const char* str);
|
||||||
|
bool ATResponse(const char* str, const char* respHdr, char* response, int& len);
|
||||||
int _sensePin, _keyPin;
|
int _sensePin, _keyPin;
|
||||||
CModerator foldbackModerator;
|
CModerator foldbackModerator;
|
||||||
|
char _MAC[32];
|
||||||
|
bool _bTest;
|
||||||
public:
|
public:
|
||||||
CBluetoothHC05(int keyPin, int sensePin);
|
CBluetoothHC05(int keyPin, int sensePin);
|
||||||
void begin();
|
void begin();
|
||||||
void send(const char* Str);
|
void send(const char* Str);
|
||||||
void check();
|
void check();
|
||||||
virtual bool isConnected();
|
virtual bool isConnected();
|
||||||
|
const char* getMAC() const { return _MAC; };
|
||||||
|
virtual bool test(char); // returns true whilst test mode is active
|
||||||
protected:
|
protected:
|
||||||
virtual void openSerial(int baudrate);
|
virtual void openSerial(int baudrate);
|
||||||
virtual void foldbackDesiredTemp();
|
virtual void foldbackDesiredTemp();
|
||||||
void flush();
|
void flush();
|
||||||
|
void decodeMACresponse(char* pResponse, int len);
|
||||||
};
|
};
|
|
@ -507,6 +507,7 @@ bool makeJSONStringIP(CModerator& moderator, char* opStr, int len)
|
||||||
bSend |= moderator.addJson("IP_STAMAC", getWifiSTAMACStr(), root);
|
bSend |= moderator.addJson("IP_STAMAC", getWifiSTAMACStr(), root);
|
||||||
bSend |= moderator.addJson("IP_STASSID", getSSID().c_str(), root);
|
bSend |= moderator.addJson("IP_STASSID", getSSID().c_str(), root);
|
||||||
bSend |= moderator.addJson("IP_OTA", NVstore.getUserSettings().enableOTA, root);
|
bSend |= moderator.addJson("IP_OTA", NVstore.getUserSettings().enableOTA, root);
|
||||||
|
bSend |= moderator.addJson("BT_MAC", getBluetoothClient().getMAC(), root);
|
||||||
|
|
||||||
if(bSend) {
|
if(bSend) {
|
||||||
root.printTo(opStr, len);
|
root.printTo(opStr, len);
|
||||||
|
|
Loading…
Reference in a new issue