• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012-2014 NXP Semiconductors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <phNxpNciHal_NfcDepSWPrio.h>
18 #include <phNxpLog.h>
19 #include <phNxpNciHal.h>
20 
21 #define CUSTOM_POLL_TIMEOUT 160    /* Timeout value to wait for NFC-DEP detection.*/
22 #define CLEAN_UP_TIMEOUT 250
23 #define MAX_WRITE_RETRY 5
24 
25 /******************* Global variables *****************************************/
26 extern phNxpNciHal_Control_t nxpncihal_ctrl;
27 extern NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd);
28 static uint8_t cmd_stop_rf_discovery[] = { 0x21, 0x06, 0x01, 0x00 }; /* IDLE */
29 static uint8_t cmd_resume_rf_discovery[] = { 0x21, 0x06, 0x01, 0x03 }; /* RF_DISCOVER */
30 
31 /*RF_DISCOVER_SELECT_CMD*/
32 static uint8_t cmd_select_rf_discovery[] = {0x21,0x04,0x03,0x01,0x04,0x02 };
33 
34 static uint8_t cmd_poll[64];
35 static uint8_t cmd_poll_len = 0;
36 int discover_type = 0xFF;
37 uint32_t cleanup_timer;
38 
39 /*PRIO LOGIC related dead functions undefined*/
40 #ifdef P2P_PRIO_LOGIC_HAL_IMP
41 
42 static int iso_dep_detected = 0x00;
43 static int poll_timer_fired = 0x00;
44 static uint8_t bIgnorep2plogic = 0;
45 static uint8_t *p_iso_ntf_buff = NULL; /* buffer to store second notification */
46 static uint8_t bIgnoreIsoDep = 0;
47 static uint32_t custom_poll_timer;
48 
49 /************** NFC-DEP SW PRIO functions ***************************************/
50 
51 static NFCSTATUS phNxpNciHal_start_polling_loop(void);
52 static NFCSTATUS phNxpNciHal_stop_polling_loop(void);
53 static NFCSTATUS phNxpNciHal_resume_polling_loop(void);
54 static void phNxpNciHal_NfcDep_store_ntf(uint8_t *p_cmd_data, uint16_t cmd_len);
55 
56 
57 /*******************************************************************************
58 **
59 ** Function         cleanup_timer_handler
60 **
61 ** Description      Callback function for cleanup timer.
62 **
63 ** Returns          None
64 **
65 *******************************************************************************/
cleanup_timer_handler(uint32_t timerId,void * pContext)66 static void cleanup_timer_handler(uint32_t timerId, void *pContext)
67 {
68     NXPLOG_NCIHAL_D(">> cleanup_timer_handler.");
69 
70     NXPLOG_NCIHAL_D(">> cleanup_timer_handler. ISO_DEP not detected second time.");
71 
72     phOsalNfc_Timer_Delete(cleanup_timer);
73     cleanup_timer=0;
74     iso_dep_detected = 0x00;
75     EnableP2P_PrioLogic = FALSE;
76     return;
77 }
78 
79 /*******************************************************************************
80 **
81 ** Function         custom_poll_timer_handler
82 **
83 ** Description      Callback function for custom poll timer.
84 **
85 ** Returns          None
86 **
87 *******************************************************************************/
custom_poll_timer_handler(uint32_t timerId,void * pContext)88 static void custom_poll_timer_handler(uint32_t timerId, void *pContext)
89 {
90     NXPLOG_NCIHAL_D(">> custom_poll_timer_handler.");
91 
92     NXPLOG_NCIHAL_D(">> custom_poll_timer_handler. NFC_DEP not detected. so giving early chance to ISO_DEP.");
93 
94     phOsalNfc_Timer_Delete(custom_poll_timer);
95 
96     if (iso_dep_detected == 0x01)
97     {
98         poll_timer_fired = 0x01;
99 
100         /*
101          * Restart polling loop.
102          * When the polling loop is stopped, polling will be restarted.
103          */
104         NXPLOG_NCIHAL_D(">> custom_poll_timer_handler - restart polling loop.");
105 
106         phNxpNciHal_stop_polling_loop();
107     }
108     else
109     {
110         NXPLOG_NCIHAL_E(">> custom_poll_timer_handler - invalid flag state (iso_dep_detected)");
111     }
112 
113     return;
114 }
115 /*******************************************************************************
116 **
117 ** Function         phNxpNciHal_stop_polling_loop
118 **
119 ** Description      Sends stop polling cmd to NFCC
120 **
121 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
122 **
123 *******************************************************************************/
phNxpNciHal_stop_polling_loop()124 static NFCSTATUS phNxpNciHal_stop_polling_loop()
125 {
126     NFCSTATUS status = NFCSTATUS_SUCCESS;
127     phNxpNciHal_Sem_t cb_data;
128     pthread_t pthread;
129     discover_type = STOP_POLLING;
130 
131     pthread_attr_t attr;
132     pthread_attr_init (&attr);
133     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
134     if (pthread_create (&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
135     {
136         NXPLOG_NCIHAL_E("fail to create pthread");
137     }
138     pthread_attr_destroy (&attr);
139     return status;
140 }
141 
142 /*******************************************************************************
143 **
144 ** Function         phNxpNciHal_resume_polling_loop
145 **
146 ** Description      Sends resume polling cmd to NFCC
147 **
148 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
149 **
150 *******************************************************************************/
phNxpNciHal_resume_polling_loop()151 static NFCSTATUS phNxpNciHal_resume_polling_loop()
152 {
153     NFCSTATUS status = NFCSTATUS_SUCCESS;
154     phNxpNciHal_Sem_t cb_data;
155     pthread_t pthread;
156     discover_type = RESUME_POLLING;
157 
158     pthread_attr_t attr;
159     pthread_attr_init (&attr);
160     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
161     if (pthread_create (&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
162     {
163         NXPLOG_NCIHAL_E("fail to create pthread");
164     }
165     pthread_attr_destroy (&attr);
166     return status;
167 }
168 
169 /*******************************************************************************
170 **
171 ** Function         phNxpNciHal_start_polling_loop
172 **
173 ** Description      Sends start polling cmd to NFCC
174 **
175 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
176 **
177 *******************************************************************************/
phNxpNciHal_start_polling_loop()178 NFCSTATUS phNxpNciHal_start_polling_loop()
179 {
180     NFCSTATUS status = NFCSTATUS_FAILED;
181     phNxpNciHal_Sem_t cb_data;
182     pthread_t pthread;
183     discover_type = START_POLLING;
184 
185     pthread_attr_t attr;
186     pthread_attr_init (&attr);
187     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
188     if (pthread_create (&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
189     {
190         NXPLOG_NCIHAL_E("fail to create pthread");
191     }
192     pthread_attr_destroy (&attr);
193     return status;
194 }
195 
196 /*******************************************************************************
197 **
198 ** Function         phNxpNciHal_NfcDep_rsp_ext
199 **
200 ** Description      Implements algorithm for NFC-DEP protocol priority over
201 **                  ISO-DEP protocol.
202 **                  Following the algorithm:
203 **                  IF ISO-DEP detected first time,set the ISO-DEP detected flag
204 **                  and resume polling loop with 60ms timeout value.
205 **                      a) if than NFC-DEP detected than send the response to
206 **                       libnfc-nci stack and stop the timer.
207 **                      b) if NFC-DEP not detected with in 60ms, than restart the
208 **                          polling loop to give early chance to ISO-DEP with a
209 **                          cleanup timer.
210 **                      c) if ISO-DEP detected second time send the response to
211 **                          libnfc-nci stack and stop the cleanup timer.
212 **                      d) if ISO-DEP not detected with in cleanup timeout, than
213 **                          clear the ISO-DEP detection flag.
214 **
215 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
216 **
217 *******************************************************************************/
phNxpNciHal_NfcDep_rsp_ext(uint8_t * p_ntf,uint16_t * p_len)218 NFCSTATUS phNxpNciHal_NfcDep_rsp_ext(uint8_t *p_ntf, uint16_t *p_len)
219 {
220     NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
221 
222     NXPLOG_NCIHAL_D(">> p_ntf[0]=%02x , p_ntf[1]=%02x",p_ntf[0],p_ntf[1]);
223 
224     if(p_ntf[0] == 0x41 && p_ntf[1] == 0x04)
225     {
226         //Tag selected, Disable P2P Prio logic.
227         bIgnoreIsoDep = 1;
228         NXPLOG_NCIHAL_D(">> Tag selected, Disable P2P Prio logic.");
229 
230     }
231     else if( ((p_ntf[0] == 0x61 && p_ntf[1] == 0x06) ||
232             (p_ntf[0] == 0x41 && p_ntf[1] == 0x06) ) && bIgnoreIsoDep == 1
233             )
234     {
235         //Tag deselected, enable P2P Prio logic.
236         bIgnoreIsoDep = 0x00;
237         NXPLOG_NCIHAL_D(">> Tag deselected, enable P2P Prio logic.");
238 
239     }
240     if (bIgnoreIsoDep == 0x00 &&
241             p_ntf[0] == 0x61 &&
242             p_ntf[1] == 0x05 && *p_len > 5)
243     {
244         if (p_ntf[5] == 0x04 && p_ntf[6] < 0x80)
245         {
246             NXPLOG_NCIHAL_D(">> ISO DEP detected.");
247 
248             if (iso_dep_detected == 0x00)
249             {
250                 NXPLOG_NCIHAL_D(
251                         ">> ISO DEP detected first time. Resume polling loop");
252 
253                 iso_dep_detected = 0x01;
254                 status = phNxpNciHal_resume_polling_loop();
255 
256                 custom_poll_timer = phOsalNfc_Timer_Create();
257                 NXPLOG_NCIHAL_D("custom poll timer started - %d", custom_poll_timer);
258 
259                 status = phOsalNfc_Timer_Start(custom_poll_timer,
260                         CUSTOM_POLL_TIMEOUT,
261                         &custom_poll_timer_handler,
262                         NULL);
263 
264                 if (NFCSTATUS_SUCCESS == status)
265                 {
266                     NXPLOG_NCIHAL_D("custom poll timer started");
267                 }
268                 else
269                 {
270                     NXPLOG_NCIHAL_E("custom poll timer not started!!!");
271                     status  = NFCSTATUS_FAILED;
272                 }
273 
274                 status = NFCSTATUS_FAILED;
275             }
276             else
277             {
278                 NXPLOG_NCIHAL_D(">> ISO DEP detected second time.");
279                 /* Store notification */
280                 phNxpNciHal_NfcDep_store_ntf(p_ntf, *p_len);
281 
282                 /* Stop Cleanup_timer */
283                 phOsalNfc_Timer_Stop(cleanup_timer);
284                 phOsalNfc_Timer_Delete(cleanup_timer);
285                 cleanup_timer=0;
286                 EnableP2P_PrioLogic = FALSE;
287                 iso_dep_detected = 0;
288                 status = NFCSTATUS_SUCCESS;
289             }
290         }
291         else if (p_ntf[5] == 0x05)
292         {
293             NXPLOG_NCIHAL_D(">> NFC-DEP Detected - stopping the custom poll timer");
294 
295             phOsalNfc_Timer_Stop(custom_poll_timer);
296             phOsalNfc_Timer_Delete(custom_poll_timer);
297             EnableP2P_PrioLogic = FALSE;
298             iso_dep_detected = 0;
299             status = NFCSTATUS_SUCCESS;
300         }
301         else
302         {
303             NXPLOG_NCIHAL_D(">>  detected other technology- stopping the custom poll timer");
304             phOsalNfc_Timer_Stop(custom_poll_timer);
305             phOsalNfc_Timer_Delete(custom_poll_timer);
306             EnableP2P_PrioLogic = FALSE;
307             iso_dep_detected = 0;
308             status = NFCSTATUS_INVALID_PARAMETER;
309         }
310     }
311     else if( bIgnoreIsoDep == 0x00 &&
312             ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || (p_ntf[0] == 0x61
313             && p_ntf[1] == 0x06))
314             )
315     {
316         NXPLOG_NCIHAL_D(">> RF disabled");
317         if (poll_timer_fired == 0x01)
318         {
319             poll_timer_fired = 0x00;
320 
321             NXPLOG_NCIHAL_D(">>restarting polling loop.");
322 
323             /* start polling loop */
324             phNxpNciHal_start_polling_loop();
325             EnableP2P_PrioLogic = FALSE;
326             NXPLOG_NCIHAL_D (">> NFC DEP NOT  detected - custom poll timer expired - RF disabled");
327 
328             cleanup_timer = phOsalNfc_Timer_Create();
329 
330             /* Start cleanup_timer */
331             NFCSTATUS status = phOsalNfc_Timer_Start(cleanup_timer,
332                     CLEAN_UP_TIMEOUT,
333                     &cleanup_timer_handler,
334                     NULL);
335 
336             if (NFCSTATUS_SUCCESS == status)
337             {
338                 NXPLOG_NCIHAL_D("cleanup timer started");
339             }
340             else
341             {
342                 NXPLOG_NCIHAL_E("cleanup timer not started!!!");
343                 status  = NFCSTATUS_FAILED;
344             }
345 
346             status = NFCSTATUS_FAILED;
347         }
348         else
349         {
350             status = NFCSTATUS_SUCCESS;
351         }
352     }
353     if (bIgnoreIsoDep == 0x00 &&
354             iso_dep_detected == 1)
355     {
356         if ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || (p_ntf[0] == 0x61
357                 && p_ntf[1] == 0x06))
358         {
359             NXPLOG_NCIHAL_D(">>iso_dep_detected Disconnect related notification");
360             status = NFCSTATUS_FAILED;
361         }
362         else
363         {
364             NXPLOG_NCIHAL_W("Never come here");
365         }
366     }
367 
368     return status;
369 }
370 /*******************************************************************************
371 **
372 ** Function         phNxpNciHal_NfcDep_store_ntf
373 **
374 ** Description      Stores the iso dep notification locally.
375 **
376 ** Returns          None
377 **
378 *******************************************************************************/
phNxpNciHal_NfcDep_store_ntf(uint8_t * p_cmd_data,uint16_t cmd_len)379 static void phNxpNciHal_NfcDep_store_ntf(uint8_t *p_cmd_data, uint16_t cmd_len)
380 {
381     p_iso_ntf_buff = NULL;
382 
383     p_iso_ntf_buff = malloc(sizeof (uint8_t) * cmd_len);
384     if (p_iso_ntf_buff == NULL)
385     {
386         NXPLOG_NCIHAL_E("Error allocating memory (p_iso_ntf_buff)");
387         return;
388     }
389     memcpy(p_iso_ntf_buff, p_cmd_data, cmd_len);
390     bIgnorep2plogic = 1;
391 }
392 
393 /*******************************************************************************
394 **
395 ** Function         phNxpNciHal_NfcDep_comapre_ntf
396 **
397 ** Description      Compare the notification with previous iso dep notification.
398 **
399 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
400 **
401 *******************************************************************************/
phNxpNciHal_NfcDep_comapre_ntf(uint8_t * p_cmd_data,uint16_t cmd_len)402 NFCSTATUS phNxpNciHal_NfcDep_comapre_ntf(uint8_t *p_cmd_data, uint16_t cmd_len)
403 {
404    NFCSTATUS status = NFCSTATUS_FAILED;
405    int32_t ret_val = -1;
406 
407    if (bIgnorep2plogic == 1)
408    {
409         ret_val = memcmp(p_cmd_data,p_iso_ntf_buff, cmd_len);
410         if(ret_val != 0)
411         {
412             NXPLOG_NCIHAL_E("Third notification is not equal to last");
413         }
414         else
415         {
416             NXPLOG_NCIHAL_E("Third notification is equal to last (disable p2p logic)");
417             status = NFCSTATUS_SUCCESS;
418         }
419         bIgnorep2plogic = 0;
420     }
421     if (p_iso_ntf_buff != NULL)
422     {
423         free(p_iso_ntf_buff);
424         p_iso_ntf_buff = NULL;
425     }
426 
427     return status;
428 }
429 
430 
phNxpNciHal_clean_P2P_Prio()431 extern NFCSTATUS phNxpNciHal_clean_P2P_Prio()
432 {
433     NFCSTATUS status = NFCSTATUS_SUCCESS;
434 
435     iso_dep_detected = 0x00;
436     EnableP2P_PrioLogic = FALSE;
437     poll_timer_fired = 0x00;
438     bIgnorep2plogic = 0x00;
439     bIgnoreIsoDep = 0x00;
440 
441     status = phOsalNfc_Timer_Stop(cleanup_timer);
442     status |= phOsalNfc_Timer_Delete(cleanup_timer);
443 
444     status |= phOsalNfc_Timer_Stop(custom_poll_timer);
445     status |= phOsalNfc_Timer_Delete(custom_poll_timer);
446     cleanup_timer=0;
447     return status;
448 }
449 
450 #endif
451 /*******************************************************************************
452 **
453 ** Function         hal_write_cb
454 **
455 ** Description      Callback function for hal write.
456 **
457 ** Returns          None
458 **
459 *******************************************************************************/
hal_write_cb(void * pContext,phTmlNfc_TransactInfo_t * pInfo)460 static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
461 {
462     phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
463 
464     if (pInfo->wStatus == NFCSTATUS_SUCCESS)
465     {
466         NXPLOG_NCIHAL_D("hal_write_cb: write successful status = 0x%x", pInfo->wStatus);
467     }
468     else
469     {
470         NXPLOG_NCIHAL_E("hal_write_cb: write error status = 0x%x", pInfo->wStatus);
471     }
472 
473     p_cb_data->status = pInfo->wStatus;
474 
475     SEM_POST(p_cb_data);
476     return;
477 }
478 
479 /*******************************************************************************
480  **
481  ** Function         tmp_thread
482  **
483  ** Description      Thread to execute custom poll commands .
484  **
485  ** Returns          None
486  **
487  *******************************************************************************/
tmp_thread(void * tmp)488 void *tmp_thread(void *tmp)
489 {
490     NFCSTATUS status = NFCSTATUS_SUCCESS;
491     uint16_t data_len;
492     NXPLOG_NCIHAL_E("tmp_thread: enter type=0x0%x",  *((int*)tmp));
493     usleep(10*1000);
494 
495     switch( *((int*)tmp) )
496     {
497     case START_POLLING:
498     {
499         CONCURRENCY_LOCK();
500         data_len = phNxpNciHal_write_unlocked(cmd_poll_len, cmd_poll);
501         CONCURRENCY_UNLOCK();
502 
503         if(data_len != cmd_poll_len)
504         {
505             NXPLOG_NCIHAL_E("phNxpNciHal_start_polling_loop: data len mismatch");
506             status = NFCSTATUS_FAILED;
507         }
508     }
509     break;
510 
511     case RESUME_POLLING:
512     {
513         CONCURRENCY_LOCK();
514         data_len = phNxpNciHal_write_unlocked(sizeof(cmd_resume_rf_discovery),
515                 cmd_resume_rf_discovery);
516         CONCURRENCY_UNLOCK();
517 
518         if(data_len != sizeof(cmd_resume_rf_discovery))
519         {
520             NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch");
521             status = NFCSTATUS_FAILED;
522         }
523     }
524     break;
525 
526     case STOP_POLLING:
527     {
528         CONCURRENCY_LOCK();
529         data_len = phNxpNciHal_write_unlocked(sizeof(cmd_stop_rf_discovery),
530                 cmd_stop_rf_discovery);
531         CONCURRENCY_UNLOCK();
532 
533         if(data_len != sizeof(cmd_stop_rf_discovery))
534         {
535             NXPLOG_NCIHAL_E("phNxpNciHal_stop_polling_loop: data len mismatch");
536             status = NFCSTATUS_FAILED;
537         }
538     }
539     break;
540 
541     case DISCOVER_SELECT:
542     {
543         CONCURRENCY_LOCK();
544         data_len = phNxpNciHal_write_unlocked(sizeof(cmd_select_rf_discovery),
545                 cmd_select_rf_discovery);
546         CONCURRENCY_UNLOCK();
547 
548         if(data_len != sizeof(cmd_resume_rf_discovery))
549         {
550             NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch");
551             status = NFCSTATUS_FAILED;
552         }
553     }
554     break;
555 
556     default:
557         NXPLOG_NCIHAL_E("No Matching case");
558         status = NFCSTATUS_FAILED;
559         break;
560     }
561 
562     NXPLOG_NCIHAL_E("tmp_thread: exit");
563     return NULL;
564 }
565 /*******************************************************************************
566  **
567  ** Function         phNxpNciHal_select_RF_Discovery
568  **
569  ** Description     Sends RF_DISCOVER_SELECT_CMD
570  ** Parameters    RfID ,  RfProtocolType
571  ** Returns          NFCSTATUS_PENDING if success
572  **
573  *******************************************************************************/
phNxpNciHal_select_RF_Discovery(unsigned int RfID,unsigned int RfProtocolType)574 NFCSTATUS phNxpNciHal_select_RF_Discovery(unsigned int RfID,unsigned int RfProtocolType)
575 {
576     NFCSTATUS status = NFCSTATUS_SUCCESS;
577     phNxpNciHal_Sem_t cb_data;
578     pthread_t pthread;
579     discover_type = DISCOVER_SELECT;
580     cmd_select_rf_discovery[3]=RfID;
581     cmd_select_rf_discovery[4]=RfProtocolType;
582 
583     pthread_attr_t attr;
584     pthread_attr_init (&attr);
585     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
586     if (pthread_create (&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
587     {
588         NXPLOG_NCIHAL_E("fail to create pthread");
589     }
590     pthread_attr_destroy (&attr);
591     return status;
592 }
593 /*******************************************************************************
594 **
595 ** Function         phNxpNciHal_NfcDep_cmd_ext
596 **
597 ** Description      Stores the polling loop configuration locally.
598 **
599 ** Returns          None
600 **
601 *******************************************************************************/
phNxpNciHal_NfcDep_cmd_ext(uint8_t * p_cmd_data,uint16_t * cmd_len)602 void phNxpNciHal_NfcDep_cmd_ext(uint8_t *p_cmd_data, uint16_t *cmd_len)
603 {
604     if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03)
605     {
606         if (*cmd_len == 6 && p_cmd_data[3] == 0x01 && p_cmd_data[4] == 0x02
607                 && p_cmd_data[5] == 0x01)
608         {
609             /* DO NOTHING */
610         }
611         else
612         {
613             /* Store the polling loop configuration */
614             cmd_poll_len = *cmd_len;
615             memset(&cmd_poll, 0, cmd_poll_len);
616             memcpy(&cmd_poll, p_cmd_data, cmd_poll_len);
617         }
618     }
619 
620     return;
621 }
622