📄 sgip_api_test.cpp
字号:
/**
* 说明:中国联通SGIP1.2接口库示例程序
* 作者:PrinceToad
* Email:princetoad@zealware.com
* Http://www.zealware.com
* 版本: 1.0 2003/09/09
* 1.1 2003/11/08
* 1.11 2003/11/25 针对1.23版本作了更新.
* 1.12 2003/12/04 针对1.24版本作了更新.
* 1.2 2004/02/26 针对sgipapi 1.28版进行修改.
* 1.3 2004/03/07 针对sgipapi 1.3版进行修改(用户可以自定义网关连接数).
* 1.31 2004/03/12 1.3没能正确读出配置文件的nodeid.
* 1.4 2004/07.19
* 示例程序介绍:
* 1. 程序会首先从配置文件中读取相关的配置参数,如网关地址端口,本地监听端口,用户名口令,企业代码,接入号等,
* 因此在启动以前需要首先配置好这些参数,有关参数的说明在配置文件中有。
* 2. 程序在调用sgip.Start()函数后启动,然后在后台进行消息的收发。这时你可以调用sgip.Submit()
* 函数发送消息;系统在收到消息后会调用PDeliver()函数,PDeliver函数作为Deliver消息的处理函数在调用
* Start函数是作为参数传入。
* 3. 程序还演示了UCS2编码的转换,演示了在收到UCS2格式的MO消息是如何转换成可以正常显示的MultiByte编码.
*/
#include "stdafx.h"
#include "sgip.h"
#pragma comment(lib, "sgip")
char g_sSmgIp[20]; // 网关地址
int g_nSmgPort; // 网关端口号
char g_sLocalIp[20]; // 本机地址
int g_nLocalPort; // 本地监听端口
char g_sUsername[20]; // 登录名
char g_sPwd[20]; // 登录口令
char g_sCorpId[20]; // 企业代码
char g_sNodeId[20]; // 源节点编号
char g_sSpId[20]; // 接入号(特服号)
char g_sServiceType[20]; // 业务代码
char g_sMsisdn[30]; // 测试用目的手机号
char g_sMsgContent[160]; // 测试用消息内容
int g_nConnCount; // 网关连接数
CString g_szSettingPath; //保存设置的文件路径
CString g_szCurPath; //保存当前路径
/**
* 从配置文件获取配置参数(配置文件setting.ini,在当前目录下)
*
*/
void GetConfigValue()
{
DWORD dwSize = 20;
ZeroMemory(g_sSmgIp, 20);
g_nSmgPort = 0;
ZeroMemory(g_sLocalIp, 20);
g_nLocalPort = 0;
ZeroMemory(g_sUsername, 20);
ZeroMemory(g_sPwd, 20);
ZeroMemory(g_sCorpId, 20);
ZeroMemory(g_sNodeId, 20);
ZeroMemory(g_sSpId, 20);
ZeroMemory(g_sMsisdn, 30);
ZeroMemory(g_sMsgContent, 160);
ZeroMemory(g_sServiceType, 20);
g_nConnCount = 0;
//获取当前路径
CString szCurPath("");
GetModuleFileName(NULL,szCurPath.GetBuffer(MAX_PATH),MAX_PATH);
szCurPath.ReleaseBuffer();
g_szCurPath = szCurPath.Left(szCurPath.ReverseFind('\\') + 1);
//设置文件在当前路径下
g_szSettingPath = g_szCurPath + "setting.ini";
// 读取配置
GetPrivateProfileString("setting", "smgip", "Not found",
g_sSmgIp, dwSize, g_szSettingPath);
g_nSmgPort = GetPrivateProfileInt("setting", "smgport", 0, g_szSettingPath);
GetPrivateProfileString("setting", "localip", "Not found",
g_sLocalIp, dwSize, g_szSettingPath);
g_nLocalPort = GetPrivateProfileInt("setting", "localport", 0, g_szSettingPath);
GetPrivateProfileString("setting", "username", "Not found",
g_sUsername, dwSize, g_szSettingPath);
GetPrivateProfileString("setting", "pwd", "Not found",
g_sPwd, dwSize, g_szSettingPath);
GetPrivateProfileString("setting", "corpid", "Not found",
g_sCorpId, dwSize, g_szSettingPath);
GetPrivateProfileString("setting", "nodeid", "Not found",
g_sNodeId, dwSize, g_szSettingPath);
GetPrivateProfileString("setting", "spid", "Not found",
g_sSpId, dwSize, g_szSettingPath);
GetPrivateProfileString("setting", "destid", "Not found",
g_sMsisdn, 30, g_szSettingPath);
GetPrivateProfileString("setting", "msgcontent", "Not found",
g_sMsgContent, 160, g_szSettingPath);
GetPrivateProfileString("setting", "servicetype", "Not found",
g_sServiceType, dwSize, g_szSettingPath);
g_nConnCount = GetPrivateProfileInt("setting", "smgconn", 3, g_szSettingPath);
}
// 输出程序的描述信息
void OutProgramInfo()
{
printf("\n*****************************************************************************\n");
printf("**软件名称 - <<中国联通SGIP1.2短消息网关开发接口库>> V1.4例程.\n");
printf("**作者主页 - http://www.zealware.com\n");
printf("**电子邮件 - Email:princetoad@zealware.com\n");
printf("**MSN - princetoad2003@hotmail.com\n");
printf("**OICQ - 50506711\n");
printf("**联系电话 - 010-13901168061\n");
printf("**授权方式 - Used Free,SourceCode On Sale.\n");
printf("**********************Published By PrinceToad Jun.19.04.*********************\n\n");
}
// 构造一条主动下发的免费消息包(相关字段从配置文件中获取,例如企业代码,接入号,目的手机号,和测试消息内容).
void SetSubmit(sgipg_submit *ss)
{
//SPNumber(SP接入号-21)
strcpy(ss->sSpNumber, g_sSpId);
//ChargeNumber(付费号码-21,全零表示由SP付费)
strcpy(ss->sChargeNumber, "000000000000000000000");
//UserCount(1)
ss->cUserCount = 1;
//UserNumber(接收消息的电话号码-21)
strcpy(ss->sUserNumber, g_sMsisdn);
//企业代码(0-99999 5)
strcpy(ss->sCorpId, g_sCorpId);
//业务代码(10)
strcpy(ss->sServiceType, g_sServiceType);
//付费类型(1,"1"表示免费)
ss->cFeeType = 1;
//Feevalue(6,10表示2分,可以填空)
//strncpy(ss->sFeeValue, "10");
//Givenvalue(6,一般填空)
//AgentFlag(1,一般为0)
ss->cAgentFlag = 0;
//Mtflag(1,一般填2,表示是由非MO消息引起的MT消息)
ss->cMorelatetoMTFlag = 2;
//priority(1,0-9.0默认)
//Expiretime,scheduleTime(16,16,可以为空)
//Reportflag(1)
ss->cReportFlag = 1;
//tppid,tpudhi(1,1 "0", "0")
//MsgCoding(1,"15")
ss->cMessageCoding = 15; // 能够显示中英文.
//msgtype(1,"0")
//024A3A694DA5B99D099585D5D1E404000CA8C2CC2EC49B4000
//content1[0]=0x06; content1[1]=0x05; content1[2]=0x04; content1[3]=0x15; content1[4]=0x81; content1[5]=0x15; content1[6]=0x81
char pchRingContent[] = "0x02 0x4A 0x3A 0x69 0x4D 0xA5 0xB9 0x9D 0x09 0x95 0x85 0xD5 0xD1 0xE4 0x04 0x00 0x0C 0xA8 0xC2 0xCC 0x2E 0xC4 0x9B 0x40 0x00";
// strcpy((char*)ss->sMsgContent, g_sMsgContent);
// 转换整数(长度)为网络字节序
// ss->nMsgLen = ntohl(strlen(g_sMsgContent));
ss->sMsgContent[0] = 0x06;
ss->sMsgContent[1] = 0x05;
ss->sMsgContent[2] = 0x04;
ss->sMsgContent[3] = 0x15;
ss->sMsgContent[4] = 0x81;
ss->sMsgContent[5] = 0x15;
ss->sMsgContent[6] = 0x81;
char* pchMsgContent = (char*)ss->sMsgContent;
memcpy(pchMsgContent + 7, pchRingContent, sizeof(pchRingContent));
ss->nMsgLen = htonl(7 + sizeof(pchRingContent));
return;
}
void PDeliver(DeliverStr deliver);
void PReport(ReportStr report);
void PResponse(MTRespStr response);
void PMTError(MTErrorStr mterror);
/**
* 处理Deliver消息的函数
*/
void PDeliver(DeliverStr deliver) {
// Edit with V1.28(打印出MO上行消息的LinkId,这里的LinkId可以不作修改的赋值给对应的MT消息)
// 打印出MO消息的相关字段,包括MO消息的内容.
char sMultiByte[141];
ZeroMemory(&sMultiByte, 141);
unsigned char uchTmp = 0;
unsigned char pchTmp[1024];
ZeroMemory(pchTmp, 1024);
// 如果是UCS2编码的话,首先需要转换成MultiByte格式,才能正常显示。
if (deliver.cMsgCoding == 8) {
memcpy(pchTmp, deliver.sMsgContent, deliver.nMsgLen);
// 高低字节转换
for (int ix=0; ix<deliver.nMsgLen/2; ix++) {
uchTmp = pchTmp[ix*2]; // 低
pchTmp[ix*2] = pchTmp[ix*2 + 1]; // 低 = 高
pchTmp[ix*2 + 1] = uchTmp; // 高 = 低
}
// 转换成MultiByte形式.
int nRet = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (LPCWSTR)pchTmp, deliver.nMsgLen/2, sMultiByte, 140, NULL, NULL);
// 重新给消息包的长度和内容赋值.
deliver.nMsgLen = nRet;
ZeroMemory(deliver.sMsgContent, 160);
memcpy(deliver.sMsgContent, sMultiByte, nRet);
}
// 输出编码方式
CString str(_T(""));
switch((int)deliver.cMsgCoding) {
case 0:
str = "ASCII编码";
break;
case 4:
str = "二进制编码";
break;
case 8:
str = "UCS2编码";
break;
case 15:
str = "GBK编码";
break;
default:
str.Format("未知-<%d>", deliver.cMsgCoding);
}
printf("Deliver, SeqId = <%u>, MsgLen = <%u>, MsgFmt = <%s>, MsgContent = <%s>, LinkId = <%s>.\n", \
deliver.nSeq, deliver.nMsgLen, str, deliver.sMsgContent, deliver.sLinkId);
return;
}
/**
* 处理Report消息的函数
*/
void PReport(ReportStr report){
printf("Report, SubmitSeqId = <%u>, SubmitDateTime = <%u>, sUserNumber = <%s>, State = <%d>, ErrorCode = <%d>.\n", \
report.nSubmitSeq, report.nSubmitDateTime, report.sUserNumber, report.cState, report.cErrcode);
return;
}
/**
* 处理SubmitResponse消息的函数
* (V1.23版本及以后可以返回完整的SUBMIT消息内容,通过MTResponse中的sgipg_submit ss字段)
*/
void PResponse(MTRespStr response){
printf("MTResponse, SeqId = <%u>, ChargeNumber = <%s>, Result = <%d>.\n", \
response.nSeq, response.ss.sChargeNumber, response.cResult);
return;
}
/**
* 处理MT失败的函数
* (V1.23版本及以后可以返回完整的SUBMIT消息内容,通过MTResponse中的sgipg_submit ss字段)
*/
void PMTError(MTErrorStr mterror){
printf("MTError.Errcode = <%d>\n", mterror.nErrorType);
return;
}
// 演示sgip.dll用法的main函数.
int main(int argc, char* argv[])
{
OutProgramInfo();
CSgip sgip; //定义一个Csgip对象
sgipg_submit ss; //定义一个Submit数据包
ZeroMemory(&ss, sizeof(sgipg_submit));
GetConfigValue(); // 取得配置参数
//启动系统(sgip.dll V1.3 使用户可以自定义同网关的连接数)
if (0 != sgip.Start(g_sLocalIp, g_nLocalPort, g_sSmgIp, \
g_nSmgPort, g_sUsername, g_sPwd, \
1, g_sNodeId, PDeliver, \
PReport, PResponse, PMTError, g_nConnCount, true) ) {
MessageBox(NULL, "初始化失败.", "提示", MB_ICONERROR);
goto finished;
}
SetSubmit(&ss); // 用于构造submit消息包的函数
//通过调用函数AddUserNumber增加群发功能.(要测试群发的话把下面这句注释去掉就行)
// sgip.AddUserNumber(&ss, "8613023456789,8613312345670-8613312345699,8613012345678");
// 向网关提交submit消息包(在这里连续发送三次,只是测试用)
// nSeq,nDateTime都是输出参数。
int ix;
unsigned int nSeq, nDateTime;
for (ix=0; ix<200000; ix++) {
TRACE("%d\n", sgip.GetSubmitSeqId());
//**GetSubmitSeqId()函数的作用是提前获得下一条Submit消息的序列号,有些用户有这样的需求.(一般用不着.)
// printf("提前获得Submit消息的序列号:%d.\n", sgip.GetSubmitSeqId());
//********************************************************************************************
//**
//**需要注意的是:sgip.Submit函数只是把submit消息提交给后台,由后台程序提交给网关,
//**因此在这里没法判断消息是否发送成功,需要通过PResponse或PMTError,和PReport来判断,
//**提交失败的话,会触发PMTError函数;提交成功的话,会触发PResponse函数;成功到达用户手机的话,
//**会触发PReport函数(当请求需要状态报告时.)其中,PMTError和PResponse函数均会返回完整的submit
//**消息包的内容(通过其输入参数mterror或response中的sgipg_submit ss字段,有些开发者可能用得到).
//**(V1.23 及以后版本支持.)
//********************************************************************************************
sgip.Submit(ss, nSeq, nDateTime);
printf("Submit sequence:<%u>, datetime:<%u>\n", nSeq, nDateTime);
// Sleep(1);
}
//主程序暂停,系统自动在后台运行,进行短消息的收发处理操作。
system("pause");
finished:
//退出系统前进行系统清理工作
sgip.Release();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -