mbim_message_response.py revision e938ff00845c29f56935f2b973dd677793b8d834
1e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius# Copyright 2014 The Chromium OS Authors. All rights reserved.
2e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius# Use of this source code is governed by a BSD-style license that can be
3e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius# found in the LICENSE file.
4e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius"""
5e938ff00845c29f56935f2b973dd677793b8d834Roshan PiusAll of the MBIM response message type definitions are in this file. These
6e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusdefinitions inherit from MBIMControlMessage.
7e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
8e938ff00845c29f56935f2b973dd677793b8d834Roshan PiusReference:
9e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    [1] Universal Serial Bus Communications Class Subclass Specification for
10e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        Mobile Broadband Interface Model
11e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        http://www.usb.org/developers/docs/devclass_docs/
12e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        MBIM10Errata1_073013.zip
13e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius"""
14e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusimport logging
15e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
16e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusfrom autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants
17e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusfrom autotest_lib.client.cros.cellular.mbim_compliance import mbim_message
18e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
19e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
20e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMControlMessageResponse(mbim_message.MBIMControlMessage):
21e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ MBIMMessage Response Message base class. """
22e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    MESSAGE_TYPE = mbim_message.MESSAGE_TYPE_RESPONSE
23e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'message_type', mbim_message.FIELD_TYPE_PAYLOAD_ID),
24e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'message_length', ''),
25e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'transaction_id', ''))
26e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
27e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMOpenDone(MBIMControlMessageResponse):
28e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ The class for MBIM_OPEN_DONE. """
29e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
30e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'status_codes', ''),)
31e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _IDENTIFIERS = {'message_type': mbim_constants.MBIM_OPEN_DONE}
32e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
33e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
34e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMCloseDone(MBIMControlMessageResponse):
35e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ The class for MBIM_CLOSE_DONE. """
36e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
37e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'status_codes', ''),)
38e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _IDENTIFIERS = {'message_type': mbim_constants.MBIM_CLOSE_DONE}
39e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
40e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
41e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMCommandDoneSecondary(MBIMControlMessageResponse):
42e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ The class for MBIM_COMMAND_DONE. """
43e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
44e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'total_fragments', ''),
45e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'current_fragment', ''))
46e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
47e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
48e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMCommandDone(MBIMControlMessageResponse):
49e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ The class for MBIM_COMMAND_DONE. """
50e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
51e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'total_fragments', ''),
52e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'current_fragment', ''),
53e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('16s', 'device_service_id', mbim_message.FIELD_TYPE_PAYLOAD_ID),
54e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'cid', mbim_message.FIELD_TYPE_PAYLOAD_ID),
55e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'status_codes', ''),
56e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'information_buffer_length', ''))
57e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _IDENTIFIERS = {'message_type': mbim_constants.MBIM_COMMAND_DONE}
58e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _SECONDARY_FRAGMENT = MBIMCommandDoneSecondary
59e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
60e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
61e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMIndicateStatusSecondary(MBIMControlMessageResponse):
62e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ The class for MBIM_INDICATE_STATUS_MSG. """
63e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
64e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'total_fragments', ''),
65e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'current_fragment', ''))
66e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
67e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
68e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMIndicateStatus(MBIMControlMessageResponse):
69e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ The class for MBIM_INDICATE_STATUS_MSG. """
70e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
71e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'total_fragments', ''),
72e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'current_fragment', ''),
73e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('16s', 'device_service_id', mbim_message.FIELD_TYPE_PAYLOAD_ID),
74e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'cid', mbim_message.FIELD_TYPE_PAYLOAD_ID),
75e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius               ('I', 'information_buffer_length', ''))
76e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _IDENTIFIERS = {'message_type': mbim_constants.MBIM_INDICATE_STATUS_MSG}
77e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _SECONDARY_FRAGMENT = MBIMIndicateStatusSecondary
78e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
79e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
80e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusclass MBIMFunctionError(MBIMControlMessageResponse):
81e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """ The class for MBIM_FUNCTION_ERROR_MSG. """
82e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
83e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _FIELDS = (('I', 'error_status_code', ''),)
84e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    _IDENTIFIERS = {'message_type': mbim_constants.MBIM_FUNCTION_ERROR_MSG}
85e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
86e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
87e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusdef reassemble_response_packets(primary_fragment, secondary_packets):
88e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """
89e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    Reassembles fragmented response messages into a single object.
90e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
91e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    It parses all the secondary fragments as |secondary_frag_class| and
92e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    merges all the payload_buffer fields into the primary fragment.
93e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
94e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    @param primary_fragment: Primary fragment message object.
95e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    @param secondary_packets: Array of the raw byte array response received
96e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius                               from device.
97e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    @returns Reassembled Response Message object.
98e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
99e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """
100e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    secondary_frag_class = primary_fragment.get_secondary_fragment()
101e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    if not secondary_frag_class:
102e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        return
103e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
104e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    for packet in secondary_packets:
105e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        secondary_fragment = secondary_frag_class(raw_data=packet)
106e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        primary_fragment.payload_buffer.extend(
107e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius            secondary_fragment.payload_buffer)
108e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    return primary_fragment
109e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
110e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
111e938ff00845c29f56935f2b973dd677793b8d834Roshan Piusdef parse_response_packets(packets):
112e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """
113e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    Parses the incoming raw data |packets| into corresponding message response
114e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    object.
115e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
116e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    The function starts the at the root of the message hierarchy tree
117e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    and then goes down the root to find the exact leaf node message class. If
118e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    there are multiple frgaments expected at any level, it will reassemble the
119e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    secondary fragments before proceeding.
120e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
121e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    @param packets: Array of the raw byte array response received from device.
122e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    @returns Response Message object.
123e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius
124e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    """
125e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    # Start with the root class for all responses and then go down the tree.
126e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    message_class = MBIMControlMessageResponse
127e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    messages = []
128e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    packet = packets[0]
129e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    while message_class is not None:
130e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        message = message_class(raw_data=packet)
131e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        # If there are secondary fragments expected at this level,
132e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        # let's reassemble the payload together before traversing down the
133e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        # message heirarchy.
134e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        if len(packets) > 1:
135e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius            message = reassemble_response_packets(message, packets[1:])
136e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius        message_class = message.find_payload_class()
137e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    logging.debug("Response Message parsed: %s", message.__class__.__name__)
138e938ff00845c29f56935f2b973dd677793b8d834Roshan Pius    return message
139