Imported gammu 0.90.7
[gammu.git] / gammu / depend / dct4.c
blob0500c0d94d28be333ad2c7a0a4d6d13d7c09e81b
2 #include "../../common/gsmstate.h"
4 #ifdef GSM_ENABLE_NOKIA_DCT4
6 #include <string.h>
8 #include "dct4.h"
9 #include "../gammu.h"
10 #include "../../common/phone/nokia/nfunc.h"
11 #include "../../common/phone/nokia/dct4/dct4func.h"
12 #include "../../common/misc/coding/coding.h"
14 extern GSM_Reply_Function UserReplyFunctions4[];
16 /* ------- some usefull functions ----------------------------------------- */
18 GSM_Error CheckDCT4Only()
20 bool found = false;
22 /* Checking if phone is DCT4 */
23 #ifdef GSM_ENABLE_NOKIA3650
24 if (strstr(N3650Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true;
25 #endif
26 #ifdef GSM_ENABLE_NOKIA6510
27 if (strstr(N6510Phone.models, s.Phone.Data.ModelInfo->model) != NULL) found = true;
28 #endif
29 if (!found) return GE_NOTSUPPORTED;
31 if (s.ConnectionType!=GCT_MBUS2 && s.ConnectionType!=GCT_FBUS2 &&
32 s.ConnectionType!=GCT_FBUS2DLR3 && s.ConnectionType!=GCT_PHONETBLUE &&
33 s.ConnectionType!=GCT_IRDAPHONET && s.ConnectionType!=GCT_BLUEPHONET)
35 return GE_OTHERCONNECTIONREQUIRED;
37 return GE_NONE;
40 static void CheckDCT4()
42 GSM_Error error;
44 error = CheckDCT4Only();
45 switch (error) {
46 case GE_NOTSUPPORTED:
47 Print_Error(GE_NOTSUPPORTED);
48 break;
49 case GE_OTHERCONNECTIONREQUIRED:
50 printf("Can't do it with current phone protocol\n");
51 GSM_TerminateConnection(&s);
52 exit(-1);
53 default:
54 break;
58 static bool answer_yes2(char *text)
60 int len;
61 char ans[99];
63 while (1) {
64 printf("%s (yes/no) ? ",text);
65 len=GetLine(stdin, ans, 99);
66 if (len==-1) exit(-1);
67 if (mystrncasecmp(ans, "yes",0)) return true;
68 if (mystrncasecmp(ans, "no" ,0)) return false;
72 /* ------------------- functions ------------------------------------------- */
74 static DCT4_Feature DCT4Features[] = {
75 {DCT4_ALS, "Alternate Line Service (ALS)", {{1,"on"},{0,"off"},{0,""}}},
76 {DCT4_A52, "Ciphering alghoritm A52", {{1,"on"},{0,"off"},{0,""}}},
77 {DCT4_CSP, "Customer Service Profile", {{0,"off"},{1,"on"},{0,""}}},
78 {DCT4_DISPLAY_PHONE_NAME, "Display both number and name for incoming calls",{{1,"on"},{0,"off"},{0,""}}},
79 {DCT4_DISPLAY_WAP_PROFILE, "Display selected WAP profile name instead of Home option menu in Services",{{1,"on"},{0,"off"},{0,""}}},
80 {DCT4_USE_PREF_SIM_NET, "Use SIM preffered network list",{{1,"on"},{0,"off"},{0,""}}},
81 {DCT4_WAP_PUSH, "WAP push", {{1,"on"},{0,"off"},{0,""}}},
83 {DCT4_GPRS_PCCH, "PCCH support for GPRS", {{1,"on"},{0,"off"},{0,""}}},
84 {DCT4_ALWAYS_ONLINE, "GPRS Always Online", {{0,"on (Context)"},{1,"off (Attach)"},{0,""}}},///??
85 {DCT4_GEA1, "GEA1 support indication", {{1,"on"},{0,"off"},{0,""}}},
86 {DCT4_EOTD, "EOTD support", {{1,"on"},{0,"off"},{0,""}}},
88 {DCT4_GAMES_WAP_DOWNLOAD, "Games WAP download", {{1,"on"},{0,"off"},{0,""}}},
89 {DCT4_GAMES_SCORE_SEND, "Games WAP score send", {{1,"on"},{0,"off"},{0,""}}},
90 {DCT4_GAMES_URL_CHECK, "Games URL check", {{1,"on"},{0,"off"},{0,""}}},
92 {DCT4_BLUETOOTH_MENU, "Bluetooth menu", {{1,"on"},{0,"off"},{0,""}}},
93 {DCT4_WAP_BOOKMARKS_MENU, "Bookmarks menu in Services", {{1,"on"},{0,"off"},{0,""}}},
94 {DCT4_WAP_GOTO_MENU, "GoTo menu in Services", {{0,"on"},{1,"off"},{0,""}}},
95 {DCT4_WAP_SETTINGS_MENU, "Profiles menu in Services", {{0,"on"},{1,"off"},{0,""}}},
96 {DCT4_SERVICES_GAMES_APP_GALLERY,"Services menu in Games/Apps/Gallery",{{1,"on"},{0,"off"},{0,""}}},
97 {DCT4_JAVA_GAMES_MENU, "Java games menu in Games", {{1,"on"},{0,"off"},{0,""}}},
98 {DCT4_SAT_CONFIRM_MENU, "Can use confirming SIM service actions", {{1,"on"},{0,"off"},{0,""}}},
100 {DCT4_5100_IDENTIFY, "Phone identification", {{1,"NPM-6U"},{0,"NPM-6"},{0,""}}},
102 #ifdef DEBUG
103 {DCT4_TEST,"",{{1,"1"},{0,"0"}}},
104 #endif
106 {0, "", {{0,""}}}
109 static DCT4_Phone_Features DCT4PhoneFeatures[] = {
110 /*3300*/ {"NEM-1", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
111 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
112 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
113 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
114 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
115 /*MORE*/ {0,0}}},
116 /*3510*/ {"NHM-8", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6},
117 {DCT4_GAMES_WAP_DOWNLOAD,7},{DCT4_GAMES_SCORE_SEND,8},
118 {DCT4_GAMES_URL_CHECK,9},{DCT4_GPRS_PCCH,13},
119 {DCT4_GEA1,15},{DCT4_ALWAYS_ONLINE,18},{0,0}}},
120 /*3510i*/{"RH-9", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,4},{DCT4_GPRS_PCCH,9},
121 {DCT4_DISPLAY_PHONE_NAME,14},{DCT4_WAP_GOTO_MENU,15},
122 {DCT4_WAP_SETTINGS_MENU,16},{DCT4_SERVICES_GAMES_APP_GALLERY,19},
123 {DCT4_DISPLAY_WAP_PROFILE,25},{0,0}}},
124 /*3650*/ {"NHL-8", {{DCT4_ALS,1},{0,0}}},
125 /*5100*/ {"NPM-6", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
126 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
127 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
128 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
129 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
130 // {DCT4_5100_IDENTIFY,10},
131 {0,0}}},
132 /*5100*/ {"NPM-6U", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
133 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
134 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
135 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
136 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
137 // {DCT4_5100_IDENTIFY,10},
138 {0,0}}},
139 /*6100*/ {"NPL-2", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
140 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
141 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
142 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
143 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
144 {0,0}}},
145 /*6310*/ {"NPE-4", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7},
146 {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9},{DCT4_BLUETOOTH_MENU,10},
147 {DCT4_GPRS_PCCH,13},{DCT4_GEA1,15},{DCT4_ALWAYS_ONLINE,18},{0,0}}},
148 /*6310i*/{"NPL-1", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7},
149 {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9},
150 {DCT4_BLUETOOTH_MENU,10},{DCT4_USE_PREF_SIM_NET,11},
151 {DCT4_GPRS_PCCH,13},{DCT4_GEA1,15},{DCT4_EOTD,16},
152 {DCT4_ALWAYS_ONLINE,17},{DCT4_JAVA_GAMES_MENU,18},
153 {DCT4_WAP_BOOKMARKS_MENU,20},{DCT4_WAP_SETTINGS_MENU,21},
154 {DCT4_WAP_PUSH,28},{DCT4_WAP_GOTO_MENU,29},{0,0}}},
155 /*6510*/ {"NPM-9", {{DCT4_ALS,1},{DCT4_A52,3},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7},
156 {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9},
157 {DCT4_GPRS_PCCH,13},{DCT4_GEA1,15},{DCT4_ALWAYS_ONLINE,18},{0,0}}},
158 /*6610*/ {"NHL-4U", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
159 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
160 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
161 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
162 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
163 {0,0}}},
164 /*6800*/ {"NHL-6", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
165 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
166 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
167 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
168 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
169 /*MORE*/ {0,0}}},
170 /*7210*/ {"NHL-4", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
171 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
172 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
173 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
174 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
175 {0,0}}},
176 /*7250*/ {"NHL-4J", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
177 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
178 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
179 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
180 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
181 {0,0}}},
182 /*7250i*/{"NHL-4JX", {{DCT4_ALS,1},{DCT4_CSP,4},{DCT4_GAMES_URL_CHECK,5},{DCT4_GPRS_PCCH,8},
183 {DCT4_GEA1,9},{DCT4_ALWAYS_ONLINE,11},{DCT4_EOTD,12},
184 {DCT4_DISPLAY_PHONE_NAME,17},{DCT4_WAP_GOTO_MENU,18},
185 {DCT4_WAP_SETTINGS_MENU,19},{DCT4_SERVICES_GAMES_APP_GALLERY,22},
186 {DCT4_DISPLAY_WAP_PROFILE,26},{DCT4_SAT_CONFIRM_MENU,27},
187 /*MORE*/ {0,0}}},
188 /*8310*/{"NHM-7", {{DCT4_ALS,1},{DCT4_CSP,6},{DCT4_GAMES_WAP_DOWNLOAD,7},
189 {DCT4_GAMES_SCORE_SEND,8},{DCT4_GAMES_URL_CHECK,9},{DCT4_GPRS_PCCH,13},
190 {DCT4_ALWAYS_ONLINE,18},{0,0}}},
191 {"", {{0,0}}}
194 static GSM_Error DCT4_ReplySetPPS(GSM_Protocol_Message msg, GSM_StateMachine *s)
196 printf("Setting done OK\n");
197 return GE_NONE;
200 void DCT4SetPhoneMenus(int argc, char *argv[])
202 int current = 10,i=0,j,z;
203 unsigned char reqSet[200] = {
204 N7110_FRAME_HEADER,0x04,0x00,0x01,0x47,0x48,0x02,
205 0x00}; /* Number of changed features */
207 if (CheckDCT4Only()!=GE_NONE) return;
209 s.User.UserReplyFunctions=UserReplyFunctions4;
211 while (DCT4PhoneFeatures[i].Model[0] != 0x00) {
212 if (!strcmp(DCT4PhoneFeatures[i].Model,s.Phone.Data.Model)) {
213 j = 0;
214 while (DCT4PhoneFeatures[i].Features[j].Name != 0x00) {
215 z = 0;
216 while (DCT4Features[z].Name != 0x00) {
217 if (DCT4Features[z].Name == DCT4PhoneFeatures[i].Features[j].Name) {
218 printf("%s : %s\n",DCT4Features[z].Text,DCT4Features[z].Values[0].Text);
219 reqSet[9]++; /* Number of features */
220 reqSet[current++] = DCT4PhoneFeatures[i].Features[j].Number; /* Feature number */
221 reqSet[current++] = DCT4Features[z].Values[0].Value; /* Value */
222 break;
224 z++;
226 j++;
229 i++;
232 if (current == 10) {
233 printf("Sorry, but configuration matrix for this model is not added yet. Please report\n");
234 return;
237 reqSet[current++] = 0x00;
238 reqSet[current++] = 0x00;
240 error=GSM_WaitFor (&s, reqSet, current, 0x1b, 4, ID_User1);
241 Print_Error(error);
244 DCT4_Phone_Tests DCT4Tests;
246 static GSM_Error DCT4_ReplyTestsNames(GSM_Protocol_Message msg, GSM_StateMachine *s)
248 int i,pos;
250 DCT4Tests.Num = msg.Buffer[5];
251 pos = 6;
253 smprintf(s,"%i names for phone tests received\n",msg.Buffer[5]);
254 for (i=0;i<msg.Buffer[5];i++) {
255 strcpy(DCT4Tests.Tests[i].Name,msg.Buffer+pos+4);
256 DCT4Tests.Tests[i].ID = msg.Buffer[pos+2];
257 smprintf(s,"%x.\"%s\"\n",DCT4Tests.Tests[i].ID,DCT4Tests.Tests[i].Name);
258 pos+=msg.Buffer[pos+1];
261 return GE_NONE;
264 static GSM_Error DCT4_ReplyTestsStartup(GSM_Protocol_Message msg, GSM_StateMachine *s)
266 int i,pos,j;
267 bool found;
269 pos = 10;
271 for (i=0;i<msg.Buffer[8];i++) {
272 found = false;
273 for (j=0;j<DCT4Tests.Num;j++) {
274 if (DCT4Tests.Tests[j].ID == msg.Buffer[pos]) {
275 DCT4Tests.Tests[j].Startup = true;
276 found = true;
277 break;
280 if (!found) printf("%x ",msg.Buffer[pos]);
281 pos++;
284 return GE_NONE;
287 static GSM_Error DCT4_ReplyTestsStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
289 int i,pos,j;
291 pos = 6;
293 smprintf(s,"%i status entries for phone tests received\n",msg.Buffer[5]);
294 for (i=0;i<msg.Buffer[5];i++) {
295 for (j=0;j<DCT4Tests.Num;j++) {
296 if (DCT4Tests.Tests[j].ID == msg.Buffer[pos+2]) {
297 printf("\"%40s\" : ",DCT4Tests.Tests[j].Name);
298 switch(msg.Buffer[pos+3]) {
299 case 0x00: printf("Passed"); break;
300 case 0x01: printf("Fail"); break;
301 case 0x03: printf("Not executed"); break;
302 case 0x06: printf("No signal"); break;
303 case 0x0D: printf("Timeout"); break;
304 default : printf("Unknown (%x)",msg.Buffer[pos+3]);
306 if (DCT4Tests.Tests[j].Startup) printf(" (startup)");
307 printf("\n");
308 break;
311 pos+=msg.Buffer[pos+1];
314 return GE_NONE;
317 void DCT4SelfTests(int argc, char *argv[])
319 int j;
320 unsigned char GetDoneST[6] = {0x00, 0x08, 0x01, 0x04, 0x01, 0x00};
321 unsigned char GetDoneST2[6] = {0x00, 0x08, 0x02, 0x04, 0x02, 0x00};
322 unsigned char GetNames[6] = {0x00, 0x08, 0x03, 0x06, 0x03, 0x00};
323 unsigned char GetStatus[6] = {0x00, 0x08, 0x04, 0x02, 0x03, 0x00};
325 unsigned char RunALL[6] = {0x00, 0x06, 0x04, 0x00, 0x03, 0x00};
327 // unsigned char GetID[6] = {0x00, 0x08, 0x00, 0x04, 0x03, 0x00};//tests ID
329 if (CheckDCT4Only()!=GE_NONE) return;
331 s.User.UserReplyFunctions=UserReplyFunctions4;
333 if (answer_yes2("Run all tests now ?")) {
334 error=GSM_WaitFor (&s, RunALL, 6, 0x35, 4, ID_User1);
335 Print_Error(error);
338 error=GSM_WaitFor (&s, GetNames, 6, 0x35, 4, ID_User1);
339 Print_Error(error);
341 for (j=0;j<DCT4Tests.Num;j++) DCT4Tests.Tests[j].Startup = false;
343 error=GSM_WaitFor (&s, GetDoneST, 6, 0x35, 4, ID_User3);
344 Print_Error(error);
346 error=GSM_WaitFor (&s, GetDoneST2, 6, 0x35, 4, ID_User3);
347 Print_Error(error);
349 error=GSM_WaitFor (&s, GetStatus, 6, 0x35, 4, ID_User2);
350 Print_Error(error);
353 static GSM_Error DCT4_ReplyVibra(GSM_Protocol_Message msg, GSM_StateMachine *s)
355 #ifdef DEBUG
356 switch (msg.Buffer[3]) {
357 case 0x0D : dbgprintf("Vibra state set OK\n"); break;
358 case 0x0F : dbgprintf("Vibra power set OK\n"); break;
360 #endif
361 return GE_NONE;
364 static GSM_Error DCT4EnableVibra(GSM_StateMachine *s, bool enable)
366 /* Enables or disables vibra */
367 unsigned char Control[6] = {N7110_FRAME_HEADER,0x0C,
368 0x01, /* 0x01 = On, 0x00 = Off */
369 0x00};
371 if (!enable) Control[4] = 0x00;
372 return GSM_WaitFor (s, Control, 6, 0x1C, 4, ID_User3);
375 void DCT4SetVibraLevel(int argc, char *argv[])
377 GSM_DateTime Date;
378 unsigned int i,j;
380 /* Set vibra level */
381 unsigned char SetLevel[6] = {N7110_FRAME_HEADER,0x0E,
382 0x64, /* Vibra power (in percent) */
383 0x00};
385 GSM_Init(true);
387 CheckDCT4();
389 s.User.UserReplyFunctions=UserReplyFunctions4;
391 SetLevel[4] = atoi(argv[2]);
392 error=GSM_WaitFor (&s, SetLevel, 6, 0x1C, 4, ID_User3);
393 Print_Error(error);
395 error=DCT4EnableVibra(&s, true);
396 Print_Error(error);
398 for (i=0;i<3;i++) {
399 GSM_GetCurrentDateTime (&Date);
400 j=Date.Second;
401 while (j==Date.Second) {
402 my_sleep(10);
403 GSM_GetCurrentDateTime(&Date);
407 error=DCT4EnableVibra(&s, false);
408 Print_Error(error);
410 GSM_Terminate();
413 void DCT4VibraTest(int argc, char *argv[])
415 unsigned char ans[200];
417 if (CheckDCT4Only()!=GE_NONE) return;
419 s.User.UserReplyFunctions=UserReplyFunctions4;
421 error=DCT4EnableVibra(&s, true);
422 Print_Error(error);
424 printf("Press any key to continue...\n");
425 GetLine(stdin, ans, 99);
427 error=DCT4EnableVibra(&s, false);
428 Print_Error(error);
431 #ifdef DEBUG
432 static GSM_Error DCT4_ReplyResetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s)
434 switch (msg.Buffer[3]) {
435 case 0x05:
436 printf("Security code set to \"12345\"\n");
437 return GE_NONE;
438 case 0x06:
439 printf("Unknown reason. Can't reset your security code\n");
440 return GE_UNKNOWN;
442 return GE_UNKNOWNRESPONSE;
445 void DCT4ResetSecurityCode(int argc, char *argv[])
447 unsigned int i;
448 unsigned char ResetCode[30] = {0x00,0x06,0x03,0x04,0x01,
449 '1','2','3','4','5','6','7','8','9','0', /* Old code */
450 0x00,
451 '1','2','3','4','5',0x00,0x00,0x00,0x00,0x00, /* New code */
452 0x00};
454 if (CheckDCT4Only()!=GE_NONE) return;
456 s.User.UserReplyFunctions=UserReplyFunctions4;
458 error=GSM_WaitFor (&s, ResetCode, 27, 0x08, 4, ID_User2);
459 if (error == GE_UNKNOWN) {
460 if (answer_yes2("Try brutal force ?")) {
461 for (i=10000;i<9999999;i++) {
462 printf("Trying %i\n",i);
463 memset(ResetCode+6,0,22);
464 sprintf(ResetCode+5,"%i",i);
465 sprintf(ResetCode+16,"12345");
466 error=GSM_WaitFor (&s, ResetCode, 27, 0x08, 4, ID_User2);
467 if (error == GE_NONE) break;
470 } else Print_Error(error);
472 #endif
474 char SecLength;
476 static GSM_Error DCT4_ReplyGetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s)
478 if (msg.Length > 12) {
479 SecLength = msg.Buffer[13];
480 if ((msg.Buffer[17]+18) == msg.Length) {
481 printf("Security code is %s\n",msg.Buffer+18);
482 // DumpMessage(stdout, msg.Buffer, msg.Length);
485 return GE_NONE;
488 void DCT4GetSecurityCode(int argc, char *argv[])
490 GSM_Error error;
491 unsigned char getlen[]={0x00, 0x08, 0x01, 0x0C,
492 0x00, 0x23, //ID
493 0x00, 0x00, //Index
494 0x00, 0x00};
495 unsigned char read[]={0x00, 0x08, 0x02, 0x04,
496 0x00, 0x23, //ID
497 0x00, 0x00, //Index
498 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00,
500 0x00}; //Length
502 if (CheckDCT4Only()!=GE_NONE) return;
504 s.User.UserReplyFunctions=UserReplyFunctions4;
506 SecLength = 0;
507 error=GSM_WaitFor (&s, getlen, sizeof(getlen), 0x23, 1, ID_User1);
508 Print_Error(error);
509 if (SecLength != 0) {
510 read[17] = SecLength;
511 error=GSM_WaitFor (&s, read, sizeof(read), 0x23, 5, ID_User1);
512 Print_Error(error);
516 static GSM_Error DCT4_ReplyGetVoiceRecord(GSM_Protocol_Message msg, GSM_StateMachine *s)
518 int i=18,j;
519 unsigned char Buffer[100];
521 switch (msg.Buffer[3]) {
522 case 0x05:
523 dbgprintf("Part of voice record received\n");
524 if (msg.Length == 6) {
525 dbgprintf("Empty\n");
526 return GE_EMPTY;
528 *s->Phone.Data.VoiceRecord = 0;
529 while (i<msg.Length) {
530 s->Phone.Data.PhoneString[(*s->Phone.Data.VoiceRecord)++] = msg.Buffer[i+1];
531 s->Phone.Data.PhoneString[(*s->Phone.Data.VoiceRecord)++] = msg.Buffer[i];
532 i += 2;
534 return GE_NONE;
535 case 0x0D:
536 dbgprintf("Last part of voice record is %02x %02x\n",msg.Buffer[11],msg.Buffer[12]);
537 dbgprintf("Token is %02x\n",msg.Buffer[13]);
538 s->Phone.Data.PhoneString[0] = msg.Buffer[11];
539 s->Phone.Data.PhoneString[1] = msg.Buffer[12];
540 s->Phone.Data.PhoneString[2] = msg.Buffer[13];
541 return GE_NONE;
542 break;
543 case 0x31:
544 dbgprintf("Names of voice records received\n");
545 j = 33;
546 for (i=0;i<msg.Buffer[9];i++) {
547 memcpy(Buffer,msg.Buffer+(j+1),msg.Buffer[j]);
548 Buffer[msg.Buffer[j]] = 0;
549 Buffer[msg.Buffer[j]+1] = 0;
550 dbgprintf("%i. \"%s\"\n",i+1,DecodeUnicodeString(Buffer));
551 if (i==*s->Phone.Data.VoiceRecord) {
552 sprintf(s->Phone.Data.PhoneString,"%s.wav",DecodeUnicodeString(Buffer));
553 return GE_NONE;
555 if (i != msg.Buffer[9] - 1) {
556 j+=msg.Buffer[j] + 1;
557 if (msg.Buffer[j] == 0x00 && msg.Buffer[j+1]==0x00) j+=2;
558 j+=23;
561 return GE_EMPTY;
563 return GE_UNKNOWNRESPONSE;
566 void DCT4GetVoiceRecord(int argc, char *argv[])
568 /* Voice records names */
569 unsigned char ReqNames[200] = {
570 N7110_FRAME_HEADER,
571 0x30,0x01,0x55,0x00,0x00,0xFF,0xFF,0x01,0x01,0x55,0x55};
572 /* Voice record token */
573 unsigned char ReqToken[200] = {
574 N7110_FRAME_HEADER,0x0C,0x00,0x44,0x00,
575 0x00, /* Location: 0, 1, ... */
576 0x55,0x55};
577 /* Voice record part */
578 unsigned char ReqGet[200] = {
579 N7110_FRAME_HEADER,0x04,0x00,0x44,
580 0x00,0x00, /* Location: 0, 1, ... */
581 0x55,0x55,0x00,
583 0x00,0x00, /* Part Location */
584 0x00,0x00,0x00,
586 0x04, /* ??? */
588 0x00}; /* Token */
590 /* WAV file headers */
591 unsigned char WAV_Header[] = {
592 'R','I','F','F',
593 0x00,0x00,0x00,0x00, /* Length */
594 'W','A','V','E'};
595 unsigned char FMT_Header[] = {'f','m','t',' ',
596 0x14,0x00,0x00,0x00,0x31,0x00,0x01,0x00,0x40,0x1f,
597 0x00,0x00,0x59,0x06,0x00,0x00,0x41,0x00,0x00,0x00,
598 0x02,0x00,0x40,0x01,'f', 'a', 'c', 't', 0x04,0x00,
599 0x00,0x00,
600 0x00,0x73,0x00,0x00}; /* Seems to be some length */
601 unsigned char DATA_Header[] = {
602 'd','a','t','a',
603 0x00,0x00,0x00,0x00}; /* Length */
605 long wavfilesize=0;
606 unsigned char FileName[100], Buffer[10000], Token;
607 unsigned int Location, size=0, CurrentLocation = 0, TokenLocation;
608 int i;
609 FILE *WAVFile;
611 Location = atoi(argv[2]);
612 if (Location == 0x00) {
613 printf("Please numerate locations from 1\n");
614 return;
616 Location--;
618 GSM_Init(true);
620 CheckDCT4();
622 s.User.UserReplyFunctions=UserReplyFunctions4;
624 s.Phone.Data.VoiceRecord = &Location;
625 s.Phone.Data.PhoneString = FileName;
626 dbgprintf("Getting voice record name\n");
627 error=GSM_WaitFor (&s, ReqNames, 14, 0x4A, 4, ID_User4);
628 Print_Error(error);
630 s.Phone.Data.PhoneString = Buffer;
631 ReqToken[7] = Location;
632 dbgprintf("Getting voice record token\n");
633 error=GSM_WaitFor (&s, ReqToken, 10, 0x23, 4, ID_User4);
634 Print_Error(error);
635 TokenLocation = Buffer[0] * 256 + Buffer[1];
636 Token = Buffer[2];
638 WAVFile = fopen(FileName, "wb");
640 fwrite(&WAV_Header, 1, sizeof(WAV_Header), WAVFile);
641 fwrite(&FMT_Header, 1, sizeof(FMT_Header), WAVFile);
642 fwrite(&DATA_Header, 1, sizeof(DATA_Header), WAVFile);
644 s.Phone.Data.VoiceRecord = &size;
645 s.Phone.Data.PhoneString = Buffer;
646 ReqGet[7] = Location;
647 fprintf(stderr,"Getting voice record and saving to \"%s\": ",FileName);
648 while (1) {
649 dbgprintf("Getting next part of voice record\n");
650 fprintf(stderr,".");
651 error=GSM_WaitFor (&s, ReqGet, 18, 0x23, 4, ID_User4);
652 if (error == GE_NONE) {
653 wavfilesize += size;
654 fwrite(Buffer,1,size,WAVFile);
656 if (error == GE_EMPTY) break;
657 Print_Error(error);
658 CurrentLocation += 4;
659 ReqGet[11] = CurrentLocation / 256;
660 ReqGet[12] = CurrentLocation % 256;
661 if (CurrentLocation+4 > TokenLocation) break;
663 dbgprintf("Getting first part in last sequence of voice record\n");
664 for (i=255;i>=0;i--) {
665 ReqGet[16] = i;
666 ReqGet[17] = Token;
667 fprintf(stderr,".");
668 error=GSM_WaitFor (&s, ReqGet, 18, 0x23, 4, ID_User4);
669 if (error == GE_NONE) {
670 wavfilesize += size;
671 fwrite(Buffer,1,size,WAVFile);
672 break;
674 if (error != GE_EMPTY) Print_Error(error);
676 while (1) {
677 dbgprintf("Getting next part of last sequence in voice record\n");
678 CurrentLocation += 4;
679 ReqGet[11] = CurrentLocation / 256;
680 ReqGet[12] = CurrentLocation % 256;
681 fprintf(stderr,".");
682 error=GSM_WaitFor (&s, ReqGet, 18, 0x23, 4, ID_User4);
683 if (error == GE_NONE) {
684 wavfilesize += size;
685 fwrite(Buffer,1,size,WAVFile);
687 if (error == GE_EMPTY) break;
688 Print_Error(error);
690 fprintf(stderr,"\n");
692 wavfilesize += sizeof(WAV_Header) + sizeof(FMT_Header) + sizeof(DATA_Header);
693 WAV_Header[4] = (unsigned char)(wavfilesize % 256);
694 WAV_Header[5] = (unsigned char)(wavfilesize / 256);
695 WAV_Header[6] = (unsigned char)(wavfilesize / (256*256));
696 WAV_Header[7] = (unsigned char)(wavfilesize / (256*256*256));
698 /* FIXME */
699 FMT_Header[36] = (unsigned char)(((wavfilesize - 238) * 5 ) % 256);
700 FMT_Header[37] = (unsigned char)(((wavfilesize - 238) * 5 ) / 256);
701 FMT_Header[38] = (unsigned char)(((wavfilesize - 238) * 5 ) / (256*256));
702 FMT_Header[39] = (unsigned char)(((wavfilesize - 238) * 5 ) / (256*256*256));
704 wavfilesize = wavfilesize - 54 - 6;
705 DATA_Header[4] = (unsigned char)(wavfilesize % 256);
706 DATA_Header[5] = (unsigned char)(wavfilesize / 256);
707 DATA_Header[6] = (unsigned char)(wavfilesize / (256*256));
708 DATA_Header[7] = (unsigned char)(wavfilesize / (256*256*256));
710 fseek( WAVFile, 0, SEEK_SET);
711 fwrite(&WAV_Header, 1, sizeof(WAV_Header), WAVFile);
712 fwrite(&FMT_Header, 1, sizeof(FMT_Header), WAVFile);
713 fwrite(&DATA_Header, 1, sizeof(DATA_Header), WAVFile);
715 fclose(WAVFile);
717 GSM_Terminate();
720 static GSM_Error DCT4_ReplyGetBTInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
722 printf("device address %02x%02x%02x%02x%02x%02x\n",
723 msg.Buffer[9],msg.Buffer[10],msg.Buffer[11],
724 msg.Buffer[12],msg.Buffer[13],msg.Buffer[14]);
725 return GE_NONE;
728 static GSM_Error DCT4_ReplyGetSimlock(GSM_Protocol_Message msg, GSM_StateMachine *s)
730 int i;
732 switch (msg.Buffer[3]) {
733 case 0x0D:
734 dbgprintf("Simlock info received\n");
735 dbgprintf("Config_Data: ");
736 for (i=14;i<22;i++) {
737 dbgprintf("%02x",msg.Buffer[i]);
739 dbgprintf("\n");
740 dbgprintf("Profile_Bits: ");
741 for (i=22;i<30;i++) {
742 dbgprintf("%02x",msg.Buffer[i]);
744 dbgprintf("\n");
745 return GE_NONE;
746 case 0x13:
747 dbgprintf("Simlock info received\n");
748 if (msg.Buffer[58] == 0x05 && msg.Buffer[59] == 0x02) {
749 dbgprintf("SIM_PATH: ");
750 for (i=44;i<52;i++) {
751 dbgprintf("%02x",msg.Buffer[i]);
753 dbgprintf("\n");
754 printf("Simlock data : ");
755 for (i=60;i<63;i++) {
756 printf("%02x",msg.Buffer[i]);
758 printf("\n");
760 return GE_NONE;
762 return GE_UNKNOWNRESPONSE;
765 void DCT4Info(int argc, char *argv[])
767 unsigned char GetBTAddress[8] = {N6110_FRAME_HEADER, 0x09, 0x19, 0x01, 0x03, 0x06};
768 unsigned char GetSimlock[5] = {N6110_FRAME_HEADER, 0x12, 0x0D};
769 unsigned char value[10];
771 if (CheckDCT4Only()!=GE_NONE) return;
773 s.User.UserReplyFunctions=UserReplyFunctions4;
775 if (IsPhoneFeatureAvailable(s.Phone.Data.ModelInfo, F_BLUETOOTH)) {
776 printf("Bluetooth : ");
778 error=GSM_WaitFor (&s, GetBTAddress, 8, 0xD7, 4, ID_User6);
779 Print_Error(error);
782 error=GSM_WaitFor (&s, GetSimlock, 5, 0x53, 4, ID_User6);
783 Print_Error(error);
784 GetSimlock[4] = 0x0E;
785 error=GSM_WaitFor (&s, GetSimlock, 5, 0x53, 4, ID_User6);
786 Print_Error(error);
787 GetSimlock[3] = 0x0C;
788 error=GSM_WaitFor (&s, GetSimlock, 4, 0x53, 4, ID_User6);
789 Print_Error(error);
790 error=NOKIA_GetPhoneString(&s,"\x00\x03\x02\x07\x00\x08",6,0x1b,value,ID_User6,10);
791 Print_Error(error);
792 printf("UEM : %s\n",value);
795 static FILE *T9File;
796 int T9Size;
797 int T9FullSize;
799 static GSM_Error DCT4_ReplyGetT9(GSM_Protocol_Message msg, GSM_StateMachine *s)
801 T9FullSize = msg.Buffer[18] * 256 + msg.Buffer[19];
802 T9Size = msg.Length - 18;
803 fwrite(msg.Buffer+18,1,T9Size,T9File);
804 return GE_NONE;
807 void DCT4GetT9(int argc, char *argv[])
809 int i,T9Dictionary=0;
810 unsigned char req[] = {N7110_FRAME_HEADER, 0x04, 0x00, 0x5B,
811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, /* Start position */
813 0x00, 0x00,
814 0x02, 0xBC}; /* How many bytes to read */
816 if (CheckDCT4Only()!=GE_NONE) return;
818 T9File = fopen("T9", "w");
819 if (T9File == NULL) return;
821 s.User.UserReplyFunctions=UserReplyFunctions4;
823 i = 0;
824 while (1) {
825 req[12] = i / 256;
826 req[13] = i % 256;
827 if (i != 0) {
828 if (T9Dictionary - i < req[16]*256+req[17]) {
829 req[16] = (T9Dictionary - i) / 256;
830 req[17] = (T9Dictionary - i) % 256;
832 if (T9Dictionary - i == 0) break;
834 error=GSM_WaitFor (&s, req, 18, 0x23, 4, ID_User3);
835 Print_Error(error);
836 if (i==0) {
837 T9Dictionary = T9FullSize;
838 dbgprintf("T9 dictionary size is %i\n",T9Dictionary);
840 i+=T9Size;
843 fclose(T9File);
846 extern GSM_Error N6510_SetLight(GSM_StateMachine *s, N6510_PHONE_LIGHTS light, bool enable);
848 void DCT4SetLight(int argc, char *argv[])
850 int i;
851 N6510_PHONE_LIGHTS type;
852 bool enable;
854 if (mystrncasecmp(argv[2],"display",0)) { type = N6510_LIGHT_DISPLAY;
855 } else if (mystrncasecmp(argv[2],"keypad",0)) { type = N6510_LIGHT_KEYPAD;
856 } else if (mystrncasecmp(argv[2],"torch",0)) { type = N6510_LIGHT_TORCH;
857 } else {
858 printf("What lights should I enable (\"%s\") ?\n",argv[2]);
859 exit(-1);
862 if (mystrncasecmp(argv[3],"on",0)) { enable = true;
863 } else if (mystrncasecmp(argv[3],"off",0)) { enable = false;
864 } else {
865 printf("What should I do (\"%s\") ?\n",argv[3]);
866 exit(-1);
869 for (i=0;i<s.ConfigNum;i++) {
870 s.Config[i].StartInfo = "false";
873 GSM_Init(true);
875 CheckDCT4();
877 error=N6510_SetLight(&s, type, enable);
878 Print_Error(error);
880 GSM_Terminate();
883 void DCT4DisplayTest(int argc, char *argv[])
885 unsigned char ans[200];
886 unsigned char req0[] = {0x00, 0x08, 0x0D, 0x00, 0x0F, 0x00};
887 unsigned char req[] = {0x00, 0x08, 0x0E, 0x00, 0x12, 0x01, 0x00, 0x04,
888 0x09, /* test number */
889 0x00};
891 if (CheckDCT4Only()!=GE_NONE) return;
893 s.User.UserReplyFunctions=UserReplyFunctions4;
895 DCT4_SetPhoneMode(&s, DCT4_MODE_TEST);
897 s.Protocol.Functions->WriteMessage(&s, req0, 6, 0x40);
899 req[8] = atoi(argv[2]);
900 s.Protocol.Functions->WriteMessage(&s, req, 10, 0x40);
902 printf("Press any key to continue...\n");
903 GetLine(stdin, ans, 99);
905 DCT4_SetPhoneMode(&s, DCT4_MODE_NORMAL);
908 int ADC;
910 static GSM_Error DCT4_ReplyGetADC(GSM_Protocol_Message msg, GSM_StateMachine *s)
912 if (msg.Buffer[6] == 0xff && msg.Buffer[7] == 0xff) return GE_NONE;
913 switch (msg.Buffer[3]) {
914 case 0x10:
915 printf("raw ");
916 printf("%10i ",msg.Buffer[8]*256+msg.Buffer[9]);
917 break;
918 case 0x12:
919 printf("unit result ");
920 printf("%10i ",(msg.Buffer[8]*256+msg.Buffer[9])*ADC);
921 break;
923 return GE_NONE;
926 struct DCT4ADCInfo {
927 char *name;
928 char *unit;
929 int x;
932 static struct DCT4ADCInfo DCT4ADC[] = {
933 {"Battery voltage, divided:", "mV", 1},
934 {"Battery voltage, scaled:", "mV", 1},
935 {"Charger voltage:", "mV", 1},
936 {"Charger current:", "mA", 1},
937 {"Battery size indicator:", "Ohms",100},
938 {"Battery temperature:", "K", 1},
939 {"Headset interconnection:", "mV", 1},
940 {"Hook interconnection:", "mV", 1},
941 {"Light sensor:", "mV", 1},
942 {"Power amplifier temperature:", "K", 1},
943 {"VCXO temperature:", "K", 1},
944 {"Resistive keyboard 1/headint2:", "mV", 1},
945 {"Resistive keyboard 1/auxdet:", "mV", 1},
946 {"Initial battery voltage:", "mV", 1},
947 {"Battery Current:", "mA", 1},
948 {"Battery Current Fast:", "mA", 1},
950 {"", "", 1}
953 void DCT4GetADC(int argc, char *argv[])
955 int i = 0;
956 unsigned char GetRaw[] = {N6110_FRAME_HEADER, 0x0F,
957 0x00, /* Test number */
958 0x01};
959 unsigned char GetUnit[] = {N6110_FRAME_HEADER, 0x11,
960 0x00, /* Test number */
961 0x01};
963 if (CheckDCT4Only()!=GE_NONE) return;
965 s.User.UserReplyFunctions=UserReplyFunctions4;
967 while (1) {
968 printf(" %30s ",DCT4ADC[i].name);
969 GetRaw[4] = i;
970 error=GSM_WaitFor (&s, GetRaw, 6, 0x17, 4, ID_User3);
971 Print_Error(error);
972 GetUnit[4] = i;
973 ADC = DCT4ADC[i].x;
974 error=GSM_WaitFor (&s, GetUnit, 6, 0x17, 4, ID_User3);
975 Print_Error(error);
976 printf("%s\n",DCT4ADC[i].unit);
977 i++;
978 if (DCT4ADC[i].name[0] == 0x00) break;
982 static double RadioFreq;
983 static unsigned char RadioName[100];
985 static GSM_Error DCT4_ReplyTuneRadio(GSM_Protocol_Message msg, GSM_StateMachine *s)
987 int length;
988 unsigned char name[100];
990 switch (msg.Buffer[3]) {
991 case 0x09:
992 N6510_DecodeFMFrequency(&RadioFreq, msg.Buffer+16);
994 length = msg.Buffer[8];
995 memcpy(name,msg.Buffer+18,length*2);
996 name[length*2] = 0x00;
997 name[length*2+1] = 0x00;
998 CopyUnicodeString(RadioName,name);
999 smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(RadioName));
1000 return GE_NONE;
1001 case 0x15:
1002 case 0x16:
1003 smprintf(s,"Response for enabling radio/headset status received\n");
1004 if (msg.Buffer[5] == 0) {
1005 smprintf(s,"Connected\n");
1006 return GE_NONE;
1008 smprintf(s,"Probably not connected\n");
1009 return GE_PERMISSION;
1011 return GE_UNKNOWNRESPONSE;
1014 void DCT4TuneRadio(int argc, char *argv[])
1016 double Freq, diff;
1017 GSM_FMStation FMStation[50],FMStat;
1018 int i, j, num;
1019 bool found;
1021 unsigned char Enable[] = {N6110_FRAME_HEADER, 0x00, 0x00, 0x00};
1022 unsigned char Disable[] = {N6110_FRAME_HEADER, 0x01, 0x0E, 0x00};
1023 // unsigned char SetVolume[] = {N6110_FRAME_HEADER, 0x14,
1024 // 0x00, /* Volume level */
1025 // 0x00};
1026 // unsigned char MuteUnMute[] = {N6110_FRAME_HEADER, 0x0F,
1027 // 0x0C, /* 0x0B = mute, 0x0C = unmute */
1028 // 0x00};
1029 unsigned char SetFreq[] = {N6110_FRAME_HEADER, 0x08,
1030 0x08, 0x14, 0x00, 0x01,
1031 0x9A, 0x28}; /* Frequency */
1032 // unsigned char Find1[] = {N6110_FRAME_HEADER, 0x08,
1033 // 0x04, 0x14, 0x00, 0x00, 0x00, 0x00};
1034 unsigned char Find2[] = {N6110_FRAME_HEADER, 0x08,
1035 0x05, 0x14, 0x00, 0x00, 0x00, 0x00};
1036 // unsigned char SetStereo[] = {N6110_FRAME_HEADER, 0x19,
1037 // 0x0A, 0x00, 0x15};
1038 // unsigned char SetMono[] = {N6110_FRAME_HEADER, 0x19,
1039 // 0x09, 0x00, 0x96};
1041 GSM_Init(true);
1043 CheckDCT4();
1045 s.User.UserReplyFunctions=UserReplyFunctions4;
1047 FMStat.Location = 1;
1048 error = Phone->GetFMStation(&s,&FMStat);
1049 if (error != GE_NONE && error != GE_EMPTY) {
1050 printf("Phone seems not to support radio\n");
1051 GSM_Terminate();
1052 exit(-1);
1055 error=GSM_WaitFor (&s, Enable, 6, 0x3E, 4, ID_User3);
1056 if (error == GE_PERMISSION) {
1057 printf("Please connect headset. Required as antenna\n");
1058 GSM_Terminate();
1059 exit(-1);
1061 Print_Error(error);
1063 num=0;
1064 for (i=88;i<108;i++) {
1065 fprintf(stderr,"%cSearching: %i percent",13,(i-88)*100/(108-88));
1066 Freq = i;
1067 N6510_EncodeFMFrequency(Freq, SetFreq+8);
1068 error=GSM_WaitFor (&s, SetFreq, 10, 0x3E, 4, ID_User3);
1069 Print_Error(error);
1071 error=GSM_WaitFor (&s, Find2, 10, 0x3E, 4, ID_User3);
1072 Print_Error(error);
1073 found = false;
1074 for (j=0;j<num;j++) {
1075 if (FMStation[j].Frequency > RadioFreq) {
1076 diff = FMStation[j].Frequency - RadioFreq;
1077 } else {
1078 diff = RadioFreq - FMStation[j].Frequency;
1080 if (diff <= 0.2) {
1081 dbgprintf("diff is %f\n",diff);
1082 found = true;
1083 break;
1086 if (!found) {
1087 dbgprintf("Adding %f, num %i\n",RadioFreq,num);
1088 FMStation[num].Frequency = RadioFreq;
1089 CopyUnicodeString(FMStation[num].StationName,RadioName);
1090 num++;
1093 fprintf(stderr,"%cSearching: %i percent",13,100);
1094 fprintf(stderr,"\n\n");
1096 i=0;
1097 while(1) {
1098 if (i==num || i==num-1) break;
1099 if (FMStation[i].Frequency > FMStation[i+1].Frequency) {
1100 memcpy(&FMStat,&FMStation[i],sizeof(GSM_FMStation));
1101 memcpy(&FMStation[i],&FMStation[i+1],sizeof(GSM_FMStation));
1102 memcpy(&FMStation[i+1],&FMStat,sizeof(GSM_FMStation));
1103 i = 0;
1104 continue;
1106 i++;
1108 for (i=0;i<num;i++) {
1109 fprintf(stderr,"%02i.",i+1);
1110 if (FMStation[i].Frequency < 100) fprintf(stderr," ");
1111 fprintf(stderr,"%.1f MHz - \"%s\" \n",
1112 FMStation[i].Frequency,
1113 DecodeUnicodeString(FMStation[i].StationName));
1116 if (answer_yes2("Do you want to save found stations")) {
1117 fprintf(stderr,"Deleting old FM stations: ");
1118 error=Phone->ClearFMStations(&s);
1119 Print_Error(error);
1120 fprintf(stderr,"Done\n");
1121 for (i=0;i<num;i++) {
1122 FMStation[i].Location = i+1;
1123 error=Phone->SetFMStation(&s,&FMStation[i]);
1124 Print_Error(error);
1125 fprintf(stderr,"%cWriting: %i percent",13,(i+1)*100/num);
1127 fprintf(stderr,"\n");
1130 error=GSM_WaitFor (&s, Disable, 6, 0x3E, 4, ID_User3);
1131 Print_Error(error);
1133 GSM_Terminate();
1136 static GSM_Reply_Function UserReplyFunctions4[] = {
1138 #ifdef DEBUG
1139 {DCT4_ReplyResetSecurityCode, "\x08",0x03,0x05,ID_User2 },
1140 {DCT4_ReplyResetSecurityCode, "\x08",0x03,0x06,ID_User2 },
1141 #endif
1143 {DCT4_ReplyGetADC, "\x17",0x03,0x10,ID_User3 },
1144 {DCT4_ReplyGetADC, "\x17",0x03,0x12,ID_User3 },
1146 {DCT4_ReplySetPPS, "\x1b",0x03,0x05,ID_User1 },
1147 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_User6 },
1149 {DCT4_ReplyVibra, "\x1C",0x03,0x0D,ID_User3 },
1150 {DCT4_ReplyVibra, "\x1C",0x03,0x0F,ID_User3 },
1152 {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x05,ID_User1 },
1153 {DCT4_ReplyGetT9, "\x23",0x03,0x05,ID_User3 },
1154 {DCT4_ReplyGetVoiceRecord, "\x23",0x03,0x05,ID_User4 },
1155 {DCT4_ReplyGetVoiceRecord, "\x23",0x03,0x0D,ID_User4 },
1156 {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x0D,ID_User1 },
1158 {DCT4_ReplyTestsStartup, "\x35",0x02,0x01,ID_User3 },
1159 {DCT4_ReplyTestsStartup, "\x35",0x02,0x02,ID_User3 },
1160 {DCT4_ReplyTestsNames, "\x35",0x02,0x03,ID_User1 },
1161 {DCT4_ReplyTestsStatus, "\x35",0x02,0x04,ID_User2 },
1163 {DCT4_ReplyTuneRadio, "\x3E",0x03,0x09,ID_User3 },
1164 {DCT4_ReplyTuneRadio, "\x3E",0x03,0x15,ID_User3 },
1165 {DCT4_ReplyTuneRadio, "\x3E",0x03,0x15,ID_SetFMStation},
1166 {DCT4_ReplyTuneRadio, "\x3E",0x03,0x16,ID_User3 },
1168 {DCT4_ReplyGetVoiceRecord, "\x4A",0x03,0x31,ID_User4 },
1170 {DCT4_ReplyGetSimlock, "\x53",0x03,0x0D,ID_User6 },
1171 {DCT4_ReplyGetSimlock, "\x53",0x03,0x13,ID_User6 },
1173 {DCT4_ReplyGetBTInfo, "\xD7",0x03,0x0A,ID_User6 },
1175 {NULL, "\x00",0x00,0x00,ID_None }
1178 #endif
1180 /* How should editor hadle tabs in this file? Add editor commands here.
1181 * vim: noexpandtab sw=8 ts=8 sts=8: