Etherios Cloud Connector very first porting for mbed. Tested in an LPC1768

Etherios Cloud Connector for Embedded v2.1.0.3 library for mbed. Early porting.

This port is centered mainly in the platform code. So it should work properly with the provided examples of send_data, device_request, data_points, RCI and firmware_update (stub implementation, not a real one... yet ;-)). Filesystem is not implemented yet, and some examples might need changes.

To run, it needs the following libraries: - mbed - mbed-rtos - EthernetInterface

Find more information (and the source code!) about Etherios Cloud Connector for Embedded here: http://www.etherios.com/products/devicecloud/support/connector and in: http://www.etherios.com

Committer:
spastor
Date:
Tue Dec 03 14:10:48 2013 +0000
Revision:
1:908afea5a49d
Parent:
0:1c358ea10753
Use internal Thread.h instead of Threads.h

Who changed what in which revision?

UserRevisionLine numberNew contents of line
spastor 0:1c358ea10753 1 /*
spastor 0:1c358ea10753 2 * Copyright (c) 2013 Digi International Inc.,
spastor 0:1c358ea10753 3 * All rights not expressly granted are reserved.
spastor 0:1c358ea10753 4 *
spastor 0:1c358ea10753 5 * This Source Code Form is subject to the terms of the Mozilla Public
spastor 0:1c358ea10753 6 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
spastor 0:1c358ea10753 7 * You can obtain one at http://mozilla.org/MPL/2.0/.
spastor 0:1c358ea10753 8 *
spastor 0:1c358ea10753 9 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
spastor 0:1c358ea10753 10 * =======================================================================
spastor 0:1c358ea10753 11 */
spastor 0:1c358ea10753 12
spastor 0:1c358ea10753 13 #define FS_TRUNC_FLAG 0x01
spastor 0:1c358ea10753 14 #define FS_IS_DIR_FLAG 0x01
spastor 0:1c358ea10753 15 #define FS_IS_REG_FLAG 0x02
spastor 0:1c358ea10753 16 #define FS_IS_LARGE_FLAG 0x02
spastor 0:1c358ea10753 17 #define FS_LS_SINGLE_FILE 0x10
spastor 0:1c358ea10753 18 #define FS_ERROR_INTERNAL_FLAG 0x40
spastor 0:1c358ea10753 19 #define FS_SESSION_ERROR_CALLED 0x80
spastor 0:1c358ea10753 20
spastor 0:1c358ea10753 21 #define FS_OPCODE_BYTES 1
spastor 0:1c358ea10753 22
spastor 0:1c358ea10753 23 typedef enum
spastor 0:1c358ea10753 24 {
spastor 0:1c358ea10753 25 fs_get_request_opcode = 1,
spastor 0:1c358ea10753 26 fs_get_response_opcode,
spastor 0:1c358ea10753 27 fs_put_request_opcode,
spastor 0:1c358ea10753 28 fs_put_response_opcode,
spastor 0:1c358ea10753 29 fs_ls_request_opcode,
spastor 0:1c358ea10753 30 fs_ls_response_opcode,
spastor 0:1c358ea10753 31 fs_rm_request_opcode,
spastor 0:1c358ea10753 32 fs_rm_response_opcode,
spastor 0:1c358ea10753 33 fs_error_opcode = 200
spastor 0:1c358ea10753 34 } fs_opcode_t;
spastor 0:1c358ea10753 35
spastor 0:1c358ea10753 36 typedef enum
spastor 0:1c358ea10753 37 {
spastor 0:1c358ea10753 38 fs_state_none,
spastor 0:1c358ea10753 39 fs_state_stat,
spastor 0:1c358ea10753 40 fs_state_open,
spastor 0:1c358ea10753 41 fs_state_lseek1,
spastor 0:1c358ea10753 42 fs_state_lseek,
spastor 0:1c358ea10753 43 fs_state_readdir,
spastor 0:1c358ea10753 44 fs_state_stat_dir_entry,
spastor 0:1c358ea10753 45 fs_state_closing,
spastor 0:1c358ea10753 46 fs_state_closed
spastor 0:1c358ea10753 47 }fs_state_t;
spastor 0:1c358ea10753 48
spastor 0:1c358ea10753 49 typedef struct
spastor 0:1c358ea10753 50 {
spastor 0:1c358ea10753 51 void * user_context;
spastor 0:1c358ea10753 52 void * errnum;
spastor 0:1c358ea10753 53 } fs_user_data;
spastor 0:1c358ea10753 54
spastor 0:1c358ea10753 55 typedef struct
spastor 0:1c358ea10753 56 {
spastor 0:1c358ea10753 57 void * user_context;
spastor 0:1c358ea10753 58 void * errnum;
spastor 0:1c358ea10753 59
spastor 0:1c358ea10753 60 void * handle;
spastor 0:1c358ea10753 61
spastor 0:1c358ea10753 62 union
spastor 0:1c358ea10753 63 {
spastor 0:1c358ea10753 64 struct
spastor 0:1c358ea10753 65 {
spastor 0:1c358ea10753 66 uint32_t bytes_done;
spastor 0:1c358ea10753 67 uint32_t data_length;
spastor 0:1c358ea10753 68 connector_file_offset_t offset;
spastor 0:1c358ea10753 69 } f;
spastor 0:1c358ea10753 70 struct
spastor 0:1c358ea10753 71 {
spastor 0:1c358ea10753 72 char path[CONNECTOR_FILE_SYSTEM_MAX_PATH_LENGTH];
spastor 0:1c358ea10753 73 size_t path_len;
spastor 0:1c358ea10753 74 uint32_t last_modified;
spastor 0:1c358ea10753 75 connector_file_offset_t file_size;
spastor 0:1c358ea10753 76 connector_file_system_hash_algorithm_t hash_alg;
spastor 0:1c358ea10753 77 } d;
spastor 0:1c358ea10753 78 }data;
spastor 0:1c358ea10753 79
spastor 0:1c358ea10753 80 fs_opcode_t opcode;
spastor 0:1c358ea10753 81 connector_status_t status;
spastor 0:1c358ea10753 82 fs_state_t state;
spastor 0:1c358ea10753 83 uint8_t flags;
spastor 0:1c358ea10753 84
spastor 0:1c358ea10753 85 } fs_context_t;
spastor 0:1c358ea10753 86
spastor 0:1c358ea10753 87 #define FsIsOpen(context) (((context)!=NULL) && ((context)->state >= fs_state_open) && ((context)->state < fs_state_closed))
spastor 0:1c358ea10753 88
spastor 0:1c358ea10753 89 #define FsIsBitSet(flag, bit) (((flag) & (bit)) == (bit))
spastor 0:1c358ea10753 90 #define FsBitSet(flag, bit) ((flag) |= (bit))
spastor 0:1c358ea10753 91 #define FsBitClear(flag, bit) ((flag) &= ~(bit))
spastor 0:1c358ea10753 92
spastor 0:1c358ea10753 93 #define FsIsDir(context) FsIsBitSet(context->flags, FS_IS_DIR_FLAG)
spastor 0:1c358ea10753 94 #define FsSetDir(context) FsBitSet(context->flags, FS_IS_DIR_FLAG)
spastor 0:1c358ea10753 95 #define FsClearDir(context) FsBitClear(context->flags, FS_IS_DIR_FLAG)
spastor 0:1c358ea10753 96
spastor 0:1c358ea10753 97 #define FsIsReg(context) FsIsBitSet(context->flags, FS_IS_REG_FLAG)
spastor 0:1c358ea10753 98 #define FsSetReg(context) FsBitSet(context->flags, FS_IS_REG_FLAG)
spastor 0:1c358ea10753 99 #define FsClearReg(context) FsBitClear(context->flags, FS_IS_REG_FLAG)
spastor 0:1c358ea10753 100
spastor 0:1c358ea10753 101 #define FsNeedTrunc(context) FsIsBitSet(context->flags, FS_TRUNC_FLAG)
spastor 0:1c358ea10753 102 #define FsSetTrunc(context) FsBitSet(context->flags, FS_TRUNC_FLAG)
spastor 0:1c358ea10753 103 #define FsClearTrunc(context) FsBitClear(context->flags, FS_TRUNC_FLAG)
spastor 0:1c358ea10753 104
spastor 0:1c358ea10753 105 #define FsIsLsSingleFile(context) FsIsBitSet(context->flags, FS_LS_SINGLE_FILE)
spastor 0:1c358ea10753 106 #define FsSetLsSingleFile(context) FsBitSet(context->flags, FS_LS_SINGLE_FILE)
spastor 0:1c358ea10753 107
spastor 0:1c358ea10753 108 #define FsHasInternalError(context) FsIsBitSet(context->flags, FS_ERROR_INTERNAL_FLAG)
spastor 0:1c358ea10753 109 #define FsSetInternalError(context, error) {FsBitSet(context->flags,FS_ERROR_INTERNAL_FLAG); context->errnum=(void *)error;}
spastor 0:1c358ea10753 110
spastor 0:1c358ea10753 111 #define FsSessionErrorCalled(context) FsIsBitSet(context->flags, FS_SESSION_ERROR_CALLED)
spastor 0:1c358ea10753 112 #define FsSetSessionErrorCalled(context) FsBitSet(context->flags, FS_SESSION_ERROR_CALLED)
spastor 0:1c358ea10753 113
spastor 0:1c358ea10753 114 #define FsSetState(context, s) (context->state = s)
spastor 0:1c358ea10753 115 #define FsGetState(context) (context->state)
spastor 0:1c358ea10753 116
spastor 0:1c358ea10753 117
spastor 0:1c358ea10753 118 #define FsOperationSuccess(status, context) (status==connector_working && context->errnum==NULL)
spastor 0:1c358ea10753 119
spastor 0:1c358ea10753 120 static void fs_set_service_error(msg_service_request_t * const service_request, connector_session_error_t const session_error)
spastor 0:1c358ea10753 121 {
spastor 0:1c358ea10753 122 service_request->error_value = session_error;
spastor 0:1c358ea10753 123 service_request->service_type = msg_service_type_error;
spastor 0:1c358ea10753 124 }
spastor 0:1c358ea10753 125
spastor 0:1c358ea10753 126 static connector_status_t fs_set_abort(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 127 fs_context_t * const context,
spastor 0:1c358ea10753 128 connector_request_id_file_system_t const file_request,
spastor 0:1c358ea10753 129 connector_status_t const error_status)
spastor 0:1c358ea10753 130 {
spastor 0:1c358ea10753 131
spastor 0:1c358ea10753 132 connector_request_id_t request_id;
spastor 0:1c358ea10753 133 request_id.file_system_request = file_request;
spastor 0:1c358ea10753 134
spastor 0:1c358ea10753 135 notify_error_status(connector_ptr->callback, connector_class_id_file_system, request_id, error_status);
spastor 0:1c358ea10753 136 context->status = connector_abort;
spastor 0:1c358ea10753 137 return context->status;
spastor 0:1c358ea10753 138 }
spastor 0:1c358ea10753 139
spastor 0:1c358ea10753 140 typedef enum
spastor 0:1c358ea10753 141 {
spastor 0:1c358ea10753 142 fs_error_path_too_long,
spastor 0:1c358ea10753 143 fs_error_format,
spastor 0:1c358ea10753 144 fs_error_invalid_offset,
spastor 0:1c358ea10753 145 fs_error_invalid_hash,
spastor 0:1c358ea10753 146 fs_error_generic,
spastor 0:1c358ea10753 147 fs_error_large_file,
spastor 0:1c358ea10753 148 fs_error_session_canceled
spastor 0:1c358ea10753 149 }fs_error_internal_t;
spastor 0:1c358ea10753 150
spastor 0:1c358ea10753 151 static void fs_get_internal_error_data(connector_file_system_get_error_t * const data)
spastor 0:1c358ea10753 152 {
spastor 0:1c358ea10753 153
spastor 0:1c358ea10753 154 unsigned long int code = (unsigned long int) data->errnum;
spastor 0:1c358ea10753 155
spastor 0:1c358ea10753 156 static struct
spastor 0:1c358ea10753 157 {
spastor 0:1c358ea10753 158 char const * hint;
spastor 0:1c358ea10753 159 connector_file_system_error_t status;
spastor 0:1c358ea10753 160
spastor 0:1c358ea10753 161 } error_data[] =
spastor 0:1c358ea10753 162 {
spastor 0:1c358ea10753 163 {"Path too long", connector_file_system_out_of_memory},
spastor 0:1c358ea10753 164 {"Request format error", connector_file_system_request_format_error},
spastor 0:1c358ea10753 165 {"Invalid offset", connector_file_system_invalid_parameter},
spastor 0:1c358ea10753 166 {"Invalid hash algorithm", connector_file_system_invalid_parameter},
spastor 0:1c358ea10753 167 {"Unspecified error", connector_file_system_unspec_error},
spastor 0:1c358ea10753 168 {"Offset is too large or negative", connector_file_system_request_format_error}
spastor 0:1c358ea10753 169 };
spastor 0:1c358ea10753 170
spastor 0:1c358ea10753 171 switch(code)
spastor 0:1c358ea10753 172 {
spastor 0:1c358ea10753 173 case fs_error_path_too_long:
spastor 0:1c358ea10753 174 case fs_error_format:
spastor 0:1c358ea10753 175 case fs_error_invalid_offset:
spastor 0:1c358ea10753 176 case fs_error_invalid_hash:
spastor 0:1c358ea10753 177 case fs_error_generic:
spastor 0:1c358ea10753 178 case fs_error_large_file:
spastor 0:1c358ea10753 179 break;
spastor 0:1c358ea10753 180
spastor 0:1c358ea10753 181 default:
spastor 0:1c358ea10753 182 ASSERT(connector_false);
spastor 0:1c358ea10753 183 code = fs_error_generic;
spastor 0:1c358ea10753 184 break;
spastor 0:1c358ea10753 185 }
spastor 0:1c358ea10753 186 ASSERT(code < asizeof(error_data));
spastor 0:1c358ea10753 187
spastor 0:1c358ea10753 188 data->error_status = error_data[code].status;
spastor 0:1c358ea10753 189 data->bytes_used = MIN_VALUE(data->bytes_available, strlen(error_data[code].hint));
spastor 0:1c358ea10753 190 memcpy(data->buffer, error_data[code].hint, data->bytes_used);
spastor 0:1c358ea10753 191 }
spastor 0:1c358ea10753 192
spastor 0:1c358ea10753 193 static connector_status_t format_file_error_msg(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 194 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 195 fs_context_t * const context)
spastor 0:1c358ea10753 196 {
spastor 0:1c358ea10753 197 connector_status_t status = connector_working;
spastor 0:1c358ea10753 198
spastor 0:1c358ea10753 199 if (service_request->service_type != msg_service_type_error)
spastor 0:1c358ea10753 200 {
spastor 0:1c358ea10753 201 /* 1st message so let's parse message-start packet:
spastor 0:1c358ea10753 202 *
spastor 0:1c358ea10753 203 * File System Get request format:
spastor 0:1c358ea10753 204 * ------------------------------------------------------
spastor 0:1c358ea10753 205 * | 0 | +1 | +1 | +N |
spastor 0:1c358ea10753 206 * ------------------------------------------------------
spastor 0:1c358ea10753 207 * | Opcode | Error code | Error Hint Length | Error hint |
spastor 0:1c358ea10753 208 * ------------------------------------------------------
spastor 0:1c358ea10753 209 *
spastor 0:1c358ea10753 210 */
spastor 0:1c358ea10753 211 enum {
spastor 0:1c358ea10753 212 field_define(fs_error_response, opcode, uint8_t),
spastor 0:1c358ea10753 213 field_define(fs_error_response, error_code, uint8_t),
spastor 0:1c358ea10753 214 field_define(fs_error_response, error_hint_len, uint8_t),
spastor 0:1c358ea10753 215 record_end(fs_error_response_header)
spastor 0:1c358ea10753 216 };
spastor 0:1c358ea10753 217
spastor 0:1c358ea10753 218 msg_service_data_t * const service_data = service_request->need_data;
spastor 0:1c358ea10753 219
spastor 0:1c358ea10753 220 size_t const header_bytes = record_bytes(fs_error_response_header);
spastor 0:1c358ea10753 221 size_t const buffer_size = MIN_VALUE(service_data->length_in_bytes - header_bytes, UCHAR_MAX);
spastor 0:1c358ea10753 222
spastor 0:1c358ea10753 223 uint8_t * fs_error_response = service_data->data_ptr;
spastor 0:1c358ea10753 224 connector_file_system_get_error_t data;
spastor 0:1c358ea10753 225
spastor 0:1c358ea10753 226 data.buffer = fs_error_response + header_bytes;
spastor 0:1c358ea10753 227 data.errnum = context->errnum;
spastor 0:1c358ea10753 228 data.bytes_available = buffer_size;
spastor 0:1c358ea10753 229 data.bytes_used = 0;
spastor 0:1c358ea10753 230
spastor 0:1c358ea10753 231 if (FsHasInternalError(context))
spastor 0:1c358ea10753 232 {
spastor 0:1c358ea10753 233 fs_get_internal_error_data(&data);
spastor 0:1c358ea10753 234 }
spastor 0:1c358ea10753 235 else
spastor 0:1c358ea10753 236 {
spastor 0:1c358ea10753 237 connector_request_id_t request_id;
spastor 0:1c358ea10753 238 data.user_context = context->user_context;
spastor 0:1c358ea10753 239 request_id.file_system_request = connector_request_id_file_system_get_error;
spastor 0:1c358ea10753 240
spastor 0:1c358ea10753 241 status = connector_callback(connector_ptr->callback,
spastor 0:1c358ea10753 242 connector_class_id_file_system,
spastor 0:1c358ea10753 243 request_id,
spastor 0:1c358ea10753 244 &data) == connector_callback_continue ?
spastor 0:1c358ea10753 245 connector_working : connector_abort;
spastor 0:1c358ea10753 246
spastor 0:1c358ea10753 247 context->user_context = data.user_context;
spastor 0:1c358ea10753 248
spastor 0:1c358ea10753 249 if (status == connector_abort)
spastor 0:1c358ea10753 250 goto done;
spastor 0:1c358ea10753 251
spastor 0:1c358ea10753 252 if (data.bytes_used > buffer_size)
spastor 0:1c358ea10753 253 {
spastor 0:1c358ea10753 254 fs_set_abort(connector_ptr,
spastor 0:1c358ea10753 255 context,
spastor 0:1c358ea10753 256 connector_request_id_file_system_get_error,
spastor 0:1c358ea10753 257 connector_invalid_data_size);
spastor 0:1c358ea10753 258 status = connector_abort;
spastor 0:1c358ea10753 259 goto done;
spastor 0:1c358ea10753 260 }
spastor 0:1c358ea10753 261 }
spastor 0:1c358ea10753 262 message_store_u8(fs_error_response, opcode, fs_error_opcode);
spastor 0:1c358ea10753 263 /* coverity[uninit_use] */
spastor 0:1c358ea10753 264 message_store_u8(fs_error_response, error_code, (uint8_t)data.error_status);
spastor 0:1c358ea10753 265 message_store_u8(fs_error_response, error_hint_len, (uint8_t) data.bytes_used);
spastor 0:1c358ea10753 266
spastor 0:1c358ea10753 267 service_data->length_in_bytes = header_bytes + data.bytes_used;
spastor 0:1c358ea10753 268
spastor 0:1c358ea10753 269 MsgSetLastData(service_data->flags);
spastor 0:1c358ea10753 270 }
spastor 0:1c358ea10753 271
spastor 0:1c358ea10753 272 done:
spastor 0:1c358ea10753 273 return status;
spastor 0:1c358ea10753 274 }
spastor 0:1c358ea10753 275
spastor 0:1c358ea10753 276 static connector_status_t fs_call_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 277 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 278 fs_context_t * const context,
spastor 0:1c358ea10753 279 connector_request_id_file_system_t const fs_request_id,
spastor 0:1c358ea10753 280 void * const pdata)
spastor 0:1c358ea10753 281 {
spastor 0:1c358ea10753 282 connector_status_t status = connector_working;
spastor 0:1c358ea10753 283 connector_callback_status_t callback_status;
spastor 0:1c358ea10753 284 connector_request_id_t request_id;
spastor 0:1c358ea10753 285 fs_user_data * const data = pdata;
spastor 0:1c358ea10753 286
spastor 0:1c358ea10753 287 request_id.file_system_request = fs_request_id;
spastor 0:1c358ea10753 288
spastor 0:1c358ea10753 289 data->user_context = context->user_context;
spastor 0:1c358ea10753 290 data->errnum = NULL;
spastor 0:1c358ea10753 291
spastor 0:1c358ea10753 292 callback_status = connector_callback(connector_ptr->callback,
spastor 0:1c358ea10753 293 connector_class_id_file_system,
spastor 0:1c358ea10753 294 request_id,
spastor 0:1c358ea10753 295 data);
spastor 0:1c358ea10753 296
spastor 0:1c358ea10753 297 context->user_context = data->user_context;
spastor 0:1c358ea10753 298
spastor 0:1c358ea10753 299 switch (callback_status)
spastor 0:1c358ea10753 300 {
spastor 0:1c358ea10753 301 case connector_callback_continue:
spastor 0:1c358ea10753 302 status = connector_working;
spastor 0:1c358ea10753 303 break;
spastor 0:1c358ea10753 304
spastor 0:1c358ea10753 305 case connector_callback_busy:
spastor 0:1c358ea10753 306 status = connector_pending;
spastor 0:1c358ea10753 307 break;
spastor 0:1c358ea10753 308
spastor 0:1c358ea10753 309 case connector_callback_unrecognized:
spastor 0:1c358ea10753 310 status = connector_working;
spastor 0:1c358ea10753 311 FsSetInternalError(context, fs_error_session_canceled);
spastor 0:1c358ea10753 312 fs_set_service_error(service_request, connector_session_error_cancel);
spastor 0:1c358ea10753 313 break;
spastor 0:1c358ea10753 314
spastor 0:1c358ea10753 315 case connector_callback_abort:
spastor 0:1c358ea10753 316 status = context->status = connector_abort;
spastor 0:1c358ea10753 317 break;
spastor 0:1c358ea10753 318
spastor 0:1c358ea10753 319 case connector_callback_error:
spastor 0:1c358ea10753 320 status = connector_working;
spastor 0:1c358ea10753 321 /* don't overwrite previous errno */
spastor 0:1c358ea10753 322 if (context->errnum == NULL)
spastor 0:1c358ea10753 323 {
spastor 0:1c358ea10753 324 if (data->errnum != NULL)
spastor 0:1c358ea10753 325 {
spastor 0:1c358ea10753 326 /* user returned errno */
spastor 0:1c358ea10753 327 context->errnum = data->errnum;
spastor 0:1c358ea10753 328 }
spastor 0:1c358ea10753 329 else
spastor 0:1c358ea10753 330 {
spastor 0:1c358ea10753 331 /* user returned connector_callback_error without setting errno */
spastor 0:1c358ea10753 332 FsSetInternalError(context, fs_error_generic);
spastor 0:1c358ea10753 333 }
spastor 0:1c358ea10753 334 }
spastor 0:1c358ea10753 335 break;
spastor 0:1c358ea10753 336 }
spastor 0:1c358ea10753 337
spastor 0:1c358ea10753 338 return status;
spastor 0:1c358ea10753 339 }
spastor 0:1c358ea10753 340
spastor 0:1c358ea10753 341 static size_t file_hash_size(connector_file_system_hash_algorithm_t const hash_alg)
spastor 0:1c358ea10753 342 {
spastor 0:1c358ea10753 343 size_t result;
spastor 0:1c358ea10753 344
spastor 0:1c358ea10753 345 switch(hash_alg)
spastor 0:1c358ea10753 346 {
spastor 0:1c358ea10753 347 case connector_file_system_hash_md5:
spastor 0:1c358ea10753 348 result = 16;
spastor 0:1c358ea10753 349 break;
spastor 0:1c358ea10753 350
spastor 0:1c358ea10753 351 case connector_file_system_hash_crc32:
spastor 0:1c358ea10753 352 result = 4;
spastor 0:1c358ea10753 353 break;
spastor 0:1c358ea10753 354
spastor 0:1c358ea10753 355 default:
spastor 0:1c358ea10753 356 result = 0;
spastor 0:1c358ea10753 357 }
spastor 0:1c358ea10753 358 return result;
spastor 0:1c358ea10753 359 }
spastor 0:1c358ea10753 360
spastor 0:1c358ea10753 361 static connector_status_t call_file_stat_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 362 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 363 fs_context_t * const context,
spastor 0:1c358ea10753 364 char const * const path,
spastor 0:1c358ea10753 365 connector_file_system_hash_algorithm_t const hash_alg)
spastor 0:1c358ea10753 366 {
spastor 0:1c358ea10753 367 connector_status_t status;
spastor 0:1c358ea10753 368
spastor 0:1c358ea10753 369 connector_file_system_stat_t data;
spastor 0:1c358ea10753 370 data.path = path;
spastor 0:1c358ea10753 371 data.hash_algorithm.requested = hash_alg;
spastor 0:1c358ea10753 372
spastor 0:1c358ea10753 373 data.statbuf.file_size = 0;
spastor 0:1c358ea10753 374 data.statbuf.last_modified = 0;
spastor 0:1c358ea10753 375 data.statbuf.flags = connector_file_system_file_type_none;
spastor 0:1c358ea10753 376
spastor 0:1c358ea10753 377 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 378 service_request,
spastor 0:1c358ea10753 379 context,
spastor 0:1c358ea10753 380 connector_request_id_file_system_stat,
spastor 0:1c358ea10753 381 &data);
spastor 0:1c358ea10753 382
spastor 0:1c358ea10753 383 if (status == connector_pending)
spastor 0:1c358ea10753 384 goto done;
spastor 0:1c358ea10753 385
spastor 0:1c358ea10753 386 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 387 goto done;
spastor 0:1c358ea10753 388
spastor 0:1c358ea10753 389 context->data.d.file_size = data.statbuf.file_size;
spastor 0:1c358ea10753 390 context->data.d.last_modified = data.statbuf.last_modified;
spastor 0:1c358ea10753 391
spastor 0:1c358ea10753 392 switch(data.statbuf.flags)
spastor 0:1c358ea10753 393 {
spastor 0:1c358ea10753 394 case connector_file_system_file_type_is_dir:
spastor 0:1c358ea10753 395 FsSetDir(context);
spastor 0:1c358ea10753 396 break;
spastor 0:1c358ea10753 397
spastor 0:1c358ea10753 398 case connector_file_system_file_type_is_reg:
spastor 0:1c358ea10753 399 FsSetReg(context);
spastor 0:1c358ea10753 400 break;
spastor 0:1c358ea10753 401
spastor 0:1c358ea10753 402 default:
spastor 0:1c358ea10753 403 context->flags = 0;
spastor 0:1c358ea10753 404 break;
spastor 0:1c358ea10753 405 }
spastor 0:1c358ea10753 406
spastor 0:1c358ea10753 407 switch(hash_alg)
spastor 0:1c358ea10753 408 {
spastor 0:1c358ea10753 409 case connector_file_system_hash_none:
spastor 0:1c358ea10753 410 context->data.d.hash_alg = hash_alg;
spastor 0:1c358ea10753 411 break;
spastor 0:1c358ea10753 412
spastor 0:1c358ea10753 413 case connector_file_system_hash_best:
spastor 0:1c358ea10753 414 switch(data.hash_algorithm.actual)
spastor 0:1c358ea10753 415 {
spastor 0:1c358ea10753 416 case connector_file_system_hash_md5:
spastor 0:1c358ea10753 417 case connector_file_system_hash_crc32:
spastor 0:1c358ea10753 418 context->data.d.hash_alg = data.hash_algorithm.actual;
spastor 0:1c358ea10753 419 break;
spastor 0:1c358ea10753 420
spastor 0:1c358ea10753 421 default:
spastor 0:1c358ea10753 422 context->data.d.hash_alg = connector_file_system_hash_none;
spastor 0:1c358ea10753 423 break;
spastor 0:1c358ea10753 424 }
spastor 0:1c358ea10753 425 break;
spastor 0:1c358ea10753 426
spastor 0:1c358ea10753 427 default:
spastor 0:1c358ea10753 428 if (hash_alg != data.hash_algorithm.actual)
spastor 0:1c358ea10753 429 context->data.d.hash_alg = connector_file_system_hash_none;
spastor 0:1c358ea10753 430 break;
spastor 0:1c358ea10753 431 }
spastor 0:1c358ea10753 432
spastor 0:1c358ea10753 433 if (context->data.d.hash_alg != connector_file_system_hash_none)
spastor 0:1c358ea10753 434 {
spastor 0:1c358ea10753 435 if (!FsIsDir(context) && !FsIsReg(context))
spastor 0:1c358ea10753 436 context->data.d.hash_alg = connector_file_system_hash_none;
spastor 0:1c358ea10753 437 }
spastor 0:1c358ea10753 438 done:
spastor 0:1c358ea10753 439 return status;
spastor 0:1c358ea10753 440 }
spastor 0:1c358ea10753 441
spastor 0:1c358ea10753 442 static connector_status_t call_file_stat_dir_entry_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 443 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 444 fs_context_t * const context,
spastor 0:1c358ea10753 445 char const * const path)
spastor 0:1c358ea10753 446 {
spastor 0:1c358ea10753 447 connector_status_t status;
spastor 0:1c358ea10753 448
spastor 0:1c358ea10753 449 connector_file_system_stat_dir_entry_t data;
spastor 0:1c358ea10753 450 data.path = path;
spastor 0:1c358ea10753 451 data.statbuf.file_size = 0;
spastor 0:1c358ea10753 452 data.statbuf.last_modified = 0;
spastor 0:1c358ea10753 453 data.statbuf.flags = connector_file_system_file_type_none;
spastor 0:1c358ea10753 454
spastor 0:1c358ea10753 455 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 456 service_request,
spastor 0:1c358ea10753 457 context,
spastor 0:1c358ea10753 458 connector_request_id_file_system_stat_dir_entry,
spastor 0:1c358ea10753 459 &data);
spastor 0:1c358ea10753 460
spastor 0:1c358ea10753 461 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 462 goto done;
spastor 0:1c358ea10753 463
spastor 0:1c358ea10753 464 context->data.d.file_size = data.statbuf.file_size;
spastor 0:1c358ea10753 465 context->data.d.last_modified = data.statbuf.last_modified;
spastor 0:1c358ea10753 466
spastor 0:1c358ea10753 467 switch(data.statbuf.flags)
spastor 0:1c358ea10753 468 {
spastor 0:1c358ea10753 469 case connector_file_system_file_type_is_dir:
spastor 0:1c358ea10753 470 FsSetDir(context);
spastor 0:1c358ea10753 471 break;
spastor 0:1c358ea10753 472
spastor 0:1c358ea10753 473 case connector_file_system_file_type_is_reg:
spastor 0:1c358ea10753 474 FsSetReg(context);
spastor 0:1c358ea10753 475 break;
spastor 0:1c358ea10753 476
spastor 0:1c358ea10753 477 default:
spastor 0:1c358ea10753 478 context->flags = 0;
spastor 0:1c358ea10753 479 break;
spastor 0:1c358ea10753 480 }
spastor 0:1c358ea10753 481
spastor 0:1c358ea10753 482 done:
spastor 0:1c358ea10753 483 return status;
spastor 0:1c358ea10753 484 }
spastor 0:1c358ea10753 485
spastor 0:1c358ea10753 486
spastor 0:1c358ea10753 487 static connector_status_t call_file_opendir_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 488 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 489 fs_context_t * const context,
spastor 0:1c358ea10753 490 char const * const path)
spastor 0:1c358ea10753 491 {
spastor 0:1c358ea10753 492 connector_status_t status;
spastor 0:1c358ea10753 493 connector_file_system_opendir_t data;
spastor 0:1c358ea10753 494
spastor 0:1c358ea10753 495 data.path = path;
spastor 0:1c358ea10753 496 data.handle = NULL;
spastor 0:1c358ea10753 497
spastor 0:1c358ea10753 498 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 499 service_request,
spastor 0:1c358ea10753 500 context,
spastor 0:1c358ea10753 501 connector_request_id_file_system_opendir,
spastor 0:1c358ea10753 502 &data);
spastor 0:1c358ea10753 503
spastor 0:1c358ea10753 504 if (status == connector_pending)
spastor 0:1c358ea10753 505 goto done;
spastor 0:1c358ea10753 506
spastor 0:1c358ea10753 507 if (FsOperationSuccess(status, context))
spastor 0:1c358ea10753 508 {
spastor 0:1c358ea10753 509 if (data.handle != NULL)
spastor 0:1c358ea10753 510 {
spastor 0:1c358ea10753 511 context->handle = data.handle;
spastor 0:1c358ea10753 512 FsSetState(context, fs_state_open);
spastor 0:1c358ea10753 513 }
spastor 0:1c358ea10753 514 else
spastor 0:1c358ea10753 515 {
spastor 0:1c358ea10753 516 status = fs_set_abort(connector_ptr,
spastor 0:1c358ea10753 517 context,
spastor 0:1c358ea10753 518 connector_request_id_file_system_opendir,
spastor 0:1c358ea10753 519 connector_invalid_data);
spastor 0:1c358ea10753 520 }
spastor 0:1c358ea10753 521 }
spastor 0:1c358ea10753 522
spastor 0:1c358ea10753 523 done:
spastor 0:1c358ea10753 524 return status;
spastor 0:1c358ea10753 525 }
spastor 0:1c358ea10753 526
spastor 0:1c358ea10753 527 /* This function is a custom implementation of GNU/Linux's non-standard strnlen() */
spastor 0:1c358ea10753 528 static int strnlen_(char const * const string, int maxlen)
spastor 0:1c358ea10753 529 {
spastor 0:1c358ea10753 530 volatile const char *e;
spastor 0:1c358ea10753 531 int n;
spastor 0:1c358ea10753 532
spastor 0:1c358ea10753 533 for (e = string, n = 0; *e && n < maxlen; e++, n++)
spastor 0:1c358ea10753 534 ;
spastor 0:1c358ea10753 535
spastor 0:1c358ea10753 536 return n;
spastor 0:1c358ea10753 537 }
spastor 0:1c358ea10753 538
spastor 0:1c358ea10753 539 static connector_status_t call_file_readdir_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 540 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 541 fs_context_t * const context,
spastor 0:1c358ea10753 542 char * const path,
spastor 0:1c358ea10753 543 size_t const buffer_size)
spastor 0:1c358ea10753 544 {
spastor 0:1c358ea10753 545 connector_status_t status;
spastor 0:1c358ea10753 546
spastor 0:1c358ea10753 547 connector_file_system_readdir_t data;
spastor 0:1c358ea10753 548 data.handle = context->handle;
spastor 0:1c358ea10753 549 data.entry_name = path;
spastor 0:1c358ea10753 550 data.bytes_available = buffer_size;
spastor 0:1c358ea10753 551 *path = '\0';
spastor 0:1c358ea10753 552
spastor 0:1c358ea10753 553 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 554 service_request,
spastor 0:1c358ea10753 555 context,
spastor 0:1c358ea10753 556 connector_request_id_file_system_readdir,
spastor 0:1c358ea10753 557 &data);
spastor 0:1c358ea10753 558 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 559 goto done;
spastor 0:1c358ea10753 560
spastor 0:1c358ea10753 561 if (path[strnlen_(path, buffer_size)] != '\0')
spastor 0:1c358ea10753 562 {
spastor 0:1c358ea10753 563 /* no NUL-character within buffer */
spastor 0:1c358ea10753 564 status = fs_set_abort(connector_ptr,
spastor 0:1c358ea10753 565 context,
spastor 0:1c358ea10753 566 connector_request_id_file_system_readdir,
spastor 0:1c358ea10753 567 connector_invalid_data_size);
spastor 0:1c358ea10753 568 }
spastor 0:1c358ea10753 569
spastor 0:1c358ea10753 570 done:
spastor 0:1c358ea10753 571 return status;
spastor 0:1c358ea10753 572 }
spastor 0:1c358ea10753 573
spastor 0:1c358ea10753 574 static connector_status_t call_file_close_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 575 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 576 fs_context_t * const context,
spastor 0:1c358ea10753 577 connector_request_id_file_system_t const fs_request_id)
spastor 0:1c358ea10753 578 {
spastor 0:1c358ea10753 579 connector_status_t status = context->status;
spastor 0:1c358ea10753 580 connector_file_system_close_t data;
spastor 0:1c358ea10753 581
spastor 0:1c358ea10753 582 if (!FsIsOpen(context))
spastor 0:1c358ea10753 583 goto done;
spastor 0:1c358ea10753 584
spastor 0:1c358ea10753 585 data.handle = context->handle;
spastor 0:1c358ea10753 586
spastor 0:1c358ea10753 587 FsSetState(context, fs_state_closing);
spastor 0:1c358ea10753 588
spastor 0:1c358ea10753 589 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 590 service_request,
spastor 0:1c358ea10753 591 context,
spastor 0:1c358ea10753 592 fs_request_id,
spastor 0:1c358ea10753 593 &data);
spastor 0:1c358ea10753 594
spastor 0:1c358ea10753 595 if (status == connector_pending)
spastor 0:1c358ea10753 596 goto done;
spastor 0:1c358ea10753 597
spastor 0:1c358ea10753 598 /* done with close, no matter if success or an error */
spastor 0:1c358ea10753 599 FsSetState(context, fs_state_closed);
spastor 0:1c358ea10753 600
spastor 0:1c358ea10753 601 done:
spastor 0:1c358ea10753 602 return status;
spastor 0:1c358ea10753 603 }
spastor 0:1c358ea10753 604
spastor 0:1c358ea10753 605 static connector_status_t call_file_hash_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 606 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 607 fs_context_t * const context,
spastor 0:1c358ea10753 608 char const * const path,
spastor 0:1c358ea10753 609 uint8_t * const hash_ptr)
spastor 0:1c358ea10753 610 {
spastor 0:1c358ea10753 611 connector_status_t status = connector_working;
spastor 0:1c358ea10753 612 connector_file_system_hash_t data;
spastor 0:1c358ea10753 613
spastor 0:1c358ea10753 614 data.bytes_requested = file_hash_size(context->data.d.hash_alg);
spastor 0:1c358ea10753 615 data.path = path;
spastor 0:1c358ea10753 616 data.hash_algorithm = context->data.d.hash_alg;
spastor 0:1c358ea10753 617 data.hash_value = hash_ptr;
spastor 0:1c358ea10753 618
spastor 0:1c358ea10753 619 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 620 service_request,
spastor 0:1c358ea10753 621 context,
spastor 0:1c358ea10753 622 connector_request_id_file_system_hash,
spastor 0:1c358ea10753 623 &data);
spastor 0:1c358ea10753 624
spastor 0:1c358ea10753 625 return status;
spastor 0:1c358ea10753 626 }
spastor 0:1c358ea10753 627
spastor 0:1c358ea10753 628 static connector_status_t call_file_open_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 629 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 630 fs_context_t * context,
spastor 0:1c358ea10753 631 char const * const path,
spastor 0:1c358ea10753 632 int const oflag)
spastor 0:1c358ea10753 633 {
spastor 0:1c358ea10753 634 connector_status_t status;
spastor 0:1c358ea10753 635 connector_file_system_open_t data;
spastor 0:1c358ea10753 636
spastor 0:1c358ea10753 637 data.path = path;
spastor 0:1c358ea10753 638 data.oflag = oflag;
spastor 0:1c358ea10753 639 data.handle = NULL;
spastor 0:1c358ea10753 640
spastor 0:1c358ea10753 641 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 642 service_request,
spastor 0:1c358ea10753 643 context,
spastor 0:1c358ea10753 644 connector_request_id_file_system_open,
spastor 0:1c358ea10753 645 &data);
spastor 0:1c358ea10753 646
spastor 0:1c358ea10753 647 if (status == connector_pending)
spastor 0:1c358ea10753 648 goto done;
spastor 0:1c358ea10753 649
spastor 0:1c358ea10753 650 if (FsOperationSuccess(status, context))
spastor 0:1c358ea10753 651 {
spastor 0:1c358ea10753 652 if (data.handle != NULL)
spastor 0:1c358ea10753 653 {
spastor 0:1c358ea10753 654 context->handle = data.handle;
spastor 0:1c358ea10753 655 FsSetState(context, fs_state_open);
spastor 0:1c358ea10753 656 }
spastor 0:1c358ea10753 657 else
spastor 0:1c358ea10753 658 {
spastor 0:1c358ea10753 659 status = fs_set_abort(connector_ptr,
spastor 0:1c358ea10753 660 context,
spastor 0:1c358ea10753 661 connector_request_id_file_system_open,
spastor 0:1c358ea10753 662 connector_invalid_data);
spastor 0:1c358ea10753 663 }
spastor 0:1c358ea10753 664 }
spastor 0:1c358ea10753 665
spastor 0:1c358ea10753 666 if (FsGetState(context) != fs_state_open)
spastor 0:1c358ea10753 667 FsSetState(context, fs_state_closed); /* never opened a file */
spastor 0:1c358ea10753 668
spastor 0:1c358ea10753 669 done:
spastor 0:1c358ea10753 670 return status;
spastor 0:1c358ea10753 671 }
spastor 0:1c358ea10753 672
spastor 0:1c358ea10753 673 static connector_status_t call_file_lseek_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 674 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 675 fs_context_t * const context,
spastor 0:1c358ea10753 676 connector_file_offset_t const offset_in,
spastor 0:1c358ea10753 677 connector_file_system_seek_origin_t const origin,
spastor 0:1c358ea10753 678 connector_file_offset_t * const offset_out)
spastor 0:1c358ea10753 679 {
spastor 0:1c358ea10753 680 connector_file_system_lseek_t data;
spastor 0:1c358ea10753 681 connector_status_t status;
spastor 0:1c358ea10753 682
spastor 0:1c358ea10753 683 data.handle = context->handle;
spastor 0:1c358ea10753 684 data.requested_offset = offset_in;
spastor 0:1c358ea10753 685 data.resulting_offset = -1;
spastor 0:1c358ea10753 686 data.origin = origin;
spastor 0:1c358ea10753 687
spastor 0:1c358ea10753 688 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 689 service_request,
spastor 0:1c358ea10753 690 context,
spastor 0:1c358ea10753 691 connector_request_id_file_system_lseek,
spastor 0:1c358ea10753 692 &data);
spastor 0:1c358ea10753 693
spastor 0:1c358ea10753 694 *offset_out = data.resulting_offset;
spastor 0:1c358ea10753 695
spastor 0:1c358ea10753 696 return status;
spastor 0:1c358ea10753 697 }
spastor 0:1c358ea10753 698
spastor 0:1c358ea10753 699
spastor 0:1c358ea10753 700 static connector_status_t call_file_ftruncate_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 701 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 702 fs_context_t * const context)
spastor 0:1c358ea10753 703 {
spastor 0:1c358ea10753 704 connector_status_t status;
spastor 0:1c358ea10753 705 connector_file_system_truncate_t data;
spastor 0:1c358ea10753 706
spastor 0:1c358ea10753 707 data.handle = context->handle;
spastor 0:1c358ea10753 708 data.length_in_bytes = context->data.f.offset;
spastor 0:1c358ea10753 709
spastor 0:1c358ea10753 710 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 711 service_request,
spastor 0:1c358ea10753 712 context,
spastor 0:1c358ea10753 713 connector_request_id_file_system_ftruncate,
spastor 0:1c358ea10753 714 &data);
spastor 0:1c358ea10753 715 return status;
spastor 0:1c358ea10753 716 }
spastor 0:1c358ea10753 717
spastor 0:1c358ea10753 718 static connector_status_t call_file_rm_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 719 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 720 fs_context_t * const context,
spastor 0:1c358ea10753 721 char const * const path)
spastor 0:1c358ea10753 722 {
spastor 0:1c358ea10753 723 connector_status_t status;
spastor 0:1c358ea10753 724 connector_file_system_remove_t data;
spastor 0:1c358ea10753 725 data.path = path;
spastor 0:1c358ea10753 726
spastor 0:1c358ea10753 727 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 728 service_request,
spastor 0:1c358ea10753 729 context,
spastor 0:1c358ea10753 730 connector_request_id_file_system_remove,
spastor 0:1c358ea10753 731 &data);
spastor 0:1c358ea10753 732 return status;
spastor 0:1c358ea10753 733 }
spastor 0:1c358ea10753 734
spastor 0:1c358ea10753 735 static connector_status_t call_file_read_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 736 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 737 fs_context_t * const context,
spastor 0:1c358ea10753 738 void * const buffer,
spastor 0:1c358ea10753 739 size_t * const buffer_size)
spastor 0:1c358ea10753 740 {
spastor 0:1c358ea10753 741 connector_status_t status;
spastor 0:1c358ea10753 742 connector_file_system_read_t data;
spastor 0:1c358ea10753 743
spastor 0:1c358ea10753 744 data.handle = context->handle;
spastor 0:1c358ea10753 745 data.buffer = buffer;
spastor 0:1c358ea10753 746 data.bytes_available = *buffer_size;
spastor 0:1c358ea10753 747 data.bytes_used = 0;
spastor 0:1c358ea10753 748
spastor 0:1c358ea10753 749 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 750 service_request,
spastor 0:1c358ea10753 751 context,
spastor 0:1c358ea10753 752 connector_request_id_file_system_read,
spastor 0:1c358ea10753 753 &data);
spastor 0:1c358ea10753 754
spastor 0:1c358ea10753 755 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 756 goto done;
spastor 0:1c358ea10753 757
spastor 0:1c358ea10753 758 if (data.bytes_used > *buffer_size)
spastor 0:1c358ea10753 759 {
spastor 0:1c358ea10753 760 status = fs_set_abort(connector_ptr,
spastor 0:1c358ea10753 761 context,
spastor 0:1c358ea10753 762 connector_request_id_file_system_read,
spastor 0:1c358ea10753 763 connector_invalid_data_size);
spastor 0:1c358ea10753 764 goto done;
spastor 0:1c358ea10753 765 }
spastor 0:1c358ea10753 766
spastor 0:1c358ea10753 767 *buffer_size = data.bytes_used;
spastor 0:1c358ea10753 768
spastor 0:1c358ea10753 769 done:
spastor 0:1c358ea10753 770 return status;
spastor 0:1c358ea10753 771 }
spastor 0:1c358ea10753 772
spastor 0:1c358ea10753 773 static connector_status_t call_file_write_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 774 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 775 fs_context_t * const context,
spastor 0:1c358ea10753 776 void const * const buffer,
spastor 0:1c358ea10753 777 size_t * const bytes_done)
spastor 0:1c358ea10753 778 {
spastor 0:1c358ea10753 779 connector_status_t status;
spastor 0:1c358ea10753 780 connector_file_system_write_t data;
spastor 0:1c358ea10753 781
spastor 0:1c358ea10753 782 data.handle = context->handle;
spastor 0:1c358ea10753 783 data.buffer = buffer;
spastor 0:1c358ea10753 784 data.bytes_available = *bytes_done;
spastor 0:1c358ea10753 785 data.bytes_used = 0;
spastor 0:1c358ea10753 786
spastor 0:1c358ea10753 787 status = fs_call_user(connector_ptr,
spastor 0:1c358ea10753 788 service_request,
spastor 0:1c358ea10753 789 context,
spastor 0:1c358ea10753 790 connector_request_id_file_system_write,
spastor 0:1c358ea10753 791 &data);
spastor 0:1c358ea10753 792
spastor 0:1c358ea10753 793 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 794 goto done;
spastor 0:1c358ea10753 795
spastor 0:1c358ea10753 796
spastor 0:1c358ea10753 797 if (data.bytes_used > *bytes_done)
spastor 0:1c358ea10753 798 {
spastor 0:1c358ea10753 799 status = fs_set_abort(connector_ptr,
spastor 0:1c358ea10753 800 context,
spastor 0:1c358ea10753 801 connector_request_id_file_system_write,
spastor 0:1c358ea10753 802 connector_invalid_data_size);
spastor 0:1c358ea10753 803 goto done;
spastor 0:1c358ea10753 804 }
spastor 0:1c358ea10753 805
spastor 0:1c358ea10753 806 *bytes_done = data.bytes_used;
spastor 0:1c358ea10753 807
spastor 0:1c358ea10753 808 if (*bytes_done == 0)
spastor 0:1c358ea10753 809 {
spastor 0:1c358ea10753 810 status = connector_pending;
spastor 0:1c358ea10753 811 }
spastor 0:1c358ea10753 812
spastor 0:1c358ea10753 813 done:
spastor 0:1c358ea10753 814 return status;
spastor 0:1c358ea10753 815 }
spastor 0:1c358ea10753 816
spastor 0:1c358ea10753 817 static size_t parse_file_path(fs_context_t * const context,
spastor 0:1c358ea10753 818 void const * const path_ptr,
spastor 0:1c358ea10753 819 size_t const buffer_size)
spastor 0:1c358ea10753 820 {
spastor 0:1c358ea10753 821 char const * const path = path_ptr;
spastor 0:1c358ea10753 822 size_t path_len = strnlen_(path, buffer_size);
spastor 0:1c358ea10753 823
spastor 0:1c358ea10753 824 if (path_len == 0)
spastor 0:1c358ea10753 825 {
spastor 0:1c358ea10753 826 FsSetInternalError(context, fs_error_format);
spastor 0:1c358ea10753 827 }
spastor 0:1c358ea10753 828 else
spastor 0:1c358ea10753 829 if (path_len >= buffer_size)
spastor 0:1c358ea10753 830 {
spastor 0:1c358ea10753 831 FsSetInternalError(context, fs_error_path_too_long);
spastor 0:1c358ea10753 832 path_len = 0;
spastor 0:1c358ea10753 833 }
spastor 0:1c358ea10753 834 else
spastor 0:1c358ea10753 835 path_len++;
spastor 0:1c358ea10753 836
spastor 0:1c358ea10753 837 return path_len;
spastor 0:1c358ea10753 838 }
spastor 0:1c358ea10753 839
spastor 0:1c358ea10753 840 static size_t parse_file_get_header(fs_context_t * const context,
spastor 0:1c358ea10753 841 uint8_t const * const header_ptr,
spastor 0:1c358ea10753 842 size_t const buffer_size)
spastor 0:1c358ea10753 843 {
spastor 0:1c358ea10753 844
spastor 0:1c358ea10753 845 /* 1st message so let's parse message-start packet:
spastor 0:1c358ea10753 846 *
spastor 0:1c358ea10753 847 * File System Get request format:
spastor 0:1c358ea10753 848 * -------------------------------------
spastor 0:1c358ea10753 849 * | 0 | N | +4 | +4 |
spastor 0:1c358ea10753 850 * --------------------------------------
spastor 0:1c358ea10753 851 * | Opcode | Path | Offset | Length |
spastor 0:1c358ea10753 852 * -------------------------------------
spastor 0:1c358ea10753 853 *
spastor 0:1c358ea10753 854 */
spastor 0:1c358ea10753 855
spastor 0:1c358ea10753 856 enum fs_get_request {
spastor 0:1c358ea10753 857 field_define(fs_get_request, offset, uint32_t),
spastor 0:1c358ea10753 858 field_define(fs_get_request, length, uint32_t),
spastor 0:1c358ea10753 859 record_end(fs_get_request_header)
spastor 0:1c358ea10753 860 };
spastor 0:1c358ea10753 861 uint8_t const * fs_get_request = header_ptr + FS_OPCODE_BYTES;
spastor 0:1c358ea10753 862 size_t const header_len = record_bytes(fs_get_request_header) + FS_OPCODE_BYTES;
spastor 0:1c358ea10753 863
spastor 0:1c358ea10753 864 size_t len = parse_file_path(context, fs_get_request, buffer_size - header_len);
spastor 0:1c358ea10753 865 if (len == 0)
spastor 0:1c358ea10753 866 goto done;
spastor 0:1c358ea10753 867
spastor 0:1c358ea10753 868 fs_get_request += len;
spastor 0:1c358ea10753 869 context->data.f.offset = message_load_be32(fs_get_request, offset);
spastor 0:1c358ea10753 870 if (context->data.f.offset < 0)
spastor 0:1c358ea10753 871 {
spastor 0:1c358ea10753 872 FsSetInternalError(context, fs_error_large_file);
spastor 0:1c358ea10753 873 len = 0;
spastor 0:1c358ea10753 874 goto done;
spastor 0:1c358ea10753 875 }
spastor 0:1c358ea10753 876 context->data.f.data_length = message_load_be32(fs_get_request, length);
spastor 0:1c358ea10753 877 len += header_len;
spastor 0:1c358ea10753 878
spastor 0:1c358ea10753 879 done:
spastor 0:1c358ea10753 880 return len;
spastor 0:1c358ea10753 881 }
spastor 0:1c358ea10753 882
spastor 0:1c358ea10753 883 static connector_status_t process_file_get_request(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 884 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 885 fs_context_t * const context)
spastor 0:1c358ea10753 886 {
spastor 0:1c358ea10753 887 msg_service_data_t * const service_data = service_request->have_data;
spastor 0:1c358ea10753 888 connector_status_t status = connector_working;
spastor 0:1c358ea10753 889
spastor 0:1c358ea10753 890 if (parse_file_get_header(context, service_data->data_ptr, service_data->length_in_bytes) > 0)
spastor 0:1c358ea10753 891 {
spastor 0:1c358ea10753 892 char const * path = service_data->data_ptr;
spastor 0:1c358ea10753 893 path += FS_OPCODE_BYTES;
spastor 0:1c358ea10753 894
spastor 0:1c358ea10753 895 status = call_file_open_user(connector_ptr, service_request, context, path, CONNECTOR_FILE_O_RDONLY);
spastor 0:1c358ea10753 896 }
spastor 0:1c358ea10753 897
spastor 0:1c358ea10753 898 return status;
spastor 0:1c358ea10753 899 }
spastor 0:1c358ea10753 900
spastor 0:1c358ea10753 901 static connector_status_t set_file_position(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 902 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 903 fs_context_t * const context)
spastor 0:1c358ea10753 904
spastor 0:1c358ea10753 905 {
spastor 0:1c358ea10753 906 connector_status_t status = connector_working;
spastor 0:1c358ea10753 907 connector_file_offset_t ret;
spastor 0:1c358ea10753 908
spastor 0:1c358ea10753 909 /* Check that offset is inside the file
spastor 0:1c358ea10753 910 Some systems crash, when trying to set offset outside the file
spastor 0:1c358ea10753 911 */
spastor 0:1c358ea10753 912
spastor 0:1c358ea10753 913 if (FsGetState(context) < fs_state_lseek1)
spastor 0:1c358ea10753 914 {
spastor 0:1c358ea10753 915 status = call_file_lseek_user(connector_ptr, service_request, context, 0, connector_file_system_seek_end, &ret);
spastor 0:1c358ea10753 916 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 917 goto done;
spastor 0:1c358ea10753 918
spastor 0:1c358ea10753 919 if (ret < context->data.f.offset)
spastor 0:1c358ea10753 920 {
spastor 0:1c358ea10753 921 ret = -1;
spastor 0:1c358ea10753 922 FsSetInternalError(context, fs_error_invalid_offset);
spastor 0:1c358ea10753 923 goto done;
spastor 0:1c358ea10753 924 }
spastor 0:1c358ea10753 925
spastor 0:1c358ea10753 926 FsSetState(context, fs_state_lseek1);
spastor 0:1c358ea10753 927 status = call_file_lseek_user(connector_ptr, service_request, context, context->data.f.offset, connector_file_system_seek_set, &ret);
spastor 0:1c358ea10753 928 if (FsOperationSuccess(status, context) && ret == -1)
spastor 0:1c358ea10753 929 {
spastor 0:1c358ea10753 930 FsSetInternalError(context, fs_error_invalid_offset);
spastor 0:1c358ea10753 931 }
spastor 0:1c358ea10753 932 }
spastor 0:1c358ea10753 933 done:
spastor 0:1c358ea10753 934 return status;
spastor 0:1c358ea10753 935 }
spastor 0:1c358ea10753 936
spastor 0:1c358ea10753 937 static connector_status_t process_get_close(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 938 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 939 fs_context_t * const context,
spastor 0:1c358ea10753 940 connector_request_id_file_system_t close_request)
spastor 0:1c358ea10753 941 {
spastor 0:1c358ea10753 942
spastor 0:1c358ea10753 943 msg_service_data_t * const service_data = service_request->need_data;
spastor 0:1c358ea10753 944 connector_status_t status = connector_working;
spastor 0:1c358ea10753 945
spastor 0:1c358ea10753 946 if (FsGetState(context) < fs_state_closed)
spastor 0:1c358ea10753 947 {
spastor 0:1c358ea10753 948 status = call_file_close_user(connector_ptr,
spastor 0:1c358ea10753 949 service_request,
spastor 0:1c358ea10753 950 context,
spastor 0:1c358ea10753 951 close_request);
spastor 0:1c358ea10753 952
spastor 0:1c358ea10753 953 if (status == connector_pending)
spastor 0:1c358ea10753 954 {
spastor 0:1c358ea10753 955 if (context->status == connector_working &&
spastor 0:1c358ea10753 956 context->errnum == NULL &&
spastor 0:1c358ea10753 957 service_data->length_in_bytes > 0)
spastor 0:1c358ea10753 958 {
spastor 0:1c358ea10753 959 /* Return final data portion, will set last bit later
spastor 0:1c358ea10753 960 when closing the file completes in the next callback */
spastor 0:1c358ea10753 961 status = connector_working;
spastor 0:1c358ea10753 962 }
spastor 0:1c358ea10753 963 goto done;
spastor 0:1c358ea10753 964 }
spastor 0:1c358ea10753 965 }
spastor 0:1c358ea10753 966
spastor 0:1c358ea10753 967 /* finished closing file */
spastor 0:1c358ea10753 968 if (context->status == connector_abort)
spastor 0:1c358ea10753 969 status = connector_abort;
spastor 0:1c358ea10753 970
spastor 0:1c358ea10753 971 /* abort condition or messaging error and session will be canceled */
spastor 0:1c358ea10753 972 if (status == connector_abort || service_request->service_type == msg_service_type_error)
spastor 0:1c358ea10753 973 goto done;
spastor 0:1c358ea10753 974
spastor 0:1c358ea10753 975 /* no errors, set last bit and send out last portion of data */
spastor 0:1c358ea10753 976 if (context->errnum == NULL)
spastor 0:1c358ea10753 977 {
spastor 0:1c358ea10753 978 MsgSetLastData(service_data->flags);
spastor 0:1c358ea10753 979 goto done;
spastor 0:1c358ea10753 980 }
spastor 0:1c358ea10753 981 /* errors */
spastor 0:1c358ea10753 982 if (MsgIsStart(service_data->flags))
spastor 0:1c358ea10753 983 {
spastor 0:1c358ea10753 984 /* send file system-level an error response if no data was sent yet, */
spastor 0:1c358ea10753 985 if (format_file_error_msg(connector_ptr, service_request, context) == connector_abort)
spastor 0:1c358ea10753 986 status = connector_abort;
spastor 0:1c358ea10753 987 }
spastor 0:1c358ea10753 988 else
spastor 0:1c358ea10753 989 {
spastor 0:1c358ea10753 990 /* or cancel the session, if it's late to send a file system level error response */
spastor 0:1c358ea10753 991 fs_set_service_error(service_request, connector_session_error_cancel);
spastor 0:1c358ea10753 992 }
spastor 0:1c358ea10753 993
spastor 0:1c358ea10753 994 done:
spastor 0:1c358ea10753 995 return status;
spastor 0:1c358ea10753 996 }
spastor 0:1c358ea10753 997
spastor 0:1c358ea10753 998
spastor 0:1c358ea10753 999 static connector_status_t process_file_get_response(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1000 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 1001 fs_context_t * const context)
spastor 0:1c358ea10753 1002 {
spastor 0:1c358ea10753 1003 msg_service_data_t * const service_data = service_request->need_data;
spastor 0:1c358ea10753 1004 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1005
spastor 0:1c358ea10753 1006 if ((context->errnum != NULL) || (FsGetState(context) >= fs_state_closing))
spastor 0:1c358ea10753 1007 {
spastor 0:1c358ea10753 1008 service_data->length_in_bytes = 0;
spastor 0:1c358ea10753 1009 goto close_file;
spastor 0:1c358ea10753 1010 }
spastor 0:1c358ea10753 1011
spastor 0:1c358ea10753 1012 {
spastor 0:1c358ea10753 1013 uint8_t * data_ptr = service_data->data_ptr;
spastor 0:1c358ea10753 1014 size_t buffer_size = service_data->length_in_bytes;
spastor 0:1c358ea10753 1015 connector_bool_t last_msg = connector_false;
spastor 0:1c358ea10753 1016 size_t bytes_read = 0;
spastor 0:1c358ea10753 1017 size_t bytes_to_read;
spastor 0:1c358ea10753 1018
spastor 0:1c358ea10753 1019 if (MsgIsStart(service_data->flags))
spastor 0:1c358ea10753 1020 {
spastor 0:1c358ea10753 1021 if (FsGetState(context) < fs_state_lseek)
spastor 0:1c358ea10753 1022 {
spastor 0:1c358ea10753 1023 if (context->data.f.offset != 0)
spastor 0:1c358ea10753 1024 {
spastor 0:1c358ea10753 1025 status = set_file_position(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1026 if (status == connector_pending)
spastor 0:1c358ea10753 1027 goto done;
spastor 0:1c358ea10753 1028
spastor 0:1c358ea10753 1029 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1030 goto close_file;
spastor 0:1c358ea10753 1031 }
spastor 0:1c358ea10753 1032 FsSetState(context, fs_state_lseek);
spastor 0:1c358ea10753 1033 }
spastor 0:1c358ea10753 1034 *data_ptr++ = fs_get_response_opcode;
spastor 0:1c358ea10753 1035 buffer_size--;
spastor 0:1c358ea10753 1036 }
spastor 0:1c358ea10753 1037
spastor 0:1c358ea10753 1038 /* bytes to read in this callback */
spastor 0:1c358ea10753 1039 bytes_to_read = MIN_VALUE(buffer_size, context->data.f.data_length - context->data.f.bytes_done);
spastor 0:1c358ea10753 1040
spastor 0:1c358ea10753 1041 while (bytes_to_read > 0)
spastor 0:1c358ea10753 1042 {
spastor 0:1c358ea10753 1043 size_t cnt = bytes_to_read;
spastor 0:1c358ea10753 1044 status = call_file_read_user(connector_ptr, service_request, context, data_ptr, &cnt);
spastor 0:1c358ea10753 1045
spastor 0:1c358ea10753 1046 if (status == connector_pending)
spastor 0:1c358ea10753 1047 {
spastor 0:1c358ea10753 1048 if (bytes_read > 0)
spastor 0:1c358ea10753 1049 status = connector_working; /* Return what's read already */
spastor 0:1c358ea10753 1050 break;
spastor 0:1c358ea10753 1051 }
spastor 0:1c358ea10753 1052 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1053 goto close_file;
spastor 0:1c358ea10753 1054
spastor 0:1c358ea10753 1055 if (cnt > 0)
spastor 0:1c358ea10753 1056 {
spastor 0:1c358ea10753 1057 data_ptr += cnt;
spastor 0:1c358ea10753 1058 bytes_to_read -= cnt;
spastor 0:1c358ea10753 1059 bytes_read += cnt;
spastor 0:1c358ea10753 1060 }
spastor 0:1c358ea10753 1061 else
spastor 0:1c358ea10753 1062 {
spastor 0:1c358ea10753 1063 bytes_to_read = 0;
spastor 0:1c358ea10753 1064 last_msg = connector_true;
spastor 0:1c358ea10753 1065 }
spastor 0:1c358ea10753 1066 }
spastor 0:1c358ea10753 1067 context->data.f.bytes_done += bytes_read;
spastor 0:1c358ea10753 1068 service_data->length_in_bytes = bytes_read;
spastor 0:1c358ea10753 1069
spastor 0:1c358ea10753 1070 if (MsgIsStart(service_data->flags))
spastor 0:1c358ea10753 1071 service_data->length_in_bytes++; /* opcode */
spastor 0:1c358ea10753 1072
spastor 0:1c358ea10753 1073 if (context->data.f.data_length == context->data.f.bytes_done)
spastor 0:1c358ea10753 1074 last_msg = connector_true;
spastor 0:1c358ea10753 1075
spastor 0:1c358ea10753 1076 if (!last_msg)
spastor 0:1c358ea10753 1077 goto done;
spastor 0:1c358ea10753 1078 }
spastor 0:1c358ea10753 1079
spastor 0:1c358ea10753 1080 close_file:
spastor 0:1c358ea10753 1081 status = process_get_close(connector_ptr,
spastor 0:1c358ea10753 1082 service_request,
spastor 0:1c358ea10753 1083 context,
spastor 0:1c358ea10753 1084 connector_request_id_file_system_close);
spastor 0:1c358ea10753 1085
spastor 0:1c358ea10753 1086 done:
spastor 0:1c358ea10753 1087 return status;
spastor 0:1c358ea10753 1088 }
spastor 0:1c358ea10753 1089
spastor 0:1c358ea10753 1090 static connector_status_t process_file_rm_request(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1091 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 1092 fs_context_t * const context)
spastor 0:1c358ea10753 1093 {
spastor 0:1c358ea10753 1094 msg_service_data_t * const service_data = service_request->have_data;
spastor 0:1c358ea10753 1095 char const * path = service_data->data_ptr;
spastor 0:1c358ea10753 1096 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1097
spastor 0:1c358ea10753 1098 path += FS_OPCODE_BYTES;
spastor 0:1c358ea10753 1099
spastor 0:1c358ea10753 1100 if (parse_file_path(context, path, service_data->length_in_bytes - FS_OPCODE_BYTES) == 0)
spastor 0:1c358ea10753 1101 goto done;
spastor 0:1c358ea10753 1102
spastor 0:1c358ea10753 1103 status = call_file_rm_user(connector_ptr, service_request, context, path);
spastor 0:1c358ea10753 1104
spastor 0:1c358ea10753 1105 done:
spastor 0:1c358ea10753 1106 return status;
spastor 0:1c358ea10753 1107 }
spastor 0:1c358ea10753 1108
spastor 0:1c358ea10753 1109 static connector_status_t process_file_response_nodata(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1110 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 1111 fs_context_t * const context,
spastor 0:1c358ea10753 1112 fs_opcode_t const opcode)
spastor 0:1c358ea10753 1113 {
spastor 0:1c358ea10753 1114 msg_service_data_t * const service_data = service_request->need_data;
spastor 0:1c358ea10753 1115 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1116
spastor 0:1c358ea10753 1117 if (context->errnum == NULL)
spastor 0:1c358ea10753 1118 {
spastor 0:1c358ea10753 1119 uint8_t * const data_ptr = service_data->data_ptr;
spastor 0:1c358ea10753 1120
spastor 0:1c358ea10753 1121 *data_ptr = opcode;
spastor 0:1c358ea10753 1122
spastor 0:1c358ea10753 1123 service_data->length_in_bytes = sizeof *data_ptr;
spastor 0:1c358ea10753 1124 MsgSetLastData(service_data->flags);
spastor 0:1c358ea10753 1125 }
spastor 0:1c358ea10753 1126 else
spastor 0:1c358ea10753 1127 {
spastor 0:1c358ea10753 1128 if (format_file_error_msg(connector_ptr, service_request, context) == connector_abort)
spastor 0:1c358ea10753 1129 {
spastor 0:1c358ea10753 1130 status = connector_abort;
spastor 0:1c358ea10753 1131 }
spastor 0:1c358ea10753 1132 }
spastor 0:1c358ea10753 1133 return status;
spastor 0:1c358ea10753 1134 }
spastor 0:1c358ea10753 1135
spastor 0:1c358ea10753 1136 static size_t parse_file_put_header(fs_context_t * const context,
spastor 0:1c358ea10753 1137 uint8_t const * const header_ptr,
spastor 0:1c358ea10753 1138 size_t const buffer_size)
spastor 0:1c358ea10753 1139 {
spastor 0:1c358ea10753 1140 /*
spastor 0:1c358ea10753 1141 *
spastor 0:1c358ea10753 1142 * File System Put request format:
spastor 0:1c358ea10753 1143 * --------------------------------------------
spastor 0:1c358ea10753 1144 * | 0 | N | +1 | +4 | N |
spastor 0:1c358ea10753 1145 * --------------------------------------------
spastor 0:1c358ea10753 1146 * | Opcode | Path | Flags | Offset | Payload |
spastor 0:1c358ea10753 1147 * --------------------------------------------
spastor 0:1c358ea10753 1148 *
spastor 0:1c358ea10753 1149 */
spastor 0:1c358ea10753 1150
spastor 0:1c358ea10753 1151 enum {
spastor 0:1c358ea10753 1152 field_define(fs_put_request, flags, uint8_t),
spastor 0:1c358ea10753 1153 field_define(fs_put_request, offset, uint32_t),
spastor 0:1c358ea10753 1154 record_end(fs_put_request_header)
spastor 0:1c358ea10753 1155 };
spastor 0:1c358ea10753 1156 uint8_t const *fs_put_request = header_ptr + FS_OPCODE_BYTES;
spastor 0:1c358ea10753 1157 size_t const header_len = record_bytes(fs_put_request_header) + FS_OPCODE_BYTES;
spastor 0:1c358ea10753 1158
spastor 0:1c358ea10753 1159 size_t len = parse_file_path(context, fs_put_request, buffer_size - header_len);
spastor 0:1c358ea10753 1160 if (len == 0)
spastor 0:1c358ea10753 1161 goto done;
spastor 0:1c358ea10753 1162
spastor 0:1c358ea10753 1163 fs_put_request += len;
spastor 0:1c358ea10753 1164 context->flags |= message_load_u8(fs_put_request, flags);
spastor 0:1c358ea10753 1165 context->data.f.offset = message_load_be32(fs_put_request, offset);
spastor 0:1c358ea10753 1166 if (context->data.f.offset < 0)
spastor 0:1c358ea10753 1167 {
spastor 0:1c358ea10753 1168 FsSetInternalError(context, fs_error_large_file);
spastor 0:1c358ea10753 1169 len = 0;
spastor 0:1c358ea10753 1170 goto done;
spastor 0:1c358ea10753 1171 }
spastor 0:1c358ea10753 1172 len += header_len;
spastor 0:1c358ea10753 1173
spastor 0:1c358ea10753 1174 done:
spastor 0:1c358ea10753 1175 return len;
spastor 0:1c358ea10753 1176 }
spastor 0:1c358ea10753 1177
spastor 0:1c358ea10753 1178
spastor 0:1c358ea10753 1179 static connector_status_t process_file_put_request(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1180 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 1181 fs_context_t * const context)
spastor 0:1c358ea10753 1182 {
spastor 0:1c358ea10753 1183 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1184
spastor 0:1c358ea10753 1185 if ((context->errnum != NULL) || (FsGetState(context) >= fs_state_closing))
spastor 0:1c358ea10753 1186 goto close_file;
spastor 0:1c358ea10753 1187
spastor 0:1c358ea10753 1188 {
spastor 0:1c358ea10753 1189 msg_service_data_t * const service_data = service_request->have_data;
spastor 0:1c358ea10753 1190 uint8_t const * data_ptr = service_data->data_ptr;
spastor 0:1c358ea10753 1191 size_t bytes_to_write = service_data->length_in_bytes;
spastor 0:1c358ea10753 1192 size_t bytes_written = 0;
spastor 0:1c358ea10753 1193
spastor 0:1c358ea10753 1194 if (MsgIsStart(service_data->flags))
spastor 0:1c358ea10753 1195 {
spastor 0:1c358ea10753 1196 size_t header_len = parse_file_put_header(context, data_ptr, service_data->length_in_bytes);
spastor 0:1c358ea10753 1197 if (header_len == 0)
spastor 0:1c358ea10753 1198 goto done;
spastor 0:1c358ea10753 1199
spastor 0:1c358ea10753 1200 if (FsGetState(context) < fs_state_open)
spastor 0:1c358ea10753 1201 {
spastor 0:1c358ea10753 1202 int open_flags = CONNECTOR_FILE_O_WRONLY | CONNECTOR_FILE_O_CREAT;
spastor 0:1c358ea10753 1203 char const * path = service_data->data_ptr;
spastor 0:1c358ea10753 1204 path += FS_OPCODE_BYTES;
spastor 0:1c358ea10753 1205
spastor 0:1c358ea10753 1206 if (FsNeedTrunc(context))
spastor 0:1c358ea10753 1207 {
spastor 0:1c358ea10753 1208 if (context->data.f.offset == 0)
spastor 0:1c358ea10753 1209 {
spastor 0:1c358ea10753 1210 open_flags |= CONNECTOR_FILE_O_TRUNC;
spastor 0:1c358ea10753 1211 FsClearTrunc(context);
spastor 0:1c358ea10753 1212 }
spastor 0:1c358ea10753 1213 }
spastor 0:1c358ea10753 1214
spastor 0:1c358ea10753 1215 status = call_file_open_user(connector_ptr, service_request, context, path, open_flags);
spastor 0:1c358ea10753 1216 if (FsGetState(context) != fs_state_open)
spastor 0:1c358ea10753 1217 goto done;
spastor 0:1c358ea10753 1218 }
spastor 0:1c358ea10753 1219
spastor 0:1c358ea10753 1220 if (FsGetState(context) < fs_state_lseek)
spastor 0:1c358ea10753 1221 {
spastor 0:1c358ea10753 1222 if (context->data.f.offset != 0)
spastor 0:1c358ea10753 1223 {
spastor 0:1c358ea10753 1224 status = set_file_position(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1225 if (status == connector_pending)
spastor 0:1c358ea10753 1226 goto done;
spastor 0:1c358ea10753 1227
spastor 0:1c358ea10753 1228 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1229 goto close_file;
spastor 0:1c358ea10753 1230 }
spastor 0:1c358ea10753 1231 FsSetState(context, fs_state_lseek);
spastor 0:1c358ea10753 1232 }
spastor 0:1c358ea10753 1233 data_ptr += header_len;
spastor 0:1c358ea10753 1234 bytes_to_write -= header_len;
spastor 0:1c358ea10753 1235 }
spastor 0:1c358ea10753 1236
spastor 0:1c358ea10753 1237 data_ptr += context->data.f.bytes_done;
spastor 0:1c358ea10753 1238 bytes_to_write -= context->data.f.bytes_done;
spastor 0:1c358ea10753 1239
spastor 0:1c358ea10753 1240 while(bytes_to_write > 0)
spastor 0:1c358ea10753 1241 {
spastor 0:1c358ea10753 1242 size_t cnt = bytes_to_write;
spastor 0:1c358ea10753 1243 status = call_file_write_user(connector_ptr, service_request, context, data_ptr, &cnt);
spastor 0:1c358ea10753 1244
spastor 0:1c358ea10753 1245 if (status == connector_pending)
spastor 0:1c358ea10753 1246 {
spastor 0:1c358ea10753 1247 context->data.f.bytes_done += bytes_written;
spastor 0:1c358ea10753 1248 context->data.f.offset += bytes_written;
spastor 0:1c358ea10753 1249 goto done;
spastor 0:1c358ea10753 1250 }
spastor 0:1c358ea10753 1251 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1252 goto close_file;
spastor 0:1c358ea10753 1253
spastor 0:1c358ea10753 1254 data_ptr += cnt;
spastor 0:1c358ea10753 1255 bytes_to_write -= cnt;
spastor 0:1c358ea10753 1256 bytes_written += cnt;
spastor 0:1c358ea10753 1257 }
spastor 0:1c358ea10753 1258 context->data.f.bytes_done = 0;
spastor 0:1c358ea10753 1259 context->data.f.offset += bytes_written;
spastor 0:1c358ea10753 1260
spastor 0:1c358ea10753 1261 if (!MsgIsLastData(service_data->flags))
spastor 0:1c358ea10753 1262 goto done;
spastor 0:1c358ea10753 1263
spastor 0:1c358ea10753 1264 if (FsNeedTrunc(context))
spastor 0:1c358ea10753 1265 {
spastor 0:1c358ea10753 1266 status = call_file_ftruncate_user(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1267 if (status == connector_pending)
spastor 0:1c358ea10753 1268 goto done;
spastor 0:1c358ea10753 1269 }
spastor 0:1c358ea10753 1270 }
spastor 0:1c358ea10753 1271 close_file:
spastor 0:1c358ea10753 1272 status = call_file_close_user(connector_ptr,
spastor 0:1c358ea10753 1273 service_request,
spastor 0:1c358ea10753 1274 context,
spastor 0:1c358ea10753 1275 connector_request_id_file_system_close);
spastor 0:1c358ea10753 1276
spastor 0:1c358ea10753 1277 if (status == connector_pending)
spastor 0:1c358ea10753 1278 goto done;
spastor 0:1c358ea10753 1279
spastor 0:1c358ea10753 1280 /* finished closing file */
spastor 0:1c358ea10753 1281 if (context->status == connector_abort)
spastor 0:1c358ea10753 1282 status = connector_abort;
spastor 0:1c358ea10753 1283
spastor 0:1c358ea10753 1284 done:
spastor 0:1c358ea10753 1285 return status;
spastor 0:1c358ea10753 1286 }
spastor 0:1c358ea10753 1287
spastor 0:1c358ea10753 1288 static size_t parse_file_ls_header(fs_context_t * const context,
spastor 0:1c358ea10753 1289 uint8_t const * const header_ptr,
spastor 0:1c358ea10753 1290 size_t const buffer_size)
spastor 0:1c358ea10753 1291 {
spastor 0:1c358ea10753 1292 /*
spastor 0:1c358ea10753 1293 * File System Ls request format:
spastor 0:1c358ea10753 1294 * ----------------------------
spastor 0:1c358ea10753 1295 * | 0 | N | 1 |
spastor 0:1c358ea10753 1296 * ----------------------------
spastor 0:1c358ea10753 1297 * | Opcode | Path | hash alg |
spastor 0:1c358ea10753 1298 * ----------------------------
spastor 0:1c358ea10753 1299 */
spastor 0:1c358ea10753 1300 uint8_t const * data_ptr = header_ptr + FS_OPCODE_BYTES;
spastor 0:1c358ea10753 1301 const size_t header_len = 1 + FS_OPCODE_BYTES;
spastor 0:1c358ea10753 1302 connector_file_system_hash_algorithm_t hash_alg;
spastor 0:1c358ea10753 1303
spastor 0:1c358ea10753 1304 size_t len = parse_file_path(context, data_ptr, buffer_size - header_len);
spastor 0:1c358ea10753 1305 if (len != 0)
spastor 0:1c358ea10753 1306 {
spastor 0:1c358ea10753 1307 data_ptr += len;
spastor 0:1c358ea10753 1308 len += header_len;
spastor 0:1c358ea10753 1309
spastor 0:1c358ea10753 1310 hash_alg = (connector_file_system_hash_algorithm_t) *data_ptr;
spastor 0:1c358ea10753 1311
spastor 0:1c358ea10753 1312 switch (hash_alg)
spastor 0:1c358ea10753 1313 {
spastor 0:1c358ea10753 1314 case connector_file_system_hash_crc32:
spastor 0:1c358ea10753 1315 case connector_file_system_hash_md5:
spastor 0:1c358ea10753 1316 case connector_file_system_hash_best:
spastor 0:1c358ea10753 1317 case connector_file_system_hash_none:
spastor 0:1c358ea10753 1318 context->data.d.hash_alg = hash_alg;
spastor 0:1c358ea10753 1319 break;
spastor 0:1c358ea10753 1320
spastor 0:1c358ea10753 1321 default:
spastor 0:1c358ea10753 1322 FsSetInternalError(context, fs_error_invalid_hash);
spastor 0:1c358ea10753 1323 len = 0;
spastor 0:1c358ea10753 1324 }
spastor 0:1c358ea10753 1325 }
spastor 0:1c358ea10753 1326 return len;
spastor 0:1c358ea10753 1327 }
spastor 0:1c358ea10753 1328
spastor 0:1c358ea10753 1329 static size_t format_file_ls_response_header(connector_file_system_hash_algorithm_t const hash_alg,
spastor 0:1c358ea10753 1330 size_t const hash_size,
spastor 0:1c358ea10753 1331 uint8_t * const data_ptr)
spastor 0:1c358ea10753 1332 {
spastor 0:1c358ea10753 1333 /*
spastor 0:1c358ea10753 1334 * File System Ls response header format:
spastor 0:1c358ea10753 1335 * --------------------------------
spastor 0:1c358ea10753 1336 * | 1 | 1 | 1 |
spastor 0:1c358ea10753 1337 * --------------------------------
spastor 0:1c358ea10753 1338 * | opcode | hash_alg | hash_bytes |
spastor 0:1c358ea10753 1339 * --------------------------------
spastor 0:1c358ea10753 1340 */
spastor 0:1c358ea10753 1341
spastor 0:1c358ea10753 1342 enum {
spastor 0:1c358ea10753 1343 field_define(fs_ls_response, opcode, uint8_t),
spastor 0:1c358ea10753 1344 field_define(fs_ls_response, hash_alg, uint8_t),
spastor 0:1c358ea10753 1345 field_define(fs_ls_response, hash_bytes, uint8_t),
spastor 0:1c358ea10753 1346 record_end(fs_ls_response_header)
spastor 0:1c358ea10753 1347 };
spastor 0:1c358ea10753 1348
spastor 0:1c358ea10753 1349 uint8_t * fs_ls_response = data_ptr;
spastor 0:1c358ea10753 1350
spastor 0:1c358ea10753 1351 message_store_u8(fs_ls_response, opcode, fs_ls_response_opcode);
spastor 0:1c358ea10753 1352 message_store_u8(fs_ls_response, hash_alg, hash_alg);
spastor 0:1c358ea10753 1353 message_store_u8(fs_ls_response, hash_bytes, hash_size);
spastor 0:1c358ea10753 1354
spastor 0:1c358ea10753 1355 return record_bytes(fs_ls_response_header);
spastor 0:1c358ea10753 1356 }
spastor 0:1c358ea10753 1357
spastor 0:1c358ea10753 1358 static size_t file_ls_resp_header_size(void)
spastor 0:1c358ea10753 1359 {
spastor 0:1c358ea10753 1360 /*
spastor 0:1c358ea10753 1361 * File System Ls request format:
spastor 0:1c358ea10753 1362 * ----------------------------
spastor 0:1c358ea10753 1363 * | 1 | 4 | 0/4 |
spastor 0:1c358ea10753 1364 * ----------------------------
spastor 0:1c358ea10753 1365 * | flags | last | size |
spastor 0:1c358ea10753 1366 * | | modified | |
spastor 0:1c358ea10753 1367 * ----------------------------
spastor 0:1c358ea10753 1368 */
spastor 0:1c358ea10753 1369
spastor 0:1c358ea10753 1370 enum {
spastor 0:1c358ea10753 1371 field_define(fs_ls_response, flags, uint8_t),
spastor 0:1c358ea10753 1372 field_define(fs_ls_response, last_modified, uint32_t),
spastor 0:1c358ea10753 1373 field_define(fs_ls_response, size, connector_file_offset_t),
spastor 0:1c358ea10753 1374 record_end(fs_ls_response_file)
spastor 0:1c358ea10753 1375 };
spastor 0:1c358ea10753 1376 return record_bytes(fs_ls_response_file);
spastor 0:1c358ea10753 1377 }
spastor 0:1c358ea10753 1378
spastor 0:1c358ea10753 1379 static size_t format_file_ls_response(fs_context_t const * context,
spastor 0:1c358ea10753 1380 char const * path,
spastor 0:1c358ea10753 1381 size_t const path_len,
spastor 0:1c358ea10753 1382 uint8_t * const data_ptr)
spastor 0:1c358ea10753 1383 {
spastor 0:1c358ea10753 1384 /*
spastor 0:1c358ea10753 1385 * File System Ls request format:
spastor 0:1c358ea10753 1386 * ----------------------------
spastor 0:1c358ea10753 1387 * | 1 | 4 | 0/4 |
spastor 0:1c358ea10753 1388 * ----------------------------
spastor 0:1c358ea10753 1389 * | flags | last | size |
spastor 0:1c358ea10753 1390 * | | modified | |
spastor 0:1c358ea10753 1391 * ----------------------------
spastor 0:1c358ea10753 1392 */
spastor 0:1c358ea10753 1393
spastor 0:1c358ea10753 1394 enum {
spastor 0:1c358ea10753 1395 field_define(fs_ls_response, flags, uint8_t),
spastor 0:1c358ea10753 1396 field_define(fs_ls_response, last_modified, uint32_t),
spastor 0:1c358ea10753 1397 record_end(fs_ls_response_dir)
spastor 0:1c358ea10753 1398 };
spastor 0:1c358ea10753 1399 enum {
spastor 0:1c358ea10753 1400 field_define(fs_ls_response, size, connector_file_offset_t),
spastor 0:1c358ea10753 1401 record_end(fs_ls_response_file)
spastor 0:1c358ea10753 1402 };
spastor 0:1c358ea10753 1403
spastor 0:1c358ea10753 1404 uint8_t * fs_ls_response = data_ptr + path_len;
spastor 0:1c358ea10753 1405 uint8_t flags = FsIsDir(context) ? FS_IS_DIR_FLAG : 0;
spastor 0:1c358ea10753 1406 size_t result;
spastor 0:1c358ea10753 1407
spastor 0:1c358ea10753 1408 #if (defined CONNECTOR_FILE_SYSTEM_HAS_LARGE_FILES)
spastor 0:1c358ea10753 1409 flags |= FS_IS_LARGE_FLAG;
spastor 0:1c358ea10753 1410 #endif
spastor 0:1c358ea10753 1411 memcpy(data_ptr, path, path_len);
spastor 0:1c358ea10753 1412
spastor 0:1c358ea10753 1413 message_store_u8(fs_ls_response, flags, flags);
spastor 0:1c358ea10753 1414 message_store_be32(fs_ls_response, last_modified, context->data.d.last_modified);
spastor 0:1c358ea10753 1415 result = path_len + record_bytes(fs_ls_response_dir);
spastor 0:1c358ea10753 1416
spastor 0:1c358ea10753 1417 if (!FsIsDir(context))
spastor 0:1c358ea10753 1418 {
spastor 0:1c358ea10753 1419 fs_ls_response += record_bytes(fs_ls_response_dir);
spastor 0:1c358ea10753 1420 #if (defined CONNECTOR_FILE_SYSTEM_HAS_LARGE_FILES)
spastor 0:1c358ea10753 1421 message_store_be64(fs_ls_response, size, context->data.d.file_size);
spastor 0:1c358ea10753 1422 #else
spastor 0:1c358ea10753 1423 message_store_be32(fs_ls_response, size, context->data.d.file_size);
spastor 0:1c358ea10753 1424 #endif
spastor 0:1c358ea10753 1425 result += record_bytes(fs_ls_response_file);
spastor 0:1c358ea10753 1426 }
spastor 0:1c358ea10753 1427
spastor 0:1c358ea10753 1428 return result;
spastor 0:1c358ea10753 1429 }
spastor 0:1c358ea10753 1430
spastor 0:1c358ea10753 1431 static connector_status_t file_store_path(fs_context_t * const context,
spastor 0:1c358ea10753 1432 char const * const path)
spastor 0:1c358ea10753 1433 {
spastor 0:1c358ea10753 1434 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1435 size_t path_len = strlen(path);
spastor 0:1c358ea10753 1436
spastor 0:1c358ea10753 1437 if (FsIsDir(context) && path[path_len - 1] != '/')
spastor 0:1c358ea10753 1438 {
spastor 0:1c358ea10753 1439 path_len++;
spastor 0:1c358ea10753 1440 }
spastor 0:1c358ea10753 1441
spastor 0:1c358ea10753 1442 if (path_len >= CONNECTOR_FILE_SYSTEM_MAX_PATH_LENGTH)
spastor 0:1c358ea10753 1443 {
spastor 0:1c358ea10753 1444 FsSetInternalError(context, fs_error_path_too_long);
spastor 0:1c358ea10753 1445 goto done;
spastor 0:1c358ea10753 1446 }
spastor 0:1c358ea10753 1447
spastor 0:1c358ea10753 1448 memcpy(context->data.d.path, path, path_len + 1);
spastor 0:1c358ea10753 1449
spastor 0:1c358ea10753 1450 if (FsIsDir(context) && (path[path_len - 1] != '/'))
spastor 0:1c358ea10753 1451 {
spastor 0:1c358ea10753 1452 context->data.d.path[path_len - 1] = '/';
spastor 0:1c358ea10753 1453 context->data.d.path[path_len] = '\0';
spastor 0:1c358ea10753 1454 }
spastor 0:1c358ea10753 1455 context->data.d.path_len = path_len;
spastor 0:1c358ea10753 1456
spastor 0:1c358ea10753 1457 done:
spastor 0:1c358ea10753 1458 return status;
spastor 0:1c358ea10753 1459 }
spastor 0:1c358ea10753 1460
spastor 0:1c358ea10753 1461 static connector_status_t process_file_ls_request(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1462 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 1463 fs_context_t * const context)
spastor 0:1c358ea10753 1464 {
spastor 0:1c358ea10753 1465 msg_service_data_t * const service_data = service_request->have_data;
spastor 0:1c358ea10753 1466 char const * path = service_data->data_ptr;
spastor 0:1c358ea10753 1467 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1468
spastor 0:1c358ea10753 1469 path += FS_OPCODE_BYTES;
spastor 0:1c358ea10753 1470
spastor 0:1c358ea10753 1471 if (context->errnum != NULL)
spastor 0:1c358ea10753 1472 goto done;
spastor 0:1c358ea10753 1473
spastor 0:1c358ea10753 1474 if (parse_file_ls_header(context, service_data->data_ptr, service_data->length_in_bytes) == 0)
spastor 0:1c358ea10753 1475 goto done;
spastor 0:1c358ea10753 1476
spastor 0:1c358ea10753 1477 if (FsGetState(context) < fs_state_stat)
spastor 0:1c358ea10753 1478 {
spastor 0:1c358ea10753 1479 status = call_file_stat_user(connector_ptr, service_request, context, path, context->data.d.hash_alg);
spastor 0:1c358ea10753 1480 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1481 {
spastor 0:1c358ea10753 1482 goto done;
spastor 0:1c358ea10753 1483 }
spastor 0:1c358ea10753 1484
spastor 0:1c358ea10753 1485 FsSetState(context, fs_state_stat);
spastor 0:1c358ea10753 1486 }
spastor 0:1c358ea10753 1487 if (FsIsDir(context))
spastor 0:1c358ea10753 1488 {
spastor 0:1c358ea10753 1489 status = call_file_opendir_user(connector_ptr, service_request, context, path);
spastor 0:1c358ea10753 1490 if (FsGetState(context) != fs_state_open)
spastor 0:1c358ea10753 1491 goto done;
spastor 0:1c358ea10753 1492 }
spastor 0:1c358ea10753 1493 else
spastor 0:1c358ea10753 1494 {
spastor 0:1c358ea10753 1495 FsSetLsSingleFile(context);
spastor 0:1c358ea10753 1496 }
spastor 0:1c358ea10753 1497
spastor 0:1c358ea10753 1498 /* call_file_stat_user must be done before store path, to strcat '/' to dir path */
spastor 0:1c358ea10753 1499 status = file_store_path(context, path);
spastor 0:1c358ea10753 1500
spastor 0:1c358ea10753 1501 done:
spastor 0:1c358ea10753 1502 return status;
spastor 0:1c358ea10753 1503 }
spastor 0:1c358ea10753 1504
spastor 0:1c358ea10753 1505 static connector_status_t process_file_ls_response(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1506 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 1507 fs_context_t * const context)
spastor 0:1c358ea10753 1508 {
spastor 0:1c358ea10753 1509 msg_service_data_t * const service_data = service_request->need_data;
spastor 0:1c358ea10753 1510 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1511
spastor 0:1c358ea10753 1512 if ((context->errnum != NULL) || (FsGetState(context) >= fs_state_closing))
spastor 0:1c358ea10753 1513 {
spastor 0:1c358ea10753 1514 service_data->length_in_bytes = 0;
spastor 0:1c358ea10753 1515 goto close_dir;
spastor 0:1c358ea10753 1516 }
spastor 0:1c358ea10753 1517 {
spastor 0:1c358ea10753 1518 uint8_t * data_ptr = service_data->data_ptr;
spastor 0:1c358ea10753 1519 size_t buffer_size = service_data->length_in_bytes;
spastor 0:1c358ea10753 1520 size_t resp_len = 0;
spastor 0:1c358ea10753 1521
spastor 0:1c358ea10753 1522 size_t const header_len = file_ls_resp_header_size();
spastor 0:1c358ea10753 1523 size_t hash_len = file_hash_size(context->data.d.hash_alg);
spastor 0:1c358ea10753 1524 char * file_path;
spastor 0:1c358ea10753 1525 size_t file_path_len;
spastor 0:1c358ea10753 1526
spastor 0:1c358ea10753 1527 if (MsgIsStart(service_data->flags))
spastor 0:1c358ea10753 1528 {
spastor 0:1c358ea10753 1529 resp_len = format_file_ls_response_header(context->data.d.hash_alg, hash_len, data_ptr);
spastor 0:1c358ea10753 1530 data_ptr += resp_len;
spastor 0:1c358ea10753 1531 buffer_size -= resp_len;
spastor 0:1c358ea10753 1532 }
spastor 0:1c358ea10753 1533
spastor 0:1c358ea10753 1534 if (FsIsLsSingleFile(context))
spastor 0:1c358ea10753 1535 {
spastor 0:1c358ea10753 1536 /* ls command was issued for a single file */
spastor 0:1c358ea10753 1537 file_path_len = context->data.d.path_len + 1;
spastor 0:1c358ea10753 1538 file_path = context->data.d.path;
spastor 0:1c358ea10753 1539
spastor 0:1c358ea10753 1540 if ((file_path_len + header_len + hash_len) > buffer_size)
spastor 0:1c358ea10753 1541 {
spastor 0:1c358ea10753 1542 FsSetInternalError(context, fs_error_path_too_long);
spastor 0:1c358ea10753 1543 goto close_dir;
spastor 0:1c358ea10753 1544 }
spastor 0:1c358ea10753 1545
spastor 0:1c358ea10753 1546 if (hash_len != 0)
spastor 0:1c358ea10753 1547 {
spastor 0:1c358ea10753 1548 uint8_t * const hash_ptr = data_ptr + file_path_len + header_len;
spastor 0:1c358ea10753 1549 status = call_file_hash_user(connector_ptr, service_request, context, file_path, hash_ptr);
spastor 0:1c358ea10753 1550 if (status == connector_pending || status == connector_abort)
spastor 0:1c358ea10753 1551 goto done;
spastor 0:1c358ea10753 1552
spastor 0:1c358ea10753 1553 if (status == connector_working && context->errnum != NULL)
spastor 0:1c358ea10753 1554 {
spastor 0:1c358ea10753 1555 if (format_file_error_msg(connector_ptr, service_request, context) == connector_abort)
spastor 0:1c358ea10753 1556 {
spastor 0:1c358ea10753 1557 status = connector_abort;
spastor 0:1c358ea10753 1558 }
spastor 0:1c358ea10753 1559 goto done;
spastor 0:1c358ea10753 1560 }
spastor 0:1c358ea10753 1561 resp_len += hash_len;
spastor 0:1c358ea10753 1562 }
spastor 0:1c358ea10753 1563
spastor 0:1c358ea10753 1564 MsgSetLastData(service_data->flags);
spastor 0:1c358ea10753 1565 }
spastor 0:1c358ea10753 1566 else
spastor 0:1c358ea10753 1567 {
spastor 0:1c358ea10753 1568 /* ls command was issued for a directory */
spastor 0:1c358ea10753 1569 file_path = context->data.d.path + context->data.d.path_len;
spastor 0:1c358ea10753 1570
spastor 0:1c358ea10753 1571 while (FsGetState(context) < fs_state_readdir)
spastor 0:1c358ea10753 1572 {
spastor 0:1c358ea10753 1573 /* read next dir entry */
spastor 0:1c358ea10753 1574 size_t len = header_len + hash_len + context->data.d.path_len;
spastor 0:1c358ea10753 1575 size_t path_max = 0;
spastor 0:1c358ea10753 1576
spastor 0:1c358ea10753 1577 context->flags = 0;
spastor 0:1c358ea10753 1578 /* minimum of bytes left for the entry name in output buffer and context->data.d.path buffer */
spastor 0:1c358ea10753 1579 if (len < buffer_size)
spastor 0:1c358ea10753 1580 path_max = MIN_VALUE((buffer_size - len), (CONNECTOR_FILE_SYSTEM_MAX_PATH_LENGTH - context->data.d.path_len));
spastor 0:1c358ea10753 1581
spastor 0:1c358ea10753 1582 status = call_file_readdir_user(connector_ptr, service_request, context, file_path, path_max);
spastor 0:1c358ea10753 1583 if (status == connector_pending)
spastor 0:1c358ea10753 1584 goto done;
spastor 0:1c358ea10753 1585
spastor 0:1c358ea10753 1586 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1587 goto close_dir;
spastor 0:1c358ea10753 1588
spastor 0:1c358ea10753 1589 if (*file_path == '\0')
spastor 0:1c358ea10753 1590 {
spastor 0:1c358ea10753 1591 /* all entries processed */
spastor 0:1c358ea10753 1592 service_data->length_in_bytes = resp_len;
spastor 0:1c358ea10753 1593 goto close_dir;
spastor 0:1c358ea10753 1594 }
spastor 0:1c358ea10753 1595 /* Don't send "." in any directory and ".." in "/" directory up to Device Cloud */
spastor 0:1c358ea10753 1596 if ((memcmp(file_path, ".", 2) != 0) &&
spastor 0:1c358ea10753 1597 (memcmp(context->data.d.path, "/..", 3) != 0))
spastor 0:1c358ea10753 1598 {
spastor 0:1c358ea10753 1599 FsSetState(context, fs_state_readdir);
spastor 0:1c358ea10753 1600 }
spastor 0:1c358ea10753 1601 }
spastor 0:1c358ea10753 1602
spastor 0:1c358ea10753 1603 file_path_len = strlen(file_path) + 1;
spastor 0:1c358ea10753 1604
spastor 0:1c358ea10753 1605 if (FsGetState(context) < fs_state_stat_dir_entry)
spastor 0:1c358ea10753 1606 {
spastor 0:1c358ea10753 1607 status = call_file_stat_dir_entry_user(connector_ptr, service_request, context, context->data.d.path);
spastor 0:1c358ea10753 1608 if (status == connector_pending)
spastor 0:1c358ea10753 1609 goto done;
spastor 0:1c358ea10753 1610
spastor 0:1c358ea10753 1611 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1612 goto close_dir;
spastor 0:1c358ea10753 1613
spastor 0:1c358ea10753 1614 FsSetState(context, fs_state_stat_dir_entry);
spastor 0:1c358ea10753 1615 }
spastor 0:1c358ea10753 1616 file_path = context->data.d.path;
spastor 0:1c358ea10753 1617 file_path_len = context->data.d.path_len + file_path_len;
spastor 0:1c358ea10753 1618
spastor 0:1c358ea10753 1619 if (FsIsDir(context))
spastor 0:1c358ea10753 1620 hash_len = 0;
spastor 0:1c358ea10753 1621
spastor 0:1c358ea10753 1622 if (hash_len != 0)
spastor 0:1c358ea10753 1623 {
spastor 0:1c358ea10753 1624 uint8_t * const hash_ptr = data_ptr + file_path_len + header_len;
spastor 0:1c358ea10753 1625
spastor 0:1c358ea10753 1626 if (FsIsReg(context))
spastor 0:1c358ea10753 1627 {
spastor 0:1c358ea10753 1628 status = call_file_hash_user(connector_ptr, service_request, context, file_path, hash_ptr);
spastor 0:1c358ea10753 1629 if (status == connector_pending)
spastor 0:1c358ea10753 1630 goto done;
spastor 0:1c358ea10753 1631
spastor 0:1c358ea10753 1632 if (!FsOperationSuccess(status, context))
spastor 0:1c358ea10753 1633 goto close_dir;
spastor 0:1c358ea10753 1634 }
spastor 0:1c358ea10753 1635 else
spastor 0:1c358ea10753 1636 {
spastor 0:1c358ea10753 1637 memset(hash_ptr, 0, hash_len);
spastor 0:1c358ea10753 1638 }
spastor 0:1c358ea10753 1639 resp_len += hash_len;
spastor 0:1c358ea10753 1640 }
spastor 0:1c358ea10753 1641
spastor 0:1c358ea10753 1642 /* to read next dir entry */
spastor 0:1c358ea10753 1643 FsSetState(context, fs_state_open);
spastor 0:1c358ea10753 1644 }
spastor 0:1c358ea10753 1645 resp_len += format_file_ls_response(context, file_path, file_path_len, data_ptr);
spastor 0:1c358ea10753 1646 service_data->length_in_bytes = resp_len;
spastor 0:1c358ea10753 1647 goto done;
spastor 0:1c358ea10753 1648 }
spastor 0:1c358ea10753 1649
spastor 0:1c358ea10753 1650 close_dir:
spastor 0:1c358ea10753 1651 status = process_get_close(connector_ptr,
spastor 0:1c358ea10753 1652 service_request,
spastor 0:1c358ea10753 1653 context,
spastor 0:1c358ea10753 1654 connector_request_id_file_system_closedir);
spastor 0:1c358ea10753 1655 done:
spastor 0:1c358ea10753 1656 return status;
spastor 0:1c358ea10753 1657 }
spastor 0:1c358ea10753 1658
spastor 0:1c358ea10753 1659 static connector_status_t allocate_file_context(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1660 fs_opcode_t const opcode,
spastor 0:1c358ea10753 1661 fs_context_t * * const result)
spastor 0:1c358ea10753 1662 {
spastor 0:1c358ea10753 1663 fs_context_t * context = NULL;
spastor 0:1c358ea10753 1664 connector_status_t status;
spastor 0:1c358ea10753 1665
spastor 0:1c358ea10753 1666 void * ptr;
spastor 0:1c358ea10753 1667
spastor 0:1c358ea10753 1668 status = malloc_data_buffer(connector_ptr, sizeof *context, named_buffer_id(msg_service), &ptr);
spastor 0:1c358ea10753 1669 if (status != connector_working)
spastor 0:1c358ea10753 1670 goto done;
spastor 0:1c358ea10753 1671
spastor 0:1c358ea10753 1672 context = ptr;
spastor 0:1c358ea10753 1673
spastor 0:1c358ea10753 1674 context->handle = NULL;
spastor 0:1c358ea10753 1675 context->user_context = NULL;
spastor 0:1c358ea10753 1676 context->flags = 0;
spastor 0:1c358ea10753 1677 context->errnum = NULL;
spastor 0:1c358ea10753 1678 context->state = fs_state_none;
spastor 0:1c358ea10753 1679 context->status = connector_working;
spastor 0:1c358ea10753 1680
spastor 0:1c358ea10753 1681 if (opcode != fs_ls_request_opcode)
spastor 0:1c358ea10753 1682 {
spastor 0:1c358ea10753 1683 context->data.f.bytes_done = 0;
spastor 0:1c358ea10753 1684 }
spastor 0:1c358ea10753 1685
spastor 0:1c358ea10753 1686 done:
spastor 0:1c358ea10753 1687 *result = context;
spastor 0:1c358ea10753 1688 return status;
spastor 0:1c358ea10753 1689 }
spastor 0:1c358ea10753 1690
spastor 0:1c358ea10753 1691 static connector_status_t file_system_request_callback(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1692 msg_service_request_t * const service_request)
spastor 0:1c358ea10753 1693 {
spastor 0:1c358ea10753 1694 msg_session_t * const session = service_request->session;
spastor 0:1c358ea10753 1695 msg_service_data_t * const service_data = service_request->have_data;
spastor 0:1c358ea10753 1696 fs_context_t * context = session->service_context;
spastor 0:1c358ea10753 1697 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1698
spastor 0:1c358ea10753 1699 if (MsgIsStart(service_data->flags))
spastor 0:1c358ea10753 1700 {
spastor 0:1c358ea10753 1701 if (context == NULL)
spastor 0:1c358ea10753 1702 {
spastor 0:1c358ea10753 1703 uint8_t const * const ptr = service_data->data_ptr;
spastor 0:1c358ea10753 1704 const fs_opcode_t opcode = (fs_opcode_t) *ptr;
spastor 0:1c358ea10753 1705
spastor 0:1c358ea10753 1706 status = allocate_file_context(connector_ptr, opcode, &context);
spastor 0:1c358ea10753 1707 if (status != connector_working)
spastor 0:1c358ea10753 1708 {
spastor 0:1c358ea10753 1709 goto done;
spastor 0:1c358ea10753 1710 }
spastor 0:1c358ea10753 1711 session->service_context = context;
spastor 0:1c358ea10753 1712 context->opcode = opcode;
spastor 0:1c358ea10753 1713 }
spastor 0:1c358ea10753 1714 }
spastor 0:1c358ea10753 1715 else
spastor 0:1c358ea10753 1716 {
spastor 0:1c358ea10753 1717 if (context == NULL)
spastor 0:1c358ea10753 1718 {
spastor 0:1c358ea10753 1719 fs_set_service_error(service_request, connector_session_error_format);
spastor 0:1c358ea10753 1720 ASSERT_GOTO(connector_false, done);
spastor 0:1c358ea10753 1721 }
spastor 0:1c358ea10753 1722 }
spastor 0:1c358ea10753 1723
spastor 0:1c358ea10753 1724 if (context->opcode != fs_put_request_opcode)
spastor 0:1c358ea10753 1725 {
spastor 0:1c358ea10753 1726 /* don't support request in >1 message */
spastor 0:1c358ea10753 1727 if ( !(MsgIsStart(service_data->flags) && MsgIsLastData(service_data->flags)) )
spastor 0:1c358ea10753 1728 {
spastor 0:1c358ea10753 1729 FsSetInternalError(context, fs_error_path_too_long);
spastor 0:1c358ea10753 1730 goto done;
spastor 0:1c358ea10753 1731 }
spastor 0:1c358ea10753 1732 }
spastor 0:1c358ea10753 1733
spastor 0:1c358ea10753 1734 switch (context->opcode)
spastor 0:1c358ea10753 1735 {
spastor 0:1c358ea10753 1736 case fs_get_request_opcode:
spastor 0:1c358ea10753 1737 status = process_file_get_request(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1738 break;
spastor 0:1c358ea10753 1739
spastor 0:1c358ea10753 1740 case fs_put_request_opcode:
spastor 0:1c358ea10753 1741 status = process_file_put_request(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1742 break;
spastor 0:1c358ea10753 1743
spastor 0:1c358ea10753 1744 case fs_rm_request_opcode:
spastor 0:1c358ea10753 1745 status = process_file_rm_request(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1746 break;
spastor 0:1c358ea10753 1747
spastor 0:1c358ea10753 1748 case fs_ls_request_opcode:
spastor 0:1c358ea10753 1749 status = process_file_ls_request(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1750 break;
spastor 0:1c358ea10753 1751
spastor 0:1c358ea10753 1752 default:
spastor 0:1c358ea10753 1753 FsSetInternalError(context, fs_error_format);
spastor 0:1c358ea10753 1754 ASSERT(connector_false);
spastor 0:1c358ea10753 1755 }
spastor 0:1c358ea10753 1756
spastor 0:1c358ea10753 1757 done:
spastor 0:1c358ea10753 1758 return status;
spastor 0:1c358ea10753 1759 }
spastor 0:1c358ea10753 1760
spastor 0:1c358ea10753 1761 static connector_status_t file_system_response_callback(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1762 msg_service_request_t * const service_request)
spastor 0:1c358ea10753 1763 {
spastor 0:1c358ea10753 1764 msg_session_t * const session = service_request->session;
spastor 0:1c358ea10753 1765 fs_context_t * const context = session->service_context;
spastor 0:1c358ea10753 1766 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1767
spastor 0:1c358ea10753 1768 if (context == NULL)
spastor 0:1c358ea10753 1769 {
spastor 0:1c358ea10753 1770 fs_set_service_error(service_request, connector_session_error_unknown_session);
spastor 0:1c358ea10753 1771 ASSERT_GOTO(connector_false, done);
spastor 0:1c358ea10753 1772 }
spastor 0:1c358ea10753 1773
spastor 0:1c358ea10753 1774
spastor 0:1c358ea10753 1775 switch (context->opcode)
spastor 0:1c358ea10753 1776 {
spastor 0:1c358ea10753 1777 case fs_get_request_opcode:
spastor 0:1c358ea10753 1778 status = process_file_get_response(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1779 break;
spastor 0:1c358ea10753 1780
spastor 0:1c358ea10753 1781 case fs_put_request_opcode:
spastor 0:1c358ea10753 1782 status = process_file_response_nodata(connector_ptr, service_request, context, fs_put_response_opcode);
spastor 0:1c358ea10753 1783 break;
spastor 0:1c358ea10753 1784
spastor 0:1c358ea10753 1785 case fs_rm_request_opcode:
spastor 0:1c358ea10753 1786 status = process_file_response_nodata(connector_ptr, service_request, context, fs_rm_response_opcode);
spastor 0:1c358ea10753 1787 break;
spastor 0:1c358ea10753 1788
spastor 0:1c358ea10753 1789 case fs_ls_request_opcode:
spastor 0:1c358ea10753 1790 status = process_file_ls_response(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1791 break;
spastor 0:1c358ea10753 1792
spastor 0:1c358ea10753 1793 default:
spastor 0:1c358ea10753 1794 fs_set_service_error(service_request, connector_session_error_unknown_session);
spastor 0:1c358ea10753 1795 ASSERT_GOTO(connector_false, done);
spastor 0:1c358ea10753 1796 break;
spastor 0:1c358ea10753 1797 }
spastor 0:1c358ea10753 1798
spastor 0:1c358ea10753 1799 done:
spastor 0:1c358ea10753 1800 return status;
spastor 0:1c358ea10753 1801 }
spastor 0:1c358ea10753 1802
spastor 0:1c358ea10753 1803 static connector_status_t file_system_free_callback(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1804 msg_service_request_t * const service_request)
spastor 0:1c358ea10753 1805 {
spastor 0:1c358ea10753 1806 msg_session_t * const session = service_request->session;
spastor 0:1c358ea10753 1807 fs_context_t * const context = session->service_context;
spastor 0:1c358ea10753 1808 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1809
spastor 0:1c358ea10753 1810 if (context != NULL)
spastor 0:1c358ea10753 1811 {
spastor 0:1c358ea10753 1812 status = free_data_buffer(connector_ptr, named_buffer_id(msg_service), context);
spastor 0:1c358ea10753 1813 }
spastor 0:1c358ea10753 1814
spastor 0:1c358ea10753 1815 return status;
spastor 0:1c358ea10753 1816 }
spastor 0:1c358ea10753 1817
spastor 0:1c358ea10753 1818 static connector_status_t call_session_error_user(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1819 msg_service_request_t * const service_request,
spastor 0:1c358ea10753 1820 fs_context_t * const context)
spastor 0:1c358ea10753 1821 {
spastor 0:1c358ea10753 1822 connector_status_t status = connector_working;
spastor 0:1c358ea10753 1823
spastor 0:1c358ea10753 1824 if (context != NULL && FsSessionErrorCalled(context))
spastor 0:1c358ea10753 1825 goto done;
spastor 0:1c358ea10753 1826
spastor 0:1c358ea10753 1827 {
spastor 0:1c358ea10753 1828 connector_file_system_session_error_t data;
spastor 0:1c358ea10753 1829 connector_request_id_t request_id;
spastor 0:1c358ea10753 1830 connector_callback_status_t callback_status;
spastor 0:1c358ea10753 1831
spastor 0:1c358ea10753 1832 request_id.file_system_request = connector_request_id_file_system_session_error;
spastor 0:1c358ea10753 1833 data.session_error = service_request->error_value;
spastor 0:1c358ea10753 1834 data.user_context = context == NULL ? NULL : context->user_context;
spastor 0:1c358ea10753 1835
spastor 0:1c358ea10753 1836 callback_status = connector_callback(connector_ptr->callback,
spastor 0:1c358ea10753 1837 connector_class_id_file_system,
spastor 0:1c358ea10753 1838 request_id,
spastor 0:1c358ea10753 1839 &data);
spastor 0:1c358ea10753 1840
spastor 0:1c358ea10753 1841 if (context != NULL)
spastor 0:1c358ea10753 1842 context->user_context = data.user_context;
spastor 0:1c358ea10753 1843
spastor 0:1c358ea10753 1844 switch(callback_status)
spastor 0:1c358ea10753 1845 {
spastor 0:1c358ea10753 1846 case connector_callback_busy:
spastor 0:1c358ea10753 1847 status = connector_pending;
spastor 0:1c358ea10753 1848 goto done;
spastor 0:1c358ea10753 1849
spastor 0:1c358ea10753 1850 case connector_callback_continue:
spastor 0:1c358ea10753 1851 break;
spastor 0:1c358ea10753 1852
spastor 0:1c358ea10753 1853 case connector_callback_abort:
spastor 0:1c358ea10753 1854 default:
spastor 0:1c358ea10753 1855 status = connector_abort;
spastor 0:1c358ea10753 1856 if (context != NULL)
spastor 0:1c358ea10753 1857 context->status = connector_abort;
spastor 0:1c358ea10753 1858 break;
spastor 0:1c358ea10753 1859 }
spastor 0:1c358ea10753 1860
spastor 0:1c358ea10753 1861 if (context != NULL)
spastor 0:1c358ea10753 1862 FsSetSessionErrorCalled(context);
spastor 0:1c358ea10753 1863 }
spastor 0:1c358ea10753 1864
spastor 0:1c358ea10753 1865 done:
spastor 0:1c358ea10753 1866 return status;
spastor 0:1c358ea10753 1867 }
spastor 0:1c358ea10753 1868
spastor 0:1c358ea10753 1869
spastor 0:1c358ea10753 1870 static connector_status_t file_system_session_error_callback(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1871 msg_service_request_t * const service_request)
spastor 0:1c358ea10753 1872 {
spastor 0:1c358ea10753 1873 msg_session_t * const session = service_request->session;
spastor 0:1c358ea10753 1874 fs_context_t * const context = session->service_context;
spastor 0:1c358ea10753 1875
spastor 0:1c358ea10753 1876 connector_status_t status = call_session_error_user(connector_ptr, service_request, context);
spastor 0:1c358ea10753 1877
spastor 0:1c358ea10753 1878 if (context != NULL)
spastor 0:1c358ea10753 1879 {
spastor 0:1c358ea10753 1880 connector_request_id_file_system_t fs_request_id = context->opcode == fs_ls_request_opcode ?
spastor 0:1c358ea10753 1881 connector_request_id_file_system_closedir :
spastor 0:1c358ea10753 1882 connector_request_id_file_system_close;
spastor 0:1c358ea10753 1883
spastor 0:1c358ea10753 1884 status = call_file_close_user(connector_ptr, service_request, context, fs_request_id);
spastor 0:1c358ea10753 1885 if (status == connector_pending)
spastor 0:1c358ea10753 1886 goto done;
spastor 0:1c358ea10753 1887
spastor 0:1c358ea10753 1888 if (context->status == connector_abort)
spastor 0:1c358ea10753 1889 status = connector_abort;
spastor 0:1c358ea10753 1890 }
spastor 0:1c358ea10753 1891
spastor 0:1c358ea10753 1892 done:
spastor 0:1c358ea10753 1893 return status;
spastor 0:1c358ea10753 1894 }
spastor 0:1c358ea10753 1895
spastor 0:1c358ea10753 1896
spastor 0:1c358ea10753 1897 static connector_status_t file_system_callback(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 1898 msg_service_request_t * const service_request)
spastor 0:1c358ea10753 1899 {
spastor 0:1c358ea10753 1900 connector_status_t status = connector_abort;
spastor 0:1c358ea10753 1901
spastor 0:1c358ea10753 1902 ASSERT_GOTO(connector_ptr != NULL, done);
spastor 0:1c358ea10753 1903 ASSERT_GOTO(service_request != NULL, done);
spastor 0:1c358ea10753 1904 ASSERT_GOTO(service_request->session != NULL, done);
spastor 0:1c358ea10753 1905
spastor 0:1c358ea10753 1906 switch (service_request->service_type)
spastor 0:1c358ea10753 1907 {
spastor 0:1c358ea10753 1908 case msg_service_type_have_data:
spastor 0:1c358ea10753 1909 status = file_system_request_callback(connector_ptr, service_request);
spastor 0:1c358ea10753 1910 break;
spastor 0:1c358ea10753 1911
spastor 0:1c358ea10753 1912 case msg_service_type_need_data:
spastor 0:1c358ea10753 1913 status = file_system_response_callback(connector_ptr, service_request);
spastor 0:1c358ea10753 1914 break;
spastor 0:1c358ea10753 1915
spastor 0:1c358ea10753 1916 case msg_service_type_error:
spastor 0:1c358ea10753 1917 status = file_system_session_error_callback(connector_ptr, service_request);
spastor 0:1c358ea10753 1918 break;
spastor 0:1c358ea10753 1919
spastor 0:1c358ea10753 1920 case msg_service_type_free:
spastor 0:1c358ea10753 1921 status = file_system_free_callback(connector_ptr, service_request);
spastor 0:1c358ea10753 1922 break;
spastor 0:1c358ea10753 1923
spastor 0:1c358ea10753 1924 default:
spastor 0:1c358ea10753 1925 ASSERT(connector_false);
spastor 0:1c358ea10753 1926 break;
spastor 0:1c358ea10753 1927 }
spastor 0:1c358ea10753 1928
spastor 0:1c358ea10753 1929 done:
spastor 0:1c358ea10753 1930 return status;
spastor 0:1c358ea10753 1931 }
spastor 0:1c358ea10753 1932
spastor 0:1c358ea10753 1933 static connector_status_t connector_facility_file_system_cleanup(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 1934 {
spastor 0:1c358ea10753 1935 return msg_cleanup_all_sessions(connector_ptr, msg_service_id_file);
spastor 0:1c358ea10753 1936 }
spastor 0:1c358ea10753 1937
spastor 0:1c358ea10753 1938 static connector_status_t connector_facility_file_system_delete(connector_data_t * const data_ptr)
spastor 0:1c358ea10753 1939 {
spastor 0:1c358ea10753 1940 return msg_delete_facility(data_ptr, msg_service_id_file);
spastor 0:1c358ea10753 1941 }
spastor 0:1c358ea10753 1942
spastor 0:1c358ea10753 1943 static connector_status_t connector_facility_file_system_init(connector_data_t * const data_ptr, unsigned int const facility_index)
spastor 0:1c358ea10753 1944 {
spastor 0:1c358ea10753 1945 return msg_init_facility(data_ptr, facility_index, msg_service_id_file, file_system_callback);
spastor 0:1c358ea10753 1946 }
spastor 0:1c358ea10753 1947