|
Jun24Written by:Martin 24.06.2011 15:00  For my PowerShell session at Swyx Technology Conference I prepared an additional demo. I didn’t show it, because there was no time and most of the audience had little experience with PowerShell anyway. This demo uses the APIs described in the SwyxIt! Client SDK to consume events from SwyxIt! and uses that to display state changes of every speed dial key the current user has configured. In order to do this you first have to create a .NET runtime callable wrapper for the API using tlbimp.exe from the Microsoft .Net Framework SDK. Using the ClientLineManager object via this interop assembly, SwyxIt! events can easily be consumed using PowerShell’s eventing support. To do so you - Create a new ClientlineManager object (demo3.ps1, line 12)
- Subscribe to an event, in this case the DispOnLineMgrNotification event on the ClientLineMgr object (demo3.ps1, line 15)
- Wait for events (clmgr-utilities.ps1, line 103)
- Check for type of event and handle it accordingly
This is a proof of concept. I did it, because I can, not because it’s the best way to program against the ClMgr-API. That being said: Enjoy  demo3.ps1 - $ScriptFolder = (split-path $MyInvocation.MyCommand.Path -Parent)
- . (join-path $ScriptFolder "clmgr-utilities.ps1")
-
- import-module ippbx
-
- function get-SpeedDialKeyStateChange
- {
- param([string[]]$SpeedDialKeyNames,
- [Clmgr.CLMgrNameKeyStates[]]$States = $null)
-
- BEGIN {
- $clmgr = new-object "CLMgr.ClientLineMgrClass"
-
- # register for line manager events
- Register-ObjectEvent -InputObject $clmgr -EventName DispOnLineMgrNotification
-
- # get speed dial key definitions
- $blob = new-object "IpPbxBlob.UserSettings"
- $Bytes = $clmgr.DispClientConfig.ConfigBuffer
- if ($Bytes) { [void]$Blob.SetBLOB($Bytes) }
- $SpeedDialKeys = $Blob.m_NameKeySettings
- }
-
- PROCESS {
- do {
- $event = wait-ClmgrEvent -MessageTypes "NameKeyStateChangedMessage","ClientShutDownRequest"
- if ($Event.sourceargs[0] -eq [clmgr.clmgrmessage]::NameKeyStateChangedMessage)
- {
- # $message parameter is speed dial key index which has changed, get state
- $idx = $Event.SourceArgs[1]
- $SpeedDialKeyState = 0
- if ($idx -gt 0)
- {
- $clmgr.GetNamekeyState($Event.SourceArgs[1], [ref] $SpeedDialKeyState)
- $Name = $SpeedDialKeys[$idx].Title
- if (!$Name) { $Name = $SpeedDialKeys[$idx].DialNumber }
- if ((!$SpeedDialKeyNames -or $SpeedDialKeyNames -contains $Name) -and (!$States -or $States -contains $SpeedDialKeyState))
- {
- new-object "PSObject" |
- Add-Member -Name "Index" -Value $idx -MemberType NoteProperty -PassThru |
- Add-Member -Name "Title" -Value $Name -MemberType NoteProperty -PassThru |
- Add-Member -Name "State" -Value $SpeedDialKeyState -MemberType NoteProperty -PassThru
- }
- }
- }
- $Event | remove-event
- } while ($Event.sourceargs[0] -ne [clmgr.clmgrmessage]::ClientShutDownRequest)
- }
-
- END {
- Get-EventSubscriber | Where-Object { $_.EventName -eq "DispOnLineMgrNotification" } | Unregister-Event
- $clmgr = $null
- }
- }
-
- get-SpeedDialKeyStateChange | format-table
clmgr-utilities.ps1 - $ScriptFolder = (split-path $MyInvocation.MyCommand.Path -Parent)
- . (join-path $ScriptFolder "custom-enum.ps1")
-
- add-type -path (join-path $ScriptFolder "Interop.Clmgr.dll")
-
- # clmgr event type
- Add-Enum -erroraction SilentlyContinue -nameSpace Clmgr -name ClMgrMessage -values @(
- "LineStateChangedMessage"; # state of a line has changed"
- "LineSelectionChangedMessage"; # line selection has changed = "; new line in focus"
- "LineDetailsChangedMessage"; # details of line has changed"
- "UserDataChangedMessage"; # user configuration has changed"
- "CallDetailsMessage"; # details of last call are available = "; after disconnect = "; for logging purpose"
- "ServerDownMessage"; # server is down = "; will be rebooted = "; ..."
- "ServerUpMessage"; # server is up again -> keep interfaces to line manger
- "WaveDeviceChanged"; # speaker and / or micro has been switched on or off
- "GroupCallNotificationMessage"; # notification about signaled call we could pick up now
- "NameKeyStateChangedMessage"; # notification about changed namekey state
- "NumberOfLinesChangedMessage"; # the number of lines has changed
- "ClientShutDownRequest"; # Client Line Manager requests client to shutdown and release all interfaces
- "PowerSuspendMessage"; # client machine goes to hibernate or suspend mode
- "PowerResumeMessage"; # client machine has returned from suspend mode -> keep interfaces to line manager
- "HandsetStateChangedMessage"; # state of handset has changed
- "SkinPhoneCommandMessage"; # for forwarding commands from PlugIn to SwyxIt!.exe.
- "SkinActionAreaStateChangedMessage"; # informing clients about a changed action area state.
- "SkinInfoDetailChangedMessage"; # informing clients about changed information area details.
- "CallbackOnBusyNotification"; # informing clients about available callback on busy
- "AsyncMessage"; # message for reporting success or problems that occured within state machine / were reported by server
- "CtiPairingStateChanged"; # informing clients about changed state of CTI pairing process
- "ChatMessage"; # for call clients that have registered as chat message receiver: new message available
- "ChatMessageAck"; # for call clients that have registered as chat message receiver:
- "RecordingError"; # Error on recording conversation
- "VolumeChanged"; # Volume of sound device has changed
- "AudioModeChanged"; # Current audio mode has changed
- "MicAdjustLevelMeter"; # Peak level meter during microphone adjustment
- "MicAdjustProceedMeter"; # Proceed level during microphone adjustment
- "LineStateChangedMessageEx"; # state of at least line has changed
- "PlaySoundFileDxProceedMeter"; # Proceed level during PlaySoundFileDx playback
- "SIPRegistrationStateChanged"; # registration state of SIP account has changed
- "WaveFilePlayed"; # wave file playback finished
- "FirstDataReceived"; # wave file playback finished
- "RegisteredSipDeviceListChanged"; # number of registered dialer mode compatible (SIP) devices for own user changed
- "DialerStartCallResult"; # message for reporting start call success or failure in dialer mode
- "LineStateChangedMessageEx2"; # state of at least line has changed
- "MediaEncryptionStatusChanged"; # media encryption state has changed
- )
-
- Add-Enum -erroraction SilentlyContinue -namespace Clmgr -name ClMgrLineState -values @(
- "Inactive"; # line is inactive
- "HookOffInternal"; # off hook, internal dialtone
- "HookOffExternal"; # off hook, external dialtone
- "Ringing"; # incoming call, ringing
- "Dialing"; # outgoing call, we are dialing"; no sound
- "Alerting"; # outgoing call, alerting = ringing on destination
- "Knocking"; # outgoing call, knocking = second call ringing on destination
- "Busy"; # outgoing call, destination is busy
- "Active"; # incoming / outgoing call, logical and physical connection is established
- "OnHold"; # incoming / outgoing call, logical connection is established"; destination gets music on hold
- "ConferenceActive"; # incoming / outgoing conference, logical and physical connection is established
- "ConferenceOnHold"; # incoming / outgoing conference, logical connection is established"; not physcically connected
- "Terminated"; # incoming / outgoing connection / call has been disconnected
- "Transferring"; # special LSOnHold, call is awaiting to be transferred"; peer gets special music on hold
- "Disabled"; # special LSInactive, wrap up time"; we will temporary not allow calls on that line
- "DirectCall" # incoming call logical and physical connection is established micro is muted
- )
-
- Add-enum -erroraction SilentlyContinue -namespace Clmgr -name ClmgrDisconnectReason -values @(
- "Normal"; # nothing special
- "Busy"; # peer was busy
- "Rejected"; # peer rejected call
- "Cancelled"; # call was cancelled
- "Transferred"; # call was transferred (connect to peers with "PubTransferCall")
- "JoinedConference"; # call was added to conference on other line with "PubJoinConference"
- "NoAnswer"; # peer did not pick up"; timeout
- "TooLate"; # call was already picked up from other phone
- "DirectCallImpossible"; # direct call to peer was not allowed
- "WrongNumber"; # invalid number was dialed
- "Unreachable"; # destination is unreachable
- "CallDiverted"; # call was redirected
- "CallRoutingFailed"; # call routing failed"; possible script error (script of peer)
- "PermissionDenied"; # permission for call was denied due to call restrictions (e.g. no long distance call allowed)
- "NetworkCongestion"; # no line available (within ISDN network)
- "NoChannelAvailable"; # no gateway channel available
- "NumberChanged"; # the number of the called party has changed
- "IncompatibleDestination";# the device type of the called party is incompatible
- "BadAddressFormat"; # wrong phone number format"; e.g. bad character
- )
-
-
- <#
- .Synopsis
- Wait for client line manager event
- .Description
- Wait for an event send from clmgr.exe via the client API
- .Parameter Eventfilter
- ScriptBlock to filter events. If it returns $true event will be returned. ScriptBlock gets two int parameter $Message and $MessageParam.
- The first defines the type of event, the second is an event specific parameter. See Client SDK for details
- .Example
- wait-event
- #>
- function wait-ClmgrEvent
- {
- param([System.Management.Automation.ScriptBlock]$EventFilter = { $true },
- [Clmgr.ClmgrMessage[]]$MessageTypes = $null,
- [int]$Timeout = -1
- )
-
- $SourceID = (Get-EventSubscriber | Where-Object { $_.EventName -eq "DispOnLineMgrNotification" } | select -first 1).SourceIdentifier
-
- $StartTime = get-date
- $TimeoutExceeded = $false
- do
- {
- $event = wait-event -SourceIdentifier $SourceID -Timeout 1
- if ($event)
- {
- $Message = $Event.SourceArgs[0]
- $MessageParam = $Event.SourceArgs[1]
-
- if ($MessageTypes)
- {
- $EventMatches = $MessageTypes -contains $Message
- }
- else
- {
- $EventMatches = $EventFilter.Invoke(@($Message,$MessageParam))
- }
- }
-
- if ($Timeout -ne -1)
- {
- $TimeoutExceeded = (((get-date) - $StartTime).TotalSeconds) -gt $timeout
- }
-
- if ($Event -and !$EventMatches)
- {
- $Event | remove-event
- }
- } while ( !$EventMatches -and !$TimeoutExceeded)
-
- if (!$TimeoutExceeded)
- {
- $event
- }
- }
Download the whole demo here: Tags: |
|