http://marcin-wiacek.fkn.pl/english/zips/mygnokii.tar.gz
[gnokii.git] / common / protocol / fbus3110.c
diff --git a/common/protocol/fbus3110.c b/common/protocol/fbus3110.c
new file mode 100644 (file)
index 0000000..64d9985
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+
+  G N O K I I
+
+  A Linux/Unix toolset and driver for Nokia mobile phones.
+
+  Released under the terms of the GNU GPL, see file COPYING for more details.
+
+  This file provides an API for support for FBUS3110 protocol
+
+*/
+
+/* "Turn on" prototypes in FBUS3110.h */
+#define __fbus3110_c 
+
+/* System header files */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef WIN32
+  #include <windows.h>
+  #include "misc_win32.h"
+#else
+  #include <ctype.h>
+#endif
+
+/* Various header file */
+#include "devices/device.h"
+#include "gsm-api.h"
+#include "protocol/fbus3110.h"
+#include "protocol/fbus.h"
+#include "newmodules/n6110.h"
+#include "misc.h"
+
+GSM_Protocol FBUS3110_Functions = {
+  FBUS3110_Initialise,
+  FBUS3110_SendMessage,
+  FBUS3110_SendFrame,
+  NULL_WritePhone,
+  FBUS3110_Terminate,
+  FBUS3110_RX_StateMachine
+};
+
+/* Local variables */
+enum FBUS_RX_States RX_State;
+
+u8 MessageDestination, MessageSource;
+
+u16 BufferCount;
+
+u16 MessageLength;
+
+u8 MessageType;
+
+u8 MessageBuffer[FBUS3110_MAX_RECEIVE_LENGTH * 6];
+
+u8 RequestSequenceNumber3110=0x10;
+
+#ifdef DEBUG   
+char *N31_PrintDevice(int Device)
+{
+  switch (Device) {
+
+//  case FBUS3110_DEVICE_PHONE:return _("Phone");
+//  case FBUS3110_DEVICE_PC   :return _("PC");
+  default               :return _("Unknown");
+  }
+}
+#endif /* DEBUG */
+
+/* N61_RX_DisplayMessage is called when a message we don't know about is
+   received so that the user can see what is going back and forth, and perhaps
+   shed some more light/explain another message type! */
+void N31_RX_DisplayMessage()
+{
+#ifdef DEBUG
+  fprintf(stdout, _("Msg Dest: %s\n"), N31_PrintDevice(MessageDestination));
+  fprintf(stdout, _("Msg Source: %s\n"), N31_PrintDevice(MessageSource));
+  fprintf(stdout, _("Msg Type: %02x\n"), MessageType);
+
+  hexdump(MessageLength-2,MessageBuffer);
+#endif
+
+  AppendLog(MessageBuffer,MessageLength-2,true);
+}
+
+/* Prepares the message header and sends it, prepends the message start byte
+          (0x1e) and other values according the value specified when called.
+          Calculates checksum and then sends the lot down the pipe... */
+int FBUS3110_SendFrame(u16 message_length, u8 message_type, u8 *buffer) {
+
+  /* Originally out_buffer[FBUS3110_MAX_CONTENT_LENGTH + 2],
+     but it made problems with MBUS */
+  u8 out_buffer[1000];
+  
+  int count, current=0;
+  unsigned char        checksum;
+
+  /* Now construct the message header. */
+  out_buffer[current++] = FBUS3110_FRAME_TO_PHONE;   /* Start of frame */
+  out_buffer[current++] = message_length + 2;        /* Length */
+  out_buffer[current++] = message_type;              /* Type */
+  out_buffer[current++] = RequestSequenceNumber3110; /* Sequence number */
+
+  /* Copy in data if any. */
+  if (message_length != 0) {
+    memcpy(out_buffer + current, buffer, message_length);
+    current += message_length;
+  }
+
+  /* Now calculate checksum over entire message and append to message. */
+  checksum = 0;
+  for (count = 0; count < current; count++) checksum ^= out_buffer[count];
+  out_buffer[current++] = checksum;
+
+#ifdef DEBUG
+  NULL_TX_DisplayMessage(current, out_buffer);
+#endif /* DEBUG */
+
+  /* Send it out... */
+  if (!NULL_WritePhone(current,out_buffer)) return (false);
+
+  return (true);
+}
+
+/* Any command we originate must have a unique SequenceNumber.
+   Observation to date suggests that these values startx at 0x10
+   and cycle up to 0x17 before repeating again.  Perhaps more
+   accurately, the numbers cycle 0,1,2,3..7 with bit 4 of the byte
+   premanently set. */
+
+void FBUS3110_UpdateSequenceNumber(void)
+{
+  RequestSequenceNumber3110++;
+
+  if (RequestSequenceNumber3110 > 0x17 || RequestSequenceNumber3110 < 0x10)
+    RequestSequenceNumber3110 = 0x10;
+}
+
+int FBUS3110_SendMessage(u16 message_length, u8 message_type, u8 *buffer) {
+
+  FBUS3110_UpdateSequenceNumber();
+
+  return FBUS3110_SendFrame(message_length, message_type, buffer);
+}
+
+int FBUS3110_SendAck(u8 message_type, u8 message_seq) {
+
+  return 0;
+}
+
+/* Applications should call FBUS3110_Terminate to shut down the FBUS3110 thread and
+   close the serial port. */
+void FBUS3110_Terminate(void)
+{
+  /* Request termination of thread */
+  CurrentRequestTerminate = true;
+
+  /* Close serial port. */
+  device_close();
+}
+
+/* RX_State machine for receive handling.  Called once for each character
+   received from the phone/phone. */
+
+void FBUS3110_RX_StateMachine(unsigned char rx_byte) {
+
+  static int checksum;
+  
+  /* XOR the byte with the current checksum */
+  checksum ^= rx_byte;
+
+  switch (RX_State) {
+       
+  case FBUS_RX_Discarding:
+    if (rx_byte != 0x55) break;
+
+  case FBUS_RX_Sync:
+
+    if (rx_byte == 0x04 || rx_byte == 0x03) {
+      MessageDestination=rx_byte;
+      RX_State = FBUS_RX_GetLength1;
+    }
+    break;
+
+  case FBUS_RX_GetLength1:
+
+    MessageLength = rx_byte;
+    RX_State = FBUS_RX_GetType;
+    
+    break;
+
+  case FBUS_RX_GetType:
+
+    MessageType=rx_byte;
+    RX_State = FBUS_RX_GetMessage;
+
+    break;
+
+  case FBUS_RX_GetMessage:
+
+    MessageBuffer[BufferCount] = rx_byte;
+    BufferCount ++;
+    
+    if (BufferCount>FBUS3110_MAX_RECEIVE_LENGTH) {
+#ifdef DEBUG
+      fprintf(stdout, "FB31: Message buffer overun - resetting\n");
+#endif
+      AppendLogText("OVERUN\n",false);
+      RX_State = FBUS_RX_Sync;
+      break;
+    }
+
+    /* If this is the last byte, it's the checksum. */
+    if (BufferCount == MessageLength) {
+
+      RX_State = FBUS_RX_Sync;    
+    }
+    break;
+  default:
+    break;
+  }
+}
+  
+/* Called by initialisation code to open comm port in asynchronous mode. */
+bool FBUS3110_OpenSerial(void)
+{
+  switch (CurrentConnectionType) {
+     case GCT_FBUS3110:
+
+#ifdef DEBUG
+       fprintf(stdout, _("Setting cable for FBUS3110 communication...\n"));
+#endif /* DEBUG */
+
+       device_changespeed(115200);   
+       break;
+     default:
+#ifdef DEBUG
+       fprintf(stdout,_("Wrong connection type for FBUS3110 module. Inform marcin-wiacek@topnet.pl about it\n"));
+#endif
+       break;
+  }
+
+  return (true);
+}
+
+/* Initialise variables and state machine. */
+GSM_Error FBUS3110_Initialise(char *port_device, char *initlength,
+                          GSM_ConnectionType connection,
+                          void (*rlp_callback)(RLP_F96Frame *frame))
+{
+  if (!StartConnection (port_device,false,connection))
+    return GE_INTERNALERROR;
+      
+  CurrentConnectionType = connection;
+
+  if (FBUS3110_OpenSerial() != true) return GE_INTERNALERROR;
+
+  return (GE_NONE);
+}