/*
 *
 *  Copyright (C) 2010 Mindspeed Technologies, Inc.
 *
 * 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
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>

#include "libcmm.h"
#include "cmm.h"

#define MAX_PATH 32

struct cmm_handle
{
	long	uniqueid;
	int	tmp_fd;
	int 	queue_id_rx;
	int 	queue_id_tx;
	char	path[MAX_PATH];
};

int getpgid(pid_t _pid); /* XXX: uclibs doesn't declare this function is unistd.h as it has to, 
			  * therefore declare it by ourselves
			  */

static int get_daemon_pid()
{
        FILE*fd;
        char buf[10];

        fd = fopen(CMM_PID_FILE_PATH, "r");
        if(fd > 0) {
		// Read the pid written in the pid file
		fgets(buf, 10, fd);
		fclose(fd);

		// Check the daemon is really running
		if (getpgid(atoi(buf)) != -1)
			return atoi(buf);
	}

	// No daemon is running
	return 0;
}

static int gen_uniqueid(cmm_handle_t *handle)
{
	unsigned i;
        srandom(time(NULL));
	
	for (i = 0; i < 10; i++) {
		handle->uniqueid = random();
		snprintf(handle->path, sizeof(handle->path), "%s.%lu", "/tmp/cmm", handle->uniqueid);
		handle->tmp_fd = open(handle->path, O_CREAT | O_EXCL);
		if (handle->tmp_fd == -1)
			continue;
		else
			return 0;
	}

        return -1;
}

cmm_handle_t *cmm_open(void)
{
	key_t key;
	int pid = get_daemon_pid();
	cmm_handle_t *handle;

	if (!pid) {
                fprintf(stderr, "Daemon is not running\n");
                return NULL;
        }

	handle = malloc(sizeof(cmm_handle_t));
	if (!handle) {
		fprintf(stderr, "Error allocating CMM handle\n");
		return NULL;
	}

	memset(handle, 0, sizeof(cmm_handle_t));
	
	if (gen_uniqueid(handle) != 0) {
		fprintf(stderr, "Error getting uniqueid\n");
		goto ERR_UNIQUEID;
	}

        pid = ((pid & 0xff) ^ ((pid >> 8) & 0xff)) | 1;
        key = ftok("/tmp", pid);
        if (key == (key_t)-1) {
                fprintf(stderr, "ftok(%d) failed, %s\n", pid, strerror(errno));
                goto ERR_QUEUE;
        }

        handle->queue_id_rx = msgget(key, 0);
        if (handle->queue_id_rx < 0) {
                fprintf(stderr, "rx msgget() failed, %s\n", strerror(errno));
                goto ERR_QUEUE;
        }

	key = ftok("/tmp", pid ^ 0xff);
        if (key == (key_t)-1) {
                fprintf(stderr, "ftok(%d) failed, %s\n", pid, strerror(errno));
                goto ERR_QUEUE;
        }

        handle->queue_id_tx = msgget(key, 0);
        if (handle->queue_id_tx < 0) {
                fprintf(stderr, "tx msgget() failed, %s\n", strerror(errno));
                goto ERR_QUEUE;
        }

	return handle;

ERR_QUEUE:
	close(handle->tmp_fd);
	unlink(handle->path);
ERR_UNIQUEID:
	free(handle);

	return NULL;
}

void cmm_close(cmm_handle_t* handle)
{
	close(handle->tmp_fd);
	unlink(handle->path);
	free(handle);
}

int cmm_send(cmm_handle_t *handle, cmm_command_t* cmd, int nonblocking)
{
	cmd->msg_type = handle->uniqueid;

        return msgsnd(handle->queue_id_tx, 
		      cmd, 
		      sizeof(cmm_command_t) - sizeof(cmd->buf) + cmd->length, 
		      nonblocking ? IPC_NOWAIT : 0);
}

int cmm_recv(cmm_handle_t *handle, cmm_response_t* res, int nonblocking)
{
        int len = msgrcv(handle->queue_id_rx, 
			 res, 
			 sizeof(cmm_response_t), 
			 handle->uniqueid, 
			 nonblocking ? IPC_NOWAIT : 0);
	if (len < 0)
                return len;

	if (res->daemon_errno) {
		errno = res->daemon_errno;
		return -1;
	}

	return len;
}

