command.c 3.6 KB

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