7 A Linux/Unix toolset and driver for Nokia mobile phones.
9 Copyright (C) 2002 Jan Kratochvil
11 Released under the terms of the GNU GPL, see file COPYING for more details.
16 #include "cfgreader.h"
20 #include <sys/ioctl.h>
25 #include <sys/types.h>
27 #include <sys/ioctl.h>
28 #include <netinet/in.h>
29 #include <sys/socket.h>
33 # include <sys/file.h>
37 #include "devices/tcp.h"
38 #include "devices/unixserial.h"
40 #ifdef HAVE_SYS_IOCTL_COMPAT_H
41 #include <sys/ioctl_compat.h>
44 #ifdef HAVE_SYS_SELECT_H
45 #include <sys/select.h>
52 /* Open the serial port and store the settings. */
54 int tcp_open(__const char *__file) {
58 struct sockaddr_in addr;
59 static bool atexit_registered=false;
60 char *filedup,*portstr,*end;
62 struct hostent *hostent;
64 if (!atexit_registered) {
65 memset(serial_close_all_openfds,-1,sizeof(serial_close_all_openfds));
66 #if 0 /* Disabled for now as atexit() functions are then called multiple times for pthreads! */
67 signal(SIGINT,unixserial_interrupted);
69 atexit(serial_close_all);
70 atexit_registered=true;
73 __fd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
75 perror("Gnokii tcp_open: socket()");
78 if (!(filedup=strdup(__file))) {
83 if (!(portstr=strchr(filedup,':'))) {
84 fprintf(stderr,"Gnokii tcp_open: colon (':') not found in connect strings \"%s\"!\n",filedup);
90 portul=strtoul(portstr,&end,0);
91 if ((end && *end) || portul>=0x10000) {
92 fprintf(stderr,"Gnokii tcp_open: Port string \"%s\" not valid for IPv4 connection!\n",portstr);
95 if (!(hostent=gethostbyname(filedup))) {
96 fprintf(stderr,"Gnokii tcp_open: Unknown host \"%s\"!\n",filedup);
99 if (hostent->h_addrtype!=AF_INET || hostent->h_length!=sizeof(addr.sin_addr) || !hostent->h_addr_list[0]) {
100 fprintf(stderr,"Gnokii tcp_open: Address resolve for host \"%s\" not compatible!\n",filedup);
105 addr.sin_family=AF_INET;
106 addr.sin_port=htons(portul);
107 memcpy(&addr.sin_addr,hostent->h_addr_list[0],sizeof(addr.sin_addr));
109 if (connect(__fd,(struct sockaddr *)&addr,sizeof(addr))) {
110 perror("Gnokii tcp_open: connect()");
114 for (i=0;i<ARRAY_LEN(serial_close_all_openfds);i++)
115 if (serial_close_all_openfds[i]==-1 || serial_close_all_openfds[i]==__fd) {
116 serial_close_all_openfds[i]=__fd;
123 int tcp_close(int __fd) {
126 for (i=0;i<ARRAY_LEN(serial_close_all_openfds);i++)
127 if (serial_close_all_openfds[i]==__fd)
128 serial_close_all_openfds[i]=-1; /* fd closed */
130 /* handle config file disconnect_script:
132 if (-1 == device_script(__fd,"disconnect_script"))
133 fprintf(stderr,"Gnokii tcp_close: disconnect_script\n");
135 return (close(__fd));
138 /* Open a device with standard options.
139 * Use value (-1) for "__with_hw_handshake" if its specification is required from the user
141 int tcp_opendevice(__const char *__file, int __with_async) {
148 fd = tcp_open(__file);
153 /* handle config file connect_script:
155 if (-1 == device_script(fd,"connect_script")) {
156 fprintf(stderr,"Gnokii tcp_opendevice: connect_script\n");
161 /* Allow process/thread to receive SIGIO */
164 retcode = fcntl(fd, F_SETOWN, getpid());
166 perror("Gnokii tcp_opendevice: fnctl(F_SETOWN)");
172 /* Make filedescriptor asynchronous. */
174 /* We need to supply FNONBLOCK (or O_NONBLOCK) again as it would get reset
175 * by F_SETFL as a side-effect!
177 retcode=fcntl(fd, F_SETFL, (__with_async ? FASYNC : 0) | FNONBLOCK);
179 perror("Gnokii tcp_opendevice: fnctl(F_SETFL)");
187 int tcp_select(int fd, struct timeval *timeout) {
189 return serial_select(fd, timeout);
193 /* Read from serial device. */
195 size_t tcp_read(int __fd, __ptr_t __buf, size_t __nbytes) {
197 return (read(__fd, __buf, __nbytes));
200 /* Write to serial device. */
202 size_t tcp_write(int __fd, __const __ptr_t __buf, size_t __n) {
204 return(write(__fd, __buf, __n));