⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsmodem.cpp

📁 用VC写的动态链接库源程序
💻 CPP
字号:
// SmsModem.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "SmsModem.h"
//#include "comutil.h"
//#include <comdef.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CSmsModemApp

BEGIN_MESSAGE_MAP(CSmsModemApp, CWinApp)
	//{{AFX_MSG_MAP(CSmsModemApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSmsModemApp construction

CSmsModemApp::CSmsModemApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
	m_nSendIn = 0;
	m_nSendOut = 0;
	m_nRecvIn = 0;
	m_nRecvOut = 0;
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CSmsModemApp object

CSmsModemApp theApp;
char	strSmsc[20];
BOOL flagModem = FALSE;

//extern "C" BOOL PASCAL EXPORT OpenModem(BSTR sPort,BSTR sSmsc)
BOOL _stdcall OpenModem(BSTR sPort,BSTR sSmsc)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if ( flagModem ) 
		return TRUE;

	if ( strlen((LPCSTR)sSmsc) > sizeof(strSmsc) ) 
		return FALSE;
	memset(strSmsc,0,sizeof(strSmsc));
	strcpy(strSmsc,"86");
	strcpy(strSmsc+2,(LPCSTR)sSmsc);

	if ( !OpenComm((LPCSTR)sPort) )
		return FALSE;
	if ( !gsmInit() )
		return FALSE;

	theApp.Init();
	flagModem = TRUE;
	return TRUE;
}

//extern "C" BOOL PASCAL EXPORT CloseModem()
BOOL _stdcall CloseModem()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if ( !flagModem ) 
		return TRUE;

	theApp.UnInit();
	flagModem = FALSE;
	return TRUE;
}

//extern "C" BOOL PASCAL EXPORT SendMsg(BSTR UserNumber,BSTR UserData)
BOOL _stdcall SendMsg(BSTR UserNumber,BSTR UserData)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if ( !flagModem ) 
		return FALSE;

	WCHAR wchar[1024];
	if ( MultiByteToWideChar(CP_ACP, 0, (LPCSTR)UserData, -1, wchar, 1024) > 70 )
		return FALSE;

	SM_PARAM SmParam;

	memset(&SmParam, 0, sizeof(SM_PARAM));
	strcpy(SmParam.SCA, strSmsc);
	strcpy(SmParam.TPA, (LPCSTR)UserNumber);
	strcpy(SmParam.TP_UD, (LPCSTR)UserData);
	SmParam.TP_PID = 0;
	SmParam.TP_DCS = GSM_UCS2;

	return theApp.PutSendMessage(&SmParam);		
}

//extern "C" BOOL PASCAL EXPORT RecvMsg(BSTR UserNumber,BSTR UserData)
BOOL _stdcall RecvMsg(BSTR UserNumber,LPLONG LenNumber,BSTR UserData,LPLONG LenData)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if ( !flagModem ) 
		return FALSE;
	
	SM_PARAM SmParam;
	if ( !theApp.GetRecvMessage(&SmParam) )
		return FALSE;

	if ( strlen(SmParam.TPA) > *LenNumber || strlen(SmParam.TP_UD) > *LenData )
		return FALSE;
//	memcpy((LPSTR)UserNumber , SmParam.TPA , sizeof(SmParam.TPA) );
//	memcpy((LPSTR)UserData , SmParam.TP_UD , sizeof(SmParam.TP_UD) );
	
/*	BSTR bstr;	
	bstr = _com_util::ConvertStringToBSTR(SmParam.TPA);
	strcpy( (LPSTR)UserNumber , (LPSTR)bstr );

	bstr = _com_util::ConvertStringToBSTR(SmParam.TP_UD);
	strcpy( (LPSTR)UserData , (LPSTR)bstr );
*/	
	WCHAR wchar[1024];
	*LenNumber=::MultiByteToWideChar(CP_ACP, 0, SmParam.TPA, -1, wchar, 1024)-1;
	*LenData=::MultiByteToWideChar(CP_ACP, 0, SmParam.TP_UD, -1, wchar, 1024)-1;
