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