|
1 /* |
|
2 * ============================================================================ |
|
3 * Name : isomodifycontacts.h |
|
4 * Part of : isolation server. |
|
5 * Version : %version: 16 % |
|
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 #include <stdio.h> |
|
31 #include <stdlib.h> |
|
32 #include <string.h> |
|
33 #include <glib.h> |
|
34 #include "msgliterals.h" |
|
35 #include "isomodifycontactlist.h" |
|
36 #include "isoutils.h" |
|
37 #include "isofetchcontactlist.h" //For send_contact_to_client func |
|
38 |
|
39 /*! \file |
|
40 * Impliments the functions in isomodifycontactlist.h |
|
41 */ |
|
42 |
|
43 /*! |
|
44 * /brief This function is called by message_send_recv function in isoservermain.c if message type |
|
45 * is EReject_Contact_Request, EAccept_Contact_Request, EAdd_Contact_Request and EDelete_Contact_Request. |
|
46 * Contacts added/removed to/from list. This function parses the message buffer, |
|
47 * validates for the arguments and calls modify_contact_list to add/remove contacts |
|
48 * |
|
49 * /param buf : buffer to be parsed |
|
50 * /param buf_len : buffer length |
|
51 * /return : error code if any, 0 on success |
|
52 */ |
|
53 gint action_parse_modify_contact_list( gchar* buf, gint buf_len ) |
|
54 { |
|
55 gchar** contactid = NULL; |
|
56 gchar* msg = NULL; |
|
57 gint meesage_type_err = 0; |
|
58 gint len = 0; |
|
59 gint contact_count = 0; |
|
60 |
|
61 //parse contacts, message.. |
|
62 iso_logger( "%s", "In - action_parse_modify_contact_list" ); |
|
63 len += sizeof( message_hdr_req ); |
|
64 //example send message - message header omitted.. |
|
65 //test.ximp@gmail.com\0ximp.telepathy@gmail.com\0\0I would like to add u!\0 |
|
66 // ^ ^ ^ ^ |
|
67 //contact1------------|contact2-----------------|-|message----------------| |
|
68 //Till Message part is parsed by the following function |
|
69 meesage_type_err = parse_into_array_of_strings( buf, &contactid, &len, buf_len, &contact_count ); |
|
70 if ( meesage_type_err < 0 ) |
|
71 { |
|
72 gchar* msg = NULL; |
|
73 //An error has occured, so propagate to next level |
|
74 free_msg_args( contactid, contact_count, msg ); |
|
75 //got error, print to file |
|
76 return meesage_type_err; |
|
77 } |
|
78 |
|
79 //Parse the message |
|
80 //message is optional.. so check if message has been sent |
|
81 if ( len < buf_len ) |
|
82 { |
|
83 |
|
84 gint err = 0; |
|
85 |
|
86 // iso_logger( "%x", len ); |
|
87 // iso_logger( "%f", len ); |
|
88 |
|
89 //parse for the message.. |
|
90 err = parse_a_string( buf, &msg, &len, buf_len ); |
|
91 |
|
92 if ( err < 0 ) |
|
93 { |
|
94 //return err; |
|
95 //ignoring the error.. |
|
96 //as message is not that important |
|
97 msg = NULL; |
|
98 } |
|
99 } |
|
100 //If there is atleast one contact to add |
|
101 if ( contact_count > 0 ) |
|
102 { |
|
103 //Add the header and message to the msg struct |
|
104 //this struct will be used in the callbacks |
|
105 send_msg_struct* msg_struct = NULL; |
|
106 msg_struct = ( send_msg_struct* ) malloc( sizeof( send_msg_struct ) ); |
|
107 if ( NULL == msg_struct ) |
|
108 { |
|
109 //An error has occured, so propagate to next level |
|
110 free_msg_args( contactid, contact_count, msg ); |
|
111 return MEM_ALLOCATION_ERROR; |
|
112 } |
|
113 //allocate memory and check for the returned value |
|
114 msg_struct->hdr_req = ( message_hdr_req* ) malloc( sizeof( message_hdr_req ) ); |
|
115 if ( NULL == msg_struct->hdr_req ) |
|
116 { |
|
117 //An error has occured, so propagate to next level |
|
118 free_msg_args( contactid, contact_count, msg ); |
|
119 free ( msg_struct ); |
|
120 return MEM_ALLOCATION_ERROR; |
|
121 } |
|
122 //initalize to 0... |
|
123 memset( msg_struct->hdr_req, '\0', sizeof( message_hdr_req ) ); |
|
124 //read message header from buffer |
|
125 memcpy( msg_struct->hdr_req, buf, sizeof( message_hdr_req ) ); |
|
126 //message, msg can be NULL as well |
|
127 msg_struct->msg = msg; |
|
128 |
|
129 meesage_type_err = modify_contact_list( msg_struct, |
|
130 ( const char** )contactid, meesage_type_err ); |
|
131 if ( meesage_type_err < 0 ) |
|
132 { |
|
133 //Do cleanup here |
|
134 //delete contact_ids and message |
|
135 //An error has occured, so propagate to next level |
|
136 free_msg_args( contactid, contact_count, msg ); |
|
137 free ( msg_struct->hdr_req ); |
|
138 free ( msg_struct ); |
|
139 return meesage_type_err; |
|
140 } |
|
141 } |
|
142 |
|
143 iso_logger( "%s", "In - action_parse_modify_contact_list" ); |
|
144 |
|
145 return meesage_type_err; |
|
146 } |
|
147 |
|
148 |
|
149 /*! |
|
150 * /brief gets the handles for contacts. Handles are returned in request_modify_contact_list_handles_cb |
|
151 * callback which is an arg for the async request to get handles. |
|
152 * |
|
153 * /param msg_hdr : The header and message passed to callbacks |
|
154 * /param contact_id : contact ids whose handles to be returned |
|
155 * /param no_cntcts : total no. of contacts to be added |
|
156 * /return : error code if any, handle on success |
|
157 */ |
|
158 guint get_handles_for_contacts ( send_msg_struct* msg_hdr, const gchar **contact_id, |
|
159 gint no_cntcts ) |
|
160 { |
|
161 |
|
162 iso_logger( "%s", "in -- get_handles_for_contacts" ); |
|
163 |
|
164 //check for the return value if 0 is ok or should some negative value to be passed |
|
165 g_return_val_if_fail (contact_id != NULL, 0); |
|
166 |
|
167 //Send request to get the handles for the contacts.. |
|
168 //handles will be returned in request_addcontacts_handles_cb |
|
169 tp_conn_request_handles_async( DBUS_G_PROXY(globalCon.conn), |
|
170 TP_CONN_HANDLE_TYPE_CONTACT, contact_id, |
|
171 request_modify_contact_list_handles_cb, ( gpointer )msg_hdr ); |
|
172 |
|
173 iso_logger( "%s", "in -- get_handles_for_contacts" ); |
|
174 //no of contacts is returned on successful completion of getting handles |
|
175 return no_cntcts; |
|
176 } |
|
177 |
|
178 |
|
179 /*! |
|
180 * /brief Handles are returned in this callback. Which will then actually do modify |
|
181 * the contact list based on the request type(add/remove/accept/reject) |
|
182 * modify_contact_list_cb is registered as the callback. |
|
183 * |
|
184 * /param proxy : unused |
|
185 * /param handles : handles of the contacts |
|
186 * /param error : error if any |
|
187 * /param message : userdata(send_msg_struct) passed back |
|
188 * /return : error code if any, handle on success |
|
189 */ |
|
190 void request_modify_contact_list_handles_cb( DBusGProxy *proxy, GArray *handles, |
|
191 GError* error, gpointer message ) |
|
192 { |
|
193 send_msg_struct* msg_hdr = ( send_msg_struct* ) message; |
|
194 UNUSED_FORMAL_PARAM(proxy); |
|
195 iso_logger( "%s", "in -- request_modify_contact_list_handles_cb" ); |
|
196 |
|
197 if ( !handles || error ) |
|
198 { |
|
199 send_response_to_client( msg_hdr->hdr_req, error->code, 0 ); |
|
200 |
|
201 if ( error ) |
|
202 { |
|
203 g_error_free(error); |
|
204 } |
|
205 free ( msg_hdr->msg ); |
|
206 free ( msg_hdr->hdr_req ); |
|
207 free ( msg_hdr ); |
|
208 iso_logger( "%s", "handle got is invalid" ); |
|
209 return; |
|
210 } |
|
211 |
|
212 //Check if the request is to add contact or delete contact |
|
213 if ( EAdd_Contact_Request == msg_hdr->hdr_req->message_type ) |
|
214 { |
|
215 //got the handles for contacts now send request to add those contacts |
|
216 tp_chan_iface_group_add_members_async ( globalCon.group_iface_subscribe, handles, |
|
217 msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req ); |
|
218 } |
|
219 else if ( EDelete_Contact_Request == msg_hdr->hdr_req->message_type ) |
|
220 { |
|
221 //got the handles for contacts now send request to delete those contacts |
|
222 tp_chan_iface_group_remove_members_async ( globalCon.group_iface_known, handles, |
|
223 msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req ); |
|
224 } |
|
225 else if ( EAccept_Contact_Request == msg_hdr->hdr_req->message_type ) |
|
226 { |
|
227 //got the handles for contacts now send request to add those contacts |
|
228 tp_chan_iface_group_add_members_async ( globalCon.group_iface_publish, handles, |
|
229 msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req ); |
|
230 } |
|
231 else if ( EReject_Contact_Request == msg_hdr->hdr_req->message_type ) |
|
232 { |
|
233 //got the handles for contacts now send request to delete those contacts |
|
234 tp_chan_iface_group_remove_members_async ( globalCon.group_iface_publish, handles, |
|
235 msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req ); |
|
236 } |
|
237 |
|
238 //free handles |
|
239 g_array_free ( handles, TRUE ); |
|
240 //free header |
|
241 //hdr_req not to be freed, it is freed by modify_contact_list_cb |
|
242 free ( msg_hdr->msg ); |
|
243 free ( msg_hdr ); |
|
244 iso_logger( "%s", "out -- request_modify_contact_list_handles_cb" ); |
|
245 } |
|
246 |
|
247 /*! |
|
248 * /brief Calls get_handles_for_contacts to get the handles for contact. |
|
249 * |
|
250 * /param msg_hdr : message request header passed to callbacks |
|
251 * /param contact_id : contact ids to be added |
|
252 * /param message : messgae if any |
|
253 * /param no_cntcts : no of contacts to be added |
|
254 * /return void |
|
255 */ |
|
256 gint modify_contact_list ( send_msg_struct* msg_hdr, const gchar **contact_ids, |
|
257 gint no_cntcts ) |
|
258 { |
|
259 |
|
260 guint err = 0; |
|
261 |
|
262 iso_logger( "%s", "in -- modify_contact_list" ); |
|
263 |
|
264 //g_array_append_val ( handles, handle ); |
|
265 //gets the handles for contacts |
|
266 //Handles are returned in request_addcontacts_handles_cb callback |
|
267 err = get_handles_for_contacts( msg_hdr, contact_ids, no_cntcts ); |
|
268 |
|
269 iso_logger( "%s", "Out -- -- modify_contact_list" ); |
|
270 |
|
271 return err; |
|
272 |
|
273 |
|
274 } |
|
275 |
|
276 /*! |
|
277 * /brief called as callback for request for modify contact list |
|
278 * This function then sends the result to client |
|
279 * |
|
280 * /param proxy unused |
|
281 * /param error Error if any |
|
282 * /param userdata request message header |
|
283 * /return void |
|
284 */ |
|
285 void modify_contact_list_cb( DBusGProxy *proxy, GError *error, gpointer userdata ) |
|
286 { |
|
287 |
|
288 int err = 0; |
|
289 //user data is of type message_hdr_req |
|
290 message_hdr_req *msg_hdr = ( message_hdr_req * )userdata; |
|
291 UNUSED_FORMAL_PARAM(proxy); |
|
292 iso_logger( "%s", "In - modify_contact_list_cb\n" ); |
|
293 //Check if there is any error |
|
294 if ( NULL != error ) |
|
295 { |
|
296 //Failed to add contact: |
|
297 iso_logger ( "%s", "Failed to modify contact: \n" ); |
|
298 |
|
299 err = send_response_to_client( msg_hdr, error->code, 0 ); |
|
300 g_error_free(error); |
|
301 } |
|
302 else |
|
303 { |
|
304 //Contact added successfully: |
|
305 iso_logger ( "%s", "Contact modify successfully:" ); |
|
306 err = send_response_to_client( msg_hdr, 0, 1 ); |
|
307 } |
|
308 //free the msg hdr |
|
309 free( msg_hdr ); |
|
310 |
|
311 if ( err < 0 ) |
|
312 { |
|
313 // failed to delievered |
|
314 return ; |
|
315 } |
|
316 iso_logger( "%s", "out -- modify_contact_list_cb" ); |
|
317 } |
|
318 |
|
319 |
|
320 /*! |
|
321 * /brief The contact names corresponding to the contact handles that are changed |
|
322 * are passed to the client |
|
323 * /param proxy |
|
324 * /param handles_name |
|
325 * /param error |
|
326 * /param userdata |
|
327 * /return void |
|
328 */ |
|
329 static void rosters_changed_contacts_cb( DBusGProxy *proxy, |
|
330 gchar **handles_names, GError *error, gpointer userdata ) |
|
331 { |
|
332 gint i = 0; |
|
333 gchar* member = NULL; |
|
334 gint mem_count = 0; |
|
335 |
|
336 gint* msg_type = ( gint* ) userdata; |
|
337 |
|
338 iso_logger( "%s", "In -- rosters_changed_contacts_cb" ); |
|
339 UNUSED_FORMAL_PARAM(proxy); |
|
340 if ( !handles_names || error ) |
|
341 { |
|
342 if ( error ) |
|
343 { |
|
344 g_error_free(error); |
|
345 } |
|
346 free ( msg_type ); |
|
347 iso_logger( "%s", "handle names error" ); |
|
348 return; |
|
349 } |
|
350 |
|
351 //read all the contacts |
|
352 //The handles_names will have NULL as it last elemnt in the array |
|
353 for ( i = 0; handles_names[i]; i++ ) |
|
354 { |
|
355 member = handles_names[i]; |
|
356 iso_logger( "This member : %s is trying to add you", |
|
357 member ); |
|
358 mem_count++; |
|
359 } |
|
360 //code to send the added contact to client |
|
361 if ( mem_count ) |
|
362 { |
|
363 gint err = 0; |
|
364 err = send_contacts_to_client( handles_names, mem_count, *msg_type ); |
|
365 if ( err ) |
|
366 { |
|
367 //How to handle the error? |
|
368 for ( i = 0; i < mem_count; i++ ) |
|
369 { |
|
370 free ( handles_names[i] ); |
|
371 } |
|
372 iso_logger( "%s", "There was error in send_contacts_to_client" ); |
|
373 free ( msg_type ); |
|
374 return; |
|
375 } |
|
376 } |
|
377 |
|
378 free ( msg_type ); |
|
379 |
|
380 iso_logger( "%s", "Out -- rosters_changed_contacts_cb" ); |
|
381 |
|
382 } |
|
383 |
|
384 /*! /brief Whenever contact list is changed by others( someone trying to add this user |
|
385 * or someone rejecting the add request etc., ) this callback registered as a signal |
|
386 * is called with the handles of the changed contacts. rosters_changed_contacts_cb is |
|
387 * passed as callback to get the contact name of the changed handles |
|
388 * |
|
389 * /param group_iface unused |
|
390 * /param message unused |
|
391 * /param added List of contacts that are recently added |
|
392 * /param removed List of contacts that were recently removed |
|
393 * /param local_pending List of contacts that are locally pending for approval |
|
394 * /param remote_pending List of contacts that are remotely pending for approval |
|
395 * /param actor unused |
|
396 * /param reason unused |
|
397 * /param userdata unused |
|
398 * /return void |
|
399 */ |
|
400 void roster_members_changed_cb ( DBusGProxy *group_iface, |
|
401 gchar *message, |
|
402 GArray *added, |
|
403 GArray *removed, |
|
404 GArray *local_pending, |
|
405 GArray *remote_pending, |
|
406 guint actor, |
|
407 guint reason, |
|
408 gpointer userdata ) |
|
409 { |
|
410 |
|
411 gint* msg_type = ( gint* ) malloc ( sizeof( gint* ) ); |
|
412 |
|
413 iso_logger( "%s", "In - roster_members_changed_cb\n" ); |
|
414 |
|
415 //members in the contact list have changed |
|
416 //Get the contact name of the handles thru rosters_changed_contacts_cb |
|
417 UNUSED_FORMAL_PARAM(message); |
|
418 UNUSED_FORMAL_PARAM(actor); |
|
419 UNUSED_FORMAL_PARAM(reason); |
|
420 UNUSED_FORMAL_PARAM(userdata); |
|
421 if ( group_iface == globalCon.group_iface_subscribe && remote_pending |
|
422 && 0 < remote_pending->len ) |
|
423 { |
|
424 *msg_type = ESubscribe_Remote_Pending; |
|
425 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
426 TP_CONN_HANDLE_TYPE_CONTACT ,remote_pending, |
|
427 rosters_changed_contacts_cb, msg_type ); |
|
428 } |
|
429 if ( group_iface == globalCon.group_iface_subscribe && removed |
|
430 && 0 < removed->len ) |
|
431 { |
|
432 //User is trying to remove the contact from list |
|
433 // |
|
434 *msg_type = ESubscribe_Removed_Or_Rejected; |
|
435 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
436 TP_CONN_HANDLE_TYPE_CONTACT ,removed, |
|
437 rosters_changed_contacts_cb, msg_type ); |
|
438 } |
|
439 if ( group_iface == globalCon.group_iface_subscribe && added |
|
440 && 0 < added->len ) |
|
441 { |
|
442 // |
|
443 *msg_type = ESubscribe_RP_Accepted; |
|
444 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
445 TP_CONN_HANDLE_TYPE_CONTACT ,added, |
|
446 rosters_changed_contacts_cb, msg_type ); |
|
447 } |
|
448 if ( group_iface == globalCon.group_iface_publish && added |
|
449 && 0 < added->len ) |
|
450 { |
|
451 *msg_type = EPublish_RP_Accepted; |
|
452 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
453 TP_CONN_HANDLE_TYPE_CONTACT ,added, |
|
454 rosters_changed_contacts_cb, msg_type ); |
|
455 } |
|
456 |
|
457 if ( group_iface == globalCon.group_iface_publish && local_pending |
|
458 && 0 < local_pending->len ) |
|
459 { |
|
460 *msg_type = ETrying_To_Add_Contact_Publish; |
|
461 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
462 TP_CONN_HANDLE_TYPE_CONTACT ,local_pending, |
|
463 rosters_changed_contacts_cb, msg_type ); |
|
464 } |
|
465 if ( group_iface == globalCon.group_iface_publish && removed |
|
466 && 0 < removed->len ) |
|
467 { |
|
468 *msg_type = EPublish_Removed_Or_Rejected; |
|
469 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
470 TP_CONN_HANDLE_TYPE_CONTACT ,removed, |
|
471 rosters_changed_contacts_cb, msg_type ); |
|
472 } |
|
473 if ( group_iface == globalCon.group_iface_known && removed |
|
474 && 0 < removed->len ) |
|
475 { |
|
476 //User is trying to remove the contact from list |
|
477 // |
|
478 *msg_type = ESubscribe_Removed_Or_Rejected; |
|
479 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
480 TP_CONN_HANDLE_TYPE_CONTACT ,removed, |
|
481 rosters_changed_contacts_cb, msg_type ); |
|
482 } |
|
483 if ( group_iface == globalCon.group_iface_known && added |
|
484 && 0 < added->len ) |
|
485 { |
|
486 //User is trying to remove the contact from list |
|
487 // |
|
488 *msg_type = ETrying_To_Add_Contact_Known; |
|
489 tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ), |
|
490 TP_CONN_HANDLE_TYPE_CONTACT ,added, |
|
491 rosters_changed_contacts_cb, msg_type ); |
|
492 } |
|
493 |
|
494 //log message |
|
495 iso_logger( "%s", "out - roster_members_changed_cb\n" ); |
|
496 } |
|
497 |