common.h
13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* CC/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _IVR_COMMON_H_
#define _IVR_COMMON_H_
#include <cstdio>
#include <cstdlib>
#include <ctype.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <exception>
#include <stdexcept>
#include <memory>
#include <bgcc.h>
#include "esl.h"
#include "esl_threadmutex.h"
#include "ims/ims_struct.h"
//global macro
#define SUCCESS (0)
#define FAILURE (1)
#define MAX_THREAD_NUM (950)
#define LOG_PATH "./conf/"
#define FLOW_PATH "./flow/"
#define IMS_SESSION_TAG "IMSDATA"
#define CREATE_SESSION_EMPTY_CALLID "create empty session by ivr"
#define LEN_8 8
#define LEN_16 16
#define LEN_32 32
#define LEN_64 64
#define LEN_128 128
#define LEN_256 256
#define LEN_512 512
#define IVR_IMS_REINIT_TIME 3
#define IVR_FAIL_GENERAL -1
#define IVR_SUCCESS 0
#define IVR_FAIL_LOCK 1
#define IVR_FAIL_EXISTS 2
#define IVR_FAIL_NOTEXISTS 3
#define IVR_FAIL_MEM 4
#define IVR_FAIL_INVALID_FSNO 5
#define IVR_FAIL_ALL_BUSY 6
#define IVR_FAIL_CONNECT 7
#define IVR_FAIL_TIMEOUT 8
#define IVR_FAIL_NOIMS 9
#define IVR_FAIL_IMS_REGIST 10
#define IVR_FAIL_IMS_NOTEXIST 11
#define IVR_FAIL_IMS_ROUTEREQUEST 12
#define IVR_FAIL_IMS_CANCELROUTEREQUEST 13
#define IVR_FAIL_IMS_TRANSAGENT 14
#define IVR_FAIL_IMS_SETASSOCIATEDATA 15
#define IVR_FAIL_IMS_GETASSOCIATEDATA 16
#define IVR_FAIL_IMS_NOMAIN 17
#define IVR_FAIL_IMS_CREATESESSION 18
#define IVR_FAIL_IMS_SESSIONINVALIDATE 19
#define IVR_FAIL_IMS_INFOINVALIDATE 20
#define IVR_FAIL_IMS_AGENTNOTASSIGNED 21
#define IVR_FAIL_IMS_ROUTEREQUEST_REPEATED 22
#define IVR_FAIL_IMS_REQIDINVALIDATE 23
#define IVR_FAIL_IMS_PROXY_FAILED 24
#define IVR_FAIL_IMS_REINIT 25
#define IVR_FAIL_IMS_MAKECALL 26
#define IVR_TRACE(fmt, arg...) do { BGCC_TRACE("ivr", fmt, ##arg); } while(0)
#define IVR_NOTICE(fmt, arg...) do { BGCC_NOTICE("ivr", fmt, ##arg); } while(0)
#define IVR_DEBUG(fmt, arg...) do { BGCC_DEBUG("ivr", fmt, ##arg); } while(0)
#define IVR_WARN(fmt, arg...) do { BGCC_WARN("ivr", fmt, ##arg); } while(0)
#define IVR_FATAL(fmt, arg...) do { BGCC_FATAL("ivr", fmt, ##arg); } while(0)
using namespace std;
typedef map<string, string> key_map_t;
typedef map<string, key_map_t> section_map_t;
typedef std::map<std::string, std::string> str2str_map;
typedef uint32_t fw_id_t; //Freeswitch唯一标志
typedef uint64_t ivr_session_id_t; //ivr的sessionid
typedef ivr::ReloadFlagT conf_reload_flag_t;
typedef ims::RouteEventT ims_route_eventdata_t;
typedef bgcc::Guard<bgcc::Mutex> locker_t;
/**
* @brief 数据库连接池
* detail description
*
*/
class DBPool;
/**
* @brief 流程节点基类
* detail description
*
*/
class NodeBase;
class ThreadPool;
class IvrTimer;
/**
* @brief 变量类型
* detail description
*
*/
enum var_type_t {
INT32 = 0, ///< 整数
STRING, ///< STRING
RESULTSET, ///< 结果集
MAP ///< 映射
};
/**
* @brief 变量类型定义
* detail description
*
*/
struct variable_t {
string name; ///< 名称
var_type_t type; ///< 类型
void* pvalue; ///< 根据变量的类型 创建不同类型的 对象指针
string initial; ///< 初始化值
};
/**
* @brief流程承载节点
* detail description
*
*/
struct flow_t {
uint32_t begin_id; ///< 流程开始节点编号
map<uint32_t, NodeBase*> id_node_map; ///< 节点映射
map<string, variable_t> name_var_map; ///< 脚本中变量的模版
uint32_t ref_count; ///< 脚本引用计数 用于延时释放内存
time_t last_modify_time; ///< 最近一次修改时间
bgcc::Mutex refcmutex; ///< mutex for ref_count
};
typedef std::map<std::string, flow_t*> flow_name_map;
struct channel_info_t {
std::string channel_name;
std::string channel_id;
std::string callsource;
};
/**
* @brief IVR事件基类
* detail description
*
*/
struct ivr_base_event_t {
// virtual destruct, delete drived class's member objects
virtual ~ivr_base_event_t() {}
enum ivr_event_type {
CALL_EVENT = 0,
MEDIA_EVENT,
IMS_EVENT,
OTHER_EVENT
};
ivr_event_type evt_type;
ivr_session_id_t sessionId;
uint64_t timestamp;
};
/**
* @brief IVR呼叫事件
* detail description
*
*/
struct ivr_call_event_t : public ivr_base_event_t {
enum call_event_name {
IVR_EVT_ANSWER = 0, //应答
IVR_EVT_ALERT, //振铃
IVR_EVT_HANGUP, //挂断
IVR_EVT_BRIDGE, //搭接成功
IVR_EVT_UNBRIDGE, //取消搭接成功
IVR_EVT_CHANLE_DESTORY, //Freeswitch拆线
IVR_EVT_CALLFAIL //外呼失败
};
enum call_event_reason {
CALL_NORMAL, //正常外呼/
CALL_DEST_BUSY, //对端忙
CALL_DEST_NOANSWER, //对端无应答
CALL_REJECTED, //对端拒绝
CALL_USER_NOT_REGISTERED,
CALL_SUBSCRIBER_ABSENT,
CALL_UNKNOW //其它原因
};
call_event_name evt_name;
call_event_reason evt_reason;
string callid; //事件对应的callid
string ani; //主叫号码
string dnis; //被叫号码
//搭接时使用下面变量,否则为空
string other_callid; //另一方通话的callid
string other_ani; //另一方通话的主叫号码
string other_dnis; //另一方通话的被叫号码
};
/**
* @brief IVR媒体事件
* detail description
*
*/
struct ivr_media_event_t : public ivr_base_event_t {
enum media_event_name {
IVR_EVT_PLAY_END = 100, //播放语音完毕
IVR_EVT_FILENOTEXIST, //语音文件不存在
IVR_EVT_GETDIGIT_SUCC, //收号成功
IVR_EVT_GETDIGIT_FAIL, //收号失败
IVR_EVT_DTMF, //用户按键
IVR_EVT_RECORD_START, //录音开始
IVR_EVT_RECORD_END //录音结束
};
enum media_event_reason {
MEDIA_END, //正常结束
MEDIA_GETDIGIT, //收号
MEDIA_INVALID_FILE, //文件异常
MEDIA_DISCONNECT, //话路断开
MEDIA_UNKNOW //其它原因
};
media_event_name evt_name;
media_event_reason evt_reason;
string callid; //媒体话路的callid
string media_data; //媒体文件名称
string digits; //收号结果
};
/**
* @brief IVR其它事件
* detail description
*
*/
struct ivr_other_event_t : public ivr_base_event_t {
enum other_event_name {
IVR_EVT_TIMEOUT = 200, //超时事件
IVR_EVT_UNKNOW //其它事件
};
other_event_name evt_name;
string data; //事件数据(超时事件为timerId)
};
struct ivr_ims_event_t : public ivr_base_event_t {
enum ims_event_name {
IVR_EVT_IMS_ROUTE_RESPONSE = 300,
IVR_EVT_IMS_NOT_RESPONSE,
IVR_EVT_IMS_UNKNOW
};
ims_event_name evt_name;
ims_route_eventdata_t data;
};
typedef queue< ivr_base_event_t* > ivr_event_queue_t;
struct ivr_thread_param_t {
ThreadPool* pool; //需要其中的_worker_queue
ivr_event_queue_t* event_queue; //该线程分配到的IVR事件队列
// sem_t * evt_sem; //队列信号量
IvrTimer* timer; //该线程分配到的计时器
};
/*
struct ivr_task_param_t{
ivr_event_queue_t * event_queue; //该线程分配到的IVR事件队列
sem_t * evt_sem; //事件队列的信号量
IvrTimer * timer; //该线程分配到的计时器
};
*/
struct session_dynamic_resource_t {
session_dynamic_resource_t() : event_queue(NULL), timer(NULL) { /*, sem(NULL)*/ }
ivr_event_queue_t* event_queue; ///<IVR事件队列,session创建后确定
IvrTimer* timer; ///<IVR计时器,session创建后确定
// sem_t *sem;
};
// timer type: usr timer or system defined timer
enum timer_type_t {
user_define, // user defined timer
ims_transagent, // ims trans agent timer
unknown // other timer
};
/**
* @brief 流程描述
* detail description
*
*/
struct base_script_t {
// virtual destruct
virtual ~base_script_t() {}
enum script_type_t {
AUTOBOUND = 0, ///<外呼类型
INBOUND = 1, ///<呼入类型
};
string name; ///<流程名称
string desc; ///<流程描述
string flow_name; ///<流程文件名称
string vox_base; ///<语音文件根路径
flow_t* flow; ///<流程节点
uint32_t type; ///<流程类型
map<string, variable_t> name_var_map; ///<通道中的变量的 副本
//esl_handle_t* handle; ///<通道中 使用的socket handle
/** 动态信息,随话路改变 **/
fw_id_t fid; ///<Freeswitch编号
string ani; ///<主叫号
string dnis; ///<被叫号
string callid; ///<该呼叫的callid
ivr_session_id_t session_id; ///<session id,session创建后确定
string channel_name;
string channel_id;
string callsource; // Freeswitch IP
string trunck;//data when transfer from other ivr
IvrTimer* timer; ///<IVR计时器,session创建后确定
// ims infomation
uint32_t imsno; // ims index
ims_session_id_t imssid; // ims session id
ims_routerequest_id_t requestId;
std::string bill_info();
};
/**
* @brief inbound流程
* detail description
*
*/
struct inbound_script_t: public base_script_t {
esl_socket_t socket; ///< 和freeswitch的连接
struct sockaddr_in* addr; ///< sockaddr
std::string dialdata;
inbound_script_t(): addr(NULL) {}
~inbound_script_t() {
if (addr) {
delete addr;
addr = NULL;
}
}
};
/**
* @brief 自动外呼流程
* detail description
*
*/
struct autorun_script_t: public base_script_t {
// vector<freeswitch_info_t> freeswitch_info_vec; ///<用到的fs信息
uint32_t autorun_chan_num; ///<执行流程的通道数
uint32_t autorun_interval; ///<自启动间隔
time_t last_startup_time; ///<最后一次启动时间
bool is_write_bill; ///<是否写话单
};
/**
* @brief 呼入相关的配置
* detail description
*
*/
struct inbound_conf_t {
map<string, inbound_script_t> dnis_script_map; ///<所有呼入流程
inbound_script_t default_script; ///<默认流程
uint32_t max_inbound_chan_num; ///<呼入最大通道数
uint32_t max_autodial_chan_num; ///<max autodial chan number
time_t last_modify_time; ///<最后一次修改时间
bool has_default; ///<是否配置了默认流程
};
/**
* @brief 自启动流程相关配置
* detail description
*
*/
struct autorun_conf_t {
vector<autorun_script_t> autorun_script_vec;///<自启动流程列表
uint32_t max_autorun_chan_num; ///<自启动通道最大数量
time_t last_modify_time; ///最后修改日期
};
struct call_data_conf_t {
string file_name;
uint32_t generate_interval;
uint32_t generate_file_size;
string generate_path;
string sendto_path;
};
typedef struct _sys_var_t {
enum {//注意和SYS_VAR的对应关系
BEGIN = 0,
ANI = 0,
DNIS = 1,
CALLID = 2,
RECORD_FILE = 3,
HANGUP_CAUSE = 4,
CALL_BEGIN_TIME = 5, ///< 呼叫到达平台的时间
CALL_ANSWER_TIME = 6, ///< 呼叫被接起的时间
TRUNCK = 7,
AGENTID= 8, //转坐席的工号
END = 9
};
} sys_var_t;
struct errorcode_string {
// get description of error code
static string tostring(int32_t errorcode);
// static int32_t tocode(const string& errorstring);
private:
static const std::map<int32_t, string>& errormap();
};
extern int32_t g_stopped;
extern sem_t g_stop_sem;
//logger config
extern uint32_t g_log_count;
extern uint32_t g_log_filecount;
extern uint32_t g_log_level;
extern uint32_t g_log_timeout;
extern string g_server_ip;
extern uint32_t g_server_port;
extern uint32_t g_reload_port;
extern call_data_conf_t g_calldata_conf;
extern inbound_conf_t g_inbound_conf;
extern autorun_conf_t g_autorun_conf;
extern pthread_rwlock_t g_inbound_conf_rwlock; // used for lock g_inbound_conf
extern pthread_rwlock_t g_autorun_conf_rwlock; // used for lock g_autorun_conf
extern DBPool* g_dbpool;///< 数据库连接池
extern uint32_t g_inbound_chan_num;
extern uint32_t g_autorun_chan_num;
extern uint32_t g_autodial_chan_num;
extern pthread_rwlock_t g_inbound_chan_rwlock;
extern pthread_rwlock_t g_autorun_chan_rwlock;
extern pthread_rwlock_t g_autodial_chan_rwlock;
extern const char* SYS_VAR[];
extern bool
g_output_esllog; // enable/disable esl log, true: output log information, false: not print
extern time_t g_autorun_script_stamp; // mark last autorun script loaded time
// every autorun chan thread save the time(st) when it started
// if st < g_autorun_script_stamp, the thread need stop,
// because autorun script ust reloaded
const char DATA_CACHE_FILE[] = "log/ivr_datacached.log";
#endif