From 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 Mon Sep 17 00:00:00 2001 From: zautrix Date: Sat, 07 Aug 2004 17:24:40 +0000 Subject: Initial revision --- (limited to 'gammu/emb/common/protocol/nokia/mbus2.c') 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 +#include + +#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: + */ -- cgit v0.9.0.2