Skip to content

Add MFi #708

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

Open
wants to merge 16 commits into
base: release_candidate
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/compile-rtk-everywhere.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ jobs:
"SparkFun UM980 Triband RTK GNSS Arduino Library"@1.0.5
"SparkFun LG290P Quadband RTK GNSS Arduino Library"@1.0.8
"SparkFun I2C Expander Arduino Library"@1.0.1
"SparkFun Apple Accessory Arduino Library"@1.0.0
"SparkFun Authentication Coprocessor Arduino Library"@1.0.0
"SparkFun Toolkit"@1.0.6

- name: Patch libmbedtls
run: |
Expand All @@ -111,6 +114,11 @@ jobs:
cd Firmware/RTK_Everywhere/Patch/
cp NetworkEvents.* /home/runner/.arduino15/packages/esp32/hardware/esp32/${{ env.CORE_VERSION }}/libraries/Network/src/

- name: Patch libbt
run: |
cd Firmware/RTK_Everywhere/Patch/
cp libbt.a /home/runner/.arduino15/packages/esp32/tools/esp32-arduino-libs/${{ env.ESP_IDF }}/esp32/lib/libbt.a

- name: Setup Python
uses: actions/setup-python@v4
with:
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/non-release-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ jobs:
"SparkFun UM980 Triband RTK GNSS Arduino Library"@1.0.5
"SparkFun LG290P Quadband RTK GNSS Arduino Library"@1.0.8
"SparkFun I2C Expander Arduino Library"@1.0.1
"SparkFun Apple Accessory Arduino Library"@1.0.0
"SparkFun Authentication Coprocessor Arduino Library"@1.0.0
"SparkFun Toolkit"@1.0.6

- name: Patch libmbedtls
run: |
Expand All @@ -110,6 +113,11 @@ jobs:
cd Firmware/RTK_Everywhere/Patch/
cp NetworkEvents.* /home/runner/.arduino15/packages/esp32/hardware/esp32/${{ env.CORE_VERSION }}/libraries/Network/src/

- name: Patch libbt
run: |
cd Firmware/RTK_Everywhere/Patch/
cp libbt.a /home/runner/.arduino15/packages/esp32/tools/esp32-arduino-libs/${{ env.ESP_IDF }}/esp32/lib/libbt.a

- name: Setup Python
uses: actions/setup-python@v4
with:
Expand Down Expand Up @@ -161,7 +169,7 @@ jobs:
mv RTK_Everywhere.ino.bin ${{ env.ARTIFACT }}

- name: Upload artifact directory to action - avoid double-zip
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT }}
path: Firmware/RTK_Everywhere/build/esp32.esp32.esp32/${{ env.ARTIFACT }}
Expand Down
120 changes: 120 additions & 0 deletions Firmware/RTK_Everywhere/AuthCoPro.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#ifdef COMPILE_AUTHENTICATION

const char *manufacturer = "SparkFun Electronics";
const char *hardwareVersion = "1.0.0";
const char *EAProtocol = "com.sparkfun.rtk";
const char *BTTransportName = "com.sparkfun.bt";
const char *LIComponentName = "com.sparkfun.li";
const char *productPlanUID = "0123456789ABCDEF"; // This comes from the MFi Portal, when you register the product with Apple

extern BTSerialInterface *bluetoothSerialSpp;

void transportConnected(bool *isConnected)
{
*isConnected = bluetoothSerialSpp->connected();
}

void transportDisconnect(bool *disconnected)
{
bluetoothSerialSpp->disconnect();
}

void beginAuthCoPro(TwoWire *i2cBus)
{
if (i2cBus == nullptr)
return; // Return silently if the Co Pro was not detected during beginI2C

appleAccessory = new SparkFunAppleAccessoryDriver;

appleAccessory->usePSRAM(online.psram);

if(!appleAccessory->begin(*i2cBus))
{
systemPrintln("Could not initialize the authentication coprocessor");
return;
}

if (settings.debugNetworkLayer)
appleAccessory->enableDebug(&Serial); // Enable debug prints to Serial

// Pass Identity Information, Protocols and Names into the accessory driver
appleAccessory->setAccessoryName(deviceName);
appleAccessory->setModelIdentifier(platformPrefix);
appleAccessory->setManufacturer(manufacturer);
appleAccessory->setSerialNumber(serialNumber);
appleAccessory->setFirmwareVersion(deviceFirmware);
appleAccessory->setHardwareVersion(hardwareVersion);
appleAccessory->setExternalAccessoryProtocol(EAProtocol);
appleAccessory->setBluetoothTransportName(BTTransportName);
appleAccessory->setBluetoothMacAddress(btMACAddress);
appleAccessory->setLocationInfoComponentName(LIComponentName);
appleAccessory->setProductPlanUID(productPlanUID);

// Pass the pointers for the latest NMEA data into the Accessory driver
latestGPGGA = (char *)rtkMalloc(latestNmeaMaxLen, "AuthCoPro");
latestGPRMC = (char *)rtkMalloc(latestNmeaMaxLen, "AuthCoPro");
latestGPGST = (char *)rtkMalloc(latestNmeaMaxLen, "AuthCoPro");
appleAccessory->setNMEApointers(latestGPGGA, latestGPRMC, latestGPGST);

// Pass the transport connected and disconnect methods into the accessory driver
appleAccessory->setTransportConnectedMethod(&transportConnected);
appleAccessory->setTransportDisconnectMethod(&transportDisconnect);

online.authenticationCoPro = true;
systemPrintln("Authentication coprocessor online");
}

static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) {
if (bda == NULL || str == NULL || size < 18) {
return NULL;
}

uint8_t *p = bda;
snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5]);
return str;
}

void updateAuthCoPro()
{
// bluetoothStart is called during STATE_ROVER_NOT_STARTED and STATE_BASE_NOT_STARTED
// appleAccessory.update() will use &transportConnected to learn if BT SPP is running

if (online.authenticationCoPro) // Coprocessor must be present and online
{
if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
{
appleAccessory->update(); // Update the Accessory driver

// Check for a new device connection
if (bluetoothSerialSpp->aclConnected() == true)
{
// // https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
// std::map<int, std::string> channels = bluetoothSerialSpp->getChannels(bluetoothSerialSpp->aclGetAddress());

// int channel = 0; // Channel 0 for auto-detect
// if (channels.size() > 0)
// channel = channels.begin()->first;

int channel = 1;

char bda_str[18];
bda2str(bluetoothSerialSpp->aclGetAddress(), bda_str, 18);

systemPrintf("Apple Device %s found, connecting on channel %d\r\n",
bda_str, channel);

bluetoothSerialSpp->connect(bluetoothSerialSpp->aclGetAddress(), channel);

if (bluetoothSerialSpp->connected())
{
appleAccessory->startHandshake((Stream *)bluetoothSerialSpp);
}
}

// That's all folks!
// Everything else is handled by the Apple Accessory Library
}
}
}

#endif
13 changes: 13 additions & 0 deletions Firmware/RTK_Everywhere/Begin.ino
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ void identifyBoard()
getMacAddresses(wifiMACAddress, "wifiMACAddress", ESP_MAC_WIFI_STA, true);
getMacAddresses(btMACAddress, "btMACAddress", ESP_MAC_BT, true);
getMacAddresses(ethernetMACAddress, "ethernetMACAddress", ESP_MAC_ETH, true);
snprintf(serialNumber, sizeof(serialNumber), "%02X%02X", btMACAddress[4], btMACAddress[5]);

// First, test for devices that do not have ID resistors
if (productVariant == RTK_UNKNOWN)
Expand Down Expand Up @@ -697,6 +698,7 @@ void beginBoard()
present.fuelgauge_max17048 = true;
present.display_i2c0 = true;
present.i2c0BusSpeed_400 = true; // Run display bus at higher speed
present.i2c1 = true; // Qwiic bus
present.display_type = DISPLAY_128x64;
present.microSd = true;
present.gpioExpander = true;
Expand All @@ -709,6 +711,9 @@ void beginBoard()
pin_I2C0_SDA = 7;
pin_I2C0_SCL = 20;

pin_I2C1_SDA = 13;
pin_I2C1_SCL = 19;

pin_GnssUart_RX = 21;
pin_GnssUart_TX = 22;

Expand Down Expand Up @@ -744,6 +749,8 @@ void beginBoard()

void beginVersion()
{
firmwareVersionGet(deviceFirmware, sizeof(deviceFirmware), false);

char versionString[21];
firmwareVersionGet(versionString, sizeof(versionString), true);

Expand Down Expand Up @@ -1592,6 +1599,12 @@ bool i2cBusInitialization(TwoWire *i2cBus, int sda, int scl, int clockKHz)
break;
}

case 0x10: {
systemPrintf(" 0x%02X - MFI343S00177 Authenication Coprocessor\r\n", addr);
i2cAuthCoPro = i2cBus; // Record the bus
break;
}

case 0x18: {
systemPrintf(" 0x%02X - PCA9557 GPIO Expander with Reset\r\n", addr);
break;
Expand Down
60 changes: 60 additions & 0 deletions Firmware/RTK_Everywhere/Bluetooth.ino
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ bool bluetoothIsConnected()
if (bluetoothSerialBle->connected() == true || bluetoothSerialBleCommands->connected() == true)
return (true);
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
{
if (bluetoothSerialSpp->connected() == true)
return (true);
}
#endif // COMPILE_BT

return (false);
Expand Down Expand Up @@ -145,6 +150,8 @@ int bluetoothRead(uint8_t *buffer, int length)
return bluetoothSerialSpp->readBytes(buffer, length);
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_BLE)
return bluetoothSerialBle->readBytes(buffer, length);
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
return 0; // Nothing to do here. SDP takes care of everything...

return 0;

Expand Down Expand Up @@ -186,6 +193,8 @@ uint8_t bluetoothRead()
return bluetoothSerialSpp->read();
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_BLE)
return bluetoothSerialBle->read();
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
return 0; // Nothing to do here. SDP takes care of everything...

return 0;
#else // COMPILE_BT
Expand Down Expand Up @@ -222,6 +231,8 @@ int bluetoothRxDataAvailable()
return bluetoothSerialSpp->available();
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_BLE)
return bluetoothSerialBle->available();
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
return 0; // Nothing to do here. SDP takes care of everything...

return (0);
#else // COMPILE_BT
Expand Down Expand Up @@ -286,6 +297,8 @@ int bluetoothWrite(const uint8_t *buffer, int length)
return bluetoothSerialBle->write(buffer, length);
return 0;
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
return length; // Nothing to do here. SDP takes care of everything...

return (0);
#else // COMPILE_BT
Expand Down Expand Up @@ -313,6 +326,8 @@ int bluetoothCommandWrite(const uint8_t *buffer, int length)
return bluetoothSerialBleCommands->write(buffer, length);
return 0;
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
return length; // Nothing to do here. SDP takes care of everything...

return (0);
#else // COMPILE_BT
Expand Down Expand Up @@ -345,6 +360,8 @@ int bluetoothWrite(uint8_t value)
{
return bluetoothSerialBle->write(value);
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
return 1; // Nothing to do here. SDP takes care of everything...

return (0);
#else // COMPILE_BT
Expand All @@ -365,6 +382,8 @@ void bluetoothFlush()
bluetoothSerialSpp->flush();
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_BLE)
bluetoothSerialBle->flush();
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
bluetoothSerialSpp->flush(); // Needed? Not sure... TODO
#else // COMPILE_BT
return;
#endif // COMPILE_BT
Expand Down Expand Up @@ -433,6 +452,8 @@ void bluetoothStart()
bluetoothSerialBle = new BTLESerial();
bluetoothSerialBleCommands = new BTLESerial();
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
bluetoothSerialSpp = new BTClassicSerial();

// Not yet implemented
// if (pinBluetoothTaskHandle == nullptr)
Expand Down Expand Up @@ -485,6 +506,31 @@ void bluetoothStart()
BLE_COMMAND_RX_UUID, BLE_COMMAND_TX_UUID); // localName, isMaster, disableBLE, rxBufferSize,
// txBufferSize, serviceID, rxID, txID
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
{
// Support Apple Accessory

bluetoothSerialSpp->enableSSP(false, false); //Enable secure pairing, authenticate without displaying anything

beginSuccess &= bluetoothSerialSpp->begin(
deviceName, true, true, settings.sppRxQueueSize, settings.sppTxQueueSize, 0, 0,
0); // localName, isMaster, disableBLE, rxBufferSize, txBufferSize, serviceID, rxID, txID

if (beginSuccess)
{
//bluetoothSerialSpp.getBtAddress(btMACAddress); // Read the ESP32 BT MAC Address

esp_sdp_init();

esp_bluetooth_sdp_hdr_overlay_t record = {(esp_bluetooth_sdp_types_t)0};
record.type = ESP_SDP_TYPE_RAW;
record.uuid.len = sizeof(UUID_IAP2);
memcpy(record.uuid.uuid.uuid128, UUID_IAP2, sizeof(UUID_IAP2));
record.service_name_length = strlen(sdp_service_name) + 1;
record.service_name = (char *)sdp_service_name;
esp_sdp_create_record((esp_bluetooth_sdp_record_t *)&record);
}
}

if (beginSuccess == false)
{
Expand Down Expand Up @@ -534,13 +580,19 @@ void bluetoothStart()
bluetoothSerialBle->setTimeout(10);
bluetoothSerialBleCommands->setTimeout(10); // Using 10 from BleSerial example
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
{
bluetoothSerialSpp->setTimeout(250); // Needed? Not sure... TODO
}

if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_AND_BLE)
systemPrint("Bluetooth SPP and BLE broadcasting as: ");
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP)
systemPrint("Bluetooth SPP broadcasting as: ");
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_BLE)
systemPrint("Bluetooth Low-Energy broadcasting as: ");
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
systemPrint("Bluetooth SPP (Accessory Mode) broadcasting as: ");

systemPrintln(deviceName);

Expand Down Expand Up @@ -627,6 +679,12 @@ void bluetoothStop()
bluetoothSerialBleCommands->disconnect(); // Drop any clients
bluetoothSerialBleCommands->end(); // Release resources
}
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
{
bluetoothSerialSpp->flush(); // Complete any transfers
bluetoothSerialSpp->disconnect(); // Drop any clients
bluetoothSerialSpp->end(); // Release resources
}

log_d("Bluetooth turned off");

Expand Down Expand Up @@ -692,6 +750,8 @@ void bluetoothTest(bool runTest)
systemPrint("SPP ");
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_BLE)
systemPrint("Low Energy ");
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_SPP_ACCESSORY_MODE)
systemPrint("SPP Accessory Mode ");
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_OFF)
systemPrint("Off ");

Expand Down
11 changes: 11 additions & 0 deletions Firmware/RTK_Everywhere/Developer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,14 @@ void convertGnssTimeToEpoch(uint32_t *epochSecs, uint32_t *epochMicros) {
}

#endif // COMPILE_ZED

//----------------------------------------
// MFi authentication coprocessor
//----------------------------------------

#ifndef COMPILE_AUTHENTICATION

void beginAuthCoPro(TwoWire *i2cBus) {systemPrintln("**MFi Authentication Not Compiled**");}
void updateAuthCoPro() {}

#endif // COMPILE_AUTHENTICATION
Loading