This commit was generated by cvs2svn to compensate for changes in r158,
[gnokii.git] / common / protocol / fbusirda.c
1 /*
2
3   G N O K I I
4
5   A Linux/Unix toolset and driver for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8
9   This file provides an API for support for fbusirda protocol
10
11 */
12
13 /* "Turn on" prototypes in fbusirda.h */
14 #define __fbusirda_c 
15
16 /* System header files */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21
22 #ifdef WIN32
23   #include <windows.h>
24   #include "misc_win32.h"
25 #else
26   #include <ctype.h>
27 #endif
28  
29 /* Various header file */
30 #include "devices/device.h"
31 #include "gsm-api.h"
32 #include "protocol/fbusirda.h"
33 #include "protocol/fbus.h"
34 #include "misc.h"
35
36 GSM_Protocol FBUSIRDA_Functions = {
37   FBUSIRDA_Initialise,
38   FBUSIRDA_SendMessage,
39   FBUSIRDA_SendFrame,
40   FBUSIRDA_WritePhone,
41   FBUSIRDA_Terminate,
42   FBUSIRDA_RX_StateMachine
43 };
44
45 /* Local variables */
46 enum FBUS_RX_States RX_State;
47
48 u8 MessageDestination, MessageSource;
49
50 u16 BufferCount;
51
52 u16 MessageLength;
53
54 u8 MessageType;
55
56 u8 MessageBuffer[FBUS_MAX_RECEIVE_LENGTH * 6];
57
58 #ifdef DEBUG
59 char *FBUSIRDA_PrintDevice(int Device)
60 {
61   switch (Device) {
62
63   case FBUS_DEVICE_PHONE:
64     return _("Phone");
65
66   case FBUS_DEVICE_PC:
67     return _("PC");
68
69   default:
70     return _("Unknown");
71
72   }
73 }
74
75 /* FBUSIRDA_RX_DisplayMessage is called when a message we don't know about is
76    received so that the user can see what is going back and forth, and perhaps
77    shed some more light/explain another message type! */
78 void FBUSIRDA_RX_DisplayMessage()
79 {
80   fprintf(stdout, _("Msg Source: %s\n"), FBUSIRDA_PrintDevice(MessageSource));
81   fprintf(stdout, _("Msg Dest: %s\n"), FBUSIRDA_PrintDevice(MessageDestination));
82   fprintf(stdout, _("Msg Type: %02x\n"), MessageType);
83
84   hexdump( MessageLength, MessageBuffer);
85 }
86 #endif /* DEBUG */
87
88 /* Prepares the message header and sends it, prepends the message start byte
89            (0x1e) and other values according the value specified when called.
90            Calculates checksum and then sends the lot down the pipe... */
91 int FBUSIRDA_SendFrame(u16 message_length, u8 message_type, u8 *buffer) {
92   u8 out_buffer[FBUSIRDA_MAX_CONTENT_LENGTH + 2];
93   
94   int current=0;
95   int header=0;
96
97   /* FIXME - we should check for the message length ... */
98
99   /* Now construct the message header. */
100
101   out_buffer[current++] = FBUSIRDA_FRAME_ID;    /* Start of the frame indicator */
102
103   out_buffer[current++] = FBUS_DEVICE_PHONE; /* Destination */
104
105   out_buffer[current++] = FBUS_DEVICE_PC;    /* Source */
106
107   out_buffer[current++] = message_type; /* Type */
108
109   out_buffer[current++] = message_length/256; /* Length1 */
110   out_buffer[current++] = message_length%256; /* Length2 */
111
112   /* Copy in data if any. */    
113         
114   if (message_length != 0) {
115     memcpy(out_buffer + current, buffer, message_length);
116     header = current;
117     current+=message_length;
118   }
119
120 #ifdef DEBUG
121   NULL_TX_DisplayMessage( current, out_buffer);
122 #endif /* DEBUG */
123
124   /* Send it out... */
125   return ( FBUSIRDA_WritePhone(current,out_buffer) - header);
126
127 }
128
129 int FBUSIRDA_SendMessage(u16 message_length, u8 message_type, u8 *buffer) {
130   
131   u8 frame_buffer[FBUSIRDA_MAX_CONTENT_LENGTH + 2];
132   u16 ret;
133
134     memcpy(frame_buffer, buffer, message_length);
135     ret = FBUSIRDA_SendFrame(message_length, message_type, frame_buffer);
136
137     if (ret != message_length)
138       {
139        printf("CAUTION:  FBUSIRDA_SendFrame return written %d bytes of %d !\n",ret, message_length);
140        return(false);
141       }
142     else
143       return (true);
144 }
145
146 int FBUSIRDA_SendAck(u8 message_type, u8 message_seq) {
147   return(true);
148 }
149
150 /* Applications should call MBUS_Terminate to shut down the MBUS thread and
151    close the serial port. */
152 void FBUSIRDA_Terminate(void)
153 {  
154   /* Request termination of thread */
155   CurrentRequestTerminate = true;
156
157   /* Close serial port. */
158   device_close();
159 }
160
161 /* RX_State machine for receive handling.  Called once for each character
162    received from the phone/phone. */
163 void FBUSIRDA_RX_StateMachine(unsigned char rx_byte) {
164
165   unsigned char max;
166
167   int i;
168
169   i=0;
170
171   switch (RX_State) {
172
173   case FBUS_RX_Discarding:
174     break;
175     
176   /* Messages from the phone start with an 0x14 (IRDA, Nokia:PhoNet).
177      We use this to "synchronise" with the incoming data stream. */
178
179   case FBUS_RX_Sync:
180
181     if (rx_byte == FBUSIRDA_FRAME_ID) {
182       BufferCount = 0;  
183       RX_State = FBUS_RX_GetDestination;
184     }
185     
186     break;
187
188   case FBUS_RX_GetDestination:
189
190     MessageDestination=rx_byte;
191     RX_State = FBUS_RX_GetSource;
192
193  /* When there is a checksum error and things get out of sync we have to manage to resync */
194     /* If doing a data call at the time, finding a 0x1e etc is really quite likely in the data stream */
195     /* Then all sorts of horrible things happen because the packet length etc is wrong... */
196     /* Therefore we test here for a destination of 0x0c and return to the top if it is not */
197
198 #ifdef DEBUG
199     if (strstr(GSM_Info->IrdaModels,"decode")!=NULL)
200      {
201        if (rx_byte!=FBUS_DEVICE_PC && rx_byte!=FBUS_DEVICE_PHONE )
202         {
203           RX_State=FBUS_RX_Sync;
204           fprintf(stdout,"decode: expected FBUS_DEVICE_PC/FBUS_DEVICE_PHONE, got %2x\n",rx_byte);
205         }
206      }//decode Model
207     else
208      {
209 #endif
210        if (rx_byte!=FBUS_DEVICE_PC)
211        {
212           RX_State=FBUS_RX_Sync;
213 #ifdef DEBUG
214           fprintf(stdout,"The FBUSIRDA stream is out of sync - expected FBUS_DEVICE_PC, got %2x\n",rx_byte);
215 #endif
216        }
217 #ifdef DEBUG
218      }//not decode Model
219 #endif
220
221     break;
222
223   case FBUS_RX_GetSource:
224
225     MessageSource=rx_byte;
226     RX_State = FBUS_RX_GetType;
227
228 #ifdef DEBUG
229     if (strstr(GSM_Info->IrdaModels,"decode")!=NULL)
230      {
231        if (rx_byte!=FBUS_DEVICE_PC && rx_byte!=FBUS_DEVICE_PHONE )
232         {
233           RX_State=FBUS_RX_Sync;
234           fprintf(stdout,"decode: expected FBUS_DEVICE_PC/FBUS_DEVICE_PHONE, got %2x\n",rx_byte);
235         }
236      }//decode Model
237     else
238      {
239 #endif
240        if (rx_byte!=FBUS_DEVICE_PHONE)
241         {
242           RX_State=FBUS_RX_Sync;
243 #ifdef DEBUG
244           fprintf(stdout,"The FBUSIRDA stream is out of sync - expected FBUS_DEVICE_PHONE, got %2x\n",rx_byte);
245 #endif
246         }
247 #ifdef DEBUG
248      }//not decode Model
249 #endif
250
251     break;
252
253   case FBUS_RX_GetType:
254
255     MessageType=rx_byte;
256     RX_State = FBUS_RX_GetLength1;
257
258     break;
259
260   case FBUS_RX_GetLength1:
261
262     MessageLength=0;
263
264     /* MW:Here are problems with conversion. For chars 0-127 it's OK, for
265        higher not (probably because rx_byte is char type) - improtant
266        for MBUS. So, I make it double and strange - generally it should be
267        more simple and make simple convert rx_byte into MessageLength */
268     if (rx_byte!=0) {
269       max=rx_byte;
270       MessageLength=max*256;
271     }
272
273     RX_State = FBUS_RX_GetLength2;
274     
275     break;
276     
277   case FBUS_RX_GetLength2:
278
279     /* MW:Here are problems with conversion. For chars 0-127 it's OK, for
280        higher not (probably because rx_byte is char type) - important
281        for MBUS. So, I make it double and strange - generally it should be
282        more simple and make simple convert rx_byte into MessageLength */      
283 #if defined(__svr4__) || defined(__FreeBSD__)
284     if (rx_byte!=0) {
285       for (i=0;i<rx_byte;i++)
286         MessageLength=MessageLength++;
287     }
288 #else
289     if (rx_byte!=0) {
290       max=rx_byte;
291       MessageLength=MessageLength+max;
292     }
293 #endif
294     
295     RX_State = FBUS_RX_GetMessage;
296
297     break;
298
299   case FBUS_RX_GetMessage:
300
301     MessageBuffer[BufferCount] = rx_byte;
302     BufferCount ++;
303
304     if (BufferCount == MessageLength)
305        {        
306         if (MessageSource == FBUS_DEVICE_PHONE)
307          {
308 #ifdef DEBUG
309            FBUSIRDA_RX_DisplayMessage();
310 #endif /* DEBUG */
311            GSM->DispatchMessage(MessageLength, MessageBuffer, MessageType);
312          }
313         else
314          {
315 #ifdef DEBUG
316            /* for --decodefile */
317            fprintf(stdout, _("Msg Source: %s\n"), FBUSIRDA_PrintDevice(MessageSource));
318            fprintf(stdout, _("Msg Dest: %s\n"), FBUSIRDA_PrintDevice(MessageDestination));
319            fprintf(stdout, _("Msg Type: %02x\n"), MessageType);
320            hexdump( MessageLength, MessageBuffer);
321 #endif /* DEBUG */
322          }
323       
324       RX_State = FBUS_RX_Sync;
325     }
326     break;
327   }
328 }
329
330 /* Called by initialisation code to open comm port in asynchronous mode. */
331 bool FBUSIRDA_OpenSerial(void)
332 {
333 #ifdef DEBUG
334   fprintf(stdout, _("Setting FBUS Irda communication...\n"));
335 #endif /* DEBUG */
336
337   return (true);
338
339 }
340
341 /* Initialise variables and state machine. */
342 GSM_Error FBUSIRDA_Initialise(char *port_device, char *initlength,
343                             GSM_ConnectionType connection,
344                             void (*rlp_callback)(RLP_F96Frame *frame))
345 {
346   CurrentConnectionType = connection;
347
348   if (!StartConnection(port_device,false,connection)) {
349     return GE_INTERNALERROR;
350   }
351   RX_State=FBUS_RX_Sync;
352   
353   return (GE_NONE);
354 }
355
356 bool FBUSIRDA_WritePhone (u16 length, u8 *buffer) {
357
358   if (!CurrentDisableKeepAlive)
359     usleep(150);
360
361   return (device_write(buffer,length));
362 }