2013-03-09 33 views
9

Zajmuję się tworzeniem aplikacji dla modemów GSM (D-Link DWM-156) w języku C# .Net za pomocą poleceń AT. Mam problem z wysyłaniem wiadomości Unicode (takich jak wiadomości napisane w języku perskim lub arabskim). Oto rdzeń mojego programu:Wysyłanie komunikatów Unicode (np. W języku perskim i arabskim) w języku C# za pomocą poleceń AT za pośrednictwem modemu GSM

SerialPort GSMPort = new SerialPort(); 

GSMPort.PortName = "COM6"; 
GSMPort.BaudRate = 9600; 
GSMPort.Parity = Parity.None; 
GSMPort.DataBits = 8; 
GSMPort.StopBits = StopBits.One; 
GSMPort.Handshake = HandShake.RequestToSend; 
GSMPort.DtrEnable = true; 
GSMPort.RtsEnable = true; 

GSMPort.Open(); 

GSMPort.Write("AT\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGF=1\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n"); 
Thread.Sleep(1000); 
GSMPort.Write(shortMessage+ "\x1A"); 

Działa dobrze dla liter angielskich i ASCII. Czytałem this article i można wysyłać wiadomości Unicode w HyperTerminal za pomocą komend AT:

AT [Enter] 
OK 
AT+CSCS="UCS2" or AT+CSCS="HEX" [Enter] ---> We have to convert our message to hex 
OK 
AT+CMGF=1 [Enter] 
OK 
AT+CMGS="destinationNumber" [Enter] 
> 0633064406270645002006450631062D06280627 ---> The hex format of our message (سلام مرحبا) 
+CMGS: 139 
OK 

Od tego polecenia działało poprawnie, dodałem GSMPort.Write("AT+CSCS=\"UCS2\"\r"); do mojego wniosku i próbowała wysłać 0645 0631 062D 0628 0627 (مرحبا) lub (سلام).

GSMPort.Write("AT\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CSCS=\"UCS2\"\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGF=1\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n"); 
Thread.Sleep(1000); 
GSMPort.Write("0633064406270645" + "\x1A"); 

Ale w przeciwieństwie do poleceń AT w HyperTerminal, cel podróży nie otrzymuje poprawnych liter. Jaka jest różnica między tymi poleceniami AT w kodzie C# a kodem Hyperterminal? Będę wdzięczny, jeśli pomożesz mi rozwiązać ten problem.


Dodatkowe informacje: Jak wiecie nie mam problemu wysyłania wiadomości Unicode (takich jak Listy perskie) przez HyperTerminal i za pomocą komend AT. W poniższym kodzie próbuję wysłać سلام, a "0633064406270645" jest jego szesnastkową formą. Ale otrzymuję □□□□ w moim telefonie.

