summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/protocol
Side-by-side diff
Diffstat (limited to 'gammu/emb/common/protocol') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/protocol/alcatel/alcabus.c255
-rw-r--r--gammu/emb/common/protocol/alcatel/alcabus.h61
-rw-r--r--gammu/emb/common/protocol/at/at.c229
-rw-r--r--gammu/emb/common/protocol/at/at.h36
-rw-r--r--gammu/emb/common/protocol/nokia/fbus2.c444
-rw-r--r--gammu/emb/common/protocol/nokia/fbus2.h38
-rw-r--r--gammu/emb/common/protocol/nokia/mbus2.c252
-rw-r--r--gammu/emb/common/protocol/nokia/mbus2.h28
-rw-r--r--gammu/emb/common/protocol/nokia/phonet.c217
-rw-r--r--gammu/emb/common/protocol/nokia/phonet.h35
-rw-r--r--gammu/emb/common/protocol/obex/obex.c120
-rw-r--r--gammu/emb/common/protocol/obex/obex.h33
-rw-r--r--gammu/emb/common/protocol/protocol.h31
-rw-r--r--gammu/emb/common/protocol/symbian/mrouter.c110
-rw-r--r--gammu/emb/common/protocol/symbian/mrouter.h31
15 files changed, 1920 insertions, 0 deletions
diff --git a/gammu/emb/common/protocol/alcatel/alcabus.c b/gammu/emb/common/protocol/alcatel/alcabus.c
new file mode 100644
index 0000000..b5b5a30
--- a/dev/null
+++ b/gammu/emb/common/protocol/alcatel/alcabus.c
@@ -0,0 +1,255 @@
+/* (c) 2002-2003 by Michal Cihar
+ *
+ * Low level functions for communication with Alcatel One Touch phones.
+ *
+ * This code implements the protocol used for synchronisation with PC.
+ */
+#include "../../gsmstate.h"
+
+#if defined(GSM_ENABLE_ALCABUS)
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../gsmcomon.h"
+#include "alcabus.h"
+
+static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned char *data, int len, unsigned char type)
+{
+ GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS;
+ unsigned char buffer[1024];
+ int size = 0;
+ int sent = 0;
+ int i = 0, checksum = 0;
+
+ if ((type == 0) && (len == 0)) return ERR_NONE;
+
+ buffer[0] = ALCATEL_HEADER;
+ buffer[1] = type;
+ switch (type) {
+ case ALCATEL_CONNECT:
+ buffer[2] = 0x0A;
+ buffer[3] = 0x04;
+ buffer[4] = 0x00;
+ size = 5;
+ d->next_frame = ALCATEL_CONNECT_ACK;
+ d->busy = true;
+ break;
+ case ALCATEL_DISCONNECT:
+ size = 2;
+ d->next_frame = ALCATEL_DISCONNECT_ACK;
+ d->busy = true;
+ break;
+ case ALCATEL_DATA:
+ buffer[2] = d->out_counter;
+
+ /* Increase outgoing packet counter */
+ if (d->out_counter == ALCATEL_MAX_COUNTER) d->out_counter = 0;
+ else d->out_counter++;
+
+ buffer[3] = '\0';
+ buffer[4] = len;
+ memcpy(buffer+5, data, len);
+ size = 5 + len;
+ d->next_frame = ALCATEL_ACK;
+ d->busy = true;
+ break;
+ case ALCATEL_ACK:
+ buffer[2] = d->in_counter;
+ if (d->in_counter == 0) d->in_counter = 1;
+ size = 3;
+ d->next_frame = ALCATEL_DATA;
+ break;
+ default:
+ /* In fact, other types probably can came just from mobile... */
+ smprintf(s,"WARNING: Wanted to send some unknown packet (%02X)\n", type);
+ return ERR_NOTIMPLEMENTED;
+ }
+
+ /* Calculate packet checksum */
+ for (i=0; i<size; i++) checksum ^= buffer[i];
+
+ buffer[size] = checksum;
+ size ++;
+
+ GSM_DumpMessageLevel2(s, buffer, size, type);
+ GSM_DumpMessageLevel3(s, buffer, size, type);
+ while (sent != size ) {
+ if ((i = s->Device.Functions->WriteDevice(s,buffer + sent, size - sent)) == 0) {
+ return ERR_DEVICEWRITEERROR;
+ }
+ sent += i;
+ }
+
+ if (type == ALCATEL_CONNECT || type == ALCATEL_DISCONNECT) {
+ /* For connect and disconnect we need a bit larger delay */
+// my_sleep(10);
+ while (d->busy) {
+ GSM_ReadDevice(s,true);
+ my_sleep(1);
+ i++;
+ if (i == 10) return ERR_TIMEOUT;
+ }
+ }
+ return ERR_NONE;
+}
+
+static GSM_Error ALCABUS_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
+{
+ GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS;
+ int i;
+ int checksum = 0;
+
+ if (d->Msg.BufferUsed < d->Msg.Length + 1) {
+ d->Msg.BufferUsed = d->Msg.Length + 1;
+ d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
+ }
+
+ /* Check for header */
+ if ((d->Msg.Length == 0) && (rx_char != ALCATEL_HEADER)) {
+ smprintf(s,"WARNING: Expecting alcatel header (%02X) but got (%02X)\n", ALCATEL_HEADER, rx_char);
+ return ERR_UNKNOWNRESPONSE;
+ /* Check for packet type */
+ } else if (d->Msg.Length == 1){
+ d->Msg.Type = rx_char;
+ /* Was it unexpected packet? */
+ if ((rx_char != d->next_frame) && (rx_char != ALCATEL_CONTROL)) {
+ smprintf(s,"WARNING: Expecting alcatel packet type (%02X) but got (%02X)\n", d->next_frame, rx_char);
+ }
+ /* Determine packet size */
+ switch (rx_char) {
+ case ALCATEL_ACK:
+ d->expected_size = 4;
+ break;
+ case ALCATEL_DATA:
+ /* Packet length is in it's header */
+ d->expected_size = -1;
+ break;
+ case ALCATEL_CONTROL:
+ d->expected_size = 4;
+ break;
+ case ALCATEL_CONNECT_ACK:
+ d->expected_size = 6;
+ break;
+ case ALCATEL_DISCONNECT_ACK:
+ d->expected_size = 3;
+ break;
+ default:
+ smprintf(s,"WARNING: Something went wrong, unknown packet received (%02X)\n", rx_char);
+ return ERR_UNKNOWNRESPONSE;
+ }
+ /* Check counter, we can probably ignore error here ;-) */
+ } else if ((d->Msg.Length == 2) && (d->Msg.Type == ALCATEL_DATA)) {
+ if (rx_char != d->in_counter) {
+ smprintf(s,"WARNING: Unexpected packet number, ignoring (expected %02X, received %02X)\n", d->in_counter, rx_char);
+ d->in_counter = rx_char;
+ }
+ /* Increase incoming packet counter */
+ if (d->in_counter == ALCATEL_MAX_COUNTER) d->in_counter = 0;
+ else d->in_counter++;
+ /* Read size for data packet */
+ } else if ((d->Msg.Length == 4) && (d->Msg.Type == ALCATEL_DATA)) {
+ /* Header till now + checksum */
+ d->expected_size = (int)rx_char + 6;
+ }
+
+ /* Write received byte into buffer */
+ d->Msg.Buffer[d->Msg.Length++] = rx_char;
+
+ /* Did we received whole packet? */
+ if (d->expected_size == d->Msg.Length) {
+ /* Check checksum */
+ for (i=0; i< (d->Msg.Length - 1); i++) checksum ^= d->Msg.Buffer[i];
+ if (checksum != d->Msg.Buffer[d->Msg.Length - 1]) {
+ /* We can only warn, as we don't know what should happend now... */
+ smprintf(s,"WARNING: Ignoring incorrect packet checksum!\n");
+ }
+
+ /* Was it data? */
+ if (d->Msg.Type == ALCATEL_DATA) {
+ /* Dispatch message */
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
+ /* Send ack */
+ ALCABUS_WriteMessage (s, 0, 0, ALCATEL_ACK);
+ /* Reset message length */
+ d->Msg.Length = 0;
+ /* Was it ack? */
+ } else if ((d->Msg.Type == ALCATEL_ACK) ||
+ (d->Msg.Type == ALCATEL_CONTROL) ||
+ (d->Msg.Type == ALCATEL_CONNECT_ACK) ||
+ (d->Msg.Type == ALCATEL_DISCONNECT_ACK)) {
+ /* TODO: check counter of ack? */
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
+ smprintf(s, "Received %s ack ",
+ (d->Msg.Type == ALCATEL_ACK) ? "normal" :
+ (d->Msg.Type == ALCATEL_CONTROL) ? "control" :
+ (d->Msg.Type == ALCATEL_CONNECT_ACK) ? "connect" :
+ (d->Msg.Type == ALCATEL_DISCONNECT_ACK) ? "disconnect" :
+ "BUG");
+ smprintf(s, "0x%02x / 0x%04x", d->Msg.Type, d->Msg.Length);
+ DumpMessage(s->di.df, s->di.dl, d->Msg.Buffer, d->Msg.Length);
+ fflush(s->di.df);
+ }
+ if (s->di.dl==DL_BINARY) {
+ smprintf(s,"%c",0x02); /* Receiving */
+ smprintf(s,"%c",d->Msg.Type);
+ smprintf(s,"%c",d->Msg.Length/256);
+ smprintf(s,"%c",d->Msg.Length%256);
+ for (i=0;i<d->Msg.Length;i++) smprintf(s,"%c",d->Msg.Buffer[i]);
+ }
+ if (d->Msg.Type != ALCATEL_CONTROL) {
+ d->next_frame = ALCATEL_DATA;
+ d->busy = false;
+ }
+ /* Reset message length */
+ d->Msg.Length = 0;
+ }
+
+ /* Was it unexpected type? */
+ if ((d->Msg.Type != d->next_frame) && (d->Msg.Type != ALCATEL_CONTROL)) {
+ return ERR_FRAMENOTREQUESTED;
+ }
+ } /* Last byte of packet */
+
+ return ERR_NONE;
+}
+
+static GSM_Error ALCABUS_Initialise(GSM_StateMachine *s)
+{
+ GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS;
+
+ /* Initialise some variables */
+ d->Msg.BufferUsed = 0;
+ d->Msg.Buffer = NULL;
+ d->Msg.Length = 0;
+ d->Msg.Type = 0;
+ d->in_counter = 1;
+ d->out_counter = 0;
+ d->busy = false;
+
+ /* Initialise protocol */
+ dbgprintf ("Initializing binary mode\n");
+ return ALCABUS_WriteMessage (s, 0, 0, ALCATEL_CONNECT);
+}
+
+static GSM_Error ALCABUS_Terminate(GSM_StateMachine *s)
+{
+ /* Terminate protocol */
+ dbgprintf ("Closing binary mode\n");
+ return ALCABUS_WriteMessage (s, 0, 0, ALCATEL_DISCONNECT);
+}
+
+GSM_Protocol_Functions ALCABUSProtocol = {
+ ALCABUS_WriteMessage,
+ ALCABUS_StateMachine,
+ ALCABUS_Initialise,
+ ALCABUS_Terminate
+};
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/alcatel/alcabus.h b/gammu/emb/common/protocol/alcatel/alcabus.h
new file mode 100644
index 0000000..3b9b44e
--- a/dev/null
+++ b/gammu/emb/common/protocol/alcatel/alcabus.h
@@ -0,0 +1,61 @@
+/* (c) 2002-2003 by Michal Cihar */
+/*
+ * Low level functions for communication with Alcatel One Touch phones.
+ *
+ * This code implements the protocol used for synchronisation with PC.
+ */
+
+#ifndef alcabus_h
+#define alcabus_h
+
+#include "../protocol.h"
+
+#define ALCATEL_HEADER 0x7E
+
+/* packet types: */
+/* used for starting binary connection (must be preceeded by
+ * AT+CPROT=16,"V1.0",16 and phone should response to it by CONNECT_ACK)
+ */
+#define ALCATEL_CONNECT 0x0A
+/* received when connect suceeded */
+#define ALCATEL_CONNECT_ACK 0x0C
+/* used for stopping binary connection */
+#define ALCATEL_DISCONNECT 0x0D
+/* received when binnary connection ends */
+#define ALCATEL_DISCONNECT_ACK 0x0E
+/* some control ack, I really don't know what should it do, so currently it
+ * is just ignored. It comes time to time, and communication continues OK also
+ * if no reply was made. */
+#define ALCATEL_CONTROL 0x0F
+/* sending/recieving data */
+#define ALCATEL_DATA 0x02
+/* acknowledge to data */
+#define ALCATEL_ACK 0x06
+
+/* Maximal value for packet counter */
+#define ALCATEL_MAX_COUNTER 0x3D
+
+typedef struct {
+ GSM_Protocol_Message Msg;
+ /* Incoming packets ID counter */
+ int in_counter;
+ /* Outgoing packets ID counter */
+ int out_counter;
+ /* Expected size of incoming packet */
+ int expected_size;
+ /* What is type of frame we expect next */
+ unsigned char next_frame;
+ /* State of mobile, if we expect something (generally some ack) we set
+ * this to true and no other action can be performed until it is false. */
+ bool busy;
+} GSM_Protocol_ALCABUSData;
+
+#ifndef GSM_USED_SERIALDEVICE
+# define GSM_USED_SERIALDEVICE
+#endif
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/at/at.c b/gammu/emb/common/protocol/at/at.c
new file mode 100644
index 0000000..f4a75b7
--- a/dev/null
+++ b/gammu/emb/common/protocol/at/at.c
@@ -0,0 +1,229 @@
+/* (c) 2002-2004 by Marcin Wiacek and Michal Cihar */
+
+#include "../../gsmstate.h"
+
+#if defined(GSM_ENABLE_AT) || defined(GSM_ENABLE_BLUEAT) || defined(GSM_ENABLE_IRDAAT)
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../gsmcomon.h"
+#include "at.h"
+
+static GSM_Error AT_WriteMessage (GSM_StateMachine *s, unsigned char *buffer,
+ int length, unsigned char type)
+{
+ int i,sent = 0;
+
+ GSM_DumpMessageLevel2(s, buffer, length, type);
+ GSM_DumpMessageLevel3(s, buffer, length, type);
+ if (s->Protocol.Data.AT.FastWrite) {
+ while (sent != length) {
+ if ((i = s->Device.Functions->WriteDevice(s,buffer + sent, length - sent)) == 0) {
+ return ERR_DEVICEWRITEERROR;
+ }
+ sent += i;
+ }
+ } else {
+ for (i=0;i<length;i++) {
+ if (s->Device.Functions->WriteDevice(s,buffer+i,1)!=1) return ERR_DEVICEWRITEERROR;
+ /* For some phones like Siemens M20 we need to wait a little
+ * after writing each char. Possible reason: these phones
+ * can't receive so fast chars or there is bug here in Gammu */
+ my_sleep(1);
+ }
+ my_sleep(400);
+ }
+
+ return ERR_NONE;
+}
+
+typedef struct {
+ char *text;
+ int lines;
+} SpecialAnswersStruct;
+
+static GSM_Error AT_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
+{
+ GSM_Protocol_Message Msg2;
+ GSM_Protocol_ATData *d = &s->Protocol.Data.AT;
+ int i;
+
+ /* These are lines with end of "normal" answers */
+ static char *StartStrings[] = {
+ "OK" , "ERROR" ,
+ "+CME ERROR:" , "+CMS ERROR:" ,
+
+ "+CPIN: " , /*A2D issue*/
+
+ NULL};
+
+ /* Some info from phone can be inside "normal" answers
+ * It starts with strings written here
+ */
+ static SpecialAnswersStruct SpecialAnswers[] = {
+ {"_OSIGQ:" ,1}, {"_OBS:" ,1},
+ {"^SCN:" ,1}, {"+CGREG:" ,1},
+ {"+CBM:" ,1}, {"+CMT:" ,2},
+ {"+CMTI:" ,1}, {"+CDS:" ,2},
+ {"+CREG:" ,1},
+
+ {"RING" ,1}, {"NO CARRIER" ,1},
+ {"NO ANSWER" ,1}, {"+COLP" ,1},
+ {"+CLIP" ,1},
+
+ {NULL ,1}};
+
+ /* Ignore leading CR, LF and ESC */
+ if (d->Msg.Length == 0) {
+ if (rx_char == 10 || rx_char == 13 || rx_char == 27) return ERR_NONE;
+ d->LineStart = d->Msg.Length;
+ }
+
+ if (d->Msg.BufferUsed < d->Msg.Length + 2) {
+ d->Msg.BufferUsed = d->Msg.Length + 2;
+ d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
+ }
+ d->Msg.Buffer[d->Msg.Length++] = rx_char;
+ d->Msg.Buffer[d->Msg.Length ] = 0;
+
+ switch (rx_char) {
+ case 0:
+ break;
+ case 10:
+ case 13:
+ if (!d->wascrlf) d->LineEnd = d->Msg.Length-1;
+ d->wascrlf = true;
+ if (d->Msg.Length > 0 && rx_char == 10 && d->Msg.Buffer[d->Msg.Length-2]==13) {
+ i = 0;
+ while (StartStrings[i] != NULL) {
+ if (strncmp(StartStrings[i],d->Msg.Buffer+d->LineStart,strlen(StartStrings[i])) == 0) {
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
+ d->Msg.Length = 0;
+ break;
+ }
+ i++;
+ }
+ if (d->Msg.Length == 0) break;
+
+ i = 0;
+ while (SpecialAnswers[i].text != NULL) {
+ if (strncmp(SpecialAnswers[i].text,d->Msg.Buffer+d->LineStart,strlen(SpecialAnswers[i].text)) == 0) {
+ /* We need something better here */
+ if (s->Phone.Data.RequestID == ID_GetNetworkInfo && strncmp(SpecialAnswers[i].text,"+CREG:",6) == 0) {
+ i++;
+ continue;
+ }
+ d->SpecialAnswerStart = d->LineStart;
+ d->SpecialAnswerLines = SpecialAnswers[i].lines;
+ }
+ i++;
+ }
+
+
+ if (d->SpecialAnswerLines == 1) {
+ /* This is end of special answer. We copy it and send to phone module */
+ Msg2.Buffer = malloc(d->LineEnd - d->SpecialAnswerStart + 3);
+ memcpy(Msg2.Buffer,d->Msg.Buffer+d->SpecialAnswerStart,d->LineEnd - d->SpecialAnswerStart + 2);
+ Msg2.Length = d->LineEnd - d->SpecialAnswerStart + 2;
+ Msg2.Buffer[Msg2.Length] = 0;
+
+ s->Phone.Data.RequestMsg = &Msg2;
+ s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
+ free(Msg2.Buffer);
+
+ /* We cut special answer from main buffer */
+ d->Msg.Length = d->SpecialAnswerStart;
+ if (d->Msg.Length != 0) d->Msg.Length = d->Msg.Length - 2;
+
+ /* We need to find earlier values of all variables */
+ d->wascrlf = false;
+ d->LineStart = 0;
+ for (i=0;i<d->Msg.Length;i++) {
+ switch(d->Msg.Buffer[i]) {
+ case 0:
+ break;
+ case 10:
+ case 13:
+ if (!d->wascrlf) d->LineEnd = d->Msg.Length-1;
+ d->wascrlf = true;
+ break;
+ default:
+ if (d->wascrlf) {
+ d->LineStart = d->Msg.Length-1;
+ d->wascrlf = false;
+ }
+ }
+ }
+ d->Msg.Buffer[d->Msg.Length] = 0;
+ }
+ if (d->SpecialAnswerLines > 0) d->SpecialAnswerLines--;
+ }
+ break;
+ case 'T':
+ /* When CONNECT string received, we know there will not follow
+ * anything AT related, after CONNECT can follow ppp data, alcabus
+ * data and also other things.
+ */
+ if (strncmp(d->Msg.Buffer+d->LineStart, "CONNECT", 7) == 0) {
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
+ d->LineStart = -1;
+ d->Msg.Length = 0;
+ break;
+ }
+ default:
+ if (d->wascrlf) {
+ d->LineStart = d->Msg.Length-1;
+ d->wascrlf = false;
+ }
+ if (d->EditMode) {
+ if (strlen(d->Msg.Buffer+d->LineStart) == 2 && strncmp(d->Msg.Buffer+d->LineStart,"> ",2)==0) {
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
+ }
+ }
+ }
+ return ERR_NONE;
+}
+
+static GSM_Error AT_Initialise(GSM_StateMachine *s)
+{
+ GSM_Protocol_ATData *d = &s->Protocol.Data.AT;
+
+ d->Msg.Buffer = NULL;
+ d->Msg.BufferUsed = 0;
+ d->Msg.Length = 0;
+ d->Msg.Type = 0;
+
+ d->SpecialAnswerLines = 0;
+ d->LineStart = -1;
+ d->LineEnd = -1;
+ d->wascrlf = false;
+ d->EditMode = false;
+ d->FastWrite = false;
+
+ s->Device.Functions->DeviceSetDtrRts(s,true,true);
+
+ return s->Device.Functions->DeviceSetSpeed(s,s->Speed);
+}
+
+static GSM_Error AT_Terminate(GSM_StateMachine *s)
+{
+ free(s->Protocol.Data.AT.Msg.Buffer);
+ return ERR_NONE;
+}
+
+GSM_Protocol_Functions ATProtocol = {
+ AT_WriteMessage,
+ AT_StateMachine,
+ AT_Initialise,
+ AT_Terminate
+};
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/at/at.h b/gammu/emb/common/protocol/at/at.h
new file mode 100644
index 0000000..e200646
--- a/dev/null
+++ b/gammu/emb/common/protocol/at/at.h
@@ -0,0 +1,36 @@
+/* (c) 2002-2003 by Marcin Wiacek and Michal Cihar */
+
+#ifndef at_h
+#define at_h
+
+#include "../protocol.h"
+
+typedef struct {
+ GSM_Protocol_Message Msg;
+ bool wascrlf;
+ int LineStart,LineEnd;
+ int SpecialAnswerLines,SpecialAnswerStart;
+
+ bool EditMode; /* wait for modem answer or not */
+ bool FastWrite;
+} GSM_Protocol_ATData;
+
+#ifndef GSM_USED_SERIALDEVICE
+# define GSM_USED_SERIALDEVICE
+#endif
+#if defined(GSM_ENABLE_BLUEAT)
+# ifndef GSM_USED_BLUETOOTHDEVICE
+# define GSM_USED_BLUETOOTHDEVICE
+# endif
+#endif
+#if defined(GSM_ENABLE_IRDAAT)
+# ifndef GSM_USED_IRDADEVICE
+# define GSM_USED_IRDADEVICE
+# endif
+#endif
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/nokia/fbus2.c b/gammu/emb/common/protocol/nokia/fbus2.c
new file mode 100644
index 0000000..8b3e024
--- a/dev/null
+++ b/gammu/emb/common/protocol/nokia/fbus2.c
@@ -0,0 +1,444 @@
+/* (c) 2002-2003 by Marcin Wiacek */
+/* based on some work from Gnokii and MyGnokii */
+
+#include "../../gsmstate.h"
+
+#if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303)
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../gsmcomon.h"
+#include "fbus2.h"
+
+static GSM_Error FBUS2_WriteFrame(GSM_StateMachine *s,
+ unsigned char *MsgBuffer,
+ int MsgLength,
+ unsigned char MsgType)
+{
+ unsigned char buffer2[FBUS2_MAX_TRANSMIT_LENGTH + 10];
+ unsigned char checksum=0;
+ int i, len, sent;
+
+ buffer2[0] = FBUS2_FRAME_ID;
+ if (s->ConnectionType==GCT_FBUS2IRDA) buffer2[0] = FBUS2_IRDA_FRAME_ID;
+
+ buffer2[1] = FBUS2_DEVICE_PHONE; //destination
+ buffer2[2] = FBUS2_DEVICE_PC; //source
+ buffer2[3] = MsgType;
+ buffer2[4] = MsgLength / 256;
+ buffer2[5] = MsgLength % 256;
+
+ memcpy(buffer2 + 6, MsgBuffer, MsgLength);
+ len = MsgLength + 6;
+
+ /* Odd messages require additional 0x00 byte */
+ if (MsgLength % 2) buffer2[len++] = 0x00;
+
+ checksum = 0;
+ for (i = 0; i < len; i+=2) checksum ^= buffer2[i];
+ buffer2[len++] = checksum;
+
+ checksum = 0;
+ for (i = 1; i < len; i+=2) checksum ^= buffer2[i];
+ buffer2[len++] = checksum;
+
+ /* Sending to phone */
+ sent=s->Device.Functions->WriteDevice(s,buffer2,len);
+ if (sent!=len) return ERR_DEVICEWRITEERROR;
+
+ return ERR_NONE;
+}
+
+static GSM_Error FBUS2_WriteMessage (GSM_StateMachine *s,
+ unsigned char *MsgBuffer,
+ int MsgLength,
+ unsigned char MsgType)
+{
+ int i, nom, togo, thislength; /* number of messages, ... */
+ unsigned char buffer2[FBUS2_MAX_TRANSMIT_LENGTH + 2], seqnum;
+ GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2;
+ GSM_Error error;
+
+ GSM_DumpMessageLevel3(s, MsgBuffer, MsgLength, MsgType);
+
+ nom = (MsgLength + FBUS2_MAX_TRANSMIT_LENGTH - 1) / FBUS2_MAX_TRANSMIT_LENGTH;
+ togo = MsgLength;
+
+ for (i = 0; i < nom; i++) {
+ seqnum = d->MsgSequenceNumber;
+ if (i==0) seqnum = seqnum + 0x40;
+ d->MsgSequenceNumber = (d->MsgSequenceNumber + 1) & 0x07;
+
+ thislength = togo;
+ if (togo > FBUS2_MAX_TRANSMIT_LENGTH) thislength = FBUS2_MAX_TRANSMIT_LENGTH;
+ memcpy(buffer2, MsgBuffer + (MsgLength - togo), thislength);
+ buffer2[thislength] = nom - i;
+ buffer2[thislength + 1] = seqnum;
+ togo = togo - thislength;
+
+ GSM_DumpMessageLevel2(s, buffer2, thislength, MsgType);
+
+ error=FBUS2_WriteFrame(s, buffer2, thislength + 2, MsgType);
+ if (error!=ERR_NONE) return error;
+ }
+
+ return ERR_NONE;
+}
+
+static GSM_Error FBUS2_SendAck(GSM_StateMachine *s,
+ unsigned char MsgType,
+ unsigned char MsgSequence)
+{
+ unsigned char buffer2[2];
+
+ buffer2[0] = MsgType;
+ buffer2[1] = MsgSequence;
+
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
+ smprintf(s,"[Sending Ack of type %02x, seq %x]\n",buffer2[0],buffer2[1]);
+ }
+
+ /* Sending to phone */
+ return FBUS2_WriteFrame(s, buffer2, 2, FBUS2_ACK_BYTE);
+}
+
+static GSM_Error FBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
+{
+ GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2;
+ unsigned char frm_num, seq_num;
+ bool correct = false;
+
+ /* XOR the byte with the earlier checksum */
+ d->Msg.CheckSum[d->Msg.Count & 1] ^= rx_char;
+
+ if (d->MsgRXState == RX_GetMessage) {
+ d->Msg.Buffer[d->Msg.Count] = rx_char;
+ d->Msg.Count++;
+
+ /* This is not last byte in frame */
+ if (d->Msg.Count != d->Msg.Length+(d->Msg.Length%2)+2) return ERR_NONE;
+
+ /* Checksum is incorrect */
+ if (d->Msg.CheckSum[0] != d->Msg.CheckSum[1]) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: checksum]\n");
+ }
+ free(d->Msg.Buffer);
+ d->Msg.Length = 0;
+ d->Msg.Buffer = NULL;
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+
+ seq_num = d->Msg.Buffer[d->Msg.Length-1];
+
+ if (d->Msg.Type == FBUS2_ACK_BYTE) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
+ smprintf(s, "[Received Ack of type %02x, seq %02x]\n",d->Msg.Buffer[0],seq_num);
+ }
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+
+ frm_num = d->Msg.Buffer[d->Msg.Length-2];
+
+ if ((seq_num & 0x40) == 0x40) {
+ d->FramesToGo = frm_num;
+ d->MultiMsg.Length = 0;
+ d->MultiMsg.Type = d->Msg.Type;
+ d->MultiMsg.Destination = d->Msg.Destination;
+ d->MultiMsg.Source = d->Msg.Source;
+ }
+
+ if ((seq_num & 0x40) != 0x40 && d->FramesToGo != frm_num) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s, "[ERROR: Missed part of multiframe msg]\n");
+ }
+
+ free(d->Msg.Buffer);
+ d->Msg.Length = 0;
+ d->Msg.Buffer = NULL;
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+
+ if ((seq_num & 0x40) != 0x40 && d->Msg.Type != d->MultiMsg.Type) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s, "[ERROR: Multiframe msg in multiframe msg]\n");
+ }
+
+ free(d->Msg.Buffer);
+ d->Msg.Length = 0;
+ d->Msg.Buffer = NULL;
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+
+ if (d->MultiMsg.BufferUsed < d->MultiMsg.Length+d->Msg.Length-2) {
+ d->MultiMsg.BufferUsed = d->MultiMsg.Length+d->Msg.Length-2;
+ d->MultiMsg.Buffer = (unsigned char *)realloc(d->MultiMsg.Buffer,d->MultiMsg.BufferUsed);
+ }
+ memcpy(d->MultiMsg.Buffer+d->MultiMsg.Length,d->Msg.Buffer,d->Msg.Length-2);
+ d->MultiMsg.Length = d->MultiMsg.Length+d->Msg.Length-2;
+
+ free(d->Msg.Buffer);
+ d->Msg.Length = 0;
+ d->Msg.Buffer = NULL;
+
+ d->FramesToGo--;
+
+ /* do not ack debug trace, as this could generate a
+ * (feedback loop) flood of which even Noah would be scared.
+ */
+ if (d->Msg.Type != 0) {
+ FBUS2_SendAck(s,d->Msg.Type,((unsigned char)(seq_num & 0x0f)));
+ }
+
+ if (d->FramesToGo == 0) {
+ s->Phone.Data.RequestMsg = &d->MultiMsg;
+ s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
+ }
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetLength2) {
+ d->Msg.Length = d->Msg.Length + rx_char;
+ d->Msg.Buffer = (unsigned char *)malloc(d->Msg.Length+3);
+ d->MsgRXState = RX_GetMessage;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetLength1) {
+ d->Msg.Length = rx_char * 256;
+ d->MsgRXState = RX_GetLength2;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetType) {
+ d->Msg.Type = rx_char;
+ d->MsgRXState = RX_GetLength1;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetSource) {
+ if (rx_char != FBUS2_DEVICE_PHONE) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_DEVICE_PHONE);
+ }
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ d->Msg.Source = rx_char;
+
+ d->MsgRXState = RX_GetType;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetDestination) {
+ if (rx_char != FBUS2_DEVICE_PC) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_DEVICE_PC);
+ }
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ d->Msg.Destination = rx_char;
+
+ d->MsgRXState = RX_GetSource;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_Sync) {
+ switch (s->ConnectionType) {
+ case GCT_FBUS2:
+ case GCT_FBUS2DLR3:
+ case GCT_FBUS2DKU5:
+ case GCT_FBUS2PL2303:
+ case GCT_FBUS2BLUE:
+ case GCT_BLUEFBUS2:
+ if (rx_char == FBUS2_FRAME_ID) correct = true;
+ break;
+ case GCT_FBUS2IRDA:
+ if (rx_char == FBUS2_IRDA_FRAME_ID) correct = true;
+ break;
+ default:
+ break;
+ }
+ if (!correct) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ if (s->ConnectionType==GCT_FBUS2IRDA) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_IRDA_FRAME_ID);
+ } else {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_FRAME_ID);
+ }
+ }
+ return ERR_NONE;
+ }
+
+ d->Msg.CheckSum[0] = rx_char;
+ d->Msg.CheckSum[1] = 0;
+ d->Msg.Count = 0;
+
+ d->MsgRXState = RX_GetDestination;
+ return ERR_NONE;
+ }
+ return ERR_NONE;
+}
+
+#if defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2PL2303)
+static void FBUS2_WriteDLR3(GSM_StateMachine *s, char *command, int length, int timeout)
+{
+ unsigned char buff[300];
+ int w = 0;
+ bool wassomething = false;
+
+ s->Device.Functions->WriteDevice(s,command,length);
+
+ for (w=0;w<timeout;w++) {
+ if (wassomething) {
+ if (s->Device.Functions->ReadDevice(s, buff, 255)==0) return;
+ } else {
+ if (s->Device.Functions->ReadDevice(s, buff, 255)>0) wassomething = true;
+ }
+ my_sleep(50);
+ }
+}
+#endif
+
+static GSM_Error FBUS2_Initialise(GSM_StateMachine *s)
+{
+ unsigned char init_char = 0x55;
+#ifdef GSM_ENABLE_FBUS2IRDA
+ unsigned char end_init_char = 0xc1;
+#endif
+
+ GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2;
+ GSM_Device_Functions *Device = s->Device.Functions;
+ GSM_Error error;
+ int count;
+
+ d->Msg.Length = 0;
+ d->Msg.Buffer = NULL;
+ d->MultiMsg.BufferUsed = 0;
+ d->MultiMsg.Length = 0;
+ d->MultiMsg.Buffer = NULL;
+
+ d->MsgSequenceNumber = 0;
+ d->FramesToGo = 0;
+ d->MsgRXState = RX_Sync;
+
+ error=Device->DeviceSetParity(s,false);
+ if (error!=ERR_NONE) return error;
+
+ switch (s->ConnectionType) {
+#if defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2BLUE)
+ case GCT_FBUS2BLUE:
+ case GCT_BLUEFBUS2:
+ FBUS2_WriteDLR3(s,"AT\r\n", 4,10);
+ FBUS2_WriteDLR3(s,"AT&F\r\n", 6,10);
+ FBUS2_WriteDLR3(s,"AT*NOKIAFBUS\r\n", 14,10);
+ break;
+#endif
+#if defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303)
+ case GCT_FBUS2DKU5:
+ case GCT_FBUS2PL2303:
+ case GCT_FBUS2DLR3:
+ error=Device->DeviceSetDtrRts(s,false,false);
+ if (error!=ERR_NONE) return error;
+ my_sleep(1000);
+
+ error=Device->DeviceSetDtrRts(s,true,true);
+ if (error!=ERR_NONE) return error;
+ error=Device->DeviceSetSpeed(s,19200);
+ if (error!=ERR_NONE) return error;
+
+ FBUS2_WriteDLR3(s,"AT\r\n", 4,10);
+ FBUS2_WriteDLR3(s,"AT&F\r\n", 6,10);
+ FBUS2_WriteDLR3(s,"AT*NOKIAFBUS\r\n", 14,10);
+
+ error=Device->CloseDevice(s);
+ if (error!=ERR_NONE) return error;
+ my_sleep(1000);
+
+ error=Device->OpenDevice(s);
+ if (error!=ERR_NONE) return error;
+ error=Device->DeviceSetParity(s,false);
+ if (error!=ERR_NONE) return error;
+ error=Device->DeviceSetSpeed(s,115200);
+ if (error!=ERR_NONE) return error;
+ error=Device->DeviceSetDtrRts(s,false,false);
+ if (error!=ERR_NONE) return error;
+
+ for (count = 0; count < 55; count ++) {
+ if (Device->WriteDevice(s,&init_char,1)!=1) return ERR_DEVICEWRITEERROR;
+ }
+ break;
+#endif
+ case GCT_FBUS2:
+ error=Device->DeviceSetSpeed(s,115200);
+ if (error!=ERR_NONE) return error;
+
+ error=Device->DeviceSetDtrRts(s,true,false); /*DTR high,RTS low*/
+ if (error!=ERR_NONE) return error;
+
+ for (count = 0; count < 55; count ++) {
+ if (Device->WriteDevice(s,&init_char,1)!=1) return ERR_DEVICEWRITEERROR;
+ my_sleep(10);
+ }
+ break;
+#ifdef GSM_ENABLE_FBUS2IRDA
+ case GCT_FBUS2IRDA:
+ error=Device->DeviceSetSpeed(s,9600);
+ if (error!=ERR_NONE) return error;
+
+ for (count = 0; count < 55; count ++) {
+ if (Device->WriteDevice(s,&init_char,1)!=1) return ERR_DEVICEWRITEERROR;
+ my_sleep(10);
+ }
+
+ if (Device->WriteDevice(s,&end_init_char,1)!=1) return ERR_DEVICEWRITEERROR;
+ my_sleep(20);
+
+ error=Device->DeviceSetSpeed(s,115200);
+ if (error!=ERR_NONE) return error;
+
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return ERR_NONE;
+}
+
+static GSM_Error FBUS2_Terminate(GSM_StateMachine *s)
+{
+ free(s->Protocol.Data.FBUS2.Msg.Buffer);
+ free(s->Protocol.Data.FBUS2.MultiMsg.Buffer);
+
+ my_sleep(200);
+ return ERR_NONE;
+}
+
+GSM_Protocol_Functions FBUS2Protocol = {
+ FBUS2_WriteMessage,
+ FBUS2_StateMachine,
+ FBUS2_Initialise,
+ FBUS2_Terminate
+};
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/nokia/fbus2.h b/gammu/emb/common/protocol/nokia/fbus2.h
new file mode 100644
index 0000000..5dd45d7
--- a/dev/null
+++ b/gammu/emb/common/protocol/nokia/fbus2.h
@@ -0,0 +1,38 @@
+/* (c) 2002-2003 by Marcin Wiacek */
+/* based on some work from Gnokii and MyGnokii */
+
+#ifndef fbus2_h
+#define fbus2_h
+
+#include "../protocol.h"
+
+#define FBUS2_FRAME_ID 0x1e
+#define FBUS2_IRDA_FRAME_ID 0x1c
+#define FBUS2_DEVICE_PHONE 0x00 /* Nokia mobile phone */
+#define FBUS2_DEVICE_PC 0x0c /* Our PC */
+#define FBUS2_ACK_BYTE 0x7f /* Acknowledge of the received frame */
+
+#define FBUS2_MAX_TRANSMIT_LENGTH 120
+
+typedef struct {
+ int MsgSequenceNumber;
+ int MsgRXState;
+ int FramesToGo;
+ GSM_Protocol_Message MultiMsg;
+ GSM_Protocol_Message Msg;
+} GSM_Protocol_FBUS2Data;
+
+#ifndef GSM_USED_SERIALDEVICE
+# define GSM_USED_SERIALDEVICE
+#endif
+#if defined(GSM_ENABLE_BLUEFBUS2)
+# ifndef GSM_USED_BLUETOOTHDEVICE
+# define GSM_USED_BLUETOOTHDEVICE
+# endif
+#endif
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/nokia/mbus2.c b/gammu/emb/common/protocol/nokia/mbus2.c
new file mode 100644
index 0000000..f07d6c5
--- a/dev/null
+++ b/gammu/emb/common/protocol/nokia/mbus2.c
@@ -0,0 +1,252 @@
+/* (c) 2001-2003 by Marcin Wiacek */
+/* based on some work from MyGnokii */
+
+#include "../../gsmstate.h"
+
+#ifdef GSM_ENABLE_MBUS2
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../gsmcomon.h"
+#include "mbus2.h"
+
+static GSM_Error MBUS2_WriteMessage (GSM_StateMachine *s,
+ unsigned char *MsgBuffer,
+ int MsgLength,
+ unsigned char MsgType)
+{
+ unsigned char *buffer2, checksum = 0;
+ GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
+ int i, sent, len;
+
+ GSM_DumpMessageLevel3(s, MsgBuffer, MsgLength, MsgType);
+
+ buffer2 = (unsigned char *)malloc(MsgLength + 8);
+
+ buffer2[0] = MBUS2_FRAME_ID;
+ buffer2[1] = MBUS2_DEVICE_PHONE; // destination
+ buffer2[2] = MBUS2_DEVICE_PC; // source
+ buffer2[3] = MsgType;
+ buffer2[4] = MsgLength / 256;
+ buffer2[5] = MsgLength % 256;
+
+ memcpy(buffer2 + 6, MsgBuffer, MsgLength);
+ len = 6 + MsgLength;
+
+ /* According to http://www.flosys.com/tdma/n5160.html some phones
+ * can have problems with checksum equal 0x1F. Phones can recognize
+ * received frame, but won't send ACK for it. When checksum is 0x1F,
+ * we increment the sequence number
+ */
+ do {
+ d->MsgSequenceNumber++;
+
+ buffer2[len] = d->MsgSequenceNumber;
+
+ /* Calculating checksum */
+ checksum = 0;
+ for (i = 0; i < len + 1; i++) checksum ^= buffer2[i];
+ } while (checksum == 0x1f);
+
+ buffer2[len++] = d->MsgSequenceNumber;
+ buffer2[len++] = checksum;
+
+ GSM_DumpMessageLevel2(s, buffer2+6, MsgLength, MsgType);
+
+ /* Sending to phone */
+ my_sleep(10);
+ sent=s->Device.Functions->WriteDevice(s,buffer2,len);
+
+ free(buffer2);
+
+ if (sent!=len) return ERR_DEVICEWRITEERROR;
+ return ERR_NONE;
+}
+
+static GSM_Error MBUS2_SendAck(GSM_StateMachine *s,
+ unsigned char type,
+ unsigned char sequence)
+{
+ GSM_Device_Functions *Device = s->Device.Functions;
+ unsigned char buffer2[6];
+ int i;
+
+ buffer2[0] = MBUS2_FRAME_ID;
+ buffer2[1] = MBUS2_DEVICE_PHONE; //destination
+ buffer2[2] = MBUS2_DEVICE_PC; //source
+ buffer2[3] = MBUS2_ACK_BYTE;
+ buffer2[4] = sequence;
+ buffer2[5] = 0;
+
+ /* Calculating checksum */
+ for (i = 0; i < 5; i++) buffer2[5] ^= buffer2[i];
+
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
+ smprintf(s,"[Sending Ack of type %02x, seq: %x]\n",type,sequence);
+ }
+
+ /* Sending to phone */
+ my_sleep(10);
+ if (Device->WriteDevice(s,buffer2,6)!=6) return ERR_DEVICEWRITEERROR;
+
+ return ERR_NONE;
+}
+
+static GSM_Error MBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
+{
+ GSM_Phone_Functions *Phone = s->Phone.Functions;
+ GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
+
+ d->Msg.CheckSum[0] = d->Msg.CheckSum[1];
+ d->Msg.CheckSum[1] ^= rx_char;
+
+ if (d->MsgRXState == RX_GetMessage) {
+ d->Msg.Buffer[d->Msg.Count] = rx_char;
+ d->Msg.Count++;
+
+ /* This is not last byte in frame */
+ if (d->Msg.Count != d->Msg.Length+2) return ERR_NONE;
+
+ /* Checksum is incorrect */
+ if (d->Msg.CheckSum[0] != rx_char) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: checksum]\n");
+ }
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+
+ if (d->Msg.Destination != MBUS2_DEVICE_PHONE) {
+ MBUS2_SendAck(s, d->Msg.Type, d->Msg.Buffer[d->Msg.Count-2]);
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = Phone->DispatchMessage(s);
+ }
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetLength2) {
+ if (d->Msg.Type == MBUS2_ACK_BYTE) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) {
+ smprintf(s,"[Received Ack]\n");
+ }
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+
+ d->Msg.Length = d->Msg.Length + rx_char;
+ if (d->Msg.BufferUsed < d->Msg.Length+2) {
+ d->Msg.BufferUsed = d->Msg.Length+2;
+ d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
+ }
+
+ d->MsgRXState = RX_GetMessage;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetLength1) {
+ d->Msg.Length = rx_char * 256;
+
+ d->MsgRXState = RX_GetLength2;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetType) {
+ d->Msg.Type = rx_char;
+
+ d->MsgRXState = RX_GetLength1;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetSource) {
+ if (rx_char != MBUS2_DEVICE_PHONE && rx_char != MBUS2_DEVICE_PC) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x and %02x]\n", rx_char, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC);
+ }
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ d->Msg.Source = rx_char;
+
+ d->MsgRXState = RX_GetType;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_GetDestination) {
+ if (rx_char != MBUS2_DEVICE_PC && rx_char != MBUS2_DEVICE_PHONE) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x and %02x]\n", rx_char, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC);
+ }
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ d->Msg.Destination = rx_char;
+
+ d->MsgRXState = RX_GetSource;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState == RX_Sync) {
+ if (rx_char != MBUS2_FRAME_ID) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, MBUS2_FRAME_ID);
+ }
+ return ERR_NONE;
+ }
+ d->Msg.CheckSum[1] = MBUS2_FRAME_ID;
+ d->Msg.Count = 0;
+
+ d->MsgRXState = RX_GetDestination;
+ return ERR_NONE;
+ }
+ return ERR_NONE;
+}
+
+static GSM_Error MBUS2_Initialise(GSM_StateMachine *s)
+{
+ GSM_Device_Functions *Device = s->Device.Functions;
+ GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2;
+ GSM_Error error;
+
+ d->Msg.Length = 0;
+ d->Msg.BufferUsed = 0;
+ d->Msg.Buffer = NULL;
+
+ d->MsgSequenceNumber = 0;
+ d->MsgRXState = RX_Sync;
+
+ error=Device->DeviceSetSpeed(s,9600);
+ if (error!=ERR_NONE) return error;
+
+ error=Device->DeviceSetParity(s,true);
+ if (error!=ERR_NONE) return error;
+
+ error=Device->DeviceSetDtrRts(s,false,true); /*DTR low,RTS high*/
+ if (error!=ERR_NONE) return error;
+ my_sleep(200);
+
+ return ERR_NONE;
+}
+
+static GSM_Error MBUS2_Terminate(GSM_StateMachine *s)
+{
+ free(s->Protocol.Data.MBUS2.Msg.Buffer);
+ return ERR_NONE;
+}
+
+GSM_Protocol_Functions MBUS2Protocol = {
+ MBUS2_WriteMessage,
+ MBUS2_StateMachine,
+ MBUS2_Initialise,
+ MBUS2_Terminate
+};
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/nokia/mbus2.h b/gammu/emb/common/protocol/nokia/mbus2.h
new file mode 100644
index 0000000..86fcab6
--- a/dev/null
+++ b/gammu/emb/common/protocol/nokia/mbus2.h
@@ -0,0 +1,28 @@
+/* (c) 2001-2003 by Marcin Wiacek */
+/* based on some work from MyGnokii */
+
+#ifndef mbus2_h
+#define mbus2_h
+
+#include "../protocol.h"
+
+#define MBUS2_FRAME_ID 0x1f
+#define MBUS2_DEVICE_PHONE 0x00 /* Nokia mobile phone */
+#define MBUS2_DEVICE_PC 0x10 /* Our PC (MBUS) */
+#define MBUS2_ACK_BYTE 0x7f /* Acknowledge of the received frame */
+
+typedef struct {
+ int MsgSequenceNumber;
+ int MsgRXState;
+ GSM_Protocol_Message Msg;
+} GSM_Protocol_MBUS2Data;
+
+#ifndef GSM_USED_SERIALDEVICE
+# define GSM_USED_SERIALDEVICE
+#endif
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/nokia/phonet.c b/gammu/emb/common/protocol/nokia/phonet.c
new file mode 100644
index 0000000..bc5717d
--- a/dev/null
+++ b/gammu/emb/common/protocol/nokia/phonet.c
@@ -0,0 +1,217 @@
+/* (c) 2002-2003 by Marcin Wiacek */
+/* based on some work from Gnokii */
+
+#include "../../gsmstate.h"
+
+#if defined(GSM_ENABLE_IRDA) || defined(GSM_ENABLE_PHONETBLUE) || defined(GSM_ENABLE_BLUEPHONET)
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../gsmcomon.h"
+#include "phonet.h"
+
+static GSM_Error PHONET_WriteMessage (GSM_StateMachine *s,
+ unsigned char *MsgBuffer,
+ int MsgLength,
+ unsigned char MsgType)
+{
+ unsigned char *buffer2;
+ int sent;
+
+ GSM_DumpMessageLevel3(s, MsgBuffer, MsgLength, MsgType);
+
+ buffer2 = (unsigned char *)malloc(MsgLength + 6);
+
+ buffer2[0] = PHONET_FRAME_ID,
+ buffer2[1] = PHONET_DEVICE_PHONE; //destination
+ buffer2[2] = PHONET_DEVICE_PC; //source
+
+ if (s->ConnectionType==GCT_PHONETBLUE || s->ConnectionType==GCT_BLUEPHONET) {
+ buffer2[0] = PHONET_BLUE_FRAME_ID;
+ buffer2[1] = PHONET_DEVICE_PHONE; //destination
+ buffer2[2] = PHONET_BLUE_DEVICE_PC; //source
+ }
+
+ buffer2[3] = MsgType;
+ buffer2[4] = MsgLength / 256;
+ buffer2[5] = MsgLength % 256;
+
+ memcpy(buffer2 + 6, MsgBuffer, MsgLength);
+
+ GSM_DumpMessageLevel2(s, buffer2+6, MsgLength, MsgType);
+
+ /* Sending to phone */
+ sent = s->Device.Functions->WriteDevice(s,buffer2,MsgLength+6);
+
+ free(buffer2);
+
+ if (sent!=MsgLength+6) return ERR_DEVICEWRITEERROR;
+ return ERR_NONE;
+}
+
+static GSM_Error PHONET_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
+{
+ GSM_Protocol_PHONETData *d = &s->Protocol.Data.PHONET;
+ bool correct = false;
+
+ if (d->MsgRXState==RX_GetMessage) {
+ d->Msg.Buffer[d->Msg.Count] = rx_char;
+ d->Msg.Count++;
+
+ /* This is not last byte in frame */
+ if (d->Msg.Count != d->Msg.Length) return ERR_NONE;
+
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
+
+ free(d->Msg.Buffer);
+ d->Msg.Length = 0;
+ d->Msg.Buffer = NULL;
+
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState==RX_GetLength2) {
+ d->Msg.Length = d->Msg.Length + rx_char;
+ d->Msg.Buffer = (unsigned char *)malloc(d->Msg.Length);
+
+ d->MsgRXState = RX_GetMessage;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState==RX_GetLength1) {
+ d->Msg.Length = rx_char * 256;
+
+ d->MsgRXState = RX_GetLength2;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState==RX_GetType) {
+ d->Msg.Type = rx_char;
+
+ d->MsgRXState = RX_GetLength1;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState==RX_GetSource) {
+ if (rx_char != PHONET_DEVICE_PHONE) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, PHONET_DEVICE_PHONE);
+ }
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ d->Msg.Source = rx_char;
+
+ d->MsgRXState = RX_GetType;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState==RX_GetDestination) {
+ switch (s->ConnectionType) {
+ case GCT_IRDAPHONET:
+ if (rx_char == PHONET_DEVICE_PC) correct = true;
+ break;
+ case GCT_PHONETBLUE:
+ case GCT_BLUEPHONET:
+ if (rx_char == PHONET_BLUE_DEVICE_PC) correct = true;
+ break;
+ default:
+ break;
+ }
+ if (!correct) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, PHONET_DEVICE_PC);
+ }
+ d->MsgRXState = RX_Sync;
+ return ERR_NONE;
+ }
+ d->Msg.Destination = rx_char;
+
+ d->MsgRXState = RX_GetSource;
+ return ERR_NONE;
+ }
+ if (d->MsgRXState==RX_Sync) {
+ switch (s->ConnectionType) {
+ case GCT_IRDAPHONET:
+ if (rx_char == PHONET_FRAME_ID) correct = true;
+ break;
+ case GCT_PHONETBLUE:
+ case GCT_BLUEPHONET:
+ if (rx_char == PHONET_BLUE_FRAME_ID) correct = true;
+ break;
+ default:
+ break;
+ }
+ if (!correct) {
+ if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
+ s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
+ smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, PHONET_FRAME_ID);
+ }
+ return ERR_NONE;
+ }
+ d->Msg.Count = 0;
+
+ d->MsgRXState = RX_GetDestination;
+ return ERR_NONE;
+ }
+ return ERR_NONE;
+}
+
+static GSM_Error PHONET_Initialise(GSM_StateMachine *s)
+{
+ int total = 0, i, n;
+ GSM_Protocol_PHONETData *d = &s->Protocol.Data.PHONET;
+ unsigned char req[50];
+
+ d->Msg.Length = 0;
+ d->Msg.Buffer = NULL;
+ d->MsgRXState = RX_Sync;
+
+ if (s->ConnectionType == GCT_PHONETBLUE || s->ConnectionType == GCT_BLUEPHONET) {
+ /* Send frame in PHONET style */
+ req[0] = PHONET_BLUE_FRAME_ID; req[1] = PHONET_DEVICE_PHONE;
+ req[2] = PHONET_BLUE_DEVICE_PC; req[3] = 0xD0;
+ req[4] = 0x00; req[5] = 0x01;
+ req[6] = 0x04;
+ if (s->Device.Functions->WriteDevice(s,req,7) != 7) return ERR_DEVICEWRITEERROR;
+
+ while (total < 7) {
+ n = s->Device.Functions->ReadDevice(s, req + total, 50 - total);
+ total += n;
+ }
+
+ /* Answer frame in PHONET style */
+ req[10] = PHONET_BLUE_FRAME_ID; req[11] = PHONET_BLUE_DEVICE_PC;
+ req[12] = PHONET_DEVICE_PHONE; req[13] = 0xD0;
+ req[14] = 0x00; req[15] = 0x01;
+ req[16] = 0x05;
+
+ for (i = 0; i < 7; i++) {
+ if (req[i] != req[10+i]) {
+ smprintf(s,"Incorrect byte in the answer\n");
+ return ERR_UNKNOWN;
+ }
+ }
+ }
+
+ return ERR_NONE;
+}
+
+static GSM_Error PHONET_Terminate(GSM_StateMachine *s)
+{
+ free(s->Protocol.Data.PHONET.Msg.Buffer);
+ return ERR_NONE;
+}
+
+GSM_Protocol_Functions PHONETProtocol = {
+ PHONET_WriteMessage,
+ PHONET_StateMachine,
+ PHONET_Initialise,
+ PHONET_Terminate
+};
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/nokia/phonet.h b/gammu/emb/common/protocol/nokia/phonet.h
new file mode 100644
index 0000000..2f6e836
--- a/dev/null
+++ b/gammu/emb/common/protocol/nokia/phonet.h
@@ -0,0 +1,35 @@
+/* (c) 2002-2003 by Marcin Wiacek */
+/* based on some work from Gnokii */
+
+#ifndef PHONET_h
+#define PHONET_h
+
+#include "../protocol.h"
+
+#define PHONET_FRAME_ID 0x14
+#define PHONET_BLUE_FRAME_ID 0x19
+#define PHONET_DEVICE_PHONE 0x00 /* Nokia mobile phone */
+#define PHONET_DEVICE_PC 0x0c /* Our PC */
+#define PHONET_BLUE_DEVICE_PC 0x10 /* Our PC */
+
+typedef struct {
+ int MsgRXState;
+ GSM_Protocol_Message Msg;
+} GSM_Protocol_PHONETData;
+
+#if defined(GSM_ENABLE_IRDAPHONET)
+# ifndef GSM_USED_IRDADEVICE
+# define GSM_USED_IRDADEVICE
+# endif
+#endif
+#if defined(GSM_ENABLE_BLUEPHONET)
+# ifndef GSM_USED_BLUETOOTHDEVICE
+# define GSM_USED_BLUETOOTHDEVICE
+# endif
+#endif
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/obex/obex.c b/gammu/emb/common/protocol/obex/obex.c
new file mode 100644
index 0000000..942c084
--- a/dev/null
+++ b/gammu/emb/common/protocol/obex/obex.c
@@ -0,0 +1,120 @@
+/* (c) 2003 by Marcin Wiacek */
+/* www.irda.org OBEX specs 1.3 */
+
+#include "../../gsmstate.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+
+#include "../../gsmcomon.h"
+#include "obex.h"
+
+static GSM_Error OBEX_WriteMessage (GSM_StateMachine *s, unsigned char *buffer,
+ int length, unsigned char type)
+{
+ unsigned char *out_buffer;
+ int current=0,sent;
+
+ out_buffer = (unsigned char *)malloc(length + 3);
+
+ OBEXAddBlock(out_buffer, &current, type, buffer, length);
+
+ GSM_DumpMessageLevel2(s, out_buffer+3, length, type);
+ GSM_DumpMessageLevel3(s, out_buffer+3, length, type);
+
+ /* Send it out... */
+ sent = s->Device.Functions->WriteDevice(s,out_buffer,current);
+
+ free(out_buffer);
+
+ if (sent!=current) return ERR_DEVICEWRITEERROR;
+ return ERR_NONE;
+}
+
+static GSM_Error OBEX_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
+{
+ GSM_Phone_Functions *Phone = s->Phone.Functions;
+ GSM_Protocol_OBEXData *d = &s->Protocol.Data.OBEX;
+
+ switch (d->MsgRXState) {
+ case RX_Sync:
+ d->Msg.Type = rx_char;
+ d->MsgRXState = RX_GetLength1;
+ break;
+ case RX_GetLength1:
+ d->Msg.Length = rx_char * 256;
+ d->MsgRXState = RX_GetLength2;
+ break;
+ case RX_GetLength2:
+ d->Msg.Length = d->Msg.Length + rx_char - 3;
+ d->Msg.Count = 0;
+ if (d->Msg.Count == d->Msg.Length) {
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = Phone->DispatchMessage(s);
+ d->MsgRXState = RX_Sync;
+ } else {
+ if (d->Msg.BufferUsed < d->Msg.Length) {
+ d->Msg.BufferUsed = d->Msg.Length;
+ d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
+ }
+ d->MsgRXState = RX_GetMessage;
+ }
+ break;
+ case RX_GetMessage:
+ d->Msg.Buffer[d->Msg.Count] = rx_char;
+ d->Msg.Count++;
+ if (d->Msg.Count == d->Msg.Length) {
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = Phone->DispatchMessage(s);
+ d->MsgRXState = RX_Sync;
+ }
+ break;
+ }
+
+ return ERR_NONE;
+}
+
+static GSM_Error OBEX_Initialise(GSM_StateMachine *s)
+{
+ GSM_Protocol_OBEXData *d = &s->Protocol.Data.OBEX;
+
+ d->Msg.BufferUsed = 0;
+ d->Msg.Buffer = NULL;
+ d->Msg.Length = 0;
+
+ d->MsgRXState = RX_Sync;
+
+ return ERR_NONE;
+}
+
+static GSM_Error OBEX_Terminate(GSM_StateMachine *s)
+{
+ free(s->Protocol.Data.OBEX.Msg.Buffer);
+ return ERR_NONE;
+}
+
+GSM_Protocol_Functions OBEXProtocol = {
+ OBEX_WriteMessage,
+ OBEX_StateMachine,
+ OBEX_Initialise,
+ OBEX_Terminate
+};
+
+#endif
+
+void OBEXAddBlock(char *Buffer, int *Pos, unsigned char ID, char *AddBuffer, int AddLength)
+{
+ Buffer[(*Pos)++] = ID;
+ Buffer[(*Pos)++] = (AddLength+3)/256;
+ Buffer[(*Pos)++] = (AddLength+3)%256;
+ if (AddBuffer != NULL) {
+ memcpy(Buffer+(*Pos),AddBuffer,AddLength);
+ (*Pos) += AddLength;
+ }
+}
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/obex/obex.h b/gammu/emb/common/protocol/obex/obex.h
new file mode 100644
index 0000000..0e927c7
--- a/dev/null
+++ b/gammu/emb/common/protocol/obex/obex.h
@@ -0,0 +1,33 @@
+/* (c) 2003 by Marcin Wiacek */
+
+#ifndef obex_h
+#define obex_h
+
+#include "../protocol.h"
+
+typedef struct {
+ int MsgRXState;
+ GSM_Protocol_Message Msg;
+} GSM_Protocol_OBEXData;
+
+#ifndef GSM_USED_SERIALDEVICE
+# define GSM_USED_SERIALDEVICE
+#endif
+#if defined(GSM_ENABLE_BLUEOBEX)
+# ifndef GSM_USED_BLUETOOTHDEVICE
+# define GSM_USED_BLUETOOTHDEVICE
+# endif
+#endif
+#if defined(GSM_ENABLE_IRDAOBEX)
+# ifndef GSM_USED_IRDADEVICE
+# define GSM_USED_IRDADEVICE
+# endif
+#endif
+
+void OBEXAddBlock(char *Buffer, int *Pos, unsigned char ID, char *AddBuffer, int AddLength);
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/protocol.h b/gammu/emb/common/protocol/protocol.h
new file mode 100644
index 0000000..f8e1fe5
--- a/dev/null
+++ b/gammu/emb/common/protocol/protocol.h
@@ -0,0 +1,31 @@
+/* (c) 2002-2003 by Marcin Wiacek */
+
+#ifndef protocol_common_h
+#define protocol_common_h
+
+typedef enum {
+ RX_Sync,
+ RX_GetDestination,
+ RX_GetSource,
+ RX_GetType,
+ RX_GetLength1,
+ RX_GetLength2,
+ RX_GetMessage
+} GSM_Protocol_RXState;
+
+typedef struct {
+ int Length;
+ int Count;
+ unsigned char Type;
+ unsigned char Source;
+ unsigned char Destination;
+ unsigned char *Buffer;
+ int BufferUsed;
+ unsigned char CheckSum[2];
+} GSM_Protocol_Message;
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/symbian/mrouter.c b/gammu/emb/common/protocol/symbian/mrouter.c
new file mode 100644
index 0000000..2ca7af1
--- a/dev/null
+++ b/gammu/emb/common/protocol/symbian/mrouter.c
@@ -0,0 +1,110 @@
+/* (c) 2003 by Marcin Wiacek */
+
+#include "../../gsmstate.h"
+
+#if defined(GSM_ENABLE_MROUTERBLUE)
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../gsmcomon.h"
+#include "mrouter.h"
+
+static GSM_Error MROUTER_WriteMessage (GSM_StateMachine *s, unsigned char *buffer,
+ int length, unsigned char type)
+{
+ unsigned char *out_buffer;
+ int current=0,sent;
+
+ out_buffer = (unsigned char *)malloc(length+1);
+
+ memcpy(out_buffer,buffer,length);
+ out_buffer[length]=0x7E;
+
+ GSM_DumpMessageLevel2(s, out_buffer, length, type);
+ GSM_DumpMessageLevel3(s, out_buffer, length, type);
+
+ /* Send it out... */
+ sent = s->Device.Functions->WriteDevice(s,out_buffer,length+1);
+
+ free(out_buffer);
+
+ if (sent!=current) return ERR_DEVICEWRITEERROR;
+ return ERR_NONE;
+}
+
+static GSM_Error MROUTER_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
+{
+ GSM_Phone_Functions *Phone = s->Phone.Functions;
+ GSM_Protocol_MROUTERData *d = &s->Protocol.Data.MROUTER;
+
+ switch (d->MsgRXState) {
+ case RX_Sync:
+ if (rx_char == 0x7E) {
+ d->MsgRXState = RX_GetMessage;
+ d->Msg.Count = 0;
+ d->Msg.Length = 0;
+ } else smprintf(s,"Sync error: %02x\n",rx_char);
+ break;
+ case RX_GetMessage:
+ if (rx_char == 0x7E) {
+ s->Phone.Data.RequestMsg = &d->Msg;
+ s->Phone.Data.DispatchError = Phone->DispatchMessage(s);
+ d->Msg.Count = 0;
+ d->Msg.Length = 0;
+ } else {
+ d->Msg.BufferUsed = d->Msg.Length+1;
+ d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed);
+
+ d->Msg.Buffer[d->Msg.Count] = rx_char;
+ d->Msg.Count++;
+ d->Msg.Length++;
+ }
+ break;
+ }
+
+ return ERR_NONE;
+}
+
+static GSM_Error MROUTER_Initialise(GSM_StateMachine *s)
+{
+ GSM_Protocol_MROUTERData *d = &s->Protocol.Data.MROUTER;
+GSM_Error error;
+
+ d->Msg.BufferUsed = 0;
+ d->Msg.Buffer = NULL;
+ d->Msg.Length = 0;
+
+ d->MsgRXState = RX_Sync;
+
+// error=s->Device.Functions->DeviceSetDtrRts(s,false,false);
+// if (error!=ERR_NONE) return error;
+
+ error=s->Device.Functions->DeviceSetSpeed(s,115200);
+ if (error!=ERR_NONE) return error;
+
+
+// error=s->Device.Functions->DeviceSetSpeed(s,115200);
+// if (error!=ERR_NONE) return error;
+
+ return ERR_NONE;
+}
+
+static GSM_Error MROUTER_Terminate(GSM_StateMachine *s)
+{
+ free(s->Protocol.Data.MROUTER.Msg.Buffer);
+ return ERR_NONE;
+}
+
+GSM_Protocol_Functions MROUTERProtocol = {
+ MROUTER_WriteMessage,
+ MROUTER_StateMachine,
+ MROUTER_Initialise,
+ MROUTER_Terminate
+};
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */
diff --git a/gammu/emb/common/protocol/symbian/mrouter.h b/gammu/emb/common/protocol/symbian/mrouter.h
new file mode 100644
index 0000000..7d72cdd
--- a/dev/null
+++ b/gammu/emb/common/protocol/symbian/mrouter.h
@@ -0,0 +1,31 @@
+/* (c) 2003 by Marcin Wiacek */
+
+#ifndef mrouter_h
+#define mrouter_h
+
+#include "../protocol.h"
+
+typedef struct {
+ int MsgRXState;
+ GSM_Protocol_Message Msg;
+} GSM_Protocol_MROUTERData;
+
+#ifndef GSM_USED_SERIALDEVICE
+# define GSM_USED_SERIALDEVICE
+#endif
+//#if defined(GSM_ENABLE_BLUEOBEX)
+//# ifndef GSM_USED_BLUETOOTHDEVICE
+//# define GSM_USED_BLUETOOTHDEVICE
+//# endif
+//#endif
+//#if defined(GSM_ENABLE_IRDAOBEX)
+//# ifndef GSM_USED_IRDADEVICE
+//# define GSM_USED_IRDADEVICE
+//# endif
+//#endif
+
+#endif
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */