/*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.sip.sipaccount;
import java.sql.SQLException;
import org.dom4j.Element;
import org.jivesoftware.openfire.event.SessionEventDispatcher;
import org.jivesoftware.openfire.event.SessionEventListener;
import org.jivesoftware.openfire.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
/**
* Implements an openfire Component and SessionEventListener. Controls every
* registration inf request and process user's SIP presence informations.
*
* @author Thiago Rocha Camargo
*/
public class SipComponent implements Component, SessionEventListener {
private static final Logger Log = LoggerFactory.getLogger(SipComponent.class);
ComponentManager componentManager = null;
/**
* Namespace of the packet extension.
*/
public static final String NAMESPACE = "http://www.jivesoftware.com/protocol/sipark";
public static final String PROPNAME = "plugin.sipark.serviceName";
public static final String NAME = "sipark";
public SipComponent() {
this.componentManager = ComponentManagerFactory.getComponentManager();
SessionEventDispatcher.addListener(this);
}
public void initialize(JID jid, ComponentManager componentManager) {
}
public void start() {
}
public void shutdown() {
SessionEventDispatcher.removeListener(this);
}
// Component Interface
public void processPacket(Packet packet) {
Log.debug(packet.toXML());
if (packet instanceof IQ) {
// Handle disco packets
IQ iq = (IQ)packet;
// Ignore IQs of type ERROR or RESULT
if (IQ.Type.error == iq.getType() || IQ.Type.result == iq.getType()) {
return;
}
processIQ(iq);
}
}
private void processIQ(IQ iq) {
IQ reply = IQ.createResultIQ(iq);
String namespace = iq.getChildElement().getNamespaceURI();
Element childElement = iq.getChildElement().createCopy();
reply.setChildElement(childElement);
if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
if (iq.getTo().getNode() == null) {
// Return service identity and features
Element identity = childElement.addElement("identity");
identity.addAttribute("category", "component");
identity.addAttribute("type", "generic");
identity.addAttribute("name", "SIP Controller");
childElement.addElement("feature").addAttribute("var", "http://jabber.org/protocol/disco#info");
childElement.addElement("feature").addAttribute("var", "http://www.jivesoftware.com/protocol/sipark");
}
}
else if (NAMESPACE.equals(namespace)) {
if (iq.getTo().getNode() == null && iq.getFrom() != null) {
SipAccount sipAccount = SipAccountDAO.getAccountByUser(iq.getFrom().toBareJID().split("@")[0]);
if (iq.getChildElement().element("status") == null) {
if (sipAccount != null && sipAccount.isEnabled()) {
// There is a SIP mapping for this user so return mapping information
Element registration = childElement.addElement("registration");
registration.addElement("jid")
.setText(sipAccount.getUsername() + "@" + componentManager.getServerName());
registration.addElement("username").setText(sipAccount.getSipUsername());
registration.addElement("authUsername").setText(sipAccount.getAuthUsername());
registration.addElement("displayPhoneNum").setText(sipAccount.getDisplayName());
registration.addElement("password").setText(sipAccount.getPassword());
registration.addElement("server").setText(sipAccount.getServer());
registration.addElement("stunServer").setText(sipAccount.getStunServer());
registration.addElement("stunPort").setText(sipAccount.getStunPort());
registration.addElement("useStun").setText(String.valueOf(sipAccount.isUseStun()));
registration.addElement("voicemail").setText(sipAccount.getVoiceMailNumber());
registration.addElement("enabled").setText(String.valueOf(sipAccount.isEnabled()));
registration.addElement("outboundproxy").setText(sipAccount.getOutboundproxy());
registration.addElement("promptCredentials").setText(String.valueOf(sipAccount.isPromptCredentials()));
}
else {
// No SIP mapping was found
reply.getChildElement().addAttribute("type", "unregistered");
}
}
else {
if (sipAccount != null) {
Element status = iq.getChildElement().element("status");
if (!status.getTextTrim().equals("")) {
sipAccount.setStatus(SipRegisterStatus.valueOf(status.getTextTrim()));
try {
SipAccountDAO.update(sipAccount);
}
catch (SQLException e) {
Log.error(e.getMessage(), e);
}
}
}
}
}
}
else {
// Answer an error since the server can't handle the requested
// namespace
reply.setError(PacketError.Condition.service_unavailable);
}
try {
componentManager.sendPacket(this, reply);
}
catch (Exception e) {
Log.error(e.getMessage(), e);
}
Log.debug("PACKET SENT: " + reply.toXML());
} // Other Methods
public String getDescription() {
return "SIP Admin Plugin";
}
public String getName() {
return "SIPAdmin";
}
public void anonymousSessionCreated(Session arg0) {
// Ignore
}
public void anonymousSessionDestroyed(Session arg0) {
// Ignore
}
public void sessionCreated(Session arg0) {
// Ignore
}
/**
* Sets the user SIP presence to Unregistered if his jabber account is disconnected.
*
* @param session the destroyed session
*/
public void sessionDestroyed(Session session) {
String username = session.getAddress().toBareJID().split("@")[0];
SipAccount sipAccount = SipAccountDAO.getAccountByUser(username);
if (sipAccount != null) {
try {
sipAccount.setStatus(SipRegisterStatus.Unregistered);
SipAccountDAO.update(sipAccount);
}
catch (SQLException e) {
Log.error(e.getMessage(), e);
}
}
}
public void resourceBound(Session session) {
// Do nothing.
}
}