001/* 002 * 003 * Copyright 2003-2005 Jive Software. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.jingleold.provider; 018 019import java.io.IOException; 020 021import org.jivesoftware.smack.packet.XmlEnvironment; 022import org.jivesoftware.smack.provider.ExtensionElementProvider; 023import org.jivesoftware.smack.xml.XmlPullParser; 024import org.jivesoftware.smack.xml.XmlPullParserException; 025 026import org.jivesoftware.smackx.jingleold.nat.ICECandidate; 027import org.jivesoftware.smackx.jingleold.nat.TransportCandidate; 028import org.jivesoftware.smackx.jingleold.packet.JingleTransport; 029import org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate; 030 031import org.jxmpp.JxmppContext; 032 033/** 034 * Provider for a Jingle transport element. 035 * 036 * @author Alvaro Saurin 037 */ 038public abstract class JingleTransportProvider extends ExtensionElementProvider<JingleTransport> { 039 040 /** 041 * Obtain the corresponding TransportNegotiator instance. 042 * 043 * @return a new TransportNegotiator instance 044 */ 045 protected JingleTransport getInstance() { 046 return new JingleTransport(); 047 } 048 049 /** 050 * Parse a iq/jingle/transport element. 051 * 052 * @param parser the structure to parse 053 * @return a transport element. 054 * @throws IOException if an I/O error occurred. 055 * @throws XmlPullParserException if an error in the XML parser occurred. 056 */ 057 @Override 058 public JingleTransport parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) throws XmlPullParserException, IOException { 059 JingleTransport trans = getInstance(); 060 061 outerloop: while (true) { 062 XmlPullParser.Event eventType = parser.next(); 063 064 if (eventType == XmlPullParser.Event.START_ELEMENT) { 065 String name = parser.getName(); 066 if (name.equals(JingleTransportCandidate.NODENAME)) { 067 JingleTransportCandidate jtc = parseCandidate(parser); 068 if (jtc != null) trans.addCandidate(jtc); 069 } 070 else { 071 // TODO: Should be SmackParseException. 072 throw new IOException("Unknown tag \"" + name + "\" in transport element."); 073 } 074 } 075 else if (eventType == XmlPullParser.Event.END_ELEMENT) { 076 if (parser.getDepth() == initialDepth) { 077 break outerloop; 078 } 079 } 080 } 081 082 return trans; 083 } 084 085 protected abstract JingleTransportCandidate parseCandidate(XmlPullParser parser); 086 087 /** 088 * RTP-ICE profile. 089 */ 090 public static class Ice extends JingleTransportProvider { 091 092 /** 093 * Default constructor. 094 */ 095 public Ice() { 096 super(); 097 } 098 099 /** 100 * Obtain the corresponding TransportNegotiator.Ice instance. 101 * 102 * @return a new TransportNegotiator.Ice instance 103 */ 104 @Override 105 protected JingleTransport getInstance() { 106 return new JingleTransport.Ice(); 107 } 108 109 /** 110 * Parse a iq/jingle/transport/candidate element. 111 * 112 * @param parser the structure to parse 113 * @return a candidate element 114 */ 115 @Override 116 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) { 117 ICECandidate mt = new ICECandidate(); 118 119 String channel = parser.getAttributeValue("", "channel"); 120 String generation = parser.getAttributeValue("", "generation"); 121 String ip = parser.getAttributeValue("", "ip"); 122 String name = parser.getAttributeValue("", "name"); 123 String network = parser.getAttributeValue("", "network"); 124 String username = parser.getAttributeValue("", "username"); 125 String password = parser.getAttributeValue("", "password"); 126 String port = parser.getAttributeValue("", "port"); 127 String preference = parser.getAttributeValue("", "preference"); 128 String proto = parser.getAttributeValue("", "proto"); 129 String type = parser.getAttributeValue("", "type"); 130 131 if (channel != null) { 132 mt.setChannel(new TransportCandidate.Channel(channel)); 133 } 134 135 if (generation != null) { 136 mt.setGeneration(Integer.parseInt(generation)); 137 } 138 139 if (ip != null) { 140 mt.setIp(ip); 141 } 142 else { 143 return null; 144 } 145 146 if (name != null) { 147 mt.setName(name); 148 } 149 150 if (network != null) { 151 mt.setNetwork(Integer.parseInt(network)); 152 } 153 154 if (username != null) { 155 mt.setUsername(username); 156 } 157 158 if (password != null) { 159 mt.setPassword(password); 160 } 161 162 if (port != null) { 163 mt.setPort(Integer.parseInt(port)); 164 } 165 166 if (preference != null) { 167 mt.setPreference(Integer.parseInt(preference)); 168 } 169 170 if (proto != null) { 171 mt.setProto(new TransportCandidate.Protocol(proto)); 172 } 173 174 if (type != null) { 175 mt.setType(ICECandidate.Type.valueOf(type)); 176 } 177 178 return new JingleTransport.Ice.Candidate(mt); 179 } 180 } 181 182 /** 183 * Raw UDP profile. 184 */ 185 public static class RawUdp extends JingleTransportProvider { 186 187 /** 188 * Default constructor. 189 */ 190 public RawUdp() { 191 super(); 192 } 193 194 /** 195 * Obtain the corresponding TransportNegotiator.RawUdp instance. 196 * 197 * @return a new TransportNegotiator.RawUdp instance 198 */ 199 @Override 200 protected JingleTransport getInstance() { 201 return new JingleTransport.RawUdp(); 202 } 203 204 /** 205 * Parse a iq/jingle/transport/candidate element. 206 * 207 * @param parser the structure to parse 208 * @return a candidate element 209 */ 210 @Override 211 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) { 212 TransportCandidate.Fixed mt = new TransportCandidate.Fixed(); 213 214 String generation = parser.getAttributeValue("", "generation"); 215 String ip = parser.getAttributeValue("", "ip"); 216 String name = parser.getAttributeValue("", "name"); 217 String port = parser.getAttributeValue("", "port"); 218 219 // LOGGER.debug(); 220 221 if (generation != null) { 222 mt.setGeneration(Integer.parseInt(generation)); 223 } 224 225 if (ip != null) { 226 mt.setIp(ip); 227 } 228 229 if (name != null) { 230 mt.setName(name); 231 } 232 233 if (port != null) { 234 mt.setPort(Integer.parseInt(port)); 235 } 236 return new JingleTransport.RawUdp.Candidate(mt); 237 } 238 } 239}