Ejemplo n.º 1
0
/*
 * usbrecords_update
 * @param[elapsed]	elapsed time
 * @ret 0 - success, -1 error
 */
int usbrecords_update(int elapsed)
{
	recovery_entry_t *item;
	recovery_entry_t *tmp_item;

	LTRACEF("Update records\n");

	platform_mutex_lock(&recovery_lock);
	/* check all entries */
	for (item = TAILQ_FIRST(&t_recovery_queue); item != NULL; item = tmp_item) {
		tmp_item = TAILQ_NEXT(item, entries);
		/* update remaining recovery time */
		item->timeout -= elapsed;
		PTRACEF(USB_RECOVERY, "Check entry(%p): timeout %d\n", item, item->timeout);
		/* expired? */
		if(item->timeout < 0) {
			TRACEF("expired timeout::destroy record\n");
			/* destroy handle */
			novacom_usbll_destroy((novacom_usbll_handle_t)item->t_token->user_data);
			/* Remove the item from queue. */
			TAILQ_REMOVE(&t_recovery_queue, item, entries);
			/* Free the item as we don't need it anymore. */
			platform_free(item->t_token);
			platform_free(item);
		}
	}

	platform_mutex_unlock(&recovery_lock);

	return 0;
}
Ejemplo n.º 2
0
/*
 * usbrecords_remove
 * @param[nduid] device nduid
 * @ret 0 - success, -1 error
 */
int usbrecords_remove(char *nduid)
{
	recovery_entry_t *item;
	recovery_entry_t *tmp_item;

	LTRACEF("Update records\n");

	platform_mutex_lock(&recovery_lock);
	/* check all entries */
	for (item = TAILQ_FIRST(&t_recovery_queue); item != NULL; item = tmp_item) {
		tmp_item = TAILQ_NEXT(item, entries);
		if(0 == strncmp(item->t_token->nduid, nduid, sizeof(item->t_token->nduid)) ) {
TRACEF("explicit remove::nduid(%s)\n", nduid);
			/* destroy handle */
			novacom_usbll_destroy((novacom_usbll_handle_t)item->t_token->user_data);
			/* Remove the item from queue. */
			TAILQ_REMOVE(&t_recovery_queue, item, entries);
			/* Free the item as we don't need it anymore. */
			platform_free(item->t_token);
			platform_free(item);
		}
	}

	platform_mutex_unlock(&recovery_lock);

	return 0;
}
Ejemplo n.º 3
0
/*
 * usbrecords_find
 * check if we can recover device based on recovery queue
 * @param[t_token] recovery token to compare against
 * @ret -1 unable to recover, 0 success (token->user_data has handle) 
 */
int usbrecords_find(transport_recovery_token_t *t_token)
{
	int rc = -1;
	recovery_entry_t *item;
	recovery_entry_t *tmp_item;

	platform_mutex_lock(&recovery_lock);
	/* check all entries */
	for (item = TAILQ_FIRST(&t_recovery_queue); item != NULL; item = tmp_item) {
		transport_recovery_token_t *token = item->t_token;
		tmp_item = TAILQ_NEXT(item, entries);
		if (token->len == t_token->len) {

			if( 0 == memcmp(token->token, t_token->token, token->len) ) {
				TRACEF("Matches, nduid(%s)\n", token->nduid);
				/* Remove the item from queue. */
				TAILQ_REMOVE(&t_recovery_queue, item, entries);
				/* restore handle */
				t_token->user_data = token->user_data;
				/* Free the item as we don't need it anymore. */
				platform_free(item->t_token);
				platform_free(item);
				/* success */
				rc = 0;
				break;
			}
		}
	}
	platform_mutex_unlock(&recovery_lock);

	return rc;
}
Ejemplo n.º 4
0
/*
 * @brief: free buffer
 */
int buffer_free(buffer_t *b)
{
	/* check */
	if (!b)
		return -1;

	/* free data if exist */
	if(b->data)
		platform_free(b->data);

	platform_free(b);
	return 0;
}
Ejemplo n.º 5
0
/*
 * @brief handle authrequest
 */
