Модем Cinterion BGS2T RS232 (GSM - модем). Подключен через Prolific USB-to-Serial Comm Port как стандартный модем 9600. ОС Windows 7 x64. Отправка СМС работает без проблем, пока не попытаться их получить. При попытке получения MessageBox выдает следующее сообщение:
AT+CMGF=1
AT+CMGL="ALL" OK
И больше ничего не выдает. Нажимаю OK, программа продолжает работу и по таймеру продолжает выдавать такие же сообщения. После попытки получения СМС модем перестает их отправлять, в том числе, в версии программы, где есть только отправка СМС без их получения. Программа при попытке отправить СМС не выдает никаких исключений. Если сим-карта вставлена в мобильный телефон, СМС приходят. СМС, которые пытался отправить на модем, во входящих на телефоне нет. Модем снова начинает отправлять СМС после выключения и включения его питания. Программа следующая, частично официально использует модифицированный текст готовой программы. Вопрос, есть ли ошибки в тексте программы, например, неправильный алгоритм получения СМС, или дело скорее в модеме, например, неправильные команды для данного модема.
C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
| public class GSM_Modem
{
private bool _isInit;
public bool IsInit { get { return _isInit; } }
public GSM_Modem()
{
_isInit = false;
}
public void Init(string port_name, int baud_rate)
{
if (_isInit)
Close();
try
{
var comPort = OpenPort(port_name, baud_rate);
_isInit = true;
comPort.Close();
}
catch
{
}
}
public void Close()
{
if (_isInit)
{
_isInit = false;
}
}
private SerialPort OpenPort(string port_name, int baud_rate)
{
SerialPort port = new SerialPort();
port.PortName = port_name;
port.BaudRate = baud_rate;
port.Open();
return port;
}
public void ReadMessage(string port_name, int baud_rate, int iteration = 0)
{
Thread.Sleep(5000);
if (_isInit)
{
try
{
SerialPort port = OpenPort(port_name, baud_rate);
port.WriteLine(string.Format("AT+CMGF=1\r"));
port.WriteLine(string.Format("AT+CMGL=\"ALL\"\r"));
Thread.Sleep(1000);
String sms = port.ReadExisting();
MessageBox.Show(sms); //Для отладки
port.Close();
return;
}
catch (Exception e)
{
MessageBox.Show(e.Message); //Для отладки
}
}
if (iteration < 3)
{
Variables.InitGSM_Modem(port_name, baud_rate);
ReadMessage(port_name, baud_rate, iteration + 1);
}
}
public void SendMessage(string port_name, int baud_rate, string number, string message, int iteration = 0)
{
if (!string.IsNullOrEmpty(number))
{
Thread.Sleep(5000);
if (_isInit)
{
string phone = new string(number.Where(_ => Char.IsDigit(_)).ToArray());
phone = "7" + phone.Substring(1);
try
{
SerialPort port = OpenPort(port_name, baud_rate);
if (phone.Length % 2 == 1)
phone += "F";
StringBuilder phoneNumber = new StringBuilder();
for (int i = 0; i < phone.Length; ++i)
{
if (i % 2 == 1)
{
phoneNumber.Append(phone[i]);
phoneNumber.Append(phone[i - 1]);
}
}
StringBuilder text = new StringBuilder();
text.Append("00");
text.Append("11");
text.Append("00");
text.Append("0B");
text.Append("91");
text.Append(phoneNumber);
text.Append("00");
text.Append("08");
text.Append("A8");
text.Append((message.Length * 2).ToString("X2"));
text.Append(ucs2(message));
int lngt = (int)Math.Round(((double)(text.Length - 2)) / 2);
port.WriteLine(string.Format("AT+CMGS={0}\r", lngt));
Thread.Sleep(1000);
port.WriteLine(text.ToString() + (char)0x1A);
port.Close();
return;
}
catch
{
}
}
if (iteration < 3)
{
Variables.InitGSM_Modem(port_name, baud_rate);
SendMessage(port_name, baud_rate, number, message, iteration + 1);
}
}
}
private static string ucs2(string str)
{
StringBuilder result = new StringBuilder();
for (int i = 0; i < str.Length; ++i)
result.Append(((int)str[i]).ToString("X4"));
return result.ToString();
}
}
public class Variables
{
public static GSM_Modem Modem { get; set; }
public static bool InitGSM_Modem(string port_name, int baud_rate)
{
CloseGSM_Modem();
if (Modem == null)
Modem = new GSM_Modem();
Modem.Init(port_name, baud_rate);
return Modem.IsInit;
}
public static void CloseGSM_Modem()
{
if (Modem != null)
Modem.Close();
}
} |
|
СМС пока пытаюсь прочитать по таймеру. Модемы ищу в реестре и записываю в массив AllModems[] структур с именем порта (тип string) и его скоростью (тип int). Если не найден ни один модем, метод поиска возвращает null. СМС пытаюсь прочитать со всех модемов, в реальности модем один.
C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| AllModems[] Modems = FindModems.FindAllModems(); //Ищем модемы в реестре
if (Modems != null) //Если нашли хотя бы один модем
{
for (int i = 0; i < Modems.Length; i++) //Пытаемся читать СМС с найденных в реестре модемов
{
try
{
Variables.InitGSM_Modem(Modems[i].PortName, Modems[i].BaudRate);
Variables.Modem.ReadMessage(Modems[i].PortName, Modems[i].BaudRate);
Variables.CloseGSM_Modem(); //Не помогает и не влияет на поведение программы
}
catch (Exception e) {MessageBox.Show(e.Message); }
}
} |
|
Добавлено через 23 часа 33 минуты
Вроде бы разобрался сам - чтобы получать СМС, необходимо ввести задержку между командами Thread.Sleep, а чтобы отправлять после получения - перевести модем обратно из строкового в цифровой режим:
C# |
1
| port.WriteLine(string.Format("AT+CMGF=0\r")); |
|
Добавлено через 8 минут
string.Format в данном случае лишний, проще так:
C# |
1
| port.WriteLine("AT+CMGF=0\r"); |
|