Secure Boot on imx6ul using HABv4 - linux

I am currently working on performing a secure boot on the imx6ul using HABv4. I followed the steps provided in the following document.
http://marc.info/?l=u-boot&m=139227973004718&q=p5
After performing all the steps I have described below, I typed hab_status in the U-boot command prompt. Then I get the HAB Events I have shown below. The only step I did not perform is fusing the SRK table. I would like to know the following information:
Is it a must to fuse the SRK table during the development stage?
From where can I find the load address that has to specify in the csf file? I used the following value defined in the Uboot configuration file. The document AN4581 (Rev.0,10/2012) describes that start* = TEXT_BASE and that it is defined in the config.mk file. However, config.mk file is not available in my U-boot folder (Probably because I am using a newer version).
#define CONFIG_SYS_TEXT_BASE 0x87800000
AN4581(Rev. 1, 10/2015) does not provide any information regarding this.
How does the Uboot knows the starting pointer of cfs? Should we specify it in any other location?
I have specified the steps I performed below. Let me know whether anything I am doing wrongly.
Steps Performed:
Please see the steps performed below.
Built u-boot.imx enabling the secure mode.
Generated all root public key files and corresponding hash.
Created csf file with the following content. Content of the file is attached at the end.
My u-uboot.imx file is 0x60830. I extended it to 0x61000 using the following command.
objcopy -I binary -O binary --pad-to 0x61000 --gap-fill=0x5A u-boot.imx u-boot-pad.imx
Then I generated csf.bin file using the command below.
./cst -o u-boot_csf.bin -i uboot.csf
Merged image and csf data using the command below.
cat u-boot-pad.imx u-boot_csf.bin > u-boot-signed.imx
Then extended the final image to 0x63000
objcopy -I binary -O binary --pad-to 0x63000 --gap-fill=0x5A u-boot-signed.imx u-boot-signed-pad.imx
The length of the block is calculated as: Length = u-boot-pad.imx (0x61000) - IVT_OFFSET (0x400).
And added 400 to the starting address as shown below.
# Address Offset Length Data File Path
Blocks = 0x87800400 0x400 0x00060C00 "u-boot-pad.imx"
HAB Events:
HAB Configuration: 0xf0, HAB State: 0x66
--------- HAB Event 1 -----------------
event data:
0xdb 0x00 0x1c 0x42 0x33 0x18 0xc0 0x00
0xca 0x00 0x14 0x00 0x02 0xc5 0x00 0x00
0x00 0x00 0x0d 0x34 0x87 0x80 0x04 0x00
0x00 0x06 0x0c 0x00
--------- HAB Event 2 -----------------
event data:
0xdb 0x00 0x14 0x42 0x33 0x0c 0xa0 0x00
0x00 0x00 0x00 0x00 0x87 0x7f 0xf7 0xd0
0x00 0x00 0x00 0x20
--------- HAB Event 3 -----------------
event data:
0xdb 0x00 0x14 0x42 0x33 0x0c 0xa0 0x00
0x00 0x00 0x00 0x00 0x87 0x7f 0xf7 0xfc
0x00 0x00 0x01 0xf0
--------- HAB Event 4 -----------------
event data:
0xdb 0x00 0x14 0x42 0x33 0x0c 0xa0 0x00
0x00 0x00 0x00 0x00 0x87 0x7f 0xf7 0xf0
0x00 0x00 0x00 0x01
--------- HAB Event 5 -----------------
event data:
0xdb 0x00 0x14 0x42 0x33 0x0c 0xa0 0x00
0x00 0x00 0x00 0x00 0x87 0x80 0x00 0x00
0x00 0x00 0x00 0x04
Command Sequency File Description:
#Illustrative Command Sequence File Description
[Header]
Version = 4.1
Hash Algorithm = sha256
Engine = ANY
Engine Configuration = 0
Certificate Format = X509
Signature Format = CMS
[Install SRK]
File = "../crts/SRK_1_2_3_4_table.bin"
# Index of the key location in the SRK table to be installed
Source index = 0
[Install CSFK]
# Key used to authenticate the CSF data
File = "../crts/CSF1_1_sha256_2048_65537_v3_usr_crt.pem"
[Authenticate CSF]
[Install Key]
# Key to install
File= "../crts/IMG1_1_sha256_2048_65537_v3_usr_crt.pem"
# Target key slot in HAB key store where key will be installed
Target Index = 2
# Key slot index used to authenticate the key to be installed
Verification index = 0
[Authenticate Data]
# Address Offset Length Data File Path
Blocks = 0x87800400 0x400 0x00060C00 "u-boot-pad.imx"
# Key slot index used to authenticate the image data
Verification index = 2
Best Regards

Related

Different memory alignment for different buffer sizes

I'm trying to educate myself regarding stack overflows and played around a bit with these -fno-stack-protector flag and tried to understand how memory is managed in a process.
I compiled the following code (using Ubuntu 18.04.1 LTS (x86_64), gcc 7.3.0., ASLR disabled)
int main (int argc, char *argv[])
{
char buff[13];
return 0;
}
as follows: gcc -g -o main main.c -fno-stack-protector. I then evoked gdb main, b 4, run and as can be seen from the the following outputs
(gdb) print &buff
$2 = (char (*)[13]) 0x7fffffffd963
0x7fffffffd963: 0xff 0xff 0x7f 0x00 0x00 0x00 0x00 0x00
0x7fffffffd96b: 0x00 0x00 0x00 0x00 0x00 0x10 0x46 0x55
0x7fffffffd973: 0x55 0x55 0x55 0x00 0x00 0x97 0x5b 0xa0
0x7fffffffd97b: 0xf7 0xff 0x7f 0x00 0x00 0x01 0x00 0x00
(gdb) info frame 0
Stack frame at 0x7fffffffd980:
[...]
Saved registers:
rbp at 0x7fffffffd970, rip at 0x7fffffffd978
the 13 bytes allocated for the buffer follow directly after the saved base pointer rbp.
After increasing the buffer size from 13 to 21 I got the following results:
(gdb) print &buff
$3 = (char (*)[21]) 0x7fffffffd950
(gdb) x/48bx buff
0x7fffffffd950: 0x10 0x46 0x55 0x55 0x55 0x55 0x00 0x00
0x7fffffffd958: 0xf0 0x44 0x55 0x55 0x55 0x55 0x00 0x00
0x7fffffffd960: 0x50 0xda 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffd968: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffd970: 0x10 0x46 0x55 0x55 0x55 0x55 0x00 0x00
0x7fffffffd978: 0x97 0x5b 0xa0 0xf7 0xff 0x7f 0x00 0x00
(gdb) info frame 0
Stack frame at 0x7fffffffd980:
[...]
Saved registers:
rbp at 0x7fffffffd970, rip at 0x7fffffffd978
Now there are additional 11 bytes after the rbp before the buffer follows.
In the second case, why are there 11 additional bytes? Is this due to the alignment of the stack, e.g. does the buffer have to be 16 bytes aligned (a multiple of 16) starting from rbp?
Why is the memory layout different in the first case, there seems to be no alignment?
The x86-64 System V ABI requires 16-byte alignment for local or global arrays that are 16 bytes or larger, and for all C99 VLAs (which are always local).
An array uses the same alignment as its elements, except that a local or global
array variable of length at least 16 bytes or a C99 variable-length array variable
always has alignment of at least 16 bytes.4
4 The alignment requirement allows the use of SSE instructions when operating on the array.
The compiler cannot in general calculate the size of a variable-length array (VLA), but it is expected
that most VLAs will require at least 16 bytes, so it is logical to mandate that VLAs have at
least a 16-byte alignment.
Fixed-size arrays smaller than one SIMD vector (16 bytes) don't have this requirement, so they can pack efficiently in the stack layout.
Note that this doesn't apply to arrays inside structs, only to locals and globals.
(For dynamic storage, the alignment of a malloc return value must be aligned enough to hold any object up to that size, and since x86-64 SysV has maxalign_t of 16 bytes, malloc must also return 16-byte aligned pointers if the size is 16 or higher. For smaller allocations, it could return only 8B-aligned for an 8B allocation if it wanted to.)
The requirement for local arrays makes it safe to write code that passes their address to a function that requires 16-byte alignment, but this is mostly not something the ABI itself really needs to specify.
It's not something that different compilers have to agree on to link their code together, the way struct layout or the calling convention is (which registers are call-clobbered, or used for arg-passing...). The compiler basically owns the stack layout for the function it's compiling, and other functions can't assume or depend on anything about it. They'd only get pointers to your local vars if you pass pointers as function args, or store pointers into globals.
Specifying it for globals is useful, though: it makes it safe for compiler-generated auto-vectorized code to assume alignment for global arrays, even when it's an extern int[] in an object file compiled by another compiler.

How to send the APDU command to get a success response?

