2012-07-09 17:39:55 +00:00
# ifndef _OSMUX_H_
# define _OSMUX_H_
2015-03-22 08:37:17 +00:00
# include <osmocom/core/endian.h>
2018-04-18 11:58:46 +00:00
# include <osmocom/core/timer.h>
2022-08-10 15:44:50 +00:00
# include <osmocom/core/msgb.h>
2015-03-22 08:37:17 +00:00
2017-04-08 18:00:47 +00:00
/*! \addtogroup osmux
* @ {
*/
/*! \file osmux.h
* Osmocom multiplex protocol helpers
*/
2022-08-10 15:46:28 +00:00
# define OSMUX_DEFAULT_PORT 1984
2012-07-09 17:39:55 +00:00
/* OSmux header:
*
2017-04-25 15:20:38 +00:00
* rtp_m ( 1 bit ) : RTP M field ( RFC3550 , RFC4867 )
* ft ( 2 bits ) : 0 = signalling , 1 = voice , 2 = dummy
2013-05-24 10:44:46 +00:00
* ctr ( 3 bits ) : Number of batched AMR payloads ( starting 0 )
* amr_f ( 1 bit ) : AMR F field ( RFC3267 )
* amr_q ( 1 bit ) : AMR Q field ( RFC3267 )
* seq ( 8 bits ) : Combination of RTP timestamp and seq . number
* circuit_id ( 8 bits ) : Circuit ID , ie . Call identifier .
* amr_ft ( 4 bits ) : AMR FT field ( RFC3267 )
* amr_cmr ( 4 bits ) : AMR CMT field ( RFC3267 )
2012-07-09 17:39:55 +00:00
*/
# define OSMUX_FT_SIGNAL 0
# define OSMUX_FT_VOICE_AMR 1
2015-07-17 18:47:04 +00:00
# define OSMUX_FT_DUMMY 2
2012-07-09 17:39:55 +00:00
struct osmux_hdr {
2018-11-15 23:18:08 +00:00
# if OSMO_IS_LITTLE_ENDIAN
osmux: major rework to reduce batch message size (add counter field)
This patch adds the counter field to the osmux header, so we can
reduce the size of the batch even further, eg.
osmuxhdr (ctr=3)
speech
speech
speech
osmuxhdr (ctr=2)
speech
speech
...
The new header is the following:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FT | CTR |F|Q| SeqNR | Circuit ID |AMR-FT |AMR-CMR|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The counter field is 3 bits long, thus, we can batch up to 8
RTP speech frames into one single batch per circuit ID.
I have also removed the RTP marker, since it can be reconstructed
from the AMR information.
Moreover, the entire workflow has been also reworked. Whenever a
packet arrives, we introduce it into the batch list. This batch
list contains a list of RTP messages ordered by RTP SSRC. Then,
once the batch timer expires or the it gets full, we build the
batch from the list of RTP messages.
Note that this allows us to put several speech frame into one
single osmux header without actually worrying about the amount
of messages that we'll receive.
The functions that reconstruct the RTP messages has been also
adjusted. Now, it returns a list of RTP messages per RTP SSRC
that has been extracted from the batch.
2012-08-02 18:24:57 +00:00
uint8_t amr_q : 1 ,
amr_f : 1 ,
ctr : 3 ,
2017-04-25 15:20:38 +00:00
ft : 2 ,
rtp_m : 1 ;
2018-11-15 23:18:08 +00:00
# elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
uint8_t rtp_m : 1 , ft : 2 , ctr : 3 , amr_f : 1 , amr_q : 1 ;
2012-07-09 17:39:55 +00:00
# endif
uint8_t seq ;
2014-08-26 11:56:19 +00:00
# define OSMUX_CID_MAX 255 /* determined by circuit_id */
osmux: major rework to reduce batch message size (add counter field)
This patch adds the counter field to the osmux header, so we can
reduce the size of the batch even further, eg.
osmuxhdr (ctr=3)
speech
speech
speech
osmuxhdr (ctr=2)
speech
speech
...
The new header is the following:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FT | CTR |F|Q| SeqNR | Circuit ID |AMR-FT |AMR-CMR|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The counter field is 3 bits long, thus, we can batch up to 8
RTP speech frames into one single batch per circuit ID.
I have also removed the RTP marker, since it can be reconstructed
from the AMR information.
Moreover, the entire workflow has been also reworked. Whenever a
packet arrives, we introduce it into the batch list. This batch
list contains a list of RTP messages ordered by RTP SSRC. Then,
once the batch timer expires or the it gets full, we build the
batch from the list of RTP messages.
Note that this allows us to put several speech frame into one
single osmux header without actually worrying about the amount
of messages that we'll receive.
The functions that reconstruct the RTP messages has been also
adjusted. Now, it returns a list of RTP messages per RTP SSRC
that has been extracted from the batch.
2012-08-02 18:24:57 +00:00
uint8_t circuit_id ;
2018-11-15 23:18:08 +00:00
# if OSMO_IS_LITTLE_ENDIAN
osmux: major rework to reduce batch message size (add counter field)
This patch adds the counter field to the osmux header, so we can
reduce the size of the batch even further, eg.
osmuxhdr (ctr=3)
speech
speech
speech
osmuxhdr (ctr=2)
speech
speech
...
The new header is the following:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FT | CTR |F|Q| SeqNR | Circuit ID |AMR-FT |AMR-CMR|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The counter field is 3 bits long, thus, we can batch up to 8
RTP speech frames into one single batch per circuit ID.
I have also removed the RTP marker, since it can be reconstructed
from the AMR information.
Moreover, the entire workflow has been also reworked. Whenever a
packet arrives, we introduce it into the batch list. This batch
list contains a list of RTP messages ordered by RTP SSRC. Then,
once the batch timer expires or the it gets full, we build the
batch from the list of RTP messages.
Note that this allows us to put several speech frame into one
single osmux header without actually worrying about the amount
of messages that we'll receive.
The functions that reconstruct the RTP messages has been also
adjusted. Now, it returns a list of RTP messages per RTP SSRC
that has been extracted from the batch.
2012-08-02 18:24:57 +00:00
uint8_t amr_cmr : 4 ,
amr_ft : 4 ;
2018-11-15 23:18:08 +00:00
# elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
uint8_t amr_ft : 4 , amr_cmr : 4 ;
2012-07-09 17:39:55 +00:00
# endif
} __attribute__ ( ( packed ) ) ;
/* one to handle all existing RTP flows */
struct osmux_in_handle {
uint8_t osmux_seq ;
2012-08-06 16:45:18 +00:00
uint8_t batch_factor ;
2014-08-28 13:01:03 +00:00
uint16_t batch_size ;
2014-08-28 14:14:16 +00:00
struct {
uint32_t input_rtp_msgs ;
uint32_t output_osmux_msgs ;
uint64_t input_rtp_bytes ;
uint64_t output_osmux_bytes ;
} stats ;
2013-02-11 21:49:27 +00:00
void ( * deliver ) ( struct msgb * msg , void * data ) ;
void * data ;
char * internal_data ; /* internal data to store batch */
2012-07-09 17:39:55 +00:00
} ;
2012-08-06 18:20:57 +00:00
# define OSMUX_MAX_CONCURRENT_CALLS 8
2012-07-09 17:39:55 +00:00
/* one per OSmux circuit_id, ie. one per RTP flow. */
struct osmux_out_handle {
2013-02-12 16:23:29 +00:00
uint16_t rtp_seq ;
uint32_t rtp_timestamp ;
2013-05-12 16:03:50 +00:00
uint32_t rtp_ssrc ;
2019-05-17 15:11:02 +00:00
uint8_t rtp_payload_type ;
2018-04-18 17:10:20 +00:00
uint8_t osmux_seq_ack ; /* Latest received seq num */
2018-04-18 11:58:46 +00:00
struct osmo_timer_list timer ;
struct llist_head list ;
void ( * tx_cb ) ( struct msgb * msg , void * data ) ; /* Used defined rtp tx callback */
void * data ; /* User defined opaque data structure */
2012-07-09 17:39:55 +00:00
} ;
2012-08-02 18:25:36 +00:00
static inline uint8_t * osmux_get_payload ( struct osmux_hdr * osmuxh )
2012-07-09 17:39:55 +00:00
{
return ( uint8_t * ) osmuxh + sizeof ( struct osmux_hdr ) ;
}
2013-02-19 16:14:33 +00:00
int osmux_snprintf ( char * buf , size_t size , struct msgb * msg ) ;
2014-08-29 13:20:56 +00:00
/* 1500 - sizeof(iphdr) = 20 bytes - sizeof(udphdr) = 8 bytes. */
# define OSMUX_BATCH_DEFAULT_MAX 1472
2012-07-09 17:39:55 +00:00
void osmux_xfrm_input_init ( struct osmux_in_handle * h ) ;
2014-08-28 10:45:04 +00:00
void osmux_xfrm_input_fini ( struct osmux_in_handle * h ) ;
2012-08-06 16:41:49 +00:00
2015-07-17 18:47:04 +00:00
int osmux_xfrm_input_open_circuit ( struct osmux_in_handle * h , int ccid , int dummy ) ;
2015-07-17 17:55:18 +00:00
void osmux_xfrm_input_close_circuit ( struct osmux_in_handle * h , int ccid ) ;
2012-10-20 18:10:31 +00:00
int osmux_xfrm_input ( struct osmux_in_handle * h , struct msgb * msg , int ccid ) ;
2012-07-09 17:39:55 +00:00
void osmux_xfrm_input_deliver ( struct osmux_in_handle * h ) ;
2022-08-31 15:28:36 +00:00
struct osmux_out_handle * osmux_xfrm_output_alloc ( void * ctx ) ;
void osmux_xfrm_output_init ( struct osmux_out_handle * h , uint32_t rtp_ssrc ) OSMO_DEPRECATED ( " Use osmux_xfrm_output_alloc() and osmux_xfrm_output_set_rtp_*() instead " ) ;
void osmux_xfrm_output_init2 ( struct osmux_out_handle * h , uint32_t rtp_ssrc , uint8_t rtp_payload_type ) OSMO_DEPRECATED ( " Use osmux_xfrm_output_alloc() and osmux_xfrm_output_set_rtp_*() instead " ) ;
void osmux_xfrm_output_set_rtp_ssrc ( struct osmux_out_handle * h , uint32_t rtp_ssrc ) ;
void osmux_xfrm_output_set_rtp_pl_type ( struct osmux_out_handle * h , uint32_t rtp_payload_type ) ;
2018-04-18 11:58:46 +00:00
void osmux_xfrm_output_set_tx_cb ( struct osmux_out_handle * h , void ( * tx_cb ) ( struct msgb * msg , void * data ) , void * data ) ;
int osmux_xfrm_output_sched ( struct osmux_out_handle * h , struct osmux_hdr * osmuxh ) ;
void osmux_xfrm_output_flush ( struct osmux_out_handle * h ) ;
2012-07-09 17:39:55 +00:00
struct osmux_hdr * osmux_xfrm_output_pull ( struct msgb * msg ) ;
2017-04-08 18:00:47 +00:00
/*! @} */
2012-07-09 17:39:55 +00:00
# endif