SerialUnix.cpp 2.59 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "SerialUnix.h"

Serial::Serial()
{
	_isConnected = false;
	_port = "";
	_ready = true;
	_cur_command = "";
}

void Serial::init()
{
	startConnection("/dev/ttyACM0");

	usleep(500000);
}

int Serial::startConnection(const char* port)
{
	printf("Attempting to connect to Serial port %s...\n", port);

	_port = "";
	_isConnected = false;

	tio.c_iflag = 0;
	tio.c_oflag = 0;
	tio.c_cflag = CS8 | CREAD | CLOCAL;
	tio.c_lflag = 0;
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 5;

	tty_fd = open(port, O_RDWR | O_NONBLOCK | O_SYNC);
	if (tty_fd < 0) {
		printf("%sError opening port: %s\n", K_ERROR, strerror(errno));
		return -1;
	}

	cfsetospeed(&tio, SERIAL_BAUD_RATE);
	cfsetispeed(&tio, SERIAL_BAUD_RATE);

	if (tcsetattr(tty_fd, TCSANOW, &tio) != 0)
	{
		printf("%sError from tcsetattr: %s\n", K_ERROR, strerror(errno));
		return -1;
	}

	_port = port;
	_ready = true;
	_isConnected = true;

	printf("%sConnected\n", K_WARNING);
	printf("%s", K_NORMAL);

	return 1;
}

void Serial::closeConnection()
{
	if (_port != "" && _isConnected)
		close(tty_fd); // Port release 
}

bool Serial::isConnected(const char* port)
{
	if (port != "")
		return (_isConnected && _port == port);
	return _isConnected;
}

std::string Serial::readSerial()
{
	if (_commands.empty())
		return "";

	std::string ret = _commands.front();
	_commands.erase(_commands.begin());

	return ret;
}

void Serial::writeSerial(const char* buffer)
{
	if(!_isConnected)
		return;

	printf("Sending packet\n");
	for (unsigned int i = 0; i < strlen(buffer); i++)
	{
		write(tty_fd, &buffer[i], 1);
	}

	bool timeout = true;
	_ready = false;
	timer = std::clock();
	while (!_ready && timeout) {
		timeout = (std::clock() - timer) / ((double)CLOCKS_PER_SEC / 1000) < SERIAL_FLAG_TIMEOUT;
		manageSerial();
	}
	if (!timeout) printf("%s---- BASE STATION ACK TIMEOUT ----\n", K_ERROR); //We got a timeout
}

int Serial::manageSerial()
{
	if(!_isConnected)
		return 0;

	int bytes = 0;
	ioctl(tty_fd, FIONREAD, &bytes);

	//go through all bytes (read them separately)
	if (bytes) { //There are bytes on the buffer
		char value;
		for (unsigned int i = 0; i < bytes; i++)
		{
			if (read(tty_fd, &value, 1) > 0) {
				//Append character to current command
				_cur_command.push_back(value);

				//End of command -> push
				if (value == SERIAL_COMMAND_END || _cur_command.size() >= MAX_SERIAL_BUFFER_SIZE) {
					//check if it is the ready flag
					if (_cur_command == SERIAL_READY_FLAG)
						_ready = true;
					else
						_commands.push_back(_cur_command);

					_cur_command = "";
				}
			}
			else {
				printf("%sFailed to read\n", K_ERROR);
				return 0;
			}
		}
	}

	return 1;
}