summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Reiss <jreiss@multitech.com>2016-02-24 13:58:31 -0600
committerJason Reiss <jreiss@multitech.com>2016-02-24 13:58:31 -0600
commit056b387a1732db3aacec7762a1a67e3b2ee60bb7 (patch)
tree8fcb129cc0084ee4bc795aae2da8fa559055fa43
parent84fcf0333a3620c6a70fe0650fda9684e0a1e259 (diff)
downloadlora-query-056b387a1732db3aacec7762a1a67e3b2ee60bb7.tar.gz
lora-query-056b387a1732db3aacec7762a1a67e3b2ee60bb7.tar.bz2
lora-query-056b387a1732db3aacec7762a1a67e3b2ee60bb7.zip
Add commands: node-config, node-add, node-update, node-delete1.0.0
-rw-r--r--main.cpp296
1 files changed, 230 insertions, 66 deletions
diff --git a/main.cpp b/main.cpp
index 33705bb..0e88644 100644
--- a/main.cpp
+++ b/main.cpp
@@ -40,22 +40,49 @@
#define MAX_RECEIVED_BYTES 2000
#define TIMEOUT 100 /* By default 100 msec */
-int opt_get_stats = 0;
+int opt_get_stats = 0;
int opt_get_nodelist = 0;
int opt_get_json = 0;
int opt_stats_reset = 0;
-int timeout = TIMEOUT;
-const char* cmd_stats = "stats";
+int opt_get_nodeconfig = 0;
+int opt_add_node = 0;
+int opt_delete_node = 0;
+int opt_update_node = 0;
+
+char* node_get_addr;
+char* node_delete_addr;
+char* node_config_addr;
+char* node_update_addr;
+char* node_update_field;
+char* node_update_value;
+int node_add_count = 0;
+char* node_add_args[6];
+
+int timeout = TIMEOUT;
+
+const char* cmd_stats = "stats";
const char* cmd_stats_reset = "stats reset";
-const char* cmd_nodelist = "node list";
+const char* cmd_node_list = "node list";
+const char* cmd_node_config = "node config";
+const char* cmd_node_update = "node update";
+const char* cmd_node_delete = "node delete";
+const char* cmd_nodeadd = "node add";
const std::string lora_network_stats_json("/var/tmp/lora_network_stats.json");
const std::string lora_network_nodelist("/var/tmp/lora_network_nodelist");
const std::string lora_network_nodelist_json("/var/tmp/lora_network_nodelist.json");
+const std::string lora_network_nodeconfig("/var/tmp/lora_network_nodeconfig");
+const std::string lora_network_nodeconfig_json("/var/tmp/lora_network_nodeconfig.json");
std::stringstream receiveStream;
-const int nodeSize = 15;
+const int nodeSize = 16;
+const int configSize = 7;
const std::string NODE_ADDR("nodeAddr");
const std::string NODE_DEV_EUI("devEui");
+const std::string NODE_APP_EUI("appEui");
+const std::string NODE_APP_KEY("appKey");
+const std::string NODE_NS_KEY("nsKey");
+const std::string NODE_DS_KEY("dsKey");
+const std::string NODE_CLASS("class");
const std::string NODE_JOINED("joined");
const std::string NODE_SEQ_NUM("seqNum");
const std::string NODE_PKTS_UP("pktsUp");
@@ -70,42 +97,99 @@ const std::string NODE_SNR_MIX("snrMin");
const std::string NODE_SNR_MAX("snrMax");
const std::string NODE_SNR_AVR("snrAvg");
-void getloraData(const char *command);
+void runCmd(const char *command);
void printStats(void);
void printNodeList(void);
+void printNodeConfig(void);
void saveToFile(const std::string& fileName, const std::string& buffer);
void parseOptions(int argc, char** argv);
void printHelp(const std::string& sApp);
std::string trim(std::string& str);
int main(int argc, char**argv)
-{
+ {
parseOptions(argc, argv);
if (opt_stats_reset) {
- getloraData(cmd_stats_reset);
+ runCmd(cmd_stats_reset);
}
if (opt_get_stats) {
- getloraData(cmd_stats);
+ runCmd(cmd_stats);
printStats();
}
if (opt_get_nodelist) {
- getloraData(cmd_nodelist);
+ runCmd(cmd_node_list);
if (opt_get_json) {
printNodeList();
} else {
- if (receiveStream.str().empty() ) {
+ if (receiveStream.str().empty()) {
return 0;
}
saveToFile(lora_network_nodelist, receiveStream.str());
std::cout << receiveStream.str();
}
}
+ if (opt_get_nodeconfig) {
+ char buff[256];
+ snprintf(buff, 256, "%s %s", cmd_node_config, node_config_addr);
+ runCmd(buff);
+ if (opt_get_json) {
+ printNodeConfig();
+ } else {
+ if (!receiveStream.str().empty()) {
+ saveToFile(lora_network_nodelist, receiveStream.str());
+ std::cout << receiveStream.str();
+ }
+ }
+ }
+ if (opt_add_node) {
+ if (node_add_count < 4) {
+ std::cout << "usage: --node-add <NODE-ADDR> [CLASS] <APP-EUI> <DEV-EUI> ([APP-KEY] | [NET-SKEY] [APP-SKEY])\n";
+ return 0;
+ }
+
+ std::stringstream cmd;
+ cmd << cmd_nodeadd;
+
+ for (int i = 0; i < node_add_count; i++) {
+ cmd << " " << node_add_args[i];
+ }
+
+ runCmd(cmd.str().c_str());
+
+ if (!receiveStream.str().empty()) {
+ std::cout << receiveStream.str();
+ }
+ }
+ if (opt_delete_node) {
+ char buff[256];
+ snprintf(buff, 256, "%s %s", cmd_node_delete, node_delete_addr);
+ runCmd(buff);
+ if (!receiveStream.str().empty()) {
+ std::cout << receiveStream.str();
+ }
+ }
+ if (opt_update_node) {
+
+ std::stringstream cmd;
+ cmd << cmd_node_update;
+
+ cmd << " " << node_update_addr;
+ cmd << " " << node_update_field;
+ cmd << " " << node_update_value;
+
+ runCmd(cmd.str().c_str());
+
+ if (!receiveStream.str().empty()) {
+ std::cout << receiveStream.str();
+ }
+ }
+
return 0;
}
-void getloraData(const char *command) {
+void runCmd(const char *command) {
int sockfd;
struct sockaddr_in servaddr;
int receiveBytes = 0;
@@ -119,15 +203,15 @@ void getloraData(const char *command) {
receiveStream.clear();
if (NULL == command) {
- printError("Command is null\n");
- return;
+ printError("Command is null\n");
+ return;
}
- sockfd=socket(AF_INET,SOCK_DGRAM,0);
- bzero(&servaddr,sizeof(servaddr));
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr=inet_addr(INET_ADDR);
- servaddr.sin_port=htons(INET_PORT);
+ servaddr.sin_addr.s_addr = inet_addr(INET_ADDR);
+ servaddr.sin_port = htons(INET_PORT);
memset(receiveMessage, 0, MAX_RECEIVED_BYTES);
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
@@ -135,13 +219,13 @@ void getloraData(const char *command) {
return;
}
- sendto(sockfd, command, strlen(command), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
+ sendto(sockfd, command, strlen(command), 0, (struct sockaddr *) &servaddr, sizeof(servaddr));
- while(1) {
+ while (1) {
receiveBytes = recvfrom(sockfd, receiveMessage, MAX_RECEIVED_BYTES, 0, NULL, NULL);
- if(receiveBytes < 0) {
- /*printf("timeout\n");*/
- break;
+ if (receiveBytes < 0) {
+ /*printf("timeout\n");*/
+ break;
}
receiveStream << std::string(receiveMessage, receiveBytes);
}
@@ -151,7 +235,7 @@ void printStats() {
Json::Reader reader;
Json::Value stats;
- if (receiveStream.str().empty() ) {
+ if (receiveStream.str().empty()) {
return;
}
@@ -166,7 +250,7 @@ void printStats() {
for (Json::Value::Members::iterator it = keys.begin(); it != keys.end(); ++it) {
const std::string& key = *it;
newKey.clear();
- for (size_t i = 0; i < key.length() ; ++i) {
+ for (size_t i = 0; i < key.length(); ++i) {
if (('_' == key[i]) || ('-' == key[i])) {
if ((i + 1) < key.length()) {
newKey.push_back(std::toupper(key[++i]));
@@ -183,12 +267,50 @@ void printStats() {
std::cout << stats.toStyledString();
}
+void printNodeConfig() {
+ std::string line;
+ std::vector < std::string > parts;
+ Json::Value nodeList = Json::ValueType::arrayValue;
+
+ if (receiveStream.str().empty()) {
+ return;
+ }
+
+ getline(receiveStream, line);
+ while (1) {
+ getline(receiveStream, line);
+ if (line.size() == 0)
+ break;
+
+ line = trim(line);
+ parts = MTS::Text::split(line, " ");
+
+ if (configSize == parts.size()) {
+ Json::Value jNode(Json::objectValue);
+ int index = 0;
+ jNode[NODE_ADDR] = parts[index++];
+ jNode[NODE_DEV_EUI] = parts[index++];
+ jNode[NODE_CLASS] = parts[index++];
+ jNode[NODE_APP_EUI] = parts[index++];
+ jNode[NODE_APP_KEY] = parts[index++];
+ jNode[NODE_NS_KEY] = parts[index++];
+ jNode[NODE_DS_KEY] = parts[index++];
+ nodeList.append(jNode);
+ }
+ else {
+ printError("Incorrect Node Data! parts.size() = [%d]\n", parts.size());
+ }
+ }
+ saveToFile(lora_network_nodelist_json, nodeList.toStyledString());
+ std::cout << nodeList.toStyledString();
+}
+
void printNodeList() {
std::string line;
- std::vector<std::string> parts;
+ std::vector < std::string > parts;
Json::Value nodeList = Json::ValueType::arrayValue;
- if (receiveStream.str().empty() ) {
+ if (receiveStream.str().empty()) {
return;
}
@@ -203,26 +325,28 @@ void printNodeList() {
if (nodeSize == parts.size()) {
Json::Value jNode(Json::objectValue);
- jNode[NODE_ADDR] = parts[0];
- jNode[NODE_DEV_EUI] = parts[1];
- jNode[NODE_JOINED] = parts[2];
- jNode[NODE_SEQ_NUM] = atoi(parts[3].c_str());
- jNode[NODE_PKTS_UP] = atoi(parts[4].c_str());
- jNode[NODE_PKTS_DOWN] = atoi(parts[5].c_str());
- jNode[NODE_PKTS_1ST] = atoi(parts[6].c_str());
- jNode[NODE_PKTS_2ND] = atoi(parts[7].c_str());
- jNode[NODE_DROPPED] = atoi(parts[8].c_str());
- jNode[NODE_RSSI_MIN] = atoi(parts[9].c_str());
- jNode[NODE_RSSI_MAX] = atoi(parts[10].c_str());
- jNode[NODE_RSSI_AVR] = atoi(parts[11].c_str());
- jNode[NODE_SNR_MIX] = atoi(parts[12].c_str());
- jNode[NODE_SNR_MAX] = atoi(parts[13].c_str());
- jNode[NODE_SNR_AVR] = atoi(parts[14].c_str());
+ int index = 0;
+ jNode[NODE_ADDR] = parts[index++];
+ jNode[NODE_DEV_EUI] = parts[index++];
+ jNode[NODE_CLASS] = parts[index++];
+ jNode[NODE_JOINED] = parts[index++];
+ jNode[NODE_SEQ_NUM] = atoi(parts[index++].c_str());
+ jNode[NODE_PKTS_UP] = atoi(parts[index++].c_str());
+ jNode[NODE_PKTS_DOWN] = atoi(parts[index++].c_str());
+ jNode[NODE_PKTS_1ST] = atoi(parts[index++].c_str());
+ jNode[NODE_PKTS_2ND] = atoi(parts[index++].c_str());
+ jNode[NODE_DROPPED] = atoi(parts[index++].c_str());
+ jNode[NODE_RSSI_MIN] = atoi(parts[index++].c_str());
+ jNode[NODE_RSSI_MAX] = atoi(parts[index++].c_str());
+ jNode[NODE_RSSI_AVR] = atoi(parts[index++].c_str());
+ jNode[NODE_SNR_MIX] = atoi(parts[index++].c_str());
+ jNode[NODE_SNR_MAX] = atoi(parts[index++].c_str());
+ jNode[NODE_SNR_AVR] = atoi(parts[index++].c_str());
nodeList.append(jNode);
}
else {
- printError("Incorrect Node Data! parts.size() = [%d]\n", parts.size());
+ printError("Incorrect Node Data! parts.size() = [%d]\n", parts.size());
}
}
saveToFile(lora_network_nodelist_json, nodeList.toStyledString());
@@ -238,45 +362,74 @@ void saveToFile(const std::string& fileName, const std::string& buffer) {
void parseOptions(int argc, char** argv) {
- if(argc == 1) {
+ if (argc == 1) {
printHelp(argv[0]);
exit(0);
}
- const char* short_options = "hvsirnjt:";
+ const char* short_options = "hvsrnc:a:u:d:jt:";
const struct option long_options[] = {
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'v'},
- {"stats", no_argument, 0, 's'},
- {"stats-reset", no_argument, 0, 'r'},
- {"node-list", no_argument, 0, 'n'},
- {"json", no_argument, 0, 'j'},
- {"timeout", required_argument, 0, 't'},
- {0, 0, 0, 0}
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
+ { "stats", no_argument, 0, 's' },
+ { "stats-reset", no_argument, 0, 'r' },
+ { "node-list", no_argument, 0, 'n' },
+ { "node-config", required_argument, 0, 'c' },
+ { "node-add", required_argument, 0, 'a' },
+ { "node-update", required_argument, 0, 'u' },
+ { "node-delete", required_argument, 0, 'd' },
+ { "json", no_argument, 0, 'j' },
+ { "timeout", required_argument, 0, 't' },
+ { 0, 0, 0, 0 }
};
int rez;
int option_index;
- while ((rez=getopt_long(argc, argv, short_options, long_options, &option_index))!=-1) {
- switch(rez){
+ while ((rez = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) {
+ switch (rez) {
case 's': {
++opt_get_stats;
break;
- };
+ }
case 'r': {
- ++opt_stats_reset;
- break;
- };
+ ++opt_stats_reset;
+ break;
+ }
case 'n': {
++opt_get_nodelist;
break;
- };
+ }
+ case 'c': {
+ ++opt_get_nodeconfig;
+ node_config_addr = optarg;
+ break;
+ }
+ case 'a': {
+ ++opt_add_node;
+ node_add_args[node_add_count++] = optarg;
+ for (int i = optind; i < argc; i++) {
+ node_add_args[node_add_count++] = argv[i];
+ }
+ break;
+ }
+ case 'u': {
+ ++opt_update_node;
+ node_update_addr = optarg;
+ node_update_field = argv[optind];
+ node_update_value = argv[optind + 1];
+ break;
+ }
+ case 'd': {
+ ++opt_delete_node;
+ node_delete_addr = optarg;
+ break;
+ }
case 'j': {
++opt_get_json;
break;
- };
+ }
case 't': {
timeout = atoi(optarg);
break;
@@ -285,13 +438,13 @@ void parseOptions(int argc, char** argv) {
printf("Version: %s\n", Version::version.c_str());
exit(0);
break;
- case 'h':
- case '?':
- default: {
+ case 'h':
+ case '?':
+ default: {
printHelp(argv[0]);
exit(0);
break;
- };
+ }
};
};
}
@@ -303,13 +456,24 @@ void printHelp(const std::string& sApp) {
printf("\t--stats (s) : get LoRa Network server statistics\n");
printf("\t--stats-reset (r) : reset LoRa Network server statistics\n");
printf("\t--node-list (n) : get Node List\n");
+ printf("\t--node-config (c) : get Node config\n");
+ printf("\t\tex: --node-config <NODE-ADDR>\n");
+ printf("\t--node-add (a) : add node\n");
+ printf("\t\tusage: --node-add <NODE-ADDR> [CLASS] <APP-EUI> <DEV-EUI> ([APP-KEY] | [NET-SKEY] [APP-SKEY])\n");
+ printf("\t\tex: --node-add 00000001 A 16ea76f6ab663d80 4c194e20d396b5f7d3e1551e4cd320de");
+ printf("\t--node-update (u) : update node info\n");
+ printf("\t\tusage: --node-update <NODE-ADDR> <FIELD-NAME> <VALUE>\n");
+ printf("\t\tex: --node-update 00000001 class C");
+ printf("\t\tex: --node-update 00000001 app-key 4c194e20d396b5f7d3e1551e4cd320de");
+ printf("\t--node-delete (d) : delete a Node\n");
+ printf("\t\tex: --node-delete <NODE-ADDR>\n");
printf("\t--json (j) : data in json format\n");
printf("\t--help (?) : returns this message\n");
printf("\t--version (v) : print version\n");
}
std::string trim(std::string& str) {
- str.erase(std::unique(str.begin(), str.end(), [](char a, char b) { return a == ' ' && b == ' '; } ), str.end() );
+ str.erase(std::unique(str.begin(), str.end(), [](char a, char b) {return a == ' ' && b == ' ';}), str.end());
return str;
}