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

📄 sip_basic.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 5 页
字号:
  return sip_name_addr_dup(&a->a_display, o->a_display,			   a->a_url, o->a_url,			   &a->a_params, o->a_params,			   b, xtra);}/** Update parameters in sip_addr_t object */static int sip_addr_update(msg_common_t *h,			   char const *name, isize_t namelen,			   char const *value){  sip_addr_t *a = (sip_addr_t *)h;  if (name == NULL) {    a->a_tag = NULL;  }  else if (namelen == strlen("tag") && !strncasecmp(name, "tag", namelen)) {    a->a_tag = value;  }  return 0;}/** Create an address header object from URL */static sip_addr_t *sip_addr_make_url(su_home_t *home, msg_hclass_t *hc, url_string_t const *us){  size_t n;  sip_header_t *h;  n = url_xtra(us->us_url);  h = sip_header_alloc(home, hc, n);      if (h) {    sip_addr_t *a = (sip_to_t *)h;    char *s2 = sip_header_data(h);    if ((size_t)url_dup(s2, n, a->a_url, us->us_url) == n)      return a;    su_free(home, h);  }  return NULL;}/** Add a tag to address structure. */staticint sip_addr_tag(su_home_t *home, sip_addr_t *a, char const *tag){  if (a && tag) {    msg_param_t value = strchr(tag, '=');    if (value)      value = strchr(value, '=') + 1;    else      value = tag;    if (a->a_tag) {      if (strcasecmp(a->a_tag, value) == 0)	return 0;      else	return -1;    }    if (tag == value)      tag = su_sprintf(home, "tag=%s", tag);    else      tag = su_strdup(home, tag);    if (tag)      if (msg_header_replace_param(home, a->a_common, tag) >= 0)	return 0;  }  return -1;}/* ====================================================================== *//**@SIP_HEADER sip_call_id Call-ID Header * * The @b Call-ID header uniquely identifies a particular invitation or all * registrations of a particular client. It is defined in @RFC3261 as * follows: *  * @code *    Call-ID  =  ( "Call-ID" / "i" ) HCOLON callid *    callid   =  word [ "@" word ] *    word        =  1*(alphanum / "-" / "." / "!" / "%" / "*" / *                   "_" / "+" / "`" / "'" / "~" / "(" / ")" / "<" / ">" / *                   ":" / "\" / DQUOTE / "/" / "[" / "]" / "?" / "{" / "}" ) * @endcode * * The parsed Call-ID Header is stored in #sip_call_id_t structure. *//**@ingroup sip_call_id * @typedef typedef struct sip_call_id_s sip_call_id_t; * * The structure #sip_call_id_t contains representation of SIP @CallID * header. * * The #sip_call_id_t is defined as follows: * @code * typedef struct sip_call_id_s { *   sip_common_t   i_common[1];        // Common fragment info *   sip_call_id_t *i_next;             // Link to next (dummy) *   char const    *i_id;               // ID value *   uint32_t       i_hash;             // Hash value (always nonzero) * } sip_call_id_t; * @endcode */static msg_xtra_f sip_call_id_dup_xtra;static msg_dup_f sip_call_id_dup_one;#define sip_call_id_update NULLmsg_hclass_t sip_call_id_class[] = SIP_HEADER_CLASS(call_id, "Call-ID", "i", i_common, single, call_id);issize_t sip_call_id_d(su_home_t *home,		       sip_header_t *h,		       char *s, 		       isize_t slen){  sip_call_id_t *i = (sip_call_id_t *)h;    i->i_id = s; /* XXX - why not sip_word_at_word_d(&s); */  i->i_hash = msg_hash_string(s);  return 0;}issize_t sip_call_id_e(char b[], isize_t bsiz, sip_header_t const *h, int flags){  sip_call_id_t const *i = (sip_call_id_t *)h;  size_t n = strlen(i->i_id);  if (bsiz > n)    strcpy(b, i->i_id);  return (issize_t)n;}/** Extra size of a #sip_call_id_t object. */isize_t sip_call_id_dup_xtra(sip_header_t const *h, isize_t offset){  sip_call_id_t const *i = (sip_call_id_t *)h;  return offset + MSG_STRING_SIZE(i->i_id);}/**Duplicate a sip_call_id object. * * Duplicate (copy deeply) a single #sip_call_id_t header object. * * @param dst   pointer to newly allocated header object * @param src   pointer to a header object to be duplicated * @param b     memory buffer used to copy external references * @param xtra  number bytes in buffer @a b * * @return Pointer to the new copy of #sip_call_id_t object, or @c NULL * upon an error. */char *sip_call_id_dup_one(sip_header_t *dst, sip_header_t const *src,			  char *b, isize_t xtra){  sip_call_id_t *i = (sip_call_id_t *)dst;  sip_call_id_t const *o = (sip_call_id_t *)src;  char *end = b + xtra;  MSG_STRING_DUP(b, i->i_id, o->i_id);  if (!(i->i_hash = o->i_hash))    i->i_hash = msg_hash_string(i->i_id);  assert(b <= end); (void)end;  return b;}/**@ingroup sip_call_id * * Create a @CallID header object.  * * Create a Call-ID header object with a new unique value. It uses * su_guid_generate() function to generate the value. If the local host name * @a domain is specified, it is prepended to the generated value instead of * local MAC address. * @param home        memory home * @param domain      local domain name * * @return A pointer to newly created @CallID header object when * successful or NULL upon an error. * * @sa su_guid_generate(), su_guid_sprintf() */sip_call_id_t *sip_call_id_create(su_home_t *home, char const *domain){  sip_call_id_t *i;  size_t xtra = su_guid_strlen + 1 + (domain ? strlen(domain) + 1 : 0);  i = (sip_call_id_t *)sip_header_alloc(home, sip_call_id_class, xtra);    if (i) {    char *b;    su_guid_t guid[1];    i->i_id = b = (char *)(i + 1);    su_guid_generate(guid);    /*     * Guid looks like "NNNNNNNN-NNNN-NNNN-NNNN-XXXXXXXXXXXX"     * where NNNNNNNN-NNNN-NNNN-NNNN is timestamp and XX is MAC address     * (but we use usually random ID for MAC because we do not have     *  guid generator available for all processes within node)     */    su_guid_sprintf(b, su_guid_strlen + 1, guid);    /* If we have a domain name don't include MAC address at the end of guid */    if (domain) {      b[8 + 5 + 5 + 5] = '@';      strcpy(b + 8 + 5 + 5 + 5 + 1, domain);    }    i->i_hash = msg_hash_string(i->i_id);  }  return i;}/* ====================================================================== *//**@SIP_HEADER sip_cseq CSeq Header  * * The CSeq header (command sequence) uniquely identifies transactions * within a dialog.  It is defined in @RFC3261 as follows: *  * @code *    CSeq              =  "CSeq" HCOLON 1*DIGIT LWS Method *    Method            =  INVITEm / ACKm / OPTIONSm / BYEm *                         / CANCELm / REGISTERm *                         / extension-method *    extension-method  =  token * @endcode * * The parsed CSeq header is stored in #sip_cseq_t structure. *//**@ingroup sip_cseq * @typedef typedef struct sip_cseq_s sip_cseq_t; * * The structure #sip_cseq_t contains representation of SIP @CSeq header. * * The #sip_cseq_t is defined as follows: * @code * typedef struct sip_cseq_s { *   sip_common_t   cs_common[1];       // Common fragment info *   sip_error_t   *cs_next;            // Link to next (dummy) *   uint32_t       cs_seq;             // Sequence number *   sip_method_t   cs_method;          // Method enum *   char const    *cs_method_name;     // Method name * } sip_cseq_t; * @endcode */static msg_xtra_f sip_cseq_dup_xtra;static msg_dup_f sip_cseq_dup_one;#define sip_cseq_update NULLmsg_hclass_t sip_cseq_class[] = SIP_HEADER_CLASS(cseq, "CSeq", "", cs_common, single, cseq);issize_t sip_cseq_d(su_home_t *home,		    sip_header_t *h,		    char *s,		    isize_t slen){  sip_cseq_t *cs = (sip_cseq_t *)h;  if (msg_uint32_d(&s, &cs->cs_seq) < 0)    return -1;  if (*s) {    if ((cs->cs_method = sip_method_d(&s, &cs->cs_method_name)) >= 0)      return 0;  }  return -1;}issize_t sip_cseq_e(char b[], isize_t bsiz, sip_header_t const *h, int flags){  sip_cseq_t const *cs = (sip_cseq_t *)h;  assert(sip_is_cseq(h));  return snprintf(b, bsiz, "%u %s", cs->cs_seq, cs->cs_method_name);}isize_t sip_cseq_dup_xtra(sip_header_t const *h, isize_t offset){  sip_cseq_t const *cs = (sip_cseq_t *)h;  if (!cs->cs_method)    return offset + MSG_STRING_SIZE(cs->cs_method_name);  else    return offset;}char *sip_cseq_dup_one(sip_header_t *dst, sip_header_t const *src,		       char *b, isize_t xtra){  sip_cseq_t *cs = (sip_cseq_t *)dst;  sip_cseq_t const *o = (sip_cseq_t *)src;  char *end = b + xtra;  if (!(cs->cs_method = o->cs_method))    MSG_STRING_DUP(b, cs->cs_method_name, o->cs_method_name);  else    cs->cs_method_name = o->cs_method_name;  cs->cs_seq = o->cs_seq;  assert(b <= end); (void)end;  return b;}/**@ingroup sip_cseq  * *燙reate a @CSeq header object.  * * Create a @CSeq header object with the * sequence number @a seq, method enum @a method and method name @a * method_name.  The memory for the header object is allocated from the * memory home @a home. * * @param home        memory home * @param seq         sequence number * @param method      method enum * @param method_name method name (required if method is not well-known) * * @par Example * The following code fragment creates a cseq object for OPTIONS request: * @code *   sip_cseq_t *cseq; *   cseq = sip_cseq_create(home, agent->seq++, SIP_METHOD_OPTIONS); * @endcode * * @return * A pointer to newly created @CSeq * header object when successful or NULL upon an error. */sip_cseq_t *sip_cseq_create(su_home_t *home,			    uint32_t seq,			    unsigned method,			    char const *method_name){  size_t xtra;  sip_cseq_t *cs;  if (method)    method_name = sip_method_name(method, method_name);  if (method_name == NULL)    return NULL;  xtra = (method ? 0 : (strlen(method_name) + 1));  cs = (sip_cseq_t *)sip_header_alloc(home, sip_cseq_class, xtra);    if (cs) {    cs->cs_seq = seq;    cs->cs_method = method;    if (!method)      method_name = strcpy((char *)(cs + 1), method_name);    cs->cs_method_name = method_name;  }  return cs;}/* ====================================================================== *//**@SIP_HEADER sip_contact Contact Header * * The Contact header contain a list of URLs used to redirect future * requests.  Its syntax is defined in @RFC3261 as follows: *  * @code *    Contact            =  ("Contact" / "m" ) HCOLON *                          ( STAR / (contact-param *(COMMA contact-param))) *    contact-param      =  (name-addr / addr-spec) *(SEMI contact-params) *    name-addr          =  [ display-name ] LAQUOT addr-spec RAQUOT *    addr-spec          =  SIP-URI / SIPS-URI / absoluteURI *    display-name       =  *(token LWS)/ quoted-string *    contact-params     =  c-p-q / c-p-expires *                          / contact-extension *    c-p-q              =  "q" EQUAL qvalue *    c-p-expires        =  "expires" EQUAL delta-seconds *    contact-extension  =  generic-param *    delta-seconds      =  1*DIGIT * @endcode * * @note * The @RFC2543 syntax allowed <comment>. We accept it, but don't encode it. * * Each parsed Contact header field is stored in #sip_contact_t structure. *//**@ingroup sip_contact * @typedef typedef struct sip_contact_s sip_contact_t; * * The structure #sip_contact_t contains representation of SIP @Contact * header. * * The #sip_contact_t is defined as follows: * @code * typedef struct sip_contact_s { *   sip_common_t        m_common[1];   // Common fragment info *   sip_contact_t      *m_next;        // Link to next *   char const         *m_display;     // Display name *   url_t               m_url[1];      // SIP URL *   msg_param_t const  *m_params;      // List of contact-params *   char const         *m_comment;     // Comment * *   char const         *m_q;           // Priority *   char const         *m_expires;     // Expiration time  * } sip_contact_t; * @endcode *  * @note The <comment> field @ref sip_contact_s::m_comment "m_comment" is * deprecated: it is parsed but not included in encoding. */static msg_xtra_f sip_contact_dup_xtra;static msg_dup_f sip_contact_dup_one;static msg_update_f sip_contact_update;/** @showinitializer */msg_hclass_t sip_contact_class[] =  /*   * Cut through the fog of macros   * SIP_HEADER_CLASS(contact, "Contact", "m", m_params, append, contact);   * and show here how the msg_hclass_t is initialized   */  {{    /* hc_hash: */     sip_contact_hash,    /* hc_parse: */    sip_contact_d,    /* hc_print: */    sip_contact_e,    /* hc_dxtra: */    sip_contact_dup_xtra,    /* hc_dup_one: */  sip_contact_dup_one,    /* hc_update: */   sip_contact_update,    /* hc_name: */     "Contact",    /* hc_len: */      sizeof("Contact") - 1,    /* hc_short: */    "m",    /* hc_size: */     MSG_ALIGN(sizeof(sip_contact_t), sizeof(void*)),    /* hc_params: */   offsetof(sip_contact_t, m_params),    /* hc_kind:	*/     msg_kind_append,    /* hc_critical: */ 0   }};issize_t sip_contact_d(su_home_t *home,

⌨️ 快捷键说明

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