1956f54b391677d78379729dd14518edddf3c7660Etan Cohen/* 2956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Copyright 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 Cohen#include <stdint.h> 18956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include "JniConstants.h" 19956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <ScopedUtfChars.h> 20956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <ScopedBytes.h> 21956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <utils/misc.h> 22956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <android_runtime/AndroidRuntime.h> 23956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <utils/Log.h> 24956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <utils/String16.h> 25956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <ctype.h> 26956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <sys/socket.h> 27956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <linux/if.h> 28956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include "wifi.h" 29956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include "wifi_hal.h" 30956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include "jni_helper.h" 31956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include "wifi_hal_mock.h" 32956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <sstream> 33956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <rapidjson/document.h> 34956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <rapidjson/stringbuffer.h> 35956f54b391677d78379729dd14518edddf3c7660Etan Cohen#include <rapidjson/writer.h> 36956f54b391677d78379729dd14518edddf3c7660Etan Cohen 37956f54b391677d78379729dd14518edddf3c7660Etan Cohennamespace android { 38956f54b391677d78379729dd14518edddf3c7660Etan Cohen 39956f54b391677d78379729dd14518edddf3c7660Etan Cohenjobject mock_mObj; /* saved HalMock object (not class!) */ 40956f54b391677d78379729dd14518edddf3c7660Etan CohenJavaVM* mock_mVM = NULL; /* saved JVM pointer */ 41956f54b391677d78379729dd14518edddf3c7660Etan Cohen 42956f54b391677d78379729dd14518edddf3c7660Etan Cohen/* Variable and function declared and defined in: 4322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen * com_android_server_wifi_nan_WifiNanNative.cpp 44956f54b391677d78379729dd14518edddf3c7660Etan Cohen */ 45956f54b391677d78379729dd14518edddf3c7660Etan Cohenextern wifi_hal_fn hal_fn; 46956f54b391677d78379729dd14518edddf3c7660Etan Cohenextern "C" jint Java_com_android_server_wifi_WifiNative_registerNatives( 47956f54b391677d78379729dd14518edddf3c7660Etan Cohen JNIEnv* env, jclass clazz); 48956f54b391677d78379729dd14518edddf3c7660Etan Cohen 49956f54b391677d78379729dd14518edddf3c7660Etan Cohennamespace hal_json_tags { 50956f54b391677d78379729dd14518edddf3c7660Etan Cohenstatic constexpr const char* const type_tag = "type"; 51956f54b391677d78379729dd14518edddf3c7660Etan Cohenstatic constexpr const char* const value_tag = "value"; 52956f54b391677d78379729dd14518edddf3c7660Etan Cohen 53956f54b391677d78379729dd14518edddf3c7660Etan Cohenstatic constexpr const char* const type_int_tag = "int"; 54956f54b391677d78379729dd14518edddf3c7660Etan Cohenstatic constexpr const char* const type_byte_array_tag = "byte_array"; 55956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 56956f54b391677d78379729dd14518edddf3c7660Etan Cohen 57956f54b391677d78379729dd14518edddf3c7660Etan CohenHalMockJsonWriter::HalMockJsonWriter() 58956f54b391677d78379729dd14518edddf3c7660Etan Cohen : allocator(doc.GetAllocator()) { 59956f54b391677d78379729dd14518edddf3c7660Etan Cohen doc.SetObject(); 60956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 61956f54b391677d78379729dd14518edddf3c7660Etan Cohen 62956f54b391677d78379729dd14518edddf3c7660Etan Cohenvoid HalMockJsonWriter::put_int(const char* name, int x) { 63956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value object(rapidjson::kObjectType); 64956f54b391677d78379729dd14518edddf3c7660Etan Cohen object.AddMember( 65956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value(hal_json_tags::type_tag, 66956f54b391677d78379729dd14518edddf3c7660Etan Cohen strlen(hal_json_tags::type_tag)), 67956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value(hal_json_tags::type_int_tag, 68956f54b391677d78379729dd14518edddf3c7660Etan Cohen strlen(hal_json_tags::type_int_tag)), 69956f54b391677d78379729dd14518edddf3c7660Etan Cohen allocator); 70956f54b391677d78379729dd14518edddf3c7660Etan Cohen object.AddMember( 71956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value(hal_json_tags::value_tag, 72956f54b391677d78379729dd14518edddf3c7660Etan Cohen strlen(hal_json_tags::value_tag)), 73956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value(x), allocator); 74956f54b391677d78379729dd14518edddf3c7660Etan Cohen doc.AddMember(rapidjson::Value(name, strlen(name)), object, allocator); 75956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 76956f54b391677d78379729dd14518edddf3c7660Etan Cohen 77956f54b391677d78379729dd14518edddf3c7660Etan Cohenvoid HalMockJsonWriter::put_byte_array(const char* name, u8* byte_array, 78956f54b391677d78379729dd14518edddf3c7660Etan Cohen int array_length) { 79956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value object(rapidjson::kObjectType); 80956f54b391677d78379729dd14518edddf3c7660Etan Cohen object.AddMember( 81956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value(hal_json_tags::type_tag, 82956f54b391677d78379729dd14518edddf3c7660Etan Cohen strlen(hal_json_tags::type_tag)), 83956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value(hal_json_tags::type_byte_array_tag, 84956f54b391677d78379729dd14518edddf3c7660Etan Cohen strlen(hal_json_tags::type_byte_array_tag)), 85956f54b391677d78379729dd14518edddf3c7660Etan Cohen allocator); 86956f54b391677d78379729dd14518edddf3c7660Etan Cohen 87956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value array(rapidjson::kArrayType); 88956f54b391677d78379729dd14518edddf3c7660Etan Cohen for (int i = 0; i < array_length; ++i) { 89956f54b391677d78379729dd14518edddf3c7660Etan Cohen array.PushBack((int) byte_array[i], allocator); 90956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 91956f54b391677d78379729dd14518edddf3c7660Etan Cohen 92956f54b391677d78379729dd14518edddf3c7660Etan Cohen object.AddMember( 93956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Value(hal_json_tags::value_tag, 94956f54b391677d78379729dd14518edddf3c7660Etan Cohen strlen(hal_json_tags::value_tag)), 95956f54b391677d78379729dd14518edddf3c7660Etan Cohen array, allocator); 96956f54b391677d78379729dd14518edddf3c7660Etan Cohen doc.AddMember(rapidjson::Value(name, strlen(name)), object, allocator); 97956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 98956f54b391677d78379729dd14518edddf3c7660Etan Cohen 99956f54b391677d78379729dd14518edddf3c7660Etan Cohenstd::string HalMockJsonWriter::to_string() { 100956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::StringBuffer strbuf; 101956f54b391677d78379729dd14518edddf3c7660Etan Cohen rapidjson::Writer < rapidjson::StringBuffer > writer(strbuf); 102956f54b391677d78379729dd14518edddf3c7660Etan Cohen doc.Accept(writer); 103956f54b391677d78379729dd14518edddf3c7660Etan Cohen return strbuf.GetString(); 104956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 105956f54b391677d78379729dd14518edddf3c7660Etan Cohen 106956f54b391677d78379729dd14518edddf3c7660Etan CohenHalMockJsonReader::HalMockJsonReader(const char* str) { 107956f54b391677d78379729dd14518edddf3c7660Etan Cohen doc.Parse(str); 108956f54b391677d78379729dd14518edddf3c7660Etan Cohen assert(doc.IsObject()); 109956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 110956f54b391677d78379729dd14518edddf3c7660Etan Cohen 111956f54b391677d78379729dd14518edddf3c7660Etan Cohenint HalMockJsonReader::get_int(const char* key, bool* error) { 112956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (!doc.HasMember(key)) { 113956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 114956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_int: can't find %s key", key); 115956f54b391677d78379729dd14518edddf3c7660Etan Cohen return 0; 116956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 117956f54b391677d78379729dd14518edddf3c7660Etan Cohen const rapidjson::Value& element = doc[key]; 118956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (!element.HasMember(hal_json_tags::value_tag)) { 119956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 120956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_int: can't find the 'value' sub-key for %s key", key); 121956f54b391677d78379729dd14518edddf3c7660Etan Cohen return 0; 122956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 123956f54b391677d78379729dd14518edddf3c7660Etan Cohen const rapidjson::Value& value = element[hal_json_tags::value_tag]; 124956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (!value.IsInt()) { 125956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 126956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_int: the value isn't an 'int' for the %s key", key); 127956f54b391677d78379729dd14518edddf3c7660Etan Cohen return 0; 128956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 129956f54b391677d78379729dd14518edddf3c7660Etan Cohen return value.GetInt(); 130956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 131956f54b391677d78379729dd14518edddf3c7660Etan Cohen 132956f54b391677d78379729dd14518edddf3c7660Etan Cohenvoid HalMockJsonReader::get_byte_array(const char* key, bool* error, u8* array, 133956f54b391677d78379729dd14518edddf3c7660Etan Cohen unsigned int max_array_size) { 134956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (!doc.HasMember(key)) { 135956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 136956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_byte_array: can't find %s key", key); 137956f54b391677d78379729dd14518edddf3c7660Etan Cohen return; 138956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 139956f54b391677d78379729dd14518edddf3c7660Etan Cohen const rapidjson::Value& element = doc[key]; 140956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (!element.HasMember(hal_json_tags::value_tag)) { 141956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 142956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_byte_array: can't find the 'value' sub-key for %s key", key); 143956f54b391677d78379729dd14518edddf3c7660Etan Cohen return; 144956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 145956f54b391677d78379729dd14518edddf3c7660Etan Cohen const rapidjson::Value& value = element[hal_json_tags::value_tag]; 146956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (!value.IsArray()) { 147956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 148956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_byte_array: the value isn't an 'array' for the %s key", key); 149956f54b391677d78379729dd14518edddf3c7660Etan Cohen return; 150956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 151956f54b391677d78379729dd14518edddf3c7660Etan Cohen 152956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (value.Size() > max_array_size) { 153956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 154956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_byte_array: size of array (%d) is larger than maximum " 155956f54b391677d78379729dd14518edddf3c7660Etan Cohen "allocated (%d)", 156956f54b391677d78379729dd14518edddf3c7660Etan Cohen value.Size(), max_array_size); 157956f54b391677d78379729dd14518edddf3c7660Etan Cohen return; 158956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 159956f54b391677d78379729dd14518edddf3c7660Etan Cohen 160956f54b391677d78379729dd14518edddf3c7660Etan Cohen for (unsigned int i = 0; i < value.Size(); ++i) { 161956f54b391677d78379729dd14518edddf3c7660Etan Cohen const rapidjson::Value& item = value[i]; 162956f54b391677d78379729dd14518edddf3c7660Etan Cohen if (!item.IsInt()) { 163956f54b391677d78379729dd14518edddf3c7660Etan Cohen *error = true; 164956f54b391677d78379729dd14518edddf3c7660Etan Cohen ALOGE("get_byte_array: the value isn't an 'int' for the %s[%d] key", key, 165956f54b391677d78379729dd14518edddf3c7660Etan Cohen i); 166956f54b391677d78379729dd14518edddf3c7660Etan Cohen return; 167956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 168956f54b391677d78379729dd14518edddf3c7660Etan Cohen array[i] = item.GetInt(); 169956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 170956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 171956f54b391677d78379729dd14518edddf3c7660Etan Cohen 172956f54b391677d78379729dd14518edddf3c7660Etan Cohen 173208f92c4d8457374ff507996d58ffa5586d1ecd5Mitchell Willsint init_wifi_hal_func_table_mock(wifi_hal_fn *fn) { 174208f92c4d8457374ff507996d58ffa5586d1ecd5Mitchell Wills if (fn == NULL) { 175956f54b391677d78379729dd14518edddf3c7660Etan Cohen return -1; 176956f54b391677d78379729dd14518edddf3c7660Etan Cohen } 177956f54b391677d78379729dd14518edddf3c7660Etan Cohen 178956f54b391677d78379729dd14518edddf3c7660Etan Cohen /* TODO: add other Wi-Fi HAL registrations here - once you have mocks */ 179956f54b391677d78379729dd14518edddf3c7660Etan Cohen 180956f54b391677d78379729dd14518edddf3c7660Etan Cohen return 0; 181956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 182956f54b391677d78379729dd14518edddf3c7660Etan Cohen 18322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohenextern "C" jint Java_com_android_server_wifi_HalMockUtils_initHalMock( 184956f54b391677d78379729dd14518edddf3c7660Etan Cohen JNIEnv* env, jclass clazz) { 185956f54b391677d78379729dd14518edddf3c7660Etan Cohen env->GetJavaVM(&mock_mVM); 186956f54b391677d78379729dd14518edddf3c7660Etan Cohen 187956f54b391677d78379729dd14518edddf3c7660Etan Cohen Java_com_android_server_wifi_WifiNative_registerNatives(env, clazz); 188956f54b391677d78379729dd14518edddf3c7660Etan Cohen return init_wifi_hal_func_table_mock(&hal_fn); 189956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 190956f54b391677d78379729dd14518edddf3c7660Etan Cohen 19122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohenextern "C" void Java_com_android_server_wifi_HalMockUtils_setHalMockObject( 192956f54b391677d78379729dd14518edddf3c7660Etan Cohen JNIEnv* env, jclass clazz, jobject hal_mock_object) { 193956f54b391677d78379729dd14518edddf3c7660Etan Cohen mock_mObj = (jobject) env->NewGlobalRef(hal_mock_object); 194956f54b391677d78379729dd14518edddf3c7660Etan Cohen} 195956f54b391677d78379729dd14518edddf3c7660Etan Cohen 196956f54b391677d78379729dd14518edddf3c7660Etan Cohen} // namespace android 197