3 * Dissector for the Skinny Client Control Protocol
4 * (The "D-Channel"-Protocol for Cisco Systems' IP-Phones)
5 * Copyright 2001, Joerg Mayer (email: see AUTHORS file)
7 * Paul E. Erkkila (pee@erkkila.org) - fleshed out the decode
8 * skeleton to report values for most message/message fields.
9 * Much help from Guy Harris on figuring out the ethereal api.
11 * This file is based on packet-aim.c, which is
12 * Copyright 2000, Ralf Hoelzer <ralf@well.com>
14 * $Id: packet-skinny.c,v 1.14 2002/03/20 23:32:54 guy Exp $
16 * Ethereal - Network traffic analyzer
17 * By Gerald Combs <gerald@ethereal.com>
18 * Copyright 1998 Gerald Combs
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 /* This implementation is based on a draft version of the 3.0
45 #include <epan/packet.h>
48 #include "packet-frame.h"
50 #define TCP_PORT_SKINNY 2000
52 #define SKINNY_SOFTKEY0 0x01
53 #define SKINNY_SOFTKEY1 0x02
54 #define SKINNY_SOFTKEY2 0x04
55 #define SKINNY_SOFTKEY3 0x08
56 #define SKINNY_SOFTKEY4 0x10
57 #define SKINNY_SOFTKEY5 0x20
58 #define SKINNY_SOFTKEY6 0x40
59 #define SKINNY_SOFTKEY7 0x80
60 #define SKINNY_SOFTKEY8 0x100
61 #define SKINNY_SOFTKEY9 0x200
62 #define SKINNY_SOFTKEY10 0x400
63 #define SKINNY_SOFTKEY11 0x800
64 #define SKINNY_SOFTKEY12 0x1000
65 #define SKINNY_SOFTKEY13 0x2000
66 #define SKINNY_SOFTKEY14 0x4000
67 #define SKINNY_SOFTKEY15 0x8000
69 /* KeyMap Show/No Show */
70 static const true_false_string softKeyMapValues = {
76 /* I will probably need this again when I change things
77 * to function pointers, but let me use the existing
78 * infrastructure for now
86 static const value_string message_id[] = {
88 /* Station -> Callmanager */
89 {0x0000, "KeepAliveMessage"},
90 {0x0001, "RegisterMessage"},
91 {0x0002, "IpPortMessage"},
92 {0x0003, "KeypadButtonMessage"},
93 {0x0004, "EnblocCallMessage"},
94 {0x0005, "StimulusMessage"},
95 {0x0006, "OffHookMessage"},
96 {0x0007, "OnHookMessage"},
97 {0x0008, "HookFlashMessage"},
98 {0x0009, "ForwardStatReqMessage"},
99 {0x000A, "SpeedDialStatReqMessage"},
100 {0x000B, "LineStatReqMessage"},
101 {0x000C, "ConfigStatReqMessage"},
102 {0x000D, "TimeDateReqMessage"},
103 {0x000E, "ButtonTemplateReqMessage"},
104 {0x000F, "VersionReqMessage"},
105 {0x0010, "CapabilitiesResMessage"},
106 {0x0011, "MediaPortListMessage"},
107 {0x0012, "ServerReqMessage"},
108 {0x0020, "AlarmMessage"},
109 {0x0021, "MulticastMediaReceptionAck"},
110 {0x0022, "OpenReceiveChannelAck"},
111 {0x0023, "ConnectionStatisticsRes"},
112 {0x0024, "OffHookWithCgpnMessage"},
113 {0x0025, "SoftKeySetReqMessage"},
114 {0x0026, "SoftKeyEventMessage"},
115 {0x0027, "UnregisterMessage"},
116 {0x0028, "SoftKeyTemplateReqMessage"},
117 {0x0029, "RegisterTokenReq"},
118 {0x002B, "unknownClientMessage1"},
119 {0x002D, "unknownClientMessage2"},
121 /* Callmanager -> Station */
122 /* 0x0000, 0x0003? */
123 {0x0081, "RegisterAckMessage"},
124 {0x0082, "StartToneMessage"},
125 {0x0083, "StopToneMessage"},
126 {0x0085, "SetRingerMessage"},
127 {0x0086, "SetLampMessage"},
128 {0x0087, "SetHkFDetectMessage"},
129 {0x0088, "SetSpeakerModeMessage"},
130 {0x0089, "SetMicroModeMessage"},
131 {0x008A, "StartMediaTransmission"},
132 {0x008B, "StopMediaTransmission"},
133 {0x008C, "StartMediaReception"},
134 {0x008D, "StopMediaReception"},
135 {0x008F, "CallInfoMessage"},
136 {0x0090, "ForwardStatMessage"},
137 {0x0091, "SpeedDialStatMessage"},
138 {0x0092, "LineStatMessage"},
139 {0x0093, "ConfigStatMessage"},
140 {0x0094, "DefineTimeDate"},
141 {0x0095, "StartSessionTransmission"},
142 {0x0096, "StopSessionTransmission"},
143 {0x0097, "ButtonTemplateMessage"},
144 {0x0098, "VersionMessage"},
145 {0x0099, "DisplayTextMessage"},
146 {0x009A, "ClearDisplay"},
147 {0x009B, "CapabilitiesReqMessage"},
148 {0x009C, "EnunciatorCommandMessage"},
149 {0x009D, "RegisterRejectMessage"},
150 {0x009E, "ServerResMessage"},
152 {0x0100, "KeepAliveAckMessage"},
153 {0x0101, "StartMulticastMediaReception"},
154 {0x0102, "StartMulticastMediaTransmission"},
155 {0x0103, "StopMulticastMediaReception"},
156 {0x0104, "StopMulticastMediaTransmission"},
157 {0x0105, "OpenReceiveChannel"},
158 {0x0106, "CloseReceiveChannel"},
159 {0x0107, "ConnectionStatisticsReq"},
160 {0x0108, "SoftKeyTemplateResMessage"},
161 {0x0109, "SoftKeySetResMessage"},
162 {0x0110, "SelectSoftKeysMessage"},
163 {0x0111, "CallStateMessage"},
164 {0x0112, "DisplayPromptStatusMessage"},
165 {0x0113, "ClearPromptStatusMessage"},
166 {0x0114, "DisplayNotifyMessage"},
167 {0x0115, "ClearNotifyMessage"},
168 {0x0116, "ActivateCallPlaneMessage"},
169 {0x0117, "DeactivateCallPlaneMessage"},
170 {0x0118, "UnregisterAckMessage"},
171 {0x0119, "BackSpaceReqMessage"},
172 {0x011A, "RegisterTokenAck"},
173 {0x011B, "RegisterTokenReject"},
174 {0x011D, "unknownForwardMessage1"},
176 {0 , NULL} /* terminator */
180 * Device type to text conversion table
182 static const value_string deviceTypes[] = {
189 {7 , "TelecasterMgr"},
190 {8 , "TelecasterBus"},
191 {20 , "Virtual30SPplus"},
192 {21 , "PhoneApplication"},
193 {30 , "AnalogAccess"},
194 {40 , "DigitalAccessPRI"},
195 {41 , "DigitalAccessT1"},
196 {42 , "DigitalAccessTitan2"},
197 {47 , "AnalogAccessElvis"},
198 {49 , "DigitalAccessLennon"},
199 {50 , "ConferenceBridge"},
200 {51 , "ConferenceBridgeYoko"},
204 {70 , "MusicOnHold"},
207 {73 , "TapiRoutePoint"},
209 {81 , "VoiceInboxAdmin"},
210 {82 , "LineAnnunciator"},
212 {100, "LoadSimulator"},
213 {110, "MediaTerminationPoint"},
214 {111, "MediaTerminationPointYoko"},
215 {120, "MGCPStation"},
223 * keypad button -> text conversion
225 static const value_string keypadButtons[] = {
245 static const value_string deviceStimuli[] = {
246 {1 , "LastNumberRedial"},
252 {7 , "ForwardNoAnswer"},
256 {0xb , "T120Whiteboard"},
257 {0xc , "T120ApplicationSharing"},
258 {0xd , "T120FileTransfer"},
261 {0x11 , "AutoAnswer"},
262 {0x21 , "GenericAppB1"},
263 {0x22 , "GenericAppB2"},
264 {0x23 , "GenericAppB3"},
265 {0x24 , "GenericAppB4"},
266 {0x25 , "GenericAppB5"},
267 {0x7b , "MeetMeConference"},
268 {0x7d , "Conference=0x7d"},
269 {0x7e , "CallPark=0x7e"},
270 {0x7f , "CallPickup"},
271 {0x80 , "GroupCallPickup=80"},
276 /* Note i'm only using 7 later on cuz i'm lazy ;) */
277 #define DeviceMaxCapabilities 18 /* max capabilities allowed in Cap response message */
279 static const value_string mediaPayloads[] = {
292 {13 , "Is11172AudioCap"},
293 {14 , "Is13818AudioCap"},
295 {16 , "G729AnnexAwAnnexB"},
299 {81 , "ActiveVoice"},
304 {86 , "G729_B_LOW_COMPLEXITY"},
308 static const value_string alarmSeverities[] = {
311 {2 , "Informational"},
320 static const value_string multicastMediaReceptionStatus[] = {
326 static const value_string openReceiveChanStatus[] = {
333 static const value_string statsProcessingTypes[] = {
335 {1 , "doNotClearStats"},
339 #define SkMaxSoftKeyCount 18 /* this value should be the same as the max soft key value */
340 static const value_string softKeyEvents[] = {
347 {7 , "CFwdNoAnswer"},
356 {16 , "MeetMeConfrn"},
358 {18 , "GrpCallPickUp"},
362 /* Define info index for each softkey event for Telecaster station. */
363 static const value_string softKeyIndexes[] = {
364 {301 , "RedialInfoIndex"},
365 {302 , "NewCallInfoIndex"},
366 {303 , "HoldInfoIndex"},
367 {304 , "TrnsferInfoIndex"},
368 {305 , "CFwdAllInfoIndex"},
369 {306 , "CFwdBusyInfoIndex"}, /* not used yet */
370 {307 , "CFwdNoAnswerInfoIndex"}, /* not used yet */
371 {308 , "BackSpaceInfoIndex"},
372 {309 , "EndCallInfoIndex"},
373 {310 , "ResumeInfoIndex"},
374 {311 , "AnswerInfoIndex"},
375 {312 , "InfoInfoIndex"},
376 {313 , "ConfrnInfoIndex"},
377 {314 , "ParkInfoIndex"},
378 {315 , "JoinInfoIndex"},
379 {316 , "MeetMeConfrnInfoIndex"},
380 {317 , "CallPickUpInfoIndex"},
381 {318 , "GrpCallPickUpInfoIndex"},
386 static const value_string buttonDefinitions[] = {
387 {1 , "LastNumberRedial"},
393 {7 , "ForwardNoAnswer"},
397 {0xb , "T120Whiteboard"},
398 {0xc , "T120ApplicationSharing"},
399 {0xd , "T120FileTransfer"},
401 {0x10 , "AnswerRelease"},
404 {0xff , "Undefined"},
408 #define StationTotalSoftKeySets 10 /* total number of the soft key sets */
409 static const value_string keySetNames[] = {
415 {5 , "Connected with transfer"},
416 {6 , "Digits after dialing first digit"},
417 {7 , "Connected with conference"},
419 {9 , "OffHook with features"},
423 /* Define soft key labels for the Telecaster station */
424 static const value_string softKeyLabel[] = {
432 {7 , "CFwdNoAnswer"},
450 * lamp cadence is defined as follows
451 * Wink (on 80%) = 448msec on / 64msec off
452 * Flash (fast flash) = 32msec on / 32msec off
453 * Blink (on 50%) = 512msec on / 512msec off
456 static const value_string stationLampModes[] = {
466 /* Defined the Call States to be sent to the Telecaste station.
467 * These are NOT the call states used in CM internally. Instead,
468 * they are the call states sent from CM and understood by the Telecaster station
470 static const value_string skinny_stationCallStates[] = {
480 {10 , "CallTransfer"},
483 {13 , "CallRemoteMultiline"},
484 {14 , "InvalidNumber"},
488 /* Defined Call Type */
489 static const value_string skinny_callTypes[] = {
490 {1 , "TsInBoundCall"},
491 {2 , "TsOutBoundCall"},
492 {3 , "TsForwardCall"},
497 * define station-playable tones;
498 * for tone definitions see SR-TSV-002275, "BOC Notes on the LEC Networks -- 1994"
500 static const value_string skinny_deviceTones[] = {
512 {0xe , "DtDtmfStar"},
513 {0xf , "DtDtmfPound"},
518 {0x21 , "DtInsideDialTone"},
519 {0x22 , "DtOutsideDialTone"},
520 {0x23 , "DtLineBusyTone"},
521 {0x24 , "DtAlertingTone"},
522 {0x25 , "DtReorderTone"},
523 {0x26 , "DtRecorderWarningTone"},
524 {0x27 , "DtRecorderDetectedTone"},
525 {0x28 , "DtRevertingTone"},
526 {0x29 , "DtReceiverOffHookTone"},
527 {0x2a , "DtPartialDialTone"},
528 {0x2b , "DtNoSuchNumberTone"},
529 {0x2c , "DtBusyVerificationTone"},
530 {0x2d , "DtCallWaitingTone"},
531 {0x2e , "DtConfirmationTone"},
532 {0x2f , "DtCampOnIndicationTone"},
533 {0x30 , "DtRecallDialTone"},
536 {0x33 , "DtBeepBonk"},
537 {0x34 , "DtMusicTone"},
538 {0x35 , "DtHoldTone"},
539 {0x36 , "DtTestTone"},
540 {0x40 , "Dt_AddCallWaiting"},
541 {0x41 , "Dt_PriorityCallWait"},
542 {0x42 , "Dt_RecallDial"},
543 {0x43 , "Dt_BargIn"},
544 {0x44 , "Dt_DistinctAlert"},
545 {0x45 , "Dt_PriorityAlert"},
546 {0x46 , "Dt_ReminderRing"},
561 {0x5e , "Dt_MFST3P"},
562 {0x5f , "Dt_MILLIWATT"},
563 {0x60 , "Dt_MILLIWATTTEST"},
564 {0x61 , "Dt_HIGHTONE"},
565 {0x62 , "Dt_FLASHOVERRIDE"},
567 {0x64 , "Dt_PRIORITY"},
568 {0x65 , "Dt_IMMEDIATE"},
569 {0x66 , "Dt_PREAMPWARN"},
570 {0x67 , "Dt_2105HZ"},
571 {0x68 , "Dt_2600HZ"},
574 {0x7f , "Dt_NoTone"},
578 /* define ring types */
579 static const value_string skinny_ringTypes[] = {
580 {0x1 , "StationRingOff"},
581 {0x2 , "StationInsideRing"},
582 {0x3 , "StationOutsideRing"},
583 {0x4 , "StationFeatureRing"},
587 static const value_string skinny_speakerModes[] = {
588 {1 , "StationSpeakerOn"},
589 {2 , "StationSpeakerOff"},
593 static const value_string skinny_silenceSuppressionModes[] = {
594 {0 , "Media_SilenceSuppression_Off"},
595 {1 , "Media_SilenceSuppression_On"},
599 static const value_string skinny_g723BitRates[] = {
600 {1 , "Media_G723BRate_5_3"},
601 {2 , "Media_G723BRate_6_4"},
605 /* define device reset types */
606 static const value_string skinny_deviceResetTypes[] = {
607 {1 , "DEVICE_RESET"},
608 {2 , "DEVICE_RESTART"},
612 static const value_string skinny_echoCancelTypes[] = {
613 {0 , "Media_EchoCancellation_Off"},
614 {1 , "Media_EchoCancellation_On"},
618 static const value_string skinny_deviceUnregisterStatusTypes[] = {
619 {0 , "UnregisterOk"},
620 {1 , "UnregisterError"},
621 {2 , "UnregisterNAK"}, /* Unregister request is rejected for reaso n such as existence of a call */
625 /* define hook flash detection mode */
626 static const value_string skinny_hookFlashDetectModes[] = {
627 {1 , "StationHookFlashOn"},
628 {2 , "StationHookFlashOff"},
632 /* define station microphone modes;
633 * Mic On - The speakerphone's microphone is turned on ONLY if the phone is in the "Speaker On (Off Hook)"
635 * Mic Off - The microphone is turned off or, if it's not on, the command is ignored.
637 static const value_string skinny_microphoneModes[] = {
638 {1 , "StationMicOn"},
639 {2 , "StationMicOff"},
643 /* define the session request types */
644 static const value_string skinny_sessionTypes[] = {
647 {4 , "ApplicationSharing"},
648 {8 , "FileTransfer"},
653 static const value_string skinny_mediaEnunciationTypes[] = {
659 #define StationMaxDirnumSize 24 /* max size of calling or called party dirnum */
660 #define StationMaxNameSize 40 /* max size of calling party's name */
661 #define StationMaxDeviceNameSize 16 /* max size of station's IP name */
662 #define StationMaxSpeedDials 10 /* max number of speed dial numbers allowed on a station */
663 #define StationMaxVersionSize 16 /* max chars in version string */
664 #define StationMaxButtonTemplateSize 42 /* max button template size */
665 #define StationMaxDisplayTextSize 33 /* max text size in DisplayText message */
666 #define StationMaxPorts 10 /* max number of ports on one device */
667 #define StationDateTemplateSize 6 /* date template in the form M/D/Y, D/M/Y, ... */
668 #define StationMaxServerNameSize 48 /* max size of server name */
669 #define StationMaxServers 5 /* max servers */
670 #define StationMaxDeviceDirnums 1024 /* max dir numbers per SCM device */
671 #define StationMaxDirnums 64 /* max dir numbers per physical station (also used in db request msg); */
672 #define StationMaxSoftKeyLabelSize 16 /* max label size in the message */
673 #define StationMaxSoftKeyDefinition 32 /* max number of soft key definition in the message */
674 #define StationMaxSoftKeySetDefinition 16 /* max number of soft key set definition in the message */
675 #define StationMaxSoftKeyIndex 16 /* max number of soft key indices in a station soft key set */
676 #define StationMaxDisplayPromptStatusSize 32 /* max status text size in the display status message */
677 #define StationMaxDisplayNotifySize 32 /* max prompt text size in the display prompt message */
679 static void dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
681 /* Initialize the protocol and registered fields */
682 static int proto_skinny = -1;
683 static int hf_skinny_data_length = -1;
684 static int hf_skinny_reserved = -1;
685 static int hf_skinny_messageid = -1;
686 static int hf_skinny_deviceName = -1;
687 static int hf_skinny_stationUserId = -1;
688 static int hf_skinny_stationInstance = -1;
689 static int hf_skinny_deviceType = -1;
690 static int hf_skinny_maxStreams = -1;
691 static int hf_skinny_stationIpPort = -1;
692 static int hf_skinny_stationKeypadButton = -1;
693 static int hf_skinny_calledParty = -1;
694 static int hf_skinny_stimulus = -1;
695 static int hf_skinny_stimulusInstance = -1;
696 static int hf_skinny_lineNumber = -1;
697 static int hf_skinny_speedDialNumber = -1;
698 static int hf_skinny_capCount = -1;
699 static int hf_skinny_payloadCapability = -1;
700 static int hf_skinny_maxFramesPerPacket = -1;
701 static int hf_skinny_alarmSeverity = -1;
702 static int hf_skinny_alarmParam1 = -1;
703 static int hf_skinny_alarmParam2 = -1;
704 static int hf_skinny_receptionStatus = -1;
705 static int hf_skinny_passThruPartyID = -1;
706 static int hf_skinny_ORCStatus = -1;
707 static int hf_skinny_ipAddress = -1;
708 static int hf_skinny_portNumber = -1;
709 static int hf_skinny_statsProcessingType = -1;
710 static int hf_skinny_callIdentifier = -1;
711 static int hf_skinny_packetsSent = -1;
712 static int hf_skinny_octetsSent = -1;
713 static int hf_skinny_packetsRecv = -1;
714 static int hf_skinny_octetsRecv = -1;
715 static int hf_skinny_packetsLost = -1;
716 static int hf_skinny_latency = -1;
717 static int hf_skinny_jitter = -1;
718 static int hf_skinny_directoryNumber = -1;
719 static int hf_skinny_softKeyEvent = -1;
720 static int hf_skinny_lineInstance = -1;
721 static int hf_skinny_keepAliveInterval = -1;
722 static int hf_skinny_dateTemplate = -1;
723 static int hf_skinny_secondaryKeepAliveInterval = -1;
724 static int hf_skinny_buttonOffset = -1;
725 static int hf_skinny_buttonCount = -1;
726 static int hf_skinny_totalButtonCount = -1;
727 static int hf_skinny_buttonInstanceNumber = -1;
728 static int hf_skinny_buttonDefinition = -1;
729 static int hf_skinny_softKeyOffset = -1;
730 static int hf_skinny_softKeyCount = -1;
731 static int hf_skinny_totalSoftKeyCount = -1;
732 static int hf_skinny_softKeyLabel = -1;
733 static int hf_skinny_softKeySetOffset = -1;
734 static int hf_skinny_softKeySetCount = -1;
735 static int hf_skinny_totalSoftKeySetCount = -1;
736 static int hf_skinny_softKeyTemplateIndex = -1;
737 static int hf_skinny_softKeyInfoIndex = -1;
738 static int hf_skinny_softKeySetDescription = -1;
739 static int hf_skinny_softKeyMap = -1;
740 static int hf_skinny_softKey0 = -1;
741 static int hf_skinny_softKey1 = -1;
742 static int hf_skinny_softKey2 = -1;
743 static int hf_skinny_softKey3 = -1;
744 static int hf_skinny_softKey4 = -1;
745 static int hf_skinny_softKey5 = -1;
746 static int hf_skinny_softKey6 = -1;
747 static int hf_skinny_softKey7 = -1;
748 static int hf_skinny_softKey8 = -1;
749 static int hf_skinny_softKey9 = -1;
750 static int hf_skinny_softKey10 = -1;
751 static int hf_skinny_softKey11 = -1;
752 static int hf_skinny_softKey12 = -1;
753 static int hf_skinny_softKey13 = -1;
754 static int hf_skinny_softKey14 = -1;
755 static int hf_skinny_softKey15 = -1;
756 static int hf_skinny_lampMode = -1;
757 static int hf_skinny_messageTimeOutValue = -1;
758 static int hf_skinny_displayMessage = -1;
759 static int hf_skinny_lineDirNumber = -1;
760 static int hf_skinny_lineFullyQualifiedDisplayName = -1;
761 static int hf_skinny_speedDialDirNumber = -1;
762 static int hf_skinny_speedDialDisplayName = -1;
763 static int hf_skinny_dateYear = -1;
764 static int hf_skinny_dateMonth = -1;
765 static int hf_skinny_dayOfWeek = -1;
766 static int hf_skinny_dateDay = -1;
767 static int hf_skinny_dateHour = -1;
768 static int hf_skinny_dateMinute = -1;
769 static int hf_skinny_dateSeconds = -1;
770 static int hf_skinny_dateMilliseconds = -1;
771 static int hf_skinny_timeStamp = -1;
772 static int hf_skinny_callState = -1;
773 static int hf_skinny_deviceTone = -1;
774 static int hf_skinny_callingPartyName = -1;
775 static int hf_skinny_callingParty = -1;
776 static int hf_skinny_calledPartyName = -1;
777 static int hf_skinny_callType = -1;
778 static int hf_skinny_originalCalledPartyName = -1;
779 static int hf_skinny_originalCalledParty = -1;
780 static int hf_skinny_ringType = -1;
781 static int hf_skinny_speakerMode = -1;
782 static int hf_skinny_remoteIpAddr = -1;
783 static int hf_skinny_remotePortNumber = -1;
784 static int hf_skinny_millisecondPacketSize = -1;
785 static int hf_skinny_precedenceValue = -1;
786 static int hf_skinny_silenceSuppression = -1;
787 static int hf_skinny_g723BitRate = -1;
788 static int hf_skinny_conferenceID = -1;
789 static int hf_skinny_deviceResetType = -1;
790 static int hf_skinny_echoCancelType = -1;
791 static int hf_skinny_deviceUnregisterStatus = -1;
792 static int hf_skinny_hookFlashDetectMode = -1;
793 static int hf_skinny_detectInterval = -1;
794 static int hf_skinny_microphoneMode = -1;
795 static int hf_skinny_unknown = -1;
796 static int hf_skinny_activeForward = -1;
797 static int hf_skinny_forwardAllActive = -1;
798 static int hf_skinny_forwardBusyActive = -1;
799 static int hf_skinny_forwardNoAnswerActive = -1;
800 static int hf_skinny_forwardNumber = -1;
801 static int hf_skinny_serverName = -1;
802 static int hf_skinny_numberLines = -1;
803 static int hf_skinny_numberSpeedDials = -1;
804 static int hf_skinny_userName = -1;
805 static int hf_skinny_sessionType = -1;
806 static int hf_skinny_version = -1;
807 static int hf_skinny_mediaEnunciationType = -1;
808 static int hf_skinny_serverIdentifier = -1;
809 static int hf_skinny_serverListenPort = -1;
810 static int hf_skinny_serverIpAddress = -1;
811 static int hf_skinny_multicastIpAddress = -1;
812 static int hf_skinny_multicastPort = -1;
813 static int hf_skinny_tokenRejWaitTime = -1;
817 /* Initialize the subtree pointers */
818 static gint ett_skinny = -1;
819 static gint ett_skinny_softKeyMap = -1;
821 /* desegmentation of SCCP */
822 static gboolean skinny_desegment = TRUE;
824 static dissector_handle_t data_handle;
826 /* Dissect a single SCCP PDU */
827 static void dissect_skinny_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
832 guint32 hdr_data_length;
833 guint32 hdr_reserved;
834 guint32 data_messageid;
835 gchar *messageid_str;
836 /* guint32 data_size; */
838 guint32 unknownLong = 0;
844 guint32 softKeyCount;
845 guint32 softKeySetCount;
846 guint16 validKeyMask;
848 /* Set up structures we will need to add the protocol subtree and manage it */
850 proto_tree *skinny_tree = NULL;
852 proto_item *skm = NULL;
853 proto_item *skm_tree = NULL;
855 hdr_data_length = tvb_get_letohl(tvb, offset);
856 hdr_reserved = tvb_get_letohl(tvb, offset+4);
857 data_messageid = tvb_get_letohl(tvb, offset+8);
859 /* In the interest of speed, if "tree" is NULL, don't do any work not
860 * necessary to generate protocol tree items. */
862 ti = proto_tree_add_item(tree, proto_skinny, tvb, offset, hdr_data_length+8, FALSE);
863 skinny_tree = proto_item_add_subtree(ti, ett_skinny);
864 proto_tree_add_uint(skinny_tree, hf_skinny_data_length, tvb, offset, 4, hdr_data_length);
865 proto_tree_add_uint(skinny_tree, hf_skinny_reserved, tvb, offset+4, 4, hdr_reserved);
868 messageid_str = val_to_str(data_messageid, message_id, "0x%08X (Unknown)");
870 if (check_col(pinfo->cinfo, COL_INFO)) {
871 col_add_str(pinfo->cinfo, COL_INFO, messageid_str);
875 proto_tree_add_uint(skinny_tree, hf_skinny_messageid, tvb,offset+8, 4, data_messageid );
879 switch(data_messageid) {
881 /* cases that do not need to be decoded */
882 case 0x0 : /* keepAlive */
885 case 0x6 : /* offHook */
888 case 0x7 : /* onHook */
891 case 0x8 : /* hookFlash */
894 case 0xc : /* configStateReqMessage */
897 case 0xd : /* timeDateReqMessage */
900 case 0xe : /* buttoneTemplateReqMessage */
903 case 0xf : /* stationVersionReqMessage */
906 case 0x12 : /* stationServerReqMessage */
909 case 0x25 : /* softKeySetReqMessage */
912 case 0x27 : /* unregisterMessage */
915 case 0x28 : /* softKeyTemplateRequest */
918 case 0x83 : /* stopTone */
921 case 0x9a : /* clearDisplay */
924 case 0x9b : /* capabilitiesReqMessage */
927 case 0x100 : /* keepAliveAck */
930 case 0x117 : /* deactivateCallPlane */
933 case 0x11a : /* registerTokenAck */
937 ** cases that need decode
941 case 0x1 : /* register message */
942 proto_tree_add_item(skinny_tree, hf_skinny_deviceName, tvb, offset+12, StationMaxDeviceNameSize, TRUE);
943 proto_tree_add_item(skinny_tree, hf_skinny_stationUserId, tvb, offset+28, 4, TRUE);
944 proto_tree_add_item(skinny_tree, hf_skinny_stationInstance, tvb, offset+32, 4, TRUE);
945 proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+36, 4, TRUE);
946 proto_tree_add_item(skinny_tree, hf_skinny_deviceType, tvb, offset+40, 4, TRUE);
947 proto_tree_add_item(skinny_tree, hf_skinny_maxStreams, tvb, offset+44, 4, TRUE);
950 case 0x2 : /* ipPortMessage */
951 proto_tree_add_item(skinny_tree, hf_skinny_stationIpPort, tvb, offset+12, 2, FALSE);
954 case 0x3 : /* keyPadButtonMessage */
955 proto_tree_add_item(skinny_tree, hf_skinny_stationKeypadButton, tvb, offset+12, 4, TRUE);
958 case 0x4 : /* stationEnblocCallMessage -- This decode NOT verified*/
959 proto_tree_add_item(skinny_tree, hf_skinny_calledParty, tvb, offset+12, StationMaxDirnumSize, TRUE);
962 case 0x5 : /* stationStimulusMessage */
963 proto_tree_add_item(skinny_tree, hf_skinny_stimulus, tvb, offset+12, 4, TRUE);
964 proto_tree_add_item(skinny_tree, hf_skinny_stimulusInstance, tvb, offset+16, 4, TRUE);
967 case 0x9 : /* stationForwardStatReqMessage */
968 proto_tree_add_item(skinny_tree, hf_skinny_lineNumber, tvb, offset+12, 4, TRUE);
971 case 0xa : /* speedDialStatReqMessage */
972 proto_tree_add_item(skinny_tree, hf_skinny_speedDialNumber, tvb, offset+12, 4, TRUE);
975 case 0xb : /* LineStatReqMessage */
976 proto_tree_add_item(skinny_tree, hf_skinny_lineNumber, tvb, offset+12, 4, TRUE);
979 case 0x10 : /* capabilitiesResMessage - VERIFIED AS IS*/
980 /* FIXME -- we are only going to decode the first 7 protocol fields for now cuz that's all it sent me
981 * on the phone i was working with. I should probably skip the struct decode and use a more piece
982 * type method using the capCount definition to control the decode loop
984 * basically changing StationMaxCapabilities definition
987 capCount = tvb_get_letohl(tvb, offset+12);
988 proto_tree_add_uint(skinny_tree, hf_skinny_capCount, tvb, offset+12, 4, capCount);
989 for (i = 0; i < capCount; i++) {
990 proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+(i*16)+16, 4, TRUE);
991 proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket, tvb, offset+(i*16)+20, 2, TRUE);
992 /* FIXME -- decode the union under here as required, is always 0 on my equipment */
996 case 0x11 : /* mediaPortList */
999 case 0x20 : /* stationAlarmMessage */
1000 proto_tree_add_item(skinny_tree, hf_skinny_alarmSeverity, tvb, offset+12, 4, TRUE);
1001 proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, 80, TRUE);
1002 proto_tree_add_item(skinny_tree, hf_skinny_alarmParam1, tvb, offset+96, 4, TRUE);
1003 proto_tree_add_item(skinny_tree, hf_skinny_alarmParam2, tvb, offset+100, 4, TRUE);
1006 case 0x21 : /* stationMulticastMediaReceptionAck - This decode NOT verified*/
1007 proto_tree_add_item(skinny_tree, hf_skinny_receptionStatus, tvb, offset+12, 4, TRUE);
1008 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1011 case 0x22 : /* stationOpenReceiveChannelAck */
1012 proto_tree_add_item(skinny_tree, hf_skinny_ORCStatus, tvb, offset+12, 4, TRUE);
1013 proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, offset+16, 4, TRUE);
1014 proto_tree_add_item(skinny_tree, hf_skinny_portNumber, tvb, offset+20, 4, TRUE);
1015 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+24, 4, TRUE);
1018 case 0x23 : /* stationConnectionStatisticsRes */
1019 proto_tree_add_item(skinny_tree, hf_skinny_directoryNumber, tvb, offset+12, StationMaxDirnumSize, TRUE);
1020 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+36, 4, TRUE);
1021 proto_tree_add_item(skinny_tree, hf_skinny_statsProcessingType, tvb, offset+40, 4, TRUE);
1022 proto_tree_add_item(skinny_tree, hf_skinny_packetsSent, tvb, offset+44, 4, TRUE);
1023 proto_tree_add_item(skinny_tree, hf_skinny_octetsSent, tvb, offset+48, 4, TRUE);
1024 proto_tree_add_item(skinny_tree, hf_skinny_packetsRecv, tvb, offset+52, 4, TRUE);
1025 proto_tree_add_item(skinny_tree, hf_skinny_octetsRecv, tvb, offset+56, 4, TRUE);
1026 proto_tree_add_item(skinny_tree, hf_skinny_packetsLost, tvb, offset+60, 4, TRUE);
1027 proto_tree_add_item(skinny_tree, hf_skinny_jitter, tvb, offset+64, 4, TRUE);
1028 proto_tree_add_item(skinny_tree, hf_skinny_latency, tvb, offset+68, 4, TRUE);
1031 case 0x24 : /* offHookWithCgpn */
1032 proto_tree_add_item(skinny_tree, hf_skinny_calledParty, tvb, offset+12,StationMaxDirnumSize, TRUE);
1035 case 0x26 : /* softKeyEventMessage */
1036 proto_tree_add_item(skinny_tree, hf_skinny_softKeyEvent, tvb, offset+12, 4, TRUE);
1037 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+16, 4, TRUE);
1038 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
1041 case 0x29 : /* registerTokenREq */
1042 proto_tree_add_item(skinny_tree, hf_skinny_deviceName, tvb, offset+12, 4, TRUE);
1043 i = offset+12+StationMaxDeviceNameSize;
1044 proto_tree_add_item(skinny_tree, hf_skinny_stationUserId, tvb, i, 4, TRUE);
1045 proto_tree_add_item(skinny_tree, hf_skinny_stationInstance, tvb, i+4, 4, TRUE);
1046 proto_tree_add_item(skinny_tree, hf_skinny_ipAddress, tvb, i+8, 4, TRUE);
1047 proto_tree_add_item(skinny_tree, hf_skinny_deviceType, tvb, i+12, 4, TRUE);
1052 * message not in the spec
1055 case 0x2b : /* unknownClientMessage1 */
1058 case 0x2d : /* unknownClientMessage2 */
1063 * Call manager -> client messages start here(ish)
1066 case 0x81 : /* registerAck */
1067 proto_tree_add_item(skinny_tree, hf_skinny_keepAliveInterval, tvb, offset+12, 4, TRUE);
1068 proto_tree_add_item(skinny_tree, hf_skinny_dateTemplate, tvb, offset+16, StationDateTemplateSize, TRUE);
1069 proto_tree_add_item(skinny_tree, hf_skinny_secondaryKeepAliveInterval, tvb, offset+24, 4, TRUE);
1072 case 0x82 : /* startTone */
1073 proto_tree_add_item(skinny_tree, hf_skinny_deviceTone, tvb, offset+12, 4, TRUE);
1076 case 0x85 : /* setRingerMessage */
1077 proto_tree_add_item(skinny_tree, hf_skinny_ringType, tvb, offset+12, 4, TRUE);
1080 case 0x86 : /* setLampMessage */
1081 proto_tree_add_item(skinny_tree, hf_skinny_stimulus, tvb, offset+12, 4, TRUE);
1082 proto_tree_add_item(skinny_tree, hf_skinny_stimulusInstance, tvb, offset+16, 4, TRUE);
1083 proto_tree_add_item(skinny_tree, hf_skinny_lampMode, tvb, offset+20, 4, TRUE);
1086 case 0x87 : /* stationHookFlashDetectMode */
1087 proto_tree_add_item(skinny_tree, hf_skinny_hookFlashDetectMode, tvb, offset+12, 4, TRUE);
1088 proto_tree_add_item(skinny_tree, hf_skinny_detectInterval, tvb, offset+16, 4, TRUE);
1091 case 0x88 : /* setSpeakerMode */
1093 proto_tree_add_item(skinny_tree, hf_skinny_speakerMode, tvb, offset+12, 4, TRUE);
1096 case 0x89 : /* setMicroMode */
1097 proto_tree_add_item(skinny_tree, hf_skinny_microphoneMode, tvb, offset+12, 4, TRUE);
1100 case 0x8a : /* startMediaTransmistion */
1101 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1102 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1103 proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr, tvb, offset+20, 4, TRUE);
1104 proto_tree_add_item(skinny_tree, hf_skinny_remotePortNumber, tvb, offset+24, 4, TRUE);
1105 proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+28, 4, TRUE);
1106 proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+32, 4, TRUE);
1107 proto_tree_add_item(skinny_tree, hf_skinny_precedenceValue, tvb, offset+36, 4, TRUE);
1108 proto_tree_add_item(skinny_tree, hf_skinny_silenceSuppression, tvb, offset+40, 4, TRUE);
1109 proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket, tvb, offset+44, 2, TRUE);
1110 proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+48, 4, TRUE);
1113 case 0x8b : /* stopMediaTransmission */
1115 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1116 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1119 case 0x8c : /* startMediaReception */
1122 case 0x8d : /* stopMediaReception */
1125 case 0x8e : /* reservered */
1128 case 0x8f : /* callInfo */
1130 proto_tree_add_item(skinny_tree, hf_skinny_callingPartyName, tvb, i, StationMaxNameSize, TRUE);
1131 i += StationMaxNameSize;
1132 proto_tree_add_item(skinny_tree, hf_skinny_callingParty, tvb, i, StationMaxDirnumSize, TRUE);
1133 i += StationMaxDirnumSize;
1134 proto_tree_add_item(skinny_tree, hf_skinny_calledPartyName, tvb, i, StationMaxNameSize, TRUE);
1135 i += StationMaxNameSize;
1136 proto_tree_add_item(skinny_tree, hf_skinny_calledParty, tvb, i, StationMaxDirnumSize, TRUE);
1137 i += StationMaxDirnumSize;
1138 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, i, 4, TRUE);
1140 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, i, 4, TRUE);
1142 proto_tree_add_item(skinny_tree, hf_skinny_callType, tvb, i, 4, TRUE);
1144 proto_tree_add_item(skinny_tree, hf_skinny_originalCalledPartyName, tvb, i, StationMaxNameSize, TRUE);
1145 i += StationMaxNameSize;
1146 proto_tree_add_item(skinny_tree, hf_skinny_originalCalledParty, tvb, i, StationMaxDirnumSize, TRUE);
1149 case 0x90 : /* forwardStat */
1150 proto_tree_add_item(skinny_tree, hf_skinny_activeForward, tvb, offset+12, 4, TRUE);
1151 proto_tree_add_item(skinny_tree, hf_skinny_lineNumber, tvb, offset+16, 4, TRUE);
1152 proto_tree_add_item(skinny_tree, hf_skinny_forwardAllActive, tvb, offset+20, 4, TRUE);
1153 proto_tree_add_item(skinny_tree, hf_skinny_forwardNumber, tvb, offset+24, StationMaxDirnumSize, TRUE);
1154 i = offset+24+StationMaxDirnumSize;
1155 proto_tree_add_item(skinny_tree, hf_skinny_forwardBusyActive, tvb, i, 4, TRUE);
1157 proto_tree_add_item(skinny_tree, hf_skinny_forwardNumber, tvb, i, StationMaxDirnumSize, TRUE);
1158 i += StationMaxDirnumSize;
1159 proto_tree_add_item(skinny_tree, hf_skinny_forwardNoAnswerActive, tvb, i, 4, TRUE);
1161 proto_tree_add_item(skinny_tree, hf_skinny_forwardNumber, tvb, i, StationMaxDirnumSize, TRUE);
1164 case 0x91 : /* speedDialStatMessage */
1165 proto_tree_add_item(skinny_tree, hf_skinny_speedDialNumber, tvb, offset+12, 4, TRUE);
1166 proto_tree_add_item(skinny_tree, hf_skinny_speedDialDirNumber, tvb, offset+16, StationMaxDirnumSize, TRUE);
1167 proto_tree_add_item(skinny_tree, hf_skinny_speedDialDisplayName, tvb, offset+40, StationMaxNameSize, TRUE);
1170 case 0x92 : /* lineStatMessage */
1171 proto_tree_add_item(skinny_tree, hf_skinny_lineNumber, tvb, offset+12, 4, TRUE);
1172 proto_tree_add_item(skinny_tree, hf_skinny_lineDirNumber, tvb, offset+16, StationMaxDirnumSize, TRUE);
1173 proto_tree_add_item(skinny_tree, hf_skinny_lineFullyQualifiedDisplayName, tvb, offset+16+StationMaxDirnumSize, StationMaxNameSize, TRUE);
1176 case 0x93 : /* configStat */
1177 proto_tree_add_item(skinny_tree, hf_skinny_deviceName, tvb, offset+12, 4, TRUE);
1178 i = offset+12+StationMaxDeviceNameSize;
1179 proto_tree_add_item(skinny_tree, hf_skinny_stationUserId, tvb, i, 4, TRUE);
1181 proto_tree_add_item(skinny_tree, hf_skinny_stationInstance, tvb, i, 4, TRUE);
1183 proto_tree_add_item(skinny_tree, hf_skinny_userName, tvb, i, StationMaxNameSize, TRUE);
1184 i += StationMaxNameSize;
1185 proto_tree_add_item(skinny_tree, hf_skinny_serverName, tvb, i, StationMaxNameSize, TRUE);
1186 i += StationMaxNameSize;
1187 proto_tree_add_item(skinny_tree, hf_skinny_numberLines, tvb, i, 4, TRUE);
1188 proto_tree_add_item(skinny_tree, hf_skinny_numberSpeedDials, tvb, i+4, 4, TRUE);
1191 case 0x94 : /* stationDefineTimeDate */
1192 proto_tree_add_item(skinny_tree, hf_skinny_dateYear, tvb, offset+12, 4, TRUE);
1193 proto_tree_add_item(skinny_tree, hf_skinny_dateMonth, tvb, offset+16, 4, TRUE);
1194 proto_tree_add_item(skinny_tree, hf_skinny_dayOfWeek, tvb, offset+20, 4, TRUE);
1195 proto_tree_add_item(skinny_tree, hf_skinny_dateDay, tvb, offset+24, 4, TRUE);
1196 proto_tree_add_item(skinny_tree, hf_skinny_dateHour, tvb, offset+28, 4, TRUE);
1197 proto_tree_add_item(skinny_tree, hf_skinny_dateMinute, tvb, offset+32, 4, TRUE);
1198 proto_tree_add_item(skinny_tree, hf_skinny_dateSeconds,tvb, offset+36, 4, TRUE);
1199 proto_tree_add_item(skinny_tree, hf_skinny_dateMilliseconds,tvb, offset+40, 4, TRUE);
1200 proto_tree_add_item(skinny_tree, hf_skinny_timeStamp, tvb, offset+44, 4, TRUE);
1203 case 0x95 : /* startSessionTransmission */
1204 proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr, tvb, offset+12, 4, TRUE);
1205 proto_tree_add_item(skinny_tree, hf_skinny_sessionType, tvb, offset+16, 4, TRUE);
1208 case 0x96 : /* stopSessionTransmission */
1209 proto_tree_add_item(skinny_tree, hf_skinny_remoteIpAddr, tvb, offset+12, 4, TRUE);
1210 proto_tree_add_item(skinny_tree, hf_skinny_sessionType, tvb, offset+16, 4, TRUE);
1213 case 0x97 : /* buttonTemplateMessage */
1216 * This decode prints out oogly subtree maybe? or something besides the VALS...
1217 * note to self: uint8 != 4 kk thx info ^_^
1220 proto_tree_add_item(skinny_tree, hf_skinny_buttonOffset, tvb, offset+12, 4, TRUE);
1221 proto_tree_add_item(skinny_tree, hf_skinny_buttonCount, tvb, offset+16, 4, TRUE);
1222 proto_tree_add_item(skinny_tree, hf_skinny_totalButtonCount, tvb, offset+20, 4, TRUE);
1223 for (i = 0; i < StationMaxButtonTemplateSize; i++) {
1224 proto_tree_add_item(skinny_tree, hf_skinny_buttonInstanceNumber, tvb, offset+(i*2)+24, 1, TRUE);
1225 proto_tree_add_item(skinny_tree, hf_skinny_buttonDefinition, tvb, offset+(i*2)+25, 1, TRUE);
1229 case 0x98 : /* version */
1230 proto_tree_add_item(skinny_tree, hf_skinny_version, tvb, offset+12, StationMaxVersionSize, TRUE);
1233 case 0x99 : /* displayTextMessage */
1234 proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+12, StationMaxDisplayTextSize, TRUE);
1237 case 0x9c : /* enunciatorCommand */
1238 proto_tree_add_item(skinny_tree, hf_skinny_mediaEnunciationType, tvb, offset+12, 4, TRUE);
1239 for (i = 0; i < StationMaxDirnumSize; i++) {
1240 proto_tree_add_item(skinny_tree, hf_skinny_unknown, tvb, offset+16+(i*4), 4, TRUE);
1242 i = offset+16+StationMaxDirnumSize;
1243 proto_tree_add_item(skinny_tree, hf_skinny_mediaEnunciationType, tvb, i, 4, TRUE);
1246 case 0x9d : /* stationRegisterReject */
1247 proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+12, StationMaxDisplayTextSize, TRUE);
1250 case 0x9e : /* serverRes */
1251 for (i = 0; i < StationMaxServers; i++) {
1252 proto_tree_add_item(skinny_tree, hf_skinny_serverIdentifier, tvb, offset+12+(i*StationMaxServers), StationMaxServers, TRUE);
1254 j = offset+12+(i*StationMaxServers);
1255 for (i = 0; i < StationMaxServers; i++) {
1256 proto_tree_add_item(skinny_tree, hf_skinny_serverListenPort, tvb, j+(i*4), 4, TRUE);
1259 for (i = 0; i < StationMaxServers; i++) {
1260 proto_tree_add_item(skinny_tree, hf_skinny_serverIpAddress, tvb, j+(i*4), 4, TRUE);
1264 case 0x9f : /* reset */
1265 proto_tree_add_item(skinny_tree, hf_skinny_deviceResetType, tvb, offset+12, 4, TRUE);
1268 case 0x101 : /* startMulticastMediaReception*/
1269 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1270 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1271 proto_tree_add_item(skinny_tree, hf_skinny_multicastIpAddress, tvb, offset+20, 4, TRUE);
1272 proto_tree_add_item(skinny_tree, hf_skinny_multicastPort, tvb, offset+24, 4, TRUE);
1273 proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+28, 4, TRUE);
1274 proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+32, 4, TRUE);
1275 proto_tree_add_item(skinny_tree, hf_skinny_echoCancelType, tvb, offset+36, 4, TRUE);
1276 proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+40, 4, TRUE);
1279 case 0x102 : /* startMulticateMediaTermination*/
1280 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1281 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1282 proto_tree_add_item(skinny_tree, hf_skinny_multicastIpAddress, tvb, offset+20, 4, TRUE);
1283 proto_tree_add_item(skinny_tree, hf_skinny_multicastPort, tvb, offset+24, 4, TRUE);
1284 proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+28, 4, TRUE);
1285 proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+32, 4, TRUE);
1286 proto_tree_add_item(skinny_tree, hf_skinny_precedenceValue, tvb, offset+36, 4, TRUE);
1287 proto_tree_add_item(skinny_tree, hf_skinny_silenceSuppression, tvb, offset+40, 4, TRUE);
1288 proto_tree_add_item(skinny_tree, hf_skinny_maxFramesPerPacket, tvb, offset+44, 2, TRUE);
1289 proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+48, 4, TRUE);
1292 case 0x103 : /* stopMulticastMediaReception*/
1293 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1294 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1297 case 0x104 : /* stopMulticastMediaTermination*/
1298 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1299 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1302 case 0x105 : /* open receive channel */
1303 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1304 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1305 proto_tree_add_item(skinny_tree, hf_skinny_millisecondPacketSize, tvb, offset+20, 4, TRUE);
1306 proto_tree_add_item(skinny_tree, hf_skinny_payloadCapability, tvb, offset+24, 4, TRUE);
1307 proto_tree_add_item(skinny_tree, hf_skinny_echoCancelType, tvb, offset+28, 4, TRUE);
1308 proto_tree_add_item(skinny_tree, hf_skinny_g723BitRate, tvb, offset+32, 4, TRUE);
1311 case 0x106 : /* closeReceiveChannel */
1312 proto_tree_add_item(skinny_tree, hf_skinny_conferenceID, tvb, offset+12, 4, TRUE);
1313 proto_tree_add_item(skinny_tree, hf_skinny_passThruPartyID, tvb, offset+16, 4, TRUE);
1316 case 0x107 : /* connectionStatisticsReq */
1319 proto_tree_add_item(skinny_tree, hf_skinny_directoryNumber, tvb, i, StationMaxDirnumSize, TRUE);
1320 i = 12 + StationMaxDirnumSize;
1321 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, i, 4, TRUE);
1323 proto_tree_add_item(skinny_tree, hf_skinny_statsProcessingType, tvb, i, 4, TRUE);
1326 case 0x108 : /* softkeyTemplateResMessage */
1327 proto_tree_add_item(skinny_tree, hf_skinny_softKeyOffset, tvb, offset+12, 4, TRUE);
1328 softKeyCount = tvb_get_letohl(tvb, offset+16);
1329 proto_tree_add_uint(skinny_tree, hf_skinny_softKeyCount, tvb, offset+16, 4, softKeyCount);
1330 proto_tree_add_item(skinny_tree, hf_skinny_totalSoftKeyCount, tvb, offset+20, 4, TRUE);
1331 for (i = 0; ((i < StationMaxSoftKeyDefinition) && (i < softKeyCount)); i++){
1332 proto_tree_add_item(skinny_tree, hf_skinny_softKeyLabel, tvb, offset+(i*20)+24, StationMaxSoftKeyLabelSize, TRUE);
1333 proto_tree_add_item(skinny_tree, hf_skinny_softKeyEvent, tvb, offset+(i*20)+40, 4, TRUE);
1335 /* there is more data here, but it doesn't make a whole lot of sense, I imagine
1336 * it's just some not zero'd out stuff in the packet or...
1340 case 0x109 : /* softkeysetres */
1341 proto_tree_add_item(skinny_tree, hf_skinny_softKeySetOffset, tvb, offset+12, 4, TRUE);
1342 softKeySetCount = tvb_get_letohl(tvb, offset+16);
1343 proto_tree_add_uint(skinny_tree, hf_skinny_softKeySetCount, tvb, offset+16, 4, softKeySetCount);
1344 proto_tree_add_item(skinny_tree, hf_skinny_totalSoftKeySetCount, tvb, offset+20, 4, TRUE);
1345 for (i = 0; ((i < StationMaxSoftKeySetDefinition) && (i < softKeySetCount)); i++) {
1346 proto_tree_add_uint(skinny_tree, hf_skinny_softKeySetDescription, tvb, offset+24+(i*48) , 1, i);
1347 for (j = 0; j < StationMaxSoftKeyIndex; j++) {
1348 proto_tree_add_item(skinny_tree, hf_skinny_softKeyTemplateIndex, tvb, offset+24+(i*48)+j, 1, TRUE);
1350 for (j = 0; j < StationMaxSoftKeyIndex; j++) {
1351 proto_tree_add_item(skinny_tree, hf_skinny_softKeyInfoIndex, tvb, offset+24+(i*48)+StationMaxSoftKeyIndex+(j*2), 2, TRUE);
1356 case 0x110 : /* selectSoftKeys */
1357 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
1358 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
1359 proto_tree_add_item(skinny_tree, hf_skinny_softKeySetDescription, tvb, offset+20, 4, TRUE);
1360 validKeyMask = tvb_get_letohs(tvb, offset + 24);
1361 skm = proto_tree_add_uint(skinny_tree, hf_skinny_softKeyMap, tvb, offset + 24, 1, validKeyMask);
1362 skm_tree = proto_item_add_subtree(skm, ett_skinny_softKeyMap);
1363 proto_tree_add_boolean(skm_tree, hf_skinny_softKey0, tvb, offset + 24, 1, validKeyMask);
1364 proto_tree_add_boolean(skm_tree, hf_skinny_softKey1, tvb, offset + 24, 1, validKeyMask);
1365 proto_tree_add_boolean(skm_tree, hf_skinny_softKey2, tvb, offset + 24, 1, validKeyMask);
1366 proto_tree_add_boolean(skm_tree, hf_skinny_softKey3, tvb, offset + 24, 1, validKeyMask);
1367 proto_tree_add_boolean(skm_tree, hf_skinny_softKey4, tvb, offset + 24, 1, validKeyMask);
1368 proto_tree_add_boolean(skm_tree, hf_skinny_softKey5, tvb, offset + 24, 1, validKeyMask);
1369 proto_tree_add_boolean(skm_tree, hf_skinny_softKey6, tvb, offset + 24, 1, validKeyMask);
1370 proto_tree_add_boolean(skm_tree, hf_skinny_softKey7, tvb, offset + 24, 1, validKeyMask);
1371 proto_tree_add_boolean(skm_tree, hf_skinny_softKey8, tvb, offset + 24, 1, validKeyMask);
1372 proto_tree_add_boolean(skm_tree, hf_skinny_softKey9, tvb, offset + 24, 1, validKeyMask);
1373 proto_tree_add_boolean(skm_tree, hf_skinny_softKey10, tvb, offset + 24, 1, validKeyMask);
1374 proto_tree_add_boolean(skm_tree, hf_skinny_softKey11, tvb, offset + 24, 1, validKeyMask);
1375 proto_tree_add_boolean(skm_tree, hf_skinny_softKey12, tvb, offset + 24, 1, validKeyMask);
1376 proto_tree_add_boolean(skm_tree, hf_skinny_softKey13, tvb, offset + 24, 1, validKeyMask);
1377 proto_tree_add_boolean(skm_tree, hf_skinny_softKey14, tvb, offset + 24, 1, validKeyMask);
1378 proto_tree_add_boolean(skm_tree, hf_skinny_softKey15, tvb, offset + 24, 1, validKeyMask);
1381 case 0x111 : /* callState */
1382 proto_tree_add_item(skinny_tree, hf_skinny_callState, tvb, offset+12, 4, TRUE);
1383 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+16, 4, TRUE);
1384 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, TRUE);
1387 case 0x112 : /* displayPromptStatus */
1388 proto_tree_add_item(skinny_tree, hf_skinny_messageTimeOutValue, tvb, offset+12, 4, TRUE);
1389 proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, StationMaxDisplayPromptStatusSize, TRUE);
1390 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+48, 4, TRUE);
1391 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+52, 4, TRUE);
1394 case 0x113: /* clearPrompt */
1395 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance , tvb, offset+12, 4, TRUE);
1396 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
1399 case 0x114 : /* displayNotify */
1400 proto_tree_add_item(skinny_tree, hf_skinny_messageTimeOutValue, tvb, offset+12, 4, TRUE);
1401 proto_tree_add_item(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, StationMaxDisplayNotifySize , TRUE);
1404 case 0x115 : /* clearNotify */
1405 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
1408 case 0x116 : /* activateCallPlane */
1409 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
1412 case 0x118 : /* unregisterAckMessage */
1413 proto_tree_add_item(skinny_tree, hf_skinny_deviceUnregisterStatus, tvb, offset+12, 4, TRUE);
1416 case 0x119 : /* backSpaceReq */
1417 proto_tree_add_item(skinny_tree, hf_skinny_lineInstance, tvb, offset+12, 4, TRUE);
1418 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, TRUE);
1421 case 0x11B : /* registerTokenReject */
1422 proto_tree_add_item(skinny_tree, hf_skinny_tokenRejWaitTime, tvb, offset+12, 4, TRUE);
1425 case 0x11D : /* new message */
1426 unknownLong = tvb_get_letohl(tvb, offset+36);
1427 proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknownLong);
1428 proto_tree_add_item(skinny_tree, hf_skinny_callIdentifier, tvb, offset+40, 4, TRUE);
1439 /* Code to actually dissect the packets */
1440 static void dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1442 /* The general structure of a packet: {IP-Header|TCP-Header|n*SKINNY}
1443 * SKINNY-Packet: {Header(Size, Reserved)|Data(MessageID, Message-Data)}
1446 volatile int offset = 0;
1447 int length_remaining;
1452 volatile guint32 hdr_data_length;
1453 guint32 hdr_reserved;
1455 /* check, if this is really an SKINNY packet, they start with a length + 0 */
1457 /* get relevant header information */
1458 hdr_data_length = tvb_get_letohl(tvb, 0);
1459 hdr_reserved = tvb_get_letohl(tvb, 4);
1461 /* data_size = MIN(8+hdr_data_length, tvb_length(tvb)) - 0xC; */
1463 /* hdr_data_length > 1024 is just a heuristic. Better values/checks welcome */
1464 if (hdr_data_length < 4 || hdr_data_length > 1024 || hdr_reserved != 0) {
1465 /* Not an SKINNY packet, just happened to use the same port */
1466 call_dissector(data_handle,tvb, pinfo, tree);
1470 /* Make entries in Protocol column and Info column on summary display */
1471 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1472 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SKINNY");
1475 if (check_col(pinfo->cinfo, COL_INFO)) {
1476 col_set_str(pinfo->cinfo, COL_INFO, "Skinny Client Control Protocol");
1479 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1480 length_remaining = tvb_length_remaining(tvb, offset);
1483 * Can we do reassembly?
1485 if (skinny_desegment && pinfo->can_desegment) {
1487 * Yes - is the length field in the SCCP header split across
1488 * segment boundaries?
1490 if (length_remaining < 4) {
1492 * Yes. Tell the TCP dissector where the data for this message
1493 * starts in the data it handed us, and how many more bytes we
1496 pinfo->desegment_offset = offset;
1497 pinfo->desegment_len = 4 - length_remaining;
1503 * Get the length of the SCCP packet.
1505 hdr_data_length = tvb_get_letohl(tvb, offset);
1508 * Can we do reassembly?
1510 if (skinny_desegment && pinfo->can_desegment) {
1512 * Yes - is the SCCP packet split across segment boundaries?
1514 if ((guint32)length_remaining < hdr_data_length + 8) {
1516 * Yes. Tell the TCP dissector where the data for this message
1517 * starts in the data it handed us, and how many more bytes we
1520 pinfo->desegment_offset = offset;
1521 pinfo->desegment_len = (hdr_data_length + 8) - length_remaining;
1527 * Construct a tvbuff containing the amount of the payload we have
1528 * available. Make its reported length the amount of data in the
1531 * XXX - if reassembly isn't enabled. the subdissector will throw a
1532 * BoundsError exception, rather than a ReportedBoundsError exception.
1533 * We really want a tvbuff where the length is "length", the reported
1534 * length is "hdr_data_length + 8", and the "if the snapshot length
1535 * were infinite" length is the minimum of the reported length of
1536 * the tvbuff handed to us and "hdr_data_length + 8", with a new type
1537 * of exception thrown if the offset is within the reported length but
1538 * beyond that third length, with that exception getting the
1539 * "Unreassembled Packet" error.
1541 length = length_remaining;
1542 if ((guint32)length > hdr_data_length + 8)
1543 length = hdr_data_length + 8;
1544 next_tvb = tvb_new_subset(tvb, offset, length, hdr_data_length + 8);
1547 * Dissect the SCCP packet.
1549 * Catch the ReportedBoundsError exception; if this particular message
1550 * happens to get a ReportedBoundsError exception, that doesn't mean
1551 * that we should stop dissecting SCCP messages within this frame or
1552 * chunk of reassembled data.
1554 * If it gets a BoundsError, we can stop, as there's nothing more to
1555 * see, so we just re-throw it.
1558 dissect_skinny_pdu(next_tvb, pinfo, tree);
1560 CATCH(BoundsError) {
1563 CATCH(ReportedBoundsError) {
1564 show_reported_bounds_error(tvb, pinfo, tree);
1569 * Skip the SCCP header and the payload.
1571 offset += hdr_data_length + 8;
1575 /* Register the protocol with Ethereal */
1577 proto_register_skinny(void)
1580 /* Setup list of header fields */
1581 static hf_register_info hf[] = {
1582 { &hf_skinny_data_length,
1583 { "Data Length", "skinny.data_length",
1584 FT_UINT32, BASE_DEC, NULL, 0x0,
1585 "Number of bytes in the data portion.",
1588 { &hf_skinny_reserved,
1589 { "Reserved", "skinny.reserved",
1590 FT_UINT32, BASE_HEX, NULL, 0x0,
1591 "Reserved for future(?) use.",
1594 /* FIXME: Enable use of message name ??? */
1595 { &hf_skinny_messageid,
1596 { "Message ID", "skinny.messageid",
1597 FT_UINT32, BASE_HEX, VALS(message_id), 0x0,
1598 "The function requested/done with this message.",
1602 { &hf_skinny_deviceName,
1603 { "DeviceName", "skinny.deviceName",
1604 FT_STRING, BASE_NONE, NULL, 0x0,
1605 "The device name of the phone.",
1609 { &hf_skinny_stationUserId,
1610 { "StationUserId", "skinny.stationUserId",
1611 FT_UINT32, BASE_DEC, NULL, 0x0,
1612 "The station user id.",
1616 { &hf_skinny_stationInstance,
1617 { "StationInstance", "skinny.stationInstance",
1618 FT_UINT32, BASE_DEC, NULL, 0x0,
1619 "The stations instance.",
1623 { &hf_skinny_deviceType,
1624 { "DeviceType", "skinny.deviceType",
1625 FT_UINT32, BASE_DEC, VALS(deviceTypes), 0x0,
1626 "DeviceType of the station.",
1630 { &hf_skinny_maxStreams,
1631 { "MaxStreams", "skinny.maxStreams",
1632 FT_UINT32, BASE_DEC, NULL, 0x0,
1633 "32 bit unsigned integer indicating the maximum number of simultansous RTP duplex streams that the client can handle.",
1637 { &hf_skinny_stationIpPort,
1638 { "StationIpPort", "skinny.stationIpPort",
1639 FT_UINT16, BASE_DEC, NULL, 0x0,
1640 "The station IP port",
1644 { &hf_skinny_stationKeypadButton,
1645 { "KeypadButton", "skinny.stationKeypadButton",
1646 FT_UINT32, BASE_HEX, VALS(keypadButtons), 0x0,
1647 "The button pressed on the phone.",
1651 { &hf_skinny_calledParty,
1652 { "CalledParty", "skinny.calledParty",
1653 FT_STRING, BASE_NONE, NULL, 0x0,
1654 "The number called.",
1658 { &hf_skinny_stimulus,
1659 { "Stimulus", "skinny.stimulus",
1660 FT_UINT32, BASE_HEX, VALS(deviceStimuli), 0x0,
1661 "Reason for the device stimulus message.",
1665 { &hf_skinny_stimulusInstance,
1666 { "StimulusInstance", "skinny.stimulusInstance",
1667 FT_UINT32, BASE_DEC, NULL, 0x0,
1668 "The instance of the stimulus",
1672 { &hf_skinny_lineNumber,
1673 { "LineNumber", "skinny.lineNumber",
1674 FT_UINT32, BASE_DEC, NULL, 0x0,
1679 { &hf_skinny_speedDialNumber,
1680 { "SpeedDialNumber", "skinny.speedDialNumber",
1681 FT_UINT32, BASE_DEC, NULL, 0x0,
1682 "Which speed dial number",
1686 { &hf_skinny_capCount,
1687 { "CapCount", "skinny.capCount",
1688 FT_UINT32, BASE_DEC, NULL, 0x0,
1689 "How many capabilities",
1693 { &hf_skinny_payloadCapability,
1694 { "PayloadCapability", "skinny.payloadCapability",
1695 FT_UINT32, BASE_DEC, VALS(mediaPayloads), 0x0,
1696 "The payload capability for this media capability structure.",
1700 { &hf_skinny_maxFramesPerPacket,
1701 { "MaxFramesPerPacket", "skinny.maxFramesPerPacket",
1702 FT_UINT16, BASE_DEC, NULL, 0x0,
1703 "Max frames per packet",
1707 { &hf_skinny_alarmSeverity,
1708 { "AlarmSeverity", "skinny.alarmSeverity",
1709 FT_UINT32, BASE_DEC, VALS(alarmSeverities), 0x0,
1710 "The severity of the reported alarm.",
1714 { &hf_skinny_alarmParam1,
1715 { "AlarmParam1", "skinny.alarmParam1",
1716 FT_UINT32, BASE_HEX, NULL, 0x0,
1717 "An as yet undecoded param1 value from the alarm message",
1721 { &hf_skinny_alarmParam2,
1722 { "AlarmParam2", "skinny.alarmParam2",
1723 FT_IPv4, BASE_NONE, NULL, 0x0,
1724 "This is the second alarm parameter i think it's an ip address",
1728 { &hf_skinny_receptionStatus,
1729 { "ReceptionStatus", "skinny.receptionStatus",
1730 FT_UINT32, BASE_DEC, VALS(multicastMediaReceptionStatus), 0x0,
1731 "The current status of the multicast media.",
1735 { &hf_skinny_passThruPartyID,
1736 { "PassThruPartyID", "skinny.passThruPartyID",
1737 FT_UINT32, BASE_DEC, NULL, 0x0,
1738 "The pass thru party id",
1742 { &hf_skinny_ORCStatus,
1743 { "OpenReceiveChannelStatus", "skinny.openReceiveChannelStatus",
1744 FT_UINT32, BASE_DEC, VALS(openReceiveChanStatus), 0x0,
1745 "The status of the opened receive channel.",
1749 { &hf_skinny_ipAddress,
1750 { "IP Address", "skinny.ipAddress",
1751 FT_IPv4, BASE_NONE, NULL, 0x0,
1756 { &hf_skinny_portNumber,
1757 { "Port Number", "skinny.portNumber",
1758 FT_UINT32, BASE_DEC, NULL, 0x0,
1763 { &hf_skinny_statsProcessingType,
1764 { "StatsProcessingType", "skinny.statsProcessingType",
1765 FT_UINT32, BASE_DEC, VALS(statsProcessingTypes), 0x0,
1766 "What do do after you send the stats.",
1770 { &hf_skinny_callIdentifier,
1771 { "Call Identifier", "skinny.callIdentifier",
1772 FT_UINT32, BASE_DEC, NULL, 0x0,
1773 "Call identifier for this call.",
1777 { &hf_skinny_packetsSent,
1778 { "Packets Sent", "skinny.packetsSent",
1779 FT_UINT32, BASE_DEC, NULL, 0x0,
1780 "Packets Sent during the call.",
1784 { &hf_skinny_octetsSent,
1785 { "Octets Sent", "skinny.octetsSent",
1786 FT_UINT32, BASE_DEC, NULL, 0x0,
1787 "Octets sent during the call.",
1791 { &hf_skinny_packetsRecv,
1792 { "Packets Received", "skinny.packetsRecv",
1793 FT_UINT32, BASE_DEC, NULL, 0x0,
1794 "Packets received during the call.",
1798 { &hf_skinny_octetsRecv,
1799 { "Octets Received", "skinny.octetsRecv",
1800 FT_UINT32, BASE_DEC, NULL, 0x0,
1801 "Octets received during the call.",
1805 { &hf_skinny_packetsLost,
1806 { "Packets Lost", "skinny.packetsLost",
1807 FT_UINT32, BASE_DEC, NULL, 0x0,
1808 "Packets lost during the call.",
1812 { &hf_skinny_latency,
1813 { "Latency(ms)", "skinny.latency",
1814 FT_UINT32, BASE_DEC, NULL, 0x0,
1815 "Average packet latency during the call.",
1819 { &hf_skinny_jitter,
1820 { "Jitter", "skinny.jitter",
1821 FT_UINT32, BASE_DEC, NULL, 0x0,
1822 "Average jitter during the call.",
1826 { &hf_skinny_directoryNumber,
1827 { "Directory Number", "skinny.directoryNumber",
1828 FT_STRING, BASE_NONE, NULL, 0x0,
1829 "The number we are reporting statistics for.",
1833 { &hf_skinny_lineInstance,
1834 { "Line Instance", "skinny.lineInstance",
1835 FT_UINT32, BASE_DEC, NULL, 0x0,
1836 "The display call plane associated with this call.",
1840 { &hf_skinny_softKeyEvent,
1841 { "SoftKeyEvent", "skinny.softKeyEvent",
1842 FT_UINT32, BASE_DEC, VALS(softKeyEvents), 0x0,
1843 "Which softkey event is being reported.",
1847 { &hf_skinny_keepAliveInterval,
1848 { "KeepAliveInterval", "skinny.keepAliveInterval",
1849 FT_UINT32, BASE_DEC, NULL, 0x0,
1850 "How often are keep alives exchanges between the client and the call manager.",
1854 { &hf_skinny_secondaryKeepAliveInterval,
1855 { "SecondaryKeepAliveInterval", "skinny.secondaryKeepAliveInterval",
1856 FT_UINT32, BASE_DEC, NULL, 0x0,
1857 "How often are keep alives exchanges between the client and the secondary call manager.",
1861 { &hf_skinny_dateTemplate,
1862 { "DateTemplate", "skinny.dateTemplate",
1863 FT_STRING, BASE_NONE, NULL, 0x0,
1864 "The display format for the date/time on the phone.",
1868 { &hf_skinny_buttonOffset,
1869 { "ButtonOffset", "skinny.buttonOffset",
1870 FT_UINT32, BASE_DEC, NULL, 0x0,
1871 "Offset is the number of the first button referenced by this message.",
1875 { &hf_skinny_buttonCount,
1876 { "ButtonCount", "skinny.buttonCount",
1877 FT_UINT32, BASE_DEC, NULL, 0x0,
1878 "Number of (VALID) button definitions in this message.",
1882 { &hf_skinny_totalButtonCount,
1883 { "TotalButtonCount", "skinny.totalButtonCount",
1884 FT_UINT32, BASE_DEC, NULL, 0x0,
1885 "The total number of buttons defined for this phone.",
1889 { &hf_skinny_buttonInstanceNumber,
1890 { "InstanceNumber", "skinny.buttonInstanceNumber",
1891 FT_UINT8, BASE_HEX, VALS(keypadButtons), 0x0,
1892 "The button instance number for a button or the StationKeyPad value, repeats allowed.",
1896 { &hf_skinny_buttonDefinition,
1897 { "ButtonDefinition", "skinny.buttonDefinition",
1898 FT_UINT8, BASE_HEX, VALS(buttonDefinitions), 0x0,
1899 "The button type for this instance (ie line, speed dial, ....",
1903 { &hf_skinny_softKeyOffset,
1904 { "SoftKeyOffset", "skinny.softKeyOffset",
1905 FT_UINT32, BASE_DEC, NULL, 0x0,
1906 "The offset for the first soft key in this message.",
1910 { &hf_skinny_softKeyCount,
1911 { "SoftKeyCount", "skinny.softKeyCount",
1912 FT_UINT32, BASE_DEC, NULL, 0x0,
1913 "The number of valid softkeys in this message.",
1917 { &hf_skinny_totalSoftKeyCount,
1918 { "TotalSoftKeyCount", "skinny.totalSoftKeyCount",
1919 FT_UINT32, BASE_DEC, NULL, 0x0,
1920 "The total number of softkeys for this device.",
1924 { &hf_skinny_softKeyLabel,
1925 { "SoftKeyLabel", "skinny.softKeyLabel",
1926 FT_STRING, BASE_NONE, NULL, 0x0,
1927 "The text label for this soft key.",
1931 { &hf_skinny_softKeySetOffset,
1932 { "SoftKeySetOffset", "skinny.softKeySetOffset",
1933 FT_UINT32, BASE_DEC, NULL, 0x0,
1934 "The offset for the first soft key set in this message.",
1938 { &hf_skinny_softKeySetCount,
1939 { "SoftKeySetCount", "skinny.softKeySetCount",
1940 FT_UINT32, BASE_DEC, NULL, 0x0,
1941 "The number of valid softkey sets in this message.",
1945 { &hf_skinny_totalSoftKeySetCount,
1946 { "TotalSoftKeySetCount", "skinny.totalSoftKeySetCount",
1947 FT_UINT32, BASE_DEC, NULL, 0x0,
1948 "The total number of softkey sets for this device.",
1952 { &hf_skinny_softKeyTemplateIndex,
1953 { "SoftKeyTemplateIndex", "skinny.softKeyTemplateIndex",
1954 FT_UINT8, BASE_DEC, VALS(softKeyEvents), 0x0,
1955 "Array of size 16 8-bit unsigned ints containing an index into the softKeyTemplate.",
1959 { &hf_skinny_softKeyInfoIndex,
1960 { "SoftKeyInfoIndex", "skinny.softKeyInfoIndex",
1961 FT_UINT16, BASE_DEC, VALS(softKeyIndexes), 0x0,
1962 "Array of size 16 16-bit unsigned integers containing an index into the soft key description information.",
1966 { &hf_skinny_softKeySetDescription,
1967 { "SoftKeySet", "skinny.softKeySetDescription",
1968 FT_UINT8, BASE_DEC, VALS(keySetNames), 0x0,
1969 "A text description of what this softkey when this softkey set is displayed",
1973 { &hf_skinny_softKeyMap,
1974 { "SoftKeyMap","skinny.softKeyMap",
1975 FT_UINT16, BASE_HEX, NULL, 0x0,
1980 { &hf_skinny_softKey0,
1981 { "SoftKey0", "skinny.softKeyMap.0",
1982 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY0,
1987 { &hf_skinny_softKey1,
1988 { "SoftKey1", "skinny.softKeyMap.1",
1989 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY1,
1994 { &hf_skinny_softKey2,
1995 { "SoftKey2", "skinny.softKeyMap.2",
1996 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY2,
2001 { &hf_skinny_softKey3,
2002 { "SoftKey3", "skinny.softKeyMap.3",
2003 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY3,
2008 { &hf_skinny_softKey4,
2009 { "SoftKey4", "skinny.softKeyMap.4",
2010 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY4,
2015 { &hf_skinny_softKey5,
2016 { "SoftKey5", "skinny.softKeyMap.5",
2017 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY5,
2022 { &hf_skinny_softKey6,
2023 { "SoftKey6", "skinny.softKeyMap.6",
2024 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY6,
2029 { &hf_skinny_softKey7,
2030 { "SoftKey7", "skinny.softKeyMap.7",
2031 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY7,
2036 { &hf_skinny_softKey8,
2037 { "SoftKey8", "skinny.softKeyMap.8",
2038 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY8,
2043 { &hf_skinny_softKey9,
2044 { "SoftKey9", "skinny.softKeyMap.9",
2045 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY9,
2050 { &hf_skinny_softKey10,
2051 { "SoftKey10", "skinny.softKeyMap.10",
2052 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY10,
2057 { &hf_skinny_softKey11,
2058 { "SoftKey11", "skinny.softKeyMap.11",
2059 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY11,
2064 { &hf_skinny_softKey12,
2065 { "SoftKey12", "skinny.softKeyMap.12",
2066 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY12,
2071 { &hf_skinny_softKey13,
2072 { "SoftKey13", "skinny.softKeyMap.13",
2073 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY13,
2078 { &hf_skinny_softKey14,
2079 { "SoftKey14", "skinny.softKeyMap.14",
2080 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY14,
2085 { &hf_skinny_softKey15,
2086 { "SoftKey15", "skinny.softKeyMap.15",
2087 FT_BOOLEAN, 16, TFS(&softKeyMapValues), SKINNY_SOFTKEY15,
2092 { &hf_skinny_lampMode,
2093 { "LampMode", "skinny.lampMode",
2094 FT_UINT32, BASE_DEC, VALS(stationLampModes), 0x0,
2099 { &hf_skinny_messageTimeOutValue,
2100 { "Message Timeout", "skinny.messageTimeOutValue",
2101 FT_UINT32, BASE_DEC, NULL, 0x0,
2102 "The timeout in seconds for this message",
2106 { &hf_skinny_displayMessage,
2107 { "DisplayMessage", "skinny.displayMessage",
2108 FT_STRING, BASE_NONE, NULL, 0x0,
2109 "The message displayed on the phone.",
2113 { &hf_skinny_lineDirNumber,
2114 { "Line Dir Number", "skinny.lineDirNumber",
2115 FT_STRING, BASE_NONE, NULL, 0x0,
2116 "The directory number for this line.",
2120 { &hf_skinny_lineFullyQualifiedDisplayName,
2121 { "DisplayName", "skinny.fqdn",
2122 FT_STRING, BASE_NONE, NULL, 0x0,
2123 "The full display name for this line.",
2127 { &hf_skinny_speedDialDirNumber,
2128 { "SpeedDial Number", "skinny.speedDialDirNum",
2129 FT_STRING, BASE_NONE, NULL, 0x0,
2130 "the number to dial for this speed dial.",
2134 { &hf_skinny_speedDialDisplayName,
2135 { "SpeedDial Display", "skinny.speedDialDisplay",
2136 FT_STRING, BASE_NONE, NULL, 0x0,
2137 "The text to display for this speed dial.",
2141 { &hf_skinny_dateYear,
2142 { "Year", "skinny.year",
2143 FT_UINT32, BASE_DEC, NULL, 0x0,
2148 { &hf_skinny_dateMonth,
2149 { "Month", "skinny.month",
2150 FT_UINT32, BASE_DEC, NULL, 0x0,
2151 "The current month",
2155 { &hf_skinny_dayOfWeek,
2156 { "DayOfWeek", "skinny.dayOfWeek",
2157 FT_UINT32, BASE_DEC, NULL, 0x0,
2158 "The day of the week",
2162 { &hf_skinny_dateDay,
2163 { "Day", "skinny.day",
2164 FT_UINT32, BASE_DEC, NULL, 0x0,
2165 "The day of the current month",
2169 { &hf_skinny_dateHour,
2170 { "Hour", "skinny.hour",
2171 FT_UINT32, BASE_DEC, NULL, 0x0,
2176 { &hf_skinny_dateMinute,
2177 { "Minute", "skinny.minute",
2178 FT_UINT32, BASE_DEC, NULL, 0x0,
2183 { &hf_skinny_dateSeconds,
2184 { "Seconds", "skinny.dateSeconds",
2185 FT_UINT32, BASE_DEC, NULL, 0x0,
2190 { &hf_skinny_dateMilliseconds,
2191 { "Milliseconds", "skinny.dateMilliseconds",
2192 FT_UINT32, BASE_DEC, NULL, 0x0,
2197 { &hf_skinny_timeStamp,
2198 { "Timestamp", "skinny.timeStamp",
2199 FT_UINT32, BASE_DEC, NULL, 0x0,
2200 "Time stamp for the call reference",
2203 { &hf_skinny_callState,
2204 { "CallState", "skinny.callState",
2205 FT_UINT32, BASE_DEC, VALS(skinny_stationCallStates), 0x0,
2206 "The D channel call state of the call",
2210 { &hf_skinny_deviceTone,
2211 { "Tone", "skinny.deviceTone",
2212 FT_UINT32, BASE_HEX, VALS(skinny_deviceTones), 0x0,
2213 "Which tone to play",
2217 { &hf_skinny_callingPartyName,
2218 { "Calling Party Name", "skinny.callingPartyName",
2219 FT_STRING, BASE_NONE, NULL, 0x0,
2220 "The passed name of the calling party.",
2224 { &hf_skinny_callingParty,
2225 { "Calling Party", "skinny.callingPartyName",
2226 FT_STRING, BASE_NONE, NULL, 0x0,
2227 "The passed number of the calling party.",
2231 { &hf_skinny_calledPartyName,
2232 { "Called Party Name", "skinny.calledPartyName",
2233 FT_STRING, BASE_NONE, NULL, 0x0,
2234 "The name of the party we are calling.",
2238 { &hf_skinny_callType,
2239 { "Call Type", "skinny.callType",
2240 FT_UINT32, BASE_DEC, VALS(skinny_callTypes), 0x0,
2241 "What type of call, in/out/etc",
2245 { &hf_skinny_originalCalledPartyName,
2246 { "Original Called Party Name", "skinny.originalCalledPartyName",
2247 FT_STRING, BASE_NONE, NULL, 0x0,
2248 "name of the original person who placed the call.",
2252 { &hf_skinny_originalCalledParty,
2253 { "Original Called Party", "skinny.originalCalledParty",
2254 FT_STRING, BASE_NONE, NULL, 0x0,
2255 "The number of the original calling party.",
2259 { &hf_skinny_ringType,
2260 { "Ring Type", "skinny.ringType",
2261 FT_UINT32, BASE_HEX, VALS(skinny_ringTypes), 0x0,
2262 "What type of ring to play",
2266 { &hf_skinny_speakerMode,
2267 { "Speaker", "skinny.speakerMode",
2268 FT_UINT32, BASE_HEX, VALS(skinny_speakerModes), 0x0,
2269 "This message sets the speaker mode on/off",
2273 { &hf_skinny_remoteIpAddr,
2274 { "Remote Ip Address", "skinny.remoteIpAddr",
2275 FT_IPv4, BASE_NONE, NULL, 0x0,
2276 "The remote end ip address for this stream",
2280 { &hf_skinny_remotePortNumber,
2281 { "Remote Port", "skinny.remotePortNumber",
2282 FT_UINT32, BASE_DEC, NULL, 0x0,
2283 "The remote port number listening for this stream",
2287 { &hf_skinny_millisecondPacketSize,
2288 { "MS/Packet", "skinny.millisecondPacketSize",
2289 FT_UINT32, BASE_DEC, NULL, 0x0,
2290 "The number of milliseconds of conversation in each packet",
2294 { &hf_skinny_precedenceValue,
2295 { "Precedence", "skinny.precedenceValue",
2296 FT_UINT32, BASE_DEC, NULL, 0x0,
2301 { &hf_skinny_silenceSuppression,
2302 { "Silence Suppression", "skinny.silenceSuppression",
2303 FT_UINT32, BASE_HEX, VALS(skinny_silenceSuppressionModes), 0x0,
2304 "Mode for silence suppression",
2308 { &hf_skinny_g723BitRate,
2309 { "G723 BitRate", "skinny.g723BitRate",
2310 FT_UINT32, BASE_DEC, VALS(skinny_g723BitRates), 0x0,
2311 "The G723 bit rate for this stream/JUNK if not g723 stream",
2315 { &hf_skinny_conferenceID,
2316 { "Conference ID", "skinny.conferenceID",
2317 FT_UINT32, BASE_DEC, NULL, 0x0,
2318 "The conference ID",
2322 { &hf_skinny_deviceResetType,
2323 { "Reset Type", "skinny.deviceResetType",
2324 FT_UINT32, BASE_DEC, VALS(skinny_deviceResetTypes), 0x0,
2325 "How the devices it to be reset (reset/restart)",
2329 { &hf_skinny_echoCancelType,
2330 { "Echo Cancel Type", "skinny.echoCancelType",
2331 FT_UINT32, BASE_DEC, VALS(skinny_echoCancelTypes), 0x0,
2332 "Is echo cancelling enabled or not",
2336 { &hf_skinny_deviceUnregisterStatus,
2337 { "Unregister Status", "skinny.deviceUnregisterStatus",
2338 FT_UINT32, BASE_DEC, VALS(skinny_deviceUnregisterStatusTypes), 0x0,
2339 "The status of the device unregister request (*CAN* be refused)",
2343 { &hf_skinny_hookFlashDetectMode,
2344 { "Hook Flash Mode", "skinny.hookFlashDetectMode",
2345 FT_UINT32, BASE_DEC, VALS(skinny_hookFlashDetectModes), 0x0,
2346 "Which method to use to detect that a hook flash has occured",
2350 { &hf_skinny_detectInterval,
2351 { "HF Detect Interval", "skinny.detectInterval",
2352 FT_UINT32, BASE_DEC, NULL, 0x0,
2353 "The number of milliseconds that determines a hook flash has occured",
2357 { &hf_skinny_microphoneMode,
2358 { "Microphone Mode", "skinny.microphoneMode",
2359 FT_UINT32, BASE_DEC, VALS(skinny_microphoneModes), 0x0,
2360 "Turns on and off the microphone on the set",
2364 { &hf_skinny_activeForward,
2365 { "Active Forward", "skinny.activeForward",
2366 FT_UINT32, BASE_DEC, NULL, 0x0,
2367 "This is non zero to indicate that a forward is active on the line",
2371 { &hf_skinny_forwardAllActive,
2372 { "Forward All", "skinny.forwardAllActive",
2373 FT_UINT32, BASE_DEC, NULL, 0x0,
2374 "Forward all calls",
2378 { &hf_skinny_forwardBusyActive,
2379 { "Forward Busy", "skinny.forwardBusyActive",
2380 FT_UINT32, BASE_DEC, NULL, 0x0,
2381 "Forward calls when busy",
2385 { &hf_skinny_forwardNoAnswerActive,
2386 { "Forward NoAns", "skinny.forwardNoAnswerActive",
2387 FT_UINT32, BASE_DEC, NULL, 0x0,
2388 "Forward only when no answer",
2392 { &hf_skinny_forwardNumber,
2393 { "Forward Number", "skinny.forwardNumber",
2394 FT_STRING, BASE_NONE, NULL, 0x0,
2395 "The number to forward calls to.",
2399 { &hf_skinny_userName,
2400 { "Username", "skinny.userName",
2401 FT_STRING, BASE_NONE, NULL, 0x0,
2402 "Username for this device.",
2406 { &hf_skinny_serverName,
2407 { "Server Name", "skinny.serverName",
2408 FT_STRING, BASE_NONE, NULL, 0x0,
2409 "The server name for this device.",
2413 { &hf_skinny_numberLines,
2414 { "Number of Lines", "skinny.numberLines",
2415 FT_UINT32, BASE_DEC, NULL, 0x0,
2416 "How many lines this device has",
2420 { &hf_skinny_numberSpeedDials,
2421 { "Number of SpeedDials", "skinny.numberSpeedDials",
2422 FT_UINT32, BASE_DEC, NULL, 0x0,
2423 "The number of speed dials this device has",
2427 { &hf_skinny_sessionType,
2428 { "Session Type", "skinny.sessionType",
2429 FT_UINT32, BASE_DEC, VALS(skinny_sessionTypes), 0x0,
2430 "The type of this session.",
2434 { &hf_skinny_version,
2435 { "Version", "skinny.version",
2436 FT_STRING, BASE_NONE, NULL, 0x0,
2441 { &hf_skinny_mediaEnunciationType,
2442 { "Enunciation Type", "skinny.mediaEnunciationType",
2443 FT_UINT32, BASE_DEC, VALS(skinny_mediaEnunciationTypes), 0x0,
2448 { &hf_skinny_serverIdentifier,
2449 { "Server Identifier", "skinny.serverIdentifier",
2450 FT_STRING, BASE_NONE, NULL, 0x0,
2451 "Server Identifier.",
2455 { &hf_skinny_serverListenPort,
2456 { "Server Port", "skinny.serverListenPort",
2457 FT_UINT32, BASE_DEC, NULL, 0x0,
2458 "The port the server listens on.",
2462 { &hf_skinny_serverIpAddress,
2463 { "Server Ip Address", "skinny.serverIpAddress",
2464 FT_IPv4, BASE_NONE, NULL, 0x0,
2465 "The IP address for this server",
2469 { &hf_skinny_multicastPort,
2470 { "Multicast Port", "skinny.multicastPort",
2471 FT_UINT32, BASE_DEC, NULL, 0x0,
2472 "The multicast port the to listens on.",
2476 { &hf_skinny_multicastIpAddress,
2477 { "Multicast Ip Address", "skinny.multicastIpAddress",
2478 FT_IPv4, BASE_NONE, NULL, 0x0,
2479 "The multicast address for this conference",
2483 { &hf_skinny_tokenRejWaitTime,
2484 { "Retry Wait Time", "skinny.tokenRejWaitTime",
2485 FT_UINT32, BASE_DEC, NULL, 0x0,
2486 "The time to wait before retrying this token request.",
2490 { &hf_skinny_unknown,
2491 { "Data", "skinny.unknown",
2492 FT_UINT32, BASE_HEX, NULL, 0x0,
2493 "Place holder for unknown data.",
2499 /* Setup protocol subtree array */
2500 static gint *ett[] = {
2502 &ett_skinny_softKeyMap,
2505 module_t *skinny_module;
2507 /* Register the protocol name and description */
2508 proto_skinny = proto_register_protocol("Skinny Client Control Protocol",
2509 "SKINNY", "skinny");
2511 /* Required function calls to register the header fields and subtrees used */
2512 proto_register_field_array(proto_skinny, hf, array_length(hf));
2513 proto_register_subtree_array(ett, array_length(ett));
2515 skinny_module = prefs_register_protocol(proto_skinny, NULL);
2516 prefs_register_bool_preference(skinny_module, "desegment",
2517 "Desegment all SCCP messages spanning multiple TCP segments",
2518 "Whether the SCCP dissector should desegment all messages spanning multiple TCP segments",
2523 proto_reg_handoff_skinny(void)
2525 dissector_handle_t skinny_handle;
2527 data_handle = find_dissector("data");
2528 skinny_handle = create_dissector_handle(dissect_skinny, proto_skinny);
2529 dissector_add("tcp.port", TCP_PORT_SKINNY, skinny_handle);
2535 * This is the status of this decode.
2536 * Items marked as N/A in the decode field have no params to test
2537 * implemented for N/A means they exist in the switch statement
2540 * id message implemented decode tested (via capture)
2541 * ---------------------------------------------------------------------------
2542 * 0x0 keepAlive Y N/A
2545 * 0x3 keypadButton Y Y
2546 * 0x4 enblocCall Y N
2550 * 0x8 hookFlash Y N/A
2551 * 0x9 forwardStatReq Y N
2552 * 0xa speedDialStatReq Y Y
2553 * 0xb lineStatReq Y Y
2554 * 0xc configStatReq Y N/A
2555 * 0xd timeDateReq Y N/A
2556 * 0xe buttonTemplateReq Y N/A
2557 * 0xf versionReq Y N/A
2558 * 0x10 capabilitiesRes Y Y -- would like more decodes
2559 * 0x11 mediaPortList S N -- no info
2560 * 0x12 serverReq Y N/A
2561 * 0x20 alarmMessage Y Y
2562 * 0x21 multicastMediaReceptionAck Y N
2563 * 0x22 openReceiveChannelAck Y Y
2564 * 0x23 connectionStatisticsRes Y Y
2565 * 0x24 offHookWithCgpn Y N
2566 * 0x25 softKeySetReq Y N/A
2567 * 0x26 softKeyEvent Y Y
2568 * 0x27 unregister Y N/A
2569 * 0x28 softKeytemplateReq Y N/A
2570 * 0x29 registerTokenReq Y N
2571 *******************************
2572 * 0x2b unknownClientMessage1 S N
2573 * 0x2d unknownClientMessage2 S N
2574 *******************************
2575 * 0x81 registerAck Y Y
2576 * 0x82 startTone Y Y
2577 * 0x83 stopTone Y N/A
2578 * 0x85 setRinger Y Y
2580 * 0x87 setHkFDetect Y N
2581 * 0x88 setSpeakerMode Y Y
2582 * 0x89 setMicroMode Y N
2583 * 0x8A startMediaTransmission Y Y
2584 * 0x8B stopMediaTransmission Y Y
2585 * 0x8C startMediaReception S N
2586 * 0x8D stopMediaReception S N
2587 * 0x8E *reserved* S *
2589 * 0x90 forwardStat Y N
2590 * 0x91 speedDialStat Y Y
2592 * 0x93 configStat Y N
2593 * 0x94 defineTimeDate Y Y
2594 * 0x95 startSessionTransmission Y N
2595 * 0x96 stopSessionTransmission Y N
2596 * 0x97 buttonTemplate Y Y -- ugly =)
2598 * 0x99 displayText Y Y
2599 * 0x9A clearDisplay Y N/A
2600 * 0x9B capabilitiesReq Y N/A
2601 * 0x9C enunciatorCommand Y N (inner loop unknown)
2602 * 0x9D registerReject Y N
2603 * 0x9E serverRes Y N
2605 * 0x100 keepAliveAck Y N/A
2606 * 0x101 startMulticastMediaReception Y N
2607 * 0x102 startMulticastMediaTransmission Y N
2608 * 0x103 stopMulticastMediaReception Y N
2609 * 0x104 stopMulticastMediaTransmission Y N
2610 * 0x105 openreceiveChannel Y Y
2611 * 0x106 closeReceiveChannel Y Y
2612 * 0x107 connectionStatisticsReq Y Y
2613 * 0x108 softKeyTemplateRes Y Y
2614 * 0x109 softKeySetRes Y Y
2615 * 0x110 selectSoftKeys Y Y
2616 * 0x111 callState Y Y
2617 * 0x112 displayPromptStatus Y Y
2618 * 0x113 clearPromptStatus Y Y
2619 * 0x114 displayNotify Y Y
2620 * 0x115 clearNotify Y Y
2621 * 0x116 activateCallPlane Y Y
2622 * 0x117 deactivateCallPlane Y N/A
2623 * 0x118 unregisterAck Y Y
2624 * 0x119 backSpaceReq Y Y
2625 * 0x11A registerTokenAck Y N
2626 * 0x11B registerTokenReject Y N
2627 *******************************
2628 * 0x11D unknownForwardMessage NC N
2629 *******************************