diff --git a/src/isdn/dss1.c b/src/isdn/dss1.c index fd51756..3fd6653 100644 --- a/src/isdn/dss1.c +++ b/src/isdn/dss1.c @@ -1064,6 +1064,8 @@ void suspend_ind(call_t *call, uint32_t pid, struct l3_msg *l3m) osmo_cc_add_ie_notify(msg, OSMO_CC_NOTIFY_USER_SUSPENDED); new_state(call, ISDN_STATE_SUSPENDED); + memcpy(call->park_callid, callid, len); + call->park_len = len; #warning use clock to send empty packets/holdmusic /* send message to osmo-cc */ @@ -1107,11 +1109,12 @@ void resume_ind(isdn_t *isdn_ep, uint32_t pid, struct l3_msg *l3m) /* process given callref */ if (!call) { + PDEBUG(DDSS1, DEBUG_NOTICE, "No parked call found with given park ID, rejecting.\n"); rc = -85; no_channel: PDEBUG(DDSS1, DEBUG_INFO, "RESUME-REJECT REQUEST (pid = 0x%x)\n", pid); l3m = create_l3msg(); - enc_ie_cause(l3m, call->isdn_ep->serving_location, -rc); + enc_ie_cause(l3m, isdn_ep->serving_location, -rc); isdn_ep->ml3->to_layer3(isdn_ep->ml3, MT_RESUME_REJECT, pid, l3m); return; } @@ -1324,6 +1327,8 @@ void mt_free(call_t *call) case ISDN_STATE_OUT_SETUP: msg = osmo_cc_new_msg(OSMO_CC_MSG_REJ_IND); break; + case ISDN_STATE_SUSPENDED: + return; default: msg = osmo_cc_new_msg(OSMO_CC_MSG_REL_IND); } @@ -2359,6 +2364,30 @@ void rel_req(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) call->isdn_ep->ml3->to_layer3(call->isdn_ep->ml3, MT_RELEASE, call->l3_pid, l3m); } +/* special case where call is suspended */ +void disc_rel_suspended(call_t *call, osmo_cc_msg_t *msg) +{ + uint8_t location, isdn_cause, socket_cause; + uint16_t sip_cause; + int rc; + + rc = osmo_cc_get_ie_cause(msg, 0, &location, &isdn_cause, &sip_cause, &socket_cause); + if (rc < 0) + isdn_cause = OSMO_CC_ISDN_CAUSE_NORM_CALL_CLEAR; + + msg = osmo_cc_new_msg((msg->type == OSMO_CC_MSG_REL_REQ) ? OSMO_CC_MSG_REL_CNF : OSMO_CC_MSG_REL_IND); + + /* cause */ + osmo_cc_add_ie_cause(msg, call->isdn_ep->serving_location, isdn_cause, 0, 0); + + /* send message to osmo-cc */ + osmo_cc_ll_msg(&call->isdn_ep->cc_ep, call->cc_callref, msg); + + /* terminate call */ + new_state(call, ISDN_STATE_IDLE); + call_destroy(call); +} + void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg) { isdn_t *isdn_ep = ep->priv; @@ -2470,6 +2499,10 @@ void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg) break; case OSMO_CC_MSG_DISC_REQ: /* call has been disconnected */ osmo_cc_helper_audio_negotiate(msg, &call->cc_session, &call->codec); + if (call->state == ISDN_STATE_SUSPENDED) { + disc_rel_suspended(call, msg); + break; + } if (call->state != ISDN_STATE_IN_SETUP && call->state != ISDN_STATE_IN_OVERLAP && call->state != ISDN_STATE_IN_PROCEEDING @@ -2485,6 +2518,10 @@ void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg) disc_req(call, call->l3_pid, msg); break; case OSMO_CC_MSG_REL_REQ: /* release isdn port */ + if (call->state == ISDN_STATE_SUSPENDED) { + disc_rel_suspended(call, msg); + break; + } rel_req(call, call->l3_pid, msg); break; default: