266 lines
7.8 KiB
PowerShell
266 lines
7.8 KiB
PowerShell
param(
|
|
[string]$Extensions = "201,205,206",
|
|
[string]$LogFile = ".\netgescon-tapi-poll.log",
|
|
[int]$IntervalSeconds = 2
|
|
)
|
|
|
|
$TapiMediaTypeAudio = 8
|
|
$TapiEventFilterCallNotification = 4
|
|
$TapiEventFilterCallState = 8
|
|
$TapiEventFilterCallMedia = 16
|
|
$TapiEventFilterCallHub = 32
|
|
$TapiEventFilterCallInfoChange = 64
|
|
$TapiEventFilterPrivate = 128
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Get-SafeProperty {
|
|
param(
|
|
[Parameter(Mandatory = $true)] $Object,
|
|
[Parameter(Mandatory = $true)] [string]$Name
|
|
)
|
|
|
|
try {
|
|
return $Object.$Name
|
|
}
|
|
catch {
|
|
return $null
|
|
}
|
|
}
|
|
|
|
function Get-SafeCallInfoString {
|
|
param(
|
|
[Parameter(Mandatory = $true)] $Call,
|
|
[Parameter(Mandatory = $true)] [int]$Id
|
|
)
|
|
|
|
try {
|
|
return [string]$Call.CallInfoString($Id)
|
|
}
|
|
catch {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
function Get-SafeMethodResult {
|
|
param(
|
|
[Parameter(Mandatory = $true)] $Object,
|
|
[Parameter(Mandatory = $true)] [string]$MethodName,
|
|
[object[]]$Arguments = @()
|
|
)
|
|
|
|
try {
|
|
return $Object.GetType().InvokeMember($MethodName, [System.Reflection.BindingFlags]::InvokeMethod, $null, $Object, $Arguments)
|
|
}
|
|
catch {
|
|
return $null
|
|
}
|
|
}
|
|
|
|
function Try-RegisterCallNotifications {
|
|
param(
|
|
[Parameter(Mandatory = $true)] $Tapi,
|
|
[Parameter(Mandatory = $true)] $Address,
|
|
[Parameter(Mandatory = $true)] [bool]$Monitor,
|
|
[Parameter(Mandatory = $true)] [bool]$Owner
|
|
)
|
|
|
|
try {
|
|
$cookie = $Tapi.RegisterCallNotifications($Address, $Monitor, $Owner, $TapiMediaTypeAudio, 0)
|
|
return [pscustomobject]@{
|
|
Ok = $true
|
|
Cookie = $cookie
|
|
Error = ''
|
|
}
|
|
}
|
|
catch {
|
|
return [pscustomobject]@{
|
|
Ok = $false
|
|
Cookie = $null
|
|
Error = $_.Exception.Message
|
|
}
|
|
}
|
|
}
|
|
|
|
function Convert-ComCollectionToArray {
|
|
param($Collection)
|
|
|
|
$items = @()
|
|
if ($null -eq $Collection) {
|
|
return $items
|
|
}
|
|
|
|
try {
|
|
foreach ($item in $Collection) {
|
|
$items += $item
|
|
}
|
|
}
|
|
catch {
|
|
}
|
|
|
|
return $items
|
|
}
|
|
|
|
function Normalize-ExtensionToken {
|
|
param([string]$Value)
|
|
|
|
if ($null -eq $Value) {
|
|
$trimmed = ''
|
|
}
|
|
else {
|
|
$trimmed = [string]$Value
|
|
}
|
|
$trimmed = $trimmed.Trim()
|
|
if ($trimmed -eq '') {
|
|
return ''
|
|
}
|
|
|
|
if ($trimmed -match '(\d+)$') {
|
|
return $matches[1].TrimStart('0')
|
|
}
|
|
|
|
return $trimmed
|
|
}
|
|
|
|
function Should-WatchAddress {
|
|
param(
|
|
[Parameter(Mandatory = $true)] $Address,
|
|
[Parameter(Mandatory = $true)] [string[]]$WatchList
|
|
)
|
|
|
|
$dial = [string](Get-SafeProperty -Object $Address -Name 'DialableAddress')
|
|
$name = [string](Get-SafeProperty -Object $Address -Name 'AddressName')
|
|
|
|
$dialToken = Normalize-ExtensionToken -Value $dial
|
|
$nameToken = Normalize-ExtensionToken -Value $name
|
|
|
|
foreach ($watch in $WatchList) {
|
|
$watchToken = Normalize-ExtensionToken -Value $watch
|
|
if ($watchToken -eq '') {
|
|
continue
|
|
}
|
|
|
|
if ($dialToken -eq $watchToken -or $nameToken -eq $watchToken) {
|
|
return $true
|
|
}
|
|
}
|
|
|
|
return $false
|
|
}
|
|
|
|
function Write-LogLine {
|
|
param([string]$Text)
|
|
|
|
$line = "{0} | {1}" -f (Get-Date).ToString('yyyy-MM-dd HH:mm:ss'), $Text
|
|
Add-Content -Path $script:LogFilePath -Value $line -Encoding UTF8
|
|
Write-Host $line
|
|
}
|
|
|
|
function Get-CallHubSnapshot {
|
|
param([Parameter(Mandatory = $true)] $Tapi)
|
|
|
|
$snapshots = @()
|
|
$hubs = Convert-ComCollectionToArray -Collection (Get-SafeProperty -Object $Tapi -Name 'CallHubs')
|
|
foreach ($hub in @($hubs)) {
|
|
$calls = Convert-ComCollectionToArray -Collection (Get-SafeProperty -Object $hub -Name 'Calls')
|
|
$snapshots += [pscustomobject]@{
|
|
HubType = $hub.GetType().FullName
|
|
CallCount = @($calls).Count
|
|
}
|
|
}
|
|
|
|
return @($snapshots)
|
|
}
|
|
|
|
$watchList = @($Extensions.Split(',') | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' })
|
|
$script:LogFilePath = $LogFile
|
|
|
|
$tapi = New-Object -ComObject TAPI.TAPI
|
|
$tapi.Initialize()
|
|
$tapi.EventFilter = $TapiEventFilterCallNotification + $TapiEventFilterCallState + $TapiEventFilterCallMedia + $TapiEventFilterCallHub + $TapiEventFilterCallInfoChange + $TapiEventFilterPrivate
|
|
|
|
$allAddresses = Convert-ComCollectionToArray -Collection $tapi.Addresses
|
|
$addresses = @($allAddresses | Where-Object {
|
|
Should-WatchAddress -Address $_ -WatchList $watchList
|
|
})
|
|
|
|
if ($addresses.Count -eq 0) {
|
|
throw "Nessun indirizzo TAPI trovato per le estensioni: $Extensions"
|
|
}
|
|
|
|
Write-LogLine "=== AVVIO POLL TAPI ==="
|
|
Write-LogLine "Watch list: $Extensions"
|
|
Write-LogLine "Provider addresses totali: $($allAddresses.Count)"
|
|
Write-LogLine "Provider addresses filtrati: $($addresses.Count)"
|
|
$registrationCookies = @()
|
|
foreach ($address in $addresses) {
|
|
$addressName = [string](Get-SafeProperty -Object $address -Name 'AddressName')
|
|
$dial = [string](Get-SafeProperty -Object $address -Name 'DialableAddress')
|
|
$provider = [string](Get-SafeProperty -Object $address -Name 'ServiceProviderName')
|
|
Write-LogLine ("ADDRESS READY name={0} dial={1} provider={2}" -f $addressName, $dial, $provider)
|
|
|
|
$registration = Try-RegisterCallNotifications -Tapi $tapi -Address $address -Monitor $true -Owner $true
|
|
if ($registration.Ok) {
|
|
$registrationCookies += $registration.Cookie
|
|
Write-LogLine ("REGISTER OK mode=monitor+owner cookie={0} address={1} dial={2}" -f $registration.Cookie, $addressName, $dial)
|
|
}
|
|
else {
|
|
Write-LogLine ("REGISTER KO address={0} dial={1} error={2}" -f $addressName, $dial, $registration.Error)
|
|
}
|
|
}
|
|
|
|
$lastSnapshot = @{}
|
|
$lastHubSignature = "__UNSET__"
|
|
|
|
while ($true) {
|
|
$hubSnapshot = Get-CallHubSnapshot -Tapi $tapi
|
|
$hubSignature = (($hubSnapshot | ForEach-Object { "{0}:{1}" -f $_.HubType, $_.CallCount }) -join '|')
|
|
if ($hubSignature -ne $lastHubSignature) {
|
|
$hubText = $hubSignature
|
|
if ($hubText -eq '') {
|
|
$hubText = 'none'
|
|
}
|
|
Write-LogLine ("CALLHUBS {0}" -f $hubText)
|
|
$lastHubSignature = $hubSignature
|
|
}
|
|
|
|
foreach ($address in $addresses) {
|
|
$addressName = [string](Get-SafeProperty -Object $address -Name 'AddressName')
|
|
$dial = [string](Get-SafeProperty -Object $address -Name 'DialableAddress')
|
|
$calls = @(Convert-ComCollectionToArray -Collection (Get-SafeProperty -Object $address -Name 'Calls'))
|
|
|
|
if ($calls.Count -eq 0) {
|
|
$key = "$addressName|$dial"
|
|
if (-not $lastSnapshot.ContainsKey($key) -or $lastSnapshot[$key] -ne 'IDLE') {
|
|
Write-LogLine ("IDLE address={0} dial={1}" -f $addressName, $dial)
|
|
$lastSnapshot[$key] = 'IDLE'
|
|
}
|
|
continue
|
|
}
|
|
|
|
$index = 0
|
|
foreach ($call in $calls) {
|
|
$index++
|
|
$state = Get-SafeProperty -Object $call -Name 'State'
|
|
if ($null -eq $state) {
|
|
$state = Get-SafeProperty -Object $call -Name 'CallState'
|
|
}
|
|
|
|
$caller = Get-SafeCallInfoString -Call $call -Id 14
|
|
$called = Get-SafeCallInfoString -Call $call -Id 15
|
|
$connected = Get-SafeCallInfoString -Call $call -Id 16
|
|
|
|
$signature = "state=$state;caller=$caller;called=$called;connected=$connected"
|
|
$key = "$addressName|$dial|$index"
|
|
|
|
if (-not $lastSnapshot.ContainsKey($key) -or $lastSnapshot[$key] -ne $signature) {
|
|
Write-LogLine ("CALL address={0} dial={1} idx={2} state={3} caller={4} called={5} connected={6}" -f $addressName, $dial, $index, $state, $caller, $called, $connected)
|
|
$lastSnapshot[$key] = $signature
|
|
}
|
|
}
|
|
}
|
|
|
|
Start-Sleep -Seconds $IntervalSeconds
|
|
}
|