Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
0:ac1725ba162c
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 0:ac1725ba162c 1
segundo 0:ac1725ba162c 2 /*
segundo 0:ac1725ba162c 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
segundo 0:ac1725ba162c 4
segundo 0:ac1725ba162c 5 Permission is hereby granted, free of charge, to any person obtaining a copy
segundo 0:ac1725ba162c 6 of this software and associated documentation files (the "Software"), to deal
segundo 0:ac1725ba162c 7 in the Software without restriction, including without limitation the rights
segundo 0:ac1725ba162c 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
segundo 0:ac1725ba162c 9 copies of the Software, and to permit persons to whom the Software is
segundo 0:ac1725ba162c 10 furnished to do so, subject to the following conditions:
segundo 0:ac1725ba162c 11
segundo 0:ac1725ba162c 12 The above copyright notice and this permission notice shall be included in
segundo 0:ac1725ba162c 13 all copies or substantial portions of the Software.
segundo 0:ac1725ba162c 14
segundo 0:ac1725ba162c 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
segundo 0:ac1725ba162c 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
segundo 0:ac1725ba162c 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
segundo 0:ac1725ba162c 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
segundo 0:ac1725ba162c 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
segundo 0:ac1725ba162c 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
segundo 0:ac1725ba162c 21 THE SOFTWARE.
segundo 0:ac1725ba162c 22 */
segundo 0:ac1725ba162c 23
segundo 0:ac1725ba162c 24 #include "netCfg.h"
segundo 0:ac1725ba162c 25 #if NET_UMTS
segundo 0:ac1725ba162c 26
segundo 0:ac1725ba162c 27 #include "UMTSStick.h"
segundo 0:ac1725ba162c 28
segundo 0:ac1725ba162c 29 #define __DEBUG
segundo 0:ac1725ba162c 30 #include "dbg/dbg.h"
segundo 0:ac1725ba162c 31
segundo 0:ac1725ba162c 32 UMTSStick::UMTSStick() : m_host(), m_pDev(NULL)
segundo 0:ac1725ba162c 33 {
segundo 0:ac1725ba162c 34
segundo 0:ac1725ba162c 35 }
segundo 0:ac1725ba162c 36
segundo 0:ac1725ba162c 37 UMTSStick::~UMTSStick()
segundo 0:ac1725ba162c 38 {
segundo 0:ac1725ba162c 39
segundo 0:ac1725ba162c 40 }
segundo 0:ac1725ba162c 41
segundo 0:ac1725ba162c 42
segundo 0:ac1725ba162c 43 UMTSStickErr UMTSStick::getSerial(UsbSerial** ppUsbSerial)
segundo 0:ac1725ba162c 44 {
segundo 0:ac1725ba162c 45 m_host.init();
segundo 0:ac1725ba162c 46
segundo 0:ac1725ba162c 47 UMTSStickErr rc;
segundo 0:ac1725ba162c 48
segundo 0:ac1725ba162c 49 rc = waitForDevice();
segundo 0:ac1725ba162c 50 if(rc)
segundo 0:ac1725ba162c 51 return rc;
segundo 0:ac1725ba162c 52
segundo 0:ac1725ba162c 53 //Device is now enumerated, read table
segundo 0:ac1725ba162c 54
segundo 0:ac1725ba162c 55 uint16_t vid = m_pDev->getVid();
segundo 0:ac1725ba162c 56 uint16_t pid = m_pDev->getPid();
segundo 0:ac1725ba162c 57
segundo 0:ac1725ba162c 58 DBG("Configuration set: vid:%04x pid:%04x\n", vid, pid);
segundo 0:ac1725ba162c 59
segundo 0:ac1725ba162c 60 bool handled = false;
segundo 0:ac1725ba162c 61 bool cdfs = false;
segundo 0:ac1725ba162c 62 const UMTSSwitchingInfo* pInfo;
segundo 0:ac1725ba162c 63 for(int i = 0; i < UMTS_SWITCHING_COUNT; i++)
segundo 0:ac1725ba162c 64 {
segundo 0:ac1725ba162c 65 pInfo = &UMTSwitchingTable[i];
segundo 0:ac1725ba162c 66 if( !checkDeviceState(pInfo, &cdfs) )
segundo 0:ac1725ba162c 67 {
segundo 0:ac1725ba162c 68 handled = true;
segundo 0:ac1725ba162c 69 break;
segundo 0:ac1725ba162c 70 }
segundo 0:ac1725ba162c 71
segundo 0:ac1725ba162c 72 } //for(int i = 0; i < UMTS_SWITCHING_COUNT; i++)
segundo 0:ac1725ba162c 73
segundo 0:ac1725ba162c 74 if(!handled)
segundo 0:ac1725ba162c 75 {
segundo 0:ac1725ba162c 76 DBG("Don't know this device!\n");
segundo 0:ac1725ba162c 77 return UMTSERR_NOTIMPLEMENTED;
segundo 0:ac1725ba162c 78 }
segundo 0:ac1725ba162c 79
segundo 0:ac1725ba162c 80 //Check if the device is in CDFS mode, in this case switch
segundo 0:ac1725ba162c 81 if(cdfs)
segundo 0:ac1725ba162c 82 {
segundo 0:ac1725ba162c 83 DBG("Switching the device by sending a magic packet\n");
segundo 0:ac1725ba162c 84
segundo 0:ac1725ba162c 85 rc = switchMode(pInfo);
segundo 0:ac1725ba162c 86 if(rc)
segundo 0:ac1725ba162c 87 return rc;
segundo 0:ac1725ba162c 88
segundo 0:ac1725ba162c 89 DBG("Now wait for device to reconnect\n");
segundo 0:ac1725ba162c 90
segundo 0:ac1725ba162c 91 m_host.releaseDevice(m_pDev);
segundo 0:ac1725ba162c 92
segundo 0:ac1725ba162c 93 //Wait for device to reconnect
segundo 0:ac1725ba162c 94 wait(3);
segundo 0:ac1725ba162c 95 rc = waitForDevice();
segundo 0:ac1725ba162c 96 if(rc)
segundo 0:ac1725ba162c 97 return rc;
segundo 0:ac1725ba162c 98 }
segundo 0:ac1725ba162c 99
segundo 0:ac1725ba162c 100 rc = findSerial(ppUsbSerial);
segundo 0:ac1725ba162c 101 if(rc)
segundo 0:ac1725ba162c 102 return rc;
segundo 0:ac1725ba162c 103
segundo 0:ac1725ba162c 104 return UMTSERR_OK;
segundo 0:ac1725ba162c 105 }
segundo 0:ac1725ba162c 106
segundo 0:ac1725ba162c 107 UMTSStickErr UMTSStick::waitForDevice()
segundo 0:ac1725ba162c 108 {
segundo 0:ac1725ba162c 109 bool ready = false;
segundo 0:ac1725ba162c 110 while(!ready)
segundo 0:ac1725ba162c 111 {
segundo 0:ac1725ba162c 112 while(!m_host.devicesCount())
segundo 0:ac1725ba162c 113 {}
segundo 0:ac1725ba162c 114 wait(1);
segundo 0:ac1725ba162c 115 if(m_host.devicesCount())
segundo 0:ac1725ba162c 116 ready = true;
segundo 0:ac1725ba162c 117 }
segundo 0:ac1725ba162c 118
segundo 0:ac1725ba162c 119 wait(2); //Wait for device to be initialized
segundo 0:ac1725ba162c 120
segundo 0:ac1725ba162c 121 if(!m_host.devicesCount())
segundo 0:ac1725ba162c 122 return UMTSERR_DISCONNECTED;
segundo 0:ac1725ba162c 123
segundo 0:ac1725ba162c 124 m_pDev = m_host.getDevice(0);
segundo 0:ac1725ba162c 125
segundo 0:ac1725ba162c 126 while(!m_pDev->enumerated())
segundo 0:ac1725ba162c 127 {
segundo 0:ac1725ba162c 128 m_host.poll();
segundo 0:ac1725ba162c 129 if(!m_host.devicesCount())
segundo 0:ac1725ba162c 130 return UMTSERR_DISCONNECTED;
segundo 0:ac1725ba162c 131 }
segundo 0:ac1725ba162c 132
segundo 0:ac1725ba162c 133 return UMTSERR_OK;
segundo 0:ac1725ba162c 134 }
segundo 0:ac1725ba162c 135
segundo 0:ac1725ba162c 136 UMTSStickErr UMTSStick::checkDeviceState(const UMTSSwitchingInfo* pInfo, bool* pCdfs)
segundo 0:ac1725ba162c 137 {
segundo 0:ac1725ba162c 138 uint16_t vid = m_pDev->getVid();
segundo 0:ac1725ba162c 139 uint16_t pid = m_pDev->getPid();
segundo 0:ac1725ba162c 140 bool handled = false;
segundo 0:ac1725ba162c 141 if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) )
segundo 0:ac1725ba162c 142 {
segundo 0:ac1725ba162c 143 DBG("Match on dongles list\n");
segundo 0:ac1725ba162c 144 if( !pInfo->targetClass ) //No specific interface to check, vid/pid couple is specific to CDFS mode
segundo 0:ac1725ba162c 145 {
segundo 0:ac1725ba162c 146 DBG("Found device in CDFS mode\n");
segundo 0:ac1725ba162c 147 handled = true;
segundo 0:ac1725ba162c 148 *pCdfs = true;
segundo 0:ac1725ba162c 149 }
segundo 0:ac1725ba162c 150 else //if( !pInfo->targetClass )
segundo 0:ac1725ba162c 151 {
segundo 0:ac1725ba162c 152 //Has to check if there is an interface of class targetClass
segundo 0:ac1725ba162c 153 byte* desc = NULL;
segundo 0:ac1725ba162c 154 int c = 0;
segundo 0:ac1725ba162c 155
segundo 0:ac1725ba162c 156 while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) )
segundo 0:ac1725ba162c 157 {
segundo 0:ac1725ba162c 158 if( desc[5] == pInfo->targetClass )
segundo 0:ac1725ba162c 159 {
segundo 0:ac1725ba162c 160 DBG("Found device in Serial mode\n");
segundo 0:ac1725ba162c 161 handled = true;
segundo 0:ac1725ba162c 162 *pCdfs = false;
segundo 0:ac1725ba162c 163 break;
segundo 0:ac1725ba162c 164 }
segundo 0:ac1725ba162c 165 }
segundo 0:ac1725ba162c 166
segundo 0:ac1725ba162c 167 if(!handled)
segundo 0:ac1725ba162c 168 {
segundo 0:ac1725ba162c 169 //All interfaces were tried, so we are in CDFS mode
segundo 0:ac1725ba162c 170 DBG("Found device in CDFS mode\n");
segundo 0:ac1725ba162c 171 handled = true;
segundo 0:ac1725ba162c 172 *pCdfs = true;
segundo 0:ac1725ba162c 173 }
segundo 0:ac1725ba162c 174 } //if( !pInfo->targetClass )
segundo 0:ac1725ba162c 175 } //if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) )
segundo 0:ac1725ba162c 176 else
segundo 0:ac1725ba162c 177 {
segundo 0:ac1725ba162c 178 //Try every vid/pid couple of the serial list
segundo 0:ac1725ba162c 179 for( int i = 0; i < 16 ; i++)
segundo 0:ac1725ba162c 180 {
segundo 0:ac1725ba162c 181 if(!pInfo->serialPidList[i])
segundo 0:ac1725ba162c 182 break;
segundo 0:ac1725ba162c 183 if( (pInfo->serialVid == vid) && (pInfo->serialPidList[i] == pid) )
segundo 0:ac1725ba162c 184 {
segundo 0:ac1725ba162c 185 DBG("Found device in Serial mode\n");
segundo 0:ac1725ba162c 186 handled = true;
segundo 0:ac1725ba162c 187 *pCdfs = false;
segundo 0:ac1725ba162c 188 break;
segundo 0:ac1725ba162c 189 }
segundo 0:ac1725ba162c 190 }
segundo 0:ac1725ba162c 191 } //if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) )
segundo 0:ac1725ba162c 192
segundo 0:ac1725ba162c 193 if(!handled)
segundo 0:ac1725ba162c 194 return UMTSERR_NOTFOUND;
segundo 0:ac1725ba162c 195
segundo 0:ac1725ba162c 196 return UMTSERR_OK;
segundo 0:ac1725ba162c 197 }
segundo 0:ac1725ba162c 198
segundo 0:ac1725ba162c 199 UMTSStickErr UMTSStick::switchMode(const UMTSSwitchingInfo* pInfo)
segundo 0:ac1725ba162c 200 {
segundo 0:ac1725ba162c 201 if(!pInfo->huaweiPacket) //Send SCSI packet on first bulk ep
segundo 0:ac1725ba162c 202 {
segundo 0:ac1725ba162c 203 //Find first bulk ep
segundo 0:ac1725ba162c 204 byte* desc = NULL;
segundo 0:ac1725ba162c 205 int c = 0;
segundo 0:ac1725ba162c 206
segundo 0:ac1725ba162c 207 UsbEndpoint *pEpOut = NULL;
segundo 0:ac1725ba162c 208
segundo 0:ac1725ba162c 209 while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) )
segundo 0:ac1725ba162c 210 {
segundo 0:ac1725ba162c 211 byte* p = desc;
segundo 0:ac1725ba162c 212 int epNum = 0;
segundo 0:ac1725ba162c 213 p = p + p[0]; //Move to next descriptor (which should be an ep descriptor)
segundo 0:ac1725ba162c 214 while (epNum < desc[4]) //Eps count in this if
segundo 0:ac1725ba162c 215 {
segundo 0:ac1725ba162c 216 if (p[1] != USB_DESCRIPTOR_TYPE_ENDPOINT)
segundo 0:ac1725ba162c 217 break;
segundo 0:ac1725ba162c 218
segundo 0:ac1725ba162c 219 if( (p[3] == 0x02) && !(p[2] & 0x80) ) //Bulk endpoint, out
segundo 0:ac1725ba162c 220 {
segundo 0:ac1725ba162c 221 DBG("Found bulk ep %02x\n", p[2]);
segundo 0:ac1725ba162c 222 pEpOut = new UsbEndpoint( m_pDev, p[2], false, USB_BULK, *((uint16_t*)&p[4]) );
segundo 0:ac1725ba162c 223 break;
segundo 0:ac1725ba162c 224 }
segundo 0:ac1725ba162c 225
segundo 0:ac1725ba162c 226 p = p + p[0]; //Move to next ep desc
segundo 0:ac1725ba162c 227 epNum++;
segundo 0:ac1725ba162c 228 }
segundo 0:ac1725ba162c 229 if(pEpOut)
segundo 0:ac1725ba162c 230 break;
segundo 0:ac1725ba162c 231 }
segundo 0:ac1725ba162c 232
segundo 0:ac1725ba162c 233 if(!pEpOut)
segundo 0:ac1725ba162c 234 return UMTSERR_NOTFOUND;
segundo 0:ac1725ba162c 235
segundo 0:ac1725ba162c 236 //Send SCSI packet
segundo 0:ac1725ba162c 237
segundo 0:ac1725ba162c 238 DBG("Sending SCSI Packet to switch\n");
segundo 0:ac1725ba162c 239 byte ramCdfsBuf[31];
segundo 0:ac1725ba162c 240 memcpy(ramCdfsBuf, pInfo->cdfsPacket, 31);
segundo 0:ac1725ba162c 241 pEpOut->transfer((volatile byte*)ramCdfsBuf, 31);
segundo 0:ac1725ba162c 242 while(pEpOut->status() == USBERR_PROCESSING);
segundo 0:ac1725ba162c 243 int ret = pEpOut->status();
segundo 0:ac1725ba162c 244 if((ret < 0) && (ret !=USBERR_DISCONNECTED)) //Packet was not transfered
segundo 0:ac1725ba162c 245 {
segundo 0:ac1725ba162c 246 DBG("Usb error %d\n", ret);
segundo 0:ac1725ba162c 247 delete pEpOut;
segundo 0:ac1725ba162c 248 return UMTSERR_USBERR;
segundo 0:ac1725ba162c 249 }
segundo 0:ac1725ba162c 250
segundo 0:ac1725ba162c 251 delete pEpOut;
segundo 0:ac1725ba162c 252 }
segundo 0:ac1725ba162c 253 else
segundo 0:ac1725ba162c 254 {
segundo 0:ac1725ba162c 255 UsbErr usbErr;
segundo 0:ac1725ba162c 256 //Send the Huawei-specific control packet
segundo 0:ac1725ba162c 257 usbErr = m_pDev->controlSend(0, 0x03, 1, 0, NULL, 0);
segundo 0:ac1725ba162c 258 if(usbErr && (usbErr != USBERR_DISCONNECTED))
segundo 0:ac1725ba162c 259 return UMTSERR_USBERR;
segundo 0:ac1725ba162c 260 }
segundo 0:ac1725ba162c 261
segundo 0:ac1725ba162c 262 DBG("The stick should be switching in serial mode now\n");
segundo 0:ac1725ba162c 263
segundo 0:ac1725ba162c 264 return UMTSERR_OK;
segundo 0:ac1725ba162c 265 }
segundo 0:ac1725ba162c 266
segundo 0:ac1725ba162c 267 UMTSStickErr UMTSStick::findSerial(UsbSerial** ppUsbSerial)
segundo 0:ac1725ba162c 268 {
segundo 0:ac1725ba162c 269 byte* desc = NULL;
segundo 0:ac1725ba162c 270 int c = 0;
segundo 0:ac1725ba162c 271
segundo 0:ac1725ba162c 272 int epOut = 0;
segundo 0:ac1725ba162c 273 int epIn = 0;
segundo 0:ac1725ba162c 274
segundo 0:ac1725ba162c 275 while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) )
segundo 0:ac1725ba162c 276 {
segundo 0:ac1725ba162c 277 byte* p = desc;
segundo 0:ac1725ba162c 278 int epNum = 0;
segundo 0:ac1725ba162c 279
segundo 0:ac1725ba162c 280 DBG("Interface of type %02x\n", desc[5]);
segundo 0:ac1725ba162c 281
segundo 0:ac1725ba162c 282 if(desc[5] != 0xFF) //Not a serial-like if
segundo 0:ac1725ba162c 283 continue;
segundo 0:ac1725ba162c 284
segundo 0:ac1725ba162c 285 p = p + p[0]; //Move to next descriptor (which should be an ep descriptor)
segundo 0:ac1725ba162c 286 while (epNum < desc[4]) //Eps count in this if
segundo 0:ac1725ba162c 287 {
segundo 0:ac1725ba162c 288 if (p[1] == USB_DESCRIPTOR_TYPE_ENDPOINT)
segundo 0:ac1725ba162c 289 {
segundo 0:ac1725ba162c 290 if( (p[3] == 0x02) && !(p[2] & 0x80) && !epOut ) //Bulk endpoint, out
segundo 0:ac1725ba162c 291 {
segundo 0:ac1725ba162c 292 DBG("Found bulk out ep %02x of payload size %04x\n", p[2], *((uint16_t*)&p[4]));
segundo 0:ac1725ba162c 293 epOut = p[2] & 0x7F;
segundo 0:ac1725ba162c 294 }
segundo 0:ac1725ba162c 295
segundo 0:ac1725ba162c 296 if( (p[3] == 0x02) && (p[2] & 0x80) && !epIn ) //Bulk endpoint, in
segundo 0:ac1725ba162c 297 {
segundo 0:ac1725ba162c 298 DBG("Found bulk in ep %02x of payload size %04x\n", p[2], *((uint16_t*)&p[4]));
segundo 0:ac1725ba162c 299 epIn = p[2] & 0x7F;
segundo 0:ac1725ba162c 300 }
segundo 0:ac1725ba162c 301
segundo 0:ac1725ba162c 302 if(epOut && epIn)
segundo 0:ac1725ba162c 303 break;
segundo 0:ac1725ba162c 304 }
segundo 0:ac1725ba162c 305
segundo 0:ac1725ba162c 306 p = p + p[0]; //Move to next ep desc
segundo 0:ac1725ba162c 307 epNum++;
segundo 0:ac1725ba162c 308 }
segundo 0:ac1725ba162c 309
segundo 0:ac1725ba162c 310 if(epOut && epIn)
segundo 0:ac1725ba162c 311 break;
segundo 0:ac1725ba162c 312 }
segundo 0:ac1725ba162c 313
segundo 0:ac1725ba162c 314 if(!epOut || !epIn)
segundo 0:ac1725ba162c 315 return UMTSERR_NOTFOUND;
segundo 0:ac1725ba162c 316
segundo 0:ac1725ba162c 317 DBG("Endpoints found, create serial object\n");
segundo 0:ac1725ba162c 318
segundo 0:ac1725ba162c 319 *ppUsbSerial = new UsbSerial(m_pDev, epIn, epOut);
segundo 0:ac1725ba162c 320
segundo 0:ac1725ba162c 321 DBG("UsbSerial object created\n");
segundo 0:ac1725ba162c 322
segundo 0:ac1725ba162c 323 return UMTSERR_OK;
segundo 0:ac1725ba162c 324 }
segundo 0:ac1725ba162c 325
segundo 0:ac1725ba162c 326 #endif