Added keypad forwarding, keypad parameter, chan_lcr keypad option 'k'.
authorAndreas Eversberg <jolly@eversberg.eu>
Tue, 27 Oct 2009 07:02:16 +0000 (08:02 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Tue, 27 Oct 2009 07:02:16 +0000 (08:02 +0100)
modified:   README
modified:   action.cpp
modified:   apppbx.cpp
modified:   chan_lcr.c
modified:   chan_lcr.h
modified:   dss1.cpp
modified:   joinpbx.cpp
modified:   joinpbx.h
modified:   message.h
modified:   route.c
modified:   route.h

README
action.cpp
apppbx.cpp
chan_lcr.c
chan_lcr.h
dss1.cpp
joinpbx.cpp
joinpbx.h
message.h
route.c
route.h

diff --git a/README b/README
index 8c0d65a..8a33e07 100644 (file)
--- a/README
+++ b/README
@@ -522,5 +522,8 @@ Changes after Version 1.6
 - Added experimental CCITT No. 5 signalling system. (for educational purpose)
 - Added socket owner/group options to options.conf
 - Fixed/simplyfied config parser. The last digit of the last line was ignored.
 - Added experimental CCITT No. 5 signalling system. (for educational purpose)
 - Added socket owner/group options to options.conf
 - Fixed/simplyfied config parser. The last digit of the last line was ignored.
+- Added Keypad facility
+ -> New option for chan_lcr: 'k'
+ -> New dialing parameter for LCR: keypad
 
 
 
 
index 8c06137..d720dbe 100644 (file)
@@ -213,6 +213,12 @@ void EndpointAppPBX::action_dialing_external(void)
        if ((rparam = routeparam(e_action, PARAM_PREFIX)))
                SPRINT(dialinginfo.id, "%s%s", rparam->string_value, e_extdialing);
 
        if ((rparam = routeparam(e_action, PARAM_PREFIX)))
                SPRINT(dialinginfo.id, "%s%s", rparam->string_value, e_extdialing);
 
+       /* process keypad */
+       if ((rparam = routeparam(e_action, PARAM_KEYPAD))) {
+               SCPY(dialinginfo.keypad, dialinginfo.id);
+               dialinginfo.id[0] = '\0';
+       }
+
        /* process number complete */
        if ((rparam = routeparam(e_action, PARAM_COMPLETE)))
                if ((rparam = routeparam(e_action, PARAM_PREFIX)))
        /* process number complete */
        if ((rparam = routeparam(e_action, PARAM_COMPLETE)))
                if ((rparam = routeparam(e_action, PARAM_PREFIX)))
index 06e3d92..9dee717 100644 (file)
@@ -1128,9 +1128,12 @@ void EndpointAppPBX::out_setup(void)
 
                /* *********************** external call */
                default:
 
                /* *********************** external call */
                default:
-               PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing external: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.id);
+               PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing external: called='%s' keypad='%s'\n", ea_endpoint->ep_serial, e_dialinginfo.id, e_dialinginfo.keypad);
                /* call to extenal interfaces */
                /* call to extenal interfaces */
-               p = e_dialinginfo.id;
+               if (e_dialinginfo.keypad[0])
+                       p = e_dialinginfo.keypad;
+               else
+                       p = e_dialinginfo.id;
                do {
                        number[0] = '\0';
                        while(*p!=',' && *p!='\0')
                do {
                        number[0] = '\0';
                        while(*p!=',' && *p!='\0')
@@ -1168,7 +1171,10 @@ void EndpointAppPBX::out_setup(void)
                        earlyb = mISDNport->earlyb;
                        PDEBUG(DEBUG_EPOINT, "EPOINT(%d) created port %s\n", ea_endpoint->ep_serial, port->p_name);
                        memset(&dialinginfo, 0, sizeof(dialinginfo));
                        earlyb = mISDNport->earlyb;
                        PDEBUG(DEBUG_EPOINT, "EPOINT(%d) created port %s\n", ea_endpoint->ep_serial, port->p_name);
                        memset(&dialinginfo, 0, sizeof(dialinginfo));
-                       SCPY(dialinginfo.id, number);
+                       if (e_dialinginfo.keypad[0])
+                               SCPY(dialinginfo.keypad, number);
+                       else
+                               SCPY(dialinginfo.id, number);
                        dialinginfo.itype = INFO_ITYPE_ISDN;
                        dialinginfo.ntype = e_dialinginfo.ntype;
                        portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, mISDNport->earlyb);
                        dialinginfo.itype = INFO_ITYPE_ISDN;
                        dialinginfo.ntype = e_dialinginfo.ntype;
                        portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, mISDNport->earlyb);
@@ -1180,7 +1186,6 @@ void EndpointAppPBX::out_setup(void)
 //printf("EXTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.id);
                        message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
                        memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
 //printf("EXTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.id);
                        message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
                        memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
-                       SCPY(message->param.setup.dialinginfo.id, number);
                        memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
                        memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
                        memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
                        memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
                        memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
                        memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
@@ -3844,6 +3849,8 @@ void EndpointAppPBX::logmessage(int message_type, union parameter *param, unsign
                }
                if (param->setup.dialinginfo.id[0])
                        add_trace("dialing", NULL, "%s", param->setup.dialinginfo.id);
                }
                if (param->setup.dialinginfo.id[0])
                        add_trace("dialing", NULL, "%s", param->setup.dialinginfo.id);
+               if (param->setup.dialinginfo.keypad[0])
+                       add_trace("keypad", NULL, "%s", param->setup.dialinginfo.keypad);
                if (param->setup.dialinginfo.display[0])
                        add_trace("display", NULL, "%s", param->setup.dialinginfo.display);
                if (param->setup.dialinginfo.sending_complete)
                if (param->setup.dialinginfo.display[0])
                        add_trace("display", NULL, "%s", param->setup.dialinginfo.display);
                if (param->setup.dialinginfo.sending_complete)
index d1b57e6..e50847c 100644 (file)
@@ -555,6 +555,15 @@ void apply_opt(struct chan_call *call, char *data)
                                        bchannel_gain(call->bchannel, call->tx_gain, 1);
                        }
                        break;
                                        bchannel_gain(call->bchannel, call->tx_gain, 1);
                        }
                        break;
+               case 'k':
+                       if (opt[1] != '\0') {
+                               CERROR(call, call->ast, "Option 'k' (keypad) expects no parameter.\n", opt);
+                               break;
+                       }
+                       CDEBUG(call, call->ast, "Option 'k' (keypad).\n");
+                       if (!call->keypad)
+                               call->keypad = 1;
+                       break;
                default:
                        CERROR(call, call->ast, "Option '%s' unknown.\n", opt);
                }
                default:
                        CERROR(call, call->ast, "Option '%s' unknown.\n", opt);
                }
@@ -586,7 +595,10 @@ static void send_setup_to_lcr(struct chan_call *call)
        memset(&newparam, 0, sizeof(union parameter));
                newparam.setup.dialinginfo.itype = INFO_ITYPE_ISDN;     
                newparam.setup.dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
        memset(&newparam, 0, sizeof(union parameter));
                newparam.setup.dialinginfo.itype = INFO_ITYPE_ISDN;     
                newparam.setup.dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
-       strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1);
+       if (call->keypad)
+               strncpy(newparam.setup.dialinginfo.keypad, call->dialstring, sizeof(newparam.setup.dialinginfo.keypad)-1);
+       else
+               strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1);
        strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1);
                newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;      
                newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
        strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1);
                newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;      
                newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
@@ -657,7 +669,10 @@ static void send_dialque_to_lcr(struct chan_call *call)
 
        /* send setup message to LCR */
        memset(&newparam, 0, sizeof(union parameter));
 
        /* send setup message to LCR */
        memset(&newparam, 0, sizeof(union parameter));
