Diffstat (limited to 'gammu/emb/gammu/depend/siemens/dsiemens.c') (more/less context) (show whitespace changes)
-rw-r--r-- | gammu/emb/gammu/depend/siemens/dsiemens.c | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/gammu/emb/gammu/depend/siemens/dsiemens.c b/gammu/emb/gammu/depend/siemens/dsiemens.c new file mode 100644 index 0000000..dc54102 --- a/dev/null +++ b/gammu/emb/gammu/depend/siemens/dsiemens.c | |||
@@ -0,0 +1,363 @@ | |||
1 | /* (c) by Walek */ | ||
2 | |||
3 | #include "../../../common/gsmstate.h" | ||
4 | |||
5 | #ifdef GSM_ENABLE_ATGEN | ||
6 | |||
7 | #include <string.h> | ||
8 | |||
9 | #include "../../../common/misc/coding/coding.h" | ||
10 | #include "../../../common/gsmcomon.h" | ||
11 | #include "../../../common/service/gsmnet.h" | ||
12 | #include "../../../common/phone/at/atgen.h" | ||
13 | #include "../../gammu.h" | ||
14 | #include "dsiemens.h" | ||
15 | #include "chiffre.h" | ||
16 | |||
17 | extern GSM_Error ATGEN_GetSIMIMSI (GSM_StateMachine *s, char *IMSI); | ||
18 | extern GSM_Error ATGEN_GetMemoryStatus (GSM_StateMachine *s, GSM_MemoryStatus *status); | ||
19 | extern GSM_Error ATGEN_SetMemory (GSM_StateMachine *s, GSM_MemoryEntry *pbk); | ||
20 | extern GSM_Reply_Function UserReplyFunctionsAtS[]; | ||
21 | |||
22 | bool new_variable; | ||
23 | GSM_Error CheckSiemens() | ||
24 | { | ||
25 | if (s.Phone.Data.Priv.ATGEN.Manufacturer != AT_Siemens) return ERR_NOTSUPPORTED; | ||
26 | return ERR_NONE; | ||
27 | } | ||
28 | |||
29 | GSM_Error ATSIEMENS_Reply_GetSAT(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
30 | { | ||
31 | GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; | ||
32 | GSM_SAT_Measure_results MeasureResult; | ||
33 | unsigned char buf[256]; | ||
34 | int length,i,rep,ChNo=1,j=0,result=0,origARFCN=0; | ||
35 | int freq_tmp,frequency[24]; | ||
36 | GSM_NetworkInfo Network; | ||
37 | |||
38 | if (Priv->ReplyState!=AT_Reply_OK) return ERR_UNKNOWN; | ||
39 | if (s->Protocol.Data.AT.EditMode) s->Protocol.Data.AT.EditMode = false; | ||
40 | if (strstr(GetLineString(msg.Buffer,Priv->Lines,2),"SSTK")) { | ||
41 | length = strlen(GetLineString(msg.Buffer,Priv->Lines,2))-7; | ||
42 | DecodeHexBin(buf, GetLineString(msg.Buffer,Priv->Lines,2)+7,length); | ||
43 | if (buf[0]==0x7f) { | ||
44 | new_variable=true; | ||
45 | return ERR_NONE; | ||
46 | } | ||
47 | else return ERR_UNKNOWN; | ||
48 | } | ||
49 | if (!strstr(GetLineString(msg.Buffer,Priv->Lines,3),"SSTK")) return ERR_UNKNOWN; | ||
50 | |||
51 | length = strlen(GetLineString(msg.Buffer,Priv->Lines,3))-7; | ||
52 | DecodeHexBin(buf, GetLineString(msg.Buffer,Priv->Lines,3)+7,length); | ||
53 | |||
54 | if (buf[3]!=0x26) return ERR_UNKNOWN; | ||
55 | |||
56 | #ifdef DEBUG | ||
57 | dbgprintf ("SAT command: Provide Local Information\nFunction: "); | ||
58 | switch (buf[4]) { | ||
59 | case 00: dbgprintf ("Loc Info\n"); break; | ||
60 | case 01: dbgprintf ("IMEI\n"); break; | ||
61 | case 02: dbgprintf ("Network Measure\n"); break; | ||
62 | case 03: dbgprintf ("Date time and timezone\n");break; | ||
63 | case 04: dbgprintf ("Language setting\n"); break; | ||
64 | case 05: dbgprintf ("Timing advance\n"); break; | ||
65 | } | ||
66 | #endif | ||
67 | /* Loc Info (MCC, MNC, LAC, Cell ID) */ | ||
68 | if (buf[4]==00) { | ||
69 | DecodeBCD (Network.NetworkCode,buf+14,2); | ||
70 | Network.NetworkCode[3] = ' '; | ||
71 | DecodeBCD (Network.NetworkCode+4,buf+16,1); | ||
72 | EncodeHexBin (Network.LAC,buf+17,2); | ||
73 | EncodeHexBin (Network.CID,buf+19,2); | ||
74 | |||
75 | printf(" Network code : %s\n",Network.NetworkCode); | ||
76 | printf(" Network name for Gammu : %s\n", | ||
77 | DecodeUnicodeString(GSM_GetNetworkName(Network.NetworkCode))); | ||
78 | printf(" CID : %s\n",Network.CID); | ||
79 | printf(" LAC : %s\n",Network.LAC); | ||
80 | } | ||
81 | |||
82 | /* Network Measure */ | ||
83 | if (buf[4]==02) { | ||
84 | |||
85 | for (i=0;i<24;i++) frequency[i]=0; | ||
86 | if (!new_variable) { | ||
87 | GetBufferI(buf+32,&j,&result,7); | ||
88 | result &= 0x67; | ||
89 | if (result !=0x47) return ERR_NOTSUPPORTED; | ||
90 | } | ||
91 | #ifdef DEBUG | ||
92 | if (new_variable)dbgprintf ("New variable Bitmap format\n"); | ||
93 | else dbgprintf ("Old variable Bitmap format\n"); | ||
94 | #endif | ||
95 | GetBufferI(buf+32,&j,&origARFCN,10); | ||
96 | /* 10 bit origin ARFCN or first frequency (new variable format) */ | ||
97 | #ifdef DEBUG | ||
98 | dbgprintf("Origin BCCH = %i\n",origARFCN); | ||
99 | #endif | ||
100 | rep = buf[31]*8; | ||
101 | if (!new_variable ){ | ||
102 | for (i=0;i<rep;i++){ | ||
103 | result = 0; | ||
104 | GetBufferI(buf+32,&j,&result,1); | ||
105 | if (result) { | ||
106 | frequency[ChNo]=i+origARFCN+1; | ||
107 | ChNo++; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | else { | ||
112 | frequency[ChNo++]=origARFCN; | ||
113 | for (i=0; i<rep; i+=10){ | ||
114 | result = 0; | ||
115 | GetBufferI(buf+32,&j,&result,10); | ||
116 | if (!result) break; | ||
117 | frequency[ChNo++]=result; | ||
118 | } | ||
119 | j=1; | ||
120 | while (j) { | ||
121 | j=0; | ||
122 | for (i=0; i<ChNo-1; i++){ | ||
123 | if (frequency[i] > frequency[i+1]){ | ||
124 | freq_tmp=frequency[i]; | ||
125 | frequency[i]=frequency[i+1]; | ||
126 | frequency[i+1]=freq_tmp; | ||
127 | j=1; | ||
128 | } | ||
129 | } | ||
130 | } | ||
131 | }; | ||
132 | #ifdef DEBUG | ||
133 | dbgprintf("Neighbor BCCH list: "); | ||
134 | for (i=1;i<ChNo;i++) dbgprintf ("%d ",frequency[i]); | ||
135 | dbgprintf ("\n"); | ||
136 | #endif | ||
137 | j= 0; | ||
138 | result= 0; | ||
139 | GetBufferI(buf+14,&j,&result,1); | ||
140 | if (result) MeasureResult.BA_used=true; | ||
141 | else MeasureResult.BA_used=false; | ||
142 | |||
143 | result= 0; | ||
144 | GetBufferI(buf+14,&j,&result,1); | ||
145 | if (result) MeasureResult.DTX_used=true; | ||
146 | else MeasureResult.DTX_used=false; | ||
147 | |||
148 | result= 0; | ||
149 | GetBufferI(buf+14,&j,&result,6); | ||
150 | MeasureResult.RXLEV_FullServicingCell=result-110; | ||
151 | |||
152 | j++;//skip spare bit | ||
153 | result= 0; | ||
154 | GetBufferI(buf+14,&j,&result,1); | ||
155 | if (result) MeasureResult.MeasValid=true; | ||
156 | else MeasureResult.MeasValid=false; | ||
157 | |||
158 | result= 0; | ||
159 | GetBufferI(buf+14,&j,&result,6); | ||
160 | MeasureResult.RXLEV_SubServicingCell=result-110; | ||
161 | |||
162 | j++;//skip spare bit | ||
163 | result= 0; | ||
164 | GetBufferI(buf+14,&j,&result,3); | ||
165 | MeasureResult.RXQUAL_FullServicingCell=result; | ||
166 | |||
167 | result= 0; | ||
168 | GetBufferI(buf+14,&j,&result,3); | ||
169 | MeasureResult.RXQUAL_SubServicingCell=result; | ||
170 | |||
171 | printf ("RX Level FULL Servicing Cell = %i\n",MeasureResult.RXLEV_FullServicingCell); | ||
172 | printf ("RX Level Sub Servicing Cell = %i\n",MeasureResult.RXLEV_FullServicingCell); | ||
173 | |||
174 | printf ("RX Quality Full Servicing Cell = %i\n",MeasureResult.RXQUAL_FullServicingCell); | ||
175 | printf ("RX Quality Sub Servicing Cell = %i\n",MeasureResult.RXQUAL_SubServicingCell); | ||
176 | |||
177 | result= 0; | ||
178 | GetBufferI(buf+14,&j,&result,3); | ||
179 | MeasureResult.NO_NCELL_M=result; | ||
180 | |||
181 | rep=MeasureResult.NO_NCELL_M; | ||
182 | |||
183 | for (i=0;i<MeasureResult.NO_NCELL_M;i++) { | ||
184 | result= 0; | ||
185 | GetBufferI(buf+14,&j,&result,6); | ||
186 | MeasureResult.NeighbourCell[i].RxLev = result-110; | ||
187 | |||
188 | result= 0; | ||
189 | GetBufferI(buf+14,&j,&result,5); | ||
190 | if (new_variable) | ||
191 | MeasureResult.NeighbourCell[i].ChFreq = frequency[result+1]; | ||
192 | else MeasureResult.NeighbourCell[i].ChFreq = frequency[result]; | ||
193 | |||
194 | result= 0; | ||
195 | GetBufferI(buf+14,&j,&result,3); | ||
196 | MeasureResult.NeighbourCell[i].NB = 10 * result; | ||
197 | result= 0; | ||
198 | GetBufferI(buf+14,&j,&result,3); | ||
199 | MeasureResult.NeighbourCell[i].NB += result; | ||
200 | |||
201 | if (MeasureResult.NeighbourCell[i].ChFreq) | ||
202 | printf("CH = %i,\t",MeasureResult.NeighbourCell[i].ChFreq); | ||
203 | else | ||
204 | printf("CH = Unknown\t"); | ||
205 | printf("RX Lev = %i dBm\t",MeasureResult.NeighbourCell[i].RxLev); | ||
206 | printf("BSIC CELL = %i\n",MeasureResult.NeighbourCell[i].NB); | ||
207 | } | ||
208 | } | ||
209 | #ifdef DEBUG | ||
210 | if (buf[4]==05) { //Timing Advance | ||
211 | if (buf[11]) dbgprintf ("Unknown Timing Advance\n"); | ||
212 | else dbgprintf ("Timing Advance = %i\n",buf[14] & 0x3f); | ||
213 | } | ||
214 | #endif | ||
215 | return ERR_NONE; | ||
216 | } | ||
217 | |||
218 | GSM_Error ATSIEMENS_Reply_GetNetmon(GSM_Protocol_Message msg, GSM_StateMachine *s) | ||
219 | { | ||
220 | GSM_Phone_ATGENData*Priv = &s->Phone.Data.Priv.ATGEN; | ||
221 | int i=2; | ||
222 | |||
223 | if (!strstr(GetLineString(msg.Buffer,Priv->Lines,1),"AT^S^MI")) return ERR_UNKNOWN; | ||
224 | while (strlen(GetLineString(msg.Buffer,Priv->Lines,i+1))) | ||
225 | printf("%s\n",GetLineString(msg.Buffer,Priv->Lines,i++)); | ||
226 | printf("\n"); | ||
227 | return ERR_NONE; | ||
228 | } | ||
229 | |||
230 | GSM_Error ATSIEMENS_GetSAT(GSM_StateMachine *s) | ||
231 | { | ||
232 | GSM_Phone_ATGENData*Priv = &s->Phone.Data.Priv.ATGEN; | ||
233 | GSM_Error error; | ||
234 | unsigned char *reqSAT[]= {"D009810301260082028182", | ||
235 | "D009810301260282028182", | ||
236 | "D009810301260582028182"},req[32]; | ||
237 | int i,len; | ||
238 | |||
239 | if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
240 | |||
241 | sprintf(req, "AT^SSTK=?\r"); | ||
242 | error = GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_User1); | ||
243 | |||
244 | for (i=0;i<3;i++){ | ||
245 | len = strlen(reqSAT[i]); | ||
246 | s->Protocol.Data.AT.EditMode = true; | ||
247 | sprintf(req, "AT^SSTK=%i,1\r",len/2); | ||
248 | error = GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_User1); | ||
249 | s->Phone.Data.DispatchError= ERR_TIMEOUT; | ||
250 | s->Phone.Data.RequestID = ID_User1; | ||
251 | error = s->Protocol.Functions->WriteMessage(s, reqSAT[i], len, 0x00); | ||
252 | if (error!=ERR_NONE) return error; | ||
253 | error = s->Protocol.Functions->WriteMessage(s, "\x1A", 1, 0x00); | ||
254 | if (error!=ERR_NONE) return error; | ||
255 | error = GSM_WaitForOnce (s, NULL,0x00, 0x00, 4); | ||
256 | if (error!=ERR_NONE) return error; | ||
257 | } | ||
258 | return ERR_NONE; | ||
259 | } | ||
260 | |||
261 | GSM_Error ATSIEMENS_GetNetmon(GSM_StateMachine *s,int test_no) | ||
262 | { | ||
263 | GSM_Phone_ATGENData*Priv = &s->Phone.Data.Priv.ATGEN; | ||
264 | unsigned char req[32]; | ||
265 | |||
266 | if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
267 | sprintf(req, "AT^S^MI=%d\r",test_no); | ||
268 | printf ("Siemens NetMonitor test #%i\n",test_no); | ||
269 | return GSM_WaitFor(s, req, strlen(req), 0x00, 3, ID_User2); | ||
270 | } | ||
271 | |||
272 | GSM_Error ATSIEMENS_ActivateNetmon (GSM_StateMachine *s,int netmon_type) | ||
273 | { | ||
274 | GSM_Phone_ATGENData*Priv = &s->Phone.Data.Priv.ATGEN; | ||
275 | unsigned char req[32]; | ||
276 | |||
277 | if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; | ||
278 | |||
279 | sprintf(req, "AT\r"); | ||
280 | printf ("Activate Siemens NetMonitor\n"); | ||
281 | siemens_code (req,req,2); | ||
282 | |||
283 | return GSM_WaitFor(s, req, strlen(req), 0x00, 3, ID_User2); | ||
284 | } | ||
285 | |||
286 | void ATSIEMENSActivateNetmon(int argc, char *argv[]) | ||
287 | { | ||
288 | GSM_MemoryStatus status; | ||
289 | GSM_MemoryEntry pbk; | ||
290 | int netmon_type, pbk_maxlocation; | ||
291 | char imsi[15], NetMonCode[32]; | ||
292 | |||
293 | GSM_Init(true); | ||
294 | if (CheckSiemens()==ERR_NOTSUPPORTED) Print_Error(ERR_NOTSUPPORTED); | ||
295 | s.User.UserReplyFunctions=UserReplyFunctionsAtS; | ||
296 | |||
297 | printf ("Activate NetMonitor...\n"); | ||
298 | netmon_type = atoi(argv[2]); | ||
299 | |||
300 | if ((netmon_type==1) || (netmon_type==2)) { | ||
301 | error = ATGEN_GetSIMIMSI (&s,imsi); | ||
302 | Print_Error(error); | ||
303 | siemens_code(imsi,NetMonCode,netmon_type); | ||
304 | |||
305 | status.MemoryType = MEM_SM; | ||
306 | error = ATGEN_GetMemoryStatus (&s,&status); | ||
307 | Print_Error(error); | ||
308 | |||
309 | pbk_maxlocation = status.MemoryUsed+status.MemoryFree; | ||
310 | pbk.MemoryType = MEM_SM; | ||
311 | pbk.Location = pbk_maxlocation; | ||
312 | pbk.EntriesNum = 2; | ||
313 | pbk.Entries[0].EntryType = PBK_Number_General; | ||
314 | EncodeUnicode (pbk.Entries[0].Text,NetMonCode,strlen(NetMonCode)); | ||
315 | pbk.Entries[1].EntryType = PBK_Text_Name; | ||
316 | sprintf (NetMonCode,"Net Monitor"); | ||
317 | EncodeUnicode (pbk.Entries[1].Text,NetMonCode,strlen(NetMonCode)); | ||
318 | error = ATGEN_SetMemory (&s, &pbk); | ||
319 | Print_Error(error); | ||
320 | } | ||
321 | else printf ("NetMonitor type should be:\n1 - full Netmon\n2 - simple NetMon\n"); | ||
322 | |||
323 | GSM_Terminate(); | ||
324 | } | ||
325 | |||
326 | void ATSIEMENSSATNetmon(int argc, char *argv[]) | ||
327 | { | ||
328 | GSM_Init(true); | ||
329 | if (CheckSiemens()==ERR_NOTSUPPORTED) Print_Error(ERR_NOTSUPPORTED); | ||
330 | s.User.UserReplyFunctions=UserReplyFunctionsAtS; | ||
331 | |||
332 | printf ("Getting Siemens Sim Aplication Toolkit NetMonitor...\n"); | ||
333 | |||
334 | error=ATSIEMENS_GetSAT(&s); | ||
335 | Print_Error(error); | ||
336 | GSM_Terminate(); | ||
337 | } | ||
338 | |||
339 | void ATSIEMENSNetmonitor(int argc, char *argv[]) | ||
340 | { | ||
341 | int test_no; | ||
342 | |||
343 | GSM_Init(true); | ||
344 | if (CheckSiemens()==ERR_NOTSUPPORTED) Print_Error(ERR_NOTSUPPORTED); | ||
345 | s.User.UserReplyFunctions=UserReplyFunctionsAtS; | ||
346 | |||
347 | printf ("Getting Siemens NetMonitor...\n"); | ||
348 | test_no = atoi(argv[2]); | ||
349 | error = ATSIEMENS_GetNetmon (&s,test_no+1); | ||
350 | Print_Error(error); | ||
351 | GSM_Terminate(); | ||
352 | } | ||
353 | |||
354 | static GSM_Reply_Function UserReplyFunctionsAtS[] = { | ||
355 | {ATSIEMENS_Reply_GetSAT, "AT^SSTK", 0x00,0x00,ID_User1}, | ||
356 | {ATSIEMENS_Reply_GetNetmon, "AT^S^MI", 0x00,0x00,ID_User2}, | ||
357 | {NULL, "\x00", 0x00,0x00,ID_None} | ||
358 | }; | ||
359 | #endif | ||
360 | |||
361 | /* How should editor hadle tabs in this file? Add editor commands here. | ||
362 | * vim: noexpandtab sw=8 ts=8 sts=8: | ||
363 | */ | ||