Move sourcelists into Makefile.common
[obnox/wireshark/wip.git] / packet-skinny.c
index 6bf6ee24c21c5cf22d6ced1d2e95d9ed21b380bb..1f9893b1d9e3038c97c3ca44357c1763a4f91335 100644 (file)
@@ -4,12 +4,14 @@
  *   (The "D-Channel"-Protocol for Cisco Systems' IP-Phones)
  * Copyright 2001, Joerg Mayer (email: see AUTHORS file)
  *
- * Further decode work by pee@erkkila.org 
+ * 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.
  *
  * This file is based on packet-aim.c, which is
  * Copyright 2000, Ralf Hoelzer <ralf@well.com>
  *
- * $Id: packet-skinny.c,v 1.12 2002/03/19 11:26:23 guy Exp $
+ * $Id: packet-skinny.c,v 1.21 2002/09/21 03:14:10 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -43,7 +45,7 @@
 #include <epan/packet.h>
 #include "prefs.h"
 
-#include "packet-frame.h"
+#include "packet-tcp.h"
 
 #define TCP_PORT_SKINNY 2000
 
@@ -115,7 +117,7 @@ static const value_string  message_id[] = {
   {0x0029, "RegisterTokenReq"},
   {0x002B, "unknownClientMessage1"},
   {0x002D, "unknownClientMessage2"},
-  
+
   /* Callmanager -> Station */
   /* 0x0000, 0x0003? */
   {0x0081, "RegisterAckMessage"},
@@ -178,42 +180,42 @@ static const value_string  message_id[] = {
  * Device type to text conversion table
  */
 static const value_string  deviceTypes[] = {
-  {1  , "DeviceStation30SPplus"},
-  {2  , "DeviceStation12SPplus"},
-  {3  , "DeviceStation12SP"},
-  {4  , "DeviceStation12"},
-  {5  , "DeviceStation30VIP"},
-  {6  , "DeviceStationTelecaster"},
-  {7  , "DeviceStationTelecasterMgr"},
-  {8  , "DeviceStationTelecasterBus"},
-  {20 , "DeviceVirtual30SPplus"},
-  {21 , "DeviceStationPhoneApplication"},
-  {30 , "DeviceAnalogAccess"},
-  {40 , "DeviceDigitalAccessPRI"},
-  {41 , "DeviceDigitalAccessT1"},
-  {42 , "DeviceDigitalAccessTitan2"},
-  {47 , "DeviceAnalogAccessElvis"},
-  {49 , "DeviceDigitalAccessLennon"},
-  {50 , "DeviceConferenceBridge"},
-  {51 , "DeviceConferenceBridgeYoko"},
-  {60 , "DeviceH225"},
-  {61 , "DeviceH323Phone"},
-  {62 , "DeviceH323Trunk"},
-  {70 , "DeviceMusicOnHold"},
-  {71 , "DevicePilot"},
-  {72 , "DeviceTapiPort"},
-  {73 , "DeviceTapiRoutePoint"},
-  {80 , "DeviceVoiceInBox"},
-  {81 , "DeviceVoiceInboxAdmin"},
-  {82 , "DeviceLineAnnunciator"},
-  {90 , "DeviceRouteList"},
-  {100, "DeviceLoadSimulator"},
-  {110, "DeviceMediaTerminationPoint"},
-  {111, "DeviceMediaTerminationPointYoko"},
-  {120, "DeviceMGCPStation"},
-  {121, "DeviceMGCPTrunk"},
-  {122, "DeviceRASProxy"},
-  {255, "DeviceNotDefined"},
+  {1  , "30SPplus"},
+  {2  , "12SPplus"},
+  {3  , "12SP"},
+  {4  , "12"},
+  {5  , "30VIP"},
+  {6  , "Telecaster"},
+  {7  , "TelecasterMgr"},
+  {8  , "TelecasterBus"},
+  {20 , "Virtual30SPplus"},
+  {21 , "PhoneApplication"},
+  {30 , "AnalogAccess"},
+  {40 , "DigitalAccessPRI"},
+  {41 , "DigitalAccessT1"},
+  {42 , "DigitalAccessTitan2"},
+  {47 , "AnalogAccessElvis"},
+  {49 , "DigitalAccessLennon"},
+  {50 , "ConferenceBridge"},
+  {51 , "ConferenceBridgeYoko"},
+  {60 , "H225"},
+  {61 , "H323Phone"},
+  {62 , "H323Trunk"},
+  {70 , "MusicOnHold"},
+  {71 , "Pilot"},
+  {72 , "TapiPort"},
+  {73 , "TapiRoutePoint"},
+  {80 , "VoiceInBox"},
+  {81 , "VoiceInboxAdmin"},
+  {82 , "LineAnnunciator"},
+  {90 , "RouteList"},
+  {100, "LoadSimulator"},
+  {110, "MediaTerminationPoint"},
+  {111, "MediaTerminationPointYoko"},
+  {120, "MGCPStation"},
+  {121, "MGCPTrunk"},
+  {122, "RASProxy"},
+  {255, "NotDefined"},
   { 0    , NULL}
 };
 
@@ -241,32 +243,32 @@ static const value_string keypadButtons[] = {
 };
 
 static const value_string deviceStimuli[] = {
-  {1    , "SsLastNumberRedial"},
-  {2    , "SsSpeedDial"},
-  {3    , "SsHold"},
-  {4    , "SsTransfer"},
-  {5    , "SsForwardAll"},
-  {6    , "SsForwardBusy"},
-  {7    , "SsForwardNoAnswer"},
-  {8    , "SsDisplay"},
-  {9    , "SsLine"},
-  {0xa  , "SsT120Chat"},
-  {0xb  , "SsT120Whiteboard"},
-  {0xc  , "SsT120ApplicationSharing"},
-  {0xd  , "SsT120FileTransfer"},
-  {0xe  , "SsVideo"},
-  {0xf  , "SsVoiceMail"},
-  {0x11 , "SsAutoAnswer"},
-  {0x21 , "SsGenericAppB1"},
-  {0x22 , "SsGenericAppB2"},
-  {0x23 , "SsGenericAppB3"},
-  {0x24 , "SsGenericAppB4"},
-  {0x25 , "SsGenericAppB5"},
-  {0x7b , "SsMeetMeConference"},
-  {0x7d , "SsConference=0x7d"},
-  {0x7e , "SsCallPark=0x7e"},
-  {0x7f , "SsCallPickup"},
-  {0x80 , "SsGroupCallPickup=80"},
+  {1    , "LastNumberRedial"},
+  {2    , "SpeedDial"},
+  {3    , "Hold"},
+  {4    , "Transfer"},
+  {5    , "ForwardAll"},
+  {6    , "ForwardBusy"},
+  {7    , "ForwardNoAnswer"},
+  {8    , "Display"},
+  {9    , "Line"},
+  {0xa  , "T120Chat"},
+  {0xb  , "T120Whiteboard"},
+  {0xc  , "T120ApplicationSharing"},
+  {0xd  , "T120FileTransfer"},
+  {0xe  , "Video"},
+  {0xf  , "VoiceMail"},
+  {0x11 , "AutoAnswer"},
+  {0x21 , "GenericAppB1"},
+  {0x22 , "GenericAppB2"},
+  {0x23 , "GenericAppB3"},
+  {0x24 , "GenericAppB4"},
+  {0x25 , "GenericAppB5"},
+  {0x7b , "MeetMeConference"},
+  {0x7d , "Conference=0x7d"},
+  {0x7e , "CallPark=0x7e"},
+  {0x7f , "CallPickup"},
+  {0x80 , "GroupCallPickup=80"},
   {0,NULL}
 };
 
@@ -275,49 +277,53 @@ static const value_string deviceStimuli[] = {
 #define DeviceMaxCapabilities 18 /* max capabilities allowed in Cap response message */
 
 static const value_string mediaPayloads[] = {
-  {1   , "Media_Payload_NonStandard"},
-  {2   , "Media_Payload_G711Alaw64k"},
-  {3   , "Media_Payload_G711Alaw56k"},
-  {4   , "Media_Payload_G711Ulaw64k"},
-  {5   , "Media_Payload_G711Ulaw56k"},
-  {6   , "Media_Payload_G722_64k"},
-  {7   , "Media_Payload_G722_56k"},
-  {8   , "Media_Payload_G722_48k"},
-  {9   , "Media_Payload_G7231"},
-  {10  , "Media_Payload_G728"},
-  {11  , "Media_Payload_G729"},
-  {12  , "Media_Payload_G729AnnexA"},
-  {13  , "Media_Payload_Is11172AudioCap"},
-  {14  , "Media_Payload_Is13818AudioCap"},
-  {15  , "Media_Payload_G729AnnexB"},
-  {16  , "Media_Payload_G729AnnexAwAnnexB"},
-  {32  , "Media_Payload_Data64"},
-  {33  , "Media_Payload_Data56"},
-  {80  , "Media_Payload_GSM"},
-  {81  , "Media_Payload_ActiveVoice"},
-  {82  , "Media_Payload_G726_32K"},
-  {83  , "Media_Payload_G726_24K"},
-  {84  , "Media_Payload_G726_16K"},
-  {85  , "Media_Payload_G729_B"},
-  {86  , "Media_Payload_G729_B_LOW_COMPLEXITY"},
+  {1   , "Non-standard codec"},
+  {2   , "G.711 A-law 64k"},
+  {3   , "G.711 A-law 56k"},
+  {4   , "G.711 u-law 64k"},
+  {5   , "G.711 u-law 56k"},
+  {6   , "G.722 64k"},
+  {7   , "G.722 56k"},
+  {8   , "G.722 48k"},
+  {9   , "G.723.1"},
+  {10  , "G.728"},
+  {11  , "G.729"},
+  {12  , "G.729 Annex A"},
+  {13  , "IS11172 AudioCap"},  /* IS11172 is an ISO MPEG standard */
+  {14  , "IS13818 AudioCap"},  /* IS13818 is an ISO MPEG standard */
+  {15  , "G.729 Annex B"},
+  {16  , "G.729 Annex A+Annex B"},
+  {18  , "GSM Full Rate"},
+  {19  , "GSM Half Rate"},
+  {20  , "GSM Enhanced Full Rate"},
+  {25  , "Wideband 256k"},
+  {32  , "Data 64k"},
+  {33  , "Data 56k"},
+  {80  , "GSM"},
+  {81  , "ActiveVoice"},
+  {82  , "G.726 32K"},
+  {83  , "G.726 24K"},
+  {84  , "G.726 16K"},
+  {85  , "G.729B"},
+  {86  , "G.729B Low Complexity"},
   {0  , NULL}
 };
 
 static const value_string alarmSeverities[] = {
-  {0   , "severityCritical"},
-  {7   , "severityMajor"},
-  {8   , "severityMinor"},
-  {1   , "severityWarning"},
-  {10  , "severityMarginal"},
-  {4   , "severityUnknown"},
-  {2   , "severityInformational"},
-  {20  , "severityTraceInfo"},
+  {0   , "Critical"},
+  {1   , "Warning"},
+  {2   , "Informational"},
+  {4   , "Unknown"},
+  {7   , "Major"},
+  {8   , "Minor"},
+  {10  , "Marginal"},
+  {20  , "TraceInfo"},
   {0  , NULL}
 };
 
 static const value_string multicastMediaReceptionStatus[] = {
-  {0  , "mmrOk"},
-  {1  , "mmrError"},
+  {0  , "Ok"},
+  {1  , "Error"},
   {0  , NULL}
 };
 
@@ -336,70 +342,70 @@ static const value_string statsProcessingTypes[] = {
 
 #define SkMaxSoftKeyCount 18 /* this value should be the same as the max soft key value */
 static const value_string softKeyEvents[] = {
-  {1   , "SkRedial"},
-  {2   , "SkNewCall"},
-  {3   , "SkHold"},
-  {4   , "SkTrnsfer"},
-  {5   , "SkCFwdAll"},
-  {6   , "SkCFwdBusy"},
-  {7   , "SkCFwdNoAnswer"},
-  {8   , "SkBackSpace"},
-  {9   , "SkEndCall"},
-  {10  , "SkResume"},
-  {11  , "SkAnswer"},
-  {12  , "SkInfo"},
-  {13  , "SkConfrn"},
-  {14  , "SkPark"},
-  {15  , "SkJoin"},
-  {16  , "SkMeetMeConfrn"},
-  {17  , "SkCallPickUp"},
-  {18  , "SkGrpCallPickUp"},
+  {1   , "Redial"},
+  {2   , "NewCall"},
+  {3   , "Hold"},
+  {4   , "Trnsfer"},
+  {5   , "CFwdAll"},
+  {6   , "CFwdBusy"},
+  {7   , "CFwdNoAnswer"},
+  {8   , "BackSpace"},
+  {9   , "EndCall"},
+  {10  , "Resume"},
+  {11  , "Answer"},
+  {12  , "Info"},
+  {13  , "Confrn"},
+  {14  , "Park"},
+  {15  , "Join"},
+  {16  , "MeetMeConfrn"},
+  {17  , "CallPickUp"},
+  {18  , "GrpCallPickUp"},
   {0   , NULL}
 };
 
 /* Define info index for each softkey event for Telecaster station. */
 static const value_string softKeyIndexes[] = {
-  {301  , "SkRedialInfoIndex"},
-  {302  , "SkNewCallInfoIndex"},
-  {303  , "SkHoldInfoIndex"},
-  {304  , "SkTrnsferInfoIndex"},
-  {305  , "SkCFwdAllInfoIndex"},
-  {306  , "SkCFwdBusyInfoIndex"},     /* not used yet */
-  {307  , "SkCFwdNoAnswerInfoIndex"}, /* not used yet */
-  {308  , "SkBackSpaceInfoIndex"},
-  {309  , "SkEndCallInfoIndex"},
-  {310  , "SkResumeInfoIndex"},
-  {311  , "SkAnswerInfoIndex"},
-  {312  , "SkInfoInfoIndex"},
-  {313  , "SkConfrnInfoIndex"},
-  {314  , "SkParkInfoIndex"},
-  {315  , "SkJoinInfoIndex"},
-  {316  , "SkMeetMeConfrnInfoIndex"},
-  {317  , "SkCallPickUpInfoIndex"},
-  {318  , "SkGrpCallPickUpInfoIndex"},
+  {301  , "RedialInfoIndex"},
+  {302  , "NewCallInfoIndex"},
+  {303  , "HoldInfoIndex"},
+  {304  , "TrnsferInfoIndex"},
+  {305  , "CFwdAllInfoIndex"},
+  {306  , "CFwdBusyInfoIndex"},     /* not used yet */
+  {307  , "CFwdNoAnswerInfoIndex"}, /* not used yet */
+  {308  , "BackSpaceInfoIndex"},
+  {309  , "EndCallInfoIndex"},
+  {310  , "ResumeInfoIndex"},
+  {311  , "AnswerInfoIndex"},
+  {312  , "InfoInfoIndex"},
+  {313  , "ConfrnInfoIndex"},
+  {314  , "ParkInfoIndex"},
+  {315  , "JoinInfoIndex"},
+  {316  , "MeetMeConfrnInfoIndex"},
+  {317  , "CallPickUpInfoIndex"},
+  {318  , "GrpCallPickUpInfoIndex"},
   {0   , NULL}
 };
 
 
 static const value_string buttonDefinitions[] = {
-  {1    , "BtLastNumberRedial"},
-  {2    , "BtSpeedDial"},
-  {3    , "BtHold"},
-  {4    , "BtTransfer"},
-  {5    , "BtForwardAll"},
-  {6    , "BtForwardBusy"},
-  {7    , "BtForwardNoAnswer"},
-  {8    , "BtDisplay"},
-  {9    , "BtLine"},
-  {0xa  , "BtT120Chat"},
-  {0xb  , "BtT120Whiteboard"},
-  {0xc  , "BtT120ApplicationSharing"},
-  {0xd  , "BtT120FileTransfer"},
-  {0xe  , "BtVideo"},
-  {0x10 , "BtAnswerRelease"},
-  {0xf0 , "BtKeypad"},
-  {0xfd , "BtAEC"},
-  {0xff , "BtUndefined"},
+  {1    , "LastNumberRedial"},
+  {2    , "SpeedDial"},
+  {3    , "Hold"},
+  {4    , "Transfer"},
+  {5    , "ForwardAll"},
+  {6    , "ForwardBusy"},
+  {7    , "ForwardNoAnswer"},
+  {8    , "Display"},
+  {9    , "Line"},
+  {0xa  , "T120Chat"},
+  {0xb  , "T120Whiteboard"},
+  {0xc  , "T120ApplicationSharing"},
+  {0xd  , "T120FileTransfer"},
+  {0xe  , "Video"},
+  {0x10 , "AnswerRelease"},
+  {0xf0 , "Keypad"},
+  {0xfd , "AEC"},
+  {0xff , "Undefined"},
   {0   , NULL}
 };
 
@@ -419,7 +425,7 @@ static const value_string keySetNames[] = {
 };
 
 /* Define soft key labels for the Telecaster station */
-static const value_string softKeyLabel[] = { 
+static const value_string softKeyLabel[] = {
   {0   , "undefined"},
   {1   , "Redial"},
   {2   , "NewCall"},
@@ -440,126 +446,226 @@ static const value_string softKeyLabel[] = {
   {17  , "PickUp"},
   {18  , "GPickUp"},
   {0   , NULL}
-}; 
+};
 
 
-/* 
- * define lamp modes; 
- * lamp cadence is defined as follows 
- * Wink (on 80%) = 448msec on / 64msec off 
- * Flash (fast flash) = 32msec on / 32msec off 
- * Blink (on 50%) = 512msec on / 512msec off 
- * On (on steady) 
+/*
+ * define lamp modes;
+ * lamp cadence is defined as follows
+ * Wink (on 80%) = 448msec on / 64msec off
+ * Flash (fast flash) = 32msec on / 32msec off
+ * Blink (on 50%) = 512msec on / 512msec off
+ * On (on steady)
  */
 static const value_string stationLampModes[] = {
   {0   , "Undefined"},
-  {0x1 , "LampOff"},
-  {0x2 , "LampOn"},
-  {0x3 , "LampWink"},
-  {0x4 , "LampFlash"},
-  {0x5 , "LampBlink"},
+  {0x1 , "Off"},
+  {0x2 , "On"},
+  {0x3 , "Wink"},
+  {0x4 , "Flash"},
+  {0x5 , "Blink"},
+  {0   , NULL}
+};
+
+/* Defined the Call States to be sent to the Telecaste station.
+ * These are NOT the call states used in CM internally. Instead,
+ * they are the call states sent from CM and understood by the Telecaster station
+ */
+static const value_string skinny_stationCallStates[] = {
+  {1   , "OffHook"},
+  {2   , "OnHook"},
+  {3   , "RingOut"},
+  {4   , "RingIn"},
+  {5   , "Connected"},
+  {6   , "Busy"},
+  {7   , "Congestion"},
+  {8   , "Hold"},
+  {9   , "CallWaiting"},
+  {10  , "CallTransfer"},
+  {11  , "CallPark"},
+  {12  , "Proceed"},
+  {13  , "CallRemoteMultiline"},
+  {14  , "InvalidNumber"},
+  {0   , NULL}
+};
+
+/* Defined Call Type */
+static const value_string skinny_callTypes[] = {
+  {1   , "InBoundCall"},
+  {2   , "OutBoundCall"},
+  {3   , "ForwardCall"},
+  {0   , NULL}
+};
+
+/*
+ * define station-playable tones;
+ * 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"},
+  {0xa  , "Dtmf0"},
+  {0xe  , "DtmfStar"},
+  {0xf  , "DtmfPound"},
+  {0x10 , "DtmfA"},
+  {0x11 , "DtmfB"},
+  {0x12 , "DtmfC"},
+  {0x13 , "DtmfD"},
+  {0x21 , "InsideDialTone"},
+  {0x22 , "OutsideDialTone"},
+  {0x23 , "LineBusyTone"},
+  {0x24 , "AlertingTone"},
+  {0x25 , "ReorderTone"},
+  {0x26 , "RecorderWarningTone"},
+  {0x27 , "RecorderDetectedTone"},
+  {0x28 , "RevertingTone"},
+  {0x29 , "ReceiverOffHookTone"},
+  {0x2a , "PartialDialTone"},
+  {0x2b , "NoSuchNumberTone"},
+  {0x2c , "BusyVerificationTone"},
+  {0x2d , "CallWaitingTone"},
+  {0x2e , "ConfirmationTone"},
+  {0x2f , "CampOnIndicationTone"},
+  {0x30 , "RecallDialTone"},
+  {0x31 , "ZipZip"},
+  {0x32 , "Zip"},
+  {0x33 , "BeepBonk"},
+  {0x34 , "MusicTone"},
+  {0x35 , "HoldTone"},
+  {0x36 , "TestTone"},
+  {0x40 , "AddCallWaiting"},
+  {0x41 , "PriorityCallWait"},
+  {0x42 , "RecallDial"},
+  {0x43 , "BargIn"},
+  {0x44 , "DistinctAlert"},
+  {0x45 , "PriorityAlert"},
+  {0x46 , "ReminderRing"},
+  {0x50 , "MF1"},
+  {0x51 , "MF2"},
+  {0x52 , "MF3"},
+  {0x53 , "MF4"},
+  {0x54 , "MF5"},
+  {0x55 , "MF6"},
+  {0x56 , "MF7"},
+  {0x57 , "MF8"},
+  {0x58 , "MF9"},
+  {0x59 , "MF0"},
+  {0x5a , "MFKP1"},
+  {0x5b , "MFST"},
+  {0x5c , "MFKP2"},
+  {0x5d , "MFSTP"},
+  {0x5e , "MFST3P"},
+  {0x5f , "MILLIWATT"},
+  {0x60 , "MILLIWATTTEST"},
+  {0x61 , "HIGHTONE"},
+  {0x62 , "FLASHOVERRIDE"},
+  {0x63 , "FLASH"},
+  {0x64 , "PRIORITY"},
+  {0x65 , "IMMEDIATE"},
+  {0x66 , "PREAMPWARN"},
+  {0x67 , "2105HZ"},
+  {0x68 , "2600HZ"},
+  {0x69 , "440HZ"},
+  {0x6a , "300HZ"},
+  {0x7f , "NoTone"},
+  {0   , NULL}
+};
+
+/* define ring types */
+static const value_string skinny_ringTypes[] = {
+  {0x1  , "RingOff"},
+  {0x2  , "InsideRing"},
+  {0x3  , "OutsideRing"},
+  {0x4  , "FeatureRing"},
+  {0   , NULL}
+};
+
+static const value_string skinny_speakerModes[] = {
+  {1   , "SpeakerOn"},
+  {2   , "SpeakerOff"},
+  {0   , NULL}
+};
+
+static const value_string skinny_silenceSuppressionModes[] = {
+  {0   , "Media_SilenceSuppression_Off"},
+  {1   , "Media_SilenceSuppression_On"},
+  {0   , NULL}
+};
+
+static const value_string skinny_g723BitRates[] = {
+  {1   , "Media_G723BRate_5_3"},
+  {2   , "Media_G723BRate_6_4"},
   {0   , NULL}
-}; 
-
-
-# define NUM_MEDIA_PAYLOADTYPES 19 
-static char *Media_PayloadList[] = { 
-  "Undefined", 
-  "Media_Payload_NonStandard", 
-  "Media_Payload_G711Alaw64k", 
-  "Media_Payload_G711Alaw56k", 
-  "Media_Payload_G711Ulaw64k", 
-  "Media_Payload_G711Ulaw56k", 
-  "Media_Payload_G722_64k", 
-  "Media_Payload_G722_56k", 
-  "Media_Payload_G722_48k", 
-  "Media_Payload_G7231", 
-  "Media_Payload_G728", 
-  "Media_Payload_G729", 
-  "Media_Payload_G729AnnexA", 
-  "Media_Payload_Is11172AudioCap", 
-  "Media_Payload_Is13818AudioCap", 
-  "Media_Payload_G729AnnexB", 
-  "Media_Payload_G729AnnexAwAnnexB", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Media_Payload_Data64", 
-  "Media_Payload_Data56", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Undefined", 
-  "Media_Payload_GSM", 
-  "Media_Payload_ActiveVoice", 
-  "Media_Payload_G726_32K", 
-  "Media_Payload_G726_24K", 
-  "Media_Payload_G726_16K", 
-  "Media_Payload_G729_B", 
-  "Media_Payload_G729_B_LOW_COMPLEXITY", 
-  "Undefined", 
-  "Undefined" 
-}; 
+};
+
+/* define device reset types  */
+static const value_string skinny_deviceResetTypes[] = {
+  {1   , "DEVICE_RESET"},
+  {2   , "DEVICE_RESTART"},
+  {0   , NULL}
+};
+
+static const value_string skinny_echoCancelTypes[] = {
+  {0    , "Media_EchoCancellation_Off"},
+  {1    , "Media_EchoCancellation_On"},
+  {0    , NULL}
+};
+
+static const value_string skinny_deviceUnregisterStatusTypes[] = {
+  {0   , "Ok"},
+  {1   , "Error"},
+  {2   , "NAK"}, /* Unregister request is rejected for reaso n such as existence of a call */
+  {0   , NULL}
+};
+
+/* define hook flash detection mode */
+static const value_string skinny_hookFlashDetectModes[] = {
+  {1   , "HookFlashOn"},
+  {2   , "HookFlashOff"},
+  {0   , NULL}
+};
+
+/* define station microphone modes;
+ * Mic On - The speakerphone's microphone is turned on ONLY if the phone is in the "Speaker On (Off Hook)"
+ * state (see above).
+ * Mic Off - The microphone is turned off or, if it's not on, the command is ignored.
+ */
+static const value_string skinny_microphoneModes[] = {
+  {1   , "MicOn"},
+  {2   , "MicOff"},
+  {0   , NULL}
+};
+
+/* define the session request types */
+static const value_string skinny_sessionTypes[] = {
+  {1   , "Chat"},
+  {2   , "Whiteboard"},
+  {4   , "ApplicationSharing"},
+  {8   , "FileTransfer"},
+  {10  , "Video"},
+  {0   , NULL}
+};
+
+static const value_string skinny_mediaEnunciationTypes[] = {
+  {1  , "None"},
+  {2  , "CallPark"},
+  {0  , NULL}
+};
 
 #define StationMaxDirnumSize 24         /* max size of calling or called party dirnum  */
 #define StationMaxNameSize 40           /* max size of calling party's 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  */
-#define StationMaxButtonTemplateSize 42 /* max button template size */ 
+#define StationMaxButtonTemplateSize 42 /* max button template size */
 #define StationMaxDisplayTextSize 33    /* max text size in DisplayText message */
 #define StationMaxPorts 10              /* max number of ports on one device */
 #define StationDateTemplateSize 6       /* date template in the form M/D/Y, D/M/Y, ... */
@@ -573,6 +679,7 @@ static char *Media_PayloadList[] = {
 #define StationMaxSoftKeyIndex 16            /* max number of soft key indices in a station soft key set */
 #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 */
 
 static void dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
@@ -667,17 +774,50 @@ static int hf_skinny_dateMinute = -1;
 static int hf_skinny_dateSeconds = -1;
 static int hf_skinny_dateMilliseconds = -1;
 static int hf_skinny_timeStamp = -1;
+static int hf_skinny_callState = -1;
+static int hf_skinny_deviceTone = -1;
+static int hf_skinny_callingPartyName = -1;
+static int hf_skinny_callingParty = -1;
+static int hf_skinny_calledPartyName = -1;
+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_speakerMode = -1;
+static int hf_skinny_remoteIpAddr = -1;
+static int hf_skinny_remotePortNumber = -1;
+static int hf_skinny_millisecondPacketSize = -1;
+static int hf_skinny_precedenceValue = -1;
+static int hf_skinny_silenceSuppression = -1;
+static int hf_skinny_g723BitRate = -1;
+static int hf_skinny_conferenceID = -1;
+static int hf_skinny_deviceResetType = -1;
+static int hf_skinny_echoCancelType = -1;
+static int hf_skinny_deviceUnregisterStatus = -1;
+static int hf_skinny_hookFlashDetectMode = -1;
+static int hf_skinny_detectInterval = -1;
+static int hf_skinny_microphoneMode = -1;
+static int hf_skinny_unknown = -1;
+static int hf_skinny_activeForward = -1;
+static int hf_skinny_forwardAllActive = -1;
+static int hf_skinny_forwardBusyActive = -1;
+static int hf_skinny_forwardNoAnswerActive = -1;
+static int hf_skinny_forwardNumber = -1;
+static int hf_skinny_serverName = -1;
+static int hf_skinny_numberLines = -1;
+static int hf_skinny_numberSpeedDials = -1;
+static int hf_skinny_userName = -1;
+static int hf_skinny_sessionType = -1;
+static int hf_skinny_version = -1;
+static int hf_skinny_mediaEnunciationType = -1;
+static int hf_skinny_serverIdentifier = -1;
+static int hf_skinny_serverListenPort = -1;
+static int hf_skinny_serverIpAddress = -1;
+static int hf_skinny_multicastIpAddress = -1;
+static int hf_skinny_multicastPort = -1;
+static int hf_skinny_tokenRejWaitTime = -1;
 
 
-static int hf_skinny_extension   = -1;
-static int hf_skinny_unknown = -1;
-static int hf_skinny_ipDest = -1;
-static int hf_skinny_ipSrc = -1;
-static int hf_skinny_destPort = -1;
-static int hf_skinny_srcPort = -1;
-static int hf_skinny_softKeyNumber = -1;
-static int hf_skinny_line = -1;
-static int hf_skinny_dialedDigit = -1;
 
 /* Initialize the subtree pointers */
 static gint ett_skinny          = -1;
@@ -688,6 +828,23 @@ static gboolean skinny_desegment = TRUE;
 
 static dissector_handle_t data_handle;
 
+/* Get the length of a single SCCP PDU */
+static guint get_skinny_pdu_len(tvbuff_t *tvb, int offset)
+{
+  guint32 hdr_data_length;
+
+  /*
+   * Get the length of the SCCP packet.
+   */
+  hdr_data_length = tvb_get_letohl(tvb, offset);
+
+  /*
+   * That length doesn't include the length of the header itself;
+   * add that in.
+   */
+  return hdr_data_length + 8;
+}
+
 /* Dissect a single SCCP PDU */
 static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -700,21 +857,8 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
   gchar   *messageid_str;
   /*  guint32 data_size; */
 
-  guint32 unknown1 = 0;
-  guint32 unknown2 = 0;
-  guint32 unknown3 = 0;
-  guint32 unknown4 = 0;
-  guint32 unknown5 = 0;
-  guint32 unknown6 = 0;
-  guint32 unknown7 = 0;
-  guint32 unknown8 = 0;
-  guint32 unknown9 = 0;
-  guint32 unknown10 = 0;
-
-  int extensionLength = 10;
-  int displayLength   = 100;
-  char extension[extensionLength];
-  char displayMessage[displayLength];
+  guint32 unknownLong = 0;
+
   guint i = 0;
   int j = 0;
 
@@ -722,11 +866,11 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
   guint32 softKeyCount;
   guint32 softKeySetCount;
   guint16 validKeyMask;
-  
+
   /* Set up structures we will need to add the protocol subtree and manage it */
   proto_item *ti;
   proto_tree *skinny_tree = NULL;
-  
+
   proto_item *skm = NULL;
   proto_item *skm_tree = NULL;
 
@@ -737,9 +881,9 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
   /* 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); 
+    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_data_length, tvb, offset, 4, hdr_data_length);
     proto_tree_add_uint(skinny_tree, hf_skinny_reserved, tvb, offset+4, 4, hdr_reserved);
   }
 
@@ -768,10 +912,10 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
     case 0x8 :    /* hookFlash */
       break;
-      
+
     case 0xc :    /* configStateReqMessage */
       break;
-      
+
     case 0xd :    /* timeDateReqMessage */
       break;
 
@@ -780,10 +924,10 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
     case 0xf :    /* stationVersionReqMessage */
       break;
-      
+
     case 0x12 :   /* stationServerReqMessage */
       break;
-      
+
     case 0x25 :   /* softKeySetReqMessage */
       break;
 
@@ -796,12 +940,24 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x83 :   /* stopTone */
       break;
 
+    case 0x9a :   /* clearDisplay */
+      break;
+
     case 0x9b :   /* capabilitiesReqMessage */
       break;
 
     case 0x100 :    /* keepAliveAck */
       break;
-       
+
+    case 0x115 :  /* clearNotifyDisplay */
+      break;
+
+    case 0x117 :  /* deactivateCallPlane */
+      break;
+
+    case 0x11a :  /* registerTokenAck */
+      break;
+
     /*
      ** cases that need decode
      **
@@ -811,7 +967,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_ipSrc, tvb, offset+36, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+36, 4, TRUE);
       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;
@@ -827,7 +983,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x4 :  /* stationEnblocCallMessage -- This decode NOT verified*/
       proto_tree_add_item(skinny_tree, hf_skinny_calledParty, tvb, offset+12, StationMaxDirnumSize, TRUE);
       break;
-      
+
     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);
@@ -836,7 +992,7 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     case 0x9  : /* stationForwardStatReqMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_lineNumber, tvb, offset+12, 4, TRUE);
       break;
-      
+
     case 0xa :  /* speedDialStatReqMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_speedDialNumber, tvb, offset+12, 4, TRUE);
       break;
@@ -852,19 +1008,22 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        *
        * basically changing StationMaxCapabilities definition
        *
-       */      
+       */
       capCount = tvb_get_letohl(tvb, offset+12);
       proto_tree_add_uint(skinny_tree, hf_skinny_capCount, tvb, offset+12, 4, capCount);
       for (i = 0; i < capCount; i++) {
        proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+(i*16)+16, 4, TRUE);
-       proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket, tvb, offset+(i*16)+20, 4, TRUE);
+       proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket, tvb, offset+(i*16)+20, 2, TRUE);
        /* FIXME -- decode the union under here as required, is always 0 on my equipment */
       }
       break;
 
+    case 0x11 : /* mediaPortList */
+      break;
+
     case 0x20 :   /* stationAlarmMessage */
       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, 80, 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);
       break;
@@ -873,13 +1032,13 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       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);
       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);
-      break;   
+      break;
 
     case 0x23    :  /* stationConnectionStatisticsRes */
       proto_tree_add_item(skinny_tree, hf_skinny_directoryNumber, tvb, offset+12, StationMaxDirnumSize, TRUE);
@@ -893,29 +1052,38 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       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);
       break;
-      
+
+    case 0x24 : /* offHookWithCgpn */
+      proto_tree_add_item(skinny_tree, hf_skinny_calledParty, tvb, offset+12,StationMaxDirnumSize, TRUE);
+      break;
+
     case 0x26 :  /* softKeyEventMessage */
       proto_tree_add_item(skinny_tree, hf_skinny_softKeyEvent, tvb, offset+12, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_unknown, tvb, offset+16, 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);
       break;
 
+    case 0x29 : /* registerTokenREq */
+      proto_tree_add_item(skinny_tree, hf_skinny_deviceName, tvb, offset+12, 4, TRUE);
+      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_deviceType, tvb, i+12, 4, TRUE);
+      break;
+
       /*
        *
        * message not in the spec
        *
        */
     case 0x2b :  /* unknownClientMessage1 */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
       break;
 
     case 0x2d :  /* unknownClientMessage2 */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
       break;
 
-      /* 
+      /*
        *
        *  Call manager -> client messages start here(ish)
        *
@@ -927,52 +1095,95 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       break;
 
     case 0x82 :  /* startTone */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
+      proto_tree_add_item(skinny_tree, hf_skinny_deviceTone, tvb, offset+12, 4, TRUE);
       break;
 
     case 0x85 : /* setRingerMessage */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
+      proto_tree_add_item(skinny_tree, hf_skinny_ringType, tvb, offset+12, 4, TRUE);
       break;
-       
+
     case 0x86 : /* setLampMessage */
       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);
       proto_tree_add_item(skinny_tree, hf_skinny_lampMode, tvb, offset+20, 4, TRUE);
       break;
 
-    case 0x88 : /* setSpeakerModeMessage */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
-      break;
-       
-    case 0x8a :
-      unknown1  = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
-      unknown2  = tvb_get_letohl(tvb, offset+16);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2);
-      proto_tree_add_item(skinny_tree, hf_skinny_ipDest,   tvb, offset+20, 4, TRUE);
-      proto_tree_add_item(skinny_tree, hf_skinny_destPort,tvb, offset+24, 4, TRUE);
-      unknown5  = tvb_get_letohl(tvb, offset+28);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+28, 4, unknown5);
-      unknown6  = tvb_get_letohl(tvb, offset+32);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+32, 4, unknown6);
-      unknown7  = tvb_get_letohl(tvb, offset+36);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknown7);
-      unknown8  = tvb_get_letohl(tvb, offset+40);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+40, 4, unknown8);
-      unknown9  = tvb_get_letohl(tvb, offset+44);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+44, 4, unknown9);
-      unknown10 = tvb_get_letohl(tvb, offset+48);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+48, 4, unknown10);
+    case 0x87 : /* stationHookFlashDetectMode */
+      proto_tree_add_item(skinny_tree, hf_skinny_hookFlashDetectMode, tvb, offset+12, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_detectInterval, tvb, offset+16, 4, TRUE);
+      break;
+
+    case 0x88 : /* setSpeakerMode */
+
+      proto_tree_add_item(skinny_tree, hf_skinny_speakerMode, tvb, offset+12, 4, TRUE);
+      break;
+
+    case 0x89 : /* setMicroMode */
+      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);
       break;
 
     case 0x8b :  /* stopMediaTransmission */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
-      unknown2 = tvb_get_letohl(tvb, offset+16);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2);
+
+      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);
+      break;
+
+    case 0x8c : /* startMediaReception */
+      break;
+
+    case 0x8d : /* stopMediaReception */
+      break;
+
+    case 0x8e : /* reservered */
+      break;
+
+    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 += 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);
+      i += StationMaxDirnumSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, i, 4, TRUE);
+      i += 4;
+      proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, i, 4, TRUE);
+      i += 4;
+      proto_tree_add_item(skinny_tree, hf_skinny_callType, tvb, i, 4, TRUE);
+      i += 4;
+      proto_tree_add_item(skinny_tree, hf_skinny_originalCalledPartyName, tvb, i, StationMaxNameSize, TRUE);
+      i += StationMaxNameSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_originalCalledParty, tvb, i, StationMaxDirnumSize, TRUE);
+      break;
+
+    case 0x90 : /* forwardStat */
+      proto_tree_add_item(skinny_tree, hf_skinny_activeForward, tvb, offset+12, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_lineNumber, tvb, offset+16, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_forwardAllActive, tvb, offset+20, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_forwardNumber, tvb, offset+24, StationMaxDirnumSize, TRUE);
+      i = offset+24+StationMaxDirnumSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_forwardBusyActive, tvb, i, 4, TRUE);
+      i += 4;
+      proto_tree_add_item(skinny_tree, hf_skinny_forwardNumber, tvb, i, StationMaxDirnumSize, TRUE);
+      i += StationMaxDirnumSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_forwardNoAnswerActive, tvb, i, 4, TRUE);
+      i += 4;
+      proto_tree_add_item(skinny_tree, hf_skinny_forwardNumber, tvb, i, StationMaxDirnumSize, TRUE);
       break;
 
     case 0x91 : /* speedDialStatMessage */
@@ -987,6 +1198,21 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_lineFullyQualifiedDisplayName, tvb, offset+16+StationMaxDirnumSize, StationMaxNameSize, TRUE);
       break;
 
+    case 0x93 : /* configStat */
+      proto_tree_add_item(skinny_tree, hf_skinny_deviceName, tvb, offset+12, StationMaxDeviceNameSize, TRUE);
+      i = offset+12+StationMaxDeviceNameSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_stationUserId, tvb, i, 4, TRUE);
+      i += 4;
+      proto_tree_add_item(skinny_tree, hf_skinny_stationInstance, tvb, i, 4, TRUE);
+      i += 4;
+      proto_tree_add_item(skinny_tree, hf_skinny_userName, tvb, i, StationMaxNameSize, TRUE);
+      i += StationMaxNameSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_serverName, tvb, i, StationMaxNameSize, TRUE);
+      i += StationMaxNameSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_numberLines, tvb, i, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_numberSpeedDials, tvb, i+4, 4, TRUE);
+      break;
+
     case 0x94 : /* stationDefineTimeDate */
       proto_tree_add_item(skinny_tree, hf_skinny_dateYear,   tvb, offset+12, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_dateMonth,  tvb, offset+16, 4, TRUE);
@@ -998,7 +1224,17 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_item(skinny_tree, hf_skinny_dateMilliseconds,tvb, offset+40, 4, TRUE);
       proto_tree_add_item(skinny_tree, hf_skinny_timeStamp, tvb, offset+44, 4, TRUE);
       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_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_sessionType, tvb, offset+16, 4, TRUE);
+      break;
+
     case 0x97 :  /* buttonTemplateMessage  */
       /*
        * FIXME
@@ -1015,49 +1251,101 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       }
       break;
 
+    case 0x98 : /* version */
+      proto_tree_add_item(skinny_tree, hf_skinny_version, tvb, offset+12, StationMaxVersionSize, TRUE);
+      break;
+
     case 0x99 :  /* displayTextMessage */
-      memset(displayMessage, '\0', displayLength);
-      tvb_memcpy(tvb, displayMessage, offset+12, 32);
-      proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, offset+12, strlen(displayMessage), displayMessage);        
-      unknown1  = tvb_get_letohl(tvb, offset+44);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+44, 4, unknown1);
+      proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+12, StationMaxDisplayTextSize, TRUE);
+      break;
+
+    case 0x9c : /* enunciatorCommand */
+      proto_tree_add_item(skinny_tree, hf_skinny_mediaEnunciationType, tvb, offset+12, 4, TRUE);
+      for (i = 0; i < StationMaxDirnumSize; i++) {
+       proto_tree_add_item(skinny_tree, hf_skinny_unknown, tvb, offset+16+(i*4), 4, TRUE);
+      }
+      i = offset+16+StationMaxDirnumSize;
+      proto_tree_add_item(skinny_tree, hf_skinny_mediaEnunciationType, tvb, i, 4, TRUE);
       break;
 
     case 0x9d : /* stationRegisterReject */
+      proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+12, StationMaxDisplayTextSize, TRUE);
+      break;
+
+    case 0x9e : /* serverRes */
+      for (i = 0; i < StationMaxServers; i++) {
+       proto_tree_add_item(skinny_tree, hf_skinny_serverIdentifier, tvb, offset+12+(i*StationMaxServers), StationMaxServerNameSize, TRUE);
+      }
+      j = offset+12+(i*StationMaxServers);
+      for (i = 0; i < StationMaxServers; i++) {
+       proto_tree_add_item(skinny_tree, hf_skinny_serverListenPort, tvb, j+(i*4), 4,  TRUE);
+      }
+      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);
+      }
       break;
-      
+
     case 0x9f :   /* reset */
-      unknown1  = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
+      proto_tree_add_item(skinny_tree, hf_skinny_deviceResetType, tvb, offset+12, 4, TRUE);
+      break;
+
+    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_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);
+      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_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_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);
+      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);
+      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);
       break;
 
     case 0x105 : /* open receive channel */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
-      unknown2 = tvb_get_letohl(tvb, offset+16);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2);
-      unknown3 = tvb_get_letohl(tvb, offset+20);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+20, 4, unknown3);
-      unknown4 = tvb_get_letohl(tvb, offset+24);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+24, 4, unknown4);
-      unknown5 = tvb_get_letohl(tvb, offset+28);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+28, 4, unknown5);
-      unknown6 = tvb_get_letohl(tvb, offset+32);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+32, 4, unknown6);
+      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);
       break;
 
     case 0x106 :  /* closeReceiveChannel */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
-      unknown2 = tvb_get_letohl(tvb, offset+16);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2);
+      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);
       break;
 
-    case 0x107 :      
-      memset(extension, '\0', extensionLength);
-      tvb_get_nstringz0(tvb, offset+12, extensionLength, extension);
-      proto_tree_add_string(skinny_tree, hf_skinny_extension, tvb, offset+12, strlen(extension), extension);
-      proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+36, 4, TRUE);
+    case 0x107 :  /* connectionStatisticsReq */
+
+      i = 12;
+      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);
+      i = i+4;
+      proto_tree_add_item(skinny_tree, hf_skinny_statsProcessingType, tvb, i, 4, TRUE);
       break;
 
     case 0x108 :   /* softkeyTemplateResMessage */
@@ -1070,7 +1358,7 @@ 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+(i*20)+40, 4, TRUE);
       }
       /* there is more data here, but it doesn't make a whole lot of sense, I imagine
-       * it's just some not zero'd out stuff in the packet or... 
+       * it's just some not zero'd out stuff in the packet or...
        */
       break;
 
@@ -1080,16 +1368,16 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       proto_tree_add_uint(skinny_tree, hf_skinny_softKeySetCount, tvb, offset+16, 4, softKeySetCount);
       proto_tree_add_item(skinny_tree, hf_skinny_totalSoftKeySetCount, tvb, offset+20, 4, TRUE);
       for (i = 0; ((i < StationMaxSoftKeySetDefinition) && (i < softKeySetCount)); i++) {
-       proto_tree_add_uint(skinny_tree, hf_skinny_softKeySetDescription, tvb, offset+(i*20)+24+j,1,i);
+       proto_tree_add_uint(skinny_tree, hf_skinny_softKeySetDescription, tvb, offset+24+(i*48) , 1, i);
        for (j = 0; j < StationMaxSoftKeyIndex; j++) {
-         proto_tree_add_item(skinny_tree, hf_skinny_softKeyTemplateIndex, tvb, offset+(i*20)+24+j, 1, TRUE);
+         proto_tree_add_item(skinny_tree, hf_skinny_softKeyTemplateIndex, tvb, offset+24+(i*48)+j, 1, TRUE);
        }
        for (j = 0; j < StationMaxSoftKeyIndex; j++) {
-         proto_tree_add_item(skinny_tree, hf_skinny_softKeyInfoIndex, tvb, offset+(i*20)+25+(j*2), 2, TRUE);
+         proto_tree_add_item(skinny_tree, hf_skinny_softKeyInfoIndex, tvb, offset+24+(i*48)+StationMaxSoftKeyIndex+(j*2), 2, TRUE);
        }
       }
       break;
-      
+
     case 0x110 : /* selectSoftKeys */
       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);
@@ -1114,58 +1402,55 @@ static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
       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);
       break;
-      
-    case 0x111 :
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
-      unknown2 = tvb_get_letohl(tvb, offset+16);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2);
+
+    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);
       break;
-      
-    case 0x112 :
+
+    case 0x112 : /* displayPromptStatus */
       proto_tree_add_item(skinny_tree, hf_skinny_messageTimeOutValue, tvb, offset+12, 4, TRUE);
       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);
       break;
-      
-    case 0x113:
+
+    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);
       break;
-      
-    case 0x114 :
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
-      memset(displayMessage,'\0',displayLength);
-      tvb_memcpy(tvb, displayMessage, offset+16, 16);
-      proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, strlen(displayMessage), displayMessage);
-      unknown2 = tvb_get_letohl(tvb, offset+32);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+32, 4, unknown2);
-      unknown3 = tvb_get_letohl(tvb, offset+36);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknown3);
-      unknown4 = tvb_get_letohl(tvb, offset+40);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+40, 4, unknown4);
-      unknown5 = tvb_get_letohl(tvb, offset+44);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+44, 4, unknown5);
-      break;
-      
-    case 0x116 :
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
+
+    case 0x114 : /* displayNotify */
+      proto_tree_add_item(skinny_tree, hf_skinny_messageTimeOutValue, tvb, offset+12, 4, TRUE);
+      proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, StationMaxDisplayNotifySize , TRUE);
+      break;
+
+    case 0x116 : /* activateCallPlane */
+      proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
       break;
 
     case 0x118 :    /* unregisterAckMessage */
-      unknown1 = tvb_get_letohl(tvb, offset+12);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1);
+      proto_tree_add_item(skinny_tree, hf_skinny_deviceUnregisterStatus, tvb, offset+12, 4, TRUE);
+      break;
+
+    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);
       break;
 
-    case 0x11D :
-      unknown1       = tvb_get_letohl(tvb, offset+36);
-      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknown1);
+    case 0x11B : /* registerTokenReject */
+      proto_tree_add_item(skinny_tree, hf_skinny_tokenRejWaitTime, tvb, offset+12, 4, TRUE);
+      break;
+
+    case 0x11D : /* new message */
+      unknownLong       = tvb_get_letohl(tvb, offset+36);
+      proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknownLong);
       proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+40, 4, TRUE);
       break;
-      
+
+
+
     default:
       break;
     }
@@ -1178,141 +1463,43 @@ static void 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)}
    */
-  
-  volatile int offset = 0;
-  int length_remaining;
-  int length;
-  tvbuff_t *next_tvb;
-
   /* Header fields */
   volatile guint32 hdr_data_length;
   guint32 hdr_reserved;
 
   /* 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);
 
   /*  data_size       = MIN(8+hdr_data_length, tvb_length(tvb)) - 0xC; */
-  
+
   /* hdr_data_length > 1024 is just a heuristic. Better values/checks welcome */
   if (hdr_data_length < 4 || hdr_data_length > 1024 || hdr_reserved != 0) {
     /* Not an SKINNY packet, just happened to use the same port */
     call_dissector(data_handle,tvb, pinfo, tree);
     return;
   }
-  
+
   /* 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");
   }
-  
+
   if (check_col(pinfo->cinfo, COL_INFO)) {
     col_set_str(pinfo->cinfo, COL_INFO, "Skinny Client Control Protocol");
   }
-  
-  while (tvb_reported_length_remaining(tvb, offset) != 0) {
-    length_remaining = tvb_length_remaining(tvb, offset);
-
-    /*
-     * Can we do reassembly?
-     */
-    if (skinny_desegment && pinfo->can_desegment) {
-      /*
-       * Yes - is the length field in the SCCP header split across
-       * segment boundaries?
-       */
-      if (length_remaining < 4) {
-       /*
-        * Yes.  Tell the TCP dissector where the data for this message
-        * starts in the data it handed us, and how many more bytes we
-        * need, and return.
-        */
-       pinfo->desegment_offset = offset;
-       pinfo->desegment_len = 4 - length_remaining;
-       return;
-      }
-    }
 
-    /*
-     * Get the length of the SCCP packet.
-     */
-    hdr_data_length = tvb_get_letohl(tvb, offset);
-
-    /*
-     * Can we do reassembly?
-     */
-    if (skinny_desegment && pinfo->can_desegment) {
-      /*
-       * Yes - is the SCCP packet split across segment boundaries?
-       */
-      if ((guint32)length_remaining < hdr_data_length + 8) {
-       /*
-        * Yes.  Tell the TCP dissector where the data for this message
-        * starts in the data it handed us, and how many more bytes we
-        * need, and return.
-        */
-       pinfo->desegment_offset = offset;
-       pinfo->desegment_len = (hdr_data_length + 8) - length_remaining;
-       return;
-      }
-    }
-
-    /*
-     * Construct a tvbuff containing the amount of the payload we have
-     * available.  Make its reported length the amount of data in the
-     * SCCP packet.
-     *
-     * XXX - if reassembly isn't enabled. the subdissector will throw a
-     * BoundsError exception, rather than a ReportedBoundsError exception.
-     * We really want a tvbuff where the length is "length", the reported
-     * length is "hdr_data_length + 8", and the "if the snapshot length
-     * were infinite" length is the minimum of the reported length of
-     * the tvbuff handed to us and "hdr_data_length + 8", with a new type
-     * of exception thrown if the offset is within the reported length but
-     * beyond that third length, with that exception getting the
-     * "Unreassembled Packet" error.
-     */
-    length = length_remaining;
-    if ((guint32)length > hdr_data_length + 8)
-      length = hdr_data_length + 8;
-    next_tvb = tvb_new_subset(tvb, offset, length, hdr_data_length + 8);
-
-    /*
-     * Dissect the SCCP packet.
-     *
-     * Catch the ReportedBoundsError exception; if this particular message
-     * happens to get a ReportedBoundsError exception, that doesn't mean
-     * that we should stop dissecting SCCP messages within this frame or
-     * chunk of reassembled data.
-     *
-     * If it gets a BoundsError, we can stop, as there's nothing more to
-     * see, so we just re-throw it.
-     */
-    TRY {
-      dissect_skinny_pdu(next_tvb, pinfo, tree);
-    }
-    CATCH(BoundsError) {
-      RETHROW;
-    }
-    CATCH(ReportedBoundsError) {
-      show_reported_bounds_error(tvb, pinfo, tree);
-    }
-    ENDTRY;
-
-    /*
-     * Skip the SCCP header and the payload.
-     */
-    offset += hdr_data_length + 8;
-  }
+  tcp_dissect_pdus(tvb, pinfo, tree, skinny_desegment, 4,
+       get_skinny_pdu_len, dissect_skinny_pdu);
 }
 
 /* Register the protocol with Ethereal */
-void 
+void
 proto_register_skinny(void)
-{                 
-  
+{
+
   /* Setup list of header fields */
   static hf_register_info hf[] = {
     { &hf_skinny_data_length,
@@ -1435,7 +1622,7 @@ proto_register_skinny(void)
 
     { &hf_skinny_maxFramesPerPacket,
       { "MaxFramesPerPacket", "skinny.maxFramesPerPacket",
-       FT_UINT32, BASE_DEC, NULL, 0x0,
+       FT_UINT16, BASE_DEC, NULL, 0x0,
        "Max frames per packet",
        HFILL }
     },
@@ -1707,135 +1894,135 @@ proto_register_skinny(void)
     },
 
     { &hf_skinny_softKeyMap,
-      { "SoftKeyMap","skinny.softKeyMap", 
+      { "SoftKeyMap","skinny.softKeyMap",
        FT_UINT16, BASE_HEX, NULL, 0x0,
-       "", 
+       "",
        HFILL }
     },
-    
+
     { &hf_skinny_softKey0,
-      { "SoftKey0", "skinny.softKeyMap.0", 
+      { "SoftKey0", "skinny.softKeyMap.0",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY0,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey1,
-      { "SoftKey1", "skinny.softKeyMap.1", 
+      { "SoftKey1", "skinny.softKeyMap.1",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY1,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey2,
-      { "SoftKey2", "skinny.softKeyMap.2", 
+      { "SoftKey2", "skinny.softKeyMap.2",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY2,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey3,
       { "SoftKey3", "skinny.softKeyMap.3",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY3,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey4,
-      { "SoftKey4", "skinny.softKeyMap.4", 
+      { "SoftKey4", "skinny.softKeyMap.4",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY4,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey5,
-      { "SoftKey5", "skinny.softKeyMap.5", 
+      { "SoftKey5", "skinny.softKeyMap.5",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY5,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey6,
-      { "SoftKey6", "skinny.softKeyMap.6", 
+      { "SoftKey6", "skinny.softKeyMap.6",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY6,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey7,
-      { "SoftKey7", "skinny.softKeyMap.7", 
+      { "SoftKey7", "skinny.softKeyMap.7",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY7,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey8,
-      { "SoftKey8", "skinny.softKeyMap.8", 
+      { "SoftKey8", "skinny.softKeyMap.8",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY8,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey9,
-      { "SoftKey9", "skinny.softKeyMap.9", 
+      { "SoftKey9", "skinny.softKeyMap.9",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY9,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey10,
-      { "SoftKey10", "skinny.softKeyMap.10", 
+      { "SoftKey10", "skinny.softKeyMap.10",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY10,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey11,
-      { "SoftKey11", "skinny.softKeyMap.11", 
+      { "SoftKey11", "skinny.softKeyMap.11",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY11,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey12,
-      { "SoftKey12", "skinny.softKeyMap.12", 
+      { "SoftKey12", "skinny.softKeyMap.12",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY12,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey13,
-      { "SoftKey13", "skinny.softKeyMap.13", 
+      { "SoftKey13", "skinny.softKeyMap.13",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY13,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey14,
-      { "SoftKey14", "skinny.softKeyMap.14", 
+      { "SoftKey14", "skinny.softKeyMap.14",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY14,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_softKey15,
-      { "SoftKey15", "skinny.softKeyMap.15", 
+      { "SoftKey15", "skinny.softKeyMap.15",
        FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY15,
-       "", 
+       "",
        HFILL }
     },
 
     { &hf_skinny_lampMode,
-      { "LampMode", "skinny.lampMode", 
+      { "LampMode", "skinny.lampMode",
        FT_UINT32, BASE_DEC, VALS(stationLampModes), 0x0,
-       "The lamp mode", 
+       "The lamp mode",
        HFILL }
     },
 
     { &hf_skinny_messageTimeOutValue,
-      { "Message Timeout", "skinny.messageTimeOutValue", 
+      { "Message Timeout", "skinny.messageTimeOutValue",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "The timeout in seconds for this message", 
+       "The timeout in seconds for this message",
        HFILL }
     },
 
@@ -1936,86 +2123,302 @@ proto_register_skinny(void)
        "Time stamp for the call reference",
        HFILL }
     },
+    { &hf_skinny_callState,
+      { "CallState", "skinny.callState",
+       FT_UINT32, BASE_DEC, VALS(skinny_stationCallStates), 0x0,
+       "The D channel call state of the call",
+       HFILL }
+    },
 
+    { &hf_skinny_deviceTone,
+      { "Tone", "skinny.deviceTone",
+       FT_UINT32, BASE_HEX, VALS(skinny_deviceTones), 0x0,
+       "Which tone to play",
+       HFILL }
+    },
 
+    { &hf_skinny_callingPartyName,
+      { "Calling Party Name", "skinny.callingPartyName",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "The passed name of the calling party.",
+       HFILL }
+    },
 
+    { &hf_skinny_callingParty,
+      { "Calling Party", "skinny.callingPartyName",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "The passed number of the calling party.",
+       HFILL }
+    },
 
+    { &hf_skinny_calledPartyName,
+      { "Called Party Name", "skinny.calledPartyName",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "The name of the party we are calling.",
+       HFILL }
+    },
 
+    { &hf_skinny_callType,
+      { "Call Type", "skinny.callType",
+       FT_UINT32, BASE_DEC, VALS(skinny_callTypes), 0x0,
+       "What type of call, in/out/etc",
+       HFILL }
+    },
 
+    { &hf_skinny_originalCalledPartyName,
+      { "Original Called Party Name", "skinny.originalCalledPartyName",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "name of the original person who placed the call.",
+       HFILL }
+    },
 
-    /* */
+    { &hf_skinny_originalCalledParty,
+      { "Original Called Party", "skinny.originalCalledParty",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "The number of the original calling party.",
+       HFILL }
+    },
 
+    { &hf_skinny_ringType,
+      { "Ring Type", "skinny.ringType",
+       FT_UINT32, BASE_HEX, VALS(skinny_ringTypes), 0x0,
+       "What type of ring to play",
+       HFILL }
+    },
 
-    { &hf_skinny_extension,
-      { "Extension", "skinny.extension",
-       FT_STRING, BASE_NONE, NULL, 0x0,
-       "The extension this packets is for.",
+    { &hf_skinny_speakerMode,
+      { "Speaker", "skinny.speakerMode",
+       FT_UINT32, BASE_HEX, VALS(skinny_speakerModes), 0x0,
+       "This message sets the speaker mode on/off",
        HFILL }
     },
 
+    { &hf_skinny_remoteIpAddr,
+      { "Remote Ip Address", "skinny.remoteIpAddr",
+       FT_IPv4, BASE_NONE, NULL, 0x0,
+       "The remote end ip address for this stream",
+       HFILL }
+    },
 
+    { &hf_skinny_remotePortNumber,
+      { "Remote Port", "skinny.remotePortNumber",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "The remote port number listening for this stream",
+       HFILL }
+    },
 
+    { &hf_skinny_millisecondPacketSize,
+      { "MS/Packet", "skinny.millisecondPacketSize",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "The number of milliseconds of conversation in each packet",
+       HFILL }
+    },
 
-    { &hf_skinny_unknown,
-      { "Unknown Long", "skinny.unknown",
-       FT_UINT32, BASE_HEX, NULL, 0x0,
-       "An as yet undecoded long value",
+    { &hf_skinny_precedenceValue,
+      { "Precedence", "skinny.precedenceValue",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "Precedence value",
        HFILL }
     },
-   
-    { &hf_skinny_ipSrc,
-      { "IP Source", "skinny.ipSrc",
-       FT_IPv4, BASE_NONE, NULL, 0x0,
-       "Ip source address",
+
+    { &hf_skinny_silenceSuppression,
+      { "Silence Suppression", "skinny.silenceSuppression",
+       FT_UINT32, BASE_HEX, VALS(skinny_silenceSuppressionModes), 0x0,
+       "Mode for silence suppression",
        HFILL }
     },
 
-    { &hf_skinny_ipDest,
-      { "IP Destination", "skinny.ipDest",
-       FT_IPv4, BASE_NONE, NULL, 0x0,
-       "IP destination address",
+    { &hf_skinny_g723BitRate,
+      { "G723 BitRate", "skinny.g723BitRate",
+       FT_UINT32, BASE_DEC, VALS(skinny_g723BitRates), 0x0,
+       "The G723 bit rate for this stream/JUNK if not g723 stream",
        HFILL }
     },
 
+    { &hf_skinny_conferenceID,
+      { "Conference ID", "skinny.conferenceID",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "The conference ID",
+       HFILL }
+    },
+
+    { &hf_skinny_deviceResetType,
+      { "Reset Type", "skinny.deviceResetType",
+       FT_UINT32, BASE_DEC, VALS(skinny_deviceResetTypes), 0x0,
+       "How the devices it to be reset (reset/restart)",
+       HFILL }
+    },
 
+    { &hf_skinny_echoCancelType,
+      { "Echo Cancel Type", "skinny.echoCancelType",
+       FT_UINT32, BASE_DEC, VALS(skinny_echoCancelTypes), 0x0,
+       "Is echo cancelling enabled or not",
+       HFILL }
+    },
+
+    { &hf_skinny_deviceUnregisterStatus,
+      { "Unregister Status", "skinny.deviceUnregisterStatus",
+       FT_UINT32, BASE_DEC, VALS(skinny_deviceUnregisterStatusTypes), 0x0,
+       "The status of the device unregister request (*CAN* be refused)",
+       HFILL }
+    },
+
+    { &hf_skinny_hookFlashDetectMode,
+      { "Hook Flash Mode", "skinny.hookFlashDetectMode",
+       FT_UINT32, BASE_DEC, VALS(skinny_hookFlashDetectModes), 0x0,
+       "Which method to use to detect that a hook flash has occured",
+       HFILL }
+    },
 
-    { &hf_skinny_destPort,
-      { "Destination Port", "skinny.destPort",
+    { &hf_skinny_detectInterval,
+      { "HF Detect Interval", "skinny.detectInterval",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "Destination Port",
+       "The number of milliseconds that determines a hook flash has occured",
+       HFILL }
+    },
+
+    { &hf_skinny_microphoneMode,
+      { "Microphone Mode", "skinny.microphoneMode",
+       FT_UINT32, BASE_DEC, VALS(skinny_microphoneModes), 0x0,
+       "Turns on and off the microphone on the set",
        HFILL }
     },
 
-    { &hf_skinny_srcPort,
-      { "Source Port", "skinny.srcPort",
+    { &hf_skinny_activeForward,
+      { "Active Forward", "skinny.activeForward",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "Source Port",
+       "This is non zero to indicate that a forward is active on the line",
        HFILL }
     },
 
-    { &hf_skinny_softKeyNumber,
-      { "SoftKey", "skinny.softKeyNumber",
+    { &hf_skinny_forwardAllActive,
+      { "Forward All", "skinny.forwardAllActive",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "SoftKey",
+       "Forward all calls",
        HFILL }
     },
 
-    { &hf_skinny_dialedDigit,
-      { "Dialed Digit", "skinny.dialedDigit",
+    { &hf_skinny_forwardBusyActive,
+      { "Forward Busy", "skinny.forwardBusyActive",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "Dialed Digit",
+       "Forward calls when busy",
        HFILL }
     },
 
-    { &hf_skinny_line,
-      { "Line", "skinny.line",
+    { &hf_skinny_forwardNoAnswerActive,
+      { "Forward NoAns", "skinny.forwardNoAnswerActive",
        FT_UINT32, BASE_DEC, NULL, 0x0,
-       "Line",
+       "Forward only when no answer",
+       HFILL }
+    },
+
+    { &hf_skinny_forwardNumber,
+      { "Forward Number", "skinny.forwardNumber",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "The number to forward calls to.",
+       HFILL }
+    },
+
+    { &hf_skinny_userName,
+      { "Username", "skinny.userName",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "Username for this device.",
+       HFILL }
+    },
+
+    { &hf_skinny_serverName,
+      { "Server Name", "skinny.serverName",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "The server name for this device.",
+       HFILL }
+    },
+
+    { &hf_skinny_numberLines,
+      { "Number of Lines", "skinny.numberLines",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "How many lines this device has",
+       HFILL }
+    },
+
+    { &hf_skinny_numberSpeedDials,
+      { "Number of SpeedDials", "skinny.numberSpeedDials",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "The number of speed dials this device has",
+       HFILL }
+    },
+
+    { &hf_skinny_sessionType,
+      { "Session Type", "skinny.sessionType",
+       FT_UINT32, BASE_DEC, VALS(skinny_sessionTypes), 0x0,
+       "The type of this session.",
+       HFILL }
+    },
+
+    { &hf_skinny_version,
+      { "Version", "skinny.version",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "Version.",
+       HFILL }
+    },
+
+    { &hf_skinny_mediaEnunciationType,
+      { "Enunciation Type", "skinny.mediaEnunciationType",
+       FT_UINT32, BASE_DEC, VALS(skinny_mediaEnunciationTypes), 0x0,
+       "No clue.",
+       HFILL }
+    },
+
+    { &hf_skinny_serverIdentifier,
+      { "Server Identifier", "skinny.serverIdentifier",
+       FT_STRING, BASE_NONE, NULL, 0x0,
+       "Server Identifier.",
+       HFILL }
+    },
+
+    { &hf_skinny_serverListenPort,
+      { "Server Port", "skinny.serverListenPort",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "The port the server listens on.",
+       HFILL }
+    },
+
+    { &hf_skinny_serverIpAddress,
+      { "Server Ip Address", "skinny.serverIpAddress",
+       FT_IPv4, BASE_NONE, NULL, 0x0,
+       "The IP address for this server",
+       HFILL }
+    },
+
+    { &hf_skinny_multicastPort,
+      { "Multicast Port", "skinny.multicastPort",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "The multicast port the to listens on.",
+       HFILL }
+    },
+
+    { &hf_skinny_multicastIpAddress,
+      { "Multicast Ip Address", "skinny.multicastIpAddress",
+       FT_IPv4, BASE_NONE, NULL, 0x0,
+       "The multicast address for this conference",
+       HFILL }
+    },
+
+    { &hf_skinny_tokenRejWaitTime,
+      { "Retry Wait Time", "skinny.tokenRejWaitTime",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "The time to wait before retrying this token request.",
+       HFILL }
+    },
+
+    { &hf_skinny_unknown,
+      { "Data", "skinny.unknown",
+       FT_UINT32, BASE_HEX, NULL, 0x0,
+       "Place holder for unknown data.",
        HFILL }
     },
 
   };
-  
+
   /* Setup protocol subtree array */
   static gint *ett[] = {
     &ett_skinny,
@@ -2027,7 +2430,7 @@ proto_register_skinny(void)
   /* Register the protocol name and description */
   proto_skinny = proto_register_protocol("Skinny Client Control Protocol",
                                         "SKINNY", "skinny");
-  
+
   /* Required function calls to register the header fields and subtrees used */
   proto_register_field_array(proto_skinny, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
@@ -2037,7 +2440,7 @@ proto_register_skinny(void)
     "Desegment all SCCP messages spanning multiple TCP segments",
     "Whether the SCCP dissector should desegment all messages spanning multiple TCP segments",
     &skinny_desegment);
-};
+}
 
 void
 proto_reg_handoff_skinny(void)
@@ -2048,3 +2451,105 @@ proto_reg_handoff_skinny(void)
   skinny_handle = create_dissector_handle(dissect_skinny, proto_skinny);
   dissector_add("tcp.port", TCP_PORT_SKINNY, skinny_handle);
 }
+
+/*
+ * FIXME:
+ *
+ * This is the status of this decode.
+ * Items marked as N/A in the decode field have no params to test
+ * implemented for N/A means they exist in the switch statement
+ * S = stubbed
+ *
+ *  id     message                     implemented  decode tested (via capture)
+ *  ---------------------------------------------------------------------------
+ *  0x0    keepAlive                       Y        N/A
+ *  0x1    register                        Y        Y
+ *  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
+ *  0x8    hookFlash                       Y        N/A
+ *  0x9    forwardStatReq                  Y        N
+ *  0xa    speedDialStatReq                Y        Y
+ *  0xb    lineStatReq                     Y        Y
+ *  0xc    configStatReq                   Y        N/A
+ *  0xd    timeDateReq                     Y        N/A
+ *  0xe    buttonTemplateReq               Y        N/A
+ *  0xf    versionReq                      Y        N/A
+ *  0x10   capabilitiesRes                 Y        Y -- would like more decodes
+ *  0x11   mediaPortList                   S        N -- no info
+ *  0x12   serverReq                       Y        N/A
+ *  0x20   alarmMessage                    Y        Y
+ *  0x21   multicastMediaReceptionAck      Y        N
+ *  0x22   openReceiveChannelAck           Y        Y
+ *  0x23   connectionStatisticsRes         Y        Y
+ *  0x24   offHookWithCgpn                 Y        N
+ *  0x25   softKeySetReq                   Y        N/A
+ *  0x26   softKeyEvent                    Y        Y
+ *  0x27   unregister                      Y        N/A
+ *  0x28   softKeytemplateReq              Y        N/A
+ *  0x29   registerTokenReq                Y        N
+ *******************************
+ *  0x2b   unknownClientMessage1           S        N
+ *  0x2d   unknownClientMessage2           S        N
+ *******************************
+ *  0x81   registerAck                     Y        Y
+ *  0x82   startTone                       Y        Y
+ *  0x83   stopTone                        Y        N/A
+ *  0x85   setRinger                       Y        Y
+ *  0x86   setLamp                         Y        Y
+ *  0x87   setHkFDetect                    Y        N
+ *  0x88   setSpeakerMode                  Y        Y
+ *  0x89   setMicroMode                    Y        N
+ *  0x8A   startMediaTransmission          Y        Y
+ *  0x8B   stopMediaTransmission           Y        Y
+ *  0x8C   startMediaReception             S        N
+ *  0x8D   stopMediaReception              S        N
+ *  0x8E   *reserved*                      S        *
+ *  0x8F   callInfo                        Y        Y
+ *  0x90   forwardStat                     Y        N
+ *  0x91   speedDialStat                   Y        Y
+ *  0x92   lineStat                        Y        Y
+ *  0x93   configStat                      Y        N
+ *  0x94   defineTimeDate                  Y        Y
+ *  0x95   startSessionTransmission        Y        N
+ *  0x96   stopSessionTransmission         Y        N
+ *  0x97   buttonTemplate                  Y        Y -- ugly =)
+ *  0x98   version                         Y        N
+ *  0x99   displayText                     Y        Y
+ *  0x9A   clearDisplay                    Y        N/A
+ *  0x9B   capabilitiesReq                 Y        N/A
+ *  0x9C   enunciatorCommand               Y        N (inner loop unknown)
+ *  0x9D   registerReject                  Y        N
+ *  0x9E   serverRes                       Y        N
+ *  0x9F   reset                           Y        Y
+ *  0x100  keepAliveAck                    Y        N/A
+ *  0x101  startMulticastMediaReception    Y        N
+ *  0x102  startMulticastMediaTransmission Y        N
+ *  0x103  stopMulticastMediaReception     Y        N
+ *  0x104  stopMulticastMediaTransmission  Y        N
+ *  0x105  openreceiveChannel              Y        Y
+ *  0x106  closeReceiveChannel             Y        Y
+ *  0x107  connectionStatisticsReq         Y        Y
+ *  0x108  softKeyTemplateRes              Y        Y
+ *  0x109  softKeySetRes                   Y        Y
+ *  0x110  selectSoftKeys                  Y        Y
+ *  0x111  callState                       Y        Y
+ *  0x112  displayPromptStatus             Y        Y
+ *  0x113  clearPromptStatus               Y        Y
+ *  0x114  displayNotify                   Y        Y
+ *  0x115  clearNotify                     Y        Y
+ *  0x116  activateCallPlane               Y        Y
+ *  0x117  deactivateCallPlane             Y        N/A
+ *  0x118  unregisterAck                   Y        Y
+ *  0x119  backSpaceReq                    Y        Y
+ *  0x11A  registerTokenAck                Y        N
+ *  0x11B  registerTokenReject             Y        N
+ *******************************
+ *  0x11D  unknownForwardMessage           NC       N
+ *******************************
+ *
+ *
+ */