Skip to content
Snippets Groups Projects
Commit 9bfe1a01 authored by schneider's avatar schneider
Browse files

feat(ble): Add ATT client module

parent 9225c7d4
No related branches found
No related tags found
No related merge requests found
#pragma once
#include <stdint.h>
#include "wsf_types.h"
#include "att_api.h"
#include "dm_api.h"
#define CARD10_UUID_SUFFIX \
0x42, 0x23, 0x42, 0x23, 0x42, 0x23, 0x42, 0x23, 0x42, 0x23, 0x42, 0x23
#define CARD10_UUID_PREFIX 0x02, 0x23, 0x42
......@@ -16,3 +22,7 @@
/*************************************************************************************************/
void BleStart(void);
/* ATT client module interface. Used by main BLE module */
void bleValueUpdate(attEvt_t *pMsg);
void bleDiscCback(dmConnId_t connId, uint8_t status);
#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 "gap/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 */
......@@ -143,6 +143,12 @@ static const smpCfg_t bleSmpCfg =
.attemptExp = 2, /*! Exponent to raise attemptTimeout on maxAttempts */
};
/*! Configurable parameters for service and characteristic discovery */
static const appDiscCfg_t bleDiscCfg =
{
FALSE /*! TRUE to wait for a secure connection before initiating discovery */
};
/* Configuration structure */
static const attCfg_t bleAttCfg =
{
......@@ -676,7 +682,6 @@ static void scannerScanReport(dmEvt_t *pMsg)
}
}
/*************************************************************************************************/
/*!
* \brief Process messages from the event handler.
......@@ -696,6 +701,11 @@ static void bleProcMsg(bleMsg_t *pMsg)
BasProcMsg(&pMsg->hdr);
break;
case ATTC_READ_RSP:
case ATTC_HANDLE_VALUE_IND:
bleValueUpdate((attEvt_t *) pMsg);
break;
case ATTS_HANDLE_VALUE_CNF:
BasProcMsg(&pMsg->hdr);
break;
......@@ -861,10 +871,12 @@ static void BleHandlerInit(void)
pAppSlaveCfg = (appSlaveCfg_t *) &bleSlaveCfg;
pAppSecCfg = (appSecCfg_t *) &bleSecCfg;
pAppUpdateCfg = (appUpdateCfg_t *) &bleUpdateCfg;
pAppDiscCfg = (appDiscCfg_t *) &bleDiscCfg;
pAppMasterCfg = (appMasterCfg_t *) &scannerMasterCfg;
/* Initialize application framework */
AppSlaveInit();
AppDiscInit();
/* Set stack configuration pointers */
pSmpCfg = (smpCfg_t *) &bleSmpCfg;
......@@ -898,10 +910,15 @@ static void BleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
/* process security-related messages */
AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
/* process discovery-related messages */
AppDiscProcDmMsg((dmEvt_t *) pMsg);
}
else if (pMsg->event >= ATT_CBACK_START && pMsg->event <= ATT_CBACK_END)
{
LOG_INFO("ble", "Ble got evt %d: %s", pMsg->event, att_events[pMsg->event - ATT_CBACK_START]);
/* process discovery-related ATT messages */
AppDiscProcAttMsg((attEvt_t *) pMsg);
}
else if (pMsg->event >= L2C_COC_CBACK_START && pMsg->event <= L2C_COC_CBACK_CBACK_END)
{
......@@ -936,6 +953,9 @@ void BleStart(void)
AttConnRegister(AppServerConnCback);
AttsCccRegister(BLE_NUM_CCC_IDX, (attsCccSet_t *) bleCccSet, bleCccCback);
/* Register for app framework discovery callbacks */
AppDiscRegister(bleDiscCback);
/* Initialize attribute server database */
SvcCoreAddGroup();
SvcDisAddGroup(); // Device Information Service
......
......@@ -2,6 +2,7 @@ ble_sources = files(
'ble.c',
'stack.c',
'ble_main.c',
'ble_attc.c',
'svc_dis.c',
'svc_core.c',
'bondings.c',
......
......@@ -184,6 +184,7 @@ void StackInit(void)
AttHandlerInit(handlerId);
AttsInit();
AttsIndInit();
AttcInit();
handlerId = WsfOsSetNextHandler(SmpHandler);
SmpHandlerInit(handlerId);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment