1956f54b391677d78379729dd14518edddf3c7660Etan Cohen/* 2956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Copyright (C) 2016 The Android Open Source Project 3956f54b391677d78379729dd14518edddf3c7660Etan Cohen * 4956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License"); 5956f54b391677d78379729dd14518edddf3c7660Etan Cohen * you may not use this file except in compliance with the License. 6956f54b391677d78379729dd14518edddf3c7660Etan Cohen * You may obtain a copy of the License at 7956f54b391677d78379729dd14518edddf3c7660Etan Cohen * 8956f54b391677d78379729dd14518edddf3c7660Etan Cohen * http://www.apache.org/licenses/LICENSE-2.0 9956f54b391677d78379729dd14518edddf3c7660Etan Cohen * 10956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Unless required by applicable law or agreed to in writing, software 11956f54b391677d78379729dd14518edddf3c7660Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS, 12956f54b391677d78379729dd14518edddf3c7660Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13956f54b391677d78379729dd14518edddf3c7660Etan Cohen * See the License for the specific language governing permissions and 14956f54b391677d78379729dd14518edddf3c7660Etan Cohen * limitations under the License. 15956f54b391677d78379729dd14518edddf3c7660Etan Cohen */ 16956f54b391677d78379729dd14518edddf3c7660Etan Cohen 17956f54b391677d78379729dd14518edddf3c7660Etan Cohenpackage com.android.server.wifi.nan; 18956f54b391677d78379729dd14518edddf3c7660Etan Cohen 19956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.hamcrest.core.IsEqual.equalTo; 20956f54b391677d78379729dd14518edddf3c7660Etan Cohen 21956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.net.wifi.nan.TlvBufferUtils; 22956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.test.suitebuilder.annotation.SmallTest; 23956f54b391677d78379729dd14518edddf3c7660Etan Cohen 24956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Rule; 25956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Test; 26956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.rules.ErrorCollector; 27956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.rules.ExpectedException; 28956f54b391677d78379729dd14518edddf3c7660Etan Cohen 29956f54b391677d78379729dd14518edddf3c7660Etan Cohen/** 30956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Unit test harness for WifiNanManager class. 31956f54b391677d78379729dd14518edddf3c7660Etan Cohen */ 32956f54b391677d78379729dd14518edddf3c7660Etan Cohen@SmallTest 33956f54b391677d78379729dd14518edddf3c7660Etan Cohenpublic class TlvBufferUtilsTest { 34956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Rule 35956f54b391677d78379729dd14518edddf3c7660Etan Cohen public ErrorCollector collector = new ErrorCollector(); 36956f54b391677d78379729dd14518edddf3c7660Etan Cohen 37956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Rule 38956f54b391677d78379729dd14518edddf3c7660Etan Cohen public ExpectedException thrown = ExpectedException.none(); 39956f54b391677d78379729dd14518edddf3c7660Etan Cohen 40956f54b391677d78379729dd14518edddf3c7660Etan Cohen /* 41956f54b391677d78379729dd14518edddf3c7660Etan Cohen * TlvBufferUtils Tests 42956f54b391677d78379729dd14518edddf3c7660Etan Cohen */ 43956f54b391677d78379729dd14518edddf3c7660Etan Cohen 44956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 45956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvBuild() { 46956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv11 = new TlvBufferUtils.TlvConstructor(1, 1); 47956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv11.allocate(15); 48956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv11.putByte(0, (byte) 2); 49956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv11.putByteArray(2, new byte[] { 50956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2 }); 51956f54b391677d78379729dd14518edddf3c7660Etan Cohen 52956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv11-correct-construction", 53956f54b391677d78379729dd14518edddf3c7660Etan Cohen utilAreArraysEqual(tlv11.getArray(), tlv11.getActualLength(), new byte[] { 54956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2, 2, 3, 0, 1, 2 }, 8), 55956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(true)); 56956f54b391677d78379729dd14518edddf3c7660Etan Cohen 57956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1); 58956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv01.allocate(15); 59956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv01.putByte(0, (byte) 2); 60956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv01.putByteArray(2, new byte[] { 61956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2 }); 62956f54b391677d78379729dd14518edddf3c7660Etan Cohen 63956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv01-correct-construction", 64956f54b391677d78379729dd14518edddf3c7660Etan Cohen utilAreArraysEqual(tlv01.getArray(), tlv01.getActualLength(), new byte[] { 65956f54b391677d78379729dd14518edddf3c7660Etan Cohen 1, 2, 3, 0, 1, 2 }, 6), 66956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(true)); 67956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 68956f54b391677d78379729dd14518edddf3c7660Etan Cohen 69956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 70956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvIterate() { 71956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv22 = new TlvBufferUtils.TlvConstructor(2, 2); 72956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv22.allocate(18); 73956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv22.putInt(0, 2); 74956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv22.putShort(2, (short) 3); 75956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv22.putZeroLengthElement(55); 76956f54b391677d78379729dd14518edddf3c7660Etan Cohen 77956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvIterable tlv22It = new TlvBufferUtils.TlvIterable(2, 2, tlv22.getArray(), 78956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv22.getActualLength()); 79956f54b391677d78379729dd14518edddf3c7660Etan Cohen int count = 0; 80956f54b391677d78379729dd14518edddf3c7660Etan Cohen for (TlvBufferUtils.TlvElement tlv : tlv22It) { 81956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (count == 0) { 82956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-mType", tlv.mType, equalTo(0)); 83956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-mLength", tlv.mLength, equalTo(4)); 84956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-DATA", tlv.getInt(), equalTo(2)); 85956f54b391677d78379729dd14518edddf3c7660Etan Cohen } else if (count == 1) { 86956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-mType", tlv.mType, equalTo(2)); 87956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-mLength", tlv.mLength, equalTo(2)); 88956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-DATA", (int) tlv.getShort(), 89956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(3)); 90956f54b391677d78379729dd14518edddf3c7660Etan Cohen } else if (count == 2) { 91956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-mType", tlv.mType, equalTo(55)); 92956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv22-correct-iteration-mLength", tlv.mLength, equalTo(0)); 93956f54b391677d78379729dd14518edddf3c7660Etan Cohen } else { 94956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("Invalid number of iterations in loop - tlv22", true, 95956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(false)); 96956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 97956f54b391677d78379729dd14518edddf3c7660Etan Cohen ++count; 98956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 99956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (count != 3) { 100956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("Invalid number of iterations outside loop - tlv22", true, 101956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(false)); 102956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 103956f54b391677d78379729dd14518edddf3c7660Etan Cohen 104956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv02 = new TlvBufferUtils.TlvConstructor(0, 2); 105956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv02.allocate(15); 106956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv02.putByte(0, (byte) 2); 107956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv02.putString(0, "ABC"); 108956f54b391677d78379729dd14518edddf3c7660Etan Cohen 109956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvIterable tlv02It = new TlvBufferUtils.TlvIterable(0, 2, tlv02.getArray(), 110956f54b391677d78379729dd14518edddf3c7660Etan Cohen tlv02.getActualLength()); 111956f54b391677d78379729dd14518edddf3c7660Etan Cohen count = 0; 112956f54b391677d78379729dd14518edddf3c7660Etan Cohen for (TlvBufferUtils.TlvElement tlv : tlv02It) { 113956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (count == 0) { 114956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv02-correct-iteration-mLength", tlv.mLength, equalTo(1)); 115956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv02-correct-iteration-DATA", (int) tlv.getByte(), 116956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(2)); 117956f54b391677d78379729dd14518edddf3c7660Etan Cohen } else if (count == 1) { 118956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv02-correct-iteration-mLength", tlv.mLength, equalTo(3)); 119956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("tlv02-correct-iteration-DATA", tlv.getString().equals("ABC"), 120956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(true)); 121956f54b391677d78379729dd14518edddf3c7660Etan Cohen } else { 122956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("Invalid number of iterations in loop - tlv02", true, 123956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(false)); 124956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 125956f54b391677d78379729dd14518edddf3c7660Etan Cohen ++count; 126956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 127956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (count != 2) { 128956f54b391677d78379729dd14518edddf3c7660Etan Cohen collector.checkThat("Invalid number of iterations outside loop - tlv02", true, 129956f54b391677d78379729dd14518edddf3c7660Etan Cohen equalTo(false)); 130956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 131956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 132956f54b391677d78379729dd14518edddf3c7660Etan Cohen 133956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 134956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvInvalidSizeT1L0() { 135956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 136956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 0); 137956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 138956f54b391677d78379729dd14518edddf3c7660Etan Cohen 139956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 140956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvInvalidSizeTm3L2() { 141956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 142956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(-3, 2); 143956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 144956f54b391677d78379729dd14518edddf3c7660Etan Cohen 145956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 146956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvInvalidSizeT1Lm2() { 147956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 148956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, -2); 149956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 150956f54b391677d78379729dd14518edddf3c7660Etan Cohen 151956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 152956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvInvalidSizeT1L3() { 153956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 154956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 3); 155956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 156956f54b391677d78379729dd14518edddf3c7660Etan Cohen 157956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 158956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvInvalidSizeT3L1() { 159956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 160956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(3, 1); 161956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 162956f54b391677d78379729dd14518edddf3c7660Etan Cohen 163956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 164956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvItInvalidSizeT1L0() { 165956f54b391677d78379729dd14518edddf3c7660Etan Cohen final byte[] dummy = { 166956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2 }; 167956f54b391677d78379729dd14518edddf3c7660Etan Cohen final int dummyLength = 3; 168956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 169956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, dummy, 170956f54b391677d78379729dd14518edddf3c7660Etan Cohen dummyLength); 171956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 172956f54b391677d78379729dd14518edddf3c7660Etan Cohen 173956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 174956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvItInvalidSizeTm3L2() { 175956f54b391677d78379729dd14518edddf3c7660Etan Cohen final byte[] dummy = { 176956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2 }; 177956f54b391677d78379729dd14518edddf3c7660Etan Cohen final int dummyLength = 3; 178956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 179956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, dummy, 180956f54b391677d78379729dd14518edddf3c7660Etan Cohen dummyLength); 181956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 182956f54b391677d78379729dd14518edddf3c7660Etan Cohen 183956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 184956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvItInvalidSizeT1Lm2() { 185956f54b391677d78379729dd14518edddf3c7660Etan Cohen final byte[] dummy = { 186956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2 }; 187956f54b391677d78379729dd14518edddf3c7660Etan Cohen final int dummyLength = 3; 188956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 189956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, dummy, 190956f54b391677d78379729dd14518edddf3c7660Etan Cohen dummyLength); 191956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 192956f54b391677d78379729dd14518edddf3c7660Etan Cohen 193956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 194956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvItInvalidSizeT1L3() { 195956f54b391677d78379729dd14518edddf3c7660Etan Cohen final byte[] dummy = { 196956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2 }; 197956f54b391677d78379729dd14518edddf3c7660Etan Cohen final int dummyLength = 3; 198956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 199956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, dummy, 200956f54b391677d78379729dd14518edddf3c7660Etan Cohen dummyLength); 201956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 202956f54b391677d78379729dd14518edddf3c7660Etan Cohen 203956f54b391677d78379729dd14518edddf3c7660Etan Cohen @Test 204956f54b391677d78379729dd14518edddf3c7660Etan Cohen public void testTlvItInvalidSizeT3L1() { 205956f54b391677d78379729dd14518edddf3c7660Etan Cohen final byte[] dummy = { 206956f54b391677d78379729dd14518edddf3c7660Etan Cohen 0, 1, 2 }; 207956f54b391677d78379729dd14518edddf3c7660Etan Cohen final int dummyLength = 3; 208956f54b391677d78379729dd14518edddf3c7660Etan Cohen thrown.expect(IllegalArgumentException.class); 209956f54b391677d78379729dd14518edddf3c7660Etan Cohen TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, dummy, 210956f54b391677d78379729dd14518edddf3c7660Etan Cohen dummyLength); 211956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 212956f54b391677d78379729dd14518edddf3c7660Etan Cohen 213956f54b391677d78379729dd14518edddf3c7660Etan Cohen /* 214956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Utilities 215956f54b391677d78379729dd14518edddf3c7660Etan Cohen */ 216956f54b391677d78379729dd14518edddf3c7660Etan Cohen 217956f54b391677d78379729dd14518edddf3c7660Etan Cohen private static boolean utilAreArraysEqual(byte[] x, int xLength, byte[] y, int yLength) { 218956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (xLength != yLength) { 219956f54b391677d78379729dd14518edddf3c7660Etan Cohen return false; 220956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 221956f54b391677d78379729dd14518edddf3c7660Etan Cohen 222956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (x != null && y != null) { 223956f54b391677d78379729dd14518edddf3c7660Etan Cohen for (int i = 0; i < xLength; ++i) { 224956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (x[i] != y[i]) { 225956f54b391677d78379729dd14518edddf3c7660Etan Cohen return false; 226956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 227956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 228956f54b391677d78379729dd14518edddf3c7660Etan Cohen } else if (xLength != 0) { 229956f54b391677d78379729dd14518edddf3c7660Etan Cohen return false; // invalid != invalid 230956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 231956f54b391677d78379729dd14518edddf3c7660Etan Cohen 232956f54b391677d78379729dd14518edddf3c7660Etan Cohen return true; 233956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 234956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 235