5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Released under the terms of the GNU GPL, see file COPYING for more details.
9 This file provides an API for support for fbusirda protocol
15 /* "Turn on" prototypes in fbusirda.h */
18 /* System header files */
26 #include "misc_win32.h"
31 /* Various header file */
32 #include "devices/device.h"
34 #include "protocol/fbusirda.h"
35 #include "protocol/fbus.h"
38 GSM_Protocol FBUSIRDA_Functions = {
44 FBUSIRDA_RX_StateMachine
48 enum FBUS_RX_States RX_State;
50 u8 MessageDestination, MessageSource;
58 u8 MessageBuffer[FBUS_MAX_RECEIVE_LENGTH * 6];
61 char *FBUSIRDA_PrintDevice(int Device)
65 case FBUS_DEVICE_PHONE:
77 /* FBUSIRDA_RX_DisplayMessage is called when a message we don't know about is
78 received so that the user can see what is going back and forth, and perhaps
79 shed some more light/explain another message type! */
80 void FBUSIRDA_RX_DisplayMessage()
82 fprintf(stdout, _("Msg Source: %s\n"), FBUSIRDA_PrintDevice(MessageSource));
83 fprintf(stdout, _("Msg Dest: %s\n"), FBUSIRDA_PrintDevice(MessageDestination));
84 fprintf(stdout, _("Msg Type: %02x\n"), MessageType);
86 hexdump( MessageLength, MessageBuffer);
90 /* Prepares the message header and sends it, prepends the message start byte
91 (0x1e) and other values according the value specified when called.
92 Calculates checksum and then sends the lot down the pipe... */
93 int FBUSIRDA_SendFrame(u16 message_length, u8 message_type, u8 *buffer) {
94 u8 out_buffer[FBUSIRDA_MAX_CONTENT_LENGTH + 2];
99 /* FIXME - we should check for the message length ... */
101 /* Now construct the message header. */
103 out_buffer[current++] = FBUSIRDA_FRAME_ID; /* Start of the frame indicator */
105 out_buffer[current++] = FBUS_DEVICE_PHONE; /* Destination */
107 out_buffer[current++] = FBUS_DEVICE_PC; /* Source */
109 out_buffer[current++] = message_type; /* Type */
111 out_buffer[current++] = message_length/256; /* Length1 */
112 out_buffer[current++] = message_length%256; /* Length2 */
114 /* Copy in data if any. */
116 if (message_length != 0) {
117 memcpy(out_buffer + current, buffer, message_length);
119 current+=message_length;
123 NULL_TX_DisplayMessage( current, out_buffer);
127 return ( FBUSIRDA_WritePhone(current,out_buffer) - header);
131 int FBUSIRDA_SendMessage(u16 message_length, u8 message_type, u8 *buffer) {
133 u8 frame_buffer[FBUSIRDA_MAX_CONTENT_LENGTH + 2];
136 memcpy(frame_buffer, buffer, message_length);
137 ret = FBUSIRDA_SendFrame(message_length, message_type, frame_buffer);
139 if (ret != message_length)
141 printf("CAUTION: FBUSIRDA_SendFrame return written %d bytes of %d !\n",ret, message_length);
148 int FBUSIRDA_SendAck(u8 message_type, u8 message_seq) {
152 /* Applications should call MBUS_Terminate to shut down the MBUS thread and
153 close the serial port. */
154 void FBUSIRDA_Terminate(void)
156 /* Request termination of thread */
157 CurrentRequestTerminate = true;
159 /* Close serial port. */
163 /* RX_State machine for receive handling. Called once for each character
164 received from the phone/phone. */
165 void FBUSIRDA_RX_StateMachine(unsigned char rx_byte) {
175 case FBUS_RX_Discarding:
178 /* Messages from the phone start with an 0x14 (IRDA, Nokia:PhoNet).
179 We use this to "synchronise" with the incoming data stream. */
183 if (rx_byte == FBUSIRDA_FRAME_ID) {
185 RX_State = FBUS_RX_GetDestination;
190 case FBUS_RX_GetDestination:
192 MessageDestination=rx_byte;
193 RX_State = FBUS_RX_GetSource;
195 /* When there is a checksum error and things get out of sync we have to manage to resync */
196 /* If doing a data call at the time, finding a 0x1e etc is really quite likely in the data stream */
197 /* Then all sorts of horrible things happen because the packet length etc is wrong... */
198 /* Therefore we test here for a destination of 0x0c and return to the top if it is not */
201 if (strstr(GSM_Info->IrdaModels,"decode")!=NULL)
203 if (rx_byte!=FBUS_DEVICE_PC && rx_byte!=FBUS_DEVICE_PHONE )
205 RX_State=FBUS_RX_Sync;
206 fprintf(stdout,"decode: expected FBUS_DEVICE_PC/FBUS_DEVICE_PHONE, got %2x\n",rx_byte);
212 if (rx_byte!=FBUS_DEVICE_PC)
214 RX_State=FBUS_RX_Sync;
216 fprintf(stdout,"The FBUSIRDA stream is out of sync - expected FBUS_DEVICE_PC, got %2x\n",rx_byte);
225 case FBUS_RX_GetSource:
227 MessageSource=rx_byte;
228 RX_State = FBUS_RX_GetType;
231 if (strstr(GSM_Info->IrdaModels,"decode")!=NULL)
233 if (rx_byte!=FBUS_DEVICE_PC && rx_byte!=FBUS_DEVICE_PHONE )
235 RX_State=FBUS_RX_Sync;
236 fprintf(stdout,"decode: expected FBUS_DEVICE_PC/FBUS_DEVICE_PHONE, got %2x\n",rx_byte);
242 if (rx_byte!=FBUS_DEVICE_PHONE)
244 RX_State=FBUS_RX_Sync;
246 fprintf(stdout,"The FBUSIRDA stream is out of sync - expected FBUS_DEVICE_PHONE, got %2x\n",rx_byte);
255 case FBUS_RX_GetType:
258 RX_State = FBUS_RX_GetLength1;
262 case FBUS_RX_GetLength1:
266 /* MW:Here are problems with conversion. For chars 0-127 it's OK, for
267 higher not (probably because rx_byte is char type) - improtant
268 for MBUS. So, I make it double and strange - generally it should be
269 more simple and make simple convert rx_byte into MessageLength */
272 MessageLength=max*256;
275 RX_State = FBUS_RX_GetLength2;
279 case FBUS_RX_GetLength2:
281 /* MW:Here are problems with conversion. For chars 0-127 it's OK, for
282 higher not (probably because rx_byte is char type) - important
283 for MBUS. So, I make it double and strange - generally it should be
284 more simple and make simple convert rx_byte into MessageLength */
285 #if defined(__svr4__) || defined(__FreeBSD__)
287 for (i=0;i<rx_byte;i++)
288 MessageLength=MessageLength++;
293 MessageLength=MessageLength+max;
297 RX_State = FBUS_RX_GetMessage;
301 case FBUS_RX_GetMessage:
303 MessageBuffer[BufferCount] = rx_byte;
306 if (BufferCount == MessageLength)
308 if (MessageSource == FBUS_DEVICE_PHONE)
311 FBUSIRDA_RX_DisplayMessage();
313 GSM->DispatchMessage(MessageLength, MessageBuffer, MessageType);
318 /* for --decodefile */
319 fprintf(stdout, _("Msg Source: %s\n"), FBUSIRDA_PrintDevice(MessageSource));
320 fprintf(stdout, _("Msg Dest: %s\n"), FBUSIRDA_PrintDevice(MessageDestination));
321 fprintf(stdout, _("Msg Type: %02x\n"), MessageType);
322 hexdump( MessageLength, MessageBuffer);
326 RX_State = FBUS_RX_Sync;
332 /* Called by initialisation code to open comm port in asynchronous mode. */
333 bool FBUSIRDA_OpenSerial(void)
336 fprintf(stdout, _("Setting FBUS Irda communication...\n"));
343 /* Initialise variables and state machine. */
344 GSM_Error FBUSIRDA_Initialise(char *port_device, char *initlength,
345 GSM_ConnectionType connection,
346 void (*rlp_callback)(RLP_F96Frame *frame))
348 CurrentConnectionType = connection;
350 if (!StartConnection(port_device,false,connection)) {
351 return GE_INTERNALERROR;
353 RX_State=FBUS_RX_Sync;
358 bool FBUSIRDA_WritePhone (u16 length, u8 *buffer) {
360 if (!CurrentDisableKeepAlive)
363 return (device_write(buffer,length));