00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <adt/list.h>
00036 #include <fibril_synch.h>
00037 #include <errno.h>
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <usb/debug.h>
00041
00043 static usb_log_level_t log_level = USB_LOG_LEVEL_WARNING;
00044
00046 static const char *log_prefix = "usb";
00047
00049 static FIBRIL_MUTEX_INITIALIZE(log_serializer);
00050
00052 static FILE *log_stream = NULL;
00053
00054
00060 void usb_log_enable(usb_log_level_t level, const char *message_prefix)
00061 {
00062 log_prefix = message_prefix;
00063 log_level = level;
00064 if (log_stream == NULL) {
00065 char *fname;
00066 int rc = asprintf(&fname, "/log/%s", message_prefix);
00067 if (rc > 0) {
00068 log_stream = fopen(fname, "w");
00069 free(fname);
00070 }
00071 }
00072 }
00073
00079 static const char *log_level_name(usb_log_level_t level)
00080 {
00081 switch (level) {
00082 case USB_LOG_LEVEL_FATAL:
00083 return " FATAL";
00084 case USB_LOG_LEVEL_ERROR:
00085 return " ERROR";
00086 case USB_LOG_LEVEL_WARNING:
00087 return " WARN";
00088 case USB_LOG_LEVEL_INFO:
00089 return " info";
00090 default:
00091 return "";
00092 }
00093 }
00094
00100 void usb_log_printf(usb_log_level_t level, const char *format, ...)
00101 {
00102 FILE *screen_stream = NULL;
00103 switch (level) {
00104 case USB_LOG_LEVEL_FATAL:
00105 case USB_LOG_LEVEL_ERROR:
00106 screen_stream = stderr;
00107 break;
00108 default:
00109 screen_stream = stdout;
00110 break;
00111 }
00112 assert(screen_stream != NULL);
00113
00114 va_list args;
00115
00116
00117
00118
00119
00120
00121
00122 fibril_mutex_lock(&log_serializer);
00123
00124 const char *level_name = log_level_name(level);
00125
00126 if ((log_stream != NULL) && (level <= log_level + 1)) {
00127 va_start(args, format);
00128
00129 fprintf(log_stream, "[%s]%s: ", log_prefix, level_name);
00130 vfprintf(log_stream, format, args);
00131 fflush(log_stream);
00132
00133 va_end(args);
00134 }
00135
00136 if (level <= log_level) {
00137 va_start(args, format);
00138
00139 fprintf(screen_stream, "[%s]%s: ", log_prefix, level_name);
00140 vfprintf(screen_stream, format, args);
00141 fflush(screen_stream);
00142
00143 va_end(args);
00144 }
00145
00146 fibril_mutex_unlock(&log_serializer);
00147 }
00148
00149
00150 #define REMAINDER_STR_FMT " (%zu)..."
00151
00152 #define REMAINDER_STR_LEN (5 + 1 + 10)
00153
00155 #define BUFFER_DUMP_GROUP_SIZE 4
00156
00158 #define BUFFER_DUMP_LEN 240
00159
00161 static fibril_local char buffer_dump[2][BUFFER_DUMP_LEN];
00163 static fibril_local int buffer_dump_index = 0;
00164
00187 const char *usb_debug_str_buffer(const uint8_t *buffer, size_t size,
00188 size_t dumped_size)
00189 {
00190
00191
00192
00193 bzero(buffer_dump[buffer_dump_index], BUFFER_DUMP_LEN);
00194
00195 if (buffer == NULL) {
00196 return "(null)";
00197 }
00198 if (size == 0) {
00199 return "(empty)";
00200 }
00201 if ((dumped_size == 0) || (dumped_size > size)) {
00202 dumped_size = size;
00203 }
00204
00205
00206 size_t buffer_remaining_size = BUFFER_DUMP_LEN - 1 - REMAINDER_STR_LEN;
00207 char *it = buffer_dump[buffer_dump_index];
00208
00209 size_t index = 0;
00210
00211 while (index < size) {
00212
00213 const char *space_before;
00214 if (index == 0) {
00215 space_before = "";
00216 } else if ((index % BUFFER_DUMP_GROUP_SIZE) == 0) {
00217 space_before = " ";
00218 } else {
00219 space_before = " ";
00220 }
00221
00222
00223
00224
00225
00226
00227 int val = buffer[index];
00228 char current_byte[16];
00229 int printed = snprintf(current_byte, 16,
00230 "%s%02x", space_before, val);
00231 if (printed < 0) {
00232 break;
00233 }
00234
00235 if ((size_t) printed > buffer_remaining_size) {
00236 break;
00237 }
00238
00239
00240 str_append(it, buffer_remaining_size + 1, current_byte);
00241
00242 buffer_remaining_size -= printed;
00243
00244 it += printed;
00245 index++;
00246
00247 if (index >= dumped_size) {
00248 break;
00249 }
00250 }
00251
00252
00253 if (index < size) {
00254 snprintf(it, REMAINDER_STR_LEN,
00255 REMAINDER_STR_FMT, size - index);
00256 }
00257
00258
00259 buffer_dump_index = 1 - buffer_dump_index;
00260
00261
00262 return buffer_dump[1 - buffer_dump_index];
00263 }
00264
00265