記事の概要
Nordic社製のBLEモジュールのCentralサービスを作成します。
サービス名はorange_cとします。
実際に作成したプロジェクトは以下を参照ください。
https://github.com/matsuikosuke/nRF52_Central_and_Peripheral
サービスの実体
instance定義用のマクロを作成します。
# define BLE_ORANGE_C_DEF(_name) \
static ble_orange_c_t _name; \
NRF_SDH_BLE_OBSERVER(_name ## _obs, \
BLE_ORANGE_C_BLE_OBSERVER_PRIO, \
ble_orange_c_on_ble_evt, &_name)
複数のCentralサービスを使用する場合のマクロも作成しておきます。
# define BLE_ORANGE_C_ARRAY_DEF(_name, _cnt) \
static ble_orange_c_t _name[_cnt]; \
NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
BLE_ORANGE_C_BLE_OBSERVER_PRIO, \
ble_orange_c_on_ble_evt, &_name, _cnt)
UUID
UUIDを定義します。
ベースになるUUID、サービスUUID、サービスに付随するCharacteristicのUUIDを作成します。
例えばCharacteristicのUUIDはNotify用、Write用、read用などそれぞれの目的に合わせて使い分けます。
ベースUUIDのxxxxの部分にサービスUUIDやCharacteristicのUUIDを代入したものが使用されます。
//BASE-UUID:4ab4xxxx-65bc-126e-3b8c-8345de91b0d3
# define ORANGE_UUID_BASE {0xd3, 0xb0, 0x91, 0xde, 0x45, 0x83, 0x8c, 0x3b, \
0x6e, 0x12, 0xbc, 0x65, 0x00, 0x00, 0xb4, 0x4a}
# define ORANGE_UUID_SERVICE 0xABC0
# define ORANGE_READ_UUID_CHAR 0xABC1 //Read
# define ORANGE_INDICATION_UUID_CHAR 0xABC2 //Indication
# define ORANGE_NOTIFICATION_UUID_CHAR 0xABC3 //Notification
# define ORANGE_WRITE_UUID_CHAR 0xABC4 //Write
BLEイベントタイプの構造体
サービスに関するイベントを定義します。
BLE接続確立時のイベント、Peripheral側からデータ受信時(Notification、Indicationなど)のイベントの構造体を作成しておく必要があります。
typedef enum
{
BLE_ORANGE_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the ORANGE Service was discovered at the peer. */
BLE_ORANGE_C_EVT_BUTTON_NOTIFICATION, /**< Event indicating that a notification of the LED Button Button characteristic was received from the peer. */
BLE_ORANGE_C_EVT_NOTIFICATION, /**< Event indicating that a notification of the ORANGE characteristic has been received from the peer. */
BLE_ORANGE_C_EVT_INDICATION, /**< Event indicating that a indication of the ORANGE characteristic has been received from the peer. */
BLE_ORANGE_C_EVT_READ
} ble_orange_c_evt_type_t;
サービスに関するハンドラの構造体
notification、notificationのCCCDコールバック、indication、notifyのCCCDコールバック、writeのようなCentralサービスに関するハンドラの構造体を作成します。
typedef struct
{
uint16_t orange_notify_cccd_handle; /**< Handle of the CCCD of the Notify characteristic. */
uint16_t orange_notify_handle; /**< Handle of the Notify characteristic as provided by the SoftDevice. */
uint16_t orange_write_handle; /**< Handle of the Write characteristic as provided by the SoftDevice. */
uint16_t orange_indicate_cccd_handle; /**< Handle of the CCCD of the Indicate characteristic. */
uint16_t orange_indicate_handle; /**< Handle of the Indicate characteristic as provided by the SoftDevice. */
uint16_t orange_read_handle;
} orange_db_t;
CCCDコールバックについては以下を参照してください。
CCCDコールバック関数の設定
BLEイベントの構造体
BLEイベントの構造体を作成します。
イベントタイプ、接続ハンドラ、イベントハンドラから成る構造体を作成します。
typedef struct
{
ble_orange_c_evt_type_t evt_type; /**< Type of the event. */
uint16_t conn_handle; /**< Connection handle on which the event occured.*/
union
{
ble_button_t button; /**< Button value received. This is filled if the evt_type is @ref BLE_ORANGE_C_EVT_BUTTON_NOTIFICATION. */
orange_db_t peer_db; /**< Handles related to the ORANGE Service found on the peer device. This is filled if the evt_type is @ref BLE_ORANGE_C_EVT_DISCOVERY_COMPLETE.*/
} params;
} ble_orange_c_evt_t;
BLEベントに対する割り込み関数の定義
BLEイベントによる割り込み処理の関数を定義します。
/**@brief Event handler type.
*
* @details This is the type of the event handler that is to be provided by the application
* of this module in order to receive events.
*/
typedef void (* ble_orange_c_evt_handler_t) (ble_orange_c_t * p_ble_orange_c, ble_orange_c_evt_t * p_evt);
Centralサービスの構造体
Centralサービスに関する構造体を作成します。
// Forward declaration of the ble_orange_c_t type.
typedef struct ble_orange_c_s ble_orange_c_t;
/**@brief Orange Client structure. */
struct ble_orange_c_s
{
uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */
orange_db_t peer_orange_db; /**< Handles related to ORANGE on the peer. */
ble_orange_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Orange service. */
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
uint8_t uuid_type; /**< UUID type. */
nrf_ble_gq_t * p_gatt_queue; /**< Pointer to the BLE GATT Queue instance. */
};
Centralサービス初期化の構造体
Centralサービス初期設定の構造体を作成します。
/**@brief Orange Client initialization structure. */
typedef struct
{
ble_orange_c_evt_handler_t evt_handler; /**< Event handler to be called by the Orange Client module when there is an event related to the ORANGE Service. */
nrf_ble_gq_t * p_gatt_queue; /**< Pointer to the BLE GATT Queue instance. */
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
} ble_orange_c_init_t;
Centaralサービス初期化処理
各種ハンドラの設定、UUIDの設定を行います
uint32_t ble_orange_c_init(ble_orange_c_t * p_ble_orange_c, ble_orange_c_init_t * p_ble_orange_c_init)
{
uint32_t err_code;
ble_uuid_t orange_uuid;
ble_uuid128_t orange_base_uuid = {ORANGE_UUID_BASE};
VERIFY_PARAM_NOT_NULL(p_ble_orange_c);
VERIFY_PARAM_NOT_NULL(p_ble_orange_c_init);
VERIFY_PARAM_NOT_NULL(p_ble_orange_c_init->evt_handler);
VERIFY_PARAM_NOT_NULL(p_ble_orange_c_init->p_gatt_queue);
p_ble_orange_c->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ble_orange_c->evt_handler = p_ble_orange_c_init->evt_handler;
p_ble_orange_c->p_gatt_queue = p_ble_orange_c_init->p_gatt_queue;
p_ble_orange_c->error_handler = p_ble_orange_c_init->error_handler;
err_code = sd_ble_uuid_vs_add(&orange_base_uuid, &p_ble_orange_c->uuid_type);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
VERIFY_SUCCESS(err_code);
orange_uuid.type = p_ble_orange_c->uuid_type;
orange_uuid.uuid = ORANGE_UUID_SERVICE;
return ble_db_discovery_evt_register(&orange_uuid);
}
GATTエラー割り込み処理
static void gatt_error_handler(uint32_t nrf_error,
void * p_ctx,
uint16_t conn_handle)
{
ble_orange_c_t * p_ble_orange_c = (ble_orange_c_t *)p_ctx;
NRF_LOG_DEBUG("A GATT Client error has occurred on conn_handle: 0X%X", conn_handle);
if (p_ble_orange_c->error_handler != NULL)
{
p_ble_orange_c->error_handler(nrf_error);
}
}
BLEイベント処理
BLEイベント処理です。
BLEイベント割り込み処理ble_evt_handler
から呼び出されます。
p_ble_evt->header.evt_id
がBLEデータ受信イベントBLE_GATTC_EVT_HVX
かBLE切断イベントBLE_GAP_EVT_DISCONNECTED
やBLE_GATTC_EVT_READ_RSP
かを判定して分岐し、イベントに対応する処理を実行します。
void ble_orange_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
if ((p_context == NULL) || (p_ble_evt == NULL))
{
return;
}
ble_orange_c_t * p_ble_orange_c = (ble_orange_c_t *)p_context;
switch (p_ble_evt->header.evt_id)
{
case BLE_GATTC_EVT_HVX:
on_hvx(p_ble_orange_c, p_ble_evt);
break;
case BLE_GATTC_EVT_READ_RSP:
on_read_rsp(p_ble_orange_c, p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnected(p_ble_orange_c, p_ble_evt);
break;
default:
break;
}
}
BLE_GATTC_EVT_HVX:BLEデータ受信イベント処理
Notification、Indicationを受信した時に行う処理です。
必須の処理に加えて、アプリケーションの仕様に基づいて処理を追加ください。
static void on_hvx(ble_orange_c_t * p_ble_orange_c, ble_evt_t const * p_ble_evt)
{
// Check if the event is on the link for this instance.
if (p_ble_orange_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
{
return;
}
// Check if this is a SmartAgri notification.
if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_orange_c->peer_orange_db.orange_notify_handle)
{
ble_orange_c_evt_t ble_orange_c_evt;
uint32_t index = 0;
ble_orange_c_evt.evt_type = BLE_ORANGE_C_EVT_NOTIFICATION;
ble_orange_c_evt.conn_handle = p_ble_orange_c->conn_handle; //By seeing this information, it is determined which device the transmission is from.
for (int i = 0; i < BLE_NOTIFICATION_DATA_LENGTH; i ++)
{
if (index >= p_ble_evt->evt.gattc_evt.params.hvx.len)
{
break;
}
notification_buf[i] = p_ble_evt->evt.gattc_evt.params.hvx.data[index];
index += 1;
}
p_ble_orange_c->evt_handler(p_ble_orange_c, &ble_orange_c_evt);
}
// Check if this is a SmartAgri indication.
if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_orange_c->peer_orange_db.orange_indicate_handle)
{
ble_orange_c_evt_t ble_orange_c_evt;
uint32_t index = 0;
ble_orange_c_evt.evt_type = BLE_ORANGE_C_EVT_INDICATION;
ble_orange_c_evt.conn_handle = p_ble_orange_c->conn_handle; //By seeing this information, it is determined which device the transmission is from.
for (int i = 0; i < BLE_INDICATION_DATA_LENGTH; i ++)
{
if (index >= p_ble_evt->evt.gattc_evt.params.hvx.len)
{
break;
}
indication_buf[i] = p_ble_evt->evt.gattc_evt.params.hvx.data[index];
index += 1;
}
// In case of Indicate, you have to add the following function that returns an ACK response
sd_ble_gattc_hv_confirm(ble_orange_c_evt.conn_handle, p_ble_orange_c->peer_orange_db.orange_indicate_handle);
p_ble_orange_c->evt_handler(p_ble_orange_c, &ble_orange_c_evt);
}
}
この処理の内容について以下に説明します。
接続ハンドラの確認
// Check if the event is on the link for this instance.
if (p_ble_orange_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
{
return;
}
p_ble_evt->evt.gattc_evt.conn_handle
がp_ble_orange_c->conn_handle
と一致しているか確認します。
複数のCentralサービスを実装している場合、p_ble_evt->evt.gattc_evt.conn_handle
には他のサービスの接続ハンドラが格納されているかもしれません。
その場合はOrangeサービスを適用していはいけないので処理を終了します。
p_ble_evt->evt.gattc_evt.params.hvx.handleの確認
p_ble_evt->evt.gattc_evt.params.hvx.handle
がサービスハンドラ構造体orange_db_t
のどれに対応するか確認します。
ただしhvx.handle``には受信に関するイベントしかないので、今回はNotificationもしくはIndicationに関するイベントである
orange_notify_handleか
orange_indicate_handle`のどちらかになります。
受信データの確認
p_ble_evt->evt.gattc_evt.params.hvx.len
には受信データのサイズが格納されています。
p_ble_evt->evt.gattc_evt.params.hvx.data[]
には受信データが格納されています。
割り込み処理はなるべく短時間で済ませたいので、データをバッファに一時退避させてから、mainループ内で受信データの解析処理をした方がいいと考えて、受信データをindication_buf
に格納しています。
受信タイプの保存と受信割り込み処理の実行
ble_orange_c_evt.evt_type
にイベントタイプを保存します。
ble_orange_c_evt.conn_handle
にはp_ble_orange_c->conn_handle
を保存します。
これらを用いてイベントに対応する割り込み処理を呼び出します。
p_ble_orange_c->evt_handler(p_ble_orange_c, &ble_orange_c_evt);
これにより割り込み処理orange_c_evt_handler
において、BLEイベントble_orange_c_evt_type_t
に対応する処理が実行されます。
今回の場合はBLEイベントBLE_ORANGE_C_EVT_NOTIFICATION
もしくはBLE_ORANGE_C_EVT_INDICATION
が使用されます。
Indication ACK応答
Indication受信時には、CentralからPeripheralに対してACK応答を送信しないといけません。
以下の処理をそれを実行しています。
// In case of Indicate, you have to add the following function that returns an ACK response
sd_ble_gattc_hv_confirm(ble_orange_c_evt.conn_handle, p_ble_orange_c->peer_orange_db.orange_indicate_handle);
BLE_GAP_EVT_DISCONNECTED:BLE切断イベント処理
BLE切断時に行う処理です。
各種ハンドラを初期化します。
static void on_disconnected(ble_orange_c_t * p_ble_orange_c, ble_evt_t const * p_ble_evt)
{
if (p_ble_orange_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
{
p_ble_orange_c->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ble_orange_c->peer_orange_db.orange_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
p_ble_orange_c->peer_orange_db.orange_notify_handle = BLE_GATT_HANDLE_INVALID;
p_ble_orange_c->peer_orange_db.orange_write_handle = BLE_GATT_HANDLE_INVALID;
p_ble_orange_c->peer_orange_db.orange_indicate_cccd_handle = BLE_GATT_HANDLE_INVALID;
p_ble_orange_c->peer_orange_db.orange_indicate_handle = BLE_GATT_HANDLE_INVALID;
}
}
BLE_GATTC_EVT_READ_RSP:Read受信処理
Read要求を実行することでPeripheralからReadデータが送信されます。
BLE_GATTC_EVT_READ_RSP
は、そのデータを受信時に発生するイベントです。
static void on_read_rsp(ble_orange_c_t *p_ble_orange_c, ble_evt_t const *p_ble_evt)
{
ble_gattc_evt_read_rsp_t const *p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
ble_orange_c_evt_t ble_orange_c_evt;
// Check if the event is on the link for this instance and the event handler is present.
if ((p_ble_orange_c->evt_handler == NULL) ||
(p_ble_orange_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle))
{
return;
}
if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS)
{
if (p_response->handle == p_ble_orange_c->peer_orange_db.orange_read_handle)
{
ble_orange_c_evt.evt_type = BLE_ORANGE_C_EVT_READ;
ble_orange_c_evt.conn_handle = p_ble_orange_c->conn_handle;
NRF_LOG_INFO("Received read data %lu of length %u", * (uint32_t *) p_response->data, p_response->len);
for(int i=0; i<p_response->len; i++)
{
central_read_buf[i] = p_response->data[i];
}
p_ble_orange_c->evt_handler(p_ble_orange_c, &ble_orange_c_evt);
}
}
}
Write送信処理
CentralからPeripheralへデータをWrite送信する処理です。
この関数はstatusに格納したデータを送信します。
uint32_t ble_orange_status_send(ble_orange_c_t * p_ble_orange_c, uint8_t status)
{
VERIFY_PARAM_NOT_NULL(p_ble_orange_c);
if (p_ble_orange_c->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
NRF_LOG_DEBUG("Writing orange status 0x%x", status);
nrf_ble_gq_req_t write_req;
memset(&write_req, 0, sizeof(nrf_ble_gq_req_t));
write_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
write_req.error_handler.cb = gatt_error_handler;
write_req.error_handler.p_ctx = p_ble_orange_c;
write_req.params.gattc_write.handle = p_ble_orange_c->peer_orange_db.orange_write_handle;
write_req.params.gattc_write.len = sizeof(status);
write_req.params.gattc_write.p_value = &status;
write_req.params.gattc_write.offset = 0;
write_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_CMD;
return nrf_ble_gq_item_add(p_ble_orange_c->p_gatt_queue, &write_req, p_ble_orange_c->conn_handle);
}
Read要求
Read要求ble_orange_read_request
を実行することで、PeripheralからReadデータが返ってきます。
Readデータ受信時にはble_orange_c_on_ble_evt
割り込み処理においてイベントBLE_GATTC_EVT_READ_RSP
が呼び出されます。
uint32_t ble_orange_read_request(ble_orange_c_t * p_ble_orange_c)
{
VERIFY_PARAM_NOT_NULL(p_ble_orange_c);
if (p_ble_orange_c->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
NRF_LOG_DEBUG("Read orange");
nrf_ble_gq_req_t read_req;
memset(&read_req, 0, sizeof(nrf_ble_gq_req_t));
read_req.type = NRF_BLE_GQ_REQ_GATTC_READ;
read_req.error_handler.cb = gatt_error_handler;
read_req.error_handler.p_ctx = p_ble_orange_c;
read_req.params.gattc_read.handle = p_ble_orange_c->peer_orange_db.orange_read_handle;
return nrf_ble_gq_item_add(p_ble_orange_c->p_gatt_queue, &read_req, p_ble_orange_c->conn_handle);
}
Discoveryイベント処理
Discoveryイベント処理においては、CentralサービスとのBLE接続確立後、Characteristicに対応するハンドラを設定します。
p_evt->params.discovered_db.char_count
にはCentralサービスに含まれるCharacteristic数が格納されています。
それらのCharacteristicのUUIDp_char->characteristic.uuid.uuid
を1つずつ確認し、Characteristicに対応するハンドルを設定します。
またconn_handle以外のハンドラが既に設定済みでないかを確認し、設定済みなら既存の設定evt.params.peer_db
を代入します。
void ble_orange_on_db_disc_evt(ble_orange_c_t * p_ble_orange_c, ble_db_discovery_evt_t const * p_evt)
{
// Check if the Test Service was discovered.
if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
p_evt->params.discovered_db.srv_uuid.uuid == ORANGE_UUID_SERVICE &&
p_evt->params.discovered_db.srv_uuid.type == p_ble_orange_c->uuid_type)
{
ble_orange_c_evt_t evt;
evt.evt_type = BLE_ORANGE_C_EVT_DISCOVERY_COMPLETE;
evt.conn_handle = p_evt->conn_handle;
for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
const ble_gatt_db_char_t * p_char = &(p_evt->params.discovered_db.charateristics[i]);
switch (p_char->characteristic.uuid.uuid)
{
case ORANGE_WRITE_UUID_CHAR:
evt.params.peer_db.orange_write_handle = p_char->characteristic.handle_value;
break;
case ORANGE_NOTIFICATION_UUID_CHAR:
evt.params.peer_db.orange_notify_handle = p_char->characteristic.handle_value;
evt.params.peer_db.orange_notify_cccd_handle = p_char->cccd_handle;
break;
case ORANGE_INDICATION_UUID_CHAR:
evt.params.peer_db.orange_indicate_handle = p_char->characteristic.handle_value;
evt.params.peer_db.orange_indicate_cccd_handle = p_char->cccd_handle;
break;
default:
break;
}
}
NRF_LOG_DEBUG("Orange Service discovered at peer.");
//If the instance was assigned prior to db_discovery, assign the db_handles
if (p_ble_orange_c->conn_handle != BLE_CONN_HANDLE_INVALID)
{
if ((p_ble_orange_c->peer_orange_db.orange_write_handle == BLE_GATT_HANDLE_INVALID)&&
(p_ble_orange_c->peer_orange_db.orange_notify_handle == BLE_GATT_HANDLE_INVALID)&&
(p_ble_orange_c->peer_orange_db.orange_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)&&
(p_ble_orange_c->peer_orange_db.orange_indicate_handle == BLE_GATT_HANDLE_INVALID)&&
(p_ble_orange_c->peer_orange_db.orange_indicate_cccd_handle == BLE_GATT_HANDLE_INVALID))
{
p_ble_orange_c->peer_orange_db = evt.params.peer_db;
}
}
p_ble_orange_c->evt_handler(p_ble_orange_c, &evt);
}
}
CCCDコールバック設定処理
CCCDコールバック設定処理です。
BLEイベント割り込み処理orange_c_evt_handler
のBLE_ORANGE_C_EVT_DISCOVERY_COMPLETE
イベント発生時に実行します。
static uint32_t cccd_configure_notify(ble_orange_c_t * p_ble_orange_c, bool enable)
{
NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d",
p_ble_orange_c->peer_orange_db.orange_notify_cccd_handle,
p_ble_orange_c->conn_handle);
nrf_ble_gq_req_t cccd_req;
uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0;
uint8_t cccd[WRITE_MESSAGE_LENGTH];
cccd[0] = LSB_16(cccd_val);
cccd[1] = MSB_16(cccd_val);
cccd_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
cccd_req.error_handler.cb = gatt_error_handler;
cccd_req.error_handler.p_ctx = p_ble_orange_c;
cccd_req.params.gattc_write.handle = p_ble_orange_c->peer_orange_db.orange_notify_cccd_handle;
cccd_req.params.gattc_write.len = WRITE_MESSAGE_LENGTH;
cccd_req.params.gattc_write.offset = 0;
cccd_req.params.gattc_write.p_value = cccd;
cccd_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
return nrf_ble_gq_item_add(p_ble_orange_c->p_gatt_queue, &cccd_req, p_ble_orange_c->conn_handle);
}
static uint32_t cccd_configure_indicate(ble_orange_c_t * p_ble_orange_c, bool enable)
{
NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d",
p_ble_orange_c->peer_orange_db.orange_indicate_cccd_handle,
p_ble_orange_c->conn_handle);
nrf_ble_gq_req_t cccd_req;
uint16_t cccd_val = enable ? BLE_GATT_HVX_INDICATION : 0;
uint8_t cccd[WRITE_MESSAGE_LENGTH];
cccd[0] = LSB_16(cccd_val);
cccd[1] = MSB_16(cccd_val);
cccd_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
cccd_req.error_handler.cb = gatt_error_handler;
cccd_req.error_handler.p_ctx = p_ble_orange_c;
cccd_req.params.gattc_write.handle = p_ble_orange_c->peer_orange_db.orange_indicate_cccd_handle;
cccd_req.params.gattc_write.len = WRITE_MESSAGE_LENGTH;
cccd_req.params.gattc_write.offset = 0;
cccd_req.params.gattc_write.p_value = cccd;
cccd_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
return nrf_ble_gq_item_add(p_ble_orange_c->p_gatt_queue, &cccd_req, p_ble_orange_c->conn_handle);
}
uint32_t ble_orange_c_orange_notification_enable(ble_orange_c_t * p_ble_orange_c)
{
VERIFY_PARAM_NOT_NULL(p_ble_orange_c);
if (p_ble_orange_c->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
return cccd_configure_notify(p_ble_orange_c, true);
}
uint32_t ble_orange_c_orange_indication_enable(ble_orange_c_t * p_ble_orange_c)
{
VERIFY_PARAM_NOT_NULL(p_ble_orange_c);
if (p_ble_orange_c->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
return cccd_configure_indicate(p_ble_orange_c, true);
}
BLEハンドラ登録処理
BLEハンドラ登録処理です。BLEイベント割り込み処理orange_c_evt_handler
のBLE_ORANGE_C_EVT_DISCOVERY_COMPLETE
イベント発生時に実行します。
uint32_t ble_orange_c_handles_assign(ble_orange_c_t * p_ble_orange_c,
uint16_t conn_handle,
const orange_db_t * p_peer_handles)
{
VERIFY_PARAM_NOT_NULL(p_ble_orange_c);
p_ble_orange_c->conn_handle = conn_handle;
if (p_peer_handles != NULL)
{
p_ble_orange_c->peer_orange_db = *p_peer_handles;
}
return nrf_ble_gq_conn_handle_register(p_ble_orange_c->p_gatt_queue, conn_handle);
}