A messenger application for Raspberry Pi Zerofor A.U.TH (Real time Embedded systems).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

807 line
21 KiB

  1. #define DEBUG
  2. #define FU08 "%hhu"
  3. #define FU16 "%hu"
  4. #define FU32 "%lu"
  5. #define FU64 "%llu"
  6. #define FSTR "%s"
  7. #include <stdio.h>
  8. #include <stdint.h>
  9. #include <stdlib.h>
  10. #include <stdbool.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include <semaphore.h>
  14. //--Tools Module
  15. #include <time.h>
  16. uint64_t TIME_u64Current(void) {
  17. return time(NULL);
  18. }
  19. uint16_t RAND_u16GetNumber(uint16_t u16Min, uint16_t u16Max) {
  20. static uint8_t i = 0;
  21. if (i == 0) {
  22. srand(time(NULL));
  23. i++;
  24. }
  25. return rand() % (u16Max + 1 - u16Min) + u16Min;
  26. }
  27. //--Log Module
  28. #include <stdarg.h>
  29. sem_t semLog;
  30. void LOG_vSetup(void) {
  31. sem_init(&semLog, 0, 1);
  32. }
  33. void LOG_vPrintf(const char* format, ...) {
  34. sem_wait(&semLog);
  35. va_list args;
  36. va_start(args, format);
  37. #ifdef DEBUG
  38. printf(FU64":", TIME_u64Current());
  39. vprintf(format, args);
  40. #endif
  41. FILE* fp;
  42. fp = fopen("/tmp/log.txt", "a");
  43. if (fp != NULL) {
  44. fprintf(fp, FU64":", TIME_u64Current());
  45. vfprintf(fp, format, args);
  46. fclose(fp);
  47. }
  48. va_end(args);
  49. sem_post(&semLog);
  50. }
  51. //--File Module
  52. #define FILE_EOF 0xFF
  53. int8_t FILE_i08Compare(char* pchPath1, char* pchPath2) {
  54. FILE* file1 = fopen(pchPath1, "r");
  55. FILE* file2 = fopen(pchPath2, "r");
  56. if (file1 == NULL) {
  57. if (file2 != NULL)
  58. fclose(file2);
  59. return 1;
  60. }
  61. if (file2 == NULL) {
  62. fclose(file1);
  63. return 2;
  64. }
  65. char ch1, ch2;
  66. do {
  67. ch1 = fgetc(file1);
  68. ch2 = fgetc(file2);
  69. if (ch1 != ch2) {
  70. fclose(file1);
  71. fclose(file2);
  72. return 0;
  73. }
  74. } while (ch1 != FILE_EOF && ch2 != FILE_EOF);
  75. if (ch1 == FILE_EOF && ch2 == FILE_EOF) {
  76. fclose(file1);
  77. fclose(file2);
  78. return 3;
  79. }
  80. else {
  81. fclose(file1);
  82. fclose(file2);
  83. return 0;
  84. }
  85. }
  86. //--WiFi Module
  87. #define NETWORK_TYPE "wlan0"
  88. #include <arpa/inet.h>
  89. #include <sys/socket.h>
  90. #define WIFI_BUFFER 2000
  91. #include <pthread.h>
  92. struct ParserArgs {
  93. int sock;
  94. struct sockaddr_in client_address;
  95. socklen_t client_address_len;
  96. bool (*bParse)(uint8_t* pu08Address, char* pchBuffer);
  97. };
  98. void WiFi_vParser(void* ptr) {
  99. struct ParserArgs temp;
  100. memcpy(&temp, ptr, sizeof(struct ParserArgs));
  101. char pchRemoteAddress[INET_ADDRSTRLEN];
  102. inet_ntop(AF_INET, &(temp.client_address.sin_addr), pchRemoteAddress, INET_ADDRSTRLEN);
  103. //uint16_t pu16RemotePort = temp.client_address.sin_port;
  104. char pchBuffer[WIFI_BUFFER];
  105. char* pchTemp = (char*)pchBuffer;
  106. int16_t i16New = 0;
  107. uint16_t u16Length = 0;
  108. uint16_t u16Remaining = WIFI_BUFFER;
  109. while ((i16New = recv(temp.sock, pchTemp, u16Remaining, 0)) > 0) {
  110. pchTemp += i16New;
  111. u16Remaining -= i16New;
  112. u16Length += i16New;
  113. pchTemp[0] = '\0';
  114. }
  115. uint8_t pu08Levels[4];
  116. sscanf(pchRemoteAddress, FU08"."FU08"."FU08"."FU08, &pu08Levels[0], &pu08Levels[1], &pu08Levels[2], &pu08Levels[3]);
  117. temp.bParse(pu08Levels, pchBuffer);
  118. close(temp.sock);
  119. }
  120. bool WiFi_bListener(int32_t i32ServerPort, bool (*bParse)(uint8_t* pu08Address, char* pchBuffer)) {
  121. struct sockaddr_in server_address;
  122. memset(&server_address, 0, sizeof(server_address));
  123. server_address.sin_family = AF_INET;
  124. server_address.sin_port = htons(i32ServerPort);
  125. server_address.sin_addr.s_addr = htonl(INADDR_ANY);
  126. int listen_sock;
  127. if ((listen_sock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
  128. return false;
  129. if ((bind(listen_sock, (struct sockaddr *)&server_address, sizeof(server_address))) == -1) {
  130. close(listen_sock);
  131. return false;
  132. }
  133. if (listen(listen_sock, WIFI_BUFFER) == -1) {
  134. close(listen_sock);
  135. return false;
  136. }
  137. while (true) {
  138. LOG_vPrintf("WiFiListener-New\n");
  139. struct ParserArgs client;
  140. client.client_address_len = sizeof(client.client_address);
  141. client.bParse = bParse;
  142. LOG_vPrintf("WiFiListener-Start\n");
  143. if ((client.sock = accept(listen_sock, (struct sockaddr *)&client.client_address, &client.client_address_len)) == -1) {
  144. return false;
  145. }
  146. WiFi_vParser(&client);
  147. LOG_vPrintf("WiFiListener-Stop\n");
  148. }
  149. close(listen_sock);
  150. return true;
  151. }
  152. bool WiFi_bSend(char* pchServerAddress, int32_t i32ServerPort, char* pchServerText) {
  153. LOG_vPrintf("WiFi-Send-Sock\n");
  154. int sock;
  155. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  156. LOG_vPrintf("WiFi-Send-Fail\n");
  157. return false;
  158. }
  159. LOG_vPrintf("WiFi-Send-Init\n");
  160. struct sockaddr_in server_address;
  161. memset(&server_address, 0, sizeof(server_address));
  162. server_address.sin_family = AF_INET;
  163. server_address.sin_addr.s_addr = inet_addr(pchServerAddress);
  164. server_address.sin_port = htons(i32ServerPort);
  165. LOG_vPrintf("WiFi-Send-Connect\n");
  166. if (connect(sock, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) {
  167. LOG_vPrintf("WiFi-Send-Fail\n");
  168. close(sock);
  169. return false;
  170. }
  171. LOG_vPrintf("WiFi-Send-Send\n");
  172. if (send(sock, pchServerText, strlen(pchServerText), MSG_CONFIRM) == -1) {
  173. LOG_vPrintf("WiFi-Send-NoConfirmation\n");
  174. close(sock);
  175. return false;
  176. }
  177. LOG_vPrintf("WiFi-Send-Close\n");
  178. close(sock);
  179. return true;
  180. }
  181. //--Messages Module
  182. #define PAYLOAD_SIZE 256
  183. #define PAYLOAD_DELIMITER '_'
  184. #define MESSAGES_SIZE 2000
  185. typedef struct tMessage {
  186. uint32_t u32Sender;
  187. uint32_t u32Receiver;
  188. uint64_t u64Timestamp;
  189. char pchMessage[PAYLOAD_SIZE];
  190. bool bDone;
  191. uint32_t* pu32Sent;
  192. uint32_t u32Sent;
  193. } sMessage;
  194. typedef struct tMessages {
  195. uint32_t u32Owner;
  196. sMessage psArray[MESSAGES_SIZE];
  197. uint16_t u16ArrayIndex;
  198. bool bFull;
  199. uint32_t u32CheckedMessages;
  200. uint32_t u32LoggedMessages;
  201. sem_t semAccess;
  202. } sMessages;
  203. void MSG_vSetup(sMessages* psMessages, uint32_t u32Owner) {
  204. sem_init(&psMessages->semAccess, 0, 1);
  205. psMessages->u32Owner = u32Owner;
  206. psMessages->u16ArrayIndex = 0;
  207. psMessages->bFull = false;
  208. psMessages->u32CheckedMessages = 0;
  209. psMessages->u32LoggedMessages = 0;
  210. }
  211. static inline sMessage* MSG_mGet(sMessages* psMessages, uint16_t u16Index) {
  212. //sem_wait(&semMessages);
  213. sMessage* temp;
  214. if (psMessages->bFull) {
  215. temp = &psMessages->psArray[(psMessages->u16ArrayIndex + u16Index) % MESSAGES_SIZE];
  216. } else
  217. temp = &psMessages->psArray[u16Index];
  218. //sem_post(&semMessages);
  219. return temp;
  220. }
  221. static inline uint16_t MSG_u16Length(sMessages* psMessages) {
  222. //sem_wait(&semMessages);
  223. uint16_t temp;
  224. if (psMessages->bFull)
  225. temp = MESSAGES_SIZE;
  226. else
  227. temp = psMessages->u16ArrayIndex;
  228. //sem_post(&semMessages);
  229. return temp;
  230. }
  231. void MSG_vInsert(sMessages* psMessages, sMessage* psMessage, bool bSent, uint32_t u32Device) {
  232. sem_wait(&psMessages->semAccess);
  233. psMessages->psArray[psMessages->u16ArrayIndex].u32Sender = psMessage->u32Sender;
  234. psMessages->psArray[psMessages->u16ArrayIndex].u32Receiver = psMessage->u32Receiver;
  235. psMessages->psArray[psMessages->u16ArrayIndex].u64Timestamp = psMessage->u64Timestamp;
  236. psMessages->psArray[psMessages->u16ArrayIndex].bDone = (psMessage->u32Receiver == psMessages->u32Owner);
  237. memcpy(psMessages->psArray[psMessages->u16ArrayIndex].pchMessage, psMessage->pchMessage, strlen(psMessage->pchMessage));
  238. if (bSent) {
  239. psMessages->psArray[psMessages->u16ArrayIndex].u32Sent = 1;
  240. psMessages->psArray[psMessages->u16ArrayIndex].pu32Sent = (uint32_t*)malloc(1 * sizeof(uint32_t));
  241. psMessages->psArray[psMessages->u16ArrayIndex].pu32Sent[0] = u32Device;
  242. }
  243. else
  244. psMessages->psArray[psMessages->u16ArrayIndex].u32Sent = 0;
  245. psMessages->u16ArrayIndex = (psMessages->u16ArrayIndex + 1) % MESSAGES_SIZE;
  246. if (psMessages->u16ArrayIndex == 0)
  247. psMessages->bFull = true;
  248. psMessages->u32LoggedMessages++;
  249. sem_post(&psMessages->semAccess);
  250. }
  251. bool MSG_bCheck(sMessages* psMessages, sMessage* psMessage) {
  252. sem_wait(&psMessages->semAccess);
  253. uint16_t u16ArrayLength = MSG_u16Length(psMessages);
  254. bool flag = false;
  255. for (uint16_t i = 0; i < u16ArrayLength; i++) {
  256. sMessage* temp = MSG_mGet(psMessages, i);
  257. if (temp->u32Sender != psMessage->u32Sender)
  258. continue;
  259. if (temp->u32Receiver != psMessage->u32Receiver)
  260. continue;
  261. if (temp->u64Timestamp != psMessage->u64Timestamp)
  262. continue;
  263. if (strcmp(temp->pchMessage, psMessage->pchMessage) != 0)
  264. continue;
  265. flag = true;
  266. break;
  267. }
  268. psMessages->u32CheckedMessages++;
  269. sem_post(&psMessages->semAccess);
  270. return flag;
  271. }
  272. bool MSG_bParse(sMessage* psMessage, char* pchBuffer) {
  273. char* pchArrays[4];
  274. bool bFlag = false;
  275. uint16_t i;
  276. char* s = pchBuffer;
  277. for (i = 0; s[i]; s[i] == PAYLOAD_DELIMITER ? i++ : *s++);
  278. if (i != 3)
  279. return false;
  280. char* pchRest = pchBuffer;
  281. for (uint8_t i = 0; i < 3; i++) {
  282. const char s[2] = { PAYLOAD_DELIMITER, '\0'};
  283. pchArrays[i] = strtok(pchRest, s);
  284. if (pchArrays[i] == NULL) {
  285. bFlag = true;
  286. break;
  287. } else {
  288. pchRest += strlen(pchRest) + 1;
  289. }
  290. }
  291. pchArrays[3] = pchRest;
  292. if (!bFlag) {
  293. psMessage->u32Sender = atoi(pchArrays[0]);
  294. psMessage->u32Receiver = atoi(pchArrays[1]);
  295. psMessage->u64Timestamp = atoi(pchArrays[2]);
  296. strcpy(psMessage->pchMessage, pchArrays[3]);
  297. }
  298. return (!bFlag);
  299. }
  300. void MSG_vExport(sMessages* psMessages) {
  301. sem_wait(&psMessages->semAccess);
  302. uint16_t u16ArrayLength = MSG_u16Length(psMessages);
  303. FILE* file = fopen("/tmp/messages.txt", "w");
  304. if (file == NULL) {
  305. sem_post(&psMessages->semAccess);
  306. return;
  307. }
  308. fprintf(file, "Checked:"FU32"\n", psMessages->u32CheckedMessages);
  309. fprintf(file, "Logged:"FU32"\n", psMessages->u32LoggedMessages);
  310. fprintf(file, "Index:"FU32"\n", psMessages->u16ArrayIndex);
  311. fprintf(file, "index:sender_receiver_timestamp_message:sent:done\n");
  312. for (uint16_t i = 0; i < u16ArrayLength; i++) {
  313. sMessage* temp = MSG_mGet(psMessages, i);
  314. fprintf(file, FU16":"FU32"_"FU32"_"FU64"_"FSTR":"FU32":"FU08"\n", i, temp->u32Sender, temp->u32Receiver, temp->u64Timestamp, temp->pchMessage, temp->u32Sent, (temp->bDone ? 1 : 0));
  315. }
  316. fclose(file);
  317. sem_post(&psMessages->semAccess);
  318. }
  319. void MSG_vSend(sMessages* psMessages, uint32_t u32Receiver, bool (*bSend)(char* pchBuffer)) {
  320. sem_wait(&psMessages->semAccess);
  321. uint16_t u16Length;
  322. if (psMessages->bFull)
  323. u16Length = MESSAGES_SIZE;
  324. else
  325. u16Length = psMessages->u16ArrayIndex;
  326. for (uint16_t i = 0; i < u16Length; i++) {
  327. sMessage* temp = MSG_mGet(psMessages, i);
  328. bool bFlag = false;
  329. if (temp->bDone)
  330. bFlag = true;
  331. else {
  332. for (uint32_t j = 0 ; j < temp->u32Sent; j++) {
  333. if (temp->pu32Sent[j] == u32Receiver) {
  334. bFlag = true;
  335. break;
  336. }
  337. }
  338. }
  339. if (bFlag)
  340. continue;
  341. else {
  342. LOG_vPrintf("Message-Send-"FU32"-Start\n", i);
  343. char pchBuffer[5 + 5 + 3 + 10 + 256];
  344. sprintf(pchBuffer, FU32"_"FU32"_"FU64"_"FSTR, temp->u32Sender, temp->u32Receiver, temp->u64Timestamp, temp->pchMessage);
  345. LOG_vPrintf("Message-Send-"FU32"-Send\n", i);
  346. if (bSend(pchBuffer)) {
  347. if (temp->u32Sent == 0)
  348. temp->pu32Sent = (uint32_t*)malloc(1 * sizeof(uint32_t));
  349. else
  350. temp->pu32Sent = (uint32_t*)realloc(temp->pu32Sent, (temp->u32Sent + 1) * sizeof(uint32_t));
  351. temp->pu32Sent[temp->u32Sent] = u32Receiver;
  352. temp->u32Sent++;
  353. temp->bDone = (temp->u32Receiver == u32Receiver);
  354. } else {
  355. LOG_vPrintf("Message-Send-"FU32"-Error\n", i);
  356. }
  357. LOG_vPrintf("Message-Send-"FU32"-Stop\n", i);
  358. }
  359. }
  360. sem_post(&psMessages->semAccess);
  361. }
  362. sMessages sMessagesList;
  363. //--Devices Module
  364. #define DEVICES_SIZE 100
  365. typedef struct tDevice {
  366. uint32_t u32Id;
  367. bool bActive;
  368. uint64_t u64Start;
  369. uint64_t u64Last;
  370. } sDevice;
  371. typedef struct tDevices {
  372. sDevice psArray[DEVICES_SIZE];
  373. uint16_t u16ArrayIndex;
  374. bool bFull;
  375. sem_t semAccess;
  376. } sDevices;
  377. void DVC_vSetup(sDevices* psDevices) {
  378. sem_init(&psDevices->semAccess, 0, 1);
  379. psDevices->u16ArrayIndex = 0;
  380. psDevices->bFull = false;
  381. }
  382. void DVC_vInsert(sDevices* psDevices, uint16_t u32Id) {
  383. //sem_wait(&semDevices);
  384. psDevices->psArray[psDevices->u16ArrayIndex].u32Id = u32Id;
  385. psDevices->psArray[psDevices->u16ArrayIndex].bActive = true;
  386. psDevices->psArray[psDevices->u16ArrayIndex].u64Start = TIME_u64Current();
  387. psDevices->psArray[psDevices->u16ArrayIndex].u64Last = 0;
  388. psDevices->u16ArrayIndex = (psDevices->u16ArrayIndex + 1) % DEVICES_SIZE;
  389. if (psDevices->u16ArrayIndex == 0)
  390. psDevices->bFull = true;
  391. //sem_post(&semDevices);
  392. }
  393. uint16_t DVC_u16Update(sDevices* psDevices, uint32_t* pu32Id, uint16_t u16IdSize, uint32_t* pu32New) {
  394. sem_wait(&psDevices->semAccess);
  395. uint16_t u16ArrayLength;
  396. if (psDevices->bFull)
  397. u16ArrayLength = DEVICES_SIZE;
  398. else
  399. u16ArrayLength = psDevices->u16ArrayIndex;
  400. bool pbFlag[u16IdSize];
  401. for (uint16_t j = 0; j < u16IdSize; j++) {
  402. pbFlag[j] = false;
  403. }
  404. for (uint16_t i = 0; i < u16ArrayLength; i++) {
  405. bool bFlag = false;
  406. for (uint16_t j = 0; j < u16IdSize; j++) {
  407. if (psDevices->psArray[i].u32Id == pu32Id[j]) {
  408. bFlag = true;
  409. pbFlag[j] = true;
  410. break;
  411. }
  412. }
  413. if (bFlag) {
  414. if (psDevices->psArray[i].bActive)
  415. psDevices->psArray[i].u64Last = TIME_u64Current();
  416. else {
  417. psDevices->psArray[i].bActive = true;
  418. psDevices->psArray[i].u64Start = TIME_u64Current();
  419. psDevices->psArray[i].u64Last = 0;
  420. }
  421. } else {
  422. psDevices->psArray[i].bActive = false;
  423. }
  424. }
  425. uint16_t u16Cnt = 0;
  426. for (uint16_t j = 0; j < u16IdSize; j++) {
  427. if (!pbFlag[j]) {
  428. DVC_vInsert(psDevices, pu32Id[j]);
  429. pu32New[u16Cnt] = pu32Id[j];
  430. u16Cnt++;
  431. }
  432. }
  433. sem_post(&psDevices->semAccess);
  434. return u16Cnt;
  435. }
  436. void DVC_vExport(sDevices* psDevices) {
  437. sem_wait(&psDevices->semAccess);
  438. uint16_t u16ArrayLength;
  439. if (psDevices->bFull)
  440. u16ArrayLength = DEVICES_SIZE;
  441. else
  442. u16ArrayLength = psDevices->u16ArrayIndex;
  443. FILE* file = fopen("/tmp/devices.txt", "w");
  444. if (file == NULL) {
  445. sem_post(&psDevices->semAccess);
  446. return;
  447. }
  448. fprintf(file, FU32"\n", psDevices->u16ArrayIndex);
  449. fprintf(file, "index:active,id,start,stop\n");
  450. for (uint16_t i = 0; i < u16ArrayLength; i++)
  451. fprintf(file, FU32":"FSTR","FU32","FU64","FU64"\n", i, psDevices->psArray[i].bActive ? "true" : "false", psDevices->psArray[i].u32Id, psDevices->psArray[i].u64Start, psDevices->psArray[i].u64Last);
  452. fclose(file);
  453. sem_post(&psDevices->semAccess);
  454. }
  455. sDevices sDevicesList;
  456. //--Timer Module
  457. #include <signal.h>
  458. #include <sys/time.h>
  459. typedef struct tInterrupt {
  460. bool bRunning;
  461. uint32_t u32Ticks;
  462. void (*vCallback)(uint32_t);
  463. } sInterrupt;
  464. sInterrupt sTimer;
  465. void TMR_vHandler(int sig) {
  466. static uint32_t i = 0;
  467. sTimer.vCallback(i - 1);
  468. i++;
  469. if (sTimer.u32Ticks > 0 && i >= sTimer.u32Ticks) {
  470. struct itimerval sInterval = {0};
  471. setitimer(ITIMER_REAL, &sInterval, NULL);
  472. sTimer.bRunning = false;
  473. }
  474. }
  475. bool TMR_bSetup(suseconds_t susInterval, void (*vCallback)(uint32_t)) {
  476. sTimer.vCallback = vCallback;
  477. sTimer.u32Ticks = 0;
  478. sTimer.bRunning = true;
  479. signal(SIGALRM, TMR_vHandler);
  480. struct itimerval sInterval;
  481. sInterval.it_interval.tv_usec = susInterval % 1000000;
  482. sInterval.it_interval.tv_sec = susInterval / 1000000;
  483. sInterval.it_value = sInterval.it_interval;
  484. if (setitimer(ITIMER_REAL, &sInterval, NULL) != 0)
  485. return false;
  486. return true;
  487. }
  488. //--High Level Application
  489. #include <stdio.h>
  490. #include <stdlib.h>
  491. #include <pthread.h>
  492. #define AEM 8844
  493. #define SERVER_PORT 2288
  494. #define INTERRUPTS
  495. #ifdef INTERRUPTS
  496. sem_t semSearcher;
  497. #endif
  498. const uint32_t pu32FriendsList[] = {7000, 7001, 7002, 7003, 8845};
  499. const uint8_t u08FriendsSize = 5;
  500. #define CREATE_PERIOD_MIN 1 //secs
  501. #define CREATE_PERIOD_MAX 1 //secs
  502. //#define CREATE_PERIOD_MIN 1*60 //secs
  503. //#define CREATE_PERIOD_MAX 5*60 //secs
  504. uint32_t u32Selector(void) {
  505. static uint32_t count = 0;
  506. count++;
  507. uint8_t index = RAND_u16GetNumber(0, u08FriendsSize - 1);
  508. sMessage temp;
  509. temp.u32Sender = AEM;
  510. temp.u32Receiver = pu32FriendsList[index];
  511. temp.u64Timestamp = TIME_u64Current();
  512. sprintf(temp.pchMessage, "I am message #%d of GKyri", count);
  513. temp.u32Sent = 0;
  514. LOG_vPrintf("Selector-Insert\n");
  515. MSG_vInsert(&sMessagesList, &temp, false, 0);
  516. /*
  517. LOG_vPrintf("Selector-Export\n");
  518. MSG_vExport(&sMessagesList);
  519. */
  520. return pu32FriendsList[index];
  521. }
  522. void APP_vCallback(uint32_t u32Tick) {
  523. static bool bRunning = false;
  524. if (!bRunning) {
  525. bRunning = true;
  526. LOG_vPrintf("Callback-Start\n");
  527. u32Selector();
  528. LOG_vPrintf("Callback-Stop\n");
  529. #ifdef INTERRUPTS
  530. sem_post(&semSearcher);
  531. #endif
  532. bRunning = false;
  533. }
  534. }
  535. void APP_vCreator(void) {
  536. uint16_t u16Interval = RAND_u16GetNumber(CREATE_PERIOD_MIN, CREATE_PERIOD_MAX);
  537. if (TMR_bSetup(500000, APP_vCallback)) {
  538. //if (TMR_bSetup(u16Interval * 1000000, APP_vCallback)) {
  539. while (true)
  540. pause();
  541. }
  542. }
  543. bool APP_bReceiveBuffer(uint8_t* pu08Address, char* pchBuffer) {
  544. LOG_vPrintf("Receiver-Start\n");
  545. uint32_t u32Id = (uint32_t)pu08Address[2] * 100 + pu08Address[3];
  546. sMessage temp;
  547. if (!MSG_bParse(&temp, pchBuffer))
  548. return false;
  549. temp.u32Sent = 0;
  550. if (!MSG_bCheck(&sMessagesList, &temp)) {
  551. LOG_vPrintf("Receiver-Insert\n");
  552. MSG_vInsert(&sMessagesList, &temp, true, u32Id);
  553. /*
  554. LOG_vPrintf("Receiver-Export\n");
  555. MSG_vExport(&sMessagesList);
  556. */
  557. }
  558. LOG_vPrintf("Receiver-Stop\n");
  559. #ifdef INTERRUPTS
  560. sem_post(&semSearcher);
  561. #endif
  562. return true;
  563. }
  564. void APP_vListener(void) {
  565. WiFi_bListener(SERVER_PORT, APP_bReceiveBuffer);
  566. }
  567. char pchMessageReceiver[15 + 1];
  568. bool APP_bSendBuffer(char* pchBuffer) {
  569. return WiFi_bSend(pchMessageReceiver, SERVER_PORT, pchBuffer);
  570. }
  571. bool APP_bSender(uint32_t u32Receiver) {
  572. sprintf(pchMessageReceiver, "10.0."FU08"."FU08, u32Receiver / 100, u32Receiver % 100);
  573. char pchTest[13 + 15 + 12 + 1];
  574. sprintf(pchTest, "ping -c1 -w1 "FSTR" > /dev/null", pchMessageReceiver);
  575. if (system(pchTest) == 0) {
  576. MSG_vSend(&sMessagesList, u32Receiver, APP_bSendBuffer);
  577. return true;
  578. } else {
  579. return false;
  580. }
  581. }
  582. #define SEARCHER_SLEEP_PERIOD 60 //secs
  583. #define SEARCHER_SLEEP_DELAY 30 //secs
  584. void APP_vSearcher(void) {
  585. #ifdef INTERRUPTS
  586. sem_init(&semSearcher, 0, 0);
  587. #endif
  588. sleep(SEARCHER_SLEEP_PERIOD);
  589. while (true) {
  590. LOG_vPrintf("Searcher-Start\n");
  591. uint16_t u16Cnt = 0;
  592. uint32_t* pu32Id = (uint32_t*)malloc(1 * sizeof(uint32_t));
  593. for (uint8_t i = 0; i < u08FriendsSize; i++) {
  594. uint32_t u32Receiver = pu32FriendsList[i];
  595. sprintf(pchMessageReceiver, "10.0."FU08"."FU08, u32Receiver / 100, u32Receiver % 100);
  596. char pchTest[13 + 15 + 12 + 1];
  597. sprintf(pchTest, "ping -c1 -w1 "FSTR" > /dev/null", pchMessageReceiver);
  598. if (system(pchTest) == 0) {
  599. pu32Id[u16Cnt] = u32Receiver;
  600. u16Cnt++;
  601. pu32Id = (uint32_t*)realloc(pu32Id, (u16Cnt + 1) * sizeof(uint32_t));
  602. }
  603. }
  604. LOG_vPrintf("Searcher-Send-Start\n");
  605. uint32_t pu32New[u16Cnt];
  606. //uint16_t u16NewLength = DVC_u16Update(&sDevicesList, pu32Id, u16Cnt, pu32New);
  607. DVC_u16Update(&sDevicesList, pu32Id, u16Cnt, pu32New);
  608. for (uint16_t i = 0; i < u16Cnt; i++) {
  609. LOG_vPrintf("Searcher-Send-"FU32"-Start\n", i);
  610. APP_bSender(pu32Id[i]);
  611. LOG_vPrintf("Searcher-Send-"FU32"-Stop\n", i);
  612. }
  613. free(pu32Id);
  614. LOG_vPrintf("Searcher-Send-Stop\n");
  615. LOG_vPrintf("Searcher-Export\n");
  616. DVC_vExport(&sDevicesList);
  617. MSG_vExport(&sMessagesList);
  618. LOG_vPrintf("Searcher-Stop\n");
  619. #ifdef INTERRUPTS
  620. for (uint16_t i = 0; i < SEARCHER_SLEEP_PERIOD; i++) {
  621. int value;
  622. sem_getvalue(&semSearcher, &value);
  623. if (value > 0) {
  624. if (i > SEARCHER_SLEEP_DELAY) {
  625. LOG_vPrintf("Searcher-Interrupt\n");
  626. sem_wait(&semSearcher);
  627. break;
  628. }
  629. }
  630. sleep(1);
  631. }
  632. #else
  633. sleep(SLEEP_PERIOD);
  634. #endif
  635. }
  636. }
  637. void APP_vSetup(void){
  638. int8_t i08Result;
  639. bool bFlag = false;
  640. i08Result = FILE_i08Compare("/root/wpa_supplicant.conf", "/etc/wpa_supplicant/wpa_supplicant.conf");
  641. if (i08Result == 0 || i08Result == 2) {
  642. bFlag = true;
  643. LOG_vPrintf("Replacing 'wpa_supplicant'\n");
  644. system("sudo cp /root/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf");
  645. }
  646. i08Result = FILE_i08Compare("/root/interfaces", "/etc/network/interfaces");
  647. if (i08Result == 0 || i08Result == 2) {
  648. bFlag = true;
  649. LOG_vPrintf("Replacing 'interfaces'\n");
  650. system("sudo cp /root/interfaces /etc/network/interfaces");
  651. }
  652. i08Result = FILE_i08Compare("/root/messenger.service", "/etc/systemd/system/messenger.service");
  653. if (i08Result == 0 || i08Result == 2) {
  654. bFlag = true;
  655. LOG_vPrintf("Replacing 'messenger.service'\n");
  656. system("sudo cp /root/messenger.service /etc/systemd/system");
  657. system("systemctl enable messenger");
  658. }
  659. if (bFlag) {
  660. LOG_vPrintf("Restarting\n");
  661. system("shutdown -r 0");
  662. exit(EXIT_SUCCESS);
  663. }
  664. }
  665. void* Th1Func(void* ptr) {
  666. APP_vListener();
  667. return NULL;
  668. }
  669. void* Th2Func(void* ptr) {
  670. APP_vCreator();
  671. return NULL;
  672. }
  673. void* Th3Func(void* ptr) {
  674. APP_vSearcher();
  675. return NULL;
  676. }
  677. int main( int argc, char* const* argv) {
  678. APP_vSetup();
  679. LOG_vSetup();
  680. MSG_vSetup(&sMessagesList, AEM);
  681. DVC_vSetup(&sDevicesList);
  682. pthread_t thread1, thread2, thread3;
  683. pthread_create( &thread1, NULL, Th1Func, NULL);
  684. pthread_create( &thread2, NULL, Th2Func, NULL);
  685. pthread_create( &thread3, NULL, Th3Func, NULL);
  686. pthread_join( thread1, NULL);
  687. pthread_join( thread2, NULL);
  688. pthread_join( thread3, NULL);
  689. return EXIT_SUCCESS;
  690. }