I have this method in my javacard applet:
public void process(APDU apdu)
{
byte[] buf = apdu.getBuffer() ;
switch(buf[ISO7816.OFFSET_INS])
{
case 0x40:
Util.arrayCopy(hello,(byte)0,buf,ISO7816.OFFSET_CDATA,(byte)5);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,(byte)5);
break;
default: ISOException.throwIt(ISO7816.SW_WRONG_INS) ;
}
}
Here hello is :
private final static byte[] hello = {0x48, 0x65, 0x6c, 0x6c, 0x6f };
and I am sending the command in the script as follows:
powerup;
// Select the installer applet
0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;
// create TestApplet applet
0x80 0xB8 0x00 0x00 0xd 0xb 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x00 0x00 0x00 0x7F;
//show hello message
0x40 0x00 0x00 0x00; //this is the command mentioned in tutorial which gave error
powerdown;
The first two commands are succeeded, but the last one gets the error as the command is not in correct format .
I also tried this command:
0x00 0x40 0x00 0x00 0x00 0x7f;
But it gave me the response 6d00 which means INS vlaue not supported.
Here is the actual Response:
CLA: 80, INS:40, P1:00,P2:00,Lc:00,Le:00,SW1:6d,SW2:00
The expected response is to get the hello value along with the success reponse 9000
I am following the tutorial
What is the proper way to give the APDU command ?
As mentioned in the answer by #BzH, command 0x40 0x00 0x00 0x00 is not correct.
The correct command is
0x80 0x40 0x00 0x00 0x00.
There is one more problem: status word 6D00 is not sent by your applet, it is sent by the card manager applet with
AID = A00000006203010801
you have selected after powerup. The card manager applet does not know INS = 0x40 instruction, therefore the status code. You have to select your applet before sending any commands:
00 A4 04 00 [Lc] [... AID of your applet instance...]
80 40 00 00 00
The card's Global Platform class byte is 0x80. So you should send:
0x80 0x40 0x00 0x00 0x00
The first APDU you are sending 0x40 0x00 0x00 0x00 is wrong, because 0x40 is considered as the class byte and 0x00 as Instruction.
Finally this command worked for me.
As the APDU commands should be given in a format,
There are four cases to be followed , when sending commands to APDU:
Case Command data Expected response data
1 No data No data
2 No data Data
3 Data No data
4 Data Data
In case 1, the length Lc is null; therefore the Lc field and the data field are empty. The length Le is also null; therefore the Le field is empty. Consequently, the body is empty.
In case 2, the length Lc is null; therefore the Lc field and the data field are empty. The length of Le is not null; therefore the Le field is present. Consequently, the body consists of the Le field.
In case 3, the length Lc is not null; therefore the Lc field is present and the data field consists of the Lc subsequent bytes. The length Le is null; therefore the Le field is empty. Consequently, the body consists of the Lc field followed by the data field.
In case 4, the length Lc is not null; therefore the Lc field is present and the data field consists of the Lc subsequent bytes. The length Le is also not null; therefore the Le field is also present. Consequently, the body consists of the Lc field followed by the data field and the Le field.
So in my case it will be case 4 , I need to send some bytes, and get some bytes.
So the command in this case should be:
0x00 0x40 0x00 0x00 0x05 0x00 0x40 0x00 0x00 0x00 0x05;
CLA INS P1 P2 Lc b1 b2 b3 b4 b5 Le
Lc- input byte length (0x05 followed by 5 bytes of input: 0x00 0x40 0x00 0x00 0x00)
Le- expeted output byte length (H,e,l,l,o in my case it is 5 bytes. Hence 0x05)
and I got the repsonse as:
CLA:00 INS:40 P1:00 P2:00 Lc:05,00,40,00,00,00 Le:05,48,65,6c,6c,6f SW1:90 SW2:00
I got the Word H,e,l,l,o in the Le field.
As suggested by #Vojta ,And another mistake I did is, I am running the command without selecting the applet,
So, the correct order should be
power up
//create installer applet
//create testapplet
//select test appplet (I missed this step in my question)
//run get Hello Command
powerdown;

Vlan interface details using NETLINK

