javaextensions/bluetooth/bluetoothcommons/src.s60/servicerecord.cpp
changeset 21 2a9601315dfc
child 47 f40128debb5d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/bluetooth/bluetoothcommons/src.s60/servicerecord.cpp	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,1651 @@
+/*
+* 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 <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "fs_methodcall.h"
+#include "javajniutils.h"
+#include "servicerecord.h"
+#include "logger.h"
+#include "javasymbianoslayer.h"
+#include "bluetoothconsts.h"
+#include "applicationinfo.h"
+#include "fileutilities.h"
+#include "javaoslayer.h"
+#include "javacommonutils.h"
+#include "btservicerecordpopulator.h"
+#include "serviceclasshandler.h"
+#include "fileutilities.h"
+#include "exceptionbase.h"
+
+using namespace java::util;
+using namespace java::fileutils;
+
+namespace java
+{
+namespace bluetooth
+{
+
+#define SERVICE_AVAILABLE 0xFF
+#define KGOEP 0x0008    // This is the fixed Id. Should not be modified at any time.
+#define SERVICE_CLASSES_BITS_POS    13
+
+// Permission: Read,Write,Execute for both Owner & Group
+#define BT_DIR_PERM 0777
+
+/**
+ * Returns the new ServiceRecord object.
+ */
+OS_EXPORT ServiceRecord* ServiceRecord::NewL(BluetoothFunctionServer* aServer)
+{
+    JELOG2(EJavaBluetooth);
+    ServiceRecord* servRec = new ServiceRecord(aServer);
+    CleanupStack::PushL(servRec);
+
+    servRec->ConstructL();
+
+    CleanupStack::Pop(servRec);
+
+    return servRec;
+}
+
+OS_EXPORT void ServiceRecord::cleanup(ServiceRecord*& aServer)
+{
+    JELOG2(EJavaBluetooth);
+    if (aServer)
+    {
+        aServer->cleanUp();
+        delete aServer;
+        aServer = NULL;
+    }
+}
+
+void ServiceRecord::ConstructL()
+{
+    JELOG2(EJavaBluetooth);
+
+    mInitializedByPush = false;
+    mRestoredFromPersistentFile = false;
+
+    // Open sdp session
+    User::LeaveIfError(mSdp.Connect());
+
+    // Open sdp database session
+    User::LeaveIfError(mSdpDB.Open(mSdp));
+
+    mRecordState = 0;
+}
+
+ServiceRecord::ServiceRecord(BluetoothFunctionServer* aServer)
+{
+    JELOG2(EJavaBluetooth);
+    mFunctionServer = aServer;
+    mRecord = 0;
+    mSrvRecFd = 0;
+}
+
+ServiceRecord::~ServiceRecord()
+{
+    JELOG2(EJavaBluetooth);
+    mFunctionServer = NULL;
+}
+
+void ServiceRecord::cleanUp()
+{
+    JELOG2(EJavaBluetooth);
+    if (mRecord)
+    {
+        TRAP_IGNORE(mSdpDB.DeleteRecordL(mRecord));
+        mRecord = 0;
+    }
+    mSdpDB.Close();
+    mSdp.Close();
+}
+
+/**
+ * Used in case there is no persistence storage of service record
+ * On success returns 0; otherwise err number.
+ *
+ * Creates and initializes the Service record.
+ * aProtocol: One among the PROTOCOL_L2CAP, PROTOCOL_RFCOMM, PROTOCOL_GOEP
+ * aPSMValue: In case of L2CAP it should be PSM Value;
+ *            In case of RFComm it should be channel number.
+ * aUuid: UUID string of the current service
+ * aServiceName: Name of the current service.
+ */
+
+OS_EXPORT int ServiceRecord::initializeRecord(int aProtocol, int aPSMValue,
+        std::wstring aUuid, std::wstring aServiceName)
+{
+    JELOG2(EJavaBluetooth);
+
+    int uuidByteLength = 0;
+    TUint8* uuidBytes = uuidToByteArray(aUuid, uuidByteLength);
+
+    TUUID uuid;
+
+    TPtrC8 uuidDes(uuidBytes, uuidByteLength);
+    TRAPD(err, uuid.SetL(uuidDes));
+
+    delete uuidBytes;
+    uuidBytes = NULL;
+
+    if (KErrNone != err)
+    {
+        LOG2(EJavaBluetooth, EInfo,
+             "- ServiceRecord::initializeRecord Error SetL:%d [UUID:%S]",
+             err, aUuid.c_str());
+        return err;
+    }
+
+    HBufC* nameString = wstringToBuf(aServiceName);
+    TPtrC nameBufPointer(nameString->Des());
+
+    HBufC8* utf8NameBuffer = HBufC8::NewMax(aServiceName.length() + 1);
+    TPtr8 utf8NameBufferPtr(utf8NameBuffer->Des());
+
+    utf8NameBufferPtr.Copy(nameBufPointer);
+
+    TRAP(err, initializeRecordL(aProtocol, aPSMValue, uuid, utf8NameBufferPtr));
+
+    return err;
+}
+
+/**
+ * Used in case of persistence storage of updated service record
+ */
+OS_EXPORT int ServiceRecord::restorePersistentRecord()
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+
+    CallMethod(ret, this, &ServiceRecord::restorePersistentRecordFs,
+               mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::restorePersistentRecordFs()
+{
+    JELOG2(EJavaBluetooth);
+
+    // Can set this flag as this function will get called
+    // only in case of push invocation
+    mInitializedByPush = true;
+
+    std::wstring persistentFileName = getPersistentFileName();
+    int persistentRecFd = -1;
+    int ret = 0;
+    int err = 0;
+
+    if (persistentFileName.length() > 0)
+    {
+        try
+        {
+            char *fileName = java::util::JavaCommonUtils::wstringToUtf8(
+                                 persistentFileName);
+            persistentRecFd = open(fileName, O_RDONLY);
+            delete fileName;
+        }
+        catch (ExceptionBase ex)
+        {
+            ELOG1(
+                EJavaBluetooth,
+                "- ServiceRecord::restorePersistentRecordFs exception Caught: %S",
+                ex.toString().c_str());
+        }
+    }
+
+    if (persistentRecFd < 0)
+        return errno;
+
+    // Reading and restoring the DeviceServiceClasses bits
+    int devServClass = 0;
+    ret = read(persistentRecFd, &devServClass, sizeof(devServClass));
+
+    if (ret <= 0)
+        return errno;
+
+    if (devServClass != 0)
+    {
+        LOG1(EJavaBluetooth, EInfo,
+             "  ServiceRecord::restorePersistentRecordFs Setting COD:0x%X",
+             devServClass);
+        ret = ServiceClassHandler::setDeviceServiceClass(devServClass, true);
+        LOG1(EJavaBluetooth, EInfo,
+             "  ServiceRecord::restorePersistentRecordFs Set COD Return:%d",
+             ret);
+    }
+
+    // Restoring all other service record data
+    int attrId = 0;
+    while ((ret = read(persistentRecFd, &attrId, sizeof(attrId))) > 0)
+    {
+        int dataType = 0;
+
+        ret = read(persistentRecFd, &dataType, sizeof(dataType));
+        if (ret <= 0)
+            break;
+
+        LOG2(EJavaBluetooth, EInfo, "  ServiceRecord reading %X, %X", attrId,
+             dataType);
+
+        switch (dataType)
+        {
+        case DataElement_DATSEQ:
+        case DataElement_DATALT:
+        {
+            err = attributeListStartFs(attrId, dataType, EFalse);
+            break;
+        }
+        case DataElement_EndList:
+        {
+            err = attributeListEndFs(attrId, EFalse);
+            break;
+        }
+        case DataElement_NULL:
+        {
+            err = setAttributeNilFs(attrId, EFalse);
+            break;
+        }
+        case DataElement_BOOL:
+        {
+            TUint8 val = 0;
+            ret = read(persistentRecFd, &val, sizeof(val));
+            if (ret <= 0)
+                break;
+
+            LOG1(EJavaBluetooth, EInfo, "  ServiceRecord reading Bool %X", val);
+            err = setAttributeBoolFs(attrId, (val) ? ETrue : EFalse, EFalse);
+            break;
+        }
+        case DataElement_INT_1:
+        case DataElement_INT_2:
+        case DataElement_INT_4:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[20] = { 0 };
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+            std::auto_ptr<HBufC8> val(convertIntToDesC(buf, dataType));
+            err = setAttributeIntFs(attrId, dataType, *val, EFalse);
+            break;
+        }
+        case DataElement_INT_8:
+        case DataElement_INT_16:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[20] = { 0 };
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+            TPtrC8 val(buf, len);
+            err = setAttributeIntFs(attrId, dataType, val, EFalse);
+            break;
+        }
+        case DataElement_U_INT_1:
+        case DataElement_U_INT_2:
+        case DataElement_U_INT_4:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[20] = { 0 };
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo, "  ServiceRecord reading INT8 %X, %S",
+                 len, buf);
+
+            std::auto_ptr<HBufC8> val(convertIntToDesC(buf, dataType));
+            err = setAttributeUintFs(attrId, dataType, *val, EFalse);
+            break;
+        }
+        case DataElement_U_INT_8:
+        case DataElement_U_INT_16:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[20] = { 0 };
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo, "  ServiceRecord reading INT16 %X, %S",
+                 len, buf);
+
+            TPtrC8 val(buf, len);
+            err = setAttributeUintFs(attrId, dataType, val, EFalse);
+            break;
+        }
+        case DataElement_UUID:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[256] = { 0 };
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo, "  ServiceRecord reading UUID %X, %S",
+                 len, buf);
+
+            TPtrC8 uuidDes(buf, len);
+
+            TUUID val;
+            TRAP(err, val.SetL(uuidDes));
+
+            if (KErrNone == err)
+            {
+                err = setAttributeUUIDFs(attrId, val, EFalse);
+            }
+            break;
+        }
+        case DataElement_STRING:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[1024] = {0};
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG1(EJavaBluetooth, EInfo, "  ServiceRecord reading STRING %X",
+                 len);
+
+            TPtrC8 val(buf, len);
+            err = setAttributeStringFs(attrId, val, EFalse);
+            break;
+        }
+        case DataElement_URL:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[1024] = {0};
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo, "  ServiceRecord reading URL %X, %S",
+                 len, buf);
+
+            TPtrC8 val(buf, len);
+            err = setAttributeUrlFs(attrId, val, EFalse);
+            break;
+        }
+        default:
+            break;
+        }
+
+        // Treated as EOF reached.
+        if (ret <= 0)
+            break;
+    }
+
+    // Indicates a successful retrieval
+    // of the service record from the persistent file
+    mRestoredFromPersistentFile = true;
+
+    return ret;
+}
+
+/**
+ * Creates and initializes the Service record.
+ * aProtocol: One among the PROTOCOL_L2CAP, PROTOCOL_RFCOMM, PROTOCOL_GOEP
+ * aPSMValue: In case of L2CAP it should be PSM Value;
+ *            In case of RFComm it should be channel number.
+ * aServiceUUID: UUID of the current service
+ * aServiceName: Name of the current service.
+ */
+OS_EXPORT void ServiceRecord::initializeRecordL(TInt aProtocol, TInt aPsmValue,
+        TUUID &aServiceUUID, TDesC8 &aServiceName)
+{
+    JELOG2(EJavaBluetooth);
+    CallMethodL(this, &ServiceRecord::initializeRecordFsL, aProtocol,
+                aPsmValue, aServiceUUID, aServiceName, mFunctionServer);
+}
+
+/**
+ * Returns the service record handle.
+ */
+OS_EXPORT int ServiceRecord::getServiceRecordID()
+{
+    return mRecord;
+}
+
+void ServiceRecord::initializeRecordFsL(TInt aProtocol, TInt aPsmValue,
+                                        TUUID &aServiceUUID, TDesC8 &aServiceName)
+{
+    JELOG2(EJavaBluetooth);
+    // Open sdp session
+    User::LeaveIfError(mSdp.Connect());
+    // Open sdp database session
+    User::LeaveIfError(mSdpDB.Open(mSdp));
+
+    LOG1(
+        EJavaBluetooth,
+        EInfo,
+        "  ServiceRecord::initializeRecordFsL: After registering to SDPDB: %S",
+        aServiceUUID.Des().Ptr());
+
+    // Creating proper ServiceClassID list
+    CSdpAttrValueDES *serviceClassIds = CSdpAttrValueDES::NewDESL(NULL);
+    serviceClassIds->BuildUUIDL(aServiceUUID);
+    if (PROTOCOL_RFCOMM == aProtocol)
+    {
+        LOG(EJavaBluetooth, EInfo,
+            "  ServiceRecord::initializeRecordFsL: Adding KSerialPortUUID");
+
+        serviceClassIds->BuildUUIDL(TUUID(KSerialPortUUID));
+    }
+
+    // Create a record of the correct service class
+    mSdpDB.CreateServiceRecordL(*serviceClassIds, mRecord);
+
+    // Add a protocol to the record
+    mSdpAttrValueList = CSdpAttrValueDES::NewDESL(NULL);
+    mLastSdpAttr = mSdpAttrValueList;
+    CleanupStack::PushL(mSdpAttrValueList);
+
+    // Getting port number
+    TSdpIntBuf<TUint> portBuf(aPsmValue);
+    LOG1(EJavaBluetooth, EInfo,
+         "  ServiceRecord::initializeRecordFsL: port value : %d", aPsmValue);
+
+    LOG(EJavaBluetooth, EInfo,
+        "  ServiceRecord::initializeRecordFsL: Creating protocol list");
+
+    // Create protocol list for our service
+
+    switch (aProtocol)
+    {
+    case PROTOCOL_L2CAP:
+        LOG(EJavaBluetooth, EInfo,
+            "  ServiceRecord::initializeRecordFsL: PROTOCOL_L2CAP");
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KL2CAP);
+        mLastSdpAttr = mLastSdpAttr -> BuildUintL(portBuf);
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        break;
+    case PROTOCOL_RFCOMM:
+        LOG(EJavaBluetooth, EInfo,
+            "  ServiceRecord::initializeRecordFsL: PROTOCOL_RFCOMM");
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KL2CAP);
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KRFCOMM);
+        mLastSdpAttr = mLastSdpAttr -> BuildUintL(portBuf);
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        break;
+    case PROTOCOL_GOEP:
+        LOG(EJavaBluetooth, EInfo,
+            "  ServiceRecord::initializeRecordFsL: PROTOCOL_GOEP");
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KL2CAP);
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KRFCOMM);
+        mLastSdpAttr = mLastSdpAttr -> BuildUintL(portBuf);
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+        mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KGOEP);
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        mLastSdpAttr = mLastSdpAttr -> EndListL();
+        break;
+    }
+
+    LOG(EJavaBluetooth, EInfo,
+        "  ServiceRecord::initializeRecordFsL: Set protocol list to the record");
+    // Set protocol list to the record
+    mSdpDB.UpdateAttributeL(mRecord, KSdpAttrIdProtocolDescriptorList,
+                            *mSdpAttrValueList);
+    CleanupStack::PopAndDestroy(mSdpAttrValueList);
+
+    mSdpAttrValueList = NULL;
+    mLastSdpAttr = NULL;
+
+    LOG(EJavaBluetooth, EInfo,
+        "  ServiceRecord::initializeRecordFsL: Update attribute");
+
+    if (aServiceName.Size() > 0)
+    {
+        // Add a name to the record
+        mSdpDB.UpdateAttributeL(mRecord, KSdpAttrIdBasePrimaryLanguage
+                                + KSdpAttrIdOffsetServiceName, aServiceName);
+        LOG1(EJavaBluetooth, EInfo,
+             "  ServiceRecord::initializeRecordFsL: Update Name: %d",
+             KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName);
+    }
+
+    mOrigUuid = uuidToWstring(aServiceUUID);
+
+    LOG1(EJavaBluetooth, EInfo,
+         "  ServiceRecord::initializeRecordFsL mOrigUuid = %S",
+         mOrigUuid.c_str());
+
+    mProtocol = aProtocol;
+}
+
+/**
+ * Opens the persistent file. Called when Update Record triggered.
+ * And stores the DeviceServiceClasses bits (32 bit) in the persistent file
+ * While retrieving the service record back from the file, it is must to read first
+ * one integer which depicts this DeviceServiceClasses. If the service classes is not
+ * set for the corresponding service, then the value 0(32 bits) is stored in place of the
+ * DeviceServiceClasses bits.
+ *
+ */
+OS_EXPORT void ServiceRecord::initializeUpdateRecord(int aDeviceServiceClasses)
+{
+    JELOG2(EJavaBluetooth);
+    std::wstring persistentFileName;
+
+    persistentFileName = getPersistentFileName();
+
+    if (persistentFileName.length() > 0)
+    {
+        try
+        {
+            char *fileName = java::util::JavaCommonUtils::wstringToUtf8(
+                                 persistentFileName);
+            mSrvRecFd = open(fileName, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+
+            if (mSrvRecFd < 0)
+            {
+                ELOG1(
+                    EJavaBluetooth,
+                    "- ServiceRecord::initializeUpdateRecord Err while file open. %d",
+                    errno);
+                return;
+            }
+            // Storing the Current DeviceClass (32 bits)
+            write(mSrvRecFd, (char *) &aDeviceServiceClasses,
+                  sizeof(aDeviceServiceClasses));
+
+            delete fileName;
+        }
+        catch (ExceptionBase ex)
+        {
+            ELOG1(
+                EJavaBluetooth,
+                "- ServiceRecord::initializeUpdateRecord exception Caught: %S",
+                ex.toString().c_str());
+        }
+    }
+}
+
+/**
+ * Closes the persistent file.
+ */
+OS_EXPORT void ServiceRecord::completesUpdateRecord()
+{
+    JELOG2(EJavaBluetooth);
+    if (0 != mSrvRecFd)
+    {
+        close(mSrvRecFd);
+        mSrvRecFd = 0;
+    }
+}
+
+/**
+ * Gets the persistent file name. This function returns the file name pattern
+ * srv_rec_<uuid>_<protocol>.txt And also, the srv_rec_XXX.txt
+ * file name will be prepended with midlet's private directory for
+ * bluetooth. That is, the final outcome of this function may be something
+ * like, <midlet_private_dir>/bt/srv_rec_XXX.txt
+ *
+ * @param aUuid
+ *            uuid string
+ * @param aProtocol
+ *            protocol name
+ * @return Null when connection not registered for push;
+ *         otherwise srv_rec_XXX file name
+ */
+std::wstring ServiceRecord::getPersistentFileName()
+{
+    JELOG2(EJavaBluetooth);
+    std::wstring noFileName;
+    std::wstring srvRecFile;
+
+    LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord:getPersistentFileName %d",
+         mProtocol);
+
+    const java::runtime::ApplicationInfo& appInf =
+        java::runtime::ApplicationInfo::getInstance();
+    const std::wstring btFilesPath = appInf.getRootPath() + L"bt\\";
+
+    if (false == FileUtilities::exists(btFilesPath))
+    {
+        try
+        {
+            LOG1(EJavaBluetooth, EInfo,
+                 "  ServiceRecord:getPersistentFileName mkdir:%S",
+                 btFilesPath.c_str());
+
+            char *dirName = JavaCommonUtils::wstringToUtf8(btFilesPath);
+            if (mkdir(dirName, BT_DIR_PERM) < 0)
+            {
+                ELOG1(EJavaBluetooth,
+                      "- ServiceRecord:getPersistentFileName Err, mkdir:%d",errno);
+                delete[] dirName;
+                return noFileName;
+            }
+            delete[] dirName;
+        }
+        catch (ExceptionBase ex)
+        {
+            ELOG1(EJavaBluetooth,
+                  "- ServiceRecord::getPersistentFileName exception Caught: %S",
+                  ex.toString().c_str());
+            return noFileName;
+        }
+    }
+
+    srvRecFile = btFilesPath + L"srv_rec_";
+
+    switch (mProtocol)
+    {
+    case PROTOCOL_L2CAP:
+        srvRecFile += mOrigUuid + L"_btl2cap.txt";
+        break;
+    case PROTOCOL_RFCOMM:
+        srvRecFile += mOrigUuid + L"_btspp.txt";
+        break;
+    case PROTOCOL_GOEP:
+        srvRecFile += mOrigUuid + L"_btgoep.txt";
+        break;
+    }
+
+    LOG1(EJavaBluetooth, EInfo,
+         "- ServiceRecord:getPersistentFileName %S", srvRecFile.c_str());
+    return srvRecFile;
+}
+
+/**
+ * Exporting this function only for the use of ServerConnection::AcceptL
+ * and ServerConnection::HandleAcceptL methods. In rest of the cases,
+ * this method should be called via setAdvertise()
+ */
+OS_EXPORT int ServiceRecord::setAdvertiseFs(TBool aAvailable)
+{
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::setAdvertise %s",
+         (aAvailable)?"True":"False");
+    int err = 0;
+
+    TInt state = aAvailable ? SERVICE_AVAILABLE : !SERVICE_AVAILABLE;
+
+    // Set availability
+    TRAP(err,
+    {
+        mSdpDB.UpdateAttributeL(mRecord,
+        KSdpAttrIdServiceAvailability, state);
+
+        mSdpDB.UpdateAttributeL(mRecord,
+                                KSdpAttrIdServiceRecordState, ++mRecordState);
+    }
+        );
+    return err;
+}
+
+/**
+ * Creates and starts the new list (DEA/DES)
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::attributeListStart(int aAttrId, int aAttrType)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::attributeListStartFs,
+               aAttrId, aAttrType, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::attributeListStartFs(int aAttrId, int aAttrType, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::attributeListStart %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId >= 0)
+        {
+            switch (aAttrType)
+            {
+            case DataElement_DATSEQ:
+                mSdpAttrValueList = CSdpAttrValueDES::NewDESL(NULL);
+                break;
+            case DataElement_DATALT:
+                mSdpAttrValueList = CSdpAttrValueDEA::NewDEAL(NULL);
+                break;
+            default:
+                break;
+            }
+            mLastSdpAttr = mSdpAttrValueList;
+        }
+        else
+        {
+            switch (aAttrType)
+            {
+            case DataElement_DATSEQ:
+                if (mLastSdpAttr)
+                    mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+                break;
+            case DataElement_DATALT:
+                if (mLastSdpAttr)
+                    mLastSdpAttr = mLastSdpAttr -> BuildDESL();
+                break;
+            default:
+                break;
+            }
+        }
+        mLastSdpAttr = mLastSdpAttr -> StartListL();
+    }
+         );
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord Writing %d, %d",
+             aAttrId, aAttrType);
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&aAttrType, sizeof(aAttrType));
+    }
+    return err;
+}
+
+/**
+ * Ends the list (DEA/DES), and update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::attributeListEnd(int aAttrId)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::attributeListEndFs,
+               aAttrId, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::attributeListEndFs(int aAttrId, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::attributeListEnd %d", aAttrId);
+    int err = 0;
+
+    if (mLastSdpAttr)
+        TRAP(err, mLastSdpAttr = mLastSdpAttr -> EndListL());
+    if (KErrNone == err && aAttrId >= 0)
+    {
+        LOG1(EJavaBluetooth, EInfo,  "*  ServiceRecord::attributeListEnd %d", aAttrId);
+        TRAP(err, mSdpDB.UpdateAttributeL(mRecord, aAttrId, *mSdpAttrValueList));
+        LOG1(EJavaBluetooth, EInfo,  "x  ServiceRecord::attributeListEnd %d", aAttrId);
+        delete mSdpAttrValueList;
+        mSdpAttrValueList = NULL;
+        mLastSdpAttr = NULL;
+    }
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        int type = DataElement_EndList;
+        LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord Writing %d, %d",
+             aAttrId, type);
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&type, sizeof(type));
+    }
+    return err;
+}
+
+/**
+ * Adds unsigned integer to the list (DEA/DES),
+ * or update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::setAttributeUint(int aAttrId, int aAttrType, TDesC8 &aNumVal)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::setAttributeUintFs,
+               aAttrId, aAttrType, aNumVal, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::setAttributeUintFs(int aAttrId, int aAttrType, TDesC8 &aNumVal, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::setAttributeUint %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId < 0)
+        {
+            if (mLastSdpAttr)
+                mLastSdpAttr = mLastSdpAttr -> BuildUintL(aNumVal);
+        }
+        else
+        {
+            CSdpAttrValueUint *val = NULL;
+            val = CSdpAttrValueUint::NewUintL(aNumVal);
+            mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val);
+            delete val;
+        }
+    }
+         );
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        int size = aNumVal.Size();
+        const TUint8 *ptr = aNumVal.Ptr();
+
+        LOG4(EJavaBluetooth, EInfo,"  ServiceRecord Writing %d, %d, %d, [%S]",
+             aAttrId, aAttrType, size, ptr);
+
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&aAttrType, sizeof(aAttrType));
+        write(mSrvRecFd, (char *)&size, sizeof(size));
+        write(mSrvRecFd, (char *)ptr, size);
+    }
+    return err;
+}
+
+/**
+ * Adds integer to the list (DEA/DES),
+ * or update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::setAttributeInt(int aAttrId, int aAttrType, TDesC8 &aNumVal)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::setAttributeIntFs,
+               aAttrId, aAttrType, aNumVal, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::setAttributeIntFs(int aAttrId, int aAttrType, TDesC8 &aNumVal, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::setAttributeInt %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId < 0)
+        {
+            if (mLastSdpAttr)
+                mLastSdpAttr = mLastSdpAttr -> BuildIntL(aNumVal);
+        }
+        else
+        {
+            CSdpAttrValueInt *val = NULL;
+            val = CSdpAttrValueInt::NewIntL(aNumVal);
+            mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val);
+            delete val;
+        }
+    }
+         );
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        int size = aNumVal.Size();
+        const TUint8 *ptr = aNumVal.Ptr();
+
+        LOG4(EJavaBluetooth, EInfo,"  ServiceRecord Writing %d, %d, %d, [%S]",
+             aAttrId, aAttrType, size, ptr);
+
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&aAttrType, sizeof(aAttrType));
+        write(mSrvRecFd, (char *)&size, sizeof(size));
+        write(mSrvRecFd, (char *)ptr, size);
+    }
+    return err;
+}
+
+/**
+ * Adds boolean value to the list (DEA/DES),
+ * or update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::setAttributeBool(int aAttrId, TBool aBoolVal)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::setAttributeBoolFs,
+               aAttrId, aBoolVal, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::setAttributeBoolFs(int aAttrId, TBool aBoolVal, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::setAttributeBool %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId < 0)
+        {
+            if (mLastSdpAttr)
+                mLastSdpAttr = mLastSdpAttr -> BuildBooleanL(aBoolVal);
+        }
+        else
+        {
+            CSdpAttrValueBoolean  *val = NULL;
+            val =  CSdpAttrValueBoolean::NewBoolL(aBoolVal);
+            mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val);
+            delete val;
+        }
+    }
+         );
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        // Taking largest type for storage
+        int type = DataElement_BOOL;
+        TUint8 val = (aBoolVal) ? 1 : 0;
+
+        LOG3(EJavaBluetooth, EInfo,"  ServiceRecord Writing %d, %d, %d",
+             aAttrId, type, val);
+
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&type, sizeof(type));
+        write(mSrvRecFd, (char *)&val, 1);
+    }
+    return err;
+}
+
+/**
+ * Adds UUID to the list (DEA/DES),
+ * or update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::setAttributeUUID(int aAttrId, TUUID &aUUIDVal)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::setAttributeUUIDFs,
+               aAttrId, aUUIDVal, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::setAttributeUUIDFs(int aAttrId, TUUID &aUUIDVal, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::setAttributeUUID %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId < 0)
+        {
+            if (mLastSdpAttr)
+                mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(aUUIDVal);
+        }
+        else
+        {
+            CSdpAttrValueUUID  *val = NULL;
+            val = CSdpAttrValueUUID::NewUUIDL(aUUIDVal);
+            mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val);
+            delete val;
+        }
+    }
+         );
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        int type = DataElement_UUID;
+        int size = aUUIDVal.Des().Size();
+        const TUint8 *ptr = aUUIDVal.Des().Ptr();
+
+        LOG4(EJavaBluetooth, EInfo,"  ServiceRecord Writing %d, %d, %d, [%S]",
+             aAttrId, type, size, ptr);
+
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&type, sizeof(type));
+        write(mSrvRecFd, (char *)&size, sizeof(size));
+        write(mSrvRecFd, (char *)ptr, size);
+    }
+    return err;
+}
+
+/**
+ * Adds string to the list (DEA/DES),
+ * or update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::setAttributeString(int aAttrId, TDesC8 &aStrVal)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::setAttributeStringFs,
+               aAttrId, aStrVal, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::setAttributeStringFs(int aAttrId, TDesC8 &aStrVal, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,
+         "+ ServiceRecord::setAttributeString %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId < 0)
+        {
+            if (mLastSdpAttr)
+                mLastSdpAttr = mLastSdpAttr -> BuildStringL(aStrVal);
+        }
+        else
+        {
+            CSdpAttrValueString   *val = NULL;
+            val = CSdpAttrValueString::NewStringL(aStrVal);
+            mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val);
+            delete val;
+        }
+    }
+         );
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        int type = DataElement_STRING;
+        int size = aStrVal.Size();
+        const TUint8 *ptr = aStrVal.Ptr();
+
+        LOG3(EJavaBluetooth, EInfo,"  ServiceRecord Writing %d, %d, %d",
+             aAttrId, type, size);
+
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&type, sizeof(type));
+        write(mSrvRecFd, (char *)&size, sizeof(size));
+        write(mSrvRecFd, (char *)ptr, size);
+    }
+    return err;
+}
+
+/**
+ * Adds URL to the list (DEA/DES),
+ * or update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::setAttributeUrl(int aAttrId, TDesC8 &aUrlVal)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::setAttributeUrlFs,
+               aAttrId, aUrlVal, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::setAttributeUrlFs(int aAttrId, TDesC8 &aUrlVal, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::setAttributeUrl %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId < 0)
+        {
+            if (mLastSdpAttr)
+                mLastSdpAttr = mLastSdpAttr -> BuildURLL(aUrlVal);
+        }
+        else
+        {
+            CSdpAttrValueURL *val = NULL;
+            val = CSdpAttrValueURL::NewURLL(aUrlVal);
+            mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val);
+            delete val;
+        }
+    }
+         );
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        int type = DataElement_URL;
+        int size = aUrlVal.Size();
+        const TUint8 *ptr = aUrlVal.Ptr();
+
+        LOG4(EJavaBluetooth, EInfo,"  ServiceRecord Writing %d, %d, %d, [%S]",
+             aAttrId, type, size, ptr);
+
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&type, sizeof(type));
+        write(mSrvRecFd, (char *)&size, sizeof(size));
+        write(mSrvRecFd, (char *)ptr, size);
+    }
+    return err;
+}
+
+/**
+ * Adds NIL to the list (DEA/DES),
+ * or update the attribute list of SDP database
+ * On success returns 0; otherwise err number.
+ */
+OS_EXPORT int ServiceRecord::setAttributeNil(int aAttrId)
+{
+    JELOG2(EJavaBluetooth);
+    int ret = 0;
+    TBool persistentReq = ETrue;
+
+    CallMethod(ret, this, &ServiceRecord::setAttributeNilFs,
+               aAttrId, persistentReq, mFunctionServer);
+    return ret;
+}
+
+int ServiceRecord::setAttributeNilFs(int aAttrId, TBool isPersistenceRequired)
+{
+    JELOG2(EJavaBluetooth);
+    LOG1(EJavaBluetooth, EInfo,  "+ ServiceRecord::setAttributeNil %d", aAttrId);
+
+    TRAPD(err,
+    {
+        if (aAttrId < 0)
+        {
+            if (mLastSdpAttr)
+                mLastSdpAttr = mLastSdpAttr -> BuildNilL();
+        }
+        else
+        {
+            CSdpAttrValueNil *val = NULL;
+            val = CSdpAttrValueNil::NewNilL();
+            mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val);
+            delete val;
+        }
+    }
+         );
+
+    // Writing into persistent file for further usage
+    if (0 != mSrvRecFd && isPersistenceRequired)
+    {
+        // Taking largest type for storage
+        int type = DataElement_NULL;
+
+        LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord Writing %d, %d",
+             aAttrId, type);
+
+        write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId));
+        write(mSrvRecFd, (char *)&type, sizeof(type));
+    }
+    return err;
+}
+
+/*
+ * This function is used to restore the Java Service Record by reading the
+ * persistent file. This function will work only once after midlet took
+ * the server connection handle from the Push framework.
+ * This function tries to populate Java Service record only when there is a
+ * successful retrieval of persistent storage exists.
+ */
+
+OS_EXPORT void ServiceRecord::restoreJavaServiceRecordL(
+    JNIEnv *aJni, jobject aServiceRecordImpl)
+{
+    JELOG2(EJavaBluetooth);
+
+    if (false == mInitializedByPush)
+    {
+        // No need of restoring anything since it is not a push service
+        return;
+    }
+
+    // Setting service record handle.
+    BTServiceRecordPopulator* srvRecPopulator =
+        BTServiceRecordPopulator::New(aJni, aServiceRecordImpl);
+
+    srvRecPopulator->SetServiceRecordHandle(mRecord);
+
+    if (false == mRestoredFromPersistentFile)
+    {
+        // No need of restoring anything from persistent file.
+        delete srvRecPopulator;
+        return;
+    }
+
+    std::wstring persistentFileName = getPersistentFileName();
+
+    int persistentRecFd = -1;
+    int ret = 0;
+
+    if (persistentFileName.length()> 0)
+    {
+        try
+        {
+            char *fileName =
+                java::util::JavaCommonUtils::wstringToUtf8(persistentFileName);
+            persistentRecFd = open(fileName, O_RDONLY);
+            delete fileName;
+        }
+        catch (ExceptionBase ex)
+        {
+            ELOG1(EJavaBluetooth,
+                  "- ServiceRecord::restoreJavaServiceRecord exception caught: %S",
+                  ex.toString().c_str());
+        }
+    }
+
+    if (persistentRecFd < 0)
+    {
+        // Nothing else to be done, as persistent file can not be opened or
+        // it is empty.
+        delete srvRecPopulator;
+        return;
+    }
+
+    MSdpElementBuilder* elementBuilder = (MSdpElementBuilder*) srvRecPopulator;
+
+    // Reading and restoring the DeviceServiceClasses bits (If any)
+    unsigned int devServClass = 0;
+    ret = read(persistentRecFd, &devServClass, sizeof(devServClass));
+    if (ret <= 0)
+        return;
+
+    elementBuilder = srvRecPopulator->SetDeviceServiceClass(devServClass);
+
+
+    // Calling first BuildDESL, is mandatory
+    elementBuilder = elementBuilder->BuildDESL();
+    elementBuilder = elementBuilder->StartListL();
+
+    int attrId = 0;
+    while ((ret = read(persistentRecFd, &attrId, sizeof(attrId))) > 0)
+    {
+        int dataType = 0;
+
+        ret = read(persistentRecFd, &dataType, sizeof(dataType));
+        if (ret <= 0)
+            break;
+
+        if (attrId > 0 && DataElement_EndList != dataType)
+        {
+            TSdpIntBuf<TUint> attrIdBuf(attrId);
+            elementBuilder = elementBuilder->BuildUintL(attrIdBuf);
+        }
+
+        LOG2(EJavaBluetooth, EInfo,
+             "  ServiceRecord reading %X, %X", attrId, dataType);
+
+        switch (dataType)
+        {
+        case DataElement_DATSEQ:
+        {
+            elementBuilder = elementBuilder->BuildDESL();
+            elementBuilder = elementBuilder->StartListL();
+            break;
+        }
+        case DataElement_DATALT:
+        {
+            elementBuilder = elementBuilder->BuildDEAL();
+            elementBuilder = elementBuilder->StartListL();
+            break;
+        }
+        case DataElement_EndList:
+        {
+            elementBuilder = elementBuilder->EndListL();
+            break;
+        }
+        case DataElement_NULL:
+        {
+            elementBuilder = elementBuilder->BuildNilL();
+            break;
+        }
+        case DataElement_BOOL:
+        {
+            TUint8 val = 0;
+            ret = read(persistentRecFd, &val, sizeof(val));
+            if (ret <= 0)
+                break;
+
+            LOG1(EJavaBluetooth, EInfo,
+                 "  ServiceRecord reading Bool %X", val);
+            elementBuilder =
+                elementBuilder->BuildBooleanL((val) ? ETrue : EFalse);
+            break;
+        }
+        case DataElement_U_INT_1:
+        case DataElement_U_INT_2:
+        case DataElement_U_INT_4:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 bytes[20] = {0};
+            ret = read(persistentRecFd, bytes, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord reading INT 0x%X, 0x%X", len, bytes);
+
+            std::auto_ptr<HBufC8> buf(convertIntToDesC(bytes, dataType));
+            elementBuilder = elementBuilder->BuildUintL(*buf);
+            break;
+        }
+        case DataElement_U_INT_8:
+        case DataElement_U_INT_16:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[20] = {0};
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord reading INT 0x%X, %S", len, buf);
+
+            TPtrC8 val(buf, len);
+            elementBuilder = elementBuilder->BuildUintL(val);
+            break;
+        }
+        case DataElement_INT_1:
+        case DataElement_INT_2:
+        case DataElement_INT_4:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 bytes[20] = {0};
+            ret = read(persistentRecFd, bytes, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord reading INT 0x%X, %S", len, bytes);
+
+            std::auto_ptr<HBufC8> buf(convertIntToDesC(bytes, dataType));
+            elementBuilder = elementBuilder->BuildIntL(*buf);
+            break;
+        }
+        case DataElement_INT_8:
+        case DataElement_INT_16:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[20] = {0};
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord reading INT %X, %S", len, buf);
+
+            TPtrC8 val(buf, len);
+            elementBuilder = elementBuilder->BuildIntL(val);
+            break;
+        }
+        case DataElement_UUID:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[256] = {0};
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo,  "  ServiceRecord reading UUID %X, %S", len, buf);
+
+            TPtrC8 uuidDes(buf, len);
+
+            TUUID val;
+            val.SetL(uuidDes);
+
+            elementBuilder = elementBuilder->BuildUUIDL(val);
+            break;
+        }
+        case DataElement_STRING:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[1024] = {0};
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG1(EJavaBluetooth, EInfo,
+                 "  ServiceRecord reading STRING %X", len);
+
+            TPtrC8 val(buf, len);
+            LOG(EJavaBluetooth, EInfo,
+                "  ServiceRecord::RestoreJavaServiceRecord BuildStringL");
+            elementBuilder = elementBuilder->BuildStringL(val);
+            break;
+        }
+        case DataElement_URL:
+        {
+            int len = 0;
+            ret = read(persistentRecFd, &len, sizeof(len));
+            if (ret <= 0)
+                break;
+
+            TUint8 buf[1024] = {0};
+            ret = read(persistentRecFd, buf, len);
+            if (ret <= 0)
+                break;
+
+            LOG2(EJavaBluetooth, EInfo,
+                 "  ServiceRecord reading URL %X, %S", len, buf);
+
+            TPtrC8 val(buf, len);
+            elementBuilder = elementBuilder->BuildURLL(val);
+            break;
+        }
+        default:
+            break;
+        }
+        if (0 == ret)
+            break;
+    }
+
+    delete srvRecPopulator;
+
+    return;
+}
+
+// Helper function
+HBufC8* ServiceRecord::convertIntToDesC(TUint8 *aBytes, int aDataType)
+{
+    JELOG2(EJavaBluetooth);
+    HBufC8* descBytes = NULL;
+    switch (aDataType)
+    {
+    case DataElement_INT_1:
+    case DataElement_U_INT_1:
+    {
+        descBytes = HBufC8::New(sizeof(TUint8) + 1);
+        TPtr8 ptr = descBytes->Des();
+        TUint value = *(TUint *)aBytes;
+        value=ByteOrder::Swap32(value);
+
+        TSdpIntBuf<TUint8> buf(value);
+        ptr.Copy(buf);
+        break;
+    }
+    case DataElement_INT_2:
+    case DataElement_U_INT_2:
+    {
+        descBytes = HBufC8::New(sizeof(TUint16) + 1);
+        TPtr8 ptr = descBytes->Des();
+        TUint value = *(TUint *)aBytes;
+        value=ByteOrder::Swap32(value);
+
+        TSdpIntBuf<TUint16> buf(value);
+        ptr.Copy(buf);
+        break;
+    }
+    case DataElement_INT_4:
+    case DataElement_U_INT_4:
+    {
+        descBytes = HBufC8::New(sizeof(TUint32) + 1);
+        TPtr8 ptr = descBytes->Des();
+        TUint value = *(TUint *)aBytes;
+        value=ByteOrder::Swap32(value);
+
+        TSdpIntBuf<TUint32> buf(value);
+        ptr.Copy(buf);
+        break;
+    }
+    default:
+    {
+        descBytes = HBufC8::New(sizeof(TUint64) + 1);
+        TPtr8 ptr = descBytes->Des();
+
+        TSdpIntBuf<TUint64> buf(*(TUint64 *)aBytes);
+        ptr.Copy(buf);
+        break;
+    }
+    }
+
+    return descBytes;
+}
+
+TUint8 *ServiceRecord::uuidToByteArray(std::wstring aUuid,
+                                       int &aUuidByteLength)
+{
+    JELOG2(EJavaBluetooth);
+
+    int len = aUuid.length();
+    int resultLen = (len/2) + 1;
+    TUint8 *result = new TUint8[resultLen];
+    int index = 0;
+    int byteIndex = 0;
+
+    LOG1(EJavaBluetooth, EInfo, "  ServiceRecord::uuidToByteArray Length:%d", len);
+
+    if ((len % 2) != 0)
+    {
+        int charPos = charToInt(aUuid[index]);
+        index += 1;
+        result[byteIndex ++] = charPos;
+    }
+
+    while (index < len)
+    {
+        result[byteIndex ++] = (charToInt(aUuid[index]) << 4) |
+                               charToInt(aUuid[index + 1]);
+        index += 2;
+    }
+    aUuidByteLength = (len /2) + (len %2);
+
+    return result;
+}
+
+TInt8 ServiceRecord::charToInt(wchar_t ch)
+{
+    std::wstring validUpperChars(L"0123456789ABCDEF"); // Never change this.
+    std::wstring validLowerChars(L"0123456789abcdef"); // Never change this.
+    TInt8 result = -1;
+    if ((result = validUpperChars.find(ch)) == std::wstring::npos)
+    {
+        result = validLowerChars.find(ch);
+    }
+    return result;
+}
+
+std::wstring ServiceRecord::uuidToWstring(TUUID aUuid)
+{
+    JELOG2(EJavaBluetooth);
+
+    std::wstring validChars(L"0123456789ABCDEF"); // Never change this.
+    std::wstring result;
+
+    int len = aUuid.Des().Size();
+    const TUint8 *ptr = aUuid.Des().Ptr();
+
+    for (int i = 0; i < len; i ++, ptr ++)
+    {
+        result += validChars[((*ptr) >> 4)];
+        result += validChars[((*ptr) & 0x0F)];
+        LOG1(EJavaBluetooth, EInfo,
+             "  ServiceRecord::uuidToWstring %S",  result.c_str());
+    }
+
+    return result;
+}
+
+}  //end namespace bluetooth
+}  //end namespace java