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;
023
024import org.jivesoftware.smackx.jingleold.nat.ICECandidate;
025import org.jivesoftware.smackx.jingleold.nat.TransportCandidate;
026import org.jivesoftware.smackx.jingleold.packet.JingleTransport;
027import org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate;
028
029import org.xmlpull.v1.XmlPullParser;
030import org.xmlpull.v1.XmlPullParserException;
031
032/**
033 * Provider for a Jingle transport element.
034 *
035 * @author Alvaro Saurin
036 */
037public abstract class JingleTransportProvider extends ExtensionElementProvider<JingleTransport> {
038
039    /**
040     * Obtain the corresponding TransportNegotiator instance.
041     *
042     * @return a new TransportNegotiator instance
043     */
044    protected JingleTransport getInstance() {
045        return new JingleTransport();
046    }
047
048    /**
049     * Parse a iq/jingle/transport element.
050     *
051     * @param parser the structure to parse
052     * @return a transport element.
053     * @throws IOException 
054     * @throws XmlPullParserException 
055     * @throws SmackException 
056     */
057    @Override
058    public JingleTransport parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException  {
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 SmackException("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
087    /**
088     * RTP-ICE profile.
089     */
090    public static class Ice extends JingleTransportProvider {
091
092        /**
093         * Defauls 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                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        @Override
216        protected JingleTransport getInstance() {
217            return new JingleTransport.RawUdp();
218        }
219
220        /**
221         * Parse a iq/jingle/transport/candidate element.
222         *
223         * @param parser the structure to parse
224         * @return a candidate element
225         */
226        @Override
227        protected JingleTransportCandidate parseCandidate(XmlPullParser parser) {
228            TransportCandidate.Fixed mt = new TransportCandidate.Fixed();
229
230            String generation = parser.getAttributeValue("", "generation");
231            String ip = parser.getAttributeValue("", "ip");
232            String name = parser.getAttributeValue("", "name");
233            String port = parser.getAttributeValue("", "port");
234
235            // LOGGER.debug();
236
237            if (generation != null) {
238                try {
239                    mt.setGeneration(Integer.parseInt(generation));
240                }
241                catch (Exception e) {
242                }
243            }
244
245            if (ip != null) {
246                mt.setIp(ip);
247            }
248
249            if (name != null) {
250                mt.setName(name);
251            }
252
253            if (port != null) {
254                try {
255                    mt.setPort(Integer.parseInt(port));
256                }
257                catch (Exception e) {
258                }
259            }
260            return new JingleTransport.RawUdp.Candidate(mt);
261        }
262    }
263}