gnokii-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch to add Caller ID to at-emulator


From: Daniele Forsi
Subject: Patch to add Caller ID to at-emulator
Date: Fri, 3 Sep 2004 21:29:40 +0200
User-agent: KMail/1.4.3

Hello,

I have added support for formatted caller id in the modem emulator with the 
following commands:

AT#CID?
AT#CID=?
AT#CID=0
AT#CID=1

Since the phone rings only once I faked a second ring calling again 
gn_atem_modem_result(MR_RING); so you should set a program to answer at the 
second RING when CID is enabled and at the first RING when CID is disabled (a 
better solution would be adding a real RING emulation...).

I also added a check to accept empty lines when in command mode (see line 
marked with /* DF */).

Daniele

Here are the patches (I tried to be consistent with the rest of the code and 
"diesis" stands for #):

diff -ru gnokii-0.6.3-orig/common/data/at-emulator.c 
gnokii-0.6.3/common/data/at-emulator.c
--- gnokii-0.6.3-orig/common/data/at-emulator.c 2004-07-05 00:04:24.000000000 
+0200
+++ gnokii-0.6.3/common/data/at-emulator.c      2004-09-01 23:32:31.000000000 
+0200
@@ -39,6 +39,7 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <time.h>
 #include <unistd.h>
 #include <ctype.h>
 
@@ -107,6 +108,7 @@
 static int     CurrentCmdBufferIndex;
 static int     IncomingCallNo;
 static int     MessageFormat;          /* Message Format (text or pdu) */
+static int     CallerIDMode;
 
        /* Current command parser */
 static void    (*Parser)(char *); /* Current command parser */
@@ -181,6 +183,8 @@
        ModemRegisters[REG_VERBOSE] |= BIT_VERBOSE;
        ModemRegisters[REG_CTRLZ] = 26;
        ModemRegisters[REG_ESCAPE] = 27;
+
+       CallerIDMode = 0;
 }
 
 
@@ -221,6 +225,7 @@
                gn_atem_modem_result(MR_RING);
                IncomingCallNo = CallInfo->call_id;
                ModemRegisters[REG_RINGCNT]++;
+               gn_atem_cid_out(CallInfo);
                if (ModemRegisters[REG_RINGATA] != 0) gn_atem_answer_phone();
                break;
        case GN_CALL_LocalHangup:
@@ -232,6 +237,41 @@
        }
 }
 
+/* This gets called to output caller id info of incoming call */
+void gn_atem_cid_out(gn_call_info *CallInfo)
+{
+       struct tm *now;
+       time_t nowh;
+       char buf[14]; /* 7 for "DATE = " + 4 digits + \n + \r + \0 */
+       int i;
+
+       nowh = time(NULL);
+       now = localtime(&nowh);
+
+       switch(CallerIDMode) {
+       case 0: /* no output */
+               break;
+       case 1: /* formatted CID */
+               snprintf(buf, sizeof(buf), "DATE = %02d%02d\n\r", 
now->tm_mon+1, 
now->tm_mday);
+               gn_atem_string_out(buf);
+
+               snprintf(buf, sizeof(buf), "TIME = %02d%02d\n\r", now->tm_hour, 
now->tm_min);
+               gn_atem_string_out(buf);
+
+               /* TO DO: handle P and O numbers */
+               gn_atem_string_out("NMBR = ");
+               gn_atem_string_out(1 + CallInfo->number); /* skip leading "+" */
+               gn_atem_string_out("\n\rNAME = ");
+               gn_atem_string_out(CallInfo->name);
+               gn_atem_string_out("\n\r");
+
+               /* FIX ME: do a real emulation of rings after the first one (at 
a lower 
level than this) */
+               gn_atem_modem_result(MR_RING);
+
+               break;
+
+       }
+}
 
 /* Handler called when characters received from serial port.
    calls state machine code to process it. */
@@ -304,6 +344,8 @@
        int regno, val;
        char str[256];
 
+       if ( !cmd_buffer[0] ) return; /* DF */
+
        if (strncasecmp (cmd_buffer, "AT", 2) != 0) {
                gn_atem_modem_result(MR_ERROR);
                return;
@@ -544,6 +586,15 @@
                        }
                        break;
 
+               /* # is the precursor to another set of commands */
+               case '#':
+                       buf++;
+                       /* Returns true if error occured */
+                       if (gn_atem_command_diesis(&buf) == true) {
+                               return;
+                       }
+                       break;
+
                default:
                        gn_atem_modem_result(MR_ERROR);
                        return;
@@ -991,6 +1042,39 @@
        return (true);
 }
 
+/* Handle AT# commands */
+bool   gn_atem_command_diesis(char **buf)
+{
+       int     number;
+       char    buffer[MAX_LINE_LENGTH];
+
+       if (strncasecmp(*buf, "CID", 3) == 0) {
+               buf[0] += 3;
+               switch (**buf) {
+               case '?':
+                       buf[0]++;
+                       gsprintf(buffer, MAX_LINE_LENGTH, "%d\n\r", 
CallerIDMode);
+                       gn_atem_string_out(buffer);
+                       return (false);
+               case '=':
+                       buf[0]++;
+                       if (**buf == '?') {
+                               buf[0]++;
+                               gn_atem_string_out("0,1\n\r");
+                               return (false);
+                       } else {
+                               number = gn_atem_num_get(buf);
+                               if ( number >= 0 && number <= 2 ) {
+                                       CallerIDMode = number;
+                                       return (false);
+                               }
+                       }
+               }
+       }
+       gn_atem_modem_result(MR_ERROR);
+       return (true);
+}
+
 /* Send a result string back.  There is much work to do here, see
    the code in the isdn driver for an idea of where it's heading... */
 void   gn_atem_modem_result(int code)
diff -ru gnokii-0.6.3-orig/include/data/at-emulator.h 
gnokii-0.6.3/include/data/at-emulator.h
--- gnokii-0.6.3-orig/include/data/at-emulator.h        2004-07-05 
00:04:24.000000000 
+0200
+++ gnokii-0.6.3/include/data/at-emulator.h     2004-09-01 23:52:15.000000000 
+0200
@@ -48,6 +48,8 @@
 int    gn_atem_num_get(char **p);
 void   gn_atem_modem_result(int code);
 void    gn_atem_call_passup(gn_call_status call_status, gn_call_info 
*call_info, struct gn_statemachine *state);
+void   gn_atem_cid_out(gn_call_info *callinfo);
+bool   gn_atem_command_diesis(char **buf);
 
        /* Global variables */
 extern bool gn_atem_initialised;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]