-       strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
+       if (call->keypad)
+               strncpy(newparam.information.keypad, call->dialque, sizeof(newparam.information.keypad)-1);
+       else
+               strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
        call->dialque[0] = '\0';
        send_message(MESSAGE_INFORMATION, call->ref, &newparam);
 }
        call->dialque[0] = '\0';
        send_message(MESSAGE_INFORMATION, call->ref, &newparam);
 }
@@ -1927,8 +1942,13 @@ static int lcr_digit(struct ast_channel *ast, char digit)
        if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING) {
                CDEBUG(call, ast, "Sending digit to LCR, because we are in dialing state.\n");
                memset(&newparam, 0, sizeof(union parameter));
        if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING) {
                CDEBUG(call, ast, "Sending digit to LCR, because we are in dialing state.\n");
                memset(&newparam, 0, sizeof(union parameter));
-               newparam.information.id[0] = digit;
-               newparam.information.id[1] = '\0';
+               if (call->keypad) {
+                       newparam.information.keypad[0] = digit;
+                       newparam.information.keypad[1] = '\0';
+               } else {
+                       newparam.information.id[0] = digit;
+                       newparam.information.id[1] = '\0';
+               }
                send_message(MESSAGE_INFORMATION, call->ref, &newparam);
        } else
        if (!call->ref
                send_message(MESSAGE_INFORMATION, call->ref, &newparam);
        } else
        if (!call->ref
@@ -2742,6 +2762,7 @@ int load_module(void)
                                 "   vr - rxgain control\n"
                                 "   vt - txgain control\n"
                                 "        Volume changes at factor 2 ^ optarg.\n"
                                 "   vr - rxgain control\n"
                                 "   vt - txgain control\n"
                                 "        Volume changes at factor 2 ^ optarg.\n"
+                                "    k - use keypad to dial this call.\n"
                );
 
  
                );
 
  
index 60a64fd..5905ea1 100644 (file)
@@ -65,6 +65,8 @@ struct chan_call {
                                        /* echo cancel pipeline by option */
        int                     tx_gain, rx_gain;
                                        /* gain by option */
                                        /* echo cancel pipeline by option */
        int                     tx_gain, rx_gain;
                                        /* gain by option */
+       int                     keypad;
+                                       /* use keypad to dial number */
        unsigned char           bf_key[56];
        int                     bf_len; /* blowfish crypt key */
        struct ast_dsp          *dsp; /* ast dsp processor for fax/tone detection */
        unsigned char           bf_key[56];
        int                     bf_len; /* blowfish crypt key */
        struct ast_dsp          *dsp; /* ast dsp processor for fax/tone detection */
index 1cb52d1..e318aa3 100644 (file)
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -402,7 +402,7 @@ void Pdss1::setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
        int bearer_coding, bearer_capability, bearer_mode, bearer_rate, bearer_multi, bearer_user;
        int exclusive, channel;
        int ret;
        int bearer_coding, bearer_capability, bearer_mode, bearer_rate, bearer_multi, bearer_user;
        int exclusive, channel;
        int ret;
-       unsigned char keypad[32] = "";
+       unsigned char keypad[33] = "";
        unsigned char useruser[128];
        int useruser_len = 0, useruser_protocol;
        class Endpoint *epoint;
        unsigned char useruser[128];
        int useruser_len = 0, useruser_protocol;
        class Endpoint *epoint;
@@ -746,7 +746,7 @@ void Pdss1::setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
 void Pdss1::information_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
 {
        int type, plan;
 void Pdss1::information_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
 {
        int type, plan;
-       unsigned char keypad[32] = "", display[128] = "";
+       unsigned char keypad[33] = "", display[128] = "";
        struct lcr_msg *message;
 
        l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_IND, DIRECTION_IN);
        struct lcr_msg *message;
 
        l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_IND, DIRECTION_IN);
@@ -2098,6 +2098,9 @@ void Pdss1::message_setup(unsigned int epoint_id, int message_id, union paramete
                enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id, max);
                SCPY(p_m_d_queue, p_dialinginfo.id + max);
        }
                enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id, max);
                SCPY(p_m_d_queue, p_dialinginfo.id + max);
        }
+       /* keypad */
+       if (p_dialinginfo.keypad[0])
+               enc_ie_keypad(l3m, (unsigned char *)p_dialinginfo.keypad);
        /* sending complete */
        if (p_dialinginfo.sending_complete)
                enc_ie_complete(l3m, 1);
        /* sending complete */
        if (p_dialinginfo.sending_complete)
                enc_ie_complete(l3m, 1);
index af070b1..d21daf3 100644 (file)
@@ -855,12 +855,17 @@ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union par
                        if (param->setup.dialinginfo.itype == INFO_ITYPE_ISDN_EXTENSION) {
                                numbers = param->setup.dialinginfo.id;
                                while((number = strsep(&numbers, ","))) {
                        if (param->setup.dialinginfo.itype == INFO_ITYPE_ISDN_EXTENSION) {
                                numbers = param->setup.dialinginfo.id;
                                while((number = strsep(&numbers, ","))) {
-                                       if (out_setup(epoint_id, message_type, param, number))
+                                       if (out_setup(epoint_id, message_type, param, number, NULL))
+                                               return; // join destroyed
+                               }
+                               numbers = param->setup.dialinginfo.id;
+                               while((number = strsep(&numbers, ","))) {
+                                       if (out_setup(epoint_id, message_type, param, NULL, number))
                                                return; // join destroyed
                                }
                                break;
                        }
                                                return; // join destroyed
                                }
                                break;
                        }
-                       if (out_setup(epoint_id, message_type, param, NULL))
+                       if (out_setup(epoint_id, message_type, param, NULL, NULL))
                                return; // join destroyed
                        break;
 
                                return; // join destroyed
                        break;
 
@@ -945,7 +950,7 @@ int track_notify(int oldstate, int notify)
  * if other outgoing endpoints already exists, they are release as well.
  * note: if this functions fails, it will destroy its own join object!
  */
  * if other outgoing endpoints already exists, they are release as well.
  * note: if this functions fails, it will destroy its own join object!
  */
-int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter *param, char *newnumber)
+int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter *param, char *newnumber, char *newkeypad)
 {
        struct join_relation *relation;
        struct lcr_msg *message;
 {
        struct join_relation *relation;
        struct lcr_msg *message;
@@ -974,7 +979,9 @@ int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter
        memcpy(&message->param, param, sizeof(union parameter));
        if (newnumber)
                SCPY(message->param.setup.dialinginfo.id, newnumber);
        memcpy(&message->param, param, sizeof(union parameter));
        if (newnumber)
                SCPY(message->param.setup.dialinginfo.id, newnumber);
-       PDEBUG(DEBUG_JOIN, "setup message sent to ep %d with number='%s'.\n", relation->epoint_id, message->param.setup.dialinginfo.id);
+       if (newkeypad)
+               SCPY(message->param.setup.dialinginfo.keypad, newkeypad);
+       PDEBUG(DEBUG_JOIN, "setup message sent to ep %d with number='%s' keypad='%s'.\n", relation->epoint_id, message->param.setup.dialinginfo.id, message->param.setup.dialinginfo.keypad);
        message_put(message);
        return(0);
 }
        message_put(message);
        return(0);
 }
index 3e275b7..18e38c0 100644 (file)
--- a/joinpbx.h
+++ b/joinpbx.h
@@ -70,7 +70,7 @@ class JoinPBX : public Join
        void bridge_data(unsigned int epoint_from, struct join_relation *relation_from, union parameter *param);
        void remove_relation(struct join_relation *relation);
        struct join_relation *add_relation(void);
        void bridge_data(unsigned int epoint_from, struct join_relation *relation_from, union parameter *param);
        void remove_relation(struct join_relation *relation);
        struct join_relation *add_relation(void);
