で、これを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 件のコメント:
コメントを投稿