| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <syslog.h>
- #include <stdint.h>
- #include <math.h>
- #include <confuse.h>
- #include "libyuarel/yuarel.h"
- //#include "libfixmath/libfixmath/fixmath.h"
- #include "sensob/sensob.h"
- //#include "../../status.h"
- #include "../../feeder.h"
- cfg_opt_t metaid_opts[] =
- {
- CFG_INT((char *)"metaid", 0, CFGF_NONE),
- CFG_INT_LIST((char *)"sensorid", 0, CFGF_NONE),
- CFG_END()
- };
- cfg_opt_t device_opts[] =
- {
- CFG_STR((char *)"unit_id", 0, CFGF_NONE),
- CFG_SEC((char *)"metaid", metaid_opts, CFGF_MULTI | CFGF_TITLE),
- CFG_END()
- };
- cfg_opt_t cfg_opts[] =
- {
- CFG_SEC((char *)"device", device_opts, CFGF_MULTI | CFGF_TITLE),
- CFG_END()
- };
- #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;
- }
- void stringToArrayn(uint8_t * data, char * str, uint16_t len)
- {
- uint16_t i;
- uint8_t j;
- char c;
- for (i = 0; i < len; i++)
- {
- data[i] = 0;
- for (j = 0; j < 2; j++)
- {
- c = str[i * 2 + j];
- if (c >= 'a') //to high case
- c -= 0x20;
- data[i] += (c - ((c < 'A')?'0':'7')) << ((j == 0)?4:0);
- }
- }
- }
- void arraynToString(char * str, uint8_t * data, uint16_t len)
- {
- uint16_t i;
- uint8_t j;
- char c;
- for (i = 0; i < len; i++)
- {
- for (j = 0; j < 2; j++)
- {
- c = (data[i] >> ((j == 0)?4:0)) & 0x0F;
- str[i * 2 + j] = c + ((c < 0x0A)?'0':'7');
- }
- }
- str[len * 2] = '\0';
- }
- char * yarel_get_param(struct yuarel_param * params, int params_count, const char * param_name)
- {
- int i;
- i = 0;
- while (i < params_count)
- {
- if (strcmp(params[i].key, param_name) == 0)
- return params[i].val;
- i++;
- }
- return NULL;
- }
- 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;
- uint8_t params_data_bin[12];
- uint8_t params_data_len;
- uint64_t pid;
- unsigned int res;
- (void)lib_data;
- (void)socket;
- (void)type;
- if ((data == NULL) || (length == 0))
- return 0;
- feederLog(LOG_DEBUG, "sigfox: 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, "sigfox: Yuarel can not parse input\n");
- return 0;
- }
-
- c = strchr(url.query, ' ');
- if (c != NULL)
- *c = 0;
- // feederLog(LOG_DEBUG, "sigfox: scheme: %s\n", url.scheme);
- // feederLog(LOG_DEBUG, "sigfox: host: %s\n", url.host);pada?
- // feederLog(LOG_DEBUG, "sigfox: port: %d\n", url.port);
- // feederLog(LOG_DEBUG, "sigfox: path: %s\n", url.path);
- feederLog(LOG_DEBUG, "sigfox: query: %s\n", url.query);
- // feederLog(LOG_DEBUG, "sigfox: 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, "sigfox: path parts: %s, %s, %s\n", parts[0], parts[1], parts[2]);
- feederLog(LOG_DEBUG, "sigfox: Query string parameters:\n");
- */
- p = yuarel_parse_query(url.query, '&', params, 16);
-
- params_data_len = strlen(yarel_get_param(params, p, "data")) / 2;
- stringToArrayn(params_data_bin, yarel_get_param(params, p, "data"), params_data_len);
- feederLog(LOG_DEBUG, "sigfox: binary data: ");
- for (i = 0; i < params_data_len; i++)
- feederLog(LOG_DEBUG, "%02X ", params_data_bin[i]);
- feederLog(LOG_DEBUG, "\n");
-
- pid = strtoll(yarel_get_param(params, p, "unit_id"), NULL, 16);
- seq = atoi(yarel_get_param(params, p, "seq"));
- if (params_data_bin[0] == 0xFF)//this is sensob message
- {
- feederLog(LOG_DEBUG, "sigfox: sensob detected\n");
- feederLog(LOG_WARNING, "sigfox: sensob protocol not supported\n");
- }
- // else if (json_data_data_bin[0] == 0xFE)//this is command todo: nebo rozlisit podle portu
- else if (params_data_bin[0] > 0xC0)//this is command todo: nebo rozlisit podle portu
- {
- feederLog(LOG_DEBUG, "sigfox: cmd detected\n");
- //cmdParse(params_data_bin, params_data_len, pid);
- }
- else if (params_data_bin[0] >= 0xA0) //this is sensob tiny message
- {
- feederLog(LOG_DEBUG, "sigfox: sensob tiny detected\n");
-
- res = sensobtiny_parse(params_data_bin, params_data_len, strtol(yarel_get_param(params, p, "ts"), NULL, 10), tm, result_array, sensors, type);
- *id = pid;
- }
- else //this is sensob lite message
- {
- feederLog(LOG_DEBUG, "sigfox: sensob lite detected\n");
- res = sensoblite_parse(params_data_bin, params_data_len, tm, result_array, sensors, type);
- *id = pid;
- }
- /*
- i = 0;
- ack = 0;
- while (i < p)
- {
- feederLog(LOG_DEBUG, "sigfox: %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 = strtoll(params[i].val, NULL, 16);
- }
- if (strcmp(params[i].key, "value") == 0)
- // result_array[0] = atof(params[i].val);
- result_array[0] = fix16_to_float(atoll(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, "sigfox: creating new unit %ld\n", *id);
- unit = unitCreate(*id);
- if (units != NULL)
- {
- unit->next = units;
- }
- units = unit;
- }
- else
- feederLog(LOG_DEBUG, "sigfox: 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 res;
- 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, "sigfox: raw data out: \n%s\n", (char *)data);
- feederLog(LOG_DEBUG, "sigfox: replying\n");
- unit->seq = 0;
- return strlen((char *)data);
- }
|