2 #include "../../gsmstate.h"
4 #if defined(GSM_ENABLE_AT) || defined(GSM_ENABLE_BLUEAT) || defined(GSM_ENABLE_IRDAAT)
9 #include "../../gsmcomon.h"
12 static GSM_Error
AT_WriteMessage (GSM_StateMachine
*s
, unsigned char *buffer
,
13 int length
, unsigned char type
)
17 GSM_DumpMessageLevel2(s
, buffer
, length
, type
);
18 GSM_DumpMessageLevel3(s
, buffer
, length
, type
);
19 if (s
->Protocol
.Data
.AT
.FastWrite
) {
20 while (sent
!= length
) {
21 if ((i
= s
->Device
.Functions
->WriteDevice(s
,buffer
+ sent
, length
- sent
)) == 0) {
22 return GE_DEVICEWRITEERROR
;
27 for (i
=0;i
<length
;i
++) {
28 if (s
->Device
.Functions
->WriteDevice(s
,buffer
+i
,1)!=1) return GE_DEVICEWRITEERROR
;
29 /* For some phones like Siemens M20 we need to wait a little
30 * after writing each char. Possible reason: these phones
31 * can't receive so fast chars or there is bug here in Gammu */
43 } SpecialAnswersStruct
;
45 static GSM_Error
AT_StateMachine(GSM_StateMachine
*s
, unsigned char rx_byte
)
47 GSM_Protocol_Message Msg2
;
48 GSM_Protocol_ATData
*d
= &s
->Protocol
.Data
.AT
;
51 /* These are lines with end of "normal" answers */
52 static char *StartStrings
[] = {
54 "+CME ERROR:" , "+CMS ERROR:" ,
56 "+CPIN: " , /*A2D issue*/
60 /* Some info from phone can be inside "normal" answers
61 * It starts with strings written here
63 static SpecialAnswersStruct SpecialAnswers
[] = {
64 {"_OSIGQ:" ,1}, {"_OBS:" ,1},
65 {"^SCN:" ,1}, {"+CGREG:" ,1},
66 {"+CBM:" ,1}, {"+CMT:" ,2},
67 {"+CMTI:" ,1}, {"+CDS:" ,2},
69 {"RING" ,1}, {"NO CARRIER" ,1},
70 {"NO ANSWER" ,1}, {"+COLP" ,1},
75 /* Ignore leading CR, LF and ESC */
76 if (d
->Msg
.Length
== 0) {
77 if (rx_byte
== 10 || rx_byte
== 13 || rx_byte
== 27) return GE_NONE
;
78 d
->LineStart
= d
->Msg
.Length
;
81 if (d
->Msg
.BufferUsed
< d
->Msg
.Length
+ 2) {
82 d
->Msg
.BufferUsed
= d
->Msg
.Length
+ 2;
83 d
->Msg
.Buffer
= (unsigned char *)realloc(d
->Msg
.Buffer
,d
->Msg
.BufferUsed
);
85 d
->Msg
.Buffer
[d
->Msg
.Length
++] = rx_byte
;
86 d
->Msg
.Buffer
[d
->Msg
.Length
] = 0;
93 if (!d
->wascrlf
) d
->LineEnd
= d
->Msg
.Length
-1;
95 if (d
->Msg
.Length
> 0 && rx_byte
== 10 && d
->Msg
.Buffer
[d
->Msg
.Length
-2]==13) {
97 while (StartStrings
[i
] != NULL
) {
98 if (strlen(StartStrings
[i
])==0) break;
99 if (strncmp(StartStrings
[i
],d
->Msg
.Buffer
+d
->LineStart
,strlen(StartStrings
[i
])) == 0) {
100 s
->Phone
.Data
.RequestMsg
= &d
->Msg
;
101 s
->Phone
.Data
.DispatchError
= s
->Phone
.Functions
->DispatchMessage(s
);
107 if (d
->Msg
.Length
== 0) break;
110 while (SpecialAnswers
[i
].text
!= NULL
) {
111 if (strlen(SpecialAnswers
[i
].text
)==0) break;
112 if (strncmp(SpecialAnswers
[i
].text
,d
->Msg
.Buffer
+d
->LineStart
,strlen(SpecialAnswers
[i
].text
)) == 0) {
113 d
->SpecialAnswerStart
= d
->LineStart
;
114 d
->SpecialAnswerLines
= SpecialAnswers
[i
].lines
;
119 if (d
->SpecialAnswerLines
== 1) {
120 /* This is end of special answer. We copy it and send to phone module */
121 Msg2
.Buffer
= malloc(d
->LineEnd
- d
->SpecialAnswerStart
+ 3);
122 memcpy(Msg2
.Buffer
,d
->Msg
.Buffer
+d
->SpecialAnswerStart
,d
->LineEnd
- d
->SpecialAnswerStart
+ 2);
123 Msg2
.Length
= d
->LineEnd
- d
->SpecialAnswerStart
+ 2;
124 Msg2
.Buffer
[Msg2
.Length
] = 0;
126 s
->Phone
.Data
.RequestMsg
= &Msg2
;
127 s
->Phone
.Data
.DispatchError
= s
->Phone
.Functions
->DispatchMessage(s
);
130 /* We cut special answer from main buffer */
131 d
->Msg
.Length
= d
->SpecialAnswerStart
;
132 if (d
->Msg
.Length
!= 0) d
->Msg
.Length
= d
->Msg
.Length
- 2;
134 /* We need to find earlier values of all variables */
137 for (i
=0;i
<d
->Msg
.Length
;i
++) {
138 switch(d
->Msg
.Buffer
[i
]) {
143 if (!d
->wascrlf
) d
->LineEnd
= d
->Msg
.Length
-1;
148 d
->LineStart
= d
->Msg
.Length
-1;
153 d
->Msg
.Buffer
[d
->Msg
.Length
] = 0;
155 if (d
->SpecialAnswerLines
> 0) d
->SpecialAnswerLines
--;
159 /* When CONNECT string received, we know there will not follow
160 * anything AT related, after CONNECT can follow ppp data, alcabus
161 * data and also other things.
163 if (strncmp(d
->Msg
.Buffer
+d
->LineStart
, "CONNECT", 7) == 0) {
164 s
->Phone
.Data
.RequestMsg
= &d
->Msg
;
165 s
->Phone
.Data
.DispatchError
= s
->Phone
.Functions
->DispatchMessage(s
);
172 d
->LineStart
= d
->Msg
.Length
-1;
176 if (strlen(d
->Msg
.Buffer
+d
->LineStart
) == 2 && strncmp(d
->Msg
.Buffer
+d
->LineStart
,"> ",2)==0) {
177 s
->Phone
.Data
.RequestMsg
= &d
->Msg
;
178 s
->Phone
.Data
.DispatchError
= s
->Phone
.Functions
->DispatchMessage(s
);
185 static GSM_Error
AT_Initialise(GSM_StateMachine
*s
)
187 GSM_Protocol_ATData
*d
= &s
->Protocol
.Data
.AT
;
189 d
->Msg
.Buffer
= NULL
;
190 d
->Msg
.BufferUsed
= 0;
194 d
->SpecialAnswerLines
= 0;
199 d
->FastWrite
= false;
201 s
->Device
.Functions
->DeviceSetDtrRts(s
,true,true);
203 return s
->Device
.Functions
->DeviceSetSpeed(s
,s
->Speed
);
206 static GSM_Error
AT_Terminate(GSM_StateMachine
*s
)
208 free(s
->Protocol
.Data
.AT
.Msg
.Buffer
);
212 GSM_Protocol_Functions ATProtocol
= {
221 /* How should editor hadle tabs in this file? Add editor commands here.
222 * vim: noexpandtab sw=8 ts=8 sts=8: