javaextensions/bluetooth/bluetoothcommons/src.s60/bluetoothclientconnection.cpp
changeset 21 2a9601315dfc
child 72 1f0034e370aa
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:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <string.h>
       
    20 #include <unistd.h>
       
    21 #include <bttypes.h>
       
    22 
       
    23 #include "logger.h"
       
    24 #include "fs_methodcall.h"
       
    25 #include "functionserver.h"
       
    26 #include "javasymbianoslayer.h"
       
    27 
       
    28 #include "bluetoothfunctionserver.h"
       
    29 #include "bluetoothclientconnection.h"
       
    30 #include <string.h>
       
    31 
       
    32 using namespace std;
       
    33 
       
    34 using namespace java::util;
       
    35 using namespace java::bluetooth;
       
    36 
       
    37 OS_EXPORT BluetoothClientConnection::BluetoothClientConnection
       
    38 (BluetoothFunctionServer* server):
       
    39         mServer(server),
       
    40         mShutdownNotifyMonitor(NULL),
       
    41         mReadNotifyMonitor(NULL),
       
    42         mBuffer(NULL, 0),
       
    43         mSendNotifyMonitor(NULL),
       
    44         mNegotiatedReceiveMtu(0),
       
    45         mNegotiatedTransmitMtu(0),
       
    46         mRemoteBTAddr(0),
       
    47         mConnectNotifyMonitor(NULL),
       
    48         mMakeJavaCallbackOnRead(EFalse),
       
    49         mReadPending(EFalse),
       
    50         mBufferInitialized(EFalse)
       
    51 {
       
    52     JELOG2(EJavaBluetooth);
       
    53 }
       
    54 
       
    55 OS_EXPORT BluetoothClientConnection::BluetoothClientConnection
       
    56 (CBluetoothSocket* aSocket, BluetoothFunctionServer* aServer):
       
    57         mServer(aServer),
       
    58         mSocket(aSocket),
       
    59         mShutdownNotifyMonitor(NULL),
       
    60         mReadNotifyMonitor(NULL),
       
    61         mBuffer(NULL, 0),
       
    62         mSendNotifyMonitor(NULL),
       
    63         mNegotiatedReceiveMtu(0),
       
    64         mNegotiatedTransmitMtu(0),
       
    65         mRemoteBTAddr(0),
       
    66         mMakeJavaCallbackOnRead(EFalse),
       
    67         mReadPending(EFalse),
       
    68         mBufferInitialized(EFalse)
       
    69 {
       
    70     JELOG2(EJavaBluetooth);
       
    71 }
       
    72 
       
    73 OS_EXPORT BluetoothClientConnection::~BluetoothClientConnection()
       
    74 {
       
    75     JELOG2(EJavaBluetooth);
       
    76 
       
    77     CloseFs();
       
    78     delete mReadNotifyMonitor;
       
    79     delete mSendNotifyMonitor;
       
    80     delete mShutdownNotifyMonitor;
       
    81     if (mBufferInitialized)
       
    82     {
       
    83         delete mBuffer.Ptr();
       
    84     }
       
    85 }
       
    86 
       
    87 // NOTE:
       
    88 // TO be called by server objects doing accept and open.
       
    89 // To be called always in Function server context
       
    90 // Must be called only after connection has been successfully established
       
    91 OS_EXPORT void BluetoothClientConnection::initialize(int protocol,
       
    92         TInt64 aRemoteAddr, int aReceiveMtu, int aTransmitMtu)
       
    93 {
       
    94     JELOG2(EJavaBluetooth);
       
    95     // Set CBluetoothSocket to notify this object on events.
       
    96     mSocket->SetNotifier(*this);
       
    97     mProtocol = protocol;
       
    98     mRemoteBTAddr = aRemoteAddr;
       
    99     mNegotiatedReceiveMtu = aReceiveMtu;
       
   100     mNegotiatedTransmitMtu = aTransmitMtu;
       
   101 
       
   102     // Because of this call, we must call initialize in FS context
       
   103     ReceiveData();
       
   104 }
       
   105 
       
   106 OS_EXPORT int BluetoothClientConnection::init(int protocol)
       
   107 {
       
   108     JELOG2(EJavaBluetooth);
       
   109     TRAPD(result, CallMethodL(this, &BluetoothClientConnection::InitL,
       
   110                               protocol, mServer));
       
   111     return result;
       
   112 }
       
   113 
       
   114 /**
       
   115  * Should be called in FunctionServer Context before any method of this class is called
       
   116  * Look at bluetoothconsts.h for constants:
       
   117  * PROTOCOL_L2CAP for L2CAP & PROTOCOL_RFCOMM for RFCOMM
       
   118  */
       
   119 void BluetoothClientConnection::InitL(TInt protocol)
       
   120 {
       
   121     JELOG2(EJavaBluetooth);
       
   122     //Connect to SocketServer
       
   123     User::LeaveIfError(mSocketServ.Connect());
       
   124     User::LeaveIfError(mSocketServ.ShareAuto());
       
   125     TProtocolDesc pdesc;
       
   126 
       
   127     if (PROTOCOL_L2CAP == protocol)
       
   128     {
       
   129         User::LeaveIfError(mSocketServ.FindProtocol(KL2CAPDesC(), pdesc));
       
   130         mSocket = CBluetoothSocket::NewL(*this, mSocketServ, pdesc.iSockType,
       
   131                                          KL2CAP);
       
   132     }
       
   133     else
       
   134     {
       
   135         User::LeaveIfError(mSocketServ.FindProtocol(KRFCOMMDesC(), pdesc));
       
   136         mSocket = CBluetoothSocket::NewL(*this, mSocketServ, pdesc.iSockType,
       
   137                                          KRFCOMM);
       
   138     }
       
   139     mProtocol = protocol;
       
   140 }
       
   141 
       
   142 OS_EXPORT void BluetoothClientConnection::close()
       
   143 {
       
   144     if (NULL == mShutdownNotifyMonitor)
       
   145     {
       
   146         mShutdownNotifyMonitor = Monitor::createMonitor();
       
   147     }
       
   148     CallMethod(this, &BluetoothClientConnection::CloseFs, mServer);
       
   149     mShutdownNotifyMonitor->wait();
       
   150     delete mSocket;
       
   151     mSocket = 0;
       
   152 }
       
   153 
       
   154 void BluetoothClientConnection::CloseFs()
       
   155 {
       
   156     JELOG2(EJavaBluetooth);
       
   157     if (mSocket)
       
   158     {
       
   159         mMakeJavaCallbackOnRead = EFalse;
       
   160         mSocket->CancelAll();
       
   161         mSocket->Shutdown(RSocket::EImmediate);
       
   162     }
       
   163 }
       
   164 
       
   165 /**
       
   166  * Calls ReceiveData in FunctionServer Context and allocates
       
   167  * memory needed and assigns to inBuf
       
   168  */
       
   169 OS_EXPORT int BluetoothClientConnection::receive(char* &inBuf)
       
   170 {
       
   171     JELOG2(EJavaBluetooth);
       
   172     // This receive must read the data already buffered and return the data.
       
   173     // For L2CAP the size of internal buffer should be the same as the
       
   174     // negotiated receive mtu.
       
   175     // For RFCOMM, it must be the same as java side buffer.
       
   176     // receive never blocks.
       
   177 
       
   178     int returnValue = mReadStatus;
       
   179     if (KErrNone == mReadStatus)
       
   180     {
       
   181         //Assign output parameter.
       
   182         int dataRead = mBuffer.Length();
       
   183 
       
   184         inBuf = new char[dataRead + 1];
       
   185         memcpy(inBuf, mBuffer.Ptr(), dataRead);
       
   186         inBuf[dataRead] = 0;
       
   187 
       
   188         LOG1(EJavaBluetooth, EInfo,
       
   189              "  BluetoothClientConnection::receive: Length of inBuf: %d",
       
   190              strlen((inBuf)));
       
   191         LOG1(EJavaBluetooth, EInfo,
       
   192              "- BluetoothClientConnection::receive: Length: %d", dataRead);
       
   193         returnValue = dataRead;
       
   194     }
       
   195     else
       
   196     {
       
   197         if (KErrEof == mReadStatus)
       
   198         {
       
   199             LOG(EJavaBluetooth, EInfo,
       
   200                 "- BluetoothClientConnection::receive: EOF");
       
   201             returnValue = 0;
       
   202         }
       
   203         else if (KErrDisconnected == mReadStatus)
       
   204         {
       
   205             ELOG(EJavaBluetooth,
       
   206                  "- BluetoothClientConnection::receive Disconnected");
       
   207             return returnValue;
       
   208         }
       
   209     }
       
   210 
       
   211     // Trigger next read before returning.
       
   212     CallMethod(mReadStatus, this, &BluetoothClientConnection::ReceiveData,
       
   213                mServer);
       
   214     // IF we reach here, it means that something got messed up :)
       
   215     return returnValue;
       
   216 }
       
   217 
       
   218 OS_EXPORT void BluetoothClientConnection::registerCallback(JNIEnv* aJni,
       
   219         jobject peer)
       
   220 {
       
   221     JELOG2(EJavaBluetooth);
       
   222     if (!(mServer->attachedToVm()))
       
   223     {
       
   224         LOG(EJavaBluetooth, EInfo,
       
   225             "+ BluetoothClientConnection::registerCallback Attaching to VM."
       
   226             " Should be called only in case of Push");
       
   227         mServer->attach(aJni, peer);
       
   228     }
       
   229     mMakeJavaCallbackOnRead = ETrue;
       
   230 
       
   231     jclass peerClass = aJni->GetObjectClass(peer);
       
   232     mReadCompleteCallback = aJni->GetMethodID(peerClass,
       
   233                             "receiveCompleteCallback", "(J)V");
       
   234 }
       
   235 
       
   236 void BluetoothClientConnection::makeReadCompleteCallback()
       
   237 {
       
   238     JELOG2(EJavaBluetooth);
       
   239     JNIEnv* jni = mServer->getValidJniEnv();
       
   240     jobject peer = mServer->getPeer();
       
   241 
       
   242     (*jni).CallVoidMethod(peer, mReadCompleteCallback,
       
   243                           reinterpret_cast<jlong>(this));
       
   244 
       
   245     mMakeJavaCallbackOnRead = EFalse;
       
   246 }
       
   247 
       
   248 //Should be called in FunctionServer context.
       
   249 TInt BluetoothClientConnection::ReceiveData()
       
   250 {
       
   251     JELOG2(EJavaBluetooth);
       
   252 
       
   253     if (!mBufferInitialized)
       
   254     {
       
   255         TUint8 *tempBuf = NULL;
       
   256         int length = 512;
       
   257         if (PROTOCOL_L2CAP == mProtocol)
       
   258         {
       
   259             length = mNegotiatedReceiveMtu;
       
   260             tempBuf = new TUint8[length];
       
   261         }
       
   262         else
       
   263         {
       
   264             tempBuf = new TUint8[length];
       
   265             // NOTE: Size of this buffer should be the same as that specifie in BluetoothStreamer.
       
   266         }
       
   267         mBuffer.Set(tempBuf, 0, length);
       
   268         mBufferInitialized = ETrue;
       
   269     }
       
   270 
       
   271     TInt error = 0;
       
   272 
       
   273     //RecvOneOrMore does not block until the whole buffer is filled.
       
   274     //Returns as soon as some data is available.
       
   275     if (PROTOCOL_L2CAP == mProtocol)
       
   276     {
       
   277         // mBuffer should be the same as the negotiated MTU value.
       
   278         error = mSocket->Read(mBuffer);
       
   279     }
       
   280     else
       
   281     {
       
   282         LOG1(
       
   283             EJavaBluetooth,
       
   284             EInfo,
       
   285             "  BluetoothClientConnection::ReceiveData on RFCOMM Length: %d",
       
   286             mBuffer.MaxSize());
       
   287         error = mSocket->RecvOneOrMore(mBuffer, 0, mSockXfrLength);
       
   288     }
       
   289 
       
   290     if (KErrNone == error)
       
   291     {
       
   292         mReadPending = true;
       
   293     }
       
   294 
       
   295     LOG1(EJavaBluetooth, EInfo,
       
   296          "- BluetoothClientConnection::ReceiveData Err:%d", error);
       
   297     return error;
       
   298 }
       
   299 
       
   300 /**
       
   301  * Sends data by calling SendData in Function Server context.
       
   302  * Blocks until send is complete.
       
   303  */
       
   304 OS_EXPORT int BluetoothClientConnection::send(const char* data, int length)
       
   305 {
       
   306     JELOG2(EJavaBluetooth);
       
   307     LOG1(EJavaBluetooth, EInfo, "  BluetoothClientConnection::send: Data Length: %d ",
       
   308          length);
       
   309 
       
   310     if (KErrDisconnected == mReadStatus)
       
   311     {
       
   312         ELOG(EJavaBluetooth, "  BluetoothClientConnection::send Disconnected");
       
   313         return mReadStatus;
       
   314     }
       
   315 
       
   316     if (NULL == data || 0 == length)
       
   317     {
       
   318         return 0;
       
   319     }
       
   320 
       
   321     if (!mSendNotifyMonitor)
       
   322     {
       
   323         mSendNotifyMonitor = Monitor::createMonitor();
       
   324     }
       
   325 
       
   326     TPtr8 dataPtr((TUint8 *) data, length, length);
       
   327     LOG1(EJavaBluetooth, EInfo,
       
   328          "  BluetoothClientConnection::send: Sending data length:%d", length);
       
   329 
       
   330     TInt error = 0;
       
   331     CallMethod(error, this, &BluetoothClientConnection::SendData, dataPtr,
       
   332                mServer);
       
   333 
       
   334     LOG(EJavaBluetooth, EInfo,
       
   335         "  BluetoothClientConnection::send: Waiting for data to come back");
       
   336 
       
   337     if (KErrNone == error)
       
   338     {
       
   339         mSendNotifyMonitor->wait();
       
   340     }
       
   341     else
       
   342     {
       
   343         return error;
       
   344     }
       
   345 
       
   346     ELOG1(EJavaBluetooth,
       
   347           "- BluetoothClientConnection::send: Sent status:%d", mWriteStatus);
       
   348 
       
   349     return mWriteStatus;
       
   350 }
       
   351 
       
   352 
       
   353 TInt BluetoothClientConnection::SendData(const TDesC8& aData)
       
   354 {
       
   355     JELOG2(EJavaBluetooth);
       
   356     return mSocket->Send(aData, 0);
       
   357 }
       
   358 
       
   359 OS_EXPORT int BluetoothClientConnection::connect(long long aBtAddress,
       
   360         int aChannel, bool aAuthenticate, bool aEncrypt, int aReceiveMTU,
       
   361         int aTransmitMTU)
       
   362 {
       
   363     JELOG2(EJavaBluetooth);
       
   364     if (NULL == mConnectNotifyMonitor)
       
   365     {
       
   366         mConnectNotifyMonitor = Monitor::createMonitor();
       
   367     }
       
   368 
       
   369     TInt auth = (aAuthenticate) ? 1 : 0;
       
   370     TInt enc = (aEncrypt) ? 1 : 0;
       
   371     TInt64 btAddress = aBtAddress;
       
   372     TInt channel = aChannel;
       
   373     mRequestedRMtu = aReceiveMTU;
       
   374     mRequestedTMtu = aTransmitMTU;
       
   375 
       
   376     TInt retVal = 0;
       
   377     CallMethod(retVal, this, &BluetoothClientConnection::Connect, btAddress,
       
   378                channel, auth, enc, mRequestedRMtu, mRequestedTMtu, mServer);
       
   379 
       
   380     if (0 == retVal)
       
   381     {
       
   382         mRemoteBTAddr = aBtAddress;
       
   383         // Will be notified by HandleConnectCompleteL()
       
   384         mConnectNotifyMonitor->wait();
       
   385         return mConnectError;
       
   386     }
       
   387 
       
   388     return retVal;
       
   389 }
       
   390 
       
   391 TInt BluetoothClientConnection::Connect(TInt64 btAddress, TInt channel,
       
   392                                         TInt authenticate, TInt encrypt, TInt receiveMTU, TInt transmitMTU)
       
   393 {
       
   394     JELOG2(EJavaBluetooth);
       
   395     LOG3(
       
   396         EJavaBluetooth,
       
   397         EInfo,
       
   398         "  BluetoothClientConnection::Connect: Channel %d, RMTU: %d TMTU %d",
       
   399         channel, receiveMTU, transmitMTU);
       
   400     LOG1(EJavaBluetooth, EInfo, "  BluetoothClientConnection::Connect %lX",
       
   401          btAddress);
       
   402     LOG(EJavaBluetooth, EInfo,
       
   403         "  BluetoothClientConnection::Connect: Applying Settings");
       
   404 
       
   405     TBTDevAddr btDeviceAddress(btAddress);
       
   406     TBTSockAddr btsockaddr;
       
   407     btsockaddr.SetBTAddr(btDeviceAddress);
       
   408     btsockaddr.SetPort(channel);
       
   409 
       
   410     // Set security
       
   411     TBTServiceSecurity secSettings;
       
   412     if (authenticate == EFalse)
       
   413         secSettings.SetAuthentication(EFalse);
       
   414     else
       
   415         secSettings.SetAuthentication(ETrue);
       
   416 
       
   417     if (encrypt == EFalse)
       
   418         secSettings.SetEncryption(EFalse);
       
   419     else
       
   420         secSettings.SetEncryption(ETrue);
       
   421     // Attach the security settings.
       
   422     btsockaddr.SetSecurity(secSettings);
       
   423 
       
   424     if (PROTOCOL_L2CAP == mProtocol)
       
   425     {
       
   426         TL2CapConfigPkg options;
       
   427 
       
   428         if (receiveMTU >= KL2MinMTU)
       
   429             options().SetMaxReceiveUnitSize(receiveMTU);
       
   430         else
       
   431             options().SetMaxReceiveUnitSize(DEFAULT_MTU);
       
   432 
       
   433         if (transmitMTU >= KL2MinMTU)
       
   434             options().SetMaxTransmitUnitSize(transmitMTU);
       
   435 
       
   436         mSocket->SetOpt(KL2CAPUpdateChannelConfig, KSolBtL2CAP, options);
       
   437     }
       
   438 
       
   439     // Will be set once handle connect complete is called.
       
   440     mConnectError = 0;
       
   441     LOG(EJavaBluetooth, EInfo,
       
   442         "  BluetoothClientConnection::StartListenerL: Connecting to Server");
       
   443     int error = mSocket->Connect(btsockaddr);
       
   444     return error;
       
   445 }
       
   446 
       
   447 OS_EXPORT int BluetoothClientConnection::getTransmitMTU()
       
   448 {
       
   449     return mNegotiatedTransmitMtu;
       
   450 }
       
   451 
       
   452 OS_EXPORT int BluetoothClientConnection::getReceiveMTU()
       
   453 {
       
   454     return mNegotiatedReceiveMtu;
       
   455 }
       
   456 
       
   457 OS_EXPORT long long BluetoothClientConnection::getRemoteAddress()
       
   458 {
       
   459     JELOG2(EJavaBluetooth);
       
   460 
       
   461     if (mRemoteBTAddr)
       
   462     {
       
   463         return mRemoteBTAddr;
       
   464     }
       
   465 
       
   466     return -1;
       
   467 }
       
   468 
       
   469 OS_EXPORT long BluetoothClientConnection::available()
       
   470 {
       
   471     JELOG2(EJavaBluetooth);
       
   472     if (KErrDisconnected == mReadStatus)
       
   473     {
       
   474         ELOG(EJavaBluetooth,
       
   475              "  BluetoothClientConnection::available Disconnected");
       
   476         return mReadStatus;
       
   477     }
       
   478 
       
   479     if (mReadPending)
       
   480     {
       
   481         return 0;
       
   482     }
       
   483     else
       
   484     {
       
   485         return mBuffer.Length();
       
   486     }
       
   487 }
       
   488 
       
   489 //------------------------------------------------------------------------------
       
   490 //  Methods from MBluetoothSocketNotifier to handle Bluetooth Events
       
   491 //------------------------------------------------------------------------------
       
   492 
       
   493 //Notification of an accept complete event
       
   494 void BluetoothClientConnection::HandleAcceptCompleteL(TInt /*err*/)
       
   495 {
       
   496     LOG1(EJavaBluetooth, EInfo,
       
   497          "+  BluetoothClientConnection::HandleAcceptCompleteL %s",
       
   498          "WARNING: Nothing to handle in this event !!");
       
   499 }
       
   500 
       
   501 // Notification of a baseband event
       
   502 void BluetoothClientConnection::HandleActivateBasebandEventNotifierCompleteL(
       
   503     TInt /*aErr*/, TBTBasebandEventNotification& /*aEventNotification*/)
       
   504 {
       
   505     LOG1(
       
   506         EJavaBluetooth,
       
   507         EInfo,
       
   508         "+  BluetoothClientConnection::HandleActivateBasebandEventNotifierCompleteL %s",
       
   509         "WARNING: Nothing to handle in this event !!");
       
   510 }
       
   511 
       
   512 //Notification of a connection complete event
       
   513 void BluetoothClientConnection::HandleConnectCompleteL(TInt err)
       
   514 {
       
   515     JELOG2(EJavaBluetooth);
       
   516     mConnectError = err;
       
   517     LOG1(EJavaBluetooth, EInfo,
       
   518          "  BluetoothClientConnection::HandleConnectCompleteL: %d", err);
       
   519 
       
   520     if (KErrNone == mConnectError && PROTOCOL_L2CAP == mProtocol)
       
   521     {
       
   522         mSocket->GetOpt(KL2CAPInboundMTU, KSolBtL2CAP, mNegotiatedReceiveMtu);
       
   523         mSocket->GetOpt(KL2CAPNegotiatedOutboundMTU, KSolBtL2CAP,
       
   524                         mNegotiatedTransmitMtu);
       
   525 
       
   526         LOG1(
       
   527             EJavaBluetooth,
       
   528             EInfo,
       
   529             "  BluetoothClientConnection::HandleConnectCompleteL Negotiate Rx %d",
       
   530             mNegotiatedReceiveMtu);
       
   531         LOG1(
       
   532             EJavaBluetooth,
       
   533             EInfo,
       
   534             "  BluetoothClientConnection::HandleConnectCompleteL Negotiate Tx %d",
       
   535             mNegotiatedTransmitMtu);
       
   536 
       
   537     }
       
   538     mConnectNotifyMonitor->notify();
       
   539 
       
   540     if (KErrNone == mConnectError)
       
   541     {
       
   542         // Start to fetch data immediately.
       
   543         ReceiveData();
       
   544     }
       
   545 }
       
   546 
       
   547 //Notification of a ioctl complete event
       
   548 void BluetoothClientConnection::HandleIoctlCompleteL(TInt /*err*/)
       
   549 {
       
   550     LOG1(EJavaBluetooth, EInfo,
       
   551          "+  BluetoothClientConnection::HandleIoctlCompleteL %s",
       
   552          "WARNING: Nothing to handle in this event !!");
       
   553 }
       
   554 
       
   555 //Notification of a receive complete event
       
   556 void BluetoothClientConnection::HandleReceiveCompleteL(TInt err)
       
   557 {
       
   558     JELOG2(EJavaBluetooth);
       
   559     mReadStatus = 0;
       
   560 
       
   561     // Here following operations are performed.
       
   562     //  1. Store receive status.
       
   563     //  2. Store amount of data read.
       
   564     //  3. Change flag to not receiving.
       
   565 
       
   566     if (err != KErrNone)
       
   567     {
       
   568         ELOG1(
       
   569             EJavaBluetooth,
       
   570             "  BluetoothClientConnection::HandleReceiveCompleteL: Error: %d",
       
   571             err);
       
   572         mReadStatus = err;
       
   573     }
       
   574     else
       
   575     {
       
   576         LOG1(
       
   577             EJavaBluetooth,
       
   578             EInfo,
       
   579             "  BluetoothClientConnection::HandleReceiveCompleteL: EWaiting Length: %d",
       
   580             mBuffer.Length());
       
   581     }
       
   582     if (mMakeJavaCallbackOnRead)
       
   583     {
       
   584         LOG(EJavaBluetooth, EInfo,
       
   585             "  BluetoothClientConnection::HandleReceiveCompleteL: Calling java");
       
   586         makeReadCompleteCallback();
       
   587     }
       
   588     mReadPending = EFalse;
       
   589 
       
   590 }
       
   591 
       
   592 //Notification of a send complete event
       
   593 void BluetoothClientConnection::HandleSendCompleteL(TInt err)
       
   594 {
       
   595     JELOG2(EJavaBluetooth);
       
   596     LOG1(EJavaBluetooth, EInfo,
       
   597          "  BluetoothClientConnection::HandleSendCompleteL %d: ", err);
       
   598     mWriteStatus = 0;
       
   599     if (err != KErrNone)
       
   600     {
       
   601         mWriteStatus = err;
       
   602     }
       
   603     mSendNotifyMonitor->notify();
       
   604 }
       
   605 
       
   606 //Notification of a shutdown complete event
       
   607 void BluetoothClientConnection::HandleShutdownCompleteL(TInt /*err*/)
       
   608 {
       
   609 //    LOG1(EJavaBluetooth, EInfo,
       
   610 //         "+  BluetoothClientConnection::HandleShutdownCompleteL Err:%d", err);
       
   611 
       
   612     mShutdownNotifyMonitor->notify();
       
   613 }
       
   614