--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/bluetooth/omjbluetooth/src.s60/bluetoothstacks60native.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1791 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <e32cmn.h>
+#include <bttypes.h>
+
+#include "functionserver.h"
+#include "javajniutils.h"
+#include "jniarrayutils.h"
+#include "jstringutils.h"
+#include "logger.h"
+#include "fs_methodcall.h"
+#include "monitor.h"
+#include "exceptionbase.h"
+
+#include "bluetoothconsts.h"
+#include "bluetoothfunctionserver.h"
+#include "discoveryagent.h"
+#include "bluetoothclientconnection.h"
+#include "btl2capserverconnection.h"
+#include "btrfcommserverconnection.h"
+#include "bluetoothstructs.h"
+#include "servicerecord.h"
+#include "bluetoothremotedevice.h"
+
+//Push related stuff
+#include "btl2cappushserverconnection.h"
+#include "btl2capserverconnectionfactory.h"
+#include "btrfcommpushserverconnection.h"
+#include "btrfcommserverconnectionfactory.h"
+#include "btobexserverconnectionfactory.h"
+#include "pushexception.h"
+#include "pusherrorcodes.h"
+
+#include "com_nokia_mj_impl_bluetooth_BluetoothStackS60.h"
+
+using namespace std;
+using namespace java::util;
+using namespace java::push;
+using namespace java::bluetooth;
+
+//
+// JNI functions specific to Bluetooth Stack
+//
+
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1createFunctionServer
+(JNIEnv *aJni, jobject aPeer)
+{
+ JELOG2(EJavaBluetooth);
+ java::bluetooth::BluetoothFunctionServer* server =
+ new java::bluetooth::BluetoothFunctionServer(*aJni, aPeer);
+ return reinterpret_cast<jlong>(server);
+}
+
+
+//
+// JNI functions specific to Discovery Agent
+//
+
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1createNativeDiscoveryAgent
+(JNIEnv* /*aJni*/, jobject /*aPeer*/, jlong aServer)
+{
+ JELOG2(EJavaBluetooth);
+ java::bluetooth::BluetoothFunctionServer *server =
+ reinterpret_cast<java::bluetooth::BluetoothFunctionServer *>(
+ static_cast<long>(aServer));
+
+ java::bluetooth::DiscoveryAgent* agent =
+ new java::bluetooth::DiscoveryAgent(server);
+
+ jlong ret = reinterpret_cast<jlong>(agent);
+ return ret;
+}
+
+
+//
+// JNI functions specific to Device Discovery
+//
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1runDeviceInquiry
+(JNIEnv *aJni, jobject aPeer, jint aAccessCode, jlong aDiscAgent)
+{
+ JELOG2(EJavaBluetooth);
+ LOG1(EJavaBluetooth, EInfo, "+ JNI::runDeviceInquiry %X", aAccessCode);
+
+ java::bluetooth::DiscoveryAgent* agent =
+ reinterpret_cast<java::bluetooth::DiscoveryAgent *>(
+ static_cast<long>(aDiscAgent));
+
+ int result = KErrNone;
+
+ result = agent->startDeviceDiscovery(aJni, aPeer, aAccessCode);
+
+ if (KErrNone != result)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::runDeviceInquiry Error before starting inquiry %d",
+ result);
+
+ java::util::JniUtils::throwNewException(aJni,
+ "javax/bluetooth/BluetoothStateException",
+ "Device inquiry failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(result));
+ return INQUIRY_ERROR;
+ }
+
+ int discStatus = 0;
+
+ do
+ {
+ //Wait for discovery agent to unlock this.
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::runDeviceInquiry: Getting next device");
+
+ DiscoveredDevice device;
+
+ discStatus = agent->getNextDevice(device);
+
+ agent->doDeviceDiscoveryCallback(aJni, aPeer, device);
+
+ device.clean();
+
+ LOG1(EJavaBluetooth, EInfo,
+ " JNI::runDeviceInquiry doDeviceDiscoveryCallback return: %d",
+ discStatus);
+
+ }
+ while ((INQUIRY_ERROR != discStatus) &&
+ (INQUIRY_COMPLETED != discStatus) &&
+ (INQUIRY_TERMINATED != discStatus));
+
+ return discStatus;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1cancelInquiry
+(JNIEnv* /*aJni*/, jobject /*aPeer*/, jlong aDiscAgent)
+{
+ JELOG2(EJavaBluetooth);
+ java::bluetooth::DiscoveryAgent* agent =
+ reinterpret_cast<java::bluetooth::DiscoveryAgent *>(
+ static_cast<long>(aDiscAgent));
+
+ jboolean ret = agent->cancelDeviceDiscovery();
+ return ret;
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1getRemoteDeviceFriendlyName
+(JNIEnv* aJni, jobject /*aPeer*/, jlong aAgent, jlong aAddr)
+{
+ JELOG2(EJavaBluetooth);
+ LOG1(EJavaBluetooth, EInfo,
+ "+ JNI::getRemoteDeviceFriendlyName DeviceAddress:%ld",
+ aAddr);
+
+ java::bluetooth::DiscoveryAgent* dAgent =
+ reinterpret_cast<java::bluetooth::DiscoveryAgent *>(
+ static_cast<long>(aAgent));
+
+ std::wstring* friendlyName = NULL;
+ TRAPD(err,
+ friendlyName = dAgent->lookupFriendlyNameL(aAddr));
+
+ if (KErrNone != err)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::getRemoteDeviceFriendlyName while lookupFriendlyNameL:%d",
+ err);
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Retrieving remote device friendly name failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ return NULL;
+ }
+
+ jstring ret;
+ try
+ {
+ if (NULL != friendlyName)
+ {
+ ret = java::util::JniUtils::wstringToJstring(aJni, *friendlyName);
+ delete friendlyName;
+ }
+ else
+ {
+ std::wstring str(L"");
+ ret = java::util::JniUtils::wstringToJstring(aJni, str);
+ }
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::getRemoteDeviceFriendlyName Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException", "Retrieving friendly name failed");
+ delete friendlyName;
+ return NULL;
+ }
+ return ret;
+}
+
+//
+// JNI functions specific to Service Search & Populate Records
+//
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1runSearchServices
+(JNIEnv *aEnv, jobject aPeer, jlong aRemoteAddress, jbyteArray aUuidSet,
+ jintArray aAttrSet, jlong aDiscAgent)
+{
+ JELOG2(EJavaBluetooth);
+ java::bluetooth::DiscoveryAgent* agent =
+ reinterpret_cast<java::bluetooth::DiscoveryAgent *>(
+ static_cast<long>(aDiscAgent));
+
+ // ...convert the UUID bytes into an 8-bit descriptor...
+ jbyte* byteArray = aEnv->GetByteArrayElements(aUuidSet, NULL);
+ TInt numUuidBytes = aEnv->GetArrayLength(aUuidSet);
+ TPtrC8 uuidsDes(reinterpret_cast<TUint8*>(byteArray), numUuidBytes);
+
+ // ...convert the Attribute IDs into pairs of 16-bits in a descriptor...
+ int numAttrIds = aEnv->GetArrayLength(aAttrSet);
+ jint* intArray = aEnv->GetIntArrayElements(aAttrSet, NULL);
+ TPtrC16 attrIdsDes(reinterpret_cast<TUint16*>(intArray), numAttrIds*2);
+
+ java::util::Monitor* serviceSearchMonitor =
+ java::util::Monitor::createMonitor();
+
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::runSearchServices calling StartSearchServices");
+ int result = KErrNone;
+
+ result = agent->StartSearchServices(
+ aEnv, aPeer, aRemoteAddress, uuidsDes, attrIdsDes,
+ serviceSearchMonitor);
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::runSearchServices returned from StartSearchServices");
+
+ if (KErrNone != result)
+ {
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::runSearchServices Error occurred before starting service search!");
+ delete serviceSearchMonitor;
+ serviceSearchMonitor = NULL;
+ return SERVICE_SEARCH_ERROR;
+ }
+
+ int searchStatus = -1;
+
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::runSearchServices waiting for search complete");
+
+ while ((SERVICE_SEARCH_ERROR != searchStatus) &&
+ (SERVICE_SEARCH_COMPLETED != searchStatus) &&
+ (SERVICE_SEARCH_TERMINATED != searchStatus) &&
+ (SERVICE_SEARCH_NO_RECORDS != searchStatus) &&
+ (SERVICE_SEARCH_DEVICE_NOT_REACHABLE != searchStatus))
+ {
+ //Wait for discoveryagent to unlock this.
+ serviceSearchMonitor->wait();
+ searchStatus = agent->getStatusOfCompletion();
+ LOG1(EJavaBluetooth, EInfo,
+ " JNI::runSearchServices doServiceDiscoveredCallback return: %d",
+ searchStatus);
+ }
+
+ delete serviceSearchMonitor;
+ serviceSearchMonitor = NULL;
+ LOG1(EJavaBluetooth, EInfo,
+ "- JNI::runSearchServices status:%d", searchStatus);
+ return searchStatus;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1cancelServiceSearch
+(JNIEnv* /*aJni*/, jobject /*aPeer*/, jlong aDiscAgent)
+{
+ JELOG2(EJavaBluetooth);
+ java::bluetooth::DiscoveryAgent* agent =
+ reinterpret_cast<java::bluetooth::DiscoveryAgent *>(
+ static_cast<long>(aDiscAgent));
+
+ jboolean ret = agent->CancelServiceSearch();
+ return ret;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1populateServiceRecordAttributeValues
+(JNIEnv *aEnv, jobject aPeer, jlong aRemoteDevice, jlong aHandle,
+ jintArray aAttrSet, jobject aServiceRecordImpl, jlong aDiscAgent)
+{
+ JELOG2(EJavaBluetooth);
+ java::bluetooth::DiscoveryAgent* agent =
+ reinterpret_cast<java::bluetooth::DiscoveryAgent *>(
+ static_cast<long>(aDiscAgent));
+
+ // ...convert the Attribute IDs into pairs of 16-bits in a descriptor...
+ int numAttrIds = aEnv->GetArrayLength(aAttrSet);
+ jint* intArray = aEnv->GetIntArrayElements(aAttrSet, NULL);
+ TPtrC16 attrIdsDes(reinterpret_cast<TUint16*>(intArray), numAttrIds*2);
+
+ java::util::Monitor* serviceSearchMonitor =
+ java::util::Monitor::createMonitor();
+
+ jobject serviceRecGlobalRef = aEnv->NewGlobalRef(aServiceRecordImpl);
+
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::populateServiceRecordAttributeValues calling PopulateServiceRecord");
+ int result = KErrNone;
+ result = agent->PopulateServiceRecordAttrValue(
+ aEnv, aPeer, aRemoteDevice, aHandle, attrIdsDes, serviceRecGlobalRef,
+ serviceSearchMonitor);
+
+ if (KErrNone != result)
+ {
+ aEnv->DeleteGlobalRef(serviceRecGlobalRef);
+ return SERVICE_SEARCH_ERROR;
+ }
+
+ // Waiting for populateServiceRecord to finish
+ serviceSearchMonitor->wait();
+
+ aEnv->DeleteGlobalRef(serviceRecGlobalRef);
+
+ return agent->GetPopulateServiceRecordStatus();
+}
+
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1cancelPopulateServicesRecordAttributeValues
+(JNIEnv* /*aJni*/, jobject /*aPeer*/, jlong aDiscAgent)
+{
+ JELOG2(EJavaBluetooth);
+ java::bluetooth::DiscoveryAgent* agent =
+ reinterpret_cast<java::bluetooth::DiscoveryAgent *>(
+ static_cast<long>(aDiscAgent));
+
+ jboolean result = agent->CancelPopulateServiceRecordAttrValue();
+ LOG1(EJavaBluetooth, EInfo,
+ "- JNI::cancelPopulateServicesRecordAttributeValues Result:%d",
+ result);
+ return;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1getRemoteAddress
+(JNIEnv* /*aJni*/, jobject /*aPeer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ return conn->getRemoteAddress();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2OpenClientConnection
+(JNIEnv* aJni, jobject /*peer*/, jlong aBtAddress, jint aChannel,
+ jboolean aAuthenticate, jboolean aEncrypt, jint aReceiveMTU,
+ jint aTransmitMTU, jlong aServer)
+{
+ JELOG2(EJavaBluetooth);
+ LOG1(EJavaBluetooth, EInfo,
+ "+ JNI:l2OpenClientConnection: btAddress = %x", aBtAddress);
+
+ BluetoothFunctionServer *server =
+ reinterpret_cast<BluetoothFunctionServer *>(
+ static_cast<long>(aServer));
+
+ BluetoothClientConnection* conn = new BluetoothClientConnection(server);
+
+ //Initialize Bluetooth Connection to L2CAP
+ int error = conn->init(PROTOCOL_L2CAP);
+ if (error != 0)
+ {
+ // If initialization was not successful,
+ // then delete BluetoothClientConnection.
+ conn->close();
+ delete conn;
+ ELOG1(EJavaBluetooth,
+ "JNI:l2OpenClientConnection: Error during init: %d", error);
+
+ jclass cls = aJni->FindClass(
+ "javax/bluetooth/BluetoothConnectionException");
+
+ jmethodID constructorID = aJni->GetMethodID(cls, "<init>", "(I)V");
+ jthrowable bcexception = (jthrowable) aJni->NewObject(
+ cls, constructorID, BC_FAILED_NOINFO);
+
+ aJni->Throw(bcexception);
+ // free the local ref
+ aJni->DeleteLocalRef(cls);
+ return error;
+ }
+
+ //Connect to the server
+ error = conn->connect(aBtAddress, aChannel, aAuthenticate, aEncrypt,
+ aReceiveMTU, aTransmitMTU);
+
+ if (error<0)
+ {
+ ELOG1(EJavaBluetooth,
+ "JNI:l2OpenClientConnection: Error during connect: %d",
+ error);
+ jclass cls = aJni->FindClass(
+ "javax/bluetooth/BluetoothConnectionException");
+ jmethodID constructorID = aJni->GetMethodID(cls, "<init>", "(I)V");
+ if (error == HCI_TIMEOUT)
+ {
+ jthrowable bcexception = (jthrowable) aJni->NewObject(
+ cls, constructorID, BC_TIMEOUT);
+ aJni->Throw(bcexception);
+ }
+ else
+ {
+ jthrowable bcexception = (jthrowable) aJni->NewObject(
+ cls, constructorID, BC_FAILED_NOINFO);
+ aJni->Throw(bcexception);
+ }
+ // free the local ref
+ aJni->DeleteLocalRef(cls);
+ conn->close();
+ delete conn;
+ return error;
+ }
+
+ LOG1(EJavaBluetooth, EInfo,
+ "- JNI:l2OpenClientConnection: Handle = %ld", conn);
+ return reinterpret_cast<jlong>(conn);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1rfClientOpen
+(JNIEnv* aJni, jobject /*peer*/, jlong aBtAddress, jint aChannel,
+ jboolean aAuthenticate, jboolean aEncrypt, jlong aServer)
+{
+ JELOG2(EJavaBluetooth);
+ LOG1(EJavaBluetooth, EInfo,
+ "+ JNI:rfClientOpen: btAddress = %ld", aBtAddress);
+ BluetoothFunctionServer *server =
+ reinterpret_cast<BluetoothFunctionServer *>(
+ static_cast<long>(aServer));
+
+ BluetoothClientConnection* conn = new BluetoothClientConnection(server);
+
+ //Initialize Bluetooth Connection to RFCOMM
+ int error = conn->init(PROTOCOL_RFCOMM);
+ if (error != 0)
+ {
+ // If initialization was not successful,
+ // delete BluetoothClientConnection.
+ conn->close();
+ delete conn;
+ ELOG1(EJavaBluetooth,
+ "JNI:rfClientOpen: Error during init: %d", error);
+
+ jclass cls = aJni->FindClass(
+ "javax/bluetooth/BluetoothConnectionException");
+ jmethodID constructorID = aJni->GetMethodID(cls, "<init>", "(I)V");
+ jthrowable bcexception = (jthrowable) aJni->NewObject(
+ cls, constructorID, BC_FAILED_NOINFO);
+ aJni->Throw(bcexception);
+ // free the local ref
+ aJni->DeleteLocalRef(cls);
+ return error;
+ }
+
+ //Connect to the server
+ error = conn->connect(aBtAddress, aChannel, aAuthenticate, aEncrypt);
+ if (error<0)
+ {
+ ELOG1(EJavaBluetooth,
+ "JNI:rfClientOpen: Error during connect: %d", error);
+ jclass cls = aJni->FindClass(
+ "javax/bluetooth/BluetoothConnectionException");
+ jmethodID constructorID = aJni->GetMethodID(cls, "<init>", "(I)V");
+ if (error == HCI_TIMEOUT)
+ {
+ jthrowable bcexception = (jthrowable) aJni->NewObject(
+ cls, constructorID, BC_TIMEOUT);
+ aJni->Throw(bcexception);
+ }
+ else
+ {
+ jthrowable bcexception = (jthrowable) aJni->NewObject(
+ cls, constructorID, BC_FAILED_NOINFO);
+ aJni->Throw(bcexception);
+ }
+ // free the local ref
+ aJni->DeleteLocalRef(cls);
+ conn->close();
+ delete conn;
+ return error;
+ }
+
+ LOG1(EJavaBluetooth, EInfo, "- JNI:rfClientOpen: Handle %ld", conn);
+ return reinterpret_cast<jlong>(conn);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2GetTransmitMTU
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ int retVal = conn->getTransmitMTU();
+ return retVal;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2GetReceiveMTU
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ int retVal = conn->getReceiveMTU();
+ return retVal;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1available
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ int retVal = conn->available();
+ return retVal;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1clientReceive
+(JNIEnv *aJni, jobject /*peer*/, jlong aHandle, jbyteArray aBuffer)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ // Memory needs to be allocated inside ClientConnection implementation.
+ // Reason to keep this here is to prevent passing JNI parameters to client.
+ char* bufferToFill = NULL;
+ int length = 0;
+
+ // Length returned will be positive if no errors resent.
+ // Else it will be error code.
+ length = conn->receive(bufferToFill);
+
+ if (length>0)
+ {
+ if (NULL == bufferToFill)
+ {
+ LOG(EJavaBluetooth, EInfo,
+ "JNI_BluetoothStackS60_clientReceive: Buffer NULL");
+ return 0; //EOF
+ }
+
+ LOG1(EJavaBluetooth, EInfo,
+ "JNI_BluetoothStackS60_clientReceive: Data %s",
+ bufferToFill);
+
+ JNIArrayUtils::CopyToJava((*aJni),
+ bufferToFill, length, aBuffer, 0, length);
+ }
+ LOG1(EJavaBluetooth, EInfo,
+ "JNI_BluetoothStackS60_clientReceive: Returning %d", length);
+
+ delete[] bufferToFill;
+ return length;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1clientSend
+(JNIEnv *aJni, jobject /*peer*/, jlong aHandle,
+ jbyteArray aBuffer, jlong aLength)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ char* bufferToSend = new char[aLength+1];
+
+ JNIArrayUtils::CopyToNative((*aJni), aBuffer, 0, aLength, bufferToSend);
+ bufferToSend[aLength] = '\0';
+ int res = conn->send(bufferToSend, aLength);
+ LOG1(EJavaBluetooth,EInfo,
+ "Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1clientSend: Sent %d"
+ , res);
+
+ delete[] bufferToSend;
+
+ return res;
+}
+
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1clientClose
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ conn->close();
+ delete conn;
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: registerForCallback
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1registerForCallback
+(JNIEnv *aJni, jobject peer, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothClientConnection *conn =
+ reinterpret_cast<BluetoothClientConnection *>(
+ static_cast<long>(aHandle));
+
+ conn->registerCallback(aJni, peer);
+}
+
+//------------------------------------------------------------------------------
+// L2CAP Server Implementations
+//------------------------------------------------------------------------------
+
+JNIEXPORT jboolean JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1isL2ServerAlreadyRunning
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ return server->isActive();
+}
+
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1restoreL2ServiceRecord(
+ JNIEnv *aJni, jobject /*peer*/,
+ jlong aHandle, jobject aServiceRecordImpl)
+{
+ JELOG2(EJavaBluetooth);
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ ServiceRecord* srvRecHandle = srvHandle->getServiceRecordHandle();
+ if (NULL != srvRecHandle)
+ {
+ TRAP_IGNORE(
+ srvRecHandle->restoreJavaServiceRecordL(aJni, aServiceRecordImpl));
+ }
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: l2ServerOpen
+ * Signature: (ZZZZZII)J
+ */
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2ServerOpen
+(JNIEnv *aJni, jobject /*peer*/, jstring aUrl, jboolean aAuthorize,
+ jboolean aAuthenticate, jboolean aEncrypt, jboolean aMaster,
+ jint aReceiveMTU, jint aTransmitMTU)
+{
+ JELOG2(EJavaBluetooth);
+ LOG2(EJavaBluetooth, EInfo,
+ "+ JNI::l2ServerOpen TxMTU:%d RxMTU:%d",
+ aTransmitMTU, aReceiveMTU);
+
+ std::wstring connectionUrl;
+ try
+ {
+ connectionUrl = JniUtils::jstringToWstring(aJni, aUrl);
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::l2ServerOpen Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException",
+ "Opening L2CAP server connection failed");
+ return NULL;
+ }
+
+ //Get handle to ServerConnectionFactory object.
+ BtL2CapServerConnectionFactory& connectionFactory =
+ BtL2CapServerConnectionFactory::getFactory();
+
+ L2CapPushServerConnection *l2CapPushServer;
+
+ ServerConnection *serverConn = connectionFactory.create(connectionUrl);
+ l2CapPushServer =
+ reinterpret_cast<L2CapPushServerConnection*>(serverConn);
+
+ if (l2CapPushServer->isActive())
+ {
+ //if we have already accepted connection or are listening, we need not
+ //go any further. return handle.
+ LOG(EJavaBluetooth, EInfo,
+ "- JNI::l2ServerOpen: Bluetooth server already running ");
+ return reinterpret_cast<jlong>(l2CapPushServer);
+ }
+ else
+ {
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::l2ServerOpen: Trying to create and run a bluetooth server ");
+
+ L2CAPServerConnection* srvHandle = l2CapPushServer->getServerObject();
+
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::l2ServerOpen: Calling open on Server Object");
+ TInt err;
+
+ err = srvHandle->ServerOpen(aAuthorize, aAuthenticate, aEncrypt,
+ aMaster, aReceiveMTU, aTransmitMTU);
+
+ if (err != KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::l2ServerOpen Error on L2CAPServerConnection.ServerOpen: %d",
+ err);
+ if (l2CapPushServer->isCreatedByPush())
+ {
+ connectionFactory.releaseConnection(connectionUrl);
+ }
+ else
+ {
+ l2CapPushServer->close();
+ delete l2CapPushServer;
+ }
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Opening L2CAP server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ return NULL;
+ }
+ return reinterpret_cast<jlong>(l2CapPushServer);
+ }
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: l2ServerGetPSM
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2ServerGetPSM
+(JNIEnv *aJni, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ //We should never be here if push plugin is already running.
+ int psmVal = srvHandle->GetServerPSM();
+
+ if (psmVal < 0)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::l2ServerGetPSM Error while GetServerPSM: %d",
+ psmVal);
+
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Opening L2CAP server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(psmVal));
+ }
+
+ LOG1(EJavaBluetooth, EInfo, "- JNI::l2ServerGetPSM PSM value:%d ", psmVal);
+ return psmVal;
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: l2ServerGetServiceRecord
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2ServerGetServiceRecord
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+ int servRecId = 0;
+ ServiceRecord* srvRecHandle = srvHandle->getServiceRecordHandle();
+
+ if (NULL != srvRecHandle)
+ {
+ servRecId = srvRecHandle->getServiceRecordID();
+ }
+ LOG1(EJavaBluetooth, EInfo,
+ "- JNI::l2ServerGetServiceRecord: %d", servRecId);
+ return servRecId;
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: l2capRegisterSDPRecord
+ * Signature: (JI[BLjava/lang/String;)I
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2capRegisterSDPRecord
+(JNIEnv *aJni, jobject /*peer*/, jlong aHandle, jint aPsmVal,
+ jbyteArray aUuid, jstring aServerName)
+{
+ JELOG2(EJavaBluetooth);
+ TInt err;
+
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ if (server->isActive())
+ {
+ //If the server is active it means that it has already done registration
+ //and has started advertising.
+ //If connection has already been accepted, then no issues at all.
+ return;
+ }
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ jbyte* byteArray = aJni->GetByteArrayElements(aUuid, NULL);
+
+ TPtrC8 uuidDes(reinterpret_cast<TUint8*>(byteArray),
+ aJni->GetArrayLength(aUuid));
+ TUUID uuid;
+
+ TRAP(err, uuid.SetL(uuidDes));
+ if (err != KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::l2capRegisterSDPRecord Error while converting UUID: %d",
+ err);
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Opening L2CAP server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ return;
+ }
+
+ JStringUtils servName(*aJni, aServerName);
+ TPtrC8 servNameP(
+ reinterpret_cast<const TUint8*>(servName.Ptr()),
+ servName.Size());
+
+ err = srvHandle->initializeServiceRecord(aPsmVal, uuid, servNameP);
+
+ if (err != KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::l2capRegisterSDPRecord Error while initializeServiceRecord: %d",
+ err);
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Opening L2CAP server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ }
+
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: l2ServerAcceptAndOpenServerConnection
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2ServerAcceptAndOpenServerConnection
+(JNIEnv *aJni, jobject /*peer*/, jlong aHandle, jintArray aReceiveMtu)
+{
+ JELOG2(EJavaBluetooth);
+
+ BluetoothClientConnection *clientHandle;
+ int receiveMtu = 0;
+
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ if (server->isConnectionAccepted())
+ {
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::l2ServerAcceptAndOpenServerConnection: returning already accepted push client ");
+ //Since connection has already been accepted, return the client object.
+ clientHandle = server->getConnectedClient();
+ receiveMtu = clientHandle->getReceiveMTU();
+ aJni->SetIntArrayRegion(aReceiveMtu, 0, 1, &receiveMtu);
+ return reinterpret_cast<jlong>(clientHandle);
+ }
+
+ if (server->isListening())
+ {
+ //Wait till connect and then return.
+ //Then we return client here.
+ java::util::Monitor* acceptMonitor =
+ java::util::Monitor::createMonitor();
+
+ server->setAcceptMonitor(acceptMonitor);
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::l2ServerAcceptAndOpenServerConnection: waiting for connection accept ");
+ acceptMonitor->wait();
+ server->unsetAcceptMonitor();
+ delete acceptMonitor;
+
+ clientHandle = server->getConnectedClient();
+ receiveMtu = clientHandle->getReceiveMTU();
+ aJni->SetIntArrayRegion(aReceiveMtu, 0, 1, &receiveMtu);
+ return reinterpret_cast<jlong>(clientHandle);
+ }
+
+ // NOTE: In case we reached here, it means that there was no corresponding
+ // push plugin active when the midlet was launched.
+ // So we go ahead with usual stuff.
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ long retVal = srvHandle->Accept();
+
+ if (retVal < KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ " JNI::l2ServerAcceptAndOpenServerConnection Error while Accept: %d ",
+ retVal);
+
+ if (KErrCancel == retVal)
+ {
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/InterruptedIOException",
+ "acceptAndOpen() failed: L2CAP server connection is closed");
+ }
+ else
+ {
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "acceptAndOpen() on L2CAP server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(retVal));
+ }
+ }
+ else
+ {
+ clientHandle = reinterpret_cast<BluetoothClientConnection *>(retVal);
+ receiveMtu = clientHandle->getReceiveMTU();
+ aJni->SetIntArrayRegion(aReceiveMtu, 0, 1, &receiveMtu);
+ }
+ return retVal;
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: l2ServerClose
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1l2ServerClose
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ BtL2CapServerConnectionFactory& connectionFactory =
+ BtL2CapServerConnectionFactory::getFactory();
+
+ std::wstring uri = server->getUri();
+
+ server->unsetClearServiceClassBitsFlag();
+ if (server->isCreatedByPush())
+ {
+ connectionFactory.releaseConnection(uri);
+ }
+ else
+ {
+ server->close();
+ delete server;
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// RFCOMM Server Implementations
+//-----------------------------------------------------------------------------
+
+
+JNIEXPORT jboolean JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1isRfServerAlreadyRunning
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ return server->isActive();
+}
+
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1restoreRfServiceRecord(
+ JNIEnv *aJni, jobject /*peer*/,
+ jlong aHandle, jobject aServiceRecordImpl)
+{
+ JELOG2(EJavaBluetooth);
+
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+
+ ServiceRecord* srvRecHandle = srvHandle->getServiceRecordHandle();
+
+ if (NULL != srvRecHandle)
+ {
+ TRAP_IGNORE(
+ srvRecHandle->restoreJavaServiceRecordL(aJni, aServiceRecordImpl));
+ }
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: rfServerOpen
+ * Signature: (ZZZJ)J
+ */
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1rfServerOpen
+(JNIEnv *aJni, jobject /*peer*/, jstring aUrl, jboolean aAuthorize,
+ jboolean aAuthenticate, jboolean aEncrypt, jboolean aIsGOEP)
+{
+ JELOG2(EJavaBluetooth);
+
+ std::wstring connectionUrl;
+ try
+ {
+ connectionUrl = JniUtils::jstringToWstring(aJni, aUrl);
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::rfServerOpen Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException",
+ "Opening server connection failed");
+ return NULL;
+ }
+
+ //Get handle to ServerConnectionFactory object.
+ ServerConnectionFactory* connectionFactory = 0;
+ if (!aIsGOEP)
+ {
+ connectionFactory = &BTRFCOMMServerConnectionFactory::getFactory();
+ }
+ else
+ {
+ connectionFactory = &BTOBEXServerConnectionFactory::getFactory();
+ }
+
+ RFCOMMPushServerConnection *rfcommPushServer;
+
+ ServerConnection *serverConn =
+ connectionFactory->create(connectionUrl);
+ rfcommPushServer =
+ reinterpret_cast<RFCOMMPushServerConnection*>(serverConn);
+
+ if (rfcommPushServer->isActive())
+ {
+ //if we have already accepted connection or are listening, we need not
+ //go any further. return handle.
+ LOG(EJavaBluetooth, EInfo,
+ "- JNI::rfServerOpen: Bluetooth server already running ");
+ return reinterpret_cast<jlong>(rfcommPushServer);
+ }
+ else
+ {
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::rfServerOpen: Opening server ");
+ RFCOMMServerConnection* srvHandle =
+ rfcommPushServer->getServerObject();
+
+ TInt err;
+
+ err = srvHandle->ServerOpen(aAuthorize, aAuthenticate, aEncrypt);
+
+ if (err != KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::rfServerOpen Error on RFCOMMServerConnection.ServerOpen: %d",
+ err);
+ if (rfcommPushServer->isCreatedByPush())
+ {
+ connectionFactory->releaseConnection(connectionUrl);
+ }
+ else
+ {
+ rfcommPushServer->close();
+ delete rfcommPushServer;
+ }
+
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Opening server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ return NULL;
+ }
+ }
+ return reinterpret_cast<jlong>(rfcommPushServer);
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: rfcommRegisterSDPRecord
+ * Signature: (JI[BLjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1rfcommRegisterSDPRecord
+(JNIEnv *aJni, jobject /*peer*/, jlong aHandle, jint aChannel,
+ jbyteArray aUuid, jstring aServerName, jboolean aIsObex)
+{
+ JELOG2(EJavaBluetooth);
+ TInt err;
+
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ if (server->isActive())
+ {
+ //If the server is active it means that it has already done
+ //registration and has started advertising.
+ //If connection has already been accepted, then no issues at all.
+ return;
+ }
+
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::rfcommRegisterSDPRecord Getting server object");
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+
+ jbyte* byteArray = aJni->GetByteArrayElements(aUuid, NULL);
+ TPtrC8 uuidDes(
+ reinterpret_cast<TUint8*>(byteArray), aJni->GetArrayLength(aUuid));
+ TUUID uuid;
+
+ TRAP(err, uuid.SetL(uuidDes));
+ if (err != KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::rfcommRegisterSDPRecord Error while converting UUID: %d",
+ err);
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Opening server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ return;
+ }
+
+ JStringUtils servName(*aJni, aServerName);
+ TPtrC8 servNameP(
+ reinterpret_cast<const TUint8*>(servName.Ptr()), servName.Size());
+
+ err = srvHandle->initializeServiceRecord(
+ aChannel, uuid, servNameP, aIsObex);
+
+ if (err != KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::rfcommRegisterSDPRecord Error while initializeServiceRecord: %d",
+ err);
+
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "Opening server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ }
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: rfGetChannel
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1rfGetChannel
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+ int channel = srvHandle->GetRfListeningChannel();
+
+ LOG1(EJavaBluetooth, EInfo, "- JNI::rfGetChannel: %d", channel);
+ return channel;
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: rfServerGetServiceRecord
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1rfServerGetServiceRecord
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+ int servRecId = 0;
+ ServiceRecord* srvRecHandle = srvHandle->getServiceRecordHandle();
+
+ if (NULL != srvRecHandle)
+ {
+ srvRecHandle->getServiceRecordID();
+ }
+ LOG1(EJavaBluetooth, EInfo,
+ "- JNI::rfServerGetServiceRecord: %d", srvRecHandle);
+ return servRecId;
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: rfServerAcceptAndOpenServerConnection
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1rfServerAcceptAndOpenServerConnection
+(JNIEnv *aJni, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ if (server->isConnectionAccepted())
+ {
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::rfServerAcceptAndOpenServerConnection: returning already accepted push client ");
+ //Since connection has already been accepted, return the client object.
+ return reinterpret_cast<jlong>(server->getConnectedClient());
+ }
+
+ if (server->isListening())
+ {
+ //Wait till connect and then return.
+ //Then we return client here.
+ java::util::Monitor* acceptMonitor =
+ java::util::Monitor::createMonitor();
+
+ server->setAcceptMonitor(acceptMonitor);
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::rfServerAcceptAndOpenServerConnection: waiting for connection accept ");
+ acceptMonitor->wait();
+ server->unsetAcceptMonitor();
+ delete acceptMonitor;
+
+ return reinterpret_cast<jlong>(server->getConnectedClient());
+ }
+
+ LOG(EJavaBluetooth, EInfo,
+ " JNI::rfServerAcceptAndOpenServerConnection Getting server object");
+
+ //NOTE: In case we reached here, it means that there was no corresponding
+ //push plugin active when the midlet was launched.
+ //So we go ahead with usual stuff.
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+
+ long clientHandle;
+
+ clientHandle = srvHandle->Accept();
+
+ if (clientHandle < KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::rfServerAcceptAndOpenServerConnection Error while Accept: %d ",
+ clientHandle);
+
+ if (KErrCancel == clientHandle)
+ {
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/InterruptedIOException",
+ "acceptAndOpen() on server connection failed: connection is closed ");
+ }
+ else
+ {
+ java::util::JniUtils::throwNewException(aJni,
+ "java/io/IOException",
+ "acceptAndOpen() on server connection failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(clientHandle));
+ }
+ }
+ return (clientHandle);
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: rfServerClose
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1rfServerClose
+(JNIEnv* /*aJni*/, jobject /*peer*/, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ ServerConnectionFactory* connectionFactory = 0;
+ if (!(server->isGOEPConnection()))
+ {
+ connectionFactory = &BTRFCOMMServerConnectionFactory::getFactory();
+ }
+ else
+ {
+ connectionFactory = &BTOBEXServerConnectionFactory::getFactory();
+ }
+ std::wstring uri = server->getUri();
+
+ server->unsetClearServiceClassBitsFlag();
+ if (server->isCreatedByPush())
+ {
+ connectionFactory->releaseConnection(uri);
+ }
+ else
+ {
+ server->close();
+ delete server;
+ }
+ return 0;
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: initializeUpdateRecord
+ * Signature: (Ljava/lang/String;J)V
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1initializeUpdateRecord
+(JNIEnv *aJni, jobject /*peer*/,
+ jstring aProtocol, jlong aHandle, jint aDeviceServiceClasses)
+{
+ JELOG2(EJavaBluetooth);
+ ServiceRecord* srvRec;
+
+ std::wstring protocol;
+
+ try
+ {
+ protocol = java::util::JniUtils::jstringToWstring(aJni, aProtocol);
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::initializeUpdateRecord Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException", "Updating service record failed");
+ return;
+ }
+
+ if (0 == protocol.compare(L"btl2cap"))
+ {
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+ else //if protocol is "btspp"
+ {
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+
+ srvRec->initializeUpdateRecord(aDeviceServiceClasses);
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: completesUpdateRecord
+ * Signature: (Ljava/lang/String;J)V
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1completesUpdateRecord
+(JNIEnv *aJni, jobject /*peer*/, jstring aProtocol, jlong aHandle)
+{
+ JELOG2(EJavaBluetooth);
+ ServiceRecord* srvRec;
+
+ std::wstring protocol;
+
+ try
+ {
+ protocol = java::util::JniUtils::jstringToWstring(aJni, aProtocol);
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::completesUpdateRecord Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException", "Updating service record failed");
+ return;
+ }
+ if (0 == protocol.compare(L"btl2cap"))
+ {
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+ else // if protocol is "btspp"
+ {
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+
+ srvRec->completesUpdateRecord();
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: sdpAddAttribute
+ * Signature: (Ljava/lang/String;JIIJ[B)V
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1sdpAddAttribute
+(JNIEnv *aJni, jobject /*peer*/, jstring aProtocol, jlong aHandle,
+ jint aAttrID, jint aAttrType, jlong aNumValue, jbyteArray aBytesValue)
+{
+ JELOG2(EJavaBluetooth);
+ ServiceRecord* srvRec;
+ int err = 0;
+
+ std::wstring protocol;
+
+ try
+ {
+ protocol = java::util::JniUtils::jstringToWstring(aJni, aProtocol);
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::sdpAddAttribute Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException", "Updating service record failed");
+ return;
+ }
+ if (0 == protocol.compare(L"btl2cap"))
+ {
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+ else // if protocol is "btspp"
+ {
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+
+ LOG1(EJavaBluetooth, EInfo,
+ " JNI::sdpAddAttribute aAttrType:%d", aAttrType);
+ switch (aAttrType)
+ {
+ case DataElement_NULL:
+ {
+ err = srvRec->setAttributeNil(aAttrID);
+ break;
+ }
+ case DataElement_BOOL:
+ {
+ TBool val = (aNumValue) ? ETrue : EFalse;
+
+ err = srvRec->setAttributeBool(aAttrID, val);
+ break;
+ }
+ case DataElement_U_INT_1:
+ case DataElement_INT_1:
+ case DataElement_U_INT_2:
+ case DataElement_INT_2:
+ case DataElement_U_INT_4:
+ case DataElement_INT_4:
+ {
+ ELOG(EJavaBluetooth, " JNI::sdpAddAttribute UINT/INT/1/2/4 element.");
+ TSdpIntBuf<TUint> val(aNumValue);
+
+ err = srvRec->setAttributeInt(aAttrID, aAttrType, val);
+ break;
+ }
+ case DataElement_INT_8:
+ {
+ TSdpIntBuf<TUint64> val(aNumValue);
+
+ err = srvRec->setAttributeInt(aAttrID, aAttrType, val);
+ break;
+ }
+ case DataElement_U_INT_8:
+ case DataElement_U_INT_16:
+ case DataElement_INT_16:
+ {
+ jbyte* bytes = aJni->GetByteArrayElements(aBytesValue, NULL);
+ TPtrC8 val(reinterpret_cast<TUint8*>(bytes),
+ aJni->GetArrayLength(aBytesValue));
+
+ err = srvRec->setAttributeUint(aAttrID, aAttrType, val);
+ break;
+ }
+ case DataElement_UUID:
+ {
+ jbyte* bytes = aJni->GetByteArrayElements(aBytesValue, NULL);
+ TPtrC8 uuidDes(reinterpret_cast<TUint8*>(bytes),
+ aJni->GetArrayLength(aBytesValue));
+
+ TUUID val;
+
+ TRAP(err, val.SetL(uuidDes));
+ if (err != KErrNone)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::sdpAddAttribute Error while converting UUID: %d",
+ err);
+ java::util::JniUtils::throwNewException(aJni,
+ "javax/bluetooth/ServiceRegistrationException",
+ "Updating service record failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ return;
+ }
+ err = srvRec->setAttributeUUID(aAttrID, val);
+ break;
+ }
+ case DataElement_STRING:
+ {
+ jbyte* bytes = aJni->GetByteArrayElements(aBytesValue, NULL);
+ TPtrC8 val(reinterpret_cast<TUint8*>(bytes),
+ aJni->GetArrayLength(aBytesValue));
+
+ err = srvRec->setAttributeString(aAttrID, val);
+ break;
+ }
+ case DataElement_URL:
+ {
+ jbyte* bytes = aJni->GetByteArrayElements(aBytesValue, NULL);
+ TPtrC8 val(reinterpret_cast<TUint8*>(bytes),
+ aJni->GetArrayLength(aBytesValue));
+
+ err = srvRec->setAttributeUrl(aAttrID, val);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (KErrNone != err)
+ {
+
+ ELOG1(EJavaBluetooth,
+ "- JNI::sdpAddAttribute Failed to update service record %d",
+ err);
+ java::util::JniUtils::throwNewException(aJni,
+ "javax/bluetooth/ServiceRegistrationException",
+ "Updating service record failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ }
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: sdpAttributeListStart
+ * Signature: (Ljava/lang/String;JII)V
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1sdpAttributeListStart
+(JNIEnv *aJni, jobject /*peer*/, jstring aProtocol, jlong aHandle,
+ jint aAttrID, jint aAttrType)
+{
+ JELOG2(EJavaBluetooth);
+ ServiceRecord* srvRec;
+ int err = 0;
+ std::wstring protocol;
+
+ try
+ {
+ protocol = java::util::JniUtils::jstringToWstring(aJni, aProtocol);
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::sdpAttributeListStart Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException", "Updating service record failed");
+ return;
+ }
+ if (0 == protocol.compare(L"btl2cap"))
+ {
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+ else // if protocol is "btspp"
+ {
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+
+ err = srvRec->attributeListStart(aAttrID, aAttrType);
+
+ if (KErrNone != err)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::sdpAttributeListStart Error while attributeListStart: %d",
+ err);
+ java::util::JniUtils::throwNewException(aJni,
+ "javax/bluetooth/ServiceRegistrationException",
+ "Updating service record failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ }
+}
+
+/*
+ * Class: com_nokia_mj_impl_bluetooth_BluetoothStackS60
+ * Method: sdpAttributeListEnd
+ * Signature: (Ljava/lang/String;JI)V
+ */
+JNIEXPORT void JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1sdpAttributeListEnd
+(JNIEnv *aJni, jobject /*peer*/, jstring aProtocol, jlong aHandle,
+ jint aAttrID)
+{
+ JELOG2(EJavaBluetooth);
+ ServiceRecord* srvRec;
+ int err = 0;
+ std::wstring protocol;
+
+ try
+ {
+ protocol = java::util::JniUtils::jstringToWstring(aJni, aProtocol);
+ }
+ catch (ExceptionBase ex)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::sdpAttributeListEnd Exception:%S", ex.what());
+ java::util::JniUtils::throwNewException(aJni,
+ "java/lang/RunTimeException", "Updating service record failed");
+ return;
+ }
+ if (0 == protocol.compare(L"btl2cap"))
+ {
+ L2CapPushServerConnection* server =
+ reinterpret_cast<L2CapPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ L2CAPServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+ else // if protocol is "btspp"
+ {
+ RFCOMMPushServerConnection* server =
+ reinterpret_cast<RFCOMMPushServerConnection *>(
+ static_cast<long>(aHandle));
+
+ RFCOMMServerConnection *srvHandle = server->getServerObject();
+
+ srvRec = srvHandle->getServiceRecordHandle();
+ }
+
+ err = srvRec->attributeListEnd(aAttrID);
+
+ if (KErrNone != err)
+ {
+ ELOG1(EJavaBluetooth,
+ "- JNI::sdpAttributeListEnd Error while attributeListEnd: %d",
+ err);
+
+ java::util::JniUtils::throwNewException(aJni,
+ "javax/bluetooth/ServiceRegistrationException",
+ "Updating service record failed. Symbian OS error: "
+ + JavaCommonUtils::intToString(err));
+ }
+}
+
+//
+// JNI functions specific to Remote Device operations
+//
+
+
+JNIEXPORT jboolean JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1isAuthenticated
+(JNIEnv* /*aJni*/, jobject /*aPeer*/, jlong aRemoteAddress)
+{
+ JELOG2(EJavaBluetooth);
+
+ jboolean ret = java::bluetooth::BluetoothRemoteDevice::getSecurityProperty(
+ REMOTE_AUTHENTICATED, aRemoteAddress);
+
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_nokia_mj_impl_bluetooth_BluetoothStackS60__1isTrusted
+(JNIEnv* /*aJni*/, jobject /*aPeer*/, jlong aRemoteAddress)
+{
+ JELOG2(EJavaBluetooth);
+
+ jboolean ret = java::bluetooth::BluetoothRemoteDevice::getSecurityProperty(
+ REMOTE_TRUSTED, aRemoteAddress);
+
+ return ret;
+}