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.jingle.provider; 018 019import org.jivesoftware.smack.packet.PacketExtension; 020import org.jivesoftware.smack.provider.PacketExtensionProvider; 021import org.jivesoftware.smackx.jingle.nat.ICECandidate; 022import org.jivesoftware.smackx.jingle.nat.TransportCandidate; 023import org.jivesoftware.smackx.jingle.packet.JingleTransport; 024import org.jivesoftware.smackx.jingle.packet.JingleTransport.JingleTransportCandidate; 025import org.xmlpull.v1.XmlPullParser; 026 027/** 028 * Provider for a Jingle transport element 029 * 030 * @author Alvaro Saurin <alvaro.saurin@gmail.com> 031 */ 032public abstract class JingleTransportProvider implements PacketExtensionProvider { 033 034 /** 035 * Creates a new provider. ProviderManager requires that every 036 * PacketExtensionProvider has a public, no-argument constructor 037 */ 038 public JingleTransportProvider() { 039 super(); 040 } 041 042 /** 043 * Obtain the corresponding TransportNegotiator instance. 044 * 045 * @return a new TransportNegotiator instance 046 */ 047 protected JingleTransport getInstance() { 048 return new JingleTransport(); 049 } 050 051 /** 052 * Parse a iq/jingle/transport element. 053 * 054 * @param parser the structure to parse 055 * @return a transport element. 056 * @throws Exception 057 */ 058 public PacketExtension parseExtension(final XmlPullParser parser) throws Exception { 059 boolean done = false; 060 JingleTransport trans = getInstance(); 061 062 while (!done) { 063 int eventType = parser.next(); 064 String name = parser.getName(); 065 066 if (eventType == XmlPullParser.START_TAG) { 067 if (name.equals(JingleTransportCandidate.NODENAME)) { 068 JingleTransportCandidate jtc = parseCandidate(parser); 069 if (jtc != null) trans.addCandidate(jtc); 070 } 071 else { 072 throw new Exception("Unknown tag \"" + name + "\" in transport element."); 073 } 074 } 075 else if (eventType == XmlPullParser.END_TAG) { 076 if (name.equals(JingleTransport.NODENAME)) { 077 done = true; 078 } 079 } 080 } 081 082 return trans; 083 } 084 085 protected abstract JingleTransportCandidate parseCandidate(final XmlPullParser parser) 086 throws Exception; 087 088 /** 089 * RTP-ICE profile 090 */ 091 public static class Ice extends JingleTransportProvider { 092 093 /** 094 * Defauls constructor. 095 */ 096 public Ice() { 097 super(); 098 } 099 100 /** 101 * Obtain the corresponding TransportNegotiator.Ice instance. 102 * 103 * @return a new TransportNegotiator.Ice instance 104 */ 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 * @throws Exception 115 */ 116 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) throws Exception { 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 try { 137 mt.setGeneration(Integer.parseInt(generation)); 138 } 139 catch (Exception e) { 140 } 141 } 142 143 if (ip != null) { 144 mt.setIp(ip); 145 } 146 else { 147 return null; 148 } 149 150 if (name != null) { 151 mt.setName(name); 152 } 153 154 if (network != null) { 155 try { 156 mt.setNetwork(Integer.parseInt(network)); 157 } 158 catch (Exception e) { 159 } 160 } 161 162 if (username != null) { 163 mt.setUsername(username); 164 } 165 166 if (password != null) { 167 mt.setPassword(password); 168 } 169 170 if (port != null) { 171 try { 172 mt.setPort(Integer.parseInt(port)); 173 } 174 catch (Exception e) { 175 } 176 } 177 178 if (preference != null) { 179 try { 180 mt.setPreference(Integer.parseInt(preference)); 181 } 182 catch (Exception e) { 183 } 184 } 185 186 if (proto != null) { 187 mt.setProto(new TransportCandidate.Protocol(proto)); 188 } 189 190 if (type != null) { 191 mt.setType(ICECandidate.Type.valueOf(type)); 192 } 193 194 return new JingleTransport.Ice.Candidate(mt); 195 } 196 } 197 198 /** 199 * Raw UDP profile 200 */ 201 public static class RawUdp extends JingleTransportProvider { 202 203 /** 204 * Defauls constructor. 205 */ 206 public RawUdp() { 207 super(); 208 } 209 210 /** 211 * Obtain the corresponding TransportNegotiator.RawUdp instance. 212 * 213 * @return a new TransportNegotiator.RawUdp instance 214 */ 215 protected JingleTransport getInstance() { 216 return new JingleTransport.RawUdp(); 217 } 218 219 /** 220 * Parse a iq/jingle/transport/candidate element. 221 * 222 * @param parser the structure to parse 223 * @return a candidate element 224 * @throws Exception 225 */ 226 protected JingleTransportCandidate parseCandidate(XmlPullParser parser) throws Exception { 227 TransportCandidate.Fixed mt = new TransportCandidate.Fixed(); 228 229 String generation = parser.getAttributeValue("", "generation"); 230 String ip = parser.getAttributeValue("", "ip"); 231 String name = parser.getAttributeValue("", "name"); 232 String port = parser.getAttributeValue("", "port"); 233 234 //LOGGER.debug(); 235 236 if (generation != null) { 237 try { 238 mt.setGeneration(Integer.parseInt(generation)); 239 } 240 catch (Exception e) { 241 } 242 } 243 244 if (ip != null) { 245 mt.setIp(ip); 246 } 247 248 if (name != null) { 249 mt.setName(name); 250 } 251 252 if (port != null) { 253 try { 254 mt.setPort(Integer.parseInt(port)); 255 } 256 catch (Exception e) { 257 } 258 } 259 return new JingleTransport.RawUdp.Candidate(mt); 260 } 261 } 262}