prepare(" SELECT r.id, r.driver_id, p.first_name, p.last_name FROM ride r JOIN passengers p ON p.id = r.passenger_id WHERE r.id = :rid AND r.passenger_id = :pid AND r.status IN ('accepted', 'arrived', 'started', 'begin') LIMIT 1 "); $stmt->execute([':rid' => $rideId, ':pid' => $jwt->user_id]); $ride = $stmt->fetch(); if (!$ride) { printFailure('No active ride found matching request', 404); exit; } $driverId = $ride['driver_id']; if (empty($driverId) || $driverId === 'yet') { printFailure('No driver accepted this ride yet', 400); exit; } $callerName = trim($ride['first_name'] . ' ' . $ride['last_name']); // 2. Query Node.js signaling server to establish session $url = (getenv('VOICE_CALL_SERVER_URL') ?: 'https://calls.intaleqapp.com') . '/sessions'; $apiKey = getenv('VOICE_CALL_API_KEY') ?: ''; $ch = curl_init($url); $payload = json_encode([ 'ride_id' => (string)$rideId, 'driver_id' => (string)$driverId, 'passenger_id' => (string)$jwt->user_id ]); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => [ "x-api-key: $apiKey", "Content-Type: application/json" ], CURLOPT_TIMEOUT => 5, CURLOPT_SSL_VERIFYPEER => false ]); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { error_log("[passenger_create_call_session.php] Signaling server session mapping failed: $result (HTTP $httpCode)"); printFailure('Signaling server error', 502); exit; } $sessionData = json_decode($result, true); if (!isset($sessionData['session_id'])) { printFailure('Invalid response schema from signaling server'); exit; } $sessionId = $sessionData['session_id']; // 3. Dispatch data-only FCM call trigger to Driver $stmtToken = $con->prepare(" SELECT token FROM driverToken WHERE captain_id = :did ORDER BY created_at DESC LIMIT 1 "); $stmtToken->execute([':did' => $driverId]); $driverTokenRow = $stmtToken->fetch(); if ($driverTokenRow && !empty($driverTokenRow['token'])) { sendFCMData( $driverTokenRow['token'], 'Incoming Call', 'Incoming WebRTC voice call', [ 'type' => 'incoming_call', 'session_id' => (string)$sessionId, 'caller_name' => $callerName, 'caller_avatar' => '', 'ride_id' => (string)$rideId ], 'Call' ); } printSuccess('Call session created successfully', [ 'session_id' => $sessionId, 'expires_in' => $sessionData['expires_in'] ?? 60 ]); } catch (Throwable $e) { error_log("[passenger_create_call_session.php] Critical exception: " . $e->getMessage()); printFailure('Server error', 500); }