author | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
commit | 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (unidiff) | |
tree | 6331418973714243beb674abc87692277b83869d /gammu/emb/common/protocol/alcatel/alcabus.c | |
parent | ef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff) | |
download | kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.zip kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.gz kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.bz2 |
Initial revision
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.c | 255 |
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 | |||
17 | static 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 | |||
97 | static 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 | |||
219 | static 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 | |||
237 | static 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 | |||
244 | GSM_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 | */ | ||