wifi_hal_mock.cpp revision 22b4156d2948e3108ae8439dc72f76fb97526ace
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
173956f54b391677d78379729dd14518edddf3c7660Etan Cohenint init_wifi_hal_func_table_mock(wifi_hal_fn *hal_fn) {
174956f54b391677d78379729dd14518edddf3c7660Etan Cohen  if (hal_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