Is [0x02, 0x03, 0x00] valid data? - validation

I am trying to write a program that returns valid data according to a message protocol within a byte[] array.
I have:
STX: 0x02
ETX: 0X03
DLE: 0x10 //Delimiter
Valid data is when the byte[] array contains STX, ETX, data and a correctly calculated LRC, for example:
byte[] validMsg1 = {0x02, // STX
0x10,0x2,0xA,0x10,0x10,0x7,0x8, // Data 2 A 10 7 8
0x03, // ETX
0x2^0xA^0x10^0x7^0x8^0x03}; // LRC calculated from the data (with the DLE removed) plus the ETX
Invalid data example:
byte[] invalidMsg1 = {0x02, // STX
0x10,0x2,0xA, // Data 2 A
0x03, // ETX
0x2^0xA^0x10^0x7^0x8^0x03,
0x02, //STX
0x05,0x44};
The byte might also contain random values around the valid data:
byte[] validMsgWithRandomData1 = {0x32,0x32,0x32, //Random data
0x02, // STX
0x31,0x32,0x10,0x02,0x33, // Data 31 32 02 33
0x03, // ETX
0x31^0x32^0x02^0x33^0x03,// LRC calculated from the data (with the DLE removed) plus the ETX
0x2,0x3,0x00,0x02 //Random data
};
My problems is that when I use the message with random data in and have 0x2,0x3,0x00,0x02 it breaks because it sees 0x02 and 0x03 as the STX and ETX and then it calculates LRC which results in 0x03 which results in this being returned: 0x2,0x3,0x00 with the last 0x03 seens as the LRC.
Question is this valid data:
byte[] data = {
0x02, // STX
0x03, // ETX
0x00, // LRC
};
I am supposed to return the most recent valid data which is that but there is better data within this which is:
byte[] validData = {
0x02, // STX
0x31,0x32,0x10,0x02,0x33, // Data 31 32 02 33
0x03, // ETX
0x31^0x32^0x02^0x33^0x03,// LRC calculated from the data (with the DLE removed) plus the ETX
};

Related

Read Data ST25DV

I made my own board with an STM32L031K6 and an ST25DV64K NFC chip. I am using the android App "NFC Tools". I can read the UID of the NFC chip with the app, so the antenna is correctly tuned. I can also read the UID with the microcontroleur via the I2C bus. When I write into the eeprom memory of the NFC chip with the microcontroleur, I can't read the data with the NFC app. It says that the tag is empty. I think I am missing a configuration, but I can't find which one.
Here is my code, executed once:
uint8_t ToWrite = 15;
uint8_t Password[17] = {0}; //Default password is"00000000"
Password[8] = 0x09; //Validation Code
// ST25DV_Address_E21 0x57 << 1; // Device select code= 0b1010111 ; E2 = 1
Password_Address = 0x900
HAL_I2C_Mem_Write(&hi2c1, ST25DV_Address_E21, Password_Address, 2, Password, 17, 0xFFF);
HAL_Delay(200);
//Read the UID
HAL_I2C_Mem_Read(&hi2c1, ST25DV_Address_E21, 0x18, 2, UID_Read, 8, 0xFFF); // This line works, UID displayed in the app and in the debugger are the same
HAL_Delay(500);
//Write some data in the eepprom memory (first address: 0x00)
for(int i = 0; i< 250; i++)
{
ToWrite++;
HAL_I2C_Mem_Write(&hi2c1,ST25DV_Address_E21, i, 2, &ToWrite, 1, 0xFF);
}
When you are writing the data in the EEPROM from address/block 0, you are simply overwriting the capability container values with all zeros. The correct way to do is initialize your tag, then write the data from block 4 and onwards.
The CC values look something like this:
0xE1, /* (block 0) */
0x40, /* (block 1) */
0x40, /* (block 2) */
0x05 /* (block 3) */
Followed by other key header values depending on the NDEF message type. Here I am illustrating for NDEF TEXT:
0x03, /*(block 4) NDEF message type (block 4) */
0x0D, /*(block 5) NDEF message length (blobk 5) eg, 13 byte message starting from here */
0xD1, /*(block 6) NDEF Record header: MB = 1, ME = 1, CF = 0, SR = 1, IL = 0, TNF = 001 > 0xD1 */
0x01, /*(block 7) Type length */
0x09, /*(block 8) Payload length = 9 (from language code) */
0x54, /*(block 9) Msg Type = Text */
0x02, /*(block 10) Language code size */
0x65, /*(block 11) Language = English, 'e', */
0x6E, /*(block 12) 'n', */
'A', /*(block 13+)Payload data */
'B',
'C',
'D',
'E',
'F'
A good reading resource to understand the NDEF payload format is here.
Hope this helps!

send feedback to datalogic scanner using vbs

I have a datalogic powerscan pm9500 connected through a serial port (COM2)
I need to send him a command for turn on LEDs so when I read the correct code it shows the green led and the red for wrong code.
Now,this is my question:
I found this code for transmit that command with c sharp.
// ----------ORIGINAL NOT WORKING MISSING DC2----------------------------------
// Send: ESC [ 6 q CR
_serialPort.Write(new byte[] { 0x1B, 0x5B, 0x36, 0x71, 0x0D }, 0, 5);
// Send: ESC [ 3 q CR
_serialPort.Write(new byte[] { 0x1B, 0x5B, 0x33, 0x71, 0x0D }, 0, 5);
// Send: ESC [ 7 q CR
_serialPort.Write(new byte[] { 0x1B, 0x5B, 0x37, 0x71, 0x0D }, 0, 5);
// ---------POSSIBLE MODIFY 1 TEORICALLY WORKING-----------------------------------
// Send: DC2 ESC [ 6 q CR
_serialPort.Write(new byte[] { 0x12, 0x1B, 0x5B, 0x36, 0x71, 0x0D }, 0, 6);
// Send: DC2 ESC [ 3 q CR
_serialPort.Write(new byte[] { 0x12, 0x1B, 0x5B, 0x33, 0x71, 0x0D }, 0, 6);
// Send: DC2 ESC [ 7 q CR
_serialPort.Write(new byte[] { 0x12, 0x1B, 0x5B, 0x37, 0x71, 0x0D }, 0, 6);
// --------POSSIBLE MODIFY 2 IF IT NOT ACCEPT CR AS CHAR---------------------------
// Send: DC2 ESC [ 6 q ESC [ G
_serialPort.Write(new byte[] { 0x12, 0x1B, 0x5B, 0x36, 0x71, 0x1B, 0x5B, 0X47 }, 0, 8);
// Send: DC2 ESC [ 3 q ESC [ G
_serialPort.Write(new byte[] { 0x12, 0x1B, 0x5B, 0x33, 0x71, 0x1B, 0x5B, 0X47 }, 0, 8);
// Send: DC2 ESC [ 7 q ESC [ G
_serialPort.Write(new byte[] { 0x12, 0x1B, 0x5B, 0x37, 0x71, 0x1B, 0x5B, 0X47 }, 0, 8);
So, I know that i need to add DC2 and CR commands but what is the vbs equivalent of these lines?
What are the correct configurations of the reader?(variable = value)
PARTIAL SOLUTION:
I USED
mscom1.output(portID, macaddr & "#" & vbcr)
were: portID is the com2 id macaddr is the mac addr of the scanner vbcr is the integrated vb char for carrage return
this code works and sends the read confirm after a read. but it didn't works if i need to add a command and sends only the read confirmation whitotu any command. someone have other ideas?

GoLang bitwise calculation

