Public Class Form1
    Public env As VBSIPPABXEnv
    Public Extensions() As Extension

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Extensions = New Extension(4) {}

        Extensions(0) = New Extension()
        Extensions(0).Username = "101"
        Extensions(0).Password = "101"

        Extensions(1) = New Extension()
        Extensions(1).Username = "102"
        Extensions(1).Password = "102"

        Extensions(2) = New Extension()
        Extensions(2).Username = "103"
        Extensions(2).Password = "103"

        Extensions(3) = New Extension()
        Extensions(3).Username = "104"
        Extensions(3).Password = "104"

        btnStartServer.Enabled = True
        btnStopServer.Enabled = False

        tb101Status.Enabled = False
        tb101At.Enabled = False

        tb102Status.Enabled = False
        tb102At.Enabled = False

        tb103Status.Enabled = False
        tb103At.Enabled = False

        tb104Status.Enabled = False
        tb104At.Enabled = False

        timer1.Enabled = False

    End Sub

    Private Sub btnStartServer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartServer.Click
        btnStartServer.Enabled = False
        btnStopServer.Enabled = True
        InitSIPServer()

        tb101Status.Enabled = True
        tb101At.Enabled = True

        tb102Status.Enabled = True
        tb102At.Enabled = True

        tb103Status.Enabled = True
        tb103At.Enabled = True

        tb104Status.Enabled = True
        tb104At.Enabled = True

        Timer1.Enabled = True

    End Sub

    Private Sub btnStopServer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStopServer.Click
        Timer1.Enabled = False

        btnStartServer.Enabled = True
        btnStopServer.Enabled = False
        FreeSIPServer()

        tb101Status.Enabled = False
        tb101At.Enabled = False

        tb102Status.Enabled = False
        tb102At.Enabled = False

        tb103Status.Enabled = False
        tb103At.Enabled = False

        tb104Status.Enabled = False
        tb104At.Enabled = False


    End Sub

    Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
        If (btnStopServer.Enabled) Then
            Timer1.Enabled = False

            btnStartServer.Enabled = True
            btnStopServer.Enabled = False

            FreeSIPServer()
        End If
        Close()

    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        env.ProcessGTAPIEvent()
    End Sub


    Public Sub InitSIPServer()
        env = New VBSIPPABXEnv()
        env.m_pMainWnd = Me
        env.CreateEnv()
        env.SetMainWnd(Me.Handle)


        env.CFG_SetValue("gtsrv.sip.server.model", "1") 'server application As 

        'SIP IP Address you want to use on local
        'Leave it unset if you want to listen on all the network interface
        'CFG_SetValue("gtsrv.sip.ip.address", "");

        'SIP Port, default 5060
        env.CFG_SetValue("gtsrv.sip.ip.port", "5060")

        'RTP PORT
        env.CFG_SetValue("gtsrv.sip.rtpstartrange", "8400")
        env.CFG_SetValue("gtsrv.sip.rtpendrange", "8800")

        'Log
        env.CFG_SetValue("gtsrv.log.level", "4")

        env.CFG_SetValue("gtsrv.log.filename", Application.StartupPath + "\\CSSIPPABX-log.txt")

        'channnel numbers, here we only use 4 channel
        env.CFG_SetValue("gtsrv.sip.boardnum.per.server", "1")
        env.CFG_SetValue("gtsrv.sip.spannum.per.board", "1")
        env.CFG_SetValue("gtsrv.sip.channum.per.span", "4") '             
        '             #We don’t recommend you set "gtsrv.sip.channum.per.span" more than 16.
        '             #Sugguested Configuration of CHANNELS, SPANS, and Boards:
        '             #Channels	gtsrv.sip.channum.per.span	gtsrv.sip.spannum.per.board	gtsrv.sip.boardnum.per.server
        '             #4			4				1				1
        '             #8			8				1				1
        '             #16			8				2				1
        '             #24			8				3				1
        '             #32			8				4				1
        '             #40			8				5				1
        '             #64			8				8				1
        '             #128			8				8				2
        '             #256			8				8				4
        '             #512			16				8				4 
        '             */

        'only use 20ms codecs
        env.CFG_SetValue("gtsrv.sip.prefered.codec", "3,0,8")

        'Internal communication port
        env.CFG_SetValue("gtsrv.net.port", "8934")

        'Configuration file, if you want to define parameters in a file
        'env.CFG_SetValue(GTSRV_CFG_FILENAME, "GTSimpelPhone.ini");

        'Application name, it is related to sdk licence
        'Please contact PCBest Network(www.pcbest.net) to get licence info
        env.SetAppName("CSSIPRegServer")

        'define outbound route, leave them unset if you don't know
        'env.CFG_SetValue("gtsrv.sip.outbound.via.type", "0");
        'env.CFG_SetValue("gtsrv.sip.outbound.via.proxy", "");

        'set sip client user info here
        'here it is actually your SIP trunk registration info, means you get this account from other SIP server/proxy,
        'and register to outside SIP server/proxy as a SIP client. 
        'We comment them out here as it is not the purpose of this sample
        'env.CFG_SetValue("gtsrv.sip.reg.client.num", "1");
        'env.CFG_SetValue("gtsrv.sip.reg1.displayname", "Any");
        'env.CFG_SetValue("gtsrv.sip.reg1.username", "12345678");
        'env.CFG_SetValue("gtsrv.sip.reg1.domain", "pcbest.net");
        'env.CFG_SetValue("gtsrv.sip.reg1.proxy", "pcbest.net");
        'env.CFG_SetValue("gtsrv.sip.reg1.authorization", "12345678");
        'env.CFG_SetValue("gtsrv.sip.reg1.password", "************");
        'env.CFG_SetValue("gtsrv.sip.reg1.expire", "3600");

        If Not env.StartServer() Then
            MessageBox.Show("StartServer failed! Please make sure the SIP port set in INI file is not being using by another application.")
        End If

        'env.Send_GetRegStatus(0);

        'Proxy code start from here:
        env.CFG_SetValue("gtsrv.sip.proxy.sites.num", "1")

        Dim domains As String = env.GetMappedPublicSIPIPAddress() + ";"
        domains += GTAPIASM.GTAPIEnv.GetLocalIP(0) + ";"
        domains += "mysipproxy.com" 'fake one. You change it to your own domain if you have

        env.CFG_SetValue("gtsrv.sip.proxy.site1.domain", domains)

        'env.CFG_SetValue("gtsrv.sip.proxy.site1.recordroute", "1");
        'env.CFG_SetValue("gtsrv.sip.proxy.site1.udp.relay", "0");

        'if map sip client's Contact address in SIP REGISTER with actual address from network
        env.CFG_SetValue("gtsrv.sip.proxy.site1.map.reg.source", "1")

        env.CFG_SetValue("gtsrv.sip.proxy.site1.check.user.status", "1")

        env.InitProxySites()

        'Add extensions

        Dim i As Integer
        For i = 0 To Extensions.Length - 1 Step i + 1
            env.ProxySetUserInfo(0, Extensions(i).Username, Extensions(i).Password, 0, 0, "", "", "", 0, "", 0, "", "")
        Next

    End Sub

    Public Sub FreeSIPServer()
        env.FreeProxySites()
        env.StopServer()
        env.DestroyEnv()
        env = Nothing
    End Sub

    Public Sub On_RecvConnected(ByVal ch As Integer)
    End Sub

    Public Sub On_RecvDialing(ByVal ch As Integer, ByVal sCaller As String, ByVal sCallee As String)
    End Sub

    Public Sub On_RecvOffered(ByVal ch As Integer, ByVal sCaller As String, ByVal sCallee As String, ByVal sDestAddr As String, ByVal sViaAddr As String, ByVal sFromIP As String, ByVal nFromPort As System.UInt16)
    End Sub

    Public Sub On_RecvIdle(ByVal ch As Integer, ByVal code As Integer, ByVal desc As String)
    End Sub

    Public Sub On_RecvRinging(ByVal ch As Integer)
    End Sub

    Public Sub On_RecvRegStatus(ByVal acct_id As Integer, ByVal status As Integer, ByVal regtime As Integer)
    End Sub

    Public Sub On_ProxyUserRegistered(ByVal pid As System.UInt32, ByVal username As String, ByVal tnow As ULong, ByVal exp_sec As System.UInt32, ByVal org_contact As String, ByVal mapped_contact As String, ByVal szUAName As String, ByVal UANatType As Integer, ByVal from_id As String, ByVal to_id As String, ByVal src_ip As String, ByVal src_port As System.UInt16)
        Dim sStatus As String = ""
        Dim sAt As String = ""

        'update local extension structure for late to use
        Dim i As Integer
        For i = 0 To Extensions.Length - 1 Step i + 1
            If Extensions(i).Username = username Then
                Extensions(i).RegTime = tnow
                Extensions(i).RegExp = exp_sec
                Extensions(i).OrgContact = org_contact
                Extensions(i).MappedContact = mapped_contact
                Extensions(i).UAName = szUAName
                Extensions(i).SIPId = from_id
                Extensions(i).FromIP = src_ip
                Extensions(i).FromPort = src_port
                Exit For
            End If
        Next

        If tnow > 0 And exp_sec > 0 Then
            'extension register
            sStatus = "Online"
            sAt = org_contact + " " + mapped_contact + " " + szUAName + " " + from_id
        ElseIf exp_sec = 0 Then
            'extension unregister
            sStatus = "Offline"
            sAt = ""
        End If

        If username = "101" Then
            tb101Status.Text = sStatus
            tb101At.Text = sAt
        End If
        If username = "102" Then
            tb102Status.Text = sStatus
            tb102At.Text = sAt
        End If
        If username = "103" Then
            tb103Status.Text = sStatus
            tb103At.Text = sAt
        End If
        If username = "104" Then
            tb104Status.Text = sStatus
            tb104At.Text = sAt
        End If
    End Sub

    Public Function On_ProxyNewCallSession(ByVal pid As System.UInt32, ByVal sid As System.UInt32, ByVal msg As System.IntPtr, ByVal authid As String, ByVal fromid As String, ByVal toid As String, ByVal suri As String, ByVal via As String, ByVal saddr As String, ByVal nport As System.UInt16, ByVal bCredit As Boolean) As String '             
        '             Possible Return values:
        '             "sip:undefined" = wait until ProxySetNewCallSessionAddr is called
        '             Sometimes you cannot immediately decide what to do with Me call, and then you can call ProxySetNewCallSessionAddr function to provide an address later.
        '             NOTE: The OCX(ActiveX) users should(have to) use ProxySetNewCallSessionAddr function later to provide one of the following values:
        '             "channel" = to channel. Default value. Then one of the channels will have On_RecvOffered event triggered.
        '             "unauthorized" = need credit to process. You should check the fromID, to see if it is a call from proxy site’s user(or extension of PBX). If it does, and Credit is False, then “unauthorized” String is Returned to ask authorization to call .
        '             "sip:123@abc.com" = with right credit or don't need credit, processed by proxy site and transfered to Me address
        '             "|" can be used to seperate the credit info. For example: "To<sip:123@abc.com>|From<sip:456@abc.com>|User<1234>|Password<4567>"
        '             Otherwise, if none of above matched, refer to user's contact info.
        '             */

        Dim toUserName As String = GTAPIASM.GTAPIEnv.GetSIPAddressInfo(1, toid)

        'check if it is for one of the extensions
        Dim i As Integer
        For i = 0 To Extensions.Length - 1 Step i + 1
            If Extensions(i).Username = toUserName Then
                'to one of extensions
                If Extensions(i).MappedContact.Length > 0 Then
                    Return Extensions(i).MappedContact
                ElseIf Extensions(i).OrgContact.Length > 0 Then
                    Return Extensions(i).OrgContact
                Else
                    'not registered
                    Return "rejected"
                End If

            End If
        Next

        If toUserName.Length > 0 Then
            If toUserName(0) = "9"c Then
                'assume there is an outbound dialplan defined starting as 9.
                'stripping off the 9 in the front
                Dim sDest As String = toUserName.Substring(1)
                'make the outgoing sip address. you will have to make changes here for other-sip-server-ip
                sDest = "<sip:" + sDest + "@other-sip-server-ip" + ">"

                Return sDest
            End If
        End If

        Return "channel"

    End Function


End Class

Public Class Extension
    Public Username As String
    Public Password As String
    Public RegTime As System.UInt32
    Public RegExp As System.UInt32
    Public OrgContact As String
    Public MappedContact As String
    Public UAName As String
    Public SIPId As String
    Public FromIP As String
    Public FromPort As System.UInt16

    Public Sub New()
        Username = ""
        Password = ""
        RegTime = 0
        RegExp = 0
        OrgContact = ""
        MappedContact = ""
        UAName = ""
        SIPId = ""
        FromIP = ""
        FromPort = 0
    End Sub
End Class

