int callback_emu ( struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len ) { static unsigned new_ws_port = 9001; char port_str[100] = {0}; switch (reason) { case LWS_CALLBACK_PROTOCOL_INIT: { ws = wsi; break; }; case LWS_CALLBACK_SERVER_WRITEABLE: { pid_t pid; sprintf(port_str, "%u", new_ws_port); // Child (pty) if( !(pid = fork()) ) { printf("Child: Got pid #%u\n", pid); char * const args[] = { "nice", "-20", "./MSP430", port_str, //"./MSP430", port_str, //"gdb", "-ex", "run", "--args", "./MSP430", port_str, NULL }; setpgid(0, 0); execvp(args[0], args); exit(1); } // Parent printf("Parent: Got pid #%u\n", pid); usleep(1000); web_send(port_str); ++new_ws_port; lws_close_reason(wsi, 0, NULL, 0); break; }; case LWS_CALLBACK_ESTABLISHED: { puts("connection established"); lws_callback_on_writable(wsi); break; } default: { printf("Some other thing: %d\n", reason); break; ws = wsi; } } return 0; }
int FLwsWebSocket::CallbackWrapper(struct lws *Instance, enum lws_callback_reasons Reason, void *UserData, void *Data, size_t Length) { FLwsWebSocket* Self = reinterpret_cast<FLwsWebSocket*>(UserData); switch (Reason) { case LWS_CALLBACK_PROTOCOL_INIT: case LWS_CALLBACK_PROTOCOL_DESTROY: case LWS_CALLBACK_GET_THREAD_ID: case LWS_CALLBACK_LOCK_POLL: case LWS_CALLBACK_UNLOCK_POLL: case LWS_CALLBACK_ADD_POLL_FD: case LWS_CALLBACK_DEL_POLL_FD: case LWS_CALLBACK_CHANGE_MODE_POLL_FD: case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: break; case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: { SSL_CTX* SslContext = reinterpret_cast<SSL_CTX*>(UserData); FSslModule::Get().GetCertificateManager().AddCertificatesToSslContext(SslContext); break; } case LWS_CALLBACK_CLIENT_ESTABLISHED: Self->bIsConnecting = false; Self->LwsConnection = Instance; if (!Self->SendQueue.IsEmpty()) { lws_callback_on_writable(Self->LwsConnection); } Self->OnConnected().Broadcast(); break; case LWS_CALLBACK_CLIENT_RECEIVE: { SIZE_T BytesLeft = lws_remaining_packet_payload(Instance); if(Self->OnMessage().IsBound()) { FUTF8ToTCHAR Convert((const ANSICHAR*)Data, Length); Self->ReceiveBuffer.Append(Convert.Get(), Convert.Length()); if (BytesLeft == 0) { Self->OnMessage().Broadcast(Self->ReceiveBuffer); Self->ReceiveBuffer.Empty(); } } Self->OnRawMessage().Broadcast(Data, Length, BytesLeft); break; } case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: { Self->LwsConnection = nullptr; Self->FlushQueues(); if (Self->OnClosed().IsBound()) { uint16 CloseStatus = *((uint16*)Data); #if PLATFORM_LITTLE_ENDIAN // The status is the first two bytes of the message in network byte order CloseStatus = BYTESWAP_ORDER16(CloseStatus); #endif FUTF8ToTCHAR Convert((const ANSICHAR*)Data + sizeof(uint16), Length - sizeof(uint16)); Self->OnClosed().Broadcast(CloseStatus, Convert.Get(), true); return 1; // Close the connection without logging if the user handles Close events } break; } case LWS_CALLBACK_WSI_DESTROY: // Getting a WSI_DESTROY before a connection has been established and no errors reported usually means there was a timeout establishing a connection if (Self->bIsConnecting) { //Self->OnConnectionError().Broadcast(TEXT("Connection timed out")); //Self->bIsConnecting = false; } if (Self->LwsConnection) { Self->LwsConnection = nullptr; } break; case LWS_CALLBACK_CLOSED: { bool ClientInitiated = Self->LwsConnection == nullptr; Self->LwsConnection = nullptr; Self->OnClosed().Broadcast(LWS_CLOSE_STATUS_NORMAL, ClientInitiated?TEXT("Successfully closed connection to server"):TEXT("Connection closed by server"), ClientInitiated); Self->FlushQueues(); break; } case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: { Self->LwsConnection = nullptr; FUTF8ToTCHAR Convert((const ANSICHAR*)Data, Length); Self->OnConnectionError().Broadcast(Convert.Get()); Self->FlushQueues(); return -1; break; } case LWS_CALLBACK_RECEIVE_PONG: break; case LWS_CALLBACK_CLIENT_WRITEABLE: case LWS_CALLBACK_SERVER_WRITEABLE: { if (Self->CloseCode != 0) { Self->LwsConnection = nullptr; FTCHARToUTF8 Convert(*Self->CloseReason); // This only sets the reason for closing the connection: lws_close_reason(Instance, (enum lws_close_status)Self->CloseCode, (unsigned char *)Convert.Get(), (size_t)Convert.Length()); Self->CloseCode = 0; Self->CloseReason = FString(); Self->FlushQueues(); return -1; // Returning non-zero will close the current connection } else { Self->SendFromQueue(); } break; } default: break; } return 0; }
int callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { unsigned char buf[LWS_PRE + 512]; struct per_session_data__dumb_increment *pss = (struct per_session_data__dumb_increment *)user; unsigned char *p = &buf[LWS_PRE]; int n, m; switch (reason) { case LWS_CALLBACK_ESTABLISHED: pss->number = 0; break; case LWS_CALLBACK_SERVER_WRITEABLE: n = sprintf((char *)p, "%d", pss->number++); m = lws_write(wsi, p, n, LWS_WRITE_TEXT); if (m < n) { lwsl_err("ERROR %d writing to di socket\n", n); return -1; } if (close_testing && pss->number == 50) { lwsl_info("close tesing limit, closing\n"); return -1; } break; case LWS_CALLBACK_RECEIVE: if (len < 6) break; if (strcmp((const char *)in, "reset\n") == 0) pss->number = 0; if (strcmp((const char *)in, "closeme\n") == 0) { lwsl_notice("dumb_inc: closing as requested\n"); lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY, (unsigned char *)"seeya", 5); return -1; } break; /* * this just demonstrates how to use the protocol filter. If you won't * study and reject connections based on header content, you don't need * to handle this callback */ case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: dump_handshake_info(wsi); /* you could return non-zero here and kill the connection */ break; /* * this just demonstrates how to handle * LWS_CALLBACK_WS_PEER_INITIATED_CLOSE and extract the peer's close * code and auxiliary data. You can just not handle it if you don't * have a use for this. */ case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: lwsl_notice("LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len %lu\n", (unsigned long)len); for (n = 0; n < (int)len; n++) lwsl_notice(" %d: 0x%02X\n", n, ((unsigned char *)in)[n]); break; default: break; } return 0; }