/*********************************************************************************

	ahjut.c

	usage: ahjut [-l ttydevice] [-d [1|2]]

					(C) 2005.2  Suwa-Koubou 
*********************************************************************************/

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    <fcntl.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <unistd.h>

#include    "xn_xx.h"


#define         ON              1
#define         OFF             0

extern void	block_mode(int sw);                                             
extern void	senddata(size_t size, unsigned char *data);                     
extern size_t	getdata(char **data);                                  

int	main(int argc, char *argv[]);
void	cmdloop(void);
void	get_file(char *fname);
void	del_file(char *fname);
void	ft_end(void);
void	get_list(void);
void	put_file(char *fname);

int	dbg;
char	rsdevice[128] = "/dev/usb/ttyACM0";

/*---------------------------------------------------------------------------
	ここから開始
--------------------------------------------------------------------------*/

int main(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind, opterr, optopt;
	char	*cmd;
	char	*rsp;
	size_t	sz;
	int	c;

	/* オプション解析 */
	while((c = getopt(argc, argv, "l:d:")) != -1){
		if(c == 'l'){
			strcpy(rsdevice, optarg);
		}else if(c == 'd'){
			if(*optarg == '1' || *optarg == '2'){
				dbg = *optarg - '0';
			}
		}else{
			printf("usage: ahjut [-l ttydevice] [-d 1|2]\n");
			exit(1);
		}
	}

	xn_device(rsdevice);
	if(xn_open() == -1){
		printf("AH-J3003 Unready.\n");
		exit(1);
	}

	/* AH-j3003初期化 */		
	xn_sputs("ATZ\r");
	while(xn_rcv_ready() != 0){
		c = xn_getc();
		fputc(c, stdout);
	}

	xn_sputs("ATE0\r");
	while(xn_rcv_ready() != 0){
		c = xn_getc();
		fputc(c, stdout);
	}

	xn_flush();

	printf("************** File Transfer Start *****************\n");

	/* ファイル転送モードへ移行 */
	block_mode(ON);

	/* 転送処理開始 */
	cmd = "FT_START[0000]\r\n";
	if(dbg) printf("-->%s", cmd);
	senddata(strlen(cmd), cmd);
	
	sz = getdata(&rsp);
	if(dbg) printf("<--%s", rsp);
	if(strncmp(rsp, "OK", 2)){
		printf("Unable change to transfer mode.\n");
		xn_close();
		exit(1);
	}
	free(rsp);
	
	/* 対話入力,結果表示 */
	cmdloop();

	/* 終了 */
	printf("File Transefer Complete.......\n");

	exit(0);
}

/*---------------------------------------------------------------------------
	ファイル転送処理コマンドループ
--------------------------------------------------------------------------*/

void	cmdloop(void)
{
	char	cmdbuf[128];

	for(;;){
		printf("FT> ");

		fgets(cmdbuf, 127, stdin);
		cmdbuf[strlen(cmdbuf)-1] = 0;	/* cut lf */

		if(strncmp(cmdbuf, "list", 4) == 0){
			get_list();
		}else if(strncmp(cmdbuf, "get ", 4) == 0){
			get_file(cmdbuf+4);
		}else if(strncmp(cmdbuf, "del ", 4) == 0){
			del_file(cmdbuf+4);
		}else if(strncmp(cmdbuf, "put ", 4) == 0){
			put_file(cmdbuf+4);
		}else if(strncmp(cmdbuf, "end", 3) == 0){
			ft_end();
			return;
		}else if(strncmp(cmdbuf, "ls", 2) == 0){
			system("dir");
		}else{
			printf("Error!\n");
			printf("list\tget\tput\tdel\tend\tls\n");
			printf("\n");
		}
	}
}


/*---------------------------------------------------------------------------
	ファイル一覧取得
--------------------------------------------------------------------------*/

void	get_list(void)
{
	char	*cmd;
	char	*rsp, *p;
	size_t	sz;

	printf("Receiving file list ..........\n"); 

	/* ファイルリスト取得 */
	cmd = "GET_LIST\r\n";
	if(dbg) printf("-->%s", cmd);
	senddata(strlen(cmd), cmd);
	sz = getdata(&rsp);
	if(dbg) printf("<--%s", rsp);
	if(strncmp(rsp, "OK", 2)) {
		free(rsp);
		return;
	}
	free(rsp);

	sz = getdata(&rsp);	/* get list */
	if(dbg) printf("<--%s", rsp);
	/* 表示出力 */		
	p = rsp;
	while (*p != '\r'){
		/* print filename */
		while(*p != ',') fputc(*p++, stdout);
		fputc('\t', stdout);
		p++; /* skip , */

		/* print file size */
		while(*p != ',') fputc(*p++, stdout);
		fputs(" byte\n", stdout);

		while(*p++ != '\n') ;
	}
	free(rsp);

	cmd = "OK\r\n";
	if(dbg) printf("-->%s", cmd);
	senddata(strlen(cmd), cmd);

}


