Update: orig2001_12_04_22_45 -> orig2001_12_14_20_46 lace bp_lace_writephonebook
authorshort <>
Fri, 14 Dec 2001 20:54:44 +0000 (20:54 +0000)
committershort <>
Fri, 14 Dec 2001 20:54:44 +0000 (20:54 +0000)
14 files changed:
Docs/protocol/nk6110.txt
common/data/at-emulator.c
common/gsm-error.c
common/gsm-sms.c
common/gsm-statemachine.c
common/phones/atgen.c
common/phones/nk7110.c
gnokii/gnokii.c
include/gnokii.h
include/gsm-common.h
include/gsm-sms.h
include/phones/nk7110.h
po/pl.po
xgnokii/Makefile

index a4f35ed..baac106 100644 (file)
@@ -298,9 +298,9 @@ Correct format is FBUS version 2/Direct IRDA/MBUS version 2
                               0x05: 5 second
                               0x0a: 10 second
                               0x0f: 15 second
-                              0x1e: 20 second
-                              0x14: 25 second
-                              0x19: 30 second
+                              0x14: 20 second
+                              0x19: 25 second
+                              0x1e: 30 second
                             where divtype:
                               0x02: all diverts for all call types ?
                                     Found only, when deactivate all diverts for all call types (with call type 0x00)
index a981388..e952df2 100644 (file)
   calling code in gsm-api.c. Inspired by and in places copied from the Linux
   kernel AT Emulator IDSN code by Fritz Elfert and others.
   
-  $Log$
-  Revision 1.1.1.1.2.1  2001/11/27 22:48:37  short
-  Update: orig2001_11_27_05_17 -> orig2001_11_27_22_58
-
-  Revision 1.1.1.2  2001/11/27 22:01:13  short
-  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Tue Nov 27 22:58 CET 2001
-
-  Revision 1.6  2001/11/27 12:19:01  pkot
-  Cleanup, indentation, ANSI complaint preprocesor symbols (Jan Kratochvil, me)
-
-  Revision 1.5  2001/11/08 16:34:19  pkot
-  Updates to work with new libsms
-
-  Revision 1.4  2001/07/03 15:27:03  pkot
-  AT commands for SMS handling support (Tamas Bondar)
-  Small at-emulator code cleanup (me)
-
-  Revision 1.3  2001/02/21 19:56:59  chris
-  More fiddling with the directory layout
-
-
 */
 
 #define                __data_at_emulator_c
index 93a0595..8dfdfa9 100644 (file)
   Error codes.
 
   $Log$
-  Revision 1.1.1.1  2001/11/25 21:58:58  short
-  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
+  Revision 1.1.1.1.2.1  2001/12/14 20:54:44  short
+  Update: orig2001_12_04_22_45 -> orig2001_12_14_20_46
+
+  Revision 1.1.1.2  2001/12/14 19:48:52  short
+  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Fri Dec 14 20:46 CET 2001
+
+  Revision 1.3  2001/12/14 14:37:41  pkot
+  Cleanups. Call divert support for at and 7110 series
 
   Revision 1.2  2001/11/08 16:34:19  pkot
   Updates to work with new libsms
@@ -37,7 +43,7 @@ char *print_error(GSM_Error e)
        case GE_TIMEOUT:                  return "Command timed out.";
        case GE_TRYAGAIN:                 return "Try again.";
        case GE_INVALIDSECURITYCODE:      return "Invalid Security code.";
-       case GE_NOTIMPLEMENTED:           return "Command called isn't implemented in model.";
+       case GE_NOTIMPLEMENTED:           return "Called command is not implemented for the used model.";
        case GE_INVALIDSMSLOCATION:       return "Invalid SMS location.";
        case GE_INVALIDPHBOOKLOCATION:    return "Invalid phonebook location.";
        case GE_INVALIDMEMORYTYPE:        return "Invalid type of memory.";
index a06c3c5..6006de5 100644 (file)
@@ -50,7 +50,7 @@ static struct udh_data headers[] = {
 
 /* This function implements packing of numbers (SMS Center number and
    destination number) for SMS sending function. */
-static int SemiOctetPack(char *Number, unsigned char *Output, SMS_NumberType type)
+int SemiOctetPack(char *Number, unsigned char *Output, SMS_NumberType type)
 {
        unsigned char *IN = Number;  /* Pointer to the input number */
        unsigned char *OUT = Output; /* Pointer to the output */
index c8638e4..a65583a 100644 (file)
@@ -199,7 +199,7 @@ GSM_Error SM_Block(GSM_Statemachine *state, GSM_Data *data, int waitfor)
 
                dprintf("SM_Block Retry - %d\n\r", retry);
                SM_Reset(state);
-               if (retry<2) SM_SendMessage(state, state->LastMsgSize, state->LastMsgType, state->LastMsg);
+               if (retry < 2) SM_SendMessage(state, state->LastMsgSize, state->LastMsgType, state->LastMsg);
        }
 
        return GE_TIMEOUT;
index 48d39bb..436523f 100644 (file)
   This file provides functions specific to generic at command compatible
   phones. See README for more details on supported mobile phones.
 
-  $Log$
-  Revision 1.1.1.1.2.1  2001/11/27 04:37:59  short
-  Update: orig2001_11_25_22_56 -> orig2001_11_27_05_17
-
-  Revision 1.1.1.2  2001/11/27 04:19:30  short
-  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Tue Nov 27 05:17 CET 2001
-
-  Revision 1.7  2001/11/26 18:06:08  pkot
-  Checking for *printf functions, N_(x) for localization, generic ARRAY_LEN, SAFE_STRNCPY, G_GNUC_PRINTF (Jan Kratochvil)
-
-  Revision 1.6  2001/11/19 13:03:18  pkot
-  nk3110.c cleanup
-
-  Revision 1.5  2001/11/08 16:49:19  pkot
-  Cleanups
-
-  Revision 1.4  2001/08/20 23:36:27  pkot
-  More cleanup in AT code (Manfred Jonsson)
-
-  Revision 1.3  2001/08/20 23:27:37  pkot
-  Add hardware shakehand to the link layer (Manfred Jonsson)
-
-  Revision 1.2  2001/08/09 11:51:39  pkot
-  Generic AT support updates and cleanup (Manfred Jonsson)
-
-  Revision 1.1  2001/07/27 00:02:21  pkot
-  Generic AT support for the new structure (Manfred Jonsson)
-
 */
 
 #include <string.h>
@@ -68,6 +40,7 @@ static GSM_Error ReplyGetRFLevel(int messagetype, unsigned char *buffer, int len
 static GSM_Error ReplyGetBattery(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
 static GSM_Error ReplyReadPhonebook(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
 static GSM_Error ReplyMemoryStatus(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
+static GSM_Error ReplyCallDivert(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
 
 static GSM_Error AT_Identify(GSM_Data *data, GSM_Statemachine *state);
 static GSM_Error AT_GetModel(GSM_Data *data, GSM_Statemachine *state);
@@ -78,6 +51,7 @@ static GSM_Error AT_GetBattery(GSM_Data *data,  GSM_Statemachine *state);
 static GSM_Error AT_GetRFLevel(GSM_Data *data,  GSM_Statemachine *state);
 static GSM_Error AT_GetMemoryStatus(GSM_Data *data,  GSM_Statemachine *state);
 static GSM_Error AT_ReadPhonebook(GSM_Data *data,  GSM_Statemachine *state);
+static GSM_Error AT_CallDivert(GSM_Data *data, GSM_Statemachine *state);
 
 typedef struct {
        int gop;
@@ -101,6 +75,7 @@ static AT_FunctionInitType AT_FunctionInit[] = {
        { GOP_GetRFLevel, AT_GetRFLevel, ReplyGetRFLevel },
        { GOP_GetMemoryStatus, AT_GetMemoryStatus, ReplyMemoryStatus },
        { GOP_ReadPhonebook, AT_ReadPhonebook, ReplyReadPhonebook },
+       { GOP_CallDivert, AT_CallDivert, ReplyCallDivert }
 };
 
 
@@ -366,6 +341,48 @@ static GSM_Error AT_ReadPhonebook(GSM_Data *data,  GSM_Statemachine *state)
 }
 
 
+static GSM_Error AT_CallDivert(GSM_Data *data, GSM_Statemachine *state)
+{
+       char req[64];
+
+       if (!data->CallDivert) return GE_UNKNOWN;
+
+       sprintf(req, "AT+CCFC=");
+
+       switch (data->CallDivert->DType) {
+       case GSM_CDV_AllTypes:
+               strcat(req, "4");
+               break;
+       case GSM_CDV_Busy:
+               strcat(req, "1");
+               break;
+       case GSM_CDV_NoAnswer:
+               strcat(req, "2");
+               break;
+       case GSM_CDV_OutOfReach:
+               strcat(req, "3");
+               break;
+       default:
+               dprintf("3. %d\n", data->CallDivert->DType);
+               return GE_NOTIMPLEMENTED;
+       }
+       if (data->CallDivert->Operation == GSM_CDV_Register)
+               sprintf(req, "%s,%d,\"%s\",%d,,,%d", req,
+                       data->CallDivert->Operation,
+                       data->CallDivert->Number.number,
+                       data->CallDivert->Number.type,
+                       data->CallDivert->Timeout);
+       else
+               sprintf(req, "%s,%d", req, data->CallDivert->Operation);
+
+       strcat(req, "\r\n");
+
+       dprintf("%s", req);
+       if (SM_SendMessage(state, strlen(req), GOP_CallDivert, req) != GE_NONE)
+               return GE_NOTREADY;
+       return SM_WaitFor(state, data, GOP_CallDivert);
+}
+
 static GSM_Error Functions(GSM_Operation op, GSM_Data *data, GSM_Statemachine *state)
 {
        if (op == GOP_Init)
@@ -540,6 +557,15 @@ static GSM_Error ReplyIdentify(int messagetype, unsigned char *buffer, int lengt
        return GE_NONE;
 }
 
+static GSM_Error ReplyCallDivert(int messagetype, unsigned char *buffer, int length, GSM_Data *data)
+{
+       int i;
+       for (i = 0; i < length; i++) {
+               dprintf("%02x ", buffer[i]);
+       }
+       dprintf("\n");
+       return GE_NONE;
+}
 
 static GSM_Error Reply(int messagetype, unsigned char *buffer, int length, GSM_Data *data)
 {
index af77996..bd3f164 100644 (file)
@@ -83,6 +83,7 @@ static GSM_IncomingFunctionType P7110_IncomingFunctions[] = {
        { P7110_MSG_CLOCK,      P7110_IncomingClock },
        { P7110_MSG_IDENTITY,   P7110_Incoming0x1b },
        { P7110_MSG_STLOGO,     P7110_IncomingStartup },
+       { P7110_MSG_DIVERT,     P7110_IncomingCallDivert },
        { 0, NULL }
 };
 
@@ -153,6 +154,8 @@ static GSM_Error P7110_Functions(GSM_Operation op, GSM_Data *data, GSM_Statemach
                return P7110_GetSMS(data, state);
        case GOP_SendSMS:
                return P7110_SendSMS(data, state);
+       case GOP_CallDivert:
+               return P7110_CallDivert(data, state);
 /* I'm not sure yet if folder functions will be shared or local
        case GOP_GetSMSFolders:
                return P7110_GetSMSFolders(data, state);
@@ -822,7 +825,7 @@ static GSM_Error P7110_GetSMSFolderStatus(GSM_Data *data, GSM_Statemachine *stat
 
 static GSM_Error P7110_SendSMS(GSM_Data *data, GSM_Statemachine *state)
 {
-       GSM_Error e;
+       GSM_Error e = GE_NONE;
        unsigned char req[256] = {FBUS_FRAME_HEADER, 0x01, 0x02, 0x00};
        int length, i;
 
@@ -1109,6 +1112,80 @@ static GSM_Error P7110_IncomingCalendar(int messagetype, unsigned char *message,
        return e;
 }
 
+static GSM_Error P7110_CallDivert(GSM_Data *data, GSM_Statemachine *state)
+{
+       unsigned short length = 0x09;
+       char req[55] = { FBUS_FRAME_HEADER, 0x01, 0x00, /* operation */
+                                               0x00,
+                                               0x00, /* divert type */
+                                               0x00, /* call type */
+                                               0x00 };
+       if (!data->CallDivert) return GE_UNKNOWN;
+       switch (data->CallDivert->Operation) {
+       case GSM_CDV_Query:
+               req[4] = 0x05;
+               break;
+       case GSM_CDV_Register:
+               req[4] = 0x03;
+               length = 0x16;
+               req[8] = 0x01;
+               req[9] = SemiOctetPack(data->CallDivert->Number.number, req + 10, data->CallDivert->Number.type);
+               req[21] = data->CallDivert->Timeout;
+               break;
+       case GSM_CDV_Erasure:
+               req[4] = 0x04;
+               break;
+       default:
+               return GE_NOTIMPLEMENTED;
+       }
+       switch (data->CallDivert->CType) {
+       case GSM_CDV_AllCalls:
+               break;
+       case GSM_CDV_VoiceCalls:
+               req[7] = 0x0b;
+               break;
+       case GSM_CDV_FaxCalls:
+               req[7] = 0x0d;
+               break;
+       case GSM_CDV_DataCalls:
+               req[7] = 0x19;
+               break;
+       default:
+               return GE_NOTIMPLEMENTED;
+       }
+       switch (data->CallDivert->DType) {
+       case GSM_CDV_AllTypes:
+               req[6] = 0x15;
+               break;
+       case GSM_CDV_Busy:
+               req[6] = 0x43;
+               break;
+       case GSM_CDV_NoAnswer:
+               req[6] = 0x3d;
+               break;
+       case GSM_CDV_OutOfReach:
+               req[6] = 0x3e;
+               break;
+       default:
+               return GE_NOTIMPLEMENTED;
+       }
+       if ((data->CallDivert->DType == GSM_CDV_AllTypes) && (data->CallDivert->CType == GSM_CDV_AllCalls))
+               req[6] = 0x02;
+
+       if (SM_SendMessage(state, length, P7110_MSG_DIVERT, req) != GE_NONE) return GE_NOTREADY;
+       return SM_WaitFor(state, data, P7110_MSG_DIVERT);
+}
+
+static GSM_Error P7110_IncomingCallDivert(int messagetype, unsigned char *message, int length, GSM_Data *data)
+{
+       int i;
+       for (i = 0; i < length; i++) {
+               dprintf("%02x ", message[i]);
+       }
+       dprintf("\n");
+       return GE_NONE;
+}
+
 static int GetMemoryType(GSM_MemoryType memory_type)
 {
        int result;
index 9a562e5..120a83f 100644 (file)
@@ -200,7 +200,12 @@ int usage(void)
                          "          gnokii --getprofile [number]\n"
                          "          gnokii --displayoutput\n"
                          "          gnokii --keysequence\n"
-               ));
+                         "          gnokii --divert {--op|-o} {register|enable|query|disable|erasure}\n"
+                         "                 {--type|-t} {all|busy|noans|outofreach|notavail}\n"
+                         "                 {--call|-c} {all|voice|fax|data}\n"
+                         "                 [{--timeout|-m} time_in_seconds]\n"
+                         "                 [{--number|-n} number]\n"
+                       ));
 #ifdef SECURITY
        fprintf(stderr, _(
                "          gnokii --entersecuritycode PIN|PIN2|PUK|PUK2\n"
@@ -405,7 +410,10 @@ int main(int argc, char *argv[])
 
                // Simulate pressing the keys
                { "keysequence",        no_argument,       NULL, OPT_KEYPRESS },
-    
+
+               /* Divert calls */
+               { "divert",             required_argument, NULL, OPT_DIVERT },
+
                // For development purposes: insert you function calls here
                { "foogle",             no_argument,       NULL, OPT_FOOGLE },
 
@@ -448,6 +456,7 @@ int main(int argc, char *argv[])
                { OPT_RESET,             0, 1, 0 },
                { OPT_GETPROFILE,        0, 1, 0 },
                { OPT_WRITEPHONEBOOK,    0, 1, 0 },
+               { OPT_DIVERT,            6, 10, 0 },
 
                { 0, 0, 0, 0 },
        };
@@ -474,12 +483,12 @@ int main(int argc, char *argv[])
                usage();
 
        switch(c) {
-       // First, error conditions
+       /* First, error conditions */
        case '?':
        case ':':
                fprintf(stderr, _("Use '%s --help' for usage informations.\n"), argv[0]);
                exit(0);
-       // Then, options with no arguments
+       /* Then, options with no arguments */
        case OPT_HELP:
                usage();
        case OPT_VERSION:
@@ -536,7 +545,7 @@ int main(int argc, char *argv[])
                case OPT_WRITEPHONEBOOK:
                        rc = writephonebook(nargc, nargv);
                        break;
-               // Now, options with arguments
+               /* Now, options with arguments */
                case OPT_SETDATETIME:
                        rc = setdatetime(nargc, nargv);
                        break;
@@ -612,17 +621,20 @@ int main(int argc, char *argv[])
                case OPT_KEYPRESS:
                        rc = presskeysequence();
                        break;
-#ifndef WIN32
-               case OPT_FOOGLE:
-                       rc = foogle(nargv);
-                       break;
-#endif
                case OPT_SENDDTMF:
                        rc = senddtmf(optarg);
                        break;
                case OPT_RESET:
                        rc = reset(optarg);
                        break;
+               case OPT_DIVERT:
+                       rc = divert(argc, argv);
+                       break;
+#ifndef WIN32
+               case OPT_FOOGLE:
+                       rc = foogle(nargv);
+                       break;
+#endif
                default:
                        fprintf(stderr, _("Unknown option: %d\n"), c);
                        break;
@@ -834,17 +846,17 @@ int savesms(int argc, char *argv[])
                                if (!strcmp(ans, _("yes"))) confirm = 1;
                                else if (!strcmp(ans, _("no"))) confirm = 0;
                        }  
-                       if (!confirm) { GSM->Terminate(); return 0; }
+                       if (!confirm) {
+                               if (GSM && GSM->Terminate) GSM->Terminate();
+                               return 0;
+                       }
                        else break;
                case GE_INVALIDSMSLOCATION:
                        fprintf(stderr, _("Invalid location\n"));
-                       GSM->Terminate();
+                       if (GSM && GSM->Terminate) GSM->Terminate();
                        return -1;
                default:
-/* FIXME: Remove this fprintf when the function is thoroughly tested */
-#ifdef DEBUG
-                       fprintf(stderr, _("Location %d empty. Saving\n"), SMS.Number);
-#endif
+                       dprintf("Location %d empty. Saving\n", SMS.Number);
                        break;
                }
        }
@@ -873,7 +885,7 @@ int savesms(int argc, char *argv[])
                fprintf(stdout, _("Saving failed (error=%d)\n"), error);
        }
        sleep(10);
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -886,7 +898,7 @@ int getsmsc(char *MessageCenterNumber)
        GSM_Error               error;
        
        memset(&MessageCenter, 0, sizeof(MessageCenter));
-       MessageCenter.No=atoi(MessageCenterNumber);
+       MessageCenter.No = atoi(MessageCenterNumber);
        
        if (GSM && GSM->GetSMSCenter && GSM->Terminate) {
                error = GSM->GetSMSCenter(&MessageCenter);
@@ -1206,14 +1218,14 @@ int deletesms(int argc, char *argv[])
                else {
                        if (error == GE_NOTIMPLEMENTED) {
                                fprintf(stderr, _("Function not implemented in %s model!\n"), model);
-                               GSM->Terminate();
+                               if (GSM && GSM->Terminate) GSM->Terminate();
                                return -1;      
                        }
                        fprintf(stdout, _("DeleteSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
                }
        }
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -1236,17 +1248,18 @@ int entersecuritycode(char *type)
        GSM_Error test;
        GSM_SecurityCode SecurityCode;
 
-       if (!strcmp(type,"PIN"))
-               SecurityCode.Type=GSCT_Pin;
-       else if (!strcmp(type,"PUK"))
-               SecurityCode.Type=GSCT_Puk;
-       else if (!strcmp(type,"PIN2"))
-               SecurityCode.Type=GSCT_Pin2;
-       else if (!strcmp(type,"PUK2"))
-               SecurityCode.Type=GSCT_Puk2;
-       // FIXME: Entering of SecurityCode does not work :-(
-       //  else if (!strcmp(type,"SecurityCode"))
-       //    SecurityCode.Type=GSCT_SecurityCode;
+       if (!strcmp(type, "PIN"))
+               SecurityCode.Type = GSCT_Pin;
+       else if (!strcmp(type, "PUK"))
+               SecurityCode.Type = GSCT_Puk;
+       else if (!strcmp(type, "PIN2"))
+               SecurityCode.Type = GSCT_Pin2;
+       else if (!strcmp(type, "PUK2"))
+               SecurityCode.Type = GSCT_Puk2;
+       /* FIXME: Entering of SecurityCode does not work :-(
+       else if (!strcmp(type, "SecurityCode"))
+               SecurityCode.Type = GSCT_SecurityCode;
+       */
        else
                usage();
 
@@ -1254,10 +1267,10 @@ int entersecuritycode(char *type)
        printf("Enter your code: ");
        gets(SecurityCode.Code);
 #else
-       strcpy(SecurityCode.Code,getpass(_("Enter your code: ")));
+       strcpy(SecurityCode.Code, getpass(_("Enter your code: ")));
 #endif
 
-       test = GSM->EnterSecurityCode(SecurityCode);
+       if (GSM && GSM->EnterSecurityCode) test = GSM->EnterSecurityCode(SecurityCode);
        if (test == GE_INVALIDSECURITYCODE)
                fprintf(stdout, _("Error: invalid code.\n"));
        else if (test == GE_NONE)
@@ -1267,7 +1280,7 @@ int entersecuritycode(char *type)
        else
                fprintf(stdout, _("Other error.\n"));
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -1276,7 +1289,7 @@ int getsecuritycodestatus(void)
 {
        int Status;
 
-       if (GSM->GetSecurityCodeStatus(&Status) == GE_NONE) {
+       if (GSM && GSM->GetSecurityCodeStatus && GSM->GetSecurityCodeStatus(&Status) == GE_NONE) {
 
                fprintf(stdout, _("Security code status: "));
 
@@ -1305,7 +1318,7 @@ int getsecuritycodestatus(void)
                }
        }
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -1316,9 +1329,9 @@ int getsecuritycodestatus(void)
 /* Voice dialing mode. */
 int dialvoice(char *Number)
 {
-       GSM->DialVoice(Number);
+       if (GSM && GSM->DialVoice) GSM->DialVoice(Number);
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -1436,9 +1449,9 @@ GSM_Error SaveBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
                while (!confirm) {
                        fprintf(stderr, _("Saving logo. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "), FileName);
                        GetLine(stdin, ans, 4);
-                       if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
-                       if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
-                       if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
+                       if (!strcmp(ans, _("O")) || !strcmp(ans, _("o"))) confirm = 1;
+                       if (!strcmp(ans, _("N")) || !strcmp(ans, _("n"))) confirm = 2;
+                       if (!strcmp(ans, _("S")) || !strcmp(ans, _("s"))) return GE_USERCANCELED;
                }  
                if (confirm == 1) break;
                if (confirm == 2) {
@@ -1627,13 +1640,13 @@ int setlogo(int argc, char *argv[])
                if (!strcmp(argv[0], "op") || !strcmp(argv[0], "startup") || !strcmp(argv[0], "caller")) {
                        if (argc > 1) {
                                if (ReadBitmapFileOnConsole(argv[1], &bitmap) != GE_NONE) {
-                                       GSM->Terminate();
+                                       if (GSM && GSM->Terminate) GSM->Terminate();
                                        return(-1);
                                }
 
                                if (!strcmp(argv[0], "op")) {
                                        if (bitmap.type != GSM_OperatorLogo || argc < 3) {
-                                               if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode, NetworkInfo.NetworkCode, 7);
+                                               if (GSM && GSM->GetNetworkInfo && GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode, NetworkInfo.NetworkCode, 7);
                                        }
                                        GSM_ResizeBitmap(&bitmap, GSM_OperatorLogo, GSM_Info);
                                        if (argc == 3) {
@@ -1657,7 +1670,7 @@ int setlogo(int argc, char *argv[])
                                        }
                                        oldbit.type = GSM_CallerLogo;
                                        oldbit.number = bitmap.number;
-                                       if (GSM->GetBitmap(&oldbit) == GE_NONE) {
+                                       if (GSM && GSM->GetBitmap && GSM->GetBitmap(&oldbit) == GE_NONE) {
                                                /* We have to get the old name and ringtone!! */
                                                bitmap.ringtone = oldbit.ringtone;
                                                strncpy(bitmap.text, oldbit.text, 255);
@@ -1681,18 +1694,18 @@ int setlogo(int argc, char *argv[])
                        }  
                } else {
                        fprintf(stderr, _("What kind of logo do you want to set ?\n"));
-                       GSM->Terminate();
+                       if (GSM && GSM->Terminate) GSM->Terminate();
                        return -1;
                }
        }
     
-       error=GSM->SetBitmap(&bitmap);
+       if (GSM && GSM->SetBitmap) error = GSM->SetBitmap(&bitmap);
   
        switch (error) {
        case GE_NONE:
                oldbit.type = bitmap.type;
                oldbit.number = bitmap.number;
-               if (GSM->GetBitmap(&oldbit) == GE_NONE) {
+               if (GSM && GSM->GetBitmap && GSM->GetBitmap(&oldbit) == GE_NONE) {
                        if (bitmap.type == GSM_WelcomeNoteText ||
                            bitmap.type == GSM_DealerNoteText) {
                                if (strcmp(bitmap.text, oldbit.text)) {
@@ -1713,13 +1726,13 @@ int setlogo(int argc, char *argv[])
                                        /* When we make it correct, we don't have this mistake */
                        
                                        strcpy(oldbit.text, "!\0");
-                                       GSM->SetBitmap(&oldbit);
-                                       GSM->GetBitmap(&oldbit);
+                                       if (GSM && GSM->SetBitmap) GSM->SetBitmap(&oldbit);
+                                       if (GSM && GSM->GetBitmap) GSM->GetBitmap(&oldbit);
                                        if (oldbit.text[0]!='!') {
                                                fprintf(stderr, _("SIM card and PIN is required\n"));
                                        } else {
-                                               GSM->SetBitmap(&bitmap);
-                                               GSM->GetBitmap(&oldbit);
+                                               if (GSM && GSM->SetBitmap) GSM->SetBitmap(&bitmap);
+                                               if (GSM && GSM->GetBitmap) GSM->GetBitmap(&oldbit);
                                                fprintf(stderr, _("too long, truncated to \"%s\" (length %i)\n"),oldbit.text,strlen(oldbit.text));
                                        }
                                        ok = false;
@@ -1749,7 +1762,7 @@ int setlogo(int argc, char *argv[])
                break;
        }
   
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -1898,7 +1911,7 @@ int getcalendarnote(int argc, char *argv[])
                }
        }
        
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return error;
 }
 
@@ -1913,12 +1926,12 @@ int writecalendarnote(char *argv[])
        }
 
         /* Error 22=Calendar full ;-) */
-       if ((GSM->WriteCalendarNote(&CalendarNote)) == GE_NONE)
+       if (GSM && GSM->WriteCalendarNote && GSM->WriteCalendarNote(&CalendarNote) == GE_NONE)
                fprintf(stdout, _("Succesfully written!\n"));
        else
                fprintf(stdout, _("Failed to write calendar note!\n"));
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -1936,7 +1949,7 @@ int deletecalendarnote(int argc, char *argv[])
 
                CalendarNote.Location = i;
 
-               if (GSM->DeleteCalendarNote(&CalendarNote) == GE_NONE) {
+               if (GSM && GSM->DeleteCalendarNote && GSM->DeleteCalendarNote(&CalendarNote) == GE_NONE) {
                        fprintf(stdout, _("   Calendar note deleted.\n"));
                } else {
                        fprintf(stderr, _("The calendar note can not be deleted\n"));
@@ -1944,7 +1957,7 @@ int deletecalendarnote(int argc, char *argv[])
 
        }
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -1987,15 +2000,16 @@ int setdatetime(int argc, char *argv[])
        }
 
        /* FIXME: Error checking should be here. */
-       GSM->SetDateTime(&Date);
+       if (GSM && GSM->SetDateTime) GSM->SetDateTime(&Date);
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
 
 /* In this mode we receive the date and time from mobile phone. */
-int getdatetime(void) {
+int getdatetime(void)
+{
        GSM_Data        data;
        GSM_DateTime    date_time;
        GSM_Error       error;
@@ -2034,9 +2048,9 @@ int setalarm(char *argv[])
        Date.Hour = atoi(argv[0]);
        Date.Minute = atoi(argv[1]);
 
-       GSM->SetAlarm(1, &Date);
+       if (GSM && GSM->SetAlarm) GSM->SetAlarm(1, &Date);
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -2117,55 +2131,55 @@ int monitormode(void)
        /* Loop here indefinitely - allows you to see messages from GSM code in
           response to unknown messages etc. The loops ends after pressing the
           Ctrl+C. */
-       data.RFUnits=&rf_units;
-       data.RFLevel=&rflevel;
-       data.BatteryUnits=&batt_units;
-       data.BatteryLevel=&batterylevel;
+       data.RFUnits = &rf_units;
+       data.RFLevel = &rflevel;
+       data.BatteryUnits = &batt_units;
+       data.BatteryLevel = &batterylevel;
 
        while (!bshutdown) {
-               if (SM_Functions(GOP_GetRFLevel,&data,sm) == GE_NONE)
+               if (SM_Functions(GOP_GetRFLevel, &data, sm) == GE_NONE)
                        fprintf(stdout, _("RFLevel: %d\n"), (int)rflevel);
 
-               if (SM_Functions(GOP_GetBatteryLevel,&data,sm) == GE_NONE)
+               if (SM_Functions(GOP_GetBatteryLevel, &data, sm) == GE_NONE)
                        fprintf(stdout, _("Battery: %d\n"), (int)batterylevel);
 
 //             if (GSM->GetPowerSource(&powersource) == GE_NONE)
 //                     fprintf(stdout, _("Power Source: %s\n"), (powersource==GPS_ACDC)?_("AC/DC"):_("battery"));
 
-               data.MemoryStatus=&SIMMemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &SIMMemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("SIM: Used %d, Free %d\n"), SIMMemoryStatus.Used, SIMMemoryStatus.Free);
 
-               data.MemoryStatus=&PhoneMemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &PhoneMemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("Phone: Used %d, Free %d\n"), PhoneMemoryStatus.Used, PhoneMemoryStatus.Free);
 
-               data.MemoryStatus=&DC_MemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &DC_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("DC: Used %d, Free %d\n"), DC_MemoryStatus.Used, DC_MemoryStatus.Free);
 
-               data.MemoryStatus=&EN_MemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &EN_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("EN: Used %d, Free %d\n"), EN_MemoryStatus.Used, EN_MemoryStatus.Free);
 
-               data.MemoryStatus=&FD_MemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &FD_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("FD: Used %d, Free %d\n"), FD_MemoryStatus.Used, FD_MemoryStatus.Free);
 
-               data.MemoryStatus=&LD_MemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &LD_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("LD: Used %d, Free %d\n"), LD_MemoryStatus.Used, LD_MemoryStatus.Free);
 
-               data.MemoryStatus=&MC_MemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &MC_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("MC: Used %d, Free %d\n"), MC_MemoryStatus.Used, MC_MemoryStatus.Free);
 
-               data.MemoryStatus=&ON_MemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &ON_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("ON: Used %d, Free %d\n"), ON_MemoryStatus.Used, ON_MemoryStatus.Free);
 
-               data.MemoryStatus=&RC_MemoryStatus;
-               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+               data.MemoryStatus = &RC_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus, &data, sm) == GE_NONE)
                        fprintf(stdout, _("RC: Used %d, Free %d\n"), RC_MemoryStatus.Used, RC_MemoryStatus.Free);
 
 //             if (GSM->GetSMSStatus(&SMSStatus) == GE_NONE)
@@ -2183,9 +2197,7 @@ int monitormode(void)
                sleep(1);
        }
 
