Gammu internals  1.38.0
fbus2.c
Go to the documentation of this file.
1 /* (c) 2002-2003 by Marcin Wiacek */
2 /* based on some work from MyGnokii (www.mwiacek.com) */
3 /* Based on some work from Gnokii (www.gnokii.org)
4  * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot
5  * GNU GPL version 2 or later
6  */
7 /* Due to a problem in the source code management, the names of some of
8  * the authors have unfortunately been lost. We do not mean to belittle
9  * their efforts and hope they will contact us to see their names
10  * properly added to the Copyright notice above.
11  * Having published their contributions under the terms of the GNU
12  * General Public License (GPL) [version 2], the Copyright of these
13  * authors will remain respected by adhering to the license they chose
14  * to publish their code under.
15  */
16 
17 #include "../../gsmstate.h"
18 
19 #if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_DKU5FBUS2) || defined(GSM_ENABLE_FBUS2PL2303)
20 
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 
25 #include "../../gsmcomon.h"
26 #include "fbus2.h"
27 
28 static GSM_Error FBUS2_Initialise(GSM_StateMachine *s);
29 
30 static GSM_Error FBUS2_WriteFrame(GSM_StateMachine *s,
31  unsigned const char *MsgBuffer,
32  int MsgLength,
33  unsigned char MsgType)
34 {
35  unsigned char buffer[FBUS2_MAX_TRANSMIT_LENGTH + 10]={0};
36  unsigned char checksum=0;
37  int i=0, length=0, sent=0;
38 
39  buffer[0] = FBUS2_FRAME_ID;
40 
41  if (s->ConnectionType==GCT_FBUS2IRDA) {
42  buffer[0] = FBUS2_IRDA_FRAME_ID;
43  }
44  buffer[1] = FBUS2_DEVICE_PHONE; /* destination */
45  buffer[2] = FBUS2_DEVICE_PC; /* source */
46  buffer[3] = MsgType;
47  buffer[4] = MsgLength / 256;
48  buffer[5] = MsgLength % 256;
49  memcpy(buffer + 6, MsgBuffer, MsgLength);
50  length = MsgLength + 6;
51 
52  /* Odd messages require additional 0x00 byte */
53  if (MsgLength % 2) {
54  buffer[length++] = 0x00;
55  }
56  checksum = 0;
57 
58  for (i = 0; i < length; i+=2) {
59  checksum ^= buffer[i];
60  }
61  buffer[length++] = checksum;
62  checksum = 0;
63 
64  for (i = 1; i < length; i+=2) {
65  checksum ^= buffer[i];
66  }
67  buffer[length++] = checksum;
68 
69  /* Sending to phone */
70  sent = s->Device.Functions->WriteDevice(s, buffer, length);
71 
72  if (sent != length) {
73  return ERR_DEVICEWRITEERROR;
74  }
75  return ERR_NONE;
76 }
77 
78 static GSM_Error FBUS2_WriteMessage (GSM_StateMachine *s,
79  unsigned const char *MsgBuffer,
80  int MsgLength,
81  int MsgType)
82 {
83  int i=0, nom=0, togo=0, thislength=0; /* number of messages, ... */
84  unsigned char buffer[FBUS2_MAX_TRANSMIT_LENGTH + 2]={0}, seqnum=0;
85  GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2;
86  GSM_Error error;
87 
88  GSM_DumpMessageBinary(s, MsgBuffer, MsgLength, MsgType);
89 
90  nom = (MsgLength + FBUS2_MAX_TRANSMIT_LENGTH - 1) / FBUS2_MAX_TRANSMIT_LENGTH;
91  togo = MsgLength;
92 
93  for (i = 0; i < nom; i++) {
94  seqnum = d->MsgSequenceNumber;
95 
96  if (i==0) {
97  seqnum = seqnum + 0x40;
98  }
99  d->MsgSequenceNumber = (d->MsgSequenceNumber + 1) & 0x07;
100 
101  thislength = togo;
102 
103  if (togo > FBUS2_MAX_TRANSMIT_LENGTH) {
104  thislength = FBUS2_MAX_TRANSMIT_LENGTH;
105  }
106  memcpy(buffer, MsgBuffer + (MsgLength - togo), thislength);
107  buffer[thislength] = nom - i;
108  buffer[thislength + 1] = seqnum;
109  togo = togo - thislength;
110 
111  GSM_DumpMessageText(s, buffer, thislength, MsgType);
112 
113  error = FBUS2_WriteFrame(s, buffer, thislength + 2, MsgType);
114 
115  if (error != ERR_NONE) {
116  return error;
117  }
118  }
119  return ERR_NONE;
120 }
121 
122 static GSM_Error FBUS2_SendAck(GSM_StateMachine *s,
123  unsigned char MsgType,
124  unsigned char MsgSequence)
125 {
126  unsigned char buffer[2]={0};
127 
128  buffer[0] = MsgType;
129  buffer[1] = MsgSequence;
130 
131  smprintf_level(s, D_TEXT, "[Sending Ack of type %02x, seq %x]\n",
132  buffer[0],
133  buffer[1]);
134 
135  /* Sending to phone */
136  return FBUS2_WriteFrame(s, buffer, 2, FBUS2_ACK_BYTE);
137 }
138 
139 static GSM_Error FBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
140 {
141  GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2;
142  unsigned char frm_num, seq_num;
143  gboolean correct = FALSE;
144 
145  /* XOR the byte with the earlier checksum */
146  d->Msg.CheckSum[d->Msg.Count & 1] ^= rx_char;
147 
148  if (d->MsgRXState == RX_GetMessage) {
149  d->Msg.Buffer[d->Msg.Count] = rx_char;
150  d->Msg.Count++;
151 
152  /* This is not last byte in frame */
153  if (d->Msg.Count != d->Msg.Length+(d->Msg.Length%2)+2) return ERR_NONE;
154 
155  /* Checksum is incorrect */
156  if (d->Msg.CheckSum[0] != d->Msg.CheckSum[1]) {
157  smprintf_level(s, D_ERROR, "[ERROR: checksum]\n");
158  free(d->Msg.Buffer);
159  d->Msg.Buffer = NULL;
160  d->Msg.Length = 0;
161  d->MsgRXState = RX_Sync;
162  return ERR_NONE;
163  }
164 
165  seq_num = d->Msg.Buffer[d->Msg.Length-1];
166 
167  if (d->Msg.Type == FBUS2_ACK_BYTE) {
168  smprintf_level(s, D_TEXT, "[Received Ack of type %02x, seq %02x]\n",
169  d->Msg.Buffer[0], seq_num);
170  free(d->Msg.Buffer);
171  d->Msg.Buffer = NULL;
172  d->Msg.Length = 0;
173  d->MsgRXState = RX_Sync;
174  return ERR_NONE;
175  }
176 
177  frm_num = d->Msg.Buffer[d->Msg.Length-2];
178 
179  if ((seq_num & 0x40) == 0x40) {
180  d->FramesToGo = frm_num;
181  d->MultiMsg.Length = 0;
182  d->MultiMsg.Type = d->Msg.Type;
184  d->MultiMsg.Source = d->Msg.Source;
185  }
186 
187  if ((seq_num & 0x40) != 0x40 && d->FramesToGo != frm_num) {
188  smprintf_level(s, D_ERROR, "[ERROR: Missed part of multiframe msg]\n");
189  free(d->Msg.Buffer);
190  d->Msg.Buffer = NULL;
191  d->Msg.Length = 0;
192  d->MsgRXState = RX_Sync;
193  return ERR_NONE;
194  }
195 
196  if ((seq_num & 0x40) != 0x40 && d->Msg.Type != d->MultiMsg.Type) {
197  smprintf_level(s, D_ERROR, "[ERROR: Multiframe msg in multiframe msg]\n");
198  free(d->Msg.Buffer);
199  d->Msg.Buffer = NULL;
200  d->Msg.Length = 0;
201  d->MsgRXState = RX_Sync;
202  return ERR_NONE;
203  }
204 
205  if (d->MultiMsg.BufferUsed < d->MultiMsg.Length+d->Msg.Length-2) {
207  d->MultiMsg.Buffer = (unsigned char *)realloc(d->MultiMsg.Buffer,d->MultiMsg.BufferUsed);
208  }
209  memcpy(d->MultiMsg.Buffer+d->MultiMsg.Length,d->Msg.Buffer,d->Msg.Length-2);
210  d->MultiMsg.Length = d->MultiMsg.Length+d->Msg.Length-2;
211 
212  free(d->Msg.Buffer);
213  d->Msg.Buffer = NULL;
214  d->Msg.Length = 0;
215  d->FramesToGo--;
216 
217  /* do not ack debug trace, as this could generate a
218  * (feedback loop) flood of which even Noah would be scared.
219  */
220  if (d->Msg.Type != 0) {
221  FBUS2_SendAck(s,d->Msg.Type,((unsigned char)(seq_num & 0x0f)));
222  }
223 
224  if (d->FramesToGo == 0) {
225  s->Phone.Data.RequestMsg = &d->MultiMsg;
227  }
228  d->MsgRXState = RX_Sync;
229  return ERR_NONE;
230  }
231  if (d->MsgRXState == RX_GetLength2) {
232  d->Msg.Length = d->Msg.Length + rx_char;
233  d->Msg.Buffer = (unsigned char *)malloc(d->Msg.Length+3);
234  if (d->Msg.Buffer == NULL) {
235  return ERR_MOREMEMORY;
236  }
238  return ERR_NONE;
239  }
240  if (d->MsgRXState == RX_GetLength1) {
241  d->Msg.Length = rx_char * 256;
243  return ERR_NONE;
244  }
245  if (d->MsgRXState == RX_GetType) {
246  d->Msg.Type = rx_char;
248  return ERR_NONE;
249  }
250  if (d->MsgRXState == RX_GetSource) {
251  if (rx_char != FBUS2_DEVICE_PHONE) {
252  smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n",
253  rx_char, FBUS2_DEVICE_PHONE);
254 
255  d->MsgRXState = RX_Sync;
256  return ERR_NONE;
257  }
258  d->Msg.Source = rx_char;
259 
260  d->MsgRXState = RX_GetType;
261  return ERR_NONE;
262  }
263  if (d->MsgRXState == RX_GetDestination) {
264  if (rx_char != FBUS2_DEVICE_PC) {
265  smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n",
266  rx_char, FBUS2_DEVICE_PC);
267 
268  d->MsgRXState = RX_Sync;
269  return ERR_NONE;
270  }
271  d->Msg.Destination = rx_char;
272 
274  return ERR_NONE;
275  }
276  if (d->MsgRXState == RX_Sync) {
277  switch (s->ConnectionType) {
278  case GCT_FBUS2:
279  case GCT_FBUS2DLR3:
280  case GCT_DKU5FBUS2:
281  case GCT_FBUS2PL2303:
282  case GCT_FBUS2BLUE:
283  case GCT_BLUEFBUS2:
284  if (rx_char == FBUS2_FRAME_ID) correct = TRUE;
285  break;
286  case GCT_FBUS2IRDA:
287  if (rx_char == FBUS2_IRDA_FRAME_ID) correct = TRUE;
288  break;
289  default:
290  break;
291  }
292  if (!correct) {
293  smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n",
294  rx_char,
296  if (rx_char == 0x20) {
297  smprintf(s, "0x20 reply detected...\n");
298  smprintf(s, "Trying to reinit connection...\n");
299  FBUS2_Initialise(s);
300  }
301  return ERR_NONE;
302  }
303 
304  d->Msg.CheckSum[0] = rx_char;
305  d->Msg.CheckSum[1] = 0;
306  d->Msg.Count = 0;
307 
309  return ERR_NONE;
310  }
311  return ERR_NONE;
312 }
313 
314 #if defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_DKU5FBUS2) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2PL2303)
315 
320 static void FBUS2_WriteDLR3(GSM_StateMachine *s, const char *command, int length, int timeout)
321 {
322  unsigned char buff[300]={0};
323  int w = 0,recvlen=0;
324  gboolean wassomething = FALSE;
325 
326  GSM_DumpMessageText(s, command, length, 0xff);
327  s->Device.Functions->WriteDevice(s, command, length);
328 
329  for (w = 0; w < timeout; w++) {
330  recvlen = s->Device.Functions->ReadDevice(s, buff, sizeof(buff));
331 
332  if (wassomething && recvlen == 0) {
333  return;
334  } else if (recvlen > 0) {
335  GSM_DumpMessageTextRecv(s, buff, recvlen, 0xff);
336  wassomething = TRUE;
337  }
338  usleep(50000);
339  }
340 }
341 
347 static GSM_Error FBUS2_ATSwitch(GSM_StateMachine *s)
348 {
349  static const char init_1[] = "AT\r\n";
350  static const char init_2[] = "AT&F\r\n";
351  static const char init_3[] = "AT*NOKIAFBUS\r\n";
352 
353  smprintf(s, "Switching to FBUS using AT commands\n");
354 
355  FBUS2_WriteDLR3(s, init_1, strlen(init_1), 100);
356  FBUS2_WriteDLR3(s, init_2, strlen(init_2), 100);
357  FBUS2_WriteDLR3(s, init_3, strlen(init_3), 100);
358 
359  return ERR_NONE;
360 }
361 #endif
362 
366 static GSM_Error FBUS2_InitSequence(GSM_StateMachine *s, const int repeats, const int delays, const gboolean terminate)
367 {
368  int count=0,write_data=0;
369  static const unsigned char init_char = 0x55;
370  static const unsigned char end_init_char = 0xc1;
371 
372  for (count = 0; count < repeats; count ++) {
373  write_data=s->Device.Functions->WriteDevice(s, &init_char, 1);
374 
375  if (write_data != 1) {
376  return ERR_DEVICEWRITEERROR;
377  }
378 
379  if (delays > 0) {
380  usleep(delays);
381  }
382  }
383 
384  if (terminate) {
385  write_data=s->Device.Functions->WriteDevice(s, &end_init_char, 1);
386 
387  if (write_data != 1) {
388  return ERR_DEVICEWRITEERROR;
389  }
390  }
391  sleep(1);
392  return ERR_NONE;
393 }
394 
395 static GSM_Error FBUS2_Initialise(GSM_StateMachine *s)
396 {
397  GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2;
399  GSM_Error error;
400  unsigned char buff[300]={0};
401 
402  d->Msg.Length = 0;
403  d->Msg.Buffer = NULL;
404  d->MultiMsg.BufferUsed = 0;
405  d->MultiMsg.Length = 0;
406  d->MultiMsg.Buffer = NULL;
407 
408  d->MsgSequenceNumber = 0;
409  d->FramesToGo = 0;
410  d->MsgRXState = RX_Sync;
411 
412  error = Device->DeviceSetParity(s, FALSE);
413  if (error != ERR_NONE) return error;
414 
415  switch (s->ConnectionType) {
416 #if defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2BLUE)
417  case GCT_FBUS2BLUE:
418  case GCT_BLUEFBUS2:
419  error = FBUS2_ATSwitch(s);
420  if (error != ERR_NONE) return error;
421  break;
422 #endif
423 #if defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_DKU5FBUS2) || defined(GSM_ENABLE_FBUS2PL2303)
424  case GCT_DKU5FBUS2:
425  case GCT_FBUS2PL2303:
426  case GCT_FBUS2DLR3:
427  error = Device->DeviceSetDtrRts(s,FALSE,FALSE);
428  if (error != ERR_NONE) return error;
429  sleep(1);
430 
431  if (! s->NoPowerCable) {
432  error = Device->DeviceSetDtrRts(s,TRUE,TRUE);
433  if (error != ERR_NONE) return error;
434  sleep(1);
435  }
436 
437  error = Device->DeviceSetSpeed(s,19200);
438  if (error != ERR_NONE) return error;
439 
440  error = FBUS2_ATSwitch(s);
441  if (error != ERR_NONE) return error;
442 
443  error = Device->DeviceSetSpeed(s,115200);
444  if (error != ERR_NONE) return error;
445 
446  error = FBUS2_InitSequence(s, 32, 0, TRUE);
447  if (error != ERR_NONE) return error;
448 
449  break;
450 #endif
451  case GCT_FBUS2:
452  error = Device->DeviceSetSpeed(s,115200);
453  if (error != ERR_NONE) return error;
454 
455  /* Set DTR as power supply if needed, RTS is always low */
456  error = Device->DeviceSetDtrRts(s, !(s->NoPowerCable), FALSE);
457  if (error != ERR_NONE) return error;
458 
459  error = FBUS2_InitSequence(s, 32, 0, TRUE);
460  if (error != ERR_NONE) return error;
461 
462  break;
463 #ifdef GSM_ENABLE_FBUS2IRDA
464  case GCT_FBUS2IRDA:
465  error = Device->DeviceSetSpeed(s,9600);
466  if (error != ERR_NONE) return error;
467 
468  error = FBUS2_InitSequence(s, 32, 0, TRUE);
469  if (error != ERR_NONE) return error;
470 
471  error = Device->DeviceSetSpeed(s,115200);
472  if (error != ERR_NONE) return error;
473 
474  break;
475 #endif
476  default:
477  break;
478  }
479 
480  /* A bit more of synchronisation could be needed here */
482  error = FBUS2_InitSequence(s, 250, 100, FALSE);
483  if (error != ERR_NONE) return error;
484  }
485 
486  /* Read any possible junk on the line */
487  while (s->Device.Functions->ReadDevice(s, buff, sizeof(buff)) > 0) {
488  usleep(1000);
489  }
490 
491  return ERR_NONE;
492 }
493 
494 static GSM_Error FBUS2_Terminate(GSM_StateMachine *s)
495 {
496  free(s->Protocol.Data.FBUS2.Msg.Buffer);
497  s->Protocol.Data.FBUS2.Msg.Buffer = NULL;
498  free(s->Protocol.Data.FBUS2.MultiMsg.Buffer);
499  s->Protocol.Data.FBUS2.MultiMsg.Buffer = NULL;
500  sleep(2);
501  return ERR_NONE;
502 }
503 
504 GSM_Protocol_Functions FBUS2Protocol = {
505  FBUS2_WriteMessage,
506  FBUS2_StateMachine,
507  FBUS2_Initialise,
508  FBUS2_Terminate
509 };
510 
511 #endif
512 
513 /* How should editor hadle tabs in this file? Add editor commands here.
514  * vim: noexpandtab sw=8 ts=8 sts=8:
515  */
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
void GSM_DumpMessageTextRecv(GSM_StateMachine *s, unsigned const char *message, size_t messagesize, int type)
Definition: gsmstate.c:1560
GSM_Error(* DeviceSetParity)(GSM_StateMachine *s, gboolean parity)
Definition: gsmstate.h:240
GSM_ConnectionType ConnectionType
Definition: gsmstate.h:1402
#define FBUS2_DEVICE_PHONE
Definition: fbus2.h:24
GSM_Error
Definition: gammu-error.h:23
GSM_Error DispatchError
Definition: gsmstate.h:689
#define FBUS2_MAX_TRANSMIT_LENGTH
Definition: fbus2.h:28
GSM_Protocol_Message Msg
Definition: fbus2.h:35
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
#define FBUS2_ACK_BYTE
Definition: fbus2.h:26
GSM_Protocol_Message MultiMsg
Definition: fbus2.h:34
int gboolean
Definition: gammu-types.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
int(* ReadDevice)(GSM_StateMachine *s, void *buf, size_t nbytes)
Definition: gsmstate.h:252
unsigned char CheckSum[2]
Definition: protocol.h:24
GSM_Device_Functions * Functions
Definition: gsmstate.h:335
GSM_Protocol Protocol
Definition: gsmstate.h:1430
GSM_Phone_Data Data
Definition: gsmstate.h:1369
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
gboolean NoPowerCable
Definition: gsmstate.h:1410
Definition: debug.h:87
#define FBUS2_IRDA_FRAME_ID
Definition: fbus2.h:22
GSM_Error(* DispatchMessage)(GSM_StateMachine *s)
Definition: gsmstate.h:765
#define TRUE
Definition: gammu-types.h:28
unsigned char * Buffer
Definition: protocol.h:22
#define FBUS2_DEVICE_PC
Definition: fbus2.h:25
GSM_Protocol_Message * RequestMsg
Definition: gsmstate.h:676
#define FBUS2_FRAME_ID
Definition: fbus2.h:23
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
int smprintf(GSM_StateMachine *s, const char *format,...)
Definition: debug.c:261