1 /*
2 * Copyright 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18 #include "JniConstants.h"
19 #include <ScopedUtfChars.h>
20 #include <ScopedBytes.h>
21 #include <utils/misc.h>
22 #include <android_runtime/AndroidRuntime.h>
23 #include <utils/Log.h>
24 #include <utils/String16.h>
25 #include <ctype.h>
26 #include <sys/socket.h>
27 #include <linux/if.h>
28 #include "wifi.h"
29 #include "wifi_hal.h"
30 #include "jni_helper.h"
31 #include "wifi_hal_mock.h"
32 #include <sstream>
33 #include <rapidjson/document.h>
34 #include <rapidjson/stringbuffer.h>
35 #include <rapidjson/writer.h>
36
37 namespace android {
38
39 jobject mock_mObj; /* saved HalMock object (not class!) */
40 JavaVM* mock_mVM = NULL; /* saved JVM pointer */
41
42 /* Variable and function declared and defined in:
43 * com_android_server_wifi_nan_WifiNanNative.cpp
44 */
45 extern wifi_hal_fn hal_fn;
46 extern "C" jint Java_com_android_server_wifi_WifiNative_registerNatives(
47 JNIEnv* env, jclass clazz);
48
49 namespace hal_json_tags {
50 static constexpr const char* const type_tag = "type";
51 static constexpr const char* const value_tag = "value";
52
53 static constexpr const char* const type_int_tag = "int";
54 static constexpr const char* const type_byte_array_tag = "byte_array";
55 }
56
HalMockJsonWriter()57 HalMockJsonWriter::HalMockJsonWriter()
58 : allocator(doc.GetAllocator()) {
59 doc.SetObject();
60 }
61
put_int(const char * name,int x)62 void HalMockJsonWriter::put_int(const char* name, int x) {
63 rapidjson::Value object(rapidjson::kObjectType);
64 object.AddMember(
65 rapidjson::Value(hal_json_tags::type_tag,
66 strlen(hal_json_tags::type_tag)),
67 rapidjson::Value(hal_json_tags::type_int_tag,
68 strlen(hal_json_tags::type_int_tag)),
69 allocator);
70 object.AddMember(
71 rapidjson::Value(hal_json_tags::value_tag,
72 strlen(hal_json_tags::value_tag)),
73 rapidjson::Value(x), allocator);
74 doc.AddMember(rapidjson::Value(name, strlen(name)), object, allocator);
75 }
76
put_byte_array(const char * name,u8 * byte_array,int array_length)77 void HalMockJsonWriter::put_byte_array(const char* name, u8* byte_array,
78 int array_length) {
79 rapidjson::Value object(rapidjson::kObjectType);
80 object.AddMember(
81 rapidjson::Value(hal_json_tags::type_tag,
82 strlen(hal_json_tags::type_tag)),
83 rapidjson::Value(hal_json_tags::type_byte_array_tag,
84 strlen(hal_json_tags::type_byte_array_tag)),
85 allocator);
86
87 rapidjson::Value array(rapidjson::kArrayType);
88 for (int i = 0; i < array_length; ++i) {
89 array.PushBack((int) byte_array[i], allocator);
90 }
91
92 object.AddMember(
93 rapidjson::Value(hal_json_tags::value_tag,
94 strlen(hal_json_tags::value_tag)),
95 array, allocator);
96 doc.AddMember(rapidjson::Value(name, strlen(name)), object, allocator);
97 }
98
to_string()99 std::string HalMockJsonWriter::to_string() {
100 rapidjson::StringBuffer strbuf;
101 rapidjson::Writer < rapidjson::StringBuffer > writer(strbuf);
102 doc.Accept(writer);
103 return strbuf.GetString();
104 }
105
HalMockJsonReader(const char * str)106 HalMockJsonReader::HalMockJsonReader(const char* str) {
107 doc.Parse(str);
108 assert(doc.IsObject());
109 }
110
get_int(const char * key,bool * error)111 int HalMockJsonReader::get_int(const char* key, bool* error) {
112 if (!doc.HasMember(key)) {
113 *error = true;
114 ALOGE("get_int: can't find %s key", key);
115 return 0;
116 }
117 const rapidjson::Value& element = doc[key];
118 if (!element.HasMember(hal_json_tags::value_tag)) {
119 *error = true;
120 ALOGE("get_int: can't find the 'value' sub-key for %s key", key);
121 return 0;
122 }
123 const rapidjson::Value& value = element[hal_json_tags::value_tag];
124 if (!value.IsInt()) {
125 *error = true;
126 ALOGE("get_int: the value isn't an 'int' for the %s key", key);
127 return 0;
128 }
129 return value.GetInt();
130 }
131
get_byte_array(const char * key,bool * error,u8 * array,unsigned int max_array_size)132 void HalMockJsonReader::get_byte_array(const char* key, bool* error, u8* array,
133 unsigned int max_array_size) {
134 if (!doc.HasMember(key)) {
135 *error = true;
136 ALOGE("get_byte_array: can't find %s key", key);
137 return;
138 }
139 const rapidjson::Value& element = doc[key];
140 if (!element.HasMember(hal_json_tags::value_tag)) {
141 *error = true;
142 ALOGE("get_byte_array: can't find the 'value' sub-key for %s key", key);
143 return;
144 }
145 const rapidjson::Value& value = element[hal_json_tags::value_tag];
146 if (!value.IsArray()) {
147 *error = true;
148 ALOGE("get_byte_array: the value isn't an 'array' for the %s key", key);
149 return;
150 }
151
152 if (value.Size() > max_array_size) {
153 *error = true;
154 ALOGE("get_byte_array: size of array (%d) is larger than maximum "
155 "allocated (%d)",
156 value.Size(), max_array_size);
157 return;
158 }
159
160 for (unsigned int i = 0; i < value.Size(); ++i) {
161 const rapidjson::Value& item = value[i];
162 if (!item.IsInt()) {
163 *error = true;
164 ALOGE("get_byte_array: the value isn't an 'int' for the %s[%d] key", key,
165 i);
166 return;
167 }
168 array[i] = item.GetInt();
169 }
170 }
171
172
init_wifi_hal_func_table_mock(wifi_hal_fn * fn)173 int init_wifi_hal_func_table_mock(wifi_hal_fn *fn) {
174 if (fn == NULL) {
175 return -1;
176 }
177
178 /* TODO: add other Wi-Fi HAL registrations here - once you have mocks */
179
180 return 0;
181 }
182
Java_com_android_server_wifi_HalMockUtils_initHalMock(JNIEnv * env,jclass clazz)183 extern "C" jint Java_com_android_server_wifi_HalMockUtils_initHalMock(
184 JNIEnv* env, jclass clazz) {
185 env->GetJavaVM(&mock_mVM);
186
187 Java_com_android_server_wifi_WifiNative_registerNatives(env, clazz);
188 return init_wifi_hal_func_table_mock(&hal_fn);
189 }
190
Java_com_android_server_wifi_HalMockUtils_setHalMockObject(JNIEnv * env,jclass clazz,jobject hal_mock_object)191 extern "C" void Java_com_android_server_wifi_HalMockUtils_setHalMockObject(
192 JNIEnv* env, jclass clazz, jobject hal_mock_object) {
193 mock_mObj = (jobject) env->NewGlobalRef(hal_mock_object);
194 }
195
196 } // namespace android
197