Minor fix for GSM HR codec negotiation: Add missing 'break'.
[lcr.git] / dss1.cpp
index 4f3d000..d02f185 100644 (file)
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -1359,10 +1359,10 @@ void Pdss1::hold_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
        l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_IND, DIRECTION_IN);
        end_trace();
 
-       if (!ACTIVE_EPOINT(p_epointlist) || p_m_hold) {
+       if (!ACTIVE_EPOINT(p_epointlist) || p_hold) {
                l3m = create_l3msg();
                l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_REJECT_REQ, DIRECTION_OUT);
-               enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_m_hold?101:31); /* normal unspecified / incompatible state */
+               enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_hold?101:31); /* normal unspecified / incompatible state */
                add_trace("reason", NULL, "no endpoint");
                end_trace();
                p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_HOLD_REJECT, p_m_d_l3id, l3m);
@@ -1383,7 +1383,7 @@ void Pdss1::hold_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
        drop_bchannel();
 
        /* set hold state */
-       p_m_hold = 1;
+       p_hold = 1;
 #if 0
        epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
        if (epoint && p_m_d_ntmode) {
@@ -1411,7 +1411,7 @@ void Pdss1::retrieve_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
        dec_ie_channel_id(l3m, &exclusive, &channel);
        end_trace();
 
-       if (!p_m_hold) {
+       if (!p_hold) {
                cause = 101; /* incompatible state */
                reject:
 
@@ -1445,7 +1445,7 @@ void Pdss1::retrieve_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
        bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
 
        /* set hold state */
-       p_m_hold = 0;
+       p_hold = 0;
        unsched_timer(&p_m_timeout);
 
        /* acknowledge retrieve */
@@ -1675,6 +1675,13 @@ void Pdss1::facility_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
                        message->param.threepty.invoke_id = fac.u.inv.invokeId;
                        message_put(message);
                        return;
+
+                       case Fac_EctExecute:
+                       message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TRANSFER);
+                       message->param.transfer.invoke = 1;
+                       message->param.transfer.invoke_id = fac.u.inv.invokeId;
+                       message_put(message);
+                       return;
                default:
                        ;
                }
@@ -2348,6 +2355,43 @@ void Pdss1::message_3pty(unsigned int epoint_id, int message_id, union parameter
        p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
 }
 
+void Pdss1::enc_ie_facility_ect(l3_msg *l3m, struct param_transfer *transfer)
+{
+       unsigned char fac_ie[256];
+       struct asn1_parm fac;
+
+       /* encode ECT facility */
+       memset(&fac, 0, sizeof(fac));
+       fac.Valid = 1;
+       if (transfer->result) {
+               fac.comp = CompReturnResult;
+               fac.u.retResult.invokeId = transfer->invoke_id;
+               fac.u.retResult.operationValuePresent = 1;
+               fac.u.retResult.operationValue = Fac_EctExecute;
+       }
+       if (transfer->error) {
+               fac.comp = CompReturnError;
+               fac.u.retError.invokeId = transfer->invoke_id;
+               fac.u.retError.errorValue = FacError_Gen_InvalidCallState;
+       }
+       encodeFac(fac_ie, &fac);
+
+       enc_ie_facility(l3m, fac_ie + 2, fac_ie[1]);
+}
+
+/* MESSAGE_TRANSFER */
+void Pdss1::message_transfer(unsigned int epoint_id, int message_id, union parameter *param)
+{
+       l3_msg *l3m;
+
+       /* sending facility */
+       l3m = create_l3msg();
+       l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
+       enc_ie_facility_ect(l3m, &param->transfer);
+       end_trace();
+       p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
+}
+
 /* MESSAGE_NOTIFY */
 void Pdss1::message_notify(unsigned int epoint_id, int message_id, union parameter *param)
 {
@@ -2552,18 +2596,7 @@ void Pdss1::message_connect(unsigned int epoint_id, int message_id, union parame
        /* screen outgoing caller id */
        do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface->name);
 
-       /* only display at connect state */
-       if (p_state == PORT_STATE_CONNECT)
-       if (p_connectinfo.display[0]) {
-               /* sending information */
-               l3m = create_l3msg();
-               l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
-               if (p_m_d_ntmode || p_m_d_tespecial)
-                       enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
-               end_trace();
-               p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
-               return;
-       }
+       set_display(p_connectinfo.display);
 
        if (p_state!=PORT_STATE_IN_SETUP && p_state!=PORT_STATE_IN_OVERLAP && p_state!=PORT_STATE_IN_PROCEEDING && p_state!=PORT_STATE_IN_ALERTING) {
                /* connect command only possible in setup, proceeding or alerting state */
@@ -2700,6 +2733,10 @@ if (/*    ||*/ p_state==PORT_STATE_OUT_SETUP) {
                enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
        /* send cause */
        enc_ie_cause(l3m, (!p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_REMOTE:param->disconnectinfo.location, param->disconnectinfo.cause);
+       /* send facility */
+       if (param->disconnectinfo.transfer.result) {
+               enc_ie_facility_ect(l3m, &param->disconnectinfo.transfer);
+       }
        /* send display */
        if (param->disconnectinfo.display[0])
                p = param->disconnectinfo.display;
@@ -2870,6 +2907,10 @@ int Pdss1::message_epoint(unsigned int epoint_id, int message_id, union paramete
                message_3pty(epoint_id, message_id, param);
                break;
 
+               case MESSAGE_TRANSFER: /* begin result message */
+               message_transfer(epoint_id, message_id, param);
+               break;
+
                case MESSAGE_OVERLAP: /* more information is needed */
                if (p_state!=PORT_STATE_IN_SETUP) {
                        break;
@@ -3088,6 +3129,23 @@ int stack2manager(struct mISDNport *mISDNport, unsigned int cmd, unsigned int pi
        return(0);
 }
 
+void Pdss1::set_display(const char *text)
+{
+       l3_msg *l3m;
+
+       /* only display at connect state */
+       if (p_state == PORT_STATE_CONNECT)
+       if (text[0]) {
+               /* sending information */
+               l3m = create_l3msg();
+               l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
+               if (p_m_d_ntmode || p_m_d_tespecial)
+                       enc_ie_display(l3m, (unsigned char *)text);
+               end_trace();
+               p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
+               return;
+       }
+}