2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 * @file client-common.cpp
18 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19 * @author Zofia Abramowska (z.abramowska@samsung.com)
21 * @brief This file is implementation of client-common functions.
26 #include <sys/types.h>
27 #include <sys/socket.h>
31 #include <dpl/errno_string.h>
32 #include <dpl/log/log.h>
33 #include <dpl/serialization.h>
34 #include <dpl/singleton.h>
35 #include <dpl/singleton_safe_impl.h>
37 #include <message-buffer.h>
39 #include <ckm/ckm-error.h>
41 #include <client-common.h>
43 IMPLEMENT_SAFE_SINGLETON(CKM::Log::LogSystem);
47 const int POLL_TIMEOUT = 8000;
49 void centKeyClientEnableLogSystem(void) {
50 CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM_CLIENT");
53 int waitForSocket(int sock, int event, int timeout) {
57 desc[0].events = event;
59 while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) {
65 LogDebug("Poll timeout");
66 } else if (-1 == retval) {
68 LogError("Error in poll: " << CKM::GetErrnoString(err));
73 } // namespace anonymous
78 int connectSocket(int& sock, char const * const interface) {
79 sockaddr_un clientAddr;
82 if (sock != -1) // guard
85 sock = socket(AF_UNIX, SOCK_STREAM, 0);
88 LogError("Error creating socket: " << GetErrnoString(err));
89 return CKM_API_ERROR_SOCKET;
92 if ((flags = fcntl(sock, F_GETFL, 0)) < 0 ||
93 fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0)
96 LogError("Error in fcntl: " << GetErrnoString(err));
97 return CKM_API_ERROR_SOCKET;
100 memset(&clientAddr, 0, sizeof(clientAddr));
102 clientAddr.sun_family = AF_UNIX;
104 if (strlen(interface) >= sizeof(clientAddr.sun_path)) {
105 LogError("Error: interface name " << interface << "is too long. Max len is:" <<
106 sizeof(clientAddr.sun_path));
107 return CKM_API_ERROR_SOCKET;
110 strcpy(clientAddr.sun_path, interface);
112 LogDebug("ClientAddr.sun_path = " << interface);
114 int retval = TEMP_FAILURE_RETRY(
115 connect(sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr)));
116 if ((retval == -1) && (errno == EINPROGRESS)) {
117 if (0 >= waitForSocket(sock, POLLOUT, POLL_TIMEOUT)) {
118 LogError("Error in waitForSocket.");
119 return CKM_API_ERROR_SOCKET;
122 socklen_t len = sizeof(error);
123 retval = getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len);
127 LogError("Error in getsockopt: " << GetErrnoString(err));
128 return CKM_API_ERROR_SOCKET;
131 if (error == EACCES) {
132 LogError("Access denied");
133 return CKM_API_ERROR_ACCESS_DENIED;
137 LogError("Error in connect: " << GetErrnoString(error));
138 return CKM_API_ERROR_SOCKET;
141 return CKM_API_SUCCESS;
146 LogError("Error connecting socket: " << GetErrnoString(err));
148 return CKM_API_ERROR_ACCESS_DENIED;
149 return CKM_API_ERROR_SOCKET;
152 return CKM_API_SUCCESS;
155 int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) {
161 if (CKM_API_SUCCESS != (ret = sock.Connect(interface))) {
162 LogError("Error in SockRAII");
166 while ((send.size() - done) > 0) {
167 if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
168 LogError("Error in poll(POLLOUT)");
169 return CKM_API_ERROR_SOCKET;
171 ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
174 LogError("Error in write: " << GetErrnoString(err));
175 return CKM_API_ERROR_SOCKET;
181 if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
182 LogError("Error in poll(POLLIN)");
183 return CKM_API_ERROR_SOCKET;
185 ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048));
188 LogError("Error in read: " << GetErrnoString(err));
189 return CKM_API_ERROR_SOCKET;
193 LogError("Read return 0/Connection closed by server(?)");
194 return CKM_API_ERROR_SOCKET;
197 RawBuffer raw(buffer, buffer+temp);
199 } while(!recv.Ready());
200 return CKM_API_SUCCESS;
203 int try_catch(const std::function<int()>& func)
207 } catch (MessageBuffer::Exception::Base &e) {
208 LogError("CKM::MessageBuffer::Exception " << e.DumpToString());
209 } catch (std::exception &e) {
210 LogError("STD exception " << e.what());
212 LogError("Unknown exception occured");
214 return CKM_API_ERROR_UNKNOWN;
217 void try_catch_async(const std::function<void()>& func, const std::function<void(int)>& error)
221 } catch (const MessageBuffer::Exception::Base& e) {
222 LogError("CKM::MessageBuffer::Exception " << e.DumpToString());
223 error(CKM_API_ERROR_BAD_REQUEST);
224 } catch (const std::exception& e) {
225 LogError("STD exception " << e.what());
226 error(CKM_API_ERROR_UNKNOWN);
228 LogError("Unknown exception occured");
229 error(CKM_API_ERROR_UNKNOWN);
235 static void init_lib(void) __attribute__ ((constructor));
236 static void init_lib(void)
238 centKeyClientEnableLogSystem();
241 static void fini_lib(void) __attribute__ ((destructor));
242 static void fini_lib(void)