4. 需求和实现
下一节详细说明共享外观功能的需求, 并讨论其实现.
4.1. 需求
共享外观功能的基本需求可概括如下:
REQ-1: 发往 AOR 的来电必须提供给一组 UA, 并且可由其中任意 UA 应答.
REQ-2: 组内每个 UA 必须能够获知组内其他 UA 的呼叫状态, 以便向用户呈现这些信息.
REQ-3: UA 必须能够以安全方式加入 (也称为桥接或共同会议) 或接起 (接管) 组内另一个 UA 的活动呼叫.
REQ-4: 该机制应只需要最少配置. 向组 AOR 注册的 UA 应能够参与共享外观组, 而不需要手动配置组成员.
REQ-5: 该机制必须能够扩展到大量外观和大量 UA, 且不会引入过多消息流量.
REQ-6: 每个呼叫或会话 (传入或传出) 都应从为 AOR 组管理的池中分配一个公共 "外观" 编号. 一旦会话终止, 该外观编号会被释放回池中, 并可由另一个传入或传出会话复用.
REQ-7: 组内每个 UA 必须能够获知该组所有外观的状态.
REQ-8: 必须有机制解决组内 UA 之间的外观竞争 (appearance contention). 在此上下文中, 竞争是指一个外观编号被关联到多个未混合且无其他关联关系的 dialog.
REQ-9: 该机制必须允许所有接收传入会话请求的 UA 在振铃提示时使用相同的外观编号.
REQ-10: 该机制必须具备在故障后重建外观状态的方法, 且不会导致过多流量和处理开销.
REQ-11: 该机制必须具有向后兼容性, 使不了解该功能的 UA 仍可向组 AOR 注册并发起和接收呼叫.
REQ-12: 该机制不得允许组外 UA 选择, 占用或操纵外观编号.
REQ-13: 出于隐私原因, 必须有机制确保外观信息不会泄露到 UA 组之外 (例如, "So who do you have on line 1?").
REQ-14: 该机制必须支持 UA 请求对线路外观的独占性 (exclusivity). 独占性意味着发出请求的 UA 希望与外部方进行私密会话, 并且不得允许其他 UA 加入或接管该呼叫. 独占性可以在传入或传出会话开始时请求, 也可以在会话期间请求. 提供共享外观服务的实体可以接受或拒绝独占性请求. 因此, 该机制必须提供一种方式, 将结果传回请求方 UA.
REQ-15: 该机制应支持 UA 在发送实际请求之前为传出请求占用特定外观编号. 这通常称为占用 (seizure).
REQ-16: 该机制应支持 UA 占用特定外观编号并同时发送请求. 当自动摘机拨号 (automatic ringdown) 功能 (电话被配置为摘机后立即拨打某个电话号码) 与共享外观结合使用时, 需要此能力. 在这种情况下, 线路占用与拨号集成在一起.
4.2. 实现
本节以非规范性方式讨论共享外观功能的实现. 规范性描述见第 5 节. 该服务的许多需求可以使用标准 SIP 机制满足, 例如:
-
SIP 分叉代理 (Forking Proxy) 和注册器/位置服务 (Registrar/Location Service) 满足 REQ-1.
-
SIP Dialog Package 满足 REQ-2.
-
SIP Replaces 和 Join 头字段的组合满足 REQ-3.
-
为 Dialog Package 使用状态代理 (State Agent) 满足 REQ-4 和 REQ-5.
REQ-6 表明需要一个实体来管理外观资源. 正如会议系统通常有一个称为焦点 (focus) 的单一控制点, 共享外观组也有一个用于外观共享资源的单一控制点. 这被定义为组的外观代理 (Appearance Agent). 外观代理可以是集中式服务器的一部分, 也可以与承担该组功能的成员 UA 共驻. 外观代理知道或能够确定组内所有成员的 dialog 状态.
虽然外观资源可以由一组 UA 在没有任何集中控制的情况下协同管理, 但这超出本文档范围. 外观代理逻辑也可能分布在组内所有 UA 中. 例如, 需要定义并实现用于为传入请求分配外观编号的规则 (例如, 选择最低可用外观编号), 以及用于竞争处理的规则 (例如, 当两个 UA 请求使用同一外观编号时, 对 dialog 标识符进行哈希并比较, 最低哈希值胜出).
为了最好地满足 REQ-9, 传入 INVITE 的外观编号除了通过 dialog package NOTIFY 递送外, 还需要包含在该 INVITE 中. 否则, 如果 NOTIFY 延迟或丢失, 组内 UA 可能会收到传入 INVITE, 但不知道在振铃提示期间应呈现哪个外观编号.
本规范为 RFC 3261 中的 Alert-Info 头字段定义一个扩展参数来携带外观编号, 该参数在第 7 节中进行规范性定义:
Alert-Info: <urn:alert:service:normal>;appearance=1
以下列表描述共享外观功能的操作.
-
UA 被配置为使用共享外观组的 AOR. 它向该 AOR 注册, 然后尝试对该 AOR 进行 dialog 状态订阅. 如果订阅失败, 回环到自身或返回错误, 它就知道不存在 State Agent, 因而也不存在 Appearance Agent, 该功能未实现.
-
如果订阅收到 200 OK, UA 就知道存在 State Agent, 并且该功能已实现. 随后 UA 按照本列表中的步骤执行.
-
从组内其他 UA 的 dialog 状态中获知的信息会呈现给用户.
-
来电会被分叉到组内所有 UA, 其中任意 UA 都可以应答. UA 从 Appearance Agent 发送的 NOTIFY 以及 INVITE 本身中接收用于呈现来电的外观编号. 如果该呼叫由组内另一个 UA 应答, UA 也会收到通知, 以便将此信息呈现给用户.
-
对于传出呼叫, 操作取决于实现. 如果用户为该呼叫占用特定外观编号, UA 会发布带有所需外观编号的 trying 状态 dialog 信息, 并在发送 INVITE 之前等待 2xx 响应.
-
对于传出呼叫, 如果用户未占用特定外观或并不关心外观编号, 可以立即发送 INVITE, 并在呼叫推进过程中从 Appearance Agent 的通知中获知外观编号.
-
对于传出呼叫, 如果用户不希望分配外观编号 (例如在咨询呼叫期间, 或 UA 正在获取 'service media', 如保持音乐 [RFC7088]), UA 也会在发送 INVITE 之前发布, 但发布内容中不包含外观编号.
-
组内已建立的呼叫可以由另一个 UA 加入 (桥接) 或接管 (接起). dialog package 通知中的信息可用于构造 Join 或 Replaces 头字段. 由于这些类型的操作使用相同的外观编号, 因此该信息会在发送 INVITE Join 或 INVITE Replaces 之前发布.
-
Appearance Agent 可能无法直接访问组内部分或全部 UA 的完整 dialog 状态. 如果是这种情况, Appearance Agent 将订阅组内各个 UA 的 dialog 状态以获取该信息. 无论如何, 每当 AOR 的聚合 dialog 状态发生变化时, Appearance Agent 都会发送正常通知 (通过 UA 在步骤 1 中建立的订阅), 包括呼叫发起, 应答, 置于保持和取消保持, 以及挂机时.