Skip to content

Commit 2026f55

Browse files
authored
Merge pull request #2508 from particle-iot/sc-107991/p2-ble-empty-address
RTL872x: Implement APIs to set/get BLE address
2 parents 7f578c5 + 8ff71fc commit 2026f55

File tree

9 files changed

+207
-37
lines changed

9 files changed

+207
-37
lines changed

hal/inc/deviceid_hal.h

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ int hal_get_device_hw_model(uint32_t* model, uint32_t* variant, void* reserved);
9898

9999
#include "deviceid_hal_compat.h"
100100

101+
#include "deviceid_hal_impl.h"
102+
101103
#ifdef __cplusplus
102104
}
103105
#endif

hal/src/gcc/deviceid_hal_impl.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2022 Particle Industries, Inc. All rights reserved.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation, either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
// placeholder

hal/src/nRF52840/deviceid_hal_impl.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2022 Particle Industries, Inc. All rights reserved.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation, either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
// placeholder

hal/src/newhal/deviceid_hal_impl.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2022 Particle Industries, Inc. All rights reserved.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation, either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
// placeholder

hal/src/rtl872x/ble_hal.cpp

+74-11
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,17 @@
1515
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
#undef LOG_COMPILE_TIME_LEVEL
18+
#define LOG_COMPILE_TIME_LEVEL LOG_LEVEL_TRACE
1919
#include "logging.h"
2020
LOG_SOURCE_CATEGORY("hal.ble");
2121

2222
#include "ble_hal.h"
2323

2424
#if HAL_PLATFORM_BLE
2525

26-
#ifdef __cplusplus
2726
extern "C" {
28-
#endif
2927
#include "rtl8721d.h"
30-
#ifdef __cplusplus
31-
} // extern "C"
32-
#endif
33-
34-
extern "C" {
28+
#include "rtl8721d_efuse.h"
3529
#include "rtk_coex.h"
3630
}
3731

@@ -43,6 +37,7 @@ extern "C" {
4337
#include <gap_adv.h>
4438
#include <gap_scan.h>
4539
#include <gap_bond_le.h>
40+
#include <gap_le.h>
4641
#include <gap_conn_le.h>
4742
#include <profile_server.h>
4843
#include <gatt_builtin_services.h>
@@ -57,7 +52,6 @@ extern "C" {
5752
#include <wifi/wifi_conf.h>
5853
#include "rtk_coex.h"
5954
#include "ftl_int.h"
60-
#include "rtl8721d.h"
6155
#include "bt_intf.h"
6256

6357
//FIXME
@@ -164,6 +158,19 @@ bool addressEqual(const hal_ble_addr_t& srcAddr, const hal_ble_addr_t& destAddr)
164158
return (srcAddr.addr_type == destAddr.addr_type && !memcmp(srcAddr.addr, destAddr.addr, BLE_SIG_ADDR_LEN));
165159
}
166160

161+
hal_ble_addr_t chipDefaultPublicAddress() {
162+
hal_ble_addr_t localAddr = {};
163+
uint8_t mac[BLE_SIG_ADDR_LEN] = {};
164+
if (hal_get_mac_address(HAL_DEVICE_MAC_BLE, mac, BLE_SIG_ADDR_LEN, nullptr) == BLE_SIG_ADDR_LEN) {
165+
// As per BLE spec, we store BLE data in little-endian
166+
for (uint8_t i = 0, j = BLE_SIG_ADDR_LEN - 1; i < BLE_SIG_ADDR_LEN; i++, j--) {
167+
localAddr.addr[i] = mac[j];
168+
}
169+
localAddr.addr_type = BLE_SIG_ADDR_TYPE_PUBLIC;
170+
}
171+
return localAddr;
172+
}
173+
167174
} //anonymous namespace
168175

169176

@@ -329,6 +336,8 @@ class BleGap {
329336
int setAppearance(uint16_t appearance) const;
330337
int setDeviceName(const char* deviceName, size_t len);
331338
int getDeviceName(char* deviceName, size_t len) const;
339+
int setDeviceAddress(const hal_ble_addr_t* address);
340+
int getDeviceAddress(hal_ble_addr_t* address) const;
332341

333342
int setAdvertisingParameters(const hal_ble_adv_params_t* params);
334343
int getAdvertisingParameters(hal_ble_adv_params_t* params) const;
@@ -391,6 +400,7 @@ class BleGap {
391400
: initialized_(false),
392401
btStackStarted_(false),
393402
state_{},
403+
addr_{},
394404
advParams_{},
395405
advTimeoutTimer_(nullptr),
396406
isScanning_(false),
@@ -483,6 +493,7 @@ class BleGap {
483493
bool initialized_;
484494
bool btStackStarted_;
485495
volatile RtlGapDevState state_; /**< This should be atomically r/w as the struct is <= uint32_t */
496+
hal_ble_addr_t addr_;
486497
hal_ble_adv_params_t advParams_;
487498
os_timer_t advTimeoutTimer_; /**< Timer for advertising timeout. */
488499
volatile bool isScanning_; /**< If it is scanning or not. */
@@ -793,6 +804,14 @@ int BleGap::init() {
793804
CHECK(setDeviceName(devName_, devNameLen_));
794805
CHECK(setAdvertisingParameters(&advParams_));
795806
CHECK(setScanParams(&scanParams_));
807+
808+
constexpr uint8_t zeros[BLE_SIG_ADDR_LEN] = {0,0,0,0,0,0};
809+
if (!memcmp(addr_.addr, zeros, BLE_SIG_ADDR_LEN)) {
810+
CHECK(setDeviceAddress(nullptr));
811+
} else {
812+
CHECK(setDeviceAddress(&addr_));
813+
}
814+
796815
/* register gap message callback */
797816
le_register_app_cb(gapEventCallback);
798817

@@ -910,6 +929,48 @@ int BleGap::getDeviceName(char* deviceName, size_t len) const {
910929
return SYSTEM_ERROR_NONE;
911930
}
912931

932+
int BleGap::setDeviceAddress(const hal_ble_addr_t* address) {
933+
CHECK_FALSE(isAdvertising(), SYSTEM_ERROR_INVALID_STATE);
934+
CHECK_FALSE(scanning(), SYSTEM_ERROR_INVALID_STATE);
935+
// RTL872x doesn't support changing the the public address.
936+
// But to be compatible with existing BLE platforms, it should accept nulllptr.
937+
if (!address) {
938+
addr_ = chipDefaultPublicAddress();
939+
return SYSTEM_ERROR_NONE;
940+
}
941+
if (address->addr_type != BLE_SIG_ADDR_TYPE_RANDOM_STATIC) {
942+
return SYSTEM_ERROR_INVALID_ARGUMENT;
943+
}
944+
if ((address->addr[5] & 0xC0) != 0xC0) {
945+
// For random static address, the two most significant bits of the address shall be equal to 1.
946+
return SYSTEM_ERROR_INVALID_ARGUMENT;
947+
}
948+
uint8_t addr[BLE_SIG_ADDR_LEN] = {};
949+
memcpy(addr, address->addr, BLE_SIG_ADDR_LEN);
950+
CHECK_RTL(le_cfg_local_identity_address(addr, GAP_IDENT_ADDR_RAND));
951+
CHECK_RTL(le_set_gap_param(GAP_PARAM_RANDOM_ADDR, BLE_SIG_ADDR_LEN, addr));
952+
addr_ = *address;
953+
954+
uint8_t advLocalAddrType = GAP_LOCAL_ADDR_LE_PUBLIC;
955+
if (address->addr_type == BLE_SIG_ADDR_TYPE_RANDOM_STATIC) {
956+
advLocalAddrType = GAP_LOCAL_ADDR_LE_RANDOM;
957+
}
958+
CHECK_RTL(le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(advLocalAddrType), &advLocalAddrType));
959+
uint8_t scanLocalAddrType = GAP_LOCAL_ADDR_LE_PUBLIC;
960+
if (address->addr_type == BLE_SIG_ADDR_TYPE_RANDOM_STATIC) {
961+
scanLocalAddrType = GAP_LOCAL_ADDR_LE_RANDOM;
962+
}
963+
CHECK_RTL(le_scan_set_param(GAP_PARAM_SCAN_LOCAL_ADDR_TYPE, sizeof(uint8_t), &scanLocalAddrType));
964+
965+
return SYSTEM_ERROR_NONE;
966+
}
967+
968+
int BleGap::getDeviceAddress(hal_ble_addr_t* address) const {
969+
CHECK_TRUE(address, SYSTEM_ERROR_INVALID_ARGUMENT);
970+
*address = addr_;
971+
return SYSTEM_ERROR_NONE;
972+
}
973+
913974
int BleGap::setAdvertisingParameters(const hal_ble_adv_params_t* params) {
914975
hal_ble_adv_params_t tempParams = {};
915976
tempParams.version = BLE_API_VERSION;
@@ -2057,13 +2118,15 @@ int hal_ble_set_callback_on_periph_link_events(hal_ble_on_link_evt_cb_t callback
20572118
int hal_ble_gap_set_device_address(const hal_ble_addr_t* address, void* reserved) {
20582119
BleLock lk;
20592120
LOG_DEBUG(TRACE, "hal_ble_gap_set_device_address().");
2060-
return SYSTEM_ERROR_NOT_SUPPORTED;
2121+
CHECK_TRUE(BleGap::getInstance().initialized(), SYSTEM_ERROR_INVALID_STATE);
2122+
return BleGap::getInstance().setDeviceAddress(address);
20612123
}
20622124

20632125
int hal_ble_gap_get_device_address(hal_ble_addr_t* address, void* reserved) {
20642126
BleLock lk;
20652127
LOG_DEBUG(TRACE, "hal_ble_gap_get_device_address().");
2066-
return SYSTEM_ERROR_NOT_SUPPORTED;
2128+
CHECK_TRUE(BleGap::getInstance().initialized(), SYSTEM_ERROR_INVALID_STATE);
2129+
return BleGap::getInstance().getDeviceAddress(address);
20672130
}
20682131

20692132
int hal_ble_gap_set_device_name(const char* device_name, size_t len, void* reserved) {

hal/src/rtl872x/deviceid_hal.cpp

+24-18
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ extern "C" {
3434
#include "rtl8721d_efuse.h"
3535
}
3636

37-
3837
namespace {
3938

4039
using namespace particle;
@@ -43,13 +42,13 @@ using namespace particle;
4342
#define EFUSE_SUCCESS 1
4443
#define EFUSE_FAILURE 0
4544

45+
#define BLE_MAC_OFFSET 0x190
4646
#define WIFI_MAC_OFFSET 0x11A
4747
#define MOBILE_SECRET_OFFSET 0x160
4848
#define SERIAL_NUMBER_OFFSET 0x16F
4949
#define HARDWARE_DATA_OFFSET 0x178
5050
#define HARDWARE_MODEL_OFFSET 0x17B
5151

52-
#define WIFI_MAC_SIZE 6
5352
#define SERIAL_NUMBER_FRONT_PART_SIZE 9
5453
#define HARDWARE_DATA_SIZE 4
5554
#define HARDWARE_MODEL_SIZE 4
@@ -80,8 +79,7 @@ int readLogicalEfuse(uint32_t offset, uint8_t* buf, size_t size) {
8079

8180
} // Anonymous
8281

83-
unsigned hal_get_device_id(uint8_t* dest, unsigned destLen)
84-
{
82+
unsigned hal_get_device_id(uint8_t* dest, unsigned destLen) {
8583
// Device ID is composed of prefix and MAC address
8684
uint8_t id[HAL_DEVICE_ID_SIZE] = {};
8785
memcpy(id, DEVICE_ID_PREFIX, DEVICE_ID_PREFIX_SIZE);
@@ -92,18 +90,29 @@ unsigned hal_get_device_id(uint8_t* dest, unsigned destLen)
9290
return HAL_DEVICE_ID_SIZE;
9391
}
9492

95-
unsigned hal_get_platform_id()
96-
{
93+
unsigned hal_get_platform_id() {
9794
return PLATFORM_ID;
9895
}
9996

100-
int HAL_Get_Device_Identifier(const char** name, char* buf, size_t buflen, unsigned index, void* reserved)
101-
{
102-
return -1;
97+
int HAL_Get_Device_Identifier(const char** name, char* buf, size_t buflen, unsigned index, void* reserved) {
98+
return SYSTEM_ERROR_NOT_SUPPORTED;
99+
}
100+
101+
int hal_get_mac_address(uint8_t type, uint8_t* dest, size_t destLen, void* reserved) {
102+
CHECK_TRUE(dest && destLen >= HAL_DEVICE_MAC_ADDR_SIZE, SYSTEM_ERROR_INVALID_ARGUMENT);
103+
CHECK_TRUE(isSupportedMacType(type), SYSTEM_ERROR_INVALID_ARGUMENT);
104+
uint8_t mac[HAL_DEVICE_MAC_ADDR_SIZE] = {};
105+
if (type == HAL_DEVICE_MAC_BLE) {
106+
CHECK(readLogicalEfuse(BLE_MAC_OFFSET, mac, HAL_DEVICE_MAC_ADDR_SIZE));
107+
} else {
108+
CHECK(readLogicalEfuse(WIFI_MAC_OFFSET, mac, HAL_DEVICE_MAC_ADDR_SIZE));
109+
// Derive the final MAC address
110+
mac[5] += type;
111+
}
112+
return HAL_DEVICE_MAC_ADDR_SIZE;
103113
}
104114

105-
int hal_get_device_serial_number(char* str, size_t size, void* reserved)
106-
{
115+
int hal_get_device_serial_number(char* str, size_t size, void* reserved) {
107116
char fullSerialNumber[HAL_DEVICE_SERIAL_NUMBER_SIZE] = {};
108117

109118
// Serial Number (15 chars) is comprised of:
@@ -115,7 +124,7 @@ int hal_get_device_serial_number(char* str, size_t size, void* reserved)
115124
CHECK(readLogicalEfuse(SERIAL_NUMBER_OFFSET, (uint8_t*)fullSerialNumber, SERIAL_NUMBER_FRONT_PART_SIZE));
116125

117126
// generate hex string from non-OUI MAC bytes
118-
uint8_t wifiMacRandomBytes[WIFI_MAC_SIZE - WIFI_OUID_SIZE] = {};
127+
uint8_t wifiMacRandomBytes[HAL_DEVICE_MAC_ADDR_SIZE - WIFI_OUID_SIZE] = {};
119128
CHECK(readLogicalEfuse(WIFI_MAC_OFFSET + WIFI_OUID_SIZE, wifiMacRandomBytes, sizeof(wifiMacRandomBytes)));
120129
bytes2hexbuf(wifiMacRandomBytes, sizeof(wifiMacRandomBytes), &fullSerialNumber[SERIAL_NUMBER_FRONT_PART_SIZE]);
121130

@@ -133,8 +142,7 @@ int hal_get_device_serial_number(char* str, size_t size, void* reserved)
133142
return HAL_DEVICE_SERIAL_NUMBER_SIZE;
134143
}
135144

136-
int hal_get_device_hw_version(uint32_t* revision, void* reserved)
137-
{
145+
int hal_get_device_hw_version(uint32_t* revision, void* reserved) {
138146
// HW Data format: | NCP_ID (LSB) | HW_VERSION | HW Feature Flags |
139147
// | byte 0 | byte 1 | byte 2/3 |
140148
uint8_t hw_data[4] = {};
@@ -146,8 +154,7 @@ int hal_get_device_hw_version(uint32_t* revision, void* reserved)
146154
return SYSTEM_ERROR_NONE;
147155
}
148156

149-
int hal_get_device_hw_model(uint32_t* model, uint32_t* variant, void* reserved)
150-
{
157+
int hal_get_device_hw_model(uint32_t* model, uint32_t* variant, void* reserved) {
151158
// HW Model format: | Model Number LSB | Model Number MSB | Model Variant LSB | Model Variant MSB |
152159
// | byte 0 | byte 1 | byte 2 | byte 3 |
153160
uint8_t hw_model[4] = {};
@@ -159,8 +166,7 @@ int hal_get_device_hw_model(uint32_t* model, uint32_t* variant, void* reserved)
159166
}
160167

161168
#ifndef HAL_DEVICE_ID_NO_DCT
162-
int hal_get_device_secret(char* data, size_t size, void* reserved)
163-
{
169+
int hal_get_device_secret(char* data, size_t size, void* reserved) {
164170
// Check if the device secret data is initialized in the DCT
165171
char secret[HAL_DEVICE_SECRET_SIZE] = {};
166172
static_assert(sizeof(secret) == DCT_DEVICE_SECRET_SIZE, "");

hal/src/rtl872x/deviceid_hal_impl.h

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2022 Particle Industries, Inc. All rights reserved.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation, either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
#define HAL_DEVICE_MAC_ADDR_SIZE 6
21+
22+
#define HAL_DEVICE_MAC_WIFI_STA 0
23+
#define HAL_DEVICE_MAC_BLE 1
24+
#define HAL_DEVICE_MAC_WIFI_AP 2
25+
#define HAL_DEVICE_MAC_ETHERNET 3
26+
27+
#define isSupportedMacType(type) ((type) == HAL_DEVICE_MAC_WIFI_STA || \
28+
(type) == HAL_DEVICE_MAC_BLE || \
29+
(type) == HAL_DEVICE_MAC_WIFI_AP || \
30+
(type) == HAL_DEVICE_MAC_ETHERNET)
31+
32+
#ifdef __cplusplus
33+
extern "C" {
34+
#endif
35+
36+
/**
37+
* Get the device's BLE MAC address.
38+
*/
39+
int hal_get_mac_address(uint8_t type, uint8_t* dest, size_t destLen, void* reserved);
40+
41+
#ifdef __cplusplus
42+
}
43+
#endif

0 commit comments

Comments
 (0)