@brief Check supported protocol, generate session handle, send replay back to originator. * @param socket Socket this request is associated to. Needed for double register check * @param receive_data Pointer to received data with request/response. */
| 553 | * @param receive_data Pointer to received data with request/response. |
| 554 | */ |
| 555 | void HandleReceivedRegisterSessionCommand(int socket, |
| 556 | const EncapsulationData *const receive_data, |
| 557 | ENIPMessage *const outgoing_message) { |
| 558 | int session_index = 0; |
| 559 | size_t session_handle = 0; |
| 560 | EncapsulationProtocolErrorCode encapsulation_protocol_status = |
| 561 | kEncapsulationProtocolSuccess; |
| 562 | |
| 563 | EipUint16 protocol_version = |
| 564 | GetIntFromMessage( |
| 565 | (const EipUint8 **const ) &receive_data->current_communication_buffer_position); |
| 566 | EipUint16 option_flag = |
| 567 | GetIntFromMessage( |
| 568 | (const EipUint8 **const ) &receive_data->current_communication_buffer_position); |
| 569 | |
| 570 | /* check if requested protocol version is supported and the register session option flag is zero*/ |
| 571 | if ( (0 < protocol_version) |
| 572 | && (protocol_version <= kSupportedProtocolVersion) |
| 573 | && (0 == option_flag) ) { /*Option field should be zero*/ |
| 574 | /* check if the socket has already a session open */ |
| 575 | for (size_t i = 0; i < OPENER_NUMBER_OF_SUPPORTED_SESSIONS; ++i) { |
| 576 | if (g_registered_sessions[i] == socket) { |
| 577 | /* the socket has already registered a session this is not allowed*/ |
| 578 | OPENER_TRACE_INFO( |
| 579 | "Error: A session is already registered at socket %d\n", |
| 580 | socket); |
| 581 | session_handle = i + 1; /*return the already assigned session back, the cip spec is not clear about this needs to be tested*/ |
| 582 | encapsulation_protocol_status = kEncapsulationProtocolInvalidCommand; |
| 583 | session_index = kSessionStatusInvalid; |
| 584 | break; |
| 585 | } |
| 586 | } |
| 587 | |
| 588 | if (kSessionStatusInvalid != session_index) { |
| 589 | session_index = GetFreeSessionIndex(); |
| 590 | if (kSessionStatusInvalid == session_index) /* no more sessions available */ |
| 591 | { |
| 592 | encapsulation_protocol_status = |
| 593 | kEncapsulationProtocolInsufficientMemory; |
| 594 | } else { /* successful session registered */ |
| 595 | SocketTimer *socket_timer = SocketTimerArrayGetEmptySocketTimer( |
| 596 | g_timestamps, |
| 597 | OPENER_NUMBER_OF_SUPPORTED_SESSIONS); |
| 598 | SocketTimerSetSocket(socket_timer, socket); |
| 599 | SocketTimerSetLastUpdate(socket_timer, g_actual_time); |
| 600 | g_registered_sessions[session_index] = socket; /* store associated socket */ |
| 601 | session_handle = session_index + 1; |
| 602 | encapsulation_protocol_status = kEncapsulationProtocolSuccess; |
| 603 | } |
| 604 | } |
| 605 | } else { /* protocol not supported */ |
| 606 | encapsulation_protocol_status = kEncapsulationProtocolUnsupportedProtocol; |
| 607 | } |
| 608 | |
| 609 | EncapsulateRegisterSessionCommandResponseMessage(receive_data, |
| 610 | session_handle, |
| 611 | encapsulation_protocol_status, |
| 612 | outgoing_message); |