first commit
This commit is contained in:
commit
876d8d17dc
3 changed files with 844 additions and 0 deletions
216
.gitignore
vendored
Normal file
216
.gitignore
vendored
Normal 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
16
README.md
Normal 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
612
sipproxy
Executable 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()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue