:pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
[gnokii.git] / common / links / atbus.c
1 /*
2
3   $Id$
4
5   G N O K I I
6
7   A Linux/Unix toolset and driver for mobile phones.
8
9   Copyright 2001 Manfred Jonsson <manfred.jonsson@gmx.de>
10
11   Released under the terms of the GNU GPL, see file COPYING for more details.
12
13   $Log$
14   Revision 1.1.1.1  2001/11/25 21:59:09  short
15   :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
16
17   Revision 1.5  2001/11/19 13:03:18  pkot
18   nk3110.c cleanup
19
20   Revision 1.4  2001/09/09 21:45:49  machek
21   Cleanups from Ladislav Michl <ladis@psi.cz>:
22
23   *) do *not* internationalize debug messages
24
25   *) some whitespace fixes, do not use //
26
27   *) break is unneccessary after return
28
29   Revision 1.3  2001/08/20 23:27:37  pkot
30   Add hardware shakehand to the link layer (Manfred Jonsson)
31
32   Revision 1.2  2001/08/09 11:51:39  pkot
33   Generic AT support updates and cleanup (Manfred Jonsson)
34
35   Revision 1.1  2001/07/27 00:02:21  pkot
36   Generic AT support for the new structure (Manfred Jonsson)
37
38 */
39
40 /* System header files */
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <errno.h>
45
46 /* Various header file */
47 #include "config.h"
48 #ifndef DEBUG
49 #define DEBUG
50 #endif
51 #include "misc.h"
52 #include "gsm-common.h"
53 #include "gsm-ringtones.h"
54 #include "gsm-networks.h"
55 #include "device.h"
56 #include "links/utils.h"
57 #include "gsm-statemachine.h"
58
59 #define __atbus_c
60 #include "links/atbus.h"
61
62 /* FIXME - pass device_* the link stuff?? */
63 /* FIXME - win32 stuff! */
64
65
66 /* FIXME - when sending an AT command while another one is still in */
67 /*         progress, the old command is aborted and the new ignored. */
68 /*         the result is _one_ error message from the phone. */
69
70 /* Some globals */
71 /* FIXME - if we use more than one phone these should be part of */
72 /*         a statemachine. */
73
74 static GSM_Statemachine *statemachine;
75 static int binlength = 0;
76 static char reply_buf[1024];
77 static int reply_buf_pos = 0;
78
79 static int xwrite(unsigned char *d, int len)
80 {
81         int res;
82         while (len) {
83                 res = device_write(d, len);
84                 if (res == -1) {
85                         if (errno != EAGAIN) {
86                                 perror("gnokii I/O error ");
87                                 return -1;
88                         }
89                 } else {
90                         d += res;
91                         len -= res;
92                 }
93         }
94         return 0;
95 }
96
97
98 static GSM_Error
99 AT_SendMessage(u16 message_length, u8 message_type, void *msg)
100 {
101         usleep(10000);
102         xwrite((char*)msg, message_length);
103         return GE_NONE;
104 }
105
106
107 /* RX_State machine for receive handling.  Called once for each character
108    received from the phone. */
109 void ATBUS_RX_StateMachine(unsigned char rx_char)
110 {
111         reply_buf[reply_buf_pos++] = rx_char;
112         reply_buf[reply_buf_pos] = '\0';
113
114         if (reply_buf_pos >= binlength) {
115                 if (((reply_buf_pos > 3) && (!strncmp(reply_buf+reply_buf_pos-4, "OK\r\n", 4)))
116                 || ((reply_buf_pos > 6) && (!strncmp(reply_buf+reply_buf_pos-7, "ERROR\r\n", 7)))) {
117                         SM_IncomingFunction(statemachine, statemachine->LastMsgType, reply_buf, reply_buf_pos);
118                         reply_buf_pos = 0;
119                         binlength = 0;
120                         return;
121                 }
122 /* needed for binary date etc
123    TODO: correct reading of variable length integers
124                 if (reply_buf_pos == 12) {
125                         if (!strncmp(reply_buf + 3, "ABC", 3) {
126                                 binlength = atoi(reply_buf + 8);
127                         }
128                 }
129 */
130         }
131 }
132
133
134 bool ATBUS_OpenSerial(int hw_handshake, char *device)
135 {
136         int result;
137         result = device_open(device, false, false, hw_handshake, GCT_Serial);
138         if (!result) {
139                 perror(_("Couldn't open ATBUS device"));
140                 return (false);
141         }
142         device_changespeed(19200);
143         if (hw_handshake) {
144                 device_setdtrrts(0, 1);
145                 sleep(1);
146                 device_setdtrrts(1, 1);
147                 /* make 7110 happy */
148                 sleep(1);
149         } else {
150                 device_setdtrrts(0, 0);
151         }
152         return (true);
153 }
154
155 GSM_Error ATBUS_Loop(struct timeval *timeout)
156 {
157         unsigned char buffer[255];
158         int count, res;
159                                 
160         res = device_select(timeout);
161         if (res > 0) {
162                 res = device_read(buffer, 255);
163                 for (count = 0; count < res; count++)
164                         ATBUS_RX_StateMachine(buffer[count]);
165         } else
166                 return GE_TIMEOUT;  
167         /* This traps errors from device_read */
168         if (res > 0)
169                 return GE_NONE;
170         else
171                 return GE_INTERNALERROR;
172 }
173
174
175 /* Initialise variables and start the link */
176 GSM_Error ATBUS_Initialise(GSM_Statemachine *state, int hw_handshake)
177 {
178         setvbuf(stdout, NULL, _IONBF, 0);
179         setvbuf(stderr, NULL, _IONBF, 0);
180
181         /* 'Copy in' the global structures */
182         statemachine = state;
183
184         /* Fill in the link functions */
185         state->Link.Loop = &ATBUS_Loop;
186         state->Link.SendMessage = &AT_SendMessage;
187
188         if (state->Link.ConnectionType == GCT_Serial) {
189                 if (!ATBUS_OpenSerial(hw_handshake, state->Link.PortDevice))
190                         return GE_DEVICEOPENFAILED;
191         } else {
192                 fprintf(stderr, "Device not supported by ATBUS");
193                 return GE_DEVICEOPENFAILED;
194         }
195
196         return GE_NONE;
197 }