47
47
#include "btle_gap.h"
48
48
#include "btle_advertising.h"
49
49
#include "custom_helper.h"
50
+ #include "btle_uart.h"
50
51
51
- static void service_error_callback ( uint32_t nrf_error );
52
- void assert_nrf_callback ( uint16_t line_num , const uint8_t * p_file_name );
53
- void app_error_handler ( uint32_t error_code , uint32_t line_num , const uint8_t * p_file_name );
54
- static error_t bond_manager_init ( void );
55
- static void btle_handler ( ble_evt_t * p_ble_evt );
56
- static void btle_soc_event_handler ( uint32_t sys_evt );
52
+ //--------------------------------------------------------------------+
53
+ // MACRO CONSTANT TYPEDEF
54
+ //--------------------------------------------------------------------+
55
+ // standard service UUID to driver offset
56
+ #define UUID2OFFSET (uuid ) ((uuid)-0x1800)
57
57
58
- /**************************************************************************/
59
- /*!
60
- Checks is all values in the supplied array are zero
58
+ btle_service_driver_t const btle_service_driver [] =
59
+ {
60
+ #if CFG_BLE_DEVICE_INFORMATION
61
+ [UUID2OFFSET (BLE_UUID_DEVICE_INFORMATION_SERVICE )] =
62
+ {
63
+ .init = device_information_init ,
64
+ .event_handler = NULL ,
65
+ },
66
+ #endif
61
67
62
- @returns 'true' if all values in the array are zero
63
- 'false' if any value is non-zero
64
- */
65
- /**************************************************************************/
66
- static inline bool is_all_zeros (uint8_t arr [], uint32_t count ) ATTR_ALWAYS_INLINE ATTR_PURE ;
67
- static inline bool is_all_zeros (uint8_t arr [], uint32_t count )
68
+ #if CFG_BLE_BATTERY
69
+ [UUID2OFFSET (BLE_UUID_BATTERY_SERVICE )] =
70
+ {
71
+ .init = battery_init ,
72
+ .event_handler = battery_handler ,
73
+ },
74
+ #endif
75
+
76
+ #if CFG_BLE_HEART_RATE
77
+ // [UUID2OFFSET(BLE_UUID_HEART_RATE_SERVICE)] =
78
+ // {
79
+ // .init = heart_rate_init,
80
+ // .event_handler = heart_rate_handler,
81
+ // },
82
+ #endif
83
+
84
+ #if CFG_BLE_IMMEDIATE_ALERT
85
+ [UUID2OFFSET (BLE_UUID_IMMEDIATE_ALERT_SERVICE )] =
86
+ {
87
+ .init = immediate_alert_init ,
88
+ .event_handler = immediate_alert_handler ,
89
+ },
90
+ #endif
91
+
92
+ #if CFG_BLE_TX_POWER
93
+ [UUID2OFFSET (BLE_UUID_TX_POWER_SERVICE )] =
94
+ {
95
+ .init = tx_power_init ,
96
+ .event_handler = NULL ,
97
+ },
98
+ #endif
99
+
100
+ #if CFG_BLE_LINK_LOSS
101
+ [UUID2OFFSET (BLE_UUID_LINK_LOSS_SERVICE )] =
102
+ {
103
+ .init = link_loss_init ,
104
+ .event_handler = link_loss_handler ,
105
+ },
106
+ #endif
107
+ };
108
+
109
+ enum {
110
+ BTLE_SERVICE_MAX = sizeof (btle_service_driver ) / sizeof (btle_service_driver_t )
111
+ };
112
+
113
+ btle_service_custom_driver_t btle_service_custom_driver [] =
68
114
{
69
- for ( uint32_t i = 0 ; i < count ; i ++ )
70
- {
71
- if (arr [i ] != 0 ) return false;
72
- }
115
+ {
116
+ .uuid_base = BLE_UART_UUID_BASE ,
117
+ .service_uuid .uuid = BLE_UART_UUID_PRIMARY_SERVICE ,
118
+ .init = uart_service_init ,
119
+ .event_handler = uart_service_handler
120
+ },
121
+ };
73
122
74
- return true;
75
- }
123
+ enum {
124
+ BTLE_SERVICE_CUSTOM_MAX = sizeof (btle_service_custom_driver ) / sizeof (btle_service_custom_driver_t )
125
+ };
126
+
127
+ //--------------------------------------------------------------------+
128
+ // INTERNAL OBJECT & FUNCTION DECLARATION
129
+ //--------------------------------------------------------------------+
130
+ static void service_error_callback (uint32_t nrf_error );
131
+ void assert_nrf_callback (uint16_t line_num , const uint8_t * p_file_name );
132
+ void app_error_handler (uint32_t error_code , uint32_t line_num , const uint8_t * p_file_name );
133
+
134
+ static error_t bond_manager_init (void );
135
+
136
+ static void btle_handler (ble_evt_t * p_ble_evt );
137
+ static void btle_soc_event_handler (uint32_t sys_evt );
76
138
77
139
/**************************************************************************/
78
140
/*!
79
141
Initialises BTLE and the underlying HW/SoftDevice
80
142
*/
81
143
/**************************************************************************/
82
- error_t btle_init (btle_service_t service_list [], uint8_t const service_count )
144
+ error_t btle_init (void )
83
145
{
84
146
/* Initialise the SoftDevice using an external 32kHz XTAL for LFCLK */
85
147
SOFTDEVICE_HANDLER_INIT (NRF_CLOCK_LFCLKSRC_XTAL_20_PPM , false);
@@ -94,105 +156,35 @@ error_t btle_init(btle_service_t service_list[], uint8_t const service_count)
94
156
/* Initialise GAP */
95
157
btle_gap_init ();
96
158
97
- /* Initialise any services present on the GATT Server */
98
- /* This sequences will be repeated for every service */
99
- for ( uint8_t sid = 0 ; sid < service_count ; sid ++ )
159
+ /* Standard Services */
160
+ for (uint16_t i = 0 ; i < BTLE_SERVICE_MAX ; i ++ )
100
161
{
101
- btle_service_t * p_service = & service_list [sid ];
102
-
103
- /* If we are using a custom UUID we first need to add it to the stack */
104
- if ( is_all_zeros (p_service -> uuid_base , 16 ) )
162
+ if ( btle_service_driver [i ].init != NULL )
105
163
{
106
- /* Seems to be a standard 16-bit BLE UUID */
107
- p_service -> uuid_type = BLE_UUID_TYPE_BLE ;
164
+ ASSERT_STATUS ( btle_service_driver [i ].init () );
108
165
}
109
- else
110
- {
111
- /* Seems to be a custom UUID, which needs to be added */
112
- p_service -> uuid_type = custom_add_uuid_base ( p_service -> uuid_base );
113
- ASSERT ( p_service -> uuid_type >= BLE_UUID_TYPE_VENDOR_BEGIN , ERROR_INVALIDPARAMETER );
114
- }
115
-
116
- /* Add the primary GATT service first ... */
117
- ble_uuid_t service_uuid = { .type = p_service -> uuid_type , .uuid = p_service -> uuid };
118
- ASSERT_STATUS ( sd_ble_gatts_service_add (BLE_GATTS_SRVC_TYPE_PRIMARY , & service_uuid , & p_service -> handle ) );
166
+ }
119
167
120
- /* ... then add all of the GATT characteristics */
121
- for (uint8_t cid = 0 ; cid < p_service -> char_count ; cid ++ )
168
+ /*Custom Services */
169
+ for (uint16_t i = 0 ; i < BTLE_SERVICE_CUSTOM_MAX ; i ++ )
170
+ {
171
+ if ( btle_service_custom_driver [i ].init != NULL )
122
172
{
123
- btle_characteristic_t * p_char = p_service -> char_pool [cid ];
124
- ble_uuid_t char_uuid = { .type = p_service -> uuid_type , .uuid = p_char -> uuid };
173
+ /* add the custom UUID to stack */
174
+ uint8_t uuid_type = custom_add_uuid_base (btle_service_custom_driver [i ].uuid_base );
175
+ ASSERT ( uuid_type >= BLE_UUID_TYPE_VENDOR_BEGIN , ERROR_INVALIDPARAMETER );
125
176
126
- ASSERT_STATUS (custom_add_in_characteristic (p_service -> handle , & char_uuid , p_char -> properties ,
127
- p_char -> init_value , p_char -> len_min , p_char -> len_max ,
128
- & p_char -> handle ) );
177
+ btle_service_custom_driver [i ].service_uuid .type = uuid_type ; /* store for later use in advertising */
178
+ ASSERT_STATUS ( btle_service_custom_driver [i ].init (uuid_type ) );
129
179
}
130
180
}
131
181
132
- /* Now we can start the advertising process */
133
- btle_advertising_init (service_list , service_count );
182
+ btle_advertising_init (btle_service_driver , BTLE_SERVICE_MAX , btle_service_custom_driver , BTLE_SERVICE_CUSTOM_MAX );
134
183
btle_advertising_start ();
135
184
136
185
return ERROR_NONE ;
137
186
}
138
187
139
- /**************************************************************************/
140
- /*!
141
- This function will attempt to update the value of a GATT characteristic
142
-
143
- @param[in] p_char A pointer to the characteristic to update
144
- @param[in] p_data A pointer to the data to use when updating
145
- @param[in] len The size (in bytes) of p_data
146
-
147
- @returns ERROR_NONE if the update was successful, otherwise an
148
- appropriate error_t value
149
- */
150
- /**************************************************************************/
151
- error_t btle_characteristic_update (btle_characteristic_t const * p_char , void const * p_data , uint16_t len )
152
- {
153
- uint16_t const conn_handle = btle_gap_get_connection ();
154
-
155
- /* Special treatment is required if notify or indicate flags are set */
156
- if ( (p_char -> properties .notify || p_char -> properties .indicate ) && (conn_handle != BLE_CONN_HANDLE_INVALID ) )
157
- {
158
- /* HVX params for the characteristic value */
159
- ble_gatts_hvx_params_t const hvx_params =
160
- {
161
- .handle = p_char -> handle .value_handle ,
162
- .type = p_char -> properties .notify ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION ,
163
- .offset = 0 ,
164
- .p_data = (uint8_t * ) p_data ,
165
- .p_len = & len
166
- };
167
-
168
- /* Now pass the params down to the SD ... */
169
- error_t error = sd_ble_gatts_hvx (conn_handle , & hvx_params );
170
-
171
- /* ... and make sure nothing unfortunate happened */
172
- switch (error )
173
- {
174
- /* Ignore the following three error types */
175
- case ERROR_NONE :
176
- case ERROR_INVALID_STATE : // Notification/indication bit not enabled in CCCD
177
- case ERROR_BLEGATTS_SYS_ATTR_MISSING :
178
- break ;
179
-
180
- /* Make sure that the local value is updated and handle any other */
181
- /* error types errors here */
182
- default :
183
- ASSERT_STATUS ( sd_ble_gatts_value_set (p_char -> handle .value_handle , 0 , & len , p_data ) );
184
- ASSERT_STATUS ( error );
185
- break ;
186
- }
187
- }
188
- else
189
- {
190
- /* If notify or indicate aren't set we can update the value like this */
191
- ASSERT_STATUS ( sd_ble_gatts_value_set (p_char -> handle .value_handle , 0 , & len , p_data ) );
192
- }
193
-
194
- return ERROR_NONE ;
195
- }
196
188
197
189
/**************************************************************************/
198
190
/*!
@@ -216,7 +208,23 @@ static void btle_handler(ble_evt_t * p_ble_evt)
216
208
ble_bondmngr_on_ble_evt (p_ble_evt );
217
209
ble_conn_params_on_ble_evt (p_ble_evt );
218
210
219
- /* Next call the application specific event handlers */
211
+ /* Standard Service Handler */
212
+ for (uint16_t i = 0 ; i < BTLE_SERVICE_MAX ; i ++ )
213
+ {
214
+ if ( btle_service_driver [i ].event_handler != NULL )
215
+ {
216
+ btle_service_driver [i ].event_handler (p_ble_evt );
217
+ }
218
+ }
219
+
220
+ /* Custom Service Handler */
221
+ for (uint16_t i = 0 ; i < BTLE_SERVICE_CUSTOM_MAX ; i ++ )
222
+ {
223
+ if ( btle_service_custom_driver [i ].event_handler != NULL )
224
+ {
225
+ btle_service_custom_driver [i ].event_handler (p_ble_evt );
226
+ }
227
+ }
220
228
switch (p_ble_evt -> header .evt_id )
221
229
{
222
230
case BLE_GAP_EVT_CONNECTED :
@@ -225,7 +233,7 @@ static void btle_handler(ble_evt_t * p_ble_evt)
225
233
226
234
case BLE_GAP_EVT_DISCONNECTED :
227
235
/* Since we are not in a connection and have not started advertising, store bonds */
228
- ASSERT_STATUS_RET_VOID ( ble_bondmngr_bonded_centrals_store () );
236
+ ( void ) ble_bondmngr_bonded_centrals_store ();
229
237
/* Start advertising again (change this if necessary!) */
230
238
btle_advertising_start ();
231
239
break ;
0 commit comments