Timeout option added

This commit is contained in:
/jdi/ 2015-10-18 10:16:03 +02:00
parent de9a3f94f7
commit aa94eeda65
10 changed files with 79 additions and 54 deletions

View file

@ -1,3 +1,7 @@
# smrtlink # smrtlink
Command-Line Tool which might in the future be able to configure TP-Link Easy Smart Switches. 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. The usage is loosely based on the swconfig utility.
##dependencys
libboost-filesystem-dev
libboost-system-dev

View file

@ -7,13 +7,14 @@
#include <iostream> #include <iostream>
#include "File.h" #include "File.h"
#include "Options.h"
std::string File::read(std::string path) { std::string File::read() {
if (!fs::exists(home)) { if (!fs::exists(home)) {
fs::create_directory(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) { if (in) {
std::string contents; std::string contents;
in.seekg(0, std::ios::end); in.seekg(0, std::ios::end);
@ -26,13 +27,13 @@ std::string File::read(std::string path) {
return ""; return "";
} }
int File::write(std::string path, std::string content) { int File::write(std::string content) {
if (!fs::exists(home)) { if (!fs::exists(home)) {
fs::create_directory(home); fs::create_directory(home);
} }
fs::path p = home / path; fs::path p = (options.file=="")?home / DEFAULT_FILE:options.file;
fs::ofstream file(p); fs::ofstream file(p);
file << content; file << content<<"\n";
file.close(); file.close();
return 0; return 0;
} }

View file

@ -14,13 +14,15 @@ namespace fs = boost::filesystem;
#include <string> #include <string>
#define DEFAULT_FILE "config.json"
class File { class File {
public: public:
File() { File() {
home = fs::path(getenv("HOME")) / ".smrtlink"; home = fs::path(getenv("HOME")) / ".smrtlink";
} }
std::string read(std::string); std::string read();
int write(std::string, std::string); int write(std::string);
private: private:
fs::path home; fs::path home;
}; };

View file

@ -25,8 +25,8 @@
-u --user <[password:]username>\n\ -u --user <[password:]username>\n\
-p --password <password>\n\ -p --password <password>\n\
Login with Username and Password\n\ Login with Username and Password\n\
-f --file <path> choose a settings file\n\ -f --file <path> choose a settings file\n\n\
-t --timeout <n> Not yet implemented\n\ -t --timeout <n> Timeout in milliseconds. Default: 180\n\
-w --wait Not yet implemented: blocking until operation is completed\n\ -w --wait Not yet implemented: blocking until operation is completed\n\
-s --permanent Not yet implemented: make changes immediately permanent\n\n\ -s --permanent Not yet implemented: make changes immediately permanent\n\n\
Command Summary:\n\ Command Summary:\n\

View file

@ -22,11 +22,11 @@ int Program::list() {
Packet p = Packet(Packet::DISCOVERY); Packet p = Packet(Packet::DISCOVERY);
p.setHostMac(host.getMac()); p.setHostMac(host.getMac());
p.setPayload( { }); p.setPayload( { });
bytes a = p.getBytes(); bytes b = p.getBytes();
p.encode(a); p.encode(b);
try { try {
asio::io_service io_service; boost::asio::io_service io_service;
Socket s(io_service); Socket s(io_service);
s.setHostIp(host.getIp()); s.setHostIp(host.getIp());
s.init(DST_PORT, SRC_PORT); s.init(DST_PORT, SRC_PORT);
@ -47,12 +47,12 @@ int Program::list() {
Switch s = Switch(); Switch s = Switch();
s.parse(d); s.parse(d);
File f; 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"; std::cout <<"Devices:\n\t"<<s.settings.hostname<<" ("<< s.device.type<<")\tMAC: "<<s.device.mac<<"\tIP: "<<s.settings.ip_addr<<"\n";
} }
return 1; return 1;
}; };
s.send(a); s.send(b);
io_service.run(); io_service.run();
} catch (std::exception& e) { } catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n"; std::cerr << "Exception: " << e.what() << "\n";
@ -63,7 +63,7 @@ int Program::list() {
int Program::sniff() { int Program::sniff() {
printf("Listening:\n"); printf("Listening:\n");
try { try {
asio::io_service io_service; boost::asio::io_service io_service;
Socket s(io_service); Socket s(io_service);
s.setHostIp(host.getIp()); s.setHostIp(host.getIp());
s.init(DST_PORT, SRC_PORT); s.init(DST_PORT, SRC_PORT);
@ -132,7 +132,7 @@ int Program::getProperty() {
p.encode(a); p.encode(a);
try { try {
asio::io_service io_service; boost::asio::io_service io_service;
Socket s(io_service); Socket s(io_service);
s.setHostIp(host.getIp()); s.setHostIp(host.getIp());
s.init(DST_PORT, SRC_PORT); s.init(DST_PORT, SRC_PORT);
@ -168,14 +168,16 @@ int Program::save() {
Switch sw = Switch(); Switch sw = Switch();
sw.settings.hostname = "testname.lan"; sw.settings.hostname = "testname.lan";
File f; File f;
f.write("config.json", sw.toString()); f.write(sw.toString());
return 1; return 1;
} }
int Program::restore() { int Program::restore() {
File f; File f;
Switch sw; Switch sw;
sw.parse(f.read("config.json")); 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"; std::cout << "Devices:\n\t" << sw.settings.hostname << " ("
<< sw.device.type << ")\tMAC: " << sw.device.mac << "\tIP: "
<< sw.settings.ip_addr << "\n";
return 1; return 1;
} }
int Program::flash() { int Program::flash() {

View file

@ -7,15 +7,14 @@
#include <cstdlib> #include <cstdlib>
#include <array> #include <array>
#include <unistd.h> #include <unistd.h>
#include <asio.hpp>
#include "Socket.h" #include "Socket.h"
#include "Packet.h" #include "Packet.h"
#include "Options.h" #include "Options.h"
#include "Host.h" #include "Host.h"
#include "Types.h" #include "Types.h"
Socket::Socket(asio::io_service& io_service) : Socket::Socket(boost::asio::io_service& io_service) :
send_socket_(io_service), receive_socket_(io_service) { send_socket_(io_service), receive_socket_(io_service), timer(io_service) {
} }
//, resolver( io_service) //, resolver( io_service)
void Socket::init(short dst_port, short src_port) { 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) if (options.flags & FLAG_DEBUG)
std::cout << "Local IP:\t" << local_ip << "\n"; std::cout << "Local IP:\t" << local_ip << "\n";
wildcard_endpoint_ = asio::ip::udp::endpoint( wildcard_endpoint_ = boost::asio::ip::udp::endpoint(
asio::ip::address_v4::from_string("0.0.0.0"), src_port); boost::asio::ip::address_v4::from_string("0.0.0.0"), src_port);
local_endpoint_ = asio::ip::udp::endpoint(asio::ip::address_v4(local_ip), local_endpoint_ = boost::asio::ip::udp::endpoint(
src_port); boost::asio::ip::address_v4(local_ip), src_port);
broadcast_endpoint_ = asio::ip::udp::endpoint( broadcast_endpoint_ = boost::asio::ip::udp::endpoint(
asio::ip::address_v4::from_string("255.255.255.255"), dst_port); boost::asio::ip::address_v4::from_string("255.255.255.255"),
dst_port);
send_socket_.open(asio::ip::udp::v4()); send_socket_.open(boost::asio::ip::udp::v4());
send_socket_.set_option(asio::socket_base::broadcast(true)); send_socket_.set_option(boost::asio::socket_base::broadcast(true));
send_socket_.set_option(asio::socket_base::reuse_address(true)); send_socket_.set_option(boost::asio::socket_base::reuse_address(true));
send_socket_.bind(local_endpoint_); send_socket_.bind(local_endpoint_);
receive_socket_.open(asio::ip::udp::v4()); receive_socket_.open(boost::asio::ip::udp::v4());
receive_socket_.set_option(asio::socket_base::broadcast(true)); receive_socket_.set_option(boost::asio::socket_base::broadcast(true));
receive_socket_.set_option(asio::socket_base::reuse_address(true)); receive_socket_.set_option(boost::asio::socket_base::reuse_address(true));
receive_socket_.bind(wildcard_endpoint_); 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) { void Socket::setHostIp(ipAddr ip) {
@ -54,9 +65,9 @@ void Socket::setHostIp(ipAddr ip) {
void Socket::send(bytes data) { void Socket::send(bytes data) {
unsigned char * a = &data[0]; 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_, broadcast_endpoint_,
[this](asio::error_code ec, std::size_t bytes_sent) [this](boost::system::error_code ec, std::size_t bytes_sent)
{ {
listen(); listen();
}); });
@ -64,12 +75,13 @@ void Socket::send(bytes data) {
void Socket::listen() { void Socket::listen() {
data.resize(MAX_LENGTH); 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_, 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) { if (ec || bytes_recvd == 0) {
listen(); //listen();
// TODO distinguish error codes
} else { } else {
data.resize(bytes_recvd); data.resize(bytes_recvd);
Packet p = Packet(Packet::RETURN); Packet p = Packet(Packet::RETURN);
@ -77,8 +89,9 @@ void Socket::listen() {
p.parse(data); p.parse(data);
datasets l = p.getPayload(); datasets l = p.getPayload();
if(!callback(p)) { if(!callback(p)) {
listen(); //TODO do something
} }
listen();
} }
}); });
} }

View file

@ -8,7 +8,7 @@
#ifndef SOCKET_H_ #ifndef SOCKET_H_
#define SOCKET_H_ #define SOCKET_H_
#include <asio.hpp> #include <boost/asio.hpp>
#include "Packet.h" #include "Packet.h"
#include "Types.h" #include "Types.h"
@ -19,7 +19,7 @@
class Socket { class Socket {
public: public:
Socket(asio::io_service&); Socket(boost::asio::io_service&);
virtual ~Socket() { virtual ~Socket() {
} }
void init(short, short); void init(short, short);
@ -31,13 +31,13 @@ public:
}; };
private: private:
asio::ip::udp::socket send_socket_; boost::asio::ip::udp::socket send_socket_;
asio::ip::udp::socket receive_socket_; boost::asio::ip::udp::socket receive_socket_;
//asio::ip::udp::resolver resolver; boost::asio::ip::udp::endpoint broadcast_endpoint_;
asio::ip::udp::endpoint broadcast_endpoint_; boost::asio::ip::udp::endpoint remote_endpoint_;
asio::ip::udp::endpoint remote_endpoint_; boost::asio::ip::udp::endpoint wildcard_endpoint_;
asio::ip::udp::endpoint wildcard_endpoint_; boost::asio::ip::udp::endpoint local_endpoint_;
asio::ip::udp::endpoint local_endpoint_; boost::asio::deadline_timer timer;
bytes data = bytes(MAX_LENGTH); bytes data = bytes(MAX_LENGTH);
ipAddr local_ip; ipAddr local_ip;

View file

@ -118,7 +118,7 @@ struct Options {
std::string interface; std::string interface;
std::string file; std::string file;
int debug_level=0; int debug_level=0;
long timeout; long timeout = 180U;
}; };
#endif /* TYPES_H_ */ #endif /* TYPES_H_ */

View file

@ -5,6 +5,9 @@
* Author: jdi * Author: jdi
*/ */
#include "../include/rapidjson/document.h"
#include "../include/rapidjson/prettywriter.h"
#include "jsonNode.h" #include "jsonNode.h"
jsonNode::jsonNode(const std::string &x, doc &root) { 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) { jsonNode::jsonNode(const ipAddr &x, doc &root) {
super(rapidjson::kStringType); super(rapidjson::kStringType);
char buffer[16]; char buffer[16];
int len = sprintf(buffer, "%d.%d.%d.%d", x[0], x[1], int len = sprintf(buffer, "%d.%d.%d.%d", x[0], x[1], x[2], x[3]);
x[2], x[3]);
this->SetString(buffer, static_cast<size_t>(len), root.GetAllocator()); this->SetString(buffer, static_cast<size_t>(len), root.GetAllocator());
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
} }
@ -27,8 +29,8 @@ jsonNode::jsonNode(const ipAddr &x, doc &root) {
jsonNode::jsonNode(const macAddr &x, doc &root) { jsonNode::jsonNode(const macAddr &x, doc &root) {
super(rapidjson::kStringType); super(rapidjson::kStringType);
char buffer[18]; char buffer[18];
int len = sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", x[0], x[1], int len = sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", x[0], x[1], x[2],
x[2], x[3], x[4], x[5]); x[3], x[4], x[5]);
this->SetString(buffer, static_cast<size_t>(len), root.GetAllocator()); this->SetString(buffer, static_cast<size_t>(len), root.GetAllocator());
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
} }

View file

@ -5,6 +5,7 @@
* Author: jdi * Author: jdi
*/ */
#include <string>
#include "lookupTable.h" #include "lookupTable.h"
lookupTable::lookupTable(std::initializer_list<set> l) { lookupTable::lookupTable(std::initializer_list<set> l) {