/*  main.c  */

/*
 *   SPDX-License-Identifier: Apache-2.0
 */

/*
 *
 *  Basic example of userspace thread protected memory
 *
 *  NOTE: The encryption algorithm is unverified and
 *  based on a 1930's erra piece of hardware.
 *  DO NOT USE THIS CODE FOR SECURITY
 *
 */
#include "main.h"
#include "enc.h"
/* the following definition name prefix is to avoid a conflict */
#define SAMP_BLOCKSIZE 50

/*
 *  The memory partitions have been named to simplify
 * the definition of variables.  A possible alternative
 * is using one source file per thread and implementing
 * a objcopy to rename the data and bss section for the
 * thread to the partiotion name.
 */

/* prepare the memory partition structures  */
FOR_EACH(K_APPMEM_PARTITION_DEFINE, (;), user_part, red_part, enc_part, blk_part, ct_part);
/* prepare the memory domain structures  */
struct k_mem_domain pt_domain, enc_domain;
/* each variable starts with a name defined in main.h
 * the names are symbolic for the memory partitions
 * purpose.
 */
volatile _app_red_b BYTE fBUFIN;
volatile _app_red_b BYTE BUFIN[63];

volatile _app_blk_b BYTE fBUFOUT;
volatile _app_blk_b BYTE BUFOUT[63];

/* declare and set wheel and reflector  */
/* To use add definition ALTMSG */
#ifdef ALTMSG
volatile _app_enc_d BYTE W1[26] = START_WHEEL;
#else
volatile _app_enc_d BYTE W1[26] = START_WHEEL2;
#endif
volatile _app_enc_d BYTE W2[26] = START_WHEEL;
volatile _app_enc_d BYTE W3[26] = START_WHEEL;
volatile _app_enc_d BYTE R[26] = REFLECT;

volatile _app_enc_b int IW1;
volatile _app_enc_b int IW2;
volatile _app_enc_b int IW3;

/*
 *   calculated by the enc thread at init and when the wheels
 *   change.
 */
volatile _app_enc_b BYTE W1R[26];
volatile _app_enc_b BYTE W2R[26];
volatile _app_enc_b BYTE W3R[26];

/*
 *	sync threads
 */
K_SEM_DEFINE(allforone, 0, 3);

struct k_thread enc_thread;
K_THREAD_STACK_DEFINE(enc_stack, STACKSIZE);

struct k_thread pt_thread;
K_THREAD_STACK_DEFINE(pt_stack, STACKSIZE);

struct k_thread ct_thread;
K_THREAD_STACK_DEFINE(ct_stack, STACKSIZE);

_app_enc_d char encMSG[] = "ENC!\n";
volatile _app_enc_b char enc_pt[50];  /* Copy form shared pt */
volatile _app_enc_b char enc_ct[50]; /* Copy to shared ct */

_app_user_d char ptMSG[] = "PT: message to encrypt\n";

/* encrypted message when W1 = START_WHEEL */
/* to use add definition ALTMSG  */
#ifdef ALTMSG
_app_user_d char ptMSG2[] = "nfttbhfspfmdqzos\n";
#else
/* encrypted message when W1 = START_WHEEL2 */
_app_user_d char ptMSG2[] = "ofttbhfspgmeqzos\n";
#endif
_app_ct_d char ctMSG[] = "CT!\n";




void main(void)
{
	struct k_mem_partition *enc_parts[] = {&enc_part, &red_part, &blk_part};
	struct k_mem_partition *pt_parts[] = {&user_part, &red_part};
	k_tid_t tPT, tENC, tCT;

	fBUFIN = 0; /* clear flags */
	fBUFOUT = 0;
	calc_rev_wheel((BYTE *) &W1, (BYTE *)&W1R);
	calc_rev_wheel((BYTE *) &W2, (BYTE *)&W2R);
	calc_rev_wheel((BYTE *) &W3, (BYTE *)&W3R);
	IW1 = 0;
	IW2 = 0;
	IW3 = 0;

	k_thread_access_grant(k_current_get(), &allforone);

	/*
	 * create an enc thread init the memory domain and add partitions
	 * then add the thread to the domain.
	 */
	tENC = k_thread_create(&enc_thread, enc_stack, STACKSIZE,
			(k_thread_entry_t)enc, NULL, NULL, NULL,
			-1, K_USER,
			K_FOREVER);
	k_thread_access_grant(tENC, &allforone);
	/* use K_FOREVER followed by k_thread_start*/
	printk("ENC Thread Created %p\n", tENC);
	k_mem_domain_init(&enc_domain, 3, enc_parts);
	printk("Partitions added to enc_domain\n");
	k_mem_domain_add_thread(&enc_domain, tENC);
	printk("enc_domain Created\n");


	tPT = k_thread_create(&pt_thread, pt_stack, STACKSIZE,
			(k_thread_entry_t)pt, NULL, NULL, NULL,
			-1, K_USER,
			K_FOREVER);
	k_thread_access_grant(tPT, &allforone);
	printk("PT Thread Created %p\n", tPT);
	k_mem_domain_init(&pt_domain, 2, pt_parts);
	k_mem_domain_add_thread(&pt_domain, tPT);
	printk("pt_domain Created\n");

	tCT = k_thread_create(&ct_thread, ct_stack, STACKSIZE,
			(k_thread_entry_t)ct, NULL, NULL, NULL,
			-1, K_USER,
			K_FOREVER);
	k_thread_access_grant(tCT, &allforone);
	printk("CT Thread Created %p\n", tCT);
	/* Re-using the default memory domain for CT */
	k_mem_domain_add_partition(&k_mem_domain_default, &ct_part);
	k_mem_domain_add_partition(&k_mem_domain_default, &blk_part);
	printk("ct partitions installed\n");

	k_thread_start(&enc_thread);
	/* need to start all three threads.  let enc go first to perform init step */

	printk("ENC thread started\n");
	k_thread_start(&pt_thread);
	printk("PT thread started\n");

	k_thread_start(&ct_thread);
	k_sem_give(&allforone);
	printk("CT thread started\n");
}



/*
 * The enc thread.
 * Function: initialize the the simulation of the wheels.
 * Copy memory from pt thread and encrypt to a local buffer
 * then copy to the ct thread.
 */
void enc(void)
{

	int index, index_out;

	while (1) {
		k_sem_take(&allforone, K_FOREVER);
		if (fBUFIN == 1) { /* 1 is process text */
			printk("ENC Thread Received Data\n");
			/* copy message form shared mem and clear flag */
			memcpy((void *)&enc_pt, (void *)BUFIN, SAMP_BLOCKSIZE);
			printk("ENC PT MSG: %s\n", (char *)&enc_pt);
			fBUFIN = 0;
			/* reset wheel: probably better as a flag option  */
			IW1 = 7;
			IW2 = 2;
			IW3 = 3;
			/* encode */
			memset((void *)&enc_ct, 0, SAMP_BLOCKSIZE);
			for (index = 0, index_out = 0; index < SAMP_BLOCKSIZE; index++) {
				if (enc_pt[index] == '\0') {
					enc_ct[index_out] = '\0';
					break;
				}
				if (enc_pt[index] >= 'a' && enc_pt[index] <= 'z') {
					enc_ct[index_out] = (BYTE)enig_enc((BYTE) enc_pt[index]);
					index_out++;
				}
			}
			/* test for CT flag */
			while (fBUFOUT != 0) {
				k_sleep(K_MSEC(1));
			}
			/* ct thread has cleared the buffer */
			memcpy((void *)&BUFOUT, (void *)&enc_ct,
			       SAMP_BLOCKSIZE);
			fBUFOUT = 1;

		}
		k_sem_give(&allforone);
	}
}

/*
 * the pt function pushes data to the enc thread.
 * It can be extended to receive data from a serial port
 * and pass the data to enc
 */
void pt(void)
{

	k_sleep(K_MSEC(20));
	while (1) {
		k_sem_take(&allforone, K_FOREVER);
		if (fBUFIN == 0) { /* send message to encode */
			printk("\nPT Sending Message 1\n");
			memset((void *)&BUFIN, 0, SAMP_BLOCKSIZE);
			memcpy((void *)&BUFIN, (void *)&ptMSG, sizeof(ptMSG));
/* strlen should not be used if user provided data, needs a max length set  */
			fBUFIN = 1;
		}
		k_sem_give(&allforone);
		k_sem_take(&allforone, K_FOREVER);
		if (fBUFIN == 0) { /* send message to decode  */
			printk("\nPT Sending Message 1'\n");
			memset((void *)&BUFIN, 0, SAMP_BLOCKSIZE);
			memcpy((void *)&BUFIN, (void *)&ptMSG2, sizeof(ptMSG2));
			fBUFIN = 1;
		}
		k_sem_give(&allforone);
		k_sleep(K_MSEC(50));
	}
}

/*
 * CT waits for fBUFOUT = 1 then copies
 * the message clears the flag and prints
 */
void ct(void)
{

	char tbuf[60];

	while (1) {
		k_sem_take(&allforone, K_FOREVER);
		if (fBUFOUT == 1) {
			printk("CT Thread Receivedd Message\n");
			memset((void *)&tbuf, 0, sizeof(tbuf));
			memcpy((void *)&tbuf, (void *)BUFOUT, SAMP_BLOCKSIZE);
			fBUFOUT = 0;
			printk("CT MSG: %s\n", (char *)&tbuf);
		}
		k_sem_give(&allforone);
	}
}
