acm4.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <stdint.h>
  6. #include <syslog.h>
  7. #include <stdarg.h>
  8. #include "../../status.h"
  9. #include "../../feeder.h"
  10. static void (*feederLog) (int priority, const char *fmt, ...);
  11. int setLog(void *func)
  12. {
  13. feederLog = func;
  14. return 0;
  15. }
  16. typedef struct acm4_header_t {
  17. uint8_t start[14];
  18. char imei[16];
  19. uint8_t end[6];
  20. } acm4_header_t;
  21. //----------------------------------------------------------------------------------------------
  22. static struct acm4_header_t acm4_header_valid = {
  23. {0x00, 0x0a, 0x02, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  24. 0x20,
  25. 0x20, 0x31},
  26. "1234567890123456",
  27. {0x20, 0x20, 0x20, 0x20, 0x20, 0x20}
  28. };
  29. #define ACM4_SHORT_LAT_DG(data) ((data[0] & 0xFE) >> 1)
  30. #define ACM4_SHORT_LAT_MIN(data) (((data[0] & 0x01) << 5) | ((data[1] & 0xF8) >> 3))
  31. #define ACM4_SHORT_LAT_SEC(data) (((data[1] & 0x07) << 4) | ((data[2] & 0xF0) >> 4))
  32. #define ACM4_SHORT_LAT_SEC_HUN(data) (((data[2] & 0x0F) << 3) | ((data[3] & 0xE0) >> 5))
  33. #define ACM4_SHORT_LON_DG(data) (((data[3] & 0x1F) << 3) | ((data[4] & 0xE0) >> 5))
  34. #define ACM4_SHORT_LON_MIN(data) (((data[4] & 0x1F) << 1) | ((data[5] & 0x80) >> 7))
  35. #define ACM4_SHORT_LON_SEC(data) (data[5] & 0x7F)
  36. #define ACM4_SHORT_LON_SEC_HUN(data) ((data[6] & 0xFE) >> 1)
  37. #define ACM4_SHORT_GPS_VALID(data) (data[6] & 0x01)
  38. #define ACM4_SHORT_LON_SIGN(data) ((data[7] & 0x80) >> 7)
  39. #define ACM4_SHORT_LAT_SIGN(data) ((data[7] & 0x40) >> 6)
  40. #define ACM4_SHORT_DAY(data) (data[7] & 0x1F)
  41. #define ACM4_SHORT_MON(data) ((data[8] & 0xF0) >> 4)
  42. //#define ACM4_SHORT_YEAR(data) ((data[8] & 0x0F) + 2003)Year can not hold more than 16 years (4 bit wide). For year greater than 2018 next line is valid (workaround)
  43. #define ACM4_SHORT_YEAR(data) ((data[8] & 0x0F) + 2019)
  44. #define ACM4_SHORT_HOUR(data) ((data[9] & 0xF8) >> 3)
  45. #define ACM4_SHORT_MIN(data) (((data[9] & 0x07) << 3) | ((data[10] & 0xE0) >> 5))
  46. #define ACM4_SHORT_SEC(data) (((data[10] & 0x1F) << 1) | ((data[11] & 0x80) >> 7))
  47. #define ACM4_SHORT_SPEED(data) (((data[11] & 0x7F) << 1) | ((data[12] & 0x80) >> 7))
  48. #define ACM4_SHORT_AN(data) ((data[12] & 0x60) >> 5)
  49. #define ACM4_SHORT_IN(data) (((((uint16_t)data[12]) & 0x001F) << 5) | ((((uint16_t)data[13]) & 0x00F8) >> 3))
  50. #define ACM4_SHORT_ARB(data) (data[14] & 0x07)
  51. #define ACM4_SHORT_ARB1(data) (data[15])
  52. #define ACM4_SHORT_ARB2(data) (data[16])
  53. #define ACM4_SHORT_SIZE 28
  54. #define ARB_OUTPUTS_STATUS 0x00
  55. #define ARB_POWER_MJ 0x01
  56. #define ARB_AN_INPUTS_STATUS 0x02
  57. #define ARB_SYSTEM_INFO 0x03
  58. #define ARB_TEMPERATURE 0x04
  59. #define ARB_USER1 0x05
  60. #define ARB_USER2 0x06
  61. #define ARB_BYTE1517_OLD_BB 0x07
  62. typedef struct acm4_dev_t {
  63. char imei[17];
  64. uint8_t *data;
  65. uint16_t size;
  66. double lat, lon;
  67. uint16_t speed, an, in;
  68. uint8_t arb;
  69. uint8_t arb1, arb2;
  70. time_t ts;
  71. int obs;
  72. int alert;
  73. int fault;
  74. struct acm4_dev_t *next;
  75. } acm4_dev_t;
  76. /*
  77. int
  78. devAdd (uint8_t * id, uint8_t len)
  79. {
  80. struct acm4_dev_t *new_dev, *last_dev;
  81. new_dev = malloc (sizeof (struct acm4_dev_t));
  82. new_dev->data = malloc (2048); //todo: do define aspon
  83. memcpy (new_dev->imei, id, (len <= 16) ? len : 16);
  84. new_dev->imei[16] = 0;
  85. new_dev->size = 0;
  86. new_dev->next = NULL;
  87. new_dev->obs = 0;
  88. new_dev->lat = new_dev->lon = 0.0;
  89. new_dev->an = new_dev->in = 0.0;
  90. new_dev->ts = 0;
  91. new_dev->arb = 0;
  92. if (acm4_devs == NULL)
  93. {
  94. acm4_devs = new_dev;
  95. }
  96. else
  97. {
  98. last_dev = acm4_devs;
  99. while (last_dev->next != NULL)
  100. {
  101. last_dev = last_dev->next;
  102. }
  103. last_dev->next = new_dev;
  104. }
  105. feederLog (LOG_DEBUG, "acm4: id %s added\n", new_dev->imei);
  106. return 0;
  107. }
  108. */
  109. /*
  110. uint8_t *
  111. devImeiCmp (struct acm4_dev_t * dev, uint8_t * data, uint16_t len)
  112. {
  113. uint8_t pattern[8];
  114. uint8_t *pos;
  115. uint8_t i;
  116. for (i = 0; i < 8; i++)
  117. {
  118. pattern[i] =
  119. (((dev->imei[2 * i] - '0') << 4) | (dev->imei[2 * i + 1] - '0'));
  120. }
  121. pos = data;
  122. while (pos = memchr (pos, pattern[0], len), (pos != NULL))
  123. {
  124. if (pos >= data + len)
  125. {
  126. return NULL;
  127. }
  128. if (memcmp (pos, pattern, 8) == 0)
  129. {
  130. return pos;
  131. }
  132. pos++;
  133. if (pos >= data + len)
  134. {
  135. return NULL;
  136. }
  137. }
  138. return NULL;
  139. }
  140. */
  141. /*
  142. struct acm4_dev_t *
  143. devFind (uint8_t * data, uint16_t len)
  144. {
  145. struct acm4_dev_t *dev;
  146. uint8_t *pos;
  147. dev = acm4_devs;
  148. while (dev != NULL)
  149. {
  150. pos = devImeiCmp (dev, data, len);
  151. if (pos != NULL)
  152. return dev;
  153. dev = dev->next;
  154. }
  155. return NULL;
  156. }
  157. */
  158. int init(void *param)
  159. {
  160. param = param;
  161. // acm4_devs = NULL;
  162. // devAdd ((uint8_t *) imeis[0], strlen (imeis[0]));
  163. return sizeof(struct acm4_dev_t);
  164. }
  165. unsigned int
  166. process(void *lib_data, int socket, unsigned char *data,
  167. unsigned int length, unsigned long long int *id, time_t * tm,
  168. double *result_array, uint64_t * sensors, unsigned int *type)
  169. {
  170. unsigned int ret = 0;
  171. static uint8_t *lpos = NULL;
  172. struct acm4_header_t *acm4_header_data;
  173. uint8_t *acm4_short_data = NULL;
  174. char imei[24];
  175. uint32_t i, j;
  176. struct tm time_str;
  177. struct acm4_dev_t *dev;
  178. dev = lib_data;
  179. if (length != 0) {
  180. /* ldata = malloc (length);
  181. if (ldata == NULL)
  182. {
  183. feederLog (LOG_WARNING,
  184. "acm4: Can not allocate data buffer, size %d\n", length);
  185. return 0;
  186. }
  187. memcpy (ldata, data, length);
  188. lpos = ldata;
  189. lsize = length;*/
  190. feederLog(LOG_DEBUG, "In data ");
  191. for (i = 0; i < length; i++) {
  192. feederLog(LOG_DEBUG, "0x%02X ", data[i]);
  193. }
  194. feederLog(LOG_DEBUG, "\n");
  195. lpos = data;
  196. acm4_header_data = (struct acm4_header_t *) lpos;
  197. if ((memcmp(acm4_header_data->start, acm4_header_valid.start, 14) == 0) && (memcmp(acm4_header_data->end, acm4_header_valid.end, 6) == 0)) //todo: sizeof misto pevne delky 14 a 6
  198. {
  199. memcpy(dev->imei, acm4_header_data->imei, 16); //todo: viz vyse sizeof
  200. dev->imei[16] = 0;
  201. feederLog(LOG_DEBUG, "acm4: information block, imei %s\n",
  202. dev->imei);
  203. lpos += sizeof(acm4_header_t);
  204. dev->size = 0;
  205. }
  206. feederLog(LOG_DEBUG, "acm4: data from %s\n", dev->imei);
  207. memcpy(dev->data + dev->size, lpos, length - (lpos - data));
  208. dev->size += length - (lpos - data);
  209. /*
  210. if ((lpos != NULL) && (ldata != NULL) && (lsize != 0)
  211. && (lpos < ldata + lsize))
  212. {
  213. acm4_short_data = (uint8_t *) lpos;
  214. ldev = devFind (lpos, lsize - (lpos - ldata));
  215. if (ldev == NULL)
  216. feederLog (LOG_WARNING, "acm4: data from unknowen device\n");
  217. else
  218. {
  219. feederLog (LOG_DEBUG, "acm4: data from %s\n", ldev->imei);
  220. memcpy (ldev->data + ldev->size, lpos, lsize - (lpos - ldata));
  221. ldev->size += lsize - (lpos - ldata);
  222. }
  223. }*/
  224. }
  225. *id = 0;
  226. if ((dev != NULL) && (dev->obs == 0) && (dev->lat == 0.0)
  227. && (dev->lon == 0.0)) {
  228. feederLog(LOG_DEBUG, "acm4: data size in dev buffer %d\n",
  229. dev->size);
  230. if (dev->size >= ACM4_SHORT_SIZE) {
  231. acm4_short_data = (uint8_t *) (dev->data);
  232. dev->lat = dev->lon = 0.0;
  233. j = 0;
  234. for (i = 20; i < 28; i++) {
  235. imei[j++] = ((acm4_short_data[i] & 0xF0) >> 4) + '0';
  236. imei[j++] = (acm4_short_data[i] & 0x0F) + '0';
  237. }
  238. imei[j] = 0;
  239. feederLog(LOG_DEBUG, "acm4: imei according data packet %s\n",
  240. imei);
  241. if (strcmp(dev->imei, imei) == 0) {
  242. if (ACM4_SHORT_GPS_VALID(acm4_short_data) == 1) {
  243. dev->lat =
  244. ((double) ACM4_SHORT_LAT_DG(acm4_short_data) +
  245. (((double) ACM4_SHORT_LAT_MIN(acm4_short_data)
  246. + ((double)
  247. (ACM4_SHORT_LAT_SEC(acm4_short_data))) *
  248. 0.01 + ((double)
  249. (ACM4_SHORT_LAT_SEC_HUN
  250. (acm4_short_data)))
  251. * 0.01 * 0.01)) / 60.0) *
  252. ((ACM4_SHORT_LAT_SIGN(acm4_short_data)) * 2 - 1);
  253. dev->lon =
  254. ((double) ACM4_SHORT_LON_DG(acm4_short_data) +
  255. (((double) ACM4_SHORT_LON_MIN(acm4_short_data) +
  256. ((double) (ACM4_SHORT_LON_SEC(acm4_short_data)))
  257. * 0.01 +
  258. ((double)
  259. (ACM4_SHORT_LON_SEC_HUN(acm4_short_data))) *
  260. 0.01 * 0.01)) / 60.0) *
  261. ((ACM4_SHORT_LON_SIGN(acm4_short_data)) * (-2) +
  262. 1);
  263. feederLog(LOG_DEBUG, "acm4: lat %lf\n", dev->lat);
  264. feederLog(LOG_DEBUG, "acm4: lon %lf\n", dev->lon);
  265. } else {
  266. feederLog(LOG_WARNING, "acm4: position not valid\n");
  267. }
  268. feederLog(LOG_DEBUG,
  269. "acm4: %04d/%02d/%02d %02d:%02d:%02d\n",
  270. ACM4_SHORT_YEAR(acm4_short_data),
  271. ACM4_SHORT_MON(acm4_short_data),
  272. ACM4_SHORT_DAY(acm4_short_data),
  273. ACM4_SHORT_HOUR(acm4_short_data),
  274. ACM4_SHORT_MIN(acm4_short_data),
  275. ACM4_SHORT_SEC(acm4_short_data));
  276. time_str.tm_year = ACM4_SHORT_YEAR(acm4_short_data) - 1900;
  277. time_str.tm_mon = ACM4_SHORT_MON(acm4_short_data) - 1;
  278. time_str.tm_mday = ACM4_SHORT_DAY(acm4_short_data);
  279. time_str.tm_hour = ACM4_SHORT_HOUR(acm4_short_data);
  280. time_str.tm_min = ACM4_SHORT_MIN(acm4_short_data);
  281. time_str.tm_sec = ACM4_SHORT_SEC(acm4_short_data);
  282. dev->ts = timegm(&time_str);
  283. feederLog(LOG_DEBUG, "acm4: timestamp %ld\n", dev->ts);
  284. dev->speed = ACM4_SHORT_SPEED(acm4_short_data);
  285. dev->an = ACM4_SHORT_AN(acm4_short_data);
  286. dev->in = ACM4_SHORT_IN(acm4_short_data);
  287. dev->arb = ACM4_SHORT_ARB(acm4_short_data);
  288. feederLog(LOG_DEBUG, "acm4: arbitrary %d\n", dev->arb);
  289. dev->arb1 = ACM4_SHORT_ARB1(acm4_short_data);
  290. dev->arb2 = ACM4_SHORT_ARB2(acm4_short_data);
  291. feederLog(LOG_DEBUG, "acm4: speed %d\n", dev->speed);
  292. feederLog(LOG_DEBUG, "acm4: an %d\n", dev->an);
  293. feederLog(LOG_DEBUG, "acm4: in %d\n", dev->in);
  294. // if ((dev->lat != 0.0) && (dev->lon != 0.0)) //kdyz nemame pozici neposilame ani info
  295. dev->obs = 1;
  296. /* else
  297. dev->obs = 0;*/
  298. if (dev->in & 0xFC)
  299. dev->alert = 1;
  300. else
  301. dev->alert = 0;
  302. }
  303. else
  304. {
  305. feederLog(LOG_WARNING, "acm4: imeis are not same\n");
  306. dev->fault = 1;
  307. }
  308. j = 0;
  309. for (i = 0; i < dev->size - ACM4_SHORT_SIZE; i++) {
  310. if ((i == 0) && ((dev->data[i + ACM4_SHORT_SIZE + j] == 0xff) || (dev->data[i + ACM4_SHORT_SIZE + j] == 0x00))) //todo: je to bug ze zdroje?
  311. {
  312. j++;
  313. }
  314. dev->data[i] = dev->data[i + ACM4_SHORT_SIZE + j];
  315. // feederLog(LOG_DEBUG, "0x%02X ", dev->data[i]);
  316. }
  317. feederLog(LOG_DEBUG, "\n");
  318. /* memcpy (dev->data, dev->data + ACM4_SHORT_SIZE,
  319. dev->size - ACM4_SHORT_SIZE);*/
  320. if (!dev->fault)
  321. dev->size -= ACM4_SHORT_SIZE;
  322. }
  323. }
  324. if (dev != NULL) {
  325. if ((dev->lat != 0.0) && (dev->lon != 0.0)) {
  326. result_array[0] = dev->lat;
  327. result_array[1] = dev->lon;
  328. result_array[2] = 0.0;
  329. result_array[3] = 1.0;
  330. result_array[4] = (double)dev->speed;
  331. sensors[0] = sensors[1] = sensors[2] = sensors[3] = sensors[4] = 0x10;
  332. *type = VALUES_TYPE_POS;
  333. dev->lat = dev->lon = 0.0;
  334. ret = 5;
  335. } else {
  336. if (dev->obs) {
  337. result_array[0] = (double) dev->speed;
  338. result_array[1] = (double) dev->an;
  339. result_array[2] = (double) dev->in;
  340. result_array[3] = (double) (dev->in & 0x01);
  341. sensors[0] = TYPE_SPEED * 1000000 + 001 * 10000;
  342. sensors[1] = TYPE_DIGITAL_INPUT * 10000000 + 002 * 10000;
  343. sensors[2] = TYPE_DIGITAL_INPUT * 10000000 + 003 * 10000;
  344. sensors[3] = TYPE_DIGITAL_INPUT * 10000000 + 004 * 10000;
  345. ret = 4;
  346. if (dev->arb == ARB_SYSTEM_INFO) {
  347. result_array[4] = (double) dev->arb1;
  348. sensors[4] = TYPE_STATUS * 10000000 + 005 * 10000;
  349. ret++;
  350. }
  351. *type = VALUES_TYPE_OBS;
  352. dev->obs = 0;
  353. feederLog(LOG_DEBUG, "Generating observations\n");
  354. }
  355. else
  356. {
  357. if (dev->alert)
  358. {
  359. j = 0;
  360. for (i = 2; i < 10; i++)
  361. {
  362. if (dev->in & (1 << i))
  363. {
  364. sensors[j] = TYPE_CAR_ALERT * 10000000 + (i - 1) * 10000;
  365. j++;
  366. }
  367. }
  368. *type = VALUES_TYPE_ALERT;
  369. ret = j;
  370. dev->alert = 0;
  371. feederLog(LOG_DEBUG, "Generating alerts\n");
  372. }
  373. }
  374. }
  375. *tm = dev->ts;
  376. *id = atoll(dev->imei);
  377. } else
  378. ret = 0;
  379. /*
  380. if (ldata != NULL)
  381. free (ldata);
  382. ldata = lpos = NULL;
  383. lsize = 0;*/
  384. return ret;
  385. }
  386. int reply(void *lib_data, int socket, unsigned char *data)
  387. {
  388. // char cmd[] = {0x1B, 0x1B, 0x1B, 0x4D, 0x45, 0x4D, 0x4F, 0x52, 0x59, 0xFF, 0xFF, 0xFF};
  389. char cmd[] = {0x1B, 0x1B, 0x1B, 'M', 'E', 'M', 'O', 'R', 'Y', '_', '0', '0', '0', '0', '1', 0xFF, 0xFF, 0xFF};
  390. struct acm4_dev_t *dev;
  391. dev = lib_data;
  392. feederLog(LOG_DEBUG, "acm4: replying\n");
  393. if (dev->fault)
  394. {
  395. // return 0; //todo: -1, ale feeder to musi sprvane zpracovat, zatim spis spadne
  396. return -1;
  397. }
  398. // sprintf(data, "MEMORY_10");
  399. memcpy(data, dev->imei, 16);
  400. memcpy(data + 16, cmd, sizeof(cmd));
  401. return 0;//strlen(data);
  402. }
  403. int open(void *lib_data, int socket)
  404. {
  405. struct acm4_dev_t *dev;
  406. dev = (struct acm4_dev_t *) lib_data;
  407. feederLog(LOG_DEBUG, "acm4: socket open\n");
  408. dev->data = malloc(20480); //todo: do define aspon a checkovat
  409. dev->imei[0] = 0;
  410. dev->size = 0;
  411. dev->obs = 0;
  412. dev->lat = dev->lon = 0.0;
  413. dev->an = dev->in = 0.0;
  414. dev->ts = 0;
  415. dev->arb = 0;
  416. dev->fault = 0;
  417. return 0;
  418. }
  419. int close(void *lib_data, int socket)
  420. {
  421. struct acm4_dev_t *dev;
  422. dev = lib_data;
  423. feederLog(LOG_DEBUG, "acm4: socket closed\n");
  424. free(dev->data);
  425. return 0;
  426. }