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