//	*LenNumber = strlen(SmParam.TPA) ;
//	*LenData = strlen(SmParam.TP_UD) ;
	if ( SmParam.TPA[0] == '8' && SmParam.TPA[1] == '6' )
	{
		strcpy( (LPSTR)UserNumber , SmParam.TPA+2 );
		*LenNumber = *LenNumber - 2 ;
	}
	else
		strcpy( (LPSTR)UserNumber , SmParam.TPA );
	strcpy( (LPSTR)UserData , SmParam.TP_UD );

	return TRUE;	
}

BOOL _stdcall Test(BSTR str)
{
	//AFX_MANAGE_STATE(AfxGetStaticModuleState());

	char a[] = "中文";
//	WCHAR wchar[1024];
//	int nCount = ::MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)*str, -1, wchar, 1024);	
//	nCount = strlen((LPCTSTR)str);
	strcpy((LPSTR)str,a);
	
//	*str = ::SysAllocString(L"中文");
	return TRUE;
}

BOOL CSmsModemApp::PutSendMessage(SM_PARAM *pparam)
{
	BOOL fSuccess = FALSE;

	EnterCriticalSection(&m_csSend);

	if ( !(m_nSendIn+1 == m_nSendOut || (m_nSendIn == MAX_SM_SEND && m_nSendOut == 0)) )
	{
		memcpy(&m_SmSend[m_nSendIn], pparam, sizeof(SM_PARAM));

		m_nSendIn++;
		if (m_nSendIn >= MAX_SM_SEND)  m_nSendIn = 0;

		fSuccess = TRUE;
	}

	LeaveCriticalSection(&m_csSend);

	return fSuccess;
}

BOOL CSmsModemApp::GetRecvMessage(SM_PARAM *pparam)
{
	BOOL fSuccess = FALSE;

	EnterCriticalSection(&m_csRecv);

	if (m_nRecvOut != m_nRecvIn)
	{
		memcpy(pparam, &m_SmRecv[m_nRecvOut], sizeof(SM_PARAM));

		m_nRecvOut++;
		if (m_nRecvOut >= MAX_SM_RECV)  m_nRecvOut = 0;

		fSuccess = TRUE;
	}

	LeaveCriticalSection(&m_csRecv);

	return fSuccess;
}

BOOL CSmsModemApp::GetSendMessage(SM_PARAM *pparam)
{
	BOOL fSuccess = FALSE;
	
	EnterCriticalSection(&m_csSend);

	if (m_nSendOut != m_nSendIn)
	{
		memcpy(pparam, &m_SmSend[m_nSendOut], sizeof(SM_PARAM));

		m_nSendOut++;
		if (m_nSendOut >= MAX_SM_SEND)  m_nSendOut = 0;

		fSuccess = TRUE;
	}

	LeaveCriticalSection(&m_csSend);

	return fSuccess;
}

BOOL CSmsModemApp::PutRecvMessage(SM_PARAM *pparam)
{
	BOOL fSuccess = FALSE;

	EnterCriticalSection(&m_csRecv);

	if ( !(m_nRecvIn+1 == m_nRecvOut || (m_nRecvIn == MAX_SM_RECV && m_nRecvOut == 0)) )
	{
		memcpy(&m_SmRecv[m_nRecvIn], pparam, sizeof(SM_PARAM));
	
		m_nRecvIn++;
		if (m_nRecvIn >= MAX_SM_RECV)  m_nRecvIn = 0;

		fSuccess = TRUE;
	}
	
	LeaveCriticalSection(&m_csRecv);

	return fSuccess;
}

UINT CSmsModemApp::SmThread(LPVOID lParam)
{
	CSmsModemApp* p=(CSmsModemApp *)lParam;	// this
	BOOL bFlag;
	int nMsg;				// 收到短消息条数
	int nDelete;			// 目前正在删除的短消息编号
	SM_BUFF buff;			// 接收短消息列表的缓冲区
	SM_PARAM param[256];	// 发送/接收短消息缓冲区
	CTime tmOrg, tmNow;		// 上次和现在的时间,计算超时用
	enum {
		stBeginRest,				// 开始休息/延时
		stContinueRest,				// 继续休息/延时
		stSendMessageRequest,		// 发送短消息
		stSendMessageResponse,		// 读取短消息列表到缓冲区
		stSendMessageWaitIdle,		// 发送不成功,等待GSM就绪
		stReadMessageRequest,		// 发送读取短消息列表的命令
		stReadMessageResponse,		// 读取短消息列表到缓冲区
		stDeleteMessageRequest,		// 删除短消息
		stDeleteMessageResponse,	// 删除短消息
		stDeleteMessageWaitIdle,	// 删除不成功,等待GSM就绪
		stExitThread				// 退出
	} nState;				// 处理过程的状态

	// 初始状态
	nState = stBeginRest;

	// 发送和接收处理的状态循环
	while (nState != stExitThread)
//	while (WaitForSingleObject(p->m_hKillThreadEvent, 20) == WAIT_OBJECT_0)
	{
		tmOrg = CTime::GetCurrentTime();
		while (!(bFlag=p->GetSendMessage(&param[0])) && (tmNow=CTime::GetCurrentTime())-tmOrg<1);
			Sleep(100);
		//等候发送短信1秒
			
		if ( bFlag )
		//有待发短消息,先发短信
		{
			gsmSendMessage(&param[0]);
			memset(&buff, 0, sizeof(buff));
			tmOrg = CTime::GetCurrentTime();
			Sleep(100);

			while ( gsmGetResponse(&buff)!=GSM_OK && (tmNow=CTime::GetCurrentTime())-tmOrg<10 )
				Sleep(100);
			//等候发送10秒
		}
		else
		//没有待发短消息,就收短信
		{
			gsmReadMessageList();
			memset(&buff, 0, sizeof(buff));
			tmOrg = CTime::GetCurrentTime();
			Sleep(100);

			while ( (nMsg=gsmGetResponse(&buff))!=GSM_OK && (tmNow=CTime::GetCurrentTime())-tmOrg<20 )
				Sleep(50);
			//等候接受20秒
			if ( nMsg==GSM_OK )
			//成功接受
			{
				nMsg = gsmParseMessageList(param, &buff);
				if (nMsg > 0)
				{
					for ( nDelete=0 ; nDelete < nMsg ; nDelete++ )
						if ( !(bFlag=p->PutRecvMessage(&param[nDelete])) )
							bFlag=bFlag;
					for ( nDelete-- ; nDelete >= 0 ; nDelete-- )
					{
						gsmDeleteMessage(param[nDelete].index);
						memset(&buff, 0, sizeof(buff));
						tmOrg = CTime::GetCurrentTime();
						Sleep(100);

						while ( gsmGetResponse(&buff)!=GSM_OK && (tmNow=CTime::GetCurrentTime())-tmOrg< 5 )
							Sleep(100);
					}
				}
			}
		}
/*
//开始		
		switch(nState)
		{
			case stBeginRest:
//				TRACE("State=stBeginRest\n");
				tmOrg = CTime::GetCurrentTime();
				nState = stContinueRest;
				break;

			case stContinueRest:
//				TRACE("State=stContinueRest\n");
				Sleep(300);
				tmNow = CTime::GetCurrentTime();
				if (p->GetSendMessage(&param[0]))
				{
					nState = stSendMessageRequest;	// 有待发短消息,就不休息了
				}
				else if (tmNow - tmOrg >= 5)		// 待发短消息队列空,休息5秒
				{
					nState = stReadMessageRequest;	// 转到读取短消息状态
				}
				break;

			case stReadMessageRequest:
//				TRACE("State=stReadMessageRequest\n");
				gsmReadMessageList();
				memset(&buff, 0, sizeof(buff));
				tmOrg = CTime::GetCurrentTime();
				nState = stReadMessageResponse;
				break;

			case stReadMessageResponse:
//				TRACE("State=stReadMessageResponse\n");
				Sleep(100);
				tmNow = CTime::GetCurrentTime();
				switch (gsmGetResponse(&buff))
				{
					case GSM_OK: 
//						TRACE("  GSM_OK %d\n", tmNow - tmOrg);
						nMsg = gsmParseMessageList(param, &buff);
						if (nMsg > 0)
						{
// ???							p->PutRecvMessage(param, nMsg);
							nDelete = 0;
							nState = stDeleteMessageRequest;
						}
						else
						{
							nState = stBeginRest;
						}
						break;
					case GSM_ERR:
//						TRACE("  GSM_ERR %d\n", tmNow - tmOrg);
						nState = stBeginRest;
						break;
					default:
//						TRACE("  GSM_WAIT %d\n", tmNow - tmOrg);
						if (tmNow - tmOrg >= 15)		// 15秒超时
						{
//							TRACE("  Timeout!\n");
							nState = stBeginRest;
						}
				}
				break;

			case stDeleteMessageRequest:
//				TRACE("State=stDeleteMessageRequest\n");
				if (nDelete < nMsg)
				{
					gsmDeleteMessage(param[nDelete].index);
					memset(&buff, 0, sizeof(buff));
					tmOrg = CTime::GetCurrentTime();
					nState = stDeleteMessageResponse;
				}
				else
				{
					nState = stBeginRest;
				}
				break;

			case stDeleteMessageResponse:
//				TRACE("State=stDeleteMessageResponse\n");
				Sleep(100);
				tmNow = CTime::GetCurrentTime();
				switch (gsmGetResponse(&buff))
				{
					case GSM_OK: 
//						TRACE("  GSM_OK %d\n", tmNow - tmOrg);
						nDelete++;
						nState = stDeleteMessageRequest;
						break;
					case GSM_ERR:
//						TRACE("  GSM_ERR %d\n", tmNow - tmOrg);
						nState = stDeleteMessageWaitIdle;
						break;
					default:
//						TRACE("  GSM_WAIT %d\n", tmNow - tmOrg);
						if (tmNow - tmOrg >= 5)		// 5秒超时
						{
//							TRACE("  Timeout!\n");
							nState = stBeginRest;
						}
				}
				break;

			case stDeleteMessageWaitIdle:
//				TRACE("State=stDeleteMessageWaitIdle\n");
				Sleep(500);
				nState = stDeleteMessageRequest;		// 直到删除成功为止
				break;
		}
//结束
*/
		// 检测是否有关闭本线程的信号
		DWORD dwEvent = WaitForSingleObject(p->m_hKillThreadEvent, 20); //WAIT_OBJECT_0
		if (dwEvent == WAIT_OBJECT_0)  nState = stExitThread;
	}

	// 置该线程结束标志
	SetEvent(p->m_hThreadKilledEvent);

	return 0;
}

void CSmsModemApp::Init()
{
	m_hKillThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	m_hThreadKilledEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	InitializeCriticalSection(&m_csSend);
	InitializeCriticalSection(&m_csRecv);

	AfxBeginThread(SmThread, this, THREAD_PRIORITY_NORMAL);
}

void CSmsModemApp::UnInit()
{
	SetEvent(m_hKillThreadEvent);			// 发出关闭子线程的信号
	WaitForSingleObject(m_hThreadKilledEvent, INFINITE);	// 等待子线程关闭

	DeleteCriticalSection(&m_csSend);
	DeleteCriticalSection(&m_csRecv);

	CloseHandle(m_hKillThreadEvent);
	CloseHandle(m_hThreadKilledEvent);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -