Changeset 503 for pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
- Timestamp:
- Jun 13, 2006 10:57:13 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
r492 r503 18 18 */ 19 19 #include <pjsua-lib/pjsua.h> 20 #include "pjsua_imp.h" 21 22 /* 23 * pjsua_pres.c 24 * 25 * Presence related stuffs. 26 */ 20 #include <pjsua-lib/pjsua_internal.h> 21 27 22 28 23 #define THIS_FILE "pjsua_pres.c" 29 24 30 25 31 32 /* ************************************************************************** 33 * THE FOLLOWING PART HANDLES SERVER SUBSCRIPTION 34 * ************************************************************************** 26 /* 27 * Get total number of buddies. 28 */ 29 PJ_DEF(unsigned) pjsua_get_buddy_count(void) 30 { 31 return pjsua_var.buddy_cnt; 32 } 33 34 35 /* 36 * Check if buddy ID is valid. 37 */ 38 PJ_DEF(pj_bool_t) pjsua_buddy_is_valid(pjsua_buddy_id buddy_id) 39 { 40 return buddy_id>=0 && buddy_id<PJ_ARRAY_SIZE(pjsua_var.buddy) && 41 pjsua_var.buddy[buddy_id].uri.slen != 0; 42 } 43 44 45 /* 46 * Enum buddy IDs. 47 */ 48 PJ_DEF(pj_status_t) pjsua_enum_buddies( pjsua_buddy_id ids[], 49 unsigned *count) 50 { 51 unsigned i, c; 52 53 PJ_ASSERT_RETURN(ids && count, PJ_EINVAL); 54 55 PJSUA_LOCK(); 56 57 for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 58 if (!pjsua_var.buddy[i].uri.slen) 59 continue; 60 ids[c] = i; 61 ++c; 62 } 63 64 *count = c; 65 66 PJSUA_UNLOCK(); 67 68 return PJ_SUCCESS; 69 70 } 71 72 73 /* 74 * Get detailed buddy info. 75 */ 76 PJ_DEF(pj_status_t) pjsua_buddy_get_info( pjsua_buddy_id buddy_id, 77 pjsua_buddy_info *info) 78 { 79 int total=0; 80 pjsua_buddy *buddy; 81 82 PJ_ASSERT_RETURN(buddy_id>=0 && 83 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 84 PJ_EINVAL); 85 86 PJSUA_LOCK(); 87 88 pj_memset(info, 0, sizeof(pjsua_buddy_info)); 89 90 buddy = &pjsua_var.buddy[buddy_id]; 91 info->id = buddy->index; 92 if (pjsua_var.buddy[buddy_id].uri.slen == 0) { 93 PJSUA_UNLOCK(); 94 return PJ_SUCCESS; 95 } 96 97 /* uri */ 98 info->uri.ptr = info->buf_ + total; 99 pj_strncpy(&info->uri, &buddy->uri, sizeof(info->buf_)-total); 100 total += info->uri.slen; 101 102 /* contact */ 103 info->contact.ptr = info->buf_ + total; 104 pj_strncpy(&info->contact, &buddy->contact, sizeof(info->buf_)-total); 105 total += info->contact.slen; 106 107 /* status and status text */ 108 if (buddy->sub == NULL || buddy->status.info_cnt==0) { 109 info->status = PJSUA_BUDDY_STATUS_UNKNOWN; 110 info->status_text = pj_str("?"); 111 } else if (pjsua_var.buddy[buddy_id].status.info[0].basic_open) { 112 info->status = PJSUA_BUDDY_STATUS_ONLINE; 113 info->status_text = pj_str("Online"); 114 } else { 115 info->status = PJSUA_BUDDY_STATUS_OFFLINE; 116 info->status_text = pj_str("Offline"); 117 } 118 119 /* monitor pres */ 120 info->monitor_pres = buddy->monitor; 121 122 PJSUA_UNLOCK(); 123 return PJ_SUCCESS; 124 } 125 126 127 /* 128 * Reset buddy descriptor. 129 */ 130 static void reset_buddy(pjsua_buddy_id id) 131 { 132 pj_memset(&pjsua_var.buddy[id], 0, sizeof(pjsua_var.buddy[id])); 133 pjsua_var.buddy[id].index = id; 134 } 135 136 137 /* 138 * Add new buddy. 139 */ 140 PJ_DEF(pj_status_t) pjsua_buddy_add( const pjsua_buddy_config *cfg, 141 pjsua_buddy_id *p_buddy_id) 142 { 143 pjsip_name_addr *url; 144 pjsip_sip_uri *sip_uri; 145 int index; 146 pj_str_t tmp; 147 148 PJ_ASSERT_RETURN(pjsua_var.buddy_cnt <= 149 PJ_ARRAY_SIZE(pjsua_var.buddy), 150 PJ_ETOOMANY); 151 152 PJSUA_LOCK(); 153 154 /* Find empty slot */ 155 for (index=0; index<PJ_ARRAY_SIZE(pjsua_var.buddy); ++index) { 156 if (pjsua_var.buddy[index].uri.slen == 0) 157 break; 158 } 159 160 /* Expect to find an empty slot */ 161 if (index == PJ_ARRAY_SIZE(pjsua_var.buddy)) { 162 PJSUA_UNLOCK(); 163 /* This shouldn't happen */ 164 pj_assert(!"index < PJ_ARRAY_SIZE(pjsua_var.buddy)"); 165 return PJ_ETOOMANY; 166 } 167 168 169 /* Get name and display name for buddy */ 170 pj_strdup_with_null(pjsua_var.pool, &tmp, &cfg->uri); 171 url = (pjsip_name_addr*)pjsip_parse_uri(pjsua_var.pool, tmp.ptr, tmp.slen, 172 PJSIP_PARSE_URI_AS_NAMEADDR); 173 174 if (url == NULL) { 175 pjsua_perror(THIS_FILE, "Unable to add buddy", PJSIP_EINVALIDURI); 176 PJSUA_UNLOCK(); 177 return PJSIP_EINVALIDURI; 178 } 179 180 /* Reset buddy, to make sure everything is cleared with default 181 * values 182 */ 183 reset_buddy(index); 184 185 /* Save URI */ 186 pjsua_var.buddy[index].uri = tmp; 187 188 sip_uri = (pjsip_sip_uri*) url->uri; 189 pjsua_var.buddy[index].name = sip_uri->user; 190 pjsua_var.buddy[index].display = url->display; 191 pjsua_var.buddy[index].host = sip_uri->host; 192 pjsua_var.buddy[index].port = sip_uri->port; 193 pjsua_var.buddy[index].monitor = cfg->subscribe; 194 if (pjsua_var.buddy[index].port == 0) 195 pjsua_var.buddy[index].port = 5060; 196 197 if (p_buddy_id) 198 *p_buddy_id = index; 199 200 pjsua_var.buddy_cnt++; 201 202 pjsua_buddy_subscribe_pres(index, cfg->subscribe); 203 204 PJSUA_UNLOCK(); 205 206 return PJ_SUCCESS; 207 } 208 209 210 /* 211 * Delete buddy. 212 */ 213 PJ_DEF(pj_status_t) pjsua_buddy_del(pjsua_buddy_id buddy_id) 214 { 215 PJ_ASSERT_RETURN(buddy_id>=0 && 216 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 217 PJ_EINVAL); 218 219 PJSUA_LOCK(); 220 221 if (pjsua_var.buddy[buddy_id].uri.slen == 0) { 222 PJSUA_UNLOCK(); 223 return PJ_SUCCESS; 224 } 225 226 /* Unsubscribe presence */ 227 pjsua_buddy_subscribe_pres(buddy_id, PJ_FALSE); 228 229 /* Remove buddy */ 230 pjsua_var.buddy[buddy_id].uri.slen = 0; 231 pjsua_var.buddy_cnt--; 232 233 /* Reset buddy struct */ 234 reset_buddy(buddy_id); 235 236 PJSUA_UNLOCK(); 237 return PJ_SUCCESS; 238 } 239 240 241 /* 242 * Enable/disable buddy's presence monitoring. 243 */ 244 PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( pjsua_buddy_id buddy_id, 245 pj_bool_t subscribe) 246 { 247 pjsua_buddy *buddy; 248 249 PJ_ASSERT_RETURN(buddy_id>=0 && 250 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 251 PJ_EINVAL); 252 253 PJSUA_LOCK(); 254 255 buddy = &pjsua_var.buddy[buddy_id]; 256 buddy->monitor = subscribe; 257 pjsua_pres_refresh(); 258 259 PJSUA_UNLOCK(); 260 261 return PJ_SUCCESS; 262 } 263 264 265 /* 266 * Dump presence subscriptions to log file. 267 */ 268 PJ_DEF(void) pjsua_pres_dump(pj_bool_t verbose) 269 { 270 unsigned acc_id; 271 unsigned i; 272 273 274 PJSUA_LOCK(); 275 276 /* 277 * When no detail is required, just dump number of server and client 278 * subscriptions. 279 */ 280 if (verbose == PJ_FALSE) { 281 282 int count = 0; 283 284 for (acc_id=0; acc_id<PJ_ARRAY_SIZE(pjsua_var.acc); ++acc_id) { 285 286 if (!pjsua_var.acc[acc_id].valid) 287 continue; 288 289 if (!pj_list_empty(&pjsua_var.acc[acc_id].pres_srv_list)) { 290 struct pjsua_srv_pres *uapres; 291 292 uapres = pjsua_var.acc[acc_id].pres_srv_list.next; 293 while (uapres != &pjsua_var.acc[acc_id].pres_srv_list) { 294 ++count; 295 uapres = uapres->next; 296 } 297 } 298 } 299 300 PJ_LOG(3,(THIS_FILE, "Number of server/UAS subscriptions: %d", 301 count)); 302 303 count = 0; 304 305 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 306 if (pjsua_var.buddy[i].uri.slen == 0) 307 continue; 308 if (pjsua_var.buddy[i].sub) { 309 ++count; 310 } 311 } 312 313 PJ_LOG(3,(THIS_FILE, "Number of client/UAC subscriptions: %d", 314 count)); 315 PJSUA_UNLOCK(); 316 return; 317 } 318 319 320 /* 321 * Dumping all server (UAS) subscriptions 322 */ 323 PJ_LOG(3,(THIS_FILE, "Dumping pjsua server subscriptions:")); 324 325 for (acc_id=0; acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc); ++acc_id) { 326 327 if (!pjsua_var.acc[acc_id].valid) 328 continue; 329 330 PJ_LOG(3,(THIS_FILE, " %.*s", 331 (int)pjsua_var.acc[acc_id].cfg.id.slen, 332 pjsua_var.acc[acc_id].cfg.id.ptr)); 333 334 if (pj_list_empty(&pjsua_var.acc[acc_id].pres_srv_list)) { 335 336 PJ_LOG(3,(THIS_FILE, " - none - ")); 337 338 } else { 339 struct pjsua_srv_pres *uapres; 340 341 uapres = pjsua_var.acc[acc_id].pres_srv_list.next; 342 while (uapres != &pjsua_var.acc[acc_id].pres_srv_list) { 343 344 PJ_LOG(3,(THIS_FILE, " %10s %s", 345 pjsip_evsub_get_state_name(uapres->sub), 346 uapres->remote)); 347 348 uapres = uapres->next; 349 } 350 } 351 } 352 353 /* 354 * Dumping all client (UAC) subscriptions 355 */ 356 PJ_LOG(3,(THIS_FILE, "Dumping pjsua client subscriptions:")); 357 358 if (pjsua_var.buddy_cnt == 0) { 359 360 PJ_LOG(3,(THIS_FILE, " - no buddy list - ")); 361 362 } else { 363 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 364 365 if (pjsua_var.buddy[i].uri.slen == 0) 366 continue; 367 368 if (pjsua_var.buddy[i].sub) { 369 PJ_LOG(3,(THIS_FILE, " %10s %.*s", 370 pjsip_evsub_get_state_name(pjsua_var.buddy[i].sub), 371 (int)pjsua_var.buddy[i].uri.slen, 372 pjsua_var.buddy[i].uri.ptr)); 373 } else { 374 PJ_LOG(3,(THIS_FILE, " %10s %.*s", 375 "(null)", 376 (int)pjsua_var.buddy[i].uri.slen, 377 pjsua_var.buddy[i].uri.ptr)); 378 } 379 } 380 } 381 382 PJSUA_UNLOCK(); 383 } 384 385 386 /*************************************************************************** 387 * Server subscription. 35 388 */ 36 389 … … 61 414 static void pres_evsub_on_srv_state( pjsip_evsub *sub, pjsip_event *event) 62 415 { 63 pjsua_srv_pres *uapres = pjsip_evsub_get_mod_data(sub, pjsua.mod.id);416 pjsua_srv_pres *uapres; 64 417 65 418 PJ_UNUSED_ARG(event); 66 419 420 PJSUA_LOCK(); 421 422 uapres = pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 67 423 if (uapres) { 68 424 PJ_LOG(3,(THIS_FILE, "Server subscription to %s is %s", … … 70 426 71 427 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) { 72 pjsip_evsub_set_mod_data(sub, pjsua .mod.id, NULL);428 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL); 73 429 pj_list_erase(uapres); 74 430 } 75 431 } 432 433 PJSUA_UNLOCK(); 76 434 } 77 435 … … 81 439 static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) 82 440 { 83 int acc_i ndex;441 int acc_id; 84 442 pjsua_acc_config *acc_config; 85 443 pjsip_method *req_method = &rdata->msg_info.msg->line.req.method; … … 97 455 /* Incoming SUBSCRIBE: */ 98 456 457 PJSUA_LOCK(); 458 99 459 /* Find which account for the incoming request. */ 100 acc_i ndex= pjsua_acc_find_for_incoming(rdata);101 acc_config = &pjsua .config.acc_config[acc_index];460 acc_id = pjsua_acc_find_for_incoming(rdata); 461 acc_config = &pjsua_var.acc[acc_id].cfg; 102 462 103 463 /* Create UAS dialog: */ … … 109 469 "Unable to create UAS dialog for subscription", 110 470 status); 111 return PJ_FALSE; 471 PJSUA_UNLOCK(); 472 return PJ_TRUE; 112 473 } 113 474 … … 122 483 pjsua_perror(THIS_FILE, "Unable to create server subscription", 123 484 status); 124 return PJ_FALSE; 485 PJSUA_UNLOCK(); 486 return PJ_TRUE; 125 487 } 126 488 … … 136 498 uapres->remote[status] = '\0'; 137 499 138 pjsip_evsub_set_mod_data(sub, pjsua .mod.id, uapres);500 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, uapres); 139 501 140 502 /* Add server subscription to the list: */ 141 pj_list_push_back(&pjsua .acc[acc_index].pres_srv_list, uapres);503 pj_list_push_back(&pjsua_var.acc[acc_id].pres_srv_list, uapres); 142 504 143 505 … … 149 511 pj_list_erase(uapres); 150 512 pjsip_pres_terminate(sub, PJ_FALSE); 513 PJSUA_UNLOCK(); 151 514 return PJ_FALSE; 152 515 } … … 156 519 pj_memset(&pres_status, 0, sizeof(pres_status)); 157 520 pres_status.info_cnt = 1; 158 pres_status.info[0].basic_open = pjsua .acc[acc_index].online_status;159 //Both pjsua .local_uri and pjsua.contact_uri are enclosed in "<" and ">"521 pres_status.info[0].basic_open = pjsua_var.acc[acc_id].online_status; 522 //Both pjsua_var.local_uri and pjsua_var.contact_uri are enclosed in "<" and ">" 160 523 //causing XML parsing to fail. 161 //pres_status.info[0].contact = pjsua .local_uri;524 //pres_status.info[0].contact = pjsua_var.local_uri; 162 525 163 526 pjsip_pres_set_status(sub, &pres_status); … … 174 537 pj_list_erase(uapres); 175 538 pjsip_pres_terminate(sub, PJ_FALSE); 539 PJSUA_UNLOCK(); 176 540 return PJ_FALSE; 177 541 } … … 180 544 /* Done: */ 181 545 546 PJSUA_UNLOCK(); 547 182 548 return PJ_TRUE; 183 549 } 184 550 185 551 552 /* Terminate server subscription for the account */ 553 void pjsua_pres_delete_acc(int acc_id) 554 { 555 pjsua_srv_pres *uapres; 556 557 uapres = pjsua_var.acc[acc_id].pres_srv_list.next; 558 559 while (uapres != &pjsua_var.acc[acc_id].pres_srv_list) { 560 561 pjsip_pres_status pres_status; 562 pj_str_t reason = { "noresource", 10 }; 563 pjsip_tx_data *tdata; 564 565 pjsip_pres_get_status(uapres->sub, &pres_status); 566 567 pres_status.info[0].basic_open = pjsua_var.acc[acc_id].online_status; 568 pjsip_pres_set_status(uapres->sub, &pres_status); 569 570 if (pjsip_pres_notify(uapres->sub, 571 PJSIP_EVSUB_STATE_TERMINATED, NULL, 572 &reason, &tdata)==PJ_SUCCESS) 573 { 574 pjsip_pres_send_request(uapres->sub, tdata); 575 } 576 577 uapres = uapres->next; 578 } 579 } 580 581 186 582 /* Refresh subscription (e.g. when our online status has changed) */ 187 static void refresh_server_subscription(int acc_i ndex)583 static void refresh_server_subscription(int acc_id) 188 584 { 189 585 pjsua_srv_pres *uapres; 190 586 191 uapres = pjsua .acc[acc_index].pres_srv_list.next;192 193 while (uapres != &pjsua .acc[acc_index].pres_srv_list) {587 uapres = pjsua_var.acc[acc_id].pres_srv_list.next; 588 589 while (uapres != &pjsua_var.acc[acc_id].pres_srv_list) { 194 590 195 591 pjsip_pres_status pres_status; … … 197 593 198 594 pjsip_pres_get_status(uapres->sub, &pres_status); 199 if (pres_status.info[0].basic_open != pjsua .acc[acc_index].online_status) {200 pres_status.info[0].basic_open = pjsua .acc[acc_index].online_status;595 if (pres_status.info[0].basic_open != pjsua_var.acc[acc_id].online_status) { 596 pres_status.info[0].basic_open = pjsua_var.acc[acc_id].online_status; 201 597 pjsip_pres_set_status(uapres->sub, &pres_status); 202 598 203 if (pjsua.quit_flag) { 204 pj_str_t reason = { "noresource", 10 }; 205 if (pjsip_pres_notify(uapres->sub, 206 PJSIP_EVSUB_STATE_TERMINATED, NULL, 207 &reason, &tdata)==PJ_SUCCESS) 208 { 209 pjsip_pres_send_request(uapres->sub, tdata); 210 } 211 } else { 212 if (pjsip_pres_current_notify(uapres->sub, &tdata)==PJ_SUCCESS) 213 pjsip_pres_send_request(uapres->sub, tdata); 214 } 599 if (pjsip_pres_current_notify(uapres->sub, &tdata)==PJ_SUCCESS) 600 pjsip_pres_send_request(uapres->sub, tdata); 215 601 } 216 602 … … 221 607 222 608 223 /* ************************************************************************** 224 * THE FOLLOWING PART HANDLES CLIENT SUBSCRIPTION 225 * ************************************************************************** 609 /*************************************************************************** 610 * Client subscription. 226 611 */ 227 612 … … 233 618 PJ_UNUSED_ARG(event); 234 619 235 buddy = pjsip_evsub_get_mod_data(sub, pjsua.mod.id); 620 PJSUA_LOCK(); 621 622 buddy = pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 236 623 if (buddy) { 237 624 PJ_LOG(3,(THIS_FILE, 238 625 "Presence subscription to %.*s is %s", 239 (int)pjsua .config.buddy_uri[buddy->index].slen,240 pjsua .config.buddy_uri[buddy->index].ptr,626 (int)pjsua_var.buddy[buddy->index].uri.slen, 627 pjsua_var.buddy[buddy->index].uri.ptr, 241 628 pjsip_evsub_get_state_name(sub))); 242 629 … … 244 631 buddy->sub = NULL; 245 632 buddy->status.info_cnt = 0; 246 pjsip_evsub_set_mod_data(sub, pjsua .mod.id, NULL);633 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL); 247 634 } 248 635 249 636 /* Call callback */ 250 if (pjsua.cb.on_buddy_state) 251 (*pjsua.cb.on_buddy_state)(buddy->index); 252 } 253 } 637 if (pjsua_var.ua_cfg.cb.on_buddy_state) 638 (*pjsua_var.ua_cfg.cb.on_buddy_state)(buddy->index); 639 } 640 641 PJSUA_UNLOCK(); 642 } 643 644 645 /* Callback when transaction state has changed. */ 646 static void pjsua_evsub_on_tsx_state(pjsip_evsub *sub, 647 pjsip_transaction *tsx, 648 pjsip_event *event) 649 { 650 pjsua_buddy *buddy; 651 pjsip_contact_hdr *contact_hdr; 652 653 PJSUA_LOCK(); 654 655 buddy = pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 656 if (!buddy) { 657 PJSUA_UNLOCK(); 658 return; 659 } 660 661 /* We only use this to update buddy's Contact, when it's not 662 * set. 663 */ 664 if (buddy->contact.slen != 0) { 665 /* Contact already set */ 666 PJSUA_UNLOCK(); 667 return; 668 } 669 670 /* Only care about 2xx response to outgoing SUBSCRIBE */ 671 if (tsx->status_code/100 != 2 || 672 tsx->role != PJSIP_UAC_ROLE || 673 event->type != PJSIP_EVENT_RX_MSG || 674 pjsip_method_cmp(&tsx->method, &pjsip_subscribe_method)!=0) 675 { 676 PJSUA_UNLOCK(); 677 return; 678 } 679 680 /* Find contact header. */ 681 contact_hdr = pjsip_msg_find_hdr(event->body.rx_msg.rdata->msg_info.msg, 682 PJSIP_H_CONTACT, NULL); 683 if (!contact_hdr) { 684 PJSUA_UNLOCK(); 685 return; 686 } 687 688 buddy->contact.ptr = pj_pool_alloc(pjsua_var.pool, PJSIP_MAX_URL_SIZE); 689 buddy->contact.slen = pjsip_uri_print( PJSIP_URI_IN_CONTACT_HDR, 690 contact_hdr->uri, 691 buddy->contact.ptr, 692 PJSIP_MAX_URL_SIZE); 693 if (buddy->contact.slen < 0) 694 buddy->contact.slen = 0; 695 696 PJSUA_UNLOCK(); 697 } 698 254 699 255 700 /* Callback called when we receive NOTIFY */ … … 263 708 pjsua_buddy *buddy; 264 709 265 buddy = pjsip_evsub_get_mod_data(sub, pjsua.mod.id); 710 PJSUA_LOCK(); 711 712 buddy = pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 266 713 if (buddy) { 267 714 /* Update our info. */ … … 277 724 PJ_UNUSED_ARG(res_hdr); 278 725 PJ_UNUSED_ARG(p_body); 726 727 PJSUA_UNLOCK(); 279 728 } 280 729 … … 284 733 { 285 734 &pjsua_evsub_on_state, 286 287 NULL, /* on_tsx_state: don't care about transaction state. */ 735 &pjsua_evsub_on_tsx_state, 288 736 289 737 NULL, /* on_rx_refresh: don't care about SUBSCRIBE refresh, unless … … 305 753 static void subscribe_buddy_presence(unsigned index) 306 754 { 307 int acc_index; 308 pjsua_acc_config *acc_config; 755 pjsua_buddy *buddy; 756 int acc_id; 757 pjsua_acc *acc; 309 758 pjsip_dialog *dlg; 310 759 pjsip_tx_data *tdata; 311 760 pj_status_t status; 312 761 313 acc_index = pjsua_acc_find_for_outgoing(&pjsua.config.buddy_uri[index]); 314 315 acc_config = &pjsua.config.acc_config[acc_index]; 316 762 buddy = &pjsua_var.buddy[index]; 763 acc_id = pjsua_acc_find_for_outgoing(&buddy->uri); 764 765 acc = &pjsua_var.acc[acc_id]; 766 767 /* Create UAC dialog */ 317 768 status = pjsip_dlg_create_uac( pjsip_ua_instance(), 318 &acc _config->id,319 &acc _config->contact,320 & pjsua.config.buddy_uri[index],769 &acc->cfg.id, 770 &acc->cfg.contact, 771 &buddy->uri, 321 772 NULL, &dlg); 322 773 if (status != PJ_SUCCESS) { … … 326 777 } 327 778 328 if (acc_config->cred_count) { 779 /* Set route-set */ 780 if (!pj_list_empty(&acc->route_set)) { 781 pjsip_dlg_set_route_set(dlg, &acc->route_set); 782 } 783 784 /* Set credentials */ 785 if (acc->cred_cnt) { 329 786 pjsip_auth_clt_set_credentials( &dlg->auth_sess, 330 acc_config->cred_count, 331 acc_config->cred_info); 787 acc->cred_cnt, acc->cred); 332 788 } 333 789 334 790 status = pjsip_pres_create_uac( dlg, &pres_callback, 335 & pjsua.buddies[index].sub);791 &buddy->sub); 336 792 if (status != PJ_SUCCESS) { 337 pjsua .buddies[index].sub = NULL;793 pjsua_var.buddy[index].sub = NULL; 338 794 pjsua_perror(THIS_FILE, "Unable to create presence client", 339 795 status); … … 342 798 } 343 799 344 pjsip_evsub_set_mod_data(pjsua.buddies[index].sub, pjsua.mod.id, 345 &pjsua.buddies[index]); 346 347 status = pjsip_pres_initiate(pjsua.buddies[index].sub, -1, &tdata); 800 pjsip_evsub_set_mod_data(buddy->sub, pjsua_var.mod.id, buddy); 801 802 status = pjsip_pres_initiate(buddy->sub, -1, &tdata); 348 803 if (status != PJ_SUCCESS) { 349 pjsip_pres_terminate( pjsua.buddies[index].sub, PJ_FALSE);350 pjsua.buddies[index].sub = NULL;804 pjsip_pres_terminate(buddy->sub, PJ_FALSE); 805 buddy->sub = NULL; 351 806 pjsua_perror(THIS_FILE, "Unable to create initial SUBSCRIBE", 352 807 status); … … 354 809 } 355 810 356 status = pjsip_pres_send_request( pjsua.buddies[index].sub, tdata);811 status = pjsip_pres_send_request(buddy->sub, tdata); 357 812 if (status != PJ_SUCCESS) { 358 pjsip_pres_terminate( pjsua.buddies[index].sub, PJ_FALSE);359 pjsua.buddies[index].sub = NULL;813 pjsip_pres_terminate(buddy->sub, PJ_FALSE); 814 buddy->sub = NULL; 360 815 pjsua_perror(THIS_FILE, "Unable to send initial SUBSCRIBE", 361 816 status); … … 368 823 static void unsubscribe_buddy_presence(unsigned index) 369 824 { 825 pjsua_buddy *buddy; 370 826 pjsip_tx_data *tdata; 371 827 pj_status_t status; 372 828 373 if (pjsua.buddies[index].sub == NULL)374 return; 375 376 if (pjsip_evsub_get_state(pjsua.buddies[index].sub) == 377 PJSIP_EVSUB_STATE_TERMINATED) 378 {379 pjsua .buddies[index].sub = NULL;380 return; 381 } 382 383 status = pjsip_pres_initiate( pjsua.buddies[index].sub, 0, &tdata);829 buddy = &pjsua_var.buddy[index]; 830 831 if (buddy->sub == NULL) 832 return; 833 834 if (pjsip_evsub_get_state(buddy->sub) == PJSIP_EVSUB_STATE_TERMINATED) { 835 pjsua_var.buddy[index].sub = NULL; 836 return; 837 } 838 839 status = pjsip_pres_initiate( buddy->sub, 0, &tdata); 384 840 if (status == PJ_SUCCESS) 385 status = pjsip_pres_send_request( pjsua.buddies[index].sub, tdata );841 status = pjsip_pres_send_request( buddy->sub, tdata ); 386 842 387 843 if (status != PJ_SUCCESS) { 388 389 pjsip_pres_terminate(pjsua.buddies[index].sub, PJ_FALSE); 390 pjsua.buddies[index].sub = NULL; 844 pjsip_pres_terminate(buddy->sub, PJ_FALSE); 845 buddy->sub = NULL; 391 846 pjsua_perror(THIS_FILE, "Unable to unsubscribe presence", 392 847 status); … … 396 851 397 852 /* It does what it says.. */ 398 static void refresh_client_subscription (void)853 static void refresh_client_subscriptions(void) 399 854 { 400 855 unsigned i; 401 856 402 for (i=0; i<pjsua.config.buddy_cnt; ++i) { 403 404 if (pjsua.buddies[i].monitor && !pjsua.buddies[i].sub) { 857 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 858 859 if (!pjsua_var.buddy[i].uri.slen) 860 continue; 861 862 if (pjsua_var.buddy[i].monitor && !pjsua_var.buddy[i].sub) { 405 863 subscribe_buddy_presence(i); 406 864 407 } else if (!pjsua .buddies[i].monitor && pjsua.buddies[i].sub) {865 } else if (!pjsua_var.buddy[i].monitor && pjsua_var.buddy[i].sub) { 408 866 unsubscribe_buddy_presence(i); 409 867 … … 418 876 pj_status_t pjsua_pres_init() 419 877 { 878 unsigned i; 420 879 pj_status_t status; 421 880 422 status = pjsip_endpt_register_module( pjsua .endpt, &mod_pjsua_pres);881 status = pjsip_endpt_register_module( pjsua_var.endpt, &mod_pjsua_pres); 423 882 if (status != PJ_SUCCESS) { 424 883 pjsua_perror(THIS_FILE, "Unable to register pjsua presence module", … … 426 885 } 427 886 887 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 888 reset_buddy(i); 889 } 890 428 891 return status; 429 892 } 430 893 431 /* 432 * Get buddy count. 433 */ 434 PJ_DEF(unsigned) pjsua_get_buddy_count(void) 435 { 436 return pjsua.config.buddy_cnt; 437 } 438 439 440 /** 441 * Get buddy info. 442 */ 443 PJ_DEF(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id index, 444 pjsua_buddy_info *info) 445 { 446 pjsua_buddy *buddy; 447 448 PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri), 449 PJ_EINVAL); 450 451 pj_memset(info, 0, sizeof(pjsua_buddy_info)); 452 453 buddy = &pjsua.buddies[index]; 454 info->index = buddy->index; 455 info->is_valid = pjsua.config.buddy_uri[index].slen; 456 if (!info->is_valid) 457 return PJ_SUCCESS; 458 459 info->name = buddy->name; 460 info->display_name = buddy->display; 461 info->host = buddy->host; 462 info->port = buddy->port; 463 info->uri = pjsua.config.buddy_uri[index]; 464 465 if (buddy->sub == NULL || buddy->status.info_cnt==0) { 466 info->status = PJSUA_BUDDY_STATUS_UNKNOWN; 467 info->status_text = pj_str("?"); 468 } else if (pjsua.buddies[index].status.info[0].basic_open) { 469 info->status = PJSUA_BUDDY_STATUS_ONLINE; 470 info->status_text = pj_str("Online"); 471 } else { 472 info->status = PJSUA_BUDDY_STATUS_OFFLINE; 473 info->status_text = pj_str("Offline"); 474 } 475 894 895 /* 896 * Start presence subsystem. 897 */ 898 pj_status_t pjsua_pres_start(void) 899 { 900 /* Nothing to do (is it?) */ 476 901 return PJ_SUCCESS; 477 902 } 478 903 479 904 480 /** 481 * Add new buddy. 482 */ 483 PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri, 484 pjsua_buddy_id *buddy_index) 485 { 486 pjsip_name_addr *url; 487 pjsip_sip_uri *sip_uri; 488 int index; 489 pj_str_t tmp; 490 491 PJ_ASSERT_RETURN(pjsua.config.buddy_cnt <= 492 PJ_ARRAY_SIZE(pjsua.config.buddy_uri), 493 PJ_ETOOMANY); 494 495 /* Find empty slot */ 496 for (index=0; index<PJ_ARRAY_SIZE(pjsua.config.buddy_uri); ++index) { 497 if (pjsua.config.buddy_uri[index].slen == 0) 498 break; 499 } 500 501 /* Expect to find an empty slot */ 502 PJ_ASSERT_RETURN(index < PJ_ARRAY_SIZE(pjsua.config.buddy_uri), 503 PJ_ETOOMANY); 504 505 506 /* Get name and display name for buddy */ 507 pj_strdup_with_null(pjsua.pool, &tmp, uri); 508 url = (pjsip_name_addr*)pjsip_parse_uri(pjsua.pool, tmp.ptr, tmp.slen, 509 PJSIP_PARSE_URI_AS_NAMEADDR); 510 511 if (url == NULL) 512 return PJSIP_EINVALIDURI; 513 514 /* Save URI */ 515 pjsua.config.buddy_uri[index] = tmp; 516 517 sip_uri = (pjsip_sip_uri*) url->uri; 518 pjsua.buddies[index].name = sip_uri->user; 519 pjsua.buddies[index].display = url->display; 520 pjsua.buddies[index].host = sip_uri->host; 521 pjsua.buddies[index].port = sip_uri->port; 522 if (pjsua.buddies[index].port == 0) 523 pjsua.buddies[index].port = 5060; 524 525 if (buddy_index) 526 *buddy_index = index; 527 528 pjsua.config.buddy_cnt++; 529 530 return PJ_SUCCESS; 531 } 532 533 534 535 /** 536 * Delete buddy. 537 */ 538 PJ_DEF(pj_status_t) pjsua_buddy_del(pjsua_buddy_id index) 539 { 540 PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri), 541 PJ_EINVAL); 542 543 if (pjsua.config.buddy_uri[index].slen == 0) 544 return PJ_SUCCESS; 545 546 /* Unsubscribe presence */ 547 pjsua_buddy_subscribe_pres(index, PJ_FALSE); 548 549 /* Remove buddy */ 550 pjsua.config.buddy_uri[index].slen = 0; 551 pjsua.config.buddy_cnt--; 552 553 return PJ_SUCCESS; 554 } 555 556 557 PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( pjsua_buddy_id index, 558 pj_bool_t monitor) 559 { 560 pjsua_buddy *buddy; 561 562 PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri), 563 PJ_EINVAL); 564 565 buddy = &pjsua.buddies[index]; 566 buddy->monitor = monitor; 905 /* 906 * Refresh presence subscriptions 907 */ 908 void pjsua_pres_refresh() 909 { 910 unsigned i; 911 912 refresh_client_subscriptions(); 913 914 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { 915 if (pjsua_var.acc[i].valid) 916 refresh_server_subscription(i); 917 } 918 } 919 920 921 /* 922 * Shutdown presence. 923 */ 924 void pjsua_pres_shutdown(void) 925 { 926 unsigned i; 927 928 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { 929 if (!pjsua_var.acc[i].valid) 930 continue; 931 pjsua_pres_delete_acc(i); 932 } 933 934 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 935 pjsua_var.buddy[i].monitor = 0; 936 } 937 567 938 pjsua_pres_refresh(); 568 return PJ_SUCCESS; 569 } 570 571 572 PJ_DEF(pj_status_t) pjsua_acc_set_online_status( pjsua_acc_id acc_index, 573 pj_bool_t is_online) 574 { 575 PJ_ASSERT_RETURN(acc_index < (int)PJ_ARRAY_SIZE(pjsua.acc), 576 PJ_EINVAL); 577 PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP); 578 579 pjsua.acc[acc_index].online_status = is_online; 580 pjsua_pres_refresh(); 581 return PJ_SUCCESS; 582 } 583 584 585 /* 586 * Refresh presence 587 */ 588 PJ_DEF(void) pjsua_pres_refresh() 589 { 590 unsigned i; 591 592 refresh_client_subscription(); 593 594 for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) 595 refresh_server_subscription(i); 596 } 597 598 599 /* 600 * Shutdown presence. 601 */ 602 void pjsua_pres_shutdown(void) 603 { 604 unsigned acc_index; 605 unsigned i; 606 607 for (acc_index=0; acc_index<(int)pjsua.config.acc_cnt; ++acc_index) { 608 pjsua.acc[acc_index].online_status = 0; 609 } 610 611 for (i=0; i<pjsua.config.buddy_cnt; ++i) { 612 pjsua.buddies[i].monitor = 0; 613 } 614 615 pjsua_pres_refresh(); 616 } 617 618 /* 619 * Dump presence status. 620 */ 621 void pjsua_pres_dump(pj_bool_t detail) 622 { 623 unsigned acc_index; 624 unsigned i; 625 626 627 /* 628 * When no detail is required, just dump number of server and client 629 * subscriptions. 630 */ 631 if (detail == PJ_FALSE) { 632 633 int count = 0; 634 635 for (acc_index=0; acc_index < (int)pjsua.config.acc_cnt; ++acc_index) { 636 637 if (!pj_list_empty(&pjsua.acc[acc_index].pres_srv_list)) { 638 struct pjsua_srv_pres *uapres; 639 640 uapres = pjsua.acc[acc_index].pres_srv_list.next; 641 while (uapres != &pjsua.acc[acc_index].pres_srv_list) { 642 ++count; 643 uapres = uapres->next; 644 } 645 } 646 } 647 648 PJ_LOG(3,(THIS_FILE, "Number of server/UAS subscriptions: %d", 649 count)); 650 651 count = 0; 652 653 for (i=0; i<pjsua.config.buddy_cnt; ++i) { 654 if (pjsua.buddies[i].sub) { 655 ++count; 656 } 657 } 658 659 PJ_LOG(3,(THIS_FILE, "Number of client/UAC subscriptions: %d", 660 count)); 661 return; 662 } 663 664 665 /* 666 * Dumping all server (UAS) subscriptions 667 */ 668 PJ_LOG(3,(THIS_FILE, "Dumping pjsua server subscriptions:")); 669 670 for (acc_index=0; acc_index < (int)pjsua.config.acc_cnt; ++acc_index) { 671 672 PJ_LOG(3,(THIS_FILE, " %.*s", 673 (int)pjsua.config.acc_config[acc_index].id.slen, 674 pjsua.config.acc_config[acc_index].id.ptr)); 675 676 if (pj_list_empty(&pjsua.acc[acc_index].pres_srv_list)) { 677 678 PJ_LOG(3,(THIS_FILE, " - none - ")); 679 680 } else { 681 struct pjsua_srv_pres *uapres; 682 683 uapres = pjsua.acc[acc_index].pres_srv_list.next; 684 while (uapres != &pjsua.acc[acc_index].pres_srv_list) { 685 686 PJ_LOG(3,(THIS_FILE, " %10s %s", 687 pjsip_evsub_get_state_name(uapres->sub), 688 uapres->remote)); 689 690 uapres = uapres->next; 691 } 692 } 693 } 694 695 /* 696 * Dumping all client (UAC) subscriptions 697 */ 698 PJ_LOG(3,(THIS_FILE, "Dumping pjsua client subscriptions:")); 699 700 if (pjsua.config.buddy_cnt == 0) { 701 702 PJ_LOG(3,(THIS_FILE, " - no buddy list - ")); 703 704 } else { 705 for (i=0; i<pjsua.config.buddy_cnt; ++i) { 706 707 if (pjsua.buddies[i].sub) { 708 PJ_LOG(3,(THIS_FILE, " %10s %.*s", 709 pjsip_evsub_get_state_name(pjsua.buddies[i].sub), 710 (int)pjsua.config.buddy_uri[i].slen, 711 pjsua.config.buddy_uri[i].ptr)); 712 } else { 713 PJ_LOG(3,(THIS_FILE, " %10s %.*s", 714 "(null)", 715 (int)pjsua.config.buddy_uri[i].slen, 716 pjsua.config.buddy_uri[i].ptr)); 717 } 718 } 719 } 720 } 721 939 }
Note: See TracChangeset
for help on using the changeset viewer.