uIPのイベント

uIPで簡単なHTTPクライアントを書いてみる。
大げさなものではなくGETしてそれを画面に出力するだけ。


まずはuIPのドキュメント通りに、各状態に合わせたハンドラを呼んでやる

void NetServer::DoEvent()
{
    if (uip_aborted())
    {
        AbortedHandler();
    }
    if (uip_timedout())
    {
        TimeoutHandler();
    }
    if (uip_closed())
    {
        ClosedHandler();
    }
    if (uip_connected())
    {
        ConnectedHandler();
    }
    if (uip_acked())
    {
        AckedHandler();
    }
    if (uip_newdata())
    {
        NewDataHandler();
    }
    if (uip_rexmit() || uip_newdata() || uip_acked() || uip_acked() || uip_connected() || uip_poll())
    {
        SendDataHandler();
    }


次にそれぞれのハンドラを定義してやります。
今回は実験なので、効率とか誰がメモリ解放するのかとか、エラーのときは?とかは一切考えていません。

void NetServer::ConnectedHandler()
{
    printf("%s\n", __FUNCTION__);
    struct server_state* s = (struct server_state *)uip_conn->appstate;
    const char* message = "GET /file HTTP/1.0\r\nServer:192.168.100.2\r\n\r\n";
    s->message = new char[strlen(message) + 1];
    strcpy(s->message, message);
    s->length = strlen(message) + 1;
}

void NetServer::AckedHandler()
{
    printf("%s\n", __FUNCTION__);
    struct server_state* s = (struct server_state *)uip_conn->appstate;
    s->length -= uip_conn->len;
    s->message += uip_conn->len;
    if(s->length == 0)
    {
        printf("send done\n");
    }
}

void NetServer::NewDataHandler()
{
    printf("%s\n", __FUNCTION__);
    for (dword i = 0; i < GetDataLength(); i++)
    {
        printf("%c", (char)uip_appdata[i]);
    }
}

void NetServer::SendDataHandler()
{
    printf("%s\n", __FUNCTION__);
    struct server_state* s = (struct server_state *)uip_conn->appstate;
    if (s->length != 0)
    {
        uip_send((volatile u8_t*)s->message, s->length);
    }
}


フローとしては
1. 接続が完了すると ConnectedHandlerが呼ばれる
2. GETを発行するために、GET文字列と長さを格納
3. 送信
4. ackedが返ってきてまだ未送信分がある場合や、再送の必要があれば再送信します。
5.uip_newdata()が1だったらデータが返ってきています。


これを踏まえたうえで次のエントリーへ。