static int create_test_dialplan(void) { int res = 0; test_message_context = ast_context_find_or_create(NULL, NULL, TEST_CONTEXT, AST_MODULE); if (!test_message_context) { return -1; } res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 1, NULL, NULL, "UserEvent", "TestMessageUnitTest,Verify:To,Value:${MESSAGE(to)}", NULL, AST_MODULE); res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 2, NULL, NULL, "UserEvent", "TestMessageUnitTest,Verify:From,Value:${MESSAGE(from)}", NULL, AST_MODULE); res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 3, NULL, NULL, "UserEvent", "TestMessageUnitTest,Verify:Body,Value:${MESSAGE(body)}", NULL, AST_MODULE); res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 4, NULL, NULL, "UserEvent", "TestMessageUnitTest,Verify:Custom,Value:${MESSAGE_DATA(custom_data)}", NULL, AST_MODULE); res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 5, NULL, NULL, "Set", "MESSAGE_DATA(custom_data)=${MESSAGE_DATA(custom_data)}", NULL, AST_MODULE); res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 6, NULL, NULL, "MessageSend", "testmsg:${MESSAGE(from)},testmsg:${MESSAGE(to)}", NULL, AST_MODULE); ast_manager_register_hook(&user_event_hook); return res; }
struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *data, enum stasis_app_subscription_model subscription_model) { RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup); size_t size; int res = 0; size_t context_size = strlen("stasis-") + strlen(name) + 1; char context_name[context_size]; ast_assert(name != NULL); ast_assert(handler != NULL); ast_verb(1, "Creating Stasis app '%s'\n", name); size = sizeof(*app) + strlen(name) + 1; app = ao2_alloc_options(size, app_dtor, AO2_ALLOC_OPT_LOCK_MUTEX); if (!app) { return NULL; } app->subscription_model = subscription_model; app->forwards = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX, AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT, forwards_sort, NULL); if (!app->forwards) { return NULL; } app->topic = stasis_topic_create(name); if (!app->topic) { return NULL; } app->bridge_router = stasis_message_router_create(ast_bridge_topic_all()); if (!app->bridge_router) { return NULL; } res |= stasis_message_router_add(app->bridge_router, ast_bridge_merge_message_type(), bridge_merge_handler, app); res |= stasis_message_router_add(app->bridge_router, ast_blind_transfer_type(), bridge_blind_transfer_handler, app); res |= stasis_message_router_add(app->bridge_router, ast_attended_transfer_type(), bridge_attended_transfer_handler, app); res |= stasis_message_router_add(app->bridge_router, stasis_subscription_change_type(), bridge_subscription_change_handler, app); if (res != 0) { return NULL; } /* Bridge router holds a reference */ ao2_ref(app, +1); app->router = stasis_message_router_create(app->topic); if (!app->router) { return NULL; } res |= stasis_message_router_add(app->router, ast_bridge_snapshot_type(), sub_bridge_update_handler, app); res |= stasis_message_router_add(app->router, ast_channel_snapshot_type(), sub_channel_update_handler, app); res |= stasis_message_router_add_cache_update(app->router, ast_endpoint_snapshot_type(), sub_endpoint_update_handler, app); res |= stasis_message_router_add(app->router, stasis_subscription_change_type(), sub_subscription_change_handler, app); stasis_message_router_set_formatters_default(app->router, sub_default_handler, app, STASIS_SUBSCRIPTION_FORMATTER_JSON); if (res != 0) { return NULL; } /* Router holds a reference */ ao2_ref(app, +1); strncpy(app->name, name, size - sizeof(*app)); app->handler = handler; app->data = ao2_bump(data); /* Create a context, a match-all extension, and a 'h' extension for this application. Note that * this should only be done if a context does not already exist. */ strcpy(context_name, "stasis-"); strcat(context_name, name); if (!ast_context_find(context_name)) { if (!ast_context_find_or_create(NULL, NULL, context_name, "res_stasis")) { ast_log(LOG_WARNING, "Could not create context '%s' for Stasis application '%s'\n", context_name, name); } else { ast_add_extension(context_name, 0, "_.", 1, NULL, NULL, "Stasis", ast_strdup(name), ast_free_ptr, "res_stasis"); ast_add_extension(context_name, 0, "h", 1, NULL, NULL, "NoOp", NULL, NULL, "res_stasis"); } } else { ast_log(LOG_WARNING, "Not creating context '%s' for Stasis application '%s' because it already exists\n", context_name, name); } ao2_ref(app, +1); return app; }
/* * ADD EXTENSION command stuff */ static int handle_context_add_extension(int fd, int argc, char *argv[]) { char *whole_exten; char *exten, *prior; int iprior = -2; char *cidmatch, *app, *app_data; char *start, *end; /* check for arguments at first */ if (argc != 5 && argc != 6) return RESULT_SHOWUSAGE; if (strcmp(argv[3], "into")) return RESULT_SHOWUSAGE; if (argc == 6) if (strcmp(argv[5], "replace")) return RESULT_SHOWUSAGE; whole_exten = argv[2]; exten = strsep(&whole_exten,","); if (strchr(exten, '/')) { cidmatch = exten; strsep(&cidmatch,"/"); } else { cidmatch = NULL; } prior = strsep(&whole_exten,","); if (prior) { if (!strcmp(prior, "hint")) { iprior = PRIORITY_HINT; } else { if (sscanf(prior, "%i", &iprior) != 1) { ast_cli(fd, "'%s' is not a valid priority\n", prior); prior = NULL; } } } app = whole_exten; if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) { *start = *end = '\0'; app_data = start + 1; process_quotes_and_slashes(app_data, ',', '|'); } else { if (app) { app_data = strchr(app, ','); if (app_data) { *app_data = '\0'; app_data++; } } else app_data = NULL; } if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT)) return RESULT_SHOWUSAGE; if (!app_data) app_data=""; if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, cidmatch, app, (void *)strdup(app_data), free, registrar)) { switch (errno) { case ENOMEM: ast_cli(fd, "Out of free memory\n"); break; case EBUSY: ast_cli(fd, "Failed to lock context(s) list, please try again later\n"); break; case ENOENT: ast_cli(fd, "No existence of '%s' context\n", argv[4]); break; case EEXIST: ast_cli(fd, "Extension %s@%s with priority %s already exists\n", exten, argv[4], prior); break; default: ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n", exten, prior, app, app_data, argv[4]); break; } return RESULT_FAILURE; } if (argc == 6) ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n", exten, argv[4], prior, exten, prior, app, app_data); else ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n", exten, prior, app, app_data, argv[4]); return RESULT_SUCCESS; }