写一下这2天的彩信收发心的,有自己的部分,也有部分代码用的别人的。
发彩信可以调用系统提供的接口,也可以自己通过socket http连接彩信网关2种方法来发送彩信。
方法1 利用socket
彩信发送:
格式大概为 http包头+mm1,xml的彩信数据
#include "ril.h"
#pragma comment(lib,"ril.lib") //自己下载
int
get_mms_packet(char* mms_context, char* context, int context_len, char* mobile_id)
{
char szToCombin[50];
char* pSubject = "MmsTest";
int iDataTextLen;
char *szXmlFileName = "my.txt";
char *id = "9604059";
//X-Mms-Message-Type(0x8c): m-send-req(0x80)
unsigned char* pCurPos = mms_context;
*pCurPos = 0x8c; pCurPos++;
*pCurPos = 0x80; pCurPos++;
//ID
*pCurPos = 0x98; pCurPos++;
strcpy( (char*)pCurPos, id );
pCurPos += strlen( mobile_id);
*pCurPos = 0x00; pCurPos++;
//X-Mms-MMS-Version(0x8d):v1.0(0x90)
*pCurPos = 0x8d; pCurPos++;
*pCurPos = 0x90; pCurPos++;
//from
*pCurPos = 0x89; pCurPos++;
*pCurPos = 0x01; pCurPos++;
*pCurPos = 0x81; pCurPos++;
//To(0x97)
memset(szToCombin, '\0', sizeof(szToCombin));
sprintf( szToCombin, "%s%s%s", "+86", mobile_id, "/TYPE=PLMN" );
*pCurPos = 0x97; pCurPos++;
strcpy( (char*)pCurPos, szToCombin);
pCurPos += strlen(szToCombin);
*pCurPos = 0x00; pCurPos++;
//subject
*pCurPos = 0x96; pCurPos++;
strcpy( (char*)pCurPos, pSubject );
pCurPos += strlen(pSubject);
*pCurPos = 0x00; pCurPos++;
//Content-Type: application/vnd.wap.multipart.mixed
*pCurPos = 0x84; pCurPos++;
*pCurPos = 0xa3; pCurPos++;
////////jpeg头
*pCurPos = 0xa1; pCurPos++;
*pCurPos = 0x9e; pCurPos++;
*pCurPos = 0xff; pCurPos++;
*pCurPos = 0xd8; pCurPos++;
//模拟的jpeg数据
*pCurPos = 0x11; pCurPos++;
*pCurPos = 0x22; pCurPos++;
*pCurPos = 0xff; pCurPos++;
*pCurPos = 0xd9; pCurPos++;
//彩信包实际长度
return (pCurPos - mms_context);
}
int
mms_send(char* mobile_num, char* context, int context_len, char* temp)
{
int mobile_type = 1; //default china mobile
char senddata[1024*3];
int rtn;
char recedata[1024*2];
char mms_context[1024*2];
int mms_context_len;
int send_len;
char* pos = 0x0;
mms_context_len = get_mms_packet(mms_context, context, context_len, mobile_num);
memset(&server_addr, 0, sizeof(ST_SOCKADDR_T));
server_addr.sa = malloc(sizeof(struct sockaddr_in));
((struct sockaddr_in*)(server_addr.sa))->sin_family=AF_INET;
((struct sockaddr_in*)(server_addr.sa))->sin_addr.s_addr=inet_addr("10.0.0.172");
((struct sockaddr_in*)(server_addr.sa))->sin_port = htons(80);
server_addr.salen = sizeof(struct sockaddr_in);
memset(recedata, '\0', sizeof(recedata));
memset(senddata, '\0', sizeof(senddata));
//mobile_type = cheak_my_mobile();
if(st_socket_create(&mms_sock, SOCK_STREAM, IPPROTO_TCP, 80) != 1)
{
return -1;
}
rtn = st_socket_connect(mms_sock, server_addr);
if(rtn != 1)
{
return rtn;
}
if(mobile_type == 1) //china mobile
{
sprintf(senddata, "POST http://mmsc.monternet.com HTTP /1.1\r\nHost: 10.0.0.172:80\r\nAccept-Charset:utf-8\r\nAccept:application/vnd.wap.mms-message,text/plain,*/*\r\nAccept-Language: en\r\nContent-Type: application/vnd.wap.mms-message\r\nContent-Length:%d\r\nUser-Agent: Nokia6235/1.0 (S190V0200.nep) UP.Browser/6.2.3.2 MMP/2.0\r\nx-wap-profile: \"http://nds1.nds.nokia.com/uaprof/N6235r200.xml\"\r\nConnection: Keep-Alive\r\n\r\n", mms_context_len);
memcpy(senddata + strlen(senddata), mms_context, mms_context_len);
}
send_len = strlen(senddata) +1;
rtn = st_socket_sendto(mms_sock, &server_addr, 0, senddata, &send_len);
if(rtn < 0)
{
return -3;
}
rtn = st_socket_recvfrom(mms_sock, 0, (ems_int8*)recedata, sizeof(recedata));
if(rtn < 0)
{
return -4;
}
memcpy(temp, senddata, send_len);
pos = strstr(recedata, "200");
if(pos == 0)
{
return -5;
}
return rtn;
}
利用mms_send就可以把彩信发送出去了。这个理论上可以跨平台运行。st_socket_create等函数是对socket的封装
彩信拦截:
void CALLBACK RILResultProc(DWORD dwCode, HRESULT hrCmdID, const void* lpData, DWORD cbData, DWORD dwParam)
{
DWORD *dwNum;
switch (dwCode)
{
case RIL_RESULT_OK:
dwNum = (DWORD*)lpData;
break;
case RIL_RESULT_NOCARRIER:
case RIL_RESULT_NODIALTONE:
case RIL_RESULT_ERROR:
case RIL_RESULT_BUSY:
break;
}
}
void RILNotifyProc(DWORD dwCode, const void* lpData, DWORD cbData, DWORD dwParam)
{
UINT uiCharactersConverted ;
//pwsMessage 中存储解码后得到的短信内容
WCHAR pwsMessage[MAX_GSM_CHARS_PER_SMS_DATAGRAM+1]; // Extra character is for NULL-terminate the string.
if(((dwCode & RIL_NCLASS_ALL)== RIL_NCLASS_MESSAGE) &&(RIL_NOTIFY_MESSAGE==dwCode))
{
// Prepare to decode the message data (using the appropriate alphabet encoding)
RILMESSAGE *prmMsg = (RILMESSAGE *)lpData;
switch(prmMsg->dwType)
{
case RIL_MSGTYPE_IN_DELIVER:
{
char *psRet=NULL;
DWORD dwAlphabet = prmMsg->msgInDeliver.rmdDataCoding.dwAlphabet;
DWORD dwHeaderLength = prmMsg->msgInDeliver.cbHdrLength;
DWORD dwBodyLength = prmMsg->msgInDeliver.cchMsgLength;
if(dwBodyLength <= 0)
{
break;
}
uiCharactersConverted = 0;//最后得到的字符数(不包含\0)
ASSERT(pwsMessage);
if (NULL == pwsMessage)
{
break;
}
MultiByteToWideChar(CP_ACP,0, prmMsg->msgInDeliver.rgbMsg,-1,strW,1024);
MessageBox(NULL, strW, _T("SMS content:"), MB_OK);
get_mms(prmMsg->msgInDeliver.rgbMsg); //开始接收彩信
break;
}
case RIL_MSGTYPE_IN_IS637DELIVER: //CDMA
{
break;
}
}
}
return;
}
BOOL RegisterRIL()
{
HRIL g_hRil;
HRESULT hResult = RIL_Initialize(1, RILResultProc, RILNotifyProc, RIL_NCLASS_MESSAGE, (DWORD) NULL, &g_hRil);
if(FAILED(hResult))
{
MessageBox(NULL, TEXT("Initialize failed!"),_T("Tips"), MB_OK);
}
return TRUE;
}
int
mms_recv(char* mobile_num, char* context, int* context_len)
{
RegisterRIL();
}
int
get_mms(char* p_url ) //接收彩信,例如 http://10.0.0.172/#dfd3*dc
{
int recv_data[1024*10];
int send_len;
int rtn;
char *pos = 0x0;
char get_string[MAX_PATH] = ""; //pUrlMbyte 就是上一步获取到的url彩信地址
sprintf( get_string, "GET %s HTTP/1.1\r\n\r\n", p_url );
if(st_socket_create(&mms_sock, SOCK_STREAM, IPPROTO_TCP, 80) != 1)
{
return -1;
}
if(st_socket_connect(mms_sock, server_addr) != 1)
{
return -1;
}
send_len = strlen(get_string) +1;
rtn = st_socket_sendto(mms_sock, &server_addr, 0, get_string, &send_len);
if(rtn < 0)
{
return -1;
}
rtn = st_socket_recvfrom(mms_sock, 0, (ems_int8*)recv_data, sizeof(recv_data)); //step 5
if(rtn < 0)
{
return -1;
}
pos = strstr(recv_data, "200");
if(pos == 0x0)
{
return -1;
}
st_socket_close(&mms_sock);
//hander recv_data
}
系统调用mms_recv即可实现短信拦截。
方法2 调用系统接口发送彩信
1 windows mobole and 魅族m8
//--------------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------
//
//
// 2010.4.13
//sylar wuhan
//
//--------------------------------------------------------------------------------
#ifdef MS_WINCE_M8
int mms_send(char *subject, char *bodytext, char* attach_path)
{
TCHAR commandLine[1024];
TCHAR t_subject[128]; TCHAR t_body[512]; TCHAR t_attach_path[256];
if(strlen(subject) > 128 || strlen(bodytext) > 512 || strlen(attach_path) > 256)
{
return -1;
}
memset(commandLine, '\0', sizeof(commandLine));
memset(t_subject, '\0', sizeof(t_subject));
memset(t_body, '\0', sizeof(t_body));
memset(t_attach_path, '\0', sizeof(t_attach_path));
MultiByteToWideChar(CP_ACP, 0, subject, -1, t_subject, sizeof(t_subject)/sizeof(TCHAR));
MultiByteToWideChar(CP_ACP, 0, bodytext, -1, t_body, sizeof(t_body)/sizeof(TCHAR));
MultiByteToWideChar(CP_ACP, 0, attach_path, -1, t_attach_path, sizeof(t_attach_path)/sizeof(TCHAR));
#ifdef UNICODE
swprintf(commandLine, _T("-attach \"%s\""), t_attach_path);
#else
sprintf(commandLine, _T("-attach \"%s\""), attach_path);
#endif
if(CreateProcess(_T("\\Windows\\SMS.exe"), commandLine, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL) == 0)
{
return -1;
}
return 1;
}
#elif MS_WINCE
int
ems_mms_send(char *subject, char *bodytext, char* attach_path)
{
TCHAR commandLine[1024];
TCHAR t_subject[127]; TCHAR t_body[511]; TCHAR t_attach_path[255]; TCHAR t_mms_name[127];
HKEY hKey = 0;
char mms_name[127];
DWORD dwType = 0;
DWORD dwBufSize = sizeof(mms_name);
const TCHAR * subkey = L"Software\\Arcsoft\\ArcSoft MMS UA\\Config\\UI";
unsigned char temp1, temp2;
int i = 0;
if(strlen(subject) > 127 || strlen(bodytext) > 511 || strlen(attach_path) > 255)
{
return -1;
}
memset(mms_name, '\0', sizeof(mms_name));
memset(commandLine, '\0', sizeof(commandLine));
memset(t_subject, '\0', sizeof(t_subject));
memset(t_body, '\0', sizeof(t_body));
memset(t_attach_path, '\0', sizeof(t_attach_path));
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,0,&hKey) != ERROR_SUCCESS)
{
dwType = REG_SZ;
if(RegQueryValueEx(hKey,L"MMSAccountName", 0, &dwType, (BYTE*)mms_name, &dwBufSize) == ERROR_SUCCESS)
{
return -1;
}
RegCloseKey(hKey);
}
for(i = 0; i < dwBufSize; i += 2)
{
mms_name[i] <= 0?(temp1 = ~(-mms_name[i]) + 1):(temp1 = mms_name[i]);
mms_name[i + 1] <= 0?(temp2 = ~(-mms_name[i + 1]) + 1):(temp2 = mms_name[i + 1]);
#if BYTE_ORDER_==BIG_EANDIN_
t_mms_name[i/2] = temp2<<8 | temp1;
#else
t_mms_name[i/2] = temp1<<8 | temp2;
#endif
}
MultiByteToWideChar(CP_ACP, 0, subject, -1, t_subject, sizeof(t_subject)/sizeof(TCHAR));
MultiByteToWideChar(CP_ACP, 0, bodytext, -1, t_body, sizeof(t_body)/sizeof(TCHAR));
MultiByteToWideChar(CP_ACP, 0, attach_path, -1, t_attach_path, sizeof(t_attach_path)/sizeof(TCHAR));
swprintf(commandLine, _T("-service \"%s\" -body \"%s\" -subject \"%s\" -attach \"%s\""), t_mms_name, t_body, t_subject, t_attach_path);
if(CreateProcess(_T("\\Windows\\tmail.exe"), commandLine, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL) == 0)
{
return -1;
}
return 1;
}
#endif
symbian s60
int Send_MMS(const char* subject, const char* bodytext,
const char* attach_path)
{
_LIT(KSubject, subject);
_LIT(KBodyText, bodytext);
_LIT(KAttachPath, attach_path);
// create empty message
CSendUi *sendui = CSendUi::NewLC();
CMessageData* message = CMessageData::NewLC();
CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL();
CleanupStack::PushL(paraFormatLayer);
CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL();
CleanupStack::PushL(charFormatLayer);
CRichText* messageBodyContent = CRichText::NewL(paraFormatLayer,
charFormatLayer);
CleanupStack::PushL(messageBodyContent);
messageBodyContent->InsertL(0, KBodyText);
message->SetSubjectL(KSubject());
message->SetBodyTextL(messageBodyContent);
message->AppendAttachmentL(KAttachPath);
// start message editor through SendUI
sendui->CreateAndSendMessageL(KSenduiMtmMmsUid, message);
CleanupStack::PopAndDestroy(5);
return 1;
}
具体原理性的说明可以参阅
http://blog.csdn.net/depraved_survival/archive/2009/03/09/3969013.aspx