/** * @brief Record action entry point * * Record action will start MixMonitor on given channel and will * set some variables for record post processing (in h extension). * * @param sess Session rnuning this application * @param app The application structure * @param args Hangup action args "ActionID" and "UniqueID" * @return 0 if the call is found, -1 otherwise */ int record_exec(session_t *sess, app_t *app, const char *args) { struct app_call_info *info; char actionid[ACTIONID_LEN]; char filename[128]; time_t timer; char timestr[25]; struct tm* tm_info; // This can only be done after authentication if (!session_test_flag(sess, SESS_FLAG_AUTHENTICATED)) { return NOT_AUTHENTICATED; } // Get Hangup parameteres if (sscanf(args, "%s %s", actionid, filename) != 2) { return INVALID_ARGUMENTS; } // Try to find the action info of the given actionid if ((info = get_call_info_from_id(sess, actionid)) && !isaac_strlen_zero(info->ochannel)) { // Check if this call is already being recorded if (info->recording) { session_write(sess, "RECORDFAILED CALL IS ALREADY BEING RECORDED\r\n"); return -1; } ami_message_t msg; memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: MixMonitor"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "File: %s/%s.wav", call_config.record_path, filename); manager_write_message(manager, &msg); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_MODULO", info->ouid); message_add_header(&msg, "Value: %sCC", info->grabaciones_modulo); manager_write_message(manager, &msg); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_PLATAFORMA", info->ouid); message_add_header(&msg, "Value: %s", info->grabaciones_plataforma); manager_write_message(manager, &msg); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_TIPO", info->ouid); message_add_header(&msg, "Value: %son-demand_ISAAC", info->grabaciones_tipo); manager_write_message(manager, &msg); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_ORIGEN", info->ouid); message_add_header(&msg, "Value: %s%s",info->grabaciones_origen,session_get_variable(sess, "AGENT")); manager_write_message(manager, &msg); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_DESTINO", info->ouid); message_add_header(&msg, "Value: %s%s",info->grabaciones_destino, info->destiny); manager_write_message(manager, &msg); time(&timer); tm_info = localtime(&timer); strftime(timestr, 25, "%Y:%m:%d_%H:%M:%S", tm_info); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_FECHA_HORA", info->ouid); message_add_header(&msg, "Value: %s%s", info->grabaciones_fecha_hora, timestr); manager_write_message(manager, &msg); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_RUTA", info->ouid); message_add_header(&msg, "Value: %s%s", info->grabaciones_ruta, call_config.record_path); manager_write_message(manager, &msg); memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Setvar"); message_add_header(&msg, "Channel: %s", info->ochannel); message_add_header(&msg, "Variable: GRABACIONES_%s_FICHERO", info->ouid); message_add_header(&msg, "Value: %s%s.wav", info->grabaciones_fichero, filename); manager_write_message(manager, &msg); // Flag this call as being recorded info->recording = true; session_write(sess, "RECORDOK\r\n"); } else { session_write(sess, "RECORDFAILED ID NOT FOUND\r\n"); return -1; } return 0; }
/* * xsession_get_session_variable () - get the value of a session variable * return : int * thread_p (in) : worker thread * name (in) : name of the variable * value (out) : variable value */ int xsession_get_session_variable (THREAD_ENTRY * thread_p, const DB_VALUE * name, DB_VALUE * value) { return session_get_variable (thread_p, name, value); }
/** * @brief CALL action entry point * * Originates a call with the given action id on current session.\n * This function will generate a call using Originate AMI command and add * a filter for capturing generated channel.\n The first leg of the call (going * to the registered session agent) will be sent to the configured incoming context * (@ref app_call_config::incontext) that is expected to make a Dial to the configured * outgoing context (@ref app_call_config::outcontext).\n * * - CALL action requires that session is authenticated (usually through * LOGIN action).\n * - CALL action receives two arguments: An unique actionid that can be used * to make other actions with the generated call (such as Hanguping or sending * DTMF codes) and the number that is wanted to call.\n * * @param sess Session rnuning this application * @param app The application structure * @param args Call action args "ActionID DestNum" * @return 0 in call cases */ int call_exec(session_t *sess, app_t *app, const char *args) { char actionid[ACTIONID_LEN]; char exten[128], options[80]; if (!session_test_flag(sess, SESS_FLAG_AUTHENTICATED)) { return NOT_AUTHENTICATED; } // Get Call parameteres if (sscanf(args, "%s %s %[^\n]", actionid, exten, options) < 2) { return INVALID_ARGUMENTS; } // Initialize application info struct app_call_info *info = malloc(sizeof(struct app_call_info)); memset(info, 0, sizeof(struct app_call_info)); isaac_strcpy(info->actionid, actionid); isaac_strcpy(info->destiny, exten); // Check if uniqueid info is requested app_args_t parsed; application_parse_args(options, &parsed); if (!isaac_strcmp(application_get_arg(&parsed, "WUID"), "1")) info->print_uniqueid = 1; if (!isaac_strcmp(application_get_arg(&parsed, "BRD"), "1")) info->broadcast = 1; // Register a Filter to get Generated Channel info->callfilter = filter_create_async(sess, call_state); filter_new_condition(info->callfilter, MATCH_EXACT, "Event", "VarSet"); filter_new_condition(info->callfilter, MATCH_EXACT, "Variable", "ACTIONID"); filter_new_condition(info->callfilter, MATCH_EXACT, "Value", actionid); filter_set_userdata(info->callfilter, (void*) info); filter_register_oneshot(info->callfilter); // Get the logged agent const char *agent = session_get_variable(sess, "AGENT"); const char *rol = session_get_variable(sess, "ROL"); // Construct a Request message ami_message_t msg; memset(&msg, 0, sizeof(ami_message_t)); message_add_header(&msg, "Action: Originate"); message_add_header(&msg, "CallerID: %s", agent); message_add_header(&msg, "Channel: Local/%s@%s", agent, call_config.incontext); message_add_header(&msg, "Context: %s", call_config.outcontext); message_add_header(&msg, "Priority: 1"); message_add_header(&msg, "ActionID: %s", actionid); message_add_header(&msg, "Exten: %s", exten); message_add_header(&msg, "Async: 1"); message_add_header(&msg, "Variable: ACTIONID=%s", actionid); message_add_header(&msg, "Variable: ROL=%s", rol); message_add_header(&msg, "Variable: CALLERID=%s", agent); message_add_header(&msg, "Variable: DESTINO=%s", exten); message_add_header(&msg, "Variable: AUTOANSWER=%d", call_config.autoanswer); // Forced CLID from application arguments if (application_get_arg(&parsed, "CLID")) message_add_header(&msg, "Variable: ISAAC_FORCED_CLID=%s", application_get_arg(&parsed, "CLID")); // Forced SRC CLID from application arguments if (application_get_arg(&parsed, "SRC_CLID")) message_add_header(&msg, "Variable: ISAAC_SRC_FORCED_CLID=%s", application_get_arg(&parsed, "SRC_CLID")); // Forced Timeout from application arguments if (application_get_arg(&parsed, "TIMEOUT")) message_add_header(&msg, "Variable: ISAAC_CALL_TIMEOUT=%s", application_get_arg(&parsed, "TIMEOUT")); // Originate absolute TIMEOUT (default 30s) if (application_get_arg(&parsed, "ABSOLUTE_TIMEOUT")) message_add_header(&msg, "Timeout: %s", application_get_arg(&parsed, "ABSOLUTE_TIMEOUT")); // Send this message to ami manager_write_message(manager, &msg); return 0; }