~ubuntu-branches/ubuntu/precise/stellarium/precise

« back to all changes in this revision

Viewing changes to src/telescope.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2008-05-19 21:28:23 UTC
  • mfrom: (3.1.5 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080519212823-m5nfiuntxstxzxj7
Tags: 0.9.1-4
Add libxcursor-dev, libxfixes-dev, libxinerama-dev, libqt4-opengl-dev to
build-deps (Closes: #479906)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Author and Copyright of this file and of the stellarium telescope feature:
3
 
 * Johannes Gajdosik, 2006
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License
7
 
 * as published by the Free Software Foundation; either version 2
8
 
 * of the License, or (at your option) any later version.
9
 
 * 
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 * 
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
 */
19
 
 
20
 
#include "telescope.h"
21
 
#include <math.h>
22
 
 
23
 
#ifdef WIN32
24
 
  #include <windows.h> // GetSystemTimeAsFileTime
25
 
  #include <winsock2.h>
26
 
  #define ERRNO WSAGetLastError()
27
 
  #undef EAGAIN
28
 
  #define EAGAIN WSAEWOULDBLOCK
29
 
  #undef EINTR
30
 
  #define EINTR WSAEINTR
31
 
  #undef EINPROGRESS
32
 
  #define EINPROGRESS WSAEINPROGRESS
33
 
  static u_long ioctlsocket_arg = 1;
34
 
  #define SET_NONBLOCKING_MODE(s) ioctlsocket(s,FIONBIO,&ioctlsocket_arg)
35
 
  #define SOCKLEN_T int
36
 
  #define close closesocket
37
 
  #define IS_INVALID_SOCKET(fd) (fd==INVALID_SOCKET)
38
 
#else
39
 
  #include <netdb.h>
40
 
  #include <netinet/in.h>
41
 
  #include <sys/socket.h>
42
 
  #include <sys/time.h>
43
 
  #include <unistd.h>
44
 
  #include <fcntl.h>
45
 
  #include <errno.h>
46
 
  #define ERRNO errno
47
 
  #define SET_NONBLOCKING_MODE(s) fcntl(s,F_SETFL,O_NONBLOCK)
48
 
  #define SOCKLEN_T socklen_t
49
 
  #define SOCKET int
50
 
  #define IS_INVALID_SOCKET(fd) (fd<0)
51
 
  #define INVALID_SOCKET (-1)
52
 
#endif
53
 
 
54
 
class TelescopeDummy : public Telescope {
55
 
public:
56
 
  TelescopeDummy(const string &name,const string &params) : Telescope(name) {
57
 
    desired_pos[0] = XYZ[0] = 1.0;
58
 
    desired_pos[1] = XYZ[1] = 0.0;
59
 
    desired_pos[2] = XYZ[2] = 0.0;
60
 
  }
61
 
private:
62
 
  bool isConnected(void) const {return true;}
63
 
  bool hasKnownPosition(void) const {return true;}
64
 
  Vec3d getObsJ2000Pos(const Navigator *nav=0) const {return XYZ;}
65
 
  void prepareSelectFds(fd_set&,fd_set&,int&) {
66
 
    XYZ = XYZ*31.0+desired_pos;
67
 
    const double lq = XYZ.lengthSquared();
68
 
    if (lq > 0.0) XYZ *= (1.0/sqrt(lq));
69
 
    else XYZ = desired_pos;
70
 
  }
71
 
  void telescopeGoto(const Vec3d &j2000_pos) {
72
 
    desired_pos = j2000_pos;
73
 
    desired_pos.normalize();
74
 
  }
75
 
  Vec3d XYZ; // j2000 position
76
 
  Vec3d desired_pos;
77
 
};
78
 
 
79
 
 
80
 
class TelescopeTcp : public Telescope {
81
 
public:
82
 
  TelescopeTcp(const string &name,const string &params);
83
 
  ~TelescopeTcp(void) {hangup();}
84
 
private:
85
 
  bool isConnected(void) const
86
 
    {return (!IS_INVALID_SOCKET(fd) && !wait_for_connection_establishment);}
87
 
  Vec3d getObsJ2000Pos(const Navigator *nav=0) const;
88
 
  void prepareSelectFds(fd_set &read_fds,fd_set &write_fds,int &fd_max);
89
 
  void handleSelectFds(const fd_set &read_fds,const fd_set &write_fds);
90
 
  void telescopeGoto(const Vec3d &j2000_pos);
91
 
  bool isInitialized(void) const {return (ntohs(address.sin_port)!=0);}
92
 
  void performReading(void);
93
 
  void performWriting(void);
94
 
private:
95
 
  void hangup(void);
96
 
  struct sockaddr_in address;
97
 
  SOCKET fd;
98
 
  bool wait_for_connection_establishment;
99
 
  long long int next_connection_attempt;
100
 
  char read_buff[120];
101
 
  char *read_buff_end;
102
 
  char write_buff[120];
103
 
  char *write_buff_end;
104
 
  long long int time_delay;
105
 
  struct Position {
106
 
    long long int server_micros;
107
 
    long long int client_micros;
108
 
    unsigned int ra_int;
109
 
    int dec_int;
110
 
    int status;
111
 
  };
112
 
  Position positions[16];
113
 
  Position *position_pointer;
114
 
  Position *const end_position;
115
 
  virtual bool hasKnownPosition(void) const
116
 
    {return (position_pointer->client_micros!=0x7FFFFFFFFFFFFFFFLL);}
117
 
};
118
 
 
119
 
Telescope *Telescope::create(const string &url) {
120
 
  string::size_type i = url.find(':');
121
 
  if (i == string::npos) {
122
 
    cerr << "Telescope::create(" << url << "): bad url: \"" << url
123
 
         << "\", ':' missing" << endl;
124
 
    return 0;
125
 
  }
126
 
  const string name = url.substr(0,i);
127
 
  if (i+2 > url.length()) {
128
 
    cerr << "Telescope::create(" << url << "): bad url: \"" << url
129
 
         << "\", too short" << endl;
130
 
    return 0;
131
 
  }
132
 
  string::size_type j = url.find(':',i+1);
133
 
  if (j == string::npos) {
134
 
    cerr << "Telescope::create(" << url << "): bad url: \"" << url
135
 
         << "\", 2nd ':' missing" << endl;
136
 
    return 0;
137
 
  }
138
 
  const string type = url.substr(i+1,j-i-1);
139
 
  if (j+2 > url.length()) {
140
 
    cerr << "Telescope::create(" << url << "): bad url: \"" << url
141
 
         << "\", too short" << endl;
142
 
    return 0;
143
 
  }
144
 
  const string params = url.substr(j+1);
145
 
  cout << "Telescope::create(" << url << "): trying to create telescope \""
146
 
       << name << "\" of type \"" << type << "\" with parameters \""
147
 
       << params << '"' << endl;
148
 
  Telescope *rval = 0;
149
 
  if (type == "Dummy") {
150
 
    rval = new TelescopeDummy(name,params);
151
 
  } else if (type == "TCP") {
152
 
    rval = new TelescopeTcp(name,params);
153
 
  } else {
154
 
    cerr << "Telescope::create(" << url << "): unknown telescop type \""
155
 
         << type << '"' << endl;
156
 
  }
157
 
  if (rval && !rval->isInitialized()) {
158
 
    delete rval;
159
 
    rval = 0;
160
 
  }
161
 
  return rval;
162
 
}
163
 
 
164
 
 
165
 
Telescope::Telescope(const string &name) : name(name) {
166
 
  std::wostringstream oss;
167
 
  oss << name.c_str();
168
 
  nameI18n = oss.str();
169
 
}
170
 
 
171
 
wstring Telescope::getInfoString(const Navigator *nav) const {
172
 
  const Vec3d equatorial_pos = get_earth_equ_pos(nav);
173
 
  double ra,dec;
174
 
  rect_to_sphe(&ra,&dec,equatorial_pos);
175
 
  std::wostringstream oss;
176
 
  oss << nameI18n << endl
177
 
      << "RA/DE: " << StelUtility::printAngleHMS(ra)
178
 
      << "/" << StelUtility::printAngleDMS(dec) << endl;
179
 
  return oss.str();
180
 
}
181
 
 
182
 
wstring Telescope::getShortInfoString(const Navigator*) const {
183
 
  return nameI18n;
184
 
}
185
 
 
186
 
 
187
 
 
188
 
long long int GetNow(void) {
189
 
#ifdef WIN32
190
 
  FILETIME file_time;
191
 
  GetSystemTimeAsFileTime(&file_time);
192
 
  return (*((__int64*)(&file_time))/10) - 86400000000LL*134774;
193
 
#else
194
 
  struct timeval tv;
195
 
  gettimeofday(&tv,0);
196
 
  return tv.tv_sec * 1000000LL + tv.tv_usec;
197
 
#endif
198
 
}
199
 
 
200
 
TelescopeTcp::TelescopeTcp(const string &name,const string &params)
201
 
             :Telescope(name),fd(INVALID_SOCKET),
202
 
              end_position(positions+(sizeof(positions)/sizeof(positions[0]))) {
203
 
  hangup();
204
 
  address.sin_port = htons(0);
205
 
  string::size_type i = params.find(':');
206
 
  if (i == string::npos) {
207
 
    cerr << "TelescopeTcp::TelescopeTcp(" << name << ',' << params << "): "
208
 
            "bad params: ':' missing" << endl;
209
 
    return;
210
 
  }
211
 
  const string host = params.substr(0,i);
212
 
  if (i+2 > params.length()) {
213
 
    cerr << "TelescopeTcp::TelescopeTcp(" << name << ',' << params << "): "
214
 
            "bad params: too short"
215
 
         << endl;
216
 
    return;
217
 
  }
218
 
  string::size_type j = params.find(':',i+1);
219
 
  if (j == string::npos) {
220
 
    cerr << "TelescopeTcp::TelescopeTcp(" << name << ',' << params << "): "
221
 
            "bad params: ':' missing" << endl;
222
 
    return;
223
 
  }
224
 
  int port;
225
 
  if (1!=sscanf(params.substr(i+1,j-i-1).c_str(),"%d",&port) ||
226
 
      port<=0 || port>0xFFFF) {
227
 
    cerr << "TelescopeTcp::TelescopeTcp(" << name << ',' << params << "): "
228
 
            "bad port" << endl;
229
 
    return;
230
 
  }
231
 
  if (1!=sscanf(params.substr(j+1).c_str(),"%Ld",&time_delay) ||
232
 
      time_delay<=0 || time_delay>10000000) {
233
 
    cerr << "TelescopeTcp::TelescopeTcp(" << name << ',' << params << "): "
234
 
            "bad time_delay" << endl;
235
 
    return;
236
 
  }
237
 
  struct hostent *hep = gethostbyname(host.c_str());
238
 
  if (hep == 0) {
239
 
    cerr << "TelescopeTcp::TelescopeTcp(" << name << ',' << params << "): "
240
 
            "unknown host" << endl;
241
 
    return;
242
 
  }
243
 
  if (hep->h_length != 4) {
244
 
    cerr << "TelescopeTcp::TelescopeTcp(" << name << ',' << params << "): "
245
 
            "only IPv4 implemented"
246
 
         << endl;
247
 
    return;
248
 
  }
249
 
  memset(&address,0,sizeof(struct sockaddr_in));
250
 
  memcpy(&(address.sin_addr),hep->h_addr,4);
251
 
  address.sin_port = htons(port);
252
 
  address.sin_family = AF_INET;
253
 
  next_connection_attempt = -0x8000000000000000LL;
254
 
 
255
 
  for (position_pointer = positions;
256
 
       position_pointer < end_position;
257
 
       position_pointer++) {
258
 
    position_pointer->server_micros = 0x7FFFFFFFFFFFFFFFLL;
259
 
    position_pointer->client_micros = 0x7FFFFFFFFFFFFFFFLL;
260
 
    position_pointer->ra_int = 0;
261
 
    position_pointer->dec_int = 0;
262
 
    position_pointer->status = 0;
263
 
  }
264
 
  position_pointer = positions;
265
 
}
266
 
 
267
 
void TelescopeTcp::hangup(void) {
268
 
  if (!IS_INVALID_SOCKET(fd)) {
269
 
    close(fd);
270
 
    fd = INVALID_SOCKET;
271
 
  }
272
 
  read_buff_end = read_buff;
273
 
  write_buff_end = write_buff;
274
 
  wait_for_connection_establishment = false;
275
 
}
276
 
 
277
 
void TelescopeTcp::telescopeGoto(const Vec3d &j2000_pos) {
278
 
  if (isConnected()) {
279
 
    if (write_buff_end-write_buff+20 < (int)sizeof(write_buff)) {
280
 
      const double ra = atan2(j2000_pos[1],j2000_pos[0]);
281
 
      const double dec = atan2(j2000_pos[2],
282
 
              sqrt(j2000_pos[0]*j2000_pos[0]+j2000_pos[1]*j2000_pos[1]));
283
 
      unsigned int ra_int = (unsigned int)floor(
284
 
                               0.5 +  ra*(((unsigned int)0x80000000)/M_PI));
285
 
      int dec_int = (int)floor(0.5 + dec*(((unsigned int)0x80000000)/M_PI));
286
 
//      cout << "TelescopeTcp(" << name << ")::telescopeGoto: "
287
 
//              "queuing packet: "
288
 
//           << (12*ra/M_PI) << ',' << (180*dec/M_PI)
289
 
//           << ";  " << ra_int << ',' << dec_int << endl;
290
 
        // length of packet:
291
 
      *write_buff_end++ = 20;
292
 
      *write_buff_end++ = 0;
293
 
        // type of packet:
294
 
      *write_buff_end++ = 0;
295
 
      *write_buff_end++ = 0;
296
 
        // client_micros:
297
 
      long long int now = GetNow();
298
 
      *write_buff_end++ = now;now>>=8;
299
 
      *write_buff_end++ = now;now>>=8;
300
 
      *write_buff_end++ = now;now>>=8;
301
 
      *write_buff_end++ = now;now>>=8;
302
 
      *write_buff_end++ = now;now>>=8;
303
 
      *write_buff_end++ = now;now>>=8;
304
 
      *write_buff_end++ = now;now>>=8;
305
 
      *write_buff_end++ = now;
306
 
        // ra:
307
 
      *write_buff_end++ = ra_int;ra_int>>=8;
308
 
      *write_buff_end++ = ra_int;ra_int>>=8;
309
 
      *write_buff_end++ = ra_int;ra_int>>=8;
310
 
      *write_buff_end++ = ra_int;
311
 
        // dec:
312
 
      *write_buff_end++ = dec_int;dec_int>>=8;
313
 
      *write_buff_end++ = dec_int;dec_int>>=8;
314
 
      *write_buff_end++ = dec_int;dec_int>>=8;
315
 
      *write_buff_end++ = dec_int;
316
 
    } else {
317
 
      cerr << "TelescopeTcp(" << name << ")::telescopeGoto: "
318
 
              "communication is too slow, I will ignore this command" << endl;
319
 
    }
320
 
  }
321
 
}
322
 
 
323
 
void TelescopeTcp::performWriting(void) {
324
 
  const int to_write = write_buff_end - write_buff;
325
 
  const int rc = send(fd,write_buff,to_write,0);
326
 
  if (rc < 0) {
327
 
    if (ERRNO != EINTR && ERRNO != EAGAIN) {
328
 
      cerr << "TelescopeTcp(" << name << ")::performWriting: "
329
 
              "send failed" << endl;
330
 
      hangup();
331
 
    }
332
 
  } else if (rc > 0) {
333
 
    if (rc >= to_write) {
334
 
        // everything written
335
 
      write_buff_end = write_buff;
336
 
    } else {
337
 
        // partly written
338
 
      memmove(write_buff,write_buff+rc,to_write-rc);
339
 
      write_buff_end -= rc;
340
 
    }
341
 
  }
342
 
}
343
 
 
344
 
void TelescopeTcp::performReading(void) {
345
 
  const int to_read = read_buff + sizeof(read_buff) - read_buff_end;
346
 
  const int rc = recv(fd,read_buff_end,to_read,0);
347
 
  if (rc < 0) {
348
 
    if (ERRNO != EINTR && ERRNO != EAGAIN) {
349
 
      cerr << "TelescopeTcp(" << name << ")::performReading: "
350
 
              "recv failed" << endl;
351
 
      hangup();
352
 
    }
353
 
  } else if (rc == 0) {
354
 
    cerr << "TelescopeTcp(" << name << ")::performReading: "
355
 
            "server has closed the connection" << endl;
356
 
    hangup();
357
 
  } else {
358
 
    read_buff_end += rc;
359
 
    char *p = read_buff;
360
 
    while (read_buff_end-p >= 2) {
361
 
      const int size = (int)(                ((unsigned char)(p[0])) |
362
 
                              (((unsigned int)(unsigned char)(p[1])) << 8) );
363
 
      if (size > (int)sizeof(read_buff) || size < 4) {
364
 
        cerr << "TelescopeTcp(" << name << ")::performReading: "
365
 
                "bad packet size: " << size << endl;
366
 
        hangup();
367
 
        return;
368
 
      }
369
 
      if (size > read_buff_end-p) {
370
 
          // wait for complete packet
371
 
        break;
372
 
      }
373
 
      const int type = (int)(                ((unsigned char)(p[2])) |
374
 
                              (((unsigned int)(unsigned char)(p[3])) << 8) );
375
 
        // dispatch:
376
 
      switch (type) {
377
 
        case 0: {
378
 
          if (size < 24) {
379
 
            cerr << "TelescopeTcp(" << name << ")::performReading: "
380
 
                    "type 0: bad packet size: " << size << endl;
381
 
            hangup();
382
 
            return;
383
 
          }
384
 
          const long long int server_micros = (long long int)
385
 
                 (  ((unsigned long long int)(unsigned char)(p[ 4])) |
386
 
                   (((unsigned long long int)(unsigned char)(p[ 5])) <<  8) |
387
 
                   (((unsigned long long int)(unsigned char)(p[ 6])) << 16) |
388
 
                   (((unsigned long long int)(unsigned char)(p[ 7])) << 24) |
389
 
                   (((unsigned long long int)(unsigned char)(p[ 8])) << 32) |
390
 
                   (((unsigned long long int)(unsigned char)(p[ 9])) << 40) |
391
 
                   (((unsigned long long int)(unsigned char)(p[10])) << 48) |
392
 
                   (((unsigned long long int)(unsigned char)(p[11])) << 56) );
393
 
          const unsigned int ra_int =
394
 
                    ((unsigned int)(unsigned char)(p[12])) |
395
 
                   (((unsigned int)(unsigned char)(p[13])) <<  8) |
396
 
                   (((unsigned int)(unsigned char)(p[14])) << 16) |
397
 
                   (((unsigned int)(unsigned char)(p[15])) << 24);
398
 
          const int dec_int =
399
 
            (int)(  ((unsigned int)(unsigned char)(p[16])) |
400
 
                   (((unsigned int)(unsigned char)(p[17])) <<  8) |
401
 
                   (((unsigned int)(unsigned char)(p[18])) << 16) |
402
 
                   (((unsigned int)(unsigned char)(p[19])) << 24) );
403
 
          const int status =
404
 
            (int)(  ((unsigned int)(unsigned char)(p[20])) |
405
 
                   (((unsigned int)(unsigned char)(p[21])) <<  8) |
406
 
                   (((unsigned int)(unsigned char)(p[22])) << 16) |
407
 
                   (((unsigned int)(unsigned char)(p[23])) << 24) );
408
 
 
409
 
          position_pointer++;
410
 
          if (position_pointer >= end_position) position_pointer = positions;
411
 
          position_pointer->server_micros = server_micros;
412
 
          position_pointer->client_micros = GetNow();
413
 
          position_pointer->ra_int = ra_int;
414
 
          position_pointer->dec_int = dec_int;
415
 
          position_pointer->status = status;
416
 
//          cout << "TelescopeTcp(" << name << ")::performReading: "
417
 
//                  "Client Time: " << position_pointer->client_micros
418
 
//               << ", ra: " << position_pointer->ra_int
419
 
//               << ", dec: " << position_pointer->dec_int
420
 
//               << endl;
421
 
        } break;
422
 
        default:
423
 
          cout << "TelescopeTcp(" << name << ")::performReading: "
424
 
                  "ignoring unknown packet, type: " << type << endl;
425
 
          break;
426
 
      }
427
 
      p += size;
428
 
    }
429
 
    if (p >= read_buff_end) {
430
 
        // everything handled
431
 
      read_buff_end = read_buff;
432
 
    } else {
433
 
        // partly handled
434
 
      memmove(read_buff,p,read_buff_end-p);
435
 
      read_buff_end -= (p-read_buff);
436
 
    }
437
 
  }
438
 
}
439
 
 
440
 
Vec3d TelescopeTcp::getObsJ2000Pos(const Navigator*) const {
441
 
  if (position_pointer->client_micros == 0x7FFFFFFFFFFFFFFFLL) {
442
 
    return Vec3d(0,0,0);
443
 
  }
444
 
  const long long int now = GetNow() - time_delay;
445
 
  const Position *p = position_pointer;
446
 
  do {
447
 
    const Position *pp = p;
448
 
    if (pp == positions) pp = end_position;
449
 
    pp--;
450
 
    if (pp->client_micros == 0x7FFFFFFFFFFFFFFFLL) break;
451
 
    if (pp->client_micros <= now && now <= p->client_micros) {
452
 
      const double h = (M_PI/(unsigned int)0x80000000)
453
 
                     / (p->client_micros - pp->client_micros);
454
 
      const long long int f0 = (now - pp->client_micros);
455
 
      const long long int f1 = (p->client_micros - now);
456
 
 
457
 
      double ra;
458
 
      if (pp->ra_int <= p->ra_int) {
459
 
        if (p->ra_int - pp->ra_int <= (unsigned int)0x80000000) {
460
 
          ra = h*(f1*pp->ra_int  + f0*p->ra_int);
461
 
        } else {
462
 
          ra = h*(f1*(0*0x100000000LL + pp->ra_int)  + f0*p->ra_int);
463
 
        }
464
 
      } else {
465
 
        if (pp->ra_int - p->ra_int <= (unsigned int)0x80000000) {
466
 
          ra = h*(f1*pp->ra_int  + f0*p->ra_int);
467
 
        } else {
468
 
          ra = h*(f1*pp->ra_int  + f0*(0*0x100000000LL + p->ra_int));
469
 
        }
470
 
      }
471
 
      const double dec = h*(f1*pp->dec_int + f0*p->dec_int);
472
 
//      cout << "TelescopeTcp(" << name << ")::getObsJ2000Pos: "
473
 
//              "Time: " << now
474
 
//           << ", ra: " << ra*(((unsigned int)0x80000000)/M_PI)
475
 
//           << ", dec: " << dec*(((unsigned int)0x80000000)/M_PI)
476
 
//           << endl;
477
 
      const double cdec = cos(dec);
478
 
      return Vec3d(cos(ra)*cdec,sin(ra)*cdec,sin(dec));
479
 
    }
480
 
    p = pp;
481
 
  } while (p != position_pointer);
482
 
  const double h = (M_PI/(unsigned int)0x80000000);
483
 
  const double ra  = h*position_pointer->ra_int;
484
 
  const double dec = h*position_pointer->dec_int;
485
 
  const double cdec = cos(dec);
486
 
  return Vec3d(cos(ra)*cdec,sin(ra)*cdec,sin(dec));
487
 
}
488
 
 
489
 
void TelescopeTcp::prepareSelectFds(fd_set &read_fds,fd_set &write_fds,
490
 
                                    int &fd_max) {
491
 
  if (IS_INVALID_SOCKET(fd)) {
492
 
      // try reconnecting
493
 
    const long long int now = GetNow();
494
 
    if (now < next_connection_attempt) return;
495
 
    next_connection_attempt = now + 5000000;
496
 
    fd = socket(AF_INET,SOCK_STREAM,0);
497
 
    if (IS_INVALID_SOCKET(fd)) {
498
 
      cerr << "TelescopeTcp(" << name << ")::prepareSelectFds: socket() failed" << endl;
499
 
      return;
500
 
    }
501
 
    if (SET_NONBLOCKING_MODE(fd) != 0) {
502
 
      cerr << "TelescopeTcp(" << name << ")::prepareSelectFds: "
503
 
              "could not set nonblocking mode" << endl;
504
 
      hangup();
505
 
      return;
506
 
    }
507
 
    if (connect(fd,(struct sockaddr*)(&address),sizeof(address)) != 0) {
508
 
      if (ERRNO != EINPROGRESS && ERRNO != EAGAIN) {
509
 
        cerr << "TelescopeTcp(" << name << ")::prepareSelectFds: "
510
 
                "connect() failed" << endl;
511
 
        hangup();
512
 
        return;
513
 
      }
514
 
      wait_for_connection_establishment = true;
515
 
    } else {
516
 
      wait_for_connection_establishment = false;
517
 
        // connection established, wait for next call of prepareSelectFds
518
 
    }
519
 
  } else {
520
 
      // socked is already connected
521
 
    if (fd_max < (int)fd) fd_max = (int)fd;
522
 
    if (wait_for_connection_establishment) {
523
 
      FD_SET(fd,&write_fds);
524
 
    } else {
525
 
      if (write_buff_end > write_buff) FD_SET(fd,&write_fds);
526
 
      FD_SET(fd,&read_fds);
527
 
    }
528
 
  }
529
 
}
530
 
 
531
 
void TelescopeTcp::handleSelectFds(const fd_set &read_fds,
532
 
                                   const fd_set &write_fds) {
533
 
  if (!IS_INVALID_SOCKET(fd)) {
534
 
    if (wait_for_connection_establishment) {
535
 
      if (FD_ISSET(fd,&write_fds)) {
536
 
        wait_for_connection_establishment = false;
537
 
        int err = 0;
538
 
        SOCKLEN_T length = sizeof(err);
539
 
        if (getsockopt(fd,SOL_SOCKET,SO_ERROR,(char*)(&err),&length) != 0) {
540
 
          cerr << "TelescopeTcp(" << name << ")::handleSelectFds: "
541
 
                  "getsockopt failed" << endl;
542
 
          hangup();
543
 
        } else {
544
 
          if (err != 0) {
545
 
//            cerr << "TelescopeTcp(" << name << ")::handleSelectFds: "
546
 
//                    "connect failed: " << err << endl;
547
 
            hangup();
548
 
          } else {
549
 
            cout << "TelescopeTcp(" << name << ")::handleSelectFds: "
550
 
                    "connection established" << endl;
551
 
          }
552
 
        }
553
 
      }
554
 
    } else { // connection already established
555
 
      if (FD_ISSET(fd,&write_fds)) {
556
 
        performWriting();
557
 
      }
558
 
      if (!IS_INVALID_SOCKET(fd) && FD_ISSET(fd,&read_fds)) {
559
 
        performReading();
560
 
      }
561
 
    }
562
 
  }
563
 
}
564
 
 
565
 
 
566