/*---------------------------------------------------------------------------
	ファイル読み出し
--------------------------------------------------------------------------*/

void	get_file(char *fname)
{
	FILE	*fout;
	char	cmd[256];
	char	*rsp;
	size_t	sz;

	sprintf(cmd, "GET_FILE[%s]\r\n", fname);
	if(dbg) printf("-->%s", cmd);
	senddata(strlen(cmd), cmd);
	sz = getdata(&rsp);
	if(dbg) printf("<--%s", rsp);
	if(strncmp(rsp, "OK", 2) == 0){
		free(rsp);

		/* ファイル本体受信 */
		sz = getdata(&rsp);
		if(dbg) printf("<--<file transefer size=%d>\n", sz);
		if((fout = fopen(fname, "w")) == NULL){
			fprintf(stderr, "file can't create.(%s)\n", fname);
		}else{
			fwrite(rsp, sz ,1, fout);
			fclose(fout);
		}
		free(rsp);
	
		strcpy(cmd,"OK\r\n");
		if(dbg) printf("-->%s", cmd);
		senddata(strlen(cmd), cmd);
		printf("%s get complete.\n", fname);
	}else{
		free(rsp);
		printf("%s not found.\n", fname);
	}

}


/*---------------------------------------------------------------------------
	ファイル削除
--------------------------------------------------------------------------*/

void	del_file(char *fname)
{
	char	cmd[256];
	char	*rsp;
	size_t	sz;


	/* ファイル削除コマンド送信 */
	sprintf(cmd, "DEL[%s]\r\n", fname);
	if(dbg) printf("-->%s", cmd);
	senddata(strlen(cmd), cmd);
	
	/* 削除結果受信 */
	sz = getdata(&rsp);
	if(dbg) printf("<--%s", rsp);
	if(strncmp(rsp, "OK", 2) == 0){
		printf("%s deleted.\n", fname);
	}else{
		printf("%s not delete, or not found.\n", fname);
	}
	free(rsp);


}


/*---------------------------------------------------------------------------
	ファイル書き込み
--------------------------------------------------------------------------*/

void	put_file(char *fname)
{
	struct stat fstatus;
	char	cmd[256];
	char	*rsp, *fp;
	size_t	sz;
	FILE	*fd;
	
	/* ファイルの検査ならびに長さ取得  */
	if( stat(fname, &fstatus) != 0){
		printf("Can't read %s, or doesn't exists.\n", fname);
		return;
	}

	/* ファイル送信コマンド作成 */
	sprintf(cmd, "PUT_FILE[%s,%d,00------------------------------]\r\n", fname, fstatus.st_size);
	if(dbg) printf("-->%s", cmd);
	senddata(strlen(cmd), cmd);

	/* 応答確認 */
	sz = getdata(&rsp);
	if(dbg) printf("<--%s", rsp);
	if(strncmp(rsp, "OK", 2) == 0){
		free(rsp);

		/* ファイルをメモリに一括読み込む */
		if( (fp = (char *)malloc(fstatus.st_size)) == NULL || 
			(fd = fopen(fname, "r")) == NULL ||
			fread(fp, 1, fstatus.st_size, fd) != (size_t)fstatus.st_size ){
			printf("file handling error. return to system.\n");
			xn_close();
			exit(1);
		}

		if(dbg) printf("--><file transefer size=%d>\n", fstatus.st_size);

		/* ファイル本体の送信 */
		senddata(fstatus.st_size, fp);
		free(fp); fclose(fd);
		 
		/* 応答確認 */
		sz = getdata(&rsp);
		if(dbg) printf("<--%s", rsp);
		if(strncmp(rsp, "OK", 2) == 0){
			printf("%s transfer complete.\n", fname);
		}else{
			printf("%s reject.\n", fname);
		}
		free(rsp);

	}else{ /* REJECT ? */
		free(rsp);
		printf("file is too big, or illegal file type.\n");
	}


}


/*---------------------------------------------------------------------------
	ファイル転送終了
--------------------------------------------------------------------------*/

void	ft_end(void)
{
	char	*cmd;
	char	*rsp;
	size_t	sz;

	/* 転送処理終了 */
	cmd = "FT_END\r\n";
	if(dbg) printf("-->%s", cmd);
	senddata(strlen(cmd), cmd);
	sz = getdata(&rsp);
	if(dbg) printf("<--%s", rsp);
	free(rsp);


	/* ファイル転送モード終了 */
	block_mode(OFF);
}


/*** end of ahjut.c *********************************************/
