/* 
 * bt_proc.c -- Implementation of /proc files in bluetooth driver
 *
 * Copyright (C) 2000  Axis Communications AB
 *
 * Mattias Agren <mattias.agren@axis.com>
 *
 * 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.
 *
 * $Id: bt_proc.c,v 1.10 2000/10/27 15:11:52 mattias Exp $
 *
 */

#define __NO_VERSION__ /* don't define kernel_version in module.h */


#ifdef __KERNEL__
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/malloc.h>
#include <linux/fs.h>
#include <linux/locks.h>
#include <linux/sched.h>
#include <linux/ioctl.h>
#include <linux/stat.h>
#include <asm/byteorder.h>
#include <linux/proc_fs.h>

#include <linux/bluetooth/bt_proc.h>
#include <linux/bluetooth/bluetooth.h>
#include <linux/bluetooth/btcommon.h>
#include <linux/bluetooth/hci.h>
#include <linux/bluetooth/l2cap.h>
#include <linux/bluetooth/rfcomm.h>

#else

#include "include/btmem.h"
#include "include/hci.h"
#include "include/l2cap.h"
#include "include/sdp.h"
#include "include/rfcomm.h"
#include "include/btdebug.h"
#include "include/btcommon.h"
#endif

extern s32 hci_send_data(bt_tx_buf *tx_buf);
extern void btmem_get_status(bt_tx_buf *current_buf);

#ifndef __KERNEL__
extern bt_stat_struct bt_stat;
extern u32 bt_initiated(void);
#endif

#ifdef __KERNEL__
static s32 bt_read_status(char *buf, char **start, off_t offset, 
			  int len, int unused)
#else

extern bt_stat_struct bt_stat;
extern u32 bt_initiated(void);
int bt_read_status(char *buf, int len)
#endif
{
	len = 0;
	len += sprintf(buf + len, "[LOCAL INFO]\n");
	len += sprintf(buf + len, "stack_initiated  : ");
	
	if (!bt_initiated()) {
		len += sprintf(buf + len, "FALSE\n");
		return len;
	} else {
		len += sprintf(buf + len, "TRUE\n");
	}

	len += sprintf(buf + len, "bytes_received   : %9d\n",
		       bt_stat.bytes_received);
	len += sprintf(buf + len, "bytes_sent       : %9d\n", bt_stat.bytes_sent);
	len += sprintf(buf + len, "local_bd_address : ");
	len += hci_sprint_local_bd(buf + len);
	len += sprintf(buf + len, "\n");
	
	len += sprintf(buf + len, "\n[REMOTE INFO]\n");
	len += hci_sprint_remote_info(buf + len);

	return len;
}
 

/* Read internal variables used for debugging */

#ifdef __KERNEL__
s32 bt_read_internal(char *buf, char **start, off_t offset, 
		     int len, int unused)
#else
int bt_read_internal(char *buf, int len)
#endif
{
	len = 0;
        len += sprintf(buf + len, "\n[Bluetooth Status]\n");
        len += sprintf(buf + len, "-----------------------------------------\n")
;

        if (!bt_initiated()) {
                len += sprintf(buf + len, "\nStack not initiated\n\n");
                return len;
        }

        len += sprintf(buf + len, "bytes received : %9d\n", 
                     bt_stat.bytes_received);
        len += sprintf(buf + len, "bytes sent     : %9d\n", 
                     bt_stat.bytes_sent);

#ifdef __KERNEL__
	len += bt_sprintf_status(buf + len);
#endif
        len += rfcomm_sprint_status(buf + len);
        len += l2cap_sprint_status(buf + len);
	len += sprintf(buf + len, "\n[HCI]\n");
        len += hci_sprint_remote_info(buf + len);

        len += sprintf(buf + len, "\n---------------------------------------\n");
        return len;
}


/*
 * General test function
 */

#ifdef __KERNEL__
static s32 bt_doit(char *buf, char **start, off_t offset, int len, int unused)
#else
int bt_doit(char *buf, int len)
#endif
{
	len = 0;

	/*
	 * trigger something...
	 */
	
	len += sprintf(buf + len, "\n did it !\n");
	
	return len;
}


#ifdef __KERNEL__
struct proc_dir_entry bt_status = {
	0, /* dynamic */
	9, "bt_status", /* namelen and name*/
	S_IFREG | S_IRUGO, /* mode */
	1, 0, 0, /* nlinks, owner, group */
	0, /* size (unused) */
	NULL, /* operations, use default */
	&bt_read_status,
};


struct proc_dir_entry bt_internal_info = {
	0, /* dynamic */
	11, "bt_internal", /* namelen and name*/
	S_IFREG | S_IRUGO, /* mode */
	1, 0, 0, /* nlinks, owner, group */
	0, /* size (unused) */
	NULL, /* operations, use default */
	&bt_read_internal,
};


struct proc_dir_entry bt_proc_doit = {                    
	0, /* dynamic */
	7, "bt_doit", /* namelen and name*/
	S_IFREG | S_IRUGO, /* mode */
	1, 0, 0, /* nlinks, owner, group */
	0, /* size (unused) */
	NULL, /* operations, use default */
	&bt_doit,
};

#endif
