Sebastián Pastor / EtheriosCloudConnector
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 typedef struct
spastor 0:1c358ea10753 14 {
spastor 0:1c358ea10753 15 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 16 #define DP_FILE_PATH_SIZE 64
spastor 0:1c358ea10753 17 #else
spastor 0:1c358ea10753 18 #define DP_FILE_PATH_SIZE 32
spastor 0:1c358ea10753 19 #endif
spastor 0:1c358ea10753 20 connector_request_data_service_send_t header;
spastor 0:1c358ea10753 21 char file_path[DP_FILE_PATH_SIZE];
spastor 0:1c358ea10753 22
spastor 0:1c358ea10753 23 enum
spastor 0:1c358ea10753 24 {
spastor 0:1c358ea10753 25 dp_content_type_binary,
spastor 0:1c358ea10753 26 dp_content_type_csv
spastor 0:1c358ea10753 27 } type;
spastor 0:1c358ea10753 28
spastor 0:1c358ea10753 29 union
spastor 0:1c358ea10753 30 {
spastor 0:1c358ea10753 31 struct
spastor 0:1c358ea10753 32 {
spastor 0:1c358ea10753 33 connector_request_data_point_single_t const * dp_request;
spastor 0:1c358ea10753 34 connector_data_point_t const * current_dp;
spastor 0:1c358ea10753 35 size_t bytes_sent;
spastor 0:1c358ea10753 36 size_t bytes_to_send;
spastor 0:1c358ea10753 37
spastor 0:1c358ea10753 38 /*************************************************************************
spastor 0:1c358ea10753 39 ** WARNING: Please don't change the order of the state unless default **
spastor 0:1c358ea10753 40 ** CSV format described in the Cloud documentation changes. **
spastor 0:1c358ea10753 41 *************************************************************************/
spastor 0:1c358ea10753 42 enum
spastor 0:1c358ea10753 43 {
spastor 0:1c358ea10753 44 dp_state_data,
spastor 0:1c358ea10753 45 dp_state_time,
spastor 0:1c358ea10753 46 dp_state_quality,
spastor 0:1c358ea10753 47 dp_state_description,
spastor 0:1c358ea10753 48 dp_state_location,
spastor 0:1c358ea10753 49 dp_state_type,
spastor 0:1c358ea10753 50 dp_state_unit,
spastor 0:1c358ea10753 51 dp_state_forward_to
spastor 0:1c358ea10753 52 } state;
spastor 0:1c358ea10753 53
spastor 0:1c358ea10753 54 } csv;
spastor 0:1c358ea10753 55
spastor 0:1c358ea10753 56 struct
spastor 0:1c358ea10753 57 {
spastor 0:1c358ea10753 58 connector_request_data_point_binary_t const * bp_request;
spastor 0:1c358ea10753 59 uint8_t * current_bp;
spastor 0:1c358ea10753 60 size_t bytes_to_send;
spastor 0:1c358ea10753 61 } binary;
spastor 0:1c358ea10753 62
spastor 0:1c358ea10753 63 } data;
spastor 0:1c358ea10753 64
spastor 0:1c358ea10753 65 } data_point_info_t;
spastor 0:1c358ea10753 66
spastor 0:1c358ea10753 67 static connector_request_data_point_single_t const * data_point_single_pending = NULL;
spastor 0:1c358ea10753 68 static connector_request_data_point_binary_t const * data_point_binary_pending = NULL;
spastor 0:1c358ea10753 69
spastor 0:1c358ea10753 70 static connector_status_t dp_initiate_data_point_single(connector_request_data_point_single_t const * const dp_ptr)
spastor 0:1c358ea10753 71 {
spastor 0:1c358ea10753 72 connector_status_t result = connector_invalid_data;
spastor 0:1c358ea10753 73
spastor 0:1c358ea10753 74 ASSERT_GOTO(dp_ptr != NULL, error);
spastor 0:1c358ea10753 75
spastor 0:1c358ea10753 76 if (data_point_single_pending != NULL)
spastor 0:1c358ea10753 77 {
spastor 0:1c358ea10753 78 result = connector_service_busy;
spastor 0:1c358ea10753 79 goto error;
spastor 0:1c358ea10753 80 }
spastor 0:1c358ea10753 81
spastor 0:1c358ea10753 82 if (dp_ptr->path == NULL)
spastor 0:1c358ea10753 83 {
spastor 0:1c358ea10753 84 connector_debug_printf("dp_initiate_data_point_single: NULL data point path\n");
spastor 0:1c358ea10753 85 goto error;
spastor 0:1c358ea10753 86 }
spastor 0:1c358ea10753 87
spastor 0:1c358ea10753 88 if ((dp_ptr->point == NULL))
spastor 0:1c358ea10753 89 {
spastor 0:1c358ea10753 90 connector_debug_printf("dp_initiate_data_point_single: NULL data point\n");
spastor 0:1c358ea10753 91 goto error;
spastor 0:1c358ea10753 92 }
spastor 0:1c358ea10753 93
spastor 0:1c358ea10753 94 data_point_single_pending = dp_ptr;
spastor 0:1c358ea10753 95 result = connector_success;
spastor 0:1c358ea10753 96
spastor 0:1c358ea10753 97 error:
spastor 0:1c358ea10753 98 return result;
spastor 0:1c358ea10753 99 }
spastor 0:1c358ea10753 100
spastor 0:1c358ea10753 101 static connector_status_t dp_initiate_data_point_binary(connector_request_data_point_binary_t const * const bp_ptr)
spastor 0:1c358ea10753 102 {
spastor 0:1c358ea10753 103 connector_status_t result = connector_invalid_data;
spastor 0:1c358ea10753 104
spastor 0:1c358ea10753 105 ASSERT_GOTO(bp_ptr != NULL, error);
spastor 0:1c358ea10753 106
spastor 0:1c358ea10753 107 if (data_point_binary_pending != NULL)
spastor 0:1c358ea10753 108 {
spastor 0:1c358ea10753 109 result = connector_service_busy;
spastor 0:1c358ea10753 110 goto error;
spastor 0:1c358ea10753 111 }
spastor 0:1c358ea10753 112
spastor 0:1c358ea10753 113 if (bp_ptr->path == NULL)
spastor 0:1c358ea10753 114 {
spastor 0:1c358ea10753 115 connector_debug_printf("dp_initiate_data_point_binary: NULL data point path\n");
spastor 0:1c358ea10753 116 goto error;
spastor 0:1c358ea10753 117 }
spastor 0:1c358ea10753 118
spastor 0:1c358ea10753 119 if ((bp_ptr->point == NULL))
spastor 0:1c358ea10753 120 {
spastor 0:1c358ea10753 121 connector_debug_printf("dp_initiate_data_point_binary: NULL data point\n");
spastor 0:1c358ea10753 122 goto error;
spastor 0:1c358ea10753 123 }
spastor 0:1c358ea10753 124
spastor 0:1c358ea10753 125 data_point_binary_pending = bp_ptr;
spastor 0:1c358ea10753 126 result = connector_success;
spastor 0:1c358ea10753 127
spastor 0:1c358ea10753 128 error:
spastor 0:1c358ea10753 129 return result;
spastor 0:1c358ea10753 130 }
spastor 0:1c358ea10753 131
spastor 0:1c358ea10753 132 static connector_status_t dp_callback_status_to_status(connector_callback_status_t const callback_status)
spastor 0:1c358ea10753 133 {
spastor 0:1c358ea10753 134 connector_status_t status;
spastor 0:1c358ea10753 135
spastor 0:1c358ea10753 136 switch (callback_status)
spastor 0:1c358ea10753 137 {
spastor 0:1c358ea10753 138 case connector_callback_continue:
spastor 0:1c358ea10753 139 status = connector_working;
spastor 0:1c358ea10753 140 break;
spastor 0:1c358ea10753 141
spastor 0:1c358ea10753 142 case connector_callback_busy:
spastor 0:1c358ea10753 143 status = connector_pending;
spastor 0:1c358ea10753 144 break;
spastor 0:1c358ea10753 145
spastor 0:1c358ea10753 146 default:
spastor 0:1c358ea10753 147 status = connector_abort;
spastor 0:1c358ea10753 148 break;
spastor 0:1c358ea10753 149 }
spastor 0:1c358ea10753 150
spastor 0:1c358ea10753 151 return status;
spastor 0:1c358ea10753 152 }
spastor 0:1c358ea10753 153
spastor 0:1c358ea10753 154 static connector_status_t dp_inform_status(connector_data_t * const connector_ptr, connector_request_id_data_point_t request,
spastor 0:1c358ea10753 155 connector_transport_t const transport, void * context, connector_session_error_t const error)
spastor 0:1c358ea10753 156 {
spastor 0:1c358ea10753 157 connector_status_t result;
spastor 0:1c358ea10753 158 connector_data_point_status_t dp_status;
spastor 0:1c358ea10753 159
spastor 0:1c358ea10753 160 dp_status.transport = transport;
spastor 0:1c358ea10753 161 dp_status.user_context = context;
spastor 0:1c358ea10753 162 dp_status.session_error = connector_session_error_none;
spastor 0:1c358ea10753 163
spastor 0:1c358ea10753 164 switch (error)
spastor 0:1c358ea10753 165 {
spastor 0:1c358ea10753 166 case connector_session_error_none:
spastor 0:1c358ea10753 167 dp_status.status = connector_data_point_status_complete;
spastor 0:1c358ea10753 168 break;
spastor 0:1c358ea10753 169
spastor 0:1c358ea10753 170 case connector_session_error_cancel:
spastor 0:1c358ea10753 171 dp_status.status = connector_data_point_status_cancel;
spastor 0:1c358ea10753 172 break;
spastor 0:1c358ea10753 173
spastor 0:1c358ea10753 174 case connector_session_error_timeout:
spastor 0:1c358ea10753 175 dp_status.status = connector_data_point_status_timeout;
spastor 0:1c358ea10753 176 break;
spastor 0:1c358ea10753 177
spastor 0:1c358ea10753 178 case connector_session_error_format:
spastor 0:1c358ea10753 179 dp_status.status = connector_data_point_status_invalid_data;
spastor 0:1c358ea10753 180 break;
spastor 0:1c358ea10753 181
spastor 0:1c358ea10753 182 default:
spastor 0:1c358ea10753 183 dp_status.status = connector_data_point_status_session_error;
spastor 0:1c358ea10753 184 dp_status.session_error = error;
spastor 0:1c358ea10753 185 break;
spastor 0:1c358ea10753 186 }
spastor 0:1c358ea10753 187
spastor 0:1c358ea10753 188 {
spastor 0:1c358ea10753 189 connector_callback_status_t callback_status;
spastor 0:1c358ea10753 190 connector_request_id_t request_id;
spastor 0:1c358ea10753 191
spastor 0:1c358ea10753 192 request_id.data_point_request = request;
spastor 0:1c358ea10753 193 callback_status = connector_callback(connector_ptr->callback, connector_class_id_data_point, request_id, &dp_status);
spastor 0:1c358ea10753 194 result = dp_callback_status_to_status(callback_status);
spastor 0:1c358ea10753 195 }
spastor 0:1c358ea10753 196
spastor 0:1c358ea10753 197 return result;
spastor 0:1c358ea10753 198 }
spastor 0:1c358ea10753 199
spastor 0:1c358ea10753 200 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 201 static connector_status_t dp_cancel_session(connector_data_t * const connector_ptr, void const * const session, uint32_t const * const request_id)
spastor 0:1c358ea10753 202 {
spastor 0:1c358ea10753 203 connector_status_t status = connector_working;
spastor 0:1c358ea10753 204 connector_bool_t cancel_all = connector_bool(request_id == NULL);
spastor 0:1c358ea10753 205
spastor 0:1c358ea10753 206 if (data_point_binary_pending != NULL)
spastor 0:1c358ea10753 207 {
spastor 0:1c358ea10753 208 connector_bool_t const has_request_id = connector_bool(data_point_binary_pending->request_id != NULL);
spastor 0:1c358ea10753 209 connector_bool_t const matching_request = connector_bool(has_request_id && *data_point_binary_pending->request_id == *request_id);
spastor 0:1c358ea10753 210
spastor 0:1c358ea10753 211 if (cancel_all || matching_request)
spastor 0:1c358ea10753 212 {
spastor 0:1c358ea10753 213 if (session == NULL)
spastor 0:1c358ea10753 214 {
spastor 0:1c358ea10753 215 status = dp_inform_status(connector_ptr, connector_request_id_data_point_binary_status, data_point_binary_pending->transport, data_point_binary_pending->user_context, connector_session_error_cancel);
spastor 0:1c358ea10753 216 if (status != connector_working)
spastor 0:1c358ea10753 217 goto done;
spastor 0:1c358ea10753 218 }
spastor 0:1c358ea10753 219 data_point_binary_pending = NULL;
spastor 0:1c358ea10753 220 }
spastor 0:1c358ea10753 221 }
spastor 0:1c358ea10753 222
spastor 0:1c358ea10753 223 if (data_point_single_pending != NULL)
spastor 0:1c358ea10753 224 {
spastor 0:1c358ea10753 225 connector_bool_t const pending_dp_has_request_id = connector_bool(data_point_single_pending->request_id != NULL);
spastor 0:1c358ea10753 226 connector_bool_t const matching_request = connector_bool(pending_dp_has_request_id && *data_point_single_pending->request_id == *request_id);
spastor 0:1c358ea10753 227
spastor 0:1c358ea10753 228 if (cancel_all || matching_request)
spastor 0:1c358ea10753 229 {
spastor 0:1c358ea10753 230 if (session == NULL)
spastor 0:1c358ea10753 231 {
spastor 0:1c358ea10753 232 status = dp_inform_status(connector_ptr, connector_request_id_data_point_single_status, data_point_single_pending->transport, data_point_single_pending->user_context, connector_session_error_cancel);
spastor 0:1c358ea10753 233 if (status != connector_working)
spastor 0:1c358ea10753 234 goto done;
spastor 0:1c358ea10753 235 }
spastor 0:1c358ea10753 236 data_point_single_pending = NULL;
spastor 0:1c358ea10753 237 }
spastor 0:1c358ea10753 238 }
spastor 0:1c358ea10753 239 done:
spastor 0:1c358ea10753 240 return status;
spastor 0:1c358ea10753 241 }
spastor 0:1c358ea10753 242 #endif
spastor 0:1c358ea10753 243
spastor 0:1c358ea10753 244 static connector_status_t dp_fill_file_path(data_point_info_t * const dp_info, char const * const path, char const * const extension)
spastor 0:1c358ea10753 245 {
spastor 0:1c358ea10753 246 connector_status_t result;
spastor 0:1c358ea10753 247 size_t const available_path_bytes = sizeof dp_info->file_path - 1;
spastor 0:1c358ea10753 248 char const path_prefix[] = "DataPoint/";
spastor 0:1c358ea10753 249 size_t const path_prefix_bytes = sizeof path_prefix - 1;
spastor 0:1c358ea10753 250 size_t const path_bytes = strlen(path);
spastor 0:1c358ea10753 251 size_t const extension_bytes = strlen(extension);
spastor 0:1c358ea10753 252 size_t const full_path_bytes = path_prefix_bytes + path_bytes + extension_bytes;
spastor 0:1c358ea10753 253
spastor 0:1c358ea10753 254 if (full_path_bytes < available_path_bytes)
spastor 0:1c358ea10753 255 {
spastor 0:1c358ea10753 256 strncpy(dp_info->file_path, path_prefix, path_prefix_bytes);
spastor 0:1c358ea10753 257 strncpy(&dp_info->file_path[path_prefix_bytes], path, path_bytes);
spastor 0:1c358ea10753 258 strncpy(&dp_info->file_path[path_prefix_bytes + path_bytes], extension, extension_bytes);
spastor 0:1c358ea10753 259 dp_info->file_path[full_path_bytes] = '\0';
spastor 0:1c358ea10753 260 result = connector_working;
spastor 0:1c358ea10753 261 }
spastor 0:1c358ea10753 262 else
spastor 0:1c358ea10753 263 {
spastor 0:1c358ea10753 264 connector_debug_printf("dp_fill_file_path [DataPoint/%s.%s]: file path bytes [%" PRIsize "] exceeds the limit [%" PRIsize "]\n", path, extension, full_path_bytes, available_path_bytes);
spastor 0:1c358ea10753 265 result = connector_invalid_data;
spastor 0:1c358ea10753 266 }
spastor 0:1c358ea10753 267
spastor 0:1c358ea10753 268 return result;
spastor 0:1c358ea10753 269 }
spastor 0:1c358ea10753 270
spastor 0:1c358ea10753 271 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 272 static connector_status_t dp_send_message(connector_data_t * const connector_ptr, data_point_info_t * const dp_info,
spastor 0:1c358ea10753 273 connector_transport_t const transport, connector_bool_t const response_needed, uint32_t * request_id)
spastor 0:1c358ea10753 274 #else
spastor 0:1c358ea10753 275 static connector_status_t dp_send_message(connector_data_t * const connector_ptr, data_point_info_t * const dp_info,
spastor 0:1c358ea10753 276 connector_transport_t const transport, connector_bool_t const response_needed)
spastor 0:1c358ea10753 277 #endif
spastor 0:1c358ea10753 278 {
spastor 0:1c358ea10753 279 connector_status_t result;
spastor 0:1c358ea10753 280
spastor 0:1c358ea10753 281 dp_info->header.transport = transport;
spastor 0:1c358ea10753 282 dp_info->header.user_context = dp_info;
spastor 0:1c358ea10753 283 dp_info->header.path = dp_info->file_path;
spastor 0:1c358ea10753 284 dp_info->header.response_required = response_needed;
spastor 0:1c358ea10753 285 dp_info->header.content_type = NULL;
spastor 0:1c358ea10753 286 dp_info->header.option = connector_data_service_send_option_overwrite;
spastor 0:1c358ea10753 287 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 288 dp_info->header.request_id = request_id;
spastor 0:1c358ea10753 289 #endif
spastor 0:1c358ea10753 290
spastor 0:1c358ea10753 291 result = connector_initiate_action(connector_ptr, connector_initiate_send_data, &dp_info->header);
spastor 0:1c358ea10753 292 switch (result)
spastor 0:1c358ea10753 293 {
spastor 0:1c358ea10753 294 case connector_init_error:
spastor 0:1c358ea10753 295 case connector_unavailable:
spastor 0:1c358ea10753 296 case connector_service_busy:
spastor 0:1c358ea10753 297 result = connector_pending;
spastor 0:1c358ea10753 298 break;
spastor 0:1c358ea10753 299
spastor 0:1c358ea10753 300 case connector_success:
spastor 0:1c358ea10753 301 result = connector_working;
spastor 0:1c358ea10753 302 goto done;
spastor 0:1c358ea10753 303
spastor 0:1c358ea10753 304 default:
spastor 0:1c358ea10753 305 connector_debug_printf("dp_send_message: connector_initiate_action failed [%d]!\n", result);
spastor 0:1c358ea10753 306 break;
spastor 0:1c358ea10753 307 }
spastor 0:1c358ea10753 308
spastor 0:1c358ea10753 309 done:
spastor 0:1c358ea10753 310 return result;
spastor 0:1c358ea10753 311 }
spastor 0:1c358ea10753 312
spastor 0:1c358ea10753 313 static void * dp_create_dp_info(connector_data_t * const connector_ptr, connector_status_t * result)
spastor 0:1c358ea10753 314 {
spastor 0:1c358ea10753 315 void * ptr;
spastor 0:1c358ea10753 316
spastor 0:1c358ea10753 317 *result = malloc_data_buffer(connector_ptr, sizeof(data_point_info_t), named_buffer_id(data_point_block), &ptr);
spastor 0:1c358ea10753 318 if (*result != connector_working)
spastor 0:1c358ea10753 319 {
spastor 0:1c358ea10753 320 connector_debug_printf("dp_create_dp_info: failed to malloc [%d]!\n", *result);
spastor 0:1c358ea10753 321 ptr = NULL;
spastor 0:1c358ea10753 322 }
spastor 0:1c358ea10753 323
spastor 0:1c358ea10753 324 return ptr;
spastor 0:1c358ea10753 325 }
spastor 0:1c358ea10753 326
spastor 0:1c358ea10753 327 static connector_status_t dp_process_csv(connector_data_t * const connector_ptr, connector_request_data_point_single_t const * const dp_ptr)
spastor 0:1c358ea10753 328 {
spastor 0:1c358ea10753 329 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 330 data_point_info_t * const dp_info = dp_create_dp_info(connector_ptr, &result);
spastor 0:1c358ea10753 331
spastor 0:1c358ea10753 332 if (dp_info == NULL) goto done;
spastor 0:1c358ea10753 333
spastor 0:1c358ea10753 334 dp_info->type = dp_content_type_csv;
spastor 0:1c358ea10753 335 dp_info->data.csv.dp_request = dp_ptr;
spastor 0:1c358ea10753 336 dp_info->data.csv.current_dp = dp_ptr->point;
spastor 0:1c358ea10753 337 dp_info->data.csv.bytes_sent = 0;
spastor 0:1c358ea10753 338 dp_info->data.csv.bytes_to_send = 0;
spastor 0:1c358ea10753 339 dp_info->data.csv.state = dp_state_data;
spastor 0:1c358ea10753 340
spastor 0:1c358ea10753 341 result = dp_fill_file_path(dp_info, dp_ptr->path, ".csv");
spastor 0:1c358ea10753 342 if (result != connector_working) goto error;
spastor 0:1c358ea10753 343 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 344 result = dp_send_message(connector_ptr, dp_info, dp_ptr->transport, dp_ptr->response_required, dp_ptr->request_id);
spastor 0:1c358ea10753 345 #else
spastor 0:1c358ea10753 346 result = dp_send_message(connector_ptr, dp_info, dp_ptr->transport, dp_ptr->response_required);
spastor 0:1c358ea10753 347 #endif
spastor 0:1c358ea10753 348 if (result == connector_working) goto done;
spastor 0:1c358ea10753 349
spastor 0:1c358ea10753 350 error:
spastor 0:1c358ea10753 351 if (result != connector_pending)
spastor 0:1c358ea10753 352 result = dp_inform_status(connector_ptr, connector_request_id_data_point_single_status, dp_ptr->transport,
spastor 0:1c358ea10753 353 dp_ptr->user_context, connector_session_error_format);
spastor 0:1c358ea10753 354
spastor 0:1c358ea10753 355 if (free_data_buffer(connector_ptr, named_buffer_id(data_point_block), dp_info) != connector_working)
spastor 0:1c358ea10753 356 result = connector_abort;
spastor 0:1c358ea10753 357
spastor 0:1c358ea10753 358 done:
spastor 0:1c358ea10753 359 return result;
spastor 0:1c358ea10753 360 }
spastor 0:1c358ea10753 361
spastor 0:1c358ea10753 362 static connector_status_t dp_process_binary(connector_data_t * const connector_ptr, connector_request_data_point_binary_t const * const bp_ptr)
spastor 0:1c358ea10753 363 {
spastor 0:1c358ea10753 364 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 365 data_point_info_t * const dp_info = dp_create_dp_info(connector_ptr, &result);
spastor 0:1c358ea10753 366
spastor 0:1c358ea10753 367 if (dp_info == NULL) goto done;
spastor 0:1c358ea10753 368
spastor 0:1c358ea10753 369 dp_info->type = dp_content_type_binary;
spastor 0:1c358ea10753 370 dp_info->data.binary.bp_request = bp_ptr;
spastor 0:1c358ea10753 371 dp_info->data.binary.current_bp = bp_ptr->point;
spastor 0:1c358ea10753 372 dp_info->data.binary.bytes_to_send = bp_ptr->bytes_used;
spastor 0:1c358ea10753 373
spastor 0:1c358ea10753 374 result = dp_fill_file_path(dp_info, bp_ptr->path, ".bin");
spastor 0:1c358ea10753 375 if (result != connector_working) goto error;
spastor 0:1c358ea10753 376 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 377 result = dp_send_message(connector_ptr, dp_info, bp_ptr->transport, bp_ptr->response_required, bp_ptr->request_id);
spastor 0:1c358ea10753 378 #else
spastor 0:1c358ea10753 379 result = dp_send_message(connector_ptr, dp_info, bp_ptr->transport, bp_ptr->response_required);
spastor 0:1c358ea10753 380 #endif
spastor 0:1c358ea10753 381 if (result == connector_working) goto done;
spastor 0:1c358ea10753 382
spastor 0:1c358ea10753 383 error:
spastor 0:1c358ea10753 384 if (result != connector_pending)
spastor 0:1c358ea10753 385 result = dp_inform_status(connector_ptr, connector_request_id_data_point_binary_status, bp_ptr->transport,
spastor 0:1c358ea10753 386 bp_ptr->user_context, connector_session_error_format);
spastor 0:1c358ea10753 387
spastor 0:1c358ea10753 388 if (free_data_buffer(connector_ptr, named_buffer_id(data_point_block), dp_info) != connector_working)
spastor 0:1c358ea10753 389 result = connector_abort;
spastor 0:1c358ea10753 390
spastor 0:1c358ea10753 391 done:
spastor 0:1c358ea10753 392 return result;
spastor 0:1c358ea10753 393 }
spastor 0:1c358ea10753 394
spastor 0:1c358ea10753 395 static connector_status_t dp_process_request(connector_data_t * const connector_ptr, connector_transport_t const transport)
spastor 0:1c358ea10753 396 {
spastor 0:1c358ea10753 397 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 398 static connector_bool_t process_csv = connector_true;
spastor 0:1c358ea10753 399
spastor 0:1c358ea10753 400 if (process_csv)
spastor 0:1c358ea10753 401 {
spastor 0:1c358ea10753 402 if ((data_point_single_pending != NULL) && (data_point_single_pending->transport == transport))
spastor 0:1c358ea10753 403 {
spastor 0:1c358ea10753 404 result = dp_process_csv(connector_ptr, data_point_single_pending);
spastor 0:1c358ea10753 405 if (result != connector_pending)
spastor 0:1c358ea10753 406 {
spastor 0:1c358ea10753 407 process_csv = connector_false;
spastor 0:1c358ea10753 408 data_point_single_pending = NULL;
spastor 0:1c358ea10753 409 goto done;
spastor 0:1c358ea10753 410 }
spastor 0:1c358ea10753 411 }
spastor 0:1c358ea10753 412 }
spastor 0:1c358ea10753 413 else
spastor 0:1c358ea10753 414 process_csv = connector_true;
spastor 0:1c358ea10753 415
spastor 0:1c358ea10753 416 if ((data_point_binary_pending != NULL) && (data_point_binary_pending->transport == transport))
spastor 0:1c358ea10753 417 {
spastor 0:1c358ea10753 418 result = dp_process_binary(connector_ptr, data_point_binary_pending);
spastor 0:1c358ea10753 419 if (result != connector_pending)
spastor 0:1c358ea10753 420 data_point_binary_pending = NULL;
spastor 0:1c358ea10753 421 }
spastor 0:1c358ea10753 422
spastor 0:1c358ea10753 423 done:
spastor 0:1c358ea10753 424 return result;
spastor 0:1c358ea10753 425 }
spastor 0:1c358ea10753 426
spastor 0:1c358ea10753 427 static size_t dp_process_string(char * const string, char * const buffer, size_t const bytes_available, size_t * bytes_used_ptr)
spastor 0:1c358ea10753 428 {
spastor 0:1c358ea10753 429 size_t bytes_processed = 0;
spastor 0:1c358ea10753 430 char const delimiters[] = {',', '\n', '\r', ' ', '\t'};
spastor 0:1c358ea10753 431 connector_bool_t need_quotes = connector_false;
spastor 0:1c358ea10753 432 size_t const delimiters_size = sizeof delimiters;
spastor 0:1c358ea10753 433 size_t index;
spastor 0:1c358ea10753 434
spastor 0:1c358ea10753 435 if ((string == NULL) || (string[0] == '\0')) goto done;
spastor 0:1c358ea10753 436
spastor 0:1c358ea10753 437 for (index = 0; index < delimiters_size; index++)
spastor 0:1c358ea10753 438 {
spastor 0:1c358ea10753 439 if (strchr(string, delimiters[index]) != NULL)
spastor 0:1c358ea10753 440 {
spastor 0:1c358ea10753 441 need_quotes = connector_true;
spastor 0:1c358ea10753 442 break;
spastor 0:1c358ea10753 443 }
spastor 0:1c358ea10753 444 }
spastor 0:1c358ea10753 445
spastor 0:1c358ea10753 446 {
spastor 0:1c358ea10753 447 char * const format = need_quotes ? "\"%s\"" : "%s";
spastor 0:1c358ea10753 448
spastor 0:1c358ea10753 449 bytes_processed = connector_snprintf(buffer, bytes_available, format, string);
spastor 0:1c358ea10753 450
spastor 0:1c358ea10753 451 if (bytes_used_ptr != NULL)
spastor 0:1c358ea10753 452 *bytes_used_ptr = need_quotes ? bytes_processed - 2 : bytes_processed;
spastor 0:1c358ea10753 453 }
spastor 0:1c358ea10753 454
spastor 0:1c358ea10753 455 done:
spastor 0:1c358ea10753 456 return bytes_processed;
spastor 0:1c358ea10753 457 }
spastor 0:1c358ea10753 458
spastor 0:1c358ea10753 459 static size_t dp_process_data(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 460 {
spastor 0:1c358ea10753 461 connector_data_point_t const * dp_ptr = dp_info->data.csv.current_dp;
spastor 0:1c358ea10753 462 connector_request_data_point_single_t const * const dp_request = dp_info->data.csv.dp_request;
spastor 0:1c358ea10753 463 size_t bytes_processed = 0;
spastor 0:1c358ea10753 464
spastor 0:1c358ea10753 465 if (dp_ptr->data.type == connector_data_type_text)
spastor 0:1c358ea10753 466 {
spastor 0:1c358ea10753 467 bytes_processed = connector_snprintf(buffer, bytes_available, "%s", dp_ptr->data.element.text);
spastor 0:1c358ea10753 468 goto done;
spastor 0:1c358ea10753 469 }
spastor 0:1c358ea10753 470
spastor 0:1c358ea10753 471 switch (dp_request->type)
spastor 0:1c358ea10753 472 {
spastor 0:1c358ea10753 473 case connector_data_point_type_integer:
spastor 0:1c358ea10753 474 bytes_processed = connector_snprintf(buffer, bytes_available, "%" PRId32, dp_ptr->data.element.native.int_value);
spastor 0:1c358ea10753 475 break;
spastor 0:1c358ea10753 476
spastor 0:1c358ea10753 477 #if (defined CONNECTOR_HAS_64_BIT_INTEGERS)
spastor 0:1c358ea10753 478 case connector_data_point_type_long:
spastor 0:1c358ea10753 479 bytes_processed = connector_snprintf(buffer, bytes_available, "%" PRId64, dp_ptr->data.element.native.long_value);
spastor 0:1c358ea10753 480 break;
spastor 0:1c358ea10753 481 #endif
spastor 0:1c358ea10753 482
spastor 0:1c358ea10753 483
spastor 0:1c358ea10753 484 case connector_data_point_type_string:
spastor 0:1c358ea10753 485 {
spastor 0:1c358ea10753 486 size_t bytes_copied = 0;
spastor 0:1c358ea10753 487
spastor 0:1c358ea10753 488 if (dp_info->data.csv.bytes_sent == 0)
spastor 0:1c358ea10753 489 dp_info->data.csv.bytes_to_send = strlen(dp_ptr->data.element.native.string_value);
spastor 0:1c358ea10753 490
spastor 0:1c358ea10753 491 bytes_processed = dp_process_string(&dp_ptr->data.element.native.string_value[dp_info->data.csv.bytes_sent], buffer, bytes_available, &bytes_copied);
spastor 0:1c358ea10753 492
spastor 0:1c358ea10753 493 dp_info->data.csv.bytes_to_send -= bytes_copied;
spastor 0:1c358ea10753 494 dp_info->data.csv.bytes_sent = (dp_info->data.csv.bytes_to_send > 0) ? dp_info->data.csv.bytes_sent + bytes_copied : 0;
spastor 0:1c358ea10753 495 break;
spastor 0:1c358ea10753 496 }
spastor 0:1c358ea10753 497
spastor 0:1c358ea10753 498 #if (defined FLOATING_POINT_SUPPORTED)
spastor 0:1c358ea10753 499 case connector_data_point_type_float:
spastor 0:1c358ea10753 500 bytes_processed = connector_snprintf(buffer, bytes_available, "%f", dp_ptr->data.element.native.float_value);
spastor 0:1c358ea10753 501 break;
spastor 0:1c358ea10753 502
spastor 0:1c358ea10753 503 case connector_data_point_type_double:
spastor 0:1c358ea10753 504 bytes_processed = connector_snprintf(buffer, bytes_available, "%lf", dp_ptr->data.element.native.double_value);
spastor 0:1c358ea10753 505 break;
spastor 0:1c358ea10753 506 #endif
spastor 0:1c358ea10753 507
spastor 0:1c358ea10753 508 default:
spastor 0:1c358ea10753 509 ASSERT_GOTO(connector_false, done);
spastor 0:1c358ea10753 510 break;
spastor 0:1c358ea10753 511 }
spastor 0:1c358ea10753 512
spastor 0:1c358ea10753 513 done:
spastor 0:1c358ea10753 514 return bytes_processed;
spastor 0:1c358ea10753 515 }
spastor 0:1c358ea10753 516
spastor 0:1c358ea10753 517 static size_t dp_process_time(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 518 {
spastor 0:1c358ea10753 519 connector_data_point_t const * dp_ptr = dp_info->data.csv.current_dp;
spastor 0:1c358ea10753 520 size_t bytes_processed = 0;
spastor 0:1c358ea10753 521
spastor 0:1c358ea10753 522 switch (dp_ptr->time.source)
spastor 0:1c358ea10753 523 {
spastor 0:1c358ea10753 524 case connector_time_cloud:
spastor 0:1c358ea10753 525 break;
spastor 0:1c358ea10753 526
spastor 0:1c358ea10753 527 case connector_time_local_epoch_fractional:
spastor 0:1c358ea10753 528 bytes_processed = connector_snprintf(buffer, bytes_available, "%u%03u",
spastor 0:1c358ea10753 529 dp_ptr->time.value.since_epoch_fractional.seconds,
spastor 0:1c358ea10753 530 dp_ptr->time.value.since_epoch_fractional.milliseconds);
spastor 0:1c358ea10753 531 break;
spastor 0:1c358ea10753 532
spastor 0:1c358ea10753 533 #if (defined CONNECTOR_HAS_64_BIT_INTEGERS)
spastor 0:1c358ea10753 534 case connector_time_local_epoch_whole:
spastor 0:1c358ea10753 535 bytes_processed = connector_snprintf(buffer, bytes_available, "%lld", dp_ptr->time.value.since_epoch_whole.milliseconds);
spastor 0:1c358ea10753 536 break;
spastor 0:1c358ea10753 537 #endif
spastor 0:1c358ea10753 538
spastor 0:1c358ea10753 539 case connector_time_local_iso8601:
spastor 0:1c358ea10753 540 bytes_processed = connector_snprintf(buffer, bytes_available, "%s", dp_ptr->time.value.iso8601_string);
spastor 0:1c358ea10753 541 break;
spastor 0:1c358ea10753 542 }
spastor 0:1c358ea10753 543
spastor 0:1c358ea10753 544 return bytes_processed;
spastor 0:1c358ea10753 545 }
spastor 0:1c358ea10753 546
spastor 0:1c358ea10753 547 static size_t dp_process_quality(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 548 {
spastor 0:1c358ea10753 549 connector_data_point_t const * dp_ptr = dp_info->data.csv.current_dp;
spastor 0:1c358ea10753 550 size_t bytes_processed = 0;
spastor 0:1c358ea10753 551
spastor 0:1c358ea10753 552 if (dp_ptr->quality.type != connector_quality_type_ignore)
spastor 0:1c358ea10753 553 bytes_processed = connector_snprintf(buffer, bytes_available, "%d", dp_ptr->quality.value);
spastor 0:1c358ea10753 554
spastor 0:1c358ea10753 555 return bytes_processed;
spastor 0:1c358ea10753 556 }
spastor 0:1c358ea10753 557
spastor 0:1c358ea10753 558 static size_t dp_process_description(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 559 {
spastor 0:1c358ea10753 560 connector_data_point_t const * dp_ptr = dp_info->data.csv.current_dp;
spastor 0:1c358ea10753 561 size_t bytes_processed = 0;
spastor 0:1c358ea10753 562
spastor 0:1c358ea10753 563 if (dp_ptr->description != 0)
spastor 0:1c358ea10753 564 bytes_processed = dp_process_string(dp_ptr->description, buffer, bytes_available, NULL);
spastor 0:1c358ea10753 565
spastor 0:1c358ea10753 566 return bytes_processed;
spastor 0:1c358ea10753 567 }
spastor 0:1c358ea10753 568
spastor 0:1c358ea10753 569 static size_t dp_process_location(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 570 {
spastor 0:1c358ea10753 571 connector_data_point_t const * dp_ptr = dp_info->data.csv.current_dp;
spastor 0:1c358ea10753 572 size_t bytes_processed = 0;
spastor 0:1c358ea10753 573
spastor 0:1c358ea10753 574 switch (dp_ptr->location.type)
spastor 0:1c358ea10753 575 {
spastor 0:1c358ea10753 576 case connector_location_type_ignore:
spastor 0:1c358ea10753 577 break;
spastor 0:1c358ea10753 578
spastor 0:1c358ea10753 579 case connector_location_type_text:
spastor 0:1c358ea10753 580 bytes_processed = connector_snprintf(buffer, bytes_available, "\"%s,%s,%s\"",
spastor 0:1c358ea10753 581 dp_ptr->location.value.text.latitude,
spastor 0:1c358ea10753 582 dp_ptr->location.value.text.longitude,
spastor 0:1c358ea10753 583 dp_ptr->location.value.text.elevation);
spastor 0:1c358ea10753 584 break;
spastor 0:1c358ea10753 585
spastor 0:1c358ea10753 586 #if (defined FLOATING_POINT_SUPPORTED)
spastor 0:1c358ea10753 587 case connector_location_type_native:
spastor 0:1c358ea10753 588 bytes_processed = connector_snprintf(buffer, bytes_available, "\"%f,%f,%f\"",
spastor 0:1c358ea10753 589 dp_ptr->location.value.native.latitude,
spastor 0:1c358ea10753 590 dp_ptr->location.value.native.longitude,
spastor 0:1c358ea10753 591 dp_ptr->location.value.native.elevation);
spastor 0:1c358ea10753 592 break;
spastor 0:1c358ea10753 593 #endif
spastor 0:1c358ea10753 594 }
spastor 0:1c358ea10753 595
spastor 0:1c358ea10753 596 return bytes_processed;
spastor 0:1c358ea10753 597 }
spastor 0:1c358ea10753 598
spastor 0:1c358ea10753 599 static size_t dp_process_type(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 600 {
spastor 0:1c358ea10753 601 char const * const type_list[] = {"INTEGER", "LONG", "FLOAT", "DOUBLE", "STRING", "BINARY"};
spastor 0:1c358ea10753 602 connector_request_data_point_single_t const * request = dp_info->data.csv.dp_request;
spastor 0:1c358ea10753 603 size_t bytes_processed = 0;
spastor 0:1c358ea10753 604
spastor 0:1c358ea10753 605 ASSERT_GOTO(asizeof(type_list) > request->type, error);
spastor 0:1c358ea10753 606 bytes_processed = connector_snprintf(buffer, bytes_available, "%s", type_list[request->type]);
spastor 0:1c358ea10753 607
spastor 0:1c358ea10753 608 error:
spastor 0:1c358ea10753 609 return bytes_processed;
spastor 0:1c358ea10753 610 }
spastor 0:1c358ea10753 611
spastor 0:1c358ea10753 612 static size_t dp_process_unit(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 613 {
spastor 0:1c358ea10753 614 connector_request_data_point_single_t const * request = dp_info->data.csv.dp_request;
spastor 0:1c358ea10753 615 size_t bytes_processed = 0;
spastor 0:1c358ea10753 616
spastor 0:1c358ea10753 617 if (request->unit != NULL)
spastor 0:1c358ea10753 618 bytes_processed = dp_process_string(request->unit, buffer, bytes_available, NULL);
spastor 0:1c358ea10753 619
spastor 0:1c358ea10753 620 return bytes_processed;
spastor 0:1c358ea10753 621 }
spastor 0:1c358ea10753 622
spastor 0:1c358ea10753 623 static size_t dp_process_forward_to(data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available)
spastor 0:1c358ea10753 624 {
spastor 0:1c358ea10753 625 connector_request_data_point_single_t const * request = dp_info->data.csv.dp_request;
spastor 0:1c358ea10753 626 size_t bytes_processed = 0;
spastor 0:1c358ea10753 627
spastor 0:1c358ea10753 628 if (request->forward_to != NULL)
spastor 0:1c358ea10753 629 bytes_processed = dp_process_string(request->forward_to, buffer, bytes_available, NULL);
spastor 0:1c358ea10753 630
spastor 0:1c358ea10753 631 return bytes_processed;
spastor 0:1c358ea10753 632 }
spastor 0:1c358ea10753 633
spastor 0:1c358ea10753 634 static size_t dp_update_state(data_point_info_t * const dp_info, char * const buffer)
spastor 0:1c358ea10753 635 {
spastor 0:1c358ea10753 636 if (dp_info->data.csv.state == dp_state_forward_to)
spastor 0:1c358ea10753 637 {
spastor 0:1c358ea10753 638 *buffer = '\n';
spastor 0:1c358ea10753 639 dp_info->data.csv.current_dp = dp_info->data.csv.current_dp->next;
spastor 0:1c358ea10753 640 dp_info->data.csv.state = dp_state_data;
spastor 0:1c358ea10753 641 }
spastor 0:1c358ea10753 642 else
spastor 0:1c358ea10753 643 {
spastor 0:1c358ea10753 644 *buffer = ',';
spastor 0:1c358ea10753 645 dp_info->data.csv.state++;
spastor 0:1c358ea10753 646 }
spastor 0:1c358ea10753 647
spastor 0:1c358ea10753 648 return 1;
spastor 0:1c358ea10753 649 }
spastor 0:1c358ea10753 650
spastor 0:1c358ea10753 651
spastor 0:1c358ea10753 652 static size_t dp_fill_csv_payload(data_point_info_t * const dp_info, void * const payload, size_t const total_bytes, connector_transport_t transport)
spastor 0:1c358ea10753 653 {
spastor 0:1c358ea10753 654 size_t bytes_copied = 0;
spastor 0:1c358ea10753 655 char * data_ptr = payload;
spastor 0:1c358ea10753 656 size_t bytes_remaining = total_bytes;
spastor 0:1c358ea10753 657 size_t (* process_fn) (data_point_info_t * const dp_info, char * const buffer, size_t const bytes_available) = NULL;
spastor 0:1c358ea10753 658
spastor 0:1c358ea10753 659 do
spastor 0:1c358ea10753 660 {
spastor 0:1c358ea10753 661 switch (dp_info->data.csv.state)
spastor 0:1c358ea10753 662 {
spastor 0:1c358ea10753 663 case dp_state_data:
spastor 0:1c358ea10753 664 process_fn = dp_process_data;
spastor 0:1c358ea10753 665 break;
spastor 0:1c358ea10753 666
spastor 0:1c358ea10753 667 case dp_state_time:
spastor 0:1c358ea10753 668 process_fn = dp_process_time;
spastor 0:1c358ea10753 669 break;
spastor 0:1c358ea10753 670
spastor 0:1c358ea10753 671 case dp_state_quality:
spastor 0:1c358ea10753 672 process_fn = dp_process_quality;
spastor 0:1c358ea10753 673 break;
spastor 0:1c358ea10753 674
spastor 0:1c358ea10753 675 case dp_state_description:
spastor 0:1c358ea10753 676 process_fn = dp_process_description;
spastor 0:1c358ea10753 677 break;
spastor 0:1c358ea10753 678
spastor 0:1c358ea10753 679 case dp_state_location:
spastor 0:1c358ea10753 680 process_fn = dp_process_location;
spastor 0:1c358ea10753 681 break;
spastor 0:1c358ea10753 682
spastor 0:1c358ea10753 683 case dp_state_type:
spastor 0:1c358ea10753 684 process_fn = dp_process_type;
spastor 0:1c358ea10753 685 break;
spastor 0:1c358ea10753 686
spastor 0:1c358ea10753 687 case dp_state_unit:
spastor 0:1c358ea10753 688 process_fn = dp_process_unit;
spastor 0:1c358ea10753 689 break;
spastor 0:1c358ea10753 690
spastor 0:1c358ea10753 691 case dp_state_forward_to:
spastor 0:1c358ea10753 692 process_fn = dp_process_forward_to;
spastor 0:1c358ea10753 693 break;
spastor 0:1c358ea10753 694 }
spastor 0:1c358ea10753 695
spastor 0:1c358ea10753 696 bytes_copied = process_fn(dp_info, data_ptr, bytes_remaining);
spastor 0:1c358ea10753 697 if (bytes_copied > 0)
spastor 0:1c358ea10753 698 {
spastor 0:1c358ea10753 699 if (bytes_copied >= bytes_remaining)
spastor 0:1c358ea10753 700 {
spastor 0:1c358ea10753 701 #if (defined CONNECTOR_SHORT_MESSAGE)
spastor 0:1c358ea10753 702 /* For SM transports this is a problem because the buffer where the CSV is
spastor 0:1c358ea10753 703 * written is preallocated. If the CSV grows to fill the buffer, then it
spastor 0:1c358ea10753 704 * is too late.
spastor 0:1c358ea10753 705 */
spastor 0:1c358ea10753 706 switch (transport)
spastor 0:1c358ea10753 707 {
spastor 0:1c358ea10753 708 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 709 case connector_transport_udp:
spastor 0:1c358ea10753 710 #endif
spastor 0:1c358ea10753 711 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 712 case connector_transport_sms:
spastor 0:1c358ea10753 713 #endif
spastor 0:1c358ea10753 714 connector_debug_printf("WARNING: Not enough space for processing the CSV DataPoint, increase the value of CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS\n");
spastor 0:1c358ea10753 715 ASSERT(connector_false);
spastor 0:1c358ea10753 716 break;
spastor 0:1c358ea10753 717 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 718 case connector_transport_tcp:
spastor 0:1c358ea10753 719 #endif
spastor 0:1c358ea10753 720 case connector_transport_all:
spastor 0:1c358ea10753 721 /* For connector_transport_tcp this is not a problem: once the packet is sent,
spastor 0:1c358ea10753 722 * this function will be called again to finish the CSV. */
spastor 0:1c358ea10753 723 break;
spastor 0:1c358ea10753 724 }
spastor 0:1c358ea10753 725 #else
spastor 0:1c358ea10753 726 UNUSED_PARAMETER(transport);
spastor 0:1c358ea10753 727 #endif
spastor 0:1c358ea10753 728 break;
spastor 0:1c358ea10753 729 }
spastor 0:1c358ea10753 730
spastor 0:1c358ea10753 731 data_ptr += bytes_copied;
spastor 0:1c358ea10753 732 bytes_remaining -= bytes_copied;
spastor 0:1c358ea10753 733 }
spastor 0:1c358ea10753 734
spastor 0:1c358ea10753 735 if (dp_info->data.csv.bytes_to_send == 0)
spastor 0:1c358ea10753 736 {
spastor 0:1c358ea10753 737 size_t const bytes_offset = dp_update_state(dp_info, data_ptr);
spastor 0:1c358ea10753 738
spastor 0:1c358ea10753 739 bytes_remaining -= bytes_offset;
spastor 0:1c358ea10753 740 data_ptr += bytes_offset;
spastor 0:1c358ea10753 741
spastor 0:1c358ea10753 742 if (dp_info->data.csv.current_dp == NULL)
spastor 0:1c358ea10753 743 {
spastor 0:1c358ea10753 744 break;
spastor 0:1c358ea10753 745 }
spastor 0:1c358ea10753 746 }
spastor 0:1c358ea10753 747 else
spastor 0:1c358ea10753 748 {
spastor 0:1c358ea10753 749 break;
spastor 0:1c358ea10753 750 }
spastor 0:1c358ea10753 751
spastor 0:1c358ea10753 752 } while (bytes_remaining > 0);
spastor 0:1c358ea10753 753
spastor 0:1c358ea10753 754 bytes_copied = total_bytes - bytes_remaining;
spastor 0:1c358ea10753 755
spastor 0:1c358ea10753 756 return bytes_copied;
spastor 0:1c358ea10753 757 }
spastor 0:1c358ea10753 758
spastor 0:1c358ea10753 759 static connector_callback_status_t dp_handle_data_callback(connector_data_service_send_data_t * const data_ptr)
spastor 0:1c358ea10753 760 {
spastor 0:1c358ea10753 761 connector_callback_status_t status = connector_callback_abort;
spastor 0:1c358ea10753 762 data_point_info_t * const dp_info = data_ptr->user_context;
spastor 0:1c358ea10753 763
spastor 0:1c358ea10753 764 ASSERT_GOTO(dp_info != NULL, error);
spastor 0:1c358ea10753 765 switch (dp_info->type)
spastor 0:1c358ea10753 766 {
spastor 0:1c358ea10753 767 case dp_content_type_binary:
spastor 0:1c358ea10753 768 if (dp_info->data.binary.bytes_to_send > data_ptr->bytes_available)
spastor 0:1c358ea10753 769 {
spastor 0:1c358ea10753 770 data_ptr->bytes_used = data_ptr->bytes_available;
spastor 0:1c358ea10753 771 data_ptr->more_data = connector_true;
spastor 0:1c358ea10753 772 }
spastor 0:1c358ea10753 773 else
spastor 0:1c358ea10753 774 {
spastor 0:1c358ea10753 775 data_ptr->bytes_used = dp_info->data.binary.bytes_to_send;
spastor 0:1c358ea10753 776 data_ptr->more_data = connector_false;
spastor 0:1c358ea10753 777 }
spastor 0:1c358ea10753 778
spastor 0:1c358ea10753 779 memcpy(data_ptr->buffer, dp_info->data.binary.current_bp, data_ptr->bytes_used);
spastor 0:1c358ea10753 780 dp_info->data.binary.current_bp += data_ptr->bytes_used;
spastor 0:1c358ea10753 781 dp_info->data.binary.bytes_to_send -= data_ptr->bytes_used;
spastor 0:1c358ea10753 782 break;
spastor 0:1c358ea10753 783
spastor 0:1c358ea10753 784 case dp_content_type_csv:
spastor 0:1c358ea10753 785 data_ptr->bytes_used = dp_fill_csv_payload(dp_info, data_ptr->buffer, data_ptr->bytes_available, data_ptr->transport);
spastor 0:1c358ea10753 786 data_ptr->more_data = (dp_info->data.csv.current_dp == NULL) ? connector_false : connector_true;
spastor 0:1c358ea10753 787 break;
spastor 0:1c358ea10753 788 }
spastor 0:1c358ea10753 789
spastor 0:1c358ea10753 790 status = connector_callback_continue;
spastor 0:1c358ea10753 791
spastor 0:1c358ea10753 792 error:
spastor 0:1c358ea10753 793 return status;
spastor 0:1c358ea10753 794 }
spastor 0:1c358ea10753 795
spastor 0:1c358ea10753 796 static connector_callback_status_t dp_handle_response_callback(connector_data_t * const connector_ptr, connector_data_service_send_response_t * const data_ptr)
spastor 0:1c358ea10753 797 {
spastor 0:1c358ea10753 798 connector_callback_status_t callback_status = connector_callback_abort;
spastor 0:1c358ea10753 799 data_point_info_t * const dp_info = data_ptr->user_context;
spastor 0:1c358ea10753 800 connector_request_id_t request_id;
spastor 0:1c358ea10753 801 connector_data_point_response_t user_data;
spastor 0:1c358ea10753 802
spastor 0:1c358ea10753 803 ASSERT_GOTO(dp_info != NULL, error);
spastor 0:1c358ea10753 804 switch (dp_info->type)
spastor 0:1c358ea10753 805 {
spastor 0:1c358ea10753 806 case dp_content_type_binary:
spastor 0:1c358ea10753 807 user_data.user_context = dp_info->data.binary.bp_request->user_context;
spastor 0:1c358ea10753 808 request_id.data_point_request = connector_request_id_data_point_binary_response;
spastor 0:1c358ea10753 809 break;
spastor 0:1c358ea10753 810
spastor 0:1c358ea10753 811 case dp_content_type_csv:
spastor 0:1c358ea10753 812 user_data.user_context = dp_info->data.csv.dp_request->user_context;
spastor 0:1c358ea10753 813 request_id.data_point_request = connector_request_id_data_point_single_response;
spastor 0:1c358ea10753 814 break;
spastor 0:1c358ea10753 815 }
spastor 0:1c358ea10753 816
spastor 0:1c358ea10753 817 user_data.transport = data_ptr->transport;
spastor 0:1c358ea10753 818 user_data.hint = data_ptr->hint;
spastor 0:1c358ea10753 819 switch (data_ptr->response)
spastor 0:1c358ea10753 820 {
spastor 0:1c358ea10753 821 case connector_data_service_send_response_success:
spastor 0:1c358ea10753 822 user_data.response = connector_data_point_response_success;
spastor 0:1c358ea10753 823 break;
spastor 0:1c358ea10753 824
spastor 0:1c358ea10753 825 case connector_data_service_send_response_bad_request:
spastor 0:1c358ea10753 826 user_data.response = connector_data_point_response_bad_request;
spastor 0:1c358ea10753 827 break;
spastor 0:1c358ea10753 828
spastor 0:1c358ea10753 829 case connector_data_service_send_response_unavailable:
spastor 0:1c358ea10753 830 user_data.response = connector_data_point_response_unavailable;
spastor 0:1c358ea10753 831 break;
spastor 0:1c358ea10753 832
spastor 0:1c358ea10753 833 case connector_data_service_send_response_cloud_error:
spastor 0:1c358ea10753 834 user_data.response = connector_data_point_response_cloud_error;
spastor 0:1c358ea10753 835 break;
spastor 0:1c358ea10753 836 default:
spastor 0:1c358ea10753 837 ASSERT(connector_false);
spastor 0:1c358ea10753 838 }
spastor 0:1c358ea10753 839
spastor 0:1c358ea10753 840 callback_status = connector_callback(connector_ptr->callback, connector_class_id_data_point, request_id, &user_data);
spastor 0:1c358ea10753 841 if (callback_status == connector_callback_busy) goto error;
spastor 0:1c358ea10753 842
spastor 0:1c358ea10753 843 #if (CONNECTOR_VERSION < 0x02010000)
spastor 0:1c358ea10753 844 if (free_data_buffer(connector_ptr, named_buffer_id(data_point_block), dp_info) != connector_working)
spastor 0:1c358ea10753 845 callback_status = connector_callback_abort;
spastor 0:1c358ea10753 846 #endif
spastor 0:1c358ea10753 847
spastor 0:1c358ea10753 848 error:
spastor 0:1c358ea10753 849 return callback_status;
spastor 0:1c358ea10753 850 }
spastor 0:1c358ea10753 851
spastor 0:1c358ea10753 852 static connector_callback_status_t dp_handle_status_callback(connector_data_t * const connector_ptr, connector_data_service_status_t * const data_ptr)
spastor 0:1c358ea10753 853 {
spastor 0:1c358ea10753 854 connector_callback_status_t callback_status = connector_callback_abort;
spastor 0:1c358ea10753 855 data_point_info_t * const dp_info = data_ptr->user_context;
spastor 0:1c358ea10753 856 connector_request_id_t request_id;
spastor 0:1c358ea10753 857 connector_data_point_status_t user_data;
spastor 0:1c358ea10753 858
spastor 0:1c358ea10753 859 ASSERT_GOTO(dp_info != NULL, error);
spastor 0:1c358ea10753 860 switch (dp_info->type)
spastor 0:1c358ea10753 861 {
spastor 0:1c358ea10753 862 case dp_content_type_binary:
spastor 0:1c358ea10753 863 user_data.user_context = dp_info->data.binary.bp_request->user_context;
spastor 0:1c358ea10753 864 request_id.data_point_request = connector_request_id_data_point_binary_status;
spastor 0:1c358ea10753 865 break;
spastor 0:1c358ea10753 866
spastor 0:1c358ea10753 867 case dp_content_type_csv:
spastor 0:1c358ea10753 868 user_data.user_context = dp_info->data.csv.dp_request->user_context;
spastor 0:1c358ea10753 869 request_id.data_point_request = connector_request_id_data_point_single_status;
spastor 0:1c358ea10753 870 break;
spastor 0:1c358ea10753 871 }
spastor 0:1c358ea10753 872
spastor 0:1c358ea10753 873 user_data.transport = data_ptr->transport;
spastor 0:1c358ea10753 874 user_data.session_error = data_ptr->session_error;
spastor 0:1c358ea10753 875 switch (data_ptr->status)
spastor 0:1c358ea10753 876 {
spastor 0:1c358ea10753 877 case connector_data_service_status_complete:
spastor 0:1c358ea10753 878 user_data.status = connector_data_point_status_complete;
spastor 0:1c358ea10753 879 break;
spastor 0:1c358ea10753 880
spastor 0:1c358ea10753 881 case connector_data_service_status_cancel:
spastor 0:1c358ea10753 882 user_data.status = connector_data_point_status_cancel;
spastor 0:1c358ea10753 883 break;
spastor 0:1c358ea10753 884
spastor 0:1c358ea10753 885 case connector_data_service_status_timeout:
spastor 0:1c358ea10753 886 user_data.status = connector_data_point_status_timeout;
spastor 0:1c358ea10753 887 break;
spastor 0:1c358ea10753 888
spastor 0:1c358ea10753 889 case connector_data_service_status_session_error:
spastor 0:1c358ea10753 890 user_data.status = connector_data_point_status_session_error;
spastor 0:1c358ea10753 891 break;
spastor 0:1c358ea10753 892
spastor 0:1c358ea10753 893 default:
spastor 0:1c358ea10753 894 user_data.status = connector_data_point_status_session_error;
spastor 0:1c358ea10753 895 break;
spastor 0:1c358ea10753 896 }
spastor 0:1c358ea10753 897
spastor 0:1c358ea10753 898 callback_status = connector_callback(connector_ptr->callback, connector_class_id_data_point, request_id, &user_data);
spastor 0:1c358ea10753 899 if (callback_status == connector_callback_busy) goto error;
spastor 0:1c358ea10753 900
spastor 0:1c358ea10753 901 if (free_data_buffer(connector_ptr, named_buffer_id(data_point_block), dp_info) != connector_working)
spastor 0:1c358ea10753 902 callback_status = connector_callback_abort;
spastor 0:1c358ea10753 903
spastor 0:1c358ea10753 904 error:
spastor 0:1c358ea10753 905 return callback_status;
spastor 0:1c358ea10753 906 }
spastor 0:1c358ea10753 907
spastor 0:1c358ea10753 908 #if (defined CONNECTOR_SHORT_MESSAGE)
spastor 0:1c358ea10753 909 static connector_callback_status_t dp_handle_length_callback(connector_data_service_length_t * const data_ptr)
spastor 0:1c358ea10753 910 {
spastor 0:1c358ea10753 911 connector_callback_status_t status = connector_callback_abort;
spastor 0:1c358ea10753 912 data_point_info_t * const dp_info = data_ptr->user_context;
spastor 0:1c358ea10753 913
spastor 0:1c358ea10753 914 ASSERT_GOTO(dp_info != NULL, error);
spastor 0:1c358ea10753 915 switch (dp_info->type)
spastor 0:1c358ea10753 916 {
spastor 0:1c358ea10753 917 case dp_content_type_binary:
spastor 0:1c358ea10753 918 data_ptr->total_bytes = dp_info->data.binary.bytes_to_send;
spastor 0:1c358ea10753 919 break;
spastor 0:1c358ea10753 920
spastor 0:1c358ea10753 921 case dp_content_type_csv:
spastor 0:1c358ea10753 922 {
spastor 0:1c358ea10753 923 size_t const sm_header_bytes = 6;
spastor 0:1c358ea10753 924 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 925 size_t const transport_layer_bytes = (data_ptr->transport == connector_transport_udp) ? 18 : 10;
spastor 0:1c358ea10753 926 size_t const max_packet_size = (data_ptr->transport == connector_transport_udp) ? SM_PACKET_SIZE_UDP : SM_PACKET_SIZE_SMS;
spastor 0:1c358ea10753 927 #else
spastor 0:1c358ea10753 928 size_t const transport_layer_bytes = 10;
spastor 0:1c358ea10753 929 size_t const max_packet_size = SM_PACKET_SIZE_SMS;
spastor 0:1c358ea10753 930 #endif
spastor 0:1c358ea10753 931 size_t const max_payload_bytes = max_packet_size - (sm_header_bytes + transport_layer_bytes);
spastor 0:1c358ea10753 932 #if !(defined CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS)
spastor 0:1c358ea10753 933 #define CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS 1
spastor 0:1c358ea10753 934 #endif
spastor 0:1c358ea10753 935
spastor 0:1c358ea10753 936 data_ptr->total_bytes = max_payload_bytes * CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS;
spastor 0:1c358ea10753 937 break;
spastor 0:1c358ea10753 938 }
spastor 0:1c358ea10753 939 }
spastor 0:1c358ea10753 940
spastor 0:1c358ea10753 941 status = connector_callback_continue;
spastor 0:1c358ea10753 942
spastor 0:1c358ea10753 943 error:
spastor 0:1c358ea10753 944 return status;
spastor 0:1c358ea10753 945 }
spastor 0:1c358ea10753 946 #endif
spastor 0:1c358ea10753 947
spastor 0:1c358ea10753 948 static connector_callback_status_t dp_handle_callback(connector_data_t * const connector_ptr, connector_request_id_data_service_t const ds_request_id, void * const data)
spastor 0:1c358ea10753 949 {
spastor 0:1c358ea10753 950 connector_callback_status_t status;
spastor 0:1c358ea10753 951
spastor 0:1c358ea10753 952 switch (ds_request_id)
spastor 0:1c358ea10753 953 {
spastor 0:1c358ea10753 954 case connector_request_id_data_service_send_data:
spastor 0:1c358ea10753 955 status = dp_handle_data_callback(data);
spastor 0:1c358ea10753 956 break;
spastor 0:1c358ea10753 957
spastor 0:1c358ea10753 958 case connector_request_id_data_service_send_response:
spastor 0:1c358ea10753 959 status = dp_handle_response_callback(connector_ptr, data);
spastor 0:1c358ea10753 960 break;
spastor 0:1c358ea10753 961
spastor 0:1c358ea10753 962 case connector_request_id_data_service_send_status:
spastor 0:1c358ea10753 963 status = dp_handle_status_callback(connector_ptr, data);
spastor 0:1c358ea10753 964 break;
spastor 0:1c358ea10753 965
spastor 0:1c358ea10753 966 #if (defined CONNECTOR_SHORT_MESSAGE)
spastor 0:1c358ea10753 967 case connector_request_id_data_service_send_length:
spastor 0:1c358ea10753 968 status = dp_handle_length_callback(data);
spastor 0:1c358ea10753 969 break;
spastor 0:1c358ea10753 970 #endif
spastor 0:1c358ea10753 971
spastor 0:1c358ea10753 972 default:
spastor 0:1c358ea10753 973 status = connector_callback_unrecognized;
spastor 0:1c358ea10753 974 break;
spastor 0:1c358ea10753 975 }
spastor 0:1c358ea10753 976
spastor 0:1c358ea10753 977 return status;
spastor 0:1c358ea10753 978 }
spastor 0:1c358ea10753 979