-       fprintf (stderr, _("Leaving monitor mode...\n"));
-
-       //GSM->Terminate();
+       fprintf(stderr, _("Leaving monitor mode...\n"));
 
        return 0;
 }
@@ -2204,7 +2216,7 @@ static GSM_Error PrettyOutputFn(char *Display, char *Indicators)
 }
 
 #if 0
-// Uncomment it if used
+/* Uncomment it if used */
 static GSM_Error OutputFn(char *Display, char *Indicators)
 {
        if (Display)
@@ -2257,7 +2269,7 @@ int displayoutput(void)
                        memset(&buf[0], 0, 102);
                        while (read(0, buf, 100) > 0) {
                                fprintf(stderr, "handling keys (%d).\n", strlen(buf));
-                               if (GSM->HandleString(buf) != GE_NONE)
+                               if (GSM && GSM->HandleString && GSM->HandleString(buf) != GE_NONE)
                                        fprintf(stdout, _("Key press simulation failed.\n"));
                                memset(buf, 0, 102);
                        }
@@ -2274,7 +2286,7 @@ int displayoutput(void)
        } else
                fprintf (stderr, _("Error!\n"));
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
 
@@ -2290,18 +2302,18 @@ int getprofile(int argc, char *argv[])
        char model[64];
 
        profile.Number = 0;
-       error = GSM->GetProfile(&profile);
+       if (GSM && GSM->GetProfile) error = GSM->GetProfile(&profile);
 
        if (error == GE_NONE) {
   
-               while (GSM->GetModel(model) != GE_NONE)
+               while (GSM && GSM->GetModel && GSM->GetModel(model) != GE_NONE)
                        sleep(1);
 
                max_profiles = 7; /* This is correct for 6110 (at least my). How do we get
                                     the number of profiles? */
 
-               /*For N5110*/
-               /*FIX ME: It should be set to 3 for N5130 and 3210 too*/
+               /* For N5110 */
+               /* FIXME: It should be set to 3 for N5130 and 3210 too */
                if (!strcmp(model, "NSE-1"))
                        max_profiles = 3;
 
@@ -2312,13 +2324,13 @@ int getprofile(int argc, char *argv[])
 
                        if (profile.Number < 0) {
                                fprintf(stderr, _("Profile number must be value from 1 to %d!\n"), max_profiles);
-                               GSM->Terminate();
+                               if (GSM && GSM->Terminate) GSM->Terminate();
                                return -1;
                        }
 
                        if (profile.Number >= max_profiles) {
                                fprintf(stderr, _("This phone supports only %d profiles!\n"), max_profiles);
-                               GSM->Terminate();
+                               if (GSM && GSM->Terminate) GSM->Terminate();
                                return -1;
                        }
                } else {
@@ -2331,7 +2343,7 @@ int getprofile(int argc, char *argv[])
                        profile.Number = i;
 
                        if (profile.Number != 0)
-                               GSM->GetProfile(&profile);
+                               if (GSM && GSM->GetProfile) GSM->GetProfile(&profile);
 
                        fprintf(stdout, "%d. \"%s\"\n", profile.Number + 1, profile.Name);
                        if (profile.DefaultName == -1) fprintf(stdout, _(" (name defined)\n"));
@@ -2371,16 +2383,16 @@ int getprofile(int argc, char *argv[])
        } else {
                if (error == GE_NOTIMPLEMENTED) {
                        fprintf(stderr, _("Function not implemented in %s model!\n"), model);
-                       GSM->Terminate();
+                       if (GSM && GSM->Terminate) GSM->Terminate();
                        return -1;
                } else {
                        fprintf(stderr, _("Unspecified error\n"));
-                       GSM->Terminate();
+                       if (GSM && GSM->Terminate) GSM->Terminate();
                        return -1;
                }
        }
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
 
@@ -2413,8 +2425,8 @@ int getmemory(int argc, char *argv[])
 
                entry.Location = count;
 
-               data.PhonebookEntry=&entry;
-               error=SM_Functions(GOP_ReadPhonebook,&data,sm);
+               data.PhonebookEntry = &entry;
+               error = SM_Functions(GOP_ReadPhonebook, &data, sm);
 
                if (error == GE_NONE) {
                        fprintf(stdout, "%s;%s;%s;%d;%d\n", entry.Name, entry.Number, memory_type_string, entry.Location, entry.Group);
@@ -2558,7 +2570,7 @@ int writephonebook(int argc, char *args[])
                        GSM_PhonebookEntry aux;
 
                        aux.Location = entry.Location;
-                       error = GSM->GetMemoryLocation(&aux);
+                       if (GSM && GSM->GetMemoryLocation) error = GSM->GetMemoryLocation(&aux);
                        
                        if (error == GE_NONE) {
                                if (!aux.Empty) {
@@ -2576,13 +2588,13 @@ int writephonebook(int argc, char *args[])
                                }
                        } else {
                                fprintf(stderr, _("Unknown error (%d)\n"), error);
-                               GSM->Terminate();
+                               if (GSM && GSM->Terminate) GSM->Terminate();
                                return 0;
                        }
                }
 
                /* Do write and report success/failure. */
-               error = GSM->WritePhonebookLocation(&entry);
+               if (GSM && GSM->WritePhonebookLocation) error = GSM->WritePhonebookLocation(&entry);
 
                if (error == GE_NONE)
                        fprintf (stdout, _("Write Succeeded: memory type: %s, loc: %d, name: %s, number: %s\n"), memory_type_string, entry.Location, entry.Name, entry.Number);
@@ -2591,7 +2603,7 @@ int writephonebook(int argc, char *args[])
 
        }
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
 
@@ -2652,11 +2664,11 @@ int setspeeddial(char *argv[])
        entry.Number = atoi(argv[0]);
        entry.Location = atoi(argv[2]);
 
-       if (GSM->SetSpeedDial(&entry) == GE_NONE) {
+       if (GSM && GSM->SetSpeedDial && GSM->SetSpeedDial(&entry) == GE_NONE) {
                fprintf(stdout, _("Succesfully written!\n"));
        }
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
 
@@ -2665,7 +2677,7 @@ int getdisplaystatus(void)
 { 
        int Status;
 
-       GSM->GetDisplayStatus(&Status);
+       if (GSM && GSM->GetDisplayStatus) GSM->GetDisplayStatus(&Status);
 
        fprintf(stdout, _("Call in progress: %s\n"), Status & (1<<DS_Call_In_Progress)?_("on"):_("off"));
        fprintf(stdout, _("Unknown: %s\n"),          Status & (1<<DS_Unknown)?_("on"):_("off"));
@@ -2676,7 +2688,7 @@ int getdisplaystatus(void)
        fprintf(stdout, _("Keyboard lock: %s\n"),    Status & (1<<DS_Keyboard_Lock)?_("on"):_("off"));
        fprintf(stdout, _("SMS storage full: %s\n"), Status & (1<<DS_SMS_Storage_Full)?_("on"):_("off"));
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
 
@@ -2697,12 +2709,12 @@ int netmonitor(char *Mode)
                mode = 0x00;
 
        memset(&Screen, 0, 50);
-       GSM->NetMonitor(mode, Screen);
+       if (GSM && GSM->NetMonitor) GSM->NetMonitor(mode, Screen);
 
        if (Screen)
                fprintf(stdout, "%s\n", Screen);
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
 
@@ -2712,10 +2724,10 @@ int identify(void)
        char imei[64], model[64], rev[64], manufacturer[64];
        GSM_Statemachine *sm = &State;
 
-       data.Manufacturer=manufacturer;
-       data.Model=model;
-       data.Revision=rev;
-       data.Imei=imei;
+       data.Manufacturer = manufacturer;
+       data.Model = model;
+       data.Revision = rev;
+       data.Imei = imei;
 
        /* Retrying is bad idea: what if function is simply not implemented?
           Anyway let's wait 2 seconds for the right packet from the phone. */
@@ -2733,15 +2745,13 @@ int identify(void)
        fprintf(stdout, _("Model:    %s\n"), model);
        fprintf(stdout, _("Revision: %s\n"), rev);
 
-       //GSM->Terminate();
-
        return 0;
 }
 
 int senddtmf(char *String)
 {
-       GSM->SendDTMF(String);
-       GSM->Terminate();
+       if (GSM && GSM->SendDTMF) GSM->SendDTMF(String);
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
 
@@ -2762,8 +2772,8 @@ int reset( char *type)
                        }
        }
 
-       GSM->Reset(_type);
-       GSM->Terminate();
+       if (GSM && GSM->Reset) GSM->Reset(_type);
+       if (GSM && GSM->Terminate) GSM->Terminate();
 
        return 0;
 }
@@ -2773,7 +2783,6 @@ int reset( char *type)
    tool. */
 int pmon(void)
 { 
-
        GSM_Error error;
        GSM_ConnectionType connection=GCT_Serial;
        GSM_Statemachine sm;
@@ -2803,16 +2812,15 @@ int sendringtone(int argc, char *argv[])
                return(-1);
        }  
 
-       error = GSM->SendRingtone(&ringtone,argv[1]);
+       if (GSM && GSM->SendRingtone) error = GSM->SendRingtone(&ringtone,argv[1]);
 
        if (error == GE_NONE) 
                fprintf(stdout, _("Send succeeded!\n"));
        else
                fprintf(stdout, _("SMS Send failed (error=%d)\n"), error);
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
-
 }
 
 
@@ -2826,16 +2834,15 @@ int setringtone(int argc, char *argv[])
                return(-1);
        }  
 
-       error = GSM->SetRingtone(&ringtone);
+       if (GSM && GSM->SetRingtone) error = GSM->SetRingtone(&ringtone);
 
        if (error == GE_NONE) 
                fprintf(stdout, _("Send succeeded!\n"));
        else
                fprintf(stdout, _("Send failed\n"));
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
-
 }
 
 int presskeysequence(void)
@@ -2847,23 +2854,124 @@ int presskeysequence(void)
        memset(&buf[0], 0, 102);
        while (read(0, buf, 100) > 0) {
                fprintf(stderr, "handling keys (%d).\n", strlen(buf));
-               if (GSM->HandleString(buf) != GE_NONE)
+               if (GSM && GSM->HandleString && GSM->HandleString(buf) != GE_NONE)
                        fprintf(stdout, _("Key press simulation failed.\n"));
                memset(buf, 0, 102);
        }
 
-       GSM->Terminate();
+       if (GSM && GSM->Terminate) GSM->Terminate();
        return 0;
 }
+
+/* Options for --divert:
+   --op, -o [register|enable|query|disable|erasure]  REQ
+   --type, -t [all|busy|noans|outofreach|notavail]   REQ
+   --call, -c [all|voice|fax|data]                   REQ
+   --timeout, m time_in_seconds                      OPT
+   --number, -n number                               OPT
+ */
+int divert(int argc, char **argv)
+{
+       int opt;
+       GSM_CallDivert cd;
+       GSM_Statemachine *sm = &State;
+       GSM_Data data;
+       GSM_Error error;
+       struct option options[] = {
+               { "op",      required_argument, NULL, 'o'},
+               { "type",    required_argument, NULL, 't'},
+               { "call",    required_argument, NULL, 'c'},
+               { "number",  required_argument, NULL, 'n'},
+               { "timeout", required_argument, NULL, 'm'},
+               { NULL,      0,                 NULL, 0}
+       };
+
+       optarg = NULL;
+       optind = 0;
+
+       /* Skip --divert */
+       argc--; argv++;
+
+       memset(&cd, 0, sizeof(GSM_CallDivert));
+
+       while ((opt = getopt_long(argc, argv, "o:t:n:c:m:", options, NULL)) != -1) {
+               switch (opt) {
+               case 'o':
+                       if (!strcmp("register", optarg)) {
+                               cd.Operation = GSM_CDV_Register;
+                       } else if (!strcmp("enable", optarg)) {
+                               cd.Operation = GSM_CDV_Enable;
+                       } else if (!strcmp("disable", optarg)) {
+                               cd.Operation = GSM_CDV_Disable;
+                       } else if (!strcmp("erasure", optarg)) {
+                               cd.Operation = GSM_CDV_Erasure;
+                       } else if (!strcmp("query", optarg)) {
+                               cd.Operation = GSM_CDV_Query;
+                       } else {
+                               usage();
+                               exit(-1);
+                       }
+                       break;
+               case 't':
+                       if (!strcmp("all", optarg)) {
+                               cd.DType = GSM_CDV_AllTypes;
+                       } else if (!strcmp("busy", optarg)) {
+                               cd.DType = GSM_CDV_Busy;
+                       } else if (!strcmp("noans", optarg)) {
+                               cd.DType = GSM_CDV_NoAnswer;
+                       } else if (!strcmp("outofreach", optarg)) {
+                               cd.DType = GSM_CDV_OutOfReach;
+                       } else if (!strcmp("notavail", optarg)) {
+                               cd.DType = GSM_CDV_NotAvailable;
+                       } else {
+                               usage();
+                               exit(-1);
+                       }
+                       break;
+               case 'c':
+                       if (!strcmp("all", optarg)) {
+                               cd.CType = GSM_CDV_AllCalls;
+                       } else if (!strcmp("voice", optarg)) {
+                               cd.CType = GSM_CDV_VoiceCalls;
+                       } else if (!strcmp("fax", optarg)) {
+                               cd.CType = GSM_CDV_FaxCalls;
+                       } else if (!strcmp("data", optarg)) {
+                               cd.CType = GSM_CDV_DataCalls;
+                       } else {
+                               usage();
+                               exit(-1);
+                       }
+                       break;
+               case 'm':
+                       cd.Timeout = atoi(optarg);
+                       break;
+               case 'n':
+                       strcpy(cd.Number.number, optarg);
+                       if (cd.Number.number[0] == '+') cd.Number.type = SMS_International;
+                       else cd.Number.type = SMS_Unknown;
+                       break;
+               default:
+                       usage();
+                       exit(-1);
+               }
+       }
+       data.CallDivert = &cd;
+       error = SM_Functions(GOP_CallDivert, &data, sm);
+
+       if (error == GE_NONE) {
+               fprintf(stderr, "Divert succeeded.\n");
+       } else {
+               fprintf(stderr, "%s\n", print_error(error));
+       }
+       return 0;
+}
+
 /* This is a "convenience" function to allow quick test of new API stuff which
    doesn't warrant a "proper" command line function. */
 #ifndef WIN32
 int foogle(char *argv[])
 {
-       /* Initialise the code for the GSM interface. */     
-       fbusinit(NULL);
-       // Fill in what you would like to test here...
+       /* Fill in what you would like to test here... */
        return 0;
 }
 #endif
index 9787065..ed5dd01 100644 (file)
   Header file for test utility.
 
   $Log$
-  Revision 1.1.1.1  2001/11/25 21:59:19  short
-  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
+  Revision 1.1.1.1.2.1  2001/12/14 20:54:44  short
+  Update: orig2001_12_04_22_45 -> orig2001_12_14_20_46
+
+  Revision 1.1.1.2  2001/12/14 19:49:13  short
+  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Fri Dec 14 20:46 CET 2001
+
+  Revision 1.28  2001/12/14 14:37:44  pkot
+  Cleanups. Call divert support for at and 7110 series
 
   Revision 1.27  2001/09/14 12:53:00  pkot
   New preview logos.
@@ -75,6 +81,7 @@ int reset(char *type);
 int getprofile(int argc, char *argv[]);
 int displayoutput();
 int presskeysequence();
+int divert(int argc, char *argv[]);
 
 typedef enum {
   OPT_HELP,
@@ -116,6 +123,7 @@ typedef enum {
   OPT_GETPROFILE,
   OPT_DISPLAYOUTPUT,
   OPT_KEYPRESS,
+  OPT_DIVERT,
   OPT_FOOGLE
 } opt_index;
 
index 6e25ba7..96f0ead 100644 (file)
   Header file for the definitions, enums etc. that are used by all models of
   handset.
 
-  $Log$
-  Revision 1.1.1.1  2001/11/25 21:59:20  short
-  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
-
-  Revision 1.83  2001/11/17 20:18:33  pkot
-  Added dau9p connection type for 6210/7110
-
-  Revision 1.82  2001/11/13 16:12:21  pkot
-  Preparing libsms to get to work. 6210/7110 SMS and SMS Folder updates
-
-  Revision 1.81  2001/11/08 16:34:20  pkot
-  Updates to work with new libsms
-
-  Revision 1.80  2001/08/20 23:36:27  pkot
-  More cleanup in AT code (Manfred Jonsson)
-
-  Revision 1.79  2001/07/27 00:02:22  pkot
-  Generic AT support for the new structure (Manfred Jonsson)
-
-  Revision 1.78  2001/06/28 00:28:45  pkot
-  Small docs updates (Pawel Kot)
-
-
 */
 
 #ifndef __gsm_common_h
@@ -430,7 +407,37 @@ typedef struct {
 #define GSM_MAX_REVISION_LENGTH (6)
 #define GSM_MAX_MODEL_LENGTH    (6)
 
+/* Data structures for the call divert */
+typedef enum {
+       GSM_CDV_Busy = 0x01,
+       GSM_CDV_NoAnswer,
+       GSM_CDV_OutOfReach,
+       GSM_CDV_NotAvailable,
+       GSM_CDV_AllTypes
+} GSM_CDV_DivertTypes;
+
+typedef enum {
+       GSM_CDV_VoiceCalls = 0x01,
+       GSM_CDV_FaxCalls,
+       GSM_CDV_DataCalls,
+       GSM_CDV_AllCalls
+} GSM_CDV_CallTypes;
 
+typedef enum {
+       GSM_CDV_Disable  = 0x00,
+       GSM_CDV_Enable   = 0x01,
+       GSM_CDV_Query    = 0x02,
+       GSM_CDV_Register = 0x03,
+       GSM_CDV_Erasure  = 0x04
+} GSM_CDV_Opers;
+
+typedef struct {
+       GSM_CDV_DivertTypes DType;
+       GSM_CDV_CallTypes   CType;
+       GSM_CDV_Opers       Operation;
+       SMS_Number          Number;
+       unsigned int        Timeout;
+} GSM_CallDivert;
 
 /* This is a generic holder for high level information - eg a GSM_Bitmap */
 
@@ -460,6 +467,7 @@ typedef struct {
        char *IncomingCallNr;
        GSM_PowerSource *PowerSource;
        GSM_DateTime *DateTime;
+       GSM_CallDivert *CallDivert;
 } GSM_Data;
 
 
@@ -520,6 +528,7 @@ typedef enum {
        GOP_GetSMSCenter,
        GOP_GetDateTime,
        GOP_GetCalendarNote,
+       GOP_CallDivert,
        GOP_Max,        /* don't append anything after this entry */
 } GSM_Operation;
 
index e99344a..3cde6f3 100644 (file)
@@ -399,11 +399,13 @@ typedef struct {
 
 extern int EncodePDUSMS(GSM_SMSMessage *SMS, char *frame);
 extern GSM_Error DecodePDUSMS(unsigned char *message, GSM_SMSMessage *SMS, int MessageLength);
+
 /* Do not use these yet */
 extern GSM_Error EncodeTextSMS();
 extern GSM_Error DecodeTextSMS(unsigned char *message, GSM_SMSMessage *SMS);
 
-/* FIXME: make this static */
+/* We really do need this in the other code */
 extern char *GetBCDNumber(u8 *Number);
+extern int SemiOctetPack(char *Number, unsigned char *Output, SMS_NumberType type);
 
 #endif /* __gnokii_sms_h_ */
index 885e4f3..df3674e 100644 (file)
 
   The various routines are called P7110_(whatever).
 
-  $Log$
-  Revision 1.1.1.1  2001/11/25 21:59:22  short
-  :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
-
-  Revision 1.7  2001/11/22 17:56:53  pkot
-  smslib update. sms sending
-
-  Revision 1.6  2001/11/08 16:47:48  pkot
-  Start fiddling with 7110 and SMS
-
-  Revision 1.5  2001/06/27 23:52:52  pkot
-  7110/6210 updates (Marian Jancar)
-
-  Revision 1.4  2001/05/24 20:47:30  chris
-  More updating of 7110 code and some of xgnokii_lowlevel changed over.
-
-  Revision 1.3  2001/03/23 13:40:25  chris
-  Pavel's patch and a few fixes.
-
-  Revision 1.2  2001/03/21 23:36:08  chris
-  Added the statemachine
-  This will break gnokii --identify and --monitor except for 6210/7110
-
-  Revision 1.1  2001/02/21 19:57:13  chris
-  More fiddling with the directory layout
-
-  Revision 1.1  2001/02/16 14:29:54  chris
-  Restructure of common/.  Fixed a problem in fbus-phonet.c
-  Lots of dprintfs for Marcin
-  Any size xpm can now be loaded (eg for 7110 startup logos)
-  nk7110 code detects 7110/6210 and alters startup logo size to suit
-  Moved Marcin's extended phonebook code into gnokii.c
-
-  Revision 1.4  2001/01/29 17:14:44  chris
-  dprintf now in misc.h (and fiddling with 7110 code)
-
-  Revision 1.3  2001/01/23 15:32:44  chris
-  Pavel's 'break' and 'static' corrections.
-  Work on logos for 7110.
-
-  Revision 1.2  2001/01/17 02:54:56  chris
-  More 7110 work.  Use with care! (eg it is not possible to delete phonebook entries)
-  I can now edit my phonebook in xgnokii but it is 'work in progress'.
-
-  Revision 1.1  2001/01/14 22:47:01  chris
-  Preliminary 7110 support (dlr9 only) and the beginnings of a new structure
-
-
 */
 
 #ifndef __phones_nk7110_h
@@ -78,6 +30,7 @@ extern bool P7110_LinkOK;
 #define P7110_MSG_COMMSTATUS   0x01    /* Communication status */
 #define P7110_MSG_SMS          0x02    /* SMS handling */
 #define P7110_MSG_PHONEBOOK    0x03    /* Phonebook functions */
+#define P7110_MSG_DIVERT       0x06    /* Call Divert */
 #define P7110_MSG_NETSTATUS    0x0a    /* Network status */
 #define P7110_MSG_CALENDAR     0x13    /* Calendar notes */
 #define P7110_MSG_FOLDER       0x14    /* Folders handling */
@@ -201,6 +154,7 @@ static GSM_Error P7110_GetSMS(GSM_Data *data, GSM_Statemachine *state);
 static GSM_Error P7110_SendSMS(GSM_Data *data, GSM_Statemachine *state);
 static GSM_Error P7110_GetSMSFolders(GSM_Data *data, GSM_Statemachine *state);
 static GSM_Error P7110_GetSMSFolderStatus(GSM_Data *data, GSM_Statemachine *state);
+static GSM_Error P7110_CallDivert(GSM_Data *data, GSM_Statemachine *state);
 
 static GSM_Error P7110_Incoming0x1b(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
 static GSM_Error P7110_IncomingPhonebook(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
@@ -211,6 +165,7 @@ static GSM_Error P7110_IncomingSMS(int messagetype, unsigned char *buffer, int l
 static GSM_Error P7110_IncomingFolder(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
 static GSM_Error P7110_IncomingClock(int messagetype, unsigned char *message, int length, GSM_Data *data);
 static GSM_Error P7110_IncomingCalendar(int messagetype, unsigned char *message, int length, GSM_Data *data);
+static GSM_Error P7110_IncomingCallDivert(int messagetype, unsigned char *message, int length, GSM_Data *data);
 
 static int GetMemoryType(GSM_MemoryType memory_type);
 
index 78dcadc..6d68f57 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -1676,7 +1676,7 @@ msgstr ""
 #: gnokii/gnokii.c:371 gnokii/gnokii.c:2634 gnokiid/virtmodem.c:282
 #: xgnokii/xgnokii.c:281 xlogos/xlogos.c:139
 msgid "GSM/FBUS init failed! (Unknown model ?). Quitting.\n"
-msgstr "Inicjalizacha GSM/FBUS nieudana! (Nieznany model?). Koñczê pracê.\n"
+msgstr "Inicjalizacja GSM/FBUS nieudana! (Nieznany model?). Koñczê pracê.\n"
 
 #: gnokii/gnokii.c:382
 msgid "Hmmm... GSM_LinkOK never went true. Quitting.\n"
index 9f0fef0..9dd80f9 100644 (file)
@@ -23,7 +23,7 @@ CFLAGS += $(PTHREAD_CFLAGS) \
 LDFLAGS += $(PTHREAD_LIBS) \
           $(GTK_LIBS)
 
-LDFLAGS += -L$(TOPDIR) -lgnokii
+LDFLAGS += -L$(TOPDIR)/common -lgnokii
 
 OBJS =         xgnokii.o \
        xgnokii_common.o \