/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "stpti.h"

const char *stioctl_filename = "/dev/stapi/stpti4_ioctl";

int open_stapi(void) {
	int stpti4fd = open(stioctl_filename, O_RDWR);

	if(stpti4fd < 0) {
		printf("Failed to open %s\n", stioctl_filename);
		exit(EXIT_FAILURE);
	}

	return stpti4fd;
}

int allocate_buffer(int stpti4fd, int st_handle, void **buffer, int size) {
	allocbuf_t buf;

	buf.handle = st_handle;
	buf.size1 = size;
	buf.size2 = 5;
	
	if(ioctl(stpti4fd, IOCTL_ALLOCBUF, &buf) != 0 ||
	   buf.errorcode != 0) {
		printf("Failed to allocate %x buffer, err = %x\n", st_handle, buf.errorcode);
		return -1;
	}
	
	*buffer = buf.buffer;

	return 0;
}

int free_buffer(int stpti4fd, void *buffer) {
	freebuf_t fb;
	fb.buffer = buffer;

	if(ioctl(stpti4fd, IOCTL_FREEBUF, &fb) != 0 ||
	   fb.errorcode != 0) {
		printf("Failed freeing buffer, err = %d\n", fb.errorcode);
		return -1;
	}

	return 0;
}

int set_buffer(int stpti4fd, int handle, void *buffer) {
	setbuffer_t setbuf;

	setbuf.handle = handle;
	setbuf.buffer = buffer;
	setbuf.magic = 1;
	setbuf.errorcode = 0;

	if(ioctl(stpti4fd, IOCTL_SETBUFFER, &setbuf) != 0 ||
	   setbuf.errorcode != 0) {
		printf("Failed setting %x buffer, err = 0x%x\n", handle, setbuf.errorcode);
		return -1;
	}

	return 0;
}

int unset_buffer(int stpti4fd, int handle) {
	unsetbuffer_t unsetbuf;

	unsetbuf.handle = handle;

	if(ioctl(stpti4fd, IOCTL_UNSETBUFFER, &unsetbuf) != 0 ||
	   unsetbuf.errorcode != 0) {
		printf("Failed unsetting %x buffer, err = %d\n", handle, unsetbuf.errorcode);
		return -1;
	}

	return 0;
}

void get_slot_handles(st_slothandles_t *st_slots) {
	FILE *pti2file;
	char *buffer=NULL;
	int len;

	/* open pti2file */
	if ((pti2file=fopen("/tmp/pti2.tmp","r")) == NULL) {
		perror("unable to open /tmp/pti2.tmp");
		exit(EXIT_FAILURE);
	}

	/* find slot handles */
	while (getline(&buffer,&len,pti2file) != EOF) {
		if (strstr(buffer,"HANDLE") != NULL) {
			sscanf(buffer, "HANDLE 0x%x", &st_slots->sthandle);
		} else if (strstr(buffer,"VID") != NULL) {
			sscanf(buffer, "VID 0x%x 0x%x", &st_slots->vpid, &st_slots->vidhandle);
		} else if (strstr(buffer,"AUD") != NULL) {
			sscanf(buffer, "AUD 0x%x 0x%x", &st_slots->apid, &st_slots->audhandle);
		} else if (strstr(buffer,"PCR") != NULL) {
			sscanf(buffer, "PCR 0x%x 0x%x", &st_slots->pcrpid, &st_slots->pcrhandle);
		} else if (strstr(buffer,"PMT") != NULL) {
			sscanf(buffer, "PMT 0x%*x 0x%x", &st_slots->pmthandle);
		}
		buffer=NULL;
	}

	/*
	printf("st_handle: 0x%x\n", st_slots->sthandle);
	printf("vslot: 0x%x\n", st_slots->vidhandle);
	printf("aslot: 0x%x\n", st_slots->audhandle);
	printf("pmtslot: 0x%x\n", st_slots->pmthandle);
    */

	/* close pti2file */
	if ((fclose(pti2file)) != 0) {
		perror("unable to close /tmp/pti2.tmp");
		exit(EXIT_FAILURE);
	}
}

