.Net API to get Extension Status

Discussion in '3CX Phone System - General' started by aspiq, Mar 2, 2012.

Thread Status:
Not open for further replies.
  1. aspiq

    Joined:
    Jun 14, 2010
    Messages:
    9
    Likes Received:
    0
    Hi
    Could some body guide me on how I can use the .NET API for 3CX to get the current status of phone extensions. Whether they are Registered(idle), Ringing or Connected

    If we can get this information, then we can from our program call the Makecall utility and make it to transfer the call to the extension which is Registered (idle)

    The status is as in the Management Console - Extension status
     
  2. aspiq

    Joined:
    Jun 14, 2010
    Messages:
    9
    Likes Received:
    0
    Hi

    After working on this for two days, we have managed to do it
    Thought I would share with the forum

    Here is the below code in VB.NET which would help with you the above


    Imports TCX.PBXAPI
    Imports TCX.Configuration ' Add a reference of 3cxpscomcpp2.dll to your project
    Imports System.Text
    Imports Microsoft.Win32
    Imports System.IO

    Public Class Form1
    Private Declare Function GetKeyValueA Lib "kernel32.dll" Alias "GetPrivateProfileStringA" (ByVal strSection As String, ByVal strKeyName As String, ByVal strNull As String, ByVal RetVal As StringBuilder, ByVal nSize As Integer, ByVal strFileName As String) As Integer
    'Public Delegate Sub UpdateConnectDlg(ByVal newConn As Integer)
    'Dim _activeConnDict As Dictionary(Of Integer, ActiveConnection)
    'Dim _queueConnDict As Dictionary(Of Integer, ActiveConnection)
    'Dim _stopUpdates As Boolean
    '#Region "Phone"

    Public ResultArray As New ArrayList
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    InitializeComponent()
    '_activeConnDict = New Dictionary(Of Integer, ActiveConnection)
    '_queueConnDict = New Dictionary(Of Integer, ActiveConnection)
    '_stopUpdates = True
    End Sub
    Protected Overrides Sub OnLoad(ByVal e As EventArgs)
    Try
    PhoneSystem.ApplicationName = "CallViewer"
    Dim regKeyAppRoot As RegistryKey
    If (IntPtr.Size = 4) Then
    regKeyAppRoot = Registry.LocalMachine.OpenSubKey("SOFTWARE\\3CX\\PhoneSystem")
    Else
    regKeyAppRoot = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node\\3CX\\PhoneSystem")
    End If
    Dim _appPath As String = CType(regKeyAppRoot.GetValue("AppPath"), String)
    Dim filePath As String = Path.Combine(_appPath, "Bin\3CXPhoneSystem.ini")
    Dim value As String = GetKeyValue("ConfService", "ConfPort", filePath)
    Dim port As Int32 = 0
    If Not String.IsNullOrEmpty(value) Then
    Int32.TryParse(value.Trim, port)
    PhoneSystem.CfgServerPort = port
    End If
    value = GetKeyValue("ConfService", "confUser", filePath)
    If Not String.IsNullOrEmpty(value) Then
    PhoneSystem.CfgServerUser = value
    End If
    value = GetKeyValue("ConfService", "confPass", filePath)
    If Not String.IsNullOrEmpty(value) Then
    PhoneSystem.CfgServerPassword = value
    End If

    Dim tenantArr() As Tenant = PhoneSystem.Root.GetTenants
    If (tenantArr.Length = 0) Then
    MessageBox.Show("Corrupted database")
    Return
    End If
    Dim dnArr() As DN = tenantArr(0).GetDN

    'Dim connArr() As ActiveConnection
    Dim DnRegistered As New ArrayList
    Dim NoOfActiveConn As Int16 = 0
    Dim DnConnArr As New ArrayList

    For Each dn As DN In dnArr
    If dn.GetType.ToString = "TCX.Configuration.Extension" And dn.IsRegistered = True Then
    DnRegistered.Add(dn.Number)
    End If

    For Each dn1 In dn.GetActiveConnections
    If dn.GetType.ToString = "TCX.Configuration.Extension" Then
    Dim ExtNo As String = ""
    ExtNo = dn1.DN.Number
    DnConnArr.Add(ExtNo)
    End If
    Next
    Next

    Dim FreeExt As New ArrayList
    FreeExt = CompareArrays(DnRegistered, DnConnArr)

    For l = 0 To FreeExt.Count - 1
    MsgBox(FreeExt.Item(l).ToString)
    Next

    Catch ex As Exception
    MessageBox.Show(String.Format("{0} {1}", ex.Message, ex.StackTrace))
    End Try
    End Sub
    Function CompareArrays(ByVal FistArray As ArrayList, ByVal SecondArray As ArrayList) As ArrayList
    'Dim ResultArray As New ArrayList
    Dim sItem As String

    If SecondArray.Count = 0 Then
    ResultArray = FistArray
    Return ResultArray
    End If

    For Each sItem In FistArray
    If Not SecondArray.Contains(Trim(sItem)) Then
    ResultArray.Add(sItem)
    End If
    Next

    Return ResultArray
    End Function
    Public Shared Function GetKeyValue(ByVal Section As String, ByVal KeyName As String, ByVal FileName As String) As String
    'Reading The KeyValue Method
    Try
    Dim JStr As StringBuilder = New StringBuilder(255)
    Dim i As Integer = GetKeyValueA(Section, KeyName, String.Empty, JStr, 255, FileName)
    Return JStr.ToString
    Catch e As System.Exception
    Throw e
    End Try
    End Function
    End Class
     
  3. aspiq

    Joined:
    Jun 14, 2010
    Messages:
    9
    Likes Received:
    0
    Hi

    Could some body help me with the Event Handlers in the ActiveCalls_QueueCalls API

    While we have been able to convert the above example to VB.NET and have even posted it, we are having problem invoking the events in them

    When we convert it to VB the events are not firing

    what is the equivalent for the following C# in VB

    PhoneSystem.Root.Inserted += new NotificationEventHandler(Root_Updated);

    how to attach the notificatioEvent handler and Root Updated to the Phonesystem.Root.Instered in VB.NET


    Looking forward to some help from the forum
     
  4. cloidhamer

    Joined:
    Jan 30, 2009
    Messages:
    27
    Likes Received:
    0
    I'm not sure how the version 10 api works, but here is how I did it on the version 9 API. I store all my data in datatables and updates every half second. Then when you need data you simply make a call to the datatable. It actually runs quite efficiently and has a very low CPU and memory load.


    Public Ds As New DataSet
    Public ExtTbl As DataTable = Ds.Tables.Add()
    Public CnnTbl As DataTable = Ds.Tables.Add()
    Public DevTbl As DataTable = Ds.Tables.Add()

    Dim oCallback As New TimerCallback(AddressOf Tmr_Elapsed)
    Public Tmr = New System.Threading.Timer(oCallback, Nothing, 500, 500)

    Private WithEvents EnumExt As New System.ComponentModel.BackgroundWorker

    'Dim oCBack As New TimerCallback(AddressOf DevTmr_Elapsed)
    'Public DevTmr = New System.Threading.Timer(oCBack, Nothing, 5000, 3600000)

    Dim Counter As Integer = 0
    Dim DevCounter As Integer = 0

    Public Cnn As String = "" 'DB connection
    Public DBPwd As String = ""

    Sub Tmr_Elapsed(ByVal state As Object)
    Try
    If TCX.Configuration.PhoneSystem.Root.Connected = False Then ps.Root.Connect()
    Catch ex As Exception
    Debug.Print(ex.Message)
    End Try

    If EnumExt.IsBusy = False Then
    EnumExt.RunWorkerAsync()
    'Debug.Print("refreshed")
    Else
    'Debug.Print("Busy")
    End If

    End Sub

    'Sub DevTmr_Elapsed(ByVal state As Object)
    ' 'EnumDevices()
    'End Sub

    Public Sub ActiveConnections()
    Dim TDS As New DataSet()
    Dim ConnTbl As DataTable = TDS.Tables.Add()

    ConnTbl.Columns.Add("Ext", GetType(String))
    ConnTbl.Columns.Add("Change", GetType(String))
    ConnTbl.Columns.Add("Status", GetType(String))
    ConnTbl.Columns.Add("CallID", GetType(String))
    ConnTbl.Columns.Add("Caller", GetType(String))
    ConnTbl.Columns.Add("Type", GetType(String))

    Dim conns As ActiveConnection() = ps.GetActiveConnections

    Dim AC As ActiveConnection
    For Each AC In conns
    ConnTbl.Rows.Add(AC.DN.Number, AC.CallID, AC.LastChangeStatus, CInt(AC.Status), AC.ExternalParty, "Call")
    Next
    If Not (CnnTbl Is Nothing) Then CnnTbl.Dispose()
    CnnTbl = ConnTbl
    ConnTbl.Dispose()
    conns = Nothing
    AC = Nothing
    End Sub

    Private Sub EnumExt_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles EnumExt.DoWork

    Dim TDS As New DataSet()
    Dim ExtTable As DataTable = TDS.Tables.Add()
    Dim ConnTbl As DataTable = TDS.Tables.Add()


    ConnTbl.Columns.Add("Ext", GetType(String))
    ConnTbl.Columns.Add("Change", GetType(String))
    ConnTbl.Columns.Add("Status", GetType(String))
    ConnTbl.Columns.Add("CallID", GetType(String))
    ConnTbl.Columns.Add("Caller", GetType(String))
    ConnTbl.Columns.Add("Type", GetType(String))
    ConnTbl.Columns.Add("Outbound", GetType(String))

    ExtTable.Columns.Add("Ext", GetType(String))
    ExtTable.Columns.Add("Group", GetType(String))
    ExtTable.Columns.Add("Desc", GetType(String))
    ExtTable.Columns.Add("Reg", GetType(String))
    ExtTable.Columns.Add("Status", GetType(String))
    ExtTable.Columns.Add("Type", GetType(String))
    ExtTable.Columns.Add("", GetType(String))

    Dim d As DN() = ps.GetExtensions

    For x = 0 To d.GetUpperBound(0)
    Dim ext As TCX.Configuration.Extension = d(x), Grp As String = ""
    If ext.Groups.Length > 0 Then Grp = ext.Groups(0).Name
    Try
    ExtTable.Rows.Add(d(x).Number, Grp, d(x).ToString, CInt(ext.UserStatus), CInt(d(x).IsRegistered), "Ext", "")
    Catch ex As Exception

    End Try
    Dim conns As ActiveConnection() = d(x).GetActiveConnections()
    Dim AC As ActiveConnection
    For Each AC In conns
    Try
    ConnTbl.Rows.Add(AC.DN.Number, AC.CallID, AC.LastChangeStatus, CInt(AC.Status), AC.ExternalParty, "Call", CInt(AC.IsOutbound))
    Catch ex As Exception

    End Try
    Next
    Next

    Try
    ExtTbl.Dispose()
    CnnTbl.Dispose()
    Catch ex As Exception

    End Try

    ExtTbl = ExtTable
    CnnTbl = ConnTbl

    TDS.Dispose()
    ExtTable.Dispose()
    ConnTbl.Dispose()
    TDS.Dispose()

    End Sub

    Public Sub EnumDevices()
    Dim TDS As New DataSet()
    Dim DeviceTbl As DataTable = TDS.Tables.Add()

    DeviceTbl.Columns.Add("Ext", GetType(String))
    DeviceTbl.Columns.Add("IP", GetType(String))

    Dim Dev As DeviceInfo() = ps.GetDetectedDevices

    Dim D As DeviceInfo
    For Each D In Dev
    DeviceTbl.Rows.Add(D.UserAgent, D.NetworkAddress)
    Next

    DevTbl.Dispose()
    DevTbl = DeviceTbl
    DeviceTbl.Dispose()
    TDS.Dispose()
    End Sub

    Public Sub GetDbConnection()

    Dim appDir As String = "C:\Program Files (x86)\3CX PhoneSystem\Bin\3CXPhoneSystem.ini"
    Dim objReader As New System.IO.StreamReader(appDir)

    Dim Txt As String = ""

    Do While objReader.Peek() <> -1
    Txt = objReader.ReadLine
    If Strings.Left(Txt, 11) = "dbPassword=" Then
    DBPwd = Strings.Right(Txt, Len(Txt) - 11)
    End If
    Loop


    Cnn = "Server=127.0.0.1;Port=5480;Database=phonesystem;User Id=phonesystem;Password=" & DBPwd & ";"

    End Sub
     
Thread Status:
Not open for further replies.