29
29
30
30
#include < cstddef>
31
31
#include < jni.h>
32
+ #include < memory>
32
33
#include < string>
33
34
34
35
namespace chip {
@@ -37,11 +38,14 @@ namespace Dnssd {
37
38
using namespace chip ::Platform;
38
39
39
40
namespace {
40
- jobject sResolverObject = nullptr ;
41
- jobject sMdnsCallbackObject = nullptr ;
42
- jmethodID sResolveMethod = nullptr ;
43
- jmethodID sPublishMethod = nullptr ;
44
- jmethodID sRemoveServicesMethod = nullptr ;
41
+ jobject sResolverObject = nullptr ;
42
+ jobject sMdnsCallbackObject = nullptr ;
43
+ jmethodID sResolveMethod = nullptr ;
44
+ jmethodID sGetTextEntryKeysMethod = nullptr ;
45
+ jmethodID sGetTextEntryDataMethod = nullptr ;
46
+ jclass sMdnsCallbackClass = nullptr ;
47
+ jmethodID sPublishMethod = nullptr ;
48
+ jmethodID sRemoveServicesMethod = nullptr ;
45
49
} // namespace
46
50
47
51
// Implementation of functions declared in lib/dnssd/platform/Dnssd.h
@@ -185,9 +189,14 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject)
185
189
sResolverObject = env->NewGlobalRef (resolverObject);
186
190
sMdnsCallbackObject = env->NewGlobalRef (mdnsCallbackObject);
187
191
jclass resolverClass = env->GetObjectClass (sResolverObject );
192
+ sMdnsCallbackClass = env->GetObjectClass (sMdnsCallbackObject );
188
193
189
194
VerifyOrReturn (resolverClass != nullptr , ChipLogError (Discovery, " Failed to get Resolver Java class" ));
190
195
196
+ sGetTextEntryKeysMethod = env->GetMethodID (sMdnsCallbackClass , " getTextEntryKeys" , " (Ljava/util/Map;)[Ljava/lang/String;" );
197
+
198
+ sGetTextEntryDataMethod = env->GetMethodID (sMdnsCallbackClass , " getTextEntryData" , " (Ljava/util/Map;Ljava/lang/String;)[B" );
199
+
191
200
sResolveMethod =
192
201
env->GetMethodID (resolverClass, " resolve" , " (Ljava/lang/String;Ljava/lang/String;JJLchip/platform/ChipMdnsCallback;)V" );
193
202
if (sResolveMethod == nullptr )
@@ -196,6 +205,18 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject)
196
205
env->ExceptionClear ();
197
206
}
198
207
208
+ if (sGetTextEntryKeysMethod == nullptr )
209
+ {
210
+ ChipLogError (Discovery, " Failed to access MdnsCallback 'getTextEntryKeys' method" );
211
+ env->ExceptionClear ();
212
+ }
213
+
214
+ if (sGetTextEntryDataMethod == nullptr )
215
+ {
216
+ ChipLogError (Discovery, " Failed to access MdnsCallback 'getTextEntryData' method" );
217
+ env->ExceptionClear ();
218
+ }
219
+
199
220
sPublishMethod =
200
221
env->GetMethodID (resolverClass, " publish" ,
201
222
" (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;[[B[Ljava/lang/String;)V" );
@@ -213,7 +234,8 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject)
213
234
}
214
235
}
215
236
216
- void HandleResolve (jstring instanceName, jstring serviceType, jstring address, jint port, jlong callbackHandle, jlong contextHandle)
237
+ void HandleResolve (jstring instanceName, jstring serviceType, jstring address, jint port, jobject textEntries, jlong callbackHandle,
238
+ jlong contextHandle)
217
239
{
218
240
VerifyOrReturn (callbackHandle != 0 , ChipLogError (Discovery, " HandleResolve called with callback equal to nullptr" ));
219
241
@@ -241,9 +263,74 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j
241
263
DnssdService service = {};
242
264
CopyString (service.mName , jniInstanceName.c_str ());
243
265
CopyString (service.mType , jniServiceType.c_str ());
244
- service.mPort = static_cast <uint16_t >(port);
266
+ service.mPort = static_cast <uint16_t >(port);
267
+ service.mTextEntrySize = 0 ;
268
+ service.mTextEntries = nullptr ;
269
+
270
+ // Note on alloc/free memory use
271
+ // We are only allocating the entries list and the data field of each entry
272
+ // so we free these in the exit section
273
+ if (textEntries != nullptr )
274
+ {
275
+ jobjectArray keys = (jobjectArray) env->CallObjectMethod (sMdnsCallbackObject , sGetTextEntryKeysMethod , textEntries);
276
+ size_t size = env->GetArrayLength (keys);
277
+ TextEntry * entries = new (std::nothrow) TextEntry[size];
278
+ VerifyOrExit (entries != nullptr , ChipLogError (Discovery, " entries alloc failure" ));
279
+ memset (entries, 0 , sizeof (entries[0 ]) * size);
280
+
281
+ service.mTextEntries = entries;
282
+ for (size_t i = 0 ; i < size; i++)
283
+ {
284
+ jstring jniKeyObject = (jstring) env->GetObjectArrayElement (keys, i);
285
+ JniUtfString key (env, jniKeyObject);
286
+ entries[i].mKey = strdup (key.c_str ());
287
+
288
+ jbyteArray datas =
289
+ (jbyteArray) env->CallObjectMethod (sMdnsCallbackObject , sGetTextEntryDataMethod , textEntries, jniKeyObject);
290
+ if (datas != nullptr )
291
+ {
292
+ size_t dataSize = env->GetArrayLength (datas);
293
+ uint8_t * data = new (std::nothrow) uint8_t [dataSize];
294
+ VerifyOrExit (data != nullptr , ChipLogError (Discovery, " data alloc failure" ));
295
+
296
+ jbyte * jnidata = env->GetByteArrayElements (datas, nullptr );
297
+ for (size_t j = 0 ; j < dataSize; j++)
298
+ {
299
+ data[j] = static_cast <uint8_t >(jnidata[j]);
300
+ }
301
+ entries[i].mDataSize = dataSize;
302
+ entries[i].mData = data;
303
+
304
+ ChipLogProgress (Discovery, " ----- entry [%u] : %s %s\n " , static_cast <unsigned int >(i), entries[i].mKey ,
305
+ std::string (reinterpret_cast <char *>(data), dataSize).c_str ());
306
+ }
307
+ else
308
+ {
309
+ ChipLogProgress (Discovery, " ----- entry [%u] : %s NULL\n " , static_cast <unsigned int >(i), entries[i].mKey );
310
+
311
+ entries[i].mDataSize = 0 ;
312
+ entries[i].mData = nullptr ;
313
+ }
314
+ service.mTextEntrySize = size;
315
+ }
316
+ }
245
317
318
+ exit :
246
319
dispatch (CHIP_NO_ERROR, &service, &ipAddress);
320
+
321
+ if (service.mTextEntries != nullptr )
322
+ {
323
+ size_t size = service.mTextEntrySize ;
324
+ for (size_t i = 0 ; i < size; i++)
325
+ {
326
+ delete[] service.mTextEntries [i].mKey ;
327
+ if (service.mTextEntries [i].mData != nullptr )
328
+ {
329
+ delete[] service.mTextEntries [i].mData ;
330
+ }
331
+ }
332
+ delete[] service.mTextEntries ;
333
+ }
247
334
}
248
335
249
336
} // namespace Dnssd
0 commit comments