17c006017SMilanka Ringwald /*
27c006017SMilanka Ringwald * Copyright (C) 2019 BlueKitchen GmbH
37c006017SMilanka Ringwald *
47c006017SMilanka Ringwald * Redistribution and use in source and binary forms, with or without
57c006017SMilanka Ringwald * modification, are permitted provided that the following conditions
67c006017SMilanka Ringwald * are met:
77c006017SMilanka Ringwald *
87c006017SMilanka Ringwald * 1. Redistributions of source code must retain the above copyright
97c006017SMilanka Ringwald * notice, this list of conditions and the following disclaimer.
107c006017SMilanka Ringwald * 2. Redistributions in binary form must reproduce the above copyright
117c006017SMilanka Ringwald * notice, this list of conditions and the following disclaimer in the
127c006017SMilanka Ringwald * documentation and/or other materials provided with the distribution.
137c006017SMilanka Ringwald * 3. Neither the name of the copyright holders nor the names of
147c006017SMilanka Ringwald * contributors may be used to endorse or promote products derived
157c006017SMilanka Ringwald * from this software without specific prior written permission.
167c006017SMilanka Ringwald * 4. Any redistribution, use, or modification is done solely for
177c006017SMilanka Ringwald * personal benefit and not for any commercial purpose or for
187c006017SMilanka Ringwald * monetary gain.
197c006017SMilanka Ringwald *
207c006017SMilanka Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
217c006017SMilanka Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
227c006017SMilanka Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
232fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
242fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
257c006017SMilanka Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
267c006017SMilanka Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
277c006017SMilanka Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
287c006017SMilanka Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
297c006017SMilanka Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
307c006017SMilanka Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
317c006017SMilanka Ringwald * SUCH DAMAGE.
327c006017SMilanka Ringwald *
337c006017SMilanka Ringwald * Please inquire about commercial licensing options at
347c006017SMilanka Ringwald * [email protected]
357c006017SMilanka Ringwald *
367c006017SMilanka Ringwald */
377c006017SMilanka Ringwald
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "obex_message_builder.c"
397c006017SMilanka Ringwald
407c006017SMilanka Ringwald #include "btstack_config.h"
417c006017SMilanka Ringwald
427c006017SMilanka Ringwald #include <stdint.h>
437c006017SMilanka Ringwald #include <stdlib.h>
447c006017SMilanka Ringwald
457c006017SMilanka Ringwald #include "btstack_util.h"
467c006017SMilanka Ringwald #include "btstack_debug.h"
477c006017SMilanka Ringwald #include "classic/obex.h"
487c006017SMilanka Ringwald #include "classic/obex_message_builder.h"
497c006017SMilanka Ringwald
50*7e1e42bbSMatthias Ringwald #if defined(ENABLE_LOG_DEBUG) || defined(ENABLE_LOG_ERROR)
51*7e1e42bbSMatthias Ringwald #define LUT(which) [which] = #which
52*7e1e42bbSMatthias Ringwald const char* lut_type[0xFF] = {
53*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_NAME),
54*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_DESCRIPTION),
55*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_IMG_HANDLE),
56*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_TYPE),
57*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_TIME_ISO_8601),
58*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_TARGET),
59*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_HTTP),
60*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_BODY),
61*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_END_OF_BODY),
62*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_WHO),
63*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_APPLICATION_PARAMETERS),
64*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_AUTHENTICATION_CHALLENGE),
65*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_AUTHENTICATION_RESPONSE),
66*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_OBJECT_CLASS),
67*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_IMG_DESCRIPTOR),
68*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_SINGLE_RESPONSE_MODE),
69*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_SINGLE_RESPONSE_MODE_PARAMETER),
70*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_COUNT),
71*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_LENGTH),
72*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_TIME_4_BYTE),
73*7e1e42bbSMatthias Ringwald LUT(OBEX_HEADER_CONNECTION_ID),
74*7e1e42bbSMatthias Ringwald };
75*7e1e42bbSMatthias Ringwald #endif
76*7e1e42bbSMatthias Ringwald
obex_message_builder_packet_init(uint8_t * buffer,uint16_t buffer_len,uint8_t opcode_or_response_code)778460ee57SMatthias Ringwald static uint8_t obex_message_builder_packet_init(uint8_t * buffer, uint16_t buffer_len, uint8_t opcode_or_response_code){
787c006017SMilanka Ringwald if (buffer_len < 3) return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
798460ee57SMatthias Ringwald buffer[0] = opcode_or_response_code;
807c006017SMilanka Ringwald big_endian_store_16(buffer, 1, 3);
817c006017SMilanka Ringwald return ERROR_CODE_SUCCESS;
827c006017SMilanka Ringwald }
837c006017SMilanka Ringwald
obex_message_builder_packet_append(uint8_t * buffer,uint16_t buffer_len,const uint8_t * data,uint16_t len)847c006017SMilanka Ringwald static uint8_t obex_message_builder_packet_append(uint8_t * buffer, uint16_t buffer_len, const uint8_t * data, uint16_t len){
857c006017SMilanka Ringwald uint16_t pos = big_endian_read_16(buffer, 1);
86*7e1e42bbSMatthias Ringwald
87*7e1e42bbSMatthias Ringwald log_debug("add type:0x%02x(%s) buffer_len:%u pos+len:%u pos:%u len:%u", data[0], lut_type[data[0]], buffer_len, pos + len, pos, len);
88*7e1e42bbSMatthias Ringwald
89*7e1e42bbSMatthias Ringwald if (buffer_len < pos + len) {
90*7e1e42bbSMatthias Ringwald log_error("ERROR_CODE_MEMORY_CAPACITY_EXCEEDED type:0x%02x(%s) buffer_len:%u size:%u pos:%u len:%u", buffer[0], lut_type[buffer[0]], buffer_len, pos + len, pos, len);
91*7e1e42bbSMatthias Ringwald return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
92*7e1e42bbSMatthias Ringwald }
93*7e1e42bbSMatthias Ringwald
946535961aSMatthias Ringwald (void)memcpy(&buffer[pos], data, len);
957c006017SMilanka Ringwald pos += len;
967c006017SMilanka Ringwald big_endian_store_16(buffer, 1, pos);
977c006017SMilanka Ringwald return ERROR_CODE_SUCCESS;
987c006017SMilanka Ringwald }
997c006017SMilanka Ringwald
obex_message_builder_get_message_length(uint8_t * buffer)1001f6020d5SMilanka Ringwald uint16_t obex_message_builder_get_message_length(uint8_t * buffer){
1011f6020d5SMilanka Ringwald return big_endian_read_16(buffer, 1);
1021f6020d5SMilanka Ringwald }
1031f6020d5SMilanka Ringwald
obex_message_builder_header_add_byte(uint8_t * buffer,uint16_t buffer_len,uint8_t header_type,uint8_t value)10481fb6ec9SMilanka Ringwald uint8_t obex_message_builder_header_add_byte(uint8_t * buffer, uint16_t buffer_len, uint8_t header_type, uint8_t value){
10581fb6ec9SMilanka Ringwald uint8_t header[2];
10681fb6ec9SMilanka Ringwald header[0] = header_type;
10781fb6ec9SMilanka Ringwald header[1] = value;
10881fb6ec9SMilanka Ringwald return obex_message_builder_packet_append(buffer, buffer_len, &header[0], sizeof(header));
10981fb6ec9SMilanka Ringwald }
11081fb6ec9SMilanka Ringwald
obex_message_builder_header_add_word(uint8_t * buffer,uint16_t buffer_len,uint8_t header_type,uint32_t value)11181fb6ec9SMilanka Ringwald uint8_t obex_message_builder_header_add_word(uint8_t * buffer, uint16_t buffer_len, uint8_t header_type, uint32_t value){
11281fb6ec9SMilanka Ringwald uint8_t header[5];
11381fb6ec9SMilanka Ringwald header[0] = header_type;
11481fb6ec9SMilanka Ringwald big_endian_store_32(header, 1, value);
11581fb6ec9SMilanka Ringwald return obex_message_builder_packet_append(buffer, buffer_len, &header[0], sizeof(header));
11681fb6ec9SMilanka Ringwald }
11781fb6ec9SMilanka Ringwald
obex_message_builder_header_add_variable(uint8_t * buffer,uint16_t buffer_len,uint8_t header_type,const uint8_t * header_data,uint16_t header_data_length)11881fb6ec9SMilanka Ringwald uint8_t obex_message_builder_header_add_variable(uint8_t * buffer, uint16_t buffer_len, uint8_t header_type, const uint8_t * header_data, uint16_t header_data_length){
1197c006017SMilanka Ringwald uint8_t header[3];
1207c006017SMilanka Ringwald header[0] = header_type;
1217c006017SMilanka Ringwald big_endian_store_16(header, 1, sizeof(header) + header_data_length);
1227c006017SMilanka Ringwald
1237c006017SMilanka Ringwald uint8_t status = obex_message_builder_packet_append(buffer, buffer_len, &header[0], sizeof(header));
1247c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
1257c006017SMilanka Ringwald
1267c006017SMilanka Ringwald return obex_message_builder_packet_append(buffer, buffer_len, header_data, header_data_length);
1277c006017SMilanka Ringwald }
1287c006017SMilanka Ringwald
obex_message_builder_header_fillup_variable(uint8_t * buffer,uint16_t buffer_len,uint8_t header_type,const uint8_t * header_data,uint16_t header_data_length,uint32_t * ret_length)12949df53afSSimon Budig uint8_t obex_message_builder_header_fillup_variable(uint8_t * buffer, uint16_t buffer_len, uint8_t header_type, const uint8_t * header_data, uint16_t header_data_length, uint32_t * ret_length){
13049df53afSSimon Budig uint8_t header[3];
13149df53afSSimon Budig header[0] = header_type;
1328eaca332SSimon Budig uint16_t pos = big_endian_read_16(buffer, 1);
13349df53afSSimon Budig
1348eaca332SSimon Budig if (sizeof (header) + header_data_length + pos > buffer_len)
1358eaca332SSimon Budig header_data_length = buffer_len - pos - sizeof (header);
13649df53afSSimon Budig
13749df53afSSimon Budig big_endian_store_16(header, 1, sizeof(header) + header_data_length);
13849df53afSSimon Budig *ret_length = 0;
13949df53afSSimon Budig uint8_t status = obex_message_builder_packet_append(buffer, buffer_len, &header[0], sizeof(header));
14049df53afSSimon Budig if (status != ERROR_CODE_SUCCESS) return status;
14149df53afSSimon Budig
14249df53afSSimon Budig *ret_length = header_data_length;
14349df53afSSimon Budig return obex_message_builder_packet_append(buffer, buffer_len, header_data, header_data_length);
14449df53afSSimon Budig }
14549df53afSSimon Budig
obex_message_builder_header_add_connection_id(uint8_t * buffer,uint16_t buffer_len,uint32_t obex_connection_id)1467c006017SMilanka Ringwald static uint8_t obex_message_builder_header_add_connection_id(uint8_t * buffer, uint16_t buffer_len, uint32_t obex_connection_id){
1477c006017SMilanka Ringwald // add connection_id header if set, must be first header if used
1487c006017SMilanka Ringwald if (obex_connection_id == OBEX_CONNECTION_ID_INVALID) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE;
1497c006017SMilanka Ringwald return obex_message_builder_header_add_word(buffer, buffer_len, OBEX_HEADER_CONNECTION_ID, obex_connection_id);
1507c006017SMilanka Ringwald }
1517c006017SMilanka Ringwald
obex_message_builder_create_connect(uint8_t * buffer,uint16_t buffer_len,uint8_t opcode,uint8_t obex_version_number,uint8_t flags,uint16_t maximum_obex_packet_length)1521f6020d5SMilanka Ringwald static inline uint8_t obex_message_builder_create_connect(uint8_t * buffer, uint16_t buffer_len, uint8_t opcode,
1531f6020d5SMilanka Ringwald uint8_t obex_version_number, uint8_t flags, uint16_t maximum_obex_packet_length){
1541f6020d5SMilanka Ringwald uint8_t status = obex_message_builder_packet_init(buffer, buffer_len, opcode);
1557c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
1567c006017SMilanka Ringwald
1577c006017SMilanka Ringwald uint8_t fields[4];
1587c006017SMilanka Ringwald fields[0] = obex_version_number;
1597c006017SMilanka Ringwald fields[1] = flags;
1607c006017SMilanka Ringwald big_endian_store_16(fields, 2, maximum_obex_packet_length);
1617c006017SMilanka Ringwald return obex_message_builder_packet_append(buffer, buffer_len, &fields[0], sizeof(fields));
1627c006017SMilanka Ringwald }
1637c006017SMilanka Ringwald
obex_message_builder_request_create_connect(uint8_t * buffer,uint16_t buffer_len,uint8_t obex_version_number,uint8_t flags,uint16_t maximum_obex_packet_length)1641f6020d5SMilanka Ringwald uint8_t obex_message_builder_request_create_connect(uint8_t * buffer, uint16_t buffer_len,
1651f6020d5SMilanka Ringwald uint8_t obex_version_number, uint8_t flags, uint16_t maximum_obex_packet_length){
1661f6020d5SMilanka Ringwald
1671f6020d5SMilanka Ringwald return obex_message_builder_create_connect(buffer, buffer_len, OBEX_OPCODE_CONNECT, obex_version_number, flags, maximum_obex_packet_length);
1681f6020d5SMilanka Ringwald }
1691f6020d5SMilanka Ringwald
obex_message_builder_response_create_connect(uint8_t * buffer,uint16_t buffer_len,uint8_t obex_version_number,uint8_t flags,uint16_t maximum_obex_packet_length,uint32_t obex_connection_id)1701f6020d5SMilanka Ringwald uint8_t obex_message_builder_response_create_connect(uint8_t * buffer, uint16_t buffer_len, uint8_t obex_version_number,
1711f6020d5SMilanka Ringwald uint8_t flags, uint16_t maximum_obex_packet_length, uint32_t obex_connection_id){
1721f6020d5SMilanka Ringwald
1731f6020d5SMilanka Ringwald uint8_t status = obex_message_builder_create_connect(buffer, buffer_len, OBEX_RESP_SUCCESS, obex_version_number, flags, maximum_obex_packet_length);
1741f6020d5SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
1751f6020d5SMilanka Ringwald return obex_message_builder_header_add_connection_id(buffer, buffer_len, obex_connection_id);
1761f6020d5SMilanka Ringwald }
1771f6020d5SMilanka Ringwald
obex_message_builder_response_create_general(uint8_t * buffer,uint16_t buffer_len,uint8_t response_code)1788460ee57SMatthias Ringwald uint8_t obex_message_builder_response_create_general(uint8_t * buffer, uint16_t buffer_len, uint8_t response_code){
1798460ee57SMatthias Ringwald return obex_message_builder_packet_init(buffer, buffer_len, response_code);
18009ef1e1eSMatthias Ringwald }
18109ef1e1eSMatthias Ringwald
obex_message_builder_response_update_code(uint8_t * buffer,uint16_t buffer_len,uint8_t response_code)182c2e0c88eSMatthias Ringwald uint8_t obex_message_builder_response_update_code(uint8_t * buffer, uint16_t buffer_len, uint8_t response_code){
183c2e0c88eSMatthias Ringwald if (buffer_len < 3) return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
184c2e0c88eSMatthias Ringwald buffer[0] = response_code;
185c2e0c88eSMatthias Ringwald return ERROR_CODE_SUCCESS;
186c2e0c88eSMatthias Ringwald }
187c2e0c88eSMatthias Ringwald
obex_message_builder_request_create_get(uint8_t * buffer,uint16_t buffer_len,uint32_t obex_connection_id)1887c006017SMilanka Ringwald uint8_t obex_message_builder_request_create_get(uint8_t * buffer, uint16_t buffer_len, uint32_t obex_connection_id){
1897c006017SMilanka Ringwald uint8_t status = obex_message_builder_packet_init(buffer, buffer_len, OBEX_OPCODE_GET | OBEX_OPCODE_FINAL_BIT_MASK);
1907c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
1917c006017SMilanka Ringwald return obex_message_builder_header_add_connection_id(buffer, buffer_len, obex_connection_id);
1927c006017SMilanka Ringwald }
1937c006017SMilanka Ringwald
obex_message_builder_request_create_put(uint8_t * buffer,uint16_t buffer_len,uint32_t obex_connection_id)1947c006017SMilanka Ringwald uint8_t obex_message_builder_request_create_put(uint8_t * buffer, uint16_t buffer_len, uint32_t obex_connection_id){
1957c006017SMilanka Ringwald uint8_t status = obex_message_builder_packet_init(buffer, buffer_len, OBEX_OPCODE_PUT | OBEX_OPCODE_FINAL_BIT_MASK);
1967c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
1977c006017SMilanka Ringwald
1987c006017SMilanka Ringwald return obex_message_builder_header_add_connection_id(buffer, buffer_len, obex_connection_id);
1997c006017SMilanka Ringwald }
2007c006017SMilanka Ringwald
obex_message_builder_request_create_set_path(uint8_t * buffer,uint16_t buffer_len,uint8_t flags,uint32_t obex_connection_id)2017c006017SMilanka Ringwald uint8_t obex_message_builder_request_create_set_path(uint8_t * buffer, uint16_t buffer_len, uint8_t flags, uint32_t obex_connection_id){
2027c006017SMilanka Ringwald uint8_t status = obex_message_builder_packet_init(buffer, buffer_len, OBEX_OPCODE_SETPATH);
2037c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
2047c006017SMilanka Ringwald
2057c006017SMilanka Ringwald uint8_t fields[2];
2067c006017SMilanka Ringwald fields[0] = flags;
2077c006017SMilanka Ringwald fields[1] = 0; // reserved
2087c006017SMilanka Ringwald status = obex_message_builder_packet_append(buffer, buffer_len, &fields[0], sizeof(fields));
2097c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
2107c006017SMilanka Ringwald return obex_message_builder_header_add_connection_id(buffer, buffer_len, obex_connection_id);
2117c006017SMilanka Ringwald }
2127c006017SMilanka Ringwald
obex_message_builder_request_create_abort(uint8_t * buffer,uint16_t buffer_len,uint32_t obex_connection_id)2137c006017SMilanka Ringwald uint8_t obex_message_builder_request_create_abort(uint8_t * buffer, uint16_t buffer_len, uint32_t obex_connection_id){
2147c006017SMilanka Ringwald uint8_t status = obex_message_builder_packet_init(buffer, buffer_len, OBEX_OPCODE_ABORT);
2157c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
2167c006017SMilanka Ringwald return obex_message_builder_header_add_connection_id(buffer, buffer_len, obex_connection_id);
2177c006017SMilanka Ringwald }
2187c006017SMilanka Ringwald
obex_message_builder_request_create_disconnect(uint8_t * buffer,uint16_t buffer_len,uint32_t obex_connection_id)2197c006017SMilanka Ringwald uint8_t obex_message_builder_request_create_disconnect(uint8_t * buffer, uint16_t buffer_len, uint32_t obex_connection_id){
2207c006017SMilanka Ringwald uint8_t status = obex_message_builder_packet_init(buffer, buffer_len, OBEX_OPCODE_DISCONNECT);
2217c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
2227c006017SMilanka Ringwald return obex_message_builder_header_add_connection_id(buffer, buffer_len, obex_connection_id);
2237c006017SMilanka Ringwald }
2247c006017SMilanka Ringwald
obex_message_builder_set_final_bit(uint8_t * buffer,uint16_t buffer_len,bool final)22549df53afSSimon Budig uint8_t obex_message_builder_set_final_bit (uint8_t * buffer, uint16_t buffer_len, bool final){
22649df53afSSimon Budig if (buffer_len < 1) return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
22749df53afSSimon Budig if (buffer[0] == OBEX_OPCODE_CONNECT ||
22849df53afSSimon Budig buffer[0] == OBEX_OPCODE_DISCONNECT ||
22949df53afSSimon Budig buffer[0] == OBEX_OPCODE_SETPATH ||
23049df53afSSimon Budig buffer[0] == OBEX_OPCODE_SESSION ||
23149df53afSSimon Budig buffer[0] == OBEX_OPCODE_ABORT){
23249df53afSSimon Budig return ERROR_CODE_COMMAND_DISALLOWED;
23349df53afSSimon Budig }
23449df53afSSimon Budig buffer[0] &= ~OBEX_OPCODE_FINAL_BIT_MASK;
23549df53afSSimon Budig buffer[0] |= (final ? OBEX_OPCODE_FINAL_BIT_MASK : 0);
23649df53afSSimon Budig return ERROR_CODE_SUCCESS;
23749df53afSSimon Budig }
23849df53afSSimon Budig
obex_message_builder_header_add_srm_enable(uint8_t * buffer,uint16_t buffer_len)2397c006017SMilanka Ringwald uint8_t obex_message_builder_header_add_srm_enable(uint8_t * buffer, uint16_t buffer_len){
240*7e1e42bbSMatthias Ringwald log_debug("SRM header enabled");
2417c006017SMilanka Ringwald return obex_message_builder_header_add_byte(buffer, buffer_len, OBEX_HEADER_SINGLE_RESPONSE_MODE, OBEX_SRM_ENABLE);
2427c006017SMilanka Ringwald }
2437c006017SMilanka Ringwald
obex_message_builder_header_add_srmp_wait(uint8_t * buffer,uint16_t buffer_len)244*7e1e42bbSMatthias Ringwald uint8_t obex_message_builder_header_add_srmp_wait(uint8_t* buffer, uint16_t buffer_len) {
245*7e1e42bbSMatthias Ringwald return obex_message_builder_header_add_byte(buffer, buffer_len, OBEX_HEADER_SINGLE_RESPONSE_MODE_PARAMETER, OBEX_SRMP_WAIT);
246*7e1e42bbSMatthias Ringwald }
247*7e1e42bbSMatthias Ringwald
obex_message_builder_header_add_target(uint8_t * buffer,uint16_t buffer_len,const uint8_t * target,uint16_t length)2487c006017SMilanka Ringwald uint8_t obex_message_builder_header_add_target(uint8_t * buffer, uint16_t buffer_len, const uint8_t * target, uint16_t length){
2497c006017SMilanka Ringwald return obex_message_builder_header_add_variable(buffer, buffer_len, OBEX_HEADER_TARGET, target, length);
2507c006017SMilanka Ringwald }
2517c006017SMilanka Ringwald
obex_message_builder_header_add_application_parameters(uint8_t * buffer,uint16_t buffer_len,const uint8_t * data,uint16_t length)2527c006017SMilanka Ringwald uint8_t obex_message_builder_header_add_application_parameters(uint8_t * buffer, uint16_t buffer_len, const uint8_t * data, uint16_t length){
2537c006017SMilanka Ringwald return obex_message_builder_header_add_variable(buffer, buffer_len, OBEX_HEADER_APPLICATION_PARAMETERS, data, length);
2547c006017SMilanka Ringwald }
2557c006017SMilanka Ringwald
obex_message_builder_header_add_challenge_response(uint8_t * buffer,uint16_t buffer_len,const uint8_t * data,uint16_t length)256c4466456SMilanka Ringwald uint8_t obex_message_builder_header_add_challenge_response(uint8_t * buffer, uint16_t buffer_len, const uint8_t * data, uint16_t length){
2577c006017SMilanka Ringwald return obex_message_builder_header_add_variable(buffer, buffer_len, OBEX_HEADER_AUTHENTICATION_RESPONSE, data, length);
2587c006017SMilanka Ringwald }
2597c006017SMilanka Ringwald
obex_message_builder_header_add_who(uint8_t * buffer,uint16_t buffer_len,const uint8_t * who)2601f6020d5SMilanka Ringwald uint8_t obex_message_builder_header_add_who(uint8_t * buffer, uint16_t buffer_len, const uint8_t * who){
2611f6020d5SMilanka Ringwald return obex_message_builder_header_add_variable(buffer, buffer_len, OBEX_HEADER_WHO, who, 16);
2621f6020d5SMilanka Ringwald }
2631f6020d5SMilanka Ringwald
obex_message_builder_body_add_static(uint8_t * buffer,uint16_t buffer_len,const uint8_t * data,uint32_t length)264948b3642SMilanka Ringwald uint8_t obex_message_builder_body_add_static(uint8_t * buffer, uint16_t buffer_len, const uint8_t * data, uint32_t length){
2657c006017SMilanka Ringwald return obex_message_builder_header_add_variable(buffer, buffer_len, OBEX_HEADER_END_OF_BODY, data, length);
2667c006017SMilanka Ringwald }
2677c006017SMilanka Ringwald
obex_message_builder_body_fillup_static(uint8_t * buffer,uint16_t buffer_len,const uint8_t * data,uint32_t length,uint32_t * ret_length)26849df53afSSimon Budig uint8_t obex_message_builder_body_fillup_static(uint8_t * buffer, uint16_t buffer_len, const uint8_t * data, uint32_t length, uint32_t *ret_length){
26949df53afSSimon Budig return obex_message_builder_header_fillup_variable(buffer, buffer_len, OBEX_HEADER_END_OF_BODY, data, length, ret_length);
27049df53afSSimon Budig }
27149df53afSSimon Budig
obex_message_builder_get_header_name_len_from_strlen(uint16_t name_len)272*7e1e42bbSMatthias Ringwald uint8_t obex_message_builder_get_header_name_len_from_strlen(uint16_t name_len) {
273*7e1e42bbSMatthias Ringwald
274*7e1e42bbSMatthias Ringwald // non-empty string have trailing \0
275*7e1e42bbSMatthias Ringwald bool add_trailing_zero = name_len > 0;
276*7e1e42bbSMatthias Ringwald return 1 + 2 + (name_len * 2) + (add_trailing_zero ? 2 : 0);
277*7e1e42bbSMatthias Ringwald }
278*7e1e42bbSMatthias Ringwald
obex_message_builder_header_add_unicode_prefix(uint8_t * buffer,uint16_t buffer_len,uint8_t header_id,const char * name,uint16_t name_len)279c1dd2356SMatthias Ringwald uint8_t obex_message_builder_header_add_unicode_prefix(uint8_t * buffer, uint16_t buffer_len, uint8_t header_id, const char * name, uint16_t name_len){
28095f75094SMatthias Ringwald // non-empty string have trailing \0
28195f75094SMatthias Ringwald bool add_trailing_zero = name_len > 0;
28295f75094SMatthias Ringwald
283*7e1e42bbSMatthias Ringwald uint16_t header_len = obex_message_builder_get_header_name_len_from_strlen(name_len);
28495f75094SMatthias Ringwald if (buffer_len < header_len) return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
2857c006017SMilanka Ringwald
2867c006017SMilanka Ringwald uint16_t pos = big_endian_read_16(buffer, 1);
287c1dd2356SMatthias Ringwald buffer[pos++] = header_id;
28895f75094SMatthias Ringwald big_endian_store_16(buffer, pos, header_len);
2897c006017SMilanka Ringwald pos += 2;
2907c006017SMilanka Ringwald int i;
2917c006017SMilanka Ringwald // @note name[len] == 0
2922946c1e3SMatthias Ringwald for (i = 0 ; i < name_len ; i++){
2937c006017SMilanka Ringwald buffer[pos++] = 0;
2947c006017SMilanka Ringwald buffer[pos++] = *name++;
2957c006017SMilanka Ringwald }
29695f75094SMatthias Ringwald if (add_trailing_zero){
29795f75094SMatthias Ringwald buffer[pos++] = 0;
29895f75094SMatthias Ringwald buffer[pos++] = 0;
29995f75094SMatthias Ringwald }
3007c006017SMilanka Ringwald big_endian_store_16(buffer, 1, pos);
3017c006017SMilanka Ringwald return ERROR_CODE_SUCCESS;
3027c006017SMilanka Ringwald }
303c1dd2356SMatthias Ringwald
obex_message_builder_header_add_name_prefix(uint8_t * buffer,uint16_t buffer_len,const char * name,uint16_t name_len)304c1dd2356SMatthias Ringwald uint8_t obex_message_builder_header_add_name_prefix(uint8_t * buffer, uint16_t buffer_len, const char * name, uint16_t name_len){
305c1dd2356SMatthias Ringwald return obex_message_builder_header_add_unicode_prefix(buffer, buffer_len, OBEX_HEADER_NAME, name, name_len);
306c1dd2356SMatthias Ringwald }
307c1dd2356SMatthias Ringwald
obex_message_builder_header_add_name(uint8_t * buffer,uint16_t buffer_len,const char * name)3082946c1e3SMatthias Ringwald uint8_t obex_message_builder_header_add_name(uint8_t * buffer, uint16_t buffer_len, const char * name){
309b56e8b56SMatthias Ringwald uint16_t name_len = (uint16_t) strlen(name);
310c1dd2356SMatthias Ringwald return obex_message_builder_header_add_unicode_prefix(buffer, buffer_len, OBEX_HEADER_NAME, name, name_len);
3112946c1e3SMatthias Ringwald }
3127c006017SMilanka Ringwald
obex_message_builder_get_header_type_len(char * type)313*7e1e42bbSMatthias Ringwald uint8_t obex_message_builder_get_header_type_len(char * type) {
314*7e1e42bbSMatthias Ringwald if (type == NULL)
315*7e1e42bbSMatthias Ringwald return 0; // type_header is ommited
316*7e1e42bbSMatthias Ringwald
317*7e1e42bbSMatthias Ringwald return (uint8_t) ( 1 // Header Encoding + ID
318*7e1e42bbSMatthias Ringwald + 2 // Length
319*7e1e42bbSMatthias Ringwald + strlen(type) // length of string in bytes
320*7e1e42bbSMatthias Ringwald + 1); // trailing \0
321*7e1e42bbSMatthias Ringwald }
322*7e1e42bbSMatthias Ringwald
obex_message_builder_header_add_type(uint8_t * buffer,uint16_t buffer_len,const char * type)3237c006017SMilanka Ringwald uint8_t obex_message_builder_header_add_type(uint8_t * buffer, uint16_t buffer_len, const char * type){
3247c006017SMilanka Ringwald uint8_t header[3];
3257c006017SMilanka Ringwald header[0] = OBEX_HEADER_TYPE;
326b56e8b56SMatthias Ringwald int len_incl_zero = (uint16_t) strlen(type) + 1;
3277c006017SMilanka Ringwald big_endian_store_16(header, 1, 1 + 2 + len_incl_zero);
3287c006017SMilanka Ringwald
3297c006017SMilanka Ringwald uint8_t status = obex_message_builder_packet_append(buffer, buffer_len, &header[0], sizeof(header));
3307c006017SMilanka Ringwald if (status != ERROR_CODE_SUCCESS) return status;
3317c006017SMilanka Ringwald return obex_message_builder_packet_append(buffer, buffer_len, (const uint8_t*)type, len_incl_zero);
3327c006017SMilanka Ringwald }
33349df53afSSimon Budig
obex_message_builder_header_add_length(uint8_t * buffer,uint16_t buffer_len,uint32_t length)33449df53afSSimon Budig uint8_t obex_message_builder_header_add_length(uint8_t * buffer, uint16_t buffer_len, uint32_t length){
33549df53afSSimon Budig return obex_message_builder_header_add_word(buffer, buffer_len, OBEX_HEADER_LENGTH, length);
33649df53afSSimon Budig }
337