windows mobile 和 symbian 平台上彩信(MMS)收发方案

写一下这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
posted @ 2010-04-13 19:12  熊健  阅读(3095)  评论(3编辑  收藏  举报