diff --git a/src/modules/websocket/websocket.c b/src/modules/websocket/websocket.c index 417313b740c..af536e42697 100644 --- a/src/modules/websocket/websocket.c +++ b/src/modules/websocket/websocket.c @@ -13,8 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Exception: permission to copy, modify, propagate, and distribute a work @@ -37,6 +37,8 @@ #include "../../core/mem/mem.h" #include "../../core/mod_fix.h" #include "../../core/parser/msg_parser.h" +#include "../../core/rpc.h" +#include "../../core/rpc_lookup.h" #include "ws_conn.h" #include "ws_handshake.h" #include "ws_frame.h" @@ -54,6 +56,8 @@ static void destroy(void); static int ws_close_fixup(void** param, int param_no); static int pv_get_ws_conid_f(struct sip_msg *, pv_param_t *, pv_value_t *); +static int ws_init_rpc(void); + sl_api_t ws_slb; #define DEFAULT_KEEPALIVE_INTERVAL 1 @@ -64,8 +68,7 @@ static int ws_keepalive_timeout = DEFAULT_KEEPALIVE_TIMEOUT; #define DEFAULT_KEEPALIVE_PROCESSES 1 static int ws_keepalive_processes = DEFAULT_KEEPALIVE_PROCESSES; -static cmd_export_t cmds[]= -{ +static cmd_export_t cmds[] = { /* ws_frame.c */ { "ws_close", (cmd_function) ws_close, 0, 0, 0, @@ -85,8 +88,7 @@ static cmd_export_t cmds[]= { 0, 0, 0, 0, 0, 0 } }; -static param_export_t params[]= -{ +static param_export_t params[] = { /* ws_frame.c */ { "keepalive_mechanism", INT_PARAM, &ws_keepalive_mechanism }, { "keepalive_timeout", INT_PARAM, &ws_keepalive_timeout }, @@ -103,8 +105,7 @@ static param_export_t params[]= { 0, 0, 0 } }; -static stat_export_t stats[] = -{ +static stat_export_t stats[] = { /* ws_conn.c */ { "ws_current_connections", 0, &ws_current_connections }, { "ws_max_concurrent_connections", 0, &ws_max_concurrent_connections }, @@ -143,8 +144,7 @@ static stat_export_t stats[] = { 0, 0, 0 } }; -static mi_export_t mi_cmds[] = -{ +static mi_export_t mi_cmds[] = { /* ws_conn.c */ { "ws.dump", ws_mi_dump, 0, 0, 0 }, @@ -166,8 +166,7 @@ static pv_export_t mod_pvs[] = { {{0, 0}, 0, 0, 0, 0, 0, 0, 0} }; -struct module_exports exports= -{ +struct module_exports exports = { "websocket", DEFAULT_DLFLAGS, /* dlopen flags */ cmds, /* Exported functions */ @@ -214,6 +213,12 @@ static int mod_init(void) goto error; } + if(ws_init_rpc()<0) + { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + if (wsconn_init() < 0) { LM_ERR("initialising WebSocket connections table\n"); @@ -356,3 +361,27 @@ static int pv_get_ws_conid_f(struct sip_msg *msg, pv_param_t *param, return pv_get_sintval(msg, param, res, msg->rcv.proto_reserved1); } + +static const char* ws_rpc_close_doc[2] = { + "Close a websocket connection by id", + 0 +}; + +rpc_export_t ws_rpc_cmds[] = { + {"ws.close", ws_rpc_close, + ws_rpc_close_doc, 0}, + {0, 0, 0, 0} +}; + +/** + * register RPC commands + */ +static int ws_init_rpc(void) +{ + if (rpc_register_array(ws_rpc_cmds)!=0) + { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + return 0; +} diff --git a/src/modules/websocket/ws_conn.h b/src/modules/websocket/ws_conn.h index e027cf5b42e..7729c00bfd6 100644 --- a/src/modules/websocket/ws_conn.h +++ b/src/modules/websocket/ws_conn.h @@ -31,6 +31,7 @@ #include "../../core/counters.h" #include "../../lib/kmi/tree.h" +#include "../../core/rpc.h" typedef enum { @@ -98,5 +99,5 @@ int wsconn_put(ws_connection_t *wsc); ws_connection_t **wsconn_get_list(void); int wsconn_put_list(ws_connection_t **list); struct mi_root *ws_mi_dump(struct mi_root *cmd, void *param); - +void ws_rpc_close(rpc_t* rpc, void* ctx); #endif /* _WS_CONN_H */ diff --git a/src/modules/websocket/ws_frame.c b/src/modules/websocket/ws_frame.c index 8808aa1be70..5f1257a6363 100644 --- a/src/modules/websocket/ws_frame.c +++ b/src/modules/websocket/ws_frame.c @@ -1089,3 +1089,38 @@ int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con) return ret; } + +/* + * RPC command to set the state of a destination address + */ +void ws_rpc_close(rpc_t* rpc, void* ctx) +{ + unsigned int id; + int ret; + ws_connection_t *wsc; + + if(rpc->scan(ctx, "d", (int*)(&id))<1) + { + LM_WARN("no connection ID parameter\n"); + rpc->fault(ctx, 500, "Invalid Parameters"); + return; + } + + if ((wsc = wsconn_get(id)) == NULL) + { + LM_WARN("bad connection ID parameter\n"); + rpc->fault(ctx, 500, "Unknown connection ID"); + return; + } + + ret = close_connection(&wsc, LOCAL_CLOSE, 1000, str_status_normal_closure); + + wsconn_put(wsc); + + if (ret < 0) + { + LM_WARN("closing connection\n"); + rpc->fault(ctx, 500, str_status_error_closing.s); + return; + } +}