imc.c

Go to the documentation of this file.
00001 /*
00002  * $Id: imc.c 4949 2008-09-18 12:02:39Z henningw $
00003  *
00004  * imc module - instant messaging conferencing implementation
00005  *
00006  * Copyright (C) 2006 Voice Sistem S.R.L.
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * ---------
00026  *  2006-10-06  first version (anca)
00027  */
00028 
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <stdlib.h>
00032 #include <sys/types.h>
00033 #include <sys/ipc.h>
00034 #include <unistd.h>
00035 #include <fcntl.h>
00036 #include <time.h>
00037 #include "../../db/db.h"
00038 #include "../../db/db_res.h"
00039 #include "../../sr_module.h"
00040 #include "../../dprint.h"
00041 #include "../../ut.h"
00042 #include "../../timer.h"
00043 #include "../../str.h"
00044 #include "../../mem/shm_mem.h"
00045 #include "../../db/db.h"
00046 #include "../../parser/parse_from.h"
00047 #include "../../parser/parse_content.h"
00048 #include "../../parser/contact/parse_contact.h"
00049 #include "../../resolve.h"
00050 #include "../../hash_func.h"
00051 #include "../../mi/mi.h"
00052 
00053 #include "../tm/tm_load.h"
00054 
00055 
00056 #include "imc_mng.h"
00057 #include "imc_cmd.h"
00058 
00059 MODULE_VERSION
00060 
00061 /** parameters */
00062 
00063 db_con_t *imc_db = NULL;
00064 db_func_t imc_dbf;
00065 static str db_url  = str_init(DEFAULT_DB_URL);
00066 str outbound_proxy = {NULL, 0};
00067 
00068 static str rooms_table   = str_init("imc_rooms");
00069 static str members_table = str_init("imc_members");
00070 
00071 static str imc_col_username = str_init("username");
00072 static str imc_col_domain   = str_init("domain");
00073 static str imc_col_flag     = str_init("flag");
00074 static str imc_col_room     = str_init("room");
00075 static str imc_col_name     = str_init("name");
00076 
00077 imc_hentry_p _imc_htable = NULL;
00078 int imc_hash_size = 4;
00079 str imc_cmd_start_str = str_init(IMC_CMD_START_STR);
00080 char imc_cmd_start_char;
00081 
00082 /** module functions */
00083 static int mod_init(void);
00084 static int child_init(int);
00085 
00086 static int imc_manager(struct sip_msg*, char *, char *);
00087 
00088 static struct mi_root* imc_mi_list_rooms(struct mi_root* cmd, void* param);
00089 static struct mi_root* imc_mi_list_members(struct mi_root* cmd, void* param);
00090 
00091 void destroy(void);
00092 
00093 /** TM bind */
00094 struct tm_binds tmb;
00095 
00096 /** TM callback function */
00097 void inv_callback( struct cell *t, int type, struct tmcb_params *ps);
00098 
00099 static cmd_export_t cmds[]={
00100    {"imc_manager",  (cmd_function)imc_manager, 0, 0, 0, REQUEST_ROUTE},
00101    {0,0,0,0,0,0}
00102 };
00103 
00104 
00105 static param_export_t params[]={
00106    {"db_url",           STR_PARAM, &db_url.s},
00107    {"hash_size",        INT_PARAM, &imc_hash_size},
00108    {"imc_cmd_start_char",  STR_PARAM, &imc_cmd_start_str.s},
00109    {"rooms_table",         STR_PARAM, &rooms_table.s},
00110    {"members_table",    STR_PARAM, &members_table.s},
00111    {"outbound_proxy",      STR_PARAM, &outbound_proxy.s},
00112    {0,0,0}
00113 };
00114 
00115 #ifdef STATISTICS
00116 #include "../../statistics.h"
00117 
00118 stat_var* imc_active_rooms;
00119 
00120 stat_export_t imc_stats[] = {
00121    {"active_rooms" ,  0,  &imc_active_rooms  },
00122    {0,0,0}
00123 };
00124 
00125 #endif
00126 
00127 static mi_export_t mi_cmds[] = {
00128    { "imc_list_rooms",    imc_mi_list_rooms,    MI_NO_INPUT_FLAG,  0,  0 },
00129    { "imc_list_members",  imc_mi_list_members,  0,                 0,  0 },
00130    { 0, 0, 0, 0, 0}
00131 };
00132 
00133 
00134 
00135 /** module exports */
00136 struct module_exports exports= {
00137    "imc",      /* module name */
00138    DEFAULT_DLFLAGS, /* dlopen flags */
00139    cmds,       /* exported commands */
00140    params,     /* exported parameters */
00141 #ifdef STATISTICS
00142    imc_stats,
00143 #else
00144    0,          /* exported statistics */
00145 #endif
00146    mi_cmds,    /* exported MI functions */
00147    0,          /* exported pseudo-variables */
00148    0,          /* extra processes */
00149    mod_init,   /* mod init */
00150    0,          /* response handler */
00151    (destroy_function) destroy,  /* destroy function */
00152    child_init  /* child init */
00153 };
00154 
00155 /**
00156  * the initiating function
00157  */
00158 int add_from_db(void)
00159 {
00160    imc_member_p member = NULL;
00161    int i, j, flag;
00162    db_key_t mq_result_cols[4], mquery_cols[2];
00163    db_key_t rq_result_cols[4];
00164    db_val_t mquery_vals[2];
00165    db_res_t *r_res= NULL;
00166    db_res_t *m_res= NULL;
00167    db_row_t *m_row = NULL, *r_row = NULL; 
00168    db_val_t *m_row_vals, *r_row_vals = NULL;
00169    str name, domain;
00170    imc_room_p room = NULL;
00171    int er_ret = -1;
00172    
00173    rq_result_cols[0] = &imc_col_name;
00174    rq_result_cols[1] = &imc_col_domain;
00175    rq_result_cols[2] = &imc_col_flag;
00176 
00177    mq_result_cols[0] = &imc_col_username;
00178    mq_result_cols[1] = &imc_col_domain;
00179    mq_result_cols[2] = &imc_col_flag;
00180 
00181    mquery_cols[0] = &imc_col_room;
00182    mquery_vals[0].type = DB_STR;
00183    mquery_vals[0].nul = 0;
00184    
00185    if(imc_dbf.use_table(imc_db, &rooms_table)< 0)
00186    {
00187       LM_ERR("use_table failed\n");
00188       return -1;
00189    }
00190 
00191    if(imc_dbf.query(imc_db,0, 0, 0, rq_result_cols,0, 3, 0,&r_res)< 0)
00192    {
00193       LM_ERR("failed to querry table\n");
00194       return -1;
00195    }
00196    if(r_res && r_res->n<=0)
00197    {
00198       LM_INFO("the query returned no result\n");
00199       imc_dbf.free_result(imc_db, r_res);
00200       r_res = NULL;
00201       return 0;
00202    }
00203 
00204    LM_DBG("found %d rooms\n", r_res->n);
00205 
00206    for(i =0 ; i< r_res->n ; i++)
00207    {
00208       /*add rooms*/
00209       r_row = &r_res->rows[i];
00210       r_row_vals = ROW_VALUES(r_row);
00211    
00212       name.s =    r_row_vals[0].val.str_val.s;
00213       name.len = strlen(name.s);
00214       
00215       domain.s =  r_row_vals[1].val.str_val.s;
00216       domain.len = strlen(domain.s);
00217       
00218       flag =   r_row_vals[2].val.int_val;
00219       
00220       room = imc_add_room(&name, &domain, flag);
00221       if(room == NULL)
00222       {
00223          LM_ERR("failed to add room\n ");
00224          goto error;
00225       }  
00226    
00227       /* add members */
00228       if(imc_dbf.use_table(imc_db, &members_table)< 0)
00229       {
00230          LM_ERR("use_table failed\n ");
00231          goto error;
00232       }
00233 
00234       mquery_vals[0].val.str_val= room->uri;
00235       
00236       if(imc_dbf.query(imc_db, mquery_cols, 0, mquery_vals, mq_result_cols, 
00237                1, 3, 0, &m_res)< 0)
00238       {
00239          LM_ERR("failed to querry table\n");
00240          goto error;
00241       }
00242 
00243       if(m_res && m_res->n <=0)
00244       {
00245          LM_INFO("the query returned no result\n");
00246          er_ret = 0;
00247          goto error; /* each room must have at least one member*/
00248       }
00249       for(j =0; j< m_res->n; j++)
00250       {
00251          m_row = &m_res->rows[j];
00252          m_row_vals = ROW_VALUES(m_row);
00253          
00254          name.s = m_row_vals[0].val.str_val.s;
00255          name.len = strlen(name.s);
00256          
00257          domain.s = m_row_vals[1].val.str_val.s;
00258          domain.len = strlen(domain.s);
00259          
00260          flag = m_row_vals[2].val.int_val;
00261          
00262          LM_DBG("adding memeber: [name]=%.*s [domain]=%.*s"
00263                " in [room]= %.*s\n",name.len, name.s, domain.len,domain.s,
00264                room->uri.len, room->uri.s);
00265 
00266          member = imc_add_member(room, &name, &domain, flag);
00267          if(member == NULL)
00268          {
00269             LM_ERR("failed to adding member\n ");
00270             goto error;
00271          }
00272          imc_release_room(room); 
00273       }
00274 
00275       if(m_res)
00276       {
00277          imc_dbf.free_result(imc_db, m_res);
00278          m_res = NULL;
00279       }
00280    }
00281 
00282    if(imc_dbf.use_table(imc_db, &members_table)< 0)
00283    {
00284       LM_ERR("use table failed\n ");
00285       goto error;
00286    }
00287 
00288    if(imc_dbf.delete(imc_db, 0, 0 , 0, 0) < 0)
00289    {
00290       LM_ERR("failed to delete information from db\n");
00291       goto error;
00292    }
00293    
00294    if(imc_dbf.use_table(imc_db, &rooms_table)< 0)
00295    {
00296       LM_ERR("use table failed\n ");
00297       goto error;
00298    }
00299 
00300    if(imc_dbf.delete(imc_db, 0, 0 , 0, 0) < 0)
00301    {
00302       LM_ERR("failed to delete information from db\n");
00303       goto error;
00304    }
00305 
00306    if(r_res)
00307    {  
00308       imc_dbf.free_result(imc_db, r_res);
00309       r_res = NULL;
00310    }
00311    if(m_res)
00312    {  
00313       imc_dbf.free_result(imc_db, m_res);
00314       m_res = NULL;
00315    }
00316 
00317    return 0;
00318 
00319 error:
00320    if(r_res)
00321    {
00322       imc_dbf.free_result(imc_db, r_res);
00323       r_res = NULL;
00324    }
00325    if(m_res)
00326    {
00327       imc_dbf.free_result(imc_db, m_res);
00328       m_res = NULL;
00329    }
00330    if(room)
00331       imc_release_room(room);
00332    return er_ret;
00333 
00334 }  
00335 
00336 
00337 static int mod_init(void)
00338 {
00339    if(imc_hash_size <= 0)
00340    {
00341       LM_ERR("invalid hash size\n");
00342       return -1;
00343    }
00344 
00345    imc_hash_size = 1 << imc_hash_size;
00346 
00347    if(imc_htable_init() < 0)
00348    {
00349       LM_ERR("initializing hash table\n");
00350       return -1;
00351    }
00352 
00353    imc_cmd_start_str.len = strlen(imc_cmd_start_str.s);
00354 
00355    if(outbound_proxy.s)
00356       outbound_proxy.len = strlen(outbound_proxy.s);
00357 
00358    rooms_table.len = strlen(rooms_table.s);
00359    members_table.len = strlen(members_table.s);
00360 
00361    /*  binding to mysql module */
00362    db_url.len = strlen(db_url.s);
00363    LM_DBG("db_url=%s/%d/%p\n", ZSW(db_url.s), db_url.len, db_url.s);
00364    
00365    if (db_bind_mod(&db_url, &imc_dbf))
00366    {
00367       LM_DBG("database module not found\n");
00368       return -1;
00369    }
00370 
00371    imc_db = imc_dbf.init(&db_url);
00372    if (!imc_db)
00373    {
00374       LM_ERR("failed to connect to the database\n");
00375       return -1;
00376    }
00377    /* read the informations stored in db */
00378    if(add_from_db() <0)
00379    {
00380       LM_ERR("failed to get information from db\n");
00381       return -1;
00382    }
00383    
00384    /* load TM API */
00385    if (load_tm_api(&tmb)!=0) {
00386       LM_ERR("unable to load tm api\n");
00387       return -1;
00388    }
00389 
00390    imc_cmd_start_char = imc_cmd_start_str.s[0];
00391    
00392    if(imc_db)
00393       imc_dbf.close(imc_db);
00394    imc_db = NULL;
00395    
00396    return 0;
00397 }
00398 
00399 /**
00400  * child init
00401  */
00402 static int child_init(int rank)
00403 {  
00404    if (imc_dbf.init==0)
00405    {
00406       LM_ERR("database not bound\n");
00407       return -1;
00408    }
00409    imc_db = imc_dbf.init(&db_url);
00410    if (!imc_db)
00411    {
00412       LM_ERR("child %d: Error while connecting database\n", rank);
00413       return -1;
00414    }
00415    else
00416    {
00417       if (imc_dbf.use_table(imc_db, &rooms_table) < 0)
00418       {
00419          LM_ERR("child %d: Error in use_table '%.*s'\n", rank, rooms_table.len, rooms_table.s);
00420          return -1;
00421       }
00422       if (imc_dbf.use_table(imc_db, &members_table) < 0)
00423       {
00424          LM_ERR("child %d: Error in use_table '%.*s'\n", rank, members_table.len, members_table.s);
00425          return -1;
00426       }
00427 
00428       LM_DBG("child %d: Database connection opened successfully\n", rank);
00429    }
00430 
00431    return 0;
00432 }
00433 
00434 
00435 static int imc_manager(struct sip_msg* msg, char *str1, char *str2)
00436 {
00437    imc_cmd_t cmd;
00438    str body;
00439    struct sip_uri from_uri, *pto_uri=NULL, *pfrom_uri=NULL;
00440    struct to_body *pfrom;
00441 
00442    body.s = get_body( msg );
00443    if (body.s==0) 
00444    {
00445       LM_ERR("cannot extract body from msg\n");
00446       goto error;
00447    }
00448    
00449    /* lungimea corpului mesajului */
00450    if (!msg->content_length) 
00451    {
00452       LM_ERR("no Content-Length\n");
00453       goto error;
00454    }
00455    body.len = get_content_length( msg );
00456 
00457    if(body.len <= 0)
00458    {
00459       LM_DBG("empty body!\n");
00460       goto error;
00461    }
00462 
00463    if(parse_sip_msg_uri(msg)<0)
00464    {
00465       LM_ERR("failed to parse r-uri\n");
00466       goto error;
00467    }
00468    
00469    pto_uri=&msg->parsed_uri;
00470    
00471    if(parse_from_header(msg)<0)
00472    {
00473       LM_ERR("failed to parse  From header\n");
00474       goto error;
00475    }
00476    pfrom = (struct to_body*)msg->from->parsed;  
00477    if(parse_uri(pfrom->uri.s, pfrom->uri.len, &from_uri)<0){
00478       LM_ERR("failed to parse From URI\n");
00479       goto error;
00480    }
00481    pfrom_uri=&from_uri;
00482 
00483    if(body.s[0]== imc_cmd_start_char)
00484    {
00485       LM_DBG("found command\n");
00486       if(imc_parse_cmd(body.s, body.len, &cmd)<0)
00487       {
00488          LM_ERR("failed to parse imc cmd!\n");
00489          goto error;
00490       }
00491 
00492       switch(cmd.type)
00493       {
00494       case IMC_CMDID_CREATE:
00495          if(imc_handle_create(msg, &cmd, pfrom_uri, pto_uri)<0)
00496          {
00497             LM_ERR("failed to handle 'create'\n");
00498             goto error;
00499          }
00500       break;
00501       case IMC_CMDID_JOIN:
00502          if(imc_handle_join(msg, &cmd, pfrom_uri, pto_uri)<0)
00503          {
00504             LM_ERR("failed to handle 'join'\n");
00505             goto error;
00506          }
00507       break;
00508       case IMC_CMDID_INVITE:
00509          if(imc_handle_invite(msg, &cmd, pfrom_uri, pto_uri)<0)
00510          {
00511             LM_ERR("failed to handle 'invite'\n");
00512             goto error;
00513          }
00514       break;
00515       case IMC_CMDID_ACCEPT:
00516          if(imc_handle_accept(msg, &cmd, pfrom_uri, pto_uri)<0)
00517          {
00518             LM_ERR("failed to handle 'accept'\n");
00519             goto error;
00520          }
00521       break;
00522       case IMC_CMDID_DENY:
00523          if(imc_handle_deny(msg, &cmd, pfrom_uri, pto_uri)<0)
00524          {
00525             LM_ERR("failed to handle 'deny'\n");
00526             goto error;
00527          }
00528       break;
00529       case IMC_CMDID_REMOVE:
00530          if(imc_handle_remove(msg, &cmd, pfrom_uri, pto_uri)<0)
00531          {
00532             LM_ERR("failed to handle 'remove'\n");
00533             goto error;
00534          }
00535       break;
00536       case IMC_CMDID_EXIT:
00537          if(imc_handle_exit(msg, &cmd, pfrom_uri, pto_uri)<0)
00538          {
00539             LM_ERR("failed to handle 'exit'\n");
00540             goto error;
00541          }
00542       break;
00543       case IMC_CMDID_LIST:
00544          if(imc_handle_list(msg, &cmd, pfrom_uri, pto_uri)<0)
00545          {
00546             LM_ERR("failed to handle 'list'\n");
00547             goto error;
00548          }
00549       break;
00550       case IMC_CMDID_DESTROY:
00551          if(imc_handle_destroy(msg, &cmd, pfrom_uri, pto_uri)<0)
00552          {
00553             LM_ERR("failed to handle 'destroy'\n");
00554             goto error;
00555          }
00556       break;
00557       case IMC_CMDID_HELP:
00558          if(imc_handle_help(msg, &cmd, &pfrom->uri,
00559          (msg->new_uri.s)?&msg->new_uri:&msg->first_line.u.request.uri)<0)
00560          {
00561             LM_ERR("failed to handle 'help'\n");
00562             goto error;
00563          }
00564       break;
00565       default:
00566          if(imc_handle_unknown(msg, &cmd, &pfrom->uri,
00567          (msg->new_uri.s)?&msg->new_uri:&msg->first_line.u.request.uri)<0)
00568          {
00569             LM_ERR("failed to handle 'unknown'\n");
00570             goto error;
00571          }
00572       }
00573                            
00574       goto done;
00575    }
00576 
00577    if(imc_handle_message(msg, &body, pfrom_uri, pto_uri)<0)
00578    {
00579       LM_ERR("failed to handle 'message'\n");
00580       goto error;
00581    }
00582 
00583 done:
00584    return 1;
00585 
00586 error:
00587 
00588    return -1;  
00589 }
00590 
00591 /**
00592  * destroy module
00593  */
00594 void destroy(void)
00595 {
00596    imc_room_p irp = NULL;
00597    imc_member_p member = NULL;
00598    int i;
00599    db_key_t mq_cols[4];
00600    db_val_t mq_vals[4];
00601    db_key_t rq_cols[4];
00602    db_val_t rq_vals[4];
00603    
00604    if(imc_db==NULL)
00605       goto done;
00606 
00607    mq_cols[0] = &imc_col_username;
00608    mq_vals[0].type = DB_STR;
00609    mq_vals[0].nul = 0;
00610          
00611    mq_cols[1] = &imc_col_domain;
00612    mq_vals[1].type = DB_STR;
00613    mq_vals[1].nul = 0;
00614    
00615    mq_cols[2] = &imc_col_flag;
00616    mq_vals[2].type = DB_INT;
00617    mq_vals[2].nul = 0;
00618 
00619    mq_cols[3] = &imc_col_room;
00620    mq_vals[3].type = DB_STR;
00621    mq_vals[3].nul = 0;
00622 
00623 
00624    rq_cols[0] = &imc_col_name;
00625    rq_vals[0].type = DB_STR;
00626    rq_vals[0].nul = 0;
00627       
00628    rq_cols[1] = &imc_col_domain;
00629    rq_vals[1].type = DB_STR;
00630    rq_vals[1].nul = 0;
00631 
00632    rq_cols[2] = &imc_col_flag;
00633    rq_vals[2].type = DB_INT;
00634    rq_vals[2].nul = 0;
00635 
00636    for(i=0; i<imc_hash_size; i++) 
00637    {
00638       irp = _imc_htable[i].rooms;
00639       
00640       while(irp)
00641       {
00642          rq_vals[0].val.str_val = irp->name;
00643          rq_vals[1].val.str_val = irp->domain;
00644          rq_vals[2].val.int_val = irp->flags;
00645 
00646          if(imc_dbf.use_table(imc_db, &rooms_table)< 0)
00647          {
00648             LM_ERR("use_table failed\n");
00649             return;
00650          }
00651 
00652          if(imc_dbf.insert(imc_db, rq_cols, rq_vals, 3)<0)
00653          {
00654             LM_ERR("failed to insert into table imc_rooms\n");
00655             return;
00656          }
00657          LM_DBG("room %d %.*s\n", i, irp->name.len, irp->name.s);
00658          member = irp->members;
00659          while(member)
00660          {
00661             mq_vals[0].val.str_val = member->user;
00662             mq_vals[1].val.str_val = member->domain;
00663             mq_vals[2].val.int_val = member->flags;
00664             mq_vals[3].val.str_val = irp->uri;
00665 
00666             if(imc_dbf.use_table(imc_db, &members_table)< 0)
00667             {
00668                LM_ERR("use_table failed\n");
00669                return;
00670             }
00671 
00672             if(imc_dbf.insert(imc_db, mq_cols, mq_vals, 4)<0)
00673             {
00674                LM_ERR("failed to insert  into table imc_rooms\n");
00675                return;
00676             }
00677             member = member->next;
00678          }
00679          irp = irp->next;
00680       }
00681    }
00682 
00683 done:
00684    imc_htable_destroy();
00685 }
00686 
00687 
00688 /************************* MI ***********************/
00689 static struct mi_root* imc_mi_list_rooms(struct mi_root* cmd_tree, void* param)
00690 {
00691    int i, len;
00692    struct mi_root* rpl_tree= NULL;
00693    struct mi_node* rpl= NULL;
00694    struct mi_node* node= NULL;
00695    struct mi_attr* attr= NULL;
00696    imc_room_p irp = NULL;
00697    char* p = NULL;
00698 
00699    rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00700    if(rpl_tree == NULL)
00701       return 0;
00702    rpl = &rpl_tree->node;
00703 
00704    for(i=0; i<imc_hash_size; i++) 
00705    {
00706       lock_get(&_imc_htable[i].lock);
00707       irp = _imc_htable[i].rooms;
00708          while(irp){
00709             node = add_mi_node_child(rpl, 0, "ROOM", 4, 0, 0);
00710             if( node == NULL)
00711                goto error;
00712 
00713             attr= add_mi_attr(node, MI_DUP_VALUE, "URI", 3, irp->uri.s,
00714                irp->uri.len);
00715             if(attr == NULL)
00716                goto error;
00717 
00718             p = int2str(irp->nr_of_members, &len);
00719             attr= add_mi_attr(node, 0, "MEMBERS", 7,p, len );
00720             if(attr == NULL)
00721                goto error;
00722 
00723             attr= add_mi_attr(node, MI_DUP_VALUE, "OWNER", 5, 
00724                   irp->members->uri.s, irp->members->uri.len);
00725             if(attr == NULL)
00726                goto error;
00727                
00728             irp = irp->next;
00729          }
00730       lock_release(&_imc_htable[i].lock);
00731    }
00732 
00733    return rpl_tree;
00734 
00735 error:
00736    lock_release(&_imc_htable[i].lock);
00737    free_mi_tree(rpl_tree);
00738    return 0;
00739 
00740 }
00741 
00742 
00743 static struct mi_root* imc_mi_list_members(struct mi_root* cmd_tree,
00744                                                 void* param)
00745 {
00746    int i, len;
00747    struct mi_root* rpl_tree = NULL;
00748    struct mi_node* node= NULL;
00749    struct mi_node* node_r= NULL;
00750    struct mi_attr* attr= NULL;
00751    char rnbuf[256];
00752    str room_name;
00753    imc_room_p room;
00754    struct sip_uri inv_uri, *pinv_uri;
00755    imc_member_p imp=NULL;
00756    char* p = NULL;
00757 
00758    node= cmd_tree->node.kids;
00759    if(node == NULL|| node->next!=NULL)
00760       return 0;
00761    
00762    /* room name */
00763    room_name.s = rnbuf;
00764    room_name.len= node->value.len;
00765    memcpy(room_name.s, node->value.s, node->value.len);
00766    if(room_name.s == NULL || room_name.len == 0)
00767    {
00768       LM_ERR(" no room name!\n");
00769       return init_mi_tree( 404, "room name not found", 19);
00770    }
00771    rnbuf[room_name.len] = '\0';
00772    if(*room_name.s=='\0' || *room_name.s=='.')
00773    {
00774       LM_INFO("empty room name\n");
00775       return init_mi_tree( 400, "empty param", 11);
00776    }
00777 
00778    /* find room */
00779    parse_uri(room_name.s,room_name.len, &inv_uri);
00780    pinv_uri=&inv_uri;
00781    room=imc_get_room(&pinv_uri->user, &pinv_uri->host);
00782 
00783    if(room==NULL)
00784    {
00785       LM_ERR("no such room!\n");
00786       return init_mi_tree( 404, "no such room", 14);
00787    }
00788 
00789    rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00790    if(rpl_tree == NULL)
00791       return 0;
00792 
00793    node_r = add_mi_node_child( &rpl_tree->node, MI_DUP_VALUE, "ROOM", 4,
00794       room_name.s, room_name.len);
00795    if(node_r == NULL)
00796       goto error;
00797    
00798 
00799    imp = room->members;
00800    i=0;
00801    while(imp)
00802    {
00803       i++;
00804       node = add_mi_node_child(node_r, MI_DUP_VALUE, "MEMBER",6, imp->uri.s,
00805          imp->uri.len);
00806       if(node == NULL)
00807          goto error;
00808       imp = imp->next;
00809    }
00810    
00811    p = int2str(i, &len);
00812    attr= add_mi_attr(node_r, MI_DUP_VALUE, "NR_OF_MEMBERS", 13, p, len);
00813    if(attr == 0)
00814       goto error;
00815 
00816    imc_release_room(room);
00817 
00818    return rpl_tree;
00819 
00820 error:
00821    imc_release_room(room);
00822    free_mi_tree(rpl_tree);
00823    return 0;
00824 }

Generated on Wed May 23 06:00:46 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6