libplctag icon indicating copy to clipboard operation
libplctag copied to clipboard

Can we use unconnected messaging with multi service request?

Open salma4791 opened this issue 2 years ago • 2 comments

Hi,

Can we use use_connected_msg=0 and allow_packing=1? MSR is not working for me using unconnected messaging. It is sending one request at a time even though the allow_packing option is set to 1.

Am using Allen-Bradley 1756-L73 ControlLogix PLC.

salma4791 avatar Dec 22 '23 12:12 salma4791

I further analyzed the code and figured out that get_payload_size(request) is only for connected messaging and for UCMM it is giving INT_MAX due to which the Bundle is not being formed and it is crashing.

/* how much space do we have to work with. */ remaining_space = session->max_payload_size - (int)sizeof(cip_multi_req_header);

        if(vector_length(session->requests)) {
            do {
                request = vector_get(session->requests, 0);

                remaining_space = remaining_space - get_payload_size(request);

                /*
                 * If we have a non-packable request, only queue it if it is the first one.
                 * If the request is packable, keep queuing as long as there is space.
                 */

                if(num_bundled_requests == 0 || (request->allow_packing && remaining_space > 0)) {
                    //pdebug(DEBUG_DETAIL, "packed %d requests with remaining space %d", num_bundled_requests+1, remaining_space);
                    bundled_requests[num_bundled_requests] = request;
                    num_bundled_requests++;

                    /* remove it from the queue. */
                    vector_remove(session->requests, 0);
                }
            } while(vector_length(session->requests) && remaining_space > 0 && num_bundled_requests < MAX_REQUESTS && request->allow_packing);

Here the get_payload_size(request) function gets the size only for connected service. int get_payload_size(ab_request_p request) { int request_data_size = 0; eip_encap *header = (eip_encap *)(request->data); eip_cip_co_req *co_req = NULL;

pdebug(DEBUG_DETAIL, "Starting.");

if(le2h16(header->encap_command) == AB_EIP_CONNECTED_SEND) {
    co_req = (eip_cip_co_req *)(request->data);
    /* get length of new request */
    request_data_size = le2h16(co_req->cpf_cdi_item_length)
                        - 2  /* for connection sequence ID */
                        + 2  /* for multipacket offset */
                        ;
} else {
    pdebug(DEBUG_DETAIL, "Not a supported type EIP packet type %d to get the payload size.", le2h16(header->encap_command));
    request_data_size = INT_MAX;
}

pdebug(DEBUG_DETAIL, "Done.");

return request_data_size;

}

Since the payload size is INT_MAX incase of unconnected send, it is giving negative value and crashing.

salma4791 avatar Dec 24 '23 08:12 salma4791

Huh... I wonder why I did that? That doesn't look right, but maybe there is some protocol difference on some PLCs? I will see if I can get to this in the next week. This does look like a bug.

kyle-github avatar Dec 24 '23 21:12 kyle-github

I finally got back to this. From what I can determine from online documentation I can find, unconnected messages go to the Connection Manager CIP object. That object does not support the service 0x0A, MultiServicePacket. That service is only available on the MessageRouter object which is what we connect to after we do a completed ForwardOpen.

I am going to close this as unsupported by the PLC unless I can find any other information.

kyle-github avatar Jun 09 '24 13:06 kyle-github