1/* $NetBSD: xlog.c,v 1.6 2008/04/28 20:24:16 martin Exp $ */
2
3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Martin Husemann <martin@NetBSD.org>.
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 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <sys/ioctl.h>
36#include <netisdn/i4b_ioctl.h>
37
38#define LOG                     1
39
40#define OK 			0xff
41#define MORE_EVENTS 		0xfe
42#define NO_EVENT 		1
43
44#define OFF_LOG_RC	0	/* 1 byte */
45#define	OFF_LOG_TIMEL1	1	/* 1 byte */
46#define	OFF_LOG_TIMEL2	2	/* 1 byte */
47#define	OFF_LOG_TIMES	3	/* 2 byte */
48#define	OFF_LOG_TIMEH	5	/* 2 byte */
49#define	OFF_LOG_CODE	7	/* 2 byte */
50#define	OFF_PAR_TEXT	9	/* 42 bytes */
51#define	OFF_PAR_L1_LEN	9	/* 2 byte */
52#define	OFF_PAR_L1_I	11	/* 22 byte */
53#define OFF_PAR_L2_CODE	9	/* 2 byte */
54#define	OFF_PAR_L2_LEN	11	/* 2 byte */
55#define	OFF_PAR_L2_I	13	/* 20 byte */
56
57#define	DIAG_SIZE	49
58#define	WORD(d,o)	(((d)[(o)])|((d)[(o)+1])<<8)
59#define	DWORD(d,o)	(WORD(d,o)|(WORD(d,o+2)<<16))
60
61void xlog(int fd, int controller);
62
63static const char *ll_name[10] = {
64  "LL_UDATA",
65  "LL_ESTABLISH",
66  "LL_RELEASE",
67  "LL_DATA",
68  "LL_RESTART",
69  "LL_RESET",
70  "LL_POLL",
71  "LL_TEST",
72  "LL_MDATA",
73  "LL_BUDATA"
74};
75
76static const char *ns_name[11] = {
77  "N_MDATA",
78  "N_CONNECT",
79  "N_CONNECT ACK",
80  "N_DISC",
81  "N_DISC ACK",
82  "N_RESET",
83  "N_RESET ACK",
84  "N_DATA",
85  "N_EDATA",
86  "N_UDATA",
87  "N_BDATA"
88};
89
90void
91xlog(int fd, int controller)
92{
93	int i, n, code, fin;
94	struct isdn_diagnostic_request req;
95	u_int8_t data[DIAG_SIZE];
96	u_int8_t rc;
97
98	printf("xlog:\n");
99	memset(&req, 0, sizeof(req));
100	req.controller = controller;
101	req.cmd = LOG;
102	req.out_param_len = DIAG_SIZE;
103	req.out_param = &data;
104
105	for (fin = 0; !fin; ) {
106		if (ioctl(fd, I4B_ACTIVE_DIAGNOSTIC, &req) == -1) {
107			perror("ioctl(I4B_ACTIVE_DIAGNOSTIC)");
108			fin = 1;
109			break;
110		}
111		rc = data[OFF_LOG_RC];
112		if (rc == NO_EVENT) {
113			fin = 1;
114			printf("No log event\n");
115			break;
116		}
117		if (rc == MORE_EVENTS) {
118			printf("More events...(0x%02x)\n", rc);
119			fin = 0;
120		} else if (rc == OK) {
121			printf("Last event...(0x%02x)\n", rc);
122			fin = 1;
123		} else {
124			printf("error: unknown rc = 0x%02x\n", rc);
125			fin = 1;
126			break;
127		}
128
129		/* print timestamp */
130		printf("%5d:%04d:%03d - ", WORD(data,OFF_LOG_TIMEH),
131			WORD(data,OFF_LOG_TIMES),
132			data[OFF_LOG_TIMEL2]*20 + data[OFF_LOG_TIMEL1]);
133
134		code = data[OFF_LOG_CODE];
135		switch (code) {
136		  case 1:
137			n = WORD(data, OFF_PAR_L1_LEN);
138			printf("B-X(%03d) ",n);
139			for (i=0; i<n && i<30; i++)
140			    printf("%02X ", data[OFF_PAR_L1_I+i]);
141			if (n>i) printf(" ...");
142			break;
143		  case 2:
144			n = WORD(data, OFF_PAR_L1_LEN);
145			printf("B-R(%03d) ", n);
146			for (i=0; i<n && i<30; i++)
147			    printf("%02X ", data[OFF_PAR_L1_I+i]);
148			if (n>i) printf(" ...");
149			break;
150		  case 3:
151			n = WORD(data, OFF_PAR_L1_LEN);
152			printf("D-X(%03d) ",n);
153			for (i=0; i<n && i<38; i++)
154			    printf("%02X ", data[OFF_PAR_L1_I+i]);
155			if (n>i) printf(" ...");
156			break;
157		  case 4:
158			n = WORD(data, OFF_PAR_L1_LEN);
159			printf("D-R(%03d) ",n);
160			for (i=0; i<n && i<38; i++)
161			    printf("%02X ", data[OFF_PAR_L1_I+i]);
162			if (n>i) printf(" ...");
163			break;
164		  case 5:
165			n = WORD(data, OFF_PAR_L2_LEN);
166			printf("SIG-EVENT(%03d)%04X - ", n, WORD(data, OFF_PAR_L2_CODE));
167			for (i=0; i<n && i<28; i++)
168			    printf("%02X ", data[OFF_PAR_L2_I+i]);
169			if (n>i) printf(" ...");
170			break;
171		  case 6:
172			code = WORD(data, OFF_PAR_L2_CODE);
173			if (code && code <= 10)
174				printf("%s IND",ll_name[code-1]);
175			else
176				printf("UNKNOWN LL IND");
177			break;
178		  case 7:
179			code = WORD(data, OFF_PAR_L2_CODE);
180			if (code && code <= 10)
181				printf("%s REQ",ll_name[code-1]);
182			else
183				printf("UNKNOWN LL REQ");
184			break;
185		  case 8:
186			n = WORD(data, OFF_PAR_L2_LEN);
187			printf("DEBUG%04X - ",WORD(data, OFF_PAR_L2_CODE));
188			for (i=0; i<n && i<38; i++)
189			    printf("%02X ", data[OFF_PAR_L2_I+i]);
190			if (n>i) printf(" ...");
191			break;
192		  case 9:
193			printf("MDL-ERROR(%s)",&data[OFF_PAR_TEXT]);
194			break;
195		  case 10:
196			printf("UTASK->PC(%02X)",WORD(data, OFF_PAR_L2_CODE));
197			break;
198		  case 11:
199			printf("PC->UTASK(%02X)",WORD(data, OFF_PAR_L2_CODE));
200			break;
201		  case 12:
202			n = WORD(data, OFF_PAR_L1_LEN);
203			printf("X-X(%03d) ",n);
204			for (i=0; i<n && i<30; i++)
205			    printf("%02X ", data[OFF_PAR_L1_I+i]);
206			if (n>i) printf(" ...");
207			break;
208		  case 13:
209			n = WORD(data, OFF_PAR_L1_LEN);
210			printf("X-R(%03d) ",n);
211			for (i=0; i<n && i<30; i++)
212			    printf("%02X ", data[OFF_PAR_L1_I+i]);
213			if (n>i) printf(" ...");
214			break;
215		  case 14:
216			code = WORD(data, OFF_PAR_L2_CODE)-1;
217			if ((code &0x0f)<=10)
218				printf("%s IND",ns_name[code &0x0f]);
219			else
220				printf("UNKNOWN NS IND");
221			break;
222		  case 15:
223			code = WORD(data, OFF_PAR_L2_CODE)-1;
224			if ((code & 0x0f)<=10)
225				printf("%s REQ",ns_name[code &0x0f]);
226			else
227				printf("UNKNOWN NS REQ");
228			break;
229		  case 16:
230			printf("TASK %02i: %s",
231				WORD(data, OFF_PAR_L2_CODE), &data[OFF_PAR_L2_I]);
232			break;
233		  case 18:
234			code = WORD(data, OFF_PAR_L2_CODE);
235			printf("IO-REQ %02x",code);
236			break;
237		  case 19:
238			code = WORD(data, OFF_PAR_L2_CODE);
239			printf("IO-CON %02x",code);
240			break;
241		  default:
242		  	printf("unknown event code = %d\n", code);
243		  	break;
244		}
245		printf("\n");
246	}
247	printf("\n");
248}
249
250