Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
Revision 58:03b89038b21a, committed 2013-09-27
- Comitter:
- nyatla
- Date:
- Fri Sep 27 12:47:51 2013 +0000
- Parent:
- 57:bc4330dfa62f
- Child:
- 59:cb5c3184c59f
- Commit message:
- add classes; checked:modwebsocket; unchecked:tcpsocket,udpsocket,httpclient.;
Changed in this revision
--- a/core/NyLPC_cMiMicEnv.h Fri Sep 13 06:38:16 2013 +0000 +++ b/core/NyLPC_cMiMicEnv.h Fri Sep 27 12:47:51 2013 +0000 @@ -13,7 +13,7 @@ #endif /* __cplusplus */ -#define NyLPC_cMiMicEnv_VERSION "MiMic/1.4.62" +#define NyLPC_cMiMicEnv_VERSION "MiMic/1.4.71" #ifdef __cplusplus
--- a/core/http/NyLPC_cHttpBasicHeaderParser.c Fri Sep 13 06:38:16 2013 +0000
+++ b/core/http/NyLPC_cHttpBasicHeaderParser.c Fri Sep 27 12:47:51 2013 +0000
@@ -26,6 +26,8 @@
#include "NyLPC_cHttpBasicHeaderParser_protected.h"
#include <stdlib.h>
+#define HTTP_TIMEOUT NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT
+
static const struct NyLPC_TTextIdTbl method_id_table[]=
{
//HTTP STANDARD
@@ -245,7 +247,7 @@
NyLPC_TInt32 rsize;
for(;;){
//タイムアウト付でストリームから読み出し。
- rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base));
+ rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base),HTTP_TIMEOUT);
if(rsize<=0){
return NyLPC_TBool_FALSE;
}
--- a/core/http/NyLPC_cHttpBodyParser.c Fri Sep 13 06:38:16 2013 +0000
+++ b/core/http/NyLPC_cHttpBodyParser.c Fri Sep 27 12:47:51 2013 +0000
@@ -1,5 +1,7 @@
#include "NyLPC_cHttpBodyParser.h"
+#define HTTP_TIMEOUT NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT
+
static NyLPC_TBool bodyHandler(NyLPC_TcHttpBasicBodyParser_t* i_inst,NyLPC_TChar i_c)
{
NyLPC_TcHttpBodyParser_t* inst=(NyLPC_TcHttpBodyParser_t*)i_inst;
@@ -40,7 +42,7 @@
}
for(;;){
//タイムアウト付でストリームから読み出し。
- rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base));
+ rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base),HTTP_TIMEOUT);
if(rsize<=0){
//Read失敗
return NyLPC_TBool_FALSE;
--- a/core/http/NyLPC_cHttpStream.c Fri Sep 13 06:38:16 2013 +0000
+++ b/core/http/NyLPC_cHttpStream.c Fri Sep 27 12:47:51 2013 +0000
@@ -67,17 +67,14 @@
#endif
-static NyLPC_TInt32 pread_func(void* i_inst,const void** o_buf_ptr);
+static NyLPC_TInt32 pread_func(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_timeout);
static NyLPC_TBool write_func(void* i_inst,const void* i_data,NyLPC_TInt32 i_length);
static void pseek_func(void* i_inst,NyLPC_TUInt16 i_seek);
static NyLPC_TBool flush_func(void* i_inst);
static void setReadEncoding_func(void* i_inst,NyLPC_TiHttpPtrStream_ET i_et);
static void setWriteEncoding_func(void* i_inst,NyLPC_TiHttpPtrStream_ET i_et);
-/**
- * HTTP送受信のタイムアウト値
- */
-#define HTTP_TIMEOUT 5*1000
+
/**
* HTTP送信バッファのヒント値
*/
@@ -130,10 +127,10 @@
// インタフェイス
//
-static NyLPC_TInt32 pread_func(void* i_inst,const void** o_buf_ptr)
+static NyLPC_TInt32 pread_func(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_timeout)
{
NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst;
- return NyLPC_cTcpSocket_precv(inst->_ref_sock,o_buf_ptr,HTTP_TIMEOUT);
+ return NyLPC_cTcpSocket_precv(inst->_ref_sock,o_buf_ptr,i_timeout);
}
static NyLPC_TBool write_func(void* i_inst,const void* i_data,NyLPC_TInt32 i_length)
@@ -146,7 +143,7 @@
while(l>0){
//送信バッファがNULLなら、割り当て。
if(inst->txb==NULL){
- inst->txb=(NyLPC_TUInt8*)NyLPC_cTcpSocket_allocSendBuf(inst->_ref_sock,HTTP_TX_BUF_HINT,&s,HTTP_TIMEOUT);
+ inst->txb=(NyLPC_TUInt8*)NyLPC_cTcpSocket_allocSendBuf(inst->_ref_sock,HTTP_TX_BUF_HINT,&s,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT);
if(inst->txb==NULL){
return NyLPC_TBool_FALSE;
}
@@ -205,7 +202,7 @@
inst->tx_len+=2;
}
//送信する。
- if(!NyLPC_cTcpSocket_psend(inst->_ref_sock,inst->txb,inst->tx_len,HTTP_TIMEOUT)){
+ if(!NyLPC_cTcpSocket_psend(inst->_ref_sock,inst->txb,inst->tx_len,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT)){
//失敗。
NyLPC_cTcpSocket_releaseSendBuf(inst->_ref_sock,inst->txb);
inst->txb=NULL;
--- a/core/http/NyLPC_iHttpPtrStream.h Fri Sep 13 06:38:16 2013 +0000 +++ b/core/http/NyLPC_iHttpPtrStream.h Fri Sep 27 12:47:51 2013 +0000 @@ -49,8 +49,13 @@ #define NyLPC_TiHttpPtrStream_ET_NONE 0x00 #define NyLPC_TiHttpPtrStream_ET_CHUNKED 0x01 +/** + * HTTP通信タイムアウトのデフォルト値 + */ +#define NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT (5*1000) -typedef NyLPC_TInt32 (*NyLPC_TiHttpPtrStream_pread)(void* i_inst,const void** o_buf_ptr); + +typedef NyLPC_TInt32 (*NyLPC_TiHttpPtrStream_pread)(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_timeout); typedef NyLPC_TBool (*NyLPC_TiHttpPtrStream_write)(void* i_inst,const void* i_data,NyLPC_TInt32 i_length); typedef void (*NyLPC_TiHttpPtrStream_rseek)(void* i_inst,NyLPC_TUInt16 i_seek); typedef NyLPC_TBool (*NyLPC_TiHttpPtrStream_flush)(void* i_inst); @@ -84,7 +89,7 @@ * 0の場合はタイムアウトです。 * 0未満の場合はエラーです。 */ -#define NyLPC_iHttpPtrStream_pread(i_inst,o_buf_ptr) (i_inst)->absfunc->pread((i_inst),(o_buf_ptr)) +#define NyLPC_iHttpPtrStream_pread(i_inst,o_buf_ptr,i_timeout) (i_inst)->absfunc->pread((i_inst),(o_buf_ptr),i_timeout) /** * ストリームへデータを書き込みます。 * @param i_length
--- a/core/net/httpcl/NyLPC_cHttpClient.c Fri Sep 13 06:38:16 2013 +0000
+++ b/core/net/httpcl/NyLPC_cHttpClient.c Fri Sep 27 12:47:51 2013 +0000
@@ -56,7 +56,7 @@
* TRUE - ステータスはIDLEへ遷移する。
* FALSE - ステータスはCLOSEDへ遷移する。
*/
-NyLPC_TBool NyLPC_cHttpClient_connect(NyLPC_TcHttpClient_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port)
+NyLPC_TBool NyLPC_cHttpClient_connect(NyLPC_TcHttpClient_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port)
{
//ステータスをclosedへ遷移
NyLPC_cHttpClient_close(i_inst);
@@ -148,7 +148,7 @@
* @return
* 0:EOF
*/
-NyLPC_TBool NyLPC_cHttpClient_write(NyLPC_TcHttpClient_t* i_inst,void* i_buf,NyLPC_TUInt32 i_buf_size)
+NyLPC_TBool NyLPC_cHttpClient_write(NyLPC_TcHttpClient_t* i_inst,const void* i_buf,NyLPC_TUInt32 i_buf_size)
{
if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){
return NyLPC_TBool_FALSE;
--- a/core/net/httpcl/NyLPC_cHttpClient.h Fri Sep 13 06:38:16 2013 +0000 +++ b/core/net/httpcl/NyLPC_cHttpClient.h Fri Sep 27 12:47:51 2013 +0000 @@ -54,7 +54,7 @@ * TRUE - ステータスはIDLEへ遷移する。 * FALSE - ステータスはCLOSEDへ遷移する。 */ -NyLPC_TBool NyLPC_cHttpClient_connect(NyLPC_TcHttpClient_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port); +NyLPC_TBool NyLPC_cHttpClient_connect(NyLPC_TcHttpClient_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port); @@ -85,7 +85,7 @@ * TRUE - 成功。 * FALSE - 失敗。ステータスはCLOSEDになる。 */ -NyLPC_TBool NyLPC_cHttpClient_write(NyLPC_TcHttpClient_t* i_inst,void* i_buf,NyLPC_TUInt32 i_buf_size); +NyLPC_TBool NyLPC_cHttpClient_write(NyLPC_TcHttpClient_t* i_inst,const void* i_buf,NyLPC_TUInt32 i_buf_size); /** * 書式文字列としてPOSTリクエストのデータを送信する。
--- a/core/net/httpd/mod/NyLPC_cModWebSocket.c Fri Sep 13 06:38:16 2013 +0000
+++ b/core/net/httpd/mod/NyLPC_cModWebSocket.c Fri Sep 27 12:47:51 2013 +0000
@@ -23,10 +23,10 @@
* <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
*
*********************************************************************************/
-#include "NyLPC_cModWebSocket.h"
+#include "NyLPC_cModWebSocket_protected.h"
#include "NyLPC_utils.h"
-
+#define HTTP_TIMEOUT NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT
#define NyLPC_TcModWebSocket_FRAME_TYPE_BIN 0x01
#define NyLPC_TcModWebSocket_FRAME_TYPE_TXT 0x02
@@ -145,9 +145,7 @@
messageHandler,
NULL
};
-#define NyLPC_TcModWebSocket_ST_START_PAYLOAD 0x01
-#define NyLPC_TcModWebSocket_ST_READ_PAYLOAD 0x02
-#define NyLPC_TcModWebSocket_ST_CLOSED 0x03
+
/**
@@ -275,6 +273,7 @@
if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),"\r\n\r\n",4)){
NyLPC_OnErrorGoto(Error3);
}
+ //connection phase
i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
}
//占有解除
@@ -310,24 +309,30 @@
}
-#define FLAGS_MASK_BIT 7
-/**
- * @return
- * n>0:データ受信
- * 0 :タイムアウト。コネクションの状態は変化しない。
- * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
- */
-NyLPC_TInt16 NyLPC_cModWebSocket_read(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_buf_len)
+NyLPC_TBool NyLPC_cModWebSocket_canRead(const NyLPC_TcModWebSocket_t* i_inst)
{
const NyLPC_TUInt8* rx;
- NyLPC_TInt32 rs,i;
+ return NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,0)>0;
+}
+
+#define FLAGS_MASK_BIT 7
+
+/**
+ * Websocketの状態を更新します。
+ * @return
+ */
+void NyLPC_cModWebSocket_update(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt32 i_time_out)
+{
+ const NyLPC_TUInt8* rx;
+ NyLPC_TInt32 rs;
NyLPC_TUInt16 header_size;
NyLPC_TUInt8 w8[2];
if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
- return -1;
+ return;
}
START:
- rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
+ rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,i_time_out);
+
//Error?
if(rs<0){
NyLPC_OnErrorGoto(Error);
@@ -337,6 +342,9 @@
goto Timeout;
}
switch(i_inst->_payload_st){
+ case NyLPC_TcModWebSocket_ST_READ_PAYLOAD:
+ //ペイロード読み出し中破何もしない
+ return;
case NyLPC_TcModWebSocket_ST_START_PAYLOAD:
//ペイロード
//2バイト溜まるまで待つ
@@ -404,7 +412,7 @@
NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
while(i_inst->payload_size!=i_inst->payload_ptr){
- rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
+ rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT);
if(rs<=0){
if(rs<0){
//Error
@@ -414,7 +422,6 @@
goto Timeout;
}
//読み込みサイズを決定
- rs=(rs<i_buf_len)?rs:i_buf_len;
NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rx,rs);
NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
i_inst->payload_ptr+=rs;
@@ -425,7 +432,7 @@
//パケットの読み捨て
NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
while(i_inst->payload_size!=i_inst->payload_ptr){
- rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
+ rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT);
if(rs<=0){
if(rs<0){
//Error
@@ -435,7 +442,6 @@
goto Timeout;
}
//読み込みサイズを決定
- rs=(rs<i_buf_len)?rs:i_buf_len;
NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
i_inst->payload_ptr+=rs;
}
@@ -450,34 +456,67 @@
//ペイロード読み出しへ
i_inst->_payload_st=NyLPC_TcModWebSocket_ST_READ_PAYLOAD;
//継続してペイロード受信処理
+ return;
+ }
+ //処理されなければエラー
+Error:
+ NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+ i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+ return;
+Timeout:
+ return;
+}
+
+/**
+ * @return
+ * n>0:データ受信
+ * 0 :タイムアウト。コネクションの状態は変化しない。
+ * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
+ */
+NyLPC_TInt16 NyLPC_cModWebSocket_read(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_buf_len)
+{
+ const NyLPC_TUInt8* rx;
+ NyLPC_TInt32 rs,i;
+ //ストリームの状態を更新する。
+ NyLPC_cModWebSocket_update(i_inst,HTTP_TIMEOUT);
+
+ switch(i_inst->_payload_st)
+ {
case NyLPC_TcModWebSocket_ST_READ_PAYLOAD:
- rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
- if(rs<=0){
- if(rs<0){
- //Error
- NyLPC_OnErrorGoto(Error);
- }
- //Timeout
- goto Timeout;
+ break;//処理継続
+ case NyLPC_TcModWebSocket_ST_START_PAYLOAD:
+ //タイムアウト扱い
+ return 0;
+ default:
+ return -1;
+ }
+ //読み出し可能なデータをパース
+ rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT);
+ if(rs<=0){
+ if(rs<0){
+ //Error
+ NyLPC_OnErrorGoto(Error);
}
- //読み込みサイズを決定
- rs=(rs<i_buf_len)?rs:i_buf_len;
- //アンマスク
- if(NyLPC_TUInt8_isBitOn(i_inst->_frame_flags_bits,FLAGS_MASK_BIT)){
- for(i=0;i<rs;i++){
- *(((NyLPC_TUInt8*)i_buf)+i)=rx[i]^i_inst->_frame_mask[(i_inst->payload_ptr+i)%4];
- }
- }else{
- memcpy(i_buf,rx,rs);
+ //Timeout
+ goto Timeout;
+ }
+ //読み込みサイズを決定
+ rs=(rs<i_buf_len)?rs:i_buf_len;
+ //アンマスク
+ if(NyLPC_TUInt8_isBitOn(i_inst->_frame_flags_bits,FLAGS_MASK_BIT)){
+ for(i=0;i<rs;i++){
+ *(((NyLPC_TUInt8*)i_buf)+i)=rx[i]^i_inst->_frame_mask[(i_inst->payload_ptr+i)%4];
}
- //読取位置を移動
- NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
- i_inst->payload_ptr+=rs;
- if(i_inst->payload_size==i_inst->payload_ptr){
- i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
- }
- return rs;
+ }else{
+ memcpy(i_buf,rx,rs);
}
+ //読取位置を移動
+ NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
+ i_inst->payload_ptr+=rs;
+ if(i_inst->payload_size==i_inst->payload_ptr){
+ i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
+ }
+ return rs;
//処理されなければエラー
Error:
NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
@@ -487,71 +526,30 @@
return 0;
}
+
+
+
static NyLPC_TBool fmt_handler(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len)
{
return NyLPC_iHttpPtrStream_write((NyLPC_TiHttpPtrStream_t*)i_inst,i_buf,i_len);
}
-NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
+
+/**
+ * Payloadヘッダを書く。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_writePayloadHeader(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TInt16 i_len)
{
- va_list a;
- NyLPC_TInt16 l;
NyLPC_TUInt16 s;
NyLPC_TChar w[4];
- //データサイズで切り分け
- if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
+ //CLOSED,CONNECTの時は使用不可
+ switch(i_inst->_payload_st){
+ case NyLPC_TcModWebSocket_ST_CLOSED:
return NyLPC_TBool_FALSE;
- }
- //書式文字列の長さを計算
- va_start(a,i_fmt);
- l=NyLPC_cFormatWriter_length(i_fmt,a);
- va_end(a);
- switch(i_inst->_frame_type)
- {
- case NyLPC_TcModWebSocket_FRAME_TYPE_TXT:
- w[0]=0x80|0x01;
+ default:
break;
- case NyLPC_TcModWebSocket_FRAME_TYPE_BIN:
- w[0]=0x80|0x02;
- break;
- default:
- NyLPC_OnErrorGoto(Error);
- }
- if(l<126){
- w[1]=(NyLPC_TUInt8)l;
- s=2;
- }else{
- w[1]=126;
- s=3;
- *((NyLPC_TUInt16*)(&(w[2])))=NyLPC_htons(l);
}
- if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,s)){
- //CLOSE
- NyLPC_OnErrorGoto(Error);
- }
- va_start(a,i_fmt);
- if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,a)){
- va_end(a);
- NyLPC_OnErrorGoto(Error);
- }
- va_end(a);
- NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
- return NyLPC_TBool_TRUE;
-Error:
- NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
- i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
- return NyLPC_TBool_FALSE;
-}
-
-NyLPC_TBool NyLPC_cModWebSocket_write(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_len)
-{
- NyLPC_TChar w[4];
- NyLPC_TUInt16 s;
//データサイズで切り分け
- if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
- return NyLPC_TBool_FALSE;
- }
- //OP CODE
switch(i_inst->_frame_type)
{
case NyLPC_TcModWebSocket_FRAME_TYPE_TXT:
@@ -575,6 +573,54 @@
//CLOSE
NyLPC_OnErrorGoto(Error);
}
+ return NyLPC_TBool_TRUE;
+Error:
+ return NyLPC_TBool_FALSE;
+}
+
+
+
+
+NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
+{
+ NyLPC_TInt16 l;
+ va_list a;
+ //ストリームの状態を更新する。
+ NyLPC_cModWebSocket_update(i_inst,0);
+
+ //書式文字列の長さを計算
+ va_start(a,i_fmt);
+ l=NyLPC_cFormatWriter_length(i_fmt,a);
+ va_end(a);
+ if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,l)){
+ //CLOSE
+ NyLPC_OnErrorGoto(Error);
+ }
+ va_start(a,i_fmt);
+ if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,a)){
+ va_end(a);
+ NyLPC_OnErrorGoto(Error);
+ }
+ va_end(a);
+ NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
+ return NyLPC_TBool_TRUE;
+Error:
+ NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+ i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+ return NyLPC_TBool_FALSE;
+}
+
+
+
+
+NyLPC_TBool NyLPC_cModWebSocket_write(NyLPC_TcModWebSocket_t* i_inst,const void* i_buf,NyLPC_TInt16 i_len)
+{
+ //ストリームの状態を更新する。
+ NyLPC_cModWebSocket_update(i_inst,0);
+ if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,i_len)){
+ //CLOSE
+ NyLPC_OnErrorGoto(Error);
+ }
if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_buf,i_len)){
//CLOSE
NyLPC_OnErrorGoto(Error);
@@ -589,6 +635,9 @@
void NyLPC_cModWebSocket_close(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code)
{
+ //ストリームの状態を更新する。
+ NyLPC_cModWebSocket_update(i_inst,0);
+
if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
return;
}
--- a/core/net/httpd/mod/NyLPC_cModWebSocket.h Fri Sep 13 06:38:16 2013 +0000 +++ b/core/net/httpd/mod/NyLPC_cModWebSocket.h Fri Sep 27 12:47:51 2013 +0000 @@ -46,6 +46,20 @@ #define NyLPC_TcModWebSocket_FRAME_TYPE_BIN 0x01 #define NyLPC_TcModWebSocket_FRAME_TYPE_TXT 0x02 +typedef NyLPC_TUInt8 NyLPC_TcModWebSocket_ST; +/** + * パケットヘッダの受信待ちである。 + */ +#define NyLPC_TcModWebSocket_ST_START_PAYLOAD 0x02 +/** + * ペイロードの読み取り中である。 + */ +#define NyLPC_TcModWebSocket_ST_READ_PAYLOAD 0x03 +/** + * WebSocketは閉じられた。 + */ +#define NyLPC_TcModWebSocket_ST_CLOSED 0x04 + /** * クラス構造体 */ @@ -57,7 +71,7 @@ */ const NyLPC_TChar* _ref_sub_protocol; /**ペイロードの解析ステータス*/ - NyLPC_TUInt8 _payload_st; + NyLPC_TcModWebSocket_ST _payload_st; NyLPC_TUInt8 _frame_type; /** * BIT0: MASK value @@ -88,9 +102,18 @@ */ NyLPC_TBool NyLPC_cModWebSocket_execute(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection); +/** + * NyLPC_cModWebSocket_read関数がブロック無しに完了できるかを返します。 + * NyLPC_cModWebSocket_readで処理をブロックしたくない場合に使います。 + * アプリケーションはこの関数を頻繁にチェックして、trueの場合は速やかにNyLPC_cModWebSocket_readを実行してください。 + */ +NyLPC_TBool NyLPC_cModWebSocket_canRead(const NyLPC_TcModWebSocket_t* i_inst); + + /** - * i_bufに最大i_buf_lenバイトのデータを受信します。 + * ストリームからデータを受信して、可能ならi_bufに最大i_buf_lenバイトのデータを受信します。 + * この関数はデータ以外のパケットも処理します。 * @return * n>0:受信成功。nバイトのデータを受信した。 * 0 :タイムアウト。コネクションの状態は変化しない。 @@ -99,18 +122,21 @@ NyLPC_TInt16 NyLPC_cModWebSocket_read(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_buf_len); /** * i_bufからi_lenバイトのデータを送信します。データは1ペーロードとしてクライアントへ送信されます。 + * この関数はデータ以外のパケットも処理します。 * @return * true: 送信に成功した。 * false:送信に失敗した。 コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。 */ -NyLPC_TBool NyLPC_cModWebSocket_write(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_len); +NyLPC_TBool NyLPC_cModWebSocket_write(NyLPC_TcModWebSocket_t* i_inst,const void* i_buf,NyLPC_TInt16 i_len); /** * 書式文字列を出力します。 */ NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...); + /** * CLOSEパケットを送信してコネクションを閉じます。 + * この関数はデータ以外のパケットも処理します。 * i_codeにはWebsocketのコード */ void NyLPC_cModWebSocket_close(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/httpd/mod/NyLPC_cModWebSocket_protected.h Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,47 @@
+#ifndef NYLPC_CMODWEBSOCKET_PROTECTED_H_
+#define NYLPC_CMODWEBSOCKET_PROTECTED_H_
+
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ * http://nyatla.jp/
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
+#include "NyLPC_cModWebSocket.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Payloadヘッダを書く。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_writePayloadHeader(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TInt16 i_len);
+
+void NyLPC_cModWebSocket_update(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt32 i_time_out);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NYLPC_CMODWEBSOCKET_H_ */
--- a/core/uip/NyLPC_cTcpSocket.c Fri Sep 13 06:38:16 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket.c Fri Sep 27 12:47:51 2013 +0000
@@ -292,7 +292,7 @@
{
int i;
struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq;
- while(!NyLPC_cStopwatch_isExpired(i_timer)){
+ do{
//クローズドに遷移してしまったら、エラーである。
if(i_inst->tcpstateflags==UIP_CLOSED){
return NULL;
@@ -310,7 +310,7 @@
i=i_inst->txbuf.wp;
i_inst->txbuf.wp=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ;
return &(q[i]);
- }
+ }while(!NyLPC_cStopwatch_isExpired(i_timer));
//失敗。タイムアウト。
return NULL;
}
@@ -424,7 +424,7 @@
{
NyLPC_TUInt8 f;
lockResource(i_inst);
- while(!NyLPC_cStopwatch_isExpired(i_timer)){
+ do{
//パケットが送信中か調べる。
if(!isPacketAcked(i_inst,i_sq)){
//まだある場合は、タスクスイッチを繰り返して消失を待つ。
@@ -437,7 +437,7 @@
f=i_inst->tcpstateflags;
unlockResource(i_inst);
return (f==UIP_CLOSED)?NyLPC_TBool_FALSE:NyLPC_TBool_TRUE;
- }
+ }while(!NyLPC_cStopwatch_isExpired(i_timer));
unlockResource(i_inst);
return NyLPC_TBool_FALSE;
}
@@ -591,7 +591,7 @@
* Public function
*/
-NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec)
+NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec)
{
volatile NyLPC_TUInt8 f;
NyLPC_TUInt32 sq;
@@ -729,10 +729,8 @@
//ESTABLISHED以外の場合は、エラー。
NyLPC_cStopwatch_setNow(&sw);
- while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec)
- {
+ do{
//読み出しバッファ情報のコピー
-
//MUTEX LOCK
lockResource(i_inst);
st=i_inst->tcpstateflags;
@@ -764,7 +762,7 @@
}
//タスクスイッチ
NyLPC_cThread_yield();
- };
+ }while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec);
//規定時間内に受信が成功しなかった。
NyLPC_cStopwatch_finalize(&sw);
return 0;
@@ -998,7 +996,7 @@
//再ロック
lockResource(i_inst);
//タイムアウトするか、UIP_CLOSED、もしくはTIME_WAITに遷移するのを待つ。(遷移はRxprocで自動的に実行。)
- while(!NyLPC_cStopwatch_isExpired(&sw)){
+ do{
switch(i_inst->tcpstateflags)
{
case UIP_TIME_WAIT:
@@ -1017,7 +1015,7 @@
default:
break;
}
- }
+ }while(!NyLPC_cStopwatch_isExpired(&sw));
unlockResource(i_inst);
}
}
--- a/core/uip/NyLPC_cTcpSocket.h Fri Sep 13 06:38:16 2013 +0000 +++ b/core/uip/NyLPC_cTcpSocket.h Fri Sep 27 12:47:51 2013 +0000 @@ -216,7 +216,7 @@ /** * TCPソケットをクライアントとしてサーバへ接続します。 */ -NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec); +NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec); #ifdef __cplusplus
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/HttpClient.cpp Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,80 @@
+#include "HttpClient.h"
+
+namespace MiMic
+{
+ HttpClient::HttpClient()
+ {
+ this->_private_tcp_rx_buf=malloc(256);
+ NyLPC_cHttpClient_initialize(&this->_inst,this->_private_tcp_rx_buf,256);
+ }
+ HttpClient::~HttpClient()
+ {
+ NyLPC_cHttpClient_finalize(&this->_inst);
+ if(this->_private_tcp_rx_buf!=NULL){
+ free(this->_private_tcp_rx_buf);
+ }
+ }
+ bool HttpClient::connect(const IpAddr& i_host,unsigned short i_port)
+ {
+ return NyLPC_cHttpClient_connect(&this->_inst,&i_host.addr.v4,i_port)?true:false;
+ }
+ /**
+ * This function sends a request to server and prevent to accept status code.
+ * Must call getStatus after successful.
+ * If request has content body(i_content_length!=0), call writeX function to send request body in before to call getStatus
+ * @return
+ * true if successful,
+ * otherwise error. Connection is closed.
+ * @example
+ * <code>
+ * //GET
+ * </code>
+ * <code>
+ * //POST
+ *
+ * </code>
+ */
+ bool HttpClient::sendMethod(NyLPC_THttpMethodType i_method,const char* i_path,int i_content_length,const char* i_mimetype,const char* i_additional_header)
+ {
+ return NyLPC_cHttpClient_sendMethod(&this->_inst,i_method,i_path,i_content_length,i_mimetype,i_additional_header)?true:false;
+ }
+ /**
+ * This function returns status code.
+ * Must call after the sendMethod was successful.
+ * @return
+ * Error:0,otherwise HTTP status code.
+ */
+ int HttpClient::getStatus()
+ {
+ return NyLPC_cHttpClient_getStatus(&this->_inst);
+ }
+ /**
+ * Close current connection.
+ */
+ void HttpClient::close()
+ {
+ NyLPC_cHttpClient_close(&this->_inst);
+ }
+ /**
+ * Read request body from http stream.
+ * @param i_rx_buf
+ * A buffer which accepts received data.
+ * @param i_rx_buf_len
+ * size of i_rx_buf in byte.
+ * @param i_read_len
+ * pointer to variable which accept received data size in byte.
+ * It is enabled in retrurn true.
+ * n>0 is datasize. n==0 is end of stream.
+ * @return
+ * true if successful,otherwise false
+ */
+ bool HttpClient::read(void* &i_rx_buf,int i_rx_buf_len,short &i_read_len)
+ {
+ return NyLPC_cHttpClient_read(&this->_inst,i_rx_buf,i_rx_buf_len,&i_read_len)?true:false;
+ }
+ bool HttpClient::write(const void* i_tx_buf,int i_tx_len)
+ {
+ return NyLPC_cHttpClient_write(&this->_inst,i_tx_buf,i_tx_len)?true:false;
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/HttpClient.h Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,85 @@
+#pragma once
+////////////////////////////////////////////////////////////////////////////////
+// HttpClient.h
+////////////////////////////////////////////////////////////////////////////////
+
+#include "NyLPC_net.h"
+#include "IpAddr.h"
+
+namespace MiMic
+{
+ class HttpClient
+ {
+ private:
+ void* _private_tcp_rx_buf;
+ protected:
+ NyLPC_TcHttpClient_t _inst;
+ public:
+ const static NyLPC_THttpMethodType HTTP_GET=NyLPC_THttpMethodType_GET;
+ const static NyLPC_THttpMethodType HTTP_POST=NyLPC_THttpMethodType_POST;
+ const static NyLPC_THttpMethodType HTTP_HEAD=NyLPC_THttpMethodType_HEAD;
+ const static unsigned int CONTENT_CHUNKED=NyLPC_cHttpHeaderWriter_CONTENT_LENGTH_UNLIMITED;
+
+ public:
+ HttpClient();
+ virtual ~HttpClient();
+ public:
+ bool connect(const IpAddr& i_host,unsigned short i_port);
+ /**
+ * This function sends a request to server and prevent to accept status code.
+ * Must call getStatus after successful.
+ * If request has content body(i_content_length!=0), call writeX function to send request body in before to call getStatus
+ * @param i_content_length
+ * size of request body.
+ * Specify CONTENT_CHUNKED if the size is unknown.
+ * @return
+ * true if successful,
+ * otherwise error. Connection is closed.
+ * @example
+ * <code>
+ * //GET
+ * </code>
+ * <code>
+ * //POST
+ *
+ * </code>
+ */
+ bool sendMethod(NyLPC_THttpMethodType i_method,const char* i_path,int i_content_length=0,const char* i_mimetype=NULL,const char* i_additional_header=NULL);
+ /**
+ * This function returns status code.
+ * Must call after the sendMethod was successful.
+ * @return
+ * Error:0,otherwise HTTP status code.
+ */
+ int getStatus();
+ /**
+ * Close current connection.
+ */
+ void close();
+ /**
+ * Read request body from http stream.
+ * This function must be call repeatedly until the end of the stream or an error.
+ * @param i_rx_buf
+ * A buffer which accepts received data.
+ * @param i_rx_buf_len
+ * size of i_rx_buf in byte.
+ * @param i_read_len
+ * pointer to variable which accept received data size in byte.
+ * It is enabled in retrurn true.
+ * n>0 is datasize. n==0 is end of stream.
+ * @return
+ * true if successful,otherwise false
+ */
+ bool read(void* &i_rx_buf,int i_rx_buf_len,short &i_read_len);
+ /**
+ * Write request body to connected http stream.
+ * This function must be call repeatedly until the end of the request content or an error.
+ * Transmission of the request body is completed by to call the AAA in the case of chunked transfer.
+ * @param i_tx_buf
+ * @param i_tx_len
+ * @return
+ * true if successful.
+ */
+ bool write(const void* i_tx_buf,int i_tx_len);
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/IpAddr.h Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,28 @@
+#pragma once
+////////////////////////////////////////////////////////////////////////////////
+// TcpSocket.h
+////////////////////////////////////////////////////////////////////////////////
+
+#include "NyLPC_net.h"
+
+namespace MiMic
+{
+ /**
+ * This class hold IP address.
+ */
+ class IpAddr
+ {
+ public:
+ union TAddrs{
+ struct NyLPC_TIPv4Addr v4;
+ }addr;
+ public:
+ IpAddr(unsigned char p4,unsigned char p3,unsigned char p2,unsigned char p1)
+ {this->setIPv4(p4,p3,p2,p1);}
+
+ void setIPv4(unsigned char p4,unsigned char p3,unsigned char p2,unsigned char p1)
+ {NyLPC_TIPv4Addr_set(&this->addr.v4,p4,p3,p2,p1);}
+ void setIPv4(const struct NyLPC_TIPv4Addr& v4)
+ {this->addr.v4=v4;}
+ };
+}
\ No newline at end of file
--- a/mbed/NetConfig.cpp Fri Sep 13 06:38:16 2013 +0000
+++ b/mbed/NetConfig.cpp Fri Sep 27 12:47:51 2013 +0000
@@ -160,6 +160,12 @@
{
NyLPC_TIPv4Addr_set(&(this->_inst.super.ip_addr),ip1,ip2,ip3,ip4);
}
+
+void NetConfig::setIpAddr(const IpAddr& i_addr)
+{
+ this->_inst.super.ip_addr=i_addr.addr.v4;
+}
+
/**
* Set IPv4 network mask value to instance.
*/
@@ -167,6 +173,11 @@
{
NyLPC_TIPv4Addr_set(&(this->_inst.super.netmask),ip1,ip2,ip3,ip4);
}
+void NetConfig::setNetMask(const IpAddr& i_mask)
+{
+ this->_inst.super.netmask=i_mask.addr.v4;
+}
+
/**
* Set IPv4 default gateway address to instance.
*/
@@ -174,6 +185,11 @@
{
NyLPC_TIPv4Addr_set(&(this->_inst.super.dr_addr),ip1,ip2,ip3,ip4);
}
+void NetConfig::setGateway(const IpAddr& i_addr)
+{
+ this->_inst.super.dr_addr=i_addr.addr.v4;
+}
+
/**
* Set ethernet mac address to instance.
*/
--- a/mbed/NetConfig.h Fri Sep 13 06:38:16 2013 +0000
+++ b/mbed/NetConfig.h Fri Sep 27 12:47:51 2013 +0000
@@ -4,11 +4,12 @@
////////////////////////////////////////////////////////////////////////////////
#include "NyLPC_net.h"
-
+#include "IpAddr.h"
namespace MiMic
{
+ class IpAddr;
/**
* Network configulation class.
* The class is used by Net constructor.
@@ -52,15 +53,17 @@
* Set IPv4 ip address to instance.
*/
void setIpAddr(unsigned char ip4,unsigned char ip3,unsigned char ip2,unsigned char ip1);
+ void setIpAddr(const IpAddr& i_addr);
/**
* Set IPv4 network mask value to instance.
*/
void setNetMask(unsigned char ip4,unsigned char ip3,unsigned char ip2,unsigned char ip1);
-
+ void setNetMask(const IpAddr& i_mask);
/**
* Set IPv4 default gateway address to instance.
*/
void setGateway(unsigned char ip4,unsigned char ip3,unsigned char ip2,unsigned char ip1);
+ void setGateway(const IpAddr& i_addr);
/**
* Set Zero configuration enable flag.
* @param v
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/TcpSocket.cpp Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,61 @@
+#pragma once
+////////////////////////////////////////////////////////////////////////////////
+// TcpSocket.h
+////////////////////////////////////////////////////////////////////////////////
+
+#include "TcpSocket.h"
+
+
+namespace MiMic
+{
+ #define TIMEOUT_IN_MSEC (5*1000)
+
+ TcpSocket::TcpSocket(void* i_rx_buf,unsigned short i_rx_buf_size)
+ {
+ this->_private_rx=NULL;
+ NyLPC_cTcpSocket_initialize(&this->_inst,i_rx_buf,i_rx_buf_size);
+ }
+ TcpSocket::TcpSocket(unsigned short i_rx_buf_size)
+ {
+ this->_private_rx=malloc(i_rx_buf_size);
+ NyLPC_cTcpSocket_initialize(&this->_inst,this->_private_rx,i_rx_buf_size);
+ }
+
+ TcpSocket::~TcpSocket()
+ {
+ NyLPC_cTcpSocket_finalize(&this->_inst);
+ if(this->_private_rx!=NULL){
+ free(this->_private_rx);
+ }
+ }
+ bool TcpSocket::connect(const IpAddr& i_addr,unsigned short i_port)
+ {
+ return NyLPC_cTcpSocket_connect(&this->_inst,&(i_addr.addr.v4),i_port,TIMEOUT_IN_MSEC)?true:false;
+ }
+
+ bool TcpSocket::send(const void* i_tx,unsigned short i_tx_size)
+ {
+ int l,t;
+ l=i_tx_size;
+ while(l>0){
+ t=NyLPC_cTcpSocket_send(&this->_inst,((const char*)i_tx)+(i_tx_size-l),l,TIMEOUT_IN_MSEC);
+ if(t<0){
+ return false;
+ }
+ l-=t;
+ }
+ return true;
+ }
+ int TcpSocket::precv(const void* &i_rx,unsigned short i_rx_size)
+ {
+ return NyLPC_cTcpSocket_precv(&this->_inst,&i_rx,TIMEOUT_IN_MSEC);
+ }
+ void TcpSocket::pseek(unsigned short i_rx_seek)
+ {
+ NyLPC_cTcpSocket_pseek(&this->_inst,i_rx_seek);
+ }
+ void TcpSocket::close()
+ {
+ return NyLPC_cTcpSocket_close(&this->_inst,TIMEOUT_IN_MSEC);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/TcpSocket.h Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,55 @@
+#pragma once
+////////////////////////////////////////////////////////////////////////////////
+// TcpSocket.h
+////////////////////////////////////////////////////////////////////////////////
+
+#include "NyLPC_net.h"
+#include "IpAddr.h"
+
+namespace MiMic
+{
+ /**
+ * Tcp Socket Class.
+ * The class is used by Net constructor.
+ */
+ class TcpSocket
+ {
+ private:
+ NyLPC_TcTcpSocket_t _inst;
+ void* _private_rx;
+ public:
+ /** wrapped base LPC class.*/
+ NyLPC_TcTcpSocket_t* refBaseInstance(){return &this->_inst;}
+
+ public:
+ TcpSocket(unsigned short i_rx_buf_size=(unsigned short)512);
+ TcpSocket(void* i_rx_buf,unsigned short i_rx_buf_size);
+ virtual ~TcpSocket();
+ /**
+ * @param i_host_addr
+ * must be IPv4 address format.
+ */
+ bool connect(const IpAddr& i_addr,unsigned short i_port);
+ bool send(const void* i_tx,unsigned short i_tx_size);
+ /**
+ * This function return recieved data and size.
+ * The function sets the head of the readable buffer which can always be read.
+ * A position is not changed until pseek was called.
+ * @param i_rx
+ * address of variable which accepts received data pointer.
+ * @retrun
+ * n<-1 Error
+ * n==0 Timeout (connection still established)
+ * n>0 Success. readable data size in i_rx.
+ */
+ int precv(const void* &i_rx,unsigned short i_rx_size);
+ /**
+ * This function seek rx pointer to next.
+ * @param i_rx_size
+ * seek size. Must be returned value which is small or equal by the precv.
+ */
+ void pseek(unsigned short i_rx_seek);
+ void close();
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/UdpSocket.cpp Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,73 @@
+////////////////////////////////////////////////////////////////////////////////
+// UdpSocket.cpp
+////////////////////////////////////////////////////////////////////////////////
+
+#include "UdpSocket.h"
+
+
+
+
+namespace MiMic
+{
+ #define TIMEOUT_IN_MSEC (2*1000)
+
+ UdpSocket::UdpSocket(unsigned short i_port,unsigned short i_rx_buf_size)
+ {
+ this->_private_rx=malloc(i_rx_buf_size);
+ NyLPC_cUdpSocket_initialize(&this->_inst,i_port,this->_private_rx,i_rx_buf_size);
+ }
+ UdpSocket::UdpSocket(unsigned short i_port,void* i_rx_buf,unsigned short i_rx_buf_size)
+ {
+ this->_private_rx=NULL;
+ NyLPC_cUdpSocket_initialize(&this->_inst,i_port,i_rx_buf,i_rx_buf_size);
+ }
+
+ UdpSocket::UdpSocket(unsigned short i_port,void* i_rx_handler)
+ {
+ }
+ UdpSocket::~UdpSocket()
+ {
+ NyLPC_cUdpSocket_finalize(&this->_inst);
+ if(this->_private_rx!=NULL){
+ free(this->_private_rx);
+ }
+ }
+
+
+ int UdpSocket::precvfrom(const void* &i_rx,IpAddr* i_peer_host,unsigned short* i_port)
+ {
+ const struct NyLPC_TIPv4RxInfo* info;
+ int rs=NyLPC_cUdpSocket_precv(&this->_inst,&i_rx,&info,TIMEOUT_IN_MSEC);
+ if(rs>1){
+ if(i_peer_host!=NULL){
+ i_peer_host->setIPv4(info->peer_ip);
+ }
+ if(i_port!=NULL){
+ *i_port=info->peer_port;
+ }
+ }
+ return rs;
+ }
+
+ void UdpSocket::precvnext(void)
+ {
+ NyLPC_cUdpSocket_pseek(&this->_inst);
+ }
+
+ bool UdpSocket::sendTo(const IpAddr& i_host,unsigned short i_port,const void* i_tx,unsigned short i_tx_size)
+ {
+ int r=NyLPC_cUdpSocket_send(&this->_inst,&i_host.addr.v4,i_port,i_tx,i_tx_size,TIMEOUT_IN_MSEC);
+ return (r!=i_tx_size);
+
+ }
+
+ void UdpSocket::joinMulticast(const IpAddr& i_host)
+ {
+ NyLPC_cUdpSocket_joinMulticast(&this->_inst,&i_host.addr.v4);
+ }
+ void UdpSocket::setBroadcast(void)
+ {
+ NyLPC_cUdpSocket_setBroadcast(&this->_inst);
+
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/UdpSocket.h Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,50 @@
+#pragma once
+////////////////////////////////////////////////////////////////////////////////
+// UdpSocket.h
+////////////////////////////////////////////////////////////////////////////////
+
+#include "NyLPC_net.h"
+#include "IpAddr.h"
+
+namespace MiMic
+{
+ /**
+ * Udp Socket Class.
+ * The class is used by Net constructor.
+ */
+ class UdpSocket
+ {
+ private:
+ NyLPC_TcUdpSocket_t _inst;
+ void* _private_rx;
+ public:
+ /** wrapped base LPC class.*/
+ NyLPC_TcUdpSocket_t* refBaseInstance(){return &this->_inst;}
+
+ public:
+ UdpSocket(unsigned short i_port,unsigned short i_rx_buf_size=(unsigned short)512);
+ UdpSocket(unsigned short i_port,void* i_rx_buf,unsigned short i_rx_buf_size);
+ /**
+ * This constructor accepts "large" packet by asynchronous handler.
+ * Must be override "onRxHandler" function.
+ */
+ UdpSocket(unsigned short i_port,void* i_rx_handler);
+ virtual ~UdpSocket();
+ /**
+ * This function return recieved data and size.
+ * The function sets the head of the oldest readable buffer.
+ * A position is not changed until precvnext was called.
+ * @param i_host_addr
+ * must be IPv4 address format.
+ */
+ int precvfrom(const void* &i_rx,IpAddr* i_peer_host=NULL,unsigned short* i_port=NULL);
+ /**
+ * This function moves rx buffer to next packet.
+ */
+ void precvnext(void);
+ bool sendTo(const IpAddr& i_host,unsigned short i_port,const void* i_tx,unsigned short i_tx_size);
+ void joinMulticast(const IpAddr& i_host);
+ void setBroadcast(void);
+ };
+}
+
--- a/mbed/mimic.h Fri Sep 13 06:38:16 2013 +0000 +++ b/mbed/mimic.h Fri Sep 27 12:47:51 2013 +0000 @@ -8,6 +8,10 @@ #include "Http.h" #include "UrlReader.h" #include "HttpdConnection.h" +#include "IpAddr.h" +#include "TcpSocket.h" +#include "UdpSocket.h" + #include "mod/ModUrl.h" #include "mod/ModRomFiles.h" #include "mod/ModRemoteMcu.h" @@ -15,6 +19,7 @@ #include "mod/ModLocalFileSystem.h" #include "mod/ModFileIo.h" #include "mod/ModUPnPDevice.h" +#include "mod/ModWebSocket.h" #include "LocalFileSystem2.h" using namespace MiMic; \ No newline at end of file
--- a/mbed/mod/ModFileIo.h Fri Sep 13 06:38:16 2013 +0000 +++ b/mbed/mod/ModFileIo.h Fri Sep 27 12:47:51 2013 +0000 @@ -1,3 +1,4 @@ +#pragma once #include "NyLPC_net.h" #include "ModBaseClass.h" #include "HttpdConnection.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/mod/ModWebSocket.cpp Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,112 @@
+#include "ModWebSocket.h"
+#include "../net/httpd/mod/NyLPC_cModWebSocket_protected.h"
+#include "HttpdConnection.h"
+
+namespace MiMic
+{
+ ModWebSocket::ModWebSocket(const char* i_path):ModBaseClass(i_path)
+ {
+ this->_mod=NULL;
+ }
+ ModWebSocket::ModWebSocket()
+ {
+ this->_mod=NULL;
+ }
+ ModWebSocket::~ModWebSocket()
+ {
+ if(this->_mod!=NULL){
+ NyLPC_cModWebSocket_finalize(this->_mod);
+ this->_mod=NULL;
+ }
+ }
+ void ModWebSocket::setParam(const char* i_path)
+ {
+ ModBaseClass::setParam(i_path);
+ }
+
+ bool ModWebSocket::execute(HttpdConnection& i_connection)
+ {
+ if(this->_mod!=NULL){
+ return false;
+ }
+ this->_mod=(NyLPC_TcModWebSocket_t*)malloc(sizeof(NyLPC_TcModWebSocket_t));
+ if(this->_mod==NULL){
+ return false;
+ }
+ //initialize websocket
+ NyLPC_cModWebSocket_initialize(this->_mod,this->_path);
+ if(NyLPC_cModWebSocket_canHandle(this->_mod,i_connection._ref_inst)){
+ if(NyLPC_cModWebSocket_execute(this->_mod,i_connection._ref_inst)){
+ return true;
+ }
+ }
+ NyLPC_cModWebSocket_finalize(this->_mod);
+ free(this->_mod);
+ this->_mod=NULL;
+ return false;
+ }
+ bool ModWebSocket::write(const void* i_tx_buf,int i_tx_size)
+ {
+ if(this->_mod==NULL){
+ return false;
+ }
+ return NyLPC_cModWebSocket_write(this->_mod,i_tx_buf,i_tx_size)?true:false;
+ }
+
+static NyLPC_TBool fmt_handler(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len)
+{
+ return NyLPC_iHttpPtrStream_write((NyLPC_TiHttpPtrStream_t*)i_inst,i_buf,i_len);
+}
+
+ bool ModWebSocket::writeF(const char* i_fmt,...)
+ {
+ NyLPC_TInt16 l;
+ va_list a;
+ //ストリームの状態を更新する。
+ NyLPC_cModWebSocket_update(this->_mod,0);
+
+ //書式文字列の長さを計算
+ va_start(a,i_fmt);
+ l=NyLPC_cFormatWriter_length(i_fmt,a);
+ va_end(a);
+ if(!NyLPC_cModWebSocket_writePayloadHeader(this->_mod,l)){
+ //CLOSE
+ NyLPC_OnErrorGoto(Error);
+ }
+ va_start(a,i_fmt);
+ if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(this->_mod->_ref_connection),i_fmt,a)){
+ va_end(a);
+ NyLPC_OnErrorGoto(Error);
+ }
+ va_end(a);
+ NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(this->_mod->_ref_connection));
+ return true;
+ Error:
+ NyLPC_cHttpdConnection_closeSocket(this->_mod->_ref_connection);
+ this->_mod->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+ return false;
+ }
+
+ int ModWebSocket::read(void* i_rx_buf,int i_rx_size)
+ {
+ if(this->_mod==NULL){
+ return false;
+ }
+ //write here!
+ return NyLPC_cModWebSocket_read(this->_mod,i_rx_buf,i_rx_size);
+ }
+ bool ModWebSocket::canRead()
+ {
+ return NyLPC_cModWebSocket_canRead(this->_mod)?true:false;
+ }
+
+ void ModWebSocket::close()
+ {
+ if(this->_mod==NULL){
+ return;
+ }
+ NyLPC_cModWebSocket_finalize(this->_mod);
+ this->_mod=NULL;
+ return;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed/mod/ModWebSocket.h Fri Sep 27 12:47:51 2013 +0000
@@ -0,0 +1,80 @@
+#pragma once
+#include "NyLPC_net.h"
+#include "ModBaseClass.h"
+#include "HttpdConnection.h"
+#include "Httpd.h"
+#include "Net.h"
+
+namespace MiMic
+{
+ class HttpdConnection;
+
+ /**
+ * This class is Websocket module.
+ * The class provides 3 services.
+ * <ul>
+ * <li>d.xml - a device description.</li>
+ * <li>control/xx - soap handler</li>
+ * <li>event/xx -event handler.</li>
+ * </ul>
+ */
+ class ModWebSocket:ModBaseClass
+ {
+ private:
+ const Net* _ref_net;
+ protected:
+ NyLPC_TcModWebSocket_t* _mod;
+ public:
+ ModWebSocket();
+ ModWebSocket(const char* i_path);
+ virtual ~ModWebSocket();
+ void setParam(const char* i_path);
+ /**
+ * This function executes websocket negotiation to the current connection.
+ * Should be handle websocket session if function successful.
+ * @return
+ * true if negotiation successful;otherwishe false.
+ */
+ bool execute(HttpdConnection& i_connection);
+ /**
+ * Write data to websocket stream.
+ * @return
+ * true if successful;otherwishe false and connection closed.
+ */
+ bool write(const void* i_tx_buf,int i_tx_size);
+ /**
+ * This function sends data to websocket stream.
+ * @param i_fmt
+ * printf like format text.
+ * @param ...
+ * argument list for i_fmt
+ */
+ bool writeF(const char* i_fmt,...);
+
+ /**
+ * This function receives data from websocket stream.
+ * @return
+ * <ul>
+ * <li>r<0 Error. The socket already closed.
+ * <li>r==0 Timeout. The connection is continued.
+ * <li>r>0 Success. Received data size.
+ * </ul>
+ * If an Error found, application should be call close and exit handler.
+ */
+ int read(void* i_rx_buf,int i_rx_size);
+ /**
+ * This function terminates websocket connection.
+ * Should be called if execute function successful.
+ */
+ void close();
+ /**
+ * This function returns read function status.
+ * This is to confirm that "read" can call without blocking.
+ * @return
+ * true if can be call "read" with no-wait. otherwise, "read" might be wait.
+ */
+ bool canRead();
+
+
+ };
+}
\ No newline at end of file
MiMic Webservice library