• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 1998-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #include <string.h>
20 
21 #include "bt_target.h"
22 #if defined(HL_INCLUDED) && (HL_INCLUDED == TRUE)
23 
24 #include "sdp_api.h"
25 #include "bta_hl_int.h"
26 
27 
28 /*******************************************************************************
29 **
30 ** Function         bta_hl_fill_sup_feature_list
31 **
32 ** Description      Fill the supported features from teh SDP record
33 **
34 ** Returns          TRUE if found, FALSE if not
35 **                  If found, the passed protocol list element is filled in.
36 **
37 *******************************************************************************/
bta_hl_fill_sup_feature_list(const tSDP_DISC_ATTR * p_attr,tBTA_HL_SUP_FEATURE_LIST_ELEM * p_list)38 BOOLEAN bta_hl_fill_sup_feature_list( const tSDP_DISC_ATTR  *p_attr,
39                                       tBTA_HL_SUP_FEATURE_LIST_ELEM *p_list)
40 {
41     tSDP_DISC_ATTR  *p_sattr;
42     UINT8           seq_len, item_cnt;
43     UINT8           list_cnt=0;
44     BOOLEAN         status=TRUE;
45 
46     for (p_attr = p_attr->attr_value.v.p_sub_attr; p_attr; p_attr = p_attr->p_next_attr)
47     {
48         /* mdep sequence */
49         if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE)
50         {
51             return(FALSE);
52         }
53         seq_len =SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
54         item_cnt=0;
55 
56         for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr && (item_cnt < 4) ; p_sattr = p_sattr->p_next_attr)
57         {
58             /* for each mdep list */
59 
60             p_list->list_elem[list_cnt].p_mdep_desp = NULL;
61             switch (item_cnt)
62             {
63                 case 0:
64                     p_list->list_elem[list_cnt].mdep_id = p_sattr->attr_value.v.u8;
65                     break;
66                 case 1:
67                     p_list->list_elem[list_cnt].data_type = p_sattr->attr_value.v.u16;
68                     break;
69                 case 2:
70                     p_list->list_elem[list_cnt].mdep_role = (tBTA_HL_MDEP_ROLE) p_sattr->attr_value.v.u8;
71                     break;
72                 case 3:
73                     p_list->list_elem[list_cnt].p_mdep_desp    = (char *) p_sattr->attr_value.v.array;
74                     break;
75             }
76 
77             item_cnt++;
78         }
79         list_cnt++;
80     }
81     p_list->num_elems = list_cnt;
82     return(status);
83 }
84 
85 /*******************************************************************************
86 **
87 ** Function         bta_hl_compose_supported_feature_list
88 **
89 ** Description      This function is called to compose a data sequence from
90 **                  the supported  feature element list struct pointer
91 **
92 ** Returns          the length of the data sequence
93 **
94 *******************************************************************************/
bta_hl_compose_supported_feature_list(UINT8 * p,UINT16 num_elem,const tBTA_HL_SUP_FEATURE_ELEM * p_elem_list)95 int bta_hl_compose_supported_feature_list( UINT8 *p, UINT16 num_elem,
96                                            const tBTA_HL_SUP_FEATURE_ELEM *p_elem_list)
97 {
98     UINT16          xx, str_len, seq_len;
99     UINT8           *p_head = p;
100 
101     for (xx = 0; xx < num_elem; xx++, p_elem_list++)
102     {
103         UINT8_TO_BE_STREAM  (p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
104         seq_len=7;
105         str_len=0;
106         if (p_elem_list->p_mdep_desp)
107         {
108             str_len = strlen(p_elem_list->p_mdep_desp)+1;
109             seq_len += str_len+2; /* todo add a # symbol for 2 */
110         }
111 
112         *p++ = (UINT8) seq_len;
113 
114         UINT8_TO_BE_STREAM  (p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
115         UINT8_TO_BE_STREAM  (p, p_elem_list->mdep_id);
116         UINT8_TO_BE_STREAM  (p, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
117         UINT16_TO_BE_STREAM (p, p_elem_list->data_type);
118         UINT8_TO_BE_STREAM  (p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
119         UINT8_TO_BE_STREAM  (p, p_elem_list->mdep_role);
120 
121         if (str_len)
122         {
123             UINT8_TO_BE_STREAM  (p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
124             UINT8_TO_BE_STREAM  (p, str_len);
125             ARRAY_TO_BE_STREAM(p, p_elem_list->p_mdep_desp, str_len);
126         }
127     }
128 
129     return(p - p_head);
130 }
131 
132 /*******************************************************************************
133 **
134 ** Function         bta_hl_add_sup_feature_list
135 **
136 ** Description      This function is called to add a protocol descriptor list to
137 **                  a record. This would be through the SDP database maintenance API.
138 **                  If the protocol list already exists in the record, it is replaced
139 **                  with the new list.
140 **
141 ** Returns          TRUE if added OK, else FALSE
142 **
143 *******************************************************************************/
bta_hl_add_sup_feature_list(UINT32 handle,UINT16 num_elem,const tBTA_HL_SUP_FEATURE_ELEM * p_elem_list)144 BOOLEAN bta_hl_add_sup_feature_list (UINT32 handle, UINT16 num_elem,
145                                      const tBTA_HL_SUP_FEATURE_ELEM *p_elem_list)
146 {
147     UINT8       *p_buf;
148     int         offset;
149     BOOLEAN     result = FALSE;
150 
151     if ((p_buf = (UINT8 *)GKI_getbuf(BTA_HL_SUP_FEATURE_SDP_BUF_SIZE)) != NULL)
152     {
153         offset = bta_hl_compose_supported_feature_list(p_buf, num_elem, p_elem_list);
154         result = SDP_AddAttribute (handle, ATTR_ID_HDP_SUP_FEAT_LIST,
155                                    DATA_ELE_SEQ_DESC_TYPE, (UINT32) offset, p_buf);
156         GKI_freebuf(p_buf);
157     }
158     return result;
159 }
160 
161 /*****************************************************************************
162 **
163 **  Function:    bta_hl_sdp_update
164 **
165 **  Purpose:     Register an HDP application with SDP
166 **
167 **  Parameters:  p_cb           - Pointer to MA instance control block
168 **               p_service_name - MA server name
169 **               inst_id        - MAS instance ID
170 **               msg_type       - Supported message type(s)
171 **
172 **
173 **  Returns:     void
174 **
175 *****************************************************************************/
bta_hl_sdp_update(UINT8 app_id)176 tBTA_HL_STATUS bta_hl_sdp_update (UINT8 app_id)
177 {
178     UINT16                          svc_class_id_list[BTA_HL_NUM_SVC_ELEMS];
179     tSDP_PROTOCOL_ELEM              proto_elem_list[BTA_HL_NUM_PROTO_ELEMS];
180     tSDP_PROTO_LIST_ELEM            add_proto_list;
181     tBTA_HL_SUP_FEATURE_LIST_ELEM   sup_feature_list;
182     UINT16                          browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
183     UINT8                           i,j, cnt,mdep_id, mdep_role;
184     UINT8                           data_exchange_spec = BTA_HL_SDP_IEEE_11073_20601;
185     UINT8                           mcap_sup_proc = BTA_HL_MCAP_SUP_PROC_MASK;
186     UINT16                          profile_uuid = UUID_SERVCLASS_HDP_PROFILE;
187     UINT16                          version = BTA_HL_VERSION_01_00;
188     UINT8                           num_services=1;
189     tBTA_HL_APP_CB                  *p_cb = BTA_HL_GET_APP_CB_PTR(0);
190     BOOLEAN                         result = TRUE;
191     tBTA_HL_STATUS                  status = BTA_HL_STATUS_OK;
192 
193     if ((p_cb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE) &&
194         (!p_cb->sup_feature.advertize_source_sdp))
195     {
196         return BTA_HL_STATUS_OK;
197     }
198 
199     num_services=1;
200     svc_class_id_list[0]= UUID_SERVCLASS_HDP_SOURCE;
201     if (p_cb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SINK)
202     {
203         svc_class_id_list[0]= UUID_SERVCLASS_HDP_SINK;
204     }
205     else
206     {
207         if (p_cb->sup_feature.app_role_mask != BTA_HL_MDEP_ROLE_MASK_SOURCE)
208         {
209             /* dual role */
210             num_services=2;
211             svc_class_id_list[1]= UUID_SERVCLASS_HDP_SINK;
212         }
213     }
214     result &= SDP_AddServiceClassIdList(p_cb->sdp_handle, num_services, svc_class_id_list);
215 
216     if (result)
217     {
218         /* add the protocol element sequence */
219         proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
220         proto_elem_list[0].num_params = 1;
221         proto_elem_list[0].params[0] = p_cb->ctrl_psm;
222         proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_MCAP_CTRL;
223         proto_elem_list[1].num_params = 1;
224         proto_elem_list[1].params[0] = version;
225         result &= SDP_AddProtocolList(p_cb->sdp_handle, BTA_HL_NUM_PROTO_ELEMS, proto_elem_list);
226 
227         result &= SDP_AddProfileDescriptorList(p_cb->sdp_handle, profile_uuid, version);
228     }
229 
230     if (result)
231     {
232         add_proto_list.num_elems = BTA_HL_NUM_ADD_PROTO_ELEMS;
233         add_proto_list.list_elem[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
234         add_proto_list.list_elem[0].num_params = 1;
235         add_proto_list.list_elem[0].params[0] = p_cb->data_psm;
236         add_proto_list.list_elem[1].protocol_uuid = UUID_PROTOCOL_MCAP_DATA;
237         add_proto_list.list_elem[1].num_params = 0;
238         result &= SDP_AddAdditionProtoLists(p_cb->sdp_handle, BTA_HL_NUM_ADD_PROTO_LISTS,
239                                             (tSDP_PROTO_LIST_ELEM *)&add_proto_list);
240     }
241 
242     if (result)
243     {
244         if (p_cb->srv_name[0] )
245         {
246             result &= SDP_AddAttribute(p_cb->sdp_handle,
247                                        (UINT16)ATTR_ID_SERVICE_NAME,
248                                        (UINT8)TEXT_STR_DESC_TYPE,
249                                        (UINT32)(strlen(p_cb->srv_name) + 1),
250                                        (UINT8 *)p_cb->srv_name);
251         } /* end of setting optional service name */
252     }
253 
254     if (result)
255     {
256         if (p_cb->srv_desp[0] )
257         {
258             result &= SDP_AddAttribute(p_cb->sdp_handle,
259                                        (UINT16)ATTR_ID_SERVICE_DESCRIPTION,
260                                        (UINT8)TEXT_STR_DESC_TYPE,
261                                        (UINT32)(strlen(p_cb->srv_desp) + 1),
262                                        (UINT8 *)p_cb->srv_desp);
263 
264         } /* end of setting optional service description */
265 
266     }
267 
268     if (result)
269     {
270         if (p_cb->provider_name[0] )
271         {
272             result &= SDP_AddAttribute(p_cb->sdp_handle,
273                                        (UINT16)ATTR_ID_PROVIDER_NAME,
274                                        (UINT8)TEXT_STR_DESC_TYPE,
275                                        (UINT32)(strlen(p_cb->provider_name) + 1),
276                                        (UINT8 *)p_cb->provider_name);
277         } /* end of setting optional provider name */
278     }
279 
280     /* add supported feture list */
281 
282     if (result)
283     {
284         cnt=0;
285         for (i=1; i< BTA_HL_NUM_MDEPS; i++)
286         {
287             if (p_cb->sup_feature.mdep[i].mdep_id)
288             {
289                 mdep_id = (UINT8)p_cb->sup_feature.mdep[i].mdep_id;
290                 mdep_role = (UINT8)p_cb->sup_feature.mdep[i].mdep_cfg.mdep_role;
291 
292                 APPL_TRACE_DEBUG1("num_of_mdep_data_types %d ", p_cb->sup_feature.mdep[i].mdep_cfg.num_of_mdep_data_types);
293                 for (j=0; j<p_cb->sup_feature.mdep[i].mdep_cfg.num_of_mdep_data_types; j++)
294                 {
295                     sup_feature_list.list_elem[cnt].mdep_id = mdep_id;
296                     sup_feature_list.list_elem[cnt].mdep_role = mdep_role;
297                     sup_feature_list.list_elem[cnt].data_type = p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].data_type;
298                     if (p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].desp[0] != '\0')
299                     {
300                         sup_feature_list.list_elem[cnt].p_mdep_desp = p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].desp;
301                     }
302                     else
303                     {
304                         sup_feature_list.list_elem[cnt].p_mdep_desp = NULL;
305                     }
306 
307                     cnt++;
308                     if (cnt==BTA_HL_NUM_SUP_FEATURE_ELEMS)
309                     {
310                         result = FALSE;
311                         break;
312                     }
313                 }
314             }
315         }
316         sup_feature_list.num_elems = cnt;
317         result &=   bta_hl_add_sup_feature_list (p_cb->sdp_handle,
318                                                  sup_feature_list.num_elems,
319                                                  sup_feature_list.list_elem);
320     }
321     if (result)
322     {
323         result &= SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_HDP_DATA_EXCH_SPEC, UINT_DESC_TYPE,
324                                    (UINT32)1, (UINT8*)&data_exchange_spec);
325     }
326 
327     if (result)
328     {
329 
330         result &= SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_HDP_MCAP_SUP_PROC, UINT_DESC_TYPE,
331                                    (UINT32)1, (UINT8*)&mcap_sup_proc);
332     }
333 
334     if (result)
335     {
336         result &= SDP_AddUuidSequence(p_cb->sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
337     }
338 
339     if (result)
340     {
341         for(i=0; i < num_services; i++)
342         {
343             bta_sys_add_uuid(svc_class_id_list[i]);
344             APPL_TRACE_DEBUG2("dbg bta_sys_add_uuid i=%d uuid=0x%x", i, svc_class_id_list[i]); //todo
345         }
346     }
347     else
348     {
349         if (p_cb->sdp_handle)
350         {
351             SDP_DeleteRecord(p_cb->sdp_handle);
352             p_cb->sdp_handle = 0;
353         }
354         status = BTA_HL_STATUS_SDP_FAIL;
355     }
356 #if BTA_HL_DEBUG == TRUE
357     APPL_TRACE_DEBUG1("bta_hl_sdp_update status=%s", bta_hl_status_code(status));
358 #endif
359     return status;
360 }
361 
362 
363 /*****************************************************************************
364 **
365 **  Function:    bta_hl_sdp_register
366 **
367 **  Purpose:     Register an HDP application with SDP
368 **
369 **  Parameters:  p_cb           - Pointer to MA instance control block
370 **               p_service_name - MA server name
371 **               inst_id        - MAS instance ID
372 **               msg_type       - Supported message type(s)
373 **
374 **
375 **  Returns:     void
376 **
377 *****************************************************************************/
bta_hl_sdp_register(UINT8 app_idx)378 tBTA_HL_STATUS bta_hl_sdp_register (UINT8 app_idx)
379 {
380     UINT16                          svc_class_id_list[BTA_HL_NUM_SVC_ELEMS];
381     tSDP_PROTOCOL_ELEM              proto_elem_list[BTA_HL_NUM_PROTO_ELEMS];
382     tSDP_PROTO_LIST_ELEM            add_proto_list;
383     tBTA_HL_SUP_FEATURE_LIST_ELEM   sup_feature_list;
384     UINT16                          browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
385     UINT8                           i,j, cnt,mdep_id, mdep_role;
386     UINT8                           data_exchange_spec = BTA_HL_SDP_IEEE_11073_20601;
387     UINT8                           mcap_sup_proc = BTA_HL_MCAP_SUP_PROC_MASK;
388     UINT16                          profile_uuid = UUID_SERVCLASS_HDP_PROFILE;
389     UINT16                          version = BTA_HL_VERSION_01_00;
390     UINT8                           num_services=1;
391     tBTA_HL_APP_CB                  *p_cb = BTA_HL_GET_APP_CB_PTR(app_idx);
392     BOOLEAN                         result = TRUE;
393     tBTA_HL_STATUS                  status = BTA_HL_STATUS_OK;
394 
395 #if BTA_HL_DEBUG == TRUE
396     APPL_TRACE_DEBUG1("bta_hl_sdp_register app_idx=%d",app_idx);
397 #endif
398 
399     if ((p_cb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE) &&
400         (!p_cb->sup_feature.advertize_source_sdp))
401     {
402         return BTA_HL_STATUS_OK;
403     }
404 
405     if ((p_cb->sdp_handle  = SDP_CreateRecord()) == 0)
406     {
407         return BTA_HL_STATUS_SDP_NO_RESOURCE;
408     }
409 
410     num_services=1;
411     svc_class_id_list[0]= UUID_SERVCLASS_HDP_SOURCE;
412     if (p_cb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SINK)
413     {
414         svc_class_id_list[0]= UUID_SERVCLASS_HDP_SINK;
415     }
416     else
417     {
418         if (p_cb->sup_feature.app_role_mask != BTA_HL_MDEP_ROLE_MASK_SOURCE)
419         {
420             /* dual role */
421             num_services=2;
422             svc_class_id_list[1]= UUID_SERVCLASS_HDP_SINK;
423         }
424     }
425     result &= SDP_AddServiceClassIdList(p_cb->sdp_handle, num_services, svc_class_id_list);
426 
427     if (result)
428     {
429         /* add the protocol element sequence */
430         proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
431         proto_elem_list[0].num_params = 1;
432         proto_elem_list[0].params[0] = p_cb->ctrl_psm;
433         proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_MCAP_CTRL;
434         proto_elem_list[1].num_params = 1;
435         proto_elem_list[1].params[0] = version;
436         result &= SDP_AddProtocolList(p_cb->sdp_handle, BTA_HL_NUM_PROTO_ELEMS, proto_elem_list);
437 
438         result &= SDP_AddProfileDescriptorList(p_cb->sdp_handle, profile_uuid, version);
439     }
440 
441     if (result)
442     {
443         add_proto_list.num_elems = BTA_HL_NUM_ADD_PROTO_ELEMS;
444         add_proto_list.list_elem[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
445         add_proto_list.list_elem[0].num_params = 1;
446         add_proto_list.list_elem[0].params[0] = p_cb->data_psm;
447         add_proto_list.list_elem[1].protocol_uuid = UUID_PROTOCOL_MCAP_DATA;
448         add_proto_list.list_elem[1].num_params = 0;
449         result &= SDP_AddAdditionProtoLists(p_cb->sdp_handle, BTA_HL_NUM_ADD_PROTO_LISTS,
450                                             (tSDP_PROTO_LIST_ELEM *)&add_proto_list);
451     }
452 
453     if (result)
454     {
455         if (p_cb->srv_name[0] )
456         {
457             result &= SDP_AddAttribute(p_cb->sdp_handle,
458                                        (UINT16)ATTR_ID_SERVICE_NAME,
459                                        (UINT8)TEXT_STR_DESC_TYPE,
460                                        (UINT32)(strlen(p_cb->srv_name) + 1),
461                                        (UINT8 *)p_cb->srv_name);
462         } /* end of setting optional service name */
463     }
464 
465     if (result)
466     {
467         if (p_cb->srv_desp[0] )
468         {
469             result &= SDP_AddAttribute(p_cb->sdp_handle,
470                                        (UINT16)ATTR_ID_SERVICE_DESCRIPTION,
471                                        (UINT8)TEXT_STR_DESC_TYPE,
472                                        (UINT32)(strlen(p_cb->srv_desp) + 1),
473                                        (UINT8 *)p_cb->srv_desp);
474 
475         } /* end of setting optional service description */
476 
477     }
478 
479     if (result)
480     {
481         if (p_cb->provider_name[0] )
482         {
483             result &= SDP_AddAttribute(p_cb->sdp_handle,
484                                        (UINT16)ATTR_ID_PROVIDER_NAME,
485                                        (UINT8)TEXT_STR_DESC_TYPE,
486                                        (UINT32)(strlen(p_cb->provider_name) + 1),
487                                        (UINT8 *)p_cb->provider_name);
488         } /* end of setting optional provider name */
489     }
490 
491     /* add supported feture list */
492 
493     if (result)
494     {
495         cnt=0;
496         for (i=1; i<= p_cb->sup_feature.num_of_mdeps; i++)
497         {
498             mdep_id = (UINT8)p_cb->sup_feature.mdep[i].mdep_id;
499             mdep_role = (UINT8)p_cb->sup_feature.mdep[i].mdep_cfg.mdep_role;
500 
501             for (j=0; j<p_cb->sup_feature.mdep[i].mdep_cfg.num_of_mdep_data_types; j++)
502             {
503                 sup_feature_list.list_elem[cnt].mdep_id = mdep_id;
504                 sup_feature_list.list_elem[cnt].mdep_role = mdep_role;
505                 sup_feature_list.list_elem[cnt].data_type = p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].data_type;
506                 if (p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].desp[0] != '\0')
507                 {
508                     sup_feature_list.list_elem[cnt].p_mdep_desp = p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].desp;
509                 }
510                 else
511                 {
512                     sup_feature_list.list_elem[cnt].p_mdep_desp = NULL;
513                 }
514 
515                 cnt++;
516                 if (cnt==BTA_HL_NUM_SUP_FEATURE_ELEMS)
517                 {
518                     result = FALSE;
519                     break;
520                 }
521             }
522         }
523         sup_feature_list.num_elems = cnt;
524         result &=   bta_hl_add_sup_feature_list (p_cb->sdp_handle,
525                                                  sup_feature_list.num_elems,
526                                                  sup_feature_list.list_elem);
527     }
528     if (result)
529     {
530         result &= SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_HDP_DATA_EXCH_SPEC, UINT_DESC_TYPE,
531                                    (UINT32)1, (UINT8*)&data_exchange_spec);
532     }
533 
534     if (result)
535     {
536 
537         result &= SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_HDP_MCAP_SUP_PROC, UINT_DESC_TYPE,
538                                    (UINT32)1, (UINT8*)&mcap_sup_proc);
539     }
540 
541     if (result)
542     {
543         result &= SDP_AddUuidSequence(p_cb->sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
544     }
545 
546     if (result)
547     {
548         for(i=0; i < num_services; i++)
549         {
550             bta_sys_add_uuid(svc_class_id_list[i]);
551             APPL_TRACE_DEBUG2("dbg bta_sys_add_uuid i=%d uuid=0x%x", i, svc_class_id_list[i]); //todo
552         }
553     }
554     else
555     {
556         if (p_cb->sdp_handle)
557         {
558             SDP_DeleteRecord(p_cb->sdp_handle);
559             p_cb->sdp_handle = 0;
560         }
561         status = BTA_HL_STATUS_SDP_FAIL;
562     }
563 #if BTA_HL_DEBUG == TRUE
564     APPL_TRACE_DEBUG1("bta_hl_sdp_register status=%s", bta_hl_status_code(status));
565 #endif
566     return status;
567 }
568 
569 /*******************************************************************************
570 **
571 ** Function         bta_hl_find_sink_or_src_srv_class_in_db
572 **
573 ** Description      This function queries an SDP database for either a HDP Sink or
574 **                  Source service class ID.
575 **                  If the p_start_rec pointer is NULL, it looks from the beginning
576 **                  of the database, else it continues from the next record after
577 **                  p_start_rec.
578 **
579 ** Returns          Pointer to record containing service class, or NULL
580 **
581 *******************************************************************************/
bta_hl_find_sink_or_src_srv_class_in_db(const tSDP_DISCOVERY_DB * p_db,const tSDP_DISC_REC * p_start_rec)582 tSDP_DISC_REC *bta_hl_find_sink_or_src_srv_class_in_db (const tSDP_DISCOVERY_DB *p_db,
583                                                         const tSDP_DISC_REC *p_start_rec)
584 {
585 #if SDP_CLIENT_ENABLED == TRUE
586     tSDP_DISC_REC   *p_rec;
587     tSDP_DISC_ATTR  *p_attr, *p_sattr;
588 
589     /* Must have a valid database */
590     if (p_db == NULL)
591         return(NULL);
592 
593 
594     if (!p_start_rec)
595     {
596 
597         p_rec = p_db->p_first_rec;
598     }
599     else
600     {
601         p_rec = p_start_rec->p_next_rec;
602     }
603 
604     while (p_rec)
605     {
606         p_attr = p_rec->p_first_attr;
607         while (p_attr)
608         {
609             if ((p_attr->attr_id == ATTR_ID_SERVICE_CLASS_ID_LIST)
610                 && (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE))
611             {
612                 for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr; p_sattr = p_sattr->p_next_attr)
613                 {
614                     if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE)
615                         && (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 2)
616                         && ( (p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SINK) ||
617                              (p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SOURCE)) )
618                     {
619                         return(p_rec);
620                     }
621                 }
622                 break;
623             }
624 
625             p_attr = p_attr->p_next_attr;
626         }
627 
628         p_rec = p_rec->p_next_rec;
629     }
630 #endif
631     /* If here, no matching UUID found */
632 
633 #if BTA_HL_DEBUG == TRUE
634     APPL_TRACE_DEBUG0("bta_hl_find_sink_or_src_srv_class_in_db failed");
635 #endif
636 
637     return(NULL);
638 }
639 #endif /* HL_INCLUDED */
640