Imports Microsoft.Win32
Imports System.Net.Sockets
Imports System.Text

Public Class smsStatPhoneHome
    Dim mtcpClient As New System.Net.Sockets.TcpClient()
    Dim networkStream As NetworkStream

    Private Enum CMDs

        HelloServer = 100
        HelloClient = 110
        ReadyForData = 120
        Version = 131
        ID = 132
        Country = 133
        WindowsVersion = 134
        Stats = 200
        OK = 400
        AllDone = 500
        ByeBye = 510
        ErrClose = 900

    End Enum



    Private Function SendAndGet(ByVal pstr As String) As String
        Try

            Dim netStream As NetworkStream

            netStream = mtcpClient.GetStream()

            Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(pstr & vbCrLf)
            netStream.Write(sendBytes, 0, sendBytes.Length)


            Dim bytes(mtcpClient.ReceiveBufferSize) As Byte
            netStream.Read(bytes, 0, CInt(mtcpClient.ReceiveBufferSize))
            ' Return the data received from the client to the console.
            Return Encoding.ASCII.GetString(bytes)

        Catch ex As Exception
            Return ""
        End Try
    End Function

    Private Function SendCMD(ByVal pCMD As CMDs) As String

        Dim str As String = ""
        Dim strRes As String

        Select Case pCMD

            Case CMDs.AllDone : str = "500 I am all done, nice to talk to you and godbye"
            Case CMDs.ByeBye : str = "510 Bye Bye, and thanks for the stats :-)"
            Case CMDs.Country : str = "133 Can I send you my country?"
            Case CMDs.HelloClient : str = "110 Hi there, nice to meet you"
            Case CMDs.HelloServer : str = "100 Hi I am the netSMSgw statistics collector, I run version " & System.Environment.Version.ToString
            Case CMDs.ID : str = "132 Can I send my installation ID?"
            Case CMDs.OK : str = "400 OK, thanks"
            Case CMDs.ReadyForData : str = "120 I am ready for some data now, if you please"
            Case CMDs.Stats : str = "200 Can I send you my statistics now?"
            Case CMDs.Version : str = "131 Can I send you my stats current version?"
            Case CMDs.WindowsVersion : str = "134 Can I send you my Windows version?"
            Case CMDs.ErrClose : str = "900 Critical error happened, Im closing the connection!"
        End Select

        strRes = SendAndGet(str)
        Return strRes

    End Function


    Public Function PhoneHome(ByVal psmsStatistics As smsStatistics) As Boolean
        Try
            Dim str As String
            'tcpClient = New System.Net.Sockets.TcpClient
            mtcpClient.Connect("192.168.100.238", 1080)

            'get reponse from stat server
            networkStream = mtcpClient.GetStream()
            Dim bytes(mtcpClient.ReceiveBufferSize) As Byte

            networkStream.Read(bytes, 0, CInt(mtcpClient.ReceiveBufferSize))
            ' Output the data received from the host to the console.
            str = Encoding.ASCII.GetString(bytes)


            'if it was not a hello, errclose
            If Not Left(str, 3) = CMDs.HelloServer Then GoTo ErrClose

            'send helo back
            str = SendCMD(CMDs.HelloClient)
            If Not Left(str, 3) = CMDs.ReadyForData Then GoTo ErrClose

            'ready for client version?
            str = SendCMD(CMDs.Version)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'send client version
            str = SendAndGet(MyVersion)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'ready for installation id?
            str = SendCMD(CMDs.ID)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'send installation id
            str = SendAndGet(gSettings.InstallationID)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose


            'ready for country?
            str = SendCMD(CMDs.Country)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'send country
            str = SendAndGet(RegValue(RegistryHive.Users, ".DEFAULT\Control Panel\International", "sCountry"))
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'ready for windows version?
            str = SendCMD(CMDs.WindowsVersion)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'send Windows version
            str = SendAndGet(System.Environment.OSVersion.VersionString)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'ready for stats?
            str = SendCMD(CMDs.Stats)
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'annonymize stats and send it
            str = SendAndGet(SerializeStat(annonymizeStats(psmsStatistics)))
            If Not Left(str, 3) = CMDs.OK Then GoTo ErrClose

            'send all done.
            str = SendCMD(CMDs.AllDone)
            If Not Left(str, 3) = CMDs.ByeBye Then GoTo ErrClose


            GoTo Close


