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