Structured the commands and environment variables
This commit is contained in:
parent
42f4d661a9
commit
67d66e73d2
File diff suppressed because it is too large
Load Diff
|
@ -96,3 +96,5 @@ int call_handle(void);
|
|||
void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg);
|
||||
void telephone_event(call_relation_t *relation, struct telephone_event *te);
|
||||
|
||||
void routing_help(const char *command);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "audio.h"
|
||||
#include "display.h"
|
||||
|
||||
int show_help = 0;
|
||||
int num_kanal = 1;
|
||||
static osmo_cc_endpoint_t *cc_ep1 = NULL, *cc_ep2 = NULL;
|
||||
|
||||
|
@ -85,9 +86,8 @@ static int handle_options(int short_option, int argi, char **argv)
|
|||
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
print_help();
|
||||
return 0;
|
||||
show_help = 1;
|
||||
break;
|
||||
case 'v':
|
||||
if (!strcasecmp(argv[argi], "list")) {
|
||||
debug_list_cat();
|
||||
|
@ -182,6 +182,19 @@ int main(int argc, char *argv[])
|
|||
argi = options_command_line(argc, argv, handle_options);
|
||||
if (argi <= 0)
|
||||
return argi;
|
||||
if (show_help) {
|
||||
if (argi < argc) {
|
||||
routing_help(argv[argi]);
|
||||
return 0;
|
||||
}
|
||||
print_usage(argv[0]);
|
||||
print_help();
|
||||
printf("\n");
|
||||
env_help();
|
||||
printf("\n");
|
||||
routing_help(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init osmo-cc endpoint */
|
||||
cc_ep1 = calloc(1, sizeof(*cc_ep1));
|
||||
|
|
|
@ -34,22 +34,241 @@
|
|||
|
||||
extern char **environ;
|
||||
|
||||
static const char *env_int(const char *name, int value)
|
||||
static struct env {
|
||||
int coding, capability, mode;
|
||||
|
||||
int type, plan, present, screen, reason;
|
||||
char *number;
|
||||
|
||||
int network_type;
|
||||
char *network_id;
|
||||
|
||||
int complete;
|
||||
} env;
|
||||
|
||||
struct env_def {
|
||||
const char *n;
|
||||
char **s;
|
||||
int *i;
|
||||
const char *d;
|
||||
const char *(*value2name)(int value);
|
||||
int num;
|
||||
} env_def[] = {
|
||||
{ .n = "BEARER_CODING", .i = &env.coding, .d = "coding of bearer capability", .value2name = osmo_cc_coding_value2name, .num = OSMO_CC_CODING_NUM },
|
||||
{ .n = "BEARER_CAPABILITY", .i = &env.capability, .d = "bearer capability", .value2name = osmo_cc_capability_value2name, .num = OSMO_CC_CAPABILITY_NUM },
|
||||
{ .n = "BEARER_MODE", .i = &env.mode, .d = "mode of bearer", .value2name = osmo_cc_mode_value2name, .num = OSMO_CC_MODE_NUM },
|
||||
|
||||
{ .n = "CALLING_TYPE", .i = &env.type, .d = "type of calling number", .value2name = osmo_cc_type_value2name, .num = OSMO_CC_TYPE_NUM },
|
||||
{ .n = "CALLING_PLAN", .i = &env.plan, .d = "numbering plan of calling number", .value2name = osmo_cc_plan_value2name, .num = OSMO_CC_PLAN_NUM },
|
||||
{ .n = "CALLING_PRESENT", .i = &env.present, .d = "presentation of calling number", .value2name = osmo_cc_present_value2name, .num = OSMO_CC_PRESENT_NUM },
|
||||
{ .n = "CALLING_SCREEN", .i = &env.screen, .d = "screen of calling number", .value2name = osmo_cc_screen_value2name, .num = OSMO_CC_SCREEN_NUM },
|
||||
{ .n = "CALLING", .s = &env.number, .d = "calling number" },
|
||||
{ .n = "CALLING_INTERFACE", .s = &env.number, .d = "calling interface name" },
|
||||
|
||||
{ .n = "CALLING2_TYPE", .i = &env.type, .d = "type of second calling number", .value2name = osmo_cc_type_value2name, .num = OSMO_CC_TYPE_NUM },
|
||||
{ .n = "CALLING2_PLAN", .i = &env.plan, .d = "numbering plan of awxons calling number", .value2name = osmo_cc_plan_value2name, .num = OSMO_CC_PLAN_NUM},
|
||||
{ .n = "CALLING2_PRESENT", .i = &env.present, .d = "presentation of second calling number", .value2name = osmo_cc_present_value2name, .num = OSMO_CC_PRESENT_NUM },
|
||||
{ .n = "CALLING2_SCREEN", .i = &env.screen, .d = "screen of second calling number", .value2name = osmo_cc_screen_value2name, .num = OSMO_CC_SCREEN_NUM },
|
||||
{ .n = "CALLING2", .s = &env.number, .d = "second calling number" },
|
||||
|
||||
{ .n = "NETWORK_TYPE", .i = &env.network_type, .d = "type of calling network" },
|
||||
{ .n = "NETWORK_ID", .s = &env.network_id, .d = "id of subscriber at calling network" },
|
||||
|
||||
{ .n = "REDIRECTING_TYPE", .i = &env.type, .d = "type of redirecting number", .value2name = osmo_cc_type_value2name, .num = OSMO_CC_TYPE_NUM },
|
||||
{ .n = "REDIRECTING_PLAN", .i = &env.plan, .d = "numbering plan of redirecting number", .value2name = osmo_cc_plan_value2name, .num = OSMO_CC_PLAN_NUM },
|
||||
{ .n = "REDIRECTING_PRESENT", .i = &env.present, .d = "presentation of redirecting number", .value2name = osmo_cc_present_value2name, .num = OSMO_CC_PRESENT_NUM },
|
||||
{ .n = "REDIRECTING_SCREEN", .i = &env.screen, .d = "screen of redirecting number", .value2name = osmo_cc_screen_value2name, .num = OSMO_CC_SCREEN_NUM },
|
||||
{ .n = "REDIRECTING_REASON", .i = &env.reason, .d = "reason for redirecting", .value2name = osmo_cc_redir_reason_value2name, .num = OSMO_CC_REDIR_REASON_NUM },
|
||||
{ .n = "REDIRECTING", .s = &env.number, .d = "redirecting number" },
|
||||
|
||||
{ .n = "DIALING_TYPE", .i = &env.type, .d = "type of dialing number", .value2name = osmo_cc_type_value2name, .num = OSMO_CC_TYPE_NUM },
|
||||
{ .n = "DIALING_PLAN", .i = &env.plan, .d = "numbering plan of dialing number", .value2name = osmo_cc_plan_value2name, .num = OSMO_CC_PLAN_NUM },
|
||||
{ .n = "DIALING", .s = &env.number, .d = "dialing number" },
|
||||
{ .n = "KEYPAD", .s = &env.number, .d = "keypad dialing (May be uses for special ISDN applications.)" },
|
||||
|
||||
{ .n = "COMPLETE", .i = &env.complete, .d = "set to '1' if dialing is a complete number" },
|
||||
|
||||
{ .n = NULL }
|
||||
};
|
||||
|
||||
static int env_set(routing_t *routing, const char *name, int index)
|
||||
{
|
||||
char *string = malloc(strlen(name) + 20);
|
||||
int i;
|
||||
|
||||
sprintf(string, "CC_%s=%d", name, value);
|
||||
for (i = 0; env_def[i].n; i++) {
|
||||
if (!strcmp(env_def[i].n, name))
|
||||
break;
|
||||
}
|
||||
if (!env_def[i].n) {
|
||||
PDEBUG(DROUTER, DEBUG_ERROR, "Software error: Environment variable '%s' does not exist in definition, please fix!\n", name);
|
||||
return index;
|
||||
}
|
||||
|
||||
return string;
|
||||
if (env_def[i].s) {
|
||||
char *string = malloc(strlen(name) + strlen(*env_def[i].s) + 8);
|
||||
sprintf(string, "CC_%s=%s", name, *env_def[i].s);
|
||||
routing->envp[index++] = string;
|
||||
}
|
||||
|
||||
if (env_def[i].i) {
|
||||
char *string = malloc(strlen(name) + 30);
|
||||
sprintf(string, "CC_%s=%d", name, *env_def[i].i);
|
||||
routing->envp[index++] = string;
|
||||
if (env_def[i].value2name && env_def[i].value2name(*env_def[i].i)[0] != '<') {
|
||||
char *string = malloc(strlen(name) + strlen(env_def[i].value2name(*env_def[i].i)) + 16);
|
||||
sprintf(string, "CC_%s_NAME=%s", name, env_def[i].value2name(*env_def[i].i));
|
||||
routing->envp[index++] = string;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static const char *env_string(const char *name, const char *value)
|
||||
static void env_add(routing_t *routing, const char *name)
|
||||
{
|
||||
char *string = malloc(strlen(name) + strlen(value) + 8);
|
||||
routing->envc = env_set(routing, name, routing->envc);
|
||||
}
|
||||
|
||||
sprintf(string, "CC_%s=%s", name, value);
|
||||
void env_help(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
return string;
|
||||
printf("Available environment variables:\n\n");
|
||||
for (i = 0; env_def[i].n; i++) {
|
||||
printf("Variable: CC_%s\n", env_def[i].n);
|
||||
printf(" Description: %s\n", env_def[i].d);
|
||||
if (env_def[i].value2name) {
|
||||
printf(" Additional variable: CC_%s_NAME\n", env_def[i].n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare environment with setup info */
|
||||
void routing_env_msg(routing_t *routing, osmo_cc_msg_t *msg)
|
||||
{
|
||||
int rc, i;
|
||||
uint8_t coding, capability, mode;
|
||||
uint8_t type, plan, present, screen, reason;
|
||||
char number[256];
|
||||
uint8_t network_type;
|
||||
char network_id[256];
|
||||
|
||||
for (i = 0; environ[i]; i++) {
|
||||
routing->envp[routing->envc++] = strdup(environ[i]);
|
||||
}
|
||||
|
||||
memset(&env, 0, sizeof(env));
|
||||
|
||||
rc = osmo_cc_get_ie_bearer(msg, 0, &coding, &capability, &mode);
|
||||
if (rc >= 0) {
|
||||
env.coding = coding;
|
||||
env.capability = capability;
|
||||
env.mode = mode;
|
||||
env_add(routing, "BEARER_CODING");
|
||||
env_add(routing, "BEARER_CAPABILITY");
|
||||
env_add(routing, "BEARER_MODE");
|
||||
}
|
||||
|
||||
rc = osmo_cc_get_ie_calling(msg, 0, &type, &plan, &present, &screen, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
env.type = type;
|
||||
env.plan = plan;
|
||||
env.present = present;
|
||||
env.screen = screen;
|
||||
env.number = number;
|
||||
env_add(routing, "CALLING_TYPE");
|
||||
env_add(routing, "CALLING_PLAN");
|
||||
env_add(routing, "CALLING_PRESENT");
|
||||
env_add(routing, "CALLING_SCREEN");
|
||||
env_add(routing, "CALLING");
|
||||
}
|
||||
rc = osmo_cc_get_ie_calling_interface(msg, 0, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
env.number = number;
|
||||
env_add(routing, "CALLING_INTERFACE");
|
||||
}
|
||||
|
||||
rc = osmo_cc_get_ie_calling(msg, 1, &type, &plan, &present, &screen, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
env.type = type;
|
||||
env.plan = plan;
|
||||
env.present = present;
|
||||
env.screen = screen;
|
||||
env.number = number;
|
||||
env_add(routing, "CALLING2_TYPE");
|
||||
env_add(routing, "CALLING2_PLAN");
|
||||
env_add(routing, "CALLING2_PRESENT");
|
||||
env_add(routing, "CALLING2_SCREEN");
|
||||
env_add(routing, "CALLING2");
|
||||
}
|
||||
rc = osmo_cc_get_ie_calling_network(msg, 0, &network_type, network_id, sizeof(network_id));
|
||||
if (rc >= 0) {
|
||||
env.network_type = network_type;
|
||||
env.network_id = network_id;
|
||||
env_add(routing, "NETWORK_TYPE");
|
||||
env_add(routing, "NETWORK_ID");
|
||||
}
|
||||
rc = osmo_cc_get_ie_redir(msg, 0, &type, &plan, &present, &screen, &reason, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
env.type = type;
|
||||
env.plan = plan;
|
||||
env.present = present;
|
||||
env.screen = screen;
|
||||
env.reason = reason;
|
||||
env.number = number;
|
||||
env_add(routing, "REDIRECTING_TYPE");
|
||||
env_add(routing, "REDIRECTING_PLAN");
|
||||
env_add(routing, "REDIRECTING_PRESENT");
|
||||
env_add(routing, "REDIRECTING_SCREEN");
|
||||
env_add(routing, "REDIRECTING_REASON");
|
||||
env_add(routing, "REDIRECTING");
|
||||
}
|
||||
|
||||
rc = osmo_cc_get_ie_called(msg, 0, &type, &plan, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
env.type = type;
|
||||
env.plan = plan;
|
||||
env_add(routing, "DIALING_TYPE");
|
||||
env_add(routing, "DIALING_PLAN");
|
||||
} else
|
||||
number[0] = 0;
|
||||
/* variable must always be present, so it can be updated when overlap dialing */
|
||||
routing->envc_dialing = routing->envc;
|
||||
env.number = number;
|
||||
env_add(routing, "DIALING");
|
||||
|
||||
rc = osmo_cc_get_ie_keypad(msg, 0, number, sizeof(number));
|
||||
if (rc < 0)
|
||||
number[0] = 0;
|
||||
/* variable must always be present, so it can be updated when overlap dialing */
|
||||
routing->envc_keypad = routing->envc;
|
||||
env.number = number;
|
||||
env_add(routing, "KEYPAD");
|
||||
|
||||
rc = osmo_cc_get_ie_complete(msg, 0);
|
||||
if (rc >= 0)
|
||||
env.complete = 1;
|
||||
/* variable must always be present, so it can be updated when overlap dialing */
|
||||
routing->envc_complete = routing->envc;
|
||||
env_add(routing, "COMPLETE");
|
||||
|
||||
routing->envp[routing->envc++] = NULL;
|
||||
}
|
||||
|
||||
/* update environment with info message */
|
||||
void routing_env_dialing(routing_t *routing, char *number, char *keypad, int complete)
|
||||
{
|
||||
free((char *)routing->envp[routing->envc_dialing]);
|
||||
env.number = number;
|
||||
env_set(routing, "DIALING", routing->envc_dialing);
|
||||
|
||||
free((char *)routing->envp[routing->envc_keypad]);
|
||||
env.number = keypad;
|
||||
env_set(routing, "KEYPAD", routing->envc_keypad);
|
||||
|
||||
free((char *)routing->envp[routing->envc_complete]);
|
||||
env.complete = complete;
|
||||
env_set(routing, "COMPLETE", routing->envc_complete);
|
||||
}
|
||||
|
||||
static void enqueue_string(struct string_queue **queue_p, const char *string, const char *suffix)
|
||||
|
@ -81,96 +300,6 @@ static char *dequeue_string(struct string_queue **queue_p)
|
|||
return string;
|
||||
}
|
||||
|
||||
/* prepare environment with setup info */
|
||||
void routing_env_msg(routing_t *routing, osmo_cc_msg_t *msg)
|
||||
{
|
||||
uint8_t coding, capability, mode;
|
||||
uint8_t type, plan, present, screen, reason;
|
||||
uint8_t network_type;
|
||||
char number[256], network_id[256];
|
||||
int rc, i;
|
||||
|
||||
for (i = 0; environ[i]; i++) {
|
||||
routing->envp[routing->envc++] = strdup(environ[i]);
|
||||
}
|
||||
|
||||
rc = osmo_cc_get_ie_bearer(msg, 0, &coding, &capability, &mode);
|
||||
if (rc >= 0) {
|
||||
routing->envp[routing->envc++] = env_int("BEARER_CODING", coding);
|
||||
routing->envp[routing->envc++] = env_int("BEARER_CAPABILITY", capability);
|
||||
routing->envp[routing->envc++] = env_int("BEARER_MODE", mode);
|
||||
}
|
||||
|
||||
rc = osmo_cc_get_ie_calling(msg, 0, &type, &plan, &present, &screen, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
routing->envp[routing->envc++] = env_int("CALLING_TYPE", type);
|
||||
routing->envp[routing->envc++] = env_int("CALLING_PLAN", plan);
|
||||
routing->envp[routing->envc++] = env_int("CALLING_PRESENT", present);
|
||||
routing->envp[routing->envc++] = env_int("CALLING_SCREEN", screen);
|
||||
routing->envp[routing->envc++] = env_string("CALLING", number);
|
||||
}
|
||||
rc = osmo_cc_get_ie_calling_interface(msg, 0, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
routing->envp[routing->envc++] = env_string("CALLING_INTERFACE", number);
|
||||
}
|
||||
|
||||
rc = osmo_cc_get_ie_calling(msg, 1, &type, &plan, &present, &screen, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
routing->envp[routing->envc++] = env_int("CALLING2_TYPE", type);
|
||||
routing->envp[routing->envc++] = env_int("CALLING2_PLAN", plan);
|
||||
routing->envp[routing->envc++] = env_int("CALLING2_PRESENT", present);
|
||||
routing->envp[routing->envc++] = env_int("CALLING2_SCREEN", screen);
|
||||
routing->envp[routing->envc++] = env_string("CALLING2", number);
|
||||
}
|
||||
rc = osmo_cc_get_ie_calling_network(msg, 0, &network_type, network_id, sizeof(network_id));
|
||||
if (rc >= 0) {
|
||||
routing->envp[routing->envc++] = env_string("NETWORK_TYPE", osmo_cc_network_type_name(network_type));
|
||||
routing->envp[routing->envc++] = env_string("NETWORK_ID", network_id);
|
||||
}
|
||||
rc = osmo_cc_get_ie_redir(msg, 0, &type, &plan, &present, &screen, &reason, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
routing->envp[routing->envc++] = env_int("REDIRECTING_TYPE", type);
|
||||
routing->envp[routing->envc++] = env_int("REDIRECTING_PLAN", plan);
|
||||
routing->envp[routing->envc++] = env_int("REDIRECTING_PRESENT", present);
|
||||
routing->envp[routing->envc++] = env_int("REDIRECTING_SCREEN", screen);
|
||||
routing->envp[routing->envc++] = env_int("REDIRECTING_REASON", reason);
|
||||
routing->envp[routing->envc++] = env_string("REDIRECTING", number);
|
||||
}
|
||||
|
||||
rc = osmo_cc_get_ie_called(msg, 0, &type, &plan, number, sizeof(number));
|
||||
if (rc >= 0) {
|
||||
routing->envp[routing->envc++] = env_int("DIALING_TYPE", type);
|
||||
routing->envp[routing->envc++] = env_int("DIALING_PLAN", plan);
|
||||
} else
|
||||
number[0] = 0;
|
||||
/* variable must always be present, so it can be updated when overlap dialing */
|
||||
routing->envc_dialing = routing->envc;
|
||||
routing->envp[routing->envc++] = env_string("DIALING", number);
|
||||
|
||||
rc = osmo_cc_get_ie_keypad(msg, 0, number, sizeof(number));
|
||||
if (rc < 0)
|
||||
number[0] = 0;
|
||||
/* variable must always be present, so it can be updated when overlap dialing */
|
||||
routing->envc_keypad = routing->envc;
|
||||
routing->envp[routing->envc++] = env_string("KEYPAD", number);
|
||||
|
||||
rc = osmo_cc_get_ie_complete(msg, 0);
|
||||
if (rc >= 0)
|
||||
routing->envp[routing->envc++] = env_int("COMPLETE", 1);
|
||||
|
||||
routing->envp[routing->envc++] = NULL;
|
||||
}
|
||||
|
||||
/* update environment with info message */
|
||||
void routing_env_dialing(routing_t *routing, const char *number, const char *keypad)
|
||||
{
|
||||
free((char *)routing->envp[routing->envc_dialing]);
|
||||
routing->envp[routing->envc_dialing] = env_string("DIALING", number);
|
||||
|
||||
free((char *)routing->envp[routing->envc_keypad]);
|
||||
routing->envp[routing->envc_keypad] = env_string("KEYPAD", keypad);
|
||||
}
|
||||
|
||||
void routing_env_free(routing_t *routing)
|
||||
{
|
||||
/* remove env */
|
||||
|
|
|
@ -15,6 +15,7 @@ typedef struct routing {
|
|||
const char *envp[256]; /* environment variables */
|
||||
int envc_dialing; /* envc index for dialing number */
|
||||
int envc_keypad; /* envc index for keypad */
|
||||
int envc_complete; /* envc index for complete */
|
||||
|
||||
pid_t script_pid; /* pid of routing script */
|
||||
int script_stdin; /* pipe to stdin */
|
||||
|
@ -32,8 +33,9 @@ typedef struct routing {
|
|||
struct string_queue *stderr_queue; /* strings read from script */
|
||||
} routing_t;
|
||||
|
||||
void env_help(void);
|
||||
void routing_env_msg(routing_t *routing, osmo_cc_msg_t *msg);
|
||||
void routing_env_dialing(routing_t *routing, const char *number, const char *keypad);
|
||||
void routing_env_dialing(routing_t *routing, char *number, char *keypad, int complete);
|
||||
void routing_env_free(routing_t *routing);
|
||||
void routing_start(routing_t *routing, const char *script, const char *shell);
|
||||
void routing_stop(routing_t *routing);
|
||||
|
|
Loading…
Reference in New Issue