ErrClose:
            SendCMD(CMDs.ErrClose)
            mtcpClient.Close()
            Return False

Close:
            mtcpClient.Close()
            Return True

        Catch ex As Exception
            MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error")
        End Try
    End Function

    Private Function SerializeStat(ByVal psmsStats As smsStatistics) As String

        ' Create a new XmlSerializer instance.
        Dim s As New Xml.Serialization.XmlSerializer(GetType(smsStatistics))



        Dim sb As New System.Text.StringBuilder
        Dim stream As New IO.StringWriter(sb)

        ' Serialize the object, and close the StreamWriter.

        s.Serialize(stream, psmsStats)
        stream.Close()

        MsgBox(sb.ToString)
        Return sb.ToString

    End Function

    Private Function annonymizeStats(ByVal pStatistics As smsStatistics) As smsStatistics
        Dim stat As smsStat

        For Each stat In pStatistics.Stats
            stat.MobileNum = "<removed>"
        Next

        Return pStatistics

    End Function

    Private Sub SendData(ByVal pstr As String)
        Try

            Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(pstr)
            networkStream.Write(sendBytes, 0, sendBytes.Length)

            Dim bytes(mtcpClient.ReceiveBufferSize) As Byte
            networkStream.ReadTimeout = 1000
            networkStream.Read(bytes, 0, CInt(mtcpClient.ReceiveBufferSize))
            ' Output the data received from the host to the console.
            Dim returndata As String = Encoding.ASCII.GetString(bytes)
            'MsgBox(returndata)
        Catch ex As Exception
            MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error")
        End Try

    End Sub



    Private Function RegValue(ByVal Hive As RegistryHive, ByVal Key As String, ByVal ValueName As String, _
                             Optional ByRef ErrInfo As String = "") As String

        'DEMO USAGE

        'Dim sAns As String
        'Dim sErr As String = ""

        'sAns = RegValue(RegistryHive.LocalMachine, _
        '  "SOFTWARE\Microsoft\Windows\CurrentVersion", _
        '  "ProgramFilesDir", sErr)
        'If sAns <> "" Then
        '    Debug.WriteLine("Value = " & sAns)
        'Else
        '    Debug.WriteLine("This error occurred: " & sErr)

        'End If

        Dim objParent As RegistryKey
        Dim objSubkey As RegistryKey
        Dim sAns As String = ""

        Select Case Hive
            Case RegistryHive.ClassesRoot
                objParent = Registry.ClassesRoot
            Case RegistryHive.CurrentConfig
                objParent = Registry.CurrentConfig
            Case RegistryHive.CurrentUser
                objParent = Registry.CurrentUser
            Case RegistryHive.DynData
                objParent = Registry.DynData
            Case RegistryHive.LocalMachine
                objParent = Registry.LocalMachine
            Case RegistryHive.PerformanceData
                objParent = Registry.PerformanceData
            Case RegistryHive.Users
                objParent = Registry.Users
            Case Else
                objParent = Registry.LocalMachine

        End Select

        Try
            objSubkey = objParent.OpenSubKey(Key)
            'if can't be found, object is not initialized

            If Not objSubkey Is Nothing Then
                sAns = (objSubkey.GetValue(ValueName))
            End If

        Catch ex As Exception

            ErrInfo = ex.Message
        Finally

            'if no error but value is empty, populate errinfo
            If ErrInfo = "" And sAns = "" Then
                ErrInfo = "No value found for requested registry key"
            End If
        End Try
        Return sAns
    End Function

End Class
