%{
/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2000-2001  Qualcomm Incorporated
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2002-2007  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include <sys/socket.h>
#include <asm/types.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

#include "hcid.h"
#include "kword.h"

int cfg_error(const char *fmt, ...);

int yyparse(void);
int yylex(void);
int yyerror(char *s); 

void yylex_destroy(void);

%}

%union {
	char *str;
	long  num;
}

%token K_OPTIONS K_DEVICE
%token K_AUTOINIT K_SECURITY K_PAIRING K_OFFMODE
%token K_PTYPE K_NAME K_CLASS K_VOICE K_PAGETO K_LM K_LP K_ISCAN K_PSCAN K_DISCOVTO
%token K_PASSKEY
%token K_YES K_NO

%token <str> WORD PATH STRING LIST HCI BDADDR
%token <num> NUM

%type  <num> bool pkt_type link_mode link_policy sec_mode pair_mode off_mode
%type  <str> dev_name hci bdaddr

%%
config: statement | config statement;
statement: 
  K_OPTIONS hcid_options

  | device device_options

  | WORD	{
			cfg_error("Invalid statement '%s'", $1);
		}

  | error	{
			yyclearin; yyerrok;
		}
  ;

device:
  K_DEVICE		{
				parser_device = &default_device;
			}

  | K_DEVICE hci	{
				parser_device = alloc_device_opts($2);
			}

  | K_DEVICE bdaddr	{
				parser_device = alloc_device_opts($2);
			}
  ;

hcid_options: '{' hcid_opts '}';
hcid_opts: | hcid_opt ';' | error ';' | hcid_opts hcid_opt ';';
hcid_opt: 
  K_AUTOINIT bool	{
				hcid.auto_init = $2;
			}

  | K_SECURITY sec_mode	{
				hcid.security = $2;
			}

  | K_PAIRING pair_mode	{
				hcid.pairing = $2;
			}

  | K_OFFMODE off_mode	{
				hcid.offmode = $2;
			}

  | K_PASSKEY STRING	{
  				strncpy((char *) hcid.pin_code, $2, 16);
				hcid.pin_len = strlen($2);
				if (hcid.pin_len > 16)
					hcid.pin_len = 16;
			}


  | WORD		{
				cfg_error("Unknown option '%s'", $1);
			}
  ;

sec_mode:
  WORD		{
			int opt = find_keyword(sec_param, $1);
			if (opt < 0) {
				cfg_error("Unknown security mode '%s'", $1);
				$$ = 0;
			} else
				$$ = opt;
		}

  | K_NO	{
			$$ = HCID_SEC_NONE;
		}
  ;

pair_mode:
  WORD		{
			int opt = find_keyword(pair_param, $1);
			if (opt < 0) {
				cfg_error("Unknown pairing mode '%s'", $1);
				$$ = 0;
			} else
				$$ = opt;
		}
  ;

off_mode:
  WORD		{
			int opt = find_keyword(off_param, $1);
			if (opt < 0) {
				cfg_error("Unknown off mode '%s'", $1);
				$$ = 0;
			} else
				$$ = opt;
		}
  ;


device_options: '{' device_opts '}';
device_opts: | device_opt ';' | error ';' | device_opts device_opt ';';
device_opt:
  K_PTYPE pkt_type	{
				parser_device->flags |= (1 << HCID_SET_PTYPE);
				parser_device->pkt_type = $2;
			}

  | K_LM link_mode	{
				parser_device->flags |= (1 << HCID_SET_LM);
				parser_device->link_mode = $2;
			}

  | K_LP link_policy	{
				parser_device->flags |= (1 << HCID_SET_LP);
				parser_device->link_policy = $2;
			}

  | K_NAME dev_name	{
				if (parser_device->name)
					free(parser_device->name);
				parser_device->flags |= (1 << HCID_SET_NAME);
				parser_device->name = strdup($2);
			}

  | K_CLASS NUM		{
				parser_device->flags |= (1 << HCID_SET_CLASS);
				parser_device->class = $2;
			}

  | K_VOICE NUM		{
				parser_device->flags |= (1 << HCID_SET_VOICE);
				parser_device->voice = $2;
			}

  | K_PAGETO NUM	{
				parser_device->flags |= (1 << HCID_SET_PAGETO);
				parser_device->pageto = $2;
			}

  | K_DISCOVTO NUM	{
				parser_device->flags |= (1 << HCID_SET_DISCOVTO);
				parser_device->discovto = $2;
			}

  | K_ISCAN bool	{
				if ($2)
					parser_device->scan |=  SCAN_INQUIRY;
				else
					parser_device->scan &= ~SCAN_INQUIRY;
			}

  | K_PSCAN bool	{
				if ($2)
					parser_device->scan |=  SCAN_PAGE;
				else
					parser_device->scan &= ~SCAN_PAGE;
			}

  | WORD		{
				cfg_error("Unknown option '%s'",$1);
				YYABORT;
			}
  ;

dev_name:
  WORD		{
			$$ = $1;
		}

  |  STRING	{
			$$ = $1;
		}
  ;

hci:
  HCI		{
			$$ = $1;
		}
  ;

bdaddr:
  BDADDR	{
			$$ = $1;
		}
  ;

pkt_type:
  WORD		{
			unsigned int opt;
			if (!hci_strtoptype($1, &opt))
				cfg_error("Unknown packet type '%s'", $1);
			$$ = opt;
		}

  | LIST	{
			unsigned int opt;
			if (!hci_strtoptype($1, &opt))
				cfg_error("Unknown packet type '%s'", $1);
			$$ = opt;
		}
  ;

link_mode:
  WORD		{
			unsigned int opt;
			if (!hci_strtolm($1, &opt))
				cfg_error("Unknown link mode '%s'", $1);
			$$ = opt;
		}

  | LIST	{
			unsigned int opt;
			if (!hci_strtolm($1, &opt))
				cfg_error("Unknown link mode '%s'", $1);
			$$ = opt;
		}
  ;

link_policy:
  WORD		{
			unsigned int opt;
			if (!hci_strtolp($1, &opt))
				cfg_error("Unknown link policy '%s'", $1);
			$$ = opt;
		}

  | LIST	{
			unsigned int opt;
			if (!hci_strtolp($1, &opt))
				cfg_error("Unknown link policy '%s'", $1);
			$$ = opt;
		}
  ;

bool: K_YES { $$ = 1; } | K_NO  { $$ = 0; };

%%

int yyerror(char *s) 
{
	error("%s line %d", s, lineno);
	return 0;
}

int cfg_error(const char *fmt, ...)
{
	char buf[255];
	va_list ap;

	va_start(ap, fmt);
	vsnprintf(buf,sizeof(buf),fmt,ap);
	va_end(ap);

	yyerror(buf);
	return 0;
}

/* 
 * Read config file. 
 */ 
int read_config(char *file) 
{
	extern FILE *yyin;

	if (!(yyin = fopen(file, "r"))) {
		error("Can't open config file %s", file);
		return -1;
	}

	lineno = 1;
	yyparse();

	fclose(yyin);

	return 0;
}
