{"id":895,"date":"2015-12-03T17:25:43","date_gmt":"2015-12-03T12:25:43","guid":{"rendered":"http:\/\/alexeyka.zantsev.com\/?p=895"},"modified":"2021-02-28T01:42:36","modified_gmt":"2021-02-27T20:42:36","slug":"provisioning-linksys-spa-9xx-and-cisco-spa-30x","status":"publish","type":"post","link":"https:\/\/alexeyka.zantsev.com\/?p=895","title":{"rendered":"Provisioning Linksys SPA-9XX and Cisco SPA-30X"},"content":{"rendered":"<p>First of all, a nice PDF with a bunch of useful links: <a href=\"https:\/\/supportforums.cisco.com\/sites\/default\/files\/legacy\/0\/8\/6\/41680-SPA_DocsMap_012711.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/supportforums.cisco.com\/sites\/default\/files\/legacy\/0\/8\/6\/41680-SPA_DocsMap_012711.pdf<\/a><\/p>\n<p>1. There are two ways of provisioning:<\/p>\n<p>&#8211; using TFTP\/FTP\/HTTP server and pushing it&#8217;s address with the DHCP option, in case of using DHCP server in your network. In this case the phone will try to download the configuration\/firmware from the server specified during the next reboot. But we need to reboot phones forcibly after that.<\/p>\n<p>&#8211; without using DHCP server and dhcp-options. Just telling the phone with a direct HTTP request the URL path of config file\/firmware to load, either from browser, or from Linux console, using curl. In this case the phone reboots automatically to apply the newly downloaded config\/firmware (if there is an active call, the phone waits for its end and only then reboots to aply config. But I haven&#8217;t tried to upgrade firmware during the active call).<\/p>\n<p>Download the archive with <a href=\"https:\/\/software.cisco.com\/portal\/pub\/download\/portal\/select.html?&amp;mdfid=283104997&amp;softwareid=282463651\" target=\"_blank\" rel=\"noopener noreferrer\">firmware<\/a>, unpack it and rename the firmware file from something like spa50x-30x-7-4-9c.bin to spa.bin.<\/p>\n<p>Next, we need some server, e.g. a small simple HTTP server <a href=\"http:\/\/ltworf.github.io\/weborf\/\" target=\"_blank\" rel=\"noopener noreferrer\">weborf<\/a>.<br \/>\nAfter installing, run it, specifying the directory with spa.bin file:<\/p>\n<pre>weborf -p 8000 -b \/home\/lexus\/downloads\/spa_303_firmware_7.5.5\/\n<\/pre>\n<p>If there is Python installed on your machine, you may use its built-in http-server, running this command from a directory with spa.bin:<\/p>\n<pre>python -m SimpleHTTPServer 8000\n<\/pre>\n<p>Remember that it&#8217;s not always possible to skip firmware releases, for example I tried:<br \/>\n&#8211; 7.5.2 &#8212;&gt; 7.6.1 &#8211; unsuccessful<br \/>\n&#8211; 7.5.2 &#8212;&gt; 7.5.5 &#8211; OK<br \/>\n&#8211; 7.5.1 &#8212;&gt; 7.5.5 &#8211; unsuccessful<br \/>\n&#8211; 7.4.9c &#8212;&gt; 7.5.5 &#8211; unsuccessful<br \/>\n&#8211; 7.4.9c &#8212;&gt; 7.5.1 &#8211; OK.<\/p>\n<p>Read below how to upgrade the firmware.<\/p>\n<p>2. Let&#8217;s imagine, we need to change the configuration of a phone. We need to disable the Call Forward feature.<br \/>\nFirst of all look through the XML-config file of a working phone: <a href=\"http:\/\/phone.ip\/admin\/spacfg.xml\" target=\"_blank\" rel=\"noopener noreferrer\">http:\/\/phone.ip\/admin\/spacfg.xml<\/a><br \/>\nTo disable CallForward feature we need to change this parameter from &#8216;Yes&#8217; to &#8216;No&#8217;:<br \/>\n<a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2015\/12\/spa303_provisioning2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-914\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2015\/12\/spa303_provisioning2.png\" alt=\"spa303_provisioning2\" width=\"642\" height=\"38\" \/><\/a><\/p>\n<p><em>Tip: all XML parameters are called the same way as in the web-interface, but with underscore instead of spaces<\/em><\/p>\n<p>Create the spa303.cfg text file in your web-server directory:<br \/>\n<a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2015\/12\/spa303_provisioning1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-912\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2015\/12\/spa303_provisioning1.png\" alt=\"spa303_provisioning1\" width=\"565\" height=\"72\" \/><\/a><\/p>\n<p>And now tell the phone using curl to apply it:<\/p>\n<pre>curl --anyauth -u admin:pass http:\/\/phone\/admin\/resync?http:\/\/websrv.ip:8000\/spa303.cfg\n<\/pre>\n<p>3. You may also provision phones from web-interface:<\/p>\n<pre>http:\/\/phone-ip\/admin\/upgrade?http:\/\/10.145.13.51:8000\/spa.bin\nhttp:\/\/phone-ip\/admin\/resync?http:\/\/10.145.13.51:8000\/spa303.cfg\n<\/pre>\n<p>&#8230; but this is not true way :) .<\/p>\n<p>It&#8217;s much more cool to do everything with curl:<\/p>\n<pre>curl --anyauth -u admin:pass http:\/\/10.145.13.232\/admin\/reboot\ncurl --anyauth -u admin:pass http:\/\/10.145.13.229\/admin\/upgrade?http:\/\/10.145.13.51:8000\/spa.bin\ncurl --anyauth -u admin:pass http:\/\/10.145.13.229\/admin\/resync?http:\/\/10.145.13.51:8000\/spa303.cfg\n<\/pre>\n<p>&#8230; they say, it&#8217;s also possible to use &#8216;&#8211;digest&#8217; option in curl, but I haven&#8217;t tried, as &#8216;&#8211;anyauth&#8217; works fine.<\/p>\n<p>Tips and Hints:<\/p>\n<p>Assuming you&#8217;re using ISC-DHCPD server:<\/p>\n<pre>        host spa303-1353 {      hardware ethernet 3c:ce:73:d3:f9:dc;\n                                fixed-address 10.145.14.103; }\n\n        host cisco303-1354 {    hardware ethernet 3c:ce:73:d3:e9:e4;\n                                fixed-address 10.145.14.104; }\n\n<\/pre>\n<p>&#8230;and need to get all phone IP addresses from its config. Do:<\/p>\n<pre>grep -A1 spa dhcpd.conf | grep -vE '^#' | grep fixed-address | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}'\ngrep -A1 cisco dhcpd.conf | grep -vE '^#' | grep fixed-address | grep -o '[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}'\n<\/pre>\n<p>&#8230; and create a text file SPA_ips_from_dhcp.txt .<\/p>\n<p>But DHCPd config may contain records of non-existent phones, that&#8217;s why we need to check if the IP addresses are real network devices (that they reply to OPTIONS SIP-requests), and these devices are Cisco and\/or Linksys phones (useragent is Cisco&#8230; or Linksys&#8230;).<\/p>\n<p>We&#8217;ll use <a href=\"https:\/\/github.com\/sandrogauci\/sipvicious\" target=\"_blank\" rel=\"noopener noreferrer\">sipvicious<\/a> tool for that (make sure to have Python installed to run it):<\/p>\n<pre>python svmap.py --inputtext=\/home\/lexus\/SPA_ips_from_dhcp.txt | grep -i SPA | awk '{print $2}' | sed 's\/.....$\/\/'\n<\/pre>\n<p>&#8230; and write this list to SPA_ips_alive.txt .<\/p>\n<p>Now it&#8217;s time to provision the actual list of IP-phones with the script:<\/p>\n<p><a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2015\/12\/spa303_provisioning3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-918\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2015\/12\/spa303_provisioning3.png\" alt=\"spa303_provisioning3\" width=\"725\" height=\"136\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>First of all, a nice PDF with a bunch of useful links: https:\/\/supportforums.cisco.com\/sites\/default\/files\/legacy\/0\/8\/6\/41680-SPA_DocsMap_012711.pdf 1. There are two ways of provisioning: &#8211; using TFTP\/FTP\/HTTP server and pushing it&#8217;s address with the DHCP option, in case of using DHCP server in your network. In this case the phone will try to download the configuration\/firmware from the server [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[213,212,215,216,214],"class_list":["post-895","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-cisco","tag-linksys","tag-provision","tag-provisioning","tag-spa"],"_links":{"self":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/895","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=895"}],"version-history":[{"count":25,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/895\/revisions"}],"predecessor-version":[{"id":3660,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/895\/revisions\/3660"}],"wp:attachment":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=895"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=895"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=895"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}