Imported gammu 0.90.7
[gammu.git] / common / protocol / nokia / mbus2.c
blobd84e2f72ddc10b2763c3d0707744fde893f52641
2 #include "../../gsmstate.h"
4 #ifdef GSM_ENABLE_MBUS2
6 #include <stdio.h>
7 #include <string.h>
9 #include "../../gsmcomon.h"
10 #include "mbus2.h"
12 static GSM_Error MBUS2_WriteMessage (GSM_StateMachine *s, unsigned char *buffer,
13 int length, unsigned char type)
15 unsigned char *out_buffer, checksum = 0;
16 GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
17 int count, current=0, sent;
19 GSM_DumpMessageLevel3(s, buffer, length, type);
21 out_buffer = (unsigned char *)malloc(length + 8);
23 /* Preparing header of message */
24 out_buffer[current++] = MBUS2_FRAME_ID;
25 out_buffer[current++] = MBUS2_DEVICE_PHONE; /* Frame destination */
26 out_buffer[current++] = MBUS2_DEVICE_PC; /* Frame source */
27 out_buffer[current++] = type; /* Frame type */
28 out_buffer[current++] = length/256; /* Frame length */
29 out_buffer[current++] = length%256; /* Frame length */
31 /* Copying frame */
32 if (length != 0) {
33 memcpy(out_buffer + current, buffer, length);
34 current+=length;
37 /* According to http://www.flosys.com/tdma/n5160.html some phones
38 * can have problems with checksum equal 0x1F. Phones can recognize
39 * received frame, but won't send ACK for it. When checksum is 0x1F,
40 * we increment the sequence number
42 do {
43 d->MsgSequenceNumber++;
45 out_buffer[current] = d->MsgSequenceNumber;
47 /* Calculating checksum */
48 checksum = 0;
49 for (count = 0; count < current + 1; count++) checksum ^= out_buffer[count];
50 } while (checksum == 0x1f);
52 /* Adding sequence and checksum */
53 out_buffer[current++] = d->MsgSequenceNumber;
54 out_buffer[current++] = checksum;
56 /* Writing debug output */
57 GSM_DumpMessageLevel2(s, out_buffer+6, length, type);
59 /* Sending to phone */
60 my_sleep(10);
61 sent=s->Device.Functions->WriteDevice(s,out_buffer,current);
63 free(out_buffer);
65 if (sent!=current) return GE_DEVICEWRITEERROR;
66 return GE_NONE;
69 static GSM_Error MBUS2_SendAck(GSM_StateMachine *s, unsigned char type, unsigned char sequence)
71 GSM_Device_Functions *Device = s->Device.Functions;
72 unsigned char out_buffer[6];
73 int count;
75 out_buffer[0] = MBUS2_FRAME_ID;
76 out_buffer[1] = MBUS2_DEVICE_PHONE;
77 out_buffer[2] = MBUS2_DEVICE_PC;
78 out_buffer[3] = MBUS2_ACK_BYTE;
79 out_buffer[4] = sequence;
80 out_buffer[5] = 0;
82 /* Calculating checksum */
83 for (count = 0; count < 5; count++) out_buffer[5] ^= out_buffer[count];
85 if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
86 s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
87 smprintf(s,"[Sending Ack of type %02x, seq: %x]\n",type,sequence);
90 /* Sending to phone */
91 my_sleep(10);
92 if (Device->WriteDevice(s,out_buffer,6)!=6) return GE_DEVICEWRITEERROR;
94 return GE_NONE;
97 static GSM_Error MBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_byte)
99 GSM_Phone_Functions *Phone = s->Phone.Functions;
100 GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
102 d->Msg.CheckSum[0] = d->Msg.CheckSum[1];
103 d->Msg.CheckSum[1] ^= rx_byte;
105 switch (d->MsgRXState) {
107 case RX_Sync:
109 if (rx_byte == MBUS2_FRAME_ID) {
110 d->Msg.CheckSum[1] = MBUS2_FRAME_ID;
111 d->Msg.Count = 0;
112 d->MsgRXState = RX_GetDestination;
113 } else {
114 if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
115 s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
116 smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_byte, MBUS2_FRAME_ID);
119 break;
121 case RX_GetDestination:
123 if (rx_byte != MBUS2_DEVICE_PC && rx_byte != MBUS2_DEVICE_PHONE) {
124 d->MsgRXState = RX_Sync;
125 if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
126 s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
127 smprintf(s,"[ERROR: incorrect char - %02x, not %02x and %02x]\n", rx_byte, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC);
129 } else {
130 d->Msg.Destination = rx_byte;
131 d->MsgRXState = RX_GetSource;
133 break;
135 case RX_GetSource:
137 if (rx_byte != MBUS2_DEVICE_PHONE && rx_byte != MBUS2_DEVICE_PC) {
138 d->MsgRXState = RX_Sync;
139 if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
140 s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
141 smprintf(s,"[ERROR: incorrect char - %02x, not %02x and %02x]\n", rx_byte, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC);
143 } else {
144 d->Msg.Source = rx_byte;
145 d->MsgRXState = RX_GetType;
147 break;
149 case RX_GetType:
151 d->Msg.Type = rx_byte;
152 d->MsgRXState = RX_GetLength1;
153 break;
155 case RX_GetLength1:
157 d->Msg.Length = rx_byte * 256;
158 d->MsgRXState = RX_GetLength2;
159 break;
161 case RX_GetLength2:
163 if (d->Msg.Type == MBUS2_ACK_BYTE)
165 if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
166 s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
167 smprintf(s,"[Received Ack]\n");
169 d->MsgRXState = RX_Sync;
170 } else {
171 d->Msg.Length = d->Msg.Length + rx_byte;
172 if (d->Msg.BufferUsed < d->Msg.Length+2) {
173 d->Msg.BufferUsed = d->Msg.Length+2;
174 d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
176 d->MsgRXState = RX_GetMessage;
178 break;
180 case RX_GetMessage:
182 d->Msg.Buffer[d->Msg.Count] = rx_byte;
183 d->Msg.Count++;
185 if (d->Msg.Count == d->Msg.Length+2) {
186 /* If this is the last byte, it's the checksum. */
187 /* Is the checksum correct? */
188 if (d->Msg.CheckSum[0] == rx_byte) {
189 if (d->Msg.Destination != MBUS2_DEVICE_PHONE) {
190 MBUS2_SendAck(s, d->Msg.Type, d->Msg.Buffer[d->Msg.Count-2]);
191 s->Phone.Data.RequestMsg = &d->Msg;
192 s->Phone.Data.DispatchError = Phone->DispatchMessage(s);
194 } else {
195 if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
196 s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
197 smprintf(s,"[ERROR: checksum]\n");
200 d->MsgRXState = RX_Sync;
202 break;
206 return GE_NONE;
209 static GSM_Error MBUS2_Initialise(GSM_StateMachine *s)
211 GSM_Device_Functions *Device = s->Device.Functions;
212 GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
213 GSM_Error error;
215 d->Msg.Length = 0;
216 d->Msg.BufferUsed = 0;
217 d->Msg.Buffer = NULL;
219 d->MsgSequenceNumber = 0;
220 d->MsgRXState = RX_Sync;
222 error=Device->DeviceSetSpeed(s,9600);
223 if (error!=GE_NONE) return error;
225 error=Device->DeviceSetParity(s,true);
226 if (error!=GE_NONE) return error;
228 error=Device->DeviceSetDtrRts(s,false,true); /*DTR low,RTS high*/
229 if (error!=GE_NONE) return error;
230 my_sleep(200);
232 return GE_NONE;
235 static GSM_Error MBUS2_Terminate(GSM_StateMachine *s)
237 free(s->Protocol.Data.MBUS2.Msg.Buffer);
238 return GE_NONE;
241 GSM_Protocol_Functions MBUS2Protocol = {
242 MBUS2_WriteMessage,
243 MBUS2_StateMachine,
244 MBUS2_Initialise,
245 MBUS2_Terminate
248 #endif
250 /* How should editor hadle tabs in this file? Add editor commands here.
251 * vim: noexpandtab sw=8 ts=8 sts=8: