📄 cmpp.cpp
字号:
goto RECV_EXIT;
}
if(dwRet != ntohl(sCmppMsg4Resp.sMsgHead.Total_Length))
{
goto RECV_EXIT;
}
}
break;
default:
goto RECV_EXIT;
}
}
}
pcCmpp->m_bIsRecvRun = false;
ATLTRACE("Recv退出!\n");
return 0;
RECV_EXIT:
pcCmpp->m_bIsRecvRun = false;
pcCmpp->Stop();
ATLTRACE("Recv退出!\n");
return 0;
}
long CCMPP::GetHostIP(char * pszIP)
{
long lError;
struct sockaddr_in sSockAddr;
struct hostent * psHostent;
DWORD dwAddr = 0;
char szIP[MAX_PATH], *pszAddr;
pszIP[0] = 0;
lError = gethostname(szIP, MAX_PATH);
if(lError)return lError;
psHostent = gethostbyname(szIP);
if(psHostent)
{
while(psHostent->h_addr_list[dwAddr])
{
memcpy(&(sSockAddr.sin_addr), psHostent->h_addr_list[dwAddr++], psHostent->h_length);
sSockAddr.sin_family = psHostent->h_addrtype;
pszAddr = inet_ntoa(sSockAddr.sin_addr);
strcat(pszIP, pszAddr);
strcat(pszIP, " ");
}
pszIP[strlen(pszIP) - 1] = 0;
lError = -((long)dwAddr);
}
else
{
dwAddr = inet_addr(szIP);
if(dwAddr == INADDR_NONE)
{
lError = ERR_SOCK_UNRESOLVE;
return lError;
}
sSockAddr.sin_addr.s_addr = dwAddr;
sSockAddr.sin_family = AF_INET;
pszAddr = inet_ntoa(sSockAddr.sin_addr);
strcpy(pszIP, pszAddr);
lError = -1;
}
return lError;
}
void CCMPP::SetReturnValue(VARIANT *pPara, long lPara)
{
if(pPara->vt & VT_BYREF)
{
switch(pPara->vt ^ VT_BYREF)
{
case VT_UI1:
case VT_I2:
case VT_I4:
*pPara->plVal = lPara;
break;
case VT_R4:
*pPara->pfltVal = (float)lPara;
break;
case VT_R8:
*pPara->pdblVal = lPara;
break;
case VT_BSTR:
char szValue[MAX_PATH];
itoa(lPara, szValue, 10);
*pPara->pbstrVal = A2BSTR(szValue);
break;
}
}
}
bool CCMPP::CheckTime(char * pszTime)
{
long lTime;
if(strlen(pszTime) == 12)
{
lTime = atol(pszTime + 2);
if(lTime >= 0101000000 && lTime <= 1231235959)
{
lTime = atol(pszTime + 4);
if(lTime >= 1000000 && lTime <= 31235959)
{
lTime = atol(pszTime + 6);
if(lTime >= 0 && lTime <= 235959)
{
lTime = atol(pszTime + 8);
if(lTime >= 0 && lTime <= 5959)
{
lTime = atol(pszTime + 10);
if(lTime >= 0 && lTime <= 59)
{
return true;
}
}
}
}
}
}
return false;
}
long CCMPP::Init(void)
{
if(m_bIsInit)
{
return ERR_INITED;
}
WSADATA wsaData;
//startup
if (WSAStartup(MAKEWORD(2,1), &wsaData) != 0)
{
return ERR_SOCK_START_FAIL;
}
return ERR_OK;
}
long CCMPP::Bind(BSTR bStrIP, short iPort, BSTR bStrSPID, BSTR bStrSharedSecret,BYTE bVersion)
{
struct
{
char Source_Addr[6];
BYTE bFill[9];
char szSharedSecret[MAX_PATH];
char szTimeStamp[11];
}sAuthenticatorICPContent;
bool bIsSocketValid = false;
CMD5 cMD5;
USES_CONVERSION;
SYSTEMTIME sSysTime4Local;
GetLocalTime(&sSysTime4Local);
DWORD dwTime = sSysTime4Local.wMonth * 100000000 +
sSysTime4Local.wDay * 1000000 +
sSysTime4Local.wHour * 10000 +
sSysTime4Local.wMinute * 100 +
sSysTime4Local.wSecond;
// plError = ERR_OK;
if(!m_bIsInit)
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_INIT_FAIL;
}
if(m_bIsBinded)
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_BINDED;
}
if(m_bIsBinding)
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_BINDING;
}
m_bIsBinding = true;
bIsSocketValid = true;
//create
m_sSocket4MT = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(m_sSocket4MT == INVALID_SOCKET)
{
// m_dwLastErr4Sys = GetLastError();
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_INIT_FAIL;
}
struct sockaddr_in sSockAddr4Dest;
DWORD dwRet;
char szPara[MAX_PATH];
//connect
strncpy(szPara, W2A(bStrIP), MAX_PATH);
dwRet = inet_addr(szPara);
if(dwRet == INADDR_NONE)
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_INVALID_IP;
}
BZERO(sSockAddr4Dest);
sSockAddr4Dest.sin_addr.S_un.S_addr = dwRet;
sSockAddr4Dest.sin_family = AF_INET;
if(!iPort)iPort = PORT_LONG_CONNECT;
sSockAddr4Dest.sin_port = htons(iPort);
dwRet = connect(m_sSocket4MT, (struct sockaddr*)&sSockAddr4Dest, sizeof(sSockAddr4Dest));
if(dwRet == SOCKET_ERROR)
{
// m_dwLastErr4Sys = GetLastError();
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_S_TIMEOUT;
}
//bind transmitter
BZERO(m_sCmppMsg);
m_sCmppMsg.sMsgHead.Total_Length = htonl(sizeof(_CMPP_HEAD) + sizeof(_CMPP_CONNECT));
m_sCmppMsg.sMsgHead.Command_ID = htonl(CMPP_CONNECT);
m_sCmppMsg.sMsgHead.Sequence_ID = htonl(++m_dwSequenceNO);
BZERO(sAuthenticatorICPContent);
sprintf(sAuthenticatorICPContent.szTimeStamp, "%02d%02d%02d%02d%02d",
sSysTime4Local.wMonth, sSysTime4Local.wDay, sSysTime4Local.wHour,
sSysTime4Local.wMinute, sSysTime4Local.wSecond);
// if(bStrSPID)strncpy(m_szSPID, W2A(bStrSPID), 6);
strcpy(m_sCmppMsg.uMsgBody.sMsgConnect.Source_Addr, W2A(bStrSPID));
strcpy(sAuthenticatorICPContent.Source_Addr, m_sCmppMsg.uMsgBody.sMsgConnect.Source_Addr);
if(bStrSharedSecret)
strncpy(sAuthenticatorICPContent.szSharedSecret, W2A(bStrSharedSecret), MAX_PATH);
if(strlen(sAuthenticatorICPContent.szSharedSecret) < MAX_PATH)
{
memcpy(sAuthenticatorICPContent.szSharedSecret +
strlen(sAuthenticatorICPContent.szSharedSecret),
sAuthenticatorICPContent.szTimeStamp, 11);
}
cMD5.MD5Update((unsigned char *)&sAuthenticatorICPContent,
sizeof(sAuthenticatorICPContent) - 11 - MAX_PATH
+ strlen(sAuthenticatorICPContent.szSharedSecret));
cMD5.MD5Final(m_sCmppMsg.uMsgBody.sMsgConnect.AuthenticatorICP);
m_sCmppMsg.uMsgBody.sMsgConnect.Version = bVersion;
m_sCmppMsg.uMsgBody.sMsgConnect.Timestamp = htonl(dwTime);
dwRet = send(m_sSocket4MT, (char *)&m_sCmppMsg, sizeof(_CMPP_HEAD) + sizeof(_CMPP_CONNECT), 0);
if(dwRet == SOCKET_ERROR)
{
// m_dwLastErr4Sys = GetLastError();
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_S_TIMEOUT;
}
if(dwRet != sizeof(_CMPP_HEAD) + sizeof(_CMPP_CONNECT))
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_S_FAIL;
}
//set option
fd_set sFDS4Read;
FD_ZERO(&sFDS4Read);
m_sTimeval4Timeout.tv_sec = m_lTimeout4Connect / 1000000;
m_sTimeval4Timeout.tv_usec = m_lTimeout4Connect % 1000000;
FD_SET(m_sSocket4MT, &sFDS4Read);
dwRet = select(0, &sFDS4Read, NULL, NULL, &m_sTimeval4Timeout);
if(dwRet == SOCKET_ERROR)
{
// m_dwLastErr4Sys = GetLastError();
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_SEL_FAIL;
}
if(!FD_ISSET(m_sSocket4MT, &sFDS4Read))
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_R_TIMEOUT;
}
dwRet = recv(m_sSocket4MT, (char *)&m_sCmppMsg, sizeof(_CMPP), 0);
if(dwRet == SOCKET_ERROR)
{
// m_dwLastErr4Sys = GetLastError();
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_R_TIMEOUT;
}
if(dwRet != sizeof(_CMPP_HEAD) + sizeof(_CMPP_CONNECT_REP))
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_R_FAIL;
}
if(!(dwRet == ntohl(m_sCmppMsg.sMsgHead.Total_Length) &&
ntohl(m_sCmppMsg.sMsgHead.Command_ID) == CMPP_CONNECT_REP &&
ntohl(m_sCmppMsg.sMsgHead.Sequence_ID) == m_dwSequenceNO))
{
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return ERR_SOCK_R_FAIL;
}
// m_dwCurErr4TCP = m_sCmppMsg.uMsgBody.sMsgConnectRep.Status;
if(m_sCmppMsg.uMsgBody.sMsgConnectRep.Status)
{
// plError = ERR_BIND_FAIL;
m_dwLastTime4TCPErr = dwTime;
if(bIsSocketValid)
{
closesocket(m_sSocket4MT);
}
m_bIsBinding = false;
return m_sCmppMsg.uMsgBody.sMsgConnectRep.Status;
}
//bind receiver
m_bIsEnableRun = true;
DWORD dwThreadID;
HANDLE hThread = CreateThread(0, 0, ThreadCMPPSend, (void *)this, 0, &dwThreadID);
CloseHandle(hThread);
hThread = CreateThread(0, 0, ThreadCMPPRecv, (void *)this, 0, &dwThreadID);
CloseHandle(hThread);
m_bIsBinded = true;
m_bIsBinding = false;
return ERR_OK;
}
long CCMPP::GetWaitSendCount()
{
long lCount = 0;
for(int i = 0; i < MAX_BUF_SIZE; i++)
{
if(m_sSMBuf[i].bFlag != BUF_VALID)
{
lCount++;
}
}
return lCount;
}
void CCMPP::AddPreFix(const char* pszMobileCode, const char* pszPreFix, char *pszResult)
{
pszResult[0] = '\0';
if( !strlen(pszMobileCode) )
{//空串
return ;
}
if(IsMobileIDWithPreFix(pszMobileCode, pszPreFix))
{//有前缀,不用加
strcpy(pszResult, pszMobileCode);
}else
{//无前缀,要加上
strcpy(pszResult, pszPreFix);
strcat(pszResult, pszMobileCode);
}
}
//检查手机号码pszMobileID是否带有pszPreFix前缀
BOOL CCMPP::IsMobileIDWithPreFix(const char* pszMobileID, const char* pszPreFix)
{
if(strlen(pszMobileID) < strlen(pszPreFix))
{//手机号码没有前缀长,则肯定不会“含有”前缀
return FALSE;
}
for(UINT i = 0; i < strlen(pszPreFix); i++)
{
if(pszMobileID[i] != pszPreFix[i])
{
return FALSE;
}
}
return TRUE;
}
bool CCMPP::AddMobileID(BSTR bStrMobileID)
{
USES_CONVERSION;
char szSeps[] = "| ,\t\n";
char *pcPos;
DWORD i = 0;
pcPos = strtok(W2A(bStrMobileID), szSeps);
while(pcPos)
{
i++;
pcPos = strtok(NULL, szSeps);
}
if(((ULONG)(MAX_BUF_SIZE - GetWaitSendCount())) < (i / m_lSendMaxNumPerPk + 1))
return false;
pcPos = strtok(W2A(bStrMobileID), szSeps);
while(pcPos)
{
if(m_lBufIdx4MulSM > 0)
{
if(GetWaitSendCount() >= MAX_BUF_SIZE)return false;
//从Buffer中取出一个空位置
// if(m_cQueueEmpty.Out((int*)(&m_lBufIdx4MulSM)))
{
m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.Pk_total = 1;
m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.Pk_number = 1;
//是否要求返回状态确认报告(0--不需要,1--需要,2--产生SMC话单
//(该MT仅供网关计费使用 不发送给目的终端)
m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.Reg_Delivery = m_bRegDeliveryFlag;
m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.Msg_level = m_bPriority;//信息级别
strcpy(m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.Service_id, m_szServiceType);//业务类型
//计费用户类型字段,0:对目的终端MSISDN计费;1:对源终端MSISDN计费;
//2:对SP计费;3:表示本字段无效,对谁计费参见Fee_terminal_id字段。
m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.Fee_UserType = m_bFeeUserType;
//OK!下面代码行:strcpy(..)将要把一个手机号码放入包中,在放入之前,加上前缀
//加上前缀(如果需要)后的手机号码
char szFee_terminal_idWithPreFix[21 * 2 + 1];
AddPreFix(m_szFeeMobileID, m_szMobileIDFix, szFee_terminal_idWithPreFix);
if(strlen(szFee_terminal_idWithPreFix) > 21)
{
return false;
}
//被计费用户的号码(如本字节填空,则表示本字段无效,
//对谁计费参见Fee_UserType字段。本字段与Fee_UserType字段互斥)
strcpy(m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.Fee_terminal_id, szFee_terminal_idWithPreFix);
//GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.9
m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.TP_pid = m_bTPpid;
//GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
m_sSMBuf[m_lBufIdx4MulSM].sCmppMsg.uMsgBody
.sMsgSubmit.TP_udhi = m_bTPudhi;
//信息格式 0:ASCII串 3:短信写卡操作
//4:二进制信息 8:UCS2编码15:含GB汉字 。。。。。。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -