BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS

Dependencies:   FatFileSystem mbed

Fork of BTstack by Norimasa Okamoto

Committer:
va009039
Date:
Tue Jun 26 14:27:45 2012 +0000
Revision:
0:1ed23ab1345f
fix overflow spp_service_buffer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:1ed23ab1345f 1
va009039 0:1ed23ab1345f 2 /*
va009039 0:1ed23ab1345f 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
va009039 0:1ed23ab1345f 4
va009039 0:1ed23ab1345f 5 Permission is hereby granted, free of charge, to any person obtaining a copy
va009039 0:1ed23ab1345f 6 of this software and associated documentation files (the "Software"), to deal
va009039 0:1ed23ab1345f 7 in the Software without restriction, including without limitation the rights
va009039 0:1ed23ab1345f 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
va009039 0:1ed23ab1345f 9 copies of the Software, and to permit persons to whom the Software is
va009039 0:1ed23ab1345f 10 furnished to do so, subject to the following conditions:
va009039 0:1ed23ab1345f 11
va009039 0:1ed23ab1345f 12 The above copyright notice and this permission notice shall be included in
va009039 0:1ed23ab1345f 13 all copies or substantial portions of the Software.
va009039 0:1ed23ab1345f 14
va009039 0:1ed23ab1345f 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
va009039 0:1ed23ab1345f 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
va009039 0:1ed23ab1345f 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
va009039 0:1ed23ab1345f 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
va009039 0:1ed23ab1345f 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
va009039 0:1ed23ab1345f 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
va009039 0:1ed23ab1345f 21 THE SOFTWARE.
va009039 0:1ed23ab1345f 22 */
va009039 0:1ed23ab1345f 23
va009039 0:1ed23ab1345f 24 #include "UsbDevice.h"
va009039 0:1ed23ab1345f 25 //#define __DEBUG
va009039 0:1ed23ab1345f 26 #include "mydbg.h"
va009039 0:1ed23ab1345f 27
va009039 0:1ed23ab1345f 28 UsbDevice::UsbDevice( UsbHostMgr* pMgr, int hub, int port, int addr ) : m_pControlEp(NULL), /*m_controlEp( this, 0x00, false, USB_CONTROL, 8 ),*/
va009039 0:1ed23ab1345f 29 m_pMgr(pMgr), m_connected(false), m_enumerated(false), m_hub(hub), m_port(port), m_addr(addr), m_refs(0),
va009039 0:1ed23ab1345f 30 m_vid(0), m_pid(0)
va009039 0:1ed23ab1345f 31 {
va009039 0:1ed23ab1345f 32 m_DeviceClass = 0x00;
va009039 0:1ed23ab1345f 33 m_InterfaceClass = 0x00;
va009039 0:1ed23ab1345f 34 }
va009039 0:1ed23ab1345f 35
va009039 0:1ed23ab1345f 36 UsbDevice::~UsbDevice()
va009039 0:1ed23ab1345f 37 {
va009039 0:1ed23ab1345f 38 DBG_ASSERT(0);
va009039 0:1ed23ab1345f 39
va009039 0:1ed23ab1345f 40 if(m_pControlEp)
va009039 0:1ed23ab1345f 41 delete m_pControlEp;
va009039 0:1ed23ab1345f 42 }
va009039 0:1ed23ab1345f 43
va009039 0:1ed23ab1345f 44 UsbErr UsbDevice::enumerate()
va009039 0:1ed23ab1345f 45 {
va009039 0:1ed23ab1345f 46 VERBOSE("Hub: %d Port: %d\n", m_hub, m_port);
va009039 0:1ed23ab1345f 47 UsbErr rc;
va009039 0:1ed23ab1345f 48 DBG("%p m_hub=%d m_port=%d\n", this, m_hub, m_port);
va009039 0:1ed23ab1345f 49 DBG_ASSERT(m_pMgr);
va009039 0:1ed23ab1345f 50 m_pMgr->resetPort(m_hub, m_port);
va009039 0:1ed23ab1345f 51
va009039 0:1ed23ab1345f 52 wait_ms(400);
va009039 0:1ed23ab1345f 53
va009039 0:1ed23ab1345f 54 uint8_t temp[8];
va009039 0:1ed23ab1345f 55 DBG_ASSERT(m_pControlEp == NULL);
va009039 0:1ed23ab1345f 56 m_pControlEp = new UsbEndpoint( this, 0x00, false, USB_CONTROL, sizeof(temp), 0 );
va009039 0:1ed23ab1345f 57 DBG_ASSERT(m_pControlEp);
va009039 0:1ed23ab1345f 58 //EDCtrl->Control = 8 << 16;/* Put max pkt size = 8 */
va009039 0:1ed23ab1345f 59 /* Read first 8 bytes of device desc */
va009039 0:1ed23ab1345f 60 DBG_ASSERT(sizeof(temp) >= 8);
va009039 0:1ed23ab1345f 61 //rc = controlReceive(
va009039 0:1ed23ab1345f 62 // USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR,
va009039 0:1ed23ab1345f 63 // (USB_DESCRIPTOR_TYPE_DEVICE << 8) |(0), 0, temp, sizeof(temp));
va009039 0:1ed23ab1345f 64 //DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 65 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, temp, sizeof(temp));
va009039 0:1ed23ab1345f 66 if (rc != USBERR_OK) {
va009039 0:1ed23ab1345f 67 DBG("rc=%d\n", rc);
va009039 0:1ed23ab1345f 68 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 69 return rc;
va009039 0:1ed23ab1345f 70 }
va009039 0:1ed23ab1345f 71 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 72 DBG_BYTES("DeviceDescriptor first 8 bytes", temp, sizeof(temp));
va009039 0:1ed23ab1345f 73 DBG_ASSERT(temp[0] == 18); // bLength
va009039 0:1ed23ab1345f 74 DBG_ASSERT(temp[1] == 0x01); // bDescriptType
va009039 0:1ed23ab1345f 75 if (rc)
va009039 0:1ed23ab1345f 76 {
va009039 0:1ed23ab1345f 77 DBG("RC=%d",rc);
va009039 0:1ed23ab1345f 78 return (rc);
va009039 0:1ed23ab1345f 79 }
va009039 0:1ed23ab1345f 80 uint8_t bMaxPacketSize = temp[7];
va009039 0:1ed23ab1345f 81 DBG_ASSERT(bMaxPacketSize >= 8);
va009039 0:1ed23ab1345f 82 DBG("Got descriptor, max ep size is %d\n", bMaxPacketSize);
va009039 0:1ed23ab1345f 83
va009039 0:1ed23ab1345f 84 m_pControlEp->updateSize(bMaxPacketSize); /* Get max pkt size of endpoint 0 */
va009039 0:1ed23ab1345f 85 rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, m_addr, 0, NULL, 0); /* Set the device address to m_addr */
va009039 0:1ed23ab1345f 86 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 87 if (rc)
va009039 0:1ed23ab1345f 88 {
va009039 0:1ed23ab1345f 89 // PRINT_Err(rc);
va009039 0:1ed23ab1345f 90 return (rc);
va009039 0:1ed23ab1345f 91 }
va009039 0:1ed23ab1345f 92 wait_ms(2);
va009039 0:1ed23ab1345f 93 //EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */
va009039 0:1ed23ab1345f 94
va009039 0:1ed23ab1345f 95 //Update address
va009039 0:1ed23ab1345f 96 m_pControlEp->updateAddr(m_addr);
va009039 0:1ed23ab1345f 97 DBG("Ep addr is now %d", m_addr);
va009039 0:1ed23ab1345f 98 /**/
va009039 0:1ed23ab1345f 99
va009039 0:1ed23ab1345f 100 //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor
va009039 0:1ed23ab1345f 101 //rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR,
va009039 0:1ed23ab1345f 102 // (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0,
va009039 0:1ed23ab1345f 103 // m_controlDataBuf, 17);
va009039 0:1ed23ab1345f 104 uint8_t DeviceDesc[18];
va009039 0:1ed23ab1345f 105 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, DeviceDesc, sizeof(DeviceDesc));
va009039 0:1ed23ab1345f 106 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 107 DBG_BYTES("DeviceDescriptor", DeviceDesc, sizeof(DeviceDesc));
va009039 0:1ed23ab1345f 108 DBG_ASSERT(DeviceDesc[0] == 18);
va009039 0:1ed23ab1345f 109 DBG_ASSERT(DeviceDesc[1] == 0x01);
va009039 0:1ed23ab1345f 110 DBG_ASSERT(DeviceDesc[17] == 1); // bNumConfiguration
va009039 0:1ed23ab1345f 111 if (rc)
va009039 0:1ed23ab1345f 112 {
va009039 0:1ed23ab1345f 113 //PRINT_Err(rc);
va009039 0:1ed23ab1345f 114 return (rc);
va009039 0:1ed23ab1345f 115 }
va009039 0:1ed23ab1345f 116
va009039 0:1ed23ab1345f 117 /*
va009039 0:1ed23ab1345f 118 rc = SerialCheckVidPid();
va009039 0:1ed23ab1345f 119 if (rc != OK) {
va009039 0:1ed23ab1345f 120 PRINT_Err(rc);
va009039 0:1ed23ab1345f 121 return (rc);
va009039 0:1ed23ab1345f 122 }
va009039 0:1ed23ab1345f 123 */
va009039 0:1ed23ab1345f 124 /**/
va009039 0:1ed23ab1345f 125 m_DeviceClass = DeviceDesc[4];
va009039 0:1ed23ab1345f 126 VERBOSE("DeviceClass: %02X\n", m_DeviceClass);
va009039 0:1ed23ab1345f 127
va009039 0:1ed23ab1345f 128 m_vid = *((uint16_t*)&DeviceDesc[8]);
va009039 0:1ed23ab1345f 129 m_pid = *((uint16_t*)&DeviceDesc[10]);
va009039 0:1ed23ab1345f 130 VERBOSE("Vender: %04X\n", m_vid);
va009039 0:1ed23ab1345f 131 VERBOSE("Product: %04X\n", m_pid);
va009039 0:1ed23ab1345f 132 int iManufacture = DeviceDesc[14];
va009039 0:1ed23ab1345f 133 if (iManufacture) {
va009039 0:1ed23ab1345f 134 char str[64];
va009039 0:1ed23ab1345f 135 rc = GetString(iManufacture, str, sizeof(str));
va009039 0:1ed23ab1345f 136 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 137 VERBOSE("Manufacture: %s\n", str);
va009039 0:1ed23ab1345f 138 }
va009039 0:1ed23ab1345f 139 int iProduct = DeviceDesc[15];
va009039 0:1ed23ab1345f 140 if (iProduct) {
va009039 0:1ed23ab1345f 141 char str[64];
va009039 0:1ed23ab1345f 142 rc = GetString(iProduct, str, sizeof(str));
va009039 0:1ed23ab1345f 143 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 144 VERBOSE("Product: %s\n", str);
va009039 0:1ed23ab1345f 145 }
va009039 0:1ed23ab1345f 146 if (DeviceDesc[4] == 0x09) { // Hub
va009039 0:1ed23ab1345f 147 return hub_init();
va009039 0:1ed23ab1345f 148 }
va009039 0:1ed23ab1345f 149
va009039 0:1ed23ab1345f 150 uint8_t ConfigDesc[9];
va009039 0:1ed23ab1345f 151 int index = 0;
va009039 0:1ed23ab1345f 152 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
va009039 0:1ed23ab1345f 153 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 154 DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
va009039 0:1ed23ab1345f 155 DBG_ASSERT(ConfigDesc[0] == 9);
va009039 0:1ed23ab1345f 156 DBG_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:1ed23ab1345f 157 int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
va009039 0:1ed23ab1345f 158 DBG("TotalLength: %d\n", wTotalLength);
va009039 0:1ed23ab1345f 159 int bConfigValue = ConfigDesc[5];
va009039 0:1ed23ab1345f 160 DBG_ASSERT(bConfigValue == 1);
va009039 0:1ed23ab1345f 161 DBG("ConfigValue: %d\n", bConfigValue);
va009039 0:1ed23ab1345f 162 DBG("MaxPower: %d mA\n", ConfigDesc[8]*2);
va009039 0:1ed23ab1345f 163
va009039 0:1ed23ab1345f 164 uint8_t* buf = new uint8_t[wTotalLength];
va009039 0:1ed23ab1345f 165 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
va009039 0:1ed23ab1345f 166 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 167 DBG_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:1ed23ab1345f 168 int pos = 0;
va009039 0:1ed23ab1345f 169 while(pos < wTotalLength) {
va009039 0:1ed23ab1345f 170 DBG_BYTES("", buf+pos, buf[pos]);
va009039 0:1ed23ab1345f 171 if (buf[pos+1] == 4) { // interface ?
va009039 0:1ed23ab1345f 172 m_InterfaceClass = buf[pos+5];
va009039 0:1ed23ab1345f 173 VERBOSE("InterfaceClass: %02X\n", m_InterfaceClass);
va009039 0:1ed23ab1345f 174 break;
va009039 0:1ed23ab1345f 175 }
va009039 0:1ed23ab1345f 176 pos += buf[pos];
va009039 0:1ed23ab1345f 177 }
va009039 0:1ed23ab1345f 178 delete[] buf;
va009039 0:1ed23ab1345f 179
va009039 0:1ed23ab1345f 180 rc = setConfiguration(1);
va009039 0:1ed23ab1345f 181 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 182 if (rc)
va009039 0:1ed23ab1345f 183 {
va009039 0:1ed23ab1345f 184 // PRINT_Err(rc);
va009039 0:1ed23ab1345f 185 return rc;
va009039 0:1ed23ab1345f 186 }
va009039 0:1ed23ab1345f 187 wait_ms(100);/* Some devices may require this delay */
va009039 0:1ed23ab1345f 188
va009039 0:1ed23ab1345f 189 m_enumerated = true;
va009039 0:1ed23ab1345f 190 return USBERR_OK;
va009039 0:1ed23ab1345f 191 }
va009039 0:1ed23ab1345f 192
va009039 0:1ed23ab1345f 193 bool UsbDevice::connected()
va009039 0:1ed23ab1345f 194 {
va009039 0:1ed23ab1345f 195 return m_connected;
va009039 0:1ed23ab1345f 196 }
va009039 0:1ed23ab1345f 197
va009039 0:1ed23ab1345f 198 bool UsbDevice::enumerated()
va009039 0:1ed23ab1345f 199 {
va009039 0:1ed23ab1345f 200 return m_enumerated;
va009039 0:1ed23ab1345f 201 }
va009039 0:1ed23ab1345f 202
va009039 0:1ed23ab1345f 203 int UsbDevice::getPid()
va009039 0:1ed23ab1345f 204 {
va009039 0:1ed23ab1345f 205 return m_pid;
va009039 0:1ed23ab1345f 206 }
va009039 0:1ed23ab1345f 207
va009039 0:1ed23ab1345f 208 int UsbDevice::getVid()
va009039 0:1ed23ab1345f 209 {
va009039 0:1ed23ab1345f 210 return m_vid;
va009039 0:1ed23ab1345f 211 }
va009039 0:1ed23ab1345f 212 #if 0
va009039 0:1ed23ab1345f 213 UsbErr UsbDevice::getConfigurationDescriptor(int config, uint8_t** pBuf)
va009039 0:1ed23ab1345f 214 {
va009039 0:1ed23ab1345f 215 DBG_ASSERT(m_controlDataBuf);
va009039 0:1ed23ab1345f 216 //For now olny one config
va009039 0:1ed23ab1345f 217 *pBuf = m_controlDataBuf;
va009039 0:1ed23ab1345f 218 return USBERR_OK;
va009039 0:1ed23ab1345f 219 }
va009039 0:1ed23ab1345f 220
va009039 0:1ed23ab1345f 221 UsbErr UsbDevice::getInterfaceDescriptor(int config, int item, uint8_t** pBuf)
va009039 0:1ed23ab1345f 222 {
va009039 0:1ed23ab1345f 223 DBG_ASSERT(m_controlDataBuf);
va009039 0:1ed23ab1345f 224 byte* desc_ptr = m_controlDataBuf;
va009039 0:1ed23ab1345f 225
va009039 0:1ed23ab1345f 226 /* if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION)
va009039 0:1ed23ab1345f 227 {
va009039 0:1ed23ab1345f 228 return USBERR_BADCONFIG;
va009039 0:1ed23ab1345f 229 }*/
va009039 0:1ed23ab1345f 230 DBG_ASSERT(m_controlDataBuf);
va009039 0:1ed23ab1345f 231 if(item>=m_controlDataBuf[4])//Interfaces count
va009039 0:1ed23ab1345f 232 return USBERR_NOTFOUND;
va009039 0:1ed23ab1345f 233
va009039 0:1ed23ab1345f 234 desc_ptr += desc_ptr[0];
va009039 0:1ed23ab1345f 235
va009039 0:1ed23ab1345f 236 *pBuf = NULL;
va009039 0:1ed23ab1345f 237
va009039 0:1ed23ab1345f 238 while (desc_ptr < m_controlDataBuf + *((uint16_t*)&m_controlDataBuf[2]))
va009039 0:1ed23ab1345f 239 {
va009039 0:1ed23ab1345f 240
va009039 0:1ed23ab1345f 241 switch (desc_ptr[1]) {
va009039 0:1ed23ab1345f 242 case USB_DESCRIPTOR_TYPE_INTERFACE:
va009039 0:1ed23ab1345f 243 if(desc_ptr[2] == item)
va009039 0:1ed23ab1345f 244 {
va009039 0:1ed23ab1345f 245 *pBuf = desc_ptr;
va009039 0:1ed23ab1345f 246 return USBERR_OK;
va009039 0:1ed23ab1345f 247 }
va009039 0:1ed23ab1345f 248 desc_ptr += desc_ptr[0]; // Move to next descriptor start
va009039 0:1ed23ab1345f 249 break;
va009039 0:1ed23ab1345f 250 }
va009039 0:1ed23ab1345f 251
va009039 0:1ed23ab1345f 252 }
va009039 0:1ed23ab1345f 253
va009039 0:1ed23ab1345f 254 if(*pBuf == NULL)
va009039 0:1ed23ab1345f 255 return USBERR_NOTFOUND;
va009039 0:1ed23ab1345f 256
va009039 0:1ed23ab1345f 257 return USBERR_OK;
va009039 0:1ed23ab1345f 258 }
va009039 0:1ed23ab1345f 259 #endif
va009039 0:1ed23ab1345f 260
va009039 0:1ed23ab1345f 261 UsbErr UsbDevice::setConfiguration(int config)
va009039 0:1ed23ab1345f 262 {
va009039 0:1ed23ab1345f 263 DBG("config=%d\n", config);
va009039 0:1ed23ab1345f 264 DBG_ASSERT(config == 1);
va009039 0:1ed23ab1345f 265 UsbErr rc = controlSend(
va009039 0:1ed23ab1345f 266 USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, // 0x00
va009039 0:1ed23ab1345f 267 SET_CONFIGURATION, config, 0, 0, 0);
va009039 0:1ed23ab1345f 268 return rc;
va009039 0:1ed23ab1345f 269 }
va009039 0:1ed23ab1345f 270
va009039 0:1ed23ab1345f 271 UsbErr UsbDevice::controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len)
va009039 0:1ed23ab1345f 272 {
va009039 0:1ed23ab1345f 273 UsbErr rc;
va009039 0:1ed23ab1345f 274 fillControlBuf(requestType, request, value, index, len);
va009039 0:1ed23ab1345f 275 DBG_ASSERT(m_pControlEp);
va009039 0:1ed23ab1345f 276 m_pControlEp->setNextToken(TD_SETUP);
va009039 0:1ed23ab1345f 277 rc = m_pControlEp->transfer(m_controlBuf, 8);
va009039 0:1ed23ab1345f 278 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 279 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:1ed23ab1345f 280 if(rc)
va009039 0:1ed23ab1345f 281 return rc;
va009039 0:1ed23ab1345f 282 if(len)
va009039 0:1ed23ab1345f 283 {
va009039 0:1ed23ab1345f 284 m_pControlEp->setNextToken(TD_OUT);
va009039 0:1ed23ab1345f 285 rc = m_pControlEp->transfer((byte*)buf, len);
va009039 0:1ed23ab1345f 286 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 287 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:1ed23ab1345f 288 if(rc)
va009039 0:1ed23ab1345f 289 return rc;
va009039 0:1ed23ab1345f 290 }
va009039 0:1ed23ab1345f 291 m_pControlEp->setNextToken(TD_IN);
va009039 0:1ed23ab1345f 292 rc = m_pControlEp->transfer(NULL, 0);
va009039 0:1ed23ab1345f 293 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 294 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:1ed23ab1345f 295 if(rc)
va009039 0:1ed23ab1345f 296 return rc;
va009039 0:1ed23ab1345f 297 return USBERR_OK;
va009039 0:1ed23ab1345f 298 }
va009039 0:1ed23ab1345f 299
va009039 0:1ed23ab1345f 300 UsbErr UsbDevice::controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len)
va009039 0:1ed23ab1345f 301 {
va009039 0:1ed23ab1345f 302 DBG("buf=%p len=%d\n", buf, len);
va009039 0:1ed23ab1345f 303 UsbErr rc;
va009039 0:1ed23ab1345f 304 fillControlBuf(requestType, request, value, index, len);
va009039 0:1ed23ab1345f 305 DBG_ASSERT(m_pControlEp);
va009039 0:1ed23ab1345f 306 m_pControlEp->setNextToken(TD_SETUP);
va009039 0:1ed23ab1345f 307 rc = m_pControlEp->transfer(m_controlBuf, 8);
va009039 0:1ed23ab1345f 308 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 309 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:1ed23ab1345f 310 if(rc)
va009039 0:1ed23ab1345f 311 return rc;
va009039 0:1ed23ab1345f 312 if(len)
va009039 0:1ed23ab1345f 313 {
va009039 0:1ed23ab1345f 314 m_pControlEp->setNextToken(TD_IN);
va009039 0:1ed23ab1345f 315 rc = m_pControlEp->transfer( (byte*) buf, len);
va009039 0:1ed23ab1345f 316 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 317 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:1ed23ab1345f 318 if(rc)
va009039 0:1ed23ab1345f 319 return rc;
va009039 0:1ed23ab1345f 320 }
va009039 0:1ed23ab1345f 321 m_pControlEp->setNextToken(TD_OUT);
va009039 0:1ed23ab1345f 322 rc = m_pControlEp->transfer(NULL, 0);
va009039 0:1ed23ab1345f 323 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 324 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:1ed23ab1345f 325 if(rc)
va009039 0:1ed23ab1345f 326 return rc;
va009039 0:1ed23ab1345f 327 return USBERR_OK;
va009039 0:1ed23ab1345f 328 }
va009039 0:1ed23ab1345f 329
va009039 0:1ed23ab1345f 330 UsbErr UsbDevice::GetDescriptor(int type, int index, const byte* buf, int len)
va009039 0:1ed23ab1345f 331 {
va009039 0:1ed23ab1345f 332 DBG("type=%02X\n", type);
va009039 0:1ed23ab1345f 333 return controlReceive(
va009039 0:1ed23ab1345f 334 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR,
va009039 0:1ed23ab1345f 335 (type << 8) |(index), 0, buf, len);
va009039 0:1ed23ab1345f 336
va009039 0:1ed23ab1345f 337 }
va009039 0:1ed23ab1345f 338
va009039 0:1ed23ab1345f 339 UsbErr UsbDevice::GetString(int index, char* buf, int len)
va009039 0:1ed23ab1345f 340 {
va009039 0:1ed23ab1345f 341 DBG("index=%d buf=%p len=%d\n", index, buf, len);
va009039 0:1ed23ab1345f 342 DBG_ASSERT(index >= 1);
va009039 0:1ed23ab1345f 343 uint8_t temp[4];
va009039 0:1ed23ab1345f 344 UsbErr rc;
va009039 0:1ed23ab1345f 345 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, 0, temp, sizeof(temp));
va009039 0:1ed23ab1345f 346 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 347 DBG_BYTES("LANG_ID", temp, sizeof(temp));
va009039 0:1ed23ab1345f 348 DBG_ASSERT(temp[0] == 4);
va009039 0:1ed23ab1345f 349 DBG_ASSERT(temp[1] == 0x03);
va009039 0:1ed23ab1345f 350
va009039 0:1ed23ab1345f 351 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp, 2);
va009039 0:1ed23ab1345f 352 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 353 DBG_BYTES("length check", temp, 2);
va009039 0:1ed23ab1345f 354 if (temp[0] == 0x00 && temp[1] == 0x00) { // for pl2303
va009039 0:1ed23ab1345f 355 if (len > 0) {
va009039 0:1ed23ab1345f 356 strcpy(buf, "");
va009039 0:1ed23ab1345f 357 }
va009039 0:1ed23ab1345f 358 return rc;
va009039 0:1ed23ab1345f 359 }
va009039 0:1ed23ab1345f 360 DBG_ASSERT(temp[1] == 0x03);
va009039 0:1ed23ab1345f 361 int temp_len = temp[0];
va009039 0:1ed23ab1345f 362
va009039 0:1ed23ab1345f 363 uint8_t* temp_buf = new uint8_t[temp_len];
va009039 0:1ed23ab1345f 364 DBG_ASSERT(temp_buf);
va009039 0:1ed23ab1345f 365 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp_buf, temp_len);
va009039 0:1ed23ab1345f 366 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 367 temp_len = temp_buf[0];
va009039 0:1ed23ab1345f 368 DBG_HEX(temp_buf, temp_len);
va009039 0:1ed23ab1345f 369 int i = 0;
va009039 0:1ed23ab1345f 370 for(int pos = 2; pos < temp_len; pos+= 2) {
va009039 0:1ed23ab1345f 371 buf[i++] = temp_buf[pos];
va009039 0:1ed23ab1345f 372 DBG_ASSERT(i < len-1);
va009039 0:1ed23ab1345f 373 }
va009039 0:1ed23ab1345f 374 buf[i] = '\0';
va009039 0:1ed23ab1345f 375 delete[] temp_buf;
va009039 0:1ed23ab1345f 376 return rc;
va009039 0:1ed23ab1345f 377 }
va009039 0:1ed23ab1345f 378
va009039 0:1ed23ab1345f 379 UsbErr UsbDevice::SetInterfaceAlternate(int interface, int alternate)
va009039 0:1ed23ab1345f 380 {
va009039 0:1ed23ab1345f 381 UsbErr rc = controlSend(
va009039 0:1ed23ab1345f 382 USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE,
va009039 0:1ed23ab1345f 383 SET_INTERFACE, alternate, interface, NULL, 0);
va009039 0:1ed23ab1345f 384 return rc;
va009039 0:1ed23ab1345f 385 }
va009039 0:1ed23ab1345f 386
va009039 0:1ed23ab1345f 387 void UsbDevice::fillControlBuf(byte requestType, byte request, word value, word index, int len)
va009039 0:1ed23ab1345f 388 {
va009039 0:1ed23ab1345f 389 #ifdef __BIG_ENDIAN
va009039 0:1ed23ab1345f 390 #error "Must implement BE to LE conv here"
va009039 0:1ed23ab1345f 391 #endif
va009039 0:1ed23ab1345f 392 m_controlBuf[0] = requestType;
va009039 0:1ed23ab1345f 393 m_controlBuf[1] = request;
va009039 0:1ed23ab1345f 394 //We are in LE so it's fine
va009039 0:1ed23ab1345f 395 *((word*)&m_controlBuf[2]) = value;
va009039 0:1ed23ab1345f 396 *((word*)&m_controlBuf[4]) = index;
va009039 0:1ed23ab1345f 397 *((word*)&m_controlBuf[6]) = (word) len;
va009039 0:1ed23ab1345f 398 }
va009039 0:1ed23ab1345f 399
va009039 0:1ed23ab1345f 400