ヘッダファイル(gvcd.h)

// --------------------------------------------------
// Global Versatile Controler http://www.gvc-on.net/
// --------------------------------------------------
// --------------------------------------------------
// Revision Memo (Y.M.D Editor/Memo)
// --------------------------------------------------
//
// 2013.06.10 T.Kabu
// 汎用制御装置 Grobal Versatile Controller Daemon (gvcd)
//
// gvcd /dev/????? (GVCが接続されているデバイス名)
//
// デバイスのパラメータは9600N81
//   9600bps
//   ノンパリティ
//   8ビット
//   ストップビット1
//   フロー制御はArduinoではしていないのでOFF
//
// パラメータはsetserialなどの外部コマンドで設定すればいいとおもう
//
// 参考URLいろいろ
// http://pinka99.ddo.jp/nanao/work/daemon.html
// http://d.hatena.ne.jp/rero/20041002/p1
// http://linuxmag.sourceforge.jp/Japanese/March2003/article287.shtml
// http://www.geocities.co.jp/Athlete-Samos/7760/study/msgkyu1.html
// http://www.geocities.jp/taka_owl2005/job/UNIX/kernel/ipc.html
// http://d.hatena.ne.jp/ka2yan/20090327
//
// ------------------------------
// BASE
// ------------------------------
// 2011.11.02 T.Kabu gvcd				とりあえず取り掛かる
// 2011.12.01 T.Kabu gvcd2c				幾つかのセンサーに対応して画面に吐き出すようにした
// 2011.12.20 T.Kabu gvcd3				デーモン化、プロセスチェック、ログ吐き出しに取り掛かる
// 2012.02.02 T.Kabu gvcd3b				テストソースからあれこれマージ、プロセス間通信(メッセージキュー)対応
// 2012.02.06 T.Kabu gvcd3c				GVCに対してコマンド送信
// 2012.03.09 T.Kabu gvcd4				スタートフレームと言う定義をやめて、デリミタメッセージにした
// 2013.06.10 T.Kabu gvcd_20130610		Rev.2用に色々修正
// 										以後、日付で逐次リビジョンアップしていく事にする
// 2013.07.18 T.Kabu gvcd_20130717		赤外線データ(つまりリモコン)の送受信保存再送が出来るようになったのでいったんFix
// 2013.12.20 T.Kabu 					清書と、赤外線データのサイズの関係で扱えるデータサイズをヘッダ込みで最大1600バイトに統一する

//---------------------------------------------------
// include
//---------------------------------------------------

// --------------------------------------------------
// Const Define
// --------------------------------------------------
#define		SOFTNAME				"Gloval Versatile Controler(GVC) Daemon"
#define		VERSION					"201312"

#define		BAUD_RATE				B9600		// シリアルポートボーレート
												// PICはそのクロックにもよりますが、B9600~になります
												// ちなみにArduinoはLinux的にB300,B1200,B2400,B4800,B9600,B19200,B38400,B57600,B115200に対応でした

#define		BUFF_SIZE				4096		// でかくすると、メッセージキューのサイズを超えてしまうので注意!!
												// 2013.12.20 赤外線データの関係で実際に扱えるデータサイズはヘッダ込みで最大1600バイトとする

#define		GVC_MIN_MESSAGE_LENGTH	7			// シリアルメッセージの最小サイズ
#define		DELIMITER_LENGTH		16			// デリミタメッセージの長さ

#define		DAYTIME_LEN				32			// 日時情報文字列の長さ

#define		GVC_MSG_DELIMITER		0xaa		// GVCデリミタメッセージ(0xaa)

#define		GVC_MSG_END				0x00		// Message delimiter(Rev.2では使用していない)

// メッセージタイプ
#define GVC_CMD_REQUEST_VERSION		0x01		// バージョン要求コマンド
#define GVC_CMD_REQUEST_MODULEINFO	0x02		// 接続モジュール情報要求コマンド
#define GVC_CMD_REQUEST_MODULEDATA	0x03		// モジュールデータ取得要求コマンド
#define GVC_MSG_0x04				0x04		// xxx (TBD)
#define GVC_MSG_ENQ					0x05		// GVCへの各種要求
#define GVC_MSG_0x06				0x06		// xxx (TBD)
#define GVC_MSG_0x07				0x07		// xxx (TBD)
#define GVC_MSG_0x08				0x08		// xxx (TBD)
#define GVC_MSG_0x09				0x09		// xxx (TBD)
#define GVC_MSG_0x0a				0x0a		// xxx (TBD)
#define GVC_MSG_0x0b				0x0b		// xxx (TBD)
#define GVC_MSG_0x0c				0x0c		// xxx (TBD)
#define GVC_MSG_0x0d				0x0d		// xxx (TBD)
#define GVC_MSG_0x0e				0x0e		// xxx (TBD)
#define GVC_MSG_0x0f				0x0f		// xxx (TBD)

