author | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
commit | 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (unidiff) | |
tree | 6331418973714243beb674abc87692277b83869d /gammu/emb/common/protocol/at/at.c | |
parent | ef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff) | |
download | kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.zip kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.gz kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.bz2 |
Initial revision
Diffstat (limited to 'gammu/emb/common/protocol/at/at.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | gammu/emb/common/protocol/at/at.c | 229 |
1 files changed, 229 insertions, 0 deletions
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 @@ | |||
1 | /* (c) 2002-2004 by Marcin Wiacek and Michal Cihar */ | ||
2 | |||
3 | #include "../../gsmstate.h" | ||
4 | |||
5 | #if defined(GSM_ENABLE_AT) || defined(GSM_ENABLE_BLUEAT) || defined(GSM_ENABLE_IRDAAT) | ||
6 | |||
7 | #include <stdio.h> | ||
8 | #include <string.h> | ||
9 | |||
10 | #include "../../gsmcomon.h" | ||
11 | #include "at.h" | ||
12 | |||
13 | static GSM_Error AT_WriteMessage (GSM_StateMachine *s, unsigned char *buffer, | ||
14 | int length, unsigned char type) | ||
15 | { | ||
16 | int i,sent = 0; | ||
17 | |||
18 | GSM_DumpMessageLevel2(s, buffer, length, type); | ||
19 | GSM_DumpMessageLevel3(s, buffer, length, type); | ||
20 | if (s->Protocol.Data.AT.FastWrite) { | ||
21 | while (sent != length) { | ||
22 | if ((i = s->Device.Functions->WriteDevice(s,buffer + sent, length - sent)) == 0) { | ||
23 | return ERR_DEVICEWRITEERROR; | ||
24 | } | ||
25 | sent += i; | ||
26 | } | ||
27 | } else { | ||
28 | for (i=0;i<length;i++) { | ||
29 | if (s->Device.Functions->WriteDevice(s,buffer+i,1)!=1) return ERR_DEVICEWRITEERROR; | ||
30 | /* For some phones like Siemens M20 we need to wait a little | ||
31 | * after writing each char. Possible reason: these phones | ||
32 | * can't receive so fast chars or there is bug here in Gammu */ | ||
33 | my_sleep(1); | ||
34 | } | ||
35 | my_sleep(400); | ||
36 | } | ||
37 | |||
38 | return ERR_NONE; | ||
39 | } | ||
40 | |||
41 | typedef struct { | ||
42 | char*text; | ||
43 | intlines; | ||
44 | } SpecialAnswersStruct; | ||
45 | |||
46 | static GSM_Error AT_StateMachine(GSM_StateMachine *s, unsigned char rx_char) | ||
47 | { | ||
48 | GSM_Protocol_Message Msg2; | ||
49 | GSM_Protocol_ATData *d = &s->Protocol.Data.AT; | ||
50 | int i; | ||
51 | |||
52 | /* These are lines with end of "normal" answers */ | ||
53 | static char *StartStrings[] = { | ||
54 | "OK" , "ERROR" , | ||
55 | "+CME ERROR:" , "+CMS ERROR:", | ||
56 | |||
57 | "+CPIN: " ,/*A2D issue*/ | ||
58 | |||
59 | NULL}; | ||
60 | |||
61 | /* Some info from phone can be inside "normal" answers | ||
62 | * It starts with strings written here | ||
63 | */ | ||
64 | static SpecialAnswersStructSpecialAnswers[] = { | ||
65 | {"_OSIGQ:" ,1}, {"_OBS:",1}, | ||
66 | {"^SCN:" ,1}, {"+CGREG:",1}, | ||
67 | {"+CBM:" ,1}, {"+CMT:",2}, | ||
68 | {"+CMTI:" ,1}, {"+CDS:",2}, | ||
69 | {"+CREG:",1}, | ||
70 | |||
71 | {"RING" ,1}, {"NO CARRIER",1}, | ||
72 | {"NO ANSWER" ,1}, {"+COLP",1}, | ||
73 | {"+CLIP",1}, | ||
74 | |||
75 | {NULL ,1}}; | ||
76 | |||
77 | /* Ignore leading CR, LF and ESC */ | ||
78 | if (d->Msg.Length == 0) { | ||
79 | if (rx_char == 10 || rx_char == 13 || rx_char == 27) return ERR_NONE; | ||
80 | d->LineStart = d->Msg.Length; | ||
81 | } | ||
82 | |||
83 | if (d->Msg.BufferUsed < d->Msg.Length + 2) { | ||
84 | d->Msg.BufferUsed= d->Msg.Length + 2; | ||
85 | d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed); | ||
86 | } | ||
87 | d->Msg.Buffer[d->Msg.Length++] = rx_char; | ||
88 | d->Msg.Buffer[d->Msg.Length ] = 0; | ||
89 | |||
90 | switch (rx_char) { | ||
91 | case 0: | ||
92 | break; | ||
93 | case 10: | ||
94 | case 13: | ||
95 | if (!d->wascrlf) d->LineEnd = d->Msg.Length-1; | ||
96 | d->wascrlf = true; | ||
97 | if (d->Msg.Length > 0 && rx_char == 10 && d->Msg.Buffer[d->Msg.Length-2]==13) { | ||
98 | i = 0; | ||
99 | while (StartStrings[i] != NULL) { | ||
100 | if (strncmp(StartStrings[i],d->Msg.Buffer+d->LineStart,strlen(StartStrings[i])) == 0) { | ||
101 | s->Phone.Data.RequestMsg= &d->Msg; | ||
102 | s->Phone.Data.DispatchError= s->Phone.Functions->DispatchMessage(s); | ||
103 | d->Msg.Length = 0; | ||
104 | break; | ||
105 | } | ||
106 | i++; | ||
107 | } | ||
108 | if (d->Msg.Length == 0) break; | ||
109 | |||
110 | i = 0; | ||
111 | while (SpecialAnswers[i].text != NULL) { | ||
112 | if (strncmp(SpecialAnswers[i].text,d->Msg.Buffer+d->LineStart,strlen(SpecialAnswers[i].text)) == 0) { | ||
113 | /* We need something better here */ | ||
114 | if (s->Phone.Data.RequestID == ID_GetNetworkInfo && strncmp(SpecialAnswers[i].text,"+CREG:",6) == 0) { | ||
115 | i++; | ||
116 | continue; | ||
117 | } | ||
118 | d->SpecialAnswerStart = d->LineStart; | ||
119 | d->SpecialAnswerLines= SpecialAnswers[i].lines; | ||
120 | } | ||
121 | i++; | ||
122 | } | ||
123 | |||
124 | |||
125 | if (d->SpecialAnswerLines == 1) { | ||
126 | /* This is end of special answer. We copy it and send to phone module */ | ||
127 | Msg2.Buffer = malloc(d->LineEnd - d->SpecialAnswerStart + 3); | ||
128 | memcpy(Msg2.Buffer,d->Msg.Buffer+d->SpecialAnswerStart,d->LineEnd - d->SpecialAnswerStart + 2); | ||
129 | Msg2.Length = d->LineEnd - d->SpecialAnswerStart + 2; | ||
130 | Msg2.Buffer[Msg2.Length] = 0; | ||
131 | |||
132 | s->Phone.Data.RequestMsg= &Msg2; | ||
133 | s->Phone.Data.DispatchError= s->Phone.Functions->DispatchMessage(s); | ||
134 | free(Msg2.Buffer); | ||
135 | |||
136 | /* We cut special answer from main buffer */ | ||
137 | d->Msg.Length = d->SpecialAnswerStart; | ||
138 | if (d->Msg.Length != 0) d->Msg.Length = d->Msg.Length - 2; | ||
139 | |||
140 | /* We need to find earlier values of all variables */ | ||
141 | d->wascrlf = false; | ||
142 | d->LineStart = 0; | ||
143 | for (i=0;i<d->Msg.Length;i++) { | ||
144 | switch(d->Msg.Buffer[i]) { | ||
145 | case 0: | ||
146 | break; | ||
147 | case 10: | ||
148 | case 13: | ||
149 | if (!d->wascrlf) d->LineEnd = d->Msg.Length-1; | ||
150 | d->wascrlf = true; | ||
151 | break; | ||
152 | default: | ||
153 | if (d->wascrlf) { | ||
154 | d->LineStart= d->Msg.Length-1; | ||
155 | d->wascrlf = false; | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | d->Msg.Buffer[d->Msg.Length] = 0; | ||
160 | } | ||
161 | if (d->SpecialAnswerLines > 0) d->SpecialAnswerLines--; | ||
162 | } | ||
163 | break; | ||
164 | case 'T': | ||
165 | /* When CONNECT string received, we know there will not follow | ||
166 | * anything AT related, after CONNECT can follow ppp data, alcabus | ||
167 | * data and also other things. | ||
168 | */ | ||
169 | if (strncmp(d->Msg.Buffer+d->LineStart, "CONNECT", 7) == 0) { | ||
170 | s->Phone.Data.RequestMsg = &d->Msg; | ||
171 | s->Phone.Data.DispatchError= s->Phone.Functions->DispatchMessage(s); | ||
172 | d->LineStart = -1; | ||
173 | d->Msg.Length = 0; | ||
174 | break; | ||
175 | } | ||
176 | default: | ||
177 | if (d->wascrlf) { | ||
178 | d->LineStart= d->Msg.Length-1; | ||
179 | d->wascrlf = false; | ||
180 | } | ||
181 | if (d->EditMode) { | ||
182 | if (strlen(d->Msg.Buffer+d->LineStart) == 2 && strncmp(d->Msg.Buffer+d->LineStart,"> ",2)==0) { | ||
183 | s->Phone.Data.RequestMsg= &d->Msg; | ||
184 | s->Phone.Data.DispatchError= s->Phone.Functions->DispatchMessage(s); | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | return ERR_NONE; | ||
189 | } | ||
190 | |||
191 | static GSM_Error AT_Initialise(GSM_StateMachine *s) | ||
192 | { | ||
193 | GSM_Protocol_ATData *d = &s->Protocol.Data.AT; | ||
194 | |||
195 | d->Msg.Buffer = NULL; | ||
196 | d->Msg.BufferUsed= 0; | ||
197 | d->Msg.Length = 0; | ||
198 | d->Msg.Type = 0; | ||
199 | |||
200 | d->SpecialAnswerLines= 0; | ||
201 | d->LineStart = -1; | ||
202 | d->LineEnd = -1; | ||
203 | d->wascrlf = false; | ||
204 | d->EditMode = false; | ||
205 | d->FastWrite = false; | ||
206 | |||
207 | s->Device.Functions->DeviceSetDtrRts(s,true,true); | ||
208 | |||
209 | return s->Device.Functions->DeviceSetSpeed(s,s->Speed); | ||
210 | } | ||
211 | |||
212 | static GSM_Error AT_Terminate(GSM_StateMachine *s) | ||
213 | { | ||
214 | free(s->Protocol.Data.AT.Msg.Buffer); | ||
215 | return ERR_NONE; | ||
216 | } | ||
217 | |||
218 | GSM_Protocol_Functions ATProtocol = { | ||
219 | AT_WriteMessage, | ||
220 | AT_StateMachine, | ||
221 | AT_Initialise, | ||
222 | AT_Terminate | ||
223 | }; | ||
224 | |||
225 | #endif | ||
226 | |||
227 | /* How should editor hadle tabs in this file? Add editor commands here. | ||
228 | * vim: noexpandtab sw=8 ts=8 sts=8: | ||
229 | */ | ||