Connection.cpp revision 9081ca65cb7959b6a06ba44823f84a6afa8bca2f
1/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
2 * @{
3 * @file
4 *
5 * Connection data.
6 *
7 * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote
18 *    products derived from this software without specific prior
19 *    written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33#include <unistd.h>
34#include <assert.h>
35#include <cstring>
36#include <errno.h>
37
38#include "Connection.h"
39
40//#define LOG_VERBOSE
41#include "log.h"
42
43
44//------------------------------------------------------------------------------
45Connection::Connection(
46    void
47) {
48	connectionData = NULL;
49	// Set invalid socketDescriptor
50	socketDescriptor = -1;
51}
52
53
54//------------------------------------------------------------------------------
55Connection::Connection(
56    int           socketDescriptor,
57    sockaddr_un   *remote
58) {
59	assert(NULL != remote);
60	assert(-1 != socketDescriptor);
61
62	this->socketDescriptor = socketDescriptor;
63	this->remote = *remote;
64	connectionData = NULL;
65}
66
67
68//------------------------------------------------------------------------------
69Connection::~Connection(
70    void
71) {
72	LOG_V(" closing Connection...");
73    if (socketDescriptor != -1)
74        close(socketDescriptor);
75    LOG_I(" Socket connection closed.");
76}
77
78
79//------------------------------------------------------------------------------
80bool Connection::connect(
81    const char *dest
82) {
83	bool ret = false;
84	int32_t len;
85
86	assert(NULL != dest);
87
88	LOG_I(" Connecting to %s socket", dest);
89	do {
90		remote.sun_family = AF_UNIX;
91		strncpy(remote.sun_path, dest, sizeof(remote.sun_path) - 1);
92		if ((socketDescriptor = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
93            LOG_ERRNO("Can't open stream socket.");
94			break;
95		}
96		len = strlen(remote.sun_path) + sizeof(remote.sun_family);
97		// The Daemon socket is in the Abstract Domain(LINUX ONLY!)
98		remote.sun_path[0] = 0;
99		if (::connect(socketDescriptor, (struct sockaddr *) &remote, len) < 0) {
100		    LOG_ERRNO("connect()");
101			break;
102		}
103		ret = true;
104	} while (false);
105
106	return ret;
107}
108
109
110//------------------------------------------------------------------------------
111size_t Connection::readData(
112    void *buffer,
113    uint32_t len
114) {
115    return readData(buffer, len, -1);
116}
117
118
119//------------------------------------------------------------------------------
120size_t Connection::readData(
121    void      *buffer,
122    uint32_t  len,
123    int32_t   timeout
124) {
125	size_t ret;
126	struct timeval tv;
127	struct timeval *ptv = NULL;
128    fd_set readfds;
129
130    assert(NULL != buffer);
131	assert(-1 != socketDescriptor);
132
133    do{
134
135        if(timeout >= 0){
136            // Calculate timeout value
137            tv.tv_sec = timeout/1000;
138            tv.tv_usec = (timeout - (tv.tv_sec * 1000)) * 1000;
139            ptv = &tv;
140        }
141
142        FD_ZERO(&readfds);
143        FD_SET(socketDescriptor, &readfds);
144        ret = select(socketDescriptor + 1, &readfds, NULL, NULL, ptv);
145
146        // check for read error
147        if (-1 == (int)ret) {
148            LOG_ERRNO("select");
149            break;
150        }
151
152        // Handle case of no descriptor ready
153        if (0 == ret) {
154            LOG_W(" Timeout during select() / No more notifications.");
155            ret = -2;
156            break;
157        }
158
159        // one or more descriptors are ready
160
161        // finally check if fd has been selected -> must socketDescriptor
162        if (!FD_ISSET(socketDescriptor, &readfds))
163        {
164            LOG_ERRNO("no fd is set, select");
165            break;
166        }
167
168        ret = recv(socketDescriptor, buffer, len, MSG_WAITALL);
169        if(0 == ret)
170        {
171            LOG_V(" readData(): peer orderly closed connection.");
172            break;
173        }
174//        if (ret != len)
175//        {
176//            LOG_ERRNO("could not receive all requested data because read");
177//            LOG_E("ret = %d", ret);
178//            ret = -1;
179//        }
180
181    }while(false);
182
183	return ret;
184}
185
186
187//------------------------------------------------------------------------------
188size_t Connection::writeData(
189    void *buffer,
190    uint32_t len
191) {
192	size_t ret;
193
194	assert(NULL != buffer);
195	assert(-1 != socketDescriptor);
196
197    ret = send(socketDescriptor, buffer, len, 0);
198    if (ret != len)
199    {
200        LOG_ERRNO("could not send all data, because send");
201        LOG_E("ret = %d", ret);
202        ret = -1;
203    }
204
205    return ret;
206}
207
208/** @} */
209