/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */


#include "BeceemAdapter.h"
//#include "Common.h"

#include "Typedefs.h"

#include "DevInfo.h"
#include "DevDetail.h"
#include "DMAcc.h"
#include "WiMAX.h"
#include "WiMAXSupp.h"

// Beceem device
#include "OMADMUserApi.h"
#include "Messages.h"
#include "ErrorDefs.h"
#include "Common.h"
#include "BeceemWiMAXExport.h"

extern "C" NS_DM_Client::IDeviceAdapter* CreateDeviceAdapter(void* param)
{
	return new NS_DM_Client::BeceemAdapter();
}

namespace NS_DM_Client
{
	const String S_loggerName("DeviceAdapter");

	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::Release()
	{
		delete this;
	}
	//-------------------------------------------------------------------------------------------

	BeceemAdapter::BeceemAdapter(): m_logger(NS_Logging::GetLogger(S_loggerName.c_str())), m_deviceHandle(0)
	{

	}
	//-------------------------------------------------------------------------------------------

	BeceemAdapter::~BeceemAdapter()
	{
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::Init(const StringMap& settings, IDaemonEngineRequest* request/* = 0*/)
	{
// 		StringMap sett = settings;
// 		sett.remove(FirmwareUpdateResultParam);
// 		return DummyDeviceAdapter::Init(sett);
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::Open()
	{
		m_deviceHandle = OpenWiMAXDevice();
		if(INVALID_HANDLE_VALUE == m_deviceHandle)
		{
			LOG_ERROR_(m_logger, "Failed to open WiMAX device, return error = %d", m_deviceHandle);
			return false;
		}
		LOG_(m_logger, "Device opened successfully");
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::Close()
	{
		CloseWiMAXDevice();
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::sendMessage(PUCHAR buffer, int length)
	{
		int res = SendWiMAXMessage(m_deviceHandle, buffer, length);
		if(res != SUCCESS)
		{
			LOG_ERROR_(m_logger, "Failed to send message errCode = %d", res);
			return false;
		}
		LOG_(m_logger, "Message was sent");
		return true;
	}
	//-------------------------------------------------------------------------------------------

	int BeceemAdapter::packMessage(void* message, USHORT type, USHORT subType, USHORT msgLength)
	{
		if(!message)
			return -1;

		memset(message, 0, sizeof(WIMAX_MESSAGE));
		((PWIMAX_MESSAGE)message)->usType = type;
		((PWIMAX_MESSAGE)message)->usSubType = subType;
		return sizeof(WIMAX_MESSAGE) + msgLength - MAX_VARIABLE_LENGTH;
	}
	//-------------------------------------------------------------------------------------------

	int BeceemAdapter::getOMADMParameterSize(POMA_DM_TREE_LEVEL treeLevel, int level)
	{
		WIMAX_MESSAGE stRequestMessage = {0};
		int length = packMessage(&stRequestMessage, TYPE_OMADM, SUBTYPE_OMADM_GET_PARAM_SIZE_REQ, sizeof(OMADM_PARAMETER_INFO));

		POMADM_PARAMETER_INFO paramInfo = (POMADM_PARAMETER_INFO)stRequestMessage.szData;
		memcpy(&paramInfo->stTreeLevel, treeLevel, level * sizeof(OMA_DM_TREE_LEVEL));
		paramInfo->u32NumOfLevel = level;

		bool res = sendMessage((PUCHAR)&stRequestMessage, length);
		if(!res)
		{
			LOG_ERROR_(m_logger, "Failed to get parameter size: %d", res);
			return 0;
		}
		return paramInfo->u32OMADMObjSize;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::getOMADMRequest(int type, USHORT subType, WIMAX_MESSAGE& requestMessage, USHORT& length)
	{
		OMA_DM_TREE_LEVEL treeLevel[] = { {type, 0} };
		int level = sizeof(treeLevel) / sizeof(treeLevel[0]);
		int parameterSize = getOMADMParameterSize(treeLevel, level);

		if(parameterSize == 0)
			return false;

		length = packMessage(&requestMessage, TYPE_OMADM, subType, sizeof(OMADM_OBJECT_INFO));

		POMADM_OBJECT_INFO OMADMObject = NULL;
		OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
		OMADMObject->u32NumOfLevel = level;
		memcpy(&OMADMObject->stTreeLevel, &treeLevel, OMADMObject->u32NumOfLevel * sizeof(OMA_DM_TREE_LEVEL));
		OMADMObject->u32OMADMObjSize = parameterSize;
		memset(OMADMObject->au8OMADMObjVal, 0, OMADMObject->u32OMADMObjSize);
		length += parameterSize;
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::GetDeviceInfo(DevInfo& deviceInfo)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_DEV_INFO, SUBTYPE_OMADM_GET_REQ, requestMessage, length);
		res = sendMessage((PUCHAR)&requestMessage, length);

		if (res)
		{
			LOG_(m_logger, "Setting up deviceInfo structure from device");

			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_DevInfo* devInfo = (ST_DevInfo*)(OMADMObject->au8OMADMObjVal);
			copyToString(deviceInfo.m_DevId, devInfo->DevId, DEVICE_ID_LEAF_SIZE);
			copyToString(deviceInfo.m_DevId, devInfo->DevId, DEVICE_ID_LEAF_SIZE);
			copyToString(deviceInfo.m_Man, devInfo->Man, MANUFATURER_NAME_LEAF_SIZE);
			copyToString(deviceInfo.m_Mod, devInfo->Mod, MODEL_NUMBER_LEAF_SIZE);
			copyToString(deviceInfo.m_DmV, devInfo->DmV, OMA_DM_CLIENT_VERSION_LEAF_SIZE);
			copyToString(deviceInfo.m_Lang, devInfo->Lang, LANGUAGE_LEAF_SIZE);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	template <class T>
	void copyToVector(std::vector<T>& dest, T* source, size_t size)
	{
		if (source)
		{
			for (size_t i = 0; i != size; ++i)
			{
				dest.push_back(*source[i]);
			}
		}
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::GetDMAccount(DMAcc& dmAccount)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_DMACC, SUBTYPE_OMADM_GET_REQ, requestMessage, length);
		res = sendMessage((PUCHAR)&requestMessage, length);

		if (res)
		{
			LOG_(m_logger, "Setting up dmAcc structure from device");
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_DMAcc* dmAcc = (ST_DMAcc*)(OMADMObject->au8OMADMObjVal);
			DMAccImpl dmAccImpl;
			copyToString(dmAccImpl.m_AppID, dmAcc->AppID, DMACC_APPID_LEAF_SIZE);
			copyToString(dmAccImpl.m_ServerID, dmAcc->ServerID, DMACC_SERVERID_LEAF_SIZE);
			copyToString(dmAccImpl.m_Name, dmAcc->Name, DMACC_NAME_LEAF_SIZE);
			copyToString(dmAccImpl.m_PrefConRef, dmAcc->PrefConRef, DMACC_PREFCONREF_LEAF_SIZE);
			copyToString(dmAccImpl.m_AAuthPref, dmAcc->AAuthPref, DMACC_AUTHPREF_LEAF_SIZE);

			// ToConRef
			size_t size = sizeof(dmAcc->ToConRef) / sizeof(ST_ToConRef);
			for (size_t i = 0; i != size; ++i)
			{
				ST_ToConRef& curElement = dmAcc->ToConRef[i];
				String curValue;
				copyToString(curValue, curElement.ConRef, CONNECTION_REFERENCES_LEAF_SIZE);
				dmAccImpl.m_ToConRef.push_back(curValue);
			}

			// AppAddr
			size = sizeof(dmAcc->AppAddr) / sizeof(ST_AppAddr);
			for (size_t i = 0; i != size; ++i)
			{
				ST_AppAddr& curElement = dmAcc->AppAddr[i];
				AppAddr curAppAddr;
				copyToString(curAppAddr.m_Addr, curElement.Addr, APP_ADDRESS_LEAF_SIZE);
				copyToString(curAppAddr.m_AddrType, curElement.AddrType, APP_ADDRESS_TYPE_LEAF_SIZE);
				copyToString(curAppAddr.m_PortNbr, curElement.Port->PortNbr, PORT_NUMBER_LEAF_SIZE);
				dmAccImpl.m_AppAddr.push_back(curAppAddr);
			}

			// AppAuth
			size = sizeof(dmAcc->AppAuth) / sizeof(ST_AppAuth);
			for (size_t i = 0; i != size; ++i)
			{
				ST_AppAuth& curElement = dmAcc->AppAuth[i];
				AppAuth curAppAuth;
				copyToString(curAppAuth.m_AAuthLevel, curElement.AAuthLevel, APP_AUTHLEVEL_LEAF_SIZE);
				copyToString(curAppAuth.m_AAuthType, curElement.AAuthType, APP_AUTHTYPE_LEAF_SIZE);
				copyToString(curAppAuth.m_AAuthName, curElement.AAuthName, APP_AUTHNAME_LEAF_SIZE);
				copyToString(curAppAuth.m_AAuthSecret, curElement.AAuthSecret, APP_AUTHSECRET_LEAF_SIZE);
				copyToString(curAppAuth.m_AAuthData, curElement.AAuthData, APP_AUTHDATA_LEAF_SIZE);
				dmAccImpl.m_AppAuth.push_back(curAppAuth);
			}
			dmAccount.m_DMAccImpl.push_back(dmAccImpl);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::GetWiMAX(WiMAX& wimax)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_WIMAX, SUBTYPE_OMADM_GET_REQ, requestMessage, length);
		res = sendMessage((PUCHAR)&requestMessage, length);

		if (res)
		{
			LOG_(m_logger, "Setting up WiMAX structure from device");
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_WIMAX* stWimax = (ST_WIMAX*)(OMADMObject->au8OMADMObjVal);
			copyToString(wimax.m_TO_WiMAX_REF, stWimax->TO_WIMAX_REF, WIMAX_WIMAX_REF_LEAF_SIZE);

			// WIMAXRadioModule
			size_t size = sizeof(stWimax->WIMAXRadioModule) / sizeof(ST_WIMAXRadioModule);
			for (size_t i = 0; i != size; ++i)
			{
				ST_WIMAXRadioModule& curElement = stWimax->WIMAXRadioModule[i];
				WiMAXRadioModule curWiMAXRadioModule;
				copyToString(curWiMAXRadioModule.m_FwV, curElement.FwV, WIMAXRADIO_FWV_LEAF_SIZE);
				copyToString(curWiMAXRadioModule.m_HwV, curElement.HwV, WIMAXRADIO_HWV_LEAF_SIZE);
				copyToString(curWiMAXRadioModule.m_MACAddress, curElement.MACAddress, WIMAXRADIO_MACADDR_LEAF_SIZE);
				copyToString(curWiMAXRadioModule.m_Man, curElement.Man, WIMAXRADIO_MAN_LEAF_SIZE);
				copyToString(curWiMAXRadioModule.m_Mod, curElement.Mod, WIMAXRADIO_MOD_LEAF_SIZE);
				copyToString(curWiMAXRadioModule.m_SwV, curElement.SwV, WIMAXRADIO_SWV_LEAF_SIZE);
//				copyToString(curWiMAXRadioModule.m_SPLock.m_Lock, curElement.SPLock.Lock, SPLOCK_LOCK_LEAF_SIZE);
//				curWiMAXRadioModule.m_SPLock.m_LockStatus = curElement.SPLock.LockStatus;
//				curWiMAXRadioModule.m_SPLock.m_VerNbr = curElement.SPLock.VerNbr;
//				copyToString(curWiMAXRadioModule.m_SPLock.m_Operator, curElement.SPLock.Operator, SPLOCK_OPERATOR_LEAF_SIZE);
				copyToString(curWiMAXRadioModule.m_TO_FUMO_REF, curElement.TO_FUMO_REF, WIMAXRADIO_TO_FUMO_REF_LEAF_SIZE);
				wimax.m_WiMAXRadioModule.push_back(curWiMAXRadioModule);
			}

			// TerminalEquipment
			copyToString(wimax.m_TerminalEquipment.m_DevID, stWimax->TerminalEquipment.DevID, TERMINALEQUIPMENT_DEVID_LEAF_SIZE);
			copyToString(wimax.m_TerminalEquipment.m_DevType, stWimax->TerminalEquipment.DevType, TERMINALEQUIPMENT_DEVTYPE_LEAF_SIZE);
			copyToString(wimax.m_TerminalEquipment.m_FwV, stWimax->TerminalEquipment.FwV, TERMINALEQUIPMENT_FWV_LEAF_SIZE);
			copyToString(wimax.m_TerminalEquipment.m_HwV, stWimax->TerminalEquipment.HwV, TERMINALEQUIPMENT_HWV_LEAF_SIZE);
			copyToString(wimax.m_TerminalEquipment.m_Man, stWimax->TerminalEquipment.Man, TERMINALEQUIPMENT_MAN_LEAF_SIZE);
			copyToString(wimax.m_TerminalEquipment.m_Mod, stWimax->TerminalEquipment.Mod, TERMINALEQUIPMENT_MOD_LEAF_SIZE);
			copyToString(wimax.m_TerminalEquipment.m_SwV, stWimax->TerminalEquipment.SwV, TERMINALEQUIPMENT_SWV_LEAF_SIZE);

			// DevCap
			wimax.m_DevCap.m_IPCap.m_CMIPV4 = stWimax->DevCap.IPCap.CMIPV4;
			wimax.m_DevCap.m_IPCap.m_CMIPV6 = stWimax->DevCap.IPCap.CMIPV6;
			wimax.m_DevCap.m_IPCap.m_IPV4 = stWimax->DevCap.IPCap.IPV4;
			wimax.m_DevCap.m_IPCap.m_IPV6 = stWimax->DevCap.IPCap.IPV6;
			wimax.m_DevCap.m_UpdateMethods.m_ClientInitiated.m_PollingSupported = stWimax->DevCap.UpdateMethods.ClientInitiated.PollingSupported;
			wimax.m_DevCap.m_UpdateMethods.m_ClientInitiated.m_PollingInterval = stWimax->DevCap.UpdateMethods.ClientInitiated.PollingInterval;
		}

		return res;
	}
	//-------------------------------------------------------------------------------------------

// 	template <>
// 	void fillElement<String, >(Y& dest, const T& source)
//
// 	template <class T, class Y>
// 	void fillElement(Y& dest, const T& source)
// 	{
//
// 	}
// 	//-------------------------------------------------------------------------------------------
//
// 	template <class T, class Y>
// 	void copyArray(std::vector<Y>& dest, T* source)
// 	{
// 		size_t size = sizeof(source) / sizeof(T);
// 		for (size_t i = 0; i != size; ++i)
// 		{
// 			T& curElement = source[i];
// 			Y newElement;
// 			fillElement(newElement, curElement);
// 			dest.push_back(newElement);
// 		}
// 	}
// 	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_CALPEntries(std::vector<CAPLEntries>& dest, const ST_CAPLEntries* source, size_t size)
	{
		for (size_t j = 0; j != size; ++j)
		{
			const ST_CAPLEntries& curEntry = source[j];
			CAPLEntries newEntry;
			newEntry.m_Priority = curEntry.Priority;
			newEntry.m_NAP_ID = curEntry.NAP_ID;
			size_t chPlanRefIdsCount = sizeof(curEntry.ChPlanRefIds) / sizeof(ST_ChPlanRefIds);
			for (size_t k = 0; k != chPlanRefIdsCount; ++k)
			{
				String refId;
				copyToString(refId, curEntry.ChPlanRefIds[k].RefId, CHANNEL_REFID_LEAF_SIZE);
				newEntry.m_ChPlanRefIds.push_back(refId);
			}
			dest.push_back(newEntry);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_CALPEntries(ST_CAPLEntries* dest, const std::vector<CAPLEntries>& source)
	{
		for (size_t j = 0; j != source.size(); ++j)
		{
			const CAPLEntries& curEntry = source[j];
			ST_CAPLEntries& newEntry = dest[j];
			newEntry.Priority = curEntry.m_Priority;
			newEntry.NAP_ID = curEntry.m_NAP_ID;
			size_t chPlanRefIdsCount = curEntry.m_ChPlanRefIds.size();
			for (size_t k = 0; k != chPlanRefIdsCount; ++k)
			{
				String refId;
				memcpy(newEntry.ChPlanRefIds[k].RefId, curEntry.m_ChPlanRefIds[k].c_str(), curEntry.m_ChPlanRefIds[k].size());
			}
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ChannelPlan(ChannelPlan& dest, const ST_ChannelPlan& source)
	{
		dest.m_BW = source.BW;
		dest.m_FFTSize = source.FFTSize;
		dest.m_DuplexMode = source.DuplexMode;
		size_t chPlanEntries = sizeof(source.Entries) / sizeof(ST_ChannelPlanEntries);
		for (size_t j = 0; j != chPlanEntries; ++j)
		{
			ST_ChannelPlanEntries curChPlanEntry = source.Entries[j];
			ChannelPlanEntries newChPlanEntry;
			newChPlanEntry.m_BW = curChPlanEntry.BW;
			newChPlanEntry.m_DuplexMode = curChPlanEntry.DuplexMode;
			newChPlanEntry.m_FFTSize = curChPlanEntry.FFTSize;
			newChPlanEntry.m_FirstFreq = curChPlanEntry.FirstFreq;
			copyToString(newChPlanEntry.m_Id, curChPlanEntry.Id, CHANNEL_REFID_LEAF_SIZE);
			newChPlanEntry.m_LastFreq = curChPlanEntry.LastFreq;
			newChPlanEntry.m_NextFreqStep = curChPlanEntry.NextFreqStep;
			copyToString(newChPlanEntry.m_Preambles, curChPlanEntry.Preambles, CHANNEL_PLAN_PREAMBLE_LEAF_SIZE);

			dest.m_Entries.push_back(newChPlanEntry);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_ChannelPlan(ST_ChannelPlan& dest, const ChannelPlan& source)
	{
		dest.BW = source.m_BW;
		dest.FFTSize = source.m_FFTSize;
		dest.DuplexMode = source.m_DuplexMode;
		size_t chPlanEntries = source.m_Entries.size();
		for (size_t j = 0; j != chPlanEntries; ++j)
		{
			ChannelPlanEntries curChPlanEntry = source.m_Entries[j];
			ST_ChannelPlanEntries& newChPlanEntry = dest.Entries[j];
			newChPlanEntry.BW = curChPlanEntry.m_BW;
			newChPlanEntry.DuplexMode = curChPlanEntry.m_DuplexMode;
			newChPlanEntry.FFTSize = curChPlanEntry.m_FFTSize;
			newChPlanEntry.FirstFreq = curChPlanEntry.m_FirstFreq;
			memcpy(newChPlanEntry.Id, curChPlanEntry.m_Id.c_str(), curChPlanEntry.m_Id.size());
			newChPlanEntry.LastFreq = curChPlanEntry.m_LastFreq;
			newChPlanEntry.NextFreqStep = curChPlanEntry.m_NextFreqStep;
			memcpy(newChPlanEntry.Preambles, curChPlanEntry.m_Preambles.c_str(), curChPlanEntry.m_Preambles.size());
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_RAPL(RAPL& dest, const ST_RAPL& source)
	{
		dest.m_Any = source.Any;
		size_t raplEntriesCount = sizeof(source.Entries) / sizeof(ST_RAPLEntries);
		for (size_t j = 0; j != raplEntriesCount; ++j)
		{
			const ST_RAPLEntries& curEntry = source.Entries[j];
			RAPLEntries newEntry;
			newEntry.m_Priority = curEntry.Priority;
			newEntry.m_V_NSP_ID = curEntry.V_NSP_ID;
			dest.m_Entries.push_back(newEntry);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_RAPL(ST_RAPL& dest, const RAPL& source)
	{
		dest.Any = source.m_Any;
		size_t raplEntriesCount = source.m_Entries.size();
		for (size_t j = 0; j != raplEntriesCount; ++j)
		{
			const RAPLEntries& curEntry = source.m_Entries[j];
			ST_RAPLEntries& newEntry = dest.Entries[j];
			newEntry.Priority = curEntry.m_Priority;
			newEntry.V_NSP_ID = curEntry.m_V_NSP_ID;
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_NetworkParameters(NetworkParameters& dest, const ST_NetworkParameters& source)
	{
		// NetworkParameters
		copyToString(dest.m_OperatorName, source.OperatorName, MAX_SIZE_OPERATORNAME);
		dest.m_PollingInterval = source.PollingInterval;

		// NetworkParameters.CALP
		dest.m_CAPL.m_Any = source.CAPL.Any;
		size_t entriesCount = sizeof(source.CAPL.Entries) / sizeof(ST_CAPLEntries);
		add_CALPEntries(dest.m_CAPL.m_Entries, source.CAPL.Entries, entriesCount);

		// NetworkParameters.ChannelPlan
		add_ChannelPlan(dest.m_ChannelPlan, source.ChannelPlan);
		// NetworkParameters.NSP
		size_t NSPCount = sizeof(source.H_NSP) / sizeof(ST_H_NSP);
		for (size_t i = 0; i != NSPCount; ++i)
		{
			dest.m_H_NSP.push_back(source.H_NSP[i].H_NSP_ID);
		}
		// NetworkParameters.RAPL
		add_RAPL(dest.m_RAPL, source.RAPL);
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_NetworkParameters(ST_NetworkParameters& dest, const NetworkParameters& source)
	{
		// NetworkParameters
		memcpy(dest.OperatorName, source.m_OperatorName.c_str(), source.m_OperatorName.size());
		dest.PollingInterval = source.m_PollingInterval;

		// NetworkParameters.CALP
		dest.CAPL.Any = source.m_CAPL.m_Any;
		//size_t entriesCount = source.m_CAPL.m_Entries.size();
		add_ST_CALPEntries(dest.CAPL.Entries, source.m_CAPL.m_Entries);

		// NetworkParameters.ChannelPlan
		add_ST_ChannelPlan(dest.ChannelPlan, source.m_ChannelPlan);
		// NetworkParameters.NSP
		for (size_t i = 0; i != source.m_H_NSP.size(); ++i)
		{
			dest.H_NSP[i].H_NSP_ID = source.m_H_NSP[i];
		}

		// NetworkParameters.RAPL
		add_ST_RAPL(dest.RAPL, source.m_RAPL);
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_Contacts(std::vector<Contacts>& dest, const ST_Contacts* source, size_t size)
	{
		for (size_t j = 0; j != size; ++j)
		{
			const ST_Contacts& curEntry = source[j];
			Contacts newEntry;
			copyToString(newEntry.m_Text, curEntry.Text, CONTACTS_TEXT_LEAF_SIZE);
			copyToString(newEntry.m_URI, curEntry.URI, CONTACTS_URI_LEAF_SIZE);
			copyToString(newEntry.m_Trigger, curEntry.Trigger, CONTACTS_TRIGGER_LEAF_SIZE);
			newEntry.m_Type = curEntry.Type;
			dest.push_back(newEntry);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_Contacts(ST_Contacts* dest, const std::vector<Contacts>& source)
	{
		for (size_t j = 0; j != source.size(); ++j)
		{
			const Contacts& curEntry = source[j];
			ST_Contacts& newEntry = dest[j];
			memcpy(newEntry.Text, curEntry.m_Text.c_str(), curEntry.m_Text.size());
			memcpy(newEntry.URI, curEntry.m_URI.c_str(), curEntry.m_URI.size());
			memcpy(newEntry.Trigger, curEntry.m_Trigger.c_str(), curEntry.m_Trigger.size());
			newEntry.Type = curEntry.m_Type;
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_RootCA(std::vector<RootCA>& dest, const ST_RootCA* source, size_t size)
	{
		for (size_t j = 0; j != size; ++j)
		{
			const ST_RootCA& curEntry = source[j];
			RootCA newEntry;
			copyToString(newEntry.m_CertID, curEntry.CertID, ROOTCA_CERTID_LEAF_SIZE);
			copyToString(newEntry.m_Certificate, curEntry.Certificate, ROOTCA_CERTIFICATE_LEAF_SIZE);
			copyToString(newEntry.m_Signature, curEntry.Signature, ROOTCA_SIGNATURE_LEAF_SIZE);
			dest.push_back(newEntry);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_RootCA(ST_RootCA* dest, const std::vector<RootCA>& source)
	{
		for (size_t j = 0; j != source.size(); ++j)
		{
			const RootCA& curEntry = source[j];
			ST_RootCA& newEntry = dest[j];
			memcpy(newEntry.CertID, curEntry.m_CertID.c_str(), curEntry.m_CertID.size());
			memcpy(newEntry.Certificate, curEntry.m_Certificate.c_str(), curEntry.m_Certificate.size());
			memcpy(newEntry.Signature, curEntry.m_Signature.c_str(), curEntry.m_Signature.size());
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_OtherSubscriptions(std::vector<OtherSubscriptions>& dest,
		const ST_OtherSubscriptions* source, size_t size)
	{
		for (size_t j = 0; j != size; ++j)
		{
			const ST_OtherSubscriptions& curEntry = source[j];
			OtherSubscriptions newEntry;
			newEntry.m_Activated = curEntry.Activated;
			copyToString(newEntry.m_Name, curEntry.Name, OTHERSUBSCRIPTIONS_NAME_LEAF_SIZE);
			// EAP
			size_t eapCount = sizeof(curEntry.EAP) / sizeof(ST_EAP);
			add_EAP(newEntry.m_EAP, curEntry.EAP, eapCount);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_OtherSubscriptions(ST_OtherSubscriptions* dest, const std::vector<OtherSubscriptions>& source)
	{
		for (size_t j = 0; j != source.size(); ++j)
		{
			const OtherSubscriptions& curEntry = source[j];
			ST_OtherSubscriptions& newEntry = dest[j];
			newEntry.Activated = curEntry.m_Activated;
			memcpy(newEntry.Name, curEntry.m_Name.c_str(), curEntry.m_Name.size());
			// EAP
			add_ST_EAP(newEntry.EAP, curEntry.m_EAP);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_EAP(std::vector<EAP>& dest, const ST_EAP* source, size_t size)
	{
		for (size_t k = 0; k != size; ++k)
		{
			EAP newEAP;
			// EAP.CERT
			size_t certCount = sizeof(source[k].CERT) / sizeof(ST_CERT);
			for (size_t l = 0; l != certCount; ++l)
			{
				CERT newCert;
				copyToString(newCert.m_CERT_TYPE, source[k].CERT[l].CERT_TYPE, CERT_CERT_TYPE_LEAF_SIZE);
				newCert.m_SER_NUM = source[k].CERT[l].SER_NUM;
				newCert.m_THUMBPRINT = source[k].CERT[l].THUMBPRINT;

				newEAP.m_CERT.push_back(newCert);
			}
			newEAP.m_EAP_AKA = source[k].EAP_AKA.USE_CHECK_CODE;
			newEAP.m_ENCAPS = source[k].ENCAPS;
			newEAP.m_METHOD_TYPE = source[k].METHOD_TYPE;
			copyToString(newEAP.m_PASSWORD, source[k].PASSWORD, EAP_PASSWORD_LEAF_SIZE);
			copyToString(newEAP.m_PROVISIONED_PSEUDO_IDENTITY, source[k].PROVISIONED_PSEUDO_IDENTITY,
				EAP_PROVISIONED_PSEUDO_IDENTITY_LEAF_SIZE);
			copyToString(newEAP.m_REALM, source[k].REALM, EAP_REALM_LEAF_SIZE);

			// EAP.SERVER_REALMS
			size_t srvRealmsCount = sizeof(source[k].SERVER_REALMS) / sizeof(ST_SERVER_REALMS);
			for (size_t l = 0; l != srvRealmsCount; ++l)
			{
				String newServerRealms;
				copyToString(newServerRealms, source[k].SERVER_REALMS[l].SERVER_REALM, SERVER_REALM_LEAF_SIZE);
				newEAP.m_SERVER_REALMS.push_back(newServerRealms);
			}

			copyToString(newEAP.m_UserIdentity, source[k].UserIdentity, EAP_USERIDENTITY_LEAF_SIZE);
			newEAP.m_VENDOR_ID = source[k].VENDOR_ID;
			newEAP.m_VENDOR_TYPE = source[k].VENDOR_TYPE;
			newEAP.m_VFY_SERVER_REALM = source[k].VFY_SERVER_REALM;
			newEAP.m_USE_PRIVACY = source[k].USE_PRIVACY;

			dest.push_back(newEAP);
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_EAP(ST_EAP* dest, const std::vector<EAP>& source)
	{
		for (size_t k = 0; k != source.size(); ++k)
		{
			ST_EAP& newEAP = dest[k];
			// EAP.CERT
			size_t certCount = source[k].m_CERT.size();
			for (size_t l = 0; l != certCount; ++l)
			{
				ST_CERT& newCert = newEAP.CERT[l];
				memcpy(newCert.CERT_TYPE, source[k].m_CERT[l].m_CERT_TYPE.c_str(), source[k].m_CERT[l].m_CERT_TYPE.size());
				newCert.SER_NUM = source[k].m_CERT[l].m_SER_NUM;
				newCert.THUMBPRINT = source[k].m_CERT[l].m_THUMBPRINT;
			}
			newEAP.EAP_AKA.USE_CHECK_CODE = source[k].m_EAP_AKA;
			newEAP.ENCAPS = source[k].m_ENCAPS;
			newEAP.METHOD_TYPE = source[k].m_METHOD_TYPE;
			memcpy(newEAP.PASSWORD, source[k].m_PASSWORD.c_str(), source[k].m_PASSWORD.size());
			memcpy(newEAP.PROVISIONED_PSEUDO_IDENTITY, source[k].m_PROVISIONED_PSEUDO_IDENTITY.c_str(),
				source[k].m_PROVISIONED_PSEUDO_IDENTITY.size());
			memcpy(newEAP.REALM, source[k].m_REALM.c_str(), source[k].m_REALM.size());

			// EAP.SERVER_REALMS
			size_t srvRealmsCount = source[k].m_SERVER_REALMS.size();
			for (size_t l = 0; l != srvRealmsCount; ++l)
			{
				memcpy(newEAP.SERVER_REALMS[l].SERVER_REALM, source[k].m_SERVER_REALMS[l].c_str(), source[k].m_SERVER_REALMS[l].size());
			}

			memcpy(newEAP.UserIdentity, source[k].m_UserIdentity.c_str(), source[k].m_UserIdentity.size());
			newEAP.VENDOR_ID = source[k].m_VENDOR_ID;
			newEAP.VENDOR_TYPE = source[k].m_VENDOR_TYPE;
			newEAP.VFY_SERVER_REALM = source[k].m_VFY_SERVER_REALM;
			newEAP.USE_PRIVACY = source[k].m_USE_PRIVACY;
		}
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_Primary(Primary& dest, const ST_Primary& source)
	{
		dest.m_Activated = source.Activated;
		copyToString(dest.m_Name, source.Name, PRIMARY_NAME_LEAF_SIZE);
		size_t eapCount = sizeof(source.EAP) / sizeof(ST_EAP);
		add_EAP(dest.m_EAP, source.EAP, eapCount);
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_Primary(ST_Primary& dest, const Primary& source)
	{
		dest.Activated = source.m_Activated;
		memcpy(dest.Name, source.m_Name.c_str(), source.m_Name.size());
		add_ST_EAP(dest.EAP, source.m_EAP);
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_SubscriptionParameters(SubscriptionParameters& dest,
		const ST_SubscriptionParameters& source)
	{
		size_t subParamsCount = sizeof(source.OtherSubscriptions) / sizeof(ST_OtherSubscriptions);
		add_OtherSubscriptions(dest.m_OtherSubscriptions, source.OtherSubscriptions, subParamsCount);
		add_Primary(dest.m_Primary, source.Primary);
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::add_ST_SubscriptionParameters(ST_SubscriptionParameters& dest, const SubscriptionParameters& source)
	{
		add_ST_OtherSubscriptions(dest.OtherSubscriptions, source.m_OtherSubscriptions);
		add_ST_Primary(dest.Primary, source.m_Primary);
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::GetWiMAXSupp(WiMAXSupp& wimaxSupp)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_WIMAXSUPP, SUBTYPE_OMADM_GET_REQ, requestMessage, length);
		res = sendMessage((PUCHAR)&requestMessage, length);

		if (res)
		{
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_WIMAXSupp* stWimaxSupp = (ST_WIMAXSupp*)(OMADMObject->au8OMADMObjVal);

			size_t size = sizeof(stWimaxSupp->Operator) / sizeof(ST_Operator);
			for (size_t i = 0; i != size; ++i)
			{
				ST_Operator& curOperator = stWimaxSupp->Operator[i];
				Operator newOperator;
				copyToString(newOperator.m_TO_IP_REF, curOperator.TO_IP_REF, OPERATOR_TO_IP_REF_LEAF_SIZE);

				add_NetworkParameters(newOperator.m_NetworkParameters, curOperator.NetworkParameters);
				size_t contactsCount = sizeof(curOperator.Contacts) / sizeof(ST_Contacts);
				add_Contacts(newOperator.m_Contacts, curOperator.Contacts, contactsCount);
				size_t rootCACount = sizeof(curOperator.RootCA) / sizeof(ST_RootCA);
				add_RootCA(newOperator.m_RootCA, curOperator.RootCA, rootCACount);
				add_SubscriptionParameters(newOperator.m_SubscriptionParameters, curOperator.SubscriptionParameters);

				wimaxSupp.m_Operator.push_back(newOperator);
			}
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::GetDeviceDetail(DevDetail& deviceDetail)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_DEV_DETAIL, SUBTYPE_OMADM_GET_REQ, requestMessage, length);
		res = sendMessage((PUCHAR)&requestMessage, length);

		if (res)
		{
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_DevDetail* devDetail = (ST_DevDetail*)(OMADMObject->au8OMADMObjVal);
			deviceDetail.m_URI.m_MaxDepth = devDetail->URI.MaxDepth;
			deviceDetail.m_URI.m_MaxSegLen = devDetail->URI.MaxSegLen;
			deviceDetail.m_URI.m_MaxTotLen = devDetail->URI.MaxTotLen;
			copyToString(deviceDetail.m_DevTyp, devDetail->DevType, DEVDETAIL_DEVTYPE_LEAF_SIZE);
			copyToString(deviceDetail.m_OEM, devDetail->OEM, DEVDETAIL_OEM_LEAF_SIZE);
			copyToString(deviceDetail.m_FwV, devDetail->FwV, DEVDETAIL_FWV_LEAF_SIZE);
			copyToString(deviceDetail.m_SwV, devDetail->SwV, DEVDETAIL_SWV_LEAF_SIZE);
			copyToString(deviceDetail.m_HwV, devDetail->HwV, DEVDETAIL_HWV_LEAF_SIZE);
			deviceDetail.m_LrgObj = devDetail->LrgObj;
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::SetDeviceInfo(const DevInfo& deviceInfo)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_DEV_INFO, SUBTYPE_OMADM_SET_REQ, requestMessage, length);

		if (res)
		{
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_DevInfo* devInfo = (ST_DevInfo*)OMADMObject->au8OMADMObjVal;
			memcpy(devInfo->DevId, deviceInfo.m_DevId.c_str(), deviceInfo.m_DevId.size());
			memcpy(devInfo->DmV, deviceInfo.m_DmV.c_str(), deviceInfo.m_DmV.size());
			memcpy(devInfo->Man, deviceInfo.m_Man.c_str(), deviceInfo.m_Man.size());
			memcpy(devInfo->Mod, deviceInfo.m_Mod.c_str(), deviceInfo.m_Mod.size());
			memcpy(devInfo->Lang, deviceInfo.m_Lang.c_str(), deviceInfo.m_Lang.size());
			res = sendMessage((PUCHAR)&requestMessage, length);
		}

		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::SetDeviceDetail(const DevDetail& deviceDetail)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_DEV_DETAIL, SUBTYPE_OMADM_SET_REQ, requestMessage, length);

		if (res)
		{
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_DevDetail* devDetail = (ST_DevDetail*)OMADMObject->au8OMADMObjVal;
			memcpy(devDetail->DevType, deviceDetail.m_DevTyp.c_str(), deviceDetail.m_DevTyp.size());
			memcpy(devDetail->FwV, deviceDetail.m_FwV.c_str(), deviceDetail.m_FwV.size());
			memcpy(devDetail->HwV, deviceDetail.m_HwV.c_str(), deviceDetail.m_HwV.size());
			memcpy(devDetail->OEM, deviceDetail.m_OEM.c_str(), deviceDetail.m_OEM.size());
			memcpy(devDetail->SwV, deviceDetail.m_SwV.c_str(), deviceDetail.m_SwV.size());
			devDetail->LrgObj = deviceDetail.m_LrgObj;
			devDetail->URI.MaxDepth = deviceDetail.m_URI.m_MaxDepth;
			devDetail->URI.MaxSegLen = deviceDetail.m_URI.m_MaxSegLen;
			devDetail->URI.MaxTotLen = deviceDetail.m_URI.m_MaxTotLen;

			res = sendMessage((PUCHAR)&requestMessage, length);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::SetDMAccount(const DMAcc& dmAccount)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_DMACC, SUBTYPE_OMADM_SET_REQ, requestMessage, length);

		if (res)
		{
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_DMAcc* dmAcc = (ST_DMAcc*)OMADMObject->au8OMADMObjVal;
			if (dmAccount.m_DMAccImpl.empty())
			{
				return false;
			}
			memcpy(dmAcc->AAuthPref, dmAccount.m_DMAccImpl[0].m_AAuthPref.c_str(), dmAccount.m_DMAccImpl[0].m_AAuthPref.size());
			memcpy(dmAcc->AppID, dmAccount.m_DMAccImpl[0].m_AppID.c_str(), dmAccount.m_DMAccImpl[0].m_AppID.size());
			memcpy(dmAcc->Name, dmAccount.m_DMAccImpl[0].m_Name.c_str(), dmAccount.m_DMAccImpl[0].m_Name.size());
			memcpy(dmAcc->PrefConRef, dmAccount.m_DMAccImpl[0].m_PrefConRef.c_str(), dmAccount.m_DMAccImpl[0].m_PrefConRef.size());
			memcpy(dmAcc->ServerID, dmAccount.m_DMAccImpl[0].m_ServerID.c_str(), dmAccount.m_DMAccImpl[0].m_ServerID.size());

			// ToConRef
			size_t size = dmAccount.m_DMAccImpl[0].m_ToConRef.size();
			for (size_t i = 0; i != size; ++i)
			{
				String curElement = dmAccount.m_DMAccImpl[0].m_ToConRef[i];
				memcpy(dmAcc->ToConRef[i].ConRef, curElement.c_str(), curElement.size());
			}
			// AppAddr
			size = dmAccount.m_DMAccImpl[0].m_AppAddr.size();
			for (size_t i = 0; i != size; ++i)
			{
				memcpy(dmAcc->AppAddr[i].Addr, dmAccount.m_DMAccImpl[0].m_AppAddr[i].m_Addr.c_str(), dmAccount.m_DMAccImpl[0].m_AppAddr[i].m_Addr.size());
				memcpy(dmAcc->AppAddr[i].AddrType, dmAccount.m_DMAccImpl[0].m_AppAddr[i].m_AddrType.c_str(), dmAccount.m_DMAccImpl[0].m_AppAddr[i].m_AddrType.size());
				memcpy(dmAcc->AppAddr[i].Port->PortNbr, dmAccount.m_DMAccImpl[0].m_AppAddr[i].m_PortNbr.c_str(), dmAccount.m_DMAccImpl[0].m_AppAddr[i].m_PortNbr.size());
			}
			// AppAuth
			size = dmAccount.m_DMAccImpl[0].m_AppAuth.size();
			for (size_t i = 0; i != size; ++i)
			{
				memcpy(dmAcc->AppAuth[i].AAuthData, dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthData.c_str(), dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthData.size());
				memcpy(dmAcc->AppAuth[i].AAuthLevel, dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthLevel.c_str(), dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthLevel.size());
				memcpy(dmAcc->AppAuth[i].AAuthType, dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthType.c_str(), dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthType.size());
				memcpy(dmAcc->AppAuth[i].AAuthName, dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthName.c_str(), dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthName.size());
				memcpy(dmAcc->AppAuth[i].AAuthSecret, dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthSecret.c_str(), dmAccount.m_DMAccImpl[0].m_AppAuth[i].m_AAuthSecret.size());
			}

			res = sendMessage((PUCHAR)&requestMessage, length);
		}

		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::SetWiMAX(const WiMAX& wimax)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_WIMAX, SUBTYPE_OMADM_SET_REQ, requestMessage, length);

		if (res)
		{
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_WIMAX* stWimax = (ST_WIMAX*)OMADMObject->au8OMADMObjVal;
			memcpy(stWimax->TO_WIMAX_REF, wimax.m_TO_WiMAX_REF.c_str(), wimax.m_TO_WiMAX_REF.size());

			// WiMAXRadioModule
			size_t size = wimax.m_WiMAXRadioModule.size();
			for (size_t i = 0; i != size; ++i)
			{
				WiMAXRadioModule curWiMAXRadioModule = wimax.m_WiMAXRadioModule[i];
				memcpy(stWimax->WIMAXRadioModule[i].FwV, curWiMAXRadioModule.m_FwV.c_str(), curWiMAXRadioModule.m_FwV.size());
				memcpy(stWimax->WIMAXRadioModule[i].HwV, curWiMAXRadioModule.m_HwV.c_str(), curWiMAXRadioModule.m_HwV.size());
				memcpy(stWimax->WIMAXRadioModule[i].MACAddress, curWiMAXRadioModule.m_MACAddress.c_str(), curWiMAXRadioModule.m_MACAddress.size());
				memcpy(stWimax->WIMAXRadioModule[i].Man, curWiMAXRadioModule.m_Man.c_str(), curWiMAXRadioModule.m_Man.size());
				memcpy(stWimax->WIMAXRadioModule[i].Mod, curWiMAXRadioModule.m_Mod.c_str(), curWiMAXRadioModule.m_Mod.size());
				memcpy(stWimax->WIMAXRadioModule[i].SwV, curWiMAXRadioModule.m_SwV.c_str(), curWiMAXRadioModule.m_SwV.size());
//				memcpy(stWimax->WIMAXRadioModule[i].SPLock.Lock, curWiMAXRadioModule.m_SPLock.m_Lock.c_str(), curWiMAXRadioModule.m_SPLock.m_Lock.size());
//				stWimax->WIMAXRadioModule[i].SPLock.LockStatus = curWiMAXRadioModule.m_SPLock.m_LockStatus;
//				stWimax->WIMAXRadioModule[i].SPLock.VerNbr = curWiMAXRadioModule.m_SPLock.m_VerNbr;
//				memcpy(stWimax->WIMAXRadioModule[i].SPLock.Operator, curWiMAXRadioModule.m_SPLock.m_Operator.c_str(), curWiMAXRadioModule.m_SPLock.m_Operator.size());
				memcpy(stWimax->WIMAXRadioModule[i].TO_FUMO_REF, curWiMAXRadioModule.m_TO_FUMO_REF.c_str(), curWiMAXRadioModule.m_TO_FUMO_REF.size());
			}
			// TerminalEquipment
			memcpy(stWimax->TerminalEquipment.DevID, wimax.m_TerminalEquipment.m_DevID.c_str(), wimax.m_TerminalEquipment.m_DevID.size());
			memcpy(stWimax->TerminalEquipment.DevType, wimax.m_TerminalEquipment.m_DevType.c_str(), wimax.m_TerminalEquipment.m_DevType.size());
			memcpy(stWimax->TerminalEquipment.FwV, wimax.m_TerminalEquipment.m_FwV.c_str(), wimax.m_TerminalEquipment.m_FwV.size());
			memcpy(stWimax->TerminalEquipment.HwV, wimax.m_TerminalEquipment.m_HwV.c_str(), wimax.m_TerminalEquipment.m_HwV.size());
			memcpy(stWimax->TerminalEquipment.Man, wimax.m_TerminalEquipment.m_Man.c_str(), wimax.m_TerminalEquipment.m_Man.size());
			memcpy(stWimax->TerminalEquipment.Mod, wimax.m_TerminalEquipment.m_Mod.c_str(), wimax.m_TerminalEquipment.m_Mod.size());
			memcpy(stWimax->TerminalEquipment.SwV, wimax.m_TerminalEquipment.m_SwV.c_str(), wimax.m_TerminalEquipment.m_SwV.size());

			// DevCap
			stWimax->DevCap.IPCap.CMIPV4 = wimax.m_DevCap.m_IPCap.m_CMIPV4;
			stWimax->DevCap.IPCap.CMIPV6 = wimax.m_DevCap.m_IPCap.m_CMIPV6;
			stWimax->DevCap.IPCap.IPV4 = wimax.m_DevCap.m_IPCap.m_IPV4;
			stWimax->DevCap.IPCap.IPV6 = wimax.m_DevCap.m_IPCap.m_IPV6;
			stWimax->DevCap.UpdateMethods.ClientInitiated.PollingSupported = wimax.m_DevCap.m_UpdateMethods.m_ClientInitiated.m_PollingSupported;
			stWimax->DevCap.UpdateMethods.ClientInitiated.PollingInterval = wimax.m_DevCap.m_UpdateMethods.m_ClientInitiated.m_PollingInterval;

			res = sendMessage((PUCHAR)&requestMessage, length);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool BeceemAdapter::SetWiMAXSupp(const WiMAXSupp& wimaxSupp)
	{
		WIMAX_MESSAGE requestMessage = {0};
		USHORT length;
		bool res = getOMADMRequest(OMA_DM_ST_ROOT_WIMAXSUPP, SUBTYPE_OMADM_SET_REQ, requestMessage, length);

		if (res)
		{
			POMADM_OBJECT_INFO OMADMObject = (POMADM_OBJECT_INFO)requestMessage.szData;
			ST_WIMAXSupp* stWimaxSupp = (ST_WIMAXSupp*)OMADMObject->au8OMADMObjVal;

			size_t size = wimaxSupp.m_Operator.size();
			for (size_t i = 0; i != size; ++i)
			{
				ST_Operator& newOperator = stWimaxSupp->Operator[i];
				memcpy(stWimaxSupp->Operator[i].TO_IP_REF, wimaxSupp.m_Operator[i].m_TO_IP_REF.c_str(),
					wimaxSupp.m_Operator[i].m_TO_IP_REF.size());

				add_ST_NetworkParameters(newOperator.NetworkParameters, wimaxSupp.m_Operator[i].m_NetworkParameters);
				add_ST_Contacts(newOperator.Contacts, wimaxSupp.m_Operator[i].m_Contacts);
				add_ST_RootCA(newOperator.RootCA, wimaxSupp.m_Operator[i].m_RootCA);
				add_ST_SubscriptionParameters(newOperator.SubscriptionParameters, wimaxSupp.m_Operator[i].m_SubscriptionParameters);
			}
			res = sendMessage((PUCHAR)&requestMessage, length);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	void BeceemAdapter::copyToString(String& destination, const void* source, int size) const
	{
		char* tmpContent = new char[size + 1];
		memset(tmpContent, 0, size + 1); // last 0 added
		memcpy(tmpContent, source, size);
		destination = tmpContent;
		delete [] tmpContent;
	}


}
