Gammu internals  1.38.0
mbus2.c
Go to the documentation of this file.
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 
15 static GSM_Error MBUS2_WriteMessage (GSM_StateMachine *s,
16  unsigned const char *MsgBuffer,
17  int 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 
72 static GSM_Error MBUS2_SendAck(GSM_StateMachine *s,
73  unsigned char type,
74  unsigned char sequence)
75 {
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 
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 
150  return ERR_NONE;
151  }
152  if (d->MsgRXState == RX_GetLength1) {
153  d->Msg.Length = rx_char * 256;
154 
156  return ERR_NONE;
157  }
158  if (d->MsgRXState == RX_GetType) {
159  d->Msg.Type = rx_char;
160 
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",
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",
180  d->MsgRXState = RX_Sync;
181  return ERR_NONE;
182  }
183  d->Msg.Destination = rx_char;
184 
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 
198  return ERR_NONE;
199  }
200  return ERR_NONE;
201 }
202 
203 static GSM_Error MBUS2_Initialise(GSM_StateMachine *s)
204 {
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 
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  */
void GSM_DumpMessageBinary(GSM_StateMachine *s, unsigned const char *message, size_t messagesize, int type)
Definition: gsmstate.c:1583
unsigned char Source
Definition: protocol.h:20
GSM_Error(* DeviceSetDtrRts)(GSM_StateMachine *s, gboolean dtr, gboolean rts)
Definition: gsmstate.h:244
struct GSM_Protocol::@1 Data
GSM_Error(* DeviceSetParity)(GSM_StateMachine *s, gboolean parity)
Definition: gsmstate.h:240
#define MBUS2_ACK_BYTE
Definition: mbus2.h:12
GSM_Error
Definition: gammu-error.h:23
GSM_Error DispatchError
Definition: gsmstate.h:689
int(* WriteDevice)(GSM_StateMachine *s, const void *buf, size_t nbytes)
Definition: gsmstate.h:256
unsigned char Destination
Definition: protocol.h:21
int smprintf_level(GSM_StateMachine *s, GSM_DebugSeverity severity, const char *format,...)
Definition: debug.c:278
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
#define MBUS2_DEVICE_PHONE
Definition: mbus2.h:10
unsigned char CheckSum[2]
Definition: protocol.h:24
GSM_Device_Functions * Functions
Definition: gsmstate.h:335
GSM_Protocol Protocol
Definition: gsmstate.h:1430
GSM_Protocol_Message Msg
Definition: mbus2.h:17
GSM_Phone_Data Data
Definition: gsmstate.h:1369
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
Definition: debug.h:87
GSM_Error(* DispatchMessage)(GSM_StateMachine *s)
Definition: gsmstate.h:765
#define TRUE
Definition: gammu-types.h:28
#define MBUS2_FRAME_ID
Definition: mbus2.h:9
unsigned char * Buffer
Definition: protocol.h:22
#define MBUS2_DEVICE_PC
Definition: mbus2.h:11
GSM_Protocol_Message * RequestMsg
Definition: gsmstate.h:676
GSM_Error(* DeviceSetSpeed)(GSM_StateMachine *s, int speed)
Definition: gsmstate.h:248
void GSM_DumpMessageText(GSM_StateMachine *s, unsigned const char *message, size_t messagesize, int type)
Definition: gsmstate.c:1555
GSM_Device Device
Definition: gsmstate.h:1429
Definition: debug.h:91