Changeset 685 for pjproject/trunk
- Timestamp:
- Aug 15, 2006 8:26:34 PM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 1 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/config.c
r659 r685 22 22 23 23 static const char *id = "config.c"; 24 const char *PJ_VERSION = "0.5.7. 1";24 const char *PJ_VERSION = "0.5.7.6"; 25 25 26 26 PJ_DEF(void) pj_dump_config(void) -
pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
r683 r685 102 102 puts (" --username=string Set authentication username"); 103 103 puts (" --password=string Set authentication password"); 104 puts (" --publish Send presence PUBLISH for this account"); 104 105 puts (" --next-cred Add another credentials"); 105 106 puts (""); … … 259 260 OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO, 260 261 OPT_LOCAL_PORT, OPT_PROXY, OPT_OUTBOUND_PROXY, OPT_REGISTRAR, 261 OPT_REG_TIMEOUT, OPT_ ID, OPT_CONTACT,262 OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT, 262 263 OPT_REALM, OPT_USERNAME, OPT_PASSWORD, 263 264 OPT_USE_STUN1, OPT_USE_STUN2, … … 287 288 { "registrar", 1, 0, OPT_REGISTRAR}, 288 289 { "reg-timeout",1, 0, OPT_REG_TIMEOUT}, 290 { "publish", 0, 0, OPT_PUBLISH}, 289 291 { "id", 1, 0, OPT_ID}, 290 292 { "contact", 1, 0, OPT_CONTACT}, … … 480 482 break; 481 483 484 case OPT_PUBLISH: /* publish */ 485 cur_acc->publish_enabled = PJ_TRUE; 486 break; 487 482 488 case OPT_ID: /* id */ 483 489 if (pjsua_verify_sip_url(pj_optarg) != 0) { -
pjproject/trunk/pjsip/build/Makefile
r604 r685 67 67 export PJSIP_SIMPLE_SRCDIR = ../src/pjsip-simple 68 68 export PJSIP_SIMPLE_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 69 errno.o evsub.o evsub_msg.o iscomposing.o pidf.o presence.o \ 69 errno.o evsub.o evsub_msg.o iscomposing.o \ 70 pidf.o presence.o presence_body.o publishc.o \ 70 71 xpidf.o 71 72 export PJSIP_SIMPLE_CFLAGS += $(_CFLAGS) -
pjproject/trunk/pjsip/build/pjsip_simple.dsp
r683 r685 110 110 # Begin Source File 111 111 112 SOURCE="..\src\pjsip-simple\presence_body.c" 113 # End Source File 114 # Begin Source File 115 112 116 SOURCE="..\src\pjsip-simple\publishc.c" 113 117 … … 115 119 116 120 !ELSEIF "$(CFG)" == "pjsip_simple - Win32 Debug" 117 118 # PROP Exclude_From_Build 1119 121 120 122 !ENDIF -
pjproject/trunk/pjsip/include/pjsip-simple/presence.h
r515 r685 104 104 * @param user_cb Pointer to callbacks to receive presence subscription 105 105 * events. 106 * @param options Option flags. Currently only PJSIP_EVSUB_NO_EVENT_ID 107 * is recognized. 106 108 * @param p_evsub Pointer to receive the presence subscription 107 109 * session. … … 111 113 PJ_DECL(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg, 112 114 const pjsip_evsub_user *user_cb, 115 unsigned options, 113 116 pjsip_evsub **p_evsub ); 114 117 … … 266 269 267 270 /** 271 * This is a utility function to create PIDF message body from PJSIP 272 * presence status (pjsip_pres_status). 273 * 274 * @param pool The pool to allocate memory for the message body. 275 * @param status Presence status to be converted into PIDF message 276 * body. 277 * @param entity The entity ID, which normally is equal to the 278 * presentity ID publishing this presence info. 279 * @param p_body Pointer to receive the SIP message body. 280 * 281 * @return PJ_SUCCESS on success. 282 */ 283 PJ_DECL(pj_status_t) pjsip_pres_create_pidf( pj_pool_t *pool, 284 const pjsip_pres_status *status, 285 const pj_str_t *entity, 286 pjsip_msg_body **p_body ); 287 288 289 /** 290 * This is a utility function to create X-PIDF message body from PJSIP 291 * presence status (pjsip_pres_status). 292 * 293 * @param pool The pool to allocate memory for the message body. 294 * @param status Presence status to be converted into X-PIDF message 295 * body. 296 * @param entity The entity ID, which normally is equal to the 297 * presentity ID publishing this presence info. 298 * @param p_body Pointer to receive the SIP message body. 299 * 300 * @return PJ_SUCCESS on success. 301 */ 302 PJ_DECL(pj_status_t) pjsip_pres_create_xpidf(pj_pool_t *pool, 303 const pjsip_pres_status *status, 304 const pj_str_t *entity, 305 pjsip_msg_body **p_body ); 306 307 308 309 /** 310 * This is a utility function to parse PIDF body into PJSIP presence status. 311 * 312 * @param rdata The incoming SIP message containing the PIDF body. 313 * @param pool Pool to allocate memory to copy the strings into 314 * the presence status structure. 315 * @param status The presence status to be initialized. 316 * 317 * @return PJ_SUCCESS on success. 318 */ 319 PJ_DECL(pj_status_t) pjsip_pres_parse_pidf(pjsip_rx_data *rdata, 320 pj_pool_t *pool, 321 pjsip_pres_status *status); 322 323 324 325 /** 326 * This is a utility function to parse X-PIDF body into PJSIP presence status. 327 * 328 * @param rdata The incoming SIP message containing the X-PIDF body. 329 * @param pool Pool to allocate memory to copy the strings into 330 * the presence status structure. 331 * @param status The presence status to be initialized. 332 * 333 * @return PJ_SUCCESS on success. 334 */ 335 PJ_DECL(pj_status_t) pjsip_pres_parse_xpidf(pjsip_rx_data *rdata, 336 pj_pool_t *pool, 337 pjsip_pres_status *status); 338 339 340 341 /** 268 342 * @} 269 343 */ -
pjproject/trunk/pjsip/include/pjsip-simple/publish.h
r683 r685 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 #ifndef __PJSIP_SIMPLE_P RESENCE_H__20 #define __PJSIP_SIMPLE_P RESENCE_H__19 #ifndef __PJSIP_SIMPLE_PUBLISH_H__ 20 #define __PJSIP_SIMPLE_PUBLISH_H__ 21 21 22 22 /** … … 24 24 * @brief SIP Extension for Event State Publication (PUBLISH, RFC 3903) 25 25 */ 26 27 #include <pjsip/sip_util.h> 26 28 27 29 … … 38 40 Extension for Event State Publication (PUBLISH) as defined by RFC 3856. 39 41 */ 42 43 /** 44 * The SIP PUBLISH method constant. 45 */ 46 extern const pjsip_method pjsip_publish_method; 40 47 41 48 … … 78 85 79 86 87 /** 88 * Initialize client publication module. 89 * 90 * @param endpt SIP endpoint. 91 * 92 * @return PJ_SUCCESS on success. 93 */ 94 PJ_DECL(pj_status_t) pjsip_publishc_init_module(pjsip_endpoint *endpt); 95 96 80 97 81 98 /** … … 83 100 * 84 101 * @param endpt Endpoint, used to allocate pool from. 102 * @param options Option flags. 85 103 * @param token Opaque data to be associated with the client publication. 86 104 * @param cb Pointer to callback function to receive publication status. … … 90 108 */ 91 109 PJ_DECL(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, 110 unsigned options, 92 111 void *token, 93 112 pjsip_publishc_cb *cb, … … 249 268 250 269 251 #endif /* __PJSIP_SIMPLE_P RESENCE_H__ */252 270 #endif /* __PJSIP_SIMPLE_PUBLISH_H__ */ 271 -
pjproject/trunk/pjsip/include/pjsip_simple.h
r515 r685 39 39 #include <pjsip-simple/presence.h> 40 40 #include <pjsip-simple/pidf.h> 41 #include <pjsip-simple/publish.h> 41 42 #include <pjsip-simple/xpidf.h> 42 43 -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r683 r685 1004 1004 1005 1005 /** 1006 * Default PUBLISH expiration 1007 */ 1008 #ifndef PJSUA_PUBLISH_EXPIRATION 1009 # define PJSUA_PUBLISH_EXPIRATION 600 1010 #endif 1011 1012 1013 /** 1006 1014 * Account configuration. 1007 1015 */ … … 1024 1032 */ 1025 1033 pj_str_t reg_uri; 1034 1035 /** 1036 * Publish presence? 1037 */ 1038 pj_bool_t publish_enabled; 1026 1039 1027 1040 /** -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
r648 r685 98 98 pj_bool_t online_status; /**< Our online status. */ 99 99 pjsua_srv_pres pres_srv_list; /**< Server subscription list. */ 100 pjsip_publishc *publish_sess; /**< Client publication session. */ 101 pj_bool_t publish_state; /**< Last published online status */ 100 102 101 103 } pjsua_acc; … … 256 258 257 259 260 #if 0 258 261 #define PJSUA_LOCK() pj_mutex_lock(pjsua_var.mutex); 259 262 #define PJSUA_UNLOCK() pj_mutex_unlock(pjsua_var.mutex); 263 #else 264 #define PJSUA_LOCK() 265 #define PJSUA_UNLOCK() 266 #endif 260 267 261 268 … … 285 292 */ 286 293 void pjsua_pres_shutdown(void); 294 295 /** 296 * Init presence for aoocunt. 297 */ 298 pj_status_t pjsua_pres_init_acc(int acc_id); 287 299 288 300 /** -
pjproject/trunk/pjsip/src/pjsip-simple/presence.c
r519 r685 180 180 PJ_DEF(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg, 181 181 const pjsip_evsub_user *user_cb, 182 unsigned options, 182 183 pjsip_evsub **p_evsub ) 183 184 { … … 191 192 192 193 /* Create event subscription */ 193 status = pjsip_evsub_create_uac( dlg, &pres_user, &STR_PRESENCE, 0, &sub); 194 status = pjsip_evsub_create_uac( dlg, &pres_user, &STR_PRESENCE, 195 options, &sub); 194 196 if (status != PJ_SUCCESS) 195 197 goto on_return; … … 413 415 414 416 /* 415 * Create PIDF document based on the presence info. 416 */ 417 static pjpidf_pres* pres_create_pidf( pj_pool_t *pool, 418 pjsip_pres *pres ) 419 { 420 pjpidf_pres *pidf; 421 unsigned i; 417 * Create message body. 418 */ 419 static pj_status_t pres_create_msg_body( pjsip_pres *pres, 420 pjsip_tx_data *tdata) 421 { 422 422 pj_str_t entity; 423 423 424 424 /* Get publisher URI */ 425 entity.ptr = pj_pool_alloc( pool, PJSIP_MAX_URL_SIZE);425 entity.ptr = pj_pool_alloc(tdata->pool, PJSIP_MAX_URL_SIZE); 426 426 entity.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, 427 427 pres->dlg->local.info->uri, 428 428 entity.ptr, PJSIP_MAX_URL_SIZE); 429 429 if (entity.slen < 1) 430 return NULL; 431 432 /* Create <presence>. */ 433 pidf = pjpidf_create(pool, &entity); 434 435 /* Create <tuple> */ 436 for (i=0; i<pres->status.info_cnt; ++i) { 437 438 pjpidf_tuple *pidf_tuple; 439 pjpidf_status *pidf_status; 440 441 /* Add tuple id. */ 442 pidf_tuple = pjpidf_pres_add_tuple(pool, pidf, 443 &pres->status.info[i].id); 444 445 /* Set <contact> */ 446 if (pres->status.info[i].contact.slen) 447 pjpidf_tuple_set_contact(pool, pidf_tuple, 448 &pres->status.info[i].contact); 449 450 451 /* Set basic status */ 452 pidf_status = pjpidf_tuple_get_status(pidf_tuple); 453 pjpidf_status_set_basic_open(pidf_status, 454 pres->status.info[i].basic_open); 455 } 456 457 return pidf; 458 } 459 460 461 /* 462 * Create XPIDF document based on the presence info. 463 */ 464 static pjxpidf_pres* pres_create_xpidf( pj_pool_t *pool, 465 pjsip_pres *pres ) 466 { 467 /* Note: PJSIP implementation of XPIDF is not complete! 468 */ 469 pjxpidf_pres *xpidf; 470 pj_str_t publisher_uri; 471 472 PJ_LOG(4,(THIS_FILE, "Warning: XPIDF format is not fully supported " 473 "by PJSIP")); 474 475 publisher_uri.ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE); 476 publisher_uri.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, 477 pres->dlg->local.info->uri, 478 publisher_uri.ptr, 479 PJSIP_MAX_URL_SIZE); 480 if (publisher_uri.slen < 1) 481 return NULL; 482 483 /* Create XPIDF document. */ 484 xpidf = pjxpidf_create(pool, &publisher_uri); 485 486 /* Set basic status. */ 487 if (pres->status.info_cnt > 0) 488 pjxpidf_set_status( xpidf, pres->status.info[0].basic_open); 489 else 490 pjxpidf_set_status( xpidf, PJ_FALSE); 491 492 return xpidf; 493 } 494 495 496 /* 497 * Function to print XML message body. 498 */ 499 static int pres_print_body(struct pjsip_msg_body *msg_body, 500 char *buf, pj_size_t size) 501 { 502 return pj_xml_print(msg_body->data, buf, size, PJ_TRUE); 503 } 504 505 506 /* 507 * Function to clone XML document. 508 */ 509 static void* xml_clone_data(pj_pool_t *pool, const void *data, unsigned len) 510 { 511 PJ_UNUSED_ARG(len); 512 return pj_xml_clone( pool, data); 513 } 514 515 516 /* 517 * Create message body. 518 */ 519 static pj_status_t pres_create_msg_body( pjsip_pres *pres, 520 pjsip_tx_data *tdata) 521 { 522 pjsip_msg_body *body; 523 524 body = pj_pool_zalloc(tdata->pool, sizeof(pjsip_msg_body)); 525 430 return PJ_ENOMEM; 431 526 432 if (pres->content_type == CONTENT_TYPE_PIDF) { 527 433 528 body->data = pres_create_pidf(tdata->pool, pres); 529 body->content_type.type = pj_str("application"); 530 body->content_type.subtype = pj_str("pidf+xml"); 434 return pjsip_pres_create_pidf(tdata->pool, &pres->status, 435 &entity, &tdata->msg->body); 531 436 532 437 } else if (pres->content_type == CONTENT_TYPE_XPIDF) { 533 438 534 body->data = pres_create_xpidf(tdata->pool, pres); 535 body->content_type.type = pj_str("application"); 536 body->content_type.subtype = pj_str("xpidf+xml"); 439 return pjsip_pres_create_xpidf(tdata->pool, &pres->status, 440 &entity, &tdata->msg->body); 537 441 538 442 } else { 539 443 return PJSIP_SIMPLE_EBADCONTENT; 540 444 } 541 542 543 body->print_body = &pres_print_body;544 body->clone_data = &xml_clone_data;545 546 tdata->msg->body = body;547 548 return PJ_SUCCESS;549 445 } 550 446 … … 723 619 } 724 620 725 /*726 * Parse PIDF to info.727 */728 static pj_status_t pres_parse_pidf( pjsip_pres *pres,729 pjsip_rx_data *rdata,730 pjsip_pres_status *pres_status)731 {732 pjpidf_pres *pidf;733 pjpidf_tuple *pidf_tuple;734 735 pidf = pjpidf_parse(rdata->tp_info.pool,736 rdata->msg_info.msg->body->data,737 rdata->msg_info.msg->body->len);738 if (pidf == NULL)739 return PJSIP_SIMPLE_EBADPIDF;740 741 pres_status->info_cnt = 0;742 743 pidf_tuple = pjpidf_pres_get_first_tuple(pidf);744 while (pidf_tuple) {745 pjpidf_status *pidf_status;746 747 pj_strdup(pres->dlg->pool,748 &pres_status->info[pres_status->info_cnt].id,749 pjpidf_tuple_get_id(pidf_tuple));750 751 pj_strdup(pres->dlg->pool,752 &pres_status->info[pres_status->info_cnt].contact,753 pjpidf_tuple_get_contact(pidf_tuple));754 755 pidf_status = pjpidf_tuple_get_status(pidf_tuple);756 if (pidf_status) {757 pres_status->info[pres_status->info_cnt].basic_open =758 pjpidf_status_is_basic_open(pidf_status);759 } else {760 pres_status->info[pres_status->info_cnt].basic_open = PJ_FALSE;761 }762 763 pidf_tuple = pjpidf_pres_get_next_tuple( pidf, pidf_tuple );764 pres_status->info_cnt++;765 }766 767 return PJ_SUCCESS;768 }769 770 /*771 * Parse XPIDF info.772 */773 static pj_status_t pres_parse_xpidf( pjsip_pres *pres,774 pjsip_rx_data *rdata,775 pjsip_pres_status *pres_status)776 {777 pjxpidf_pres *xpidf;778 779 xpidf = pjxpidf_parse(rdata->tp_info.pool,780 rdata->msg_info.msg->body->data,781 rdata->msg_info.msg->body->len);782 if (xpidf == NULL)783 return PJSIP_SIMPLE_EBADXPIDF;784 785 pres_status->info_cnt = 1;786 787 pj_strdup(pres->dlg->pool,788 &pres_status->info[0].contact,789 pjxpidf_get_uri(xpidf));790 pres_status->info[0].basic_open = pjxpidf_get_status(xpidf);791 pres_status->info[0].id.slen = 0;792 793 return PJ_SUCCESS;794 }795 796 621 797 622 /* … … 837 662 pj_stricmp(&ctype_hdr->media.subtype, &STR_PIDF_XML)==0) 838 663 { 839 status = pres_parse_pidf( pres, rdata, &pres->tmp_status); 664 status = pjsip_pres_parse_pidf( rdata, pres->dlg->pool, 665 &pres->tmp_status); 840 666 } 841 667 else … … 843 669 pj_stricmp(&ctype_hdr->media.subtype, &STR_XPIDF_XML)==0) 844 670 { 845 status = pres_parse_xpidf( pres, rdata, &pres->tmp_status); 671 status = pjsip_pres_parse_xpidf( rdata, pres->dlg->pool, 672 &pres->tmp_status); 846 673 } 847 674 else -
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 } -
pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
r610 r685 334 334 unsigned i; 335 335 336 PJ_UNUSED_ARG(mod); 337 336 338 /* Check arguments. */ 337 PJ_ASSERT_RETURN(endpt!=NULL && mod!=NULL &&count>0 && tags, PJ_EINVAL);339 PJ_ASSERT_RETURN(endpt!=NULL && count>0 && tags, PJ_EINVAL); 338 340 PJ_ASSERT_RETURN(htype==PJSIP_H_ACCEPT || 339 341 htype==PJSIP_H_ALLOW || 340 342 htype==PJSIP_H_SUPPORTED, 341 343 PJ_EINVAL); 342 343 PJ_UNUSED_ARG(mod);344 344 345 345 /* Find the header. */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c
r683 r685 99 99 pjsip_name_addr *name_addr; 100 100 pjsip_sip_uri *sip_uri, *sip_reg_uri; 101 pj_status_t status; 101 102 unsigned i; 102 103 … … 221 222 } 222 223 223 /* Init presence subscription */ 224 pj_list_init(&acc->pres_srv_list); 224 status = pjsua_pres_init_acc(acc_id); 225 if (status != PJ_SUCCESS) 226 return status; 227 225 228 226 229 /* Mark account as valid */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r657 r685 525 525 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 526 526 527 /* Init PUBLISH module */ 528 pjsip_publishc_init_module(pjsua_var.endpt); 527 529 528 530 /* Init xfer/REFER module */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
r683 r685 567 567 568 568 569 /* 570 * Client presence publication callback. 571 */ 572 static void publish_cb(struct pjsip_publishc_cbparam *param) 573 { 574 pjsua_acc *acc = param->token; 575 576 if (param->code/100 != 2 || param->status != PJ_SUCCESS) { 577 if (param->status != PJ_SUCCESS) { 578 char errmsg[PJ_ERR_MSG_SIZE]; 579 580 pj_strerror(param->status, errmsg, sizeof(errmsg)); 581 PJ_LOG(1,(THIS_FILE, 582 "Client publication (PUBLISH) failed, status=%d, msg=%s", 583 param->status, errmsg)); 584 } else { 585 PJ_LOG(1,(THIS_FILE, 586 "Client publication (PUBLISH) failed (%d/%.*s)", 587 param->code, (int)param->reason.slen, 588 param->reason.ptr)); 589 } 590 591 pjsip_publishc_destroy(param->pubc); 592 acc->publish_sess = NULL; 593 } 594 } 595 596 597 /* 598 * Send PUBLISH request. 599 */ 600 static pj_status_t send_publish(int acc_id, pj_bool_t active) 601 { 602 pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; 603 pjsua_acc *acc = &pjsua_var.acc[acc_id]; 604 pjsip_pres_status pres_status; 605 pjsip_tx_data *tdata; 606 pj_status_t status; 607 608 609 /* Create PUBLISH request */ 610 if (active) { 611 status = pjsip_publishc_publish(acc->publish_sess, PJ_TRUE, &tdata); 612 if (status != PJ_SUCCESS) { 613 pjsua_perror(THIS_FILE, "Error creating PUBLISH request", status); 614 goto on_error; 615 } 616 617 /* Set our online status: */ 618 pj_bzero(&pres_status, sizeof(pres_status)); 619 pres_status.info_cnt = 1; 620 pres_status.info[0].basic_open = acc->online_status; 621 622 /* Create and add PIDF message body */ 623 status = pjsip_pres_create_pidf(tdata->pool, &pres_status, 624 &acc_cfg->id, &tdata->msg->body); 625 if (status != PJ_SUCCESS) { 626 pjsua_perror(THIS_FILE, "Error creating PIDF for PUBLISH request", 627 status); 628 pjsip_tx_data_dec_ref(tdata); 629 goto on_error; 630 } 631 } else { 632 status = pjsip_publishc_unpublish(acc->publish_sess, &tdata); 633 if (status != PJ_SUCCESS) { 634 pjsua_perror(THIS_FILE, "Error creating PUBLISH request", status); 635 goto on_error; 636 } 637 } 638 639 /* Add headers etc */ 640 pjsua_process_msg_data(tdata, NULL); 641 642 /* Send the PUBLISH request */ 643 status = pjsip_publishc_send(acc->publish_sess, tdata); 644 if (status != PJ_SUCCESS) { 645 pjsua_perror(THIS_FILE, "Error sending PUBLISH request", status); 646 goto on_error; 647 } 648 649 acc->publish_state = acc->online_status; 650 return PJ_SUCCESS; 651 652 on_error: 653 pjsip_publishc_destroy(acc->publish_sess); 654 acc->publish_sess = NULL; 655 return status; 656 } 657 658 659 /* Create client publish session */ 660 static pj_status_t create_publish(int acc_id) 661 { 662 const pj_str_t STR_PRESENCE = { "presence", 8 }; 663 pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; 664 pjsua_acc *acc = &pjsua_var.acc[acc_id]; 665 pj_status_t status; 666 667 /* Create and init client publication session */ 668 if (acc_cfg->publish_enabled) { 669 670 /* Create client publication */ 671 status = pjsip_publishc_create(pjsua_var.endpt, 0, acc, &publish_cb, 672 &acc->publish_sess); 673 if (status != PJ_SUCCESS) { 674 acc->publish_sess = NULL; 675 return status; 676 } 677 678 /* Initialize client publication */ 679 status = pjsip_publishc_init(acc->publish_sess, &STR_PRESENCE, 680 &acc_cfg->id, &acc_cfg->id, 681 &acc_cfg->id, 682 PJSUA_PUBLISH_EXPIRATION); 683 if (status != PJ_SUCCESS) { 684 acc->publish_sess = NULL; 685 return status; 686 } 687 688 /* Send initial PUBLISH request */ 689 if (acc->online_status != 0) { 690 status = send_publish(acc_id, PJ_TRUE); 691 if (status != PJ_SUCCESS) 692 return status; 693 } 694 695 } else { 696 acc->publish_sess = NULL; 697 } 698 699 return PJ_SUCCESS; 700 } 701 702 703 /* Init presence for account */ 704 pj_status_t pjsua_pres_init_acc(int acc_id) 705 { 706 pjsua_acc *acc = &pjsua_var.acc[acc_id]; 707 708 /* Init presence subscription */ 709 pj_list_init(&acc->pres_srv_list); 710 711 712 return create_publish(acc_id); 713 } 714 715 569 716 /* Terminate server subscription for the account */ 570 717 void pjsua_pres_delete_acc(int acc_id) 571 718 { 719 pjsua_acc *acc = &pjsua_var.acc[acc_id]; 720 pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; 572 721 pjsua_srv_pres *uapres; 573 722 574 723 uapres = pjsua_var.acc[acc_id].pres_srv_list.next; 575 724 576 while (uapres != & pjsua_var.acc[acc_id].pres_srv_list) {725 while (uapres != &acc->pres_srv_list) { 577 726 578 727 pjsip_pres_status pres_status; … … 594 743 uapres = uapres->next; 595 744 } 745 746 if (acc->publish_sess) { 747 acc->online_status = PJ_FALSE; 748 send_publish(acc_id, PJ_FALSE); 749 if (acc->publish_sess) { 750 pjsip_publishc_destroy(acc->publish_sess); 751 acc->publish_sess = NULL; 752 } 753 acc_cfg->publish_enabled = PJ_FALSE; 754 } 596 755 } 597 756 … … 600 759 static void refresh_server_subscription(int acc_id) 601 760 { 761 pjsua_acc *acc = &pjsua_var.acc[acc_id]; 762 pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; 602 763 pjsua_srv_pres *uapres; 603 764 604 765 uapres = pjsua_var.acc[acc_id].pres_srv_list.next; 605 766 606 while (uapres != & pjsua_var.acc[acc_id].pres_srv_list) {767 while (uapres != &acc->pres_srv_list) { 607 768 608 769 pjsip_pres_status pres_status; … … 610 771 611 772 pjsip_pres_get_status(uapres->sub, &pres_status); 612 if (pres_status.info[0].basic_open != pjsua_var.acc[acc_id].online_status) {613 pres_status.info[0].basic_open = pjsua_var.acc[acc_id].online_status;773 if (pres_status.info[0].basic_open != acc->online_status) { 774 pres_status.info[0].basic_open = acc->online_status; 614 775 pjsip_pres_set_status(uapres->sub, &pres_status); 615 776 … … 621 782 622 783 uapres = uapres->next; 784 } 785 786 /* Send PUBLISH if required */ 787 if (acc_cfg->publish_enabled) { 788 if (acc->publish_sess == NULL) 789 create_publish(acc_id); 790 791 if (acc->publish_sess && acc->publish_state != acc->online_status) { 792 send_publish(acc_id, PJ_TRUE); 793 } 623 794 } 624 795 } … … 820 991 821 992 status = pjsip_pres_create_uac( dlg, &pres_callback, 822 &buddy->sub);993 PJSIP_EVSUB_NO_EVENT_ID, &buddy->sub); 823 994 if (status != PJ_SUCCESS) { 824 995 pjsua_var.buddy[index].sub = NULL;
Note: See TracChangeset
for help on using the changeset viewer.