Python Forum
I am a total noob, I need this reworked
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
I am a total noob, I need this reworked
#1
OK so I know enough about Python and that is that I don't know it. I normally install IP phones not program them. Anyuway, I have been looking all over for a script to tell my phones where the server is at when they boot. When they boot they multicast on 224.0.1.75 port 5060 with a request for a provisioning server. The server would respond with a message where the server is located. I found this Python script and I tried to set it to my phones but to no avail. The first two octets of my MAC addresses are 80:82 The phones are Atcom. When I run this script it shows that it is listening (well I get no errors) but there are no responses to the phones. Can someone look at this and help me getting this working? It originally was created for snom phones. The original creater I cannot get to respond to email requests. Thanks
[inline]#! /usr/bin/python
#
# snom multicast telephone discovery
#
#
# Author: Filip Polsakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import socket
import struct
import sys
import re

from optparse import OptionParser

class snom_phone(object):
"""Basic representation of a snom phone."""

def __init__(self, mac=None, ip=None, mod=None, fw=None, subs=None):
"""Default constructor."""
self.mac_addr = mac
self.ip_addr = ip
self.sip_port = 5060
self.model = mod
self.fw_version = fw
self.subscribe = subs

def __repr__(self):
"""Gets a string representation of the phone"""
return "%s (MAC: %s) running Firmware %s found at IP %s" % (self.model, self.__macrepr(self.mac_addr), self.fw_version, self.ip_addr)

def __macrepr(self, m):
""" Normalize a MAC address to lower case unix style """
m = re.sub("[.:-]", "", m)
m = m.lower()
n = "%s:%s:%s:%s:%s:%s" % (m[0:2], m[2:4], m[4:6], m[6:8], m[8:10], m[10:])
return n

def parse(text):
"""Parses the incoming SUBSCRIBE."""
try:
lines = text.split('\r\n')

# Line 1 conatains the SUBSCRIBE and our MAC
new_phone = atcomtec(subs=text)
new_phone.mac_addr = lines[0][80:82]

# We can read the IP address from line 2
new_phone.ip_addr = lines[1][17:].split(';')[0].split(':')[0]
new_phone.sip_port = lines[1][17:].split(';')[0].split(':')[1]

# The other interesting information can be found in line 7
model_info = lines[6]
l_model_info = model_info.split(';')
new_phone.model = l_model_info[3].split('=')[1][1:-1]
new_phone.fw_version = l_model_info[4].split('=')[1][1:-1]
print new_phone

return new_phone
except:
# Parsing failed. Probably not a SUBSCRIBE
return None


def get_sip_info(text):
"""Get some relevant SIP information which we need in order to generate the responses."""

lines = text.split('\r\n')
# Some SIP info we need
call_id = lines[4][9:]
cseq = lines[5][6]
via_header = lines[1]
from_header = lines[2]
to_header = lines[3]

if options.verbose: print "CallId: " + call_id + "; CSeq: " + cseq + "\r\n";
return (call_id, cseq, via_header, from_header, to_header)

def get_ip_address():
# This is a simple hack to find our IP address
# AFAIK this is the only platform-independent way to obtain the address

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('snom.com', 0))
return s.getsockname()[0]

prov_uri = None
parser = OptionParser()
parser.add_option('-u', '--url', action="store", dest="prov_uri", help="URI of the provisioning server")
parser.add_option('-l', '--local-ip', action="store", dest="local_ip", help="Local IP address")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
help="make lots of noise")

(options, args) = parser.parse_args()



print "Nimbus PnP Provisioning Server\n"

print "Provisioning URI is %s\n" % options.prov_uri

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('224.0.1.75', 5060))
mreq = struct.pack('4sl', socket.inet_aton('224.0.1.75'), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
if not options.local_ip:
ip_adr = get_ip_address()
else:
ip_adr = options.local_ip

print "Local IP Address is :: %s" % ip_adr
print "=" * 80

while True:
subs = sock.recv(10240)

if options.verbose: print subs

phone = parse(subs)
(call_id, cseq, via_header, from_header, to_header) = get_sip_info(subs)

if phone:
# Create a socket to send data
sendsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sendsock.bind(('%s' % ip_adr, 1036))

# If a phone has been recognized first send 200 OK
ok_response = "SIP/2.0 200 OK\r\n"
ok_response += via_header + "\r\n"
ok_response += "Contact: <sip:" + phone.ip_addr + ":" + phone.sip_port + ";transport=tcp;handler=dum>\r\n"
ok_response += to_header + "\r\n"
ok_response += from_header + "\r\n"
ok_response += "Call-ID: %s\r\n" % call_id
ok_response += "CSeq: %s SUBSCRIBE\r\nExpires: 0\r\nContent-Length: 0\r\n" % cseq

sendsock.sendto(ok_response, ("%s" % phone.ip_addr, int(phone.sip_port)))

# Now send a NOTIFY with the configuration URL

if not options.prov_uri:
prov_uri = "tftp://192.168.0.20"
else:
prov_uri = options.prov_uri
prov_uri = "%s/%s.htm" % (prov_uri,phone.model)

notify = "NOTIFY sip:%s:%s SIP/2.0\r\n" % (phone.ip_addr, phone.sip_port)
notify += via_header + "\r\n"
notify += "Max-Forwards: 20\r\n"
notify += "Contact: <sip:%s:1036;transport=TCP;handler=dum>\r\n" % ip_adr
notify += to_header + "\r\n"
notify += from_header + "\r\n"
notify += "Call-ID: %s\r\n" % call_id
notify += "CSeq: 3 NOTIFY\r\n"
notify += "Content-Type: application/url\r\n"
notify += "Subscription-State: terminated;reason=timeout\r\n"
notify += "Event: ua-profile;profile-type=\"device\";vendor=\"OEM\";model=\"OEM\";version=\"7.1.19\"\r\n"
notify += "Content-Length: %i\r\n" % (len(prov_uri))
notify += "\r\n%s" % prov_uri

print "Sending NOTIFY with URI :: %s\n" % prov_uri
if options.verbose: print notify
sendsock.sendto(notify, ("%s" % phone.ip_addr, int(phone.sip_port)))
[/inline]
Reply


Messages In This Thread
I am a total noob, I need this reworked - by edlentz - Oct-06-2017, 07:09 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020