mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-17 01:02:12 +00:00
Add mod_megaco skeleton with basic profile support and a lot of todos for Kapil
This commit is contained in:
parent
67c43a0759
commit
6a32e98c49
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# install - install a program, script, or datafile
|
# install - install a program, script, or datafile
|
||||||
|
|
||||||
scriptversion=2009-04-28.21; # UTC
|
scriptversion=2011-01-19.21; # UTC
|
||||||
|
|
||||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
@ -156,6 +156,10 @@ while test $# -ne 0; do
|
|||||||
-s) stripcmd=$stripprog;;
|
-s) stripcmd=$stripprog;;
|
||||||
|
|
||||||
-t) dst_arg=$2
|
-t) dst_arg=$2
|
||||||
|
# Protect names problematic for `test' and other utilities.
|
||||||
|
case $dst_arg in
|
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||||
|
esac
|
||||||
shift;;
|
shift;;
|
||||||
|
|
||||||
-T) no_target_directory=true;;
|
-T) no_target_directory=true;;
|
||||||
@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
|||||||
fi
|
fi
|
||||||
shift # arg
|
shift # arg
|
||||||
dst_arg=$arg
|
dst_arg=$arg
|
||||||
|
# Protect names problematic for `test' and other utilities.
|
||||||
|
case $dst_arg in
|
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -200,7 +208,11 @@ if test $# -eq 0; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test -z "$dir_arg"; then
|
if test -z "$dir_arg"; then
|
||||||
trap '(exit $?); exit' 1 2 13 15
|
do_exit='(exit $ret); exit $ret'
|
||||||
|
trap "ret=129; $do_exit" 1
|
||||||
|
trap "ret=130; $do_exit" 2
|
||||||
|
trap "ret=141; $do_exit" 13
|
||||||
|
trap "ret=143; $do_exit" 15
|
||||||
|
|
||||||
# Set umask so as not to create temps with too-generous modes.
|
# Set umask so as not to create temps with too-generous modes.
|
||||||
# However, 'strip' requires both read and write access to temps.
|
# However, 'strip' requires both read and write access to temps.
|
||||||
@ -228,9 +240,9 @@ fi
|
|||||||
|
|
||||||
for src
|
for src
|
||||||
do
|
do
|
||||||
# Protect names starting with `-'.
|
# Protect names problematic for `test' and other utilities.
|
||||||
case $src in
|
case $src in
|
||||||
-*) src=./$src;;
|
-* | [=\(\)!]) src=./$src;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if test -n "$dir_arg"; then
|
if test -n "$dir_arg"; then
|
||||||
@ -252,12 +264,7 @@ do
|
|||||||
echo "$0: no destination specified." >&2
|
echo "$0: no destination specified." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dst=$dst_arg
|
dst=$dst_arg
|
||||||
# Protect names starting with `-'.
|
|
||||||
case $dst in
|
|
||||||
-*) dst=./$dst;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# If destination is a directory, append the input filename; won't work
|
# If destination is a directory, append the input filename; won't work
|
||||||
# if double slashes aren't ignored.
|
# if double slashes aren't ignored.
|
||||||
@ -385,7 +392,7 @@ do
|
|||||||
|
|
||||||
case $dstdir in
|
case $dstdir in
|
||||||
/*) prefix='/';;
|
/*) prefix='/';;
|
||||||
-*) prefix='./';;
|
[-=\(\)!]*) prefix='./';;
|
||||||
*) prefix='';;
|
*) prefix='';;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@ -403,7 +410,7 @@ do
|
|||||||
|
|
||||||
for d
|
for d
|
||||||
do
|
do
|
||||||
test -z "$d" && continue
|
test X"$d" = X && continue
|
||||||
|
|
||||||
prefix=$prefix$d
|
prefix=$prefix$d
|
||||||
if test -d "$prefix"; then
|
if test -d "$prefix"; then
|
||||||
|
@ -773,7 +773,8 @@ typedef gid_t switch_gid_t;
|
|||||||
typedef ino_t switch_ino_t;
|
typedef ino_t switch_ino_t;
|
||||||
typedef dev_t switch_dev_t;
|
typedef dev_t switch_dev_t;
|
||||||
#endif
|
#endif
|
||||||
typedef off64_t switch_off_t;
|
|
||||||
|
typedef off_t switch_off_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure for referencing file information
|
* Structure for referencing file information
|
||||||
|
3
src/mod/endpoints/mod_megaco/Makefile
Normal file
3
src/mod/endpoints/mod_megaco/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
BASE=../../../..
|
||||||
|
LOCAL_OBJS=megaco.o
|
||||||
|
include $(BASE)/build/modmake.rules
|
132
src/mod/endpoints/mod_megaco/megaco.c
Normal file
132
src/mod/endpoints/mod_megaco/megaco.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Sangoma Technologies
|
||||||
|
* Mathieu Rene <mrene@avgs.ca>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* <Insert license here>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mod_megaco.h"
|
||||||
|
|
||||||
|
megaco_profile_t *megaco_profile_locate(const char *name)
|
||||||
|
{
|
||||||
|
megaco_profile_t *profile = switch_core_hash_find_rdlock(megaco_globals.profile_hash, name, megaco_globals.profile_rwlock);
|
||||||
|
|
||||||
|
if (profile) {
|
||||||
|
if (switch_thread_rwlock_tryrdlock(profile->rwlock) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile %s is locked\n", name);
|
||||||
|
profile = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void megaco_profile_release(megaco_profile_t *profile)
|
||||||
|
{
|
||||||
|
switch_thread_rwlock_unlock(profile->rwlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
|
||||||
|
{
|
||||||
|
switch_xml_t cfg, xml, x_profiles, x_profile, x_settings;
|
||||||
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
|
switch_event_t *event = NULL;
|
||||||
|
int count;
|
||||||
|
const char *file = "megaco.conf";
|
||||||
|
|
||||||
|
if (!(xml = switch_xml_open_cfg(file, &cfg, NULL))) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open %s\n", file);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x_profile = switch_xml_child(x_profiles, "profile"); x_profile; x_profile = x_profile->next) {
|
||||||
|
const char *name = switch_xml_attr_soft(x_profile, "name");
|
||||||
|
if (strcmp(name, profile->name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(x_settings = switch_xml_child(x_profile, "settings"))) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
count = switch_event_import_xml(switch_xml_child(x_settings, "param"), "name", "value", &event);
|
||||||
|
// status = switch_xml_config_parse_event(event, count, reload, instructions);
|
||||||
|
|
||||||
|
/* TODO: Initialize stack configuration */
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (xml) {
|
||||||
|
switch_xml_free(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
switch_event_destroy(&event);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_status_t megaco_profile_start(const char *profilename)
|
||||||
|
{
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
megaco_profile_t *profile;
|
||||||
|
|
||||||
|
switch_assert(profilename);
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting profile: %s\n", profilename);
|
||||||
|
|
||||||
|
switch_core_new_memory_pool(&pool);
|
||||||
|
profile = switch_core_alloc(pool, sizeof(*profile));
|
||||||
|
profile->pool = pool;
|
||||||
|
profile->name = switch_core_strdup(pool, profilename);
|
||||||
|
|
||||||
|
switch_thread_rwlock_create(&profile->rwlock, pool);
|
||||||
|
|
||||||
|
/* TODO: Kapil: Insert stack per-interface startup code here */
|
||||||
|
|
||||||
|
switch_core_hash_insert_wrlock(megaco_globals.profile_hash, profile->name, profile, megaco_globals.profile_rwlock);
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started profile: %s\n", profile->name);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
fail:
|
||||||
|
switch_core_destroy_memory_pool(&pool);
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch_status_t megaco_profile_destroy(megaco_profile_t **profile)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stopping profile: %s\n", (*profile)->name);
|
||||||
|
switch_thread_rwlock_wrlock((*profile)->rwlock);
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Kapil: Insert stack per-interface shutdown code here */
|
||||||
|
|
||||||
|
|
||||||
|
switch_thread_rwlock_unlock((*profile)->rwlock);
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stopped profile: %s\n", (*profile)->name);
|
||||||
|
switch_core_hash_delete_wrlock(megaco_globals.profile_hash, (*profile)->name, megaco_globals.profile_rwlock);
|
||||||
|
|
||||||
|
switch_core_destroy_memory_pool(&(*profile)->pool);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||||
|
*/
|
141
src/mod/endpoints/mod_megaco/mod_megaco.c
Normal file
141
src/mod/endpoints/mod_megaco/mod_megaco.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Sangoma Technologies
|
||||||
|
* Mathieu Rene <mrene@avgs.ca>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* <Insert license here>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mod_megaco.h"
|
||||||
|
|
||||||
|
struct megaco_globals megaco_globals;
|
||||||
|
|
||||||
|
SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load);
|
||||||
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown);
|
||||||
|
SWITCH_MODULE_DEFINITION(mod_megaco, mod_megaco_load, mod_megaco_shutdown, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
#define MEGACO_FUNCTION_SYNTAX "profile [name] [start | stop]"
|
||||||
|
SWITCH_STANDARD_API(megaco_function)
|
||||||
|
{
|
||||||
|
int argc;
|
||||||
|
char *argv[10];
|
||||||
|
char *dup = NULL;
|
||||||
|
|
||||||
|
if (zstr(cmd)) {
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
dup = strdup(cmd);
|
||||||
|
argc = switch_split(dup, ' ', argv);
|
||||||
|
|
||||||
|
if (argc < 1 || zstr(argv[0])) {
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[0], "profile")) {
|
||||||
|
if (zstr(argv[1]) || zstr(argv[2])) {
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[2], "start")) {
|
||||||
|
megaco_profile_t *profile = megaco_profile_locate(argv[1]);
|
||||||
|
if (profile) {
|
||||||
|
megaco_profile_release(profile);
|
||||||
|
stream->write_function(stream, "-ERR Profile %s is already started\n", argv[2]);
|
||||||
|
} else {
|
||||||
|
megaco_profile_start(argv[1]);
|
||||||
|
stream->write_function(stream, "+OK\n");
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[2], "stop")) {
|
||||||
|
megaco_profile_t *profile = megaco_profile_locate(argv[1]);
|
||||||
|
if (profile) {
|
||||||
|
megaco_profile_release(profile);
|
||||||
|
megaco_profile_destroy(&profile);
|
||||||
|
stream->write_function(stream, "+OK\n");
|
||||||
|
} else {
|
||||||
|
stream->write_function(stream, "-ERR No such profile\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
stream->write_function(stream, "-ERR Usage: "MEGACO_FUNCTION_SYNTAX"\n");
|
||||||
|
|
||||||
|
done:
|
||||||
|
switch_safe_free(dup);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static switch_status_t console_complete_hashtable(switch_hash_t *hash, const char *line, const char *cursor, switch_console_callback_match_t **matches)
|
||||||
|
{
|
||||||
|
switch_hash_index_t *hi;
|
||||||
|
void *val;
|
||||||
|
const void *vvar;
|
||||||
|
switch_console_callback_match_t *my_matches = NULL;
|
||||||
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
|
|
||||||
|
for (hi = switch_hash_first(NULL, hash); hi; hi = switch_hash_next(hi)) {
|
||||||
|
switch_hash_this(hi, &vvar, NULL, &val);
|
||||||
|
switch_console_push_match(&my_matches, (const char *) vvar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (my_matches) {
|
||||||
|
*matches = my_matches;
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches)
|
||||||
|
{
|
||||||
|
switch_status_t status;
|
||||||
|
switch_thread_rwlock_rdlock(megaco_globals.profile_rwlock);
|
||||||
|
status = console_complete_hashtable(megaco_globals.profile_hash, line, cursor, matches);
|
||||||
|
switch_thread_rwlock_unlock(megaco_globals.profile_rwlock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load)
|
||||||
|
{
|
||||||
|
switch_api_interface_t *api_interface;
|
||||||
|
|
||||||
|
memset(&megaco_globals, 0, sizeof(megaco_globals));
|
||||||
|
megaco_globals.pool = pool;
|
||||||
|
|
||||||
|
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||||
|
|
||||||
|
switch_core_hash_init(&megaco_globals.profile_hash, pool);
|
||||||
|
switch_thread_rwlock_create(&megaco_globals.profile_rwlock, pool);
|
||||||
|
|
||||||
|
SWITCH_ADD_API(api_interface, "megaco", "megaco", megaco_function, MEGACO_FUNCTION_SYNTAX);
|
||||||
|
|
||||||
|
switch_console_set_complete("add megaco profile ::megaco::list_profiles start");
|
||||||
|
switch_console_set_complete("add megaco profile ::megaco::list_profiles stop");
|
||||||
|
switch_console_add_complete_func("::megaco::list_profiles", list_profiles);
|
||||||
|
|
||||||
|
/* TODO: Kapil: Insert stack global startup code here */
|
||||||
|
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown)
|
||||||
|
{
|
||||||
|
/* TODO: Kapil: Insert stack global shutdown code here */
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||||
|
*/
|
56
src/mod/endpoints/mod_megaco/mod_megaco.h
Normal file
56
src/mod/endpoints/mod_megaco/mod_megaco.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Sangoma Technologies
|
||||||
|
* Mathieu Rene <mrene@avgs.ca>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* <Insert license here>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MOD_MEGACO_H
|
||||||
|
#define MOD_MEGACO_H
|
||||||
|
|
||||||
|
#include <switch.h>
|
||||||
|
|
||||||
|
struct megaco_globals {
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
switch_hash_t *profile_hash;
|
||||||
|
switch_thread_rwlock_t *profile_rwlock;
|
||||||
|
/* TODO: Kapil: add global variables here */
|
||||||
|
};
|
||||||
|
extern struct megaco_globals megaco_globals; /* < defined in mod_megaco.c */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PF_RUNNING = (1 << 0)
|
||||||
|
} megaco_profile_flags_t;
|
||||||
|
|
||||||
|
typedef struct megaco_profile_s {
|
||||||
|
char *name;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
switch_thread_rwlock_t *rwlock; /* < Reference counting rwlock */
|
||||||
|
megaco_profile_flags_t flags;
|
||||||
|
|
||||||
|
/* TODO: Kapil: Insert interface-specific stack elements here */
|
||||||
|
} megaco_profile_t;
|
||||||
|
|
||||||
|
|
||||||
|
megaco_profile_t *megaco_profile_locate(const char *name);
|
||||||
|
void megaco_profile_release(megaco_profile_t *profile);
|
||||||
|
|
||||||
|
switch_status_t megaco_profile_start(const char *profilename);
|
||||||
|
switch_status_t megaco_profile_destroy(megaco_profile_t **profile);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MOD_MEGACO_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||||
|
*/
|
Loading…
x
Reference in New Issue
Block a user