Merge "pjsip_options: wrongly applied "UNKNOWN" status"
authorJenkins2 <jenkins2@gerrit.asterisk.org>
Fri, 15 Dec 2017 15:49:50 +0000 (09:49 -0600)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Fri, 15 Dec 2017 15:49:50 +0000 (09:49 -0600)
1  2 
res/res_pjsip/pjsip_options.c

@@@ -41,7 -41,7 +41,7 @@@ static const char *status_map [] = 
        [UNAVAILABLE] = "Unreachable",
        [AVAILABLE] = "Reachable",
        [UNKNOWN] = "Unknown",
-       [CREATED] = "Created",
+       [CREATED] = "NonQualified",
        [REMOVED] = "Removed",
  };
  
@@@ -49,7 -49,7 +49,7 @@@ static const char *short_status_map [] 
        [UNAVAILABLE] = "Unavail",
        [AVAILABLE] = "Avail",
        [UNKNOWN] = "Unknown",
-       [CREATED] = "Created",
+       [CREATED] = "NonQual",
        [REMOVED] = "Removed",
  };
  
@@@ -205,24 -205,12 +205,12 @@@ static void update_contact_status(cons
                return;
        }
  
-       if (is_contact_refresh
-               && status->status == CREATED) {
-               /*
-                * The contact status hasn't been updated since creation
-                * and we don't want to re-send a created status.
-                */
-               if (contact->qualify_frequency
-                       || status->rtt_start.tv_sec > 0) {
-                       /* Ignore, the status will change soon. */
-                       return;
-               }
-               /*
-                * Convert to a regular contact status update
-                * because the status may never change.
-                */
-               is_contact_refresh = 0;
-               value = UNKNOWN;
+       /*
+        * If the current status is CREATED, and it's a refresh or the given value is
+        * also CREATED then there is nothing to update as nothing needs to change.
+        */
+       if (status->status == CREATED && (is_contact_refresh || status->status == value)) {
+               return;
        }
  
        update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
@@@ -595,7 -583,7 +583,7 @@@ static void qualify_and_schedule(struc
  
                schedule_qualify(contact, contact->qualify_frequency * 1000);
        } else {
-               update_contact_status(contact, UNKNOWN, 0);
+               update_contact_status(contact, CREATED, 0);
        }
  }
  
@@@ -1127,7 -1115,7 +1115,7 @@@ static void qualify_and_schedule_contac
        if (contact->qualify_frequency) {
                schedule_qualify(contact, initial_interval);
        } else {
-               update_contact_status(contact, UNKNOWN, 0);
+               update_contact_status(contact, CREATED, 0);
        }
  }
  
@@@ -1147,24 -1135,7 +1135,24 @@@ static int qualify_and_schedule_cb_with
  
  static int qualify_and_schedule_cb_without_aor(void *obj, void *arg, int flags)
  {
 -      qualify_and_schedule_contact((struct ast_sip_contact *) obj);
 +      /*
 +       * These are really dynamic contacts. We need to retrieve the aor associated
 +       * with the contact since it's possible some of the aor's fields were updated
 +       * since last load.
 +       */
 +      struct ast_sip_contact *contact = obj;
 +      struct ast_sip_aor *aor = ast_sip_location_retrieve_aor(contact->aor);
 +
 +      if (aor) {
 +              qualify_and_schedule_cb_with_aor(obj, aor, flags);
 +              ao2_ref(aor, -1);
 +      } else {
 +              ast_log(LOG_WARNING, "Unable to locate AOR for contact '%s'. Keeping old "
 +                      "associated settings: frequency=%d, timeout=%f, authenticate=%s\n",
 +                      contact->uri, contact->qualify_frequency, contact->qualify_timeout,
 +                      contact->authenticate_qualify ? "yes" : "no");
 +              qualify_and_schedule_contact(contact);
 +      }
  
        return 0;
  }
@@@ -1192,21 -1163,32 +1180,21 @@@ static int qualify_and_schedule_all_cb(
        return 0;
  }
  
 -/*!
 - * \internal
 - * \brief Unschedule all existing contacts
 - */
 -static int unschedule_all_cb(void *obj, void *arg, int flags)
 -{
 -      struct sched_data *data = obj;
 -
 -      AST_SCHED_DEL_UNREF(sched, data->id, ao2_ref(data, -1));
 -
 -      return CMP_MATCH;
 -}
 -
  static void qualify_and_schedule_all(void)
  {
        struct ao2_container *aors;
        struct ao2_container *contacts;
  
 -      if (!var) {
 -              return;
 -      }
 -      aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
 -              "aor", AST_RETRIEVE_FLAG_MULTIPLE, var);
 +      /*
 +       * It's possible that the AOR had some of it's fields updated prior to a
 +       * reload. For instance qualifying could have been turned on or off by
 +       * setting the qualify_frequency. Due to this we have to iterate through
 +       * all contacts (static and dynamic), and not just ones where the frequency
 +       * is greater than zero, updating any contact fields with the AOR's values.
 +       */
  
 -      ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, unschedule_all_cb, NULL);
 +      aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
 +              "aor", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
  
        if (aors) {
                ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
        }
  
        contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
 -              "contact", AST_RETRIEVE_FLAG_MULTIPLE, var);
 +              "contact", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
        if (contacts) {
                ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_without_aor, NULL);
                ao2_ref(contacts, -1);
        }
 -
 -      ast_variables_destroy(var);
 -
  }
  
  int ast_sip_format_contact_ami(void *obj, void *arg, int flags)