Opens a CAN connection using `CanalOpen()`.

        :param str configuration: the configuration: "device_id; baudrate"
        :param int flags: the flags to be set

        :raises can.CanError: if any error occurred
        :returns: Valid handle for CANAL API functions on success

def open(self, configuration, flags):
        """
        Opens a CAN connection using `CanalOpen()`.

        :param str configuration: the configuration: "device_id; baudrate"
        :param int flags: the flags to be set

        :raises can.CanError: if any error occurred
        :returns: Valid handle for CANAL API functions on success
        """
        try:
            # we need to convert this into bytes, since the underlying DLL cannot
            # handle non-ASCII configuration strings
            config_ascii = configuration.encode('ascii', 'ignore')
            result = self.__m_dllBasic.CanalOpen(config_ascii, flags)
        except Exception as ex:
            # catch any errors thrown by this call and re-raise
            raise can.CanError('CanalOpen() failed, configuration: "{}", error: {}'
                               .format(configuration, ex))
        else:
            # any greater-than-zero return value indicates a success
            # (see https://grodansparadis.gitbooks.io/the-vscp-daemon/canal_interface_specification.html)
            # raise an error if the return code is <= 0
            if result <= 0:
                raise can.CanError('CanalOpen() failed, configuration: "{}", return code: {}'
                                   .format(configuration, result))
            else:
                return result