found bug (shitty overflow ;))
This commit is contained in:
parent
22568636be
commit
ce50c2ed4d
5 changed files with 92 additions and 63 deletions
|
@ -45,17 +45,17 @@ int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_
|
|||
case CURLINFO_TEXT:
|
||||
case CURLINFO_END:
|
||||
if (end) *end = '\0'; /* terminate without \n */
|
||||
print(3, "%.*s", (channel_t *) ch, (int) size, data);
|
||||
print(3, "CURL: %.*s", (channel_t *) ch, (int) size, data);
|
||||
break;
|
||||
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
case CURLINFO_DATA_IN:
|
||||
print(6, "Received %lu bytes", (channel_t *) ch, (unsigned long) size);
|
||||
print(6, "CURL: Received %lu bytes", (channel_t *) ch, (unsigned long) size);
|
||||
break;
|
||||
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
case CURLINFO_DATA_OUT:
|
||||
print(6, "Sent %lu bytes.. ", (channel_t *) ch, (unsigned long) size);
|
||||
print(6, "CURL: Sent %lu bytes.. ", (channel_t *) ch, (unsigned long) size);
|
||||
break;
|
||||
|
||||
case CURLINFO_HEADER_IN:
|
||||
|
@ -78,10 +78,8 @@ size_t curl_custom_write_callback(void *ptr, size_t size, size_t nmemb, void *da
|
|||
|
||||
memcpy(&(response->data[response->size]), ptr, realsize);
|
||||
response->size += realsize;
|
||||
response->data[response->size] = 0;
|
||||
//response->data[response->size] = 0;
|
||||
|
||||
print(1, "Addr: %lu", NULL, &(response->data));
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
@ -109,8 +107,15 @@ json_object * api_build_json(channel_t *ch) {
|
|||
|
||||
CURL * api_curl_init(channel_t *ch) {
|
||||
CURL *curl;
|
||||
struct curl_slist *header = NULL;
|
||||
char url[255], agent[255];
|
||||
|
||||
char buffer[255];
|
||||
sprintf(agent, "User-Agent: vzlogger/%s (%s)", VZ_VERSION, curl_version()); /* build user agent */
|
||||
sprintf(url, "%s/data/%s.json", ch->middleware, ch->uuid); /* build url */
|
||||
|
||||
header = curl_slist_append(header, "Content-type: application/json");
|
||||
header = curl_slist_append(header, "Accept: application/json");
|
||||
header = curl_slist_append(header, agent);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (!curl) {
|
||||
|
@ -118,12 +123,8 @@ CURL * api_curl_init(channel_t *ch) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sprintf(buffer, "%s/data/%s.json", ch->middleware, ch->uuid); /* build url */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, buffer);
|
||||
|
||||
sprintf(buffer, "vzlogger/%s (%s)", VZ_VERSION, curl_version()); /* build user agent */
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, buffer);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, (int) opts.verbose);
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_custom_debug_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *) ch);
|
||||
|
@ -131,10 +132,9 @@ CURL * api_curl_init(channel_t *ch) {
|
|||
return curl;
|
||||
}
|
||||
|
||||
char * api_parse_exception(CURLresponse response) {
|
||||
void api_parse_exception(CURLresponse response, char *err) {
|
||||
struct json_tokener * json_tok;
|
||||
struct json_object * json_obj;
|
||||
char *errstr;
|
||||
|
||||
json_tok = json_tokener_new();
|
||||
json_obj = json_tokener_parse_ex(json_tok, response.data, response.size);
|
||||
|
@ -142,19 +142,20 @@ char * api_parse_exception(CURLresponse response) {
|
|||
json_obj = json_object_object_get(json_obj, "exception");
|
||||
|
||||
if (json_obj) {
|
||||
errstr = json_object_get_string(json_object_object_get(json_obj, "message"));
|
||||
sprintf(err, "[%s] %s",
|
||||
json_object_get_string(json_object_object_get(json_obj, "type")),
|
||||
json_object_get_string(json_object_object_get(json_obj, "message"))
|
||||
);
|
||||
}
|
||||
else {
|
||||
errstr = "missing exception";
|
||||
strcpy(err, "missing exception");
|
||||
}
|
||||
}
|
||||
else {
|
||||
errstr = json_tokener_errors[json_tok->err];
|
||||
strcpy(err, json_tokener_errors[json_tok->err]);
|
||||
}
|
||||
|
||||
json_tokener_free(json_tok);
|
||||
|
||||
return errstr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -173,36 +174,33 @@ void *api_thread(void *arg) {
|
|||
|
||||
do { /* start thread mainloop */
|
||||
CURLresponse response;
|
||||
int curl_code, http_code;
|
||||
int curl_code;
|
||||
long int http_code;
|
||||
char *json_str;
|
||||
|
||||
/* initialize response */
|
||||
response.data = NULL;
|
||||
response.size = 0;
|
||||
|
||||
//pthread_mutex_lock(&ch->mutex);
|
||||
//while (queue_is_empty(&ch->queue)) { /* detect spurious wakeups */
|
||||
// pthread_cond_wait(&ch->condition, &ch->mutex); /* sleep until new data has been read */
|
||||
//}
|
||||
//pthread_mutex_unlock(&ch->mutex);
|
||||
pthread_mutex_lock(&ch->mutex);
|
||||
while (queue_is_empty(&ch->queue)) { /* detect spurious wakeups */
|
||||
pthread_cond_wait(&ch->condition, &ch->mutex); /* sleep until new data has been read */
|
||||
}
|
||||
pthread_mutex_unlock(&ch->mutex);
|
||||
|
||||
//if (opts.verbose > 5) queue_print(&ch->queue); /* Debugging */
|
||||
pthread_mutex_lock(&ch->mutex);
|
||||
json_str = json_object_to_json_string(api_build_json(ch));
|
||||
pthread_mutex_unlock(&ch->mutex);
|
||||
|
||||
//pthread_mutex_lock(&ch->mutex);
|
||||
//json_str = json_object_to_json_string(api_build_json(ch));
|
||||
//pthread_mutex_unlock(&ch->mutex);
|
||||
print(1, "JSON request body: %s", ch, json_str);
|
||||
|
||||
//print(1, "JSON body: %s", ch, json_str);
|
||||
|
||||
//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_custom_write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &response);
|
||||
|
||||
curl_code = curl_easy_perform(curl);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
print(1, "Addr: %lu", ch, &(response.data));
|
||||
print(1, "Response: %s", ch, response.data);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
if (curl_code == CURLE_OK && http_code == 200) { /* everything is ok */
|
||||
print(1, "Request succeeded with code: %i", ch, http_code);
|
||||
|
@ -211,10 +209,12 @@ void *api_thread(void *arg) {
|
|||
}
|
||||
else { /* error */
|
||||
if (curl_code != CURLE_OK) {
|
||||
print(-1, "CURL failed: %s", ch, curl_easy_strerror(curl_code));
|
||||
print(-1, "CURL: %s", ch, curl_easy_strerror(curl_code));
|
||||
}
|
||||
else if (http_code != 200) {
|
||||
print(-1, "Invalid middlware response: %s", ch, api_parse_exception(response));
|
||||
char err[255];
|
||||
api_parse_exception(response, &err);
|
||||
print(-1, "Invalid middlware response: %s", ch, err);
|
||||
}
|
||||
|
||||
print(2, "Sleeping %i seconds due to previous failure", ch, RETRY_PAUSE);
|
||||
|
@ -225,7 +225,7 @@ void *api_thread(void *arg) {
|
|||
free(json_str);
|
||||
// TODO free json objects
|
||||
|
||||
//if (response.data) free(response.data);
|
||||
if (response.data) free(response.data);
|
||||
|
||||
pthread_testcancel(); /* test for cancelation request */
|
||||
} while (opts.daemon);
|
||||
|
|
|
@ -43,6 +43,6 @@ int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_
|
|||
size_t curl_custom_write_callback(void *ptr, size_t size, size_t nmemb, void *data);
|
||||
|
||||
json_object * api_build_json(channel_t *ch);
|
||||
void *api_thread(void *arg);
|
||||
void * api_thread(void *arg);
|
||||
|
||||
#endif /* _API_H_ */
|
||||
|
|
|
@ -212,13 +212,21 @@ int parse_channels(char * filename, channel_t * chans) {
|
|||
}
|
||||
|
||||
char line[256];
|
||||
int j = 0;
|
||||
int chan_num = 0, line_num = 1;
|
||||
|
||||
while (j < MAX_CHANNELS && fgets(line, sizeof line, file) != NULL) { /* read a line */
|
||||
while (chan_num < MAX_CHANNELS && fgets(line, sizeof line, file) != NULL) { /* read a line */
|
||||
if (line[0] == ';' || line[0] == '\n') continue; /* skip comments */
|
||||
|
||||
channel_t ch;
|
||||
protocol_t *prot;
|
||||
channel_t ch = {
|
||||
chan_num,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
protocols
|
||||
};
|
||||
|
||||
char *tok = strtok(line, " \t");
|
||||
|
||||
for (int i = 0; i < 7 && tok != NULL; i++) {
|
||||
|
@ -226,21 +234,39 @@ int parse_channels(char * filename, channel_t * chans) {
|
|||
|
||||
switch(i) {
|
||||
case 0: /* protocol */
|
||||
prot = protocols; /* reset pointer */
|
||||
while (prot->name && strcmp(prot->name, tok) != 0) prot++; /* linear search */
|
||||
ch.prot = prot;
|
||||
while (ch.prot->name && strcmp(ch.prot->name, tok) != 0) ch.prot++; /* linear search */
|
||||
|
||||
if (ch.prot == NULL) {
|
||||
print(-1, "Invalid protocol: %s in %s:%i", NULL, tok, filename, line_num);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* interval */
|
||||
ch.interval = atoi(tok);
|
||||
ch.interval = strtol(tok, (char **) NULL, 10);
|
||||
|
||||
if (errno == EINVAL || errno == ERANGE) {
|
||||
print(-1, "Invalid interval: %s in %s:%i", NULL, tok, filename, line_num);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* uuid */
|
||||
if (len == 0) { // TODO add uuid validation
|
||||
print(-1, "Missing uuid in %s:%i", NULL, filename, line_num);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ch.uuid = (char *) malloc(len+1); /* including string termination */
|
||||
strcpy(ch.uuid, tok);
|
||||
break;
|
||||
|
||||
case 3: /* middleware */
|
||||
if (len == 0) { // TODO add uuid validation
|
||||
print(-1, "Missing middleware in %s:%i", NULL, filename, line_num);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ch.middleware = (char *) malloc(len+1); /* including string termination */
|
||||
strcpy(ch.middleware, tok);
|
||||
break;
|
||||
|
@ -248,22 +274,23 @@ int parse_channels(char * filename, channel_t * chans) {
|
|||
case 4: /* options */
|
||||
ch.options = (char *) malloc(len);
|
||||
strncpy(ch.options, tok, len-1);
|
||||
ch.options[len] = '\0'; /* replace \n by \0 */
|
||||
ch.options[len-1] = '\0'; /* replace \n by \0 */
|
||||
break;
|
||||
}
|
||||
|
||||
tok = strtok(NULL, " \t");
|
||||
}
|
||||
|
||||
ch.id = j;
|
||||
|
||||
print(1, "Parsed %s (on %s)", &ch, ch.uuid, ch.middleware);
|
||||
chans[j++] = ch;
|
||||
print(1, "Parsed ch#%i (protocol=%s interval=%i uuid=%s middleware=%s options=%s)", &ch, ch.id, ch.prot->name, ch.interval, ch.uuid, ch.middleware, ch.options);
|
||||
chans[chan_num] = ch;
|
||||
|
||||
chan_num++;
|
||||
line_num++;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return j;
|
||||
return chan_num;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -288,7 +315,7 @@ void *read_thread(void *arg) {
|
|||
pthread_mutex_unlock(&ch->mutex);
|
||||
|
||||
print(1, "Value read: %.3f (next reading in %i secs)", ch, rd.value, ch->interval);
|
||||
if (opts.verbose > 5) queue_print(&ch->queue); /* Debugging */
|
||||
//if (opts.verbose > 5) queue_print(&ch->queue); /* Debugging */
|
||||
|
||||
pthread_testcancel(); /* test for cancelation request */
|
||||
sleep(ch->interval); /* else sleep and restart aquisition */
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "protocol.h"
|
||||
#include "queue.h"
|
||||
|
@ -50,16 +51,17 @@
|
|||
* Datatype for every channel
|
||||
*/
|
||||
typedef struct {
|
||||
char * middleware;
|
||||
char * uuid;
|
||||
unsigned int interval;
|
||||
char * options;
|
||||
|
||||
int id; /* only for internal usage & debugging */
|
||||
|
||||
char *middleware;
|
||||
char *uuid;
|
||||
char *options;
|
||||
|
||||
queue_t queue; /* circular queue to buffer readings */
|
||||
unsigned int interval;
|
||||
|
||||
void *handle; /* handle to store connection status */
|
||||
protocol_t *prot; /* pointer to protocol */
|
||||
void * handle; /* handle to store connection status */
|
||||
queue_t queue; /* circular queue to buffer readings */
|
||||
|
||||
pthread_t reading_thread; /* pthread for asynchronus reading */
|
||||
pthread_t logging_thread; /* pthread for asynchronus logging */
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
;prot intval uuid middleware options
|
||||
;1wire 3 52960fe0-8882-11e0-b356-85eba28c1922 http://localhost/workspace/volkszaehler.org/htdocs/middleware /mnt/1wire/10.12E6D3000800/temperature
|
||||
;obis 10 ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 http://volkszaehler.org/demo/middleware.php /dev/ttyS0
|
||||
obis 10 ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 http://volkszaehler.org/demo/middleware.php /dev/ttyS1
|
||||
obis 10 ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 http://volksxzaehler.org/demo/middleware.php /dev/ttyS1
|
||||
|
|
Loading…
Add table
Reference in a new issue