Namespace TCP
    ''' <summary>
    ''' Classe de gestion d'une trame
    ''' </summary>
    ''' <remarks></remarks>
    Friend Class Frame

        Inherits Modbus.BaseFrame
        ''' <summary>
        ''' Retourne la trame correspondante aux données reçues (Nothing si inconnu ou incorrect)
        ''' </summary>
        ''' <param name="ptData">Trame reçue</param>
        ''' <param name="pRequest">Précise si la trame est une requête ou une réponse</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function GetFrame(ByVal ptData As Byte(), ByVal pRequest As Boolean) As Frame

            Dim lFrame As Modbus.Frame.ClsFrameModbusBase

            If ptData.Length < 6 OrElse ptData.Length <> (CUInt(ptData(4) << 8) + ptData(5) + 6) Then
#If DEBUG Then
                Stop
#End If
                Return Nothing
            End If

            Try
                lFrame = Modbus.Frame.ClsFrameModbusBase.GetClassFromFrame(GetArrayRange(ptData, 0, ptData.Length - 6), pRequest)
                Return New Frame(lFrame, CUShort(ptData(0) << 8) + ptData(1))
            Catch ex As Exception
#If DEBUG Then
                Stop
#End If
                Return Nothing
            End Try
        End Function
        ''' <summary>
        ''' Retourne la trame correspondante aux données reçues (Nothing si inconnu ou incorrect)
        ''' </summary>
        ''' <param name="pFrame">Trame reçue (ASCII)</param>
        ''' <param name="pRequest">Précise si la trame est une requête ou une réponse</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overloads Shared Function GetFrame(ByVal pFrame As String, ByVal pRequest As Boolean) As Frame
            Dim ltBytes As New List(Of Byte)
            Dim lCtrl As String = "0123456789ABCDEF"
            Dim lStr As String = ""

            pFrame = pFrame.ToUpper

            For i As Integer = 0 To pFrame.Length - 1
                If lCtrl.Contains(pFrame.Substring(i, 1)) Then
                    lStr += pFrame.Substring(i, 1)
                End If
                If lStr.Length >= 2 Then
                    ltBytes.Add(Byte.Parse(lStr.Substring(0, 2), Globalization.NumberStyles.HexNumber))
                    If lStr.Length = 2 Then
                        lStr = ""
                    Else
                        lStr = lStr.Substring(2)
                    End If
                End If
            Next

            Return GetFrame(ltBytes.ToArray, pRequest)
        End Function

        ''' <summary>
        ''' ID de la transaction
        ''' </summary>
        ''' <remarks></remarks>
        Private mID As UShort

        ''' <summary>
        ''' Constructeur
        ''' </summary>
        ''' <param name="pFrame">Trame à empacter</param>
        ''' <param name="pID">ID de la transaction</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal pFrame As Modbus.Frame.ClsFrameModbusBase, ByVal pID As UShort)
            MyBase.New(pFrame)
            mID = pID
        End Sub

        ''' <summary>
        ''' ID de la transaction
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ID() As UShort
            Get
                Return mID
            End Get
        End Property

        ''' <summary>
        ''' Retourne La trame au format ASCII
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function GetFrame() As Byte()
            Dim ltData As New List(Of Byte)
            ltData.AddRange(Trame.GetFrame)
            ltData.AddRange(UShortToByteArrayCRC(CalcCRC16(ltData.ToArray, False)))
            Return ltData.ToArray
        End Function
        ''' <summary>
        ''' Retourne La trame au format ASCII
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function GetFrameAscii() As String
            Dim ltByte As Byte() = GetFrame()
            Dim lStr As New Text.StringBuilder

            For i As Integer = 0 To ltByte.GetUpperBound(0)
                lStr.Append(ltByte(i).ToString("X2"))
            Next

            lStr.Append(vbCr)
            lStr.Append(vbLf)

            Return lStr.ToString
        End Function
    End Class
End Namespace