📄 smsmodem.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(¶m[0])) && (tmNow=CTime::GetCurrentTime())-tmOrg<1);
Sleep(100);
//等候发送短信1秒
if ( bFlag )
//有待发短消息,先发短信
{
gsmSendMessage(¶m[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(¶m[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(¶m[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 + -