⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nua_glib.c

📁 this is simple sip stack.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005-2006 Nokia Corporation. * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * Copyright (C) 2005 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@file nua_glib.c Interface towards libsofia-sip-ua. *  * @author Kai Vehmanen <kai.vehmanen@nokia.com> * @author Rob Taylor <rob.taylor@collabora.co.uk> * @author Pekka Pessi <pekka.pessi@nokia.com> * @author Martti Mela <martti.mela@nokia.com> */#include <stddef.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <stdarg.h>#include <assert.h>#include <glib.h>#include "sofia-sip/nua_glib.h"#include "nua_glib_priv.h"#include "nua_glib_marshal.h"/*=============== Class and Object init ===============*/G_DEFINE_TYPE(NuaGlib, nua_glib, G_TYPE_OBJECT);  /*signal enum*/enum{  NGSIG_CALL_FORKED = 1,  NGSIG_INCOMING_INVITE,  NGSIG_INCOMING_REINVITE,  NGSIG_CALL_STATE_CHANGED,  NGSIG_INCOMING_ACTIVE,  NGSIG_CALL_TERMINATED,  NGSIG_INCOMING_PRACK,  NGSIG_INCOMING_BYE,  NGSIG_INCOMING_CANCEL,  NGSIG_INCOMING_MESSAGE,  NGSIG_INCOMING_INFO,  NGSIG_INCOMING_REFER,  NGSIG_INCOMING_NOTIFY,  NGSIG_ERROR,  NGSIG_SHUTDOWN,  NGSIG_REGISTER_ANSWERED,  NGSIG_UNREGISTER_ANSWERED,  NGSIG_PUBLISH_ANSWERED,  NGSIG_INVITE_ANSWERED,  NGSIG_BYE_ANSWERED,  NGSIG_MESSAGE_ANSWERED,  NGSIG_INFO_ANSWERED,  NGSIG_REFER_ANSWERED,  NGSIG_SUBSCRIBE_ANSWERED,  NGSIG_UNSUBSCRIBE_ANSWERED,  NGSIG_NOTIFY_ANSWERED,  NGSIG_OPTIONS_ANSWERED,  NGSIG_AUTH_REQUIRED,  NGSIG_LAST_SIGNAL};static guint signals[NGSIG_LAST_SIGNAL] = {0};enum{  PROP_ADDRESS = 1,  PROP_PASSWORD,  PROP_CONTACT,  PROP_PROXY,  PROP_REGISTRAR,  PROP_STUN_SERVER,  LAST_PROPERTY};void final_shutdown(NuaGlib *self){  g_object_unref(self);}static GObjectClass *parent_class=NULL;  static int sof_init(NuaGlibPrivate *priv, const char *contact);static void priv_submit_authlist(NuaGlibOp *op);static void priv_oper_handle_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags);static void priv_oper_check_response_for_auth(NuaGlib *self, NuaGlibOp *op, int status, sip_t const *sip, tagi_t *tags);static GObject *nua_glib_constructor (GType                  type,		      guint                  n_construct_properties,		      GObjectConstructParam *construct_properties){  GObject *obj;  int res = 0;  GSource *gsource;  {    /* Invoke parent constructor.     * this calls our init, and then set_property with any     * CONSTRUCT params     */    NuaGlibClass *klass;    klass = NUA_GLIB_CLASS (g_type_class_peek (NUA_GLIB_TYPE));    parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));    obj = parent_class->constructor (type,                                     n_construct_properties,                                     construct_properties);  }    NuaGlib *self = NUA_GLIB(obj);  /* create a su event loop and connect it to glib */  self->priv->root = su_root_source_create(self);  assert(self->priv->root);  gsource = su_root_gsource(self->priv->root);  assert(gsource);  g_source_attach(gsource, NULL);  /*check address has been set*/  g_assert(strcmp(self->priv->address, "no-address-set")!=0);  res = sof_init(self->priv, self->priv->contact);  if (res != -1) {    self->priv->nua = nua_create(self->priv->root, 				 sof_callback, self,				 NUTAG_SOA_NAME("default"),				 TAG_IF(self->priv->stun_server,					STUNTAG_SERVER(self->priv->stun_server)),				 TAG_IF(self->priv->contact,					NUTAG_URL(self->priv->contact)),				 /* XXX: SOATAG_CAPS_SDP_STR(local_caps), */				 TAG_NULL());    if (self->priv->nua) {      nua_set_params(self->priv->nua,                     TAG_IF(self->priv->proxy, NUTAG_PROXY(self->priv->proxy)),                     TAG_IF(self->priv->registrar, NUTAG_REGISTRAR(self->priv->registrar)),                     NUTAG_ENABLEMESSAGE(1),                     NUTAG_ENABLEINVITE(1),                     /* NUTAG_SESSION_TIMER(s_e), */                     /* NUTAG_MIN_SE(min_se), */                     SOATAG_AF(SOA_AF_IP4_IP6),                     SIPTAG_FROM_STR(self->priv->address),                     /* NUTAG_CERTIFICATE_DIR(getenv("SIPCERTDIR")),*/                     TAG_NULL());      nua_get_params(self->priv->nua, TAG_ANY(), TAG_NULL());      self->priv->init=TRUE;      g_signal_connect_after(self, "shutdown", (GCallback)final_shutdown, NULL);    }  }  return obj;}static voidnua_glib_init(NuaGlib *self){  self->priv =  g_new0(NuaGlibPrivate, 1); /* initialize sofia su OS abstraction layer */  su_init();  su_home_init(self->priv->home);}static voidnua_glib_dispose(GObject *obj){  NuaGlib *self = NUA_GLIB(obj);  if (self->priv->init)  {    g_free((gpointer)self->priv->contact);    nua_shutdown(self->priv->nua);    self->priv->init = FALSE;    /*now hold a ref to ourselves that we drop when distruction is complete*/    g_object_ref (obj);  /* TODO:some start/stop nua funtions to do su_init/de_init?  su_deinit();*/  }  /* Chain up to the parent class */  G_OBJECT_CLASS (parent_class)->dispose (obj);}static voidnua_glib_finalize (GObject *obj){  NuaGlib *self = NUA_GLIB(obj);  su_root_break(self->priv->root);  nua_destroy(self->priv->nua);  su_root_destroy(self->priv->root), self->priv->root = NULL;  su_home_deinit(self->priv->home);  g_free(self->priv);  /* Chain up to the parent class */  G_OBJECT_CLASS (parent_class)->finalize (obj); }staticvoid nua_glib_set_property(GObject      *object,			   guint         property_id,			   const GValue *value,			   GParamSpec   *pspec){  NuaGlib *self = (NuaGlib*) object;#define STORE_PARAM(s, x)			\  g_free ((gpointer)(s)->priv->x);		\  (s)->priv->x = g_value_dup_string (value)  switch (property_id) {  case PROP_ADDRESS: {    if (self->priv->nua)    {      nua_set_params(self->priv->nua,                     SIPTAG_FROM_STR(self->priv->address),                     TAG_NULL());      nua_get_params(self->priv->nua, TAG_ANY(), TAG_NULL());    }    else /*setting in constructor*/    {      self->priv->address = su_strdup(self->priv->home, g_value_get_string (value));    }    break;  }  case PROP_PASSWORD: {    STORE_PARAM(self, password);    break;  }  case PROP_CONTACT: {    STORE_PARAM(self, contact);    break;  }  case PROP_PROXY: {    STORE_PARAM(self, proxy);    if (self->priv->nua)    {      nua_set_params(self->priv->nua,                     NUTAG_PROXY(self->priv->proxy),                     TAG_NULL());    }    break;  }  case PROP_REGISTRAR: {    STORE_PARAM(self, registrar);    if (self->priv->nua)    {      nua_set_params(self->priv->nua,                     NUTAG_REGISTRAR(self->priv->registrar),                     TAG_NULL());    }    break;  }  case PROP_STUN_SERVER: {    STORE_PARAM(self, stun_server);    break;  } default:    /* We don't have any other property... */    G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);    break;  }}static voidnua_glib_get_property (GObject      *object,                        guint         property_id,                        GValue       *value,                        GParamSpec   *pspec){  NuaGlib *self = (NuaGlib *) object;  switch (property_id) {  case PROP_ADDRESS: {    g_value_set_string (value, self->priv->address);    break;  }  case PROP_PASSWORD: {    g_value_set_string (value, self->priv->password);    break;  }  case PROP_CONTACT: {    g_value_set_string (value, self->priv->contact);    break;  }  case PROP_PROXY: {    g_value_set_string (value, self->priv->proxy);    break;  }  case PROP_REGISTRAR: {    g_value_set_string (value, self->priv->registrar);    break;  }  case PROP_STUN_SERVER: {    g_value_set_string (value, self->priv->stun_server);    break;  }  default:    /* We don't have any other property... */    G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);    break;  }}static voidnua_glib_class_init (NuaGlibClass *nua_glib_class){  GObjectClass *gobject_class = G_OBJECT_CLASS(nua_glib_class);  GParamSpec *param_spec;   gobject_class->constructor = nua_glib_constructor;  gobject_class->dispose = nua_glib_dispose;  gobject_class->finalize = nua_glib_finalize;  gobject_class->set_property = nua_glib_set_property;  gobject_class->get_property = nua_glib_get_property;    param_spec = g_param_spec_string("address",                                   "NuaGlib construction property",                                   "The address-of-record for this UA (e.g. 'sip:first.surname@myprovider.com')",                                   "no-address-set", /*default value*/                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT);  g_object_class_install_property (gobject_class,                                   PROP_ADDRESS,                                   param_spec);  param_spec = g_param_spec_string("password",                                   "NuaGlib construction property",                                   "SIP account password",                                   NULL, /*default value*/                                   G_PARAM_READWRITE);  g_object_class_install_property (gobject_class,                                   PROP_PASSWORD,                                   param_spec);  param_spec = g_param_spec_string("contact",                                   "NuaGlib construction property",                                   "local bind interface (e.g. 'sip:0.0.0.0:*') [optional]",                                   NULL, /*default value*/                                   G_PARAM_READWRITE );  g_object_class_install_property (gobject_class,                                   PROP_CONTACT,                                   param_spec);  param_spec = g_param_spec_string("proxy",                                   "NuaGlib construction property",                                   "SIP outgoing proxy URI (e.g. 'sip:sipproxy.myprovider.com') [optional]",                                   NULL, /*default value*/                                   G_PARAM_READWRITE );  g_object_class_install_property (gobject_class,                                   PROP_PROXY,                                   param_spec);  param_spec = g_param_spec_string("registrar",                                   "NuaGlib construction property",                                   "SIP registrar URI (e.g. 'sip:sip.myprovider.com') [optional]",                                   NULL, /*default value*/                                   G_PARAM_READWRITE );  g_object_class_install_property (gobject_class,                                   PROP_REGISTRAR,                                   param_spec);  param_spec = g_param_spec_string("stun-server",                                   "NuaGlib construction property",                                   "STUN server address (FQDN or dotted-decimal) [optional]",                                   "", /*default value*/                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);  g_object_class_install_property (gobject_class,                                   PROP_STUN_SERVER,                                   param_spec);  /**   * NuaGlib::call-forked:   * @nua_glib: the object that received the signal   * @op: pointer to the operation representing the call that was forked   * @status: SIP status of fork (see SIP RFC)   * @phrase: Reason for fork   *   * Emitted when an outgoing call has been forked.   * This is when an INVITE request is answered with multiple 200 responses.   */  signals[NGSIG_CALL_FORKED] =   g_signal_new("call-forked",    G_OBJECT_CLASS_TYPE (nua_glib_class),    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,    0, NULL, NULL,    nua_glib_marshal_VOID__POINTER_INT_STRING,    G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING);  /**   * NuaGlib::incoming-invite:   * @nua_glib: the object that received the signal   * @op: pointer to the operation created to represent this call   * @display: the display name of the invite recipient   * @url: the url of the invite recipient   * @subject: the subject of the invite (can be NULL)   *   * Emitted when an call invite is received   * Should be answered with nua_glib_answer or nua_glib_decline   */  signals[NGSIG_INCOMING_INVITE] =   g_signal_new("incoming-invite",    G_OBJECT_CLASS_TYPE (nua_glib_class),    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,    0, NULL, NULL,    nua_glib_marshal_VOID__POINTER_STRING_STRING_STRING,    G_TYPE_NONE, 4, G_TYPE_POINTER , G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);  /**   * NuaGlib::incoming-reinvite:   * @nua_glib: the object that received the signal   * @op: pointer to the operation representing the existing call   *   * Emitted when an call invite is received for a call already in progress   * Usually represents   */  signals[NGSIG_INCOMING_REINVITE] =   g_signal_new("incoming-reinvite",    G_OBJECT_CLASS_TYPE (nua_glib_class),    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,    0, NULL, NULL,    g_cclosure_marshal_VOID__POINTER,    G_TYPE_NONE, 1, G_TYPE_POINTER);  /**   * NuaGlib::call-state-changed:   * @nua_glib: the object that received the signal   * @op: pointer to the operation representing the existing call   * @audio: #NuaGlibMediaActive describing audio availiablity   * @video: #NuaGlibMediaActive describing video availiablity   * @image: #NuaGlibMediaActive describing image availiablity   * @chat: #NuaGlibMediaActive describing chat availiablity   * @l_sdp: String containing any new local caps as SDP, can be NULL   * @r_sdp: String containing any new remote cap as SDP, can be NULL   *   * Emitted when call state changes.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -