Timeout option added
This commit is contained in:
		
							parent
							
								
									de9a3f94f7
								
							
						
					
					
						commit
						aa94eeda65
					
				
					 10 changed files with 79 additions and 54 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,7 @@
 | 
			
		|||
# smrtlink
 | 
			
		||||
Command-Line Tool which might in the future be able to configure TP-Link Easy Smart Switches.
 | 
			
		||||
The usage is loosely based on the swconfig utility. 
 | 
			
		||||
 | 
			
		||||
##dependencys
 | 
			
		||||
	libboost-filesystem-dev
 | 
			
		||||
	libboost-system-dev
 | 
			
		||||
							
								
								
									
										11
									
								
								src/File.cpp
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								src/File.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,13 +7,14 @@
 | 
			
		|||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include "File.h"
 | 
			
		||||
#include "Options.h"
 | 
			
		||||
 | 
			
		||||
std::string File::read(std::string path) {
 | 
			
		||||
std::string File::read() {
 | 
			
		||||
	if (!fs::exists(home)) {
 | 
			
		||||
		fs::create_directory(home);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs::ifstream in((home / path), std::ios::in | std::ios::binary);
 | 
			
		||||
	fs::ifstream in(((options.file=="")?home / DEFAULT_FILE:options.file), std::ios::in | std::ios::binary);
 | 
			
		||||
	if (in) {
 | 
			
		||||
		std::string contents;
 | 
			
		||||
		in.seekg(0, std::ios::end);
 | 
			
		||||
| 
						 | 
				
			
			@ -26,13 +27,13 @@ std::string File::read(std::string path) {
 | 
			
		|||
	return "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int File::write(std::string path, std::string content) {
 | 
			
		||||
int File::write(std::string content) {
 | 
			
		||||
	if (!fs::exists(home)) {
 | 
			
		||||
		fs::create_directory(home);
 | 
			
		||||
	}
 | 
			
		||||
	fs::path p = home / path;
 | 
			
		||||
	fs::path p = (options.file=="")?home / DEFAULT_FILE:options.file;
 | 
			
		||||
	fs::ofstream file(p);
 | 
			
		||||
	file << content;
 | 
			
		||||
	file << content<<"\n";
 | 
			
		||||
	file.close();
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,13 +14,15 @@ namespace fs = boost::filesystem;
 | 
			
		|||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_FILE "config.json"
 | 
			
		||||
 | 
			
		||||
class File {
 | 
			
		||||
public:
 | 
			
		||||
	File() {
 | 
			
		||||
		home = fs::path(getenv("HOME")) / ".smrtlink";
 | 
			
		||||
	}
 | 
			
		||||
	std::string read(std::string);
 | 
			
		||||
	int write(std::string, std::string);
 | 
			
		||||
	std::string read();
 | 
			
		||||
	int write(std::string);
 | 
			
		||||
private:
 | 
			
		||||
	fs::path home;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,8 +25,8 @@
 | 
			
		|||
		-u --user <[password:]username>\n\
 | 
			
		||||
		-p --password <password>\n\
 | 
			
		||||
					Login with Username and Password\n\
 | 
			
		||||
		-f --file <path>	choose a settings file\n\
 | 
			
		||||
		-t --timeout <n>	Not yet implemented\n\
 | 
			
		||||
		-f --file <path>	choose a settings file\n\n\
 | 
			
		||||
		-t --timeout <n>	Timeout in milliseconds. Default: 180\n\
 | 
			
		||||
		-w --wait		Not yet implemented: blocking until operation is completed\n\
 | 
			
		||||
		-s --permanent		Not yet implemented: make changes immediately permanent\n\n\
 | 
			
		||||
	Command Summary:\n\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,11 +22,11 @@ int Program::list() {
 | 
			
		|||
	Packet p = Packet(Packet::DISCOVERY);
 | 
			
		||||
	p.setHostMac(host.getMac());
 | 
			
		||||
	p.setPayload( { });
 | 
			
		||||
	bytes a = p.getBytes();
 | 
			
		||||
	p.encode(a);
 | 
			
		||||
	bytes b = p.getBytes();
 | 
			
		||||
	p.encode(b);
 | 
			
		||||
 | 
			
		||||
	try {
 | 
			
		||||
		asio::io_service io_service;
 | 
			
		||||
		boost::asio::io_service io_service;
 | 
			
		||||
		Socket s(io_service);
 | 
			
		||||
		s.setHostIp(host.getIp());
 | 
			
		||||
		s.init(DST_PORT, SRC_PORT);
 | 
			
		||||
| 
						 | 
				
			
			@ -47,12 +47,12 @@ int Program::list() {
 | 
			
		|||
						Switch s = Switch();
 | 
			
		||||
						s.parse(d);
 | 
			
		||||
						File f;
 | 
			
		||||
						f.write("config.json", s.toString());
 | 
			
		||||
						f.write(s.toString());
 | 
			
		||||
						std::cout <<"Devices:\n\t"<<s.settings.hostname<<" ("<< s.device.type<<")\tMAC: "<<s.device.mac<<"\tIP: "<<s.settings.ip_addr<<"\n";
 | 
			
		||||
					}
 | 
			
		||||
					return 1;
 | 
			
		||||
				};
 | 
			
		||||
		s.send(a);
 | 
			
		||||
		s.send(b);
 | 
			
		||||
		io_service.run();
 | 
			
		||||
	} catch (std::exception& e) {
 | 
			
		||||
		std::cerr << "Exception: " << e.what() << "\n";
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ int Program::list() {
 | 
			
		|||
int Program::sniff() {
 | 
			
		||||
	printf("Listening:\n");
 | 
			
		||||
	try {
 | 
			
		||||
		asio::io_service io_service;
 | 
			
		||||
		boost::asio::io_service io_service;
 | 
			
		||||
		Socket s(io_service);
 | 
			
		||||
		s.setHostIp(host.getIp());
 | 
			
		||||
		s.init(DST_PORT, SRC_PORT);
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ int Program::getProperty() {
 | 
			
		|||
	p.encode(a);
 | 
			
		||||
 | 
			
		||||
	try {
 | 
			
		||||
		asio::io_service io_service;
 | 
			
		||||
		boost::asio::io_service io_service;
 | 
			
		||||
		Socket s(io_service);
 | 
			
		||||
		s.setHostIp(host.getIp());
 | 
			
		||||
		s.init(DST_PORT, SRC_PORT);
 | 
			
		||||
| 
						 | 
				
			
			@ -168,14 +168,16 @@ int Program::save() {
 | 
			
		|||
	Switch sw = Switch();
 | 
			
		||||
	sw.settings.hostname = "testname.lan";
 | 
			
		||||
	File f;
 | 
			
		||||
	f.write("config.json", sw.toString());
 | 
			
		||||
	f.write(sw.toString());
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
int Program::restore() {
 | 
			
		||||
	File f;
 | 
			
		||||
	Switch sw;
 | 
			
		||||
	sw.parse(f.read("config.json"));
 | 
			
		||||
	std::cout <<"Devices:\n\t"<<sw.settings.hostname<<" ("<< sw.device.type<<")\tMAC: "<<sw.device.mac<<"\tIP: "<<sw.settings.ip_addr<<"\n";
 | 
			
		||||
	sw.parse(f.read());
 | 
			
		||||
	std::cout << "Devices:\n\t" << sw.settings.hostname << " ("
 | 
			
		||||
			<< sw.device.type << ")\tMAC: " << sw.device.mac << "\tIP: "
 | 
			
		||||
			<< sw.settings.ip_addr << "\n";
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
int Program::flash() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,15 +7,14 @@
 | 
			
		|||
#include <cstdlib>
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <asio.hpp>
 | 
			
		||||
#include "Socket.h"
 | 
			
		||||
#include "Packet.h"
 | 
			
		||||
#include "Options.h"
 | 
			
		||||
#include "Host.h"
 | 
			
		||||
#include "Types.h"
 | 
			
		||||
 | 
			
		||||
Socket::Socket(asio::io_service& io_service) :
 | 
			
		||||
		send_socket_(io_service), receive_socket_(io_service) {
 | 
			
		||||
Socket::Socket(boost::asio::io_service& io_service) :
 | 
			
		||||
		send_socket_(io_service), receive_socket_(io_service), timer(io_service) {
 | 
			
		||||
}
 | 
			
		||||
//, resolver(				io_service)
 | 
			
		||||
void Socket::init(short dst_port, short src_port) {
 | 
			
		||||
| 
						 | 
				
			
			@ -29,23 +28,35 @@ void Socket::init(short dst_port, short src_port) {
 | 
			
		|||
	if (options.flags & FLAG_DEBUG)
 | 
			
		||||
		std::cout << "Local IP:\t" << local_ip << "\n";
 | 
			
		||||
 | 
			
		||||
	wildcard_endpoint_ = asio::ip::udp::endpoint(
 | 
			
		||||
			asio::ip::address_v4::from_string("0.0.0.0"), src_port);
 | 
			
		||||
	local_endpoint_ = asio::ip::udp::endpoint(asio::ip::address_v4(local_ip),
 | 
			
		||||
			src_port);
 | 
			
		||||
	broadcast_endpoint_ = asio::ip::udp::endpoint(
 | 
			
		||||
			asio::ip::address_v4::from_string("255.255.255.255"), dst_port);
 | 
			
		||||
	wildcard_endpoint_ = boost::asio::ip::udp::endpoint(
 | 
			
		||||
			boost::asio::ip::address_v4::from_string("0.0.0.0"), src_port);
 | 
			
		||||
	local_endpoint_ = boost::asio::ip::udp::endpoint(
 | 
			
		||||
			boost::asio::ip::address_v4(local_ip), src_port);
 | 
			
		||||
	broadcast_endpoint_ = boost::asio::ip::udp::endpoint(
 | 
			
		||||
			boost::asio::ip::address_v4::from_string("255.255.255.255"),
 | 
			
		||||
			dst_port);
 | 
			
		||||
 | 
			
		||||
	send_socket_.open(asio::ip::udp::v4());
 | 
			
		||||
	send_socket_.set_option(asio::socket_base::broadcast(true));
 | 
			
		||||
	send_socket_.set_option(asio::socket_base::reuse_address(true));
 | 
			
		||||
	send_socket_.open(boost::asio::ip::udp::v4());
 | 
			
		||||
	send_socket_.set_option(boost::asio::socket_base::broadcast(true));
 | 
			
		||||
	send_socket_.set_option(boost::asio::socket_base::reuse_address(true));
 | 
			
		||||
	send_socket_.bind(local_endpoint_);
 | 
			
		||||
 | 
			
		||||
	receive_socket_.open(asio::ip::udp::v4());
 | 
			
		||||
	receive_socket_.set_option(asio::socket_base::broadcast(true));
 | 
			
		||||
	receive_socket_.set_option(asio::socket_base::reuse_address(true));
 | 
			
		||||
	receive_socket_.open(boost::asio::ip::udp::v4());
 | 
			
		||||
	receive_socket_.set_option(boost::asio::socket_base::broadcast(true));
 | 
			
		||||
	receive_socket_.set_option(boost::asio::socket_base::reuse_address(true));
 | 
			
		||||
	receive_socket_.bind(wildcard_endpoint_);
 | 
			
		||||
 | 
			
		||||
	if (options.timeout != 0) {
 | 
			
		||||
		timer.expires_from_now(
 | 
			
		||||
				boost::posix_time::milliseconds(options.timeout));
 | 
			
		||||
		timer.async_wait([this](const boost::system::error_code& error)
 | 
			
		||||
		{
 | 
			
		||||
			if (!error)
 | 
			
		||||
			{
 | 
			
		||||
				receive_socket_.close();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Socket::setHostIp(ipAddr ip) {
 | 
			
		||||
| 
						 | 
				
			
			@ -54,9 +65,9 @@ void Socket::setHostIp(ipAddr ip) {
 | 
			
		|||
 | 
			
		||||
void Socket::send(bytes data) {
 | 
			
		||||
	unsigned char * a = &data[0];
 | 
			
		||||
	send_socket_.async_send_to(asio::buffer(a, data.size()),
 | 
			
		||||
	send_socket_.async_send_to(boost::asio::buffer(a, data.size()),
 | 
			
		||||
			broadcast_endpoint_,
 | 
			
		||||
			[this](asio::error_code ec, std::size_t bytes_sent)
 | 
			
		||||
			[this](boost::system::error_code ec, std::size_t bytes_sent)
 | 
			
		||||
			{
 | 
			
		||||
				listen();
 | 
			
		||||
			});
 | 
			
		||||
| 
						 | 
				
			
			@ -64,12 +75,13 @@ void Socket::send(bytes data) {
 | 
			
		|||
 | 
			
		||||
void Socket::listen() {
 | 
			
		||||
	data.resize(MAX_LENGTH);
 | 
			
		||||
	receive_socket_.async_receive_from(asio::buffer(data, MAX_LENGTH),
 | 
			
		||||
	receive_socket_.async_receive_from(boost::asio::buffer(data, MAX_LENGTH),
 | 
			
		||||
			remote_endpoint_,
 | 
			
		||||
			[this](asio::error_code ec, std::size_t bytes_recvd)
 | 
			
		||||
			[this](boost::system::error_code ec, std::size_t bytes_recvd)
 | 
			
		||||
			{
 | 
			
		||||
				if (ec || bytes_recvd == 0) {
 | 
			
		||||
					listen();
 | 
			
		||||
					//listen();
 | 
			
		||||
					// TODO distinguish error codes
 | 
			
		||||
				} else {
 | 
			
		||||
					data.resize(bytes_recvd);
 | 
			
		||||
					Packet p = Packet(Packet::RETURN);
 | 
			
		||||
| 
						 | 
				
			
			@ -77,8 +89,9 @@ void Socket::listen() {
 | 
			
		|||
					p.parse(data);
 | 
			
		||||
					datasets l = p.getPayload();
 | 
			
		||||
					if(!callback(p)) {
 | 
			
		||||
						listen();
 | 
			
		||||
						//TODO do something
 | 
			
		||||
					}
 | 
			
		||||
					listen();
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/Socket.h
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								src/Socket.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
#ifndef SOCKET_H_
 | 
			
		||||
#define SOCKET_H_
 | 
			
		||||
 | 
			
		||||
#include <asio.hpp>
 | 
			
		||||
#include <boost/asio.hpp>
 | 
			
		||||
#include "Packet.h"
 | 
			
		||||
#include "Types.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@
 | 
			
		|||
 | 
			
		||||
class Socket {
 | 
			
		||||
public:
 | 
			
		||||
	Socket(asio::io_service&);
 | 
			
		||||
	Socket(boost::asio::io_service&);
 | 
			
		||||
	virtual ~Socket() {
 | 
			
		||||
	}
 | 
			
		||||
	void init(short, short);
 | 
			
		||||
| 
						 | 
				
			
			@ -31,13 +31,13 @@ public:
 | 
			
		|||
	};
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	asio::ip::udp::socket send_socket_;
 | 
			
		||||
	asio::ip::udp::socket receive_socket_;
 | 
			
		||||
	//asio::ip::udp::resolver resolver;
 | 
			
		||||
	asio::ip::udp::endpoint broadcast_endpoint_;
 | 
			
		||||
	asio::ip::udp::endpoint remote_endpoint_;
 | 
			
		||||
	asio::ip::udp::endpoint wildcard_endpoint_;
 | 
			
		||||
	asio::ip::udp::endpoint local_endpoint_;
 | 
			
		||||
	boost::asio::ip::udp::socket send_socket_;
 | 
			
		||||
	boost::asio::ip::udp::socket receive_socket_;
 | 
			
		||||
	boost::asio::ip::udp::endpoint broadcast_endpoint_;
 | 
			
		||||
	boost::asio::ip::udp::endpoint remote_endpoint_;
 | 
			
		||||
	boost::asio::ip::udp::endpoint wildcard_endpoint_;
 | 
			
		||||
	boost::asio::ip::udp::endpoint local_endpoint_;
 | 
			
		||||
	boost::asio::deadline_timer timer;
 | 
			
		||||
	bytes data = bytes(MAX_LENGTH);
 | 
			
		||||
	ipAddr local_ip;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ struct Options {
 | 
			
		|||
	std::string interface;
 | 
			
		||||
	std::string file;
 | 
			
		||||
	int debug_level=0;
 | 
			
		||||
	long timeout;
 | 
			
		||||
	long timeout = 180U;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* TYPES_H_ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,9 @@
 | 
			
		|||
 *      Author: jdi
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "../include/rapidjson/document.h"
 | 
			
		||||
#include "../include/rapidjson/prettywriter.h"
 | 
			
		||||
 | 
			
		||||
#include "jsonNode.h"
 | 
			
		||||
 | 
			
		||||
jsonNode::jsonNode(const std::string &x, doc &root) {
 | 
			
		||||
| 
						 | 
				
			
			@ -18,8 +21,7 @@ jsonNode::jsonNode(const std::string &x, doc &root) {
 | 
			
		|||
jsonNode::jsonNode(const ipAddr &x, doc &root) {
 | 
			
		||||
	super(rapidjson::kStringType);
 | 
			
		||||
	char buffer[16];
 | 
			
		||||
	int len = sprintf(buffer, "%d.%d.%d.%d", x[0], x[1],
 | 
			
		||||
			x[2], x[3]);
 | 
			
		||||
	int len = sprintf(buffer, "%d.%d.%d.%d", x[0], x[1], x[2], x[3]);
 | 
			
		||||
	this->SetString(buffer, static_cast<size_t>(len), root.GetAllocator());
 | 
			
		||||
	memset(buffer, 0, sizeof(buffer));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,8 +29,8 @@ jsonNode::jsonNode(const ipAddr &x, doc &root) {
 | 
			
		|||
jsonNode::jsonNode(const macAddr &x, doc &root) {
 | 
			
		||||
	super(rapidjson::kStringType);
 | 
			
		||||
	char buffer[18];
 | 
			
		||||
	int len = sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", x[0], x[1],
 | 
			
		||||
			x[2], x[3], x[4], x[5]);
 | 
			
		||||
	int len = sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", x[0], x[1], x[2],
 | 
			
		||||
			x[3], x[4], x[5]);
 | 
			
		||||
	this->SetString(buffer, static_cast<size_t>(len), root.GetAllocator());
 | 
			
		||||
	memset(buffer, 0, sizeof(buffer));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
 *      Author: jdi
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "lookupTable.h"
 | 
			
		||||
 | 
			
		||||
lookupTable::lookupTable(std::initializer_list<set> l) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue