rest.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <syslog.h>
  6. #include <stdint.h>
  7. #include <math.h>
  8. #include "libyuarel/yuarel.h"
  9. //#include "../../status.h"
  10. #include "../../feeder.h"
  11. #define RECVD_HISTORY_SIZE 32//must be dividable by 8
  12. typedef struct unit_t
  13. {
  14. uint32_t id;
  15. uint8_t recvd[RECVD_HISTORY_SIZE];
  16. uint8_t pos, recvd_size;
  17. uint32_t seq;
  18. uint8_t ack;
  19. struct unit_t * next;
  20. } unit_t;
  21. static struct unit_t * units, * unit_now;
  22. //static uint32_t seq;
  23. static uint8_t ack;
  24. static void (* feederLog)(int priority, const char * fmt, ...);
  25. int setLog(void * func)
  26. {
  27. feederLog = (void(*)(int, const char * , ...))func;
  28. return 0;
  29. }
  30. int init(void * param)
  31. {
  32. (void)param;
  33. // seq = 0;
  34. units = unit_now = NULL;
  35. ack = 0;
  36. return 0;
  37. }
  38. struct unit_t * unitFind(struct unit_t * unit, uint32_t id)
  39. {
  40. while (unit != NULL)
  41. {
  42. if (unit->id == id)
  43. return unit;
  44. unit = unit->next;
  45. }
  46. return NULL;
  47. }
  48. struct unit_t * unitCreate(uint32_t id)
  49. {
  50. struct unit_t * unit;
  51. unit = (struct unit_t *)malloc(sizeof(struct unit_t));
  52. unit->id = id;
  53. memset(unit->recvd, 0, RECVD_HISTORY_SIZE);
  54. unit->seq = 0;
  55. unit->pos = 0;
  56. unit->next = NULL;
  57. return unit;
  58. }
  59. void unitUpdateRecvd(struct unit_t * unit, uint8_t flag)
  60. {
  61. unit->recvd[unit->pos++] = flag;
  62. if (unit->pos > RECVD_HISTORY_SIZE)
  63. unit->pos = 0;
  64. }
  65. unsigned int
  66. process(void *lib_data, int socket, unsigned char *data,
  67. unsigned int length, unsigned long long int *id, time_t * tm,
  68. double *result_array, uint64_t * sensors, unsigned int *type)
  69. {
  70. struct yuarel url;
  71. int p, i;
  72. // char * parts[3];
  73. struct yuarel_param params[16];
  74. char *c;
  75. struct unit_t * unit;
  76. uint32_t seq;
  77. (void)lib_data;
  78. (void)socket;
  79. (void)type;
  80. if ((data == NULL) || (length == 0))
  81. return 0;
  82. feederLog(LOG_DEBUG, "rest: raw data in:\n%s\n", (char *)data);
  83. seq = 0;
  84. *id = 0;
  85. data[length] = 0;
  86. if (yuarel_parse(&url, (char *)(data + 4)) != 0)//skip leading GET
  87. {
  88. feederLog(LOG_WARNING, "rest: Yuarel can not parse input\n");
  89. return 0;
  90. }
  91. c = strchr(url.query, ' ');
  92. if (c != NULL)
  93. *c = 0;
  94. // feederLog(LOG_DEBUG, "rest: scheme: %s\n", url.scheme);
  95. // feederLog(LOG_DEBUG, "rest: host: %s\n", url.host);pada?
  96. // feederLog(LOG_DEBUG, "rest: port: %d\n", url.port);
  97. // feederLog(LOG_DEBUG, "rest: path: %s\n", url.path);
  98. feederLog(LOG_DEBUG, "rest: query: %s\n", url.query);
  99. // feederLog(LOG_DEBUG, "rest: fragment: %s\n", url.fragment);pada?
  100. /*
  101. if (3 != yuarel_split_path(url.path, parts, 3)) {
  102. fprintf(stderr, "Could not split path!\n");
  103. return 0;
  104. }
  105. feederLog(LOG_DEBUG, "rest: path parts: %s, %s, %s\n", parts[0], parts[1], parts[2]);
  106. feederLog(LOG_DEBUG, "rest: Query string parameters:\n");
  107. */
  108. p = yuarel_parse_query(url.query, '&', params, 16);
  109. i = 0;
  110. ack = 0;
  111. while (i < p)
  112. {
  113. feederLog(LOG_DEBUG, "rest: %s: %s\n", params[i].key, params[i].val);
  114. if (strcmp(params[i].key, "date") == 0)
  115. *tm = atoll(params[i].val);
  116. if (strcmp(params[i].key, "sensor_id") == 0)
  117. sensors[0] = atoll(params[i].val);
  118. if (strcmp(params[i].key, "unit_id") == 0)
  119. {
  120. //*id = atoll(params[i].val);
  121. *id = strtoll(params[i].val, NULL, 16);
  122. }
  123. if (strcmp(params[i].key, "value") == 0)
  124. result_array[0] = atof(params[i].val);
  125. if (strcmp(params[i].key, "seq") == 0)
  126. seq = atoi(params[i].val);
  127. if (strcmp(params[i].key, "ack") == 0)
  128. ack = (strcmp(params[i].val, "true") == 0)?1:0;
  129. i++;
  130. }
  131. *type = VALUES_TYPE_OBS;
  132. unit = unitFind(units, *id);
  133. if (unit == NULL)
  134. {
  135. feederLog(LOG_DEBUG, "rest: creating new unit %ld\n", *id);
  136. unit = unitCreate(*id);
  137. if (units != NULL)
  138. {
  139. unit->next = units;
  140. }
  141. units = unit;
  142. }
  143. else
  144. feederLog(LOG_DEBUG, "rest: unit %ld found\n", unit->id);
  145. if (unit->seq == 0)//todo: je nula opravdu vyjimecna?
  146. unit->seq = seq;
  147. else
  148. {
  149. while (unit->seq++, unit->seq < seq)
  150. unitUpdateRecvd(unit, 0);
  151. }
  152. unitUpdateRecvd(unit, 1);
  153. unit->ack = ack;
  154. unit_now = unit;
  155. if (*id != 0)
  156. return 1;
  157. return 0;
  158. }
  159. int reply(void * lib_data, int socket, unsigned char *data)
  160. {
  161. uint8_t i, j;
  162. struct unit_t * unit;
  163. char * buf;
  164. (void)lib_data;
  165. (void)socket;
  166. unit = unit_now;
  167. if (unit == NULL)
  168. {
  169. //todo: odpovededet nejakym chybou
  170. return 0;
  171. }
  172. if (unit->seq == 0)
  173. return 0;
  174. time((time_t *)data);
  175. /*todo
  176. memset(data + 4, 0, 4);
  177. for (i = 0; i < RECVD_HISTORY_SIZE; i++)
  178. {
  179. j = unit->pos - (RECVD_HISTORY_SIZE + i);
  180. if (j > RECVD_HISTORY_SIZE) //rotated (less then zero)
  181. j += RECVD_HISTORY_SIZE;
  182. data[4 + i / 8] |= unit->recvd[j] << (i % 8);
  183. }
  184. */
  185. buf = (char *)data;
  186. time_t now = time(0);
  187. struct tm tm = *gmtime(&now);
  188. sprintf(buf, "HTTP/1.0 204 NO CONTENT\r\nServer: feeder\r\nContent-Length: %d\r\nDate: ", 0);
  189. strftime(buf + strlen(buf), 1000, "%a, %d %b %Y %H:%M:%S %Z", &tm);
  190. sprintf(buf + strlen(buf), "\r\n\r\n");
  191. feederLog(LOG_DEBUG, "rest: raw data out: \n%s\n", (char *)data);
  192. feederLog(LOG_DEBUG, "rest: replying\n");
  193. unit->seq = 0;
  194. return strlen((char *)data);
  195. }