1 /* (c) 2001-2003 by Marcin Wiacek */
2 /* based on some work from MyGnokii (www.mwiacek.com) */
3
4 #include "../../gsmstate.h"
5
6 #ifdef GSM_ENABLE_MBUS2
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11
12 #include "../../gsmcomon.h"
13 #include "mbus2.h"
14
MBUS2_WriteMessage(GSM_StateMachine * s,unsigned const char * MsgBuffer,size_t MsgLength,int MsgType)15 static GSM_Error MBUS2_WriteMessage (GSM_StateMachine *s,
16 unsigned const char *MsgBuffer,
17 size_t MsgLength,
18 int MsgType)
19 {
20 unsigned char *buffer=NULL, checksum = 0;
21 GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
22 int i=0, sent=0, length=0;
23
24 GSM_DumpMessageBinary(s, MsgBuffer, MsgLength, MsgType);
25
26 buffer = (unsigned char *)malloc(MsgLength + 8);
27
28 buffer[0] = MBUS2_FRAME_ID;
29 buffer[1] = MBUS2_DEVICE_PHONE; /* destination */
30 buffer[2] = MBUS2_DEVICE_PC; /* source */
31 buffer[3] = MsgType;
32 buffer[4] = MsgLength / 256;
33 buffer[5] = MsgLength % 256;
34
35 memcpy(buffer + 6, MsgBuffer, MsgLength);
36 length = 6 + MsgLength;
37
38 /* According to http://www.flosys.com/tdma/n5160.html some phones
39 * can have problems with checksum equal 0x1F. Phones can recognize
40 * received frame, but won't send ACK for it. When checksum is 0x1F,
41 * we increment the sequence number
42 */
43 do {
44 d->MsgSequenceNumber++;
45
46 buffer[length] = d->MsgSequenceNumber;
47
48 /* Calculating checksum */
49 checksum = 0;
50
51 for (i = 0; i < length + 1; i++) {
52 checksum ^= buffer[i];
53 }
54 } while (checksum == 0x1f);
55
56 buffer[length++] = d->MsgSequenceNumber;
57 buffer[length++] = checksum;
58
59 GSM_DumpMessageText(s, buffer+6, MsgLength, MsgType);
60
61 /* Sending to phone */
62 sent=s->Device.Functions->WriteDevice(s,buffer,length);
63 free(buffer);
64 buffer=NULL;
65
66 if (sent!=length) {
67 return ERR_DEVICEWRITEERROR;
68 }
69 return ERR_NONE;
70 }
71
MBUS2_SendAck(GSM_StateMachine * s,unsigned char type,unsigned char sequence)72 static GSM_Error MBUS2_SendAck(GSM_StateMachine *s,
73 unsigned char type,
74 unsigned char sequence)
75 {
76 GSM_Device_Functions *Device = s->Device.Functions;
77 unsigned char buffer[6]={0};
78 int i=0,length=0,write_data=0;
79
80 buffer[0] = MBUS2_FRAME_ID;
81 buffer[1] = MBUS2_DEVICE_PHONE; /* destination */
82 buffer[2] = MBUS2_DEVICE_PC; /* source */
83 buffer[3] = MBUS2_ACK_BYTE;
84 buffer[4] = sequence;
85 buffer[5] = '\0';
86 length=strlen(buffer);
87
88 /* Calculating checksum */
89 for (i = 0; i < length; i++) {
90 buffer[5] ^= buffer[i];
91 }
92 smprintf_level(s, D_TEXT, "[Sending Ack of type %02x, seq: %x]\n",type,sequence);
93
94 /* Sending to phone */
95 write_data=Device->WriteDevice(s,buffer,length);
96
97 if (write_data!=length) {
98 return ERR_DEVICEWRITEERROR;
99 }
100 return ERR_NONE;
101 }
102
MBUS2_StateMachine(GSM_StateMachine * s,unsigned char rx_char)103 static GSM_Error MBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
104 {
105 GSM_Phone_Functions *Phone = s->Phone.Functions;
106 GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
107
108 d->Msg.CheckSum[0] = d->Msg.CheckSum[1];
109 d->Msg.CheckSum[1] ^= rx_char;
110
111 if (d->MsgRXState == RX_GetMessage) {
112 d->Msg.Buffer[d->Msg.Count] = rx_char;
113 d->Msg.Count++;
114
115 /* This is not last byte in frame */
116 if (d->Msg.Count != d->Msg.Length+2) return ERR_NONE;
117
118 /* Checksum is incorrect */
119 if (d->Msg.CheckSum[0] != rx_char) {
120 smprintf_level(s, D_ERROR, "[ERROR: checksum]\n");
121
122 d->MsgRXState = RX_Sync;
123 return ERR_NONE;
124 }
125
126 if (d->Msg.Destination != MBUS2_DEVICE_PHONE) {
127 MBUS2_SendAck(s, d->Msg.Type, d->Msg.Buffer[d->Msg.Count-2]);
128 s->Phone.Data.RequestMsg = &d->Msg;
129 s->Phone.Data.DispatchError = Phone->DispatchMessage(s);
130 }
131
132 d->MsgRXState = RX_Sync;
133 return ERR_NONE;
134 }
135 if (d->MsgRXState == RX_GetLength2) {
136 if (d->Msg.Type == MBUS2_ACK_BYTE) {
137 smprintf_level(s, D_TEXT, "[Received Ack]\n");
138
139 d->MsgRXState = RX_Sync;
140 return ERR_NONE;
141 }
142
143 d->Msg.Length = d->Msg.Length + rx_char;
144 if (d->Msg.BufferUsed < d->Msg.Length+2) {
145 d->Msg.BufferUsed = d->Msg.Length+2;
146 d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
147 }
148
149 d->MsgRXState = RX_GetMessage;
150 return ERR_NONE;
151 }
152 if (d->MsgRXState == RX_GetLength1) {
153 d->Msg.Length = rx_char * 256;
154
155 d->MsgRXState = RX_GetLength2;
156 return ERR_NONE;
157 }
158 if (d->MsgRXState == RX_GetType) {
159 d->Msg.Type = rx_char;
160
161 d->MsgRXState = RX_GetLength1;
162 return ERR_NONE;
163 }
164 if (d->MsgRXState == RX_GetSource) {
165 if (rx_char != MBUS2_DEVICE_PHONE && rx_char != MBUS2_DEVICE_PC) {
166 smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x and %02x]\n",
167 rx_char, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC);
168 d->MsgRXState = RX_Sync;
169 return ERR_NONE;
170 }
171 d->Msg.Source = rx_char;
172
173 d->MsgRXState = RX_GetType;
174 return ERR_NONE;
175 }
176 if (d->MsgRXState == RX_GetDestination) {
177 if (rx_char != MBUS2_DEVICE_PC && rx_char != MBUS2_DEVICE_PHONE) {
178 smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x and %02x]\n",
179 rx_char, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC);
180 d->MsgRXState = RX_Sync;
181 return ERR_NONE;
182 }
183 d->Msg.Destination = rx_char;
184
185 d->MsgRXState = RX_GetSource;
186 return ERR_NONE;
187 }
188 if (d->MsgRXState == RX_Sync) {
189 if (rx_char != MBUS2_FRAME_ID) {
190 smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n",
191 rx_char, MBUS2_FRAME_ID);
192 return ERR_NONE;
193 }
194 d->Msg.CheckSum[1] = MBUS2_FRAME_ID;
195 d->Msg.Count = 0;
196
197 d->MsgRXState = RX_GetDestination;
198 return ERR_NONE;
199 }
200 return ERR_NONE;
201 }
202
MBUS2_Initialise(GSM_StateMachine * s)203 static GSM_Error MBUS2_Initialise(GSM_StateMachine *s)
204 {
205 GSM_Device_Functions *Device = s->Device.Functions;
206 GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
207 GSM_Error error;
208
209 d->Msg.Length = 0;
210 d->Msg.BufferUsed = 0;
211 d->Msg.Buffer = NULL;
212
213 d->MsgSequenceNumber = 0;
214 d->MsgRXState = RX_Sync;
215
216 error=Device->DeviceSetSpeed(s,9600);
217 if (error!=ERR_NONE) return error;
218
219 error=Device->DeviceSetParity(s,TRUE);
220 if (error!=ERR_NONE) return error;
221
222 error=Device->DeviceSetDtrRts(s,FALSE,TRUE); /*DTR low,RTS high*/
223 if (error!=ERR_NONE) return error;
224 usleep(200000);
225
226 return ERR_NONE;
227 }
228
MBUS2_Terminate(GSM_StateMachine * s)229 static GSM_Error MBUS2_Terminate(GSM_StateMachine *s)
230 {
231 free(s->Protocol.Data.MBUS2.Msg.Buffer);
232 s->Protocol.Data.MBUS2.Msg.Buffer=NULL;
233 return ERR_NONE;
234 }
235
236 GSM_Protocol_Functions MBUS2Protocol = {
237 MBUS2_WriteMessage,
238 MBUS2_StateMachine,
239 MBUS2_Initialise,
240 MBUS2_Terminate
241 };
242
243 #endif
244
245 /* How should editor hadle tabs in this file? Add editor commands here.
246 * vim: noexpandtab sw=8 ts=8 sts=8:
247 */
248