Mikhail Zaytsev 1 yıl önce
işleme
c74f791be5
7 değiştirilmiş dosya ile 308 ekleme ve 0 silme
  1. 31 0
      .vscode/launch.json
  2. 28 0
      .vscode/tasks.json
  3. BIN
      client
  4. 249 0
      client.c
  5. 0 0
      command.c
  6. 0 0
      command.h
  7. 0 0
      main.h

+ 31 - 0
.vscode/launch.json

@@ -0,0 +1,31 @@
+{
+    "configurations": [
+        {
+            "name": "C/C++: gcc-11 build and debug active file",
+            "type": "cppdbg",
+            "request": "launch",
+            "program": "${fileDirname}/${fileBasenameNoExtension}",
+            "args": ["127.0.0.1"],
+            "stopAtEntry": false,
+            "cwd": "${fileDirname}",
+            "environment": [],
+            "externalConsole": false,
+            "MIMode": "gdb",
+            "setupCommands": [
+                {
+                    "description": "Enable pretty-printing for gdb",
+                    "text": "-enable-pretty-printing",
+                    "ignoreFailures": true
+                },
+                {
+                    "description": "Set Disassembly Flavor to Intel",
+                    "text": "-gdb-set disassembly-flavor intel",
+                    "ignoreFailures": true
+                }
+            ],
+            "preLaunchTask": "C/C++: gcc-11 build active file",
+            "miDebuggerPath": "/usr/bin/gdb"
+        }
+    ],
+    "version": "2.0.0"
+}

+ 28 - 0
.vscode/tasks.json

@@ -0,0 +1,28 @@
+{
+    "tasks": [
+        {
+            "type": "cppbuild",
+            "label": "C/C++: gcc-11 build active file",
+            "command": "/usr/bin/gcc-11",
+            "args": [
+                "-fdiagnostics-color=always",
+                "-g",
+                "${file}",
+                "-o",
+                "${fileDirname}/${fileBasenameNoExtension}"
+            ],
+            "options": {
+                "cwd": "${fileDirname}"
+            },
+            "problemMatcher": [
+                "$gcc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "detail": "Task generated by Debugger."
+        }
+    ],
+    "version": "2.0.0"
+}


+ 249 - 0
client.c

@@ -0,0 +1,249 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <arpa/inet.h> 
+#include <inttypes.h>
+#include <signal.h>
+
+volatile int sockfd = 0;
+
+typedef void (*CommandHandler)(char*);
+
+// Определяем тип функции преобразования
+typedef void (*ConvertFunc)(char *str, void *output);
+
+void handleCloseSignal(int signal);
+void handleFreqCmd(char* recvBuff);
+void handleLdCmd(char* recvBuff);
+void handlePowCmd(char* recvBuff);
+void handleArmCmd(char* recvBuff);
+void handleAttCmd(char* recvBuff);
+void handleIdnCmd(char* recvBuff);
+void processCommand(char* recvBuff);
+void convertToUInt16(char *str, void *output);
+void convertToUint64(char *str, void *output);
+void convertToDouble(char *str, void *output);
+void splitLexeme(uint8_t *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc);
+
+//Обработчик ошибок
+void error(const char *msg)
+{
+	perror(msg);
+
+	if (sockfd != 0) 
+	{
+		close(sockfd);
+	}
+
+	exit(1);
+} 
+
+//Обработчик сигнала SIGINT завершения программы при нажатии Ctrl+C
+void handleCloseSignal(int signal)
+{
+	if (signal == SIGINT) 
+	{
+		printf("\nCaught signal %d, closing socket and exiting...\n", signal);
+		if (sockfd != 0) 
+		{
+			close(sockfd);
+		}
+		exit(0);
+	}
+}
+
+//handleXXXXCmd - обработчики команд
+void handleFreqCmd(char* recvBuff)
+{
+	printf("\nTMSG44:FREQ\n");
+	uint64_t freq[1] = {0};
+
+	splitLexeme(recvBuff, freq, sizeof(freq[0]), convertToUint64);
+
+	printf("%" PRId64 "\n", freq[0]);
+}
+
+void handleLdCmd(char* recvBuff)
+{
+	printf("\nTMSG44:LD?\n");
+}
+
+void handlePowCmd(char* recvBuff)
+{
+	printf("\nTMSG44:POW\n");
+	double pow[1] = {0};
+
+	splitLexeme(recvBuff, pow, sizeof(pow[0]), convertToDouble);
+	printf("%f\n", pow[0]);
+}
+
+void handleArmCmd(char* recvBuff)
+{
+	printf("\nTMSG44:ARM\n");
+	uint16_t armCode[1] = {0};
+
+	splitLexeme(recvBuff, armCode, sizeof(armCode[0]), convertToUInt16);
+	printf("\n%u\n", armCode[0]);
+}
+
+void handleAttCmd(char* recvBuff)
+{
+	printf("\nTMSG44:ATT\n");
+	uint16_t attCode[1] = {0};
+
+	splitLexeme(recvBuff, attCode, sizeof(attCode[0]), convertToUInt16);
+	printf("\n%u\n", attCode[0]);
+}
+
+void handleIdnCmd(char* recvBuff)
+{
+	printf("\n*IDN?\n");
+}
+
+typedef struct {
+	const char* command;
+	CommandHandler handler;
+} Command;
+
+//Массив структур Command, который связывает строки команд с соответствующими функциями.
+Command commands[] = {
+	{"TMSG44:FREQ ", 	handleFreqCmd},
+	{"TMSG44:LD?", 		handleLdCmd},
+	{"TMSG44:POW ", 	handlePowCmd},
+	{"TMSG44:ARM ", 	handleArmCmd},
+	{"TMSG44:ATT ", 	handleAttCmd},
+	{"*IDN?", 			handleIdnCmd},
+	{NULL, NULL} // Завершающий элемент для обозначения конца массива
+};
+
+//Проходим по массиву команд и ищем команду, которая совпадает с началом строки recvBuff. 
+//Если команда найдена, вызывается соответствующая функция-обработчик
+void processCommand(char* recvBuff) 
+{
+	for (int i = 0; commands[i].command != NULL; i++) 
+	{
+		if (!strncasecmp(recvBuff, commands[i].command, strlen(commands[i].command))) 
+		{
+			commands[i].handler(recvBuff);
+			return;
+		}
+	}
+	printf("\nUnknown command: %s\n", recvBuff);
+}
+
+//=========================================================//
+
+// Преобразование строки в uint16_t
+void convertToUInt16(char *str, void *output) 
+{
+	*(uint16_t *)output = (uint16_t)strtoul(str, NULL, 10);
+}
+
+// Преобразование строки в unsigned long long int
+void convertToUint64(char *str, void *output) 
+{
+	*(uint64_t *)output = (uint64_t)strtoull(str, NULL, 10);
+}
+
+// Преобразование строки в double
+void convertToDouble(char *str, void *output) 
+{
+	*(double *)output = strtod(str, NULL);
+}
+
+// Универсальная функция для разделения строки на лексемы
+void splitLexeme(uint8_t *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc) 
+{
+	uint8_t counter = 0;
+
+	// Разделители лексем
+	char charSeparator[3] = {' ', '\n', '\\'};
+	char *ptrLexeme = NULL;
+
+	// Инициализируем функцию
+	ptrLexeme = strtok((char *)ptrSCPI, charSeparator);
+
+	// Ищем лексемы разделенные разделителем
+	ptrLexeme = strtok(NULL, charSeparator);
+
+	// Ищем лексемы строки
+	while (ptrLexeme) {
+		// Проверяем, является ли первый символ лексемы числом
+		if(('0' <= ptrLexeme[0]) && (ptrLexeme[0] <= '9')) {
+			// Преобразуем строку с числом в число
+			convertFunc(ptrLexeme, (uint8_t *)numOutAndValue + counter * elementSize);
+			counter++;
+		}
+		// Ищем лексемы разделенные разделителем
+		ptrLexeme = strtok(NULL, charSeparator);
+	}
+}
+//====================================================//
+
+int main(int argc, char *argv[])
+{
+	//argv[1] = "127.0.0.1";
+	int n = 0;
+	char recvBuff[1024];
+	struct sockaddr_in serv_addr;
+
+	// Установка обработчика сигналов
+	signal(SIGINT, handleCloseSignal);
+
+	if(argc != 2)
+	{
+		printf("\n Usage: %s <ip of server> \n",argv[0]);
+		return 1;
+	} 
+
+	memset(recvBuff, '0',sizeof(recvBuff));
+	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+	{
+		error("Error : Could not create socket");
+	} 
+
+	memset(&serv_addr, '0', sizeof(serv_addr)); 
+
+	serv_addr.sin_family = AF_INET;
+	serv_addr.sin_port = htons(5000); 
+
+	if (inet_pton(AF_INET, argv[1], &serv_addr.sin_addr) <= 0)
+	{
+		error("inet_pton error occured");
+	} 
+
+	if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
+	{
+	   error("Error : Connect Failed");
+	}
+
+	while ((n = read(sockfd, recvBuff, sizeof(recvBuff) - 1)) > 0)
+	{
+		recvBuff[n] = 0;
+		if(fputs(recvBuff, stdout) == EOF)
+		{
+			printf("\n Error : Fputs error\n");
+			break;
+		}
+		//Запуск парсера команд
+		processCommand(recvBuff);
+	} 
+
+	if (n == 0)
+	{
+		// Соединение закрыто сервером
+		printf("\n Server closed the connection\n");
+	}
+	else if (n < 0)
+	{
+		error("Read error");
+	} 
+
+	close(sockfd);
+	return 0;
+}

+ 0 - 0
command.c


+ 0 - 0
command.h


+ 0 - 0
main.h