def _discover_services(self, sk8):
        """ TODO """

        ts = time.time()

        # start by discovering primary service UUIDs
        # params to ble_cmd_attclient_read_by_group_type are:
        #   conn_handle, start handle, end handle, UUID identifier to match (little endian)
        self._set_conn_state(sk8.conn_handle, self._STATE_DISCOVER_SERVICES)
        self.api.ble_cmd_attclient_read_by_group_type(sk8.conn_handle, 0x0001, 0xFFFF, RAW_UUID_GATT_PRIMARY_SERVICE)
        self._wait_for_conn_state(sk8.conn_handle, self._STATE_DISCOVER_SERVICES)
        logger.debug('Service discovery took: {:.3f}s'.format(time.time() - ts))

        logger.debug('Found {} primary services'.format(sk8.services))

        # now discover characteristics and descriptors within each service
        tc = time.time()
        for service in sk8.services.values():
            self._set_conn_state(sk8.conn_handle, self._STATE_DISCOVER_CHARS)
            self.api.ble_cmd_attclient_read_by_type(sk8.conn_handle, service.start_handle, service.end_handle, RAW_UUID_GATT_CHAR_DECL)
            self._wait_for_conn_state(sk8.conn_handle, self._STATE_DISCOVER_CHARS)

            self._set_conn_state(sk8.conn_handle, self._STATE_DISCOVER_DESCS)
            self.api.ble_cmd_attclient_find_information(sk8.conn_handle, service.start_handle, service.end_handle)
            self._wait_for_conn_state(sk8.conn_handle, self._STATE_DISCOVER_DESCS)

        logger.debug('Characteristic discovery took: {:.3f}s'.format(time.time() - tc))

        return True
TODO