/*
 * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "IntelMetadataBuffer"
#include <utils/Log.h>

#include "IntelMetadataBuffer.h"
#include <string.h>
#include <stdio.h>

#ifdef INTEL_VIDEO_XPROC_SHARING
#include <binder/IServiceManager.h>
#include <binder/MemoryBase.h>
#include <binder/Parcel.h>
#include <utils/List.h>
#include <utils/threads.h>
#include <ui/GraphicBuffer.h>

//#define TEST

struct ShareMemMap {
    uint32_t sessionflag;
    intptr_t value;
    intptr_t value_backup;
    uint32_t type;
    sp<MemoryBase> membase;
    sp<GraphicBuffer> gbuffer;
};

List <ShareMemMap *> gShareMemMapList;
Mutex gShareMemMapListLock;

enum {
    SHARE_MEM = IBinder::FIRST_CALL_TRANSACTION,
    GET_MEM,
    CLEAR_MEM,
};

enum {
    ST_MEMBASE = 0,
    ST_GFX,
    ST_MAX,
};

#define REMOTE_PROVIDER 0x80000000
#define REMOTE_CONSUMER 0x40000000

static ShareMemMap* ReadMemObjFromBinder(const Parcel& data, uint32_t sessionflag, intptr_t value) {

    uint32_t type = data.readInt32();
    if (type >= ST_MAX)
        return NULL;

    ShareMemMap* map = new ShareMemMap;
    map->sessionflag = sessionflag;
    map->type = type;
    map->value_backup = value;
    map->membase = NULL;
    map->gbuffer= NULL;

//    LOGI("ReadMemObjFromBinder");

    if (type == ST_MEMBASE) /*offset, size, heap*/
    {
        ssize_t offset = data.readInt32();
        size_t size = data.readInt32();

        sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());

        sp<MemoryBase> mem = new MemoryBase(heap, offset, size);
        if (mem == NULL)
        {
            delete map;
            return NULL;
        }

        map->value = (intptr_t)( mem->pointer() + 0x0FFF) & ~0x0FFF;
        map->membase = mem;

#ifdef TEST
        ALOGI("membase heapID:%d, pointer:%x data:%x, aligned value:%x", \
           heap->getHeapID(), mem->pointer(), *((intptr_t *)(mem->pointer())), map->value);
#endif

    }
    else if (type == ST_GFX) /*graphicbuffer*/
    {
        sp<GraphicBuffer> buffer = new GraphicBuffer();
        if (buffer == NULL)
        {
            delete map;
            return NULL;
        }
        data.read(*buffer);

        map->value = (intptr_t)buffer->handle;
        map->gbuffer = buffer;

#ifdef TEST
        void* usrptr[3];
        buffer->lock(GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN, &usrptr[0]);
        buffer->unlock();
        ALOGI("gfx handle:%p data:%x", (intptr_t)buffer->handle, *((intptr_t *)usrptr[0]));
#endif
    }

    gShareMemMapListLock.lock();
    gShareMemMapList.push_back(map);
    gShareMemMapListLock.unlock();
    return map;
}

static status_t WriteMemObjToBinder(Parcel& data, ShareMemMap* smem) {

    if (smem->type >= ST_MAX)
        return BAD_VALUE;

//    LOGI("WriteMemObjToBinder");

    data.writeInt32(smem->type);

    if (smem->type == ST_MEMBASE) /*offset, size, heap*/
    {
        ssize_t offset;
        size_t size;
        sp<IMemoryHeap> heap = smem->membase->getMemory(&offset, &size);
        data.writeInt32(offset);
        data.writeInt32(size);
        data.writeStrongBinder(heap->asBinder());
#ifdef TEST
        ALOGI("membase heapID:%d pointer:%x data:%x", \
            heap->getHeapID(), smem->membase->pointer(), *((int *)(smem->membase->pointer())));
#endif
    }
    else if (smem->type == ST_GFX) /*graphicbuffer*/
        data.write(*(smem->gbuffer));

    return NO_ERROR;
}

static void ClearLocalMem(uint32_t sessionflag)
{
    List<ShareMemMap *>::iterator node;

    gShareMemMapListLock.lock();

    for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); )
    {
        if ((*node)->sessionflag == sessionflag) //remove all buffers belong to this session
        {
            (*node)->membase = NULL;
            (*node)->gbuffer = NULL;
            delete (*node);
            node = gShareMemMapList.erase(node);
        }
        else
            node ++;
    }

    gShareMemMapListLock.unlock();
}

static ShareMemMap* FindShareMem(uint32_t sessionflag, intptr_t value, bool isBackup)
{
    List<ShareMemMap *>::iterator node;

    gShareMemMapListLock.lock();
    for(node = gShareMemMapList.begin(); node !=  gShareMemMapList.end(); node++)
    {
        if (isBackup)
        {
            if ((*node)->sessionflag == sessionflag && (*node)->value_backup == value)
            {
                gShareMemMapListLock.unlock();
                return (*node);
            }
        }
        else if ((*node)->sessionflag == sessionflag && (*node)->value == value)
        {
            gShareMemMapListLock.unlock();
            return (*node);
        }
    }
    gShareMemMapListLock.unlock();

    return NULL;
}

static ShareMemMap* PopShareMem(uint32_t sessionflag, intptr_t value)
{
    List<ShareMemMap *>::iterator node;

    gShareMemMapListLock.lock();
    for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); node++)
    {
        if ((*node)->sessionflag == sessionflag && (*node)->value == value)
        {
            gShareMemMapList.erase(node);
            gShareMemMapListLock.unlock();
            return (*node);
        }
    }
    gShareMemMapListLock.unlock();

    return NULL;
}

static void PushShareMem(ShareMemMap* &smem)
{
    gShareMemMapListLock.lock();
    gShareMemMapList.push_back(smem);
    gShareMemMapListLock.unlock();
}

static sp<IBinder> GetIntelBufferSharingService() {

    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder = sm->checkService(String16("media.IntelBufferSharing"));

    if (binder == 0)
        LOGE("media.IntelBufferSharing service is not published");

    return binder;
}

IntelBufferSharingService* IntelBufferSharingService::gBufferService = NULL;

status_t IntelBufferSharingService::instantiate(){
    status_t ret = NO_ERROR;

    if (gBufferService == NULL) {
        gBufferService = new IntelBufferSharingService();
        ret = defaultServiceManager()->addService(String16("media.IntelBufferSharing"), gBufferService);
        LOGI("IntelBufferSharingService::instantiate() ret = %d\n", ret);
    }

    return ret;
}

status_t IntelBufferSharingService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {

    //TODO: if pid is int32?
    pid_t pid = data.readInt32();
    uint32_t sessionflag = data.readInt32();

    switch(code)
    {
        case SHARE_MEM:
        {

            if (pid == getpid()) //in same process, should not use binder
            {
                LOGE("onTransact in same process, wrong sessionflag?");
                return UNKNOWN_ERROR;
            }

            intptr_t value = data.readIntPtr();

//            LOGI("onTransact SHARE_MEM value=%x", value);

            //different process
            ShareMemMap* map = ReadMemObjFromBinder(data, sessionflag, value);
            if (map == NULL)
                return UNKNOWN_ERROR;

            reply->writeIntPtr(map->value);

            return NO_ERROR;
        }
        case CLEAR_MEM:
        {
//            LOGI("onTransact CLEAR_MEM sessionflag=%x", sessionflag);

            if (pid == getpid()) //in same process, should not use binder
            {
                //same process, return same pointer in data
                LOGE("onTransact CLEAR_MEM in same process, wrong sessionflag?");
                return UNKNOWN_ERROR;
            }

            ClearLocalMem(sessionflag);
            return NO_ERROR;
        }
        case GET_MEM:
        {

            if (pid == getpid()) //in same process, should not use binder
            {
                LOGE("onTransact GET_MEM in same process, wrong sessionflag?");
                return UNKNOWN_ERROR;
            }

            intptr_t value = data.readIntPtr();

//            LOGI("onTransact GET_MEM value=%x", value);

            ShareMemMap* smem = FindShareMem(sessionflag, value, false);
            if (smem && (NO_ERROR == WriteMemObjToBinder(*reply, smem)))
                return NO_ERROR;
            else
                LOGE("onTransact GET_MEM: Not find mem");

            return UNKNOWN_ERROR;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);

    }
    return NO_ERROR;
}
#endif

IntelMetadataBuffer::IntelMetadataBuffer()
{
    mType = IntelMetadataBufferTypeCameraSource;
    mValue = 0;
    mInfo = NULL;
    mExtraValues = NULL;
    mExtraValues_Count = 0;
    mBytes = NULL;
    mSize = 0;
#ifdef INTEL_VIDEO_XPROC_SHARING
    mSessionFlag = 0;
#endif
}

