Prepare to support MO Call HOLD
Add function pointers to the call_leg struct for call hold and retrieve. Add function to send re-INVITE to SIP side when MNCC side puts call on HOLD/RETRIEVES. Add MNCC/SIP CC_HOLD to call states. Change-Id: I2595626dfa50eb2f8e29a02540b708c9c1dce88c
This commit is contained in:
parent
5f73c2033b
commit
bd2d14bd4a
|
@ -40,6 +40,7 @@ const struct value_string mncc_state_vals[] = {
|
||||||
{ MNCC_CC_INITIAL, "INITIAL" },
|
{ MNCC_CC_INITIAL, "INITIAL" },
|
||||||
{ MNCC_CC_PROCEEDING, "PROCEEDING" },
|
{ MNCC_CC_PROCEEDING, "PROCEEDING" },
|
||||||
{ MNCC_CC_CONNECTED, "CONNECTED" },
|
{ MNCC_CC_CONNECTED, "CONNECTED" },
|
||||||
|
{ MNCC_CC_HOLD, "ON HOLD" },
|
||||||
{ 0, NULL },
|
{ 0, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ const struct value_string sip_state_vals[] = {
|
||||||
{ SIP_CC_INITIAL, "INITIAL" },
|
{ SIP_CC_INITIAL, "INITIAL" },
|
||||||
{ SIP_CC_DLG_CNFD, "CONFIRMED" },
|
{ SIP_CC_DLG_CNFD, "CONFIRMED" },
|
||||||
{ SIP_CC_CONNECTED, "CONNECTED" },
|
{ SIP_CC_CONNECTED, "CONNECTED" },
|
||||||
|
{ SIP_CC_HOLD, "ON HOLD" },
|
||||||
{ 0, NULL },
|
{ 0, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
13
src/call.h
13
src/call.h
|
@ -75,6 +75,17 @@ struct call_leg {
|
||||||
*/
|
*/
|
||||||
void (*dtmf)(struct call_leg *, int keypad);
|
void (*dtmf)(struct call_leg *, int keypad);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call HOLD requested
|
||||||
|
*/
|
||||||
|
void (*hold_call)(struct call_leg *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call HOLD ended
|
||||||
|
*/
|
||||||
|
void (*retrieve_call)(struct call_leg *);
|
||||||
|
|
||||||
|
|
||||||
void (*update_rtp)(struct call_leg *);
|
void (*update_rtp)(struct call_leg *);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -83,6 +94,7 @@ enum sip_cc_state {
|
||||||
SIP_CC_INITIAL,
|
SIP_CC_INITIAL,
|
||||||
SIP_CC_DLG_CNFD,
|
SIP_CC_DLG_CNFD,
|
||||||
SIP_CC_CONNECTED,
|
SIP_CC_CONNECTED,
|
||||||
|
SIP_CC_HOLD,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sip_dir {
|
enum sip_dir {
|
||||||
|
@ -113,6 +125,7 @@ enum mncc_cc_state {
|
||||||
MNCC_CC_INITIAL,
|
MNCC_CC_INITIAL,
|
||||||
MNCC_CC_PROCEEDING, /* skip delivered state */
|
MNCC_CC_PROCEEDING, /* skip delivered state */
|
||||||
MNCC_CC_CONNECTED,
|
MNCC_CC_CONNECTED,
|
||||||
|
MNCC_CC_HOLD,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mncc_dir {
|
enum mncc_dir {
|
||||||
|
|
40
src/sip.c
40
src/sip.c
|
@ -40,6 +40,9 @@ static void sip_release_call(struct call_leg *_leg);
|
||||||
static void sip_ring_call(struct call_leg *_leg);
|
static void sip_ring_call(struct call_leg *_leg);
|
||||||
static void sip_connect_call(struct call_leg *_leg);
|
static void sip_connect_call(struct call_leg *_leg);
|
||||||
static void sip_dtmf_call(struct call_leg *_leg, int keypad);
|
static void sip_dtmf_call(struct call_leg *_leg, int keypad);
|
||||||
|
static void sip_hold_call(struct call_leg *_leg);
|
||||||
|
static void sip_retrieve_call(struct call_leg *_leg);
|
||||||
|
|
||||||
|
|
||||||
/* Find a SIP Call leg by given nua_handle */
|
/* Find a SIP Call leg by given nua_handle */
|
||||||
static struct sip_call_leg *sip_find_leg(nua_handle_t *nh)
|
static struct sip_call_leg *sip_find_leg(nua_handle_t *nh)
|
||||||
|
@ -160,6 +163,8 @@ static void new_call(struct sip_agent *agent, nua_handle_t *nh,
|
||||||
leg->base.ring_call = sip_ring_call;
|
leg->base.ring_call = sip_ring_call;
|
||||||
leg->base.connect_call = sip_connect_call;
|
leg->base.connect_call = sip_connect_call;
|
||||||
leg->base.dtmf = sip_dtmf_call;
|
leg->base.dtmf = sip_dtmf_call;
|
||||||
|
leg->base.hold_call = sip_hold_call;
|
||||||
|
leg->base.retrieve_call = sip_retrieve_call;
|
||||||
leg->agent = agent;
|
leg->agent = agent;
|
||||||
leg->nua_handle = nh;
|
leg->nua_handle = nh;
|
||||||
nua_handle_bind(nh, leg);
|
nua_handle_bind(nh, leg);
|
||||||
|
@ -441,6 +446,7 @@ static void sip_release_call(struct call_leg *_leg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SIP_CC_CONNECTED:
|
case SIP_CC_CONNECTED:
|
||||||
|
case SIP_CC_HOLD:
|
||||||
LOGP(DSIP, LOGL_NOTICE, "Ending leg(%p) in con\n", leg);
|
LOGP(DSIP, LOGL_NOTICE, "Ending leg(%p) in con\n", leg);
|
||||||
nua_bye(leg->nua_handle, TAG_END());
|
nua_bye(leg->nua_handle, TAG_END());
|
||||||
break;
|
break;
|
||||||
|
@ -503,6 +509,40 @@ static void sip_dtmf_call(struct call_leg *_leg, int keypad)
|
||||||
talloc_free(buf);
|
talloc_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sip_hold_call(struct call_leg *_leg)
|
||||||
|
{
|
||||||
|
struct sip_call_leg *leg;
|
||||||
|
struct call_leg *other_leg;
|
||||||
|
OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);
|
||||||
|
leg = (struct sip_call_leg *) _leg;
|
||||||
|
other_leg = call_leg_other(&leg->base);
|
||||||
|
char *sdp = sdp_create_file(leg, other_leg, sdp_sendonly);
|
||||||
|
nua_invite(leg->nua_handle,
|
||||||
|
NUTAG_MEDIA_ENABLE(0),
|
||||||
|
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
|
||||||
|
SIPTAG_PAYLOAD_STR(sdp),
|
||||||
|
TAG_END());
|
||||||
|
talloc_free(sdp);
|
||||||
|
leg->state = SIP_CC_HOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sip_retrieve_call(struct call_leg *_leg)
|
||||||
|
{
|
||||||
|
struct sip_call_leg *leg;
|
||||||
|
struct call_leg *other_leg;
|
||||||
|
OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);
|
||||||
|
leg = (struct sip_call_leg *) _leg;
|
||||||
|
other_leg = call_leg_other(&leg->base);
|
||||||
|
char *sdp = sdp_create_file(leg, other_leg, sdp_sendrecv);
|
||||||
|
nua_invite(leg->nua_handle,
|
||||||
|
NUTAG_MEDIA_ENABLE(0),
|
||||||
|
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
|
||||||
|
SIPTAG_PAYLOAD_STR(sdp),
|
||||||
|
TAG_END());
|
||||||
|
talloc_free(sdp);
|
||||||
|
leg->state = SIP_CC_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
static int send_invite(struct sip_agent *agent, struct sip_call_leg *leg,
|
static int send_invite(struct sip_agent *agent, struct sip_call_leg *leg,
|
||||||
const char *calling_num, const char *called_num)
|
const char *calling_num, const char *called_num)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue