| /* |
| * |
| * Copyright (c) 2022 Project CHIP Authors |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * Provides an implementation of the BLEManager singleton object |
| * for the Beken platforms. |
| */ |
| |
| /* this file behaves like a config.h, comes first */ |
| #include <crypto/CHIPCryptoPAL.h> |
| #include <platform/CommissionableDataProvider.h> |
| #include <platform/DeviceInstanceInfoProvider.h> |
| #include <platform/internal/CHIPDeviceLayerInternal.h> |
| #include <setup_payload/AdditionalDataPayloadGenerator.h> |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE |
| #include <ble/Ble.h> |
| #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING |
| #include <setup_payload/AdditionalDataPayloadGenerator.h> |
| #endif |
| #include "stdio.h" |
| #include "timers.h" |
| #include <string.h> |
| |
| // BK7231n BLE related header files |
| #include "matter_pal.h" |
| |
| /******************************************************************************* |
| * Local data types |
| *******************************************************************************/ |
| using namespace ::chip; |
| using namespace ::chip::Ble; |
| |
| namespace chip { |
| namespace DeviceLayer { |
| namespace Internal { |
| |
| namespace { |
| |
| /******************************************************************************* |
| * Macros & Constants definitions |
| *******************************************************************************/ |
| #ifndef MAX_ADV_DATA_LEN |
| #define MAX_ADV_DATA_LEN 31 |
| #endif |
| #define CHIP_ADV_DATA_TYPE_FLAGS 0x01 |
| #define CHIP_ADV_DATA_FLAGS 0x06 |
| |
| /* advertising configuration */ |
| #define CHIP_ADV_SHORT_UUID_LEN (2) |
| |
| /* FreeRTOS sw timer */ |
| TimerHandle_t bleFastAdvTimer; |
| |
| enum |
| { |
| DriveBLEExtPerfEvt_DISCONNECT = 0, |
| }; |
| |
| const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, |
| 0x9D, 0x11 } }; |
| const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, |
| 0x9D, 0x12 } }; |
| static const uint8_t _svc_uuid[16] = { 0xF6, 0xFF, 0, 0, 0x0, 0x0, 0, 0, 0, 0, 0x0, 0x0, 0, 0, 0, 0 }; |
| |
| #define UUID_CHIPoBLECharact_RX \ |
| { \ |
| 0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 \ |
| } |
| // #define UUID_CHIPoBLECharact_RX { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, |
| // 0x11 |
| // } |
| #define ChipUUID_CHIPoBLECharact_TX \ |
| { \ |
| 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 \ |
| } |
| // #define ChipUUID_CHIPoBLECharact_TX { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, |
| // 0x12 } |
| #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING |
| #define UUID_CHIPoBLEChar_C3 \ |
| { \ |
| 0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0x63, 0x64 \ |
| } |
| #endif |
| #define BEKEN_ATT_DECL_PRIMARY_SERVICE_128 \ |
| { \ |
| 0x00, 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ |
| } |
| #define BEKEN_ATT_DECL_CHARACTERISTIC_128 \ |
| { \ |
| 0x03, 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ |
| } |
| #define BEKEN_ATT_DESC_CLIENT_CHAR_CFG_128 \ |
| { \ |
| 0x02, 0x29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ |
| } |
| |
| enum |
| { |
| SVR_FFF6_IDX_SVC, |
| SVR_FFF6_RX_DECL, |
| SVR_FFF6_RX_VALUE, |
| SVR_FFF6_TX_DECL, |
| SVR_FFF6_TX_VALUE, |
| #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING |
| SVR_FFF6_C3_VALUE, |
| #endif |
| SVR_FFF6_TX_CFG, |
| SVR_FFF6_MAX, |
| }; |
| |
| ble_attm_desc_t svr_fff6_att_db[SVR_FFF6_MAX] = { |
| // Service Declaration |
| [SVR_FFF6_IDX_SVC] = { BEKEN_ATT_DECL_PRIMARY_SERVICE_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 2 }, |
| |
| // Level Characteristic Declaration |
| [SVR_FFF6_RX_DECL] = { BEKEN_ATT_DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0 }, |
| // Level Characteristic Value BK_PERM_RIGHT_ENABLE WRITE_REQ_POS RI_POS UUID_LEN_POS BK_PERM_RIGHT_UUID_128 |
| [SVR_FFF6_RX_VALUE] = { UUID_CHIPoBLECharact_RX, BK_BLE_PERM_SET(WRITE_REQ, ENABLE), |
| BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_128), 512 }, |
| |
| /// RD_POS NTF_POS |
| [SVR_FFF6_TX_DECL] = { BEKEN_ATT_DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(NTF, ENABLE), 0, 0 }, |
| //// UUID_LEN_POS BK_PERM_RIGHT_UUID_128 RD_POS |
| [SVR_FFF6_TX_VALUE] = { ChipUUID_CHIPoBLECharact_TX, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(NTF, ENABLE), |
| BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_128), 512 }, |
| #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING |
| [SVR_FFF6_C3_VALUE] = { UUID_CHIPoBLEChar_C3, BK_BLE_PERM_SET(RD, ENABLE), |
| BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_128), 512 }, |
| #endif |
| [SVR_FFF6_TX_CFG] = { BEKEN_ATT_DESC_CLIENT_CHAR_CFG_128, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(WRITE_REQ, ENABLE), 0, |
| 2 }, |
| }; |
| |
| /// const static uint8_t svr_fff6_att_db_item = SVR_FFF6_MAX; |
| } // namespace |
| |
| BLEManagerImpl BLEManagerImpl::sInstance; |
| |
| int BLEManagerImpl::beken_ble_init(void) |
| { |
| int status; |
| |
| struct bk_ble_db_cfg ble_db_cfg; |
| |
| ble_db_cfg.att_db = svr_fff6_att_db; |
| ble_db_cfg.att_db_nb = SVR_FFF6_MAX; |
| ble_db_cfg.prf_task_id = 0; |
| ble_db_cfg.start_hdl = 0; |
| ble_db_cfg.svc_perm = BK_BLE_PERM_SET(SVC_UUID_LEN, UUID_16); |
| memcpy(&(ble_db_cfg.uuid[0]), &_svc_uuid[0], 16); |
| status = bk_ble_create_db(&ble_db_cfg); |
| |
| if (status != BK_ERR_BLE_SUCCESS) |
| { |
| return -1; |
| } |
| return 0; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::_Init() |
| { |
| CHIP_ERROR err; |
| |
| // Initialize the CHIP BleLayer. |
| err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); |
| SuccessOrExit(err); |
| |
| mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; |
| memset(mBleConnections, 0, sizeof(mBleConnections)); |
| // Check if BLE stack is initialized |
| VerifyOrExit(!mFlags.Has(Flags::kAMEBABLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE); |
| bk_ble_set_notice_cb(ble_event_notice); |
| |
| // Set related flags |
| mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); |
| mFlags.Set(Flags::kAMEBABLEStackInitialized); |
| mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false); |
| mFlags.Set(Flags::kFastAdvertisingEnabled); |
| mFlags.Set(Flags::kSlowAdvertisingEnabled); |
| if (!mFlags.Has(Flags::kBEKENBLEAdvTimer)) |
| { |
| uint32_t bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME; |
| bleFastAdvTimer = xTimerCreate("", (bleAdvTimeoutMs / 2), pdFALSE, NULL, ble_adv_timer_timeout_handle); |
| mFlags.Set(Flags::kBEKENBLEAdvTimer); |
| } |
| |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| |
| exit: |
| return err; |
| } |
| |
| void BLEManagerImpl::HandleTXCharRead(void * param) |
| { |
| CHIPoBLEConState * conState; |
| ble_read_req_t * r_req = (ble_read_req_t *) param; |
| if (param == NULL) |
| { |
| ChipLogError(DeviceLayer, "HandleTXCharRead failed: %p", param); |
| } |
| r_req->length = 0; |
| } |
| |
| void BLEManagerImpl::HandleTXCharCCCDRead(void * param) |
| { |
| CHIPoBLEConState * conState; |
| ble_read_req_t * r_req = (ble_read_req_t *) param; |
| conState = GetConnectionState(r_req->conn_idx); |
| |
| if (param == NULL) |
| { |
| ChipLogError(DeviceLayer, "HandleTXCharCCCDRead failed"); |
| return; |
| } |
| |
| if (conState != NULL) |
| { |
| r_req->value[0] = conState->subscribed ? 1 : 0; |
| r_req->value[1] = 0; |
| r_req->length = 2; |
| } |
| else |
| { |
| ChipLogError(DeviceLayer, "conState failed: %p", conState); |
| r_req->length = 0; |
| } |
| } |
| |
| void BLEManagerImpl::HandleTXCharCCCDWrite(int conn_id, int notificationsEnabled, int indicationsEnabled) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| // If the client has requested to enabled indications/notifications |
| if (indicationsEnabled || notificationsEnabled) |
| { |
| // If indications are not already enabled for the connection... |
| if (!IsSubscribed(conn_id)) |
| { |
| // Record that indications have been enabled for this connection. |
| err = SetSubscribed(conn_id); |
| VerifyOrExit(err != CHIP_ERROR_NO_MEMORY, err = CHIP_NO_ERROR); |
| SuccessOrExit(err); |
| } |
| } |
| else |
| { |
| // If indications had previously been enabled for this connection, record that they are no longer enabled. |
| UnsetSubscribed(conn_id); |
| } |
| |
| // Post an event to the Chip queue to process either a CHIPoBLE Subscribe or Unsubscribe based on |
| // whether the client is enabling or disabling indications. |
| { |
| ChipDeviceEvent event; |
| event.Type = (indicationsEnabled || notificationsEnabled) ? DeviceEventType::kCHIPoBLESubscribe |
| : DeviceEventType::kCHIPoBLEUnsubscribe; |
| event.CHIPoBLESubscribe.ConId = conn_id; |
| PlatformMgr().PostEventOrDie(&event); |
| } |
| |
| ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", |
| (indicationsEnabled || notificationsEnabled) ? "subscribe" : "unsubscribe"); |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err)); |
| } |
| |
| return; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::HandleTXComplete(int conn_id) |
| { |
| // Post an event to the Chip queue to process the indicate confirmation. |
| ChipDeviceEvent event; |
| event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; |
| event.CHIPoBLEIndicateConfirm.ConId = conn_id; |
| PlatformMgr().PostEventOrDie(&event); |
| return CHIP_NO_ERROR; |
| } |
| |
| uint16_t BLEManagerImpl::_NumConnections(void) |
| { |
| uint16_t numCons = 0; |
| |
| for (uint8_t i = 0; i < kMaxConnections; i++) |
| { |
| if (mBleConnections[i].allocated == 1) |
| { |
| numCons += 1; |
| } |
| } |
| |
| return numCons; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::HandleGAPConnect(uint16_t conn_id) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| // Track the number of active GAP connections. |
| mNumGAPCons++; |
| err = SetSubscribed(conn_id); |
| VerifyOrExit(err != CHIP_ERROR_NO_MEMORY, err = CHIP_NO_ERROR); |
| SuccessOrExit(err); |
| |
| exit: |
| return err; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(uint16_t conn_id, uint16_t disc_cause) |
| { |
| // Update the number of GAP connections. |
| if (mNumGAPCons > 0) |
| { |
| mNumGAPCons--; |
| } |
| |
| if (RemoveConnection(conn_id)) |
| { |
| CHIP_ERROR disconReason; |
| switch (disc_cause) |
| { |
| case 0x13: |
| case 0x08: |
| disconReason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; |
| break; |
| case 0x16: |
| disconReason = BLE_ERROR_APP_CLOSED_CONNECTION; |
| break; |
| default: |
| disconReason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; |
| break; |
| } |
| HandleConnectionError(conn_id, disconReason); |
| } |
| |
| // Force a reconfiguration of advertising in case we switched to non-connectable mode when |
| // the BLE connection was established. |
| mFlags.Set(Flags::kAdvertisingRefreshNeeded); |
| return CHIP_NO_ERROR; |
| } |
| |
| bool BLEManagerImpl::RemoveConnection(uint8_t connectionHandle) |
| { |
| CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle); |
| bool status = false; |
| |
| if (bleConnState != NULL) |
| { |
| bleConnState->Reset(); |
| memset(bleConnState, 0, sizeof(CHIPoBLEConState)); |
| status = true; |
| } |
| return status; |
| } |
| |
| BLEManagerImpl::CHIPoBLEConState * BLEManagerImpl::GetConnectionState(uint8_t connectionHandle, bool allocate) |
| { |
| uint8_t freeIndex = kMaxConnections; |
| |
| for (uint8_t i = 0; i < kMaxConnections; i++) |
| { |
| if (mBleConnections[i].allocated == 1) |
| { |
| if (mBleConnections[i].conn_idx == connectionHandle) |
| { |
| return &mBleConnections[i]; |
| } |
| } |
| |
| else if (i < freeIndex) |
| { |
| freeIndex = i; |
| } |
| } |
| |
| if (allocate) |
| { |
| if (freeIndex < kMaxConnections) |
| { |
| mBleConnections[freeIndex].Set(connectionHandle); |
| return &mBleConnections[freeIndex]; |
| } |
| |
| ChipLogError(DeviceLayer, "Failed to allocate CHIPoBLEConState"); |
| } |
| |
| return NULL; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT); |
| VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); |
| |
| if (val != mServiceMode) |
| { |
| mServiceMode = val; |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); |
| |
| if (mFlags.Has(Flags::kAdvertisingEnabled) != val) |
| { |
| mFlags.Set(Flags::kAdvertisingEnabled, val); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) |
| { |
| switch (mode) |
| { |
| case BLEAdvertisingMode::kFastAdvertising: |
| mFlags.Set(Flags::kFastAdvertisingEnabled, true); |
| break; |
| case BLEAdvertisingMode::kSlowAdvertising: |
| mFlags.Set(Flags::kFastAdvertisingEnabled, false); |
| break; |
| default: |
| return CHIP_ERROR_INVALID_ARGUMENT; |
| } |
| mFlags.Set(Flags::kAdvertisingRefreshNeeded); |
| |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) |
| { |
| if (strlen(mDeviceName) >= bufSize) |
| { |
| return CHIP_ERROR_BUFFER_TOO_SMALL; |
| } |
| strcpy(buf, mDeviceName); |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); |
| |
| if (deviceName != NULL && deviceName[0] != 0) |
| { |
| VerifyOrExit(strlen(deviceName) >= kMaxDeviceNameLength, err = CHIP_ERROR_INVALID_ARGUMENT); |
| strcpy(mDeviceName, deviceName); |
| mFlags.Set(Flags::kDeviceNameSet); |
| ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName); |
| } |
| else |
| { |
| mDeviceName[0] = 0; |
| mFlags.Clear(Flags::kDeviceNameSet); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) |
| { |
| switch (event->Type) |
| { |
| // Platform specific events |
| case DeviceEventType::kCHIPoBLESubscribe: |
| HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); |
| { |
| ChipDeviceEvent connEstEvent; |
| connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; |
| PlatformMgr().PostEventOrDie(&connEstEvent); |
| } |
| break; |
| |
| case DeviceEventType::kCHIPoBLEUnsubscribe: { |
| ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe"); |
| HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); |
| } |
| break; |
| |
| case DeviceEventType::kCHIPoBLEWriteReceived: { |
| ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEWriteReceived"); |
| HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX, |
| PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); |
| } |
| break; |
| |
| case DeviceEventType::kCHIPoBLEConnectionError: { |
| ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEConnectionError"); |
| HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); |
| } |
| break; |
| |
| case DeviceEventType::kCHIPoBLEIndicateConfirm: { |
| ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm"); |
| HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); |
| } |
| break; |
| |
| case DeviceEventType::kServiceProvisioningChange: |
| case DeviceEventType::kWiFiConnectivityChange: |
| ChipLogProgress(DeviceLayer, "Updating advertising data"); |
| StartAdvertising(); |
| break; |
| |
| default: |
| ChipLogProgress(DeviceLayer, "_OnPlatformEvent default: event->Type = %d", event->Type); |
| break; |
| } |
| } |
| |
| bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) |
| { |
| ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported"); |
| return false; |
| } |
| |
| bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) |
| { |
| ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported"); |
| return false; |
| } |
| |
| bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) |
| { |
| CHIP_ERROR err; |
| ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId); |
| uint32_t delay_time = 20; |
| int ret; |
| |
| do |
| { |
| ret = bk_ble_disconnect(conId, beken_ble_cmd_cb); |
| if (BK_ERR_BLE_SUCCESS == ret) |
| { |
| break; |
| } |
| |
| rtos_delay_milliseconds(10); |
| delay_time--; |
| } while (delay_time); |
| // Beken Ble close function |
| err = MapBLEError(ret); |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(DeviceLayer, "bk_ble_disconnect() failed: %s", ErrorStr(err)); |
| } |
| |
| return false; |
| } |
| |
| uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const |
| { |
| CHIPoBLEConState * conState = const_cast<BLEManagerImpl *>(this)->GetConnectionState(conId); |
| return (conState != NULL) ? conState->mtu : 0; |
| } |
| |
| bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, |
| PacketBufferHandle pBuf) |
| { |
| ChipLogError(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported"); |
| return false; |
| } |
| |
| bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, |
| PacketBufferHandle pBuf) |
| { |
| ChipLogError(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported"); |
| return false; |
| } |
| |
| bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, |
| const ChipBleUUID * svcId, const ChipBleUUID * charId) |
| { |
| ChipLogError(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported"); |
| return false; |
| } |
| |
| void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) |
| { |
| // Nothing to do |
| } |
| |
| bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, |
| PacketBufferHandle data) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| int ret; |
| |
| VerifyOrExit(IsSubscribed(conId), err = CHIP_ERROR_INVALID_ARGUMENT); |
| ret = bk_ble_send_noti_value(conId, data->DataLength(), data->Start(), 0, SVR_FFF6_TX_VALUE); |
| err = MapBLEError(ret); |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %s", ErrorStr(err)); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /******************************************************************************* |
| * Private functions |
| *******************************************************************************/ |
| |
| CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| // If the device name is not specified, generate a CHIP-standard name based on the bottom digits of the Chip device id. |
| uint16_t discriminator; |
| SuccessOrExit(err = GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator)); |
| |
| if (!mFlags.Has(Flags::kDeviceNameSet)) |
| { |
| snprintf(mDeviceName, sizeof(mDeviceName), "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator); |
| mDeviceName[kMaxDeviceNameLength] = 0; |
| } |
| |
| // Configure the BLE device name. |
| sInstance.mFlags.Set(Flags::kDeviceNameDefSet); |
| bk_ble_appm_set_dev_name(kMaxDeviceNameLength, (uint8_t *) mDeviceName); |
| exit: |
| return err; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::StartAdvertising(void) |
| { |
| ble_err_t bk_err; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| ChipLogProgress(DeviceLayer, "StartAdvertising..."); |
| ChipLogProgress(DeviceLayer, "BLE flag = %x", mFlags.Raw()); |
| if ((!mFlags.Has(Flags::kDeviceNameSet)) && (!mFlags.Has(Flags::kDeviceNameDefSet))) |
| { |
| err = sInstance.ConfigureAdvertisingData(); |
| SuccessOrExit(err); |
| } |
| // Post a CHIPoBLEAdvertisingChange(Stopped) event. |
| if (mFlags.Has(Flags::kBEKENBLEADVStop)) |
| { |
| bk_ble_delete_advertising(adv_actv_idx, beken_ble_cmd_cb); |
| mFlags.Clear(Flags::kBEKENBLEADVStop); |
| ChipDeviceEvent advChange; |
| advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; |
| advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; |
| PlatformMgr().PostEventOrDie(&advChange); |
| goto exit; |
| } |
| else if (!mFlags.Has(Flags::kBEKENBLEADVCreate)) |
| { |
| ChipLogProgress(DeviceLayer, "BLE ADVCreate..."); |
| uint16_t adv_int_min; |
| uint16_t adv_int_max; |
| ble_adv_param_t adv_param; |
| |
| memset(&adv_param, 0, sizeof(adv_param)); |
| |
| if (mFlags.Has(Flags::kFastAdvertisingEnabled)) |
| { |
| adv_int_min = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN; |
| adv_int_max = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX; |
| mFlags.Set(Flags::kAdvertisingIsFastADV); |
| } |
| else |
| { |
| adv_int_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; |
| adv_int_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; |
| mFlags.Clear(Flags::kAdvertisingIsFastADV); |
| } |
| |
| adv_actv_idx = bk_ble_get_idle_actv_idx_handle(); |
| if (UNKNOW_ACT_IDX == adv_actv_idx) |
| { |
| ChipLogError(DeviceLayer, "adv act-idx:%d error", adv_actv_idx); |
| return MapBLEError(-1); |
| } |
| adv_param.chnl_map = 7; |
| adv_param.adv_intv_max = 160; |
| adv_param.adv_intv_min = 160; |
| adv_param.own_addr_type = 0; |
| adv_param.adv_type = 0; |
| adv_param.adv_prop = 3; |
| adv_param.prim_phy = 1; |
| // bk_ble_create_advertising(adv_actv_idx, 7, adv_int_min, adv_int_max, beken_ble_cmd_cb); |
| bk_err = bk_ble_create_advertising(adv_actv_idx, &adv_param, beken_ble_cmd_cb); |
| if (bk_err != BK_OK) |
| { |
| ChipLogProgress(DeviceLayer, "BLE ADVCreate ret= %x.", bk_err); |
| } |
| ChipLogProgress(DeviceLayer, "BLE ADVCreate ret= %x. adv_actv_idx = %x", bk_err, adv_actv_idx); |
| sInstance.mFlags.Clear(Flags::kAdvertisingRefreshNeeded); |
| goto exit; |
| } |
| else if (!mFlags.Has(Flags::kBEKENBLEADVSetData)) |
| { |
| ChipLogProgress(DeviceLayer, "BLE SetData..."); |
| ChipBLEDeviceIdentificationInfo deviceIdInfo; |
| uint8_t advData[MAX_ADV_DATA_LEN] = { 0 }; |
| uint8_t index = 0; |
| /**************** Prepare advertising data *******************************************/ |
| memset(advData, 0, sizeof(advData)); |
| advData[index++] = 0x02; // length |
| advData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags |
| advData[index++] = CHIP_ADV_DATA_FLAGS; // AD value |
| advData[index++] = static_cast<uint8_t>(sizeof(deviceIdInfo) + CHIP_ADV_SHORT_UUID_LEN + 1); |
| ; // length |
| advData[index++] = 0x16; // AD type: (Service Data - 16-bit UUID) |
| advData[index++] = static_cast<uint8_t>(_svc_uuid[0] & 0xFF); // AD value |
| advData[index++] = static_cast<uint8_t>(_svc_uuid[1] & 0xFF); // AD value |
| err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo); |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(DeviceLayer, "GetBLEDeviceIdentificationInfo(): %s", ErrorStr(err)); |
| ExitNow(); |
| } |
| |
| #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING |
| deviceIdInfo.SetAdditionalDataFlag(true); |
| #endif |
| VerifyOrExit(index + sizeof(deviceIdInfo) <= sizeof(advData), err = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG); |
| |
| memcpy(&advData[index], &deviceIdInfo, sizeof(deviceIdInfo)); |
| index = static_cast<uint8_t>(index + sizeof(deviceIdInfo)); |
| bk_ble_set_adv_data(adv_actv_idx, advData, index, beken_ble_cmd_cb); |
| goto exit; |
| } |
| else if (!mFlags.Has(Flags::kBEKENBLEADVSetRsp)) |
| { |
| /// uint8_t advData[MAX_ADV_DATA_LEN] = { 0 }; |
| /// bk_ble_set_scan_rsp_data(adv_actv_idx, advData, 0xF, beken_ble_cmd_cb); |
| sInstance.mFlags.Set(Flags::kBEKENBLEADVSetRsp); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| goto exit; |
| } |
| else if (!mFlags.Has(Flags::kBEKENBLEADVStarted)) |
| { |
| ChipLogProgress(DeviceLayer, "BLE Started..."); |
| bk_ble_start_advertising(adv_actv_idx, 0, beken_ble_cmd_cb); |
| goto exit; |
| } |
| |
| if (mFlags.Has(Flags::kBEKENBLEADVStarted)) |
| { |
| ChipDeviceEvent advChange; |
| advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; |
| advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; |
| PlatformMgr().PostEventOrDie(&advChange); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::StopAdvertising(void) |
| { |
| // Change flag status to the 'not Advertising state' |
| if ((mFlags.Has(Flags::kBEKENBLEADVStarted)) && (!mFlags.Has(Flags::kBEKENBLEADVStop))) |
| { |
| mFlags.Set(Flags::kBEKENBLEADVStop); |
| bk_ble_stop_advertising(adv_actv_idx, beken_ble_cmd_cb); |
| ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopping"); |
| goto exit; |
| } |
| |
| // Post a CHIPoBLEAdvertisingChange(Stopped) event. |
| if (mFlags.Has(Flags::kBEKENBLEADVStop)) |
| { |
| bk_ble_delete_advertising(adv_actv_idx, beken_ble_cmd_cb); |
| mFlags.Clear(Flags::kBEKENBLEADVStop); |
| ChipDeviceEvent advChange; |
| advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; |
| advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; |
| PlatformMgr().PostEventOrDie(&advChange); |
| } |
| exit: |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) |
| { |
| switch (bleErr) |
| { |
| case BK_ERR_BLE_SUCCESS: |
| return CHIP_NO_ERROR; |
| default: |
| return CHIP_ERROR_INCORRECT_STATE; |
| } |
| } |
| |
| void BLEManagerImpl::DriveBLEState(void) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| // Check if BLE stack is initialized |
| VerifyOrExit(mFlags.Has(Flags::kAMEBABLEStackInitialized), /* */); |
| if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled) |
| { |
| if (!mFlags.Has(Flags::kBekenBLESGATTSReady)) |
| { |
| beken_ble_init(); |
| goto exit; |
| } |
| } |
| |
| if ((!mFlags.Has(Flags::kFastAdvertisingEnabled)) && (!mFlags.Has(Flags::kSlowAdvertisingEnabled))) |
| { |
| mFlags.Clear(Flags::kAdvertisingEnabled); |
| mFlags.Clear(Flags::kAdvertisingRefreshNeeded); |
| } |
| |
| if (mFlags.Has(Flags::kAdvertisingRefreshNeeded)) |
| { |
| if (mFlags.Has(Flags::kBEKENBLEADVStarted)) |
| { |
| err = StopAdvertising(); |
| SuccessOrExit(err); |
| goto exit; |
| } |
| else if (mFlags.Has(Flags::kBEKENBLEADVStarted)) |
| { |
| bk_ble_delete_advertising(adv_actv_idx, beken_ble_cmd_cb); |
| goto exit; |
| } |
| } |
| |
| // Start advertising if needed... |
| if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && |
| ((mFlags.Has(Flags::kAdvertisingEnabled)) || (mFlags.Has(Flags::kAdvertisingRefreshNeeded)))) |
| { |
| // Start/re-start advertising if not already started, or if there is a pending change |
| // to the advertising configuration. |
| if (!mFlags.Has(Flags::kBEKENBLEADVStarted)) |
| { |
| err = StartAdvertising(); |
| SuccessOrExit(err); |
| } |
| else |
| { |
| mFlags.Clear(Flags::kAdvertisingRefreshNeeded); |
| } |
| } |
| // Otherwise, stop advertising if it is enabled. |
| else if ((mFlags.Has(Flags::kBEKENBLEADVStarted)) || (mFlags.Has(Flags::kBEKENBLEADVStop))) |
| { |
| err = StopAdvertising(); |
| SuccessOrExit(err); |
| ChipLogProgress(DeviceLayer, "Stopped Advertising"); |
| } |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); |
| mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; |
| } |
| } |
| |
| void BLEManagerImpl::DriveBLEState(intptr_t arg) |
| { |
| sInstance.DriveBLEState(); |
| } |
| |
| void BLEManagerImpl::DriveBLEExtPerf(intptr_t arg) |
| { |
| int arg_int = static_cast<int>(arg); |
| int event = arg_int & 0xFFU; |
| switch (event) |
| { |
| case DriveBLEExtPerfEvt_DISCONNECT: { |
| uint8_t conn_indx = (arg_int >> 8) & 0xFFU; |
| sInstance.CloseConnection(conn_indx); |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| |
| /******************************************************************************* |
| * FreeRTOS Task Management Functions |
| *******************************************************************************/ |
| void BLEManagerImpl::ble_adv_timer_timeout_handle(TimerHandle_t xTimer) |
| { |
| if (sInstance.mFlags.Has(Flags::kFastAdvertisingEnabled)) |
| { |
| ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop Fast advertisement"); |
| |
| sInstance.mFlags.Clear(Flags::kFastAdvertisingEnabled); |
| // Stop advertising, change interval and restart it; |
| sInstance.StopAdvertising(); |
| } |
| else if (sInstance._IsAdvertisingEnabled()) |
| { |
| // Advertisement time expired. Stop advertising |
| ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop slow advertisement"); |
| sInstance.mFlags.Clear(Flags::kSlowAdvertisingEnabled); |
| sInstance.StopAdvertising(); |
| } |
| } |
| |
| void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) |
| { |
| if (xTimerIsTimerActive(bleFastAdvTimer)) |
| { |
| if (xTimerStop(bleFastAdvTimer, 0) == pdFAIL) |
| { |
| ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); |
| sInstance.mFlags.Clear(Flags::kBEKENBLEAdvTimerRun); |
| } |
| } |
| } |
| |
| void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) |
| { |
| CancelBleAdvTimeoutTimer(); |
| // timer is not active, change its period to required value (== restart). |
| // FreeRTOS- Block for a maximum of 100 ticks if the change period command |
| // cannot immediately be sent to the timer command queue. |
| if (xTimerChangePeriod(bleFastAdvTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) |
| { |
| ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); |
| } |
| else |
| { |
| xTimerStart(bleFastAdvTimer, BEKEN_WAIT_FOREVER); |
| sInstance.mFlags.Set(Flags::kBEKENBLEAdvTimerRun); |
| } |
| } |
| |
| CHIP_ERROR BLEManagerImpl::SetSubscribed(uint16_t conId) |
| { |
| CHIPoBLEConState * bleConnState = GetConnectionState(conId, false); |
| |
| if (bleConnState != NULL) |
| { |
| bleConnState->subscribed = 1; |
| return CHIP_NO_ERROR; |
| } |
| |
| return CHIP_ERROR_NO_MEMORY; |
| } |
| |
| bool BLEManagerImpl::UnsetSubscribed(uint16_t conId) |
| { |
| CHIPoBLEConState * bleConnState = GetConnectionState(conId, false); |
| |
| if (bleConnState != NULL) |
| { |
| bleConnState->subscribed = 0; |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool BLEManagerImpl::IsSubscribed(uint16_t conId) |
| { |
| CHIPoBLEConState * bleConnState = GetConnectionState(conId, false); |
| |
| if (bleConnState != NULL) |
| { |
| if (bleConnState->subscribed) |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void BLEManagerImpl::HandleRXCharWrite(uint8_t * p_value, uint16_t len, uint8_t conn_id) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| PacketBufferHandle buf = System::PacketBufferHandle::New(len, 0); |
| memcpy(buf->Start(), p_value, len); |
| buf->SetDataLength(len); |
| |
| // Post an event to the Chip queue to deliver the data into the Chip stack. |
| { |
| ChipDeviceEvent event; |
| event.Type = DeviceEventType::kCHIPoBLEWriteReceived; |
| event.CHIPoBLEWriteReceived.ConId = (uint16_t) conn_id; |
| event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); |
| PlatformMgr().PostEventOrDie(&event); |
| } |
| |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err)); |
| } |
| } |
| |
| void BLEManagerImpl::HandleTXCharConfirm(CHIPoBLEConState * conState, int status) |
| { |
| // If the confirmation was successful... |
| if (status == 0) |
| { |
| // Post an event to the Chip queue to process the indicate confirmation. |
| ChipDeviceEvent event; |
| event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; |
| event.CHIPoBLEIndicateConfirm.ConId = conState->conn_idx; |
| PlatformMgr().PostEventOrDie(&event); |
| } |
| else |
| { |
| ChipDeviceEvent event; |
| event.Type = DeviceEventType::kCHIPoBLEConnectionError; |
| event.CHIPoBLEConnectionError.ConId = conState->conn_idx; |
| event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; |
| PlatformMgr().PostEventOrDie(&event); |
| } |
| } |
| |
| void BLEManagerImpl::beken_ble_cmd_cb(ble_cmd_t cmd, ble_cmd_param_t * param) |
| { |
| ChipLogProgress(DeviceLayer, "cmd:%d idx:%d status:%d\r\n", cmd, param->cmd_idx, param->status); |
| switch (cmd) |
| { |
| case BLE_CREATE_ADV: |
| sInstance.mFlags.Set(Flags::kBEKENBLEADVCreate); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| break; |
| case BLE_SET_ADV_DATA: |
| sInstance.mFlags.Set(Flags::kBEKENBLEADVSetData); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| break; |
| case BLE_SET_RSP_DATA: |
| sInstance.mFlags.Set(Flags::kBEKENBLEADVSetRsp); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| break; |
| case BLE_START_ADV: { |
| uint32_t bleAdvTimeoutMs; |
| sInstance.mFlags.Set(Flags::kBEKENBLEADVStarted); |
| // if (sInstance.mFlags.Has(Flags::kAdvertisingIsFastADV)){ |
| bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME; |
| //}else{ |
| // bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT; |
| //} |
| StartBleAdvTimeoutTimer(bleAdvTimeoutMs); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| } |
| break; |
| case BLE_STOP_ADV: |
| sInstance.mFlags.Clear(Flags::kBEKENBLEADVStarted); |
| ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); |
| CancelBleAdvTimeoutTimer(); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| break; |
| case BLE_DELETE_ADV: |
| sInstance.mFlags.Clear(Flags::kBEKENBLEADVCreate); |
| sInstance.mFlags.Clear(Flags::kBEKENBLEADVSetData); |
| sInstance.mFlags.Clear(Flags::kBEKENBLEADVSetRsp); |
| sInstance.mFlags.Clear(Flags::kBEKENBLEADVStarted); |
| sInstance.adv_actv_idx = kUnusedIndex; |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| break; |
| case BLE_CONN_DIS_CONN: |
| break; |
| default: |
| break; |
| } |
| } |
| |
| #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING |
| void BLEManagerImpl::HandleC3CharRead(void * param) |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| chip::System::PacketBufferHandle bufferHandle; |
| ble_read_req_t * r_req = (ble_read_req_t *) param; |
| |
| AdditionalDataPayloadGeneratorParams additionalDataPayloadParams; |
| BitFlags<AdditionalDataFields> additionalDataFields; |
| |
| #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) |
| uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {}; |
| MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId); |
| |
| err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan); |
| SuccessOrExit(err); |
| err = ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter); |
| SuccessOrExit(err); |
| additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan; |
| additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId); |
| #endif /* CHIP_ENABLE_ROTATING_DEVICE_ID */ |
| |
| err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(additionalDataPayloadParams, bufferHandle, |
| additionalDataFields); |
| SuccessOrExit(err); |
| if (r_req->value == NULL) |
| { |
| ChipLogError(DeviceLayer, "param->value == NULL"); |
| return; |
| } |
| memcpy(r_req->value, bufferHandle->Start(), bufferHandle->DataLength()); |
| r_req->length = bufferHandle->DataLength(); |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data"); |
| } |
| return; |
| } |
| #endif |
| |
| void BLEManagerImpl::ble_event_notice(ble_notice_t notice, void * param) |
| { |
| /// BLEManagerImpl * blemgr = static_cast<BLEManagerImpl *>(param); |
| static int conn_idx = 0; // TODO. will improve this when driver notify the status and channel to app. |
| switch (notice) |
| { |
| case BLE_5_STACK_OK: { |
| ChipLogProgress(DeviceLayer, "ble stack ok"); |
| sInstance.mFlags.Set(Flags::kAMEBABLEStackInitialized); |
| } |
| break; |
| case BLE_5_WRITE_EVENT: { |
| ble_write_req_t * w_req = (ble_write_req_t *) param; |
| ChipLogProgress(DeviceLayer, "write_cb:conn_idx:%d, prf_id:%d, add_id:%d, len:%d, data[0]:%02x\r\n", w_req->conn_idx, |
| w_req->prf_id, w_req->att_idx, w_req->len, w_req->value[0]); |
| if (w_req->att_idx == SVR_FFF6_TX_VALUE) |
| { |
| sInstance.HandleRXCharWrite((uint8_t *) &w_req->value[0], w_req->len, w_req->conn_idx); |
| } |
| else if (w_req->att_idx == SVR_FFF6_TX_CFG) |
| { |
| int notificationsEnabled = w_req->value[0] | (w_req->value[0] << 8); |
| sInstance.HandleTXCharCCCDWrite(w_req->conn_idx, notificationsEnabled); |
| } |
| else if (w_req->att_idx == SVR_FFF6_RX_VALUE) |
| { |
| sInstance.HandleRXCharWrite((uint8_t *) &w_req->value[0], w_req->len, w_req->conn_idx); |
| } |
| break; |
| } |
| case BLE_5_READ_EVENT: { |
| ble_read_req_t * r_req = (ble_read_req_t *) param; |
| ChipLogProgress(DeviceLayer, "read_cb:conn_idx:%d, prf_id:%d, add_id:%d\r\n", r_req->conn_idx, r_req->prf_id, |
| r_req->att_idx); |
| if (r_req->att_idx == SVR_FFF6_RX_VALUE) |
| { |
| sInstance.HandleTXCharRead(param); |
| } |
| if (r_req->att_idx == SVR_FFF6_TX_CFG) |
| { |
| sInstance.HandleTXCharCCCDRead(param); |
| } |
| #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING |
| if (r_req->att_idx == SVR_FFF6_C3_VALUE) |
| { |
| ChipLogProgress(DeviceLayer, "SVR_FFF6_OPT_VALUE!!!!\r\n"); |
| sInstance.HandleTXCharRead((void *) param); |
| } |
| #endif |
| break; |
| } |
| case BLE_5_TX_DONE: { |
| ChipLogProgress(DeviceLayer, "BLE_5_TX_DONE"); |
| #if 0 |
| tx_done_rsp_t* txd_rsp = (tx_done_rsp_t*)param; |
| if(txd_rsp) { |
| CHIPoBLEConState * conState = sInstance.GetConnectionState(txd_rsp->conn_idx,false); |
| if (conState != NULL) |
| { |
| sInstance.HandleTXCharConfirm(conState, txd_rsp->status); |
| } |
| } |
| #endif |
| CHIPoBLEConState * conState = sInstance.GetConnectionState(conn_idx, false); |
| if (conState != NULL) |
| { |
| sInstance.HandleTXCharConfirm(conState, 0); |
| } |
| } |
| break; |
| case BLE_5_MTU_CHANGE: { |
| ble_mtu_change_t * m_ind = (ble_mtu_change_t *) param; |
| ChipLogProgress(DeviceLayer, "m_ind:conn_idx:%d, mtu_size:%d\r\n", m_ind->conn_idx, m_ind->mtu_size); |
| CHIPoBLEConState * conState = sInstance.GetConnectionState(m_ind->conn_idx); |
| if (conState != NULL) |
| { |
| conState->mtu = (m_ind->mtu_size >= (1 << 10)) ? ((1 << 10) - 1) : m_ind->mtu_size; |
| } |
| break; |
| } |
| case BLE_5_CONNECT_EVENT: { |
| ble_conn_ind_t * c_ind = (ble_conn_ind_t *) param; |
| ChipLogProgress(DeviceLayer, "BLE GATT connection established (con %u)", c_ind->conn_idx); |
| ChipLogProgress(DeviceLayer, "c_ind:conn_idx:%d, addr_type:%d, peer_addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n", |
| c_ind->conn_idx, c_ind->peer_addr_type, c_ind->peer_addr[0], c_ind->peer_addr[1], c_ind->peer_addr[2], |
| c_ind->peer_addr[3], c_ind->peer_addr[4], c_ind->peer_addr[5]); |
| sInstance.mFlags.Clear(Flags::kBEKENBLEADVStarted); |
| CHIPoBLEConState * bleConnState = sInstance.GetConnectionState(c_ind->conn_idx, true); |
| if (bleConnState == NULL) |
| { |
| ChipLogError(DeviceLayer, "BLE_5_CONNECT_EVENT failed"); |
| int ext_evt = DriveBLEExtPerfEvt_DISCONNECT | (c_ind->conn_idx << 8); |
| PlatformMgr().ScheduleWork(DriveBLEExtPerf, ext_evt); |
| } |
| conn_idx = c_ind->conn_idx; |
| break; |
| } |
| case BLE_5_DISCONNECT_EVENT: { |
| ble_discon_ind_t * d_ind = (ble_discon_ind_t *) param; |
| ChipLogProgress(DeviceLayer, "d_ind:conn_idx:%d,reason:%d\r\n", d_ind->conn_idx, d_ind->reason); |
| sInstance.HandleGAPDisconnect(d_ind->conn_idx, d_ind->reason); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| break; |
| } |
| case BLE_5_ATT_INFO_REQ: { |
| ble_att_info_req_t * a_ind = (ble_att_info_req_t *) param; |
| ChipLogProgress(DeviceLayer, "a_ind:conn_idx:%d\r\n", a_ind->conn_idx); |
| if (SVR_FFF6_RX_VALUE == a_ind->att_idx) |
| { |
| a_ind->length = 512; |
| a_ind->status = BK_ERR_BLE_SUCCESS; |
| } |
| else if (SVR_FFF6_TX_CFG == a_ind->att_idx) |
| { |
| a_ind->length = 2; |
| a_ind->status = BK_ERR_BLE_SUCCESS; |
| } |
| break; |
| } |
| case BLE_5_CREATE_DB: { |
| ble_create_db_t * cd_ind = (ble_create_db_t *) param; |
| ChipLogProgress(DeviceLayer, "cd_ind:prf_id:%d, status:%d\r\n", cd_ind->prf_id, cd_ind->status); |
| sInstance.mFlags.Set(Flags::kBekenBLESGATTSReady); |
| PlatformMgr().ScheduleWork(DriveBLEState, 0); |
| break; |
| } |
| default: { |
| ChipLogProgress(DeviceLayer, "Unhandled event:%x", notice); |
| } |
| break; |
| } |
| } |
| |
| } // namespace Internal |
| } // namespace DeviceLayer |
| } // namespace chip |
| #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE |