Branch update for mygnokii2002_03_17_19_29nl
[gnokii.git] / gnokii / gnokii.c
index 1cbe8fe..25f66ec 100644 (file)
@@ -286,6 +286,7 @@ static char *print_error(GSM_Error e)
         case GE_INVALIDBOOKMARKLOCATION:  return "Invalid or empty WAP bookmark location";
         case GE_INSIDESETTINGSMENU:       return "Inside WAP Settings menu. Please leave it and try again";
         case GE_INVALIDSETTINGSLOCATION:  return "Invalid or empty WAP settings location";
+        case GE_EMPTYSMSC:                return "Empty SMSC number. Use --smsc";
        default:                          return "Unknown error.";
        }
 }
@@ -478,8 +479,8 @@ int GSM_SendMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int
   int w,i;
   
   struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
+             { "smscno",       required_argument, NULL, '2'},
+             { "smsc",         required_argument, NULL, '1'},
             { "name",         required_argument, NULL, '3'},
              { "unicode",      no_argument,       NULL, '4'},
              { "profilestyle", no_argument,       NULL, '5'},
@@ -552,7 +553,7 @@ int GSM_SendMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int
     if (error == GE_SMSSENDOK) {
       fprintf(stdout, _("SMS %i/%i sent OK !\n"),w+1,MultiSMS->number);
     } else {
-      fprintf(stdout, _("SMS %i/%i, sending failed (error=%d)\n"),w+1,MultiSMS->number, error);
+      fprintf(stdout, _("SMS %i/%i, sending failed (%d, %s)\n"),w+1,MultiSMS->number, error,print_error(error));
     }
 
   }
@@ -570,8 +571,8 @@ static int GSM_SaveMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argn
   GSM_SMSMessage SMSold;
 
   struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
+             { "smscno",       required_argument, NULL, '2'},
+             { "smsc",         required_argument, NULL, '1'},
             { "name",         required_argument, NULL, '3'},
              { "unicode",      no_argument,       NULL, '4'},
              { "profilestyle", no_argument,       NULL, '5'},
@@ -680,7 +681,7 @@ static int GSM_SaveMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argn
     if (error == GE_NONE)
       fprintf(stdout, _("SMS %i/%i saved at location %i !\n"),w+1,MultiSMS->number,MultiSMS->SMS[w].MessageNumber);
     else
-      fprintf(stdout, _("SMS %i/%i saving failed (error=%d, location=%i)\n"), w+1, MultiSMS->number, error,MultiSMS->SMS[w].Location);
+      fprintf(stdout, _("SMS %i/%i saving failed (%d, %s, location=%i)\n"), w+1, MultiSMS->number,error,print_error(error),MultiSMS->SMS[w].Location);
   }
 
   GSM->Terminate();  
@@ -943,6 +944,7 @@ static int usage(void)
   fprintf(stdout, _(
 "          gnokii --sniff [port]\n"
 "          gnokii --decodefile file\n"
+"          gnokii --getbinringfromfile file name offset file2\n"
   ));
 #endif
 
@@ -1141,6 +1143,7 @@ int main(int argc, char *argv[])
 #ifdef DEBUG
     { "sniff",              optional_argument, NULL, OPT_SNIFFER    },// Will show datas from port
     { "decodefile",         required_argument, NULL, OPT_DECODEFILE },//decode input file
+    { "getbinringfromfile", required_argument, NULL, OPT_GETBINRINGFROMFILE },
 #endif
 #endif /* UCLINUX */
 
@@ -1168,6 +1171,7 @@ int main(int argc, char *argv[])
 #ifdef DEBUG
     { OPT_SNIFFER,           0, 1, 0 },
     { OPT_DECODEFILE,        1, 1, 0 },
+    { OPT_GETBINRINGFROMFILE,4, 4, 0 },
 #endif
 
     { OPT_SETDATETIME,       0, 5, 0 },
@@ -1333,6 +1337,7 @@ int main(int argc, char *argv[])
 #ifdef DEBUG
     case OPT_SNIFFER:               rc = sniff(nargc, nargv);       break;
     case OPT_DECODEFILE:            rc = decodefile(nargc, nargv);  break;
+    case OPT_GETBINRINGFROMFILE:    rc = getbinringfromfile(nargc, nargv);break;
 #endif                                 
        
     // Now, options with arguments
@@ -1434,7 +1439,141 @@ int main(int argc, char *argv[])
 /* Restores various phone settings from one file */
 int restoresettings(char *argv[])
 {
-  fprintf(stdout,_("Work in progress. Not usefull now. Sorry\n"));
+  GSM_Backup Backup;
+  GSM_PhonebookEntry pbk;
+
+  int confirm;
+  char ans[4];
+
+  int i,pos;
+
+  GSM_MemoryStatus SIMMemoryStatus = {GMT_SM, 0, 0};
+  GSM_MemoryStatus PhoneMemoryStatus = {GMT_ME, 0, 0};
+
+  if (GSM_ReadBackupFile(argv[0], &Backup)!=GE_NONE) return 1;
+
+  fbusinit(NULL);
+
+  if (Backup.SIMPhonebookUsed!=0) {
+    confirm=-1;    
+    while (confirm < 0) {
+      fprintf(stderr, _("Restore SIM phonebook ? "));
+      GetLine(stdin, ans, 99);
+      if (!strcmp(ans, "yes")) confirm = 1;
+      if (!strcmp(ans, "no" )) confirm = 0;
+    }
+    if (confirm==1) {
+      if (GSM->GetMemoryStatus(&SIMMemoryStatus) != GE_NONE) {
+        fprintf(stderr,_("Error getting memory status !\n"));
+        GSM->Terminate();
+      }
+      i=0;pos=1;
+
+      while ((pos-1)!=SIMMemoryStatus.Used+SIMMemoryStatus.Free) {
+        pbk.Location=pos;
+        pbk.MemoryType=GMT_SM;
+        pbk.Name[0]=0;
+        pbk.Number[0]=0;
+        pbk.SubEntriesCount = 0;
+        if (i<Backup.SIMPhonebookUsed) {
+          if (Backup.SIMPhonebook[i].Location==pbk.Location) {
+            pbk=Backup.SIMPhonebook[i];
+            i++;
+//#ifdef DEBUG
+//            fprintf(stdout,_("Copying from backup\n"));
+//#endif
+          }
+        }
+//#ifdef DEBUG
+//        fprintf(stdout,_("Setting location %i\n"),pbk.Location);
+//#endif
+        GSM->WritePhonebookLocation(&pbk);
+       fprintf(stderr,_("."));
+        pos++;
+      }
+      fprintf(stderr,_("\n"));
+    }
+  }
+  if (Backup.PhonePhonebookUsed!=0) {
+    confirm=-1;    
+    while (confirm < 0) {
+      fprintf(stderr, _("Restore phone phonebook ? "));
+      GetLine(stdin, ans, 99);
+      if (!strcmp(ans, "yes")) confirm = 1;
+      if (!strcmp(ans, "no" )) confirm = 0;
+    }
+    if (confirm==1) {
+      if (GSM->GetMemoryStatus(&PhoneMemoryStatus) != GE_NONE) {
+        fprintf(stderr,_("Error getting memory status !\n"));
+        GSM->Terminate();
+      }
+
+      i=0;pos=1;
+
+      while ((pos-1)!=PhoneMemoryStatus.Used+PhoneMemoryStatus.Free) {
+        pbk.Location=pos;
+        pbk.MemoryType=GMT_ME;
+        pbk.Name[0]=0;
+        pbk.Number[0]=0;
+        pbk.SubEntriesCount = 0;
+        if (i<Backup.PhonePhonebookUsed) {
+          if (Backup.PhonePhonebook[i].Location==pbk.Location) {
+            pbk=Backup.PhonePhonebook[i];
+            i++;
+//#ifdef DEBUG
+//            fprintf(stdout,_("Copying from backup\n"));
+//#endif
+          }
+        }
+//#ifdef DEBUG
+//        fprintf(stdout,_("Setting location %i\n"),pbk.Location);
+//#endif
+        GSM->WritePhonebookLocation(&pbk);
+       fprintf(stderr,_("."));
+        pos++;
+      }
+      fprintf(stderr,_("\n"));
+    }
+  }
+  if (Backup.CallerAvailable==true) {
+    confirm=-1;    
+    while (confirm < 0) {
+      fprintf(stderr, _("Restore caller groups ? "));
+      GetLine(stdin, ans, 99);
+      if (!strcmp(ans, "yes")) confirm = 1;
+      if (!strcmp(ans, "no" )) confirm = 0;
+    }
+    if (confirm==1) {
+      for (i=0;i<5;i++) GSM->SetBitmap(&Backup.CallerGroups[i]);
+    }
+  }
+  if (Backup.OperatorLogoAvailable==true) {
+    confirm=-1;    
+    while (confirm < 0) {
+      fprintf(stderr, _("Restore operator logo ? "));
+      GetLine(stdin, ans, 99);
+      if (!strcmp(ans, "yes")) confirm = 1;
+      if (!strcmp(ans, "no" )) confirm = 0;
+    }
+    if (confirm==1) {
+      GSM->SetBitmap(&Backup.OperatorLogo);
+    }
+  }
+  if (Backup.StartupLogoAvailable==true) {
+    confirm=-1;    
+    while (confirm < 0) {
+      fprintf(stderr, _("Restore startup logo ? "));
+      GetLine(stdin, ans, 99);
+      if (!strcmp(ans, "yes")) confirm = 1;
+      if (!strcmp(ans, "no" )) confirm = 0;
+    }
+    if (confirm==1) {
+      GSM->SetBitmap(&Backup.StartupLogo);
+    }
+  }
+
+  GSM->Terminate();
+
   return 0;
 }
 
@@ -1453,7 +1592,7 @@ int backupsettings(char *argv[])
 
   fprintf(stderr,_("Backup phonebook from SIM..."));
   Backup.SIMPhonebookUsed=0;
-  if (GSM->GetMemoryStatus(&SIMMemoryStatus) == GE_NONE) {//FIXME
+  if (GSM->GetMemoryStatus(&SIMMemoryStatus) == GE_NONE) {
     Backup.SIMPhonebookSize=SIMMemoryStatus.Used+SIMMemoryStatus.Free;
 
     PbkEntry.MemoryType=GMT_SM;
@@ -1528,11 +1667,10 @@ int backupsettings(char *argv[])
   Backup.OperatorLogoAvailable=true;
   Backup.OperatorLogo.type=GSM_7110OperatorLogo;
   if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
-    Backup.OperatorLogoAvailable=true;
     Backup.OperatorLogo.type=GSM_OperatorLogo;
     if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
       Backup.OperatorLogoAvailable=false;
-      fprintf(stderr,_("Error\n"));
+     fprintf(stderr,_("Error\n"));
     } else fprintf(stderr,_("Done\n"));
   } else fprintf(stderr,_("Done\n"));
 
@@ -1574,9 +1712,6 @@ int presskeysequence(char *argv[])
   
   sleep(1);
 
-  /* We need to make sure that the init is finished to avoid interrupted */
-  /* multiframe packets... */
-
   fbusinit(NULL);
   
   for (i=0;i<strlen(argv[0]);i++)
@@ -1640,8 +1775,8 @@ int sendsms(int argc, char *argv[])
   GSM_UDH SMSUDHType=GSM_NoUDH;
 
   struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
+             { "smscno",       required_argument, NULL, '2'},
+             { "smsc",         required_argument, NULL, '1'},
              { "long",        required_argument, NULL, '3'},
              { "enablevoice",  no_argument,       NULL, '4'},
             { "disablevoice", no_argument,       NULL, '5'},
@@ -1826,8 +1961,8 @@ int savesms(int argc, char *argv[])
   bool interactive=false;
 
   struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
+             { "smscno",       required_argument, NULL, '2'},
+             { "smsc",         required_argument, NULL, '1'},
              { "long",        required_argument, NULL, '3'},
              { "enablevoice",  no_argument,       NULL, '4'},
             { "disablevoice", no_argument,       NULL, '5'},
@@ -2120,11 +2255,8 @@ int getsms(int argc, char *argv[])
      int i;
      
      /* [end] can be only argv[4] */
-     if (argv[4][0] == '-') {
-        end_message = start_message;
-     } else {
-        end_message = atoi(argv[4]);
-     }
+     if (argv[4][0] == '-') { end_message = start_message; }
+                       else { end_message = atoi(argv[4]); }
 
      /* parse all options (beginning with '-' */
      while ((i = getopt(argc, argv, "f:")) != -1) {
@@ -2183,16 +2315,12 @@ int getsms(int argc, char *argv[])
           switch (message.Status)
           {
            case  GSS_SENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(read)\n"));
-                else
-                 fprintf(stdout, _("(sent)\n"));
+                if (message.folder==0) fprintf(stdout, _("(read)\n")); //GST_INBOX
+                                  else fprintf(stdout, _("(sent)\n"));
                break;
            case  GSS_NOTSENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(unread)\n"));
-                else
-                 fprintf(stdout, _("(not sent)\n"));
+                if (message.folder==0) fprintf(stdout, _("(unread)\n")); //GST_INBOX
+                                  else fprintf(stdout, _("(not sent)\n"));
                break;
            case  GSS_UNKNOWN:
                fprintf(stdout, _("(not known :-()\n"));
@@ -2245,16 +2373,12 @@ int getsms(int argc, char *argv[])
          switch (message.Status)
            {
            case  GSS_SENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(read)\n"));
-                else
-                 fprintf(stdout, _("(sent)\n"));
+                if (message.folder==0) fprintf(stdout, _("(read)\n")); //GST_INBOX
+                                  else fprintf(stdout, _("(sent)\n"));
                break;
            case  GSS_NOTSENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(unread)\n"));
-                else
-                 fprintf(stdout, _("(not sent)\n"));
+                if (message.folder==0) fprintf(stdout, _("(unread)\n")); //GST_INBOX
+                                  else fprintf(stdout, _("(not sent)\n"));
                break;
             case  GSS_UNKNOWN:
                 fprintf(stdout, _("(not known :-()\n"));
@@ -3277,7 +3401,7 @@ int setlogo(int argc, char *argv[])
           bitmap.type=GSM_StartupLogo;
           bitmap.width=84;
           bitmap.height=48;
-         bitmap.size=bitmap.width*bitmap.height/8;
+         bitmap.size=GSM_GetBitmapSize(&bitmap);
           num=argv[1][0]-'0';
           if (num>=1 && num<=3) {
            bitmap.number=num;
@@ -3391,7 +3515,7 @@ int setlogo(int argc, char *argv[])
          strncpy(bitmap.netcode,"000 00",7);
          bitmap.width=72;
          bitmap.height=14;
-         bitmap.size=bitmap.width*bitmap.height/8;
+         bitmap.size=GSM_GetBitmapSize(&bitmap);
          GSM_ClearBitmap(&bitmap);
        }
         if (!strcmp(argv[0],"7110op"))
@@ -3400,7 +3524,7 @@ int setlogo(int argc, char *argv[])
          strncpy(bitmap.netcode,"000 00",7);
          bitmap.width=78;
          bitmap.height=21;
-          bitmap.size=(bitmap.width*bitmap.height + 7)/8;
+          bitmap.size=GSM_GetBitmapSize(&bitmap);
          GSM_ClearBitmap(&bitmap);
        }
        /* FIX ME: how to remove startup and group logos ? */
@@ -7659,53 +7783,34 @@ int getringtone(int argc, char *argv[])
   GSM_Error error;
   GSM_Ringtone SMringtone;
 
-  int i;
-  
-  char model[64];
-
-  FILE *file;
-
   ringtone.location=1;
   if (argc>1) ringtone.location=atoi(argv[1]);
 
   /* Initialise the GSM interface. */
   fbusinit(NULL);
 
-  error=GSM->GetBinRingtone(&ringtone);
-
-  while (GSM->GetModel(model)  != GE_NONE)
-    sleep(1);
-
-  GSM->Terminate();
+  error=GSM_GetPhoneRingtone(&ringtone,&SMringtone);
 
   fprintf(stdout, _("Downloaded ringtone, location %i: "),ringtone.location);
   
   switch (error) {
     case GE_NONE:
       fprintf(stdout, _("get succeeded!\n"));
-      fprintf(stdout, _("Name: %s (binary format)\n"),ringtone.name);
+      /* In 33.. we have normal "Smart Messaging" format */
+      if (GetModelFeature (FN_RINGTONES)==F_RING_SM) {
+        fprintf(stdout, _("Name: %s (normal format)\n"),SMringtone.name);
+        GSM_SaveRingtoneFileOnConsole(argv[0], &SMringtone);   
+      } else {
+        fprintf(stdout, _("Name: %s (binary format)\n"),ringtone.name);
+        GSM_SaveBinRingtoneFile(argv[0], &ringtone);
+      }
+      GSM->Terminate();
+      return 0;
       break;
     case GE_INVALIDRINGLOCATION:
       fprintf(stdout, _("invalid location %i!\n"),ringtone.location);
       break;
     case GE_UNKNOWNMODEL:
-    
-      /* In 3310 we have normal "Smart Messaging" format */
-      if (GetModelFeature (FN_RINGTONES)==F_RING_SM) {
-      
-        i=7;
-       if (ringtone.frame[9]==0x4a && ringtone.frame[10]==0x3a) i=8;
-       ringtone.frame[i]=0x02;
-       
-        GSM_UnPackRingtone(&SMringtone, ringtone.frame+i, ringtone.length-i);
-
-        fprintf(stdout, _("Name: %s (normal format)\n"),SMringtone.name);
-
-        GSM_SaveRingtoneFileOnConsole(argv[0], &SMringtone);
-       
-       return 0;
-      }
-
       fprintf(stdout, _("mygnokii doesn't know format for this model!\n"));
       break;
     case GE_NOTIMPLEMENTED:
@@ -7715,21 +7820,10 @@ int getringtone(int argc, char *argv[])
       fprintf(stdout, _("not supported by this model!\n"));
       break;
   }
-  
-  if (error!=GE_NONE)
-    return(-1);
-  
-  file = fopen(argv[0], "wb");
-      
-  if (!file)
-    return(GE_CANTOPENFILE);
 
-  fwrite(ringtone.frame, 1, ringtone.length, file);    
-  
-  fclose(file);
+  GSM->Terminate();
   
-  return 0;
-
+  return(-1);
 }
 
 int binringtoneconvert(int argc, char *argv[])
@@ -8932,7 +9026,7 @@ int savephonebookentry(int argc, char *argv[])
 
       /* Put entry into SMS structure */
 #ifndef UCLINUX
-      if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) {
+      if (GetModelFeature(FN_PHONEBOOK)==F_PBK71INT) {
         GSM_SavePhonebookEntryToSMS(&MultiSMS,&entry,21);
       } else
 #endif /* UCLINUX */
@@ -8979,7 +9073,7 @@ int sendphonebookentry(int argc, char *argv[])
     case GE_NONE:
 
       /* Put entry into SMS structure */
-      if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) {
+      if (GetModelFeature(FN_PHONEBOOK)==F_PBK71INT) {
         GSM_SavePhonebookEntryToSMS(&MultiSMS,&entry,21);
       } else {
         GSM_SavePhonebookEntryToSMS(&MultiSMS,&entry,10);
@@ -8999,4 +9093,76 @@ int sendphonebookentry(int argc, char *argv[])
   return 0;
 }
 
+#ifdef DEBUG
+int getbinringfromfile(int argc, char *argv[])
+{
+  FILE *file;
+  int i,j;
+  bool found;
+  GSM_BinRingtone binring,ringtone;
+
+  fprintf(stdout,_("Offset %ld\n"),atol(argv[2]));
+
+  file = fopen(argv[0], "rb");
+
+  if (!file) return(GE_CANTOPENFILE);
+
+  fseek(file,atol(argv[2]),0);
+  
+  ringtone.length=fread(ringtone.frame, 1, 900, file);
+
+  fclose(file);
+
+  i=0;found=false;
+  while (true) {
+    if (ringtone.frame[i  ]==0x00 && ringtone.frame[i+1]==0x02 && 
+        ringtone.frame[i+2]==0xFC && ringtone.frame[i+3]==0x09) {
+      found=true;
+      break;
+    }
+    i++;
+    if (i==ringtone.length-3) break;
+  }
+
+  if (!found) {
+    fprintf(stdout,_("Start not found\n"));
+    return (-1);
+  }
+
+  j=0;found=false;
+  while (true) {
+    if (ringtone.frame[j]==0x07 && ringtone.frame[j+1]==0x0B) {
+      found=true;
+      break;
+    }
+    j++;
+    if (j==ringtone.length-2) break;
+  }
+
+  if (!found) {
+    fprintf(stdout,_("End not found\n"));
+    return (-1);
+  }
+
+  binring.length=0;
+  binring.frame[binring.length++]=0x00;
+  binring.frame[binring.length++]=0x00;
+  binring.frame[binring.length++]=0x0C;
+  binring.frame[binring.length++]=0x01;
+  binring.frame[binring.length++]=0x2C;
+  
+  memcpy(binring.frame+binring.length,argv[1],strlen(argv[1]));
+  binring.length=binring.length+strlen(argv[1]);
+
+  binring.frame[binring.length++]=0x00;
+
+  memcpy(binring.frame+binring.length,ringtone.frame+i,j-i+2);
+  binring.length=binring.length+j-i+2;
+
+  GSM_SaveBinRingtoneFile(argv[3], &binring); 
+
+  return GE_NONE;
+}
+#endif
+
 #endif /* UCLINUX */