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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 607 void DispSNEP (UINT8 local_sap, UINT8 remote_sap, BT_HDR *p_buf, BOOLEAN is_first, BOOLEAN is_rx) {} 608 void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx) {} 609 void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx) {} 610 void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {} 611 void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {} 612 void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond) {} 613 void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv) {} 614