AJ_Status AJ_Net_MCastUp(AJ_MCastSocket* mcastSock) { uint8_t ret = 0; AJ_InfoPrintf(("AJ_Net_MCastUp(mcastSock=0x%p)\n", mcastSock)); // // Arduino does not choose an ephemeral port if we enter 0 -- it happily // uses 0 and then increments each time we bind, up through the well-known // system ports. // ret = g_clientUDP.begin(AJ_EphemeralPort()); if (ret != 1) { g_clientUDP.stop(); AJ_ErrPrintf(("AJ_Net_MCastUp(): begin() fails. status=AJ_ERR_READ\n")); return AJ_ERR_READ; } else { AJ_IOBufInit(&mcastSock->rx, rxData, sizeof(rxData), AJ_IO_BUF_RX, (void*)&g_clientUDP); mcastSock->rx.recv = AJ_Net_RecvFrom; AJ_IOBufInit(&mcastSock->tx, txData, sizeof(txData), AJ_IO_BUF_TX, (void*)&g_clientUDP); mcastSock->tx.send = AJ_Net_SendTo; } AJ_InfoPrintf(("AJ_Net_MCastUp(): status=AJ_OK\n")); return AJ_OK; }
AJ_Status AJ_Net_Connect(AJ_BusAttachment* bus, const AJ_Service* service) { int ret; IPAddress ip(service->ipv4); if (!(service->addrTypes & AJ_ADDR_TCP4)) { AJ_ErrPrintf(("AJ_Net_Connect(): only IPV4 TCP supported\n", ret)); return AJ_ERR_CONNECT; } AJ_InfoPrintf(("AJ_Net_Connect(bus=0x%p, addrType=%d.)\n", bus, service->addrTypes)); ret = g_client.connect(ip, service->ipv4port); if (ret != 1) { AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret)); return AJ_ERR_CONNECT; } else { AJ_IOBufInit(&bus->sock.rx, rxData, sizeof(rxData), AJ_IO_BUF_RX, (void*)&g_client); bus->sock.rx.recv = AJ_Net_Recv; AJ_IOBufInit(&bus->sock.tx, txData, sizeof(txData), AJ_IO_BUF_TX, (void*)&g_client); bus->sock.tx.send = AJ_Net_Send; AJ_ErrPrintf(("AJ_Net_Connect(): connect() success: status=AJ_OK\n")); return AJ_OK; } AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret)); return AJ_ERR_CONNECT; }
AJ_Status AJ_Net_Connect(AJ_NetSocket* netSock, uint16_t port, uint8_t addrType, const uint32_t* addr) { int ret; IPAddress ip(*addr); AJ_InfoPrintf(("AJ_Net_Connect(nexSock=0x%p, port=%d., addrType=%d., addr=0x%p)\n", netSock, port, addrType, addr)); AJ_InfoPrintf(("AJ_Net_Connect(): Connect to 0x%x:%u.\n", addr, port));; ret = g_client.connect(ip, port); #ifdef NOTDEF Serial.print("Connecting to: "); Serial.print(ip); Serial.print(':'); Serial.println(port); #endif if (ret == -1) { AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret)); return AJ_ERR_CONNECT; } else { AJ_IOBufInit(&netSock->rx, rxData, sizeof(rxData), AJ_IO_BUF_RX, (void*)&g_client); netSock->rx.recv = AJ_Net_Recv; AJ_IOBufInit(&netSock->tx, txData, sizeof(txData), AJ_IO_BUF_TX, (void*)&g_client); netSock->tx.send = AJ_Net_Send; AJ_ErrPrintf(("AJ_Net_Connect(): connect() success: status=AJ_OK\n")); return AJ_OK; } AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed: %d: status=AJ_ERR_CONNECT\n", ret)); return AJ_ERR_CONNECT; }
AJ_Status AJ_Net_MCastUp(AJ_MCastSocket* mcastSock) { AJ_Status status = AJ_OK; size_t numMDnsRecvSocks; struct sockaddr_storage addrBuf; socklen_t addrLen = sizeof(addrBuf); struct sockaddr_in* sin; SOCKET tmp_sock = INVALID_SOCKET; // bring up WinSock WinsockCheck(); AJ_InfoPrintf(("AJ_Net_MCastUp(mcastSock=0x%p)\n", mcastSock)); // create the mDNS recv socket tmp_sock = MDnsRecvUp(mcastSock); if (tmp_sock != INVALID_SOCKET) { getsockname(tmp_sock, (struct sockaddr*) &addrBuf, &addrLen); sin = (struct sockaddr_in*) &addrBuf; AJ_InfoPrintf(("AJ_Net_MCastUp(): mDNS recv port: %d\n", ntohs(sin->sin_port))); } if (NumMcastSocks == 0) { AJ_ErrPrintf(("AJ_Net_MCastUp(): No mDNS recv socket found. status=AJ_ERR_READ\n")); return AJ_ERR_READ; } numMDnsRecvSocks = NumMcastSocks; // create the sending sockets Mcast4Up(MDNS_IPV4_MULTICAST_GROUP, MDNS_UDP_PORT, TRUE, ntohs(sin->sin_port)); Mcast6Up(MDNS_IPV6_MULTICAST_GROUP, MDNS_UDP_PORT, TRUE, ntohs(sin->sin_port)); // create the NS sockets only if considering pre-14.06 routers if (AJ_GetMinProtoVersion() < 10) { Mcast4Up(AJ_IPV4_MULTICAST_GROUP, AJ_UDP_PORT, FALSE, 0); Mcast6Up(AJ_IPV6_MULTICAST_GROUP, AJ_UDP_PORT, FALSE, 0); } AJ_IOBufInit(&mcastSock->rx, rxDataMCast, sizeof(rxDataMCast), AJ_IO_BUF_RX, (void*) McastSocks); mcastSock->rx.recv = AJ_Net_RecvFrom; AJ_IOBufInit(&mcastSock->tx, txDataMCast, sizeof(txDataMCast), AJ_IO_BUF_TX, (void*) McastSocks); mcastSock->tx.send = AJ_Net_SendTo; return AJ_OK; }
AJ_Status AJ_Net_Connect(AJ_BusAttachment* bus, const AJ_Service* service) { DWORD ret; SOCKADDR_STORAGE addrBuf; socklen_t addrSize; SOCKET sock; /* Initialize Winsock, if not done already */ WinsockCheck(); #ifdef AJ_ARDP if (service->addrTypes & (AJ_ADDR_UDP4 | AJ_ADDR_UDP6)) { return AJ_Net_ARDP_Connect(bus, service); } #endif AJ_InfoPrintf(("AJ_Net_Connect(bus=0x%p, addrType=%d.)\n", bus, service->addrTypes)); memset(&addrBuf, 0, sizeof(addrBuf)); if (service->addrTypes & AJ_ADDR_TCP4) { struct sockaddr_in* sa = (struct sockaddr_in*)&addrBuf; sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (sock == INVALID_SOCKET) { AJ_ErrPrintf(("AJ_Net_Connect(): invalid socket. status=AJ_ERR_CONNECT\n")); return AJ_ERR_CONNECT; } sa->sin_family = AF_INET; sa->sin_port = htons(service->ipv4port); sa->sin_addr.s_addr = service->ipv4; addrSize = sizeof(*sa); AJ_InfoPrintf(("AJ_Net_Connect(): Connect to \"%s:%u\"\n", inet_ntoa(sa->sin_addr), service->ipv4port));; } else if (service->addrTypes & AJ_ADDR_TCP6) { struct sockaddr_in6* sa = (struct sockaddr_in6*)&addrBuf; sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (sock == INVALID_SOCKET) { AJ_ErrPrintf(("AJ_Net_Connect(): invalid socket. status=AJ_ERR_CONNECT\n")); return AJ_ERR_CONNECT; } sa->sin6_family = AF_INET6; sa->sin6_port = htons(service->ipv6port); memcpy(sa->sin6_addr.s6_addr, service->ipv6, sizeof(sa->sin6_addr.s6_addr)); addrSize = sizeof(*sa); } else { AJ_ErrPrintf(("AJ_Net_Connect: only TCPv6 and TCPv4 are supported\n")); return AJ_ERR_CONNECT; } ret = connect(sock, (struct sockaddr*)&addrBuf, addrSize); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed. WSAGetLastError()=0x%x, status=AJ_ERR_CONNECT\n", WSAGetLastError())); closesocket(sock); return AJ_ERR_CONNECT; } else { AJ_IOBufInit(&bus->sock.rx, rxData, sizeof(rxData), AJ_IO_BUF_RX, &netContext); bus->sock.rx.recv = AJ_Net_Recv; AJ_IOBufInit(&bus->sock.tx, txData, sizeof(txData), AJ_IO_BUF_TX, &netContext); bus->sock.tx.send = AJ_Net_Send; netContext.tcpSock = sock; AJ_InfoPrintf(("AJ_Net_Connect(): status=AJ_OK\n")); sendEvent = CreateEvent(NULL, TRUE, FALSE, NULL); recvEvent = CreateEvent(NULL, TRUE, FALSE, NULL); interruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL); wsaOverlapped.hEvent = INVALID_HANDLE_VALUE; return AJ_OK; } }
static AJ_Status AJ_Net_ARDP_Connect(AJ_BusAttachment* bus, const AJ_Service* service) { SOCKET udpSock = INVALID_SOCKET; AJ_Status status; SOCKADDR_STORAGE addrBuf; socklen_t addrSize; DWORD ret; AJ_ARDP_InitFunctions(AJ_ARDP_UDP_Recv, AJ_ARDP_UDP_Send); // otherwise backpressure is guaranteed! assert(sizeof(txData) <= UDP_SEGMAX * (UDP_SEGBMAX - ARDP_HEADER_SIZE - UDP_HEADER_SIZE)); memset(&addrBuf, 0, sizeof(addrBuf)); if (service->addrTypes & AJ_ADDR_UDP4) { struct sockaddr_in* sa = (struct sockaddr_in*) &addrBuf; udpSock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED); if (udpSock == INVALID_SOCKET) { AJ_ErrPrintf(("AJ_Net_ARDP_Connect(): socket() failed. status=AJ_ERR_CONNECT\n")); goto ConnectError; } sa->sin_family = AF_INET; sa->sin_port = htons(service->ipv4portUdp); sa->sin_addr.s_addr = service->ipv4Udp; addrSize = sizeof(struct sockaddr_in); AJ_InfoPrintf(("AJ_Net_ARDP_Connect(): Connect to \"%s:%u\"\n", inet_ntoa(sa->sin_addr), service->ipv4portUdp));; } else if (service->addrTypes & AJ_ADDR_UDP6) { struct sockaddr_in6* sa = (struct sockaddr_in6*) &addrBuf; udpSock = WSASocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED); if (udpSock == INVALID_SOCKET) { AJ_ErrPrintf(("AJ_Net_ARDP_Connect(): socket() failed. status=AJ_ERR_CONNECT\n")); goto ConnectError; } sa->sin6_family = AF_INET6; sa->sin6_port = htons(service->ipv6portUdp); memcpy(sa->sin6_addr.s6_addr, service->ipv6Udp, sizeof(sa->sin6_addr.s6_addr)); addrSize = sizeof(struct sockaddr_in6); } else { AJ_ErrPrintf(("AJ_Net_ARDP_Connect(): Invalid addrTypes %u, status=AJ_ERR_CONNECT\n", service->addrTypes)); return AJ_ERR_CONNECT; } ret = connect(udpSock, (struct sockaddr*) &addrBuf, addrSize); // must do this before calling AJ_MarshalMethodCall! if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_Connect(): connect() failed. WSAGetLastError()=0x%x, status=AJ_ERR_CONNECT\n", WSAGetLastError())); goto ConnectError; } else { netContext.udpSock = udpSock; AJ_IOBufInit(&bus->sock.rx, rxData, sizeof(rxData), AJ_IO_BUF_RX, &netContext); bus->sock.rx.recv = AJ_ARDP_Recv; AJ_IOBufInit(&bus->sock.tx, txData, sizeof(txData), AJ_IO_BUF_TX, &netContext); bus->sock.tx.send = AJ_ARDP_Send; sendEvent = CreateEvent(NULL, TRUE, FALSE, NULL); recvEvent = CreateEvent(NULL, TRUE, FALSE, NULL); interruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL); wsaOverlapped.hEvent = INVALID_HANDLE_VALUE; } status = AJ_ARDP_UDP_Connect(bus, &netContext, service, &bus->sock); if (status != AJ_OK) { goto ConnectError; } return AJ_OK; ConnectError: if (udpSock != INVALID_SOCKET) { closesocket(udpSock); } return AJ_ERR_CONNECT; }