/*
 *
 *     Module Name: root.c
 *	       Version: 1.00
 *   Original Date: 08/23/99	
 *	        Author: Charles Gordon
 *	      Language: Ansi C
 * Compile Options:
 * Compile defines:
 *	     Libraries:
 *    Link Options:
 *
 *    Entry Points: applicationStart(), applicationTcpDown()
 *
 *  Copyrighted (c) by NETsilicon, Inc.  All Rights Reserved.
 *
 * Description.
 * =======================================================================
 *  applicationStart() is the entry point for user applications.  This
 *  This function will be called after the kernel has started and the
 *  TCP/IP stack has loaded.  applicationTcpDown() is called periodically
 *  after the kernel has started while the system is waiting for the
 *  TCP/IP stack to start.  
 *
 *
 *
 *
 * Edit Date/Ver   Edit Description
 * ==============  =======================================================
 *
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <tx_api.h>
#include <sysAccess.h>

#include <fs_api.h>
#include <nasntp.h>
#include <http_awsapi.h>
#include "fileinit.h"
#include "bsp_api.h"
#include "appconf.h"
#include "ssl.h"
#include "server.h"     /*  For username/password */

/*
 * Set this to 1 to run the system POST tests during startup.
 */
const int APP_POST = 0;
 
 
/*
 * Set this to 1 to run the manufacturing burn in tests.
 */
int APP_BURN_IN_TEST = 0; 

static int create_filesystem_volume(void)
{
    int             rc = NAFS_MALLOC_FAILED;
	char		    *volume0_area = NULL;
	char		    *volume1_area = NULL;

    if (NABspFilesystemForCLib == 0)
    {
        volume0_area = (char *)malloc(FS_VOLUME1_SIZE);
        if (volume0_area == NULL) 
        {
            printf ("Unable to allocate memory for file system.\n");
            goto _ret;
        }

        volume1_area = (char *)malloc(FS_VOLUME1_SIZE);
        if (volume1_area == NULL) 
        {
            printf ("Unable to allocate memory for file system.\n");
            free(volume0_area);
            goto _ret;
        }
    }
    rc = FileSystem_CreateRamVolume (FS_VOLUME1, volume0_area, FS_VOLUME1_SIZE);
    if (rc == NAFS_SUCCESS)
    {
        rc = FileSystem_CreateRamVolume (FS_VOLUME2, volume1_area, FS_VOLUME2_SIZE);
        if (rc != NAFS_SUCCESS) 
            free(volume1_area);
        
    }
    else
    {
        free(volume0_area);
        free(volume1_area);
    }
_ret: 
    return rc;
}
/*
 *
 *  Function: void applicationTcpDown (void)
 *
 *  Description:
 *
 *      This routine will be called by the NET+OS root thread once every 
 *      clock tick while it is waiting for the TCP/IP stack to come up.  
 *      This function can increment a counter everytime it's called to 
 *      keep track of how long we've been waiting for the stack to start.
 *      If we've been waiting too long, then this function can do something
 *      to handle the error.  
 *
 *      This function will not be called once the stack has started.
 *
 *  Parameters:
 *
 *      none
 *
 *  Return Values:
 *
 *      none
 *
 */

void applicationTcpDown (void)

{
    static int ticksPassed = 0;

    ticksPassed++;
/*
 * Code to handle error condition if the stack doesn't come up goes here.
 */
}




/*
 *
 *  Function: void applicationStart (void)
 *
 *  Description:
 *
 *      This routine is responsible for starting the user application.  It should 
 *      create any threads or other resources the application needs.
 *
 *      ThreadX, the NET+OS device drivers, and the TCP/IP stack will be running
 *      when this function is called.
 *
 *  Parameters:
 *
 *      none
 *
 *  Return Values:
 *
 *      none
 *
 */

void applicationStart (void)
{

#define GROUP1_USERNAME			"dir0"
#define GROUP1_PASSWORD			"dir0"
#define GROUP2_USERNAME			"dir1"
#define GROUP2_PASSWORD			"dir1"
#define ALLGROUP_USERNAME		"user"
#define ALLGROUP_PASSWORD		"password"

    char            *file_name;
    unsigned long   file_size;
    int             status;

	int certificate_length;
	char* certificate=NULL;
	char  cipher_list[] =	SSL_CIPHER_LIST_HTTPS_DEFAULT;
	int	  cipher_list_len=	SSL_CIPHER_LIST_HTTPS_DEFAULT_LEN;
	char* key=NULL;
	int	  key_data_len;

    status = NAsetSysAccess (NASYSACC_ADD, ALLGROUP_USERNAME, ALLGROUP_PASSWORD, NASYSACC_FS_SUPER_USER | NASYSACC_LEVEL_RW, NULL);
    if (status != 0)
        printf("NASetSysAccess Error: unsuccessfully set \"%s\" username \"%s\" password %d\n", 
                        ALLGROUP_USERNAME , ALLGROUP_PASSWORD, status);

    /*  Secure account Safe can only be used through the Secure Gateway -- this account's password will never be exposed!   */
    NAsetSysAccess (NASYSACC_ADD, "Safe", "netsilicon", NASYSACC_LEVEL_HTTP_R3 | NASYSACC_LEVEL_RW, "127.0.0.1");
    if (status != 0)
        printf("NASetSysAccess Error: unsuccessfully set \"Safe\" username \"netsilicon\" password %d\n", 
                        status);

    status = create_filesystem_volume();
    if (status != NAFS_SUCCESS)
    {
        printf("applicationStart Error: unable to create volume\n");
        goto _applicationStart_cont;
    }

    status = FileSystem_CreateDirectory(FS_VOLUME1_SUB_DIR0, NAFS_FS_GROUP1, GROUP1_USERNAME, GROUP1_PASSWORD);
    if (status != NAFS_SUCCESS)
        printf("Unable to create %s directory for %d group id with %s username & %s passowrd [%d].\n", 
                FS_VOLUME1_SUB_DIR0, NAFS_FS_GROUP1, GROUP1_USERNAME, GROUP1_PASSWORD, status);

    status = FileSystem_CreateDirectory(FS_VOLUME1_SUB_DIR1, NAFS_FS_GROUP2, GROUP2_USERNAME, GROUP2_PASSWORD);
    if (status != NAFS_SUCCESS)
        printf("Unable to create %s directory for %d group id with %s username & %s passowrd [%d]\n", 
                FS_VOLUME1_SUB_DIR1, NAFS_FS_GROUP2, GROUP2_USERNAME, GROUP2_PASSWORD, status);

    status = FileSystem_CreateDirectory(FS_VOLUME1_SUB_DIR0_1, NAFS_FS_GROUP1, GROUP1_USERNAME, GROUP1_PASSWORD);
    if (status != NAFS_SUCCESS)
        printf("Unable to create %s directory for %d group id with %s username & %s passowrd [%d]\n", 
                FS_VOLUME1_SUB_DIR0_1, NAFS_FS_GROUP1, GROUP1_USERNAME, GROUP1_PASSWORD, status);

    status = FileSystem_CreateTestFile(FS_VOLUME1_DIR, NAFS_FS_GROUP1, &file_name, &file_size);
    if (status != NAFS_SUCCESS)
        printf("Unable to create a test file in %s directory for %d group id [%d].\n", 
                FS_VOLUME1_DIR, NAFS_FS_GROUP1, status);

    ftp_server_app_init();

    printf ("%s Ready\n", APP_DIALOG_APP_NAME);

	/* Generate X.509 certificate for use by HTTPS server */
    printf ("Generating certificate.  This may take a few minutes.\n");
	certificate_length = NASSLX509Generate(&certificate, &key, &key_data_len, SSL_CERTIFICATE_KEY_TYPE_RSA, 1024, 1, "NAHTTPS Example Certificate", "020630120000Z", "120630120000Z");

	if(certificate_length <= 0 || key_data_len <= 0)
	{
		printf("Error generating X.509 certificate.\n");
		return;
	}

	/* Start Advanced HTTPS and HTTP servers */
    /* RpHSStartServerSecure(cipher_list, cipher_list_len, certificate, certificate_length, key, key_data_len, HTTP_AND_HTTPS); */
	
	/* OR */

	/* Start Advanced HTTPS server only */
	RpHSStartServerSecure(cipher_list, cipher_list_len, certificate, certificate_length, key, key_data_len, HTTPS_ONLY);
    printf ("AWS HTTPS Web Server Sample Application is ready.\n");

_applicationStart_cont:
    tx_thread_suspend(tx_thread_identify());
}

int HSStartServer(void){return 0;}



