21. juli 2005 - 17:53Der er
13 kommentarer og 1 løsning
SMS med Siemens M1 GSM MODEM
Er der nogen der har kendskab til SIEMENS M1 GSM Modem Har problemmer med at få den til at sende. Har nu prøvet lidt forskelligt med PDU Kan fint læse SMS i Modem. Men den melder fejl hvergang jeg vil sende
Jeg har lavet noget til et Siemens GSM modem engang, men kan ikke lige huske om det var M1 modellen. Du skal sørge for at lave din PDU header rigtig og pakke data i det lidt specielle 7-bit dataformat.
Headeren skal se sådan ud: private static readonly byte [] SubmitPDUHeader = { 0x00, 0x11, // msg Submit, TP-VP relative format 0x00, 0x0A, // number lenght = 10 0x91, // international format 0x00,0x00,0x00,0x00,0x00, // 5 bytes for phone number 0x00, // PID 0x00, // data coding scheme = 7 bit characters to utlize 160 character SMS 0xAA // validity period = 4 days };
Jeg har noget C# kode til at pakke tekst ned i en PDU, men det er af ret ringe kvalitet da det bare skulle bruges til en hurtig test, før jeg skulle implementere mod modemet i en mikroprocessor. Jeg kan poste det, hvis du vil se det.
int bitpos = 0; byte [] buf = new byte[cbOut]; fixed ( byte * pBuf = &buf[0] ) { int * ptr = (int *)pBuf; foreach(byte b in ascii) { if ( b > 127 ) throw new ApplicationException("Only 7 - bit characters are allowed."); *ptr |= (b << bitpos); bitpos += 7; if ( bitpos > 32 ) { ptr++; bitpos -= 32; *ptr |= (b >> (7-bitpos)); } } } return buf; }
protected string ParsePhoneNumber(byte [] src, int offset, int length) { StringBuilder number = new StringBuilder(); for ( int i = offset ; i < offset + length ; i++ ) { number.Append((src[i] & 0x0F).ToString()); if ( src[i] >> 4 != 0x0F ) number.Append((src[i] >> 4).ToString()); } return number.ToString(); }
protected byte [] StringToBytes(string str) { if ( str == null ) throw new ArgumentNullException("str"); else if ( str.Length % 2 != 0 ) throw new ApplicationException("An even number of ascii characters must be provided.");
byte [] bout = new byte[str.Length/2]; for ( int i = 0 ; i < bout.Length ; i++ ) { string cur = str.Substring(i*2,2); bout[i] = Byte.Parse(cur,NumberStyles.HexNumber); } return bout; }
protected unsafe string UnpackSeptetChars(byte [] src, int offset, int length) { StringBuilder msg = new StringBuilder(); int bc = 0; byte cur = 0; fixed(byte * bPtr = &src[offset]) { int * ptr = (int *)bPtr; for( int i = 0 ; i < length ; i++ ) { cur = (byte)((*ptr >> bc) & 0x7f ); bc += 7; if ( bc >= 32 ) { bc -= 32; cur |= (byte)(((*(++ptr)) << (7-bc)) & 0x7F); } msg.Append((char)cur); } }
return msg.ToString(); }
public override string ToString() { return PDUString; } }
public class SenderPDU : PDU {
private const int NUMBER_LENGTH = 10; private static readonly byte [] SubmitPDUHeader = { 0x00, 0x11, // msg Submit, TP-VP relative format 0x00, 0x0A, // number lenght = 10 0x91, // international format 0x00,0x00,0x00,0x00,0x00, // 5 bytes for phone number 0x00, // PID 0x00, // data coding scheme = 7 bit characters to utlize 160 character SMS 0xAA // validity period = 4 days };
public SenderPDU(string text,string number) { pduString = PreparePDU(text,number); }
protected string PreparePDU(string message,string receiver) { byte [] msg = StringToPDU(message); byte [] pdu = new byte[SubmitPDUHeader.Length + msg.Length + 1]; SubmitPDUHeader.CopyTo(pdu,0); pdu[SubmitPDUHeader.Length] = (byte)message.Length; for ( int i = SubmitPDUHeader.Length + 1 ; i < SubmitPDUHeader.Length + msg.Length + 1 ; i++ ) pdu[i] = msg[i - (SubmitPDUHeader.Length +1)];
if ( receiver.Length != NUMBER_LENGTH ) throw new ApplicationException("Receiver must be 10 characters."); else { byte [] recv = System.Text.Encoding.ASCII.GetBytes(receiver); for( int i = 0 ; i < NUMBER_LENGTH ; i++ ) { recv[i] -= 0x30; if ( recv[i] > 9 ) throw new ApplicationException("Invalid phone number"); else { if ( i % 2 == 0 ) pdu[(i/2)+NUMBER_OFFSET] = recv[i]; else pdu[(i/2)+NUMBER_OFFSET] |= (byte)(recv[i]<<4); } } }
septetLength = pdu.Length - 1; StringBuilder spdu = new StringBuilder(pdu.Length + 1); foreach(byte b in pdu) spdu.Append(b.ToString("X2")); spdu.Append((char)0x1a); return spdu.ToString(); }
'Prøv dette stykke kode. 'Du skal bruge en Form en mscomm og en knap
Option Explicit
'Tested on Siemens(19200 baud) and Bosch (9600 baud)
Private Sub Command1_Click() Dim sms As String Dim buffer$ If MSComm1.PortOpen = False Then MSComm1.CommPort = 7 MSComm1.Settings = "19200,N,8,1" MSComm1.InputLen = 0 MSComm1.Handshaking = comNone MSComm1.PortOpen = True End If
'echo off MSComm1.Output = "atE0" & Chr$(13) Do DoEvents buffer$ = buffer$ & MSComm1.Input Loop Until InStr(buffer$, "OK") buffer$ = ""
Do DoEvents buffer$ = buffer$ & MSComm1.Input Loop Until InStr(buffer$, "OK")
MSComm1.PortOpen = False
End Sub
Function MakeSms(number As String, txt As String) As String MakeSms = "001100" MakeSms = MakeSms + ConvNumber(number) MakeSms = MakeSms + "000064" MakeSms = MakeSms + ConvTxt(txt) End Function
Function ConvNumber(num As String) As String
Dim i As Integer Dim numType As String
'default local number numType = "81"
'but if international number then ..... If Left$(num, 3) = "+00" And Len(num) > 3 Then num = Mid$(num, 4): numType = "91" If Left$(num, 2) = "00" And Len(num) > 2 Then num = Mid$(num, 3): numType = "91" If Left$(num, 1) = "+" And Len(num) > 1 Then num = Mid$(num, 2): numType = "91"
ConvNumber = Right$("00" & Hex(Len(num)), 2)
ConvNumber = ConvNumber + numType
For i = 1 To Len(num) Step 2 ConvNumber = ConvNumber + Mid$(num + "F", i + 1, 1) + Mid$(num + "F", i, 1) Next i
End Function
Function ConvTxt(txt As String) As String Dim i As Integer Dim datArr1(1 To 256) As Byte
Dim l As Integer Dim touw As String
'no more than 160 chars If Len(txt) > 160 Then txt = Left$(txt, 160)
l = Len(txt)
ConvTxt = Right$("00" & Hex(Len(txt)), 2) For i = 1 To l datArr1(i) = Asc(Mid$(txt, i, 1)) Next i
'make a bit stream of septets touw = "" For i = 1 To l touw = ToBin7(datArr1(i)) + touw Next i
'and convert it to octets While Len(touw) > 8 ConvTxt = ConvTxt + Bin2Hex(Right$(touw, 8)) touw = Mid$(touw, 1, Len(touw) - 8) Wend
ConvTxt = ConvTxt + Bin2Hex(touw)
Debug.Print ConvTxt End Function
Function ToBin7(ByVal num As Byte) As String 'convert to padded 7 place binary number While num > 0 ToBin7 = Trim(num Mod 2) + ToBin7 num = num \ 2 Wend
ToBin7 = Right$("0000000" + ToBin7, 7) End Function
Function Bin2Hex(ByVal touw As String) As String 'convert binary to a padded 2 place hex number Dim x As Integer Dim num As Long
For x = 1 To Len(touw) If Mid$(touw, x, 1) = "1" Then num = num + 2 ^ (Len(touw) - x) End If Next x
Hvis det er noget du udvikler til andre så vil jeg foreslå at du finder et andet modem, så vil du opleve lykken ved at noget virker første gang. Du kan checke mit system ved at sende en SMS til +299486431 med teksten nuu så får du den aktuelle vind i Nuuk, Grønland, du kan også sende en blank SMS til samme nummer.
'Tested on Siemens(19200 baud) and Bosch (9600 baud)
Private Sub Command1_Click() Dim SMS As String Dim buffer$ If MSComm1.PortOpen = False Then MSComm1.CommPort = 1 MSComm1.Settings = "19200,N,8,1" MSComm1.InputLen = 0 MSComm1.Handshaking = comNone MSComm1.PortOpen = True End If
'echo off Sleep 1000 MSComm1.Output = "ATE0" & Chr$(13) Debug.Print "ATE0" Do DoEvents buffer$ = buffer$ & MSComm1.Input Loop Until InStr(buffer$, "OK") Debug.Print "OK" buffer$ = "" ' Udbyder SMS Central Nr +4540590000 = sonofon MSComm1.Output = "AT+CSCA=+4540590000" & Chr$(13) Debug.Print "AT+CSCA=+4540590000" Do DoEvents buffer$ = buffer$ & MSComm1.Input Loop Until InStr(buffer$, "OK") Debug.Print "OK" buffer$ = ""
MSComm1.Output = SMS Do DoEvents buffer$ = buffer$ & MSComm1.Input Loop Until InStr(buffer$, "OK") Or InStr(buffer$, "ERROR") Debug.Print buffer$ MSComm1.PortOpen = False
End Sub Function MakeSms(number As String, txt As String) As String MakeSms = "" 'MakeSms = MakeSms + ConvNumber(Central) MakeSms = MakeSms + "1100" MakeSms = MakeSms + ConvNumber(number) MakeSms = MakeSms + ConvTxt(txt) End Function Function ConvNumber(num As String) As String Dim i As Integer Dim numType As String
'default local number numType = "81"
'but if international number then ..... If Left$(num, 3) = "+00" And Len(num) > 3 Then num = Mid$(num, 4): numType = "91" If Left$(num, 2) = "00" And Len(num) > 2 Then num = Mid$(num, 3): numType = "91" If Left$(num, 1) = "+" And Len(num) > 1 Then num = Mid$(num, 2): numType = "91"
ConvNumber = Right$("00" & Hex(Len(num)), 2)
ConvNumber = ConvNumber + numType
For i = 1 To Len(num) Step 2 ConvNumber = ConvNumber + Mid$(num + "F", i + 1, 1) + Mid$(num + "F", i, 1) Next i ConvNumber = ConvNumber + "0000A7"
End Function
Function ConvTxt(txt As String) As String Dim i As Integer Dim datArr1(1 To 256) As Byte
Dim l As Integer Dim touw As String
'no more than 160 chars If Len(txt) > 160 Then txt = Left$(txt, 160)
l = Len(txt)
ConvTxt = Right$("00" & Hex(Len(txt)), 2) For i = 1 To l datArr1(i) = Asc(Mid$(txt, i, 1)) Next i
'make a bit stream of septets touw = "" For i = 1 To l touw = ToBin7(datArr1(i)) + touw Next i
'and convert it to octets While Len(touw) > 8 ConvTxt = ConvTxt + Bin2Hex(Right$(touw, 8)) touw = Mid$(touw, 1, Len(touw) - 8) Wend
ConvTxt = ConvTxt + Bin2Hex(touw)
End Function
Function ToBin7(ByVal num As Byte) As String 'convert to padded 7 place binary number While num > 0 ToBin7 = Trim(num Mod 2) + ToBin7 num = num \ 2 Wend
ToBin7 = Right$("0000000" + ToBin7, 7) End Function
Function Bin2Hex(ByVal touw As String) As String 'convert binary to a padded 2 place hex number Dim x As Integer Dim num As Long
For x = 1 To Len(touw) If Mid$(touw, x, 1) = "1" Then num = num + 2 ^ (Len(touw) - x) End If Next x
Bin2Hex = Right$("00" + Hex(num), 2) End Function
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.