2016-03-22 13:47:38 +00:00
|
|
|
#pragma once
|
|
|
|
|
2016-03-24 17:24:47 +00:00
|
|
|
#include "mncc_protocol.h"
|
|
|
|
|
2016-03-22 13:47:38 +00:00
|
|
|
#include <osmocom/core/linuxlist.h>
|
2016-03-23 16:08:03 +00:00
|
|
|
#include <osmocom/core/timer.h>
|
2016-04-04 15:06:29 +00:00
|
|
|
#include <osmocom/core/utils.h>
|
2021-10-27 13:28:36 +00:00
|
|
|
#include <osmocom/gsm/gsm29205.h>
|
2016-03-22 13:47:38 +00:00
|
|
|
|
2016-03-24 17:26:24 +00:00
|
|
|
#include <stdbool.h>
|
2020-09-09 15:39:09 +00:00
|
|
|
#include <netinet/in.h>
|
2016-03-22 19:56:45 +00:00
|
|
|
|
2016-03-22 13:47:38 +00:00
|
|
|
struct sip_agent;
|
|
|
|
struct mncc_connection;
|
|
|
|
|
2016-03-26 05:17:29 +00:00
|
|
|
|
|
|
|
struct nua_handle_s;
|
|
|
|
|
2016-03-22 13:47:38 +00:00
|
|
|
struct call_leg;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* One instance of a call with two legs. The initial
|
|
|
|
* field will always be used by the entity that has
|
|
|
|
* launched the call.
|
|
|
|
*/
|
|
|
|
struct call {
|
|
|
|
struct llist_head entry;
|
|
|
|
|
2016-03-22 15:31:26 +00:00
|
|
|
unsigned int id;
|
2016-03-22 13:47:38 +00:00
|
|
|
struct call_leg *initial;
|
|
|
|
struct call_leg *remote;
|
2016-04-04 17:52:41 +00:00
|
|
|
|
|
|
|
const char *source;
|
|
|
|
const char *dest;
|
2021-10-27 13:28:36 +00:00
|
|
|
|
|
|
|
/* Global Call Reference */
|
2021-01-31 04:24:29 +00:00
|
|
|
struct osmo_gcr_parsed gcr;
|
2021-10-27 13:28:36 +00:00
|
|
|
bool gcr_present;
|
2016-03-22 13:47:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
CALL_TYPE_NONE,
|
|
|
|
CALL_TYPE_SIP,
|
|
|
|
CALL_TYPE_MNCC,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct call_leg {
|
|
|
|
int type;
|
2016-03-22 20:03:19 +00:00
|
|
|
struct call *call;
|
2016-03-22 15:31:26 +00:00
|
|
|
|
2016-03-24 17:26:24 +00:00
|
|
|
bool in_release;
|
2018-08-31 13:44:30 +00:00
|
|
|
/* Field to hold GSM 04.08 Cause Value. Section 10.5.4.11 Table 10.86 */
|
|
|
|
int cause;
|
2016-03-24 17:26:24 +00:00
|
|
|
|
2016-03-24 16:35:42 +00:00
|
|
|
/**
|
|
|
|
* RTP data
|
|
|
|
*/
|
2020-09-09 15:39:09 +00:00
|
|
|
struct sockaddr_storage addr;
|
2016-03-24 16:35:42 +00:00
|
|
|
uint32_t payload_type;
|
|
|
|
uint32_t payload_msg_type;
|
|
|
|
|
2019-08-15 04:12:54 +00:00
|
|
|
/* SDP as received for this call leg. If this is an MNCC call leg, contains the SDP most recently received in an
|
|
|
|
* MNCC message; if this is a SIP call leg, contains the SDP most recently received in a SIP message. If no SDP
|
|
|
|
* was received yet, this string is empty. Otherwise a nul terminated string. */
|
forward SDP between SIP and MNCC
We have added support for sending SDP via MNCC a long time ago, but so
far the SDP section remained empty. Now, implement actually forwarding
SDP codec information between SIP and MNCC.
The aim is to let the MSC know about all codec choices the remote SIP
call leg has to offer, so that finding a codec match between local and
remote call leg becomes possible.
Store any SDP info contained in incoming SIP and MNCC messages, and send
the stored SDP to the other call leg in all outgoing SIP and MNCC
messages.
In sdp_create_file(), we used to compose fixed SDP -- instead, take the
other call leg's SDP as-is, only make sure to modify the mode (e.g.
"a=sendrecv") to reflect the current call hold state.
The RTP address and codec info in the MNCC structures is now essentially
a redundant / possibly less accurate copy of the SDP info, but leave all
of that as-is, for backwards compat.
There is codec checking that may reject unexpected codecs. The
overall/future aim is to leave all codec checking up to the MSC, but so
far just leave current behaviour unchanged, until we notice problems.
Related: SYS#5066
Related: osmo-ttcn3-hacks Ib2ae8449e673f5027f01d428d3718c006f76d93e
Change-Id: I3df5d06f38ee2d122706a9ebffde7db4f2bd6bae
2019-08-15 04:12:54 +00:00
|
|
|
char rx_sdp[1024];
|
|
|
|
/* If the contents of rx_sdp[] changes, set rx_sdp_changed = true. When the other call leg transmits the next
|
|
|
|
* message, it can decide whether to include SDP because there is new information, or whether to omit SDP
|
|
|
|
* because it was already sent identically earlier. */
|
|
|
|
bool rx_sdp_changed;
|
2019-08-15 04:12:54 +00:00
|
|
|
|
2018-10-02 14:04:17 +00:00
|
|
|
/**
|
|
|
|
* Remote started to ring/alert
|
|
|
|
*/
|
|
|
|
void (*ring_call)(struct call_leg *);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remote picked up
|
|
|
|
*/
|
|
|
|
void (*connect_call)(struct call_leg *);
|
2016-03-24 20:02:36 +00:00
|
|
|
|
2016-03-22 15:31:26 +00:00
|
|
|
/**
|
|
|
|
* Set by the call_leg implementation and will be called
|
|
|
|
* by the application to release the call.
|
|
|
|
*/
|
2016-03-22 20:03:19 +00:00
|
|
|
void (*release_call)(struct call_leg *);
|
2017-02-22 12:50:11 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A DTMF key was entered. Forward it.
|
|
|
|
*/
|
|
|
|
void (*dtmf)(struct call_leg *, int keypad);
|
2019-07-30 13:58:55 +00:00
|
|
|
|
2019-07-30 14:26:03 +00:00
|
|
|
/**
|
|
|
|
* Call HOLD requested
|
|
|
|
*/
|
|
|
|
void (*hold_call)(struct call_leg *);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call HOLD ended
|
|
|
|
*/
|
|
|
|
void (*retrieve_call)(struct call_leg *);
|
|
|
|
|
|
|
|
|
2019-07-30 13:58:55 +00:00
|
|
|
void (*update_rtp)(struct call_leg *);
|
|
|
|
|
2016-03-22 13:47:38 +00:00
|
|
|
};
|
|
|
|
|
2016-03-26 05:17:29 +00:00
|
|
|
enum sip_cc_state {
|
|
|
|
SIP_CC_INITIAL,
|
|
|
|
SIP_CC_DLG_CNFD,
|
|
|
|
SIP_CC_CONNECTED,
|
2019-07-30 14:26:03 +00:00
|
|
|
SIP_CC_HOLD,
|
2016-03-26 05:17:29 +00:00
|
|
|
};
|
|
|
|
|
2016-03-26 17:55:33 +00:00
|
|
|
enum sip_dir {
|
|
|
|
SIP_DIR_MO,
|
|
|
|
SIP_DIR_MT,
|
|
|
|
};
|
|
|
|
|
2016-03-22 13:47:38 +00:00
|
|
|
struct sip_call_leg {
|
2016-03-26 05:17:29 +00:00
|
|
|
/* base class */
|
2016-03-22 13:47:38 +00:00
|
|
|
struct call_leg base;
|
|
|
|
|
2016-03-26 05:17:29 +00:00
|
|
|
/* back pointer */
|
2016-03-22 13:47:38 +00:00
|
|
|
struct sip_agent *agent;
|
2016-03-26 05:17:29 +00:00
|
|
|
|
|
|
|
/* per instance members */
|
|
|
|
struct nua_handle_s *nua_handle;
|
|
|
|
enum sip_cc_state state;
|
2016-03-26 17:55:33 +00:00
|
|
|
enum sip_dir dir;
|
2016-03-26 19:55:02 +00:00
|
|
|
|
|
|
|
/* mo field */
|
2016-03-26 05:17:29 +00:00
|
|
|
const char *wanted_codec;
|
2016-03-26 19:55:02 +00:00
|
|
|
|
|
|
|
/* mt field */
|
|
|
|
const char *sdp_payload;
|
2016-03-22 13:47:38 +00:00
|
|
|
};
|
|
|
|
|
2016-03-22 19:56:45 +00:00
|
|
|
enum mncc_cc_state {
|
|
|
|
MNCC_CC_INITIAL,
|
2016-03-24 20:02:36 +00:00
|
|
|
MNCC_CC_PROCEEDING, /* skip delivered state */
|
|
|
|
MNCC_CC_CONNECTED,
|
2019-07-30 14:26:03 +00:00
|
|
|
MNCC_CC_HOLD,
|
2016-03-22 19:56:45 +00:00
|
|
|
};
|
|
|
|
|
2016-03-31 12:17:58 +00:00
|
|
|
enum mncc_dir {
|
|
|
|
MNCC_DIR_MO,
|
|
|
|
MNCC_DIR_MT,
|
|
|
|
};
|
|
|
|
|
2016-03-22 13:47:38 +00:00
|
|
|
struct mncc_call_leg {
|
|
|
|
struct call_leg base;
|
|
|
|
|
2016-03-22 19:56:45 +00:00
|
|
|
enum mncc_cc_state state;
|
2016-03-31 12:17:58 +00:00
|
|
|
enum mncc_dir dir;
|
|
|
|
|
2016-03-22 19:56:45 +00:00
|
|
|
uint32_t callref;
|
|
|
|
struct gsm_mncc_number called;
|
|
|
|
struct gsm_mncc_number calling;
|
2016-03-23 16:07:00 +00:00
|
|
|
char imsi[16];
|
2016-03-22 19:56:45 +00:00
|
|
|
|
2016-03-23 16:08:03 +00:00
|
|
|
struct osmo_timer_list cmd_timeout;
|
|
|
|
int rsp_wanted;
|
|
|
|
|
2016-03-22 13:47:38 +00:00
|
|
|
struct mncc_connection *conn;
|
2018-08-31 13:44:30 +00:00
|
|
|
/* Field to hold GSM 04.08 Cause Value. Section 10.5.4.11 Table 10.86 */
|
|
|
|
int cause;
|
2016-03-22 13:47:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern struct llist_head g_call_list;
|
|
|
|
void calls_init(void);
|
2016-03-22 15:31:26 +00:00
|
|
|
|
2016-03-24 17:48:45 +00:00
|
|
|
struct call_leg *call_leg_other(struct call_leg *leg);
|
2016-03-22 15:31:26 +00:00
|
|
|
|
forward SDP between SIP and MNCC
We have added support for sending SDP via MNCC a long time ago, but so
far the SDP section remained empty. Now, implement actually forwarding
SDP codec information between SIP and MNCC.
The aim is to let the MSC know about all codec choices the remote SIP
call leg has to offer, so that finding a codec match between local and
remote call leg becomes possible.
Store any SDP info contained in incoming SIP and MNCC messages, and send
the stored SDP to the other call leg in all outgoing SIP and MNCC
messages.
In sdp_create_file(), we used to compose fixed SDP -- instead, take the
other call leg's SDP as-is, only make sure to modify the mode (e.g.
"a=sendrecv") to reflect the current call hold state.
The RTP address and codec info in the MNCC structures is now essentially
a redundant / possibly less accurate copy of the SDP info, but leave all
of that as-is, for backwards compat.
There is codec checking that may reject unexpected codecs. The
overall/future aim is to leave all codec checking up to the MSC, but so
far just leave current behaviour unchanged, until we notice problems.
Related: SYS#5066
Related: osmo-ttcn3-hacks Ib2ae8449e673f5027f01d428d3718c006f76d93e
Change-Id: I3df5d06f38ee2d122706a9ebffde7db4f2bd6bae
2019-08-15 04:12:54 +00:00
|
|
|
void call_leg_rx_sdp(struct call_leg *cl, const char *rx_sdp);
|
|
|
|
|
2016-03-22 20:03:19 +00:00
|
|
|
void call_leg_release(struct call_leg *leg);
|
2016-03-22 19:56:45 +00:00
|
|
|
|
|
|
|
|
2016-03-26 17:52:22 +00:00
|
|
|
struct call *call_mncc_create(void);
|
2016-03-26 18:51:33 +00:00
|
|
|
struct call *call_sip_create(void);
|
2016-04-04 15:06:29 +00:00
|
|
|
|
|
|
|
const char *call_leg_type(struct call_leg *leg);
|
|
|
|
const char *call_leg_state(struct call_leg *leg);
|
|
|
|
|
|
|
|
extern const struct value_string call_type_vals[];
|
|
|
|
extern const struct value_string mncc_state_vals[];
|
|
|
|
extern const struct value_string mncc_dir_vals[];
|
|
|
|
extern const struct value_string sip_state_vals[];
|
|
|
|
extern const struct value_string sip_dir_vals[];
|