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 }