AndroidAccessory.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 The Android Open Source Project
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 #include <Max3421e.h>
00019 #include <Usb.h>
00020 #include <AndroidAccessory.h>
00021 
00022 #define USB_ACCESSORY_VENDOR_ID         0x18D1
00023 #define USB_ACCESSORY_PRODUCT_ID        0x2D00
00024 
00025 #define USB_ACCESSORY_ADB_PRODUCT_ID    0x2D01
00026 #define ACCESSORY_STRING_MANUFACTURER   0
00027 #define ACCESSORY_STRING_MODEL          1
00028 #define ACCESSORY_STRING_DESCRIPTION    2
00029 #define ACCESSORY_STRING_VERSION        3
00030 #define ACCESSORY_STRING_URI            4
00031 #define ACCESSORY_STRING_SERIAL         5
00032 
00033 #define ACCESSORY_GET_PROTOCOL          51
00034 #define ACCESSORY_SEND_STRING           52
00035 #define ACCESSORY_START                 53
00036 
00037 
00038 AndroidAccessory::AndroidAccessory(const char *manufacturer,
00039                                    const char *model,
00040                                    const char *description,
00041                                    const char *version,
00042                                    const char *uri,
00043                                    const char *serial) : manufacturer(manufacturer),
00044                                                          model(model),
00045                                                          description(description),
00046                                                          version(version),
00047                                                          uri(uri),
00048                                                          serial(serial),
00049                                                          connected(false)
00050 {
00051 
00052 }
00053 
00054 void AndroidAccessory::powerOn(void)
00055 {
00056     max.powerOn();
00057     delay(200);
00058 }
00059 
00060 int AndroidAccessory::getProtocol(byte addr)
00061 {
00062     uint16_t protocol = -1;
00063     usb.ctrlReq(addr, 0,
00064                 USB_SETUP_DEVICE_TO_HOST |
00065                 USB_SETUP_TYPE_VENDOR |
00066                 USB_SETUP_RECIPIENT_DEVICE,
00067                 ACCESSORY_GET_PROTOCOL, 0, 0, 0, 2, (char *)&protocol);
00068     return protocol;
00069 }
00070 
00071 void AndroidAccessory::sendString(byte addr, int index, const char *str)
00072 {
00073     usb.ctrlReq(addr, 0,
00074                 USB_SETUP_HOST_TO_DEVICE |
00075                 USB_SETUP_TYPE_VENDOR |
00076                 USB_SETUP_RECIPIENT_DEVICE,
00077                 ACCESSORY_SEND_STRING, 0, 0, index,
00078                 strlen(str) + 1, (char *)str);
00079 }
00080 
00081 
00082 bool AndroidAccessory::switchDevice(byte addr)
00083 {
00084     int protocol = getProtocol(addr);
00085 
00086     if (protocol == 1) {
00087         Serial.print("device supports protcol 1\n");
00088     } else {
00089         Serial.print("could not read device protocol version\n");
00090         return false;
00091     }
00092 
00093     sendString(addr, ACCESSORY_STRING_MANUFACTURER, manufacturer);
00094     sendString(addr, ACCESSORY_STRING_MODEL, model);
00095     sendString(addr, ACCESSORY_STRING_DESCRIPTION, description);
00096     sendString(addr, ACCESSORY_STRING_VERSION, version);
00097     sendString(addr, ACCESSORY_STRING_URI, uri);
00098     sendString(addr, ACCESSORY_STRING_SERIAL, serial);
00099 
00100     usb.ctrlReq(addr, 0,
00101                 USB_SETUP_HOST_TO_DEVICE |
00102                 USB_SETUP_TYPE_VENDOR |
00103                 USB_SETUP_RECIPIENT_DEVICE,
00104                 ACCESSORY_START, 0, 0, 0, 0, NULL);
00105 
00106     while (usb.getUsbTaskState() != USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
00107         max.Task();
00108         usb.Task();
00109     }
00110 
00111     return true;
00112 }
00113 
00114 // Finds the first bulk IN and bulk OUT endpoints
00115 bool AndroidAccessory::findEndpoints(byte addr, EP_RECORD *inEp, EP_RECORD *outEp)
00116 {
00117     int len;
00118     byte err;
00119     uint8_t *p;
00120 
00121     err = usb.getConfDescr(addr, 0, 4, 0, (char *)descBuff);
00122     if (err) {
00123         Serial.print("Can't get config descriptor length\n");
00124         return false;
00125     }
00126 
00127 
00128     len = descBuff[2] | ((int)descBuff[3] << 8);
00129     if (len > sizeof(descBuff)) {
00130         Serial.print("config descriptor too large\n");
00131             /* might want to truncate here */
00132         return false;
00133     }
00134 
00135     err = usb.getConfDescr(addr, 0, len, 0, (char *)descBuff);
00136     if (err) {
00137         Serial.print("Can't get config descriptor\n");
00138         return false;
00139     }
00140 
00141     p = descBuff;
00142     inEp->epAddr = 0;
00143     outEp->epAddr = 0;
00144     while (p < (descBuff + len)){
00145         uint8_t descLen = p[0];
00146         uint8_t descType = p[1];
00147         USB_ENDPOINT_DESCRIPTOR *epDesc;
00148         EP_RECORD *ep;
00149 
00150         switch (descType) {
00151         case USB_DESCRIPTOR_CONFIGURATION:
00152             Serial.print("config desc\n");
00153             break;
00154 
00155         case USB_DESCRIPTOR_INTERFACE:
00156             Serial.print("interface desc\n");
00157             break;
00158 
00159         case USB_DESCRIPTOR_ENDPOINT:
00160             epDesc = (USB_ENDPOINT_DESCRIPTOR *)p;
00161             if (!inEp->epAddr && (epDesc->bEndpointAddress & 0x80))
00162                 ep = inEp;
00163             else if (!outEp->epAddr)
00164                 ep = outEp;
00165             else
00166                 ep = NULL;
00167 
00168             if (ep) {
00169                 ep->epAddr = epDesc->bEndpointAddress & 0x7f;
00170                 ep->Attr = epDesc->bmAttributes;
00171                 ep->MaxPktSize = epDesc->wMaxPacketSize;
00172                 ep->sndToggle = bmSNDTOG0;
00173                 ep->rcvToggle = bmRCVTOG0;
00174             }
00175             break;
00176 
00177         default:
00178             Serial.print("unkown desc type ");
00179             Serial.println( descType, HEX);
00180             break;
00181         }
00182 
00183         p += descLen;
00184     }
00185 
00186     if (!(inEp->epAddr && outEp->epAddr))
00187         Serial.println("can't find accessory endpoints");
00188 
00189     return inEp->epAddr && outEp->epAddr;
00190 }
00191 
00192 bool AndroidAccessory::configureAndroid(void)
00193 {
00194     byte err;
00195     EP_RECORD inEp, outEp;
00196 
00197     if (!findEndpoints(1, &inEp, &outEp))
00198         return false;
00199 
00200     memset(&epRecord, 0x0, sizeof(epRecord));
00201 
00202     epRecord[inEp.epAddr] = inEp;
00203     if (outEp.epAddr != inEp.epAddr)
00204         epRecord[outEp.epAddr] = outEp;
00205 
00206     in = inEp.epAddr;
00207     out = outEp.epAddr;
00208 
00209     Serial.println(inEp.epAddr, HEX);
00210     Serial.println(outEp.epAddr, HEX);
00211 
00212     epRecord[0] = *(usb.getDevTableEntry(0,0));
00213     usb.setDevTableEntry(1, epRecord);
00214 
00215     err = usb.setConf( 1, 0, 1 );
00216     if (err) {
00217         Serial.print("Can't set config to 1\n");
00218         return false;
00219     }
00220 
00221     usb.setUsbTaskState( USB_STATE_RUNNING );
00222 
00223     return true;
00224 }
00225 
00226 bool AndroidAccessory::isConnected(void)
00227 {
00228     USB_DEVICE_DESCRIPTOR *devDesc = (USB_DEVICE_DESCRIPTOR *) descBuff;
00229     byte err;
00230 
00231     max.Task();
00232     usb.Task();
00233 
00234     if (!connected &&
00235         usb.getUsbTaskState() >= USB_STATE_CONFIGURING &&
00236         usb.getUsbTaskState() != USB_STATE_RUNNING) {
00237         Serial.print("\nDevice addressed... ");
00238         Serial.print("Requesting device descriptor.\n");
00239 
00240         err = usb.getDevDescr(1, 0, 0x12, (char *) devDesc);
00241         if (err) {
00242             Serial.print("\nDevice descriptor cannot be retrieved. Trying again\n");
00243             return false;
00244         }
00245 
00246         if (isAccessoryDevice(devDesc)) {
00247             Serial.print("found android acessory device\n");
00248 
00249             connected = configureAndroid();
00250         } else {
00251             Serial.print("found possible device. swithcing to serial mode\n");
00252             switchDevice(1);
00253         }
00254     } else if (usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
00255         if (connected)
00256             Serial.println("disconnect\n");
00257         connected = false;
00258     }
00259 
00260     return connected;
00261 }
00262 
00263 int AndroidAccessory::read(void *buff, int len, unsigned int nakLimit)
00264 {
00265     return usb.newInTransfer(1, in, len, (char *)buff, nakLimit);
00266 }
00267 
00268 int AndroidAccessory::write(void *buff, int len)
00269 {
00270     usb.outTransfer(1, out, len, (char *)buff);
00271     return len;
00272 }
00273 


rosserial_adk_demo
Author(s): Adam Stambler
autogenerated on Mon Dec 2 2013 12:02:02