jsonrtc.c 9.5 KB

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