I have a buffer :
buffer := bytes.NewBuffer([]byte{
0x85, 0x02, 0xFF, 0xFF,
0x00, 0x01, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x03,
0x41, 0x42, 0x43,
})
I am trying to return the int value of buffer[8:24]
I get
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
Not sure how to shift such a large section. of the byte.
new to this. Any help would be great. my initial approach was
requestid := (uint64(buffer.Bytes()[8]&0xff)<<24 + uint64(buffer.Bytes()[9]&0xff)<<16 + uint64(buffer.Bytes()[10]&0xff)<<8 + uint64(buffer.Bytes()[11]&0xff.....)))
but this got tedious, and I know there has to be an easier way.
You have to do the manual bit shifting and OR'ing, but your code can be cleaned up by removing all those buffer.Bytes() calls.
You also do not need the &0xff parts. What n&0xff does, is clear out all bits outside of the 0-255 range. Since each value in the buffer is already a byte (0-255), these operations do nothing at all. If we want to do 22 & 255, we get the following:
Hexadecimal | Decimal | Binary
--------------|-------------|----------------------
x 0x16 | 22 | 00010110
y 0xff | 255 | 11111111
--------------|-------------|---------------------- AND (&)
0x16 | 22 | 00010110 = x
As you can see, the operation has no effect at all. Replace x with any 8-bit value and you will see the same result. The outcome of x & 0xff is always x.
Additionally, when you assign to the requestId, you start by shifting by 24 bits. This tells me you are reading a 32-bit integer. Why then do you continue reading values beyond 32 bits and converting it all to a 64 bit integer?
If you are reading a 64-bit int in Big Endian, try this:
data := buf.Bytes()[8:]
requestid := uint64(data[0])<<56 | uint64(data[1])<<48 |
uint64(data[2])<<40 | uint64(data[3])<<32 |
uint64(data[4])<<24 | uint64(data[5])<<16 |
uint64(data[6])<<8 | uint64(data[7])
If you are reading a 64-bit int in Little Endian, try this:
data := buf.Bytes()[8:]
requestid := uint64(data[7])<<56 | uint64(data[6])<<48 |
uint64(data[5])<<40 | uint64(data[4])<<32 |
uint64(data[3])<<24 | uint64(data[2])<<16 |
uint64(data[1])<<8 | uint64(data[0])
If you are reading a 32-bit int in Big Endian, try this:
data := buf.Bytes()[8:]
requestid := uint32(data[0])<<24 | uint32(data[1])<<16 |
uint32(data[2])<<8 | uint32(data[3])
If you are reading a 32-bit int in Little Endian, try this:
data := buf.Bytes()[8:]
requestid := uint32(data[3])<<24 | uint32(data[2])<<16 |
uint32(data[1])<<8 | uint32(data[0])
binary package
Alternatively, you can use the encoding/binary package:
var value uint64
err := binary.Read(buf, binary.LittleEndian, &value)
....

24bit USB Sample Rate Support

My question is quite similar to this question: Link, but i am not allowed to comment.
I'm implementing a PIC32 as a soundcard, and i now have a working USB audio stream, supporting 16-bit at 32kHz and 48kHz sample rates. I now want to change the bit depth to 24-bit, so i change my USB Descriptors to:
bSubFrameSize = 0x03, // 3 bytes per sample
bBitResolution = 0x18, // 24-bit resolution
When i do this, he bit resolution is changed as it is suppose to, but in the properties of the microphone, the dropdown menu where i could change the sampling frequency is grey.
I havn't changed anything in the endpoint descriptors, where both 32kHz and 48kHz still is supported.
My USB topology has 1 Audio control interface with a couple of Units, and 2 Audio Streaming Interfaces, for streaming IN and OUT.
Marc O answered his question by saying that something in his Input Terminal, i have tried changing wChannelConfig but i doesn't work.
I have tried Uninstalling and Installing the device drivers, but doesn't work.
What more do i need to change in the descriptors, to be able to select the sampling Frequency?
Thanks :)
Edit: Added Descriptor code and descriped progress
When i changed the no of channels to 2, and made the wChannelConfig = 0x03 -> right + Left Front, i saw the the field on he picture change to: "2 channel, 24 bit, 48000 Hz (Studio Quality)", but it still didn't make the dropdown menu white, and i couldn't change sample rate.
Below i've added the Audio funcion descriptors:
//CD
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_CONFIGURATION, // Configuration Descriptor (0x02)
0x10, // Total length in bytes of data returned
0x01, // 2. Byte af Total Length
0x05, // Number of Interfaces: 5 3 Audio + 2 Comm
0x01, // Configuration Value, Value to use as an argument to select this configuration
0x00, // iConfiguration, Index of String Descriptor describing this configuration
_DEFAULT | _SELF, // bmAttributes, selfpowered
0xFA, // Maximum Power : 250 mA
// ######## Audio Control Interface Descriptor
//ID - Interface Descriptor
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x00, // Number of Interface: Interface nr 0
0x00, // Value used to select alternative setting
0x00, // Number of Endpoints used for this interface, 0
AUDIO_DEVICE, // Class Code (Assigned by USB Org), AUDIO
AUDIOCONTROL, // Subclass Code (Assigned by USB Org), AUDIOCONTROL
0x00, // Protocol Code (Assigned by USB Org)
0x00, // Index of String Descriptor Describing this interface
// HEADER
0x0A, // Size : 10 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
HEADER, // HEADER descriptor subtype
0x00,0x01, // Audio Device compliant to the USB Audio specification version 1.00
0x46,0x00, // 64 bytes - Total number of bytes returned for the class-specific AudioControl interface descriptor. // Includes the combined length of this descriptor header and all Unit and Terminal descriptors.
0x02, // bInCollection -> Number of streaming interfaces = 2
0x01, // en form for index: "AudioStreaming interface 1 belongs to this AudioControl interface."
0x02, // beskriver nok streaming interface 2's index
// INPUT_TERMINAL ID = 1 USB Stream
0x0B, // size : 12 bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
INPUT_TERMINAL, // INPUT_TERMINAL - Descriptor subtype = 2
INPUT_TER_USB, // ID of this Input Terminal. // Constant uniquely identifying the Terminal within the audio function.
USB_STREAMING, // wTerminalType -> 0x0101 = USB streamming
0x00, // bAssocTerminal -> 0x00 = No association.
0x02, // bNrChannels -> 0x01 two channel.
0x03, // wChannelConfig -> 0x03 = right + Left Front
0x00, // iChannelNames -> 0x00 = Unused.
0x00, // iTerminal -> 0x00 = Unused.
// INPUT_TERMINAL ID = 4 MICROPHONE
0x0B, // size : 12 bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
INPUT_TERMINAL, // INPUT_TERMINAL - Descriptor subtype
INPUT_TER_MIC, // bTerminalID -> ID of this Input Terminal = 4
MICROPHONE, // wTerminalType -> 0x0201 = Microphone
0x00, // bAssocTerminal -> 0x00 = No association.
0x02, // bNrChannels -> 0x01 one channel.
0x03, // wChannelConfig -> 0x03 = right + Left Front
0x00, // iChannelNames -> 0x00 = Unused.
0x00, // iTerminal -> 0x00 = Unused.
// OUTPUT_TERMINAL ID = 3 SPEAKER
0x09, // size : 9 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
OUTPUT_TERMINAL, // OUTPUT_TERMINAL - Descriptor subtype
OUTPUT_TER_SPEAK, // bTerminalID -> ID of this Output Terminal = 3
SPEAKER, // wTerminalType -> 0x0301 = Speaker
0x00, // bAssocTerminal -> 0x00 = Unused
FEATURE_OUT, // bSourceID -> 0x02 = From Input Terminal ID 2 = USB stream
0x00, // iTerminal -> 0x00 = Unused.
// OUTPUT_TERMINAL ID = 6 USB Stream
0x09, // Size : 9 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
OUTPUT_TERMINAL, // OUTPUT_TERMINAL - Descriptor subtype
OUTPUT_TER_USB, // bTerminalID -> ID of this Output Terminal = 6
USB_STREAMING, // wTerminalType -> 0x0101 = USB streaming
0x00, // bAssocTerminal -> 0x00 = Unused
FEATURE_IN, // bSourceID -> 0x05 = Feature Unit that sets IN features SOURCE = 5 (Feature_IN)
0x00, // iTerminal -> 0x00 = Unused.
// FEATURE_UNIT ID = 2
0x0A, // Size : 10 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FEATURE_UNIT, // FEATURE_UNIT - Descriptor subtype
FEATURE_OUT, // bUnitID -> ID 2
INPUT_TER_USB, // bSourceID -> 0x01 = connected to Input Terminal 1 SOURCE = 1 (Input USB)
0x01, // bControlSize -> 0x01 = 1 Byte
0x03, // bmaControls(n = channel nr) -> 0x03 = Mute + volume
0x03, // bmaControls(n = channel nr) -> 0x03 = Mute + volume
0x00, // bmaControls(n = channel nr) -> 0x00 = no master control
0x00, // iFeature -> string Descriptor Unused
// FEATURE_UNIT ID = 5
0x0A, // Size : 9 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FEATURE_UNIT, // FEATURE_UNIT - Descriptor subtype
FEATURE_IN, // bUnitID -> ID 5
INPUT_TER_MIC, // bSourceID -> 0x04 = Connected to Unit ID 4 SOURCE = 4 (Input Mic.)
0x01, // bControlSize -> 0x01 = 1 Byte
0x03, // bmaControls(1) -> 0b0000011 = Mute + Volume no. of Channels +1 = no. of bmaControls
0x03, // bmaControls(2) -> 0b0000011 = Mute + Volume no. of Channels +1 = no. of bmaControls
0x00, // bmaControls(3) -> 0x00 = No controls supperted no. of Channels +1 = no. of bmaControls
0x00, // iFeature -> string Descriptor Unused
// ######## AUDIO STREAM INTERFACE 1 OUT SPEAKER
//ID // Alternate Setting 0 - 0 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x01, // bInterfaceNumber -> 0x01 Interface ID = 1
0x00, // bAlternateSetting -> 0x00 = index of this interface's alternate setting
0x00, // bNumEndpoints -> 0x00 = 0 Endpoints to this interface
AUDIO_DEVICE, // bInterfaceClass -> 0x01 = Audio Interface
AUDIOSTREAMING, // bInterfaceSubclass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused
//ID // Alternate Setting 1 - 1 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x01, // bInterfaceNumber -> 0x01 Interface ID = 1
0x01, // bAlternateSetting -> 0x01 = index of this interface's alternate setting
0x01, // bNumEndpoints -> 0x01 = 1 Endpoints to this interface
0x01, // bInterfaceClass -> 0x01 = Audio Interface
0x02, // bInterfaceSubclass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused
// ASID GENERAL
0x07, // Size : 7 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
AS_GENERAL, // bDescriptorSubtype -> 0x01 = GENERAL subtype
0x01, // bTerminalLink -> 0x01 = The Terminal ID of the Terminal to which the endpoint of this interface is connected.
0x01, // bDelay -> 0x01 = Delay (delta) introduced by the data path (see Section 3.4, ?Inter Channel Synchronization? - in Audio Devices). Expressed in number of frames.
0x01,0x00, // wFormatTag -> 0x0001 = PCM
// ASID FORMAT_TYPE
0x0E, // Size : 14 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FORMAT_TYPE, // bDescriptorSubtype -> 0x02 = FORMAT_TYPE
0x01, // bFormatType -> 0x01 = FORMAT_TYPE_I -> ref: A.1.1 Audio Data Format Type I Codes -> Audio Data Format Dok
0x02, // bNrChannels -> 0x02 = Two channels
BYTES_PR_SAMPLE, // bSubFrameSize -> 0x03 = 3 bytes pr audio subframe
BIT_RESOLUTION, // bBitResolution -> 0x18 = 24 bit pr sample
0x02, // bSamFreqType -> 0x02 = 2 sample frequencies supported
0x00,0x7D,0x00, // tSamFreq -> 0x7D00 = 32000 Hz
0x80,0xBB,0x00, // tSamFreq -> 0xBB80 = 48000 Hz
//ED ENDPOINT OUT
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_ENDPOINT, // 0x05 -> ENDPOINT Descriptor Type
0x01, // bEndpointAddress -> 0x01 = adress 1, OUT, -> ref 9.6.6 Endpoint -> usb_20 Dok
0x09, // bmAttributes -> 0b00001001 -> Bits 0-1 = 01 = Isochronous , Bits 2-3 = 10 = Adaptive
AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE ), AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE )>>8,
0x01, // bInterval -> 0x01 = 1 millisecond
0x00, // Unused
0x00, // Unused
//AS ENDPOINT
0x07, // Size : 7 Bytes
CS_ENDPOINT, // CS_ENDPOINT
EP_GENERAL, // bDescriptorSubtype -> 0x01 = GENERAL
SAMPLING_FREQ_CONTROL, // bmAttributes -> 0b00000001 = Bit 1 = 1 => Sample Freq Control is supported by this endpoint
0x00, // bLockDelayUnits -> 0x00 = Indicates the units used for the wLockDelay field: 0 = Undefined
0x00,0x00, // the time it takes this endpoint to reliably lock its internal clock recovery circuitry.
// ######## AUDIO STREAM INTERFACE 2 IN MICROPHONE
//ID // Alternate Setting 0 - 0 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x02, // bInterfaceNumber -> 0x02 Interface ID = 2
0x00, // bAlternateSetting -> 0x00 = Value used to select this alternate setting for the interface identified in the prior field
0x00, // bNumEndpoints -> 0x00 = 0 -> Number of endpoints used by this interface
AUDIO_DEVICE, // bInterfaceClass -> 0x01 = 1 = AUDIO
AUDIOSTREAMING, // bInterfaceSubClass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused -> Index of string descriptor.
//ID // Alternate Setting 1 - 1 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x02, // bInterfaceNumber -> 0x02 Interface ID = 2
0x01, // bAlternateSetting -> 0x01 = Value used to select this alternate setting for the interface identified in the prior field
0x01, // bNumEndpoints -> 0x01 = 1 -> Number of endpoints used by this interface
0x01, // bInterfaceClass -> 0x01 = 1 = AUDIO
0x02, // bInterfaceSubClass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused -> Index of string descriptor.
// ASID GENERAL
0x07, // Size : 7 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
AS_GENERAL, // GENERAL Descriptor
0x06, // bTerminalLink -> 0x06 = The Terminal ID of the Terminal to which the endpoint of this interface is connected. = 6
0x01, // bDelay -> 0x01 = Delay (delta) introduced by the data path (see Section 3.4, ?Inter Channel Synchronization? - in Audio Devices). Expressed in number of frames.
0x01,0x00, // wFormatTag -> 0x0001 = PCM
// ASID FORMAT_TYPE
0x0E, // Size : 14 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FORMAT_TYPE, // bDescriptorSubtype -> 0x02 = FORMAT_TYPE
0x01, // bFormatType -> 0x01 = FORMAT_TYPE_I -> ref: A.1.1 Audio Data Format Type I Codes -> Audio Data Format Dok
0x02, // bNrChannels -> 0x02 = Two channels
BYTES_PR_SAMPLE, // bSubFrameSize -> 0x03 = 3 bytes pr audio subframe
BIT_RESOLUTION, // bBitResolution -> 0x18 = 24 bit pr sample
0x02, // bSamFreqType -> 0x02 = 2 sample frequencies supported
0x00,0x7D,0x00, // tSamFreq -> 0x7D00 = 32000 Hz
0x80,0xBB,0x00, // tSamFreq -> 0xBB80 = 48000 Hz
//ED ENDPOINT IN
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_ENDPOINT, // 0x05 -> ENDPOINT Descriptor Type
0x82, // bEndpointAddress -> 0x82 = adress 2, IN, -> ref 9.6.6 Endpoint -> usb_20 Dok
0x05, // bmAttributes -> 0b00000101 -> Bits 0-1 = 01 = Isochronous , Bits 2-3 = 01 = Asynchronous
AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE ), AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE )>>8,
0x01, // bInterval -> 0x01 = 1 millisecond
0x00, // unused
0x00, // unused
//AS ENDPOINT
0x07, // Size : 7 Bytes
CS_ENDPOINT, // bDescriptorType -> 0x25 = CS_ENDPOINT
EP_GENERAL, // bDescriptorSubtype -> 0x01 = GENERAL
SAMPLING_FREQ_CONTROL, // bmAttributes -> 0b00000001 = Bit 1 = 1 => Sample Freq Control is supported by this endpoint
0x00, // bLockDelayUnits -> 0x00 = Indicates the units used for the wLockDelay field: 0 = Undefined
0x00,0x00, // the time it takes this endpoint to reliably lock its internal clock recovery circuitry.
This post is quite old but my reply maybe helpful to others facing the same difficulty.
I noticed that windows does not make changes to the installed drivers when the interface changes. You must manually uninstall the windows driver for your device and let windows reinstall it either on USB re-connection or reset of the device.