#define GVC_MSG_0x10				0x10		// xxx (TBD)
#define GVC_MSG_0x11				0x11		// xxx (TBD)
#define GVC_MSG_0x12				0x12		// xxx (TBD)
#define GVC_MSG_0x13				0x13		// xxx (TBD)
#define GVC_MSG_0x14				0x14		// xxx (TBD)
#define GVC_MSG_0x15				0x15		// xxx (TBD)
#define GVC_MSG_0x16				0x16		// xxx (TBD)
#define GVC_MSG_0x17				0x17		// xxx (TBD)
#define GVC_MSG_0x18				0x18		// xxx (TBD)
#define GVC_MSG_0x19				0x19		// xxx (TBD)
#define GVC_MSG_0x1a				0x1a		// xxx (TBD)
#define GVC_MSG_0x1b				0x1b		// xxx (TBD)
#define GVC_MSG_0x1c				0x1c		// xxx (TBD)
#define GVC_MSG_0x1d				0x1d		// xxx (TBD)
#define GVC_MSG_0x1e				0x1e		// xxx (TBD)
#define GVC_MSG_0x1f				0x1f		// xxx (TBD)

#define GVC_MSG_0x20				0x20		// xxx (TBD)
#define GVC_MSG_OTHER				0x21		// 各種情報メッセージ
#define GVC_MSG_0x22				0x22		// xxx (TBD)
#define GVC_MSG_0x23				0x23		// xxx (TBD)
#define GVC_MSG_0x24				0x24		// xxx (TBD)
#define GVC_MSG_0x25				0x25		// xxx (TBD)
#define GVC_MSG_0x26				0x26		// xxx (TBD)
#define GVC_MSG_0x27				0x27		// xxx (TBD)
#define GVC_MSG_0x28				0x28		// xxx (TBD)
#define GVC_MSG_0x29				0x29		// xxx (TBD)
#define GVC_MSG_0x2a				0x2a		// xxx (TBD)
#define GVC_MSG_0x2b				0x2b		// xxx (TBD)
#define GVC_MSG_0x2c				0x2c		// xxx (TBD)
#define GVC_MSG_0x2d				0x2d		// xxx (TBD)
#define GVC_MSG_0x2e				0x2e		// xxx (TBD)
#define GVC_MSG_0x2f				0x2f		// xxx (TBD)

#define GVC_MSG_0x30				0x30		// xxx (TBD)
#define GVC_MSG_0x31				0x31		// xxx (TBD)
#define GVC_MSG_0x32				0x32		// xxx (TBD)
#define GVC_MSG_0x33				0x33		// xxx (TBD)
#define GVC_MSG_0x34				0x34		// xxx (TBD)
#define GVC_MSG_0x35				0x35		// xxx (TBD)
#define GVC_MSG_0x36				0x36		// xxx (TBD)
#define GVC_MSG_0x37				0x37		// xxx (TBD)
#define GVC_MSG_0x38				0x38		// xxx (TBD)
#define GVC_MSG_0x39				0x39		// xxx (TBD)
#define GVC_MSG_0x3a				0x3a		// xxx (TBD)
#define GVC_MSG_0x3b				0x3b		// xxx (TBD)
#define GVC_MSG_0x3c				0x3c		// xxx (TBD)
#define GVC_MSG_0x3d				0x3d		// xxx (TBD)
#define GVC_MSG_0x3e				0x3e		// xxx (TBD)
#define GVC_MSG_0x3f				0x3f		// xxx (TBD)

#define GVC_MSG_0x40				0x40		// xxx (TBD)
#define GVC_MSG_0x41				0x41		// 'A' Acceleration (TBD)
#define GVC_MSG_0x42				0x42		// 'B' xxx (TBD)
#define GVC_MSG_0x43				0x43		// 'C' Compass (TBD)
#define GVC_MSG_DIST				0x44		// 'D' Distance (TBD)
#define GVC_MSG_0x45				0x45		// 'E' xxx (TBD)
#define GVC_MSG_0x46				0x46		// 'F' xxx (TBD)
#define GVC_MSG_0x47				0x47		// 'G' Gyro (TBD)
#define GVC_MSG_HUMI				0x48		// 'H' Humidity (TBD)
#define GVC_MSG_IR					0x49		// 'I' Infrared (TBD)
#define GVC_MSG_0x4a				0x4a		// 'J' xxx (TBD)
#define GVC_MSG_0x4b				0x4b		// 'K' xxx (TBD)
#define GVC_MSG_LIGHT				0x4c		// 'L' LIGHT (TBD)
#define GVC_MSG_0x4d				0x4d		// 'M' xxx (TBD)
#define GVC_MSG_0x4e				0x4e		// 'N' xxx (TBD)
#define GVC_MSG_0x4f				0x4f		// 'O' xxx (TBD)

#define GVC_MSG_PRESS				0x50		// 'P' Pressure (TBD)
#define GVC_MSG_0x51				0x51		// 'Q' xxx (TBD)
#define GVC_MSG_0x52				0x52		// 'R' xxx (TBD)
#define GVC_MSG_0x53				0x53		// 'S' xxx (TBD)
#define GVC_MSG_TEMP				0x54		// 'T' Templeture (TBD)
#define GVC_MSG_0x55				0x55		// 'U' xxx (TBD)
#define GVC_MSG_0x56				0x56		// 'V' xxx (TBD)
#define GVC_MSG_0x57				0x57		// 'W' xxx (TBD)
#define GVC_MSG_0x58				0x58		// 'X' xxx (TBD)
#define GVC_MSG_0x59				0x59		// 'Y' xxx (TBD)
#define GVC_MSG_0x5a				0x5a		// 'Z' xxx (TBD)
#define GVC_MSG_0x5b				0x5b		// xxx (TBD)
#define GVC_MSG_0x5c				0x5c		// xxx (TBD)
#define GVC_MSG_0x5d				0x5d		// xxx (TBD)
#define GVC_MSG_0x5e				0x5e		// xxx (TBD)
#define GVC_MSG_0x5f				0x5f		// xxx (TBD)

#define GVC_MSG_0x60				0x60		// 'a' xxx (TBD)
#define GVC_MSG_0x61				0x61		// 'b' xxx (TBD)
#define GVC_MSG_0x62				0x62		// 'c' xxx (TBD)
#define GVC_MSG_0x63				0x63		// 'd' xxx (TBD)
#define GVC_MSG_0x64				0x64		// 'e' xxx (TBD)
#define GVC_MSG_0x65				0x65		// 'f' xxx (TBD)
#define GVC_MSG_0x66				0x66		// 'g' xxx (TBD)
#define GVC_MSG_0x67				0x67		// 'h' xxx (TBD)
#define GVC_MSG_0x68				0x68		// 'X' xxx (TBD)
#define GVC_MSG_0x69				0x69		// 'i' xxx (TBD)
#define GVC_MSG_0x6a				0x6a		// 'j' xxx (TBD)
#define GVC_MSG_0x6b				0x6b		// 'k' xxx (TBD)
#define GVC_MSG_0x6c				0x6c		// 'l' xxx (TBD)
#define GVC_MSG_0x6d				0x6d		// 'm' xxx (TBD)
#define GVC_MSG_0x6e				0x6e		// 'n' xxx (TBD)
#define GVC_MSG_0x6f				0x6f		// 'o' xxx (TBD)

#define GVC_MSG_0x70				0x70		// 'p' xxx (TBD)
#define GVC_MSG_0x71				0x71		// 'q' xxx (TBD)
#define GVC_MSG_0x72				0x72		// 'r' xxx (TBD)
#define GVC_MSG_0x73				0x73		// 's' xxx (TBD)
#define GVC_MSG_0x74				0x74		// 't' xxx (TBD)
#define GVC_MSG_0x75				0x75		// 'u' xxx (TBD)
#define GVC_MSG_0x76				0x76		// 'v' xxx (TBD)
#define GVC_MSG_0x77				0x77		// 'w' xxx (TBD)
#define GVC_MSG_0x78				0x78		// 'x' xxx (TBD)
#define GVC_MSG_0x79				0x79		// 'y' xxx (TBD)
#define GVC_MSG_0x7a				0x7a		// 'z' xxx (TBD)
#define GVC_MSG_0x7b				0x7b		// xxx (TBD)
#define GVC_MSG_0x7c				0x7c		// xxx (TBD)
#define GVC_MSG_0x7d				0x7d		// xxx (TBD)
#define GVC_MSG_0x7e				0x7e		// xxx (TBD)
#define GVC_MSG_0x7f				0x7f		// STOP (TBD)

#define GVC_MSG_0xff				0xff		// END (TBD)

#define GVC_DEV_00					0			// GVC DEVICE NO 0 (DO NOT USE THIS!!)
#define GVC_DEV_01					1			// GVC DEVICE NO 1
#define GVC_DEV_02					2			// GVC DEVICE NO 2
#define GVC_DEV_03					3			// GVC DEVICE NO 3
#define GVC_DEV_04					4			// GVC DEVICE NO 4
#define GVC_DEV_05					5			// GVC DEVICE NO 5
#define GVC_DEV_06					6			// GVC DEVICE NO 6
#define GVC_DEV_07					7			// GVC DEVICE NO 7
#define GVC_DEV_08					8			// GVC DEVICE NO 8
#define GVC_DEV_09					9			// GVC DEVICE NO 9

#define GVC_I2C_MESSAGE_HEADER_SIZE	4			// I2C上を流れるメッセージのヘッダー部分(format,cmd,data_len)の長さ
#define GVC_SERIAL_MESSAGE_HEADER_SIZE	6		// シリアル上を流れるメッセージのヘッダー部分(msg_type, dev_num, format,cmd,data_len)の長さ

#define	GVC_IR_DATALEN_MAX			1568		// 赤外線データの最大長 2013.12.20 仮決定

// ログファイル名設定
#define		GVC_LOG_FILENAME		"/var/log/gvcd.log"

// PIDファイル名設定
#define		GVC_PID_FILENAME		"/var/run/gvcd.pid"

// メッセージキュータイプを設定
#define		COMMAND_Q			1				// 送信(命令)メッセージタイプ
#define		RESULT_Q			9				// 受信(結果)メッセージタイプ

// --------------------------------------------------
// Structure
// --------------------------------------------------
//  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
// ------------------------------
// GVC I2C MESSAGE (GVC  Module)
// ------------------------------
typedef struct _GVC_I2C_MESSAGE_T_
{
	unsigned char format;								// format
	unsigned char cmd;									// cmd
	unsigned short int data_len;						// data length
	unsigned char data[];								// data array (最低3バイトで、その最後はchecksumが入る)
} GVC_I2C_MESSAGE_t;

// ------------------------------
// GVC SERIAL MESSAGE (gvcd  GVC)
// ------------------------------
typedef struct _GVC_SERIAL_MESSAGE_T_
{
	unsigned char msg_type;								// message type
	unsigned char dev_num;								// device number
	unsigned char format;								// format
	unsigned char cmd;									// cmd
	unsigned short int data_len;						// data length
	unsigned char data[];								// data array (最低3バイトで、その最後はchecksumが入る)
} GVC_SERIAL_MESSAGE_t;
// unionで複数構成にしてもいいかなと思ったけど、まぁそこまでいじるよりもダイレクトにポインタ参照で入れていったほうが早いし…

// ------------------------------
// 命令メッセージ(こちらはメッセージキューに使うので、msg_data[]の長さはあらかじめ指定している)
// ------------------------------
typedef struct _GVC_QUEUE_MESSAGE_T_
{
	unsigned char gvc_num;								// 対象GVCの番号(現状は0x01で一台のみが対象)
	unsigned char msg_type;								// メッセージタイプ(0x05)
	unsigned char dev_num;								// 対象デバイス番号(※GVCで把握できるデバイス番号)
	unsigned char format;								// format
	unsigned char cmd;									// cmd
	unsigned short int data_len;						// data length
	unsigned char data[BUFF_SIZE];						// data array (最低3バイトで、その最後はchecksumが入る、メッセージ自体は固定長、GVCとのやり取りは任意長にgvcdが変換)
} GVC_QUEUE_MESSAGE_t;

// --------------------------------
// メッセージキュー構造体を定義(gvc_cmd(仮称)とgvcdとのやり取りのためのメッセージキュー)
// --------------------------------
typedef struct  _GVC_MESSAGE_QUEUE_T_
{
	unsigned long qtype;								// メッセージキュータイプ(基本的には1=gvc_cmdからgvcdへの命令)
	GVC_QUEUE_MESSAGE_t q;								// やり取りするメッセージキューデータ(GVCの命令形メッセージ)
} GVC_MESSAGE_QUEUE_t;
// メッセージキュー、というかLinuxレベルになるとテーブル構造体のアラインメントが行われるから注意すること!!
// PICではもちろんメモリ空間的にリニアに扱われるが、Linuxではメッセージ全体のCRCの計算などができない(めんどい)

// --------------------------------------------------
// Prototype Define
// --------------------------------------------------

// --------------------------------------------------
// Variable Param
// --------------------------------------------------
// CRC-8-CCITTテーブルの配列	参考:http://blog.goo.ne.jp/masaki_goo_2006/e/b852b25b96de412e0df3b474e406e704
static unsigned char CRC8Table[ 256 ] = {
	0x00, 0x8D, 0x97, 0x1A, 0xA3, 0x2E, 0x34, 0xB9,
	0xCB, 0x46, 0x5C, 0xD1, 0x68, 0xE5, 0xFF, 0x72,
	0x1B, 0x96, 0x8C, 0x01, 0xB8, 0x35, 0x2F, 0xA2,
	0xD0, 0x5D, 0x47, 0xCA, 0x73, 0xFE, 0xE4, 0x69,
	0x36, 0xBB, 0xA1, 0x2C, 0x95, 0x18, 0x02, 0x8F,
	0xFD, 0x70, 0x6A, 0xE7, 0x5E, 0xD3, 0xC9, 0x44,
	0x2D, 0xA0, 0xBA, 0x37, 0x8E, 0x03, 0x19, 0x94,
	0xE6, 0x6B, 0x71, 0xFC, 0x45, 0xC8, 0xD2, 0x5F,

	0x6C, 0xE1, 0xFB, 0x76, 0xCF, 0x42, 0x58, 0xD5,
	0xA7, 0x2A, 0x30, 0xBD, 0x04, 0x89, 0x93, 0x1E,
	0x77, 0xFA, 0xE0, 0x6D, 0xD4, 0x59, 0x43, 0xCE,
	0xBC, 0x31, 0x2B, 0xA6, 0x1F, 0x92, 0x88, 0x05,
	0x5A, 0xD7, 0xCD, 0x40, 0xF9, 0x74, 0x6E, 0xE3,
	0x91, 0x1C, 0x06, 0x8B, 0x32, 0xBF, 0xA5, 0x28,
	0x41, 0xCC, 0xD6, 0x5B, 0xE2, 0x6F, 0x75, 0xF8,
	0x8A, 0x07, 0x1D, 0x90, 0x29, 0xA4, 0xBE, 0x33,

	0xD8, 0x55, 0x4F, 0xC2, 0x7B, 0xF6, 0xEC, 0x61,
	0x13, 0x9E, 0x84, 0x09, 0xB0, 0x3D, 0x27, 0xAA,
	0xC3, 0x4E, 0x54, 0xD9, 0x60, 0xED, 0xF7, 0x7A,
	0x08, 0x85, 0x9F, 0x12, 0xAB, 0x26, 0x3C, 0xB1,
	0xEE, 0x63, 0x79, 0xF4, 0x4D, 0xC0, 0xDA, 0x57,
	0x25, 0xA8, 0xB2, 0x3F, 0x86, 0x0B, 0x11, 0x9C,
	0xF5, 0x78, 0x62, 0xEF, 0x56, 0xDB, 0xC1, 0x4C,
	0x3E, 0xB3, 0xA9, 0x24, 0x9D, 0x10, 0x0A, 0x87,

	0xB4, 0x39, 0x23, 0xAE, 0x17, 0x9A, 0x80, 0x0D,
	0x7F, 0xF2, 0xE8, 0x65, 0xDC, 0x51, 0x4B, 0xC6,
	0xAF, 0x22, 0x38, 0xB5, 0x0C, 0x81, 0x9B, 0x16,
	0x64, 0xE9, 0xF3, 0x7E, 0xC7, 0x4A, 0x50, 0xDD,
	0x82, 0x0F, 0x15, 0x98, 0x21, 0xAC, 0xB6, 0x3B,
	0x49, 0xC4, 0xDE, 0x53, 0xEA, 0x67, 0x7D, 0xF0,
	0x99, 0x14, 0x0E, 0x83, 0x3A, 0xB7, 0xAD, 0x20,
	0x52, 0xDF, 0xC5, 0x48, 0xF1, 0x7C, 0x66, 0xEB,
};

// --------------------------------------------------
// Sub Routine
// --------------------------------------------------
// ------------------------------
// CRC8テーブルから計算
// ------------------------------
unsigned char GetCRC8( const void *buff, size_t size )
{
	unsigned char *data = (unsigned char *)buff;
	unsigned char  crc8 = 0x00;

	while ( size != 0 )
	{
		crc8 = CRC8Table[ crc8 ^ *data ];
		data++;
		size--;
	}
	return crc8;
}