From f8dd0ea5e85c28dedfd6dc4fca815e50dd5fa5ab Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Thu, 13 Apr 2023 15:11:33 -0700 Subject: [PATCH] using configured ice server --- app/mobile/src/context/useAppContext.hook.js | 4 +-- app/mobile/src/context/useRingContext.hook.js | 36 ++++++++----------- app/mobile/src/dashboard/Dashboard.jsx | 17 +++++++++ app/mobile/src/dashboard/Dashboard.styled.js | 18 +++++++++- app/mobile/src/dashboard/useDashboard.hook.js | 24 ++++++++++--- app/mobile/src/session/Session.jsx | 7 ++-- app/mobile/src/session/cards/Cards.jsx | 2 +- .../src/session/cards/cardItem/CardItem.jsx | 10 +++--- app/mobile/src/session/cards/useCards.hook.js | 8 +++++ app/mobile/src/session/useSession.hook.js | 8 ++--- 10 files changed, 94 insertions(+), 40 deletions(-) diff --git a/app/mobile/src/context/useAppContext.hook.js b/app/mobile/src/context/useAppContext.hook.js index ee900bc3..07fb6a12 100644 --- a/app/mobile/src/context/useAppContext.hook.js +++ b/app/mobile/src/context/useAppContext.hook.js @@ -181,8 +181,8 @@ export function useAppContext() { card.actions.setRevision(cardRev); } if (activity.ring) { - const { cardId, callId, calleeToken } = activity.ring; - ring.actions.ring(cardId, callId, calleeToken); + const { cardId, callId, calleeToken, iceUrl, iceUsername, icePassword } = activity.ring; + ring.actions.ring(cardId, callId, calleeToken, iceUrl, iceUsername, icePassword); } } catch (err) { diff --git a/app/mobile/src/context/useRingContext.hook.js b/app/mobile/src/context/useRingContext.hook.js index cc0b8b8c..647bf6b8 100644 --- a/app/mobile/src/context/useRingContext.hook.js +++ b/app/mobile/src/context/useRingContext.hook.js @@ -49,14 +49,6 @@ export function useRingContext() { const connected = useRef(false); const candidates = useRef([]); - const iceServers = [ - { - urls: 'turn:44.238.207.157:3478?transport=udp', - username: 'user', - credential: 'pass' - }, - ]; - const constraints = { mandatory: { OfferToReceiveAudio: true, @@ -168,9 +160,9 @@ export function useRingContext() { processing.current = false; } - const transmit = async (policy) => { + const transmit = async (policy, ice) => { - pc.current = new RTCPeerConnection({ iceServers }); + pc.current = new RTCPeerConnection({ iceServers: ice }); pc.current.addEventListener( 'connectionstatechange', event => { console.log("CONNECTION STATE", event); } ); @@ -234,7 +226,7 @@ export function useRingContext() { } } - const connect = async (policy, node, token, clearRing, clearAlive) => { + const connect = async (policy, node, token, clearRing, clearAlive, ice) => { // connect signal socket connected.current = false; @@ -256,7 +248,7 @@ export function useRingContext() { if (policy === 'polite') { connected.current = true; InCallManager.start({media: 'audio'}); - transmit('polite'); + transmit('polite', ice); polite(); } } @@ -311,7 +303,7 @@ export function useRingContext() { if (policy === 'impolite') { connected.current = true; InCallManager.start({media: 'audio'}); - transmit('impolite'); + transmit('impolite', ice); impolite(); } } @@ -335,9 +327,9 @@ export function useRingContext() { clearSession: () => { access.current = null; }, - ring: (cardId, callId, calleeToken) => { + ring: (cardId, callId, calleeToken, iceUrl, iceUsername, icePassword) => { const key = `${cardId}:${callId}` - const call = ringing.current.get(key) || { cardId, calleeToken, callId } + const call = ringing.current.get(key) || { cardId, calleeToken, callId, iceUrl, iceUsername, icePassword } call.expires = Date.now() + EXPIRE; ringing.current.set(key, call); updateState({ ringing: ringing.current }); @@ -369,7 +361,7 @@ export function useRingContext() { } } }, - accept: async (cardId, callId, contactNode, contactToken, calleeToken) => { + accept: async (cardId, callId, contactNode, contactToken, calleeToken, iceUrl, iceUsername, icePassword) => { if (calling.current) { throw new Error("active session"); } @@ -382,7 +374,8 @@ export function useRingContext() { updateState({ ringing: ringing.current, callStatus: "connecting", cardId }); calling.current = { callId, contactNode, contactToken, host: false }; - await connect('impolite', contactNode, calleeToken, () => {}, () => {}); + const ice = [{ urls: iceUrl, username: iceUsername, credential: icePassword }]; + await connect('impolite', contactNode, calleeToken, () => {}, () => {}, ice); } }, end: async () => { @@ -412,9 +405,9 @@ export function useRingContext() { // create call const { server, token } = access.current; const call = await addCall(server, token, cardId); - const { id, keepAlive, callerToken, calleeToken } = call; + const { id, keepAlive, callerToken, calleeToken, iceUrl, iceUsername, icePassword } = call; try { - await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken }); + await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, iceUrl, iceUsername, icePassword }); } catch (err) { console.log(err); @@ -436,7 +429,7 @@ export function useRingContext() { } } else { - await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken }); + await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, iceUrl, iceUsername, icePassword }); index += 1; } } @@ -447,7 +440,8 @@ export function useRingContext() { updateState({ callStatus: "ringing", cardId }); calling.current = { callId: id, host: true }; - await connect('polite', server, callerToken, () => clearInterval(ringInterval), () => clearInterval(aliveInterval)); + const ice = [{ urls: iceUrl, username: iceUsername, credential: icePassword }]; + await connect('polite', server, callerToken, () => clearInterval(ringInterval), () => clearInterval(aliveInterval), ice); }, enableVideo: async () => { if (!videoTrack.current) { diff --git a/app/mobile/src/dashboard/Dashboard.jsx b/app/mobile/src/dashboard/Dashboard.jsx index 7d891ab5..7168386b 100644 --- a/app/mobile/src/dashboard/Dashboard.jsx +++ b/app/mobile/src/dashboard/Dashboard.jsx @@ -191,6 +191,8 @@ export function Dashboard(props) { onValueChange={actions.setPushSupported} trackColor={styles.track}/> + + actions.setEnableImage(!state.enableImage)}> Enable Image Queue: @@ -209,6 +211,21 @@ export function Dashboard(props) { + + + actions.setEnableIce(!state.enableIce)}> + Enable WebRTC Calls: + + + + + + diff --git a/app/mobile/src/dashboard/Dashboard.styled.js b/app/mobile/src/dashboard/Dashboard.styled.js index e8c37d98..820410a4 100644 --- a/app/mobile/src/dashboard/Dashboard.styled.js +++ b/app/mobile/src/dashboard/Dashboard.styled.js @@ -194,7 +194,7 @@ export const styles = StyleSheet.create({ padding: 4, borderRadius: 4, marginBottom: 16, - fontSize: 16, + fontSize: 12, color: Colors.text, }, switch: { @@ -224,4 +224,20 @@ export const styles = StyleSheet.create({ borderRadius: 4, borderColor: Colors.divider, }, + label: { + borderTopWidth: 1, + borderColor: Colors.divider, + marginTop: 12, + }, + labelText: { + fontSize: 14, + color: Colors.text, + }, + ice: { + display: 'flex', + flexDirection: 'row', + marginTop: 8, + alignItems: 'center', + paddingBottom: 8, + } }); diff --git a/app/mobile/src/dashboard/useDashboard.hook.js b/app/mobile/src/dashboard/useDashboard.hook.js index 37628826..99063fa7 100644 --- a/app/mobile/src/dashboard/useDashboard.hook.js +++ b/app/mobile/src/dashboard/useDashboard.hook.js @@ -28,6 +28,10 @@ export function useDashboard(config, server, token) { enableAudio: true, enableVideo: true, createToken: null, + enableIce: false, + iceUrl: null, + iceUsername: null, + icePassword: null, }); const navigate = useNavigate(); @@ -55,8 +59,8 @@ export function useDashboard(config, server, token) { }; useEffect(() => { - const { keyType, accountStorage, domain, enableImage, enableAudio, enableVideo, pushSupported } = config; - updateState({ keyType, storage: accountStorage.toString(), domain, enableImage, enableAudio, enableVideo, pushSupported }); + const { keyType, accountStorage, domain, enableImage, enableAudio, enableVideo, pushSupported, enableIce, iceUrl, iceUsername, icePassword } = config; + updateState({ keyType, storage: accountStorage.toString(), domain, enableImage, enableAudio, enableVideo, pushSupported, enableIce, iceUrl, iceUsername, icePassword }); }, [config]); useEffect(() => { @@ -111,9 +115,21 @@ export function useDashboard(config, server, token) { setKeyType: (keyType) => { updateState({ keyType }); }, + setEnableIce: (enableIce) => { + updateState({ enableIce }); + }, + setIceUrl: (iceUrl) => { + updateState({ iceUrl }); + }, + setIceUsername: (iceUsername) => { + updateState({ iceUsername }); + }, + setIcePassword: (icePassword) => { + updateState({ icePassword }); + }, saveConfig: async () => { - const { storage, domain, keyType, enableImage, enableAudio, enableVideo } = state; - const config = { accountStorage: Number(storage), domain, keyType, enableImage, enableAudio, enableVideo }; + const { storage, domain, keyType, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword } = state; + const config = { accountStorage: Number(storage), domain, keyType, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword }; await setNodeConfig(server, token, config); }, enableUser: async (accountId, enabled) => { diff --git a/app/mobile/src/session/Session.jsx b/app/mobile/src/session/Session.jsx index 5bb95d62..ce6ed02b 100644 --- a/app/mobile/src/session/Session.jsx +++ b/app/mobile/src/session/Session.jsx @@ -329,7 +329,8 @@ export function Session() { useEffect(() => { let incoming = []; for (let i = 0; i < state.ringing.length; i++) { - const { img, name, handle, callId, cardId, contactNode, contactToken, calleeToken } = state.ringing[i]; + const call = state.ringing[i]; + const { img, cardId, callId, name, handle, contactNode } = call || {}; const label = name ? name : `${handle}@${contactNode}`; const key = `${cardId}:${callId}` incoming.push( @@ -339,10 +340,10 @@ export function Session() { actions.ignore({ cardId, callId })}> - actions.decline({ cardId, contactNode, contactToken, callId })}> + actions.decline(call)}> - actions.accept({ cardId, callId, contactNode, contactToken, calleeToken })}> + actions.accept(call)}> diff --git a/app/mobile/src/session/cards/Cards.jsx b/app/mobile/src/session/cards/Cards.jsx index 61fbf851..c5fcc952 100644 --- a/app/mobile/src/session/cards/Cards.jsx +++ b/app/mobile/src/session/cards/Cards.jsx @@ -66,7 +66,7 @@ export function CardsBody({ filter, sort, openContact, addChannel }) { data={state.cards} initialNumToRender={25} renderItem={({ item }) => call(item)} message={() => addChannel(item.cardId)} />} + enableIce={state.enableIce} call={() => call(item)} message={() => addChannel(item.cardId)} />} keyExtractor={item => item.cardId} /> )} diff --git a/app/mobile/src/session/cards/cardItem/CardItem.jsx b/app/mobile/src/session/cards/cardItem/CardItem.jsx index b4c51c68..89701683 100644 --- a/app/mobile/src/session/cards/cardItem/CardItem.jsx +++ b/app/mobile/src/session/cards/cardItem/CardItem.jsx @@ -4,7 +4,7 @@ import { styles } from './CardItem.styled'; import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import Colors from 'constants/Colors'; -export function CardItem({ item, openContact, call, message }) { +export function CardItem({ item, openContact, enableIce, call, message }) { const select = () => { const { guid, name, handle, node, location, description, imageSet } = item; @@ -26,9 +26,11 @@ export function CardItem({ item, openContact, call, message }) { - - - + { enableIce && ( + + + + )} )} { item.status === 'connected' && item.offsync === 1 && ( diff --git a/app/mobile/src/session/cards/useCards.hook.js b/app/mobile/src/session/cards/useCards.hook.js index 4d53bba8..6fb03c62 100644 --- a/app/mobile/src/session/cards/useCards.hook.js +++ b/app/mobile/src/session/cards/useCards.hook.js @@ -1,13 +1,16 @@ import { useState, useEffect, useRef, useContext } from 'react'; import { CardContext } from 'context/CardContext'; import { RingContext } from 'context/RingContext'; +import { AccountContext } from 'context/AccountContext'; export function useCards(filter, sort) { const [state, setState] = useState({ cards: [], + enableIce: false, }); + const account = useContext(AccountContext); const card = useContext(CardContext); const ring = useContext(RingContext); @@ -15,6 +18,11 @@ export function useCards(filter, sort) { setState((s) => ({ ...s, ...value })); } + useEffect(() => { + const { enableIce } = account.state.status || {}; + updateState({ enableIce }); + }, [account.state]); + const setCardItem = (item) => { const { profile, detail, cardId } = item.card || { profile: {}, detail: {} } const { name, handle, node, guid, location, description, imageSet } = profile; diff --git a/app/mobile/src/session/useSession.hook.js b/app/mobile/src/session/useSession.hook.js index 80578343..4f0687a1 100644 --- a/app/mobile/src/session/useSession.hook.js +++ b/app/mobile/src/session/useSession.hook.js @@ -44,14 +44,14 @@ export function useSession() { const expired = Date.now(); ring.state.ringing.forEach(call => { if (call.expires > expired && !call.status) { - const { callId, cardId, calleeToken } = call; + const { callId, cardId, calleeToken, iceUrl, iceUsername, icePassword } = call; const contact = card.state.cards.get(cardId); if (contact) { const { imageSet, name, handle, node, guid } = contact.card?.profile || {}; const { token } = contact.card?.detail || {}; const contactToken = `${guid}.${token}`; const img = imageSet ? card.actions.getCardImageUrl(cardId) : null; - ringing.push({ cardId, img, name, handle, contactNode: node, callId, contactToken, calleeToken }); + ringing.push({ cardId, img, name, handle, contactNode: node, callId, contactToken, calleeToken, iceUrl, iceUsername, icePassword }); } } }); @@ -106,8 +106,8 @@ export function useSession() { await ring.actions.decline(cardId, contactNode, contactToken, callId); }, accept: async (call) => { - const { cardId, callId, contactNode, contactToken, calleeToken } = call; - await ring.actions.accept(cardId, callId, contactNode, contactToken, calleeToken); + const { cardId, callId, contactNode, contactToken, calleeToken, iceUrl, iceUsername, icePassword } = call; + await ring.actions.accept(cardId, callId, contactNode, contactToken, calleeToken, iceUrl, iceUsername, icePassword); }, end: async () => { await ring.actions.end();