diff --git a/src/modules/imc/doc/imc.xml b/src/modules/imc/doc/imc.xml
index 99f97a5eed3..f0f4a73d1b0 100644
--- a/src/modules/imc/doc/imc.xml
+++ b/src/modules/imc/doc/imc.xml
@@ -37,6 +37,13 @@
anca@voice-system.ro
+
+ Joey
+ Golan
+
+ joeygo@gmail.com
+
+
2006
diff --git a/src/modules/imc/doc/imc_admin.xml b/src/modules/imc/doc/imc_admin.xml
index 85a31a844a1..6f7f5a02582 100644
--- a/src/modules/imc/doc/imc_admin.xml
+++ b/src/modules/imc/doc/imc_admin.xml
@@ -453,6 +453,20 @@ if(is_method("MESSAGE)
-eg: #add sip:john@kamailio.org sip:chat-000@kamailio.org
or #add john@kamailio.org sent to sip:chat-000@kamailio.org
-error case: return codes: -50 -- -59
+
+11.modify
+ -modify user role in a room
+ -takes 3 parameters:
+ 1)the complete address of the user
+ 2)the role of the user
+ 3)the address of the room -if not present it will be considered
+ to be the address in the To header of the message
+ -only certain users have the right to invite other user: the owner
+ and the administrators
+ -roles: owner, admin, member
+ -eg: #invite sip:john@kamailio.org admin sip:chat-000@kamailio.org
+ or #invite john@kamailio.org admin sent to sip:chat-000@kamailio.org
+ -error case: return codes: -120 -- -129
...
diff --git a/src/modules/imc/imc_cmd.c b/src/modules/imc/imc_cmd.c
index 8d9c6f3ea18..4f8a1501425 100644
--- a/src/modules/imc/imc_cmd.c
+++ b/src/modules/imc/imc_cmd.c
@@ -62,6 +62,7 @@ static str msg_join_attempt_bcast = STR_STATIC_INIT(PREFIX "%.*s attempted to jo
static str msg_join_attempt_ucast = STR_STATIC_INIT(PREFIX "Private rooms are by invitation only. Room owners have been notified.");
static str msg_invite = STR_STATIC_INIT(PREFIX "%.*s invites you to join the room (send '%.*saccept' or '%.*sreject')");
static str msg_add_reject = STR_STATIC_INIT(PREFIX "You don't have the permmission to add members to this room");
+static str msg_modify_reject = STR_STATIC_INIT(PREFIX "You don't have the permmission to modify members in this room");
#if 0
static str msg_rejected = STR_STATIC_INIT(PREFIX "%.*s has rejected invitation");
#endif
@@ -289,6 +290,9 @@ int imc_parse_cmd(char *buf, int len, imc_cmd_p cmd)
} else if(cmd->name.len==(sizeof("destroy")-1)
&& !strncasecmp(cmd->name.s, "destroy", cmd->name.len)) {
cmd->type = IMC_CMDID_DESTROY;
+ } else if(cmd->name.len==(sizeof("modify")-1)
+ && !strncasecmp(cmd->name.s, "modify", cmd->name.len)) {
+ cmd->type = IMC_CMDID_MODIFY;
} else if(cmd->name.len==(sizeof("help")-1)
&& !strncasecmp(cmd->name.s, "help", cmd->name.len)) {
cmd->type = IMC_CMDID_HELP;
@@ -1295,6 +1299,122 @@ int imc_handle_message(struct sip_msg* msg, str *msgbody,
return rv;
}
+int imc_handle_modify(struct sip_msg* msg, imc_cmd_t *cmd,
+ struct imc_uri *src, struct imc_uri *dst)
+{
+ int rv = -1;
+ imc_room_p rm = 0;
+ imc_member_p member = 0;
+ int flag_member = 0;
+ str body;
+ struct imc_uri user, room;
+ int params = 0;
+
+ memset(&user, '\0', sizeof(user));
+ memset(&room, '\0', sizeof(room));
+
+ if (cmd->param[0].s) {
+ params++;
+ if (cmd->param[1].s) {
+ params++;
+ if (cmd->param[2].s) {
+ params++;
+ }
+ }
+ }
+
+ switch(params) {
+ case 0:
+ LM_INFO("Modify command with missing argument from [%.*s]\n", STR_FMT(&src->uri));
+ goto error;
+ case 1:
+ LM_INFO("Modify command with missing argument role\n");
+ goto error;
+ case 2:
+ case 3:
+ /* identify the role */
+ if(cmd->param[1].len==(sizeof(IMC_MEMBER_OWNER_STR)-1)
+ && !strncasecmp(cmd->param[1].s, IMC_MEMBER_OWNER_STR, cmd->param[1].len))
+ {
+ flag_member |= IMC_MEMBER_OWNER;
+ } else if(cmd->param[1].len==(sizeof(IMC_MEMBER_ADMIN_STR)-1)
+ && !strncasecmp(cmd->param[1].s, IMC_MEMBER_ADMIN_STR, cmd->param[1].len))
+ {
+ flag_member |= IMC_MEMBER_ADMIN;
+ } else if(cmd->param[1].len==(sizeof(IMC_MEMBER_INVITED_STR)-1)
+ && !strncasecmp(cmd->param[1].s, IMC_MEMBER_INVITED_STR, cmd->param[1].len))
+ {
+ flag_member |= IMC_MEMBER_INVITED;
+ } else {
+ LM_INFO("Modify command with unknown argument role [%.*s]\n", STR_FMT(&cmd->param[1]));
+ goto error;
+ }
+
+ if (build_imc_uri(&room, cmd->param[3].s ? cmd->param[3] : dst->parsed.user, &dst->parsed))
+ goto error;
+ break;
+ default:
+ LM_ERR("Invalid number of parameters %d\n", params);
+ goto error;
+ }
+
+ if (build_imc_uri(&user, cmd->param[0], &dst->parsed))
+ goto error;
+
+ rm = imc_get_room(&room.parsed.user, &room.parsed.host);
+ if (rm == NULL || (rm->flags & IMC_ROOM_DELETED)) {
+ LM_ERR("Room [%.*s] does not exist!\n", STR_FMT(&room.uri));
+ goto error;
+ }
+ member = imc_get_member(rm, &src->parsed.user, &src->parsed.host);
+
+ if (member == NULL) {
+ LM_ERR("User [%.*s] is not member of room [%.*s]!\n", STR_FMT(&src->uri), STR_FMT(&room.uri));
+ goto error;
+ }
+
+ if (!(member->flags & IMC_MEMBER_OWNER) &&
+ !(member->flags & IMC_MEMBER_ADMIN)) {
+ LM_ERR("User [%.*s] has no right to modify others role!\n", STR_FMT(&member->uri));
+ imc_send_message(&rm->uri, &member->uri, build_headers(msg), &msg_modify_reject);
+ goto done;
+ }
+
+ member = imc_get_member(rm, &user.parsed.user, &user.parsed.host);
+ if (member == NULL) {
+ LM_ERR("User [%.*s] is not member of room [%.*s]!\n", STR_FMT(&member->uri), STR_FMT(&room.uri));
+ goto error;
+ }
+
+ rv = imc_modify_member(rm, &src->parsed.user, &src->parsed.host, flag_member);
+
+ if (rv == -1) {
+ LM_ERR("Failed to modify member [%.*s] role [%.*s]\n", STR_FMT(&member->uri), STR_FMT(&cmd->param[1]));
+ goto error;
+ }
+
+ body.s = imc_body_buf;
+ body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_joined.s, STR_FMT(format_uri(member->uri)));
+
+ if (body.len < 0) {
+ LM_ERR("Error while building response\n");
+ goto error;
+ }
+
+ if (body.len > 0)
+ imc_room_broadcast(rm, build_headers(msg), &body);
+
+ if (body.len >= sizeof(imc_body_buf))
+ LM_ERR("Truncated message '%.*s'\n", STR_FMT(&body));
+
+done:
+ rv = 0;
+error:
+ if (user.uri.s != NULL) pkg_free(user.uri.s);
+ if (room.uri.s != NULL) pkg_free(room.uri.s);
+ if (rm != NULL) imc_release_room(rm);
+ return rv;
+}
int imc_room_broadcast(imc_room_p room, str *ctype, str *body)
{
diff --git a/src/modules/imc/imc_cmd.h b/src/modules/imc/imc_cmd.h
index 64f444d715c..b35dfe7dcf6 100644
--- a/src/modules/imc/imc_cmd.h
+++ b/src/modules/imc/imc_cmd.h
@@ -48,6 +48,7 @@
#define IMC_CMDID_UNKNOWN 11
#define IMC_CMDID_ADD 12
#define IMC_CMDID_ROOMS 13
+#define IMC_CMDID_MODIFY 14
#define IMC_CMD_CREATE "create"
@@ -61,10 +62,14 @@
#define IMC_CMD_MEMBERS "members"
#define IMC_CMD_ADD "add"
#define IMC_CMD_ROOMS "rooms"
+#define IMC_CMD_MODIFY "modify"
#define IMC_ROOM_PRIVATE "private"
#define IMC_ROOM_PRIVATE_LEN (sizeof(IMC_ROOM_PRIVATE)-1)
+#define IMC_ROOM_ROLE "role"
+#define IMC_ROLE_LEN (sizeof(IMC_ROOM_ROLE)-1)
+
#define IMC_HELP_MSG "\r\n"IMC_CMD_START_STR IMC_CMD_CREATE" - \
create new conference room\r\n\
"IMC_CMD_START_STR IMC_CMD_JOIN" [] - \
@@ -73,6 +78,8 @@ join the conference room\r\n\
invite a user to join a conference room\r\n\
"IMC_CMD_START_STR IMC_CMD_ADD" [] - \
add a user to a conference room\r\n\
+"IMC_CMD_START_STR IMC_CMD_MODIFY" [] - \
+modify user role in a conference room\r\n\
"IMC_CMD_START_STR IMC_CMD_ACCEPT" - \
accept invitation to join a conference room\r\n\
"IMC_CMD_START_STR IMC_CMD_REJECT" - \
@@ -129,5 +136,7 @@ int imc_handle_help(struct sip_msg* msg, imc_cmd_t *cmd,
struct imc_uri *src, struct imc_uri *dst);
int imc_handle_message(struct sip_msg* msg, str *msgbody,
struct imc_uri *src, struct imc_uri *dst);
+int imc_handle_modify(struct sip_msg* msg, imc_cmd_t *cmd,
+ struct imc_uri *src, struct imc_uri *dst);
#endif
diff --git a/src/modules/imc/imc_mng.c b/src/modules/imc/imc_mng.c
index dc65d060888..7740a74b681 100644
--- a/src/modules/imc/imc_mng.c
+++ b/src/modules/imc/imc_mng.c
@@ -344,8 +344,38 @@ imc_member_p imc_add_member(imc_room_p room, str* user, str* domain, int flags)
return imp;
}
+imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flags) {
+ imc_member_p imp = NULL;
+ unsigned int hashid;
+
+ if(room==NULL || user == NULL || user->s==NULL || user->len<=0
+ || domain == NULL || domain->s==NULL || domain->len<=0)
+ {
+ LM_ERR("invalid parameters\n");
+ return NULL;
+ }
+
+ hashid = core_case_hash(user, domain, 0);
+ imp = room->members;
+ while(imp)
+ {
+ if(imp->hashid==hashid && imp->user.len==user->len
+ && imp->domain.len==domain->len
+ && !strncasecmp(imp->user.s, user->s, user->len)
+ && !strncasecmp(imp->domain.s, domain->s, domain->len))
+ {
+ LM_DBG("member found. modify flags\n");
+ imp->flags = flags;
+ return 0;
+ }
+ imp = imp->next;
+ }
+
+ return -1;
+}
+
/**
- * search memeber
+ * search member
*/
imc_member_p imc_get_member(imc_room_p room, str* user, str* domain)
{
@@ -374,7 +404,7 @@ imc_member_p imc_get_member(imc_room_p room, str* user, str* domain)
imp = imp->next;
}
- return NULL;
+ return 0;
}
/**
diff --git a/src/modules/imc/imc_mng.h b/src/modules/imc/imc_mng.h
index 206351e3cd3..866a1fa56dd 100644
--- a/src/modules/imc/imc_mng.h
+++ b/src/modules/imc/imc_mng.h
@@ -38,6 +38,10 @@
#define IMC_MEMBER_DELETED (1<<3)
#define IMC_MEMBER_SKIP (1<<4)
+#define IMC_MEMBER_OWNER_STR "owner"
+#define IMC_MEMBER_ADMIN_STR "admin"
+#define IMC_MEMBER_INVITED_STR "member"
+
typedef struct _imc_member
{
unsigned int hashid;
@@ -81,6 +85,7 @@ typedef struct _imc_hentry
} imc_hentry_t, *imc_hentry_p;
imc_member_p imc_add_member(imc_room_p room, str* user, str* domain, int flags);
+imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flags);
imc_member_p imc_get_member(imc_room_p room, str* user, str* domain);
int imc_del_member(imc_room_p room, str* user, str* domain);