#include "StdAfx.h"
#include "GobiApiWms.h"
#include "FuncList.h"
#include "StatusCtrl.h"
#include "GobiConnectionMgmtAPI.h"
#include <GobiAPI.h>
#include "SwiWwanCmApi.h"

#define FUNC_DeleteSMS      				L"DeleteSMS"
#define FUNC_GetSMSList                     L"GetSMSList"
#define FUNC_GetSMS                         L"GetSMS"
#define FUNC_ModifySMSStatus                L"ModifySMSStatus"
#define FUNC_SaveSMS                        L"SaveSMS"
#define FUNC_SendSMS                        L"SendSMS"
#define FUNC_GetSMSCAddress                 L"GetSMSCAddress"
#define FUNC_SetSMSCAddress                 L"SetSMSCAddress"
#define FUNC_GetSMSRoutes                   L"GetSMSRoutes"
#define FUNC_SetSMSRoutes                   L"SetSMSRoutes"
#define FUNC_GetRoutes                      L"GetRoutes"
#define FUNC_SetRoutes                      L"SetRoutes"
#define FUNCT_SetNewSMSCallback				L"SetNewSMSCallback"
#define FUNC_ReadWCDMATextMsg				L"ReadWCDMATextMsg"
#define FUNC_ReadCDMATextMsg				L"ReadCDMATextMsg"
#define FUNC_StoreWCDMATextMsg				L"StoreWCDMATextMsg"
#define FUNC_SendWCDMATextMsg				L"SendWCDMATextMsg"
#define FUNC_SendCDMATextMsg				L"SendCDMATextMsg"
#define FUNC_SetSMSProtocol                 L"SetSMSProtocol"
#define FUNC_GetSMSProtocol                 L"GetSMSProtocol"

#define PARAM_TechPref						L"TechnologyPref"
#define PARAM_Duration						L"Duration"
#define PARAM_MessageTag					L"MessageTag"
#define PARAM_StorageType					L"StorageType"
#define PARAM_MessageIndex					L"MessageIndex"
#define PARAM_MessageFormat					L"MessageFormat"
#define PARAM_MessageSize					L"MessageSize"
#define PARAM_Message						L"Message"
#define PARAM_SmscAddress					L"SmscAddress"
#define PARAM_SmscType						L"SmscType"
#define PARAM_Enable						L"Enable"
#define PARAM_MsgType						L"Message Type"
#define PARAM_MsgClass						L"Message Class"
#define PARAM_RouteStorage					L"Route Storage"
#define PARAM_ReceiptAction					L"Receipt Action"
#define PARAM_MsgRefNum					    L"Message Reference Number"
#define PARAM_RejectDuplicates				L"Reject Duplicates"
#define PARAM_StatusReportReq				L"Status Report Request"
#define PARAM_ReplyPath						L"Reply Path"
#define PARAM_ValidityFormat				L"Validity Format"
#define PARAM_ValidityPeriod				L"Validity Period"
#define PARAM_EncodingAlphabet				L"Encoding Alphabet"
#define PARAM_DestinationAddress			L"Destination Address"
#define PARAM_TextMessage					L"Text Message"
#define PARAM_MessageProtocol               L"MessageProtocol"

CParamList CGobiApiWms::m_sSetNetworkPrefParams;
CParamList CGobiApiWms::m_sGetSMSList;
CParamList CGobiApiWms::m_sGetSMS;
CParamList CGobiApiWms::m_sSetSmscAddress;
CParamList CGobiApiWms::m_sModifySMSStatus;
CParamList CGobiApiWms::m_sSaveSMS;
CParamList CGobiApiWms::m_sSendSMS;
CParamList CGobiApiWms::m_sDeleteSMS;
CParamList CGobiApiWms::m_sSetRoutes;
CParamList CGobiApiWms::m_sSetNewSmsCallback;
CParamList CGobiApiWms::m_sReadWCDMATextMsg;
CParamList CGobiApiWms::m_sReadCDMATextMsg;
CParamList CGobiApiWms::m_sStoreWCDMATextMsg;
CParamList CGobiApiWms::m_sStoreCDMATextMsg;
CParamList CGobiApiWms::m_sSendWCDMATextMsg;
CParamList CGobiApiWms::m_sSendCDMATextMsg;
CParamList CGobiApiWms::m_sSMSProtocol;

// List of supported functions
const TableFuncEntry CGobiApiWms::m_TableFunc[] = 
{
	{FUNC_DeleteSMS,			FuncDeleteSMS,			&m_sDeleteSMS},
	{FUNC_GetSMSList,			FuncGetSMSList,			&m_sGetSMSList},
	{FUNC_GetSMS,				FuncGetSMS,				&m_sGetSMS},
	{FUNC_ModifySMSStatus,		FuncModifySMSStatus,	&m_sModifySMSStatus},
	{FUNC_SaveSMS,				FuncSaveSMS,			&m_sSaveSMS},
	{FUNC_SendSMS,				FuncSendSMS,			&m_sSendSMS},
	{FUNC_GetSMSCAddress,		FuncGetSMSCAddress},
	{FUNC_SetSMSCAddress,		FuncSetSMSCAddress,		&m_sSetSmscAddress},
	{FUNC_GetSMSRoutes,			FuncGetSMSRoutes},
	{FUNC_SetSMSRoutes,			FuncSetSMSRoutes,		&m_sSetRoutes},
	{FUNC_GetRoutes,			FuncGetRoutes},
	{FUNC_SetRoutes,			FuncSetRoutes,			&m_sSetRoutes},
	{FUNCT_SetNewSMSCallback,	FuncSetNewSmsCallback,	&m_sSetNewSmsCallback},
	{FUNC_ReadWCDMATextMsg,	    FuncReadWCDMATextMsg,	&m_sReadWCDMATextMsg},
	{FUNC_ReadCDMATextMsg,	    FuncReadCDMATextMsg,	&m_sReadCDMATextMsg},
	{FUNC_StoreWCDMATextMsg,    FuncStoreWCDMATextMsg,  &m_sStoreWCDMATextMsg},
	{FUNC_SendWCDMATextMsg,     FuncSendWCDMATextMsg,   &m_sSendWCDMATextMsg},
	{FUNC_SendCDMATextMsg,      FuncSendCDMATextMsg,    &m_sSendCDMATextMsg},
    {FUNC_SetSMSProtocol,       FuncSetSMSProtocol,     &m_sSMSProtocol},
    {FUNC_GetSMSProtocol,       FuncGetSMSProtocol},
	{FUNC_EndOfList}
};

CGobiApiWms::CGobiApiWms(HMODULE hQCDll)
{
	// Initialize the QC Dll pointer
	m_hQCDll = hQCDll;

	// Define SetNetworkPrefParams configurable parameters
	m_sSetNetworkPrefParams.Add(PARAM_TechPref, L"0");
	m_sSetNetworkPrefParams.Add(PARAM_Duration, L"1");

	// Define GetSMSList configurable parameters
	m_sGetSMSList.Add(PARAM_StorageType, L"1");	// UIM = 0, NV = 1
	m_sGetSMSList.Add(PARAM_MessageTag, L"-1");	// Unread (optional)

	// Define GetSMS configurable parameters
	m_sGetSMS.Add(PARAM_StorageType, L"1");		// UIM = 0, NV = 1
	m_sGetSMS.Add(PARAM_MessageIndex, L"0");	// first message

	// Define configurable parameters for SetSMSCAddress 
	m_sSetSmscAddress.Add(PARAM_SmscAddress, L"+17057969300");
	m_sSetSmscAddress.Add(PARAM_SmscType, L"145");

	// Define configurable parameters for ModifySMSStatus
	m_sModifySMSStatus.Add(PARAM_StorageType, L"1");	// UIM = 0, NV = 1
	m_sModifySMSStatus.Add(PARAM_MessageIndex, L"0");	// index of the message
	m_sModifySMSStatus.Add(PARAM_MessageTag, L"0");		// Read=0, Not read=1

	// Define configurable parameters for DeleteSMS
	m_sDeleteSMS.Add(PARAM_StorageType, L"1");		// UIM = 0, NV = 1
	m_sDeleteSMS.Add(PARAM_MessageIndex, L"-1");	// index of the message (optional)
	m_sDeleteSMS.Add(PARAM_MessageTag, L"-1");		// Read=0, Not read=1 (optional)

	// Define configurable parameters for SaveSMS
	m_sSaveSMS.Add(PARAM_StorageType, L"1");	// UIM = 0, NV = 1
	m_sSaveSMS.Add(PARAM_MessageFormat, L"6");	// 0-CDMA (IS-637B), 1-5 Reserved, 6-GSM/WCDMA PP
	m_sSaveSMS.Add(PARAM_MessageSize, L"24");	// length of message content in bytes
	m_sSaveSMS.Add(PARAM_Message, L"0001000B916140057651F000000B46F9BB0D3ABEC569900C");	// 16045067150, "From Gobi 2"

	// Define configurable parameters for SendSMS
	m_sSendSMS.Add(PARAM_MessageFormat, L"6");	// 0-CDMA (IS-637B), 1-5 Reserved, 6-GSM/WCDMA PP
	m_sSendSMS.Add(PARAM_MessageSize, L"0");	// length of message content in bytes
	m_sSendSMS.Add(PARAM_Message, L"");			// PDU message
     
	// Define configurable parameters for SetRoutes
	m_sSetRoutes.Add (PARAM_MsgType, L"0");
	m_sSetRoutes.Add (PARAM_MsgClass, L"0");
	m_sSetRoutes.Add (PARAM_RouteStorage, L"0");
	m_sSetRoutes.Add (PARAM_ReceiptAction, L"0");

	// Define configurable parameters for SetNewSMSCallback
	m_sSetNewSmsCallback.Add(PARAM_Enable, L"1");

	// Define message parameters for ReadWCDMATextMsg
	m_sReadWCDMATextMsg.Add(PARAM_StorageType, L"1");	// UIM = 0, NV = 1
	m_sReadWCDMATextMsg.Add(PARAM_MessageIndex, L"1");

	// Define message parameters for ReadCDMATextMsg
	m_sReadCDMATextMsg.Add(PARAM_StorageType, L"1");	// UIM = 0, NV = 1
	m_sReadCDMATextMsg.Add(PARAM_MessageIndex, L"1");

	// Define message parameters for StoreWCDMATextMsg
	m_sStoreWCDMATextMsg.Add(PARAM_StorageType, L"1");	// UIM = 0, NV = 1
	m_sStoreWCDMATextMsg.Add(PARAM_MsgRefNum, L"1");
	m_sStoreWCDMATextMsg.Add(PARAM_RejectDuplicates, L"0");
	m_sStoreWCDMATextMsg.Add(PARAM_StatusReportReq, L"0");
	m_sStoreWCDMATextMsg.Add(PARAM_ReplyPath, L"0");
	m_sStoreWCDMATextMsg.Add(PARAM_ValidityFormat, L"3");
	m_sStoreWCDMATextMsg.Add(PARAM_ValidityPeriod, L"11030110111292");
	m_sStoreWCDMATextMsg.Add(PARAM_EncodingAlphabet, L"0");
	m_sStoreWCDMATextMsg.Add(PARAM_DestinationAddress, L"");
	m_sStoreWCDMATextMsg.Add(PARAM_TextMessage, L"Hello World!");

	// Define message parameter for SendCDMATextMsg
	m_sSendCDMATextMsg.Add(PARAM_DestinationAddress, L"");
	m_sSendCDMATextMsg.Add(PARAM_TextMessage, L"Hello World!");
	m_sSendCDMATextMsg.Add(PARAM_StorageType, L"1");	// UIM = 0, NV = 1
	m_sSendCDMATextMsg.Add(PARAM_MsgRefNum, L"1");
	m_sSendCDMATextMsg.Add(PARAM_ValidityFormat, L"0");
	m_sSendCDMATextMsg.Add(PARAM_ValidityPeriod, L"");
	m_sSendCDMATextMsg.Add(PARAM_EncodingAlphabet, L"0");

	// Define message parameters for SendWCDMATextMsg
	m_sSendWCDMATextMsg.Add(PARAM_DestinationAddress, L"");
	m_sSendWCDMATextMsg.Add(PARAM_TextMessage, L"Hello World!");
	m_sSendWCDMATextMsg.Add(PARAM_MsgRefNum, L"1");
	m_sSendWCDMATextMsg.Add(PARAM_RejectDuplicates, L"0");
	m_sSendWCDMATextMsg.Add(PARAM_StatusReportReq, L"0");
	m_sSendWCDMATextMsg.Add(PARAM_ReplyPath, L"0");
	m_sSendWCDMATextMsg.Add(PARAM_ValidityFormat, L"0");
	m_sSendWCDMATextMsg.Add(PARAM_ValidityPeriod, L"");
	m_sSendWCDMATextMsg.Add(PARAM_EncodingAlphabet, L"0");

    // Define message parameters for SetSMSProtocol
    m_sSMSProtocol.Add( PARAM_MessageProtocol, L"0" );
}

CGobiApiWms::~CGobiApiWms(void)
{
}

BOOL CGobiApiWms::GetAvailFuncList(CFuncList* pFuncList)
{
	TBD_FUNCTION(CGobiApiWms::GetAvailFuncList);

	int iIndex = 0;

	while (m_TableFunc[iIndex].szFuncName.Compare(FUNC_EndOfList))
	{
		pFuncList->Add(L"SMS", m_TableFunc[iIndex].szFuncName, m_TableFunc[iIndex].pParamList);
		TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, m_TableFunc[iIndex].szFuncName);
		iIndex++;
	}

	return TRUE;
}

UINT CGobiApiWms::ExecuteFunctions(CFuncList* pFuncList, UINT &nTotalExec)
{
	TBD_FUNCTION(CGobiApiWms::Execute);

	int iIndex = 0;
	m_nNumErrors = 0;
	nTotalExec = 0;

	while (m_TableFunc[iIndex].szFuncName.Compare(FUNC_EndOfList))
	{
		if (pFuncList->Find(m_TableFunc[iIndex].szFuncName))
		{
			// Get list of parameters
			CParamList sParams;
			pFuncList->GetFuncParams(m_TableFunc[iIndex].szFuncName, sParams);

			// execute function
			if (!m_TableFunc[iIndex].pFunc(&sParams))
				// increment error counter
				m_nNumErrors++;

			// increment total functions executed
			nTotalExec++;
		}

		iIndex++;
	}

	return m_nNumErrors;
}

BOOL CGobiApiWms::FuncDeleteSMS(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncDeleteSMS", STATUSMSG_Send);

	BOOL bRet = FALSE;

	// create structure for easy comparison later
	ULONG nStorageType; 
	ULONG nMessageIndex; 
	ULONG nMessageTag; 

	// initialize structure
	nStorageType = _ttoi(pParams->GetValue(PARAM_StorageType));
	nMessageIndex = _ttoi(pParams->GetValue(PARAM_MessageIndex));
	nMessageTag = _ttoi(pParams->GetValue(PARAM_MessageTag));

	// call Sierra interface
	ULONG nRet = DeleteSMS(nStorageType, 
						   (nMessageIndex == -1)?NULL:&nMessageIndex, 
						   (nMessageTag == -1)?NULL:&nMessageTag);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"DeleteSMS completed successfully");
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		bRet = TRUE;
	}

	return bRet;
}

BOOL CGobiApiWms::FuncGetSMSList(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncGetSMSList", STATUSMSG_Send);

	BOOL bRet = FALSE;

	typedef struct
	{
		ULONG  messageIndex;
		ULONG  messageTag;
	} STRUCT_SMSMessageList;

	// create structure for easy comparison later
	typedef struct 
	{
		ULONG   storageType; 
		ULONG   RequestedTag; 
		ULONG   MessageListSize; 
		STRUCT_SMSMessageList Messages[60]; 
	} STRUCT_GetSMSList;

	STRUCT_GetSMSList sParam;
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_GetSMSList));
	// initialize structure
	sParam.MessageListSize = sizeof(sParam.Messages)/sizeof(sParam.Messages[0]);
	sParam.storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
	sParam.RequestedTag = _ttoi(pParams->GetValue(PARAM_MessageTag));

	// call Sierra interface
	ULONG nRet = GetSMSList(sParam.storageType, 
							(sParam.RequestedTag == -1)?NULL:&sParam.RequestedTag,
							&sParam.MessageListSize,
							(BYTE*) &sParam.Messages[0]);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"Modem reports there are %d SMS messages", sParam.MessageListSize);
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		for( unsigned int i=0; i<sParam.MessageListSize; i++ )
		{
			strTemp.Format(L"Message Index: %d Message Tag: %d", sParam.Messages[i].messageIndex, sParam.Messages[i].messageTag);
		    ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		}

		bRet = TRUE;
	}

	// Compare with QC DLL
	if (m_hQCDll)
	{
		// function prototype
		typedef ULONG (SWICMAPI*LPFN_GETSMSLIST) (ULONG, ULONG*, ULONG*, BYTE*);

		// get pointer to function
		LPFN_GETSMSLIST pFn = (LPFN_GETSMSLIST)GetProcAddress_W(m_hQCDll, FUNC_GetSMSList);

		// execute function
		if (pFn)
		{
			STRUCT_GetSMSList sQcParam;
			// clear structure
			memset(&sQcParam, 0, sizeof(STRUCT_GetSMSList));
	        // initialize structure
			sQcParam.MessageListSize = sizeof(sParam.Messages)/sizeof(sParam.Messages[0]);
			sQcParam.storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
			sQcParam.RequestedTag = _ttoi(pParams->GetValue(PARAM_MessageTag));

			ULONG nQcRet = pFn(sQcParam.storageType, 
							  (sQcParam.RequestedTag == -1)?NULL:&sQcParam.RequestedTag, 
							  &sQcParam.MessageListSize,
							  (BYTE*) &sQcParam.Messages[0]);

			if (nQcRet != nRet)
			{
				strTemp.Format(L"QC returned a different status code: %04d", nQcRet);
				ADDSTATUS(strTemp, STATUSMSG_Error);
				bRet = FALSE;
			}
			else
			{
				ADDSTATUS(L"Response matches Qualcomm DLL", STATUSMSG_Status);
				bRet = TRUE;
			}
		}
	}

	return bRet;
}

BOOL CGobiApiWms::FuncGetSMS(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncGetSMS", STATUSMSG_Send);

	BOOL bRet = FALSE;

	// create structure for easy comparison later
	typedef struct 
	{
		ULONG   storageType; 
		ULONG   messageIndex;
		ULONG   MessageTag; 
		ULONG   MessageFormat;
		ULONG   MessageSize;
		BYTE    Message[512];    // Extra long for now
	} STRUCT_GetSMS;

	STRUCT_GetSMS sParam;
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_GetSMS));

	// initialize structure. These three are inputs
	sParam.storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
	sParam.messageIndex = _ttoi(pParams->GetValue(PARAM_MessageIndex));
	sParam.MessageSize = sizeof(sParam.Message);

	// call Sierra interface
	ULONG nRet = GetSMS( sParam.storageType, 
		                 sParam.messageIndex,
						 &sParam.MessageTag,
					     &sParam.MessageFormat,
				         &sParam.MessageSize,
						 &sParam.Message[0]);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"Selected SMS is %d bytes long. Format: %x, Tag: %x", sParam.MessageSize, sParam.MessageFormat, sParam.MessageTag);
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);


        // Print the details for each one
		for( unsigned int i=0; i<sParam.MessageSize; i++ )
		{
		    strTemp.Format(L"%02x", sParam.Message[i]);
			ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		}
		bRet = TRUE;
	}

	// Compare with QC DLL
	if (m_hQCDll)
	{
		// function prototype
		typedef ULONG (SWICMAPI*LPFN_GETSMS) (ULONG, ULONG, ULONG*, ULONG*, ULONG*, BYTE*);

		// get pointer to function
		LPFN_GETSMS pFn = (LPFN_GETSMS)GetProcAddress_W(m_hQCDll, FUNC_GetSMS);

		// execute function
		if (pFn)
		{
			STRUCT_GetSMS sQcParam;
			// clear structure
			memset(&sQcParam, 0, sizeof(STRUCT_GetSMS));
	        // initialize structure
			sQcParam.storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
			sQcParam.messageIndex = _ttoi(pParams->GetValue(PARAM_MessageIndex));
	        sQcParam.MessageSize = sizeof(sQcParam.Message);

			ULONG nQcRet = pFn(sQcParam.storageType,
				              sQcParam.messageIndex,
							  &sQcParam.MessageTag, 
							  &sQcParam.MessageFormat,
							  &sQcParam.MessageSize,
							  &sQcParam.Message[0]);

			if (nQcRet != nRet)
			{
				strTemp.Format(L"QC returned a different status code: %04d", nQcRet);
				ADDSTATUS(strTemp, STATUSMSG_Error);
				bRet = FALSE;
			}
			else
			{
				ADDSTATUS(L"Response matches Qualcomm DLL", STATUSMSG_Status);
				bRet = TRUE;
			}
		}
	}

	return bRet;
}

BOOL CGobiApiWms::FuncModifySMSStatus(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncModifySMSStatus", STATUSMSG_Send);

	BOOL bRet = FALSE;

	// create structure for easy comparison later
	typedef struct 
	{
		ULONG   storageType; 
		ULONG   MessageIndex; 
		ULONG   MessageTag; 
	} STRUCT_ModifySMSStatus;

	STRUCT_ModifySMSStatus sParam;
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_ModifySMSStatus));

	// initialize structure
	sParam.storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
	sParam.MessageIndex = _ttoi(pParams->GetValue(PARAM_MessageIndex));
	sParam.MessageTag = _ttoi(pParams->GetValue(PARAM_MessageTag));

	// call Sierra interface
	ULONG nRet = ModifySMSStatus( sParam.storageType, 
							      sParam.MessageIndex,
							      sParam.MessageTag);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"ModifySMSStatus completed successfully");
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		bRet = TRUE;
	}

	// Compare with QC DLL
	if (m_hQCDll)
	{
		// function prototype
		typedef ULONG (SWICMAPI*LPFN_MODIFYSMSSTATUS) (ULONG, ULONG, ULONG);

		// get pointer to function
		LPFN_MODIFYSMSSTATUS pFn = (LPFN_MODIFYSMSSTATUS)GetProcAddress_W(m_hQCDll, FUNC_ModifySMSStatus);

		// execute function
		if (pFn)
		{
			ULONG nQcRet = pFn(sParam.storageType, 
							  sParam.MessageIndex, 
							  sParam.MessageTag);

			if (nQcRet != nRet)
			{
				strTemp.Format(L"QC returned a different status code: %04d", nQcRet);
				ADDSTATUS(strTemp, STATUSMSG_Error);
				bRet = FALSE;
			}
			else
			{
				ADDSTATUS(L"Response matches Qualcomm DLL", STATUSMSG_Status);
				bRet = TRUE;
			}
		}
	}

	return bRet;
}

// Helper function to convert ASCII hex characters to binary
unsigned char hex2bin(unsigned char h, unsigned char l)
{
	h |= 0x20; // to lower
	h -= 0x30;
	h -= -(h > 9) & 0x27;
	l |= 0x20;
	l -= 0x30;
	l -= -(l > 9) & 0x27;
	return h << 4 | l;
}

BOOL CGobiApiWms::FuncSaveSMS(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncSaveSMS", STATUSMSG_Send);

	BOOL bRet = FALSE;

	// SmsPduGen (Minaz Fazal), can be used to generate SMS PDUs. 
	//Another good reference source for interpreting this kind of thing is:
	// http://dreamfabric.com/sms/
	// A sample message:     
	/*
	BYTE SMSMessage[] = {
	0x00,             // - No SMSC Information included (use the phone's)
	0x01,             // - First octet of this SMS-Send message
	0x00,             // - Let the phone set the message reference number
	0x0B,             // - Length of destination phone #, decimal semi-octets
	0x91,             // - Type of address of called number
	0x61, 0x06, 0x54, 0x60, 0x17, 0xF5, // - Dest. no: 1 604 506 7150 (Steve's work SIM)
	0x71, 0x87, 0x38, 0x98, 0x13, 0xF3, // - Dest. no: 1 604 506 7150 (Steve's work SIM)
	0x00,             // - TP-PID Protocol identifier
	0x00,             // - TP-DCS Data Coding Scheme
	0x0B,             // - TP-UDL, length+1 of the user data, in bytes
	0x46, 0xF9, 0xBB, // - Encoded user message: "From Gobi 2"
	0x0D, 0x3A, 0xBE, 
	0xC5, 0x69, 0x90, 
	0x0C};
	*/

	// create structure for easy comparison later
	typedef struct 
	{
		ULONG   storageType; 
		ULONG   messageFormat; 
		ULONG   messageSize;
		ULONG   MessageIndex;
		BYTE    Message[256];    // Max WMS Payload Size
	} STRUCT_SaveSMS;

	STRUCT_SaveSMS sParam;
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_SaveSMS));

	// initialize structure
	sParam.storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
	sParam.messageFormat = _ttoi(pParams->GetValue(PARAM_MessageFormat));
	sParam.messageSize = _ttoi(pParams->GetValue(PARAM_MessageSize));

	// Get message payload and convert to ASCII
	CW2A buf(pParams->GetValue(PARAM_Message));

	// convert ASCII hex string to binary
	int iIndex = 0;

	for(int i=0; i<(int)strlen(buf); i+=2) 
	{
		sParam.Message[iIndex] = hex2bin(buf[i], buf[i+1]);
		iIndex++;
	}

	// call Sierra interface
	ULONG nRet = SaveSMS( sParam.storageType, 
		                  sParam.messageFormat,
						  sParam.messageSize,
						  &sParam.Message[0],
						  &sParam.MessageIndex);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"Message saved at index: %d", sParam.MessageIndex);
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		bRet = TRUE;
	}

	// Compare with QC DLL
	if (m_hQCDll)
	{
		// function prototype
		typedef ULONG (SWICMAPI*LPFN_SAVESMS) (ULONG, ULONG, ULONG, BYTE*, ULONG*);

		// get pointer to function
		LPFN_SAVESMS pFn = (LPFN_SAVESMS)GetProcAddress_W(m_hQCDll, FUNC_SaveSMS);

		// execute function
		if (pFn)
		{
			ULONG nQcRet = pFn( sParam.storageType, 
		                       sParam.messageFormat,
						       sParam.messageSize,
						       &sParam.Message[0],
						       &sParam.MessageIndex);

			if (nQcRet != nRet)
			{
				strTemp.Format(L"QC returned a different status code: %04d", nQcRet);
				ADDSTATUS(strTemp, STATUSMSG_Error);
				bRet = FALSE;
			}
			else
			{
				ADDSTATUS(L"Response matches Qualcomm DLL", STATUSMSG_Status);
				bRet = TRUE;
			}
		}
	}

	return bRet;
}

