javaextensions/comm/src.s60/nativecommconnection.cpp
changeset 21 2a9601315dfc
child 87 1627c337e51e
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  ?Description
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <stdlib.h>
       
    21 #include <stdio.h>
       
    22 #include <usbman.h>
       
    23 #include <acminterface.h>
       
    24 #include "logger.h"
       
    25 #include "javacommonutils.h"
       
    26 #include "s60commonutils.h"
       
    27 #include "com_nokia_mj_impl_comm_CommConnectionImpl.h"
       
    28 #include "nativecommconnection.h"
       
    29 #include "fs_methodcall.h"
       
    30 
       
    31 
       
    32 #if defined (__WINS__)
       
    33 _LIT(PDD_NAME,"ECDRV");
       
    34 _LIT(LDD_NAME,"ECOMM");
       
    35 #else
       
    36 _LIT(PDD_NAME, "EUART1");
       
    37 _LIT(LDD_NAME, "ECOMM");
       
    38 #endif
       
    39 
       
    40 _LIT(KSymbianIRComm1, "IRComm");
       
    41 _LIT(KSymbianIRComm2, "IRCOMM");
       
    42 _LIT(KSymbianComm,"COMM");
       
    43 _LIT(KSymbianAcm,"ACM");
       
    44 _LIT(KSymbianBTComm1,"BTComm");
       
    45 _LIT(KSymbianBTComm2,"BTCOMM");
       
    46 _LIT(KSymbianECUART,"ECUART");
       
    47 
       
    48 enum TCOMMOPTIONSINDEX
       
    49 {
       
    50     ECommBaudRateIndex = com_nokia_mj_impl_comm_CommConnectionImpl_COMM_BAUDRATE_INDEX,
       
    51 
       
    52     ECommBitsPerCharIndex = com_nokia_mj_impl_comm_CommConnectionImpl_COMM_BITSPERCHAR_INDEX,
       
    53 
       
    54     ECommStopBitsIndex = com_nokia_mj_impl_comm_CommConnectionImpl_COMM_STOPBITS_INDEX,
       
    55 
       
    56     ECommParityIndex = com_nokia_mj_impl_comm_CommConnectionImpl_COMM_PARITY_INDEX,
       
    57 
       
    58     ECommBlockingIndex = com_nokia_mj_impl_comm_CommConnectionImpl_COMM_BLOCKING_INDEX,
       
    59 
       
    60     ECommAutoRtsIndex = com_nokia_mj_impl_comm_CommConnectionImpl_COMM_AUTORTS_INDEX,
       
    61 
       
    62     ECommAutoCtsIndex = com_nokia_mj_impl_comm_CommConnectionImpl_COMM_AUTOCTS_INDEX
       
    63 };
       
    64 
       
    65 using namespace java::util;
       
    66 using namespace java::comm;
       
    67 
       
    68 NativeCommConnection::NativeCommConnection(FunctionServer *aFuncServ) :  mConnectionIsOpen(false),mInternalBuf(NULL),mInternalBuflength(0)
       
    69 {
       
    70     JELOG2(ESOCKET);
       
    71     iFuncServ = aFuncServ;
       
    72     mPortNames.insert(TPair("IR", "IRComm"));
       
    73     mPortNames.insert(TPair("USB", "ACM"));
       
    74     mPortNames.insert(TPair("COM", "COMM"));
       
    75     mPortNames.insert(TPair("BT", "BTComm"));
       
    76     mReadInProgress = false;
       
    77     mWriteInProgress = false;
       
    78 }
       
    79 
       
    80 NativeCommConnection::~NativeCommConnection()
       
    81 {
       
    82     JELOG2(ESOCKET);
       
    83 
       
    84 }
       
    85 
       
    86 int NativeCommConnection::doGetBaudRate()
       
    87 {
       
    88     JELOG2(ESOCKET);
       
    89     if (mConnectionIsOpen == false)
       
    90         return -1;
       
    91     return TBpsToTInt(mCommConfig.iRate);
       
    92 
       
    93 }
       
    94 int NativeCommConnection::getBaudRate()
       
    95 {
       
    96     JELOG2(ESOCKET);
       
    97     int rate = 0;
       
    98     CallMethod(rate,this, &NativeCommConnection::doGetBaudRate,iFuncServ);
       
    99     ILOG1(ESOCKET, "NativeCommConnection::getBaudRate(), returning %d",rate);
       
   100     return rate;
       
   101 
       
   102 }
       
   103 
       
   104 int NativeCommConnection::doSetBaudRate(const int aBaudRate)
       
   105 {
       
   106     JELOG2(ESOCKET);
       
   107     int oldvalue = doGetBaudRate();
       
   108     TBps tmpRate = mCommConfig.iRate;       // store the old rate, in case the setConfig fails, restore back this old one
       
   109 
       
   110     mCommConfig.iRate = TIntToTBps(aBaudRate);
       
   111     TCommConfig configBuf;
       
   112     TCommConfigV01& configRef = configBuf();
       
   113     configRef = mCommConfig;
       
   114     int ret = mComm.SetConfig(configBuf);
       
   115     if (ret < 0)
       
   116     {
       
   117         ELOG1(ESOCKET, "NativeCommConnection::doSetBaudRate(), setConfig failed for input %d",aBaudRate);
       
   118         /* value provided in aBaudRate is not supported, so restore back the old one */
       
   119         mCommConfig.iRate = tmpRate;
       
   120     }
       
   121     return oldvalue;
       
   122 }
       
   123 
       
   124 int NativeCommConnection::setBaudRate(const int aBaudRate)
       
   125 {
       
   126     int oldRate = 0;
       
   127     CallMethod(oldRate,this, &NativeCommConnection::doSetBaudRate,aBaudRate,iFuncServ);
       
   128     return oldRate;
       
   129 }
       
   130 
       
   131 int NativeCommConnection::writeBytes(JNIEnv& aJni, jbyteArray aJavaBuffer,
       
   132                                      int aOffset, int aLength)
       
   133 {
       
   134     JELOG2(ESOCKET);
       
   135     TBuf8<512> writeBuffer;
       
   136     int ret = S60CommonUtils::CopyToNative(aJni, aJavaBuffer, aOffset, aLength,
       
   137                                            writeBuffer);
       
   138     ILOG(ESOCKET, "NativeCommConnection::writeBytes(), copy to native completed");
       
   139 
       
   140     //TDesC8 tmp = writeBuffer.
       
   141     int handle = reinterpret_cast<int>(this);
       
   142     int bufhandle = reinterpret_cast<int>(&writeBuffer);
       
   143 
       
   144 
       
   145     //TRequestStatus status;
       
   146     //  mComm.Write(status, writeBuffer);
       
   147     //  User::WaitForRequest(status);
       
   148 
       
   149     int retValue = 0;
       
   150     CallMethod(retValue,this, &NativeCommConnection::doWrite,handle,bufhandle,iFuncServ);
       
   151 
       
   152     if (retValue != KErrNone)
       
   153     {
       
   154         ELOG1(ESOCKET, "NativeCommConnection::writeBytes() failed, status = %d",retValue);
       
   155         return retValue;
       
   156     }
       
   157     else
       
   158     {
       
   159         int tmp = writeBuffer.Length();
       
   160         return aLength;
       
   161     }
       
   162 
       
   163 }
       
   164 
       
   165 
       
   166 int NativeCommConnection::doWrite(int aNativeCommConnectionHandle, int aBufferHandle)
       
   167 {
       
   168     JELOG2(ESOCKET);
       
   169     mWriteInProgress = true;
       
   170     NativeCommConnection *nativeObj = reinterpret_cast<NativeCommConnection*>(aNativeCommConnectionHandle);
       
   171     //TBuf8<512> writeBuffer = reinterpret_cast<TBuf8<512>>(aBufferHandle);
       
   172     TDesC8* writeBuffer = reinterpret_cast<TDesC8*>(aBufferHandle);
       
   173     TBuf8<512> tmp;
       
   174 
       
   175     TRequestStatus status;
       
   176     nativeObj->mComm.Write(status,*writeBuffer);
       
   177     User::WaitForRequest(status);
       
   178     ILOG1(ESOCKET, "NativeCommConnection::doWrite(), status = %d",status.Int());
       
   179     return status.Int();
       
   180 }
       
   181 
       
   182 int NativeCommConnection::doRead(JNIEnv& aJni, jbyteArray aJavaBuffer)
       
   183 {
       
   184     JELOG2(ESOCKET);
       
   185 
       
   186     if (mInternalBuf!=NULL)
       
   187     {
       
   188         TPtrC8 tmpPtr(mInternalBuf->Des());
       
   189         /* available was called before read, so copy the data already read, which is store in internal buffer */
       
   190         S60CommonUtils::CopyToJava(aJni, tmpPtr, aJavaBuffer, 0,
       
   191                                    mInternalBuflength);
       
   192         mInternalBuf = NULL;
       
   193         ILOG1(ESOCKET, "--NativeCommConnection::doRead(), copied from internal buffer ,len = %d",mInternalBuflength);
       
   194         return mInternalBuflength;
       
   195     }
       
   196 
       
   197     mReadInProgress = true;
       
   198     ILOG(ESOCKET, "NativeCommConnection::doRead(), continuing");
       
   199     TRequestStatus status;
       
   200     TBuf8<512> readBuffer;
       
   201     mComm.ReadOneOrMore(status, readBuffer); // block until at least 1 byte of data is read
       
   202     User::WaitForRequest(status);
       
   203     int length = readBuffer.Length();
       
   204     TPtrC8 receiveBufferPtr = readBuffer.Ptr();
       
   205 
       
   206 
       
   207     if (status.Int() == KErrNone)
       
   208     {
       
   209 
       
   210         S60CommonUtils::CopyToJava(aJni, readBuffer, aJavaBuffer, 0,
       
   211                                    length);
       
   212     }
       
   213     if (status.Int() != KErrNone)
       
   214     {
       
   215         return status.Int(); // error code
       
   216     }
       
   217     else
       
   218     {
       
   219         ILOG1(ESOCKET, "NativeCommConnection::doRead(), read successfully, length = %d",length);
       
   220         return length;
       
   221     }
       
   222 
       
   223 }
       
   224 
       
   225 int NativeCommConnection::readBytes(JNIEnv& aJni, jbyteArray aJavaBuffer)
       
   226 {
       
   227     JELOG2(ESOCKET);
       
   228     int ret = 0;
       
   229     CallMethod(ret,this,&NativeCommConnection::doRead,aJni,aJavaBuffer,iFuncServ);
       
   230     return ret;
       
   231 }
       
   232 
       
   233 void NativeCommConnection::initializePortSettings(int *aNumericOptions)
       
   234 {
       
   235     JELOG2(ESOCKET);
       
   236     // mCommConfig holds the current configuration, update it with new values
       
   237     TParity parity;
       
   238     if (aNumericOptions[ECommParityIndex] == 1)
       
   239     {
       
   240         parity = EParityOdd;
       
   241         mCommConfig.iParity = parity;
       
   242     }
       
   243     else if (aNumericOptions[ECommParityIndex] == 2)
       
   244     {
       
   245         parity = EParityEven;
       
   246         mCommConfig.iParity = parity;
       
   247     }
       
   248 
       
   249     if (aNumericOptions[ECommAutoCtsIndex] == 1)
       
   250         mCommConfig.iHandshake |= KConfigObeyCTS; // option: autocts
       
   251     else
       
   252         mCommConfig.iHandshake &= ~KConfigObeyCTS;
       
   253 
       
   254     if (aNumericOptions[ECommAutoRtsIndex] == 1)
       
   255         mCommConfig.iHandshake |= KConfigFreeRTS; // option: autorts
       
   256     else
       
   257         mCommConfig.iHandshake &= ~KConfigFreeRTS;
       
   258 
       
   259     if (aNumericOptions[ECommBaudRateIndex] != -1)
       
   260         doSetBaudRate(aNumericOptions[ECommBaudRateIndex]); // option: baudrate
       
   261 
       
   262     if (aNumericOptions[ECommBitsPerCharIndex] == 7)
       
   263         mCommConfig.iDataBits = EData7; //  option: bitsperchar
       
   264     else
       
   265         mCommConfig.iDataBits = EData8;
       
   266 
       
   267     if (aNumericOptions[ECommStopBitsIndex] == 1)
       
   268         mCommConfig.iStopBits = EStop1; // option: stopbits
       
   269     else
       
   270         mCommConfig.iStopBits = EStop2;
       
   271 
       
   272     TCommConfig configBuf1;
       
   273     TCommConfigV01& configRef = configBuf1();
       
   274     configRef = mCommConfig;
       
   275     mComm.SetConfig(configBuf1); // set the new configuration
       
   276 
       
   277 }
       
   278 
       
   279 std::basic_string<char> NativeCommConnection::mapToSymbianPortName(
       
   280     const std::string aJavaPortName)
       
   281 {
       
   282     JELOG2(ESOCKET);
       
   283     std::map<std::string, std::string>::iterator itr = mPortNames.find(
       
   284                 aJavaPortName);
       
   285     if (itr != mPortNames.end())
       
   286     {
       
   287         return itr->second; // take the value string <name,value>
       
   288     }
       
   289     return NULL;
       
   290 }
       
   291 
       
   292 int NativeCommConnection::openPortConnection(std::string aJavaPortName, int aPortNumber, int *aNumericOptions)
       
   293 {
       
   294     int ret = 0;
       
   295     CallMethod(ret,this,&NativeCommConnection::openCommPortConnection,aJavaPortName,aPortNumber,aNumericOptions,iFuncServ);
       
   296     return ret;
       
   297 }
       
   298 
       
   299 int NativeCommConnection::openCommPortConnection(
       
   300     const std::string aJavaPortName, int aPortNumber, int *aNumericOptions)
       
   301 {
       
   302     JELOG2(ESOCKET);
       
   303     mNativePortName = mapToSymbianPortName(aJavaPortName);
       
   304     int ret = connectToCommServer();
       
   305     if (ret != KErrNone)
       
   306     {
       
   307         return ret; // error occurred
       
   308     }
       
   309 
       
   310     // RComm.Open() takes the argument port id in the form "IR::0" (or) "ACM::1" ,...
       
   311     // The java port number always starts from 1( MIDP spec).
       
   312     // So convert this java port number to actual native port number using the base index stored previously.
       
   313 
       
   314     std::basic_string<char> prtname;
       
   315     char portNumberString[50];
       
   316     sprintf(portNumberString, "%d", (aPortNumber + mPortLowIndex) - 1);
       
   317     prtname = mNativePortName + "::" + portNumberString;
       
   318 
       
   319     /* convert from string to TBuf16 */
       
   320     TBuf8<50> portNameUTF;
       
   321     TBuf16<50> portname;
       
   322     TPtrC8 portNamePtr((TText8*) prtname.c_str());
       
   323     portNameUTF.Copy(portNamePtr);
       
   324     portname.Copy(portNameUTF); // convert from TBuf8 to TBuf16, because RCommServer.open() accepts only TDesc16 type
       
   325 
       
   326     char* t5 = (char *)prtname.c_str();
       
   327 
       
   328     ret = mComm.Open(mCommServer, portname, ECommExclusive);
       
   329     if (ret == KErrNone)
       
   330     {
       
   331         ILOG(ESOCKET, "openCommPortConnection() success");
       
   332         mConnectionIsOpen = true;
       
   333         TCommConfig cBuf;
       
   334         TCommConfigV01& c = cBuf();
       
   335         mComm.Config(cBuf);
       
   336         mCommConfig = c;
       
   337         initializePortSettings(aNumericOptions);
       
   338     }
       
   339     ELOG1(ESOCKET, "--NativeCommConnection::openCommPortConnection()",2);
       
   340     return ret;
       
   341 }
       
   342 
       
   343 void NativeCommConnection::doOpenConnnection(int portNameHandle)
       
   344 {
       
   345     JELOG2(ESOCKET);
       
   346     char *t2 = reinterpret_cast<char*>(portNameHandle);
       
   347     TBuf8<50> portNameUTF;
       
   348     TBuf16<50> portname;
       
   349     TPtrC8 portNamePtr((TText8*) t2);
       
   350     portNameUTF.Copy(portNamePtr);
       
   351     portname.Copy(portNameUTF);
       
   352 
       
   353 
       
   354     int rc = mComm.Open(mCommServer, portname, ECommExclusive);
       
   355     if (rc != KErrNone)
       
   356     {
       
   357         ELOG1(ESOCKET, "NativeCommConnection open failed: %d", rc);
       
   358     }
       
   359 }
       
   360 
       
   361 void NativeCommConnection::doStopReading()
       
   362 {
       
   363     mComm.ReadCancel();     // cancel the read
       
   364     mReadInProgress = false;
       
   365     if (!mWriteInProgress)
       
   366     {
       
   367         ILOG(ESOCKET, "++NativeCommConnection::doStopReading(), releasing the connection");
       
   368         /* if there is no write going on, then release the comm port */
       
   369         mComm.Close();
       
   370         mCommServer.Close();
       
   371         mConnectionIsOpen = false;
       
   372     }
       
   373 }
       
   374 
       
   375 void NativeCommConnection::stopReading()
       
   376 {
       
   377     JELOG2(ESOCKET);
       
   378     CallMethod(this, &NativeCommConnection::doStopReading,iFuncServ);
       
   379     // cancel any pending read operation
       
   380 }
       
   381 
       
   382 void NativeCommConnection::doStopWriting()
       
   383 {
       
   384     mComm.WriteCancel();
       
   385     mWriteInProgress = false;
       
   386 }
       
   387 
       
   388 void NativeCommConnection::stopWriting()
       
   389 {
       
   390     // cancel any pending write operation
       
   391     JELOG2(ESOCKET);
       
   392     CallMethod(this, &NativeCommConnection::doStopWriting,iFuncServ);
       
   393 }
       
   394 
       
   395 int NativeCommConnection::doAvailable()
       
   396 {
       
   397     TRequestStatus status;
       
   398     TBuf8<512> readBuffer;
       
   399     mComm.ReadOneOrMore(status, readBuffer); // block until at least 1 byte of data is read
       
   400     User::WaitForRequest(status);
       
   401     int length = readBuffer.Length();
       
   402     TPtrC8 receiveBufferPtr = readBuffer.Ptr();
       
   403     if (status.Int() == KErrNone)
       
   404     {
       
   405         TRAPD(err,mInternalBuf = HBufC8::NewL(length));
       
   406         if (err < 0)
       
   407         {
       
   408             return err;
       
   409         }
       
   410         TPtr8 tmpPtr(mInternalBuf->Des());
       
   411         tmpPtr.Copy(readBuffer);
       
   412         mInternalBuflength = length;
       
   413         return length;
       
   414     }
       
   415     else
       
   416         return 0;
       
   417 
       
   418 }
       
   419 
       
   420 int NativeCommConnection::available()
       
   421 {
       
   422     JELOG2(ESOCKET);
       
   423     int ret;
       
   424     CallMethod(ret,this, &NativeCommConnection::doAvailable,iFuncServ);
       
   425     ILOG1(ESOCKET, "NativeCommConnection::available(), returning %d",ret);
       
   426     return ret;
       
   427 }
       
   428 
       
   429 int NativeCommConnection::connectToCommServer()
       
   430 {
       
   431     JELOG2(ESOCKET);
       
   432     int ret = 0;
       
   433     User::LoadPhysicalDevice(PDD_NAME); // load physical device drivers
       
   434     User::LoadLogicalDevice(LDD_NAME); // load logical device drivers
       
   435 
       
   436     ret = mCommServer.Connect();
       
   437     if (ret != KErrNone)
       
   438         return -ret;
       
   439 
       
   440     /* convert from std::string * to TBuf16 */
       
   441     TBuf8<50> portNameUTF;
       
   442     TBuf16<50> portname;
       
   443     TPtrC8 portNamePtr((TText8*) mNativePortName.c_str()); // covert c-style char* to symbian specific TPtr8
       
   444     portNameUTF.Copy(portNamePtr);
       
   445     portname.Copy(portNameUTF);
       
   446 
       
   447     /* Load the comm module corresponding to the name */
       
   448     if (portname.Match(KSymbianIRComm1) != KErrNotFound)
       
   449         ret = mCommServer.LoadCommModule(KSymbianIRComm2);
       
   450     else if (portname.Match(KSymbianComm) != KErrNotFound)
       
   451         ret = mCommServer.LoadCommModule(KSymbianECUART);
       
   452     else if (portname.Match(KSymbianBTComm1) != KErrNotFound)
       
   453         ret = mCommServer.LoadCommModule(KSymbianBTComm2);
       
   454     else if (portname.Match(KSymbianAcm) != KErrNotFound)
       
   455         ret = mCommServer.LoadCommModule(KAcmCsyName);
       
   456 
       
   457     if (ret != KErrNone)
       
   458         return ret;
       
   459 
       
   460     // Get base offsets of specified port.
       
   461     TSerialInfo info;
       
   462     ret = mCommServer.GetPortInfo(portname, info);
       
   463     if (ret == KErrNone)
       
   464         mPortLowIndex = info.iLowUnit;
       
   465 
       
   466     ILOG1(ESOCKET, "NativeCommConnection::Lowunit  = %d", mPortLowIndex);
       
   467 
       
   468     return ret;
       
   469 }
       
   470 
       
   471 void NativeCommConnection::doClose()
       
   472 {
       
   473     JELOG2(ESOCKET);
       
   474     if (mConnectionIsOpen != false)
       
   475     {
       
   476         mComm.Close();
       
   477         mCommServer.Close();
       
   478         mConnectionIsOpen = false;
       
   479     }
       
   480 }
       
   481 
       
   482 void NativeCommConnection::close()
       
   483 {
       
   484     CallMethod(this, &NativeCommConnection::doClose,iFuncServ);
       
   485 
       
   486 }
       
   487 
       
   488 // convert a baud rate passed as a TBps into an integer,
       
   489 int NativeCommConnection::TBpsToTInt(TBps aRate)
       
   490 {
       
   491     JELOG2(ESOCKET);
       
   492     switch (aRate)
       
   493     {
       
   494     case EBps50:
       
   495         return 50;
       
   496     case EBps75:
       
   497         return 75;
       
   498     case EBps110:
       
   499         return 110;
       
   500     case EBps134:
       
   501         return 134;
       
   502     case EBps150:
       
   503         return 150;
       
   504     case EBps300:
       
   505         return 300;
       
   506     case EBps600:
       
   507         return 600;
       
   508     case EBps1200:
       
   509         return 1200;
       
   510     case EBps1800:
       
   511         return 1800;
       
   512     case EBps2000:
       
   513         return 2000;
       
   514     case EBps2400:
       
   515         return 2400;
       
   516     case EBps3600:
       
   517         return 3600;
       
   518     case EBps4800:
       
   519         return 4800;
       
   520     case EBps7200:
       
   521         return 7200;
       
   522     case EBps9600:
       
   523         return 9600;
       
   524     case EBps19200:
       
   525         return 19200;
       
   526     case EBps38400:
       
   527         return 38400;
       
   528     case EBps57600:
       
   529         return 57600;
       
   530     case EBps115200:
       
   531         return 115200;
       
   532     case EBps230400:
       
   533         return 230400;
       
   534     case EBps460800:
       
   535         return 460800;
       
   536     case EBps576000:
       
   537         return 576000;
       
   538     case EBps1152000:
       
   539         return 1152000;
       
   540     case EBps4000000:
       
   541         return 4000000;
       
   542     case EBps921600:
       
   543         return 921600;
       
   544     default:
       
   545         return -1;
       
   546     }
       
   547 }
       
   548 
       
   549 // convert a baud rate passed as an int into a TBps enum value,
       
   550 // rates are rounded down to the next rate, anything less than 75 is set to 50
       
   551 TBps NativeCommConnection::TIntToTBps(const TInt aRate)
       
   552 {
       
   553     JELOG2(ESOCKET);
       
   554     if (aRate > 4000000)
       
   555         return EBpsSpecial;
       
   556     if (aRate == 4000000)
       
   557         return EBps4000000;
       
   558     if (aRate >= 1152000)
       
   559         return EBps1152000;
       
   560     if (aRate >= 921600)
       
   561         return EBps921600;
       
   562     if (aRate >= 576000)
       
   563         return EBps576000;
       
   564     if (aRate >= 460800)
       
   565         return EBps460800;
       
   566     if (aRate >= 230400)
       
   567         return EBps230400;
       
   568     if (aRate >= 115200)
       
   569         return EBps115200;
       
   570     if (aRate >= 57600)
       
   571         return EBps57600;
       
   572     if (aRate >= 38400)
       
   573         return EBps38400;
       
   574     if (aRate >= 19200)
       
   575         return EBps19200;
       
   576     if (aRate >= 9600)
       
   577         return EBps9600;
       
   578     if (aRate >= 7200)
       
   579         return EBps7200;
       
   580     if (aRate >= 4800)
       
   581         return EBps4800;
       
   582     if (aRate >= 3600)
       
   583         return EBps3600;
       
   584     if (aRate >= 2400)
       
   585         return EBps2400;
       
   586     if (aRate >= 2000)
       
   587         return EBps2000;
       
   588     if (aRate >= 1800)
       
   589         return EBps1800;
       
   590     if (aRate >= 1200)
       
   591         return EBps1200;
       
   592     if (aRate >= 600)
       
   593         return EBps600;
       
   594     if (aRate >= 300)
       
   595         return EBps300;
       
   596     if (aRate >= 150)
       
   597         return EBps150;
       
   598     if (aRate >= 134)
       
   599         return EBps134;
       
   600     if (aRate >= 110)
       
   601         return EBps110;
       
   602     if (aRate >= 75)
       
   603         return EBps75;
       
   604     return EBps50;
       
   605 }
       
   606