Apagada docs

Aprendiendo a programar el pasado

Herramientas de usuario

Herramientas del sitio


en:samsung_tv_ue32h5303aw_format

Formato de archivo de canales del TV Samsung ue32h5303aw

Samsung TV Samsung model ue32h5303aw (and I guess more models from same manufacturer) can export channel list to a file named channel_list_UE32H5303_1401.scm in a usb memory.

In such file name, UE32H5303 matches model number, and 1401 is the channel exporter version.

That .scm file is actually a .zip file that can be unzipped to extract the following files:

  • FineTune_Digital
  • TSIDList
  • TransponderDataBase.dat
  • UserTransponderDataBase.dat
  • SatDataBase.dat
  • map-AirA
  • map-AirD
  • ServiceProviders
  • RadioMap
  • map-ChKey
  • CloneInfo

The terrestrial digital broadcast channels are stored inside map-AirA. It uses the following format:

1000 320-byte records with channels stored this way: (Since I use basic, first byt is “byte 1”. If you use C or java, you have to substract 1 from all seek positions):

  • Bytes 1-2: Program # (intel format, big endian).
  • Bytes 3-4: Video PID (intel format, big endian). -1 for radios.
  • Bytes 5-6: Channel PID (intel format, big endian), valid for both TV and Radios.
  • Byte 13: Bit rate (usually 8).
  • Byte 20: Active (1) / Deleted (0).
  • Bytes 21-22: XResolution (intel format, big endian). -1 for radios.
  • Bytes 23-24: YResolution (intel format, big endian). -1 for radios.
  • Byte 32: Locked channel (1 if locked, 0 if available).
  • Bytes 43-44: Channel #.
  • Bytes 66-282?: Channel name, two-byte unicode big-endian, zero-padded. it seems at least a 128 byte name can be stored here.
  • Bytes 283-284: ??? (14 for SD, 5 for HD, 7 for “La 1 HD”, 255 for radios. “La 1 HD” supports java, but “Telemadrid HD” does also and has “5”).
  • Byte 320: Verification. It doesn't seem to be CRC, but XOR, addition, or maybe roled-left or roled-right addition, but I can't manage to decode it.

VBA (visual basic for applications, i.e. office macro) to read map-AirD from desktop:

read_samsung_map_aird.bas
Sub Read_Samsung_map_AirD()
'
' Lee el fichero map_AirD extraído de un fichero de lista de canales de Samsung.
' Read map_AirD extracted from a Samsung channel list.
'
' (Para extraerlo, cambie la extensión del archivo SCM a ZIP y extráigalo).
' (To extract from the SCM file, change extension from SCM to ZIP and unzip it).
 
Dim a$
Const outputDetails = 1     ' Detalles / Output channel details.
Const outputCSV = 2         ' CSV / Output a CSV channel list
Const outputHex = 4         ' Hex / Output hexdump
'
' Specify here what to output, like outputDetails + outputHex
' Indique aquí la salida que desea, como outputDetails+outputHex
'
Dim outputType As Integer: outputType = outputCSV
'
' Skip empty records? / ¿Saltar canales vacíos?
'
Dim skipEmpty As Boolean: skipEmpty = True
 
'
' Input file. This points to [user folder]\desktop\map-AirD
' Archivo de entrada. Esto apunta a escritorio\map-AirD
'
Dim inFile$: inFile$ = Environ$("userprofile") + "\Desktop\map-AirD"
'            inFile$=  "E:\prueba\map-AirD"
 
