libosmo-netif
0.2.0-dirty
Osmocom network interface library
|
00001 #ifndef _OSMUX_H_ 00002 #define _OSMUX_H_ 00003 00004 #include <osmocom/core/endian.h> 00005 #include <osmocom/core/timer.h> 00006 00015 /* OSmux header: 00016 * 00017 * rtp_m (1 bit): RTP M field (RFC3550, RFC4867) 00018 * ft (2 bits): 0=signalling, 1=voice, 2=dummy 00019 * ctr (3 bits): Number of batched AMR payloads (starting 0) 00020 * amr_f (1 bit): AMR F field (RFC3267) 00021 * amr_q (1 bit): AMR Q field (RFC3267) 00022 * seq (8 bits): Combination of RTP timestamp and seq. number 00023 * circuit_id (8 bits): Circuit ID, ie. Call identifier. 00024 * amr_ft (4 bits): AMR FT field (RFC3267) 00025 * amr_cmr (4 bits): AMR CMT field (RFC3267) 00026 */ 00027 00028 #define OSMUX_FT_SIGNAL 0 00029 #define OSMUX_FT_VOICE_AMR 1 00030 #define OSMUX_FT_DUMMY 2 00031 00032 struct osmux_hdr { 00033 #if OSMO_IS_BIG_ENDIAN 00034 uint8_t rtp_m:1, 00035 ft:2, 00036 ctr:3, 00037 amr_f:1, 00038 amr_q:1; 00039 #elif OSMO_IS_LITTLE_ENDIAN 00040 uint8_t amr_q:1, 00041 amr_f:1, 00042 ctr:3, 00043 ft:2, 00044 rtp_m:1; 00045 #endif 00046 uint8_t seq; 00047 #define OSMUX_CID_MAX 255 /* determined by circuit_id */ 00048 uint8_t circuit_id; 00049 #if OSMO_IS_BIG_ENDIAN 00050 uint8_t amr_ft:4, 00051 amr_cmr:4; 00052 #elif OSMO_IS_LITTLE_ENDIAN 00053 uint8_t amr_cmr:4, 00054 amr_ft:4; 00055 #endif 00056 } __attribute__((packed)); 00057 00058 /* one to handle all existing RTP flows */ 00059 struct osmux_in_handle { 00060 uint8_t osmux_seq; 00061 uint8_t batch_factor; 00062 uint16_t batch_size; 00063 00064 struct { 00065 uint32_t input_rtp_msgs; 00066 uint32_t output_osmux_msgs; 00067 uint64_t input_rtp_bytes; 00068 uint64_t output_osmux_bytes; 00069 } stats; 00070 00071 void (*deliver)(struct msgb *msg, void *data); 00072 void *data; 00073 char *internal_data; /* internal data to store batch */ 00074 }; 00075 00076 #define OSMUX_MAX_CONCURRENT_CALLS 8 00077 00078 /* one per OSmux circuit_id, ie. one per RTP flow. */ 00079 struct osmux_out_handle { 00080 uint16_t rtp_seq; 00081 uint32_t rtp_timestamp; 00082 uint32_t rtp_ssrc; 00083 uint8_t osmux_seq_ack; /* Latest received seq num */ 00084 struct osmo_timer_list timer; 00085 struct llist_head list; 00086 void (*tx_cb)(struct msgb *msg, void *data); /* Used defined rtp tx callback */ 00087 void *data; /* User defined opaque data structure */ 00088 }; 00089 00090 static inline uint8_t *osmux_get_payload(struct osmux_hdr *osmuxh) 00091 { 00092 return (uint8_t *)osmuxh + sizeof(struct osmux_hdr); 00093 } 00094 00095 int osmux_snprintf(char *buf, size_t size, struct msgb *msg); 00096 00097 /* 1500 - sizeof(iphdr) = 20 bytes - sizeof(udphdr) = 8 bytes. */ 00098 #define OSMUX_BATCH_DEFAULT_MAX 1472 00099 00100 void osmux_xfrm_input_init(struct osmux_in_handle *h); 00101 void osmux_xfrm_input_fini(struct osmux_in_handle *h); 00102 00103 int osmux_xfrm_input_open_circuit(struct osmux_in_handle *h, int ccid, int dummy); 00104 void osmux_xfrm_input_close_circuit(struct osmux_in_handle *h, int ccid); 00105 00106 int osmux_xfrm_input(struct osmux_in_handle *h, struct msgb *msg, int ccid); 00107 void osmux_xfrm_input_deliver(struct osmux_in_handle *h); 00108 00109 void osmux_xfrm_output_init(struct osmux_out_handle *h, uint32_t rtp_ssrc); 00110 void osmux_xfrm_output_set_tx_cb(struct osmux_out_handle *h, void (*tx_cb)(struct msgb *msg, void *data), void *data); 00111 int osmux_xfrm_output(struct osmux_hdr *osmuxh, struct osmux_out_handle *h, struct llist_head *list) OSMO_DEPRECATED("Use osmux_xfrm_output_sched() instead"); 00112 int osmux_xfrm_output_sched(struct osmux_out_handle *h, struct osmux_hdr *osmuxh); 00113 void osmux_xfrm_output_flush(struct osmux_out_handle *h); 00114 struct osmux_hdr *osmux_xfrm_output_pull(struct msgb *msg); 00115 00116 void osmux_tx_sched(struct llist_head *list, void (*tx_cb)(struct msgb *msg, void *data), void *data) OSMO_DEPRECATED("Use osmux_xfrm_output_set_tx_cb() instead"); 00117 00120 #endif