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.SmackException;
022import org.jivesoftware.smack.provider.ExtensionElementProvider;
023import org.jivesoftware.smackx.jingleold.nat.ICECandidate;
024import org.jivesoftware.smackx.jingleold.nat.TransportCandidate;
025import org.jivesoftware.smackx.jingleold.packet.JingleTransport;
026import org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate;
027import org.xmlpull.v1.XmlPullParser;
028import org.xmlpull.v1.XmlPullParserException;
029
030/**
031 * Provider for a Jingle transport element
032 *
033 * @author Alvaro Saurin <alvaro.saurin@gmail.com>
034 */
035public abstract class JingleTransportProvider extends ExtensionElementProvider<JingleTransport> {
036
037    /**
038     * Obtain the corresponding TransportNegotiator instance.
039     *
040     * @return a new TransportNegotiator instance
041     */
042    protected JingleTransport getInstance() {
043        return new JingleTransport();
044    }
045
046    /**
047     * Parse a iq/jingle/transport element.
048     *
049     * @param parser the structure to parse
050     * @return a transport element.
051     * @throws IOException 
052     * @throws XmlPullParserException 
053     * @throws SmackException 
054     */
055    @Override
056    public JingleTransport parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException  {
057        boolean done = false;
058        JingleTransport trans = getInstance();
059
060        while (!done) {
061            int eventType = parser.next();
062            String name = parser.getName();
063
064            if (eventType == XmlPullParser.START_TAG) {
065                if (name.equals(JingleTransportCandidate.NODENAME)) {
066                    JingleTransportCandidate jtc = parseCandidate(parser);
067                    if (jtc != null) trans.addCandidate(jtc);
068                }
069                else {
070                    throw new SmackException("Unknown tag \"" + name + "\" in transport element.");
071                }
072            }
073            else if (eventType == XmlPullParser.END_TAG) {
074                if (name.equals(JingleTransport.NODENAME)) {
075                    done = true;
076                }
077            }
078        }
079
080        return trans;
081    }
082
083    protected abstract JingleTransportCandidate parseCandidate(final 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        protected JingleTransport getInstance() {
103            return new JingleTransport.Ice();
104        }
105
106        /**
107         * Parse a iq/jingle/transport/candidate element.
108         *
109         * @param parser the structure to parse
110         * @return a candidate element
111         */
112        protected JingleTransportCandidate parseCandidate(XmlPullParser parser) {
113            ICECandidate mt = new ICECandidate();
114
115            String channel = parser.getAttributeValue("", "channel");
116            String generation = parser.getAttributeValue("", "generation");
117            String ip = parser.getAttributeValue("", "ip");
118            String name = parser.getAttributeValue("", "name");
119            String network = parser.getAttributeValue("", "network");
120            String username = parser.getAttributeValue("", "username");
121            String password = parser.getAttributeValue("", "password");
122            String port = parser.getAttributeValue("", "port");
123            String preference = parser.getAttributeValue("", "preference");
124            String proto = parser.getAttributeValue("", "proto");
125            String type = parser.getAttributeValue("", "type");
126
127            if (channel != null) {
128                mt.setChannel(new TransportCandidate.Channel(channel));
129            }
130
131            if (generation != null) {
132                try {
133                    mt.setGeneration(Integer.parseInt(generation));
134                }
135                catch (Exception e) {
136                }
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                try {
152                    mt.setNetwork(Integer.parseInt(network));
153                }
154                catch (Exception e) {
155                }
156            }
157
158            if (username != null) {
159                mt.setUsername(username);
160            }
161
162            if (password != null) {
163                mt.setPassword(password);
164            }
165
166            if (port != null) {
167                try {
168                    mt.setPort(Integer.parseInt(port));
169                }
170                catch (Exception e) {
171                }
172            }
173
174            if (preference != null) {
175                try {
176                    mt.setPreference(Integer.parseInt(preference));
177                }
178                catch (Exception e) {
179                }
180            }
181
182            if (proto != null) {
183                mt.setProto(new TransportCandidate.Protocol(proto));
184            }
185
186            if (type != null) {
187                mt.setType(ICECandidate.Type.valueOf(type));
188            }
189
190            return new JingleTransport.Ice.Candidate(mt);
191        }
192    }
193
194    /**
195     * Raw UDP profile
196     */
197    public static class RawUdp extends JingleTransportProvider {
198
199        /**
200         * Defauls constructor.
201         */
202        public RawUdp() {
203            super();
204        }
205
206        /**
207         * Obtain the corresponding TransportNegotiator.RawUdp instance.
208         *
209         * @return a new TransportNegotiator.RawUdp instance
210         */
211        protected JingleTransport getInstance() {
212            return new JingleTransport.RawUdp();
213        }
214
215        /**
216         * Parse a iq/jingle/transport/candidate element.
217         *
218         * @param parser the structure to parse
219         * @return a candidate element
220         */
221        protected JingleTransportCandidate parseCandidate(XmlPullParser parser) {
222            TransportCandidate.Fixed mt = new TransportCandidate.Fixed();
223
224            String generation = parser.getAttributeValue("", "generation");
225            String ip = parser.getAttributeValue("", "ip");
226            String name = parser.getAttributeValue("", "name");
227            String port = parser.getAttributeValue("", "port");
228
229            //LOGGER.debug();
230
231            if (generation != null) {
232                try {
233                    mt.setGeneration(Integer.parseInt(generation));
234                }
235                catch (Exception e) {
236                }
237            }
238
239            if (ip != null) {
240                mt.setIp(ip);
241            }
242
243            if (name != null) {
244                mt.setName(name);
245            }
246
247            if (port != null) {
248                try {
249                    mt.setPort(Integer.parseInt(port));
250                }
251                catch (Exception e) {
252                }
253            }
254            return new JingleTransport.RawUdp.Candidate(mt);
255        }
256    }
257}