#include #include #include #include #include #include #include #include "libyuarel/yuarel.h" //#include "../../status.h" #include "../../feeder.h" #define RECVD_HISTORY_SIZE 32//must be dividable by 8 typedef struct unit_t { uint32_t id; uint8_t recvd[RECVD_HISTORY_SIZE]; uint8_t pos, recvd_size; uint32_t seq; uint8_t ack; struct unit_t * next; } unit_t; static struct unit_t * units, * unit_now; //static uint32_t seq; static uint8_t ack; static void (* feederLog)(int priority, const char * fmt, ...); int setLog(void * func) { feederLog = (void(*)(int, const char * , ...))func; return 0; } int init(void * param) { (void)param; // seq = 0; units = unit_now = NULL; ack = 0; return 0; } struct unit_t * unitFind(struct unit_t * unit, uint32_t id) { while (unit != NULL) { if (unit->id == id) return unit; unit = unit->next; } return NULL; } struct unit_t * unitCreate(uint32_t id) { struct unit_t * unit; unit = (struct unit_t *)malloc(sizeof(struct unit_t)); unit->id = id; memset(unit->recvd, 0, RECVD_HISTORY_SIZE); unit->seq = 0; unit->pos = 0; unit->next = NULL; return unit; } void unitUpdateRecvd(struct unit_t * unit, uint8_t flag) { unit->recvd[unit->pos++] = flag; if (unit->pos > RECVD_HISTORY_SIZE) unit->pos = 0; } unsigned int process(void *lib_data, int socket, unsigned char *data, unsigned int length, unsigned long long int *id, time_t * tm, double *result_array, uint64_t * sensors, unsigned int *type) { struct yuarel url; int p, i; // char * parts[3]; struct yuarel_param params[16]; char *c; struct unit_t * unit; uint32_t seq; (void)lib_data; (void)socket; (void)type; if ((data == NULL) || (length == 0)) return 0; feederLog(LOG_DEBUG, "rest: raw data in:\n%s\n", (char *)data); seq = 0; *id = 0; data[length] = 0; if (yuarel_parse(&url, (char *)(data + 4)) != 0)//skip leading GET { feederLog(LOG_WARNING, "rest: Yuarel can not parse input\n"); return 0; } c = strchr(url.query, ' '); if (c != NULL) *c = 0; // feederLog(LOG_DEBUG, "rest: scheme: %s\n", url.scheme); // feederLog(LOG_DEBUG, "rest: host: %s\n", url.host);pada? // feederLog(LOG_DEBUG, "rest: port: %d\n", url.port); // feederLog(LOG_DEBUG, "rest: path: %s\n", url.path); feederLog(LOG_DEBUG, "rest: query: %s\n", url.query); // feederLog(LOG_DEBUG, "rest: fragment: %s\n", url.fragment);pada? /* if (3 != yuarel_split_path(url.path, parts, 3)) { fprintf(stderr, "Could not split path!\n"); return 0; } feederLog(LOG_DEBUG, "rest: path parts: %s, %s, %s\n", parts[0], parts[1], parts[2]); feederLog(LOG_DEBUG, "rest: Query string parameters:\n"); */ p = yuarel_parse_query(url.query, '&', params, 16); i = 0; ack = 0; while (i < p) { feederLog(LOG_DEBUG, "rest: %s: %s\n", params[i].key, params[i].val); if (strcmp(params[i].key, "date") == 0) *tm = atoll(params[i].val); if (strcmp(params[i].key, "sensor_id") == 0) sensors[0] = atoll(params[i].val); if (strcmp(params[i].key, "unit_id") == 0) { //*id = atoll(params[i].val); *id = strtoll(params[i].val, NULL, 16); } if (strcmp(params[i].key, "value") == 0) result_array[0] = atof(params[i].val); if (strcmp(params[i].key, "seq") == 0) seq = atoi(params[i].val); if (strcmp(params[i].key, "ack") == 0) ack = (strcmp(params[i].val, "true") == 0)?1:0; i++; } *type = VALUES_TYPE_OBS; unit = unitFind(units, *id); if (unit == NULL) { feederLog(LOG_DEBUG, "rest: creating new unit %ld\n", *id); unit = unitCreate(*id); if (units != NULL) { unit->next = units; } units = unit; } else feederLog(LOG_DEBUG, "rest: unit %ld found\n", unit->id); if (unit->seq == 0)//todo: je nula opravdu vyjimecna? unit->seq = seq; else { while (unit->seq++, unit->seq < seq) unitUpdateRecvd(unit, 0); } unitUpdateRecvd(unit, 1); unit->ack = ack; unit_now = unit; if (*id != 0) return 1; return 0; } int reply(void * lib_data, int socket, unsigned char *data) { uint8_t i, j; struct unit_t * unit; char * buf; (void)lib_data; (void)socket; unit = unit_now; if (unit == NULL) { //todo: odpovededet nejakym chybou return 0; } if (unit->seq == 0) return 0; time((time_t *)data); /*todo memset(data + 4, 0, 4); for (i = 0; i < RECVD_HISTORY_SIZE; i++) { j = unit->pos - (RECVD_HISTORY_SIZE + i); if (j > RECVD_HISTORY_SIZE) //rotated (less then zero) j += RECVD_HISTORY_SIZE; data[4 + i / 8] |= unit->recvd[j] << (i % 8); } */ buf = (char *)data; time_t now = time(0); struct tm tm = *gmtime(&now); sprintf(buf, "HTTP/1.0 204 NO CONTENT\r\nServer: feeder\r\nContent-Length: %d\r\nDate: ", 0); strftime(buf + strlen(buf), 1000, "%a, %d %b %Y %H:%M:%S %Z", &tm); sprintf(buf + strlen(buf), "\r\n\r\n"); feederLog(LOG_DEBUG, "rest: raw data out: \n%s\n", (char *)data); feederLog(LOG_DEBUG, "rest: replying\n"); unit->seq = 0; return strlen((char *)data); }