blob: f1d26b81dcd549161f93babf17ed80102d703a43 [file] [log] [blame]
/* $Header: /pjproject/pjsip/src/pjsip_simple/messaging.h 6 8/31/05 9:05p Bennylp $ */
#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