res_pjsip: Allow configuration of endpoint identifier query order
[asterisk/asterisk.git] / include / asterisk / res_pjsip.h
index f4f9ba7..a34c4b3 100644 (file)
@@ -91,6 +91,8 @@ struct ast_sip_transport {
        AST_DECLARE_STRING_FIELDS(
                /*! Certificate of authority list file */
                AST_STRING_FIELD(ca_list_file);
+               /*! Certificate of authority list path */
+               AST_STRING_FIELD(ca_list_path);
                /*! Public certificate file */
                AST_STRING_FIELD(cert_file);
                /*! Optional private key of the certificate file */
@@ -128,6 +130,8 @@ struct ast_sip_transport {
        unsigned int tos;
        /*! QOS COS value */
        unsigned int cos;
+       /*! Write timeout */
+       int write_timeout;
 };
 
 /*!
@@ -151,6 +155,10 @@ struct ast_sip_contact {
                AST_STRING_FIELD(uri);
                /*! Outbound proxy to use for qualify */
                AST_STRING_FIELD(outbound_proxy);
+               /*! Path information to place in Route headers */
+               AST_STRING_FIELD(path);
+               /*! Content of the User-Agent header in REGISTER request */
+               AST_STRING_FIELD(user_agent);
        );
        /*! Absolute time that this contact is no longer valid after */
        struct timeval expiration_time;
@@ -214,16 +222,20 @@ struct ast_sip_aor {
        unsigned int remove_existing;
        /*! Any permanent configured contacts */
        struct ao2_container *permanent_contacts;
+       /*! Determines whether SIP Path headers are supported */
+       unsigned int support_path;
 };
 
 /*!
- * \brief Aor/Contact pair used for ast_sip_for_each_contact callback.
+ * \brief A wrapper for contact that adds the aor_id and
+ * a consistent contact id.  Used by ast_sip_for_each_contact.
  */
-struct ast_sip_aor_contact_pair {
-       SORCERY_OBJECT(details);
-       /*! Aor */
-       struct ast_sip_aor *aor;
-       /*! Contact */
+struct ast_sip_contact_wrapper {
+       /*! The id of the parent aor. */
+       char *aor_id;
+       /*! The id of contact in form of aor_id/contact_uri. */
+       char *contact_id;
+       /*! Pointer to the actual contact. */
        struct ast_sip_contact *contact;
 };
 
@@ -463,12 +475,18 @@ struct ast_sip_media_rtp_configuration {
        unsigned int use_ptime;
        /*! Do we use AVPF exclusively for this endpoint? */
        unsigned int use_avpf;
+       /*! Do we force AVP, AVPF, SAVP, or SAVPF even for DTLS media streams? */
+       unsigned int force_avp;
+       /*! Do we use the received media transport in our answer SDP */
+       unsigned int use_received_transport;
        /*! \brief DTLS-SRTP configuration information */
        struct ast_rtp_dtls_cfg dtls_cfg;
        /*! Should SRTP use a 32 byte tag instead of an 80 byte tag? */
        unsigned int srtp_tag_32;
        /*! Do we use media encryption? what type? */
        enum ast_sip_session_media_encryption encryption;
+       /*! Do we want to optimistically support encryption if possible? */
+       unsigned int encryption_optimistic;
 };
 
 /*!
@@ -516,8 +534,6 @@ struct ast_sip_endpoint_media_configuration {
        struct ast_sip_direct_media_configuration direct_media;
        /*! T.38 (FoIP) options */
        struct ast_sip_t38_configuration t38;
-       /*! Codec preferences */
-       struct ast_codec_pref prefs;
        /*! Configured codecs */
        struct ast_format_cap *codecs;
        /*! DSCP TOS bits for audio streams */
@@ -554,6 +570,10 @@ struct ast_sip_endpoint {
                AST_STRING_FIELD(fromuser);
                /*! Domain to place in From header */
                AST_STRING_FIELD(fromdomain);
+               /*! Context to route incoming MESSAGE requests to */
+               AST_STRING_FIELD(message_context);
+               /*! Accountcode to auto-set on channels */
+               AST_STRING_FIELD(accountcode);
        );
        /*! Configuration for extensions */
        struct ast_sip_endpoint_extensions extensions;
@@ -589,6 +609,12 @@ struct ast_sip_endpoint {
        unsigned int allowtransfer;
        /*! Method used when handling redirects */
        enum ast_sip_session_redirect redirect_method;
+       /*! Variables set on channel creation */
+       struct ast_variable *channel_vars;
+       /*! Whether to place a 'user=phone' parameter into the request URI if user is a number */
+       unsigned int usereqphone;
+       /*! Whether to pass through hold and unhold using re-invites with recvonly and sendrecv */
+       unsigned int moh_passthrough;
 };
 
 /*!
@@ -754,6 +780,23 @@ int ast_sip_register_outbound_authenticator(struct ast_sip_outbound_authenticato
 void ast_sip_unregister_outbound_authenticator(struct ast_sip_outbound_authenticator *auth);
 
 /*!
+ * \brief Register a SIP endpoint identifier with a name.
+ *
+ * An endpoint identifier's purpose is to determine which endpoint a given SIP
+ * message has come from.
+ *
+ * Multiple endpoint identifiers may be registered so that if an endpoint
+ * cannot be identified by one identifier, it may be identified by another.
+ *
+ * \param identifier The SIP endpoint identifier to register
+ * \param name The name of the endpoint identifier
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_endpoint_identifier_by_name(struct ast_sip_endpoint_identifier *identifier,
+                                                const char *name);
+
+/*!
  * \brief Register a SIP endpoint identifier
  *
  * An endpoint identifier's purpose is to determine which endpoint a given SIP
@@ -816,36 +859,6 @@ pjsip_endpoint *ast_sip_get_pjsip_endpoint(void);
 struct ast_sorcery *ast_sip_get_sorcery(void);
 
 /*!
- * \brief Initialize transport support on a sorcery instance
- *
- * \param sorcery The sorcery instance
- *
- * \retval -1 failure
- * \retval 0 success
- */
-int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery);
-
-/*!
- * \brief Initialize qualify support on a sorcery instance
- *
- * \param sorcery The sorcery instance
- *
- * \retval -1 failure
- * \retval 0 success
- */
-int ast_sip_initialize_sorcery_qualify(struct ast_sorcery *sorcery);
-
-/*!
- * \brief Initialize location support on a sorcery instance
- *
- * \param sorcery The sorcery instance
- *
- * \retval -1 failure
- * \retval 0 success
- */
-int ast_sip_initialize_sorcery_location(struct ast_sorcery *sorcery);
-
-/*!
  * \brief Retrieve a named AOR
  *
  * \param aor_name Name of the AOR
@@ -884,6 +897,16 @@ struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_si
 struct ast_sip_contact *ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list);
 
 /*!
+ * \brief Retrieve the first bound contact AND the AOR chosen from a list of AORs
+ *
+ * \param aor_list A comma-separated list of AOR names
+ * \param aor The chosen AOR
+ * \param contact The chosen contact
+ */
+ void ast_sip_location_retrieve_contact_and_aor_from_list(const char *aor_list, struct ast_sip_aor **aor,
+       struct ast_sip_contact **contact);
+
+/*!
  * \brief Retrieve a named contact
  *
  * \param contact_name Name of the contact
@@ -899,11 +922,14 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na
  * \param aor Pointer to the AOR
  * \param uri Full contact URI
  * \param expiration_time Optional expiration time of the contact
+ * \param path_info Path information
+ * \param user_agent User-Agent header from REGISTER request
  *
  * \retval -1 failure
  * \retval 0 success
  */
-int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time);
+int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
+       struct timeval expiration_time, const char *path_info, const char *user_agent);
 
 /*!
  * \brief Update a contact
@@ -926,26 +952,6 @@ int ast_sip_location_update_contact(struct ast_sip_contact *contact);
 int ast_sip_location_delete_contact(struct ast_sip_contact *contact);
 
 /*!
- * \brief Initialize domain aliases support on a sorcery instance
- *
- * \param sorcery The sorcery instance
- *
- * \retval -1 failure
- * \retval 0 success
- */
-int ast_sip_initialize_sorcery_domain_alias(struct ast_sorcery *sorcery);
-
-/*!
- * \brief Initialize authentication support on a sorcery instance
- *
- * \param sorcery The sorcery instance
- *
- * \retval -1 failure
- * \retval 0 success
- */
-int ast_sip_initialize_sorcery_auth(struct ast_sorcery *sorcery);
-
-/*!
  * \brief Callback called when an outbound request with authentication credentials is to be sent in dialog
  *
  * This callback will have the created request on it. The callback's purpose is to do any extra
@@ -981,26 +987,6 @@ int ast_sip_dialog_setup_outbound_authentication(pjsip_dialog *dlg, const struct
                ast_sip_dialog_outbound_auth_cb cb, void *user_data);
 
 /*!
- * \brief Initialize the distributor module
- *
- * The distributor module is responsible for taking an incoming
- * SIP message and placing it into the threadpool. Once in the threadpool,
- * the distributor will perform endpoint lookups and authentication, and
- * then distribute the message up the stack to any further modules.
- *
- * \retval -1 Failure
- * \retval 0 Success
- */
-int ast_sip_initialize_distributor(void);
-
-/*!
- * \brief Destruct the distributor module.
- *
- * Unregisters pjsip modules and cleans up any allocated resources.
- */
-void ast_sip_destroy_distributor(void);
-
-/*!
  * \brief Retrieves a reference to the artificial auth.
  *
  * \retval The artificial auth
@@ -1188,8 +1174,26 @@ pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint,
  *
  * \param endpoint A pointer to the endpoint
  * \param rdata The request that is starting the dialog
+ * \param[out] status On failure, the reason for failure in creating the dialog
+ */
+pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status);
+
+/*!
+ * \brief General purpose method for creating an rdata structure using specific information
+ *
+ * \param rdata[out] The rdata structure that will be populated
+ * \param packet A SIP message
+ * \param src_name The source IP address of the message
+ * \param src_port The source port of the message
+ * \param transport_type The type of transport the message was received on
+ * \param local_name The local IP address the message was received on
+ * \param local_port The local port the message was received on
+ *
+ * \retval 0 success
+ * \retval -1 failure
  */
-pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
+int ast_sip_create_rdata(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port, char *transport_type,
+       const char *local_name, int local_port);
 
 /*!
  * \brief General purpose method for creating a SIP request
@@ -1207,18 +1211,22 @@ pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint,
  *
  * \param method The method of the SIP request to send
  * \param dlg Optional. If specified, the dialog on which to request the message.
- * \param endpoint Optional. If specified, the request will be created out-of-dialog
- * to the endpoint.
+ * \param endpoint Optional. If specified, the request will be created out-of-dialog to the endpoint.
  * \param uri Optional. If specified, the request will be sent to this URI rather
- * this value.
  * than one configured for the endpoint.
+ * \param contact The contact with which this request is associated for out-of-dialog requests.
  * \param[out] tdata The newly-created request
+ *
+ * The provided contact is attached to tdata with its reference bumped, but will
+ * not survive for the entire lifetime of tdata since the contact is cleaned up
+ * when all supplements have completed execution.
+ *
  * \retval 0 Success
  * \retval -1 Failure
  */
 int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg,
                struct ast_sip_endpoint *endpoint, const char *uri,
-               pjsip_tx_data **tdata);
+               struct ast_sip_contact *contact, pjsip_tx_data **tdata);
 
 /*!
  * \brief General purpose method for sending a SIP request
@@ -1231,12 +1239,50 @@ int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg,
  * they arrive.
  *
  * \param tdata The request to send
- * \param dlg Optional. If specified, the dialog on which the request should be sent
- * \param endpoint Optional. If specified, the request is sent out-of-dialog to the endpoint.
+ * \param dlg Optional. The dialog in which the request is sent.  Otherwise it is out-of-dialog.
+ * \param endpoint Optional. If specified, the out-of-dialog request is sent to the endpoint.
+ * \param token Data to be passed to the callback upon receipt of out-of-dialog response.
+ * \param callback Callback to be called upon receipt of out-of-dialog response.
+ *
+ * \retval 0 Success
+ * \retval -1 Failure (out-of-dialog callback will not be called.)
+ */
+int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg,
+       struct ast_sip_endpoint *endpoint, void *token,
+       void (*callback)(void *token, pjsip_event *e));
+
+/*!
+ * \brief General purpose method for creating a SIP response
+ *
+ * Its typical use would be to create responses for out of dialog
+ * requests.
+ *
+ * \param rdata The rdata from the incoming request.
+ * \param st_code The response code to transmit.
+ * \param contact The contact with which this request is associated.
+ * \param[out] tdata The newly-created response
+ *
+ * The provided contact is attached to tdata with its reference bumped, but will
+ * not survive for the entire lifetime of tdata since the contact is cleaned up
+ * when all supplements have completed execution.
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code,
+       struct ast_sip_contact *contact, pjsip_tx_data **p_tdata);
+
+/*!
+ * \brief Send a response to an out of dialog request
+ *
+ * \param res_addr The response address for this response
+ * \param tdata The response to send
+ * \param endpoint The ast_sip_endpoint associated with this response
+ *
  * \retval 0 Success
  * \retval -1 Failure
  */
-int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint);
+int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint);
 
 /*!
  * \brief Determine if an incoming request requires authentication
@@ -1390,6 +1436,15 @@ void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size);
 struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata);
 
 /*!
+ * \brief Add 'user=phone' parameter to URI if enabled and user is a phone number.
+ *
+ * \param endpoint The endpoint to use for configuration
+ * \param pool The memory pool to allocate the parameter from
+ * \param uri The URI to check for user and to add parameter to
+ */
+void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri);
+
+/*!
  * \brief Retrieve any endpoints available to sorcery.
  *
  * \retval Endpoints available to sorcery, NULL if no endpoints found.
@@ -1497,14 +1552,9 @@ void ast_sip_report_req_no_support(struct ast_sip_endpoint *endpoint, pjsip_rx_d
  */
 void ast_sip_report_mem_limit(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
 
-void ast_sip_initialize_global_headers(void);
-void ast_sip_destroy_global_headers(void);
-
 int ast_sip_add_global_request_header(const char *name, const char *value, int replace);
 int ast_sip_add_global_response_header(const char *name, const char *value, int replace);
 
-int ast_sip_initialize_sorcery_global(struct ast_sorcery *sorcery);
-
 /*!
  * \brief Retrieves the value associated with the given key.
  *
@@ -1564,11 +1614,12 @@ void *ast_sip_dict_set(pj_pool_t* pool, void *ht,
  * \brief For every contact on an AOR call the given 'on_contact' handler.
  *
  * \param aor the aor containing a list of contacts to iterate
- * \param on_contact callback on each contact on an AOR
+ * \param on_contact callback on each contact on an AOR.  The object
+ * received by the callback will be a ast_sip_contact_wrapper structure.
  * \param arg user data passed to handler
  * \retval 0 Success, non-zero on failure
  */
-int ast_sip_for_each_contact(struct ast_sip_aor *aor,
+int ast_sip_for_each_contact(const struct ast_sip_aor *aor,
                ao2_callback_fn on_contact, void *arg);
 
 /*!
@@ -1628,8 +1679,12 @@ struct ast_sip_ami {
        struct mansession *s;
        /*! Manager message */
        const struct message *m;
+       /*! Manager Action ID */
+       const char *action_id;
        /*! user specified argument data */
        void *arg;
+       /*! count of objects */
+       int count;
 };
 
 /*!
@@ -1743,4 +1798,131 @@ int ast_sip_for_each_channel(const struct ast_sip_endpoint *endpoint,
                ao2_callback_fn on_channel_snapshot,
                                      void *arg);
 
+enum ast_sip_supplement_priority {
+       /*! Top priority. Supplements with this priority are those that need to run before any others */
+       AST_SIP_SUPPLEMENT_PRIORITY_FIRST = 0,
+       /*! Channel creation priority.
+        * chan_pjsip creates a channel at this priority. If your supplement depends on being run before
+        * or after channel creation, then set your priority to be lower or higher than this value.
+        */
+       AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL = 1000000,
+       /*! Lowest priority. Supplements with this priority should be run after all other supplements */
+       AST_SIP_SUPPLEMENT_PRIORITY_LAST = INT_MAX,
+};
+
+/*!
+ * \brief A supplement to SIP message processing
+ *
+ * These can be registered by any module in order to add
+ * processing to incoming and outgoing SIP out of dialog
+ * requests and responses
+ */
+struct ast_sip_supplement {
+       /*! Method on which to call the callbacks. If NULL, call on all methods */
+       const char *method;
+       /*! Priority for this supplement. Lower numbers are visited before higher numbers */
+       enum ast_sip_supplement_priority priority;
+       /*!
+        * \brief Called on incoming SIP request
+        * This method can indicate a failure in processing in its return. If there
+        * is a failure, it is required that this method sends a response to the request.
+        * This method is always called from a SIP servant thread.
+        *
+        * \note
+        * The following PJSIP methods will not work properly:
+        * pjsip_rdata_get_dlg()
+        * pjsip_rdata_get_tsx()
+        * The reason is that the rdata passed into this function is a cloned rdata structure,
+        * and its module data is not copied during the cloning operation.
+        * If you need to get the dialog, you can get it via session->inv_session->dlg.
+        *
+        * \note
+        * There is no guarantee that a channel will be present on the session when this is called.
+        */
+       int (*incoming_request)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata);
+       /*!
+        * \brief Called on an incoming SIP response
+        * This method is always called from a SIP servant thread.
+        *
+        * \note
+        * The following PJSIP methods will not work properly:
+        * pjsip_rdata_get_dlg()
+        * pjsip_rdata_get_tsx()
+        * The reason is that the rdata passed into this function is a cloned rdata structure,
+        * and its module data is not copied during the cloning operation.
+        * If you need to get the dialog, you can get it via session->inv_session->dlg.
+        *
+        * \note
+        * There is no guarantee that a channel will be present on the session when this is called.
+        */
+       void (*incoming_response)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata);
+       /*!
+        * \brief Called on an outgoing SIP request
+        * This method is always called from a SIP servant thread.
+        */
+       void (*outgoing_request)(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata);
+       /*!
+        * \brief Called on an outgoing SIP response
+        * This method is always called from a SIP servant thread.
+        */
+       void (*outgoing_response)(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata);
+       /*! Next item in the list */
+       AST_LIST_ENTRY(ast_sip_supplement) next;
+};
+
+/*!
+ * \brief Register a supplement to SIP out of dialog processing
+ *
+ * This allows for someone to insert themselves in the processing of out
+ * of dialog SIP requests and responses. This, for example could allow for
+ * a module to set channel data based on headers in an incoming message.
+ * Similarly, a module could reject an incoming request if desired.
+ *
+ * \param supplement The supplement to register
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_supplement(struct ast_sip_supplement *supplement);
+
+/*!
+ * \brief Unregister a an supplement to SIP out of dialog processing
+ *
+ * \param supplement The supplement to unregister
+ */
+void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement);
+
+/*!
+ * \brief Retrieve the system debug setting (yes|no|host).
+ *
+ * \note returned string needs to be de-allocated by caller.
+ *
+ * \retval the system debug setting.
+ */
+char *ast_sip_get_debug(void);
+
+/*!
+ * \brief Retrieve the global endpoint_identifier_order setting.
+ *
+ * Specifies the order by which endpoint identifiers should be regarded.
+ *
+ * \retval the global endpoint_identifier_order value
+ */
+char *ast_sip_get_endpoint_identifier_order(void);
+
+/*! \brief Determines whether the res_pjsip module is loaded */
+#define CHECK_PJSIP_MODULE_LOADED()                            \
+       do {                                                    \
+               if (!ast_module_check("res_pjsip.so")           \
+                       || !ast_sip_get_pjsip_endpoint()) {     \
+                       return AST_MODULE_LOAD_DECLINE;         \
+               }                                               \
+       } while(0)
+
+/*!
+ * \brief Retrieve the system keep alive interval setting.
+ *
+ * \retval the keep alive interval.
+ */
+unsigned int ast_sip_get_keep_alive_interval(void);
+
 #endif /* _RES_PJSIP_H */