2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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.
18 #include "ptp_container.h"
19 #include "ptp_datacodes.h"
20 #include "mtp_transport.h"
21 #include "mtp_support.h"
27 void _hdlr_init_cmd_container(cmd_container_t *cntr)
30 cntr->type = CONTAINER_UNDEFINED;
31 cntr->code = PTP_OPCODE_UNDEFINED;
32 cntr->len = sizeof(header_container_t);
37 mtp_uint32 _hdlr_get_param_cmd_container(cmd_container_t *cntr,
40 if (index < cntr->no_param)
41 return cntr->params[index];
47 void _hdlr_copy_cmd_container_unknown_params(cmd_container_t *src,
53 dst->type = src->type;
54 dst->code = src->code;
57 (src->len - sizeof(header_container_t)) / sizeof(mtp_uint32);
59 for (ii = 0; ii < dst->no_param; ii++)
60 dst->params[ii] = src->params[ii];
66 void _hdlr_copy_cmd_container(cmd_container_t *src, cmd_container_t *dst)
71 dst->type = src->type;
72 dst->code = src->code;
74 dst->no_param = src->no_param;
76 for (ii = 0; ii < dst->no_param; ii++)
77 dst->params[ii] = src->params[ii];
82 mtp_bool _hdlr_add_param_resp_container(resp_blk_t *dst, mtp_uint32 num,
87 retvm_if(num > MAX_MTP_PARAMS, FALSE, "num(%d) exceed", num);
88 retvm_if(num != 0 && params == NULL, FALSE, "num = %d, params = %p", num, params);
91 dst->len = sizeof(header_container_t) + sizeof(mtp_uint32) * (dst->no_param);
93 for (ii = 0; ii < dst->no_param; ii++) {
94 dst->params[ii] = params[ii];
96 _util_conv_byte_order(&(dst->params[ii]),
97 sizeof(dst->params[ii]));
98 #endif /* __BIG_ENDIAN__ */
100 #ifdef __BIG_ENDIAN__
101 _util_conv_byte_order(&(dst->no_param), sizeof(dst->no_param));
102 _util_conv_byte_order(&(dst->len), sizeof(dst->len));
103 #endif /* __BIG_ENDIAN__ */
108 mtp_bool _hdlr_validate_cmd_container(mtp_uchar *blk, mtp_uint32 size)
110 if (size < sizeof(header_container_t) || size > sizeof(cmd_container_t))
113 /* LCOV_EXCL_START */
114 cmd_container_t *ptr = NULL;
116 ptr = (cmd_container_t *)blk;
118 if (ptr->len != size || ptr->type != CONTAINER_CMD_BLK) {
119 ERR("size = [%d] length[%d] type[%d]\n", size, ptr->len,
128 void _hdlr_init_data_container(data_container_t *dst, mtp_uint16 code,
131 _hdlr_init_cmd_container((cmd_container_t *)dst);
132 dst->type = CONTAINER_DATA_BLK;
136 #ifdef __BIG_ENDIAN__
137 _hdlr_conv_data_container_byte_order(dst);
138 #endif /* __BIG_ENDIAN__ */
142 mtp_uchar *_hdlr_alloc_buf_data_container(data_container_t *dst,
143 mtp_uint32 bufsz, mtp_uint64 pkt_size)
146 header_container_t *header = NULL;
148 pkt_size = (pkt_size + sizeof(header_container_t) > 0xFFFFFFFF) ?
149 0xFFFFFFFF : pkt_size + sizeof(header_container_t);
152 blk_len = bufsz + sizeof(header_container_t);
153 dst->data = (mtp_uchar *)g_malloc(blk_len);
154 if (dst->data == NULL) {
155 ERR("g_malloc() Fail");
159 memset(dst->data, 0, blk_len);
160 dst->len = bufsz + sizeof(header_container_t);
161 header = (header_container_t *)dst->data;
162 header->len = pkt_size;
163 #ifdef __BIG_ENDIAN__
164 _util_conv_byte_order(&(header->len), sizeof(header->len));
165 #endif /* __BIG_ENDIAN__ */
166 header->type = dst->type;
167 header->code = dst->code;
168 header->tid = dst->tid;
169 return (dst->data + sizeof(header_container_t));
172 /* LCOV_EXCL_START */
173 mtp_bool _hdlr_send_data_container(data_container_t *dst)
177 sent = _transport_send_pkt_to_tx_mq(dst->data, dst->len);
179 if (sent != dst->len)
185 mtp_bool _hdlr_send_bulk_data(mtp_uchar *dst, mtp_uint32 len)
189 sent = _transport_send_bulk_pkt_to_tx_mq(dst, len);
197 mtp_bool _hdlr_rcv_data_container(data_container_t *dst, mtp_uint32 size)
200 mtp_uint32 bytes_rcvd;
203 header_container_t *header = NULL;
208 /* Allocated space for data + header */
209 /* Also allocate extra space in case chip writes DWORDS */
211 blk_size = size + sizeof(header_container_t) + sizeof(mtp_uint32);
212 dst->data = (mtp_uchar *)g_malloc(blk_size);
213 if (dst->data == NULL) {
214 ERR("g_malloc() Fail");
219 _transport_rcv_temp_file_data(dst->data, blk_size, &bytes_rcvd);
220 exp_code = dst->code;
222 header = (header_container_t *)dst->data;
224 #ifdef __BIG_ENDIAN__
225 _hdlr_conv_data_container_byte_order((data_container_t *)dst->data);
226 #endif /* __BIG_ENDIAN__ */
228 /* Copy the header from the data block to the structure */
229 dst->len = header->len;
230 dst->type = header->type;
231 dst->code = header->code;
232 dst->tid = header->tid;
233 if (dst->len != bytes_rcvd || dst->type != CONTAINER_DATA_BLK ||
234 dst->code != exp_code || dst->tid != exp_tid) {
235 ERR("HEADER FAILURE");
236 ERR("HEADER length[%d], Type[%d], Code[%d], tid[%d]\n",
237 dst->len, dst->type, dst->code, dst->tid);
238 ERR("EXPECTED length[%d], Type[%d], Code[%d], tid[%d]\n",
239 bytes_rcvd, CONTAINER_DATA_BLK, exp_code, exp_tid);
246 /* LCOV_EXCL_START */
247 mtp_bool _hdlr_rcv_file_in_data_container(data_container_t *dst,
248 mtp_char *filepath, mtp_uint32 path_len)
251 mtp_uint64 bytes_rcvd;
254 header_container_t *header = NULL;
259 /* Allocated space for data + header */
260 /* Also allocate extra space in case chip writes DWORDS */
262 blk_size = sizeof(header_container_t) + sizeof(mtp_uint32);
263 dst->data = (mtp_uchar *)g_malloc((mtp_uint32) blk_size);
264 if (dst->data == NULL) {
265 ERR("g_malloc() Fail");
270 _transport_rcv_temp_file_info(dst->data, filepath, &bytes_rcvd,
272 exp_code = dst->code;
274 header = (header_container_t *)dst->data;
276 #ifdef __BIG_ENDIAN__
277 _hdlr_conv_data_container_byte_order((data_container_t *)dst->data);
278 #endif /* __BIG_ENDIAN__ */
280 /* Copy the header from the data block to the structure */
281 dst->len = header->len;
282 dst->type = header->type;
283 dst->code = header->code;
284 dst->tid = header->tid;
286 if ((dst->len != bytes_rcvd && bytes_rcvd < MTP_FILESIZE_4GB) ||
287 dst->type != CONTAINER_DATA_BLK ||
288 dst->code != exp_code || dst->tid != exp_tid) {
289 ERR("HEADER FAILURE");
290 ERR("HEADER length[%d], Type[%d], Code[%d], tid[%d]\n",
291 dst->len, dst->type, dst->code, dst->tid);
292 ERR("EXPECTED length[%llu], Type[%d], Code[%d], tid[%d]\n",
293 bytes_rcvd, CONTAINER_DATA_BLK, exp_code, exp_tid);
301 mtp_uint32 _hdlr_get_payload_size(data_container_t *dst)
303 if (dst->data == NULL) {
304 ERR("Payload data is NULL");
308 return (dst->len - sizeof(header_container_t));
311 mtp_uchar *_hdlr_get_payload_data(data_container_t *dst)
313 if (dst->data == NULL) {
314 ERR("Payload data is NULL");
318 return (dst->data + sizeof(header_container_t));
321 void _hdlr_resp_container_init(cmd_container_t *dst, mtp_uint16 resp_code,
324 _hdlr_init_cmd_container(dst);
325 dst->type = CONTAINER_RESP_BLK;
326 dst->code = resp_code;
328 #ifdef __BIG_ENDIAN__
329 _hdlr_conv_cmd_container_byte_order(dst);
330 #endif /* __BIG_ENDIAN__ */
334 /* LCOV_EXCL_START */
335 mtp_bool _hdlr_send_resp_container(cmd_container_t *dst)
339 #ifdef __BIG_ENDIAN__
342 _hdlr_copy_cmd_container(dst, &resp_blk);
343 _hdlr_conv_cmd_container_byte_order(&resp_blk);
344 sent = _transport_send_pkt_to_tx_mq((mtp_uchar *)&resp_blk, dst->len);
345 #else /* __BIG_ENDIAN__ */
347 sent = _transport_send_pkt_to_tx_mq((mtp_uchar *)dst, dst->len);
349 if (sent != dst->len) {
350 ERR("_transport_send_pkt_to_tx_mq() Fail: dst->len(%u), sent(%u)",
359 void _hdlr_init_event_container(cmd_container_t *dst, mtp_uint16 code,
360 mtp_uint32 tid, mtp_uint32 param1, mtp_uint32 param2)
362 dst->type = CONTAINER_EVENT_BLK;
366 dst->params[0] = param1;
367 dst->len = sizeof(header_container_t) + sizeof(mtp_uint32) * 1;
368 #ifdef __BIG_ENDIAN__
369 _hdlr_conv_cmd_container_byte_order(dst);
370 #endif /* __BIG_ENDIAN__ */
374 void _hdlr_init_event_container_with_param(cmd_container_t *dst,
375 mtp_uint16 code, mtp_uint32 tid, mtp_uint32 param1, mtp_uint32 param2)
377 dst->type = CONTAINER_EVENT_BLK;
381 dst->params[0] = param1;
382 dst->params[1] = param2;
383 dst->len = sizeof(header_container_t) + sizeof(mtp_uint32) * 3;
384 #ifdef __BIG_ENDIAN__
385 _hdlr_conv_cmd_container_byte_order(dst);
386 #endif /* __BIG_ENDIAN__ */
390 /* LCOV_EXCL_START */
391 mtp_bool _hdlr_send_event_container(cmd_container_t *dst)
396 retval = _transport_send_event((mtp_uchar *)dst, dst->len, &sent);
397 return (retval == MTP_ERROR_NONE && sent == dst->len) ?
402 void _hdlr_conv_cmd_container_byte_order(cmd_container_t *dst)
404 #ifdef __BIG_ENDIAN__
407 _util_conv_byte_order(&(dst->code), sizeof(dst->code));
408 _util_conv_byte_order(&(dst->len), sizeof(dst->len));
409 _util_conv_byte_order(&(dst->no_param), sizeof(dst->NumParams));
410 _util_conv_byte_order(&(dst->tid), sizeof(dst->tid));
411 _util_conv_byte_order(&(dst->type), sizeof(dst->Type));
413 for (idx = 0; idx < dst->no_param; idx++) {
414 _util_conv_byte_order(&(dst->params[idx]),
415 sizeof(dst->params[idx]));
417 #endif /* __BIG_ENDIAN__ */
421 void _hdlr_conv_data_container_byte_order(data_container_t *dst)
423 #ifdef __BIG_ENDIAN__
426 _util_conv_byte_order(&(dst->code), sizeof(dst->code));
427 _util_conv_byte_order(&(dst->len), sizeof(dst->len));
428 _util_conv_byte_order(&(dst->no_param), sizeof(dst->NumParams));
429 _util_conv_byte_order(&(dst->tid), sizeof(dst->tid));
430 _util_conv_byte_order(&(dst->type), sizeof(dst->Type));
431 for (idx = 0; idx < dst->no_param; idx++) {
432 _util_conv_byte_order(&(dst->params[idx]),
433 sizeof(dst->params[idx]));
435 #endif /* __BIG_ENDIAN__ */