2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.parser.impl;
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.junit.Assert.assertArrayEquals;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertThat;
15 import static org.junit.Assert.assertTrue;
16 import static org.junit.Assert.fail;
18 import com.google.common.collect.Lists;
19 import com.google.common.collect.Maps;
20 import io.netty.buffer.ByteBuf;
21 import io.netty.buffer.Unpooled;
22 import java.net.UnknownHostException;
23 import java.util.Arrays;
24 import java.util.List;
26 import org.junit.BeforeClass;
27 import org.junit.Test;
28 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
29 import org.opendaylight.protocol.bgp.parser.BGPError;
30 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
31 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
32 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
33 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
34 import org.opendaylight.protocol.util.ByteArray;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.KeepaliveBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.NotifyBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ProtocolVersion;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParametersBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilities;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilitiesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.MultiprotocolCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.multiprotocol._case.MultiprotocolCapabilityBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
54 import org.opendaylight.yangtools.yang.binding.Notification;
56 public class ParserTest {
58 private static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
59 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
60 (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
61 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
63 private static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
64 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
65 (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
67 private static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
68 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
69 (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
71 private static final byte[] openWithCpblt1 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
72 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
73 (byte) 0xff, (byte) 0x00, (byte) 0x2b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
74 (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x0e, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x04,
75 (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x40,
76 (byte) 0x04, (byte) 0x00, (byte) 0x47 };
78 private static final byte[] openWithCpblt2 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
79 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
80 (byte) 0xff, (byte) 0x00, (byte) 0x2b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
81 (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x0e, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x04,
82 (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x47, (byte) 0x01, (byte) 0x04, (byte) 0x00,
83 (byte) 0x01, (byte) 0x00, (byte) 0x01 };
85 private static final byte[] updMsgWithUnrecognizedAttribute = new byte[] {
86 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
87 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x79, (byte) 0x02,
88 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x62, (byte) 0x90, (byte) 0x0e, (byte) 0x00, (byte) 0x34, (byte) 0x40, (byte) 0x04, (byte) 0x47, (byte) 0x04, (byte) 0x0a, (byte) 0x19,
89 (byte) 0x02, (byte) 0x1b, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x27, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
90 (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x1a, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x48, (byte) 0x02, (byte)0x01,
91 (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
92 (byte) 0x43, (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x64,
93 (byte) 0x80, (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66, (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte)0x33,
94 (byte) 0x04, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b
97 static MessageRegistry reg;
100 public static void setupClass() throws Exception {
101 reg = ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry();
105 public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException {
106 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
107 wrong = ByteArray.cutBytes(wrong, 16);
109 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong));
110 fail("Exception should have occcured.");
111 } catch (final IllegalArgumentException e) {
112 assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", e.getMessage());
119 public void testBadMsgType() throws BGPParsingException {
120 final byte[] bytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
121 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
122 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
124 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
125 fail("Exception should have occured.");
126 } catch (final BGPDocumentedException e) {
127 assertEquals(BGPError.BAD_MSG_TYPE, e.getError());
134 public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException {
135 final Notification keepAlive = new KeepaliveBuilder().build();
136 final ByteBuf buffer = Unpooled.buffer();
137 ParserTest.reg.serializeMessage(keepAlive, buffer);
138 assertArrayEquals(keepAliveBMsg, ByteArray.getAllBytes(buffer));
140 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)));
142 assertTrue(m instanceof Keepalive);
146 public void testBadKeepAliveMsg() throws BGPParsingException {
147 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
148 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
149 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
152 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
153 fail("Exception should have occured.");
154 } catch (final BGPDocumentedException e) {
155 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
156 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
163 public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException {
164 final Notification open = new OpenBuilder().setMyAsNumber(100).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("20.20.20.20")).setVersion(
165 new ProtocolVersion((short) 4)).build();
166 final ByteBuf bytes = Unpooled.buffer();
167 ParserTest.reg.serializeMessage(open, bytes);
168 assertArrayEquals(openBMsg, ByteArray.getAllBytes(bytes));
170 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
172 assertTrue(m instanceof Open);
173 assertEquals(100, ((Open) m).getMyAsNumber().intValue());
174 assertEquals(180, ((Open) m).getHoldTimer().intValue());
175 assertEquals(new Ipv4Address("20.20.20.20"), ((Open) m).getBgpIdentifier());
176 assertTrue(((Open) m).getBgpParameters().isEmpty());
180 public void testBadHoldTimeError() throws BGPParsingException {
181 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
182 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
183 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
184 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
187 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
188 fail("Exception should have occured.");
189 } catch (final BGPDocumentedException e) {
190 assertEquals("Hold time value not acceptable.", e.getMessage());
191 assertEquals(BGPError.HOLD_TIME_NOT_ACC, e.getError());
198 public void testBadMsgLength() throws BGPParsingException {
199 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
200 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
201 (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
202 (byte) 0xff, (byte) 0xff };
205 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
206 fail("Exception should have occured.");
207 } catch (final BGPDocumentedException e) {
208 assertEquals("Open message too small.", e.getMessage());
209 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
214 public void testBadVersion() throws BGPParsingException {
215 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
216 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
217 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
218 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
221 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
222 fail("Exception should have occured.");
223 } catch (final BGPDocumentedException e) {
224 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
225 assertEquals(BGPError.VERSION_NOT_SUPPORTED, e.getError());
232 public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException {
233 Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()).setErrorSubcode(
234 BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
235 final ByteBuf bytes = Unpooled.buffer();
236 ParserTest.reg.serializeMessage(notMsg, bytes);
237 assertArrayEquals(notificationBMsg, ByteArray.subByte(bytes.array(),0,bytes.writerIndex()));
239 Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
241 assertTrue(m instanceof Notify);
242 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
243 assertArrayEquals(new byte[] { 4, 9 }, ((Notify) m).getData());
245 notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode(
246 BGPError.CONNECTION_NOT_SYNC.getSubcode()).build();
250 ParserTest.reg.serializeMessage(notMsg, bytes);
252 m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
254 assertTrue(m instanceof Notify);
255 assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
256 assertNull(((Notify) m).getData());
260 public void testWrongLength() throws BGPParsingException {
261 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
262 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
263 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
266 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
267 fail("Exception should have occured.");
268 } catch (final BGPDocumentedException e) {
269 assertEquals("Notification message too small.", e.getMessage());
270 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
277 public void testUnrecognizedError() throws BGPParsingException, BGPDocumentedException {
278 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
279 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
280 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
283 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
284 fail("Exception should have occured.");
285 } catch (final IllegalArgumentException e) {
286 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
293 public void testTLVParser() throws UnknownHostException {
295 final BgpTableType t1 = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
296 final BgpTableType t2 = new BgpTableTypeImpl(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class);
298 final List<OptionalCapabilities> capas = Lists.newArrayList();
300 capas.add(new OptionalCapabilitiesBuilder().setCParameters(
301 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
302 new MultiprotocolCapabilityBuilder().setAfi(LinkstateAddressFamily.class).setSafi(
303 LinkstateSubsequentAddressFamily.class).build()).build()).build());
304 capas.add(new OptionalCapabilitiesBuilder().setCParameters(
305 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
306 new MultiprotocolCapabilityBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).build()).build()).build());
307 final List<BgpParameters> tlvs = Lists.newArrayList(new BgpParametersBuilder().setOptionalCapabilities(capas).build());
309 final Map<BgpTableType, Boolean> tableTypes = Maps.newHashMap();
310 tableTypes.put(t1, true);
311 tableTypes.put(t2, true);
312 final Open open = new OpenBuilder().setMyAsNumber(72).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("172.20.160.170")).setVersion(
313 new ProtocolVersion((short) 4)).setBgpParameters(tlvs).build();
315 final ByteBuf result = Unpooled.buffer();
316 ParserTest.reg.serializeMessage(open, result);
318 // the capabilities can be swapped.
319 assertTrue(Arrays.equals(openWithCpblt1, ByteArray.getAllBytes(result)) || Arrays.equals(openWithCpblt2, ByteArray.getAllBytes(result)));
323 public void testParseUpdMsgWithUnrecognizedAttribute() throws BGPDocumentedException, BGPParsingException {
325 reg.parseMessage(Unpooled.copiedBuffer(updMsgWithUnrecognizedAttribute));
326 fail("Exception should have occured.");
327 } catch (final BGPDocumentedException e) {
328 assertEquals("Well known attribute not recognized.", e.getMessage());
329 assertEquals(BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED, e.getError());