1/* 2 * This is a reverse-engineered driver for mobile WiMAX (802.16e) devices 3 * based on Samsung CMC-730 chip. 4 * Copyright (C) 2008-2009 Alexander Gordeev <lasaine@lvk.cs.msu.su> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21#include <ctype.h> 22#include <stdarg.h> 23#include <stdio.h> 24#include <string.h> 25#include <syslog.h> 26 27#include "config.h" 28#include "logging.h" 29 30/* the reason we define MADWIMAX_VERSION as a static string, rather than a 31 macro, is to make dependency tracking easier (only logging.o depends 32 on madwimax_version.h), and also to prevent all sources from 33 having to be recompiled each time the version changes (they only 34 need to be re-linked). */ 35#include "madwimax_version.h" 36 37const char* get_madwimax_version() 38{ 39 return MADWIMAX_VERSION_MACRO; 40} 41 42static int wimax_log_level = 0; 43 44/* set wmlog level to the desired value */ 45void set_wmlog_level(int level) 46{ 47 wimax_log_level = level; 48} 49 50/* increase wmlog level by 1 */ 51void inc_wmlog_level() 52{ 53 wimax_log_level++; 54} 55 56FILE *logfile = NULL; 57 58/* log to stderr */ 59static void wmlog_file(const char *fmt, va_list va) 60{ 61 vfprintf(logfile, fmt, va); 62 fprintf(logfile, "\n"); 63 fflush(logfile); 64} 65 66/* log to syslog */ 67static void wmlog_syslog(const char *fmt, va_list va) 68{ 69 vsyslog(LOG_INFO, fmt, va); 70} 71 72typedef void (*wmlogger_func)(const char *fmt, va_list va); 73 74static wmlogger_func loggers[2] = {[WMLOGGER_FILE] = wmlog_file, [WMLOGGER_SYSLOG] = wmlog_syslog}; 75static wmlogger_func selected_logger = wmlog_file; 76 77/* set logger to stderr or syslog */ 78void set_wmlogger(const char *progname, int logger, FILE *file) 79{ 80 selected_logger = loggers[logger]; 81 if (logger == WMLOGGER_SYSLOG) { 82 openlog(progname, LOG_PID, LOG_DAEMON); 83 } else { 84 closelog(); 85 logfile = file; 86 } 87} 88 89/* print wmlog message. */ 90void wmlog_msg(int level, const char *fmt, ...) 91{ 92 va_list va; 93 94 if (level > wimax_log_level) return; 95 96 va_start(va, fmt); 97 selected_logger(fmt, va); 98 va_end(va); 99} 100 101/* print wmlog message. */ 102static inline void wmlog_msg_priv(const char *fmt, ...) 103{ 104 va_list va; 105 106 va_start(va, fmt); 107 selected_logger(fmt, va); 108 va_end(va); 109} 110 111/* If a character is not printable, return a dot. */ 112#define toprint(x) (isprint((unsigned int)x) ? (x) : '.') 113 114/* dump message and len bytes from buf in hexadecimal and ASCII. */ 115void wmlog_dumphexasc(int level, const void *buf, int len, const char *fmt, ...) 116{ 117 int i; 118 va_list va; 119 120 if (level > wimax_log_level) return; 121 122 va_start(va, fmt); 123 selected_logger(fmt, va); 124 va_end(va); 125 126 for (i = 0; i < len; i+=16) { 127 int j; 128 char hex[49]; 129 char ascii[17]; 130 memset(hex, ' ', 48); 131 for(j = i; j < i + 16 && j < len; j++) { 132 sprintf(hex + ((j - i) * 3), " %02x", ((unsigned char*)buf)[j]); 133 ascii[j - i] = toprint(((unsigned char*)buf)[j]); 134 } 135 hex[(j - i) * 3] = ' '; 136 hex[48] = 0; 137 ascii[j - i] = 0; 138 wmlog_msg_priv(" %08x:%s %s", i, hex, ascii); 139 } 140} 141 142