Imports GPSConnector.Common

Public MustInherit Class TeltonikaDevice
    Implements IGPSProcessor
    ReadOnly dataContainer As New Dictionary(Of String, TeltonikaDeviceData)
    Public Function ProcessData(ByVal rawData As String, uniqueKey As String) As GPSProcessorResult Implements IGPSProcessor.ProcessData
        Throw New NotImplementedException()
    End Function
    Public Sub Cleanup(ByVal uniqueKey As String) Implements IGPSProcessor.Cleanup
        Try
            If dataContainer.ContainsKey(uniqueKey) Then
                dataContainer(uniqueKey) = Nothing
                dataContainer.Remove(uniqueKey)
            End If
        Catch ex As Exception

        End Try

    End Sub

    Public Function ProcessData(ByVal rawData As Byte(), ByVal uniqueKey As String) As GPSProcessorResult Implements IGPSProcessor.ProcessData
        Dim imei As String = String.Empty
        Dim result As New GPSProcessorResult

        Try
            If Not dataContainer.ContainsKey(uniqueKey) Then
                dataContainer.Add(uniqueKey, New TeltonikaDeviceData() With {.UniqueKey = uniqueKey})
            End If
            Dim TeltonikaDeviceData As TeltonikaDeviceData = dataContainer(uniqueKey)
            If (UBound(rawData) >= 3) Then ' minimum length
                If (rawData(0) = 0 AndAlso rawData(1) = 15 AndAlso rawData.Length >= 17) OrElse (rawData(0) = 15 AndAlso rawData.Length >= 16) Then ' sending the IMEI

                    For i = rawData.Length - 15 To rawData.Length - 1
                        If (rawData(i) <> 0) Then
                            imei = imei & Chr(rawData(i))
                        End If
                    Next i
                    TeltonikaDeviceData.Reset()
                    TeltonikaDeviceData.IMEI = imei
                    result.Success = True
                    result.BackMessages.Add(New Byte() {&H1})
                Else
                    If Not String.IsNullOrEmpty(TeltonikaDeviceData.IMEI) Then
                        If TeltonikaDeviceData.DataLength > 0 AndAlso TeltonikaDeviceData.LastIndex < TeltonikaDeviceData.DataLength Then ' data length was set so this is continuation
                            Dim lastIndex As Integer = TeltonikaDeviceData.LastIndex
                            Dim i As Integer
                            For i = 0 To rawData.Length - 1
                                TeltonikaDeviceData.Data(i + lastIndex) = rawData(i)
                                lastIndex = lastIndex + 1
                                If lastIndex = TeltonikaDeviceData.DataLength Then
                                    Exit For
                                End If

                            Next i

                            If TeltonikaDeviceData.Data.Length = TeltonikaDeviceData.DataLength Then
                                If i < rawData.Length - 1 Then
                                    ReDim TeltonikaDeviceData.CRC(rawData.Length - 2 - i)
                                    Dim f As Integer = 0
                                    For ii = i + 1 To rawData.Length - 1
                                        TeltonikaDeviceData.CRC(f) = rawData(ii)
                                        f = f + 1
                                    Next
                                End If

                                result = ParseData(TeltonikaDeviceData)
                                TeltonikaDeviceData.Reset(True)
                            Else
                                TeltonikaDeviceData.LastIndex = lastIndex
                                result.Success = True
                            End If
                        Else ' this data must be begin. we need to set data length.
                            If rawData(8) = CodeId Then          'Codec ID test   =>  Data-zacatek
                                TeltonikaDeviceData.DataLength = CInt("&H" & Hex(rawData(4)) & Hex(rawData(5)) & Hex(rawData(6)) & Hex(rawData(7)))
                                TeltonikaDeviceData.NumberOfRecord = CInt("&H" & Hex(rawData(9)))
                                Dim j As Integer = 0
                                ReDim TeltonikaDeviceData.Data(TeltonikaDeviceData.DataLength - 1)
                                Dim i As Integer
                                For i = 8 To rawData.Length - 1
                                    TeltonikaDeviceData.Data(j) = rawData(i)
                                    j = j + 1
                                    If j = TeltonikaDeviceData.DataLength Then
                                        Exit For
                                    End If
                                Next i
                                If TeltonikaDeviceData.Data.Length = TeltonikaDeviceData.DataLength Then
                                    'get CRC
                                    If i < rawData.Length - 1 Then
                                        ReDim TeltonikaDeviceData.CRC(rawData.Length - 2 - i)
                                        Dim f As Integer = 0
                                        For ii = i + 1 To rawData.Length - 1
                                            TeltonikaDeviceData.CRC(f) = rawData(ii)
                                            f = f + 1
                                        Next
                                    End If
                                    result = ParseData(TeltonikaDeviceData)
                                    TeltonikaDeviceData.Reset(True)
                                Else
                                    TeltonikaDeviceData.LastIndex = j
                                    result.Success = True
                                End If

                            Else
                                result.Success = False
                            End If
                        End If
                    End If
                End If
            End If

        Catch ex As Exception
            result.Success = False
        End Try

        Return result
    End Function
    Public MustOverride Function ParseData(teltonikaDeviceData As TeltonikaDeviceData) As GPSProcessorResult
    Public MustOverride ReadOnly Property CodeId As Integer
End Class
Public Class TeltonikaDeviceData
    Public Property UniqueKey As String

    Public Property IMEI As String
    Public Property DataLength As Integer
    Public Property Data As Byte()
    Public Property NumberOfRecord As Integer
    Public Property LastIndex As Integer
    Public Property CRC As Byte()
    Public Sub Reset(Optional keepIMEI As Boolean = False)
        If Not keepIMEI Then
            IMEI = String.Empty
        End If
        Data = New Byte() {}
        CRC = New Byte() {}
        NumberOfRecord = 0
        DataLength = 0
    End Sub
End Class