- Timestamp:
- Oct 20, 2009 1:56:26 PM (15 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
r2907 r2956 2620 2620 pjsua_buddy_get_info(buddy_id, &info); 2621 2621 2622 PJ_LOG(3,(THIS_FILE, "%.*s status is %.*s (subscription state is %s)", 2622 PJ_LOG(3,(THIS_FILE, "%.*s status is %.*s, subscription state is %s " 2623 "(last termination reason code=%d %.*s)", 2623 2624 (int)info.uri.slen, 2624 2625 info.uri.ptr, 2625 2626 (int)info.status_text.slen, 2626 2627 info.status_text.ptr, 2627 info.sub_state_name)); 2628 info.sub_state_name, 2629 info.sub_term_code, 2630 (int)info.sub_term_reason.slen, 2631 info.sub_term_reason.ptr)); 2628 2632 } 2629 2633 -
pjproject/trunk/pjsip/include/pjsip_simple.h
r2394 r2956 36 36 37 37 #include <pjsip-simple/evsub.h> 38 #include <pjsip-simple/evsub_msg.h> 38 39 #include <pjsip-simple/iscomposing.h> 39 40 #include <pjsip-simple/presence.h> -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r2943 r2956 1398 1398 1399 1399 /** 1400 * Schedule a timer entry. Note that the timer callback may be executed 1401 * by different thread, depending on whether worker thread is enabled or 1402 * not. 1403 * 1404 * @param entry Timer heap entry. 1405 * @param delay The interval to expire. 1406 * 1407 * @return PJ_SUCCESS on success, or the appropriate error code. 1408 * 1409 * @see pjsip_endpt_schedule_timer() 1410 */ 1411 PJ_DECL(pj_status_t) pjsua_schedule_timer(pj_timer_entry *entry, 1412 const pj_time_val *delay); 1413 1414 1415 /** 1416 * Cancel the previously scheduled timer. 1417 * 1418 * @param entry Timer heap entry. 1419 * 1420 * @see pjsip_endpt_cancel_timer() 1421 */ 1422 PJ_DECL(void) pjsua_cancel_timer(pj_timer_entry *entry); 1423 1424 1425 /** 1400 1426 * This is a utility function to display error message for the specified 1401 1427 * error code. The error message will be sent to the log. … … 3129 3155 3130 3156 /** 3131 * Specifies the last presence subscription terminatino reason. If 3157 * Specifies the last presence subscription termination code. This would 3158 * return the last status of the SUBSCRIBE request. If the subscription 3159 * is terminated with NOTIFY by the server, this value will be set to 3160 * 200, and subscription termination reason will be given in the 3161 * \a sub_term_reason field. 3162 */ 3163 unsigned sub_term_code; 3164 3165 /** 3166 * Specifies the last presence subscription termination reason. If 3132 3167 * presence subscription is currently active, the value will be empty. 3133 3168 */ -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
r2945 r2956 186 186 pjsip_dialog *dlg; /**< The underlying dialog. */ 187 187 pjsip_evsub *sub; /**< Buddy presence subscription */ 188 unsigned term_code; /**< Subscription termination code */ 188 189 pj_str_t term_reason;/**< Subscription termination reason */ 189 190 pjsip_pres_status status; /**< Buddy presence status. */ 190 191 pj_timer_entry timer; /**< Resubscription timer */ 191 192 } pjsua_buddy; 192 193 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r2949 r2956 2319 2319 } 2320 2320 2321 /* 2322 * Schedule a timer entry. 2323 */ 2324 PJ_DEF(pj_status_t) pjsua_schedule_timer( pj_timer_entry *entry, 2325 const pj_time_val *delay) 2326 { 2327 return pjsip_endpt_schedule_timer(pjsua_var.endpt, entry, delay); 2328 } 2329 2330 /* 2331 * Cancel the previously scheduled timer. 2332 * 2333 */ 2334 PJ_DEF(void) pjsua_cancel_timer(pj_timer_entry *entry) 2335 { 2336 pjsip_endpt_cancel_timer(pjsua_var.endpt, entry); 2337 } 2321 2338 2322 2339 /** -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
r2943 r2956 25 25 26 26 27 static void subscribe_buddy_presence(unsigned index); 27 static void subscribe_buddy_presence(pjsua_buddy_id buddy_id); 28 static void unsubscribe_buddy_presence(pjsua_buddy_id buddy_id); 28 29 29 30 … … 31 32 * Find buddy. 32 33 */ 33 static pjsua_buddy_id pjsua_find_buddy(const pjsip_uri *uri)34 static pjsua_buddy_id find_buddy(const pjsip_uri *uri) 34 35 { 35 36 const pjsip_sip_uri *sip_uri; … … 61 62 } 62 63 64 #define LOCK_DIALOG 1 65 #define LOCK_PJSUA 2 66 #define LOCK_ALL (LOCK_DIALOG | LOCK_PJSUA) 67 68 /* Buddy lock object */ 69 struct buddy_lock 70 { 71 pjsua_buddy *buddy; 72 pjsip_dialog *dlg; 73 pj_uint8_t flag; 74 }; 75 76 /* Acquire lock to the specified buddy_id */ 77 pj_status_t lock_buddy(const char *title, 78 pjsua_buddy_id buddy_id, 79 struct buddy_lock *lck, 80 unsigned _unused_) 81 { 82 enum { MAX_RETRY=50 }; 83 pj_bool_t has_pjsua_lock = PJ_FALSE; 84 unsigned retry; 85 86 PJ_UNUSED_ARG(_unused_); 87 88 pj_bzero(lck, sizeof(*lck)); 89 90 for (retry=0; retry<MAX_RETRY; ++retry) { 91 92 if (PJSUA_TRY_LOCK() != PJ_SUCCESS) { 93 pj_thread_sleep(retry/10); 94 continue; 95 } 96 97 has_pjsua_lock = PJ_TRUE; 98 lck->flag = LOCK_PJSUA; 99 lck->buddy = &pjsua_var.buddy[buddy_id]; 100 101 if (lck->buddy->dlg == NULL) 102 return PJ_SUCCESS; 103 104 if (pjsip_dlg_try_inc_lock(lck->buddy->dlg) != PJ_SUCCESS) { 105 lck->flag = 0; 106 lck->buddy = NULL; 107 has_pjsua_lock = PJ_FALSE; 108 PJSUA_UNLOCK(); 109 pj_thread_sleep(retry/10); 110 continue; 111 } 112 113 lck->dlg = lck->buddy->dlg; 114 lck->flag = LOCK_DIALOG; 115 PJSUA_UNLOCK(); 116 117 break; 118 } 119 120 if (lck->flag == 0) { 121 if (has_pjsua_lock == PJ_FALSE) 122 PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire PJSUA mutex " 123 "(possibly system has deadlocked) in %s", 124 title)); 125 else 126 PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire dialog mutex " 127 "(possibly system has deadlocked) in %s", 128 title)); 129 return PJ_ETIMEDOUT; 130 } 131 132 return PJ_SUCCESS; 133 } 134 135 /* Release buddy lock */ 136 static void unlock_buddy(struct buddy_lock *lck) 137 { 138 if (lck->flag & LOCK_DIALOG) 139 pjsip_dlg_dec_lock(lck->dlg); 140 141 if (lck->flag & LOCK_PJSUA) 142 PJSUA_UNLOCK(); 143 } 144 63 145 64 146 /* … … 87 169 if (!uri) 88 170 buddy_id = PJSUA_INVALID_ID; 89 else 90 buddy_id = pjsua_find_buddy(uri); 171 else { 172 PJSUA_LOCK(); 173 buddy_id = find_buddy(uri); 174 PJSUA_UNLOCK(); 175 } 91 176 92 177 pj_pool_release(pool); … … 140 225 { 141 226 unsigned total=0; 227 struct buddy_lock lck; 142 228 pjsua_buddy *buddy; 143 144 PJ_ASSERT_RETURN(buddy_id>=0 && 145 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 146 PJ_EINVAL); 147 148 PJSUA_LOCK(); 229 pj_status_t status; 230 231 PJ_ASSERT_RETURN(pjsua_buddy_is_valid(buddy_id), PJ_EINVAL); 149 232 150 233 pj_bzero(info, sizeof(pjsua_buddy_info)); 151 234 152 buddy = &pjsua_var.buddy[buddy_id]; 235 status = lock_buddy("pjsua_buddy_get_info()", buddy_id, &lck, 0); 236 if (status != PJ_SUCCESS) 237 return status; 238 239 buddy = lck.buddy; 153 240 info->id = buddy->index; 154 241 if (pjsua_var.buddy[buddy_id].uri.slen == 0) { 155 PJSUA_UNLOCK();242 unlock_buddy(&lck); 156 243 return PJ_SUCCESS; 157 244 } … … 187 274 } else { 188 275 info->status = PJSUA_BUDDY_STATUS_OFFLINE; 189 info->status_text = pj_str("Offline"); 276 info->rpid = buddy->status.info[0].rpid; 277 278 if (info->rpid.note.slen) 279 info->status_text = info->rpid.note; 280 else 281 info->status_text = pj_str("Offline"); 190 282 } 191 283 … … 194 286 195 287 /* subscription state and termination reason */ 288 info->sub_term_code = buddy->term_code; 196 289 if (buddy->sub) { 197 290 info->sub_state = pjsip_evsub_get_state(buddy->sub); … … 219 312 } 220 313 221 PJSUA_UNLOCK();314 unlock_buddy(&lck); 222 315 return PJ_SUCCESS; 223 316 } … … 229 322 void *user_data) 230 323 { 231 PJ_ASSERT_RETURN(buddy_id>=0 && 232 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 233 PJ_EINVAL); 234 235 PJSUA_LOCK(); 324 struct buddy_lock lck; 325 pj_status_t status; 326 327 PJ_ASSERT_RETURN(pjsua_buddy_is_valid(buddy_id), PJ_EINVAL); 328 329 status = lock_buddy("pjsua_buddy_set_user_data()", buddy_id, &lck, 0); 330 if (status != PJ_SUCCESS) 331 return status; 236 332 237 333 pjsua_var.buddy[buddy_id].user_data = user_data; 238 334 239 PJSUA_UNLOCK();335 unlock_buddy(&lck); 240 336 241 337 return PJ_SUCCESS; … … 248 344 PJ_DEF(void*) pjsua_buddy_get_user_data(pjsua_buddy_id buddy_id) 249 345 { 346 struct buddy_lock lck; 347 pj_status_t status; 250 348 void *user_data; 251 349 252 PJ_ASSERT_RETURN( buddy_id>=0 &&253 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 254 NULL);255 256 PJSUA_LOCK();350 PJ_ASSERT_RETURN(pjsua_buddy_is_valid(buddy_id), NULL); 351 352 status = lock_buddy("pjsua_buddy_get_user_data()", buddy_id, &lck, 0); 353 if (status != PJ_SUCCESS) 354 return NULL; 257 355 258 356 user_data = pjsua_var.buddy[buddy_id].user_data; 259 357 260 PJSUA_UNLOCK();358 unlock_buddy(&lck); 261 359 262 360 return user_data; … … 383 481 PJ_DEF(pj_status_t) pjsua_buddy_del(pjsua_buddy_id buddy_id) 384 482 { 483 struct buddy_lock lck; 484 pj_status_t status; 485 385 486 PJ_ASSERT_RETURN(buddy_id>=0 && 386 487 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), … … 391 492 } 392 493 494 status = lock_buddy("pjsua_buddy_del()", buddy_id, &lck, 0); 495 if (status != PJ_SUCCESS) 496 return status; 497 393 498 /* Unsubscribe presence */ 394 499 pjsua_buddy_subscribe_pres(buddy_id, PJ_FALSE); 395 396 PJSUA_LOCK();397 500 398 501 /* Not interested with further events for this buddy */ … … 409 512 reset_buddy(buddy_id); 410 513 411 PJSUA_UNLOCK();514 unlock_buddy(&lck); 412 515 return PJ_SUCCESS; 413 516 } … … 420 523 pj_bool_t subscribe) 421 524 { 422 pjsua_buddy *buddy; 423 424 PJ_ASSERT_RETURN(buddy_id>=0 && 425 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 426 PJ_EINVAL); 427 428 PJSUA_LOCK(); 429 430 buddy = &pjsua_var.buddy[buddy_id]; 431 buddy->monitor = subscribe; 432 433 PJSUA_UNLOCK(); 434 435 pjsua_pres_refresh(); 436 525 struct buddy_lock lck; 526 pj_status_t status; 527 528 PJ_ASSERT_RETURN(pjsua_buddy_is_valid(buddy_id), PJ_EINVAL); 529 530 status = lock_buddy("pjsua_buddy_subscribe_pres()", buddy_id, &lck, 0); 531 if (status != PJ_SUCCESS) 532 return status; 533 534 lck.buddy->monitor = subscribe; 535 536 pjsua_buddy_update_pres(buddy_id); 537 538 unlock_buddy(&lck); 437 539 return PJ_SUCCESS; 438 540 } … … 444 546 PJ_DEF(pj_status_t) pjsua_buddy_update_pres(pjsua_buddy_id buddy_id) 445 547 { 446 pjsua_buddy *buddy;447 448 PJ_ASSERT_RETURN(buddy_id>=0 && 449 buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), 450 PJ_EINVAL); 451 452 PJSUA_LOCK();453 454 buddy = &pjsua_var.buddy[buddy_id]; 455 456 /* Return error if buddy's presence monitoring is not enabled */457 if (!buddy->monitor) { 458 PJSUA_UNLOCK();459 return PJ_ EINVALIDOP;548 struct buddy_lock lck; 549 pj_status_t status; 550 551 PJ_ASSERT_RETURN(pjsua_buddy_is_valid(buddy_id), PJ_EINVAL); 552 553 status = lock_buddy("pjsua_buddy_update_pres()", buddy_id, &lck, 0); 554 if (status != PJ_SUCCESS) 555 return status; 556 557 /* Is this an unsubscribe request? */ 558 if (!lck.buddy->monitor) { 559 unsubscribe_buddy_presence(buddy_id); 560 unlock_buddy(&lck); 561 return PJ_SUCCESS; 460 562 } 461 563 462 564 /* Ignore if presence is already active for the buddy */ 463 if ( buddy->sub) {464 PJSUA_UNLOCK();565 if (lck.buddy->sub) { 566 unlock_buddy(&lck); 465 567 return PJ_SUCCESS; 466 568 } … … 469 571 subscribe_buddy_presence(buddy_id); 470 572 471 PJSUA_UNLOCK();573 unlock_buddy(&lck); 472 574 473 575 return PJ_SUCCESS; … … 806 908 pjsua_buddy_id buddy_id; 807 909 808 buddy_id = pjsua_find_buddy(rdata->msg_info.from->uri);910 buddy_id = find_buddy(rdata->msg_info.from->uri); 809 911 810 912 (*pjsua_var.ua_cfg.cb.on_incoming_subscribe)(acc_id, uapres, buddy_id, … … 952 1054 953 1055 /* Subscribe to buddy's presence if we're not subscribed */ 954 buddy_id = pjsua_find_buddy(srv_pres->dlg->remote.info->uri);1056 buddy_id = find_buddy(srv_pres->dlg->remote.info->uri); 955 1057 if (buddy_id != PJSUA_INVALID_ID) { 956 1058 pjsua_buddy *b = &pjsua_var.buddy[buddy_id]; … … 1281 1383 */ 1282 1384 1385 static void buddy_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry) 1386 { 1387 pjsua_buddy *buddy = (pjsua_buddy*)entry->user_data; 1388 1389 PJ_UNUSED_ARG(th); 1390 1391 entry->id = PJ_FALSE; 1392 pjsua_buddy_update_pres(buddy->index); 1393 } 1394 1395 /* Reschedule subscription refresh timer or terminate the subscription 1396 * refresh timer for the specified buddy. 1397 */ 1398 static void buddy_resubscribe(pjsua_buddy *buddy, pj_bool_t resched, 1399 unsigned msec_interval) 1400 { 1401 if (buddy->timer.id) { 1402 pjsua_cancel_timer(&buddy->timer); 1403 buddy->timer.id = PJ_FALSE; 1404 } 1405 1406 if (resched) { 1407 pj_time_val delay; 1408 1409 pj_timer_entry_init(&buddy->timer, 0, buddy, &buddy_timer_cb); 1410 delay.sec = 0; 1411 delay.msec = msec_interval; 1412 pj_time_val_normalize(&delay); 1413 1414 if (pjsua_schedule_timer(&buddy->timer, &delay)==PJ_SUCCESS) 1415 buddy->timer.id = PJ_TRUE; 1416 } 1417 } 1418 1283 1419 /* Callback called when *client* subscription state has changed. */ 1284 1420 static void pjsua_evsub_on_state( pjsip_evsub *sub, pjsip_event *event) … … 1288 1424 PJ_UNUSED_ARG(event); 1289 1425 1290 PJSUA_LOCK(); 1291 1426 /* Note: #937: no need to acuire PJSUA_LOCK here. Since the buddy has 1427 * a dialog attached to it, lock_buddy() will use the dialog 1428 * lock, which we are currently holding! 1429 */ 1292 1430 buddy = (pjsua_buddy*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 1293 1431 if (buddy) { … … 1299 1437 1300 1438 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) { 1439 int resub_delay = -1; 1440 1301 1441 if (buddy->term_reason.ptr == NULL) { 1302 1442 buddy->term_reason.ptr = (char*) … … 1307 1447 pjsip_evsub_get_termination_reason(sub), 1308 1448 PJSUA_BUDDY_SUB_TERM_REASON_LEN); 1449 1450 buddy->term_code = 200; 1451 1452 /* Determine whether to resubscribe automatically */ 1453 if (event->type==PJSIP_EVENT_TSX_STATE) { 1454 const pjsip_transaction *tsx = event->body.tsx_state.tsx; 1455 if (pjsip_method_cmp(&tsx->method, 1456 &pjsip_subscribe_method)==0) 1457 { 1458 buddy->term_code = tsx->status_code; 1459 switch (tsx->status_code) { 1460 case PJSIP_SC_CALL_TSX_DOES_NOT_EXIST: 1461 /* 481: we refreshed too late? resubscribe 1462 * immediately. 1463 */ 1464 resub_delay = 500; 1465 break; 1466 } 1467 } else if (pjsip_method_cmp(&tsx->method, 1468 &pjsip_notify_method)==0) 1469 { 1470 if (pj_stricmp2(&buddy->term_reason, "deactivated")==0 || 1471 pj_stricmp2(&buddy->term_reason, "timeout")==0) { 1472 /* deactivated: The subscription has been terminated, 1473 * but the subscriber SHOULD retry immediately with 1474 * a new subscription. 1475 */ 1476 /* timeout: The subscription has been terminated 1477 * because it was not refreshed before it expired. 1478 * Clients MAY re-subscribe immediately. The 1479 * "retry-after" parameter has no semantics for 1480 * "timeout". 1481 */ 1482 resub_delay = 500; 1483 } 1484 else if (pj_stricmp2(&buddy->term_reason, "probation")==0|| 1485 pj_stricmp2(&buddy->term_reason, "giveup")==0) { 1486 /* probation: The subscription has been terminated, 1487 * but the client SHOULD retry at some later time. 1488 * If a "retry-after" parameter is also present, the 1489 * client SHOULD wait at least the number of seconds 1490 * specified by that parameter before attempting to re- 1491 * subscribe. 1492 */ 1493 /* giveup: The subscription has been terminated because 1494 * the notifier could not obtain authorization in a 1495 * timely fashion. If a "retry-after" parameter is 1496 * also present, the client SHOULD wait at least the 1497 * number of seconds specified by that parameter before 1498 * attempting to re-subscribe; otherwise, the client 1499 * MAY retry immediately, but will likely get put back 1500 * into pending state. 1501 */ 1502 const pjsip_sub_state_hdr *sub_hdr; 1503 pj_str_t sub_state = { "Subscription-State", 18 }; 1504 const pjsip_msg *msg; 1505 1506 msg = event->body.tsx_state.src.rdata->msg_info.msg; 1507 sub_hdr = (const pjsip_sub_state_hdr*) 1508 pjsip_msg_find_hdr_by_name(msg, &sub_state, 1509 NULL); 1510 if (sub_hdr && sub_hdr->retry_after > 0) 1511 resub_delay = sub_hdr->retry_after * 1000; 1512 } 1513 1514 } 1515 } 1516 1517 /* For other cases of subscription termination, if resubscribe 1518 * timer is not set, schedule with default expiration (plus minus 1519 * some random value, to avoid sending SUBSCRIBEs all at once) 1520 */ 1521 if (resub_delay == -1) { 1522 pj_assert(PJSUA_PRES_TIMER >= 3); 1523 resub_delay = PJSUA_PRES_TIMER*1000 - 2500 + (pj_rand()%5000); 1524 } 1525 1526 buddy_resubscribe(buddy, PJ_TRUE, resub_delay); 1527 1309 1528 } else { 1529 buddy->term_code = 0; 1310 1530 buddy->term_reason.slen = 0; 1311 1531 } … … 1319 1539 buddy->sub = NULL; 1320 1540 buddy->status.info_cnt = 0; 1541 buddy->dlg = NULL; 1321 1542 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL); 1322 1543 } 1323 1544 } 1324 1325 PJSUA_UNLOCK();1326 1545 } 1327 1546 … … 1335 1554 pjsip_contact_hdr *contact_hdr; 1336 1555 1337 PJSUA_LOCK(); 1338 1556 /* Note: #937: no need to acuire PJSUA_LOCK here. Since the buddy has 1557 * a dialog attached to it, lock_buddy() will use the dialog 1558 * lock, which we are currently holding! 1559 */ 1339 1560 buddy = (pjsua_buddy*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 1340 1561 if (!buddy) { 1341 PJSUA_UNLOCK();1342 1562 return; 1343 1563 } … … 1348 1568 if (buddy->contact.slen != 0) { 1349 1569 /* Contact already set */ 1350 PJSUA_UNLOCK();1351 1570 return; 1352 1571 } … … 1358 1577 pjsip_method_cmp(&tsx->method, pjsip_get_subscribe_method())!=0) 1359 1578 { 1360 PJSUA_UNLOCK();1361 1579 return; 1362 1580 } … … 1367 1585 PJSIP_H_CONTACT, NULL); 1368 1586 if (!contact_hdr) { 1369 PJSUA_UNLOCK();1370 1587 return; 1371 1588 } … … 1379 1596 if (buddy->contact.slen < 0) 1380 1597 buddy->contact.slen = 0; 1381 1382 PJSUA_UNLOCK();1383 1598 } 1384 1599 … … 1394 1609 pjsua_buddy *buddy; 1395 1610 1396 PJSUA_LOCK(); 1397 1611 /* Note: #937: no need to acuire PJSUA_LOCK here. Since the buddy has 1612 * a dialog attached to it, lock_buddy() will use the dialog 1613 * lock, which we are currently holding! 1614 */ 1398 1615 buddy = (pjsua_buddy*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 1399 1616 if (buddy) { … … 1410 1627 PJ_UNUSED_ARG(res_hdr); 1411 1628 PJ_UNUSED_ARG(p_body); 1412 1413 PJSUA_UNLOCK();1414 1629 } 1415 1630 … … 1437 1652 1438 1653 /* It does what it says.. */ 1439 static void subscribe_buddy_presence( unsigned index)1654 static void subscribe_buddy_presence(pjsua_buddy_id buddy_id) 1440 1655 { 1441 1656 pj_pool_t *tmp_pool = NULL; … … 1447 1662 pj_status_t status; 1448 1663 1449 buddy = &pjsua_var.buddy[ index];1664 buddy = &pjsua_var.buddy[buddy_id]; 1450 1665 acc_id = pjsua_acc_find_for_outgoing(&buddy->uri); 1451 1666 … … 1453 1668 1454 1669 PJ_LOG(4,(THIS_FILE, "Using account %d for buddy %d subscription", 1455 acc_id, index));1670 acc_id, buddy_id)); 1456 1671 1457 1672 /* Generate suitable Contact header unless one is already set in … … 1494 1709 PJSIP_EVSUB_NO_EVENT_ID, &buddy->sub); 1495 1710 if (status != PJ_SUCCESS) { 1496 pjsua_var.buddy[index].sub = NULL;1711 buddy->sub = NULL; 1497 1712 pjsua_perror(THIS_FILE, "Unable to create presence client", 1498 1713 status); … … 1565 1780 1566 1781 /* It does what it says... */ 1567 static void unsubscribe_buddy_presence( unsigned index)1782 static void unsubscribe_buddy_presence(pjsua_buddy_id buddy_id) 1568 1783 { 1569 1784 pjsua_buddy *buddy; … … 1571 1786 pj_status_t status; 1572 1787 1573 buddy = &pjsua_var.buddy[ index];1788 buddy = &pjsua_var.buddy[buddy_id]; 1574 1789 1575 1790 if (buddy->sub == NULL) … … 1577 1792 1578 1793 if (pjsip_evsub_get_state(buddy->sub) == PJSIP_EVSUB_STATE_TERMINATED) { 1579 pjsua_var.buddy[index].sub = NULL;1794 buddy->sub = NULL; 1580 1795 return; 1581 1796 } … … 1595 1810 } 1596 1811 1597 1598 /* Lock all buddies */1599 #define LOCK_BUDDIES unsigned cnt_ = 0; \1600 pjsip_dialog *dlg_list_[PJSUA_MAX_BUDDIES]; \1601 unsigned i_; \1602 for (i_=0; i_<PJ_ARRAY_SIZE(pjsua_var.buddy);++i_) { \1603 if (pjsua_var.buddy[i_].sub) { \1604 dlg_list_[cnt_++] = pjsua_var.buddy[i_].dlg; \1605 pjsip_dlg_inc_lock(pjsua_var.buddy[i_].dlg); \1606 } \1607 } \1608 PJSUA_LOCK();1609 1610 /* Unlock all buddies */1611 #define UNLOCK_BUDDIES PJSUA_UNLOCK(); \1612 for (i_=0; i_<cnt_; ++i_) { \1613 pjsip_dlg_dec_lock(dlg_list_[i_]); \1614 }1615 1616 1617 1618 1812 /* It does what it says.. */ 1619 static voidrefresh_client_subscriptions(void)1813 static pj_status_t refresh_client_subscriptions(void) 1620 1814 { 1621 1815 unsigned i; 1622 1623 LOCK_BUDDIES; 1816 pj_status_t status; 1624 1817 1625 1818 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 1626 1627 if (!pjsua_var.buddy[i].uri.slen) 1819 struct buddy_lock lck; 1820 1821 if (!pjsua_buddy_is_valid(i)) 1628 1822 continue; 1823 1824 status = lock_buddy("refresh_client_subscriptions()", i, &lck, 0); 1825 if (status != PJ_SUCCESS) 1826 return status; 1629 1827 1630 1828 if (pjsua_var.buddy[i].monitor && !pjsua_var.buddy[i].sub) { … … 1635 1833 1636 1834 } 1637 } 1638 1639 UNLOCK_BUDDIES; 1835 1836 unlock_buddy(&lck); 1837 } 1838 1839 return PJ_SUCCESS; 1640 1840 } 1641 1841 … … 1655 1855 1656 1856 entry->id = PJ_FALSE; 1657 refresh_client_subscriptions(); 1857 1858 /* #937: No need to do bulk client refresh, as buddies have their 1859 * own individual timer now. 1860 */ 1861 //refresh_client_subscriptions(); 1658 1862 1659 1863 pjsip_endpt_schedule_timer(pjsua_var.endpt, entry, &delay); … … 1708 1912 1709 1913 /* 1710 * Refresh presence subscriptions1711 */1712 void pjsua_pres_refresh()1713 {1714 unsigned i;1715 1716 refresh_client_subscriptions();1717 1718 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) {1719 if (pjsua_var.acc[i].valid)1720 pjsua_pres_update_acc(i, PJ_FALSE);1721 }1722 }1723 1724 1725 /*1726 1914 * Shutdown presence. 1727 1915 */ … … 1747 1935 } 1748 1936 1749 pjsua_pres_refresh(); 1750 } 1937 refresh_client_subscriptions(); 1938 1939 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { 1940 if (pjsua_var.acc[i].valid) 1941 pjsua_pres_update_acc(i, PJ_FALSE); 1942 } 1943 }
Note: See TracChangeset
for help on using the changeset viewer.