CSR3026开发问题总结-2

tech2024-10-20  8

添加ble gatt blood pressure功能 参考: 【蓝牙】如何新建一个BLE GATT SERVICE

其中上面blog中提到的 用生成的handle

Subject: [PATCH] add blood pressure --- TWS/apps/applications/earbud/av_headset.h | 107 ++++----- TWS/apps/applications/earbud/av_headset_db.db | 3 + TWS/apps/applications/earbud/av_headset_gatt.c | 182 ++++++++++++++- TWS/apps/applications/earbud/av_headset_gatt.h | 23 +- .../earbud/qcc512x_qcc302x/CF376_CF440/earbud.x2p | 4 +- .../profiles/default_qcc512x_qcc302x/library.h | 6 +- .../gatt_blood_pressure_server.c | 255 +++++++++++++++++++++ .../gatt_blood_pressure_server.h | 93 ++++++++ .../gatt_blood_pressure_server_db.dbi | 29 +++ .../gatt_blood_pressure_server_db.h | 22 ++ .../gatt_blood_pressure_server_uuids.h | 9 + TWS/apps/libs/library/library.h | 6 +- TWS/apps/libs/libs_qcc512x_qcc302x.x2p | 6 + TWS/apps/libs/libs_qcc512x_rom_v21.x2p | 6 + 14 files changed, 672 insertions(+), 79 deletions(-) create mode 100644 TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c create mode 100644 TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h create mode 100644 TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi create mode 100644 TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h create mode 100644 TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_uuids.h diff --git a/TWS/apps/applications/earbud/av_headset.h b/TWS/apps/applications/earbud/av_headset.h index de2ce49..afe63bc 100644 --- a/TWS/apps/applications/earbud/av_headset.h +++ b/TWS/apps/applications/earbud/av_headset.h @@ -14,11 +14,11 @@ Legal information <CENTER><b>Confidential and Proprietary – Qualcomm Technologies International, Ltd.</b></CENTER> -<b>NO PUBLIC DISCLOSURE PERMITTED:</b> Please report postings of this document on public servers or websites to: DocCtrlAgent@qualcomm.com. +<b>NO PUBLIC DISCLOSURE PERMITTED:</b> Please report postings of this document on public servers or websites to: DocCtrlAgent@qualcomm.com. <b>Restricted Distribution:</b> Not to be distributed to anyone who is not an employee of either Qualcomm Technologies International, Ltd. or its affiliated companies without the express approval of Qualcomm Configuration Management. -Not to be used, copied, reproduced, or modified in whole or in part, nor its contents revealed in any manner to others without the express written permission of Qualcomm Technologies International, Ltd. +Not to be used, copied, reproduced, or modified in whole or in part, nor its contents revealed in any manner to others without the express written permission of Qualcomm Technologies International, Ltd. All Qualcomm products mentioned herein are products of Qualcomm Technologies, Inc. and/or its subsidiaries. @@ -43,23 +43,23 @@ include @startuml - class init << (T,Green) >> #paleGreen { + class init << (T,Green) >> #paleGreen { Initialise the application .... Initialises all other modules at startup } - class led << (T,lightblue) >> { + class led << (T,lightblue) >> { Manages the LEDs } - class hfp << (T,lightblue) >> #Orange { - Manages HFP connections + class hfp << (T,lightblue) >> #Orange { + Manages HFP connections } - class ui << (T,lightblue) >> #Orange { - Manages the UI + class ui << (T,lightblue) >> #Orange { + Manages the UI } - class sm << (T,lightblue) >> #lightBlue { - Main application state machine + class sm << (T,lightblue) >> #lightBlue { + Main application state machine } class link_policy << (T,lightblue) >> { Manages the device link policy settings @@ -67,10 +67,10 @@ include class av << (T,lightblue) >> #Orange { Manages A2DP and AVRCP connections } - class charger << (T,lightblue) >> { + class charger << (T,lightblue) >> { Manages the charger } - class battery << (T,lightblue) >> { + class battery << (T,lightblue) >> { Manages the battery status } class temperature << (T,lightblue) >> { @@ -79,52 +79,52 @@ include class power << (T,lightblue) >> #Orange { Manages power, shutdown, sleep } - class pairing << (T,lightblue) >> #Orange { - Manages peer and handset pairing + class pairing << (T,lightblue) >> #Orange { + Manages peer and handset pairing } - class scanning << (T,lightblue) >> { - Manages the device scanning state + class scanning << (T,lightblue) >> { + Manages the device scanning state } - class device << (T,lightblue) >> { + class device << (T,lightblue) >> { Paired devices database } - class con_manager << (T,lightblue) >> { - Manages the device connection state machine + class con_manager << (T,lightblue) >> { + Manages the device connection state machine } - class peer_sig << (T,lightblue) >> { + class peer_sig << (T,lightblue) >> { Manages peer signalling messages } - class handset_sig << (T,lightblue) >> { - Manages the handset signalling messages + class handset_sig << (T,lightblue) >> { + Manages the handset signalling messages } - class phy_state << (T,lightblue) >> #Orange { + class phy_state << (T,lightblue) >> #Orange { Manages physcial state of the Earbud } - class kymera << (T,lightblue) >> { + class kymera << (T,lightblue) >> { Manages the audio subsystem } - class upgrade << (T,red) >> #lightGrey { - Manages the device upgrade + class upgrade << (T,red) >> #lightGrey { + Manages the device upgrade } - class proximity << (T,lightblue) >> { + class proximity << (T,lightblue) >> { Manages the proximity sensor } - class accelerometer << (T,lightblue) >> { + class accelerometer << (T,lightblue) >> { Manages the accelerometer } - class rules << (.,red) >> #yellow { - Application rules engine + class rules << (.,red) >> #yellow { + Application rules engine } - class chains << (.,red) >> #pink { - User defined audio chains + class chains << (.,red) >> #pink { + User defined audio chains } - class buttons << (.,red) >> #pink { - User defined button inputs + class buttons << (.,red) >> #pink { + User defined button inputs } - class peer_sync << (T,lightblue) >> { + class peer_sync << (T,lightblue) >> { Peer Earbud state synchronisation } - class scofwd << (T,lightblue) >> { + class scofwd << (T,lightblue) >> { SCO and MIC forwarding } @@ -201,7 +201,7 @@ include scofwd -l-> peer_sig : scofwd sig scofwd -u-> link_policy - @enduml + @enduml */ @@ -271,7 +271,7 @@ include enum { /*! Connecting reminder timeout */ - APP_INTERNAL_UI_CONNECTING_TIMEOUT= INTERNAL_MESSAGE_BASE, + APP_INTERNAL_UI_CONNECTING_TIMEOUT= INTERNAL_MESSAGE_BASE, APP_INTERNAL_UI_INQUIRY_TIMEOUT, /*!< Inquiry reminder timeout */ APP_INTERNAL_PAIRING_INIT }; @@ -357,30 +357,30 @@ typedef struct appTaskData advManagerTaskData adv_manager; /*!< Task information for the advertising manager */ } appTaskData; -/*! The global application data structure. +/*! The global application data structure. \note Do not access directly */ extern appTaskData globalApp; -/*! Get pointer to application data structure */ +/*! Get pointer to application data structure */ #define appGetApp() (&globalApp) -/*! Get pointer to application task */ +/*! Get pointer to application task */ #define appGetAppTask() (&globalApp.task) -/*! Get pointer to the system message task */ +/*! Get pointer to the system message task */ #define appGetSysTask() (&globalApp.systask) /*! Get pointer to init data structure */ #define appGetInit() (&globalApp.init) -/*! Get pointer to UI data structure */ +/*! Get pointer to UI data structure */ #define appGetUi() (&globalApp.ui) -/*! Get pointer to UI task */ +/*! Get pointer to UI task */ #define appGetUiTask() (&globalApp.ui.task) -/*! Get pointer to LED controller data structure */ +/*! Get pointer to LED controller data structure */ #define appGetLed() (&globalApp.led) /*! Get pointer to the proximity sensor data structure */ @@ -391,16 +391,16 @@ extern appTaskData globalApp; /*! Get pointer to the acceleromter data structure */ #define appGetAccelerometer() (&globalApp.accelerometer) -/*! Get pointer to Link Policy Manager data structure */ +/*! Get pointer to Link Policy Manager data structure */ #define appGetLp() (&globalApp.lp) -/*! Get pointer to CODEC task */ +/*! Get pointer to CODEC task */ #define appGetCodecTask() (globalApp.codec_task) -/*! Get pointer to HFP data structure */ +/*! Get pointer to HFP data structure */ #define appGetHfp() (&globalApp.hfp) -/*! Get pointer to HFP task */ +/*! Get pointer to HFP task */ #define appGetHfpTask() (&globalApp.hfp.task) /*! Get pointer to the GATT modules task data */ @@ -427,7 +427,10 @@ extern appTaskData globalApp; #define appGetGattBatteryServerRight(inst) (&appGetGattInstance(inst)->battery_server_right) #endif #define appGetHrTask() (&globalApp.gatt.gatt_hr_task) - +#define appGetBloodPressureTask() (&globalApp.gatt.gatt_blood_pressure_task) +#if defined(INCLUDE_GATT_BLOOD_PRESSURE) +#define appGetGattBPServerInst(inst) (&appGetGattInstance(inst)->bp_server) +#endif #if defined(INCLUDE_GATT_HR_SERVER) #define appGetGattHrServerInst(inst) (&appGetGattInstance(inst)->hr_server) @@ -480,12 +483,12 @@ extern appTaskData globalApp; #endif /* INCLUDE_DFU */ #ifdef INCLUDE_AV -/*! Get pointer to AV data structure */ +/*! Get pointer to AV data structure */ #define appGetAv() (&globalApp.av) #endif #ifdef INCLUDE_CHARGER -/*! Get pointer to charger data structure */ +/*! Get pointer to charger data structure */ #define appGetCharger() (&globalApp.charger) #endif diff --git a/TWS/apps/applications/earbud/av_headset_db.db b/TWS/apps/applications/earbud/av_headset_db.db index ba8e99a..03c53d7 100644 --- a/TWS/apps/applications/earbud/av_headset_db.db +++ b/TWS/apps/applications/earbud/av_headset_db.db @@ -22,3 +22,6 @@ ADD_BATTERY_SERVICE(2) #ifdef INCLUDE_GATT_HR_SERVER #include "gatt_heart_rate_server_db.dbi" #endif +#if defined(INCLUDE_GATT_BLOOD_PRESSURE) +#include "gatt_blood_pressure_server_db.dbi" +#endif diff --git a/TWS/apps/applications/earbud/av_headset_gatt.c b/TWS/apps/applications/earbud/av_headset_gatt.c index a8ff5ad..6de1073 100644 --- a/TWS/apps/applications/earbud/av_headset_gatt.c +++ b/TWS/apps/applications/earbud/av_headset_gatt.c @@ -83,7 +83,7 @@ static void appGattHandleGattExchangeMtuInd(GATT_EXCHANGE_MTU_IND_T* ind) GattExchangeMtuResponse(ind->cid, appConfigBleGattMtuMin()); } -/*! @brief Handle confirmation about GATT Manager registration. +/*! @brief Handle confirmation about GATT Manager registration. And set-up for resolvable addressing. */ @@ -151,8 +151,10 @@ bool appGattGoConnectable(void) #ifdef INCLUDE_GATT_HR_SERVER appAdvManagerSetService(advert,GATT_SERVICE_UUID_HEART_RATE); #endif + // appAdvManagerSetService(advert,GATT_SERVICE_UUID_BLOOD_PRESSURE); + adv_params.undirect_adv.filter_policy = ble_filter_none; - appConfigBleGetAdvertisingRate(appGetGatt()->advertising_mode, + appConfigBleGetAdvertisingRate(appGetGatt()->advertising_mode, &adv_params.undirect_adv.adv_interval_min, &adv_params.undirect_adv.adv_interval_max); appAdvManagerSetAdvertParams(advert, &adv_params); @@ -226,7 +228,7 @@ static void appGattHandleGattManRemoteClientConnectCfm(GATT_MANAGER_REMOTE_CLIEN // gattClientAdd(cfm->cid,ble_gap_role_peripheral); Does discovery. Not obvs useful. } else - { + { DEBUG_LOG("appGattHandleGattManRemoteClientConnectCfm. Unable to add new GATT client"); GattManagerDisconnectRequest(cfm->cid); } @@ -326,6 +328,8 @@ static void appGattHandleBattServerReadLevelInd(const GATT_BATTERY_SERVER_READ_L /* Return requested battery level */ GattBatteryServerReadLevelResponse(ind->battery_server, ind->cid, battery_percent); + GattBatteryServerSendLevelNotification(ind->battery_server, (uint16)0x0002, &ind->cid, 99); + } #define NAMESPACE_BLUETOOTH_SIG 0x01 /* Bluetooth SIG Namespace */ @@ -354,7 +358,7 @@ static void appGattHandleBatteryServerReadPresentationInd(const GATT_BATTERY_SER Panic(); } - DEBUG_LOG("appGattHandleBatteryServerReadPresentationInd bas=[0x%p] cid=[0x%x]\n", + DEBUG_LOG("appGattHandleBatteryServerReadPresentationInd bas=[0x%p] cid=[0x%x]\n", ind->battery_server,ind->cid); GattBatteryServerReadPresentationResponse(ind->battery_server, @@ -397,7 +401,7 @@ static void appGattHandleGattGapReadDeviceNameInd(const GATT_GAP_SERVER_READ_DEV DEBUG_LOG("appGattHandleGattGapReadDeviceNameInd"); - /* It is (barely) possible that there is not a local name set, + /* It is (barely) possible that there is not a local name set, in which case use a fallback */ if (!name) { @@ -509,7 +513,7 @@ static void appGattMessageHandler(Task task, MessageId id, Message message) /*! Handle CL_DM_BLE_CONFIGURE_LOCAL_ADDRESS_CFM message - This completes the library initialisation, so inform the application + This completes the library initialisation, so inform the application */ static void appGattHandleDmBleCconfigureLocalAddressCfm(CL_DM_BLE_CONFIGURE_LOCAL_ADDRESS_CFM_T *cfm) { @@ -534,8 +538,150 @@ bool appGattHandleConnectionLibraryMessages(MessageId id, Message message, bool } return already_handled; } +#if defined(INCLUDE_GATT_BLOOD_PRESSURE) +void sendSeanLevelAccessRsp(const SEANS *sean_server, uint16 cid, uint8 sean_level, uint16 result) +{ + DEBUG_LOG("SEAN: sendSeanLevelAccessRsp: result:%d\n", result); + + sendSeanAccessRsp((Task)&sean_server->lib_task, cid, HANDLE_SEAN_READ, result, 1, &sean_level); +} +void sendSeanLevelAccessRsp_2(const SEANS *sean_server, uint16 cid, uint8 sean_level, uint16 result) +{ + DEBUG_LOG("SEAN: sendSeanLevelAccessRsp: result:%d\n", result); + + sendSeanAccessRsp((Task)&sean_server->lib_task, cid, HANDLE_SEAN_NOTIFICATION, result, 2, &sean_level); +} + +bool GattSeanServerReadSthResponse(const SEANS *sean_server, uint16 cid, uint8 sean_level) +{ + DEBUG_LOG("SEAN: GattSeanServerReadSthResponse: sean_level:%d\n", sean_level); + + gatt_status_t status = gatt_status_failure; + + if (sean_server == NULL) + { + return FALSE; + } + + if (sean_level <= 0xff) + { + status = gatt_status_success; + } + else + { + status = gatt_status_insufficient_resources; + } + sendSeanLevelAccessRsp(sean_server, cid, sean_level, status); + + return TRUE; +} +bool GattSeanServerReadclientconfigResponse(const SEANS *sean_server, uint16 cid, uint16 sean_level) +{ + DEBUG_LOG("SEAN: GattSeanServerReadSthResponse: sean_level:%d\n", sean_level); + + gatt_status_t status = gatt_status_failure; + + if (sean_server == NULL) + { + return FALSE; + } + + if (sean_level <= 0xffff) + { + status = gatt_status_success; + } + else + { + status = gatt_status_insufficient_resources; + } + sendSeanLevelAccessRsp_2(sean_server, cid, sean_level, status); + + return TRUE; +} + +static uint8 i = 0; + +static void appGattHandleSeanServerReadSthInd(const GATT_SEAN_SERVER_READ_STH_IND_T * ind) +{ + uint8 return_value = 0xAA; + if (i%2 == 1)return_value = 0xBB; + else return_value = 0xAA; + DEBUG_LOG("SEAN: appGattHandleSeanServerReadSthInd bas=[0x%p] cid=[0x%x]\n", (void *)ind->sean_server, ind->cid); + + DEBUG_LOG("SEAN: Return value =[%u]\n", return_value); + i++; + if (i == 100)i = 0; + /* Return requested battery level */ + GattSeanServerReadSthResponse(ind->sean_server, ind->cid, return_value); +} +static void appGattHandleSeanServerReadclientconfigInd(const GATT_SEAN_SERVER_READ_STH_IND_T * ind) +{ + uint16 return_value = 0xAAAA; + if (i%2 == 1)return_value = 0xBBBB; + else return_value = 0xAAAA; + DEBUG_LOG("SEAN: appGattHandleSeanServerReadSthInd bas=[0x%p] cid=[0x%x]\n", (void *)ind->sean_server, ind->cid); + + DEBUG_LOG("SEAN: Return value =[%u]\n", return_value); + i++; + if (i == 100)i = 0; + /* Return requested battery level */ + GattSeanServerReadclientconfigResponse(ind->sean_server, ind->cid, return_value); +} +#if 0 +static void appGattHandleSeanServerReadClientConfig(const GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T *ind) +{ + DEBUG_LOG("SEAN: appGattHandleSeanServerReadClientConfig Return value =[%u]\n", ind->config_value); + //global_sean_server = ind->sean_server; + cur_cid = ind->cid; +} +#endif +static void appGattHandleSeanServerWriteSth(const GATT_SEAN_SERVER_WRITE_STH_IND_T * ind) +{ + uint16 client_config = 0; + + client_config = ind->write_value ; + // client_config = 0x98; + DEBUG_LOG("SEAN: appGattHandleSeanServerWriteSth, write_value=[0x%x] cid=[0x%x]\n", client_config,ind->cid); + GattSeanServerWriteToNofityResponse(ind->sean_server, ind->cid, client_config); + +} + +void appGattSeanMessageHandler(Task task, MessageId id, Message message) +{ + UNUSED(task); + + DEBUG_LOG("SEAN: appGattSeanMessageHandler id:%d 0x%x", id, id); + switch (id) + { + case GATT_SEAN_SERVER_READ_STH_IND: + //TODO: DO STH HERE! + appGattHandleSeanServerReadSthInd((const GATT_SEAN_SERVER_READ_STH_IND_T *) message); + break; + case GATT_SEAN_SERVER_WRITE_STH_IND: + appGattHandleSeanServerWriteSth((const GATT_SEAN_SERVER_WRITE_STH_IND_T *)message); + DEBUG_LOG("SEAN: appGattSeanMessageHandler:GATT_SEAN_SERVER_READ_STH_IND_T++"); + + appGattHandleSeanServerReadclientconfigInd((const GATT_SEAN_SERVER_READ_STH_IND_T *) message); + + DEBUG_LOG("SEAN: appGattSeanMessageHandler:GATT_SEAN_SERVER_READ_STH_IND_T--"); + break; + case GATT_SEAN_SERVER_READ_CLIENT_CONFIG_IND: + DEBUG_LOG("SEAN: appGattSeanMessageHandler:GATT_SEAN_SERVER_READ_CLIENT_CONFIG_IND"); + appGattHandleSeanServerReadclientconfigInd((const GATT_SEAN_SERVER_READ_STH_IND_T *) message); + break; + case GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND: + DEBUG_LOG("SEAN: appGattSeanMessageHandler:GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND cid=[0x%x]",((const GATT_SEAN_SERVER_READ_STH_IND_T *) message)->cid); + // appGattHandleSeanServerReadClientConfig((const GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T *)message); + + break; + default: + DEBUG_LOG("SEAN: appGattSeanMessageHandler. Unhandled message id:0x%x", id); + break; + } +} +#endif #ifdef INCLUDE_GATT_BATTERY_SERVER static void appGattBatteryMessageHandler(Task task, MessageId id, Message message) { @@ -597,7 +743,9 @@ void appGattInit(void) #ifdef INCLUDE_GATT_BATTERY_SERVER gatt->gatt_battery_task.handler = appGattBatteryMessageHandler; #endif - +#if defined(INCLUDE_GATT_BLOOD_PRESSURE) + gatt->gatt_blood_pressure_task.handler = appGattSeanMessageHandler; +#endif /* Initialise the GATT Manager */ if (!GattManagerInit(appGetGattTask())) { @@ -619,8 +767,8 @@ void appGattInit(void) #endif for (gatt_instance = 0; gatt_instance < appConfigBleGetGattServerInstances(); gatt_instance++) { - if (GattServerInit(appGetGattServerInst(gatt_instance), appGetGattTask(), - HANDLE_GATT_SERVICE, HANDLE_GATT_SERVICE_END) + if (GattServerInit(appGetGattServerInst(gatt_instance), appGetGattTask(), + HANDLE_GATT_SERVICE, HANDLE_GATT_SERVICE_END) != gatt_server_status_success) { DEBUG_LOG("APP:GATT: GATT server init failed"); @@ -628,7 +776,7 @@ void appGattInit(void) } if (GattGapServerInit(appGetGattGapServerInst(gatt_instance), appGetGattGapTask(), - HANDLE_GAP_SERVICE, HANDLE_GAP_SERVICE_END) + HANDLE_GAP_SERVICE, HANDLE_GAP_SERVICE_END) != gatt_gap_server_status_success) { DEBUG_LOG("APP:GATT: GAP server init failed"); @@ -637,7 +785,7 @@ void appGattInit(void) #ifdef INCLUDE_GATT_BATTERY_SERVER if (!GattBatteryServerInit(appGetGattBatteryServerLeft(gatt_instance), - appGetGattBatteryTask(), &battery_server_params, + appGetGattBatteryTask(), &battery_server_params, HANDLE_BATTERY_SERVICE1, HANDLE_BATTERY_SERVICE1_END)) { DEBUG_LOG("APP:GATT: GATT battery server init (left) failed"); @@ -645,7 +793,7 @@ void appGattInit(void) } if (!GattBatteryServerInit(appGetGattBatteryServerRight(gatt_instance), - appGetGattBatteryTask(), &battery_server_params, + appGetGattBatteryTask(), &battery_server_params, HANDLE_BATTERY_SERVICE2, HANDLE_BATTERY_SERVICE2_END)) { DEBUG_LOG("APP:GATT: GATT battery server init (right) failed"); @@ -658,6 +806,16 @@ void appGattInit(void) #endif #ifdef INCLUDE_GATT_HR_SERVER GattHrServerInit(appGetHrTask(),appGetGattHrServerInst(gatt_instance),HANDLE_HEART_RATE_SERVICE,HANDLE_HEART_RATE_SERVICE_END); +#endif +#if defined(INCLUDE_GATT_BLOOD_PRESSURE) + + gatt_sean_server_init_params_t bloodpressure_server_params = {.enable_notifications = TRUE}; + + GattSeanServerInit(appGetGattBPServerInst(gatt_instance), + appGetBloodPressureTask(), + &bloodpressure_server_params, + HANDLE_SEAN_SERVICE, + HANDLE_SEAN_SERVICE_END); #endif } /* complete registration of servers */ diff --git a/TWS/apps/applications/earbud/av_headset_gatt.h b/TWS/apps/applications/earbud/av_headset_gatt.h index 16c07ef..8dcd3a9 100644 --- a/TWS/apps/applications/earbud/av_headset_gatt.h +++ b/TWS/apps/applications/earbud/av_headset_gatt.h @@ -16,7 +16,7 @@ #include <gatt_gap_server.h> #include <gatt_battery_server.h> #include <gatt_heart_rate_server.h> - +#include <gatt_blood_pressure_server.h> /*! Messages sent by the av_headset_gatt module */ typedef enum { APP_GATT_INIT_CFM = APP_GATT_MESSAGE_BASE, /*!< Application GATT module has initialised */ @@ -26,7 +26,7 @@ typedef enum { } av_headet_gatt_messages; -/*! GATT Client Configuration attributes that need to be stored per remote client +/*! GATT Client Configuration attributes that need to be stored per remote client @note This is a server only structure */ @@ -64,6 +64,9 @@ typedef struct #ifdef INCLUDE_GATT_HR_SERVER GHRS_T hr_server; #endif +#if defined(INCLUDE_GATT_BLOOD_PRESSURE) + SEANS bp_server; +#endif } gattGattServerInfo; @@ -77,6 +80,8 @@ typedef struct TaskData gatt_battery_task; TaskData gatt_hr_task; + + TaskData gatt_blood_pressure_task; /*! Advertising rate to use when connecting */ appConfigBleAdvertisingMode advertising_mode; @@ -93,7 +98,7 @@ COMPILE_TIME_ASSERT(1==appConfigBleGetGattServerInstances(),double_check_multipl /*! Start a BLE connection Starts advertising to make a new connection as a peripheral. The message - APP_GATT_CONNECTABLE will be sent when advertising is started. And + APP_GATT_CONNECTABLE will be sent when advertising is started. And APP_GATT_CONNECTION_MADE if a connection is made. \returns FALSE if there is an existing connection, TRUE otherwise @@ -106,7 +111,7 @@ bool appGattGoConnectable(void); and the application logic currently allows a connection then advertising will be started. - If there is an existin BLE connection, or advertising is in progress, and + If there is an existin BLE connection, or advertising is in progress, and connections are no longer allowed - then the BLE activity will be stopped. \param allow Enable or disable BLE connection @@ -115,7 +120,7 @@ bool appGattGoConnectable(void); */ bool appGattAllowBleConnections(bool allow); -/*! Does the GATT module have a BLE connection +/*! Does the GATT module have a BLE connection \return TRUE if there is a BLE connection */ #define appGattHasBleConnection() (0 != appGetGatt()->instance[0].conn_id) @@ -139,13 +144,13 @@ void appGattSetAdvertisingMode(appConfigBleAdvertisingMode mode); /*! Handler for connection library messages not sent directly This function is called to handle any connection library messages sent to - the application that the GATT module is interested in. If a message + the application that the GATT module is interested in. If a message is processed then the function returns TRUE. - \note Some connection library messages can be sent directly as the + \note Some connection library messages can be sent directly as the request is able to specify a destination for the response. - \param id Identifier of the connection library message + \param id Identifier of the connection library message \param message The message content (if any) \param already_handled Indication whether this message has been processed by another module. The handler may choose to ignore certain @@ -157,7 +162,7 @@ void appGattSetAdvertisingMode(appConfigBleAdvertisingMode mode); bool appGattHandleConnectionLibraryMessages(MessageId id, Message message, bool already_handled); -/*! @brief Initialise the GATT component. +/*! @brief Initialise the GATT component. */ void appGattInit(void); diff --git a/TWS/apps/applications/earbud/qcc512x_qcc302x/CF376_CF440/earbud.x2p b/TWS/apps/applications/earbud/qcc512x_qcc302x/CF376_CF440/earbud.x2p index 7b0a062..2d3e323 100644 --- a/TWS/apps/applications/earbud/qcc512x_qcc302x/CF376_CF440/earbud.x2p +++ b/TWS/apps/applications/earbud/qcc512x_qcc302x/CF376_CF440/earbud.x2p @@ -12,13 +12,13 @@ <property name="CHIP_TYPE">qcc512x_qcc302x</property> <property name="DBG_CORE">app/p1</property> <property name="DEFAULT_LIBS">usb_early_init</property> - <property name="DEFS">AV_DEBUG BLUELAB CF376_CF440 DEBUG HAVE_1_BUTTON HAVE_32BIT_DATA_WIDTH HAVE_3_LEDS HAVE_THERMISTOR HYDRA HYDRACORE INCLUDE_AV INCLUDE_CHARGER INCLUDE_DFU INCLUDE_GATT INCLUDE_GATT_BATTERY_SERVER INCLUDE_GATT_GAIA_SERVER INCLUDE_HFP INCLUDE_MICFWD INCLUDE_PROMPTS INCLUDE_SCOFWD INCLUDE_TEMPERATURE INCLUDE_TONES INSTALL_HYDRA_LOG THERMISTOR_ADC=adcsel_led5 THERMISTOR_DATA_FILE=thermistor_lp4549652p3m.h THERMISTOR_ON=THERMISTOR_PIO_UNUSED USE_BDADDR_FOR_LEFT_RIGHT __KALIMBA__</property> + <property name="DEFS">AV_DEBUG BLUELAB CF376_CF440 DEBUG HAVE_1_BUTTON HAVE_32BIT_DATA_WIDTH HAVE_3_LEDS HAVE_THERMISTOR HYDRA HYDRACORE INCLUDE_AV INCLUDE_CHARGER INCLUDE_DFU INCLUDE_GATT INCLUDE_GATT_BATTERY_SERVER INCLUDE_GATT_GAIA_SERVER INCLUDE_GATT_BLOOD_PRESSURE INCLUDE_HFP INCLUDE_MICFWD INCLUDE_PROMPTS INCLUDE_SCOFWD INCLUDE_TEMPERATURE INCLUDE_TONES INSTALL_HYDRA_LOG THERMISTOR_ADC=adcsel_led5 THERMISTOR_DATA_FILE=thermistor_lp4549652p3m.h THERMISTOR_ON=THERMISTOR_PIO_UNUSED USE_BDADDR_FOR_LEFT_RIGHT __KALIMBA__</property> <property name="EXTRA_WARNINGS">FALSE</property> <property name="FLASH_CONFIG">..\..\64Mbit_default_flash_config.py</property> <property name="HW_VARIANT">CF376_CF440</property> <property name="INCPATHS">../../../../installed_libs\include\firmware_qcc512x_qcc302x ../../../../installed_libs\include\firmware_qcc512x_qcc302x/app ../../../../installed_libs\include\profiles\default_qcc512x_qcc302x ../../../../installed_libs\include\standard ../../chains sdk://audio/kalimba/kymera/common/interface/gen/k32</property> <property name="LIBPATHS">../../../../installed_libs\lib\default_qcc512x_qcc302x\native ../../../../installed_libs\lib\os\qcc512x_qcc302x</property> - <property name="LIBS">a2dp anc audio_plugin_common audio_processor avrcp bdaddr byte_utils chain connection cryptovm custom_operator file_list gaia gain_utils gatt gatt_battery_server gatt_gap_server gatt_manager gatt_server hfp input_event_manager logging operators packetiser_helper pio_common region rtime rwcp_server sdp_parse service system_clock transport_adaptation transport_manager upgrade usb_device_class vmal gatt_heart_rate_server</property> + <property name="LIBS">a2dp anc audio_plugin_common audio_processor avrcp bdaddr byte_utils chain connection cryptovm custom_operator file_list gaia gain_utils gatt gatt_battery_server gatt_gap_server gatt_manager gatt_server hfp input_event_manager logging operators packetiser_helper pio_common region rtime rwcp_server sdp_parse service system_clock transport_adaptation transport_manager upgrade usb_device_class vmal gatt_heart_rate_server gatt_blood_pressure_server</property> <property name="OUTPUT">earbud</property> <property name="OUTPUT_TYPE">EXECUTABLE</property> <property name="PRESERVED_LIBS">qcc512x_qcc302x</property> diff --git a/TWS/apps/installed_libs/include/profiles/default_qcc512x_qcc302x/library.h b/TWS/apps/installed_libs/include/profiles/default_qcc512x_qcc302x/library.h index bc7a218..690eee3 100644 --- a/TWS/apps/installed_libs/include/profiles/default_qcc512x_qcc302x/library.h +++ b/TWS/apps/installed_libs/include/profiles/default_qcc512x_qcc302x/library.h @@ -64,7 +64,7 @@ all ADK libraries. /*! @brief Default reserved service channel */ #define RESERVED_DEFAULT_CHANNEL (0x0E) -/*! Base values for library messages +/*! Base values for library messages */ @@ -164,7 +164,7 @@ all ADK libraries. messages are handled by default in the main task. Consequently the NFC_CL_MESSAGE_BASE SHOULD NOT be the same value as another base handled in the main task. Its value can be changed. - + @warning NFC_MESSAGE_BASE is used for the NFC_API and CAN NOT be changed. The NFC API messages are handled by default in NFC_CL task. If NFC_CL task is overridden by the main task then 0x7E00 SHOULD NOT be use by other base. @@ -185,6 +185,8 @@ all ADK libraries. /*! @brief Message base for transport manager libraries*/ #define TRANSPORT_MGR_MESSAGE_BASE 0x7F7A #define VA_AUDIO_MGR_MESSAGE_BASE 0x7F80 +#define GATT_SEAN_SERVER_MESSAGE_BASE 0x7F90 + #endif /* _LIBRARY_H */ /*@}*/ diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c new file mode 100644 index 0000000..8ac6381 --- /dev/null +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c @@ -0,0 +1,255 @@ +#include "gatt_blood_pressure_server.h" +#include "gatt_blood_pressure_server_db.h" +void sendSeanAccessRsp(Task task, + uint16 cid, + uint16 handle, + uint16 result, + uint16 size_value, + const uint8 *value) +{ + if (!GattManagerServerAccessResponse(task, cid, handle, result, size_value, value)) + { + /* The GATT Manager should always know how to send this response */ + GATT_SEAN_SERVER_DEBUG_PANIC(("Couldn't send GATT access response\n")); + } +} + +static void sendSeanAccessErrorRsp(const SEANS *sean_server, const GATT_MANAGER_SERVER_ACCESS_IND_T *access_ind, uint16 error) +{ + sendSeanAccessRsp((Task)&sean_server->lib_task, access_ind->cid, access_ind->handle, error, 0, NULL); +} + +static void seanServiceAccess(SEANS *sean_server, const GATT_MANAGER_SERVER_ACCESS_IND_T *access_ind) +{ + if (access_ind->flags & ATT_ACCESS_READ) + { + sendSeanAccessRsp((Task)&sean_server->lib_task, access_ind->cid, HANDLE_SEAN_SERVICE, gatt_status_success, 0, NULL); + } + else if (access_ind->flags & ATT_ACCESS_WRITE) + { + /* Write of battery level not allowed. */ + sendSeanAccessErrorRsp(sean_server, access_ind, gatt_status_write_not_permitted); + } + else + { + /* Reject access requests that aren't read/write, which shouldn't happen. */ + sendSeanAccessErrorRsp(sean_server, access_ind, gatt_status_request_not_supported); + } +} +static void readSthAccess(SEANS *sean_server, const GATT_MANAGER_SERVER_ACCESS_IND_T *access_ind) +{ + PRINT("SEAN: readSthAccess\n"); + // UNUSED(sean_server); + // UNUSED(access_ind); + if (access_ind->flags & ATT_ACCESS_READ) + { + PRINT("SEAN: readSthAccess: ATT_ACCESS_READ\n"); + /* Send read level message to app_task so it can return the current level */ + MAKE_SEAN_MESSAGE(GATT_SEAN_SERVER_READ_STH_IND); + message->sean_server = sean_server; /* Pass the instance which can be returned in the response */ + message->cid = access_ind->cid; /* Pass the CID which can be returned in the response */ + MessageSend(sean_server->app_task, GATT_SEAN_SERVER_READ_STH_IND, message); + } + else if (access_ind->flags & ATT_ACCESS_WRITE) + { + PRINT("SEAN: readSthAccess: ATT_ACCESS_WRITE\n"); + /* Send read level message to app_task so it can return the current level */ + MAKE_SEAN_MESSAGE(GATT_SEAN_SERVER_WRITE_STH_IND); + message->sean_server = sean_server; /* Pass the instance which can be returned in the response */ + message->cid = access_ind->cid; /* Pass the CID which can be returned in the response */ + message->write_value = (access_ind->value[0]) + (access_ind->value[1]<<8); +// sendSeanNotificationRsp((Task)&sean_server->lib_task, access_ind->cid, HANDLE_SEAN_CLIENT_CONFIG_MESSAGE, GATT_CLIENT_CONFIG_OCTET_SIZE, access_ind->value); + MessageSend(sean_server->app_task, GATT_SEAN_SERVER_WRITE_STH_IND, message); + sendSeanAccessRsp((Task)&sean_server->lib_task, access_ind->cid, access_ind->handle, gatt_status_success, 0, NULL); + //DEBUG_LOG("SEAN: WRITE VALUE: %02x%02x\n", access_ind->value[0], access_ind->value[1]); + + } + else + { + /* Reject access requests that aren't read/write, which shouldn't happen. */ + sendSeanAccessErrorRsp(sean_server, access_ind, gatt_status_request_not_supported); + } +} +static void seanConfigAccess(SEANS *seanserver, const GATT_MANAGER_SERVER_ACCESS_IND_T *access_ind) +{ + if (access_ind->flags & ATT_ACCESS_READ) + { + /* On a Read, ask the app for current client config value */ + MAKE_SEAN_MESSAGE(GATT_SEAN_SERVER_READ_CLIENT_CONFIG_IND); + message->sean_server = seanserver; /* Pass the instance which can be returned in the response */ + message->cid = access_ind->cid; /* Pass the CID so the client can be identified */ + MessageSend(seanserver->app_task, GATT_SEAN_SERVER_READ_CLIENT_CONFIG_IND, message); + } + else if (access_ind->flags & ATT_ACCESS_WRITE) + { + if (access_ind->size_value == GATT_CLIENT_CONFIG_OCTET_SIZE) + { + /* On a Write, send new client config value to the app */ + MAKE_SEAN_MESSAGE(GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND); + message->sean_server = seanserver; + message->cid = access_ind->cid; + message->config_value = (access_ind->value[0] & 0xFF) | ((access_ind->value[1] << 8) & 0xFF00); + MessageSend(seanserver->app_task, GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND, message); + /* Library response to the access request */ + sendSeanAccessRsp(&seanserver->lib_task, access_ind->cid, access_ind->handle, gatt_status_success, 0, NULL); + + } + else + { + sendSeanAccessErrorRsp(seanserver, access_ind, gatt_status_invalid_length); + } + } + else + { + /* Reject access requests that aren't read/write, which shouldn't happen. */ + sendSeanAccessErrorRsp(seanserver, access_ind, gatt_status_request_not_supported); + } +} +static void handleSeanAccess(SEANS *sean_server, const GATT_MANAGER_SERVER_ACCESS_IND_T *access_ind) +{ + switch (access_ind->handle) + { + case HANDLE_SEAN_SERVICE: + { + PRINT("SEAN: handleSeanAccess: HANDLE_SEAN_SERVICE_MESSAGE\n"); + seanServiceAccess(sean_server, access_ind); + } + break; + + case HANDLE_SEAN_READ: + { + PRINT("SEAN: handleSeanAccess: HANDLE_SEAN_READ_MESSAGE\n"); + readSthAccess(sean_server, access_ind); + } + break; + + case HANDLE_SEAN_WRITE: + { + PRINT("SEAN: handleSeanAccess: HANDLE_SEAN_WRITE_MESSAGE\n"); + readSthAccess(sean_server, access_ind); + } + break; + + case HANDLE_SEAN_NOTIFICATION: + { + PRINT("SEAN: handleSeanAccess: HANDLE_SEAN_CLIENT_CONFIG_MESSAGE\n"); + seanConfigAccess(sean_server, access_ind); + } + + break; + + default: + { + /* Respond to invalid handles */ + sendSeanAccessErrorRsp(sean_server, access_ind, gatt_status_invalid_handle); + } + break; + } +} + +static void seanServerMsgHandler(Task task,MessageId id,Message payload) +{ + //DEBUG_LOG("SEAN: seanServerMsgHandler, id: %d\n", id); + SEANS *sean_server = (SEANS *)task; + + switch (id) + { + case GATT_MANAGER_SERVER_ACCESS_IND: + { + /* Read/write access to characteristic */ + handleSeanAccess(sean_server,(GATT_MANAGER_SERVER_ACCESS_IND_T *)payload); + } + break; + case GATT_MANAGER_REMOTE_CLIENT_NOTIFICATION_CFM: + { + /* Library just absorbs confirmation messages */ + } + break; + default: + { + /* Unrecognised GATT Manager message */ + GATT_SEAN_SERVER_DEBUG_PANIC(("SEAN: GATT Manager Server Msg not handled\n")); + } + break; + } +} +bool GattSeanServerInit(SEANS *sean_server, + Task app_task, + const gatt_sean_server_init_params_t *init_params, + uint16 start_handle, + uint16 end_handle) +{ +// DEBUG_LOG("SEAN: GattSeanServerInit\n"); + + gatt_manager_server_registration_params_t registration_params; + + if ((app_task == NULL) || (sean_server == NULL)) + { + GATT_SEAN_SERVER_PANIC(("SEANS: Invalid Initialisation parameters")); + return FALSE; + } + + /* Set up library handler for external messages */ + sean_server->lib_task.handler = seanServerMsgHandler; + + /* Store the Task function parameter. + All library messages need to be sent here */ + sean_server->app_task = app_task; + + /* Check optional initialisation parameters */ + /* When GATT_MANAGER_USE_CONST_DB is enabled then it is the callers responsibility + * to register the appropriate GATT battery server configuration when the + * const database is registered. + */ + if (init_params) + { + /* Store notifications enable flag */ + sean_server->notifications_enabled = init_params->enable_notifications; + } + else + { + sean_server->notifications_enabled = FALSE; + } + + /* Setup data required for Battery Service to be registered with the GATT Manager */ + registration_params.task = &sean_server->lib_task; + registration_params.start_handle = start_handle; + registration_params.end_handle = end_handle; + + /* Register with the GATT Manager and verify the result */ + return (GattManagerRegisterServer(&registration_params) == gatt_manager_status_success); +} +static void sendSeanNotificationRsp(Task task, + uint16 cid, + uint16 handle, + uint16 size_value, + const uint8 *value) +{ + PRINT("SEAN: sendSeanNotificationRsp++\n"); + GattManagerRemoteClientNotify(task, cid, handle, size_value, value); + + PRINT("SEAN: sendSeanNotificationRsp--\n"); +} +void sendSeanConfigAccessRsp(const SEANS *sean_server, uint16 cid, uint16 client_config) +{ + uint8 config_resp[GATT_CLIENT_CONFIG_OCTET_SIZE]; + + config_resp[0] = client_config & 0xFF; + config_resp[1] = (client_config >> 8) & 0xFF; + sendSeanNotificationRsp((Task)&sean_server->lib_task, cid, HANDLE_SEAN_READ, 1, config_resp); + +} +bool GattSeanServerWriteToNofityResponse(const SEANS *sean_server, uint16 cid, uint16 client_config) +{ + PRINT("SEAN: GattSeanServerReadClientConfigResponse\n"); + if (sean_server == NULL) + { + return FALSE; + } + PRINT("SEAN: GattSeanServerReadClientConfigResponse 2\n"); + + sendSeanConfigAccessRsp(sean_server, cid, client_config); + + return TRUE; +} + diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h new file mode 100644 index 0000000..10ef0a7 --- /dev/null +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h @@ -0,0 +1,93 @@ +#ifndef GATT_BLOOD_PRESSURE_SERVER_H_ +#define GATT_BLOOD_PRESSURE_SERVER_H_ +#include "gatt_manager.h" +#include <panic.h> +#include <print.h> +#include <stdio.h> +#include <stdlib.h> +#include <csrtypes.h> +#include <message.h> +#include <library.h> + +#define GATT_CLIENT_CONFIG_OCTET_SIZE sizeof(uint8) * 2 + +typedef enum +{ + /* Server messages */ + GATT_SEAN_SERVER_READ_STH_IND = GATT_SEAN_SERVER_MESSAGE_BASE, /* 00 */ + GATT_SEAN_SERVER_WRITE_STH_IND, /* 01 */ + GATT_SEAN_SERVER_READ_CLIENT_CONFIG_IND, + GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND, + /* Library message limit */ + GATT_SEAN_SERVER_MESSAGE_TOP +} gatt_sean_server_message_id_t; +//#ifdef DEBUG_LOG +//#undef DEBUG_LOG +//#define DEBUG_LOG(x) PRINT(x) +//#endif +#define GATT_SEAN_SERVER_DEBUG_INFO(x) {PRINT(("%s:%d - ", __FILE__, __LINE__)); PRINT(x);} +#define GATT_SEAN_SERVER_DEBUG_PANIC(x) {GATT_SEAN_SERVER_DEBUG_INFO(x); Panic();} +#define GATT_SEAN_SERVER_PANIC(x) {GATT_SEAN_SERVER_DEBUG_INFO(x); Panic();} + +typedef struct __SEANS +{ + TaskData lib_task; + Task app_task; + bool notifications_enabled; +} SEANS; +typedef struct +{ + bool enable_notifications; /*! Flag that can be used to enable or disable notifications */ +} gatt_sean_server_init_params_t; +typedef struct __GATT_SEAN_SERVER_READ_STH_IND +{ + const SEANS *sean_server; + uint16 cid; +} GATT_SEAN_SERVER_READ_STH_IND_T; +typedef struct __GATT_SEAN_SERVER_WRITE_STH_IND +{ + const SEANS *sean_server; + uint16 cid; + uint16 write_value; +} GATT_SEAN_SERVER_WRITE_STH_IND_T; +typedef struct __GATT_SEAN_SERVER_READ_CLIENT_CONFIG_IND +{ + const SEANS *sean_server; + uint16 cid; +} GATT_SEAN_SERVER_READ_CLIENT_CONFIG_IND_T; + +/*! @brief Contents of the GATT_BATTERY_SERVER_WRITE_CLIENT_CONFIG_IND message that is sent by the library, + due to a write of the local battery level client configuration characteristic. + */ +typedef struct __GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND +{ + const SEANS *sean_server; + uint16 cid; + uint16 config_value; +} GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T; +#define MAKE_SEAN_MESSAGE(TYPE) TYPE##_T *message = (TYPE##_T*)PanicNull(calloc(1,sizeof(TYPE##_T))) +#define MAKE_SEAN_MESSAGE_WITH_LEN(TYPE, LEN) TYPE##_T *message = (TYPE##_T *) PanicNull(calloc(1,sizeof(TYPE##_T) + ((LEN) - 1) * sizeof(uint8))) + + +void sendSeanAccessRsp(Task task, + uint16 cid, + uint16 handle, + uint16 result, + uint16 size_value, + const uint8 *value); +void sendSeanLevelAccessRsp(const SEANS *sean_server, uint16 cid, uint8 sean_level, uint16 result); +bool GattSeanServerReadSthResponse(const SEANS *sean_server, uint16 cid, uint8 sean_level); +void appGattSeanMessageHandler(Task task, MessageId id, Message message); + +void sendSeanConfigAccessRsp(const SEANS *sean_server, uint16 cid, uint16 client_config); +void sendSeanLevelAccessRsp_2(const SEANS *sean_server, uint16 cid, uint8 sean_level, uint16 result); +bool GattSeanServerReadclientconfigResponse(const SEANS *sean_server, uint16 cid, uint16 sean_level); +bool GattSeanServerWriteToNofityResponse(const SEANS *sean_server, uint16 cid, uint16 client_config); + +bool GattSeanServerInit(SEANS *sean_server, + Task app_task, + const gatt_sean_server_init_params_t *init_params, + uint16 start_handle, + uint16 end_handle); + +#endif diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi new file mode 100644 index 0000000..3a6f9b5 --- /dev/null +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi @@ -0,0 +1,29 @@ +#ifndef __GATT_SEAN_SERVER_DB_DBI__ +#define __GATT_SEAN_SERVER_DB_DBI__ + +#include "gatt_blood_pressure_server_uuids.h" + +primary_service { + uuid : UUID_SEAN_SERVICE, + name : "SEAN_SERVICE", + characteristic { + uuid : UUID_SEAN_READ, + name : "SEAN_READ", + flags : [ FLAG_IRQ , FLAG_DYNLEN ], + properties : [ read , notify ], + value : 0x0, + client_config { + flags : [ FLAG_IRQ , FLAG_DYNLEN ], + name : "SEAN_NOTIFICATION" + } + }, + + characteristic { + uuid : UUID_SEAN_WRITE, + name : "SEAN_WRITE", + flags : [ FLAG_IRQ , FLAG_DYNLEN ], + properties : [ write ], + value : 0x0 + } +}, +#endif /* __GATT_SEAN_SERVER_DB_DBI__ */ diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h new file mode 100644 index 0000000..46489df --- /dev/null +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h @@ -0,0 +1,22 @@ +/* + * THIS FILE IS AUTOGENERATED, DO NOT EDIT! + * + * generated by gattdbgen from gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi_ + */ +#ifndef __GATT_BLOOD_PRESSURE_SERVER_DB_H +#define __GATT_BLOOD_PRESSURE_SERVER_DB_H + +#include <csrtypes.h> + +#define HANDLE_SEAN_SERVICE (0x0001) +#define HANDLE_SEAN_SERVICE_END (0xffff) +#define HANDLE_SEAN_READ (0x0003) +#define HANDLE_SEAN_NOTIFICATION (0x0004) +#define HANDLE_SEAN_WRITE (0x0006) + +uint16 *GattGetDatabase(uint16 *len); +uint16 GattGetDatabaseSize(void); + +#endif + +/* End-of-File */ diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_uuids.h b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_uuids.h new file mode 100644 index 0000000..fcca7ec --- /dev/null +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_uuids.h @@ -0,0 +1,9 @@ +#ifndef __SEAN_UUIDS_H__ +#define __SEAN_UUIDS_H__ + +#define UUID_SEAN_SERVICE 0x1810 +#define UUID_SEAN_READ 0x2A35 +#define UUID_SEAN_WRITE 0x2A49 +//#define UUID_SEAN_NOTIFY 0x2A35 + +#endif /* __SEAN_UUIDS_H__ */ diff --git a/TWS/apps/libs/library/library.h b/TWS/apps/libs/library/library.h index bc7a218..690eee3 100644 --- a/TWS/apps/libs/library/library.h +++ b/TWS/apps/libs/library/library.h @@ -64,7 +64,7 @@ all ADK libraries. /*! @brief Default reserved service channel */ #define RESERVED_DEFAULT_CHANNEL (0x0E) -/*! Base values for library messages +/*! Base values for library messages */ @@ -164,7 +164,7 @@ all ADK libraries. messages are handled by default in the main task. Consequently the NFC_CL_MESSAGE_BASE SHOULD NOT be the same value as another base handled in the main task. Its value can be changed. - + @warning NFC_MESSAGE_BASE is used for the NFC_API and CAN NOT be changed. The NFC API messages are handled by default in NFC_CL task. If NFC_CL task is overridden by the main task then 0x7E00 SHOULD NOT be use by other base. @@ -185,6 +185,8 @@ all ADK libraries. /*! @brief Message base for transport manager libraries*/ #define TRANSPORT_MGR_MESSAGE_BASE 0x7F7A #define VA_AUDIO_MGR_MESSAGE_BASE 0x7F80 +#define GATT_SEAN_SERVER_MESSAGE_BASE 0x7F90 + #endif /* _LIBRARY_H */ /*@}*/ diff --git a/TWS/apps/libs/libs_qcc512x_qcc302x.x2p b/TWS/apps/libs/libs_qcc512x_qcc302x.x2p index e82d830..20e18bf 100644 --- a/TWS/apps/libs/libs_qcc512x_qcc302x.x2p +++ b/TWS/apps/libs/libs_qcc512x_qcc302x.x2p @@ -992,6 +992,12 @@ <file path="gatt_transmit_power_server/gatt_transmit_power_server_private.h"/> <file path="gatt_transmit_power_server/gatt_transmit_power_server_uuids.h"/> </folder> + <folder name="gatt_blood_pressure_server"> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server.c"/> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server.h"/> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi"/> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server_uuids.h"/> + </folder> <folder name="hfp"> <file path="hfp/hfp.h"/> <file path="hfp/hfp_at_cmd.c"/> diff --git a/TWS/apps/libs/libs_qcc512x_rom_v21.x2p b/TWS/apps/libs/libs_qcc512x_rom_v21.x2p index c6d5bd7..c36c5cc 100644 --- a/TWS/apps/libs/libs_qcc512x_rom_v21.x2p +++ b/TWS/apps/libs/libs_qcc512x_rom_v21.x2p @@ -876,6 +876,12 @@ <file path="gatt_heart_rate_server/gatt_heart_rate_server_private.h"/> <file path="gatt_heart_rate_server/gatt_heart_rate_server_uuids.h"/> </folder> + <folder name="gatt_blood_pressure_server"> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server.c"/> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server.h"/> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi"/> + <file path="gatt_blood_pressure_server/gatt_blood_pressure_server_uuids.h"/> + </folder> <folder name="gatt_hid_client"> <file path="gatt_hid_client/gatt_hid_client.c"/> <file path="gatt_hid_client/gatt_hid_client.h"/> -- 2.14.1.windows.1

有些参考blog中提到的没有需要自己定义,如下

在参考过程中发现读功能发出后老是断线,后来参考电池gatt_battery_level_service发现要回复一个respond,读notify config descp也是,参考电池回复一下respond,不然后莫名掉线

在实现notify中出现手机端老是不能接收到设备,后来调试时,在battery加了notify功能,电池可以通知,说明tws此功能是可以的,后来,在原来notify再加了read功能,发现nrf connect仍没有notify, 后面再看了一下写的uuid为对应的name形成的handle,将size由2改成1个字节,就可以在手机端收到了,后来发现电池改成2个字节手机也收不到了,看来是数据长度的问题 编译后会生成 btsnoop log分析也成功了 会出现切换主耳,广播扫描不了,发现是关掉了,是逻辑中的电池电量的对比引起

diff --git a/TWS/apps/applications/earbud/av_headset_conn_rules.c b/TWS/apps/applications/earbud/av_headset_conn_rules.c index 361b4dd..c3f11dd 100644 --- a/TWS/apps/applications/earbud/av_headset_conn_rules.c +++ b/TWS/apps/applications/earbud/av_headset_conn_rules.c @@ -2397,7 +2397,8 @@ static ruleAction ruleBleConnectionUpdate(void) if (our_battery < peer_battery) { DEBUG_LOG("ruleBleConnectionUpdate Peer (out of case) has stronger battery."); - connectable = FALSE; + //comment by zhongyukang ,otherwise it will mask ble adv + // connectable = FALSE; } else if (our_battery == peer_battery) {

逻辑中uart与blood pressure service连接起来,期间 面临的主要是编译问题

From 04717add8eaebdf90a642d631d29ce3f18ddebcc Mon Sep 17 00:00:00 2001 From: zyukang <zyukang@waterworld.com.cn> Date: Tue, 22 Sep 2020 11:47:20 +0800 Subject: [PATCH 1/3] connect uart and blood service --- TWS/apps/applications/earbud/av_headset_gatt.c | 23 ++++++++++++++++++++++- TWS/apps/applications/earbud/av_headset_gatt.h | 4 +++- TWS/apps/applications/earbud/peripherals/uart.c | 10 ++++++++-- TWS/apps/applications/earbud/peripherals/uart.h | 2 ++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/TWS/apps/applications/earbud/av_headset_gatt.c b/TWS/apps/applications/earbud/av_headset_gatt.c index 9fb890c..491051b 100644 --- a/TWS/apps/applications/earbud/av_headset_gatt.c +++ b/TWS/apps/applications/earbud/av_headset_gatt.c @@ -23,7 +23,13 @@ #include <gatt_gap_server.h> #include <gaia.h> #include <panic.h> - +#ifdef HAVE_UART +#include "peripherals/uart.h" +#endif +#if defined(INCLUDE_GATT_BLOOD_PRESSURE) +const SEANS *gsean_server =NULL; +uint16 gcid = 0; +#endif /*! Earbud GATT database, for the required GATT and GAP servers. */ extern const uint16 gattDatabase[]; @@ -624,6 +630,8 @@ static void appGattHandleSeanServerReadclientconfigInd(const GATT_SEAN_SERVER_RE i++; if (i == 100)i = 0; /* Return requested battery level */ + gsean_server = ind->sean_server; + gcid = ind->cid; GattSeanServerReadclientconfigResponse(ind->sean_server, ind->cid, return_value); } #if 0 @@ -637,14 +645,27 @@ static void appGattHandleSeanServerReadClientConfig(const GATT_SEAN_SERVER_WRITE static void appGattHandleSeanServerWriteSth(const GATT_SEAN_SERVER_WRITE_STH_IND_T * ind) { uint16 client_config = 0; + uint8 config_resp[GATT_CLIENT_CONFIG_OCTET_SIZE]; client_config = ind->write_value ; // client_config = 0x98; DEBUG_LOG("SEAN: appGattHandleSeanServerWriteSth, write_value=[0x%x] cid=[0x%x]\n", client_config,ind->cid); GattSeanServerWriteToNofityResponse(ind->sean_server, ind->cid, client_config); + config_resp[0] = client_config & 0xFF; + config_resp[1] = (client_config >> 8) & 0xFF; +#ifdef HAVE_UART + uart_data_stream_tx_data((const uint8*)&config_resp,1); +#endif } +bool GattSeanServerNofityClient( uint16 value) +{ + if((gsean_server) &&(gcid)) { + return GattSeanServerWriteToNofityResponse(gsean_server,gcid, value); + } + return FALSE; +} void appGattSeanMessageHandler(Task task, MessageId id, Message message) { UNUSED(task); diff --git a/TWS/apps/applications/earbud/av_headset_gatt.h b/TWS/apps/applications/earbud/av_headset_gatt.h index 8dcd3a9..79e2d12 100644 --- a/TWS/apps/applications/earbud/av_headset_gatt.h +++ b/TWS/apps/applications/earbud/av_headset_gatt.h @@ -165,6 +165,8 @@ bool appGattHandleConnectionLibraryMessages(MessageId id, Message message, bool /*! @brief Initialise the GATT component. */ void appGattInit(void); - +#ifdef INCLUDE_GATT_BLOOD_PRESSURE +extern bool GattSeanServerNofityClient( uint16 value); +#endif #endif /* _AV_HEADSET_GATT_H_ */ diff --git a/TWS/apps/applications/earbud/peripherals/uart.c b/TWS/apps/applications/earbud/peripherals/uart.c index 2622592..9ae999c 100644 --- a/TWS/apps/applications/earbud/peripherals/uart.c +++ b/TWS/apps/applications/earbud/peripherals/uart.c @@ -1,9 +1,11 @@ #ifdef HAVE_UART #include "uart.h" +#ifdef INCLUDE_GATT_BLOOD_PRESSURE +extern bool GattSeanServerNofityClient( uint16 value); +#endif UARTStreamTaskData theUARTStreamTask; static void UARTStreamMessageHandler(Task ppTask,MessageId pId,Message pMessage); static void uart_data_stream_rx_data(Source src); -static void uart_data_stream_tx_data(const uint8*data,uint16 length); /*UART*/ void uart_data_stream_init(void) { @@ -60,7 +62,11 @@ void uart_data_stream_rx_data(Source src) PanicNull((void*)data); DEBUG_LOG("uart_data_stream_rx_data reg:0x%x 0x%x 0x%x",data[0],data[1],data[2]); /*Transmitthereceiveddata*/ - uart_data_stream_tx_data(data,length); +// uart_data_stream_tx_data(data,length); +#ifdef INCLUDE_GATT_BLOOD_PRESSURE + uint16 value = (data[0] &0xFF) |((data[1] <<8)&0xFF00); + GattSeanServerNofityClient((uint16)value); +#endif /*Discardsthespecifiedamountofbytesfromthefrontofthespecified source*/ SourceDrop(src,length); diff --git a/TWS/apps/applications/earbud/peripherals/uart.h b/TWS/apps/applications/earbud/peripherals/uart.h index 12d33c9..c5dcb85 100644 --- a/TWS/apps/applications/earbud/peripherals/uart.h +++ b/TWS/apps/applications/earbud/peripherals/uart.h @@ -23,4 +23,6 @@ Sink uart_sink; Source uart_source; }UARTStreamTaskData; extern void uart_data_stream_init(void); +extern void uart_data_stream_tx_data(const uint8*data,uint16 length); + #endif -- 1.9.1

添加只在使能notify功能时才发通知给client

From 46161a3012e80bab2cfb7ebaf1b481a64fb63780 Mon Sep 17 00:00:00 2001 From: zyukang <zyukang@waterworld.com.cn> Date: Tue, 22 Sep 2020 14:22:49 +0800 Subject: [PATCH 2/3] blood pressure service add notify func --- TWS/apps/applications/earbud/av_headset_gatt.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/TWS/apps/applications/earbud/av_headset_gatt.c b/TWS/apps/applications/earbud/av_headset_gatt.c index 491051b..8d7f583 100644 --- a/TWS/apps/applications/earbud/av_headset_gatt.c +++ b/TWS/apps/applications/earbud/av_headset_gatt.c @@ -630,8 +630,6 @@ static void appGattHandleSeanServerReadclientconfigInd(const GATT_SEAN_SERVER_RE i++; if (i == 100)i = 0; /* Return requested battery level */ - gsean_server = ind->sean_server; - gcid = ind->cid; GattSeanServerReadclientconfigResponse(ind->sean_server, ind->cid, return_value); } #if 0 @@ -650,7 +648,7 @@ static void appGattHandleSeanServerWriteSth(const GATT_SEAN_SERVER_WRITE_STH_IND client_config = ind->write_value ; // client_config = 0x98; DEBUG_LOG("SEAN: appGattHandleSeanServerWriteSth, write_value=[0x%x] cid=[0x%x]\n", client_config,ind->cid); - GattSeanServerWriteToNofityResponse(ind->sean_server, ind->cid, client_config); + // GattSeanServerWriteToNofityResponse(ind->sean_server, ind->cid, client_config); config_resp[0] = client_config & 0xFF; config_resp[1] = (client_config >> 8) & 0xFF; @@ -691,9 +689,16 @@ void appGattSeanMessageHandler(Task task, MessageId id, Message message) appGattHandleSeanServerReadclientconfigInd((const GATT_SEAN_SERVER_READ_STH_IND_T *) message); break; case GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND: - DEBUG_LOG("SEAN: appGattSeanMessageHandler:GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND cid=[0x%x]",((const GATT_SEAN_SERVER_READ_STH_IND_T *) message)->cid); + DEBUG_LOG("SEAN: appGattSeanMessageHandler:GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND cid=[0x%x] value:0x%x",((const GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T *) message)->cid,((const GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T *) message)->config_value); // appGattHandleSeanServerReadClientConfig((const GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T *)message); - + GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T * ind = (( GATT_SEAN_SERVER_WRITE_CLIENT_CONFIG_IND_T *) message); + if (ind->config_value) { + gsean_server = ind->sean_server; + gcid = ind->cid; + }else { + gsean_server = NULL; + gcid = 0; + } break; default: DEBUG_LOG("SEAN: appGattSeanMessageHandler. Unhandled message id:0x%x", id); -- 1.9.1

修改att数据长度,最大为10个字节,修改空指针引起的crash (多数是数组越界访问),发给client最大10个字节,接收2个字节

ATT最小为23个字节

From ee43f190fd93f5bedd9775c0a65630af9c64eeca Mon Sep 17 00:00:00 2001 From: zyukang <zyukang@waterworld.com.cn> Date: Wed, 23 Sep 2020 18:15:20 +0800 Subject: [PATCH 3/3] gatt modify data length --- TWS/apps/applications/earbud/av_headset_gatt.c | 6 +++--- TWS/apps/applications/earbud/av_headset_gatt.h | 4 +++- TWS/apps/applications/earbud/peripherals/uart.c | 19 ++++++++++++------- TWS/apps/libs/gatt/gatt_private.h | 6 +++--- .../gatt_blood_pressure_server.c | 19 ++++++++++++------- .../gatt_blood_pressure_server.h | 4 ++-- .../gatt_blood_pressure_server_db.dbi | 8 ++++++++ .../gatt_blood_pressure_server_db.h | 5 +++-- 8 files changed, 46 insertions(+), 25 deletions(-) diff --git a/TWS/apps/applications/earbud/av_headset_gatt.c b/TWS/apps/applications/earbud/av_headset_gatt.c index 8d7f583..ad3bfad 100644 --- a/TWS/apps/applications/earbud/av_headset_gatt.c +++ b/TWS/apps/applications/earbud/av_headset_gatt.c @@ -653,14 +653,14 @@ static void appGattHandleSeanServerWriteSth(const GATT_SEAN_SERVER_WRITE_STH_IND config_resp[0] = client_config & 0xFF; config_resp[1] = (client_config >> 8) & 0xFF; #ifdef HAVE_UART - uart_data_stream_tx_data((const uint8*)&config_resp,1); + uart_data_stream_tx_data((const uint8*)&config_resp,2); #endif } -bool GattSeanServerNofityClient( uint16 value) +bool GattSeanServerNofityClient( const uint8*data,uint16 length) { if((gsean_server) &&(gcid)) { - return GattSeanServerWriteToNofityResponse(gsean_server,gcid, value); + return GattSeanServerWriteToNofityResponse(gsean_server,gcid, data,length); } return FALSE; } diff --git a/TWS/apps/applications/earbud/av_headset_gatt.h b/TWS/apps/applications/earbud/av_headset_gatt.h index 79e2d12..ab8f52e 100644 --- a/TWS/apps/applications/earbud/av_headset_gatt.h +++ b/TWS/apps/applications/earbud/av_headset_gatt.h @@ -166,7 +166,9 @@ bool appGattHandleConnectionLibraryMessages(MessageId id, Message message, bool */ void appGattInit(void); #ifdef INCLUDE_GATT_BLOOD_PRESSURE -extern bool GattSeanServerNofityClient( uint16 value); +//extern bool GattSeanServerNofityClient( uint16 value); +extern bool GattSeanServerNofityClient( const uint8*data,uint16 length); + #endif #endif /* _AV_HEADSET_GATT_H_ */ diff --git a/TWS/apps/applications/earbud/peripherals/uart.c b/TWS/apps/applications/earbud/peripherals/uart.c index 9ae999c..16129aa 100644 --- a/TWS/apps/applications/earbud/peripherals/uart.c +++ b/TWS/apps/applications/earbud/peripherals/uart.c @@ -1,7 +1,7 @@ #ifdef HAVE_UART #include "uart.h" #ifdef INCLUDE_GATT_BLOOD_PRESSURE -extern bool GattSeanServerNofityClient( uint16 value); +bool GattSeanServerNofityClient( const uint8*data,uint16 length); #endif UARTStreamTaskData theUARTStreamTask; static void UARTStreamMessageHandler(Task ppTask,MessageId pId,Message pMessage); @@ -60,16 +60,21 @@ void uart_data_stream_rx_data(Source src) /*Mapsthespecifiedsourceintotheaddressmap*/ data=SourceMap(src); PanicNull((void*)data); - DEBUG_LOG("uart_data_stream_rx_data reg:0x%x 0x%x 0x%x",data[0],data[1],data[2]); + DEBUG_LOG("uart_data_stream_rx_data reg:0x%x length %d",data[0],length); /*Transmitthereceiveddata*/ // uart_data_stream_tx_data(data,length); #ifdef INCLUDE_GATT_BLOOD_PRESSURE - uint16 value = (data[0] &0xFF) |((data[1] <<8)&0xFF00); - GattSeanServerNofityClient((uint16)value); +// if(length < 2) return; +// uint16 value = (data[0] &0xFF) |((data[1] <<8)&0xFF00); + GattSeanServerNofityClient(data,length); #endif /*Discardsthespecifiedamountofbytesfromthefrontofthespecified source*/ + DEBUG_LOG("uart_data_stream_rx_data reg:0x%x ",data[0]); + data = NULL; SourceDrop(src,length); + DEBUG_LOG("SourceDrop--- "); + } void UARTStreamMessageHandler(Task ppTask,MessageId pId,Message pMessage) { @@ -81,9 +86,9 @@ void UARTStreamMessageHandler(Task ppTask,MessageId pId,Message pMessage) case MESSAGE_MORE_DATA: uart_data_stream_rx_data(((MessageMoreData*)pMessage)->source); break; - // case MESSAGE_MORE_SPACE: - // uart_data_stream_rx_data(((MessageMoreData*)pMessage)->source); - // break; + case MESSAGE_MORE_SPACE: + uart_data_stream_rx_data(((MessageMoreData*)pMessage)->source); + break; default: break; } diff --git a/TWS/apps/libs/gatt/gatt_private.h b/TWS/apps/libs/gatt/gatt_private.h index c61dad4..e84776f 100644 --- a/TWS/apps/libs/gatt/gatt_private.h +++ b/TWS/apps/libs/gatt/gatt_private.h @@ -415,7 +415,7 @@ typedef struct uint16 handle; uint16 offs; uint16 size_value; - uint8 value[1]; + uint8 value[10]; } GATT_INTERNAL_WRITE_REQ_T; typedef struct @@ -430,7 +430,7 @@ typedef struct uint16 handle; uint16 result; uint16 size_value; - uint8 value[1]; + uint8 value[10]; } GATT_INTERNAL_ACCESS_RES_T; typedef struct @@ -440,7 +440,7 @@ typedef struct uint16 handle; uint16 flags; uint16 size_value; - uint8 value[1]; + uint8 value[10]; } GATT_INTERNAL_HANDLE_VALUE_REQ_T; typedef GATT_INTERNAL_HANDLE_VALUE_REQ_T GATT_INTERNAL_HANDLE_VALUE_NTF_T; diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c index 8ac6381..9ad84a5 100644 --- a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.c @@ -230,16 +230,21 @@ static void sendSeanNotificationRsp(Task task, PRINT("SEAN: sendSeanNotificationRsp--\n"); } -void sendSeanConfigAccessRsp(const SEANS *sean_server, uint16 cid, uint16 client_config) +void sendSeanConfigAccessRsp(const SEANS *sean_server, uint16 cid, const uint8*data,uint16 length) { - uint8 config_resp[GATT_CLIENT_CONFIG_OCTET_SIZE]; +// uint8 config_resp[10]; +// int i = 0; - config_resp[0] = client_config & 0xFF; - config_resp[1] = (client_config >> 8) & 0xFF; - sendSeanNotificationRsp((Task)&sean_server->lib_task, cid, HANDLE_SEAN_READ, 1, config_resp); +// config_resp[0] = client_config & 0xFF; +// config_resp[1] = (client_config >> 8) & 0xFF; + +// for(i = 0;i< length;i++) { +// config_resp[i] = data[i] & 0xFF; +// } + sendSeanNotificationRsp((Task)&sean_server->lib_task, cid, HANDLE_SEAN_READ, length, data); } -bool GattSeanServerWriteToNofityResponse(const SEANS *sean_server, uint16 cid, uint16 client_config) +bool GattSeanServerWriteToNofityResponse(const SEANS *sean_server, uint16 cid, const uint8*data,uint16 length) { PRINT("SEAN: GattSeanServerReadClientConfigResponse\n"); if (sean_server == NULL) @@ -248,7 +253,7 @@ bool GattSeanServerWriteToNofityResponse(const SEANS *sean_server, uint16 cid, u } PRINT("SEAN: GattSeanServerReadClientConfigResponse 2\n"); - sendSeanConfigAccessRsp(sean_server, cid, client_config); + sendSeanConfigAccessRsp(sean_server, cid, data,length); return TRUE; } diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h index 10ef0a7..81b44db 100644 --- a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server.h @@ -79,10 +79,10 @@ void sendSeanLevelAccessRsp(const SEANS *sean_server, uint16 cid, uint8 sean_lev bool GattSeanServerReadSthResponse(const SEANS *sean_server, uint16 cid, uint8 sean_level); void appGattSeanMessageHandler(Task task, MessageId id, Message message); -void sendSeanConfigAccessRsp(const SEANS *sean_server, uint16 cid, uint16 client_config); +void sendSeanConfigAccessRsp(const SEANS *sean_server, uint16 cid, const uint8*data,uint16 length); void sendSeanLevelAccessRsp_2(const SEANS *sean_server, uint16 cid, uint8 sean_level, uint16 result); bool GattSeanServerReadclientconfigResponse(const SEANS *sean_server, uint16 cid, uint16 sean_level); -bool GattSeanServerWriteToNofityResponse(const SEANS *sean_server, uint16 cid, uint16 client_config); +bool GattSeanServerWriteToNofityResponse(const SEANS *sean_server, uint16 cid, const uint8*data,uint16 length); bool GattSeanServerInit(SEANS *sean_server, Task app_task, diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi index 3a6f9b5..819aaca 100644 --- a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.dbi @@ -12,6 +12,14 @@ primary_service { flags : [ FLAG_IRQ , FLAG_DYNLEN ], properties : [ read , notify ], value : 0x0, + presentation_format { + format :uint8, + exponent :-1, + name : "SEAN_FORMAT", + unit :0x2781, + name_space :0, + description: 0 + }, client_config { flags : [ FLAG_IRQ , FLAG_DYNLEN ], name : "SEAN_NOTIFICATION" diff --git a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h index 46489df..0ffe9b7 100644 --- a/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h +++ b/TWS/apps/libs/gatt_blood_pressure_server/gatt_blood_pressure_server_db.h @@ -11,8 +11,9 @@ #define HANDLE_SEAN_SERVICE (0x0001) #define HANDLE_SEAN_SERVICE_END (0xffff) #define HANDLE_SEAN_READ (0x0003) -#define HANDLE_SEAN_NOTIFICATION (0x0004) -#define HANDLE_SEAN_WRITE (0x0006) +#define HANDLE_SEAN_FORMAT (0x0004) +#define HANDLE_SEAN_NOTIFICATION (0x0005) +#define HANDLE_SEAN_WRITE (0x0007) uint16 *GattGetDatabase(uint16 *len); uint16 GattGetDatabaseSize(void); -- 1.9.1

出仓对耳超时,发传统广播

diff --git a/TWS/apps/applications/earbud/av_headset_con_manager.c b/TWS/apps/applications/earbud/av_headset_con_manager.c index f51f1cd..2af5ff0 100644 --- a/TWS/apps/applications/earbud/av_headset_con_manager.c +++ b/TWS/apps/applications/earbud/av_headset_con_manager.c @@ -179,7 +179,7 @@ void appConManagerSendCloseAclRequest(const bdaddr *addr, bool force) } -/* Implementation of create ACL function. +/* Implementation of create ACL function. This includes a BLE flag so can be used to create BLE and BREDR connections if needed. */ static uint16 *appConManagerCreateAclImpl(const bdaddr *addr, bool is_ble) @@ -365,7 +365,7 @@ static void appConManagerHandleClDmAclOpenedIndication(const CL_DM_ACL_OPENED_IN appLinkPolicyUpdateLinkSupervisionTimeout(&ind->bd_addr.addr); /* Check if this is a BREDR BDADDR for handset */ - if ( !(ind->flags & DM_ACL_FLAG_ULP) + if ( !(ind->flags & DM_ACL_FLAG_ULP) && appDeviceIsHandset(&ind->bd_addr.addr)) { DEBUG_LOG("appConManagerHandleClDmAclOpenedIndication, handset"); @@ -468,10 +468,9 @@ static void appConManagerHandleClSmAuthoriseIndication(const CL_SM_AUTHORISE_IND DEBUG_LOG("appConManagerHandleClSmAuthoriseIndication, ALLOW peer"); authorise = TRUE; } - else + else { bool handset = appDeviceIsHandset(&ind->bd_addr); - if (handset && theConMgr->handset_connect_allowed) { DEBUG_LOG("appConManagerHandleClSmAuthoriseIndication, ALLOW handset (bredr)"); @@ -507,7 +506,7 @@ bool appConManagerHandleConnectionLibraryMessages(MessageId id,Message message, case CL_DM_ACL_OPENED_IND: appConManagerHandleClDmAclOpenedIndication((CL_DM_ACL_OPENED_IND_T *)message); return TRUE; - + case CL_DM_ACL_CLOSED_IND: appConManagerHandleClDmAclClosedIndication((CL_DM_ACL_CLOSED_IND_T *)message); return TRUE; @@ -515,7 +514,7 @@ bool appConManagerHandleConnectionLibraryMessages(MessageId id,Message message, case CL_DM_BLE_ACCEPT_CONNECTION_PAR_UPDATE_IND: { CL_DM_BLE_ACCEPT_CONNECTION_PAR_UPDATE_IND_T *ind = (CL_DM_BLE_ACCEPT_CONNECTION_PAR_UPDATE_IND_T *)message; - + ConnectionDmBleAcceptConnectionParUpdateResponse(TRUE, &ind->taddr, ind->id, ind->conn_interval_min, ind->conn_interval_max, @@ -558,7 +557,7 @@ static void appConManagerHandleMessage(Task task, MessageId id, Message message) } /*! \brief Configure role switch policy. - + Currently we want to never automatically ask for a role switch nor refuse a request for a role switch. */ @@ -577,7 +576,7 @@ static void appConManagerSetupRoleSwitchPolicy(void) void appConManagerInit(void) { conManagerTaskData *theConMgr = appGetConManager(); - + DEBUG_LOG("appConManagerInit"); memset(theConMgr, 0, sizeof(*theConMgr)); @@ -588,6 +587,7 @@ void appConManagerInit(void) /* create a task list to track tasks interested in connection * event indications */ theConMgr->connection_client_tasks = appTaskListInit(); + theConMgr->handset_connect_allowed = TRUE;/*add by zhongyukang*/ /* setup role switch policy */ appConManagerSetupRoleSwitchPolicy(); diff --git a/TWS/apps/applications/earbud/av_headset_config.h b/TWS/apps/applications/earbud/av_headset_config.h index f67b9c3..0d01a72 100644 --- a/TWS/apps/applications/earbud/av_headset_config.h +++ b/TWS/apps/applications/earbud/av_headset_config.h @@ -25,7 +25,7 @@ #define appConfigDfuAllowBredrUpgradeOutOfCase() FALSE -/*! Only allow upgrades when the request has been made by the user (through the UI) +/*! Only allow upgrades when the request has been made by the user (through the UI) and the device is in the case. */ #define appConfigDfuOnlyFromUiInCase() FALSE @@ -36,21 +36,21 @@ /*! Timeout for starting DFU mode after a restart caused by an upgrade completing. The timeout will only apply if the device - is out of the case. + is out of the case. The timeout can be set to 0, in which case there is no limit. */ #define appConfigDfuTimeoutToStartAfterRestartMs() (D_SEC(30)) -/*! Timeout for DFU mode, entered after a reboot in DFU mode. +/*! Timeout for DFU mode, entered after a reboot in DFU mode. This is the timeout for an abnormal restart. Restarts that occur - as part of the normal upgrade process use + as part of the normal upgrade process use appConfigDfuTimeoutToStartAfterRestartMs() The timeout can be set to 0, in which case there is no limit. */ #define appConfigDfuTimeoutToStartAfterRebootMs() (D_SEC(15)) -/*! Timeout for DFU mode, entered from UI +/*! Timeout for DFU mode, entered from UI This is the timeout for starting an upgrade when the user has requested DFU and then placed the device into the case. @@ -60,7 +60,7 @@ /*! Timeout for DFU mode, requested from GAIA - This is the timeout for starting an upgrade after the GAIA + This is the timeout for starting an upgrade after the GAIA upgrade protocol has been connected. Only applicable in the in case DFU mode. @@ -119,7 +119,7 @@ /*! Number of paired devices that are remembered */ #define appConfigMaxPairedDevices() (4) -#ifdef CF133_BATT +#ifdef CF133_BATT /*! Minimum RSSI to pair with a device */ #define appConfigPeerPairingMinRssi() (-60) #else @@ -127,12 +127,12 @@ #define appConfigPeerPairingMinRssi() (-50) #endif -/*! Minimum difference in RSSI between devices discovered +/*! Minimum difference in RSSI between devices discovered with the highest RSSI in order to pair */ #define appConfigPeerPairingMinRssiDelta() (10) /*! Timeout in seconds for user initiated peer pairing */ -#define appConfigPeerPairingTimeout() (120) +#define appConfigPeerPairingTimeout() (30) /*! Timeout in seconds for user initiated handset pairing */ #define appConfigHandsetPairingTimeout() (120) /*! Timeout in seconds to disable page/inquiry scan after entering idle state */ @@ -243,11 +243,11 @@ /*! The volume setting to use for no gain, when volume is specifed on range of 0-127 */ #define appConfigVolumeNoGain127Step() (127) -/*! Number of volume steps to use per AV UI volume event. +/*! Number of volume steps to use per AV UI volume event. The full volume range is 0-127 */ #define appConfigGetAvVolumeStep() (8) -/*! Number of volume steps to use per HFP UI volume event. +/*! Number of volume steps to use per HFP UI volume event. The full volume range is 0-15 */ #define appConfigGetHfpVolumeStep() (1) @@ -298,9 +298,9 @@ //!@} /*! @{ Which microphones to use for SCO */ - /*! microphone to use for the first SCO mic */ + /*! microphone to use for the first SCO mic */ #define appConfigScoMic1() (0) - /*! microphone to use for the second SCO mic. This should be defined as + /*! microphone to use for the second SCO mic. This should be defined as NO_MIC if using 1-mic CVC */ #define appConfigScoMic2() (NO_MIC) /* Don't use microphone for SCO 2nd mic (CVC 1-mic) */ /*! @} */ @@ -346,9 +346,9 @@ //!@} /*! @{ Which microphones to use for SCO */ - /*! microphone to use for the first SCO mic */ + /*! microphone to use for the first SCO mic */ #define appConfigScoMic1() (0) /* Use microphone 0 for SCO 1st mic */ - /*! microphone to use for the second SCO mic. This should be defined as + /*! microphone to use for the second SCO mic. This should be defined as NO_MIC if using 1-mic CVC */ #define appConfigScoMic2() (NO_MIC) /* Don't use microphone for SCO 2nd mic (CVC 1-mic) */ /*! @} */ @@ -380,8 +380,8 @@ #define appConfigScoFwdRingMs() (1000) -/*! The minimum time to play to be added on incoming SCO connections - to allow synchronisation. This should represent the total propagation +/*! The minimum time to play to be added on incoming SCO connections + to allow synchronisation. This should represent the total propagation delay in the chain */ #define appConfigScoChainBaseTTP() (15000) @@ -411,7 +411,7 @@ /*! Charger configuration */ -/*! The time to debounce charger state changes (ms). +/*! The time to debounce charger state changes (ms). The charger hardware will have a more limited range. */ #define appConfigChargerStateChangeDebounce() (128) @@ -481,7 +481,7 @@ /*! The interval at which the battery voltage is read. */ #define appConfigBatteryReadPeriodMs() D_SEC(2) -/*! Margin to apply on battery readings before accepting that +/*! Margin to apply on battery readings before accepting that the level has changed. Units of milli-volts */ #define appConfigSmBatteryHysteresisMargin() (50) @@ -638,13 +638,13 @@ extern const thermistorConfig thermistor_config; #endif /* INCLUDE_TEMPERATURE */ -/*! The time to play delay added in the SCO receive path. +/*! The time to play delay added in the SCO receive path. A value of 40 will cause some missing / delayed packets in - good test conditions. + good test conditions. It is estimated that 60 is the lowest value that may be used in the real world, with random 2.4GHz interference. - It is recommended that the final value used should be selected + It is recommended that the final value used should be selected based on expected useage, and tolerance for delays vs. errors introduced by Packet Loss Concealment. */ #define appConfigScoFwdVoiceTtpMs() (70) @@ -657,7 +657,7 @@ extern const promptConfig prompt_config[]; /******************************************** - * SETTINGS for Bluetooth Low Energy (BLE) + * SETTINGS for Bluetooth Low Energy (BLE) ********************************************/ /*! Define whether BLE is allowed when out of the case. @@ -666,7 +666,7 @@ extern const promptConfig prompt_config[]; consumption and extend battery life. It will not be possible to start an upgrade or read battery information. - \note Any existing BLE connections will not be affected + \note Any existing BLE connections will not be affected when leaving the case. */ #define appConfigBleAllowedOutOfCase() (TRUE) @@ -675,9 +675,9 @@ extern const promptConfig prompt_config[]; /*! Should new connections be allowed when music is being played or when we are in a call. - Selecting this option - \li reduces power consumption slightly as the advertisements neccesary - for a connection are relatively low power, + Selecting this option + \li reduces power consumption slightly as the advertisements neccesary + for a connection are relatively low power, \li stops any distortion from connections \note Existing connections are not affected by this option @@ -704,7 +704,7 @@ extern const promptConfig prompt_config[]; /*! Enumerated type to select pre-defined advertising rate settings */ -typedef enum +typedef enum { APP_ADVERT_RATE_SLOW, /*!< Select a slow advertising rate */ APP_ADVERT_RATE_FAST, /*!< Select a fast advertising rate */ @@ -716,7 +716,7 @@ typedef enum Populate values for min and max advertising interval \param rate Advertising mode requested - \param[out] min_rate Pointer to value for lowest advertising interval + \param[out] min_rate Pointer to value for lowest advertising interval \param[out] max_rate Pointer to value for highest advertising interval \return TRUE if the mode is known, and min_rate and max_rate could be populated. @@ -726,7 +726,7 @@ bool appConfigBleGetAdvertisingRate(appConfigBleAdvertisingMode rate, uint16 *mi /*! Should we use a random address in our BLE advertisements - When using Resolvable Private Addresses the address used will change between + When using Resolvable Private Addresses the address used will change between connections and over time for adverts. When paired with a device the public address is still available to the peer. */ diff --git a/TWS/apps/applications/earbud/av_headset_conn_rules.c b/TWS/apps/applications/earbud/av_headset_conn_rules.c index c3f11dd..6cd0381 100644 --- a/TWS/apps/applications/earbud/av_headset_conn_rules.c +++ b/TWS/apps/applications/earbud/av_headset_conn_rules.c @@ -107,7 +107,7 @@ typedef struct /*! Macro used to create an entry in the rules table that requires additional flags. */ #define RULE_WITH_FLAGS(event, name, message, flags) \ - { event, RULE_STATUS_NOT_DONE, flags, name, message } + { event, RULE_STATUS_NOT_DONE, flags, name, message } /*! \{ Rule function prototypes, so we can build the rule tables below. */ @@ -334,7 +334,7 @@ typedef enum else (yes) :Already paired; stop - @enduml + @enduml */ static ruleAction rulePeerPair(void) { @@ -385,7 +385,7 @@ static ruleAction rulePeerPair(void) else (no) end endif - @enduml + @enduml */ static ruleAction ruleAutoHandsetPair(void) { @@ -458,7 +458,7 @@ static ruleAction ruleAutoHandsetPair(void) else (no) :Already paired; end - @enduml + @enduml */ static ruleAction rulePeerSync(void) { @@ -495,7 +495,7 @@ static ruleAction rulePeerSyncIfNotComplete(void) else (no) :Not paired; end - @enduml + @enduml */ static ruleAction ruleForwardLinkKeys(void) { @@ -533,7 +533,7 @@ static ruleAction ruleForwardLinkKeys(void) stop endif endif - @enduml + @enduml */ static ruleAction ruleConnectBatteryVoltage(ruleConnectReason reason) { @@ -573,7 +573,7 @@ static ruleAction ruleConnectBatteryVoltage(ruleConnectReason reason) static ruleAction ruleConnectHandsetStandard(ruleConnectReason reason) { if ((reason == RULE_CONNECT_USER) || (reason == RULE_CONNECT_LINK_LOSS)) - { + { RULE_LOG("ruleConnectHandsetStandard, run as standard handset and user requested connection/link-loss"); return RULE_ACTION_RUN; } @@ -612,14 +612,14 @@ static ruleAction ruleConnectHandsetStandard(ruleConnectReason reason) else { RULE_LOG("ruleConnectHandsetStandard, ignore as standard handset and both out of case"); - return RULE_ACTION_IGNORE; + return RULE_ACTION_IGNORE; } } } else { RULE_LOG("ruleConnectHandsetStandard, ignore as in case"); - return RULE_ACTION_IGNORE; + return RULE_ACTION_IGNORE; } } else @@ -641,7 +641,7 @@ static ruleAction ruleConnectHandsetStandard(ruleConnectReason reason) if (Not IsPairedWithHandset()) then (yes) :Not paired with handset, don't connect; end - endif + endif if (IsHandsetA2dpConnected() and IsHandsetAvrcpConnected() and IsHandsetHfpConnected()) then (yes) :Already connected; end @@ -686,7 +686,7 @@ static ruleAction ruleConnectHandsetStandard(ruleConnectReason reason) endif endif - @enduml + @enduml */ static ruleAction ruleConnectHandset(ruleConnectReason reason, rulePostHandsetConnectAction post_connect_action) @@ -992,7 +992,7 @@ static ruleAction ruleNoSyncConnectHandset(void) :Don't connect as peer is not connected to handset; end endif - @enduml + @enduml */ static ruleAction ruleConnectPeerHandset(ruleConnectReason reason) { @@ -1045,7 +1045,7 @@ static ruleAction ruleConnectPeerHandset(ruleConnectReason reason) if ((reason == RULE_CONNECT_USER) || (reason == RULE_CONNECT_PAIRING) || (reason == RULE_CONNECT_OUT_OF_CASE) - || (conn_rules->allow_connect_after_pairing && + || (conn_rules->allow_connect_after_pairing && appDeviceHasJustPaired(&handset_addr)) ) { @@ -1158,7 +1158,7 @@ static ruleAction rulePairingConnectPeerHandset(void) :Don't need to connect, peer will connect to us; end endif - else (no) + else (no) :Peer is not connected to handset yet; if (IsPairedWithHandset()) then (yes) if (Not IsTwsHandset()) then (yes) @@ -1189,7 +1189,7 @@ static ruleAction rulePairingConnectPeerHandset(void) end endif - @enduml + @enduml */ static ruleAction ruleConnectPeer(ruleConnectReason reason) { @@ -1252,13 +1252,13 @@ static ruleAction ruleConnectPeer(ruleConnectReason reason) { bdaddr peer_addr; uint8 profiles; - + appDeviceGetPeerBdAddr(&peer_addr); profiles = appDeviceWasConnectedProfiles(&peer_addr); /* Always attempt to connect A2DP and SCOFWD if user initiated connect, * out-of-case connect or sync connect */ - if ((reason == RULE_CONNECT_OUT_OF_CASE) || + if ((reason == RULE_CONNECT_OUT_OF_CASE) || (reason == RULE_CONNECT_USER) || (reason == RULE_CONNECT_PEER_SYNC)) { @@ -1338,7 +1338,7 @@ static ruleAction ruleOutOfCaseConnectPeer(void) start if (Not IsPeerSyncComplete()) then (yes) :Peer sync not completed; - end + end endif if (IsPeerHandsetA2dpConnected() or IsPeerHandsetHfpConnected()) then (yes) @@ -1500,7 +1500,7 @@ static ruleAction ruleInEarScoTransferToEarbud(void) RULE_LOG("ruleInEarScoTransferToEarbud, ignore as this earbud already has SCO"); return RULE_ACTION_IGNORE; } - + /* Peer sync must be complete as this rule uses peer state */ if (!appPeerSyncIsComplete()) { @@ -1750,12 +1750,12 @@ static ruleAction ruleBothConnectedDisconnect(void) * only 1 profile is connected, but there is active audio this will * count higher than all profiles being connected. */ int this_earbud_score = (appDeviceIsHandsetA2dpConnected() ? 1 : 0) + - (appDeviceIsHandsetAvrcpConnected() ? 1 : 0) + + (appDeviceIsHandsetAvrcpConnected() ? 1 : 0) + (appDeviceIsHandsetHfpConnected() ? 1 : 0) + (appHfpIsScoActive() ? 3 : 0) + (appDeviceIsHandsetA2dpStreaming() ? 3 : 0); int other_earbud_score = (appPeerSyncIsPeerHandsetA2dpConnected() ? 1 : 0) + - (appPeerSyncIsPeerHandsetAvrcpConnected() ? 1 : 0) + + (appPeerSyncIsPeerHandsetAvrcpConnected() ? 1 : 0) + (appPeerSyncIsPeerHandsetHfpConnected() ? 1 : 0) + (appPeerSyncIsPeerScoActive() ? 3 : 0) + (appPeerSyncIsPeerHandsetA2dpStreaming() ? 3 : 0); @@ -1809,7 +1809,7 @@ static ruleAction ruleBothConnectedDisconnect(void) */ static ruleAction ruleInCaseDisconnectPeer(void) { - if (appSmIsInCase() && (appDeviceIsPeerA2dpConnected() || + if (appSmIsInCase() && (appDeviceIsPeerA2dpConnected() || appDeviceIsPeerAvrcpConnectedForAv() || appDeviceIsPeerScoFwdConnected())) { @@ -1871,7 +1871,7 @@ static ruleAction ruleDfuAllowHandsetConnect(void) RULE_LOG("ruleDfuAllowHandsetConnect, ignore as already connected to handset"); return RULE_ACTION_IGNORE; } - /* This rule has been run when entering the special DFU mode. + /* This rule has been run when entering the special DFU mode. This should only be entered when we restart during an update, or if the user has requested it (only possible if appConfigDfuOnlyFromUiInCase() is TRUE */ @@ -1962,7 +1962,7 @@ static ruleAction ruleCheckUpgradable(void) else :Not connected with A2DP to handset; end - endif + endif @enduml */ static ruleAction ruleDisconnectPeer(void) @@ -2294,7 +2294,7 @@ static ruleAction ruleScoForwardingControl(void) RULE_LOG("ruleScoForwardingControl, run and enable forwarding as peer in ear"); return RULE_ACTION_RUN_PARAM(forwarding_enabled); } - + RULE_LOG("ruleScoForwardingControl, ignore"); return RULE_ACTION_IGNORE; } @@ -2330,7 +2330,7 @@ static ruleAction ruleHandoverConnectHandsetAndPlay(void) /*! @brief Rule to determine if BLE connection settings should be changed - \todo include UML documentation. + \todo include UML documentation. */ static ruleAction ruleBleConnectionUpdate(void) @@ -2417,15 +2417,19 @@ static ruleAction ruleBleConnectionUpdate(void) if (connectable == is_ble_connecting) { - RULE_LOG("ruleBleConnectionUpdate, IGNORE - no change"); + DEBUG_LOG("ruleBleConnectionUpdate, IGNORE - no change: connectable %d",connectable); + if(paired_with_peer) return RULE_ACTION_IGNORE; + else { + connectable = TRUE; + } } if (connectable) { RULE_LOG("ruleBleConnectionUpdate, run, need to allow new BLE connections"); } - else + else { RULE_LOG("ruleBleConnectionUpdate, run, need to disallow new BLE connections"); } @@ -2779,9 +2783,9 @@ bool appConnRulesInProgress(void) } /*! \brief Register a task to receive notifications that no rules are in progress. */ -void appConnRulesNopClientRegister(Task task) -{ - connRulesTaskData *conn_rules = appGetConnRules(); - appTaskListAddTask(conn_rules->nop_tasks, task); +void appConnRulesNopClientRegister(Task task) +{ + connRulesTaskData *conn_rules = appGetConnRules(); + appTaskListAddTask(conn_rules->nop_tasks, task); } diff --git a/TWS/apps/applications/earbud/av_headset_pairing.c b/TWS/apps/applications/earbud/av_headset_pairing.c index f9d6840..9da2df6 100644 --- a/TWS/apps/applications/earbud/av_headset_pairing.c +++ b/TWS/apps/applications/earbud/av_headset_pairing.c @@ -100,7 +100,7 @@ static void appPairingInitialiseEir(const uint8 *local_name, uint16 size_local_n EIR_UUID128(UUID_TWS_SINK_SERVICE) }; #endif - + uint8 *const eir = (uint8 *)PanicUnlessMalloc(EIR_MAX_SIZE + 1); uint8 *const eir_end = eir + EIR_MAX_SIZE + 1; uint8 *eir_ptr = eir; @@ -121,7 +121,7 @@ static void appPairingInitialiseEir(const uint8 *local_name, uint16 size_local_n *eir_ptr++ = sizeof(eir_128bit_uuids); memmove(eir_ptr, eir_128bit_uuids, sizeof(eir_128bit_uuids)); eir_ptr += sizeof(eir_128bit_uuids); - + /* Add TWS+ EIR data */ *eir_ptr++ = EIR_SIZE_MANUFACTURER_SPECIFIC; *eir_ptr++ = EIR_TYPE_MANUFACTURER_SPECIFIC; @@ -259,18 +259,20 @@ static void appPairingExitIdle(pairingTaskData *thePairing) /* Lock pairing now that a pairing operation is underway */ thePairing->pairing_lock = 1; + thePairing->is_user_initiated = TRUE; + } static void appPairingEnterPeerInquiry(pairingTaskData *thePairing) { - DEBUG_LOG("appPairingEnterPeerInquiry"); + DEBUG_LOG("appPairingEnterPeerInquiry thePairing->is_user_initiated %d",thePairing->is_user_initiated); /* Reset address & peak RSSI value */ BdaddrSetZero(&thePairing->bd_addr[0]); BdaddrSetZero(&thePairing->bd_addr[1]); thePairing->inquiry_rssi[0] = thePairing->inquiry_rssi[1] = appConfigPeerPairingMinRssi() - appConfigPeerPairingMinRssiDelta(); - + thePairing->is_user_initiated = TRUE; /* Set inquiry Tx power, RSSI mode and start periodic inquiry */ /*ConnectionWriteInquiryTx(-40);*/ ConnectionWriteInquiryMode(&thePairing->task, inquiry_mode_rssi); @@ -430,7 +432,7 @@ static void appPairingExitHandsetDiscoverable(pairingTaskData *thePairing) static void appPairingEnterHandsetSdpSearchAuthenticated(pairingTaskData *thePairing) { DEBUG_LOG("appPairingEnterHandsetSdpSearchAuthenticated"); - + /* Perform SDP search */ ConnectionSdpServiceSearchAttributeRequest(&thePairing->task, &thePairing->bd_addr[0], 0x32, appSdpGetTwsSourceServiceSearchRequestSize(), appSdpGetTwsSourceServiceSearchRequest(), @@ -802,10 +804,10 @@ static void appHandleClSdpServiceSearchAttributeCfm(pairingTaskData *thePairing, uint16 tws_version = DEVICE_TWS_STANDARD; appSdpFindTwsVersion(cfm->attributes, cfm->attributes + cfm->size_attributes, &tws_version); appDeviceSetTwsVersion(&cfm->bd_addr, tws_version); - + DEBUG_LOGF("appHandleClSdpServiceSearchAttributeCfm, TWS+ device %x,%x,%lx, version %d", cfm->bd_addr.nap, cfm->bd_addr.uap, cfm->bd_addr.lap, tws_version); - + /* Send confirmation to main task */ appPairingHandsetComplete(thePairing, pairingHandsetSuccess, &cfm->bd_addr); } @@ -813,11 +815,11 @@ static void appHandleClSdpServiceSearchAttributeCfm(pairingTaskData *thePairing, { DEBUG_LOGF("appHandleClSdpServiceSearchAttributeCfm, standard device %x,%x,%lx", cfm->bd_addr.nap, cfm->bd_addr.uap, cfm->bd_addr.lap); - + /* No response data, so handset doesn't have UUID and/or version attribute, therefore treat as standard handset */ appDeviceSetTwsVersion(&cfm->bd_addr, DEVICE_TWS_STANDARD); - + /* Send confirmation to main task */ appPairingHandsetComplete(thePairing, pairingHandsetSuccess, &cfm->bd_addr); } @@ -839,7 +841,7 @@ static void appHandleClSdpServiceSearchAttributeCfm(pairingTaskData *thePairing, } } break; - + case PAIRING_STATE_IDLE: { /* Extract TWS version number */ @@ -1110,7 +1112,7 @@ static void appPairingHandleClSmAuthenticateConfirm(const CL_SM_AUTHENTICATE_CFM #else /* TWS+ disabled, so assume handset is standard handset */ appDeviceSetTwsVersion(&cfm->bd_addr, DEVICE_TWS_STANDARD); - + /* Send confirmation to main task */ appPairingHandsetComplete(thePairing, pairingHandsetSuccess, &cfm->bd_addr); #endif @@ -1185,9 +1187,9 @@ static bool appPairingHandleClSmAuthoriseIndication(const CL_SM_AUTHORISE_IND_T } else if (appDeviceIsPeer(&ind->bd_addr)) { - /* Connection is to peer, so nothing to do with handset pairing. Let + /* Connection is to peer, so nothing to do with handset pairing. Let connection mananger deal with authorisation by returning FALSE - indicating CL_SM_AUTHORISE_IND hasn't been handled, caller has to + indicating CL_SM_AUTHORISE_IND hasn't been handled, caller has to deal with it */ return FALSE; } @@ -1278,7 +1280,7 @@ static void appPairingHandleClSmIoCapabilityReqIndication(const CL_SM_IO_CAPABIL case PAIRING_STATE_HANDSET_SDP_SEARCH_AUTHENTICATED: #endif /* If we have secure connections enabled, this is when cross transport - pairing for our peer earbud arives. + pairing for our peer earbud arives. case PAIRING_STATE_PEER_SCO_FWD_SDP_SEARCH: */ case PAIRING_STATE_IDLE: if (ind->tpaddr.transport == TRANSPORT_BLE_ACL) @@ -1305,7 +1307,7 @@ static void appPairingHandleClSmIoCapabilityReqIndication(const CL_SM_IO_CAPABIL break; } /* Static address only allowed in one permission mode, anything else is OK now */ - if ( !random_address && !existing + if ( !random_address && !existing && thePairing->ble_permission != pairingBleAllowAll) { break; @@ -1877,7 +1879,7 @@ static void appPairingHandleClSmBleSimplePairingCompleteInd(const CL_SM_BLE_SIMP } memset(&thePairing->pending_ble_address,0,sizeof(thePairing->pending_ble_address)); } - + } @@ -1907,7 +1909,7 @@ bool appPairingHandleConnectionLibraryMessages(MessageId id,Message message, boo case CL_SM_USER_CONFIRMATION_REQ_IND: appPairingHandleClSmUserConfirmationReqIndication((CL_SM_USER_CONFIRMATION_REQ_IND_T *)message); return TRUE; - + case CL_SM_REMOTE_IO_CAPABILITY_IND: appPairingHandleClSmRemoteIoCapabilityIndication((CL_SM_REMOTE_IO_CAPABILITY_IND_T *)message); return TRUE; @@ -1919,13 +1921,13 @@ bool appPairingHandleConnectionLibraryMessages(MessageId id,Message message, boo case CL_SM_USER_PASSKEY_NOTIFICATION_IND: case CL_SM_KEYPRESS_NOTIFICATION_IND: case CL_DM_WRITE_APT_CFM: - /* These messages are associated with pairing, although as + /* These messages are associated with pairing, although as indications they required no handling */ return TRUE; case CL_DM_LINK_SUPERVISION_TIMEOUT_IND: return TRUE; - + case CL_SM_BLE_SIMPLE_PAIRING_COMPLETE_IND: appPairingHandleClSmBleSimplePairingCompleteInd((const CL_SM_BLE_SIMPLE_PAIRING_COMPLETE_IND_T *)message); return TRUE; @@ -2063,7 +2065,7 @@ static void appPairingHandleMessage(Task task, MessageId id, Message message) case CL_SM_ADD_AUTH_DEVICE_CFM: appPairingHandleClSmAddAuthDeviceConfirm((CL_SM_ADD_AUTH_DEVICE_CFM_T*)message); - return; + return; } appHandleUnexpected(id); diff --git a/TWS/apps/applications/earbud/av_headset_sm.c b/TWS/apps/applications/earbud/av_headset_sm.c index a29fb59..0b7e277 100644 --- a/TWS/apps/applications/earbud/av_headset_sm.c +++ b/TWS/apps/applications/earbud/av_headset_sm.c @@ -66,7 +66,7 @@ static void appSmDeletePairingAndReset(void) /* Flood fill PS to force a defrag on reboot */ PsFlood(); - + appPowerReboot(); } @@ -292,7 +292,7 @@ static void appEnterStartup(void) appConnRulesSetEvent(appGetSmTask(), RULE_EVENT_STARTUP); /* As we have entered startup state we know there is no upgrade in - progress. If needed block upgrades until we know we are in an + progress. If needed block upgrades until we know we are in an appropriate state */ #ifdef INCLUDE_DFU if ( ( !appConfigDfuAllowBleUpgradeOutOfCase() @@ -731,7 +731,7 @@ void appSetState(appState new_state) /* transitioning from connectable to not connectable, or vice versa */ if (appSmStateIsConnectable(previous_state) != appSmStateIsConnectable(new_state)) { - /* Kick the rules engine. The rule for RULE_EVENT_PAGE_SCAN_UPDATE is + /* Kick the rules engine. The rule for RULE_EVENT_PAGE_SCAN_UPDATE is an always evaluated rule, so the event does not need to be reset */ appConnRulesSetEvent(appGetSmTask(), RULE_EVENT_PAGE_SCAN_UPDATE); } @@ -906,7 +906,7 @@ static void appSmHandleConManagerConnectionInd(CON_MANAGER_CONNECTION_IND_T* ind if (ind->ble) { - /*! Although we get this, indicating that the BLE link has changed + /*! Although we get this, indicating that the BLE link has changed state, our booleans that track this are not yet updated, so there is no point kicking the peer synchronisation. */ } @@ -916,7 +916,7 @@ static void appSmHandleConManagerConnectionInd(CON_MANAGER_CONNECTION_IND_T* ind if (!ind->ble) { /* A BREDR connection won't neccessarily evaluate rules. - And if we evaluate them now, the conditions needed for Upgrade control + And if we evaluate them now, the conditions needed for Upgrade control will not have changed. Send a message instead. */ MessageSend(appGetSmTask(), SM_INTERNAL_BREDR_CONNECTED, NULL); } @@ -1007,7 +1007,7 @@ static void appSmHandlePairingPeerPairConfirm(PAIRING_PEER_PAIR_CFM_T *cfm) /* peer pairing operation completed, always moved * back to STARTUP, if not successful the rules * will try again */ - appSetState(APP_STATE_STARTUP); + appSetState(APP_STATE_HANDSET_PAIRING); } break; @@ -1582,7 +1582,7 @@ static void appSmHandleConnRulesSelectMic(CONN_RULES_SELECT_MIC_T* crsm) static void appSmHandleConnRulesScoForwardingControl(CONN_RULES_SCO_FORWARDING_CONTROL_T* crsfc) { DEBUG_LOGF("appSmHandleConnRulesScoForwardingControl forwarding %u", crsfc->forwarding_control); - + if (crsfc->forwarding_control) { /* enabled forwarding */ @@ -1891,7 +1891,7 @@ static void appSmHandleInternalDeleteHandsets(void) break; } default: - DEBUG_LOGF("appSmHandleInternalDeleteHandsets bad state %u", + DEBUG_LOGF("appSmHandleInternalDeleteHandsets bad state %u", appGetState()); break; } @@ -1990,20 +1990,20 @@ static void appSmHandleUpgradeConnected(void) { case APP_STATE_IN_CASE_DFU: /* If we are in the special DFU case mode then start a fresh time - for dfu mode as well as a timer to trap for an application that + for dfu mode as well as a timer to trap for an application that opens then closes the upgrade connection. */ DEBUG_LOG("appSmHandleStartUpgrade, valid state to enter DFU"); appSmStartDfuTimer(); DEBUG_LOG("appSmHandleUpgradeConnected Start SM_INTERNAL_TIMEOUT_DFU_AWAIT_DISCONNECT %dms", appConfigDfuTimeoutCheckForSupportMs()); - MessageSendLater(appGetSmTask(), SM_INTERNAL_TIMEOUT_DFU_AWAIT_DISCONNECT, + MessageSendLater(appGetSmTask(), SM_INTERNAL_TIMEOUT_DFU_AWAIT_DISCONNECT, NULL, appConfigDfuTimeoutCheckForSupportMs()); break; default: /* In all other states and modes we don't need to do anything. - Start of an actual upgrade will be blocked if needed, + Start of an actual upgrade will be blocked if needed, see appSmHandleDfuAllow() */ break; } @@ -2296,7 +2296,7 @@ void appSmHandleMessage(Task task, MessageId id, Message message) break; case CONN_RULES_SCO_FORWARDING_CONTROL: appSmHandleConnRulesScoForwardingControl((CONN_RULES_SCO_FORWARDING_CONTROL_T*)message); - break; + break; case CONN_RULES_ANC_ENABLE: appKymeraAncEnable(); break; @@ -2546,7 +2546,7 @@ void appSmEnterDfuModeInCase(bool enable) { DEBUG_LOG("appSmEnterDfuModeInCase (re)start SM_INTERNAL_TIMEOUT_DFU_MODE_START %dms", appConfigDfuTimeoutToPlaceInCaseMs()); - MessageSendLater(appGetSmTask(), SM_INTERNAL_TIMEOUT_DFU_MODE_START, + MessageSendLater(appGetSmTask(), SM_INTERNAL_TIMEOUT_DFU_MODE_START, NULL, appConfigDfuTimeoutToPlaceInCaseMs()); } }

会有一系列问题

后来fae给的建议是在生产时完成对耳,然后将平台删除对耳的去掉

diff --git a/TWS/apps/applications/earbud/av_headset_ui.c b/TWS/apps/applications/earbud/av_headset_ui.c index 1b121e2..045db69 100644 --- a/TWS/apps/applications/earbud/av_headset_ui.c +++ b/TWS/apps/applications/earbud/av_headset_ui.c @@ -918,9 +918,16 @@ static void appUiHandleMessage(Task task, MessageId id, Message message) /* Delete Handset Pairings */ case APP_MFB_BUTTON_8_SECOND: - DEBUG_LOG("APP_MFB_BUTTON_6_SECOND"); + DEBUG_LOG("APP_MFB_BUTTON_8_SECOND"); if (appSmIsOutOfCase()) - appSmDeleteHandsets(); + { + if (!appSmIsPairing()) + appSmPairHandset(); + else + { + // TODO: Cancel pairing + } + } break; #if defined(HAVE_6_BUTTONS) || defined(HAVE_9_BUTTONS)

担心ota升级会有影响,就测试了一下,发现dfu不能用传统蓝牙升级,打开即可

diff --git a/TWS/apps/applications/earbud/av_headset_config.h b/TWS/apps/applications/earbud/av_headset_config.h index f67b9c3..08cf45a 100644 --- a/TWS/apps/applications/earbud/av_headset_config.h +++ b/TWS/apps/applications/earbud/av_headset_config.h @@ -22,7 +22,7 @@ /*! Can BREDR be used to perform upgrades when not in the case */ -#define appConfigDfuAllowBredrUpgradeOutOfCase() FALSE +#define appConfigDfuAllowBredrUpgradeOutOfCase() TRUE /*! Only allow upgrades when the request has been made by the user (through the UI)

制作dfu包

80-cg791-1_ab_adk_6.3.x_device_firmware_upgrade_user_guide.pdf

1 .用mde制作 安全密钥:

2.rebuild一下工程

3.生成bin

以下出现的跟据需求选

最后生成 通过gaia连接tws升级 这里试了很多次,不过都是接着升级的,出现了错误,后来发现要升级前,重新poweroff /poweron就没怎么出现以下的footer错误了 之后出现连接gaia连接不上,也是断电上电解决 的

最新回复(0)