jsonrtc.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * This file is part of the jsonrtc.
  3. * written in 2018 by Helmut Pozimski.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, version 2.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <kore/kore.h>
  18. #include <kore/http.h>
  19. #include <fcntl.h>
  20. #include <unistd.h>
  21. #include <string.h>
  22. #include <sys/ioctl.h>
  23. #include <linux/rtc.h>
  24. #include <cjson/cJSON.h>
  25. int page(struct http_request *);
  26. int handle_time(struct http_request *);
  27. int handle_wkalrm(struct http_request *);
  28. int
  29. page(struct http_request *req)
  30. {
  31. http_response(req, 200, NULL, 0);
  32. return (KORE_RESULT_OK);
  33. }
  34. static char * read_body(struct http_request *req) {
  35. int ret;
  36. struct kore_buf * buf;
  37. u_int8_t data[128];
  38. char * body;
  39. buf = kore_buf_alloc(128);
  40. while(1) {
  41. ret = http_body_read(req, data, sizeof(data));
  42. if (ret == -1) {
  43. kore_buf_free(buf);
  44. return NULL;
  45. } else if (ret == 0) {
  46. break;
  47. }
  48. kore_buf_append(buf,data,ret);
  49. }
  50. body = kore_buf_stringify(buf, NULL);
  51. kore_buf_free(buf);
  52. return body;
  53. }
  54. int handle_time(struct http_request *req) {
  55. int fdesc;
  56. struct rtc_time time;
  57. int ret;
  58. char *result_string;
  59. cJSON *time_json, *json_min, *json_hour, *json_mday,
  60. *json_mon, *json_year, *json_sec, *json_wday;
  61. if(req->method == HTTP_METHOD_GET) {
  62. time_json = cJSON_CreateObject();
  63. fdesc = open("/dev/rtc", O_RDONLY);
  64. ret = ioctl(fdesc, RTC_RD_TIME, &time);
  65. close(fdesc);
  66. if (!ret) {
  67. json_sec = cJSON_CreateNumber(time.tm_sec);
  68. json_min = cJSON_CreateNumber(time.tm_min);
  69. json_hour = cJSON_CreateNumber(time.tm_hour);
  70. json_mday = cJSON_CreateNumber(time.tm_mday);
  71. json_mon = cJSON_CreateNumber(time.tm_mon);
  72. json_year = cJSON_CreateNumber(time.tm_year);
  73. json_wday = cJSON_CreateNumber(time.tm_wday);
  74. cJSON_AddItemToObject(time_json, "seconds", json_sec);
  75. cJSON_AddItemToObject(time_json, "minutes", json_min);
  76. cJSON_AddItemToObject(time_json, "hour", json_hour);
  77. cJSON_AddItemToObject(time_json, "mday", json_mday);
  78. cJSON_AddItemToObject(time_json, "month", json_mon);
  79. cJSON_AddItemToObject(time_json, "year", json_year);
  80. cJSON_AddItemToObject(time_json, "wday", json_wday);
  81. result_string = cJSON_Print(time_json);
  82. cJSON_Delete(time_json);
  83. http_response_header(req, "Content-Type", "application/json");
  84. http_response(req, 200, result_string, strlen(result_string));
  85. return KORE_RESULT_OK;
  86. }
  87. cJSON_Delete(time_json);
  88. result_string = "Error: could not get time from /dev/rtc\n";
  89. http_response(req, 500, result_string, strlen(result_string));
  90. return KORE_RESULT_OK;
  91. } else if (req->method == HTTP_METHOD_POST) {
  92. char * body;
  93. body = read_body(req);
  94. if (body == NULL) {
  95. result_string = "Error: could not read request body\n";
  96. http_response(req, 500, result_string, strlen(result_string));
  97. return (KORE_RESULT_OK);
  98. }
  99. time_json = cJSON_Parse(body);
  100. if (time_json == NULL) {
  101. result_string = "Error: could not parse json\n";
  102. http_response(req, 500, result_string, strlen(result_string));
  103. return (KORE_RESULT_OK);
  104. }
  105. json_sec = cJSON_GetObjectItemCaseSensitive(time_json, "seconds");
  106. json_min = cJSON_GetObjectItemCaseSensitive(time_json, "minutes");
  107. json_hour = cJSON_GetObjectItemCaseSensitive(time_json, "hour");
  108. json_mday = cJSON_GetObjectItemCaseSensitive(time_json, "mday");
  109. json_mon = cJSON_GetObjectItemCaseSensitive(time_json, "month");
  110. json_year = cJSON_GetObjectItemCaseSensitive(time_json, "year");
  111. json_wday = cJSON_GetObjectItemCaseSensitive(time_json, "wday");
  112. if (cJSON_IsNumber(json_sec) && cJSON_IsNumber(json_min) && cJSON_IsNumber(json_hour) &&
  113. cJSON_IsNumber(json_mday) && cJSON_IsNumber(json_mon) &&
  114. cJSON_IsNumber(json_year) && cJSON_IsNumber(json_wday)) {
  115. time.tm_sec = json_sec->valueint;
  116. time.tm_min = json_min->valueint;
  117. time.tm_hour = json_hour->valueint;
  118. time.tm_mday = json_mday->valueint;
  119. time.tm_mon = json_mon->valueint;
  120. time.tm_year = json_year->valueint;
  121. time.tm_wday = json_wday->valueint;
  122. } else {
  123. cJSON_Delete(time_json);
  124. result_string = "Error: invalid or missing values in json object\n";
  125. http_response(req, 500, result_string, strlen(result_string));
  126. return (KORE_RESULT_OK);
  127. }
  128. cJSON_Delete(time_json);
  129. fdesc = open("/dev/rtc", O_WRONLY);
  130. ret = ioctl(fdesc, RTC_SET_TIME, &time);
  131. close(fdesc);
  132. if (ret) {
  133. result_string = "Error: Could not set time via /dev/rtc\n";
  134. http_response(req, 500, result_string, strlen(result_string));
  135. return (KORE_RESULT_OK);
  136. }
  137. http_response(req, 200, NULL, 0);
  138. return KORE_RESULT_OK;
  139. } else {
  140. http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
  141. return (KORE_RESULT_OK);
  142. }
  143. }
  144. int handle_wkalrm(struct http_request *req) {
  145. char *result_string;
  146. struct rtc_wkalrm alarm;
  147. int fdesc, ret;
  148. cJSON *alarm_json, *json_min, *json_hour, *json_mday,
  149. *json_mon, *json_year, *json_sec, *json_wday,
  150. *json_enabled, *json_pending;
  151. if(req->method == HTTP_METHOD_GET) {
  152. alarm_json = cJSON_CreateObject();
  153. fdesc = open("/dev/rtc", O_RDONLY);
  154. ret = ioctl(fdesc, RTC_WKALM_RD, &alarm);
  155. close(fdesc);
  156. if (!ret) {
  157. json_sec = cJSON_CreateNumber(alarm.time.tm_sec);
  158. json_min = cJSON_CreateNumber(alarm.time.tm_min);
  159. json_hour = cJSON_CreateNumber(alarm.time.tm_hour);
  160. json_mday = cJSON_CreateNumber(alarm.time.tm_mday);
  161. json_mon = cJSON_CreateNumber(alarm.time.tm_mon);
  162. json_year = cJSON_CreateNumber(alarm.time.tm_year);
  163. json_wday = cJSON_CreateNumber(alarm.time.tm_wday);
  164. json_enabled = cJSON_CreateNumber(alarm.enabled);
  165. json_pending = cJSON_CreateNumber(alarm.pending);
  166. cJSON_AddItemToObject(alarm_json, "seconds", json_sec);
  167. cJSON_AddItemToObject(alarm_json, "minutes", json_min);
  168. cJSON_AddItemToObject(alarm_json, "hour", json_hour);
  169. cJSON_AddItemToObject(alarm_json, "mday", json_mday);
  170. cJSON_AddItemToObject(alarm_json, "month", json_mon);
  171. cJSON_AddItemToObject(alarm_json, "year", json_year);
  172. cJSON_AddItemToObject(alarm_json, "wday", json_wday);
  173. cJSON_AddItemToObject(alarm_json, "enabled", json_enabled);
  174. cJSON_AddItemToObject(alarm_json, "pending", json_pending);
  175. result_string = cJSON_Print(alarm_json);
  176. cJSON_Delete(alarm_json);
  177. http_response_header(req, "Content-Type", "application/json");
  178. http_response(req, 200, result_string, strlen(result_string));
  179. return KORE_RESULT_OK;
  180. }
  181. cJSON_Delete(alarm_json);
  182. result_string = "Error: could not get alarm from /dev/rtc\n";
  183. http_response(req, 500, result_string, strlen(result_string));
  184. return KORE_RESULT_OK;
  185. } else if (req->method == HTTP_METHOD_POST) {
  186. char * body = read_body(req);
  187. if (body == NULL) {
  188. result_string = "Error: could not read request body\n";
  189. http_response(req, 500, result_string, strlen(result_string));
  190. return (KORE_RESULT_OK);
  191. }
  192. alarm_json = cJSON_Parse(body);
  193. if (alarm_json == NULL) {
  194. result_string = "Error: could not parse json\n";
  195. http_response(req, 500, result_string, strlen(result_string));
  196. return (KORE_RESULT_OK);
  197. }
  198. json_sec = cJSON_GetObjectItemCaseSensitive(alarm_json, "seconds");
  199. json_min = cJSON_GetObjectItemCaseSensitive(alarm_json, "minutes");
  200. json_hour = cJSON_GetObjectItemCaseSensitive(alarm_json, "hour");
  201. json_mday = cJSON_GetObjectItemCaseSensitive(alarm_json, "mday");
  202. json_mon = cJSON_GetObjectItemCaseSensitive(alarm_json, "month");
  203. json_year = cJSON_GetObjectItemCaseSensitive(alarm_json, "year");
  204. json_wday = cJSON_GetObjectItemCaseSensitive(alarm_json, "wday");
  205. json_enabled = cJSON_GetObjectItemCaseSensitive(alarm_json, "enabled");
  206. if (cJSON_IsNumber(json_sec) && cJSON_IsNumber(json_min) && cJSON_IsNumber(json_hour) &&
  207. cJSON_IsNumber(json_mday) && cJSON_IsNumber(json_mon) &&
  208. cJSON_IsNumber(json_year) && cJSON_IsNumber(json_wday) &&
  209. cJSON_IsNumber(json_enabled)) {
  210. alarm.time.tm_sec = json_sec->valueint;
  211. alarm.time.tm_min = json_min->valueint;
  212. alarm.time.tm_hour = json_hour->valueint;
  213. alarm.time.tm_mday = json_mday->valueint;
  214. alarm.time.tm_mon = json_mon->valueint;
  215. alarm.time.tm_year = json_year->valueint;
  216. alarm.time.tm_wday = json_wday->valueint;
  217. alarm.enabled = json_enabled->valueint;
  218. } else {
  219. cJSON_Delete(alarm_json);
  220. result_string = "Error: invalid or missing values in json object\n";
  221. http_response(req, 500, result_string, strlen(result_string));
  222. return (KORE_RESULT_OK);
  223. }
  224. cJSON_Delete(alarm_json);
  225. fdesc = open("/dev/rtc", O_WRONLY);
  226. ret = ioctl(fdesc, RTC_WKALM_SET, &alarm);
  227. close(fdesc);
  228. if (ret) {
  229. result_string = "Error: Could not set alarm via /dev/rtc\n";
  230. http_response(req, 500, result_string, strlen(result_string));
  231. return (KORE_RESULT_OK);
  232. }
  233. http_response(req, 200, NULL, 0);
  234. return KORE_RESULT_OK;
  235. } else {
  236. http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
  237. return (KORE_RESULT_OK);
  238. }
  239. }