NodeBase* NodeSetAssociateData::run(base_script_t* param) { if (NULL == param) { IVR_WARN("base_script_t pointer should not be null"); return NULL; } IVR_TRACE("%s", enter(param->name_var_map).c_str()); const char* exit = EXIT_FAIL; string key_data; string value_data; const map<string, variable_t>& vars = param->name_var_map; if (!parse_all(_key_data, vars, key_data) || key_data.empty() || !parse_all(_value_data, vars, value_data)) { IVR_WARN("get key or key failed!, key %s, value %s", _key_data.c_str(), _value_data.c_str()); return _find_exit_node(param, exit); } if (IVR_SUCCESS == ims_mgr_t::get_instance()->set_associatedata( param->imsno, param->imssid, key_data, value_data)) { IVR_TRACE("set associate data success!"); exit = EXIT_SUCC; } else { IVR_WARN("set associate data failed!"); } return _find_exit_node(param, exit); }
NodeBase* NodeStopRecord::run(base_script_t* param) { if (NULL == param) { IVR_WARN("base_script_t pointer should not be null"); return NULL; } IVR_TRACE("%s", enter(param->name_var_map).c_str()); const char* exit = EXIT_FAIL; string callid; fw_id_t fs_no = param->fid; if (true == parse_expression(_callid, param->name_var_map, callid)) { IVR_TRACE("callid=%s", callid.c_str()); fs_opr_t* opr = NULL; if (fs_mgr_t::instance()->fetch_opr(fs_no, &opr) == IVR_SUCCESS) { if (NULL != opr) { if (opr->record(callid.c_str(), "", false) == IVR_SUCCESS) { exit = EXIT_SUCC; } else { IVR_WARN("opr stop record failed(callid %s)", _callid.c_str()); } fs_mgr_t::instance()->free_opr(&opr); } else { IVR_WARN("fetch opr failed. freeswitch no is %d", fs_no); } } } else { IVR_WARN("parse callid failed(%s)", _callid.c_str()); } NodeBase* exit_node_ptr = NULL; std::map<std::string, NodeBase*>::iterator citr; citr = _exit_node_map.find(exit); if (citr != _exit_node_map.end()) { exit_node_ptr = citr->second; IVR_TRACE("%s exit from %s()", leave(param->name_var_map).c_str(), exit); } else { IVR_WARN("Can not find exit %s in _exit_node_map", exit); } return exit_node_ptr; }
void InboundChanThread::heartbeat(esl_handle_t& handle) { uint32_t inbound_chan_num_cp = 0; uint32_t cpu = CpuManager::get_instance()->get_cpu_occupy(); std::string err; char resp[20] = {0}; bzero(resp, 20); { rw_lock_t lock(g_inbound_chan_rwlock); if (lock.locked()) { inbound_chan_num_cp = g_inbound_chan_num; } else { err = "lock inbound num failed"; } } if (err.length()) { IVR_WARN("%s", err.c_str()); } snprintf(resp, 20, "cpu=%02u,chan=%05u", cpu, inbound_chan_num_cp); esl_send(&handle, resp); IVR_TRACE("ivr-loadbalance-resp = %s", resp); }
NodeBase* NodeSetAppData::run(base_script_t* param) { const char* exit = EXIT_FAIL; std::string ret = ""; IVR_TRACE("%s", enter(param->name_var_map).c_str()); if (parse_expression(_app_data, param->name_var_map, ret)) { if (ret.length() > 512 || ret.find("\n", 0, ret.length() - 1) != std::string::npos) { exit = EXIT_FAIL; IVR_WARN("appdata is too long(%d)", int(ret.length())); } else { //to do set call data ivr::IvrCallDataCollection::instance().set_appdata(param->session_id, ret); exit = EXIT_SUCC; } } else { IVR_WARN("parse assign expression failed(%s)", _app_data.c_str()); } IVR_TRACE("%s exit from %s", leave(param->name_var_map).c_str(), exit); return _exit_node_map[exit]; }
NodeBase* NodeGetAssociateData::run(base_script_t* param) { if (NULL == param) { IVR_WARN("base_script_t pointer should not be null"); return NULL; } IVR_TRACE("%s", enter(param->name_var_map).c_str()); const char* exit = EXIT_FAIL; string data_key, data_value; const map<string, variable_t>& vars = param->name_var_map; if (vars.find(_value_data) == vars.end()) { IVR_WARN("δÕÒµ½ÐèÒª¸³ÖµµÄ±äÁ¿ %s", _value_data.c_str()); return _find_exit_node(param, exit); } if (parse_all(_key_data, vars, data_key) && !data_key.empty()) { int32_t recode = ims_mgr_t::get_instance()->get_associatedata(param->imsno, param->imssid, data_key, data_value); if (IVR_SUCCESS == recode) { variable_t& var = param->name_var_map[_value_data]; if (var.type == STRING && NULL != var.pvalue) { *((string*)(var.pvalue)) = data_value; exit = EXIT_SUCC; } else { IVR_WARN("get associate data set result failed"); } } else { IVR_WARN("get associate data failed"); } } else { IVR_WARN("½âÎökey×Ö·û´®Ê§°Ü %s", _key_data.c_str()); } return _find_exit_node(param, exit); }
NodeBase* NodeSetAssociateData::_find_exit_node(base_script_t* param, const char* exit) { NodeBase* exit_node_ptr = NULL; std::map<std::string, NodeBase*>::iterator citr; citr = _exit_node_map.find(exit); if (citr != _exit_node_map.end()) { exit_node_ptr = citr->second; IVR_TRACE("%s exit from %s(%s)", leave(param->name_var_map).c_str(), exit, param->callid.c_str()); } else { IVR_WARN("Can not find exit %s in _exit_node_map", exit); } return exit_node_ptr; }
bool InboundChanThread::check_capability() { bool result = false; ostringstream ostm; { rw_lock_t lock(g_inbound_chan_rwlock, true); if (lock.locked()) { if (g_inbound_chan_num < g_inbound_conf.max_inbound_chan_num) { ++g_inbound_chan_num; result = true; } else { ostm << "[IB]achieve max capability,reject service(" << g_inbound_chan_num << ")"; } } else { ostm << "lock inbound rwlock failed"; } } if (!result) { IVR_WARN("%s", ostm.str().c_str()); } return result; }
uint32_t InboundChanThread::execute(void* taskparam) { string callid, ani, dnis; NodeBase* node = NULL; inbound_script_t script; std::string err; channel_info_t cinfo; // clear flow ptr script.flow = NULL; uint32_t ret = 0; std::string curr; dnis = ((inbound_script_t*)_param)->dnis; ostringstream ost; fs_opr_t* opr = NULL; IVR_DEBUG("inbound_execute event queue pointer %lu, queue size: %lu", (uint64_t)(((session_dynamic_resource_t*)taskparam)->event_queue), ((session_dynamic_resource_t*)taskparam)->event_queue->size()); ivr_session_id_t ivr_s_id; session_dynamic_resource_t* resource = NULL; IvrInstanceManager* mgr = NULL; if (!check_capability()) { ret = 1; goto END; } //inbound_script 对象 作为流程执行run函数的参数param { rw_lock_t lock(g_inbound_conf_rwlock, false); if (!lock.locked()) { IVR_WARN("failed lock!"); goto CHAN_END; } if (g_inbound_conf.dnis_script_map.find(dnis) == g_inbound_conf.dnis_script_map.end()) { if (!g_inbound_conf.has_default) { IVR_WARN("没有找到可以匹配的流程(dnis=%s),且默认流程未配置或未正确加载", dnis.c_str()); ret = 1; goto CHAN_END; } else { IVR_TRACE("没有找到可以匹配的流程(dnis=%s),启动默认流程", dnis.c_str()); script = g_inbound_conf.default_script; if (SUCCESS != FlowManager::attach_flow(g_inbound_conf.default_script.flow, &script.flow)) { ret = 1; goto CHAN_END; } } } else { IVR_TRACE("找到匹配的流程(dnis=%s)", dnis.c_str()); script = g_inbound_conf.dnis_script_map[dnis]; if (SUCCESS != FlowManager::attach_flow(g_inbound_conf.dnis_script_map[dnis].flow, &script.flow)) { ret = 1; goto CHAN_END; } } } // init ims information script.imsno = (uint32_t) - 1; script.imssid = 0; script.requestId = 0; script.type = ((inbound_script_t*)_param)->type; script.fid = ((inbound_script_t*)_param)->fid; script.ani = ((inbound_script_t*)_param)->ani; script.dnis = ((inbound_script_t*)_param)->dnis; script.callid = ((inbound_script_t*)_param)->callid; script.callsource = ((inbound_script_t*)_param)->callsource; script.channel_name = ((inbound_script_t*)_param)->channel_name; script.channel_id = ((inbound_script_t*)_param)->channel_id; script.trunck = ((inbound_script_t*)_param)->trunck; ivr_tools_t::build_vars(script.flow->name_var_map, script.name_var_map); // don't add channel information here // if answer the call, will add information //创建实例 resource = (session_dynamic_resource_t*)taskparam; mgr = IvrInstanceManager::get_instance(); if (IVR_SUCCESS != mgr->create_ivr_instance(script.type, script.fid, &ivr_s_id, *resource, script.callid.c_str())) { IVR_WARN("创建实例失败(dnis=%s)", script.dnis.c_str()); goto CHAN_END; } //添加uuid if (IVR_SUCCESS != mgr->add_uuid(ivr_s_id, script.callid)) { IVR_WARN("创建实例失败(dnis=%s)", script.dnis.c_str()); mgr->destroy_ivr_instance(ivr_s_id); goto CHAN_END; } //注册uuid if (fs_mgr_t::instance()->fetch_opr(script.fid, &opr) == IVR_SUCCESS) { if (NULL == opr || IVR_SUCCESS != opr->register_session(script.callid.c_str(), ivr_s_id)) { IVR_WARN("添加uuid失败(dnis=%s)", script.dnis.c_str()); mgr->destroy_ivr_instance(ivr_s_id); fs_mgr_t::instance()->free_opr(&opr); goto CHAN_END; } fs_mgr_t::instance()->free_opr(&opr); } else { IVR_WARN("注册实例失败(dnis=%s)", script.dnis.c_str()); mgr->destroy_ivr_instance(ivr_s_id); goto CHAN_END; } // update channel info cinfo.callsource = _param->callsource; cinfo.channel_id = _param->channel_id; cinfo.channel_name = _param->channel_name; IvrInstanceManager::get_instance()->add_channel_info(script.callid, cinfo); //设置script内容 script.session_id = ivr_s_id; script.timer = resource->timer; curr = ivr_tools_t::get_current_second(); *(string*)script.name_var_map[SYS_VAR[sys_var_t::ANI]].pvalue = script.ani; *(string*)script.name_var_map[SYS_VAR[sys_var_t::DNIS]].pvalue = script.dnis; *(string*)script.name_var_map[SYS_VAR[sys_var_t::CALLID]].pvalue = script.callid; *(string*)script.name_var_map[SYS_VAR[sys_var_t::TRUNCK]].pvalue = script.trunck; *(string*)script.name_var_map[SYS_VAR[sys_var_t::RECORD_FILE]].pvalue = ""; *(string*)script.name_var_map[SYS_VAR[sys_var_t::HANGUP_CAUSE]].pvalue = "user_hangup"; *(string*)script.name_var_map[SYS_VAR[sys_var_t::CALL_BEGIN_TIME]].pvalue = curr; *(string*)script.name_var_map[SYS_VAR[sys_var_t::CALL_ANSWER_TIME]].pvalue = curr; //运行流程 node = script.flow->id_node_map[script.flow->begin_id]; ost << "\n================"; ost << "ANI:\t" << script.ani << endl; ost << "DNIS:\t" << script.dnis << endl; ost << "CALLID:\t" << script.callid << endl; ost << "TRUNCK:\t" << script.trunck << endl; ost << "FID:\t" << script.fid << endl; ost << "SESSIONID:\t" << script.session_id << endl; ost << "================"; IVR_DEBUG("%s", ost.str().c_str()); #if IVR_ENABLE_DEBUGER IvrDebuger::get_instance()->report(this, "startup", script, node); #endif do { #if IVR_ENABLE_DEBUGER if (IvrDebuger::get_instance()->wait(this) == 1) { break; } #endif node = node->run(&script); #if IVR_ENABLE_DEBUGER IvrDebuger::get_instance()->report(this, "runnode", script, node); #endif } while (node && !g_stopped); if (!node) { CallDataManager* calldata_manager = CallDataManager::get_instance(); calldata_manager->push_calldata(script.bill_info().c_str()); } ivr_tools_t::destroy_vars(script.name_var_map); mgr->destroy_ivr_instance(ivr_s_id); ims_mgr_t::get_instance()->unbind_session_id(ivr_s_id); if (resource->timer != NULL) { // clear all timer resource->timer->clear_all_timer(); } CHAN_END: FlowManager::detach_flow(&script.flow); { rw_lock_t lock(g_inbound_chan_rwlock, true); if (lock.locked()) { --g_inbound_chan_num; } else { err = "lock inbound rwlock failed"; } } if (err.length()) { IVR_WARN("%s", err.c_str()); } END: return ret; }
NodeBase* NodeJsonGet::run(base_script_t* param) { IVR_TRACE("%s", enter(param->name_var_map).c_str()); const char* exit = EXIT_FAIL; std::string value = ""; std::string input = ""; std::string key = ""; variable_t var_value; variable_t var_reason; std::string reason_type_error = "reason type error"; var_value.pvalue = &reason_type_error; var_reason.pvalue = &reason_type_error; if (param->name_var_map.find(_value) == param->name_var_map.end()) { IVR_WARN("not found variable %s", _value.c_str()); goto LEAVE; } if (param->name_var_map.find(_reason) == param->name_var_map.end()) { IVR_WARN("not found variable %s", _reason.c_str()); goto LEAVE; } var_value = param->name_var_map[_value]; var_reason = param->name_var_map[_reason]; if (var_reason.type != INT32) { IVR_WARN("变量%s 的类型错误", _reason.c_str()); //(*(std::string*)var_reason.pvalue).assign("5"); goto LEAVE; } (*(std::string*)var_reason.pvalue).assign("0"); if (parse_all(_input, param->name_var_map, input) && parse_all(_key, param->name_var_map, key)) { IVR_TRACE("INPUT: %s; key: %s", input.c_str(), key.c_str()); //获取json串 json_object* obj = json_tokener_parse(input.c_str()); if (is_error(obj) || NULL == obj) { IVR_TRACE("未找到需要赋值的变量"); (*(std::string*)var_reason.pvalue).assign("1"); goto LEAVE; } const char* tmp = json_object_get_string(obj); if (tmp[0] >= '0' && tmp[0] <= '9') { IVR_TRACE("未找到需要赋值的变量"); (*(std::string*)var_reason.pvalue).assign("1"); json_object_put(obj); goto LEAVE; } //查找key json_object* obj_value = json_object_object_get(obj, key.c_str()); if (is_error(obj_value) || NULL == obj_value) { IVR_TRACE("未找到key值"); (*(std::string*)var_reason.pvalue).assign("2"); json_object_put(obj); goto LEAVE; } //根据需要转化 if (0 == strcasecmp(_valuetype.c_str(), PARAMITEM_TYPE_STRING)) { const char* cstr_value = json_object_get_string(obj_value); if (NULL == cstr_value) { IVR_TRACE("转换key值错误"); (*(std::string*)var_reason.pvalue).assign("3"); json_object_put(obj); //json_object_put(obj_value); goto LEAVE; } if (var_value.type != STRING) { IVR_TRACE("赋值变量类型错误"); (*(std::string*)var_reason.pvalue).assign("4"); json_object_put(obj); //json_object_put(obj_value); goto LEAVE; } value.assign(cstr_value); *(string*)var_value.pvalue = value; exit = EXIT_SUCC; json_object_put(obj); goto LEAVE; } else if (0 == strcasecmp(_valuetype.c_str(), PARAMITEM_TYPE_INT32)) { int32_t int32_value = json_object_get_int(obj_value); if (var_value.type != INT32) { IVR_TRACE("赋值变量类型错误"); (*(std::string*)var_reason.pvalue).assign("4"); json_object_put(obj); //json_object_put(obj_value); goto LEAVE; } std::stringstream ss; ss << int32_value; ss >> value; *(string*)var_value.pvalue = value; exit = EXIT_SUCC; json_object_put(obj); goto LEAVE; } else if (0 == strcasecmp(_valuetype.c_str(), PARAMITEM_TYPE_BOOL)) {
NodeBase* NodeJsonGetArray::run(base_script_t* param) { IVR_TRACE("%s", enter(param->name_var_map).c_str()); const char* exit = EXIT_FAIL; std::string value = ""; std::string valueindex = ""; std::string input = ""; std::string key = ""; variable_t var_value; variable_t var_reason; std::string reason_type_error = "reason type error"; var_value.pvalue = &reason_type_error; var_reason.pvalue = &reason_type_error; if (param->name_var_map.find(_value) == param->name_var_map.end()) { IVR_WARN("not found variable %s", _value.c_str()); goto LEAVE; } if (param->name_var_map.find(_reason) == param->name_var_map.end()) { IVR_WARN("not found variable %s", _reason.c_str()); goto LEAVE; } var_value = param->name_var_map[_value]; var_reason = param->name_var_map[_reason]; if (var_reason.type != INT32) { IVR_WARN("变量%s 的类型错误", _reason.c_str()); //(*(std::string*)var_reason.pvalue).assign("5"); goto LEAVE; } (*(std::string*)var_reason.pvalue).assign("0"); if (parse_all(_input, param->name_var_map, input) && parse_all(_key, param->name_var_map, key) && parse_expression(_valueindex, param->name_var_map, valueindex)) { IVR_TRACE("INPUT: %s; key: %s", input.c_str(), key.c_str()); //获取json串 json_object* obj = json_tokener_parse(input.c_str()); if (is_error(obj) || NULL == obj) { IVR_TRACE("未找到需要赋值的变量"); (*(std::string*)var_reason.pvalue).assign("1"); goto LEAVE; } const char* tmp = json_object_get_string(obj); if (tmp[0] >= '0' && tmp[0] <= '9') { IVR_TRACE("未找到需要赋值的变量"); (*(std::string*)var_reason.pvalue).assign("1"); json_object_put(obj); goto LEAVE; } //查找key json_object* obj_value = json_object_object_get(obj, key.c_str()); if (is_error(obj_value) || NULL == obj_value) { IVR_TRACE("未找到key值"); (*(std::string*)var_reason.pvalue).assign("2"); json_object_put(obj); goto LEAVE; } //检查是否为array if (! json_object_is_type(obj_value, json_type_array)) { IVR_WARN("jsonget array 中出现非array值"); //TODO: assign what? (*(std::string*)var_reason.pvalue).assign("10"); json_object_put(obj); //json_object_put(obj_value); goto LEAVE; } if (!ivr_tools_t::is_nonnegative_integer(valueindex)) { IVR_WARN("下标需为非负整数值: %s", valueindex.c_str()); //TODO: assign what? (*(std::string*)var_reason.pvalue).assign("11"); json_object_put(obj); //json_object_put(obj_value); goto LEAVE; } int32_t tmp_value_index = atoi(valueindex.c_str()); int32_t array_len = json_object_array_length(obj_value); if (tmp_value_index < 0 || tmp_value_index >= array_len) { IVR_WARN("jsonget array 中下标值越界"); //TODO: assign what? (*(std::string*)var_reason.pvalue).assign("12"); json_object_put(obj); //json_object_put(obj_value); goto LEAVE; } json_object* obj_sub = json_object_array_get_idx(obj_value, tmp_value_index); if (is_error(obj_sub) || NULL == obj_sub) { IVR_TRACE("未找到key中下标为%d的值", tmp_value_index); //TODO: assign what? (*(std::string*)var_reason.pvalue).assign("13"); json_object_put(obj); //json_object_put(obj_value); goto LEAVE; } //根据需要转化 if (0 == strcasecmp(_valuetype.c_str(), PARAMITEM_TYPE_STRING)) { const char* cstr_value = json_object_get_string(obj_sub); if (NULL == cstr_value) { IVR_TRACE("转换key值错误"); (*(std::string*)var_reason.pvalue).assign("3"); json_object_put(obj); //json_object_put(obj_value); //json_object_put(obj_sub); goto LEAVE; } if (var_value.type != STRING) { IVR_TRACE("赋值变量类型错误"); (*(std::string*)var_reason.pvalue).assign("4"); json_object_put(obj); //json_object_put(obj_value); //json_object_put(obj_sub); goto LEAVE; } value.assign(cstr_value); *(string*)var_value.pvalue = value; exit = EXIT_SUCC; json_object_put(obj); goto LEAVE; } else if (0 == strcasecmp(_valuetype.c_str(), PARAMITEM_TYPE_INT32)) { int32_t int32_value = json_object_get_int(obj_sub); if (var_value.type != INT32) { IVR_TRACE("赋值变量类型错误"); (*(std::string*)var_reason.pvalue).assign("4"); json_object_put(obj); //json_object_put(obj_value); //json_object_put(obj_sub); goto LEAVE; } std::stringstream ss; ss << int32_value; ss >> value; *(string*)var_value.pvalue = value; exit = EXIT_SUCC; json_object_put(obj); goto LEAVE; } else if (0 == strcasecmp(_valuetype.c_str(), PARAMITEM_TYPE_BOOL)) {