diff --git a/baresipy/__init__.py b/baresipy/__init__.py index 127bd84..3b422b0 100644 --- a/baresipy/__init__.py +++ b/baresipy/__init__.py @@ -20,8 +20,8 @@ class BareSIP(Thread): - def __init__(self, user, pwd, gateway, transport="udp", tts=None, debug=False, - block=True, config_path=None, sounds_path=None): + def __init__(self, user, pwd, gateway, transport="udp", other_sip_configs="", tts=None, debug=False, + block=True, config_path=None, sounds_path=None, auto_start_process=True): config_path = config_path or join("~", ".baresipy") self.config_path = expanduser(config_path) if not isdir(self.config_path): @@ -62,12 +62,8 @@ def __init__(self, user, pwd, gateway, transport="udp", tts=None, debug=False, self.pwd = pwd self.gateway = gateway self.transport = transport - if tts: - self.tts = tts - else: - self.tts = ResponsiveVoice(gender=ResponsiveVoice.MALE) - self._login = "sip:{u}@{g};transport={t};auth_pass={p}".format(u=self.user, p=self.pwd, - g=self.gateway, t=self.transport) + self.block = block + self.started_once = False self._prev_output = "" self.running = False self.ready = False @@ -77,10 +73,28 @@ def __init__(self, user, pwd, gateway, transport="udp", tts=None, debug=False, self._call_status = None self.audio = None self._ts = None - self.baresip = pexpect.spawn('baresip -f ' + self.config_path) + self.baresip = None + + if tts: + self.tts = tts + else: + self.tts = ResponsiveVoice(gender=ResponsiveVoice.MALE) + self._server = "sip:{u}@{g}".format(u=self.user, g=self.gateway) + self._login = self._server + ";transport={t};auth_pass={p};{o};".format( + p=self.pwd, t=self.transport, o=other_sip_configs + ).replace(';;', ';').rstrip(';') + + if auto_start_process: + self.start_process() + + def start_process(self): + if self.started_once: + LOG.error('Python Thread Instance cannot be started more than once. Please create a new BareSIP instance') + return + self.started_once = True super().__init__() self.start() - if block: + if self.block: self.wait_until_ready() # properties @@ -104,6 +118,10 @@ def do_command(self, action): def login(self): LOG.info("Adding account: " + self.user) self.baresip.sendline("/uanew " + self._login) + + def logout(self): + LOG.info("Removing account: " + self.user) + self.baresip.sendline("/uadelall") def call(self, number): LOG.info("Dialling: " + number) @@ -165,23 +183,34 @@ def check_call_status(self): self.do_command("/callstat") sleep(0.1) return self.call_status + + def killBareSIPSubProcess(self): + if self.baresip != None and self.baresip.isalive(): + LOG.info("Killing BareSip process") + self.baresip.sendline("/quit") + self.baresip.close() + self.baresip.kill(signal.SIGKILL) + self.baresip = None # this would prompt the run() loop to call startBareSIPProcess + + def startBareSIPSubProcess(self): + LOG.info("Starting BareSip process") + self.baresip = pexpect.spawn('baresip -f ' + self.config_path) def quit(self): if self.updated_config: LOG.info("restoring original config") with open(join(self.config_path, "config"), "w") as f: f.write(self._original_config) - LOG.info("Exiting") + LOG.info("Closing BareSIP instance") if self.running: if self.current_call: self.hang() - self.baresip.sendline("/quit") - self.running = False - self.current_call = None - self._call_status = None - self.abort = True - self.baresip.close() - self.baresip.kill(signal.SIGKILL) + + self.killBareSIPSubProcess() + self.current_call = None + self._call_status = None + self.abort = True + self.running = False def send_dtmf(self, number): number = str(number) @@ -334,6 +363,14 @@ def run(self): self.running = True while self.running: try: + if self.baresip == None: + self.startBareSIPSubProcess() + continue + if not self.baresip.isalive(): + self.killBareSIPSubProcess() + sleep(0.5) + continue + out = self.baresip.readline().decode("utf-8") if out != self._prev_output: @@ -344,7 +381,8 @@ def run(self): self.handle_ready() elif "account: No SIP accounts found" in out: self._handle_no_accounts() - elif "All 1 useragent registered successfully!" in out: + # elif "All 1 useragent registered successfully!" in out or\ + elif "200 OK" in out: self.ready = True self.handle_login_success() elif "ua: SIP register failed:" in out or\ @@ -445,6 +483,9 @@ def run(self): pass except KeyboardInterrupt: self.running = False + except: + # Uncaught Exception. Gracefully quit + self.running = False self.quit()