3 Copyright (C) 2001 Pavel Machek <pavel@ucw.cz>
4 Copyright (C) 2001 Michl Ladislav <xmichl03@stud.fee.vutbr.cz>
6 Released under the terms of the GNU GPL, see file COPYING for more details.
10 /* System header files */
17 /* Various header file */
23 #include "gsm-common.h"
24 #include "gsm-ringtones.h"
25 #include "gsm-networks.h"
27 #include "links/utils.h"
30 #include "links/cbus.h"
32 /* FIXME - pass device_* the link stuff?? */
33 /* FIXME - win32 stuff! */
40 CBUS_Link clink; /* CBUS specific stuff, internal to this file */
44 char reply_buf[10240];
46 /*--------------------------------------------------------------------------*/
48 bool CBUS_OpenSerial()
51 result = device_open(glink->PortDevice, false, false, false, GCT_Serial);
53 perror(_("Couldn't open CBUS device"));
56 device_changespeed(9600);
57 device_setdtrrts(1, 0);
61 /* -------------------------------------------------------------------- */
63 static int xread(unsigned char *d, int len)
67 res = device_read(d, len);
69 if (errno != EAGAIN) {
70 printf("I/O error : %m?!\n");
72 } else device_select(NULL);
82 static int xwrite(unsigned char *d, int len)
86 res = device_write(d, len);
88 if (errno != EAGAIN) {
89 printf("I/O error : %m?!\n");
102 say(unsigned char *c, int len)
104 unsigned char d[10240];
108 if (memcmp(c, d, len)) {
110 printf("Did not get my own echo?: ");
111 for (i=0; i<len; i++)
121 printf("Waiting ack\n");
122 if (xread(&c, 1) == 0) {
123 printf("Got %x\n", c);
127 } else printf("Timeout?\n");
132 sendpacket(unsigned char *msg, int len, unsigned short cmd)
134 unsigned char p[10240], csum = 0;
143 memcpy(p+6, msg, len);
148 for (i=0; i<pos; i++) {
156 for (i=0; i<=pos; i++) {
165 /* -------------------------------------------------------------------- */
168 static GSM_Error CommandAck(int messagetype, unsigned char *buffer, int length)
174 static GSM_Error PhoneReply(int messagetype, unsigned char *buffer, int length)
176 if (!strncmp(buffer, "OK", 2)) {
178 printf("Phone okays\n");
180 strncpy(reply_buf, buffer, length);
181 reply_buf[length+1] = '\0';
182 printf("Phone says: %s\n", reply_buf);
185 u8 buf[2] = { 0x3e, 0x68 };
187 CBUS_SendMessage(2, 0x3f, buf);
197 printf("AT command: %s\n", msg);
198 CBUS_SendMessage(strlen(msg), 0x3c, msg);
202 // getpacket(); /* This should be phone's acknowledge of AT command */
206 /* -------------------------------------------------- */
208 /* RX_State machine for receive handling. Called once for each character
209 received from the phone. */
212 internal_dispatch(GSM_Link *glink, GSM_Phone *gphone, int type, u8 *buf, int len)
215 case '=': CommandAck(type, buf, len);
217 case '>': PhoneReply(type, buf, len);
219 default: dprintf("Unknown Frame Type 68/ %02x\n", type);
224 void CBUS_RX_StateMachine(unsigned char rx_byte)
226 CBUS_IncomingFrame *i = &clink.i;
228 /* checksum is XOR of all bytes in the frame */
229 if (i->state != CBUS_RX_GetCSum) i->checksum ^= rx_byte;
237 if (i->prev_rx_byte == 0x19) {
238 i->state = CBUS_RX_FrameType1;
242 if ((i->prev_rx_byte == 0x38) || (i->prev_rx_byte == 0x34)) {
243 i->state = CBUS_RX_FrameType1;
248 if (i->state != CBUS_RX_Header) {
249 i->FrameHeader1 = i->prev_rx_byte;
250 i->FrameHeader2 = rx_byte;
252 i->checksum = i->prev_rx_byte ^ rx_byte;
256 /* FIXME: Do you know exact meaning? just mail me. ladis. */
257 case CBUS_RX_FrameType1:
258 i->FrameType1 = rx_byte;
259 i->state = CBUS_RX_FrameType2;
262 /* FIXME: Do you know exact meaning? just mail me. ladis. */
263 case CBUS_RX_FrameType2:
264 i->FrameType2 = rx_byte;
265 i->state = CBUS_RX_GetLengthLB;
268 /* message length - low byte */
269 case CBUS_RX_GetLengthLB:
270 i->MessageLength = rx_byte;
271 i->state = CBUS_RX_GetLengthHB;
274 /* message length - high byte */
275 case CBUS_RX_GetLengthHB:
276 i->MessageLength = i->MessageLength | rx_byte << 8;
277 /* there are also empty commands */
278 if (i->MessageLength == 0)
279 i->state = CBUS_RX_GetCSum;
281 i->state = CBUS_RX_GetMessage;
284 /* get each byte of the message body */
285 case CBUS_RX_GetMessage:
286 i->buffer[i->BufferCount++] = rx_byte;
287 /* avoid buffer overflow */
288 if (i->BufferCount > CBUS_MAX_MSG_LENGTH) {
289 dprintf("CBUS: Message buffer overun - resetting\n");
290 i->state = CBUS_RX_Header;
294 if (i->BufferCount == i->MessageLength)
295 i->state = CBUS_RX_GetCSum;
299 case CBUS_RX_GetCSum:
300 /* compare against calculated checksum. */
301 if (i->checksum == rx_byte) {
307 printf("ack lost, expect armagedon!\n");
309 /* Got checksum, matches calculated one, so
310 * now pass to appropriate dispatch handler. */
311 i->buffer[i->MessageLength + 1] = 0;
312 /* FIXME: really call it :-) */
314 switch(i->FrameType2) {
316 internal_dispatch(glink, gphone, i->FrameType1, i->buffer, i->MessageLength);
319 if (i->FrameType1 == 0x91) {
321 printf("Registration acknowledged\n");
323 printf("Unknown message\n");
326 /* checksum doesn't match so ignore. */
327 dprintf("CBUS: Checksum error; expected: %02x, got: %02x", i->checksum, rx_byte);
330 i->state = CBUS_RX_Header;
335 i->prev_rx_byte = rx_byte;
338 int CBUS_SendMessage(u16 message_length, u8 message_type, void * buffer)
340 sendpacket(buffer, message_length, message_type);
344 static GSM_Error AT_SendMessage(u16 message_length, u8 message_type, void * buffer)
350 /* This is the main loop function which must be called regularly */
351 /* timeout can be used to make it 'busy' or not */
353 /* ladis: this function ought to be the same for all phones... */
355 GSM_Error CBUS_Loop(struct timeval *timeout)
357 unsigned char buffer[255];
360 res = device_select(timeout);
362 res = device_read(buffer, 255);
363 for (count = 0; count < res; count++)
364 CBUS_RX_StateMachine(buffer[count]);
368 /* This traps errors from device_read */
372 return GE_INTERNALERROR;
376 int CBUS_TX_SendAck(u8 message_type, u8 message_seq)
378 dprintf("[Sending Ack]\n");
383 /* Initialise variables and start the link */
385 GSM_Error CBUS_Initialise(GSM_Statemachine *state)
387 setvbuf(stdout, NULL, _IONBF, 0);
388 setvbuf(stderr, NULL, _IONBF, 0);
390 /* 'Copy in' the global structures */
391 glink = &(state->Link);
392 gphone = &(state->Phone);
394 /* Fill in the link functions */
395 glink->Loop = &CBUS_Loop;
396 glink->SendMessage = &AT_SendMessage;
398 if (glink->ConnectionType == GCT_Serial) {
399 if (!CBUS_OpenSerial())
400 return GE_DEVICEOPENFAILED;
402 fprintf(stderr, "Device not supported by CBUS");
403 return GE_DEVICEOPENFAILED;
406 dprintf("Saying hello...");
408 char init1[] = { 0, 0x38, 0x19, 0xa6, 0x70, 0x00, 0x00, 0xf7, 0xa5 };
413 dprintf("second hello...");
415 char init1[] = { 0x38, 0x19, 0x90, 0x70, 0x01, 0x00, 0x1f, 0xdf };