I want to connect to Cisco router from my c++ application. Need it in order to get interface status. My linux station (Ubuntu) and the router connected via serial interface.

connected from puty or minicom or Console Connections work.

for example:

root@test:/etc/minicom# cu -l /dev/ttyS0 -s 9600
Connected.

Router#show int summary

 *: interface is up
 IHQ: pkts in input hold queue     IQD: pkts dropped from input queue
 OHQ: pkts in output hold queue    OQD: pkts dropped from output queue
 RXBS: rx rate (bits/sec)          RXPS: rx rate (pkts/sec)
 TXBS: tx rate (bits/sec)          TXPS: tx rate (pkts/sec)
 TRTL: throttle count

Now i tried to do the same with C++ (or C) , but read hang.

My c code:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <iostream>
#include<stdio.h>
#include<sys/ioctl.h>
#include<unistd.h>
#include<fcntl.h>
using namespace std;
int fd1;
int fd2;
char *buff, *buffer, *bufptr;
int wr, rd, nbytes, tries;

int configure_port(int fd)      // configure the port
        {
    struct termios port_settings;     // structure to store the port settings in
    bzero(&port_settings, sizeof(port_settings));
    cfsetispeed(&port_settings, B9600);    // set baud rates
    cfsetospeed(&port_settings, B9600);

    port_settings.c_cflag &= ~PARENB;    // set no parity, stop bits, data bits
    port_settings.c_cflag &= ~CSTOPB;
    port_settings.c_cflag &= ~CSIZE;
    port_settings.c_cflag |= CS8;

    tcsetattr(fd, TCSANOW, &port_settings);    // apply the settings to the port
    return (fd);

}
int main() {
    fd1 = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd1 == -1) {
        perror("open_port: Unable to open /dev/ttyS0 – ");
    } else {
        fcntl(fd1, F_SETFL, 0);
    }
    printf("Port 1 has been sucessfully opened and %d is the file description\n",fd1);
    configure_port(fd1);

wr = write(fd1, "\r", 1);
cout << " wr status " << wr << endl;
wr = write(fd1, "\r", 1);
cout << " wr  status " << wr << endl;
wr = write(fd1, "ena\r", 4);
cout << " wr status " << wr << endl;
wr = write(fd1, "show int sum\r", 13);
cout << " wr status " << wr << endl;
rd = read(fd1, buff, 50);
cout << " rd status " << rd << endl;
cout << rd << endl;
    return 0;
}
有帮助吗?

解决方案 2

This work - probably sleep was missing.

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <iostream>
#include<stdio.h>
#include<sys/ioctl.h>
#include<unistd.h>
#include<fcntl.h>

using namespace std;

int set_interface_attribs(int fd, int speed, int parity) {
    struct termios tty;
    memset(&tty, 0, sizeof tty);
    if (tcgetattr(fd, &tty) != 0) {
        printf("err");//error_message("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;         // ignore break signal
    tty.c_lflag = 0;                // no signaling chars, no echo,
                                    // no canonical processing
    tty.c_oflag = 0;                // no remapping, no delays
    tty.c_cc[VMIN] = 0;            // read doesn't block
    tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

    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) {
        printf("err");//error_message("error %d from tcsetattr", errno);
        return -1;
    }
    return 0;
}

void set_blocking(int fd, int should_block) {
    struct termios tty;
    memset(&tty, 0, sizeof tty);
    if (tcgetattr(fd, &tty) != 0) {
        printf("err");//error_message("error %d from tggetattr", errno);
        return;
    }

    tty.c_cc[VMIN] = should_block ? 1 : 0;
    tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

    if (tcsetattr(fd, TCSANOW, &tty) != 0)
        printf("err");//error_message("error %d setting term attributes", errno);
}

int main(int argc, char **argv) {
    char *portname = "/dev/ttyS0";
    int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("err");//error_message("error %d opening %s: %s", errno, portname,strerror(errno));
        return -1;
    }

    set_interface_attribs(fd, B9600, 0); // set speed to 115,200 bps, 8n1 (no parity)
    set_blocking(fd, 0);                // set no blocking
    write(fd, "\r", 1);           // send 7 character greeting
    write(fd, "\r", 1);
    usleep(100000);
    char buf[1000];
    write(fd, "ena\r", 4);
    memset(&buf, 0, sizeof buf);
    usleep(100000);
    write(fd, "show int sum\r", 15);
    sleep(1);
    memset(&buf, 0, sizeof buf);
    int n = read(fd, buf, sizeof buf); // read up to 100 characters if ready to read
    cout << " n " << n << endl;
    cout << " buf " << buf <<  endl;
    close(fd);
}

其他提示

You aren't zeroing your port_settings struct first before modifying it. That's surely a bug, though it may not be the source of your problems. Have you tried building one of the dozens of "termios sample programs" available on the intnernet for comparison?

You should use SNMP to get interface status/statistics instead of connecting to serial console.

This is exact purpose what was SNMP designed for.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top