From e8a91e12f9338fdb0f41ed33f1e8f5217df1c4d8 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Wed, 5 Oct 2022 20:12:23 +0200 Subject: [PATCH] Updated libs --- src/isdn/isdn.c | 6 +- src/isdn/ph_driver.c | 4 +- src/libdebug/debug.c | 1 + src/libdebug/debug.h | 75 +++++++++--------- src/libjitter/jitter.c | 145 +++++++++++++++++++++-------------- src/libjitter/jitter.h | 4 +- src/libosmocc/endpoint.c | 16 ++++ src/libosmocc/helper.c | 4 +- src/libosmocc/helper.h | 4 +- src/libosmocc/message.h | 2 + src/libosmocc/rtp.c | 10 +-- src/libosmocc/rtp.h | 2 +- src/libosmocc/session.c | 4 +- src/libosmocc/session.h | 6 +- src/libph_socket/ph_socket.c | 4 +- src/libph_socket/ph_socket.h | 4 +- src/libsample/sample.c | 29 ++++++- src/libsample/sample.h | 6 +- 18 files changed, 202 insertions(+), 124 deletions(-) diff --git a/src/isdn/isdn.c b/src/isdn/isdn.c index 717fa52..22e4758 100644 --- a/src/isdn/isdn.c +++ b/src/isdn/isdn.c @@ -1508,7 +1508,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len) g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); else g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); - osmo_cc_rtp_send(call->codec, data, len, 1, len); + osmo_cc_rtp_send(call->codec, data, len, 0, 1, len); free(data); /* mix audio for (hold) remote interface and forward */ @@ -1525,7 +1525,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len) g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); else g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); - osmo_cc_rtp_send(other->codec, data, len, 1, len); + osmo_cc_rtp_send(other->codec, data, len, 0, 1, len); free(data); } @@ -1537,7 +1537,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len) if (call->bridge_enabled) return; - osmo_cc_rtp_send(call->codec, data, len, 1, len); + osmo_cc_rtp_send(call->codec, data, len, 0, 1, len); } /* receive audio and control from B-channel, transmit data from jitter buffer accoring to received length */ diff --git a/src/isdn/ph_driver.c b/src/isdn/ph_driver.c index cb4c2fd..53aaafe 100644 --- a/src/isdn/ph_driver.c +++ b/src/isdn/ph_driver.c @@ -292,11 +292,11 @@ static void ph_socket_rx_msg(ph_socket_t *s, int channel, uint8_t prim, uint8_t case PH_PRIM_CTRL_IND: if (length >= 1) { switch (data[0]) { - case PH_CTRL_ENABLE: + case PH_CTRL_UNBLOCK: printk(KERN_DEBUG "PH-SOCKET Interface available\n"); drv->enabled = 1; break; - case PH_CTRL_DISABLE: + case PH_CTRL_BLOCK: printk(KERN_DEBUG "PH-SOCKET Interface unavailable\n"); drv->enabled = 0; if (drv->activated) { diff --git a/src/libdebug/debug.c b/src/libdebug/debug.c index bf23035..f7b91e0 100644 --- a/src/libdebug/debug.c +++ b/src/libdebug/debug.c @@ -57,6 +57,7 @@ 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" }, diff --git a/src/libdebug/debug.h b/src/libdebug/debug.h index ba55fdb..5942651 100644 --- a/src/libdebug/debug.h +++ b/src/libdebug/debug.h @@ -19,43 +19,44 @@ #define DJOLLY 12 #define DEURO 13 #define DPOCSAG 14 -#define DFUENF 15 -#define DFRAME 16 -#define DCALL 17 -#define DCC 18 -#define DDB 19 -#define DTRANS 20 -#define DDMS 21 -#define DSMS 22 -#define DSDR 23 -#define DUHD 24 -#define DSOAPY 25 -#define DWAVE 26 -#define DRADIO 27 -#define DAM791X 28 -#define DUART 29 -#define DDEVICE 30 -#define DDATENKLO 31 -#define DZEIT 32 -#define DSIM1 33 -#define DSIM2 34 -#define DSIMI 35 -#define DSIM7 36 -#define DMTP2 37 -#define DMTP3 38 -#define DMUP 39 -#define DROUTER 40 -#define DSTDERR 41 -#define DSS5 42 -#define DISDN 43 -#define DMISDN 44 -#define DDSS1 45 -#define DSIP 46 -#define DTEL 47 -#define DUK0 48 -#define DPH 49 -#define DDCF77 50 -#define DJITTER 51 +#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); diff --git a/src/libjitter/jitter.c b/src/libjitter/jitter.c index 87fc754..1de03c2 100644 --- a/src/libjitter/jitter.c +++ b/src/libjitter/jitter.c @@ -28,13 +28,13 @@ * * Packets with the same sequence are dropped. * + * Early packts that exceed maximum jitter window size cause jitter + * window to shift into the future. + * * Late packets cause jitter window to shift into the past (allowing more * delay). Minimum jitter window size is added also, to prevent subsequent * packets from beeing late too. * - * Early packts that exceed maximum jitter window size cause jitter - * window to shift into the future. - * * If no sequence is provided (autosequence), the sequence number is generated * by a counter. Also the timestamp is generated by counting the length of each * frame. @@ -51,16 +51,17 @@ * * Missing packets are interpolated by repeating last 20ms of audio (optional) * or by inserting zeroes (sample size > 1 byte) or by inserting 0xff (sample - * size = 1). + * size = 1). In case of repeating audio, the number of turns are limited until + * buffer is reset to silence, if no frames are received for a certain time. * - * Optionally the constant delay will be measured continuously and lowered to - * minimum window size. (adaptive jitter buffer window) + * Optionally the constant delay will be measured continuously and lowered if + * greater than minimum window size. (adaptive jitter buffer size) * * Note that the delay is measured with time stamp of frame, no matter what * the length is. Length is an extra delay, but not considered here. * * - * Unocking: + * Unlocking: * * If the buffer is created or reset, the buffer is locked, so no packets are * stored. When the playout routine is called, the buffer is unlocked. This @@ -80,8 +81,9 @@ #include "jitter.h" #define INITIAL_DELAY_INTERVAL 0.5 -#define REPEAT_DELAY_INTERVAL 2.0 +#define REPEAT_DELAY_INTERVAL 3.0 #define EXTRA_BUFFER 0.020 // 20 ms +#define EXTRA_TIMEOUT 0.500 // maximum time to repeat extrapolation buffer /* uncomment to enable heavy debugging */ //#define HEAVY_DEBUG @@ -98,7 +100,6 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_ jb->target_window_size = (int)(samplerate * target_window_duration); jb->max_window_size = (int)(samplerate * max_window_duration); jb->window_flags = window_flags; - jb->delay_value = -1; jb->extra_size = (int)(EXTRA_BUFFER * samplerate); jb->extra_samples = calloc(sample_size, jb->extra_size); @@ -107,7 +108,7 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_ rc = -ENOMEM; goto error; } - + jb->extra_timeout_max = (int)ceil(EXTRA_TIMEOUT / EXTRA_BUFFER); /* optionally give a string to be show with the debug */ if (name && *name) @@ -117,7 +118,7 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_ jitter_reset(jb); - PDEBUG(DJITTER, DEBUG_DEBUG, "%sCreated jitter buffer.\n", jb->name); + PDEBUG(DJITTER, DEBUG_INFO, "%sCreated jitter buffer. (samplerate=%.0f, target_window=%.0fms, max_window=%.0fms, flag:latency=%s flag:repeat=%s)\n", jb->name, samplerate, target_window_duration * 1000.0, max_window_duration * 1000.0, (window_flags & JITTER_FLAG_LATENCY) ? "true" : "false", (window_flags & JITTER_FLAG_REPEAT) ? "true" : "false"); error: if (rc) @@ -125,15 +126,20 @@ error: return rc; } +static void clear_extra_buffer(jitter_t *jb) +{ + if (jb->sample_size == 1) + memset(jb->extra_samples, 0xff, jb->sample_size * jb->extra_size); + else + memset(jb->extra_samples, 0, jb->sample_size * jb->extra_size); +} + /* reset jitter buffer */ void jitter_reset(jitter_t *jb) { jitter_frame_t *jf, *temp; - if (!jb->window_valid) - return; - - PDEBUG(DJITTER, DEBUG_DEBUG, "%sReset jitter buffer.\n", jb->name); + PDEBUG(DJITTER, DEBUG_INFO, "%sReset jitter buffer.\n", jb->name); /* jitter buffer locked */ jb->unlocked = 0; @@ -151,20 +157,22 @@ void jitter_reset(jitter_t *jb) jb->frame_list = NULL; /* clear extrapolation buffer */ - if (jb->extra_samples) { - if (jb->sample_size == 1) - memset(jb->extra_samples, 0xff, jb->sample_size * jb->extra_size); - else - memset(jb->extra_samples, 0, jb->sample_size * jb->extra_size); - } + if (jb->extra_samples) + clear_extra_buffer(jb); jb->extra_index = 0; + jb->extra_timeout_count = jb->extra_timeout_max; /* no data in buffer yet, so we set timeout condition */ + + /* delay measurement and reduction */ + jb->delay_counter = 0.0; + jb->delay_interval = INITIAL_DELAY_INTERVAL; + jb->min_delay_value = -1; } void jitter_destroy(jitter_t *jb) { jitter_reset(jb); - PDEBUG(DJITTER, DEBUG_DEBUG, "%sDestroying jitter buffer.\n", jb->name); + PDEBUG(DJITTER, DEBUG_INFO, "%sDestroying jitter buffer.\n", jb->name); if (jb->extra_samples) { free(jb->extra_samples); @@ -208,6 +216,25 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint jb->next_timestamp = timestamp + length; } + /* first packet (with this ssrc) sets window size to target_window_size */ + if (!jb->window_valid || jb->window_ssrc != ssrc) { + if (!jb->window_valid) + PDEBUG(DJITTER, DEBUG_DEBUG, "%s Initial frame after init or reset.\n", jb->name); + else + PDEBUG(DJITTER, DEBUG_DEBUG, "%s SSRC changed.\n", jb->name); + // NOTE: Reset must be called before finding the frame location below, because there will be no frame in list anymore! + jitter_reset(jb); + jb->unlocked = 1; + /* when using dynamic jitter buffer, we use half of the target delay */ + if ((jb->window_flags & JITTER_FLAG_LATENCY)) { + jb->window_timestamp = timestamp - (uint32_t)jb->target_window_size / 2; + } else { + jb->window_timestamp = timestamp - (uint32_t)jb->target_window_size; + } + jb->window_valid = 1; + jb->window_ssrc = ssrc; + } + /* find location where to put frame into the list, depending on sequence number */ jfp = &jb->frame_list; while(*jfp) { @@ -223,37 +250,25 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint jfp = &((*jfp)->next); } - /* first packet (with this ssrc) sets window size to target_window_size */ - if (!jb->window_valid || jb->window_ssrc != ssrc) { - if (!jb->window_valid) - PDEBUG(DJITTER, DEBUG_DEBUG, "%s Initial frame after init or reset.\n", jb->name); - else - PDEBUG(DJITTER, DEBUG_DEBUG, "%s SSRC changed.\n", jb->name); - jitter_reset(jb); - jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size); - jb->window_valid = 1; - jb->window_ssrc = ssrc; - jb->delay_counter = 0.0; - jb->delay_interval = INITIAL_DELAY_INTERVAL; - jb->delay_value = -1; - } - offset_timestamp = timestamp - jb->window_timestamp; +#ifdef HEAVY_DEBUG + PDEBUG(DJITTER, DEBUG_DEBUG, "%sFrame has offset of %.0fms in jitter buffer.\n", jb->name, (double)offset_timestamp * jb->sample_duration * 1000.0); +#endif /* measure delay */ - if (offset_timestamp > jb->delay_value) - jb->delay_value = offset_timestamp; + if (jb->min_delay_value < 0 || offset_timestamp < jb->min_delay_value) + jb->min_delay_value = offset_timestamp; /* if frame is too early (delay ceases), shift window to the future */ if (offset_timestamp > jb->max_window_size) { if ((jb->window_flags & JITTER_FLAG_LATENCY)) { - PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, and add target window size. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size); - /* shift window so frame fits to the start of window + target delay */ - jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size); - } else { - PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size); + PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, to make the frame fit to the end. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size); /* shift window so it fits to the end of window */ jb->window_timestamp = timestamp - jb->max_window_size; + } else { + PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, to make the frame fit to the target delay. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size); + /* shift window so frame fits to the start of window + target delay */ + jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size); } } @@ -261,12 +276,12 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint if (offset_timestamp < 0) { if ((jb->window_flags & JITTER_FLAG_LATENCY)) { PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past, and add target window size. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp); + /* shift window so frame fits to the start of window + half of target delay */ + jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size) / 2; + } else { + PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past, and add half target window size. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp); /* shift window so frame fits to the start of window + target delay */ jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size); - } else { - PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp); - /* shift window so frame fits to the start of window */ - jb->window_timestamp = timestamp; } } @@ -302,18 +317,21 @@ void jitter_load(jitter_t *jb, void *samples, int length) /* now unlock jitter buffer */ jb->unlocked = 1; + /* reduce delay */ jb->delay_counter += jb->sample_duration * (double)length; if (jb->delay_counter >= jb->delay_interval) { - if (jb->delay_value >= 0) - PDEBUG(DJITTER, DEBUG_DEBUG, "%s Statistics: target_delay=%.0fms max_delay=%.0fms current_delay=%.0fms\n", jb->name, (double)jb->target_window_size * jb->sample_duration * 1000.0, (double)jb->max_window_size * jb->sample_duration * 1000.0, (double)jb->delay_value * jb->sample_duration * 1000.0); - /* delay reduction, if greater than target jitter window size */ - if ((jb->window_flags & JITTER_FLAG_LATENCY) && jb->delay_value > jb->target_window_size) { - PDEBUG(DJITTER, DEBUG_DEBUG, "%s Reducing current delay of %.0fms that is greater than target jitter window size of %.0fms.\n", jb->name, (double)jb->delay_value * jb->sample_duration * 1000.0, (double)jb->target_window_size * jb->sample_duration * 1000.0); - jb->window_timestamp += (uint32_t)(jb->delay_value - jb->target_window_size); + if (jb->min_delay_value >= 0) + PDEBUG(DJITTER, DEBUG_DEBUG, "%s Statistics: target_window_delay=%.0fms max_window_delay=%.0fms current min_delay=%.0fms\n", jb->name, (double)jb->target_window_size * jb->sample_duration * 1000.0, (double)jb->max_window_size * jb->sample_duration * 1000.0, (double)jb->min_delay_value * jb->sample_duration * 1000.0); + /* delay reduction, if maximum delay is greater than target jitter window size */ + if ((jb->window_flags & JITTER_FLAG_LATENCY) && jb->min_delay_value > jb->target_window_size) { + PDEBUG(DJITTER, DEBUG_DEBUG, "%s Reducing current minimum delay of %.0fms, because maximum delay is greater than target window size of %.0fms.\n", jb->name, (double)jb->min_delay_value * jb->sample_duration * 1000.0, (double)jb->target_window_size * jb->sample_duration * 1000.0); + /* only reduce delay to half of the target window size */ + jb->window_timestamp += jb->min_delay_value - jb->target_window_size / 2; + } jb->delay_counter -= jb->delay_interval; jb->delay_interval = REPEAT_DELAY_INTERVAL; - jb->delay_value = -1; + jb->min_delay_value = -1; } /* process all frames until output buffer is loaded */ @@ -342,8 +360,18 @@ void jitter_load(jitter_t *jb, void *samples, int length) count2 = jb->extra_size - jb->extra_index; memcpy(samples, (uint8_t *)jb->extra_samples + jb->extra_index * jb->sample_size, count2 * jb->sample_size); jb->extra_index += count2; - if (jb->extra_index == jb->extra_size) + if (jb->extra_index == jb->extra_size) { jb->extra_index = 0; + if ((jb->window_flags & JITTER_FLAG_REPEAT) && jb->extra_timeout_count < jb->extra_timeout_max) { + jb->extra_timeout_count++; + if (jb->extra_timeout_count == jb->extra_timeout_max) { +#ifdef HEAVY_DEBUG + PDEBUG(DJITTER, DEBUG_DEBUG, "%s Repeated jitter buffer enough, clearing to silence.\n", jb->name); +#endif + clear_extra_buffer(jb); + } + } + } samples = (uint8_t *)samples + count2 * jb->sample_size; length -= count2; jb->window_timestamp += count2; @@ -360,8 +388,8 @@ void jitter_load(jitter_t *jb, void *samples, int length) count = length; if (jf->length - index < count) count = jf->length - index; - /* if extrapolation is used, limit count to what we can store into buffer */ - if (jb->extra_samples && jb->extra_size - jb->extra_index < count) + /* if extrapolation is to be written, limit count to what we can store into buffer */ + if ((jb->window_flags & JITTER_FLAG_REPEAT) && jb->extra_size - jb->extra_index < count) count = jb->extra_size - jb->extra_index; /* copy samples from packet to play out, increment sample pointer and decrement length */ #ifdef HEAVY_DEBUG @@ -376,6 +404,7 @@ void jitter_load(jitter_t *jb, void *samples, int length) jb->extra_index += count; if (jb->extra_index == jb->extra_size) jb->extra_index = 0; + jb->extra_timeout_count = 0; /* now we have new data, we reset timeout condition */ } /* increment time stamp */ jb->window_timestamp += count; diff --git a/src/libjitter/jitter.h b/src/libjitter/jitter.h index 758511b..dc618cb 100644 --- a/src/libjitter/jitter.h +++ b/src/libjitter/jitter.h @@ -39,12 +39,14 @@ typedef struct jitter { /* reduction of delay */ double delay_interval; double delay_counter; - int32_t delay_value; + int32_t min_delay_value; /* extrapolation */ int extra_size; int extra_index; void *extra_samples; + int extra_timeout_max; + int extra_timeout_count; /* list of frames */ jitter_frame_t *frame_list; diff --git a/src/libosmocc/endpoint.c b/src/libosmocc/endpoint.c index 29a3003..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) | diff --git a/src/libosmocc/helper.c b/src/libosmocc/helper.c index 8917917..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, uint32_t ssrc, 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, 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) +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 97a284f..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, 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, 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); +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.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 f6572ca..b118833 100644 --- a/src/libosmocc/rtp.c +++ b/src/libosmocc/rtp.c @@ -132,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]; @@ -141,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); @@ -321,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; @@ -336,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->tx_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; @@ -382,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, media->rx_ssrc, 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/session.c b/src/libosmocc/session.c index 3546900..8216c05 100644 --- a/src/libosmocc/session.c +++ b/src/libosmocc/session.c @@ -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, uint32_t ssrc, 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, uint32_t ssrc, 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 0464cc9..791bcb4 100644 --- a/src/libosmocc/session.h +++ b/src/libosmocc/session.h @@ -79,7 +79,7 @@ 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, uint32_t ssrc, 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 tx_ssrc, rx_ssrc; @@ -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, uint32_t ssrc, 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, uint32_t ssrc, 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); diff --git a/src/libph_socket/ph_socket.c b/src/libph_socket/ph_socket.c index 1457cec..52c76cc 100644 --- a/src/libph_socket/ph_socket.c +++ b/src/libph_socket/ph_socket.c @@ -80,7 +80,7 @@ int ph_socket_init(ph_socket_t *s, void (*ph_socket_rx_msg)(ph_socket_t *s, int static void close_connection(ph_socket_t *s) { struct socket_msg_list *ml; - uint8_t disable = PH_CTRL_DISABLE; + uint8_t disable = PH_CTRL_BLOCK; if (s->connect <= 0) return; @@ -123,7 +123,7 @@ void ph_socket_exit(ph_socket_t *s) int ph_socket_work(ph_socket_t *s) { - uint8_t enable = PH_CTRL_ENABLE; + uint8_t enable = PH_CTRL_UNBLOCK; int rc, flags; int work = 0; diff --git a/src/libph_socket/ph_socket.h b/src/libph_socket/ph_socket.h index cf2f319..4bcfeee 100644 --- a/src/libph_socket/ph_socket.h +++ b/src/libph_socket/ph_socket.h @@ -62,8 +62,8 @@ #define PH_MODE_HDLC 0x01 /* HDLC transcoding is performed via B-channel */ /* one byte sent with control messages */ -#define PH_CTRL_DISABLE 0x00 /* disable (block) interface, when socket is disconnected */ -#define PH_CTRL_ENABLE 0x01 /* enable (unblock) interface, when socket is connected */ +#define PH_CTRL_BLOCK 0x00 /* disable (block) interface, when socket is disconnected */ +#define PH_CTRL_UNBLOCK 0x01 /* enable (unblock) interface, when socket is connected */ #define PH_CTRL_LOOP_DISABLE 0x04 /* disable loopback */ #define PH_CTRL_LOOP1_ENABLE 0x05 /* enable LT transceier loopback */ #define PH_CTRL_LOOP2_ENABLE 0x06 /* enable NT transceier loopback */ diff --git a/src/libsample/sample.c b/src/libsample/sample.c index a084b66..607adc5 100644 --- a/src/libsample/sample.c +++ b/src/libsample/sample.c @@ -25,6 +25,7 @@ * of 16 bits signed value: */ static double int_16_speech_level = SPEECH_LEVEL * 0.7079; /* 16 dBm below dBm0, which is about 3dBm below full 16 bit range */ +static double int_16_1mw_level = 0.7079; /* dBm0, 3dBm below full 16 bit range */ /* A sample_t is a value that has virtually infinite precision but will also * support high numbers. 'double' or 'float' types are sufficient. @@ -40,7 +41,8 @@ static double int_16_speech_level = SPEECH_LEVEL * 0.7079; /* 16 dBm below dBm0, * envelope is network dependent. */ -void samples_to_int16(int16_t *spl, sample_t *samples, int length) +/* sample conversion relative to SPEECH level */ +void samples_to_int16_speech(int16_t *spl, sample_t *samples, int length) { int32_t value; @@ -55,10 +57,33 @@ void samples_to_int16(int16_t *spl, sample_t *samples, int length) } } -void int16_to_samples(sample_t *samples, int16_t *spl, int length) +void int16_to_samples_speech(sample_t *samples, int16_t *spl, int length) { while (length--) { *samples++ = (double)(*spl++) / 32767.0 / int_16_speech_level; } } +/* sample conversion relative to 1mW level */ +void samples_to_int16_1mw(int16_t *spl, sample_t *samples, int length) +{ + int32_t value; + + while (length--) { + value = *samples++ * int_16_1mw_level * 32768.0; + if (value > 32767.0) + *spl++ = 32767; + else if (value < -32767.0) + *spl++ = -32767; + else + *spl++ = (uint16_t)value; + } +} + +void int16_to_samples_1mw(sample_t *samples, int16_t *spl, int length) +{ + while (length--) { + *samples++ = (double)(*spl++) / 32767.0 / int_16_1mw_level; + } +} + diff --git a/src/libsample/sample.h b/src/libsample/sample.h index 01a17df..333ff7e 100644 --- a/src/libsample/sample.h +++ b/src/libsample/sample.h @@ -3,6 +3,8 @@ typedef double sample_t; #define SPEECH_LEVEL 0.1585 -void samples_to_int16(int16_t *spl, sample_t *samples, int length); -void int16_to_samples(sample_t *samples, int16_t *spl, int length); +void samples_to_int16_speech(int16_t *spl, sample_t *samples, int length); +void int16_to_samples_speech(sample_t *samples, int16_t *spl, int length); +void samples_to_int16_1mw(int16_t *spl, sample_t *samples, int length); +void int16_to_samples_1mw(sample_t *samples, int16_t *spl, int length);