Fix load errors related to the new ari_model_validators.
authorDavid M. Lee <dlee@digium.com>
Wed, 3 Jul 2013 19:46:50 +0000 (19:46 +0000)
committerDavid M. Lee <dlee@digium.com>
Wed, 3 Jul 2013 19:46:50 +0000 (19:46 +0000)
The Asterisk strategy of loading modules with RTLD_LAZY to extract metadata
from the module works well enough, until you try to take the address of a
function.

If a module takes the address of a function, that function needs to be
resolved at load time. That kinda defeats RTLD_LAZY.

This patch adds some ari_validator_{id}_fn() wrapper functions for safely
getting the function pointer from a different module.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393576 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/res_stasis_http_bridges.c
res/res_stasis_http_channels.c
res/res_stasis_http_endpoints.c
res/res_stasis_http_events.c
res/res_stasis_http_recordings.c
res/res_stasis_http_sounds.c
res/stasis_http/ari_model_validators.c
res/stasis_http/ari_model_validators.h
rest-api-templates/ari_model_validators.c.mustache
rest-api-templates/ari_model_validators.h.mustache
rest-api-templates/res_stasis_http_resource.c.mustache

index 878c1ce..f46b7ac 100644 (file)
@@ -76,7 +76,7 @@ static void stasis_http_get_bridges_cb(
        default:
                if (200 <= code && code <= 299) {
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_bridge);
+                               ari_validate_bridge_fn());
                } else {
                        ast_log(LOG_ERROR, "Invalid error response %d for /bridges\n", code);
                        is_valid = 0;
index 5343714..108f356 100644 (file)
@@ -76,7 +76,7 @@ static void stasis_http_get_channels_cb(
        default:
                if (200 <= code && code <= 299) {
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_channel);
+                               ari_validate_channel_fn());
                } else {
                        ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
                        is_valid = 0;
index 3323330..f85de3b 100644 (file)
@@ -76,7 +76,7 @@ static void stasis_http_get_endpoints_cb(
        default:
                if (200 <= code && code <= 299) {
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_endpoint);
+                               ari_validate_endpoint_fn());
                } else {
                        ast_log(LOG_ERROR, "Invalid error response %d for /endpoints\n", code);
                        is_valid = 0;
@@ -126,7 +126,7 @@ static void stasis_http_get_endpoints_by_tech_cb(
        default:
                if (200 <= code && code <= 299) {
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_endpoint);
+                               ari_validate_endpoint_fn());
                } else {
                        ast_log(LOG_ERROR, "Invalid error response %d for /endpoints/{tech}\n", code);
                        is_valid = 0;
index 4217263..7172e27 100644 (file)
@@ -64,7 +64,7 @@ static void stasis_http_event_websocket_ws_cb(struct ast_websocket *ws_session,
        }
 #if defined(AST_DEVMODE)
        session = ari_websocket_session_create(ws_session,
-               ari_validate_event);
+               ari_validate_event_fn());
 #else
        session = ari_websocket_session_create(ws_session, NULL);
 #endif
index 5b80432..e09ccbd 100644 (file)
@@ -76,7 +76,7 @@ static void stasis_http_get_stored_recordings_cb(
        default:
                if (200 <= code && code <= 299) {
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_stored_recording);
+                               ari_validate_stored_recording_fn());
                } else {
                        ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored\n", code);
                        is_valid = 0;
@@ -218,7 +218,7 @@ static void stasis_http_get_live_recordings_cb(
        default:
                if (200 <= code && code <= 299) {
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_live_recording);
+                               ari_validate_live_recording_fn());
                } else {
                        ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live\n", code);
                        is_valid = 0;
index da02062..84fdeee 100644 (file)
@@ -87,7 +87,7 @@ static void stasis_http_get_sounds_cb(
        default:
                if (200 <= code && code <= 299) {
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_sound);
+                               ari_validate_sound_fn());
                } else {
                        ast_log(LOG_ERROR, "Invalid error response %d for /sounds\n", code);
                        is_valid = 0;
index b41c154..c721727 100644 (file)
@@ -52,6 +52,11 @@ int ari_validate_asterisk_info(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_asterisk_info_fn(void)
+{
+       return ari_validate_asterisk_info;
+}
+
 int ari_validate_endpoint(struct ast_json *json)
 {
        int res = 1;
@@ -127,6 +132,11 @@ int ari_validate_endpoint(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_endpoint_fn(void)
+{
+       return ari_validate_endpoint;
+}
+
 int ari_validate_caller_id(struct ast_json *json)
 {
        int res = 1;
@@ -176,6 +186,11 @@ int ari_validate_caller_id(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_caller_id_fn(void)
+{
+       return ari_validate_caller_id;
+}
+
 int ari_validate_channel(struct ast_json *json)
 {
        int res = 1;
@@ -321,6 +336,11 @@ int ari_validate_channel(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_fn(void)
+{
+       return ari_validate_channel;
+}
+
 int ari_validate_dialed(struct ast_json *json)
 {
        int res = 1;
@@ -338,6 +358,11 @@ int ari_validate_dialed(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_dialed_fn(void)
+{
+       return ari_validate_dialed;
+}
+
 int ari_validate_dialplan_cep(struct ast_json *json)
 {
        int res = 1;
@@ -403,6 +428,11 @@ int ari_validate_dialplan_cep(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_dialplan_cep_fn(void)
+{
+       return ari_validate_dialplan_cep;
+}
+
 int ari_validate_bridge(struct ast_json *json)
 {
        int res = 1;
@@ -501,6 +531,11 @@ int ari_validate_bridge(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_bridge_fn(void)
+{
+       return ari_validate_bridge;
+}
+
 int ari_validate_live_recording(struct ast_json *json)
 {
        int res = 1;
@@ -534,6 +569,11 @@ int ari_validate_live_recording(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_live_recording_fn(void)
+{
+       return ari_validate_live_recording;
+}
+
 int ari_validate_stored_recording(struct ast_json *json)
 {
        int res = 1;
@@ -602,6 +642,11 @@ int ari_validate_stored_recording(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_stored_recording_fn(void)
+{
+       return ari_validate_stored_recording;
+}
+
 int ari_validate_format_lang_pair(struct ast_json *json)
 {
        int res = 1;
@@ -651,6 +696,11 @@ int ari_validate_format_lang_pair(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_format_lang_pair_fn(void)
+{
+       return ari_validate_format_lang_pair;
+}
+
 int ari_validate_sound(struct ast_json *json)
 {
        int res = 1;
@@ -710,6 +760,11 @@ int ari_validate_sound(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_sound_fn(void)
+{
+       return ari_validate_sound;
+}
+
 int ari_validate_playback(struct ast_json *json)
 {
        int res = 1;
@@ -800,6 +855,11 @@ int ari_validate_playback(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_playback_fn(void)
+{
+       return ari_validate_playback;
+}
+
 int ari_validate_application_replaced(struct ast_json *json)
 {
        int res = 1;
@@ -858,6 +918,11 @@ int ari_validate_application_replaced(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_application_replaced_fn(void)
+{
+       return ari_validate_application_replaced;
+}
+
 int ari_validate_bridge_created(struct ast_json *json)
 {
        int res = 1;
@@ -932,6 +997,11 @@ int ari_validate_bridge_created(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_bridge_created_fn(void)
+{
+       return ari_validate_bridge_created;
+}
+
 int ari_validate_bridge_destroyed(struct ast_json *json)
 {
        int res = 1;
@@ -1006,6 +1076,11 @@ int ari_validate_bridge_destroyed(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_bridge_destroyed_fn(void)
+{
+       return ari_validate_bridge_destroyed;
+}
+
 int ari_validate_bridge_merged(struct ast_json *json)
 {
        int res = 1;
@@ -1096,6 +1171,11 @@ int ari_validate_bridge_merged(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_bridge_merged_fn(void)
+{
+       return ari_validate_bridge_merged;
+}
+
 int ari_validate_channel_caller_id(struct ast_json *json)
 {
        int res = 1;
@@ -1202,6 +1282,11 @@ int ari_validate_channel_caller_id(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_caller_id_fn(void)
+{
+       return ari_validate_channel_caller_id;
+}
+
 int ari_validate_channel_created(struct ast_json *json)
 {
        int res = 1;
@@ -1276,6 +1361,11 @@ int ari_validate_channel_created(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_created_fn(void)
+{
+       return ari_validate_channel_created;
+}
+
 int ari_validate_channel_destroyed(struct ast_json *json)
 {
        int res = 1;
@@ -1382,6 +1472,11 @@ int ari_validate_channel_destroyed(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_destroyed_fn(void)
+{
+       return ari_validate_channel_destroyed;
+}
+
 int ari_validate_channel_dialplan(struct ast_json *json)
 {
        int res = 1;
@@ -1488,6 +1583,11 @@ int ari_validate_channel_dialplan(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_dialplan_fn(void)
+{
+       return ari_validate_channel_dialplan;
+}
+
 int ari_validate_channel_dtmf_received(struct ast_json *json)
 {
        int res = 1;
@@ -1594,6 +1694,11 @@ int ari_validate_channel_dtmf_received(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_dtmf_received_fn(void)
+{
+       return ari_validate_channel_dtmf_received;
+}
+
 int ari_validate_channel_entered_bridge(struct ast_json *json)
 {
        int res = 1;
@@ -1677,6 +1782,11 @@ int ari_validate_channel_entered_bridge(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_entered_bridge_fn(void)
+{
+       return ari_validate_channel_entered_bridge;
+}
+
 int ari_validate_channel_hangup_request(struct ast_json *json)
 {
        int res = 1;
@@ -1769,6 +1879,11 @@ int ari_validate_channel_hangup_request(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_hangup_request_fn(void)
+{
+       return ari_validate_channel_hangup_request;
+}
+
 int ari_validate_channel_left_bridge(struct ast_json *json)
 {
        int res = 1;
@@ -1859,6 +1974,11 @@ int ari_validate_channel_left_bridge(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_left_bridge_fn(void)
+{
+       return ari_validate_channel_left_bridge;
+}
+
 int ari_validate_channel_state_change(struct ast_json *json)
 {
        int res = 1;
@@ -1933,6 +2053,11 @@ int ari_validate_channel_state_change(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_state_change_fn(void)
+{
+       return ari_validate_channel_state_change;
+}
+
 int ari_validate_channel_userevent(struct ast_json *json)
 {
        int res = 1;
@@ -2023,6 +2148,11 @@ int ari_validate_channel_userevent(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_userevent_fn(void)
+{
+       return ari_validate_channel_userevent;
+}
+
 int ari_validate_channel_varset(struct ast_json *json)
 {
        int res = 1;
@@ -2122,6 +2252,11 @@ int ari_validate_channel_varset(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_channel_varset_fn(void)
+{
+       return ari_validate_channel_varset;
+}
+
 int ari_validate_event(struct ast_json *json)
 {
        int res = 1;
@@ -2253,6 +2388,11 @@ int ari_validate_event(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_event_fn(void)
+{
+       return ari_validate_event;
+}
+
 int ari_validate_playback_finished(struct ast_json *json)
 {
        int res = 1;
@@ -2327,6 +2467,11 @@ int ari_validate_playback_finished(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_playback_finished_fn(void)
+{
+       return ari_validate_playback_finished;
+}
+
 int ari_validate_playback_started(struct ast_json *json)
 {
        int res = 1;
@@ -2401,6 +2546,11 @@ int ari_validate_playback_started(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_playback_started_fn(void)
+{
+       return ari_validate_playback_started;
+}
+
 int ari_validate_stasis_end(struct ast_json *json)
 {
        int res = 1;
@@ -2475,6 +2625,11 @@ int ari_validate_stasis_end(struct ast_json *json)
        return res;
 }
 
+ari_validator ari_validate_stasis_end_fn(void)
+{
+       return ari_validate_stasis_end;
+}
+
 int ari_validate_stasis_start(struct ast_json *json)
 {
        int res = 1;
@@ -2565,3 +2720,8 @@ int ari_validate_stasis_start(struct ast_json *json)
 
        return res;
 }
+
+ari_validator ari_validate_stasis_start_fn(void)
+{
+       return ari_validate_stasis_start;
+}
index c4d0f27..5375796 100644 (file)
 /*! \file
  *
  * \brief Generated file - Build validators for ARI model objects.
+ *
+ * In addition to the normal validation functions one would normally expect,
+ * each validator has a ari_validate_{id}_fn() companion function that returns
+ * the validator's function pointer.
+ *
+ * The reason for this seamingly useless indirection is the way function
+ * pointers interfere with module loading. Asterisk attempts to dlopen() each
+ * module using \c RTLD_LAZY in order to read some metadata from the module.
+ * Unfortunately, if you take the address of a function, the function has to be
+ * resolvable at load time, even if \c RTLD_LAZY is specified. By moving the
+ * function-address-taking into this module, we can once again be lazy.
  */
 
  /*
@@ -128,6 +139,11 @@ int ari_validate_list(struct ast_json *json, int (*fn)(struct ast_json *));
 /*! @} */
 
 /*!
+ * \brief Function type for validator functions. Allows for 
+ */
+typedef int (*ari_validator)(struct ast_json *json);
+
+/*!
  * \brief Validator for AsteriskInfo.
  *
  * Asterisk system information
@@ -139,6 +155,13 @@ int ari_validate_list(struct ast_json *json, int (*fn)(struct ast_json *));
 int ari_validate_asterisk_info(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_asterisk_info().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_asterisk_info_fn(void);
+
+/*!
  * \brief Validator for Endpoint.
  *
  * An external device that may offer/accept calls to/from Asterisk.
@@ -152,6 +175,13 @@ int ari_validate_asterisk_info(struct ast_json *json);
 int ari_validate_endpoint(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_endpoint().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_endpoint_fn(void);
+
+/*!
  * \brief Validator for CallerID.
  *
  * Caller identification
@@ -163,6 +193,13 @@ int ari_validate_endpoint(struct ast_json *json);
 int ari_validate_caller_id(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_caller_id().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_caller_id_fn(void);
+
+/*!
  * \brief Validator for Channel.
  *
  * A specific communication connection between Asterisk and an Endpoint.
@@ -174,6 +211,13 @@ int ari_validate_caller_id(struct ast_json *json);
 int ari_validate_channel(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_fn(void);
+
+/*!
  * \brief Validator for Dialed.
  *
  * Dialed channel information.
@@ -185,6 +229,13 @@ int ari_validate_channel(struct ast_json *json);
 int ari_validate_dialed(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_dialed().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_dialed_fn(void);
+
+/*!
  * \brief Validator for DialplanCEP.
  *
  * Dialplan location (context/extension/priority)
@@ -196,6 +247,13 @@ int ari_validate_dialed(struct ast_json *json);
 int ari_validate_dialplan_cep(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_dialplan_cep().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_dialplan_cep_fn(void);
+
+/*!
  * \brief Validator for Bridge.
  *
  * The merging of media from one or more channels.
@@ -209,6 +267,13 @@ int ari_validate_dialplan_cep(struct ast_json *json);
 int ari_validate_bridge(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_bridge().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_bridge_fn(void);
+
+/*!
  * \brief Validator for LiveRecording.
  *
  * A recording that is in progress
@@ -220,6 +285,13 @@ int ari_validate_bridge(struct ast_json *json);
 int ari_validate_live_recording(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_live_recording().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_live_recording_fn(void);
+
+/*!
  * \brief Validator for StoredRecording.
  *
  * A past recording that may be played back.
@@ -231,6 +303,13 @@ int ari_validate_live_recording(struct ast_json *json);
 int ari_validate_stored_recording(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_stored_recording().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_stored_recording_fn(void);
+
+/*!
  * \brief Validator for FormatLangPair.
  *
  * Identifies the format and language of a sound file
@@ -242,6 +321,13 @@ int ari_validate_stored_recording(struct ast_json *json);
 int ari_validate_format_lang_pair(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_format_lang_pair().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_format_lang_pair_fn(void);
+
+/*!
  * \brief Validator for Sound.
  *
  * A media file that may be played back.
@@ -253,6 +339,13 @@ int ari_validate_format_lang_pair(struct ast_json *json);
 int ari_validate_sound(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_sound().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_sound_fn(void);
+
+/*!
  * \brief Validator for Playback.
  *
  * Object representing the playback of media to a channel
@@ -264,6 +357,13 @@ int ari_validate_sound(struct ast_json *json);
 int ari_validate_playback(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_playback().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_playback_fn(void);
+
+/*!
  * \brief Validator for ApplicationReplaced.
  *
  * Notification that another WebSocket has taken over for an application.
@@ -277,6 +377,13 @@ int ari_validate_playback(struct ast_json *json);
 int ari_validate_application_replaced(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_application_replaced().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_application_replaced_fn(void);
+
+/*!
  * \brief Validator for BridgeCreated.
  *
  * Notification that a bridge has been created.
@@ -288,6 +395,13 @@ int ari_validate_application_replaced(struct ast_json *json);
 int ari_validate_bridge_created(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_bridge_created().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_bridge_created_fn(void);
+
+/*!
  * \brief Validator for BridgeDestroyed.
  *
  * Notification that a bridge has been destroyed.
@@ -299,6 +413,13 @@ int ari_validate_bridge_created(struct ast_json *json);
 int ari_validate_bridge_destroyed(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_bridge_destroyed().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_bridge_destroyed_fn(void);
+
+/*!
  * \brief Validator for BridgeMerged.
  *
  * Notification that one bridge has merged into another.
@@ -310,6 +431,13 @@ int ari_validate_bridge_destroyed(struct ast_json *json);
 int ari_validate_bridge_merged(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_bridge_merged().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_bridge_merged_fn(void);
+
+/*!
  * \brief Validator for ChannelCallerId.
  *
  * Channel changed Caller ID.
@@ -321,6 +449,13 @@ int ari_validate_bridge_merged(struct ast_json *json);
 int ari_validate_channel_caller_id(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_caller_id().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_caller_id_fn(void);
+
+/*!
  * \brief Validator for ChannelCreated.
  *
  * Notification that a channel has been created.
@@ -332,6 +467,13 @@ int ari_validate_channel_caller_id(struct ast_json *json);
 int ari_validate_channel_created(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_created().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_created_fn(void);
+
+/*!
  * \brief Validator for ChannelDestroyed.
  *
  * Notification that a channel has been destroyed.
@@ -343,6 +485,13 @@ int ari_validate_channel_created(struct ast_json *json);
 int ari_validate_channel_destroyed(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_destroyed().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_destroyed_fn(void);
+
+/*!
  * \brief Validator for ChannelDialplan.
  *
  * Channel changed location in the dialplan.
@@ -354,6 +503,13 @@ int ari_validate_channel_destroyed(struct ast_json *json);
 int ari_validate_channel_dialplan(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_dialplan().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_dialplan_fn(void);
+
+/*!
  * \brief Validator for ChannelDtmfReceived.
  *
  * DTMF received on a channel.
@@ -367,6 +523,13 @@ int ari_validate_channel_dialplan(struct ast_json *json);
 int ari_validate_channel_dtmf_received(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_dtmf_received().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_dtmf_received_fn(void);
+
+/*!
  * \brief Validator for ChannelEnteredBridge.
  *
  * Notification that a channel has entered a bridge.
@@ -378,6 +541,13 @@ int ari_validate_channel_dtmf_received(struct ast_json *json);
 int ari_validate_channel_entered_bridge(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_entered_bridge().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_entered_bridge_fn(void);
+
+/*!
  * \brief Validator for ChannelHangupRequest.
  *
  * A hangup was requested on the channel.
@@ -389,6 +559,13 @@ int ari_validate_channel_entered_bridge(struct ast_json *json);
 int ari_validate_channel_hangup_request(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_hangup_request().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_hangup_request_fn(void);
+
+/*!
  * \brief Validator for ChannelLeftBridge.
  *
  * Notification that a channel has left a bridge.
@@ -400,6 +577,13 @@ int ari_validate_channel_hangup_request(struct ast_json *json);
 int ari_validate_channel_left_bridge(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_left_bridge().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_left_bridge_fn(void);
+
+/*!
  * \brief Validator for ChannelStateChange.
  *
  * Notification of a channel's state change.
@@ -411,6 +595,13 @@ int ari_validate_channel_left_bridge(struct ast_json *json);
 int ari_validate_channel_state_change(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_state_change().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_state_change_fn(void);
+
+/*!
  * \brief Validator for ChannelUserevent.
  *
  * User-generated event with additional user-defined fields in the object.
@@ -422,6 +613,13 @@ int ari_validate_channel_state_change(struct ast_json *json);
 int ari_validate_channel_userevent(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_userevent().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_userevent_fn(void);
+
+/*!
  * \brief Validator for ChannelVarset.
  *
  * Channel variable changed.
@@ -433,6 +631,13 @@ int ari_validate_channel_userevent(struct ast_json *json);
 int ari_validate_channel_varset(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_channel_varset().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_channel_varset_fn(void);
+
+/*!
  * \brief Validator for Event.
  *
  * Base type for asynchronous events from Asterisk.
@@ -444,6 +649,13 @@ int ari_validate_channel_varset(struct ast_json *json);
 int ari_validate_event(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_event().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_event_fn(void);
+
+/*!
  * \brief Validator for PlaybackFinished.
  *
  * Event showing the completion of a media playback operation.
@@ -455,6 +667,13 @@ int ari_validate_event(struct ast_json *json);
 int ari_validate_playback_finished(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_playback_finished().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_playback_finished_fn(void);
+
+/*!
  * \brief Validator for PlaybackStarted.
  *
  * Event showing the start of a media playback operation.
@@ -466,6 +685,13 @@ int ari_validate_playback_finished(struct ast_json *json);
 int ari_validate_playback_started(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_playback_started().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_playback_started_fn(void);
+
+/*!
  * \brief Validator for StasisEnd.
  *
  * Notification that a channel has left a Stasis appliction.
@@ -477,6 +703,13 @@ int ari_validate_playback_started(struct ast_json *json);
 int ari_validate_stasis_end(struct ast_json *json);
 
 /*!
+ * \brief Function pointer to ari_validate_stasis_end().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_stasis_end_fn(void);
+
+/*!
  * \brief Validator for StasisStart.
  *
  * Notification that a channel has entered a Stasis appliction.
@@ -487,6 +720,13 @@ int ari_validate_stasis_end(struct ast_json *json);
  */
 int ari_validate_stasis_start(struct ast_json *json);
 
+/*!
+ * \brief Function pointer to ari_validate_stasis_start().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_stasis_start_fn(void);
+
 /*
  * JSON models
  *
index 0e87f8e..04a6d11 100644 (file)
@@ -112,6 +112,11 @@ int ari_validate_{{c_id}}(struct ast_json *json)
 {{/properties}}
        return res;
 }
+
+ari_validator ari_validate_{{c_id}}_fn(void)
+{
+       return ari_validate_{{c_id}};
+}
 {{/models}}
 {{/api_declaration}}
 {{/apis}}
index 65efbbd..b5b90ac 100644 (file)
 /*! \file
  *
  * \brief Generated file - Build validators for ARI model objects.
+ *
+ * In addition to the normal validation functions one would normally expect,
+ * each validator has a ari_validate_{id}_fn() companion function that returns
+ * the validator's function pointer.
+ *
+ * The reason for this seamingly useless indirection is the way function
+ * pointers interfere with module loading. Asterisk attempts to dlopen() each
+ * module using \c RTLD_LAZY in order to read some metadata from the module.
+ * Unfortunately, if you take the address of a function, the function has to be
+ * resolvable at load time, even if \c RTLD_LAZY is specified. By moving the
+ * function-address-taking into this module, we can once again be lazy.
  */
 
  /*
@@ -124,6 +135,11 @@ int ari_validate_date(struct ast_json *json);
 int ari_validate_list(struct ast_json *json, int (*fn)(struct ast_json *));
 
 /*! @} */
+
+/*!
+ * \brief Function type for validator functions. Allows for 
+ */
+typedef int (*ari_validator)(struct ast_json *json);
 {{#apis}}
 {{#api_declaration}}
 {{#models}}
@@ -138,6 +154,13 @@ int ari_validate_list(struct ast_json *json, int (*fn)(struct ast_json *));
  * \returns False (zero) if invalid.
  */
 int ari_validate_{{c_id}}(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ari_validate_{{c_id}}().
+ *
+ * See \ref ari_model_validators.h for more details.
+ */
+ari_validator ari_validate_{{c_id}}_fn(void);
 {{/models}}
 {{/api_declaration}}
 {{/apis}}
index 0f0535b..d358732 100644 (file)
@@ -89,7 +89,7 @@ static void stasis_http_{{c_nickname}}_cb(
 {{#response_class}}
 {{#is_list}}
                        is_valid = ari_validate_list(response->message,
-                               ari_validate_{{c_singular_name}});
+                               ari_validate_{{c_singular_name}}_fn());
 {{/is_list}}
 {{^is_list}}
                        is_valid = ari_validate_{{c_name}}(
@@ -125,7 +125,7 @@ static void stasis_http_{{c_nickname}}_ws_cb(struct ast_websocket *ws_session,
 {{> param_parsing}}
 #if defined(AST_DEVMODE)
        session = ari_websocket_session_create(ws_session,
-               ari_validate_{{response_class.c_name}});
+               ari_validate_{{response_class.c_name}}_fn());
 #else
        session = ari_websocket_session_create(ws_session, NULL);
 #endif