Initially implement the new osmo-mgw and libosmo-mgcp

Leave the old osmo-bsc_mgcp and libosmo-legacy-mgcp as it is; on a copy thereof
(added by a previous commit), apply changes to initially implement the new
osmo-mgw.

Adjust build system and debian packaging to accomodate the new libosmo-mgcp and
osmo-mgw.

The main differences:

*) use a list to manage rtp connections.

Aggregate all rtp related information inside a single struct.

Use a linked list to manage the both connections (net and bts).
The idea behind using a list is that we might support conference
calls at some later point.

Store the linked list in struct mgcp_endpoint, have a private linked
list for each endpoint. The list contains connection items which are
implemented in struct mgcp_conn. A connection is allocated and freed
using the functions in mgcp_conn.c. A connection is allocated on the
reception of a CRCX command and freed with the reception of a DLCX
command.

*) remove external transcoder feature

Fortunatelly the external transcoder feature is not needed
anymore. This patch removes the related code.

*) vty: get rid of CONN_BTS and CONN_NET

Since the new connection model does not make a difference
between BTS and NET connections the VTY should not use
the fixed CONN_BTS and CONN_NET constants.

- Handle the conns list inside the endpoint directly
- introduce function to dump basic rtp connection info
- introduce human readable names for connections

Parts of the code adjusted to use generalized connections instead of explicit
BTS/NET ones:

- teach mgcp_send_dummy() to send dummy packets to any RTP connection
- network: generalize mgcp_bind_net/bts_rtp_port()
- network: generalize mgcp_send()
- tap: generalize call tapping feature
- stat: generalize statistics
- Replace rtp_data_net() and rtp_data_bts() with generalized rtp_data_rx()

*) mgcp_protocol.c fixes:

- check ci string before it is converted:
  In case of missing ci, a nullpointer is delivered to strtoul().
  Add a function that takes ci, checks it and converts it to an
  uint32_t. Use the return code to react on missing ci.
- output error message on missing CI.
- when parsing the mode, print log message when mode is missing.
- use mode_orig when mode is missing.
- fix ptime formatstring to use %u rather than %d.
- cosmetic: log when connection is deleted on DLCX.
- change loglevels of CRCX, MDCX, DLCX events from DEBUG to NOTICE.

*) mgcp_test

- apply rename of strline_r() to mgcp_strline().
- MGCP command macros:
  - Add 'I: 1' parameters.
  - Use proper port numbers:
    from m=audio 0 RTP/AVP 126
    to   m=audio 16002 RTP/AVP 128
  - Change ptime to 'a=ptime:40' because this is what the MGW currently
    returns.  CRCX generally feed a ptime:40 and this is expected to be
    returned.
- struct mgcp_test: Use only one ptype, there are no explicit BTS and NET
  endpoints anymore.
  Hence remove one column from tests[].
- test_messages():
  - Enable: remove '#if 0'
  - Remove concept of BTS and NET endpoints: test only one conn, as they are
    now interchangeable anyway.
  - remove endpoint init, now done internally.
  - add false asserts in error cases.
- test_retransmission():
  - remove endpoint init, now done internally.
  - add false asserts in error cases.
- test_packet_error_detection():
  - Remove concept of BTS and NET endpoints: test only one conn, as they are
    now interchangeable anyway. Use arbitrary conn ids (e.g. 4711).
  - remove endpoint init, now done internally.
  - add false assert in error case.
  - Assert that a conn really vanishes on DLCX, previously the conn would
    remain and just be unused, now it is actually discarded.
- test_no_cycle()
  - Remove concept of BTS and NET endpoints: test only one conn, as they are
    now interchangeable anyway. Use arbitrary conn ids (e.g. 4711).
- test_no_name()
  - Enable: remove '#if 0'.
  - remove endpoint init, now done internally.
  - add false assert in error case.
- mgcp_test.ok: adjust expected results to status quo:
  - We now see two dummy packets instead of one, now sent to both sides because
    we don't know of BTS or NET side. (maybe drop dummy packets later...)
  - packet duration, conn mode: now sane defaults show instead of unset.
- various whitespace and formatting changes from lindent.

Change-Id: Ie008599136c7ed8a0dfbb0cf803188975a499fc5
This commit is contained in:
Philipp Maier 2017-08-22 16:35:41 +02:00 committed by Harald Welte
parent f83ec56212
commit 87bd9be0b0
42 changed files with 3402 additions and 4597 deletions

View File

@ -20,6 +20,7 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = \
libosmo-legacy-mgcp.pc \
libosmo-mgcp-client.pc \
libosmo-mgcp.pc \
$(NULL)
BUILT_SOURCES = $(top_srcdir)/.version

View File

@ -119,18 +119,23 @@ AM_CONFIG_HEADER(bscconfig.h)
AC_OUTPUT(
libosmo-legacy-mgcp.pc
libosmo-mgcp-client.pc
libosmo-mgcp.pc
include/Makefile
include/osmocom/Makefile
include/osmocom/legacy_mgcp/Makefile
include/osmocom/mgcp_client/Makefile
include/osmocom/mgcp/Makefile
src/Makefile
src/libosmo-legacy-mgcp/Makefile
src/libosmo-mgcp-client/Makefile
src/libosmo-mgcp/Makefile
src/osmo-bsc_mgcp/Makefile
src/osmo-mgw/Makefile
tests/Makefile
tests/atlocal
tests/legacy_mgcp/Makefile
tests/mgcp_client/Makefile
tests/mgcp/Makefile
doc/Makefile
doc/examples/Makefile
contrib/Makefile

33
debian/control vendored
View File

@ -16,23 +16,23 @@ Homepage: https://osmocom.org/projects/osmo-mgw
Package: osmo-mgw
Architecture: any
Multi-Arch: foreign
Depends: libosmo-legacy-mgcp0, ${misc:Depends}, ${shlibs:Depends}
Depends: libosmo-mgcp0, ${misc:Depends}, ${shlibs:Depends}
Description: OsmoMGW: Osmocom's Media Gateway for 2G and 3G circuit-switched mobile networks
Package: libosmo-legacy-mgcp0
Package: libosmo-mgcp0
Section: libs
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: libosmo-legacy-mgcp: Osmocom's Media Gateway server library
Description: libosmo-mgcp: Osmocom's Media Gateway server library
Package: libosmo-legacy-mgcp-dev
Package: libosmo-mgcp-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libosmo-legacy-mgcp0 (= ${binary:Version}), ${misc:Depends}
Description: libosmo-legacy-mgcp: Osmocom's Media Gateway server library
Depends: libosmo-mgcp0 (= ${binary:Version}), ${misc:Depends}
Description: libosmo-mgcp: Osmocom's Media Gateway server library
Package: libosmo-mgcp-client0
Section: libs
@ -48,3 +48,24 @@ Architecture: any
Multi-Arch: same
Depends: libosmo-mgcp-client0 (= ${binary:Version}), ${misc:Depends}
Description: libosmo-mgcp-client: Osmocom's Media Gateway Control Protocol client utilities
Package: osmo-bsc-mgcp
Architecture: any
Multi-Arch: foreign
Depends: libosmo-legacy-mgcp0, ${misc:Depends}, ${shlibs:Depends}
Description: OsmoBSC-MGCP: Osmocom's Legacy Media Gateway; use osmo-mgw instead.
Package: libosmo-legacy-mgcp0
Section: libs
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: libosmo-legacy-mgcp: Osmocom's Legacy Media Gateway server library; use libosmo-mgcp instead.
Package: libosmo-legacy-mgcp-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libosmo-legacy-mgcp0 (= ${binary:Version}), ${misc:Depends}
Description: libosmo-legacy-mgcp: Osmocom's Legacy Media Gateway server library; use libosmo-mgcp instead.

4
debian/libosmo-mgcp-dev.install vendored Normal file
View File

@ -0,0 +1,4 @@
usr/include/osmocom/mgcp
usr/lib/*/libosmo-mgcp.so
usr/lib/*/libosmo-mgcp.a
usr/lib/*/pkgconfig/libosmo-mgcp.pc

1
debian/libosmo-mgcp0.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/libosmo-mgcp.so.*

View File

@ -6,7 +6,6 @@ mgcp
!bts ip 10.24.24.1
!bind ip 10.23.24.1
bind port 2427
rtp base 4000
rtp force-ptime 20
sdp audio payload number 98
sdp audio payload name AMR/8000

View File

@ -8,4 +8,7 @@ nobase_include_HEADERS = \
osmocom/legacy_mgcp/osmux.h \
osmocom/mgcp_client/mgcp_client.h \
osmocom/mgcp_client/mgcp_common.h \
osmocom/mgcp/mgcp.h \
osmocom/mgcp/mgcp_internal.h \
osmocom/mgcp/osmux.h \
$(NULL)

View File

@ -1,4 +1,5 @@
SUBDIRS = \
legacy_mgcp \
mgcp_client \
mgcp \
$(NULL)

View File

@ -1,4 +1,7 @@
noinst_HEADERS = \
mgcp_transcode.h \
vty.h \
mgcp_msg.h \
mgcp_conn.h \
mgcp_stat.h \
mgcp_ep.h \
$(NULL)

View File

@ -20,21 +20,21 @@
*
*/
#ifndef OPENBSC_MGCP_H
#define OPENBSC_MGCP_H
#pragma once
#include <osmocom/core/msgb.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/logging.h>
#include <osmocom/mgcp/mgcp_ep.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define RTP_PORT_DEFAULT 4000
#define RTP_PORT_NET_DEFAULT 16000
#define RTP_PORT_DEFAULT_RANGE_START 16002
#define RTP_PORT_DEFAULT_RANGE_END RTP_PORT_DEFAULT_RANGE_START + 64
/**
* Calculate the RTP audio port for the given multiplex
@ -102,26 +102,20 @@ typedef int (*mgcp_processing_setup)(struct mgcp_endpoint *endp,
struct mgcp_rtp_end *dst_end,
struct mgcp_rtp_end *src_end);
struct mgcp_conn_rtp;
typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
int *payload_type,
const char**subtype_name,
const char**fmtp_extra);
#define PORT_ALLOC_STATIC 0
#define PORT_ALLOC_DYNAMIC 1
const char**fmtp_extra,
struct mgcp_conn_rtp *conn);
/**
* This holds information on how to allocate ports
*/
struct mgcp_port_range {
int mode;
/* addr or NULL to fall-back to default */
char *bind_addr;
/* pre-allocated from a base? */
int base_port;
/* dynamically allocated */
int range_start;
int range_end;
@ -160,6 +154,10 @@ struct mgcp_trunk_config {
/* timer */
struct osmo_timer_list keepalive_timer;
/* When set, incoming RTP packets are not filtered
* when ports and ip-address do not match (debug) */
int rtp_accept_all;
unsigned int number_endpoints;
struct mgcp_endpoint *endpoints;
};
@ -188,16 +186,8 @@ struct mgcp_config {
int source_port;
char *local_ip;
char *source_addr;
char *bts_ip;
char *call_agent_addr;
struct in_addr bts_in;
/* transcoder handling */
char *transcoder_ip;
struct in_addr transcoder_in;
int transcoder_remote_base;
/* RTP processing */
mgcp_processing rtp_processing_cb;
mgcp_processing_setup setup_rtp_processing_cb;
@ -206,12 +196,10 @@ struct mgcp_config {
struct osmo_wqueue gw_fd;
struct mgcp_port_range bts_ports;
struct mgcp_port_range net_ports;
struct mgcp_port_range transcoder_ports;
int endp_dscp;
int bts_force_ptime;
int force_ptime;
mgcp_change change_cb;
mgcp_policy policy_cb;
@ -226,10 +214,6 @@ struct mgcp_config {
struct mgcp_trunk_config trunk;
struct llist_head trunks;
/* only used for start with a static configuration */
int last_net_port;
int last_bts_port;
enum mgcp_role role;
/* osmux translator: 0 means disabled, 1 means enabled */
@ -259,11 +243,6 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
int mgcp_vty_init(void);
int mgcp_endpoints_allocate(struct mgcp_trunk_config *cfg);
void mgcp_release_endp(struct mgcp_endpoint *endp);
void mgcp_initialize_endp(struct mgcp_endpoint *endp);
int mgcp_reset_transcoder(struct mgcp_config *cfg);
void mgcp_format_stats(struct mgcp_endpoint *endp, char *stats, size_t size);
int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, uint32_t *pr, uint32_t *_or, int *loss, uint32_t *jitter);
void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval);
/*
@ -293,7 +272,4 @@ int mgcp_send_reset_all(struct mgcp_config *cfg);
int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port);
int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, struct sockaddr_in *addr, char *buf, int rc);
int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len);
#endif

View File

@ -0,0 +1,40 @@
/* Message connection list handling */
/*
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Philipp Maier
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/core/linuxlist.h>
#include <inttypes.h>
struct mgcp_conn *mgcp_conn_alloc(void *ctx, struct mgcp_endpoint *endp,
uint32_t id, enum mgcp_conn_type type,
char *name);
struct mgcp_conn *mgcp_conn_get(struct mgcp_endpoint *endp, uint32_t id);
struct mgcp_conn_rtp *mgcp_conn_get_rtp(struct mgcp_endpoint *endp,
uint32_t id);
void mgcp_conn_free(struct mgcp_endpoint *endp, uint32_t id);
void mgcp_conn_free_oldest(struct mgcp_endpoint *endp);
void mgcp_conn_free_all(struct mgcp_endpoint *endp);
char *mgcp_conn_dump(struct mgcp_conn *conn);
struct mgcp_conn *mgcp_find_dst_conn(struct mgcp_conn *conn);

View File

@ -0,0 +1,50 @@
/* Endpoint types */
/*
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Philipp Maier
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
struct sockaddr_in;
struct mgcp_conn;
/* Callback type for RTP dispatcher functions
(e.g mgcp_dispatch_rtp_bridge_cb, see below) */
typedef int (*mgcp_dispatch_rtp_cb) (int proto, struct sockaddr_in * addr,
char *buf, unsigned int buf_size,
struct mgcp_conn * conn);
/*! MGCP endpoint properties */
struct mgcp_endpoint_type {
/*!< maximum number of connections */
int max_conns;
/*!< callback that defines how to dispatch incoming RTP data */
mgcp_dispatch_rtp_cb dispatch_rtp_cb;
};
/*! MGCP endpoint typeset */
struct mgcp_endpoint_typeset {
struct mgcp_endpoint_type rtp;
};
/*! static MGCP endpoint typeset (pre-initalized, read-only) */
extern const struct mgcp_endpoint_typeset ep_typeset;

View File

@ -23,11 +23,16 @@
#pragma once
#include <string.h>
#include <inttypes.h>
#include <osmocom/core/select.h>
#include <osmocom/mgcp/mgcp.h>
#include <osmocom/core/linuxlist.h>
#define CI_UNUSED 0
#define CONN_ID_BTS 0
#define CONN_ID_NET 1
enum mgcp_trunk_type {
MGCP_TRUNK_VIRTUAL,
MGCP_TRUNK_E1,
@ -80,8 +85,10 @@ struct mgcp_rtp_codec {
struct mgcp_rtp_end {
/* statistics */
unsigned int packets;
unsigned int octets;
unsigned int packets_rx;
unsigned int octets_rx;
unsigned int packets_tx;
unsigned int octets_tx;
unsigned int dropped_packets;
struct in_addr addr;
@ -104,24 +111,11 @@ struct mgcp_rtp_end {
int force_aligned_timing;
void *rtp_process_data;
/*
* Each end has a socket...
*/
/* Each end has a separate socket for RTP and RTCP */
struct osmo_fd rtp;
struct osmo_fd rtcp;
int local_port;
int local_alloc;
};
enum {
MGCP_TAP_BTS_IN,
MGCP_TAP_BTS_OUT,
MGCP_TAP_NET_IN,
MGCP_TAP_NET_OUT,
/* last element */
MGCP_TAP_COUNT
};
struct mgcp_rtp_tap {
@ -136,51 +130,36 @@ struct mgcp_lco {
int pkt_period_max; /* time in ms */
};
enum mgcp_type {
/* Specific rtp connection type (see struct mgcp_conn_rtp) */
enum mgcp_conn_rtp_type {
MGCP_RTP_DEFAULT = 0,
MGCP_RTP_TRANSCODED,
MGCP_OSMUX_BSC,
MGCP_OSMUX_BSC_NAT,
};
#include <osmocom/legacy_mgcp/osmux.h>
#include <osmocom/mgcp/osmux.h>
struct mgcp_conn;
struct mgcp_endpoint {
int allocated;
uint32_t ci;
char *callid;
struct mgcp_lco local_options;
int conn_mode;
int orig_mode;
/* MGCP connection (RTP) */
struct mgcp_conn_rtp {
/* backpointer */
struct mgcp_config *cfg;
struct mgcp_trunk_config *tcfg;
/* Backpointer to conn struct */
struct mgcp_conn *conn;
/* port status for bts/net */
struct mgcp_rtp_end bts_end;
struct mgcp_rtp_end net_end;
/* Specific connection type */
enum mgcp_conn_rtp_type type;
/*
* For transcoding we will send from the local_port
* of trans_bts and it will arrive at trans_net from
* where we will forward it to the network.
*/
struct mgcp_rtp_end trans_bts;
struct mgcp_rtp_end trans_net;
enum mgcp_type type;
/* Port status */
struct mgcp_rtp_end end;
/* sequence bits */
struct mgcp_rtp_state net_state;
struct mgcp_rtp_state bts_state;
/* Sequence bits */
struct mgcp_rtp_state state;
/* fields for re-transmission */
char *last_trans;
char *last_response;
/* tap for the endpoint */
struct mgcp_rtp_tap taps[MGCP_TAP_COUNT];
/* taps for the rtp connection */
struct mgcp_rtp_tap tap_in;
struct mgcp_rtp_tap tap_out;
/* Osmux states (optional) */
struct {
/* Osmux state: disabled, activating, active */
enum osmux_state state;
@ -200,38 +179,64 @@ struct mgcp_endpoint {
} osmux;
};
#define for_each_line(line, save) \
for (line = strline_r(NULL, &save); line;\
line = strline_r(NULL, &save))
/*! Connection type, specifies which member of the union "u" in mgcp_conn
* contains a useful connection description (currently only RTP) */
enum mgcp_conn_type {
MGCP_CONN_TYPE_RTP,
};
static inline char *strline_r(char *str, char **saveptr)
{
char *result;
/*! MGCP connection (untyped) */
struct mgcp_conn {
/*!< list head */
struct llist_head entry;
if (str)
*saveptr = str;
/*!< Backpointer to the endpoint where the conn belongs to */
struct mgcp_endpoint *endp;
result = *saveptr;
/*!< type of the connection (union) */
enum mgcp_conn_type type;
if (*saveptr != NULL) {
*saveptr = strpbrk(*saveptr, "\r\n");
/*!< mode of the connection */
enum mgcp_connection_mode mode;
if (*saveptr != NULL) {
char *eos = *saveptr;
/*!< copy of the mode to restore the original setting (VTY) */
enum mgcp_connection_mode mode_orig;
if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
(*saveptr)++;
(*saveptr)++;
if ((*saveptr)[0] == '\0')
*saveptr = NULL;
/*!< connection id to identify the conntion */
uint32_t id;
*eos = '\0';
}
}
/*!< human readable name (vty, logging) */
char name[256];
return result;
}
/*!< union with connection description */
union {
struct mgcp_conn_rtp rtp;
} u;
/*!< pointer to optional private data */
void *priv;
};
#include <osmocom/mgcp/mgcp_conn.h>
struct mgcp_endpoint_type;
struct mgcp_endpoint {
char *callid;
struct mgcp_lco local_options;
struct llist_head conns;
/* backpointer */
struct mgcp_config *cfg;
struct mgcp_trunk_config *tcfg;
const struct mgcp_endpoint_type *type;
/* fields for re-transmission */
char *last_trans;
char *last_response;
};
#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
@ -247,12 +252,15 @@ struct mgcp_parse_data {
int found;
};
int mgcp_send_dummy(struct mgcp_endpoint *endp);
int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
int mgcp_bind_trans_bts_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
int mgcp_bind_trans_net_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
int mgcp_free_rtp_port(struct mgcp_rtp_end *end);
int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,
char *buf, int rc, struct mgcp_conn_rtp *conn_src,
struct mgcp_conn_rtp *conn_dst);
int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);
int mgcp_dispatch_rtp_bridge_cb(int proto, struct sockaddr_in *addr, char *buf,
unsigned int buf_size, struct mgcp_conn *conn);
int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port,
struct mgcp_conn_rtp *conn);
void mgcp_free_rtp_port(struct mgcp_rtp_end *end);
/* For transcoding we need to manage an in and an output that are connected */
static inline int endp_back_channel(int endpoint)
@ -268,10 +276,6 @@ void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
uint32_t mgcp_rtp_packet_duration(struct mgcp_endpoint *endp,
struct mgcp_rtp_end *rtp);
void mgcp_state_calc_loss(struct mgcp_rtp_state *s, struct mgcp_rtp_end *,
uint32_t *expected, int *loss);
uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *);
/* payload processing default functions */
int mgcp_rtp_processing_default(struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end,
char *data, int *len, int buf_size);
@ -282,8 +286,9 @@ int mgcp_setup_rtp_processing_default(struct mgcp_endpoint *endp,
void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
int *payload_type,
const char**subtype_name,
const char**fmtp_extra);
const char**audio_name,
const char**fmtp_extra,
struct mgcp_conn_rtp *conn);
/* internal RTP Annex A counting */
void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
@ -316,10 +321,9 @@ int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, st
int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
int payload_type, const char *audio_name);
/**
* Internal network related
*/
/*! get the ip-address where the mgw application is bound on.
* \param[in] endp mgcp endpoint, that holds a copy of the VTY parameters
* \returns pointer to a string that contains the source ip-address */
static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
{
if (endp->cfg->net_ports.bind_addr)
@ -327,11 +331,4 @@ static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
return endp->cfg->source_addr;
}
static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
{
if (endp->cfg->bts_ports.bind_addr)
return endp->cfg->bts_ports.bind_addr;
return endp->cfg->source_addr;
}
int mgcp_msg_terminate_nul(struct msgb *msg);

View File

@ -0,0 +1,58 @@
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/* Message parser/generator utilities */
/*
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2012 by On-Waves
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
struct mgcp_conn;
struct mgcp_parse_data;
struct mgcp_endpoint;
void mgcp_disp_msg(unsigned char *message, unsigned int len, char *preamble);
int mgcp_parse_conn_mode(const char *msg, struct mgcp_endpoint *endp,
struct mgcp_conn *conn);
int mgcp_parse_header(struct mgcp_parse_data *pdata, char *data);
int mgcp_parse_osmux_cid(const char *line);
int mgcp_check_param(const struct mgcp_endpoint *endp, const char *line);
int mgcp_verify_call_id(struct mgcp_endpoint *endp, const char *callid);
int mgcp_verify_ci(struct mgcp_endpoint *endp, const char *ci);
char *mgcp_strline(char *str, char **saveptr);
#define for_each_line(line, save)\
for (line = mgcp_strline(NULL, &save); line;\
line = mgcp_strline(NULL, &save))
#define for_each_non_empty_line(line, save)\
for (line = strtok_r(NULL, "\r\n", &save); line;\
line = strtok_r(NULL, "\r\n", &save))
int mgcp_parse_ci(uint32_t *conn_id, const char *ci);

View File

@ -0,0 +1,37 @@
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/* The statistics generator */
/*
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2012 by On-Waves
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/mgcp/mgcp_internal.h>
#include <inttypes.h>
void mgcp_format_stats(char *str, size_t str_len, struct mgcp_conn *conn);
/* Exposed for test purposes only, do not use actively */
void calc_loss(struct mgcp_rtp_state *s, struct mgcp_rtp_end *,
uint32_t *expected, int *loss);
/* Exposed for test purposes only, do not use actively */
uint32_t calc_jitter(struct mgcp_rtp_state *);

View File

@ -1,90 +0,0 @@
/*
* (C) 2014 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef OPENBSC_MGCP_TRANSCODE_H
#define OPENBSC_MGCP_TRANSCODE_H
#include "bscconfig.h"
#include <gsm.h>
#ifdef HAVE_BCG729
#include <bcg729/decoder.h>
#include <bcg729/encoder.h>
#endif
enum audio_format {
AF_INVALID,
AF_S16,
AF_L16,
AF_GSM,
AF_G729,
AF_PCMA,
AF_PCMU
};
struct mgcp_process_rtp_state {
/* decoding */
enum audio_format src_fmt;
union {
gsm gsm_handle;
#ifdef HAVE_BCG729
bcg729DecoderChannelContextStruct *g729_dec;
#endif
} src;
size_t src_frame_size;
size_t src_samples_per_frame;
/* processing */
/* encoding */
enum audio_format dst_fmt;
union {
gsm gsm_handle;
#ifdef HAVE_BCG729
bcg729EncoderChannelContextStruct *g729_enc;
#endif
} dst;
size_t dst_frame_size;
size_t dst_samples_per_frame;
int dst_packet_duration;
int is_running;
uint16_t next_seq;
uint32_t next_time;
int16_t samples[10*160];
size_t sample_cnt;
size_t sample_offs;
};
int mgcp_transcoding_setup(struct mgcp_endpoint *endp,
struct mgcp_rtp_end *dst_end,
struct mgcp_rtp_end *src_end);
void mgcp_transcoding_net_downlink_format(struct mgcp_endpoint *endp,
int *payload_type,
const char**audio_name,
const char**fmtp_extra);
int mgcp_transcoding_process_rtp(struct mgcp_endpoint *endp,
struct mgcp_rtp_end *dst_end,
char *data, int *len, int buf_size);
int mgcp_transcoding_get_frame_size(void *state_, int nsamples, int dst);
#endif /* OPENBSC_MGCP_TRANSCODE_H */

View File

@ -1,7 +1,8 @@
#ifndef _OPENBSC_OSMUX_H_
#define _OPENBSC_OSMUX_H_
#pragma once
#include <osmocom/netif/osmux.h>
struct mgcp_conn_rtp;
#define OSMUX_PORT 1984
@ -11,16 +12,13 @@ enum {
};
int osmux_init(int role, struct mgcp_config *cfg);
int osmux_enable_endpoint(struct mgcp_endpoint *endp, struct in_addr *addr, uint16_t port);
void osmux_disable_endpoint(struct mgcp_endpoint *endp);
void osmux_allocate_cid(struct mgcp_endpoint *endp);
void osmux_release_cid(struct mgcp_endpoint *endp);
int osmux_xfrm_to_rtp(struct mgcp_endpoint *endp, int type, char *buf, int rc);
int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp);
int osmux_send_dummy(struct mgcp_endpoint *endp);
int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
struct in_addr *addr, uint16_t port);
void osmux_disable_conn(struct mgcp_conn_rtp *conn);
void osmux_allocate_cid(struct mgcp_conn_rtp *conn);
void osmux_release_cid(struct mgcp_conn_rtp *conn);
int osmux_xfrm_to_osmux(char *buf, int buf_len, struct mgcp_conn_rtp *conn);
int osmux_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);
int osmux_get_cid(void);
void osmux_put_cid(uint8_t osmux_cid);
int osmux_used_cid(void);
@ -38,4 +36,3 @@ enum osmux_usage {
OSMUX_USAGE_ONLY = 2,
};
#endif

10
libosmo-mgcp.pc.in Normal file
View File

@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Osmocom Media Gateway Control Protocol library
Description: C Utility Library
Version: @VERSION@
Libs: -L${libdir} -losmo-mgcp
Cflags: -I${includedir}/

View File

@ -16,13 +16,15 @@
app_configs = {
"mgcp": ["doc/examples/osmo-bsc_mgcp/mgcp.cfg"],
"osmo-mgw": ["doc/examples/osmo-mgw/osmo-mgw.cfg"],
"osmo-bsc_mgcp": ["doc/examples/osmo-bsc_mgcp/mgcp.cfg"],
}
apps = [(4243, "src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp"),
apps = [(4243, "src/osmo-mgw/osmo-mgw", "OsmoMGW", "osmo-mgw"),
(4243, "src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "osmo-bsc_mgcp"),
]
vty_command = ["./src/osmo-bsc_mgcp/osmo-bsc_mgcp", "-c",
"doc/examples/osmo-bsc_mgcp/mgcp.cfg"]
vty_command = ["./src/osmo-mgw/osmo-mgw", "-c",
"doc/examples/osmo-mgw/osmo-mgw.cfg"]
vty_app = apps[0]

View File

@ -23,9 +23,11 @@ AM_LDFLAGS = \
SUBDIRS = \
libosmo-legacy-mgcp \
libosmo-mgcp-client \
libosmo-mgcp \
$(NULL)
# Programs
SUBDIRS += \
osmo-bsc_mgcp \
osmo-mgw \
$(NULL)

View File

@ -10,7 +10,6 @@ AM_CFLAGS = \
$(LIBOSMOVTY_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(LIBBCG729_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
@ -18,33 +17,31 @@ AM_LDFLAGS = \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMONETIF_LIBS) \
$(COVERAGE_LDFLAGS) \
$(LIBBCG729_LIBS) \
$(NULL)
# This is not at all related to the release version, but a range of supported
# API versions. Read TODO_RELEASE in the source tree's root!
LEGACY_MGCP_LIBVERSION=0:0:0
MGCP_LIBVERSION=0:0:0
lib_LTLIBRARIES = \
libosmo-legacy-mgcp.la \
libosmo-mgcp.la \
$(NULL)
noinst_HEADERS = \
g711common.h \
$(NULL)
libosmo_legacy_mgcp_la_SOURCES = \
libosmo_mgcp_la_SOURCES = \
mgcp_common.c \
mgcp_protocol.c \
mgcp_network.c \
mgcp_vty.c \
mgcp_osmux.c \
mgcp_sdp.c \
mgcp_msg.c \
mgcp_conn.c \
mgcp_stat.c \
mgcp_ep.c \
$(NULL)
if BUILD_MGCP_TRANSCODING
libosmo_legacy_mgcp_la_SOURCES += \
mgcp_transcode.c \
$(NULL)
endif
libosmo_legacy_mgcp_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LEGACY_MGCP_LIBVERSION)
libosmo_mgcp_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(MGCP_LIBVERSION)

View File

@ -23,7 +23,7 @@
#include <errno.h>
#include <osmocom/core/utils.h>
#include <osmocom/legacy_mgcp/mgcp.h>
#include <osmocom/mgcp/mgcp.h>
const struct value_string mgcp_connection_mode_strs[] = {
{ MGCP_CONN_NONE, "none" },

View File

@ -0,0 +1,286 @@
/* Message connection list handling */
/*
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Philipp Maier
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/mgcp_ep.h>
/* Reset codec state and free memory */
static void mgcp_rtp_codec_reset(struct mgcp_rtp_codec *codec)
{
codec->payload_type = -1;
codec->subtype_name = NULL;
codec->audio_name = NULL;
codec->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM;
codec->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN;
codec->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE;
codec->channels = DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS;
/* see also mgcp_sdp.c, mgcp_set_audio_info() */
talloc_free(codec->subtype_name);
talloc_free(codec->audio_name);
}
/* Reset states, free memory, set defaults and reset codec state */
static void mgcp_rtp_conn_reset(struct mgcp_conn_rtp *conn)
{
struct mgcp_rtp_end *end = &conn->end;
conn->type = MGCP_RTP_DEFAULT;
conn->osmux.allocated_cid = -1;
end->rtp.fd = -1;
end->rtcp.fd = -1;
end->local_port = 0;
end->packets_rx = 0;
end->octets_rx = 0;
end->packets_tx = 0;
end->octets_tx = 0;
end->dropped_packets = 0;
end->rtp_port = end->rtcp_port = 0;
talloc_free(end->fmtp_extra);
end->fmtp_extra = NULL;
/* Set default values */
end->frames_per_packet = 0; /* unknown */
end->packet_duration_ms = DEFAULT_RTP_AUDIO_PACKET_DURATION_MS;
end->output_enabled = 0;
mgcp_rtp_codec_reset(&end->codec);
mgcp_rtp_codec_reset(&end->alt_codec);
}
/*! allocate a new connection list entry.
* \param[in] ctx talloc context
* \param[in] endp associated endpoint
* \param[in] id identification number of the connection
* \param[in] type connection type (e.g. MGCP_CONN_TYPE_RTP)
* \returns pointer to allocated connection, NULL on error */
struct mgcp_conn *mgcp_conn_alloc(void *ctx, struct mgcp_endpoint *endp,
uint32_t id, enum mgcp_conn_type type,
char *name)
{
struct mgcp_conn *conn;
OSMO_ASSERT(endp);
OSMO_ASSERT(endp->conns.next != NULL && endp->conns.prev != NULL);
OSMO_ASSERT(strlen(name) < sizeof(conn->name));
/* Do not allow more then two connections */
if (llist_count(&endp->conns) >= endp->type->max_conns)
return NULL;
/* Prevent duplicate connection IDs */
if (mgcp_conn_get(endp, id))
return NULL;
/* Create new connection and add it to the list */
conn = talloc_zero(ctx, struct mgcp_conn);
if (!conn)
return NULL;
conn->endp = endp;
conn->type = type;
conn->mode = MGCP_CONN_NONE;
conn->mode_orig = MGCP_CONN_NONE;
conn->id = id;
conn->u.rtp.conn = conn;
strcpy(conn->name, name);
switch (type) {
case MGCP_CONN_TYPE_RTP:
mgcp_rtp_conn_reset(&conn->u.rtp);
break;
default:
/* NOTE: This should never be called with an
* invalid type, its up to the programmer
* to ensure propery types */
OSMO_ASSERT(false);
}
llist_add(&conn->entry, &endp->conns);
return conn;
}
/*! find a connection by its ID.
* \param[in] endp associated endpoint
* \param[in] id identification number of the connection
* \returns pointer to allocated connection, NULL if not found */
struct mgcp_conn *mgcp_conn_get(struct mgcp_endpoint *endp, uint32_t id)
{
OSMO_ASSERT(endp);
OSMO_ASSERT(endp->conns.next != NULL && endp->conns.prev != NULL);
struct mgcp_conn *conn;
llist_for_each_entry(conn, &endp->conns, entry) {
if (conn->id == id)
return conn;
}
return NULL;
}
/*! find an RTP connection by its ID.
* \param[in] endp associated endpoint
* \param[in] id identification number of the connection
* \returns pointer to allocated connection, NULL if not found */
struct mgcp_conn_rtp *mgcp_conn_get_rtp(struct mgcp_endpoint *endp, uint32_t id)
{
OSMO_ASSERT(endp);
OSMO_ASSERT(endp->conns.next != NULL && endp->conns.prev != NULL);
struct mgcp_conn *conn;
conn = mgcp_conn_get(endp, id);
if (!conn)
return NULL;
if (conn->type == MGCP_CONN_TYPE_RTP)
return &conn->u.rtp;
return NULL;
}
/*! free a connection by its ID.
* \param[in] endp associated endpoint
* \param[in] id identification number of the connection */
void mgcp_conn_free(struct mgcp_endpoint *endp, uint32_t id)
{
OSMO_ASSERT(endp);
OSMO_ASSERT(endp->conns.next != NULL && endp->conns.prev != NULL);
struct mgcp_conn *conn;
conn = mgcp_conn_get(endp, id);
if (!conn)
return;
switch (conn->type) {
case MGCP_CONN_TYPE_RTP:
osmux_disable_conn(&conn->u.rtp);
osmux_release_cid(&conn->u.rtp);
mgcp_free_rtp_port(&conn->u.rtp.end);
break;
default:
/* NOTE: This should never be called with an
* invalid type, its up to the programmer
* to ensure propery types */
OSMO_ASSERT(false);
}
llist_del(&conn->entry);
talloc_free(conn);
}
/*! free oldest connection in the list.
* \param[in] endp associated endpoint */
void mgcp_conn_free_oldest(struct mgcp_endpoint *endp)
{
OSMO_ASSERT(endp);
OSMO_ASSERT(endp->conns.next != NULL && endp->conns.prev != NULL);
struct mgcp_conn *conn;
if (llist_empty(&endp->conns))
return;
conn = llist_last_entry(&endp->conns, struct mgcp_conn, entry);
if (!conn)
return;
mgcp_conn_free(endp, conn->id);
}
/*! free all connections at once.
* \param[in] endp associated endpoint */
void mgcp_conn_free_all(struct mgcp_endpoint *endp)
{
OSMO_ASSERT(endp);
OSMO_ASSERT(endp->conns.next != NULL && endp->conns.prev != NULL);
struct mgcp_conn *conn;
struct mgcp_conn *conn_tmp;
/* Drop all items in the list */
llist_for_each_entry_safe(conn, conn_tmp, &endp->conns, entry) {
mgcp_conn_free(endp, conn->id);
}
return;
}
/*! dump basic connection information to human readble string.
* \param[in] conn to dump
* \returns human readble string */
char *mgcp_conn_dump(struct mgcp_conn *conn)
{
static char str[256];
if (!conn) {
snprintf(str, sizeof(str), "(null connection)");
return str;
}
switch (conn->type) {
case MGCP_CONN_TYPE_RTP:
/* Dump RTP connection */
snprintf(str, sizeof(str), "(%s/rtp, id:%u, ip:%s, "
"rtp:%u rtcp:%u)",
conn->name,
conn->id,
inet_ntoa(conn->u.rtp.end.addr),
ntohs(conn->u.rtp.end.rtp_port),
ntohs(conn->u.rtp.end.rtcp_port));
break;
default:
/* Should not happen, we should be able to dump
* every possible connection type. */
snprintf(str, sizeof(str), "(unknown connection type)");
break;
}
return str;
}
/*! find destination connection on a specific endpoint.
* \param[in] conn to search a destination for
* \returns destination connection, NULL on failure */
struct mgcp_conn *mgcp_find_dst_conn(struct mgcp_conn *conn)
{
struct mgcp_endpoint *endp;
struct mgcp_conn *partner_conn;
endp = conn->endp;
/*! NOTE: This simply works by grabbing the first connection that is
* not the supplied connection, which is suitable for endpoints that
* do not serve more than two connections. */
llist_for_each_entry(partner_conn, &endp->conns, entry) {
if (conn != partner_conn) {
return partner_conn;
}
}
return NULL;
}

View File

@ -0,0 +1,32 @@
/* Endpoint types */
/*
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Philipp Maier
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmocom/mgcp/mgcp_ep.h>
#include <osmocom/mgcp/mgcp_internal.h>
/* Endpoint typeset definition */
const struct mgcp_endpoint_typeset ep_typeset = {
/* Specify endpoint properties for RTP endpoint */
.rtp.max_conns = 2,
.rtp.dispatch_rtp_cb = mgcp_dispatch_rtp_bridge_cb
};

404
src/libosmo-mgcp/mgcp_msg.c Normal file
View File

@ -0,0 +1,404 @@
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/* Message parser/generator utilities */
/*
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2012 by On-Waves
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <limits.h>
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/mgcp_msg.h>
#include <osmocom/mgcp/mgcp_conn.h>
/*! Display an mgcp message on the log output.
* \param[in] message mgcp message string
* \param[in] len message mgcp message string length
* \param[in] preamble string to display in logtext in front of each line */
void mgcp_disp_msg(unsigned char *message, unsigned int len, char *preamble)
{
unsigned char line[80];
unsigned char *ptr;
unsigned int consumed = 0;
unsigned int consumed_line = 0;
unsigned int line_count = 0;
if (!log_check_level(DLMGCP, LOGL_DEBUG))
return;
while (1) {
memset(line, 0, sizeof(line));
ptr = line;
consumed_line = 0;
do {
if (*message != '\n' && *message != '\r') {
*ptr = *message;
ptr++;
}
message++;
consumed++;
consumed_line++;
} while (*message != '\n' && consumed < len
&& consumed_line < sizeof(line));
if (strlen((const char *)line)) {
LOGP(DLMGCP, LOGL_DEBUG, "%s: line #%02u: %s\n",
preamble, line_count, line);
line_count++;
}
if (consumed >= len)
return;
}
}
/*! Parse connection mode.
* \param[in] mode as string (recvonly, sendrecv, sendonly or loopback)
* \param[in] endp pointer to endpoint (only used for log output)
* \param[out] associated connection to be modified accordingly
* \returns 0 on success, -1 on error */
int mgcp_parse_conn_mode(const char *mode, struct mgcp_endpoint *endp,
struct mgcp_conn *conn)
{
int ret = 0;
if (!mode) {
LOGP(DLMGCP, LOGL_ERROR,
"endpoint:%x missing connection mode\n",
ENDPOINT_NUMBER(endp));
return -1;
}
if (!conn)