libmain.c revision 993437a401849447dfaabc2edf53e682e056a5a4
1/****************************************************************************
2**
3**  Name:       libmain.h
4**
5**  Function    This file contains helper functions for NFA
6**
7**  Copyright (c) 2011-2012, Broadcom Corp., All Rights Reserved.
8**  Broadcom Bluetooth Core. Proprietary and confidential.
9**
10*****************************************************************************/
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <fcntl.h>
14#include <errno.h>
15#include "buildcfg.h"
16#include "nfa_mem_co.h"
17#include "nfa_nv_co.h"
18#include "nfa_nv_ci.h"
19#include <cutils/log.h>
20#include "config.h"
21
22#define LOG_TAG "BrcmNfcNfa"
23#define PRINT(s) __android_log_write(ANDROID_LOG_DEBUG, "BrcmNci", s)
24#define MAX_NCI_PACKET_SIZE  259
25
26extern UINT32 ScrProtocolTraceFlag;         // = SCR_PROTO_TRACE_ALL; // 0x017F;
27static const char* sTable = "0123456789abcdef";
28extern char bcm_nfc_location[];
29
30/*******************************************************************************
31**
32** Function         nfa_mem_co_alloc
33**
34** Description      allocate a buffer from platform's memory pool
35**
36** Returns:
37**                  pointer to buffer if successful
38**                  NULL otherwise
39**
40*******************************************************************************/
41NFC_API extern void *nfa_mem_co_alloc(UINT32 num_bytes)
42{
43    return malloc(num_bytes);
44}
45
46
47/*******************************************************************************
48**
49** Function         nfa_mem_co_free
50**
51** Description      free buffer previously allocated using nfa_mem_co_alloc
52**
53** Returns:
54**                  Nothing
55**
56*******************************************************************************/
57NFC_API extern void nfa_mem_co_free(void *pBuffer)
58{
59    free(pBuffer);
60}
61
62/*******************************************************************************
63**
64** Function         nfa_nv_co_init
65**
66** Description      This function is executed as a part of the start up sequence
67**                  to make sure the control block is initialized.
68**
69** Parameters       void.
70**
71** Returns          void
72**
73**
74*******************************************************************************/
75NFC_API extern void nfa_nv_co_init(void)
76{
77    ALOGD ("%s: enter/exit ", __FUNCTION__);
78}
79
80/*******************************************************************************
81**
82** Function         nfa_nv_co_read
83**
84** Description      This function is called by NFA to read in data from the
85**                  previously opened file.
86**
87** Parameters       pBuffer   - buffer to read the data into.
88**                  nbytes  - number of bytes to read into the buffer.
89**
90** Returns          void
91**
92**                  Note: Upon completion of the request, nfa_nv_ci_read() is
93**                        called with the buffer of data, along with the number
94**                        of bytes read into the buffer, and a status.  The
95**                        call-in function should only be called when ALL requested
96**                        bytes have been read, the end of file has been detected,
97**                        or an error has occurred.
98**
99*******************************************************************************/
100NFC_API extern void nfa_nv_co_read(UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
101{
102    char filename[256], filename2[256];
103    strcpy(filename2, bcm_nfc_location);
104    strcat(filename2, "/nfaStorage.bin");
105    if (strlen(filename2) > 200)
106    {
107        ALOGE ("%s: filename too long", __FUNCTION__);
108        return;
109    }
110    sprintf (filename, "%s%u", filename2, block);
111
112    ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
113    int fileStream = open (filename, O_RDONLY);
114    if (fileStream > 0)
115    {
116        size_t actualRead = read (fileStream, pBuffer, nbytes);
117        if (actualRead > 0)
118        {
119            ALOGD ("%s: read bytes=%u", __FUNCTION__, actualRead);
120            nfa_nv_ci_read (actualRead, NFA_NV_CO_OK, block);
121        }
122        else
123        {
124            ALOGE ("%s: fail to read", __FUNCTION__);
125            nfa_nv_ci_read (actualRead, NFA_NV_CO_FAIL, block);
126        }
127        close (fileStream);
128    }
129    else
130    {
131        ALOGE ("%s: fail to open", __FUNCTION__);
132        nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
133    }
134}
135
136/*******************************************************************************
137**
138** Function         nfa_nv_co_write
139**
140** Description      This function is called by io to send file data to the
141**                  phone.
142**
143** Parameters       pBuffer   - buffer to read the data from.
144**                  nbytes  - number of bytes to write out to the file.
145**
146** Returns          void
147**
148**                  Note: Upon completion of the request, nfa_nv_ci_write() is
149**                        called with the file descriptor and the status.  The
150**                        call-in function should only be called when ALL requested
151**                        bytes have been written, or an error has been detected,
152**
153*******************************************************************************/
154NFC_API extern void nfa_nv_co_write(const UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
155{
156    char filename[256], filename2[256];
157    strcpy(filename2, bcm_nfc_location);
158    strcat(filename2, "/nfaStorage.bin");
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         byte2hex
194**
195** Description      convert a byte array to hexadecimal string
196**
197** Returns:
198**                  Nothing
199**
200*******************************************************************************/
201static inline void byte2hex(const char* data, char** str)
202{
203    **str = sTable[(*data >> 4) & 0xf];
204    ++*str;
205    **str = sTable[*data & 0xf];
206    ++*str;
207}
208
209/*******************************************************************************
210**
211** Function         byte2char
212**
213** Description      convert a byte array to displayable text string
214**
215** Returns:
216**                  Nothing
217**
218*******************************************************************************/
219static inline void byte2char(const char* data, char** str)
220{
221    **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
222    ++(*str);
223}
224
225/*******************************************************************************
226**
227** Function         word2hex
228**
229** Description      Convert a two byte into text string as little-endian WORD
230**
231** Returns:
232**                  Nothing
233**
234*******************************************************************************/
235static inline void word2hex(const char* data, char** hex)
236{
237    byte2hex(&data[1], hex);
238    byte2hex(&data[0], hex);
239}
240
241/*******************************************************************************
242**
243** Function         dumpbin
244**
245** Description      convert a byte array to a blob of text string for logging
246**
247** Returns:
248**                  Nothing
249**
250*******************************************************************************/
251void dumpbin(const char* data, int size, UINT32 trace_layer, UINT32 trace_type)
252{
253    char line_buff[256];
254    char *line;
255    int i, j, addr;
256    const int width = 16;
257    if(size <= 0)
258        return;
259#ifdef __RAW_HEADER
260    //write offset
261    line = line_buff;
262    *line++ = ' ';
263    *line++ = ' ';
264    *line++ = ' ';
265    *line++ = ' ';
266    *line++ = ' ';
267    *line++ = ' ';
268    for(j = 0; j < width; j++)
269    {
270        byte2hex((const char*)&j, &line);
271        *line++ = ' ';
272    }
273    *line = 0;
274    PRINT(line_buff);
275#endif
276    for(i = 0; i < size / width; i++)
277    {
278        line = line_buff;
279        //write address:
280        addr = i*width;
281        word2hex((const char*)&addr, &line);
282        *line++ = ':'; *line++ = ' ';
283        //write hex of data
284        for(j = 0; j < width; j++)
285        {
286            byte2hex(&data[j], &line);
287            *line++ = ' ';
288        }
289        //write char of data
290        for(j = 0; j < width; j++)
291            byte2char(data++, &line);
292        //wirte the end of line
293        *line = 0;
294        //output the line
295        PRINT(line_buff);
296    }
297    //last line of left over if any
298    int leftover = size % width;
299    if(leftover > 0)
300    {
301        line = line_buff;
302        //write address:
303        addr = i*width;
304        word2hex((const char*)&addr, &line);
305        *line++ = ':'; *line++ = ' ';
306        //write hex of data
307        for(j = 0; j < leftover; j++)
308        {
309            byte2hex(&data[j], &line);
310            *line++ = ' ';
311        }
312        //write hex padding
313        for(; j < width; j++)
314        {
315            *line++ = ' ';
316            *line++ = ' ';
317            *line++ = ' ';
318        }
319        //write char of data
320        for(j = 0; j < leftover; j++)
321            byte2char(data++, &line);
322        //write the end of line
323        *line = 0;
324        //output the line
325        PRINT(line_buff);
326    }
327}
328
329/*******************************************************************************
330**
331** Function         scru_dump_hex
332**
333** Description      print a text string to log
334**
335** Returns:
336**                  text string
337**
338*******************************************************************************/
339UINT8 *scru_dump_hex (UINT8 *p, char *pTitle, UINT32 len, UINT32 layer, UINT32 type)
340{
341    if(pTitle && *pTitle)
342        PRINT(pTitle);
343    dumpbin(p, len, layer, type);
344    return p;
345}
346
347/*******************************************************************************
348**
349** Function         DispHciCmd
350**
351** Description      Display a HCI command string
352**
353** Returns:
354**                  Nothing
355**
356*******************************************************************************/
357void DispHciCmd (BT_HDR *pBuffer)
358{
359    UINT8   *p = (UINT8 *)(pBuffer + 1) + pBuffer->offset;
360
361    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
362        return;
363}
364
365
366/*******************************************************************************
367**
368** Function         DispHciEvt
369**
370** Description      display a NCI event
371**
372** Returns:
373**                  Nothing
374**
375*******************************************************************************/
376void DispHciEvt (BT_HDR *pBuffer)
377{
378    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
379        return;
380}
381
382/*******************************************************************************
383**
384** Function         DispNciDump
385**
386** Description      Log raw NCI packet as hex-ascii bytes
387**
388** Returns          None.
389**
390*******************************************************************************/
391void DispNciDump (UINT8 *data, UINT16 len, BOOLEAN is_recv)
392{
393    char line_buf[(MAX_NCI_PACKET_SIZE*2)+1];
394    int i,j;
395
396    for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
397    {
398        line_buf[j++] = sTable[(*data >> 4) & 0xf];
399        line_buf[j++] = sTable[*data & 0xf];
400        data++;
401    }
402    line_buf[j] = '\0';
403
404    __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
405}
406