I understand that new interface addition can be detected using RTE_NEWLINK message type in NETLINK. Netlink sends a message with which we can get index and name of the interface using (if_indextoname & if_nametoindex).
My question is , if we add a VLAN interface, it sends a message with interface name (example: eth1.10). Does this vlan number only be available in interface name
or is it available anywhere inside NL_MSG structure. I dont want to parse
interface name and get VLAN number
I executed the below code and added a vlan sub interface, but couldn't find vlan information from attribute structures. It didnt print anything even though RTM_NEWLINK detected the new interface. Please correct me if i am looking for VLAN information at a wrong place in code.
if(nl_msg_hdr->nlmsg_type == RTM_NEWLINK)
{
struct ifinfomsg *ifi;
struct rtattr *rt_attr;
int rtattrlen;
ifi = (struct ifinfomsg *) NLMSG_DATA(nl_msg_hdr);
printf("RTM_NEWLINK");
for (;RTA_OK(rt_attr, rtattrlen); rt_attr = RTA_NEXT(rt_attr, rtattrlen)) {
if (rt_attr->rta_type == IFLA_LINKINFO)
printf(" IFLA_LINKINFO \n");
if (rt_attr->rta_type == IFLA_LINK)
printf(" IFLA_LINK \n");
if (rt_attr->rta_type == IFLA_INFO_DATA)
printf(" IFLA_INFO_DATA\n");
if (rt_attr->rta_type == IFLA_VLAN_ID)
printf(" IFLA_VLAN_ID\n");
}
}
x/200bx nl_msg_hdr - 200 bytes hex-dump (VLAN ID is 33 in my case)
0x7fffffffd250: 0xa4 0x04 0x00 0x00 0x10 0x00 0x00 0x00
0x7fffffffd258: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffd260: 0x00 0x00 0x01 0x00 0x27 0x00 0x00 0x00
0x7fffffffd268: 0x02 0x10 0x00 0x00 0xff 0xff 0xff 0xff
0x7fffffffd270: 0x0d 0x00 0x03 0x00 0x76 0x65 0x74 0x68
0x7fffffffd278: 0x31 0x2e 0x33 0x33 0x00 0x00 0x00 0x00
0x7fffffffd280: 0x08 0x00 0x0d 0x00 0x00 0x00 0x00 0x00
0x7fffffffd288: 0x05 0x00 0x10 0x00 0x02 0x00 0x00 0x00
0x7fffffffd290: 0x05 0x00 0x11 0x00 0x00 0x00 0x00 0x00
0x7fffffffd298: 0x08 0x00 0x04 0x00 0xdc 0x05 0x00 0x00
0x7fffffffd2a0: 0x08 0x00 0x1b 0x00 0x00 0x00 0x00 0x00
0x7fffffffd2a8: 0x08 0x00 0x1e 0x00 0x00 0x00 0x00 0x00
0x7fffffffd2b0: 0x08 0x00 0x1f 0x00 0x01 0x00 0x00 0x00
0x7fffffffd2b8: 0x08 0x00 0x20 0x00 0x01 0x00 0x00 0x00
0x7fffffffd2c0: 0x08 0x00 0x05 0x00 0x0a 0x00 0x00 0x00
0x7fffffffd2c8: 0x05 0x00 0x21 0x00 0x01 0x00 0x00 0x00
0x7fffffffd2d0: 0x09 0x00 0x06 0x00 0x6e 0x6f 0x6f 0x70
0x7fffffffd2d8: 0x00 0x00 0x00 0x00 0x24 0x00 0x0e 0x00
0x7fffffffd2e0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffd2e8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffd2f0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffd2f8: 0x00 0x00 0x00 0x00 0x00 0x88 0xff 0xff
0x7fffffffd300: 0x0a 0x00 0x01 0x00 0x66 0x0f 0x70 0x37
0x7fffffffd308: 0x0b 0x27 0x00 0x00 0x0a 0x00 0x02 0x00
0x7fffffffd310: 0xff 0xff 0xff 0xff 0xff 0xff 0x00 0x00
The vlan info is available in RTM_NEWLINK messages: IFLA_LINKINFO / IFLA_INFO_DATA / IFLA_VLAN_ID:
# the message structure:
[ nlmsg fields ]
[ ifinfmsg fields ]
nla chain:
[ IFLA_IFNAME ]
[ IFLA_… ]
[ IFLA_LINKINFO ]
nla chain:
[ IFLA_INFO_KIND ]
...
[ IFLA_INFO_DATA ]
nla chain:
[ IFLA_VLAN_ID ]
and the corresponding code (python sample with pyroute2):
from pyroute2 import IPRoute
ip = IPRoute()
# assume `ifindex` contains VLAN interface index
nlmsg = ip.get_links(ifindex)[0]
vid = nlmsg.get_attr('IFLA_LINKINFO').\
get_attr('IFLA_INFO_DATA').\
get_attr('IFLA_VLAN_ID')
print(vid)
Checked on kernels from 2.6.32 (RHEL6.5) to 4.1.0-rc6 (F22).
And yes, you're right — one should not rely on the interface name as the source of VLAN id. The interface name can be literally any.

Linux device driver to send AND receive audio over USB

I'm trying to send/receive audio over USB from my embedded linux device to/from a Windows host.
I understand there are 2 protocols to send audio over USB - USB Audio Class 1 and 2 (UAC1 & UAC2). I found them explained here: http://www.thewelltemperedcomputer.com/HW/USB_Audio.htm.
I have currently used the existing UAC1 device driver in Linux to get audio from the host PC. It works for me. I am now trying to change the device driver to also be capable of sending audio to the host PC.
I see that there's a UAC2 driver (in the latest Linux kernel) that both sends and receives audio from the host. But I'd like to have a UAC1 driver that does that, so that I don't have to install any extra drivers on the Windows host (especially ones I have to buy: http://www.thesycon.de/eng/usb_audiodriver.shtml).
I've modified the linux device driver at linux/drivers/usb/gadget/f_audio.c (I'm using an older kernel). I've changed the USB header descriptor to include the extra endpoint for sending audio to host.
static struct usb_descriptor_header *hs_audio_desc[] = {
(struct usb_descriptor_header *)&std_ac_if_desc,
(struct usb_descriptor_header *)&ac_hdr_desc,
(struct usb_descriptor_header *)&usb_it_desc,
(struct usb_descriptor_header *)&usb_ot_desc,
(struct usb_descriptor_header *)&std_as_out_if0_desc,
(struct usb_descriptor_header *)&std_as_out_if1_desc,
(struct usb_descriptor_header *)&as_out_hdr_desc,
(struct usb_descriptor_header *)&as_out_fmt1_desc,
(struct usb_descriptor_header *)&hs_epout_desc,
(struct usb_descriptor_header *)&as_iso_out_desc,
(struct usb_descriptor_header *)&std_as_in_if0_desc,
(struct usb_descriptor_header *)&std_as_in_if1_desc,
(struct usb_descriptor_header *)&as_in_hdr_desc,
(struct usb_descriptor_header *)&as_in_fmt1_desc,
(struct usb_descriptor_header *)&hs_epin_desc,
(struct usb_descriptor_header *)&as_iso_in_desc,
NULL,
};
The OUT endpoint is defined as:
struct usb_endpoint_descriptor hs_epout_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
.wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE),
.bInterval = 4,
};
The IN endpoint is defined as:
struct usb_endpoint_descriptor hs_epin_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
.wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE),
.bInterval = 4,
};
In epautoconf.c, the bEndpointAddress field is usually OR'ed with the endpoint number. I see in my case that this is happening.
The 'bEndpointAddress' field for my OUT endpoint is 0x01 and for my IN endpoint is 0x81 when I print it in epautoconf.c.
I'm however not able to see it on the host side. On my Windows PC, I use USB View tool to see the descriptors and I see that the values are 0x00 and 0x80.
What could have possibly changed the value of bEndpointAdress?
These are the USB descriptors I see in Windows using USB View tool:
Device Descriptor:
bcdUSB: 0x0200
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x40 (64)
idVendor: 0x1D6B
idProduct: 0x0101
bcdDevice: 0x0316
iManufacturer: 0x01
0x0409: "Linux 3.2.0 with musb-hdrc"
iProduct: 0x02
0x0409: "Linux USB Audio Gadget"
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: High
Device Address: 0x13
Open Pipes: 0
Configuration Descriptor:
wTotalLength: 0x0095
bNumInterfaces: 0x03
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0xC0 (Bus Powered Self Powered )
MaxPower: 0x01 (2 Ma)
Interface Descriptor:
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x01 (Audio Control)
bInterfaceProtocol: 0x00
iInterface: 0x04
0x0409: "Topology Control"
Audio Control Interface Header Descriptor:
bLength: 0x0A
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bcdADC: 0x0100
wTotalLength: 0x001F
bInCollection: 0x02
baInterfaceNr[1]: 0x01
baInterfaceNr[2]: 0x02
Audio Control Input Terminal Descriptor:
bLength: 0x0C
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bTerminalID: 0x02
wTerminalType: 0x0201 (Microphone)
bAssocTerminal: 0x00
bNrChannels: 0x02
wChannelConfig: 0x0003
iChannelNames: 0x00
iTerminal: 0x07
Audio Control Output Terminal Descriptor:
bLength: 0x09
bDescriptorType: 0x24
bDescriptorSubtype: 0x03
bTerminalID: 0x01
wTerminalType: 0x0301 (Speaker)
bAssocTerminal: 0x00
bSoruceID: 0x00
iTerminal: 0x09
Interface Descriptor:
bInterfaceNumber: 0x01
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0B
0x0409: "Playback Inactive"
Interface Descriptor:
bInterfaceNumber: 0x01
bAlternateSetting: 0x01
bNumEndpoints: 0x01
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0C
0x0409: "Playback Active"
Audio Streaming Class Specific Interface Descriptor:
bLength: 0x07
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bTerminalLink: 0x01
bDelay: 0x01
wFormatTag: 0x0001 (PCM)
Audio Streaming Format Type Descriptor:
bLength: 0x0B
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bFormatType: 0x01
bNrChannels: 0x00
bSubframeSize: 0x02
bBitResolution: 0x10
bSamFreqType: 0x01
tSamFreq[1]: 0x00BB80 (48000 Hz)
Endpoint Descriptor:
bEndpointAddress: 0x00 OUT
Transfer Type: Isochronous
wMaxPacketSize: 0x00C8 (200)
bInterval: 0x04
Audio Streaming Class Specific Audio Data Endpoint Descriptor:
bLength: 0x07
bDescriptorType: 0x25
bDescriptorSubtype: 0x01
bmAttributes: 0x00
bLockDelayUnits: 0x00
wLockDelay: 0x0000
Interface Descriptor:
bInterfaceNumber: 0x02
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0D
0x0409: "Capture Inactive"
Interface Descriptor:
bInterfaceNumber: 0x02
bAlternateSetting: 0x01
bNumEndpoints: 0x01
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x0E
0x0409: "Capture Active"
Audio Streaming Class Specific Interface Descriptor:
bLength: 0x07
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bTerminalLink: 0x02
bDelay: 0x01
wFormatTag: 0x0001 (PCM)
Audio Streaming Format Type Descriptor:
bLength: 0x0B
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bFormatType: 0x01
bNrChannels: 0x00
bSubframeSize: 0x02
bBitResolution: 0x10
bSamFreqType: 0x01
tSamFreq[1]: 0x00BB80 (48000 Hz)
Endpoint Descriptor:
bEndpointAddress: 0x80 IN
Transfer Type: Isochronous
wMaxPacketSize: 0x00C8 (200)
bInterval: 0x04
Audio Streaming Class Specific Audio Data Endpoint Descriptor:
bLength: 0x07
bDescriptorType: 0x25
bDescriptorSubtype: 0x01
bmAttributes: 0x00
bLockDelayUnits: 0x00
wLockDelay: 0x0000
Why won't Windows install the UAC1 driver?
For my first question, I got an answer from the linux-usb mailing list. It turns out that 'epautoconf.c' does not change 'bEndpointAdress'. So I changed the value in the definition of 'bEndpointAdress' and it is correctly conveyed to the host now.
Windows installs the UAC1 driver correctly when I use this configuration:
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: High
Device Address: 0x11
Open Pipes: 0
Configuration Descriptor:
wTotalLength: 0x00E7
bNumInterfaces: 0x03
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0xC0 (Bus Powered Self Powered )
MaxPower: 0x01 (2 Ma)
Interface Descriptor:
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x01 (Audio Control)
bInterfaceProtocol: 0x00
iInterface: 0x00
Audio Control Interface Header Descriptor:
bLength: 0x0A
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bcdADC: 0x0100
wTotalLength: 0x0065
bInCollection: 0x02
baInterfaceNr[1]: 0x01
baInterfaceNr[2]: 0x02
Audio Control Input Terminal Descriptor:
bLength: 0x0C
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bTerminalID: 0x01
wTerminalType: 0x0201 (Microphone)
bAssocTerminal: 0x00
bNrChannels: 0x02
wChannelConfig: 0x0003
iChannelNames: 0x00
iTerminal: 0x00
Audio Control Feature Unit Descriptor:
bLength: 0x0A
bDescriptorType: 0x24
bDescriptorSubtype: 0x06
bUnitID: 0x02
bSourceID: 0x01
bControlSize: 0x01
bmaControls[0]:
03
bmaControls[1]:
00
bmaControls[2]:
00
iFeature: 0x00
Audio Control Input Terminal Descriptor:
bLength: 0x0C
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bTerminalID: 0x03
wTerminalType: 0x0402 (Headset)
bAssocTerminal: 0x09
bNrChannels: 0x02
wChannelConfig: 0x0003
iChannelNames: 0x00
iTerminal: 0x00
Audio Control Feature Unit Descriptor:
bLength: 0x0A
bDescriptorType: 0x24
bDescriptorSubtype: 0x06
bUnitID: 0x04
bSourceID: 0x03
bControlSize: 0x01
bmaControls[0]:
03
bmaControls[1]:
00
bmaControls[2]:
00
iFeature: 0x00
Audio Control Selector Unit Descriptor:
bLength: 0x06
bDescriptorType: 0x24
bDescriptorSubtype: 0x05
bUnitID: 0x05
bNrInPins: 0x01
baSourceID[1]: 0x04
iSelector: 0x09
Audio Control Output Terminal Descriptor:
bLength: 0x09
bDescriptorType: 0x24
bDescriptorSubtype: 0x03
bTerminalID: 0x06
wTerminalType: 0x0101 (USB streaming)
bAssocTerminal: 0x00
bSoruceID: 0x05
iTerminal: 0x00
Audio Control Input Terminal Descriptor:
bLength: 0x0C
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bTerminalID: 0x07
wTerminalType: 0x0101 (USB streaming)
bAssocTerminal: 0x00
bNrChannels: 0x02
wChannelConfig: 0x0003
iChannelNames: 0x00
iTerminal: 0x00
Audio Control Feature Unit Descriptor:
bLength: 0x0A
bDescriptorType: 0x24
bDescriptorSubtype: 0x06
bUnitID: 0x08
bSourceID: 0x0A
bControlSize: 0x01
bmaControls[0]:
01
bmaControls[1]:
02
bmaControls[2]:
02
iFeature: 0x00
Audio Control Output Terminal Descriptor:
bLength: 0x09
bDescriptorType: 0x24
bDescriptorSubtype: 0x03
bTerminalID: 0x09
wTerminalType: 0x0402 (Headset)
bAssocTerminal: 0x03
bSoruceID: 0x08
iTerminal: 0x00
Audio Control Mixer Unit Descriptor:
bLength: 0x0D
bDescriptorType: 0x24
bDescriptorSubtype: 0x04
bUnitID: 0x0A
bNrInPins: 0x02
baSourceID[1]: 0x07
baSourceID[2]: 0x02
bNrChannels: 0x02
wChannelConfig: 0x0003
iChannelNames: 0x00
bmControls:
00
iMixer: 0x00
Interface Descriptor:
bInterfaceNumber: 0x01
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x00
Interface Descriptor:
bInterfaceNumber: 0x01
bAlternateSetting: 0x01
bNumEndpoints: 0x01
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x00
Audio Streaming Class Specific Interface Descriptor:
bLength: 0x07
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bTerminalLink: 0x06
bDelay: 0x01
wFormatTag: 0x0001 (PCM)
Audio Streaming Format Type Descriptor:
bLength: 0x0B
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bFormatType: 0x01
bNrChannels: 0x02
bSubframeSize: 0x02
bBitResolution: 0x10
bSamFreqType: 0x01
tSamFreq[1]: 0x00BB80 (48000 Hz)
Endpoint Descriptor:
bEndpointAddress: 0x01 OUT
Transfer Type: Isochronous
wMaxPacketSize: 0x00C8 (200)
bInterval: 0x04
Audio Streaming Class Specific Audio Data Endpoint Descriptor:
bLength: 0x07
bDescriptorType: 0x25
bDescriptorSubtype: 0x01
bmAttributes: 0x01
bLockDelayUnits: 0x00
wLockDelay: 0x0000
Interface Descriptor:
bInterfaceNumber: 0x02
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x00
Interface Descriptor:
bInterfaceNumber: 0x02
bAlternateSetting: 0x01
bNumEndpoints: 0x01
bInterfaceClass: 0x01 (Audio)
bInterfaceSubClass: 0x02 (Audio Streaming)
bInterfaceProtocol: 0x00
iInterface: 0x00
Audio Streaming Class Specific Interface Descriptor:
bLength: 0x07
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bTerminalLink: 0x07
bDelay: 0x01
wFormatTag: 0x0001 (PCM)
Audio Streaming Format Type Descriptor:
bLength: 0x0B
bDescriptorType: 0x24
bDescriptorSubtype: 0x02
bFormatType: 0x01
bNrChannels: 0x02
bSubframeSize: 0x02
bBitResolution: 0x10
bSamFreqType: 0x01
tSamFreq[1]: 0x00BB80 (48000 Hz)
Endpoint Descriptor:
bEndpointAddress: 0x81 IN
Transfer Type: Isochronous
wMaxPacketSize: 0x00C8 (200)
bInterval: 0x04
Audio Streaming Class Specific Audio Data Endpoint Descriptor:
bLength: 0x07
bDescriptorType: 0x25
bDescriptorSubtype: 0x01
bmAttributes: 0x01
bLockDelayUnits: 0x01
wLockDelay: 0x0004

