| /****************************************************************************** |
| * Copyright (c) 2017 Ericsson AB |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html |
| * |
| * Contributors: |
| * Lenard Nagy |
| * version R1A |
| ******************************************************************************/ |
| |
| #include "SerialPort.hh" |
| |
| namespace SerialPortTypes { |
| |
| SerialPort::SerialPort(const char *par_port_name) |
| : SerialPort_BASE(par_port_name) |
| { |
| //Set default values |
| speed = B9600; //9600 baud |
| blocking = 1; //set blocking |
| dataBits = CS8; //8 data bits |
| stopBit = ~CSTOPB; //1 stop bit |
| parity = 0; //parity: none |
| } |
| |
| SerialPort::~SerialPort() |
| { |
| |
| } |
| |
| void SerialPort::set_parameter(const char * parameter_name, |
| const char * parameter_value) |
| { |
| if (strcmp(parameter_name, "deviceFileName") == 0) { |
| param_device_file = (char*) malloc(strlen(parameter_value)); |
| strcpy(param_device_file, parameter_value); |
| //printf("Parameter %s set to %s\n", parameter_name, param_device_file); |
| } else if (strcmp(parameter_name, "deviceSpeed") == 0) { |
| if (strcmp(parameter_value, "B0") == 0) { |
| speed = B0; |
| } else if (strcmp(parameter_value, "B50") == 0) { |
| speed = B50; |
| } else if (strcmp(parameter_value, "B75") == 0) { |
| speed = B75; |
| } else if (strcmp(parameter_value, "B75") == 0) { |
| speed = B75; |
| } else if (strcmp(parameter_value, "B110") == 0) { |
| speed = B110; |
| } else if (strcmp(parameter_value, "B134") == 0) { |
| speed = B134; |
| } else if (strcmp(parameter_value, "B150") == 0) { |
| speed = B150; |
| } else if (strcmp(parameter_value, "B200") == 0) { |
| speed = B200; |
| } else if (strcmp(parameter_value, "B300") == 0) { |
| speed = B300; |
| } else if (strcmp(parameter_value, "B600") == 0) { |
| speed = B600; |
| } else if (strcmp(parameter_value, "B1200") == 0) { |
| speed = B1200; |
| } else if (strcmp(parameter_value, "B1800") == 0) { |
| speed = B1800; |
| } else if (strcmp(parameter_value, "B2400") == 0) { |
| speed = B2400; |
| } else if (strcmp(parameter_value, "B4800") == 0) { |
| speed = B4800; |
| } else if (strcmp(parameter_value, "B9600") == 0) { |
| speed = B9600; |
| } else if (strcmp(parameter_value, "B19200") == 0) { |
| speed = B19200; |
| } else if (strcmp(parameter_value, "B38400") == 0) { |
| speed = B38400; |
| } else if (strcmp(parameter_value, "B57600") == 0) { |
| speed = B57600; |
| } else if (strcmp(parameter_value, "B115200") == 0) { |
| speed = B115200; |
| } else if (strcmp(parameter_value, "B230400") == 0) { |
| speed = B230400; |
| } else if (strcmp(parameter_value, "B460800") == 0) { |
| speed = B460800; |
| } else { |
| TTCN_error("Invalid %s value: %s\n", parameter_name, parameter_value); |
| } |
| //printf("Parameter %s set to %s (int: %u)\n", parameter_name, parameter_value, speed); |
| } else if (strcmp(parameter_name, "deviceParity") == 0) { |
| if (strcmp(parameter_value, "none") == 0) { |
| parity = 0; |
| } else if (strcmp(parameter_value, "odd") == 0) { |
| parity = PARENB|PARODD; |
| } else if (strcmp(parameter_value, "even") == 0) { |
| parity = PARENB; |
| } else if (strcmp(parameter_value, "mark") == 0) { |
| parity = PARENB|PARODD|CMSPAR; |
| } else if (strcmp(parameter_value, "space") == 0) { |
| parity = PARENB|CMSPAR; |
| } else { |
| TTCN_error("Invalid %s value: %s\n", parameter_name, parameter_value); |
| } |
| |
| //printf("Parameter %s set to %s (int: %d)\n", parameter_name, parameter_value, parity); |
| } else if (strcmp(parameter_name, "deviceBlocking") == 0) { |
| if (strcmp(parameter_value, "no") == 0) { |
| blocking = 0; |
| } else if (strcmp(parameter_value, "yes") == 0) { |
| blocking = 1; |
| } else { |
| TTCN_error("Invalid %s value: %s\n", parameter_name, parameter_value); |
| } |
| |
| //printf("Parameter %s set to %s (int: %d)\n", parameter_name, parameter_value, blocking); |
| } else if (strncmp(parameter_name, "EOLChar", 7) == 0) { |
| eolChars.push_back(parameter_value[0]); |
| printf("Parameter %s set to %s (int: %d)\n", parameter_name, parameter_value, eolChars.back()); |
| } else if (strcmp(parameter_name, "dataBits") == 0) { |
| if (strcmp(parameter_value, "5") == 0) { |
| dataBits = CS5; |
| } else if (strcmp(parameter_value, "6") == 0) { |
| dataBits = CS6; |
| } else if (strcmp(parameter_value, "7") == 0) { |
| dataBits = CS7; |
| } else if (strcmp(parameter_value, "8") == 0) { |
| dataBits = CS8; |
| } else { |
| TTCN_error("Invalid %s value: %s\n", parameter_name, parameter_value); |
| } |
| //printf("Parameter %s set to %s (int: %d, hex: 0x%0)\n", parameter_name, parameter_value, dataBits); |
| } else if (strcmp(parameter_name, "stopBit") == 0) { |
| if (strcmp(parameter_value, "1") == 0) { |
| stopBit = ~CSTOPB; |
| } else if (strcmp(parameter_value, "2") == 0) { |
| stopBit = CSTOPB; |
| } else { |
| TTCN_error("Invalid %s value: %s\n", parameter_name, parameter_value); |
| } |
| //printf("Parameter %s set to %s (int: %d, hex: 0x%0)\n", parameter_name, parameter_value, stopBit); |
| } |
| } |
| |
| /*void SerialPort::Handle_Fd_Event(int fd, boolean is_readable, |
| boolean is_writable, boolean is_error) {}*/ |
| |
| void SerialPort::Handle_Fd_Event_Error(int /*fd*/) |
| { |
| //printf("===ELNRNAG=== Message received e\n"); |
| } |
| |
| void SerialPort::Handle_Fd_Event_Writable(int fd) |
| { |
| //printf("Message received w\n"); |
| Handle_Fd_Event_Readable(fd); |
| } |
| |
| void SerialPort::Handle_Fd_Event_Readable(int fd) |
| { |
| //printf("Message received r\n"); |
| |
| char input_buffer[1]; |
| char* pointer = input_buffer; |
| int read_bytes = read(fd, pointer, 1); //sizeof(input_buffer)); |
| |
| if (read_bytes > 0) { |
| //printf("Incoming: %s (%d)\n",input_buffer, input_buffer[0]); |
| |
| if (ret_buffer.is_bound()) { //already bound, concatenate |
| //printf ("already bound, concatenate"); |
| ret_buffer += input_buffer[0]; |
| } else { //ret_buffer not bound, create new |
| //printf("ret_buffer not bound, create new"); |
| ret_buffer = CHARSTRING(read_bytes, (const char*)pointer); |
| } |
| |
| for(unsigned int i = 0; i < eolChars.size(); i++){ |
| if (input_buffer[0] == eolChars.at(i)) { //EOL received, returning |
| //printf("EOL received, returning"); |
| CHARSTRING ret_val = CHARSTRING(ret_buffer); |
| ret_buffer = CHARSTRING(""); |
| incoming_message(ret_val); |
| } |
| } |
| } |
| } |
| |
| /*void SerialPort::Handle_Timeout(double time_since_last_call) {}*/ |
| |
| void SerialPort::user_map(const char * system_port) |
| { |
| if (param_device_file != NULL && param_device_file[0] != '\0'){ |
| device_fd = open(param_device_file, O_RDWR | O_NOCTTY | O_NDELAY); |
| if (device_fd == -1) |
| { |
| TTCN_error("Unable to open port %s", param_device_file); |
| } else { |
| set_interface_attribs (device_fd, speed, parity, dataBits, stopBit); |
| set_blocking (device_fd, blocking); |
| Handler_Add_Fd_Read(device_fd); |
| ret_buffer = CHARSTRING(""); |
| } |
| } else { |
| TTCN_error("No device file set in configuration file!"); |
| } |
| } |
| |
| void SerialPort::user_unmap(const char * /*system_port*/) |
| { |
| Handler_Remove_Fd_Read(device_fd); |
| close(device_fd); |
| free(param_device_file); |
| ret_buffer.clean_up(); |
| } |
| |
| void SerialPort::user_start() |
| { |
| |
| } |
| |
| void SerialPort::user_stop() |
| { |
| |
| } |
| |
| void SerialPort::outgoing_send(const CHARSTRING& send_par) |
| { |
| const char* data = (const char*)send_par; |
| if (data != NULL) { |
| long data_length = send_par.lengthof(); |
| //printf("Sending message: %s\n", data); |
| int n = write(device_fd, data, data_length); |
| //printf("Sent message: %s\n", data); |
| if (n < data_length) { |
| TTCN_error("Error while sending data on port %s", param_device_file); |
| } |
| |
| } |
| } |
| |
| int SerialPort::set_interface_attribs (int fd, speed_t speed, int parity, int dataBits, int stopBit) |
| { |
| struct termios tty; |
| memset (&tty, 0, sizeof tty); |
| if (tcgetattr (fd, &tty) != 0) |
| { |
| TTCN_error ("error %d from tcgetattr", errno); |
| return -1; |
| } |
| |
| cfsetospeed (&tty, speed); |
| cfsetispeed (&tty, speed); |
| |
| tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars |
| // disable IGNBRK for mismatched speed tests; otherwise receive break |
| // as \000 chars |
| tty.c_iflag &= ~IGNBRK; // disable break processing |
| tty.c_lflag = 0; // no signaling chars, no echo, |
| // no canonical processing |
| tty.c_oflag = 0; // no remapping, no delays |
| |
| tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl |
| |
| tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, |
| // enable reading |
| tty.c_cflag &= ~(PARENB | PARODD); // shut off parity |
| tty.c_cflag |= parity; |
| tty.c_cflag &= ~CSTOPB; |
| tty.c_cflag &= ~CRTSCTS; |
| |
| if (tcsetattr (fd, TCSANOW, &tty) != 0) |
| { |
| TTCN_error ("error %d from tcsetattr", errno); |
| return -1; |
| } |
| return 0; |
| } |
| |
| void SerialPort::set_blocking (int fd, int should_block) |
| { |
| struct termios tty; |
| memset (&tty, 0, sizeof tty); |
| if (tcgetattr (fd, &tty) != 0) |
| { |
| TTCN_error ("error %d from tggetattr", errno); |
| return; |
| } |
| |
| tty.c_cc[VMIN] = should_block ? 1 : 0; |
| tty.c_cc[VTIME] = 0; // 0.5 seconds read timeout |
| |
| if (tcsetattr (fd, TCSANOW, &tty) != 0) |
| TTCN_error ("error %d setting term attributes", errno); |
| } |
| |
| |
| } /* end of namespace */ |
| |