for EthernetInterface library compatibility.\\ ** Unoffical fix. may be a problem. **
Dependents: SNIC-httpclient-example SNIC-ntpclient-example
Fork of SNICInterface by
Revision 3:9f90024d7fb2, committed 2014-03-13
- Comitter:
- kishino
- Date:
- Thu Mar 13 01:34:56 2014 +0000
- Parent:
- 2:0ba43344c814
- Child:
- 4:99cc93fe7d88
- Commit message:
- The following API was created.; =>Connect to AP.; =>Disconnect from AP.; =>Scan AP.
Changed in this revision
--- a/YDwifi/YDwifi.cpp Tue Mar 11 10:38:36 2014 +0000
+++ b/YDwifi/YDwifi.cpp Thu Mar 13 01:34:56 2014 +0000
@@ -14,6 +14,7 @@
bool is_receive;
}tagUART_RECVBUF_T;
tagUART_RECVBUF_T gUART_RCVBUF;
+unsigned char gUART_TEMP_BUF[UART_RECVBUF_SIZE];
C_YDwifi *C_YDwifi::mInstance_p;
@@ -92,38 +93,49 @@
// Check received data is EOM.
if( recvdata == UART_CMD_EOM )
{
+/*
printf("[recv]\r\n");
for( i = 0; i < gUART_RCVBUF.size; i++ )
{
printf("%02x ", gUART_RCVBUF.buf[i]);
}
printf("\r\n");
-
- // Get buffer for payload data
- unsigned char *payload_buf_p = instance_p->mUartCommand.getResponseBuf();
+*/
unsigned char command_id;
+ // Get payload from received data from UART.
+ int payload_len = C_YD_UartMsg::getResponsePayload( gUART_RCVBUF.size, gUART_RCVBUF.buf
+ , &command_id, gUART_TEMP_BUF );
+/*
+ printf("[payload]\r\n");
+ for( i = 0; i < payload_len; i++ )
+ {
+ printf("%02x ", gUART_TEMP_BUF[i]);
+ }
+ printf("\r\n");
+*/
+ // Check scan results indication
+ if( (command_id == UART_CMD_ID_WIFI) || (gUART_TEMP_BUF[0] == UART_CMD_SID_WIFI_SCAN_RESULT_IND) )
+ {
+ // Scan result indicate
+ instance_p->mUartCommand.scanResultIndicate( gUART_TEMP_BUF, payload_len );
+ }
- if( payload_buf_p != NULL )
+ // Checks in the command which is waiting.
+ if( instance_p->mUartCommand.isWaitingCommand(command_id, gUART_TEMP_BUF) )
{
- // Get payload from received data from UART.
- int payload_len = C_YD_UartMsg::getResponsePayload( gUART_RCVBUF.size, gUART_RCVBUF.buf
- , &command_id, payload_buf_p );
- printf("[payload]\r\n");
- for( i = 0; i < payload_len; i++ )
+ // Get buffer for payload data
+ unsigned char *payload_buf_p = instance_p->mUartCommand.getResponseBuf();
+ if( payload_buf_p != NULL )
{
- printf("%02x ", payload_buf_p[i]);
+ memcpy( payload_buf_p, gUART_TEMP_BUF, payload_len );
+ instance_p->mUartCommand.setResponseBuf( NULL );
}
- printf("\r\n");
-
- // Checks in the command which is waiting.
- if( instance_p->mUartCommand.isWaitingCommand(command_id, payload_buf_p) )
- {
- // Set status
- instance_p->mUartCommand.setCommandStatus( payload_buf_p[2] );
- // Set signal for command response wait.
- instance_p->mUartCommand.signal();
- }
+ // Set status
+ instance_p->mUartCommand.setCommandStatus( gUART_TEMP_BUF[2] );
+ // Set signal for command response wait.
+ instance_p->mUartCommand.signal();
}
+
gUART_RCVBUF.size = 0;
gUART_RCVBUF.is_receive = false;
}
--- a/YDwifi/YDwifi.h Tue Mar 11 10:38:36 2014 +0000
+++ b/YDwifi/YDwifi.h Thu Mar 13 01:34:56 2014 +0000
@@ -20,14 +20,29 @@
/** Wi-Fi security
*/
typedef enum SECURITY {
+ /** Securiry Open */
e_SEC_OPEN = 0x00,
+ /** Securiry WEP */
e_SEC_WEP = 0x01,
+ /** Securiry WPA-PSK(TKIP) */
e_SEC_WPA_TKIP = 0x02,
+ /** Securiry WPA2-PSK(AES) */
e_SEC_WPA2_AES = 0x04,
+ /** Securiry WPA2-PSK(TKIP/AES) */
e_SEC_WPA2_MIXED = 0x06,
+ /** Securiry WPA-PSK(AES) */
e_SEC_WPA_AES = 0x07
}E_SECURITY;
+ /** Wi-Fi Network type
+ */
+ typedef enum NETWORK_TYPE {
+ /** Infrastructure */
+ e_INFRA = 0,
+ /** Adhoc */
+ e_ADHOC = 1
+ }E_NETWORK_TYPE;
+
// ----- YDwifi.cpp -----
/** Constructor
* \param tx mbed pin to use for tx line of Serial interface
@@ -63,6 +78,25 @@
unsigned char seq;
}tagGEN_FW_VER_GET_REQ_T;
+ /** WIFI_DISCONNECT_REQ Command */
+ typedef struct
+ {
+ unsigned char cmd_sid;
+ unsigned char seq;
+ }tagWIFI_DISCONNECT_REQ_T;
+
+ /** WIFI_SCAN_REQ Command */
+ typedef struct
+ {
+ unsigned char cmd_sid;
+ unsigned char seq;
+ unsigned char scan_type;
+ unsigned char bss_type;
+ unsigned char bssid[BSSID_MAC_LENTH];
+ unsigned char chan_list;
+ unsigned char ssid[SSID_MAX_LENGTH+1];
+ }tagWIFI_SCAN_REQ_T;
+
static C_YDwifi *mInstance_p;
Mutex mUartMutex;
--- a/YDwifi/YDwifiUartCommand.cpp Tue Mar 11 10:38:36 2014 +0000
+++ b/YDwifi/YDwifiUartCommand.cpp Thu Mar 13 01:34:56 2014 +0000
@@ -42,6 +42,11 @@
return mResponseBuf_p;
}
+void C_YDwifiUartCommand::setScanResultHandler( void (*handler_p)(tagSCAN_RESULT_T *scan_result) )
+{
+ mScanResultHandler_p = handler_p;
+}
+
int C_YDwifiUartCommand::wait()
{
@@ -76,3 +81,39 @@
return ret;
}
+void C_YDwifiUartCommand::scanResultIndicate( unsigned char *payload_p, int payload_len )
+{
+ if( (payload_p == NULL) || (mScanResultHandler_p == NULL) )
+ {
+ return;
+ }
+
+ tagSCAN_RESULT_T scan_result;
+ int ap_count = payload_p[2];
+ unsigned char *ap_info_p = &payload_p[3];
+ int ap_info_idx = 0;
+
+ printf("%d\r\n", ap_count);
+ for( int i = 0; i < ap_count; i++ )
+ {
+ scan_result.channel = ap_info_p[ap_info_idx];
+ ap_info_idx++;
+ scan_result.rssi = (signed)ap_info_p[ap_info_idx];
+ ap_info_idx++;
+ scan_result.security= ap_info_p[ap_info_idx];
+ ap_info_idx++;
+ memcpy( scan_result.bssid, &ap_info_p[ap_info_idx], BSSID_MAC_LENTH );
+ ap_info_idx += BSSID_MAC_LENTH;
+ scan_result.network_type= ap_info_p[ap_info_idx];
+ ap_info_idx++;
+ scan_result.max_rate= ap_info_p[ap_info_idx];
+ ap_info_idx++;
+ ap_info_idx++; // reserved
+ strcpy( scan_result.ssid, (char *)&ap_info_p[ap_info_idx] );
+ ap_info_idx += strlen( (char *)&ap_info_p[ap_info_idx] );
+ ap_info_idx++;
+
+ // Scanresult callback
+ mScanResultHandler_p( &scan_result );
+ }
+}
--- a/YDwifi/YDwifiUartCommand.h Tue Mar 11 10:38:36 2014 +0000
+++ b/YDwifi/YDwifiUartCommand.h Thu Mar 13 01:34:56 2014 +0000
@@ -5,16 +5,40 @@
namespace murata_wifi
{
+/** Max length of SSID */
+#define SSID_MAX_LENGTH 32
+/** Max length of BSSID */
+#define BSSID_MAC_LENTH 6
/** Wait signal ID of UART command */
#define UART_COMMAND_SIGNAL 0x00000001
/** Timeout of UART command wait(ms)*/
#define UART_COMMAND_WAIT_TIMEOUT 10000
+/** Scan result
+*/
+typedef struct {
+ /** Channel */
+ unsigned char channel;
+ /** RSSI */
+ signed char rssi;
+ /** Security type */
+ unsigned char security;
+ /** BSSID */
+ unsigned char bssid[BSSID_MAC_LENTH];
+ /** Network type */
+ unsigned char network_type;
+ /** Max data rate */
+ unsigned char max_rate;
+ /** SSID */
+ char ssid[SSID_MAX_LENGTH+1];
+}tagSCAN_RESULT_T;
+
+/** C_YDwifiUartCommand class
+ */
class C_YDwifiUartCommand
{
public:
-
/** Set Command ID
@param cmd_id Command ID
*/
@@ -54,6 +78,13 @@
@return Pointer of response buffer
*/
unsigned char *getResponseBuf();
+
+ /** Set scan result callback hander
+ @param handler_p Pointer of callback function
+ */
+ void setScanResultHandler( void (*handler_p)(tagSCAN_RESULT_T *scan_result) );
+
+ void scanResultIndicate( unsigned char *payload_p, int payload_len );
/** Checks in the command which is waiting from Command ID and Sub ID.
@param command_id Command ID
@@ -77,6 +108,8 @@
unsigned char mCommandStatus;
/** ResponseData of command response */
unsigned char *mResponseBuf_p;
+ /** Scan result handler */
+ void (*mScanResultHandler_p)(tagSCAN_RESULT_T *scan_result);
};
}
--- a/YDwifi/YDwifi_uartmsg.cpp Tue Mar 11 10:38:36 2014 +0000
+++ b/YDwifi/YDwifi_uartmsg.cpp Thu Mar 13 01:34:56 2014 +0000
@@ -89,7 +89,7 @@
int i;
// get payload length
- payload_len = ( ( (recvdata_p[1] & ~0x80) & 0xff) | ( ( (recvdata_p[2] & ~0xC0) << 7) & 0xff00) );
+ payload_len = ( ( (recvdata_p[1] & ~0x80) & 0xff) | ( ( (recvdata_p[2] & ~0xC0) << 7) & 0xff80) );
// get Command ID
*command_id_p = (recvdata_p[3] & ~0x80);
@@ -104,6 +104,7 @@
*payload_p = (*buf & ~0x80);
payload_p++;
response_len++;
+ isESC = false;
}
else
{
--- a/YDwifiInterface.cpp Tue Mar 11 10:38:36 2014 +0000
+++ b/YDwifiInterface.cpp Thu Mar 13 01:34:56 2014 +0000
@@ -12,7 +12,7 @@
/** MemoryPool for payload of UART response */
MemoryPool<tagMEMPOOL_BLOCK_T, MEMPOOL_PAYLOAD_NUM> gMEMPOOL_PAYLOAD;
-#define UART_REQUEST_PAYLOAD_MAX 512
+#define UART_REQUEST_PAYLOAD_MAX 256
C_YDwifiInterface::C_YDwifiInterface( PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm, int baud):
C_YDwifi(tx, rx, cts, rts, reset, alarm, baud)
@@ -28,7 +28,7 @@
int C_YDwifiInterface::getFWVersion( unsigned char *version_p )
{
- // Get buffer for response payloadfrom MemoryPool
+ // Get buffer for response payload from MemoryPool
tagMEMPOOL_BLOCK_T *payload_buf = gMEMPOOL_PAYLOAD.alloc();
if( payload_buf == NULL )
{
@@ -37,15 +37,15 @@
}
tagGEN_FW_VER_GET_REQ_T req;
- unsigned char payload_array[UART_REQUEST_PAYLOAD_MAX];
- unsigned char command_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned char payload_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned char command_array[UART_REQUEST_PAYLOAD_MAX];
unsigned short payload_len;
unsigned int command_len;
int ret;
// Make request
req.cmd_sid = UART_CMD_SID_GEN_FW_VER_GET_REQ;
- req.seq = mUartRequestSeq++;
+ req.seq = mUartRequestSeq++;
// Make command payload
payload_len = C_YD_UartMsg::makePayload( sizeof(tagGEN_FW_VER_GET_REQ_T), (unsigned char *)&req, payload_array );
@@ -54,7 +54,7 @@
// Set data for response
mUartCommand.setCommandID( UART_CMD_ID_GEN );
- mUartCommand.setCommandSID( UART_CMD_SID_GEN_FW_VER_GET_REQ );
+ mUartCommand.setCommandSID( req.cmd_sid );
mUartCommand.setResponseBuf( payload_buf->buf );
// Send uart command request
@@ -70,7 +70,6 @@
return -1;
}
- printf("getFWversion status:%02x\r\n", mUartCommand.getCommandStatus());
if( mUartCommand.getCommandStatus() == 0 )
{
unsigned char version_len = payload_buf->buf[3];
@@ -79,3 +78,232 @@
gMEMPOOL_PAYLOAD.free( payload_buf );
return 0;
}
+
+int C_YDwifiInterface::connect(const char *ssid_p, unsigned char ssid_len, E_SECURITY sec_type
+ , const char *sec_key_p, unsigned char sec_key_len)
+{
+ // Parameter check(SSID)
+ if( (ssid_p == NULL) || (ssid_len == 0) )
+ {
+ printf( "connect failed [ parameter NG:SSID ]\r\n" );
+ return -1;
+ }
+
+ // Parameter check(Security key)
+ if( (sec_type != e_SEC_OPEN) && ( (sec_key_len == 0) || (sec_key_p == NULL) ) )
+ {
+ printf( "connect failed [ parameter NG:Security key ]\r\n" );
+ return -1;
+ }
+
+ // Get buffer for response payloadfrom MemoryPool
+ tagMEMPOOL_BLOCK_T *payload_buf = gMEMPOOL_PAYLOAD.alloc();
+ if( payload_buf == NULL )
+ {
+ printf("connect payload_buf NULL\r\n");
+ return -1;
+ }
+
+ unsigned char buf[UART_REQUEST_PAYLOAD_MAX];
+ unsigned char payload_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned char command_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned int buf_len = 0;
+ unsigned short payload_len;
+ unsigned int command_len;
+ int ret;
+
+ memset( buf, 0, UART_REQUEST_PAYLOAD_MAX );
+ // Make request
+ buf[0] = UART_CMD_SID_WIFI_JOIN_REQ;
+ buf_len++;
+ buf[1] = mUartRequestSeq++;
+ buf_len++;
+ // SSID
+ memcpy( &buf[2], ssid_p, ssid_len );
+ buf_len += ssid_len;
+ buf_len++;
+
+ // Security mode
+ buf[ buf_len ] = (unsigned char)sec_type;
+ buf_len++;
+
+ // Security key
+ if( sec_type != e_SEC_OPEN )
+ {
+ buf[ buf_len ] = sec_key_len;
+ buf_len++;
+ if( sec_key_len > 0 )
+ {
+ memcpy( &buf[buf_len], sec_key_p, sec_key_len );
+ buf_len += sec_key_len;
+ }
+ }
+ // Make command payload
+ payload_len = C_YD_UartMsg::makePayload( buf_len, (unsigned char *)buf, payload_array );
+ // Make all command request
+ command_len = C_YD_UartMsg::makeRequest( UART_CMD_ID_WIFI, payload_array, payload_len, command_array );
+ // Set data for response
+ mUartCommand.setCommandID( UART_CMD_ID_WIFI );
+ mUartCommand.setCommandSID( UART_CMD_SID_WIFI_JOIN_REQ );
+ mUartCommand.setResponseBuf( payload_buf->buf );
+
+ // Send uart command request
+ sendUart( command_len, command_array );
+
+ // Wait UART response
+ ret = mUartCommand.wait();
+ if( ret != 0 )
+ {
+ printf( "join failed\r\n" );
+ gMEMPOOL_PAYLOAD.free( payload_buf );
+ return -1;
+ }
+
+ if( mUartCommand.getCommandStatus() != 0 )
+ {
+ printf("join status:%02x\r\n", mUartCommand.getCommandStatus());
+ ret = -1;
+ }
+ gMEMPOOL_PAYLOAD.free( payload_buf );
+
+ return ret;
+}
+
+int C_YDwifiInterface::disconnect()
+{
+ // Get buffer for response payloadfrom MemoryPool
+ tagMEMPOOL_BLOCK_T *payload_buf = gMEMPOOL_PAYLOAD.alloc();
+ if( payload_buf == NULL )
+ {
+ printf("disconnect payload_buf NULL\r\n");
+ return -1;
+ }
+
+ tagWIFI_DISCONNECT_REQ_T req;
+ unsigned char payload_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned char command_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned short payload_len;
+ unsigned int command_len;
+ int ret;
+
+ // Make request
+ req.cmd_sid = UART_CMD_SID_WIFI_DISCONNECT_REQ;
+ req.seq = mUartRequestSeq++;
+
+ // Make command payload
+ payload_len = C_YD_UartMsg::makePayload( sizeof(tagWIFI_DISCONNECT_REQ_T), (unsigned char *)&req, payload_array );
+ // Make all command request
+ command_len = C_YD_UartMsg::makeRequest( UART_CMD_ID_WIFI, payload_array, payload_len, command_array );
+
+ // Set data for response
+ mUartCommand.setCommandID( UART_CMD_ID_WIFI );
+ mUartCommand.setCommandSID( req.cmd_sid );
+ mUartCommand.setResponseBuf( payload_buf->buf );
+
+ // Send uart command request
+ sendUart( command_len, command_array );
+
+ // Wait UART response
+ ret = mUartCommand.wait();
+ if( ret != 0 )
+ {
+ printf( "disconnect failed\r\n" );
+ gMEMPOOL_PAYLOAD.free( payload_buf );
+ return -1;
+ }
+
+ if( mUartCommand.getCommandStatus() != 0 )
+ {
+ printf("disconnect status:%02x\r\n", mUartCommand.getCommandStatus());
+ ret = -1;
+ }
+ gMEMPOOL_PAYLOAD.free( payload_buf );
+ return 0;
+}
+
+int C_YDwifiInterface::scan( const char *ssid_p, unsigned char *bssid_p
+ , void (*result_handler_p)(tagSCAN_RESULT_T *scan_result) )
+{
+ // Get buffer for response payloadfrom MemoryPool
+ tagMEMPOOL_BLOCK_T *payload_buf = gMEMPOOL_PAYLOAD.alloc();
+ if( payload_buf == NULL )
+ {
+ printf("scan payload_buf NULL\r\n");
+ return -1;
+ }
+
+ tagWIFI_SCAN_REQ_T req;
+ unsigned char payload_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned char command_array[UART_REQUEST_PAYLOAD_MAX];
+ unsigned short payload_len;
+ unsigned int command_len;
+ unsigned int buf_len = 0;
+ int ret;
+
+ memset( &req, 0, sizeof(tagWIFI_SCAN_REQ_T) );
+ // Make request
+ req.cmd_sid = UART_CMD_SID_WIFI_SCAN_REQ;
+ buf_len++;
+ req.seq = mUartRequestSeq++;
+ buf_len++;
+
+ // Set scan type(Active scan)
+ req.scan_type = 0;
+ buf_len++;
+ // Set bss type(any)
+ req.bss_type = 2;
+ buf_len++;
+ // Set BSSID
+ if( bssid_p != NULL )
+ {
+ memcpy( req.bssid, bssid_p, BSSID_MAC_LENTH );
+ }
+ buf_len += BSSID_MAC_LENTH;
+ // Set channel list(0)
+ req.chan_list = 0;
+ buf_len++;
+ //Set SSID
+ if( ssid_p != NULL )
+ {
+ strcpy( (char *)req.ssid, ssid_p );
+ buf_len += strlen(ssid_p);
+ }
+ else
+ {
+ buf_len++;
+ }
+
+ // Make command payload
+ payload_len = C_YD_UartMsg::makePayload( buf_len, (unsigned char *)&req, payload_array );
+ // Make all command request
+ command_len = C_YD_UartMsg::makeRequest( UART_CMD_ID_WIFI, payload_array, payload_len, command_array );
+
+ // Set data for response
+ mUartCommand.setCommandID( UART_CMD_ID_WIFI );
+ mUartCommand.setCommandSID( req.cmd_sid );
+ mUartCommand.setResponseBuf( payload_buf->buf );
+ // Set scan result callback
+ mUartCommand.setScanResultHandler( result_handler_p );
+
+ // Send uart command request
+ sendUart( command_len, command_array );
+
+ // Wait UART response
+ ret = mUartCommand.wait();
+ printf( "scan wait:%d\r\n", ret );
+ if( ret != 0 )
+ {
+ printf( "scan failed\r\n" );
+ gMEMPOOL_PAYLOAD.free( payload_buf );
+ return -1;
+ }
+
+ if( mUartCommand.getCommandStatus() != 0 )
+ {
+ printf("scan status:%02x\r\n", mUartCommand.getCommandStatus());
+ ret = -1;
+ }
+ gMEMPOOL_PAYLOAD.free( payload_buf );
+
+ return 0;
+}
\ No newline at end of file
--- a/YDwifiInterface.h Tue Mar 11 10:38:36 2014 +0000
+++ b/YDwifiInterface.h Thu Mar 13 01:34:56 2014 +0000
@@ -6,9 +6,10 @@
namespace murata_wifi
{
+/** C_YDwifiInterface class
+ */
class C_YDwifiInterface: public C_YDwifi {
public:
-
/** Constructor
@param tx mbed pin to use for tx line of Serial interface
@param rx mbed pin to use for rx line of Serial interface
@@ -33,23 +34,40 @@
*/
int getFWVersion( unsigned char *version_p );
-#if 0
- /** Connect
- * Bring the interface up, start DHCP if needed.
- * \param sec the Wi-Fi security type
- * \param ssid the Wi-Fi SSID
- * \param phrase the Wi-Fi passphrase or security key
- * \param mode the Wi-Fi mode
- * \return 0 on success, a negative number on failure
- */
- int connect(Security sec, const char* ssid, const char* phrase, WiFiMode mode = WM_INFRASTRUCTURE);
+ /** Connect to AP
+ @param ssid_p Wi-Fi SSID(null terminated)
+ @param ssid_len Wi-Fi SSID length
+ @param sec_type Wi-Fi security type.
+ @param sec_key_len Wi-Fi passphrase or security key length
+ @param sec_key_p Wi-Fi passphrase or security key
+ @return 0 on success, a negative number on failure
+ @note This function is blocked until a returns.
+ When you use it by UI thread, be careful.
+ */
+ int connect(const char *ssid_p, unsigned char ssid_len, E_SECURITY sec_type, const char *sec_key_p, unsigned char sec_key_len);
- /** Disconnect
- * Bring the interface down
- * \return 0 on success, a negative number on failure
- */
- int disconnect();
-
+ /** Disconnect from AP
+ @return 0 on success, a negative number on failure
+ @note This function is blocked until a returns.
+ When you use it by UI thread, be careful.
+ */
+ int disconnect();
+
+ /** Scan AP
+ @param ssid_p Wi-Fi SSID(null terminated)
+ If do not specify SSID, set to NULL.
+ @param bssid_p Wi-Fi BSSID(null terminated)
+ If do not specify SSID, set to NULL.
+ @param result_handler_p Pointer of scan result callback function.
+ @return 0 on success, a negative number on failure
+ @note This function is blocked until a returns.
+ When you use it by UI thread, be careful.
+ Scan results will be notified by asynchronous callback function.
+ */
+ int scan( const char *ssid_p, unsigned char *bssid_p
+ ,void (*result_handler_p)(tagSCAN_RESULT_T *scan_result) );
+
+#if 0
/** Get the MAC address of your Ethernet interface
* \return a pointer to a string containing the MAC address
*/
@@ -72,5 +90,4 @@
#endif
};
}
-
#endif /* _YD_WIFIINTERFACE_H_ */
\ No newline at end of file
ban4jp -
