137 lines
4.6 KiB
C
137 lines
4.6 KiB
C
/**
|
|
* Implementation of local interface via libmicrohttpd
|
|
*
|
|
* @package vzlogger
|
|
* @copyright Copyright (c) 2011, The volkszaehler.org project
|
|
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
|
* @author Steffen Vogel <info@steffenvogel.de>
|
|
*/
|
|
/*
|
|
* This file is part of volkzaehler.org
|
|
*
|
|
* volkzaehler.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* volkzaehler.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <json/json.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
|
|
#include "vzlogger.h"
|
|
#include "channel.h"
|
|
#include "local.h"
|
|
#include "api.h"
|
|
|
|
extern config_options_t options;
|
|
|
|
int handle_request(void *cls, struct MHD_Connection *connection, const char *url, const char *method,
|
|
const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) {
|
|
|
|
int status;
|
|
int response_code = MHD_HTTP_NOT_FOUND;
|
|
|
|
list_t *mappings = (list_t *) cls;
|
|
|
|
struct MHD_Response *response;
|
|
const char *mode = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "mode");
|
|
|
|
print(log_info+1, "Local request received: method=%s url=%s mode=%s", "http", method, url, mode);
|
|
|
|
if (strcmp(method, "GET") == 0) {
|
|
struct timespec ts;
|
|
struct timeval tp;
|
|
|
|
struct json_object *json_obj = json_object_new_object();
|
|
struct json_object *json_data = json_object_new_array();
|
|
struct json_object *json_exception = NULL;
|
|
|
|
const char *uuid = url + 1; /* strip leading slash */
|
|
const char *json_str;
|
|
int show_all = 0;
|
|
|
|
if (strcmp(url, "/") == 0) {
|
|
if (options.channel_index) {
|
|
show_all = TRUE;
|
|
}
|
|
else {
|
|
json_exception = json_object_new_object();
|
|
|
|
json_object_object_add(json_exception, "message", json_object_new_string("channel index is disabled"));
|
|
json_object_object_add(json_exception, "code", json_object_new_int(0));
|
|
}
|
|
}
|
|
|
|
foreach(*mappings, mapping, map_t) {
|
|
foreach(mapping->channels, ch, channel_t) {
|
|
if (strcmp(ch->uuid, uuid) == 0 || show_all) {
|
|
response_code = MHD_HTTP_OK;
|
|
|
|
/* blocking until new data arrives (comet-like blocking of HTTP response) */
|
|
if (mode && strcmp(mode, "comet") == 0) {
|
|
/* convert from timeval to timespec */
|
|
gettimeofday(&tp, NULL);
|
|
ts.tv_sec = tp.tv_sec + options.comet_timeout;
|
|
ts.tv_nsec = tp.tv_usec * 1000;
|
|
|
|
pthread_mutex_lock(&ch->buffer.mutex);
|
|
pthread_cond_timedwait(&ch->condition, &ch->buffer.mutex, &ts);
|
|
pthread_mutex_unlock(&ch->buffer.mutex);
|
|
}
|
|
|
|
struct json_object *json_ch = json_object_new_object();
|
|
|
|
json_object_object_add(json_ch, "uuid", json_object_new_string(ch->uuid));
|
|
json_object_object_add(json_ch, "middleware", json_object_new_string(ch->middleware));
|
|
json_object_object_add(json_ch, "last", json_object_new_double(ch->last.value));
|
|
json_object_object_add(json_ch, "interval", json_object_new_int(mapping->meter.interval));
|
|
json_object_object_add(json_ch, "protocol", json_object_new_string(meter_get_details(mapping->meter.protocol)->name));
|
|
|
|
struct json_object *json_tuples = api_json_tuples(&ch->buffer, ch->buffer.head, ch->buffer.tail);
|
|
json_object_object_add(json_ch, "tuples", json_tuples);
|
|
|
|
json_object_array_add(json_data, json_ch);
|
|
}
|
|
}
|
|
}
|
|
|
|
json_object_object_add(json_obj, "version", json_object_new_string(VERSION));
|
|
json_object_object_add(json_obj, "generator", json_object_new_string(PACKAGE));
|
|
json_object_object_add(json_obj, "data", json_data);
|
|
|
|
if (json_exception) {
|
|
json_object_object_add(json_obj, "exception", json_exception);
|
|
}
|
|
|
|
json_str = json_object_to_json_string(json_obj);
|
|
response = MHD_create_response_from_data(strlen(json_str), (void *) json_str, FALSE, TRUE);
|
|
json_object_put(json_obj);
|
|
|
|
MHD_add_response_header(response, "Content-type", "application/json");
|
|
}
|
|
else {
|
|
char *response_str = strdup("not implemented\n");
|
|
|
|
response = MHD_create_response_from_data(strlen(response_str), (void *) response_str, TRUE, FALSE);
|
|
response_code = MHD_HTTP_METHOD_NOT_ALLOWED;
|
|
|
|
MHD_add_response_header(response, "Content-type", "text/text");
|
|
}
|
|
|
|
status = MHD_queue_response(connection, response_code, response);
|
|
|
|
MHD_destroy_response(response);
|
|
|
|
return status;
|
|
}
|