diff options
author | Benny Prijono <bennylp@teluu.com> | 2005-11-09 16:27:11 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2005-11-09 16:27:11 +0000 |
commit | 9f379fcbe89024353a25b3737d79ec7a82b6408f (patch) | |
tree | b6ce94ad1d8af3ffdf4fa82fe659d50d9ece34db /pjsip/include/pjsip-simple | |
parent | d578e2e00a14e5faa775c51a25ddbc2f3d3a2fda (diff) |
Begin organizing directory structure of pjsip
git-svn-id: http://svn.pjsip.org/repos/pjproject/main@38 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/include/pjsip-simple')
-rw-r--r-- | pjsip/include/pjsip-simple/event_notify.h | 315 | ||||
-rw-r--r-- | pjsip/include/pjsip-simple/event_notify_msg.h | 102 | ||||
-rw-r--r-- | pjsip/include/pjsip-simple/messaging.h | 253 | ||||
-rw-r--r-- | pjsip/include/pjsip-simple/pidf.h | 161 | ||||
-rw-r--r-- | pjsip/include/pjsip-simple/presence.h | 214 | ||||
-rw-r--r-- | pjsip/include/pjsip-simple/xpidf.h | 118 |
6 files changed, 1163 insertions, 0 deletions
diff --git a/pjsip/include/pjsip-simple/event_notify.h b/pjsip/include/pjsip-simple/event_notify.h new file mode 100644 index 00000000..91b53657 --- /dev/null +++ b/pjsip/include/pjsip-simple/event_notify.h @@ -0,0 +1,315 @@ +/* $Id$ + * + */ +#ifndef __PJSIP_SIMPLE_EVENT_NOTIFY_H__ +#define __PJSIP_SIMPLE_EVENT_NOTIFY_H__ + +/** + * @file event_notify.h + * @brief SIP Specific Event Notification Extension (RFC 3265) + */ + +#include <pjsip/sip_types.h> +#include <pjsip/sip_auth.h> +#include <pjsip_simple/event_notify_msg.h> +#include <pj/timer.h> + +/** + * @defgroup PJSIP_EVENT_NOT SIP Event Notification (RFC 3265) Module + * @ingroup PJSIP_SIMPLE + * @{ + * + * This module provides the implementation of SIP Extension for SIP Specific + * Event Notification (RFC 3265). It extends PJSIP by supporting SUBSCRIBE and + * NOTIFY methods. + * + * This module itself is extensible; new event packages can be registered to + * this module to handle specific extensions (such as presence). + */ + +PJ_BEGIN_DECL + +typedef struct pjsip_event_sub_cb pjsip_event_sub_cb; +typedef struct pjsip_event_sub pjsip_event_sub; + +/** + * This enumeration describes subscription state as described in the RFC 3265. + * The standard specifies that extensions may define additional states. In the + * case where the state is not known, the subscription state will be set to + * PJSIP_EVENT_SUB_STATE_UNKNOWN, and the token will be kept in state_str + * member of the susbcription structure. + */ +typedef enum pjsip_event_sub_state +{ + /** State is NULL. */ + PJSIP_EVENT_SUB_STATE_NULL, + + /** Subscription is active. */ + PJSIP_EVENT_SUB_STATE_ACTIVE, + + /** Subscription is pending. */ + PJSIP_EVENT_SUB_STATE_PENDING, + + /** Subscription is terminated. */ + PJSIP_EVENT_SUB_STATE_TERMINATED, + + /** Subscription state can not be determined. Application can query + * the state information in state_str member. + */ + PJSIP_EVENT_SUB_STATE_UNKNOWN, + +} pjsip_event_sub_state; + +/** + * This structure describes notification to be called when incoming SUBSCRIBE + * request is received. The module will call the callback registered by package + * that matches the event description in the incoming SUBSCRIBE. + */ +typedef struct pjsip_event_sub_pkg_cb +{ + /** + * This callback is called to first enquery the package whether it wants + * to accept incoming SUBSCRIBE request. If it does, then on_subscribe + * will be called. + * + * @param rdata The incoming request. + * @param status The status code to be returned back to subscriber. + */ + void (*on_query_subscribe)(pjsip_rx_data *rdata, int *status); + + /** + * This callback is called when the module receives incoming SUBSCRIBE + * request. + * + * @param sub The subscription instance. + * @param rdata The received buffer. + * @param cb Callback to be registered to the subscription instance. + * @param expires The expiration to be set. + */ + void (*on_subscribe)(pjsip_event_sub *sub, pjsip_rx_data *rdata, + pjsip_event_sub_cb **cb, int *expires); + +} pjsip_event_sub_pkg_cb; + +/** + * This structure describes callback that is registered by application or + * package to receive notifications about a subscription. + */ +struct pjsip_event_sub_cb +{ + /** + * This callback is used by both subscriber and notifier. It is called + * when the subscription has been terminated. + * + * @param sub The subscription instance. + * @param reason The termination reason. + */ + void (*on_sub_terminated)(pjsip_event_sub *sub, const pj_str_t *reason); + + /** + * This callback is called when we received SUBSCRIBE request to refresh + * the subscription. + * + * @param sub The subscription instance. + * @param rdata The received SUBSCRIBE request. + */ + void (*on_received_refresh)(pjsip_event_sub *sub, pjsip_rx_data *rdata); + + /** + * This callback is called when the module receives final response on + * previously sent SUBSCRIBE request. + * + * @param sub The subscription instance. + * @param event The event. + */ + void (*on_received_sub_response)(pjsip_event_sub *sub, pjsip_event *event); + + /** + * This callback is called when the module receives incoming NOTIFY + * request. + * + * @param sub The subscription instance. + * @param rdata The received data. + */ + void (*on_received_notify)(pjsip_event_sub *sub, pjsip_rx_data *rdata); + + /** + * This callback is called when the module receives final response to + * previously sent NOTIFY request. + * + * @param sub The subscription instance. + * @param event The event. + */ + void (*on_received_notify_response)(pjsip_event_sub *sub, pjsip_event *event); + +}; + +/** + * This structure describes an event subscription record. The structure is used + * to represent both subscriber and notifier. + */ +struct pjsip_event_sub +{ + pj_pool_t *pool; /**< Pool. */ + pjsip_endpoint *endpt; /**< Endpoint. */ + pjsip_event_sub_cb cb; /**< Callback. */ + pj_mutex_t *mutex; /**< Mutex. */ + pjsip_role_e role; /**< Role (UAC=subscriber, UAS=notifier) */ + pjsip_event_sub_state state; /**< Subscription state. */ + pj_str_t state_str; /**< String describing the state. */ + pjsip_from_hdr *from; /**< Cached local info (From) */ + pjsip_to_hdr *to; /**< Cached remote info (To) */ + pjsip_contact_hdr *contact; /**< Cached local contact. */ + pjsip_cid_hdr *call_id; /**< Cached Call-ID */ + int cseq; /**< Outgoing CSeq */ + pjsip_event_hdr *event; /**< Event description. */ + pjsip_expires_hdr *uac_expires; /**< Cached Expires header (UAC only). */ + pjsip_accept_hdr *local_accept; /**< Local Accept header. */ + pjsip_route_hdr route_set; /**< Route-set. */ + + pj_str_t key; /**< Key in the hash table. */ + void *user_data; /**< Application data. */ + int default_interval; /**< Refresh interval. */ + pj_timer_entry timer; /**< Internal timer. */ + pj_time_val expiry_time; /**< Time when subscription expires. */ + int pending_tsx; /**< Number of pending transactions. */ + pj_bool_t delete_flag; /**< Pending deletion flag. */ + + pjsip_auth_session auth_sess; /**< Authorization sessions. */ + unsigned cred_cnt; /**< Number of credentials. */ + pjsip_cred_info *cred_info; /**< Array of credentials. */ +}; + + + + +/** + * Initialize the module and get the instance of the module to be registered to + * endpoint. + * + * @return The module instance. + */ +PJ_DECL(pjsip_module*) pjsip_event_sub_get_module(void); + + +/** + * Register event package. + * + * @param event The event identification for the package. + * @param accept_cnt Number of strings in Accept array. + * @param accept Array of Accept value. + * @param cb Callback to receive incoming SUBSCRIBE for the package. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_event_sub_register_pkg( const pj_str_t *event_name, + int accept_cnt, + const pj_str_t accept[], + const pjsip_event_sub_pkg_cb *cb ); + + +/** + * Create initial subscription instance (client). + * + * @param endpt The endpoint. + * @param from URL to put in From header. + * @param to The target resource. + * @param event Event package. + * @param expires Expiration time. + * @param accept Accept specification. + * @param user_data Application data to attach to this subscription. + * + * @return New client subscription instance. + */ +PJ_DECL(pjsip_event_sub*) pjsip_event_sub_create( pjsip_endpoint *endpt, + const pj_str_t *from, + const pj_str_t *to, + const pj_str_t *event, + int expires, + int accept_cnt, + const pj_str_t accept[], + void *user_data, + const pjsip_event_sub_cb *cb); + +/** + * Set credentials to be used for outgoing request messages. + * + * @param sub Subscription instance. + * @param count Number of credentials. + * @param cred Array of credential info. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_event_sub_set_credentials( pjsip_event_sub *sub, + int count, + const pjsip_cred_info cred[]); + +/** + * Set route set for outgoing requests. + * + * @param sub Subscription instance. + * @param route_set List of route headers. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_event_sub_set_route_set( pjsip_event_sub *sub, + const pjsip_route_hdr *route_set ); + + +/** + * Send SUBSCRIBE request. + * + * @param sub Subscription instance. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_event_sub_subscribe( pjsip_event_sub *sub ); + +/** + * Terminate subscription (client). This will send unsubscription request to + * notifier. + * + * @param sub Client subscription instance. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_event_sub_unsubscribe( pjsip_event_sub *sub ); + + +/** + * For notifier, send NOTIFY request to subscriber, and set the state of + * the subscription. + * + * @param sub The server subscription (notifier) instance. + * @param state New state to set. + * @param reason Specify reason if new state is terminated, otherwise + * put NULL. + * @param type Description of content type. + * @param body Text body to send with the NOTIFY, or NULL if the + * NOTIFY request should not contain any message body. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_event_sub_notify( pjsip_event_sub *sub, + pjsip_event_sub_state state, + const pj_str_t *reason, + pjsip_msg_body *body); + +/** + * Destroy subscription instance. + * + * @param sub The client or server subscription instance. + * + * @return Zero on success, one if the subscription will be + * deleted automatically later, or -1 on error. + */ +PJ_DECL(pj_status_t) pjsip_event_sub_destroy(pjsip_event_sub *sub); + + +PJ_END_DECL + +/** + * @} + */ + +#endif /* __PJSIP_SIMPLE_EVENT_NOTIFY_H__ */ diff --git a/pjsip/include/pjsip-simple/event_notify_msg.h b/pjsip/include/pjsip-simple/event_notify_msg.h new file mode 100644 index 00000000..ab66a05d --- /dev/null +++ b/pjsip/include/pjsip-simple/event_notify_msg.h @@ -0,0 +1,102 @@ +/* $Id$ + * + */ +#ifndef __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__ +#define __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__ + +/** + * @file event_notify_msg.h + * @brief SIP Event Notification Headers (RFC 3265) + */ +#include <pjsip/sip_msg.h> + +/** + * @ingroup PJSIP_EVENT_NOT + * @{ + */ + +PJ_BEGIN_DECL + + +/** Max events in Allow-Events header. */ +#define PJSIP_MAX_ALLOW_EVENTS 16 + +/** + * This structure describes Event header. + */ +typedef struct pjsip_event_hdr +{ + PJSIP_DECL_HDR_MEMBER(struct pjsip_event_hdr) + pj_str_t event_type; /**< Event name. */ + pj_str_t id_param; /**< Optional event ID parameter. */ + pj_str_t other_param; /**< Other parameter, concatenated together. */ +} pjsip_event_hdr; + +/** + * Create an Event header. + * + * @param pool The pool. + * + * @return New Event header instance. + */ +PJ_DECL(pjsip_event_hdr*) pjsip_event_hdr_create(pj_pool_t *pool); + + +/** + * This structure describes Allow-Events header. + */ +typedef struct pjsip_allow_events_hdr +{ + PJSIP_DECL_HDR_MEMBER(struct pjsip_allow_events_hdr) + int event_cnt; /**< Number of event names. */ + pj_str_t events[PJSIP_MAX_ALLOW_EVENTS]; /**< Event names. */ +} pjsip_allow_events_hdr; + + +/** + * Create a new Allow-Events header. + * + * @param pool. The pool. + * + * @return Allow-Events header. + */ +PJ_DECL(pjsip_allow_events_hdr*) pjsip_allow_events_hdr_create(pj_pool_t *pool); + + +/** + * This structure describes Subscription-State header. + */ +typedef struct pjsip_sub_state_hdr +{ + PJSIP_DECL_HDR_MEMBER(struct pjsip_sub_state_hdr) + pj_str_t sub_state; /**< Subscription state. */ + pj_str_t reason_param; /**< Optional termination reason. */ + int expires_param; /**< Expires param, or -1. */ + int retry_after; /**< Retry after param, or -1. */ + pj_str_t other_param; /**< Other parameter, concatenated together. */ +} pjsip_sub_state_hdr; + +/** + * Create new Subscription-State header. + * + * @param pool The pool. + * + * @return Subscription-State header. + */ +PJ_DECL(pjsip_sub_state_hdr*) pjsip_sub_state_hdr_create(pj_pool_t *pool); + +/** + * Initialize parser for event notify module. + */ +PJ_DEF(void) pjsip_event_notify_init_parser(void); + + +PJ_END_DECL + + +/** + * @} + */ + +#endif /* __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__ */ + diff --git a/pjsip/include/pjsip-simple/messaging.h b/pjsip/include/pjsip-simple/messaging.h new file mode 100644 index 00000000..ef7484bf --- /dev/null +++ b/pjsip/include/pjsip-simple/messaging.h @@ -0,0 +1,253 @@ +/* $Id$ + * + */ +#ifndef __PJSIP_SIMPLE_MESSAGING_H__ +#define __PJSIP_SIMPLE_MESSAGING_H__ + +/** + * @file messaging.h + * @brief Instant Messaging Extension (RFC 3428) + */ + +#include <pjsip/sip_msg.h> + +PJ_BEGIN_DECL + +/** + * @defgroup PJSIP_MESSAGING SIP Instant Messaging (RFC 3428) Module + * @ingroup PJSIP_SIMPLE + * @{ + * + * This module provides the implementation of SIP Extension for Instant + * Messaging (RFC 3428). It extends PJSIP by supporting MESSAGE method. + * + * The RFC 3428 doesn't provide any means of dialog for the purpose of sending/ + * receiving instant messaging. IM with SIP is basicly sessionless, which means + * that there is absolutely no correlation between IM messages sent or received + * by a host. Any correlation between IM messages is only perceivable by + * user, phsychologically. + * + * However, the RFC doesn't prohibit sending IM within a dialog (presumably + * using the same Call-ID and CSeq namespace), although it prohibits creating + * a dialog specificly for creating IM session. + * + * The implementation here is modeled to support both ways of sending IM msgs, + * i.e. sending IM message individually and sending IM message within a dialog. + * Although IM message can be associated with a dialog, this implementation of + * IM module is completely independent of the User Agent library in PJSIP. Yes, + * that's what is called modularity, and it demonstrates the clearness + * of PJSIP design (the last sentence is of course marketing crap :)). + * + * To send an IM message as part of dialog, application would first create the + * message using #pjsip_messaging_create_msg, using dialog's Call-ID, CSeq, + * From, and To header, then send the message using #pjsip_dlg_send_msg instead + * of #pjsip_messaging_send_msg. + * + * To send IM messages individually, application has two options. The first is + * to create the request with #pjsip_messaging_create_msg then send it with + * #pjsip_messaging_send_msg. But this way, application has to pre-construct + * From and To header first, which is not too convenient. + * + * The second option (to send IM messages not associated with a dialog) is to + * first create an 'IM session'. An 'IM session' here is not a SIP dialog, as + * it doesn't have Contact header etc. An 'IM session' here is just a local + * state to cache most of IM headers, for convenience and optimization. Appl + * creates an IM session with #pjsip_messaging_create_session, and destroy + * the session with #pjsip_messaging_destroy_session. To create an outgoing + * IM message, application would call #pjsip_messaging_session_create_msg, + * and to send the message it would use #pjsip_messaging_send_msg. + * + * Message authorization is handled by application, as usual, by inserting a + * proper WWW-Authenticate or Proxy-Authenticate header before sending the + * message. + * + * And the last bit, to handle incoing IM messages. + * + * To handle incoming IM messages, application would register a global callback + * to be called when incoming messages arrive, by registering with function + * #pjsip_messaging_set_incoming_callback. This will be the global callback + * for all incoming IM messages. Although the message was sent as part of + * a dialog, it would still come here. And as long as the request has proper + * identification (Call-ID, From/To tag), the dialog will be aware of the + * request and update it's state (remote CSeq) accordingly. + */ + + + +/** + * Typedef for callback to be called when outgoing message has been sent + * and a final response has been received. + */ +typedef void (*pjsip_messaging_cb)(void *token, int status_code); + +/** + * Typedef for callback to receive incoming message. + * + * @param rdata Incoming message data. + * + * @return The status code to be returned back to original sender. + * Application must return a final status code upon returning + * from this function, or otherwise the stack will respond + * with error. + */ +typedef int (*pjsip_on_new_msg_cb)(pjsip_rx_data *rdata); + +/** + * Opaque data type for instant messaging session. + */ +typedef struct pjsip_messaging_session pjsip_messaging_session; + +/** + * Get the messaging module. + * + * @return SIP module. + */ +PJ_DECL(pjsip_module*) pjsip_messaging_get_module(); + +/** + * Set the global callback to be called when incoming message is received. + * + * @param cb The callback to be called when incoming message is received. + * + * @return The previous callback. + */ +PJ_DECL(pjsip_on_new_msg_cb) +pjsip_messaging_set_incoming_callback(pjsip_on_new_msg_cb cb); + + +/** + * Create an instant message transmit data buffer using the specified arguments. + * The returned transmit data buffers will have it's reference counter set + * to 1, and when application send the buffer, the send function will decrement + * the reference counter. When the reference counter reach zero, the buffer + * will be deleted. As long as the function does not increment the buffer's + * reference counter between creating and sending the request, the buffer + * will always be deleted and no memory leak will occur. + * + * @param endpt Endpoint instance. + * @param target Target URL. + * @param from The "From" header, which content will be copied to request. + * If the "From" header doesn't have a tag parameter, the + * function will generate one. + * @param to The "To" header, which content will be copied to request. + * @param call_id Optionally specify Call-ID, or put NULL to make this + * function generate a unique Call-ID automatically. + * @param cseq Optionally specify CSeq, or put -1 to make this function + * generate a random CSeq. + * @param text Optionally specify "text/plain" message body, or put NULL + * if application wants to put body other than "text/plain" + * manually. + * + * @return SIP transmit data buffer, which reference count has been + * set to 1. + */ +PJ_DECL(pjsip_tx_data*) +pjsip_messaging_create_msg_from_hdr(pjsip_endpoint *endpt, + const pjsip_uri *target, + const pjsip_from_hdr *from, + const pjsip_to_hdr *to, + const pjsip_cid_hdr *call_id, + int cseq, + const pj_str_t *text); + +/** + * Create instant message, by specifying URL string for both From and To header. + * + * @param endpt Endpoint instance. + * @param target Target URL. + * @param from URL of the sender. + * @param to URL of the recipient. + * @param call_id Optionally specify Call-ID, or put NULL to make this + * function generate a unique Call-ID automatically. + * @param cseq Optionally specify CSeq, or put -1 to make this function + * generate a random CSeq. + * @param text Optionally specify "text/plain" message body, or put NULL + * if application wants to put body other than "text/plain" + * manually. + * + * @return SIP transmit data buffer, which reference count has been + * set to 1. + */ +PJ_DECL(pjsip_tx_data*) pjsip_messaging_create_msg( pjsip_endpoint *endpt, + const pj_str_t *target, + const pj_str_t *from, + const pj_str_t *to, + const pj_str_t *call_id, + int cseq, + const pj_str_t *text); + +/** + * Send the instant message transmit buffer and attach a callback to be called + * when the request has received a final response. This function will decrement + * the transmit buffer's reference counter, and when the reference counter + * reach zero, the buffer will be deleted. As long as the function does not + * increment the buffer's reference counter between creating the request and + * calling this function, the buffer will always be deleted regardless whether + * the sending was failed or succeeded. + * + * @param endpt Endpoint instance. + * @param tdata Transmit data buffer. + * @param token Token to be associated with the SIP transaction which sends + * this request. + * @param cb The callback to be called when the SIP request has received + * a final response from destination. + * + * @return Zero if the transaction was started successfully. Note that + * this doesn't mean the request has been received successfully + * by remote recipient. + */ +PJ_DECL(pj_status_t) pjsip_messaging_send_msg( pjsip_endpoint *endpt, + pjsip_tx_data *tdata, + void *token, + pjsip_messaging_cb cb ); + +/** + * Create an instant messaging session, which can conveniently be used to send + * multiple instant messages to the same recipient. + * + * @param endpt Endpoint instance. + * @param from URI of sender. The function will add a unique tag parameter + * to this URI in the From header. + * @param to URI of recipient. + * + * @return Messaging session. + */ +PJ_DECL(pjsip_messaging_session*) +pjsip_messaging_create_session( pjsip_endpoint *endpt, + const pj_str_t *from, + const pj_str_t *to ); + +/** + * Create an instant message using instant messaging session, and optionally + * attach a text message. + * + * @param ses The instant messaging session. + * @param text Optional "text/plain" message to be attached as the + * message body. If this parameter is NULL, then no message + * body will be created, and application can attach any + * type of message body before the request is sent. + * + * @return SIP transmit data buffer, which reference counter has been + * set to 1. + */ +PJ_DECL(pjsip_tx_data*) +pjsip_messaging_session_create_msg( pjsip_messaging_session *ses, + const pj_str_t *text ); + +/** + * Destroy an instant messaging session. + * + * @param ses The instant messaging session. + * + * @return Zero on successfull. + */ +PJ_DECL(pj_status_t) +pjsip_messaging_destroy_session( pjsip_messaging_session *ses ); + +/** + * @} + */ + +PJ_END_DECL + +#endif diff --git a/pjsip/include/pjsip-simple/pidf.h b/pjsip/include/pjsip-simple/pidf.h new file mode 100644 index 00000000..a6caeb6c --- /dev/null +++ b/pjsip/include/pjsip-simple/pidf.h @@ -0,0 +1,161 @@ +/* $Id$ + * + */ +#ifndef __PJSIP_SIMPLE_PIDF_H__ +#define __PJSIP_SIMPLE_PIDF_H__ + +/** + * @file pidf.h + * @brief PIDF/Presence Information Data Format (RFC 3863) + */ +#include <pj/types.h> +#include <pj/xml.h> + +PJ_BEGIN_DECL + + +/** + * @defgroup PJSIP_SIMPLE_PIDF PIDF/Presence Information Data Format (RFC 3863) + * @ingroup PJSIP_SIMPLE + * @{ + * + * This file provides tools for manipulating Presence Information Data + * Format (PIDF) as described in RFC 3863. + */ +typedef struct pj_xml_node pjpidf_pres; +typedef struct pj_xml_node pjpidf_tuple; +typedef struct pj_xml_node pjpidf_status; +typedef struct pj_xml_node pjpidf_note; + +typedef struct pjpidf_status_op +{ + void (*construct)(pj_pool_t*, pjpidf_status*); + pj_bool_t (*is_basic_open)(const pjpidf_status*); + void (*set_basic_open)(pjpidf_status*, pj_bool_t); +} pjpidf_status_op; + +typedef struct pjpidf_tuple_op +{ + void (*construct)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*); + + const pj_str_t* (*get_id)(const pjpidf_tuple* ); + void (*set_id)(pj_pool_t*, pjpidf_tuple *, const pj_str_t*); + + pjpidf_status* (*get_status)(pjpidf_tuple* ); + + const pj_str_t* (*get_contact)(const pjpidf_tuple*); + void (*set_contact)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*); + void (*set_contact_prio)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*); + const pj_str_t* (*get_contact_prio)(const pjpidf_tuple*); + + pjpidf_note* (*add_note)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*); + pjpidf_note* (*get_first_note)(pjpidf_tuple*); + pjpidf_note* (*get_next_note)(pjpidf_tuple*, pjpidf_note*); + + const pj_str_t* (*get_timestamp)(const pjpidf_tuple*); + void (*set_timestamp)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*); + void (*set_timestamp_np)(pj_pool_t*,pjpidf_tuple*, pj_str_t*); + +} pjpidf_tuple_op; + +typedef struct pjpidf_pres_op +{ + void (*construct)(pj_pool_t*, pjpidf_pres*, const pj_str_t*); + + pjpidf_tuple* (*add_tuple)(pj_pool_t*, pjpidf_pres*, const pj_str_t*); + pjpidf_tuple* (*get_first_tuple)(pjpidf_pres*); + pjpidf_tuple* (*get_next_tuple)(pjpidf_pres*, pjpidf_tuple*); + pjpidf_tuple* (*find_tuple)(pjpidf_pres*, const pj_str_t*); + void (*remove_tuple)(pjpidf_pres*, pjpidf_tuple*); + + pjpidf_note* (*add_note)(pj_pool_t*, pjpidf_pres*, const pj_str_t*); + pjpidf_note* (*get_first_note)(pjpidf_pres*); + pjpidf_note* (*get_next_note)(pjpidf_pres*, pjpidf_note*); + +} pjpidf_pres_op; + + +extern struct pjpidf_op_desc +{ + pjpidf_pres_op pres; + pjpidf_tuple_op tuple; + pjpidf_status_op status; +} pjpidf_op; + + +/****************************************************************************** + * Top level API for managing presence document. + *****************************************************************************/ +PJ_DECL(pjpidf_pres*) pjpidf_create(pj_pool_t *pool, const pj_str_t *entity); +PJ_DECL(pjpidf_pres*) pjpidf_parse(pj_pool_t *pool, char *text, int len); +PJ_DECL(int) pjpidf_print(const pjpidf_pres* pres, char *buf, int len); + + +/****************************************************************************** + * API for managing Presence node. + *****************************************************************************/ +PJ_DECL(void) pjpidf_pres_construct(pj_pool_t *pool, pjpidf_pres *pres, + const pj_str_t *entity); +PJ_DECL(pjpidf_tuple*) pjpidf_pres_add_tuple(pj_pool_t *pool, pjpidf_pres *pres, + const pj_str_t *id); +PJ_DECL(pjpidf_tuple*) pjpidf_pres_get_first_tuple(pjpidf_pres *pres); +PJ_DECL(pjpidf_tuple*) pjpidf_pres_get_next_tuple(pjpidf_pres *pres, + pjpidf_tuple *t); +PJ_DECL(pjpidf_tuple*) pjpidf_pres_find_tuple(pjpidf_pres *pres, + const pj_str_t *id); +PJ_DECL(void) pjpidf_pres_remove_tuple(pjpidf_pres *pres, + pjpidf_tuple*); + +PJ_DECL(pjpidf_note*) pjpidf_pres_add_note(pj_pool_t *pool, pjpidf_pres *pres, + const pj_str_t *text); +PJ_DECL(pjpidf_note*) pjpidf_pres_get_first_note(pjpidf_pres *pres); +PJ_DECL(pjpidf_note*) pjpidf_pres_get_next_note(pjpidf_pres*, pjpidf_note*); + + +/****************************************************************************** + * API for managing Tuple node. + *****************************************************************************/ +PJ_DECL(void) pjpidf_tuple_construct(pj_pool_t *pool, pjpidf_tuple *t, + const pj_str_t *id); +PJ_DECL(const pj_str_t*) pjpidf_tuple_get_id(const pjpidf_tuple *t ); +PJ_DECL(void) pjpidf_tuple_set_id(pj_pool_t *pool, pjpidf_tuple *t, + const pj_str_t *id); + +PJ_DECL(pjpidf_status*) pjpidf_tuple_get_status(pjpidf_tuple *t); + +PJ_DECL(const pj_str_t*) pjpidf_tuple_get_contact(const pjpidf_tuple *t); +PJ_DECL(void) pjpidf_tuple_set_contact(pj_pool_t *pool, pjpidf_tuple *t, + const pj_str_t *contact); +PJ_DECL(void) pjpidf_tuple_set_contact_prio(pj_pool_t *pool, pjpidf_tuple *t, + const pj_str_t *prio); +PJ_DECL(const pj_str_t*) pjpidf_tuple_get_contact_prio(const pjpidf_tuple *t); + +PJ_DECL(pjpidf_note*) pjpidf_tuple_add_note(pj_pool_t *pool, pjpidf_tuple *t, + const pj_str_t *text); +PJ_DECL(pjpidf_note*) pjpidf_tuple_get_first_note(pjpidf_tuple *t); +PJ_DECL(pjpidf_note*) pjpidf_tuple_get_next_note(pjpidf_tuple *t, pjpidf_note *n); + +PJ_DECL(const pj_str_t*) pjpidf_tuple_get_timestamp(const pjpidf_tuple *t); +PJ_DECL(void) pjpidf_tuple_set_timestamp(pj_pool_t *pool, pjpidf_tuple *t, + const pj_str_t *ts); +PJ_DECL(void) pjpidf_tuple_set_timestamp_np( pj_pool_t*, pjpidf_tuple *t, + pj_str_t *ts); + + +/****************************************************************************** + * API for managing Status node. + *****************************************************************************/ +PJ_DECL(void) pjpidf_status_construct(pj_pool_t*, pjpidf_status*); +PJ_DECL(pj_bool_t) pjpidf_status_is_basic_open(const pjpidf_status*); +PJ_DECL(void) pjpidf_status_set_basic_open(pjpidf_status*, pj_bool_t); + + +/** + * @} + */ + + +PJ_END_DECL + + +#endif /* __PJSIP_SIMPLE_PIDF_H__ */ diff --git a/pjsip/include/pjsip-simple/presence.h b/pjsip/include/pjsip-simple/presence.h new file mode 100644 index 00000000..80ed93c0 --- /dev/null +++ b/pjsip/include/pjsip-simple/presence.h @@ -0,0 +1,214 @@ +/* $Id$ + * + */ +#ifndef __PJSIP_SIMPLE_PRESENCE_H__ +#define __PJSIP_SIMPLE_PRESENCE_H__ + +/** + * @file presence.h + * @brief SIP Extension for Presence (RFC 3856) + */ +#include <pjsip_simple/event_notify.h> +#include <pjsip_simple/pidf.h> +#include <pjsip_simple/xpidf.h> + + +PJ_BEGIN_DECL + + +/** + * @defgroup PJSIP_SIMPLE_PRES SIP Extension for Presence (RFC 3856) + * @ingroup PJSIP_SIMPLE + * @{ + * + * This module contains the implementation of SIP Presence Extension as + * described in RFC 3856. It uses the SIP Event Notification framework + * (event_notify.h) and extends the framework by implementing "presence" + * event package. + */ + +/** + * Presence message body type. + */ +typedef enum pjsip_pres_type +{ + PJSIP_PRES_TYPE_PIDF, + PJSIP_PRES_TYPE_XPIDF, +} pjsip_pres_type; + +/** + * This structure describe a presentity, for both subscriber and notifier. + */ +typedef struct pjsip_presentity +{ + pjsip_event_sub *sub; /**< Event subscribtion record. */ + pjsip_pres_type pres_type; /**< Presentity type. */ + pjsip_msg_body *uas_body; /**< Message body (UAS only). */ + union { + pjpidf_pres *pidf; + pjxpidf_pres *xpidf; + } uas_data; /**< UAS data. */ + pj_str_t timestamp; /**< Time of last update. */ + void *user_data; /**< Application data. */ +} pjsip_presentity; + + +/** + * This structure describe callback that is registered to receive notification + * from the presence module. + */ +typedef struct pjsip_presence_cb +{ + /** + * This callback is first called when the module receives incoming + * SUBSCRIBE request to determine whether application wants to accept + * the request. If it does, then on_presence_request will be called. + * + * @param rdata The received message. + * @return Application should return 2xx to accept the request, + * or failure status (>=300) to reject the request. + */ + void (*accept_presence)(pjsip_rx_data *rdata, int *status); + + /** + * This callback is called when the module receive the first presence + * subscription request. + * + * @param pres The presence descriptor. + * @param rdata The incoming request. + * @param timeout Timeout to be set for incoming request. Otherwise + * app can just leave this and accept the default. + */ + void (*on_received_request)(pjsip_presentity *pres, pjsip_rx_data *rdata, + int *timeout); + + /** + * This callback is called when the module received subscription refresh + * request. + * + * @param pres The presence descriptor. + * @param rdata The incoming request. + */ + void (*on_received_refresh)(pjsip_presentity *pres, pjsip_rx_data *rdata); + + /** + * This callback is called when the module receives incoming NOTIFY + * request. + * + * @param pres The presence descriptor. + * @param open The latest status of the presentity. + */ + void (*on_received_update)(pjsip_presentity *pres, pj_bool_t open); + + /** + * This callback is called when the subscription has terminated. + * + * @param sub The subscription instance. + * @param reason The termination reason. + */ + void (*on_terminated)(pjsip_presentity *pres, const pj_str_t *reason); + +} pjsip_presence_cb; + + +/** + * Initialize the presence module and register callback. + * + * @param cb Callback structure. + */ +PJ_DECL(void) pjsip_presence_init(const pjsip_presence_cb *cb); + + +/** + * Create to presence subscription of a presentity URL. + * + * @param endpt Endpoint instance. + * @param local_url Local URL. + * @param remote_url Remote URL which the presence is being subscribed. + * @param expires The expiration. + * @param user_data User data to attach to presence subscription. + * + * @return The presence structure if successfull, or NULL if + * failed. + */ +PJ_DECL(pjsip_presentity*) pjsip_presence_create( pjsip_endpoint *endpt, + const pj_str_t *local_url, + const pj_str_t *remote_url, + int expires, + void *user_data ); + +/** + * Set credentials to be used by this presentity for outgoing requests. + * + * @param pres Presentity instance. + * @param count Number of credentials in the array. + * @param cred Array of credentials. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_presence_set_credentials( pjsip_presentity *pres, + int count, + const pjsip_cred_info cred[]); + +/** + * Set route set for outgoing requests. + * + * @param pres Presentity instance. + * @param route_set List of route headers. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_presence_set_route_set( pjsip_presentity *pres, + const pjsip_route_hdr *hdr ); + +/** + * Send SUBSCRIBE request for the specified presentity. + * + * @param pres The presentity instance. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_presence_subscribe( pjsip_presentity *pres ); + +/** + * Ceased the presence subscription. + * + * @param pres The presence structure. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjsip_presence_unsubscribe( pjsip_presentity *pres ); + +/** + * Notify subscriber about change in local status. + * + * @param pres The presence structure. + * @param state Set the state of the subscription. + * @param open Set the presence status (open or closed). + * + * @return Zero if a NOTIFY request can be sent. + */ +PJ_DECL(pj_status_t) pjsip_presence_notify( pjsip_presentity *pres, + pjsip_event_sub_state state, + pj_bool_t open ); + +/** + * Destroy presence structure and the underlying subscription. + * + * @param pres The presence structure. + * + * @return Zero if the subscription was destroyed, or one if + * the subscription can not be destroyed immediately + * and will be destroyed later, or -1 if failed. + */ +PJ_DECL(pj_status_t) pjsip_presence_destroy( pjsip_presentity *pres ); + + +/** + * @} + */ + +PJ_END_DECL + + +#endif /* __PJSIP_SIMPLE_PRESENCE_H__ */ diff --git a/pjsip/include/pjsip-simple/xpidf.h b/pjsip/include/pjsip-simple/xpidf.h new file mode 100644 index 00000000..27254fa7 --- /dev/null +++ b/pjsip/include/pjsip-simple/xpidf.h @@ -0,0 +1,118 @@ +/* $Id$ + * + */ +#ifndef __PJSIP_SIMPLE_XPIDF_H__ +#define __PJSIP_SIMPLE_XPIDF_H__ + +/** + * @file xpidf.h + * @brief XPIDF/Presence Information Data Format + */ +#include <pj/types.h> +#include <pj/xml.h> + +PJ_BEGIN_DECL + +/** + * @defgroup PJSIP_SIMPLE_XPIDF XPIDF/Presence Information Data Format + * @ingroup PJSIP_SIMPLE + * @{ + * + * This is an old presence data format as described in: + * draft-rosenberg-impp-pidf-00.txt. + * + * We won't support this format extensively here, as it seems there's not + * too many implementations support this anymore, as it shouldn't. + */ + +/** Type definitions for XPIDF root document. */ +typedef pj_xml_node pjxpidf_pres; + + +/** + * Create a new XPIDF document. + * + * @param pool Pool. + * @param uri URI to set in the XPIDF document. + * + * @return XPIDF document. + */ +PJ_DECL(pjxpidf_pres*) pjxpidf_create(pj_pool_t *pool, const pj_str_t *uri); + + +/** + * Parse XPIDF document. + * + * @param pool Pool. + * @param text Input text. + * @param len Length of input text. + * + * @return XPIDF document. + */ +PJ_DECL(pjxpidf_pres*) pjxpidf_parse(pj_pool_t *pool, char *text, pj_size_t len); + + +/** + * Print XPIDF document. + * + * @param pres The XPIDF document to print. + * @param text Buffer to place the output. + * @param len Length of the buffer. + * + * @return The length printed. + */ +PJ_DECL(int) pjxpidf_print( pjxpidf_pres *pres, char *text, pj_size_t len); + + +/** + * Get URI in the XPIDF document + * + * @param pres XPIDF document + * + * @return The URI, or an empty string. + */ +PJ_DECL(pj_str_t*) pjxpidf_get_uri(pjxpidf_pres *pres); + + +/** + * Set the URI of the XPIDF document. + * + * @param pool Pool. + * @param pres The XPIDF document. + * @param uri URI to set in the XPIDF document. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjxpidf_set_uri(pj_pool_t *pool, pjxpidf_pres *pres, + const pj_str_t *uri); + + +/** + * Get presence status in the XPIDF document. + * + * @param pres XPIDF document. + * + * @return True to indicate the contact is online. + */ +PJ_DECL(pj_bool_t) pjxpidf_get_status(pjxpidf_pres *pres); + + +/** + * Set presence status in the XPIDF document. + * + * @param pres XPIDF document. + * @param status Status to set, True for online, False for offline. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pjxpidf_set_status(pjxpidf_pres *pres, pj_bool_t status); + + +/** + * @} + */ + +PJ_END_DECL + + +#endif /* __PJSIP_SIMPLE_XPIDF_H__ */ |