#!/usr/bin/python

from socket import *
import sys, getopt
import time

dhcp_f = dhcp_f = gw_f = mask_f = serial_f = 0
get_settings_f = 0
req_ser = 0

GET_TIMEOUT = 3
FIND_TIMEOUT = 3

broadcast_port = 49049
broadcast_addr = '255.255.255.255'


def usage():
	print "Usage\r\n\
	--help \t\t\tprint usage info\r\n\
	--find \t\t\tdiscover devices in the network\r\n\
	--req=<seral> \t\trequest settings from device\r\n\
	--serial=<serial> \tserial number of the device to apply settings to\r\n\
	--dhcp=<True|False> \tset dhcp option\r\n\
	--ip=<addr> \t\tset ip addr\r\n\
	--gw=<addr> \t\tset gatewauy addr\r\n\
	--mask=<addr> \t\tset netmask addr\r\n\
	--broadcast=<addr> \tbroadcast addr to use"

def find():
	cs=socket(AF_INET, SOCK_DGRAM)
	cs.settimeout(FIND_TIMEOUT)
	cs.bind(('',broadcast_port))

	count = 0
	found = 0
	ser_list = []

	print "Model \t\tSerial \t\tIP-address \tMAC-address \t\tFW version" 

	while (count < FIND_TIMEOUT):
		try:
			m=cs.recvfrom(broadcast_port)
		except timeout:
			print "Not found"
			sys.exit(2)

		message = m[0]

		s=message.split(";")
	
		if len(s) > 1:
			model = s[0]
			serial = s[1]
			ip = m[1][0]
			mac = s[2]
			fw = s[3]

			if serial not in ser_list:
				ser_list.append(serial)  	
				print model, '\t', serial, '\t', ip, '\t', mac, '\t', fw
				found=found+1
	
		count=count+1
		time.sleep(1)

	print "Found: ", found


def get_settings(serial):
	print "\r\nBroadcast request to: ", broadcast_addr

	timeout = 0
	found = 0

	cs=socket(AF_INET, SOCK_DGRAM)
	cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
	cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
	cs.settimeout(GET_TIMEOUT)

        cs.bind(('', broadcast_port))

	buf = '{"serno":"' + serial + '","dhcp":"","ipaddress":"","gateway":"","mask":""}'

	cs.sendto(buf, (broadcast_addr, broadcast_port))

	while (timeout < GET_TIMEOUT):
 		m=cs.recvfrom(broadcast_port)
		
		if m[0] == buf: 
			continue		
		message = m[0]

		message = message.replace("{", "")
		message = message.replace("}", "")

		tags = message.split(",")
		if not tags[0]:
			continue

		values = tags[0].split(":")
		if not values[0]:
			continue
		
		if values[0] == '"serno"':
			resp_serial = values.pop().replace('"', '')

			if resp_serial == serial:
				resp_dhcp = tags[1].split(":").pop().replace('"', '')
				resp_ip = tags[2].split(":").pop().replace('"', '')
				resp_gw = tags[3].split(":").pop().replace('"', '')
				resp_netmask = tags[4].split(":").pop().replace('"', '')

				print "\r\nSeral number: \t", resp_serial 
				print "DHCP: \t\t", resp_dhcp
				print "IP: \t\t", resp_ip 
				print "Geteway: \t", resp_gw 
				print "Netmask: \t", resp_netmask

				print "\r\nCommand to set settings: \r\n" + sys.argv[0] \
					+ " --serial=" + resp_serial \
					+ " --dhcp=" + resp_dhcp \
					+ " --ip=" + resp_ip \
					+ " --gw=" + resp_gw \
					+ " --mask=" + resp_netmask \
					+ " --broadcast=255.255.255.255"

				found = 1
				break

		timeout = timeout + 1;
	
	if not found:
		print "Not found"
	

def set_settings():
	print "\r\nBroadcast request to: ", broadcast_addr

	print "\r\nSeral number: \t", serial_set 
	print "DHCP: \t\t", dhcp_set 
	print "IP: \t\t", ip_set 
	print "Geteway: \t", gw_set 
	print "Netmask: \t", mask_set 
	
	cs=socket(AF_INET, SOCK_DGRAM)
	cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
	cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

	buf = '{"serno":"' + serial_set + '","dhcp":"' + dhcp_set + '","ipaddress":"' \
		+ ip_set + '","gateway":"' + gw_set + '","mask":"' + mask_set + '"}'

	

	cs.sendto(buf, (broadcast_addr, broadcast_port))

	print "\r\nCommand to request settings: \r\n" + sys.argv[0] \
		+ " --req=" + serial_set \
		+ " --broadcast=255.255.255.255"


try:                                	
	opts, args = getopt.getopt(sys.argv[1:], "hb:fr:s:d:i:g:m:", \
		["help", "broadcast=", "find", "req=", "serial=", "dhcp=", "ip=", "gw=", "mask="])
except getopt.GetoptError:          
	usage()                         
	sys.exit(2)     
               
for opt, arg in opts:                
	if opt in ("-h", "--help"):      
		usage()                     
		sys.exit()
  	if opt in ("-b", "--broadcast"): 
		broadcast_addr = arg
	if opt in ("-f", "--find"):      
		find()                     
		sys.exit()
	elif opt in ("-r", "--req"): 
		get_settings_f = 1 
    		req_ser = arg 
	elif opt in ("-s", "--serial"):                               
		serial_set = arg
		serial_f = 1           
	elif opt in ("-d", "--dhcp"):                               
		dhcp_set = arg
		dhcp_f = 1                  
	elif opt in ("-i", "--ip"): 
		ip_set = arg
		ip_f = 1  
	elif opt in ("-g", "--gw"): 
		gw_set = arg
		gw_f = 1  
	elif opt in ("-m", "--mask"):
		mask_set = arg
		mask_f = 1 

if get_settings_f == 1:
	get_settings(req_ser)                     
	sys.exit()
elif (dhcp_f and dhcp_f and gw_f and mask_f and serial_f):
	set_settings()
	sys.exit()
else:
    	print "Error: Not enough parameters"
	usage()
	sys.exit(2)