/*! * \internal * \brief Attempt to qualify the contact * * \details Sends a SIP OPTIONS request to the given contact in order to make * sure that contact is available. */ static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact) { pjsip_tx_data *tdata; RAII_VAR(struct ast_sip_endpoint *, endpoint_local, NULL, ao2_cleanup); if (contact->authenticate_qualify) { endpoint_local = ao2_bump(endpoint); if (!endpoint_local) { /* * Find the "first" endpoint to completely qualify the contact - any * endpoint that is associated with the contact should do. */ endpoint_local = find_an_endpoint(contact); if (!endpoint_local) { ast_log(LOG_ERROR, "Unable to find an endpoint to qualify contact %s\n", contact->uri); return -1; } } } if (ast_sip_create_request("OPTIONS", NULL, NULL, NULL, contact, &tdata)) { ast_log(LOG_ERROR, "Unable to create request to qualify contact %s\n", contact->uri); return -1; } /* If an outbound proxy is specified set it on this request */ if (!ast_strlen_zero(contact->outbound_proxy) && ast_sip_set_outbound_proxy(tdata, contact->outbound_proxy)) { pjsip_tx_data_dec_ref(tdata); ast_log(LOG_ERROR, "Unable to apply outbound proxy on request to qualify contact %s\n", contact->uri); return -1; } init_start_time(contact); ao2_ref(contact, +1); if (ast_sip_send_out_of_dialog_request(tdata, endpoint_local, (int)(contact->qualify_timeout * 1000), contact, qualify_contact_cb) != PJ_SUCCESS) { ast_log(LOG_ERROR, "Unable to send request to qualify contact %s\n", contact->uri); update_contact_status(contact, UNAVAILABLE); ao2_ref(contact, -1); return -1; } return 0; }
/*! * \internal * \brief Qualify the given contact and set up scheduling if configured. */ static void qualify_and_schedule(struct ast_sip_contact *contact) { unschedule_qualify(contact); if (contact->qualify_frequency) { ao2_ref(contact, +1); if (ast_sip_push_task(NULL, qualify_contact_task, contact)) { ao2_ref(contact, -1); } schedule_qualify(contact, contact->qualify_frequency * 1000); } else { update_contact_status(contact, UNKNOWN); } }
static void qualify_and_schedule_contact(struct ast_sip_contact *contact) { int initial_interval; int max_time = ast_sip_get_max_initial_qualify_time(); /* Delay initial qualification by a random fraction of the specified interval */ if (max_time && max_time < contact->qualify_frequency) { initial_interval = max_time; } else { initial_interval = contact->qualify_frequency; } initial_interval = (int)((initial_interval * 1000) * ast_random_double()); unschedule_qualify(contact); if (contact->qualify_frequency) { schedule_qualify(contact, initial_interval); } else { update_contact_status(contact, UNKNOWN, 0); } }
/*! * \internal * \brief A contact has been updated. */ static void contact_updated(const void *obj) { update_contact_status(obj, AVAILABLE, 1); }