command.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "command.h"
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <inttypes.h>
  5. #include <stdio.h>
  6. #include <strings.h>
  7. #include <string.h>
  8. #include <sys/socket.h>
  9. #include <unistd.h>
  10. #include <time.h>
  11. #include "Devices/lmx2594.h"
  12. //Массив структур Command, который связывает строки команд с соответствующими функциями.
  13. Command commands[] = {
  14. {"TMSG44:FREQ ", handleFreqCmd},
  15. {"TMSG44:LD?", handleLdCmd},
  16. {"TMSG44:POW ", handlePowCmd},
  17. {"TMSG44:ARM ", handleArmCmd},
  18. {"TMSG44:ATT ", handleAttCmd},
  19. {"*IDN?", handleIdnCmd},
  20. {NULL, NULL} // Завершающий элемент для обозначения конца массива
  21. };
  22. //handleXXXXCmd - обработчики команд
  23. void handleFreqCmd(const char* recvBuff)
  24. {
  25. printf("\nTMSG44:FREQ\n");
  26. double freq[1] = {0};
  27. splitLexeme(recvBuff, freq, sizeof(freq[0]), convertToDouble);
  28. printf("%f\n", freq[0]);
  29. lmx_freq_set(bar1, freq[0]);
  30. printf("The frequency is set to %f Hz\n", freq[0]);
  31. }
  32. void handleLdCmd(const char* recvBuff)
  33. {
  34. int n = 0;
  35. char messageLd[] = "1\n";
  36. printf("\nTMSG44:LD?\n");
  37. uint32_t ld_status = lmx_ld_status(bar1);
  38. printf("LD status: %d\n", ld_status);
  39. clock_t before = clock();
  40. clock_t difference;
  41. int difference_msec = 0;
  42. int trigger = 10; //10ms
  43. while(!ld_status)
  44. {
  45. difference = clock() - before;
  46. difference_msec = difference * 1000 / CLOCKS_PER_SEC;
  47. if(difference_msec >= trigger)
  48. {
  49. strcpy(messageLd, "0\n");
  50. printf("LD timeout\n");
  51. break;
  52. }
  53. usleep(1000);
  54. uint32_t ld_status = lmx_ld_status(bar1);
  55. }
  56. send(conn_fd, messageLd, sizeof(messageLd), 0);
  57. printf("\nSend msg LD!\n");
  58. }
  59. void handlePowCmd(const char* recvBuff)
  60. {
  61. printf("\nTMSG44:POW\n");
  62. double pow[1] = {0};
  63. splitLexeme(recvBuff, pow, sizeof(pow[0]), convertToDouble);
  64. printf("%f\n", pow[0]);
  65. }
  66. void handleArmCmd(const char* recvBuff)
  67. {
  68. printf("\nTMSG44:ARM\n");
  69. uint16_t armCode[1] = {0};
  70. splitLexeme(recvBuff, armCode, sizeof(armCode[0]), convertToUInt16);
  71. printf("\n%u\n", armCode[0]);
  72. }
  73. void handleAttCmd(const char* recvBuff)
  74. {
  75. printf("\nTMSG44:ATT\n");
  76. uint16_t attCode[1] = {0};
  77. splitLexeme(recvBuff, attCode, sizeof(attCode[0]), convertToUInt16);
  78. printf("\n%u\n", attCode[0]);
  79. }
  80. void handleIdnCmd(const char* recvBuff)
  81. {
  82. ssize_t n;
  83. printf("\n*IDN?\n");
  84. char messageIdn[] = "TMSG44_CoolPi\n";
  85. n = send(conn_fd, messageIdn, sizeof(messageIdn), 0);
  86. printf("%ld \n", n);
  87. }
  88. //Проходим по массиву команд и ищем команду, которая совпадает с началом строки recvBuff.
  89. //Если команда найдена, вызывается соответствующая функция-обработчик
  90. void processCommand(const char* recvBuff)
  91. {
  92. for (int i = 0; commands[i].command != NULL; i++)
  93. {
  94. if (!strncasecmp(recvBuff, commands[i].command, strlen(commands[i].command)))
  95. {
  96. commands[i].handler(recvBuff);
  97. return;
  98. }
  99. }
  100. printf("\nUnknown command: %s\n", recvBuff);
  101. }
  102. // Преобразование строки в uint16_t
  103. void convertToUInt16(const char *str, void *output)
  104. {
  105. *(uint16_t *)output = (uint16_t)strtoul(str, NULL, 10);
  106. }
  107. // Преобразование строки в unsigned long long int
  108. void convertToUint64(const char *str, void *output)
  109. {
  110. *(uint64_t *)output = (uint64_t)strtoull(str, NULL, 10);
  111. }
  112. // Преобразование строки в double
  113. void convertToDouble(const char *str, void *output)
  114. {
  115. *(double *)output = strtod(str, NULL);
  116. }
  117. // Универсальная функция для разделения строки на лексемы
  118. void splitLexeme(const char *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc)
  119. {
  120. uint8_t counter = 0;
  121. // Разделители лексем
  122. const char charSeparator[] = {" "};
  123. char *ptrLexeme = NULL;
  124. // Указатель для хранения контекста токенизации
  125. char *savePtr;
  126. // Инициализируем функцию
  127. ptrLexeme = strtok_r((char *)ptrSCPI, charSeparator, &savePtr);
  128. // Ищем лексемы разделенные разделителем
  129. ptrLexeme = strtok_r(NULL, charSeparator, &savePtr);
  130. // Ищем лексемы строки
  131. while (ptrLexeme) {
  132. // Проверяем, является ли первый символ лексемы числом
  133. if(('0' <= ptrLexeme[0]) && (ptrLexeme[0] <= '9')) {
  134. // Преобразуем строку с числом в число
  135. convertFunc(ptrLexeme, (uint8_t *)numOutAndValue + counter * elementSize);
  136. counter++;
  137. }
  138. // Ищем лексемы разделенные разделителем
  139. ptrLexeme = strtok_r(NULL, charSeparator, &savePtr);
  140. }
  141. }