Add -lncurses to LDD flags
[lcr.git] / remote.cpp
index 43c9233..cb6e528 100644 (file)
@@ -16,15 +16,15 @@ unsigned int new_remote = 1000;
 /*
  * constructor
  */
-Premote::Premote(int type, char *portname, struct port_settings *settings, struct interface *interface, int remote_id) : Port(type, portname, settings)
+Premote::Premote(int type, char *portname, struct port_settings *settings, struct interface *interface, int remote_id) : Port(type, portname, settings, interface)
 {
        union parameter param;
 
        p_callerinfo.itype = (interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
        p_r_ref = new_remote++;
        SCPY(p_r_remote_app, interface->remote_app);
-       SCPY(p_r_interface_name, interface->name);
        p_r_tones = (interface->is_tones == IS_YES);
+       p_r_earlyb = (interface->is_earlyb == IS_YES);
 
        /* send new ref to remote socket */
        memset(&param, 0, sizeof(union parameter));
@@ -56,11 +56,12 @@ int Premote::message_epoint(unsigned int epoint_id, int message_type, union para
        if (Port::message_epoint(epoint_id, message_type, param))
                return 1;
 
-       if (message_type == MESSAGE_SETUP) {
+       switch (message_type) {
+       case MESSAGE_SETUP:
                struct interface *interface;
-               interface = getinterfacebyname(p_r_interface_name);
+               interface = getinterfacebyname(p_interface_name);
                if (!interface) {
-                       PERROR("Cannot find interface %s.\n", p_r_interface_name);
+                       PERROR("Cannot find interface %s.\n", p_interface_name);
                        return 0;
                }
                /* attach only if not already */
@@ -80,7 +81,40 @@ int Premote::message_epoint(unsigned int epoint_id, int message_type, union para
                        else
                                SCPY(param->setup.dialinginfo.context, "lcr");
                }
+               memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
+               memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
+               memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
+               memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
+               /* screen */
+               do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_interface_name);
+               do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_interface_name);
+               do_screen(1, p_redirinfo.id, sizeof(p_redirinfo.id), &p_redirinfo.ntype, &p_redirinfo.present, p_interface_name);
+               memcpy(&param->setup.callerinfo, &p_callerinfo, sizeof(p_callerinfo));
+               memcpy(&param->setup.redirinfo, &p_redirinfo, sizeof(p_redirinfo));
+
+               new_state(PORT_STATE_OUT_SETUP);
+               break;
+
+       case MESSAGE_PROCEEDING:
+               new_state(PORT_STATE_IN_PROCEEDING);
+               break;
+
+       case MESSAGE_ALERTING:
+               new_state(PORT_STATE_IN_ALERTING);
+               break;
+
+       case MESSAGE_CONNECT:
+               memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
+               new_state(PORT_STATE_CONNECT);
+               break;
+
+       case MESSAGE_DISCONNECT:
+               new_state(PORT_STATE_OUT_DISCONNECT);
+               break;
 
+       case MESSAGE_RELEASE:
+               new_state(PORT_STATE_RELEASE);
+               break;
        }
 
        /* look for Remote's interface */
@@ -89,20 +123,6 @@ int Premote::message_epoint(unsigned int epoint_id, int message_type, union para
                return 0;               
        }
 
-#if 0
-       /* enable audio path */
-       if (message_type == MESSAGE_SETUP) {
-               union parameter newparam;
-               memset(&newparam, 0, sizeof(union parameter));
-               admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_PATTERN, &newparam);
-               newparam.audiopath = 1;
-               admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_AUDIOPATH, &newparam);
-       }
-#endif
-
-       if (message_type == MESSAGE_CONNECT)
-               new_state(PORT_STATE_CONNECT);
-
        if (message_type == MESSAGE_RELEASE) {
                new_state(PORT_STATE_RELEASE);
                delete this;
@@ -120,13 +140,33 @@ void Premote::message_remote(int message_type, union parameter *param)
 
        switch (message_type) {
        case MESSAGE_TRAFFIC:
+               if (p_dov_rx)
+                       dov_rx(param->traffic.data, param->traffic.len);
+               /* record audio */
+               if (p_record)
+                       record(param->traffic.data, param->traffic.len, 0); // from down
+               if (p_tap)
+                       tap(param->traffic.data, param->traffic.len, 0); // from down
                bridge_tx(param->traffic.data, param->traffic.len);
-               break;
+               if (p_tone_name[0]) {
+                       read_audio(param->traffic.data, param->traffic.len);
+                       /* record audio */
+                       if (p_record)
+                               record(param->traffic.data, param->traffic.len, 1); // from up
+                       if (p_tap)
+                               tap(param->traffic.data, param->traffic.len, 1); // from up
+                       admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, param);
+               } else if (p_dov_tx) {
+                       /* use receeived traffic to trigger sending DOV */
+                       dov_tx(param->traffic.data, param->traffic.len);
+                       admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, param);
+               }
+               return;
 
        case MESSAGE_SETUP:
-               interface = getinterfacebyname(p_r_interface_name);
+               interface = getinterfacebyname(p_interface_name);
                if (!interface) {
-                       PERROR("Cannot find interface %s.\n", p_r_interface_name);
+                       PERROR("Cannot find interface %s.\n", p_interface_name);
                        return;
                }
 
@@ -151,20 +191,46 @@ void Premote::message_remote(int message_type, union parameter *param)
                epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming
 
                epointlist_new(epoint->ep_serial);
-               /* FALL THROUGH: */
-       default:
-               if (message_type == MESSAGE_CONNECT)
-                       new_state(PORT_STATE_CONNECT);
-               /* cannot just forward, because param is not of container "struct lcr_msg" */
-               message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type);
-               memcpy(&message->param, param, sizeof(message->param));
-               message_put(message);
-
-               if (message_type == MESSAGE_RELEASE) {
-                       new_state(PORT_STATE_RELEASE);
-                       delete this;
-                       return;
-               }
+
+               memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
+               memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
+               memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
+               memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
+
+               new_state(PORT_STATE_IN_SETUP);
+               break;
+
+       case MESSAGE_PROCEEDING:
+               new_state(PORT_STATE_OUT_PROCEEDING);
+               break;
+
+       case MESSAGE_ALERTING:
+               new_state(PORT_STATE_OUT_ALERTING);
+               break;
+
+       case MESSAGE_CONNECT:
+               memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
+               new_state(PORT_STATE_CONNECT);
+               break;
+
+       case MESSAGE_DISCONNECT:
+               new_state(PORT_STATE_IN_DISCONNECT);
+               break;
+
+       case MESSAGE_RELEASE:
+               new_state(PORT_STATE_RELEASE);
+               break;
+       }
+
+       /* cannot just forward, because param is not of container "struct lcr_msg" */
+       message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type);
+       memcpy(&message->param, param, sizeof(message->param));
+       message_put(message);
+
+       if (message_type == MESSAGE_RELEASE) {
+               new_state(PORT_STATE_RELEASE);
+               delete this;
+               return;
        }
 }
 
@@ -173,12 +239,24 @@ int Premote::bridge_rx(unsigned char *data, int len)
 {
        union parameter newparam;
        int l;
+       int ret;
+
+       if ((ret = Port::bridge_rx(data, len)))
+               return ret;
 
-       /* don't send tones, if not enabled or not connected */
-       if (!p_r_tones
-        && p_state != PORT_STATE_CONNECT)
+       /* send tones, if connected, or if early audio is enabled in proceeding/alerting state */
+       if (p_state != PORT_STATE_CONNECT
+        && !(p_r_earlyb
+         && (p_state == PORT_STATE_OUT_PROCEEDING
+          || p_state == PORT_STATE_OUT_ALERTING))
+        && !(p_r_tones
+         && (p_state == PORT_STATE_IN_PROCEEDING
+          || p_state == PORT_STATE_IN_ALERTING)))
                return 0;
 
+       if (p_tone_name[0])
+               return 0;
+
        memset(&newparam, 0, sizeof(union parameter));
        /* split, if exeeds data size */
        while(len) {
@@ -187,6 +265,11 @@ int Premote::bridge_rx(unsigned char *data, int len)
                len -= l;
                memcpy(newparam.traffic.data, data, l);
                data += l;
+               /* record audio */
+               if (p_record)
+                       record(data, len, 1); // from up
+               if (p_tap)
+                       tap(data, len, 1); // from up
                admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, &newparam);
        }