fix: per-peer SDP handling and invitePeer group context
SDP payloads (offer, answer, renegotiate) are specific to individual PeerConnections and cannot be shared across peers. This commit: - Adds group-context overloads to createCallOffer, createCallAnswer, and createRenegotiate that include all member p-tags but wrap to a single target peer - Removes createGroupRenegotiate (renegotiation is always per-peer) - Updates sendRenegotiation/sendRenegotiationAnswer to take explicit peerPubKey and use per-peer wrapping with group p-tags - Updates invitePeer to include all existing group members + invitee in p-tags so the new peer sees the full group composition - Documents SDP per-peer vs sign-once distinction in NIP-AC spec https://claude.ai/code/session_013h2E7spwHDgSjunqumsYgp
This commit is contained in:
+43
-18
@@ -299,30 +299,46 @@ class CallManager(
|
||||
onRenegotiationOfferReceived?.invoke(event)
|
||||
}
|
||||
|
||||
suspend fun sendRenegotiation(sdpOffer: String) {
|
||||
/**
|
||||
* Sends a renegotiation offer to a specific peer. SDP is per-PeerConnection
|
||||
* so this is always addressed to a single peer. In group calls the inner
|
||||
* event includes `p` tags for all members for group context.
|
||||
*/
|
||||
suspend fun sendRenegotiation(
|
||||
sdpOffer: String,
|
||||
peerPubKey: HexKey,
|
||||
) {
|
||||
val callId = currentCallId() ?: return
|
||||
val peerPubKeys = currentPeerPubKeys() ?: return
|
||||
|
||||
if (peerPubKeys.size > 1) {
|
||||
val result = factory.createGroupRenegotiate(sdpOffer, peerPubKeys, callId, signer)
|
||||
result.wraps.forEach { publishEvent(it) }
|
||||
} else {
|
||||
val result = factory.createRenegotiate(sdpOffer, peerPubKeys.first(), callId, signer)
|
||||
publishEvent(result.wrap)
|
||||
}
|
||||
val result =
|
||||
if (peerPubKeys.size > 1) {
|
||||
factory.createRenegotiate(sdpOffer, peerPubKey, peerPubKeys, callId, signer)
|
||||
} else {
|
||||
factory.createRenegotiate(sdpOffer, peerPubKey, callId, signer)
|
||||
}
|
||||
publishEvent(result.wrap)
|
||||
}
|
||||
|
||||
suspend fun sendRenegotiationAnswer(sdpAnswer: String) {
|
||||
/**
|
||||
* Sends a renegotiation answer to a specific peer. SDP is per-PeerConnection
|
||||
* so this is always addressed to a single peer. In group calls the inner
|
||||
* event includes `p` tags for all members for group context.
|
||||
*/
|
||||
suspend fun sendRenegotiationAnswer(
|
||||
sdpAnswer: String,
|
||||
peerPubKey: HexKey,
|
||||
) {
|
||||
val callId = currentCallId() ?: return
|
||||
val peerPubKeys = currentPeerPubKeys() ?: return
|
||||
|
||||
if (peerPubKeys.size > 1) {
|
||||
val result = factory.createGroupCallAnswer(sdpAnswer, peerPubKeys, callId, signer)
|
||||
result.wraps.forEach { publishEvent(it) }
|
||||
} else {
|
||||
val result = factory.createCallAnswer(sdpAnswer, peerPubKeys.first(), callId, signer)
|
||||
publishEvent(result.wrap)
|
||||
}
|
||||
val result =
|
||||
if (peerPubKeys.size > 1) {
|
||||
factory.createCallAnswer(sdpAnswer, peerPubKey, peerPubKeys, callId, signer)
|
||||
} else {
|
||||
factory.createCallAnswer(sdpAnswer, peerPubKey, callId, signer)
|
||||
}
|
||||
publishEvent(result.wrap)
|
||||
}
|
||||
|
||||
fun onPeerConnected() {
|
||||
@@ -339,7 +355,11 @@ class CallManager(
|
||||
)
|
||||
}
|
||||
|
||||
/** Invites a new peer into the current call by sending them an offer. */
|
||||
/**
|
||||
* Invites a new peer into the current call by sending them an offer.
|
||||
* The inner event includes `p` tags for all existing group members plus
|
||||
* the new invitee so they can see the full group composition.
|
||||
*/
|
||||
suspend fun invitePeer(
|
||||
peerPubKey: HexKey,
|
||||
sdpOffer: String,
|
||||
@@ -347,16 +367,19 @@ class CallManager(
|
||||
val current = _state.value
|
||||
val callId: String
|
||||
val callType: CallType
|
||||
val existingMembers: Set<HexKey>
|
||||
when (current) {
|
||||
is CallState.Connecting -> {
|
||||
callId = current.callId
|
||||
callType = current.callType
|
||||
existingMembers = current.peerPubKeys + current.pendingPeerPubKeys
|
||||
_state.value = current.copy(pendingPeerPubKeys = current.pendingPeerPubKeys + peerPubKey)
|
||||
}
|
||||
|
||||
is CallState.Connected -> {
|
||||
callId = current.callId
|
||||
callType = current.callType
|
||||
existingMembers = current.allPeerPubKeys
|
||||
_state.value = current.copy(pendingPeerPubKeys = current.pendingPeerPubKeys + peerPubKey)
|
||||
}
|
||||
|
||||
@@ -365,7 +388,9 @@ class CallManager(
|
||||
}
|
||||
}
|
||||
|
||||
val result = factory.createCallOffer(sdpOffer, peerPubKey, callId, callType, signer)
|
||||
// All group members: existing peers + the new invitee + ourselves
|
||||
val allMembers = existingMembers + peerPubKey + signer.pubKey
|
||||
val result = factory.createCallOffer(sdpOffer, peerPubKey, allMembers, callId, callType, signer)
|
||||
publishEvent(result.wrap)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user