1 /* |
|
2 * ============================================================================ |
|
3 * Name : isoim.c |
|
4 * Part of : isolation server instant messaing componenet. |
|
5 * Version : %version: bh1cfmsg#28 % |
|
6 * |
|
7 * Copyright © 2007-2008 Nokia. All rights reserved. |
|
8 * All rights reserved. |
|
9 * Redistribution and use in source and binary forms, with or without modification, |
|
10 * are permitted provided that the following conditions are met: |
|
11 * Redistributions of source code must retain the above copyright notice, this list |
|
12 * of conditions and the following disclaimer.Redistributions in binary form must |
|
13 * reproduce the above copyright notice, this list of conditions and the following |
|
14 * disclaimer in the documentation and/or other materials provided with the distribution. |
|
15 * Neither the name of the Nokia Corporation nor the names of its contributors may be used |
|
16 * to endorse or promote products derived from this software without specific prior written |
|
17 * permission. |
|
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY |
|
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
|
21 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
|
23 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
|
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
27 * ============================================================================ |
|
28 * Template version: 1.0 |
|
29 */ |
|
30 |
|
31 #include "tp-conn-gen.h" |
|
32 #include <stdlib.h> |
|
33 #include <string.h> |
|
34 #include <stdio.h> |
|
35 |
|
36 #include "isoim.h" |
|
37 #include "isoutils.h" |
|
38 |
|
39 #include "msgliterals.h" |
|
40 #include "msg_enums.h" |
|
41 |
|
42 /*! \file |
|
43 * Impliments the functions in isoim.h |
|
44 */ |
|
45 |
|
46 /*! /brief requests the handles for the contacts to which message should be sent. |
|
47 * request_handles_cb is registered as a callback. necessary data to be sent is |
|
48 * passed as userdata |
|
49 * |
|
50 * /param msghdr request header that will be passed back to client |
|
51 * /param contact_id all contacts |
|
52 * /param message |
|
53 * /param no_cntcts no. of contacts the msg shld be sent to |
|
54 * /return : error code on failure, 0 on success |
|
55 */ |
|
56 void send_message( send_msg_struct* msg_hdr, |
|
57 const gchar **contact_id ) |
|
58 { |
|
59 |
|
60 //request for the handles to contact |
|
61 tp_conn_request_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
62 TP_CONN_HANDLE_TYPE_CONTACT, |
|
63 contact_id,request_handles_cb, ( gpointer ) msg_hdr ); |
|
64 } |
|
65 |
|
66 |
|
67 /*! /brief handles for contacts are recieved and text channel created (if already |
|
68 * there same is used) message is sent to those contacts. |
|
69 * |
|
70 * |
|
71 * /param proxy unused |
|
72 * /param handles contact handles |
|
73 * /param error error if any in getting the handles for contact |
|
74 * /param userdata Has request header and message to be sent to reciever |
|
75 * The request header is used for mapping of response to correct request |
|
76 * |
|
77 */ |
|
78 void request_handles_cb(DBusGProxy *proxy, GArray *handles, GError* error, gpointer message) |
|
79 { |
|
80 TpChan* text_chan = NULL; //for send msg |
|
81 guint contact_handle; |
|
82 DBusGProxy *text_iface = NULL; |
|
83 send_msg_struct* msg_hdr = ( send_msg_struct* ) message; |
|
84 |
|
85 UNUSED_FORMAL_PARAM(proxy); |
|
86 //There was error in requesting handles to the contacts |
|
87 if ( error ) |
|
88 { |
|
89 iso_logger( "%s", error->message); |
|
90 |
|
91 iso_logger( "err code: %d ", error->code ); |
|
92 //Send error to client |
|
93 //What happens if |
|
94 send_response_to_client( msg_hdr->hdr_req, error->code, 0 ); |
|
95 g_error_free(error); |
|
96 return; |
|
97 } |
|
98 |
|
99 contact_handle = g_array_index( handles, guint, 0 ); |
|
100 //get the text channel for the contact handle |
|
101 text_chan = g_hash_table_find( globalCon.text_channels, |
|
102 (GHRFunc) text_channels_find_func, |
|
103 &contact_handle); |
|
104 |
|
105 iso_logger( "text_chan : %d ", text_chan ); |
|
106 |
|
107 //create a text channel |
|
108 if ( text_chan == NULL ) |
|
109 { |
|
110 |
|
111 text_chan = tp_conn_new_channel( globalCon.dbusConn,globalCon.conn,globalCon.connmgr_bus,TP_IFACE_CHANNEL_TYPE_TEXT, |
|
112 TP_CONN_HANDLE_TYPE_CONTACT,contact_handle, TRUE ); |
|
113 |
|
114 if(!text_chan) |
|
115 { |
|
116 send_response_to_client( msg_hdr->hdr_req, NOT_CONNECTED , 0 ); |
|
117 g_error_free(error); |
|
118 return; |
|
119 } |
|
120 |
|
121 iso_logger( "%s", dbus_g_proxy_get_path(DBUS_G_PROXY(text_chan))); |
|
122 g_hash_table_insert( globalCon.text_channels,g_strdup(dbus_g_proxy_get_path(DBUS_G_PROXY(text_chan))),text_chan); |
|
123 } |
|
124 |
|
125 //get interface.. |
|
126 text_iface = tp_chan_get_interface( text_chan,TELEPATHY_CHAN_IFACE_TEXT_QUARK ); |
|
127 |
|
128 |
|
129 |
|
130 if ( NULL == text_iface ) |
|
131 { |
|
132 free( msg_hdr->msg ); |
|
133 free( msg_hdr->hdr_req ); |
|
134 free( msg_hdr ); |
|
135 |
|
136 //Free proxy ? |
|
137 return ; |
|
138 } |
|
139 |
|
140 //send async |
|
141 tp_chan_type_text_send_async( text_iface, TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, |
|
142 ( const char * )msg_hdr->msg,sendreply_cb, msg_hdr->hdr_req ); // see if any user date should be passed |
|
143 |
|
144 |
|
145 iso_logger( "Message being sent is %s", msg_hdr->msg ); |
|
146 |
|
147 free( msg_hdr->msg ); |
|
148 free( msg_hdr ); |
|
149 |
|
150 iso_logger( "%s", "tp_chan_type_text_send_async after\n"); |
|
151 } |
|
152 |
|
153 /*! /brief parse the params for send and validates them |
|
154 * |
|
155 * /param aMsgBuffer message buffer to be parsed |
|
156 * /param aContactId pointer to an array of strings, After this function this |
|
157 * arg wil have the contacts to which message should be sent to |
|
158 * /param aSendMsg message to be sent |
|
159 * /param len : msg_len no. of bytes in aMsgBuffer |
|
160 * /param contact_count : no. of contacts |
|
161 * /return returns error code on failure, or 0 |
|
162 */ |
|
163 gint parse_for_send( gchar* msg_buf, gchar*** contact_ids, |
|
164 gchar** send_msg, gint msg_len, gint* contact_count ) |
|
165 { |
|
166 gchar* users = NULL; |
|
167 |
|
168 gint len = 0; |
|
169 gint err = 0; |
|
170 |
|
171 iso_logger( "%s", "In - parse_for_send\n" ); |
|
172 //skip the msg_hdr part |
|
173 len += sizeof( message_hdr_req ); |
|
174 //example send message - message header omitted.. |
|
175 //test.ximp@gmail.com\0ximp.telepathy@gmail.com\0\0hi, how r u?\0 |
|
176 // ^ ^ ^ ^ |
|
177 //contact1------------|contact2-----------------|-|message------| |
|
178 |
|
179 //gets the contacts, returns no. of contacts on success |
|
180 //error code on error |
|
181 err = parse_into_array_of_strings( msg_buf, contact_ids, &len, msg_len, |
|
182 contact_count ); |
|
183 if ( err < 0 ) |
|
184 { |
|
185 //An error has occured, so propagate to next level |
|
186 return err; |
|
187 } |
|
188 |
|
189 |
|
190 /* |
|
191 Will never come here.. coz it has been already handled in |
|
192 parse_into_array_of_strings |
|
193 if ( *contact_count > MAX_MSG_RECEIPIENTS ) |
|
194 { |
|
195 return INVALID_PARAMETERES; |
|
196 }*/ |
|
197 //reset the userlen |
|
198 |
|
199 //parse for the message.. |
|
200 err = parse_a_string( msg_buf, &users, &len, msg_len ); |
|
201 |
|
202 if ( err < 0 ) |
|
203 { |
|
204 return err; |
|
205 } |
|
206 //set the pointer to send message |
|
207 *send_msg = users; |
|
208 |
|
209 iso_logger( "%s", "Out - parse_for_send\n" ); |
|
210 //return the no. of contacts to be sent to |
|
211 return 0; |
|
212 } |
|
213 /*! /brief calls parse_for_send to parse the parameters, and calls |
|
214 * send_message for sending the message |
|
215 * |
|
216 * /param buf : message buffer to be parsed |
|
217 * /param len : msg_len no. of bytes in msg_buf |
|
218 * |
|
219 * /return gint : parse error code if any |
|
220 */ |
|
221 int action_parse_send( gchar* buf, gint msg_len ) |
|
222 { |
|
223 gchar** contactid = NULL; |
|
224 gchar* sendmsg = NULL; |
|
225 message_hdr_req *msg_hdr = NULL; |
|
226 gint meesage_type_err = 0; |
|
227 //It is very imp to initailize the contact_count to 0 here |
|
228 gint contact_count = 0; |
|
229 send_msg_struct* msg_struct = NULL; |
|
230 //parse contacts, message.. |
|
231 iso_logger( "%s", "In - action_parse_send\n" ); |
|
232 meesage_type_err = parse_for_send( buf, |
|
233 &contactid,&sendmsg, msg_len, &contact_count ); |
|
234 |
|
235 //if <= 0 there is some error in the message formation |
|
236 if ( contact_count > 0 && meesage_type_err == 0 ) |
|
237 { |
|
238 |
|
239 //send message |
|
240 msg_hdr = ( message_hdr_req* ) malloc( sizeof( message_hdr_req ) ); |
|
241 if ( NULL == msg_hdr ) |
|
242 { |
|
243 //free resources allocated for this operation |
|
244 free_msg_args( contactid, contact_count, sendmsg ); |
|
245 return MEM_ALLOCATION_ERROR; |
|
246 } |
|
247 memset( msg_hdr, '\0', sizeof( message_hdr_req ) ); |
|
248 //read message header from buffer |
|
249 memcpy( msg_hdr, buf, sizeof( message_hdr_req ) ); |
|
250 |
|
251 //fill the contacts and message into a struct |
|
252 msg_struct = ( send_msg_struct* ) malloc ( sizeof ( send_msg_struct ) ); |
|
253 if ( NULL == msg_struct ) |
|
254 { |
|
255 free ( msg_hdr ); |
|
256 free_msg_args( contactid, contact_count, sendmsg ); |
|
257 return MEM_ALLOCATION_ERROR; |
|
258 } |
|
259 msg_struct->hdr_req = msg_hdr; |
|
260 msg_struct->msg = sendmsg; |
|
261 //msg_struct is sent callback... which should be feed there.. |
|
262 send_message( msg_struct, |
|
263 ( const gchar** ) contactid ); |
|
264 } |
|
265 else |
|
266 { |
|
267 //there was some error, free resources allocated for this operation |
|
268 free_msg_args( contactid, contact_count, sendmsg ); |
|
269 } |
|
270 |
|
271 iso_logger( "%s", "Out - action_parse_send\n" ); |
|
272 //return error on failure, or no. of contacts message sent to on success |
|
273 return meesage_type_err; |
|
274 |
|
275 } |
|
276 |
|
277 /*! /brief Function to check if the channel is already present in the maintained hash |
|
278 * text_channels_find_func. |
|
279 * |
|
280 * /param key unused |
|
281 * /param text_channel hash table element |
|
282 * /param contact_handle to be searched item |
|
283 * /return boolean |
|
284 */ |
|
285 gboolean text_channels_find_func( gchar *key, |
|
286 TpChan *text_channel, |
|
287 guint *contact_handle ) |
|
288 { |
|
289 iso_logger( "%s", "In - text_channels_find_func\n" ); |
|
290 //Check for the handles |
|
291 UNUSED_FORMAL_PARAM(key); |
|
292 if ( ( text_channel->handle == *contact_handle ) ) |
|
293 return TRUE; |
|
294 |
|
295 return FALSE; |
|
296 } |
|
297 |
|
298 /*! /brief Once the send request is sent to n/w server this callback is called |
|
299 * |
|
300 * /param proxy unused |
|
301 * /param error n/w error if any |
|
302 * /param userdata message header from which a response is formed |
|
303 * /return void |
|
304 */ |
|
305 void sendreply_cb( DBusGProxy *proxy, GError *error, gpointer userdata ) |
|
306 { |
|
307 int err = 0; |
|
308 |
|
309 message_hdr_req* msg_hdr = ( message_hdr_req* ) userdata; |
|
310 // create the msg queue |
|
311 //user data is of type message_hdr_req |
|
312 iso_logger( "%s", "In - sendreply_cb\n" ); |
|
313 UNUSED_FORMAL_PARAM(proxy); |
|
314 if ( NULL != error ) |
|
315 { |
|
316 //There was some error |
|
317 //send the response for the msg_hdr request to client |
|
318 err = send_response_to_client( msg_hdr, error->code, 0 ); |
|
319 //free the message |
|
320 g_error_free(error); |
|
321 |
|
322 } |
|
323 else |
|
324 { |
|
325 //send the response for the msg_hdr request to client |
|
326 err = send_response_to_client( msg_hdr, 0, 1 ); |
|
327 } |
|
328 //Free the header recved as callback userdata |
|
329 free( msg_hdr ); |
|
330 |
|
331 if ( err < 0 ) |
|
332 { |
|
333 // failed to delievered |
|
334 return ; |
|
335 } |
|
336 iso_logger( "%s", "Out - sendreply_cb\n" ); |
|
337 } |
|
338 |
|
339 /*! /brief This function is called by tg to as a response to request for the |
|
340 * handles from the text channel. If there is no error, sent message( |
|
341 * which has failed ) with its deatils is then sent to client |
|
342 * |
|
343 * /param proxy unused |
|
344 * /param handles_names contac names (sender name) |
|
345 * /param error error if any |
|
346 * /param userdata send_error_struct |
|
347 * /return void |
|
348 */ |
|
349 static void inspect_handles_for_error_cb( DBusGProxy *proxy,char **handles_names, |
|
350 GError *error, gpointer userdata ) |
|
351 { |
|
352 |
|
353 gint pri = MSG_PRI_NORMAL; |
|
354 gint result = 0; |
|
355 gint timeout = NO_WAIT; |
|
356 gint err = 0; |
|
357 |
|
358 send_error_struct* msg_struct = ( send_error_struct* ) userdata; |
|
359 gchar* rmsg = NULL; |
|
360 gint index = 0; |
|
361 gint len = 0; |
|
362 UNUSED_FORMAL_PARAM(proxy); |
|
363 iso_logger( "%s", "In - inspect_handles_for_error_cb" ); |
|
364 if ( !handles_names || error || NULL == handles_names[0] ) |
|
365 { |
|
366 if ( error ) |
|
367 { |
|
368 g_error_free( error ); |
|
369 } |
|
370 //Free the userdata passed to the callback |
|
371 if ( NULL != msg_struct ) |
|
372 { |
|
373 if ( msg_struct->msg_body ) |
|
374 { |
|
375 g_free( msg_struct->msg_body ); |
|
376 } |
|
377 g_free( msg_struct ); |
|
378 } |
|
379 return; |
|
380 } |
|
381 //Allocate the memory and check for NULL |
|
382 rmsg = ( gchar* ) malloc ( MAX_MSG_SIZE ); |
|
383 if ( NULL == rmsg ) |
|
384 { |
|
385 goto mem_clean; |
|
386 } |
|
387 //set memory to 0 |
|
388 memset( rmsg, '\0', MAX_MSG_SIZE ); |
|
389 //copy the header |
|
390 //the response header, message type(from libtp), timestamp |
|
391 memcpy( rmsg + index, msg_struct, sizeof( message_hdr_resp ) |
|
392 + 2 * sizeof( guint ) ); |
|
393 |
|
394 index += sizeof( message_hdr_resp ) + 2 * sizeof( guint ); |
|
395 |
|
396 //Copy the name to whom message was sent |
|
397 len = strlen( handles_names[0] ); |
|
398 strcpy( rmsg + index, handles_names[0] ); |
|
399 index += len + 1; |
|
400 |
|
401 //Copy the message body |
|
402 if ( msg_struct->msg_body ) |
|
403 { |
|
404 len = strlen( msg_struct->msg_body ); |
|
405 strcpy( rmsg + index, msg_struct->msg_body ); |
|
406 index += len + 1; |
|
407 } |
|
408 rmsg[index++] = '\0'; |
|
409 //Header format |
|
410 //msgHdr|msg_type|timestamp|reciepient_name\0sent_msg\0 |
|
411 // ^ ^ ^ |
|
412 // | | | |
|
413 //no dilimeter here nul nul |
|
414 //send to the client |
|
415 result = MsgQSend( RESPONSE_QUEUE, rmsg, index, |
|
416 pri, timeout, &err ); |
|
417 iso_logger( "%s", "After MsgQSend" ); |
|
418 //If memory allocation for rmsg has failed control comes |
|
419 //here |
|
420 mem_clean: |
|
421 |
|
422 for ( len = 0; handles_names[len]; len++ ) |
|
423 { |
|
424 free ( handles_names[len] ); |
|
425 } |
|
426 |
|
427 if ( msg_struct->msg_body ) |
|
428 { |
|
429 g_free( msg_struct->msg_body ); |
|
430 } |
|
431 g_free( msg_struct ); |
|
432 |
|
433 if ( result < 0 ) |
|
434 { |
|
435 //Failed to deliver the message |
|
436 iso_logger( "%s", "Failed to deliver the message to client" ); |
|
437 return; |
|
438 } |
|
439 iso_logger( "%s", "Out - inspect_handles_for_error_cb" ); |
|
440 |
|
441 } |
|
442 |
|
443 /*! /brief This function on registered for "senderror" signal is called when the message |
|
444 * sending is failed. Calls tp_conn_inspect_handles_async to get the contact name |
|
445 * from text channel |
|
446 * |
|
447 * /param proxy : unused |
|
448 * /param error : error code |
|
449 * /param timestamp : sent to inspect_handles_for_error_cb thru' send_error_struct |
|
450 * /param message_type : sent to inspect_handles_for_error_cb thru' send_error_struct |
|
451 * /param message_body : sent to inspect_handles_for_error_cb thru' send_error_struct |
|
452 * /param user_data text_chan from where to get the contatc name of reciepien |
|
453 * /return void |
|
454 */ |
|
455 static void senderror_cb ( DBusGProxy *proxy, |
|
456 guint error, |
|
457 guint timestamp, |
|
458 guint message_type, |
|
459 gchar *message_body, |
|
460 gpointer user_data ) |
|
461 { |
|
462 |
|
463 TpChan *text_chan = ( TpChan * ) user_data; |
|
464 send_error_struct* msg_struct = NULL; |
|
465 GArray* fetch_members = NULL; |
|
466 DBusGProxyCall* call_id = NULL; |
|
467 |
|
468 //Logs |
|
469 iso_logger( "%s", "In - SendError_cb\n" ); |
|
470 iso_logger( "error is %d", error ); |
|
471 iso_logger( "error is %d", message_type ); |
|
472 iso_logger( "error is %d", timestamp ); |
|
473 iso_logger( "error is %s", message_body ); |
|
474 UNUSED_FORMAL_PARAM(proxy); |
|
475 //Allocate memory and check for NULL |
|
476 //This msg_struct is passed to callback.. |
|
477 //So not deleting here.. ownership is transfered |
|
478 msg_struct = ( send_error_struct* ) malloc ( sizeof( send_error_struct ) ); |
|
479 |
|
480 if ( NULL == text_chan || NULL == msg_struct ) |
|
481 { |
|
482 return; |
|
483 } |
|
484 //Set the values to NULL |
|
485 memset( msg_struct, '\0', sizeof( send_error_struct ) ); |
|
486 //Message type is send error |
|
487 msg_struct->hdr_resp.hdr_req.message_type = ESend_Error; |
|
488 //other values are set to 0 |
|
489 msg_struct->hdr_resp.hdr_req.protocol_id = 0; |
|
490 msg_struct->hdr_resp.hdr_req.session_id = 0; |
|
491 msg_struct->hdr_resp.hdr_req.request_id = 0; |
|
492 |
|
493 //Message is sent as single entity.. |
|
494 //Message is not long enough to be broken into |
|
495 msg_struct->hdr_resp.continue_flag = 0; |
|
496 msg_struct->hdr_resp.response = 0; |
|
497 |
|
498 //Set the error type |
|
499 msg_struct->hdr_resp.error_type = error; |
|
500 //Set the values from libtelepathy |
|
501 msg_struct->msg_type = message_type; |
|
502 msg_struct->timestamp = timestamp; |
|
503 //Not checking for NULL here.. |
|
504 //I feel it is ok to send without the message |
|
505 //Taken care of this in inspect_handles_for_error_cb |
|
506 msg_struct->msg_body = strdup( message_body ); |
|
507 |
|
508 //Create an array of handles to get the handle name |
|
509 fetch_members = g_array_new ( FALSE, FALSE, sizeof ( guint32 ) ); |
|
510 g_array_append_val( fetch_members, text_chan->handle ); |
|
511 //Call libtp function to get the contact name for the handle |
|
512 //msg_struct is passed to inspect handles call back to be passed to |
|
513 //client as error |
|
514 call_id = tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
515 TP_CONN_HANDLE_TYPE_CONTACT ,fetch_members, |
|
516 inspect_handles_for_error_cb, msg_struct ); |
|
517 |
|
518 g_array_free( fetch_members, TRUE ); |
|
519 if ( NULL == call_id ) |
|
520 { |
|
521 return ; |
|
522 } |
|
523 |
|
524 iso_logger( "%s", "Out - SendError_cb" ); |
|
525 |
|
526 } |
|
527 |
|
528 |
|
529 |
|
530 |
|
531 /*! /brief called as a callback to acknowledge the msg ack. |
|
532 * |
|
533 * /param proxy unused |
|
534 * /param error error if any |
|
535 * /param userdata unused |
|
536 * /return void |
|
537 */ |
|
538 static void msg_ack_pending_cb( DBusGProxy *proxy, GError *error, gpointer userdata ) |
|
539 |
|
540 { |
|
541 gchar *str = "Inside msg_ack_pending_cb"; |
|
542 UNUSED_FORMAL_PARAM(proxy); |
|
543 UNUSED_FORMAL_PARAM(userdata); |
|
544 if ( error ) |
|
545 { |
|
546 //If there was error, ignore it and free the memory |
|
547 g_error_free(error); |
|
548 } |
|
549 |
|
550 iso_logger( str ); |
|
551 } |
|
552 |
|
553 |
|
554 |
|
555 /*! /brief This function is a callback for to get the contact name from handles. |
|
556 * This function acknowledges the recieved message and send that to client(adap) |
|
557 * |
|
558 * /param proxy unused |
|
559 * /param handles_names 2D array of message sender(one contact ended with a NULL string) |
|
560 * /param error error if any |
|
561 * /param userdata Received_UserData that has message body, response header etc., |
|
562 * /return void |
|
563 */ |
|
564 static void getting_sender_cb( DBusGProxy *proxy,char **handles_names, GError *error, gpointer userdata ) |
|
565 { |
|
566 |
|
567 gchar *str = "Inside getting_sender_cb"; |
|
568 GArray *message_ids; |
|
569 gint result = 0; |
|
570 Received_UserData *user_data = ( Received_UserData* )userdata; |
|
571 iso_logger( "%s", str ); |
|
572 UNUSED_FORMAL_PARAM(proxy); |
|
573 if ( !handles_names || error ) |
|
574 { |
|
575 if ( error ) |
|
576 { |
|
577 //If there was error, ignore it and free the memory |
|
578 g_error_free(error); |
|
579 } |
|
580 //Free the userdata passed to the callback |
|
581 g_free( user_data->message_body ); |
|
582 g_free( user_data ); |
|
583 iso_logger( "%s", "handle names error" ); |
|
584 return; |
|
585 } |
|
586 |
|
587 message_ids = g_array_new ( FALSE, FALSE, sizeof ( guint ) ); |
|
588 if ( NULL == message_ids ) |
|
589 { |
|
590 //Free the userdata passed to the callback |
|
591 g_free( user_data->message_body ); |
|
592 g_free( user_data ); |
|
593 return ; |
|
594 } |
|
595 g_array_append_val ( message_ids, user_data->message_id ); |
|
596 //Acknowledge that message has been recieved |
|
597 tp_chan_type_text_acknowledge_pending_messages_async( user_data->proxy, message_ids, |
|
598 msg_ack_pending_cb, NULL ); |
|
599 //Send to the client the messgae and the sender name |
|
600 result = send_message_to_client( user_data->message_body , *handles_names ); |
|
601 |
|
602 if ( 0 > result ) |
|
603 { |
|
604 return; |
|
605 } |
|
606 |
|
607 iso_logger( "%s", "getting_sender_cb" ); |
|
608 iso_logger( "%s", user_data->message_body ); |
|
609 |
|
610 //Free the messgae ids array |
|
611 g_array_free ( message_ids, TRUE ); |
|
612 //free the recieved data |
|
613 g_free( user_data->message_body ); |
|
614 g_free( user_data ); |
|
615 |
|
616 |
|
617 } |
|
618 |
|
619 |
|
620 |
|
621 |
|
622 /*! /brief when a message is recieved this function is called by |
|
623 * telepathygabble(by emitting signal). This function then requests tg |
|
624 * to get the contact names corresponding to handles. |
|
625 * |
|
626 * /param proxy sent to getting_sender_cb as param in userdata |
|
627 * /param timestamp unused |
|
628 * /param handles_names |
|
629 * /param message_type unused |
|
630 * /param message_flags unused |
|
631 * /param message_body recieved message |
|
632 * /param userdata unused |
|
633 */ |
|
634 void receivedMessage_cb ( DBusGProxy *proxy, |
|
635 guint message_id, |
|
636 guint timestamp, |
|
637 guint from_handle, |
|
638 guint message_type, |
|
639 guint message_flags, |
|
640 gchar *message_body, |
|
641 gpointer user_data ) |
|
642 { |
|
643 GArray *handles = NULL; |
|
644 Received_UserData *recv_userdata = NULL; |
|
645 |
|
646 iso_logger( "%s", "receivedMessage_cb:" ); |
|
647 UNUSED_FORMAL_PARAM(timestamp); |
|
648 UNUSED_FORMAL_PARAM(message_type); |
|
649 UNUSED_FORMAL_PARAM(message_flags); |
|
650 UNUSED_FORMAL_PARAM(user_data); |
|
651 //Allocate memory and initalize the structure |
|
652 recv_userdata = g_new ( Received_UserData, 1 ); |
|
653 if ( NULL == recv_userdata ) |
|
654 { |
|
655 |
|
656 free ( message_body ); |
|
657 return ; |
|
658 } |
|
659 //TBD : Check if this assignment works.. |
|
660 //previously it was strdup of message_body |
|
661 recv_userdata->message_body = strdup( message_body ); |
|
662 recv_userdata->message_id = message_id; |
|
663 recv_userdata->proxy = proxy; |
|
664 |
|
665 //logs |
|
666 iso_logger( "%s", message_body ); |
|
667 //allocate memory for the handles |
|
668 handles = g_array_new ( FALSE, FALSE, sizeof ( guint32 ) ); |
|
669 if ( NULL == handles ) |
|
670 { |
|
671 //free previously allocated struct |
|
672 g_free( recv_userdata->message_body ); |
|
673 g_free( recv_userdata ); |
|
674 return ; |
|
675 } |
|
676 |
|
677 g_array_append_val ( handles, from_handle ); |
|
678 //get the sender name corresponding to the handles |
|
679 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
680 TP_CONN_HANDLE_TYPE_CONTACT ,handles, |
|
681 getting_sender_cb,recv_userdata ); |
|
682 //free handles |
|
683 g_array_free ( handles, TRUE ); |
|
684 |
|
685 } |
|
686 |
|
687 |
|
688 /*! /brief whenevr a new channel handler for text is created, this function is called. This |
|
689 * function also registers that channel for Received and SendError signals. Also the pending |
|
690 * messages are also retrieved in this function |
|
691 * |
|
692 * /param tp_chan new channel created |
|
693 */ |
|
694 void text_channel_init( TpChan *text_chan ) |
|
695 { |
|
696 |
|
697 GPtrArray *messages_list ; |
|
698 guint i = 0; |
|
699 GArray *message_ids; |
|
700 DBusGProxy *text_iface; |
|
701 GArray *handles = NULL; |
|
702 Received_UserData *recv_userdata = NULL; |
|
703 |
|
704 |
|
705 iso_logger( "%s", "inside text_channel_init" ); |
|
706 //text_chan has been checked for NULL in the callee function |
|
707 text_iface = tp_chan_get_interface( text_chan , |
|
708 TELEPATHY_CHAN_IFACE_TEXT_QUARK ); |
|
709 |
|
710 message_ids = g_array_new ( FALSE, TRUE, sizeof ( guint ) ); |
|
711 |
|
712 handles = g_array_new ( FALSE, FALSE, sizeof ( guint32 ) ); |
|
713 //If memory allocation fialure, return from here |
|
714 if ( !text_iface || !message_ids || !handles ) |
|
715 { |
|
716 return ; |
|
717 } |
|
718 |
|
719 tp_chan_type_text_list_pending_messages( text_iface, |
|
720 FALSE, |
|
721 &messages_list, |
|
722 NULL ); |
|
723 //For all the pending messages get the sender name |
|
724 //and send to client the sender name and recv msg |
|
725 for ( i = 0; i < messages_list->len ; i++ ) |
|
726 { |
|
727 guint message_id; |
|
728 guint from_handle; |
|
729 const gchar *message_body; |
|
730 GValueArray *message_struct; |
|
731 |
|
732 message_struct = ( GValueArray * ) g_ptr_array_index ( messages_list, i ); |
|
733 |
|
734 //Not all the fields used currently |
|
735 //Ignoring the unused fields |
|
736 message_id = g_value_get_uint( g_value_array_get_nth( message_struct, 0 ) ); |
|
737 //get the handle to sender |
|
738 from_handle = g_value_get_uint(g_value_array_get_nth( message_struct, 2 ) ); |
|
739 //Get the message body |
|
740 message_body = g_value_get_string( g_value_array_get_nth( message_struct, 5 ) ); |
|
741 |
|
742 iso_logger ( "%s", message_body ); |
|
743 |
|
744 g_array_append_val( handles, from_handle ); |
|
745 //Allocate memory for the recv data |
|
746 recv_userdata = g_new( Received_UserData, 1 ); |
|
747 if ( !recv_userdata ) |
|
748 { |
|
749 break; //Break from the loop |
|
750 } |
|
751 //Set all the necessary fields |
|
752 recv_userdata->message_body = g_strdup( message_body ); |
|
753 recv_userdata->message_id = message_id; |
|
754 recv_userdata->proxy = text_iface; |
|
755 //get the name for the sender handle |
|
756 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
757 TP_CONN_HANDLE_TYPE_CONTACT ,handles, |
|
758 getting_sender_cb, recv_userdata ); |
|
759 |
|
760 g_array_append_val ( message_ids, message_id ); |
|
761 |
|
762 //To reuse the array, remove the 1 that was inserted |
|
763 g_array_remove_range( handles, 0, handles->len ); |
|
764 |
|
765 } |
|
766 iso_logger ( "%s", "before ack pending msg"); |
|
767 //acknowledge the recved messages |
|
768 tp_chan_type_text_acknowledge_pending_messages( text_iface, message_ids, |
|
769 NULL ); |
|
770 |
|
771 iso_logger ( "%s", "after ack pending msg" ); |
|
772 |
|
773 //Listen to Received signal |
|
774 dbus_g_proxy_connect_signal( text_iface, "Received", |
|
775 G_CALLBACK( receivedMessage_cb ), |
|
776 NULL, NULL ); |
|
777 |
|
778 //Register for the senderror signal |
|
779 dbus_g_proxy_connect_signal( text_iface, "SendError", |
|
780 G_CALLBACK( senderror_cb ), |
|
781 text_chan, NULL ); |
|
782 |
|
783 //Should the messages_list be freed? |
|
784 g_array_free( message_ids, TRUE ); |
|
785 g_array_free( handles, TRUE ); |
|
786 |
|
787 |
|
788 } |
|
789 |
|
790 |
|
791 |
|
792 |
|
793 /*! /brief called by getting_sender_cb to send the recieved message to client |
|
794 * |
|
795 * /param msg message recieved |
|
796 * /param sender message from whom recieved |
|
797 */ |
|
798 gint send_message_to_client( const gchar *msg , const gchar *sender ) |
|
799 |
|
800 { |
|
801 gint len=0; |
|
802 gint pri = MSG_PRI_NORMAL; |
|
803 gchar *rmsg = NULL; |
|
804 gint index = 0; |
|
805 gint err; |
|
806 message_hdr_resp* msg_resp = NULL; |
|
807 gint result; |
|
808 gint timeout = NO_WAIT; |
|
809 |
|
810 msg_resp = ( message_hdr_resp* ) malloc ( sizeof( message_hdr_resp ) ); |
|
811 if ( NULL == msg_resp ) |
|
812 { |
|
813 return MEM_ALLOCATION_ERROR; |
|
814 } |
|
815 //Allocate memory and initialze to 0 |
|
816 rmsg = ( gchar* ) malloc ( MAX_MSG_SIZE ); |
|
817 if ( NULL == rmsg ) |
|
818 { |
|
819 free ( msg_resp ); |
|
820 return MEM_ALLOCATION_ERROR; |
|
821 } |
|
822 |
|
823 //Initialze the memory to 0 |
|
824 memset( msg_resp, '\0', sizeof( message_hdr_resp ) ); |
|
825 //Set the message type to EText_Message_Receive and set other fields |
|
826 //to default values |
|
827 msg_resp->hdr_req.message_type = EText_Message_Receive; |
|
828 msg_resp->hdr_req.protocol_id = 1; |
|
829 msg_resp->hdr_req.session_id = 1; |
|
830 msg_resp->hdr_req.request_id =1; |
|
831 //Set the respone as success and error is 0 |
|
832 msg_resp->response = 1; |
|
833 msg_resp->error_type = 0; |
|
834 |
|
835 memset( rmsg, '\0', MAX_MSG_SIZE ); |
|
836 //copy the header |
|
837 memcpy( rmsg, msg_resp, sizeof( message_hdr_resp ) ); |
|
838 index += sizeof( message_hdr_resp ); |
|
839 |
|
840 //copy the sender |
|
841 //putting sender in message queue |
|
842 len = strlen(sender); |
|
843 strcpy( rmsg + index, sender ); |
|
844 index += len + 1; |
|
845 |
|
846 //putting message body |
|
847 len = strlen(msg); |
|
848 strcpy( rmsg + index, msg ); |
|
849 index += len + 1; |
|
850 |
|
851 //Header format |
|
852 //msgHdr|sender_name\0recved_msg\0 |
|
853 // ^ ^ ^ |
|
854 // | | | |
|
855 //no dilimeter here nul nul |
|
856 //send to the client |
|
857 result = MsgQSend( RESPONSE_QUEUE, rmsg, index, |
|
858 pri, timeout, &err ); |
|
859 free ( rmsg ); |
|
860 |
|
861 free ( msg_resp ); |
|
862 |
|
863 if ( result < 0 ) |
|
864 { |
|
865 return MSG_Q_SEND_FAILED; |
|
866 } |
|
867 |
|
868 iso_logger( "%s", "message is:\n" ); |
|
869 return TRUE; |
|
870 } |
|
871 |
|
872 // end of files |
|
873 |
|
874 |
|