-       int out_setup(unsigned int epoint_id, int message, union parameter *param, char *newnumber);
+       int out_setup(unsigned int epoint_id, int message, union parameter *param, char *newnumber, char *newkeypad);
        void play_jingle(int in);
 }; 
 
        void play_jingle(int in);
 }; 
 
index 0849f54..63abc65 100644 (file)
--- a/message.h
+++ b/message.h
@@ -178,6 +178,7 @@ struct dialing_info {
        int ntype;                      /* type of number */
        int sending_complete;           /* end of dialing */
        char display[84];               /* display information */
        int ntype;                      /* type of number */
        int sending_complete;           /* end of dialing */
        char display[84];               /* display information */
+       char keypad[33];                /* send keypad facility */
 };
 
 /* call-info structure CONNECT */
 };
 
 /* call-info structure CONNECT */
diff --git a/route.c b/route.c
index 4fecf38..126424f 100644 (file)
--- a/route.c
+++ b/route.c
@@ -242,13 +242,16 @@ struct param_defs param_defs[] = {
        { PARAM_ON,
          "on", PARAM_TYPE_STRING,
          "on=[init|hangup]", "Defines if the action is executed on call init or on hangup."},
        { PARAM_ON,
          "on", PARAM_TYPE_STRING,
          "on=[init|hangup]", "Defines if the action is executed on call init or on hangup."},
+       { PARAM_KEYPAD,
+         "keypad",     PARAM_TYPE_NULL,
+         "keypad", "Use 'keypad facility' for dialing, instead of 'called number'."},
        { 0, NULL, 0, NULL, NULL}
 };
 
 struct action_defs action_defs[] = {
        { ACTION_EXTERNAL,
          "extern",     &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
        { 0, NULL, 0, NULL, NULL}
 };
 
 struct action_defs action_defs[] = {
        { ACTION_EXTERNAL,
          "extern",     &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
-         PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
+         PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT,
          "Call is routed to extern number as dialed."},
        { ACTION_INTERNAL,
          "intern",     &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_internal, &EndpointAppPBX::action_hangup_call,
          "Call is routed to extern number as dialed."},
        { ACTION_INTERNAL,
          "intern",     &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_internal, &EndpointAppPBX::action_hangup_call,
@@ -256,7 +259,7 @@ struct action_defs action_defs[] = {
          "Call is routed to intern extension as given by the dialed number or specified by option."},
        { ACTION_OUTDIAL,
          "outdial",    &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
          "Call is routed to intern extension as given by the dialed number or specified by option."},
        { ACTION_OUTDIAL,
          "outdial",    &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
-         PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
+         PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT,
          "Same as 'extern'"},
        { ACTION_REMOTE,
          "remote",     &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call,
          "Same as 'extern'"},
        { ACTION_REMOTE,
          "remote",     &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call,
diff --git a/route.h b/route.h
index 837aebd..3530ef4 100644 (file)
--- a/route.h
+++ b/route.h
@@ -146,6 +146,7 @@ enum { /* defines when a statement should be executed */
 #define PARAM_CONTEXT          (1LL<<45)
 #define PARAM_EXTEN            (1LL<<46)
 #define PARAM_ON               (1LL<<47)
 #define PARAM_CONTEXT          (1LL<<45)
 #define PARAM_EXTEN            (1LL<<46)
 #define PARAM_ON               (1LL<<47)
+#define PARAM_KEYPAD           (1LL<<48)
 
 /* action index
  * NOTE: The given index is the actual entry number of action_defs[], so add/remove both lists!!!
 
 /* action index
  * NOTE: The given index is the actual entry number of action_defs[], so add/remove both lists!!!