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

📄 sip_basic.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
 * @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);int sip_call_id_d(su_home_t *home,		  sip_header_t *h,		  char *s, 		  int slen){  sip_call_id_t *i = h->sh_call_id;    i->i_id = s; /* XXX - why not sip_word_at_word_d(&s); */  i->i_hash = msg_hash_string(s);  return 0;}int sip_call_id_e(char b[], int bsiz, sip_header_t const *h, int flags){  int n = strlen(h->sh_call_id->i_id);  if (bsiz > n)    strcpy(b, h->sh_call_id->i_id);  return n;}/** Extra size of a sip_call_id_t object. */int sip_call_id_dup_xtra(sip_header_t const *h, int offset){  sip_call_id_t const *i = h->sh_call_id;  return offset + MSG_STRING_SIZE(i->i_id);}/** * Duplicate a sip_call_id object. * * The function sip_call_id_dup_one() duplicates (deep copies)  * a #sip_call_id 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 @c 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, int xtra){  sip_call_id_t *i = dst->sh_call_id;  sip_call_id_t const *o = src->sh_call_id;  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);  return b;}/**@ingroup sip_call_id * * Create a @b Call-ID header object.  * * The function sip_call_id_create() creates 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 * The function sip_call_id_create() returns a pointer to newly created @b * Call-ID header object when successful or NULL upon an error. */sip_call_id_t *sip_call_id_create(su_home_t *home, char const *domain){  sip_call_id_t *i;  int xtra = su_guid_strlen + 1 + (domain ? strlen(domain) + 1 : 0);  i = sip_header_alloc(home, sip_call_id_class, xtra)->sh_call_id;    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 * *//**@ingroup sip_cseq * @typedef typedef struct sip_cseq_s sip_cseq_t; * * The structure #sip_cseq_t contains representation of SIP @b 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_unknown_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);int sip_cseq_d(su_home_t *home,	       sip_header_t *h,	       char *s,	       int slen){  sip_cseq_t *cs = h->sh_cseq;  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;}int sip_cseq_e(char b[], int bsiz, sip_header_t const *h, int flags){  assert(sip_is_cseq(h));  return snprintf(b, bsiz, 		  "%u %s", 		  h->sh_cseq->cs_seq,		  h->sh_cseq->cs_method_name);}int sip_cseq_dup_xtra(sip_header_t const *h, int offset){  sip_cseq_t const *cs = h->sh_cseq;  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, int xtra){  sip_cseq_t *cs = dst->sh_cseq;  sip_cseq_t const *o = src->sh_cseq;  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);  return b;}/**@ingroup sip_cseq  * *燙reate a @b CSeq header object.  * * The function sip_cseq_create() creates 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 * The function sip_cseq_create() returns a pointer to newly created @b 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_header_alloc(home, sip_cseq_class, xtra)->sh_cseq;    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 [S10.14] 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. *//**@ingroup sip_contact * @typedef typedef struct sip_contact_s sip_contact_t; * * The structure #sip_contact_t contains representation of SIP @b 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 * *   msg_param_t         m_q;           // Priority *   msg_param_t         m_expires;     // Expiration time  * } sip_contact_t; * @endcode *  * @note: The field @ref sip_contact_s::m_comment m_comment is deprecated. */static msg_xtra_f sip_contact_dup_xtra;static msg_dup_f sip_contact_dup_one;static msg_update_f sip_contact_update;msg_hclass_t sip_contact_class[] = SIP_HEADER_CLASS(contact, "Contact", "m", m_params, append, contact);int sip_contact_d(su_home_t *home,		  sip_header_t *h,		  char *s,		  int slen){  sip_header_t **hh = &h->sh_succ, *h0 = h;  sip_contact_t *m = h->sh_contact;  assert(h);  for (;*s;) {    /* Ignore empty entries (comma-whitespace) */    if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; }    if (!h) {      /* If there are multiple contacts on one line        * we must allocate next header structure */      if (!(h = sip_header_alloc(home, h0->sh_class, 0)))	return -1;      *hh = h; h->sh_prev = hh; hh = &h->sh_succ;       m = m->m_next = h->sh_contact;    }    if (sip_name_addr_d(home, &s, &m->m_display, m->m_url,			&m->m_params, &m->m_comment) == -1)      return -1;    if (*s != '\0' && *s != ',')      return -1;    if (m->m_params)       msg_header_update_params(m->m_common, 0);    h = NULL;  }  if (h)		/* Empty list is an error */    return -1;  return 0;}int sip_contact_e(char b[], int bsiz, sip_header_t const *h, int flags){  sip_contact_t const *m = h->sh_contact;  int always_lt_gt = MSG_IS_CANONIC(flags) && m->m_url->url_type != url_any;  assert(sip_is_contact(h));  return sip_name_addr_e(b, bsiz, flags,			 m->m_display, always_lt_gt, m->m_url, 			 m->m_params,			 NULL /* m->m_comment */);}int sip_contact_dup_xtra(sip_header_t const *h, int offset){  int rv = offset;  sip_contact_t const *m = h->sh_contact;  MSG_PARAMS_SIZE(rv, m->m_params);  rv += MSG_STRING_SIZE(m->m_display);  rv += url_xtra(m->m_url);  rv += MSG_STRING_SIZE(m->m_comment);  return rv;}char *sip_contact_dup_one(sip_header_t *dst, sip_header_t const *src,			  char *b, int xtra){  char *end = b + xtra;  sip_contact_t *m = dst->sh_contact;  sip_contact_t const *o = src->sh_contact;  b = msg_params_dup(&m->m_params, o->m_params, b, xtra);  MSG_STRING_DUP(b, m->m_display, o->m_display);  URL_DUP(b, end, m->m_url, o->m_url);  MSG_STRING_DUP(b, m->m_comment, o->m_comment);  assert(b <= end);  return b;}/** Update parameter in sip_contact_t */static int sip_contact_update(msg_common_t *h, 			      char const *name, int namelen,			      char const *value){  sip_contact_t *m = (sip_contact_t *)h;  if (name == NULL) {    m->m_q = NULL;    m->m_expires = NULL;  }  else if (namelen == 1 && strncasecmp(name, "q", 1) == 0) {    /* XXX - check for invalid value? */    m->m_q = value;  }  else if (namelen == strlen("expires") && 	   !strncasecmp(name, "expires", namelen)) {    m->m_expires = value;  }  return 0;}/**@ingroup sip_contact  * * Add a parameter to a @b Contact header object * * The function sip_contact_add_param() adds a parameter to a contact * object. It does not copy the contents of the string @c param.  * * @note This function @b does @b not duplicate @p param. * * @param home   memory home * @param m      sip_contact_t object * @param param  parameter string * * @return 0 when successful, and -1 upon an error. * * @deprecated Use msg_header_replace_param() directly. */int sip_contact_add_param(su_home_t *home,			  sip_contact_t *m,			  char const *param){  return msg_header_replace_param(home, m->m_common, param);}/* ====================================================================== *//**@SIP_HEADER sip_content_length Content-Length Header * * The Content-Length header indicates the size of the message-body in * decimal number of octets.  Its syntax is defined in [S10.18] as * follows: * * @code *    Content-Length  =  ( "Content-Length" / "l" ) HCOLON 1*DIGIT

⌨️ 快捷键说明

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