Changeset 685 for pjproject/trunk/pjsip/src/pjsip-simple/publishc.c
- Timestamp:
- Aug 15, 2006 8:26:34 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-simple/publishc.c
r683 r685 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 #include <pjsip-ua/sip_regc.h> 19 #include <pjsip-simple/publish.h> 20 #include <pjsip/sip_auth.h> 20 21 #include <pjsip/sip_endpoint.h> 21 #include <pjsip/sip_parser.h> 22 #include <pjsip/sip_module.h> 22 #include <pjsip/sip_errno.h> 23 #include <pjsip/sip_event.h> 24 #include <pjsip/sip_msg.h> 23 25 #include <pjsip/sip_transaction.h> 24 #include <pjsip/sip_ event.h>26 #include <pjsip/sip_uri.h> 25 27 #include <pjsip/sip_util.h> 26 #include <pjsip/sip_auth_msg.h>27 #include <pjsip/sip_errno.h>28 28 #include <pj/assert.h> 29 29 #include <pj/guid.h> 30 #include <pj/log.h> 30 31 #include <pj/os.h> 31 32 #include <pj/pool.h> 32 #include <pj/log.h>33 33 #include <pj/rand.h> 34 34 #include <pj/string.h> 35 #include <pj/timer.h> 35 36 36 37 37 38 #define REFRESH_TIMER 1 38 39 #define DELAY_BEFORE_REFRESH 5 39 #define THIS_FILE "sip_regc.c" 40 #define THIS_FILE "publishc.c" 41 42 43 const pjsip_method pjsip_publish_method = 44 { 45 PJSIP_OTHER_METHOD, 46 { "PUBLISH", 7 } 47 }; 48 40 49 41 50 /** 42 * SIP client registration structure.51 * SIP client publication structure. 43 52 */ 44 struct pjsip_ regc53 struct pjsip_publishc 45 54 { 46 55 pj_pool_t *pool; … … 50 59 51 60 void *token; 52 pjsip_regc_cb *cb; 53 54 pj_str_t str_srv_url; 55 pjsip_uri *srv_url; 61 pjsip_publishc_cb *cb; 62 63 pj_str_t event; 64 pj_str_t str_target_uri; 65 pjsip_uri *target_uri; 56 66 pjsip_cid_hdr *cid_hdr; 57 67 pjsip_cseq_hdr *cseq_hdr; … … 59 69 pjsip_from_hdr *from_hdr; 60 70 pjsip_to_hdr *to_hdr; 61 char *contact_buf; 62 pjsip_generic_string_hdr *contact_hdr; 71 pj_str_t etag; 63 72 pjsip_expires_hdr *expires_hdr; 64 pjsip_contact_hdr *unreg_contact_hdr;65 pjsip_expires_hdr *unreg_expires_hdr;66 73 pj_uint32_t expires; 67 74 pjsip_route_hdr route_set; … … 70 77 pjsip_auth_clt_sess auth_sess; 71 78 72 /* Auto refresh registration. */73 pj_bool_t auto_re g;74 pj_time_val last_re g;75 pj_time_val next_re g;79 /* Auto refresh publication. */ 80 pj_bool_t auto_refresh; 81 pj_time_val last_refresh; 82 pj_time_val next_refresh; 76 83 pj_timer_entry timer; 77 84 }; … … 79 86 80 87 81 PJ_DEF(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token, 82 pjsip_regc_cb *cb, 83 pjsip_regc **p_regc) 88 /* 89 * Initialize client publication module. 90 */ 91 PJ_DEF(pj_status_t) pjsip_publishc_init_module(pjsip_endpoint *endpt) 92 { 93 return pjsip_endpt_add_capability( endpt, NULL, PJSIP_H_ALLOW, NULL, 94 1, &pjsip_publish_method.name); 95 } 96 97 98 PJ_DEF(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, 99 unsigned options, 100 void *token, 101 pjsip_publishc_cb *cb, 102 pjsip_publishc **p_pubc) 84 103 { 85 104 pj_pool_t *pool; 86 pjsip_ regc *regc;105 pjsip_publishc *pubc; 87 106 pj_status_t status; 88 107 89 108 /* Verify arguments. */ 90 PJ_ASSERT_RETURN(endpt && cb && p_regc, PJ_EINVAL); 91 92 pool = pjsip_endpt_create_pool(endpt, "regc%p", 1024, 1024); 109 PJ_ASSERT_RETURN(endpt && cb && p_pubc, PJ_EINVAL); 110 PJ_ASSERT_RETURN(options == 0, PJ_EINVAL); 111 112 PJ_UNUSED_ARG(options); 113 114 pool = pjsip_endpt_create_pool(endpt, "pubc%p", 1024, 1024); 93 115 PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); 94 116 95 regc = pj_pool_zalloc(pool, sizeof(struct pjsip_regc)); 96 97 regc->pool = pool; 98 regc->endpt = endpt; 99 regc->token = token; 100 regc->cb = cb; 101 regc->contact_buf = pj_pool_alloc(pool, PJSIP_REGC_CONTACT_BUF_SIZE); 102 regc->expires = PJSIP_REGC_EXPIRATION_NOT_SPECIFIED; 103 104 status = pjsip_auth_clt_init(®c->auth_sess, endpt, regc->pool, 0); 117 pubc = pj_pool_zalloc(pool, sizeof(struct pjsip_publishc)); 118 119 pubc->pool = pool; 120 pubc->endpt = endpt; 121 pubc->token = token; 122 pubc->cb = cb; 123 pubc->expires = PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED; 124 125 status = pjsip_auth_clt_init(&pubc->auth_sess, endpt, pubc->pool, 0); 105 126 if (status != PJ_SUCCESS) 106 127 return status; 107 128 108 pj_list_init(& regc->route_set);129 pj_list_init(&pubc->route_set); 109 130 110 131 /* Done */ 111 *p_ regc = regc;112 return PJ_SUCCESS; 113 } 114 115 116 PJ_DEF(pj_status_t) pjsip_ regc_destroy(pjsip_regc *regc)117 { 118 PJ_ASSERT_RETURN( regc, PJ_EINVAL);119 120 if ( regc->pending_tsx) {121 regc->_delete_flag = 1;122 regc->cb = NULL;132 *p_pubc = pubc; 133 return PJ_SUCCESS; 134 } 135 136 137 PJ_DEF(pj_status_t) pjsip_publishc_destroy(pjsip_publishc *pubc) 138 { 139 PJ_ASSERT_RETURN(pubc, PJ_EINVAL); 140 141 if (pubc->pending_tsx) { 142 pubc->_delete_flag = 1; 143 pubc->cb = NULL; 123 144 } else { 124 pjsip_endpt_release_pool(regc->endpt, regc->pool); 125 } 126 127 return PJ_SUCCESS; 128 } 129 130 131 PJ_DEF(pj_status_t) pjsip_regc_get_info( pjsip_regc *regc, 132 pjsip_regc_info *info ) 133 { 134 PJ_ASSERT_RETURN(regc && info, PJ_EINVAL); 135 136 info->server_uri = regc->str_srv_url; 137 info->client_uri = regc->from_uri; 138 info->is_busy = (regc->pending_tsx != 0); 139 info->auto_reg = regc->auto_reg; 140 info->interval = regc->expires; 141 142 if (regc->pending_tsx) 143 info->next_reg = 0; 144 else if (regc->auto_reg == 0) 145 info->next_reg = 0; 146 else if (regc->expires < 0) 147 info->next_reg = regc->expires; 148 else { 149 pj_time_val now, next_reg; 150 151 next_reg = regc->next_reg; 152 pj_gettimeofday(&now); 153 PJ_TIME_VAL_SUB(next_reg, now); 154 info->next_reg = next_reg.sec; 155 } 156 157 return PJ_SUCCESS; 158 } 159 160 161 PJ_DEF(pj_pool_t*) pjsip_regc_get_pool(pjsip_regc *regc) 162 { 163 return regc->pool; 164 } 165 166 static void set_expires( pjsip_regc *regc, pj_uint32_t expires) 167 { 168 if (expires != regc->expires) { 169 regc->expires_hdr = pjsip_expires_hdr_create(regc->pool, expires); 145 pjsip_endpt_release_pool(pubc->endpt, pubc->pool); 146 } 147 148 return PJ_SUCCESS; 149 } 150 151 152 PJ_DEF(pj_pool_t*) pjsip_publishc_get_pool(pjsip_publishc *pubc) 153 { 154 return pubc->pool; 155 } 156 157 static void set_expires( pjsip_publishc *pubc, pj_uint32_t expires) 158 { 159 if (expires != pubc->expires) { 160 pubc->expires_hdr = pjsip_expires_hdr_create(pubc->pool, expires); 170 161 } else { 171 regc->expires_hdr = NULL; 172 } 173 } 174 175 176 static pj_status_t set_contact( pjsip_regc *regc, 177 int contact_cnt, 178 const pj_str_t contact[] ) 179 { 180 int i; 181 char *s; 182 const pj_str_t contact_STR = { "Contact", 7}; 183 184 /* Concatenate contacts. */ 185 for (i=0, s=regc->contact_buf; i<contact_cnt; ++i) { 186 if ((s-regc->contact_buf) + contact[i].slen + 2 > PJSIP_REGC_CONTACT_BUF_SIZE) { 187 return PJSIP_EURITOOLONG; 188 } 189 pj_memcpy(s, contact[i].ptr, contact[i].slen); 190 s += contact[i].slen; 191 192 if (i != contact_cnt - 1) { 193 *s++ = ','; 194 *s++ = ' '; 195 } 196 } 197 198 /* Set "Contact" header. */ 199 regc->contact_hdr = pjsip_generic_string_hdr_create(regc->pool, 200 &contact_STR, 201 NULL); 202 regc->contact_hdr->hvalue.ptr = regc->contact_buf; 203 regc->contact_hdr->hvalue.slen = (s - regc->contact_buf); 204 205 return PJ_SUCCESS; 206 } 207 208 209 PJ_DEF(pj_status_t) pjsip_regc_init( pjsip_regc *regc, 210 const pj_str_t *srv_url, 211 const pj_str_t *from_url, 212 const pj_str_t *to_url, 213 int contact_cnt, 214 const pj_str_t contact[], 215 pj_uint32_t expires) 162 pubc->expires_hdr = NULL; 163 } 164 } 165 166 167 PJ_DEF(pj_status_t) pjsip_publishc_init(pjsip_publishc *pubc, 168 const pj_str_t *event, 169 const pj_str_t *target_uri, 170 const pj_str_t *from_uri, 171 const pj_str_t *to_uri, 172 pj_uint32_t expires) 216 173 { 217 174 pj_str_t tmp; 218 pj_status_t status; 219 220 PJ_ASSERT_RETURN(regc && srv_url && from_url && to_url && 221 contact_cnt && contact && expires, PJ_EINVAL); 175 176 PJ_ASSERT_RETURN(pubc && event && target_uri && from_uri && to_uri && 177 expires, PJ_EINVAL); 178 179 /* Copy event type */ 180 pj_strdup_with_null(pubc->pool, &pubc->event, event); 222 181 223 182 /* Copy server URL. */ 224 pj_strdup_with_null( regc->pool, ®c->str_srv_url, srv_url);183 pj_strdup_with_null(pubc->pool, &pubc->str_target_uri, target_uri); 225 184 226 185 /* Set server URL. */ 227 tmp = regc->str_srv_url;228 regc->srv_url = pjsip_parse_uri( regc->pool, tmp.ptr, tmp.slen, 0);229 if ( regc->srv_url== NULL) {186 tmp = pubc->str_target_uri; 187 pubc->target_uri = pjsip_parse_uri( pubc->pool, tmp.ptr, tmp.slen, 0); 188 if (pubc->target_uri == NULL) { 230 189 return PJSIP_EINVALIDURI; 231 190 } 232 191 233 192 /* Set "From" header. */ 234 pj_strdup_with_null( regc->pool, ®c->from_uri, from_url);235 tmp = regc->from_uri;236 regc->from_hdr = pjsip_from_hdr_create(regc->pool);237 regc->from_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen,193 pj_strdup_with_null(pubc->pool, &pubc->from_uri, from_uri); 194 tmp = pubc->from_uri; 195 pubc->from_hdr = pjsip_from_hdr_create(pubc->pool); 196 pubc->from_hdr->uri = pjsip_parse_uri(pubc->pool, tmp.ptr, tmp.slen, 238 197 PJSIP_PARSE_URI_AS_NAMEADDR); 239 if (!regc->from_hdr->uri) { 240 PJ_LOG(4,(THIS_FILE, "regc: invalid source URI %.*s", 241 from_url->slen, from_url->ptr)); 198 if (!pubc->from_hdr->uri) { 242 199 return PJSIP_EINVALIDURI; 243 200 } 244 201 245 202 /* Set "To" header. */ 246 pj_strdup_with_null( regc->pool, &tmp, to_url);247 regc->to_hdr = pjsip_to_hdr_create(regc->pool);248 regc->to_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen,203 pj_strdup_with_null(pubc->pool, &tmp, to_uri); 204 pubc->to_hdr = pjsip_to_hdr_create(pubc->pool); 205 pubc->to_hdr->uri = pjsip_parse_uri(pubc->pool, tmp.ptr, tmp.slen, 249 206 PJSIP_PARSE_URI_AS_NAMEADDR); 250 if (!regc->to_hdr->uri) { 251 PJ_LOG(4,(THIS_FILE, "regc: invalid target URI %.*s", to_url->slen, to_url->ptr)); 207 if (!pubc->to_hdr->uri) { 252 208 return PJSIP_EINVALIDURI; 253 209 } 254 210 255 211 256 /* Set "Contact" header. */257 status = set_contact( regc, contact_cnt, contact);258 if (status != PJ_SUCCESS)259 return status;260 261 212 /* Set "Expires" header, if required. */ 262 set_expires( regc, expires);213 set_expires( pubc, expires); 263 214 264 215 /* Set "Call-ID" header. */ 265 regc->cid_hdr = pjsip_cid_hdr_create(regc->pool);266 pj_create_unique_string( regc->pool, ®c->cid_hdr->id);216 pubc->cid_hdr = pjsip_cid_hdr_create(pubc->pool); 217 pj_create_unique_string(pubc->pool, &pubc->cid_hdr->id); 267 218 268 219 /* Set "CSeq" header. */ 269 regc->cseq_hdr = pjsip_cseq_hdr_create(regc->pool); 270 regc->cseq_hdr->cseq = pj_rand() % 0xFFFF; 271 pjsip_method_set( ®c->cseq_hdr->method, PJSIP_REGISTER_METHOD); 272 273 /* Create "Contact" header used in unregistration. */ 274 regc->unreg_contact_hdr = pjsip_contact_hdr_create(regc->pool); 275 regc->unreg_contact_hdr->star = 1; 276 277 /* Create "Expires" header used in unregistration. */ 278 regc->unreg_expires_hdr = pjsip_expires_hdr_create( regc->pool, 0); 220 pubc->cseq_hdr = pjsip_cseq_hdr_create(pubc->pool); 221 pubc->cseq_hdr->cseq = pj_rand() % 0xFFFF; 222 pjsip_method_set( &pubc->cseq_hdr->method, PJSIP_REGISTER_METHOD); 279 223 280 224 /* Done. */ … … 282 226 } 283 227 284 PJ_DEF(pj_status_t) pjsip_ regc_set_credentials( pjsip_regc *regc,228 PJ_DEF(pj_status_t) pjsip_publishc_set_credentials( pjsip_publishc *pubc, 285 229 int count, 286 230 const pjsip_cred_info cred[] ) 287 231 { 288 PJ_ASSERT_RETURN( regc && count && cred, PJ_EINVAL);289 return pjsip_auth_clt_set_credentials(& regc->auth_sess, count, cred);290 } 291 292 PJ_DEF(pj_status_t) pjsip_ regc_set_route_set( pjsip_regc *regc,232 PJ_ASSERT_RETURN(pubc && count && cred, PJ_EINVAL); 233 return pjsip_auth_clt_set_credentials(&pubc->auth_sess, count, cred); 234 } 235 236 PJ_DEF(pj_status_t) pjsip_publishc_set_route_set( pjsip_publishc *pubc, 293 237 const pjsip_route_hdr *route_set) 294 238 { 295 239 const pjsip_route_hdr *chdr; 296 240 297 PJ_ASSERT_RETURN( regc && route_set, PJ_EINVAL);298 299 pj_list_init(& regc->route_set);241 PJ_ASSERT_RETURN(pubc && route_set, PJ_EINVAL); 242 243 pj_list_init(&pubc->route_set); 300 244 301 245 chdr = route_set->next; 302 246 while (chdr != route_set) { 303 pj_list_push_back(& regc->route_set, pjsip_hdr_clone(regc->pool, chdr));247 pj_list_push_back(&pubc->route_set, pjsip_hdr_clone(pubc->pool, chdr)); 304 248 chdr = chdr->next; 305 249 } … … 308 252 } 309 253 310 static pj_status_t create_request(pjsip_ regc *regc,254 static pj_status_t create_request(pjsip_publishc *pubc, 311 255 pjsip_tx_data **p_tdata) 312 256 { 313 pj_status_t status; 257 const pj_str_t STR_EVENT = { "Event", 5 }; 258 pj_status_t status; 259 pjsip_generic_string_hdr *hdr; 314 260 pjsip_tx_data *tdata; 315 261 316 PJ_ASSERT_RETURN( regc && p_tdata, PJ_EINVAL);262 PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); 317 263 318 264 /* Create the request. */ 319 status = pjsip_endpt_create_request_from_hdr( regc->endpt,320 &pjsip_ register_method,321 regc->srv_url,322 regc->from_hdr,323 regc->to_hdr,265 status = pjsip_endpt_create_request_from_hdr( pubc->endpt, 266 &pjsip_publish_method, 267 pubc->target_uri, 268 pubc->from_hdr, 269 pubc->to_hdr, 324 270 NULL, 325 regc->cid_hdr,326 regc->cseq_hdr->cseq,271 pubc->cid_hdr, 272 pubc->cseq_hdr->cseq, 327 273 NULL, 328 274 &tdata); … … 331 277 332 278 /* Add cached authorization headers. */ 333 pjsip_auth_clt_init_req( & regc->auth_sess, tdata );279 pjsip_auth_clt_init_req( &pubc->auth_sess, tdata ); 334 280 335 281 /* Add Route headers from route set, ideally after Via header */ 336 if (!pj_list_empty(& regc->route_set)) {282 if (!pj_list_empty(&pubc->route_set)) { 337 283 pjsip_hdr *route_pos; 338 284 const pjsip_route_hdr *route; … … 342 288 route_pos = &tdata->msg->hdr; 343 289 344 route = regc->route_set.next;345 while (route != & regc->route_set) {290 route = pubc->route_set.next; 291 while (route != &pubc->route_set) { 346 292 pjsip_hdr *new_hdr = pjsip_hdr_shallow_clone(tdata->pool, route); 347 293 pj_list_insert_after(route_pos, new_hdr); … … 351 297 } 352 298 299 /* Add Event header */ 300 hdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_EVENT, 301 &pubc->event); 302 if (hdr) 303 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr); 304 305 306 /* Add SIP-If-Match if we have etag */ 307 if (pubc->etag.slen) { 308 const pj_str_t STR_HNAME = { "SIP-If-Match", 12 }; 309 310 hdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_HNAME, 311 &pubc->etag); 312 if (hdr) 313 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr); 314 } 315 316 353 317 /* Done. */ 354 318 *p_tdata = tdata; … … 357 321 358 322 359 PJ_DEF(pj_status_t) pjsip_ regc_register(pjsip_regc *regc, pj_bool_t autoreg,360 pjsip_tx_data **p_tdata)361 { 362 pjsip_msg *msg; 323 PJ_DEF(pj_status_t) pjsip_publishc_publish(pjsip_publishc *pubc, 324 pj_bool_t auto_refresh, 325 pjsip_tx_data **p_tdata) 326 { 363 327 pj_status_t status; 364 328 pjsip_tx_data *tdata; 365 329 366 PJ_ASSERT_RETURN( regc && p_tdata, PJ_EINVAL);367 368 status = create_request( regc, &tdata);330 PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); 331 332 status = create_request(pubc, &tdata); 369 333 if (status != PJ_SUCCESS) 370 334 return status; 371 335 372 /* Add Contact header. */ 373 msg = tdata->msg; 374 pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->contact_hdr); 375 if (regc->expires_hdr) 376 pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->expires_hdr); 377 378 if (regc->timer.id != 0) { 379 pjsip_endpt_cancel_timer(regc->endpt, ®c->timer); 380 regc->timer.id = 0; 381 } 382 383 regc->auto_reg = autoreg; 336 /* Add Expires header */ 337 if (pubc->expires_hdr) { 338 pjsip_hdr *dup; 339 340 dup = pjsip_hdr_shallow_clone(tdata->pool, pubc->expires_hdr); 341 if (dup) 342 pjsip_msg_add_hdr(tdata->msg, dup); 343 } 344 345 /* Cancel existing timer */ 346 if (pubc->timer.id != 0) { 347 pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer); 348 pubc->timer.id = 0; 349 } 350 351 pubc->auto_refresh = auto_refresh; 384 352 385 353 /* Done */ … … 389 357 390 358 391 PJ_DEF(pj_status_t) pjsip_ regc_unregister(pjsip_regc *regc,392 pjsip_tx_data **p_tdata)359 PJ_DEF(pj_status_t) pjsip_publishc_unpublish(pjsip_publishc *pubc, 360 pjsip_tx_data **p_tdata) 393 361 { 394 362 pjsip_tx_data *tdata; 395 363 pjsip_msg *msg; 396 pj_status_t status; 397 398 PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); 399 400 if (regc->timer.id != 0) { 401 pjsip_endpt_cancel_timer(regc->endpt, ®c->timer); 402 regc->timer.id = 0; 403 } 404 405 status = create_request(regc, &tdata); 364 pjsip_expires_hdr *expires; 365 pj_status_t status; 366 367 PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); 368 369 if (pubc->timer.id != 0) { 370 pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer); 371 pubc->timer.id = 0; 372 } 373 374 status = create_request(pubc, &tdata); 406 375 if (status != PJ_SUCCESS) 407 376 return status; 408 377 409 378 msg = tdata->msg; 410 pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_contact_hdr); 411 pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr); 379 380 /* Add Expires:0 header */ 381 expires = pjsip_expires_hdr_create(tdata->pool, 0); 382 pjsip_msg_add_hdr( msg, (pjsip_hdr*)expires); 412 383 413 384 *p_tdata = tdata; … … 416 387 417 388 418 PJ_DEF(pj_status_t) pjsip_regc_update_contact( pjsip_regc *regc, 419 int contact_cnt, 420 const pj_str_t contact[] ) 421 { 422 PJ_ASSERT_RETURN(regc, PJ_EINVAL); 423 return set_contact( regc, contact_cnt, contact ); 424 } 425 426 427 PJ_DEF(pj_status_t) pjsip_regc_update_expires( pjsip_regc *regc, 428 pj_uint32_t expires ) 429 { 430 PJ_ASSERT_RETURN(regc, PJ_EINVAL); 431 set_expires( regc, expires ); 432 return PJ_SUCCESS; 433 } 434 435 436 static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code, 437 const pj_str_t *reason, 438 pjsip_rx_data *rdata, pj_int32_t expiration, 439 int contact_cnt, pjsip_contact_hdr *contact[]) 440 { 441 struct pjsip_regc_cbparam cbparam; 442 443 444 cbparam.regc = regc; 445 cbparam.token = regc->token; 389 PJ_DEF(pj_status_t) pjsip_publishc_update_expires( pjsip_publishc *pubc, 390 pj_uint32_t expires ) 391 { 392 PJ_ASSERT_RETURN(pubc, PJ_EINVAL); 393 set_expires( pubc, expires ); 394 return PJ_SUCCESS; 395 } 396 397 398 static void call_callback(pjsip_publishc *pubc, pj_status_t status, 399 int st_code, const pj_str_t *reason, 400 pjsip_rx_data *rdata, pj_int32_t expiration) 401 { 402 struct pjsip_publishc_cbparam cbparam; 403 404 405 cbparam.pubc = pubc; 406 cbparam.token = pubc->token; 446 407 cbparam.status = status; 447 408 cbparam.code = st_code; 448 409 cbparam.reason = *reason; 449 410 cbparam.rdata = rdata; 450 cbparam.contact_cnt = contact_cnt;451 411 cbparam.expiration = expiration; 452 if (contact_cnt) { 453 pj_memcpy( cbparam.contact, contact, 454 contact_cnt*sizeof(pjsip_contact_hdr*)); 455 } 456 457 (*regc->cb)(&cbparam); 458 } 459 460 static void regc_refresh_timer_cb( pj_timer_heap_t *timer_heap, 412 413 (*pubc->cb)(&cbparam); 414 } 415 416 static void pubc_refresh_timer_cb( pj_timer_heap_t *timer_heap, 461 417 struct pj_timer_entry *entry) 462 418 { 463 pjsip_ regc *regc = entry->user_data;419 pjsip_publishc *pubc = entry->user_data; 464 420 pjsip_tx_data *tdata; 465 421 pj_status_t status; … … 468 424 469 425 entry->id = 0; 470 status = pjsip_ regc_register(regc, 1, &tdata);426 status = pjsip_publishc_publish(pubc, 1, &tdata); 471 427 if (status == PJ_SUCCESS) { 472 status = pjsip_ regc_send(regc, tdata);428 status = pjsip_publishc_send(pubc, tdata); 473 429 } 474 430 … … 476 432 char errmsg[PJ_ERR_MSG_SIZE]; 477 433 pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg)); 478 call_callback( regc, status, 400, &reason, NULL, -1, 0, NULL);434 call_callback(pubc, status, 400, &reason, NULL, -1); 479 435 } 480 436 } … … 483 439 { 484 440 pj_status_t status; 485 pjsip_ regc *regc = token;441 pjsip_publishc *pubc = token; 486 442 pjsip_transaction *tsx = event->body.tsx_state.tsx; 487 443 488 444 /* Decrement pending transaction counter. */ 489 pj_assert( regc->pending_tsx > 0);490 -- regc->pending_tsx;491 492 /* If registration data has been deleted by user then remove registration445 pj_assert(pubc->pending_tsx > 0); 446 --pubc->pending_tsx; 447 448 /* If publication data has been deleted by user then remove publication 493 449 * data from transaction's callback, and don't call callback. 494 450 */ 495 if ( regc->_delete_flag) {451 if (pubc->_delete_flag) { 496 452 497 453 /* Nothing to do */ … … 504 460 pjsip_tx_data *tdata; 505 461 506 status = pjsip_auth_clt_reinit_req( & regc->auth_sess,462 status = pjsip_auth_clt_reinit_req( &pubc->auth_sess, 507 463 rdata, 508 464 tsx->last_tx, … … 510 466 511 467 if (status == PJ_SUCCESS) { 512 status = pjsip_ regc_send(regc, tdata);468 status = pjsip_publishc_send(pubc, tdata); 513 469 } 514 470 515 471 if (status != PJ_SUCCESS) { 516 call_callback( regc, status, tsx->status_code,472 call_callback(pubc, status, tsx->status_code, 517 473 &rdata->msg_info.msg->line.status.reason, 518 rdata, -1 , 0, NULL);474 rdata, -1); 519 475 } 520 476 … … 522 478 523 479 } else { 524 int contact_cnt = 0;525 pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT];526 480 pjsip_rx_data *rdata; 527 481 pj_int32_t expiration = 0xFFFF; 528 482 529 483 if (tsx->status_code/100 == 2) { 530 int i;531 pjsip_contact_hdr *hdr;532 484 pjsip_msg *msg; 533 485 pjsip_expires_hdr *expires; 486 pjsip_generic_string_hdr *etag_hdr; 487 const pj_str_t STR_ETAG = { "SIP-ETag", 8 }; 534 488 535 489 rdata = event->body.tsx_state.src.rdata; 536 490 msg = rdata->msg_info.msg; 537 hdr = pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL); 538 while (hdr) { 539 contact[contact_cnt++] = hdr; 540 hdr = hdr->next; 541 if (hdr == (void*)&msg->hdr) 542 break; 543 hdr = pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, hdr); 491 492 /* Save ETag value */ 493 etag_hdr = (pjsip_generic_string_hdr*) 494 pjsip_msg_find_hdr_by_name(msg, &STR_ETAG, NULL); 495 if (etag_hdr) { 496 pj_strdup(pubc->pool, &pubc->etag, &etag_hdr->hvalue); 497 } else { 498 pubc->etag.slen = 0; 544 499 } 545 500 501 /* Update expires value */ 546 502 expires = pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL); 547 503 … … 549 505 expiration = expires->ivalue; 550 506 551 for (i=0; i<contact_cnt; ++i) { 552 hdr = contact[i]; 553 if (hdr->expires >= 0 && hdr->expires < expiration) 554 expiration = contact[i]->expires; 555 } 556 557 if (regc->auto_reg && expiration != 0 && expiration != 0xFFFF) { 507 if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) { 558 508 pj_time_val delay = { 0, 0}; 559 509 560 510 delay.sec = expiration - DELAY_BEFORE_REFRESH; 561 if ( regc->expires != PJSIP_REGC_EXPIRATION_NOT_SPECIFIED &&562 delay.sec > (pj_int32_t) regc->expires)511 if (pubc->expires != PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED && 512 delay.sec > (pj_int32_t)pubc->expires) 563 513 { 564 delay.sec = regc->expires;514 delay.sec = pubc->expires; 565 515 } 566 516 if (delay.sec < DELAY_BEFORE_REFRESH) 567 517 delay.sec = DELAY_BEFORE_REFRESH; 568 regc->timer.cb = ®c_refresh_timer_cb;569 regc->timer.id = REFRESH_TIMER;570 regc->timer.user_data = regc;571 pjsip_endpt_schedule_timer( regc->endpt, ®c->timer, &delay);572 pj_gettimeofday(& regc->last_reg);573 regc->next_reg = regc->last_reg;574 regc->next_reg.sec += delay.sec;518 pubc->timer.cb = &pubc_refresh_timer_cb; 519 pubc->timer.id = REFRESH_TIMER; 520 pubc->timer.user_data = pubc; 521 pjsip_endpt_schedule_timer( pubc->endpt, &pubc->timer, &delay); 522 pj_gettimeofday(&pubc->last_refresh); 523 pubc->next_refresh = pubc->last_refresh; 524 pubc->next_refresh.sec += delay.sec; 575 525 } 576 526 … … 583 533 /* Call callback. */ 584 534 if (expiration == 0xFFFF) expiration = -1; 585 call_callback( regc, PJ_SUCCESS, tsx->status_code,535 call_callback(pubc, PJ_SUCCESS, tsx->status_code, 586 536 (rdata ? &rdata->msg_info.msg->line.status.reason 587 537 : pjsip_get_status_text(tsx->status_code)), 588 rdata, expiration, 589 contact_cnt, contact); 590 591 } 592 593 /* Delete the record if user destroy regc during the callback. */ 594 if (regc->_delete_flag && regc->pending_tsx==0) { 595 pjsip_regc_destroy(regc); 596 } 597 } 598 599 PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata) 538 rdata, expiration); 539 540 } 541 542 /* Delete the record if user destroy pubc during the callback. */ 543 if (pubc->_delete_flag && pubc->pending_tsx==0) { 544 pjsip_publishc_destroy(pubc); 545 } 546 } 547 548 549 PJ_DEF(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc, 550 pjsip_tx_data *tdata) 600 551 { 601 552 pj_status_t status; … … 604 555 605 556 /* Make sure we don't have pending transaction. */ 606 if ( regc->pending_tsx) {607 PJ_LOG(4,(THIS_FILE, "Unable to send request, regc has another "557 if (pubc->pending_tsx) { 558 PJ_LOG(4,(THIS_FILE, "Unable to send request, pubc has another " 608 559 "transaction pending")); 609 560 pjsip_tx_data_dec_ref( tdata ); … … 615 566 616 567 /* Increment CSeq */ 617 cseq = ++ regc->cseq_hdr->cseq;568 cseq = ++pubc->cseq_hdr->cseq; 618 569 cseq_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL); 619 570 cseq_hdr->cseq = cseq; … … 622 573 * may be called even before send_request() returns! 623 574 */ 624 ++regc->pending_tsx; 625 status = pjsip_endpt_send_request(regc->endpt, tdata, -1, regc, &tsx_callback); 575 ++pubc->pending_tsx; 576 status = pjsip_endpt_send_request(pubc->endpt, tdata, -1, pubc, 577 &tsx_callback); 626 578 if (status!=PJ_SUCCESS) { 627 -- regc->pending_tsx;579 --pubc->pending_tsx; 628 580 PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status)); 629 581 }
Note: See TracChangeset
for help on using the changeset viewer.