static int novacom_handle_authrequest(device_handle_t dev, uint32_t chan, buffer_t *b, buffer_t *r, unsigned char cmd)
{
	int rc=-1;
	bool res = false;
	char *mode = NULL;
	char *str = NULL;

	/* skip version */
	if ( 0 != buffer_getbyte(b, NULL) ) {
		goto done;
	}

	/* get mode */
	if (0 != buffer_getstring(b, (unsigned char **)&mode) ) {
		goto done;
	}

	/* get hash */
	if ( 0 != buffer_getstring(b, (unsigned char **)&str) ) {
		goto done;
	}

	LTRACEF("mode %s, hash %s\n", mode, str);
	rc = strlen(mode);
	if ( (AUTH_METHOD_PASSWORD_LEN == rc)
		&& ( 0 == strncmp(mode, AUTH_METHOD_PASSWORD, rc)) ) {
		/*password request */
		res = auth_process_passw(str, strlen(str), 0);
	} else if ( (AUTH_METHOD_TOKEN_LEN == rc)
				&& ( 0 == strncmp(mode, AUTH_METHOD_TOKEN, rc)) ) {
		/*token request*/
		res = auth_process_token(str, strlen(str));
	}
	rc = (true == res)?0:-1;

done:
	/* pickup res */
	LTRACEF("result(%d)\n", rc);
	if (rc)
		buffer_putbyte(r, SSH_MSG_USERAUTH_FAILURE);
	else 
		buffer_putbyte(r, SSH_MSG_USERAUTH_SUCCESS);
	buffer_putbyte(r, 0);
	buffer_putbyte(r, cmd);

	/*resources */
	platform_free(mode);
	platform_free(str);
	return rc;
}
Ejemplo n.º 6
0
/*
 * @brief reports device list
 * @param sc socket
 * @param channel
 * @param url command url
 * @param dev device handle
 * @param ssid session id
 * @ret -1 error, 0 success
 */
int novacom_hostcmd_devremove(SOCKET sc, uint32_t channel, novacom_command_url_t *url, void *_dev, const char *ssid)
{
	int rc=-1;
	buffer_t *b = buffer_new(100); /* 44 + 44 + 2 */
	device_handle_t dev = (device_handle_t)_dev;
	char *file = NULL;
	char hash[SHA1_HASH_STRSIZE];

	if ( strlen(ssid) != NOVACOM_AUTHSESSION_LEN) {
		LTRACEF("invalid ssid length(%d)\n", strlen(ssid));
		goto done;
	}
	/* buffer */
	if (!b)
		goto done;

	/* expecting at least one parameter */
	if (url->argcount < 1) {
		goto done;
	}

	/* message type(auth.h) */
	rc = buffer_putbyte(b, SSH_MSG_USERAUTH_TOKENREQUEST_RM);
	if (rc)
		goto done;

	/* version info */
	rc = buffer_putbyte(b, 0);
	if (rc)
		goto done;

	/* password info */
	rc = buffer_putstring(b, (const unsigned char *)url->args[0], strlen(url->args[0]));
	if (rc)
		goto done;

	/* token hash info */
	file = novacom_rnduid(dev);
	if (!file)
		goto done;
	rc = tokenstorage_readhash(file, ssid, hash, sizeof(hash));
	if (-1 == rc) {
		LTRACEF("unable to get hashed token\n");
		goto done;
	}

	/* pack it */
	rc = buffer_putstring(b, (unsigned char *)hash, sizeof(hash));
	if (rc)
		goto done;

	rc = novacom_write_channel_async(dev, channel, b->data, b->pos, ASYNC_FLAG_COPY, (novacom_async_callback)&socketcmd_write_callback, (void *)url);

done:
	LTRACEF("rc(%d)\n", rc);
	platform_free(file);
	buffer_free(b);
	return rc;
}
Ejemplo n.º 7
0
void openrct2_dispose()
{
	network_close();
	http_dispose();
	language_close_all();
	openrct2_release_rct2_segment();
	platform_free();
}
Ejemplo n.º 8
0
    void openrct2_dispose()
    {
        network_close();
        http_dispose();
        language_close_all();
        rct2_dispose();
        config_release();
#ifndef DISABLE_NETWORK
        EVP_MD_CTX_destroy(gHashCTX);
#endif // DISABLE_NETWORK
        rct2_interop_dispose();
        platform_free();
    }
Ejemplo n.º 9
0
static long
ioctl_add_module(char *file)
{
    char *buf;
    int64_t ret;

    if (g_num_files >= MAX_NUM_MODULES)
    {
        ALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n");
        return BF_IOCTL_FAILURE;
    }

    buf = (char *)platform_alloc(g_module_length);
    if (buf == NULL)
    {
        ALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n");
        return BF_IOCTL_FAILURE;
    }

    ALERT("address to copy from %p size: 0x%" PRId64 "\n", file, g_module_length);

    ret = copyin((user_addr_t)file, (void *)buf, g_module_length);

    if (ret != 0)
    {
        ALERT("IOCTL_ADD_MODULE: failed to copy memory from userspace\n");
        goto failed;
    }

    ret = common_add_module(buf, g_module_length);
    if (ret != BF_SUCCESS)
    {
        ALERT("IOCTL_ADD_MODULE: failed to add module\n");
        goto failed;
    }

    files[g_num_files] = buf;
    files_sizes[g_num_files] = g_module_length;

    g_num_files++;

    DEBUG("IOCTL_ADD_MODULE: succeeded\n");
    return BF_IOCTL_SUCCESS;

failed:

    platform_free(buf, g_module_length);

    DEBUG("IOCTL_ADD_MODULE: failed\n");
    return BF_IOCTL_FAILURE;
}
Ejemplo n.º 10
0
/*
 * @brief: create new buffer
 */
buffer_t *buffer_new(size_t size)
{
	buffer_t *buf = NULL;
	buf = (buffer_t *)platform_calloc(sizeof(buffer_t));
	if (buf && size) {
		buf->data = (unsigned char *)platform_calloc(size);
		buf->len = size;
		if (!buf->data) {
			platform_free(buf);
			buf = NULL;
		}
	}
	return buf;
}
Ejemplo n.º 11
0
void clean_up( void ) {
	sound_free();
	game_list_free();
	submenu_free();
	platform_free();
	menu_free();
	hint_free();
	font_free();
	bg_free();
	location_free();
	event_free();
	snap_free();
	video_free();
	sdl_free();
}
Ejemplo n.º 12
0
/*
 * @brief: set buffer data
 */
int buffer_setdata(buffer_t *b, unsigned char *data, size_t size)
{
	if (b->data) {
		platform_free(b->data);
	}

	b->data = (unsigned char *)platform_calloc(size);
	if (!b->data) {
		return -1;
	}
	memcpy(b->data, data, size);
#if LOCAL_TRACE
	hexdump8(b->data, MIN(size, 64));
#endif
	b->pos = 0;
	b->len = size;
	return 0;
}
Ejemplo n.º 13
0
internal void *resize_pixel_buffer(struct pixel_buffer *buf, int height,
				   int width)
{
	debug(1, "Buffer was %d x %d, need %d x %d\n",
	      buf->width, buf->height, width, height);
	if (buf->pixels) {
		platform_free(buf->pixels, buf->pixels_bytes_len);
	}
	buf->width = width;
	buf->height = height;
	buf->pixels_bytes_len = buf->height * buf->width * buf->bytes_per_pixel;
	buf->pitch = buf->width * buf->bytes_per_pixel;
	buf->pixels = platform_alloc(buf->pixels_bytes_len);
	if (!buf->pixels) {
		debug(0, "Could not alloc buf->pixels (%d)\n",
		      buf->pixels_bytes_len);
	}
	return buf->pixels;
}
Ejemplo n.º 14
0
static long
ioctl_unload_vmm(void)
{
    int i;
    int64_t ret;
    long status = BF_IOCTL_SUCCESS;

    ret = common_unload_vmm();
    if (ret != BF_SUCCESS)
    {
        ALERT("IOCTL_UNLOAD_VMM: failed to unload vmm: %lld\n", ret);
        status = BF_IOCTL_FAILURE;
    }

    for (i = 0; i < g_num_files; i++)
        platform_free(files[i], files_sizes[i]);

    g_num_files = 0;

    if (status == BF_IOCTL_SUCCESS)
        DEBUG("IOCTL_UNLOAD_VMM: succeeded\n");

    return status;
}
Ejemplo n.º 15
0
static void *novacom_usb_tx_thread(void *arg)
{
	novacom_usb_handle_t *handle = (novacom_usb_handle_t *)arg;
	int rc;
	struct novacom_tx_packet packet;
	char *buf;

	buf = platform_calloc(MAX_MTU);
	platform_assert(buf != NULL);

	LTRACEF("start::wait for startup event: %p\n", handle);
	platform_event_wait(&handle->tx_startup_event);   //why waiting rx for starting ???
	handle->tx_startup_wait = 0;			  //change status to started
	LTRACEF("start::startup event received, continue: %p\n", handle);

	handle->tx_timeout = novacom_usbll_get_timeout(handle->usbll_handle);
	while (!novacom_shutdown && !handle->shutdown) {
		// see if we have something to send
		packet.len = novacom_usbll_get_mtu(handle->usbll_handle);
		packet.buf = buf;
		if (novacom_usbll_prepare_tx_packet(handle->usbll_handle, &packet, 100) != TX_NO_PACKET) {
			// write a block back
#if FAULTY_TX
			if (rand() < (RAND_MAX / 10)) {
				TRACEF("dropped tx packet\n");
			} else {
#endif
				rc = novacom_usb_write(handle, packet.buf, packet.len);
				if (rc < 0) {
					platform_time_t st;
					platform_time_t et;
					int time_used = 0;
					unsigned int count = 0;
					TRACEL(LOG_ALWAYS, "usbll(%08x) error writing packet, result(%d), errno %d\n", novacom_usbll_getuid(handle->usbll_handle), rc, errno);
					platform_get_time(&st);
					while (rc < 0 && !handle->shutdown) { //shutdown asap
						platform_get_time(&et);
						if (platform_delta_time_msecs(&st, &et) >= g_usbio_retry_timeout) {
							handle->shutdown = true;
							break;
						}
						if (g_usbio_retry_delay > 0) {
							if ((g_usbio_retry_timeout-time_used) >= g_usbio_retry_delay) {
								usleep(g_usbio_retry_delay * 1000);
								time_used += g_usbio_retry_delay;
							}
							else {
								usleep((g_usbio_retry_timeout - time_used) * 1000);
								time_used = g_usbio_retry_timeout;
							}
						}
						rc = novacom_usb_write(handle, packet.buf, packet.len);
						count++;

					}
		    			TRACEL(LOG_ALWAYS, "usbll(%08x) writing packet, writes(%ld), duration(%dms), result(%d), last_errno %ld\n", novacom_usbll_getuid(handle->usbll_handle), count, platform_delta_time_msecs(&st, &et), rc, errno);
					count = 0;
				}
				if (rc >=0) {
					TRACEF/*LOG_PRINTF*/("usbll(%08x) wrote tx packet len=%d\n", novacom_usbll_getuid(handle->usbll_handle), rc);
				}

#if FAULTY_TX
			}
#endif
		}
	}

	LTRACEF("shutting down handle %p\n", handle);

	platform_event_signal(&handle->tx_shutdown_event);

	platform_free(buf);

	return NULL;
}
Ejemplo n.º 16
0
/*
 * @brief: service reply
 * @ret
 * -1 error
 *  0 ok
 */
int novacom_service_reply(const char *devid, struct novacom_command_url *url, const void *buf, size_t len)
{
	int rc=-1;
	unsigned char type; /* reply cmd type */
	unsigned char version; /* reply cmd version */
	unsigned char cmd; /* reply cmd */
	buffer_t *b = buffer_new(0);

	LTRACEF("len %d\n", len);
	/* buffer wrapper */
	rc = buffer_setdata(b, (unsigned char *)buf, len);
	if (rc)
		goto done;

	/* recover message type, version, cmd */
	rc = buffer_getbyte(b, &type);
	if (rc)
		goto done;
	rc = buffer_getbyte(b, &version);
	if (rc)
		goto done;
	rc = buffer_getbyte(b, &cmd);
	if (rc)
		goto done;

	LTRACEF("msg type: %d, cmd %d\n", type, cmd);
	switch(cmd) {
		case SSH_MSG_DISCONNECT:
		case SSH_MSG_USERAUTH_REQUEST:
			rc = (SSH_MSG_USERAUTH_FAILURE == type)? -1:0;
		break;
		case SSH_MSG_USERAUTH_TOKENREQUEST_RM:
			rc = (SSH_MSG_USERAUTH_FAILURE == type)? -1:0;
			/* delete local store */
			if (SSH_MSG_USERAUTH_SUCCESS == type) {
				tokenstorage_remove(devid);
			}
		break;
		case SSH_MSG_USERAUTH_TOKENREQUEST_ADD:
			if (SSH_MSG_USERAUTH_TOKEN_REPLY == type) {
				unsigned char *token = NULL;
				rc = buffer_getblob(b, &token);
				LTRACEF("rc %d\n", rc);

				if (rc > 0) {
					LTRACEF("save token reply to local store\n");
					rc = tokenstorage_store(devid, token, rc);
					if (rc < 0) {
						TRACEF("Unable to save token in local store\n");
					}
					platform_free(token);
				}
			} else {
				rc = -1;
			}
		break;
		default: {
			rc = -1;
		}
		break;
	}

done:
	buffer_free(b);

	return rc;
}
Ejemplo n.º 17
0
/*
 * @brief handle token request
 * mode=0:add token request
 * mode=1:remove token request
 */
static int novacom_handle_tokenrequest(device_handle_t dev, uint32_t chan, buffer_t *b, buffer_t *r, unsigned char cmd)
{
	int rc=-1;
	char *hash = NULL;
	char *token = NULL;
	char *blob = NULL;

	/* skip version */
	if ( 0 != buffer_getbyte(b, NULL) ) {
		LTRACEF("missing version\n");
		goto out;
	}

	/* get hash */
	if ( 0 != buffer_getstring(b, (unsigned char **)&hash) ) {
		LTRACEF("missing password hash\n");
		goto out;
	}

	/* get hashed token for "remove" */
	if ( (SSH_MSG_USERAUTH_TOKENREQUEST_RM == cmd)
			&& ( 0 != buffer_getstring(b, (unsigned char **)&token) ) ) {
		LTRACEF("missing token hash\n");
		goto out;
	}

	/* verify that password hash is good */
	if ( true != auth_process_passw(hash, strlen(hash), 1) ) {
		LTRACEF("invalid password hash\n");
		goto out;
	}

	/* process tokens */
	if (SSH_MSG_USERAUTH_TOKENREQUEST_RM == cmd) {
		rc = auth_tokenfile_delete(token, strlen(token));
		/* pickup res */
		if (!rc) {
			buffer_putbyte(r, SSH_MSG_USERAUTH_SUCCESS);
			buffer_putbyte(r, 0);   /* version */
			buffer_putbyte(r, cmd); /* command */
		}
	} else {
		blob = platform_calloc(NOVACOM_AUTHTOKEN_LEN);
		if (!blob) {
			LTRACEF("unable to allocate token\n");
			goto out;
		}
		/* fill with random data */
		LTRACEF("generate token\n");
		rc = auth_tokenfile_buffergenerate(blob, NOVACOM_AUTHTOKEN_LEN);
		if (rc) {
			LTRACEF("unable to generate token\n");
			goto out;
		}
		/* save token: creating file with name:<rnduid> */
		LTRACEF("save token\n");
		char *file = novacom_rnduid(dev);
		if (!file) {
			LTRACEF("unable to retrieve rnduid\n");
			goto out;
		}
		rc = auth_tokenfile_create(file, blob, NOVACOM_AUTHTOKEN_LEN);
		platform_free(file);
		if (rc) {
			LTRACEF("unable to store token\n");
			goto out;
		}
		LTRACEF("token generated && saved\n");
		/* pickup res */
		buffer_putbyte(r, SSH_MSG_USERAUTH_TOKEN_REPLY);
		buffer_putbyte(r, 0);   /* version */
		buffer_putbyte(r, cmd); /* command */
		/* resize output buffer to fit token data */
		rc = buffer_resize(r, 16 + NOVACOM_AUTHTOKEN_LEN);
		if (rc)
			goto out;

		rc = buffer_putblob(r, (unsigned char *)blob, NOVACOM_AUTHTOKEN_LEN);
		LTRACEF("token placed\n");
	}

out:
	/* error result */
	if (rc) {
		buffer_setpos(r, 0);
		buffer_putbyte(r, SSH_MSG_USERAUTH_FAILURE);
		buffer_putbyte(r, 0);   /* version */
		buffer_putbyte(r, cmd); /* command */
	}
	LTRACEF("result(%d), r->pos %d, r->size %d\n", rc, r->pos, r->len);
	/* free resources */
	platform_free(hash);
	platform_free(token);
	platform_free(blob);
	return rc;
}
Ejemplo n.º 18
0
static void *novacom_usb_rx_thread(void *arg)
{
	novacom_usb_handle_t *handle = (novacom_usb_handle_t *)arg;
	transport_recovery_token_t *rec_token = NULL;					///< recovery token
	int rc;
	int packet_type;
	char *buf;
	int sniff = 1;

	buf = platform_calloc(MAX_MTU);
	platform_assert(buf != NULL);

	LTRACEF("start, handle %p\n", handle);

	handle->rx_timeout = novacom_usbll_get_timeout(handle->usbll_handle);
	while (!novacom_shutdown && !handle->shutdown) {
		platform_time_t st;
		int time_used;
		// read a block from the pmux
		rc = novacom_usb_read(handle, buf, novacom_usbll_get_mtu(handle->usbll_handle));
		platform_get_time(&st);
		time_used = 0;
		if (rc <= 0) {
			platform_time_t et;
			unsigned int count = 0;
			TRACEL(LOG_ALWAYS, "%s:%d -- usbll(%08x) error: reading packet, result(%d), errno %d\n", __FUNCTION__, __LINE__, novacom_usbll_getuid(handle->usbll_handle), rc, errno);
			while (rc <= 0 && !handle->shutdown) { //shutdown asap
				platform_get_time(&et);
				if (platform_delta_time_msecs(&st, &et) >= g_usbio_retry_timeout) {
					handle->shutdown = true;
					break;
				}
				if (g_usbio_retry_delay > 0) {
					if ((g_usbio_retry_timeout-time_used) >= g_usbio_retry_delay) {
						usleep(g_usbio_retry_delay * 1000);
						time_used += g_usbio_retry_delay;
					}
					else {
						usleep((g_usbio_retry_timeout - time_used) * 1000);
						time_used = g_usbio_retry_timeout;
					}
				}
				rc = novacom_usb_read(handle, buf, novacom_usbll_get_mtu(handle->usbll_handle));
				count++;

			}
		    TRACEL(LOG_ALWAYS, "%s:%d -- usbll(%08x) reading packet, reads(%ld), duration(%dms), result(%d), last_errno %ld\n",  __FUNCTION__, __LINE__, novacom_usbll_getuid(handle->usbll_handle), count, platform_delta_time_msecs(&st, &et), rc, errno);
 		    count = 0;

		}

		/* sniff */
		if(sniff) {
			uint32_t uid = ((handle->busnum & 0x0FFFF) << 16) | (handle->devnum & 0x0FFFF);
			transport_recovery_token_t sniff_token;
			int ret;

			/* generate token from packet */
			ret = novacom_usbll_generate_recovery_token(buf, rc, &sniff_token);
			if(ret == -1) {
				TRACEL(LOG_ERROR, "%s:%d -- Used out system resouce, exit now !!!\n", __FUNCTION__, __LINE__);
				abort();
			}
			/* check queue for saved connections */
			ret = usbrecords_find(&sniff_token);
			/* free interface recovery token */
			platform_free(sniff_token.token);
			/* check result: create new handle, or recover */
			if(ret) {
				LTRACEF("Unable to recover(%d)\n", ret);
				handle->usbll_handle = novacom_usbll_create(handle->devtype, MAX_MTU, 0, USBDEVFS_IOCTL_TIMEOUT);
			} else {
				TRACEL(LOG_ERROR, "Recovered record...\n");
				handle->usbll_handle = sniff_token.user_data;
			}
			/* update uid */
			novacom_usbll_setuid(handle->usbll_handle, uid);
			handle->rx_timeout = novacom_usbll_get_timeout(handle->usbll_handle);
			handle->tx_timeout = novacom_usbll_get_timeout(handle->usbll_handle);
			sniff = 0;
		}
		/* process */
		packet_type = PACKET_TYPE_NULL;
		if (rc > 0) {
			// process it
			packet_type = novacom_usbll_process_packet(handle->usbll_handle, buf, rc);
			if (packet_type == PACKET_TYPE_BADPACKET) {
				platform_time_t et;
				TRACEF("received bad packet\n");
				platform_get_time(&et);
				if (platform_delta_time_msecs(&st, &et) >= g_usbio_retry_timeout) {
					handle->shutdown = true;
					break;
				}
				if (g_usbio_retry_delay > 0) {
					if ((g_usbio_retry_timeout-time_used) >= g_usbio_retry_delay) {
						usleep(g_usbio_retry_delay * 1000);
						time_used += g_usbio_retry_delay;
					}
					else {
						usleep((g_usbio_retry_timeout - time_used) * 1000);
						time_used = g_usbio_retry_timeout;
					}
				}
				///handle->shutdown = true;
				///break;
			} else if(handle->tx_startup_wait) {
				platform_event_signal(&handle->tx_startup_event);
			}
		} else {
#if TRACE_ZERO_LEN_PACKETS
			log_printf(LOG_TRACE, "RX zero len\n");
#endif
		}
	}

	LTRACEF("shutting down handle %p\n", handle);

	/* wake up tx thread (if still waits for startup) */
	if(handle->tx_startup_wait) {
		LTRACEF("wake up tx thread\n");
		platform_event_signal(&handle->tx_startup_event);
	}

	/* wait for the tx thread to exit */
	LTRACEF("waiting on tx thread\n");
	platform_event_wait(&handle->tx_shutdown_event);

	/* RX thread is responsible for cleaning up */
	LTRACEF("cleaning up handle %p\n", handle);

	/* grab recovery token if available */
	if(handle->usbll_handle) {
		rc = -1;
		rec_token = platform_calloc(sizeof(transport_recovery_token_t));
		if(rec_token) {
			snprintf(rec_token->nduid, sizeof(rec_token->nduid), "%s", novacom_usbll_get_nduid(handle->usbll_handle));
			rc = novacom_usbll_get_recovery_token(handle->usbll_handle, rec_token);
			if(rc != -1) {
				rc = usbrecords_add(rec_token);
			} else {
				LTRACEF("unable to recovery token!!!\n");
			}
		}
		/* error: free memory, destroy device */
		if(rc == -1) { //we should never go here.
			novacom_usbll_destroy(handle->usbll_handle);
			platform_free(rec_token);
		}
	}

	novacom_usb_close(handle);
	platform_event_destroy(&handle->tx_startup_event);
	platform_event_destroy(&handle->tx_shutdown_event);
	platform_free(handle);
	platform_free(buf);

	return NULL;
}
Ejemplo n.º 19
0
int main(int argc, char *argv[])
{
	char *title;
	SDL_Window *window;
	Uint32 flags;
	int x, y, width, height, shutdown;
	SDL_Renderer *renderer;
	SDL_Event event;
	SDL_AudioDeviceID sdl_audio_dev;
	struct timespec start, last_print, now, elapsed;
	unsigned long total_elapsed_seconds;
	double fps;
	unsigned long int frame_count, frames_since_print;
	struct game_memory mem;
	struct pixel_buffer *virtual_win;
	struct pixel_buffer blit_buf;
	struct human_input input[2];
	struct human_input *tmp_input;
	struct human_input *new_input;
	struct human_input *old_input;
	struct sdl_texture_buffer texture_buf;
	struct sdl_event_context event_ctx;
	struct audio_ring_buffer audio_ring_buf;
	struct audio_buffer audio_buf;

	pixel_buffer_init(&blit_buf);

	texture_buf.texture = NULL;
	texture_buf.pixel_buf = &blit_buf;

	flags =
	    SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER |
	    SDL_INIT_HAPTIC;
	if (SDL_Init(flags) != 0) {
		return 1;
	}

	height = 480;
	width = 640;

	mem.is_initialized = 0;
	mem.fixed_memory_size = 4 * 1024 * 1024;
	mem.transient_memory_size = 1 * 1024 * 1024;
	mem.fixed_memory =
	    platform_alloc(mem.fixed_memory_size + mem.transient_memory_size);
	if (mem.fixed_memory == 0) {
		debug(0, "did not alloc game memory\n");
		return 1;
	}

	mem.transient_memory = mem.fixed_memory + mem.fixed_memory_size;

	init_game(&mem, HANDMAIDEN_AUDIO_DEFAULT_VOLUME,
		  HANDMAIDEN_AUDIO_START_VOLUME);

	virtual_win = NULL;
	update_pixel_buffer(&mem, &virtual_win);
	if (!virtual_win) {
		debug(0, "did not assign virtual_win\n");
	}

	sdl_init_joysticks(&event_ctx);

	title = (argc > 1) ? argv[1] : "Handmaiden Hero";
	x = SDL_WINDOWPOS_UNDEFINED;
	y = SDL_WINDOWPOS_UNDEFINED;
	flags = SDL_WINDOW_RESIZABLE;
	window = SDL_CreateWindow(title, x, y, width, height, flags);
	if (!window) {
		debug(0, "Could not SDL_CreateWindow\n");
		return 2;
	}

	renderer = SDL_CreateRenderer(window, FIRST_SUPPORTING, NONE);
	if (!renderer) {
		return 3;
	}

	sdl_resize_texture_buf(window, renderer, &texture_buf);

	if (init_audio_ring_buffer(&audio_ring_buf)) {
		sdl_audio_dev = sdl_init_audio(&audio_ring_buf);
	} else {
		sdl_audio_dev = 0;
	}
	if (sdl_audio_dev && audio_ring_buf.buf_len) {
		audio_buf.stream_pos = 0;
		audio_buf.num_samples = 0;
		audio_buf.samples =
		    (int *)platform_alloc(audio_ring_buf.buf_len);
		if (!audio_buf.samples) {
			debug(0, "could not allocate audio_buf.samples[%u]\n",
			      audio_ring_buf.buf_len);
			audio_buf.buf_len = 0;
		} else {
			audio_buf.buf_len = audio_ring_buf.buf_len;
		}
	}

	/* start audio playing by setting "pause" to zero */
	if (sdl_audio_dev && audio_buf.samples) {
		SDL_PauseAudioDevice(sdl_audio_dev, 0);
	}

	event_ctx.event = &event;
	event_ctx.texture_buf = &texture_buf;
	event_ctx.renderer = renderer;
	event_ctx.window = window;
	event_ctx.win_id = SDL_GetWindowID(window);

	clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
	last_print.tv_sec = start.tv_sec;
	last_print.tv_nsec = start.tv_nsec;
	total_elapsed_seconds = 0;
	frames_since_print = 0;
	frame_count = 0;
	shutdown = 0;
	old_input = &input[0];
	new_input = &input[1];
	init_input(old_input);
	init_input(new_input);
	while (!shutdown) {
		tmp_input = new_input;
		new_input = old_input;
		old_input = tmp_input;
		init_input(new_input);

		while (SDL_PollEvent(&event)) {
			if ((shutdown = process_event(&event_ctx, new_input))) {
				break;
			}
		}
		process_joysticks(&event_ctx, old_input, new_input);

		if (shutdown || (shutdown = process_input(&mem, new_input))) {
			break;
		}
		update_pixel_buffer(&mem, &virtual_win);
		stretch_buffer(virtual_win, &blit_buf);
		sdl_blit_texture(renderer, &texture_buf);
		if (sdl_audio_dev && audio_buf.samples) {
			if ((audio_ring_buf.write_cursor -
			     audio_ring_buf.play_cursor) <
			    audio_ring_buf.buf_len) {
				SDL_LockAudio();
				if (fill_ring_buf
				    (&audio_ring_buf, &mem, &audio_buf) < 0) {
					shutdown = 1;
				}
				SDL_UnlockAudio();
			}
		}
		frame_count++;
		frames_since_print++;

		clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now);
		diff_timespecs(last_print, now, &elapsed);
		if (((elapsed.tv_sec * 1000000000) + elapsed.tv_nsec) >
		    100000000) {
			fps =
			    ((double)frames_since_print) /
			    (((double)elapsed.tv_sec) * 1000000000.0 +
			     ((double)elapsed.tv_nsec) / 1000000000.0);
			frames_since_print = 0;
			last_print.tv_sec = now.tv_sec;
			last_print.tv_nsec = now.tv_nsec;
			diff_timespecs(start, now, &elapsed);
			total_elapsed_seconds = elapsed.tv_sec + 1;
			if (FPS_PRINTER) {
				debug(0, "fps: %.02f (avg fps: %.f) %u, %u%s",
				      fps,
				      (double)frame_count /
				      (double)total_elapsed_seconds,
				      audio_ring_buf.play_cursor,
				      audio_ring_buf.write_cursor,
				      ERIC_DEBUG ? "\n" : "\r");
			}
		}
	}
	debug(0, "\n");

	if (sdl_audio_dev) {
		SDL_CloseAudioDevice(sdl_audio_dev);
	}
	close_audio_debug_logging(&audio_ring_buf);
	sdl_close_joysticks(&event_ctx);

	/* we probably do not need to do these next steps */
	if (HANDMAIDEN_TRY_TO_MAKE_VALGRIND_HAPPY) {
		/* first cleanup SDL stuff */
		if (texture_buf.texture) {
			SDL_DestroyTexture(texture_buf.texture);
		}
		SDL_DestroyRenderer(renderer);
		SDL_DestroyWindow(window);
		SDL_Quit();

		/* then collect our own garbage */
		if (blit_buf.pixels) {
			platform_free(blit_buf.pixels,
				      blit_buf.pixels_bytes_len);
		}
		if (audio_ring_buf.buf) {
			platform_free(audio_ring_buf.buf,
				      audio_ring_buf.buf_len);
		}
		if (audio_buf.samples) {
			platform_free(audio_buf.samples, audio_buf.buf_len);
		}
		if (mem.fixed_memory) {
			platform_free(mem.fixed_memory,
				      mem.fixed_memory_size +
				      mem.transient_memory_size);
		}
	}

	return 0;
}