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