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
|
# 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
|
11
src/File.cpp
11
src/File.cpp
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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\
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
18
src/Socket.h
18
src/Socket.h
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue