/*  main.c  */

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

/*
 *
 *  Basic example of userspace thread protected memory
 *
 *  NOTE: The encryption algorithim 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, part0, part1, part2, part3, part4);
/* prepare the memory domain structures  */
struct k_mem_domain dom0, dom1, dom2;
/* each variable starts with a name defined in main.h
 * the names are symbolic for the memory partitions
 * purpose.
 */
_app_red_b BYTE fBUFIN;
_app_red_b BYTE BUFIN[63];

_app_blk_b BYTE fBUFOUT;
_app_blk_b BYTE BUFOUT[63];

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

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

/*
 *   calculated by the enc thread at init and when the wheels
 *   change.
 */
_app_enc_b BYTE W1R[26];
_app_enc_b BYTE W2R[26];
_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";
_app_enc_d int enc_state = 1;
_app_enc_b char enc_pt[50];  /* Copy form shared pt */
_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 *dom1_parts[] = {&part2, &part1, &part3};
	struct k_mem_partition *dom2_parts[] = {&part4, &part3};
	struct k_mem_partition *dom0_parts[] = {&part0, &part1};
	k_tid_t tPT, tENC, tCT;

	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 %08X\n", (unsigned int) tENC);
	k_mem_domain_init(&dom1, 3, dom1_parts);
	printk("Partitions added to dom1\n");
	k_mem_domain_add_thread(&dom1, tENC);
	printk("dom1 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 %08X\n", (unsigned int) tPT);
	k_mem_domain_init(&dom0, 2, dom0_parts);
	k_mem_domain_add_thread(&dom0, tPT);
	printk("dom0 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 %08X\n", (unsigned int) tCT);
	k_mem_domain_init(&dom2, 2, dom2_parts);
	k_mem_domain_add_thread(&dom2, tCT);
	printk("dom2 Created\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");
	k_thread_abort(k_current_get());

}



/*
 * 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;
	if (enc_state == 1) {
		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;
		enc_state = 0;
	}

	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(&enc_pt, 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(&enc_ct, 0, SAMP_BLOCKSIZE); /* clear memory */
			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(100);
			}
			/* ct thread has cleared the buffer */
			memcpy(&BUFOUT, &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(2000);
	while (1) {
		k_sem_take(&allforone, K_FOREVER);
		if (fBUFIN == 0) { /* send message to encode */
			printk("\nPT Sending Message 1\n");
			memset(&BUFIN, 0, SAMP_BLOCKSIZE);
			memcpy(&BUFIN, &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(&BUFIN, 0, SAMP_BLOCKSIZE);
			memcpy(&BUFIN, &ptMSG2, sizeof(ptMSG2));
			fBUFIN = 1;
		}
		k_sem_give(&allforone);
		k_sleep(5000);
	}
}

/*
 * 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(&tbuf, 0, sizeof(tbuf));
			memcpy(&tbuf, BUFOUT, SAMP_BLOCKSIZE);
			fBUFOUT = 0;
			printk("CT MSG: %s\n", (char *)&tbuf);
		}
		k_sem_give(&allforone);
	}
}
