📄 nua_glib.c
字号:
return; case nua_r_register: sof_r_register(status, phrase, nua, self, nh, op, sip, tags); return; case nua_r_unregister: sof_r_unregister(status, phrase, nua, self, nh, op, sip, tags); return; case nua_r_options: sof_r_options(status, phrase, nua, self, nh, op, sip, tags); return; case nua_r_invite: sof_r_invite(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_fork: sof_i_fork(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_invite: sof_i_invite(nua, self, nh, op, sip, tags); return; case nua_i_prack: sof_i_prack(nua, self, nh, op, sip, tags); return; case nua_i_active: sof_i_active(nua, self, nh, op, sip, tags); return; case nua_i_state: sof_i_state(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_terminated: sof_i_terminated(status, phrase, nua, self, nh, op, sip, tags); return; case nua_r_bye: sof_r_bye(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_bye: sof_i_bye(nua, self, nh, op, sip, tags); return; case nua_r_message: sof_r_message(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_message: sof_i_message(nua, self, nh, op, sip, tags); return; case nua_r_info: sof_r_info(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_info: sof_i_info(nua, self, nh, op, sip, tags); return; case nua_r_refer: sof_r_refer(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_refer: sof_i_refer(nua, self, nh, op, sip, tags); return; case nua_r_subscribe: sof_r_subscribe(status, phrase, nua, self, nh, op, sip, tags); return; case nua_r_unsubscribe: sof_r_unsubscribe(status, phrase, nua, self, nh, op, sip, tags); return; case nua_r_publish: sof_r_publish(status, phrase, nua, self, nh, op, sip, tags); return; case nua_r_notify: sof_r_notify(status, phrase, nua, self, nh, op, sip, tags); return; case nua_i_notify: sof_i_notify(nua, self, nh, op, sip, tags); return; case nua_i_cancel: sof_i_cancel(nua, self, nh, op, sip, tags); return; case nua_i_error: sof_i_error(nua, self, nh, op, status, phrase, tags); return; default: break; } if (status > 100) g_warning("%s: unknown event %d: %03d %s\n", self->priv->name, event, status, phrase); else g_warning("%s: unknown event %d\n", self->priv->name, event); tl_print(stderr, "", tags);}/* ====================================================================== */static inlinevoid oper_assign(NuaGlibOp *op, sip_method_t method, char const *name);static void nua_glib_op_destroy(NuaGlib *self, NuaGlibOp *op);static NuaGlibOp *nua_glib_op_create(NuaGlib *self, sip_method_t method, char const *name, const char *address, tag_type_t tag, tag_value_t value, ...){ NuaGlibOp *op, *old; ta_list ta; enter; for (old = self->priv->operations; old; old = old->op_next) if (!old->op_persistent) break; if (address) { int have_url = 1; sip_to_t *to; to = sip_to_make(self->priv->home, address); if (to == NULL) { /*TODO, error returns*/ g_warning("%s: %s: invalid address: %s\n", self->priv->name, name, address); return NULL; } /* Try to make sense out of the URL */ if (url_sanitize(to->a_url) < 0) { /*TODO, error returns*/ g_warning("%s: %s: invalid address\n", self->priv->name, name); return NULL; } if (!(op = su_zalloc(self->priv->home, sizeof(*op)))) { /*TODO, error returns*/ g_warning("%s: %s: cannot create handle\n", self->priv->name, name); return NULL; } op->op_parent = self; op->op_next = self->priv->operations; op->op_prev_state = -1; self->priv->operations = op; if (method == sip_method_register) have_url = 0; ta_start(ta, tag, value); op->op_handle = nua_handle(self->priv->nua, op, TAG_IF(have_url, NUTAG_URL(to->a_url)), SIPTAG_TO(to), ta_tags(ta)); ta_end(ta); op->op_ident = sip_header_as_string(self->priv->home, (sip_header_t *)to); oper_assign(op, method, name); if (!op->op_persistent) { NuaGlibOp *old_next; for (; old; old = old_next) { /* Clean old handles */ old_next = old->op_next; if (!old->op_persistent && !old->op_callstate) nua_glib_op_destroy(self, old); } } su_free(self->priv->home, to); } else if (method || name) oper_assign(op = old, method, name); else return old; if (!op) { if (address) /*TODO, error returns*/ g_warning("%s: %s: invalid destination\n", self->priv->name, name); else /*TODO, error returns*/ g_warning("%s: %s: no destination\n", self->priv->name, name); return NULL; } return op;}static NuaGlibOp *nua_glib_op_create2(NuaGlib *self, sip_method_t method, char const *name, nua_handle_t *nh, sip_from_t const *from){ NuaGlibOp *op; enter; if ((op = su_zalloc(self->priv->home, sizeof(*op)))) { op->op_parent = self; op->op_next = self->priv->operations; self->priv->operations = op; oper_assign(op, method, name); nua_handle_bind(op->op_handle = nh, op); op->op_ident = sip_header_as_string(self->priv->home, (sip_header_t*)from); } else { SU_DEBUG_1(("%s: cannot create operation object for %s\n", self->priv->name, name)); } return op;}/** Delete operation and attached handles and identities */static void nua_glib_op_destroy(NuaGlib *self, NuaGlibOp *op){ NuaGlibOp **prev; if (!op) return; g_assert(op->data == NULL); /* Remove from queue */ for (prev = &self->priv->operations; *prev && *prev != op; prev = &(*prev)->op_next) ; if (*prev) *prev = op->op_next, op->op_next = NULL; if (op->op_authlist) nua_glib_auth_clear(self, op); if (op->op_handle) nua_handle_destroy(op->op_handle), op->op_handle = NULL; su_free(self->priv->home, op);}/* ====================================================================== */static void oper_assign(NuaGlibOp *op, sip_method_t method, char const *name){ if (!op) return; op->op_method = method, op->op_method_name = name; op->op_persistent = method == sip_method_subscribe || method == sip_method_register || method == sip_method_publish;}/** * Helper function called from all response callback handler. * Checks whether authentication is needed, and handles it if * require. Marks succesful authentications as completed. */static void priv_oper_check_response_for_auth(NuaGlib *self, NuaGlibOp *op, int status, sip_t const *sip, tagi_t *tags){ if (status == 401 || status == 407) { priv_oper_handle_auth(self, op, sip, tags); } else if (status >= 200 && status <= 299){ if (op->op_authstate != opa_none && op->op_authstate != opa_auth_ok) { op->op_authstate = opa_auth_ok; SU_DEBUG_3(("%s: authorization of %s (%p) was succesful\n", self->priv->name, op->op_method_name, op)); } }}/** * Handles authentication challenge for operation 'op'. */static void priv_oper_handle_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags){ sip_www_authenticate_t const *wa = sip->sip_www_authenticate; sip_proxy_authenticate_t const *pa = sip->sip_proxy_authenticate; sip_from_t const *sipfrom = sip->sip_from; const char *realm = NULL; enter; tl_gets(tags, SIPTAG_WWW_AUTHENTICATE_REF(wa), SIPTAG_PROXY_AUTHENTICATE_REF(pa), TAG_NULL()); SU_DEBUG_3(("%s: %s (%p) was unauthorized\n", self->priv->name, op->op_method_name, op)); /* step: the initial challenge */ if (op->op_authstate == opa_none) { if (wa) { sl_header_print(stdout, "Server auth: %s\n", (sip_header_t *)wa); realm = msg_params_find(wa->au_params, "realm="); nua_glib_auth_add(self, op, wa->au_scheme, realm, sipfrom->a_url->url_user, self->priv->password); } if (pa) { sl_header_print(stdout, "Proxy auth: %s\n", (sip_header_t *)pa); realm = msg_params_find(pa->au_params, "realm="); nua_glib_auth_add(self, op, pa->au_scheme, realm, sipfrom->a_url->url_user, self->priv->password); } op->op_authstate = opa_try_derived; priv_submit_authlist(op); } /* step: a new challenge and local credentials updated since last attempt */ else if (op->op_authstate == opa_retry) { priv_submit_authlist(op); } /* step: a new challenge, ask for matching credentials */ else if (op->op_authstate == opa_try_derived) { g_message("Requesting for additional authentication credentials %s(%s)", self->priv->name, op->op_method_name); op->op_authstate = opa_auth_req; g_signal_emit(self, signals[NGSIG_AUTH_REQUIRED], 0, op, op->op_method_name, realm); } /* step: a new challenge, ask for matching credentials */ else if (op->op_authstate == opa_auth_req) { g_message("Failed auth for %s by %s", op->op_method_name, self->priv->name); op->op_authstate = opa_failed; }}/** * nua_glib_op_owner: * * get the owning NuaGlib for a given NuaGlibOp */NuaGlib* nua_glib_op_owner(NuaGlibOp *op){ return op->op_parent;}sip_method_tnua_glib_op_method_type(NuaGlibOp *op){ return op->op_method;}/** * nua_glib_op_set_data: * @op: op to attach data to * @data: data to attach * * Attach an applciation specific blob of data to a NuaGlibOp * The application is in charge of deleting the data when it * removes any internal references to the @op. When it has done * so, it should call this function with @data set to NULL * Failing to do so will cause an assertion. */voidnua_glib_op_set_data(NuaGlibOp *op, gpointer data){ op->data = data;}/** * nua_glib_op_get_data: * @op: op to get data from * * Get an application specific blob of data from a NuaGlibOp * Returns: attached data */gpointernua_glib_op_get_data(NuaGlibOp *op){ return op->data ;}/** * nua_glib_op_get_identity: * @op: op to get data from * * Get the identity of an operation * This is the contents of To: when initiating, From: when receiving. * Returns: the identity */const gchar *nua_glib_op_get_identity(NuaGlibOp *op){ return op->op_ident;}static void sof_i_error(nua_t *nua, NuaGlib *self, nua_handle_t *nh, NuaGlibOp *op, int status, char const *phrase, tagi_t tags[]){ g_signal_emit(self, signals[NGSIG_ERROR], status, phrase);}/** * nua_glib_invite: * @destination sip address to invite * @local_sdp an SDP blob describing local capabilites * * Issue an INVITE * Return value: operation descriptor for this operation, NULL if failure * */NuaGlibOp *nua_glib_invite(NuaGlib *self, const char *destination, const char *local_sdp){ NuaGlibOp *op; op = nua_glib_op_create(self, SIP_METHOD_INVITE, destination, TAG_END()); /* SDP O/A note: * - pass media information to nua_invite() in the * SOATAG_USER_SDP_STR() tag * - see also: sof_i_state() and nua_glib_answer() */ if (op) { nua_invite(op->op_handle, SOATAG_USER_SDP_STR(local_sdp), TAG_END()); op->op_callstate |= opc_sent; return op; } return NULL;}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -