/** * FAILMOVED can come from both ends and in both cases we need to dispatch * an error event * * @param Streamwide_Engine_Signal $signal * @return void */ protected function _handleFailMovedSignal(Streamwide_Engine_Signal $signal) { $this->_unsubscribeFromEngineEvents(); $remote = $signal->getRemote(); $callLeg = $remote === $this->_leftCallLeg->getName() ? $this->_leftCallLeg : $this->_rightCallLeg; return $this->dispatchErrorEvent(self::CALL_LEG_UPDATE_FAILED_ERR_CODE, array('callLeg' => $callLeg)); }
/** * We have received CHILD signal from the MS call leg, we need to send * FAIL to the SIP call leg and dispatch an error event * * @param Streamwide_Engine_Signal $signal * @return void */ protected function _handleChildSignal(Streamwide_Engine_Signal $signal) { $this->_unsubscribeFromEngineEvents(); $remote = $signal->getRemote(); if ($remote === $this->_leftCallLeg->getName()) { if ($this->_leftCallLeg->isAlive()) { $this->_leftCallLeg->setDead(); } return $this->dispatchErrorEvent(self::CALL_LEG_DIED_ERR_CODE, array('callLeg' => $this->_leftCallLeg)); } if ($remote === $this->_rightCallLeg->getName()) { $failSignal = Streamwide_Engine_Signal::factory(Streamwide_Engine_Signal::FAIL, $this->_leftCallLeg->getName()); if (false === $failSignal->send()) { return $this->dispatchErrorEvent(self::FAIL_SIGNAL_SEND_ERR_CODE); } if ($this->_rightCallLeg->isAlive()) { $this->_rightCallLeg->setDead(); } return $this->dispatchErrorEvent(self::CALL_LEG_DIED_ERR_CODE, array('callLeg' => $this->_rightCallLeg)); } }
/** * Handle a CHILD signal received in the middle of the connection process * * @param Streamwide_Engine_Signal $signal * @param string $errorCode * @return void */ protected function _handleChildSignal(Streamwide_Engine_Signal $signal, $errorCode) { $this->_unsubscribeFromEngineEvents(); $remoteName = $signal->getRemote(); $defunctCallLeg = $remoteName === $this->_leftCallLeg->getName() ? $this->_leftCallLeg : $this->_rightCallLeg; if ($defunctCallLeg->isAlive()) { $defunctCallLeg->setDead(); } return $this->dispatchErrorEvent($errorCode, array('callLeg' => $defunctCallLeg)); }
/** * MOVED from the left call leg will be answered with FAILMOVED. MOVED * from the right call leg will be stored and left to be handled later. * * @param Streamwide_Engine_Signal $signal * @return void */ protected function _handleMovedSignal(Streamwide_Engine_Signal $signal) { $remote = $signal->getRemote(); if ($remote === $this->_leftCallLeg->getName()) { $failMovedSignal = Streamwide_Engine_Signal::factory(Streamwide_Engine_Signal::FAILMOVED, $this->_leftCallLeg->getName(), array('code' => '491')); if (false === $failMovedSignal->send()) { $this->_unsubscribeFromEngineEvents(); return $this->dispatchErrorEvent(self::FAILMOVED_SIGNAL_SEND_ERR_CODE); } } if ($remote === $this->_rightCallLeg->getName()) { $this->_movedSignal = $signal; } }
/** * We have received FAILMOVED. If it came from SIP call leg we need to send a * FAILSDP to the MS call leg and dispatch an error event. If it came from MS call * leg the fax environment could not be created * * @param Streamwide_Engine_Signal $signal * @return void */ protected function _handleFailMovedSignal(Streamwide_Engine_Signal $signal) { $this->_unsubscribeFromEngineEvents(); $remote = $signal->getRemote(); if ($remote === $this->_leftCallLeg->getName()) { $failSdpSignal = Streamwide_Engine_Signal::factory(Streamwide_Engine_Signal::FAILSDP, $this->_rightCallLeg->getName(), $signal->getParams()); if (false === $failSdpSignal->send()) { $this->dispatchErrorEvent(self::FAILSDP_SIGNAL_SEND_ERR_CODE); } return null; } if ($remote === $this->_rightCallLeg->getName()) { return $this->dispatchErrorEvent(self::FAX_ENV_NOT_CREATED_ERR_CODE); } }
protected function _handleFailMovedSignal(Streamwide_Engine_Signal $signal) { $remote = $signal->getRemote(); $params = $signal->getParams(); $failureCode = isset($params['code']) ? $params['code'] : null; if ($remote === $this->_leftCallLeg->getName()) { $this->_sipCallLegUpdateFailed = true; $signal = Streamwide_Engine_Signal::factory(Streamwide_Engine_Signal::FAILSDP, $this->_rightCallLeg->getName(), null !== $failureCode ? array('code' => $failureCode) : $failureCode); if (false === $signal->send()) { $this->_unsubscribeFromEngineEvents(); $this->dispatchErrorEvent(self::FAILSDP_SIGNAL_SEND_ERR_CODE); } return; } if ($remote === $this->_rightCallLeg->getName()) { $this->_unsubscribeFromEngineEvents(); $errorCode = self::MS_NOT_UPDATED_ERR_CODE; if ($this->_sipCallLegUpdateFailed) { $errorCode = self::SIP_NOT_UPDATED_ERR_CODE; } return $this->dispatchErrorEvent($errorCode, array('failureCode' => $failureCode, 'signal' => $signal)); } }
/** * Relay a signal from one call leg to another * * @param Streamwide_Engine_Signal $signal * @return boolean * @throws RuntimeException */ protected function _relaySignal(Streamwide_Engine_Signal $signal) { $remote = $signal->getRemote(); if ($signal->hasBeenRelayed()) { $errorMessageTpl = $this->_errors[self::SIGNAL_RELAY_ERR_CODE]; $callLegName = $remote === $this->_leftCallLeg->getName() ? $this->_rightCallLeg->getName() : $this->_leftCallLeg->getName(); $this->_errors[self::SIGNAL_RELAY_ERR_CODE] = sprintf($errorMessageTpl, $signal->getName(), $callLegName); $this->dispatchErrorEvent(self::SIGNAL_RELAY_ERR_CODE); return false; } $callLegName = null; if ($remote === $this->_leftCallLeg->getName()) { $this->_relayFlow = self::LEFT_TO_RIGHT_RELAY; $callLegName = $this->_rightCallLeg->getName(); } elseif ($remote === $this->_rightCallLeg->getName()) { $this->_relayFlow = self::RIGHT_TO_LEFT_RELAY; $callLegName = $this->_leftCallLeg->getName(); } // this should not happen (but it doesn't hurt to check) if (null === $callLegName) { throw new RuntimeException(sprintf('Invalid remote name found in %s signal', $signal->getName())); } $preRelayCallback = $this->_retrievePreRelayCallback($signal); if (null !== $preRelayCallback) { $signal = call_user_func_array($preRelayCallback, array($signal)); } if (false === $signal->relay($callLegName)) { $errorMessageTpl = $this->_errors[self::SIGNAL_RELAY_ERR_CODE]; $this->_errors[self::SIGNAL_RELAY_ERR_CODE] = sprintf($errorMessageTpl, $signal->getName(), $callLegName); $this->dispatchErrorEvent(self::SIGNAL_RELAY_ERR_CODE); return false; } return true; }
/** * Because we are sending 2 CREATE signals, we can receive two OK signals as response (if * everything is well). On OK received from the SIP call leg we send an OKSDP signal * to the MS call leg. On OK received from the MS call leg we dispatch the CONNECTED event * * @param Streamwide_Engine_Signal $signal * @return void */ protected function _handleOkSignal(Streamwide_Engine_Signal $signal) { $remoteName = $signal->getRemote(); $params = $signal->getParams(); if ($remoteName === $this->_rightCallLeg->getName()) { // The OK came from the media server call leg $this->_rightCallLeg->setAlive(); $this->_rightCallLeg->okSent(); $this->_rightCallLeg->setParams($params); if ($this->_msNegotiationActive) { if ($this->_leftCallLeg->hasSentOrReceivedOk()) { $params = $this->_leftCallLeg->getParams(); $moved = Streamwide_Engine_Signal::factory(Streamwide_Engine_Signal::MOVED, $this->_rightCallLeg->getName(), array('sdp' => $params['sdp'])); if (false === $moved->send()) { $this->_unsubscribeFromEngineEvents(); return $this->dispatchErrorEvent(self::MOVED_SIGNAL_SEND_ERR_CODE); } } $event = new Streamwide_Engine_Events_Event(Streamwide_Engine_Events_Event::EARLY_MEDIA_NEGOTIATED); return $this->dispatchEvent($event); } else { $this->_unsubscribeFromEngineEvents(); $event = new Streamwide_Engine_Events_Event(Streamwide_Engine_Events_Event::CONNECTED); $event->setParam('signal', $signal); if (null !== $this->_movedSignal) { $event->setParam('moved', $this->_movedSignal); } return $this->dispatchEvent($event); } } if ($remoteName === $this->_leftCallLeg->getName()) { // The OK came from the sip call leg $this->_leftCallLeg->setAlive(); $this->_leftCallLeg->okSent(); $this->_leftCallLeg->setParams($params); if ($this->_msNegotiationActive) { if ($this->_rightCallLeg->hasSentOrReceivedOk()) { $moved = Streamwide_Engine_Signal::factory(Streamwide_Engine_Signal::MOVED, $this->_rightCallLeg->getName(), array('sdp' => $params['sdp'])); if (false === $moved->send()) { $this->_unsubscribeFromEngineEvents(); return $this->dispatchErrorEvent(self::MOVED_SIGNAL_SEND_ERR_CODE); } } return; } else { $okSdp = Streamwide_Engine_Signal::factory(Streamwide_Engine_Signal::OKSDP, $this->_rightCallLeg->getName(), array('sdp' => $params['sdp'])); if (false === $okSdp->send()) { $this->_unsubscribeFromEngineEvents(); return $this->dispatchErrorEvent(self::OKSDP_SIGNAL_SEND_ERR_CODE); } } } }