1
/*********************************************************************
6
* Status: Experimental.
7
* Author: Dag Brattli <dagb@cs.uit.no>
8
* Created at: Wed Mar 31 15:30:46 1999
9
* Modified at: Wed Dec 8 09:46:16 1999
10
* Modified by: Dag Brattli <dagb@cs.uit.no>
12
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
14
* This program is free software; you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License as
16
* published by the Free Software Foundation; either version 2 of
17
* the License, or (at your option) any later version.
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, write to the Free Software
26
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29
********************************************************************/
31
#include <sys/socket.h>
32
#include <sys/types.h>
34
#include <string.h> /* For strstr */
35
#include <stdio.h> /* For printf */
41
extern struct ias_query last_ias;
42
extern struct lsap_state conn[];
45
* Function parse_iriap (buf)
47
* Try to parse and print the LM-IAS query
50
inline void parse_iriap_command(GNetBuf *buf, GString *str, guint8 slsap_sel)
59
/* Kill "unused" warning */
60
slsap_sel = slsap_sel;
62
opcode = buf->data[n++];
64
opcode &= ~IAP_LST; /* Mask away LST bit */
67
case GET_VALUE_BY_CLASS:
68
name_len = buf->data[n++];
69
memcpy( name, buf->data+n, name_len); n+=name_len;
70
name[name_len] = '\0';
72
attr_len = buf->data[n++];
73
memcpy( attr, buf->data+n, attr_len); n+=attr_len;
74
attr[attr_len] = '\0';
76
g_string_sprintfa(str, "GET_VALUE_BY_CLASS: \"%s\" \"%s\" ",
79
/* Check if this is a TinyTP lookup */
80
if (strstr(attr, "TinyTP"))
84
/* Reset to undefined (handle IAS failures properly) */
85
last_ias.lsap_sel = LSAP_ANY;
87
/* Check if this is a OBEX lookup */
88
if (strstr(name, "OBEX"))
92
/* Check if this is a IrCOMM lookup */
93
if (strstr(name, "IrCOMM") || strstr(name, "IrLPT"))
97
/* Check if this is a IrNET lookup */
98
if (strstr(name, "IrNet"))
109
* Function parse_irias_value (buf)
114
void parse_irias_value(GNetBuf *buf, GString *str)
126
/* Get length, MSB first */
127
memcpy(&len, buf->data+n, 2); n += 2;
128
len = GUINT16_FROM_BE(len);
130
/* Get object ID, MSB first */
131
memcpy(&obj_id, buf->data+n, 2); n += 2;
132
obj_id = GUINT16_FROM_BE(obj_id);
134
type = buf->data[n++];
138
memcpy(&tmp_cpu32, buf->data+n, 4); n += 4;
139
tmp_cpu32 = GUINT32_FROM_BE(tmp_cpu32);
141
/* Legal values restricted to 0x01-0x6f, page 15 irttp */
142
g_string_sprintfa(str, "Integer: %02x ", tmp_cpu32);
143
last_ias.lsap_sel = tmp_cpu32;
146
charset = buf->data[n++];
164
value_len = buf->data[n++];
166
/* Make sure the string is null-terminated */
167
memcpy(string, buf->data+n, value_len);
168
string[value_len] = 0x00;
170
g_string_sprintfa(str, "String: %s ", string);
173
memcpy(&tmp_cpu16, buf->data+n, 2); n += 2;
174
tmp_cpu16 = GUINT16_FROM_BE(tmp_cpu16);
175
value_len = tmp_cpu16;
177
g_netbuf_pull(buf, n);
178
if (last_ias.ircomm) {
179
g_string_append(str, "\n\tIrCOMM Parameters ");
180
parse_ircomm_params(value_len, buf, str);
182
g_string_append(str, "N/A ");
185
g_print("%s() Unknown IAS value type! ", __FUNCTION__);
191
* Function parse_iriap_response (buf)
196
inline void parse_iriap_response(GNetBuf *buf, GString *str, guint8 dlsap_sel)
200
/* Kill "unused" warning */
201
dlsap_sel = dlsap_sel;
203
opcode = buf->data[0] & ~IAP_LST; /* Mask away LST bit */
206
g_netbuf_pull(buf, 2);
210
g_print("%s() Sorry, GET_INFO_BASE not implemented!\n", __FUNCTION__);
212
case GET_VALUE_BY_CLASS:
213
g_string_append(str, "GET_VALUE_BY_CLASS: ");
216
g_print("%s() Sorry, not implemented!\n", __FUNCTION__);
222
g_string_append(str, "Success ");
223
parse_irias_value(buf, str);
225
case IAS_CLASS_UNKNOWN:
226
g_string_append(str, "No such class ");
228
case IAS_ATTRIB_UNKNOWN:
229
g_string_append(str, "No such attribute ");
232
g_string_append(str, "Unknown response code ");
237
* Function parse_irttp (buf, str)
239
* Parse IrTTP data frame
242
inline void parse_irnet(GNetBuf *buf, GString *str)
244
/* Kill "unused" warning */
247
g_string_sprintfa(str, "IrNET ");
248
/* If you want to hook PPP frame decoding, you can do it here.
249
* I don't think it's worth it, PPP has debug capabilities.
254
* Function parse_irttp (buf, str)
256
* Parse IrTTP data frame
259
inline void parse_irttp(GNetBuf *buf, GString *str)
261
g_string_sprintfa(str, "TTP credits=%d ", buf->data[0] & 0x7f);
263
if (buf->data[0] & 0x80)
264
g_string_append(str, "More ");
266
/* Remove TTP header */
267
g_netbuf_pull(buf, 1);
271
* Function parse_irttp_connect (buf, str)
273
* Parse IrTTP connect frame
276
inline void parse_irttp_connect(GNetBuf *buf, GString *str)
281
g_string_sprintfa(str, "TTP credits=%d ", buf->data[0] & 0x7f);
283
if (buf->data[0] & 0x80) {
288
memcpy(&tmp_cpu, buf->data+4, 2); /* Align value */
289
tmp_cpu = GUINT16_FROM_BE(tmp_cpu); /* Convert to host order */
291
/* Remove TTP parameters */
292
g_netbuf_pull(buf, plen);
294
g_string_sprintfa(str, "MaxSduSize=%d ", tmp_cpu);
296
/* Remove TTP header */
297
g_netbuf_pull(buf, 1);
301
* Function parse_irlmp (buf)
306
inline void parse_irlmp(GNetBuf *buf, GString *str,
307
guint8 caddr, int type, int cmd)
309
guint8 slsap_sel, dlsap_sel;
314
ctrl = buf->data[0] & CONTROL_BIT;
315
dlsap_sel = buf->data[0] & LSAP_MASK;
316
slsap_sel = buf->data[1];
318
/* Remove IrLMP header */
319
g_netbuf_pull(buf, 2);
321
g_string_sprintfa(str, "LM slsap=%02x dlsap=%02x ", slsap_sel,
324
/* Control or data? */
327
rsvd = buf->data[1]; /* reason/status/rsvd */
329
/* Remove IrLMP control header (2 bytes) */
330
g_netbuf_pull(buf, 2);
334
g_string_append(str, "CONN_CMD ");
335
if (dlsap_sel == last_ias.lsap_sel) {
336
i = find_free_connection();
338
printf("No more space for connection!\n");
342
conn[i].caddr = caddr;
344
conn[i].slsap_sel = slsap_sel;
345
conn[i].dlsap_sel = dlsap_sel;
347
conn[i].slsap_sel = dlsap_sel;
348
conn[i].dlsap_sel = slsap_sel;
350
conn[i].ttp = last_ias.ttp;
351
conn[i].obex = last_ias.obex;
352
conn[i].ircomm = last_ias.ircomm;
353
conn[i].irnet = last_ias.irnet;
356
parse_irttp_connect(buf, str);
358
parse_ircomm_connect(buf, str);
360
parse_irnet(buf, str);
362
if((config_force_ttp) && (dlsap_sel != 0x00))
363
parse_irttp_connect(buf, str);
367
g_string_append(str, "CONN_RSP ");
369
i = find_connection(slsap_sel, dlsap_sel);
371
i = find_connection(dlsap_sel, slsap_sel);
374
parse_irttp_connect(buf, str);
376
parse_ircomm_connect(buf, str);
378
parse_irnet(buf, str);
380
if((config_force_ttp) && (slsap_sel != 0x00))
381
parse_irttp_connect(buf, str);
385
g_string_append(str, "DISC ");
387
/* Mark this connection as invalid */
389
i = find_connection(slsap_sel, dlsap_sel);
391
i = find_connection(dlsap_sel, slsap_sel);
400
/* Check if this is a LM-IAS query */
401
if (dlsap_sel == 0x00)
402
parse_iriap_command(buf, str, slsap_sel);
403
else if (slsap_sel == 0x00)
404
parse_iriap_response(buf, str, dlsap_sel);
406
/* Find connection */
408
i = find_connection(slsap_sel, dlsap_sel);
410
i = find_connection(dlsap_sel, slsap_sel);
412
if (conn[i].valid && conn[i].ttp)
413
parse_irttp(buf, str);
414
if (conn[i].valid && conn[i].obex)
415
parse_obex(buf, str, cmd);
416
if (conn[i].valid && conn[i].ircomm) {
418
parse_ircomm_ttp(buf, str);
420
parse_ircomm_lmp(buf, str);
422
if (conn[i].valid && conn[i].irnet)
423
parse_irnet(buf, str);
425
/* Not IAS and unknow connection */
426
if((dlsap_sel != 0x00) && (slsap_sel != 0x00) && (i == -1)) {
428
parse_irttp(buf, str);
435
* Function parse_ui_irlmp (buf)
437
* Parse IrLMP frame in UI frame
440
inline void parse_ui_irlmp(GNetBuf *buf, GString *str, int type)
442
guint8 slsap_sel, dlsap_sel;
445
/* Kill "unused" warning */
448
ctrl = buf->data[0] & CONTROL_BIT;
449
dlsap_sel = buf->data[0] & LSAP_MASK;
450
slsap_sel = buf->data[1];
452
/* Remove IrLMP header */
453
g_netbuf_pull(buf, 2);
455
g_string_sprintfa(str, "LM slsap=%02x dlsap=%02x ", slsap_sel,
458
/* Let's see if it's Ultra, and decode it - Jean II */
459
if((slsap_sel == 0x70) && (dlsap_sel == 0x70))
461
int upid = buf->data[0] & 0x7F;
462
g_netbuf_pull(buf, 1);
464
g_string_sprintfa(str, " Ultra-PID=%02x ", upid);
466
/* Check Obex over Ultra */
469
/* Remove SAR field */
470
g_netbuf_pull(buf, 1);
472
/* Decode Obex stuff - no connection, always a command */
473
parse_obex(buf, str, 1);