Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
connector_tcp_open.h
00001 /* 00002 * Copyright (c) 2013 Digi International Inc., 00003 * All rights not expressly granted are reserved. 00004 * 00005 * This Source Code Form is subject to the terms of the Mozilla Public 00006 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 00007 * You can obtain one at http://mozilla.org/MPL/2.0/. 00008 * 00009 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343 00010 * ======================================================================= 00011 */ 00012 00013 static connector_status_t connect_to_cloud(connector_data_t * const connector_ptr, char const * cloud_url) 00014 { 00015 connector_status_t result = connector_working; 00016 00017 connector_callback_status_t status; 00018 connector_network_open_t open_data; 00019 00020 connector_request_id_t request_id; 00021 00022 open_data.device_cloud_url = cloud_url; 00023 open_data.handle = NULL; 00024 00025 request_id.network_request = connector_request_id_network_open; 00026 status = connector_callback(connector_ptr->callback, connector_class_id_network_tcp, request_id, &open_data); 00027 ASSERT(status != connector_callback_unrecognized); 00028 switch (status) 00029 { 00030 case connector_callback_continue: 00031 connector_ptr->edp_data.network_handle = open_data.handle; 00032 break; 00033 case connector_callback_abort: 00034 result = connector_abort; 00035 break; 00036 00037 case connector_callback_unrecognized: 00038 result = connector_unavailable; 00039 break; 00040 00041 case connector_callback_error: 00042 result = connector_open_error; 00043 break; 00044 case connector_callback_busy: 00045 result = connector_pending; 00046 break; 00047 } 00048 00049 return result; 00050 } 00051 00052 static connector_status_t send_version(connector_data_t * connector_ptr, uint16_t const type, uint32_t const version) 00053 { 00054 enum edp_version { 00055 field_define(edp_version, version, uint32_t), 00056 record_end(edp_version) 00057 }; 00058 size_t const version_message_size = record_bytes(edp_version); 00059 00060 connector_status_t result = connector_pending; 00061 uint8_t * edp_version; 00062 uint8_t * packet; 00063 00064 /* 00065 * version packet format: 00066 * ------------------------- 00067 * | 0 - 1 | 2 - 3 | 4 - 7 | 00068 * ------------------------- 00069 * | EDP header | version | 00070 * ------------------------- 00071 */ 00072 00073 packet = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &edp_version, NULL); 00074 if (packet != NULL) 00075 { 00076 message_store_be32(edp_version, version, version); 00077 00078 result = tcp_initiate_send_packet(connector_ptr, packet, version_message_size, 00079 type, 00080 tcp_release_packet_buffer, 00081 NULL); 00082 } 00083 00084 return result; 00085 } 00086 00087 static connector_status_t receive_edp_version(connector_data_t * const connector_ptr) 00088 { 00089 #define CLOUD_OVERLOAD_RESPONSE 0x02 00090 00091 connector_status_t result; 00092 uint8_t * ptr; 00093 connector_buffer_t * packet_buffer; 00094 00095 result = tcp_receive_packet(connector_ptr, &packet_buffer); 00096 00097 if (result == connector_working && packet_buffer != NULL) 00098 { 00099 uint16_t type; 00100 uint8_t response_code; 00101 uint8_t * const packet = packet_buffer->buffer; 00102 00103 connector_debug_printf("Receive Mt version\n"); 00104 /* 00105 * MT version response packet format: 00106 * --------------- 00107 * |0 - 1 | 2 - 3 | 00108 * --------------- 00109 * | Type | length | 00110 * --------------- 00111 * 00112 */ 00113 00114 ptr = GET_PACKET_DATA_POINTER(packet, PACKET_EDP_HEADER_SIZE); 00115 { 00116 uint8_t * edp_header = packet; 00117 type = message_load_be16(edp_header, type); 00118 } 00119 response_code = *ptr; 00120 00121 tcp_release_receive_packet(connector_ptr, packet_buffer); 00122 if (type != E_MSG_MT2_TYPE_VERSION_OK) 00123 { 00124 /* 00125 * The received message is not acceptable. 00126 */ 00127 switch (type) 00128 { 00129 /* Expected MTv2 message types... */ 00130 case E_MSG_MT2_TYPE_LEGACY_EDP_VER_RESP: 00131 if (response_code == CLOUD_OVERLOAD_RESPONSE) { 00132 connector_debug_printf("receive_edp_version: MTv2 legacy Cloud responded with overload msg\n"); 00133 } 00134 else { 00135 connector_debug_printf("receive_edp_version: MTv2 legacy bad version\n"); 00136 } 00137 break; 00138 case E_MSG_MT2_TYPE_VERSION_BAD: 00139 connector_debug_printf("receive_edp_version: bad version\n"); 00140 break; 00141 case E_MSG_MT2_TYPE_CLOUD_OVERLOAD: 00142 connector_debug_printf("receive_edp_version: Device Cloud responded with overload msg\n"); 00143 break; 00144 /* Unexpected/unknown MTv2 message types... */ 00145 default: 00146 connector_debug_printf("receive_edp_version: unknown MTv2 message\n"); 00147 } 00148 /* mt version error. let's notify user. 00149 * 00150 * ignore error status callback return value since Device Cloud 00151 * will close the connection. 00152 */ 00153 result = connector_abort; 00154 } 00155 } 00156 else if (result == connector_idle) result = connector_pending; 00157 00158 return result; 00159 } 00160 00161 static size_t build_keepalive_param(uint8_t * const edp_header, uint16_t const type, uint16_t const value) 00162 { 00163 enum edp_keepalive{ 00164 field_define(edp_keepalive, interval, uint16_t), 00165 record_end(edp_keepalive) 00166 }; 00167 00168 size_t const keepalive_size = record_bytes(edp_keepalive); 00169 uint8_t * edp_keepalive; 00170 00171 edp_keepalive = GET_PACKET_DATA_POINTER(edp_header, PACKET_EDP_HEADER_SIZE); 00172 message_store_be16(edp_header, type, type); 00173 { 00174 uint16_t const keepalive_size16 = (uint16_t) keepalive_size; 00175 00176 ASSERT(keepalive_size <= UINT16_MAX); 00177 message_store_be16(edp_header, length, keepalive_size16); 00178 } 00179 message_store_be16(edp_keepalive, interval, value); 00180 00181 00182 return (PACKET_EDP_HEADER_SIZE + keepalive_size); /* return count of bytes added to buffer */ 00183 } 00184 00185 static connector_status_t send_keepalive(connector_data_t * const connector_ptr) 00186 { 00187 connector_status_t result = connector_working; 00188 00189 uint8_t * ptr; 00190 uint8_t * packet; 00191 uint8_t * start_ptr; 00192 size_t i; 00193 00194 struct { 00195 uint16_t type; 00196 uint16_t value; 00197 } keepalive_parameters[3]; 00198 00199 #define init_param(i, t, v) keepalive_parameters[i].type = (t); keepalive_parameters[i].value = (v) 00200 init_param(0, E_MSG_MT2_TYPE_KA_RX_INTERVAL, GET_RX_KEEPALIVE_INTERVAL(connector_ptr)); 00201 init_param(1, E_MSG_MT2_TYPE_KA_TX_INTERVAL, GET_TX_KEEPALIVE_INTERVAL(connector_ptr)); 00202 init_param(2, E_MSG_MT2_TYPE_KA_WAIT, GET_WAIT_COUNT(connector_ptr)); 00203 #undef init_param 00204 00205 connector_debug_printf("Send keepalive params \n"); 00206 connector_debug_printf("Rx keepalive parameter = %d\n", keepalive_parameters[0].value); 00207 connector_debug_printf("Tx keepalive parameter = %d\n", keepalive_parameters[1].value); 00208 connector_debug_printf("Wait Count parameter = %d\n", keepalive_parameters[2].value); 00209 00210 packet = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &ptr, NULL); 00211 if (packet == NULL) 00212 { 00213 result = connector_pending; 00214 goto done; 00215 } 00216 ptr = (uint8_t *)packet; 00217 start_ptr = ptr; 00218 00219 for (i=0; i < asizeof(keepalive_parameters); i++) 00220 { 00221 size_t const len = build_keepalive_param(ptr, keepalive_parameters[i].type, keepalive_parameters[i].value); 00222 ptr += len; 00223 } 00224 /* Setting the total_length will enable tcp_send_packet_process. 00225 * Clear length to 0 for actual length that has been sent. 00226 */ 00227 { 00228 size_t const total_packet_length = (size_t)(ptr - start_ptr); 00229 ASSERT(ptr > start_ptr); 00230 connector_ptr->edp_data.send_packet.total_length = total_packet_length; 00231 connector_ptr->edp_data.send_packet.bytes_sent = 0; 00232 connector_ptr->edp_data.send_packet.ptr = packet; 00233 connector_ptr->edp_data.send_packet.complete_cb = tcp_release_packet_buffer; 00234 } 00235 00236 done: 00237 return result; 00238 } 00239 00240 static connector_status_t receive_protocol_version(connector_data_t * const connector_ptr) 00241 { 00242 enum { 00243 initialization_version_response_acceptable, 00244 initialization_version_response_unacceptable, 00245 initialization_version_response_unavailable 00246 }; 00247 00248 connector_status_t result; 00249 connector_buffer_t * packet_buffer; 00250 00251 result = tcp_receive_packet(connector_ptr, &packet_buffer); 00252 00253 if (result == connector_working) 00254 { 00255 uint8_t * edp_header; 00256 00257 ASSERT(packet_buffer != NULL); 00258 00259 edp_header = packet_buffer->buffer; 00260 00261 connector_debug_printf("Receive protocol version\n"); 00262 /* 00263 * version response packet format: 00264 * --------------------------------------- 00265 * | 0 - 1 | 2 - 3 | 4 | 00266 * --------------------------------------- 00267 * | Payload Type | length | response code | 00268 * ---------------------------------------- 00269 */ 00270 /* 00271 * Empty data packet 00272 */ 00273 if (message_load_be16(edp_header, length) > 0) 00274 { 00275 uint8_t * const response_code = GET_PACKET_DATA_POINTER(edp_header, PACKET_EDP_HEADER_SIZE); 00276 /* Parse the version response (0 = version response ok). 00277 * If the protocol version number was not acceptable to Device Cloud, 00278 * tell the application. 00279 */ 00280 if (*response_code != initialization_version_response_acceptable) 00281 { 00282 edp_set_close_status(connector_ptr, connector_close_status_abort); 00283 connector_debug_printf("receive_protocol_version:version is not accepted by Device Cloud\n"); 00284 edp_set_active_state(connector_ptr, connector_transport_close); 00285 } 00286 } 00287 00288 tcp_release_receive_packet(connector_ptr, packet_buffer); 00289 } 00290 else if (result == connector_idle) result = connector_pending; 00291 00292 return result; 00293 } 00294 00295 static connector_status_t send_identity_verification(connector_data_t * const connector_ptr) 00296 { 00297 /* The security operations other than encryption... */ 00298 #define SECURITY_OPER_IDENT_FORM UINT32_C(0x80) 00299 00300 /* Identity verification form codes... */ 00301 #define SECURITY_IDENT_FORM_SIMPLE UINT32_C(0x00) /* simple verification */ 00302 #define SECURITY_IDENT_FORM_PASSWORD UINT32_C(0x02) /* password verification */ 00303 00304 enum edp_security { 00305 field_define(edp_security, opcode, uint8_t), 00306 field_define(edp_security, identity, uint8_t), 00307 record_end(edp_security) 00308 }; 00309 00310 connector_status_t result; 00311 size_t const edp_security_size = record_bytes(edp_security); 00312 uint8_t * edp_security; 00313 uint8_t * edp_header; 00314 uint8_t identity = SECURITY_IDENT_FORM_SIMPLE; 00315 00316 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &edp_security, NULL); 00317 if (edp_header == NULL) 00318 { 00319 result = connector_pending; 00320 goto done; 00321 } 00322 00323 00324 connector_debug_printf("Send identity verification\n"); 00325 00326 /* 00327 * packet format: 00328 * ----------------------------------------------------- 00329 * | 0 - 1 | 2 - 3 | 4 | 5 | 00330 * ----------------------------------------------------- 00331 * | EDP header | Form opcode | identity verification | 00332 * ----------------------------------------------------- 00333 */ 00334 message_store_u8(edp_security, opcode, SECURITY_OPER_IDENT_FORM); 00335 00336 { 00337 00338 #if (defined CONNECTOR_IDENTITY_VERIFICATION) 00339 connector_identity_verification_t const identity_verification = CONNECTOR_IDENTITY_VERIFICATION; 00340 #else 00341 connector_identity_verification_t const identity_verification = connector_ptr->edp_data.config.identity_verification; 00342 #endif 00343 00344 switch (identity_verification) 00345 { 00346 case connector_identity_verification_simple: 00347 identity = SECURITY_IDENT_FORM_SIMPLE; 00348 break; 00349 case connector_identity_verification_password: 00350 identity = SECURITY_IDENT_FORM_PASSWORD; 00351 break; 00352 } 00353 } 00354 00355 message_store_u8(edp_security, identity, identity); 00356 00357 result = tcp_initiate_send_packet(connector_ptr, edp_header, edp_security_size, 00358 E_MSG_MT2_TYPE_PAYLOAD, 00359 tcp_release_packet_buffer, 00360 NULL); 00361 00362 done: 00363 return result; 00364 } 00365 00366 #if (CONNECTOR_VERSION >= 0x02010000) 00367 static connector_status_t send_provisioning(connector_data_t * const connector_ptr) 00368 { 00369 #define SECURITY_OPER_PROVISION_ID 0x89 00370 #define PROVISION_ID_LENGTH 4 00371 00372 enum edp_device_id { 00373 field_define(edp_provision_id, opcode, uint8_t), 00374 field_define(edp_provision_id, provision_id, uint32_t), 00375 record_end(edp_provision_id) 00376 }; 00377 00378 connector_status_t result; 00379 uint8_t * edp_header; 00380 uint8_t * edp_provision_id; 00381 size_t const provision_id_message_size = record_bytes(edp_provision_id); 00382 00383 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &edp_provision_id, NULL); 00384 if (edp_header == NULL) 00385 { 00386 result = connector_pending; 00387 goto done; 00388 } 00389 00390 /* 00391 * packet format: 00392 * ------------------------------------------------------- 00393 * | 0 - 1 | 2 - 3 | 4 | 5 - 8 | 00394 * ------------------------------------------------------- 00395 * | EDP header | Provision ID opcode | Provision ID ID | 00396 * ------------------------------------------------------- 00397 */ 00398 message_store_u8(edp_provision_id, opcode, SECURITY_OPER_PROVISION_ID); 00399 00400 #if !(defined CONNECTOR_VENDOR_ID) 00401 ASSERT(connector_ptr->edp_data.config.vendor_id != 0); 00402 message_store_be32(edp_provision_id, provision_id, connector_ptr->edp_data.config.vendor_id); 00403 #else 00404 message_store_be32(edp_provision_id, provision_id, CONNECTOR_VENDOR_ID); 00405 #endif 00406 00407 result = tcp_initiate_send_packet(connector_ptr, edp_header, provision_id_message_size, 00408 E_MSG_MT2_TYPE_PAYLOAD, tcp_release_packet_buffer, 00409 NULL); 00410 done: 00411 return result; 00412 } 00413 #endif 00414 00415 static connector_status_t send_device_id(connector_data_t * const connector_ptr) 00416 { 00417 #define SECURITY_OPER_DEVICE_ID 0x81 00418 00419 enum edp_device_id { 00420 field_define(edp_device_id, opcode, uint8_t), 00421 field_define_array(edp_device_id, id, DEVICE_ID_LENGTH), 00422 record_end(edp_device_id) 00423 }; 00424 00425 connector_status_t result; 00426 uint8_t * edp_header; 00427 uint8_t * edp_device_id; 00428 size_t const device_id_message_size = record_bytes(edp_device_id); 00429 00430 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &edp_device_id, NULL); 00431 if (edp_header == NULL) 00432 { 00433 result = connector_pending; 00434 goto done; 00435 } 00436 00437 /* 00438 * packet format: 00439 * ---------------------------------------------- 00440 * | 0 - 1 | 2 - 3 | 4 | 5 - 20 | 00441 * ---------------------------------------------- 00442 * | EDP header | Device ID opcode | Device ID | 00443 * ---------------------------------------------- 00444 */ 00445 message_store_u8(edp_device_id, opcode, SECURITY_OPER_DEVICE_ID); 00446 00447 ASSERT(connector_ptr->device_id != NULL); 00448 memcpy((edp_device_id + field_named_data(edp_device_id, id, offset)), connector_ptr->device_id, DEVICE_ID_LENGTH); 00449 00450 connector_debug_hexvalue("Sending Device ID", connector_ptr->device_id, DEVICE_ID_LENGTH); 00451 00452 result = tcp_initiate_send_packet(connector_ptr, edp_header, device_id_message_size, 00453 E_MSG_MT2_TYPE_PAYLOAD, tcp_release_packet_buffer, 00454 NULL); 00455 done: 00456 return result; 00457 } 00458 00459 #if (CONNECTOR_VERSION >= 0x02010000) 00460 static connector_status_t receive_device_id(connector_data_t * const connector_ptr) 00461 { 00462 connector_status_t result; 00463 connector_buffer_t * packet_buffer; 00464 00465 result = tcp_receive_packet(connector_ptr, &packet_buffer); 00466 00467 if (result == connector_working) 00468 { 00469 uint8_t * edp_header; 00470 00471 ASSERT(packet_buffer != NULL); 00472 00473 edp_header = packet_buffer->buffer; 00474 00475 /* 00476 * packet format: 00477 * ---------------------------------------------- 00478 * | 0 - 1 | 2 - 3 | 4 | 5 - 20 | 00479 * ---------------------------------------------- 00480 * | EDP header | Device ID opcode | Device ID | 00481 * ---------------------------------------------- 00482 */ 00483 { 00484 uint8_t * const opcode = GET_PACKET_DATA_POINTER(edp_header, PACKET_EDP_HEADER_SIZE); 00485 00486 if (*opcode != SECURITY_OPER_DEVICE_ID) 00487 { 00488 /* Device ID error. Notify user. */ 00489 result = connector_abort; 00490 } 00491 else 00492 { 00493 uint8_t * const device_id = opcode + sizeof(*opcode); 00494 connector_request_id_t request_id; 00495 connector_callback_status_t status; 00496 connector_config_pointer_data_t device_id_data; 00497 00498 /* Update internal device_id, needed for future connections */ 00499 memcpy(connector_ptr->device_id, device_id, DEVICE_ID_LENGTH); 00500 /* Call user function to save the provisioned Device ID */ 00501 device_id_data.bytes_required = DEVICE_ID_LENGTH; 00502 device_id_data.data = device_id; 00503 00504 connector_debug_hexvalue("Received Device ID", device_id, DEVICE_ID_LENGTH); 00505 00506 request_id.config_request = connector_request_id_config_set_device_id; 00507 status = connector_callback(connector_ptr->callback, connector_class_id_config, request_id, &device_id_data); 00508 switch (status) 00509 { 00510 case connector_callback_continue: 00511 break; 00512 case connector_callback_abort: 00513 result = connector_abort; 00514 break; 00515 case connector_callback_unrecognized: 00516 case connector_callback_error: 00517 result = connector_device_error; 00518 break; 00519 case connector_callback_busy: 00520 result = connector_pending; 00521 break; 00522 } 00523 } 00524 } 00525 00526 tcp_release_receive_packet(connector_ptr, packet_buffer); 00527 } 00528 else if (result == connector_idle) result = connector_pending; 00529 00530 return result; 00531 } 00532 #endif 00533 00534 static connector_status_t send_cloud_url(connector_data_t * const connector_ptr) 00535 { 00536 #define SECURITY_OPER_URL UINT32_C(0x86) 00537 00538 /* 00539 * packet format: 00540 * ------------------------------------------------ 00541 * | 0 - 1 | 2 - 3 | 4 | 5 - 6 | 7... | 00542 * ------------------------------------------------ 00543 * | EDP Header | URL opcode | URL length | URL | 00544 * ------------------------------------------------ 00545 */ 00546 enum edp_cloud_url { 00547 field_define(edp_cloud_url, opcode, uint8_t), 00548 field_define(edp_cloud_url, url_length, uint16_t), 00549 record_end(edp_cloud_url) 00550 }; 00551 connector_status_t result; 00552 uint8_t * edp_header; 00553 00554 char * cloud_url = connector_ptr->edp_data.config.cloud_url; 00555 uint8_t * edp_cloud_url; 00556 uint8_t * start_ptr; 00557 00558 static char const url_prefix[] = URL_PREFIX; 00559 static size_t const prefix_length = sizeof url_prefix -1; 00560 00561 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &start_ptr, NULL); 00562 if (edp_header == NULL) 00563 { 00564 result = connector_pending; 00565 goto done; 00566 } 00567 00568 edp_cloud_url = start_ptr; 00569 00570 connector_debug_printf("Send Device Cloud url = %.*s\n", (int)connector_ptr->edp_data.config.cloud_url_length, connector_ptr->edp_data.config.cloud_url); 00571 00572 message_store_u8(edp_cloud_url, opcode, SECURITY_OPER_URL); 00573 00574 { 00575 size_t const len = connector_ptr->edp_data.config.cloud_url_length + prefix_length; 00576 uint16_t const len16 = (uint16_t) len; 00577 00578 ASSERT(len <= UINT16_MAX); 00579 message_store_be16(edp_cloud_url, url_length, len16); 00580 } 00581 00582 edp_cloud_url += record_bytes(edp_cloud_url); 00583 memcpy(edp_cloud_url, url_prefix, prefix_length); 00584 edp_cloud_url += prefix_length; 00585 00586 memcpy(edp_cloud_url, cloud_url, connector_ptr->edp_data.config.cloud_url_length); 00587 edp_cloud_url += connector_ptr->edp_data.config.cloud_url_length; 00588 00589 { 00590 size_t const length = (size_t)(edp_cloud_url-start_ptr); 00591 ASSERT(edp_cloud_url > start_ptr); 00592 00593 result = tcp_initiate_send_packet(connector_ptr, edp_header, length, 00594 E_MSG_MT2_TYPE_PAYLOAD, 00595 tcp_release_packet_buffer, 00596 NULL); 00597 } 00598 done: 00599 return result; 00600 } 00601 00602 static connector_status_t send_password(connector_data_t * const connector_ptr) 00603 { 00604 #define SECURITY_OPER_PASSWORD 0x88 00605 00606 /* 00607 * packet format: 00608 * ----------------------------------------------------- 00609 * | 0 - 1 | 2 - 3 | 4 | 5 | 7... | 00610 * ----------------------------------------------------- 00611 * | EDP Header | password opcode | length | password | 00612 * ----------------------------------------------------- 00613 */ 00614 enum edp_password { 00615 field_define(edp_password, opcode, uint8_t), 00616 field_define(edp_password, password_length, uint16_t), 00617 record_end(edp_password) 00618 }; 00619 connector_status_t result; 00620 uint8_t * edp_header; 00621 00622 uint8_t * edp_password; 00623 uint8_t * start_ptr; 00624 00625 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &start_ptr, NULL); 00626 if (edp_header == NULL) 00627 { 00628 result = connector_pending; 00629 goto done; 00630 } 00631 00632 edp_password = start_ptr; 00633 00634 message_store_u8(edp_password, opcode, SECURITY_OPER_PASSWORD); 00635 00636 { 00637 uint16_t const length16 = (uint16_t) connector_ptr->edp_data.config.password_length; 00638 00639 ASSERT(connector_ptr->edp_data.config.password_length <= UINT16_MAX); 00640 message_store_be16(edp_password, password_length, length16); 00641 } 00642 edp_password += record_bytes(edp_password); 00643 00644 memcpy(edp_password, connector_ptr->edp_data.config.password, connector_ptr->edp_data.config.password_length); 00645 edp_password += connector_ptr->edp_data.config.password_length; 00646 00647 { 00648 size_t const length = (size_t)(edp_password-start_ptr); 00649 00650 ASSERT(edp_password > start_ptr); 00651 result = tcp_initiate_send_packet(connector_ptr, edp_header, length, 00652 E_MSG_MT2_TYPE_PAYLOAD, 00653 tcp_release_packet_buffer, 00654 NULL); 00655 } 00656 done: 00657 return result; 00658 } 00659 00660 static connector_status_t send_vendor_id(connector_data_t * const connector_ptr) 00661 { 00662 /* 00663 * packet format: 00664 * ---------------------------------------------------------------- 00665 * | 0 - 1 | 2 - 3 | 4 | 5 | 6 - 9 | 00666 * ---------------------------------------------------------------- 00667 * | EDP Header | security coding | vendor ID opcode | vendor ID | 00668 * ---------------------------------------------------------------- 00669 */ 00670 enum edp_vendor_msg { 00671 field_define(edp_vendor_msg, security_coding, uint8_t), 00672 field_define(edp_vendor_msg, opcode, uint8_t), 00673 field_define(edp_vendor_msg, vendor_id, uint32_t), 00674 record_end(edp_vendor_msg) 00675 }; 00676 00677 connector_status_t result; 00678 uint8_t * edp_header = NULL; 00679 00680 size_t const discovery_vendor_header_size = record_bytes(edp_vendor_msg); 00681 uint8_t * edp_vendor_msg; 00682 00683 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &edp_vendor_msg, NULL); 00684 if (edp_header == NULL) 00685 { 00686 result = connector_pending; 00687 goto done; 00688 } 00689 00690 message_store_u8(edp_vendor_msg, security_coding, SECURITY_PROTO_NONE); 00691 message_store_u8(edp_vendor_msg, opcode, DISC_OP_VENDOR_ID); 00692 #if !(defined CONNECTOR_VENDOR_ID) 00693 message_store_be32(edp_vendor_msg, vendor_id, connector_ptr->edp_data.config.vendor_id); 00694 #if (defined CONNECTOR_DEBUG) 00695 connector_debug_printf("Send vendor id = 0x%08X\n", connector_ptr->edp_data.config.vendor_id); 00696 #endif 00697 00698 #else 00699 { 00700 message_store_be32(edp_vendor_msg, vendor_id, CONNECTOR_VENDOR_ID); 00701 connector_debug_printf("Send vendor id = 0x%08X\n", CONNECTOR_VENDOR_ID); 00702 } 00703 #endif 00704 00705 result = tcp_initiate_send_packet(connector_ptr, edp_header, 00706 discovery_vendor_header_size, 00707 E_MSG_MT2_TYPE_PAYLOAD, 00708 tcp_release_packet_buffer, 00709 NULL); 00710 done: 00711 return result; 00712 } 00713 00714 static connector_status_t send_device_type(connector_data_t * const connector_ptr) 00715 { 00716 /* 00717 * packet format: 00718 * -------------------------------------------------------------------- 00719 * | 0 - 1 | 2 - 3 | 4 | 5 | 6 - 7 | 8... | 00720 * -------------------------------------------------------------------- 00721 * | EDP Header | security | device type | Device type | Device type | 00722 * | | coding | opcode | length | | 00723 * -------------------------------------------------------------------- 00724 */ 00725 enum edp_device_type_msg { 00726 field_define(edp_device_type, security_coding, uint8_t), 00727 field_define(edp_device_type, opcode, uint8_t), 00728 field_define(edp_device_type, length, uint16_t), 00729 record_end(edp_device_type) 00730 }; 00731 size_t const device_type_header_size = record_bytes(edp_device_type); 00732 00733 connector_status_t result; 00734 uint8_t * edp_header = NULL; 00735 uint8_t * edp_device_type; 00736 00737 #if (defined CONNECTOR_DEVICE_TYPE) 00738 static const char connector_device_type[] = CONNECTOR_DEVICE_TYPE; 00739 size_t device_type_length = sizeof connector_device_type-1; 00740 #else 00741 char * connector_device_type = connector_ptr->edp_data.config.device_type; 00742 size_t const device_type_length = connector_ptr->edp_data.config.device_type_length; 00743 #endif 00744 00745 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &edp_device_type, NULL); 00746 if (edp_header == NULL) 00747 { 00748 result = connector_pending; 00749 goto done; 00750 } 00751 00752 message_store_u8(edp_device_type, security_coding, SECURITY_PROTO_NONE); 00753 message_store_u8(edp_device_type, opcode, DISC_OP_DEVICETYPE); 00754 00755 { 00756 uint16_t const length16 = (uint16_t) device_type_length; 00757 00758 ASSERT(device_type_length <= UINT8_MAX); /* Despite the size is a 16-bit integer, the maximum allowed is 255 */ 00759 message_store_be16(edp_device_type, length, length16); 00760 } 00761 00762 edp_device_type += device_type_header_size; 00763 memcpy(edp_device_type, connector_device_type, device_type_length); 00764 00765 connector_debug_printf("Send device type = %.*s\n", (int)device_type_length, connector_device_type); 00766 00767 result = tcp_initiate_send_packet(connector_ptr, edp_header, 00768 (device_type_header_size + device_type_length), 00769 E_MSG_MT2_TYPE_PAYLOAD, 00770 tcp_release_packet_buffer, 00771 NULL); 00772 done: 00773 return result; 00774 } 00775 00776 static connector_status_t send_complete(connector_data_t * const connector_ptr) 00777 { 00778 /* 00779 * packet format: 00780 * ----------------------------------------- 00781 * | 0 - 1 | 2 - 3 | 4 | 5 | 00782 * ----------------------------------------- 00783 * | EDP Header | coding | initialization | 00784 * | | scheme | done opcode | 00785 * ----------------------------------------- 00786 */ 00787 enum edp_discovery_complete { 00788 field_define(edp_discovery_complete, security_coding, uint8_t), 00789 field_define(edp_discovery_complete, opcode, uint8_t), 00790 record_end(edp_discovery_complete) 00791 }; 00792 size_t const discovery_complete_message_size = record_bytes(edp_discovery_complete); 00793 uint8_t * edp_discovery_complete; 00794 connector_status_t result; 00795 uint8_t * edp_header = NULL; 00796 00797 edp_header = tcp_get_packet_buffer(connector_ptr, E_MSG_MT2_MSG_NUM, &edp_discovery_complete, NULL); 00798 if (edp_header == NULL) 00799 { 00800 result = connector_pending; 00801 goto done; 00802 } 00803 00804 connector_debug_printf("Send complete\n"); 00805 message_store_u8(edp_discovery_complete, security_coding, SECURITY_PROTO_NONE); 00806 message_store_u8(edp_discovery_complete, opcode, DISC_OP_INITCOMPLETE); 00807 00808 result = tcp_initiate_send_packet(connector_ptr, edp_header, 00809 discovery_complete_message_size, 00810 E_MSG_MT2_TYPE_PAYLOAD, 00811 tcp_release_packet_buffer, 00812 NULL); 00813 00814 done: 00815 return result; 00816 } 00817 00818 static connector_status_t layer_discovery_facility(connector_data_t * const connector_ptr); 00819 00820 static connector_status_t edp_tcp_open_process(connector_data_t * const connector_ptr) 00821 { 00822 connector_status_t result = connector_idle; 00823 00824 switch (edp_get_edp_state(connector_ptr)) 00825 { 00826 case edp_communication_connect_to_cloud: 00827 result = connect_to_cloud(connector_ptr, connector_ptr->edp_data.config.cloud_url); 00828 00829 switch(result) 00830 { 00831 case connector_working: 00832 edp_set_edp_state(connector_ptr, edp_communication_send_version); 00833 connector_ptr->edp_data.send_packet.packet_buffer.in_use = connector_false; 00834 connector_ptr->edp_data.receive_packet.packet_buffer.in_use = connector_false; 00835 connector_ptr->edp_data.receive_packet.packet_buffer.next = NULL; 00836 connector_ptr->edp_data.receive_packet.free_packet_buffer = &connector_ptr->edp_data.receive_packet.packet_buffer; 00837 break; 00838 case connector_unavailable: 00839 edp_set_active_state(connector_ptr, connector_transport_idle); 00840 connector_ptr->edp_data.stop.auto_connect = connector_false; 00841 break; 00842 case connector_open_error: 00843 { 00844 connector_ptr->edp_data.connect_at = 0; 00845 edp_set_active_state(connector_ptr, connector_transport_wait_for_reconnect); 00846 #if (defined CONNECTOR_NETWORK_TCP_START) 00847 if (CONNECTOR_NETWORK_TCP_START == connector_connect_manual) 00848 #else 00849 if (connector_ptr->edp_data.connect_type == connector_connect_manual) 00850 #endif 00851 { 00852 /* Application must call initiate_action to Start Cloud Connector */ 00853 edp_set_active_state(connector_ptr, connector_transport_idle); 00854 } 00855 break; 00856 } 00857 case connector_success: 00858 case connector_init_error: 00859 case connector_invalid_data_size: 00860 case connector_invalid_data_range: 00861 case connector_invalid_data: 00862 case connector_keepalive_error: 00863 case connector_bad_version: 00864 case connector_device_terminated: 00865 case connector_service_busy: 00866 case connector_invalid_response: 00867 case connector_no_resource: 00868 case connector_idle: 00869 case connector_pending: 00870 case connector_active: 00871 case connector_abort: 00872 case connector_device_error: 00873 case connector_exceed_timeout: 00874 case connector_invalid_payload_packet: 00875 break; 00876 } 00877 break; 00878 00879 case edp_communication_send_version: 00880 case edp_communication_send_keepalive: 00881 case edp_initialization_send_protocol_version: 00882 case edp_security_send_identity_verification: 00883 case edp_security_send_device_id: 00884 case edp_security_send_device_cloud_url: 00885 case edp_security_send_password: 00886 case edp_discovery_send_vendor_id: 00887 case edp_discovery_send_device_type: 00888 case edp_discovery_facility: 00889 case edp_discovery_send_complete: 00890 { 00891 connector_edp_state_t next_state = edp_get_edp_state(connector_ptr); 00892 00893 switch (edp_get_edp_state(connector_ptr)) 00894 { 00895 case edp_communication_send_version: 00896 connector_debug_printf("Send MT Version\n"); 00897 result = send_version(connector_ptr, E_MSG_MT2_TYPE_VERSION, EDP_MT_VERSION); 00898 if (result == connector_working) 00899 { 00900 next_state = edp_communication_receive_version_response; 00901 } 00902 break; 00903 00904 case edp_communication_send_keepalive: 00905 result = send_keepalive(connector_ptr); 00906 if (result == connector_working) 00907 { 00908 next_state = edp_initialization_send_protocol_version; 00909 } 00910 break; 00911 00912 case edp_initialization_send_protocol_version: 00913 { 00914 #define EDP_PROTOCOL_VERSION 0x120 00915 00916 connector_debug_printf("Send protocol version\n"); 00917 result = send_version(connector_ptr, E_MSG_MT2_TYPE_PAYLOAD, EDP_PROTOCOL_VERSION); 00918 if (result == connector_working) 00919 { 00920 next_state = edp_initialization_receive_protocol_version; 00921 } 00922 break; 00923 } 00924 case edp_security_send_identity_verification: 00925 result = send_identity_verification(connector_ptr); 00926 if (result == connector_working) 00927 { 00928 next_state = edp_security_send_device_id; 00929 } 00930 break; 00931 case edp_security_send_device_id: 00932 #if (CONNECTOR_VERSION >= 0x02010000) 00933 if (connector_ptr->connector_got_device_id) 00934 { 00935 result = send_device_id(connector_ptr); 00936 if (result == connector_working) 00937 { 00938 next_state = edp_security_send_device_cloud_url; 00939 } 00940 } 00941 else 00942 { 00943 result = send_provisioning(connector_ptr); 00944 if (result == connector_working) 00945 { 00946 next_state = edp_security_receive_device_id; 00947 } 00948 } 00949 #else 00950 result = send_device_id(connector_ptr); 00951 if (result == connector_working) 00952 next_state = edp_security_send_device_cloud_url; 00953 #endif 00954 break; 00955 case edp_security_send_device_cloud_url: 00956 result = send_cloud_url(connector_ptr); 00957 if (result == connector_working) 00958 { 00959 #if (defined CONNECTOR_IDENTITY_VERIFICATION) 00960 next_state = (CONNECTOR_IDENTITY_VERIFICATION == connector_identity_verification_password) ? edp_security_send_password : edp_discovery_send_vendor_id; 00961 #else 00962 next_state = (connector_ptr->edp_data.config.identity_verification == connector_identity_verification_password) ? edp_security_send_password : edp_discovery_send_vendor_id; 00963 #endif 00964 } 00965 break; 00966 00967 case edp_security_send_password: 00968 result = send_password(connector_ptr); 00969 if (result == connector_working) 00970 { 00971 next_state = edp_discovery_send_vendor_id; 00972 } 00973 break; 00974 00975 case edp_discovery_send_vendor_id: 00976 result = send_vendor_id(connector_ptr); 00977 if (result == connector_working) 00978 { 00979 next_state = edp_discovery_send_device_type; 00980 } 00981 break; 00982 00983 case edp_discovery_send_device_type: 00984 result = send_device_type(connector_ptr); 00985 if (result == connector_working) 00986 { 00987 next_state = edp_discovery_facility; 00988 } 00989 break; 00990 case edp_discovery_facility: 00991 result = layer_discovery_facility(connector_ptr); 00992 00993 if (result == connector_working) 00994 { 00995 next_state = edp_discovery_send_complete; 00996 } 00997 break; 00998 00999 case edp_discovery_send_complete: 01000 result = send_complete(connector_ptr); 01001 break; 01002 01003 default: 01004 break; 01005 } 01006 01007 if (result == connector_working || result == connector_idle || result == connector_pending) 01008 { 01009 result = edp_tcp_send_process(connector_ptr); 01010 if (result == connector_working) 01011 { 01012 if (edp_get_edp_state(connector_ptr) == edp_discovery_send_complete) 01013 { 01014 /* we are connected and EDP communication is fully established. */ 01015 edp_set_edp_state(connector_ptr, edp_facility_process); 01016 edp_set_active_state(connector_ptr, connector_transport_receive); 01017 01018 if (notify_status(connector_ptr->callback, connector_tcp_communication_started) != connector_working) 01019 result = connector_abort; 01020 01021 } 01022 01023 edp_set_edp_state(connector_ptr, next_state); 01024 } 01025 } 01026 01027 goto done; 01028 } 01029 case edp_communication_receive_version_response: 01030 result = receive_edp_version(connector_ptr); 01031 if (result == connector_working) 01032 { 01033 edp_set_edp_state(connector_ptr, edp_communication_send_keepalive); 01034 } 01035 01036 break; 01037 01038 case edp_initialization_receive_protocol_version: 01039 result = receive_protocol_version(connector_ptr); 01040 if (result == connector_working) 01041 { 01042 edp_set_edp_state(connector_ptr, edp_security_send_identity_verification); 01043 } 01044 break; 01045 #if (CONNECTOR_VERSION >= 0x02010000) 01046 case edp_security_receive_device_id: 01047 result = receive_device_id(connector_ptr); 01048 if (result == connector_working) 01049 { 01050 connector_ptr->connector_got_device_id = connector_true; 01051 edp_set_edp_state(connector_ptr, edp_security_send_device_cloud_url); 01052 } 01053 break; 01054 #endif 01055 case edp_facility_process: 01056 /* Should not be here since active state should not be open state. */ 01057 ASSERT(connector_false); 01058 break; 01059 } 01060 01061 done: 01062 if (result != connector_idle && result != connector_pending && result != connector_working) 01063 { 01064 if (edp_get_edp_state(connector_ptr) != edp_communication_connect_to_cloud) 01065 { 01066 /* set the close state and make it goes to close connection state */ 01067 edp_set_close_status(connector_ptr, connector_close_status_device_error); 01068 edp_set_active_state(connector_ptr, connector_transport_close); 01069 result = connector_working; 01070 } 01071 } 01072 return result; 01073 } 01074
Generated on Tue Jul 12 2022 19:18:38 by
1.7.2