IntelMetadataBuffer::IntelMetadataBuffer(IntelMetadataBufferType type, intptr_t value)
{
    mType = type;
    mValue = value;
    mInfo = NULL;
    mExtraValues = NULL;
    mExtraValues_Count = 0;
    mBytes = NULL;
    mSize = 0;
#ifdef INTEL_VIDEO_XPROC_SHARING
    mSessionFlag = 0;
#endif
}

IntelMetadataBuffer::~IntelMetadataBuffer()
{
    if (mInfo)
        delete mInfo;

    if (mExtraValues)
        delete[] mExtraValues;

    if (mBytes)
        delete[] mBytes;
}


IntelMetadataBuffer::IntelMetadataBuffer(const IntelMetadataBuffer& imb)
     :mType(imb.mType), mValue(imb.mValue), mInfo(NULL), mExtraValues(NULL),
      mExtraValues_Count(imb.mExtraValues_Count), mBytes(NULL), mSize(imb.mSize)
#ifdef INTEL_VIDEO_XPROC_SHARING
      ,mSessionFlag(imb.mSessionFlag)
#endif
{
    if (imb.mInfo)
        mInfo = new ValueInfo(*imb.mInfo);

    if (imb.mExtraValues)
    {
        mExtraValues = new intptr_t[mExtraValues_Count];
        memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count);
    }

    if (imb.mBytes)
    {
        mBytes = new uint8_t[mSize];
        memcpy(mBytes, imb.mBytes, mSize);
    }
}

const IntelMetadataBuffer& IntelMetadataBuffer::operator=(const IntelMetadataBuffer& imb)
{
    mType = imb.mType;
    mValue = imb.mValue;
    mInfo = NULL;
    mExtraValues = NULL;
    mExtraValues_Count = imb.mExtraValues_Count;
    mBytes = NULL;
    mSize = imb.mSize;
#ifdef INTEL_VIDEO_XPROC_SHARING
    mSessionFlag = imb.mSessionFlag;
#endif

    if (imb.mInfo)
        mInfo = new ValueInfo(*imb.mInfo);

    if (imb.mExtraValues)
    {
        mExtraValues = new intptr_t[mExtraValues_Count];
        memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count);
    }

    if (imb.mBytes)
    {
        mBytes = new uint8_t[mSize];
        memcpy(mBytes, imb.mBytes, mSize);
    }

    return *this;
}

