From: Jeremy Rosen <jeremy.rosen@openwide.fr>
To: alsa-devel@alsa-project.org
Subject: Problem using alsa to implement an Android dock
Date: Mon, 10 Jun 2013 11:03:05 +0200 (CEST) [thread overview]
Message-ID: <312118621.168631.1370854985139.JavaMail.root@openwide.fr> (raw)
In-Reply-To: <14938206.164554.1370852219153.JavaMail.root@openwide.fr>
[-- Attachment #1: Type: text/plain, Size: 1658 bytes --]
Hello everybody
I am trying to implement an android dock on linux, and there is some
cases where alsa seems to not properly recognise the Android phone as
a USB sound device...
First a little bit of context
since Android 4.1 it is possible to put an android phone (connected
to a PC via USB) in "dock mode" Basically you send a couple of special
USB packet to the phone and the phone will disconnect from the USB
bus then reconnect as a USB sound device. You can then use any tool
to handle it as an audio source and redirct the sound to your speaker.
For those intereset the details can be found at
http://source.android.com/tech/accessories/aoap/aoa2.html
This works really well, no problem with that...
However Android also has something called "accessory mode" which is
used to create custom apps that communicate in "raw" mode with the host
my problems arrive when both the dock mode and the accessory mode are
enabled. in that case Alsa will not recognise the usb sound device exposed
by android. It will create an entry for it in /proc/asound but there
are no mixer or input stream
I attach the output of lsusb -v in both cases and a small C program that
I use to put the phone in the proper modes
(there is a small section of code to (un)comment to en/disable accessory
mode, it uses libusb for usb access and should be trivial to compile with
it)
At this point I am not sure how to proceed, is this a real bug or something
not implemented ? what extra info do I need to provide ? any help would
be welcome
Regards
Jérémy Rosen
fight key loggers : write some perl using vim
[-- Attachment #2: audio_accessory.txt --]
[-- Type: text/plain, Size: 5845 bytes --]
Bus 002 Device 010: ID 18d1:2d04 Google Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x18d1 Google Inc.
idProduct 0x2d04
bcdDevice 2.28
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 133
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 0
iInterface 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 40
bInCollection 2
baInterfaceNr( 0) 0
baInterfaceNr( 1) 1
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 0
bNrChannels 2
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 3
wTerminalType 0x0101 USB Streaming
bAssocTerminal 2
bSourceID 2
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 2
bSourceID 1
bControlSize 2
bmaControls( 0) 0x00
bmaControls( 0) 0x00
iFeature 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 1
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 44100
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 13
Transfer Type Isochronous
Synch Type Synchronous
Usage Type Data
wMaxPacketSize 0x0100 1x 256 bytes
bInterval 4
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 1 Milliseconds
wLockDelay 1 Milliseconds
[-- Attachment #3: audio_only.txt --]
[-- Type: text/plain, Size: 5099 bytes --]
Bus 002 Device 008: ID 18d1:2d02 Google Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x18d1 Google Inc.
idProduct 0x2d02
bcdDevice 2.28
iManufacturer 1 LGE
iProduct 2 Nexus 4
iSerial 3 0076aa569a181282
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 110
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 40
bInCollection 2
baInterfaceNr( 0) 0
baInterfaceNr( 1) 1
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 0
bNrChannels 2
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 3
wTerminalType 0x0101 USB Streaming
bAssocTerminal 2
bSourceID 2
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 2
bSourceID 1
bControlSize 2
bmaControls( 0) 0x00
bmaControls( 0) 0x00
iFeature 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 1
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 44100
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 13
Transfer Type Isochronous
Synch Type Synchronous
Usage Type Data
wMaxPacketSize 0x0100 1x 256 bytes
bInterval 4
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 1 Milliseconds
wLockDelay 1 Milliseconds
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0000
(Bus Powered)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: usbAccConfig.c --]
[-- Type: text/x-csrc; name=usbAccConfig.c, Size: 4818 bytes --]
/*
usbAccConfig.c
copyright (c) 2013 Jeremy Rosen <jeremy.rosen@openwide.fr>
usbAccConfig is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
usbAccConfig is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with usbAccConfig. If not, see <http://www.gnu.org/licenses/>.
if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <usb.h>
#include <libusb.h>
#include <string.h>
#include <unistd.h>
// VID and PID of phones in Android accessory mode
#define GOOGLE_VID 0x18d1
#define ACCESSORY_PID_BASE 0x2D00
// Parameters passed to Android to recognise the device
#define MANUFACTURER "Openwide"
#define MODEL "TestUsbAccessory"
#define DESCRIPTION "A simple program to test the accessory mode of Android phones"
#define VERSION "1.0"
#define URI "http://linuxembedded.fr"
#define SERIAL "N/A"
// Capabilities detected on the Android device
#define CAPABILITY_ACC 1<<0
#define CAPABILITY_ADB 1<<1
#define CAPABILITY_AUDIO 1<<2
typedef struct {
int vid;
int pid;
} usb_identifier;
usb_identifier skipped_id[] = {
// hardwired : list of embedded peripherals of the raspberry-pi
{0x0424,0x9512},
{0x1d6b,0x0002},
{0x0424,0xec00},
{GOOGLE_VID,ACCESSORY_PID_BASE},
{GOOGLE_VID,ACCESSORY_PID_BASE + 1},
{GOOGLE_VID,ACCESSORY_PID_BASE + 2},
{GOOGLE_VID,ACCESSORY_PID_BASE + 3},
{GOOGLE_VID,ACCESSORY_PID_BASE + 4},
{GOOGLE_VID,ACCESSORY_PID_BASE + 5},
{0,0}
};
static int pollDevice(int vid, int pid);
int main (int argc, char *argv[]){
libusb_init(NULL);
if(argc < 3) {
printf("no device vid pid on command line\n");
return 0;
} else {
int vid = strtol(argv[1],NULL,0);
int pid = strtol(argv[2],NULL,0);
usb_identifier *id = skipped_id;
while(id->pid || id->vid) {
if(vid == id->vid && pid == id->pid) {
printf("device skipped");
return 0;
}
id++;
}
if(!pollDevice(vid,pid)) {
libusb_exit(NULL);
printf("Given device isn't an android device\n");
return 0;
}
}
printf( "Done, no errors. Device should reappear as an android accessory\n");
libusb_exit(NULL);
return 0;
}
// sends the correct sequence to check if it is an android device
// if it is, puts the device in accessory mode and return 1
// if it isn't, return 0
static int pollDevice(int vid, int pid) {
unsigned char ioBuffer[2];
int devVersion;
int response=0;
struct libusb_device_handle* handle;
if((handle = libusb_open_device_with_vid_pid(NULL, vid, pid)) == NULL) goto error;
// poll protocol : is this an android device ?
response = libusb_control_transfer( handle, 0xC0, 51, 0, 0, ioBuffer, 2, 0);
if(response < 0) goto error;
devVersion = ioBuffer[1] << 8 | ioBuffer[0];
printf("Version Code Device: %d\n", devVersion);
if(devVersion == 0) {
// not an android device
goto error;
}
usleep(1000);//sometimes hangs on the next transfer :(
/**** Comment the following block to disable Accessory mode ******/
#if 0
response = libusb_control_transfer(handle,0x40,52,0,0,(unsigned char*)MANUFACTURER,strlen(MANUFACTURER)+1,0);
if(response < 0) goto error;
response = libusb_control_transfer(handle,0x40,52,0,1,(unsigned char*)MODEL,strlen(MODEL)+1,0);
if(response < 0) goto error;
response = libusb_control_transfer(handle,0x40,52,0,2,(unsigned char*)DESCRIPTION,strlen(DESCRIPTION)+1,0);
if(response < 0) goto error;
response = libusb_control_transfer(handle,0x40,52,0,3,(unsigned char*)VERSION,strlen(VERSION)+1,0);
if(response < 0) goto error;
response = libusb_control_transfer(handle,0x40,52,0,4,(unsigned char*)URI,strlen(URI)+1,0);
if(response < 0) goto error;
response = libusb_control_transfer(handle,0x40,52,0,5,(unsigned char*)SERIAL,strlen(SERIAL)+1,0);
if(response < 0) goto error;
#endif
/***** Comment the following block to disable audio accessory mode ***/
#if 1
if(devVersion >= 2) {
printf("Sending Audio mode request\n");
response = libusb_control_transfer(handle,0x40,58,1,0,NULL,0,0);
if(response < 0) goto error;
}
#endif
/**** fin de la section à supprimer ****/
printf("Sending Accessory Identification \n");
response = libusb_control_transfer(handle,0x40,53,0,0,NULL,0,0);
if(response < 0) goto error;
libusb_close(handle);
return 1;
error:
if(response) printf("USB error : %s\n",libusb_error_name(response));
libusb_close(handle);
return 0;
}
[-- Attachment #5: Type: text/plain, Size: 0 bytes --]
next parent reply other threads:[~2013-06-10 9:03 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <14938206.164554.1370852219153.JavaMail.root@openwide.fr>
2013-06-10 9:03 ` Jeremy Rosen [this message]
2013-06-10 12:02 ` Problem using alsa to implement an Android dock Clemens Ladisch
2013-06-10 12:37 ` Jeremy Rosen
2013-06-11 19:44 ` Clemens Ladisch
2013-06-12 15:16 ` Jeremy Rosen
2013-06-12 15:30 ` Clemens Ladisch
2013-06-12 15:43 ` Jeremy Rosen
2013-06-12 20:08 ` Clemens Ladisch
2013-06-13 8:24 ` Jeremy Rosen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=312118621.168631.1370854985139.JavaMail.root@openwide.fr \
--to=jeremy.rosen@openwide.fr \
--cc=alsa-devel@alsa-project.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.