imc_cmd.c

Go to the documentation of this file.
00001 /*
00002  * $Id: imc_cmd.c 5694 2009-03-12 23:07:36Z 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  */
00025 
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <unistd.h>
00030 #include <sys/types.h>
00031 #include "../../mem/shm_mem.h"
00032 #include "../../mem/mem.h"
00033 #include "../../sr_module.h"
00034 #include "../../dprint.h"
00035 #include "../../parser/parse_uri.h"
00036 
00037 #include "imc.h"
00038 #include "imc_cmd.h"
00039 
00040 #define IMC_BUF_SIZE 1024
00041 
00042 static char imc_body_buf[IMC_BUF_SIZE];
00043 
00044 static str imc_msg_type = { "MESSAGE", 7 };
00045 static str imc_hdr_ctype = { "Content-Type: text/plain\r\n",  26};
00046 
00047 int imc_send_message(str *src, str *dst, str *headers, str *body);
00048 int imc_room_broadcast(imc_room_p room, str *ctype, str *body);
00049 void imc_inv_callback( struct cell *t, int type, struct tmcb_params *ps);
00050 
00051 /**
00052  * parse cmd
00053  */
00054 int imc_parse_cmd(char *buf, int len, imc_cmd_p cmd)
00055 {
00056    char *p;
00057    int i;
00058    if(buf==NULL || len<=0 || cmd==NULL)
00059    {
00060       LM_ERR("invalid parameters\n");
00061       return -1;
00062    }
00063 
00064    memset(cmd, 0, sizeof(imc_cmd_t));
00065    if(buf[0]!=imc_cmd_start_char)
00066    {
00067       LM_ERR("invalid command [%.*s]\n", len, buf);
00068       return -1;
00069    }
00070    p = &buf[1];
00071    cmd->name.s = p;
00072    while(*p && p<buf+len)
00073    {
00074       if(*p==' ' || *p=='\t' || *p=='\r' || *p=='\n')
00075          break;
00076       p++;
00077    }
00078    if(cmd->name.s == p)
00079    {
00080       LM_ERR("no command in [%.*s]\n", len, buf);
00081       return -1;
00082    }
00083    cmd->name.len = p - cmd->name.s;
00084 
00085    /* identify the command */
00086    if(cmd->name.len==(sizeof("create")-1)
00087          && !strncasecmp(cmd->name.s, "create", cmd->name.len))
00088    {
00089       cmd->type = IMC_CMDID_CREATE;
00090    } else if(cmd->name.len==(sizeof("join")-1)
00091             && !strncasecmp(cmd->name.s, "join", cmd->name.len)) {
00092       cmd->type = IMC_CMDID_JOIN;
00093    } else if(cmd->name.len==(sizeof("invite")-1)
00094             && !strncasecmp(cmd->name.s, "invite", cmd->name.len)) {
00095       cmd->type = IMC_CMDID_INVITE;
00096    } else if(cmd->name.len==(sizeof("accept")-1)
00097             && !strncasecmp(cmd->name.s, "accept", cmd->name.len)) {
00098       cmd->type = IMC_CMDID_ACCEPT;
00099    } else if(cmd->name.len==(sizeof("deny")-1)
00100             && !strncasecmp(cmd->name.s, "deny", cmd->name.len)) {
00101       cmd->type = IMC_CMDID_DENY;
00102    } else if(cmd->name.len==(sizeof("remove")-1)
00103             && !strncasecmp(cmd->name.s, "remove", cmd->name.len)) {
00104       cmd->type = IMC_CMDID_REMOVE;
00105    } else if(cmd->name.len==(sizeof("exit")-1)
00106             && !strncasecmp(cmd->name.s, "exit", cmd->name.len)) {
00107       cmd->type = IMC_CMDID_EXIT;
00108    } else if(cmd->name.len==(sizeof("list")-1)
00109             && !strncasecmp(cmd->name.s, "list", cmd->name.len)) {
00110       cmd->type = IMC_CMDID_LIST;
00111    } else if(cmd->name.len==(sizeof("destroy")-1)
00112             && !strncasecmp(cmd->name.s, "destroy", cmd->name.len)) {
00113       cmd->type = IMC_CMDID_DESTROY;
00114    } else if(cmd->name.len==(sizeof("help")-1)
00115             && !strncasecmp(cmd->name.s, "help", cmd->name.len)) {
00116       cmd->type = IMC_CMDID_HELP;
00117       goto done;
00118    } else {
00119       cmd->type = IMC_CMDID_UNKNOWN;
00120       goto done;
00121    }
00122 
00123 
00124    if(*p=='\0' || p>=buf+len)
00125       goto done;
00126    
00127    i=0;
00128    do {
00129       while(p<buf+len && (*p==' ' || *p=='\t'))
00130          p++;
00131       if(p>=buf+len || *p=='\0' || *p=='\r' || *p=='\n')
00132          goto done;
00133       cmd->param[i].s = p;
00134       while(p<buf+len)
00135       {
00136          if(*p=='\0' || *p==' ' || *p=='\t' || *p=='\r' || *p=='\n')
00137             break;
00138          p++;
00139       }
00140       cmd->param[i].len =  p - cmd->param[i].s;
00141       i++;
00142       if(i>=IMC_CMD_MAX_PARAM)
00143          break;
00144    } while(1);
00145    
00146 done:
00147    LM_ERR("command: [%.*s]\n", cmd->name.len, cmd->name.s);
00148    for(i=0; i<IMC_CMD_MAX_PARAM; i++)
00149    {
00150       if(cmd->param[i].len<=0)
00151          break;
00152       LM_DBG("parameter %d=[%.*s]\n", i, cmd->param[i].len, cmd->param[i].s);
00153    }
00154    return 0;
00155 }
00156 
00157 /**
00158  *
00159  */
00160 int imc_handle_create(struct sip_msg* msg, imc_cmd_t *cmd,
00161       struct sip_uri *src, struct sip_uri *dst)
00162 {
00163    imc_room_p room = 0;
00164    imc_member_p member = 0;
00165    int flag_room = 0;
00166    int flag_member = 0;
00167    str body;
00168 
00169    room = imc_get_room(&cmd->param[0], &dst->host);
00170    if(room== NULL)
00171    {
00172       LM_DBG("new room [%.*s]\n",   cmd->param[0].len, cmd->param[0].s);
00173       if(cmd->param[1].len==IMC_ROOM_PRIVATE_LEN
00174          && !strncasecmp(cmd->param[1].s, IMC_ROOM_PRIVATE,
00175             cmd->param[1].len))
00176       {
00177          flag_room |= IMC_ROOM_PRIV;               
00178          LM_DBG("room with private flag on\n");
00179       }
00180          
00181       room= imc_add_room(&cmd->param[0], &dst->host, flag_room);
00182       if(room == NULL)
00183       {
00184          LM_ERR("failed to add new room\n");
00185          goto error;
00186       }  
00187       LM_DBG("added room uri= %.*s\n", room->uri.len, room->uri.s);
00188       flag_member |= IMC_MEMBER_OWNER;
00189       /* adding the owner as the forst member*/
00190       member= imc_add_member(room, &src->user, &src->host, flag_member);
00191       if(member == NULL)
00192       {
00193          LM_ERR("failed to add owner [%.*s]\n", src->user.len, src->user.s);
00194          goto error;
00195       }
00196       LM_DBG("added the owner as the first member "
00197             "[%.*s]\n",member->uri.len, member->uri.s);
00198    
00199       /* send info message */
00200       body.s = "*** room was created";
00201       body.len = sizeof("*** room was created")-1;
00202       imc_send_message(&room->uri, &member->uri, &imc_hdr_ctype, &body);
00203       goto done;
00204    }
00205    
00206    /* room already exists */
00207 
00208    LM_DBG("room [%.*s] already created\n",   cmd->param[0].len, cmd->param[0].s);
00209    if(!(room->flags & IMC_ROOM_PRIV)) 
00210    {
00211       LM_DBG("checking if the user [%.*s] is a member\n",
00212             src->user.len, src->user.s);
00213       member= imc_get_member(room, &src->user, &src->host);
00214       if(member== NULL)
00215       {              
00216          member= imc_add_member(room, &src->user, &src->host, flag_member);
00217          if(member == NULL)
00218          {
00219             LM_ERR("failed to add member [%.*s]\n",
00220                src->user.len, src->user.s);
00221             goto error;
00222          }
00223          LM_DBG("added as member [%.*s]\n",member->uri.len, member->uri.s);
00224          /* send info message */
00225          body.s = imc_body_buf;
00226          body.len = snprintf(body.s, IMC_BUF_SIZE,
00227             "*** <%.*s> has joined the room",
00228             member->uri.len, member->uri.s);
00229          if(body.len>0)
00230             imc_room_broadcast(room, &imc_hdr_ctype, &body);
00231 
00232          if(body.len>=IMC_BUF_SIZE)
00233             LM_ERR("member name %.*s truncated\n", member->uri.len, member->uri.s);
00234       }
00235    }
00236 
00237 done:
00238    if(room!=NULL)
00239       imc_release_room(room);
00240    return 0;
00241 
00242 error:
00243    if(room!=NULL)
00244       imc_release_room(room);
00245    return -1;
00246 }
00247 
00248 
00249 /**
00250  *
00251  */
00252 int imc_handle_join(struct sip_msg* msg, imc_cmd_t *cmd,
00253       struct sip_uri *src, struct sip_uri *dst)
00254 {
00255    imc_room_p room = 0;
00256    imc_member_p member = 0;
00257    int flag_room = 0;
00258    int flag_member = 0;
00259    str room_name;
00260    str body;
00261 
00262    room_name = cmd->param[0].s?cmd->param[0]:dst->user;
00263    room=imc_get_room(&room_name, &dst->host);
00264    if(room== NULL || (room->flags&IMC_ROOM_DELETED))
00265    {        
00266       LM_DBG("could not find room [%.*s]- adding\n", 
00267             room_name.len, room_name.s);
00268       room= imc_add_room(&room_name, &dst->host, flag_room);
00269       if(room == NULL)
00270       {
00271          LM_ERR("failed to add new room [%.*s]\n",
00272             room_name.len, room_name.s);
00273          goto error;
00274       }
00275       LM_DBG("created a new room [%.*s]\n", room->name.len, room->name.s);
00276 
00277       flag_member |= IMC_MEMBER_OWNER;
00278       member= imc_add_member(room, &src->user, &src->host, flag_member);
00279       if(member == NULL)
00280       {
00281          LM_ERR("failed to add new member [%.*s]\n",
00282             src->user.len, src->user.s);
00283          goto error;
00284       }
00285       /* send info message */
00286       body.s = "*** room was created";
00287       body.len = sizeof("*** room was created")-1;
00288       imc_send_message(&room->uri, &member->uri, &imc_hdr_ctype, &body);
00289       goto done;
00290    }
00291 
00292    /* room exists */
00293    LM_DBG("found room [%.*s]\n", room_name.len, room_name.s);
00294 
00295    member= imc_get_member(room, &src->user, &src->host);
00296    if(!(room->flags & IMC_ROOM_PRIV))
00297    {
00298       LM_DBG("room [%.*s] is public\n", room_name.len, room_name.s);
00299       if(member== NULL)
00300       {              
00301          LM_DBG("adding new member [%.*s]\n", src->user.len, src->user.s);
00302          member= imc_add_member(room, &src->user,
00303                            &src->host, flag_member);  
00304          if(member == NULL)
00305          {
00306             LM_ERR("adding new user [%.*s]\n", src->user.len, src->user.s);
00307             goto error;
00308          }  
00309          goto build_inform;
00310       } else { 
00311          LM_DBG("member [%.*s] is in room already\n",
00312             member->uri.len,member->uri.s );
00313       }
00314    } else {
00315       if(member==NULL)
00316       {
00317          LM_ERR("attept to join private room [%.*s] from user [%.*s]\n",
00318                room_name.len, room_name.s,   src->user.len, src->user.s);
00319          goto build_inform;
00320 
00321       }
00322 
00323       if(member->flags & IMC_MEMBER_INVITED) 
00324          member->flags &= ~IMC_MEMBER_INVITED;
00325    }
00326 
00327 build_inform:
00328    /* send info message */
00329    body.s = imc_body_buf;
00330    body.len = snprintf(body.s, IMC_BUF_SIZE, "*** <%.*s> has joined the room",
00331                member->uri.len, member->uri.s);
00332    if(body.len>0)
00333       imc_room_broadcast(room, &imc_hdr_ctype, &body);
00334 
00335    if(body.len>=IMC_BUF_SIZE)
00336       LM_ERR("member name %.*s truncated\n", member->uri.len, member->uri.s);
00337 
00338 done:
00339    if(room!=NULL)
00340       imc_release_room(room);
00341    return 0;
00342 
00343 error:
00344    if(room!=NULL)
00345       imc_release_room(room);
00346    return -1;
00347 }
00348 
00349 /**
00350  *
00351  */
00352 int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd,
00353       struct sip_uri *src, struct sip_uri *dst)
00354 {
00355    imc_room_p room = 0;
00356    imc_member_p member = 0;
00357    int flag_member = 0;
00358    int size = 0;
00359    int i = 0;
00360    int add_domain = 0;
00361    int add_sip = 0;
00362    str uri = {0, 0};
00363    str body;
00364    str room_name;
00365    struct sip_uri inv_uri;
00366    del_member_t *cback_param = NULL;
00367    int result;
00368 
00369 
00370    size = cmd->param[0].len+2 ;  
00371    add_domain = 1;
00372    add_sip = 0;
00373    while (i<size )
00374    {
00375       if(cmd->param[0].s[i]== '@')
00376       {  
00377          add_domain = 0;
00378          break;
00379       }
00380       i++;
00381    }
00382 
00383    if(add_domain)
00384       size += dst->host.len;
00385    if(cmd->param[0].len<4 || strncmp(cmd->param[0].s, "sip:", 4)!=0)
00386    {
00387       size += 4;
00388       add_sip = 1;
00389    }
00390       
00391    uri.s = (char*)pkg_malloc(size *sizeof(char));
00392    if(uri.s == NULL)
00393    {
00394       LM_ERR("no more pkg memory\n");
00395       goto error;
00396    }
00397    size= 0;
00398    if(add_sip)
00399    {  
00400       strcpy(uri.s, "sip:");
00401       size=4;
00402    }
00403       
00404    memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len);
00405    size += cmd->param[0].len;
00406 
00407    if(add_domain)
00408    {  
00409       uri.s[size] = '@';
00410       size++;
00411       memcpy(uri.s+ size, dst->host.s, dst->host.len);
00412       size+= dst->host.len;
00413    }
00414    uri.len = size;
00415 
00416    if(parse_uri(uri.s, uri.len, &inv_uri)!=0)
00417    {
00418       LM_ERR("bad uri [%.*s]!\n", uri.len, uri.s);
00419       goto error;
00420    }
00421                
00422    room_name = (cmd->param[1].s)?cmd->param[1]:dst->user;
00423    room = imc_get_room(&room_name, &dst->host);          
00424    if(room== NULL || (room->flags&IMC_ROOM_DELETED))
00425    {
00426       LM_ERR("the room does not exist [%.*s]!\n",
00427             room_name.len, room_name.s);
00428       goto error;
00429    }        
00430    member= imc_get_member(room, &src->user, &src->host);
00431 
00432    if(member==NULL)
00433    {
00434       LM_ERR("user [%.*s] is not member of[%.*s]!\n",
00435          src->user.len, src->user.s, room_name.len, room_name.s);
00436       goto error;
00437    }
00438    if(!(member->flags & IMC_MEMBER_OWNER) &&
00439          !(member->flags & IMC_MEMBER_ADMIN))
00440    {
00441       LM_ERR("user [%.*s] has no right to invite"
00442             " other users!\n", src->user.len, src->user.s);
00443       goto error;
00444    }
00445     
00446    member= imc_get_member(room, &inv_uri.user, &inv_uri.host);
00447    if(member!=NULL)
00448    {
00449       LM_ERR("user [%.*s] is already member"
00450             " of the room!\n", inv_uri.user.len, inv_uri.user.s);
00451       goto error;
00452    }
00453       
00454    flag_member |= IMC_MEMBER_INVITED;     
00455    member=imc_add_member(room, &inv_uri.user, &inv_uri.host, flag_member);
00456    if(member == NULL)
00457    {
00458       LM_ERR("adding member [%.*s]\n",
00459             inv_uri.user.len, inv_uri.user.s);
00460       goto error; 
00461    }
00462    
00463    body.len = 13 + member->uri.len - 4/* sip: */ + 28;   
00464    if(body.len>=IMC_BUF_SIZE || member->uri.len>=IMC_BUF_SIZE
00465          || room->uri.len>=IMC_BUF_SIZE)
00466    {
00467       LM_ERR("buffer size overflow\n");
00468       goto error; 
00469    }
00470 
00471    body.s = imc_body_buf;
00472    memcpy(body.s, "INVITE from: ", 13);
00473    memcpy(body.s+13, member->uri.s + 4, member->uri.len - 4);
00474    memcpy(body.s+ 9 + member->uri.len, "(Type: '#accept' or '#deny')", 28);   
00475    body.s[body.len] = '\0';         
00476 
00477    LM_DBG("to=[%.*s]\nfrom=[%.*s]\nbody=[%.*s]\n", 
00478          member->uri.len,member->uri.s,room->uri.len, room->uri.s,
00479          body.len, body.s);
00480             
00481    cback_param = (del_member_t*)shm_malloc(sizeof(del_member_t));
00482    if(cback_param==NULL)
00483    {
00484       LM_ERR("no more shm\n");
00485       goto error; 
00486    }
00487    memset(cback_param, 0, sizeof(del_member_t));
00488    cback_param->room_name = room->name;
00489    cback_param->room_domain = room->domain;
00490    cback_param->member_name = member->user;
00491    cback_param->member_domain = member->domain;
00492    cback_param->inv_uri = member->uri;
00493    /*?!?! possible race with 'remove user' */
00494    result= tmb.t_request(&imc_msg_type,            /* Request Method */
00495             &member->uri,                    /* Request-URI */
00496             &member->uri,                    /* To */
00497             &room->uri,                      /* From */
00498             &imc_hdr_ctype,                     /* Extra headers */
00499             &body,                              /* Message body */
00500             (outbound_proxy.s)?&outbound_proxy:NULL,/* outbound proxy*/
00501             imc_inv_callback,                /* callback function*/
00502             (void*)(cback_param)             /* callback param*/
00503          );          
00504    if(result< 0)
00505    {
00506       LM_ERR("in tm send request\n");
00507       shm_free(cback_param);
00508       goto error;
00509    }
00510    if(uri.s!=NULL)
00511       pkg_free(uri.s);
00512 
00513    imc_release_room(room);
00514 
00515    return 0;
00516 
00517 error:
00518    if(uri.s!=0)
00519       pkg_free(uri.s);
00520    if(room!=NULL)
00521       imc_release_room(room);
00522    return -1;
00523 }
00524 
00525 /**
00526  *
00527  */
00528 int imc_handle_accept(struct sip_msg* msg, imc_cmd_t *cmd,
00529       struct sip_uri *src, struct sip_uri *dst)
00530 {
00531    imc_room_p room = 0;
00532    imc_member_p member = 0;
00533    str room_name;
00534    str body;
00535    
00536    /* accepting the invitation */
00537    room_name = cmd->param[0].s?cmd->param[0]:dst->user;
00538    room=imc_get_room(&room_name, &dst->host);
00539    if(room== NULL || (room->flags&IMC_ROOM_DELETED))
00540    {
00541       LM_ERR("room [%.*s] is not created!\n",   room_name.len, room_name.s);
00542       goto error;
00543    }        
00544    /* if aready invited add as a member */
00545    member=imc_get_member(room, &src->user, &src->host);
00546    if(member==NULL || !(member->flags & IMC_MEMBER_INVITED))
00547    {
00548       LM_ERR("user [%.*s] not invited in the room!\n",
00549             src->user.len, src->user.s);
00550       goto error;
00551    }
00552          
00553    member->flags &= ~IMC_MEMBER_INVITED;
00554                
00555    /* send info message */
00556    body.s = imc_body_buf;
00557    body.len = snprintf(body.s, IMC_BUF_SIZE, "*** <%.*s> has joined the room",
00558                member->uri.len, member->uri.s);
00559    if(body.len>0)
00560       imc_room_broadcast(room, &imc_hdr_ctype, &body);
00561 
00562    if(body.len>=IMC_BUF_SIZE)
00563       LM_ERR("member name %.*s truncated\n", member->uri.len, member->uri.s);
00564 
00565    imc_release_room(room);
00566    return 0;
00567 
00568 error:
00569    if(room!=NULL)
00570       imc_release_room(room);
00571    return -1;
00572 }
00573 
00574 /**
00575  *
00576  */
00577 int imc_handle_remove(struct sip_msg* msg, imc_cmd_t *cmd,
00578       struct sip_uri *src, struct sip_uri *dst)
00579 {
00580    imc_room_p room = 0;
00581    imc_member_p member = 0;
00582    str room_name;
00583    str body;
00584    str uri = {0, 0};
00585    int size =0;
00586    int i = 0;
00587    int add_domain = 0;
00588    int add_sip = 0;
00589    struct sip_uri inv_uri;
00590 
00591    size= cmd->param[0].len+2;
00592    add_domain = 1;
00593    while (i<size )
00594    {
00595       if(cmd->param[0].s[i]== '@')
00596       {  
00597          add_domain =0;
00598          break;
00599       }
00600       i++;
00601    }
00602 
00603    if(add_domain)
00604       size += dst->host.len;
00605    if(cmd->param[0].len<=4 || strncmp(cmd->param[0].s, "sip:", 4)!=0)
00606    {
00607       size+= 4;
00608       add_sip = 1;
00609    }
00610 
00611    uri.s = (char*)pkg_malloc(size*sizeof(char));
00612    if(uri.s == NULL)
00613    {
00614       LM_ERR("no more pkg memory\n");
00615       goto error;
00616    }
00617 
00618    size= 0;
00619    if(add_sip)
00620    {  
00621       strcpy(uri.s, "sip:");
00622       size = 4;
00623    }
00624                
00625    memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len);
00626    size+= cmd->param[0].len;
00627 
00628    if(add_domain)
00629    {  
00630       uri.s[size] = '@';
00631       size++;
00632       memcpy(uri.s+size, dst->host.s, dst->host.len);
00633       size+= dst->host.len;
00634    }
00635    uri.len = size;
00636 
00637    if(parse_uri(uri.s, uri.len, &inv_uri)<0)
00638    {
00639       LM_ERR("invalid uri [%.*s]\n", uri.len, uri.s);
00640       goto error;
00641    }
00642                
00643    room_name = cmd->param[1].s?cmd->param[1]:dst->user;
00644    room= imc_get_room(&room_name, &dst->host);
00645    if(room==NULL || (room->flags&IMC_ROOM_DELETED))
00646    {
00647       LM_ERR("room [%.*s]does not exist!\n", room_name.len, room_name.s);
00648       goto error;
00649    }        
00650 
00651    /* verify if the user who sent the request is a member in the room
00652     * and has the right to remove other users */
00653    member= imc_get_member(room, &src->user, &src->host);
00654 
00655    if(member== NULL)
00656    {
00657       LM_ERR("user [%.*s] is not member of room [%.*s]!\n", 
00658             src->user.len, src->user.s, room_name.len, room_name.s);
00659       goto error;
00660    }
00661    
00662    if(!(member->flags & IMC_MEMBER_OWNER) &&
00663       !(member->flags & IMC_MEMBER_ADMIN))
00664    {
00665          LM_ERR("user [%.*s] has no right to remove other users [%.*s]!\n",
00666                src->user.len, src->user.s,   uri.len, uri.s);
00667          goto error;
00668    }
00669 
00670    /* verify if the user that is to be removed is a member of the room */
00671    member= imc_get_member(room, &inv_uri.user, &inv_uri.host);
00672    if(member== NULL)
00673    {
00674       LM_ERR("user [%.*s] is not member of room [%.*s]!\n", 
00675             inv_uri.user.len, inv_uri.user.s, room_name.len, room_name.s);
00676       goto error;
00677    }
00678             
00679    if(member->flags & IMC_MEMBER_OWNER)
00680    {
00681       LM_ERR("user [%.*s] is owner of room [%.*s]"
00682          " -- cannot be removed!\n", inv_uri.user.len, inv_uri.user.s,
00683          room_name.len, room_name.s);
00684       goto error;
00685    }  
00686 
00687    /* send message to the removed person */
00688    body.s = "You have been removed from this room";
00689    body.len = strlen(body.s);
00690 
00691    LM_DBG("to: [%.*s]\nfrom: [%.*s]\nbody: [%.*s]\n",
00692          member->uri.len, member->uri.s , room->uri.len, room->uri.s,
00693          body.len, body.s);
00694    imc_send_message(&room->uri, &member->uri, &imc_hdr_ctype, &body);
00695 
00696    member->flags |= IMC_MEMBER_DELETED;
00697    imc_del_member(room, &inv_uri.user, &inv_uri.host);
00698 
00699    body.s = imc_body_buf;
00700    body.len = snprintf(body.s, IMC_BUF_SIZE, "*** <%.*s> has joined the room",
00701                member->uri.len, member->uri.s);
00702    if(body.len>0)
00703       imc_room_broadcast(room, &imc_hdr_ctype, &body);
00704 
00705    if(body.len>=IMC_BUF_SIZE)
00706       LM_ERR("member name %.*s truncated\n", member->uri.len, member->uri.s);
00707 
00708    if(uri.s!=0)
00709       pkg_free(uri.s);
00710    imc_release_room(room);
00711    return 0;
00712 
00713 error:
00714    if(uri.s!=0)
00715       pkg_free(uri.s);
00716    if(room!=NULL)
00717       imc_release_room(room);
00718    return -1;
00719 }
00720 
00721 /**
00722  *
00723  */
00724 int imc_handle_deny(struct sip_msg* msg, imc_cmd_t *cmd,
00725       struct sip_uri *src, struct sip_uri *dst)
00726 {
00727    imc_room_p room = 0;
00728    imc_member_p member = 0;
00729    str room_name;
00730    // str body;
00731 
00732    /* denying an invitation */
00733    room_name = cmd->param[0].s?cmd->param[0]:dst->user;
00734    room= imc_get_room(&room_name, &dst->host);
00735 
00736    if(room== NULL || (room->flags&IMC_ROOM_DELETED))
00737    {
00738       LM_ERR("room [%.*s] does not exist!\n", room_name.len, room_name.s);
00739       goto error;
00740    }        
00741    /* If the user is an invited member, delete it froim the list */
00742    member= imc_get_member(room, &src->user, &src->host);
00743    if(member==NULL || !(member->flags & IMC_MEMBER_INVITED))
00744    {
00745       LM_ERR("user [%.*s] was not invited in room [%.*s]!\n", 
00746             src->user.len, src->user.s,   room_name.len, room_name.s);
00747       goto error;
00748    }     
00749    
00750 #if 0
00751    /* send info message */
00752    body.s = imc_body_buf;
00753    body.len = snprintf(body.s, IMC_BUF_SIZE, 
00754          "The user [%.*s] has denied the invitation",
00755          src->user.len, src->user.s);
00756    if(body.len>0)
00757       imc_send_message(&room->uri, &memeber->uri, &imc_hdr_ctype, &body);
00758 #endif
00759    LM_ERR("user [%.*s] declined invitation in room [%.*s]!\n", 
00760          src->user.len, src->user.s,   room_name.len, room_name.s);
00761 
00762    imc_del_member(room, &src->user, &src->host);
00763    
00764    imc_release_room(room);
00765 
00766    return 0;
00767 error:
00768    if(room!=NULL)
00769       imc_release_room(room);
00770    return -1;
00771 }
00772 
00773 /**
00774  *
00775  */
00776 int imc_handle_list(struct sip_msg* msg, imc_cmd_t *cmd,
00777       struct sip_uri *src, struct sip_uri *dst)
00778 {
00779    imc_room_p room = 0;
00780    imc_member_p member = 0;
00781    imc_member_p imp = 0;
00782    str room_name;
00783    str body;
00784    char *p;
00785    
00786    /* the user wants to leave the room */
00787    room_name = cmd->param[0].s?cmd->param[0]:dst->user;
00788 
00789    room= imc_get_room(&room_name, &dst->host);
00790    if(room== NULL || (room->flags&IMC_ROOM_DELETED))
00791    {
00792       LM_ERR("room [%.*s] does not exist!\n",   room_name.len, room_name.s);
00793       goto error;
00794    }     
00795 
00796    /* verify if the user is a member of the room */
00797    member = imc_get_member(room, &src->user, &src->host);
00798 
00799    if(member == NULL)
00800    {
00801       LM_ERR("user [%.*s] is not member of room [%.*s]!\n", 
00802             src->user.len, src->user.s,   room_name.len, room_name.s);
00803       goto error;
00804    }
00805    p = imc_body_buf;
00806    strncpy(p, "Members:\n", 9);
00807    p+=9;
00808    imp = room->members;
00809 
00810    while(imp)
00811    {
00812       if((imp->flags&IMC_MEMBER_INVITED)||(imp->flags&IMC_MEMBER_DELETED)
00813             || (imp->flags&IMC_MEMBER_SKIP))
00814       {
00815          imp = imp->next;
00816          continue;
00817       }
00818       if(imp->flags & IMC_MEMBER_OWNER)
00819          *p++ = '*';
00820       else if(imp->flags & IMC_MEMBER_ADMIN)
00821          *p++ = '~';
00822       strncpy(p, imp->uri.s, imp->uri.len);
00823       p += imp->uri.len;
00824       *p++ = '\n';
00825       imp = imp->next;
00826    }
00827    
00828    imc_release_room(room);
00829 
00830    /* write over last '\n' */
00831    *(--p) = 0;
00832    body.s   = imc_body_buf;
00833    body.len = p-body.s;
00834    LM_DBG("members = [%.*s]\n", body.len, body.s);
00835    imc_send_message(&room->uri, &member->uri, &imc_hdr_ctype, &body);
00836 
00837 
00838    return 0;
00839 error:
00840    if(room!=NULL)
00841       imc_release_room(room);
00842    return -1;
00843 }
00844 
00845 /**
00846  *
00847  */
00848 int imc_handle_exit(struct sip_msg* msg, imc_cmd_t *cmd,
00849       struct sip_uri *src, struct sip_uri *dst)
00850 {
00851    imc_room_p room = 0;
00852    imc_member_p member = 0;
00853    str room_name;
00854    str body;
00855    
00856    /* the user wants to leave the room */
00857    room_name = cmd->param[0].s?cmd->param[0]:dst->user;
00858 
00859    room= imc_get_room(&room_name, &dst->host);
00860    if(room== NULL || (room->flags&IMC_ROOM_DELETED))
00861    {
00862       LM_ERR("room [%.*s] does not exist!\n",   room_name.len, room_name.s);
00863       goto error;
00864    }     
00865 
00866    /* verify if the user is a member of the room */
00867    member= imc_get_member(room, &src->user, &src->host);
00868 
00869    if(member== NULL)
00870    {
00871       LM_ERR("user [%.*s] is not member of room [%.*s]!\n", 
00872             src->user.len, src->user.s,   room_name.len, room_name.s);
00873       goto error;
00874    }
00875          
00876    if(member->flags & IMC_MEMBER_OWNER)
00877    {
00878       /*If the user is the owner of the room, the room is distroyed */
00879       room->flags |=IMC_ROOM_DELETED;
00880 
00881       body.s = imc_body_buf;
00882       strcpy(body.s, "The room has been destroyed");
00883       body.len = strlen(body.s);
00884       imc_room_broadcast(room, &imc_hdr_ctype, &body);
00885 
00886       imc_release_room(room);
00887       
00888       imc_del_room(&room_name, &dst->host);
00889       room = NULL;
00890       goto done;
00891    } else {
00892       /* delete user */
00893       member->flags |= IMC_MEMBER_DELETED;
00894       imc_del_member(room, &src->user, &src->host);
00895       body.s = imc_body_buf;
00896       body.len = snprintf(body.s, IMC_BUF_SIZE, 
00897             "The user [%.*s] has left the room",
00898             src->user.len, src->user.s);
00899       if(body.len>0)
00900          imc_room_broadcast(room, &imc_hdr_ctype, &body);
00901 
00902       if(body.len>=IMC_BUF_SIZE)
00903          LM_ERR("user name %.*s truncated\n", src->user.len, src->user.s);
00904    }
00905 
00906 done:
00907    if(room!=NULL)
00908       imc_release_room(room);
00909    return 0;
00910 
00911 error:
00912    if(room!=NULL)
00913       imc_release_room(room);
00914    return -1;
00915 }
00916 
00917 /**
00918  *
00919  */
00920 int imc_handle_destroy(struct sip_msg* msg, imc_cmd_t *cmd,
00921       struct sip_uri *src, struct sip_uri *dst)
00922 {
00923    imc_room_p room = 0;
00924    imc_member_p member = 0;
00925    str room_name;
00926    str body;
00927    
00928    /* distrugere camera */
00929    room_name = cmd->param[0].s?cmd->param[0]:dst->user;
00930 
00931    room= imc_get_room(&room_name, &dst->host);
00932    if(room== NULL || (room->flags&IMC_ROOM_DELETED))
00933    {
00934       LM_ERR("room [%.*s] does not exist!\n",   room_name.len, room_name.s);
00935       goto error;
00936    }     
00937 
00938    /* verify is the user is a member of the room*/
00939    member= imc_get_member(room, &src->user, &src->host);
00940 
00941    if(member== NULL)
00942    {
00943       LM_ERR("user [%.*s] is not a member of room [%.*s]!\n", 
00944             src->user.len, src->user.s,   room_name.len, room_name.s);
00945       goto error;
00946    }
00947          
00948    if(!(member->flags & IMC_MEMBER_OWNER))
00949    {
00950       LM_ERR("user [%.*s] is not owner of room [%.*s] -- cannot destroy it"
00951             "!\n", src->user.len, src->user.s, room_name.len, room_name.s);
00952       goto error;
00953    }
00954    room->flags |= IMC_ROOM_DELETED;
00955 
00956    body.s = imc_body_buf;
00957    strcpy(body.s, "The room has been destroyed");
00958    body.len = strlen(body.s);
00959 
00960    /* braodcast message */
00961    imc_room_broadcast(room, &imc_hdr_ctype, &body);
00962 
00963    imc_release_room(room);
00964 
00965    LM_DBG("deleting room\n");
00966    imc_del_room(&room_name, &dst->host);
00967 
00968    return 0;
00969 
00970 error:
00971    if(room!=NULL)
00972       imc_release_room(room);
00973    return -1;
00974 }
00975 
00976 /**
00977  *
00978  */
00979 int imc_handle_help(struct sip_msg* msg, imc_cmd_t *cmd, str *src, str *dst)
00980 {
00981    str body;
00982 
00983    body.s   = IMC_HELP_MSG;
00984    body.len = IMC_HELP_MSG_LEN;
00985 
00986    LM_DBG("to: [%.*s] from: [%.*s]\n", src->len, src->s, dst->len, dst->s);
00987    tmb.t_request(&imc_msg_type,                 /* Request method */
00988             NULL,                         /* Request-URI */
00989             src,                          /* To */
00990             dst,                          /* From */
00991             &imc_hdr_ctype,                     /* Headers */
00992             &body,                           /* Body */
00993             (outbound_proxy.s)?&outbound_proxy:NULL,/* outbound proxy */
00994             NULL,                         /* callback function */
00995             NULL                          /* callback parameter*/
00996             );
00997    return 0;
00998 }
00999 
01000 /**
01001  *
01002  */
01003 int imc_handle_unknown(struct sip_msg* msg, imc_cmd_t *cmd, str *src, str *dst)
01004 {
01005    str body;
01006 
01007    body.s   = imc_body_buf;
01008    body.len = snprintf(body.s, IMC_BUF_SIZE,
01009       "invalid command '%.*s' - send ''%.*shelp' for details",
01010       cmd->name.len, cmd->name.s, imc_cmd_start_str.len, imc_cmd_start_str.s);
01011 
01012    if(body.len<0 || body.len>=IMC_BUF_SIZE)
01013    {
01014       LM_ERR("unable to print message\n");
01015       return -1;
01016    }
01017 
01018    LM_DBG("to: [%.*s] from: [%.*s]\n", src->len, src->s, dst->len, dst->s);
01019    tmb.t_request(&imc_msg_type,                 /* Request method */
01020             NULL,                         /* Request-URI */
01021             src,                          /* To */
01022             dst,                          /* From */
01023             &imc_hdr_ctype,                     /* Headers */
01024             &body,                           /* Body */
01025             (outbound_proxy.s)?&outbound_proxy:NULL,/* outbound proxy */
01026             NULL,                         /* callback function */
01027             NULL                          /* callback parameter*/
01028          );
01029    return 0;
01030 }
01031 
01032 /**
01033  *
01034  */
01035 int imc_handle_message(struct sip_msg* msg, str *msgbody,
01036       struct sip_uri *src, struct sip_uri *dst)
01037 {
01038    imc_room_p room = 0;
01039    imc_member_p member = 0;
01040    str body;
01041 
01042    room = imc_get_room(&dst->user, &dst->host);    
01043    if(room==NULL || (room->flags&IMC_ROOM_DELETED))
01044    {
01045       LM_ERR("room [%.*s] does not exist!\n",   dst->user.len, dst->user.s);
01046       goto error;
01047    }
01048 
01049    member= imc_get_member(room, &src->user, &src->host);
01050    if(member== NULL || (member->flags & IMC_MEMBER_INVITED))
01051    {
01052       LM_ERR("user [%.*s] has no rights to send messages in room [%.*s]!\n",
01053             src->user.len, src->user.s,   dst->user.len, dst->user.s);
01054       goto error;
01055    }
01056    
01057    LM_DBG("broadcast to room [%.*s]\n", room->uri.len, room->uri.s);
01058 
01059    body.s = imc_body_buf;
01060    body.len = msgbody->len + member->uri.len /* -4 (sip:) +4 (<>: ) */;
01061    if(body.len>=IMC_BUF_SIZE)
01062    {
01063       LM_ERR("buffer overflow [%.*s]\n", msgbody->len, msgbody->s);
01064       goto error;
01065    }
01066    body.s[0] = '<';
01067    memcpy(body.s + 1, member->uri.s + 4, member->uri.len - 4);
01068    memcpy(body.s + 1 + member->uri.len - 4, ">: ", 3);      
01069    memcpy(body.s + 1 + member->uri.len - 4 +3, msgbody->s, msgbody->len);
01070    body.s[body.len] = '\0';
01071 
01072    member->flags |= IMC_MEMBER_SKIP;
01073    imc_room_broadcast(room, &imc_hdr_ctype, &body);
01074    member->flags &= ~IMC_MEMBER_SKIP;
01075 
01076    imc_release_room(room);
01077    return 0;
01078 
01079 error:
01080    if(room!=NULL)
01081       imc_release_room(room);
01082    return -1;
01083 }
01084 
01085 /*
01086  *
01087  */
01088 int imc_room_broadcast(imc_room_p room, str *ctype, str *body)
01089 {
01090    imc_member_p imp;
01091 
01092    if(room==NULL || body==NULL)
01093       return -1;
01094 
01095    imp = room->members;
01096 
01097    LM_DBG("nr = %d\n", room->nr_of_members );
01098 
01099    while(imp)
01100    {
01101       LM_DBG("to uri = %.*s\n", imp->uri.len, imp->uri.s);
01102       if((imp->flags&IMC_MEMBER_INVITED)||(imp->flags&IMC_MEMBER_DELETED)
01103             || (imp->flags&IMC_MEMBER_SKIP))
01104       {
01105          imp = imp->next;
01106          continue;
01107       }
01108       
01109       /* to-do: callbac to remove user fi delivery fails */
01110       imc_send_message(&room->uri, &imp->uri, ctype, body);
01111       
01112       imp = imp->next;
01113    }
01114    return 0;
01115 }
01116 
01117 /*
01118  *
01119  */
01120 int imc_send_message(str *src, str *dst, str *headers, str *body)
01121 {
01122    if(src==NULL || dst==NULL || body==NULL)
01123       return -1;
01124    /* to-do: callbac to remove user fi delivery fails */
01125    tmb.t_request(&imc_msg_type,                 /* Request method */
01126          NULL,                            /* Request-URI */
01127          dst,                             /* To */
01128          src,                             /* From */
01129          headers,                         /* Headers */
01130          body,                            /* Body */
01131          (outbound_proxy.s)?&outbound_proxy:NULL,  /* outbound proxy */
01132          NULL,                            /* callback function */
01133          NULL                             /* callback parameter */
01134       );
01135    return 0;
01136 }
01137 
01138 /*
01139  *
01140  */
01141 void imc_inv_callback( struct cell *t, int type, struct tmcb_params *ps)
01142 {
01143    str body_final;
01144    char from_uri_buf[256];
01145    char to_uri_buf[256];
01146    char body_buf[256];
01147    str from_uri_s, to_uri_s;
01148    imc_member_p member= NULL;
01149    imc_room_p room = NULL;
01150 
01151    if(ps->param==NULL || *ps->param==NULL || 
01152          (del_member_t*)(*ps->param) == NULL)
01153    {
01154       LM_DBG("member not received\n");
01155       return;
01156    }
01157    
01158    LM_DBG("completed with status %d [member name domain:"
01159          "%p/%.*s/%.*s]\n",ps->code, ps->param, 
01160          ((del_member_t *)(*ps->param))->member_name.len,
01161          ((del_member_t *)(*ps->param))->member_name.s,
01162          ((del_member_t *)(*ps->param))->member_domain.len, 
01163          ((del_member_t *)(*ps->param))->member_domain.s);
01164    if(ps->code < 300)
01165       return;
01166    else
01167    {
01168       room= imc_get_room(&((del_member_t *)(*ps->param))->room_name,
01169                   &((del_member_t *)(*ps->param))->room_domain );
01170       if(room==NULL)
01171       {
01172          LM_ERR("the room does not exist!\n");
01173          goto error;
01174       }        
01175       /*verify if the user who sent the request is a member in the room
01176        * and has the right to remove other users */
01177       member= imc_get_member(room,
01178             &((del_member_t *)(*ps->param))->member_name,
01179             &((del_member_t *)(*ps->param))->member_domain);
01180 
01181       if(member== NULL)
01182       {
01183          LM_ERR("the user is not a member of the room!\n");
01184          goto error;
01185       }
01186       imc_del_member(room,
01187             &((del_member_t *)(*ps->param))->member_name,
01188             &((del_member_t *)(*ps->param))->member_domain);
01189       goto build_inform;
01190 
01191    }
01192    
01193 
01194 build_inform:
01195       
01196    body_final.s = body_buf;
01197    body_final.len = member->uri.len - 4 /* sip: part of URI */ + 20;
01198    memcpy(body_final.s, member->uri.s + 4, member->uri.len - 4);
01199    memcpy(body_final.s+member->uri.len-4," is not registered.  ",21);
01200       
01201    goto send_message;
01202 
01203 send_message:
01204    
01205    from_uri_s.s = from_uri_buf;
01206    from_uri_s.len = room->uri.len;
01207    strncpy(from_uri_s.s, room->uri.s, room->uri.len);
01208 
01209    LM_DBG("sending message\n");
01210    
01211    to_uri_s.s = to_uri_buf;
01212    to_uri_s.len = ((del_member_t *)(*ps->param))->inv_uri.len;
01213    strncpy(to_uri_s.s,((del_member_t *)(*ps->param))->inv_uri.s ,
01214          ((del_member_t *)(*ps->param))->inv_uri.len);
01215 
01216    LM_DBG("to: %.*s\nfrom: %.*s\nbody: %.*s\n", to_uri_s.len, to_uri_s.s,
01217          from_uri_s.len, from_uri_s.s, body_final.len, body_final.s);
01218    tmb.t_request(&imc_msg_type,                    /* Request method*/
01219                NULL,                         /* Request-URI */
01220                &to_uri_s,                       /* To */
01221                &from_uri_s,                     /* From */
01222                NULL,                         /* Headers */
01223                &body_final,                     /* Body */
01224                (outbound_proxy.s)?&outbound_proxy:NULL,/* outbound proxy*/
01225                NULL,                      /* callback function */
01226                NULL                       /* callback parameter*/
01227             );
01228    if(room!=NULL)
01229    {
01230       imc_release_room(room);
01231    }
01232 
01233    if((del_member_t *)(*ps->param))
01234       shm_free(*ps->param);
01235 
01236    return;
01237 
01238 error:
01239    if(room!=NULL)
01240    {
01241       imc_release_room(room);
01242    }
01243    if((del_member_t *)(*ps->param))
01244       shm_free(*ps->param);
01245    return; 
01246 }
01247 

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