1.2
This commit is contained in:
parent
299490ca5f
commit
0f01d375db
13 changed files with 347 additions and 262 deletions
3
Makefile
3
Makefile
|
@ -15,8 +15,7 @@ $(BUILDDIR):
|
|||
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system -lpthread
|
||||
|
||||
$(CC) $^ -o $(BUILDDIR)/$@ -lboost_filesystem -lboost_system -lreadline -lboost_program_options
|
||||
|
||||
$(OBJECTS): $(BUILDDIR)/%.o : $(SOURCEDIR)/%.cpp
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
|
|
@ -3,8 +3,10 @@ Command-Line Tool which might in the future be able to configure TP-Link Easy Sm
|
|||
The usage is loosely based on the swconfig utility.
|
||||
|
||||
### dependencys
|
||||
libboost-filesystem-dev
|
||||
libboost-system-dev
|
||||
libboost-filesystem
|
||||
libboost-system
|
||||
libboost-program-options
|
||||
libreadline
|
||||
|
||||
### compatible devices
|
||||
+ TL-SG105E
|
||||
|
|
|
@ -7,27 +7,40 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include<boost/program_options/parsers.hpp>
|
||||
#include<readline/readline.h>
|
||||
#include<readline/history.h>
|
||||
|
||||
#include "Program.h"
|
||||
#include "Interactive.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Interactive::Interactive() {
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
}
|
||||
|
||||
Interactive::~Interactive() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
int Interactive::run() {
|
||||
int Interactive::loop() {
|
||||
string cmd;
|
||||
while(cmd.compare("quit")){
|
||||
cout<< "smrtlink>" << flush;
|
||||
cin >> cmd;
|
||||
cout << cmd <<endl;;
|
||||
vector<string> v;
|
||||
Program p = Program();
|
||||
p.init();
|
||||
while (1) {
|
||||
cmd = readline("smrtlink> ");
|
||||
if (!cmd.compare("quit") || !cmd.compare("q"))
|
||||
return 0;
|
||||
if (!cmd.empty()) {
|
||||
add_history(cmd.c_str());
|
||||
v = boost::program_options::split_unix(cmd);
|
||||
p.run(v);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Interactive::single(vector<string> v) {
|
||||
Program p = Program();
|
||||
p.init();
|
||||
p.run(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,12 @@
|
|||
|
||||
class Interactive {
|
||||
public:
|
||||
Interactive();
|
||||
virtual ~Interactive();
|
||||
int run();
|
||||
Interactive() {
|
||||
}
|
||||
virtual ~Interactive() {
|
||||
}
|
||||
int loop();
|
||||
int single(std::vector<std::string> v);
|
||||
};
|
||||
|
||||
#endif /* INTERACTIVE_H_ */
|
||||
|
|
|
@ -158,8 +158,8 @@ std::string Packet::opCodeToString() {
|
|||
return "SET";
|
||||
case CONFIRM:
|
||||
return "CONFIRM";
|
||||
case RETURN:
|
||||
return "RETURN";
|
||||
case REPLY:
|
||||
return "REPLY";
|
||||
default:
|
||||
return "NONE";
|
||||
}
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
|
||||
static short sequenceId = 0;
|
||||
|
||||
class Packet
|
||||
{
|
||||
class Packet {
|
||||
public:
|
||||
enum OpCode {DISCOVERY, GET, RETURN, SET, CONFIRM, NONE};
|
||||
enum OpCode {
|
||||
DISCOVERY, GET, REPLY, SET, CONFIRM, NONE
|
||||
};
|
||||
Packet(OpCode);
|
||||
static void encode(bytes&);
|
||||
bytes getBytes();
|
||||
|
|
160
src/Program.cpp
160
src/Program.cpp
|
@ -6,6 +6,9 @@
|
|||
*/
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include "Constant.h"
|
||||
#include "Program.h"
|
||||
|
@ -14,11 +17,110 @@
|
|||
#include "Socket.h"
|
||||
#include "Switch.h"
|
||||
#include "Packet.h"
|
||||
#include "Filter.h"
|
||||
#include "Types.h"
|
||||
#include "lookup.h"
|
||||
#include "table.h"
|
||||
|
||||
using namespace smrtlink;
|
||||
using namespace std;
|
||||
|
||||
int Program::run(vector<string> arg) {
|
||||
int optind = 0;
|
||||
std::vector<std::string> vect;
|
||||
std::map<std::string, std::string> ll;
|
||||
std::cmatch sm;
|
||||
std::string cmd = arg[optind++];
|
||||
|
||||
io_service->reset();
|
||||
sock->clear();
|
||||
switch (caseArg(cmd.c_str())) {
|
||||
case caseArg("reboot"):
|
||||
if (reboot())
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("reset"):
|
||||
if (!reset())
|
||||
return 0;
|
||||
break;
|
||||
case caseArg("save"):
|
||||
if (save())
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("restore"):
|
||||
if (restore())
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("flash"):
|
||||
if (flash())
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case caseArg("list"):
|
||||
if (list())
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case caseArg("sniff"):
|
||||
if (sniff())
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case caseArg("encode"):
|
||||
if (optind < arg.size()) {
|
||||
std::string s(arg[optind]);
|
||||
optind++;
|
||||
if (!encode(s))
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, "Argument expected after encode\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case caseArg("set"):
|
||||
while (optind < arg.size()) {
|
||||
if (regex_match(arg[optind].c_str(), sm,
|
||||
std::regex("^([a-z]+)=(.*)$"))) {
|
||||
if (!snd_lookup.exists(sm[1]) && !rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
ll.insert(std::pair<std::string, std::string>(sm[1], sm[2]));
|
||||
} else {
|
||||
cerr << "Invalid Syntax " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (setProperty(ll))
|
||||
return 1;
|
||||
break;
|
||||
case caseArg("get"):
|
||||
while (optind < arg.size()) {
|
||||
if (regex_match(arg[optind].c_str(), sm,
|
||||
std::regex("^([a-z]+)$"))) {
|
||||
if (!snd_lookup.exists(sm[1]) && !rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
vect.push_back(sm[1]);
|
||||
} else {
|
||||
cerr << "Invalid argument " << arg[optind] << endl;
|
||||
return 1;
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (getProperty(vect))
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command: %s\n", cmd.c_str());
|
||||
return 1;
|
||||
}
|
||||
io_service->run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printHeader(Packet p) {
|
||||
if (options.flags.HEADER) {
|
||||
if (options.flags.HEX) {
|
||||
|
@ -93,15 +195,18 @@ int Program::list() {
|
|||
cout <<"Received Payload:\n"<<a.getBody()<<"\n";
|
||||
} else {
|
||||
datasets d =a.getPayload();
|
||||
Switch sw = Switch();
|
||||
sw.parse(d);
|
||||
|
||||
int b = a.getSwitchMac().hash();
|
||||
if (devices.empty()||devices.find(b) == devices.end())
|
||||
devices.insert(pair<int,Switch>(b,Switch()));
|
||||
devices[a.getSwitchMac().hash()].parse(d);
|
||||
devices[a.getSwitchMac().hash()].print();
|
||||
|
||||
File f;
|
||||
f.write(sw.toString());
|
||||
sw.print();
|
||||
f.write(devices[a.getSwitchMac().hash()].toString());
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
io_service->run();
|
||||
} catch (exception& e) {
|
||||
cerr << "Exception: " << e.what() << "\n";
|
||||
}
|
||||
|
@ -111,22 +216,15 @@ int Program::list() {
|
|||
int Program::sniff() {
|
||||
printf("Listening:\n");
|
||||
try {
|
||||
boost::asio::io_service io_service;
|
||||
Socket s(io_service);
|
||||
s.setHostIp(host.getIp());
|
||||
s.init(DST_PORT, SRC_PORT);
|
||||
s.callback = [](Packet p) {
|
||||
sock->listen([](Packet p) {
|
||||
cout << p.opCodeToString() << "\n";
|
||||
printHeader(p);
|
||||
printPacket(p);
|
||||
return 0;
|
||||
};
|
||||
s.listen();
|
||||
io_service.run();
|
||||
});
|
||||
} catch (exception& e) {
|
||||
cerr << "Exception: " << e.what() << "\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -179,8 +277,6 @@ int Program::setProperty(map<string, string> prop) {
|
|||
});
|
||||
return 0;
|
||||
});
|
||||
|
||||
io_service->run();
|
||||
} catch (exception& e) {
|
||||
cerr << "Exception: " << e.what() << "\n";
|
||||
}
|
||||
|
@ -210,7 +306,6 @@ int Program::getProperty(vector<string> prop) {
|
|||
return 0;
|
||||
});
|
||||
|
||||
io_service->run();
|
||||
} catch (exception& e) {
|
||||
cerr << "Exception: " << e.what() << "\n";
|
||||
}
|
||||
|
@ -240,19 +335,20 @@ int Program::flash() {
|
|||
|
||||
int Program::reboot() {
|
||||
try {
|
||||
discover([this](Packet a) {
|
||||
discover(
|
||||
[this](Packet a) {
|
||||
datasets d =a.getPayload();
|
||||
Switch sw = Switch();
|
||||
sw.parse(d);
|
||||
cout <<sw.settings.hostname<<"\t";
|
||||
int b = a.getSwitchMac().hash();
|
||||
if (devices.empty()||devices.find(b) == devices.end())
|
||||
devices.insert(pair<int,Switch>(b,Switch()));
|
||||
devices[a.getSwitchMac().hash()].parse(d);
|
||||
datasets t = { {SND_PING, 0, {}}};
|
||||
get(a, t, [this](Packet a) {
|
||||
datasets d =a.getPayload();
|
||||
Switch sw = Switch();
|
||||
sw.parse(d);
|
||||
cout <<devices[a.getSwitchMac().hash()].settings.hostname<<"\t";
|
||||
devices[a.getSwitchMac().hash()].parse(d);
|
||||
datasets t = { {REBOOT, 1, {options.flags.PERMANENT?(byte)1:(byte)0}}};
|
||||
set(a,t,[this](Packet a) {
|
||||
if( a.getOpCode()==Packet::CONFIRM)
|
||||
cout<< "rebooting now.\n";
|
||||
return 0;
|
||||
});
|
||||
|
@ -260,7 +356,6 @@ int Program::reboot() {
|
|||
});
|
||||
return 0;
|
||||
});
|
||||
io_service->run();
|
||||
} catch (exception& e) {
|
||||
cerr << "Exception: " << e.what() << "\n";
|
||||
}
|
||||
|
@ -289,33 +384,32 @@ int Program::reset() {
|
|||
});
|
||||
return 0;
|
||||
});
|
||||
io_service->run();
|
||||
} catch (exception& e) {
|
||||
cerr << "Exception: " << e.what() << "\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Program::discover(function<int(Packet)> c) {
|
||||
int Program::discover(Listener c) {
|
||||
Packet p = Packet(Packet::DISCOVERY);
|
||||
p.setHostMac(host.getMac());
|
||||
p.setPayload( { });
|
||||
sock->callback = c;
|
||||
sock->listen(c, Filter(Packet::REPLY));
|
||||
sock->send(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Program::get(Packet l, datasets t, function<int(Packet)> c) {
|
||||
int Program::get(Packet l, datasets t, Listener c) {
|
||||
Packet p = Packet(Packet::GET);
|
||||
p.setSwitchMac(l.getSwitchMac());
|
||||
p.setHostMac(host.getMac());
|
||||
p.setPayload(t);
|
||||
sock->callback = c;
|
||||
sock->listen(c, Filter(Packet::REPLY).mac(l.getSwitchMac()));
|
||||
sock->send(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Program::set(Packet l, datasets t, function<int(Packet)> c) {
|
||||
int Program::set(Packet l, datasets t, Listener c) {
|
||||
Packet p = Packet(Packet::SET);
|
||||
p.setSwitchMac(l.getSwitchMac());
|
||||
p.setTokenId(l.getTokenId());
|
||||
|
@ -325,12 +419,14 @@ int Program::set(Packet l, datasets t, function<int(Packet)> c) {
|
|||
datasets ld = { { LOGIN_USER, (short) (n.size()), n }, { LOGIN_PASSWORD,
|
||||
(short) (w.size()), w } };
|
||||
p.setPayload(ld + t);
|
||||
sock->callback = c;
|
||||
sock->listen(c, Filter(Packet::CONFIRM).mac(l.getSwitchMac()));
|
||||
sock->send(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Program::init() {
|
||||
io_service = std::make_shared<boost::asio::io_service>();
|
||||
sock = std::make_shared < Socket > (*io_service);
|
||||
if (options.interface.compare("") == 0)
|
||||
options.interface = host.getIface();
|
||||
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
#define PROGRAM_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "Types.h"
|
||||
#include "Host.h"
|
||||
#include "Switch.h"
|
||||
#include "Socket.h"
|
||||
|
||||
class Program {
|
||||
|
@ -19,15 +21,19 @@ private:
|
|||
std::shared_ptr<boost::asio::io_service> io_service;
|
||||
std::shared_ptr<Socket> sock;
|
||||
Host host = Host();
|
||||
std::map<int, Switch> devices;
|
||||
int get(Packet, datasets, std::function<int(Packet)>);
|
||||
int set(Packet, datasets, std::function<int(Packet)>);
|
||||
int discover(std::function<int(Packet)>);
|
||||
public:
|
||||
Program() {
|
||||
io_service = std::make_shared<boost::asio::io_service>();
|
||||
sock = std::make_shared<Socket>(*io_service);
|
||||
}
|
||||
void init();
|
||||
int run(std::vector<std::string>);
|
||||
std::function<int()> callback = []() {
|
||||
return 0;
|
||||
};
|
||||
|
||||
int list();
|
||||
int sniff();
|
||||
int encode(std::string);
|
||||
|
|
|
@ -5,22 +5,26 @@
|
|||
* Author: jdi
|
||||
*/
|
||||
#include <cstdlib>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <unistd.h>
|
||||
#include "Socket.h"
|
||||
#include "Packet.h"
|
||||
#include "Constant.h"
|
||||
#include "Filter.h"
|
||||
#include "Host.h"
|
||||
#include "Types.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
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) {
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
Socket::~Socket() {
|
||||
}
|
||||
|
||||
void Socket::init(short dst_port, short src_port) {
|
||||
if (options.flags.REVERSE) {
|
||||
short p = dst_port;
|
||||
dst_port = src_port;
|
||||
|
@ -47,26 +51,25 @@ void Socket::init(short dst_port, short src_port) {
|
|||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
void Socket::setHostIp(ipAddr ip) {
|
||||
local_ip = ip;
|
||||
}
|
||||
|
||||
void Socket::clear(){
|
||||
callback.clear();
|
||||
}
|
||||
|
||||
void Socket::listen(Listener l, Filter f) {
|
||||
if (callback.find(f) == callback.end()) {
|
||||
callback.insert(ListenerPair(f, l));
|
||||
} else {
|
||||
callback[f] = l;
|
||||
}
|
||||
receive();
|
||||
}
|
||||
|
||||
void Socket::send(Packet p) {
|
||||
bytes data = p.getBytes();
|
||||
p.encode(data);
|
||||
|
@ -75,11 +78,12 @@ void Socket::send(Packet p) {
|
|||
broadcast_endpoint_,
|
||||
[this](boost::system::error_code ec, std::size_t bytes_sent)
|
||||
{
|
||||
listen();
|
||||
receive();
|
||||
settimeout();
|
||||
});
|
||||
}
|
||||
|
||||
void Socket::listen() {
|
||||
void Socket::receive() {
|
||||
data.resize(MAX_LENGTH);
|
||||
receive_socket_.async_receive_from(boost::asio::buffer(data, MAX_LENGTH),
|
||||
remote_endpoint_,
|
||||
|
@ -92,13 +96,37 @@ void Socket::listen() {
|
|||
data.resize(bytes_recvd);
|
||||
Packet p = Packet(Packet::NONE);
|
||||
p.encode(data);
|
||||
// std::cout << "err" << p.getErrorCode() <<std::endl;
|
||||
p.parse(data);
|
||||
//std::cout << "err" << p.getErrorCode() <<std::endl;
|
||||
if(!callback(p)) {
|
||||
//TODO do something
|
||||
for(auto r : callback) {
|
||||
if(r.first.pass(p)) {
|
||||
r.second(p);
|
||||
// std::cout<<"pass"<<std::endl;
|
||||
break;
|
||||
} else {
|
||||
// std::cout<<"no pass"<<std::endl;
|
||||
}
|
||||
listen();
|
||||
}
|
||||
receive();
|
||||
settimeout();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Socket::settimeout() {
|
||||
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();
|
||||
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_);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
18
src/Socket.h
18
src/Socket.h
|
@ -8,8 +8,10 @@
|
|||
#ifndef SOCKET_H_
|
||||
#define SOCKET_H_
|
||||
|
||||
#include <map>
|
||||
#include <boost/asio.hpp>
|
||||
#include "Packet.h"
|
||||
#include "Filter.h"
|
||||
#include "Types.h"
|
||||
|
||||
#define SRC_PORT 29809
|
||||
|
@ -17,20 +19,22 @@
|
|||
|
||||
#define MAX_LENGTH 1024
|
||||
|
||||
typedef std::function<int(Packet)> Listener;
|
||||
typedef std::pair<Filter, Listener> ListenerPair;
|
||||
|
||||
class Socket {
|
||||
public:
|
||||
Socket(boost::asio::io_service&);
|
||||
virtual ~Socket() {
|
||||
}
|
||||
virtual ~Socket();
|
||||
void init(short, short);
|
||||
void clear();
|
||||
void send(Packet);
|
||||
void listen();
|
||||
void setHostIp(ipAddr);
|
||||
std::function<int(Packet)> callback = [](Packet a) {
|
||||
return 0;
|
||||
};
|
||||
void listen(Listener l, Filter f = Filter());
|
||||
|
||||
private:
|
||||
void receive();
|
||||
void settimeout();
|
||||
boost::asio::ip::udp::socket send_socket_;
|
||||
boost::asio::ip::udp::socket receive_socket_;
|
||||
boost::asio::ip::udp::endpoint broadcast_endpoint_;
|
||||
|
@ -40,7 +44,7 @@ private:
|
|||
boost::asio::deadline_timer timer;
|
||||
bytes data = bytes(MAX_LENGTH);
|
||||
ipAddr local_ip;
|
||||
int initialized = 0;
|
||||
std::map<Filter, Listener> callback = { };
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -65,9 +65,13 @@ public:
|
|||
int parse(datasets);
|
||||
int parse(dataset);
|
||||
int parse(std::string);
|
||||
int print();
|
||||
int set(std::pair<std::string,std::string>);
|
||||
|
||||
std::string get(std::string);
|
||||
std::string toString();
|
||||
|
||||
int print();
|
||||
|
||||
struct {
|
||||
std::string type;
|
||||
std::string hardware_version;
|
||||
|
|
33
src/Types.h
33
src/Types.h
|
@ -50,6 +50,28 @@ public:
|
|||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
int hash() {
|
||||
int ret=0;
|
||||
for (unsigned i = 0; i < 6; i++) {
|
||||
ret = (ret*33) ^ (*this)[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool operator==(const macAddr &A) {
|
||||
for (unsigned i = 0; i < 6; i++) {
|
||||
if(A[i]!=(*this)[i])return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const macAddr &A) {
|
||||
for (unsigned i = 0; i < 6; i++) {
|
||||
if(A[i]!=(*this)[i])return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -95,6 +117,14 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
namespace smrtlink {
|
||||
|
||||
constexpr unsigned int caseArg(const char* str, int h = 0) {
|
||||
return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> operator+(const std::vector<T> &A, const std::vector<T> &B) {
|
||||
std::vector<T> AB;
|
||||
|
@ -117,6 +147,7 @@ struct Options {
|
|||
bool JSON;
|
||||
bool PLAIN;
|
||||
bool REVERSE;
|
||||
|
||||
bool HEADER;
|
||||
bool PERMANENT;
|
||||
bool WAIT;
|
||||
|
@ -128,7 +159,7 @@ struct Options {
|
|||
std::string file;
|
||||
int debug_level = 0;
|
||||
int verbosity = 0;
|
||||
long timeout = 180U;
|
||||
long timeout = 250U;
|
||||
};
|
||||
|
||||
#endif /* TYPES_H_ */
|
||||
|
|
122
src/smrtlink.cpp
122
src/smrtlink.cpp
|
@ -1,14 +1,13 @@
|
|||
//============================================================================
|
||||
// Name : smrtlink.cpp
|
||||
// Author : jdi
|
||||
// Version :
|
||||
// Version : 1.2
|
||||
// Copyright : GPL v2
|
||||
// Description : SmrtLink in C++, Ansi-style
|
||||
//============================================================================
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
@ -21,6 +20,7 @@
|
|||
#include "Interactive.h"
|
||||
#include "Host.h"
|
||||
#include "Program.h"
|
||||
#include "Types.h"
|
||||
#include "Switch.h"
|
||||
#include "lookup.h"
|
||||
|
||||
|
@ -32,10 +32,6 @@ using namespace std;
|
|||
|
||||
Options options;
|
||||
|
||||
constexpr unsigned int caseArg(const char* str, int h = 0) {
|
||||
return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h];
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int index, opt;
|
||||
|
||||
|
@ -56,7 +52,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "bhrVsxP:U:i:t::", longopts,
|
||||
while ((opt = getopt_long(argc, argv, "bhrVXsxP:U:i:t::", longopts,
|
||||
&index)) != -1) {
|
||||
switch (opt) {
|
||||
|
||||
|
@ -149,118 +145,20 @@ int main(int argc, char *argv[]) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
Interactive p = Interactive();
|
||||
if (options.flags.INTERACTIVE) {
|
||||
if (optind < argc) {
|
||||
cerr << "Command is ignored in interactive mode\n";
|
||||
}
|
||||
Interactive p = Interactive();
|
||||
if (!p.run())
|
||||
if (!p.loop())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if (optind < argc) {
|
||||
Program p = Program();
|
||||
p.init();
|
||||
std::vector<std::string> vect;
|
||||
std::map<std::string, std::string> list;
|
||||
std::cmatch sm;
|
||||
std::string cmd = std::string(argv[optind++]);
|
||||
switch (caseArg(cmd.c_str())) {
|
||||
case caseArg("reboot"):
|
||||
if (!p.reboot())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("reset"):
|
||||
if (!p.reset())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("save"):
|
||||
if (!p.save())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("restore"):
|
||||
if (!p.restore())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("flash"):
|
||||
if (!p.flash())
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
|
||||
case caseArg("list"):
|
||||
if (!p.list())
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case caseArg("sniff"):
|
||||
if (!p.sniff())
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case caseArg("encode"):
|
||||
if (optind < argc) {
|
||||
std::string s(argv[optind]);
|
||||
optind++;
|
||||
if (p.encode(s))
|
||||
exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
fprintf(stderr, "Argument expected after encode\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case caseArg("set"):
|
||||
while (optind < argc) {
|
||||
if (regex_match(argv[optind], sm,
|
||||
std::regex("^([a-z]+)=(.*)$"))) {
|
||||
if (!snd_lookup.exists(sm[1])&&!rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
list.insert(
|
||||
std::pair<std::string, std::string>(sm[1], sm[2]));
|
||||
} else {
|
||||
cerr << "Invalid Syntax " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (!p.setProperty(list))
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Not yet implemented.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case caseArg("get"):
|
||||
while (optind < argc) {
|
||||
if (regex_match(argv[optind], sm, std::regex("^([a-z]+)$"))) {
|
||||
if (!snd_lookup.exists(sm[1])&&!rcv_lookup.exists(sm[1])) {
|
||||
cerr << "Unknown argument " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
vect.push_back(sm[1]);
|
||||
} else {
|
||||
cerr << "Invalid argument " << argv[optind] << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
if (!p.getProperty(vect))
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command: %s\n", cmd.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (optind < argc) {
|
||||
vector<string> v;
|
||||
while (optind < argc)
|
||||
v.push_back(argv[optind++]);
|
||||
p.single(v);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue