Updated libs

master
Andreas Eversberg 4 months ago
parent 6a812616a4
commit 4027c98c53

@ -84,3 +84,10 @@ extern int debug_limit_scroll;
const char *debug_hex(const uint8_t *data, int len);
#define LOGP PDEBUG
#define LOGL_DEBUG DEBUG_DEBUG
#define LOGL_INFO DEBUG_INFO
#define LOGL_NOTICE DEBUG_NOTICE
#define LOGL_ERROR DEBUG_ERROR
#define osmo_hexdump debug_hex

@ -24,6 +24,7 @@
#include <arpa/inet.h>
#include <unistd.h>
#include "../libtimer/timer.h"
#include "../libselect/select.h"
#include "../libdebug/debug.h"
#include "endpoint.h"
@ -35,11 +36,11 @@ static osmo_cc_call_t *call_new(osmo_cc_endpoint_t *ep, uint32_t callref)
call = calloc(1, sizeof(*call));
if (!call) {
PDEBUG(DCC, DEBUG_ERROR, "No memory for call process instance.\n");
LOGP(DCC, LOGL_ERROR, "No memory for call process instance.\n");
abort();
}
PDEBUG(DCC, DEBUG_DEBUG, "Creating new call with callref %u.\n", callref);
LOGP(DCC, LOGL_DEBUG, "Creating new call with callref %u.\n", callref);
call->ep = ep;
call->callref = callref;
@ -58,7 +59,7 @@ static void call_delete(osmo_cc_call_t *call)
{
osmo_cc_call_t **cp;
PDEBUG(DCC, DEBUG_DEBUG, "Destroying call with callref %u.\n", call->callref);
LOGP(DCC, LOGL_DEBUG, "Destroying call with callref %u.\n", call->callref);
/* detach from call process list */
cp = &call->ep->call_list;
@ -104,7 +105,7 @@ static const char *state_names[] = {
static void new_call_state(osmo_cc_call_t *call, enum osmo_cc_state new_state)
{
PDEBUG(DCC, DEBUG_DEBUG, "Changing call state with callref %u from %s to %s.\n", call->callref, state_names[call->state], state_names[new_state]);
LOGP(DCC, LOGL_DEBUG, "Changing call state with callref %u from %s to %s.\n", call->callref, state_names[call->state], state_names[new_state]);
call->state = new_state;
}
@ -159,12 +160,12 @@ static int split_address(const char *address, const char **host_p, uint16_t *por
*host_p = osmo_cc_host_of_address(address);
if (!(*host_p)) {
PDEBUG(DCC, DEBUG_ERROR, "Host IP in given address '%s' is invalid.\n", address);
LOGP(DCC, LOGL_ERROR, "Host IP in given address '%s' is invalid.\n", address);
return -EINVAL;
}
portstring = osmo_cc_port_of_address(address);
if (!portstring) {
PDEBUG(DCC, DEBUG_ERROR, "Port number in given address '%s' is not specified or invalid.\n", address);
LOGP(DCC, LOGL_ERROR, "Port number in given address '%s' is not specified or invalid.\n", address);
return -EINVAL;
}
*port_p = atoi(portstring);
@ -219,7 +220,7 @@ static void forward_to_ul(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
if (address && msg->type == OSMO_CC_MSG_SETUP_IND) {
rc = split_address(address, &host, &port);
if (rc < 0) {
PDEBUG(DCC, DEBUG_ERROR, "Given remote peer's address '%s' in setup message is invalid, rejecting call.\n", address);
LOGP(DCC, LOGL_ERROR, "Given remote peer's address '%s' in setup message is invalid, rejecting call.\n", address);
reject:
/* reject, due to error */
osmo_cc_free_msg(msg);
@ -228,21 +229,21 @@ reject:
call_delete(call);
return;
}
PDEBUG(DCC, DEBUG_DEBUG, "Using host IP '%s' and port '%d' from setup message.\n", host, port);
LOGP(DCC, LOGL_DEBUG, "Using host IP '%s' and port '%d' from setup message.\n", host, port);
}
/* for attach message, use remote peer */
if (msg->type == OSMO_CC_MSG_ATTACH_IND) {
host = call->ep->remote_host;
port = call->ep->remote_port;
PDEBUG(DCC, DEBUG_DEBUG, "Using host IP '%s' and port '%d' from remote address for attach message.\n", host, port);
LOGP(DCC, LOGL_DEBUG, "Using host IP '%s' and port '%d' from remote address for attach message.\n", host, port);
}
/* if there is no remote peer in the setup message, use remote peer */
if (!address && msg->type == OSMO_CC_MSG_SETUP_IND && call->ep->remote_host) {
host = call->ep->remote_host;
port = call->ep->remote_port;
PDEBUG(DCC, DEBUG_DEBUG, "Using host IP '%s' and port '%d' from remote address for setup message.\n", host, port);
LOGP(DCC, LOGL_DEBUG, "Using host IP '%s' and port '%d' from remote address for setup message.\n", host, port);
}
/* if there is no remote peer set, try to use the interface name */
@ -256,16 +257,16 @@ reject:
/* check for incoming attachment */
att = osmo_cc_get_attached_interface(call->ep, interface);
if (!att && !interface[0]) {
PDEBUG(DCC, DEBUG_ERROR, "No remote peer attached, rejecting call.\n");
LOGP(DCC, LOGL_ERROR, "No remote peer attached, rejecting call.\n");
goto reject;
}
if (!att) {
PDEBUG(DCC, DEBUG_ERROR, "No remote peer attached for given interface '%s', rejecting call.\n", interface);
LOGP(DCC, LOGL_ERROR, "No remote peer attached for given interface '%s', rejecting call.\n", interface);
goto reject;
}
host = att->attached_host;
port = att->attached_port;
PDEBUG(DCC, DEBUG_DEBUG, "Using host IP '%s' and port '%d' from attached peer for setup message.\n", host, port);
LOGP(DCC, LOGL_DEBUG, "Using host IP '%s' and port '%d' from attached peer for setup message.\n", host, port);
}
/* add local interface name to setup message */
@ -278,13 +279,13 @@ reject:
}
/* send attach indication to socket */
void send_attach_ind(struct timer *timer)
void send_attach_ind(void *data)
{
osmo_cc_endpoint_t *ep = (osmo_cc_endpoint_t *)timer->priv;
osmo_cc_endpoint_t *ep = data;
osmo_cc_call_t *call;
osmo_cc_msg_t *msg;
PDEBUG(DCC, DEBUG_DEBUG, "Trying to attach to remote peer \"%s\".\n", ep->remote_host);
LOGP(DCC, LOGL_DEBUG, "Trying to attach to remote peer \"%s\".\n", ep->remote_host);
/* create new call for attachment */
call = osmo_cc_call_new(ep);
@ -305,7 +306,7 @@ void send_attach_ind(struct timer *timer)
void attach_rsp(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
{
PDEBUG(DCC, DEBUG_INFO, "Attached to remote peer \"%s\".\n", call->ep->remote_address);
LOGP(DCC, LOGL_INFO, "Attached to remote peer \"%s\".\n", call->ep->remote_address);
/* set state */
new_call_state(call, OSMO_CC_STATE_ATTACH_OUT);
@ -320,11 +321,11 @@ void attach_rel(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
if (call->state == OSMO_CC_STATE_ATTACH_SENT
|| call->state == OSMO_CC_STATE_ATTACH_OUT) {
timer_start(&call->ep->attach_timer, OSMO_CC_ATTACH_TIMER);
PDEBUG(DCC, DEBUG_INFO, "Attachment to remote peer \"%s\" failed, retrying.\n", call->ep->remote_address);
LOGP(DCC, LOGL_INFO, "Attachment to remote peer \"%s\" failed, retrying.\n", call->ep->remote_address);
}
if (call->attached_name)
PDEBUG(DCC, DEBUG_INFO, "Peer with remote interface \"%s\" detached from us.\n", call->attached_name);
LOGP(DCC, LOGL_INFO, "Peer with remote interface \"%s\" detached from us.\n", call->attached_name);
/* change state */
new_call_state(call, OSMO_CC_STATE_IDLE);
@ -355,12 +356,12 @@ void attach_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
if (rc < 0)
address[0] = '\0';
if (!address[0]) {
PDEBUG(DCC, DEBUG_ERROR, "Attachment request from remote peer has no remote address set, rejecting.\n");
LOGP(DCC, LOGL_ERROR, "Attachment request from remote peer has no remote address set, rejecting.\n");
rel:
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* message to socket */
forward_to_ul(call, msg);
@ -372,7 +373,7 @@ rel:
}
rc = split_address(address, &host, &port);
if (rc < 0) {
PDEBUG(DCC, DEBUG_ERROR, "Given remote peer's address '%s' in attach message is invalid, rejecting call.\n", address);
LOGP(DCC, LOGL_ERROR, "Given remote peer's address '%s' in attach message is invalid, rejecting call.\n", address);
goto rel;
}
free((char *)call->attached_host);
@ -387,11 +388,11 @@ rel:
call->attached_name = strdup(interface);
}
PDEBUG(DCC, DEBUG_INFO, "Remote peer with socket address '%s' and port '%d' and interface '%s' attached to us.\n", call->attached_host, call->attached_port, call->attached_name);
LOGP(DCC, LOGL_INFO, "Remote peer with socket address '%s' and port '%d' and interface '%s' attached to us.\n", call->attached_host, call->attached_port, call->attached_name);
/* changing to confirm message */
msg->type = OSMO_CC_MSG_ATTACH_CNF;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* message to socket */
forward_to_ul(call, msg);
@ -666,7 +667,7 @@ static void disc_collision_ind(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_REQ;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to lower layer */
forward_to_ll(call, msg);
@ -687,7 +688,7 @@ static void disc_collision_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
if (call->lower_layer_released) {
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to upper layer */
forward_to_ul(call, msg);
@ -725,7 +726,7 @@ static void rej_ind_disc(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to REL_IND */
msg->type = OSMO_CC_MSG_REL_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to upper layer */
forward_to_ul(call, msg);
@ -741,7 +742,7 @@ static void rej_req_disc(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_REQ;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to lower layer */
forward_to_ll(call, msg);
@ -770,7 +771,7 @@ static void rel_ind_other(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to DISC_IND */
msg->type = OSMO_CC_MSG_DISC_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
call->lower_layer_released = 1;
/* to upper layer */
@ -797,7 +798,7 @@ static void rel_req_other(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to DISC_REQ */
msg->type = OSMO_CC_MSG_DISC_REQ;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
LOGP(DCC, LOGL_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
call->upper_layer_released = 1;
/* to lower layer */
@ -954,16 +955,16 @@ static void handle_msg(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
&& ((1 << call->state) & statemachine_list[i].states))
break;
if (i == STATEMACHINE_LEN) {
PDEBUG(DCC, DEBUG_INFO, "Message %s unhandled at state %s (callref %d)\n",
LOGP(DCC, LOGL_INFO, "Message %s unhandled at state %s (callref %d)\n",
osmo_cc_msg_value2name(msg->type), state_names[call->state], call->callref);
osmo_cc_free_msg(msg);
return;
}
PDEBUG(DCC, DEBUG_INFO, "Handle message %s at state %s (callref %d)\n",
LOGP(DCC, LOGL_INFO, "Handle message %s at state %s (callref %d)\n",
osmo_cc_msg_value2name(msg->type), state_names[call->state], call->callref);
if (debuglevel <= DEBUG_INFO)
osmo_cc_debug_ie(msg, DEBUG_INFO);
if (debuglevel <= LOGL_INFO)
osmo_cc_debug_ie(msg, LOGL_INFO);
statemachine_list[i].action(call, msg);
}
@ -1040,7 +1041,7 @@ void osmo_cc_ll_msg(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg
osmo_cc_call_t *call;
if (!(msg->type & 1)) {
PDEBUG(DCC, DEBUG_ERROR, "Received message from lower layer that is not an _IND nor _CNF, please fix!\n");
LOGP(DCC, LOGL_ERROR, "Received message from lower layer that is not an _IND nor _CNF, please fix!\n");
osmo_cc_free_msg(msg);
return;
}
@ -1063,7 +1064,7 @@ void osmo_cc_ul_msg(void *priv, uint32_t callref, osmo_cc_msg_t *msg)
osmo_cc_call_t *call;
if ((msg->type & 1)) {
PDEBUG(DCC, DEBUG_ERROR, "Received message from socket that is not an _REQ nor _RSP, please fix!\n");
LOGP(DCC, LOGL_ERROR, "Received message from socket that is not an _REQ nor _RSP, please fix!\n");
osmo_cc_free_msg(msg);
return;
}
@ -1124,7 +1125,7 @@ static int osmo_cc_set_name(osmo_cc_endpoint_t *ep, const char *text)
text++;
}
} else {
PDEBUG(DCC, DEBUG_ERROR, "Invalid name definition '%s'\n", text);
LOGP(DCC, LOGL_ERROR, "Invalid name definition '%s'\n", text);
return -EINVAL;
}
@ -1187,12 +1188,12 @@ static int osmo_cc_set_address(osmo_cc_endpoint_t *ep, const char *text)
text++;
}
if (!strcasecmp(text, "auto")) {
PDEBUG(DCC, DEBUG_DEBUG, "setting automatic remote peer selection\n");
LOGP(DCC, LOGL_DEBUG, "setting automatic remote peer selection\n");
ep->remote_auto = 1;
return 0;
}
if (!strcasecmp(text, "none")) {
PDEBUG(DCC, DEBUG_DEBUG, "disable automatic remote peer selection\n");
LOGP(DCC, LOGL_DEBUG, "disable automatic remote peer selection\n");
ep->remote_auto = 0;
return 0;
}
@ -1201,7 +1202,7 @@ static int osmo_cc_set_address(osmo_cc_endpoint_t *ep, const char *text)
host_p = &ep->remote_host;
port_p = &ep->remote_port;
} else {
PDEBUG(DCC, DEBUG_ERROR, "Invalid local or remote address definition '%s'\n", text);
LOGP(DCC, LOGL_ERROR, "Invalid local or remote address definition '%s'\n", text);
return -EINVAL;
}
@ -1226,7 +1227,7 @@ static int osmo_cc_set_address(osmo_cc_endpoint_t *ep, const char *text)
enum osmo_cc_session_addrtype addrtype;
addrtype = osmo_cc_address_type(*host_p);
if (addrtype == osmo_cc_session_addrtype_unknown) {
PDEBUG(DCC, DEBUG_ERROR, "Given local address '%s' is invalid.\n", *host_p);
LOGP(DCC, LOGL_ERROR, "Given local address '%s' is invalid.\n", *host_p);
return -EINVAL;
}
osmo_cc_set_local_peer(&ep->session_config, osmo_cc_session_nettype_inet, addrtype, *host_p);
@ -1260,7 +1261,7 @@ static int osmo_cc_set_rtp(osmo_cc_endpoint_t *ep, const char *text)
text += 9;
ports = 1;
} else {
PDEBUG(DCC, DEBUG_ERROR, "Invalid RTP definition '%s'\n", text);
LOGP(DCC, LOGL_ERROR, "Invalid RTP definition '%s'\n", text);
return -EINVAL;
}
@ -1275,7 +1276,7 @@ static int osmo_cc_set_rtp(osmo_cc_endpoint_t *ep, const char *text)
enum osmo_cc_session_addrtype addrtype;
addrtype = osmo_cc_address_type(text);
if (addrtype == osmo_cc_session_addrtype_unknown) {
PDEBUG(DCC, DEBUG_ERROR, "Given RTP address '%s' is invalid.\n", text);
LOGP(DCC, LOGL_ERROR, "Given RTP address '%s' is invalid.\n", text);
return -EINVAL;
}
osmo_cc_set_local_peer(&ep->session_config, osmo_cc_session_nettype_inet, addrtype, text);
@ -1288,7 +1289,7 @@ static int osmo_cc_set_rtp(osmo_cc_endpoint_t *ep, const char *text)
/* from port */
while (*text > ' ') {
if (*text < '0' || *text > '9') {
PDEBUG(DCC, DEBUG_ERROR, "Given 'from' port in '%s' is invalid.\n", text);
LOGP(DCC, LOGL_ERROR, "Given 'from' port in '%s' is invalid.\n", text);
return -EINVAL;
}
from = from * 10 + *text - '0';
@ -1305,7 +1306,7 @@ static int osmo_cc_set_rtp(osmo_cc_endpoint_t *ep, const char *text)
/* to port */
while (*text > ' ') {
if (*text < '0' || *text > '9') {
PDEBUG(DCC, DEBUG_ERROR, "Given 'to' port in '%s' is invalid.\n", text);
LOGP(DCC, LOGL_ERROR, "Given 'to' port in '%s' is invalid.\n", text);
return -EINVAL;
}
to = to * 10 + *text - '0';
@ -1334,10 +1335,10 @@ int osmo_cc_new(osmo_cc_endpoint_t *ep, const char *version, const char *name, u
int rc;
int i;
PDEBUG(DCC, DEBUG_DEBUG, "Creating new endpoint instance.\n");
LOGP(DCC, LOGL_DEBUG, "Creating new endpoint instance.\n");
if (!!strcmp(version, OSMO_CC_VERSION)) {
PDEBUG(DCC, DEBUG_ERROR, "Application was compiled for different Osmo-CC version.\n");
LOGP(DCC, LOGL_ERROR, "Application was compiled for different Osmo-CC version.\n");
return OSMO_CC_RC_VERSION_MISMATCH;
}
@ -1391,7 +1392,7 @@ int osmo_cc_new(osmo_cc_endpoint_t *ep, const char *version, const char *name, u
return rc;
}
} else {
PDEBUG(DCC, DEBUG_ERROR, "Unknown osmo-cc argument \"%s\"\n", argv[i]);
LOGP(DCC, LOGL_ERROR, "Unknown osmo-cc argument \"%s\"\n", argv[i]);
return -EINVAL;
}
}
@ -1407,7 +1408,7 @@ int osmo_cc_new(osmo_cc_endpoint_t *ep, const char *version, const char *name, u
port = ep->local_port;
if (!host) {
host = "127.0.0.1";
PDEBUG(DCC, DEBUG_DEBUG, "No local peer set, using default \"%s\"\n", host);
LOGP(DCC, LOGL_DEBUG, "No local peer set, using default \"%s\"\n", host);
}
rc = osmo_cc_open_socket(&ep->os, host, port, ep, osmo_cc_ul_msg, serving_location);
if (rc < 0) {
@ -1429,12 +1430,12 @@ int osmo_cc_new(osmo_cc_endpoint_t *ep, const char *version, const char *name, u
if (ep->remote_auto) {
free((char *)ep->remote_host);
ep->remote_host = strdup(ep->local_host);
PDEBUG(DCC, DEBUG_DEBUG, "Remote peer set to auto, using local peer's host \"%s\" for remote peer.\n", ep->remote_host);
LOGP(DCC, LOGL_DEBUG, "Remote peer set to auto, using local peer's host \"%s\" for remote peer.\n", ep->remote_host);
if (rc == OSMO_CC_DEFAULT_PORT)
ep->remote_port = OSMO_CC_DEFAULT_PORT + 1;
else
ep->remote_port = OSMO_CC_DEFAULT_PORT;
PDEBUG(DCC, DEBUG_DEBUG, " -> Using remote port %d.\n", ep->remote_port);
LOGP(DCC, LOGL_DEBUG, " -> Using remote port %d.\n", ep->remote_port);
/* create address string */
free((char *)ep->remote_address);
addrtype = osmo_cc_address_type(ep->remote_host);
@ -1447,7 +1448,7 @@ int osmo_cc_new(osmo_cc_endpoint_t *ep, const char *version, const char *name, u
/* attach to remote host */
timer_init(&ep->attach_timer, send_attach_ind, ep);
if (ep->remote_host) {
send_attach_ind(&ep->attach_timer);
send_attach_ind(ep->attach_timer.data);
}
}
@ -1459,7 +1460,7 @@ void osmo_cc_delete(osmo_cc_endpoint_t *ep)
{
osmo_cc_endpoint_t **epp;
PDEBUG(DCC, DEBUG_DEBUG, "Destroying endpoint instance.\n");
LOGP(DCC, LOGL_DEBUG, "Destroying endpoint instance.\n");
/* detach from list >*/
epp = &osmo_cc_endpoint_list;
@ -1535,7 +1536,7 @@ const char *osmo_cc_host_of_address(const char *address)
char *p;
if (strlen(address) >= sizeof(host)) {
PDEBUG(DCC, DEBUG_ERROR, "String way too long!\n");
LOGP(DCC, LOGL_ERROR, "String way too long!\n");
return NULL;
}

@ -25,6 +25,7 @@
#include <sys/time.h>
#include <inttypes.h>
#include "../libtimer/timer.h"
#include "../libselect/select.h"
#include "../libdebug/debug.h"
#include "endpoint.h"
#include "helper.h"
@ -62,24 +63,24 @@ const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *pr
int i, selected_codec_i, telephone_event_i;
if (*session_p) {
PDEBUG(DCC, DEBUG_ERROR, "Session already set, please fix!\n");
LOGP(DCC, LOGL_ERROR, "Session already set, please fix!\n");
abort();
}
if (*codec_p) {
PDEBUG(DCC, DEBUG_ERROR, "Codec already set, please fix!\n");
LOGP(DCC, LOGL_ERROR, "Codec already set, please fix!\n");
abort();
}
/* SDP IE */
rc = osmo_cc_get_ie_sdp(msg, 0, offer_sdp, sizeof(offer_sdp));
if (rc < 0) {
PDEBUG(DCC, DEBUG_ERROR, "There is no SDP included in setup request.\n");
LOGP(DCC, LOGL_ERROR, "There is no SDP included in setup request.\n");
return NULL;
}
*session_p = osmo_cc_session_receive_offer(conf, priv, offer_sdp);
if (!*session_p) {
PDEBUG(DCC, DEBUG_ERROR, "Failed to parse SDP.\n");
LOGP(DCC, LOGL_ERROR, "Failed to parse SDP.\n");
return NULL;
}
@ -123,7 +124,7 @@ const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *pr
break;
}
if (!selected_codec) {
PDEBUG(DCC, DEBUG_ERROR, "No codec found in setup message that we support.\n");
LOGP(DCC, LOGL_ERROR, "No codec found in setup message that we support.\n");
osmo_cc_free_session(*session_p);
*session_p = NULL;
return NULL;
@ -153,7 +154,7 @@ int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **sessi
int rc;
if (!(*session_p)) {
PDEBUG(DCC, DEBUG_ERROR, "Session not set, please fix!\n");
LOGP(DCC, LOGL_ERROR, "Session not set, please fix!\n");
abort();
}
@ -184,7 +185,7 @@ int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **sessi
}
}
if (!(*codec_p)) {
PDEBUG(DCC, DEBUG_ERROR, "No codec found in setup reply message that we support.\n");
LOGP(DCC, LOGL_ERROR, "No codec found in setup reply message that we support.\n");
return -EIO;
}

@ -374,7 +374,7 @@ osmo_cc_msg_t *osmo_cc_new_msg(uint8_t msg_type)
/* allocate message */
msg = calloc(1, sizeof(*msg) + 65535);
if (!msg) {
PDEBUG(DCC, DEBUG_ERROR, "No memory\n");
LOGP(DCC, LOGL_ERROR, "No memory\n");
abort();
}
/* set message type and zero length */
@ -453,14 +453,14 @@ void osmo_cc_debug_ie(osmo_cc_msg_t *msg, int level)
ie = (osmo_cc_ie_t *)p;
/* check for minimum IE length */
if (msg_len < sizeof(*ie)) {
PDEBUG(DCC, level, "****** Rest of message is too short for an IE: value=%s\n", debug_hex(p, msg_len));
LOGP(DCC, level, "****** Rest of message is too short for an IE: value=%s\n", debug_hex(p, msg_len));
return;
}
/* get actual IE length */
len = ntohs(ie->length_networkorder);
/* check if IE length does not exceed message */
if (msg_len < sizeof(*ie) + len) {
PDEBUG(DCC, level, "****** IE: type=0x%02x length=%d would exceed the rest length of message (%d bytes left)\n", ie->type, len, msg_len - (int)sizeof(*ie));
LOGP(DCC, level, "****** IE: type=0x%02x length=%d would exceed the rest length of message (%d bytes left)\n", ie->type, len, msg_len - (int)sizeof(*ie));
return;
}
switch (ie->type) {
@ -468,109 +468,109 @@ void osmo_cc_debug_ie(osmo_cc_msg_t *msg, int level)
rc = osmo_cc_get_ie_called(msg, ie_repeat[ie->type], &type, &plan, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) plan=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), string);
LOGP(DCC, level, " %s type=%d(%s) plan=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), string);
break;
case OSMO_CC_IE_CALLED_SUB:
rc = osmo_cc_get_ie_called_sub(msg, ie_repeat[ie->type], &type, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), string);
LOGP(DCC, level, " %s type=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), string);
break;
case OSMO_CC_IE_CALLED_NAME:
rc = osmo_cc_get_ie_called_name(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_CALLED_INTERFACE:
rc = osmo_cc_get_ie_called_interface(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_COMPLETE:
rc = osmo_cc_get_ie_complete(msg, ie_repeat[ie->type]);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s\n", osmo_cc_ie_value2name(ie->type));
LOGP(DCC, level, " %s\n", osmo_cc_ie_value2name(ie->type));
break;
case OSMO_CC_IE_CALLING:
rc = osmo_cc_get_ie_calling(msg, ie_repeat[ie->type], &type, &plan, &present, &screen, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) plan=%d(%s), presentation=%d(%s), screening=%d(%s), number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), present, osmo_cc_present_value2name(present), screen, osmo_cc_screen_value2name(screen), string);
LOGP(DCC, level, " %s type=%d(%s) plan=%d(%s), presentation=%d(%s), screening=%d(%s), number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), present, osmo_cc_present_value2name(present), screen, osmo_cc_screen_value2name(screen), string);
break;
case OSMO_CC_IE_CALLING_SUB:
rc = osmo_cc_get_ie_calling_sub(msg, ie_repeat[ie->type], &type, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), string);
LOGP(DCC, level, " %s type=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), string);
break;
case OSMO_CC_IE_CALLING_NAME:
rc = osmo_cc_get_ie_calling_name(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_CALLING_INTERFACE:
rc = osmo_cc_get_ie_calling_interface(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_CALLING_NETWORK:
rc = osmo_cc_get_ie_calling_network(msg, ie_repeat[ie->type], &type, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) id='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_network_value2name(type), string);
LOGP(DCC, level, " %s type=%d(%s) id='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_network_value2name(type), string);
break;
case OSMO_CC_IE_BEARER:
rc = osmo_cc_get_ie_bearer(msg, ie_repeat[ie->type], &coding, &capability, &mode);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s coding=%d(%s) capability=%d(%s) mode=%d(%s)\n", osmo_cc_ie_value2name(ie->type), coding, osmo_cc_coding_value2name(coding), capability, osmo_cc_capability_value2name(capability), mode, osmo_cc_mode_value2name(mode));
LOGP(DCC, level, " %s coding=%d(%s) capability=%d(%s) mode=%d(%s)\n", osmo_cc_ie_value2name(ie->type), coding, osmo_cc_coding_value2name(coding), capability, osmo_cc_capability_value2name(capability), mode, osmo_cc_mode_value2name(mode));
break;
case OSMO_CC_IE_REDIR:
rc = osmo_cc_get_ie_redir(msg, ie_repeat[ie->type], &type, &plan, &present, &screen, &reason, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) plan=%d(%s) presentation=%d(%s) screening=%d(%s) reason=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), present, osmo_cc_present_value2name(present), screen, osmo_cc_screen_value2name(screen), reason, osmo_cc_redir_reason_value2name(reason), string);
LOGP(DCC, level, " %s type=%d(%s) plan=%d(%s) presentation=%d(%s) screening=%d(%s) reason=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), present, osmo_cc_present_value2name(present), screen, osmo_cc_screen_value2name(screen), reason, osmo_cc_redir_reason_value2name(reason), string);
break;
case OSMO_CC_IE_DTMF:
rc = osmo_cc_get_ie_dtmf(msg, ie_repeat[ie->type], &duration_ms, &pause_ms, &dtmf_mode, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s duration=%dms pause=%dms mode=%d(%s)\n", osmo_cc_ie_value2name(ie->type), duration_ms, pause_ms, dtmf_mode, osmo_cc_dtmf_mode_value2name(dtmf_mode));
LOGP(DCC, level, " %s duration=%dms pause=%dms mode=%d(%s)\n", osmo_cc_ie_value2name(ie->type), duration_ms, pause_ms, dtmf_mode, osmo_cc_dtmf_mode_value2name(dtmf_mode));
break;
case OSMO_CC_IE_KEYPAD:
rc = osmo_cc_get_ie_keypad(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s digits='%s'\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s digits='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_PROGRESS:
rc = osmo_cc_get_ie_progress(msg, ie_repeat[ie->type], &coding, &location, &progress);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s coding=%d(%s) location=%d(%s) progress=%d(%s)\n", osmo_cc_ie_value2name(ie->type), coding, osmo_cc_coding_value2name(coding), location, osmo_cc_location_value2name(location), progress, osmo_cc_progress_value2name(progress));
LOGP(DCC, level, " %s coding=%d(%s) location=%d(%s) progress=%d(%s)\n", osmo_cc_ie_value2name(ie->type), coding, osmo_cc_coding_value2name(coding), location, osmo_cc_location_value2name(location), progress, osmo_cc_progress_value2name(progress));
break;
case OSMO_CC_IE_NOTIFY:
rc = osmo_cc_get_ie_notify(msg, ie_repeat[ie->type], &notify);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s indicator=%d(%s)\n", osmo_cc_ie_value2name(ie->type), notify, osmo_cc_notify_value2name(notify));
LOGP(DCC, level, " %s indicator=%d(%s)\n", osmo_cc_ie_value2name(ie->type), notify, osmo_cc_notify_value2name(notify));
break;
case OSMO_CC_IE_CAUSE:
rc = osmo_cc_get_ie_cause(msg, ie_repeat[ie->type], &location, &isdn_cause, &sip_cause, &socket_cause);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s location=%d(%s) isdn_cause=%d(%s) sip_cause=%d socket_cause=%d(%s)\n", osmo_cc_ie_value2name(ie->type), location, osmo_cc_location_value2name(location), isdn_cause, osmo_cc_isdn_cause_value2name(isdn_cause), sip_cause, socket_cause, osmo_cc_socket_cause_value2name(socket_cause));
LOGP(DCC, level, " %s location=%d(%s) isdn_cause=%d(%s) sip_cause=%d socket_cause=%d(%s)\n", osmo_cc_ie_value2name(ie->type), location, osmo_cc_location_value2name(location), isdn_cause, osmo_cc_isdn_cause_value2name(isdn_cause), sip_cause, socket_cause, osmo_cc_socket_cause_value2name(socket_cause));
break;
case OSMO_CC_IE_DISPLAY:
rc = osmo_cc_get_ie_display(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s info='%s'\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s info='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_SDP:
rc = osmo_cc_get_ie_sdp(msg, ie_repeat[ie->type], string, sizeof(string));
@ -582,22 +582,22 @@ void osmo_cc_debug_ie(osmo_cc_msg_t *msg, int level)
if (string[i] == '\n')
string[i] = 'n';
}
PDEBUG(DCC, level, " %s payload=%s\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s payload=%s\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_SOCKET_ADDRESS:
rc = osmo_cc_get_ie_socket_address(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s address='%s'\n", osmo_cc_ie_value2name(ie->type), string);
LOGP(DCC, level, " %s address='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_PRIVATE:
rc = osmo_cc_get_ie_private(msg, ie_repeat[ie->type], &unique, (uint8_t *)string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s unique=%u=0x%08x private=%s\n", osmo_cc_ie_value2name(ie->type), unique, unique, debug_hex((uint8_t *)string, rc));
LOGP(DCC, level, " %s unique=%u=0x%08x private=%s\n", osmo_cc_ie_value2name(ie->type), unique, unique, debug_hex((uint8_t *)string, rc));
break;
default:
PDEBUG(DCC, level, " %s type=0x%02x length=%d value=%s\n", osmo_cc_ie_value2name(ie->type), ie->type, len, debug_hex(ie->data, len));
LOGP(DCC, level, " %s type=0x%02x length=%d value=%s\n", osmo_cc_ie_value2name(ie->type), ie->type, len, debug_hex(ie->data, len));
}
ie_repeat[ie->type]++;
p += sizeof(*ie) + len;
@ -625,16 +625,16 @@ int osmo_cc_get_ie_struct(osmo_cc_msg_t *msg, uint8_t ie_type, int ie_repeat, in
ie = (osmo_cc_ie_t *)p;
/* check for minimum IE length */
if (msg_len < sizeof(*ie)) {
PDEBUG(DCC, DEBUG_ERROR, "MSG short read\n");
osmo_cc_debug_ie(msg, DEBUG_ERROR);
LOGP(DCC, LOGL_ERROR, "MSG short read\n");
osmo_cc_debug_ie(msg, LOGL_ERROR);
return -EINVAL;
}
/* get actual IE length */
len = ntohs(ie->length_networkorder);
/* check if IE length does not exceed message */
if (msg_len < sizeof(*ie) + len) {
PDEBUG(DCC, DEBUG_ERROR, "MSG short read\n");
osmo_cc_debug_ie(msg, DEBUG_ERROR);
LOGP(DCC, LOGL_ERROR, "MSG short read\n");
osmo_cc_debug_ie(msg, LOGL_ERROR);
return -EINVAL;
}
/* check if IE matches the one that is searched for */
@ -652,7 +652,7 @@ int osmo_cc_get_ie_struct(osmo_cc_msg_t *msg, uint8_t ie_type, int ie_repeat, in
}
/* return IE and indicate how many bytes we have more than the given length*/
if (ntohs(ie->length_networkorder) < ie_len) {
PDEBUG(DCC, DEBUG_ERROR, "IE 0x%02d has length of %d, but we expect it to have at least %d!\n", ie_type, ntohs(ie->length_networkorder), ie_len);
LOGP(DCC, LOGL_ERROR, "IE 0x%02d has length of %d, but we expect it to have at least %d!\n", ie_type, ntohs(ie->length_networkorder), ie_len);
return -EINVAL;
}
*ie_struct = ie;
@ -728,7 +728,7 @@ void *osmo_cc_add_ie(osmo_cc_msg_t *msg, uint8_t ie_type, int ie_len)
msg_len = ntohs(msg->length_networkorder);
new_msg_len = msg_len + sizeof(*ie) + ie_len;
if (new_msg_len > 65535) {
PDEBUG(DCC, DEBUG_ERROR, "MSG overflow\n");
LOGP(DCC, LOGL_ERROR, "MSG overflow\n");
return NULL;
}
msg->length_networkorder = htons(new_msg_len);

@ -28,6 +28,7 @@
#include <arpa/inet.h>
#include "../libdebug/debug.h"
#include "../libtimer/timer.h"
#include "../libselect/select.h"
#include "endpoint.h"
#define RTP_VERSION 2
@ -67,11 +68,11 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_
if (len < 0) {
if (errno == EAGAIN)
return -EAGAIN;
PDEBUG(DCC, DEBUG_DEBUG, "Read errno = %d (%s)\n", errno, strerror(errno));
LOGP(DCC, LOGL_DEBUG, "Read errno = %d (%s)\n", errno, strerror(errno));
return -EIO;
}
if (len < 12) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame too short (len = %d).\n", len);
LOGP(DCC, LOGL_NOTICE, "Received RTP frame too short (len = %d).\n", len);
return -EINVAL;
}
@ -86,20 +87,20 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_
*ssrc_p = ntohl(rtph->ssrc);
if (version != RTP_VERSION) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP version %d not supported.\n", version);
LOGP(DCC, LOGL_NOTICE, "Received RTP version %d not supported.\n", version);
return -EINVAL;
}
payload = data + sizeof(*rtph) + (csrc_count << 2);
payload_len = len - sizeof(*rtph) - (csrc_count << 2);
if (payload_len < 0) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame too short (len = %d, csrc count = %d).\n", len, csrc_count);
LOGP(DCC, LOGL_NOTICE, "Received RTP frame too short (len = %d, csrc count = %d).\n", len, csrc_count);
return -EINVAL;
}
if (extension) {
if (payload_len < (int)sizeof(*rtpxh)) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame too short for extension header.\n");
LOGP(DCC, LOGL_NOTICE, "Received RTP frame too short for extension header.\n");
return -EINVAL;
}
rtpxh = (struct rtp_x_hdr *)payload;
@ -107,19 +108,19 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_
payload += x_len;
payload_len -= x_len;
if (payload_len < (int)sizeof(*rtpxh)) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame too short, extension header exceeds frame length.\n");
LOGP(DCC, LOGL_NOTICE, "Received RTP frame too short, extension header exceeds frame length.\n");
return -EINVAL;
}
}
if (padding) {
if (payload_len < 1) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame too short for padding length.\n");
LOGP(DCC, LOGL_NOTICE, "Received RTP frame too short for padding length.\n");
return -EINVAL;
}
payload_len -= payload[payload_len - 1];
if (payload_len < 0) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame padding is greater than payload.\n");
LOGP(DCC, LOGL_NOTICE, "Received RTP frame padding is greater than payload.\n");
return -EINVAL;
}
}
@ -132,6 +133,22 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_
return 0;
}
static int rtcp_receive(int sock)
{
static uint8_t data[2048];
int len;
len = read(sock, data, sizeof(data));
if (len < 0) {
if (errno == EAGAIN)
return -EAGAIN;
LOGP(DCC, LOGL_DEBUG, "Read errno = %d (%s)\n", errno, strerror(errno));
return -EIO;
}
return 0;
}
static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t marker, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc)
{
struct rtp_hdr *rtph;
@ -147,16 +164,19 @@ static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t marker
rtph->ssrc = htonl(ssrc);
len += payload_len;
if (len > (int)sizeof(data)) {
PDEBUG(DCC, DEBUG_NOTICE, "Buffer overflow, please fix!.\n");
LOGP(DCC, LOGL_NOTICE, "Buffer overflow, please fix!.\n");
abort();
}
memcpy(data + sizeof(*rtph), payload, payload_len);
rc = write(sock, data, len);
if (rc < 0)
PDEBUG(DCC, DEBUG_DEBUG, "Write errno = %d (%s)\n", errno, strerror(errno));
LOGP(DCC, LOGL_DEBUG, "Write errno = %d (%s)\n", errno, strerror(errno));
}
static int rtp_listen_cb(struct osmo_fd *ofd, unsigned int when);
static int rtcp_listen_cb(struct osmo_fd *ofd, unsigned int when);
/* open and bind RTP
* set local port to what we bound
*/
@ -186,7 +206,7 @@ int osmo_cc_rtp_open(osmo_cc_session_media_t *media)
rc = inet_pton(AF_INET, media->connection_data_local.address, &sa4->sin_addr);
if (rc < 1) {
pton_error:
PDEBUG(DCC, DEBUG_NOTICE, "Cannot bind to address '%s'.\n", media->connection_data_local.address);
LOGP(DCC, LOGL_NOTICE, "Cannot bind to address '%s'.\n", media->connection_data_local.address);
return -EINVAL;
}
sport = &sa4->sin_port;
@ -204,7 +224,7 @@ pton_error:
slen = sizeof(*sa6);
break;
case osmo_cc_session_addrtype_unknown:
PDEBUG(DCC, DEBUG_NOTICE, "Unsupported address type '%s'.\n", media->connection_data_local.addrtype_name);
LOGP(DCC, LOGL_NOTICE, "Unsupported address type '%s'.\n", media->connection_data_local.addrtype_name);
return -EINVAL;
}
@ -217,46 +237,54 @@ pton_error:
rc = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
if (rc < 0) {
socket_error:
PDEBUG(DCC, DEBUG_ERROR, "Cannot create socket (domain=%d, errno=%d(%s))\n", domain, errno, strerror(errno));
LOGP(DCC, LOGL_ERROR, "Cannot create socket (domain=%d, errno=%d(%s))\n", domain, errno, strerror(errno));
osmo_cc_rtp_close(media);
return -EIO;
}
media->rtp_socket = rc;
media->rtp_ofd.fd = rc;
media->rtp_ofd.cb = rtp_listen_cb;
media->rtp_ofd.data = media;
media->rtp_ofd.when = OSMO_FD_READ;
osmo_fd_register(&media->rtp_ofd);
rc = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
if (rc < 0)
goto socket_error;
media->rtcp_socket = rc;
media->rtcp_ofd.fd = rc;
media->rtcp_ofd.cb = rtcp_listen_cb;
media->rtcp_ofd.data = media;
media->rtcp_ofd.when = OSMO_FD_READ;
osmo_fd_register(&media->rtcp_ofd);
/* bind sockets */
*sport = htons(conf->rtp_port_next);
rc = bind(media->rtp_socket, (struct sockaddr *)&sa, slen);
rc = bind(media->rtp_ofd.fd, (struct sockaddr *)&sa, slen);
if (rc < 0) {
bind_error:
osmo_cc_rtp_close(media);
conf->rtp_port_next = (conf->rtp_port_next + 2 > conf->rtp_port_to) ? conf->rtp_port_from : conf->rtp_port_next + 2;
if (conf->rtp_port_next == start_port) {
PDEBUG(DCC, DEBUG_ERROR, "Cannot bind socket (errno=%d(%s))\n", errno, strerror(errno));
LOGP(DCC, LOGL_ERROR, "Cannot bind socket (errno=%d(%s))\n", errno, strerror(errno));
return -EIO;
}
continue;
}
*sport = htons(conf->rtp_port_next + 1);
rc = bind(media->rtcp_socket, (struct sockaddr *)&sa, slen);
rc = bind(media->rtcp_ofd.fd, (struct sockaddr *)&sa, slen);
if (rc < 0)
goto bind_error;
media->description.port_local = conf->rtp_port_next;
conf->rtp_port_next = (conf->rtp_port_next + 2 > conf->rtp_port_to) ? conf->rtp_port_from : conf->rtp_port_next + 2;
/* set nonblocking io */
flags = fcntl(media->rtp_socket, F_GETFL);
/* set nonblocking io, to prevent write to block */
flags = fcntl(media->rtp_ofd.fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(media->rtp_socket, F_SETFL, flags);
flags = fcntl(media->rtcp_socket, F_GETFL);
fcntl(media->rtp_ofd.fd, F_SETFL, flags);
flags = fcntl(media->rtcp_ofd.fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(media->rtcp_socket, F_SETFL, flags);
fcntl(media->rtcp_ofd.fd, F_SETFL, flags);
break;
}
PDEBUG(DCC, DEBUG_DEBUG, "Opening media port %d\n", media->description.port_local);
LOGP(DCC, LOGL_DEBUG, "Opening media port %d\n", media->description.port_local);
return 0;
}
@ -273,7 +301,7 @@ int osmo_cc_rtp_connect(osmo_cc_session_media_t *media)
uint16_t *sport;
int rc;
PDEBUG(DCC, DEBUG_DEBUG, "Connecting media port %d->%d\n", media->description.port_local, media->description.port_remote);
LOGP(DCC, LOGL_DEBUG, "Connecting media port %d->%d\n", media->description.port_local, media->description.port_remote);
switch (media->connection_data_remote.addrtype) {
case osmo_cc_session_addrtype_ipv4:
@ -283,7 +311,7 @@ int osmo_cc_rtp_connect(osmo_cc_session_media_t *media)
rc = inet_pton(AF_INET, media->connection_data_remote.address, &sa4->sin_addr);
if (rc < 1) {
pton_error:
PDEBUG(DCC, DEBUG_NOTICE, "Cannot connect to address '%s'.\n", media->connection_data_remote.address);
LOGP(DCC, LOGL_NOTICE, "Cannot connect to address '%s'.\n", media->connection_data_remote.address);
return -EINVAL;
}
sport = &sa4->sin_port;
@ -300,20 +328,20 @@ pton_error:
slen = sizeof(*sa6);
break;
case osmo_cc_session_addrtype_unknown:
PDEBUG(DCC, DEBUG_NOTICE, "Unsupported address type '%s'.\n", media->connection_data_local.addrtype_name);
LOGP(DCC, LOGL_NOTICE, "Unsupported address type '%s'.\n", media->connection_data_local.addrtype_name);
return -EINVAL;
}
*sport = htons(media->description.port_remote);
rc = connect(media->rtp_socket, (struct sockaddr *)&sa, slen);
rc = connect(media->rtp_ofd.fd, (struct sockaddr *)&sa, slen);
if (rc < 0) {
connect_error:
PDEBUG(DCC, DEBUG_NOTICE, "Cannot connect to address '%s'.\n", media->connection_data_remote.address);
LOGP(DCC, LOGL_NOTICE, "Cannot connect to address '%s'.\n", media->connection_data_remote.address);
osmo_cc_rtp_close(media);
return -EIO;
}
*sport = htons(media->description.port_remote + 1);
rc = connect(media->rtcp_socket, (struct sockaddr *)&sa, slen);
rc = connect(media->rtcp_ofd.fd, (struct sockaddr *)&sa, slen);
if (rc < 0)
goto connect_error;
@ -326,7 +354,7 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, ui
uint8_t *payload = NULL;
int payload_len = 0;
if (!codec || !codec->media->rtp_socket)
if (!codec || !codec->media->rtp_ofd.fd)
return;
if (codec->encoder)
@ -336,7 +364,7 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, ui
payload_len = len;
}
rtp_send(codec->media->rtp_socket, payload, payload_len, marker, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc);
rtp_send(codec->media->rtp_ofd.fd, payload, payload_len, marker, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc);
codec->media->tx_sequence += inc_sequence;
codec->media->tx_timestamp += inc_timestamp;
@ -344,9 +372,9 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, ui
free(payload);
}
/* receive rtp data for given media, return < 0, if there is nothing this time */
int osmo_cc_rtp_receive(osmo_cc_session_media_t *media, void *priv)
static int rtp_listen_cb(struct osmo_fd *ofd, unsigned int when)
{
osmo_cc_session_media_t *media = ofd->data;
int rc;
uint8_t *payload = NULL;
int payload_len = 0;
@ -356,49 +384,63 @@ int osmo_cc_rtp_receive(osmo_cc_session_media_t *media, void *priv)
uint8_t *data;
int len;
if (!media || media->rtp_socket <= 0)
return -EIO;
if (when & OSMO_FD_READ) {
rc = rtp_receive(media->rtp_ofd.fd, &payload, &payload_len, &marker, &payload_type, &media->rx_sequence, &media->rx_timestamp, &media->rx_ssrc);
if (rc < 0)
return rc;
rc = rtp_receive(media->rtp_socket, &payload, &payload_len, &marker, &payload_type, &media->rx_sequence, &media->rx_timestamp, &media->rx_ssrc);
if (rc < 0)
return rc;
/* search for codec */
for (codec = media->codec_list; codec; codec = codec->next) {
if (codec->payload_type_local == payload_type)
break;
}
if (!codec) {
LOGP(DCC, LOGL_NOTICE, "Received RTP frame for unknown codec (payload_type = %d).\n", payload_type);
return 0;
}
/* search for codec */
for (codec = media->codec_list; codec; codec = codec->next) {
if (codec->payload_type_local == payload_type)
break;
}
if (!codec) {
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame for unknown codec (payload_type = %d).\n", payload_type);
return 0;
}
if (codec->decoder)
codec->decoder(payload, payload_len, &data, &len, media->session->priv);
else {
data = payload;
len = payload_len;
}
if (codec->decoder)
codec->decoder(payload, payload_len, &data, &len, priv);
else {
data = payload;
len = payload_len;
if (codec->media->receive)
codec->media->receiver(codec, marker, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len);
if (codec->decoder)
free(data);
}
if (codec->media->receive)
codec->media->receiver(codec, marker, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len);
return 0;
}
static int rtcp_listen_cb(struct osmo_fd *ofd, unsigned int when)
{
osmo_cc_session_media_t *media = ofd->data;
int rc;
if (codec->decoder)
free(data);
if (when & OSMO_FD_READ) {
rc = rtcp_receive(media->rtp_ofd.fd);
if (rc < 0)
return rc;
}
return 0;
}
void osmo_cc_rtp_close(osmo_cc_session_media_t *media)
{
if (media->rtp_socket) {
close(media->rtp_socket);
media->rtp_socket = 0;
if (media->rtp_ofd.fd) {
osmo_fd_unregister(&media->rtp_ofd);
close(media->rtp_ofd.fd);
media->rtp_ofd.fd = 0;
}
if (media->rtcp_socket) {
close(media->rtcp_socket);
media->rtcp_socket = 0;
if (media->rtcp_ofd.fd) {
osmo_fd_unregister(&media->rtcp_ofd);
close(media->rtcp_ofd.fd);
media->rtcp_ofd.fd = 0;
}
}

@ -3,6 +3,5 @@ void osmo_cc_set_rtp_ports(osmo_cc_session_config_t *conf, uint16_t from, uint16
int osmo_cc_rtp_open(osmo_cc_session_media_t *media);
int osmo_cc_rtp_connect(osmo_cc_session_media_t *media);
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp, void *priv);
int osmo_cc_rtp_receive(osmo_cc_session_media_t *media, void *priv);
void osmo_cc_rtp_close(osmo_cc_session_media_t *media);

@ -24,6 +24,7 @@
#include <arpa/inet.h>
#include <unistd.h>
#include "../libtimer/timer.h"
#include "../libselect/select.h"
#include "../libdebug/debug.h"
#include "endpoint.h"
#include "message.h"
@ -152,7 +153,7 @@ int osmo_cc_add_screen(osmo_cc_endpoint_t *ep, const char *text)
text += 17;
list_p = &ep->screen_called_out;
} else {
PDEBUG(DCC, DEBUG_ERROR, "Invalid screening definition \"%s\". It must start with 'screen-calling-in' or 'screen-called-in' or 'screen-calling-out' or 'screen-called-out'\n", text);
LOGP(DCC, LOGL_ERROR, "Invalid screening definition \"%s\". It must start with 'screen-calling-in' or 'screen-called-in' or 'screen-calling-out' or 'screen-called-out'\n", text);
return -EINVAL;
}
@ -171,7 +172,7 @@ next_from:
token = osmo_cc_strtok_quotes(&text);
if (!token) {
free(list);
PDEBUG(DCC, DEBUG_ERROR, "Missing 'from' string in screening definition \"%s\". If the string shall be empty, use double quotes. (\'\' or \"\")\n", text);
LOGP(DCC, LOGL_ERROR, "Missing 'from' string in screening definition \"%s\". If the string shall be empty, use double quotes. (\'\' or \"\")\n", text);
return -EINVAL;
}
if (!strcasecmp(token, "unknown")) {
@ -208,8 +209,8 @@ next_from:
if (no_present) {
no_present_error:
free(list);
PDEBUG(DCC, DEBUG_ERROR, "Error in screening definition '%s'.\n", text);
PDEBUG(DCC, DEBUG_ERROR, "Keyword '%s' not allowed in screen entry for called number\n", token);
LOGP(DCC, LOGL_ERROR, "Error in screening definition '%s'.\n", text);
LOGP(DCC, LOGL_ERROR, "Keyword '%s' not allowed in screen entry for called number\n", token);
return -EINVAL;
}
list->has_from_present = 1;
@ -231,8 +232,8 @@ no_present_error:
if (token[i] == '*') {
if (star_used) {
free(list);
PDEBUG(DCC, DEBUG_ERROR, "Error in screening definition '%s'.\n", text);
PDEBUG(DCC, DEBUG_ERROR, "The '*' may be used only once.\n");
LOGP(DCC, LOGL_ERROR, "Error in screening definition '%s'.\n", text);
LOGP(DCC, LOGL_ERROR, "The '*' may be used only once.\n");
return -EINVAL;
}
list->from[j] = SCREEN_STAR;
@ -250,8 +251,8 @@ next_to:
token = osmo_cc_strtok_quotes(&text);