Bluetooth not write scanning using HCI

I am trying to implement Bluetooth on an existing embedded device. The controller I’m using is the LS Research TiWi-uB2, which uses the Ti CC2564 dual mode IC. The host is a LPC2378 microcontroller. The device needs to be discoverable by other devices (Android devices & PCs for the moment). There is no ready made BT stack for this device which suits me needs (cost, static memory allocation, memory size) so I’m writing my own stack.
Going through Volume 2 Part E of the specification I eventually got meaningful communication on the HCI, but the device does not ever appear to be ‘discoverable’ by anything else. At this point I’m only using the BR/EDR features rather than the LE features.
Here is a debug dump of the HCI interface (including the UART packet types):
BT_Reset
Tx: 0x01 0x03 0x0C 0x00
Rx: 0x04 0x0E 0x04 0x01 0x03 0x0C 0x00
Device info
Tx: 0x01 0x01 0x10 0x00
Rx: 0x04 0x0E 0x0C 0x01 0x01 0x10 0x00 0x06 0x00 0x00 0x06 0x0D 0x00 0x0F 0x1B
Local supported commands
Tx: 0x01 0x02 0x10 0x00
Rx: 0x04 0x0E 0x44 0x01 0x02 0x10 0x00 0xFF 0xFF 0xFF 0x03 0xCE 0xFF 0xFF 0xFF 0xFF
Local supported features
Tx: 0x01 0x03 0x10 0x00
Rx: 0x04 0x0E 0x0C 0x01 0x03 0x10 0x00 0xFF 0xFE 0x2D 0xFE 0xDB 0xFF 0x7B 0x87
Get device address
Tx: 0x01 0x09 0x10 0x00
Rx: 0x04 0x0E 0x0A 0x01 0x09 0x10 0x00 0x81 0xA6 0xD3 0x2F 0x18 0x00
Address: 00 18 2F D3 A6 81
Read buffer size
Tx: 0x01 0x05 0x10 0x00
Rx: 0x04 0x0E 0x0B 0x01 0x05 0x10 0x00 0xFD 0x03 0xB4 0x04 0x00 0x04 0x00
ACL len = 1021
Write buffer size
Tx: 0x01 0x33 0x0C 0x07 0xFC 0x00 0x00 0x00 0x00 0x00 0x00
Rx: 0x04 0x0E 0x04 0x01 0x33 0x0C 0x00
Write local name
Tx: 0x01 0x13 0x0C 0x08 0x42 0x54 0x5F 0x54 0x65 0x73 0x74 0x00
Rx: 0x04 0x0E 0x04 0x01 0x13 0x0C 0x00
Read class of device
Tx: 0x01 0x23 0x0C 0x00
Rx: 0x04 0x0E 0x07 0x01 0x23 0x0C 0x00 0x14 0x01 0x08
Write class of device
Tx: 0x01 0x24 0x0C 0x03 0x14 0x01 0x08
Rx: 0x04 0x0E 0x04 0x01 0x24 0x0C 0x00
Write scan enabled
Tx: 0x01 0x1A 0x0C 0x01 0x03
Rx: 0x04 0x0E 0x04 0x01 0x1A 0x0C 0x00
Finished
I can also do link inquiry:
Tx: 0x01 0x01 0x04 0x05 0x33 0x8B 0x9E 0x0A 0x0A
Rx: 0x04 0x0F 0x04 0x00 0x01 0x01 0x04
…
Rx: 0x04 0x01 0x01 0x00
But it does not find any devices.
I’m sure I’m missing something fairly obvious out, but can’t see what it might be. I can't see that the CC2564 needs to be specially treated to run in BR/EDR mode, and all the defaults seem reasonable.
Update
The module needs an initialization script (aka 'service pack'). See https://code.google.com/p/btstack/wiki/MSP430GettingStarted under 'Init Scripts'. The good news is that with the script the module is now discoverable. The bad news is that according to LS Research my own stack would not be Bluetooth SIG complaint - I would have to use the Bluetopia stack. It seems that everything is geared heavily to using the Ti processor.
At this point I'll have to wait until the BR/EDR/BLE modules with a higher level interface come on line.
Bluetooth compliance is only needed, when you are using public profiles (SPP for example), or when you expose your device in a connectable manner for other devices in public (like headsets or keyboards). Shortly, qualification is only needed if you are selling your device on global market as a "Bluetooth" device (so you can use the logo)...at least in my understanding...
And the service pack does not contain any part of the stack, so its completely royalty free.
And there are no Bluetooth specific operations (even discovery) permitted before loading the service pack according to this document:
cc256x guide

Resources