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 13:34:02 2013 +0000
Revision:
0:1c358ea10753
First commit

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 FW_TARGET_COUNT 1
spastor 0:1c358ea10753 14 #define FW_NO_CODE_SIZE -1
spastor 0:1c358ea10753 15 /**
spastor 0:1c358ea10753 16 * Firmware Upgrade Facility Opcodes
spastor 0:1c358ea10753 17 * @doc These are the valid opcodes for the Firmware Upgrade Facility
spastor 0:1c358ea10753 18 */
spastor 0:1c358ea10753 19 typedef enum {
spastor 0:1c358ea10753 20 fw_target_list_opcode,
spastor 0:1c358ea10753 21 fw_info_request_opcode,
spastor 0:1c358ea10753 22 fw_info_response_opcode,
spastor 0:1c358ea10753 23 fw_download_request_opcode,
spastor 0:1c358ea10753 24 fw_download_response_opcode,
spastor 0:1c358ea10753 25 fw_binary_block_opcode,
spastor 0:1c358ea10753 26 fw_binary_block_ack_opcode,
spastor 0:1c358ea10753 27 fw_download_abort_opcode,
spastor 0:1c358ea10753 28 fw_download_complete_opcode,
spastor 0:1c358ea10753 29 fw_download_complete_response_opcode,
spastor 0:1c358ea10753 30 fw_target_reset_opcode,
spastor 0:1c358ea10753 31 fw_download_status_opcode,
spastor 0:1c358ea10753 32 fw_error_opcode
spastor 0:1c358ea10753 33 } fw_opcodes_t;
spastor 0:1c358ea10753 34
spastor 0:1c358ea10753 35 typedef union {
spastor 0:1c358ea10753 36 enum {
spastor 0:1c358ea10753 37 fw_invalid_target,
spastor 0:1c358ea10753 38 fw_invalid_opcode,
spastor 0:1c358ea10753 39 fw_invalid_msg
spastor 0:1c358ea10753 40 } error_status;
spastor 0:1c358ea10753 41
spastor 0:1c358ea10753 42 enum {
spastor 0:1c358ea10753 43 fw_user_abort,
spastor 0:1c358ea10753 44 fw_device_error,
spastor 0:1c358ea10753 45 fw_invalid_offset,
spastor 0:1c358ea10753 46 fw_invalid_data,
spastor 0:1c358ea10753 47 fw_hardware_error
spastor 0:1c358ea10753 48 } abort_status;
spastor 0:1c358ea10753 49
spastor 0:1c358ea10753 50 } fw_abort_status_t;
spastor 0:1c358ea10753 51
spastor 0:1c358ea10753 52 #define connector_firmware_status_download_configured_to_reject 0x06
spastor 0:1c358ea10753 53
spastor 0:1c358ea10753 54 /* Firmware message header format:
spastor 0:1c358ea10753 55 * ------------------------
spastor 0:1c358ea10753 56 * | 0 | 1 | 3... |
spastor 0:1c358ea10753 57 * ------------------------
spastor 0:1c358ea10753 58 * | opcode | target | data |
spastor 0:1c358ea10753 59 * ------------------------
spastor 0:1c358ea10753 60 *
spastor 0:1c358ea10753 61 */
spastor 0:1c358ea10753 62 enum fw_message {
spastor 0:1c358ea10753 63 field_define(fw_message, opcode, uint8_t),
spastor 0:1c358ea10753 64 field_define(fw_message, target, uint8_t),
spastor 0:1c358ea10753 65 record_end(fw_message)
spastor 0:1c358ea10753 66 };
spastor 0:1c358ea10753 67
spastor 0:1c358ea10753 68 #define FW_MESSAGE_HEADER_SIZE record_bytes(fw_message)
spastor 0:1c358ea10753 69 #define FW_MESSAGE_RESPONSE_MAX_SIZE 16
spastor 0:1c358ea10753 70
spastor 0:1c358ea10753 71 typedef struct {
spastor 0:1c358ea10753 72 connector_data_t * connector_ptr;
spastor 0:1c358ea10753 73 connector_bool_t send_busy;
spastor 0:1c358ea10753 74 size_t response_size;
spastor 0:1c358ea10753 75 uint8_t response_buffer[FW_MESSAGE_RESPONSE_MAX_SIZE + PACKET_EDP_FACILITY_SIZE];
spastor 0:1c358ea10753 76 } connector_firmware_data_t;
spastor 0:1c358ea10753 77
spastor 0:1c358ea10753 78
spastor 0:1c358ea10753 79 /* abort and error message format:
spastor 0:1c358ea10753 80 * --------------------------
spastor 0:1c358ea10753 81 * | 0 | 1 | 2 |
spastor 0:1c358ea10753 82 * --------------------------
spastor 0:1c358ea10753 83 * | opcode | target | status |
spastor 0:1c358ea10753 84 * --------------------------
spastor 0:1c358ea10753 85 *
spastor 0:1c358ea10753 86 */
spastor 0:1c358ea10753 87 enum fw_abort {
spastor 0:1c358ea10753 88 field_define(fw_abort, opcode, uint8_t),
spastor 0:1c358ea10753 89 field_define(fw_abort, target, uint8_t),
spastor 0:1c358ea10753 90 field_define(fw_abort, status, uint8_t),
spastor 0:1c358ea10753 91 record_end(fw_abort)
spastor 0:1c358ea10753 92 };
spastor 0:1c358ea10753 93
spastor 0:1c358ea10753 94 #define FW_ABORT_HEADER_SIZE record_bytes(fw_abort)
spastor 0:1c358ea10753 95
spastor 0:1c358ea10753 96 static connector_status_t send_fw_message(connector_firmware_data_t * const fw_ptr)
spastor 0:1c358ea10753 97 {
spastor 0:1c358ea10753 98
spastor 0:1c358ea10753 99 connector_status_t status;
spastor 0:1c358ea10753 100
spastor 0:1c358ea10753 101 status = tcp_initiate_send_facility_packet(fw_ptr->connector_ptr, fw_ptr->response_buffer, fw_ptr->response_size, E_MSG_FAC_FW_NUM, NULL, NULL);
spastor 0:1c358ea10753 102 fw_ptr->send_busy = (status == connector_pending) ? connector_true : connector_false;
spastor 0:1c358ea10753 103 return status;
spastor 0:1c358ea10753 104
spastor 0:1c358ea10753 105 }
spastor 0:1c358ea10753 106
spastor 0:1c358ea10753 107 static connector_status_t send_fw_abort(connector_firmware_data_t * const fw_ptr, uint8_t const target, uint8_t const msg_opcode, fw_abort_status_t const abort_status)
spastor 0:1c358ea10753 108 {
spastor 0:1c358ea10753 109
spastor 0:1c358ea10753 110 connector_status_t status;
spastor 0:1c358ea10753 111
spastor 0:1c358ea10753 112 uint8_t * fw_abort = GET_PACKET_DATA_POINTER(fw_ptr->response_buffer, PACKET_EDP_FACILITY_SIZE);
spastor 0:1c358ea10753 113 uint8_t abort_code = (uint8_t)abort_status.error_status;
spastor 0:1c358ea10753 114
spastor 0:1c358ea10753 115 ASSERT(abort_status.error_status <= UCHAR_MAX);
spastor 0:1c358ea10753 116 ASSERT((sizeof fw_ptr->response_buffer - PACKET_EDP_FACILITY_SIZE) > FW_ABORT_HEADER_SIZE);
spastor 0:1c358ea10753 117
spastor 0:1c358ea10753 118 /* build abort message */
spastor 0:1c358ea10753 119 message_store_u8(fw_abort, opcode, msg_opcode);
spastor 0:1c358ea10753 120 message_store_u8(fw_abort, target, target);
spastor 0:1c358ea10753 121 message_store_u8(fw_abort, status, abort_code);
spastor 0:1c358ea10753 122
spastor 0:1c358ea10753 123 fw_ptr->response_size = FW_ABORT_HEADER_SIZE;
spastor 0:1c358ea10753 124 status = send_fw_message(fw_ptr);
spastor 0:1c358ea10753 125
spastor 0:1c358ea10753 126 return status;
spastor 0:1c358ea10753 127
spastor 0:1c358ea10753 128 }
spastor 0:1c358ea10753 129
spastor 0:1c358ea10753 130 static connector_status_t process_fw_info_request(connector_firmware_data_t * const fw_ptr, uint8_t * const fw_message, uint16_t const length)
spastor 0:1c358ea10753 131 {
spastor 0:1c358ea10753 132 /* firmware info response message format:
spastor 0:1c358ea10753 133 * ---------------------------------------------------
spastor 0:1c358ea10753 134 * | 0 | 1 | 2 - 5 | 6 - 9 | 10 ... |
spastor 0:1c358ea10753 135 * ---------------------------------------------------
spastor 0:1c358ea10753 136 * | opcode | target | version | Available | Firmware |
spastor 0:1c358ea10753 137 * | | | | code size | ID string |
spastor 0:1c358ea10753 138 * ---------------------------------------------------
spastor 0:1c358ea10753 139 *
spastor 0:1c358ea10753 140 * Firmware ID string = [descr]0xa[file name spec]
spastor 0:1c358ea10753 141 */
spastor 0:1c358ea10753 142 enum fw_info {
spastor 0:1c358ea10753 143 field_define(fw_info, opcode, uint8_t),
spastor 0:1c358ea10753 144 field_define(fw_info, target, uint8_t),
spastor 0:1c358ea10753 145 field_define(fw_info, version, uint32_t),
spastor 0:1c358ea10753 146 field_define(fw_info, code_size, uint32_t),
spastor 0:1c358ea10753 147 record_end(fw_info)
spastor 0:1c358ea10753 148 };
spastor 0:1c358ea10753 149
spastor 0:1c358ea10753 150 #define MAX_FW_INFO_REQUEST_LENGTH 2
spastor 0:1c358ea10753 151
spastor 0:1c358ea10753 152 connector_data_t * const connector_ptr = fw_ptr->connector_ptr;
spastor 0:1c358ea10753 153 connector_status_t status = connector_idle;
spastor 0:1c358ea10753 154 uint8_t const target = message_load_u8(fw_message, target);
spastor 0:1c358ea10753 155
spastor 0:1c358ea10753 156 connector_debug_printf("Firmware Facility: process info request\n");
spastor 0:1c358ea10753 157 /* parse firmware info request
spastor 0:1c358ea10753 158 * -----------------
spastor 0:1c358ea10753 159 * | 0 | 1 |
spastor 0:1c358ea10753 160 * -----------------
spastor 0:1c358ea10753 161 * | opcode | target |
spastor 0:1c358ea10753 162 * -----------------
spastor 0:1c358ea10753 163 */
spastor 0:1c358ea10753 164 if (length != MAX_FW_INFO_REQUEST_LENGTH)
spastor 0:1c358ea10753 165 {
spastor 0:1c358ea10753 166 fw_abort_status_t fw_status;
spastor 0:1c358ea10753 167 connector_debug_printf("process_fw_info_request: invalid message length\n");
spastor 0:1c358ea10753 168
spastor 0:1c358ea10753 169 fw_status.error_status = fw_invalid_msg;
spastor 0:1c358ea10753 170 status = send_fw_abort(fw_ptr, target, fw_error_opcode, fw_status);
spastor 0:1c358ea10753 171 goto done;
spastor 0:1c358ea10753 172
spastor 0:1c358ea10753 173 }
spastor 0:1c358ea10753 174
spastor 0:1c358ea10753 175 /* let's build a response.
spastor 0:1c358ea10753 176 * build and send firmware info response
spastor 0:1c358ea10753 177 */
spastor 0:1c358ea10753 178 {
spastor 0:1c358ea10753 179 #define FW_NOT_UPGRADABLE_DESCRIPTION "Non updateable firmware"
spastor 0:1c358ea10753 180
spastor 0:1c358ea10753 181 static const char fw_target_description[] = FW_NOT_UPGRADABLE_DESCRIPTION;
spastor 0:1c358ea10753 182 static const size_t fw_target_description_length = sizeof fw_target_description -1;
spastor 0:1c358ea10753 183
spastor 0:1c358ea10753 184 uint8_t * edp_header;
spastor 0:1c358ea10753 185 uint8_t * fw_info;
spastor 0:1c358ea10753 186 uint8_t * start_ptr;
spastor 0:1c358ea10753 187 size_t avail_length;
spastor 0:1c358ea10753 188
spastor 0:1c358ea10753 189 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_FAC_FW_NUM, &fw_info, &avail_length);
spastor 0:1c358ea10753 190 if (edp_header == NULL)
spastor 0:1c358ea10753 191 {
spastor 0:1c358ea10753 192 status = connector_pending;
spastor 0:1c358ea10753 193 goto done;
spastor 0:1c358ea10753 194 }
spastor 0:1c358ea10753 195 start_ptr = fw_info;
spastor 0:1c358ea10753 196
spastor 0:1c358ea10753 197 ASSERT(avail_length > (record_bytes(fw_info) + fw_target_description_length));
spastor 0:1c358ea10753 198
spastor 0:1c358ea10753 199 message_store_u8(fw_info, opcode, fw_info_response_opcode);
spastor 0:1c358ea10753 200 message_store_u8(fw_info, target, 0);
spastor 0:1c358ea10753 201 message_store_be32(fw_info, version, rci_get_firmware_target_zero_version());
spastor 0:1c358ea10753 202 message_store_be32(fw_info, code_size, FW_NO_CODE_SIZE);
spastor 0:1c358ea10753 203 fw_info += record_bytes(fw_info);
spastor 0:1c358ea10753 204
spastor 0:1c358ea10753 205
spastor 0:1c358ea10753 206
spastor 0:1c358ea10753 207 memcpy(fw_info, fw_target_description, fw_target_description_length);
spastor 0:1c358ea10753 208 fw_info += fw_target_description_length;
spastor 0:1c358ea10753 209 *fw_info++ = '\n';
spastor 0:1c358ea10753 210
spastor 0:1c358ea10753 211 /* reset back to initial values */
spastor 0:1c358ea10753 212
spastor 0:1c358ea10753 213 status = tcp_initiate_send_facility_packet(connector_ptr, edp_header, fw_info-start_ptr, E_MSG_FAC_FW_NUM, tcp_release_packet_buffer, NULL);
spastor 0:1c358ea10753 214
spastor 0:1c358ea10753 215 if (status != connector_working)
spastor 0:1c358ea10753 216 {
spastor 0:1c358ea10753 217 tcp_release_packet_buffer(connector_ptr, edp_header, connector_working, NULL);
spastor 0:1c358ea10753 218 }
spastor 0:1c358ea10753 219 }
spastor 0:1c358ea10753 220
spastor 0:1c358ea10753 221 done:
spastor 0:1c358ea10753 222 return status;
spastor 0:1c358ea10753 223 }
spastor 0:1c358ea10753 224
spastor 0:1c358ea10753 225 static connector_status_t process_fw_download_request(connector_firmware_data_t * const fw_ptr, uint8_t * fw_download_request, uint16_t const length)
spastor 0:1c358ea10753 226 {
spastor 0:1c358ea10753 227
spastor 0:1c358ea10753 228 /* Firmware download request message format:
spastor 0:1c358ea10753 229 * -----------------------------------------------------------
spastor 0:1c358ea10753 230 * | 0 | 1 | 2 - 5 | 6 - 9 | 10... |
spastor 0:1c358ea10753 231 * -----------------------------------------------------------
spastor 0:1c358ea10753 232 * | opcode | target | version | code size | firmware ID string |
spastor 0:1c358ea10753 233 * ------------------------------------------------------------
spastor 0:1c358ea10753 234 *
spastor 0:1c358ea10753 235 * Firmware ID string: [label]0x0a[file name spec]0xa[file name]
spastor 0:1c358ea10753 236 *
spastor 0:1c358ea10753 237 * Call the callback with these values and send download request response.
spastor 0:1c358ea10753 238 */
spastor 0:1c358ea10753 239 enum fw_download_request {
spastor 0:1c358ea10753 240 field_define(fw_download_request, opcode, uint8_t),
spastor 0:1c358ea10753 241 field_define(fw_download_request, target, uint8_t),
spastor 0:1c358ea10753 242 field_define(fw_download_request, version, uint32_t),
spastor 0:1c358ea10753 243 field_define(fw_download_request, code_size, uint32_t),
spastor 0:1c358ea10753 244 record_end(fw_download_request)
spastor 0:1c358ea10753 245 };
spastor 0:1c358ea10753 246
spastor 0:1c358ea10753 247
spastor 0:1c358ea10753 248 /* Firmware download response message format:
spastor 0:1c358ea10753 249 * ---------------------------------
spastor 0:1c358ea10753 250 * | 0 | 1 | 2 |
spastor 0:1c358ea10753 251 * ---------------------------------
spastor 0:1c358ea10753 252 * | opcode | target | response type |
spastor 0:1c358ea10753 253 * ---------------------------------
spastor 0:1c358ea10753 254 *
spastor 0:1c358ea10753 255 */
spastor 0:1c358ea10753 256 enum fw_download_response {
spastor 0:1c358ea10753 257 field_define(fw_download_response, opcode, uint8_t),
spastor 0:1c358ea10753 258 field_define(fw_download_response, target, uint8_t),
spastor 0:1c358ea10753 259 field_define(fw_download_response, response_type, uint8_t),
spastor 0:1c358ea10753 260 record_end(fw_download_response)
spastor 0:1c358ea10753 261 };
spastor 0:1c358ea10753 262
spastor 0:1c358ea10753 263 connector_status_t status = connector_idle;
spastor 0:1c358ea10753 264 fw_abort_status_t response_status;
spastor 0:1c358ea10753 265
spastor 0:1c358ea10753 266 uint8_t const target_number = message_load_u8(fw_download_request, target);
spastor 0:1c358ea10753 267
spastor 0:1c358ea10753 268 if (length < record_bytes(fw_download_request))
spastor 0:1c358ea10753 269 {
spastor 0:1c358ea10753 270 connector_debug_printf("process_fw_download_request: invalid message length\n");
spastor 0:1c358ea10753 271 response_status.error_status = fw_invalid_msg;
spastor 0:1c358ea10753 272 status = send_fw_abort(fw_ptr, target_number, fw_error_opcode, response_status);
spastor 0:1c358ea10753 273 goto done;
spastor 0:1c358ea10753 274 }
spastor 0:1c358ea10753 275
spastor 0:1c358ea10753 276 {
spastor 0:1c358ea10753 277 /* get a buffer for sending a response */
spastor 0:1c358ea10753 278 uint8_t * fw_download_response = GET_PACKET_DATA_POINTER(fw_ptr->response_buffer, PACKET_EDP_FACILITY_SIZE);
spastor 0:1c358ea10753 279
spastor 0:1c358ea10753 280 ASSERT((sizeof fw_ptr->response_buffer - PACKET_EDP_FACILITY_SIZE) > record_bytes(fw_download_response));
spastor 0:1c358ea10753 281
spastor 0:1c358ea10753 282 /* send error firmware download response */
spastor 0:1c358ea10753 283 message_store_u8(fw_download_response, opcode, fw_download_response_opcode);
spastor 0:1c358ea10753 284 message_store_u8(fw_download_response, target, target_number);
spastor 0:1c358ea10753 285 message_store_u8(fw_download_response, response_type, connector_firmware_status_download_configured_to_reject);
spastor 0:1c358ea10753 286
spastor 0:1c358ea10753 287 fw_ptr->response_size = record_bytes(fw_download_response);
spastor 0:1c358ea10753 288
spastor 0:1c358ea10753 289 status = send_fw_message(fw_ptr);
spastor 0:1c358ea10753 290 }
spastor 0:1c358ea10753 291
spastor 0:1c358ea10753 292 done:
spastor 0:1c358ea10753 293 return status;
spastor 0:1c358ea10753 294 }
spastor 0:1c358ea10753 295
spastor 0:1c358ea10753 296
spastor 0:1c358ea10753 297 static connector_status_t fw_discovery(connector_data_t * const connector_ptr, void * const facility_data,
spastor 0:1c358ea10753 298 uint8_t * const packet, unsigned int * receive_timeout)
spastor 0:1c358ea10753 299 {
spastor 0:1c358ea10753 300 /* Firmware target list message format:
spastor 0:1c358ea10753 301 *
spastor 0:1c358ea10753 302 * --------------------------------------------------------
spastor 0:1c358ea10753 303 * | 0 | 1 | 2 - 5 | 6 ... |
spastor 0:1c358ea10753 304 * -------------------------------------------------------
spastor 0:1c358ea10753 305 * | opcode | target | version | Additional target-version |
spastor 0:1c358ea10753 306 * | | | | pairs |
spastor 0:1c358ea10753 307 * -------------------------------------------------------
spastor 0:1c358ea10753 308 *
spastor 0:1c358ea10753 309 */
spastor 0:1c358ea10753 310 enum fw_target_list {
spastor 0:1c358ea10753 311 field_define(fw_target_list, opcode, uint8_t),
spastor 0:1c358ea10753 312 field_define(fw_target_list, target, uint8_t),
spastor 0:1c358ea10753 313 field_define(fw_target_list, version, uint32_t),
spastor 0:1c358ea10753 314 record_end(fw_target_list)
spastor 0:1c358ea10753 315 };
spastor 0:1c358ea10753 316
spastor 0:1c358ea10753 317 connector_status_t status = connector_idle;
spastor 0:1c358ea10753 318
spastor 0:1c358ea10753 319 UNUSED_PARAMETER(packet);
spastor 0:1c358ea10753 320 UNUSED_PARAMETER(receive_timeout);
spastor 0:1c358ea10753 321 UNUSED_PARAMETER(facility_data);
spastor 0:1c358ea10753 322
spastor 0:1c358ea10753 323 /* Construct a target list message.
spastor 0:1c358ea10753 324 */
spastor 0:1c358ea10753 325 {
spastor 0:1c358ea10753 326
spastor 0:1c358ea10753 327 uint8_t * edp_header;
spastor 0:1c358ea10753 328 uint8_t * fw_target_list;
spastor 0:1c358ea10753 329 size_t avail_length;
spastor 0:1c358ea10753 330
spastor 0:1c358ea10753 331 /* get packet pointer for constructing target list info */
spastor 0:1c358ea10753 332 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_FAC_FW_NUM, &fw_target_list, &avail_length);
spastor 0:1c358ea10753 333 if (edp_header == NULL)
spastor 0:1c358ea10753 334 {
spastor 0:1c358ea10753 335 status = connector_pending;
spastor 0:1c358ea10753 336 goto done;
spastor 0:1c358ea10753 337 }
spastor 0:1c358ea10753 338
spastor 0:1c358ea10753 339 ASSERT(avail_length >= record_bytes(fw_target_list));
spastor 0:1c358ea10753 340
spastor 0:1c358ea10753 341 message_store_u8(fw_target_list, opcode, fw_target_list_opcode);
spastor 0:1c358ea10753 342
spastor 0:1c358ea10753 343 {
spastor 0:1c358ea10753 344 uint8_t const target_number = 0; /* one target only */
spastor 0:1c358ea10753 345
spastor 0:1c358ea10753 346 message_store_u8(fw_target_list, target, target_number);
spastor 0:1c358ea10753 347 message_store_be32(fw_target_list, version, rci_get_firmware_target_zero_version());
spastor 0:1c358ea10753 348 }
spastor 0:1c358ea10753 349
spastor 0:1c358ea10753 350 status = tcp_initiate_send_facility_packet(connector_ptr, edp_header, record_bytes(fw_target_list),
spastor 0:1c358ea10753 351 E_MSG_FAC_FW_NUM, tcp_release_packet_buffer, NULL);
spastor 0:1c358ea10753 352 }
spastor 0:1c358ea10753 353
spastor 0:1c358ea10753 354 done:
spastor 0:1c358ea10753 355 return status;
spastor 0:1c358ea10753 356 }
spastor 0:1c358ea10753 357
spastor 0:1c358ea10753 358 static connector_status_t fw_process(connector_data_t * const connector_ptr, void * const facility_data,
spastor 0:1c358ea10753 359 uint8_t * const edp_header, unsigned int * const receive_timeout)
spastor 0:1c358ea10753 360 {
spastor 0:1c358ea10753 361 connector_status_t status = connector_idle;
spastor 0:1c358ea10753 362 connector_firmware_data_t * const fw_ptr = facility_data;
spastor 0:1c358ea10753 363 uint8_t opcode;
spastor 0:1c358ea10753 364 uint8_t target;
spastor 0:1c358ea10753 365 uint8_t * fw_message;
spastor 0:1c358ea10753 366 uint16_t length;
spastor 0:1c358ea10753 367
spastor 0:1c358ea10753 368 UNUSED_PARAMETER(receive_timeout);
spastor 0:1c358ea10753 369 fw_ptr->connector_ptr = connector_ptr;
spastor 0:1c358ea10753 370
spastor 0:1c358ea10753 371 if (edp_header == NULL)
spastor 0:1c358ea10753 372 {
spastor 0:1c358ea10753 373 goto done;
spastor 0:1c358ea10753 374 }
spastor 0:1c358ea10753 375
spastor 0:1c358ea10753 376 if (fw_ptr->send_busy == connector_true)
spastor 0:1c358ea10753 377 {
spastor 0:1c358ea10753 378 /* callback is already called for this message.
spastor 0:1c358ea10753 379 * We're here because we were unable to send a response
spastor 0:1c358ea10753 380 * message which already message is constructed in
spastor 0:1c358ea10753 381 * fw_ptr->response_buffer.
spastor 0:1c358ea10753 382 */
spastor 0:1c358ea10753 383 status = send_fw_message(fw_ptr);
spastor 0:1c358ea10753 384 goto done;
spastor 0:1c358ea10753 385 }
spastor 0:1c358ea10753 386
spastor 0:1c358ea10753 387 length = message_load_be16(edp_header, length);
spastor 0:1c358ea10753 388 if (length < FW_MESSAGE_HEADER_SIZE)
spastor 0:1c358ea10753 389 {
spastor 0:1c358ea10753 390 connector_debug_printf("fw_process: invalid packet size %d\n", length);
spastor 0:1c358ea10753 391 goto done;
spastor 0:1c358ea10753 392 }
spastor 0:1c358ea10753 393
spastor 0:1c358ea10753 394 fw_message = GET_PACKET_DATA_POINTER(edp_header, PACKET_EDP_FACILITY_SIZE);
spastor 0:1c358ea10753 395 opcode = message_load_u8(fw_message, opcode);
spastor 0:1c358ea10753 396 target = message_load_u8(fw_message, target);
spastor 0:1c358ea10753 397
spastor 0:1c358ea10753 398 ASSERT(FW_TARGET_COUNT == 1);
spastor 0:1c358ea10753 399
spastor 0:1c358ea10753 400 if (target >= FW_TARGET_COUNT)
spastor 0:1c358ea10753 401 {
spastor 0:1c358ea10753 402 fw_abort_status_t fw_status;
spastor 0:1c358ea10753 403
spastor 0:1c358ea10753 404 connector_debug_printf("fw_process: invalid target\n");
spastor 0:1c358ea10753 405
spastor 0:1c358ea10753 406 fw_status.error_status = fw_invalid_target;
spastor 0:1c358ea10753 407 status = send_fw_abort(fw_ptr, target, fw_error_opcode, fw_status);
spastor 0:1c358ea10753 408 goto done;
spastor 0:1c358ea10753 409 }
spastor 0:1c358ea10753 410
spastor 0:1c358ea10753 411 switch(opcode)
spastor 0:1c358ea10753 412 {
spastor 0:1c358ea10753 413 case fw_info_request_opcode:
spastor 0:1c358ea10753 414 status = process_fw_info_request(fw_ptr, fw_message, length);
spastor 0:1c358ea10753 415 break;
spastor 0:1c358ea10753 416 case fw_download_request_opcode:
spastor 0:1c358ea10753 417 status = process_fw_download_request(fw_ptr, fw_message, length);
spastor 0:1c358ea10753 418 break;
spastor 0:1c358ea10753 419 case fw_download_complete_opcode:
spastor 0:1c358ea10753 420 case fw_binary_block_opcode:
spastor 0:1c358ea10753 421 /* We already reject the download request.
spastor 0:1c358ea10753 422 * so should not receive this packet.
spastor 0:1c358ea10753 423 */
spastor 0:1c358ea10753 424 ASSERT(connector_false);
spastor 0:1c358ea10753 425 break;
spastor 0:1c358ea10753 426 case fw_download_abort_opcode:
spastor 0:1c358ea10753 427 break;
spastor 0:1c358ea10753 428 case fw_target_reset_opcode:
spastor 0:1c358ea10753 429 break;
spastor 0:1c358ea10753 430 default:
spastor 0:1c358ea10753 431 {
spastor 0:1c358ea10753 432 fw_abort_status_t fw_status;
spastor 0:1c358ea10753 433 fw_status.error_status = fw_invalid_opcode;
spastor 0:1c358ea10753 434 status = send_fw_abort(fw_ptr, target, fw_error_opcode, fw_status);
spastor 0:1c358ea10753 435 break;
spastor 0:1c358ea10753 436 }
spastor 0:1c358ea10753 437 }
spastor 0:1c358ea10753 438
spastor 0:1c358ea10753 439 done:
spastor 0:1c358ea10753 440 return status;
spastor 0:1c358ea10753 441 }
spastor 0:1c358ea10753 442
spastor 0:1c358ea10753 443 static connector_status_t connector_facility_firmware_delete(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 444 {
spastor 0:1c358ea10753 445 return del_facility_data(connector_ptr, E_MSG_FAC_FW_NUM);
spastor 0:1c358ea10753 446 }
spastor 0:1c358ea10753 447
spastor 0:1c358ea10753 448 static connector_status_t connector_facility_firmware_init(connector_data_t * const connector_ptr, unsigned int const facility_index)
spastor 0:1c358ea10753 449 {
spastor 0:1c358ea10753 450 connector_status_t status = connector_idle;
spastor 0:1c358ea10753 451 connector_firmware_data_t * fw_ptr;
spastor 0:1c358ea10753 452
spastor 0:1c358ea10753 453 /* Add firmware access facility to Device Cloud
spastor 0:1c358ea10753 454 *
spastor 0:1c358ea10753 455 * Make sure firmware access facility is not already created. If firmware
spastor 0:1c358ea10753 456 * access facility is already created, we probably reconnect to Device Cloud
spastor 0:1c358ea10753 457 * so just need to reset to initial state.
spastor 0:1c358ea10753 458 *
spastor 0:1c358ea10753 459 */
spastor 0:1c358ea10753 460 fw_ptr = get_facility_data(connector_ptr, E_MSG_FAC_FW_NUM);
spastor 0:1c358ea10753 461 if (fw_ptr == NULL)
spastor 0:1c358ea10753 462 {
spastor 0:1c358ea10753 463 void * ptr;
spastor 0:1c358ea10753 464 status = add_facility_data(connector_ptr, facility_index, E_MSG_FAC_FW_NUM, &ptr, sizeof *fw_ptr);
spastor 0:1c358ea10753 465
spastor 0:1c358ea10753 466 if (status != connector_working || ptr == NULL)
spastor 0:1c358ea10753 467 {
spastor 0:1c358ea10753 468 goto done;
spastor 0:1c358ea10753 469 }
spastor 0:1c358ea10753 470 fw_ptr = ptr;
spastor 0:1c358ea10753 471 }
spastor 0:1c358ea10753 472 fw_ptr->send_busy = connector_false;
spastor 0:1c358ea10753 473 fw_ptr->connector_ptr = connector_ptr;
spastor 0:1c358ea10753 474
spastor 0:1c358ea10753 475 done:
spastor 0:1c358ea10753 476 return status;
spastor 0:1c358ea10753 477 }
spastor 0:1c358ea10753 478
spastor 0:1c358ea10753 479