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

📄 nua_glib.c

📁 sip协议栈
💻 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> */#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{  CALL_FORKED,  INCOMING_INVITE,  INCOMING_REINVITE,  CALL_STATE_CHANGED,  INCOMING_ACTIVE,  CALL_TERMINATED,  INCOMING_PRACK,  INCOMING_BYE,  INCOMING_CANCEL,  INCOMING_MESSAGE,  INCOMING_INFO,  INCOMING_REFER,  INCOMING_NOTIFY,  ERROR,  SHUTDOWN,  REGISTER_ANSWERED,  UNREGISTER_ANSWERED,  PUBLISH_ANSWERED,  INVITE_ANSWERED,  BYE_ANSWERED,  MESSAGE_ANSWERED,  INFO_ANSWERED,  REFER_ANSWERED,  SUBSCRIBE_ANSWERED,  UNSUBSCRIBE_ANSWERED,  NOTIFY_ANSWERED,  OPTIONS_ANSWERED,  MEDIA_ANSWERED,  GET_ANSWERED,  LAST_SIGNAL};static guint signals[LAST_SIGNAL] = {0};enum{  PROP_CONTACT = 1,  PROP_ADDRESS,  PROP_PROXY,  PROP_REGISTRAR,  PROP_AUTHINFO,  PROP_STUN,  PROP_SIP_BIND_ADDR,  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 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"),				 NUTAG_MEDIA_ENABLE(1),				 TAG_IF(self->priv->bind_addr,					NUTAG_URL(self->priv->bind_addr)),				 TAG_IF(self->priv->stun,					STUNTAG_SERVER(self->priv->stun)),				 TAG_IF(self->priv->contact,					NUTAG_URL(self->priv->contact)),				 /* NUTAG_MEDIA_ADDRESS(self->priv->media), */				 /* SOATAG_USER_SDP_STR(local_caps), */				 TAG_NULL());    if (self->priv->nua) {      int min_se = 0;      int s_e = 0;      if (getenv("MIN_SE")) min_se = atoi(getenv("MIN_SE"));      if (getenv("SESSION_EXPIRES")) s_e = atoi(getenv("SESSION_EXPIRES"));            /* XXX: fix getenvs */            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);  self->priv->authinfo = g_strdup("");}static voidnua_glib_dispose(GObject *obj){  NuaGlib *self = NUA_GLIB(obj);  if (self->priv->init)  {    g_free((gpointer)self->priv->contact);    g_free((gpointer)self->priv->authinfo);    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_CONTACT: {    STORE_PARAM(self, contact);    break;  }  case PROP_ADDRESS: {    if (self->priv->nua)    {      nua_set_params(self->priv->nua,                     SIPTAG_FROM_STR(g_value_get_string (value)),                     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_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_AUTHINFO: {    STORE_PARAM(self, authinfo);    break;  }  case PROP_STUN: {    STORE_PARAM(self, stun);    break;  }  case PROP_SIP_BIND_ADDR: {    STORE_PARAM(self, bind_addr);    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_CONTACT: {    g_value_set_string (value, self->priv->contact);    break;  }  case PROP_ADDRESS: {    g_value_set_string (value, self->priv->address);    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_AUTHINFO: {    g_value_set_string (value, self->priv->authinfo);    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("contact",                                   "NuaGlib construction property",                                   "The contact url for this UA",                                   NULL, /*default value*/                                   G_PARAM_READWRITE );  g_object_class_install_property (gobject_class,                                   PROP_CONTACT,                                   param_spec);  param_spec = g_param_spec_string("address",                                   "NuaGlib construction property",                                   "The address-of-contact for this UA",                                   "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("proxy",                                   "NuaGlib construction property",                                   "The SIP proxy to use",                                   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",                                   "The SIP registrar to use",                                   NULL, /*default value*/                                   G_PARAM_READWRITE );  g_object_class_install_property (gobject_class,                                   PROP_REGISTRAR,                                   param_spec);  param_spec = g_param_spec_string("authinfo",                                   "NuaGlib construction property",                                 "Authorization info of form:"                                 "basic digest scheme:\"realm\":user:password ",                                   NULL, /*default value*/                                   G_PARAM_READWRITE );  g_object_class_install_property (gobject_class,                                   PROP_AUTHINFO,                                   param_spec);  param_spec = g_param_spec_string("stun",                                   "NuaGlib construction property",                                   "STUN server address",                                   "", /*default value*/                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);  g_object_class_install_property (gobject_class,                                   PROP_STUN,                                   param_spec);  param_spec = g_param_spec_string("bind_address",                                   "NuaGlib construction property",                                   "Bind address (i.e. sip:[::]:*) for SIP stack",                                   "", /*default value*/                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);  g_object_class_install_property(gobject_class,				  PROP_SIP_BIND_ADDR,				  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[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[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[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

⌨️ 快捷键说明

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