From Ania:
[obnox/wireshark/wip.git] / epan / dissectors / packet-skinny.c
index 426b01f928312bbdf9209de70677b3dba58cf80d..3667f888641cd9ae154f3605ecb1a8a354ae82aa 100644 (file)
@@ -6,15 +6,15 @@
  *
  * Paul E. Erkkila (pee@erkkila.org) - fleshed out the decode
  * skeleton to report values for most message/message fields.
- * Much help from Guy Harris on figuring out the ethereal api.
+ * Much help from Guy Harris on figuring out the wireshark api.
  *
  * This file is based on packet-aim.c, which is
  * Copyright 2000, Ralf Hoelzer <ralf@well.com>
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
 # include "config.h"
 #endif
 
-#include <string.h>
-
 #include <epan/packet.h>
-#include "prefs.h"
+#include <epan/prefs.h>
+#include <epan/tap.h>
 
 #include "packet-rtp.h"
 #include "packet-tcp.h"
+#include "packet-skinny.h"
 
 #define TCP_PORT_SKINNY 2000
 
@@ -73,6 +73,16 @@ static const true_false_string softKeyMapValues = {
   "Do Not Show"
 };
 
+#define BASIC_MSG_TYPE 0x00
+#define CM7_MSG_TYPE_A 0x12
+#define CM7_MSG_TYPE_B 0x11
+
+static const value_string header_version[] = {
+  { BASIC_MSG_TYPE, "Basic message type" },
+  { CM7_MSG_TYPE_A, "CM7 message type A" },
+  { CM7_MSG_TYPE_B, "CM7 message type B" },
+  { 0             , NULL }
+};
 
 /* I will probably need this again when I change things
  * to function pointers, but let me use the existing
@@ -223,9 +233,12 @@ static const value_string  message_id[] = {
   {0x013C, "AuditConferenceReqMessage"},
   {0x013D, "AuditParticipantReqMessage"},
   {0x013F, "UserToDeviceDataVersion1Message"},
+  {0x014A, "CM5CallInfoMessage"},
+  {0x015A, "XMLAlarmMessage"},
 
   {0     , NULL}       /* terminator */
 };
+static value_string_ext message_id_ext = VALUE_STRING_EXT_INIT(message_id);
 
 /*
  * Device type to text conversion table
@@ -239,9 +252,9 @@ static const value_string  deviceTypes[] = {
   {6  , "Telecaster"},
   {7  , "TelecasterMgr"},
   {8  , "TelecasterBus"},
-       {9  , "Polycom"},
-       {10 , "VGC"},
-       {12 , "ATA"},
+  {9  , "Polycom"},
+  {10 , "VGC"},
+  {12 , "ATA"},
   {20 , "Virtual30SPplus"},
   {21 , "PhoneApplication"},
   {30 , "AnalogAccess"},
@@ -266,7 +279,7 @@ static const value_string  deviceTypes[] = {
   {82 , "LineAnnunciator"},
   {83 , "SoftwareMtpDixieLand"},
   {84 , "CiscoMediaServer"},
-       {85 , "ConferenceBridgeFlint"},
+  {85 , "ConferenceBridgeFlint"},
   {90 , "RouteList"},
   {100, "LoadSimulator"},
   {110, "MediaTerminationPoint"},
@@ -276,16 +289,17 @@ static const value_string  deviceTypes[] = {
   {120, "MGCPStation"},
   {121, "MGCPTrunk"},
   {122, "RASProxy"},
-       {125, "Trunk"},
-       {126, "Annunciator"},
+  {125, "Trunk"},
+  {126, "Annunciator"},
   {127, "MonitorBridge"},
   {128, "Recorder"},
   {129, "MonitorBridgeYoko"},
   {131, "SipTrunk"},
-       {254, "UnknownMGCPGateway"},
+  {254, "UnknownMGCPGateway"},
   {255, "NotDefined"},
   { 0    , NULL}
 };
+static value_string_ext deviceTypes_ext = VALUE_STRING_EXT_INIT(deviceTypes);
 
 /*
  * keypad button -> text conversion
@@ -309,17 +323,18 @@ static const value_string keypadButtons[] = {
   {0xf   , "Pound"},
   {0     , NULL}
 };
+static value_string_ext keypadButtons_ext = VALUE_STRING_EXT_INIT(keypadButtons);
 
 static const value_string deviceStimuli[] = {
-  {1    , "LastNumberRedial"},
-  {2    , "SpeedDial"},
-  {3    , "Hold"},
-  {4    , "Transfer"},
-  {5    , "ForwardAll"},
-  {6    , "ForwardBusy"},
-  {7    , "ForwardNoAnswer"},
-  {8    , "Display"},
-  {9    , "Line"},
+  {0x1  , "LastNumberRedial"},
+  {0x2  , "SpeedDial"},
+  {0x3  , "Hold"},
+  {0x4  , "Transfer"},
+  {0x5  , "ForwardAll"},
+  {0x6  , "ForwardBusy"},
+  {0x7  , "ForwardNoAnswer"},
+  {0x8  , "Display"},
+  {0x9  , "Line"},
   {0xa  , "T120Chat"},
   {0xb  , "T120Whiteboard"},
   {0xc  , "T120ApplicationSharing"},
@@ -328,22 +343,23 @@ static const value_string deviceStimuli[] = {
   {0xf  , "VoiceMail"},
   {0x10 , "AutoAnswerRelease"},
   {0x11 , "AutoAnswer"},
-       {0x12 , "Select"},
-       {0x13 , "Privacy"},
-       {0x14 , "ServiceURL"},
-       {0x1B , "MaliciousCall"},
+  {0x12 , "Select"},
+  {0x13 , "Privacy"},
+  {0x14 , "ServiceURL"},
+  {0x1B , "MaliciousCall"},
   {0x21 , "GenericAppB1"},
   {0x22 , "GenericAppB2"},
   {0x23 , "GenericAppB3"},
   {0x24 , "GenericAppB4"},
   {0x25 , "GenericAppB5"},
   {0x7b , "MeetMeConference"},
-  {0x7d , "Conference=0x7d"},
-  {0x7e , "CallPark=0x7e"},
+  {0x7d , "Conference"},
+  {0x7e , "CallPark"},
   {0x7f , "CallPickup"},
-  {0x80 , "GroupCallPickup=80"},
+  {0x80 , "GroupCallPickup"},
   {0,NULL}
 };
+static value_string_ext deviceStimuli_ext = VALUE_STRING_EXT_INIT(deviceStimuli);
 
 
 /* Note i'm only using 7 later on cuz i'm lazy ;) */
@@ -379,14 +395,15 @@ static const value_string mediaPayloads[] = {
   {84  , "G.726 16K"},
   {85  , "G.729B"},
   {86  , "G.729B Low Complexity"},
-       {100 , "H261"},
-       {101 , "H263"},
-       {102 , "Vieo"},
-       {105 , "T120"},
-       {106 , "H224"},
-       {257 , "RFC2833_DynPayload"},
+  {100 , "H261"},
+  {101 , "H263"},
+  {102 , "Video"},
+  {105 , "T120"},
+  {106 , "H224"},
+  {257 , "RFC2833_DynPayload"},
   {0  , NULL}
 };
+static value_string_ext mediaPayloads_ext = VALUE_STRING_EXT_INIT(mediaPayloads);
 
 static const value_string alarmSeverities[] = {
   {0   , "Critical"},
@@ -399,6 +416,7 @@ static const value_string alarmSeverities[] = {
   {20  , "TraceInfo"},
   {0  , NULL}
 };
+static value_string_ext alarmSeverities_ext = VALUE_STRING_EXT_INIT(alarmSeverities);
 
 static const value_string multicastMediaReceptionStatus[] = {
   {0  , "Ok"},
@@ -424,7 +442,7 @@ static const value_string softKeyEvents[] = {
   {1   , "Redial"},
   {2   , "NewCall"},
   {3   , "Hold"},
-  {4   , "Trnsfer"},
+  {4   , "Transfer"},
   {5   , "CFwdAll"},
   {6   , "CFwdBusy"},
   {7   , "CFwdNoAnswer"},
@@ -441,6 +459,7 @@ static const value_string softKeyEvents[] = {
   {18  , "GrpCallPickUp"},
   {0   , NULL}
 };
+static value_string_ext softKeyEvents_ext = VALUE_STRING_EXT_INIT(softKeyEvents);
 
 /* Define info index for each softkey event for Telecaster station. */
 static const value_string softKeyIndexes[] = {
@@ -464,18 +483,19 @@ static const value_string softKeyIndexes[] = {
   {318  , "GrpCallPickUpInfoIndex"},
   {0   , NULL}
 };
+static value_string_ext softKeyIndexes_ext = VALUE_STRING_EXT_INIT(softKeyIndexes);
 
 
 static const value_string buttonDefinitions[] = {
-  {1    , "LastNumberRedial"},
-  {2    , "SpeedDial"},
-  {3    , "Hold"},
-  {4    , "Transfer"},
-  {5    , "ForwardAll"},
-  {6    , "ForwardBusy"},
-  {7    , "ForwardNoAnswer"},
-  {8    , "Display"},
-  {9    , "Line"},
+  {0x1  , "LastNumberRedial"},
+  {0x2  , "SpeedDial"},
+  {0x3  , "Hold"},
+  {0x4  , "Transfer"},
+  {0x5  , "ForwardAll"},
+  {0x6  , "ForwardBusy"},
+  {0x7  , "ForwardNoAnswer"},
+  {0x8  , "Display"},
+  {0x9  , "Line"},
   {0xa  , "T120Chat"},
   {0xb  , "T120Whiteboard"},
   {0xc  , "T120ApplicationSharing"},
@@ -487,6 +507,7 @@ static const value_string buttonDefinitions[] = {
   {0xff , "Undefined"},
   {0   , NULL}
 };
+static value_string_ext buttonDefinitions_ext = VALUE_STRING_EXT_INIT(buttonDefinitions);
 
 #define StationTotalSoftKeySets 10 /* total number of the soft key sets */
 static const value_string keySetNames[] = {
@@ -502,9 +523,11 @@ static const value_string keySetNames[] = {
   {9   , "OffHook with features"},
   {0   , NULL}
 };
+static value_string_ext keySetNames_ext = VALUE_STRING_EXT_INIT(keySetNames);
 
+#if 0
 /* Define soft key labels for the Telecaster station */
-static const value_string softKeyLabel[] = {
+static const value_string softKeyLabel[] _U_ = {
   {0   , "undefined"},
   {1   , "Redial"},
   {2   , "NewCall"},
@@ -526,7 +549,7 @@ static const value_string softKeyLabel[] = {
   {18  , "GPickUp"},
   {0   , NULL}
 };
-
+#endif
 
 /*
  * define lamp modes;
@@ -545,6 +568,7 @@ static const value_string stationLampModes[] = {
   {0x5 , "Blink"},
   {0   , NULL}
 };
+static value_string_ext stationLampModes_ext = VALUE_STRING_EXT_INIT(stationLampModes);
 
 /* Defined the Call States to be sent to the Telecaste station.
  * These are NOT the call states used in CM internally. Instead,
@@ -567,6 +591,7 @@ static const value_string skinny_stationCallStates[] = {
   {14  , "InvalidNumber"},
   {0   , NULL}
 };
+static value_string_ext skinny_stationCallStates_ext = VALUE_STRING_EXT_INIT(skinny_stationCallStates);
 
 /* Defined Call Type */
 static const value_string skinny_callTypes[] = {
@@ -581,16 +606,16 @@ static const value_string skinny_callTypes[] = {
  * for tone definitions see SR-TSV-002275, "BOC Notes on the LEC Networks -- 1994"
  */
 static const value_string skinny_deviceTones[] = {
-  {0    , "Silence"},
-  {1    , "Dtmf1"},
-  {2    , "Dtmf2"},
-  {3    , "Dtmf3"},
-  {4    , "Dtmf4"},
-  {5    , "Dtmf5"},
-  {6    , "Dtmf6"},
-  {7    , "Dtmf7"},
-  {8    , "Dtmf8"},
-  {9    , "Dtmf9"},
+  {0x0  , "Silence"},
+  {0x1  , "Dtmf1"},
+  {0x2  , "Dtmf2"},
+  {0x3  , "Dtmf3"},
+  {0x4  , "Dtmf4"},
+  {0x5  , "Dtmf5"},
+  {0x6  , "Dtmf6"},
+  {0x7  , "Dtmf7"},
+  {0x8  , "Dtmf8"},
+  {0x9  , "Dtmf9"},
   {0xa  , "Dtmf0"},
   {0xe  , "DtmfStar"},
   {0xf  , "DtmfPound"},
@@ -620,7 +645,7 @@ static const value_string skinny_deviceTones[] = {
   {0x34 , "MusicTone"},
   {0x35 , "HoldTone"},
   {0x36 , "TestTone"},
-       {0x37 , "DtMoniterWarningTone"},
+  {0x37 , "DtMoniterWarningTone"},
   {0x40 , "AddCallWaiting"},
   {0x41 , "PriorityCallWait"},
   {0x42 , "RecallDial"},
@@ -666,6 +691,7 @@ static const value_string skinny_deviceTones[] = {
   {0x7f , "NoTone"},
   {0   , NULL}
 };
+static value_string_ext skinny_deviceTones_ext = VALUE_STRING_EXT_INIT(skinny_deviceTones);
 
 /* define ring types */
 static const value_string skinny_ringTypes[] = {
@@ -677,6 +703,13 @@ static const value_string skinny_ringTypes[] = {
   {0x6  , "PrecedenceRing"},
   {0   , NULL}
 };
+static value_string_ext skinny_ringTypes_ext = VALUE_STRING_EXT_INIT(skinny_ringTypes);
+
+static const value_string skinny_ringModes[] = {
+  {0x1  , "RingForever"},
+  {0x2  , "RingOnce"},
+  {0   , NULL}
+};
 
 static const value_string skinny_speakerModes[] = {
   {1   , "SpeakerOn"},
@@ -734,6 +767,7 @@ static const value_string skinny_modifyConfResults[] = {
   {6   , "SystemErr"},
   {0   , NULL}
 };
+static value_string_ext skinny_modifyConfResults_ext = VALUE_STRING_EXT_INIT(skinny_modifyConfResults);
 
 static const value_string skinny_deleteConfResults[] = {
   {0   , "Ok"},
@@ -750,6 +784,7 @@ static const value_string skinny_addParticipantResults[] = {
   {4   , "SystemErr"},
   {0   , NULL}
 };
+static value_string_ext skinny_addParticipantResults_ext = VALUE_STRING_EXT_INIT(skinny_addParticipantResults);
 
 static const value_string skinny_auditParticipantResults[] = {
   {0   , "Ok"},
@@ -791,6 +826,7 @@ static const value_string skinny_sessionTypes[] = {
   {10  , "Video"},
   {0   , NULL}
 };
+static value_string_ext skinny_sessionTypes_ext = VALUE_STRING_EXT_INIT(skinny_sessionTypes);
 
 static const value_string skinny_mediaEnunciationTypes[] = {
   {1  , "None"},
@@ -825,6 +861,7 @@ static const value_string skinny_Layouts[] = {
   {10 , "ThreeByThree4Alt2"},
   {0  , NULL}
 };
+static value_string_ext skinny_Layouts_ext = VALUE_STRING_EXT_INIT(skinny_Layouts);
 
 static const value_string skinny_transmitOrReceive[] = {
   {1  , "Station_Receive_only"},
@@ -863,6 +900,7 @@ static const value_string skinny_miscCommandType[] = {
   {7  , "temporalSpatialTradeOff"},
   {0  , NULL}
 };
+static value_string_ext skinny_miscCommandType_ext = VALUE_STRING_EXT_INIT(skinny_miscCommandType);
 
 static const value_string skinny_formatTypes[] = {
   {1  , "sqcif (128x96)"},
@@ -873,6 +911,7 @@ static const value_string skinny_formatTypes[] = {
   {6  , "custom_base"},
   {0  , NULL}
 };
+static value_string_ext skinny_formatTypes_ext = VALUE_STRING_EXT_INIT(skinny_formatTypes);
 
 static const value_string cast_callSecurityStatusTypes[] = {
   {0   , "CallSecurityStatusUnknown"},
@@ -883,6 +922,7 @@ static const value_string cast_callSecurityStatusTypes[] = {
 
 #define StationMaxDirnumSize 24         /* max size of calling or called party dirnum  */
 #define StationMaxNameSize 40           /* max size of calling party's name  */
+#define StationMaxDisplayNameSize 44    /* max size of display name  */
 #define StationMaxDeviceNameSize 16     /* max size of station's IP name  */
 #define StationMaxSpeedDials 10         /* max number of speed dial numbers allowed on a station */
 #define StationMaxVersionSize 16        /* max chars in version string  */
@@ -901,30 +941,28 @@ static const value_string cast_callSecurityStatusTypes[] = {
 #define StationMaxDisplayPromptStatusSize 32 /* max status text size in the display status message */
 #define StationMaxDisplayNotifySize 32       /* max prompt text size in the display prompt message */
 #define StationMaxAlarmMessageSize 80        /* max size for an alarm message */
-#define StationMaxUserDeviceDataSize   2000    /* max size of user data between application and device */
-#define StationMaxConference   32
-#define AppConferenceIDSize            32
-#define AppDataSize                            24
-#define MAX_CUSTOM_PICTURES                            6
-#define MAX_LAYOUT_WITH_SAME_SERVICE   5
-#define MAX_SERVICE_TYPE                               4
-#define DeviceMaxCapabilities       18  /* max capabilities allowed in Cap response message */
+#define StationMaxUserDeviceDataSize 2000    /* max size of user data between application and device */
+#define StationMaxConference 32
+#define AppConferenceIDSize 32
+#define AppDataSize 24
+#define MAX_CUSTOM_PICTURES 6
+#define MAX_LAYOUT_WITH_SAME_SERVICE 5
+#define MAX_SERVICE_TYPE 4
+#define DeviceMaxCapabilities 18         /* max capabilities allowed in Cap response message */
 #define StationMaxCapabilities       DeviceMaxCapabilities
-#define StationMaxVideoCapabilities    10
-#define StationMaxDataCapabilities   5
-#define MAX_LEVEL_PREFERENCE            4
-#define MaxAnnouncementList    32
-#define StationMaxMonitorParties       16          /* Max Monitor Bridge whisper matrix parties,  rm, M&R in Parche */
-#define StationMaxServiceURLSize     256       /* max number of service URLs length */
-#define MAX_PICTURE_FORMAT                      5
-#define MAX_REFERENCE_PICTURE           4
-
-static void dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+#define StationMaxVideoCapabilities 10
+#define StationMaxDataCapabilities  5
+#define MAX_LEVEL_PREFERENCE 4
+#define MaxAnnouncementList 32
+#define StationMaxMonitorParties 16      /* Max Monitor Bridge whisper matrix parties,  rm, M&R in Parche */
+#define StationMaxServiceURLSize 256    /* max number of service URLs length */
+#define MAX_PICTURE_FORMAT 5
+#define MAX_REFERENCE_PICTURE 4
 
 /* Initialize the protocol and registered fields */
 static int proto_skinny          = -1;
 static int hf_skinny_data_length = -1;
-static int hf_skinny_reserved    = -1;
+static int hf_skinny_hdr_version = -1;
 static int hf_skinny_messageid   = -1;
 static int hf_skinny_deviceName  = -1;
 static int hf_skinny_stationUserId = -1;
@@ -1001,6 +1039,7 @@ static int hf_skinny_messageTimeOutValue = -1;
 static int hf_skinny_displayMessage = -1;
 static int hf_skinny_lineDirNumber = -1;
 static int hf_skinny_lineFullyQualifiedDisplayName = -1;
+static int hf_skinny_lineDisplayName = -1;
 static int hf_skinny_speedDialDirNumber = -1;
 static int hf_skinny_speedDialDisplayName = -1;
 static int hf_skinny_dateYear = -1;
@@ -1021,6 +1060,7 @@ static int hf_skinny_callType = -1;
 static int hf_skinny_originalCalledPartyName = -1;
 static int hf_skinny_originalCalledParty = -1;
 static int hf_skinny_ringType = -1;
+static int hf_skinny_ringMode = -1;
 static int hf_skinny_speakerMode = -1;
 static int hf_skinny_remoteIpAddr = -1;
 static int hf_skinny_remotePortNumber = -1;
@@ -1037,7 +1077,7 @@ static int hf_skinny_detectInterval = -1;
 static int hf_skinny_microphoneMode = -1;
 static int hf_skinny_headsetMode = -1;
 static int hf_skinny_unknown = -1;
-static int hf_skinny_data = -1;
+static int hf_skinny_xmlData = -1;
 static int hf_skinny_activeForward = -1;
 static int hf_skinny_forwardAllActive = -1;
 static int hf_skinny_forwardBusyActive = -1;
@@ -1158,6 +1198,10 @@ static int hf_cast_lastRedirectingReason = -1;
 static int hf_cast_callInstance = -1;
 static int hf_cast_callSecurityStatus = -1;
 
+/* Skinny content type and internet media type used by other dissectors
+ *  * are the same.  List of media types from IANA at:
+ *   * http://www.iana.org/assignments/media-types/index.html */
+static dissector_table_t media_type_dissector_table;
 
 /* Initialize the subtree pointers */
 static gint ett_skinny          = -1;
@@ -1167,11 +1211,19 @@ static gint ett_skinny_softKeyMap = -1;
 /* desegmentation of SCCP */
 static gboolean skinny_desegment = TRUE;
 
-static dissector_handle_t data_handle;
 static dissector_handle_t rtp_handle=NULL;
 
+/* tap register id */
+static int skinny_tap = -1;
+
+/* skinny protocol tap info */
+#define MAX_SKINNY_MESSAGES_IN_PACKET 10
+static skinny_info_t pi_arr[MAX_SKINNY_MESSAGES_IN_PACKET];
+static int pi_current = 0;
+static skinny_info_t *si;
+
 /* Get the length of a single SCCP PDU */
-static guint get_skinny_pdu_len(tvbuff_t *tvb, int offset)
+static guint get_skinny_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
 {
   guint32 hdr_data_length;
 
@@ -1187,16 +1239,35 @@ static guint get_skinny_pdu_len(tvbuff_t *tvb, int offset)
   return hdr_data_length + 8;
 }
 
+static void
+dissect_skinny_xml(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, const gint start, gint length)
+{
+  proto_item *item = NULL;
+  proto_tree *subtree = NULL;
+  tvbuff_t *next_tvb;
+  dissector_handle_t handle;
+
+  item = proto_tree_add_item(tree, hf_skinny_xmlData, tvb, start, length, TRUE);
+  subtree = proto_item_add_subtree(item, 0);
+  next_tvb = tvb_new_subset(tvb, start, length, -1);
+  handle = dissector_get_string_handle(media_type_dissector_table, "text/xml");
+  if (handle != NULL) {
+    gboolean dissected;
+    dissected = call_dissector(handle, next_tvb, pinfo, subtree);
+   }
+}
+
 /* Dissect a single SCCP PDU */
-static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static void
+dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
   int offset = 0;
+  gboolean is_video = FALSE; /* FIX ME: need to indicate video or not */
 
   /* Header fields */
   guint32 hdr_data_length;
-  guint32 hdr_reserved;
+  guint32 hdr_version;
   guint32 data_messageid;
-  gchar   *messageid_str;
   /*  guint32 data_size; */
 
   guint i = 0;
@@ -1222,41 +1293,53 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
   proto_item *skm_tree = NULL;
 
   hdr_data_length = tvb_get_letohl(tvb, offset);
-  hdr_reserved    = tvb_get_letohl(tvb, offset+4);
+  hdr_version     = tvb_get_letohl(tvb, offset+4);
   data_messageid  = tvb_get_letohl(tvb, offset+8);
 
+  /* Initialise stat info for passing to tap */
+  pi_current++;
+  if (pi_current == MAX_SKINNY_MESSAGES_IN_PACKET)
+  {
+       /* Overwrite info in first struct if run out of space... */
+       pi_current = 0;
+  }
+  si = &pi_arr[pi_current];
+  si->messId = data_messageid;
+  si->messageName = val_to_str_ext(data_messageid, &message_id_ext, "0x%08X (Unknown)");
+  si->callId = 0;
+  si->lineId = 0;
+  si->passThruId = 0;
+  si->callState = 0;
+  g_free(si->callingParty);
+  si->callingParty = NULL;
+  g_free(si->calledParty);
+  si->calledParty = NULL;
+
   /* In the interest of speed, if "tree" is NULL, don't do any work not
    * necessary to generate protocol tree items. */
   if (tree) {
     ti = proto_tree_add_item(tree, proto_skinny, tvb, offset, hdr_data_length+8, FALSE);
     skinny_tree = proto_item_add_subtree(ti, ett_skinny);
     proto_tree_add_uint(skinny_tree, hf_skinny_data_length, tvb, offset, 4, hdr_data_length);
-    proto_tree_add_uint(skinny_tree, hf_skinny_reserved, tvb, offset+4, 4, hdr_reserved);
+    proto_tree_add_uint(skinny_tree, hf_skinny_hdr_version, tvb, offset+4, 4, hdr_version);
   }
 
-  messageid_str = val_to_str(data_messageid, message_id, "0x%08X (Unknown)");
-
   if (check_col(pinfo->cinfo, COL_INFO)) {
-    col_add_str(pinfo->cinfo, COL_INFO, messageid_str);
+    col_add_fstr(pinfo->cinfo, COL_INFO,"%s ", si->messageName);
+       col_set_fence(pinfo->cinfo, COL_INFO);
   }
 
   if (tree) {
     proto_tree_add_uint(skinny_tree, hf_skinny_messageid, tvb,offset+8, 4, data_messageid );
   }
 
-  if (tree) {
+  {
     switch(data_messageid) {
 
     /* cases that do not need to be decoded */
     case 0x0 :    /* keepAlive */
       break;
 
-    case 0x6 :    /* offHook */
-      break;
-
-    case 0x7 :    /* onHook    */
-      break;
-
     case 0x8 :    /* hookFlash */
       break;
 
@@ -1284,9 +1367,6 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x28 :   /* softKeyTemplateRequest */
       break;
 
-    case 0x83 :   /* stopTone */
-      break;
-
     case 0x9a :   /* clearDisplay */
       break;
 
@@ -1317,7 +1397,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_deviceName, tvb, offset+12, StationMaxDeviceNameSize, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_stationUserId, tvb, offset+28, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_stationInstance, tvb, offset+32, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+36, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+36, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_deviceType, tvb, offset+40, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_maxStreams, tvb, offset+44, 4, TRUE);
       break;
@@ -1328,6 +1408,12 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
     case 0x3 :  /* keyPadButtonMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_stationKeypadButton, tvb, offset+12, 4, TRUE);
+      if (hdr_data_length > 8) {
+                 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+16, 4, TRUE);
+                 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
+                 si->lineId = tvb_get_letohl(tvb, offset+16);
+                 si->callId = tvb_get_letohl(tvb, offset+20);
+      }
       break;
 
     case 0x4 :  /* stationEnblocCallMessage -- This decode NOT verified*/
@@ -1337,6 +1423,28 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x5 : /* stationStimulusMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_stimulus, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_stimulusInstance, tvb, offset+16, 4, TRUE);
+      if (hdr_data_length > 12) {
+                 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
+             si->callId = tvb_get_letohl(tvb, offset+20);
+      }
+      break;
+
+    case 0x6 :    /* offHook */
+      if (hdr_data_length > 4) {
+                 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
+                 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+                 si->lineId = tvb_get_letohl(tvb, offset+12);
+                 si->callId = tvb_get_letohl(tvb, offset+16);
+      }
+      break;
+
+    case 0x7 :    /* onHook    */
+      if (hdr_data_length > 4) {
+                 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
+                 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+                 si->lineId = tvb_get_letohl(tvb, offset+12);
+                 si->callId = tvb_get_letohl(tvb, offset+16);
+      }
       break;
 
     case 0x9  : /* stationForwardStatReqMessage */
@@ -1375,28 +1483,50 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_alarmSeverity, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, StationMaxAlarmMessageSize, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_alarmParam1, tvb, offset+96, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_alarmParam2, tvb, offset+100, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_alarmParam2, tvb, offset+100, 4, FALSE);
       break;
 
     case 0x21 : /* stationMulticastMediaReceptionAck - This decode NOT verified*/
       proto_tree_add_item(skinny_tree, hf_skinny_receptionStatus, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x22 : /* stationOpenReceiveChannelAck */
-      proto_tree_add_item(skinny_tree, hf_skinny_ORCStatus, tvb, offset+12, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+16, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_portNumber, tvb, offset+20, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+24, 4, TRUE);
-      if((!pinfo->fd->flags.visited) && rtp_handle){
-           address src_addr;
-           guint32 ipv4_address;
-
-           src_addr.type=AT_IPv4;
-           src_addr.len=4;
-           src_addr.data=(char *)&ipv4_address;
-           tvb_memcpy(tvb, (char *)&ipv4_address, offset+16, 4);
-           rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+20), 0, "Skinny", pinfo->fd->num);
+      if (hdr_version == BASIC_MSG_TYPE) {
+        proto_tree_add_item(skinny_tree, hf_skinny_ORCStatus, tvb, offset+12, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+16, 4, FALSE);
+        proto_tree_add_item(skinny_tree, hf_skinny_portNumber, tvb, offset+20, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+24, 4, TRUE);
+        if (rtp_handle) {
+          address src_addr;
+          guint32 ipv4_address;
+
+          src_addr.type = AT_IPv4;
+          src_addr.len = 4;
+          src_addr.data = (guint8 *)&ipv4_address;
+          ipv4_address = tvb_get_ipv4(tvb, offset+16);
+          rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+20), 0, "Skinny", pinfo->fd->num, is_video, NULL);
+        }
+        si->passThruId = tvb_get_letohl(tvb, offset+24);
+      } else if (hdr_version == CM7_MSG_TYPE_A || hdr_version == CM7_MSG_TYPE_B) {
+        proto_tree_add_item(skinny_tree, hf_skinny_ORCStatus, tvb, offset+12, 4, TRUE);
+        /* unknown uint32_t stuff */
+        proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+20, 4, FALSE);
+        /* 3x unknown uint32_t stuff, space for IPv6 maybe */
+        proto_tree_add_item(skinny_tree, hf_skinny_portNumber, tvb, offset+36, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+40, 4, TRUE);
+        if (rtp_handle) {
+          address src_addr;
+          guint32 ipv4_address;
+
+          src_addr.type = AT_IPv4;
+          src_addr.len = 4;
+          src_addr.data = (guint8 *)&ipv4_address;
+          ipv4_address = tvb_get_ipv4(tvb, offset+20);
+          rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+36), 0, "Skinny", pinfo->fd->num, is_video, NULL);
+        }
+        si->passThruId = tvb_get_letohl(tvb, offset+40);
       }
       break;
 
@@ -1411,6 +1541,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_packetsLost, tvb, offset+60, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_jitter, tvb, offset+64, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_latency, tvb, offset+68, 4, TRUE);
+      si->callId = tvb_get_letohl(tvb, offset+36);
       break;
 
     case 0x24 : /* offHookWithCgpn */
@@ -1421,6 +1552,8 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_softKeyEvent, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x29 : /* registerTokenREq */
@@ -1428,16 +1561,18 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       i = offset+12+StationMaxDeviceNameSize;
       proto_tree_add_item(skinny_tree, hf_skinny_stationUserId, tvb, i, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_stationInstance, tvb, i+4, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, i+8, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, i+8, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_deviceType, tvb, i+12, 4, TRUE);
       break;
 
     case 0x2A : /* MediaTransmissionFailure */
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+20, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+20, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_portNumber, tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+28, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+28);
       break;
 
     case 0x2B : /* HeadsetStatusMessage */
@@ -1462,7 +1597,9 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_transactionID, tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_data_length, tvb, offset+28, 4, TRUE);
       count = tvb_get_letohl( tvb, offset+28);
-      proto_tree_add_uint(skinny_tree, hf_skinny_data, tvb, offset+30, 1, count);
+      dissect_skinny_xml(skinny_tree, tvb, pinfo, offset+30, count);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x2F : /* DeviceToUserDataResponseMessage */
@@ -1472,7 +1609,9 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_transactionID, tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_data_length, tvb, offset+28, 4, TRUE);
       count = tvb_get_letohl( tvb, offset+28);
-      proto_tree_add_uint(skinny_tree, hf_skinny_data, tvb, offset+30, 1, count);
+      dissect_skinny_xml(skinny_tree, tvb, pinfo, offset+30, count);
+      si->lineId = tvb_get_letohl(tvb, offset+12);
+      si->callId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x30 : /* UpdateCapabilitiesMessage */
@@ -1609,10 +1748,12 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
     case 0x31 : /* OpenMultiMediaReceiveChannelAckMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_ORCStatus, tvb, offset+12, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+16, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+16, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_portNumber, tvb, offset+20, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+28, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+24);
+      si->callId = tvb_get_letohl(tvb, offset+28);
       break;
 
     case 0x32 : /* ClearConferenceMessage */
@@ -1653,6 +1794,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_addParticipantResults, tvb, offset+20, 4, TRUE);
+      si->callId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x39 : /* AuditConferenceResMessage */
@@ -1700,7 +1842,9 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+38, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_appInstanceID, tvb, offset+42, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_routingID, tvb, offset+46, 4, TRUE);
-      proto_tree_add_uint(skinny_tree, hf_skinny_data, tvb, offset+50, 1, count);
+      dissect_skinny_xml(skinny_tree, tvb, pinfo, offset+50, count);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x42 : /* DeviceToUserDataResponseVersion1Message */
@@ -1715,7 +1859,9 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+38, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_appInstanceID, tvb, offset+42, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_routingID, tvb, offset+46, 4, TRUE);
-      proto_tree_add_uint(skinny_tree, hf_skinny_data, tvb, offset+50, 1, count);
+      dissect_skinny_xml(skinny_tree, tvb, pinfo, offset+50, count);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
 
@@ -1732,10 +1878,33 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
     case 0x82 :  /* startTone */
       proto_tree_add_item(skinny_tree, hf_skinny_deviceTone, tvb, offset+12, 4, TRUE);
+      /* offset 16 to 19: reserved */
+      if (hdr_data_length > 12) {
+                 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+20, 4, TRUE);
+                 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+24, 4, TRUE);
+                 si->lineId = tvb_get_letohl(tvb, offset+20);
+                 si->callId = tvb_get_letohl(tvb, offset+24);
+      }
+      break;
+
+    case 0x83 :   /* stopTone */
+      if (hdr_data_length > 4) {
+                 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
+                 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+                 si->lineId = tvb_get_letohl(tvb, offset+12);
+                 si->callId = tvb_get_letohl(tvb, offset+16);
+      }
       break;
 
     case 0x85 : /* setRingerMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_ringType, tvb, offset+12, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_ringMode, tvb, offset+16, 4, TRUE);
+      if (hdr_data_length > 12) {
+                 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+20, 4, TRUE);
+                 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+24, 4, TRUE);
+                 si->lineId = tvb_get_letohl(tvb, offset+20);
+                 si->callId = tvb_get_letohl(tvb, offset+24);
+      }
       break;
 
     case 0x86 : /* setLampMessage */
@@ -1758,33 +1927,63 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_microphoneMode, tvb, offset+12, 4, TRUE);
       break;
 
-    case 0x8a : /* startMediaTransmistion */
-      proto_tree_add_item(skinny_tree, hf_skinny_conferenceID,          tvb, offset+12, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID,       tvb, offset+16, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr,          tvb, offset+20, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_remotePortNumber,      tvb, offset+24, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+28, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability,     tvb, offset+32, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_precedenceValue,       tvb, offset+36, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_silenceSuppression,    tvb, offset+40, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket,    tvb, offset+44, 2, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate,           tvb, offset+48, 4, TRUE);
-      if((!pinfo->fd->flags.visited) && rtp_handle){
-           address src_addr;
-           guint32 ipv4_address;
-
-           src_addr.type=AT_IPv4;
-           src_addr.len=4;
-           src_addr.data=(char *)&ipv4_address;
-           tvb_memcpy(tvb, (char *)&ipv4_address, offset+20, 4);
-           rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+24), 0, "Skinny", pinfo->fd->num);
+    case 0x8a : /* startMediaTransmission */
+      if (hdr_version == BASIC_MSG_TYPE) {
+        proto_tree_add_item(skinny_tree, hf_skinny_conferenceID,          tvb, offset+12, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID,       tvb, offset+16, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr,          tvb, offset+20, 4, FALSE);
+        proto_tree_add_item(skinny_tree, hf_skinny_remotePortNumber,      tvb, offset+24, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+28, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability,     tvb, offset+32, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_precedenceValue,       tvb, offset+36, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_silenceSuppression,    tvb, offset+40, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket,    tvb, offset+44, 2, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate,           tvb, offset+48, 4, TRUE);
+        if (rtp_handle) {
+          address src_addr;
+          guint32 ipv4_address;
+
+          src_addr.type = AT_IPv4;
+          src_addr.len = 4;
+          src_addr.data = (char *)&ipv4_address;
+          ipv4_address = tvb_get_ipv4(tvb, offset+20);
+          rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+24), 0, "Skinny", pinfo->fd->num, is_video, NULL);
+        }
+        si->passThruId = tvb_get_letohl(tvb, offset+16);
+      }
+      else if (hdr_version == CM7_MSG_TYPE_A || hdr_version == CM7_MSG_TYPE_B)
+      {
+        proto_tree_add_item(skinny_tree, hf_skinny_conferenceID,          tvb, offset+12, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID,       tvb, offset+16, 4, TRUE);
+        /* unknown uint32_t stuff */
+        proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr,          tvb, offset+24, 4, FALSE);
+        /* 3x unknown uint32_t stuff, space for IPv6 maybe */
+        proto_tree_add_item(skinny_tree, hf_skinny_remotePortNumber,      tvb, offset+40, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+44, 4, TRUE);
+        proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability,     tvb, offset+48, 4, TRUE);
+        /* There is some more... */
+        /* proto_tree_add_item(skinny_tree, hf_skinny_precedenceValue,       tvb, offset+52, 4, TRUE); */
+        /* proto_tree_add_item(skinny_tree, hf_skinny_silenceSuppression,    tvb, offset+56, 4, TRUE); */
+        /* proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket,    tvb, offset+60, 2, TRUE); */
+        /* proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate,           tvb, offset+62, 4, TRUE); */
+        if (rtp_handle) {
+          address src_addr;
+          guint32 ipv4_address;
+
+          src_addr.type = AT_IPv4;
+          src_addr.len = 4;
+          src_addr.data = (char *)&ipv4_address;
+          ipv4_address = tvb_get_ipv4(tvb, offset+24);
+          rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+40), 0, "Skinny", pinfo->fd->num, is_video, NULL);
+        }
+        si->passThruId = tvb_get_letohl(tvb, offset+16);
       }
       break;
 
     case 0x8b :  /* stopMediaTransmission */
-
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x8c : /* startMediaReception */
@@ -1799,16 +1998,20 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x8f : /* callInfo */
       i = offset+12;
       proto_tree_add_item(skinny_tree, hf_skinny_callingPartyName, tvb, i, StationMaxNameSize, TRUE);
-      i += StationMaxNameSize;
       proto_tree_add_item(skinny_tree, hf_skinny_callingParty, tvb, i, StationMaxDirnumSize, TRUE);
+      i += StationMaxNameSize;
+      si->callingParty = g_strdup(tvb_format_stringzpad(tvb, i, StationMaxDirnumSize));
       i += StationMaxDirnumSize;
       proto_tree_add_item(skinny_tree, hf_skinny_calledPartyName, tvb, i, StationMaxNameSize, TRUE);
       i += StationMaxNameSize;
       proto_tree_add_item(skinny_tree, hf_skinny_calledParty, tvb, i, StationMaxDirnumSize, TRUE);
+      si->calledParty = g_strdup(tvb_format_stringzpad(tvb, i, StationMaxDirnumSize));
       i += StationMaxDirnumSize;
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, i, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, i);
       i += 4;
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, i, 4, TRUE);
+      si->callId = tvb_get_letohl(tvb, i);
       i += 4;
       proto_tree_add_item(skinny_tree, hf_skinny_callType, tvb, i, 4, TRUE);
       i += 4;
@@ -1837,23 +2040,23 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_cast_callSecurityStatus, tvb, i, 4, TRUE);
       i += 4;
       val = tvb_get_letohl( tvb, i);
-                 ti_sub = proto_tree_add_text(skinny_tree, tvb, offset, 8, "partyPIRestrictionBits");
-                 skinny_sub_tree = proto_item_add_subtree(ti_sub, ett_skinny_tree);
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      ti_sub = proto_tree_add_text(skinny_tree, tvb, i, 8, "partyPIRestrictionBits");
+      skinny_sub_tree = proto_item_add_subtree(ti_sub, ett_skinny_tree);
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x01, 4*8, "Does RestrictCallingPartyName", "Doesn't RestrictCallingPartyName"));
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x02, 4*8, "Does RestrictCallingPartyNumber", "Doesn't RestrictCallingPartyNumber"));
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x04, 4*8, "Does RestrictCalledPartyName", "Doesn't RestrictCalledPartyName"));
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x08, 4*8, "Does RestrictCalledPartyNumber", "Doesn't RestrictCalledPartyNumber"));
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x10, 4*8, "Does RestrictOriginalCalledPartyName", "Doesn't RestrictOriginalCalledPartyName"));
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x20, 4*8, "Does RestrictOriginalCalledPartyNumber", "Doesn't RestrictOriginalCalledPartyNumber"));
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x40, 4*8, "Does RestrictLastRedirectPartyName", "Doesn't RestrictLastRedirectPartyName"));
-      proto_tree_add_text(skinny_sub_tree, tvb, i, 4,
+      proto_tree_add_text(skinny_sub_tree, tvb, i, 4, "%s",
              decode_boolean_bitfield( val, 0x80, 4*8, "Does RestrictLastRedirectPartyNumber", "Doesn't RestrictLastRedirectPartyNumber"));
       break;
 
@@ -1882,6 +2085,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_lineNumber, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_lineDirNumber, tvb, offset+16, StationMaxDirnumSize, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_lineFullyQualifiedDisplayName, tvb, offset+16+StationMaxDirnumSize, StationMaxNameSize, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_lineDisplayName, tvb, offset+16+StationMaxDirnumSize+StationMaxNameSize, StationMaxDisplayNameSize, TRUE);
       break;
 
     case 0x93 : /* configStat */
@@ -1912,12 +2116,12 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       break;
 
     case 0x95 : /* startSessionTransmission */
-      proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr,  tvb, offset+12, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr,  tvb, offset+12, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_sessionType, tvb, offset+16, 4, TRUE);
       break;
 
     case 0x96 : /* stopSessionTransmission */
-      proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr,  tvb, offset+12, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr,  tvb, offset+12, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_sessionType, tvb, offset+16, 4, TRUE);
       break;
 
@@ -1968,7 +2172,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       }
       j = j+(i*4);
       for (i = 0; i < StationMaxServers; i++) {
-             proto_tree_add_item(skinny_tree, hf_skinny_serverIpAddress, tvb, j+(i*4), 4, TRUE);
+             proto_tree_add_item(skinny_tree, hf_skinny_serverIpAddress, tvb, j+(i*4), 4, FALSE);
       }
       break;
 
@@ -1979,18 +2183,19 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x101 : /* startMulticastMediaReception*/
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_multicastIpAddress, tvb, offset+20, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_multicastIpAddress, tvb, offset+20, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_multicastPort, tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+28, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+32, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_echoCancelType, tvb, offset+36, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+40, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x102 : /* startMulticateMediaTermination*/
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_multicastIpAddress, tvb, offset+20, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_multicastIpAddress, tvb, offset+20, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_multicastPort, tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+28, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+32, 4, TRUE);
@@ -1998,16 +2203,19 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_silenceSuppression, tvb, offset+40, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket, tvb, offset+44, 2, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+48, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x103 : /* stopMulticastMediaReception*/
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x104 : /* stopMulticastMediaTermination*/
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x105 : /* open receive channel */
@@ -2017,11 +2225,13 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability,       tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_echoCancelType,          tvb, offset+28, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate,             tvb, offset+32, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x106 :  /* closeReceiveChannel */
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x107 :  /* connectionStatisticsReq */
@@ -2030,6 +2240,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_directoryNumber, tvb, i, StationMaxDirnumSize, TRUE);
       i = 12 + StationMaxDirnumSize;
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, i, 4, TRUE);
+      si->callId = tvb_get_letohl(tvb, i);
       i = i+4;
       proto_tree_add_item(skinny_tree, hf_skinny_statsProcessingType, tvb, i, 4, TRUE);
       break;
@@ -2069,30 +2280,35 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_softKeySetDescription, tvb, offset+20, 4, TRUE);
       validKeyMask = tvb_get_letohs(tvb, offset + 24);
-      skm = proto_tree_add_uint(skinny_tree, hf_skinny_softKeyMap, tvb, offset + 24, 1, validKeyMask);
+      skm = proto_tree_add_uint(skinny_tree, hf_skinny_softKeyMap, tvb, offset + 24, 4, validKeyMask);
       skm_tree = proto_item_add_subtree(skm, ett_skinny_softKeyMap);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey0,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey1,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey2,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey3,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey4,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey5,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey6,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey7,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey8,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey9,  tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey10, tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey11, tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey12, tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey13, tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey14, tvb, offset + 24, 1, validKeyMask);
-      proto_tree_add_boolean(skm_tree, hf_skinny_softKey15, tvb, offset + 24, 1, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey0,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey1,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey2,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey3,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey4,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey5,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey6,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey7,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey8,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey9,  tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey10, tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey11, tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey12, tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey13, tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey14, tvb, offset + 24, 4, validKeyMask);
+      proto_tree_add_boolean(skm_tree, hf_skinny_softKey15, tvb, offset + 24, 4, validKeyMask);
+      si->lineId = tvb_get_letohl(tvb, offset+12);
+      si->callId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x111 : /* callState */
       proto_tree_add_item(skinny_tree, hf_skinny_callState, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
+      si->callState = tvb_get_letohl(tvb, offset+12);
       break;
 
     case 0x112 : /* displayPromptStatus */
@@ -2100,11 +2316,15 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, StationMaxDisplayPromptStatusSize, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+48, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+52, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+48);
+      si->callId = tvb_get_letohl(tvb, offset+52);
       break;
 
     case 0x113: /* clearPrompt */
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance  , tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+12);
+      si->callId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x114 : /* displayNotify */
@@ -2114,6 +2334,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
     case 0x116 : /* activateCallPlane */
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+12);
       break;
 
     case 0x118 :    /* unregisterAckMessage */
@@ -2123,6 +2344,8 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x119 : /* backSpaceReq */
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+12);
+      si->callId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x11B : /* registerTokenReject */
@@ -2133,16 +2356,20 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+20, 4, TRUE);
-           proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+24, 4, TRUE);
-           proto_tree_add_item(skinny_tree, hf_skinny_echoCancelType, tvb, offset+28, 4, TRUE);
-           proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+32, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+24, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_echoCancelType, tvb, offset+28, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+32, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+34, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+34);
       break;
 
     case 0x11D : /* DialedNumberMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_calledParty, tvb, offset+12, StationMaxDirnumSize, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+16+StationMaxDirnumSize, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20+StationMaxDirnumSize, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12+StationMaxDirnumSize, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+12+StationMaxDirnumSize+4, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+12+StationMaxDirnumSize);
+      si->callId = tvb_get_letohl(tvb, offset+16+StationMaxDirnumSize);
       break;
 
     case 0x11E : /* UserToDeviceDataMessage */
@@ -2152,7 +2379,9 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_transactionID, tvb, offset+24, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_data_length, tvb, offset+28, 4, TRUE);
       count = tvb_get_letohl( tvb, offset+28);
-      proto_tree_add_uint(skinny_tree, hf_skinny_data, tvb, offset+30, 1, count);
+      dissect_skinny_xml(skinny_tree, tvb, pinfo, offset+30, count);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x11F : /* FeatureStatMessage */
@@ -2209,48 +2438,56 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_deviceTone, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x128 : /* SendDtmfToneMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_deviceTone, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x129 : /* SubscribeDtmfPayloadReqMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_payloadDtmf, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x12A : /* SubscribeDtmfPayloadResMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_payloadDtmf, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x12B : /* SubscribeDtmfPayloadErrMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_payloadDtmf, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x12C : /* UnSubscribeDtmfPayloadReqMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_payloadDtmf, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x12D : /* UnSubscribeDtmfPayloadResMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_payloadDtmf, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x12E : /* UnSubscribeDtmfPayloadErrMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_payloadDtmf, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x12F : /* ServiceURLStatMessage */
@@ -2263,6 +2500,8 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_callSelectStat, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+20, 4, TRUE);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x131 : /* OpenMultiMediaChannelMessage */
@@ -2274,6 +2513,9 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_payload_rfc_number, tvb, offset+32, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_payloadType, tvb, offset+36, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_isConferenceCreator, tvb, offset+40, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->lineId = tvb_get_letohl(tvb, offset+24);
+      si->callId = tvb_get_letohl(tvb, offset+28);
 
       /* add audio part of union */
                  ti_sub = proto_tree_add_text(skinny_tree, tvb, offset, 12, "audioParameters");
@@ -2336,12 +2578,14 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+20, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+24, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+24, 4, FALSE);
       proto_tree_add_item(skinny_tree, hf_skinny_portNumber, tvb, offset+28, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+32, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_payload_rfc_number, tvb, offset+36, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_payloadType, tvb, offset+40, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_DSCPValue, tvb, offset+44, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+32);
 
       /* add audio part of union */
                  ti_sub = proto_tree_add_text(skinny_tree, tvb, offset, 12, "audioParameters");
@@ -2404,6 +2648,8 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x134 : /* MiscellaneousCommandMessage */
@@ -2411,6 +2657,8 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_miscCommandType, tvb, offset+24, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
 
       /* show videoFreezePicture */
       /* not sure of format */
@@ -2468,12 +2716,16 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_maxBitRate, tvb, offset+24, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x136 : /* CloseMultiMediaReceiveChannel */
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
+      si->passThruId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
     case 0x137 : /* CreateConferenceReqMessage */
@@ -2514,11 +2766,13 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x13A : /* AddParticipantReqMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+      si->callId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x13B : /* DropParticipantReqMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+      si->callId = tvb_get_letohl(tvb, offset+16);
       break;
 
     case 0x13D : /* AuditParticipantReqMessage */
@@ -2537,54 +2791,71 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+38, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_appInstanceID, tvb, offset+42, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_routingID, tvb, offset+46, 4, TRUE);
-      proto_tree_add_uint(skinny_tree, hf_skinny_data, tvb, offset+50, 1, count);
+      dissect_skinny_xml(skinny_tree, tvb, pinfo, offset+50, count);
+      si->lineId = tvb_get_letohl(tvb, offset+16);
+      si->callId = tvb_get_letohl(tvb, offset+20);
       break;
 
+    case 0x15A : /* XMLAlarmMessage */
+      dissect_skinny_xml(skinny_tree, tvb, pinfo, offset+12, hdr_data_length-4);
+      break;
+
+    case 0x14A : /* CM5CallInfoMessage */
+      /* unknown uint32_t stuff */
+      proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_callType, tvb, offset+20, 4, TRUE);
+      /* 5x unknown uint32_t stuff */
+      break;
 
     default:
       break;
     }
   }
+  tap_queue_packet(skinny_tap, pinfo, si);
 }
 
+
 /* Code to actually dissect the packets */
-static void dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static gboolean
+dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
   /* The general structure of a packet: {IP-Header|TCP-Header|n*SKINNY}
    * SKINNY-Packet: {Header(Size, Reserved)|Data(MessageID, Message-Data)}
    */
   /* Header fields */
