• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-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 /******************************************************************************
20  *
21  *  NFA interface for connection handover
22  *
23  ******************************************************************************/
24 #include <string.h>
25 #include "nfc_api.h"
26 #include "nfa_sys.h"
27 #include "nfa_sys_int.h"
28 #include "nfa_p2p_api.h"
29 #include "nfa_cho_api.h"
30 #include "nfa_cho_int.h"
31 #include "nfa_mem_co.h"
32 
33 /*****************************************************************************
34 **  Constants
35 *****************************************************************************/
36 
37 /*******************************************************************************
38 **
39 ** Function         NFA_ChoRegister
40 **
41 ** Description      This function is called to register callback function to receive
42 **                  connection handover events.
43 **
44 **                  On this registration, "urn:nfc:sn:handover" server will be
45 **                  registered on LLCP if enable_server is TRUE.
46 **
47 **                  The result of the registration is reported with NFA_CHO_REG_EVT.
48 **
49 ** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
50 **                  should happen before calling this function
51 **
52 ** Returns          NFA_STATUS_OK if successfully initiated
53 **                  NFA_STATUS_FAILED otherwise
54 **
55 *******************************************************************************/
NFA_ChoRegister(BOOLEAN enable_server,tNFA_CHO_CBACK * p_cback)56 tNFA_STATUS NFA_ChoRegister (BOOLEAN        enable_server,
57                              tNFA_CHO_CBACK *p_cback)
58 {
59     tNFA_CHO_API_REG *p_msg;
60 
61     CHO_TRACE_API1 ("NFA_ChoRegister (): enable_server=%d", enable_server);
62 
63     if (  (nfa_cho_cb.state != NFA_CHO_ST_DISABLED)
64         ||(nfa_cho_cb.p_cback != NULL)  )
65     {
66         CHO_TRACE_ERROR0 ("NFA_ChoRegister (): Already registered or callback is not provided");
67         return (NFA_STATUS_FAILED);
68     }
69 
70     if ((p_msg = (tNFA_CHO_API_REG *) GKI_getbuf (sizeof (tNFA_CHO_API_REG))) != NULL)
71     {
72         p_msg->hdr.event = NFA_CHO_API_REG_EVT;
73 
74         p_msg->enable_server = enable_server;
75         p_msg->p_cback       = p_cback;
76 
77         nfa_sys_sendmsg (p_msg);
78 
79         return (NFA_STATUS_OK);
80     }
81 
82     return (NFA_STATUS_FAILED);
83 }
84 
85 /*******************************************************************************
86 **
87 ** Function         NFA_ChoDeregister
88 **
89 ** Description      This function is called to deregister callback function from NFA
90 **                  Connection Handover Application.
91 **
92 **                  If this is the valid deregistration, NFA Connection Handover
93 **                  Application will close the service with "urn:nfc:sn:handover"
94 **                  on LLCP and deregister NDEF type handler if any.
95 **
96 ** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
97 **                  should happen before calling this function
98 **
99 ** Returns          NFA_STATUS_OK if successfully initiated
100 **                  NFA_STATUS_FAILED otherwise
101 **
102 *******************************************************************************/
NFA_ChoDeregister(void)103 tNFA_STATUS NFA_ChoDeregister (void)
104 {
105     tNFA_CHO_API_DEREG *p_msg;
106 
107     CHO_TRACE_API0 ("NFA_ChoDeregister ()");
108 
109     if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
110     {
111         CHO_TRACE_ERROR0 ("NFA_ChoDeregister (): Not registered");
112         return (NFA_STATUS_FAILED);
113     }
114 
115     if ((p_msg = (tNFA_CHO_API_DEREG *) GKI_getbuf (sizeof (tNFA_CHO_API_DEREG))) != NULL)
116     {
117         p_msg->event = NFA_CHO_API_DEREG_EVT;
118 
119         nfa_sys_sendmsg (p_msg);
120 
121         return (NFA_STATUS_OK);
122     }
123 
124     return (NFA_STATUS_FAILED);
125 }
126 
127 /*******************************************************************************
128 **
129 ** Function         NFA_ChoConnect
130 **
131 ** Description      This function is called to create data link connection to
132 **                  Connection Handover server on peer device.
133 **
134 **                  It must be called after receiving NFA_CHO_ACTIVATED_EVT.
135 **                  NFA_CHO_CONNECTED_EVT will be returned if successful.
136 **                  Otherwise, NFA_CHO_DISCONNECTED_EVT will be returned.
137 **
138 **                  If NFA_CHO_ROLE_REQUESTER is returned in NFA_CHO_CONNECTED_EVT,
139 **                  Handover Request Message can be sent.
140 **                  If NFA_CHO_ROLE_SELECTOR is returned in NFA_CHO_CONNECTED_EVT
141 **                  because of collision, application must wait for Handover
142 **                  Request Message.
143 **
144 ** Returns          NFA_STATUS_OK if successfully initiated
145 **                  NFA_STATUS_FAILED otherwise
146 **
147 *******************************************************************************/
NFA_ChoConnect(void)148 tNFA_STATUS NFA_ChoConnect (void)
149 {
150     tNFA_CHO_API_CONNECT *p_msg;
151 
152     CHO_TRACE_API0 ("NFA_ChoConnect ()");
153 
154     if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
155     {
156         CHO_TRACE_ERROR0 ("NFA_ChoConnect (): Not registered");
157         return (NFA_STATUS_FAILED);
158     }
159     else if (nfa_cho_cb.state == NFA_CHO_ST_CONNECTED)
160     {
161         CHO_TRACE_ERROR0 ("NFA_ChoConnect (): Already connected");
162         return (NFA_STATUS_FAILED);
163     }
164 
165     if ((p_msg = (tNFA_CHO_API_CONNECT *) GKI_getbuf (sizeof (tNFA_CHO_API_CONNECT))) != NULL)
166     {
167         p_msg->event = NFA_CHO_API_CONNECT_EVT;
168 
169         nfa_sys_sendmsg (p_msg);
170 
171         return (NFA_STATUS_OK);
172     }
173 
174     return (NFA_STATUS_FAILED);
175 }
176 
177 /*******************************************************************************
178 **
179 ** Function         NFA_ChoDisconnect
180 **
181 ** Description      This function is called to disconnect data link connection with
182 **                  Connection Handover server on peer device.
183 **
184 **                  NFA_CHO_DISCONNECTED_EVT will be returned.
185 **
186 ** Returns          NFA_STATUS_OK if successfully initiated
187 **                  NFA_STATUS_FAILED otherwise
188 **
189 *******************************************************************************/
NFA_ChoDisconnect(void)190 tNFA_STATUS NFA_ChoDisconnect (void)
191 {
192     tNFA_CHO_API_DISCONNECT *p_msg;
193 
194     CHO_TRACE_API0 ("NFA_ChoDisconnect ()");
195 
196     if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
197     {
198         CHO_TRACE_ERROR0 ("NFA_ChoDisconnect (): Not registered");
199         return (NFA_STATUS_FAILED);
200     }
201 
202     if ((p_msg = (tNFA_CHO_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_CHO_API_DISCONNECT))) != NULL)
203     {
204         p_msg->event = NFA_CHO_API_DISCONNECT_EVT;
205 
206         nfa_sys_sendmsg (p_msg);
207 
208         return (NFA_STATUS_OK);
209     }
210 
211     return (NFA_STATUS_FAILED);
212 }
213 
214 /*******************************************************************************
215 **
216 ** Function         NFA_ChoSendHr
217 **
218 ** Description      This function is called to send Handover Request Message with
219 **                  Handover Carrier records or Alternative Carrier records.
220 **
221 **                  It must be called after receiving NFA_CHO_CONNECTED_EVT.
222 **
223 **                  NDEF may include one or more Handover Carrier records or Alternative
224 **                  Carrier records with auxiliary data.
225 **                  The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
226 **                  Payload ID must be unique and Payload ID length must be less than
227 **                  or equal to NFA_CHO_MAX_REF_NAME_LEN.
228 **
229 **                  The alternative carrier information of Handover Select record
230 **                  will be sent to application by NFA_CHO_SELECT_EVT. Application
231 **                  may receive NFA_CHO_REQUEST_EVT because of handover collision.
232 **
233 ** Returns          NFA_STATUS_OK if successfully initiated
234 **                  NFA_STATUS_FAILED otherwise
235 **
236 *******************************************************************************/
NFA_ChoSendHr(UINT8 num_ac_info,tNFA_CHO_AC_INFO * p_ac_info,UINT8 * p_ndef,UINT32 ndef_len)237 tNFA_STATUS NFA_ChoSendHr (UINT8             num_ac_info,
238                            tNFA_CHO_AC_INFO *p_ac_info,
239                            UINT8            *p_ndef,
240                            UINT32            ndef_len)
241 {
242     tNFA_CHO_API_SEND_HR *p_msg;
243     UINT16               msg_size;
244     UINT8                *p_ndef_buf;
245 
246     CHO_TRACE_API2 ("NFA_ChoSendHr (): num_ac_info=%d, ndef_len=%d", num_ac_info, ndef_len);
247 
248     if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED)
249     {
250         CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Not connected");
251         return (NFA_STATUS_FAILED);
252     }
253 
254     if (num_ac_info > NFA_CHO_MAX_AC_INFO)
255     {
256         CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Too many AC information");
257         return (NFA_STATUS_FAILED);
258     }
259 
260     p_ndef_buf = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
261 
262     if (!p_ndef_buf)
263     {
264         CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Failed to allocate buffer for NDEF");
265         return NFA_STATUS_FAILED;
266     }
267     else if (ndef_len > LLCP_POOL_BUF_SIZE)
268     {
269         CHO_TRACE_ERROR1 ("NFA_ChoSendHr (): Failed to allocate buffer for %d bytes", ndef_len);
270         GKI_freebuf (p_ndef_buf);
271         return NFA_STATUS_FAILED;
272     }
273 
274     msg_size = sizeof (tNFA_CHO_API_SEND_HR) + num_ac_info * sizeof (tNFA_CHO_AC_INFO);
275 
276     if ((p_msg = (tNFA_CHO_API_SEND_HR *) GKI_getbuf (msg_size)) != NULL)
277     {
278         p_msg->hdr.event = NFA_CHO_API_SEND_HR_EVT;
279 
280         memcpy (p_ndef_buf, p_ndef, ndef_len);
281         p_msg->p_ndef        = p_ndef_buf;
282         p_msg->max_ndef_size = LLCP_POOL_BUF_SIZE;
283         p_msg->cur_ndef_size = ndef_len;
284 
285         p_msg->num_ac_info   = num_ac_info;
286         p_msg->p_ac_info     = (tNFA_CHO_AC_INFO *) (p_msg + 1);
287         memcpy (p_msg->p_ac_info, p_ac_info, num_ac_info * sizeof (tNFA_CHO_AC_INFO));
288 
289         nfa_sys_sendmsg (p_msg);
290         return (NFA_STATUS_OK);
291     }
292     else
293     {
294         GKI_freebuf (p_ndef_buf);
295         return (NFA_STATUS_FAILED);
296     }
297 }
298 
299 /*******************************************************************************
300 **
301 ** Function         NFA_ChoSendHs
302 **
303 ** Description      This function is called to send Handover Select message with
304 **                  Alternative Carrier records as response to Handover Request
305 **                  message.
306 **
307 **                  NDEF may include one or more Alternative Carrier records with
308 **                  auxiliary data.
309 **                  The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
310 **                  Payload ID must be unique and Payload ID length must be less than
311 **                  or equal to NFA_CHO_MAX_REF_NAME_LEN.
312 **
313 ** Returns          NFA_STATUS_OK if successfully initiated
314 **                  NFA_STATUS_FAILED otherwise
315 **
316 *******************************************************************************/
NFA_ChoSendHs(UINT8 num_ac_info,tNFA_CHO_AC_INFO * p_ac_info,UINT8 * p_ndef,UINT32 ndef_len)317 tNFA_STATUS NFA_ChoSendHs (UINT8             num_ac_info,
318                            tNFA_CHO_AC_INFO *p_ac_info,
319                            UINT8            *p_ndef,
320                            UINT32            ndef_len)
321 {
322     tNFA_CHO_API_SEND_HS *p_msg;
323     UINT16               msg_size;
324     UINT8                *p_ndef_buf;
325 
326     CHO_TRACE_API2 ("NFA_ChoSendHs(): num_ac_info=%d, ndef_len=%d",
327                     num_ac_info, ndef_len);
328 
329     if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED)
330     {
331         CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Not connected");
332         return (NFA_STATUS_FAILED);
333     }
334 
335     if (num_ac_info > NFA_CHO_MAX_AC_INFO)
336     {
337         CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Too many AC information");
338         return (NFA_STATUS_FAILED);
339     }
340 
341     p_ndef_buf = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
342     if (!p_ndef_buf)
343     {
344         CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Failed to allocate buffer for NDEF");
345         return NFA_STATUS_FAILED;
346     }
347     else if (ndef_len > LLCP_POOL_BUF_SIZE)
348     {
349         CHO_TRACE_ERROR1 ("NFA_ChoSendHs (): Failed to allocate buffer for %d bytes", ndef_len);
350         GKI_freebuf (p_ndef_buf);
351         return NFA_STATUS_FAILED;
352     }
353 
354     msg_size = sizeof (tNFA_CHO_API_SEND_HS) + num_ac_info * sizeof (tNFA_CHO_AC_INFO);
355 
356     if ((p_msg = (tNFA_CHO_API_SEND_HS *) GKI_getbuf (msg_size)) != NULL)
357     {
358         p_msg->hdr.event = NFA_CHO_API_SEND_HS_EVT;
359 
360         memcpy (p_ndef_buf, p_ndef, ndef_len);
361         p_msg->p_ndef        = p_ndef_buf;
362         p_msg->max_ndef_size = LLCP_POOL_BUF_SIZE;
363         p_msg->cur_ndef_size = ndef_len;
364 
365         p_msg->num_ac_info   = num_ac_info;
366         p_msg->p_ac_info     = (tNFA_CHO_AC_INFO *) (p_msg + 1);
367         memcpy (p_msg->p_ac_info, p_ac_info, num_ac_info * sizeof (tNFA_CHO_AC_INFO));
368 
369         nfa_sys_sendmsg (p_msg);
370         return (NFA_STATUS_OK);
371     }
372     else
373     {
374         GKI_freebuf (p_ndef_buf);
375         return (NFA_STATUS_FAILED);
376     }
377 }
378 
379 /*******************************************************************************
380 **
381 ** Function         NFA_ChoSendSelectError
382 **
383 ** Description      This function is called to send Error record to indicate failure
384 **                  to process the most recently received Handover Request message.
385 **
386 **                  error_reason : NFA_CHO_ERROR_TEMP_MEM
387 **                                 NFA_CHO_ERROR_PERM_MEM
388 **                                 NFA_CHO_ERROR_CARRIER
389 **
390 ** Returns          NFA_STATUS_OK if successfully initiated
391 **                  NFA_STATUS_FAILED otherwise
392 **
393 *******************************************************************************/
NFA_ChoSendSelectError(UINT8 error_reason,UINT32 error_data)394 tNFA_STATUS NFA_ChoSendSelectError (UINT8  error_reason,
395                                     UINT32 error_data)
396 {
397     tNFA_CHO_API_SEL_ERR *p_msg;
398 
399     CHO_TRACE_API2 ("NFA_ChoSendSelectError (): error_reason=0x%x, error_data=0x%x",
400                      error_reason, error_data);
401 
402     if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
403     {
404         CHO_TRACE_ERROR0 ("NFA_ChoSendSelectError (): Not registered");
405         return (NFA_STATUS_FAILED);
406     }
407 
408     if ((p_msg = (tNFA_CHO_API_SEL_ERR *) GKI_getbuf (sizeof (tNFA_CHO_API_SEL_ERR))) != NULL)
409     {
410         p_msg->hdr.event = NFA_CHO_API_SEL_ERR_EVT;
411 
412         p_msg->error_reason = error_reason;
413         p_msg->error_data   = error_data;
414 
415         nfa_sys_sendmsg (p_msg);
416 
417         return (NFA_STATUS_OK);
418     }
419 
420     return (NFA_STATUS_FAILED);
421 }
422 
423 /*******************************************************************************
424 **
425 ** Function         NFA_ChoSetTraceLevel
426 **
427 ** Description      This function sets the trace level for CHO.  If called with
428 **                  a value of 0xFF, it simply returns the current trace level.
429 **
430 ** Returns          The new or current trace level
431 **
432 *******************************************************************************/
NFA_ChoSetTraceLevel(UINT8 new_level)433 UINT8 NFA_ChoSetTraceLevel (UINT8 new_level)
434 {
435     if (new_level != 0xFF)
436         nfa_cho_cb.trace_level = new_level;
437 
438     return (nfa_cho_cb.trace_level);
439 }
440 
441 #if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
442 /*******************************************************************************
443 **
444 ** Function         NFA_ChoSetTestParam
445 **
446 ** Description      This function is called to set test parameters.
447 **
448 *******************************************************************************/
NFA_ChoSetTestParam(UINT8 test_enable,UINT8 test_version,UINT16 test_random_number)449 void NFA_ChoSetTestParam (UINT8        test_enable,
450                           UINT8        test_version,
451                           UINT16       test_random_number)
452 {
453     nfa_cho_cb.test_enabled         = test_enable;
454     nfa_cho_cb.test_version         = test_version;
455     nfa_cho_cb.test_random_number   = test_random_number;
456 }
457 #endif
458