GSMPort.Encoding = UnicodeEncoding.GetEncoding(1256); 
GSMPort.Write("AT\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CSCS=\"UCS2\"\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGF=1\r"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n"); 
Thread.Sleep(1000); 
GSMPort.Write("0633064406270645" + "\x1A"); 

W środowisku hiperterminalnym Z drugiej strony wszystko idzie dobrze, a ja otrzymuję komunikat سلام.

AT [Enter] 
OK 
AT+CSCS="UCS2" 
OK 
AT+CMGF=1 [Enter] 
OK 
AT+CMGS="destinationNumber" [Enter] 
> 0633064406270645 [Ctrl+Z] 
+CMGS: 139 
OK 

Zauważyłem, że we właściwościach HyperTerminal gdybym sprawdzić „linię wysyłania kończy się linia zasila” (jest w Ustawienia-> Ustawienia-> Nastawienia ASCII, sprawdź poniższy obrazek), będę mieć ten sam problem, jaki miałem w kodzie C#. Sądzę, że domyślnie włączona jest opcja "wysyłanie linii końcowych z wierszami" w GSMPort.Write? Jeśli tak, jak mogę go wyłączyć?

enter image description here

+1

na twoim AT + CMGS polecenie ci pisowni tak dobrze, jak \ r \ n. W skrypcie AT widzę tylko \ r. – rene

+0

Tak, to prawda, WriteLine generuje dodatkowe linie ([Enter]) w wiadomości. –

+0

sprawdź, czy twój modem obsługuje kodowanie Unicode! – saeed

Odpowiedz

8

I w końcu okazało się, jak rozwiązać ten problem.Jak już wspomniałem w sekcji "Informacje dodatkowe" mojego pytania, wysyłanie linii kończy się z powodu linii, która spowodowała niedopasowanie między SerialPort w C# i komend AT w trybie hiperterminalnym do wysyłania wiadomości Unicode. Właśnie zastąpiłem \r liniami danych \n. Zmodyfikowany kod jest następująca:

GSMPort.Write("AT\n"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CSCS=\"UCS2\"\n"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGF=1\n"); 
Thread.Sleep(1000); 
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\n"); 
Thread.Sleep(1000); 
GSMPort.Write("0633064406270645" + "\x1A"); 

Leave SerialPort.Encoding i SerialPort.NewLine właściwości niezmienione. Zmiana ich wartości domyślnych nie jest konieczna, wystarczy ustawić AT+CSCS="UCS2", aby wysyłać wiadomości w formacie Unicode.

+0

Pomogło mi to, więc oznaczyłem to jako przydatne, ale wciąż mam pytanie: czy konwertujesz wszystkie wiadomości na HEX, w tym ASCII lub UNICODE? Doceniam, czy mógłbyś mi powiedzieć, co w końcu zrobiłeś. – Masoud

+0

@Masoud Założyłem, aby wysyłać arabskie sms za pomocą powyższego kodu, ale otrzymałem "otrzymane zgłoszenie jest niekompletne" Czy możesz mi pomóc –

2

Domyślne kodowanie dla SerialPort jest . Ustaw kod SerialPort.Encoding na kod obsługujący używany zestaw znaków (np. Encoding.UTF32) lub użyj SerialPort.Write(char[], int, int) i przekonwertuj ciąg znaków Unicode na bajty w dowolny sposób.

+0

Dzięki za odpowiedź. Zmieniłem kodowanie GSMPort.Encoding na Encoding.UTF8, Encoding.Unicode i Encoding.UTF32. Ale żadna z tych zmian nie zakończyła się sukcesem. Problem nadal istnieje: GSMPort.Write ("AT + CSCS = \" UCS2 \ "\ r"); GSMPort.Encoding = Kodowanie.Unicode; –

+0

Upewnij się, że ustawiłeś "Kodowanie" * przed * nazywasz 'Write' –

+0

Tak, wcześniej nazwałem' GSMPort.Encoding' przed wszystkimi 'Write's, ale nadal nie działa. –

2

Przede wszystkim sprawdź obsługę modemu unicode następnie zmienić swój kod do tego
musimy podać prawidłową DCS (dane Coding Scheme) dla wiadomości Unicode, czyli 0x08.

Możemy ustawić tę wartość przez zmianę czwarty parametr komendy AT + CSMP do '8':

AT + CSMP = 1,167,0,8

GSMPort.Write("AT\r"); 
    Thread.Sleep(1000); 
    GSMPort.Write("AT+CSCS=\"UCS2\"\r"); 
    Thread.Sleep(1000); 
    GSMPort.Write("AT+CMGF=1\r"); 
    Thread.Sleep(1000); 
    GSMPort.Write("AT+CSMP=1,167,0,8\r"); //AT+CSMP=1,167,0,8 
    Thread.Sleep(1000); 
    GSMPort.WriteLine("AT+CMGS=\"" + destinationNumber + "\"\r\n"); 
    Thread.Sleep(1000); 
    GSMPort.WriteLine("0633064406270645" + "\x1A"); 
+0

Mogę wysyłać wiadomości Unicode za pomocą poleceń AT w środowisku Hyperterminal, więc tak, jestem pewien, że modem obsługuje Unicode. Dzięki za twoje rozwiązanie wypróbowałem 'GSMPort.Write (" AT + CSMP = 1,167,0,8 \ r ");' ale nic nie zmienia. Używając 'AT + CSMP?' Ta struktura w trybie hiperterminalnym to '+ AT + CSMP = 1,071,0,0', ale nie działa również. Próbowałem też 'AT + CSMP = 1,07, 8, 8'. –

+0

czy działa poprawnie, gdy wysyłasz sms za pomocą poleceń hyperterminal, jeśli tak, to jaka jest kolejka poleceń – saeed

+0

Proszę sprawdzić moje pytanie. Opiszę, jaka sekwencja poleceń AT użyłem w hyperterminalu. Jeśli potrzebujesz więcej informacji na temat mojego modemu i jego statusu, proszę daj mi znać. –