diff --git a/AGENTS.md b/AGENTS.md index c420804..85617e9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,7 +15,8 @@ make - **C++ Standard**: C++11 (enforced) - **Build System**: CMake (generates `compile_commands.json` automatically) -- **Build Directory**: `/build` (ignored in git) +- **Build Directory**: `build/` (ignored in git) +- **PIP Library**: Installed at `/usr/local/include/pip` - **Entrypoint**: `src/main.cpp` ## Dependencies @@ -42,10 +43,24 @@ clang-format -i src/*.cpp src/*.h The server creates a `PIKbdListener` that: - Captures F10 key press for graceful exit -- Starts an HTTP server (address printed on startup) +- Starts an HTTP server on `0.0.0.0:8888` - Waits for exit signal via `WAIT_FOR_EXIT` macro +## API Endpoints + +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/connect` | GET | Connects TCP client to 127.0.0.1:1234 | +| `/api/disconnect` | GET | Disconnects TCP client | + +## Testing + +Use `reproduce_crash.sh` to test the TCP connect/disconnect functionality: +```bash +./reproduce_crash.sh +``` + ## Notes - Qt Creator is the primary IDE (`.qtcreator/` config present) -- No tests or CI configured +- No unit tests or CI configured diff --git a/reproduce_crash.sh b/reproduce_crash.sh new file mode 100755 index 0000000..360b538 --- /dev/null +++ b/reproduce_crash.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Script to test TCP connect/disconnect functionality + +BASE_URL="http://127.0.0.1:8888" + +echo "=== Test 1: Connect to TCP server ===" +echo "GET /api/connect" +curl -s "$BASE_URL/api/connect" +echo "" + +echo "" +echo "=== Test 2: Attempt reconnect (already connected) ===" +echo "GET /api/connect" +curl -s "$BASE_URL/api/connect" +echo "" + +echo "" +echo "=== Test 3: Disconnect from TCP server ===" +echo "GET /api/disconnect" +curl -s "$BASE_URL/api/disconnect" +echo "" + +echo "" +echo "=== Test 4: Attempt disconnect (already disconnected) ===" +echo "GET /api/disconnect" +curl -s "$BASE_URL/api/disconnect" +echo "" + +echo "" +echo "=== Test 5: Reconnect after disconnect ===" +echo "GET /api/connect" +curl -s "$BASE_URL/api/connect" +echo "" + +echo "" +echo "=== Test 6: Final disconnect ===" +echo "GET /api/disconnect" +curl -s "$BASE_URL/api/disconnect" +echo "" diff --git a/src/main.cpp b/src/main.cpp index 6535043..222cf61 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,79 @@ +#include +#include +#include #include +#include #include +// Global TCP client +PIClientServer::Client * tcpClient = nullptr; + +// Connect handler - connects to 127.0.0.1:1234 +PIHTTP::MessageMutable handleConnect(const PIHTTP::MessageConst & request) { + PIHTTP::MessageMutable response; + + if (!tcpClient) { + tcpClient = new PIClientServer::Client(); + } + + // Check if already connected via underlying TCP + if (tcpClient->getTCP() && tcpClient->getTCP()->isConnecting()) { + response.setCode(PIHTTP::Code::Ok); + response.setBody(PIString("Already connected").toUTF8()); + } else { + // Connect to server - PIClientServer::Client handles threading internally + PINetworkAddress addr("127.0.0.1", 1234); + tcpClient->connect(addr); + piMSleep(10); + response.setCode(PIHTTP::Code::Ok); + response.setBody(PIString("Connected to 127.0.0.1:1234").toUTF8()); + } + + piCout << "[handleConnect]" << PIString::fromUTF8(response.body()); + return response; +} + +// Disconnect handler - disconnects from the TCP server +PIHTTP::MessageMutable handleDisconnect(const PIHTTP::MessageConst & request) { + PIHTTP::MessageMutable response; + + if (tcpClient && tcpClient->getTCP() && tcpClient->getTCP()->isConnecting()) { + tcpClient->stopAndWait(); + tcpClient->close(); + piDeleteSafety(tcpClient); + response.setCode(PIHTTP::Code::Ok); + response.setBody(PIString("Disconnected").toUTF8()); + } else { + response.setCode(PIHTTP::Code::Ok); + response.setBody(PIString("Not connected").toUTF8()); + } + + piCout << "[handleDisconnect]" << PIString::fromUTF8(response.body()); + return response; +} + + int main(int argc, char * argv[]) { PIKbdListener ls; ls.enableExitCapture(PIKbdListener::F10); ls.start(); - piCout << "started on" << httpaddr; + + // Create HTTP server + PIHTTPServer server; + + // Register API endpoints + server.registerPath("/api/connect", PIHTTP::Method::Get, handleConnect); + server.registerPath("/api/disconnect", PIHTTP::Method::Get, handleDisconnect); + + // Start server on all interfaces, port 8888 + server.listenAll(8888); + + piCout << "HTTP server started on 0.0.0.0:8888"; + piCout << "\nEndpoints:"; + piCout << "\n GET /api/connect - Connect to 127.0.0.1:1234"; + piCout << "\n GET /api/disconnect - Disconnect from TCP server"; + WAIT_FOR_EXIT ls.stopAndWait(); }