71
Steven lin [email protected] BLE server profile

About BLE server profile

Embed Size (px)

DESCRIPTION

how to builder the B.L.E(bluetooth low energy ) on Nordic Framework(nRF6310)

Citation preview

Page 1: About BLE server profile

Steven lin

[email protected]

BLE server profile

Page 2: About BLE server profile

About BLE,BT Explanation BLE, it is important to understand that all the profile and

service support is entirely in the application space.

This means that with BLE, there isn't really a need for a serial port service to transmit custom data, since you can easily make your custom service, that is specially tailored for the data your application needs to transfer.

Page 3: About BLE server profile

About BLE,BT Explanation This avoids the need for cramming all kinds of data into

serial packages, and most often this leads to much cleaner data handling strategies and hence applications.

Page 4: About BLE server profile

About BLE,BT create custom profile To create a custom service, you should try to follow the

general flow of the existing services, and mor or less copy them. The battery service (ble_bas.c/ble_bas.h) is probably the simplest one, and should provde a good starting point.

If you look at it, you can see that the init function first adds a service, using the sd_ble_gatts_service_add() function, then calls an internal function to add a characteristic. This internal functions sets up a lot of parameter structures, that in different ways affect the characteristic added.

Page 5: About BLE server profile

About BLE,BT Explanation Most services also needs to know what happens on run-

time, so you need to create a event handler to handle events coming from the stack. This should be named service_name_on_ble_evt(), and be called from the applications main.c-file's ble_evt_dispatch() method. Finally, most services also need some API function to actually do something useful, for example the battery service's method to update the measured battery value.

Page 6: About BLE server profile

Builder custom profile Start \ble_app_template project.

File structure :( reference Keil C Interger develop suit)

Page 7: About BLE server profile

Builder custom profile Client v.s Server

Client is no have data(information).

Client can send Request, Command and Confirmation

Server is have data .(information,so the device usually is server)

Server can send Response, Notification and Indication

Page 8: About BLE server profile

Builder custom profile

Page 9: About BLE server profile

Builder custom profile

Page 10: About BLE server profile

Builder custom profile

Page 11: About BLE server profile

Builder custom profile

Page 12: About BLE server profile

Builder custom profile

Page 13: About BLE server profile

Nordic BLE Framework The Software Structure

It have three parts: AP,GAP and GATTS.

The SVC and ble event is the Software interrupt.

Page 14: About BLE server profile

Nordic BLE Framework The Software Structure

SVC

Event

Page 15: About BLE server profile

Nordic BLE Framework GAP : Advertiser , GAP Service(device ,appearance ..),

Connection and Security。

Page 16: About BLE server profile

Nordic BLE Framework GAP API: GAP SVC

Page 17: About BLE server profile

Nordic BLE Framework GAP API: GAP Event

The GAP Events association with GATT Events.

Page 18: About BLE server profile

Nordic BLE Framework GAP With Center:

Page 19: About BLE server profile

Nordic BLE Framework GAP module:

Page 20: About BLE server profile

Nordic BLE Framework GATT Structure:

Page 21: About BLE server profile

Nordic BLE Framework GATT API:

Page 22: About BLE server profile

Nordic BLE Framework GATT Events:

Page 23: About BLE server profile

Nordic BLE Framework GATT module:

Page 24: About BLE server profile

Nordic BLE Framework GATT module:

Page 25: About BLE server profile

Builder custom profile 1.main loop( have to sure the order function caller)

int main(void)

{

ble_stack_init(); //Encodes the required advertising data and passes it to the stack

bond_manager_init();//if it have .

gap_params_init();

//GAP initialization, setup all the necessary GAP,set device name

//permissions and appearance,reference appearance device

advertising_init(); //adverrising the service (profile),advertising data to stack

services_init(); //** advertising data and passes it to the stack

conn_params_init();//Connection Parameters module

sec_params_init();//security parameters

radio_notification_init();//Radio Notification event handler

// Start execution

application_timers_start();

advertising_start();

}

Page 26: About BLE server profile

Builder custom profile Static void services_init(void)

init function first adds a service, using the sd_ble_gatts_service_add() function, then calls an internal function to add a characteristic. This internal functions sets up a lot of parameter structures, that in different ways affect the characteristic added.

what happens on run-time, so you need to create a event handler to handle events coming from the stack. This should be named service_name_on_ble_evt(), and be called from the applications main.c-file's ble_evt_dispatch() method.

1.caller sd_ble_gatts_service_add() then add char,last register the event handler

Page 27: About BLE server profile

Builder custom profile Static void services_init(void)

Page 28: About BLE server profile

Builder custom profile Static void services_init(void)

https://www.bluetooth.org/en-us/specification/adopted-specifications

Page 29: About BLE server profile

Builder custom profile Static void services_init(void)

https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml

Page 30: About BLE server profile

Builder custom profile Static void services_init(void)

https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml

Page 31: About BLE server profile

Builder custom profile Profile , service , Characteristic ,descriptor and declare.

Battery service :

實作,提供value 及notify

Service , 0x180F

Characteristics, 0x2A19

Descriptors(Client Characteristic Configuration), 0x2902

https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorsHomePage.aspx

Page 32: About BLE server profile

File structure: C:\Keil\ARM\Device\Nordic\nrf51822\Include\ble\ble_services\ble_bas.h

C:\Keil\ARM\Device\Nordic\nrf51822\Source\ble\ble_services\ble_bas.c

Data structure:

Struct: 1. ble_bas_evt_t//Battery Service event

2. ble_bas_init_t//Battery Service init structure

3. ble_bas_t//Battery Service structure

Page 33: About BLE server profile

Functioin: 1. uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t *

p_bas_init);

2. void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt);

3. uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level);

/**@brief Battery Service event handler type. */ 1. typedef void (*ble_bas_evt_handler_t) (ble_bas_t * p_bas,

ble_bas_evt_t * p_evt);

Page 34: About BLE server profile

/**@brief Battery Service event type. */

typedef enum

{

BLE_BAS_EVT_NOTIFICATION_ENABLED, /**< Battery value notification enabled event. */

BLE_BAS_EVT_NOTIFICATION_DISABLED /**< Battery value notification disabled event. */

} ble_bas_evt_type_t;

/**@brief Battery Service event. */

typedef struct

{

ble_bas_evt_type_t evt_type; /**< Type of event. */

} ble_bas_evt_t;

Page 35: About BLE server profile

/**@brief Battery Service init structure. This contains all options and data needed for

* initialization of the service.*/

typedef struct

{

ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */

bool support_notification; /**< TRUE if notification of Battery Level measurement is supported. */

ble_srv_report_ref_t * p_report_ref; /**< If not NULL, a Report Reference descriptor with the specified value will be added to the Battery Level characteristic */

uint8_t initial_batt_level; /**< Initial battery level */

ble_srv_cccd_security_mode_t battery_level_char_attr_md; /**< Initial security level for battery characteristics attribute */

ble_gap_conn_sec_mode_t battery_level_report_read_perm; /**< Initial security level for battery report read attribute */

} ble_bas_init_t;

//for pc

Page 36: About BLE server profile

/**@brief Battery Service structure. This contains various status information for the service. */

typedef struct ble_bas_s

{

ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */

uint16_t service_handle; /**< Handle of Battery Service (as provided by the BLE stack). */

ble_gatts_char_handles_t battery_level_handles; /**< Handles related to the Battery Level characteristic. */

uint16_t report_ref_handle; /**< Handle of the Report Reference descriptor. */

uint8_t battery_level_last; /**< Last Battery Level measurement passed to the Battery Service. */

uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */

bool is_notification_supported; /**< TRUE if notification of Battery Level is supported. */

} ble_bas_t;

Page 37: About BLE server profile

// Initialize Battery Service

memset(&bas_init, 0, sizeof(bas_init));

// Here the sec level for the Battery Service can be changed/increased.

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);

BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

bas_init.evt_handler = NULL;

bas_init.support_notification = true;

bas_init.p_report_ref = NULL;

bas_init.initial_batt_level = 100;

err_code = ble_bas_init(&m_bas, &bas_init);

APP_ERROR_CHECK(err_code);

Page 38: About BLE server profile

uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init)

{

uint32_t err_code;

ble_uuid_t ble_uuid;

// Initialize service structure

p_bas->evt_handler = p_bas_init->evt_handler;

p_bas->conn_handle = BLE_CONN_HANDLE_INVALID;

p_bas->is_notification_supported = p_bas_init->support_notification;

p_bas->battery_level_last = INVALID_BATTERY_LEVEL;

// Add service

BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_SERVICE);

err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_bas->service_handle);

if (err_code != NRF_SUCCESS)

{

return err_code;

}

// Add battery level characteristic

return battery_level_char_add(p_bas, p_bas_init);

}

Page 39: About BLE server profile

/**@brief Add Battery Level characteristic.

*

* @param[in] p_bas Battery Service structure.

* @param[in] p_bas_init Information needed to initialize the service.

*

* @return NRF_SUCCESS on success, otherwise an error code.

*/

static uint32_t battery_level_char_add(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init)

{

uint32_t err_code;

ble_gatts_char_md_t char_md;

ble_gatts_attr_md_t cccd_md;

ble_gatts_attr_t attr_char_value;

ble_uuid_t ble_uuid;

ble_gatts_attr_md_t attr_md;

uint8_t initial_battery_level;

uint8_t encoded_report_ref[BLE_SRV_ENCODED_REPORT_REF_LEN];

uint8_t init_len;

Page 40: About BLE server profile
Page 41: About BLE server profile

以battery service 中,由上可知有一個characteristics/及一個CCCD .而每一個characteristics由上到下:

1. ble_gatts_char_md_t char_md;//GATT Characteristic metadata

Characteristic Properties, user description descriptor, Pointer to a presentation format structure and Attribute metadata for the Client(server) Characteristic Configuration Descriptor.

A. ble_gatts_attr_md_t attr_md;//Attribute metadata A. Read(write) permissions, Variable length, Value location and

Read(write) Authorization on every read(write) operation

B. ble_gatts_attr_md_t cccd_md //Attribute metadata A. Read(write) permissions, Variable length, Value location and

Read(write) Authorization

Page 42: About BLE server profile

2. ble_gatts_attr_t attr_char_value;//GATT Attribute

Pointer to the attribute UUID, Pointer to the attribute metadata structure, attribute value length in bytes and Pointer to the attribute data if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer

Page 43: About BLE server profile

/**@brief GATT Characteristic metadata. */

typedef struct

{

ble_gatt_char_props_t char_props; /**< Characteristic Properties. */

ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */

uint8_t* p_char_user_desc; /**< Pointer to a UTF-8, NULL if the descriptor is not required. */

uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */

uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */

ble_gatts_char_pf_t* p_char_pf; /**< Pointer to a presentation format structure or NULL if the descriptor is not required. */

ble_gatts_attr_md_t* p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */

ble_gatts_attr_md_t* p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */

ble_gatts_attr_md_t* p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */

} ble_gatts_char_md_t;

Page 44: About BLE server profile

/**@brief GATT Characteristic Properties. */

typedef struct

{

/* Standard properties */

uint8_t broadcast :1; /**< Broadcasting of value permitted. */

uint8_t read :1; /**< Reading value permitted. */

uint8_t write_wo_resp :1; /**< Writing value with Write Command permitted. */

uint8_t write :1; /**< Writing value with Write Request permitted. */

uint8_t notify :1; /**< Notications of value permitted. */

uint8_t indicate :1; /**< Indications of value permitted. */

uint8_t auth_signed_wr :1; /**< Writing value with Signed Write Command permitted. */

} ble_gatt_char_props_t;

Page 45: About BLE server profile

/**@brief Attribute metadata. */

typedef struct

{

ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */

ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */

uint8_t vlen :1; /**< Variable length attribute. */

uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/

uint8_t rd_auth :1; /**< Read Authorization and value will be requested from the application on every read operation. */

uint8_t wr_auth :1; /**< Write Authorization will be requested from the application on every Write Request operation (but not Write Command). */

} ble_gatts_attr_md_t;

Page 46: About BLE server profile

/**@brief GATT Attribute. */

typedef struct

{

ble_uuid_t* p_uuid; /**< Pointer to the attribute UUID. */

ble_gatts_attr_md_t* p_attr_md; /**< Pointer to the attribute metadata structure. */

uint16_t init_len; /**< Initial attribute value length in bytes. */

uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */

uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */

uint8_t* p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer

that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location.

The stack may access that memory directly without the application's knowledge. */

} ble_gatts_attr_t;

Page 47: About BLE server profile

設定

1.cccd_md,//notify

2. char_md

3.BLE_UUID_BLE_ASSIGN

4. attr_md

5. attr_char_value

6. sd_ble_gatts_characteristic_add

Page 48: About BLE server profile

// Add Battery Level characteristic

if (p_bas->is_notification_supported)

{

memset(&cccd_md, 0, sizeof(cccd_md));

// According to BAS_SPEC_V10, the read operation on cccd should be possible without

// authentication.

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);

cccd_md.write_perm = p_bas_init->battery_level_char_attr_md.cccd_write_perm;

cccd_md.vloc = BLE_GATTS_VLOC_STACK;

}

Page 49: About BLE server profile

memset(&char_md, 0, sizeof(char_md));

char_md.char_props.read = 1;

char_md.char_props.notify = (p_bas->is_notification_supported) ? 1 : 0;

char_md.p_char_user_desc = NULL;

char_md.p_char_pf = NULL;

char_md.p_user_desc_md = NULL;

char_md.p_cccd_md = (p_bas->is_notification_supported) ? &cccd_md : NULL;

char_md.p_sccd_md = NULL;

Page 50: About BLE server profile

BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_LEVEL_CHAR);

memset(&attr_md, 0, sizeof(attr_md));

attr_md.read_perm = p_bas_init-

>battery_level_char_attr_md.read_perm; attr_md.write_perm = p_bas_init-

>battery_level_char_attr_md.write_perm; attr_md.vloc = BLE_GATTS_VLOC_STACK; attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0;

Page 51: About BLE server profile

initial_battery_level = p_bas_init->initial_batt_level;

memset(&attr_char_value, 0, sizeof(attr_char_value));

attr_char_value.p_uuid = &ble_uuid;

attr_char_value.p_attr_md = &attr_md;

attr_char_value.init_len = sizeof(uint8_t);

attr_char_value.init_offs = 0;

attr_char_value.max_len = sizeof(uint8_t);

attr_char_value.p_value = &initial_battery_level;

Page 52: About BLE server profile

err_code = sd_ble_gatts_characteristic_add(p_bas->service_handle, &char_md,

&attr_char_value,

&p_bas->battery_level_handles);

if (err_code != NRF_SUCCESS)

{

return err_code;

}

Page 53: About BLE server profile

if (p_bas_init->p_report_ref != NULL)

{

// Add Report Reference descriptor

BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR);

memset(&attr_md, 0, sizeof(attr_md));

attr_md.read_perm = p_bas_init->battery_level_report_read_perm;

BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);

attr_md.vloc = BLE_GATTS_VLOC_STACK;

attr_md.rd_auth = 0;

attr_md.wr_auth = 0;

attr_md.vlen = 0;

Page 54: About BLE server profile

init_len = ble_srv_report_ref_encode(encoded_report_ref, p_bas_init->p_report_ref);

memset(&attr_char_value, 0, sizeof(attr_char_value));

attr_char_value.p_uuid = &ble_uuid;

attr_char_value.p_attr_md = &attr_md;

attr_char_value.init_len = init_len;

attr_char_value.init_offs = 0;

attr_char_value.max_len = attr_char_value.init_len;

attr_char_value.p_value = encoded_report_ref;

Page 55: About BLE server profile

err_code = sd_ble_gatts_descriptor_add(p_bas->battery_level_handles.value_handle,

&attr_char_value,

&p_bas->report_ref_handle);

if (err_code != NRF_SUCCESS)

{

return err_code;

}

}

else

{

p_bas->report_ref_handle = BLE_GATT_HANDLE_INVALID;

}

return NRF_SUCCESS;

}

Page 56: About BLE server profile

/**@brief Disconnect event handler. * * @param[in] p_bas Battery Service structure. * @param[in] p_ble_evt Event received from the BLE

stack. */ static void on_disconnect(ble_bas_t * p_bas, ble_evt_t *

p_ble_evt) { UNUSED_PARAMETER(p_ble_evt); p_bas->conn_handle = BLE_CONN_HANDLE_INVALID; }

Page 57: About BLE server profile

/**@brief Connect event handler.

*

* @param[in] p_bas Battery Service structure.

* @param[in] p_ble_evt Event received from the BLE stack.

*/

static void on_connect(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)

{

p_bas->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;

}

Page 58: About BLE server profile

void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)

{

switch (p_ble_evt->header.evt_id)

{

case BLE_GAP_EVT_CONNECTED:

on_connect(p_bas, p_ble_evt);

break;

case BLE_GAP_EVT_DISCONNECTED:

on_disconnect(p_bas, p_ble_evt);

break;

case BLE_GATTS_EVT_WRITE:

on_write(p_bas, p_ble_evt);

break;

default:

break;

}

}

Page 59: About BLE server profile

/**@brief Write event handler.

*

* @param[in] p_bas Battery Service structure.

* @param[in] p_ble_evt Event received from the BLE stack.

*/

static void on_write(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)

{

if (p_bas->is_notification_supported)

{

ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;

if (

(p_evt_write->handle == p_bas->battery_level_handles.cccd_handle)

&&

(p_evt_write->len == 2)

)

Page 60: About BLE server profile

{

// CCCD written, call application event handler

if (p_bas->evt_handler != NULL)

{

ble_bas_evt_t evt;

if (ble_srv_is_notification_enabled(p_evt_write->data))

{

evt.evt_type = BLE_BAS_EVT_NOTIFICATION_ENABLED;

}

else

{

evt.evt_type = BLE_BAS_EVT_NOTIFICATION_DISABLED;

}

p_bas->evt_handler(p_bas, &evt);

}

}

}

}

Page 61: About BLE server profile

Nordic FrameWork support service Alert Notification Service Client,ble_ans_c

Energon bank Service module, ble_band

Battery Service module,ble_bas

Blood Pressure Service module. ble_bps

Cycling Speed and Cadence Service, ble_cscs

Device Information Service, ble_dis

Glucose Service module. ble_gls

Glucose Database Service. ble_gls_db

Human Interface Device Service, ble_hids

Page 62: About BLE server profile

Nordic FrameWork support service Heart Rate Service ,ble_hrs

Health Thermometer Service ,ble_hts

Immediate Alert Service,ble_ias

Immediate Alert Service Client,ble_ias_c

Link Loss Service,ble_lls

Running Speed and Cadence Service,ble_rscs

TX Power Service,ble_tps

Page 63: About BLE server profile

Reference Battery Service (BAS)

http://developer.bluetooth.org/TechnologyOverview/Pages/BAS.aspx

The external appearance of this https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml

Page 64: About BLE server profile

Other Service

Page 65: About BLE server profile

Other Service

Page 66: About BLE server profile

Other Service

Page 67: About BLE server profile

Other Service

Page 68: About BLE server profile

Other Service

Page 69: About BLE server profile

Other Service

Page 70: About BLE server profile

Other Service

Page 71: About BLE server profile

Builder custom profile Static void services_init(void)