All of lore.kernel.org
 help / color / mirror / Atom feed
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 --]



       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.