// Roco.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <winsock2.h> #pragma comment(lib, "Ws2_32.lib") void broadcastThreadFunction(void *context) { const SOCKET *broadcastSocket = (SOCKET*)context; sockaddr_in broadcastSocketServiceInfo; ZeroMemory(&broadcastSocketServiceInfo, sizeof(broadcastSocketServiceInfo)); broadcastSocketServiceInfo.sin_family = AF_INET; broadcastSocketServiceInfo.sin_addr.s_addr = htonl(INADDR_BROADCAST); broadcastSocketServiceInfo.sin_port = htons(28777); static const char broadcastMessage[] = "ROCO-BROADCAST-MESSAGE"; do { const int result = sendto(*broadcastSocket, broadcastMessage, sizeof(broadcastMessage), 0, (SOCKADDR*)&broadcastSocketServiceInfo, sizeof(broadcastSocketServiceInfo)); if (result == SOCKET_ERROR && ::WSAGetLastError() == WSAENOTSOCK) { break; } ::Sleep(300); } while (true); _endthread(); } int _tmain(int argc, _TCHAR* argv[]) { if (argc >= 2 && _tcscmp(argv[1], _T("/silent")) == 0) { ::ShowWindow(::GetConsoleWindow(), SW_HIDE); } WSADATA wsaData; ZeroMemory(&wsaData, sizeof(wsaData)); printf("Initializing network... "); int result = ::WSAStartup(MAKEWORD(2,2), &wsaData); if (result == NO_ERROR) { printf("Done.\n"); printf("Creating broadcast socket... "); const SOCKET broadcastSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (broadcastSocket != INVALID_SOCKET) { printf("Done.\n"); static const BOOL onValue = TRUE; setsockopt(broadcastSocket, SOL_SOCKET, SO_BROADCAST, (const char*)&onValue, sizeof(onValue)); printf("Starting broadcast thread... "); HANDLE broadcastThreadHandle =(HANDLE)_beginthread(broadcastThreadFunction, 0, (void*)&broadcastSocket); if (broadcastThreadHandle != INVALID_HANDLE_VALUE) { printf("Done.\n"); printf("Creating listen socket... "); const SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenSocket != INVALID_SOCKET) { printf("Done.\n"); printf("Binding listen socket... "); sockaddr_in listenSocketServiceInfo; ZeroMemory(&listenSocketServiceInfo, sizeof(listenSocketServiceInfo)); listenSocketServiceInfo.sin_family = AF_INET; listenSocketServiceInfo.sin_addr.s_addr = htonl(INADDR_ANY); listenSocketServiceInfo.sin_port = htons(28666); result = bind(listenSocket, (SOCKADDR*)&listenSocketServiceInfo, sizeof(listenSocketServiceInfo)); if (result != SOCKET_ERROR) { printf("Done.\n"); printf("Listening for incoming connection... "); result = listen(listenSocket, SOMAXCONN); if (result != SOCKET_ERROR) { printf("Done.\n"); unsigned connectionIndex = 0; do { printf("Accepting incoming connection #%d... ", connectionIndex + 1); ::ResumeThread(broadcastThreadHandle); SOCKET commandSocket = accept(listenSocket, NULL, NULL); if (commandSocket != INVALID_SOCKET) { printf("Done.\n"); ::SuspendThread(broadcastThreadHandle); printf("Sending PING to command socket... "); static const char ping[] = "PING"; result = send(commandSocket, ping, sizeof(ping), 0); if (result != SOCKET_ERROR && result == sizeof(ping)) { printf("Done.\n"); printf("Receiving PONG from command socket... "); static char pong[sizeof("PONG")]; pong[0] = '\0'; result = recv(commandSocket, pong, sizeof(pong), 0); if (result != SOCKET_ERROR && result == sizeof(pong) && strcmp(pong, "PONG") == 0) { printf("Done.\n"); unsigned commandIndex = 0; do { printf("Waiting for command #%d...\n", commandIndex + 1); static char command[2]; ZeroMemory(command, sizeof(command)); result = recv(commandSocket, command, sizeof(command), 0); if (result != SOCKET_ERROR && result == sizeof(command)) { enum { CC_KEY_DOWM = 1, CC_KEY_UP = 0 }; const char commandCode = command[0]; const char keyCode = command[1]; static const char res = 1; switch (commandCode) { case CC_KEY_DOWM: { printf("KEY_DOWN(%d)\n", keyCode); keybd_event(keyCode, 0, 0, 0); send(commandSocket, &res, sizeof(res), 0); } break; case CC_KEY_UP: { printf("KEY_UP(%d)\n", keyCode); keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0); send(commandSocket, &res, sizeof(res), 0); } break; default: { printf("Invalid command received - %d!\n", commandCode); } break; } } else { printf("Could not receive command from socket (error - %d)!\n", ::WSAGetLastError()); break; } ++commandIndex; } while (true); } else { printf("\nCould not receive PONG from command socket (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not sent PING to command socket (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not accept incoming connection (error - %d)!\n", ::WSAGetLastError()); } ++connectionIndex; } while (true); } else { printf("\nCould not listen for incoming connection (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not bind listen socket (error - %d)!\n", ::WSAGetLastError()); } closesocket(listenSocket); } else { printf("\nCould not create listen socket (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not start broadcast thread!\n"); } ::ResumeThread(broadcastThreadHandle); closesocket(broadcastSocket); ::WaitForSingleObject(broadcastThreadHandle, INFINITE); } else { printf("\nCould not create broadcast socket (error - %d)!\n", ::WSAGetLastError()); } ::WSACleanup(); } else { printf("\nWSAStartup failed (error - %d)!", result); } return 0; }
::ShowWindow(::GetConsoleWindow(), SW_HIDE);
package com.dummy.roco; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.Socket; import java.util.Timer; import java.util.TimerTask; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.MulticastLock; import android.os.Bundle; import android.os.StrictMode; import android.os.Vibrator; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.LinearLayout; public class RemoteControlActivity extends Activity { protected static class ButtonInfo { public final String text_; public final int code_; public ButtonInfo(final String text, final int code) { text_ = text; if (code != 0) { code_ = code; } else { code_ = text.codePointAt(0); } } } protected static class CommandButton extends Button { protected ButtonInfo buttonInfo_; protected Socket commandSocket_; protected Vibrator vibrator_; protected Timer commandTimer_; protected final int COMMAND_DELAY = 200; public CommandButton(final Context context, final ButtonInfo buttonInfo, final Socket commandSocket, final Vibrator vibrator) { super(context); buttonInfo_ = buttonInfo; commandSocket_ = commandSocket; vibrator_ = vibrator; setText(buttonInfo_.text_); setTextSize(getTextSize()); setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startCommandTimer(); break; case MotionEvent.ACTION_UP: stopCommandTimer(); break; } return false; } }); } protected void sendCommand(final int commandCode, final int buttonCode) { final byte command[] = { (byte) commandCode, (byte) buttonCode }; try { commandSocket_.getOutputStream().write(command); } catch (Exception exception) { exception.printStackTrace(); } } public void startCommandTimer() { vibrator_.vibrate(10); sendCommand(CC_KEY_DOWM, buttonInfo_.code_); commandTimer_ = new Timer(); commandTimer_.schedule(new TimerTask() { @Override public void run() { sendCommand(CC_KEY_DOWM, buttonInfo_.code_); } }, COMMAND_DELAY, COMMAND_DELAY); } public void stopCommandTimer() { commandTimer_.cancel(); commandTimer_.purge(); commandTimer_ = null; sendCommand(CC_KEY_UP, buttonInfo_.code_); vibrator_.vibrate(10); } } protected static final ButtonInfo buttonInfos_[][] = { { new ButtonInfo("1", 0), new ButtonInfo("2", 0), new ButtonInfo("3", 0) }, { new ButtonInfo("4", 0), new ButtonInfo("5", 0), new ButtonInfo("6", 0) }, { new ButtonInfo("7", 0), new ButtonInfo("8", 0), new ButtonInfo("9", 0) }, { new ButtonInfo("¾", 8), new ButtonInfo("↑", 38), new ButtonInfo("¤", 77) }, { new ButtonInfo("←", 37), new ButtonInfo("®", 13), new ButtonInfo("→", 39) }, { new ButtonInfo("§", 32), new ButtonInfo("↓", 40), new ButtonInfo("«", 27) } }; protected static final int CC_KEY_DOWM = 1; protected static final int CC_KEY_UP = 0; protected final Socket commandSocket_ = new Socket(); protected Vibrator vibrator_; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); vibrator_ = (Vibrator) getSystemService(VIBRATOR_SERVICE); final LinearLayout mainLayout = new LinearLayout(this); mainLayout.setOrientation(LinearLayout.VERTICAL); for (int i = 0; i < buttonInfos_.length; ++i) { final LinearLayout rowLayout = new LinearLayout(this); rowLayout.setOrientation(LinearLayout.HORIZONTAL); for (int j = 0; j < buttonInfos_[i].length; ++j) { final CommandButton button = new CommandButton(this, buttonInfos_[i][j], commandSocket_, vibrator_); final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); layoutParams.weight = 1.0f; rowLayout.addView(button, layoutParams); } final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); layoutParams.weight = 1.0f; mainLayout.addView(rowLayout, layoutParams); } setContentView(mainLayout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); MulticastLock multicastLock = null; DatagramSocket broadcastSocket = null; try { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .permitAll().build()); final WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); if (wifiManager != null) { multicastLock = wifiManager .createMulticastLock("ROCO-MulticastLock"); } if (multicastLock != null) { multicastLock.acquire(); } broadcastSocket = new DatagramSocket(28777); broadcastSocket.setBroadcast(true); broadcastSocket.setSoTimeout(1000); final byte[] datagramPacketData = new byte["ROCO-BROADCAST-MESSAGE\0" .length()]; final DatagramPacket datagramPacket = new DatagramPacket( datagramPacketData, datagramPacketData.length); broadcastSocket.receive(datagramPacket); if (new String(datagramPacketData) .compareTo("ROCO-BROADCAST-MESSAGE\0") != 0) { throw new Exception("Could not get ROCO server address!"); } commandSocket_.setSoTimeout(500); commandSocket_.connect(new InetSocketAddress(datagramPacket .getAddress().getHostAddress(), 28666), commandSocket_ .getSoTimeout()); final byte ping[] = new byte["PING\0".length()]; commandSocket_.getInputStream().read(ping); if (new String(ping).compareTo("PING\0") != 0) { throw new Exception( "Could not receive PING from command socket!"); } commandSocket_.getOutputStream().write( new String("PONG\0").getBytes()); } catch (Exception exception) { final AlertDialog alertDialog = new AlertDialog.Builder(this) .create(); alertDialog.setCancelable(false); alertDialog.setTitle("Roco: Error"); alertDialog .setMessage("Could not connect to the server!\nError - '" + exception.toString() + "'\n\nExiting..."); alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); finish(); } }); alertDialog.show(); } finally { if (broadcastSocket != null) { broadcastSocket.close(); } if (multicastLock != null && multicastLock.isHeld()) { multicastLock.release(); } } } @Override protected void onDestroy() { try { commandSocket_.close(); } catch (Exception exception) { exception.printStackTrace(); } super.onDestroy(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK)) { finish(); } return super.onKeyDown(keyCode, event); } }
Source: https://habr.com/ru/post/224429/
All Articles