command.c 4.1 KB

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