summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/protocol/alcatel/alcabus.c
Unidiff
Diffstat (limited to 'gammu/emb/common/protocol/alcatel/alcabus.c') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/protocol/alcatel/alcabus.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/gammu/emb/common/protocol/alcatel/alcabus.c b/gammu/emb/common/protocol/alcatel/alcabus.c
new file mode 100644
index 0000000..b5b5a30
--- a/dev/null
+++ b/gammu/emb/common/protocol/alcatel/alcabus.c
@@ -0,0 +1,255 @@
1/* (c) 2002-2003 by Michal Cihar
2 *
3 * Low level functions for communication with Alcatel One Touch phones.
4 *
5 * This code implements the protocol used for synchronisation with PC.
6 */
7#include "../../gsmstate.h"
8
9#if defined(GSM_ENABLE_ALCABUS)
10
11#include <stdio.h>
12#include <string.h>
13
14#include "../../gsmcomon.h"
15#include "alcabus.h"
16
17static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned char *data, int len, unsigned char type)
18{
19 GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS;
20 unsigned char buffer[1024];
21 int size = 0;
22 int sent = 0;
23 int i = 0, checksum = 0;
24
25 if ((type == 0) && (len == 0)) return ERR_NONE;
26
27 buffer[0] = ALCATEL_HEADER;
28 buffer[1] = type;
29 switch (type) {
30 case ALCATEL_CONNECT:
31 buffer[2] = 0x0A;
32 buffer[3] = 0x04;
33 buffer[4] = 0x00;
34 size = 5;
35 d->next_frame = ALCATEL_CONNECT_ACK;
36 d->busy = true;
37 break;
38 case ALCATEL_DISCONNECT:
39 size = 2;
40 d->next_frame = ALCATEL_DISCONNECT_ACK;
41 d->busy = true;
42 break;
43 case ALCATEL_DATA:
44 buffer[2] = d->out_counter;
45
46 /* Increase outgoing packet counter */
47 if (d->out_counter == ALCATEL_MAX_COUNTER) d->out_counter = 0;
48 else d->out_counter++;
49
50 buffer[3] = '\0';
51 buffer[4] = len;
52 memcpy(buffer+5, data, len);
53 size = 5 + len;
54 d->next_frame = ALCATEL_ACK;
55 d->busy = true;
56 break;
57 case ALCATEL_ACK:
58 buffer[2] = d->in_counter;
59 if (d->in_counter == 0) d->in_counter = 1;
60 size = 3;
61 d->next_frame = ALCATEL_DATA;
62 break;
63 default:
64 /* In fact, other types probably can came just from mobile... */
65 smprintf(s,"WARNING: Wanted to send some unknown packet (%02X)\n", type);
66 return ERR_NOTIMPLEMENTED;
67 }
68
69 /* Calculate packet checksum */
70 for (i=0; i<size; i++) checksum ^= buffer[i];
71
72 buffer[size] = checksum;
73 size ++;
74
75 GSM_DumpMessageLevel2(s, buffer, size, type);
76 GSM_DumpMessageLevel3(s, buffer, size, type);
77 while (sent != size ) {
78 if ((i = s->Device.Functions->WriteDevice(s,buffer + sent, size - sent)) == 0) {
79 return ERR_DEVICEWRITEERROR;
80 }
81 sent += i;
82 }
83
84 if (type == ALCATEL_CONNECT || type == ALCATEL_DISCONNECT) {
85 /* For connect and disconnect we need a bit larger delay */
86 // my_sleep(10);
87 while (d->busy) {
88 GSM_ReadDevice(s,true);
89 my_sleep(1);
90 i++;
91 if (i == 10) return ERR_TIMEOUT;
92 }
93 }
94 return ERR_NONE;
95}
96
97static GSM_Error ALCABUS_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
98{
99 GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS;
100 int i;
101 int checksum = 0;
102
103 if (d->Msg.BufferUsed < d->Msg.Length + 1) {
104 d->Msg.BufferUsed= d->Msg.Length + 1;
105 d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
106 }
107
108 /* Check for header */
109 if ((d->Msg.Length == 0) && (rx_char != ALCATEL_HEADER)) {
110 smprintf(s,"WARNING: Expecting alcatel header (%02X) but got (%02X)\n", ALCATEL_HEADER, rx_char);
111 return ERR_UNKNOWNRESPONSE;
112 /* Check for packet type */
113 } else if (d->Msg.Length == 1){
114 d->Msg.Type = rx_char;
115 /* Was it unexpected packet? */
116 if ((rx_char != d->next_frame) && (rx_char != ALCATEL_CONTROL)) {
117 smprintf(s,"WARNING: Expecting alcatel packet type (%02X) but got (%02X)\n", d->next_frame, rx_char);
118 }
119 /* Determine packet size */
120 switch (rx_char) {
121 case ALCATEL_ACK:
122 d->expected_size = 4;
123 break;
124 case ALCATEL_DATA:
125 /* Packet length is in it's header */
126 d->expected_size = -1;
127 break;
128 case ALCATEL_CONTROL:
129 d->expected_size = 4;
130 break;
131 case ALCATEL_CONNECT_ACK:
132 d->expected_size = 6;
133 break;
134 case ALCATEL_DISCONNECT_ACK:
135 d->expected_size = 3;
136 break;
137 default:
138 smprintf(s,"WARNING: Something went wrong, unknown packet received (%02X)\n", rx_char);
139 return ERR_UNKNOWNRESPONSE;
140 }
141 /* Check counter, we can probably ignore error here ;-) */
142 } else if ((d->Msg.Length == 2) && (d->Msg.Type == ALCATEL_DATA)) {
143 if (rx_char != d->in_counter) {
144 smprintf(s,"WARNING: Unexpected packet number, ignoring (expected %02X, received %02X)\n", d->in_counter, rx_char);
145 d->in_counter = rx_char;
146 }
147 /* Increase incoming packet counter */
148 if (d->in_counter == ALCATEL_MAX_COUNTER) d->in_counter = 0;
149 else d->in_counter++;
150 /* Read size for data packet */
151 } else if ((d->Msg.Length == 4) && (d->Msg.Type == ALCATEL_DATA)) {
152 /* Header till now + checksum */
153 d->expected_size = (int)rx_char + 6;
154 }
155
156 /* Write received byte into buffer */
157 d->Msg.Buffer[d->Msg.Length++] = rx_char;
158
159 /* Did we received whole packet? */
160 if (d->expected_size == d->Msg.Length) {
161 /* Check checksum */
162 for (i=0; i< (d->Msg.Length - 1); i++) checksum ^= d->Msg.Buffer[i];
163 if (checksum != d->Msg.Buffer[d->Msg.Length - 1]) {
164 /* We can only warn, as we don't know what should happend now... */
165 smprintf(s,"WARNING: Ignoring incorrect packet checksum!\n");
166 }
167
168 /* Was it data? */
169 if (d->Msg.Type == ALCATEL_DATA) {
170 /* Dispatch message */
171 s->Phone.Data.RequestMsg= &d->Msg;
172 s->Phone.Data.DispatchError= s->Phone.Functions->DispatchMessage(s);
173 /* Send ack */
174 ALCABUS_WriteMessage (s, 0, 0, ALCATEL_ACK);
175 /* Reset message length */
176 d->Msg.Length = 0;
177 /* Was it ack? */
178 } else if ((d->Msg.Type == ALCATEL_ACK) ||
179 (d->Msg.Type == ALCATEL_CONTROL) ||
180 (d->Msg.Type == ALCATEL_CONNECT_ACK) ||
181 (d->Msg.Type == ALCATEL_DISCONNECT_ACK)) {
182 /* TODO: check counter of ack? */
183 if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
184 s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
185 smprintf(s, "Received %s ack ",
186 (d->Msg.Type == ALCATEL_ACK) ? "normal" :
187 (d->Msg.Type == ALCATEL_CONTROL) ? "control" :
188 (d->Msg.Type == ALCATEL_CONNECT_ACK) ? "connect" :
189 (d->Msg.Type == ALCATEL_DISCONNECT_ACK) ? "disconnect" :
190 "BUG");
191 smprintf(s, "0x%02x / 0x%04x", d->Msg.Type, d->Msg.Length);
192 DumpMessage(s->di.df, s->di.dl, d->Msg.Buffer, d->Msg.Length);
193 fflush(s->di.df);
194 }
195 if (s->di.dl==DL_BINARY) {
196 smprintf(s,"%c",0x02);/* Receiving */
197 smprintf(s,"%c",d->Msg.Type);
198 smprintf(s,"%c",d->Msg.Length/256);
199 smprintf(s,"%c",d->Msg.Length%256);
200 for (i=0;i<d->Msg.Length;i++) smprintf(s,"%c",d->Msg.Buffer[i]);
201 }
202 if (d->Msg.Type != ALCATEL_CONTROL) {
203 d->next_frame = ALCATEL_DATA;
204 d->busy = false;
205 }
206 /* Reset message length */
207 d->Msg.Length = 0;
208 }
209
210 /* Was it unexpected type? */
211 if ((d->Msg.Type != d->next_frame) && (d->Msg.Type != ALCATEL_CONTROL)) {
212 return ERR_FRAMENOTREQUESTED;
213 }
214 } /* Last byte of packet */
215
216 return ERR_NONE;
217}
218
219static GSM_Error ALCABUS_Initialise(GSM_StateMachine *s)
220{
221 GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS;
222
223 /* Initialise some variables */
224 d->Msg.BufferUsed= 0;
225 d->Msg.Buffer = NULL;
226 d->Msg.Length = 0;
227 d->Msg.Type = 0;
228 d->in_counter = 1;
229 d->out_counter = 0;
230 d->busy = false;
231
232 /* Initialise protocol */
233 dbgprintf ("Initializing binary mode\n");
234 return ALCABUS_WriteMessage (s, 0, 0, ALCATEL_CONNECT);
235}
236
237static GSM_Error ALCABUS_Terminate(GSM_StateMachine *s)
238{
239 /* Terminate protocol */
240 dbgprintf ("Closing binary mode\n");
241 return ALCABUS_WriteMessage (s, 0, 0, ALCATEL_DISCONNECT);
242}
243
244GSM_Protocol_Functions ALCABUSProtocol = {
245 ALCABUS_WriteMessage,
246 ALCABUS_StateMachine,
247 ALCABUS_Initialise,
248 ALCABUS_Terminate
249};
250
251#endif
252
253/* How should editor hadle tabs in this file? Add editor commands here.
254 * vim: noexpandtab sw=8 ts=8 sts=8:
255 */