blob: 37f9fea9b9106e59b007009317f3546638f26306 [file] [log] [blame]
/*
*
* 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