#include <stdint.h> #include <stdbool.h> #include "wsf_types.h" #include "util/bstream.h" #include "app_api.h" #include "app_cfg.h" #include "att_api.h" #include "dm_api.h" #include "gatt/gatt_api.h" #include "profiles/gap_api.h" #include "tipc/tipc_api.h" #include "modules/log.h" /* card10: * copied from lib/sdk/Libraries/BTLE/stack/ble-profiles/sources/apps/tag/tag_main.c * and lib/sdk/Libraries/BTLE/stack/ble-profiles/sources/apps/watch/watch_main.c */ /* clang-format off */ /* clang-formet turned off for easier diffing against orginal file */ /************************************************************************************************** ATT Client Discovery Data **************************************************************************************************/ static uint16_t s_hdlList[APP_DB_HDL_LIST_LEN]; /*! the Client handle list, s_hdlList[], is set as follows: * * ------------------------------- <- BLE_DISC_GATT_START * | GATT svc changed handle | * ------------------------------- * | GATT svc changed ccc handle | * ------------------------------- <- BLE_DISC_GAP_START * | GAP central addr res handle | * ------------------------------- * | GAP RPA Only handle | * ------------------------------- <- BLE_DISC_CTS_START * | TIPC_CTS_CT_HDL_IDX | * ------------------------------- * | TIPC_CTS_CT_CCC_HDL_IDX | * ------------------------------- * | TIPC_CTS_LTI_HDL_IDX | * ------------------------------- * | TIPC_CTS_RTI_HDL_IDX | * ------------------------------- */ /*! Start of each service's handles in the the handle list */ #define BLE_DISC_GATT_START 0 #define BLE_DISC_GAP_START (BLE_DISC_GATT_START + GATT_HDL_LIST_LEN) #define BLE_DISC_CTS_START (BLE_DISC_GAP_START + GAP_HDL_LIST_LEN) #define BLE_DISC_HDL_LIST_LEN (BLE_DISC_CTS_START + TIPC_CTS_HDL_LIST_LEN) /*! Pointers into handle list for each service's handles */ static uint16_t *pBleGattHdlList = &s_hdlList[BLE_DISC_GATT_START]; static uint16_t *pBleGapHdlList = &s_hdlList[BLE_DISC_GAP_START]; static uint16_t *pBleCtsHdlList = &s_hdlList[BLE_DISC_CTS_START]; /* sanity check: make sure handle list length is <= app db handle list length */ extern char wsf_ct_assert[(BLE_DISC_HDL_LIST_LEN <= APP_DB_HDL_LIST_LEN) ? 1 : -1]; /************************************************************************************************** ATT Client Data **************************************************************************************************/ /* Default value for GATT service changed ccc descriptor */ static const uint8_t bleGattScCccVal[] = {UINT16_TO_BYTES(ATT_CLIENT_CFG_INDICATE)}; /* List of characteristics to configure */ static const attcDiscCfg_t bleDiscCfgList[] = { /* Write: GATT service changed ccc descriptor */ {bleGattScCccVal, sizeof(bleGattScCccVal), (GATT_SC_CCC_HDL_IDX + BLE_DISC_GATT_START)}, /* Read: GAP central address resolution attribute */ {NULL, 0, (GAP_CAR_HDL_IDX + BLE_DISC_GAP_START)}, /* Read: CTS Current time */ {NULL, 0, (TIPC_CTS_CT_HDL_IDX + BLE_DISC_CTS_START)}, /* Read: CTS Local time information */ {NULL, 0, (TIPC_CTS_LTI_HDL_IDX + BLE_DISC_CTS_START)}, /* Read: CTS Reference time information */ {NULL, 0, (TIPC_CTS_RTI_HDL_IDX + BLE_DISC_CTS_START)}, }; /* Characteristic configuration list length */ #define BLE_DISC_CFG_LIST_LEN (sizeof(bleDiscCfgList) / sizeof(attcDiscCfg_t)) /* sanity check: make sure configuration list length is <= handle list length */ extern char wsf_ct_assert[(BLE_DISC_CFG_LIST_LEN <= BLE_DISC_HDL_LIST_LEN) ? 1 : -1]; /************************************************************************************************** ATT Client Discovery Data **************************************************************************************************/ /*! Discovery states: enumeration of services to be discovered */ enum { BLE_DISC_GATT_SVC, /* GATT service */ BLE_DISC_GAP_SVC, /* GAP service */ BLE_DISC_SLAVE_CTS_SVC, BLE_DISC_SVC_MAX /* Discovery complete */ }; /*************************************************************************************************/ /*! * \brief Process a received ATT indication. * * \param pMsg Pointer to ATT callback event message. * * \return None. */ /*************************************************************************************************/ void bleValueUpdate(attEvt_t *pMsg) { if (pMsg->hdr.status == ATT_SUCCESS) { /* determine which profile the handle belongs to */ /* GATT */ if (GattValueUpdate(pBleGattHdlList, pMsg) == ATT_SUCCESS) { return; } /* GAP */ if (GapValueUpdate(pBleGapHdlList, pMsg) == ATT_SUCCESS) { return; } /* current time */ if (TipcCtsValueUpdate(pBleCtsHdlList, pMsg) == ATT_SUCCESS) { return; } } } /*************************************************************************************************/ /*! * \brief GAP service discovery has completed. * * \param connId Connection identifier. * * \return None. */ /*************************************************************************************************/ static void bleDiscGapCmpl(dmConnId_t connId) { appDbHdl_t dbHdl; /* if RPA Only attribute found on peer device */ if ((pBleGapHdlList[GAP_RPAO_HDL_IDX] != ATT_HANDLE_NONE) && ((dbHdl = AppDbGetHdl(connId)) != APP_DB_HDL_NONE)) { /* update DB */ AppDbSetPeerRpao(dbHdl, TRUE); } } /*************************************************************************************************/ /*! * \brief Discovery callback. * * \param connId Connection identifier. * \param status Service or configuration status. * * \return None. */ /*************************************************************************************************/ void bleDiscCback(dmConnId_t connId, uint8_t status) { static uint8_t discState; static const char * const disc_status[] = { "APP_DISC_INIT", /*!< \brief No discovery or configuration complete */ "APP_DISC_SEC_REQUIRED", /*!< \brief Security required to complete configuration */ "APP_DISC_START", /*!< \brief Service discovery started */ "APP_DISC_CMPL", /*!< \brief Service discovery complete */ "APP_DISC_FAILED", /*!< \brief Service discovery failed */ "APP_DISC_CFG_START", /*!< \brief Service configuration started */ "APP_DISC_CFG_CONN_START", /*!< \brief Configuration for connection setup started */ "APP_DISC_CFG_CMPL" /*!< \brief Service configuration complete */ }; LOG_INFO("ble", "bleDiscCback: %s (%d)", disc_status[status], status); switch(status) { case APP_DISC_INIT: /* set handle list when initialization requested */ AppDiscSetHdlList(connId, BLE_DISC_HDL_LIST_LEN, s_hdlList); break; case APP_DISC_SEC_REQUIRED: /* request security */ AppSlaveSecurityReq(connId); break; case APP_DISC_START: /* initialize discovery state */ discState = BLE_DISC_GATT_SVC; GattDiscover(connId, pBleGattHdlList); break; case APP_DISC_FAILED: case APP_DISC_CMPL: if (status == APP_DISC_FAILED && pAppCfg->abortDisc) { if (discState == BLE_DISC_GATT_SVC) { /* discovery failed */ AppDiscComplete(connId, APP_DISC_FAILED); break; } } /* next discovery state */ discState++; if (discState == BLE_DISC_GAP_SVC) { /* discover GAP service */ GapDiscover(connId, pBleGapHdlList); } else if (discState == BLE_DISC_SLAVE_CTS_SVC) { /* discover current time service */ TipcCtsDiscover(connId, pBleCtsHdlList); } else { /* discovery complete */ AppDiscComplete(connId, APP_DISC_CMPL); /* GAP service discovery completed */ bleDiscGapCmpl(connId); /* start configuration */ AppDiscConfigure(connId, APP_DISC_CFG_START, BLE_DISC_CFG_LIST_LEN, (attcDiscCfg_t *) bleDiscCfgList, BLE_DISC_HDL_LIST_LEN, s_hdlList); } break; case APP_DISC_CFG_START: /* start configuration */ AppDiscConfigure(connId, APP_DISC_CFG_START, BLE_DISC_CFG_LIST_LEN, (attcDiscCfg_t *) bleDiscCfgList, BLE_DISC_HDL_LIST_LEN, s_hdlList); break; case APP_DISC_CFG_CMPL: AppDiscComplete(connId, APP_DISC_CFG_CMPL); break; case APP_DISC_CFG_CONN_START: /* no connection setup configuration for this application */ break; default: break; } } /* clang-format on */