Changeset 2968 for pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
- Timestamp:
- Oct 26, 2009 11:21:37 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
r2960 r2968 1854 1854 } 1855 1855 1856 /*************************************************************************** 1857 * MWI 1858 */ 1859 /* Callback called when *client* subscription state has changed. */ 1860 static void mwi_evsub_on_state( pjsip_evsub *sub, pjsip_event *event) 1861 { 1862 pjsua_acc *acc; 1863 1864 PJ_UNUSED_ARG(event); 1865 1866 /* Note: #937: no need to acuire PJSUA_LOCK here. Since the buddy has 1867 * a dialog attached to it, lock_buddy() will use the dialog 1868 * lock, which we are currently holding! 1869 */ 1870 acc = (pjsua_acc*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 1871 if (!acc) 1872 return; 1873 1874 PJ_LOG(4,(THIS_FILE, 1875 "MWI subscription for %.*s is %s", 1876 (int)acc->cfg.id.slen, acc->cfg.id.ptr, 1877 pjsip_evsub_get_state_name(sub))); 1878 1879 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) { 1880 /* Clear subscription */ 1881 acc->mwi_dlg = NULL; 1882 acc->mwi_sub = NULL; 1883 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL); 1884 1885 } 1886 } 1887 1888 /* Callback called when we receive NOTIFY */ 1889 static void mwi_evsub_on_rx_notify(pjsip_evsub *sub, 1890 pjsip_rx_data *rdata, 1891 int *p_st_code, 1892 pj_str_t **p_st_text, 1893 pjsip_hdr *res_hdr, 1894 pjsip_msg_body **p_body) 1895 { 1896 pjsua_mwi_info mwi_info; 1897 pjsua_acc *acc; 1898 1899 PJ_UNUSED_ARG(p_st_code); 1900 PJ_UNUSED_ARG(p_st_text); 1901 PJ_UNUSED_ARG(res_hdr); 1902 PJ_UNUSED_ARG(p_body); 1903 1904 acc = (pjsua_acc*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); 1905 if (!acc) 1906 return; 1907 1908 /* Construct mwi_info */ 1909 pj_bzero(&mwi_info, sizeof(mwi_info)); 1910 mwi_info.evsub = sub; 1911 mwi_info.rdata = rdata; 1912 1913 /* Call callback */ 1914 if (pjsua_var.ua_cfg.cb.on_mwi_info) { 1915 (*pjsua_var.ua_cfg.cb.on_mwi_info)(acc->index, &mwi_info); 1916 } 1917 } 1918 1919 1920 /* Event subscription callback. */ 1921 static pjsip_evsub_user mwi_cb = 1922 { 1923 &mwi_evsub_on_state, 1924 NULL, /* on_tsx_state: not interested */ 1925 NULL, /* on_rx_refresh: don't care about SUBSCRIBE refresh, unless 1926 * we want to authenticate 1927 */ 1928 1929 &mwi_evsub_on_rx_notify, 1930 1931 NULL, /* on_client_refresh: Use default behaviour, which is to 1932 * refresh client subscription. */ 1933 1934 NULL, /* on_server_timeout: Use default behaviour, which is to send 1935 * NOTIFY to terminate. 1936 */ 1937 }; 1938 1939 void pjsua_start_mwi(pjsua_acc *acc) 1940 { 1941 pj_pool_t *tmp_pool = NULL; 1942 pj_str_t contact; 1943 pjsip_tx_data *tdata; 1944 pj_status_t status; 1945 1946 if (!acc->cfg.mwi_enabled) { 1947 if (acc->mwi_sub) { 1948 /* Terminate MWI subscription */ 1949 pjsip_tx_data *tdata; 1950 pjsip_evsub *sub = acc->mwi_sub; 1951 1952 /* Detach sub from this account */ 1953 acc->mwi_sub = NULL; 1954 acc->mwi_dlg = NULL; 1955 pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL); 1956 1957 /* Unsubscribe */ 1958 status = pjsip_mwi_initiate(acc->mwi_sub, 0, &tdata); 1959 if (status == PJ_SUCCESS) { 1960 status = pjsip_mwi_send_request(acc->mwi_sub, tdata); 1961 } 1962 } 1963 return; 1964 } 1965 1966 if (acc->mwi_sub) { 1967 /* Subscription is already active */ 1968 return; 1969 1970 } 1971 1972 /* Generate suitable Contact header unless one is already set in 1973 * the account 1974 */ 1975 if (acc->contact.slen) { 1976 contact = acc->contact; 1977 } else { 1978 tmp_pool = pjsua_pool_create("tmpmwi", 512, 256); 1979 status = pjsua_acc_create_uac_contact(tmp_pool, &contact, 1980 acc->index, &acc->cfg.id); 1981 if (status != PJ_SUCCESS) { 1982 pjsua_perror(THIS_FILE, "Unable to generate Contact header", 1983 status); 1984 pj_pool_release(tmp_pool); 1985 return; 1986 } 1987 } 1988 1989 /* Create UAC dialog */ 1990 status = pjsip_dlg_create_uac( pjsip_ua_instance(), 1991 &acc->cfg.id, 1992 &contact, 1993 &acc->cfg.id, 1994 NULL, &acc->mwi_dlg); 1995 if (status != PJ_SUCCESS) { 1996 pjsua_perror(THIS_FILE, "Unable to create dialog", status); 1997 if (tmp_pool) pj_pool_release(tmp_pool); 1998 return; 1999 } 2000 2001 /* Increment the dialog's lock otherwise when presence session creation 2002 * fails the dialog will be destroyed prematurely. 2003 */ 2004 pjsip_dlg_inc_lock(acc->mwi_dlg); 2005 2006 /* Create UAC subscription */ 2007 status = pjsip_mwi_create_uac(acc->mwi_dlg, &mwi_cb, 2008 PJSIP_EVSUB_NO_EVENT_ID, &acc->mwi_sub); 2009 if (status != PJ_SUCCESS) { 2010 pjsua_perror(THIS_FILE, "Error creating MWI subscription", status); 2011 if (tmp_pool) pj_pool_release(tmp_pool); 2012 pjsip_dlg_dec_lock(acc->mwi_dlg); 2013 return; 2014 } 2015 2016 /* If account is locked to specific transport, then lock dialog 2017 * to this transport too. 2018 */ 2019 if (acc->cfg.transport_id != PJSUA_INVALID_ID) { 2020 pjsip_tpselector tp_sel; 2021 2022 pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); 2023 pjsip_dlg_set_transport(acc->mwi_dlg, &tp_sel); 2024 } 2025 2026 /* Set route-set */ 2027 if (!pj_list_empty(&acc->route_set)) { 2028 pjsip_dlg_set_route_set(acc->mwi_dlg, &acc->route_set); 2029 } 2030 2031 /* Set credentials */ 2032 if (acc->cred_cnt) { 2033 pjsip_auth_clt_set_credentials( &acc->mwi_dlg->auth_sess, 2034 acc->cred_cnt, acc->cred); 2035 } 2036 2037 /* Set authentication preference */ 2038 pjsip_auth_clt_set_prefs(&acc->mwi_dlg->auth_sess, &acc->cfg.auth_pref); 2039 2040 pjsip_evsub_set_mod_data(acc->mwi_sub, pjsua_var.mod.id, acc); 2041 2042 status = pjsip_mwi_initiate(acc->mwi_sub, -1, &tdata); 2043 if (status != PJ_SUCCESS) { 2044 pjsip_dlg_dec_lock(acc->mwi_dlg); 2045 if (acc->mwi_sub) { 2046 pjsip_pres_terminate(acc->mwi_sub, PJ_FALSE); 2047 } 2048 acc->mwi_sub = NULL; 2049 acc->mwi_dlg = NULL; 2050 pjsua_perror(THIS_FILE, "Unable to create initial MWI SUBSCRIBE", 2051 status); 2052 if (tmp_pool) pj_pool_release(tmp_pool); 2053 return; 2054 } 2055 2056 pjsua_process_msg_data(tdata, NULL); 2057 2058 status = pjsip_pres_send_request(acc->mwi_sub, tdata); 2059 if (status != PJ_SUCCESS) { 2060 pjsip_dlg_dec_lock(acc->mwi_dlg); 2061 if (acc->mwi_sub) { 2062 pjsip_pres_terminate(acc->mwi_sub, PJ_FALSE); 2063 } 2064 acc->mwi_sub = NULL; 2065 acc->mwi_dlg = NULL; 2066 pjsua_perror(THIS_FILE, "Unable to send initial MWI SUBSCRIBE", 2067 status); 2068 if (tmp_pool) pj_pool_release(tmp_pool); 2069 return; 2070 } 2071 2072 pjsip_dlg_dec_lock(acc->mwi_dlg); 2073 if (tmp_pool) pj_pool_release(tmp_pool); 2074 2075 } 2076 2077 2078 /***************************************************************************/ 2079 1856 2080 /* Timer callback to re-create client subscription */ 1857 2081 static void pres_timer_cb(pj_timer_heap_t *th, … … 1861 2085 pj_time_val delay = { PJSUA_PRES_TIMER, 0 }; 1862 2086 1863 /* Retry failed PUBLISH requests */ 2087 entry->id = PJ_FALSE; 2088 2089 /* Retry failed PUBLISH and MWI SUBSCRIBE requests */ 1864 2090 for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { 1865 2091 pjsua_acc *acc = &pjsua_var.acc[i]; 2092 2093 /* Retry PUBLISH */ 1866 2094 if (acc->cfg.publish_enabled && acc->publish_sess==NULL) 1867 2095 pjsua_pres_init_publish_acc(acc->index); 1868 } 1869 1870 entry->id = PJ_FALSE; 2096 2097 /* Re-subscribe MWI subscription if it's terminated prematurely */ 2098 if (acc->cfg.mwi_enabled && !acc->mwi_sub) 2099 pjsua_start_mwi(acc); 2100 } 1871 2101 1872 2102 /* #937: No need to do bulk client refresh, as buddies have their
Note: See TracChangeset
for help on using the changeset viewer.