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 size_t actualRead = read (fileStream, pBuffer, nbytes);
114 if (actualRead > 0)
115 {
116 ALOGD ("%s: read bytes=%u", __FUNCTION__, actualRead);
117 nfa_nv_ci_read (actualRead, NFA_NV_CO_OK, block);
118 }
119 else
120 {
121 ALOGE ("%s: fail to read", __FUNCTION__);
122 nfa_nv_ci_read (actualRead, NFA_NV_CO_FAIL, block);
123 }
124 close (fileStream);
125 }
126 else
127 {
128 ALOGE ("%s: fail to open", __FUNCTION__);
129 nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
130 }
131 }
132
133 /*******************************************************************************
134 **
135 ** Function nfa_nv_co_write
136 **
137 ** Description This function is called by io to send file data to the
138 ** phone.
139 **
140 ** Parameters pBuffer - buffer to read the data from.
141 ** nbytes - number of bytes to write out to the file.
142 **
143 ** Returns void
144 **
145 ** Note: Upon completion of the request, nfa_nv_ci_write() is
146 ** called with the file descriptor and the status. The
147 ** call-in function should only be called when ALL requested
148 ** bytes have been written, or an error has been detected,
149 **
150 *******************************************************************************/
nfa_nv_co_write(const UINT8 * pBuffer,UINT16 nbytes,UINT8 block)151 NFC_API extern void nfa_nv_co_write(const UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
152 {
153 char filename[256], filename2[256];
154
155 memset (filename, 0, sizeof(filename));
156 memset (filename2, 0, sizeof(filename2));
157 strcpy(filename2, bcm_nfc_location);
158 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
159 if (strlen(filename2) > 200)
160 {
161 ALOGE ("%s: filename too long", __FUNCTION__);
162 return;
163 }
164 sprintf (filename, "%s%u", filename2, block);
165 ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
166
167 int fileStream = 0;
168
169 fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
170 if (fileStream >= 0)
171 {
172 size_t actualWritten = write (fileStream, pBuffer, nbytes);
173 ALOGD ("%s: %d bytes written", __FUNCTION__, actualWritten);
174 if (actualWritten > 0) {
175 nfa_nv_ci_write (NFA_NV_CO_OK);
176 }
177 else
178 {
179 ALOGE ("%s: fail to write", __FUNCTION__);
180 nfa_nv_ci_write (NFA_NV_CO_FAIL);
181 }
182 close (fileStream);
183 }
184 else
185 {
186 ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
187 nfa_nv_ci_write (NFA_NV_CO_FAIL);
188 }
189 }
190
191 /*******************************************************************************
192 **
193 ** Function delete_stack_non_volatile_store
194 **
195 ** Description Delete all the content of the stack's storage location.
196 **
197 ** Parameters none
198 **
199 ** Returns none
200 **
201 *******************************************************************************/
delete_stack_non_volatile_store()202 void delete_stack_non_volatile_store ()
203 {
204 static BOOLEAN firstTime = TRUE;
205 char filename[256], filename2[256];
206
207 if (firstTime == FALSE)
208 return;
209 firstTime = FALSE;
210
211 ALOGD ("%s", __FUNCTION__);
212
213 memset (filename, 0, sizeof(filename));
214 memset (filename2, 0, sizeof(filename2));
215 strcpy(filename2, bcm_nfc_location);
216 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
217 if (strlen(filename2) > 200)
218 {
219 ALOGE ("%s: filename too long", __FUNCTION__);
220 return;
221 }
222 sprintf (filename, "%s%u", filename2, DH_NV_BLOCK);
223 remove (filename);
224 sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK);
225 remove (filename);
226 sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK);
227 remove (filename);
228 sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK);
229 remove (filename);
230 }
231
232 /*******************************************************************************
233 **
234 ** Function byte2hex
235 **
236 ** Description convert a byte array to hexadecimal string
237 **
238 ** Returns:
239 ** Nothing
240 **
241 *******************************************************************************/
byte2hex(const char * data,char ** str)242 static inline void byte2hex(const char* data, char** str)
243 {
244 **str = sTable[(*data >> 4) & 0xf];
245 ++*str;
246 **str = sTable[*data & 0xf];
247 ++*str;
248 }
249
250 /*******************************************************************************
251 **
252 ** Function byte2char
253 **
254 ** Description convert a byte array to displayable text string
255 **
256 ** Returns:
257 ** Nothing
258 **
259 *******************************************************************************/
byte2char(const char * data,char ** str)260 static inline void byte2char(const char* data, char** str)
261 {
262 **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
263 ++(*str);
264 }
265
266 /*******************************************************************************
267 **
268 ** Function word2hex
269 **
270 ** Description Convert a two byte into text string as little-endian WORD
271 **
272 ** Returns:
273 ** Nothing
274 **
275 *******************************************************************************/
word2hex(const char * data,char ** hex)276 static inline void word2hex(const char* data, char** hex)
277 {
278 byte2hex(&data[1], hex);
279 byte2hex(&data[0], hex);
280 }
281
282 /*******************************************************************************
283 **
284 ** Function dumpbin
285 **
286 ** Description convert a byte array to a blob of text string for logging
287 **
288 ** Returns:
289 ** Nothing
290 **
291 *******************************************************************************/
dumpbin(const char * data,int size,UINT32 trace_layer,UINT32 trace_type)292 void dumpbin(const char* data, int size, UINT32 trace_layer, UINT32 trace_type)
293 {
294 char line_buff[256];
295 char *line;
296 int i, j, addr;
297 const int width = 16;
298 if(size <= 0)
299 return;
300 #ifdef __RAW_HEADER
301 //write offset
302 line = line_buff;
303 *line++ = ' ';
304 *line++ = ' ';
305 *line++ = ' ';
306 *line++ = ' ';
307 *line++ = ' ';
308 *line++ = ' ';
309 for(j = 0; j < width; j++)
310 {
311 byte2hex((const char*)&j, &line);
312 *line++ = ' ';
313 }
314 *line = 0;
315 PRINT(line_buff);
316 #endif
317 for(i = 0; i < size / width; i++)
318 {
319 line = line_buff;
320 //write address:
321 addr = i*width;
322 word2hex((const char*)&addr, &line);
323 *line++ = ':'; *line++ = ' ';
324 //write hex of data
325 for(j = 0; j < width; j++)
326 {
327 byte2hex(&data[j], &line);
328 *line++ = ' ';
329 }
330 //write char of data
331 for(j = 0; j < width; j++)
332 byte2char(data++, &line);
333 //wirte the end of line
334 *line = 0;
335 //output the line
336 PRINT(line_buff);
337 }
338 //last line of left over if any
339 int leftover = size % width;
340 if(leftover > 0)
341 {
342 line = line_buff;
343 //write address:
344 addr = i*width;
345 word2hex((const char*)&addr, &line);
346 *line++ = ':'; *line++ = ' ';
347 //write hex of data
348 for(j = 0; j < leftover; j++)
349 {
350 byte2hex(&data[j], &line);
351 *line++ = ' ';
352 }
353 //write hex padding
354 for(; j < width; j++)
355 {
356 *line++ = ' ';
357 *line++ = ' ';
358 *line++ = ' ';
359 }
360 //write char of data
361 for(j = 0; j < leftover; j++)
362 byte2char(data++, &line);
363 //write the end of line
364 *line = 0;
365 //output the line
366 PRINT(line_buff);
367 }
368 }
369
370 /*******************************************************************************
371 **
372 ** Function scru_dump_hex
373 **
374 ** Description print a text string to log
375 **
376 ** Returns:
377 ** text string
378 **
379 *******************************************************************************/
scru_dump_hex(UINT8 * p,char * pTitle,UINT32 len,UINT32 layer,UINT32 type)380 UINT8 *scru_dump_hex (UINT8 *p, char *pTitle, UINT32 len, UINT32 layer, UINT32 type)
381 {
382 if(pTitle && *pTitle)
383 PRINT(pTitle);
384 dumpbin(p, len, layer, type);
385 return p;
386 }
387
388 /*******************************************************************************
389 **
390 ** Function DispHciCmd
391 **
392 ** Description Display a HCI command string
393 **
394 ** Returns:
395 ** Nothing
396 **
397 *******************************************************************************/
DispHciCmd(BT_HDR * p_buf)398 void DispHciCmd (BT_HDR *p_buf)
399 {
400 int i,j;
401 int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
402 UINT8 * data = (UINT8*) p_buf;
403 int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
404
405 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
406 return;
407
408 if (nBytes > sizeof(log_line))
409 return;
410
411 for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
412 {
413 log_line[j++] = sTable[(*data >> 4) & 0xf];
414 log_line[j++] = sTable[*data & 0xf];
415 data++;
416 }
417 log_line[j] = '\0';
418
419 __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
420 }
421
422
423 /*******************************************************************************
424 **
425 ** Function DispHciEvt
426 **
427 ** Description display a NCI event
428 **
429 ** Returns:
430 ** Nothing
431 **
432 *******************************************************************************/
DispHciEvt(BT_HDR * p_buf)433 void DispHciEvt (BT_HDR *p_buf)
434 {
435 int i,j;
436 int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
437 UINT8 * data = (UINT8*) p_buf;
438 int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
439
440 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
441 return;
442
443 if (nBytes > sizeof(log_line))
444 return;
445
446 for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
447 {
448 log_line[j++] = sTable[(*data >> 4) & 0xf];
449 log_line[j++] = sTable[*data & 0xf];
450 data++;
451 }
452 log_line[j] = '\0';
453
454 __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
455 }
456
457 /*******************************************************************************
458 **
459 ** Function DispNciDump
460 **
461 ** Description Log raw NCI packet as hex-ascii bytes
462 **
463 ** Returns None.
464 **
465 *******************************************************************************/
DispNciDump(UINT8 * data,UINT16 len,BOOLEAN is_recv)466 void DispNciDump (UINT8 *data, UINT16 len, BOOLEAN is_recv)
467 {
468 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI))
469 return;
470
471 char line_buf[(MAX_NCI_PACKET_SIZE*2)+1];
472 int i,j;
473
474 for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
475 {
476 line_buf[j++] = sTable[(*data >> 4) & 0xf];
477 line_buf[j++] = sTable[*data & 0xf];
478 data++;
479 }
480 line_buf[j] = '\0';
481
482 __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
483 }
484
485
486 /*******************************************************************************
487 **
488 ** Function DispLLCP
489 **
490 ** Description Log raw LLCP packet as hex-ascii bytes
491 **
492 ** Returns None.
493 **
494 *******************************************************************************/
DispLLCP(BT_HDR * p_buf,BOOLEAN is_recv)495 void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv)
496 {
497 int i,j;
498 int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
499 UINT8 * data = (UINT8*) p_buf;
500 int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
501
502 if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
503 return;
504
505 for (i = 0; i < data_len; )
506 {
507 for(j = 0; i < data_len && j < sizeof(log_line)-3; i++)
508 {
509 log_line[j++] = sTable[(*data >> 4) & 0xf];
510 log_line[j++] = sTable[*data & 0xf];
511 data++;
512 }
513 log_line[j] = '\0';
514 __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmLlcpR": "BrcmLlcpX", log_line);
515 }
516 }
517
518
519 /*******************************************************************************
520 **
521 ** Function DispHcp
522 **
523 ** Description Log raw HCP packet as hex-ascii bytes
524 **
525 ** Returns None.
526 **
527 *******************************************************************************/
DispHcp(UINT8 * data,UINT16 len,BOOLEAN is_recv)528 void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv)
529 {
530 int i,j;
531 int nBytes = (len*2)+1;
532 char line_buf[400];
533
534 if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
535 return;
536
537 if (nBytes > sizeof(line_buf))
538 return;
539
540 // Only trace HCP if we're tracing HCI as well
541 if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
542 return;
543
544 for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
545 {
546 line_buf[j++] = sTable[(*data >> 4) & 0xf];
547 line_buf[j++] = sTable[*data & 0xf];
548 data++;
549 }
550 line_buf[j] = '\0';
551
552 __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmHcpR": "BrcmHcpX", line_buf);
553 }
554
DispSNEP(UINT8 local_sap,UINT8 remote_sap,BT_HDR * p_buf,BOOLEAN is_first,BOOLEAN is_rx)555 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)556 void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx) {}
DispT3TagMessage(BT_HDR * p_msg,BOOLEAN is_rx)557 void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx) {}
DispRWT4Tags(BT_HDR * p_buf,BOOLEAN is_rx)558 void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
DispCET4Tags(BT_HDR * p_buf,BOOLEAN is_rx)559 void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
DispRWI93Tag(BT_HDR * p_buf,BOOLEAN is_rx,UINT8 command_to_respond)560 void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond) {}
DispNDEFMsg(UINT8 * pMsg,UINT32 MsgLen,BOOLEAN is_recv)561 void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv) {}
562