Changeset 1501


Ignore:
Timestamp:
Oct 16, 2007 1:34:14 AM (17 years ago)
Author:
bennylp
Message:

More ticket #399: added callback to report NAT detection result, and sends NAT type in SDP

Location:
pjproject/trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/include/pjnath/errno.h

    r1154 r1501  
    111111#define PJNATH_ESTUNIPV6NOTSUPP     (PJNATH_ERRNO_START+41) /* 370041 */ 
    112112 
     113/** 
     114 * @hideinitializer 
     115 * Invalid STUN server or server not configured. 
     116 */ 
     117#define PJNATH_ESTUNINSERVER        (PJNATH_ERRNO_START+42) /* 370042 */ 
    113118 
    114119 
  • pjproject/trunk/pjnath/include/pjnath/nat_detect.h

    r1497 r1501  
    4949{ 
    5050    /** 
    51      * NAT type is unknown, because the detection has failed. 
     51     * NAT type is unknown because the detection has not been performed. 
    5252     */ 
    5353    PJ_STUN_NAT_TYPE_UNKNOWN, 
     54 
     55    /** 
     56     * NAT type is unknown because there is failure in the detection 
     57     * process, possibly because server does not support RFC 3489. 
     58     */ 
     59    PJ_STUN_NAT_TYPE_ERR_UNKNOWN, 
    5460 
    5561    /** 
     
    150156typedef void pj_stun_nat_detect_cb(void *user_data, 
    151157                                   const pj_stun_nat_detect_result *res); 
     158 
     159 
     160/** 
     161 * Get the NAT name from the specified NAT type. 
     162 * 
     163 * @param type          NAT type. 
     164 * 
     165 * @return              NAT name. 
     166 */ 
     167PJ_DECL(const char*) pj_stun_get_nat_name(pj_stun_nat_type type); 
    152168 
    153169 
  • pjproject/trunk/pjnath/src/pjnath/errno.c

    r1154 r1501  
    5050    PJ_BUILD_ERR( PJNATH_ESTUNNOMAPPEDADDR, "STUN (XOR-)MAPPED-ADDRESS attribute not found"), 
    5151    PJ_BUILD_ERR( PJNATH_ESTUNIPV6NOTSUPP,  "STUN IPv6 attribute not supported"), 
     52    PJ_BUILD_ERR( PJNATH_ESTUNINSERVER,     "Invalid STUN server or server not configured"), 
    5253 
    5354    /* ICE related errors */ 
  • pjproject/trunk/pjnath/src/pjnath/nat_detect.c

    r1499 r1501  
    3333{ 
    3434    "Unknown", 
    35     "Open Internet", 
     35    "ErrUnknown", 
     36    "Open", 
    3637    "Blocked", 
    3738    "Symmetric UDP", 
     
    130131 
    131132 
     133/* 
     134 * Get the NAT name from the specified NAT type. 
     135 */ 
     136PJ_DEF(const char*) pj_stun_get_nat_name(pj_stun_nat_type type) 
     137{ 
     138    PJ_ASSERT_RETURN(type >= 0 && type <= PJ_STUN_NAT_TYPE_PORT_RESTRICTED, 
     139                     "*Invalid*"); 
     140 
     141    return nat_type_names[type]; 
     142} 
     143 
    132144static int test_executed(nat_detect_session *sess) 
    133145{ 
     
    388400        { 
    389401            /* Permanent error */ 
    390             end_session(sess, -bytes_read, PJ_STUN_NAT_TYPE_UNKNOWN); 
     402            end_session(sess, -bytes_read, PJ_STUN_NAT_TYPE_ERR_UNKNOWN); 
    391403            goto on_return; 
    392404        } 
     
    407419    if (status != PJ_EPENDING) { 
    408420        pj_assert(status != PJ_SUCCESS); 
    409         end_session(sess, status, PJ_STUN_NAT_TYPE_UNKNOWN); 
     421        end_session(sess, status, PJ_STUN_NAT_TYPE_ERR_UNKNOWN); 
    410422    } 
    411423 
     
    628640                 */ 
    629641                end_session(sess, sess->result[ST_TEST_2].status,  
    630                             PJ_STUN_NAT_TYPE_UNKNOWN); 
     642                            PJ_STUN_NAT_TYPE_ERR_UNKNOWN); 
    631643                break; 
    632644            } 
     
    691703                             */ 
    692704                            end_session(sess, sess->result[ST_TEST_3].status, 
    693                                         PJ_STUN_NAT_TYPE_UNKNOWN); 
     705                                        PJ_STUN_NAT_TYPE_ERR_UNKNOWN); 
    694706                            break; 
    695707                        } 
     
    708720                     */ 
    709721                    end_session(sess, sess->result[ST_TEST_1B].status, 
    710                                 PJ_STUN_NAT_TYPE_UNKNOWN); 
     722                                PJ_STUN_NAT_TYPE_ERR_UNKNOWN); 
    711723                    break; 
    712724                } 
     
    717729                 */ 
    718730                end_session(sess, sess->result[ST_TEST_2].status,  
    719                             PJ_STUN_NAT_TYPE_UNKNOWN); 
     731                            PJ_STUN_NAT_TYPE_ERR_UNKNOWN); 
    720732                break; 
    721733            } 
     
    727739         */ 
    728740        end_session(sess, sess->result[ST_TEST_1].status,  
    729                     PJ_STUN_NAT_TYPE_UNKNOWN); 
     741                    PJ_STUN_NAT_TYPE_ERR_UNKNOWN); 
    730742        break; 
    731743    } 
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c

    r1500 r1501  
    18861886 
    18871887/* 
     1888 * NAT type detection callback. 
     1889 */ 
     1890static void on_nat_detect(const pj_stun_nat_detect_result *res) 
     1891{ 
     1892    if (res->status != PJ_SUCCESS) { 
     1893        pjsua_perror(THIS_FILE, "NAT detection failed", res->status); 
     1894    } else { 
     1895        PJ_LOG(3, (THIS_FILE, "NAT detected as %s", res->nat_type_name)); 
     1896    } 
     1897} 
     1898 
     1899 
     1900/* 
    18881901 * Print buddy list. 
    18891902 */ 
     
    23132326 
    23142327 
    2315 /* Callback upon NAT detection completion */ 
    2316 static void nat_detect_cb(void *user_data, 
    2317                           const pj_stun_nat_detect_result *res) 
    2318 { 
    2319     PJ_UNUSED_ARG(user_data); 
    2320  
    2321     if (res->status != PJ_SUCCESS) { 
    2322         pjsua_perror(THIS_FILE, "NAT detection failed", res->status); 
    2323     } else { 
    2324         PJ_LOG(3, (THIS_FILE, "NAT detected as %s", res->nat_type_name)); 
    2325     } 
    2326 } 
    2327  
    2328  
    2329 /* 
    2330  * Detect NAT type. 
    2331  */ 
    2332 static void detect_nat_type(void) 
    2333 { 
    2334     pj_status_t status; 
    2335  
    2336     status = pjsua_detect_nat_type(NULL, &nat_detect_cb); 
    2337     if (status != PJ_SUCCESS) 
    2338         pjsua_perror(THIS_FILE, "Error", status); 
    2339 } 
    2340  
    2341  
    23422328/* 
    23432329 * Main "user interface" loop. 
     
    24542440 
    24552441        case 'n': 
    2456             detect_nat_type(); 
     2442            pjsua_detect_nat_type(); 
    24572443            break; 
    24582444 
     
    33083294    app_config.cfg.cb.on_call_transfer_status = &on_call_transfer_status; 
    33093295    app_config.cfg.cb.on_call_replaced = &on_call_replaced; 
     3296    app_config.cfg.cb.on_nat_detect = &on_nat_detect; 
    33103297 
    33113298    /* Initialize pjsua */ 
     
    35093496        return status; 
    35103497    } 
    3511  
    3512     if (app_config.cfg.stun_domain.slen || app_config.cfg.stun_host.slen) 
    3513         detect_nat_type(); 
    35143498 
    35153499    console_app_main(&uri_arg); 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r1495 r1501  
    566566     * Notify application when media state in the call has changed. 
    567567     * Normal application would need to implement this callback, e.g. 
    568      * to connect the call's media to sound device. 
     568     * to connect the call's media to sound device. When ICE is used, 
     569     * this callback will also be called to report ICE negotiation 
     570     * failure. 
    569571     * 
    570572     * @param call_id   The call index. 
     
    892894                      pj_bool_t is_typing); 
    893895 
     896    /** 
     897     * Callback when the library has finished performing NAT type 
     898     * detection. 
     899     * 
     900     * @param res           NAT detection result. 
     901     */ 
     902    void (*on_nat_detect)(const pj_stun_nat_detect_result *res); 
     903 
    894904} pjsua_callback; 
    895905 
     
    978988     */ 
    979989    pj_str_t        stun_relay_host; 
     990 
     991    /** 
     992     * Include local endpoint's NAT type in the SDP to assist troubleshooting. 
     993     * The valid values are: 
     994     *  - 0: no information will be added in SDP. 
     995     *  - 1: only the NAT type number is added. 
     996     *  - 2: add both NAT type number and name. 
     997     * 
     998     * Default: 2 
     999     */ 
     1000    int             nat_type_in_sdp; 
    9801001 
    9811002    /** 
     
    13161337 * This is a utility function to detect NAT type in front of this 
    13171338 * endpoint. Once invoked successfully, this function will complete  
    1318  * asynchronously and report the result in the callback. 
    1319  * 
    1320  * @param srv_port      Optional STUN server and port, in "SERVER[:PORT]" 
    1321  *                      format. If this option is NULL, the function will use 
    1322  *                      the STUN server that has been set in the pjsua 
    1323  *                      configuration. 
    1324  * @param user_data     User data to be returned back in the callback. 
    1325  * @param cb            Optional callback to report the detection result. 
    1326  * 
    1327  * @return              PJ_SUCCESS if detection is started successfully. 
    1328  */ 
    1329 PJ_DECL(pj_status_t) pjsua_detect_nat_type(void *user_data, 
    1330                                            pj_stun_nat_detect_cb *cb); 
     1339 * asynchronously and report the result in \a on_nat_detect() callback 
     1340 * of pjsua_callback. 
     1341 * 
     1342 * After NAT has been detected and the callback is called, application can 
     1343 * get the detected NAT type by calling #pjsua_get_nat_type(). Application 
     1344 * can also perform NAT detection by calling #pjsua_detect_nat_type() 
     1345 * again at later time. 
     1346 * 
     1347 * Note that STUN must be enabled to run this function successfully. 
     1348 * 
     1349 * @return              PJ_SUCCESS on success, or the appropriate error code. 
     1350 */ 
     1351PJ_DECL(pj_status_t) pjsua_detect_nat_type(void); 
     1352 
     1353 
     1354/** 
     1355 * Get the NAT type as detected by #pjsua_detect_nat_type() function. 
     1356 * This function will only return useful NAT type after #pjsua_detect_nat_type() 
     1357 * has completed successfully and \a on_nat_detect() callback has been called. 
     1358 * 
     1359 * @param type          NAT type. 
     1360 * 
     1361 * @return              When detection is in progress, this function will  
     1362 *                      return PJ_EPENDING and \a type will be set to  
     1363 *                      PJ_STUN_NAT_TYPE_UNKNOWN. After NAT type has been 
     1364 *                      detected successfully, this function will return 
     1365 *                      PJ_SUCCESS and \a type will be set to the correct 
     1366 *                      value. Other return values indicate error and 
     1367 *                      \a type will be set to PJ_STUN_NAT_TYPE_ERR_UNKNOWN. 
     1368 */ 
     1369PJ_DECL(pj_status_t) pjsua_get_nat_type(pj_stun_nat_type *type); 
    13311370 
    13321371 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r1452 r1501  
    195195    pj_dns_resolver     *resolver;  /**< DNS resolver.                  */ 
    196196 
     197    /* Detected NAT type */ 
     198    pj_stun_nat_type     nat_type;      /**< NAT type.                  */ 
     199    pj_status_t          nat_status;    /**< Detection status.          */ 
     200    pj_bool_t            nat_in_progress; /**< Detection in progress    */ 
     201 
    197202    /* Account: */ 
    198203    unsigned             acc_cnt;            /**< Number of accounts.   */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r1495 r1501  
    5252 
    5353    pjsua_var.stun_status = PJ_EUNKNOWN; 
     54    pjsua_var.nat_status = PJ_EPENDING; 
    5455} 
    5556 
     
    8081    cfg->max_calls = 4; 
    8182    cfg->thread_cnt = 1; 
     83    cfg->nat_type_in_sdp = 2; 
    8284} 
    8385 
     
    18591861 
    18601862 
     1863/* Callback upon NAT detection completion */ 
     1864static void nat_detect_cb(void *user_data,  
     1865                          const pj_stun_nat_detect_result *res) 
     1866{ 
     1867    PJ_UNUSED_ARG(user_data); 
     1868 
     1869    pjsua_var.nat_in_progress = PJ_FALSE; 
     1870    pjsua_var.nat_status = res->status; 
     1871    pjsua_var.nat_type = res->nat_type; 
     1872 
     1873    if (pjsua_var.ua_cfg.cb.on_nat_detect) { 
     1874        (*pjsua_var.ua_cfg.cb.on_nat_detect)(res); 
     1875    } 
     1876} 
     1877 
     1878 
    18611879/* 
    18621880 * Detect NAT type. 
    18631881 */ 
    1864 PJ_DEF(pj_status_t) pjsua_detect_nat_type( void *user_data, 
    1865                                            pj_stun_nat_detect_cb *cb) 
     1882PJ_DEF(pj_status_t) pjsua_detect_nat_type() 
    18661883{ 
    18671884    pj_status_t status; 
     1885 
     1886    if (pjsua_var.nat_in_progress) 
     1887        return PJ_SUCCESS; 
    18681888 
    18691889    /* Make sure STUN server resolution has completed */ 
    18701890    status = pjsua_resolve_stun_server(PJ_TRUE); 
    18711891    if (status != PJ_SUCCESS) { 
     1892        pjsua_var.nat_status = status; 
     1893        pjsua_var.nat_type = PJ_STUN_NAT_TYPE_ERR_UNKNOWN; 
    18721894        return status; 
    18731895    } 
     
    18751897    /* Make sure we have STUN */ 
    18761898    if (pjsua_var.stun_srv.ipv4.sin_family == 0) { 
    1877         return PJ_EINVALIDOP; 
    1878     } 
    1879  
    1880     return pj_stun_detect_nat_type(&pjsua_var.stun_srv.ipv4,  
    1881                                    &pjsua_var.stun_cfg,  
    1882                                    user_data, cb); 
     1899        pjsua_var.nat_status = PJNATH_ESTUNINSERVER; 
     1900        return PJNATH_ESTUNINSERVER; 
     1901    } 
     1902 
     1903    status = pj_stun_detect_nat_type(&pjsua_var.stun_srv.ipv4,  
     1904                                     &pjsua_var.stun_cfg,  
     1905                                     NULL, &nat_detect_cb); 
     1906 
     1907    if (status != PJ_SUCCESS) { 
     1908        pjsua_var.nat_status = status; 
     1909        pjsua_var.nat_type = PJ_STUN_NAT_TYPE_ERR_UNKNOWN; 
     1910        return status; 
     1911    } 
     1912 
     1913    pjsua_var.nat_in_progress = PJ_TRUE; 
     1914 
     1915    return PJ_SUCCESS; 
     1916} 
     1917 
     1918 
     1919/* 
     1920 * Get NAT type. 
     1921 */ 
     1922PJ_DEF(pj_status_t) pjsua_get_nat_type(pj_stun_nat_type *type) 
     1923{ 
     1924    *type = pjsua_var.nat_type; 
     1925    return pjsua_var.nat_status; 
    18831926} 
    18841927 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r1482 r1501  
    195195    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
    196196 
     197    /* Perform NAT detection */ 
     198    pjsua_detect_nat_type(); 
     199 
    197200    return PJ_SUCCESS; 
    198201} 
     
    759762    if (status != PJ_SUCCESS) 
    760763        goto on_error; 
     764 
     765    /* Add NAT info in the SDP */ 
     766    if (pjsua_var.ua_cfg.nat_type_in_sdp) { 
     767        pjmedia_sdp_attr *a; 
     768        pj_str_t value; 
     769        char nat_info[80]; 
     770 
     771        value.ptr = nat_info; 
     772        if (pjsua_var.ua_cfg.nat_type_in_sdp == 1) { 
     773            value.slen = pj_ansi_snprintf(nat_info, sizeof(nat_info), 
     774                                          "%d", pjsua_var.nat_type); 
     775        } else { 
     776            const char *type_name = pj_stun_get_nat_name(pjsua_var.nat_type); 
     777            value.slen = pj_ansi_snprintf(nat_info, sizeof(nat_info), 
     778                                          "%d %s", 
     779                                          pjsua_var.nat_type, 
     780                                          type_name); 
     781        } 
     782 
     783        a = pjmedia_sdp_attr_create(pool, "X-nat", &value); 
     784 
     785        pjmedia_sdp_attr_add(&sdp->attr_count, sdp->attr, a); 
     786 
     787    } 
    761788 
    762789    if (pjsua_var.media_cfg.enable_ice) { 
Note: See TracChangeset for help on using the changeset viewer.