Hi,

        As some of you may have noticed, this week was my Linux-IrDA
week (next week I'll be back on Wireless LANs).
        While testing things around, I did notice a few limitations
and bugs in irdadump :
        o Ultra decoding is not supported
        o Obex decoding can mix up command and response frames
        o Obex try to decode frames containing no Obex payload
        o If a IAS query fails, we assume that all further connections
to the IAS sockets are TTP connection (this one was funny).
        o Obex type header not supported
        o Obex target header not supported
        o Don't fully decode success frames
        o Don't handle connect frames that don't have parameters
        o Lenght miscalculated on connect frames (probably alignement)
        Patch attached (of course) ;-)

        Voila...

        Jean
diff -u -p irda-utils-0.9.10/irdadump/src/irdadump.d1.h 
irda-utils-0.9.10/irdadump/src/irdadump.h
--- irda-utils-0.9.10/irdadump/src/irdadump.d1.h        Wed Nov  8 11:49:46 2000
+++ irda-utils-0.9.10/irdadump/src/irdadump.h   Wed Nov  8 11:54:23 2000
@@ -192,8 +192,9 @@ struct lsap_state {
        guint8   dlsap_sel;  /* Destination logical service access point */
 };
 
-inline void parse_obex(struct lsap_state *conn, GNetBuf *buf, GString *str);
-inline void parse_irlmp(GNetBuf *buf, GString *str, int type);
+inline void parse_obex(struct lsap_state *conn, GNetBuf *buf, GString *str,
+                      int cmd);
+inline void parse_irlmp(GNetBuf *buf, GString *str, int type, int cmd);
 inline void parse_ui_irlmp(GNetBuf *buf, GString *str, int type);
 
 #endif /* IRDADUMP_H */
diff -u -p irda-utils-0.9.10/irdadump/src/irdadump.d1.c 
irda-utils-0.9.10/irdadump/src/irdadump.c
--- irda-utils-0.9.10/irdadump/src/irdadump.d1.c        Wed Nov  8 11:49:29 2000
+++ irda-utils-0.9.10/irdadump/src/irdadump.c   Wed Nov  8 11:50:43 2000
@@ -323,7 +323,7 @@ inline void parse_i_frame(guint8 caddr, 
        
        /* Check if we should print IrLMP information */
        if (config_print_irlmp)
-               parse_irlmp(buf, str, type);
+               parse_irlmp(buf, str, type, cmd);
 
 
        if (config_print_lost_frames) {
diff -u -p irda-utils-0.9.10/irdadump/src/irlmp.d1.c 
irda-utils-0.9.10/irdadump/src/irlmp.c
--- irda-utils-0.9.10/irdadump/src/irlmp.d1.c   Wed Nov  8 11:49:41 2000
+++ irda-utils-0.9.10/irdadump/src/irlmp.c      Wed Nov  8 17:40:35 2000
@@ -75,6 +75,8 @@ inline void parse_iriap_command(GNetBuf 
                        last_ias.ttp = 1;
                else
                        last_ias.ttp = 0;
+               /* Reset to undefined (handle IAS failures properly) */
+               last_ias.lsap_sel = LSAP_ANY;
 
                /* Check if this is a OBEX lookup */
                if (strstr(name, "OBEX"))
@@ -227,7 +229,7 @@ inline void parse_iriap_response(GNetBuf
  *    Parse IrLMP frame
  *
  */
-inline void parse_irlmp(GNetBuf *buf, GString *str, int type)
+inline void parse_irlmp(GNetBuf *buf, GString *str, int type, int cmd)
 {
        guint8 slsap_sel, dlsap_sel;
        int ctrl;
@@ -325,7 +327,7 @@ inline void parse_irlmp(GNetBuf *buf, GS
                        if (conn[i].valid && conn[i].ttp)
                                parse_irttp(buf, str);
                        if (conn[i].valid && conn[i].obex)
-                               parse_obex(&conn[0], buf, str);
+                               parse_obex(&conn[0], buf, str, cmd);
 #if 0
                        if (conn[i].valid && conn[i].ircomm)
                                parse_ircomm(&conn[0], buf, str);
@@ -356,4 +358,13 @@ inline void parse_ui_irlmp(GNetBuf *buf,
 
        g_string_sprintfa(str, "LM slsap=%02x dlsap=%02x ", slsap_sel, 
                          dlsap_sel);
+
+       /* Let's see if it's Ultra, and decode it - Jean II */
+       if((slsap_sel == 0x70) && (dlsap_sel == 0x70))
+         {
+           int upid = buf->data[0] & 0x7F;
+           g_netbuf_pull(buf, 1);
+
+           g_string_sprintfa(str, " Ultra-PID=%02x ", upid);
+         }
 }
diff -u -p irda-utils-0.9.10/irdadump/src/obex.d1.h 
irda-utils-0.9.10/irdadump/src/obex.h
--- irda-utils-0.9.10/irdadump/src/obex.d1.h    Wed Nov  8 11:49:21 2000
+++ irda-utils-0.9.10/irdadump/src/obex.h       Wed Nov  8 11:50:03 2000
@@ -55,10 +55,11 @@
 
 #define HEADER_COUNT       0xc0
 #define HEADER_NAME        0x01 /* - */
-#define HEADER_TYPE        0x42
+#define HEADER_TYPE        0x42 /* - */
 #define HEADER_TIME        0x44
 #define HEADER_LENGTH      0xc3 /* - */
 #define HEADER_DESCRIPTION 0x05 /* - */
+#define HEADER_TARGET     0x46 /* - */
 #define HEADER_BODY        0x48 /* - */
 #define HEADER_BODY_END    0x49 /* - */
 
@@ -77,6 +78,12 @@ struct obex_connect_frame {
        guint8  version;
        guint8  flags;
        guint16 mtu;
+} __attribute__((packed));
+
+/* Minimal Obex header */
+struct obex_minimal_frame {
+       guint8  opcode;
+       guint16 len;
 } __attribute__((packed));
 
 #endif
diff -u -p irda-utils-0.9.10/irdadump/src/obex.d1.c 
irda-utils-0.9.10/irdadump/src/obex.c
--- irda-utils-0.9.10/irdadump/src/obex.d1.c    Wed Nov  8 11:49:17 2000
+++ irda-utils-0.9.10/irdadump/src/obex.c       Wed Nov  8 17:15:57 2000
@@ -48,7 +48,7 @@ void unicode_to_char(guint8 *buf)
  *    
  *
  */
-int parse_obex_header(GNetBuf *buf, GString *str)
+int parse_obex_header(GNetBuf *buf, GString *str, int istext)
 {
        char string[255];
        guint32 tmp_int;
@@ -69,14 +69,19 @@ int parse_obex_header(GNetBuf *buf, GStr
                len += tmp_short;
 
                /* g_print("%s ", string);fflush(stdout); */
-               g_string_sprintfa(str, "%s ", string);
+               g_string_sprintfa(str, "\"%s\" ", string);
                break;
        case OBEX_BYTE_STREAM:
                 /* g_print("OBEX_BYTE_STREAM");fflush(stdout); */
                memcpy(&tmp_short, buf->data+1, 2); /* Align value */
                tmp_short = GINT16_FROM_BE(tmp_short) - 3;
                len += tmp_short + 3;
-               g_string_append(str, "[byte stream]");
+               if(istext) {
+                       memcpy(string, buf->data+3, tmp_short);
+                       string[tmp_short] = '\0';
+                       g_string_sprintfa(str, "\"%s\" ", string);
+               } else
+                       g_string_sprintfa(str, "[%d bytes] ", tmp_short);
                break;
        case OBEX_BYTE:
                /* g_print("OBEX_BYTE");fflush(stdout); */
@@ -106,16 +111,18 @@ int parse_obex_header(GNetBuf *buf, GStr
  */
 inline void parse_obex_headers(GNetBuf *buf, GString *str)
 {
+       struct obex_minimal_frame *frame;
        int final;
        guint16 size;
        int len;
 
+       frame = (struct obex_minimal_frame *) buf->data;
+
        /* We know it's a put frame, but we have to check if it's the final */
-       final = buf->data[0] & OBEX_FINAL;
+       final = frame->opcode & OBEX_FINAL;
 
        /* Length of this frame */
-       memcpy(&size, buf+1, 2);
-       size = ntohs(size);
+       size = ntohs(frame->len);
        
        /* Remove the OBEX common header */
        g_netbuf_pull(buf, 3);
@@ -129,27 +136,35 @@ inline void parse_obex_headers(GNetBuf *
                switch (buf->data[0]) {
                case HEADER_NAME:
                        g_string_append(str, "Name=");
-                       len = parse_obex_header(buf, str);
+                       len = parse_obex_header(buf, str, 0);
                        break;
                case HEADER_DESCRIPTION:
                        g_string_append(str, "Description=");
-                       len = parse_obex_header(buf, str);
+                       len = parse_obex_header(buf, str, 0);
                        break;
                case HEADER_LENGTH:
                        g_string_append(str, "Lenght=");
-                       len = parse_obex_header(buf, str);
+                       len = parse_obex_header(buf, str, 0);
+                       break;
+               case HEADER_TYPE:
+                       g_string_append(str, "Type=");
+                       len = parse_obex_header(buf, str, 1);
+                       break;
+               case HEADER_TARGET:
+                       g_string_append(str, "Target=");
+                       len = parse_obex_header(buf, str, 1);
                        break;
                case HEADER_BODY:
                        g_string_append(str, "body=");
-                       len = parse_obex_header(buf, str);
+                       len = parse_obex_header(buf, str, 0);
                        break;
                case HEADER_BODY_END:
-                       g_string_append(str, "body end=");
-                       len = parse_obex_header(buf, str);
+                       g_string_append(str, "body-end=");
+                       len = parse_obex_header(buf, str, 0);
                        break;
                default:
                        g_string_append(str, "custom=");
-                       len = parse_obex_header(buf, str);
+                       len = parse_obex_header(buf, str, 0);
                        break;
                }
                 /* g_print("len=%d\n", len);fflush(stdout); */
@@ -168,13 +183,49 @@ inline void parse_obex_connect(GNetBuf *
        frame = (struct obex_connect_frame *) buf->data;
 
        length  = ntohs(frame->len);
-       version = frame->version;
-       flags   = frame->flags;
-       mtu     = ntohs(frame->mtu);
-
-       g_string_sprintfa(str, "CONNECT len=%d ver=%d.%d flags=%d mtu=%d ", 
-                         length, ((version & 0xf0) >> 4), version & 0x0f, 
-                         flags, mtu);
+
+       /* Check if it contains connection setup parameters - Jean II */
+       if(length == 7) {
+               version = frame->version;
+               flags   = frame->flags;
+               mtu     = ntohs(frame->mtu);
+
+               g_string_sprintfa(str,
+                                 "CONNECT len=%d ver=%d.%d flags=%d mtu=%d ", 
+                                 length, ((version & 0xf0) >> 4),
+                                 version & 0x0f, flags, mtu);
+       } else
+               g_string_sprintfa(str, "CONNECT len=%d ", length);
+}
+
+/*
+ * The first success frame contains the negociated Obex parameters
+ * Jean II
+ */
+inline void parse_obex_success(GNetBuf *buf, GString *str)
+{
+       struct obex_connect_frame *frame;
+       guint16 length;
+       guint8 version;
+       int flags;
+       guint16 mtu;
+       
+       frame = (struct obex_connect_frame *) buf->data;
+
+       length  = ntohs(frame->len);
+
+       /* Check if it contains connection setup parameters */
+       if(length == 7) {
+               version = frame->version;
+               flags   = frame->flags;
+               mtu     = ntohs(frame->mtu);
+
+               g_string_sprintfa(str,
+                                 "SUCCESS len=%d ver=%d.%d flags=%d mtu=%d ", 
+                                 length, ((version & 0xf0) >> 4),
+                                 version & 0x0f, flags, mtu);
+       } else
+               g_string_sprintfa(str, "SUCCESS len=%d ", length);
 }
 
 /*
@@ -183,9 +234,16 @@ inline void parse_obex_connect(GNetBuf *
  *    Parse OBEX commands and responses
  *
  */
-inline void parse_obex(struct lsap_state *conn, GNetBuf *buf, GString *str)
+inline void parse_obex(struct lsap_state *conn, GNetBuf *buf, GString *str,
+                      int cmd)
 {
-       guint8 opcode;
+       guint8  opcode;
+       int     len;
+
+       /* Check for empty frames - Jean II */
+       len = g_netbuf_get_len(buf);
+       if(len == 0)
+         return;
 
        /* g_print(__FUNCTION__);fflush(stdout); */
 
@@ -193,7 +251,8 @@ inline void parse_obex(struct lsap_state
 
        opcode = buf->data[0] & ~OBEX_FINAL; /* Remove final bit */
 
-       if (conn->obex_rsp) {
+       /* Check if it's a command or response frame - Jean II */
+       if (!cmd) {
                switch (opcode) {
                case OBEX_CONTINUE:
                        g_string_append(str, "CONTINUE ");
@@ -202,7 +261,7 @@ inline void parse_obex(struct lsap_state
                        g_string_append(str, "SWITCH_PRO ");
                        break;
                case OBEX_SUCCESS:
-                       g_string_append(str, "SUCCESS ");
+                       parse_obex_success(buf, str);
                        break;
                case OBEX_CREATED:
                        g_string_append(str, "CREATED ");
@@ -221,7 +280,7 @@ inline void parse_obex(struct lsap_state
                                          opcode);
                        break;
                }
-               /* Next frame is a command */
+               /* Next frame is a command (maybe) */
                conn->obex_rsp = 0;
        } else {
                switch (opcode) {
@@ -255,7 +314,7 @@ inline void parse_obex(struct lsap_state
                                                 opcode);
                        break;
                }
-               /* Next frame should be a response */
+               /* Next frame should be a response (maybe) */
                conn->obex_rsp = 1;
        }
 }

Reply via email to