void setup() { if(mode == Http) { req = initialReq; initialReq = 0; QByteArray jsonpCallback = initialJsonpCallback; initialJsonpCallback.clear(); // don't need these things initialLastPart.clear(); initialBody.clear(); requests.insert(req, new RequestItem(req, jsonpCallback, RequestItem::Connect)); connect(req, SIGNAL(bytesWritten(int)), SLOT(req_bytesWritten(int))); connect(req, SIGNAL(error()), SLOT(req_error())); } else { connect(sock, SIGNAL(connected()), SLOT(sock_connected())); connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); connect(sock, SIGNAL(framesWritten(int, int)), SLOT(sock_framesWritten(int, int))); connect(sock, SIGNAL(closed()), SLOT(sock_closed())); connect(sock, SIGNAL(peerClosed()), SLOT(sock_peerClosed())); connect(sock, SIGNAL(error()), SLOT(sock_error())); } }
/* Close down a socket - preferably politely */ void net_close(struct socket *s) { uint16_t i = sock2wiz_map[s - sockets]; uint16_t off = i << 8; if (s->s_type == SOCKTYPE_TCP && s->s_state != SS_CLOSED) { w5100_writeb(Sn_CR + off, DISCON); s->s_state = SS_CLOSING; } else { irqmask &= ~(1 << i); w5100_writeb(IMR, irqmask); w5100_writeb(Sn_CR + off, CLOSE); wiz2sock_map[i] = 0xFF; sock_closed(s); } }
void startHandleSocket(ZWebSocket *sock, int basePathStart, const QByteArray &asPath, const DomainMap::Entry &route) { Session *s = new Session(this); s->sock = sock; QByteArray encPath = sock->requestUri().path(QUrl::FullyEncoded).toUtf8(); s->path = encPath.mid(basePathStart); s->asUri = sock->requestUri(); if(!asPath.isEmpty()) s->asUri.setPath(QString::fromUtf8(asPath), QUrl::StrictMode); else s->asUri.setPath(QString::fromUtf8(encPath.mid(0, basePathStart) + "/websocket"), QUrl::StrictMode); s->route = route; connect(sock, SIGNAL(closed()), SLOT(sock_closed())); connect(sock, SIGNAL(error()), SLOT(sock_error())); sessions += s; sessionsBySocket.insert(s->sock, s); handleSocket(s); }
/* * Process interrupts from the WizNet device */ static void w5100_event_s(uint8_t i) { int sn = wiz2sock_map[i]; struct socket *s; uint16_t offset = i << 8; uint16_t stat = w5100_readw(Sn_IR + offset); /* BE read of reg pair */ /* We got a pending event for a dead socket as we killed it. Shoot it again to make sure it's dead */ if (sn == 0xFF) { w5100_writeb(Sn_CR + offset, CLOSE); irqmask &= ~(1 << i); w5100_writeb(IMR, irqmask); return; } s = &sockets[sn]; if (stat & 0x1000) { /* Transmit completed: window re-open. We can allow more data to flow from the user */ s->s_iflag &= ~SI_THROTTLE; wakeup(&s->s_data); } if (stat & 0x800) { /* Timeout */ s->s_error = ETIMEDOUT; w5100_writeb(Sn_CR + offset, CLOSE); w5100_wakeall(s); w5100_eof(s); /* Fall through and let CLOSE state processing do the work */ } if (stat & 0x400) { /* Receive wake: Poke the user in case they are reading */ s->s_iflag |= SI_DATA; wakeup(&s->s_iflag); } if (stat & 0x200) { /* Disconnect: Just kill our host socket. Not clear if this is right or we need to drain data first */ w5100_writeb(Sn_CR + offset, CLOSE); w5100_eof(s); /* When we fall through we'll see CLOSE state and do the actual shutting down */ } if (stat & 0x100) { /* Connect: Move into connected state */ if (s->s_state == SS_CONNECTING) { s->s_state = SS_CONNECTED; wakeup(s); } } /* Clear interrupt sources down */ w5100_writeb(Sn_IR + offset, stat >> 8); switch ((uint8_t)stat) { case 0: /* SOCK_CLOSED */ if (s->s_state != SS_CLOSED && s->s_state != SS_UNUSED) { if (s->s_state != SS_CLOSING && s->s_state != SS_DEAD) { s->s_error = ECONNRESET; /* Sort of a guess */ w5100_wakeall(s); } else wakeup(s); irqmask &= ~(1 << i); w5100_writeb(IMR, irqmask); w5100_eof(s); /* Net layer wants us to burn the socket */ if (s->s_state == SS_DEAD) { wiz2sock_map[i] = 0xFF; sock_closed(s); } else /* so net_close() burns the socket */ s->s_state = SS_CLOSED; } break; case 0x13: /* SOCK_INIT */ break; case 0x14: /* SOCK_LISTEN */ break; case 0x17: /* SOCK_ESTABLISHED */ if (s->s_state == SS_CONNECTING) { s->s_state == SS_CONNECTED; wakeup(s); } else if (s->s_state == SS_LISTENING) { /* * The WizNET believes you allocte a LISTEN socket and * it turns into a connection and you then if need be * allocate another LISTEN socket. * * The socket API believes you set a listening socket * up and it stays listening creating new connected * sockets. * * We do some gymnastics to convince both sides that * what they saw happened. */ int slot; struct socket *ac; int aslot; /* Find a new wiznet slot and socket */ slot = net_alloc(); if (slot == -1 || (ac = sock_alloc_accept(s)) == NULL) { /* No socket free, go back to listen */ w5100_writeb(Sn_CR + offset, CLOSE); net_bind(s); net_listen(s); break; } /* Resources exist so do the juggling */ aslot = ac - sockets; /* Map the existing socket to the new w5100 socket */ sock2wiz_map[sn] = slot; wiz2sock_map[slot] = sn; /* Map the new socket to the existing w5100 socket */ sock2wiz_map[aslot] = i; wiz2sock_map[i] = aslot; /* Now set the new socket back up as it should be */ net_bind(ac); net_listen(ac); /* And kick the accepter */ wakeup(s); } break; case 0x1C: /* SOCK_CLOSE_WAIT */ if (s->s_state == SS_CONNECTED || s->s_state == SS_CONNECTING) s->s_state = SS_CLOSEWAIT; w5100_eof(s); if (s->s_state == SS_ACCEPTWAIT) { /* HUM ??? */ } break; case 0x22: /* SOCK_UDP */ case 0x32: /* SOCK_IPRAW */ case 0x42: /* SOCK_MACRAW */ /* Socket has been created */ s->s_state = SS_UNCONNECTED; wakeup(s); break; } }