BOOL CGobiApiWms::FuncSendSMS(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncSendSMS", STATUSMSG_Send);

	BOOL bRet = FALSE;

	// SmsPduGen (Minaz Fazal), can be used to generate SMS PDUs. 
	//Another good reference source for interpreting this kind of thing is:
	// http://dreamfabric.com/sms/
	// A sample message:     
	/*
	BYTE SMSMessage[] = {
	0x00,             // - No SMSC Information included (use the phone's)
	0x01,             // - First octet of this SMS-Send message
	0x00,             // - Let the phone set the message reference number
	0x0B,             // - Length of destination phone #, decimal semi-octets
	0x91,             // - Type of address of called number
	0x61, 0x06, 0x54, 0x60, 0x17, 0xF5, // - Dest. no: 1 604 506 7150 (Steve's work SIM)
	0x00,             // - TP-PID Protocol identifier
	0x00,             // - TP-DCS Data Coding Scheme
	0x0B,             // - TP-UDL, length+1 of the user data, in bytes
	0x46, 0xF9, 0xBB, // - Encoded user message: "From Gobi 2"
	0x0D, 0x3A, 0xBE, 
	0xC5, 0x69, 0x90, 
	0x0C};
	*/

	// create structure for easy comparison later
	typedef struct 
	{
		ULONG   messageFormat; 
		ULONG   messageSize;
		ULONG   MessageFailureCode;
		BYTE    Message[256];    // Max WMS Payload Size
	} STRUCT_SendSMS;

	STRUCT_SendSMS sParam;
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_SendSMS));

	// initialize structure
	sParam.messageFormat = _ttoi(pParams->GetValue(PARAM_MessageFormat));
	sParam.messageSize = _ttoi(pParams->GetValue(PARAM_MessageSize));

	// Get message payload and convert to ASCII
	CW2A buf(pParams->GetValue(PARAM_Message));

	// convert ASCII hex string to binary
	int iIndex = 0;

	for(int i=0; i<(int)strlen(buf); i+=2) 
	{
		sParam.Message[iIndex] = hex2bin(buf[i], buf[i+1]);
		iIndex++;
	}

	// call Sierra interface
	ULONG nRet = SendSMS( sParam.messageFormat,
						  sParam.messageSize,
						  &sParam.Message[0],
						  NULL,//link timer, for use with multi sms
						  &sParam.MessageFailureCode);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (nRet)
	{
		strTemp.Format(L"Message sending response %d", sParam.MessageFailureCode);
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	}
	else
	{
		bRet = TRUE;
	}

	// Compare with QC DLL
	if (m_hQCDll)
	{
		ADDSTATUS(L"Attempting to send with QC DLL", STATUSMSG_Send);

		// function prototype
		typedef ULONG (SWICMAPI*LPFN_SENDSMS) (ULONG, ULONG, BYTE*, ULONG*);

		// get pointer to function
		LPFN_SENDSMS pFn = (LPFN_SENDSMS)GetProcAddress_W(m_hQCDll, FUNC_SendSMS);

		// execute function
		if (pFn)
		{
			// Send the same message, but clear the result code first
			sParam.MessageFailureCode = 0;
			
			ULONG nQcRet = pFn( sParam.messageFormat,
						       sParam.messageSize,
						       &sParam.Message[0],
						       &sParam.MessageFailureCode);

			if (nQcRet != nRet)
			{
				strTemp.Format(L"QC returned a different status code: %04d", nQcRet);
				ADDSTATUS(strTemp, STATUSMSG_Error);
				bRet = FALSE;
			}
			else
			{
				ADDSTATUS(L"Response matches Qualcomm DLL", STATUSMSG_Status);
				bRet = TRUE;
			}
		}
	}

	return bRet;
}

BOOL CGobiApiWms::FuncGetSMSCAddress(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncGetSMSCAddress", STATUSMSG_Send);
	UNREFERENCED_PARAMETER(pParams);
	const BYTE MAX_Name = 0xFF;
	BOOL bRet = FALSE;

	// create structure for easy comparison later
	typedef struct 
	{
		BYTE   addressSize; 
		CHAR   SMSCAddress[40]; 
		BYTE   typeSize; 
		CHAR   SMSCType[40];
	} STRUCT_GetSMSCAddress;

	STRUCT_GetSMSCAddress sParam;
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_GetSMSCAddress));
	// initialize structure
	sParam.addressSize = sizeof(sParam.SMSCAddress);
	sParam.typeSize = sizeof(sParam.SMSCType);

	// call Sierra interface
	ULONG nRet = GetSMSCAddress( sParam.addressSize, 
							     sParam.SMSCAddress,
							     sParam.typeSize,
								 sParam.SMSCType);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"GetSMSCAddress completed successfully");
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		TCHAR szString1U[MAX_Name] = L"";
		TCHAR szString2U[MAX_Name] = L"";
	    if (MultiByteToWideChar(CP_ACP, 0, sParam.SMSCType, -1, szString1U, MAX_Name))
	    {
	        if (MultiByteToWideChar(CP_ACP, 0, sParam.SMSCAddress, -1, szString2U, MAX_Name))
			{
	  	        strTemp.Format(L"SMSC Address Type: %s, SMSC Address: %s", szString1U, szString2U);
			}
		    ADDSTATUS(strTemp, STATUSMSG_Receive);
	    }

		bRet = TRUE;
	}

	// Compare with QC DLL
	if (m_hQCDll)
	{
		// function prototype
		typedef ULONG (SWICMAPI*LPFN_GETSMSCADDRESS) (BYTE, CHAR*, BYTE, CHAR*);

		// get pointer to function
		LPFN_GETSMSCADDRESS pFn = (LPFN_GETSMSCADDRESS)GetProcAddress_W(m_hQCDll, FUNC_GetSMSCAddress);

		// execute function
		if (pFn)
		{
			STRUCT_GetSMSCAddress sQcParam;
			// clear structure
			memset(&sQcParam, 0, sizeof(STRUCT_GetSMSCAddress));
	        sQcParam.addressSize = sizeof(sParam.SMSCAddress);
	        sQcParam.typeSize = sizeof(sParam.SMSCType);

			ULONG nQcRet = pFn(sQcParam.addressSize, 
							     sQcParam.SMSCAddress,
							     sQcParam.typeSize,
								 sQcParam.SMSCType);

			if (nQcRet != nRet)
			{
				strTemp.Format(L"QC returned a different status code: %04d", nQcRet);
				ADDSTATUS(strTemp, STATUSMSG_Error);
				bRet = FALSE;
			}
			else
			{
				ADDSTATUS(L"Response matches Qualcomm DLL", STATUSMSG_Status);
				bRet = TRUE;
			}
		}
	}

	return bRet;
}

BOOL CGobiApiWms::FuncSetSMSCAddress(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncSetSMSCAddress", STATUSMSG_Send);
	const BYTE MAX_Length = 40;
	BOOL bRet = FALSE;

	// create structure for easy comparison later
	typedef struct 
	{
		CHAR   SMSCAddress[MAX_Length]; 
		CHAR   SMSCType[MAX_Length];
	} STRUCT_SetSMSCAddress;

	STRUCT_SetSMSCAddress sParam;
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_SetSMSCAddress));
	// initialize structure
	strcpy_s(sParam.SMSCType, MAX_Length, CW2A(pParams->GetValue(PARAM_SmscType)));
	strcpy_s(sParam.SMSCAddress, MAX_Length, CW2A(pParams->GetValue(PARAM_SmscAddress)));

	// call Sierra interface
	ULONG nRet = SetSMSCAddress( sParam.SMSCAddress,
								 sParam.SMSCType);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %04d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"SetSMSCAddress completed successfully");
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		bRet = TRUE;
	}

	// Compare with QC DLL
	if (m_hQCDll)
	{
		// function prototype
		typedef ULONG (SWICMAPI*LPFN_SETSMSCADDRESS) (CHAR*, CHAR*);

		// get pointer to function
		LPFN_SETSMSCADDRESS pFn = (LPFN_SETSMSCADDRESS)GetProcAddress_W(m_hQCDll, FUNC_SetSMSCAddress);

		// execute function
		if (pFn)
		{
			ULONG nQcRet = pFn(sParam.SMSCAddress, sParam.SMSCType);

			if (nQcRet != nRet)
			{
				strTemp.Format(L"QC returned a different status code: %04d", nQcRet);
				ADDSTATUS(strTemp, STATUSMSG_Error);
				bRet = FALSE;
			}
			else
			{
				ADDSTATUS(L"Response matches Qualcomm DLL", STATUSMSG_Status);
				bRet = TRUE;
			}
		}
	}

	return bRet;
}

BOOL CGobiApiWms::FuncGetSMSRoutes(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncGetSMSRoutes", STATUSMSG_Send);
	UNREFERENCED_PARAMETER(pParams);

	BOOL bRet = FALSE;

	BYTE routeInstances;
	typedef struct
	{
		ULONG   messageType;
		ULONG   messageClass;
		ULONG   routeStorage;
		ULONG   receiptAction;
	} STRUCT_SMSRouteList;

	UINT const nBufSize = 15;
	STRUCT_SMSRouteList sParam[nBufSize];
	// clear structure
	memset(&sParam, 0, sizeof(sParam));
	// initialize structure
	routeInstances = nBufSize;

	// call Sierra interface
	ULONG nRet = GetSMSRoutes( &routeInstances, (BYTE*)&sParam);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"Modem reports there are %d routes", routeInstances);
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		for( unsigned int i=0; i <routeInstances; i++ )
		{
			strTemp.Format(L"Route: %d; Type: %d; Class: %d; Storage: %d; Value: %d", 
				i+1, sParam[i].messageType, sParam[i].messageClass, sParam[i].routeStorage, sParam[i].receiptAction);
			ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		}

		bRet = TRUE;
	}

	// no equivalent Compare with QC DLL
	return bRet;
}

BOOL CGobiApiWms::FuncSetSMSRoutes(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncSetSMSRoutes", STATUSMSG_Send);

	BOOL bRet = FALSE;

	BYTE routeInstances = 0;
	typedef struct
	{
		ULONG   messageType;
		ULONG   messageClass;
		ULONG   routeStorage;
		ULONG   receiptAction;
	} STRUCT_SMSRouteList;

	STRUCT_SMSRouteList sParam[1];
	// clear structure
	memset(&sParam, 0, sizeof(sParam));
	// Get user selected parameters
	if (pParams)
	{
		routeInstances          = 1;
		sParam[0].messageType   = _ttoi(pParams->GetValue(PARAM_MsgType));
		sParam[0].messageClass  = _ttoi(pParams->GetValue(PARAM_MsgClass));
		sParam[0].routeStorage  = _ttoi(pParams->GetValue(PARAM_RouteStorage));
		sParam[0].receiptAction = _ttoi(pParams->GetValue(PARAM_ReceiptAction));
	}

	CString strTemp;
	strTemp.Format(L"Setting Type: %d; Class: %d; Storage: %d; Value: %d", 
		sParam[0].messageType, sParam[0].messageClass, sParam[0].routeStorage, sParam[0].receiptAction);
	ADDSTATUS(strTemp, STATUSMSG_Send);

	// call Sierra interface
	ULONG nRet = SetSMSRoutes( &routeInstances, (BYTE*)&sParam);

	// display output in GUI
	strTemp.Format(L"Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		bRet = TRUE;
	}

	// no equivalent Compare with QC DLL

	return bRet;
}

BOOL CGobiApiWms::FuncGetRoutes(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncGetRoutes", STATUSMSG_Send);
	UNREFERENCED_PARAMETER(pParams);

	BOOL bRet = FALSE;

	ULONG routeInstances;
	typedef struct
	{
		BYTE   messageType;
		BYTE   messageClass;
		BYTE   routeStorage;
		BYTE   receiptAction;
	} STRUCT_RouteList;

	STRUCT_RouteList sParam[20];
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_RouteList));
	// initialize structure

	// call Sierra interface
	ULONG nRet = GetRoutes( &routeInstances, (BYTE*)&sParam);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"Modem reports there are %d routes", routeInstances);
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		for( unsigned int i=0; i <routeInstances; i++ )
		{
			strTemp.Format(L"Route: %d; Message Type: %d; Message Class: %d", i+1, sParam[i].messageType, sParam[i].messageClass);
		    ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
			strTemp.Format(L"Route: %d; Route Storage: %d; ReceiptAction: %d", i+1, sParam[i].routeStorage, sParam[i].receiptAction);
		    ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		}

		bRet = TRUE;
	}

	// no equivalent Compare with QC DLL
	return bRet;
}

BOOL CGobiApiWms::FuncSetRoutes(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncSetRoutes", STATUSMSG_Send);

	BOOL bRet = FALSE;

	ULONG routeInstances = 0;
	typedef struct
	{
		BYTE   messageType;
		BYTE   messageClass;
		BYTE   routeStorage;
		BYTE   receiptAction;
	} STRUCT_RouteList;

	STRUCT_RouteList sParam[1];
	// clear structure
	memset(&sParam, 0, sizeof(STRUCT_RouteList));
	// Get user selected parameters
	if (pParams)
	{
		routeInstances          = 1;
		sParam[0].messageType   = (BYTE)_ttoi(pParams->GetValue(PARAM_MsgType));
		sParam[0].messageClass  = (BYTE)_ttoi(pParams->GetValue(PARAM_MsgClass));
		sParam[0].routeStorage  = (BYTE)_ttoi(pParams->GetValue(PARAM_RouteStorage));
		sParam[0].receiptAction = (BYTE)_ttoi(pParams->GetValue(PARAM_ReceiptAction));
	}

	// call Sierra interface
	ULONG nRet = SetRoutes( routeInstances, (BYTE*)&sParam);

	// display output in GUI
	CString strTemp;
	strTemp.Format(L"Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if (!nRet)
	{
		strTemp.Format(L"%d routes set", routeInstances);
		ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		for( unsigned int i=0; i <routeInstances; i++ )
		{
			strTemp.Format(L"Route: %d; Message Type: %d; Message Class: %d", i+1, sParam[i].messageType, sParam[i].messageClass);
			ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
			strTemp.Format(L"Route: %d; Route Storage: %d; ReceiptAction: %d", i+1, sParam[i].routeStorage, sParam[i].receiptAction);
			ADDSTATUS(strTemp, (nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		}

		bRet = TRUE;
	}

	// no equivalent Compare with QC DLL

	return bRet;
}

BOOL CGobiApiWms::FuncReadWCDMATextMsg(CParamList* pParams /*= NULL*/)
{
	ULONG messageIndex = 2;
	ULONG storageType = 0;

	ADDSTATUS(L"FuncReadWCDMATextMsg", STATUSMSG_Send);

	ULONG    messageTag;
	ULONG    messageFormat;
	ULONG    rawLength = 177;
	BYTE     raw[177];

	const BYTE MAX_Name = 0xFF;
    TCHAR szStringU[MAX_Name] = L"";

	BOOLEAN more2Send;
	BOOLEAN replyPath;
	BOOLEAN statusReportInd;
	BOOLEAN rejectDuplicates;
	BOOLEAN statusReportReq;

	BYTE     validityFormat;
	BYTE     timeStamp[7];

	BYTE     SCaddressSize = 14;
	CHAR     SCaddress[14];
	BYTE     addressSize = 14;
	CHAR     address[14];

	BOOLEAN  concatFlag =  FALSE;
	ULONG    messageRefNum = 0;
	BYTE    totalNumSeg = 0;
	BYTE    numSeg = 0;

	BYTE     messageLength = 160;
	WCHAR    message[160]; 

	if (pParams)
	{
		storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
		messageIndex = _ttoi(pParams->GetValue(PARAM_MessageIndex));
	}

	ULONG nRet = GetSMS(storageType, messageIndex, &messageTag, &messageFormat, &rawLength, raw);

	CString strTemp;
	strTemp.Format(L"GetSMS()Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if(nRet != 0)
		return FALSE;

	if(messageFormat != 6)
	{
		ADDSTATUS(L"NON WCDMA message index", STATUSMSG_Send);
		return FALSE;
	}

	switch(messageTag)
	{
	case 0:
		strTemp.Format(L"MessageTag: MT Read (%d)", messageTag);
		break;
	case 1:
		strTemp.Format(L"MessageTag: MT Unread (%d)", messageTag);
		break;
	case 2:
		strTemp.Format(L"MessageTag: MO Sent (%d)", messageTag);
		break;
	case 3:
		strTemp.Format(L"MessageTag: MO Draft (%d)", messageTag);
		break;
	default:
		strTemp.Format(L"MessageTag: Undefined (%d)", messageTag);
		break;
	}

	// if read or unread message
	if(messageTag == 0 || messageTag == 1)
	{
		nRet = WCDMADecodeMTTextMsg(
			raw, 
			&addressSize, 
			address,
			&messageLength,
			message,
			&SCaddressSize, 
			SCaddress, 
			&more2Send, 
			&replyPath, 
			&statusReportInd, 
			timeStamp,
			&concatFlag,
			&messageRefNum,
			&totalNumSeg,
			&numSeg);

		strTemp.Format(L"WCDMADecodeMTTextMsg()  Result: %4d", nRet);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		if(nRet != 0)
		{
			return FALSE;
		}

		strTemp.Format(L"More[%d] Reply[%d] Status[%d]", more2Send, replyPath, statusReportInd);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		switch( timeStamp[1])
		{
		case 1:
			strTemp.Format(L"TimeStamp: 20%02x JAN %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 2:
			strTemp.Format(L"TimeStamp: 20%02x FEB %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 3:
			strTemp.Format(L"TimeStamp: 20%02x MAR %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 4:
			strTemp.Format(L"TimeStamp: 20%02x APR %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 5:
			strTemp.Format(L"TimeStamp: 20%02x MAY %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 6:
			strTemp.Format(L"TimeStamp: 20%02x JUN %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 7:
			strTemp.Format(L"TimeStamp: 20%02x JULY %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 8:
			strTemp.Format(L"TimeStamp: 20%02x AUG %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 9:
			strTemp.Format(L"TimeStamp: 20%02x SEPT %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 10:
			strTemp.Format(L"TimeStamp: 20%02x OCT %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 11:
			strTemp.Format(L"TimeStamp: 20%02x NOV %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 12:
			strTemp.Format(L"TimeStamp: 20%02x DEC %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		default:
			strTemp.Format(L"TimeStamp: 20%02x Month[%d] %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		}
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		MultiByteToWideChar(CP_ACP, 0, address, -1, szStringU, MAX_Name);
		strTemp.Format(L"OriginatingAddress: %s", szStringU);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	}
	else if (messageTag == 2 || messageTag == 3)
	{
		nRet = WCDMADecodeMOTextMsg(
			raw,
			&addressSize,
			address,
			&messageLength,
			message,
			&SCaddressSize, 
			SCaddress, 
			&rejectDuplicates,
			&replyPath,
			&statusReportReq,
			&validityFormat,
			timeStamp,
			&concatFlag,
			&messageRefNum,
			&totalNumSeg,
			&numSeg);

		strTemp.Format(L"WCDMADecodeMOTextMsg()  Result: %4d", nRet);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		if(nRet != 0)
			return FALSE;

		strTemp.Format(L"Duplicates[%d] Reply[%d] Status[%d]", rejectDuplicates, replyPath, statusReportReq);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		switch(validityFormat)
		{
		case 0:
			strTemp.Format(L"No Validity Period Present");
			ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
			break;

		case 1:  // relative
			strTemp.Format(L"Relative Validity Period [%d]", timeStamp[0]);
			ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
			break;

		case 2:  // enhanced
			strTemp.Format(L"Enhanced Validity Period [%02x%02x%02x%02x%02x%02x%02x]", timeStamp[0], timeStamp[1], timeStamp[2],timeStamp[3], timeStamp[4], timeStamp[5], timeStamp[6]);
			ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
			break;

		case 3:  // absolute
		switch( timeStamp[1])
		{
		case 1:
			strTemp.Format(L"Validity Period: 20%02x JAN %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 2:
			strTemp.Format(L"Validity Period: 20%02x FEB %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 3:
			strTemp.Format(L"Validity Period: 20%02x MAR %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 4:
			strTemp.Format(L"Validity Period: 20%02x APR %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 5:
			strTemp.Format(L"Validity Period: 20%02x MAY %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 6:
			strTemp.Format(L"Validity Period: 20%02x JUN %2x %02x:%02x:%02x %2x", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 7:
			strTemp.Format(L"Validity Period: 20%02x JULY %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 8:
			strTemp.Format(L"Validity Period: 20%02x AUG %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 9:
			strTemp.Format(L"Validity Period: 20%02x SEPT %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 10:
			strTemp.Format(L"Validity Period: 20%02x OCT %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 11:
			strTemp.Format(L"Validity Period: 20%02x NOV %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 12:
			strTemp.Format(L"Validity Period: 20%02x DEC %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		default:
			strTemp.Format(L"Validity Period: 20%02x Month[%d] %2x %02x:%02x:%02x %2x", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		}
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
		break;
		default: // unknown
			strTemp.Format(L"UNKNOWN Validity Period Format [%d]", validityFormat);
			ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
			break;
		}

		MultiByteToWideChar(CP_ACP, 0, address, -1, szStringU, MAX_Name);
		strTemp.Format(L"DestinationAddress: %s", szStringU);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	}


	MultiByteToWideChar(CP_ACP, 0, SCaddress, -1, szStringU, MAX_Name);
	strTemp.Format(L"ScAddress: %s", szStringU);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	strTemp.Format(L"ConCat: %d  RefNum: %d, TotalSeq: %d SeqNum: %d", concatFlag, messageRefNum, totalNumSeg, numSeg);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	strTemp.Format(L"MessageLength: %d", messageLength);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	strTemp.Format(L"message: %s", message);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	
	return TRUE;
}
BOOL CGobiApiWms::FuncReadCDMATextMsg(CParamList* pParams /*= NULL*/)
{
	ULONG messageIndex = 2;
	ULONG storageType = 0;

	ADDSTATUS(L"FuncReadCDMATextMsg", STATUSMSG_Send);

	ULONG    messageTag;
	ULONG    messageFormat;
	ULONG    rawLength = 177;
	BYTE     raw[177];

	const BYTE MAX_Name = 0xFF;
    TCHAR szStringU[MAX_Name] = L"";

	if (pParams)
	{
		storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
		messageIndex = _ttoi(pParams->GetValue(PARAM_MessageIndex));
	}

	ULONG nRet = GetSMS(storageType, messageIndex, &messageTag, &messageFormat, &rawLength, raw);

	CString strTemp;
	strTemp.Format(L"GetSMS()Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if(nRet != 0)
		return FALSE;

	if(messageFormat != 0)
	{
		ADDSTATUS(L"NON CDMA message index", STATUSMSG_Send);
		return FALSE;
	}

	switch(messageTag)
	{
	case 0:
		strTemp.Format(L"MessageTag: MT Read (%d)", messageTag);
		break;
	case 1:
		strTemp.Format(L"MessageTag: MT Unread (%d)", messageTag);
		break;
	case 2:
		strTemp.Format(L"MessageTag: MO Sent (%d)", messageTag);
		break;
	case 3:
		strTemp.Format(L"MessageTag: MO Draft (%d)", messageTag);
		break;
	default:
		strTemp.Format(L"MessageTag: Undefined (%d)", messageTag);
		break;
	}

ULONG messageID;
BYTE  replyAddrLength = 14;
CHAR  replyAddr[14];
BYTE  textMessageLength = 240;
WCHAR textMessage[240];
BYTE  priority = 0xFF;
BYTE  privacy = 0xFF;
BYTE  language = 0xFF;
BYTE  timeStamp[7];
BYTE  abValidity[7];
BYTE  relValidity = 0;
BYTE  displayMode = 0;
BOOL  userAcknowledgementReq = FALSE;
BOOL  readAcknowledgementReq = FALSE;
BYTE  alertPriority = 0xFF;




	// if read or unread message
	if(messageTag == 0 || messageTag == 1)
	{
		nRet = CDMADecodeMTTextMsg(rawLength,
				raw,
				&messageID,
				&replyAddrLength,
				replyAddr,
				&textMessageLength,
				textMessage,
				&priority,
				&privacy,
				&language,
				timeStamp,
				abValidity,
				&relValidity,
				&displayMode,
				&userAcknowledgementReq,
				&readAcknowledgementReq,
				&alertPriority);

		strTemp.Format(L"CDMADecodeMTTextMsg()  Result: %4d", nRet);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		if(nRet != 0)
		{
			return FALSE;
		}

		MultiByteToWideChar(CP_ACP, 0, replyAddr, -1, szStringU, MAX_Name);
		strTemp.Format(L"SendAddress: %s", szStringU);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		strTemp.Format(L"UserAck[%d] ReadAck[%d]", userAcknowledgementReq, readAcknowledgementReq );
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

		switch( timeStamp[1])
		{
		case 1:
			strTemp.Format(L"TimeStamp: 20%02d JAN %2d %02d:%02d:%02d %2d", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 2:
			strTemp.Format(L"TimeStamp: 20%02d FEB %2d %02d:%02d:%02d %2d", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 3:
			strTemp.Format(L"TimeStamp: 20%02d MAR %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 4:
			strTemp.Format(L"TimeStamp: 20%02d APR %2d %02d:%02d:%02d %2d", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 5:
			strTemp.Format(L"TimeStamp: 20%02d MAY %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 6:
			strTemp.Format(L"TimeStamp: 20%02d JUN %2d %02d:%02d:%02d %2d", timeStamp[0], timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 7:
			strTemp.Format(L"TimeStamp: 20%02d JULY %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 8:
			strTemp.Format(L"TimeStamp: 20%02d AUG %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 9:
			strTemp.Format(L"TimeStamp: 20%02d SEPT %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 10:
			strTemp.Format(L"TimeStamp: 20%02d OCT %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 11:
			strTemp.Format(L"TimeStamp: 20%02d NOV %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		case 12:
			strTemp.Format(L"TimeStamp: 20%02d DEC %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		default:
			if(timeStamp[0] == 0xFF && timeStamp[1] == 0xFF)
				strTemp.Format(L"TimeStamp: Unavailable");
			else
				strTemp.Format(L"TimeStamp: 20%02d Month[%d] %2d %02d:%02d:%02d %2d", timeStamp[0],  timeStamp[2], timeStamp[3], timeStamp[4], timeStamp[5],timeStamp[6]);
			break;
		}
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	}

		switch( abValidity[1])
		{
		case 1:
			strTemp.Format(L"Absolute Validity Period: 20%02d JAN %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 2:
			strTemp.Format(L"Absolute Validity Period: 20%02d FEB %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 3:
			strTemp.Format(L"Absolute Validity Period: 20%02d MAR %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 4:
			strTemp.Format(L"Absolute Validity Period: 20%02d APR %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 5:
			strTemp.Format(L"Absolute Validity Period: 20%02d MAY %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 6:
			strTemp.Format(L"Absolute Validity Period: 20%02d JUN %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 7:
			strTemp.Format(L"Absolute Validity Period: 20%02d JULY %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 8:
			strTemp.Format(L"Absolute Validity Period: 20%02d AUG %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 9:
			strTemp.Format(L"Absolute Validity Period: 20%02d SEPT %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 10:
			strTemp.Format(L"Absolute Validity Period: 20%02d OCT %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 11:
			strTemp.Format(L"Absolute Validity Period: 20%02d NOV %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		case 12:
			strTemp.Format(L"Absolute Validity Period: 20%02d DEC %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		default:
			if(abValidity[0] == 0xFF && abValidity[1] == 0xFF)
				strTemp.Format(L"Absolute Validity Period: Unavailable");
			else
				strTemp.Format(L"Absolute Validity Period: 20%02d Month[%d] %2d %02d:%02d:%02d %2d", abValidity[0], abValidity[2], abValidity[3], abValidity[4], abValidity[5],abValidity[6]);
			break;
		}
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if(relValidity == 0xFF)
	{
		strTemp.Format(L"Relative Validity Period: Unavailable");
	}
	else
	{
		strTemp.Format(L"Relative Validity Period: %d", relValidity);
	}
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	switch(priority)
	{
	case 0:
		strTemp.Format(L"Priority: Normal");
		break;
	case 1:
		strTemp.Format(L"Priority: Interative");
		break;
	case 2:
		strTemp.Format(L"Priority: Urgent");
		break;
	case 3:
		strTemp.Format(L"Priority: Emergency");
		break;
	case 255:
		strTemp.Format(L"Priority: Unavailable");
		break;

	default:
		strTemp.Format(L"Priority: UNKNOWN[%d]", priority);
	}
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	switch(alertPriority)
	{
	case 0:
		strTemp.Format(L"Alert: Default");
		break;
	case 1:
		strTemp.Format(L"Alert: Low");
		break;
	case 2:
		strTemp.Format(L"Alert: Medium");
		break;
	case 3:
		strTemp.Format(L"Alert: High");
		break;
	case 255:
		strTemp.Format(L"Alert: Unavailable");
		break;

	default:
		strTemp.Format(L"Alert: UNKNOWN[%d]", alertPriority);
	}
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	strTemp.Format(L"textMessageLength: %d", textMessageLength);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	strTemp.Format(L"textMessage: %s", textMessage);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	
	return TRUE;
}
BOOL CGobiApiWms::FuncStoreWCDMATextMsg(CParamList* pParams /*= NULL*/)
{
	BYTE pduListSize = 5;
	BYTE pduList[885];
	CHAR scAddress[] = "+17057969300";
	CHAR mtAddress[14];
	BOOLEAN rejectDuplicates;
	BOOLEAN statusReportReq;
	BOOLEAN replyPath;
	BYTE    validityFormat;
	BYTE    validityPeriod[8];
	BYTE    messageRefNum = 0;
	BYTE    encodingAlphabet = 0;
	ULONG   textLength = 12;
	WCHAR   text[800];
	BYTE    pduLength = 0;
	BYTE*   pPdu;
	int     i;

	ULONG messageIndex;
	ULONG storageType = 0;

	ADDSTATUS(L"FuncStoreWCDMATextMsg", STATUSMSG_Send);

	if (pParams)
	{
		storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
		rejectDuplicates = (0==_ttoi(pParams->GetValue(PARAM_RejectDuplicates)))?FALSE:TRUE;
		statusReportReq = (0==_ttoi(pParams->GetValue(PARAM_StatusReportReq)))?FALSE:TRUE;
		replyPath = (0==_ttoi(pParams->GetValue(PARAM_ReplyPath)))?FALSE:TRUE;

		// Get message payload and convert to ASCII
		CW2A buf(pParams->GetValue(PARAM_ValidityPeriod));

		// convert ASCII hex string to binary
		int iIndex = 0;

		for(int i=0; i<(int)strlen(buf); i+=2) 
		{
			validityPeriod[iIndex] = hex2bin(buf[i], buf[i+1]);
			iIndex++;
		}

		validityFormat = (BYTE)_ttoi(pParams->GetValue(PARAM_ValidityFormat));

		messageRefNum = (BYTE)_ttoi(pParams->GetValue(PARAM_MsgRefNum));
		encodingAlphabet = (BYTE)_ttoi(pParams->GetValue(PARAM_EncodingAlphabet));
		strcpy_s(mtAddress, 14, CW2A(pParams->GetValue(PARAM_DestinationAddress)));
		wcscpy_s(text, 800, (pParams->GetValue(PARAM_TextMessage)));
		textLength = (ULONG)wcslen(text);
	}

	ULONG nRet = WCDMAEncodeMOTextMsg(&pduListSize, pduList, 
		messageRefNum, mtAddress, textLength, text, 
		scAddress, &rejectDuplicates, 
		&statusReportReq, &replyPath,
		&validityFormat, validityPeriod, 
		&encodingAlphabet);

	CString strTemp;
	strTemp.Format(L"WCDMAEncodeMOTextMsg()  Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if(nRet == 0)
	{
		pduLength = pduList[0];
		pPdu      = &pduList[1];

		for(i = 0; i < pduListSize; i++)
		{
			nRet = SaveSMS(storageType, 6, pduLength, pPdu, &messageIndex);

			strTemp.Format(L"SaveSMS()  Result: %4d  Segment[%d] Index[%d]", nRet, i+1, messageIndex);
			ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

			pduLength = *(pPdu + 176);
			pPdu      = pPdu + 177;
		}
	}
	else if(nRet == 897)
	{
		strTemp.Format(L"SWI_ERR_API_IMPOSSIBLE_ENCODING possible encoding: %d", encodingAlphabet);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	}


	return TRUE;
}
BOOL CGobiApiWms::FuncSendWCDMATextMsg(CParamList* pParams /*= NULL*/)
{
	BYTE pduListSize = 5;
	BYTE pduList[885];
	CHAR scAddress[] = "+17057969300";
	CHAR mtAddress[14];
	BOOLEAN rejectDuplicates;
	BOOLEAN statusReportReq;
	BOOLEAN replyPath;
	BYTE    validityFormat;
	BYTE    validityPeriod[7];
	BYTE    messageRefNum = 0;
	BYTE    encodingAlphabet = 0;
	ULONG   textLength = 12;
	WCHAR   text[800];
	BYTE    pduLength;
	BYTE*   pPdu;
	int     i;
	ULONG   storageType;
	ULONG   failureCode = 0;

	ADDSTATUS(L"FuncSendWCDMATextMsg", STATUSMSG_Send);

	if (pParams)
	{
		storageType = _ttoi(pParams->GetValue(PARAM_StorageType));
		rejectDuplicates = (0==_ttoi(pParams->GetValue(PARAM_RejectDuplicates)))?FALSE:TRUE;
		statusReportReq = (0==_ttoi(pParams->GetValue(PARAM_StatusReportReq)))?FALSE:TRUE;
		replyPath = (0==_ttoi(pParams->GetValue(PARAM_ReplyPath)))?FALSE:TRUE;

		// Get message payload and convert to ASCII
		CW2A buf(pParams->GetValue(PARAM_ValidityPeriod));

		// convert ASCII hex string to binary
		int iIndex = 0;

		for(int i=0; i<(int)strlen(buf); i+=2) 
		{
			validityPeriod[iIndex] = hex2bin(buf[i], buf[i+1]);
			iIndex++;
		}

		validityFormat = (BYTE)_ttoi(pParams->GetValue(PARAM_ValidityFormat));
		messageRefNum = (BYTE)_ttoi(pParams->GetValue(PARAM_MsgRefNum));
		encodingAlphabet = (BYTE)_ttoi(pParams->GetValue(PARAM_EncodingAlphabet));
		strcpy_s(mtAddress, 14, CW2A(pParams->GetValue(PARAM_DestinationAddress)));
		wcscpy_s(text, 800, (pParams->GetValue(PARAM_TextMessage)));
		textLength = (ULONG)wcslen(text);
	}

	ULONG nRet = WCDMAEncodeMOTextMsg(&pduListSize, pduList, 
		messageRefNum, mtAddress, textLength, text,
		scAddress, &rejectDuplicates, 
		&statusReportReq, &replyPath,
		&validityFormat, validityPeriod, 
		&encodingAlphabet);

	CString strTemp;
	strTemp.Format(L"WCDMAEncodeMOTextMsg()  Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if(nRet == 0)
	{
		pduLength = pduList[0];
		pPdu      = &pduList[1];

		for(i = 0; i < pduListSize; i++)
		{
			nRet = SendSMS(6, pduLength, pPdu, 0, &failureCode); //not for multi-SMS

			strTemp.Format(L"SendSMS()  Result: %4d  Segment[%d] failure[%d]", nRet, i+1, failureCode);
			ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

			pduLength = *(pPdu + 176);
			pPdu      = pPdu + 177;
		}
	}
	else if(nRet == 897)
	{
		strTemp.Format(L"SWI_ERR_API_IMPOSSIBLE_ENCODING possible encoding: %d", encodingAlphabet);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	}

	return TRUE;
}
BOOL CGobiApiWms::FuncSendCDMATextMsg(CParamList* pParams /*= NULL*/)
{
	BYTE pduListSize = 240;
	BYTE pduList[240];
	CHAR mtAddress[14];
	BYTE    validityFormat;
	BYTE    validityPeriod[7];
	BYTE    messageRefNum = 0;
	BYTE    encodingAlphabet = 0;
	ULONG   textLength = 12;
	WCHAR   text[800];
	ULONG   storageType;
	ULONG   failureCode = 0;

	ADDSTATUS(L"FuncSendCDMATextMsg", STATUSMSG_Send);
	UNREFERENCED_PARAMETER(validityFormat);

	if (pParams)
	{
		storageType = _ttoi(pParams->GetValue(PARAM_StorageType));

		// Get message payload and convert to ASCII
		CW2A buf(pParams->GetValue(PARAM_ValidityPeriod));

		// convert ASCII hex string to binary
		int iIndex = 0;

		for(int i=0; i<(int)strlen(buf); i+=2) 
		{
			validityPeriod[iIndex] = hex2bin(buf[i], buf[i+1]);
			iIndex++;
		}

		messageRefNum = (BYTE)_ttoi(pParams->GetValue(PARAM_MsgRefNum));
		encodingAlphabet = (BYTE)_ttoi(pParams->GetValue(PARAM_EncodingAlphabet));
		strcpy_s(mtAddress, 14, CW2A(pParams->GetValue(PARAM_DestinationAddress)));
		wcscpy_s(text, 800, (pParams->GetValue(PARAM_TextMessage)));
		textLength = (ULONG)wcslen(text);
	}

	ULONG nRet = CDMAEncodeMOTextMsg(&pduListSize, pduList, 
		messageRefNum, mtAddress, NULL, textLength, text, NULL, NULL);

	CString strTemp;
	strTemp.Format(L"WCDMAEncodeMOTextMsg()  Result: %4d", nRet);
	ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);

	if(nRet == 0)
	{
		nRet = SendSMS(0, pduListSize, pduList, 0, &failureCode); //Not for multi-SMS

		strTemp.Format(L"SendSMS()  Result: %4d failure[%d]", nRet, failureCode);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	}
	else if(nRet == 897)
	{
		strTemp.Format(L"SWI_ERR_API_IMPOSSIBLE_ENCODING possible encoding: %d", encodingAlphabet);
		ADDSTATUS(strTemp,(nRet==0)?STATUSMSG_Receive:STATUSMSG_Error);
	}

	return TRUE;
}

// Callbacks

static void SWICALLBACK NewSMSCallback(ULONG nStorageType, ULONG nMessageIndex)
{
	CString strTemp;
	strTemp.Format(L"New SMS message: StorageType %d, MessageIndex %d", nStorageType, nMessageIndex);
	ADDSTATUS(strTemp, STATUSMSG_Notif);  
}

BOOL CGobiApiWms::FuncSetNewSmsCallback(CParamList* pParams /*= NULL*/)
{
	ADDSTATUS(L"FuncSetNewSmsCallback", STATUSMSG_Send);

	ULONG ret = 0;

	if (0 != _ttoi(pParams->GetValue(PARAM_Enable)))
	{
		ret = SetNewSMSCallback(NewSMSCallback);
	}
	else
	{
		ret = SetNewSMSCallback(NULL);
	}

	CString strTemp;
	strTemp.Format(L"Result: %d", ret);

	return ADDSTATUS(strTemp, (0==ret)?STATUSMSG_Receive:STATUSMSG_Error);
}

BOOL CGobiApiWms::FuncSetSMSProtocol( CParamList * pParams /* = NULL */ )
{
    ADDSTATUS( L"FuncSetSMSProtocol", STATUSMSG_Send );

    BOOL bRet = FALSE;
    BYTE Protocol = 0;

    if (pParams)
    {
        Protocol = (BYTE)_ttoi( pParams->GetValue( PARAM_MessageProtocol ) );
    }

    ULONG nRet = SetSMSProtocol( Protocol );

    CString strTemp;
    strTemp.Format( L"Result: %d", nRet );
    ADDSTATUS( strTemp, STATUSMSG_Receive );

    if (!nRet)
    {
        bRet = TRUE;
    }

    return bRet;
}

BOOL CGobiApiWms::FuncGetSMSProtocol( CParamList * pParams /* = NULL */ )
{
    UNREFERENCED_PARAMETER(pParams);
    ADDSTATUS( L"FuncGetSMSProtocol", STATUSMSG_Send );

    BOOL bRet = FALSE;
    BYTE SMSMessageProtocol = 0;

    ULONG nRet = GetSMSProtocol( &SMSMessageProtocol );

    CString strTemp;
    strTemp.Format( L"Result: %d", nRet );
    ADDSTATUS( strTemp, STATUSMSG_Receive );

    if (!nRet)
    {
        strTemp.Format( L"SMS Protocol: %d", SMSMessageProtocol );
        ADDSTATUS( strTemp, STATUSMSG_Receive );

        bRet = TRUE;
    }

    return bRet;
}