:pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
[gnokii.git] / common / links / fbus-phonet.c
1 /*
2
3   $Id$
4
5   G N O K I I
6
7   A Linux/Unix toolset and driver for Nokia mobile phones.
8
9   Copyright (C) 2000 Hugh Blemings & Pavel Janík ml.
10   Copyright (C) 2000 Chris Kemp
11
12   Released under the terms of the GNU GPL, see file COPYING for more details.
13
14   This file provides an API for accessing functions via fbus over irda. 
15   See README for more details on supported mobile phones.
16
17   The various routines are called PHONET_(whatever).
18
19   $Log$
20   Revision 1.1.1.1  2001/11/25 21:59:09  short
21   :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
22
23   Revision 1.8  2001/08/20 23:27:37  pkot
24   Add hardware shakehand to the link layer (Manfred Jonsson)
25
26   Revision 1.7  2001/06/27 23:52:49  pkot
27   7110/6210 updates (Marian Jancar)
28
29   Revision 1.6  2001/06/20 21:27:36  pkot
30   IrDA patch (Marian Jancar)
31
32   Revision 1.5  2001/05/07 16:24:03  pkot
33   DLR-3P temporary fix. How should I do it better?
34
35   Revision 1.4  2001/03/23 13:40:23  chris
36   Pavel's patch and a few fixes.
37
38   Revision 1.3  2001/03/21 23:36:05  chris
39   Added the statemachine
40   This will break gnokii --identify and --monitor except for 6210/7110
41
42   Revision 1.2  2001/02/21 19:57:06  chris
43   More fiddling with the directory layout
44
45   Revision 1.1  2001/02/16 14:29:52  chris
46   Restructure of common/.  Fixed a problem in fbus-phonet.c
47   Lots of dprintfs for Marcin
48   Any size xpm can now be loaded (eg for 7110 startup logos)
49   nk7110 code detects 7110/6210 and alters startup logo size to suit
50   Moved Marcin's extended phonebook code into gnokii.c
51
52   Revision 1.1  2001/02/06 21:15:35  chris
53   Preliminary irda support for 7110 etc.  Not well tested!
54
55
56 */
57
58 /* System header files */
59
60 #include <stdio.h>
61 #include <string.h>
62 #include <stdlib.h>
63
64 /* Various header file */
65
66 #include "config.h"
67 #include "misc.h"
68 #include "gsm-common.h"
69 #include "gsm-ringtones.h"
70 #include "gsm-networks.h"
71 #include "device.h"
72
73 #define __links_fbus_phonet_c
74 #include "links/fbus.h"
75 #include "links/fbus-phonet.h"
76
77 /* FIXME - pass device_* the link stuff?? */
78 /* FIXME - win32 stuff! */
79
80
81 /* Some globals */
82
83 GSM_Link *glink;
84 GSM_Statemachine *statemachine;
85 PHONET_IncomingMessage imessage;
86
87
88 /*--------------------------------------------*/
89
90 bool PHONET_Open()
91 {
92         int result;
93
94         /* Open device. */
95
96         result = device_open(glink->PortDevice, false, false, false, GCT_Irda);
97
98         if (!result) {
99                 perror(_("Couldn't open PHONET device"));
100                 return false;
101         }
102
103         return (true);
104 }
105
106
107 /* RX_State machine for receive handling.  Called once for each character
108    received from the phone. */
109
110 void PHONET_RX_StateMachine(unsigned char rx_byte) {
111   
112         PHONET_IncomingMessage *i=&imessage;
113
114         //  if (isprint(rx_byte))
115         //  fprintf(stderr, "[%02x%c]", (unsigned char) rx_byte, rx_byte);
116         //else
117         //  fprintf(stderr, "[%02x ]", (unsigned char) rx_byte);
118
119
120         switch (i->state) {
121         
122         case FBUS_RX_Sync:
123                 if (rx_byte == FBUS_PHONET_FRAME_ID) {
124                         i->state=FBUS_RX_GetDestination;
125                 } 
126                 break;
127
128         case FBUS_RX_GetDestination:
129
130                 i->MessageDestination=rx_byte;
131                 i->state = FBUS_RX_GetSource;
132     
133                 if (rx_byte!=0x0c) {
134                         i->state=FBUS_RX_Sync;
135                         dprintf("The fbus stream is out of sync - expected 0x0c, got %2x\n",rx_byte);
136                 }
137                 break;
138
139         case FBUS_RX_GetSource:
140
141                 i->MessageSource=rx_byte;
142                 i->state = FBUS_RX_GetType;
143
144                 /* Source should be 0x00 */
145     
146                 if (rx_byte!=0x00)  {
147                         i->state=FBUS_RX_Sync;
148                         dprintf("The fbus stream is out of sync - expected 0x00, got %2x\n",rx_byte);
149                 }
150
151                 break;
152  
153         case FBUS_RX_GetType:
154
155                 i->MessageType=rx_byte;
156                 i->state = FBUS_RX_GetLength1;
157
158                 break;
159
160         case FBUS_RX_GetLength1:
161
162                 i->MessageLength=rx_byte<<8;
163                 i->state = FBUS_RX_GetLength2;
164
165                 break;
166     
167         case FBUS_RX_GetLength2:
168
169                 i->MessageLength=i->MessageLength + rx_byte;
170                 i->state = FBUS_RX_GetMessage;
171                 i->BufferCount=0;
172
173                 break;
174     
175         case FBUS_RX_GetMessage:
176
177                 i->MessageBuffer[i->BufferCount] = rx_byte;
178                 i->BufferCount++;
179     
180                 if (i->BufferCount>PHONET_MAX_FRAME_LENGTH) {
181                         dprintf("PHONET: Message buffer overun - resetting\n");
182                         i->state = FBUS_RX_Sync;
183                         break;
184                 }
185
186                 /* Is that it? */
187
188                 if (i->BufferCount == i->MessageLength) {
189                         SM_IncomingFunction(statemachine, i->MessageType, i->MessageBuffer, i->MessageLength);
190                         i->state = FBUS_RX_Sync;
191                 }
192                 break;
193         default:
194                 i->state = FBUS_RX_Sync;
195                 break;
196         }
197 }
198
199
200 /* This is the main loop function which must be called regularly */
201 /* timeout can be used to make it 'busy' or not */ 
202
203 GSM_Error PHONET_Loop(struct timeval *timeout)
204 {
205         GSM_Error       error = GE_INTERNALERROR;
206         unsigned char   buffer[255];
207         int             count, res;
208         
209         res = device_select(timeout);
210         
211         if (res > 0) { 
212                 res = device_read(buffer, 255);
213                 for (count = 0; count < res; count++) {
214                         PHONET_RX_StateMachine(buffer[count]);
215                 }
216                 if (res > 0) {
217                         error = GE_NONE;        /* This traps errors from device_read */
218                 }
219         } else if (!res) {
220                 error = GE_TIMEOUT;
221         }
222         
223         return error;
224 }
225
226 /* Main function to send an fbus message */
227
228 GSM_Error PHONET_SendMessage(u16 messagesize, u8 messagetype, void *message) {
229
230         u8 out_buffer[PHONET_MAX_TRANSMIT_LENGTH + 5];
231         int current = 0;
232         int total, sent;
233
234         /* FIXME - we should check for the message length ... */
235
236         /* Now construct the message header. */
237
238         out_buffer[current++] = FBUS_PHONET_FRAME_ID;
239         out_buffer[current++] = FBUS_DEVICE_PHONE; /* Destination */
240         out_buffer[current++] = FBUS_DEVICE_PC;    /* Source */
241
242         out_buffer[current++] = messagetype; /* Type */
243
244         out_buffer[current++] = (messagesize & 0xff00) >> 8;
245         out_buffer[current++] = (messagesize & 0x00ff);
246
247         /* Copy in data if any. */
248         
249         if (messagesize > 0) {
250                 memcpy(out_buffer + current, message, messagesize);
251                 current += messagesize;
252         }
253
254 #ifdef DEBUG
255         {
256                 int count;
257                 fprintf(stderr, _("PC: "));
258
259                 for (count = 0; count < current; count++)
260                         fprintf(stderr, "%02x:", out_buffer[count]);
261
262                 fprintf(stderr, "\n");
263         }
264 #endif /* DEBUG */
265
266         /* Send it out... */
267
268         total=current;
269         current=0;
270         sent=0;
271         
272         do {
273                 sent=device_write(out_buffer+current, total-current);
274                 if (sent<0) return (false);
275                 else current+=sent;
276         } while (current<total);
277
278         return GE_NONE;
279 }
280
281
282
283 /* Initialise variables and start the link */
284
285 GSM_Error PHONET_Initialise(GSM_Link *newlink, GSM_Statemachine *state)
286 {
287         GSM_Error error = GE_INTERNALERROR;
288         
289         /* 'Copy in' the global structures */
290         glink = newlink;
291         statemachine = state;
292         
293         /* Fill in the link functions */
294         glink->Loop = &PHONET_Loop;
295         glink->SendMessage = &PHONET_SendMessage;
296         
297         if ((glink->ConnectionType == GCT_Infrared) || (glink->ConnectionType == GCT_Irda)) {
298                 if (PHONET_Open() == true) {
299                         error = GE_NONE;
300                         
301                         /* Init variables */
302                         imessage.state = FBUS_RX_Sync;
303                         imessage.BufferCount = 0;
304                 } else {
305                         error = GE_DEVICEOPENFAILED;
306                 }
307         } else { 
308                 error = GE_DEVICEOPENFAILED;    /* ConnectionType == GCT_Serial etc */
309         }
310         
311         return error;
312