1515
1616#include "ble_event.h"
1717#include "ble_discovery_def.h"
18+ #include "dev_descr.h"
1819
1920#include <logging/log.h>
2021LOG_MODULE_REGISTER (MODULE , CONFIG_DESKTOP_BLE_DISCOVERY_LOG_LEVEL );
2122
23+ enum discovery_state {
24+ DISCOVERY_STATE_START ,
25+ DISCOVERY_STATE_DEV_DESCR ,
26+ DISCOVERY_STATE_DIS ,
27+ DISCOVERY_STATE_HIDS ,
28+
29+ DISCOVERY_STATE_COUNT ,
30+ };
31+
32+ static enum discovery_state state ;
33+
2234static u16_t peer_vid ;
2335static u16_t peer_pid ;
36+ static bool peer_llpm_support ;
2437static struct bt_conn * discovering_peer_conn ;
2538
26- static struct k_work hids_discovery_start ;
39+ static struct k_work next_discovery_step ;
2740
2841#define VID_POS_IN_PNP_ID sizeof(u8_t)
2942#define PID_POS_IN_PNP_ID (VID_POS_IN_PNP_ID + sizeof(u16_t))
@@ -41,10 +54,12 @@ static void peer_unpair(void)
4154 }
4255 bt_conn_unref (discovering_peer_conn );
4356 discovering_peer_conn = NULL ;
57+ state = DISCOVERY_STATE_START ;
4458}
4559
4660static void hids_discovery_completed (struct bt_gatt_dm * dm , void * context )
4761{
62+ __ASSERT_NO_MSG (dm != NULL );
4863 __ASSERT_NO_MSG (bt_gatt_dm_conn_get (dm ) == discovering_peer_conn );
4964 BUILD_ASSERT_MSG (PEER_TYPE_COUNT <= __CHAR_BIT__ , "" );
5065 LOG_INF ("HIDS discovery procedure succeeded" );
@@ -56,6 +71,7 @@ static void hids_discovery_completed(struct bt_gatt_dm *dm, void *context)
5671
5772 event -> dm = dm ;
5873 event -> pid = peer_pid ;
74+ event -> peer_llpm_support = peer_llpm_support ;
5975
6076 for (size_t i = 0 ; i < ARRAY_SIZE (bt_peripherals ); i ++ ) {
6177 if (bt_peripherals [i ].pid == peer_pid ) {
@@ -81,93 +97,94 @@ static void hids_discovery_completed(struct bt_gatt_dm *dm, void *context)
8197 peer_unpair ();
8298}
8399
84- static void hids_discovery_service_not_found (struct bt_conn * conn ,
85- void * context )
100+ static void service_not_found (struct bt_conn * conn , void * context )
86101{
87- LOG_ERR ("Cannot find HIDS during the discovery " );
102+ LOG_ERR ("Service not found " );
88103 __ASSERT_NO_MSG (discovering_peer_conn == conn );
89104 peer_unpair ();
90105}
91106
92- static void hids_discovery_error_found (struct bt_conn * conn , int err ,
93- void * context )
107+ static void discovery_error (struct bt_conn * conn , int err , void * context )
94108{
95- LOG_ERR ("HIDS discovery failed (err:%d)" , err );
109+ LOG_ERR ("Error discovering peer (err:%d)" , err );
96110 __ASSERT_NO_MSG (discovering_peer_conn == conn );
97111 peer_unpair ();
98112}
99113
100- static void start_hids_discovery ( struct bt_conn * conn )
114+ static void read_dev_descr ( const u8_t * ptr , u16_t len )
101115{
102- static const struct bt_gatt_dm_cb discovery_cb = {
103- .completed = hids_discovery_completed ,
104- .service_not_found = hids_discovery_service_not_found ,
105- .error_found = hids_discovery_error_found ,
106- };
107-
108- int err = bt_gatt_dm_start (conn , BT_UUID_HIDS , & discovery_cb , NULL );
109-
110- if (err == - EALREADY ) {
111- LOG_ERR ("Discovery already in progress" );
112- module_set_state (MODULE_STATE_ERROR );
113- } else if (err ) {
114- LOG_ERR ("Cannot start the discovery (err:%d)" , err );
115- peer_unpair ();
116- }
116+ __ASSERT_NO_MSG (len >= DEV_DESCR_LEN );
117+ peer_llpm_support = ptr [DEV_DESCR_LLPM_SUPPORT_POS ];
118+ LOG_INF ("LLPM %ssupported" , peer_llpm_support ? ("" ) : ("not " ));
117119}
118120
119- static bool verify_peer ( void )
121+ static void read_dis ( const u8_t * ptr , u16_t len )
120122{
121- if (peer_vid != vendor_vid ) {
122- LOG_WRN ("Invalid peripheral VID" );
123- return false;
124- }
123+ __ASSERT_NO_MSG (len >= MIN_LEN_DIS_PNP_ID );
125124
126- return true ;
127- }
125+ peer_vid = sys_get_le16 ( & ptr [ VID_POS_IN_PNP_ID ]) ;
126+ peer_pid = sys_get_le16 ( & ptr [ PID_POS_IN_PNP_ID ]);
128127
129- static void hids_discovery_start_fn (struct k_work * w )
130- {
131- if (!verify_peer ()) {
132- peer_unpair ();
133- } else {
134- start_hids_discovery (discovering_peer_conn );
135- }
128+ LOG_INF ("VID: %02x PID: %02x" , peer_vid , peer_pid );
136129}
137130
138131static u8_t read_attr (struct bt_conn * conn , u8_t err ,
139- struct bt_gatt_read_params * params ,
140- const void * data , u16_t length )
132+ struct bt_gatt_read_params * params ,
133+ const void * data , u16_t length )
141134{
142135 if (err ) {
143- LOG_ERR ("Problem with reading GATT (err:%u )" , err );
136+ LOG_ERR ("Problem reading GATT (err:%" PRIu8 " )" , err );
144137 peer_unpair ();
145138 return BT_GATT_ITER_STOP ;
146139 }
147140
148- __ASSERT_NO_MSG (length >= MIN_LEN_DIS_PNP_ID );
141+ __ASSERT_NO_MSG (data != NULL );
149142 const u8_t * data_ptr = data ;
150143
151- peer_vid = sys_get_le16 (& data_ptr [VID_POS_IN_PNP_ID ]);
152- peer_pid = sys_get_le16 (& data_ptr [PID_POS_IN_PNP_ID ]);
144+ switch (state ) {
145+ case DISCOVERY_STATE_DEV_DESCR :
146+ read_dev_descr (data_ptr , length );
147+ break ;
153148
154- LOG_INF ("VID: %02x PID: %02x" , peer_vid , peer_pid );
149+ case DISCOVERY_STATE_DIS :
150+ read_dis (data_ptr , length );
151+ break ;
152+
153+ default :
154+ __ASSERT_NO_MSG (false);
155+ }
155156
156- k_work_submit (& hids_discovery_start );
157+ k_work_submit (& next_discovery_step );
157158
158159 return BT_GATT_ITER_STOP ;
159160}
160161
161- static void dis_read_completed (struct bt_gatt_dm * dm , void * context )
162+ static void discovery_completed (struct bt_gatt_dm * dm , void * context )
162163{
164+ __ASSERT_NO_MSG (dm != NULL );
163165 __ASSERT_NO_MSG (discovering_peer_conn == bt_gatt_dm_conn_get (dm ));
166+ const struct bt_uuid * uuid = NULL ;
164167 const struct bt_gatt_attr * attr ;
165168 int err ;
166169
167- attr = bt_gatt_dm_char_by_uuid (dm , BT_UUID_DIS_PNP_ID );
170+ switch (state ) {
171+ case DISCOVERY_STATE_DEV_DESCR :
172+ uuid = & custom_desc_chrc_uuid .uuid ;
173+ break ;
174+
175+ case DISCOVERY_STATE_DIS :
176+ uuid = BT_UUID_DIS_PNP_ID ;
177+ break ;
178+
179+ default :
180+ /* Should not happen. */
181+ __ASSERT_NO_MSG (false);
182+ }
183+
184+ attr = bt_gatt_dm_char_by_uuid (dm , uuid );
168185
169186 if (!attr ) {
170- LOG_ERR ("PnP ID characteristic not found - disconnecting" );
187+ LOG_ERR ("Characteristic not found - disconnecting" );
171188 err = bt_gatt_dm_data_release (dm );
172189 if (err ) {
173190 goto error ;
@@ -184,48 +201,99 @@ static void dis_read_completed(struct bt_gatt_dm *dm, void *context)
184201
185202 rp .single .handle = attr -> handle + 1 ;
186203
204+ err = bt_gatt_read (bt_gatt_dm_conn_get (dm ), & rp );
205+ if (err ) {
206+ LOG_ERR ("GATT read problem (err:%d)" , err );
207+ peer_unpair ();
208+ }
209+
187210 err = bt_gatt_dm_data_release (dm );
188211 if (err ) {
189212 goto error ;
190213 }
191214
192- bt_gatt_read (discovering_peer_conn , & rp );
193215 return ;
194216error :
195217 LOG_ERR ("Discovery data release failed (err:%d)" , err );
196218 module_set_state (MODULE_STATE_ERROR );
197219}
198220
199- static void dis_not_found (struct bt_conn * conn , void * context )
221+ static void start_discovery (struct bt_conn * conn ,
222+ const struct bt_uuid * svc_uuid ,
223+ bool discovery_hids )
200224{
201- LOG_ERR ("DIS not found" );
202- __ASSERT_NO_MSG (discovering_peer_conn == conn );
203- peer_unpair ();
225+ static const struct bt_gatt_dm_cb discovery_cb = {
226+ .completed = discovery_completed ,
227+ .service_not_found = service_not_found ,
228+ .error_found = discovery_error ,
229+ };
230+
231+ static const struct bt_gatt_dm_cb hids_discovery_cb = {
232+ .completed = hids_discovery_completed ,
233+ .service_not_found = service_not_found ,
234+ .error_found = discovery_error ,
235+ };
236+
237+ int err = bt_gatt_dm_start (conn , svc_uuid ,
238+ discovery_hids ? & hids_discovery_cb : & discovery_cb ,
239+ NULL );
240+
241+ __ASSERT_NO_MSG (err != - EALREADY );
242+ __ASSERT_NO_MSG (err != - EINVAL );
243+ if (err ) {
244+ LOG_ERR ("Cannot start discovery (err:%d)" , err );
245+ peer_unpair ();
246+ }
204247}
205248
206- static void dis_read_error ( struct bt_conn * conn , int err , void * context )
249+ static bool verify_peer ( void )
207250{
208- LOG_ERR ("Error discovering DIS (err:%d)" , err );
209- __ASSERT_NO_MSG (discovering_peer_conn == conn );
210- peer_unpair ();
251+ if (peer_vid != vendor_vid ) {
252+ LOG_WRN ("Invalid peripheral VID" );
253+ return false;
254+ }
255+
256+ return true;
211257}
212258
213- static void start_dis_read (struct bt_conn * conn )
259+ static void next_discovery_step_fn (struct k_work * w )
214260{
215- static const struct bt_gatt_dm_cb dis_discovery_cb = {
216- .completed = dis_read_completed ,
217- .service_not_found = dis_not_found ,
218- .error_found = dis_read_error ,
219- };
261+ BUILD_ASSERT_MSG ((DISCOVERY_STATE_HIDS + 1 ) == DISCOVERY_STATE_COUNT ,
262+ "HIDs must be discovered last - after device is verified" );
220263
221- int err = bt_gatt_dm_start ( conn , BT_UUID_DIS , & dis_discovery_cb , NULL ) ;
264+ state ++ ;
222265
223- if (err ) {
224- LOG_ERR ("Cannot start DIS discovery (err:%d)" , err );
225- peer_unpair ();
266+ switch (state ) {
267+ case DISCOVERY_STATE_DEV_DESCR :
268+ start_discovery (discovering_peer_conn , & custom_desc_uuid .uuid , false);
269+ break ;
270+
271+ case DISCOVERY_STATE_DIS :
272+ start_discovery (discovering_peer_conn , BT_UUID_DIS , false);
273+ break ;
274+
275+ case DISCOVERY_STATE_HIDS :
276+ if (!verify_peer ()) {
277+ peer_unpair ();
278+ } else {
279+ start_discovery (discovering_peer_conn , BT_UUID_HIDS , true);
280+ }
281+ break ;
282+
283+ case DISCOVERY_STATE_START :
284+ case DISCOVERY_STATE_COUNT :
285+ default :
286+ __ASSERT_NO_MSG (false);
226287 }
227288}
228289
290+ static void init (void )
291+ {
292+ k_work_init (& next_discovery_step , next_discovery_step_fn );
293+ state = DISCOVERY_STATE_START ;
294+ module_set_state (MODULE_STATE_READY );
295+ }
296+
229297static bool event_handler (const struct event_header * eh )
230298{
231299 if (is_ble_peer_event (eh )) {
@@ -236,8 +304,7 @@ static bool event_handler(const struct event_header *eh)
236304 case PEER_STATE_SECURED :
237305 discovering_peer_conn = event -> id ;
238306 bt_conn_ref (discovering_peer_conn );
239-
240- start_dis_read (event -> id );
307+ k_work_submit (& next_discovery_step );
241308 break ;
242309
243310 default :
@@ -258,6 +325,7 @@ static bool event_handler(const struct event_header *eh)
258325 }
259326 bt_conn_unref (discovering_peer_conn );
260327 discovering_peer_conn = NULL ;
328+ state = DISCOVERY_STATE_START ;
261329
262330 return false;
263331 }
@@ -267,9 +335,7 @@ static bool event_handler(const struct event_header *eh)
267335 cast_module_state_event (eh );
268336
269337 if (check_state (event , MODULE_ID (main ), MODULE_STATE_READY )) {
270- k_work_init (& hids_discovery_start ,
271- hids_discovery_start_fn );
272- module_set_state (MODULE_STATE_READY );
338+ init ();
273339 }
274340
275341 return false;
0 commit comments