Subversion Repositories HomeAutomation

Rev

Rev 984 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 984 Rev 999
Line 16... Line 16...
16
 *  You should have received a copy of the GNU General Public License   *
16
 *  You should have received a copy of the GNU General Public License   *
17
 *  along with this program; if not, write to the             *
17
 *  along with this program; if not, write to the             *
18
 *  Free Software Foundation, Inc.,                    *
18
 *  Free Software Foundation, Inc.,                    *
19
 *  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.       *
19
 *  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.       *
20
 ***************************************************************************/
20
 ***************************************************************************/
-
 
21
 
-
 
22
#include "socketeventcallback.h"
-
 
23
 
21
 
24
 
22
#include "asyncsocket.h"
25
#include "asyncsocket.h"
23
 
26
 
24
int socketCount = 1;
27
int socketCount = 1;
25
 
28
 
Line 27... Line 30...
27
{
30
{
28
    myId = socketCount++;
31
    myId = socketCount++;
29
    mySocket = -1;
32
    mySocket = -1;
30
    myReconnectTimeout = 0;
33
    myReconnectTimeout = 0;
31
    myForceReconnect = false;
34
    myForceReconnect = false;
-
 
35
    myEventCallback = NULL;
32
}
36
}
33
 
37
 
34
AsyncSocket::~AsyncSocket()
38
AsyncSocket::~AsyncSocket()
35
{
39
{
36
    stop();
40
    stop();
Line 239... Line 243...
239
 
243
 
240
            case ENOTSOCK:
244
            case ENOTSOCK:
241
            throw new SocketException("sockfd is a descriptor for a file, not a socket.");
245
            throw new SocketException("sockfd is a descriptor for a file, not a socket.");
242
 
246
 
243
            //case EACCES:
247
            //case EACCES:
244
            //throw new SocketException("Search permission is denied on a component of the path prefix. (See also path_resolution(7).)");
248
            //throw new SocketException("Search permission is denied on a component of the path prefix. (See also path_resolution(7).)");
245
 
249
 
246
            case EADDRNOTAVAIL:
250
            case EADDRNOTAVAIL:
247
            throw new SocketException("A nonexistent interface was requested or the requested address was not local.");
251
            throw new SocketException("A nonexistent interface was requested or the requested address was not local.");
248
 
252
 
249
            case EFAULT:
253
            case EFAULT:
250
            throw new SocketException("addr points outside the user's accessible address space.");
254
            throw new SocketException("addr points outside the user's accessible address space.");
Line 261... Line 265...
261
            case ENOENT:
265
            case ENOENT:
262
            throw new SocketException("The file does not exist.");
266
            throw new SocketException("The file does not exist.");
263
 
267
 
264
            case ENOMEM:
268
            case ENOMEM:
265
            throw new SocketException("Insufficient kernel memory was available.");
269
            throw new SocketException("Insufficient kernel memory was available.");
266
 
270
 
267
            case ENOTDIR:
271
            case ENOTDIR:
268
            throw new SocketException("A component of the path prefix is not a directory.");
272
            throw new SocketException("A component of the path prefix is not a directory.");
269
 
273
 
270
            case EROFS:
274
            case EROFS:
271
            throw new SocketException("The socket inode would reside on a read-only file system.");
275
            throw new SocketException("The socket inode would reside on a read-only file system.");
272
 
276
 
273
            default:
277
            default:
274
            throw new SocketException("Unknow exception: " + itos(errno));
278
            throw new SocketException("Unknow exception: " + itos(errno));
275
            break;
279
            break;
276
        }
280
        }
277
    }
281
    }
278
 
282
 
279
    status = ::listen(mySocket, MAXCONNECTIONS);
283
    status = ::listen(mySocket, MAXCONNECTIONS);
280
 
284
 
281
    if (status == -1)
285
    if (status == -1)
282
    {
286
    {
283
        silentClose();
287
        silentClose();
284
        switch (errno)
288
        switch (errno)
285
        {
289
        {
Line 289... Line 293...
289
            case EBADF:
293
            case EBADF:
290
            throw new SocketException("The argument sockfd is not a valid descriptor.");
294
            throw new SocketException("The argument sockfd is not a valid descriptor.");
291
 
295
 
292
            case ENOTSOCK:
296
            case ENOTSOCK:
293
            throw new SocketException("The argument sockfd is not a socket.");
297
            throw new SocketException("The argument sockfd is not a socket.");
294
 
298
 
295
            case EOPNOTSUPP:
299
            case EOPNOTSUPP:
296
            throw new SocketException("The socket is not of a type that supports the listen() operation.");
300
            throw new SocketException("The socket is not of a type that supports the listen() operation.");
297
 
301
 
298
            default:
302
            default:
299
            throw new SocketException("Unknow exception: " + itos(errno));
303
            throw new SocketException("Unknow exception: " + itos(errno));
300
            break;
304
            break;
301
        }
305
        }
302
    }
306
    }
303
}
307
}
304
 
308
 
305
bool AsyncSocket::accept(AsyncSocket* newSocket)
309
bool AsyncSocket::accept(AsyncSocket* newSocket)
306
{
310
{
Line 309... Line 313...
309
 
313
 
310
    if (socket > 0)
314
    if (socket > 0)
311
    {
315
    {
312
        newSocket->setSocket(socket);
316
        newSocket->setSocket(socket);
313
        return true;
317
        return true;
314
    }
318
    }
315
 
319
 
316
    return false;
320
    return false;
317
}
321
}
318
 
322
 
319
void AsyncSocket::connect()
323
void AsyncSocket::connect()
320
{
324
{
321
    eventAdd(SocketEvent::TYPE_CONNECTING);
325
    eventAdd(SocketEvent::TYPE_CONNECTING);
322
 
326
 
323
    create();
327
    create();
324
 
328
 
325
    memset(&myAddressStruct, 0, sizeof(myAddressStruct));
329
    memset(&myAddressStruct, 0, sizeof(myAddressStruct));
326
 
330
 
327
    myAddressStruct.sin_family = AF_INET;
331
    myAddressStruct.sin_family = AF_INET;
328
    myAddressStruct.sin_port = htons(myPort);
332
    myAddressStruct.sin_port = htons(myPort);
329
 
333
 
330
    struct hostent *hptr = gethostbyname(myAddress.c_str());
334
    struct hostent *hptr = gethostbyname(myAddress.c_str());
331
    if (hptr == NULL)
335
    if (hptr == NULL)
332
    {
336
    {
333
        silentClose();
337
        silentClose();
334
        throw new SocketException("Connect: Could not resolv ip address");
338
        throw new SocketException("Connect: Could not resolv ip address");
335
    }
339
    }
336
 
340
 
337
    memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length);
341
    memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length);
338
 
342
 
339
    int status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct));
343
    int status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct));
340
 
344
 
341
    if (status == -1)
345
    if (status == -1)
Line 352... Line 356...
352
            case EADDRINUSE:
356
            case EADDRINUSE:
353
            throw new SocketException("Local address is already in use.");
357
            throw new SocketException("Local address is already in use.");
354
 
358
 
355
            case EAFNOSUPPORT:
359
            case EAFNOSUPPORT:
356
            throw new SocketException("The passed address didn't have the correct address family in its sa_family field.");
360
            throw new SocketException("The passed address didn't have the correct address family in its sa_family field.");
357
 
361
 
358
            case EAGAIN:
362
            case EAGAIN:
359
            throw new SocketException("No more free local ports or insufficient entries in the routing cache. For AF_INET see the net.ipv4.ip_local_port_range sysctl in ip(7) on how to increase the number of local ports.");
363
            throw new SocketException("No more free local ports or insufficient entries in the routing cache. For AF_INET see the net.ipv4.ip_local_port_range sysctl in ip(7) on how to increase the number of local ports.");
360
 
364
 
361
            case EALREADY:
365
            case EALREADY:
362
            throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed.");
366
            throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed.");
Line 464... Line 468...
464
}
468
}
465
 
469
 
466
void AsyncSocket::eventAdd(unsigned int eventType, string eventData)
470
void AsyncSocket::eventAdd(unsigned int eventType, string eventData)
467
{
471
{
468
    SocketEvent socketEvent(eventType, eventData);
472
    SocketEvent socketEvent(eventType, eventData);
-
 
473
 
-
 
474
    if (myEventCallback == NULL)
-
 
475
    {
469
    myEventQueue.push(socketEvent);
476
        myEventQueue.push(socketEvent);
470
    myEventSemaphore.broadcast();
477
        myEventSemaphore.broadcast();
-
 
478
    }
-
 
479
    else
-
 
480
    {
-
 
481
        myEventCallback->handleEvent(myId, socketEvent);
-
 
482
    }
-
 
483
}
-
 
484
 
-
 
485
void AsyncSocket::eventSetCallback(SocketEventCallback* eventCallback)
-
 
486
{
-
 
487
    myEventCallback = eventCallback;
471
}
488
}