Diffstat (limited to 'gammu/emb/common/phone/at/siemens.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | gammu/emb/common/phone/at/siemens.c | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/gammu/emb/common/phone/at/siemens.c b/gammu/emb/common/phone/at/siemens.c new file mode 100644 index 0000000..ab7dd2c --- a/dev/null +++ b/gammu/emb/common/phone/at/siemens.c | |||
@@ -0,0 +1,320 @@ | |||
1 | /* (c) 2002-2003 by Walek */ | ||
2 | |||
3 | #include "../../gsmstate.h" | ||
4 | |||
5 | #ifdef GSM_ENABLE_ATGEN | ||
6 | |||
7 | #include <string.h> | ||
8 | #include <time.h> | ||
9 | #include <ctype.h> | ||
10 | |||
11 | #include "../../misc/coding/coding.h" | ||
12 | #include "../../gsmcomon.h" | ||
13 | #include "../../service/sms/gsmsms.h" | ||
14 | #include "../pfunc.h" | ||
15 | |||
16 | extern GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s); | ||
17 | |||
18 | GSM_Error ATGEN_CMS35ReplySetFunction (GSM_Protocol_Message msg, GSM_StateMachine *s,char *function) | ||
19 | { | ||
20 | if (s->Protocol.Data.AT.EditMode) { | ||
21 | s->Protocol.Data.AT.EditMode = false; | ||
22 | return ERR_NONE; | ||
23 | } | ||
24 | dbgprintf ("Written %s",function); | ||
25 | if (s->Phone.Data.Priv.ATGEN.ReplyState == AT_Reply_OK){ | ||
26 | dbgprintf (" - OK\n"); | ||
27 | return ERR_NONE; | ||
28 | } else { | ||
29 | dbgprintf (" - error\n"); | ||
30 | return ERR_UNKNOWN; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *templ, | ||
35 | unsigned char *buffer, int *len) | ||
36 | { | ||
37 | GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; | ||
38 | int i=2, pos=0, length=0; | ||
39 | unsigned char buf[512]; | ||
40 | |||
41 | if (strstr(GetLineString(msg.Buffer,Priv->Lines,2),"OK")) return ERR_EMPTY; | ||
42 | if (!strstr(GetLineString(msg.Buffer,Priv->Lines,2),templ)) return ERR_UNKNOWN; | ||
43 | |||
44 | while (1) { | ||
45 | if (Priv->Lines.numbers[i*2+1]==0) break; | ||
46 | if ((!strstr(GetLineString(msg.Buffer,Priv->Lines,i+1),templ)) && | ||
47 | (strstr(GetLineString(msg.Buffer,Priv->Lines,i),templ))){ | ||
48 | length = strlen(GetLineString(msg.Buffer,Priv->Lines,i+1)); | ||
49 | DecodeHexBin(buf, GetLineString(msg.Buffer,Priv->Lines,i+1),length); | ||
50 | length = length/2; | ||
51 | memcpy (buffer+pos,buf,length); | ||
52 | pos+=length; | ||
53 | } | ||
54 | i++; | ||
55 | } | ||
56 | *len = pos; | ||
57 | return ERR_NONE; | ||
58 | } | ||
59 | |||
60 | GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ, | ||
61 | int Location, GSM_Phone_RequestID RequestID, int len) | ||
62 | { | ||
63 | GSM_Phone_Data *Phone = &s->Phone.Data; | ||
64 | GSM_Error error; | ||
65 | unsigned char req[20],req1[512],hexreq[2096]; | ||
66 | int MaxFrame,CurrentFrame,size,sz,pos=0; | ||
67 | |||
68 | EncodeHexBin(hexreq,buff,len); | ||
69 | size = len * 2; | ||
70 | MaxFrame = size / 352; | ||
71 | if (size % 352) MaxFrame++; | ||
72 | |||
73 | for (CurrentFrame=0;CurrentFrame<MaxFrame;CurrentFrame++) { | ||
74 | pos=CurrentFrame*352; | ||
75 | if (pos+352 < size) sz = 352; else sz = size - pos; | ||
76 | sprintf(req, "AT^SBNW=\"%s\",%i,%i,%i\r",templ,Location,CurrentFrame+1,MaxFrame); | ||
77 | s->Protocol.Data.AT.EditMode = true; | ||
78 | error = GSM_WaitFor (s, req, strlen(req), 0x00, 3, RequestID); | ||
79 | s->Phone.Data.DispatchError=ERR_TIMEOUT; | ||
80 | s->Phone.Data.RequestID=RequestID; | ||
81 | if (error!=ERR_NONE) return error; | ||
82 | memcpy (req1,hexreq+pos,sz); | ||
83 | error = s->Protocol.Functions->WriteMessage(s, req1, sz, 0x00); | ||
84 | if (error!=ERR_NONE) return error; | ||
85 | error = s->Protocol.Functions->WriteMessage(s,"\x1A", 1, 0x00); | ||
86 | if (error!=ERR_NONE) return error; | ||
87 | error = GSM_WaitForOnce(s, NULL, 0x00, 0x00, 4); | ||
88 | if (error == ERR_TIMEOUT) return error; | ||
89 | } | ||
90 | return Phone->DispatchError; | ||
91 | } | ||
92 | |||
93 | GSM_Error ATGEN_CMS35ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
94 | { | ||
95 | unsigned char buffer[4096]; | ||
96 | int length; | ||
97 | GSM_Error error; | ||
98 | |||
99 | error = GetSiemensFrame(msg,s,"bmp",buffer,&length); | ||
100 | if (error!=ERR_NONE) return error; | ||
101 | dbgprintf ("Operator logo received lenght=%i\n",length); | ||
102 | error = BMP2Bitmap (buffer,NULL,s->Phone.Data.Bitmap); | ||
103 | if (error==ERR_NONE) return error; | ||
104 | else return ERR_UNKNOWN; | ||
105 | } | ||
106 | |||
107 | GSM_Error ATGEN_CMS35ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
108 | { | ||
109 | return ATGEN_CMS35ReplySetFunction (msg, s, "Operator Logo"); | ||
110 | } | ||
111 | |||
112 | GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) | ||
113 | { | ||
114 | unsigned char req[32]; | ||
115 | |||
116 | if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
117 | if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED; | ||
118 | if (Bitmap->Location-1 < 0) Bitmap->Location++; | ||
119 | s->Phone.Data.Bitmap=Bitmap; | ||
120 | sprintf(req, "AT^SBNR=\"bmp\",%i\r", Bitmap->Location-1); | ||
121 | smprintf(s, "Getting Bitmap\n"); | ||
122 | return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetBitmap); | ||
123 | } | ||
124 | |||
125 | GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) | ||
126 | { | ||
127 | unsigned char buffer[4096]; | ||
128 | int length; | ||
129 | GSM_Errorerror; | ||
130 | |||
131 | if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
132 | if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED; | ||
133 | |||
134 | error = Bitmap2BMP (buffer,NULL,Bitmap); | ||
135 | if (error!=ERR_NONE) return error; | ||
136 | length = 0x100 * buffer[3] + buffer[2]; | ||
137 | buffer[58]=0xff; buffer[59]=0xff; buffer[60]=0xff; | ||
138 | if (Bitmap->Location-1 < 0) Bitmap->Location++; | ||
139 | s->Phone.Data.Bitmap=Bitmap; | ||
140 | return SetSiemensFrame(s, buffer,"bmp",Bitmap->Location-1, | ||
141 | ID_SetBitmap,length); | ||
142 | } | ||
143 | |||
144 | GSM_Error ATGEN_CMS35ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
145 | { | ||
146 | unsigned char buffer[32]; | ||
147 | int length; | ||
148 | GSM_Error error; | ||
149 | |||
150 | error = GetSiemensFrame(msg,s,"mid",s->Phone.Data.Ringtone->NokiaBinary.Frame,&length); | ||
151 | if (error!=ERR_NONE) return error; | ||
152 | dbgprintf ("Midi ringtone received\n"); | ||
153 | |||
154 | s->Phone.Data.Ringtone->Format = RING_MIDI; | ||
155 | s->Phone.Data.Ringtone->NokiaBinary.Length= length; | ||
156 | sprintf(buffer,"Individual"); | ||
157 | EncodeUnicode (s->Phone.Data.Ringtone->Name,buffer,strlen(buffer)); | ||
158 | return ERR_NONE; | ||
159 | } | ||
160 | |||
161 | GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) | ||
162 | { | ||
163 | unsigned char req[32]; | ||
164 | |||
165 | if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
166 | |||
167 | s->Phone.Data.Ringtone=Ringtone; | ||
168 | sprintf(req, "AT^SBNR=\"mid\",%i\r", Ringtone->Location-1); | ||
169 | smprintf(s, "Getting RingTone\n"); | ||
170 | return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetRingtone); | ||
171 | } | ||
172 | |||
173 | GSM_Error ATGEN_CMS35ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
174 | { | ||
175 | return ATGEN_CMS35ReplySetFunction (msg, s, "Ringtone"); | ||
176 | } | ||
177 | |||
178 | GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) | ||
179 | { | ||
180 | GSM_Phone_Data *Phone = &s->Phone.Data; | ||
181 | |||
182 | if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
183 | |||
184 | if (Ringtone->Location==255) Ringtone->Location=1; | ||
185 | if (Ringtone->Location-1 > 1) return ERR_INVALIDLOCATION; | ||
186 | |||
187 | s->Phone.Data.Ringtone= Ringtone; | ||
188 | Phone->Ringtone = Ringtone; | ||
189 | return SetSiemensFrame(s, Ringtone->NokiaBinary.Frame,"mid",Ringtone->Location-1, | ||
190 | ID_SetRingtone,Ringtone->NokiaBinary.Length); | ||
191 | } | ||
192 | |||
193 | GSM_Error ATGEN_CMS35ReplyGetNextCal(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
194 | { | ||
195 | GSM_Phone_Data *Data = &s->Phone.Data; | ||
196 | GSM_CalendarEntry*Calendar = Data->Cal; | ||
197 | GSM_ToDoEntry ToDo; | ||
198 | GSM_Error error; | ||
199 | unsigned char buffer[354]; | ||
200 | int len, pos=0; | ||
201 | |||
202 | if (Data->Priv.ATGEN.ReplyState != AT_Reply_OK) return ERR_UNKNOWN; | ||
203 | |||
204 | error = GetSiemensFrame(msg,s,"vcs",buffer,&len); | ||
205 | if (error!=ERR_NONE) return error; | ||
206 | error=GSM_DecodeVCALENDAR_VTODO(buffer,&pos,Calendar,&ToDo,Siemens_VCalendar,0); | ||
207 | |||
208 | return error; | ||
209 | } | ||
210 | |||
211 | GSM_Error SIEMENS_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) | ||
212 | { | ||
213 | GSM_Phone_ATGENData*Priv = &s->Phone.Data.Priv.ATGEN; | ||
214 | GSM_Error error; | ||
215 | unsigned char req[32]; | ||
216 | int Location; | ||
217 | |||
218 | if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
219 | |||
220 | if (start) Note->Location=Priv->FirstCalendarPos; | ||
221 | s->Phone.Data.Cal = Note; | ||
222 | Note->EntriesNum = 0; | ||
223 | smprintf(s, "Getting VCALENDAR\n"); | ||
224 | Location = Note->Location; | ||
225 | while (1){ | ||
226 | Location++; | ||
227 | sprintf(req, "AT^SBNR=\"vcs\",%i\r",Location); | ||
228 | error = GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetCalendarNote); | ||
229 | if ((error!=ERR_NONE) && (error!=ERR_EMPTY)) return ERR_INVALIDLOCATION; | ||
230 | Note->Location = Location; | ||
231 | Priv->FirstCalendarPos = Location; | ||
232 | if (Location > MAX_VCALENDAR_LOCATION) return ERR_EMPTY; | ||
233 | if (error==ERR_NONE) return error; | ||
234 | } | ||
235 | return error; | ||
236 | } | ||
237 | |||
238 | GSM_Error ATGEN_CMS35ReplySetCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
239 | { | ||
240 | return ATGEN_CMS35ReplySetFunction (msg, s, "Calendar Note"); | ||
241 | } | ||
242 | |||
243 | GSM_Error ATGEN_CMS35ReplyDeleteCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
244 | { | ||
245 | GSM_Phone_Data *Data = &s->Phone.Data; | ||
246 | |||
247 | if (Data->Cal->Location > MAX_VCALENDAR_LOCATION) return ERR_UNKNOWN; | ||
248 | |||
249 | if (Data->Priv.ATGEN.ReplyState== AT_Reply_OK) { | ||
250 | smprintf(s, "Calendar note deleted\n"); | ||
251 | return ERR_NONE; | ||
252 | } else { | ||
253 | smprintf(s, "Can't delete calendar note\n"); | ||
254 | return ERR_UNKNOWN; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | GSM_Error SIEMENS_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) | ||
259 | { | ||
260 | unsigned char req[32]; | ||
261 | |||
262 | if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
263 | s->Phone.Data.Cal = Note; | ||
264 | sprintf(req, "AT^SBNW=\"vcs\",%i,0\r",Note->Location); | ||
265 | smprintf(s, "Deleting calendar note\n"); | ||
266 | return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_DeleteCalendarNote); | ||
267 | } | ||
268 | |||
269 | GSM_Error SIEMENS_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) | ||
270 | { | ||
271 | GSM_Phone_ATGENData*Priv = &s->Phone.Data.Priv.ATGEN; | ||
272 | GSM_Error error; | ||
273 | unsigned char req[500]; | ||
274 | int size=0; | ||
275 | |||
276 | if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
277 | // if (Note->Location==0x00) return ERR_INVALIDLOCATION; | ||
278 | |||
279 | s->Phone.Data.Cal = Note; | ||
280 | error=GSM_EncodeVCALENDAR(req,&size,Note,true,Siemens_VCalendar); | ||
281 | |||
282 | return SetSiemensFrame (s,req,"vcs",Note->Location,ID_SetCalendarNote,size); | ||
283 | } | ||
284 | |||
285 | /* (c) by Timo Teras */ | ||
286 | GSM_Error ATGEN_SL45ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
287 | { | ||
288 | #ifndef ENABLE_LGPL | ||
289 | GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; | ||
290 | GSM_MemoryEntry *Memory = s->Phone.Data.Memory; | ||
291 | unsigned char buffer[500],buffer2[500]; | ||
292 | |||
293 | switch (Priv->ReplyState) { | ||
294 | case AT_Reply_OK: | ||
295 | smprintf(s, "Phonebook entry received\n"); | ||
296 | CopyLineString(buffer, msg.Buffer, Priv->Lines, 3); | ||
297 | DecodeHexBin(buffer2,buffer,strlen(buffer)); | ||
298 | Memory->EntriesNum = 0; | ||
299 | DecodeVCARD21Text(buffer2, Memory); | ||
300 | if (Memory->EntriesNum == 0) return ERR_EMPTY; | ||
301 | return ERR_NONE; | ||
302 | case AT_Reply_Error: | ||
303 | smprintf(s, "Error - too high location ?\n"); | ||
304 | return ERR_INVALIDLOCATION; | ||
305 | case AT_Reply_CMSError: | ||
306 | return ATGEN_HandleCMSError(s); | ||
307 | default: | ||
308 | break; | ||
309 | } | ||
310 | return ERR_UNKNOWNRESPONSE; | ||
311 | #else | ||
312 | return ERR_NOTIMPLEMENTED; | ||
313 | #endif | ||
314 | } | ||
315 | |||
316 | #endif | ||
317 | |||
318 | /* How should editor hadle tabs in this file? Add editor commands here. | ||
319 | * vim: noexpandtab sw=8 ts=8 sts=8: | ||
320 | */ | ||