www.pudn.com > xltsm.rar > cngp_api.cpp
#include "StdAfx.h" #include#include "smei.h" #include "MD5CheckSum.h" static SOCKET g_sktDeliver = INVALID_SOCKET; static BOOL g_bLogin = FALSE; /* static char g_szServerIP[16]="202.108.250.176"; // CNGP服务器地址 static int g_nServerPort = 9890; // CNGP端口(单位:ms) static int g_nTimeOut = 5000; // CNGP超时时间(单位:ms) static char g_szUser[11] = "Bjzhx"; // CNGP登录名 static char g_szPwd[33] = "1234"; // CNGP登录密码 */ int GenerateSequenceId() { static int nSeq = 1; char sSequenceId[11]; sprintf(sSequenceId, "%s%02d", CTime::GetCurrentTime().Format("%m%d%H%M"), nSeq++); if (nSeq >= 100) nSeq = 1; return atol(sSequenceId); } int _recvwait(SOCKET s, char* lpBuf, int cbBuf, int nTimeOut) { int nResult, nRecvBytes; for (nRecvBytes = 0; nRecvBytes < cbBuf; nRecvBytes += nResult) { fd_set readfds; timeval tv = {nTimeOut, 0}; FD_ZERO(&readfds); FD_SET(s, &readfds); nResult = select(0, &readfds, NULL, NULL, &tv); if (nResult == SOCKET_ERROR){ printf("\nselect() failed, error code: %d\n", WSAGetLastError()); return SP_ERROR_SOCKET_SELECTFAILED; } if (nResult == 0) return SP_ERROR_SOCKET_RECVTIMEOUT; nResult = recv(s, lpBuf + nRecvBytes, cbBuf - nRecvBytes, 0); if (nResult == SOCKET_ERROR){ printf("\nrecv() failed, error code: %d\n", WSAGetLastError()); return SP_ERROR_SOCKET_RECVERROR; } if (nResult == 0) return SP_ERROR_SOCKET_RECVERROR; // 多有可能是对方挂断了连接 } return SP_ERROR_OK; } int _sendcmd(SOCKET s, unsigned int nTotalLength, unsigned int nCommandId, unsigned int nCommandStatus, unsigned int nSequenceId, void * lpvData, int lenData) { int r; CNGP_HEAD head; head.nTotalLength = htonl(nTotalLength); head.nCommandId = htonl(nCommandId); head.nCommandStatus = htonl(nCommandStatus); head.nSequenceId = htonl(nSequenceId); r = send(s, (char*)&head, sizeof(head), 0); if (r < 0) return SP_ERROR_SOCKET_SENDERROR; if (r != sizeof(head)) return SP_ERROR_SOCKET_SENDTIMEOUT; if (lpvData != NULL && lenData > 0){ _ASSERT (lenData == (int)nTotalLength - (int)sizeof(head)); r = send(s, (char*)lpvData, lenData, 0); if (r < 0) return SP_ERROR_SOCKET_SENDERROR; if (r != lenData) return SP_ERROR_SOCKET_SENDTIMEOUT; } return SP_ERROR_OK; } int _recvresult(SOCKET s, CNGP_HEAD* phead, LPVOID lpBody, int cbBody) { int r, nRest; _ASSERT(phead != NULL); r = _recvwait(s, (char*)phead, sizeof(CNGP_HEAD), CNGP_RECV_TIMEOUT); if (r != SP_ERROR_OK){ printf("\nCNGP head cannot be received Successfully due to failure of _recvresult(). It returns a code of %d.\n", r); return r; } phead->nTotalLength = ntohl(phead->nTotalLength); phead->nCommandId = ntohl(phead->nCommandId); phead->nCommandStatus = ntohl(phead->nCommandStatus); phead->nSequenceId = ntohl(phead->nSequenceId); nRest = phead->nTotalLength - sizeof(CNGP_HEAD); if (nRest > cbBody) return SP_ERROR_OVERFLOW; if (lpBody != NULL && cbBody > 0) { memset(lpBody, 0, cbBody); if (nRest > 0){ r = _recvwait(s, (char*)lpBody, nRest, CNGP_RECV_TIMEOUT); if (r != SP_ERROR_OK){ printf("\nCNGP body cannot be received Successfully due to failure of _recvresult(). It returns a code of %d.\n", r); return r; } } } return SP_ERROR_OK; } int _recvresult(SOCKET s, int nCommandId, LPVOID lpRecvBuf, int cbRecvBuf, int *pCommandStatus) { int r; CNGP_HEAD head; r = _recvresult(s, &head, lpRecvBuf, cbRecvBuf); if (r == SP_ERROR_OK){ if (head.nCommandId != (unsigned int)nCommandId) return SP_ERROR_INVALID_COMMAND; if (pCommandStatus != NULL) * pCommandStatus = head.nCommandStatus; } return r; } int _activetest(SOCKET hSocket) { int nErrorCode = ERROR_SUCCESS; _ASSERT (hSocket != INVALID_SOCKET); // 发送ACTIVE_TEST给服务器 if (_sendcmd(hSocket, sizeof(CNGP_HEAD), CNGP_ACTIVE_TEST, 0, GenerateSequenceId(), NULL, 0) != SP_ERROR_OK){ // 发送数据失败,多因为网络质量不好 nErrorCode = WSAGetLastError(); printf("\n_activetest failed due to failure of _sendcmd(), error code: %d\n", nErrorCode); } else { int nCmdStatus; if (_recvresult(hSocket, CNGP_ACTIVE_TEST_RESP, NULL, 0, &nCmdStatus) != SP_ERROR_OK){ // 接受数据失败,可能原因:网络质量不好或鉴权失败,或数据不对 nErrorCode = WSAGetLastError(); printf("\n_activetest failed due to failure of _recvresult(), error code: %d\n", nErrorCode); return nErrorCode; } if (nCmdStatus != 0) { nErrorCode = ERROR_NETWORK_BUSY; printf("\n_activetest failed due to a CNGP command status: %d\n", nCmdStatus); return nErrorCode; } } return nErrorCode; } void _logout(SOCKET& hSocket) { if (hSocket != INVALID_SOCKET){ if (_sendcmd(hSocket, sizeof(CNGP_HEAD), CNGP_EXIT, 0, GenerateSequenceId(), NULL, 0) != SP_ERROR_OK){ // 发送数据失败,多因为网络质量不好 printf("\n_Logout failed due to failure of _sendcmd(), error code: %d\n", WSAGetLastError()); } else { int nCmdStatus; if (_recvresult(hSocket, CNGP_EXIT_RESP, NULL, 0, &nCmdStatus) != SP_ERROR_OK){ // 接受数据失败,可能原因:网络质量不好或鉴权失败,或数据不对 printf("\n_Logout failed due to failure of _recvresult(), error code: %d\n", WSAGetLastError()); } if (nCmdStatus != 0){ printf("\n收到EXIT_RESP...状态:%d", nCmdStatus); } } // 不管结果,直接关闭SOCKET closesocket(hSocket); hSocket = INVALID_SOCKET; } return; } SOCKET _login(LPCSTR Server, WORD Port, LPCTSTR SystemID, LPCTSTR Password, int nLoginMode) { SOCKET hSocket; sockaddr_in addr; int r, nCmdStatus; hSocket = socket(AF_INET, SOCK_STREAM, 0); if (hSocket == INVALID_SOCKET) { printf("\nsocket() failed, error code: %d\n", WSAGetLastError()); return INVALID_SOCKET; } try { memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(Port); addr.sin_addr.S_un.S_addr = inet_addr(Server); if (connect(hSocket, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) throw (int)WSAGetLastError(); CNGP_LOGIN_BODY login; CNGP_LOGIN_RESP_BODY loginresp; unsigned char szAuthClient[16]; CString sTimeStamp; memset(&login, 0, sizeof(login)); memset(&loginresp, 0, sizeof(loginresp)); sTimeStamp = CTime::GetCurrentTime().Format("%m%d%H%M%S"); unsigned char lpszOrgin[10 + 7 + 15 + 10 + 1], *p; p = lpszOrgin; memcpy(p, SystemID, strlen(SystemID)); p += strlen(SystemID); memset(p, '\0', 7); p += 7; memcpy(p, Password, strlen(Password)); p += strlen(Password); memcpy(p, sTimeStamp, 10); p += 10; _ASSERT( p - lpszOrgin == (int)(strlen(SystemID) + 7 + strlen(Password) + 10) ); CMD5Checksum::GetMD5((BYTE*)(const char*)lpszOrgin, strlen(SystemID) + 7 + strlen(Password) + 10, szAuthClient, 16); memcpy(login.sClientID, SystemID, sizeof(login.sClientID)); memcpy(login.sAuthenticatorClient, szAuthClient, sizeof(login.sAuthenticatorClient)); login.cLoginMode = nLoginMode; login.nTimeStamp = htonl(atoi(sTimeStamp)); login.cVersion = '\x10'; r = _sendcmd(hSocket, sizeof(CNGP_HEAD)+sizeof(login), CNGP_LOGIN, 0, GenerateSequenceId(), &login, sizeof(login)); if (r != SP_ERROR_OK) throw (int)WSAGetLastError(); r = _recvresult(hSocket, CNGP_LOGIN_RESP, &loginresp, sizeof(loginresp), &nCmdStatus); if (r != SP_ERROR_OK) throw (int)WSAGetLastError(); if (nCmdStatus == 0) return hSocket; printf("\n登录失败,状态码:%d\n", nCmdStatus); } catch(int e){ closesocket(hSocket); printf("\nLogin failed, error code: %d\n", e); } return INVALID_SOCKET; } int _delivery(SOCKET& hSocket, int nWaitSeconds) { int nErrorCode = ERROR_SUCCESS; // 0 int r, nCmdStatus; fd_set readfds; FILE *fp; char szFileName[_MAX_PATH], buf[1024]; CNGP_HEAD head; CNGP_DELIVER_RESP_BODY deliver_resp; _ASSERT(hSocket != INVALID_SOCKET); FD_ZERO(&readfds); FD_SET(hSocket, &readfds); timeval tv = {nWaitSeconds, 0}; r = select(0, &readfds, NULL, NULL, &tv); if (r == SOCKET_ERROR){ nErrorCode = WSAGetLastError(); printf("\nselect() failed, Error code: %d!\n", nErrorCode); return nErrorCode; } if (r == 0) return ERROR_SUCCESS; if (_recvresult(hSocket, &head, buf, sizeof(buf)) != SP_ERROR_OK){ nErrorCode = WSAGetLastError(); printf("\n_recvresult() failed, Error code: %d!\n", nErrorCode); return nErrorCode; } switch(head.nCommandId){ case CNGP_DELIVER: nCmdStatus = 0; memset(&deliver_resp, 0, sizeof(deliver_resp)); memcpy(deliver_resp.sMsgID, ((CNGP_DELIVER_BODY*)buf)->sMsgID, sizeof(deliver_resp.sMsgID)); deliver_resp.tlvCongestionState.wTag = 0x0428; deliver_resp.tlvCongestionState.wLength = 1; deliver_resp.tlvCongestionState.cValue = 80; sprintf(szFileName, "./phsqueue/_%s_%d.mol", CTime::GetCurrentTime().Format("%Y%m%d%H%M%S"), head.nSequenceId); fp = fopen(szFileName, "wb"); if (fp != NULL){ if (fwrite(buf, head.nTotalLength - sizeof(CNGP_HEAD), 1, fp) != 1){ nCmdStatus = SP_ERROR_FILE_WRITEERROR; } fclose(fp); } else { nCmdStatus = SP_ERROR_FILE_OPENERROR; } if (_sendcmd(hSocket, sizeof(CNGP_HEAD)+sizeof(deliver_resp), CNGP_DELIVER_RESP, nCmdStatus, head.nSequenceId, &deliver_resp, sizeof(deliver_resp)) != SP_ERROR_OK){ // 发送数据失败,多因为网络质量不好 nErrorCode = WSAGetLastError(); printf("\nDeliver::_sendcmd() failed, error code: %d\n", nErrorCode); return nErrorCode; } break; case CNGP_ACTIVE_TEST: printf("\n收到ACTIVE_TEST...处理\n"); if (_sendcmd(hSocket, sizeof(CNGP_HEAD), CNGP_ACTIVE_TEST_RESP, 0, head.nSequenceId, NULL, 0) != SP_ERROR_OK){ // 发送数据失败,多因为网络质量不好 nErrorCode = WSAGetLastError(); printf("\n发送ACTIVE_TEST_RESP...失败:错误码:%d!\n", nErrorCode); return nErrorCode; } printf("\n发送ACTIVE_TEST_RESP...成功!\n"); break; case CNGP_ACTIVE_TEST_RESP: printf("\nACTIVE_TEST_RESP\n"); break; default: printf("\nUnknown command id: %ld status: %ld\n", head.nCommandId, head.nCommandStatus); } return ERROR_SUCCESS; } int _submit(LPCSTR Server, WORD Port, LPCTSTR SystemID, LPCTSTR Password) { SOCKET hSocket; _finddata_t fi; long lFind = _findfirst("./phsqueue/*.mtl", &fi); if (lFind == -1) return 0; hSocket = _login(Server, Port, SystemID, Password, LOGINMODE_SUBMIT); if (hSocket == INVALID_SOCKET){ printf("\n登录失败,暂时不能发送短信。\n"); _findclose(lFind); return -1; } if (_activetest(hSocket) != ERROR_SUCCESS){ printf("\nACTIVE_TEST失败,暂时不能发送短信。\n"); _findclose(lFind); return -1; } for (int i = 0; i < 16 && hSocket != INVALID_SOCKET; i++){ char szFileName[sizeof(fi.name) + 20]; Sleep(0); sprintf(szFileName, "./phsqueue/%s", fi.name); FILE *fp = fopen(szFileName, "rb"); if (fp != NULL){ CNGP_SUBMIT_BODY submit; memset(&submit, 0, sizeof(submit)); fread(&submit, sizeof(submit), 1, fp); fclose(fp); int nCmdStatus = _sendcmd(hSocket, sizeof(CNGP_HEAD) + sizeof(submit) - sizeof(submit.sMsgContent) + submit.cMsgLength, CNGP_SUBMIT, 0, GenerateSequenceId(), &submit, sizeof(submit) - sizeof(submit.sMsgContent) + submit.cMsgLength); if (nCmdStatus != SP_ERROR_OK){ // 发送数据失败,多因为网络质量不好 printf("\nSubmit failed due to failure of _sendcmd(), error code: %d\n", WSAGetLastError()); Sleep(1000); break; } if (unlink(szFileName) == -1){ _ASSERT(FALSE); printf("\nunlink('%s') failed, error code: %d\n", szFileName, errno); exit(-1); } } if (_findnext(lFind, &fi) == -1){ int n = i + 1; for (int i = 0; i < n; i++){ CNGP_HEAD head; char buf[1024]; int result = _recvresult(hSocket, &head, buf, sizeof(buf)); if (result != SP_ERROR_OK){ printf("\n连接被断开。"); break; } if (head.nCommandStatus != 0){ printf("\nSubmit failed, due to submit_resp's data: command id: %08XH status: %d seqid: %d\n", head.nCommandId, head.nCommandStatus, head.nSequenceId); } } break; } } _logout(hSocket); _findclose(lFind); return 0L; } int _CNGPSubmit( LPCTSTR sSPID, // SP的企业代码 unsigned char bySubType, // 短消息子类型(0=取消订阅,1=订阅或点播请求,2=点播下发,3=订阅下发,其他保留) unsigned char byNeedReport, // 是否要求返回状态报告:(0=不要求,1=要求) unsigned char byPriority, // 发送优先级(从0到3)3为最高级 LPCTSTR sService, // 业务类型 LPCTSTR sFeeType, // 资费类型:00=免费 01=按条收费 02=包月 03=封顶 04=包月扣费请求 05=CR话单 其他:保留 unsigned char byFeeUserType, // 计费用户类型字段0:对目的终端计费1:对源终端计费2:对SP计费3:按照计费用户号码计费其他保留 LPCTSTR sFeeCode, // 每条短消息的信息费,单位:分 unsigned char byMsgFormat, // 短消息格式(参见短消息格式代码表7.1) LPCTSTR sValidTime, // 有效时间,(格式:yyyymmddhhmmss) LPCTSTR sAtTime, // 定时发送时间,(格式:yyyymmddhhmmss) LPCTSTR sOrgAddr, // 短消息发送用户号码 LPCTSTR sChargeAddr, // 计费用户号码 unsigned char byUserNum, // 短消息接收号码总数(≤100) LPCTSTR sDestAddrs, // 短消息接收号码(连续存储DestTermIDCount个号码) unsigned char byMsgLen, // 短消息长度 LPCTSTR sMsgContent, // 短消息内容 unsigned char byProValue, // 协议标识(参见TLV说明表7.5) unsigned char* byMsgID) // 接收MSID的字段 SMEI的扩展 { FILE *fp; int nCmdStatus = 0; char szFileName[_MAX_PATH]; CNGP_SUBMIT_BODY submit; memset(&submit, 0, sizeof(submit)); memccpy(submit.sSPID, sSPID, 0, sizeof(submit.sSPID)); submit.cSubType = bySubType; submit.cNeedReport = byNeedReport; submit.cPriority = byPriority; memccpy(submit.sServiceID, sService, 0, sizeof(submit.sServiceID)); memccpy(submit.sFeeType, sFeeType, 0, sizeof(submit.sFeeType)); submit.cFeeUserType = byFeeUserType; memccpy(submit.sFeeCode, sFeeCode, 0, sizeof(submit.sFeeCode)); submit.cMsgFormat = byMsgFormat; memccpy(submit.sValidTime, sValidTime, 0, sizeof(submit.sValidTime)); memccpy(submit.sAtTime, sAtTime, 0, sizeof(submit.sAtTime)); memccpy(submit.sSrcTermID, sOrgAddr, 0, sizeof(submit.sSrcTermID)); memccpy(submit.sChargeTermID, sChargeAddr, 0, sizeof(submit.sChargeTermID)); submit.cDestTermIDCount = byUserNum; memccpy(submit.sDestTermID, sDestAddrs, 0, sizeof(submit.sDestTermID)); submit.cMsgLength = byMsgLen; memccpy(submit.sMsgContent, sMsgContent, 0, sizeof(submit.sMsgContent)); submit.ProtocolID.wTag = htons(0x0100); submit.ProtocolID.wLength = htons(1); submit.ProtocolID.cValue = byProValue; memmove(submit.sMsgContent + byMsgLen, &submit.ProtocolID, sizeof(submit.ProtocolID)); sprintf(szFileName, "./phsqueue/_%s_%d.mtl", CTime::GetCurrentTime().Format("%Y%m%d%H%M%S"), GenerateSequenceId()); fp = fopen(szFileName, "wb"); if (fp != NULL){ if (fwrite(&submit, sizeof(submit) - sizeof(submit.sMsgContent) + byMsgLen, 1, fp) != 1){ nCmdStatus = SP_ERROR_FILE_WRITEERROR; } fclose(fp); } else { nCmdStatus = SP_ERROR_FILE_OPENERROR; } return nCmdStatus; } int _GetCNGPDeliverSM( char* sMsgID, //返回:SMGW产生的短消息流水号,由三部分组成:SMGW代码:3字节(BCD码)时间:4字节(BCD码)序列号:3字节(BCD码) unsigned char* byMsgFormat, //返回:断消息格式 char* sRecvTime, //返回:接收时间 char* sOrgAddr, //返回:源地址 char* sDestAddr, //返回:目标地址 unsigned char* byMsgLen, //返回:消息长度 char* sMsgContent, //返回:消息内容 unsigned char* byProValue, //返回:协议标识 unsigned char* byIsReport, //返回:状态报告标志 char* sSrcMsgID, //返回:状态报告中原始MsgID char* sSubmitdate, //报告:原发送时间 char* sDonedate, //报告:发送完成时间 char* sStatus, //报告:发送状态 int iDeliverAckResult) { long lFind; _finddata_t fi; char szFileName[20 + sizeof(fi.name)]; lFind = _findfirst("./phsqueue/*.mol", &fi); if (lFind != -1){ sprintf(szFileName, "./phsqueue/%s", fi.name); FILE *fp = fopen(szFileName, "rb"); while (fp == NULL && _findnext(lFind, &fi) != -1){ sprintf(szFileName, "./phsqueue/%s", fi.name); fp = fopen(szFileName, "rb"); } if (fp != NULL){ CNGP_DELIVER_BODY deliver; memset(&deliver, 0, sizeof(deliver)); fread(&deliver, sizeof(deliver), 1, fp); memcpy(sMsgID, deliver.sMsgID, sizeof(deliver.sMsgID)); *byMsgFormat = deliver.cMsgFormat; memcpy(sRecvTime, deliver.sRecvTime, sizeof(deliver.sRecvTime)); memcpy(sOrgAddr, deliver.sSrcTermID, sizeof(deliver.sSrcTermID)); memcpy(sDestAddr, deliver.sDestTermID, sizeof(deliver.sDestTermID)); *byMsgLen = deliver.cMsgLength; if (*byMsgLen < sizeof(deliver.sMsgContent)){ memcpy(sMsgContent, deliver.sMsgContent, *byMsgLen); } *byProValue = deliver.tlvProtocolID.cValue; *byIsReport = deliver.cIsReport; if (*byIsReport){ sscanf(sMsgContent, "id:%10s sub:001 dlvrd:001; submit_date:%10s done_date: %10s stat:%7s; err:E;txt:", sSrcMsgID, sSubmitdate, sDonedate, sStatus); } fclose(fp); _findclose(lFind); if (unlink(szFileName) == -1){ printf("\nunlink('%s') failed, error code: %d\n", szFileName, errno); } return 0; } _findclose(lFind); } return -1; } BOOL _Logout() { _logout(g_sktDeliver); g_bLogin = FALSE; return TRUE; }