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