Watt-32 tcp/ip  2.2 dev-rel.10
sock_in.c
Go to the documentation of this file.
1 
11 #include <stdio.h>
12 
13 #include "copyrigh.h"
14 #include "wattcp.h"
15 #include "language.h"
16 #include "misc.h"
17 #include "timer.h"
18 #include "wdpmi.h"
19 #include "pctcp.h"
20 
21 /*
22  * ip user level timer stuff
23  * void ip_timer_init (void *s, int delayseconds)
24  * int ip_timer_expired (void *s)
25  * - 0 if not expired
26  */
27 void W32_CALL ip_timer_init (sock_type *s, unsigned seconds)
28 {
29  if (seconds)
30  s->tcp.usertimer = set_timeout (1000UL * seconds);
31  else s->tcp.usertimer = 0;
32 }
33 
34 int W32_CALL ip_timer_expired (const sock_type *s)
35 {
36  if (!s->tcp.usertimer)
37  return (0);
38  return chk_timeout (s->tcp.usertimer);
39 }
40 
41 /*
42  * _ip_delay0 called by macro sock_wait_established()
43  *
44  */
45 int W32_CALL _ip_delay0 (sock_type *s, int timeout_sec, UserHandler fn, int *statusptr)
46 {
47  int status = -1;
48 
49  ip_timer_init (s, timeout_sec);
50  do
51  {
52 #if !defined(USE_UDP_ONLY)
53  if (s->tcp.ip_type == TCP_PROTO && tcp_established(&s->tcp))
54  {
55  status = 0;
56  break;
57  }
58 #endif
59 
60  if (!tcp_tick(s))
61  {
62  if (s->tcp.err_msg == NULL)
63  s->tcp.err_msg = _LANG("Host refused connection");
64  status = -1; /* get an early reset */
65  break;
66  }
67  if (ip_timer_expired(s))
68  {
69  if (s->tcp.err_msg == NULL)
70  s->tcp.err_msg = _LANG("Open timed out");
71  if (!(s->tcp.locflags & LF_NOCLOSE))
72  sock_close (s);
73  status = -1;
74  break;
75  }
76  if (fn && (status = (*fn)(s)) != 0)
77  break;
78 
79  if (s->tcp.usr_yield)
80  (*s->tcp.usr_yield)();
81  else WATT_YIELD();
82 
83  if (s->tcp.ip_type == UDP_PROTO)
84  {
85  status = 0;
86  break;
87  }
88  }
89  while (1);
90 
91  if (statusptr)
92  *statusptr = status;
93  return (status);
94 }
95 
96 /*
97  * _ip_delay1 called by macro sock_wait_input()
98  */
99 int W32_CALL _ip_delay1 (sock_type *s, int timeoutseconds, UserHandler fn, int *statusptr)
100 {
101  int status = -1;
102 
103  ip_timer_init (s, timeoutseconds);
104 
105 #if !defined(USE_UDP_ONLY)
106  sock_flush (s); /* new enhancement */
107 #endif
108 
109  do
110  {
111  if (sock_dataready(s))
112  {
113  status = 0;
114  break;
115  }
116  if (s->tcp.locflags & LF_GOT_FIN)
117  {
118  status = 1;
119  break;
120  }
121  if (!tcp_tick(s))
122  {
123  status = 1;
124  break;
125  }
126 
127  if (ip_timer_expired(s))
128  {
129  if (s->tcp.err_msg == NULL)
130  s->tcp.err_msg = _LANG("Connection timed out");
131  if (!(s->tcp.locflags & LF_NOCLOSE))
132  sock_close (s);
133  status = -1;
134  break;
135  }
136  if (fn && (status = (*fn)(s)) != 0)
137  break;
138 
139  if (s->tcp.usr_yield)
140  (*s->tcp.usr_yield)();
141  else WATT_YIELD();
142  }
143  while (1);
144 
145  if (statusptr)
146  *statusptr = status;
147  return (status);
148 }
149 
150 /*
151  * _ip_delay2 called by macro sock_wait_closed();
152  */
153 int W32_CALL _ip_delay2 (sock_type *s, int timeoutseconds, UserHandler fn, int *statusptr)
154 {
155  int status = -1;
156 
157  if (s->tcp.ip_type != TCP_PROTO)
158  {
159  if (statusptr)
160  *statusptr = 1;
161  return (1);
162  }
163 
164 #if !defined(USE_UDP_ONLY)
165  ip_timer_init (s, timeoutseconds);
166 
167  do
168  {
169  /* in this situation we know user is not planning to read rx_data
170  */
171  s->tcp.rx_datalen = 0;
172 
173  if (!tcp_tick(s))
174  {
175  status = 1;
176  break;
177  }
178  if (ip_timer_expired(s))
179  {
180  if (s->tcp.err_msg == NULL)
181  s->tcp.err_msg = _LANG("Connection timed out");
182  TCP_ABORT (&s->tcp);
183  status = -1;
184  break;
185  }
186  if (fn && (status = (*fn)(s)) != 0)
187  break;
188 
189  if (s->tcp.usr_yield)
190  (*s->tcp.usr_yield)();
191  else WATT_YIELD();
192  }
193  while (1);
194 
195  if (statusptr)
196  *statusptr = status;
197 
198 #else
199  ARGSUSED (fn);
200  ARGSUSED (timeoutseconds);
201 #endif
202  return (status);
203 }
204 
205 int W32_CALL sock_timeout (sock_type *s, int sec)
206 {
207  if (s->tcp.ip_type != TCP_PROTO)
208  return (1);
209 
210 #if !defined(USE_UDP_ONLY)
211  if (s->tcp.state != tcp_StateESTAB)
212  return (2);
213 
214  s->tcp.timeout = set_timeout (1000UL * sec);
215 #else
216  ARGSUSED (sec);
217 #endif
218  return (0);
219 }
220 
221 int W32_CALL sock_established (sock_type *s)
222 {
223  switch (s->tcp.ip_type)
224  {
225  case UDP_PROTO:
226  return (1);
227 
228 #if !defined(USE_UDP_ONLY)
229  case TCP_PROTO:
230  return (s->tcp.state == tcp_StateESTAB ||
231  s->tcp.state == tcp_StateESTCL ||
232  s->tcp.state == tcp_StateCLOSWT);
233 #endif
234  default:
235  return (0);
236  }
237 }
238 
int W32_CALL tcp_established(const _tcp_Socket *s)
Returns 1 if TCP connection is established.
Definition: pctcp.c:635
int W32_CALL sock_close(sock_type *s)
Close a UDP/TCP socket.
Definition: pctcp.c:3139
void W32_CALL sock_flush(sock_type *s)
Send pending TCP data.
Definition: pctcp.c:3103
Core definitions.
DWORD W32_CALL set_timeout(DWORD msec)
Return time for when given timeout (msec) expires.
Definition: timer.c:503
WORD W32_CALL tcp_tick(sock_type *s)
Must be called periodically by user application (or BSD socket API).
Definition: pctcp.c:1389
WORD W32_CALL sock_dataready(sock_type *s)
sock_dataready - returns number of bytes waiting to be read.
Definition: sock_io.c:246
BOOL W32_CALL chk_timeout(DWORD value)
Check if milli-sec value has expired:
Definition: timer.c:547
DWORD timeout
timer for retrans etc.
Definition: wattcp.h:631
UINT state
tcp connection state
Definition: wattcp.h:622