Build modbus frame (add MBAP for Modbus/TCP, slave AD + CRC for RTU)

        :param fc: modbus function code
        :type fc: int
        :param body: modbus frame body
        :type body: str (Python2) or class bytes (Python3)
        :returns: modbus frame
        :rtype: str (Python2) or class bytes (Python3)

def _mbus_frame(self, fc, body):
        """Build modbus frame (add MBAP for Modbus/TCP, slave AD + CRC for RTU)

        :param fc: modbus function code
        :type fc: int
        :param body: modbus frame body
        :type body: str (Python2) or class bytes (Python3)
        :returns: modbus frame
        :rtype: str (Python2) or class bytes (Python3)
        """
        # build frame body
        f_body = struct.pack('B', fc) + body
        # modbus/TCP
        if self.__mode == const.MODBUS_TCP:
            # build frame ModBus Application Protocol header (mbap)
            self.__hd_tr_id = random.randint(0, 65535)
            tx_hd_pr_id = 0
            tx_hd_length = len(f_body) + 1
            f_mbap = struct.pack('>HHHB', self.__hd_tr_id, tx_hd_pr_id,
                                 tx_hd_length, self.__unit_id)
            return f_mbap + f_body
        # modbus RTU
        elif self.__mode == const.MODBUS_RTU:
            # format [slave addr(unit_id)]frame_body[CRC16]
            slave_ad = struct.pack('B', self.__unit_id)
            return self._add_crc(slave_ad + f_body)