mod_skinny
About
SCCP (or Skinny), is a ToIP protocol used in Cisco products like Cisco IP Phones 79xx.
For more info, see Skinny Call Control Protocol on Wikipedia.
If you use SCCP please test the Patterns Dialplan Configuration halfway down this page and provide feedback at the bottom of this page on how it works. Specifically, will FreeSWITCH recognize variable length dial strings and will it timeout properly as specified by the data provided to the skinny-wait dialplan application. Thanks.
Features
Implemented
- Incoming and outgoing calls (early media supported)
- Shared lines and multiple calls per lines
- CallInfo set as early as possible
- New call made from: OffHook, Softkeys (Redial, NewCall), Stimulus (LastNumberRedial, VoiceMail, SpeedDial)
- Answering calls via: OffHook, Softkeys (Answer)
- Holding/Retrieving calls via Softkeys (Hold, Resume) or Stimulus (Hold), with MOH (music on hold)
- Transfer via Softkeys (Transfer) or Stimulus (Transfer). Blind transfer (with OnHook)
- Ending call via: OnHook, Softkeys (EndCall)
- Misc: SoftKeys (Backspace)
- Handle firmware version request (VersionReqMessage) per device type or per device
- Patterns for dialed numbers to process (patterns-dialplan and patterns-context)
- Custom applications can be made using the API and events: See Custom applications
- Custom Events: See Custom Events
- API Commands: See API Commands
- Message Waiting indicator (MWI) on the first line of each device
- Working on x86 (32-bit) and x86_64 (64-bit)
Missing
Missing features that somebody with a Cisco Skinny system needs to add.
Click here to expand...
(bold means Important missing features ; this list doesn't mean that anyone is working on it :-P )
- Softkeys/Stimulus:
- CFwdAll/ForwardAll, CFwdBusy/ForwardBusy, CFwdNoAnswer/ForwardNoAnswer; see FS-3048 -Authenticate to see issue details
- /AutoAnswer, /AutoAnswerRelease
- /ServiceURL
- /Conference, /MeetMeConference, Join, MeetMeConfrn
- Park/CallPark, CallPickUp/CallPickup, GrpCallPickUp/GroupCallPickup; see FS-5662 -Authenticate to see issue details
- Info
- Confrn
- DND (DoNotDisturb); see FS-3047 -Authenticate to see issue details
- Per line:
- no-answer-duration
- Ring policies: on-idle, on-active (when any line on the phone has a call in progress); see FS-5384 -Authenticate to see issue details
- Ring policies: call-pickup-group/on-idle, call-pickup-group/on-active
- busy-trigger (number of active calls before busy)
- Features:
- Improved presence:
- Message Waiting indicator (MWI) improvements (how to handle multiple lines?)
- Shared Line Appearance common to mod_sofia (SCA)
- Busy Lamp Field
- Message Waiting indicator (MWI) improvements (how to handle multiple lines?)
- Better behavior (when: other leg busy, ...)
- IPMA (manager-assistant)
- Extension mobility
- Soft-key template and Soft-key sets configurable via XML
- Bypass Media (help needed)
- Codec Negotiation (help needed, see FS-5460 -Authenticate to see issue details
- Dynamic Speed Dials (need more info on this)
- Other platforms than i386: amd64 (need more testing), ppc (nothing done)
- Support for Smart Phone Control Protocol (SPCP) info for CP-500 phones and the SPA525 phone
- Improved presence:
- Administration and management:
- LDAP schema
- xml_curl module to read from LDAP (prototype to be committed)
- GOsa plugin and/or FreePBX module
- Use FUSE to automagicaly create files on TFTP request
- Whisper Coaching
- Custom Events:
- API Commands:
skinny profile <profile_name> device <device_name> send SelectSoftKeysMessage [...] skinny profile <profile_name> device <device_name> send CallInfo [...] skinny profile <profile_name> device <device_name> send StartTone <tone> skinny profile <profile_name> device <device_name> send StopTone skinny status profile <profile_name> line <line_name> skinny status profile <profile_name> device <device_name> buttons [<button_type>]
Interop List
This list is a work-in-progress; please add any tested SCCP phone.
Model | DeviceTypeId | Status |
---|---|---|
Cisco IP Phone 7910 | 6 | OK(1) |
Cisco IP Phone 7940 | 8 | OK(2) |
Cisco IP Phone 7960 | 7 | OK(2) |
Cisco IP Phone 7961 | 30018 | OK |
Cisco IP Phone 7975 | 437 | OK |
Nokia Call Connect 2.0 | ? | Not tested(3) |
Footnotes:
- The six buttons (msgs, conf, forward, speed 1, speed 2 and redial) have button positions 5 to 10 respectively.
- Also tested with Cisco Unified IP Phone Expansion Module 7914: adds 14 definable buttons with working lights. Button number starts with 3 for the 7940 and 7 for the 7960.
- Mobile Business Solutions From Cisco and Nokia Downloads
"DeviceTypeId" can be found by issuing the following command on fs_cli:
skinny status profile internal device <your_device>
Building
There is no additional dependency needed to build mod_skinny. You just need to edit modules.conf (uncomment endpoints/mod_skinny) and run:
make mod_skinny
Also uncomment <load module="mod_skinny"/> in ~/freeswitch/conf/auto_configs/modules.conf.xml so that FreeSWITCH actually loads the module at start time.
Configuration
- 192.168.0.2 is the IP of the TFTP server
- 192.168.0.3 is the IP of the FreeSWITCH server (with mod_skinny)
- SEP001120AABBCC is the phone id (based on the MAC address)
- Voicemail/Messages is hardwired in code to dial extension "vmain".
DHCP and TFTP Configuration
This is widely discussed at voip-info.org (http://www.voip-info.org/wiki/view/Asterisk+phone+cisco+79xx), here is a quick overview.
DHCP
First, the phone gets its IP address and other network configs through DHCP.
The important setting is the tftp server option
using udhcp (the most lightweight) , this is set in /etc/udhcpd.conf:
opt tftp 192.168.0.2
using ISC DHCP (widely used), this is set in /etc/dhcp3/dhcpd.conf:
option tftp-server-name 192.168.0.2;
TFTP
There are plenty of TFTP server implementations. In the root of the tftp directory (usually /srv/tftp), put the following files:
XMLDefault.cnf.xml Expand source
<Default>
<callManagerGroup>
<members>
<member priority="0">
<callManager>
<ports>
<ethernetPhonePort>2000</ethernetPhonePort>
</ports>
<processNodeName>192.168.0.3</processNodeName>
</callManager>
</member>
</members>
</callManagerGroup>
<loadInformation30002 model="Cisco 7960">P00307010100</loadInformation30002>
</Default>
SEP001120AABBCC.cnf.xml (minimal) Expand source
<device>
<devicePool>
<callManagerGroup>
<members>
<member priority="0">
<callManager>
<ports>
<ethernetPhonePort>2000</ethernetPhonePort>
</ports>
<processNodeName>192.168.0.3</processNodeName>
</callManager>
</member>
</members>
</callManagerGroup>
</devicePool>
</device>
SEP001120AABBCC.cnf.xml (extended) Expand source
<device>
<devicePool>
<callManagerGroup>
<members>
<member priority="0">
<callManager>
<ports>
<ethernetPhonePort>2000</ethernetPhonePort>
</ports>
<processNodeName>192.168.0.3</processNodeName>
</callManager>
</member>
</members>
</callManagerGroup>
<dateTimeSetting>
<dateTemplate>M/D/YA</dateTemplate>
<timeZone>Central Europe Standard/Daylight Time</timeZone>
</dateTimeSetting>
</devicePool>
<versionStamp>{Jan 20 01 00:00:00}</versionStamp>
<userLocale>
<name>French_France</name>
<uid>2</uid>
<langCode>fr</langCode>
<version>4.0(1)SR1FRA</version>
<winCharSet>iso-8859-1</winCharSet>
</userLocale>
<networkLocale>France</networkLocale>
<networkLocaleInfo>
<name>France</name>
<uid>14</uid>
<version>4.0(1)SR1</version>
</networkLocaleInfo>
<idleTimeout>0</idleTimeout>
<authenticationURL></authenticationURL>
<directoryURL></directoryURL>
<idleURL></idleURL>
<informationURL></informationURL>
<messagesURL></messagesURL>
<proxyServerURL></proxyServerURL>
<servicesURL></servicesURL>
</device>
- dateTemplate seems to be ignored. Use date-format from the profile configuration
- timeZone codes are listed on http://www.cisco.com/en/US/docs/voice%5Fip%5Fcomm/cucme/command/reference/cme%5Ft1ht.html
- You need the corresponding files on your TFTP server if you are using userLocale and networkLocale. More info on the Cisco website (You must have an account on Cisco.com to download locale files)
- All *URL options may point to a Cisco 79XX XML Service, sathieu's xml-directory or sathieu's cisco-xml browser,
FreeSWITCH Configuration
The configuration is loaded from autolad_configs as usual. The default is:
conf/autoload_configs/skinny.conf.xml
<configuration name="skinny.conf" description="Skinny Profiles">
<profiles>
<X-PRE-PROCESS cmd="include" data="../skinny_profiles/*.xml"/>
</profiles>
</configuration>
Profile Configurations
Each profile is put in conf/skinny_profiles. The default configuration should work without modifications.
conf/skinny_profiles/internal.xml Expand source
<profile name="internal">
<settings>
<param name="domain" value="$${domain}"/>
<param name="ip" value="$${local_ip_v4}"/>
<param name="port" value="2000"/>
<param name="patterns-dialplan" value="XML"/>
<param name="patterns-context" value="skinny-patterns"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="keep-alive" value="60"/>
<param name="date-format" value="D/M/Y"/>
<param name="odbc-dsn" value=""/>
<param name="debug" value="4"/>
<param name="auto-restart" value="true"/>
<param name="ext-voicemail" value="vmain"/>
<param name="ext-redial" value="redial"/>
<!-- <param name="ext-autodial" value="operator"/> -->
<param name="digit-timeout" value="10000"/>
</settings>
<soft-key-set-sets>
<soft-key-set-set name="default">
<soft-key-set name="KeySetOnHook" value="SoftkeyNewcall,SoftkeyRedial"/>
<soft-key-set name="KeySetConnected" value="SoftkeyEndcall,SoftkeyHold,SoftkeyNewcall,SoftkeyTransfer"/>
<soft-key-set name="KeySetOnHold" value="SoftkeyNewcall,SoftkeyResume,SoftkeyEndcall"/>
<soft-key-set name="KeySetRingIn" value="SoftkeyAnswer,SoftkeyEndcall,SoftkeyNewcall"/>
<soft-key-set name="KeySetOffHook" value=",SoftkeyRedial,SoftkeyEndcall"/>
<soft-key-set name="KeySetConnectedWithTransfer" value="SoftkeyEndcall,SoftkeyHold,SoftkeyNewcall,SoftkeyTransfer"/>
<soft-key-set name="KeySetDigitsAfterDialingFirstDigit" value="SoftkeyBackspace,,SoftkeyEndcall"/>
<!-- <soft-key-set name="KeySetConnectedWithConference" value=""/> -->
<soft-key-set name="KeySetRingOut" value=",,SoftkeyEndcall,SoftkeyTransfer"/>
<soft-key-set name="KeySetOffHookWithFeatures" value=",SoftkeyRedial,SoftkeyEndcall"/>
<soft-key-set name="KeySetInUseHint" value="SoftkeyNewcall,SoftkeyRedial"/>
</soft-key-set-set>
</soft-key-set-sets>
<device-types>
<device-type id="Cisco ATA 186">
<param name="firmware-version" value="ATA030101SCCP04"/>
</device-type>
</device-types>
</profile>
-
If ip="", mod_skinny will listen on all IP addresses. If you want to force IPv6, use ip="::"
-
If ext-autodial is set, the phone will do a ringdown/automatically dial that number when taken off-hook. This is useful for customer service and emergency phones.
-
mod_skinny logs a lot under [DEBUG], every skinny message received or sent. keepAlive and keepAliveAck messages are only logged if profile's debug is >=10.
-
When issuing a reloadxml command, those values are not reloaded. Use skinny profile <profile_name> set <name> <value> instead.
-
You typically don't have to bother about the firmware-version unless your phone asks for it through skinny (most Cisco phones use XML files from tftp). If you have missed one, mod_skinny will complain in the log with the following message:
[DEBUG] skinny_server.c:1501 Device SEP001120AABBCC:0 is requesting for firmware version, but none is set.
-
The auto-restart param is used when a network interface ip changes. If set to true, the socket will be closed (including all connected listeners) and reopened on the new IP.
Device Configuration
Devices are set up as users in conf/directory. The critical parameter here is id, which corresponds to the MAC address.
conf/directory/default/skinny-example.xml Expand source
<include>
<user id="SEP001120AABBCC">
<params>
<!-- for devices requesting firmware via SCCP, like ATA186
<param name="skinny-firmware-version" value="ATA030101SCCP04"
<param name="skinny-soft-key-set-set" value="default"
-->
<param name="foo" value="bar"/>
</params>
<skinny>
<buttons>
<!--
position: 1..
type: one of line, speed-dial
label: button label
-->
<!--
value is the directory number (or user)
caller-name is shown to the calling party during call
ring-on-active defaults to 1, if set to 0, will not generate call waiting beep if a call is active
ring-on-idle defaults to 1, if set to 0, will not ring audibly if a call is active
-->
<button position="1" type="Line" label="Line 1" value="1101" caller-name="Calling as 1101"/>
<button position="3" type="Line" label="Shared Line 10" value="1110" caller-name="Calling as 1110"/>
<!--
value is the directory number to call
-->
<button position="5" type="SpeedDial" label="Call 1001" value="1001"/>
<!--
value is the URL
-->
<button position="6" type="ServiceUrl" label="Some URL" value="http://phone-xml.berbee.com/menu.xml"/>
</buttons>
</skinny>
</user>
</include>
More information on ServiceUrls at http://www.voip-info.org/wiki/view/Asterisk+Cisco+79XX+XML+Services
Patterns Dialplan configuration
This dialplan is used when calling from a skinny phone. The default configuration will allow you to call SIP phones and some tests like the variable info dump to fs_cli (9192).
As all the call process is made on the server, we need a way to know how many digits are necessary to route the call. Executing the dialplan each time a digit is pressed is not correct. An other dialplan context is used to say simply what mod_skinny should do:
Please test on your SCPP/Skinny system and tell us how to improve this module at FS-477 -Authenticate to see issue details
conf/dialplan/skinny-patterns.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
NOTICE:
This context is used for skinny to match dialed number
The special applications:
- skinny-process tells skinny to process the call (route, set call forwarding, ...)
- skinny-drop tells skinny to drop the call
- skinny-wait tells skinny to wait for more digits, falls back to setting in profile if data not provided, and then system default of 10 seconds
-->
<!-- http://wiki.freeswitch.org/wiki/Mod_skinny -->
<include>
<context name="skinny-patterns">
<!--
Wait for another digit by default
-->
<extension name="Default" continue="true">
<condition field="destination_number" expression="^(.*)$" >
<action application="skinny-wait" data="10" />
</condition>
</extension>
<!--
You can place files in the skinny-patterns directory to get included.
-->
<X-PRE-PROCESS cmd="include" data="skinny-patterns/*.xml"/>
</context>
</include>
You can select the diaplan context by setting patterns-dialplan and patterns-context in the skinny profile configuration.
Dialplan configuration
This dialplan snippet is necessary when you need to send a call to a skinny phone. Without this, you will not be able to call your skinny phones!
Add something like this to (Example with 11xx):
conf/dialplan/default.xml
<extension name="Local_Extension_Skinny">
<condition field="destination_number" expression="^(11[01][0-9])$">
<action application="bridge" data="skinny/internal/${destination_number}"/>
</condition>
</extension>
Outgoing Channel Syntax
Basic form:
skinny/<profile>/<number>
API Commands
Note: most of the command arguments can be auto completed on CLI by using tab (for example <ring_type>).
USAGE:
skinny help skinny status profile <profile_name> skinny status profile <profile_name> device <device_name> skinny profile <profile_name> device <device_name> send ResetMessage [DeviceReset|DeviceRestart] skinny profile <profile_name> device <device_name> send SetRingerMessage <ring_type> <ring_mode> skinny profile <profile_name> device <device_name> send SetLampMessage <stimulus> <instance> <lamp_mode> skinny profile <profile_name> device <device_name> send SetSpeakerModeMessage <speaker_mode> skinny profile <profile_name> device <device_name> send CallStateMessage <call_state> <line_instance> <call_id> skinny profile <profile_name> device <device_name> send <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data> skinny profile <profile_name> set <name> <value>
(More TODO)
Custom Events
skinny::register
Event-Subclass: skinny%3A%3Aregister Event-Name: CUSTOM Core-UUID: 1f9d861e-e5cc-4b5c-b32d-9a7a1dd0b540 FreeSWITCH-Hostname: netthieu FreeSWITCH-IPv4: 192.168.0.3 FreeSWITCH-IPv6: %3A%3A1 Event-Date-Local: 2010-09-24%2002%3A19%3A16 Event-Date-GMT: Fri,%2024%20Sep%202010%2000%3A19%3A16%20GMT Event-Date-Timestamp: 1285287556518629 Event-Calling-File: skinny_protocol.c Event-Calling-Function: skinny_device_event Event-Calling-Line-Number: 224 Skinny-Profile-Name: internal Skinny-Device-Name: SEP001120AABBCC Skinny-Station-User-Id: 0 Skinny-Station-Instance: 0 Skinny-IP-Address: 192.168.0.4 Skinny-Device-Type: 30018 Skinny-Max-Streams: 5 Skinny-Port: (null) Skinny-Codecs: undef
skinny::unregister
Event-Subclass: skinny%3A%3Aunregister Event-Name: CUSTOM Core-UUID: 1f9d861e-e5cc-4b5c-b32d-9a7a1dd0b540 FreeSWITCH-Hostname: netthieu FreeSWITCH-IPv4: 192.168.0.3 FreeSWITCH-IPv6: %3A%3A1 Event-Date-Local: 2010-09-24%2002%3A18%3A39 Event-Date-GMT: Fri,%2024%20Sep%202010%2000%3A18%3A39%20GMT Event-Date-Timestamp: 1285287519036825 Event-Calling-File: skinny_protocol.c Event-Calling-Function: skinny_device_event Event-Calling-Line-Number: 224 Skinny-Profile-Name: internal Skinny-Device-Name: SEP001120AABBCC Skinny-Station-User-Id: 0 Skinny-Station-Instance: 0 Skinny-IP-Address: 192.168.0.4 Skinny-Device-Type: 30018 Skinny-Max-Streams: 5 Skinny-Port: 3500 Skinny-Codecs: WIDEBAND,ULAW,ALAW,G729,G729,G729,G729,RFC2833_DYNPAYLOAD
skinny::expire
skinny::alarm
Event-Subclass: skinny%3A%3Aalarm Event-Name: CUSTOM Core-UUID: 1f9d861e-e5cc-4b5c-b32d-9a7a1dd0b540 FreeSWITCH-Hostname: netthieu FreeSWITCH-IPv4: 192.168.0.3 FreeSWITCH-IPv6: %3A%3A1 Event-Date-Local: 2010-09-24%2002%3A19%3A16 Event-Date-GMT: Fri,%2024%20Sep%202010%2000%3A19%3A16%20GMT Event-Date-Timestamp: 1285287556312672 Event-Calling-File: skinny_protocol.c Event-Calling-Function: skinny_device_event Event-Calling-Line-Number: 224 Skinny-Alarm-Severity: 2 Skinny-Alarm-DisplayMessage: 22%3A%20Nom%SEP001120AABBCC%20Image%3D%20SCCP41.8-3-1S%20Dernier%3DR%E9init.-R%E9init. Skinny-Alarm-Param1: 0 Skinny-Alarm-Param2: 0
skinny::call_state
this is for internal use and might change in the future.
skinny::user_to_device
Event-Subclass: skinny%3A%3Auser_to_device Event-Name: CUSTOM Core-UUID: 1f9d861e-e5cc-4b5c-b32d-9a7a1dd0b540 FreeSWITCH-Hostname: netthieu FreeSWITCH-IPv4: 192.168.0.3 FreeSWITCH-IPv6: %3A%3A1 Event-Date-Local: 2010-09-24%2002%3A10%3A01 Event-Date-GMT: Fri,%2024%20Sep%202010%2000%3A10%3A01%20GMT Event-Date-Timestamp: 1285287001570252 Event-Calling-File: skinny_protocol.c Event-Calling-Function: skinny_device_event Event-Calling-Line-Number: 224 Skinny-Profile-Name: internal Skinny-Device-Name: SEP001120AABBCC Skinny-Station-User-Id: 0 Skinny-Station-Instance: 0 Skinny-IP-Address: 192.168.0.4 Skinny-Device-Type: 30018 Skinny-Max-Streams: 5 Skinny-Port: 3500 Skinny-Codecs: WIDEBAND,ULAW,ALAW,G729,G729,G729,G729,RFC2833_DYNPAYLOAD Skinny-UserToDevice-Message-Id-String: UserToDeviceDataVersion1Message Skinny-UserToDevice-sequence-flag: 2 Content-Length: 111
<CiscoIPPhoneText><Title>Hello</Title><Prompt>Amazing</Prompt><Text>This is some text</Text></CiscoIPPhoneText>
skinny::device_to_user
Event-Subclass: skinny%3A%3Adevice_to_user Event-Name: CUSTOM Core-UUID: 1f9d861e-e5cc-4b5c-b32d-9a7a1dd0b540 FreeSWITCH-Hostname: netthieu FreeSWITCH-IPv4: 192.168.0.3 FreeSWITCH-IPv6: %3A%3A1 Event-Date-Local: 2010-09-24%2002%3A10%3A01 Event-Date-GMT: Fri,%2024%20Sep%202010%2000%3A10%3A01%20GMT Event-Date-Timestamp: 1285287001696990 Event-Calling-File: skinny_protocol.c Event-Calling-Function: skinny_device_event Event-Calling-Line-Number: 224 Skinny-Profile-Name: internal Skinny-Device-Name: SEP001120AABBCC Skinny-Station-User-Id: 0 Skinny-Station-Instance: 0 Skinny-IP-Address: 192.168.0.4 Skinny-Device-Type: 30018 Skinny-Max-Streams: 5 Skinny-Port: 3500 Skinny-Codecs: WIDEBAND,ULAW,ALAW,G729,G729,G729,G729,RFC2833_DYNPAYLOAD Skinny-DeviceToUser-Message-Id: 66 Skinny-DeviceToUser-Message-Id-String: DeviceToUserDataResponseVersion1Message Skinny-DeviceToUser-Application-Id: 0 Skinny-DeviceToUser-Line-Instance: 0 Skinny-DeviceToUser-Call-Id: 0 Skinny-DeviceToUser-Transaction-Id: 0 Skinny-DeviceToUser-Data-Length: 172 Skinny-DeviceToUser-Sequence-Flag: 2 Skinny-DeviceToUser-Display-Priority: 0 Skinny-DeviceToUser-Conference-Id: 0 Skinny-DeviceToUser-App-Instance-Id: 0 Skinny-DeviceToUser-Routing-Id: 0 Content-Length: 171
<?xml version="1.0" encoding="iso8859-1"?> <CiscoIPPhoneResponse> <ResponseItem URL="cip.xml.XmlTextObject@e771b" Data="SUCCESS" Status="0" /> </CiscoIPPhoneResponse>
skinny::xml_alarm
Event-Subclass: skinny%3A%3Axml_alarm Event-Name: CUSTOM Core-UUID: a4aaa78c-9cfe-4e15-abb8-52e222a361d8 FreeSWITCH-Hostname: servthieu FreeSWITCH-IPv4: 192.168.0.3 FreeSWITCH-IPv6: %3A%3A1 Event-Date-Local: 2010-12-19%2022%3A10%3A43 Event-Date-GMT: Sun,%2019%20Dec%202010%2021%3A10%3A43%20GMT Event-Date-Timestamp: 1292793043629627 Event-Calling-File: skinny_protocol.c Event-Calling-Function: skinny_device_event Event-Calling-Line-Number: 224 Content-Length: 1232
<?xml version="1.0" encoding="UTF-8"?> <x-cisco-alarm> <Alarm Name="LastOutOfServiceInformation"> <ParameterList> <String name="DeviceName">SEP001120AABBCC</String> <String name="DeviceIPv4Address">192.168.0.4</String> <String name="IPv4DefaultGateway">192.168.0.254</String> <String name="DeviceIPv6Address"></String> <String name="IPv6DefaultGateway"></String> <String name="ModelNumber">CP-7961G</String> <String name="NeighborIPv4Address">192.168.0.253</String> <String name="NeighborIPv6Address"></String> <String name="NeighborDeviceID">sw2.local</String> <String name="NeighborPortID">3</String> <Enum name="DHCPv4Status">1</Enum> <Enum name="DHCPv6Status">0</Enum> <Enum name="TFTPCfgStatus">0</Enum> <Enum name="DNSStatusUnifiedCM1">0</Enum> <Enum name="DNSStatusUnifiedCM2">0</Enum> <Enum name="DNSStatusUnifiedCM3">0</Enum> <String name="VoiceVLAN">4095</String> <String name="UnifiedCMIPAddress"><not open></String> <String name="LocalPort">-1</String> <String name="TimeStamp">1289313813826</String> <Enum name="ReasonForOutOfService"></Enum> <String name="LastProtocolEventSent">1:Register</String> <String name="LastProtocolEventReceived">129:RegisterAck</String> </ParameterList> </Alarm> </x-cisco-alarm>
More
If you want one more, file a JIRA ticket or, better yet, submit a patch to add the features. The FreeSWITCH developer team has no Skinny systems against which to test.
Custom Applications
If you want to write a custom application, you can control the phone by using the API. For example:
skinny profile internal device SEP001120AABBCC send UserToDeviceDataVersion1Message sequence-flag=2 '<CiscoIPPhoneText><Title>Hello</Title><Prompt>Amazing</Prompt><Text>This is some text</Text></CiscoIPPhoneText>'
You can also register to event skinny::device_to_user (and others).
Related documentation:
- Complete reference to CiscoIPPhone XML Objects from Cisco's Cisco Unified IP Phone Services Application Development Notes, Release 8.5(1)
- Cisco 79XX XML Services from voip-info.org
- Cisco Unified Communications Manager XML Developers Guide, Release 8.5(1)
Example implementations :
- There is an example XML Directory for Cisco IP Phones PHP application in freeswitch-contrib.git/sathieu/xml-directory.
- Perl's Cisco::IPPhone
- http://fisheye.freeswitch.org/browse/freeswitch-contrib/sathieu/cisco-xml
References
Docs
- Skinny Call Control Protocol (SCCP) - Fragment of a VoIP course dealing with SCCP, with sample captures
- Wireshark's skinny dissector
- SCCP Call Flows from Cisco ATA 186 and Cisco ATA 188 Analog Telephone Adaptor Administrator's Guide (SCCP)
- Call states sent to SCCP endpoints by Cisco CallManager
- Skinny Call Control Protocol (SCCP) - Cisco Systems
Existing implementations
- Asterisk's chan_skinny.c
- Asterisk's out-of tree chan-sccp
- Asterisk's out-of tree chan_sccp2
- Asterisk's out-of tree chan_sccp-b further development of chan_sccp2
- FreeSWITCH's mod_skinny (MODENDP-293)
Skinny Message list
Message | Code | Status in mod_skinny |
---|---|---|
Station -> Callmanager | ||
KeepAliveMessage | 0x0000 | DONE |
RegisterMessage | 0x0001 | DONE |
IpPortMessage | 0x0002 | DONE |
KeypadButtonMessage | 0x0003 | DONE |
EnblocCallMessage | 0x0004 | DONE |
StimulusMessage | 0x0005 | DONE |
OffHookMessage | 0x0006 | DONE |
OnHookMessage | 0x0007 | DONE |
HookFlashMessage | 0x0008 | |
ForwardStatReqMessage | 0x0009 | DONE |
SpeedDialStatReqMessage | 0x000A | DONE |
LineStatReqMessage | 0x000B | DONE |
ConfigStatReqMessage | 0x000C | DONE |
TimeDateReqMessage | 0x000D | DONE |
ButtonTemplateReqMessage | 0x000E | DONE |
VersionReqMessage | 0x000F | DONE |
CapabilitiesResMessage | 0x0010 | DONE |
MediaPortListMessage | 0x0011 | |
ServerReqMessage | 0x0012 | |
AlarmMessage | 0x0020 | DONE |
MulticastMediaReceptionAck | 0x0021 | |
OpenReceiveChannelAck | 0x0022 | DONE |
ConnectionStatisticsRes | 0x0023 | |
OffHookWithCgpnMessage | 0x0024 | |
SoftKeySetReqMessage | 0x0025 | DONE |
SoftKeyEventMessage | 0x0026 | DONE |
UnregisterMessage | 0x0027 | DONE |
SoftKeyTemplateReqMessage | 0x0028 | DONE |
RegisterTokenReq | 0x0029 | |
MediaTransmissionFailure | 0x002A | |
HeadsetStatusMessage | 0x002B | DONE |
MediaResourceNotification | 0x002C | |
RegisterAvailableLinesMessage | 0x002D | DONE |
DeviceToUserDataMessage | 0x002E | DONE |
DeviceToUserDataResponseMessage | 0x002F | DONE |
UpdateCapabilitiesMessage | 0x0030 | |
OpenMultiMediaReceiveChannelAckMessage | 0x0031 | |
ClearConferenceMessage | 0x0032 | |
ServiceURLStatReqMessage | 0x0033 | DONE |
FeatureStatReqMessage | 0x0034 | DONE |
CreateConferenceResMessage | 0x0035 | |
DeleteConferenceResMessage | 0x0036 | |
ModifyConferenceResMessage | 0x0037 | |
AddParticipantResMessage | 0x0038 | |
AuditConferenceResMessage | 0x0039 | |
AuditParticipantResMessage | 0x0040 | |
DeviceToUserDataVersion1Message | 0x0041 | DONE |
DeviceToUserDataResponseVersion1Message | 0x0042 | DONE |
DialedPhoneBookMessage | 0x0048 | Incomplete |
AccessoryStatusMessage | 0x0049 | DONE |
? | 0x004A | |
Callmanager -> Station | ||
RegisterAckMessage | 0x0081 | DONE |
StartToneMessage | 0x0082 | DONE |
StopToneMessage | 0x0083 | DONE |
SetRingerMessage | 0x0085 | DONE |
SetLampMessage | 0x0086 | DONE |
SetHookFlashDetectModeMessage | 0x0087 | |
SetSpeakerModeMessage | 0x0088 | DONE |
SetMicroModeMessage | 0x0089 | |
StartMediaTransmission | 0x008A | DONE |
StopMediaTransmission | 0x008B | DONE |
StartMediaReception | 0x008C | |
StopMediaReception | 0x008D | |
CallInfoMessage | 0x008F | DONE |
ForwardStatMessage | 0x0090 | Incomplete |
SpeedDialStatMessage | 0x0091 | DONE |
LineStatMessage | 0x0092 | DONE |
ConfigStatMessage | 0x0093 | DONE |
DefineTimeDate | 0x0094 | DONE |
StartSessionTransmission | 0x0095 | |
StopSessionTransmission | 0x0096 | |
ButtonTemplateMessage | 0x0097 | DONE |
VersionMessage | 0x0098 | DONE |
DisplayTextMessage | 0x0099 | |
ClearDisplay | 0x009A | |
CapabilitiesReqMessage | 0x009B | DONE |
EnunciatorCommandMessage | 0x009C | |
RegisterRejectMessage | 0x009D | DONE |
ServerResMessage | 0x009E | |
Reset | 0x009F | DONE |
KeepAliveAckMessage | 0x0100 | DONE |
StartMulticastMediaReception | 0x0101 | |
StartMulticastMediaTransmission | 0x0102 | |
StopMulticastMediaReception | 0x0103 | |
StopMulticastMediaTransmission | 0x0104 | |
OpenReceiveChannel | 0x0105 | DONE |
CloseReceiveChannel | 0x0106 | DONE |
ConnectionStatisticsReq | 0x0107 | |
SoftKeyTemplateResMessage | 0x0108 | DONE |
SoftKeySetResMessage | 0x0109 | DONE |
SelectSoftKeysMessage | 0x0110 | DONE |
CallStateMessage | 0x0111 | DONE |
DisplayPromptStatusMessage | 0x0112 | DONE |
ClearPromptStatusMessage | 0x0113 | DONE |
DisplayNotifyMessage | 0x0114 | |
ClearNotifyMessage | 0x0115 | |
ActivateCallPlaneMessage | 0x0116 | DONE |
DeactivateCallPlaneMessage | 0x0117 | |
UnregisterAckMessage | 0x0118 | DONE |
BackSpaceReqMessage | 0x0119 | DONE |
RegisterTokenAck | 0x011A | |
RegisterTokenReject | 0x011B | |
StartMediaFailureDetection | 0x011C | |
DialedNumberMessage | 0x011D | DONE |
UserToDeviceDataMessage | 0x011E | DONE |
FeatureStatMessage | 0x011F | DONE |
DisplayPriNotifyMessage | 0x0120 | DONE |
ClearPriNotifyMessage | 0x0121 | |
StartAnnouncementMessage | 0x0122 | |
StopAnnouncementMessage | 0x0123 | |
AnnouncementFinishMessage | 0x0124 | |
NotifyDtmfToneMessage | 0x0127 | |
SendDtmfToneMessage | 0x0128 | |
SubscribeDtmfPayloadReqMessage | 0x0129 | |
SubscribeDtmfPayloadResMessage | 0x012A | |
SubscribeDtmfPayloadErrMessage | 0x012B | |
UnSubscribeDtmfPayloadReqMessage | 0x012C | |
UnSubscribeDtmfPayloadResMessage | 0x012D | |
UnSubscribeDtmfPayloadErrMessage | 0x012E | |
ServiceURLStatMessage | 0x012F | DONE |
CallSelectStatMessage | 0x0130 | |
OpenMultiMediaChannelMessage | 0x0131 | |
StartMultiMediaTransmission | 0x0132 | |
StopMultiMediaTransmission | 0x0133 | |
MiscellaneousCommandMessage | 0x0134 | |
FlowControlCommandMessage | 0x0135 | |
CloseMultiMediaReceiveChannel | 0x0136 | |
CreateConferenceReqMessage | 0x0137 | |
DeleteConferenceReqMessage | 0x0138 | |
ModifyConferenceReqMessage | 0x0139 | |
AddParticipantReqMessage | 0x013A | |
DropParticipantReqMessage | 0x013B | |
AuditConferenceReqMessage | 0x013C | |
AuditParticipantReqMessage | 0x013D | |
UserToDeviceDataVersion1Message | 0x013F | DONE |
FlowControlCommandMessage | 0x0141 | |
? | 0x0142 | |
? | 0x0143 | |
? | 0x0144 | |
DisplayDynamicPromptStatusMessage | 0x0145 | |
FeatureStatAdvancedMessage | 0x0146 | |
LineStatDynamicMessage | 0x0147 | |
ServiceURLStatDynamicMessage | 0x0148 | |
SpeedDialStatDynamicMessage | 0x0149 | |
CallInfoDynamicMessage | 0x014A | |
DialedPhoneBookAckMessage | 0x0152 | Incomplete |
? | 0x0153 | |
StartMediaTransmissionAck | 0x0154 | |
ExtensionDeviceCaps | 0x0159 | |
XMLAlarmMessage | 0x015A | DONE |
SPARegisterMessage | 0x8000 |