/************************************************************
**
**     Object name : km-netapi
**
**     Public      : ** WsHandleOpen
**                   ** WsHandleClose
**                   
**                   WsGetSystemInfo
**                   WsGetTargetType
**                   WsGetTargetSubType
**                   WsGetBytePerSample
**                   WsGetFrameSize
**                   WsGetHeaderSize
**                   WsGetChannelNum
**                   WsGetResolutionBit
**
**                   ** WsSetSamplingFreq
**                   WsGetSamplingFreq
**                   WsSetChannelMode
**                   WsGetChannelMode
**                   ** WsSetCaptureChannels
**                   WsGetCaptureChannels
**                   WsSetCaptureChannelsList
**                   WsGetCaptureChannelsList
**
**                   ** WsSetHeaderFlag
**
**                   WsADStart
**                   WsADStop
**                   WsAdDaStart
**                   
**                   WsSetAdMode
**                   WsGetAdMode
**                   WsSetAdSleepMode
**                   WsGetAdSleepMode
**                   
**                   WsDataRead
**                   WsSampleDataRead
**                   WsFrameRead
**                   KM_WL_WsFrameRead
**                   RASP_WL_WsFrameReadFloatFormat
**                   WsFrameReadDummy
**
**                   ** WsSetAdDataFormat
**                   WsGetAdDataFormat
**                   
**                   WsWordClockOutput
**
**     Private     : WsControlClient
**                   WsControlClient2
**
**     Description
**     -- -- -- -- -- -- -- --
**     KMをネットワーク経由で利用するためのAPI
**
**     History
**     -- -- -- -- -- -- -- --
**     2013.09.01 M.Takigahira  新規作成
**                              librasp-apiをベースに移植
**
**     Copyright (c) 2013 HRI. All rights reserved. 
**
**     当社の許可なしに複製および転載を禁ず
**
*/


/*=========================================================*/
/*               Special Macro Definition                  */
/*=========================================================*/
#ifdef WIN32
#pragma warning(disable:4996)
#endif

#undef DEBUG

/*=========================================================*/
/*                   Include Files                         */
/*=========================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef WIN32

#include "WinSockVersion.h"

#ifdef _DEBUG
#define DEBUG
#endif

#else // WIN32

#include <unistd.h>
#include <sys/types.h>
//#include <sys/io.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <fcntl.h>
#include <errno.h>

#endif // WIN32

// KM specific
#include "libkm-netapi.h"
//#include "km-netapi-cmd.h"

/*=========================================================*/
/*                   Macro Definition                      */
/*=========================================================*/
#define KM_WL_SAMPLE_PER_FRAME         256

//#define RASP24_HEADER_SIZE  (sizeof(int) * 2)
#define KM_WL_HEADER_SIZE  (sizeof(short) * 4) //Old_Firmware_Header is (sizeof(short) * 3)

#ifdef DEBUG
#define DEBUG_PRINT printf
#else
#define DEBUG_PRINT(...)
#endif

#ifdef DEBUG_LOG
#define LOG_PRINT printf
#else
#define LOG_PRINT(...)
#endif

#define CONNECT_TIMEOUT 3000

/*=========================================================*/
/*                 Structure Declaration                   */
/*=========================================================*/

/*=========================================================*/
/*                    Private Valiable                     */
/*=========================================================*/

/*=========================================================*/
/*                    Public Valiable                      */
/*=========================================================*/

/*=========================================================*/
/*                   Private Functions                     */
/*=========================================================*/
static void crc16_ccitt(WS_KM_HANDLE_t *h_ws);
static unsigned short calc_checksum(WS_KM_HANDLE_t *h_ws, unsigned short crc, unsigned char *array, int start, int count);

static short ulaw_dec_old(unsigned char code); //old
static short ulaw_dec(unsigned char u_val);
static unsigned char ulaw_enc(int pcm_val);

static int WsKmControlClient(SOCKET socket_fd, int cmd, int *arg);
static int WsKmControlClient2(SOCKET socket_fd, int cmd, int *arg1, int *arg2);
static int UpdateChannelModeInfo(WS_KM_HANDLE_t *h_ws, int ch_mode);
static int CheckCaptureChannels(WS_KM_HANDLE_t *h_ws, int capture_channels, int print_flag);
static int ConnectWithTimeout(const int socket, const struct sockaddr *address, const socklen_t address_len, const int timeout_ms);

int KM_WL_WsKmFrameRead(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size);
int WsKmFrameReadDummy(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size);

#ifdef WIN32
#else
int (*WsKmFrameRead)(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size) = &WsKmFrameReadDummy;
#endif

//----------------------------------------------------------
//                          共通
//----------------------------------------------------------

//int m_state = RECV_STATE_FOUND_ID;
//int m_data_raw_idx = 0;
//unsigned short m_id;
//int m_length;
//unsigned short m_crc16;
//m16_t m_data_raw[PACKET_SIZE]; //ushort

//m16_t m_micdata_recv[4][256]; // マイクデータ保存用(受信バッファ用) short (pcm)

//int m_connected = 0; // 接続中かどうかを示すフラグ
//long m_recv_packet_count = 0; // データ受信パケット数

//int m_crc_error = 0;
//int m_serial_error_cnt = 0; // CRCエラー数

//static void crc16_ccitt(WS_KM_HANDLE_t *h_ws){ }
//static unsigned short calc_checksum(WS_KM_HANDLE_t *h_ws, unsigned short crc, unsigned char *array, int start, int count){ return 0; }
//static short ulaw_dec_old(unsigned char code){ return 0; }
//static short ulaw_dec(unsigned char u_val){ return 0; }
//static unsigned char ulaw_enc(int pcm_val){ return 0; }
//void packet_parse(WS_KM_HANDLE_t *h_ws, unsigned short data){ }

/* History : 2016.06.03 M.Takigahira 全関数ダミーに置き換え */
static int ConnectWithTimeout(const int socket, const struct sockaddr *address, const socklen_t address_len, const int timeout_ms){ return 0; }
static int WsKmControlClient(SOCKET socket_fd, int cmd, int *arg){ return 0; }
static int WsKmControlClient2(SOCKET socket_fd, int cmd, int *arg1, int *arg2){ return 0; }
WS_KM_HANDLE_t *WsKmHandleOpen(char *ip_addr){ return NULL; }
int WsKmHandleClose(WS_KM_HANDLE_t *h_ws){ return 0; }
int WsKmGetSystemInfo(WS_KM_HANDLE_t *h_ws, int *target_type){ return 0; }
int WsKmGetTargetType(WS_KM_HANDLE_t *h_ws, int *target_type){ return 0; }
int WsKmGetTargetSubType(WS_KM_HANDLE_t *h_ws, int *target_sub_type){ return 0; }
int WsKmGetBytePerSample(WS_KM_HANDLE_t *h_ws, int *byte_per_sample){ return 0; }
int WsKmGetFrameSize(WS_KM_HANDLE_t *h_ws, int *frame_size){ return 0; }
int WsKmGetHeaderSize(WS_KM_HANDLE_t *h_ws, int *header_size){ return 0; }
int WsKmGetChannelNum(WS_KM_HANDLE_t *h_ws, int *channel_num){ return 0; }
int WsKmGetResolutionBit(WS_KM_HANDLE_t *h_ws, int *resolution_bit){ return 0; }
int WsKmGetBoardNum(WS_KM_HANDLE_t *h_ws, int *board_num){ return 0; }
int WsKmHandleShow(WS_KM_HANDLE_t *h_ws){ return 0; }
int WsKmSetSamplingFreq(WS_KM_HANDLE_t *h_ws, int freq){ return 0; }
int WsKmGetSamplingFreq(WS_KM_HANDLE_t *h_ws, int *freq){ return 0; }
int WsKmSetChannelMode(WS_KM_HANDLE_t *h_ws, int channel_mode){ return 0; }
int WsKmGetChannelMode(WS_KM_HANDLE_t *h_ws, int *channel_mode){ return 0; }
int WsKmSetCaptureChannels(WS_KM_HANDLE_t *h_ws, int board_no, int channels){ return 0; }
int WsKmGetCaptureChannels(WS_KM_HANDLE_t *h_ws, int board_no, int *channels){ return 0; }
static int CheckCaptureChannels(WS_KM_HANDLE_t *h_ws, int capture_channels, int print_flag){ return 0; }
static int UpdateChannelModeInfo(WS_KM_HANDLE_t *h_ws, int ch_mode){ return 0; }
int WsKmSetCaptureChannelList(WS_KM_HANDLE_t *h_ws, int *channel_list){ return 0; }
int WsKmGetCaptureChannelList(WS_KM_HANDLE_t *h_ws, int *channel_list){ return 0; }
int WsKmSetCaptureGain(WS_KM_HANDLE_t *h_ws, int channel, int gain){ return 0; }
int WsKmGetCaptureGain(WS_KM_HANDLE_t *h_ws, int channel, int *gain){ return 0; }
int WsKmSetCaptureGainList(WS_KM_HANDLE_t *h_ws, int *gain_list){ return 0; }
int WsKmGetCaptureGainList(WS_KM_HANDLE_t *h_ws, int *gain_list){ return 0; }
int WsKmSetHeaderFlag(WS_KM_HANDLE_t *h_ws, int header_flag){ return 0; }
int WsKmGetHeaderFlag(WS_KM_HANDLE_t *h_ws, int *header_flag){ return 0; }
int WsKmADStart(WS_KM_HANDLE_t *h_ws){ return 0; }
int WsKmADStop(WS_KM_HANDLE_t *h_ws){ return 0; }
int WsKmAdDaStart(WS_KM_HANDLE_t *h_ws){ return 0; }
int WsKmSetAdMode(WS_KM_HANDLE_t *h_ws, int ad_mode){ return 0; }
int WsKmGetAdMode(WS_KM_HANDLE_t *h_ws, int *ad_mode){ return 0; }
int WsKmSetAdSleepMode(WS_KM_HANDLE_t *h_ws, int sleep_mode){ return 0; }
int WsKmGetAdSleepMode(WS_KM_HANDLE_t *h_ws, int *sleep_mode){ return 0; }
int WsKmDataRead(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size){ return 0; }
int WsKmSampleDataRead(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size){ return 0; }
int RASP24_WsKmFrameRead(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size){ return 0; }
int KM_WL_WsKmFrameRead(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size){ return 0; }
int WsKmFrameReadDummy(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size){ return -1; }
int RASP_WL_WsKmFrameReadFloatFormat(WS_KM_HANDLE_t *h_ws, char *buffer, size_t read_req_size){ return 0; }
int WsKmSetAdDataFormat(WS_KM_HANDLE_t *h_ws, int format_type){ return 0; }
int WsKmGetAdDataFormat(WS_KM_HANDLE_t *h_ws, int *format_type){ return 0; }
int WsKmWordClockOutput(WS_KM_HANDLE_t *h_ws, int mode){ return 0; }
int WsKmSystemPowerDown(WS_KM_HANDLE_t *h_ws){ return 0; }
/* EOF */
