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/at') 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 +#include + +#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;iDevice.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;iMsg.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: + */ -- cgit v0.9.0.2