1 /******************************************************************************
2 *
3 * Copyright (C) 2011-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 #include "OverrideLog.h"
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include "buildcfg.h"
24 #include "nfa_mem_co.h"
25 #include "nfa_nv_co.h"
26 #include "nfa_nv_ci.h"
27 #include "config.h"
28 #include "nfc_hal_nv_co.h"
29
30 #define LOG_TAG "BrcmNfcNfa"
31 #define PRINT(s) __android_log_write(ANDROID_LOG_DEBUG, "BrcmNci", s)
32 #define MAX_NCI_PACKET_SIZE 259
33 #define MAX_LOGCAT_LINE 4096
34 static char log_line[MAX_LOGCAT_LINE];
35
36 extern UINT32 ScrProtocolTraceFlag; // = SCR_PROTO_TRACE_ALL; // 0x017F;
37 static const char* sTable = "0123456789abcdef";
38 extern char bcm_nfc_location[];
39 static const char* sNfaStorageBin = "/nfaStorage.bin";
40
41 /*******************************************************************************
42 **
43 ** Function nfa_mem_co_alloc
44 **
45 ** Description allocate a buffer from platform's memory pool
46 **
47 ** Returns:
48 ** pointer to buffer if successful
49 ** NULL otherwise
50 **
51 *******************************************************************************/
nfa_mem_co_alloc(UINT32 num_bytes)52 NFC_API extern void *nfa_mem_co_alloc(UINT32 num_bytes)
53 {
54 return malloc(num_bytes);
55 }
56
57
58 /*******************************************************************************
59 **
60 ** Function nfa_mem_co_free
61 **
62 ** Description free buffer previously allocated using nfa_mem_co_alloc
63 **
64 ** Returns:
65 ** Nothing
66 **
67 *******************************************************************************/
nfa_mem_co_free(void * pBuffer)68 NFC_API extern void nfa_mem_co_free(void *pBuffer)
69 {
70 free(pBuffer);
71 }
72
73
74 /*******************************************************************************
75 **
76 ** Function nfa_nv_co_read
77 **
78 ** Description This function is called by NFA to read in data from the
79 ** previously opened file.
80 **
81 ** Parameters pBuffer - buffer to read the data into.
82 ** nbytes - number of bytes to read into the buffer.
83 **
84 ** Returns void
85 **
86 ** Note: Upon completion of the request, nfa_nv_ci_read() is
87 ** called with the buffer of data, along with the number
88 ** of bytes read into the buffer, and a status. The
89 ** call-in function should only be called when ALL requested
90 ** bytes have been read, the end of file has been detected,
91 ** or an error has occurred.
92 **
93 *******************************************************************************/
nfa_nv_co_read(UINT8 * pBuffer,UINT16 nbytes,UINT8 block)94 NFC_API extern void nfa_nv_co_read(UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
95 {
96 char filename[256], filename2[256];
97
98 memset (filename, 0, sizeof(filename));
99 memset (filename2, 0, sizeof(filename2));
100 strcpy(filename2, bcm_nfc_location);
101 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
102 if (strlen(filename2) > 200)
103 {
104 ALOGE ("%s: filename too long", __FUNCTION__);
105 return;
106 }
107 sprintf (filename, "%s%u", filename2, block);
108
109 ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
110 int fileStream = open (filename, O_RDONLY);
111 if (fileStream >= 0)
112 {
113 unsigned short checksum = 0;
114 size_t actualReadCrc = read (fileStream, &checksum, sizeof(checksum));
115 size_t actualReadData = read (fileStream, pBuffer, nbytes);
116 close (fileStream);
117 if (actualReadData > 0)
118 {
119 ALOGD ("%s: data size=%u", __FUNCTION__, actualReadData);
120 nfa_nv_ci_read (actualReadData, NFA_NV_CO_OK, block);
121 }
122 else
123 {
124 ALOGE ("%s: fail to read", __FUNCTION__);
125 nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
126 }
127 }
128 else
129 {
130 ALOGD ("%s: fail to open", __FUNCTION__);
131 nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
132 }
133 }
134
135 /*******************************************************************************
136 **
137 ** Function nfa_nv_co_write
138 **
139 ** Description This function is called by io to send file data to the
140 ** phone.
141 **
142 ** Parameters pBuffer - buffer to read the data from.
143 ** nbytes - number of bytes to write out to the file.
144 **
145 ** Returns void
146 **
147 ** Note: Upon completion of the request, nfa_nv_ci_write() is
148 ** called with the file descriptor and the status. The
149 ** call-in function should only be called when ALL requested
150 ** bytes have been written, or an error has been detected,
151 **
152 *******************************************************************************/
nfa_nv_co_write(const UINT8 * pBuffer,UINT16 nbytes,UINT8 block)153 NFC_API extern void nfa_nv_co_write(const UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
154 {
155 char filename[256], filename2[256];
156
157 memset (filename, 0, sizeof(filename));
158 memset (filename2, 0, sizeof(filename2));
159 strcpy(filename2, bcm_nfc_location);
160 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
161 if (strlen(filename2) > 200)
162 {
163 ALOGE ("%s: filename too long", __FUNCTION__);
164 return;
165 }
166 sprintf (filename, "%s%u", filename2, block);
167 ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
168
169 int fileStream = 0;
170
171 fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
172 if (fileStream >= 0)
173 {
174 unsigned short checksum = crcChecksumCompute (pBuffer, nbytes);
175 size_t actualWrittenCrc = write (fileStream, &checksum, sizeof(checksum));
176 size_t actualWrittenData = write (fileStream, pBuffer, nbytes);
177 ALOGD ("%s: %d bytes written", __FUNCTION__, actualWrittenData);
178 if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum)))
179 {
180 nfa_nv_ci_write (NFA_NV_CO_OK);
181 }
182 else
183 {
184 ALOGE ("%s: fail to write", __FUNCTION__);
185 nfa_nv_ci_write (NFA_NV_CO_FAIL);
186 }
187 close (fileStream);
188 }
189 else
190 {
191 ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
192 nfa_nv_ci_write (NFA_NV_CO_FAIL);
193 }
194 }
195
196 /*******************************************************************************
197 **
198 ** Function delete_stack_non_volatile_store
199 **
200 ** Description Delete all the content of the stack's storage location.
201 **
202 ** Parameters forceDelete: unconditionally delete the storage.
203 **
204 ** Returns none
205 **
206 *******************************************************************************/
delete_stack_non_volatile_store(BOOLEAN forceDelete)207 void delete_stack_non_volatile_store (BOOLEAN forceDelete)
208 {
209 static BOOLEAN firstTime = TRUE;
210 char filename[256], filename2[256];
211
212 if ((firstTime == FALSE) && (forceDelete == FALSE))
213 return;
214 firstTime = FALSE;
215
216 ALOGD ("%s", __FUNCTION__);
217
218 memset (filename, 0, sizeof(filename));
219 memset (filename2, 0, sizeof(filename2));
220 strcpy(filename2, bcm_nfc_location);
221 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
222 if (strlen(filename2) > 200)
223 {
224 ALOGE ("%s: filename too long", __FUNCTION__);
225 return;
226 }
227 sprintf (filename, "%s%u", filename2, DH_NV_BLOCK);
228 remove (filename);
229 sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK);
230 remove (filename);
231 sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK);
232 remove (filename);
233 sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK);
234 remove (filename);
235 }
236
237 /*******************************************************************************
238 **
239 ** Function verify_stack_non_volatile_store
240 **
241 ** Description Verify the content of all non-volatile store.
242 **
243 ** Parameters none
244 **
245 ** Returns none
246 **
247 *******************************************************************************/
verify_stack_non_volatile_store()248 void verify_stack_non_volatile_store ()
249 {
250 ALOGD ("%s", __FUNCTION__);
251 char filename[256], filename2[256];
252 BOOLEAN isValid = FALSE;
253
254 memset (filename, 0, sizeof(filename));
255 memset (filename2, 0, sizeof(filename2));
256 strcpy(filename2, bcm_nfc_location);
257 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
258 if (strlen(filename2) > 200)
259 {
260 ALOGE ("%s: filename too long", __FUNCTION__);
261 return;
262 }
263
264 sprintf (filename, "%s%u", filename2, DH_NV_BLOCK);
265 if (crcChecksumVerifyIntegrity (filename))
266 {
267 sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK);
268 if (crcChecksumVerifyIntegrity (filename))
269 {
270 sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK);
271 if (crcChecksumVerifyIntegrity (filename))
272 {
273 sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK);
274 if (crcChecksumVerifyIntegrity (filename))
275 isValid = TRUE;
276 }
277 }
278 }
279
280 if (isValid == FALSE)
281 delete_stack_non_volatile_store (TRUE);
282 }
283
284 /*******************************************************************************
285 **
286 ** Function byte2hex
287 **
288 ** Description convert a byte array to hexadecimal string
289 **
290 ** Returns:
291 ** Nothing
292 **
293 *******************************************************************************/
byte2hex(const char * data,char ** str)294 static inline void byte2hex(const char* data, char** str)
295 {
296 **str = sTable[(*data >> 4) & 0xf];
297 ++*str;
298 **str = sTable[*data & 0xf];
299 ++*str;
300 }
301
302 /*******************************************************************************
303 **
304 ** Function byte2char
305 **
306 ** Description convert a byte array to displayable text string
307 **
308 ** Returns:
309 ** Nothing
310 **
311 *******************************************************************************/
byte2char(const char * data,char ** str)312 static inline void byte2char(const char* data, char** str)
313 {
314 **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
315 ++(*str);
316 }
317
318 /*******************************************************************************
319 **
320 ** Function word2hex
321 **
322 ** Description Convert a two byte into text string as little-endian WORD
323 **
324 ** Returns:
325 ** Nothing
326 **
327 *******************************************************************************/
word2hex(const char * data,char ** hex)328 static inline void word2hex(const char* data, char** hex)
329 {
330 byte2hex(&data[1], hex);
331 byte2hex(&data[0], hex);
332 }
333
334 /*******************************************************************************
335 **
336 ** Function dumpbin
337 **
338 ** Description convert a byte array to a blob of text string for logging
339 **
340 ** Returns:
341 ** Nothing
342 **
343 *******************************************************************************/
dumpbin(const char * data,int size,UINT32 trace_layer,UINT32 trace_type)344 void dumpbin(const char* data, int size, UINT32 trace_layer, UINT32 trace_type)
345 {
346 char line_buff[256];
347 char *line;
348 int i, j, addr;
349 const int width = 16;
350 if(size <= 0)
351 return;
352 #ifdef __RAW_HEADER
353 //write offset
354 line = line_buff;
355 *line++ = ' ';
356 *line++ = ' ';
357 *line++ = ' ';
358 *line++ = ' ';
359 *line++ = ' ';
360 *line++ = ' ';
361 for(j = 0; j < width; j++)
362 {
363 byte2hex((const char*)&j, &line);
364 *line++ = ' ';
365 }
366 *line = 0;
367 PRINT(line_buff);
368 #endif
369 for(i = 0; i < size / width; i++)
370 {
371 line = line_buff;
372 //write address:
373 addr = i*width;
374 word2hex((const char*)&addr, &line);
375 *line++ = ':'; *line++ = ' ';
376 //write hex of data
377 for(j = 0; j < width; j++)
378 {
379 byte2hex(&data[j], &line);
380 *line++ = ' ';
381 }
382 //write char of data
383 for(j = 0; j < width; j++)
384 byte2char(data++, &line);
385 //wirte the end of line
386 *line = 0;
387 //output the line
388 PRINT(line_buff);
389 }
390 //last line of left over if any
391 int leftover = size % width;
392 if(leftover > 0)
393 {
394 line = line_buff;
395 //write address:
396 addr = i*width;
397 word2hex((const char*)&addr, &line);
398 *line++ = ':'; *line++ = ' ';
399 //write hex of data
400 for(j = 0; j < leftover; j++)
401 {
402 byte2hex(&data[j], &line);
403 *line++ = ' ';
404 }
405 //write hex padding
406 for(; j < width; j++)
407 {
408 *line++ = ' ';
409 *line++ = ' ';
410 *line++ = ' ';
411 }
412 //write char of data
413 for(j = 0; j < leftover; j++)
414 byte2char(data++, &line);
415 //write the end of line
416 *line = 0;
417 //output the line
418 PRINT(line_buff);
419 }
420 }
421
422 /*******************************************************************************
423 **
424 ** Function scru_dump_hex
425 **
426 ** Description print a text string to log
427 **
428 ** Returns:
429 ** text string
430 **
431 *******************************************************************************/
scru_dump_hex(UINT8 * p,char * pTitle,UINT32 len,UINT32 layer,UINT32 type)432 UINT8 *scru_dump_hex (UINT8 *p, char *pTitle, UINT32 len, UINT32 layer, UINT32 type)
433 {
434 if(pTitle && *pTitle)
435 PRINT(pTitle);
436 dumpbin(p, len, layer, type);
437 return p;
438 }
439
440 /*******************************************************************************
441 **
442 ** Function DispHciCmd
443 **
444 ** Description Display a HCI command string
445 **
446 ** Returns:
447 ** Nothing
448 **
449 *******************************************************************************/
DispHciCmd(BT_HDR * p_buf)450 void DispHciCmd (BT_HDR *p_buf)
451 {
452 int i,j;
453 int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
454 UINT8 * data = (UINT8*) p_buf;
455 int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
456
457 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
458 return;
459
460 if (nBytes > sizeof(log_line))
461 return;
462
463 for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
464 {
465 log_line[j++] = sTable[(*data >> 4) & 0xf];
466 log_line[j++] = sTable[*data & 0xf];
467 data++;
468 }
469 log_line[j] = '\0';
470
471 __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
472 }
473
474
475 /*******************************************************************************
476 **
477 ** Function DispHciEvt
478 **
479 ** Description display a NCI event
480 **
481 ** Returns:
482 ** Nothing
483 **
484 *******************************************************************************/
DispHciEvt(BT_HDR * p_buf)485 void DispHciEvt (BT_HDR *p_buf)
486 {
487 int i,j;
488 int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
489 UINT8 * data = (UINT8*) p_buf;
490 int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
491
492 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
493 return;
494
495 if (nBytes > sizeof(log_line))
496 return;
497
498 for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
499 {
500 log_line[j++] = sTable[(*data >> 4) & 0xf];
501 log_line[j++] = sTable[*data & 0xf];
502 data++;
503 }
504 log_line[j] = '\0';
505
506 __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
507 }
508
509 /*******************************************************************************
510 **
511 ** Function DispNciDump
512 **
513 ** Description Log raw NCI packet as hex-ascii bytes
514 **
515 ** Returns None.
516 **
517 *******************************************************************************/
DispNciDump(UINT8 * data,UINT16 len,BOOLEAN is_recv)518 void DispNciDump (UINT8 *data, UINT16 len, BOOLEAN is_recv)
519 {
520 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI))
521 return;
522
523 char line_buf[(MAX_NCI_PACKET_SIZE*2)+1];
524 int i,j;
525
526 for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
527 {
528 line_buf[j++] = sTable[(*data >> 4) & 0xf];
529 line_buf[j++] = sTable[*data & 0xf];
530 data++;
531 }
532 line_buf[j] = '\0';
533
534 __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
535 }
536
537
538 /*******************************************************************************
539 **
540 ** Function DispLLCP
541 **
542 ** Description Log raw LLCP packet as hex-ascii bytes
543 **
544 ** Returns None.
545 **
546 *******************************************************************************/
DispLLCP(BT_HDR * p_buf,BOOLEAN is_recv)547 void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv)
548 {
549 int i,j;
550 int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
551 UINT8 * data = (UINT8*) p_buf;
552 int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
553
554 if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
555 return;
556
557 for (i = 0; i < data_len; )
558 {
559 for(j = 0; i < data_len && j < sizeof(log_line)-3; i++)
560 {
561 log_line[j++] = sTable[(*data >> 4) & 0xf];
562 log_line[j++] = sTable[*data & 0xf];
563 data++;
564 }
565 log_line[j] = '\0';
566 __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmLlcpR": "BrcmLlcpX", log_line);
567 }
568 }
569
570
571 /*******************************************************************************
572 **
573 ** Function DispHcp
574 **
575 ** Description Log raw HCP packet as hex-ascii bytes
576 **
577 ** Returns None.
578 **
579 *******************************************************************************/
DispHcp(UINT8 * data,UINT16 len,BOOLEAN is_recv)580 void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv)
581 {
582 int i,j;
583 int nBytes = (len*2)+1;
584 char line_buf[400];
585
586 if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
587 return;
588
589 if (nBytes > sizeof(line_buf))
590 return;
591
592 // Only trace HCP if we're tracing HCI as well
593 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
594 return;
595
596 for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
597 {
598 line_buf[j++] = sTable[(*data >> 4) & 0xf];
599 line_buf[j++] = sTable[*data & 0xf];
600 data++;
601 }
602 line_buf[j] = '\0';
603
604 __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmHcpR": "BrcmHcpX", line_buf);
605 }
606
DispSNEP(UINT8 local_sap,UINT8 remote_sap,BT_HDR * p_buf,BOOLEAN is_first,BOOLEAN is_rx)607 void DispSNEP (UINT8 local_sap, UINT8 remote_sap, BT_HDR *p_buf, BOOLEAN is_first, BOOLEAN is_rx) {}
DispCHO(UINT8 * pMsg,UINT32 MsgLen,BOOLEAN is_rx)608 void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx) {}
DispT3TagMessage(BT_HDR * p_msg,BOOLEAN is_rx)609 void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx) {}
DispRWT4Tags(BT_HDR * p_buf,BOOLEAN is_rx)610 void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
DispCET4Tags(BT_HDR * p_buf,BOOLEAN is_rx)611 void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
DispRWI93Tag(BT_HDR * p_buf,BOOLEAN is_rx,UINT8 command_to_respond)612 void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond) {}
DispNDEFMsg(UINT8 * pMsg,UINT32 MsgLen,BOOLEAN is_recv)613 void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv) {}
614