sip: Continue SIP->MNCC (MO or SIP Originated) implementation
Copy out to/from numbers, copy the sdp file, set the magic for the nh handle. With the incoming cancel the leg and the entire call will be terminated.
This commit is contained in:
parent
5f29be5acf
commit
7a30c94030
|
@ -87,7 +87,12 @@ struct sip_call_leg {
|
||||||
struct nua_handle_s *nua_handle;
|
struct nua_handle_s *nua_handle;
|
||||||
enum sip_cc_state state;
|
enum sip_cc_state state;
|
||||||
enum sip_dir dir;
|
enum sip_dir dir;
|
||||||
|
|
||||||
|
/* mo field */
|
||||||
const char *wanted_codec;
|
const char *wanted_codec;
|
||||||
|
|
||||||
|
/* mt field */
|
||||||
|
const char *sdp_payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mncc_cc_state {
|
enum mncc_cc_state {
|
||||||
|
|
51
src/sip.c
51
src/sip.c
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
extern void *tall_mncc_ctx;
|
extern void *tall_mncc_ctx;
|
||||||
|
|
||||||
|
static void sip_release_call(struct call_leg *_leg);
|
||||||
|
|
||||||
static void call_progress(struct sip_call_leg *leg, const sip_t *sip)
|
static void call_progress(struct sip_call_leg *leg, const sip_t *sip)
|
||||||
{
|
{
|
||||||
struct call_leg *other = call_leg_other(&leg->base);
|
struct call_leg *other = call_leg_other(&leg->base);
|
||||||
|
@ -72,6 +74,10 @@ static void call_connect(struct sip_call_leg *leg, const sip_t *sip)
|
||||||
static void new_call(struct sip_agent *agent, nua_handle_t *nh,
|
static void new_call(struct sip_agent *agent, nua_handle_t *nh,
|
||||||
const sip_t *sip)
|
const sip_t *sip)
|
||||||
{
|
{
|
||||||
|
struct call *call;
|
||||||
|
struct sip_call_leg *leg;
|
||||||
|
const char *from = NULL, *to = NULL;
|
||||||
|
|
||||||
LOGP(DSIP, LOGL_DEBUG, "Incoming call handle(%p)\n", nh);
|
LOGP(DSIP, LOGL_DEBUG, "Incoming call handle(%p)\n", nh);
|
||||||
|
|
||||||
if (!sdp_screen_sdp(sip)) {
|
if (!sdp_screen_sdp(sip)) {
|
||||||
|
@ -81,8 +87,35 @@ static void new_call(struct sip_agent *agent, nua_handle_t *nh,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nua_respond(nh, SIP_501_NOT_IMPLEMENTED, TAG_END());
|
call = call_sip_create();
|
||||||
nua_handle_destroy(nh);
|
if (!call) {
|
||||||
|
LOGP(DSIP, LOGL_ERROR, "No supported codec.\n");
|
||||||
|
nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
|
||||||
|
nua_handle_destroy(nh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sip->sip_to)
|
||||||
|
to = sip->sip_to->a_url->url_user;
|
||||||
|
if (sip->sip_from)
|
||||||
|
from = sip->sip_from->a_url->url_user;
|
||||||
|
|
||||||
|
if (!to || !from) {
|
||||||
|
LOGP(DSIP, LOGL_ERROR, "Unknown from/to for invite.\n");
|
||||||
|
nua_respond(nh, SIP_406_NOT_ACCEPTABLE, TAG_END());
|
||||||
|
nua_handle_destroy(nh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
leg = (struct sip_call_leg *) call->initial;
|
||||||
|
leg->state = SIP_CC_DLG_CNFD;
|
||||||
|
leg->dir = SIP_DIR_MO;
|
||||||
|
|
||||||
|
leg->base.release_call = sip_release_call;
|
||||||
|
leg->agent = agent;
|
||||||
|
leg->nua_handle = nh;
|
||||||
|
nua_handle_bind(nh, leg);
|
||||||
|
leg->sdp_payload = talloc_strdup(leg, sip->sip_payload->pl_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nua_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
|
void nua_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
|
||||||
|
@ -135,12 +168,22 @@ void nua_callback(nua_event_t event, int status, char const *phrase, nua_t *nua,
|
||||||
other->release_call(other);
|
other->release_call(other);
|
||||||
} else if (event == nua_i_invite) {
|
} else if (event == nua_i_invite) {
|
||||||
/* new incoming leg */
|
/* new incoming leg */
|
||||||
struct sip_call_leg *leg = (struct sip_call_leg *) hmagic;
|
|
||||||
|
|
||||||
if (status == 100)
|
if (status == 100)
|
||||||
new_call((struct sip_agent *) magic, nh, sip);
|
new_call((struct sip_agent *) magic, nh, sip);
|
||||||
} else if (event == nua_i_cancel) {
|
} else if (event == nua_i_cancel) {
|
||||||
LOGP(DSIP, LOGL_ERROR, "Canceled but not implemented.\n");
|
struct sip_call_leg *leg;
|
||||||
|
struct call_leg *other;
|
||||||
|
|
||||||
|
LOGP(DSIP, LOGL_ERROR, "Canceled on leg(%p)\n", hmagic);
|
||||||
|
|
||||||
|
leg = (struct sip_call_leg *) hmagic;
|
||||||
|
other = call_leg_other(&leg->base);
|
||||||
|
|
||||||
|
nua_handle_destroy(leg->nua_handle);
|
||||||
|
call_leg_release(&leg->base);
|
||||||
|
if (other)
|
||||||
|
other->release_call(other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue