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 031/** 032 * Provider for a Jingle transport element. 033 * 034 * @author Alvaro Saurin 035 */ 036public abstract class JingleTransportProvider extends ExtensionElementProvider<JingleTransport> { 037 038 /** 039 * Obtain the corresponding TransportNegotiator instance. 040 * 041 * @return a new TransportNegotiator instance 042 */ 043 protected JingleTransport getInstance() { 044 return new JingleTransport(); 045 } 046 047 /** 048 * Parse a iq/jingle/transport element. 049 * 050 * @param parser the structure to parse 051 * @return a transport element. 052 * @throws IOException if an I/O error occurred. 053 * @throws XmlPullParserException if an error in the XML parser occurred. 054 */ 055 @Override 056 public JingleTransport parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException { 057 JingleTransport trans = getInstance(); 058 059 outerloop: while (true) { 060 XmlPullParser.Event eventType = parser.next(); 061 062 if (eventType == XmlPullParser.Event.START_ELEMENT) { 063 String name = parser.getName(); 064 if (name.equals(JingleTransportCandidate.NODENAME)) { 065 JingleTransportCandidate jtc = parseCandidate(parser); 066 if (jtc != null) trans.addCandidate(jtc); 067 } 068 else { 069 // TODO: Should be SmackParseException. 070 throw new IOException("Unknown tag \"" + name + "\" in transport element."); 071 } 072 } 073 else if (eventType == XmlPullParser.Event.END_ELEMENT) { 074 if (parser.getDepth() == initialDepth) { 075 break outerloop; 076 } 077 } 078 } 079 080 return trans; 081 } 082 083 protected abstract JingleTransportCandidate parseCandidate(XmlPullParser parser); 084 085 /** 086 * RTP-ICE profile. 087 */ 088 public static class Ice extends JingleTransportProvider { 089 090 /** 091 * Defauls constructor. 092 */ 093 public Ice() { 094 super(); 095 } 096 097 /** 098 * Obtain the corresponding TransportNegotiator.Ice instance. 099 * 100 * @return a new TransportNegotiator.Ice instance 101 */ 102 @Override 103 protected JingleTransport getInstance() { 104 return new JingleTransport.Ice(); 105 } 106 107 /** 108 * Parse a iq/jingle/transport/candidate element. 109 * 110 * @param parser the structure to parse 111 * @return a candidate element 112 */ 113 @Override 114 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) { 115 ICECandidate mt = new ICECandidate(); 116 117 String channel = parser.getAttributeValue("", "channel"); 118 String generation = parser.getAttributeValue("", "generation"); 119 String ip = parser.getAttributeValue("", "ip"); 120 String name = parser.getAttributeValue("", "name"); 121 String network = parser.getAttributeValue("", "network"); 122 String username = parser.getAttributeValue("", "username"); 123 String password = parser.getAttributeValue("", "password"); 124 String port = parser.getAttributeValue("", "port"); 125 String preference = parser.getAttributeValue("", "preference"); 126 String proto = parser.getAttributeValue("", "proto"); 127 String type = parser.getAttributeValue("", "type"); 128 129 if (channel != null) { 130 mt.setChannel(new TransportCandidate.Channel(channel)); 131 } 132 133 if (generation != null) { 134 try { 135 mt.setGeneration(Integer.parseInt(generation)); 136 } 137 catch (Exception e) { 138 } 139 } 140 141 if (ip != null) { 142 mt.setIp(ip); 143 } 144 else { 145 return null; 146 } 147 148 if (name != null) { 149 mt.setName(name); 150 } 151 152 if (network != null) { 153 try { 154 mt.setNetwork(Integer.parseInt(network)); 155 } 156 catch (Exception e) { 157 } 158 } 159 160 if (username != null) { 161 mt.setUsername(username); 162 } 163 164 if (password != null) { 165 mt.setPassword(password); 166 } 167 168 if (port != null) { 169 try { 170 mt.setPort(Integer.parseInt(port)); 171 } 172 catch (Exception e) { 173 } 174 } 175 176 if (preference != null) { 177 try { 178 mt.setPreference(Integer.parseInt(preference)); 179 } 180 catch (Exception e) { 181 } 182 } 183 184 if (proto != null) { 185 mt.setProto(new TransportCandidate.Protocol(proto)); 186 } 187 188 if (type != null) { 189 mt.setType(ICECandidate.Type.valueOf(type)); 190 } 191 192 return new JingleTransport.Ice.Candidate(mt); 193 } 194 } 195 196 /** 197 * Raw UDP profile. 198 */ 199 public static class RawUdp extends JingleTransportProvider { 200 201 /** 202 * Defauls constructor. 203 */ 204 public RawUdp() { 205 super(); 206 } 207 208 /** 209 * Obtain the corresponding TransportNegotiator.RawUdp instance. 210 * 211 * @return a new TransportNegotiator.RawUdp instance 212 */ 213 @Override 214 protected JingleTransport getInstance() { 215 return new JingleTransport.RawUdp(); 216 } 217 218 /** 219 * Parse a iq/jingle/transport/candidate element. 220 * 221 * @param parser the structure to parse 222 * @return a candidate element 223 */ 224 @Override 225 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) { 226 TransportCandidate.Fixed mt = new TransportCandidate.Fixed(); 227 228 String generation = parser.getAttributeValue("", "generation"); 229 String ip = parser.getAttributeValue("", "ip"); 230 String name = parser.getAttributeValue("", "name"); 231 String port = parser.getAttributeValue("", "port"); 232 233 // LOGGER.debug(); 234 235 if (generation != null) { 236 try { 237 mt.setGeneration(Integer.parseInt(generation)); 238 } 239 catch (Exception e) { 240 } 241 } 242 243 if (ip != null) { 244 mt.setIp(ip); 245 } 246 247 if (name != null) { 248 mt.setName(name); 249 } 250 251 if (port != null) { 252 try { 253 mt.setPort(Integer.parseInt(port)); 254 } 255 catch (Exception e) { 256 } 257 } 258 return new JingleTransport.RawUdp.Candidate(mt); 259 } 260 } 261}