blob: 313dcbbd10de5efb9a1e73384cc42401cbbb1955 [file] [log] [blame]
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +02001/** Log wrapper for Android.
2 * @{
3 * @file
4 *
5 * Maps LOG_*() macros to __android_log_print() if LOG_ANDROID is defined.
6 * Adds some extra info to log output like LOG_TAG, file name and line number.
7 *
Oana Medvesanedfb7202013-02-06 21:58:30 +01008 * <!-- Copyright Trustonic 2012-2013 -->
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +02009 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34#ifndef TLCWRAPPERANDROIDLOG_H_
35#define TLCWRAPPERANDROIDLOG_H_
36
37#include <unistd.h>
38#include <stdio.h>
39#include <android/log.h>
40
Lukas Häneldb4b53e2012-10-22 13:49:41 +020041/** LOG_I(fmt, args...)
42 * Informative logging, only shown in debug version
43 */
44
45/** LOG_W(fmt, args...)
46 * Warnings logging, only shown in debug version
47 */
48
49/** LOG_E(fmt, args...)
50 * Error logging, shown in debug and release version
51 */
52
53/** LOG_V(fmt, args...)
54 * Verbose logging, shown in debug version if the including file defines LOG_VERBOSE
55 */
56
57/** LOG_I_BUF(szDescriptor, blob, sizeOfBlob)
58 * Binary logging, line-wise output to LOG_I
59 */
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020060
61#define EOL "\n"
62#define DUMMY_FUNCTION() do{}while(0)
63
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020064#ifdef LOG_ANDROID
Lukas Häneldb4b53e2012-10-22 13:49:41 +020065// log to adb logcat
66#ifdef NDEBUG // no logging in debug version
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020067 #define LOG_I(fmt, args...) DUMMY_FUNCTION()
68 #define LOG_W(fmt, args...) DUMMY_FUNCTION()
69#else
Lukas Häneldb4b53e2012-10-22 13:49:41 +020070 // add LINE
71 #define LOG_I(fmt, args...) LOG_i(fmt";%d", ## args, __LINE__)
72 #define LOG_W(fmt, args...) LOG_w(fmt";%d", ## args, __LINE__)
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020073#endif
Lukas Häneldb4b53e2012-10-22 13:49:41 +020074 // LOG_E is always defined
75 #define _LOG_E(fmt, args...) LOG_e(fmt, ## args)
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020076
Lukas Häneldb4b53e2012-10-22 13:49:41 +020077 // actually mapping to log system, adding level and tag.
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020078 #define LOG_i(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
79 #define LOG_w(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
80 #define LOG_e(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
81
82#else //!defined(LOG_ANDROID)
Lukas Häneldb4b53e2012-10-22 13:49:41 +020083// log to std.out using printf
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020084
85 // #level / #LOG_TAG ( process_id): __VA_ARGS__
86 // Example:
87 // I/McDrvBasicTest_0_1( 4075): setUp
88 #define _LOG_x(_x_,...) \
89 do \
90 { \
91 printf("%s/%s(%d): ",_x_,LOG_TAG,getpid()); \
92 printf(__VA_ARGS__); \
93 printf(EOL); \
94 } while(1!=1)
95
96
Lukas Häneldb4b53e2012-10-22 13:49:41 +020097#ifdef NDEBUG // no logging in debug version
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +020098 #define LOG_I(fmt, args...) DUMMY_FUNCTION()
99 #define LOG_W(fmt, args...) DUMMY_FUNCTION()
100#else
101 #define LOG_I(...) _LOG_x("I",__VA_ARGS__)
102 #define LOG_W(...) _LOG_x("W",__VA_ARGS__)
103#endif
104 #define _LOG_E(...) _LOG_x("E",__VA_ARGS__)
105
106#endif //defined(LOG_ANDROID)
107
Lukas Häneldb4b53e2012-10-22 13:49:41 +0200108#if defined(LOG_VERBOSE)
109#define LOG_V LOG_I
110#else
111#define LOG_V(...) DUMMY_FUNCTION()
112#endif
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +0200113
114/** LOG_E() needs to be more prominent:
115 * Display "*********** ERROR ***********" before actual error message.
116 */
117#define LOG_E(...) \
118 do \
119 { \
Lukas Häneldb4b53e2012-10-22 13:49:41 +0200120 _LOG_E(" *****************************"); \
121 _LOG_E(" *** ERROR: "__VA_ARGS__); \
Oana Medvesanedfb7202013-02-06 21:58:30 +0100122 _LOG_E(" *** Detected in %s/%u()", __FUNCTION__, __LINE__); \
Lukas Häneldb4b53e2012-10-22 13:49:41 +0200123 _LOG_E(" *****************************"); \
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +0200124 } while(1!=1)
125
Lukas Häneldb4b53e2012-10-22 13:49:41 +0200126#define LOG_ERRNO(MESSAGE) \
127 LOG_E("%s failed with \"%s\"(errno %i)", MESSAGE, strerror(errno), errno);
Lukas Hänelf6f0f3d2012-05-21 11:21:57 +0200128
129#define LOG_I_BUF LOG_I_Buf
130
131__attribute__ ((unused))
132static void LOG_I_Buf(
133 const char * szDescriptor,
134 const void * blob,
135 size_t sizeOfBlob
136) {
137
138 #define CPL 0x10 // chars per line
139 #define OVERHEAD 20
140
141 char buffer[CPL * 4 + OVERHEAD];
142
143 uint32_t index = 0;
144
145 uint32_t moreThanOneLine = (sizeOfBlob > CPL);
146 uint32_t blockLen = CPL;
147 uint32_t addr = 0;
148 uint32_t i = 0;
149
150 if (NULL != szDescriptor)
151 {
152 index += sprintf(&buffer[index], "%s", szDescriptor);
153 }
154
155 if (moreThanOneLine)
156 {
157 if (NULL == szDescriptor)
158 {
159 index += sprintf(&buffer[index], "memory dump");
160 }
161 index += sprintf(&buffer[index], " (0x%08x, %d bytes)", (uint32_t)blob,sizeOfBlob);
162 LOG_I("%s", buffer);
163 index = 0;
164 }
165 else if (NULL == szDescriptor)
166 {
167 index += sprintf(&buffer[index], "Data at 0x%08x: ", (uint32_t)blob);
168 }
169
170 if(sizeOfBlob == 0) {
171 LOG_I("%s", buffer);
172 }
173 else
174 {
175 while (sizeOfBlob > 0)
176 {
177 if (sizeOfBlob < blockLen)
178 {
179 blockLen = sizeOfBlob;
180 }
181
182 // address
183 if (moreThanOneLine)
184 {
185 index += sprintf(&buffer[index], "0x%08X | ",addr);
186 addr += CPL;
187 }
188 // bytes as hex
189 for (i=0; i<blockLen; ++i)
190 {
191 index += sprintf(&buffer[index], "%02x ", ((const char *)blob)[i] );
192 }
193 // spaces if necessary
194 if ((blockLen < CPL) && (moreThanOneLine))
195 {
196 // add spaces
197 for (i=0; i<(3*(CPL-blockLen)); ++i) {
198 index += sprintf(&buffer[index], " ");
199 }
200 }
201 // bytes as ASCII
202 index += sprintf(&buffer[index], "| ");
203 for (i=0; i<blockLen; ++i)
204 {
205 char c = ((const char *)blob)[i];
206 index += sprintf(&buffer[index], "%c",(c>32)?c:'.');
207 }
208
209 blob = &(((const char *)blob)[blockLen]);
210 sizeOfBlob -= blockLen;
211
212 // print line to logcat / stdout
213 LOG_I("%s", buffer);
214 index = 0;
215 }
216 }
217}
218
219#endif /** TLCWRAPPERANDROIDLOG_H_ */
220
221/** @} */