first commit

This commit is contained in:
Wonko the Sane 2021-07-10 14:17:24 +01:00
commit 876d8d17dc
3 changed files with 844 additions and 0 deletions

216
.gitignore vendored Normal file
View file

@ -0,0 +1,216 @@
# Created by https://www.toptal.com/developers/gitignore/api/python,emacs,git
# Edit at https://www.toptal.com/developers/gitignore?templates=python,emacs,git
### Emacs ###
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
dist/
# Flycheck
flycheck_*.el
# server auth directory
/server/
# projectiles files
.projectile
# directory configuration
.dir-locals.el
# network security
/network-security.data
### Git ###
# Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false
*.orig
# Created by git when using merge tools for conflicts
*.BACKUP.*
*.BASE.*
*.LOCAL.*
*.REMOTE.*
*_BACKUP_*.txt
*_BASE_*.txt
*_LOCAL_*.txt
*_REMOTE_*.txt
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# End of https://www.toptal.com/developers/gitignore/api/python,emacs,git
# pyenv bits
.python-version
# things truck adds for WingIDE
# which he has forgotten and will add later.

16
README.md Normal file
View file

@ -0,0 +1,16 @@
The new and improved python3 version is here!
Because as we all know, python2 is the work of the devil, a major contributor to global warming
and is probably responsible for the death of Jesus.
Installing.
Find a nice place to put the file 'sipproxy', preferrably in a directory of its own.
cd to that directory in a terminal/console/xterm and invoke the program by typing ./sipproxy
It is purposely verbose, and will display a running commentary on what is happening.
During this first run, the config file will be created as conf/config.conf and the phone book
will be created as conf/addressbook.conf; (Both of these files require editing, and a great
deal of effort has been put into using the right number words to enable the user to understand
what is required, without competing with 'War & Peace').

612
sipproxy Executable file
View file

@ -0,0 +1,612 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#import sys first so that if we bale in the following try we can still exit clean.
import sys
try:
# twisted imports
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
# system imports
import codecs
import os
import re
import signal
import socket
import syslog
import time
except ImportError:
print("Some modules missing: requires Twisted among others.\n")
sys.exit(1)
##################################################################
os.chdir(os.path.dirname(__file__))
BaseDir = os.getcwd()
CRLF = "\r\n"
confdir = "conf"
conffile = "config.conf"
config = "/" + confdir + "/" + conffile
phonebookfile = BaseDir + "/" + confdir + "/addressbook.conf"
ITSP = "127.0.0.1"
##################################################################
def ReadConfig():
print("Read config")
try:
with codecs.open(BaseDir + config, 'r', encoding='utf-8') as configfile:
for line in configfile:
preconf(line)
except:
print("Error reading " + BaseDir + config + "\nAborting")
def CreateConfig():
print("Not found.\n")
print("Checking that " + BaseDir + "/" + confdir + " exists")
if (os.path.isdir(BaseDir + "/" + confdir) == False):
print("No. Attempting to create " + BaseDir + "/" + confdir)
try:
os.mkdir(BaseDir + "/" + confdir)
print("Success\n")
except OSError as e:
print("Can\'t create " + BaseDir + "/" + confdir)
print(e)
sys.exit(1)
except IOError as e:
print("Can\'t create " + BaseDir + "/" + confdir)
print(e)
sys.exit(1)
else:
print("Yes.")
print("Attempting to write configuration file " + BaseDir + config)
try:
fh = codecs.open(BaseDir + config, 'w', encoding='utf-8')
fh.write('\n')
except IOError as e:
print("Error: can\'t write file - " + BaseDir + config)
print(e)
sys.exit(1)
except OSError as e:
print("Error: can\'t write file - " + BaseDir + config)
print(e)
sys.exit(1)
else:
fh.close()
with codecs.open(BaseDir + config, 'w', encoding='utf-8') as configfile:
configfile.write("# This software was written as a shim for a Grandstream Budget One VOIP telephone\r")
configfile.write(" operating on an ipv4 lan, to add a phone book and get around the UDP NAT problem.\r")
configfile.write(" consequently it does not require a stun server or other black magic to operate.\r")
configfile.write(" It will probably work with other VOIP telephones\n")
configfile.write("# Prerequisites.\r")
configfile.write(" A VOIP telephone\r")
configfile.write(" A computer on which to run, that has either direct access to the Internet, or has\r")
configfile.write(" the following 3 UDP ports portforwarded from something that does.\r")
configfile.write(" 5060, 11110, and 11111\n")
configfile.write("# The important settings in your VOIP telephone are :- \n")
configfile.write(" IP address:\r")
configfile.write(" SIP Server:\r")
configfile.write(" Outbound Proxy:\r")
configfile.write(" local RTP port:\r")
configfile.write("# These must match up with the settings below or it just won\'t work \n")
configfile.write("# In this configuration file, there are no defaults,\r")
configfile.write("# lines beginning with white space are comments\r")
configfile.write(" Anything after a # is a comment\n")
configfile.write(" The configuration lines must begin in column 1\r")
configfile.write(" so each of the following lines needs a value.\n\n")
configfile.write("LocalPhoneIP = 192.168.0.42 # ip address of the VOIP telephone\n")
configfile.write("LocalPhonePort = 5004 # local RTP port: in the telephone's setup menu\n")
configfile.write("ThisBoxIP = 192.168.0.69 # the Internet connected box I am running on\r")
configfile.write(" this is also the Outbound Proxy: in your telephone's setup.\n")
configfile.write("PublicIP = 127.0.0.1 # Where the sip provider will send your incoming calls\n")
configfile.write("ITSP = sip.sipdiscount.com # (Internet Telephone Service Provider)\r")
configfile.write(" this the same as SIP Server: in your telephone\'s setup.\n")
configfile.write("UserID = bob_smith # SIP User ID: in your telephone\'s setup. This is used to \r")
configfile.write(" prevent random idiots making your phone ring whilst unsuccessfully\r")
configfile.write(" trying to steal your bandwidth/services.\n")
configfile.write("logfile = /var/log/phone.log # needs root to write to /var/log so use a file you have actual\r")
configfile.write(" permission to write to.\n")
configfile.write(" \n")
configfile.write(" \n")
print("Config file " + BaseDir + config + " successfully written.")
print("Additionally, " + BaseDir + config + " will require editing before you can continue.")
def preconf(line):
global LocalPhoneIP
global LocalPhonePort
global ThisBoxIP
global PublicIP
global ITSP
global UserID
global logfile
if(line[:12] == u"LocalPhoneIP"):
LocalPhoneIP = line.split("=")[1].strip()
LocalPhoneIP = LocalPhoneIP.split("#")[0].strip()
print("LocalPhoneIP = " + LocalPhoneIP)
if(line[:14] == u"LocalPhonePort"):
LocalPhonePort = line.split("=")[1].strip()
LocalPhonePort = LocalPhonePort.split("#")[0].strip()
print("LocalPhonePort = " + LocalPhonePort)
if(line[:9] == u"ThisBoxIP"):
ThisBoxIP = line.split("=")[1].strip()
ThisBoxIP = ThisBoxIP.split("#")[0].strip()
print("ThisBoxIP = " + ThisBoxIP)
if(line[:8] == u"PublicIP"):
PublicIP = line.split("=")[1].strip()
PublicIP = PublicIP.split("#")[0].strip()
print("PublicIP = " + PublicIP)
if(line[:4] == u"ITSP"):
ITSP = line.split("=")[1].strip()
ITSP = ITSP.split("#")[0].strip()
print("ITSP = " + ITSP)
if(line[:6] == u"UserID"):
UserID = line.split("=")[1].strip()
UserID = UserID.split("#")[0].strip()
print("UserID = " + UserID)
if(line[:7] == u"logfile"):
logfile = line.split("=")[1].strip()
logfile = logfile.split("#")[0].strip()
print("logfile = " + logfile)
def isip(addr):
try:
socket.inet_aton(addr)
return True
except socket.error:
return False
##################################################################
#variable
BookList = []
Destination = "127.0.0.1"
Remote_Audio_IP = "127.0.0.1"
Remote_Audio_Port = "61110"
Local_Audio_IP = "127.0.0.1"
Local_Audio_Port = "61110"
register_regex = 'CSeq: (.+?) REGISTER'
inviteSD_regex = 'INVITE sip:(.+?)@sipdiscount.com SIP/2'
register_pattern=re.compile(register_regex, flags=re.IGNORECASE)
inviteSD_pattern=re.compile(inviteSD_regex, flags=re.IGNORECASE)
##################################################################
class Sip(DatagramProtocol):
def datagramReceived(self, data, addr):
global Destination
try:
data = data.decode()
except UnicodeDecodeError as e:
print("random shite detected from " + addr[0])
print(e)
return
Time = time.strftime("%Y-%m-%d %H:%M:%S")
reg = re.findall(register_pattern,data)
if reg:
Destination = ITSP # Registration always with ITSP
print(Time, "From:", addr[0])
print(data[:12])
else:
try:
syslog.syslog("From " + addr[0])
syslog.syslog(data)
print(Time, "From:", addr[0])
print(data)
except TypeError:
syslog.syslog("TypeError")
print(Time, "TypeError:")
tdata = Proxy(data, addr)
if (addr[0] == LocalPhoneIP):
reg = re.findall(register_pattern,tdata)
if reg:
Destination = ITSP # Registration always with ITSP
self.transport.write(tdata.encode(), (Destination, 5060))
print(tdata[:12])
else:
syslog.syslog("To " + Destination)
syslog.syslog(tdata)
print(Time, "To:", Destination)
self.transport.write(tdata.encode(), (Destination, 5060))
print(tdata)
else:
if (addr[0] != LocalPhoneIP):
Logit(Time + " From ip: " + addr[0] + " " + data)
if (UserID in data):
Destination = addr[0]
reg = re.findall(register_pattern,tdata)
if reg:
self.transport.write(tdata.encode(), (LocalPhoneIP, 5060))
print(tdata[:12])
else:
syslog.syslog("To " + LocalPhoneIP)
syslog.syslog(tdata)
print(Time, "To:", LocalPhoneIP)
self.transport.write(tdata.encode(), (LocalPhoneIP, 5060))
print(tdata)
else:
Logit(Time + " From ip: " + addr[0] + " " + tdata)
##################################################################
def Proxy(data, addr):
if (addr[0] == LocalPhoneIP):
tdata = FromLocal(data, addr)
else:
tdata = FromRemote(data, addr)
if ("m=audio" in tdata):
return(tdata.strip() + CRLF)
else:
return(tdata.strip() + CRLF + CRLF)
##################################################################
def FromRemote(data, addr):
global Remote_Audio_IP # spurious, probably unneeded
data = data.replace(PublicIP, LocalPhoneIP)
data = data.replace(addr[0], ThisBoxIP)
data = Remote_SDP_Edit(data)
return data
##################################################################
def FromLocal(data, addr):
global Destination
data = FoneBook(data)
# Too many bugs, needs thinking about.
# reg = re.findall(register_pattern,data)
# if reg:
# Destination = ITSP
# print("Destination is " + Destination)
# data = data.replace(addr[0], PublicIP)
# data = Local_SDP_Edit(data)
# return data
#
# sd = re.findall(inviteSD_pattern,data)
# if sd:
# Destination = ITSP
# print("Destination is " + Destination)
# else:
# if ("INVITE sip:" in data):
# begin = data.find("@")
# begin = begin + 1
# nigeb = data.find(" ", begin)
# Destination = data[begin:nigeb]
# Destination = Destination.split(':')[0]
# print("Destination is " + Destination)
#
# if isip(Destination) == False:
# Destination = socket.gethostbyname(Destination)
#
# print("Destination is " + Destination)
data = data.replace(addr[0], PublicIP)
data = Local_SDP_Edit(data)
# print(data)
return data
##################################################################
class OutRTP(DatagramProtocol):
def datagramReceived(self, data, addr):
global Remote_Audio_IP
global Remote_Audio_Port
if (addr[0] == LocalPhoneIP):
dst = ((Remote_Audio_IP, int(Remote_Audio_Port)))
else:
dst = ((LocalPhoneIP, int(LocalPhonePort)))
self.transport.write(data, dst)
##################################################################
class OutRTCP(DatagramProtocol):
def datagramReceived(self, data, addr):
global Remote_Audio_IP
global Remote_Audio_Port
if (addr[0] == LocalPhoneIP):
dst = ((Remote_Audio_IP, int(Remote_Audio_Port) + 1))
else:
dst = ((LocalPhoneIP, (int(LocalPhonePort) + 1)))
self.transport.write(data, dst)
##################################################################
def FoneBook(data):
for line in BookList:
if (line.split("=")[0] in data):
data = data.replace(line.split("=")[0],line.split("=")[1])
return data
##################################################################
def Local_SDP_Edit(data): #fiddle with data from localphone
global Local_Audio_IP
global Local_Audio_Port
if ("m=audio" in data):
PortA = data.split("m=audio ")[1]
Local_Audio_Port = PortA.split()[0]
IPA = data.split("c=IN IP4 ")[1]
Local_Audio_IP = IPA.split()[0]
data = data.replace("m=audio " + Local_Audio_Port, "m=audio 11110")
data = data.replace("IN IP4 " + Local_Audio_IP, "IN IP4 " + PublicIP)
First = data.split("Content-Length: ")[0] + "Content-Length: "
Second = data.split(CRLF + CRLF)[1]
ilength = len(Second)
return First + str(ilength) + CRLF + CRLF + Second
else:
return data
##################################################################
def Remote_SDP_Edit(data): #fiddle with data from remotephone
global Remote_Audio_IP
global Remote_Audio_Port
if ("m=audio" in data):
PortA = data.split("m=audio ")[1]
Remote_Audio_Port = PortA.split()[0]
IPA = data.split("c=IN IP4 ")[1]
Remote_Audio_IP= IPA.split()[0]
data = data.replace("m=audio " + Remote_Audio_Port, "m=audio 11110")
data = data.replace("IN IP4 " + Remote_Audio_IP, "IN IP4 " + ThisBoxIP)
First = data.split("Content-Length: ")[0] + "Content-Length: "
Second = data.split(CRLF + CRLF)[1]
ilength = len(Second)
return First + str(ilength) + CRLF + CRLF + Second
else:
return data
##################################################################
def signal_handler(sig, frame):
print
print("signal", sig)
Time = time.strftime("%Y-%m-%d %H:%M:%S")
print(Time, "Shutting down")
reactor.stop()
print('reactor stopped')
syslog.syslog("SIGINT - Shutting Down!")
os._exit(0)
syslog.syslog("Not Visible in syslog.")
quit()
##################################################################
def MkFoneBook():
Blurb001 = "# This fonebook is crude, the error checking is minimal, so if you screw it up, then it wont work.\n"
Blurb002 = "# However, if you delete the screwed up copy, the basic file will be recreated by SipProxy.\n\n"
Blurb003 = "# Lines beginning with # are ignored, as are lines consisting solely of whitespace and blank lines.\n#\n"
Blurb004 = "#Replace=With\n"
Blurb005 = "#01* Geographic area codes.\n"
Blurb006 = "INVITE sip:01=INVITE sip:00441\n"
Blurb007 = "ACK sip:01=ACK sip:00441\n"
Blurb008 = "BYE sip:01=BYE sip:00441\n"
Blurb009 = "CANCEL sip:01=CANCEL sip:00441\n\n"
Blurb010 = "#02* Geographic area codes (introduced in 2000).\n"
Blurb011 = "INVITE sip:02=INVITE sip:00442\n"
Blurb012 = "ACK sip:02=ACK sip:00442\n"
Blurb013 = "BYE sip:02=BYE sip:00442\n"
Blurb014 = "CANCEL sip:02=CANCEL sip:00442\n\n"
Blurb015 = "#03* Nationwide non-geographic code, charged to caller at geographic area code rates (introduced 2007).\n"
Blurb016 = "INVITE sip:03=INVITE sip:00443\n"
Blurb017 = "ACK sip:03=ACK sip:00443\n"
Blurb018 = "BYE sip:03=BYE sip:00443\n"
Blurb019 = "CANCEL sip:03=CANCEL sip:00443\n\n"
Blurb020 = "#05* Corporate numbering and VoIP services\n"
Blurb021 = "INVITE sip:05=INVITE sip:00445\n"
Blurb022 = "ACK sip:05=ACK sip:00445\n"
Blurb023 = "BYE sip:05=BYE sip:00445\n"
Blurb024 = "CANCEL sip:05=CANCEL sip:00445\n\n"
Blurb025 = "#07* Mostly for mobile phones\n"
Blurb026 = "INVITE sip:07=INVITE sip:00447\n"
Blurb027 = "ACK sip:07=ACK sip:00447\n"
Blurb028 = "BYE sip:07=BYE sip:00447\n"
Blurb029 = "CANCEL sip:07=CANCEL sip:00447\n\n"
Blurb030 = "#08* Freephone (toll free) on 080, and Special Services (formerly known as local and national rate) on 084 and 087.\n"
Blurb031 = "INVITE sip:08=INVITE sip:00448\n"
Blurb032 = "ACK sip:08=ACK sip:00448\n"
Blurb033 = "BYE sip:08=BYE sip:00448\n"
Blurb034 = "CANCEL sip:08=CANCEL sip:00448\n\n"
Blurb035 = "#The following numbers are for Scunthorpe (01724) local numbers.\n"
Blurb036 = "INVITE sip:2=INVITE sip:004417242\n"
Blurb037 = "ACK sip:2=ACK sip:004417242\n"
Blurb038 = "BYE sip:2=BYE sip:004417242\n"
Blurb039 = "CANCEL sip:2=CANCEL sip:004417242\n\n"
Blurb040 = "INVITE sip:3=INVITE sip:004417243\n"
Blurb041 = "ACK sip:3=ACK sip:004417243\n"
Blurb042 = "BYE sip:3=BYE sip:004417243\n"
Blurb043 = "CANCEL sip:3=CANCEL sip:004417243\n\n"
Blurb044 = "INVITE sip:7=INVITE sip:004417247\n"
Blurb045 = "ACK sip:7=ACK sip:004417247\n"
Blurb046 = "BYE sip:7=BYE sip:004417247\n"
Blurb047 = "CANCEL sip:7=CANCEL sip:004417247\n\n"
Blurb048 = "INVITE sip:8=INVITE sip:004417248\n"
Blurb049 = "ACK sip:8=ACK sip:004417248\n"
Blurb050 = "BYE sip:8=BYE sip:004417248\n"
Blurb051 = "CANCEL sip:8=CANCEL sip:004417248\n\n"
Blurb052 = "# Here can be placed upto 100, 3 digit, speed dial shortcuts, from 100 to 199.\n"
Blurb053 = "# Each entry is a pair of lines, firstly the #speed dial number and description.\n"
Blurb054 = "# Secondly the 'Replace=With' for the preceeding line.\n\n"
Blurb0541 = "# As far as the telephone is concerned, all traffic goes to sipdiscount.com\n"
Blurb0542 = "# so if we want it go elsewhere we need to check the destination after the phonebook\n"
Blurb0543 = "# has fiddled with it and set the destination accordingly.\n\n"
Blurb055 = "#100 Example speed dial 1\n"
Blurb056 = "INVITE sip:100@sip.sipdiscount.com=INVITE sip:00441724280280@sip.sipdiscount.com\n"
Blurb057 = "ACK sip:100@sip.sipdiscount.com=ACK sip:00441724280280@sip.sipdiscount.com\n"
Blurb058 = "BYE sip:100@sip.sipdiscount.com=BYE sip:00441724280280@sip.sipdiscount.com\n"
Blurb059 = "CANCEL sip:100@sip.sipdiscount.com=CANCEL sip:00441724280280@sip.sipdiscount.com\n\n"
Blurb060 = "#101 Example speed dial 2\n"
Blurb061 = "INVITE sip:101@sip.sipdiscount.com=INVITE sip:00441724855555@sip.sipdiscount.com\n"
Blurb062 = "ACK sip:101@sip.sipdiscount.com=ACK sip:00441724855555@sip.sipdiscount.com\n"
Blurb063 = "BYE sip:101@sip.sipdiscount.com=BYE sip:00441724855555@sip.sipdiscount.com\n"
Blurb064 = "CANCEL sip:101@sip.sipdiscount.com=CANCEL sip:00441724855555@sip.sipdiscount.com\n"
try:
fh = codecs.open(phonebookfile, 'w', encoding='utf-8')
fh.write(Blurb001)
fh.write(Blurb002)
fh.write(Blurb003)
fh.write(Blurb004)
fh.write(Blurb005)
fh.write(Blurb006)
fh.write(Blurb007)
fh.write(Blurb008)
fh.write(Blurb009)
fh.write(Blurb010)
fh.write(Blurb011)
fh.write(Blurb012)
fh.write(Blurb013)
fh.write(Blurb014)
fh.write(Blurb015)
fh.write(Blurb016)
fh.write(Blurb017)
fh.write(Blurb018)
fh.write(Blurb019)
fh.write(Blurb020)
fh.write(Blurb021)
fh.write(Blurb022)
fh.write(Blurb023)
fh.write(Blurb024)
fh.write(Blurb025)
fh.write(Blurb026)
fh.write(Blurb027)
fh.write(Blurb028)
fh.write(Blurb029)
fh.write(Blurb030)
fh.write(Blurb031)
fh.write(Blurb032)
fh.write(Blurb033)
fh.write(Blurb034)
fh.write(Blurb035)
fh.write(Blurb036)
fh.write(Blurb037)
fh.write(Blurb038)
fh.write(Blurb039)
fh.write(Blurb040)
fh.write(Blurb041)
fh.write(Blurb042)
fh.write(Blurb043)
fh.write(Blurb044)
fh.write(Blurb045)
fh.write(Blurb046)
fh.write(Blurb047)
fh.write(Blurb048)
fh.write(Blurb049)
fh.write(Blurb050)
fh.write(Blurb051)
fh.write(Blurb052)
fh.write(Blurb053)
fh.write(Blurb054)
fh.write(Blurb0541)
fh.write(Blurb0542)
fh.write(Blurb0543)
fh.write(Blurb055)
fh.write(Blurb056)
fh.write(Blurb057)
fh.write(Blurb058)
fh.write(Blurb059)
fh.write(Blurb060)
fh.write(Blurb061)
fh.write(Blurb062)
fh.write(Blurb063)
fh.write(Blurb064)
except IOError:
pass
else:
print("Phone book written")
print("The phone book will need to be edited to create your speed dial")
print("shortcuts and to map your local exchange. This is not absolutely")
print("necessary immediately, and sipproxy will still function regardless.")
fh.close()
##################################################################
def Logit(Blurb):
try:
fh = codecs.open(logfile, 'a', encoding='utf-8')
Blurb = Blurb.replace("\n","\\n")
Blurb = Blurb.replace("\r","\\r")
fh.write(Blurb)
fh.write("\n")
except IOError:
pass
else:
fh.close()
##################################################################
def ReadFoneBook():
global BookList
try:
with codecs.open(phonebookfile, 'r', encoding='utf-8') as config:
for line in config:
if line[:1] != "#" and line.strip() != "":
BookList.append(line.strip())
except IOError:
pass
##################################################################
print("\n\n\n\n\n\n")
print(" ____ ____")
print(" / ___) _ ____ | _ \\")
print("( (___ (_)| _ \| |_) )_ __ ___ __ ____ __")
print(" \__ \| || |_) | __/| '__/ _ \\\ \/ /\ \/ /")
print(" ___) | || __/| | | | ( (_) )> < \ / ")
print("(_____/|_||_| |_| |_| \___//_/\_\ /_/ ")
print("\n\n\n\n\n\n")
print("The all new and improved sipproxy running under Python " + (sys.version))
print("Initialising " + __file__)
print("Looking for " + BaseDir + config)
if os.path.isfile(BaseDir + config):
result = ReadConfig()
else:
result = CreateConfig()
if os.path.isfile(phonebookfile):
print("Phone book already exists, not overwriting")
sys.exit(0)
else:
result = MkFoneBook()
sys.exit(0)
if isip(ITSP) == False:
Destination = socket.gethostbyname(ITSP)
ITSP = Destination
print("ITSP = " + Destination)
else:
Destination = ITSP
if os.path.isfile(phonebookfile):
result = ReadFoneBook()
else:
result = MkFoneBook()
signal.signal(signal.SIGINT, signal_handler)
Time = time.strftime("%Y-%m-%d %H:%M:%S")
print(Time, "Everything started up")
Logit(Time + "Started up OK")
syslog.syslog("Everything started up")
reactor.listenUDP(5060, Sip())
reactor.listenUDP(11110, OutRTP())
reactor.listenUDP(11111, OutRTCP())
reactor.run()