• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-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 "OverrideLog.h"
20 #include <string.h>
21 #include "gki.h"
22 #include "nfc_hal_api.h"
23 #include "nfc_hal_int.h"
24 #include "userial.h"
25 #include "nfc_target.h"
26 
27 #include <pthread.h>
28 #include <termios.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <gki_int.h>
34 #include "hcidefs.h"
35 #include <poll.h>
36 #include "upio.h"
37 #include "bcm2079x.h"
38 #include "config.h"
39 
40 #define HCISU_EVT                           EVENT_MASK(APPL_EVT_0)
41 #define MAX_ERROR                           10
42 #define default_transport                   "/dev/bcm2079x"
43 
44 #define NUM_RESET_ATTEMPTS                  5
45 #define NFC_WAKE_ASSERTED_ON_POR            UPIO_OFF
46 
47 #ifndef BTE_APPL_MAX_USERIAL_DEV_NAME
48 #define BTE_APPL_MAX_USERIAL_DEV_NAME           (256)
49 #endif
50 extern UINT8 appl_trace_level;
51 
52 
53 /* Mapping of USERIAL_PORT_x to linux */
54 extern UINT32 ScrProtocolTraceFlag;
55 static tUPIO_STATE current_nfc_wake_state = UPIO_OFF;
56 int uart_port  = 0;
57 int isLowSpeedTransport = 0;
58 int nfc_wake_delay = 0;
59 int nfc_write_delay = 0;
60 int gPowerOnDelay = 300;
61 static int gPrePowerOffDelay = 0;    // default value
62 static int gPostPowerOffDelay = 0;     // default value
63 static pthread_mutex_t close_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
64 
65 char userial_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
66 char power_control_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
67 tSNOOZE_MODE_CONFIG gSnoozeModeCfg = {
68     NFC_HAL_LP_SNOOZE_MODE_SPI_I2C,     /* Sleep Mode (0=Disabled 1=UART 8=SPI/I2C) */
69     NFC_HAL_LP_IDLE_THRESHOLD_HOST,     /* Idle Threshold Host */
70     NFC_HAL_LP_IDLE_THRESHOLD_HC,       /* Idle Threshold HC */
71     NFC_HAL_LP_ACTIVE_LOW,              /* NFC Wake active mode (0=ActiveLow 1=ActiveHigh) */
72     NFC_HAL_LP_ACTIVE_HIGH              /* Host Wake active mode (0=ActiveLow 1=ActiveHigh) */
73 };
74 
75 UINT8 bcmi2cnfc_client_addr = 0;
76 UINT8 bcmi2cnfc_read_multi_packets = 0;
77 
78 #define USERIAL_Debug_verbose     ((ScrProtocolTraceFlag & 0x80000000) == 0x80000000)
79 
80 #include <sys/socket.h>
81 
82 #define LOG_TAG "USERIAL_LINUX"
83 
84 static UINT8 spi_negotiation[10] = { 0xF0, /* CMD */
85                                     0x00, /* SPI PARM Negotiation */
86                                     0x01, /* SPI Version */
87                                     0x00, /* SPI Mode:0, SPI_INT active low */
88                                     0x00, /* 8Bit, MSB first, Little Endian byte order */
89                                     0x00, /* Reserved */
90                                     0xFF, /* Sleep timeout Lower Byte */
91                                     0xFF, /* Sleep timeout Upper Byte */
92                                     0x00, /* Reserved */
93                                     0x00 /* Reserved */
94 };
95 static UINT8 spi_nego_res[20];
96 
97 /* Modes used when powering off (independent
98    of what the stack/jni has configured */
99 #define POM_NORMAL          (0)     /* Normal */
100 #define POM_CE3SO           (1)     /* Go to CE3-SO */
101 #define POM_NFC_OFF         (2)     /* Set NFC Off bit */
102 
103 static int gPowerOffMode = POM_NORMAL;
104 
105 static UINT8 ce3_so_cmd[10] = { 0x10,
106                                 0x2F, /* CMD */
107                                 0x08,
108                                 0x06, /* size of cmd */
109                                 0x02, /* CE3 power-level */
110                                 0xF3, /* LpmUicc */
111                                 0x01, /* LpmListenTech */
112                                 0x01, /* Param */
113                                 0x00, /* Forced */
114                                 0x00  /* Debug */
115 };
116 
117 static UINT8 set_nfc_off_cmd[5] = {
118                                 0x10,
119                                 0x2F, /* CMD */
120                                 0x38,
121                                 0x01, /* size of cmd */
122                                 0x01  /* setNfcOff */
123 };
124 
125 #include <ctype.h>
126 
127 #define USING_BRCM_USB TRUE
128 
129 /* use tc interface to change baudrate instead of close/open sequence which can fail on some platforms
130  * due to tx line movement when opeing/closing the UART. the 43xx do not like this. */
131 #ifndef USERIAL_USE_TCIO_BAUD_CHANGE
132 #define USERIAL_USE_TCIO_BAUD_CHANGE FALSE
133 #endif
134 
135 #ifndef USERIAL_USE_IO_BT_WAKE
136 #define USERIAL_USE_IO_BT_WAKE FALSE
137 #endif
138 
139 /* this are the ioctl values used for bt_wake ioctl via UART driver. you may need to redefine at for
140  * you platform! Logically they need to be unique and not colide with existing uart ioctl's.
141  */
142 #ifndef USERIAL_IO_BT_WAKE_ASSERT
143 #define USERIAL_IO_BT_WAKE_ASSERT   0x8003
144 #endif
145 #ifndef USERIAL_IO_BT_WAKE_DEASSERT
146 #define USERIAL_IO_BT_WAKE_DEASSERT 0x8004
147 #endif
148 #ifndef USERIAL_IO_BT_WAKE_GET_ST
149 #define USERIAL_IO_BT_WAKE_GET_ST   0x8005
150 #endif
151 
152 /* the read limit in this current implementation depends on the GKI_BUF3_SIZE
153  * It would be better to use some ring buffer from the USERIAL_Read() is reading
154  * instead of putting it into GKI buffers.
155  */
156 #define READ_LIMIT (USERIAL_POOL_BUF_SIZE-BT_HDR_SIZE)
157 /*
158  * minimum buffer size requirement to read a full sized packet from NFCC = 255 + 4 byte header
159  */
160 #define MIN_BUFSIZE 259
161 #define     POLL_TIMEOUT    1000
162 /* priority of the reader thread */
163 #define USERIAL_READ_TRHEAD_PRIO 90
164 /* time (ms) to wait before trying to allocate again a GKI buffer */
165 #define NO_GKI_BUFFER_RECOVER_TIME 100
166 #define MAX_SERIAL_PORT (USERIAL_PORT_15 + 1)
167 
168 extern void dumpbin(const char* data, int size);
169 extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
170 
171 static pthread_t      worker_thread1 = 0;
172 
173 typedef struct  {
174     volatile unsigned long bt_wake_state;
175     int             sock;
176     tUSERIAL_CBACK      *ser_cb;
177     UINT16      baud;
178     UINT8       data_bits;
179     UINT16      parity;
180     UINT8       stop_bits;
181     UINT8       port;
182     tUSERIAL_OPEN_CFG open_cfg;
183     int         sock_power_control;
184     int         client_device_address;
185     struct timespec write_time;
186 } tLINUX_CB;
187 
188 static tLINUX_CB linux_cb;  /* case of multipel port support use array : [MAX_SERIAL_PORT] */
189 
190 void userial_close_thread(UINT32 params);
191 
192 static UINT8 device_name[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
193 static int   bSerialPortDevice = FALSE;
194 static int _timeout = POLL_TIMEOUT;
195 static BOOLEAN is_close_thread_is_waiting = FALSE;
196 
197 static int change_client_addr(int addr);
198 
199 int   perf_log_every_count = 0;
200 typedef struct {
201     const char* label;
202     long    lapse;
203     long    bytes;
204     long    count;
205     long    overhead;
206 } tPERF_DATA;
207 
208 /*******************************************************************************
209 **
210 ** Function         perf_reset
211 **
212 ** Description      reset performance measurement data
213 **
214 ** Returns          none
215 **
216 *******************************************************************************/
perf_reset(tPERF_DATA * t)217 void perf_reset(tPERF_DATA* t)
218 {
219     t->count =
220     t->bytes =
221     t->lapse = 0;
222 }
223 
224 /*******************************************************************************
225 **
226 ** Function         perf_log
227 **
228 ** Description      produce a log entry of cvurrent performance data
229 **
230 ** Returns          none
231 **
232 *******************************************************************************/
perf_log(tPERF_DATA * t)233 void perf_log(tPERF_DATA* t)
234 {
235     // round to nearest ms
236     // t->lapse += 500;
237     // t->lapse /= 1000;
238     if (t->lapse)
239     {
240         if (t->bytes)
241             ALOGD( "%s:%s, bytes=%ld, lapse=%ld (%d.%02d kbps) (bus data rate %d.%02d kbps) overhead %d(%d percent)\n",
242                     __func__,
243                     t->label, t->bytes, t->lapse,
244                     (int)(8 * t->bytes / t->lapse), (int)(800 * t->bytes / (t->lapse)) % 100,
245                     (int)(9 * (t->bytes + t->count * t->overhead) / t->lapse), (int)(900 * (t->bytes + t->count * t->overhead) / (t->lapse)) % 100,
246                     (int)(t->count * t->overhead), (int)(t->count * t->overhead * 100 / t->bytes)
247                     );
248         else
249             ALOGD( "%s:%s, lapse=%ld (average %ld)\n", __func__,
250                     t->label, t->lapse, (int)t->lapse / t->count
251                     );
252     }
253     perf_reset(t);
254 }
255 
256 /*******************************************************************************
257 **
258 ** Function         perf_update
259 **
260 ** Description      update perforamnce measurement data
261 **
262 ** Returns          none
263 **
264 *******************************************************************************/
perf_update(tPERF_DATA * t,long lapse,long bytes)265 void perf_update(tPERF_DATA* t, long lapse, long bytes)
266 {
267     if (!perf_log_every_count)
268         return;
269     // round to nearest ms
270     lapse += 500;
271     lapse /= 1000;
272     t->count++;
273     t->bytes += bytes;
274     t->lapse += lapse;
275     if (t->count == perf_log_every_count)
276         perf_log(t);
277 }
278 
279 static tPERF_DATA   perf_poll = {"USERIAL_Poll", 0, 0, 0, 0};
280 static tPERF_DATA   perf_read = {"USERIAL_Read", 0, 0, 0, 9};
281 static tPERF_DATA   perf_write = {"USERIAL_Write", 0, 0, 0, 3};
282 static tPERF_DATA   perf_poll_2_poll = {"USERIAL_Poll_to_Poll", 0, 0, 0, 0};
283 static clock_t      _poll_t0 = 0;
284 
285 static UINT32 userial_baud_tbl[] =
286 {
287     300,        /* USERIAL_BAUD_300          0 */
288     600,        /* USERIAL_BAUD_600          1 */
289     1200,       /* USERIAL_BAUD_1200         2 */
290     2400,       /* USERIAL_BAUD_2400         3 */
291     9600,       /* USERIAL_BAUD_9600         4 */
292     19200,      /* USERIAL_BAUD_19200        5 */
293     57600,      /* USERIAL_BAUD_57600        6 */
294     115200,     /* USERIAL_BAUD_115200       7 */
295     230400,     /* USERIAL_BAUD_230400       8 */
296     460800,     /* USERIAL_BAUD_460800       9 */
297     921600,     /* USERIAL_BAUD_921600       10 */
298     1000000,    /* USERIAL_BAUD_1M           11 */
299     1500000,    /* USERIAL_BAUD_1_5M         12 */
300     2000000,    /* USERIAL_BAUD_2M           13 */
301     3000000,    /* USERIAL_BAUD_3M           14 */
302     4000000     /* USERIAL_BAUD_4M           15 */
303 };
304 
305 /*******************************************************************************
306 **
307 ** Function         wake_state
308 **
309 ** Description      return current state of NFC_WAKE gpio
310 **
311 ** Returns          GPIO value to wake NFCC
312 **
313 *******************************************************************************/
wake_state()314 static inline int wake_state()
315 {
316     return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
317 }
318 
319 /*******************************************************************************
320 **
321 ** Function         sleep_state
322 **
323 ** Description      return current state of NFC_WAKE gpio
324 **
325 ** Returns          GPIO value to allow NFCC to goto sleep
326 **
327 *******************************************************************************/
sleep_state()328 static inline int sleep_state()
329 {
330     return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_OFF : UPIO_ON);
331 }
332 
333 /*******************************************************************************
334 **
335 ** Function         isWake
336 **
337 ** Description      return current state of NFC_WAKE gpio based on the active mode setting
338 **
339 ** Returns          asserted_state if it's awake, deasserted_state if it's allowed to sleep
340 **
341 *******************************************************************************/
isWake(int state)342 static inline int isWake(int state)
343 {
344     int     asserted_state = ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
345     return (state != -1) ?
346         state == asserted_state :
347         current_nfc_wake_state == asserted_state;
348 }
349 
350 /*******************************************************************************
351 **
352 ** Function           setWriteDelay
353 **
354 ** Description        Record a delay for the next write operation
355 **
356 ** Input Parameter    delay in milliseconds
357 **
358 ** Comments           use this function to register a delay before next write,
359 **                    This is used in three instances: power up delay, wake delay
360 **                    and write delay
361 **
362 *******************************************************************************/
setWriteDelay(int delay)363 static void setWriteDelay(int delay)
364 {
365     if (delay <= 0) {
366         // Set a minimum delay of 5ms between back-to-back writes
367         delay = 5;
368     }
369 
370     clock_gettime(CLOCK_MONOTONIC, &linux_cb.write_time);
371     if (delay > 1000)
372     {
373         linux_cb.write_time.tv_sec += delay / 1000;
374         delay %= 1000;
375     }
376     unsigned long write_delay = delay * 1000 * 1000;
377     linux_cb.write_time.tv_nsec += write_delay;
378     if (linux_cb.write_time.tv_nsec > 1000*1000*1000)
379     {
380         linux_cb.write_time.tv_nsec -= 1000*1000*1000;
381         linux_cb.write_time.tv_sec++;
382     }
383 }
384 
385 /*******************************************************************************
386 **
387 ** Function           doWriteDelay
388 **
389 ** Description        Execute a delay as registered in setWriteDelay()
390 **
391 ** Output Parameter   none
392 **
393 ** Returns            none
394 **
395 ** Comments           This function calls GKI_Delay to execute a delay to fulfill
396 **                    the delay registered earlier.
397 **
398 *******************************************************************************/
doWriteDelay()399 static void doWriteDelay()
400 {
401     struct timespec now;
402     clock_gettime(CLOCK_MONOTONIC, &now);
403     long delay = 0;
404 
405     if (now.tv_sec > linux_cb.write_time.tv_sec)
406         return;
407     else if (now.tv_sec == linux_cb.write_time.tv_sec)
408     {
409         if (now.tv_nsec > linux_cb.write_time.tv_nsec)
410             return;
411         delay = (linux_cb.write_time.tv_nsec - now.tv_nsec) / 1000000;
412     }
413     else
414         delay = (linux_cb.write_time.tv_sec - now.tv_sec) * 1000 + linux_cb.write_time.tv_nsec / 1000000 - now.tv_nsec / 1000000;
415 
416     if (delay > 0 && delay < 1000)
417     {
418         ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "doWriteDelay() delay %ld ms", delay);
419         GKI_delay(delay);
420     }
421 }
422 
423 /*******************************************************************************
424 **
425 ** Function         create_signal_fds
426 **
427 ** Description      create a socketpair for read thread to use
428 **
429 ** Returns          file descriptor
430 **
431 *******************************************************************************/
432 
433 static int signal_fds[2];
create_signal_fds(struct pollfd * set)434 static inline int create_signal_fds(struct pollfd* set)
435 {
436     if (signal_fds[0] == 0 && socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0)
437     {
438         ALOGE("%s create_signal_sockets:socketpair failed, errno: %d", __func__, errno);
439         return -1;
440     }
441     set->fd = signal_fds[0];
442     return signal_fds[0];
443 }
444 
445 /*******************************************************************************
446 **
447 ** Function         close_signal_fds
448 **
449 ** Description      close the socketpair
450 **
451 ** Returns          none
452 **
453 *******************************************************************************/
close_signal_fds()454 static inline void close_signal_fds()
455 {
456     int stat = 0;
457 
458     stat = close(signal_fds[0]);
459     if (stat == -1)
460         ALOGE ("%s, fail close index 0; errno=%d", __FUNCTION__, errno);
461     signal_fds[0] = 0;
462 
463     stat = close(signal_fds[1]);
464     if (stat == -1)
465         ALOGE ("%s, fail close index 1; errno=%d", __FUNCTION__, errno);
466     signal_fds[1] = 0;
467 }
468 
469 /*******************************************************************************
470 **
471 ** Function         send_wakeup_signal
472 **
473 ** Description      send a one byte data to the socket as signal to the read thread
474 **                  for it to stop
475 **
476 ** Returns          number of bytes sent, or error no
477 **
478 *******************************************************************************/
send_wakeup_signal()479 static inline int send_wakeup_signal()
480 {
481     char sig_on = 1;
482     ALOGD("%s: Sending signal to %d", __func__, signal_fds[1]);
483     return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
484 }
485 
486 /*******************************************************************************
487 **
488 ** Function         reset_signal
489 **
490 ** Description      read the one byte data from the socket
491 **
492 ** Returns          received data
493 **
494 *******************************************************************************/
reset_signal()495 static inline int reset_signal()
496 {
497     char sig_recv = 0;
498     ALOGD("%s: Receiving signal from %d", __func__, signal_fds[0]);
499     recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
500     return (int)sig_recv;
501 }
502 
503 /*******************************************************************************
504 **
505 ** Function         is_signaled
506 **
507 ** Description      test if there's data waiting on the socket
508 **
509 ** Returns          TRUE is data is available
510 **
511 *******************************************************************************/
is_signaled(struct pollfd * set)512 static inline int is_signaled(struct pollfd* set)
513 {
514     return ((set->revents & POLLIN) == POLLIN) || ((set->revents & POLLRDNORM) == POLLRDNORM) ;
515 }
516 
517 /******************************************************************************/
518 
519 typedef unsigned char uchar;
520 
521 BUFFER_Q Userial_in_q;
522 
523 /*******************************************************************************
524  **
525  ** Function           USERIAL_GetLineSpeed
526  **
527  ** Description        This function convert USERIAL baud to line speed.
528  **
529  ** Output Parameter   None
530  **
531  ** Returns            line speed
532  **
533  *******************************************************************************/
USERIAL_GetLineSpeed(UINT8 baud)534 UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud)
535 {
536     return (baud <= USERIAL_BAUD_4M) ?
537             userial_baud_tbl[baud-USERIAL_BAUD_300] : 0;
538 }
539 
540 /*******************************************************************************
541  **
542  ** Function           USERIAL_GetBaud
543  **
544  ** Description        This function convert line speed to USERIAL baud.
545  **
546  ** Output Parameter   None
547  **
548  ** Returns            line speed
549  **
550  *******************************************************************************/
USERIAL_GetBaud(UINT32 line_speed)551 UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed)
552 {
553     UINT8 i;
554     for (i = USERIAL_BAUD_300; i <= USERIAL_BAUD_921600; i++)
555     {
556         if (userial_baud_tbl[i-USERIAL_BAUD_300] == line_speed)
557             return i;
558     }
559 
560     return USERIAL_BAUD_AUTO;
561 }
562 
563 /*******************************************************************************
564 **
565 ** Function           USERIAL_Init
566 **
567 ** Description        This function initializes the  serial driver.
568 **
569 ** Output Parameter   None
570 **
571 ** Returns            Nothing
572 **
573 *******************************************************************************/
574 
USERIAL_Init(void * p_cfg)575 UDRV_API void    USERIAL_Init(void * p_cfg)
576 {
577     ALOGI(__FUNCTION__);
578 
579     //if userial_close_thread() is waiting to run; let it go first;
580     //let it finish; then continue this function
581     while (TRUE)
582     {
583         pthread_mutex_lock(&close_thread_mutex);
584         if (is_close_thread_is_waiting)
585         {
586             pthread_mutex_unlock(&close_thread_mutex);
587             ALOGI("USERIAL_Init(): wait for close-thread");
588             sleep (1);
589         }
590         else
591             break;
592     }
593 
594     memset(&linux_cb, 0, sizeof(linux_cb));
595     linux_cb.sock = -1;
596     linux_cb.ser_cb = NULL;
597     linux_cb.sock_power_control = -1;
598     linux_cb.client_device_address = 0;
599     GKI_init_q(&Userial_in_q);
600     pthread_mutex_unlock(&close_thread_mutex);
601 }
602 
603 /*******************************************************************************
604  **
605  ** Function           my_read
606  **
607  ** Description        This function read a packet from driver.
608  **
609  ** Output Parameter   None
610  **
611  ** Returns            number of bytes in the packet or error code
612  **
613  *******************************************************************************/
my_read(int fd,uchar * pbuf,int len)614 int my_read(int fd, uchar *pbuf, int len)
615 {
616     struct pollfd fds[2];
617 
618     int n = 0;
619     int ret = 0;
620     int count = 0;
621     int offset = 0;
622     clock_t t1, t2;
623 
624     if (!isLowSpeedTransport && _timeout != POLL_TIMEOUT)
625         ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter, pbuf=%lx, len = %d\n", __func__, (unsigned long)pbuf, len);
626     memset(pbuf, 0, len);
627     /* need to use select in order to avoid collistion between read and close on same fd */
628     /* Initialize the input set */
629     fds[0].fd = fd;
630     fds[0].events = POLLIN | POLLERR | POLLRDNORM;
631     fds[0].revents = 0;
632 
633     create_signal_fds(&fds[1]);
634     fds[1].events = POLLIN | POLLERR | POLLRDNORM;
635     fds[1].revents = 0;
636     t1 = clock();
637     n = TEMP_FAILURE_RETRY(poll(fds, 2, _timeout));
638     t2 = clock();
639     perf_update(&perf_poll, t2 - t1, 0);
640     if (_poll_t0)
641         perf_update(&perf_poll_2_poll, t2 - _poll_t0, 0);
642 
643     _poll_t0 = t2;
644     /* See if there was an error */
645     if (n < 0)
646     {
647         ALOGD( "select failed; errno = %d\n", errno);
648         return -errno;
649     }
650     else if (n == 0)
651         return -EAGAIN;
652 
653     if (is_signaled(&fds[1]))
654     {
655         ALOGD( "%s: exit signal received\n", __func__);
656         reset_signal();
657         return -1;
658     }
659     if (!bSerialPortDevice || len < MIN_BUFSIZE)
660         count = len;
661     else
662         count = 1;
663     do {
664         t2 = clock();
665         ret = TEMP_FAILURE_RETRY(read(fd, pbuf+offset, (size_t)count));
666         if (ret > 0)
667             perf_update(&perf_read, clock()-t2, ret);
668 
669         if (ret <= 0 || !bSerialPortDevice || len < MIN_BUFSIZE)
670             break;
671 
672         if (isLowSpeedTransport)
673             goto done;
674 
675         if (offset == 0)
676         {
677             if (pbuf[offset] == HCIT_TYPE_NFC)
678                 count = 3;
679             else if (pbuf[offset] == HCIT_TYPE_EVENT)
680                 count = 2;
681             else
682             {
683                 ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x\n", __func__, offset, pbuf[offset]);
684                 break;
685             }
686             offset = 1;
687         }
688         else if (offset == 1)
689         {
690             offset += count;
691             count = pbuf[offset-1];
692             if (count > (len - offset)) //if (count > (remaining buffer size))
693                 count = len - offset; //only read what the remaining buffer size can hold
694         }
695         else
696         {
697             offset += ret;
698             count -= ret;
699         }
700         if (count == 0)
701         {
702             ret = offset;
703             break;
704         }
705     } while (count > 0);
706 
707 
708  #if VALIDATE_PACKET
709 /*
710  * vallidate the packet structure
711  */
712     if (ret > 0 && len >= MIN_BUFSIZE)
713     {
714         count = 0;
715         while (count < ret)
716         {
717             if (pbuf[count] == HCIT_TYPE_NFC)
718             {
719                 if (USERIAL_Debug_verbose)
720                     scru_dump_hex(pbuf+count, NULL, pbuf[count+3]+4, 0, 0);
721                 count += pbuf[count+3]+4;
722             }
723             else if (pbuf[count] == HCIT_TYPE_EVENT)
724             {
725                 if (USERIAL_Debug_verbose)
726                     scru_dump_hex(pbuf+count, NULL, pbuf[count+2]+3, 0, 0);
727                 count += pbuf[count+2]+3;
728             }
729             else
730             {
731                 ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x, remain %d bytes\n", __func__, count, pbuf[count], ret-count);
732                 scru_dump_hex(pbuf+count, NULL, ret - count, 0, 0);
733                 break;
734             }
735         } /* while*/
736     }
737 #endif
738 done:
739     if (!isLowSpeedTransport)
740         ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: return %d(0x%x) bytes, errno=%d count=%d, n=%d, timeout=%d\n", __func__,
741             ret, ret, errno, count, n, _timeout);
742     if (_timeout == POLL_TIMEOUT)
743         _timeout = -1;
744     return ret;
745 }
746 extern BOOLEAN gki_chk_buf_damage(void *p_buf);
747 static int sRxLength = 0;
748 
749 /*******************************************************************************
750  **
751  ** Function           userial_read_thread
752  **
753  ** Description        entry point of read thread.
754  **
755  ** Output Parameter   None
756  **
757  ** Returns            0
758  **
759  *******************************************************************************/
userial_read_thread(UINT32 arg)760 UINT32 userial_read_thread(UINT32 arg)
761 {
762     int rx_length;
763     int error_count = 0;
764     int bErrorReported = 0;
765     int iMaxError = MAX_ERROR;
766     BT_HDR *p_buf = NULL;
767 
768     worker_thread1 = pthread_self();
769 
770     ALOGD( "start userial_read_thread, id=%lx", worker_thread1);
771     _timeout = POLL_TIMEOUT;
772 
773     for (;linux_cb.sock > 0;)
774     {
775         BT_HDR *p_buf;
776         UINT8 *current_packet;
777 
778         if ((p_buf = (BT_HDR *) GKI_getpoolbuf( USERIAL_POOL_ID ) )!= NULL)
779         {
780             p_buf->offset = 0;
781             p_buf->layer_specific = 0;
782 
783             current_packet = (UINT8 *) (p_buf + 1);
784             rx_length = my_read(linux_cb.sock, current_packet, READ_LIMIT);
785 
786         }
787         else
788         {
789             ALOGE( "userial_read_thread(): unable to get buffer from GKI p_buf = %p poolid = %d\n", p_buf, USERIAL_POOL_ID);
790             rx_length = 0;  /* paranoia setting */
791             GKI_delay( NO_GKI_BUFFER_RECOVER_TIME );
792             continue;
793         }
794         if (rx_length > 0)
795         {
796             bErrorReported = 0;
797             error_count = 0;
798             iMaxError = 3;
799             if (rx_length > sRxLength)
800                 sRxLength = rx_length;
801             p_buf->len = (UINT16)rx_length;
802             GKI_enqueue(&Userial_in_q, p_buf);
803             if (!isLowSpeedTransport)
804                 ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "userial_read_thread(): enqueued p_buf=%p, count=%d, length=%d\n",
805                             p_buf, Userial_in_q.count, rx_length);
806 
807             if (linux_cb.ser_cb != NULL)
808                 (*linux_cb.ser_cb)(linux_cb.port, USERIAL_RX_READY_EVT, (tUSERIAL_EVT_DATA *)p_buf);
809 
810             GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
811         }
812         else
813         {
814             GKI_freebuf( p_buf );
815             if (rx_length == -EAGAIN)
816                 continue;
817             else if (rx_length == -1)
818             {
819                 ALOGD( "userial_read_thread(): exiting\n");
820                 break;
821             }
822             else if (rx_length == 0 && !isWake(-1))
823                 continue;
824             ++error_count;
825             if (rx_length <= 0 && ((error_count > 0) && ((error_count % iMaxError) == 0)))
826             {
827                 if (bErrorReported == 0)
828                 {
829                     ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d return USERIAL_ERR_EVT\n",
830                             rx_length, error_count, errno);
831                     if (linux_cb.ser_cb != NULL)
832                         (*linux_cb.ser_cb)(linux_cb.port, USERIAL_ERR_EVT, (tUSERIAL_EVT_DATA *)p_buf);
833 
834                     GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
835                     ++bErrorReported;
836                 }
837                 if (sRxLength == 0)
838                 {
839                     ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d exit read thread\n",
840                             rx_length, error_count, errno);
841                     break;
842                 }
843             }
844         }
845     } /* for */
846 
847     ALOGD( "userial_read_thread(): freeing GKI_buffers\n");
848     while ((p_buf = (BT_HDR *) GKI_dequeue (&Userial_in_q)) != NULL)
849     {
850         GKI_freebuf(p_buf);
851         ALOGD("userial_read_thread: dequeued buffer from Userial_in_q\n");
852     }
853 
854     GKI_exit_task (GKI_get_taskid ());
855     ALOGD( "USERIAL READ: EXITING TASK\n");
856 
857     return 0;
858 }
859 
860 /*******************************************************************************
861  **
862  ** Function           userial_to_tcio_baud
863  **
864  ** Description        helper function converts USERIAL baud rates into TCIO conforming baud rates
865  **
866  ** Output Parameter   None
867  **
868  ** Returns            TRUE - success
869  **                    FALSE - unsupported baud rate, default of 115200 is used
870  **
871  *******************************************************************************/
userial_to_tcio_baud(UINT8 cfg_baud,UINT32 * baud)872 BOOLEAN userial_to_tcio_baud(UINT8 cfg_baud, UINT32 * baud)
873 {
874     if (cfg_baud == USERIAL_BAUD_600)
875         *baud = B600;
876     else if (cfg_baud == USERIAL_BAUD_1200)
877         *baud = B1200;
878     else if (cfg_baud == USERIAL_BAUD_9600)
879         *baud = B9600;
880     else if (cfg_baud == USERIAL_BAUD_19200)
881         *baud = B19200;
882     else if (cfg_baud == USERIAL_BAUD_57600)
883         *baud = B57600;
884     else if (cfg_baud == USERIAL_BAUD_115200)
885         *baud = B115200 | CBAUDEX;
886     else if (cfg_baud == USERIAL_BAUD_230400)
887         *baud = B230400;
888     else if (cfg_baud == USERIAL_BAUD_460800)
889         *baud = B460800;
890     else if (cfg_baud == USERIAL_BAUD_921600)
891         *baud = B921600;
892     else if (cfg_baud == USERIAL_BAUD_1M)
893         *baud = B1000000;
894     else if (cfg_baud == USERIAL_BAUD_2M)
895         *baud = B2000000;
896     else if (cfg_baud == USERIAL_BAUD_3M)
897         *baud = B3000000;
898     else if (cfg_baud == USERIAL_BAUD_4M)
899         *baud = B4000000;
900     else
901     {
902         ALOGE( "userial_to_tcio_baud: unsupported baud idx %i", cfg_baud );
903         *baud = B115200;
904         return FALSE;
905     }
906     return TRUE;
907 }
908 
909 #if (USERIAL_USE_IO_BT_WAKE==TRUE)
910 /*******************************************************************************
911  **
912  ** Function           userial_io_init_bt_wake
913  **
914  ** Description        helper function to set the open state of the bt_wake if ioctl
915  **                    is used. it should not hurt in the rfkill case but it might
916  **                    be better to compile it out.
917  **
918  ** Returns            none
919  **
920  *******************************************************************************/
userial_io_init_bt_wake(int fd,unsigned long * p_wake_state)921 void userial_io_init_bt_wake( int fd, unsigned long * p_wake_state )
922 {
923     /* assert BT_WAKE for ioctl. should NOT hurt on rfkill version */
924     ioctl( fd, USERIAL_IO_BT_WAKE_ASSERT, NULL);
925     ioctl( fd, USERIAL_IO_BT_WAKE_GET_ST, p_wake_state );
926     if ( *p_wake_state == 0)
927         ALOGI("\n***userial_io_init_bt_wake(): Ooops, asserted BT_WAKE signal, but still got BT_WAKE state == to %d\n",
928              *p_wake_state );
929 
930     *p_wake_state = 1;
931 }
932 #endif
933 
934 /*******************************************************************************
935 **
936 ** Function           USERIAL_Open
937 **
938 ** Description        Open the indicated serial port with the given configuration
939 **
940 ** Output Parameter   None
941 **
942 ** Returns            Nothing
943 **
944 *******************************************************************************/
USERIAL_Open(tUSERIAL_PORT port,tUSERIAL_OPEN_CFG * p_cfg,tUSERIAL_CBACK * p_cback)945 UDRV_API void USERIAL_Open(tUSERIAL_PORT port, tUSERIAL_OPEN_CFG *p_cfg, tUSERIAL_CBACK *p_cback)
946 {
947     UINT32 baud = 0;
948     UINT8 data_bits = 0;
949     UINT16 parity = 0;
950     UINT8 stop_bits = 0;
951     struct termios termios;
952     const char ttyusb[] = "/dev/ttyUSB";
953     const char devtty[] = "/dev/tty";
954     unsigned long num = 0;
955     int     ret = 0;
956 
957     ALOGI("USERIAL_Open(): enter");
958 
959     //if userial_close_thread() is waiting to run; let it go first;
960     //let it finish; then continue this function
961     while (TRUE)
962     {
963         pthread_mutex_lock(&close_thread_mutex);
964         if (is_close_thread_is_waiting)
965         {
966             pthread_mutex_unlock(&close_thread_mutex);
967             ALOGI("USERIAL_Open(): wait for close-thread");
968             sleep (1);
969         }
970         else
971             break;
972     }
973 
974     // restore default power off delay settings incase they were changed in userial_set_poweroff_delays()
975     gPrePowerOffDelay = 0;
976     gPostPowerOffDelay = 0;
977 
978     if ( !GetStrValue ( NAME_TRANSPORT_DRIVER, userial_dev, sizeof ( userial_dev ) ) )
979         strcpy ( userial_dev, default_transport );
980     if ( GetNumValue ( NAME_UART_PORT, &num, sizeof ( num ) ) )
981         uart_port = num;
982     if ( GetNumValue ( NAME_LOW_SPEED_TRANSPORT, &num, sizeof ( num ) ) )
983         isLowSpeedTransport = num;
984     if ( GetNumValue ( NAME_NFC_WAKE_DELAY, &num, sizeof ( num ) ) )
985         nfc_wake_delay = num;
986     if ( GetNumValue ( NAME_NFC_WRITE_DELAY, &num, sizeof ( num ) ) )
987         nfc_write_delay = num;
988     if ( GetNumValue ( NAME_PERF_MEASURE_FREQ, &num, sizeof ( num ) ) )
989         perf_log_every_count = num;
990     if ( GetNumValue ( NAME_POWER_ON_DELAY, &num, sizeof ( num ) ) )
991         gPowerOnDelay = num;
992     if ( GetNumValue ( NAME_PRE_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
993         gPrePowerOffDelay = num;
994     if ( GetNumValue ( NAME_POST_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
995         gPostPowerOffDelay = num;
996     if ( GetNumValue ( NAME_POWER_OFF_MODE, &num, sizeof ( num ) ) )
997         gPowerOffMode = num;
998     ALOGI("USERIAL_Open() device: %s port=%d, uart_port=%d WAKE_DELAY(%d) WRITE_DELAY(%d) POWER_ON_DELAY(%d) PRE_POWER_OFF_DELAY(%d) POST_POWER_OFF_DELAY(%d)",
999             (char*)userial_dev, port, uart_port, nfc_wake_delay, nfc_write_delay, gPowerOnDelay, gPrePowerOffDelay,
1000             gPostPowerOffDelay);
1001 
1002     strcpy((char*)device_name, (char*)userial_dev);
1003     sRxLength = 0;
1004     _poll_t0 = 0;
1005 
1006     if ((strncmp(userial_dev, ttyusb, sizeof(ttyusb)-1) == 0) ||
1007         (strncmp(userial_dev, devtty, sizeof(devtty)-1) == 0) )
1008     {
1009         if (uart_port >= MAX_SERIAL_PORT)
1010         {
1011             ALOGD( "Port > MAX_SERIAL_PORT\n");
1012             goto done_open;
1013         }
1014         bSerialPortDevice = TRUE;
1015         sprintf((char*)device_name, "%s%d", (char*)userial_dev, uart_port);
1016         ALOGI("USERIAL_Open() using device_name: %s ", (char*)device_name);
1017         if (!userial_to_tcio_baud(p_cfg->baud, &baud))
1018             goto done_open;
1019 
1020         if (p_cfg->fmt & USERIAL_DATABITS_8)
1021             data_bits = CS8;
1022         else if (p_cfg->fmt & USERIAL_DATABITS_7)
1023             data_bits = CS7;
1024         else if (p_cfg->fmt & USERIAL_DATABITS_6)
1025             data_bits = CS6;
1026         else if (p_cfg->fmt & USERIAL_DATABITS_5)
1027             data_bits = CS5;
1028         else
1029             goto done_open;
1030 
1031         if (p_cfg->fmt & USERIAL_PARITY_NONE)
1032             parity = 0;
1033         else if (p_cfg->fmt & USERIAL_PARITY_EVEN)
1034             parity = PARENB;
1035         else if (p_cfg->fmt & USERIAL_PARITY_ODD)
1036             parity = (PARENB | PARODD);
1037         else
1038             goto done_open;
1039 
1040         if (p_cfg->fmt & USERIAL_STOPBITS_1)
1041             stop_bits = 0;
1042         else if (p_cfg->fmt & USERIAL_STOPBITS_2)
1043             stop_bits = CSTOPB;
1044         else
1045             goto done_open;
1046     }
1047     else
1048         strcpy((char*)device_name, (char*)userial_dev);
1049 
1050     {
1051         ALOGD("%s Opening %s\n",  __FUNCTION__, device_name);
1052         if ((linux_cb.sock = open((char*)device_name, O_RDWR | O_NOCTTY )) == -1)
1053         {
1054             ALOGI("%s unable to open %s",  __FUNCTION__, device_name);
1055             GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE);
1056             goto done_open;
1057         }
1058         ALOGD( "%s sock = %d\n", __FUNCTION__, linux_cb.sock);
1059         if (GetStrValue ( NAME_POWER_CONTROL_DRIVER, power_control_dev, sizeof ( power_control_dev ) ) &&
1060             power_control_dev[0] != '\0')
1061         {
1062             if (strcmp(power_control_dev, userial_dev) == 0)
1063                 linux_cb.sock_power_control = linux_cb.sock;
1064             else
1065             {
1066                 if ((linux_cb.sock_power_control = open((char*)power_control_dev, O_RDWR | O_NOCTTY )) == -1)
1067                 {
1068                     ALOGI("%s unable to open %s",  __FUNCTION__, power_control_dev);
1069                 }
1070             }
1071         }
1072         if ( bSerialPortDevice )
1073         {
1074             tcflush(linux_cb.sock, TCIOFLUSH);
1075             tcgetattr(linux_cb.sock, &termios);
1076 
1077             termios.c_cflag &= ~(CSIZE | PARENB);
1078             termios.c_cflag = CLOCAL|CREAD|data_bits|stop_bits|parity;
1079             if (!parity)
1080                 termios.c_cflag |= IGNPAR;
1081             // termios.c_cflag &= ~CRTSCTS;
1082             termios.c_oflag = 0;
1083             termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
1084             termios.c_iflag &= ~(BRKINT | ICRNL | INLCR | ISTRIP | IXON | IGNBRK | PARMRK | INPCK);
1085             termios.c_lflag = 0;
1086             termios.c_iflag = 0;
1087             cfsetospeed(&termios, baud);
1088             cfsetispeed(&termios, baud);
1089 
1090             termios.c_cc[VTIME] = 0;
1091             termios.c_cc[VMIN] = 1;
1092             tcsetattr(linux_cb.sock, TCSANOW, &termios);
1093 
1094             tcflush(linux_cb.sock, TCIOFLUSH);
1095 
1096 #if (USERIAL_USE_IO_BT_WAKE==TRUE)
1097             userial_io_init_bt_wake( linux_cb.sock, &linux_cb.bt_wake_state );
1098 #endif
1099             GKI_delay(gPowerOnDelay);
1100         }
1101         else
1102         {
1103             USERIAL_PowerupDevice(port);
1104         }
1105     }
1106 
1107     linux_cb.ser_cb     = p_cback;
1108     linux_cb.port = port;
1109     memcpy(&linux_cb.open_cfg, p_cfg, sizeof(tUSERIAL_OPEN_CFG));
1110     GKI_create_task ((TASKPTR)userial_read_thread, USERIAL_HAL_TASK, (INT8*)"USERIAL_HAL_TASK", 0, 0, (pthread_cond_t*)NULL, NULL);
1111 
1112 
1113 #if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
1114     ALOGD( "Leaving USERIAL_Open\n");
1115 #endif
1116 
1117 #if (SERIAL_AMBA == TRUE)
1118     /* give 20ms time for reader thread */
1119     GKI_delay(20);
1120 #endif
1121 
1122 done_open:
1123     pthread_mutex_unlock(&close_thread_mutex);
1124     ALOGI("USERIAL_Open(): exit");
1125     return;
1126 }
1127 
1128 /*******************************************************************************
1129 **
1130 ** Function           USERIAL_Read
1131 **
1132 ** Description        Read data from a serial port using byte buffers.
1133 **
1134 ** Output Parameter   None
1135 **
1136 ** Returns            Number of bytes actually read from the serial port and
1137 **                    copied into p_data.  This may be less than len.
1138 **
1139 *******************************************************************************/
1140 
1141 static BT_HDR *pbuf_USERIAL_Read = NULL;
1142 
USERIAL_Read(tUSERIAL_PORT port,UINT8 * p_data,UINT16 len)1143 UDRV_API UINT16  USERIAL_Read(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
1144 {
1145     UINT16 total_len = 0;
1146     UINT16 copy_len = 0;
1147     UINT8 * current_packet = NULL;
1148 
1149 #if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
1150     ALOGD( "%s ++ len=%d pbuf_USERIAL_Read=%p, p_data=%p\n", __func__, len, pbuf_USERIAL_Read, p_data);
1151 #endif
1152     do
1153     {
1154         if (pbuf_USERIAL_Read != NULL)
1155         {
1156             current_packet = ((UINT8 *)(pbuf_USERIAL_Read + 1)) + (pbuf_USERIAL_Read->offset);
1157 
1158             if ((pbuf_USERIAL_Read->len) <= (len - total_len))
1159                 copy_len = pbuf_USERIAL_Read->len;
1160             else
1161                 copy_len = (len - total_len);
1162 
1163             memcpy((p_data + total_len), current_packet, copy_len);
1164 
1165             total_len += copy_len;
1166 
1167             pbuf_USERIAL_Read->offset += copy_len;
1168             pbuf_USERIAL_Read->len -= copy_len;
1169 
1170             if (pbuf_USERIAL_Read->len == 0)
1171             {
1172                 GKI_freebuf(pbuf_USERIAL_Read);
1173                 pbuf_USERIAL_Read = NULL;
1174             }
1175         }
1176 
1177         if (pbuf_USERIAL_Read == NULL && (total_len < len))
1178             pbuf_USERIAL_Read = (BT_HDR *)GKI_dequeue(&Userial_in_q);
1179 
1180     } while ((pbuf_USERIAL_Read != NULL) && (total_len < len));
1181 
1182 #if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
1183     ALOGD( "%s: returned %d bytes", __func__, total_len);
1184 #endif
1185     return total_len;
1186 }
1187 
1188 /*******************************************************************************
1189 **
1190 ** Function           USERIAL_Readbuf
1191 **
1192 ** Description        Read data from a serial port using GKI buffers.
1193 **
1194 ** Output Parameter   Pointer to a GKI buffer which contains the data.
1195 **
1196 ** Returns            Nothing
1197 **
1198 ** Comments           The caller of this function is responsible for freeing the
1199 **                    GKI buffer when it is finished with the data.  If there is
1200 **                    no data to be read, the value of the returned pointer is
1201 **                    NULL.
1202 **
1203 *******************************************************************************/
1204 
USERIAL_ReadBuf(tUSERIAL_PORT port,BT_HDR ** p_buf)1205 UDRV_API void    USERIAL_ReadBuf(tUSERIAL_PORT port, BT_HDR **p_buf)
1206 {
1207 
1208 }
1209 
1210 /*******************************************************************************
1211 **
1212 ** Function           USERIAL_WriteBuf
1213 **
1214 ** Description        Write data to a serial port using a GKI buffer.
1215 **
1216 ** Output Parameter   None
1217 **
1218 ** Returns            TRUE  if buffer accepted for write.
1219 **                    FALSE if there is already a buffer being processed.
1220 **
1221 ** Comments           The buffer will be freed by the serial driver.  Therefore,
1222 **                    the application calling this function must not free the
1223 **                    buffer.
1224 **
1225 *******************************************************************************/
1226 
USERIAL_WriteBuf(tUSERIAL_PORT port,BT_HDR * p_buf)1227 UDRV_API BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT port, BT_HDR *p_buf)
1228 {
1229     return FALSE;
1230 }
1231 
1232 /*******************************************************************************
1233 **
1234 ** Function           USERIAL_Write
1235 **
1236 ** Description        Write data to a serial port using a byte buffer.
1237 **
1238 ** Output Parameter   None
1239 **
1240 ** Returns            Number of bytes actually written to the transport.  This
1241 **                    may be less than len.
1242 **
1243 *******************************************************************************/
USERIAL_Write(tUSERIAL_PORT port,UINT8 * p_data,UINT16 len)1244 UDRV_API UINT16  USERIAL_Write(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
1245 {
1246     int ret = 0, total = 0;
1247     int i = 0;
1248     clock_t t;
1249 
1250     ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write: (%d bytes)", len);
1251     pthread_mutex_lock(&close_thread_mutex);
1252 
1253     doWriteDelay();
1254     t = clock();
1255     while (len != 0 && linux_cb.sock != -1)
1256     {
1257         ret = TEMP_FAILURE_RETRY(write(linux_cb.sock, p_data + total, len));
1258         if (ret < 0)
1259         {
1260             ALOGE("USERIAL_Write len = %d, ret = %d, errno = %d", len, ret, errno);
1261             break;
1262         }
1263         else
1264         {
1265             ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write len = %d, ret = %d", len, ret);
1266         }
1267 
1268         total += ret;
1269         len -= ret;
1270     }
1271     perf_update(&perf_write, clock() - t, total);
1272 
1273     /* register a delay for next write */
1274     setWriteDelay(total * nfc_write_delay / 1000);
1275 
1276     pthread_mutex_unlock(&close_thread_mutex);
1277 
1278     return ((UINT16)total);
1279 }
1280 
1281 /*******************************************************************************
1282 **
1283 ** Function           userial_change_rate
1284 **
1285 ** Description        change naud rate
1286 **
1287 ** Output Parameter   None
1288 **
1289 ** Returns            None
1290 **
1291 *******************************************************************************/
userial_change_rate(UINT8 baud)1292 void userial_change_rate(UINT8 baud)
1293 {
1294 #if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
1295     struct termios termios;
1296 #endif
1297 #if (USERIAL_USE_TCIO_BAUD_CHANGE==TRUE)
1298     UINT32 tcio_baud;
1299 #endif
1300 
1301 #if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
1302     tcflush(linux_cb.sock, TCIOFLUSH);
1303 
1304     tcgetattr(linux_cb.sock, &termios);
1305 
1306     cfmakeraw(&termios);
1307     cfsetospeed(&termios, baud);
1308     cfsetispeed(&termios, baud);
1309 
1310     termios.c_cflag |= (CLOCAL | CREAD | CRTSCTS | stop_bits);
1311 
1312     tcsetattr(linux_cb.sock, TCSANOW, &termios);
1313     tcflush(linux_cb.sock, TCIOFLUSH);
1314 
1315 #else
1316 #if (USERIAL_USE_TCIO_BAUD_CHANGE==FALSE)
1317     fprintf(stderr, "userial_change_rate: Closing UART Port\n");
1318     ALOGI("userial_change_rate: Closing UART Port\n");
1319     USERIAL_Close(linux_cb.port);
1320 
1321     GKI_delay(50);
1322 
1323     /* change baud rate in settings - leave everything else the same  */
1324     linux_cb.open_cfg.baud = baud;
1325 
1326     ALOGD( "userial_change_rate: Attempting to reopen the UART Port at 0x%08x\n", (unsigned int)USERIAL_GetLineSpeed(baud));
1327     ALOGI("userial_change_rate: Attempting to reopen the UART Port at %i\n", (unsigned int)USERIAL_GetLineSpeed(baud));
1328 
1329     USERIAL_Open(linux_cb.port, &linux_cb.open_cfg, linux_cb.ser_cb);
1330 #else /* amba uart */
1331     fprintf(stderr, "userial_change_rate(): changeing baud rate via TCIO \n");
1332     ALOGI( "userial_change_rate: (): changeing baud rate via TCIO \n");
1333     /* change baud rate in settings - leave everything else the same  */
1334     linux_cb.open_cfg.baud = baud;
1335     if (!userial_to_tcio_baud(linux_cb.open_cfg.baud, &tcio_baud))
1336         return;
1337 
1338     tcflush(linux_cb.sock, TCIOFLUSH);
1339 
1340     /* get current settings. they should be fine besides baud rate we want to change */
1341     tcgetattr(linux_cb.sock, &termios);
1342 
1343     /* set input/output baudrate */
1344     cfsetospeed(&termios, tcio_baud);
1345     cfsetispeed(&termios, tcio_baud);
1346     tcsetattr(linux_cb.sock, TCSANOW, &termios);
1347 
1348     tcflush(linux_cb.sock, TCIOFLUSH);
1349 #endif
1350 #endif   /* USING_BRCM_USB  */
1351 }
1352 
1353 /*******************************************************************************
1354 **
1355 ** Function           userial_close_port
1356 **
1357 ** Description        close the transport driver
1358 **
1359 ** Returns            Nothing
1360 **
1361 *******************************************************************************/
userial_close_port(void)1362 void userial_close_port( void )
1363 {
1364     USERIAL_Close(linux_cb.port);
1365 }
1366 
1367 /*******************************************************************************
1368 **
1369 ** Function           USERIAL_Ioctl
1370 **
1371 ** Description        Perform an operation on a serial port.
1372 **
1373 ** Output Parameter   The p_data parameter is either an input or output depending
1374 **                    on the operation.
1375 **
1376 ** Returns            Nothing
1377 **
1378 *******************************************************************************/
1379 
USERIAL_Ioctl(tUSERIAL_PORT port,tUSERIAL_OP op,tUSERIAL_IOCTL_DATA * p_data)1380 UDRV_API void    USERIAL_Ioctl(tUSERIAL_PORT port, tUSERIAL_OP op, tUSERIAL_IOCTL_DATA *p_data)
1381 {
1382 #if (defined LINUX_OS) && (LINUX_OS == TRUE)
1383     USB_SCO_CONTROL ioctl_data;
1384 
1385     /* just ignore port parameter as we are using USB in this case  */
1386 #endif
1387 
1388     switch (op)
1389     {
1390     case USERIAL_OP_FLUSH:
1391         break;
1392     case USERIAL_OP_FLUSH_RX:
1393         break;
1394     case USERIAL_OP_FLUSH_TX:
1395         break;
1396     case USERIAL_OP_BAUD_WR:
1397         ALOGI( "USERIAL_Ioctl: Received USERIAL_OP_BAUD_WR on port: %d, ioctl baud%i\n", port, p_data->baud);
1398         linux_cb.port = port;
1399         userial_change_rate(p_data->baud);
1400         break;
1401 
1402     default:
1403         break;
1404     }
1405 
1406     return;
1407 }
1408 
1409 
1410 /*******************************************************************************
1411 **
1412 ** Function         USERIAL_SetPowerOffDelays
1413 **
1414 ** Description      Set power off delays used during USERIAL_Close().  The
1415 **                  values in the conf. file setting override these if set.
1416 **
1417 ** Returns          None.
1418 **
1419 *******************************************************************************/
USERIAL_SetPowerOffDelays(int pre_poweroff_delay,int post_poweroff_delay)1420 UDRV_API void USERIAL_SetPowerOffDelays(int pre_poweroff_delay, int post_poweroff_delay)
1421 {
1422     gPrePowerOffDelay = pre_poweroff_delay;
1423     gPostPowerOffDelay = post_poweroff_delay;
1424 }
1425 
1426 /*******************************************************************************
1427 **
1428 ** Function           USERIAL_Close
1429 **
1430 ** Description        Close a serial port
1431 **
1432 ** Output Parameter   None
1433 **
1434 ** Returns            Nothing
1435 **
1436 *******************************************************************************/
USERIAL_Close(tUSERIAL_PORT port)1437 UDRV_API void    USERIAL_Close(tUSERIAL_PORT port)
1438 {
1439     pthread_attr_t attr;
1440     pthread_t      close_thread;
1441     UINT8          res[10];
1442     UINT32         delay = 100;
1443 
1444     ALOGD ("%s: enter; gPowerOffMode=%d", __FUNCTION__, gPowerOffMode);
1445 
1446     /* Do we need to put NFCC into certain mode before switching off?... */
1447     if (gPowerOffMode != POM_NORMAL)
1448     {
1449         switch (gPowerOffMode)
1450         {
1451         case POM_CE3SO:
1452             ALOGD ("%s: Sending Set_PwrLevel cmd to go to CE3-SO mode", __FUNCTION__);
1453             USERIAL_Write(port, ce3_so_cmd, sizeof (ce3_so_cmd));
1454             delay = 1000;
1455             break;
1456 
1457         case POM_NFC_OFF:
1458             ALOGD ("%s: Sending Set_NfcOff cmd", __FUNCTION__);
1459             USERIAL_Write(port, set_nfc_off_cmd, sizeof (set_nfc_off_cmd));
1460             break;
1461         }
1462 
1463         USERIAL_Read(port, res, sizeof ( res ));
1464         GKI_delay(delay);
1465     }
1466 
1467     // check to see if thread is already running
1468     if (pthread_mutex_trylock(&close_thread_mutex) == 0)
1469     {
1470         // mutex aquired so thread is not running
1471         is_close_thread_is_waiting = TRUE;
1472         pthread_mutex_unlock(&close_thread_mutex);
1473 
1474         // close transport in a new thread so we don't block the caller
1475         // make thread detached, no other thread will join
1476         pthread_attr_init(&attr);
1477         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1478         pthread_create( &close_thread, &attr, (void *)userial_close_thread, NULL);
1479         pthread_attr_destroy(&attr);
1480     }
1481     else
1482     {
1483         // mutex not aquired to thread is already running
1484         ALOGD( "USERIAL_Close(): already closing \n");
1485     }
1486     ALOGD ("%s: exit", __FUNCTION__);
1487 }
1488 
1489 
1490 /*******************************************************************************
1491 **
1492 ** Function         userial_close_thread
1493 **
1494 ** Description      Thread to close USERIAL
1495 **
1496 ** Returns          None.
1497 **
1498 *******************************************************************************/
userial_close_thread(UINT32 params)1499 void userial_close_thread(UINT32 params)
1500 {
1501     BT_HDR                  *p_buf = NULL;
1502     int result;
1503 
1504     ALOGD( "%s: closing transport (%d)\n", __FUNCTION__, linux_cb.sock);
1505     pthread_mutex_lock(&close_thread_mutex);
1506     is_close_thread_is_waiting = FALSE;
1507 
1508     if (linux_cb.sock <= 0)
1509     {
1510         ALOGD( "%s: already closed (%d)\n", __FUNCTION__, linux_cb.sock);
1511         pthread_mutex_unlock(&close_thread_mutex);
1512         return;
1513     }
1514 
1515     send_wakeup_signal();
1516     result = pthread_join( worker_thread1, NULL );
1517     if ( result < 0 )
1518         ALOGE( "%s: pthread_join() FAILED: result: %d", __FUNCTION__, result );
1519     else
1520         ALOGD( "%s: pthread_join() joined: result: %d", __FUNCTION__, result );
1521 
1522     if (linux_cb.sock_power_control > 0)
1523     {
1524         result = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, sleep_state());
1525         ALOGD("%s: Delay %dms before turning off the chip", __FUNCTION__, gPrePowerOffDelay);
1526         GKI_delay(gPrePowerOffDelay);
1527         result = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
1528         ALOGD("%s: Delay %dms after turning off the chip", __FUNCTION__, gPostPowerOffDelay);
1529         GKI_delay(gPostPowerOffDelay);
1530     }
1531     result = close(linux_cb.sock);
1532     if (result == -1)
1533         ALOGE("%s: fail close linux_cb.sock; errno=%d", __FUNCTION__, errno);
1534 
1535     if (linux_cb.sock_power_control > 0 && linux_cb.sock_power_control != linux_cb.sock)
1536     result = close(linux_cb.sock_power_control);
1537     if (result == -1)
1538         ALOGE("%s: fail close linux_cb.sock_power_control; errno=%d", __FUNCTION__, errno);
1539 
1540     linux_cb.sock_power_control = -1;
1541     linux_cb.sock = -1;
1542 
1543     close_signal_fds();
1544     pthread_mutex_unlock(&close_thread_mutex);
1545     ALOGD("%s: exiting", __FUNCTION__);
1546 }
1547 
1548 /*******************************************************************************
1549 **
1550 ** Function           USERIAL_Feature
1551 **
1552 ** Description        Check whether a feature of the serial API is supported.
1553 **
1554 ** Output Parameter   None
1555 **
1556 ** Returns            TRUE  if the feature is supported
1557 **                    FALSE if the feature is not supported
1558 **
1559 *******************************************************************************/
1560 
USERIAL_Feature(tUSERIAL_FEATURE feature)1561 UDRV_API BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE feature)
1562 {
1563     switch (feature)
1564     {
1565     case USERIAL_FEAT_PORT_1:
1566     case USERIAL_FEAT_PORT_2:
1567     case USERIAL_FEAT_PORT_3:
1568     case USERIAL_FEAT_PORT_4:
1569 
1570     case USERIAL_FEAT_BAUD_600:
1571     case USERIAL_FEAT_BAUD_1200:
1572     case USERIAL_FEAT_BAUD_9600:
1573     case USERIAL_FEAT_BAUD_19200:
1574     case USERIAL_FEAT_BAUD_57600:
1575     case USERIAL_FEAT_BAUD_115200:
1576 
1577     case USERIAL_FEAT_STOPBITS_1:
1578     case USERIAL_FEAT_STOPBITS_2:
1579 
1580     case USERIAL_FEAT_PARITY_NONE:
1581     case USERIAL_FEAT_PARITY_EVEN:
1582     case USERIAL_FEAT_PARITY_ODD:
1583 
1584     case USERIAL_FEAT_DATABITS_5:
1585     case USERIAL_FEAT_DATABITS_6:
1586     case USERIAL_FEAT_DATABITS_7:
1587     case USERIAL_FEAT_DATABITS_8:
1588 
1589     case USERIAL_FEAT_FC_HW:
1590     case USERIAL_FEAT_BUF_BYTE:
1591 
1592     case USERIAL_FEAT_OP_FLUSH_RX:
1593     case USERIAL_FEAT_OP_FLUSH_TX:
1594         return TRUE;
1595     default:
1596         return FALSE;
1597     }
1598 
1599     return FALSE;
1600 }
1601 
1602 /*****************************************************************************
1603 **
1604 ** Function         UPIO_Set
1605 **
1606 ** Description
1607 **      This function sets one or more GPIO devices to the given state.
1608 **      Multiple GPIOs of the same type can be masked together to set more
1609 **      than one GPIO. This function can only be used on types UPIO_LED and
1610 **      UPIO_GENERAL.
1611 **
1612 ** Input Parameters:
1613 **      type    The type of device.
1614 **      pio     Indicates the particular GPIOs.
1615 **      state   The desired state.
1616 **
1617 ** Output Parameter:
1618 **      None.
1619 **
1620 ** Returns:
1621 **      None.
1622 **
1623 *****************************************************************************/
UPIO_Set(tUPIO_TYPE type,tUPIO pio,tUPIO_STATE new_state)1624 UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE new_state)
1625 {
1626     int     ret;
1627     if (type == UPIO_GENERAL)
1628     {
1629         if (pio == NFC_HAL_LP_NFC_WAKE_GPIO)
1630         {
1631             if (new_state == UPIO_ON || new_state == UPIO_OFF)
1632             {
1633                 if (linux_cb.sock_power_control > 0)
1634                 {
1635                     ALOGD("%s: ioctl, state=%d", __func__, new_state);
1636                     ret = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, new_state);
1637                     if (isWake(new_state) && nfc_wake_delay > 0 && new_state != current_nfc_wake_state)
1638                     {
1639                         ALOGD("%s: ioctl, old state=%d, insert delay for %d ms", __func__, current_nfc_wake_state, nfc_wake_delay);
1640                         setWriteDelay(nfc_wake_delay);
1641                     }
1642                     current_nfc_wake_state = new_state;
1643                 }
1644             }
1645         }
1646     }
1647 }
1648 
1649 /*****************************************************************************
1650 **
1651 ** Function         setReadPacketSize
1652 **
1653 ** Description
1654 **      This function sets the packetSize to the driver.
1655 **      this enables faster read operation of NCI/HCI responses
1656 **
1657 ** Input Parameters:
1658 **      len     number of bytes to read per operation.
1659 **
1660 ** Output Parameter:
1661 **      None.
1662 **
1663 ** Returns:
1664 **      None.
1665 **
1666 *****************************************************************************/
setReadPacketSize(int len)1667 void setReadPacketSize(int len)
1668 {
1669     int ret;
1670     ALOGD("%s: ioctl, len=%d", __func__, len);
1671     ret = ioctl(linux_cb.sock, BCMNFC_READ_FULL_PACKET, len);
1672 }
1673 
1674 
USERIAL_IsClosed()1675 UDRV_API BOOLEAN USERIAL_IsClosed()
1676 {
1677     return (linux_cb.sock == -1) ? TRUE : FALSE;
1678 }
1679 
USERIAL_PowerupDevice(tUSERIAL_PORT port)1680 UDRV_API void USERIAL_PowerupDevice(tUSERIAL_PORT port)
1681 {
1682     int ret = -1;
1683     unsigned long num = 0;
1684     unsigned int resetSuccess = 0;
1685     unsigned int numTries = 0;
1686     unsigned char spi_negotiation[64];
1687     int delay = gPowerOnDelay;
1688     ALOGD("%s: enter", __FUNCTION__);
1689 
1690     if ( GetNumValue ( NAME_READ_MULTI_PACKETS, &num, sizeof ( num ) ) )
1691         bcmi2cnfc_read_multi_packets = num;
1692 
1693     if (bcmi2cnfc_read_multi_packets > 0)
1694         ioctl(linux_cb.sock, BCMNFC_READ_MULTI_PACKETS, bcmi2cnfc_read_multi_packets);
1695 
1696     while (!resetSuccess && numTries < NUM_RESET_ATTEMPTS) {
1697         if (numTries++ > 0) {
1698             ALOGW("BCM2079x: retrying reset, attempt %d/%d", numTries, NUM_RESET_ATTEMPTS);
1699         }
1700         if (linux_cb.sock_power_control > 0)
1701         {
1702             current_nfc_wake_state = NFC_WAKE_ASSERTED_ON_POR;
1703             ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, NFC_WAKE_ASSERTED_ON_POR);
1704             ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
1705             GKI_delay(10);
1706             ret = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 1);
1707         }
1708 
1709         ret = GetStrValue ( NAME_SPI_NEGOTIATION, (char*)spi_negotiation, sizeof ( spi_negotiation ) );
1710         if (ret > 0 && spi_negotiation[0] > 0 && spi_negotiation[0] < sizeof ( spi_negotiation ) - 1)
1711         {
1712             int len = spi_negotiation[0];
1713             /* Wake control is not available: Start SPI negotiation*/
1714             USERIAL_Write(port, &spi_negotiation[1], len);
1715             USERIAL_Read(port, spi_nego_res, sizeof ( spi_nego_res ));
1716         }
1717 
1718         if ( GetNumValue ( NAME_CLIENT_ADDRESS, &num, sizeof ( num ) ) )
1719             bcmi2cnfc_client_addr = num & 0xFF;
1720         if (bcmi2cnfc_client_addr != 0 &&
1721             0x07 < bcmi2cnfc_client_addr &&
1722             bcmi2cnfc_client_addr < 0x78)
1723         {
1724             /* Delay needed after turning on chip */
1725             GKI_delay(delay);
1726             ALOGD( "Change client address to %x\n", bcmi2cnfc_client_addr);
1727             ret = change_client_addr(bcmi2cnfc_client_addr);
1728             if (!ret) {
1729                 resetSuccess = 1;
1730                 linux_cb.client_device_address = bcmi2cnfc_client_addr;
1731                 /* Delay long enough for address change */
1732                 /* MACO xxx this needs to be at least 200 ms for BCM2079x B3 */
1733                 delay = 200;
1734             }
1735         } else {
1736             resetSuccess = 1;
1737         }
1738     }
1739 
1740     if (!resetSuccess) {
1741         ALOGE("BCM2079x: failed to initialize NFC controller");
1742     }
1743 
1744     GKI_delay(delay);
1745     ALOGD("%s: exit", __FUNCTION__);
1746 }
1747 
1748 #define DEFAULT_CLIENT_ADDRESS 0x77
1749 #define ALIAS_CLIENT_ADDRESS   0x79
change_client_addr(int addr)1750 static int change_client_addr(int addr)
1751 {
1752     int ret;
1753     int i;
1754     char addr_data[] = {
1755         0xFA, 0xF2, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2A
1756     };
1757     int size = sizeof(addr_data) - 1;
1758 
1759     addr_data[5] = addr & 0xFF;
1760 
1761     /* set the checksum */
1762     ret = 0;
1763     for (i = 1; i < size; ++i)
1764         ret += addr_data[i];
1765     addr_data[size] = (ret & 0xFF);
1766     ALOGD( "change_client_addr() change addr from 0x%x to 0x%x\n", DEFAULT_CLIENT_ADDRESS, addr);
1767     /* ignore the return code from IOCTL */
1768     /* always revert back to the default client address */
1769     ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, DEFAULT_CLIENT_ADDRESS);
1770     /* Send address change command (skipping first byte) */
1771     ret = TEMP_FAILURE_RETRY(write(linux_cb.sock, &addr_data[1], size));
1772 
1773     /* If it fails, it is likely a B3 we are talking to */
1774     if (ret != size) {
1775         ALOGD( "change_client_addr() change addr to 0x%x by setting BSP address to 0x%x\n", addr, ALIAS_CLIENT_ADDRESS);
1776         /* legacy kernel */
1777         /* MACO xxx commented out code below only works with new kernel driver,
1778          * but Mako/Manta ship with old one */
1779         ret = ioctl(linux_cb.sock, BCMNFC_CHANGE_ADDR, addr);
1780         return ret;
1781         /*
1782         ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, ALIAS_CLIENT_ADDRESS);
1783         size++;
1784         ret = write(linux_cb.sock, addr_data, size);
1785         */
1786     }
1787 
1788     if (ret == size) {
1789         ALOGD( "change_client_addr() set client address 0x%x to client driver\n", addr);
1790         ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, addr);
1791     }
1792     else {
1793         ret = -EIO;
1794     }
1795     return ret;
1796 }
1797