IMB_Result IntelMetadataBuffer::GetType(IntelMetadataBufferType& type)
{
    type = mType;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetType(IntelMetadataBufferType type)
{
    if (type < IntelMetadataBufferTypeLast)
        mType = type;
    else
        return IMB_INVAL_PARAM;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::GetValue(intptr_t& value)
{
    value = mValue;

#ifndef INTEL_VIDEO_XPROC_SHARING
    return IMB_SUCCESS;
#else
    if ((mSessionFlag & REMOTE_CONSUMER) == 0) //no sharing or is local consumer
        return IMB_SUCCESS;

    //try to find if it is already cached.
    ShareMemMap* smem = FindShareMem(mSessionFlag, mValue, true);
    if(smem)
    {
        value = smem->value;
        return IMB_SUCCESS;
    }

    //is remote provider and not find from cache, then pull from service
    sp<IBinder> binder = GetIntelBufferSharingService();
    if (binder == 0)
        return IMB_NO_SERVICE;

    //Detect IntelBufferSharingService, share mem to service
    Parcel data, reply;

    //send pid, sessionflag, and memtype
    pid_t pid = getpid();
    //TODO: if pid is int32?
    data.writeInt32(pid);
    data.writeInt32(mSessionFlag);
    data.writeIntPtr(mValue);

    //do transcation
    if (binder->transact(GET_MEM, data, &reply) != NO_ERROR)
        return IMB_SERVICE_FAIL;

    //get type/Mem OBJ
    smem = ReadMemObjFromBinder(reply, mSessionFlag, mValue);
    if (smem)
        value = smem->value;
    else
        return IMB_SERVICE_FAIL;

    return IMB_SUCCESS;
#endif
}

IMB_Result IntelMetadataBuffer::SetValue(intptr_t value)
{
    mValue = value;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::GetValueInfo(ValueInfo* &info)
{
    info = mInfo;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetValueInfo(ValueInfo* info)
{
    if (info)
    {
        if (mInfo == NULL)
            mInfo = new ValueInfo;

        memcpy(mInfo, info, sizeof(ValueInfo));
    }
    else
        return IMB_INVAL_PARAM;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::GetExtraValues(intptr_t* &values, uint32_t& num)
{
    values = mExtraValues;
    num = mExtraValues_Count;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetExtraValues(intptr_t* values, uint32_t num)
{
    if (values && num > 0)
    {
        if (mExtraValues && mExtraValues_Count != num)
        {
            delete[] mExtraValues;
            mExtraValues = NULL;
        }

        if (mExtraValues == NULL)
            mExtraValues = new intptr_t[num];

        memcpy(mExtraValues, values, sizeof(intptr_t) * num);
        mExtraValues_Count = num;
    }
    else
        return IMB_INVAL_PARAM;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::UnSerialize(uint8_t* data, uint32_t size)
{
    if (!data || size == 0)
        return IMB_INVAL_PARAM;

    IntelMetadataBufferType type;
    intptr_t value;
    uint32_t extrasize = size - sizeof(type) - sizeof(value);
    ValueInfo* info = NULL;
    intptr_t* ExtraValues = NULL;
    uint32_t ExtraValues_Count = 0;

    memcpy(&type, data, sizeof(type));
    data += sizeof(type);
    memcpy(&value, data, sizeof(value));
    data += sizeof(value);

    switch (type)
    {
        case IntelMetadataBufferTypeCameraSource:
        case IntelMetadataBufferTypeEncoder:
        case IntelMetadataBufferTypeUser:
        {
            if (extrasize >0 && extrasize < sizeof(ValueInfo))
                return IMB_INVAL_BUFFER;

            if (extrasize > sizeof(ValueInfo)) //has extravalues
            {
                if ( (extrasize - sizeof(ValueInfo)) % sizeof(mValue) != 0 )
                    return IMB_INVAL_BUFFER;
                ExtraValues_Count = (extrasize - sizeof(ValueInfo)) / sizeof(mValue);
            }

            if (extrasize > 0)
            {
                info = new ValueInfo;
                memcpy(info, data, sizeof(ValueInfo));
                data += sizeof(ValueInfo);
            }

            if (ExtraValues_Count > 0)
            {
                ExtraValues = new intptr_t[ExtraValues_Count];
                memcpy(ExtraValues, data, ExtraValues_Count * sizeof(mValue));
            }

            break;
        }
        case IntelMetadataBufferTypeGrallocSource:
            if (extrasize > 0)
                return IMB_INVAL_BUFFER;

            break;
        default:
            return IMB_INVAL_BUFFER;
    }

    //store data
    mType = type;
    mValue = value;
    if (mInfo)
        delete mInfo;
    mInfo = info;
    if (mExtraValues)
        delete[] mExtraValues;
    mExtraValues = ExtraValues;
    mExtraValues_Count = ExtraValues_Count;
#ifdef INTEL_VIDEO_XPROC_SHARING
    if (mInfo != NULL)
        mSessionFlag = mInfo->sessionFlag;
#endif
    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::Serialize(uint8_t* &data, uint32_t& size)
{
    if (mBytes == NULL)
    {
        if (mType == IntelMetadataBufferTypeGrallocSource && mInfo)
            return IMB_INVAL_PARAM;

        //assemble bytes according members
        mSize = sizeof(mType) + sizeof(mValue);
        if (mInfo)
        {
            mSize += sizeof(ValueInfo);
            if (mExtraValues)
                mSize += sizeof(mValue) * mExtraValues_Count;
        }

        mBytes = new uint8_t[mSize];
        uint8_t *ptr = mBytes;
        memcpy(ptr, &mType, sizeof(mType));
        ptr += sizeof(mType);
        memcpy(ptr, &mValue, sizeof(mValue));
        ptr += sizeof(mValue);

        if (mInfo)
        {
        #ifdef INTEL_VIDEO_XPROC_SHARING
            mInfo->sessionFlag = mSessionFlag;
        #endif
            memcpy(ptr, mInfo, sizeof(ValueInfo));
            ptr += sizeof(ValueInfo);

            if (mExtraValues)
                memcpy(ptr, mExtraValues, mExtraValues_Count * sizeof(mValue));
        }
    }

    data = mBytes;
    size = mSize;

    return IMB_SUCCESS;
}

uint32_t IntelMetadataBuffer::GetMaxBufferSize()
{
    return 256;
}

#ifdef INTEL_VIDEO_XPROC_SHARING
IMB_Result IntelMetadataBuffer::GetSessionFlag(uint32_t& sessionflag)
{
    sessionflag = mSessionFlag;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::SetSessionFlag(uint32_t sessionflag)
{
    mSessionFlag = sessionflag;

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::ShareValue(sp<MemoryBase> mem)
{
    mValue = (intptr_t)((intptr_t) ( mem->pointer() + 0x0FFF) & ~0x0FFF);

    if (mSessionFlag == 0) //no sharing
        return IMB_SUCCESS;

    if (mSessionFlag & REMOTE_PROVIDER) //is remote provider
    {
        sp<IBinder> binder = GetIntelBufferSharingService();
        if (binder == 0)
            return IMB_NO_SERVICE;

        //Detect IntelBufferSharingService, share mem to service
        Parcel data, reply;

        //send pid, sessionflag, and value
        pid_t pid = getpid();
        //TODO: if pid is int32?
        data.writeInt32(pid);
        data.writeInt32(mSessionFlag);
        data.writeIntPtr(mValue);

        //send type/obj (offset/size/MemHeap)
        ShareMemMap smem;
        smem.membase = mem;
        smem.type = ST_MEMBASE;
        if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //do transcation
        if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //set new value gotten from peer
        mValue = reply.readIntPtr();
//        LOGI("ShareValue(membase) Get reply from sevice, new value:%x\n", mValue);
    }
    else  //is local provider , direct access list
    {
        ShareMemMap* smem = new ShareMemMap;
        smem->sessionflag = mSessionFlag;
        smem->value = mValue;
        smem->value_backup = mValue;
        smem->type = ST_MEMBASE;
        smem->membase = mem;
        smem->gbuffer = NULL;
        PushShareMem(smem);
    }

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::ShareValue(sp<GraphicBuffer> gbuffer)
{
    mValue = (intptr_t)gbuffer->handle;

    if (mSessionFlag == 0) //no sharing
        return IMB_SUCCESS;

    if (mSessionFlag & REMOTE_PROVIDER == 0) //is remote provider
    {
        sp<IBinder> binder = GetIntelBufferSharingService();
        if (binder == 0)
            return IMB_NO_SERVICE;

        Parcel data, reply;

        //send pid, sessionflag, and memtype
        pid_t pid = getpid();
        //TODO: if pid is int32 ?
        data.writeInt32(pid);
        data.writeInt32(mSessionFlag);
        data.writeIntPtr(mValue);

        //send value/graphicbuffer obj
        ShareMemMap smem;
        smem.gbuffer = gbuffer;
        smem.type = ST_GFX;
        if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //do transcation
        if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
            return IMB_SERVICE_FAIL;

        //set new value gotten from peer
        mValue = reply.readIntPtr();
//        LOGI("ShareValue(gfx) Get reply from sevice, new value:%x\n", mValue);
    }
    else //is local provider, direct access list
    {
        ShareMemMap* smem = new ShareMemMap;
        smem->sessionflag = mSessionFlag;
        smem->value = mValue;
        smem->value_backup = mValue;
        smem->type = ST_GFX;
        smem->membase = NULL;
        smem->gbuffer = gbuffer;
        PushShareMem(smem);
    }

    return IMB_SUCCESS;
}

IMB_Result IntelMetadataBuffer::ClearContext(uint32_t sessionflag, bool isProvider)
{
    if (sessionflag == 0) //no sharing
        return IMB_SUCCESS;

    //clear local firstly
    ClearLocalMem(sessionflag);

    //clear mem on service if it is remote user
    if ((isProvider && (sessionflag & REMOTE_PROVIDER)) || (!isProvider && (sessionflag & REMOTE_CONSUMER)))
    {
//        LOGI("CLEAR_MEM sessionflag=%x", sessionflag);

        sp<IBinder> binder = GetIntelBufferSharingService();
        if (binder == 0)
            return IMB_NO_SERVICE;

        //Detect IntelBufferSharingService, unshare mem from service
        Parcel data, reply;

        //send pid and sessionflag
        pid_t pid = getpid();
        //TODO: if pid is int32?
        data.writeInt32(pid);
        data.writeInt32(sessionflag);

        if (binder->transact(CLEAR_MEM, data, &reply) != NO_ERROR)
            return IMB_SERVICE_FAIL;
    }

    return IMB_SUCCESS;
}

uint32_t IntelMetadataBuffer::MakeSessionFlag(bool romoteProvider, bool remoteConsumer, uint16_t sindex)
{
    uint32_t sessionflag = 0;

    if (romoteProvider)
        sessionflag |= REMOTE_PROVIDER;

    if (remoteConsumer)
        sessionflag |= REMOTE_CONSUMER;

    return sessionflag + sindex;
}
#endif
