Skip to content

Commit

Permalink
Add support for Cisco phones 79xx
Browse files Browse the repository at this point in the history
  • Loading branch information
JonatanGarbuyo committed Aug 23, 2023
1 parent e6de8f5 commit d7dac86
Show file tree
Hide file tree
Showing 4 changed files with 582 additions and 38 deletions.
71 changes: 71 additions & 0 deletions setup/db/update/endpointconfig/version_sql/10_4.0.0-3_4.0.0-4.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@

INSERT INTO `mac_prefix` (`mac_prefix`, `description`, `id_manufacturer`) VALUES
("00:07:0E", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:17:0E", "Cisco - 7970", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:17:59", "Cisco - 7970", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:19:30", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:1C:58", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:1E:4A", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:1E:F7", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:1D:70", "Cisco - 7942", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:1D:A2", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:21:A0", "Cisco - 7975G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:22:90", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:23:04", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:24:14", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:26:0B", "Cisco - 79XX", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:27:90", "Cisco - 8865", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:76:86", "Cisco - 7821", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("00:B0:E1", "Cisco - 7821", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("1C:E6:C7", "Cisco - 7945G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("3C:41:0E", "Cisco - 8865", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("40:F4:EC", "Cisco - 7975G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("50:F7:22", "Cisco - 8865", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("58:97:1E", "Cisco - 7945G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("64:A0:E7", "Cisco - 7962", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("64:D9:89", "Cisco - 7942", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("B8:62:1F", "Cisco - 7945G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("C0:62:6B", "Cisco - 7945G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("CC:5A:53", "Cisco - 8865", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("D0:57:4C", "Cisco - 7945G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("D0:C2:82", "Cisco - 7945G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("D4:2C:44", "Cisco - 7821", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("DC:7B:94", "Cisco - 7942", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("E8:04:62", "Cisco - 7975G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("F8:B7:E2", "Cisco - 8865", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
("F8:7B:20", "Cisco - 8851", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco"))
;

INSERT INTO `model` (`max_accounts`, `static_ip_supported`, `dynamic_ip_supported`, `static_prov_supported`, `name`, `description`, `id_manufacturer`) VALUES
(2, 0, 1, 0, "79XX", "Cisco - 79XX", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(2, 0, 1, 0, "7821", "Cisco - 7821", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(2, 0, 1, 0, "7941G", "Cisco - 7941G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(2, 0, 1, 0, "7942", "Cisco - 7942", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(2, 0, 1, 0, "7945G", "Cisco - 7945G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(2, 0, 1, 0, "7962", "Cisco - 7962", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(8, 0, 1, 0, "7970", "Cisco - 7970", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(8, 0, 1, 0, "7975G", "Cisco - 7975G", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(5, 0, 1, 0, "8851", "Cisco - 8851", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco")),
(5, 0, 1, 0, "8865", "Cisco - 8865", (SELECT `id` FROM manufacturer WHERE `name` = "Cisco"))
;

INSERT INTO `model_properties` (`property_key`, `property_value`, `id_model`) VALUES
("max_sip_accounts", "2", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7821")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7821")),
("max_sip_accounts", "2", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7941G")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7941G")),
("max_sip_accounts", "2", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7942")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7942")),
("max_sip_accounts", "2", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7945")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7945")),
("max_sip_accounts", "2", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7962")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7962")),
("max_sip_accounts", "8", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7970")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7970")),
("max_sip_accounts", "8", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7975G")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "7975G")),
("max_sip_accounts", "5", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "8851")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "8851")),
("max_sip_accounts", "5", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "8865")),
("max_iax2_accounts", "0", (SELECT model.id FROM manufacturer, model WHERE manufacturer.id = model.id_manufacturer AND manufacturer.name = "Cisco" AND model.name = "8865"))
;
6 changes: 6 additions & 0 deletions setup/tftpboot/DialTemplate.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<DIALTEMPLATE>
<!-- Dial immediatly after presing # -->
<TEMPLATE MATCH="*#" TIMEOUT="0" Rewrite="%1" />
<!-- Anything else. Wait 4 seconds, then dial -->
<TEMPLATE MATCH="*" TIMEOUT="4" />
</DIALTEMPLATE>
140 changes: 102 additions & 38 deletions setup/usr/share/issabel/endpoint-classes/class/issabel/vendor/Cisco.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class Endpoint(BaseEndpoint):

def __init__(self, amipool, dbpool, sServerIP, sIP, mac):
BaseEndpoint.__init__(self, 'Cisco', amipool, dbpool, sServerIP, sIP, mac)

self._timeZone = "SA Eastern Standard Time"

if Endpoint._global_serverip == None:
Endpoint._global_serverip = sServerIP
elif Endpoint._global_serverip != sServerIP:
Expand All @@ -49,50 +52,80 @@ def __init__(self, amipool, dbpool, sServerIP, sIP, mac):

# TODO: might be possible to derive model from MAC range, requires database change


def setExtraParameters(self, param):
if not BaseEndpoint.setExtraParameters(self, param): return False
if 'timeZone' in param: self._timeZone = param['timeZone']
return True


def probeModel(self):
''' Probe specific model of the Cisco phone
This probe only works if the phone has access to a configuration that
enables telnet.
This probe first tries to get the model using telnet. If that fails,
it falls back to extracting the model from the web page.
'''
sModel = None

sModel = self._probeModelTelnet()

if not sModel:
sModel = self._probeModelWeb()

if sModel:
self._saveModel(sModel)


def _probeModelTelnet(self):
'''Probe specific model of the Cisco phone using telnet'''
sModel = None
try:
telnet = telnetlib.Telnet()
telnet.open(self._ip)
telnet.get_socket().settimeout(10)
except socket.timeout, e:
logging.error('Endpoint %s@%s failed to telnet - timeout (%s)' %
(self._vendorname, self._ip, str(e)))
return
except socket.error, e:
logging.error('Endpoint %s@%s failed to telnet - %s' %
(self._vendorname, self._ip, str(e)))
return

sModel = None

try:

# Attempt login with default credentials
telnet.read_until('Password :', 10)
telnet.write('cisco\r\n') # Password

idx, m, text = telnet.expect([r'Password :', r'> '], 10)
if idx == 0:
# Login failed
telnet.close()
return
raise Exception('Telnet login failed.')

telnet.write('show config\r\n')
text = telnet.read_until('> ', 10)
telnet.write('exit\r\n')
telnet.close()

m = re.search(r'IP Phone CP-(\w+)', text)
if m != None: sModel = m.group(1)
except socket.error, e:
if m:
sModel = m.group(1)

except Exception, e:
logging.error('Endpoint %s@%s connection failure - %s' %
(self._vendorname, self._ip, str(e)))
return False
finally:
telnet.close()

return sModel


def _probeModelWeb(self):
'''Probe specific model of the Cisco phone from its web page'''
sModel = None
try:
response = urllib2.urlopen('http://' + self._ip + '/')
htmlbody = response.read()

# Search for the text that contains the Cisco phone model
model_match = re.search(r'IP Phone CP-(\w+)', htmlbody, re.IGNORECASE)

if model_match:
sModel = model_match.group(1)
except Exception, e:
logging.error('Endpoint %s@%s web connection failure - %s' %
(self._vendorname, self._ip, str(e)))

if sModel != None: self._saveModel(sModel)
return sModel


@staticmethod
Expand Down Expand Up @@ -125,28 +158,47 @@ def updateGlobalConfig(serveriplist, amipool, endpoints):
logging.error('Failed to write global config for Cisco - %s' % (str(e),))
return False


def updateLocalConfig(self):
'''Configuration for Cisco endpoints (local)
'''Update local configuration for Cisco endpoints
The function generates the configuration file for Cisco endpoints based on the phone's MAC address.
The file SIPXXXXXXXXXXXX.cnf contains the SIP configuration. Here
XXXXXXXXXXXX is replaced by the UPPERCASE MAC address of the phone.
For XML compatible models, the configuration file is named SEPXXXXXXXXXXXX.cnf.xml,
where XXXXXXXXXXXX is the UPPERCASE MAC address of the phone.
For XML incompatible models, the configuration file is named SIPXXXXXXXXXXXX.cnf,
following the same MAC address format.
To reboot the phone, it is necessary to issue the AMI command:
sip notify cisco-check-cfg {$EXTENSION}. Verified with Cisco 7960.
'''
# Check that there is at least one account to configure
if len(self._accounts) <= 0:
logging.error('Endpoint %s@%s has no accounts to configure' %
(self._vendorname, self._ip))
return False

# Need to calculate UPPERCASE version of MAC address without colons
sConfigFile = 'SIP' + (self._mac.replace(':', '').upper()) + '.cnf'
sConfigPath = self._tftpdir + '/' + sConfigFile
vars = self._prepareVarList()
try:
self._writeTemplate('Cisco_local_SIP.tpl', vars, sConfigPath)

# Check that there is at least one account to configure
if not self._accounts:
raise ValueError('Endpoint %s@%s has no accounts to configure' %
(self._vendorname, self._ip))

# Need to calculate UPPERCASE version of MAC address without colons
uppercase_mac = self._mac.replace(':', '').upper()
config_file_name ='SEP' + uppercase_mac + '.cnf.xml'
config_file_template = 'Cisco_local_SEP.tpl'

if self._is_xml_incompatible():
config_file_name = 'SIP' + uppercase_mac + '.cnf'
config_file_template = 'Cisco_local_SIP.tpl'

config_file_path = self._tftpdir + '/' + config_file_name

vars = self._prepareVarList()
vars.update({
'timeZone':self._timeZone,
'server_port':5060
})


self._writeTemplate(config_file_template, vars, config_file_path)

# Must execute cisco-check-cfg with extension, not IP
if self._hasRegisteredExtension():
self._amireboot('cisco-check-cfg')
Expand All @@ -160,6 +212,18 @@ def updateLocalConfig(self):
logging.error('Endpoint %s@%s failed to write configuration file - %s' %
(self._vendorname, self._ip, str(e)))
return False
except Exception, e:
logging.error('Endpoint %s@%s failed to update local configuration - %s' %
(self._vendorname, self._ip, str(e)))
return False

def _is_xml_incompatible(self):
# Implement logic to determine if the model is XML incompatible
# For example, check the model name or model number
# Return True for Cisco models that are XML incompatible, False otherwise
# For demonstration purposes, assuming models 7960 and 7940 are XML incompatible
# return self._model in ['7960', '7940']
return False

def _rebootbytelnet(self):
'''Start reboot of Cisco phone by telnet'''
Expand Down Expand Up @@ -196,4 +260,4 @@ def _rebootbytelnet(self):
logging.error('Endpoint %s@%s connection failure - %s' %
(self._vendorname, self._ip, str(e)))
return False


Loading

0 comments on commit d7dac86

Please sign in to comment.