2 * Low level functions for communication with Alcatel One Touch phones.
4 * This code implements the protocol used for synchronisation with PC.
6 #include "../../gsmstate.h"
8 #if defined(GSM_ENABLE_ALCABUS)
13 #include "../../gsmcomon.h"
16 static GSM_Error
ALCABUS_WriteMessage (GSM_StateMachine
*s
, unsigned char *data
, int len
, unsigned char type
)
18 GSM_Protocol_ALCABUSData
*d
= &s
->Protocol
.Data
.ALCABUS
;
19 unsigned char buffer
[1024];
22 int i
= 0, checksum
= 0;
24 if ((type
== 0) && (len
== 0)) return GE_NONE
;
26 buffer
[0] = ALCATEL_HEADER
;
34 d
->next_frame
= ALCATEL_CONNECT_ACK
;
37 case ALCATEL_DISCONNECT
:
39 d
->next_frame
= ALCATEL_DISCONNECT_ACK
;
43 buffer
[2] = d
->out_counter
;
45 /* Increase outgoing packet counter */
46 if (d
->out_counter
== ALCATEL_MAX_COUNTER
) d
->out_counter
= 0;
47 else d
->out_counter
++;
51 memcpy(buffer
+5, data
, len
);
53 d
->next_frame
= ALCATEL_ACK
;
57 buffer
[2] = d
->in_counter
;
58 if (d
->in_counter
== 0) d
->in_counter
= 1;
60 d
->next_frame
= ALCATEL_DATA
;
63 /* In fact, other types probably can came just from mobile... */
64 smprintf(s
,"WARNING: Wanted to send some unknown packet (%02X)\n", type
);
65 return GE_NOTIMPLEMENTED
;
68 /* Calculate packet checksum */
69 for (i
=0; i
<size
; i
++) checksum
^= buffer
[i
];
71 buffer
[size
] = checksum
;
74 GSM_DumpMessageLevel2(s
, buffer
, size
, type
);
75 GSM_DumpMessageLevel3(s
, buffer
, size
, type
);
76 while (sent
!= size
) {
77 if ((i
= s
->Device
.Functions
->WriteDevice(s
,buffer
+ sent
, size
- sent
)) == 0) {
78 return GE_DEVICEWRITEERROR
;
83 if (type
== ALCATEL_CONNECT
|| type
== ALCATEL_DISCONNECT
) {
84 /* For connect and disconnect we need a bit larger delay */
87 GSM_ReadDevice(s
,true);
90 if (i
== 10) return GE_TIMEOUT
;
96 static GSM_Error
ALCABUS_StateMachine(GSM_StateMachine
*s
, unsigned char rx_byte
)
98 GSM_Protocol_ALCABUSData
*d
= &s
->Protocol
.Data
.ALCABUS
;
102 if (d
->Msg
.BufferUsed
< d
->Msg
.Length
+ 1) {
103 d
->Msg
.BufferUsed
= d
->Msg
.Length
+ 1;
104 d
->Msg
.Buffer
= (unsigned char *)realloc(d
->Msg
.Buffer
,d
->Msg
.BufferUsed
);
107 /* Check for header */
108 if ((d
->Msg
.Length
== 0) && (rx_byte
!= ALCATEL_HEADER
)) {
109 smprintf(s
,"WARNING: Expecting alcatel header (%02X) but got (%02X)\n", ALCATEL_HEADER
, rx_byte
);
110 return GE_UNKNOWNRESPONSE
;
111 /* Check for packet type */
112 } else if (d
->Msg
.Length
== 1){
113 d
->Msg
.Type
= rx_byte
;
114 /* Was it unexpected packet? */
115 if ((rx_byte
!= d
->next_frame
) && (rx_byte
!= ALCATEL_CONTROL
)) {
116 smprintf(s
,"WARNING: Expecting alcatel packet type (%02X) but got (%02X)\n", d
->next_frame
, rx_byte
);
118 /* Determine packet size */
121 d
->expected_size
= 4;
124 /* Packet length is in it's header */
125 d
->expected_size
= -1;
127 case ALCATEL_CONTROL
:
128 d
->expected_size
= 4;
130 case ALCATEL_CONNECT_ACK
:
131 d
->expected_size
= 6;
133 case ALCATEL_DISCONNECT_ACK
:
134 d
->expected_size
= 3;
137 smprintf(s
,"WARNING: Something went wrong, unknown packet received (%02X)\n", rx_byte
);
138 return GE_UNKNOWNRESPONSE
;
140 /* Check counter, we can probably ignore error here ;-) */
141 } else if ((d
->Msg
.Length
== 2) && (d
->Msg
.Type
== ALCATEL_DATA
)) {
142 if (rx_byte
!= d
->in_counter
) {
143 smprintf(s
,"WARNING: Unexpected packet number, ignoring (expected %02X, received %02X)\n", d
->in_counter
, rx_byte
);
144 d
->in_counter
= rx_byte
;
146 /* Increase incoming packet counter */
147 if (d
->in_counter
== ALCATEL_MAX_COUNTER
) d
->in_counter
= 0;
148 else d
->in_counter
++;
149 /* Read size for data packet */
150 } else if ((d
->Msg
.Length
== 4) && (d
->Msg
.Type
== ALCATEL_DATA
)) {
151 /* Header till now + checksum */
152 d
->expected_size
= (int)rx_byte
+ 6;
155 /* Write received byte into buffer */
156 d
->Msg
.Buffer
[d
->Msg
.Length
++] = rx_byte
;
158 /* Did we received whole packet? */
159 if (d
->expected_size
== d
->Msg
.Length
) {
161 for (i
=0; i
< (d
->Msg
.Length
- 1); i
++) checksum
^= d
->Msg
.Buffer
[i
];
162 if (checksum
!= d
->Msg
.Buffer
[d
->Msg
.Length
- 1]) {
163 /* We can only warn, as we don't know what should happend now... */
164 smprintf(s
,"WARNING: Ignoring incorrect packet checksum!\n");
168 if (d
->Msg
.Type
== ALCATEL_DATA
) {
169 /* Dispatch message */
170 s
->Phone
.Data
.RequestMsg
= &d
->Msg
;
171 s
->Phone
.Data
.DispatchError
= s
->Phone
.Functions
->DispatchMessage(s
);
173 ALCABUS_WriteMessage (s
, 0, 0, ALCATEL_ACK
);
174 /* Reset message length */
177 } else if ((d
->Msg
.Type
== ALCATEL_ACK
) ||
178 (d
->Msg
.Type
== ALCATEL_CONTROL
) ||
179 (d
->Msg
.Type
== ALCATEL_CONNECT_ACK
) ||
180 (d
->Msg
.Type
== ALCATEL_DISCONNECT_ACK
)) {
181 /* TODO: check counter of ack? */
182 if (s
->di
.dl
==DL_TEXT
|| s
->di
.dl
==DL_TEXTALL
||
183 s
->di
.dl
==DL_TEXTDATE
|| s
->di
.dl
==DL_TEXTALLDATE
) {
184 smprintf(s
, "Received %s ack ",
185 (d
->Msg
.Type
== ALCATEL_ACK
) ? "normal" :
186 (d
->Msg
.Type
== ALCATEL_CONTROL
) ? "control" :
187 (d
->Msg
.Type
== ALCATEL_CONNECT_ACK
) ? "connect" :
188 (d
->Msg
.Type
== ALCATEL_DISCONNECT_ACK
) ? "disconnect" :
190 smprintf(s
, "0x%02x / 0x%04x", d
->Msg
.Type
, d
->Msg
.Length
);
191 DumpMessage(s
->di
.df
, d
->Msg
.Buffer
, d
->Msg
.Length
);
194 if (s
->di
.dl
==DL_BINARY
) {
195 smprintf(s
,"%c",0x02); /* Receiving */
196 smprintf(s
,"%c",d
->Msg
.Type
);
197 smprintf(s
,"%c",d
->Msg
.Length
/256);
198 smprintf(s
,"%c",d
->Msg
.Length
%256);
199 for (i
=0;i
<d
->Msg
.Length
;i
++) smprintf(s
,"%c",d
->Msg
.Buffer
[i
]);
201 if (d
->Msg
.Type
!= ALCATEL_CONTROL
) {
202 d
->next_frame
= ALCATEL_DATA
;
205 /* Reset message length */
209 /* Was it unexpected type? */
210 if ((d
->Msg
.Type
!= d
->next_frame
) && (d
->Msg
.Type
!= ALCATEL_CONTROL
)) {
211 return GE_FRAMENOTREQUESTED
;
213 } /* Last byte of packet */
218 static GSM_Error
ALCABUS_Initialise(GSM_StateMachine
*s
)
220 GSM_Protocol_ALCABUSData
*d
= &s
->Protocol
.Data
.ALCABUS
;
222 /* Initialise some variables */
223 d
->Msg
.BufferUsed
= 0;
224 d
->Msg
.Buffer
= NULL
;
231 /* Initialise protocol */
232 dbgprintf ("Initializing binary mode\n");
233 return ALCABUS_WriteMessage (s
, 0, 0, ALCATEL_CONNECT
);
236 static GSM_Error
ALCABUS_Terminate(GSM_StateMachine
*s
)
238 /* Terminate protocol */
239 dbgprintf ("Closing binary mode\n");
240 return ALCABUS_WriteMessage (s
, 0, 0, ALCATEL_DISCONNECT
);
243 GSM_Protocol_Functions ALCABUSProtocol
= {
244 ALCABUS_WriteMessage
,
245 ALCABUS_StateMachine
,
252 /* How should editor hadle tabs in this file? Add editor commands here.
253 * vim: noexpandtab sw=8 ts=8 sts=8: