1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 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 
20 /******************************************************************************
21  *
22  *  This file contains source code for some utility functions to help parse
23  *  and build NFC Data Exchange Format (NDEF) messages for Connection
24  *  Handover
25  *
26  ******************************************************************************/
27 
28 #include <string.h>
29 #include "ndef_utils.h"
30 
31 /*******************************************************************************
32 **
33 ** Static Local Functions
34 */
35 static UINT8 *ndef_get_bt_oob_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
36                                       char *p_id_str);
37 
38 /*******************************************************************************
39 **
40 ** Static data
41 */
42 
43 /* Handover Request Record Type */
44 static UINT8 hr_rec_type[HR_REC_TYPE_LEN] = { 0x48, 0x72 }; /* "Hr" */
45 
46 /* Handover Select Record Type */
47 static UINT8 hs_rec_type[HS_REC_TYPE_LEN] = { 0x48, 0x73 }; /* "Hs" */
48 
49 /* Handover Carrier recrod Type */
50 static UINT8 hc_rec_type[HC_REC_TYPE_LEN] = { 0x48, 0x63 }; /* "Hc" */
51 
52 /* Collision Resolution Record Type */
53 static UINT8 cr_rec_type[CR_REC_TYPE_LEN] = { 0x63, 0x72 }; /* "cr" */
54 
55 /* Alternative Carrier Record Type */
56 static UINT8 ac_rec_type[AC_REC_TYPE_LEN] = { 0x61, 0x63 }; /* "ac" */
57 
58 /* Error Record Type */
59 static UINT8 err_rec_type[ERR_REC_TYPE_LEN] = { 0x65, 0x72, 0x72 }; /* "err" */
60 
61 /* Bluetooth OOB Data Type */
62 static UINT8 *p_bt_oob_rec_type = (UINT8 *)"application/vnd.bluetooth.ep.oob";
63 
64 /* Wifi WSC Data Type */
65 static UINT8 *p_wifi_wsc_rec_type = (UINT8 *)"application/vnd.wfa.wsc";
66 
67 /*******************************************************************************
68 **
69 ** Function         NDEF_MsgCreateWktHr
70 **
71 ** Description      This function creates Handover Request Record with version.
72 **
73 ** Returns          NDEF_OK if all OK
74 **
75 *******************************************************************************/
NDEF_MsgCreateWktHr(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,UINT8 version)76 tNDEF_STATUS NDEF_MsgCreateWktHr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
77                                   UINT8 version )
78 {
79     tNDEF_STATUS    status;
80 
81     NDEF_MsgInit (p_msg, max_size, p_cur_size);
82 
83     /* Add record with version */
84     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
85                              NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN,
86                              NULL, 0, &version, 1);
87 
88     return (status);
89 }
90 
91 /*******************************************************************************
92 **
93 ** Function         NDEF_MsgCreateWktHs
94 **
95 ** Description      This function creates Handover Select Record with version.
96 **
97 ** Returns          NDEF_OK if all OK
98 **
99 *******************************************************************************/
NDEF_MsgCreateWktHs(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,UINT8 version)100 tNDEF_STATUS NDEF_MsgCreateWktHs (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
101                                   UINT8 version )
102 {
103     tNDEF_STATUS    status;
104 
105     NDEF_MsgInit (p_msg, max_size, p_cur_size);
106 
107     /* Add record with version */
108     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
109                              NDEF_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN,
110                              NULL, 0, &version, 1);
111 
112     return (status);
113 }
114 
115 /*******************************************************************************
116 **
117 ** Function         NDEF_MsgAddWktHc
118 **
119 ** Description      This function adds Handover Carrier Record.
120 **
121 ** Returns          NDEF_OK if all OK
122 **
123 *******************************************************************************/
NDEF_MsgAddWktHc(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str,UINT8 ctf,UINT8 carrier_type_len,UINT8 * p_carrier_type,UINT8 carrier_data_len,UINT8 * p_carrier_data)124 tNDEF_STATUS NDEF_MsgAddWktHc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
125                                char  *p_id_str, UINT8 ctf,
126                                UINT8 carrier_type_len, UINT8 *p_carrier_type,
127                                UINT8 carrier_data_len, UINT8 *p_carrier_data)
128 {
129     tNDEF_STATUS    status;
130     UINT8           payload[256], *p, id_len;
131     UINT32          payload_len;
132 
133     if (carrier_type_len + carrier_data_len + 2 > 256)
134     {
135         return (NDEF_MSG_INSUFFICIENT_MEM);
136     }
137 
138     p = payload;
139 
140     UINT8_TO_STREAM (p, (ctf & 0x07));
141     UINT8_TO_STREAM (p, carrier_type_len);
142     ARRAY_TO_STREAM (p, p_carrier_type, carrier_type_len);
143     ARRAY_TO_STREAM (p, p_carrier_data, carrier_data_len);
144 
145     payload_len = (UINT32)carrier_type_len + carrier_data_len + 2;
146 
147     id_len = (UINT8)strlen (p_id_str);
148 
149     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
150                              NDEF_TNF_WKT, hc_rec_type, HC_REC_TYPE_LEN,
151                              (UINT8*)p_id_str, id_len, payload, payload_len);
152     return (status);
153 }
154 
155 /*******************************************************************************
156 **
157 ** Function         NDEF_MsgAddWktAc
158 **
159 ** Description      This function adds Alternative Carrier Record.
160 **
161 ** Returns          NDEF_OK if all OK
162 **
163 *******************************************************************************/
NDEF_MsgAddWktAc(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,UINT8 cps,char * p_carrier_data_ref_str,UINT8 aux_data_ref_count,char * p_aux_data_ref_str[])164 tNDEF_STATUS NDEF_MsgAddWktAc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
165                                UINT8 cps, char *p_carrier_data_ref_str,
166                                UINT8 aux_data_ref_count, char *p_aux_data_ref_str[])
167 {
168     tNDEF_STATUS    status;
169     UINT32          payload_len;
170     UINT8           ref_str_len, xx;
171     UINT8 *p_rec, *p;
172 
173     /* get payload length first */
174 
175     /* CPS, length of carrier data ref, carrier data ref, Aux data reference count */
176     payload_len = 3 + (UINT8)strlen (p_carrier_data_ref_str);
177     for (xx = 0; xx < aux_data_ref_count; xx++)
178     {
179         /* Aux Data Reference length (1 byte) */
180         payload_len += 1 + (UINT8)strlen (p_aux_data_ref_str[xx]);
181     }
182 
183     /* reserve memory for payload */
184     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
185                              NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN,
186                              NULL, 0, NULL, payload_len);
187 
188     if (status == NDEF_OK)
189     {
190         /* get AC record added at the end */
191         p_rec = NDEF_MsgGetLastRecInMsg (p_msg);
192 
193         /* get start pointer of reserved payload */
194         p = NDEF_RecGetPayload (p_rec, &payload_len);
195 
196         /* Add Carrier Power State */
197         UINT8_TO_BE_STREAM (p, cps);
198 
199         /* Carrier Data Reference length */
200         ref_str_len = (UINT8)strlen (p_carrier_data_ref_str);
201 
202         UINT8_TO_BE_STREAM (p, ref_str_len);
203 
204         /* Carrier Data Reference */
205         ARRAY_TO_BE_STREAM (p, p_carrier_data_ref_str, ref_str_len);
206 
207         /* Aux Data Reference Count */
208         UINT8_TO_BE_STREAM (p, aux_data_ref_count);
209 
210         for (xx = 0; xx < aux_data_ref_count; xx++)
211         {
212             /* Aux Data Reference length (1 byte) */
213             ref_str_len = (UINT8)strlen (p_aux_data_ref_str[xx]);
214 
215             UINT8_TO_BE_STREAM (p, ref_str_len);
216 
217             /* Aux Data Reference */
218             ARRAY_TO_BE_STREAM (p, p_aux_data_ref_str[xx], ref_str_len);
219         }
220     }
221 
222     return (status);
223 }
224 
225 /*******************************************************************************
226 **
227 ** Function         NDEF_MsgAddWktCr
228 **
229 ** Description      This function adds Collision Resolution Record.
230 **
231 ** Returns          NDEF_OK if all OK
232 **
233 *******************************************************************************/
NDEF_MsgAddWktCr(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,UINT16 random_number)234 tNDEF_STATUS NDEF_MsgAddWktCr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
235                                UINT16 random_number )
236 {
237     tNDEF_STATUS    status;
238     UINT8           data[2], *p;
239 
240     p = data;
241     UINT16_TO_BE_STREAM (p, random_number);
242 
243     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
244                              NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN,
245                              NULL, 0, data, 2);
246     return (status);
247 }
248 
249 /*******************************************************************************
250 **
251 ** Function         NDEF_MsgAddWktErr
252 **
253 ** Description      This function adds Error Record.
254 **
255 ** Returns          NDEF_OK if all OK
256 **
257 *******************************************************************************/
NDEF_MsgAddWktErr(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,UINT8 error_reason,UINT32 error_data)258 tNDEF_STATUS NDEF_MsgAddWktErr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
259                                 UINT8 error_reason, UINT32 error_data )
260 {
261     tNDEF_STATUS    status;
262     UINT8           payload[5], *p;
263     UINT32          payload_len;
264 
265     p = payload;
266 
267     UINT8_TO_BE_STREAM (p, error_reason);
268 
269     if (error_reason == 0x02)
270     {
271         UINT32_TO_BE_STREAM (p, error_data);
272         payload_len = 5;
273     }
274     else
275     {
276         UINT8_TO_BE_STREAM (p, error_data);
277         payload_len = 2;
278     }
279 
280     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
281                              NDEF_TNF_WKT, err_rec_type, ERR_REC_TYPE_LEN,
282                              NULL, 0, payload, payload_len);
283     return (status);
284 }
285 
286 /*******************************************************************************
287 **
288 ** Function         NDEF_MsgAddMediaBtOob
289 **
290 ** Description      This function adds BT OOB Record.
291 **
292 ** Returns          NDEF_OK if all OK
293 **
294 *******************************************************************************/
NDEF_MsgAddMediaBtOob(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str,BD_ADDR bd_addr)295 tNDEF_STATUS NDEF_MsgAddMediaBtOob (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
296                                     char *p_id_str, BD_ADDR bd_addr)
297 {
298     tNDEF_STATUS    status;
299     UINT8           payload[BD_ADDR_LEN + 2];
300     UINT8          *p;
301     UINT8           payload_len, id_len;
302 
303     p = payload;
304 
305     /* length including itself */
306     UINT16_TO_STREAM (p, BD_ADDR_LEN + 2);
307 
308     /* BD Addr */
309     BDADDR_TO_STREAM (p, bd_addr);
310 
311     payload_len = BD_ADDR_LEN + 2;
312     id_len = (UINT8)strlen (p_id_str);
313 
314     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
315                              NDEF_TNF_MEDIA, p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN,
316                              (UINT8*)p_id_str, id_len, payload, payload_len);
317     return (status);
318 }
319 
320 /*******************************************************************************
321 **
322 ** Function         NDEF_MsgAppendMediaBtOobCod
323 **
324 ** Description      This function appends COD EIR data at the end of BT OOB Record.
325 **
326 ** Returns          NDEF_OK if all OK
327 **
328 *******************************************************************************/
NDEF_MsgAppendMediaBtOobCod(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str,DEV_CLASS cod)329 tNDEF_STATUS NDEF_MsgAppendMediaBtOobCod (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
330                                           char *p_id_str, DEV_CLASS cod)
331 {
332     tNDEF_STATUS    status;
333     UINT8          *p_rec;
334     UINT8           eir_data[BT_OOB_COD_SIZE + 2];
335     UINT8          *p;
336     UINT8           eir_data_len;
337     UINT32          oob_data_len;
338 
339     /* find record by Payload ID */
340     p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
341 
342     if (!p_rec)
343         return (NDEF_REC_NOT_FOUND);
344 
345     /* create EIR data format for COD */
346     p = eir_data;
347     UINT8_TO_STREAM (p, BT_OOB_COD_SIZE + 1);
348     UINT8_TO_STREAM (p, BT_EIR_OOB_COD_TYPE);
349     DEVCLASS_TO_STREAM (p, cod);
350     eir_data_len = BT_OOB_COD_SIZE + 2;
351 
352     /* append EIR data at the end of record */
353     status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
354                                    p_rec, eir_data, eir_data_len);
355 
356     /* update BT OOB data length, if success */
357     if (status == NDEF_OK)
358     {
359         /* payload length is the same as BT OOB data length */
360         p = NDEF_RecGetPayload (p_rec, &oob_data_len);
361         UINT16_TO_STREAM (p, oob_data_len);
362     }
363 
364     return (status);
365 }
366 
367 /*******************************************************************************
368 **
369 ** Function         NDEF_MsgAppendMediaBtOobName
370 **
371 ** Description      This function appends Bluetooth Local Name EIR data
372 **                  at the end of BT OOB Record.
373 **
374 ** Returns          NDEF_OK if all OK
375 **
376 *******************************************************************************/
NDEF_MsgAppendMediaBtOobName(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str,BOOLEAN is_complete,UINT8 name_len,UINT8 * p_name)377 tNDEF_STATUS NDEF_MsgAppendMediaBtOobName (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
378                                            char *p_id_str, BOOLEAN is_complete,
379                                            UINT8 name_len, UINT8 *p_name)
380 {
381     tNDEF_STATUS    status;
382     UINT8          *p_rec;
383     UINT8           eir_data[256];
384     UINT8          *p;
385     UINT8           eir_data_len;
386     UINT32          oob_data_len;
387 
388     /* find record by Payload ID */
389     p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
390 
391     if (!p_rec)
392         return (NDEF_REC_NOT_FOUND);
393 
394     /* create EIR data format for COD */
395     p = eir_data;
396     UINT8_TO_STREAM (p, name_len + 1);
397 
398     if (is_complete)
399     {
400         UINT8_TO_STREAM (p, BT_EIR_COMPLETE_LOCAL_NAME_TYPE);
401     }
402     else
403     {
404         UINT8_TO_STREAM (p, BT_EIR_SHORTENED_LOCAL_NAME_TYPE);
405     }
406 
407     ARRAY_TO_STREAM (p, p_name, name_len);
408     eir_data_len = name_len + 2;
409 
410     /* append EIR data at the end of record */
411     status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
412                                    p_rec, eir_data, eir_data_len);
413 
414     /* update BT OOB data length, if success */
415     if (status == NDEF_OK)
416     {
417         /* payload length is the same as BT OOB data length */
418         p = NDEF_RecGetPayload (p_rec, &oob_data_len);
419         UINT16_TO_STREAM (p, oob_data_len);
420     }
421 
422     return (status);
423 }
424 
425 /*******************************************************************************
426 **
427 ** Function         NDEF_MsgAppendMediaBtOobHashCRandR
428 **
429 ** Description      This function appends Hash C and Rand R at the end of BT OOB Record.
430 **
431 ** Returns          NDEF_OK if all OK
432 **
433 *******************************************************************************/
NDEF_MsgAppendMediaBtOobHashCRandR(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str,UINT8 * p_hash_c,UINT8 * p_rand_r)434 tNDEF_STATUS NDEF_MsgAppendMediaBtOobHashCRandR (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
435                                                  char *p_id_str, UINT8 *p_hash_c, UINT8 *p_rand_r)
436 {
437     tNDEF_STATUS    status;
438     UINT8          *p_rec;
439     UINT8           eir_data[BT_OOB_HASH_C_SIZE + BT_OOB_RAND_R_SIZE + 4];
440     UINT8          *p;
441     UINT8           eir_data_len;
442     UINT32          oob_data_len;
443 
444     /* find record by Payload ID */
445     p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
446 
447     if (!p_rec)
448         return (NDEF_REC_NOT_FOUND);
449 
450     /* create EIR data format */
451     p = eir_data;
452 
453     UINT8_TO_STREAM   (p, BT_OOB_HASH_C_SIZE + 1);
454     UINT8_TO_STREAM   (p, BT_EIR_OOB_SSP_HASH_C_TYPE);
455     ARRAY16_TO_STREAM (p, p_hash_c);
456 
457     UINT8_TO_STREAM   (p, BT_OOB_RAND_R_SIZE + 1);
458     UINT8_TO_STREAM   (p, BT_EIR_OOB_SSP_RAND_R_TYPE);
459     ARRAY16_TO_STREAM (p, p_rand_r);
460 
461     eir_data_len = BT_OOB_HASH_C_SIZE + BT_OOB_RAND_R_SIZE + 4;
462 
463     /* append EIR data at the end of record */
464     status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
465                                    p_rec, eir_data, eir_data_len);
466 
467     /* update BT OOB data length, if success */
468     if (status == NDEF_OK)
469     {
470         /* payload length is the same as BT OOB data length */
471         p = NDEF_RecGetPayload (p_rec, &oob_data_len);
472         UINT16_TO_STREAM (p, oob_data_len);
473     }
474 
475     return (status);
476 }
477 
478 /*******************************************************************************
479 **
480 ** Function         NDEF_MsgAppendMediaBtOobEirData
481 **
482 ** Description      This function appends EIR Data at the end of BT OOB Record.
483 **
484 ** Returns          NDEF_OK if all OK
485 **
486 *******************************************************************************/
NDEF_MsgAppendMediaBtOobEirData(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str,UINT8 eir_type,UINT8 data_len,UINT8 * p_data)487 tNDEF_STATUS NDEF_MsgAppendMediaBtOobEirData (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
488                                               char *p_id_str,
489                                               UINT8 eir_type, UINT8 data_len, UINT8 *p_data)
490 {
491     tNDEF_STATUS    status;
492     UINT8          *p_rec;
493     UINT8           eir_data[256];
494     UINT8          *p;
495     UINT8           eir_data_len;
496     UINT32          oob_data_len;
497 
498     /* find record by Payload ID */
499     p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
500 
501     if (!p_rec)
502         return (NDEF_REC_NOT_FOUND);
503 
504     /* create EIR data format */
505     p = eir_data;
506     UINT8_TO_STREAM (p, data_len + 1);
507     UINT8_TO_STREAM (p, eir_type);
508     ARRAY_TO_STREAM (p, p_data, data_len);
509     eir_data_len = data_len + 2;
510 
511     /* append EIR data at the end of record */
512     status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
513                                    p_rec, eir_data, eir_data_len);
514 
515     /* update BT OOB data length, if success */
516     if (status == NDEF_OK)
517     {
518         /* payload length is the same as BT OOB data length */
519         p = NDEF_RecGetPayload (p_rec, &oob_data_len);
520         UINT16_TO_STREAM (p, oob_data_len);
521     }
522 
523     return (status);
524 }
525 
526 /*******************************************************************************
527 **
528 ** Function         NDEF_MsgAddMediaWifiWsc
529 **
530 ** Description      This function adds Wifi Wsc Record header.
531 **
532 ** Returns          NDEF_OK if all OK
533 **
534 *******************************************************************************/
NDEF_MsgAddMediaWifiWsc(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str,UINT8 * p_payload,UINT32 payload_len)535 tNDEF_STATUS NDEF_MsgAddMediaWifiWsc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
536                                     char *p_id_str, UINT8 *p_payload, UINT32 payload_len)
537 {
538     tNDEF_STATUS    status;
539     UINT8           id_len = 0;
540 
541     if (p_id_str)
542         id_len = (UINT8)strlen (p_id_str);
543 
544     status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
545                              NDEF_TNF_MEDIA, p_wifi_wsc_rec_type, WIFI_WSC_REC_TYPE_LEN,
546                              (UINT8*)p_id_str, id_len, p_payload, payload_len);
547     return (status);
548 }
549 
550 /*******************************************************************************
551 **
552 **              Static Local Functions
553 **
554 *******************************************************************************/
555 /*******************************************************************************
556 **
557 ** Function         ndef_get_bt_oob_record
558 **
559 ** Description      This function returns BT OOB record which has matched payload ID
560 **
561 ** Returns          pointer of record if found, otherwise NULL
562 **
563 *******************************************************************************/
ndef_get_bt_oob_record(UINT8 * p_msg,UINT32 max_size,UINT32 * p_cur_size,char * p_id_str)564 static UINT8 *ndef_get_bt_oob_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
565                                       char *p_id_str)
566 {
567     UINT8  *p_rec, *p_type;
568     UINT8   id_len, tnf, type_len;
569 
570     /* find record by Payload ID */
571     id_len = (UINT8)strlen (p_id_str);
572     p_rec = NDEF_MsgGetFirstRecById (p_msg, (UINT8*)p_id_str, id_len);
573 
574     if (!p_rec)
575         return (NULL);
576 
577     p_type = NDEF_RecGetType (p_rec, &tnf, &type_len);
578 
579     /* check type if this is BT OOB record */
580     if ((!p_rec)
581       ||(tnf != NDEF_TNF_MEDIA)
582       ||(type_len != BT_OOB_REC_TYPE_LEN)
583       ||(memcmp (p_type, p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN)))
584     {
585         return (NULL);
586     }
587 
588     return (p_rec);
589 }
590 
591