At 指令文档
SMS_PDU-mode文档
短消息Text编码原码(下载至PJ Naughter的主页)
pdu编码示例:
//message中的位的设置可以参考文档中的说明
//红色的字表示可能与mfcsms中不同的地方
CString CSMSMessage::CreatePDUMessage() const { CByteArray message; //message.SetSize(0, 280);
//First thing to do is work on the Service Center Number if (!AddEncodedSMSCNumber(message, m_sServiceCenterNumber, m_ServiceCenterNumberAddressType)) return _T("");
//Form the SMS-SUBMIT octet BYTE bySMSSubmit = 0x1; //By default set this PDU to an SMS-SUBMIT if (m_bUseValidityPeriod) { if (m_bUseRelativeValidityPeriod) bySMSSubmit |= 0x10; else bySMSSubmit |= 0x18; } if (m_bRequireStatusReport) bySMSSubmit |= 0x20; message.Add(bySMSSubmit);
//Next is the TP-Message-Reference. We let the phone set the message reference itself message.Add(0x0);
//Next is the Phone number ASSERT(m_sPhoneNumber.GetLength()); //Must specify a number to deliver the message to if (!AddEncodedPhoneNumber(message, m_sPhoneNumber, m_PhoneNumberAddressType)) return _T("");
//Next is the Protocol Identifier message.Add(0x0);
//Next is the Data encoding scheme (this code always use PDU encoding) message.Add(0x8);
//Next is the validity period if (m_bUseValidityPeriod) { if (m_bUseRelativeValidityPeriod) { //Relative Validity period is pseudo logarithmitly encoded into 1 octet BYTE byValidityPeriod = 0; if (m_RelativeValidityPeriod <= CTimeSpan(0, 12, 0, 0)) byValidityPeriod = (BYTE) ((m_RelativeValidityPeriod.GetTotalSeconds() / 300) - 1); else if (m_RelativeValidityPeriod <= CTimeSpan(1, 0, 0, 0)) byValidityPeriod = (BYTE) (((m_RelativeValidityPeriod.GetTotalSeconds() - 43200) / 1800) + 143); else if (m_RelativeValidityPeriod <= CTimeSpan(30, 0, 0, 0)) byValidityPeriod = (BYTE) ((m_RelativeValidityPeriod.GetTotalSeconds() / 86400) + 166); else byValidityPeriod = (BYTE) ((m_RelativeValidityPeriod.GetTotalSeconds() / 604800) + 192);
message.Add(byValidityPeriod); } else { //Absolute Validity period is encoded into 7 octets message.Add(SwappedNibble(m_AbsoluteValidityPeriod.wYear % 100)); message.Add(SwappedNibble(m_AbsoluteValidityPeriod.wMonth)); message.Add(SwappedNibble(m_AbsoluteValidityPeriod.wDay)); message.Add(SwappedNibble(m_AbsoluteValidityPeriod.wHour)); message.Add(SwappedNibble(m_AbsoluteValidityPeriod.wMinute)); message.Add(SwappedNibble(m_AbsoluteValidityPeriod.wSecond));
long nLocalTimeZone = labs(m_TimeZone); BYTE byTimeZone = SwappedNibble(nLocalTimeZone / 15); if (m_TimeZone < 0) byTimeZone |= 0x80; message.Add(byTimeZone); } }
//Next is the length of the user data int nMessageLength = m_sMessage.GetLength(); int nActualLen=0; for(int j=0;j<nMessageLength;j++) { BYTE data=(BYTE)m_sMessage.GetAt(j); int nNibble = (int)data; if(nNibble>=0&&nNibble<=127) nActualLen=nActualLen+2; else nActualLen=nActualLen+1;
} if (nMessageLength > 255) { TRACE(_T("CSMSMessage::CreatePDUMessage, Cannot encode %s as it is longer than the maximum size of 255\n"), m_sMessage); return _T(""); } if (nMessageLength == 0) { TRACE(_T("CSMSMessage::CreatePDUMessage, Failing as no message has been specified to be sent\n")); return _T(""); } //Initially we just add a place holder as it will be updated later on once we have added the actual data int nDataLengthIndex = message.GetSize(); message.Add((BYTE) nActualLen);
//Finally before we return from the function, convert from the BYTE array representation to the string version WCHAR wcBuffer[256]; char cBuffer[256]; memset(cBuffer,0,256); memset(wcBuffer,0,256*2); MultiByteToWideChar(CP_ACP, 0, m_sMessage, nMessageLength, wcBuffer, 256); memcpy((void*)cBuffer,(void*)wcBuffer,256);
char tmp; for(int k =0; k<nMessageLength; k++) { tmp = cBuffer[2*k]; cBuffer[2*k] = cBuffer[2*k+1]; cBuffer[2*k+1]=tmp; }
for(k=0;k<nActualLen;k++) message.Add(cBuffer[k]);
int nArraySize = message.GetSize(); CString sMsg; int nBufferSize = (nArraySize*2) + 1; TCHAR* pszData = sMsg.GetBuffer(nBufferSize); int nPDUOutputIndex = 0; for (int i=0; i<nArraySize; i++) { BYTE byData = message.GetAt(i); int nNibble1 = (byData & 0xF0) >> 4; if (nNibble1 > 9) pszData[nPDUOutputIndex] = (TCHAR) (nNibble1 - 10 + _T('A')); else pszData[nPDUOutputIndex] = (TCHAR) (nNibble1 + _T('0')); ++nPDUOutputIndex; int nNibble2 = byData & 0xF; if (nNibble2 > 9) pszData[nPDUOutputIndex] = (TCHAR) (nNibble2 - 10 + _T('A')); else pszData[nPDUOutputIndex] = (TCHAR) (nNibble2 + _T('0')); ++nPDUOutputIndex; } sMsg.ReleaseBuffer(nPDUOutputIndex);
return sMsg; }
使用at指令发送端消息示例:
//Check to see if there is a modem on the specified serial port char* pszATMsg = "AT\r";//测试连接是否成功 Write(pszATMsg, strlen(pszATMsg)); if (!WaitForSerialResponse("OK", dwTimeout, 32)) { CString sError; sError.LoadString(IDS_SMSSERIALPORT_FAIL_RECEIVE_RESPONSE_FROM_MODEM); AfxThrowSMSException(sError, E_SMS_NO_MODEM_RESPONSE); }
char* pszSelectMessageMsg = "AT+CSMS=0\r"; //Select Message service Write(pszSelectMessageMsg, strlen(pszSelectMessageMsg)); if (!WaitForSerialResponse("OK", dwTimeout, 32)) { CString sError; sError.LoadString(IDS_SMSSERIALPORT_MODEM_DOES_NOT_SUPPORT_SMS); AfxThrowSMSException(sError, E_SMS_NO_SMS_SUPPORT); }
char* pszMessageFormat = "AT+CMGF=0\r"; //Set the transfer mode to PDU Write(pszMessageFormat, strlen(pszMessageFormat)); if (!WaitForSerialResponse("OK", dwTimeout, 32)) { CString sError; sError.LoadString(IDS_SMSSERIALPORT_FAIL_SET_PDU_MODE); AfxThrowSMSException(sError, E_SMS_SET_PDU_MODE); }
CString sSendCommand; sSendCommand.Format(_T("AT+CMGS=%d\r"), nMsgSize); //Prepare to send the PDU LPSTR pszAsciiSendCommand = T2A((LPTSTR) (LPCTSTR) sSendCommand); Write(pszAsciiSendCommand, strlen(pszAsciiSendCommand)); if (!WaitForSerialResponse(">", dwTimeout, 32)) { CString sError; sError.LoadString(IDS_SMSSERIALPORT_FAIL_SEND_SMS_MESSAGE_TO_MODEM); AfxThrowSMSException(sError, E_SMS_SEND_MESSAGE_TO_MODEM); }
//And finally write out the PDU as a string LPSTR pszAsciiPDU = T2A((LPTSTR) (LPCTSTR) sData); int nAsciiPDULength = strlen(pszAsciiPDU); Write(pszAsciiPDU, nAsciiPDULength);//pszAsciiPDU是短消息的PDU编码 Write("\x1A", 1); if (!WaitForSerialResponse("OK", dwTimeout, 32 + nAsciiPDULength)) { CString sError; sError.LoadString(IDS_SMSSERIALPORT_FAIL_SEND_SMS_MESSAGE); AfxThrowSMSException(sError, E_SMS_SEND_MESSAGE); }
我的主页 
|