blob: e906b0dea9ec50696e67624d8495658acc25527e [file] [log] [blame]
Nick Pelly5d9927b2010-09-23 12:47:58 -07001/*
2 * Copyright (C) 2010 NXP Semiconductors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18 * \file phOsalNfc.c
19 * \brief OSAL Implementation for linux
20 *
21 * Project: Trusted NFC Linux Light
22 *
23 * $Date: 03 aug 2009
24 * $Author: Jérémie Corbier
25 * $Revision: 1.0
26 *
27 */
28
29#include <stddef.h>
30#include <stdlib.h>
31#include <stdio.h>
32#include <signal.h>
33#include <unistd.h>
34
35#include <phOsalNfc.h>
36
37#ifdef ANDROID
38#define LOG_TAG "NFC-HCI"
39
40#include <utils/Log.h>
41
42phOsalNfc_Exception_t phOsalNfc_Exception;
43#endif
44
45#ifdef DEBUG
46#define MAX_PRINT_BUFSIZE (0x450U)
47char phOsalNfc_DbgTraceBuffer[MAX_PRINT_BUFSIZE];
48#endif
49
Sunil Jogi82063252012-04-10 11:37:25 -070050void phLibNfc_Mgt_Recovery();
51
Nick Pelly5d9927b2010-09-23 12:47:58 -070052/*!
53 * \brief Allocates memory.
54 * This function attempts to allocate \a size bytes on the heap and
55 * returns a pointer to the allocated block.
56 *
57 * \param size size of the memory block to be allocated on the heap.
58 *
59 * \return pointer to allocated memory block or NULL in case of error.
60 */
61void *phOsalNfc_GetMemory(uint32_t size)
62{
63 void *pMem = (void *)malloc(size);
64 return pMem;
65}
66
67/*!
68 * \brief Frees allocated memory block.
69 * This function deallocates memory region pointed to by \a pMem.
70 *
71 * \param pMem pointer to memory block to be freed.
72 */
73void phOsalNfc_FreeMemory(void *pMem)
74{
75 if(NULL != pMem)
76 free(pMem);
77}
78
79void phOsalNfc_DbgString(const char *pString)
80{
81#ifdef DEBUG
82 if(pString != NULL)
83#ifndef ANDROID
84 printf(pString);
85#else
Steve Block1f23e482011-12-20 16:20:37 +000086 ALOGD("%s", pString);
Nick Pelly5d9927b2010-09-23 12:47:58 -070087#endif
88#endif
89}
90
91void phOsalNfc_DbgTrace(uint8_t data[], uint32_t size)
92{
93#ifdef DEBUG
94 uint32_t i;
95#ifdef ANDROID
96 char buf[10];
97#endif
98
99 if(size == 0)
100 return;
101
102#ifndef ANDROID
103 for(i = 0; i < size; i++)
104 {
105 if((i % 10) == 0)
106 printf("\n\t\t\t");
107 printf("%02X ", data[i]);
108 }
109 printf("\n\tBlock size is: %d\n", size);
110#else
111 phOsalNfc_DbgTraceBuffer[0] = '\0';
112 for(i = 0; i < size; i++)
113 {
114 if((i % 10) == 0)
115 {
Steve Block1f23e482011-12-20 16:20:37 +0000116 ALOGD("%s", phOsalNfc_DbgTraceBuffer);
Nick Pelly5d9927b2010-09-23 12:47:58 -0700117 phOsalNfc_DbgTraceBuffer[0] = '\0';
118 }
119
120 snprintf(buf, 10, "%02X ", data[i]);
121 strncat(phOsalNfc_DbgTraceBuffer, buf, 10);
122 }
Steve Block1f23e482011-12-20 16:20:37 +0000123 ALOGD("%s", phOsalNfc_DbgTraceBuffer);
124 ALOGD("Block size is: %d", size);
Nick Pelly5d9927b2010-09-23 12:47:58 -0700125#endif
126#endif
127}
128
129/*!
130 * \brief Raises exception.
131 * This function raises an exception of type \a eExceptionType with
132 * reason \a reason to stack clients.
133 *
134 * \param eExceptionType exception type.
135 * \param reason reason for this exception.
136 *
137 * \note Clients willing to catch exceptions are to handle the SIGABRT signal.
138 * On Linux, exception type and reason are passed to the signal handler as
139 * a pointer to a phOsalNfc_Exception_t structure.
140 * As sigqueue is not available in Android, exception information are
141 * stored in the phOsalNfc_Exception global.
142 */
143void phOsalNfc_RaiseException(phOsalNfc_ExceptionType_t eExceptionType, uint16_t reason)
144{
Daniel Tomasbad5c192010-11-03 20:23:31 +0100145 if(eExceptionType == phOsalNfc_e_UnrecovFirmwareErr)
146 {
Martijn Coenen6141c4b2012-06-08 17:24:36 -0700147 ALOGE("HCI Timeout - Exception raised - Force restart of NFC service");
Sunil Jogi82063252012-04-10 11:37:25 -0700148 phLibNfc_Mgt_Recovery();
Daniel Tomasbad5c192010-11-03 20:23:31 +0100149 abort();
Martijn Coenen6141c4b2012-06-08 17:24:36 -0700150 } else {
151 ALOGD("phOsalNfc_RaiseException() called");
Daniel Tomasbad5c192010-11-03 20:23:31 +0100152 }
Nick Pelly5d9927b2010-09-23 12:47:58 -0700153}
154
Daniel Tomasc1f33132011-04-21 14:11:28 -0700155/*!
156 * \brief display data bytes.
157 * This function displays data bytes for debug purpose
158 * \param[in] pString pointer to string to be displayed.
159 * \param[in] length number of bytes to be displayed.
160 * \param[in] pBuffer pointer to data bytes to be displayed.
161 *
162 */
Nick Pelly5ea62ad2011-10-19 18:36:47 -0700163void phOsalNfc_PrintData(const char *pString, uint32_t length, uint8_t *pBuffer,
164 int verbosity)
Daniel Tomasc1f33132011-04-21 14:11:28 -0700165{
Nick Pellyfafed3c2011-06-23 17:15:08 -0700166 char print_buffer[length * 3 + 1];
Nick Pelly5ea62ad2011-10-19 18:36:47 -0700167 unsigned int i;
Daniel Tomasc1f33132011-04-21 14:11:28 -0700168
Nick Pellyfafed3c2011-06-23 17:15:08 -0700169 if (pString == NULL) {
170 pString = "";
Daniel Tomasc1f33132011-04-21 14:11:28 -0700171 }
Nick Pellyfafed3c2011-06-23 17:15:08 -0700172 print_buffer[0] = '\0';
173 for (i = 0; i < length; i++) {
174 snprintf(&print_buffer[i*3], 4, " %02X", pBuffer[i]);
175 }
Nick Pelly5ea62ad2011-10-19 18:36:47 -0700176
177 char llc[40] = "";
178
179 if (verbosity >= 2) {
180 uint8_t llc_header = 0;
181 if (!strcmp(pString, "SEND") && length >= 2) {
182 llc_header = pBuffer[1];
183 } else if (!strcmp(pString, "RECV") && length >= 2) {
184 llc_header = pBuffer[0];
185 }
186
187 if ((llc_header & 0xC0) == 0x80) {
188 // I
189 uint8_t ns = (llc_header & 0x38) >> 3;
190 uint8_t nr = llc_header & 0x07;
191 snprintf(&llc[0], sizeof(llc), "I %d (%d)", ns, nr);
192 } else if ((llc_header & 0xE0) == 0xC0) {
193 // S
194 uint8_t t = (llc_header & 0x18) >> 3;
195 uint8_t nr = llc_header & 0x07;
196 char *type;
197 switch (t) {
198 case 0x00: type = "RR "; break;
199 case 0x01: type = "REJ"; break;
200 case 0x02: type = "RNR"; break;
201 case 0x03: type = "SREJ"; break;
202 default: type = "???"; break;
203 }
204 snprintf(&llc[0], sizeof(llc), "S %s (%d)", type, nr);
205 } else if ((llc_header & 0xE0) == 0xE0) {
206 // U
207 snprintf(&llc[0], sizeof(llc), "U");
208 } else if (length > 1) {
209 snprintf(&llc[0], sizeof(llc), "???");
210 }
211 }
212
Steve Block1f23e482011-12-20 16:20:37 +0000213 ALOGD("> %s:%s\t%s", pString, print_buffer, llc);
Daniel Tomasc1f33132011-04-21 14:11:28 -0700214}