diff options
Diffstat (limited to 'src/router/call.c')
-rw-r--r-- | src/router/call.c | 134 |
1 files changed, 73 insertions, 61 deletions
diff --git a/src/router/call.c b/src/router/call.c index eca0f75..945c2ac 100644 --- a/src/router/call.c +++ b/src/router/call.c @@ -78,7 +78,7 @@ call_t *call_list = NULL; struct timer status_timer; -static osmo_cc_endpoint_t *cc_ep; +static osmo_cc_endpoint_t *cc_ep_list[3]; static const char *routing_script, *routing_shell; static struct osmo_cc_helper_audio_codecs codecs_def[] = { @@ -95,31 +95,34 @@ static void refresh_status(void) int from_count, to_count; call_t *call; call_relation_t *relation; + int e; display_status_start(); - for (cc_call = cc_ep->call_list; cc_call; cc_call = cc_call->next) { - if (cc_call->state != OSMO_CC_STATE_ATTACH_IN) - continue; - if (!cc_call->attached_name) - continue; - from_count = 0; - for (call = call_list; call; call = call->next) { - if (!call->relation_list) + for (e = 0; cc_ep_list[e]; e++) { + for (cc_call = cc_ep_list[e]->call_list; cc_call; cc_call = cc_call->next) { + if (cc_call->state != OSMO_CC_STATE_ATTACH_IN) continue; - if (!!strcmp(cc_call->attached_name, call->relation_list->interface)) + if (!cc_call->attached_name) continue; - to_count = 0; - for (relation = call->relation_list->next; relation; relation = relation->next) { - display_status_line(cc_call->attached_name, from_count, call->relation_list->id, to_count, relation->interface, relation->id, relation->state); - to_count++; + from_count = 0; + for (call = call_list; call; call = call->next) { + if (!call->relation_list) + continue; + if (!!strcmp(cc_call->attached_name, call->relation_list->interface)) + continue; + to_count = 0; + for (relation = call->relation_list->next; relation; relation = relation->next) { + display_status_line(cc_call->attached_name, from_count, call->relation_list->id, to_count, relation->interface, relation->id, relation->state); + to_count++; + } + if (!to_count) + display_status_line(cc_call->attached_name, from_count, call->relation_list->id, 0, NULL, NULL, 0); + from_count++; } - if (!to_count) - display_status_line(cc_call->attached_name, from_count, call->relation_list->id, 0, NULL, NULL, 0); - from_count++; + if (!from_count) + display_status_line(cc_call->attached_name, 0, NULL, 0, NULL, NULL, 0); } - if (!from_count) - display_status_line(cc_call->attached_name, 0, NULL, 0, NULL, NULL, 0); } display_status_end(); @@ -132,11 +135,14 @@ static void status_timeout(struct timer *timer) static int last_interfaces = -1; osmo_cc_call_t *cc_call; int interfaces = 0; + int e; - for (cc_call = cc_ep->call_list; cc_call; cc_call = cc_call->next) { - if (cc_call->state != OSMO_CC_STATE_ATTACH_IN) - continue; - interfaces++; + for (e = 0; cc_ep_list[e]; e++) { + for (cc_call = cc_ep_list[e]->call_list; cc_call; cc_call = cc_call->next) { + if (cc_call->state != OSMO_CC_STATE_ATTACH_IN) + continue; + interfaces++; + } } if (interfaces != last_interfaces) { @@ -314,9 +320,11 @@ static void relation_destroy(call_relation_t *relation) status_needs_update = 1; } -int call_init(osmo_cc_endpoint_t *ep, const char *_routing_script, const char *_routing_shell) +int call_init(osmo_cc_endpoint_t *cc_ep1, osmo_cc_endpoint_t *cc_ep2, const char *_routing_script, const char *_routing_shell) { - cc_ep = ep; + cc_ep_list[0] = cc_ep1; + cc_ep_list[1] = cc_ep2; + cc_ep_list[2] = NULL; routing_script = _routing_script; routing_shell = _routing_shell; timer_init(&status_timer, status_timeout, NULL); @@ -405,7 +413,7 @@ static void proxy_send_sdp_answer(call_relation_t *relation, osmo_cc_msg_t *msg) */ /* a new call is received */ -static void orig_setup(uint32_t callref, osmo_cc_msg_t *old_msg) +static void orig_setup(osmo_cc_endpoint_t *cc_ep, uint32_t callref, osmo_cc_msg_t *old_msg) { call_t *call; call_relation_t *relation; @@ -421,7 +429,9 @@ static void orig_setup(uint32_t callref, osmo_cc_msg_t *old_msg) abort(); } relation = relation_create(call); + /* link with cc */ + relation->cc_ep = cc_ep; relation->cc_callref = callref; PDEBUG(DROUTER, DEBUG_DEBUG, "%s CC-SETUP-REQ from originator.\n", relation_name(relation)); @@ -517,7 +527,7 @@ static void orig_info(call_t *call, osmo_cc_msg_t *old_msg) strcat(call->relation_list->next->id, number); new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_INFO_IND; - osmo_cc_ll_msg(cc_ep, call->relation_list->next->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->next->cc_ep, call->relation_list->next->cc_callref, new_msg); return; } @@ -571,7 +581,7 @@ static void orig_disc(call_t *call, osmo_cc_msg_t *old_msg) if (!call->relation_list->next) { new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); /* destroy call */ call_destroy(call); return; @@ -585,7 +595,7 @@ static void orig_disc(call_t *call, osmo_cc_msg_t *old_msg) /* forward disc message */ new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_DISC_IND; - osmo_cc_ll_msg(cc_ep, call->relation_list->next->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->next->cc_ep, call->relation_list->next->cc_callref, new_msg); new_state(call, CALL_STATE_DISC_FROM_ORIG); return; } @@ -594,11 +604,11 @@ static void orig_disc(call_t *call, osmo_cc_msg_t *old_msg) for (relation = call->relation_list->next; relation; relation = relation->next) { new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, relation->cc_callref, new_msg); + osmo_cc_ll_msg(relation->cc_ep, relation->cc_callref, new_msg); } new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); /* destroy call */ call_destroy(call); } @@ -620,11 +630,11 @@ static void orig_rel(call_t *call, osmo_cc_msg_t *old_msg) for (relation = call->relation_list->next; relation; relation = relation->next) { new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, relation->cc_callref, new_msg); + osmo_cc_ll_msg(relation->cc_ep, relation->cc_callref, new_msg); } new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_CNF; - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); /* destroy call */ call_destroy(call); } @@ -640,7 +650,7 @@ static void orig_other(call_t *call, osmo_cc_msg_t *old_msg) if (call->relation_list->next && !call->forking) { new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = old_msg->type | 1; /* convert REQ->IND, RSP->CNF */ - osmo_cc_ll_msg(cc_ep, call->relation_list->next->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->next->cc_ep, call->relation_list->next->cc_callref, new_msg); return; } } @@ -663,7 +673,7 @@ static void term_progress(call_t *call, call_relation_t *relation, osmo_cc_msg_t new_msg->type = OSMO_CC_MSG_PROGRESS_IND; /* send SDP answer */ proxy_send_sdp_answer(call->relation_list, new_msg); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); } } @@ -699,7 +709,7 @@ static void term_overlap(call_t *call, call_relation_t *relation, osmo_cc_msg_t } /* send SDP answer */ proxy_send_sdp_answer(call->relation_list, new_msg); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); } /* proceeding is received from terminating side */ @@ -735,7 +745,7 @@ static void term_proc(call_t *call, call_relation_t *relation, osmo_cc_msg_t *ol } /* send SDP answer */ proxy_send_sdp_answer(call->relation_list, new_msg); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); } /* alerting is received from terminating side */ @@ -772,7 +782,7 @@ static void term_alert(call_t *call, call_relation_t *relation, osmo_cc_msg_t *o } /* send SDP answer */ proxy_send_sdp_answer(call->relation_list, new_msg); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); } /* connect is received from terminating side */ @@ -815,8 +825,8 @@ static void term_connect(call_t *call, call_relation_t *relation, osmo_cc_msg_t PDEBUG(DROUTER, DEBUG_DEBUG, "Sending 'non-selected user clearing' to other terminator.\n"); /* send release message */ new_msg = osmo_cc_new_msg(OSMO_CC_MSG_REL_IND); - osmo_cc_add_ie_cause(new_msg, cc_ep->serving_location, OSMO_CC_ISDN_CAUSE_NONSE_USER_CLR, 0, 0); - osmo_cc_ll_msg(cc_ep, other->cc_callref, new_msg); + osmo_cc_add_ie_cause(new_msg, other->cc_ep->serving_location, OSMO_CC_ISDN_CAUSE_NONSE_USER_CLR, 0, 0); + osmo_cc_ll_msg(other->cc_ep, other->cc_callref, new_msg); /* destroy terminating relation */ relation_destroy(other); } @@ -839,7 +849,7 @@ static void term_connect(call_t *call, call_relation_t *relation, osmo_cc_msg_t /* use earlier SDP if not included */ if (!sdp[0] && relation->sdp) osmo_cc_add_ie_sdp(new_msg, relation->sdp); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); } /* disconnect is received from terminating side */ @@ -876,7 +886,7 @@ static void term_disc(call_t *call, call_relation_t *relation, osmo_cc_msg_t *ol new_msg->type = OSMO_CC_MSG_DISC_IND; /* send SDP answer */ proxy_send_sdp_answer(call->relation_list, new_msg); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); return; } @@ -889,7 +899,7 @@ static void term_disc(call_t *call, call_relation_t *relation, osmo_cc_msg_t *ol /* release the terminator */ new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, relation->cc_callref, new_msg); + osmo_cc_ll_msg(relation->cc_ep, relation->cc_callref, new_msg); /* remove relation */ relation_destroy(relation); @@ -898,8 +908,8 @@ static void term_disc(call_t *call, call_relation_t *relation, osmo_cc_msg_t *ol if (!call->relation_list->next) { PDEBUG(DROUTER, DEBUG_DEBUG, "All terminators have disconnected, so we forward a release with the collected cause.\n"); new_msg = osmo_cc_new_msg(OSMO_CC_MSG_REL_IND); - osmo_cc_add_ie_cause(new_msg, cc_ep->serving_location, call->collect_cause, 0, 0); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_add_ie_cause(new_msg, call->relation_list->cc_ep->serving_location, call->collect_cause, 0, 0); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); /* destroy call */ call_destroy(call); } @@ -912,10 +922,10 @@ static void term_disc(call_t *call, call_relation_t *relation, osmo_cc_msg_t *ol PDEBUG(DROUTER, DEBUG_DEBUG, "Got a disconnect after connect, so we directly forward this disconnect.\n"); new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, relation->cc_callref, new_msg); + osmo_cc_ll_msg(relation->cc_ep, relation->cc_callref, new_msg); /* destroy call */ call_destroy(call); return; @@ -947,11 +957,11 @@ static void term_rel(call_t *call, call_relation_t *relation, osmo_cc_msg_t *old /* forward message to originator */ new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); /* confirm to terminator */ new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_CNF; - osmo_cc_ll_msg(cc_ep, relation->cc_callref, new_msg); + osmo_cc_ll_msg(relation->cc_ep, relation->cc_callref, new_msg); /* destroy call */ call_destroy(call); return; @@ -966,7 +976,7 @@ static void term_rel(call_t *call, call_relation_t *relation, osmo_cc_msg_t *old /* confirm the terminator */ new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_CNF; - osmo_cc_ll_msg(cc_ep, relation->cc_callref, new_msg); + osmo_cc_ll_msg(relation->cc_ep, relation->cc_callref, new_msg); /* remove relation */ relation_destroy(relation); @@ -975,8 +985,8 @@ static void term_rel(call_t *call, call_relation_t *relation, osmo_cc_msg_t *old if (!call->relation_list->next) { PDEBUG(DROUTER, DEBUG_DEBUG, "All terminators have released, so we forward it with the collected cause.\n"); new_msg = osmo_cc_new_msg(OSMO_CC_MSG_REL_IND); - osmo_cc_add_ie_cause(new_msg, cc_ep->serving_location, call->collect_cause, 0, 0); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_add_ie_cause(new_msg, call->relation_list->cc_ep->serving_location, call->collect_cause, 0, 0); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); /* destroy call */ call_destroy(call); } @@ -989,10 +999,10 @@ static void term_rel(call_t *call, call_relation_t *relation, osmo_cc_msg_t *old PDEBUG(DROUTER, DEBUG_DEBUG, "Got a release after connect, so we directly forward this release.\n"); new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_IND; - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = OSMO_CC_MSG_REL_CNF; - osmo_cc_ll_msg(cc_ep, relation->cc_callref, new_msg); + osmo_cc_ll_msg(relation->cc_ep, relation->cc_callref, new_msg); /* destroy call */ call_destroy(call); return; @@ -1012,13 +1022,13 @@ static void term_other(call_t *call, call_relation_t *relation, osmo_cc_msg_t *o if (!call->relation_list->next->next) { new_msg = osmo_cc_clone_msg(old_msg); new_msg->type = old_msg->type | 1; /* convert REQ->IND, RSP->CNF */ - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); return; } } /* handle message from upper layer */ -void cc_message(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref, osmo_cc_msg_t *msg) +void cc_message(osmo_cc_endpoint_t *cc_ep, uint32_t callref, osmo_cc_msg_t *msg) { call_t *call; call_relation_t *relation; @@ -1045,7 +1055,7 @@ void cc_message(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref PDEBUG(DROUTER, DEBUG_ERROR, "Received message without call instance, please fix!\n"); return; } - orig_setup(callref, msg); + orig_setup(cc_ep, callref, msg); osmo_cc_free_msg(msg); return; } @@ -1447,11 +1457,13 @@ next_call: if (calls > 1) call->forking = 1; + /* create endpoint */ - osmo_cc_call_t *cc_call = osmo_cc_call_new(cc_ep); + osmo_cc_call_t *cc_call = osmo_cc_call_new(att->ep); call_relation_t *relation = relation_create(call); /* link with cc */ + relation->cc_ep = att->ep; relation->cc_callref = cc_call->callref; PDEBUG(DROUTER, DEBUG_DEBUG, "%s CC-SETUP-IND to terminator.\n", relation_name(relation)); @@ -1942,7 +1954,7 @@ void routing_close(routing_t *routing) new_state(call, CALL_STATE_OVERLAP); /* forward message to originator */ new_msg = osmo_cc_new_msg(OSMO_CC_MSG_SETUP_ACK_IND); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); return; } @@ -1953,8 +1965,8 @@ void routing_close(routing_t *routing) /* there is no way to dial more digits, so we release the call */ new_msg = osmo_cc_new_msg(OSMO_CC_MSG_REL_IND); - osmo_cc_add_ie_cause(new_msg, cc_ep->serving_location, OSMO_CC_ISDN_CAUSE_NO_ROUTE, 0, 0); - osmo_cc_ll_msg(cc_ep, call->relation_list->cc_callref, new_msg); + osmo_cc_add_ie_cause(new_msg, call->relation_list->cc_ep->serving_location, OSMO_CC_ISDN_CAUSE_NO_ROUTE, 0, 0); + osmo_cc_ll_msg(call->relation_list->cc_ep, call->relation_list->cc_callref, new_msg); /* destroy call */ call_destroy(call); |