<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _read_opt_calipso(self, code, *, desc):
 """Read HOPOPT CALIPSO option. Structure of HOPOPT CALIPSO option [RFC 5570]: | Next Header | Hdr Ext Len | Option Type | Option Length| | CALIPSO Domain of Interpretation | | Cmpt Length | Sens Level | Checksum (CRC-16) | | Compartment Bitmap (Optional; variable length) | Octets Bits Name Description 0 0 hopopt.calipso.type Option Type 0 0 hopopt.calipso.type.value Option Number 0 0 hopopt.calipso.type.action Action (00) 0 2 hopopt.calipso.type.change Change Flag (0) 1 8 hopopt.calipso.length Length of Option Data 2 16 hopopt.calipso.domain CALIPSO Domain of Interpretation 6 48 hopopt.calipso.cmpt_len Cmpt Length 7 56 hopopt.calipso.level Sens Level 8 64 hopopt.calipso.chksum Checksum (CRC-16) 9 72 hopopt.calipso.bitmap Compartment Bitmap """

        _type = self._read_opt_type(code)
        _size = self._read_unpack(1)
        if _size < 8 and _size % 8 != 0:
            raise ProtocolError(f'{self.alias}: [Optno {code}] invalid format')
        _cmpt = self._read_unpack(4)
        _clen = self._read_unpack(1)
        if _clen % 2 != 0:
            raise ProtocolError(f'{self.alias}: [Optno {code}] invalid format')
        _sens = self._read_unpack(1)
        _csum = self._read_fileng(2)

        opt = dict(
            desc=desc,
            type=_type,
            length=_size + 2,
            domain=_cmpt,
            cmpt_len=_clen * 4,
            level=_sens,
            chksum=_csum,
        )

        if _clen:
            _bmap = list()
            for _ in range(_clen // 2):
                _bmap.append(self._read_binary(8))
            opt['bitmap'] = tuple(_bmap)

        _plen = _size - _clen * 4 - 8
        if _plen:
            self._read_fileng(_plen)

        return opt