+/* Open a device with standard options.
+ * Use value (-1) for "__with_hw_handshake" if its specification is required from the user
+ */
+int serial_opendevice(__const char *__file, int __with_odd_parity, int __with_async, int __with_hw_handshake) {
+
+ int fd;
+ int retcode;
+ struct termios tp;
+
+ /* handle config file handshake override: */
+ {
+char *s=CFG_Get(CFG_Info, "global", "handshake");
+
+ if (s && (!strcasecmp(s,"software") || !strcasecmp(s,"rtscts")))
+ __with_hw_handshake=false;
+ else if (s && (!strcasecmp(s,"hardware") || !strcasecmp(s,"xonxoff")))
+ __with_hw_handshake=true;
+ else if (s)
+ fprintf(stderr,_("Unrecognized [%s] option \"%s\", use \"%s\" or \"%s\" value, ignoring!"),
+ "global","handshake","software","hardware");
+
+ if (__with_hw_handshake==-1) {
+ fprintf(stderr,_("[%s] option \"%s\" not found, trying to use \"%s\" value!"),
+ "global","handshake","software");
+ __with_hw_handshake=false;
+ }
+ }
+
+ /* Open device */
+
+ /* O_NONBLOCK MUST be used here as the CLOCAL may be currently off
+ * and if DCD is down the "open" syscall would be stuck wating for DCD.
+ */
+ fd = serial_open(__file, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+ if (fd < 0)
+ return fd;
+
+ /* Initialise the port settings */
+
+ memcpy(&tp, &serial_termios, sizeof(struct termios));
+
+ /* Set port settings for canonical input processing */
+
+ tp.c_cflag = B0 | CS8 | CLOCAL | CREAD | HUPCL;
+ if (__with_odd_parity) {
+ tp.c_cflag |= (PARENB | PARODD);
+ tp.c_iflag = 0;
+ }
+ else
+ tp.c_iflag = IGNPAR;
+ if (__with_hw_handshake)
+ tp.c_cflag |= CRTSCTS;
+ else
+ tp.c_cflag &= ~CRTSCTS;
+
+ tp.c_oflag = 0;
+ tp.c_lflag = 0;
+ tp.c_cc[VMIN] = 1;
+ tp.c_cc[VTIME] = 0;
+
+ retcode=tcflush(fd, TCIFLUSH);
+ if (retcode == -1) {
+ perror("Gnokii serial_opendevice: tcflush");
+ serial_close(fd);
+ return(-1);
+ }
+
+ retcode=tcsetattr(fd, TCSANOW, &tp);
+ if (retcode == -1){
+ perror("Gnokii serial_opendevice: tcsetattr");
+ serial_close(fd);
+ return(-1);
+ }
+
+ /* Set speed */
+ {
+char *baudratestring=CFG_Get(CFG_Info, "global", "serial_baudrate");
+int baudrate=0;
+
+ if (baudratestring)
+ baudrate=atoi(baudratestring);
+ if (baudrate && !serial_changespeed(fd,baudrate))
+ baudrate=0;
+ if (!baudrate)
+ serial_changespeed(fd,19200/*default value*/);
+ }
+
+ /* We need to turn off O_NONBLOCK now (we have CLOCAL set so it is safe).
+ * When we run some device script it really doesn't expect NONBLOCK!
+ */
+
+ retcode=fcntl(fd, F_SETFL, 0);
+ if (retcode == -1){
+ perror("Gnokii serial_opendevice: fnctl(F_SETFL)");
+ serial_close(fd);
+ return(-1);
+ }
+
+ /* handle config file connect_script:
+ */
+ if (-1 == device_script(fd,"connect_script")) {
+ fprintf(stderr,"Gnokii serial_opendevice: connect_script\n");
+ serial_close(fd);
+ return(-1);
+ }
+
+ /* Allow process/thread to receive SIGIO */