SIMPLE-TLV vs BER-TLV

I have found in docs they are referring to SIMPLE-TLV and BER-TLV . I was look into most of the EMV and GP docs but they have not mentioned the different.
Could anyone help me to understand the difference of two ?
Data fields in ISO/IEC 7816-4 for smart cards
BER encoding
This is the specification of the more common BER encoding used by ISO/IEC 7816-4:
Each BER-TLV data object shall consists of 2 or 3 consecutive fields
(see ISO/IEC 8825 and annex D).
The tag field T consists of one or more consecutive bytes. It encodes
a class, a type and a number. The length field consists of one or more
consecutive bytes. It encodes an integer L. If L is not null, then the
value field V consists of L consecutive bytes. If L is null, then the
data object is empty: there is no value field.
Note that ISO/IEC 7816 only allows the use of up to 5 length bytes (specifying a size up to 2^32 - 1 bytes) in the current standard. Indefinite length encoding is not supported either. These limitations are specific to smart cards. Note that 4 and 5 byte length encodings were introduced in a later version of ISO/IEC 7816-4; earlier cards / card reading applications may only support 3 length bytes (i.e. a value size up to 64KiB bytes, instead of 4GiB).
The BER TLV specification is much more expansive (which is why SIMPLE-TLV is called "simple"). I won't go into the details too much as there is plenty of information available on the internet. To name just a few differences, the tags have syntactical meaning and may consist of multiple bytes and the length encoding is rather complex.
Normally BER should only be used as an encoding of ASN.1 structures, with the ASN.1 syntax defining the structure. ISO 7816-4 however messes this up and only specifies the BER tag bytes directly.
Note that sometimes DER is specified instead of BER. In that case you should only use the minimum number of bytes for the size of the length field - e.g. a single length byte with value 05 in the samples below. The ISO/IEC specification of BER encoding is basically a copy of the US specific X.690 standard, also reflected in the international standard ISO/IEC 8825-1 (both payware).
SIMPLE-TLV encoding
The BER specification in ISO/IEC 7816-4 is followed by the SIMPLE-TLV specification. SIMPLE-TLV is specific to ISO 7816-4.
Each SIMPLE-TLV data object shall consist of 2 or 3 consecutive
fields.
The tag field T consists of a single byte encoding only a number from
1 to 254 (e.g. a record identifier). It codes no class and no
construction-type. The length field consists of 1 or 3 consecutive
bytes. If the leading byte of the length field is in the range from
'00' to 'FE', then the length field consists of a single byte encoding
an integer L valued from 0 to 254. If the leading byte is equal to
'FF', then the length field continues on the two subsequent bytes
which encode an integer L with a value from 0 to 65535. If L in not
null, then the value field V consists of consecutive bytes. If L is
null, then the data object is empty: there is no value field.
Note that the standard forgets to specify the endianness directly. You can however assume big endian encoding within ISO/IEC 7816-4.
Samples
The following samples are all used to convey the same tag number (which defines the field) and value, except one that defines tag number 31 for BER.
Sample SIMPLE-TLV
0F 05 48656C6C6F // tag number 15, length 5 then the value
0F FF0005 48656C6C6F // tag number 15, length 5 (two bytes), then the value
Sample BER-TLV:
4F 05 48656C6C6F // *application specific*, primitive encoding of tag number 15, length 5 then the value
4F 8105 48656C6C6F // the same, using two bytes to encode the length
4F 820005 48656C6C6F // the same, using three bytes to encode the length
4F 83000005 48656C6C6F // the same, using four bytes to encode the length
4F 8400000005 48656C6C6F // the same , using five bytes to encode the length
5F0F 05 48656C6C6F // **invalid** encoding of the same, with two bytes for the tag, specifiying a tag number 15 which is smaller than 31
5F1F 05 48656C6C6F // application specific, primitive encoding of **tag number 31**
In the last example with the two byte tag encoding, the first byte is 40 hex, where the first 3 leftmost bits 010 specify application specific encoding, adding the magic value 1F (31) to it to indicate that another byte will follow with the actual tag number, again 1F, so value 31.
Differences
The following differences should be noted:
SIMPLE-TLV is a different method of encoding for tag and length (although the encoding may look similar, e.g. when using a single byte to indicate the length part)
SIMPLE-TLV does not contain information about the class of the field, e.g. if it is defined for ASN.1 (because it is not linked to ASN.1)
SIMPLE-TLV does not contain information if it is primitive or constructed (primitive directly specifies a value, constructed means nested TLV structures)
SIMPLE-TLV has restrictions regarding the tag number (between 1 and 254, inclusive) and length (up to 65535)
Simple TLV simply consists of Tag (or Type), Length, and Value.
The BER-TLV is a special TLV which has one or more TLV inside its Value. So it has composite structure.
Tag1 Len1 Tag2-Len2-Value2 Tag3-Len3-Value3 ... TagN-LenN-ValueN
------------------------Value1------------------------
[Example C# code for Bert-Tlv Parser][1]:
[1]https://github.com/umitkoc/BertTlv
public class Tlv : ITlv, IFile
{
List<TlvModel> modelList=new();
string parser = "";
string length = "";
String empty = "";
string ascii = "";
int decValue = 0;
int step = 0;
public Tlv(String data)
{
TlvParser(data.Replace(" ",""));
}
public void readTag()
{
String line = "";
StreamReader sr = new StreamReader("taglist.txt");
while ((line = sr.ReadLine()) != null)
{
modelList.Add(new()
{
tag = line.Split(",")[0].Trim(),
description = line.Split(",")[1].Trim()
});
}
sr.Close();
}
public void insertTag()
{
try
{
StreamWriter sw = new StreamWriter("test.txt");
foreach (var item in modelList)
{
sw.WriteLine($"{item.tag},{item.description}");
}
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
public int writeFile(String parser)
{
StreamWriter sw = new StreamWriter("output.txt");
sw.WriteLine(parser);
sw.Close();
return 0;
}
private int TlvParser(String data, int i = 0, string tag = "")
{
if (i == 0)
{
readTag();
}
if (i < data.Length)
{
tag += data[i];
TlvModel model = getTag(tag);
if (model != null)
{
decValue = int.Parse(data.Substring(i + 1, 2), System.Globalization.NumberStyles.HexNumber);
// lengthControl(data,i+3,decValue);
if (model.description.Contains("Template"))
{
parser += $"{empty}|------ tag: {model.tag}({model.description})\n";
step += 1;
empty = Empty();
return TlvParser(data, i + 3, "");
}
else
{
parser += $"{empty}|------ tag: {model.tag}({model.description}){empty}|------ value --> {ConvertHex(data.Substring(i + 3, decValue * 2))} \n";
}
i += 3 + decValue * 2;
return TlvParser(data, i, "");
}
else
{
return TlvParser(data, i + 1, tag);
}
}
return writeFile(parser);
}
public TlvModel getTag(string tag)
{
return modelList.Find(i => i.tag == tag);
}
public string ConvertHex(string hex)
{
ascii = "";
for (int i = 0; i < hex.Length; i += 2)
{
ascii += System.Convert.ToChar(System.Convert.ToUInt32(hex.Substring(i, 2), 16));
}
return ascii;
}
private string Empty()
{
for (int s = 0; s < step; s++)
{
empty += "\t";
}
return empty;
}
public void setTag(TlvModel model)
{
modelList.Add(model);
insertTag();
}
}

Resources