Browse Source

坐席外呼逻辑开发,待调试,fix

刘威 5 months ago
parent
commit
49aedbe8c1
31 changed files with 758 additions and 355 deletions
  1. 7 7
      build.mak
  2. 2 2
      build/os-auto.mak
  3. 309 102
      config.log
  4. 18 18
      config.status
  5. 14 0
      docker/Dockerfile
  6. 1 1
      pjlib/build/os-auto.mak
  7. 1 1
      pjlib/include/pj/compat/m_auto.h
  8. 1 1
      pjlib/include/pj/compat/os_auto.h
  9. 4 4
      pjmedia/build/os-auto.mak
  10. BIN
      pjsip-apps/src/swig/python/__pycache__/pjsua2.cpython-39.pyc
  11. BIN
      pjsip-apps/src/swig/python/dist/pjsua2-2.14.dev0-py3.9-linux-x86_64.egg
  12. 10 3
      src/core/callcenter/acd.py
  13. 6 0
      src/core/callcenter/cache.py
  14. 3 3
      src/core/callcenter/call.py
  15. 4 7
      src/core/callcenter/esl/client.py
  16. 2 2
      src/core/callcenter/esl/handler/channel_answer_handler.py
  17. 2 2
      src/core/callcenter/esl/handler/channel_bridge_handler.py
  18. 2 2
      src/core/callcenter/esl/handler/channel_hangup_complete_handler.py
  19. 7 4
      src/core/callcenter/esl/handler/channel_hangup_handler.py
  20. 2 2
      src/core/callcenter/esl/handler/channel_park_handler.py
  21. 2 2
      src/core/callcenter/esl/handler/channel_progress_media_handler.py
  22. 2 2
      src/core/callcenter/esl/handler/default_esl_event_handler.py
  23. 2 2
      src/core/callcenter/esl/handler/detected_tone_handler.py
  24. 2 2
      src/core/callcenter/esl/handler/dtmf_handler.py
  25. 2 3
      src/core/callcenter/esl/handler/esl_event_handler.py
  26. 2 2
      src/core/callcenter/esl/handler/playback_stop_handler.py
  27. 2 2
      src/core/callcenter/esl/handler/record_stop_handler.py
  28. 176 0
      src/core/callcenter/web.py
  29. 1 1
      src/core/callcenter/ws.py
  30. 167 173
      src/core/server.py
  31. 5 5
      third_party/build/os-auto.mak

+ 7 - 7
build.mak

@@ -9,7 +9,7 @@ export HOST_NAME := unix
 export CC_NAME := gcc
 export TARGET_ARCH := 
 export STD_CPP_LIB := 
-export TARGET_NAME := aarch64-unknown-linux-gnu
+export TARGET_NAME := x86_64-unknown-linux-gnu
 export CROSS_COMPILE := 
 export LINUX_POLL := select 
 export SHLIB_SUFFIX := so
@@ -187,8 +187,8 @@ FFMPEG_CFLAGS =   -DPJMEDIA_USE_OLD_FFMPEG=1
 FFMPEG_LDFLAGS =   
 
 # Video4Linux2
-V4L2_CFLAGS = -DPJMEDIA_VIDEO_DEV_HAS_V4L2=1
-V4L2_LDFLAGS = -lv4l2
+V4L2_CFLAGS = 
+V4L2_LDFLAGS = 
 
 # OPENH264 flags
 OPENH264_CFLAGS =  
@@ -239,7 +239,7 @@ export APP_CFLAGS := -DPJ_AUTOCONF=1\
         -I$(PJDIR)/pjnath/include\
         -I$(PJDIR)/pjmedia/include\
         -I$(PJDIR)/pjsip/include
-export APP_CXXFLAGS := -fPIC $(APP_CFLAGS)
+export APP_CXXFLAGS := -g -O2 $(APP_CFLAGS)
 export APP_LDFLAGS := -L$(PJDIR)/pjlib/lib\
         -L$(PJDIR)/pjlib-util/lib\
         -L$(PJDIR)/pjnath/lib\
@@ -247,7 +247,7 @@ export APP_LDFLAGS := -L$(PJDIR)/pjlib/lib\
         -L$(PJDIR)/pjsip/lib\
         -L$(PJDIR)/third_party/lib\
         $(PJ_VIDEO_LDFLAGS) \
-        -fPIC
+        
 export APP_LDXXFLAGS := $(APP_LDFLAGS)
 
 export APP_LIB_FILES := \
@@ -329,7 +329,7 @@ export APP_LDLIBS := $(PJSUA_LIB_LDLIB) \
         $(APP_THIRD_PARTY_LIBS)\
         $(APP_THIRD_PARTY_EXT)\
         $(PJLIB_LDLIB) \
-        -lssl -lcrypto -luuid -lm -lrt -lpthread  -lasound   -lv4l2
+        -lssl -lcrypto -luuid -lm -lrt -lpthread   
 export APP_LDXXLIBS := $(PJSUA2_LIB_LDLIB) \
         -lstdc++ \
         $(APP_LDLIBS)
@@ -353,5 +353,5 @@ export PJ_INSTALL_DIR := /usr/local
 export PJ_INSTALL_INC_DIR := ${prefix}/include
 export PJ_INSTALL_LIB_DIR := ${exec_prefix}/lib
 export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1  -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1
-export PJ_INSTALL_LDFLAGS_PRIVATE := $(APP_THIRD_PARTY_LIBS) $(APP_THIRD_PARTY_EXT) -lssl -lcrypto -luuid -lm -lrt -lpthread  -lasound   -lv4l2
+export PJ_INSTALL_LDFLAGS_PRIVATE := $(APP_THIRD_PARTY_LIBS) $(APP_THIRD_PARTY_EXT) -lssl -lcrypto -luuid -lm -lrt -lpthread   
 export PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(filter-out $(PJ_INSTALL_LDFLAGS_PRIVATE),$(APP_LDXXLIBS))

+ 2 - 2
build/os-auto.mak

@@ -2,9 +2,9 @@
 
 export OS_CFLAGS   := $(CC_DEF)PJ_AUTOCONF=1 -fPIC -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1
 
-export OS_CXXFLAGS := $(CC_DEF)PJ_AUTOCONF=1 -fPIC
+export OS_CXXFLAGS := $(CC_DEF)PJ_AUTOCONF=1 -g -O2
 
-export OS_LDFLAGS  := -fPIC -lssl -lcrypto -luuid -lm -lrt -lpthread  -lasound   -lv4l2
+export OS_LDFLAGS  :=  -lssl -lcrypto -luuid -lm -lrt -lpthread   
 
 export OS_SOURCES  := 
 

File diff suppressed because it is too large
+ 309 - 102
config.log


+ 18 - 18
config.status

@@ -416,7 +416,7 @@ $config_headers
 
 Report bugs to the package provider."
 
-ac_cs_config='CFLAGS=-fPIC CXXFLAGS=-fPIC LDFLAGS=-fPIC'
+ac_cs_config='CFLAGS=-fPIC'
 ac_cs_version="\
 pjproject config.status 2.x
 configured by ./aconfigure, generated by GNU Autoconf 2.71,
@@ -505,7 +505,7 @@ if $ac_cs_silent; then
 fi
 
 if $ac_cs_recheck; then
-  set X /bin/bash './aconfigure'  'CFLAGS=-fPIC' 'CXXFLAGS=-fPIC' 'LDFLAGS=-fPIC' $ac_configure_extra_args --no-create --no-recursion
+  set X /bin/bash './aconfigure'  'CFLAGS=-fPIC' $ac_configure_extra_args --no-create --no-recursion
   shift
   \printf "%s\n" "running CONFIG_SHELL=/bin/bash $*" >&6
   CONFIG_SHELL='/bin/bash'
@@ -613,8 +613,8 @@ S["ac_webrtc_aec3_cflags"]=""
 S["ac_webrtc_aec3_instset"]=""
 S["ac_no_webrtc_aec3"]="1"
 S["ac_webrtc_ldflags"]=""
-S["ac_webrtc_cflags"]="-DWEBRTC_ARCH_ARM64"
-S["ac_webrtc_instset"]="neon"
+S["ac_webrtc_cflags"]=""
+S["ac_webrtc_instset"]="sse2"
 S["ac_no_webrtc"]=""
 S["ac_no_yuv"]=""
 S["ac_no_srtp"]=""
@@ -648,8 +648,8 @@ S["ac_vpx_ldflags"]=""
 S["ac_vpx_cflags"]=""
 S["ac_openh264_ldflags"]=""
 S["ac_openh264_cflags"]=""
-S["ac_v4l2_ldflags"]="-lv4l2"
-S["ac_v4l2_cflags"]="-DPJMEDIA_VIDEO_DEV_HAS_V4L2=1"
+S["ac_v4l2_ldflags"]=""
+S["ac_v4l2_cflags"]=""
 S["PKG_CONFIG"]="pkg-config"
 S["SAVED_PKG_CONFIG_PATH"]=""
 S["ac_ffmpeg_ldflags"]=" "
@@ -687,7 +687,7 @@ S["ac_oboe_ldflags"]=""
 S["ac_oboe_cflags"]=""
 S["ac_pa_cflags"]=" -DHAVE_SYS_SOUNDCARD_H -DHAVE_LINUX_SOUNDCARD_H -DPA_LITTLE_ENDIAN"
 S["ac_external_pa"]="0"
-S["ac_pjmedia_snd"]="alsa"
+S["ac_pjmedia_snd"]="null"
 S["ac_pjmedia_resample"]="libresample"
 S["ac_external_webrtc_aec3"]="0"
 S["ac_external_webrtc"]="0"
@@ -723,31 +723,31 @@ S["ac_ct_AR"]="ar"
 S["AR"]="ar"
 S["RANLIB"]="ranlib"
 S["ac_ct_CXX"]="g++"
-S["CXXFLAGS"]="-fPIC"
+S["CXXFLAGS"]="-g -O2"
 S["CXX"]="g++"
 S["OBJEXT"]="o"
 S["EXEEXT"]=""
 S["ac_ct_CC"]="gcc"
 S["CPPFLAGS"]=""
-S["LDFLAGS"]="-fPIC"
+S["LDFLAGS"]=""
 S["CFLAGS"]="-fPIC -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1"
 S["CC"]="gcc"
 S["target_os"]="linux-gnu"
 S["target_vendor"]="unknown"
-S["target_cpu"]="aarch64"
-S["target"]="aarch64-unknown-linux-gnu"
+S["target_cpu"]="x86_64"
+S["target"]="x86_64-unknown-linux-gnu"
 S["host_os"]="linux-gnu"
 S["host_vendor"]="unknown"
-S["host_cpu"]="aarch64"
-S["host"]="aarch64-unknown-linux-gnu"
+S["host_cpu"]="x86_64"
+S["host"]="x86_64-unknown-linux-gnu"
 S["build_os"]="linux-gnu"
 S["build_vendor"]="unknown"
-S["build_cpu"]="aarch64"
-S["build"]="aarch64-unknown-linux-gnu"
+S["build_cpu"]="x86_64"
+S["build"]="x86_64-unknown-linux-gnu"
 S["target_alias"]=""
 S["host_alias"]=""
 S["build_alias"]=""
-S["LIBS"]="-lssl -lcrypto -luuid -lm -lrt -lpthread  -lasound   -lv4l2"
+S["LIBS"]="-lssl -lcrypto -luuid -lm -lrt -lpthread   "
 S["ECHO_T"]=""
 S["ECHO_N"]="-n"
 S["ECHO_C"]=""
@@ -834,7 +834,7 @@ D["HAVE_LIBPTHREAD"]=" 1"
 D["HAVE_LIBRT"]=" 1"
 D["HAVE_LIBM"]=" 1"
 D["HAVE_LIBUUID"]=" 1"
-D["PJ_M_NAME"]=" \"aarch64\""
+D["PJ_M_NAME"]=" \"x86_64\""
 D["PJ_POOL_ALIGNMENT"]=" 8"
 D["HAVE_STDIO_H"]=" 1"
 D["HAVE_STDLIB_H"]=" 1"
@@ -883,7 +883,7 @@ D["PJ_HAS_UNISTD_H"]=" 1"
 D["PJ_HAS_EXECINFO_H"]=" 1"
 D["PJ_HAS_NET_IF_H"]=" 1"
 D["PJ_HAS_LOCALTIME_R"]=" 1"
-D["PJ_OS_NAME"]=" \"aarch64-unknown-linux-gnu\""
+D["PJ_OS_NAME"]=" \"x86_64-unknown-linux-gnu\""
 D["PJ_HAS_ERRNO_VAR"]=" 1"
 D["PJ_HAS_HIGH_RES_TIMER"]=" 1"
 D["PJ_HAS_MALLOC"]=" 1"

+ 14 - 0
docker/Dockerfile

@@ -1,5 +1,19 @@
 FROM python:3.9
+#RUN apt install vim wget curl
 RUN pip3 install swig cython pip setuptools --upgrade
+RUN pip3 install flask flask_socketio mmh3 apscheduler
+
 WORKDIR /code
+ADD ./* .
+
+# pjsua2
+RUN  ./configure CFLAGS="-fPIC"
+RUN cd ./pjsip-apps/src/swig/python && make && make install
+# pyESL
+RUN cd /code/python-ESL-1.4.18 && python setup.py install
+# nls
+RUN cd /code/alibabacloud-nls-python-sdk-1.0.2 && pip install -r requirements.txt && python setup.py install
+
+
 
 CMD ["tail", "-f", "/dev/null"]

+ 1 - 1
pjlib/build/os-auto.mak

@@ -24,7 +24,7 @@ export TEST_OBJS +=     main.o
 # Additional LDFLAGS for pjlib-test
 #
 # Disabled, as this causes duplicated LDFLAGS, which may raise linking errors
-#export TEST_LDFLAGS += -fPIC -lssl -lcrypto -luuid -lm -lrt -lpthread  -lasound   -lv4l2
+#export TEST_LDFLAGS +=  -lssl -lcrypto -luuid -lm -lrt -lpthread   
 
 #
 # TARGETS are make targets in the Makefile, to be executed for this given

+ 1 - 1
pjlib/include/pj/compat/m_auto.h

@@ -26,7 +26,7 @@
  */
 
 /* Machine name, filled in by autoconf script */
-#define PJ_M_NAME "aarch64"
+#define PJ_M_NAME "x86_64"
 
 /* Endianness. It's reported on pjsip list on 09/02/13 that autoconf
  * endianness detection failed for universal build, so special case

+ 1 - 1
pjlib/include/pj/compat/os_auto.h

@@ -27,7 +27,7 @@
  */
 
 /* Canonical OS name */
-#define PJ_OS_NAME "aarch64-unknown-linux-gnu"
+#define PJ_OS_NAME "x86_64-unknown-linux-gnu"
 
 /* Legacy macros */
 /* #undef PJ_WIN64 */

+ 4 - 4
pjmedia/build/os-auto.mak

@@ -15,8 +15,8 @@ FFMPEG_CFLAGS =   -DPJMEDIA_USE_OLD_FFMPEG=1
 FFMPEG_LDFLAGS =   
 
 # Video4Linux2
-V4L2_CFLAGS = -DPJMEDIA_VIDEO_DEV_HAS_V4L2=1
-V4L2_LDFLAGS = -lv4l2
+V4L2_CFLAGS = 
+V4L2_LDFLAGS = 
 
 # Directshow
 DSHOW_CFLAGS = 
@@ -58,7 +58,7 @@ export LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) $(DSHOW_LDFLA
 #   - alsa:             Unix ALSA (alsa_dev.c)
 #   - null:             Null sound device (nullsound.c)
 #   - external:         Link with no sounddev (app will provide)
-AC_PJMEDIA_SND=alsa
+AC_PJMEDIA_SND=null
 
 #
 # Codecs
@@ -227,7 +227,7 @@ ifeq (,1)
 export CFLAGS += -DPJMEDIA_HAS_WEBRTC_AEC=0
 else
 export CFLAGS += -DPJMEDIA_HAS_WEBRTC_AEC=1
-ifneq ($(findstring arm,$(neon)),)
+ifneq ($(findstring arm,$(sse2)),)
 export CFLAGS += -DPJMEDIA_WEBRTC_AEC_USE_MOBILE=1
 endif
 

BIN
pjsip-apps/src/swig/python/__pycache__/pjsua2.cpython-39.pyc


BIN
pjsip-apps/src/swig/python/dist/pjsua2-2.14.dev0-py3.9-linux-x86_64.egg


+ 10 - 3
src/core/callcenter/acd.py

@@ -1,17 +1,24 @@
 #!/usr/bin/env python3
 # encoding:utf-8
+import time
+from datetime import datetime
+from src.core.callcenter.call import CallService
 from src.core.callcenter.model import CallInfo
 from apscheduler.schedulers.background import BackgroundScheduler
 
 
 class AcdService:
-    def __init__(self):
+    def __init__(self, client, logger):
+        self.client = client
+        self.logger = logger
+        self.call_service = CallService(client, logger)
         scheduler = BackgroundScheduler()
-        scheduler.add_job(self.try_transfer_agent, 'interval', seconds=5)
+        scheduler.add_job(self.try_transfer_agent, 'interval', seconds=5, max_instances=1)
         scheduler.start()
 
     def transfer_to_agent(self, call_info: CallInfo, device_id, service_id):
         pass
 
     def try_transfer_agent(self):
-        pass
+        time.sleep(10)
+        self.logger.info('come in task %s', datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

+ 6 - 0
src/core/callcenter/cache.py

@@ -52,12 +52,16 @@ def get_call_info_by_device_id(device_id):
 
 # 获取callInfo
 def get_call_info(call_id):
+    if not call_id:
+        return None
     text = redis_handler.get(CALL_INFO + call_id)
     if not text:
         return CallInfo.from_json(text)
 
 
 def remove_call_info(call_id):
+    if not call_id:
+        return None
     call_info = get_call_info(call_id)
     if call_info and call_info.device_info_map:
         for k, v in call_info.device_info_map.items():
@@ -66,6 +70,8 @@ def remove_call_info(call_id):
 
 
 def add_device(device_id, call_id):
+    if not device_id or not call_id:
+        return None
     deviceCall[device_id] = call_id
 
 

+ 3 - 3
src/core/callcenter/call.py

@@ -13,12 +13,12 @@ from src.core.callcenter.snowflake import Snowflake
 
 class CallService:
 
-    def __init__(self):
+    def __init__(self, client, logger):
         worker_id = 1
         data_center_id = 1
+        self.client = client
+        self.logger = logger
         self.snowflake = Snowflake(worker_id, data_center_id)
-        from src.core.server import inbound_client
-        self.client = inbound_client
 
     def call(self, request: MakeCallRequest, agent: AgentInfo):
         call_id = 'C' + self.snowflake.next_id()

+ 4 - 7
src/core/callcenter/esl/client.py

@@ -8,7 +8,6 @@ import mmh3
 import threading
 import traceback
 import concurrent.futures
-from src.core import singleton
 from src.core.callcenter.constant import SK, EMPTY
 from src.core.callcenter.esl.constant.esl_constant import BRIDGE_VARIABLES, BRIDGE, HANGUP, NORMAL_CLEARING, SIP_HEADER, SPACE, SPLIT, SOFIA, \
     ORIGINATE, PARK, SET, EAVESDROP, SMF_ALEG, EXECUTE, PLAYBACK, PAUSE, TRANSFER, UUID_TRANSFER, UUID_BROADCAST, UUID_BREAK, UUID_HOLD, \
@@ -20,19 +19,17 @@ from src.core.callcenter.enumeration import CallCause
 from src.core.callcenter.esl.handler.default_esl_event_handler import DefaultEslEventHandler
 
 
-@singleton
 class InboundClient:
 
-    def __init__(self):
+    def __init__(self, logger):
         self.con = None
         self.thread_num = 32
         self.is_stopping = False
+        self.logger = logger
         self.handler_table = self.scan_esl_event_handlers()
-        self.default_event_handler = DefaultEslEventHandler(self)
+        self.default_event_handler = DefaultEslEventHandler(self, self.logger)
         self.host, self.port, self.password = 'localhost', '8021', '4918257983818884358'
         self.executors = {x: concurrent.futures.ThreadPoolExecutor(max_workers=1) for x in range(self.thread_num)}
-        from src.core.server import app
-        self.logger = app.logger
 
         threading.Thread(target=self.start, args=()).start()
         # gw = CacheUtil.getRouteGetway(saasId)
@@ -54,7 +51,7 @@ class InboundClient:
         handlers = {}
         for _cls in classes:
             items = handlers.get(_cls._esl_event_name, [])
-            items.append(_cls(self))
+            items.append(_cls(self, self.logger))
             handlers[_cls._esl_event_name] = items
         return handlers
 

+ 2 - 2
src/core/callcenter/esl/handler/channel_answer_handler.py

@@ -15,8 +15,8 @@ from src.core.callcenter.model import CallInfo, DeviceInfo, NextCommand
 @EslEventName(CHANNEL_ANSWER)
 class ChannelAnswerHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         call_id = EslEventUtil.getCallId(event)

+ 2 - 2
src/core/callcenter/esl/handler/channel_bridge_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(CHANNEL_BRIDGE)
 class ChannelBridgeHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/channel_hangup_complete_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(CHANNEL_HANGUP_COMPLETE)
 class ChannelHangupCompleteHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 7 - 4
src/core/callcenter/esl/handler/channel_hangup_handler.py

@@ -16,13 +16,16 @@ from src.core.callcenter.model import CallInfo, DeviceInfo, NextCommand
 @EslEventName(CHANNEL_HANGUP)
 class ChannelHangupHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
-        self.acd_service = AcdService()
-        self.call_service = CallService()
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
+        self.acd_service = AcdService(inbound_client, logger)
+        self.call_service = CallService(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         call_id = EslEventUtil.getCallId(event)
+        if not call_id:
+            self.logger.info("call_id is null")
+            return
         call = Cache.get_call_info(call_id)
         if not call:
             self.logger.info("call:{} is null", call_id)

+ 2 - 2
src/core/callcenter/esl/handler/channel_park_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(CHANNEL_PARK)
 class ChannelParkHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         service = event.getHeader("variable_service")

+ 2 - 2
src/core/callcenter/esl/handler/channel_progress_media_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(CHANNEL_PROGRESS_MEDIA)
 class ChannelProgressMediaHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/default_esl_event_handler.py

@@ -8,8 +8,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 
 class DefaultEslEventHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         self.logger.info(json.loads(event.serialize('json')))

+ 2 - 2
src/core/callcenter/esl/handler/detected_tone_handler.py

@@ -10,8 +10,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(DETECTED_TONE)
 class DetectedToneHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/dtmf_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(DTMF)
 class DTMFHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 3
src/core/callcenter/esl/handler/esl_event_handler.py

@@ -5,10 +5,9 @@ from abc import ABC, abstractmethod
 
 
 class EslEventHandler(ABC):
-    def __init__(self, inbound_client):
+    def __init__(self, inbound_client, logger):
         self.inbound_client = inbound_client
-        from src.core.server import app
-        self.logger = app.logger
+        self.logger = logger
 
     @abstractmethod
     def handle(self, address, event, coreUUID):

+ 2 - 2
src/core/callcenter/esl/handler/playback_stop_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(PLAYBACK_STOP)
 class PlaybackStopHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/record_stop_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(RECORD_STOP)
 class RecordStopHandler(EslEventHandler):
 
-    def __init__(self, inbound):
-        super().__init__(inbound)
+    def __init__(self, inbound_client, logger):
+        super().__init__(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 176 - 0
src/core/callcenter/web.py

@@ -0,0 +1,176 @@
+#!/usr/bin/env python3
+# encoding:utf-8
+
+import threading
+from logging.config import dictConfig
+
+from src.core.callcenter.esl.client import InboundClient
+from flask import Flask, render_template_string
+
+from src.core.callcenter.call import CallService
+from src.core.callcenter.model import MakeCallRequest, AgentInfo
+
+dictConfig({
+        "version": 1,
+        "disable_existing_loggers": False,  # 不覆盖默认配置
+        "formatters": {  # 日志输出样式
+            "default": {
+                "format": "%(asctime)s - %(module)s.%(lineno)d - %(levelname)s - %(threadName)s: %(message)s"
+            }
+        },
+        "handlers": {
+            "console": {
+                "class": "logging.StreamHandler",  # 控制台输出
+                "level": "INFO",
+                "formatter": "default",
+            },
+            "log_file": {
+                "class": "logging.handlers.RotatingFileHandler",
+                "level": "INFO",
+                "formatter": "default",   # 日志输出样式对应formatters
+                "filename": "./logs/flask.log",  # 指定log文件目录
+                "maxBytes": 20*1024*1024,   # 文件最大20M
+                "backupCount": 10,          # 最多10个文件
+                "encoding": "utf8",         # 文件编码
+            },
+
+        },
+        "root": {
+            "level": "INFO",  # # handler中的level会覆盖掉这里的level
+            "handlers": ["console", "log_file"],
+        },
+    }
+)
+
+app = Flask(__name__)
+app.config['SECRET_KEY'] = ''
+
+client = InboundClient(app.logger)
+call_service = CallService(client, app.logger)
+
+
+@app.route('/')
+def index():
+    return render_template_string("""<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>SocketIO Example</title>
+    <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
+</head>
+<body>
+    <h1>SocketIO Test</h1>
+    <script>
+        var socket = io('/ws/cs-im');
+        socket.on('response', function(msg) {
+            alert(msg);
+        });
+
+        socket.on('login', function(msg) {
+            alert('Received from server: ' + msg);
+        });
+        socket.emit('login', {'appCode':'1111','userId':'1111','token':'1111'});
+    </script>
+</body>
+</html>""")
+
+
+@app.route('/open/agent/get-cdn-url', methods=['POST'])
+def get_cdn_url():
+    """获取cdn地址"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/get-init-config', methods=['POST'])
+def get_init_config():
+    """获取初始化配置"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/check-in', methods=['POST'])
+def check_in():
+    """坐席签入"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/check-out', methods=['POST'])
+def check_out():
+    """坐席签出"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/busy', methods=['POST'])
+def busy():
+    """坐席置忙"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/idle', methods=['POST'])
+def idle():
+    """坐席置闲"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/turn-on', methods=['POST'])
+def turn_on():
+    """接通"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/hang-up', methods=['POST'])
+def hang_up():
+    """挂断"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/agent-state', methods=['POST'])
+def agent_state():
+    """获取坐席状态"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/manual-call', methods=['POST'])
+def manual_call():
+    """外呼"""
+    request = MakeCallRequest()
+    agent = AgentInfo()
+    call_service.call(request, agent)
+    return 'Hello World!'
+
+
+@app.route('/open/agent/manual-hang', methods=['POST'])
+def manual_hang():
+    """挂断"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/listen', methods=['POST'])
+def listen():
+    """发起监听"""
+    return 'Hello World!'
+
+
+@app.route('/open/agent/reload-phone', methods=['POST'])
+def reload_phone():
+    """重新获取分机信息"""
+    return 'Hello World!'
+
+
+@app.route('/open/monitor/load-agent-group-data', methods=['POST'])
+def load_agent_group_data():
+    """获取监控组成员信息"""
+    return 'Hello World!'
+
+
+@app.route('/open/human-service/member-active', methods=['POST'])
+def member_active():
+    """机器人外呼-签入人工组"""
+    return 'Hello World!'
+
+
+@app.route('/open/num/generate', methods=['POST'])
+def num_generate():
+    """获取 cti 流程 ID"""
+    return 'Hello World!'
+
+

+ 1 - 1
src/core/callcenter/ws.py

@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 # encoding:utf-8
 
-from src.core.server import app
+from src.core.callcenter.web import app
 from flask import request, session
 from flask_socketio import SocketIO, Namespace, join_room, leave_room, emit
 

+ 167 - 173
src/core/server.py

@@ -1,183 +1,177 @@
 #!/usr/bin/env python3
 # encoding:utf-8
-import threading
-
-from logging.config import dictConfig
-from flask import Flask, render_template_string
-
-
-dictConfig({
-        "version": 1,
-        "disable_existing_loggers": False,  # 不覆盖默认配置
-        "formatters": {  # 日志输出样式
-            "default": {
-                "format": "%(asctime)s - %(module)s.%(lineno)d - %(levelname)s - %(threadName)s: %(message)s"
-            }
-        },
-        "handlers": {
-            "console": {
-                "class": "logging.StreamHandler",  # 控制台输出
-                "level": "DEBUG",
-                "formatter": "default",
-            },
-            "log_file": {
-                "class": "logging.handlers.RotatingFileHandler",
-                "level": "INFO",
-                "formatter": "default",   # 日志输出样式对应formatters
-                "filename": "./logs/flask.log",  # 指定log文件目录
-                "maxBytes": 20*1024*1024,   # 文件最大20M
-                "backupCount": 10,          # 最多10个文件
-                "encoding": "utf8",         # 文件编码
-            },
-
-        },
-        "root": {
-            "level": "DEBUG",  # # handler中的level会覆盖掉这里的level
-            "handlers": ["console", "log_file"],
-        },
-    }
-)
-
-
-app = Flask(__name__)
-app.config['SECRET_KEY'] = ''
-
-
-def new_client():
-    from src.core.callcenter.esl.client import InboundClient
-    client = InboundClient()
-    return client
-
-
-inbound_client = new_client()
-
-
-@app.route('/')
-def index():
-    return render_template_string("""<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title>SocketIO Example</title>
-    <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
-</head>
-<body>
-    <h1>SocketIO Test</h1>
-    <script>
-        var socket = io('/ws/cs-im');
-        socket.on('response', function(msg) {
-            alert(msg);
-        });
-
-        socket.on('login', function(msg) {
-            alert('Received from server: ' + msg);
-        });
-        socket.emit('login', {'appCode':'1111','userId':'1111','token':'1111'});
-    </script>
-</body>
-</html>""")
-
-
-@app.route('/open/agent/get-cdn-url', methods=['POST'])
-def get_cdn_url():
-    """获取cdn地址"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/get-init-config', methods=['POST'])
-def get_init_config():
-    """获取初始化配置"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/check-in', methods=['POST'])
-def check_in():
-    """坐席签入"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/check-out', methods=['POST'])
-def check_out():
-    """坐席签出"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/busy', methods=['POST'])
-def busy():
-    """坐席置忙"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/idle', methods=['POST'])
-def idle():
-    """坐席置闲"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/turn-on', methods=['POST'])
-def turn_on():
-    """接通"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/hang-up', methods=['POST'])
-def hang_up():
-    """挂断"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/agent-state', methods=['POST'])
-def agent_state():
-    """获取坐席状态"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/manual-call', methods=['POST'])
-def manual_call():
-    """外呼"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/manual-hang', methods=['POST'])
-def manual_hang():
-    """挂断"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/listen', methods=['POST'])
-def listen():
-    """发起监听"""
-    return 'Hello World!'
-
-
-@app.route('/open/agent/reload-phone', methods=['POST'])
-def reload_phone():
-    """重新获取分机信息"""
-    return 'Hello World!'
-
-
-@app.route('/open/monitor/load-agent-group-data', methods=['POST'])
-def load_agent_group_data():
-    """获取监控组成员信息"""
-    return 'Hello World!'
-
-
-@app.route('/open/human-service/member-active', methods=['POST'])
-def member_active():
-    """机器人外呼-签入人工组"""
-    return 'Hello World!'
-
-
-@app.route('/open/num/generate', methods=['POST'])
-def num_generate():
-    """获取 cti 流程 ID"""
-    return 'Hello World!'
 
+import threading
+# from logging.config import dictConfig
+# from flask import Flask, render_template_string
+#
+#
+# dictConfig({
+#         "version": 1,
+#         "disable_existing_loggers": False,  # 不覆盖默认配置
+#         "formatters": {  # 日志输出样式
+#             "default": {
+#                 "format": "%(asctime)s - %(module)s.%(lineno)d - %(levelname)s - %(threadName)s: %(message)s"
+#             }
+#         },
+#         "handlers": {
+#             "console": {
+#                 "class": "logging.StreamHandler",  # 控制台输出
+#                 "level": "DEBUG",
+#                 "formatter": "default",
+#             },
+#             "log_file": {
+#                 "class": "logging.handlers.RotatingFileHandler",
+#                 "level": "INFO",
+#                 "formatter": "default",   # 日志输出样式对应formatters
+#                 "filename": "./logs/flask.log",  # 指定log文件目录
+#                 "maxBytes": 20*1024*1024,   # 文件最大20M
+#                 "backupCount": 10,          # 最多10个文件
+#                 "encoding": "utf8",         # 文件编码
+#             },
+#
+#         },
+#         "root": {
+#             "level": "DEBUG",  # # handler中的level会覆盖掉这里的level
+#             "handlers": ["console", "log_file"],
+#         },
+#     }
+# )
+#
+#
+# app = Flask(__name__)
+# app.config['SECRET_KEY'] = ''
+#
+#
+# @app.route('/')
+# def index():
+#     return render_template_string("""<!DOCTYPE html>
+# <html lang="en">
+# <head>
+#     <meta charset="UTF-8">
+#     <title>SocketIO Example</title>
+#     <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
+# </head>
+# <body>
+#     <h1>SocketIO Test</h1>
+#     <script>
+#         var socket = io('/ws/cs-im');
+#         socket.on('response', function(msg) {
+#             alert(msg);
+#         });
+#
+#         socket.on('login', function(msg) {
+#             alert('Received from server: ' + msg);
+#         });
+#         socket.emit('login', {'appCode':'1111','userId':'1111','token':'1111'});
+#     </script>
+# </body>
+# </html>""")
+#
+#
+# @app.route('/open/agent/get-cdn-url', methods=['POST'])
+# def get_cdn_url():
+#     """获取cdn地址"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/get-init-config', methods=['POST'])
+# def get_init_config():
+#     """获取初始化配置"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/check-in', methods=['POST'])
+# def check_in():
+#     """坐席签入"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/check-out', methods=['POST'])
+# def check_out():
+#     """坐席签出"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/busy', methods=['POST'])
+# def busy():
+#     """坐席置忙"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/idle', methods=['POST'])
+# def idle():
+#     """坐席置闲"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/turn-on', methods=['POST'])
+# def turn_on():
+#     """接通"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/hang-up', methods=['POST'])
+# def hang_up():
+#     """挂断"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/agent-state', methods=['POST'])
+# def agent_state():
+#     """获取坐席状态"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/manual-call', methods=['POST'])
+# def manual_call():
+#     """外呼"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/manual-hang', methods=['POST'])
+# def manual_hang():
+#     """挂断"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/listen', methods=['POST'])
+# def listen():
+#     """发起监听"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/agent/reload-phone', methods=['POST'])
+# def reload_phone():
+#     """重新获取分机信息"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/monitor/load-agent-group-data', methods=['POST'])
+# def load_agent_group_data():
+#     """获取监控组成员信息"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/human-service/member-active', methods=['POST'])
+# def member_active():
+#     """机器人外呼-签入人工组"""
+#     return 'Hello World!'
+#
+#
+# @app.route('/open/num/generate', methods=['POST'])
+# def num_generate():
+#     """获取 cti 流程 ID"""
+#     return 'Hello World!'
+
+from src.core.callcenter.web import app
+from src.core.callcenter.ws import socketio
+# from src.core.voip.hello import pjsua2_test
 
 if __name__ == '__main__':
+    # threading.Thread(target=pjsua2_test, args=()).start()
     # out = OutboundClient()
     # threading.Thread(target=out.start, args=()).start()
     # threading.Thread(target=on.start, args=()).start()
-    from src.core.callcenter.ws import socketio
     socketio.run(app, host='127.0.0.1', port=5000, allow_unsafe_werkzeug=True, debug=True)
     # app.run(host='127.0.0.1', port=5000, debug=True)

+ 5 - 5
third_party/build/os-auto.mak

@@ -31,7 +31,7 @@ ifneq (,1)
 DIRS += g7221
 endif
 
-ifneq ($(findstring pa,alsa),)
+ifneq ($(findstring pa,null),)
 ifeq (0,1)
 # External PA
 else
@@ -84,15 +84,15 @@ ifeq (0,1)
 # External webrtc
 else
 DIRS += webrtc
-WEBRTC_OTHER_CFLAGS = -fexceptions -DWEBRTC_POSIX=1 -DWEBRTC_ARCH_ARM64
-ifneq ($(findstring sse2,neon),)
+WEBRTC_OTHER_CFLAGS = -fexceptions -DWEBRTC_POSIX=1 
+ifneq ($(findstring sse2,sse2),)
     WEBRTC_SRC = \
     	      modules/audio_processing/aec/aec_core_sse2.o		 \
 	      modules/audio_processing/aec/aec_rdft_sse2.o	         \
 	      modules/audio_processing/aecm/aecm_core_c.o	         \
 	      modules/audio_processing/ns/nsx_core_c.o	                 \
 	      system_wrappers/source/cpu_features.o
-else ifneq ($(findstring neon,neon),)
+else ifneq ($(findstring neon,sse2),)
     WEBRTC_SRC = \
        	      modules/audio_processing/aec/aec_core_neon.o               \
 	      modules/audio_processing/aec/aec_rdft_neon.o               \
@@ -104,7 +104,7 @@ else ifneq ($(findstring neon,neon),)
 	      common_audio/signal_processing/downsample_fast_neon.o      \
 	      common_audio/signal_processing/min_max_operations_neon.o
     WEBRTC_OTHER_CFLAGS += -DWEBRTC_HAS_NEON
-else ifneq ($(findstring mips,neon),)
+else ifneq ($(findstring mips,sse2),)
     WEBRTC_SRC = \
               modules/audio_processing/aec/aec_core_mips.o               \
 	      modules/audio_processing/aec/aec_rdft_mips.o               \

Some files were not shown because too many files changed in this diff