javaextensions/bluetooth/bluetoothcommons/src.s60/btservicerecordpopulator.cpp
changeset 21 2a9601315dfc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/bluetooth/bluetoothcommons/src.s60/btservicerecordpopulator.cpp	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,476 @@
+/*
+* 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 "btservicerecordpopulator.h"
+
+#include "bluetoothconsts.h"
+
+namespace java
+{
+namespace bluetooth
+{
+
+OS_EXPORT BTServiceRecordPopulator* BTServiceRecordPopulator::New(JNIEnv* aJni,
+        jobject aServiceRecordImpl)
+{
+    JELOG2(EJavaBluetooth);
+    BTServiceRecordPopulator* populator = new BTServiceRecordPopulator();
+    populator->Construct(aJni, aServiceRecordImpl);
+    return populator;
+}
+
+BTServiceRecordPopulator::BTServiceRecordPopulator()
+{
+}
+
+void BTServiceRecordPopulator::Construct(JNIEnv* aJni,
+        jobject aServiceRecordImpl)
+{
+    JELOG2(EJavaBluetooth);
+    mCurrentState = ENotPopulating;
+    mAttributeFound = false;
+    mCurrentAttributeId = 0;
+    mDataElementListPopulator = NULL;
+    mJni = aJni;
+    mServiceRecordImpl = aServiceRecordImpl;
+    mServiceRecordImplClass = mJni->GetObjectClass(mServiceRecordImpl);
+    mPopulateAttributeValueMethod = mJni->GetMethodID(mServiceRecordImplClass,
+                                    "populateAttributeValue", "(ILjavax/bluetooth/DataElement;)V");
+    mDataElementClass = mJni->FindClass("javax/bluetooth/DataElement");
+}
+
+OS_EXPORT BTServiceRecordPopulator::~BTServiceRecordPopulator()
+{
+    JELOG2(EJavaBluetooth);
+    if (mDataElementListPopulator)
+    {
+        delete mDataElementListPopulator;
+        mDataElementListPopulator = NULL;
+    }
+    mCurrentState = ENotPopulating;
+    mCurrentAttributeId = 0;
+    mJni = NULL;
+    mServiceRecordImpl = NULL;
+    mServiceRecordImplClass = NULL;
+    mPopulateAttributeValueMethod = NULL;
+    mDataElementClass = NULL;
+}
+
+OS_EXPORT bool BTServiceRecordPopulator::isAttributesFound()
+{
+    return mAttributeFound;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::SetServiceRecordHandle(
+    TUint32 aServRecHandle)
+{
+    JELOG2(EJavaBluetooth);
+
+    jmethodID populateServiceRecordHandleMethod = mJni->GetMethodID(
+                mServiceRecordImplClass, "populateServiceRecordHandle", "(I)V");
+
+    mJni->CallVoidMethod(mServiceRecordImpl, populateServiceRecordHandleMethod,
+                         aServRecHandle);
+
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::SetDeviceServiceClass(
+    TUint32 aDeviceClass)
+{
+    JELOG2(EJavaBluetooth);
+
+    jmethodID setDeviceServiceClassMethod = mJni->GetMethodID(
+                                                mServiceRecordImplClass, "setDeviceServiceClasses", "(I)V");
+
+    mJni->CallVoidMethod(mServiceRecordImpl, setDeviceServiceClassMethod,
+                         aDeviceClass);
+
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildDESL()
+{
+    JELOG2(EJavaBluetooth);
+    if (ENotPopulating == mCurrentState)
+    {
+        // Expected BuildDESL must call at the beginning
+        mCurrentState = EReadyForStartList;
+    }
+    else if (EReadyForAttributeValue == mCurrentState)
+    {
+        LOG(EJavaBluetooth, EInfo,
+            "  BTServiceRecordPopulator::BuildDESL Constructing List");
+        mCurrentState = EReadyForAttributeId;
+        jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                  "<init>", "(I)V");
+        mCurrentDataElement = mJni->NewObject(mDataElementClass, constructorID,
+                                              DataElement_DATSEQ);
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+
+        mDataElementListPopulator = BTDataElementListPopulator::New(mJni, this,
+                                    mCurrentDataElement, false);
+        return mDataElementListPopulator;
+    }
+
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildDEAL()
+{
+    JELOG2(EJavaBluetooth);
+    if (EReadyForAttributeValue == mCurrentState)
+    {
+        LOG(EJavaBluetooth, EInfo,
+            "  BTServiceRecordPopulator::BuildDEAL Constructing List");
+        mCurrentState = EReadyForAttributeId;
+        jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                  "<init>", "(I)V");
+        mCurrentDataElement = mJni->NewObject(mDataElementClass, constructorID,
+                                              DataElement_DATALT);
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+
+        mDataElementListPopulator = BTDataElementListPopulator::New(mJni, this,
+                                    mCurrentDataElement, false);
+        return mDataElementListPopulator;
+    }
+
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::StartListL()
+{
+    JELOG2(EJavaBluetooth);
+    if (EReadyForStartList == mCurrentState)
+    {
+        mCurrentState = EReadyForAttributeId;
+    }
+    else
+    {
+        LOG(EJavaBluetooth, EInfo,
+            "  BTServiceRecordPopulator::StartListL Called without DESL");
+    }
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildUintL(const TDesC8& aUint)
+{
+    JELOG2(EJavaBluetooth);
+    CSdpAttrValue* value = CSdpAttrValueUint::NewUintL(aUint);
+    TUint dataSize = value->DataSize();
+
+    if (EReadyForAttributeId == mCurrentState)
+    {
+        LOG1(EJavaBluetooth, EInfo,
+             "  BTServiceRecordPopulator::BuildUintL Got Attribute ID %X",
+             value->Uint());
+        mCurrentState = EReadyForAttributeValue;
+        mAttributeFound = true;
+        if (mDataElementListPopulator)
+        {
+            delete mDataElementListPopulator;
+            mDataElementListPopulator = NULL;
+        }
+
+        LOG1(
+            EJavaBluetooth,
+            EInfo,
+            "  BTServiceRecordPopulator::BuildUintL Setting attribute ID %X",
+            value->Uint());
+        mCurrentAttributeId = (TSdpAttributeID) value->Uint();
+    }
+    else
+    {
+        mCurrentState = EReadyForAttributeId;
+
+        if (dataSize <= 4)
+        {
+            jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                      "<init>", "(IJ)V");
+            jlong dataValue = (jlong) value->Uint();
+
+            if (dataSize == 1)
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_U_INT_1, dataValue);
+            }
+            else if (dataSize == 2)
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_U_INT_2, dataValue);
+            }
+            else //if (dataSize == 4)
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_U_INT_4, dataValue);
+            }
+        }
+        else
+        {
+            jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                      "<init>", "(ILjava/lang/Object;)V");
+
+            jbyte* bytes = (jbyte*) aUint.Ptr();
+            jbyteArray byteArray = mJni->NewByteArray(dataSize);
+            mJni->SetByteArrayRegion(byteArray, 0, dataSize, bytes);
+
+            if (dataSize == 8)
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_U_INT_8, byteArray);
+            }
+            else
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_U_INT_16, byteArray);
+            }
+        }
+
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+    }
+    delete value;
+    value = NULL;
+
+    LOG(EJavaBluetooth, EInfo, "- BTServiceRecordPopulator::BuildUintL");
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::EndListL()
+{
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildIntL(const TDesC8& aInt)
+{
+    JELOG2(EJavaBluetooth);
+
+    if (EReadyForAttributeValue == mCurrentState)
+    {
+        mCurrentState = EReadyForAttributeId;
+
+        CSdpAttrValue* value = CSdpAttrValueInt::NewIntL(aInt);
+        TUint dataSize = value->DataSize();
+
+        if (dataSize < 8)
+        {
+            jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                      "<init>", "(IJ)V");
+            jlong dataValue = (jlong) value->Int();
+
+            if (dataSize == 1)
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_INT_1, dataValue);
+            }
+            else if (dataSize == 2)
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_INT_2, dataValue);
+            }
+            else // (dataSize == 4)
+            {
+                mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                      constructorID, DataElement_INT_4, dataValue);
+            }
+        }
+        else if (dataSize == 8)
+        {
+            jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                      "<init>", "(IJ)V");
+            const TUint8* ptr = value->Des().Ptr();
+            TUint highBytes = BigEndian::Get32(ptr);
+            TUint lowBytes = BigEndian::Get32(ptr + sizeof(TUint));
+            TInt64 dataValue = MAKE_TINT64(highBytes, lowBytes);
+            mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                  constructorID, DataElement_INT_8, (jlong)dataValue);
+        }
+        else
+        {
+            jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                      "<init>", "(ILjava/lang/Object;)V");
+
+            jbyte* bytes = (jbyte*) aInt.Ptr();
+            jbyteArray byteArray = mJni->NewByteArray(dataSize);
+            mJni->SetByteArrayRegion(byteArray, 0, dataSize, bytes);
+
+            mCurrentDataElement = mJni->NewObject(mDataElementClass,
+                                                  constructorID, DataElement_INT_16, byteArray);
+        }
+        delete value;
+        value = NULL;
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+    }
+    LOG(EJavaBluetooth, EInfo, "- BTServiceRecordPopulator::BuildIntL");
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildNilL()
+{
+    JELOG2(EJavaBluetooth);
+    if (EReadyForAttributeValue == mCurrentState)
+    {
+        mCurrentState = EReadyForAttributeId;
+
+        jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                  "<init>", "(I)V");
+        mCurrentDataElement = mJni->NewObject(mDataElementClass, constructorID,
+                                              DataElement_NULL);
+
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+    }
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildBooleanL(TBool aBool)
+{
+    JELOG2(EJavaBluetooth);
+    if (EReadyForAttributeValue == mCurrentState)
+    {
+        mCurrentState = EReadyForAttributeId;
+
+        jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                  "<init>", "(Z)V");
+        mCurrentDataElement = mJni->NewObject(mDataElementClass, constructorID,
+                                              aBool);
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+    }
+    LOG1(EJavaBluetooth, EInfo, "- BTServiceRecordPopulator::BuildBooleanL %d",
+         (int) aBool);
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildStringL(
+    const TDesC8& aString)
+{
+    JELOG2(EJavaBluetooth);
+    if (EReadyForAttributeValue == mCurrentState)
+    {
+        mCurrentState = EReadyForAttributeId;
+
+        HBufC8* bufString = HBufC8::New(aString.Length()+1);
+        TPtr8 ptr = bufString->Des();
+
+        ptr.Copy(aString);
+        jstring dataValue = mJni->NewStringUTF((char *) ptr.PtrZ());
+        delete bufString;
+        jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                  "<init>", "(ILjava/lang/Object;)V");
+        mCurrentDataElement = mJni->NewObject(mDataElementClass, constructorID,
+                                              DataElement_STRING, dataValue);
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+    }
+    LOG1(EJavaBluetooth, EInfo, "- BTServiceRecordPopulator::BuildStringL %S",
+         (char *) aString.Ptr());
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildURLL(const TDesC8& aURL)
+{
+    JELOG2(EJavaBluetooth);
+    if (EReadyForAttributeValue == mCurrentState)
+    {
+        mCurrentState = EReadyForAttributeId;
+        HBufC8* bufString = HBufC8::New(aURL.Length()+1);
+        TPtr8 ptr = bufString->Des();
+
+        ptr.Copy(aURL);
+        jstring dataValue = mJni->NewStringUTF((char *) ptr.PtrZ());
+        delete bufString;
+        jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                  "<init>", "(ILjava/lang/Object;)V");
+        mCurrentDataElement = mJni->NewObject(mDataElementClass, constructorID,
+                                              DataElement_URL, dataValue);
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+    }
+    LOG1(EJavaBluetooth, EInfo, "- BTServiceRecordPopulator::BuildURLL %S",
+         (char *) aURL.Ptr());
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildUUIDL(const TUUID& aUUID)
+{
+    JELOG2(EJavaBluetooth);
+    if (EReadyForAttributeValue == mCurrentState)
+    {
+        mCurrentState = EReadyForAttributeId;
+
+        jobject dataValue = TUUIDtoJUUID(aUUID);
+        jmethodID constructorID = mJni->GetMethodID(mDataElementClass,
+                                  "<init>", "(ILjava/lang/Object;)V");
+        mCurrentDataElement = mJni->NewObject(mDataElementClass, constructorID,
+                                              DataElement_UUID, dataValue);
+        mJni->CallVoidMethod(mServiceRecordImpl, mPopulateAttributeValueMethod,
+                             mCurrentAttributeId, mCurrentDataElement);
+    }
+    return this;
+}
+
+MSdpElementBuilder* BTServiceRecordPopulator::BuildUnknownL(TUint8 /*aType*/,
+        TUint8 /*aSizeDesc*/, const TDesC8& /*aData*/)
+{
+    // Ignore if any unknown type of data exist !!
+    JELOG2(EJavaBluetooth);
+    return this;
+}
+
+char BTServiceRecordPopulator::NibbleToHexChar(TUint8 aByte)
+{
+    char hexChars[] = "0123456789abcdef";
+    return hexChars[aByte];
+}
+
+jobject BTServiceRecordPopulator::TUUIDtoJUUID(const TUUID& aUUID)
+{
+    JELOG2(EJavaBluetooth);
+    TPtrC8 ptrUUID = aUUID.Des();
+    TInt uuidLen = ptrUUID.Length();
+    char *strUUIDBuff = new char[(uuidLen * 2) + 1];
+    int strIndex = 0;
+    int ptrIndex = 0;
+
+    for (ptrIndex = 0; ptrIndex < uuidLen; ptrIndex++)
+    {
+        strUUIDBuff[strIndex++] = NibbleToHexChar((ptrUUID[ptrIndex] >> 4)
+                                  & 0xf);
+        strUUIDBuff[strIndex++] = NibbleToHexChar(ptrUUID[ptrIndex] & 0xf);
+    }
+    strUUIDBuff[strIndex] = 0;
+
+    jstring uuidString = mJni->NewStringUTF(strUUIDBuff);
+    jclass uuidClass = mJni->FindClass("javax/bluetooth/UUID");
+    jmethodID constructorID = mJni->GetMethodID(uuidClass, "<init>",
+                              "(Ljava/lang/String;Z)V");
+    bool isShortUUID = (uuidLen > 4) ? false : true;
+
+    LOG1(EJavaBluetooth, EInfo, "- BTServiceRecordPopulator::TUUIDtoJUUID %s",
+         strUUIDBuff);
+    delete[] strUUIDBuff;
+    strUUIDBuff = NULL;
+    return mJni->NewObject(uuidClass, constructorID, uuidString, isShortUUID);
+}
+
+} //end namespace bluetooth
+} //end namespace java