PJ_DEF(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
					   pj_bool_t force )
{
    pj_status_t status;
    pjsip_transport_type_e tp_type;

    /* Make sure id is in range. */
    PJ_ASSERT_RETURN(id>=0 && id<(int)PJ_ARRAY_SIZE(pjsua_var.tpdata), 
		     PJ_EINVAL);

    /* Make sure that transport exists */
    PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL);

    tp_type = pjsua_var.tpdata[id].type & ~PJSIP_TRANSPORT_IPV6;

    if (force) {
    	/* Forcefully closing transport is deprecated, since any pending
    	 * transactions that are using the transport may not terminate
    	 * properly and can even crash.
    	 */
	PJ_LOG(1, (THIS_FILE, "pjsua_transport_close(force=PJ_TRUE) is "
			      "deprecated."));
    	
    	/* To minimize the effect to users, we shouldn't hard-deprecate this
    	 * and let it continue as if force is false.
    	 */
    	// return PJ_EINVAL;
    }

    /* If force is not specified, transports will be closed at their
     * convenient time.
     */
    switch (tp_type) {
	case PJSIP_TRANSPORT_UDP:
	    status = pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);
	    break;
	case PJSIP_TRANSPORT_TLS:
	case PJSIP_TRANSPORT_TCP:
	    /* This will close the TCP listener, but existing TCP/TLS
	     * connections (if any) will still linger 
	     */
	    status = (*pjsua_var.tpdata[id].data.factory->destroy)
			(pjsua_var.tpdata[id].data.factory);
	    break;
	default:
	    return PJ_EINVAL;
    }

    /* Cleanup pjsua data. We don't need to keep the transport
     * descriptor, the transport will be destroyed later by the last user
     * which decrements the transport's reference.
     */
    if (status == PJ_SUCCESS) {
    	pjsua_var.tpdata[id].type = PJSIP_TRANSPORT_UNSPECIFIED;
    	pjsua_var.tpdata[id].data.ptr = NULL;
    }

    return status;
}
PJ_DEF(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
					   pj_bool_t force )
{
    pj_status_t status;
    pjsip_transport_type_e tp_type;

     
    PJ_ASSERT_RETURN(id>=0 && id<(int)PJ_ARRAY_SIZE(pjsua_var.tpdata), 
		     PJ_EINVAL);

     
    PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL);

    tp_type = pjsua_var.tpdata[id].type & ~PJSIP_TRANSPORT_IPV6;

    if (force) {
    	 
	PJ_LOG(1, (THIS_FILE, "pjsua_transport_close(force=PJ_TRUE) is "
			      "deprecated."));
    	
    	 
    	 
    }

     
    switch (tp_type) {
	case PJSIP_TRANSPORT_UDP:
	    status = pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);
	    break;
	case PJSIP_TRANSPORT_TLS:
	case PJSIP_TRANSPORT_TCP:
	     
	    status = (*pjsua_var.tpdata[id].data.factory->destroy)
			(pjsua_var.tpdata[id].data.factory);
	    break;
	default:
	    return PJ_EINVAL;
    }

     
    if (status == PJ_SUCCESS) {
    	pjsua_var.tpdata[id].type = PJSIP_TRANSPORT_UNSPECIFIED;
    	pjsua_var.tpdata[id].data.ptr = NULL;
    }

    return status;
}