diff --git a/cnc/include/cnc.h b/cnc/include/cnc.h index 50d643c..0be8ab6 100644 --- a/cnc/include/cnc.h +++ b/cnc/include/cnc.h @@ -5,9 +5,17 @@ #include "lpacket.h" #include "lsocket.h" #include "lpolllist.h" +#include "lpeer.h" -struct { +struct sLaika_cnc { struct sLaika_socket sock; -} sLaika_cnc; + struct sLaika_pollList pList; +}; + +struct sLaika_cnc *laikaC_newCNC(uint16_t port); +void laikaC_freeCNC(struct sLaika_cnc *cnc); + +void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer); +bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout); #endif \ No newline at end of file diff --git a/cnc/src/cnc.c b/cnc/src/cnc.c index 838b8ee..354e7a3 100644 --- a/cnc/src/cnc.c +++ b/cnc/src/cnc.c @@ -1,2 +1,88 @@ +#include "lmem.h" +#include "lerror.h" + #include "cnc.h" +size_t laikaC_pktSizeTbl[LAIKAPKT_MAXNONE] = { + [LAIKAPKT_HANDSHAKE_REQ] = LAIKA_MAGICLEN + sizeof(uint8_t) + sizeof(uint8_t), + [LAIKAPKT_HANDSHAKE_RES] = sizeof(uint8_t) +}; + +void laikaC_pktHandler(struct sLaika_peer *peer, LAIKAPKT_ID id) { + printf("got %d packet id!\n", id); +} + +struct sLaika_cnc *laikaC_newCNC(uint16_t port) { + struct sLaika_cnc *cnc = laikaM_malloc(sizeof(struct sLaika_cnc)); + + /* init socket & pollList */ + laikaS_initSocket(&cnc->sock); + laikaP_initPList(&cnc->pList); + + /* bind sock to port */ + laikaS_bind(&cnc->sock, port); + + /* add sock to pollList */ + laikaP_addSock(&cnc->pList, &cnc->sock); +} + +void laikaC_freeCNC(struct sLaika_cnc *cnc) { + laikaS_cleanSocket(&cnc->sock); + laikaP_cleanPList(&cnc->pList); + laikaM_free(cnc); +} + +void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { + laikaP_rmvSock(&cnc->pList, (struct sLaika_sock*)peer); + laikaS_kill(&peer->sock); +} + +bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) { + struct sLaika_peer *peer; + struct sLaika_pollEvent *evnts; + int numEvents, i; + + evnts = laikaP_poll(&cnc->pList, timeout, &numEvents); + + /* if we have 0 events, we reached the timeout, let the caller know */ + if (numEvents == 0) { + return false; + } + + /* walk through and handle each event */ + for (i = 0; i < numEvents; i++) { + if (evnts[i].sock == &cnc->sock) { /* event on listener? */ + peer = laikaS_newPeer( + laikaC_pktHandler, + &cnc->pList, + laikaC_pktSizeTbl + ); + + /* setup and accept new peer */ + laikaS_acceptFrom(&peer->sock, &cnc->sock); + laikaS_setNonBlock(&peer->sock); + + /* add to our pollList */ + laikaP_addSock(&cnc->pList, (struct sLaika_sock*)peer); + continue; + } + + peer = (struct sLaika_peer*)evnts[i].sock; + + LAIKA_TRY + if (evnts[i].pollIn && !laikaS_handlePeerIn(peer)) + laikaC_killPeer(cnc, peer); + + if (evnts[i].pollOut && !laikaS_handlePeerOut(peer)) + laikaC_killPeer(cnc, peer); + + if (!evnts[i].pollIn && !evnts[i].pollOut) + laikaC_killPeer(cnc, peer); + + LAIKA_CATCH + laikaC_killPeer(cnc, peer); + LAIKA_TRYEND + } + + return true; +} \ No newline at end of file diff --git a/lib/include/lsocket.h b/lib/include/lsocket.h index c93b543..6a55dff 100644 --- a/lib/include/lsocket.h +++ b/lib/include/lsocket.h @@ -64,7 +64,7 @@ struct sLaika_socket { int inCap; }; -#define laikaS_isAlive(sock) (sock->sock != INVALID_SOCKET) +#define laikaS_isAlive(arg) (arg->sock != INVALID_SOCKET) void laikaS_init(void); void laikaS_cleanUp(void); diff --git a/lib/src/lpeer.c b/lib/src/lpeer.c index 0a58e27..0b0199a 100644 --- a/lib/src/lpeer.c +++ b/lib/src/lpeer.c @@ -23,7 +23,6 @@ void laikaS_freePeer(struct sLaika_peer *peer) { bool laikaS_handlePeerIn(struct sLaika_peer *peer) { RAWSOCKCODE err; int recvd; - bool _tryCatchRes; switch (peer->pktID) { case LAIKAPKT_MAXNONE: @@ -46,17 +45,20 @@ bool laikaS_handlePeerIn(struct sLaika_peer *peer) { /* have we received the full packet? */ if (peer->pktSize == peer->sock.inCount) { - /* dispatch to packet handler */ - LAIKA_TRY - peer->pktHandler(peer, peer->pktID); - _tryCatchRes = true; - LAIKA_CATCH - _tryCatchRes = false; - LAIKA_TRYEND /* can't skip this, so the return is after */ + peer->pktHandler(peer, peer->pktID); /* dispatch to packet handler */ - return _tryCatchRes; + /* reset */ + peer->sock.inCount = 0; + peer->pktID = LAIKAPKT_MAXNONE; } + + break; } + + if (peer->sock.outCount > 0 && !laikaS_handlePeerOut(peer)) + return false; + + return laikaS_isAlive((&peer->sock)); } bool laikaS_handlePeerOut(struct sLaika_peer *peer) {