Tizen 2.1 base
[platform/core/security/drm-client.git] / service / drm_client_ipc.cpp
1 /*\r
2  *  drm-client\r
3  *\r
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
5  *\r
6  * Contact: Hakjoo Ko <hakjoo.ko@samsung.com>\r
7  *                      Mahendra Kumar Prajapat <mahendra.p@samsung.com>\r
8  *                      Harsha Shekar <h.shekar@samsung.com>\r
9  *\r
10  *\r
11  * Licensed under the Apache License, Version 2.0 (the "License");\r
12  * you may not use this file except in compliance with the License.\r
13  * You may obtain a copy of the License at\r
14  *\r
15  * http://www.apache.org/licenses/LICENSE-2.0\r
16  *\r
17  * Unless required by applicable law or agreed to in writing, software\r
18  * distributed under the License is distributed on an "AS IS" BASIS,\r
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
20  * See the License for the specific language governing permissions and\r
21  * limitations under the License.\r
22  *\r
23  */\r
24 \r
25 /**\r
26  * @file                drm_client_ipc.cpp\r
27  * @brief       DRM Client Inter process communication definitions.\r
28  * @author      Mahendra Kumar Prajapat (mahendra.p@samsung.com)\r
29  * @author      Harsha Shekar (h.shekar@samsung.com)\r
30  * @author      Ravi S (ravi.cs@samsung.com)\r
31  * @version     0.1\r
32  * @history     0.1: DRM Client Inter process communication definitions.\r
33  */\r
34 \r
35 #include <stdio.h>\r
36 #include <stdlib.h>\r
37 #include <string.h>\r
38 #include <unistd.h>\r
39 #include <sys/stat.h>\r
40 #include <sys/un.h>\r
41 #include <sys/types.h>\r
42 #include <sys/socket.h>\r
43 #include <errno.h>\r
44 #include <pthread.h>\r
45 #include <signal.h>\r
46 \r
47 #include "drm_client_ipc.h"\r
48 #include "drm_client_log.h"\r
49 \r
50 \r
51 /**\r
52  * @brief Sync socket fd on a thread basis\r
53  */\r
54 static __thread int sockfd = -1;\r
55 \r
56 /**\r
57  * @brief Client info on a thread basis\r
58  */\r
59 static __thread drm_client_info_s client_info;\r
60 \r
61 /**\r
62  * @brief Async socket fd on a process basis\r
63  */\r
64 static int async_sockfd = -1;\r
65 \r
66 /**\r
67  * @brief Storing the registered callbacks\r
68  */\r
69 static drm_client_cb_info_s client_cb_info[DRM_MAX_CLIENT_SUPPORTED];\r
70 \r
71 /**\r
72  * @brief Mutex to serialise async socket per process\r
73  */\r
74 pthread_mutex_t async_mutex = PTHREAD_MUTEX_INITIALIZER;\r
75 \r
76 /**\r
77  * Library load time constructor\r
78  */\r
79 void __drm_client_lib_load_constructor (void) __attribute__((constructor));\r
80 \r
81 /**\r
82  * Library load time constructor\r
83  */\r
84 void __drm_client_lib_unload_destructor (void) __attribute__((destructor));\r
85 \r
86 \r
87 /**\r
88  * Constructor for library load time\r
89  *\r
90  *\r
91  * @param               void\r
92  * @return              void\r
93  * @remarks\r
94  * @see\r
95  * @since       0.1\r
96  */\r
97 void __drm_client_lib_load_constructor(void)\r
98 {\r
99         DRM_CLIENT_LOG("libdrm-client.so.0 loaded!!!");\r
100 }\r
101 \r
102 /**\r
103  * Destructor for library unload time\r
104  *\r
105  *\r
106  * @param               void\r
107  * @return              void\r
108  * @remarks\r
109  * @see\r
110  * @since       0.1\r
111  */\r
112 void __drm_client_lib_unload_destructor(void)\r
113 {\r
114         DRM_CLIENT_LOG("libdrm-client.so.0 unloaded!!!");\r
115 \r
116         /* Close the sockets */\r
117         DRM_CLIENT_LOG("Closing sockets!!");\r
118         if (sockfd >= 0) {\r
119                 close(sockfd);\r
120                 sockfd = -1;\r
121         }\r
122         if (async_sockfd >= 0) {\r
123                 close(async_sockfd);\r
124                 async_sockfd = -1;\r
125         }\r
126         DRM_CLIENT_LOG("Closed sockets!!");\r
127 }\r
128 \r
129 /**\r
130  *  Private function\r
131  *\r
132  *\r
133  * @param[in]   callinfo        Callback information\r
134  * @return              void\r
135  * @remarks\r
136  * @see\r
137  * @since       0.1\r
138  */\r
139 void __search_client_info_cb(drm_client_cb_data_s* callinfo)\r
140 {\r
141         int i = 0;\r
142         for (i = 0; i < DRM_MAX_CLIENT_SUPPORTED; i++) {\r
143 \r
144                 DRM_CLIENT_LOG("client_cb_info[i].client_id = %d", client_cb_info[i].client_id);\r
145                 DRM_CLIENT_LOG("callinfo->client_id = %d", callinfo->client_id);\r
146 \r
147                 if (client_cb_info[i].client_id == callinfo->client_id) {\r
148                         if (client_cb_info[i].operation_callback.callback) {\r
149 \r
150                                 client_cb_info[i].operation_callback.callback(\r
151                                                 &callinfo->callback_operation_info,\r
152                                                 &callinfo->call_bk_data);\r
153                         } else {\r
154                                 DRM_CLIENT_EXCEPTION("Callback function is NULL here!!!!");\r
155                         }\r
156                         /* Callback found, return from here */\r
157                         return;\r
158                 }\r
159         }\r
160 \r
161         if (DRM_MAX_CLIENT_SUPPORTED == i) {\r
162                 /* Client information for the process not yet stored */\r
163                 DRM_CLIENT_EXCEPTION("Callback information not stored!!, i = %d", i);\r
164                 return;\r
165         }\r
166 }\r
167 \r
168 /**\r
169  *  Private function\r
170  *      Thread handler\r
171  *\r
172  * @param[in]   thread_arg      Thread argument\r
173  * @return              void\r
174  * @remarks\r
175  * @see\r
176  * @since       0.1\r
177  */\r
178 void *client_async_cb_handler(void *thread_arg) {\r
179         drm_client_cb_data_s callinfo;\r
180         int retval = 0, result = 0;\r
181 \r
182         /* This Async thread will be running for the entire process alive time\r
183          * to handle all the async related operations sent from the server\r
184          */\r
185         while (1) {\r
186                 memset(&callinfo, 0x00, sizeof(drm_client_cb_data_s));\r
187                 retval = read(async_sockfd, &callinfo, sizeof(drm_client_cb_data_s));\r
188                 if (0 == retval) {\r
189                         DRM_CLIENT_LOG("Read returns 0!, retval = %d", retval);\r
190                         DRM_CLIENT_LOG("Server end closed!!!!");\r
191                         /* Since server end closes\r
192                          * async socket creation needs to be done again\r
193                          */\r
194                         goto ErrorExit;\r
195                 } else if (retval < 0 || retval < sizeof(drm_client_cb_data_s)) {\r
196                         DRM_CLIENT_EXCEPTION(\r
197                                         " Async call_back read error!!, retval = %d, error = %s",\r
198                                         retval, strerror(errno));\r
199                 }\r
200 \r
201                 DRM_CLIENT_LOG(\r
202                                 "Calling application  call back function from client, retval = %d",\r
203                                 retval);\r
204                 /* Search the client cb info from the received client_id and call corresponding handler */\r
205                 __search_client_info_cb(&callinfo);\r
206         }\r
207 \r
208 ErrorExit:\r
209         pthread_mutex_lock(&async_mutex);\r
210         if (async_sockfd >= 0) {\r
211                 close(async_sockfd);\r
212                 async_sockfd = -1;\r
213         }\r
214         pthread_mutex_unlock(&async_mutex);\r
215         return NULL;\r
216 }\r
217 \r
218 \r
219 \r
220 /**\r
221  *  Private function\r
222  *      Create Async socket\r
223  *\r
224  * @param[in]   client_in       Client request data\r
225  * @return              void\r
226  * @remarks\r
227  * @see\r
228  * @since       0.1\r
229  */\r
230 static int  __create_async_socket(drm_request_data_s *client_in)\r
231 {\r
232         struct sockaddr_un clientaddr;\r
233         int temp_len_sock = 0;\r
234         int retval = 0;\r
235         drm_result_e result = DRM_RETURN_SUCCESS;\r
236         pthread_t async_thread = 0;\r
237         int rv = 0;\r
238         /* Create a Async socket */\r
239         if ((async_sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)\r
240         {\r
241                 DRM_CLIENT_EXCEPTION("socket error!!, async_sockfd = %d, error = %s",async_sockfd, strerror(errno));\r
242                 result = DRM_RETURN_COMMUNICATION_ERROR;\r
243                 goto ErrorExit;\r
244         }\r
245         DRM_CLIENT_LOG(" async_sockfd created successful , async_sockfd = %d",async_sockfd);\r
246 \r
247         temp_len_sock = strlen(DRM_SOCK_PATH);\r
248         memset(&clientaddr, 0x00, sizeof(clientaddr));\r
249         clientaddr.sun_family = AF_UNIX;\r
250         memcpy(clientaddr.sun_path, DRM_SOCK_PATH, temp_len_sock);\r
251         clientaddr.sun_path[temp_len_sock] = '\0';\r
252 \r
253         /* connect to the server, on same server SOCK_PATH */\r
254         if ((retval = connect(async_sockfd, (struct sockaddr*) &clientaddr,sizeof(clientaddr))) < 0)\r
255         {\r
256                 DRM_CLIENT_EXCEPTION("Async socket connect error!!, retval = %d, error = %s",retval, strerror(errno));\r
257                 result = DRM_RETURN_COMMUNICATION_ERROR;\r
258                 goto ErrorExit;\r
259         }\r
260         DRM_CLIENT_LOG("async_sockfd Connection success retval=%d ", retval);\r
261 \r
262         /* Store the necessary information into the client info and send to server */\r
263         client_info.p_id = getpid();\r
264         client_info.thread_id = pthread_self();\r
265         client_info.client_id = client_info.p_id + client_info.thread_id;\r
266         DRM_CLIENT_LOG("Client_id = %d", client_info.client_id);\r
267         client_info.sync_sock_fd = -1;\r
268         client_info.async_sock_fd = async_sockfd;\r
269 \r
270         /* Send the server */\r
271         if ((retval = write(async_sockfd, (char*) &client_info,sizeof(client_info))) < 0|| retval < sizeof(client_info))\r
272         {\r
273                 DRM_CLIENT_EXCEPTION("Async write error!!, retval = %d, error = %s",retval, strerror(errno));\r
274                 result = DRM_RETURN_COMMUNICATION_ERROR;\r
275                 goto ErrorExit;\r
276         }\r
277         DRM_CLIENT_LOG("async_sockfd Sent info to server");\r
278 \r
279         /* Separate thread is created to handle async callback handling */\r
280         rv = pthread_create(&async_thread, NULL, client_async_cb_handler, NULL);\r
281         if (rv != 0) {\r
282                 DRM_CLIENT_EXCEPTION("pthread_create creation failed for Async socket");\r
283                 goto ErrorExit;\r
284         }\r
285         DRM_CLIENT_LOG("pthread_create success = [%d]", async_thread);\r
286         DRM_CLIENT_LOG("Async socket create success");\r
287         return 1;\r
288 \r
289 ErrorExit:\r
290         /* Prevent: 35135 [h.shekar]*/\r
291         if(async_sockfd >= 0) {\r
292                 close(async_sockfd);\r
293                 async_sockfd = -1;\r
294         }\r
295         return 0;\r
296 }\r
297 \r
298 /**\r
299  *  Private function\r
300  *      Create Sync socket\r
301  *\r
302  * @param[in]   client_in       Client request data\r
303  * @return              void\r
304  * @remarks\r
305  * @see\r
306  * @since       0.1\r
307  */\r
308 static int __get_socket(drm_request_data_s *client_in)\r
309 {\r
310         int fd;\r
311         int temp_len_sock = 0;\r
312         int retval = 0;\r
313         struct sockaddr_un clientaddr;\r
314         static int num_clients = 0;\r
315 \r
316         if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {\r
317                 DRM_CLIENT_EXCEPTION("sockfd socket create error!!, sockfd = %d, error = %s",fd, strerror(errno));\r
318                 goto ErrorExit;\r
319         }\r
320         DRM_CLIENT_LOG(" sockfd created successful , sockfd = %d",fd);\r
321 \r
322         /* Set parameters to be used in connect */\r
323         temp_len_sock = strlen(DRM_SOCK_PATH);\r
324         memset(&clientaddr, 0x00, sizeof(clientaddr));\r
325         clientaddr.sun_family = AF_UNIX;\r
326         memcpy(clientaddr.sun_path, DRM_SOCK_PATH, temp_len_sock);\r
327         clientaddr.sun_path[temp_len_sock] = '\0';\r
328 \r
329         if ((retval = connect(fd, (struct sockaddr*)&clientaddr,sizeof(clientaddr))) < 0)\r
330         {\r
331                 DRM_CLIENT_EXCEPTION("connect error!!, retval = %d, error = %s",retval, strerror(errno));\r
332                 goto ErrorExit;\r
333         }\r
334         DRM_CLIENT_LOG("sync socket is created sockfd = %d retval = %d",fd,retval);\r
335 \r
336         client_info.p_id = getpid();\r
337         client_info.thread_id = pthread_self();\r
338         client_info.client_id = client_info.p_id + client_info.thread_id;\r
339         DRM_CLIENT_LOG("Client_id = %d", client_info.client_id);\r
340         client_info.sync_sock_fd = fd;\r
341         client_info.async_sock_fd = async_sockfd;\r
342 \r
343         DRM_CLIENT_LOG("Writing socket sockfd = %d size=%d",fd,sizeof(client_info));\r
344 \r
345         DRM_CLIENT_LOG("client_info.client_id before send = %d", client_info.client_id);\r
346         if ((retval = write(fd, (char*) &client_info,sizeof(client_info))) < 0 || retval < sizeof(client_info))\r
347         {\r
348                 DRM_CLIENT_EXCEPTION("write error!!, retval = %d, error = %s",retval, strerror(errno));\r
349                 goto ErrorExit;\r
350         }\r
351         DRM_CLIENT_LOG("Written socket sockfd = %d retval=%d",fd,retval);\r
352         return fd;\r
353 \r
354 ErrorExit:\r
355 \r
356         /* Prevent: 35135 [h.shekar]*/\r
357         if (fd >= 0)\r
358                 close(fd);\r
359 \r
360         return -1;\r
361 }\r
362 \r
363 /**\r
364  *  This API is used to send a request to the Server to call corresponding API\r
365  *\r
366  * @param[in]   client_in       Carries the input parameters of Client API to Server\r
367  * @param[out]  server_out      Carries the output parameters of Client API from Server\r
368  * @return              0 on success & other values on failure\r
369  * @remarks\r
370  * @see\r
371  * @since 0.1\r
372  */\r
373 int drm_client_comm(drm_request_data_s *client_in, drm_response_data_s *server_out)\r
374 {\r
375         int retval = 0;\r
376         drm_request_data_s send_data;\r
377         drm_response_data_s recv_data;\r
378         drm_result_e result = DRM_RETURN_SUCCESS;\r
379         unsigned int offset = 0;\r
380         unsigned int bytes_write = DRM_MAX_CHUNK_SIZE;\r
381         unsigned int bytes_read = DRM_MAX_CHUNK_SIZE;\r
382 \r
383         /* memset the structures */\r
384         memset(&send_data, 0x0, sizeof(drm_request_data_s));\r
385         memset(&recv_data, 0x0, sizeof(drm_response_data_s));\r
386 \r
387         DRM_CLIENT_LOG("drm_client_comm in");\r
388 \r
389         /* Create Async socket if not created already for this process */\r
390         pthread_mutex_lock(&async_mutex);\r
391         if (-1 == async_sockfd) {\r
392                 DRM_CLIENT_LOG("Creating async socket for current process!!");\r
393                 if(!__create_async_socket(client_in))\r
394                 {\r
395                         DRM_CLIENT_EXCEPTION("__create_async_socket returned error");\r
396                         pthread_mutex_unlock(&async_mutex);\r
397                         goto ErrorExit;\r
398                 }\r
399         }\r
400         pthread_mutex_unlock(&async_mutex);\r
401 \r
402         /* Create Sync Socket on a per thread basis */\r
403         if (-1 == sockfd) {\r
404                 DRM_CLIENT_LOG("initial sockfd = %d", sockfd);\r
405                 sockfd = __get_socket(client_in);\r
406                 DRM_CLIENT_LOG("after get_socket sockfd = %d", sockfd);\r
407                 if (sockfd < 0) {\r
408                         DRM_CLIENT_EXCEPTION("get_socket failed sockfd = %d", sockfd);\r
409                         result = DRM_RETURN_COMMUNICATION_ERROR;\r
410                         goto ErrorExit;\r
411                 }\r
412         }\r
413 \r
414         /* Store the callback on a thread basis to be handled for each client */\r
415         DRM_CLIENT_LOG("Callback = %p", ((drm_initiator_info_s*) (client_in->fixed_data.request_data))->operation_callback.callback);\r
416         DRM_CLIENT_LOG("Client id = %d", client_info.client_id);\r
417 \r
418         if (((drm_initiator_info_s*) (client_in->fixed_data.request_data))->operation_callback.callback) {\r
419                 /* Callback present, store if not yet stored\r
420                  * Loop through the list checking for client id if stored */\r
421                 int loop = 0;\r
422                 for (; loop < DRM_MAX_CLIENT_SUPPORTED; loop++) {\r
423                         if (client_cb_info[loop].client_id == client_info.client_id) {\r
424                                 DRM_CLIENT_LOG("Callback info already stored!!, client_id[%d] = %d",\r
425                                                 loop, client_cb_info[loop].client_id);\r
426                                 break;\r
427                         } else if (client_cb_info[loop].client_id == 0) {\r
428                                 DRM_CLIENT_LOG("No entry for cb yet, loop = %d", loop);\r
429                                 DRM_CLIENT_LOG("Empty structure, storing client callback here, id = %d", client_info.client_id);\r
430                                 client_cb_info[loop].client_id = client_info.client_id;\r
431                                 memcpy(&client_cb_info[loop].operation_callback,\r
432                                                 &(((drm_initiator_info_s*) (client_in->fixed_data.request_data))->operation_callback),\r
433                                                 sizeof(drm_operation_cb_s));\r
434                                 break;\r
435                         }\r
436                 }\r
437                 if (DRM_MAX_CLIENT_SUPPORTED == loop) {\r
438                         DRM_CLIENT_LOG("loop = %d, Maximum clients reached!!!", loop);\r
439                 }\r
440         }\r
441 \r
442         /* Copy the data received from the client into local */\r
443         memcpy(&send_data, client_in, sizeof(drm_request_data_s));\r
444         /* First write the static structures */\r
445         DRM_CLIENT_LOG("Writing socket sockfd = %d size=%d",sockfd,sizeof(drm_req_fixed_data_s));\r
446         if ((retval = write(sockfd, (char*) &send_data.fixed_data,sizeof(drm_req_fixed_data_s))) < 0|| retval < sizeof(drm_req_fixed_data_s))\r
447         {\r
448                 DRM_CLIENT_EXCEPTION("write error!!, retval = %d, error = %s",retval, strerror(errno));\r
449                 result = DRM_RETURN_COMMUNICATION_ERROR;\r
450                 goto ErrorExit;\r
451         }\r
452         DRM_CLIENT_LOG("Written socket sockfd = %d retval=%d",sockfd,retval);\r
453 \r
454         /* Now send the additional data items if any */\r
455         if (send_data.fixed_data.num_data_items > 0) {\r
456                 for (unsigned int i = 0; i < send_data.fixed_data.num_data_items; i++)\r
457                 {\r
458                         if (send_data.fixed_data.data_length[i] > DRM_MAX_CHUNK_SIZE)\r
459                         {\r
460                                 while (bytes_write > 0)\r
461                                 {\r
462                                         DRM_CLIENT_LOG("Writing socket sockfd = %d size=%d",sockfd,bytes_write);\r
463                                         if ((retval = write(sockfd,(void*)(send_data.data_items[i] + offset), bytes_write)) < 0 || retval < bytes_write)\r
464                                         {\r
465                                                 DRM_CLIENT_EXCEPTION("write error!!, retval = %d, error = %s",retval, strerror(errno));\r
466                                                 result = DRM_RETURN_COMMUNICATION_ERROR;\r
467                                                 goto ErrorExit;\r
468                                         }\r
469                                         DRM_CLIENT_LOG("Written socket sockfd = %d retval=%d",sockfd,retval);\r
470                                         offset += DRM_MAX_CHUNK_SIZE;\r
471                                         bytes_write = (int)(send_data.fixed_data.data_length[i] - offset) > (int)DRM_MAX_CHUNK_SIZE ? DRM_MAX_CHUNK_SIZE :(int)(send_data.fixed_data.data_length[i] - offset);\r
472                                         DRM_CLIENT_LOG("offset = %d, bytes_write = %d", offset, bytes_write);\r
473                                 }\r
474                                 bytes_write = DRM_MAX_CHUNK_SIZE;\r
475                         }\r
476                         else\r
477                         {\r
478                                 DRM_CLIENT_LOG("Writing socket sockfd = %d size=%d",sockfd,send_data.fixed_data.data_length[i]);\r
479                                 if ((retval = write(sockfd, send_data.data_items[i], send_data.fixed_data.data_length[i])) < 0 || retval < send_data.fixed_data.data_length[i])\r
480                                 {\r
481                                         DRM_CLIENT_EXCEPTION("write error!!, retval = %d, error = %s",retval, strerror(errno));\r
482                                         result = DRM_RETURN_COMMUNICATION_ERROR;\r
483                                         goto ErrorExit;\r
484                                 }\r
485                                 DRM_CLIENT_LOG("Written socket sockfd = %d retval=%d",sockfd,retval);\r
486                         }\r
487                 }\r
488         }\r
489         /* Set offset to be used again */\r
490         offset = 0;\r
491         /* Read the fixed data into the receive structure */\r
492         DRM_CLIENT_LOG("Reading socket sockfd = %d size=%d",sockfd,sizeof(drm_resp_fixed_data_s));\r
493         if ((retval = read(sockfd, (char*) &recv_data.fixed_data,sizeof(drm_resp_fixed_data_s))) < 0 || retval < sizeof(drm_resp_fixed_data_s))\r
494         {\r
495                 DRM_CLIENT_EXCEPTION("read error!!, retval = %d, error = %s",retval, strerror(errno));\r
496                 result = DRM_RETURN_COMMUNICATION_ERROR;\r
497                 goto ErrorExit;\r
498         }\r
499         DRM_CLIENT_LOG("Read socket sockfd = %d retval=%d",sockfd,retval);\r
500         if (recv_data.fixed_data.num_data_items > 0) {\r
501                 for (unsigned int loop = 0; loop < recv_data.fixed_data.num_data_items; loop++)\r
502                 {\r
503                         /* Allocate memory for the data items */\r
504                         recv_data.data_items[loop] = (char*) malloc(recv_data.fixed_data.data_length[loop]);\r
505                         if (!recv_data.data_items[loop]) {\r
506                                 DRM_CLIENT_EXCEPTION("Memory Allocation Error!, buf = %p",recv_data.data_items[loop]);\r
507                                 recv_data.fixed_data.resp_result=DRM_RETURN_INSUFFICIENT_MEMORY;\r
508                                 goto ErrorExit;\r
509                         }\r
510                         if (recv_data.fixed_data.data_length[loop] > DRM_MAX_CHUNK_SIZE)\r
511                         {\r
512                                 while (bytes_read > 0)\r
513                                 {\r
514                                         DRM_CLIENT_LOG("Reading socket sockfd = %d size=%d",sockfd,bytes_read);\r
515                                         if ((retval = read(sockfd,(void*)(recv_data.data_items[loop] + offset),bytes_read)) < 0 || retval < bytes_read)\r
516                                         {\r
517                                                 DRM_CLIENT_EXCEPTION("Read error!!, retval = %d, error = %s", retval,strerror(errno));\r
518                                                 recv_data.fixed_data.resp_result=DRM_RETURN_COMMUNICATION_ERROR;\r
519                                                 goto ErrorExit;\r
520                                         }\r
521                                         DRM_CLIENT_LOG("Read socket sockfd = %d retval=%d",sockfd,retval);\r
522                                         offset += DRM_MAX_CHUNK_SIZE;\r
523                                         bytes_read = (int)(recv_data.fixed_data.data_length[loop] - offset) > (int) DRM_MAX_CHUNK_SIZE ? DRM_MAX_CHUNK_SIZE :(int)(recv_data.fixed_data.data_length[loop] - offset);\r
524                                         DRM_CLIENT_LOG("offset = %d, bytes_read = %d", offset, bytes_read);\r
525                                 }\r
526                                 bytes_read = DRM_MAX_CHUNK_SIZE;\r
527                         }\r
528                         else\r
529                         {\r
530                                 DRM_CLIENT_LOG("Reading socket sockfd = %d size=%d",sockfd,recv_data.fixed_data.data_length[loop]);\r
531                                 if ((retval = read(sockfd,recv_data.data_items[loop],recv_data.fixed_data.data_length[loop])) < 0 || retval < recv_data.fixed_data.data_length[loop])\r
532                                 {\r
533                                         DRM_CLIENT_EXCEPTION("Read error!!, retval = %d, error = %s",retval, strerror(errno));\r
534                                         recv_data.fixed_data.resp_result=DRM_RETURN_COMMUNICATION_ERROR;\r
535                                         goto ErrorExit;\r
536                                 }\r
537                                 DRM_CLIENT_LOG("Read socket sockfd = %d retval=%d",sockfd,retval);\r
538                         }\r
539                 }\r
540         }\r
541         /* Copy the data from the server back to the client into the output parameter */\r
542         memcpy(server_out, &recv_data, sizeof(drm_response_data_s));\r
543         DRM_CLIENT_LOG("drm_client_comm success!!!, result = %d", result);\r
544         return result;\r
545 \r
546         ErrorExit:\r
547         if (sockfd >= 0) {\r
548                 close(sockfd);\r
549                 sockfd = -1;\r
550         }\r
551         return result;\r
552 }\r