2013年7月29日月曜日

websocket RX63N

7/25 発売のCQ出版のInterface 誌は HTML5の特集です。
で、これをRX63Nで動作させられないかと記事を読んだのですが、わからん。

cwebsocketを発見したので、これで動作確認してみる。
http://code.google.com/p/cwebsocket/

解凍してbase64_enc.c, sha1.c, websocket.c x86_server/main.c を RX63Nのプロジェクトに組み込みます。
RX63Nのコンパイルオプションでは C99を選択します。
 tcp_main::  
 void tcp_start(void)  
 {  
      W     size;  
      ER     ercd;  
      char     ver[128];  
      printk("%s", (char*)R_t4_version.library);  
      /* start LAN controller */  
      ercd = lan_open();  
      if (ercd != E_OK)  
      {  
           printk("lan_open %08x\n",ercd);  
           while (1);  
      }  
      /* initialize TCP/IP */  
      size = tcpudp_get_ramsize();  
      if (size > (sizeof(tcpudp_work)))  
      {  
           while (1);  
      }  
      ercd = tcpudp_open(tcpudp_work);  
      if (ercd != E_OK)  
      {  
           while (1);  
      }  
 ...     略  
 config_tcpudp.c::  
 /*** Definition of TCP reception point (only port number needs to be set) ***/  
 const T_TCP_CREP tcp_crep[] =  
 {  
      /* { attribute of reception point, {local IP address, local port number}} */  
      { 0x0000, { 0, 8088 }},  
 };  
 /* Total number of TCP reception points */  
 const H __tcprepn = sizeof(tcp_crep) / sizeof(T_TCP_CREP);  
 /*** Definition of TCP communication end point  
    (only receive window size needs to be set) ***/  
 const T_TCP_CCEP tcp_ccep[] =  
 {  
      /* { attribute of TCP communication end point,  
         top address of transmit window buffer, size of transmit window buffer,  
         top address of receive window buffer, size of receive window buffer,  
         address of callback routine }  
      */  
      { 0, 0, 0, 0, 1460, 0 },  
 };  
 ...     略  
x86_server/main.c -> echo_srv.c::  
 #include "websocket.h"  
 #define BUF_LEN 512  
 void clientWorker(ID cepid);  
 /******************************************************************************  
 Exported global variables and functions (to be accessed by other files)  
 ******************************************************************************/  
 void error(const char *msg)  
 {  
   //エラー処理省き  
   return;  
 }  
 int safeSend(ID cepid, const uint8_t *buffer, size_t bufferSize)  
 {  
   ER written;  
      written = tcp_snd_dat(cepid, buffer, bufferSize, TMO_FEVR);  
   if (written < 0) {  
           tcp_sht_cep(cepid);  
           tcp_cls_cep(cepid, TMO_FEVR);  
     return EXIT_FAILURE;  
   }  
   return EXIT_SUCCESS;  
 }  
 void clientWorker(ID cepid)  
 {  
   uint8_t buffer[BUF_LEN];  
   memset(buffer, 0, BUF_LEN);  
   size_t readedLength = 0;  
   size_t frameSize = BUF_LEN;  
   enum wsState state = WS_STATE_OPENING;  
   uint8_t *data = NULL;  
   size_t dataSize = 0;  
   enum wsFrameType frameType = WS_INCOMPLETE_FRAME;  
   struct handshake hs;  
   nullHandshake(&hs);  
   #define prepareBuffer frameSize = BUF_LEN; memset(buffer, 0, BUF_LEN);  
   #define initNewFrame frameType = WS_INCOMPLETE_FRAME; readedLength = 0; memset(buffer, 0, BUF_LEN);  
   printk(" connect websocket srv\n");  
   while (frameType == WS_INCOMPLETE_FRAME) {  
     ER readed = tcp_rcv_dat(cepid, buffer+readedLength, BUF_LEN-readedLength, TMO_FEVR);  
     if (readed <= 0) {  
                tcp_sht_cep(cepid);  
                tcp_cls_cep(cepid, TMO_FEVR);  
          return;  
     }  
     readedLength+= readed;  
     //assert(readedLength <= BUF_LEN);  
           printk("readed=%d\n",readed);  
     if (state == WS_STATE_OPENING) {  
       frameType = wsParseHandshake(buffer, readedLength, &hs);  
     } else {  
       frameType = wsParseInputFrame(buffer, readedLength, &data, &dataSize);  
     }  
     if ((frameType == WS_INCOMPLETE_FRAME && readedLength == BUF_LEN) || frameType == WS_ERROR_FRAME) {  
       if (frameType == WS_INCOMPLETE_FRAME)  
         printk("buffer too small\n");  
       else  
         printk("error in incoming frame\n");  
       if (state == WS_STATE_OPENING) {  
         prepareBuffer;  
         frameSize = sprintf((char *)buffer,  
                   "HTTP/1.1 400 Bad Request\r\n"  
                   "%s%s\r\n\r\n",  
                   versionField,  
                   version);  
         safeSend(cepid, buffer, frameSize);  
         break;  
       } else {  
         prepareBuffer;  
         wsMakeFrame(NULL, 0, buffer, &frameSize, WS_CLOSING_FRAME);  
         if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
           break;  
         state = WS_STATE_CLOSING;  
         initNewFrame;  
       }  
     }  
     if (state == WS_STATE_OPENING) {  
       //assert(frameType == WS_OPENING_FRAME);  
       if (frameType == WS_OPENING_FRAME) {  
         // if resource is right, generate answer handshake and send it  
         if (strcmp(hs.resource, "/echo") != 0) {  
           frameSize = sprintf((char *)buffer, "HTTP/1.1 404 Not Found\r\n\r\n");  
           if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
             break;  
         }  
         prepareBuffer;  
         wsGetHandshakeAnswer(&hs, buffer, &frameSize);  
         if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
           break;  
         state = WS_STATE_NORMAL;  
         initNewFrame;  
       }  
     } else {  
       if (frameType == WS_CLOSING_FRAME) {  
         if (state == WS_STATE_CLOSING) {  
           break;  
         } else {  
           prepareBuffer;  
           wsMakeFrame(NULL, 0, buffer, &frameSize, WS_CLOSING_FRAME);  
           safeSend(cepid, buffer, frameSize);  
           break;  
         }  
       } else if (frameType == WS_TEXT_FRAME) {  
         uint8_t *recievedString = NULL;  
         recievedString = malloc(dataSize+1);  
         //assert(recievedString);  
         memcpy(recievedString, data, dataSize);  
         recievedString[ dataSize ] = 0;  
         prepareBuffer;  
         wsMakeFrame(recievedString, dataSize, buffer, &frameSize, WS_TEXT_FRAME);  
         if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)  
           break;  
         initNewFrame;  
       }  
     }  
   } // read/write cycle  
      tcp_sht_cep(cepid);  
      tcp_cls_cep(cepid, TMO_FEVR);  
 }  
 void websocket_srv(ID id)  
 {  
      ID cepid, repid;  
      ER ercd;  
   T_IPV4EP dst_addr;  
      /* setting of reception point and communucation end point */  
      cepid = id;  
      repid = id;  
      /* TCP wait connection */  
      ercd = tcp_acp_cep(cepid, repid, &dst_addr, TMO_FEVR);  
      if (ercd == E_OK)  
      {  
           clientWorker(cepid);  
      }  
      /* shutdown */  
      tcp_sht_cep(cepid);  
      tcp_cls_cep(cepid, TMO_FEVR);  
      return;  
 }  
あとは htons() がないといわれたら、
 #include <machine.h>  
 #define htons(x) rev(x)  
とか

ネットで参考になった記事は
http://d.hatena.ne.jp/mzp/20110123/websokcet

2013.07.29



0 件のコメント:

コメントを投稿