Changeset 3196 for pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
- Timestamp:
- Jun 3, 2010 10:41:32 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
r3190 r3196 47 47 static const pj_str_t HCONTACT = { "Contact", 7 }; 48 48 49 49 50 PJ_DEF(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m) 50 51 { … … 90 91 91 92 pj_list_init(&dlg->inv_hdr); 93 pj_list_init(&dlg->rem_cap_hdr); 92 94 93 95 status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_); … … 523 525 dlg->remote.tag_hval = pj_hash_calc(0, dlg->remote.info->tag.ptr, 524 526 dlg->remote.info->tag.slen); 527 528 /* Update remote capabilities info */ 529 pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, PJ_TRUE); 525 530 526 531 /* Register this dialog to user agent. */ … … 1775 1780 pjsip_contact_hdr *contact; 1776 1781 1782 /* Update remote capability info, when To tags in the dialog remote 1783 * info and the incoming response are different, e.g: first response 1784 * with To-tag or forking, apply strict update. 1785 */ 1786 pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, 1787 pj_strcmp(&dlg->remote.info->tag, 1788 &rdata->msg_info.to->tag)); 1789 1777 1790 /* Update To tag. */ 1778 1791 pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag); 1779 1792 /* No need to update remote's tag_hval since its never used. */ 1780 1781 1793 1782 1794 /* RFC 3271 Section 12.1.2: … … 1860 1872 dlg_update_routeset(dlg, rdata); 1861 1873 } 1862 1863 1874 1864 1875 /* Pass to dialog usages. */ … … 1963 1974 } 1964 1975 1976 1977 /* 1978 * Check if the specified capability is supported by remote. 1979 */ 1980 PJ_DEF(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap( 1981 pjsip_dialog *dlg, 1982 int htype, 1983 const pj_str_t *hname, 1984 const pj_str_t *token) 1985 { 1986 const pjsip_generic_array_hdr *hdr; 1987 pjsip_dialog_cap_status cap_status = PJSIP_DIALOG_CAP_UNSUPPORTED; 1988 unsigned i; 1989 1990 PJ_ASSERT_RETURN(dlg && token, PJ_FALSE); 1991 1992 pjsip_dlg_inc_lock(dlg); 1993 1994 hdr = (const pjsip_generic_array_hdr*) 1995 pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname); 1996 if (!hdr) { 1997 cap_status = PJSIP_DIALOG_CAP_UNKNOWN; 1998 } else { 1999 for (i=0; i<hdr->count; ++i) { 2000 if (!pj_stricmp(&hdr->values[i], token)) { 2001 cap_status = PJSIP_DIALOG_CAP_SUPPORTED; 2002 break; 2003 } 2004 } 2005 } 2006 2007 pjsip_dlg_dec_lock(dlg); 2008 2009 return cap_status; 2010 } 2011 2012 2013 /* 2014 * Update remote capability of ACCEPT, ALLOW, and SUPPORTED from 2015 * the received message. 2016 */ 2017 PJ_DEF(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg, 2018 const pjsip_msg *msg, 2019 pj_bool_t strict) 2020 { 2021 pjsip_hdr_e htypes[] = 2022 { PJSIP_H_ACCEPT, PJSIP_H_ALLOW, PJSIP_H_SUPPORTED }; 2023 unsigned i; 2024 2025 PJ_ASSERT_RETURN(dlg && msg, PJ_EINVAL); 2026 2027 pjsip_dlg_inc_lock(dlg); 2028 2029 /* Retrieve all specified capability header types */ 2030 for (i = 0; i < PJ_ARRAY_SIZE(htypes); ++i) { 2031 const pjsip_generic_array_hdr *hdr; 2032 pj_status_t status; 2033 2034 /* Find this capability type in the message */ 2035 hdr = (const pjsip_generic_array_hdr*) 2036 pjsip_msg_find_hdr(msg, htypes[i], NULL); 2037 if (!hdr) { 2038 /* Not found. 2039 * If strict update is specified, remote this capability type 2040 * from the capability list. 2041 */ 2042 if (strict) 2043 pjsip_dlg_remove_remote_cap_hdr(dlg, htypes[i], NULL); 2044 } else { 2045 /* Found, a capability type may be specified in multiple headers, 2046 * so combine all the capability tags/values into a temporary 2047 * header. 2048 */ 2049 pjsip_generic_array_hdr tmp_hdr; 2050 2051 /* Init temporary header */ 2052 pjsip_generic_array_hdr_init(dlg->pool, &tmp_hdr, NULL); 2053 pj_memcpy(&tmp_hdr, hdr, sizeof(pjsip_hdr)); 2054 2055 while (hdr) { 2056 unsigned j; 2057 2058 /* Append the header content to temporary header */ 2059 for(j=0; j<hdr->count && 2060 tmp_hdr.count<PJSIP_GENERIC_ARRAY_MAX_COUNT; ++j) 2061 { 2062 tmp_hdr.values[tmp_hdr.count++] = hdr->values[j]; 2063 } 2064 2065 /* Get the next header for this capability */ 2066 hdr = (const pjsip_generic_array_hdr*) 2067 pjsip_msg_find_hdr(msg, htypes[i], hdr->next); 2068 } 2069 2070 /* Save this capability */ 2071 status = pjsip_dlg_set_remote_cap_hdr(dlg, &tmp_hdr); 2072 if (status != PJ_SUCCESS) { 2073 pjsip_dlg_dec_lock(dlg); 2074 return status; 2075 } 2076 } 2077 } 2078 2079 pjsip_dlg_dec_lock(dlg); 2080 2081 return PJ_SUCCESS; 2082 } 2083 2084 2085 /* 2086 * Get the value of the specified capability header field of remote. 2087 */ 2088 PJ_DEF(const pjsip_hdr*) pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg, 2089 int htype, 2090 const pj_str_t *hname) 2091 { 2092 pjsip_hdr *hdr; 2093 2094 /* Check arguments. */ 2095 PJ_ASSERT_RETURN(dlg, NULL); 2096 PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen), 2097 NULL); 2098 2099 pjsip_dlg_inc_lock(dlg); 2100 2101 hdr = dlg->rem_cap_hdr.next; 2102 while (hdr != &dlg->rem_cap_hdr) { 2103 if ((htype != PJSIP_H_OTHER && htype == hdr->type) || 2104 (htype == PJSIP_H_OTHER && pj_stricmp(&hdr->name, hname) == 0)) 2105 { 2106 pjsip_dlg_dec_lock(dlg); 2107 return hdr; 2108 } 2109 hdr = hdr->next; 2110 } 2111 2112 pjsip_dlg_dec_lock(dlg); 2113 2114 return NULL; 2115 } 2116 2117 2118 /* 2119 * Set remote capability header from a SIP header containing array 2120 * of capability tags/values. 2121 */ 2122 PJ_DEF(pj_status_t) pjsip_dlg_set_remote_cap_hdr( 2123 pjsip_dialog *dlg, 2124 const pjsip_generic_array_hdr *cap_hdr) 2125 { 2126 pjsip_generic_array_hdr *hdr; 2127 2128 /* Check arguments. */ 2129 PJ_ASSERT_RETURN(dlg && cap_hdr, PJ_EINVAL); 2130 2131 pjsip_dlg_inc_lock(dlg); 2132 2133 /* Find the header. */ 2134 hdr = (pjsip_generic_array_hdr*) 2135 pjsip_dlg_get_remote_cap_hdr(dlg, cap_hdr->type, &cap_hdr->name); 2136 2137 /* Quick compare if the capability is up to date */ 2138 if (hdr && hdr->count == cap_hdr->count) { 2139 unsigned i; 2140 pj_bool_t uptodate = PJ_TRUE; 2141 2142 for (i=0; i<hdr->count; ++i) { 2143 if (pj_stricmp(&hdr->values[i], &cap_hdr->values[i])) 2144 uptodate = PJ_FALSE; 2145 } 2146 2147 /* Capability is up to date, just return PJ_SUCCESS */ 2148 if (uptodate) { 2149 pjsip_dlg_dec_lock(dlg); 2150 return PJ_SUCCESS; 2151 } 2152 } 2153 2154 /* Remove existing capability header if any */ 2155 if (hdr) 2156 pj_list_erase(hdr); 2157 2158 /* Add the new capability header */ 2159 hdr = (pjsip_generic_array_hdr*) pjsip_hdr_clone(dlg->pool, cap_hdr); 2160 hdr->type = cap_hdr->type; 2161 pj_strdup(dlg->pool, &hdr->name, &cap_hdr->name); 2162 pj_list_push_back(&dlg->rem_cap_hdr, hdr); 2163 2164 pjsip_dlg_dec_lock(dlg); 2165 2166 /* Done. */ 2167 return PJ_SUCCESS; 2168 } 2169 2170 /* 2171 * Remove a remote capability header. 2172 */ 2173 PJ_DEF(pj_status_t) pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg, 2174 int htype, 2175 const pj_str_t *hname) 2176 { 2177 pjsip_generic_array_hdr *hdr; 2178 2179 /* Check arguments. */ 2180 PJ_ASSERT_RETURN(dlg, PJ_EINVAL); 2181 PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen), 2182 PJ_EINVAL); 2183 2184 pjsip_dlg_inc_lock(dlg); 2185 2186 hdr = (pjsip_generic_array_hdr*) 2187 pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname); 2188 if (!hdr) { 2189 pjsip_dlg_dec_lock(dlg); 2190 return PJ_ENOTFOUND; 2191 } 2192 2193 pj_list_erase(hdr); 2194 2195 pjsip_dlg_dec_lock(dlg); 2196 2197 return PJ_SUCCESS; 2198 }
Note: See TracChangeset
for help on using the changeset viewer.