A messenger application for Raspberry Pi Zerofor A.U.TH (Real time Embedded systems).
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

807 lignes
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. }