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 FBUS3110 protocol
13 /* "Turn on" prototypes in FBUS3110.h */
16 /* System header files */
23 #include "misc_win32.h"
28 /* Various header file */
29 #include "devices/device.h"
31 #include "protocol/fbus3110.h"
32 #include "protocol/fbus.h"
33 #include "newmodules/n6110.h"
36 GSM_Protocol FBUS3110_Functions = {
42 FBUS3110_RX_StateMachine
46 enum FBUS_RX_States RX_State;
48 u8 MessageDestination, MessageSource;
56 u8 MessageBuffer[FBUS3110_MAX_RECEIVE_LENGTH * 6];
58 u8 RequestSequenceNumber3110=0x10;
61 char *N31_PrintDevice(int Device)
65 // case FBUS3110_DEVICE_PHONE:return _("Phone");
66 // case FBUS3110_DEVICE_PC :return _("PC");
67 default :return _("Unknown");
72 /* N61_RX_DisplayMessage is called when a message we don't know about is
73 received so that the user can see what is going back and forth, and perhaps
74 shed some more light/explain another message type! */
75 void N31_RX_DisplayMessage()
78 fprintf(stdout, _("Msg Dest: %s\n"), N31_PrintDevice(MessageDestination));
79 fprintf(stdout, _("Msg Source: %s\n"), N31_PrintDevice(MessageSource));
80 fprintf(stdout, _("Msg Type: %02x\n"), MessageType);
82 hexdump(MessageLength-2,MessageBuffer);
85 AppendLog(MessageBuffer,MessageLength-2,true);
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 FBUS3110_SendFrame(u16 message_length, u8 message_type, u8 *buffer) {
93 /* Originally out_buffer[FBUS3110_MAX_CONTENT_LENGTH + 2],
94 but it made problems with MBUS */
98 unsigned char checksum;
100 /* Now construct the message header. */
101 out_buffer[current++] = FBUS3110_FRAME_TO_PHONE; /* Start of frame */
102 out_buffer[current++] = message_length + 2; /* Length */
103 out_buffer[current++] = message_type; /* Type */
104 out_buffer[current++] = RequestSequenceNumber3110; /* Sequence number */
106 /* Copy in data if any. */
107 if (message_length != 0) {
108 memcpy(out_buffer + current, buffer, message_length);
109 current += message_length;
112 /* Now calculate checksum over entire message and append to message. */
114 for (count = 0; count < current; count++) checksum ^= out_buffer[count];
115 out_buffer[current++] = checksum;
118 NULL_TX_DisplayMessage(current, out_buffer);
122 if (!NULL_WritePhone(current,out_buffer)) return (false);
127 /* Any command we originate must have a unique SequenceNumber.
128 Observation to date suggests that these values startx at 0x10
129 and cycle up to 0x17 before repeating again. Perhaps more
130 accurately, the numbers cycle 0,1,2,3..7 with bit 4 of the byte
133 void FBUS3110_UpdateSequenceNumber(void)
135 RequestSequenceNumber3110++;
137 if (RequestSequenceNumber3110 > 0x17 || RequestSequenceNumber3110 < 0x10)
138 RequestSequenceNumber3110 = 0x10;
141 int FBUS3110_SendMessage(u16 message_length, u8 message_type, u8 *buffer) {
143 FBUS3110_UpdateSequenceNumber();
145 return FBUS3110_SendFrame(message_length, message_type, buffer);
148 int FBUS3110_SendAck(u8 message_type, u8 message_seq) {
153 /* Applications should call FBUS3110_Terminate to shut down the FBUS3110 thread and
154 close the serial port. */
155 void FBUS3110_Terminate(void)
157 /* Request termination of thread */
158 CurrentRequestTerminate = true;
160 /* Close serial port. */
164 /* RX_State machine for receive handling. Called once for each character
165 received from the phone/phone. */
167 void FBUS3110_RX_StateMachine(unsigned char rx_byte) {
171 /* XOR the byte with the current checksum */
176 case FBUS_RX_Discarding:
177 if (rx_byte != 0x55) break;
181 if (rx_byte == 0x04 || rx_byte == 0x03) {
182 MessageDestination=rx_byte;
183 RX_State = FBUS_RX_GetLength1;
187 case FBUS_RX_GetLength1:
189 MessageLength = rx_byte;
190 RX_State = FBUS_RX_GetType;
194 case FBUS_RX_GetType:
197 RX_State = FBUS_RX_GetMessage;
201 case FBUS_RX_GetMessage:
203 MessageBuffer[BufferCount] = rx_byte;
206 if (BufferCount>FBUS3110_MAX_RECEIVE_LENGTH) {
208 fprintf(stdout, "FB31: Message buffer overun - resetting\n");
210 AppendLogText("OVERUN\n",false);
211 RX_State = FBUS_RX_Sync;
215 /* If this is the last byte, it's the checksum. */
216 if (BufferCount == MessageLength) {
218 RX_State = FBUS_RX_Sync;
226 /* Called by initialisation code to open comm port in asynchronous mode. */
227 bool FBUS3110_OpenSerial(void)
229 switch (CurrentConnectionType) {
233 fprintf(stdout, _("Setting cable for FBUS3110 communication...\n"));
236 device_changespeed(115200);
240 fprintf(stdout,_("Wrong connection type for FBUS3110 module. Inform marcin-wiacek@topnet.pl about it\n"));
248 /* Initialise variables and state machine. */
249 GSM_Error FBUS3110_Initialise(char *port_device, char *initlength,
250 GSM_ConnectionType connection,
251 void (*rlp_callback)(RLP_F96Frame *frame))
253 if (!StartConnection (port_device,false,connection))
254 return GE_INTERNALERROR;
256 CurrentConnectionType = connection;
258 if (FBUS3110_OpenSerial() != true) return GE_INTERNALERROR;