Dim f As Integer, g As Integer
Dim Position As Integer, Channel As Integer
 
 
Open inFile$ For Binary As #1
firstname = 66
endname = 320
Seek 1, 1
While Loc(1) < LOF(1)
'
' El fichero contiene 1000 registros de 320 bytes, uno por cada posible canal.
' File contains 1000 320-byte records, one for each possible channel.
'
    a$ = InputB$(320, 1)
 
 
    If Not ((AscB(LeftB(a$, 1)) = 0) And (skipEmpty)) Then
        deleted = (AscB(MidB(a$, 20, 1)) = 0)
        Position = AscB(MidB(a$, 1, 1)) + AscB(MidB(a$, 2, 1)) * 256
        Channel = AscB(MidB(a$, 43, 1)) + AscB(MidB(a$, 44, 1)) * 256
        Unknown1 = AscB(MidB(a$, 283, 1)) + AscB(MidB(a$, 284, 1)) * 256
        pname$ = Trim$(MidB(a$, 66, 66 + 256))
        If AscB(MidB(a$, 22, 1)) = 255 Then
            ResolutionX = -1
        Else
            ResolutionX = AscB(MidB(a$, 21, 1)) + AscB(MidB(a$, 22, 1)) * 256
        End If
        If AscB(MidB(a$, 24, 1)) = 255 Then
            resolutionY = -1
        Else
            resolutionY = AscB(MidB(a$, 23, 1)) + AscB(MidB(a$, 24, 1)) * 256
        End If
        If AscB(MidB(a$, 4, 1)) = 255 Then
            VideoID = -1
            'RadioID: a PID that is valid for both TVs and radios, but is not the Audio ID
            RadioID = AscB(MidB(a$, 5, 1)) + AscB(MidB(a$, 6, 1)) * 256
        Else
            VideoID = AscB(MidB(a$, 3, 1)) + AscB(MidB(a$, 4, 1)) * 256
            'RadioID: a PID that is valid for both TVs and radios, but is not the Audio ID
            RadioID = AscB(MidB(a$, 5, 1)) + AscB(MidB(a$, 6, 1)) * 256
        End If
 
        'If deleted Then pname$ = "(D)" + pname$
        'Display hex records for given channels only.
        ' This allows more detailed reverse engineering.
        '
        encontrar$ = ""
        If encontrar$ > "" Then
            If InStr(pname$, encontrar$) > 0 Then
                outputType = outputType Or outputHex
            Else
                outputType = outputType And (Not outputHex)
            End If
        End If
        '
        'pname$ is unicode, use Instr, Chr instead of InstrB, ChrB
        '
        Inst = InStr(pname$, Chr(0))
        If Inst > 0 Then pname$ = Left(pname$, Inst - 1)
 
        'Buscar longitud del campo de texto...
       ' For q = firstname + LenB(pname$) + 1 To 320
       '     If endname >= LenB(a$) Then endname = LenB(a$)
       '     If q > endname Then Exit For
       '     If AscB(MidB(a$, q, 1)) <> 0 Then
       '         endname = q
       '     End If
       ' Next q
       ' Debug.Print endname
 
        ' No muestres canales vacíos
        ' Do not show empty channels
        If Position > 0 And Channel > 0 Then
 
            ' Salida para humanos
            ' Human readable output
            If (outputType And outputDetails) Then
                Debug.Print "Deleted? "; deleted; ";";
                Debug.Print "Position #"; Position; ";";
                Debug.Print "Channel #"; Channel; ";";
                Debug.Print "Program name:"; pname$; ";";
                Debug.Print "AnchoBanda:"; AscB(MidB(a$, 13, 1));
                Debug.Print "VideoPID:"; VideoID;
                Debug.Print "_____PID:"; RadioID;
                Debug.Print "Resolution:"; ResolutionX; "x"; resolutionY;
                Debug.Print "Unknown1:"; Unknown1;
                'Debug.Print
            End If
 
            ''Salida para CSV / CSV output
            ' CSV formato es_ES: datos delimitados con ";"
            ' CSV es_ES format: data delimited with ";" instead of ","
            If (outputType And outputCSV) Then
                Debug.Print Trim$(Str$(Position)) + ";" + Trim(Str$(Channel)) + ";""" + pname$ + """";
                Debug.Print Str$(AscB(MidB(a$, 13, 1))) + ";";
                Debug.Print Str$(VideoID) + ";";
                Debug.Print Str$(RadioID) + ";";
                Debug.Print Str$(ResolutionX) + ";";
                Debug.Print Str$(resolutionY) + ";";
                Debug.Print Str$(Unknown1) + ";";
                If deleted Then Debug.Print "Deleted"; Else Debug.Print "Active";
                   Debug.Print
            End If
 
        End If
 
        '
        xorval = 0
        xorval1 = 0
        xorval0 = 0
 
        For g = 0 To 319 Step 16
        '
        'Step 16: muestro 16 bytes en cada línea. / 16 bytes per line
        '
 
        'saltar registros vacíos en hexdump
        'skip empty records in hexdump
 
 
            For f = 1 To 16
                n = AscB(MidB$(a$, g + f, 1))
                'xorval = (xorval + n) Mod 256
                'If (f And 1) Then xorval1 = (xorval1 + n) Mod 256 Else xorval0 = (xorval0 + n) Mod 256
                If (outputType And outputHex) Then
                    Debug.Print Right$("00" + Hex$(n), 2) + " ";
                    If n >= 32 Then Debug.Print Chr$(n); Else Debug.Print (".");
                    Debug.Print " ";
                End If
            Next
 
          If (outputType And outputHex) Then Debug.Print
        Next
 
        'Last value is some form of verification code, maybe xor, maybe crc.
        'I can't guess what is it.
        'Debug.Print GetCRC32(a$)
        'Debug.Print Hex(xorval), Hex(xorval1), Hex(xorval0)
    End If
 
Wend
 
Close #1
Stop ' allows to use debug window before exiting
End Sub
Public Function GetCRC32(ByVal buffer As String) As String
    '
    ' Modified from code by Tim Hartwig,
    ' http://dotnet-snippets.com/snippet/calculate-crc32-hash-from-file/587
    '
        Dim CRC32Result As Long: CRC32Result = &HFFFFFFFF
        Dim CRC32Table(256) As Long
        Dim DWPolynomial As Long: DWPolynomial = &HEDB88320
        Dim DWCRC As Long
        Dim i As Integer, j As Integer, n As Integer
 
        'Create CRC32 Table
        For i = 0 To 255
            DWCRC = i
            For j = 8 To 1 Step -1
                If (DWCRC And 1) Then
                    DWCRC = ((DWCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
                    DWCRC = DWCRC Xor DWPolynomial
                Else
                    DWCRC = ((DWCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
                End If
            Next j
            CRC32Table(i) = DWCRC
        Next i
 
        'Calcualting CRC32 Hash
 
            For i = 1 To LenB(buffer)
                n = (CRC32Result And &HFF) Xor AscB(MidB(buffer, i, 1))
                CRC32Result = ((CRC32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
                CRC32Result = CRC32Result Xor CRC32Table(n)
            Next i
        GetCRC32 = Hex(Not (CRC32Result))
End Function

Other files in the SCM archive:

* Cloneinfo contains a line with the “PSE” signature, and a second line that contains the TV model number.

Este sitio web utiliza cookies. Al utilizar el sitio web, usted acepta almacenar cookies en su computadora. También reconoce que ha leído y entendido nuestra Política de privacidad. Si no está de acuerdo abandone el sitio web.Más información
en/samsung_tv_ue32h5303aw_format.txt · Última modificación: 2017/09/24 12:18 por nepenthes