1 contributor
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#include <sqlite3.h>
#include <strings.h>
//~ #include "json.h"
#include "jsmn.h"
//~ #define MAXLINE 4096
#define MAXLINE 5000
static char logline[MAXLINE]="";
static char current_time[21]="";
static time_t epoch_time=-1;
static unsigned short PORT = 8080;
static int socket_fd;
static int st_log_to_file=0;
static FILE *file_fd=NULL;
#define LATEST 500
#define MAXDEVEUI 100
static char deveui[MAXDEVEUI][17];
static unsigned short deveui_count=0;
sqlite3 *db;
const char sqlite3_name[]="http-okay.db";
static int rc;
char *errMsg = 0;
const char *sql_table_cnx = "CREATE TABLE IF NOT EXISTS cnx("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"ip CHAR(16),"
"port,"
"date CHAR(21));";
const char *sql_table_content = "CREATE TABLE IF NOT EXISTS content("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"date CHAR(21),"
"epoch INTEGER,"
"method CHAR(16),"
"host CHAR(256),"
"path CHAR(2048),"
"version CHAR(16),"
"user_agent CHAR(256),"
"content CHAR(4096));";
const char sql_table_name[] = "content";
const char sql_query_format[] = "SELECT date,content FROM %s ORDER BY id DESC LIMIT %d;";
const char html_output[]="index.2.html";
#define APPNAME "ApplicationServer"
const char html_header[]="<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"
"<link rel=\"icon\" type=\"image/png\" href=\"favicon.png\" sizes=\"32x32\">\n"
"<title>"APPNAME"</title>\n"
"<style>\n"
"html{font-family: \"Lucida Sans\", sans-serif;}\n"
"h1,h2{background-color:#3f87a6;color: #fff;}\n"
"table {margin: 0 auto;text-align: center;border-collapse: collapse;border: 1px solid #d4d4d4;height: 500px;}\n"
"tr:nth-child(even) {background: #d4d4d4;}\n"
"th{background-color: #3f87a6;color: #fff;font-weight: bold;}\n"
"th,td{padding: 1px 4px;font-size: 0.8em;}\n"
"th {border-bottom: 1px solid #d4d4d4;}\n"
".sf7 {background-color: #15db00;font-size: 0.7em}\n"
".sf8 {background-color: #408000;font-size: 0.7em}\n"
".sf9 {background-color: #52ad00;font-size: 0.7em}\n"
".sf10 {background-color: #7a8500;font-size: 0.7em}\n"
".sf11 {background-color: #FF5F1F;color: #fff;font-size: 0.7em}\n"
".sf12 {background-color: #f00;color: #fff;font-size: 0.7em}\n"
".sfna {background-color: #fff;}\n"
"#all-stats {font-size: 1.0em;font-family: monospace; display:inline;}\n"
"li {display: list-item;margin-left: 1em;list-style-type: none;}\n"
".box {width: 30px;text-align: center;display: inline-block;margin-right: 2px;font-size: 0.9em;}\n"
".tooltippacket {visibility: hidden;width: 700px;word-break: break-all;overflow: hidden;background-color: rgba(255,255,255,1);color: #000;padding: 5px 0;padding-left: 10px;position: absolute;z-index: 1;font-size: 0.9em;}\n"
".arrow-up{width: 0;height: 0;margin-bottom: 0px;border-left: 10px solid transparent;border-right: 10px solid transparent;border-bottom: 10px solid #108000;display: inline-block;}"
".arrow-up-gray{width: 0;height: 0;margin-bottom: 0px;border-left: 10px solid transparent;border-right: 10px solid transparent;border-bottom: 10px solid #ccc;display: inline-block;}"
".arrow-up:hover .tooltippacket,"
".arrow-up-gray:hover .tooltippacket {visibility: visible;}\n"
".arrow-up:hover,"
".arrow-up-gray:hover {background-color: yellow;}\n"
".btn-green {background: #1abc9c; margin-right: 4px;}\n"
"</style>\n"
"</head>\n"
"<body>\n"
" <h2>"APPNAME"</h2>\n";
const char html_header_2[]="<script>\n"
"function filterOut(classname) {\n"
" const collection = document.getElementsByClassName(classname);\n"
" for (let i = 0; i < collection.length; i++) {\n"
" if(collection[i].style.display == 'none' ) {\n"
" collection[i].style.display='table-row';\n"
" document.getElementById(\"f\"+classname).style.color=\"#000\";\n"
" } else {\n"
" collection[i].style.display='none';\n"
" document.getElementById(\"f\"+classname).style.color=\"#faa\";\n"
" }\n"
" }\n"
"}\n"
"function clickAll() {\n"
" document.querySelectorAll('.stat-box').forEach(box => box.click());\n"
"}\n"
"</script>\n"
"</body></html>\n"
"\n";
const char html_stat_start[]="<button class=\"btn-green\" onclick=\"clickAll()\">ToggleAll</button>\n<button class=\"btn-green\" onClick=\"window.location.reload();\">Reload</button>\n"
"<hr />\n"
"<div id=\"all-stats\">\n";
const char html_stat_end[]="</div>\n<hr>\n";
static char *get_rfc3339() {
epoch_time = time(NULL);
struct tm *tm_info;
tm_info = gmtime(&epoch_time);
strftime(current_time, 21, "%Y-%m-%dT%H:%M:%SZ", tm_info);
return current_time;
}
const char* colorSnr(float f) {
if( f < -7.5) {
return "sf12";
} else if( f < -5) {
return "sf11";
} else if( f < -2.5) {
return "sf10";
} else if( f < 0) {
return "sf9";
} else if( f < 2.5) {
return "sf8";
} else {
return "sf7";
}
}
const char* colorRssi(float f) {
if( f < -105) {
return "sf12";
} else if( f < -95) {
return "sf11";
} else if( f < -85) {
return "sf10";
} else if( f < 80) {
return "sf9";
} else {
return "sf7";
}
}
static void *stats_box(char *stats) {
//~ char stats[4096]="";
strncat(stats,html_stat_start,sizeof(html_stat_start));
for(int i =0; i < deveui_count;i++) {
char temp[256]="";
sprintf(temp,"<div class=\"stat-box\" id=\"f%s\" onclick=\"filterOut('%s');\" style=\"cursor: pointer;\">%s</div>\n",
deveui[i],
deveui[i],
deveui[i]);
strcat(stats,temp);
}
strncat(stats,html_stat_end,sizeof(html_stat_end));
}
static void usage() {
printf("Usage: http-okay <PORT> <OUTFILE>\n");
exit(0);
}
static void mylog() {
printf("%s",logline);
fflush(stdout);
if( 0 != st_log_to_file ) {
if( NULL != file_fd ) {
fwrite(logline,1,strlen(logline),file_fd);
fflush(file_fd);
}
}
}
static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start &&
strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
return 0;
}
return -1;
}
typedef struct {
char method[16];
char path[2048];
char version[16];
char user_agent[256];
char host[256];
char content[4096];
} http_req_t;
void http_req_parse(const char *request, http_req_t *http_request) {
char *request_copy = strdup(request);
char *line = strtok(request_copy, "\r\n");
if (line) {
sscanf(line, "%15s %255s %15s", http_request->method, http_request->path, http_request->version);
}
bzero(&http_request->content, 4096);
bzero(&http_request->host, 256);
bzero(&http_request->user_agent, 256);
int content_length = 0;
while (line != NULL && strlen(line) > 0) {
if (strncmp(line, "User-Agent: ", 12) == 0) {
sscanf(line + 12, "%255[^\r\n]", http_request->user_agent);
} else if (strncmp(line, "Host: ", 6) == 0) {
sscanf(line + 6, "%255[^\r\n]", http_request->host);
} else if (strncmp(line, "Content-Length: ", 16) == 0) {
sscanf(line + 16, "%d", &content_length);
}
//printf("DEBUG: %s\n", line);
line = strtok(NULL, "\r\n");
}
if( content_length ) {
strncpy(http_request->content,request+strlen(request)-content_length,content_length);
}
free(request_copy);
}
static void signal_int_handler() {
printf("\nExiting\n");
close(socket_fd);
if( NULL != file_fd ) {
fclose(file_fd);
}
exit(0);
}
static int mysqlite3_callback(void *NotUsed, int argc, char **argv, char **azColName) {
for (int i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
void mysqlite3_create() {
rc = sqlite3_open(sqlite3_name, &db);
if(rc) {
fprintf(stderr,"Can't open database: %s\n", sqlite3_errmsg(db));
} else {
snprintf(logline, MAXLINE, "%s : Database %s open success\n",get_rfc3339(), sqlite3_name);
mylog();
}
rc = sqlite3_exec(db, sql_table_cnx, mysqlite3_callback, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr,"SQL error: %s\n", errMsg);
sqlite3_free(errMsg);
} else {
snprintf(logline, MAXLINE, "%s : Table CNX create success\n", get_rfc3339());
mylog();
}
rc = sqlite3_exec(db, sql_table_content, mysqlite3_callback, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr,"SQL error: %s\n", errMsg);
sqlite3_free(errMsg);
} else {
snprintf(logline, MAXLINE, "%s : Table CONTENT create success\n", get_rfc3339());
mylog();
}
}
void mysqlite3_begin() {
const char *sqlBeginTransaction = "BEGIN TRANSACTION;";
rc = sqlite3_exec(db, sqlBeginTransaction, mysqlite3_callback, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error (Begin Transaction): %s\n", errMsg);
sqlite3_free(errMsg);
}
}
void mysqlite3_commit() {
const char *sqlCommit = "COMMIT;";
rc = sqlite3_exec(db, sqlCommit, mysqlite3_callback, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error (Commit): %s\n", errMsg);
sqlite3_free(errMsg);
}
}
void mysqlite3_content_insert(http_req_t *http_req) {
mysqlite3_begin();
const char *sql_insert_content_templ = "INSERT INTO content (date, epoch, host, method, path, version, user_agent, content) "
"VALUES ('%s', %d, '%s', '%s', '%s', '%s', '%s', '%s');";
char sql_insert_content_values[4096];
bzero(sql_insert_content_values, 4096);
strcat(sql_insert_content_values,"INSERT INTO content (date, epoch, host, method, path, version, user_agent, content) VALUES (");
char sql_str_templ[16]="'%s',";
char sql_int_templ[16]="%d,";
char sql_str_templ_last[16]="'%s');";
char sql_str_temp[4095];
sprintf(sql_str_temp,sql_str_templ,get_rfc3339());
strcat(sql_insert_content_values,sql_str_temp);
sprintf(sql_str_temp,sql_int_templ,epoch_time);
strcat(sql_insert_content_values,sql_str_temp);
sprintf(sql_str_temp,sql_str_templ,http_req->host);
strcat(sql_insert_content_values,sql_str_temp);
sprintf(sql_str_temp,sql_str_templ,http_req->method);
strcat(sql_insert_content_values,sql_str_temp);
sprintf(sql_str_temp,sql_str_templ,http_req->path);
strcat(sql_insert_content_values,sql_str_temp);
sprintf(sql_str_temp,sql_str_templ,http_req->version);
strcat(sql_insert_content_values,sql_str_temp);
sprintf(sql_str_temp,sql_str_templ,http_req->user_agent);
strcat(sql_insert_content_values,sql_str_temp);
sprintf(sql_str_temp,sql_str_templ_last,http_req->content);
strcat(sql_insert_content_values,sql_str_temp);
rc = sqlite3_exec(db, sql_insert_content_values, mysqlite3_callback, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error (Insert): %s\n", errMsg);
sqlite3_free(errMsg);
}
mysqlite3_commit();
}
void mysqlite3_cnx_insert(char *date,char *ip,unsigned short port) {
mysqlite3_begin();
const char *sql_insert_cnx_templ = "INSERT INTO cnx (ip, port, date) "
"VALUES ('%s', %d, '%s'); ";
char sql_insert_cnx_values[256]="";
snprintf(sql_insert_cnx_values,256,sql_insert_cnx_templ,ip,port,date);
rc = sqlite3_exec(db, sql_insert_cnx_values, mysqlite3_callback, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error (Insert): %s\n", errMsg);
sqlite3_free(errMsg);
}
mysqlite3_commit();
}
void mysqlite3_query(int limit) {
char sql_query[256];
snprintf(sql_query, sizeof(sql_query), sql_query_format, sql_table_name, limit);
snprintf(logline, MAXLINE, "%s : Extracting latest %d records\n", get_rfc3339(), limit);
mylog();
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, sql_query, -1, &stmt, NULL) == SQLITE_OK) {
int count=0;
FILE *fd = fopen(html_output,"wt");
fwrite(html_header,sizeof(html_header)-1,1,fd);
fwrite(html_header_2,sizeof(html_header_2)-1,1,fd);
char generated_date[64]="";
//memset(generated_date, 0x0, 64 );
bzero(generated_date,64);
sprintf(generated_date,"\n<p>Generated at %s</p>\n", get_rfc3339());
fwrite(generated_date,strlen(generated_date),1,fd);
//~ fwrite(html_stat_start,sizeof(html_stat_start),1,fd);
//~ fwrite(html_stat_end,sizeof(html_stat_end),1,fd);
char html_table[4096]="";
memset(html_table, 0x0, 4096);
snprintf(html_table, 4096, "<table>\n<tr>\n<th>Time</th>\n<th>DevEUI</th>\n<th>FPort</th>\n<th>FCntUp</th>\n<th>FCntDn</th>\n<th>Payload</th>\n<th>SF</th>\n<th>RSSI</th>\n<th>SNR</th>\n<th>LC</th>\n<th>LRRID</th>\n<th>Late</th>\n<th>Count</th>\n<th>MAC</th>\n</tr>\n");
fwrite(html_table,strlen(html_table),1,fd);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const unsigned char *rec_content = sqlite3_column_text(stmt, 1);
const unsigned char *rec_date = sqlite3_column_text(stmt, 0);
int r;
jsmn_parser p;
jsmn_init(&p);
jsmntok_t t[256];
r = jsmn_parse(&p, rec_content, strlen(rec_content), t, sizeof(t) / sizeof(t[0]));
if (r < 0) {
snprintf(logline, MAXLINE, "%s : Failed to parse JSON: %d\n", get_rfc3339(), r);
mylog();
}
if (r < 1 || t[0].type != JSMN_OBJECT) {
snprintf(logline, MAXLINE, "%s : Missing object\n", get_rfc3339());
mylog();
} else {
char *p_Time= NULL;
char *p_DevEUI= NULL;
char *p_FPort= NULL;
char *p_FCntUp= NULL;
char *p_FCntDn= NULL;
char *p_payload_hex= NULL;
char *p_SpFact= NULL;
char *p_LrrRSSI= NULL;
float f_LrrRSSI= -199;
char *p_LrrSNR= NULL;
float f_LrrSNR= 99;
char *p_Channel= NULL;
char *p_Lrrid= NULL;
char *p_Late= NULL;
unsigned short i_Late=0;
char *p_DevLrrCnt= NULL;
char *p_rawMacCommands= NULL;
char empty[]="";
int free_p_rawMacCommands=0;
for (int i = 1; i < r; i++) {
if (jsoneq(rec_content, &t[i], "Time") == 0) {
p_Time=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_Time: %s\n", p_Time);
i++;
} else if (jsoneq(rec_content, &t[i], "DevEUI") == 0) {
p_DevEUI=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_DevEUI: %s\n", p_DevEUI);
i++;
} else if (jsoneq(rec_content, &t[i], "FPort") == 0) {
p_FPort=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_FPort: %s\n", p_FPort);
i++;
} else if (jsoneq(rec_content, &t[i], "FCntUp") == 0) {
p_FCntUp=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_FCntUp: %s\n", p_FCntUp);
i++;
} else if (jsoneq(rec_content, &t[i], "FCntDn") == 0) {
p_FCntDn=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_FCntDn: %s\n", p_FCntDn);
i++;
} else if (jsoneq(rec_content, &t[i], "payload_hex") == 0) {
p_payload_hex=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_payload_hex: %s\n", p_payload_hex);
i++;
} else if (jsoneq(rec_content, &t[i], "SpFact") == 0) {
p_SpFact=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_SpFact: %s\n", p_SpFact);
i++;
} else if (jsoneq(rec_content, &t[i], "LrrRSSI") == 0) {
p_LrrRSSI=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
f_LrrRSSI=(float)strtod(p_LrrRSSI,NULL);
//~ printf(" p_LrrRSSI: %s\n", p_LrrRSSI);
i++;
} else if (jsoneq(rec_content, &t[i], "LrrSNR") == 0) {
p_LrrSNR=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_LrrSNR: %s\n", p_LrrSNR);
f_LrrSNR=(float)strtod(p_LrrSNR,NULL);
i++;
} else if (jsoneq(rec_content, &t[i], "Channel") == 0) {
p_Channel=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_Channel: %s\n", p_Channel);
i++;
} else if (jsoneq(rec_content, &t[i], "Lrrid") == 0) {
p_Lrrid=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_Lrrid: %s\n", p_Lrrid);
i++;
} else if (jsoneq(rec_content, &t[i], "Late") == 0) {
p_Late=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_Late: %s\n", p_Late);
i_Late=atoi(p_Late);
//~ printf(" i_Late: %d\n", i_Late);
i++;
} else if (jsoneq(rec_content, &t[i], "DevLrrCnt") == 0) {
p_DevLrrCnt=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
//~ printf(" p_DevLrrCnt: %s\n", p_DevLrrCnt);
i++;
} else if (jsoneq(rec_content, &t[i], "rawMacCommands") == 0) {
//~ printf(" p_rawMacCommands: %s\n", p_rawMacCommands);
if( 0 == t[i + 1].end - t[i + 1].start ) {
p_rawMacCommands=(char *)empty;
} else {
p_rawMacCommands=strndup(rec_content + t[i + 1].start,t[i + 1].end - t[i + 1].start);
free_p_rawMacCommands=1;
}
i++;
}
}
char uplink_type[32]="arrow-up";
if(i_Late) {
strcpy(uplink_type,"arrow-up-gray");
}
if(!p_rawMacCommands) {
p_rawMacCommands=empty;
}
unsigned short found=0;
for(int j = 0; j<deveui_count;j++) {
if(0 == strcmp(deveui[j],p_DevEUI)) {
found=1;
break;
}
}
if( 0 == found ) {
printf("Adding %s\n", p_DevEUI);
strcpy(deveui[deveui_count],p_DevEUI);
deveui_count++;
}
char table_line[4096]="";
memset(table_line, 0x0, 4096 );
sprintf(table_line, "<tr class=\"%s\"><td><div class=\"%s\"><span class=\"tooltippacket\">%s</span></div>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td class=\"sf%s\">%s</td><td class=\"%s\">%s</td><td class=\"%s\">%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",
p_DevEUI,
uplink_type,
rec_content,
p_Time,
p_DevEUI,
p_FPort,
p_FCntUp,
p_FCntDn,
p_payload_hex,
p_SpFact,
p_SpFact,
colorRssi(f_LrrRSSI),
p_LrrRSSI,
colorSnr(f_LrrSNR),
p_LrrSNR,
p_Channel,
p_Lrrid,
p_Late,
p_DevLrrCnt,
p_rawMacCommands);
fwrite(table_line,strlen(table_line),1,fd);
if(p_Time) free(p_Time);
if(p_DevEUI) free(p_DevEUI);
if(p_FPort) free(p_FPort);
if(p_FCntUp) free(p_FCntUp);
if(p_FCntDn) free(p_FCntDn);
if(p_payload_hex) free(p_payload_hex);
if(p_SpFact) free(p_SpFact);
if(p_LrrRSSI) free(p_LrrRSSI);
if(p_LrrSNR) free(p_LrrSNR);
if(p_Channel) free(p_Channel);
if(p_Lrrid) free(p_Lrrid);
if(p_Late) free(p_Late);
if(p_DevLrrCnt) free(p_DevLrrCnt);
if(p_rawMacCommands && free_p_rawMacCommands ) free(p_rawMacCommands);
}
//snprintf(logline, MAXLINE, "%s : Record%d: %s\n", get_rfc3339(), count, rec_date);
//mylog();
count++;
}
fwrite("</table>\n",strlen("</table>\n"),1,fd);
char all_stats[4096];
bzero(all_stats,4096);
stats_box(all_stats);
fwrite(all_stats,strlen(all_stats),1,fd);
fclose(fd);
sqlite3_finalize(stmt);
} else {
fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
}
}
void response_to_client(int connection_fd) {
char buf[4096] = {0};
while (1) {
const int read_size = read(connection_fd,&buf, sizeof(buf));
if (read_size == -1) {
if (errno == EINTR) {
continue;
}
printf("Unable to read socket : %s\n", strerror(errno));
exit(1);
}
if (read_size == 0) {
return;
}
break;
}
snprintf(logline, MAXLINE, "%s : %s\n", get_rfc3339(), buf);
mylog();
snprintf(logline, MAXLINE, "%s : ------------\n",get_rfc3339());
mylog();
http_req_t http_request;
http_req_parse(buf,&http_request);
/*
printf(" Method: %s\n", http_request.method);
printf(" Host: %s\n", http_request.host);
printf(" Path: %s\n", http_request.path);
printf(" Version: %s\n", http_request.version);
printf(" User-Agent: %s\n", http_request.user_agent);
printf(" Content: %s\n", http_request.content);
*/
mysqlite3_content_insert(&http_request);
const char msg[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: 2\r\n\r\n"
"OK\r\n";
int offset = 0;
while (offset < strlen(msg)) {
while (1) {
int write_response = write(connection_fd, msg+offset, strlen(msg+offset));
if (write_response == -1) {
if (errno == EINTR) {
continue;
}
printf("Unable to write socket : %s\n", strerror(errno));
exit(1);
}
offset += write_response;
break;
}
}
}
void main(int argc,char **argv) {
signal(SIGINT, signal_int_handler);
if(argc > 1) {
if( 0 == strcmp(argv[1], "help")) {
usage();
} else if( 0 == strcmp(argv[1], "--help")) {
usage();
}
if( argc > 2 ) {
st_log_to_file=1;
file_fd=fopen(argv[2],"at+");
}
}
for(int i = 0; i < MAXDEVEUI; i++ ){
strcpy(deveui[i],"-1");
}
//SQLITE
mysqlite3_create();
mysqlite3_query(LATEST);
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
fprintf(stderr,"Unable to create socket file descriptor: %s\n", strerror(errno));
exit(1);
}
struct sockaddr_in server_address, client_address;
bzero(&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
if ( argc > 1 ) {
PORT = atoi(argv[1]);
}
server_address.sin_port = htons(PORT);
snprintf(logline, MAXLINE, "%s : Listening on %d\n", get_rfc3339(), PORT);
mylog();
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
const int reuse = 1;
const int reuse_addr_response = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
if (reuse_addr_response == -1) {
fprintf(stderr, "Unable to set SO_REUSEADDR to socket\n");
exit(1);
}
const int bind_response = bind(socket_fd, (struct sockaddr *)&server_address, sizeof(server_address));
if (bind_response == -1) {
fprintf(stderr, "Unable to bind the socket to file descriptor : %s\n", strerror(errno));
exit(1);
}
const int listen_response = listen(socket_fd, 5);
if (listen_response != 0) {
fprintf(stderr, "Unable to listen to port %d: %s", PORT, strerror(errno));
exit(1);
}
while (1) {
unsigned int client_socket_len = sizeof(client_address);
const int connection_fd = accept(socket_fd, (struct sockaddr*)&client_address, &client_socket_len);
if (connection_fd == -1) {
fprintf(stderr, "Unable to accept incoming connection : %s\n", strerror(errno));
}
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_address.sin_addr, client_ip, INET_ADDRSTRLEN);
snprintf(logline, MAXLINE, "%s : Connection from %s:%d\n", get_rfc3339(), client_ip, ntohs(client_address.sin_port));
mylog();
mysqlite3_cnx_insert(get_rfc3339(),client_ip,ntohs(client_address.sin_port));
response_to_client(connection_fd);
close(connection_fd);
mysqlite3_query(LATEST);
}
}