clientpipe.c

Go to the documentation of this file.
00001 /* OpenSER PURPLE MODULE
00002  * 
00003  * Copyright (C) 2008 Atos Worldline
00004  * Contact: Eric PTAK <eric.ptak@atosorigin.com>
00005  *
00006  * This program is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018  *
00019  */
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <stdlib.h>
00023 #include <errno.h>
00024 
00025 #include "../../dprint.h"
00026 
00027 #include "purple.h"
00028 #include "purplepipe.h"
00029 #include "purple_sip.h"
00030 #include "clientpipe.h"
00031 #include "mapping.h"
00032 #include "hashtable.h"
00033 #include "clientaccount.h"
00034 #include "utils.h"
00035 
00036 #include <libpurple/account.h>
00037 #include <libpurple/accountopt.h>
00038 #include <libpurple/conversation.h>
00039 #include <libpurple/connection.h>
00040 #include <libpurple/core.h>
00041 #include <libpurple/debug.h>
00042 #include <libpurple/eventloop.h>
00043 #include <libpurple/ft.h>
00044 #include <libpurple/log.h>
00045 #include <libpurple/notify.h>
00046 #include <libpurple/plugin.h>
00047 #include <libpurple/prefs.h>
00048 #include <libpurple/prpl.h>
00049 #include <libpurple/pounce.h>
00050 #include <libpurple/savedstatuses.h>
00051 #include <libpurple/sound.h>
00052 #include <libpurple/status.h>
00053 #include <libpurple/util.h>
00054 #include <libpurple/whiteboard.h>
00055 #include <libpurple/xmlnode.h>
00056 
00057 static void pipe_handle_message(struct purple_message *message) {
00058    LM_DBG("handling message cmd\n");
00059    PurpleAccount *account = NULL;
00060    extern_account_t *accounts = NULL;
00061    extern_user_t *users = NULL;
00062    int naccounts = 0, nusers = 0;
00063    int i, j;
00064 
00065    PurpleConversation *conv = NULL;
00066    LM_DBG("calling find_accounts(\"%s\", &naccounts)\n", message->from);
00067    accounts = find_accounts(message->from, &naccounts);
00068    LM_DBG("found %d extra account(s) for <%s>", naccounts, message->from);
00069 
00070    LM_DBG("calling find_users(\"%s\", &nusers)\n", message->to);
00071    users = find_users(message->to, &nusers);
00072    LM_DBG("found %d extra user(s) for <%s>", nusers, message->to);
00073 
00074    for (i = 0; i < naccounts; i++) {
00075       LM_DBG("calling client_find_account(\"%s\")\n", accounts[i].username);
00076       account = client_find_account(&accounts[i]);
00077       if ((account) && purple_account_is_connected(account)) {
00078          //enable_account(account);
00079          for (j = 0; j < nusers; j++) {
00080             if (!strcmp(accounts[i].protocol, users[j].protocol)) {
00081                LM_DBG("mathing protocol found: %s\n", accounts[i].protocol);
00082                conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, users[j].username, account);
00083                if (conv == NULL)
00084                   conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, users[j].username);
00085                purple_conv_im_send(purple_conversation_get_im_data(conv), message->body);
00086                break;
00087             }
00088          }
00089       }
00090       else if (account == NULL)
00091          LM_DBG("not account found neither created\n");
00092       else if (purple_account_is_disconnected(account))
00093          LM_DBG("account is disconnected cannot send message\n");
00094    }
00095    if (accounts)
00096       extern_account_free(accounts, naccounts);
00097    if (users)
00098       extern_user_free(users, nusers);
00099 
00100 }
00101 
00102 static void pipe_handle_publish(struct purple_publish *publish) {
00103    PurpleAccount *account = NULL;
00104    extern_account_t *accounts = NULL;
00105    int naccounts = 0;
00106    int i;
00107 
00108    LM_DBG("calling find_accounts(\"%s\", &naccoutns)\n", publish->from);
00109    accounts = find_accounts(publish->from, &naccounts);
00110    LM_DBG("found %d extra account(s) for <%s>", naccounts, publish->from);
00111 
00112    for (i = 0; i < naccounts; i++) {
00113       LM_DBG("calling client_find_account(\"%s\")\n", accounts[i].username);
00114       account = client_find_account(&accounts[i]);
00115       if (account) {
00116       
00117          if (publish->basic == PURPLE_BASIC_OPEN) {
00118             client_enable_account(account);
00119             LM_DBG("basic = open, setting up new status... %s,%d,%s\n", account[i].username, publish->primitive, publish->note);
00120             PurpleStatusType *type = purple_account_get_status_type_with_primitive(account, publish->primitive);
00121             if (purple_status_type_get_attr(type, "message")) {
00122                purple_account_set_status(account, purple_status_type_get_id(type), TRUE, "message", publish->note, NULL);
00123             } else {
00124                purple_account_set_status(account, purple_status_type_get_id(type), TRUE, NULL);
00125             }
00126          }
00127 
00128          else if (publish->basic == PURPLE_BASIC_CLOSED){
00129             LM_DBG("basic = closed, setting up new status to offline... %s\n", account[i].username);
00130             PurpleStatusType *type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_OFFLINE);
00131             purple_account_set_status(account, purple_status_type_get_id(type), TRUE, NULL);
00132          }
00133          
00134       }
00135    }
00136 
00137    if (accounts)
00138       extern_account_free(accounts, naccounts);
00139 
00140 }
00141 
00142 static void pipe_handle_subscribe(struct purple_subscribe *subscribe) {
00143    PurpleAccount *account = NULL;
00144    extern_account_t *accounts = NULL;
00145    extern_user_t *users = NULL;
00146    int naccounts = 0, nusers = 0;
00147    int i, j;
00148    PurpleBuddy *buddy = NULL;
00149 
00150    int d = 0;
00151 
00152    const char *note;
00153    enum purple_publish_basic basic;
00154    enum purple_publish_activity activity;
00155 
00156    LM_DBG("calling find_accounts(\"%s\", &naccounts)\n", subscribe->from);
00157    accounts = find_accounts(subscribe->from, &naccounts);
00158    LM_DBG("found %d extra account(s) for <%s>", naccounts, subscribe->from);
00159    
00160    LM_DBG("calling find_users(\"%s\", &nusers)\n", subscribe->to);
00161    users = find_users(subscribe->to, &nusers);
00162    LM_DBG("found %d extra user(s) for <%s>", nusers, subscribe->to);
00163 
00164    for (i = 0; i < naccounts; i++) {
00165       LM_DBG("calling client_find_account(\"%s\")\n", accounts[i].username);
00166       account = client_find_account(&accounts[i]);
00167       //if ((account) && (purple_account_is_connected(account) || purple_account_is_connecting(account))) {
00168       if (account) {
00169          for (j = 0; j < nusers; j++) {
00170             if (!strcmp(accounts[i].protocol, users[j].protocol)) {
00171                LM_DBG("found matching protocol: %s\n", accounts[i].protocol);
00172 
00173                LM_DBG("subscribe expires : %d\n", subscribe->expires);
00174                if (subscribe->expires == 0)
00175                   d = hashtable_dec_counter(users[j].username);
00176                else
00177                   d = hashtable_inc_counter(users[j].username);
00178                
00179                LM_DBG("<%s> is now referenced %d times\n", users[j].username, d);
00180                if (d == 0) {
00181                   LM_DBG("<%s> is no more referenced, removing presence...\n", users[j].username);
00182                   if (purple_send_sip_publish(subscribe->to, users[j].username, PURPLE_BASIC_CLOSED, 0, NULL) < 0)
00183                      LM_ERR("error sending presence for %s", subscribe->to);
00184                   else
00185                      LM_DBG("presence message sent successfully\n");
00186                }
00187 
00188                else {
00189    
00190                   buddy = purple_find_buddy(account, users[j].username);
00191                   if (buddy == NULL) {
00192                      LM_DBG("<%s> not found in <%s> buddy list, adding\n", users[j].username, accounts[i].username);
00193                      buddy = purple_buddy_new(account, users[j].username, users[j].username);
00194                      //purple_blist_add_buddy(buddy, NULL, NULL, NULL);
00195                      purple_account_add_buddy(account, buddy);
00196                   }
00197                   else {
00198                      LM_DBG("<%s> found in <%s> buddy list, sending publish\n", users[j].username, accounts[i].username);
00199                      PurplePresence *presence = purple_buddy_get_presence(buddy);
00200                      PurpleStatus *status = purple_presence_get_active_status(presence);
00201                      PurpleStatusType *type = purple_status_get_type(status);
00202                      PurpleStatusPrimitive primitive = purple_status_type_get_primitive(type);
00203                      note = purple_status_get_attr_string(status, "message");
00204                      primitive_parse(primitive, &basic, &activity);
00205 
00206                      if (purple_send_sip_publish(subscribe->to, users[j].username, basic, activity, note) < 0)
00207                         LM_ERR("error sending presence for %s", subscribe->to);
00208                      else
00209                         LM_DBG("presence message sent successfully\n");
00210                      
00211                   }  
00212    
00213                }
00214 
00215                break;
00216             }
00217          }
00218       }
00219    }
00220    if (accounts)
00221       extern_account_free(accounts, naccounts);
00222    if (users)
00223       extern_user_free(users, nusers);
00224    
00225 }
00226 
00227 void pipe_reader(gpointer data, gint fd, PurpleInputCondition condition) {
00228    struct purple_cmd *cmd;
00229    if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
00230       LM_ERR("failed to read from command pipe: %s\n", strerror(errno));
00231       return;
00232    }
00233    
00234    switch (cmd->type) {
00235            case PURPLE_MESSAGE_CMD:
00236       LM_DBG("received message cmd via pipe from <%s> to <%s>\n", cmd->message.from, cmd->message.to);
00237       pipe_handle_message(&cmd->message);
00238       break;
00239 
00240       case PURPLE_SUBSCRIBE_CMD:
00241       LM_DBG("received subscribe cmd via pipe from <%s> to <%s>\n", cmd->subscribe.from, cmd->subscribe.to);
00242       pipe_handle_subscribe(&cmd->subscribe);
00243       break;
00244 
00245       case PURPLE_PUBLISH_CMD:
00246       LM_DBG("received publish cmd via pipe from <%s>\n", cmd->publish.from);
00247       pipe_handle_publish(&cmd->publish);
00248       break;
00249 
00250       default:
00251       LM_ERR("unknown cmd type 0x%x\n", cmd->type);
00252    }
00253    purple_free_cmd(cmd);
00254 }
00255 
00256 

Generated on Mon May 21 18:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6