/* (c) 2001-2003 by Marcin Wiacek */ /* based on some work from MyGnokii (www.mwiacek.com) */ #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: */