00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
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
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
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
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
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
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
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 + 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
00494 result= tmb.t_request(&imc_msg_type,
00495 &member->uri,
00496 &member->uri,
00497 &room->uri,
00498 &imc_hdr_ctype,
00499 &body,
00500 (outbound_proxy.s)?&outbound_proxy:NULL,
00501 imc_inv_callback,
00502 (void*)(cback_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
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
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
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
00652
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
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
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
00731
00732
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
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
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
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
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
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
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
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
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
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
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
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
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,
00988 NULL,
00989 src,
00990 dst,
00991 &imc_hdr_ctype,
00992 &body,
00993 (outbound_proxy.s)?&outbound_proxy:NULL,
00994 NULL,
00995 NULL
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,
01020 NULL,
01021 src,
01022 dst,
01023 &imc_hdr_ctype,
01024 &body,
01025 (outbound_proxy.s)?&outbound_proxy:NULL,
01026 NULL,
01027 NULL
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 ;
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
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
01125 tmb.t_request(&imc_msg_type,
01126 NULL,
01127 dst,
01128 src,
01129 headers,
01130 body,
01131 (outbound_proxy.s)?&outbound_proxy:NULL,
01132 NULL,
01133 NULL
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
01176
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 + 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,
01219 NULL,
01220 &to_uri_s,
01221 &from_uri_s,
01222 NULL,
01223 &body_final,
01224 (outbound_proxy.s)?&outbound_proxy:NULL,
01225 NULL,
01226 NULL
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