[FEATURE] Implement kernel -> user connection
[platform/core/system/swap-manager.git] / daemon / da_protocol_inst.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  * Contributors:
23  * - Samsung RnD Institute Russia
24  *
25  */
26
27 #include "debug.h"
28 #include "da_protocol.h"
29 #include "da_protocol_inst.h"
30 #include "da_inst.h"
31 #include "da_protocol_check.h"
32
33 //----------------- hash
34 static uint32_t calc_lib_hash(struct us_lib_inst_t *lib)
35 {
36         uint32_t hash = 0;
37         char *p = lib->bin_path;
38         while (*p != 0) {
39                 hash <<= 1;
40                 hash += *p;
41                 p++;
42         }
43         return hash;
44 }
45
46 static uint32_t calc_app_hash(struct app_info_t *app)
47 {
48         uint32_t hash = 0;
49         char *p = app->exe_path;
50         while (*p != 0) {
51                 hash <<= 1;
52                 hash += *p;
53                 p++;
54         }
55         return hash;
56 }
57
58
59 //----------------------------------- parse -----------------------------------
60 static int parse_us_inst_func(struct msg_buf_t *msg, struct probe_list_t **dest)
61 {
62         //probe format
63         //name       | type   | len       | info
64         //------------------------------------------
65         //func_addr  | uint64 | 8         |
66         //args       | string | len(args) |end with '\0'
67         //ret_type   | char   | 1         |
68
69         uint32_t size = 0;
70         struct us_func_inst_plane_t *func;
71         int par_count = 0;
72         char *ret_type = NULL;
73
74         par_count = strlen(msg->cur_pos + sizeof(func->func_addr));
75         size = sizeof(*func) + par_count + 1 +
76                sizeof(char) /* sizeof(char) for ret_type */;
77         func = malloc(size);
78         if (!parse_int64(msg, &(func->func_addr))) {
79                 LOGE("func addr parsing error\n");
80                 goto err_ret;
81         }
82
83         if (!parse_string_no_alloc(msg, func->args) ||
84             !check_us_inst_func_args(func->args))
85         {
86                 LOGE("args format parsing error\n");
87                 goto err_ret;
88         }
89
90         //func->args type is char[0]
91         //and we need put ret_type after func->args
92         ret_type = func->args + par_count + 1;
93         if (!parse_int8(msg, (uint8_t *)ret_type) ||
94             !check_us_inst_func_ret_type(*ret_type))
95         {
96                 LOGE("return type parsing error\n");
97                 goto err_ret;
98         }
99
100         *dest = new_probe();
101         if (*dest == NULL) {
102                 LOGE("alloc new_probe error\n");
103                 goto err_ret;
104         }
105         (*dest)->size = size;
106         (*dest)->func = func;
107         return 1;
108 err_ret:
109         free(func);
110         return 0;
111 }
112
113 static int parse_func_inst_list(struct msg_buf_t *msg,
114                                 struct data_list_t *dest)
115 {
116         uint32_t i = 0, num = 0;
117         struct probe_list_t *probe_el;
118
119         if (!parse_int32(msg, &num) ||
120                 !check_us_app_inst_func_count(num))
121         {
122                 LOGE("func num parsing error\n");
123                 return 0;
124         }
125         //parse user space function list
126
127         parse_deb("app_int_num = %d\n", num);
128         for (i = 0; i < num; i++) {
129                 parse_deb("app_int #%d\n", i);
130                 if (!parse_us_inst_func(msg, &probe_el)) {
131                         // TODO maybe need to free allocated memory up there
132                         LOGE("parse us inst func #%d failed\n", i + 1);
133                         return 0;
134                 }
135                 probe_list_append(dest, probe_el);
136         }
137         dest->func_num = num;
138         return 1;
139 }
140
141 static int parse_inst_lib(struct msg_buf_t *msg, struct lib_list_t **dest)
142 {
143         *dest = new_lib();
144         if (*dest == NULL) {
145                 LOGE("lib alloc error\n");
146                 return 0;
147         };
148
149         if (!parse_string(msg, &((*dest)->lib->bin_path)) ||
150             !check_exec_path((*dest)->lib->bin_path))
151         {
152                 LOGE("bin path parsing error\n");
153                 return 0;
154         }
155
156         if (!parse_func_inst_list(msg, (struct data_list_t *) *dest)) {
157                 LOGE("funcs parsing error\n");
158                 return 0;
159         }
160
161         (*dest)->size +=  strlen((*dest)->lib->bin_path) + 1 + sizeof((*dest)->func_num);
162         (*dest)->hash = calc_lib_hash((*dest)->lib);
163         return 1;
164
165 }
166
167 int parse_lib_inst_list(struct msg_buf_t *msg,
168                         uint32_t *num,
169                         struct lib_list_t **lib_list)
170 {
171         uint32_t i = 0;
172         struct lib_list_t *lib = NULL;
173         if (!parse_int32(msg, num) ||
174                 !check_lib_inst_count(*num))
175         {
176                 LOGE("lib num parsing error\n");
177                 return 0;
178         }
179
180         for (i = 0; i < *num; i++) {
181                 if (!parse_inst_lib(msg, &lib)) {
182                         // TODO maybe need free allocated memory up there
183                         LOGE("parse is inst lib #%d failed\n", i + 1);
184                         return 0;
185                 }
186                 data_list_append((struct data_list_t **)lib_list,
187                                  (struct data_list_t *)lib);
188         }
189
190         return 1;
191 }
192
193 int parse_inst_app(struct msg_buf_t *msg, struct app_list_t **dest)
194 {
195         char *start, *end;
196         struct app_info_t *app_info = NULL;
197         *dest = new_app();
198
199         if (*dest == NULL) {
200                 LOGE("lib alloc error\n");
201                 return 0;
202         };
203
204         app_info = (*dest)->app;
205         start = msg->cur_pos;
206         if (!parse_int32(msg, &app_info->app_type) ||
207                 !check_app_type(app_info->app_type))
208         {
209                 LOGE("app type parsing error <0x%X>\n", app_info->app_type);
210                 return 0;
211         }
212
213         if (!parse_string(msg, &app_info->app_id) ||
214                 !check_app_id(app_info->app_type, app_info->app_id))
215         {
216                 LOGE("app id parsing error\n");
217                 return 0;
218         }
219         if (!parse_string(msg, &app_info->exe_path) ||
220                 !check_exec_path(app_info->exe_path))
221         {
222                 LOGE("exec path parsing error\n");
223                 return 0;
224         }
225         end = msg->cur_pos;
226
227         if (!parse_func_inst_list(msg, (struct data_list_t *)*dest)) {
228                 LOGE("funcs parsing error\n");
229                 return 0;
230         }
231
232         (*dest)->size += (end - start) + sizeof((*dest)->func_num);
233         (*dest)->hash = calc_app_hash(app_info);
234         return 1;
235 }
236
237 int parse_app_inst_list(struct msg_buf_t *msg,
238                         uint32_t *num,
239                         struct app_list_t  **app_list)
240 {
241         uint32_t i = 0;
242         struct app_list_t *app = NULL;
243         if (!parse_int32(msg, num) ||
244                 !check_lib_inst_count(*num))
245         {
246                 LOGE("app num parsing error\n");
247                 return 0;
248         }
249
250         parse_deb("app_int_num = %d\n", *num);
251         for (i = 0; i < *num; i++) {
252                 parse_deb("app_int #%d\n", i);
253                 if (!parse_inst_app(msg, &app)) {
254                         // TODO maybe need free allocated memory up there
255                         LOGE("parse is inst app #%d failed\n", i + 1);
256                         return 0;
257                 }
258                 data_list_append((struct data_list_t **)app_list,
259                                  (struct data_list_t *)app);
260         }
261
262         if (!parse_replay_event_seq(msg, &prof_session.replay_event_seq)) {
263                 LOGE("replay parsing error\n");
264                 return 0;
265         }
266
267         return 1;
268 }
269