From 240c89f783813d3f306b8f06041c4d65ec101575 Mon Sep 17 00:00:00 2001 From: "simon.kagstrom" Date: Sat, 20 Feb 2010 13:01:23 +0000 Subject: [PATCH] First round of network refactoring: The network connection will be stateless. Currently only getting the list of peers will work, but more is on the way. --- Src/C64_SDL.h | 22 ++---------- Src/Network.cpp | 68 ++++++++++++++++++++++++++--------- Src/Network.h | 44 ++++++++++++----------- Src/gui/network_menu.cpp | 1 + Src/gui/network_user_menu.cpp | 3 ++ 5 files changed, 83 insertions(+), 55 deletions(-) diff --git a/Src/C64_SDL.h b/Src/C64_SDL.h index 9d5f209..45ef49c 100644 --- a/Src/C64_SDL.h +++ b/Src/C64_SDL.h @@ -171,24 +171,6 @@ void C64::network_vblank() js = &TheCIA1->Joystick1; else js = &TheCIA1->Joystick2; - } else if (this->network_connection_type == CONNECT) { - network_connection_error_t err = this->network->ConnectFSM(); - - if (err == OK) { - if (this->network->is_master) - this->network_connection_type = MASTER; - else - this->network_connection_type = CLIENT; - this->linecnt = 0; - } - else if (err != AGAIN_ERROR) - { - if (err == VERSION_ERROR) - Gui::gui->status_bar->queueMessage("Get a new version at http://www.c64-network.org"); - delete remote; - this->network = NULL; - } - return; } else { if (ThePrefs.JoystickSwap) js = &TheCIA1->Joystick2; @@ -196,6 +178,7 @@ void C64::network_vblank() js = &TheCIA1->Joystick1; } + remote->ResetNetworkUpdate(); /* Has the peer sent any data? */ if (remote->ReceiveUpdate() == true) { @@ -214,6 +197,8 @@ void C64::network_vblank() if (this->network_connection_type == CLIENT) this->TheDisplay->Update(remote->GetScreen()); } + if (this->network_connection_type == CONNECT) + return; /* Encode and send updates to the other side (what is determined by * if this is the master or not) */ @@ -239,7 +224,6 @@ void C64::network_vblank() /* Disconnect or broken data */ printf("Could not send update\n"); } - remote->ResetNetworkUpdate(); static uint32_t last_traffic_update; diff --git a/Src/Network.cpp b/Src/Network.cpp index 8a1507e..2fe9861 100644 --- a/Src/Network.cpp +++ b/Src/Network.cpp @@ -561,18 +561,18 @@ bool Network::ReceiveUpdate(NetworkUpdate *dst, size_t total_sz, size_t received = 0; bool has_stop = false; - if (this->Select(this->sock, tv) == false) - return false; - if (sz_left <= 0) return false; - printf("Have something\n"); /* Receive the header */ do { + if (this->Select(this->sock, tv) == false) + return false; + /* Only timeout the first run */ + tv = NULL; + ssize_t actual_sz = this->ReceiveFrom(p, this->sock, 4096, NULL); - printf("AS: %d\n", actual_sz); if (actual_sz <= 0) return false; @@ -904,7 +904,8 @@ bool Network::DecodeUpdate(C64Display *display, uint8 *js, MOS6581 *dst) while (p->type != STOP) { - printf("decoding %d\n", p->type); + if (p->magic != FRODO_NETWORK_MAGIC) + break; switch(p->type) { case SOUND_UPDATE: @@ -940,15 +941,8 @@ bool Network::DecodeUpdate(C64Display *display, uint8 *js, MOS6581 *dst) } break; case TEXT_MESSAGE: - { - static char display_buf[80]; - - strncpy(display_buf, (char*)p->data, 80); - display->display_status_string(display_buf, 4); - } break; - case LIST_PEERS: - { - } break; + Gui::gui->status_bar->queueMessage((const char*)p->data); + break; case REGISTER_DATA: { NetworkUpdateRegisterData *rd = (NetworkUpdateRegisterData *)p->data; @@ -965,7 +959,50 @@ bool Network::DecodeUpdate(C64Display *display, uint8 *js, MOS6581 *dst) if (ud->type == BANDWIDTH_PING) type = BANDWIDTH_ACK; this->SendPingAck(ping->seq, type, ud->size); + this->SendServerUpdate(); + this->ResetNetworkUpdate(); } break; + case LIST_PEERS: + { + NetworkUpdateListPeers *lp = (NetworkUpdateListPeers *)this->ud->data; + + if (lp->n_peers == 1 && (lp->flags & NETWORK_UPDATE_LIST_PEERS_IS_CONNECT)) + { + NetworkUpdatePeerInfo *pi = &lp->peers[0]; + + printf("FiXME! Got peer: %s, %d\n", (char*)pi->public_ip, pi->public_port); + break; + } + + for (unsigned i = 0; i < lp->n_peers; i++) + { + if (lp->peers[i].version != FRODO_NETWORK_PROTOCOL_VERSION) + { + warning("Peer %d has wrong version: %d vs %d\n", + i, lp->peers[i].version, FRODO_NETWORK_PROTOCOL_VERSION); + break; + } + } + if (lp->n_peers == 0) + { + Gui::gui->status_bar->queueMessage("No peers, waiting for connection..."); + this->is_master = true; + break; + } + /* FIXME! Not necessarily true! */ + this->is_master = false; + + Gui::gui->status_bar->queueMessage("Got list of peers"); + Gui::gui->nuv->setPeers(lp); + Gui::gui->activate(); + Gui::gui->pushView(Gui::gui->nuv); + } break; + case CONNECT_TO_PEER: + if (this->is_master) + TheC64->network_connection_type = MASTER; + else + TheC64->network_connection_type = CLIENT; + break; case BANDWIDTH_ACK: case ACK: /* We won't receive this, but it also doesn't really matter */ @@ -1028,7 +1065,6 @@ bool Network::ConnectToBroker() /* Reset peer selection */ this->peer_selected = -1; - pi->is_master = 0; /* Will be set later */ pi->key = ThePrefs.NetworkKey; pi->version = FRODO_NETWORK_PROTOCOL_VERSION; pi->avatar = ThePrefs.NetworkAvatar; diff --git a/Src/Network.h b/Src/Network.h index 51e80af..baa0d46 100644 --- a/Src/Network.h +++ b/Src/Network.h @@ -157,12 +157,14 @@ struct NetworkUpdatePeerInfo uint32 screenshot_key; /* Key number of the screenshot */ }; +#define NETWORK_UPDATE_LIST_PEERS_IS_CONNECT 1 struct NetworkUpdateListPeers { uint32 n_peers; uint8 your_ip[16]; uint16 your_port; - uint8 d[2]; /* Pad to 4 bytes */ + uint8 flags; + uint8 d; /* Pad to 4 bytes */ /* Followed by the actual peers */ NetworkUpdatePeerInfo peers[]; @@ -264,11 +266,31 @@ public: void Disconnect(); bool is_master; /* Some peers are more equal than others */ -protected: + void InitNetwork(); void ShutdownNetwork(); + + bool ConnectToBroker(); + + bool ConnectToPeer(); + + bool WaitForPeerReply(); + + bool SendBandWidthTest(); + + network_connection_error_t WaitForBandWidthReply(); + + network_connection_error_t WaitForPeerList(); + + network_connection_error_t WaitForPeerAddress(); + + network_connection_error_t WaitForPeerSelection(); + + bool SelectPeer(uint32 id); + +protected: /** Encode part of a screen into @a dst in a single sweep * * @param dst the destination update structure @@ -347,26 +369,8 @@ protected: bool ScanDataForStop(NetworkUpdate *ud, size_t max_size); - bool ConnectToBroker(); - bool AppendScreenshot(NetworkUpdatePeerInfo *pi); - bool ConnectToPeer(); - - bool WaitForPeerReply(); - - bool SendBandWidthTest(); - - network_connection_error_t WaitForBandWidthReply(); - - network_connection_error_t WaitForPeerList(); - - network_connection_error_t WaitForPeerAddress(); - - network_connection_error_t WaitForPeerSelection(); - - bool SelectPeer(uint32 id); - size_t FillNetworkBuffer(NetworkUpdate *p); NetworkUpdate *GetNext(NetworkUpdate *p) diff --git a/Src/gui/network_menu.cpp b/Src/gui/network_menu.cpp index d9fc360..457bd7d 100644 --- a/Src/gui/network_menu.cpp +++ b/Src/gui/network_menu.cpp @@ -74,6 +74,7 @@ public: TheC64->network = new Network(Gui::gui->np->NetworkServer, Gui::gui->np->NetworkPort); TheC64->network_connection_type = CONNECT; + TheC64->network->ConnectToBroker(); } break; case 6: diff --git a/Src/gui/network_user_menu.cpp b/Src/gui/network_user_menu.cpp index a81d01a..e221580 100644 --- a/Src/gui/network_user_menu.cpp +++ b/Src/gui/network_user_menu.cpp @@ -192,8 +192,11 @@ public: return; this->freePeers(); + this->n_peers = peerList->n_peers; messages = (const char **)xmalloc( (peerList->n_peers + 1) * sizeof(const char*)); + this->peers = (PeerInfo**)xrealloc((void*)this->peers, + peerList->n_peers * sizeof(PeerInfo*)); for (unsigned i = 0; i < peerList->n_peers; i++) {