device_ip/admin/spacfg.xml
device_ip/admin/spacfg.xml
- but this does not work on all devices) or find somewhere on the vast expanses of the Internet.generator.sh
) collects the configuration file from the device information described in the devices.list file and configuration pieces from the templates {modelName, common/start, common/network, common/end}
directory.pusher.sh
) - copies already generated device configuration files into a directory accessible via http:http: // server_ip / configsand then refers to the device on a special link which contains information from where to get the configuration and then apply it:
curl --digest -u USERNAME: PASSWORD http: // device_IP / admin / resync? http: //server_ip/configs/CONFIGFILE.xml
devices.list
file that describes the device configuration; the line should be in this format:DEVICE_MODEL|NETWORK_NAME|LINE1_DESCR|LINE1_NUMBER|LINE1_PASS|LINE2_DESCR|LINE2_NUMBER|LINE2_PASS|STATION_NAME|USER_PASSWORD
generator.sh
pusher.sh single NETWORK_NAME_IN_DNS
and watch the log in the terminaldevices.list
file which describes the device configuration.generator.sh
pusher.sh single NETWORK_NAME_IN_DNS
generator.sh
- there is a variable in it that is responsible for dial plan.generator.sh
pusher.sh all
and watch the log in the terminal or on your syslog server (do you have it, right?). For example, like this: tail -f /var/log/messages | egrep -i "(pap2t|spa-)"
tail -f /var/log/messages | egrep -i "(pap2t|spa-)"
################################################## ################################################## ######################################### # LINE FORMAT: DEVICE_MODEL | NETWORK_NAME | LINE1_DESCR | LINE1_NUMBER | LINE1_PASS | LINE2_DESCR | LINE2_NUMBER | LINE2_PASS | STATION_NAME | USER_PASSWORD # ################################################## ################################################## ######################################### ################# # voip gateways # ################# # PAP2T PAP2T | voip1.f3r1 | Reception1 | 3000 | 3000pass | Reception2 | 3001 | 3001pass PAP2T | voip2.f3r1 | Finance | 3030 | 3030pass ||| # SPA3102 SPA3102 | voip0.f3r1 | Meeting room | 3131 | 3131pass ############### # voip phones # ############### # SPA901 SPA901 | vph0.f3lr2 | Zavhoz | 3040 | 3040pass ||| # SPA921 SPA921 | vph0.f3r3 | Boss | 3050 | 3050pass ||| Shef | 1234 # SPA941 SPA941 | vph0.f3r4 | Admin | 3060 | 3060pass |||| Admin | 3060 # SPA942 SPA941 | vph0.f4r1 | Manager1 | 3080 | 3080pass ||| Manager1 # Cisco SPA502G SPA502G | vph1.f4r1 | Manager2 | 3090 | 3090pass ||| Manager2
#! / bin / bash ########################################## config section ###### ######################################## adminPass = 'qwerty123' userPass = 'qwerty123' dialPlan = '(* 8S0 | * xx | 1 [0-9] [0-9] S0 | [95] [0-9] xxS0 | 2xxxxxxS0 | 0 [3-7] xxxxxxxxS0 | 0 [89] x [1 -9] xxxxxxS0 | 0 [89] 00xxxxxxxS0 | 02xxxxxxxS0 | xxxxxxxxxxxx.) ' sipProxy = 'sip.yourdomain.com' # here is configs for PSTN line on SPA3102 devices dialPlanSPA3102 = '(xx.)' sipProxySPA3102 = $ sipProxy ########################################### do not edit below this ## ##################################### curPath = `dirname $ {0}` devicesList = $ {curPath} /devices.list cat $ {devicesList} | sed '/ * # / d; / ^ * $ / d '| while read line; do model = `echo $ {line} | cut -f1 -d '|' | tr '[: lower:]' '[: upper:]' ` networkName = `echo $ {line} | cut -f2 -d '|' ` ipStr = `host -t any $ {networkName}` if [`echo $ {ipStr} | grep 'not found:' | wc -l` -gt 0] then echo "Error: $ {networkName} not found in DNS. Please fix this." exit 1 else ip = `echo $ {ipStr} | cut -f4 -d '' ` fi echo -n "Device ip - $ {ip}." line1Descr = `echo $ {line} | cut -f3 -d '|' ` line1Phone = `echo $ {line} | cut -f4 -d '|' ` line1Pass = `echo $ {line} | cut -f5 -d '|' ` line2Descr = `echo $ {line} | cut -f6 -d '|' ` line2Phone = `echo $ {line} | cut -f7 -d '|' ` line2Pass = `echo $ {line} | cut -f8 -d '|' ` stationName = `echo $ {line} | cut -f9 -d '|' ` userPassFromConfig = `echo $ {line} | cut -f10 -d '|' ` if ["$ {userPassFromConfig}"! = ""] then userPass = $ {userPassFromConfig} echo -n "Set not default user pass." fi case "$ {model}" in PAP2T) echo "Creating profile for $ {model} - $ {networkName} ..." outputFile = $ {curPath} / configs / $ {model} - $ {ip} .xml cat $ {curPath} / templates / common / start> $ {outputFile} cat $ {curPath} / templates / common / network >> $ {outputFile} cat $ {curPath} / templates / pap2t >> $ {outputFile} # here config individual settings echo '<Static_IP ua = "rw">' $ {ip} '</ Static_IP>' >> $ {outputFile} echo '<HostName ua = "rw">' $ {networkName} '</ HostName>' >> $ {outputFile} echo '<Admin_Passwd ua = "na">' $ {adminPass} '</ Admin_Passwd>' >> $ {outputFile} echo '<User_Password ua = "rw">' $ {userPass} '</ User_Password>' >> $ {outputFile} echo '<Display_Name_1_ ua = "na">' $ {line1Descr} '</ Display_Name_1_>' >> $ {outputFile} echo '<User_ID_1_ua = "na">' $ {line1Phone} '</ User_ID_1_>' >> $ {outputFile} echo '<Password_1_ua = "na">' $ {line1Pass} '</ Password_1_>' >> $ {outputFile} echo '<Display_Name_2_ ua = "na">' $ {line2Descr} '</ Display_Name_2_>' >> $ {outputFile} echo '<User_ID_2_ ua = "na">' $ {line2Phone} '</ User_ID_2_>' >> $ {outputFile} echo '<Password_2_ ua = "na">' $ {line2Pass} '</ Password_2_>' >> $ {outputFile} echo '<Dial_Plan_1_ua = "na">' $ {dialPlan} '</ Dial_Plan_1_>' >> $ {outputFile} echo '<Proxy_1_ ua = "na">' $ {sipProxy} '</ Proxy_1_>' >> $ {outputFile} echo '<Dial_Plan_2_ua = "na">' $ {dialPlan} '</ Dial_Plan_2_>' >> $ {outputFile} echo '<Proxy_2_ ua = "na">' $ {sipProxy} '</ Proxy_2_>' >> $ {outputFile} cat $ {curPath} / templates / common / end >> $ {outputFile} ;; SPA3102) echo "Creating profile for $ {model} - $ {networkName} ..." outputFile = $ {curPath} / configs / $ {model} - $ {ip} .xml cat $ {curPath} / templates / common / start> $ {outputFile} cat $ {curPath} / templates / common / network >> $ {outputFile} cat $ {curPath} / templates / spa3102 >> $ {outputFile} # here config individual settings echo '<Static_IP ua = "rw">' $ {ip} '</ Static_IP>' >> $ {outputFile} echo '<HostName ua = "rw">' $ {networkName} '</ HostName>' >> $ {outputFile} echo '<Admin_Passwd ua = "na">' $ {adminPass} '</ Admin_Passwd>' >> $ {outputFile} echo '<User_Password ua = "rw">' $ {userPass} '</ User_Password>' >> $ {outputFile} echo '<Display_Name_1_ ua = "na">' $ {line1Descr} '</ Display_Name_1_>' >> $ {outputFile} echo '<User_ID_1_ua = "na">' $ {line1Phone} '</ User_ID_1_>' >> $ {outputFile} echo '<Password_1_ua = "na">' $ {line1Pass} '</ Password_1_>' >> $ {outputFile} echo '<Display_Name_2_ ua = "na">' $ {line2Descr} '</ Display_Name_2_>' >> $ {outputFile} echo '<User_ID_2_ ua = "na">' $ {line2Phone} '</ User_ID_2_>' >> $ {outputFile} echo '<Password_2_ ua = "na">' $ {line2Pass} '</ Password_2_>' >> $ {outputFile} echo '<Dial_Plan_1_ua = "na">' $ {dialPlan} '</ Dial_Plan_1_>' >> $ {outputFile} echo '<Proxy_1_ ua = "na">' $ {sipProxy} '</ Proxy_1_>' >> $ {outputFile} echo '<Dial_Plan_1_2_ua = "na">' $ {dialPlanSPA3102} '</ Dial_Plan_1_2_>' >> $ {outputFile} echo '<Proxy_2_ ua = "na">' $ {sipProxySPA3102} '</ Proxy_2_>' >> $ {outputFile} cat $ {curPath} / templates / common / end >> $ {outputFile} ;; SPA901) echo "Creating profile for $ {model} - $ {networkName} ..." outputFile = $ {curPath} / configs / $ {model} - $ {ip} .xml cat $ {curPath} / templates / common / start> $ {outputFile} cat $ {curPath} / templates / common / network >> $ {outputFile} cat $ {curPath} / templates / spa901 >> $ {outputFile} # here config individual settings echo '<Static_IP ua = "rw">' $ {ip} '</ Static_IP>' >> $ {outputFile} echo '<HostName ua = "rw">' $ {networkName} '</ HostName>' >> $ {outputFile} echo '<Admin_Passwd ua = "na">' $ {adminPass} '</ Admin_Passwd>' >> $ {outputFile} echo '<User_Password ua = "rw">' $ {userPass} '</ User_Password>' >> $ {outputFile} echo '<Display_Name_1_ ua = "na">' $ {line1Descr} '</ Display_Name_1_>' >> $ {outputFile} echo '<User_ID_1_ua = "na">' $ {line1Phone} '</ User_ID_1_>' >> $ {outputFile} echo '<Password_1_ua = "na">' $ {line1Pass} '</ Password_1_>' >> $ {outputFile} echo '<Dial_Plan_1_ua = "na">' $ {dialPlan} '</ Dial_Plan_1_>' >> $ {outputFile} echo '<Proxy_1_ ua = "na">' $ {sipProxy} '</ Proxy_1_>' >> $ {outputFile} cat $ {curPath} / templates / common / end >> $ {outputFile} ;; SPA921) echo "Creating profile for $ {model} - $ {networkName} ..." outputFile = $ {curPath} / configs / $ {model} - $ {ip} .xml cat $ {curPath} / templates / common / start> $ {outputFile} cat $ {curPath} / templates / common / network >> $ {outputFile} #cat $ {curPath} / templates / spa921 >> $ {outputFile} # here config individual settings echo '<Static_IP ua = "rw">' $ {ip} '</ Static_IP>' >> $ {outputFile} echo '<HostName ua = "rw">' $ {networkName} '</ HostName>' >> $ {outputFile} echo '<Admin_Passwd ua = "na">' $ {adminPass} '</ Admin_Passwd>' >> $ {outputFile} echo '<User_Password ua = "rw">' $ {userPass} '</ User_Password>' >> $ {outputFile} echo '<Station_Name ua = "na">' $ {stationName} '</ Station_Name>' >> $ {outputFile} echo '<Display_Name_1_ ua = "na">' $ {line1Descr} '</ Display_Name_1_>' >> $ {outputFile} echo '<User_ID_1_ua = "na">' $ {line1Phone} '</ User_ID_1_>' >> $ {outputFile} echo '<Password_1_ua = "na">' $ {line1Pass} '</ Password_1_>' >> $ {outputFile} echo '<Dial_Plan_1_ua = "na">' $ {dialPlan} '</ Dial_Plan_1_>' >> $ {outputFile} echo '<Proxy_1_ ua = "na">' $ {sipProxy} '</ Proxy_1_>' >> $ {outputFile} cat $ {curPath} / templates / common / end >> $ {outputFile} ;; SPA941) echo "Creating profile for $ {model} - $ {networkName} ..." outputFile = $ {curPath} / configs / $ {model} - $ {ip} .xml cat $ {curPath} / templates / common / start> $ {outputFile} cat $ {curPath} / templates / common / network >> $ {outputFile} #cat $ {curPath} / templates / spa941 >> $ {outputFile} # here config individual settings echo '<Static_IP ua = "rw">' $ {ip} '</ Static_IP>' >> $ {outputFile} echo '<HostName ua = "rw">' $ {networkName} '</ HostName>' >> $ {outputFile} echo '<Admin_Passwd ua = "na">' $ {adminPass} '</ Admin_Passwd>' >> $ {outputFile} echo '<User_Password ua = "rw">' $ {userPass} '</ User_Password>' >> $ {outputFile} echo '<Station_Name ua = "na">' $ {stationName} '</ Station_Name>' >> $ {outputFile} echo '<Display_Name_1_ ua = "na">' $ {line1Descr} '</ Display_Name_1_>' >> $ {outputFile} echo '<User_ID_1_ua = "na">' $ {line1Phone} '</ User_ID_1_>' >> $ {outputFile} echo '<Password_1_ua = "na">' $ {line1Pass} '</ Password_1_>' >> $ {outputFile} echo '<Display_Name_2_ ua = "na">' $ {line2Descr} '</ Display_Name_2_>' >> $ {outputFile} echo '<User_ID_2_ ua = "na">' $ {line2Phone} '</ User_ID_2_>' >> $ {outputFile} echo '<Password_2_ ua = "na">' $ {line2Pass} '</ Password_2_>' >> $ {outputFile} echo '<Dial_Plan_1_ua = "na">' $ {dialPlan} '</ Dial_Plan_1_>' >> $ {outputFile} echo '<Proxy_1_ ua = "na">' $ {sipProxy} '</ Proxy_1_>' >> $ {outputFile} echo '<Dial_Plan_2_ua = "na">' $ {dialPlan} '</ Dial_Plan_2_>' >> $ {outputFile} echo '<Proxy_2_ ua = "na">' $ {sipProxy} '</ Proxy_2_>' >> $ {outputFile} cat $ {curPath} / templates / common / end >> $ {outputFile} ;; SPA502G) echo "Creating profile for $ {model} - $ {networkName} ..." outputFile = $ {curPath} / configs / $ {model} - $ {ip} .xml cat $ {curPath} / templates / common / start> $ {outputFile} cat $ {curPath} / templates / common / network >> $ {outputFile} cat $ {curPath} / templates / spa502g >> $ {outputFile} # here config individual settings echo '<Static_IP ua = "rw">' $ {ip} '</ Static_IP>' >> $ {outputFile} echo '<HostName ua = "rw">' $ {networkName} '</ HostName>' >> $ {outputFile} echo '<Admin_Passwd ua = "na">' $ {adminPass} '</ Admin_Passwd>' >> $ {outputFile} echo '<User_Password ua = "rw">' $ {userPass} '</ User_Password>' >> $ {outputFile} echo '<Station_Name ua = "na">' $ {stationName} '</ Station_Name>' >> $ {outputFile} # <Station_Display_Name ua = "na"> </ Station_Display_Name> echo '<Display_Name_1_ ua = "na">' $ {line1Descr} '</ Display_Name_1_>' >> $ {outputFile} echo '<User_ID_1_ua = "na">' $ {line1Phone} '</ User_ID_1_>' >> $ {outputFile} echo '<Password_1_ua = "na">' $ {line1Pass} '</ Password_1_>' >> $ {outputFile} echo '<Dial_Plan_1_ua = "na">' $ {dialPlan} '</ Dial_Plan_1_>' >> $ {outputFile} echo '<Proxy_1_ ua = "na">' $ {sipProxy} '</ Proxy_1_>' >> $ {outputFile} cat $ {curPath} / templates / common / end >> $ {outputFile} ;; esac done
#! / bin / bash user = admin pass = qwerty123 sourceLink = "http://192.168.50.10/configs" configsPath = "` dirname $ {0} `/ configs" cp $ {configsPath} / *. xml / var / www / html / configs case $ 1 in all) ls -1 $ {configsPath} | while read line; do deviceIP = `echo $ {line} | cut -f2 -d- | cut -f1-4 -d.` echo "$ {deviceIP} ___________________________________________________________________________" curl --digest -u $ {user}: $ {pass} http: // $ {deviceIP} / admin / resync? $ {sourceLink} / $ {line} done ;; single) networkName = $ 2 ipStr = `host -t any $ {networkName}` if [`echo $ {ipStr} | grep 'not found:' | wc -l` -gt 0] then echo "Error: $ {networkName} not found in DNS. Please fix this." exit 1 else ip = `echo $ {ipStr} | cut -f4 -d '' ` fi ls -1 $ {configsPath} | grep $ {ip} | while read line; do deviceIP = `echo $ {line} | cut -f2 -d- | cut -f1-4 -d.` echo "$ {deviceIP} ___________________________________________________________________________" curl --digest -u $ {user}: $ {pass} http: // $ {deviceIP} / admin / resync? $ {sourceLink} / $ {line} done ;; *) echo "Use this script with parameters. Here is examples:" echo "* $ {0} all * - for provisioning on all devices" echo "* $ {0} single NETWORK_NAME_IN_DNS * - for provisioning on single device" ;; esac
<Ring_Waveform ua = "na"> Trapezoid </ Ring_Waveform>
<Ring_Waveform ua = "na"> Trapezoid </ Ring_Waveform> <FAX_Line_Toggle_Code ua = "na"> </ FAX_Line_Toggle_Code>
<Paging_Code ua = "na"> </ Paging_Code> <Call_Park_Code ua = "na"> </ Call_Park_Code> <Call_UnPark_Code ua = "na"> </ Call_UnPark_Code> <Call_Pickup_Code ua = "na"> </ Call_Pickup_Code> <Group_Call_Pickup_Code ua = "na"> </ Group_Call_Pickup_Code> <Enable_CDP ua = "na"> No </ Enable_CDP>
<Paging_Code ua="na"></Paging_Code>
<Call_Park_Code ua="na"></Call_Park_Code>
<Call_UnPark_Code ua="na"></Call_UnPark_Code>
<Call_Pickup_Code ua="na"></Call_Pickup_Code>
<? xml version = "1.0" encoding = "UTF-8" standalone = "yes"?> <flat-profile>
<Restricted_Access_Domains ua = "na"> </ Restricted_Access_Domains> <Enable_Web_Server ua = "na"> Yes </ Enable_Web_Server> <Web_Server_Port ua = "na"> 80 </ Web_Server_Port> <Enable_Web_Admin_Access ua = "na"> Yes </ Enable_Web_Admin_Access> <DHCP ua = "rw"> No </ DHCP> <NetMask ua = "rw"> 255.255.255.0 </ NetMask> <Gateway ua = "rw"> 192.168.50.254 </ Gateway> <Domain ua = "rw"> yourdomain.com </ Domain> <Primary_DNS ua = "rw"> 192.168.71.3 </ Primary_DNS> <Secondary_DNS ua = "rw"> 192.168.71.6 </ Secondary_DNS> <Primary_NTP_Server ua = "na"> ntp.yourdomain.com </ Primary_NTP_Server> <Secondary_NTP_Server ua = "na"> ntp2.yourdomain.com </ Secondary_NTP_Server> <Syslog_Server ua = "na"> syslog.yourdomain.com </ Syslog_Server> <DNS_Server_Order ua = "na"> Manual </ DNS_Server_Order> <DNS_Query_Mode ua = "na"> Parallel </ DNS_Query_Mode> <Debug_Server ua = "na"> </ Debug_Server> <Debug_Level ua = "na"> 0 </ Debug_Level> <Provision_Enable ua = "na"> Yes </ Provision_Enable> <Resync_On_Reset ua = "na"> No </ Resync_On_Reset> <Resync_Periodic ua = "na"> 3600 </ Resync_Periodic> <Profile_Rule ua = "na"> / init.cfg </ Profile_Rule> <Profile_Rule_B ua = "na"> </ Profile_Rule_B> <Profile_Rule_C ua = "na"> </ Profile_Rule_C> <Profile_Rule_D ua = "na"> </ Profile_Rule_D> <Upgrade_Enable ua = "na"> Yes </ Upgrade_Enable> <Upgrade_Error_Retry_Delay ua = "na"> 3600 </ Upgrade_Error_Retry_Delay> <Log_Upgrade_Request_Msg ua = "na"> $ PN $ MAC - Requesting upgrade $ SCHEME: // $ SERVIP: $ PORT $ PATH </ Log_Upgrade_Request_Msg> <Log_Upgrade_Success_Msg ua = "na"> $ PN $ MAC - Successful upgrade $ SCHEME: // $ SERVIP: $ PORT $ PATH - $ ERR </ Log_Upgrade_Success_Msg> <Log_Upgrade_Failure_Msg ua = "na"> $ PN $ MAC - Upgrade failed: $ ERR </ Log_Upgrade_Failure_Msg> <Call_Return_Code ua = "na"> </ Call_Return_Code> <Blind_Transfer_Code ua = "na"> </ Blind_Transfer_Code> <Call_Back_Act_Code ua = "na"> </ Call_Back_Act_Code> <Call_Back_Deact_Code ua = "na"> </ Call_Back_Deact_Code> <Cfwd_All_Act_Code ua = "na"> </ Cfwd_All_Act_Code> <Cfwd_All_Deact_Code ua = "na"> </ Cfwd_All_Deact_Code> <Cfwd_Busy_Act_Code ua = "na"> </ Cfwd_Busy_Act_Code> <Cfwd_Busy_Deact_Code ua = "na"> </ Cfwd_Busy_Deact_Code> <Cfwd_No_Ans_Act_Code ua = "na"> </ Cfwd_No_Ans_Act_Code> <Cfwd_No_Ans_Deact_Code ua = "na"> </ Cfwd_No_Ans_Deact_Code> <Cfwd_Last_Act_Code ua = "na"> </ Cfwd_Last_Act_Code> <Cfwd_Last_Deact_Code ua = "na"> </ Cfwd_Last_Deact_Code> <Block_Last_Act_Code ua = "na"> </ Block_Last_Act_Code> <Block_Last_Deact_Code ua = "na"> </ Block_Last_Deact_Code> <Accept_Last_Act_Code ua = "na"> </ Accept_Last_Act_Code> <Accept_Last_Deact_Code ua = "na"> </ Accept_Last_Deact_Code> <CW_Act_Code ua = "na"> </ CW_Act_Code> <CW_Deact_Code ua = "na"> </ CW_Deact_Code> <CW_Per_Call_Act_Code ua = "na"> </ CW_Per_Call_Act_Code> <CW_Per_Call_Deact_Code ua = "na"> </ CW_Per_Call_Deact_Code> <Block_CID_Act_Code ua = "na"> </ Block_CID_Act_Code> <Block_CID_Deact_Code ua = "na"> </ Block_CID_Deact_Code> <Block_CID_Per_Call_Act_Code ua = "na"> </ Block_CID_Per_Call_Act_Code> <Block_CID_Per_Call_Deact_Code ua = "na"> </ Block_CID_Per_Call_Deact_Code> <Block_ANC_Act_Code ua = "na"> </ Block_ANC_Act_Code> <Block_ANC_Deact_Code ua = "na"> </ Block_ANC_Deact_Code> <DND_Act_Code ua = "na"> </ DND_Act_Code> <DND_Deact_Code ua = "na"> </ DND_Deact_Code> <CID_Act_Code ua = "na"> </ CID_Act_Code> <CID_Deact_Code ua = "na"> </ CID_Deact_Code> <CWCID_Act_Code ua = "na"> </ CWCID_Act_Code> <CWCID_Deact_Code ua = "na"> </ CWCID_Deact_Code> <Dist_Ring_Act_Code ua = "na"> </ Dist_Ring_Act_Code> <Dist_Ring_Deact_Code ua = "na"> </ Dist_Ring_Deact_Code> <Speed_Dial_Act_Code ua = "na"> </ Speed_Dial_Act_Code> <Secure_All_Call_Act_Code ua = "na"> </ Secure_All_Call_Act_Code> <Secure_No_Call_Act_Code ua = "na"> </ Secure_No_Call_Act_Code> <Secure_One_Call_Act_Code ua = "na"> </ Secure_One_Call_Act_Code> <Secure_One_Call_Deact_Code ua = "na"> </ Secure_One_Call_Deact_Code> <Conference_Act_Code ua = "na"> </ Conference_Act_Code> <Attn-Xfer_Act_Code ua = "na"> </ Attn-Xfer_Act_Code> <Modem_Line_Toggle_Code ua = "na"> </ Modem_Line_Toggle_Code> <Media_Loopback_Code ua = "na"> </ Media_Loopback_Code> <Time_Zone ua = "na"> GMT + 02: 00 </ Time_Zone> <Daylight_Saving_Time_Rule ua = "na"> start = 3 / -1 / 7/3; end = 10 / -1 / 7/4; save = 1 </ Daylight_Saving_Time_Rule>
</ flat-profile>
Source: https://habr.com/ru/post/134851/
All Articles