Avatar billede midcom Nybegynder
21. juli 2005 - 17:53 Der 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
Avatar billede driis Nybegynder
21. juli 2005 - 18:11 #1
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.
Avatar billede midcom Nybegynder
21. juli 2005 - 18:28 #2
kan du lave et eks. på en PDU pakke
Avatar billede driis Nybegynder
21. juli 2005 - 19:10 #3
Jeg har brugt det her C# kode, jeg har desværre ikke noget i VB:

public abstract class PDU
    {
        protected int septetLength = 0;
        protected string pduString = String.Empty;
        protected const int NUMBER_OFFSET = 5;

        public int SeptetLength
        {
            get { return septetLength; }
        }

        public string PDUString
        {
            get { return pduString; }
        }

        protected unsafe byte [] StringToPDU(string str)
        {
            byte [] ascii = System.Text.Encoding.ASCII.GetBytes(str);
            int cbOut = (ascii.Length * 7);
            if ( cbOut % 8 != 0 )
                cbOut = cbOut / 8 + 1;
            else
                cbOut /= 8;
           
            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();
        }
Avatar billede midcom Nybegynder
21. juli 2005 - 19:15 #4
Siger mig ikke en disse
Avatar billede jens_nuuk Nybegynder
22. juli 2005 - 04:47 #5
Hvorfor sender du ikke SMS'en som ren tekst i stedet for i PDU mode
Du kan sæte modemet op til at modtage tekst og AT kommandoer.
Avatar billede midcom Nybegynder
22. juli 2005 - 09:08 #6
Den kan kun sende i PDU
Melder fejl nå jeg prøver at sætte den til text format
Avatar billede midcom Nybegynder
22. juli 2005 - 09:50 #7
TEKST = "hellohello" OG ER E8329BFD4697D9EC37
AT+CMGS=23
> 0011000A9154010203040000AA09E8329BFD4697D9EC37
ERROR
Sådan sender jeg
Avatar billede jens_nuuk Nybegynder
23. juli 2005 - 01:05 #8
Behøver det så være et Siemens M1 modem?
Jeg bruger et Wavecom Fastrack modem det fungerer perfekt i tekst mode.
Avatar billede midcom Nybegynder
23. juli 2005 - 08:39 #9
Ja nu sidder jeg jo lige med et Siemens M1
Avatar billede jens_nuuk Nybegynder
24. juli 2005 - 04:34 #10
'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$ = ""
 
  'set pdu mode
  MSComm1.Output = "AT+CMGF=0" & Chr$(13)
  Do
      DoEvents
  buffer$ = buffer$ & MSComm1.Input
  Loop Until InStr(buffer$, "OK")
  buffer$ = ""
 
  sms = MakeSms("004917212345678", "Does it work?")
 
  Debug.Print sms
 
  MSComm1.Output = "AT+CMGS=" & Len(sms) / 2 & Chr$(13)
  Do
      DoEvents
  buffer$ = buffer$ & MSComm1.Input
  Loop Until InStr(buffer$, ">")
  buffer$ = ""
 
  MSComm1.Output = sms + Chr$(26)
 
  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
 
  Bin2Hex = Right$("00" + Hex(num), 2)
End Function
Avatar billede midcom Nybegynder
25. juli 2005 - 00:21 #11
Hej Jens.
Det er ellers et fint det du kom med.
Men den melder stadig ERROR
dette sendes der ud på port

0011000A9154xxxxxxxx0000AA0AE8329BFD4697D9EC37
Avatar billede jens_nuuk Nybegynder
25. juli 2005 - 02:15 #12
Du kan prøve at downloade denne fil
www.inusoft.dk/upload/pdu.zip
Det kan være den kan hjælpe.

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.
Avatar billede midcom Nybegynder
25. juli 2005 - 12:23 #13
Ja det ender det nok med. For dette her lort kan jeg ikke få til at virke.
Men tak for hjælpen
Avatar billede midcom Nybegynder
26. juli 2005 - 16:28 #14
Det lykkes alligevel..


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 = 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 = "AT+CMGF=0" & Chr$(13)
  Debug.Print "AT+CMGF=0"
  Do
      DoEvents
  buffer$ = buffer$ & MSComm1.Input
  Loop Until InStr(buffer$, "OK")
  Debug.Print "OK"
  buffer$ = ""
 
  'xxxxxxxx = modtager nr
  SMS = MakeSms("+45xxxxxxxx", "hellohello")
 
  MSComm1.Output = "AT+CMGS=" & (Len(SMS) / 2 - 1) & Chr$(13)
  Debug.Print "AT+CMGS=" & (Len(SMS) / 2 - 1) & Chr$(13)
  Do
      DoEvents
  buffer$ = buffer$ & MSComm1.Input
  Loop Until InStr(buffer$, ">")
  Debug.Print ">"
  Debug.Print SMS
  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
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester