Add clearmode and handle bearer capability according to Osmo-CC spec

This commit is contained in:
Andreas Eversberg 2022-07-03 21:06:17 +02:00
parent 8c0419b70e
commit bc888d85cc
2 changed files with 66 additions and 25 deletions

View File

@ -38,18 +38,37 @@
#include <mISDN/q931.h>
#include <mISDN/suppserv.h>
static struct osmo_cc_helper_audio_codecs codecs_alaw[] = {
static struct osmo_cc_helper_audio_codecs codecs_offer_alaw_ulaw[] = {
{ "PCMA", 8000, 1, g711_transcode_flipped, g711_transcode_flipped },
{ "PCMU", 8000, 1, g711_transcode_alaw_flipped_to_ulaw, g711_transcode_ulaw_to_alaw_flipped },
{ NULL, 0, 0, NULL, NULL},
};
static struct osmo_cc_helper_audio_codecs codecs_ulaw[] = {
static struct osmo_cc_helper_audio_codecs codecs_offer_ulaw_alaw[] = {
{ "PCMU", 8000, 1, g711_transcode_flipped, g711_transcode_flipped },
{ "PCMA", 8000, 1, g711_transcode_ulaw_flipped_to_alaw, g711_transcode_alaw_to_ulaw_flipped },
{ NULL, 0, 0, NULL, NULL},
};
static struct osmo_cc_helper_audio_codecs codecs_offer_clearmode[] = {
{ "CLEARMODE", 8000, 1, NULL, NULL },
{ NULL, 0, 0, NULL, NULL},
};
static struct osmo_cc_helper_audio_codecs codecs_accept_alaw_ulaw_clearmode[] = {
{ "PCMA", 8000, 1, g711_transcode_flipped, g711_transcode_flipped },
{ "PCMU", 8000, 1, g711_transcode_alaw_flipped_to_ulaw, g711_transcode_ulaw_to_alaw_flipped },
{ "CLEARMODE", 8000, 1, NULL, NULL },
{ NULL, 0, 0, NULL, NULL},
};
static struct osmo_cc_helper_audio_codecs codecs_accept_ulaw_alaw_clearmode[] = {
{ "PCMA", 8000, 1, g711_transcode_flipped, g711_transcode_flipped },
{ "PCMU", 8000, 1, g711_transcode_alaw_flipped_to_ulaw, g711_transcode_ulaw_to_alaw_flipped },
{ "CLEARMODE", 8000, 1, NULL, NULL },
{ NULL, 0, 0, NULL, NULL},
};
static struct l3_msg *create_l3msg(void)
{
struct l3_msg *l3m;
@ -101,7 +120,8 @@ static void release_and_destroy(call_t *call, uint8_t cc_isdn_cause, uint16_t cc
if (cc_isdn_cause || cc_sip_cause) {
/* create osmo-cc message */
if (call->state == ISDN_STATE_OUT_SETUP)
if (call->state == ISDN_STATE_IDLE
|| call->state == ISDN_STATE_OUT_SETUP)
msg = osmo_cc_new_msg(OSMO_CC_MSG_REJ_IND);
else
msg = osmo_cc_new_msg(OSMO_CC_MSG_REL_IND);
@ -183,6 +203,8 @@ void setup_ind(call_t *call, uint32_t pid, struct l3_msg *l3m)
char redir[33];
char display[128];
int rc;
struct osmo_cc_helper_audio_codecs *codecs;
int clearmode = 0;
PDEBUG(DDSS1, DEBUG_INFO, "SETUP INDICATION (pid = 0x%x)\n", pid);
@ -261,21 +283,29 @@ void setup_ind(call_t *call, uint32_t pid, struct l3_msg *l3m)
osmo_cc_add_ie_redir(msg, type, plan, present, screen, reason, redir);
}
/* bearer capability FIXME: clearmode */
/* bearer capability */
rc = dec_ie_bearer(l3m, &coding, &capability, &has_mode, &mode, &rate, &has_multi, &multi, &has_user, &user);
if (rc >= 0) {
if (!has_mode)
mode = 0;
osmo_cc_add_ie_bearer(msg, coding, capability, mode);
/* set bchannel mode */
/* use clear mode */
if (capability==OSMO_CC_CAPABILITY_DATA
|| capability==OSMO_CC_CAPABILITY_DATA_RESTRICTED
|| capability==OSMO_CC_CAPABILITY_VIDEO)
call->b_mode = B_MODE_HDLC;
clearmode = 1;
}
/* select codec */
if (clearmode)
codecs = codecs_offer_clearmode;
else if (call->isdn_ep->law == 'a')
codecs = codecs_offer_alaw_ulaw;
else
codecs = codecs_offer_ulaw_alaw;
/* sdp offer */
call->cc_session = osmo_cc_helper_audio_offer(&call->isdn_ep->cc_ep.session_config, call, (call->isdn_ep->law == 'a') ? codecs_alaw : codecs_ulaw, bchannel_send, msg, 1);
call->cc_session = osmo_cc_helper_audio_offer(&call->isdn_ep->cc_ep.session_config, call, codecs, bchannel_send, msg, 1);
/* dialing complete */
dec_ie_complete(l3m, &sending_complete);
@ -1509,11 +1539,18 @@ void setup_req(call_t *call, osmo_cc_msg_t *msg)
char display[128];
int channel, exclusive;
int rc;
struct osmo_cc_helper_audio_codecs *codecs;
PDEBUG(DDSS1, DEBUG_INFO, "SETUP REQUEST\n");
/* select codec */
if (call->isdn_ep->law == 'a')
codecs = codecs_accept_alaw_ulaw_clearmode;
else
codecs = codecs_accept_ulaw_alaw_clearmode;
/* sdp accept, force our codec, so we can use bchannel bridging if remote side supports it too */
sdp = osmo_cc_helper_audio_accept(&call->isdn_ep->cc_ep.session_config, call, (call->isdn_ep->law == 'a') ? codecs_alaw : codecs_ulaw, bchannel_send, msg, &call->cc_session, &call->codec, 1/*force*/);
sdp = osmo_cc_helper_audio_accept(&call->isdn_ep->cc_ep.session_config, call, codecs, bchannel_send, msg, &call->cc_session, &call->codec, 1/*force*/);
if (!sdp) {
release_and_destroy(call, 47, 415/* Unsupported Media*/, 0);
return;
@ -1544,28 +1581,32 @@ void setup_req(call_t *call, osmo_cc_msg_t *msg)
/* creating setup */
l3m = create_l3msg();
/* bearer capability FIXME: clearmode */
/* bearer capability */
rc = osmo_cc_get_ie_bearer(msg, 0, &coding, &capability, &mode);
if (rc < 0) {
PDEBUG(DDSS1, DEBUG_DEBUG, "No bearer capability given, generating from selected codec.\n");
coding = OSMO_CC_CODING_ITU_T;
capability = OSMO_CC_CAPABILITY_AUDIO;
mode = OSMO_CC_MODE_CIRCUIT;
}
if (!strcmp(call->codec->payload_name, "CLEARMODE")) {
capability = OSMO_CC_CAPABILITY_DATA;
mode = OSMO_CC_MODE_CIRCUIT;
} else {
capability = OSMO_CC_CAPABILITY_AUDIO;
mode = OSMO_CC_MODE_CIRCUIT;
}
} else
PDEBUG(DDSS1, DEBUG_DEBUG, "Bearer capability given, override what is defined by selected codec.\n");
rate = (mode == OSMO_CC_MODE_PACKET) ? 0x00 : 0x10;
if (mode == OSMO_CC_MODE_CIRCUIT && call->isdn_ep->law == 'u') {
if (capability == OSMO_CC_CAPABILITY_AUDIO || capability == OSMO_CC_CAPABILITY_SPEECH) {
has_user = 1;
user = 2;
if (call->isdn_ep->law == 'u')
user = 2;
else
user = 3;
} else {
has_user = 0;
user = 0;
}
if (mode == OSMO_CC_MODE_CIRCUIT && call->isdn_ep->law == 'a') {
has_user = 1;
user = 3;
}
/* set bchannel mode */
if (capability==OSMO_CC_CAPABILITY_DATA
|| capability==OSMO_CC_CAPABILITY_DATA_RESTRICTED
|| capability==OSMO_CC_CAPABILITY_VIDEO)
call->b_mode = B_MODE_HDLC;
printf("rate=%d\n", rate);
enc_ie_bearer(l3m, coding, capability, 1, mode, rate, 0, 0, has_user, user);
/* channel information */

View File

@ -933,7 +933,7 @@ static int bchannel_create(isdn_t *isdn_ep, int index)
/* open socket */
if (isdn_ep->b_mode[index] == B_MODE_HDLC) {
PDEBUG(DISDN, DEBUG_NOTICE, "Use B-Channel with HDLC l!!!\n");
PDEBUG(DISDN, DEBUG_NOTICE, "Use B-Channel with HDLC!!!\n");
}
rc = socket(PF_ISDN, SOCK_DGRAM, (isdn_ep->b_mode[index] == B_MODE_HDLC) ? ISDN_P_B_L2DSPHDLC : ISDN_P_B_L2DSP);
if (rc < 0) {