summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsip_simple/messaging.h
blob: f1d26b81dcd549161f93babf17ed80102d703a43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/* $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