1 /** 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 * 8 * <!-- Copyright Giesecke & Devrient GmbH 2010 - 2011 --> 9 * 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 41 /** 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 */ 60 61 #define EOL "\n" 62 #define DUMMY_FUNCTION() do{}while(0) 63 64 #ifdef LOG_ANDROID 65 // log to adb logcat 66 #ifdef NDEBUG // no logging in debug version 67 #define LOG_I(fmt, args...) DUMMY_FUNCTION() 68 #define LOG_W(fmt, args...) DUMMY_FUNCTION() 69 #else 70 // 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__) 73 #endif 74 // LOG_E is always defined 75 #define _LOG_E(fmt, args...) LOG_e(fmt, ## args) 76 77 // actually mapping to log system, adding level and tag. 78 #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) 83 // log to std.out using printf 84 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 97 #ifdef NDEBUG // no logging in debug version 98 #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 108 #if defined(LOG_VERBOSE) 109 #define LOG_V LOG_I 110 #else 111 #define LOG_V(...) DUMMY_FUNCTION() 112 #endif 113 114 /** LOG_E() needs to be more prominent: 115 * Display "*********** ERROR ***********" before actual error message. 116 */ 117 #define LOG_E(...) \ 118 do \ 119 { \ 120 _LOG_E(" *****************************"); \ 121 _LOG_E(" *** ERROR: "__VA_ARGS__); \ 122 _LOG_E(" *** Detected in %s:%i/%s()", __FILE__, __LINE__, __FUNCTION__); \ 123 _LOG_E(" *****************************"); \ 124 } while(1!=1) 125 126 #define LOG_ERRNO(MESSAGE) \ 127 LOG_E("%s failed with \"%s\"(errno %i)", MESSAGE, strerror(errno), errno); 128 129 #define LOG_I_BUF LOG_I_Buf 130 131 __attribute__ ((unused)) 132 static 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 /** @} */ 222