/* Send RTSP message and get response */ static int transactRtspMessage(PRTSP_MESSAGE request, PRTSP_MESSAGE response) { SOCK_RET err; int ret = 0; int offset; char* serializedMessage = NULL; int messageLen; sock = connectTcpSocket(remoteAddr, 48010); if (sock == INVALID_SOCKET) { return ret; } enableNoDelay(sock); serializedMessage = serializeRtspMessage(request, &messageLen); if (serializedMessage == NULL) { closesocket(sock); return ret; } // Send our message err = send(sock, serializedMessage, messageLen, 0); if (err == SOCKET_ERROR) { goto Exit; } // Read the response until the server closes the connection offset = 0; for (;;) { err = recv(sock, &responseBuffer[offset], RTSP_MAX_RESP_SIZE - offset, 0); if (err <= 0) { // Done reading break; } offset += err; // Warn if the RTSP message is too big if (offset == RTSP_MAX_RESP_SIZE) { Limelog("RTSP message too long\n"); goto Exit; } } if (parseRtspMessage(response, responseBuffer, offset) == RTSP_ERROR_SUCCESS) { // Successfully parsed response ret = 1; } else { Limelog("Failed to parse RTSP response\n"); } Exit: if (serializedMessage != NULL) { free(serializedMessage); } closesocket(sock); sock = INVALID_SOCKET; return ret; }
// Start the video stream int startVideoStream(void* rendererContext, int drFlags) { int err; // This must be called before the decoder thread starts submitting // decode units LC_ASSERT(NegotiatedVideoFormat != 0); VideoCallbacks.setup(NegotiatedVideoFormat, StreamConfig.width, StreamConfig.height, StreamConfig.fps, rendererContext, drFlags); rtpSocket = bindUdpSocket(RemoteAddr.ss_family, RTP_RECV_BUFFER); if (rtpSocket == INVALID_SOCKET) { return LastSocketError(); } err = PltCreateThread(ReceiveThreadProc, NULL, &receiveThread); if (err != 0) { return err; } if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { err = PltCreateThread(DecoderThreadProc, NULL, &decoderThread); if (err != 0) { return err; } } if (ServerMajorVersion == 3) { // Connect this socket to open port 47998 for our ping thread firstFrameSocket = connectTcpSocket(&RemoteAddr, RemoteAddrLen, FIRST_FRAME_PORT, FIRST_FRAME_TIMEOUT_SEC); if (firstFrameSocket == INVALID_SOCKET) { return LastSocketError(); } } // Start pinging before reading the first frame so GFE knows where // to send UDP data err = PltCreateThread(UdpPingThreadProc, NULL, &udpPingThread); if (err != 0) { return err; } if (ServerMajorVersion == 3) { // Read the first frame to start the flow of video err = readFirstFrame(); if (err != 0) { return err; } } return 0; }
/* Begin the input stream */ int startInputStream(void) { int err; inputSock = connectTcpSocket(&RemoteAddr, RemoteAddrLen, 35043); if (inputSock == INVALID_SOCKET) { return LastSocketFail(); } enableNoDelay(inputSock); err = PltCreateThread(inputSendThreadProc, NULL, &inputSendThread); if (err != 0) { return err; } return err; }
/* Starts the control stream */ int startControlStream(void) { int err; ctlSock = connectTcpSocket(&RemoteAddr, RemoteAddrLen, 47995); if (ctlSock == INVALID_SOCKET) { return LastSocketFail(); } enableNoDelay(ctlSock); // Send START A if (!sendMessageAndDiscardReply(packetTypes[IDX_START_A], payloadLengths[IDX_START_A], preconstructedPayloads[IDX_START_A])) { Limelog("Start A failed: %d\n", (int)LastSocketError()); return LastSocketFail(); } // Send START B if (!sendMessageAndDiscardReply(packetTypes[IDX_START_B], payloadLengths[IDX_START_B], preconstructedPayloads[IDX_START_B])) { Limelog("Start B failed: %d\n", (int)LastSocketError()); return LastSocketFail(); } err = PltCreateThread(lossStatsThreadFunc, NULL, &lossStatsThread); if (err != 0) { return err; } err = PltCreateThread(resyncThreadFunc, NULL, &resyncThread); if (err != 0) { return err; } return 0; }
void *bluetoothThreadFunction( void *d ) { struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 }; char buf[BT_BUFFER_SIZE] = { 0 }; int client, bytes_read, status; unsigned int opt = sizeof(rem_addr); fd_set readfds; fd_set master; int maxfd, sock_flags, i; struct timeval timeout; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); bluetoothtoken_t *bt = (bluetoothtoken_t*)d; FD_ZERO(&master); FD_ZERO(&readfds); // put server socket into nonblocking mode sock_flags = fcntl( bt->s, F_GETFL, 0 ); fcntl( bt->s, F_SETFL, sock_flags | O_NONBLOCK ); FD_SET(bt->s, &master); maxfd = bt->s; while(1) { readfds = master; if(select(maxfd+1, &readfds, NULL, NULL, NULL) == -1) { logError("bt-server select failed, bluetooth thread dies"); //TODO close all pairs pthread_exit(NULL); return NULL; } for(i=0;i<=maxfd;i++) { if(FD_ISSET(i, &readfds)) { if (i == bt->s) { client = accept( bt->s, (struct sockaddr*)&rem_addr, &opt ); if( client >= 0 ){ FD_SET(client, &master); /* add to master set */ if(client > maxfd) { maxfd = client; } logDebug("new bt connection! tcp..."); int tcpfd; while((tcpfd = connectTcpSocket(hostname, portno))<0) { logError("failed to setup tcp socket for bt connection: %d, retrying", tcpfd); sleep(1); } FD_SET(tcpfd, &master); if (tcpfd > maxfd) { maxfd = tcpfd; } addPair(client, tcpfd); logDebug("new bt <-> tcp connection!"); } else { logError("bt accept failed"); } } else { bytes_read = read(i, buf, sizeof(buf)); if (bytes_read <= 0) { logError("rx error, closing both"); // don't know if it was bt or tcp socket... closePair(i, 0, &master); closePair(0, i, &master); } else { if(peerWrite(i, buf, bytes_read) != bytes_read) { logError("tx error, closing both"); closePair(i, 0, &master); closePair(0, i, &master); } } } } } } logDebug("bluetooth thread finished"); pthread_exit(NULL); return NULL; }