add more nimble example
1. make heart rate sensor example really work using nRF Toolbox HRM 2. add master device scan example 3. add gatt server example(seems not working)
This commit is contained in:
6
examples/nimble_heart_rate_sensor/README_cn.md
Normal file
6
examples/nimble_heart_rate_sensor/README_cn.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# NimBLE心率传感器案例
|
||||
|
||||
本案例通过实现一个模拟的BLE心率传感器,展示如何通过GATT notification来实现异步的数据传输。
|
||||
|
||||
编译工程并烧写后,使用手机或任何能支持心率传感器app(建议使用Nordic官方的`nRF Toolbox`工具)的设备连接开发板创建的Heart Rate Sensor蓝牙设备,app界面上可以获取到传感器所在位置以及上传过来的心率信息。
|
||||
|
13
examples/nimble_heart_rate_sensor/README_en.md
Normal file
13
examples/nimble_heart_rate_sensor/README_en.md
Normal file
@@ -0,0 +1,13 @@
|
||||
NimBLE Heart Rate Sensor Example
|
||||
================================
|
||||
This example demonstrates how to implement asynchronous data transfer using GATT
|
||||
notifications by implementing a mock-up BLE heart rate sensor. Once flashed on
|
||||
a node, you can connect to it using any phone or device capable of using such a
|
||||
heart rate sensor, e.g. Nordics `nRF Toolbox` for Android
|
||||
(https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrftoolbox).
|
||||
|
||||
The heart rate sensor is simulated by simply providing an up- and down counter
|
||||
for its BPM value.
|
||||
|
||||
On top of the heart rate service, this example implements the device information
|
||||
as well as the battery service.
|
46
examples/nimble_heart_rate_sensor/blehr_sens.h
Normal file
46
examples/nimble_heart_rate_sensor/blehr_sens.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef H_BLEHR_SENSOR_
|
||||
#define H_BLEHR_SENSOR_
|
||||
|
||||
#include "nimble/ble.h"
|
||||
#include "modlog/modlog.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Heart-rate configuration */
|
||||
#define GATT_HRS_UUID 0x180D
|
||||
#define GATT_HRS_MEASUREMENT_UUID 0x2A37
|
||||
#define GATT_HRS_BODY_SENSOR_LOC_UUID 0x2A38
|
||||
#define GATT_DEVICE_INFO_UUID 0x180A
|
||||
#define GATT_MANUFACTURER_NAME_UUID 0x2A29
|
||||
#define GATT_MODEL_NUMBER_UUID 0x2A24
|
||||
|
||||
extern uint16_t hrs_hrm_handle;
|
||||
|
||||
int gatt_svr_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
238
examples/nimble_heart_rate_sensor/gatt_svr.c
Normal file
238
examples/nimble_heart_rate_sensor/gatt_svr.c
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/ble_uuid.h"
|
||||
#include "blehr_sens.h"
|
||||
|
||||
#include "services/dis/ble_svc_dis.h"
|
||||
#include "services/bas/ble_svc_bas.h"
|
||||
|
||||
static const char *manuf_name = "TencentOS tiny";
|
||||
static const char *model_num = "TOS HR Sensor";
|
||||
uint16_t hrs_hrm_handle;
|
||||
|
||||
static const char *serial_num = "deadbeef-baddad";
|
||||
static const char *firmware_ver = "1.0.0";
|
||||
static const char *hardware_ver = "V1.0";
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_heart_rate(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_battery_level(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
/* GATT service definitions */
|
||||
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
|
||||
{
|
||||
/* Service: Heart-rate */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = BLE_UUID16_DECLARE(GATT_HRS_UUID),
|
||||
.characteristics = (struct ble_gatt_chr_def[]) { {
|
||||
/* Characteristic: Heart-rate measurement */
|
||||
.uuid = BLE_UUID16_DECLARE(GATT_HRS_MEASUREMENT_UUID),
|
||||
.access_cb = gatt_svr_chr_access_heart_rate,
|
||||
.val_handle = &hrs_hrm_handle,
|
||||
.flags = BLE_GATT_CHR_F_NOTIFY,
|
||||
}, {
|
||||
/* Characteristic: Body sensor location */
|
||||
.uuid = BLE_UUID16_DECLARE(GATT_HRS_BODY_SENSOR_LOC_UUID),
|
||||
.access_cb = gatt_svr_chr_access_heart_rate,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
}, {
|
||||
0, /* No more characteristics in this service */
|
||||
}, }
|
||||
},
|
||||
|
||||
{
|
||||
/* Service: Device Information */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = BLE_UUID16_DECLARE(GATT_DEVICE_INFO_UUID),
|
||||
.characteristics = (struct ble_gatt_chr_def[]) { {
|
||||
/* Characteristic: * Manufacturer name */
|
||||
.uuid = BLE_UUID16_DECLARE(GATT_MANUFACTURER_NAME_UUID),
|
||||
.access_cb = gatt_svr_chr_access_device_info,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
}, {
|
||||
/* Characteristic: Model number string */
|
||||
.uuid = BLE_UUID16_DECLARE(GATT_MODEL_NUMBER_UUID),
|
||||
.access_cb = gatt_svr_chr_access_device_info,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
}, {
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_SERIAL_NUMBER),
|
||||
.access_cb = gatt_svr_chr_access_device_info,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
}, {
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_FIRMWARE_REVISION),
|
||||
.access_cb = gatt_svr_chr_access_device_info,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
}, {
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_HARDWARE_REVISION),
|
||||
.access_cb = gatt_svr_chr_access_device_info,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
}, {
|
||||
0, /* No more characteristics in this service */
|
||||
}, }
|
||||
},
|
||||
{
|
||||
/* Service: Battery Level */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_BAS_UUID16),
|
||||
.characteristics = (struct ble_gatt_chr_def[]) { {
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_BAS_CHR_UUID16_BATTERY_LEVEL),
|
||||
.access_cb = gatt_svr_chr_access_battery_level,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
}, {
|
||||
0, /* No more characteristics in this service */
|
||||
}, }
|
||||
},
|
||||
{
|
||||
0, /* No more services */
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_heart_rate(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
/* Sensor location, set to "Chest" */
|
||||
static uint8_t body_sens_loc = 0x01;
|
||||
uint16_t uuid;
|
||||
int rc;
|
||||
|
||||
uuid = ble_uuid_u16(ctxt->chr->uuid);
|
||||
|
||||
if (uuid == GATT_HRS_BODY_SENSOR_LOC_UUID) {
|
||||
rc = os_mbuf_append(ctxt->om, &body_sens_loc, sizeof(body_sens_loc));
|
||||
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
uint16_t uuid;
|
||||
int rc;
|
||||
|
||||
uuid = ble_uuid_u16(ctxt->chr->uuid);
|
||||
|
||||
if (uuid == GATT_MANUFACTURER_NAME_UUID) {
|
||||
rc = os_mbuf_append(ctxt->om, manuf_name, strlen(manuf_name));
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
if (uuid == GATT_MODEL_NUMBER_UUID) {
|
||||
rc = os_mbuf_append(ctxt->om, model_num, strlen(model_num));
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
if (uuid == BLE_SVC_DIS_CHR_UUID16_SERIAL_NUMBER) {
|
||||
rc = os_mbuf_append(ctxt->om, serial_num, strlen(serial_num));
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
if (uuid == BLE_SVC_DIS_CHR_UUID16_FIRMWARE_REVISION) {
|
||||
rc = os_mbuf_append(ctxt->om, firmware_ver, strlen(firmware_ver));
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
if (uuid == BLE_SVC_DIS_CHR_UUID16_HARDWARE_REVISION) {
|
||||
rc = os_mbuf_append(ctxt->om, hardware_ver, strlen(hardware_ver));
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_battery_level(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
MODLOG_DFLT(DEBUG, "[READ] battery level service: battery level value");
|
||||
|
||||
uint8_t level = 42;
|
||||
int res = os_mbuf_append(ctxt->om, &level, sizeof(level));
|
||||
return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
void
|
||||
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
|
||||
{
|
||||
char buf[BLE_UUID_STR_LEN];
|
||||
|
||||
switch (ctxt->op) {
|
||||
case BLE_GATT_REGISTER_OP_SVC:
|
||||
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
|
||||
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
|
||||
ctxt->svc.handle);
|
||||
break;
|
||||
|
||||
case BLE_GATT_REGISTER_OP_CHR:
|
||||
MODLOG_DFLT(DEBUG, "registering characteristic %s with "
|
||||
"def_handle=%d val_handle=%d\n",
|
||||
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
|
||||
ctxt->chr.def_handle,
|
||||
ctxt->chr.val_handle);
|
||||
break;
|
||||
|
||||
case BLE_GATT_REGISTER_OP_DSC:
|
||||
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
|
||||
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
|
||||
ctxt->dsc.handle);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
gatt_svr_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ble_gatts_count_cfg(gatt_svr_svcs);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_gatts_add_svcs(gatt_svr_svcs);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
294
examples/nimble_heart_rate_sensor/main.c
Normal file
294
examples/nimble_heart_rate_sensor/main.c
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "console/console.h"
|
||||
#include "config/private_syscfg.h"
|
||||
#include "nimble/ble.h"
|
||||
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/ble_gatt.h"
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
#include "services/gatt/ble_svc_gatt.h"
|
||||
|
||||
#include "blehr_sens.h"
|
||||
#include "nimble/nimble_port_tencentos_tiny.h"
|
||||
|
||||
static bool notify_state;
|
||||
|
||||
/* Connection handle */
|
||||
static uint16_t conn_handle;
|
||||
|
||||
static const char *device_name = "Heart Rate Sensor";
|
||||
|
||||
static int blehr_gap_event(struct ble_gap_event *event, void *arg);
|
||||
|
||||
static uint8_t ble_addr_type;
|
||||
|
||||
/* Sending notify data timer */
|
||||
static struct ble_npl_callout blehr_tx_timer;
|
||||
|
||||
/* Variable to simulate heart beats */
|
||||
static uint8_t heartrate = 90;
|
||||
|
||||
static ble_uuid16_t svc_adv_uuids[] =
|
||||
{
|
||||
{ BLE_UUID_TYPE_16, GATT_HRS_UUID }
|
||||
};
|
||||
|
||||
/*
|
||||
* Enables advertising with parameters:
|
||||
* o General discoverable mode
|
||||
* o Undirected connectable mode
|
||||
*/
|
||||
static void
|
||||
blehr_advertise(void)
|
||||
{
|
||||
struct ble_gap_adv_params adv_params;
|
||||
struct ble_hs_adv_fields fields;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Set the advertisement data included in our advertisements:
|
||||
* o Flags (indicates advertisement type and other general info)
|
||||
* o Advertising tx power
|
||||
* o Device name
|
||||
*/
|
||||
memset(&fields, 0, sizeof(fields));
|
||||
|
||||
/*
|
||||
* Advertise two flags:
|
||||
* o Discoverability in forthcoming advertisement (general)
|
||||
* o BLE-only (BR/EDR unsupported)
|
||||
*/
|
||||
fields.flags = BLE_HS_ADV_F_DISC_GEN |
|
||||
BLE_HS_ADV_F_BREDR_UNSUP;
|
||||
|
||||
/*
|
||||
* Indicate that the TX power level field should be included; have the
|
||||
* stack fill this value automatically. This is done by assigning the
|
||||
* special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
|
||||
*/
|
||||
fields.tx_pwr_lvl_is_present = 1;
|
||||
fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
||||
|
||||
fields.name = (uint8_t *)device_name;
|
||||
fields.name_len = strlen(device_name);
|
||||
fields.name_is_complete = 1;
|
||||
|
||||
/*** 0x02,0x03 - 16-bit service class UUIDs. */
|
||||
fields.num_uuids16 = 1;
|
||||
fields.uuids16 = svc_adv_uuids;
|
||||
fields.uuids16_is_complete = 1;
|
||||
|
||||
rc = ble_gap_adv_set_fields(&fields);
|
||||
if (rc != 0) {
|
||||
MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*** 0xff - Manufacturer specific data. */
|
||||
memset(&fields, 0, sizeof(fields));
|
||||
fields.mfg_data = (uint8_t*)"GZH:Bluetooth-BLE,177341833";
|
||||
fields.mfg_data_len = 27;
|
||||
|
||||
rc = ble_gap_adv_rsp_set_fields(&fields);
|
||||
if (rc != 0) {
|
||||
MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin advertising */
|
||||
memset(&adv_params, 0, sizeof(adv_params));
|
||||
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||
rc = ble_gap_adv_start(ble_addr_type, NULL, BLE_HS_FOREVER,
|
||||
&adv_params, blehr_gap_event, NULL);
|
||||
if (rc != 0) {
|
||||
MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blehr_tx_hrate_stop(void)
|
||||
{
|
||||
ble_npl_callout_stop(&blehr_tx_timer);
|
||||
}
|
||||
|
||||
/* Reset heartrate measurment */
|
||||
static void
|
||||
blehr_tx_hrate_reset(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ble_npl_callout_reset(&blehr_tx_timer, OS_TICKS_PER_SEC);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
/* This functions simulates heart beat and notifies it to the client */
|
||||
static void
|
||||
blehr_tx_hrate(struct os_event *ev)
|
||||
{
|
||||
static uint8_t hrm[2];
|
||||
int rc;
|
||||
struct os_mbuf *om;
|
||||
|
||||
if (!notify_state) {
|
||||
blehr_tx_hrate_stop();
|
||||
heartrate = 90;
|
||||
return;
|
||||
}
|
||||
|
||||
hrm[0] = 0x06; /* contact of a sensor */
|
||||
hrm[1] = heartrate; /* storing dummy data */
|
||||
|
||||
/* Simulation of heart beats */
|
||||
heartrate++;
|
||||
if (heartrate == 160) {
|
||||
heartrate = 90;
|
||||
}
|
||||
|
||||
om = ble_hs_mbuf_from_flat(hrm, sizeof(hrm));
|
||||
|
||||
rc = ble_gattc_notify_custom(conn_handle, hrs_hrm_handle, om);
|
||||
|
||||
assert(rc == 0);
|
||||
blehr_tx_hrate_reset();
|
||||
}
|
||||
|
||||
static int
|
||||
blehr_gap_event(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
switch (event->type) {
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
/* A new connection was established or a connection attempt failed */
|
||||
MODLOG_DFLT(INFO, "connection %s; status=%d\n",
|
||||
event->connect.status == 0 ? "established" : "failed",
|
||||
event->connect.status);
|
||||
|
||||
if (event->connect.status != 0) {
|
||||
/* Connection failed; resume advertising */
|
||||
blehr_advertise();
|
||||
conn_handle = 0;
|
||||
}
|
||||
else {
|
||||
conn_handle = event->connect.conn_handle;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
MODLOG_DFLT(INFO, "disconnect; reason=%d\n", event->disconnect.reason);
|
||||
conn_handle = BLE_HS_CONN_HANDLE_NONE; /* reset conn_handle */
|
||||
|
||||
/* Connection terminated; resume advertising */
|
||||
blehr_advertise();
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||
MODLOG_DFLT(INFO, "adv complete\n");
|
||||
blehr_advertise();
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_SUBSCRIBE:
|
||||
MODLOG_DFLT(INFO, "subscribe event; cur_notify=%d\n value handle; "
|
||||
"val_handle=%d\n",
|
||||
event->subscribe.cur_notify, hrs_hrm_handle);
|
||||
if (event->subscribe.attr_handle == hrs_hrm_handle) {
|
||||
notify_state = event->subscribe.cur_notify;
|
||||
blehr_tx_hrate_reset();
|
||||
} else if (event->subscribe.attr_handle != hrs_hrm_handle) {
|
||||
notify_state = event->subscribe.cur_notify;
|
||||
blehr_tx_hrate_stop();
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_MTU:
|
||||
MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d mtu=%d\n",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.value);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
blehr_on_sync(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Use privacy */
|
||||
rc = ble_hs_id_infer_auto(0, &ble_addr_type);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Begin advertising */
|
||||
blehr_advertise();
|
||||
}
|
||||
|
||||
int ble_boot(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* Initialize the NimBLE host configuration */
|
||||
ble_hs_cfg.sync_cb = blehr_on_sync;
|
||||
|
||||
ble_npl_callout_init(&blehr_tx_timer, nimble_port_get_dflt_eventq(),
|
||||
blehr_tx_hrate, NULL);
|
||||
|
||||
/* verify and add our custom services */
|
||||
rc = gatt_svr_init();
|
||||
assert(rc == 0);
|
||||
|
||||
/* Set the default device name */
|
||||
rc = ble_svc_gap_device_name_set(device_name);
|
||||
assert(rc == 0);
|
||||
|
||||
/* run an event loop for handling the heart rate update events */
|
||||
extern void nimble_port_run(void);
|
||||
nimble_port_tencentos_tiny_init(nimble_port_run);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
k_task_t ble_boot_task;
|
||||
k_stack_t ble_boot_stack[512];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
/* Initialize OS */
|
||||
tos_knl_init();
|
||||
|
||||
nimble_port_init();
|
||||
|
||||
tos_task_create(&ble_boot_task, "boot", ble_boot, NULL,
|
||||
4,
|
||||
ble_boot_stack, sizeof(ble_boot_stack),
|
||||
0);
|
||||
tos_knl_start();
|
||||
}
|
||||
|
Reference in New Issue
Block a user