123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- /*
- * This file is part of the jsonrtc.
- * written in 2018 by Helmut Pozimski.
- *
- * This program 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, version 2.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <kore/kore.h>
- #include <kore/http.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #include <linux/rtc.h>
- #include <cjson/cJSON.h>
- #define IOCTL_DS13307_ALRM _IOR('p', 0x15, unsigned char)
- int page(struct http_request *);
- int handle_time(struct http_request *);
- int handle_wkalrm(struct http_request *);
- int detect_device(struct http_request *);
- int handle_nvmem(struct http_request *);
- int
- page(struct http_request *req)
- {
- http_response(req, 200, NULL, 0);
- return (KORE_RESULT_OK);
- }
- static char * read_body(struct http_request *req) {
- int ret;
- struct kore_buf * buf;
- u_int8_t data[128];
- char * body;
- buf = kore_buf_alloc(128);
- while(1) {
- ret = http_body_read(req, data, sizeof(data));
- if (ret == -1) {
- kore_buf_free(buf);
- return NULL;
- } else if (ret == 0) {
- break;
- }
- kore_buf_append(buf,data,ret);
- }
- body = kore_buf_stringify(buf, NULL);
- kore_buf_free(buf);
- return body;
- }
- int handle_time(struct http_request *req) {
- int fdesc;
- struct rtc_time time;
- int ret;
- char *result_string;
- cJSON *time_json, *json_min, *json_hour, *json_mday,
- *json_mon, *json_year, *json_sec, *json_wday;
- http_response_header(req, "Access-Control-Allow-Origin", "*");
- if(req->method == HTTP_METHOD_GET) {
- time_json = cJSON_CreateObject();
- fdesc = open("/dev/rtc", O_RDONLY);
- ret = ioctl(fdesc, RTC_RD_TIME, &time);
- close(fdesc);
- if (!ret) {
- json_sec = cJSON_CreateNumber(time.tm_sec);
- json_min = cJSON_CreateNumber(time.tm_min);
- json_hour = cJSON_CreateNumber(time.tm_hour);
- json_mday = cJSON_CreateNumber(time.tm_mday);
- json_mon = cJSON_CreateNumber(time.tm_mon);
- json_year = cJSON_CreateNumber(time.tm_year);
- json_wday = cJSON_CreateNumber(time.tm_wday);
- cJSON_AddItemToObject(time_json, "seconds", json_sec);
- cJSON_AddItemToObject(time_json, "minutes", json_min);
- cJSON_AddItemToObject(time_json, "hour", json_hour);
- cJSON_AddItemToObject(time_json, "mday", json_mday);
- cJSON_AddItemToObject(time_json, "month", json_mon);
- cJSON_AddItemToObject(time_json, "year", json_year);
- cJSON_AddItemToObject(time_json, "wday", json_wday);
- result_string = cJSON_Print(time_json);
- cJSON_Delete(time_json);
- http_response_header(req, "Content-Type", "application/json");
- http_response(req, 200, result_string, strlen(result_string));
- return KORE_RESULT_OK;
- }
- cJSON_Delete(time_json);
- result_string = "Error: could not get time from /dev/rtc\n";
- http_response(req, 500, result_string, strlen(result_string));
- return KORE_RESULT_OK;
- } else if (req->method == HTTP_METHOD_POST) {
- char * body;
- body = read_body(req);
- if (body == NULL) {
- result_string = "Error: could not read request body\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- time_json = cJSON_Parse(body);
- if (time_json == NULL) {
- result_string = "Error: could not parse json\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- json_sec = cJSON_GetObjectItemCaseSensitive(time_json, "seconds");
- json_min = cJSON_GetObjectItemCaseSensitive(time_json, "minutes");
- json_hour = cJSON_GetObjectItemCaseSensitive(time_json, "hour");
- json_mday = cJSON_GetObjectItemCaseSensitive(time_json, "mday");
- json_mon = cJSON_GetObjectItemCaseSensitive(time_json, "month");
- json_year = cJSON_GetObjectItemCaseSensitive(time_json, "year");
- json_wday = cJSON_GetObjectItemCaseSensitive(time_json, "wday");
- if (cJSON_IsNumber(json_sec) && cJSON_IsNumber(json_min) && cJSON_IsNumber(json_hour) &&
- cJSON_IsNumber(json_mday) && cJSON_IsNumber(json_mon) &&
- cJSON_IsNumber(json_year) && cJSON_IsNumber(json_wday)) {
- time.tm_sec = json_sec->valueint;
- time.tm_min = json_min->valueint;
- time.tm_hour = json_hour->valueint;
- time.tm_mday = json_mday->valueint;
- time.tm_mon = json_mon->valueint;
- time.tm_year = json_year->valueint;
- time.tm_wday = json_wday->valueint;
- } else {
- cJSON_Delete(time_json);
- result_string = "Error: invalid or missing values in json object\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- cJSON_Delete(time_json);
- fdesc = open("/dev/rtc", O_WRONLY);
- ret = ioctl(fdesc, RTC_SET_TIME, &time);
- close(fdesc);
- if (ret) {
- result_string = "Error: Could not set time via /dev/rtc\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- http_response(req, 200, NULL, 0);
- return KORE_RESULT_OK;
- } else {
- http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
- return (KORE_RESULT_OK);
- }
- }
- int handle_wkalrm(struct http_request *req) {
- char *result_string;
- struct rtc_wkalrm alarm;
- int fdesc, ret;
- unsigned char alarm_bit;
- cJSON *alarm_json, *json_min, *json_hour, *json_mday,
- *json_mon, *json_year, *json_sec, *json_wday,
- *json_enabled, *json_pending;
- http_response_header(req, "Access-Control-Allow-Origin", "*");
- if(req->method == HTTP_METHOD_GET) {
- alarm_json = cJSON_CreateObject();
- fdesc = open("/dev/rtc", O_RDONLY);
- ret = ioctl(fdesc, RTC_WKALM_RD, &alarm);
- ret |= ioctl(fdesc, IOCTL_DS13307_ALRM, &alarm_bit);
- close(fdesc);
- if (!ret) {
- json_sec = cJSON_CreateNumber(alarm.time.tm_sec);
- json_min = cJSON_CreateNumber(alarm.time.tm_min);
- json_hour = cJSON_CreateNumber(alarm.time.tm_hour);
- json_mday = cJSON_CreateNumber(alarm.time.tm_mday);
- json_mon = cJSON_CreateNumber(alarm.time.tm_mon);
- json_year = cJSON_CreateNumber(alarm.time.tm_year);
- json_wday = cJSON_CreateNumber(alarm.time.tm_wday);
- json_enabled = cJSON_CreateNumber(alarm.enabled);
- json_pending = cJSON_CreateNumber(alarm_bit);
- cJSON_AddItemToObject(alarm_json, "seconds", json_sec);
- cJSON_AddItemToObject(alarm_json, "minutes", json_min);
- cJSON_AddItemToObject(alarm_json, "hour", json_hour);
- cJSON_AddItemToObject(alarm_json, "mday", json_mday);
- cJSON_AddItemToObject(alarm_json, "month", json_mon);
- cJSON_AddItemToObject(alarm_json, "year", json_year);
- cJSON_AddItemToObject(alarm_json, "wday", json_wday);
- cJSON_AddItemToObject(alarm_json, "enabled", json_enabled);
- cJSON_AddItemToObject(alarm_json, "pending", json_pending);
- result_string = cJSON_Print(alarm_json);
- cJSON_Delete(alarm_json);
- http_response_header(req, "Content-Type", "application/json");
- http_response(req, 200, result_string, strlen(result_string));
- return KORE_RESULT_OK;
- }
- cJSON_Delete(alarm_json);
- result_string = "Error: could not get alarm from /dev/rtc\n";
- http_response(req, 500, result_string, strlen(result_string));
- return KORE_RESULT_OK;
- } else if (req->method == HTTP_METHOD_POST) {
- char * body = read_body(req);
- if (body == NULL) {
- result_string = "Error: could not read request body\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- alarm_json = cJSON_Parse(body);
- if (alarm_json == NULL) {
- result_string = "Error: could not parse json\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- json_sec = cJSON_GetObjectItemCaseSensitive(alarm_json, "seconds");
- json_min = cJSON_GetObjectItemCaseSensitive(alarm_json, "minutes");
- json_hour = cJSON_GetObjectItemCaseSensitive(alarm_json, "hour");
- json_mday = cJSON_GetObjectItemCaseSensitive(alarm_json, "mday");
- json_mon = cJSON_GetObjectItemCaseSensitive(alarm_json, "month");
- json_year = cJSON_GetObjectItemCaseSensitive(alarm_json, "year");
- json_wday = cJSON_GetObjectItemCaseSensitive(alarm_json, "wday");
- json_enabled = cJSON_GetObjectItemCaseSensitive(alarm_json, "enabled");
- if (cJSON_IsNumber(json_sec) && cJSON_IsNumber(json_min) && cJSON_IsNumber(json_hour) &&
- cJSON_IsNumber(json_mday) && cJSON_IsNumber(json_mon) &&
- cJSON_IsNumber(json_year) && cJSON_IsNumber(json_wday) &&
- cJSON_IsNumber(json_enabled)) {
- alarm.time.tm_sec = json_sec->valueint;
- alarm.time.tm_min = json_min->valueint;
- alarm.time.tm_hour = json_hour->valueint;
- alarm.time.tm_mday = json_mday->valueint;
- alarm.time.tm_mon = json_mon->valueint;
- alarm.time.tm_year = json_year->valueint;
- alarm.time.tm_wday = json_wday->valueint;
- alarm.enabled = json_enabled->valueint;
- } else {
- cJSON_Delete(alarm_json);
- result_string = "Error: invalid or missing values in json object\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- cJSON_Delete(alarm_json);
- fdesc = open("/dev/rtc", O_WRONLY);
- ret = ioctl(fdesc, RTC_WKALM_SET, &alarm);
- close(fdesc);
- if (ret) {
- result_string = "Error: Could not set alarm via /dev/rtc\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- http_response(req, 200, NULL, 0);
- return KORE_RESULT_OK;
- } else {
- http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
- return (KORE_RESULT_OK);
- }
- }
- int detect_device(struct http_request *req) {
- if(req->method == HTTP_METHOD_GET) {
- http_response_header(req, "Access-Control-Allow-Origin", "*");
- if (access("/sys/bus/nvmem/devices/ds1307_nvram0/nvmem", F_OK) != -1) {
- http_response(req, 200, "DS1307", 6);
- } else {
- http_response(req, 200, "DS1337", 6);
- }
- return KORE_RESULT_OK;
- } else {
- http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
- return (KORE_RESULT_OK);
- }
- }
- int handle_nvmem(struct http_request *req) {
- int fdesc, bytes_read;
- unsigned char buf[56];
- char r_string[113];
- char buf2[3];
- char * result_object;
- char * result_string;
- cJSON *json_response, *json_string;
- http_response_header(req, "Access-Control-Allow-Origin", "*");
- if(req->method == HTTP_METHOD_GET) {
- fdesc = open("/sys/bus/nvmem/devices/ds1307_nvram0/nvmem", O_RDONLY);
- bytes_read = read(fdesc, &buf, 56);
- close(fdesc);
- if(bytes_read == 56) {
- r_string[112] = '\0';
- for(int i=0; i<56; i++) {
- if (buf[i] <= 15) {
- sprintf(buf2, "0%x", buf[i]);
- } else {
- sprintf(buf2, "%x", buf[i]);
- }
- strcpy(r_string + i*2, buf2);
- }
- json_response = cJSON_CreateObject();
- json_string = cJSON_CreateString(r_string);
- cJSON_AddItemToObject(json_response, "content", json_string);
- result_object = cJSON_Print(json_response);
- cJSON_Delete(json_response);
- http_response_header(req, "Content-Type", "application/json");
- http_response(req, 200, result_object, strlen(result_object));
- } else {
- result_string = "Error: could not read from nvmem\n";
- http_response(req, 500, result_string, strlen(result_string));
- }
- return KORE_RESULT_OK;
- } else if (req->method == HTTP_METHOD_POST) {
- unsigned char to_write[56];
- int buf3 = 0;
- int bytes_written;
- cJSON *body_json, *input_json;
- char * input_string;
- char * body = read_body(req);
- if (body == NULL) {
- result_string = "Error: could not read request body\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- body_json = cJSON_Parse(body);
- input_json = cJSON_GetObjectItemCaseSensitive(body_json, "content");
- if (cJSON_IsString(input_json)) {
- input_string = input_json->valuestring;
- } else {
- result_string = "Error: invalid value in json content\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- }
- for (int i=0; i<112; i++) {
- if(i%2 == 0) {
- buf3 = 0;
- } else {
- buf3 = buf3 <<4;
- }
- if((input_string[i] >= '0') && (input_string[i] <= '9')) {
- buf3 += input_string[i] - '0';
- } else if ((input_string[i] >= 'A') && (input_string[i] <= 'Z')) {
- buf3 += input_string[i] - 55;
- } else if ((input_string[i] >= 'a') && (input_string[i] <= 'z')) {
- buf3 += input_string[i] - 87;
- }
- if (i%2 != 0) {
- to_write[i/2] = (unsigned char) buf3;
- }
- }
- cJSON_Delete(body_json);
- fdesc = open("/sys/bus/nvmem/devices/ds1307_nvram0/nvmem", O_WRONLY);
- bytes_written = write(fdesc, to_write, 56);
- close(fdesc);
- if (bytes_written == 56) {
- http_response(req, 200, NULL, 0);
- return (KORE_RESULT_OK);
- }
- result_string = "Error: could not write to nvmem\n";
- http_response(req, 500, result_string, strlen(result_string));
- return (KORE_RESULT_OK);
- } else {
- http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
- return (KORE_RESULT_OK);
- }
- }
|