/*
 *      test.c from Access Point SNMP Utils for Linux
 *
 * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 from
 * June 1991 as published by the Free Software Foundation.
 *
 * 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 <math.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "ap-utils.h"

#define TEST_MODE _("[T] Test mode: ")
#define ANTENNA _("[A] Antenna: ")
#define SIGLEVEL _("[S] Signal level: ")
#define RATE _("[R] Rate: ")
#define FILER _("[F] TxFiler: ")
#define COMMAND _("[O] Command: ")
#define __HELP _("T - Test mode On/Off; CASRFO - set options; Q - quit to menu")

extern WINDOW *main_sub;
extern short ap_type;
extern char *channels[];

void test()
{
    struct TestModeCommandStruct_ATMEL410 {
	unsigned char Channel;
	unsigned char Antenna;
	unsigned char RegCR31;
	unsigned char Rate;
	unsigned char TxFiler;	//US 01 - JPN 02
	unsigned char Command;	//CMD_CONTINUOUS_TX 0x01, CMD_CONTINUOUS_RX 0x02, CMD_CARRIER_ACCURACY 0x03, CMD_IDLE 0x04
	unsigned char Res1;
	unsigned char Res2;
    } testmode;

    struct TestModeStatistics {
	unsigned long SuccessFrames;
	unsigned long FailedFrames;
    } *teststat = NULL;

    char TestModeOnOff[] =
	{ 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x08, 0x01,
	0x00
    };
    char TestModeCommandStruct[] =
	{ 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x08, 0x02,
	0x00
    };
    char TestModeStatistics[] =
	{ 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x08, 0x09,
	0x00
    };

    char message[1024], *antenna[2] =
	{ _("Left"), _("Right") }, *filer[2] = {
    "EN", "US"}, *rates[4] = {
    "1", "2", "5.5", "11"};
    char teston = 2, *commands[4] =
	{ "CONTINUOUS_TX", "CONTINUOUS_RX", "CARRIER_ACCURACY", "IDLE" };
    varbind varbinds[5];

    if (ap_type == ATMEL12350) {
#if 1 /* Temporary kludge */
	mvwaddstr(main_sub, 1, 0, _("Devices with ATMEL12350 MIB not yet supported."));
	wrefresh(main_sub);
	goto exit;
#endif
	TestModeOnOff[5] = 0xE0;
	TestModeOnOff[6] = 0x3E;
	TestModeCommandStruct[5] = 0xE0;
	TestModeCommandStruct[6] = 0x3E;
	TestModeStatistics[5] = 0xE0;
	TestModeStatistics[6] = 0x3E;
    }

    print_top(NULL, _("Test mode"));
    mvwaddstr(main_sub, 3, 6,
	      _
	      ("Using the \"Test mode\" may cause loss of your current"));
    mvwaddstr(main_sub, 4, 6, _("configuration."));
    mvwaddstr(main_sub, 6, 20, _("Do you want to continue? "));
    wrefresh(main_sub);

    if (help_ysn())
	goto quit;

    print_help(__HELP);

    sprintf(message, "%s%s", TEST_MODE, OFF);
    mvwaddstr(main_sub, 0, 0, message);

    mvwaddstr(main_sub, 2, 1, _("Options:"));
    testmode.Channel = 1;
    sprintf(message, "%s%02u (%u MHz)", CHANNEL, testmode.Channel,
	    2407 + 5 * testmode.Channel);
    mvwaddstr(main_sub, 3, 0, message);

    testmode.Antenna = 1;
    sprintf(message, "%s%s", ANTENNA, antenna[testmode.Antenna - 1]);
    mvwaddstr(main_sub, 4, 0, message);

    testmode.RegCR31 = 128;
    sprintf(message, "%s%u", SIGLEVEL, testmode.RegCR31);
    mvwaddstr(main_sub, 5, 0, message);

    testmode.Rate = 2;
    sprintf(message, "%s%.1f Mbit/s", RATE, (float) testmode.Rate / 2);
    mvwaddstr(main_sub, 6, 0, message);

    testmode.TxFiler = 1;
    sprintf(message, "%s%s", FILER, filer[testmode.TxFiler - 1]);
    mvwaddstr(main_sub, 7, 0, message);

    testmode.Command = 1;
    sprintf(message, "%s%s", COMMAND, commands[testmode.Command - 1]);
    mvwaddstr(main_sub, 8, 0, message);

    mvwaddstr(main_sub, 10, 1, _("Statistics:"));
    mvwaddstr(main_sub, 11, 0, _("Success Frames: 0 Failed Frames: 0"));

    wrefresh(main_sub);
    noecho();
    while (1) {
	switch (getch()) {
	case 'Q':
	case 'q':
	    if (teston == 1) {
		teston = 2;
		varbinds[0].oid = TestModeOnOff;
		varbinds[0].len_oid = sizeof(TestModeOnOff);
		varbinds[0].value = &teston;
		varbinds[0].len_val = 1;
		varbinds[0].type = INT_VALUE;
		if (snmp(varbinds, 1, SET) <= 0) {
		    print_helperr(ERR_RET);
		    goto exit;
		}
	    }
	    goto quit;
	case 'T':
	case 't':
	    teston = on_off(0, 1 + strlen(TEST_MODE));

	    if (teston == 1) {
		clear_main_new(0, 1);
		print_menusel(0, 0, TEST_MODE, ON);
		varbinds[0].oid = TestModeOnOff;
		varbinds[0].len_oid = sizeof(TestModeOnOff);
		varbinds[0].value = &teston;
		varbinds[0].len_val = 1;
		varbinds[0].type = INT_VALUE;
		varbinds[1].oid = TestModeCommandStruct;
		varbinds[1].len_oid = sizeof(TestModeCommandStruct);
		varbinds[1].len_val = sizeof(testmode);
		varbinds[1].value = (char *) &testmode;
		varbinds[1].type = STRING_VALUE;
		if (snmp(varbinds, 2, SET) <= 0) {
		    print_helperr(ERR_RET);
		    goto exit;
		}
	    } else {
		varbinds[0].oid = TestModeStatistics;
		varbinds[0].len_oid = sizeof(TestModeStatistics);
		varbinds[0].value = TestModeStatistics;
		varbinds[0].len_val = 0;
		varbinds[0].type = NULL_VALUE;

		if (snmp(varbinds, 1, GET) <= 0) {
		    print_helperr(ERR_RET);
		    getch();
		    print_help(__HELP);
		} else {
		    teststat =
			(struct TestModeStatistics *) malloc(varbinds[0].
							     len_val);
		    memcpy(teststat, varbinds[0].value,
			   sizeof(struct TestModeStatistics));
		    clear_main_new(11, 12);
		    sprintf(message,
			    _("Success Frames: %lu Failed Frames: %lu"),
			    swap4(teststat->SuccessFrames),
			    swap4(teststat->FailedFrames));
		    mvwaddstr(main_sub, 11, 0, message);
		    free(teststat);
		}
		clear_main_new(0, 1);
		sprintf(message, "%s%s", TEST_MODE, OFF);
		mvwaddstr(main_sub, 0, 0, message);

		varbinds[0].oid = TestModeOnOff;
		varbinds[0].len_oid = sizeof(TestModeOnOff);
		varbinds[0].value = &teston;
		varbinds[0].len_val = 1;
		varbinds[0].type = INT_VALUE;

		if (snmp(varbinds, 1, SET) <= 0) {
		    print_helperr(ERR_RET);
		    goto exit;
		}
		wrefresh(main_sub);
	    }
	    continue;
	case 'C':
	case 'c':
	    testmode.Channel = menu_choose(3, strlen(CHANNEL), channels,
		14) + 1;
	    clear_main_new(3, 4);
	    sprintf(message, "%02u (%u MHz)", testmode.Channel,
		2407 + 5 * testmode.Channel);
	    print_menusel(3, 0, CHANNEL, message);
	    continue;
	case 'R':
	case 'r':
	    switch (menu_choose(6, strlen(RATE), rates, 4)) {
	    case 0:
		testmode.Rate = 2;
		break;
	    case 1:
		testmode.Rate = 4;
		break;
	    case 2:
		testmode.Rate = 11;
		break;
	    case 3:
		testmode.Rate = 22;
	    }
	    clear_main_new(6, 7);
	    sprintf(message, "%.1f Mbit/s", (float) testmode.Rate / 2);
	    print_menusel(6, 0, RATE, message);
	    continue;
	case 'A':
	case 'a':
	    testmode.Antenna = menu_choose(4, strlen(ANTENNA), antenna, 2) + 1;
	    clear_main_new(4, 5);
	    print_menusel(4, 0, ANTENNA, antenna[testmode.Antenna - 1]);
	    continue;
	case 'O':
	case 'o':
	    testmode.Command = menu_choose(8, strlen(COMMAND), commands, 4) + 1;
	    clear_main_new(8, 9);
	    print_menusel(8, 0, COMMAND, commands[testmode.Command - 1]);
	    continue;
	case 'F':
	case 'f':
	    testmode.TxFiler = menu_choose(7, strlen(FILER), filer, 2) + 1;
	    clear_main_new(7, 8);
	    print_menusel(7, 0, FILER, filer[testmode.TxFiler - 1]);
	    continue;
	case 'S':
	case 's':
//          make_field(5, strlen(SIGLEVEL), 4);
	    get_value(message, 5, strlen(SIGLEVEL), 4, INT_STRING, 0, 255,
		__HELP);
	    print_menusel(5, 0, SIGLEVEL, message);
	    testmode.RegCR31 = atoi(message) & 0xFF;
	    continue;
	default:
	    continue;
	}
	break;
    }

    print_help(ANY_KEY);
  exit:
    getch();
  quit:
    print_top(NULL, NULL);
    clear_main(0);
}
