Ticket #406: New PJSUA API to update buddy's presence subscription

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1535 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/build.symbian/pjsua_libU.def b/build.symbian/pjsua_libU.def
index a277601..fd3a628 100644
--- a/build.symbian/pjsua_libU.def
+++ b/build.symbian/pjsua_libU.def
@@ -25,96 +25,97 @@
 	pjsua_buddy_get_info                     @ 24 NONAME
 	pjsua_buddy_is_valid                     @ 25 NONAME
 	pjsua_buddy_subscribe_pres               @ 26 NONAME
-	pjsua_call_answer                        @ 27 NONAME
-	pjsua_call_dial_dtmf                     @ 28 NONAME
-	pjsua_call_dump                          @ 29 NONAME
-	pjsua_call_get_conf_port                 @ 30 NONAME
-	pjsua_call_get_count                     @ 31 NONAME
-	pjsua_call_get_info                      @ 32 NONAME
-	pjsua_call_get_max_count                 @ 33 NONAME
-	pjsua_call_get_rem_nat_type              @ 34 NONAME
-	pjsua_call_get_user_data                 @ 35 NONAME
-	pjsua_call_hangup                        @ 36 NONAME
-	pjsua_call_hangup_all                    @ 37 NONAME
-	pjsua_call_has_media                     @ 38 NONAME
-	pjsua_call_is_active                     @ 39 NONAME
-	pjsua_call_make_call                     @ 40 NONAME
-	pjsua_call_reinvite                      @ 41 NONAME
-	pjsua_call_send_im                       @ 42 NONAME
-	pjsua_call_send_request                  @ 43 NONAME
-	pjsua_call_send_typing_ind               @ 44 NONAME
-	pjsua_call_set_hold                      @ 45 NONAME
-	pjsua_call_set_user_data                 @ 46 NONAME
-	pjsua_call_update                        @ 47 NONAME
-	pjsua_call_xfer                          @ 48 NONAME
-	pjsua_call_xfer_replaces                 @ 49 NONAME
-	pjsua_codec_get_param                    @ 50 NONAME
-	pjsua_codec_set_param                    @ 51 NONAME
-	pjsua_codec_set_priority                 @ 52 NONAME
-	pjsua_conf_add_port                      @ 53 NONAME
-	pjsua_conf_adjust_rx_level               @ 54 NONAME
-	pjsua_conf_adjust_tx_level               @ 55 NONAME
-	pjsua_conf_connect                       @ 56 NONAME
-	pjsua_conf_disconnect                    @ 57 NONAME
-	pjsua_conf_get_active_ports              @ 58 NONAME
-	pjsua_conf_get_max_ports                 @ 59 NONAME
-	pjsua_conf_get_port_info                 @ 60 NONAME
-	pjsua_conf_get_signal_level              @ 61 NONAME
-	pjsua_conf_remove_port                   @ 62 NONAME
-	pjsua_config_default                     @ 63 NONAME
-	pjsua_config_dup                         @ 64 NONAME
-	pjsua_create                             @ 65 NONAME
-	pjsua_destroy                            @ 66 NONAME
-	pjsua_detect_nat_type                    @ 67 NONAME
-	pjsua_dump                               @ 68 NONAME
-	pjsua_enum_accs                          @ 69 NONAME
-	pjsua_enum_buddies                       @ 70 NONAME
-	pjsua_enum_calls                         @ 71 NONAME
-	pjsua_enum_codecs                        @ 72 NONAME
-	pjsua_enum_conf_ports                    @ 73 NONAME
-	pjsua_enum_snd_devs                      @ 74 NONAME
-	pjsua_enum_transports                    @ 75 NONAME
-	pjsua_get_buddy_count                    @ 76 NONAME
-	pjsua_get_ec_tail                        @ 77 NONAME
-	pjsua_get_nat_type                       @ 78 NONAME
-	pjsua_get_pjmedia_endpt                  @ 79 NONAME
-	pjsua_get_pjsip_endpt                    @ 80 NONAME
-	pjsua_get_pool_factory                   @ 81 NONAME
-	pjsua_get_snd_dev                        @ 82 NONAME
-	pjsua_get_var                            @ 83 NONAME
-	pjsua_handle_events                      @ 84 NONAME
-	pjsua_im_send                            @ 85 NONAME
-	pjsua_im_typing                          @ 86 NONAME
-	pjsua_init                               @ 87 NONAME
-	pjsua_logging_config_default             @ 88 NONAME
-	pjsua_logging_config_dup                 @ 89 NONAME
-	pjsua_media_config_default               @ 90 NONAME
-	pjsua_media_transports_create            @ 91 NONAME
-	pjsua_msg_data_init                      @ 92 NONAME
-	pjsua_perror                             @ 93 NONAME
-	pjsua_player_create                      @ 94 NONAME
-	pjsua_player_destroy                     @ 95 NONAME
-	pjsua_player_get_conf_port               @ 96 NONAME
-	pjsua_player_get_port                    @ 97 NONAME
-	pjsua_player_set_pos                     @ 98 NONAME
-	pjsua_playlist_create                    @ 99 NONAME
-	pjsua_pool_create                        @ 100 NONAME
-	pjsua_pres_dump                          @ 101 NONAME
-	pjsua_reconfigure_logging                @ 102 NONAME
-	pjsua_recorder_create                    @ 103 NONAME
-	pjsua_recorder_destroy                   @ 104 NONAME
-	pjsua_recorder_get_conf_port             @ 105 NONAME
-	pjsua_recorder_get_port                  @ 106 NONAME
-	pjsua_set_ec                             @ 107 NONAME
-	pjsua_set_no_snd_dev                     @ 108 NONAME
-	pjsua_set_null_snd_dev                   @ 109 NONAME
-	pjsua_set_snd_dev                        @ 110 NONAME
-	pjsua_start                              @ 111 NONAME
-	pjsua_transport_close                    @ 112 NONAME
-	pjsua_transport_config_default           @ 113 NONAME
-	pjsua_transport_config_dup               @ 114 NONAME
-	pjsua_transport_create                   @ 115 NONAME
-	pjsua_transport_get_info                 @ 116 NONAME
-	pjsua_transport_register                 @ 117 NONAME
-	pjsua_transport_set_enable               @ 118 NONAME
-	pjsua_verify_sip_url                     @ 119 NONAME
+	pjsua_buddy_update_pres                  @ 27 NONAME
+	pjsua_call_answer                        @ 28 NONAME
+	pjsua_call_dial_dtmf                     @ 29 NONAME
+	pjsua_call_dump                          @ 30 NONAME
+	pjsua_call_get_conf_port                 @ 31 NONAME
+	pjsua_call_get_count                     @ 32 NONAME
+	pjsua_call_get_info                      @ 33 NONAME
+	pjsua_call_get_max_count                 @ 34 NONAME
+	pjsua_call_get_rem_nat_type              @ 35 NONAME
+	pjsua_call_get_user_data                 @ 36 NONAME
+	pjsua_call_hangup                        @ 37 NONAME
+	pjsua_call_hangup_all                    @ 38 NONAME
+	pjsua_call_has_media                     @ 39 NONAME
+	pjsua_call_is_active                     @ 40 NONAME
+	pjsua_call_make_call                     @ 41 NONAME
+	pjsua_call_reinvite                      @ 42 NONAME
+	pjsua_call_send_im                       @ 43 NONAME
+	pjsua_call_send_request                  @ 44 NONAME
+	pjsua_call_send_typing_ind               @ 45 NONAME
+	pjsua_call_set_hold                      @ 46 NONAME
+	pjsua_call_set_user_data                 @ 47 NONAME
+	pjsua_call_update                        @ 48 NONAME
+	pjsua_call_xfer                          @ 49 NONAME
+	pjsua_call_xfer_replaces                 @ 50 NONAME
+	pjsua_codec_get_param                    @ 51 NONAME
+	pjsua_codec_set_param                    @ 52 NONAME
+	pjsua_codec_set_priority                 @ 53 NONAME
+	pjsua_conf_add_port                      @ 54 NONAME
+	pjsua_conf_adjust_rx_level               @ 55 NONAME
+	pjsua_conf_adjust_tx_level               @ 56 NONAME
+	pjsua_conf_connect                       @ 57 NONAME
+	pjsua_conf_disconnect                    @ 58 NONAME
+	pjsua_conf_get_active_ports              @ 59 NONAME
+	pjsua_conf_get_max_ports                 @ 60 NONAME
+	pjsua_conf_get_port_info                 @ 61 NONAME
+	pjsua_conf_get_signal_level              @ 62 NONAME
+	pjsua_conf_remove_port                   @ 63 NONAME
+	pjsua_config_default                     @ 64 NONAME
+	pjsua_config_dup                         @ 65 NONAME
+	pjsua_create                             @ 66 NONAME
+	pjsua_destroy                            @ 67 NONAME
+	pjsua_detect_nat_type                    @ 68 NONAME
+	pjsua_dump                               @ 69 NONAME
+	pjsua_enum_accs                          @ 70 NONAME
+	pjsua_enum_buddies                       @ 71 NONAME
+	pjsua_enum_calls                         @ 72 NONAME
+	pjsua_enum_codecs                        @ 73 NONAME
+	pjsua_enum_conf_ports                    @ 74 NONAME
+	pjsua_enum_snd_devs                      @ 75 NONAME
+	pjsua_enum_transports                    @ 76 NONAME
+	pjsua_get_buddy_count                    @ 77 NONAME
+	pjsua_get_ec_tail                        @ 78 NONAME
+	pjsua_get_nat_type                       @ 79 NONAME
+	pjsua_get_pjmedia_endpt                  @ 80 NONAME
+	pjsua_get_pjsip_endpt                    @ 81 NONAME
+	pjsua_get_pool_factory                   @ 82 NONAME
+	pjsua_get_snd_dev                        @ 83 NONAME
+	pjsua_get_var                            @ 84 NONAME
+	pjsua_handle_events                      @ 85 NONAME
+	pjsua_im_send                            @ 86 NONAME
+	pjsua_im_typing                          @ 87 NONAME
+	pjsua_init                               @ 88 NONAME
+	pjsua_logging_config_default             @ 89 NONAME
+	pjsua_logging_config_dup                 @ 90 NONAME
+	pjsua_media_config_default               @ 91 NONAME
+	pjsua_media_transports_create            @ 92 NONAME
+	pjsua_msg_data_init                      @ 93 NONAME
+	pjsua_perror                             @ 94 NONAME
+	pjsua_player_create                      @ 95 NONAME
+	pjsua_player_destroy                     @ 96 NONAME
+	pjsua_player_get_conf_port               @ 97 NONAME
+	pjsua_player_get_port                    @ 98 NONAME
+	pjsua_player_set_pos                     @ 99 NONAME
+	pjsua_playlist_create                    @ 100 NONAME
+	pjsua_pool_create                        @ 101 NONAME
+	pjsua_pres_dump                          @ 102 NONAME
+	pjsua_reconfigure_logging                @ 103 NONAME
+	pjsua_recorder_create                    @ 104 NONAME
+	pjsua_recorder_destroy                   @ 105 NONAME
+	pjsua_recorder_get_conf_port             @ 106 NONAME
+	pjsua_recorder_get_port                  @ 107 NONAME
+	pjsua_set_ec                             @ 108 NONAME
+	pjsua_set_no_snd_dev                     @ 109 NONAME
+	pjsua_set_null_snd_dev                   @ 110 NONAME
+	pjsua_set_snd_dev                        @ 111 NONAME
+	pjsua_start                              @ 112 NONAME
+	pjsua_transport_close                    @ 113 NONAME
+	pjsua_transport_config_default           @ 114 NONAME
+	pjsua_transport_config_dup               @ 115 NONAME
+	pjsua_transport_create                   @ 116 NONAME
+	pjsua_transport_get_info                 @ 117 NONAME
+	pjsua_transport_register                 @ 118 NONAME
+	pjsua_transport_set_enable               @ 119 NONAME
+	pjsua_verify_sip_url                     @ 120 NONAME
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index bb2eb3d..579d722 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -3334,6 +3334,29 @@
 
 
 /**
+ * Update the presence information for the buddy. Although the library
+ * periodically refreshes the presence subscription for all buddies, some
+ * application may want to refresh the buddy's presence subscription
+ * immediately, and in this case it can use this function to accomplish
+ * this.
+ *
+ * Note that the buddy's presence subscription will only be initiated
+ * if presence monitoring is enabled for the buddy. See 
+ * #pjsua_buddy_subscribe_pres() for more info. Also if presence subscription
+ * for the buddy is already active, this function will not do anything.
+ *
+ * Once the presence subscription is activated successfully for the buddy,
+ * application will be notified about the buddy's presence status in the
+ * on_buddy_state() callback.
+ *
+ * @param buddy_id	Buddy identification.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_update_pres(pjsua_buddy_id buddy_id);
+
+
+/**
  * Dump presence subscriptions to log.
  *
  * @param verbose	Yes or no.
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index 0d750e0..482be7e 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -311,6 +311,42 @@
 
 
 /*
+ * Update buddy's presence.
+ */
+PJ_DEF(pj_status_t) pjsua_buddy_update_pres(pjsua_buddy_id buddy_id)
+{
+    pjsua_buddy *buddy;
+
+    PJ_ASSERT_RETURN(buddy_id>=0 && 
+			buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy),
+		     PJ_EINVAL);
+
+    PJSUA_LOCK();
+
+    buddy = &pjsua_var.buddy[buddy_id];
+
+    /* Return error if buddy's presence monitoring is not enabled */
+    if (!buddy->monitor) {
+	PJSUA_UNLOCK();
+	return PJ_EINVALIDOP;
+    }
+
+    /* Ignore if presence is already active for the buddy */
+    if (buddy->sub) {
+	PJSUA_UNLOCK();
+	return PJ_SUCCESS;
+    }
+
+    /* Initiate presence subscription */
+    subscribe_buddy_presence(buddy_id);
+
+    PJSUA_UNLOCK();
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Dump presence subscriptions to log file.
  */
 PJ_DEF(void) pjsua_pres_dump(pj_bool_t verbose)