-  volatile guint32 hdr_data_length;
-  guint32 hdr_reserved;
+  guint32 hdr_data_length;
+  guint32 hdr_version;
 
   /* check, if this is really an SKINNY packet, they start with a length + 0 */
 
   /* get relevant header information */
   hdr_data_length = tvb_get_letohl(tvb, 0);
-  hdr_reserved    = tvb_get_letohl(tvb, 4);
+  hdr_version     = tvb_get_letohl(tvb, 4);
 
   /*  data_size       = MIN(8+hdr_data_length, tvb_length(tvb)) - 0xC; */
 
-  if (hdr_data_length < 4 || hdr_reserved != 0) {
-    /* Not an SKINNY packet, just happened to use the same port */
-    call_dissector(data_handle,tvb, pinfo, tree);
-    return;
+  if ((hdr_data_length < 4) ||
+      ((hdr_version != BASIC_MSG_TYPE) &&
+       (hdr_version != CM7_MSG_TYPE_A) &&
+       (hdr_version != CM7_MSG_TYPE_B))
+     ) 
+  {
+      /* Not an SKINNY packet, just happened to use the same port */
+    return FALSE;
   }
 
   /* Make entries in Protocol column and Info column on summary display */
-  if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
-    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SKINNY");
-  }
+  col_set_str(pinfo->cinfo, COL_PROTOCOL, "SKINNY");
 
-  if (check_col(pinfo->cinfo, COL_INFO)) {
-    col_set_str(pinfo->cinfo, COL_INFO, "Skinny Client Control Protocol");
-  }
+  col_set_str(pinfo->cinfo, COL_INFO, "Skinny Client Control Protocol");
 
   tcp_dissect_pdus(tvb, pinfo, tree, skinny_desegment, 4,
        get_skinny_pdu_len, dissect_skinny_pdu);
+
+  return TRUE;
 }
 
-/* Register the protocol with Ethereal */
+/* Register the protocol with Wireshark */
 void
 proto_register_skinny(void)
 {
@@ -2597,16 +2868,16 @@ proto_register_skinny(void)
        "Number of bytes in the data portion.",
        HFILL }
     },
-    { &hf_skinny_reserved,
-      { "Reserved", "skinny.reserved",
-       FT_UINT32, BASE_HEX, NULL, 0x0,
-       "Reserved for future(?) use.",
+    { &hf_skinny_hdr_version,
+      { "Header version", "skinny.hdr_version",
+       FT_UINT32, BASE_HEX, VALS(header_version), 0x0,
+       "Header version.",
        HFILL }
     },
     /* FIXME: Enable use of message name ???  */
     { &hf_skinny_messageid,
       { "Message ID", "skinny.messageid",
-       FT_UINT32, BASE_HEX, VALS(message_id), 0x0,
+       FT_UINT32, BASE_HEX|BASE_EXT_STRING, &message_id_ext, 0x0,
        "The function requested/done with this message.",
        HFILL }
     },
@@ -2634,7 +2905,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_deviceType,
       { "DeviceType", "skinny.deviceType",
-       FT_UINT32, BASE_DEC, VALS(deviceTypes), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &deviceTypes_ext, 0x0,
        "DeviceType of the station.",
        HFILL }
     },
@@ -2655,7 +2926,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_stationKeypadButton,
       { "KeypadButton", "skinny.stationKeypadButton",
-       FT_UINT32, BASE_HEX, VALS(keypadButtons), 0x0,
+       FT_UINT32, BASE_HEX|BASE_EXT_STRING, &keypadButtons_ext, 0x0,
        "The button pressed on the phone.",
        HFILL }
     },
@@ -2669,7 +2940,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_stimulus,
       { "Stimulus", "skinny.stimulus",
-       FT_UINT32, BASE_HEX, VALS(deviceStimuli), 0x0,
+       FT_UINT32, BASE_HEX|BASE_EXT_STRING, &deviceStimuli_ext, 0x0,
        "Reason for the device stimulus message.",
        HFILL }
     },
@@ -2704,7 +2975,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_payloadCapability,
       { "PayloadCapability", "skinny.payloadCapability",
-       FT_UINT32, BASE_DEC, VALS(mediaPayloads), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &mediaPayloads_ext, 0x0,
        "The payload capability for this media capability structure.",
        HFILL }
     },
@@ -2718,7 +2989,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_alarmSeverity,
       { "AlarmSeverity", "skinny.alarmSeverity",
-       FT_UINT32, BASE_DEC, VALS(alarmSeverities), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &alarmSeverities_ext, 0x0,
        "The severity of the reported alarm.",
        HFILL }
     },
@@ -2851,7 +3122,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_softKeyEvent,
       { "SoftKeyEvent", "skinny.softKeyEvent",
-       FT_UINT32, BASE_DEC, VALS(softKeyEvents), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &softKeyEvents_ext, 0x0,
        "Which softkey event is being reported.",
        HFILL }
     },
@@ -2900,14 +3171,14 @@ proto_register_skinny(void)
 
     { &hf_skinny_buttonInstanceNumber,
       { "InstanceNumber", "skinny.buttonInstanceNumber",
-       FT_UINT8, BASE_HEX, VALS(keypadButtons), 0x0,
+       FT_UINT8, BASE_HEX|BASE_EXT_STRING, &keypadButtons_ext, 0x0,
        "The button instance number for a button or the StationKeyPad value, repeats allowed.",
        HFILL }
     },
 
     { &hf_skinny_buttonDefinition,
       { "ButtonDefinition", "skinny.buttonDefinition",
-       FT_UINT8, BASE_HEX, VALS(buttonDefinitions), 0x0,
+       FT_UINT8, BASE_HEX|BASE_EXT_STRING, &buttonDefinitions_ext, 0x0,
        "The button type for this instance (ie line, speed dial, ....",
        HFILL }
     },
@@ -2963,21 +3234,21 @@ proto_register_skinny(void)
 
     { &hf_skinny_softKeyTemplateIndex,
       { "SoftKeyTemplateIndex", "skinny.softKeyTemplateIndex",
-       FT_UINT8, BASE_DEC, VALS(softKeyEvents), 0x0,
+       FT_UINT8, BASE_DEC|BASE_EXT_STRING, &softKeyEvents_ext, 0x0,
        "Array of size 16 8-bit unsigned ints containing an index into the softKeyTemplate.",
        HFILL }
     },
 
     { &hf_skinny_softKeyInfoIndex,
       { "SoftKeyInfoIndex", "skinny.softKeyInfoIndex",
-       FT_UINT16, BASE_DEC, VALS(softKeyIndexes), 0x0,
+       FT_UINT16, BASE_DEC|BASE_EXT_STRING, &softKeyIndexes_ext, 0x0,
        "Array of size 16 16-bit unsigned integers containing an index into the soft key description information.",
        HFILL }
     },
 
     { &hf_skinny_softKeySetDescription,
       { "SoftKeySet", "skinny.softKeySetDescription",
-       FT_UINT8, BASE_DEC, VALS(keySetNames), 0x0,
+       FT_UINT8, BASE_DEC|BASE_EXT_STRING, &keySetNames_ext, 0x0,
        "A text description of what this softkey when this softkey set is displayed",
        HFILL }
     },
@@ -2985,125 +3256,125 @@ proto_register_skinny(void)
     { &hf_skinny_softKeyMap,
       { "SoftKeyMap","skinny.softKeyMap",
        FT_UINT16, BASE_HEX, NULL, 0x0,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey0,
       { "SoftKey0", "skinny.softKeyMap.0",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY0,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey1,
       { "SoftKey1", "skinny.softKeyMap.1",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY1,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey2,
       { "SoftKey2", "skinny.softKeyMap.2",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY2,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey3,
       { "SoftKey3", "skinny.softKeyMap.3",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY3,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey4,
       { "SoftKey4", "skinny.softKeyMap.4",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY4,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey5,
       { "SoftKey5", "skinny.softKeyMap.5",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY5,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey6,
       { "SoftKey6", "skinny.softKeyMap.6",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY6,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey7,
       { "SoftKey7", "skinny.softKeyMap.7",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY7,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey8,
       { "SoftKey8", "skinny.softKeyMap.8",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY8,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey9,
       { "SoftKey9", "skinny.softKeyMap.9",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY9,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey10,
       { "SoftKey10", "skinny.softKeyMap.10",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY10,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey11,
       { "SoftKey11", "skinny.softKeyMap.11",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY11,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey12,
       { "SoftKey12", "skinny.softKeyMap.12",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY12,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey13,
       { "SoftKey13", "skinny.softKeyMap.13",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY13,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey14,
       { "SoftKey14", "skinny.softKeyMap.14",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY14,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_softKey15,
       { "SoftKey15", "skinny.softKeyMap.15",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY15,
-       "",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_lampMode,
       { "LampMode", "skinny.lampMode",
-       FT_UINT32, BASE_DEC, VALS(stationLampModes), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &stationLampModes_ext, 0x0,
        "The lamp mode",
        HFILL }
     },
@@ -3130,12 +3401,19 @@ proto_register_skinny(void)
     },
 
     { &hf_skinny_lineFullyQualifiedDisplayName,
-      { "DisplayName", "skinny.fqdn",
+      { "FullyQualifiedDisplayName", "skinny.fqdn",
        FT_STRING, BASE_NONE, NULL, 0x0,
        "The full display name for this line.",
        HFILL }
     },
 
+    { &hf_skinny_lineDisplayName,
+      { "DisplayName", "skinny.displayName",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "The display name for this line.",
+       HFILL }
+    },
+
     { &hf_skinny_speedDialDirNumber,
       { "SpeedDial Number", "skinny.speedDialDirNum",
        FT_STRING, BASE_NONE, NULL, 0x0,
@@ -3188,21 +3466,21 @@ proto_register_skinny(void)
     { &hf_skinny_dateMinute,
       { "Minute", "skinny.minute",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "Minute",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_dateSeconds,
       { "Seconds", "skinny.dateSeconds",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "Seconds",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_dateMilliseconds,
       { "Milliseconds", "skinny.dateMilliseconds",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "Milliseconds",
+       NULL,
        HFILL }
     },
 
@@ -3214,14 +3492,14 @@ proto_register_skinny(void)
     },
     { &hf_skinny_callState,
       { "CallState", "skinny.callState",
-       FT_UINT32, BASE_DEC, VALS(skinny_stationCallStates), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &skinny_stationCallStates_ext, 0x0,
        "The D channel call state of the call",
        HFILL }
     },
 
     { &hf_skinny_deviceTone,
       { "Tone", "skinny.deviceTone",
-       FT_UINT32, BASE_HEX, VALS(skinny_deviceTones), 0x0,
+       FT_UINT32, BASE_HEX|BASE_EXT_STRING, &skinny_deviceTones_ext, 0x0,
        "Which tone to play",
        HFILL }
     },
@@ -3270,11 +3548,18 @@ proto_register_skinny(void)
 
     { &hf_skinny_ringType,
       { "Ring Type", "skinny.ringType",
-       FT_UINT32, BASE_HEX, VALS(skinny_ringTypes), 0x0,
+       FT_UINT32, BASE_HEX|BASE_EXT_STRING, &skinny_ringTypes_ext, 0x0,
        "What type of ring to play",
        HFILL }
     },
 
+    { &hf_skinny_ringMode,
+      { "Ring Mode", "skinny.ringMode",
+       FT_UINT32, BASE_HEX, VALS(skinny_ringModes), 0x0,
+       "What mode of ring to play",
+       HFILL }
+    },
+
     { &hf_skinny_speakerMode,
       { "Speaker", "skinny.speakerMode",
        FT_UINT32, BASE_HEX, VALS(skinny_speakerModes), 0x0,
@@ -3445,7 +3730,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_sessionType,
       { "Session Type", "skinny.sessionType",
-       FT_UINT32, BASE_DEC, VALS(skinny_sessionTypes), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &skinny_sessionTypes_ext, 0x0,
        "The type of this session.",
        HFILL }
     },
@@ -3513,10 +3798,10 @@ proto_register_skinny(void)
        HFILL }
     },
 
-    { &hf_skinny_data,
-      { "Data", "skinny.data",
-       FT_UINT8, BASE_HEX, NULL, 0x0,
-       "dataPlace holder for unknown data.",
+    { &hf_skinny_xmlData,
+      { "XmlData", "skinny.xmlData",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "dataPlace holder for XML data.",
        HFILL }
     },
 
@@ -3585,7 +3870,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_modifyConfResults,
       { "ModifyConfResults", "skinny.modifyConfResults",
-       FT_UINT32, BASE_DEC, VALS(skinny_modifyConfResults), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &skinny_modifyConfResults_ext, 0x0,
        "The modify conference results",
        HFILL }
     },
@@ -3599,7 +3884,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_addParticipantResults,
       { "AddParticipantResults", "skinny.addParticipantResults",
-       FT_UINT32, BASE_DEC, VALS(skinny_addParticipantResults), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &skinny_addParticipantResults_ext, 0x0,
        "The add conference participant results",
        HFILL }
     },
@@ -3809,8 +4094,8 @@ proto_register_skinny(void)
 
     { &hf_skinny_layout,
       { "Layout", "skinny.layout",
-       FT_UINT32, BASE_DEC, VALS(skinny_Layouts), 0x0,
-       "Layout",
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &skinny_Layouts_ext, 0x0,
+       NULL,
        HFILL }
     },
 
@@ -3831,7 +4116,7 @@ proto_register_skinny(void)
     { &hf_skinny_transmitOrReceive,
       { "TransmitOrReceive", "skinny.transmitOrReceive",
        FT_UINT32, BASE_DEC, VALS(skinny_transmitOrReceive), 0x0,
-       "TransmitOrReceive",
+       NULL,
        HFILL }
     },
 
@@ -3851,7 +4136,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_format,
       { "Format", "skinny.format",
-       FT_UINT32, BASE_DEC, VALS(skinny_formatTypes), 0x0,
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &skinny_formatTypes_ext, 0x0,
        "Format.",
        HFILL }
     },
@@ -3978,21 +4263,21 @@ proto_register_skinny(void)
     { &hf_skinny_endOfAnnAck,
       { "EndOfAnnAck", "skinny.endOfAnnAck",
        FT_UINT32, BASE_DEC, VALS(skinny_endOfAnnAck), 0x0,
-       "EndOfAnnAck",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_annPlayMode,
       { "annPlayMode", "skinny.annPlayMode",
        FT_UINT32, BASE_DEC, VALS(skinny_annPlayMode), 0x0,
-       "AnnPlayMode",
+       NULL,
        HFILL }
     },
 
     { &hf_skinny_annPlayStatus,
       { "AnnPlayStatus", "skinny.annPlayStatus",
        FT_UINT32, BASE_DEC, VALS(skinny_annPlayStatus), 0x0,
-       "AnnPlayStatus",
+       NULL,
        HFILL }
     },
 
@@ -4096,8 +4381,8 @@ proto_register_skinny(void)
 
     { &hf_skinny_miscCommandType,
       { "MiscCommandType", "skinny.miscCommandType",
-       FT_UINT32, BASE_DEC, VALS(skinny_miscCommandType), 0x0,
-       "MiscCommandType",
+       FT_UINT32, BASE_DEC|BASE_EXT_STRING, &skinny_miscCommandType_ext, 0x0,
+       NULL,
        HFILL }
     },
 
@@ -4252,17 +4537,24 @@ proto_register_skinny(void)
     "Whether the SCCP dissector should reassemble messages spanning multiple TCP segments."
     " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
     &skinny_desegment);
+
+  skinny_tap = register_tap("skinny");
 }
 
 void
 proto_reg_handoff_skinny(void)
 {
+  static gboolean skinny_prefs_initialized = FALSE;
   dissector_handle_t skinny_handle;
-
-  data_handle = find_dissector("data");
-  rtp_handle = find_dissector("rtp");
-  skinny_handle = create_dissector_handle(dissect_skinny, proto_skinny);
-  dissector_add("tcp.port", TCP_PORT_SKINNY, skinny_handle);
+  
+  if (!skinny_prefs_initialized) {
+    rtp_handle = find_dissector("rtp");
+    /* Skinny content type and internet media type used by other dissectors are the same */
+    media_type_dissector_table = find_dissector_table("media_type");
+    skinny_handle = new_create_dissector_handle(dissect_skinny, proto_skinny);
+    dissector_add_uint("tcp.port", TCP_PORT_SKINNY, skinny_handle);
+    skinny_prefs_initialized = TRUE;
+  }
 }
 
 /*
@@ -4280,9 +4572,9 @@ proto_reg_handoff_skinny(void)
  *  0x2    ipPort                          Y        Y
  *  0x3    keypadButton                    Y        Y
  *  0x4    enblocCall                      Y        N
- *  0x5    stimulus                        Y        N
- *  0x6    offHook                         Y        N/A
- *  0x7    onHook                          Y        N/A
+ *  0x5    stimulus                        Y        Y
+ *  0x6    offHook                         Y        Y
+ *  0x7    onHook                          Y        Y
  *  0x8    hookFlash                       Y        N/A
  *  0x9    forwardStatReq                  Y        N
  *  0xa    speedDialStatReq                Y        Y
@@ -4325,7 +4617,7 @@ proto_reg_handoff_skinny(void)
  *  0x42   deviceToUserDataResponseVersion1
  *  0x81   registerAck                     Y        Y
  *  0x82   startTone                       Y        Y
- *  0x83   stopTone                        Y        N/A
+ *  0x83   stopTone                        Y        Y
  *  0x85   setRinger                       Y        Y
  *  0x86   setLamp                         Y        Y
  *  0x87   setHkFDetect                    Y        N