1 /*
2
3 G N O K I I
4
5 A Linux/Unix toolset and driver for the mobile phones.
6
7 This file is part of gnokii.
8
9 Gnokii is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 Gnokii is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with gnokii; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 Copyright (C) 1999-2000 Hugh Blemings & Pavel Janik ml.
24 Copyright (C) 2001-2011 Pawel Kot
25 Copyright (C) 2002 Ladis Michl
26 Copyright (C) 2002-2003 BORBELY Zoltan
27 Copyright (C) 2003-2004 Osma Suominen
28
29 This file provides an API for accessing functions via fbus.
30 See README for more details on supported mobile phones.
31
32 The various routines are called fb3110_(whatever).
33
34 */
35
36 #include "config.h"
37
38 /* System header files */
39
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
43
44 /* Various header file */
45
46 #include "compat.h"
47 #include "misc.h"
48 #include "gnokii-internal.h"
49 #include "device.h"
50
51 #include "links/fbus-3110.h"
52 #include "links/utils.h"
53
54 static bool fb3110_serial_open(struct gn_statemachine *state);
55 static void fb3110_rx_frame_handle(fb3110_incoming_frame *i, struct gn_statemachine *state);
56 static void fb3110_rx_state_machine(unsigned char rx_byte, struct gn_statemachine *state);
57 static gn_error fb3110_tx_frame_send(u8 frame_type, u8 message_length, u8 message_type, u8 sequence_byte, u8 *buffer, struct gn_statemachine *state);
58 static gn_error fb3110_message_send(unsigned int messagesize, unsigned char messagetype, unsigned char *message, struct gn_statemachine *state);
59 static void fb3110_tx_ack_send(u8 messagetype, u8 checksum, struct gn_statemachine *state);
60 static void fb3110_sequence_number_update(struct gn_statemachine *state);
61 static int fb3110_message_type_fold(int type);
62
63 /* FIXME - win32 stuff! */
64
65 #define FBUSINST(s) (*((fb3110_link **)(&(s)->link.link_instance)))
66
67
68 /*--------------------------------------------*/
69
fb3110_serial_open(struct gn_statemachine * state)70 static bool fb3110_serial_open(struct gn_statemachine *state)
71 {
72 if (!state)
73 return false;
74
75 /* Open device. */
76 if (!device_open(state->config.port_device, false, false, false, GN_CT_Serial, state)) {
77 perror(_("Couldn't open FBUS device"));
78 return false;
79 }
80 device_changespeed(115200, state);
81
82 return true;
83 }
84
85 /*
86 * Handles one complete frame. What to do with it depends on the frame
87 * type. Frames are acknowledged if needed and information about them is
88 * passed to the main statemachine.
89 */
90
fb3110_rx_frame_handle(fb3110_incoming_frame * i,struct gn_statemachine * state)91 static void fb3110_rx_frame_handle(fb3110_incoming_frame *i, struct gn_statemachine *state)
92 {
93 int count;
94
95 if (!i)
96 return;
97
98 dprintf("--> %02x:%02x:", i->frame_type, i->frame_len);
99 for (count = 0; count < i->buffer_count; count++)
100 dprintf("%02hhx:", i->buffer[count]);
101 dprintf("\n");
102
103 if (i->frame_type == FB3110_FRAME_TYPE_IN_RLP) { /* RLP frame */
104
105 /* Transfer RLP frame to state machine. The messagetype
106 * should always be 0x02 in this case, so the frame type
107 * doesn't have to be passed to the statemachine and on to
108 * the driver - RLP frames can be told apart by messagetype.
109 * But check message type anyway just to make sure. */
110
111 if (i->buffer[0] != 0x02)
112 dprintf("RLP frame with non-0x02 message type (0x%02x) received!\n", i->buffer[0]);
113
114 sm_incoming_function(i->buffer[0], i->buffer, i->frame_len, state);
115
116 } else if (i->buffer[1] < 0x08 || i->buffer[1] > 0x0f) { /* msg frame */
117
118 /* Send an ack */
119 fb3110_tx_ack_send(i->buffer[0], i->buffer[1], state);
120
121 if (FBUSINST(state)->last_incoming_sequence_number == i->buffer[1]) {
122 dprintf("Duplicate message received. Sent ack, not handling.\n");
123 return;
124 }
125
126 FBUSINST(state)->last_incoming_sequence_number = i->buffer[1];
127
128 /* Transfer message to state machine */
129 sm_incoming_function(fb3110_message_type_fold(i->buffer[0]), i->buffer, i->frame_len, state);
130
131 } else { /* ack frame */
132 fb3110_sequence_number_update(state);
133 dprintf("Received ack for message type 0x%02x\n", i->buffer[0]);
134 sm_incoming_acknowledge(state);
135 }
136 }
137
138
139 /*
140 * RX_State machine for receive handling.
141 * Called once for each character received from the phone.
142 */
fb3110_rx_state_machine(unsigned char rx_byte,struct gn_statemachine * state)143 static void fb3110_rx_state_machine(unsigned char rx_byte, struct gn_statemachine *state)
144 {
145 fb3110_incoming_frame *i = &FBUSINST(state)->i;
146
147 if (!i)
148 return;
149
150 switch (i->state) {
151
152 /* Phone is currently off. Wait for 0x55 before
153 restarting */
154 case FB3110_RX_Discarding:
155 if (rx_byte != 0x55)
156 break;
157
158 /* Seen 0x55, restart at 0x04 */
159 i->state = FB3110_RX_Sync;
160
161 dprintf("restarting.\n");
162
163 /* FALLTHROUGH */
164
165 /* Messages from the phone start with an 0x04 during
166 "normal" operation, 0x03 when in data/fax mode. We
167 use this to "synchronise" with the incoming data
168 stream. */
169 case FB3110_RX_Sync:
170 if (rx_byte == 0x04 || rx_byte == 0x03) {
171 i->frame_type = rx_byte;
172 i->checksum = rx_byte;
173 i->state = FB3110_RX_GetLength;
174 }
175 break;
176
177 /* Next byte is the length of the message including
178 the message type byte but not including the checksum. */
179 case FB3110_RX_GetLength:
180 i->frame_len = rx_byte;
181 i->buffer_count = 0;
182 i->checksum ^= rx_byte;
183 i->state = FB3110_RX_GetMessage;
184 break;
185
186 /* Get each byte of the message. We deliberately
187 get one too many bytes so we get the checksum
188 here as well. */
189 case FB3110_RX_GetMessage:
190 i->buffer[i->buffer_count] = rx_byte;
191 i->buffer_count++;
192
193 if (i->buffer_count >= FB3110_FRAME_MAX_LENGTH) {
194 dprintf("FBUS: Message buffer overun - resetting\n");
195 i->state = FB3110_RX_Sync;
196 break;
197 }
198
199 /* If this is the last byte, it's the checksum. */
200 if (i->buffer_count > i->frame_len) {
201
202 /* Is the checksum correct? */
203 if (rx_byte == i->checksum) {
204 /* Frame received OK, deal with it! */
205 fb3110_rx_frame_handle(i, state);
206 } else {
207 /* Checksum didn't match so ignore. */
208 dprintf("Bad checksum!\n");
209 }
210 i->state = FB3110_RX_Sync;
211 }
212 i->checksum ^= rx_byte;
213 break;
214 }
215 }
216
217
218 /*
219 * This is the main loop function which must be called regularly
220 * timeout can be used to make it 'busy' or not
221 */
fb3110_loop(struct timeval * timeout,struct gn_statemachine * state)222 static gn_error fb3110_loop(struct timeval *timeout, struct gn_statemachine *state)
223 {
224 unsigned char buffer[BUFFER_SIZE];
225 int count, res;
226
227 res = device_select(timeout, state);
228 if (res > 0) {
229 res = device_read(buffer, sizeof(buffer), state);
230 for (count = 0; count < res; count++)
231 fb3110_rx_state_machine(buffer[count], state);
232 } else
233 return GN_ERR_TIMEOUT;
234
235 /* This traps errors from device_read */
236 if (res > 0)
237 return GN_ERR_NONE;
238 else
239 return GN_ERR_INTERNALERROR;
240 }
241
242
243 /*
244 * Prepares the message header and sends it, prepends the message start
245 * byte (0x01) and other values according the value specified when called.
246 * Calculates checksum and then sends the lot down the pipe...
247 */
fb3110_tx_frame_send(u8 frame_type,u8 message_length,u8 message_type,u8 sequence_byte,u8 * buffer,struct gn_statemachine * state)248 static gn_error fb3110_tx_frame_send(u8 frame_type, u8 message_length, u8 message_type, u8 sequence_byte, u8 *buffer, struct gn_statemachine *state)
249 {
250
251 u8 out_buffer[FB3110_TRANSMIT_MAX_LENGTH];
252 int count, current = 0;
253 unsigned char checksum;
254
255 /* Check message isn't too long, once the necessary
256 header and trailer bytes are included. */
257 if ((message_length + 5) > FB3110_TRANSMIT_MAX_LENGTH) {
258 fprintf(stderr, _("fb3110_tx_frame_send - message too long!\n"));
259 return GN_ERR_INTERNALERROR;
260 }
261
262 /* Now construct the message header. */
263 out_buffer[current++] = frame_type; /* Start of frame */
264 out_buffer[current++] = message_length + 2; /* Length */
265 out_buffer[current++] = message_type; /* Type */
266 out_buffer[current++] = sequence_byte; /* Sequence number */
267
268 /* Copy in data if any. */
269 if (message_length != 0) {
270 memcpy(out_buffer + current, buffer, message_length);
271 current += message_length;
272 }
273
274 /* Now calculate checksum over entire message
275 and append to message. */
276 checksum = 0;
277 for (count = 0; count < current; count++)
278 checksum ^= out_buffer[count];
279 out_buffer[current++] = checksum;
280
281 dprintf("<-- ");
282 for (count = 0; count < current; count++)
283 dprintf("%02hhx:", out_buffer[count]);
284 dprintf("\n");
285
286 /* Send it out... */
287 if (device_write(out_buffer, current, state) != current)
288 return GN_ERR_INTERNALERROR;
289
290 return GN_ERR_NONE;
291 }
292
293
294 /*
295 * Main function to send an fbus message
296 */
fb3110_message_send(unsigned int messagesize,unsigned char messagetype,unsigned char * message,struct gn_statemachine * state)297 static gn_error fb3110_message_send(unsigned int messagesize, unsigned char messagetype, unsigned char *message, struct gn_statemachine *state)
298 {
299 u8 seqnum, frame_type;
300
301 /* Data (RLP) frame always have message type 0x01 */
302 if (messagetype == 0x01) {
303 /* this is a bit of a hack: outgoing RLP frames have and
304 extra byte between msgtype and seqno, indicating DTX;
305 thus we swap seqnum with message[0] */
306 seqnum = message[0];
307 message[0] = 0xd9; /* seqno constant for RLP frames */
308 frame_type = FB3110_FRAME_TYPE_OUT_RLP;
309 } else { /* normal command frame */
310 seqnum = FBUSINST(state)->request_sequence_number;
311 frame_type = FB3110_FRAME_TYPE_OUT_CMD;
312 }
313
314 return fb3110_tx_frame_send(frame_type, messagesize, messagetype, seqnum, message, state);
315 }
316
317
318 /*
319 * Sends the "standard" acknowledge message back to the phone in response to
320 * a message it sent automatically or in response to a command sent to it.
321 */
fb3110_tx_ack_send(u8 messagetype,u8 seqno,struct gn_statemachine * state)322 static void fb3110_tx_ack_send(u8 messagetype, u8 seqno, struct gn_statemachine *state)
323 {
324 if (fb3110_tx_frame_send(FB3110_FRAME_TYPE_OUT_CMD, 0, messagetype, (seqno & 0x1f) - 0x08, NULL, state))
325 dprintf("Failed to acknowledge message type %02x.\n", messagetype);
326 else
327 dprintf("Acknowledged message type %02x.\n", messagetype);
328 }
329
330
fb3110_reset(struct gn_statemachine * state)331 static void fb3110_reset(struct gn_statemachine *state)
332 {
333 /* Init variables */
334 FBUSINST(state)->i.state = FB3110_RX_Sync;
335 }
336
337 /*
338 * Initialise variables and start the link
339 * newlink is actually part of state - but the link code should not
340 * anything about state. State is only passed around to allow for
341 * muliple state machines (one day...)
342 */
fb3110_initialise(struct gn_statemachine * state)343 gn_error fb3110_initialise(struct gn_statemachine *state)
344 {
345 unsigned char init_char = 0x55;
346 unsigned char count;
347 static int try = 0;
348
349 if (!state)
350 return GN_ERR_FAILED;
351
352 try++;
353 if (try > 2) return GN_ERR_FAILED;
354
355 /* Fill in the link functions */
356 state->link.loop = &fb3110_loop;
357 state->link.send_message = &fb3110_message_send;
358 state->link.reset = &fb3110_reset;
359 state->link.cleanup = NULL;
360
361 /* Check for a valid init length */
362 if (state->config.init_length == 0)
363 state->config.init_length = 100;
364
365 /* Start up the link */
366 if ((FBUSINST(state) = calloc(1, sizeof(fb3110_link))) == NULL)
367 return GN_ERR_MEMORYFULL;
368
369 FBUSINST(state)->request_sequence_number = 0x10;
370
371 /* Since 0x08 is within the range of seqnos used for computer->ME,
372 * it should be pretty safe to assume that the phone doesn't
373 * initiate communication with that seqno. If we use e.g. 0x00 or
374 * 0x30, some nasty errors may happen. */
375 FBUSINST(state)->last_incoming_sequence_number = 0x08;
376
377 if (!fb3110_serial_open(state)) {
378 free(FBUSINST(state));
379 FBUSINST(state) = NULL;
380 return GN_ERR_FAILED;
381 }
382
383 /* Send init string to phone, this is a bunch of 0x55 characters.
384 Timing is empirical. I believe that we need/can do this for any
385 phone to get the UART synced */
386 for (count = 0; count < state->config.init_length; count++) {
387 usleep(1000);
388 device_write(&init_char, 1, state);
389 }
390
391 fb3110_reset(state);
392
393 return GN_ERR_NONE;
394 }
395
396
397 /* Any command we originate must have a unique SequenceNumber. Observation to
398 * date suggests that these values start at 0x10 and cycle up to 0x17
399 * before repeating again. Perhaps more accurately, the numbers cycle
400 * 0,1,2,3..7 with bit 4 of the byte premanently set.
401 */
fb3110_sequence_number_update(struct gn_statemachine * state)402 static void fb3110_sequence_number_update(struct gn_statemachine *state)
403 {
404 FBUSINST(state)->request_sequence_number++;
405
406 if (FBUSINST(state)->request_sequence_number > 0x17 || FBUSINST(state)->request_sequence_number < 0x10)
407 FBUSINST(state)->request_sequence_number = 0x10;
408 }
409
410 /* The 3110 protocol has a tendency to use different message types to
411 * indicate successful and failed actions. These are not handled very well by
412 * the gnokii internals, so they are "folded" together and dealt with in the
413 * 3110 code instead. The logic is that each success/failure message type
414 * pair is reported as the type of the message to indicate success.
415 * The argument is the original message type i.e. first byte of message. */
416
fb3110_message_type_fold(int type)417 static int fb3110_message_type_fold(int type)
418 {
419 switch (type) {
420 case 0x16:
421 case 0x17:
422 return 0x16; /* initialization */
423 case 0x21:
424 case 0x22:
425 return 0x21; /* send DTMF */
426 case 0x28:
427 case 0x29:
428 return 0x28; /* SMS sent */
429 case 0x2a:
430 case 0x2b:
431 return 0x2a; /* SMS saved */
432 case 0x2c:
433 case 0x2d:
434 return 0x2c; /* SMS read */
435 case 0x2e:
436 case 0x2f:
437 return 0x2e; /* SMS deleted */
438 case 0x3d:
439 case 0x3e:
440 return 0x3d; /* SMSC set */
441 case 0x44:
442 case 0x45:
443 return 0x44; /* mem location set */
444 case 0x46:
445 case 0x47:
446 return 0x46; /* mem location read */
447 default:
448 return type; /* all others left as-is */
449 }
450 }
451