diff --git a/src/libdebug/debug.c b/src/libdebug/debug.c index 67ba00c..f7b91e0 100644 --- a/src/libdebug/debug.c +++ b/src/libdebug/debug.c @@ -57,6 +57,8 @@ struct debug_cat { { "jollycom", "\033[1;34m" }, { "eurosignal", "\033[1;34m" }, { "pocsag", "\033[1;34m" }, + { "golay", "\033[1;34m" }, + { "5-ton-folge", "\033[1;34m" }, { "frame", "\033[0;36m" }, { "call", "\033[0;37m" }, { "cc", "\033[1;32m" }, @@ -89,12 +91,16 @@ struct debug_cat { { "dss1", "\033[1;34m" }, { "sip", "\033[1;35m" }, { "telephone", "\033[1;34m" }, + { "uk0", "\033[1;34m" }, + { "ph", "\033[0;33m" }, + { "dcf77", "\033[1;34m" }, + { "jitter", "\033[0;36m" }, { NULL, NULL } }; int debuglevel = DEBUG_INFO; int debug_date = 0; -uint64_t debug_mask = ~0; +uint64_t debug_mask[2] = { ~0, ~0 }; extern int num_kanal; void (*clear_console_text)(void) = NULL; @@ -105,6 +111,25 @@ int debug_limit_scroll = 0; static int lock_initialized = 0; static pthread_mutex_t debug_mutex; +void lock_debug(void) +{ + int rc; + + if (!lock_initialized) { + rc = pthread_mutex_init(&debug_mutex, NULL); + if (rc == 0) + lock_initialized = 1; + } + if (lock_initialized) + pthread_mutex_lock(&debug_mutex); +} + +void unlock_debug(void) +{ + if (lock_initialized) + pthread_mutex_unlock(&debug_mutex); +} + void get_win_size(int *w, int *h) { struct winsize win; @@ -127,22 +152,15 @@ void _printdebug(const char *file, const char __attribute__((unused)) *function, int s = sizeof(buffer) - 1; const char *p; va_list args; - int w, h; - int rc; + int w, h = 0; // make GCC happy if (debuglevel > level) return; - if (!(debug_mask & ((uint64_t)1 << cat))) + if (!(debug_mask[cat >> 6] & ((uint64_t)1 << (cat & 63)))) return; - if (!lock_initialized) { - rc = pthread_mutex_init(&debug_mutex, NULL); - if (rc == 0) - lock_initialized = 1; - } - if (lock_initialized) - pthread_mutex_lock(&debug_mutex); + lock_debug(); buffer[sizeof(buffer) - 1] = '\0'; @@ -174,15 +192,14 @@ void _printdebug(const char *file, const char __attribute__((unused)) *function, printf("%04d-%02d-%02d %02d:%02d:%02d.%03d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 10000.0)); } - printf("%s%s:%4d %s: %s\033[0;39m", debug_cat[cat].color, file, line, debug_level[level], buffer); + printf("%s%s %4d %s-%s: %s\033[0;39m", debug_cat[cat].color, file, line, debug_cat[cat].name, debug_level[level], buffer); if (debug_limit_scroll) printf("\0337\033[%d;%dr\0338", 1, h); if (print_console_text) print_console_text(); fflush(stdout); - if (lock_initialized) - pthread_mutex_unlock(&debug_mutex); + unlock_debug(); } const char *debug_amplitude(double level) @@ -274,7 +291,7 @@ int parse_debug_opt(const char *optarg) return -EINVAL; } if (dstring) - debug_mask = 0; + memset(debug_mask, 0, sizeof(debug_mask)); while((p = strsep(&dstring, ","))) { for (i = 0; debug_cat[i].name; i++) { if (!strcasecmp(p, debug_cat[i].name)) @@ -285,7 +302,7 @@ int parse_debug_opt(const char *optarg) free(dup); return -EINVAL; } - debug_mask |= ((uint64_t)1 << i); + debug_mask[i >> 6] |= ((uint64_t)1 << (i & 63)); } free(dup); diff --git a/src/libdebug/debug.h b/src/libdebug/debug.h index ae16857..5942651 100644 --- a/src/libdebug/debug.h +++ b/src/libdebug/debug.h @@ -19,38 +19,48 @@ #define DJOLLY 12 #define DEURO 13 #define DPOCSAG 14 -#define DFRAME 15 -#define DCALL 16 -#define DCC 17 -#define DDB 18 -#define DTRANS 19 -#define DDMS 20 -#define DSMS 21 -#define DSDR 22 -#define DUHD 23 -#define DSOAPY 24 -#define DWAVE 25 -#define DRADIO 26 -#define DAM791X 27 -#define DUART 28 -#define DDEVICE 29 -#define DDATENKLO 30 -#define DZEIT 31 -#define DSIM1 32 -#define DSIM2 33 -#define DSIMI 34 -#define DSIM7 35 -#define DMTP2 36 -#define DMTP3 37 -#define DMUP 38 -#define DROUTER 39 -#define DSTDERR 40 -#define DSS5 41 -#define DISDN 42 -#define DMISDN 43 -#define DDSS1 44 -#define DSIP 45 -#define DTEL 46 +#define DGOLAY 15 +#define DFUENF 16 +#define DFRAME 17 +#define DCALL 18 +#define DCC 19 +#define DDB 20 +#define DTRANS 21 +#define DDMS 22 +#define DSMS 23 +#define DSDR 24 +#define DUHD 25 +#define DSOAPY 26 +#define DWAVE 27 +#define DRADIO 28 +#define DAM791X 29 +#define DUART 30 +#define DDEVICE 31 +#define DDATENKLO 32 +#define DZEIT 33 +#define DSIM1 34 +#define DSIM2 35 +#define DSIMI 36 +#define DSIM7 37 +#define DMTP2 38 +#define DMTP3 39 +#define DMUP 40 +#define DROUTER 41 +#define DSTDERR 42 +#define DSS5 43 +#define DISDN 44 +#define DMISDN 45 +#define DDSS1 46 +#define DSIP 47 +#define DTEL 48 +#define DUK0 49 +#define DPH 50 +#define DDCF77 51 +#define DJITTER 52 +//NOTE: increment mask array, if 127 is exceeded + +void lock_debug(void); +void unlock_debug(void); void get_win_size(int *w, int *h); diff --git a/src/libosmocc/cause.c b/src/libosmocc/cause.c index 4a3a41e..df2b07b 100644 --- a/src/libosmocc/cause.c +++ b/src/libosmocc/cause.c @@ -22,7 +22,7 @@ #include "message.h" #include "cause.h" -/* stolen from freeswitch */ +/* stolen from freeswitch, did some corrections */ /* map sip responses to QSIG cause codes ala RFC4497 section 8.4.4 */ static uint8_t status2isdn_cause(uint16_t status) { @@ -36,10 +36,9 @@ static uint8_t status2isdn_cause(uint16_t status) case 603: return 21; //SWITCH_CAUSE_CALL_REJECTED; case 404: - return 1; //SWITCH_CAUSE_UNALLOCATED_NUMBER; case 485: case 604: - return 3; //SWITCH_CAUSE_NO_ROUTE_DESTINATION; + return 1; //SWITCH_CAUSE_UNALLOCATED_NUMBER; case 408: case 504: return 102; //SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE; @@ -55,7 +54,7 @@ static uint8_t status2isdn_cause(uint16_t status) case 513: return 127; //SWITCH_CAUSE_INTERWORKING; case 480: - return 180; //SWITCH_CAUSE_NO_USER_RESPONSE; + return 18; //SWITCH_CAUSE_NO_USER_RESPONSE; case 400: case 481: case 500: @@ -68,7 +67,7 @@ static uint8_t status2isdn_cause(uint16_t status) return 28; //SWITCH_CAUSE_INVALID_NUMBER_FORMAT; case 488: case 606: - return 88; //SWITCH_CAUSE_INCOMPATIBLE_DESTINATION; + return 65; //SWITCH_CAUSE_BERER_CAPABILITY_NOT_IMPLEMENTED; case 502: return 38; //SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; case 405: @@ -81,7 +80,7 @@ static uint8_t status2isdn_cause(uint16_t status) case 483: return 25; //SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR; case 487: - return 31; //??? SWITCH_CAUSE_ORIGINATOR_CANCEL; + return 31; //??? SWITCH_CAUSE_ORIGINATOR_CANCEL; (not specified) default: return 31; //SWITCH_CAUSE_NORMAL_UNSPECIFIED; } diff --git a/src/libosmocc/endpoint.c b/src/libosmocc/endpoint.c index 120b53c..cb591b8 100644 --- a/src/libosmocc/endpoint.c +++ b/src/libosmocc/endpoint.c @@ -568,6 +568,18 @@ static void notify_ind(osmo_cc_call_t *call, osmo_cc_msg_t *msg) forward_to_ul(call, msg); } +static void update_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg) +{ + /* to lower layer */ + forward_to_ll(call, msg); +} + +static void update_cnf(osmo_cc_call_t *call, osmo_cc_msg_t *msg) +{ + /* to upper layer */ + forward_to_ul(call, msg); +} + static void disc_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg) { /* change state */ @@ -853,6 +865,10 @@ static struct statemachine { OSMO_CC_MSG_INFO_IND, info_ind}, {SBIT(OSMO_CC_STATE_ACTIVE), OSMO_CC_MSG_INFO_REQ, info_req}, + {SBIT(OSMO_CC_STATE_ACTIVE), + OSMO_CC_MSG_UPDATE_REQ, update_req}, + {SBIT(OSMO_CC_STATE_ACTIVE), + OSMO_CC_MSG_UPDATE_CNF, update_cnf}, /* call release */ {SBIT(OSMO_CC_STATE_INIT_OUT) | SBIT(OSMO_CC_STATE_INIT_IN) | @@ -1072,6 +1088,36 @@ void osmo_cc_ul_msg(void *priv, uint32_t callref, osmo_cc_msg_t *msg) osmo_cc_msg_list_enqueue(&call->sock_queue, msg, call->callref); } +static void osmo_cc_help_name(void) +{ + printf("Name options:\n\n"); + + printf("name \n"); + + printf("Allows to override endpoint name given by application.\n"); +} + +static int osmo_cc_set_name(osmo_cc_endpoint_t *ep, const char *text) +{ + if (!strncasecmp(text, "name", 4)) { + text += 4; + /* remove spaces after keyword */ + while (*text) { + if (*text > 32) + break; + text++; + } + } else { + PDEBUG(DCC, DEBUG_ERROR, "Invalid name definition '%s'\n", text); + return -EINVAL; + } + + free((char *)ep->local_name); + ep->local_name = strdup(text); + + return 0; +} + static void osmo_cc_help_address(void) { printf("Address options:\n\n"); @@ -1080,6 +1126,8 @@ static void osmo_cc_help_address(void) printf("local []:\n"); printf("remote :\n"); printf("remote []:\n\n"); + printf("remote auto\n\n"); + printf("remote none\n\n"); printf("These options can be used to define local and remote IP and port for the socket\n"); printf("interface. Note that IPv6 addresses must be enclosed by '[' and ']'.\n\n"); @@ -1090,6 +1138,9 @@ static void osmo_cc_help_address(void) printf("If no remote address is given, the local IP is used. If the local port is %d,\n", OSMO_CC_DEFAULT_PORT); printf("the remote port will be %d. If not, the remote port will be %d. This way it is\n", OSMO_CC_DEFAULT_PORT + 1, OSMO_CC_DEFAULT_PORT); printf("possible to link two interfaces without any IP configuration required.\n\n"); + + printf("Use 'remote auto' to enable and 'remote none' to disable. This can be useful to\n"); + printf("override application default.\n\n"); } static int osmo_cc_set_address(osmo_cc_endpoint_t *ep, const char *text) @@ -1124,6 +1175,11 @@ static int osmo_cc_set_address(osmo_cc_endpoint_t *ep, const char *text) ep->remote_auto = 1; return 0; } + if (!strcasecmp(text, "none")) { + PDEBUG(DCC, DEBUG_DEBUG, "disable automatic remote peer selection\n"); + ep->remote_auto = 0; + return 0; + } ep->remote_auto = 0; address_p = &ep->remote_address; host_p = &ep->remote_host; @@ -1220,6 +1276,7 @@ static int osmo_cc_set_rtp(osmo_cc_endpoint_t *ep, const char *text) return -EINVAL; } from = from * 10 + *text - '0'; + text++; } /* remove spaces after keyword */ @@ -1235,7 +1292,8 @@ static int osmo_cc_set_rtp(osmo_cc_endpoint_t *ep, const char *text) PDEBUG(DCC, DEBUG_ERROR, "Given 'to' port in '%s' is invalid.\n", text); return -EINVAL; } - from = from * 10 + *text - '0'; + to = to * 10 + *text - '0'; + text++; } osmo_cc_set_rtp_ports(&ep->session_config, from, to); @@ -1247,9 +1305,10 @@ static int osmo_cc_set_rtp(osmo_cc_endpoint_t *ep, const char *text) void osmo_cc_help(void) { - osmo_cc_help_screen(); + osmo_cc_help_name(); osmo_cc_help_address(); osmo_cc_help_rtp(); + osmo_cc_help_screen(); } /* create a new endpoint instance */ @@ -1286,6 +1345,12 @@ int osmo_cc_new(osmo_cc_endpoint_t *ep, const char *version, const char *name, u /* apply args */ for (i = 0; i < argc; i++) { + if (!strncasecmp(argv[i], "name", 4)) { + rc = osmo_cc_set_name(ep, argv[i]); + if (rc < 0) { + return rc; + } + } else if (!strncasecmp(argv[i], "local", 5)) { rc = osmo_cc_set_address(ep, argv[i]); if (rc < 0) { diff --git a/src/libosmocc/helper.c b/src/libosmocc/helper.c index 807542e..4eeee92 100644 --- a/src/libosmocc/helper.c +++ b/src/libosmocc/helper.c @@ -29,7 +29,7 @@ #include "endpoint.h" #include "helper.h" -osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug) +osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug) { osmo_cc_session_t *session; osmo_cc_session_media_t *media; @@ -52,7 +52,7 @@ osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, vo return session; } -const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec) +const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec) { char offer_sdp[65536]; const char *accept_sdp; diff --git a/src/libosmocc/helper.h b/src/libosmocc/helper.h index c12a50a..0d3585e 100644 --- a/src/libosmocc/helper.h +++ b/src/libosmocc/helper.h @@ -7,7 +7,7 @@ struct osmo_cc_helper_audio_codecs { void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len); }; -osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug); -const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec); +osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug); +const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec); int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p); diff --git a/src/libosmocc/message.c b/src/libosmocc/message.c index 5b069dd..ab66a9f 100644 --- a/src/libosmocc/message.c +++ b/src/libosmocc/message.c @@ -33,7 +33,8 @@ } #define _OSMO_CC_NAME2VALUE(array) { \ - for (int value = 0; (size_t)value < (sizeof(array) / sizeof(array[0])); value++) { \ + int value; \ + for (value = 0; (size_t)value < (sizeof(array) / sizeof(array[0])); value++) { \ if (!strcasecmp(array[value], name)) \ return value; \ } \ diff --git a/src/libosmocc/message.h b/src/libosmocc/message.h index 2bb299a..8f4d487 100644 --- a/src/libosmocc/message.h +++ b/src/libosmocc/message.h @@ -30,6 +30,8 @@ enum osmo_cc_msg_type { OSMO_CC_MSG_NOTIFY_IND = 0x85, OSMO_CC_MSG_INFO_REQ = 0x88, OSMO_CC_MSG_INFO_IND = 0x89, + OSMO_CC_MSG_UPDATE_REQ = 0x91, + OSMO_CC_MSG_UPDATE_CNF = 0x93, OSMO_CC_MSG_ATTACH_REQ = 0xf8, OSMO_CC_MSG_ATTACH_IND = 0xf9, OSMO_CC_MSG_ATTACH_RSP = 0xfa, diff --git a/src/libosmocc/rtp.c b/src/libosmocc/rtp.c index afaf22d..b118833 100644 --- a/src/libosmocc/rtp.c +++ b/src/libosmocc/rtp.c @@ -52,7 +52,7 @@ struct rtp_x_hdr { uint16_t length; } __attribute__((packed)); -static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_t *marker_p, uint8_t *pt_p, uint16_t *sequence_p, uint32_t *timestamp_p) +static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_t *marker_p, uint8_t *pt_p, uint16_t *sequence_p, uint32_t *timestamp_p, uint32_t *ssrc_p) { static uint8_t data[2048]; int len; @@ -83,6 +83,7 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_ payload_type = rtph->byte1 & 0x7f; *sequence_p = ntohs(rtph->sequence); *timestamp_p = ntohl(rtph->timestamp); + *ssrc_p = ntohl(rtph->ssrc); if (version != RTP_VERSION) { PDEBUG(DCC, DEBUG_NOTICE, "Received RTP version %d not supported.\n", version); @@ -131,7 +132,7 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_ return 0; } -static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc) +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; char data[sizeof(*rtph) + payload_len]; @@ -140,7 +141,7 @@ static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t pt, ui rtph = (struct rtp_hdr *)data; len = sizeof(*rtph); rtph->byte0 = RTP_VERSION << 6; - rtph->byte1 = pt; + rtph->byte1 = pt | (marker << 7); rtph->sequence = htons(sequence); rtph->timestamp = htonl(timestamp); rtph->ssrc = htonl(ssrc); @@ -172,7 +173,7 @@ int osmo_cc_rtp_open(osmo_cc_session_media_t *media) int flags; int rc; - media->rtp_ssrc = rand(); + media->tx_ssrc = rand(); osmo_cc_rtp_close(media); @@ -182,7 +183,12 @@ int osmo_cc_rtp_open(osmo_cc_session_media_t *media) memset(&sa, 0, sizeof(sa)); sa4 = (struct sockaddr_in *)&sa; sa4->sin_family = domain; - sa4->sin_addr.s_addr = INADDR_ANY; + 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); + return -EINVAL; + } sport = &sa4->sin_port; slen = sizeof(*sa4); break; @@ -191,7 +197,9 @@ int osmo_cc_rtp_open(osmo_cc_session_media_t *media) memset(&sa, 0, sizeof(sa)); sa6 = (struct sockaddr_in6 *)&sa; sa6->sin6_family = domain; - sa6->sin6_addr = in6addr_any; + rc = inet_pton(AF_INET6, media->connection_data_local.address, &sa6->sin6_addr); + if (rc < 1) + goto pton_error; sport = &sa6->sin6_port; slen = sizeof(*sa6); break; @@ -313,7 +321,7 @@ connect_error: } /* send rtp data with given codec */ -void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, int inc_sequence, int inc_timestamp) +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) { uint8_t *payload = NULL; int payload_len = 0; @@ -328,7 +336,7 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, in payload_len = len; } - rtp_send(codec->media->rtp_socket, payload, payload_len, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->rtp_ssrc); + 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); codec->media->tx_sequence += inc_sequence; codec->media->tx_timestamp += inc_timestamp; @@ -351,7 +359,7 @@ int osmo_cc_rtp_receive(osmo_cc_session_media_t *media) if (!media || media->rtp_socket <= 0) return -EIO; - rc = rtp_receive(media->rtp_socket, &payload, &payload_len, &marker, &payload_type, &media->rx_sequence, &media->rx_timestamp); + 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; @@ -374,7 +382,7 @@ int osmo_cc_rtp_receive(osmo_cc_session_media_t *media) } if (codec->media->receive) - codec->media->receiver(codec, media->rx_sequence, media->rx_timestamp, data, len); + codec->media->receiver(codec, marker, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len); if (codec->decoder) free(data); diff --git a/src/libosmocc/rtp.h b/src/libosmocc/rtp.h index e309f56..eb74f73 100644 --- a/src/libosmocc/rtp.h +++ b/src/libosmocc/rtp.h @@ -2,7 +2,7 @@ void osmo_cc_set_rtp_ports(osmo_cc_session_config_t *conf, uint16_t from, uint16_t to); 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, int inc_sequence, int inc_timestamp); +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); int osmo_cc_rtp_receive(osmo_cc_session_media_t *media); void osmo_cc_rtp_close(osmo_cc_session_media_t *media); diff --git a/src/libosmocc/screen.c b/src/libosmocc/screen.c index 5040ce6..5558f42 100644 --- a/src/libosmocc/screen.c +++ b/src/libosmocc/screen.c @@ -58,6 +58,10 @@ void osmo_cc_help_screen(void) printf("to allow any suffix to match from now on. The new caller ID or dialed number\n"); printf("may contain a '*', to append the suffix from the current caller ID or dialed\n"); printf("number.\n\n"); + + printf("When screening an incoming caller ID or dialed number, the '@' can be appended\n"); + printf("to the 'new caller ID', followed by a 'host:port', to route call to a special\n"); + printf("Osmo-CC endpoint. This way it is possible to do simple routing.\n\n"); } char *osmo_cc_strtok_quotes(const char **text_p) @@ -139,6 +143,7 @@ int osmo_cc_add_screen(osmo_cc_endpoint_t *ep, const char *text) } else if (!strncasecmp(text, "screen-called-in", 16)) { text += 16; list_p = &ep->screen_called_in; + calling_in = 1; } else if (!strncasecmp(text, "screen-calling-out", 18)) { text += 18; list_p = &ep->screen_calling_out; @@ -218,6 +223,7 @@ no_present_error: list->from_present = OSMO_CC_PRESENT_RESTRICTED; goto next_from; } else { + star_used = 0; for (i = j = 0; token[i] && j < (int)sizeof(list->from) - 1; i++, j++) { if (token[i] == '?') list->from[j] = SCREEN_QUESTIONMARK; @@ -240,7 +246,6 @@ no_present_error: list->from[j] = '\0'; } - star_used = 0; next_to: token = osmo_cc_strtok_quotes(&text); if (!token) { @@ -293,6 +298,7 @@ next_to: list->to_present = OSMO_CC_PRESENT_RESTRICTED; goto next_to; } else { + at_used = star_used = 0; for (i = j = 0; token[i] && j < (int)sizeof(list->to) - 1; i++, j++) { if (token[i] == '*') { if (star_used) { @@ -506,7 +512,8 @@ static int osmo_cc_screen(const char *what, osmo_cc_screen_list_t *list, uint8_t continue; /* '@' means to stop and return routing also */ } else if (list->to[i] == SCREEN_AT) { - *routing_p = &list->to[i]; + if (routing_p) + *routing_p = &list->to[i + 1]; break; } /* copy output digit */ @@ -543,6 +550,8 @@ static int osmo_cc_screen(const char *what, osmo_cc_screen_list_t *list, uint8_t PDEBUG(DCC, DEBUG_INFO, " -> present = restricted\n"); break; } + if (routing_p && *routing_p) + PDEBUG(DCC, DEBUG_INFO, " -> remote = %s\n", *routing_p); return 0; } @@ -586,13 +595,13 @@ osmo_cc_msg_t *osmo_cc_screen_msg(osmo_cc_endpoint_t *ep, osmo_cc_msg_t *old_msg if (in && ep->screen_called_in) { rc = osmo_cc_get_ie_called(old_msg, 0, &called_type, &called_plan, id, sizeof(id)); if (rc >= 0) { - rc = osmo_cc_screen("incoming dialed number", ep->screen_called_in, &called_type, NULL, called, sizeof(called), id, NULL); + rc = osmo_cc_screen("incoming dialed number", ep->screen_called_in, &called_type, NULL, called, sizeof(called), id, routing_p); if (rc >= 0) called_status = 1; } else { called_type = OSMO_CC_TYPE_UNKNOWN; called_plan = OSMO_CC_PLAN_TELEPHONY; - rc = osmo_cc_screen("incoming dialed number", ep->screen_called_in, &called_type, NULL, called, sizeof(called), "", NULL); + rc = osmo_cc_screen("incoming dialed number", ep->screen_called_in, &called_type, NULL, called, sizeof(called), "", routing_p); if (rc >= 0) called_status = 1; } diff --git a/src/libosmocc/sdp.c b/src/libosmocc/sdp.c index 8e44117..849bfb9 100644 --- a/src/libosmocc/sdp.c +++ b/src/libosmocc/sdp.c @@ -260,7 +260,7 @@ struct osmo_cc_session *osmo_cc_session_parsesdp(osmo_cc_session_config_t *conf, memset(&ccd, 0, sizeof(ccd)); /* create SDP session description */ - session = osmo_cc_new_session(conf, priv, NULL, NULL, NULL, osmo_cc_session_nettype_inet, osmo_cc_session_addrtype_ipv4, "127.0.0.1", NULL, 0); // values will be replaced by local definitions during negotiation + session = osmo_cc_new_session(conf, priv, NULL, NULL, NULL, 0, 0, NULL, NULL, 0); /* check every line of SDP and parse its data */ while(*sdp) { diff --git a/src/libosmocc/session.c b/src/libosmocc/session.c index 50a4a92..8216c05 100644 --- a/src/libosmocc/session.c +++ b/src/libosmocc/session.c @@ -29,7 +29,7 @@ #include "../liboptions/options.h" #include "endpoint.h" -#define NTP_OFFSET 2208988800 +#define NTP_OFFSET 2208988800U void osmo_cc_set_local_peer(osmo_cc_session_config_t *conf, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address) { @@ -127,7 +127,7 @@ void osmo_cc_free_session(osmo_cc_session_t *session) free(session); } -osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len), int debug) +osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug) { osmo_cc_session_config_t *conf = session->config; osmo_cc_session_media_t *media, **mediap; @@ -374,7 +374,7 @@ osmo_cc_session_t *osmo_cc_session_receive_offer(osmo_cc_session_config_t *conf, return session; } -void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len)) +void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len)) { osmo_cc_session_config_t *conf = media->session->config; diff --git a/src/libosmocc/session.h b/src/libosmocc/session.h index c0717c0..791bcb4 100644 --- a/src/libosmocc/session.h +++ b/src/libosmocc/session.h @@ -79,10 +79,10 @@ typedef struct osmo_cc_session_media { osmo_cc_session_connection_data_t connection_data_local, connection_data_remote; struct osmo_cc_session_codec *codec_list; int send, receive; - void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len); + void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len); int rtp_socket; int rtcp_socket; - uint32_t rtp_ssrc; + uint32_t tx_ssrc, rx_ssrc; uint16_t tx_sequence, rx_sequence; uint32_t tx_timestamp, rx_timestamp; int accepted; @@ -110,14 +110,14 @@ typedef struct osmo_cc_session_codec { void osmo_cc_set_local_peer(osmo_cc_session_config_t *conf, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address); osmo_cc_session_t *osmo_cc_new_session(osmo_cc_session_config_t *conf, void *priv, const char *username, const char *sess_id, const char *sess_version, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *unicast_address, const char *session_name, int debug); void osmo_cc_free_session(osmo_cc_session_t *session); -osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len), int debug); +osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug); void osmo_cc_free_media(osmo_cc_session_media_t *media); osmo_cc_session_codec_t *osmo_cc_add_codec(osmo_cc_session_media_t *media, const char *playload_name, uint32_t playload_rate, int playload_channels, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), int debug); void osmo_cc_free_codec(osmo_cc_session_codec_t *codec); int osmo_cc_session_check(struct osmo_cc_session *session, int remote); const char *osmo_cc_session_send_offer(osmo_cc_session_t *session); osmo_cc_session_t *osmo_cc_session_receive_offer(osmo_cc_session_config_t *conf, void *priv, const char *sdp); -void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len)); +void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len)); void osmo_cc_session_accept_codec(osmo_cc_session_codec_t *codec, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len)); const char *osmo_cc_session_send_answer(osmo_cc_session_t *session); int osmo_cc_session_receive_answer(osmo_cc_session_t *session, const char *sdp);