Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
yunhanw-google committed Mar 6, 2023
1 parent 08a3e36 commit a63953c
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
import java.util.logging.Logger;

public final class PairOnNetworkLongImInvokeCommand extends PairingCommand {
private static final Logger logger = Logger.getLogger(PairOnNetworkLongImInvokeCommand.class.getName());
private static final int MATTER_PORT = 5540;
private long devicePointer;
private static final int CLUSTER_ID_IDENTIFY = 0x0003;
private static final int IDENTIFY_COMMAND = 0;
private static Logger logger = Logger.getLogger(PairOnNetworkLongImInvokeCommand.class.getName());
private long devicePointer;

private void setDevicePointer(long devicePointer) {
this.devicePointer = devicePointer;
Expand Down Expand Up @@ -67,7 +67,7 @@ protected void runCommand() {
byte[] intTLV = {0x15, 0x24, 0x00, 0x01, 0x18};
InvokeElement element =
InvokeElement.newInstance(
/* endpointId= */ 0, CLUSTER_ID_IDENTIFY, IDENTIFY_COMMAND, intTLV);
/* endpointId= */ 0, CLUSTER_ID_IDENTIFY, IDENTIFY_COMMAND, intTLV, null);

currentCommissioner()
.pairDeviceWithAddress(
Expand Down
95 changes: 36 additions & 59 deletions src/controller/java/AndroidCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,28 +422,6 @@ CHIP_ERROR CreateChipAttributePath(const app::ConcreteDataAttributePath & aPath,
return err;
}

CHIP_ERROR InvokeCallback::CreateInvokeElement(const app::ConcreteCommandPath & aPath, jobject & outObj)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
CHIP_ERROR err = CHIP_NO_ERROR;

jclass invokeElementCls = nullptr;
err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/model/InvokeElement", invokeElementCls);
ReturnErrorOnFailure(err);
JniClass invokeElementJniCls(invokeElementCls);

jmethodID invokeElementCtor =
env->GetStaticMethodID(invokeElementCls, "newInstance", "(JJJ)Lchip/devicecontroller/model/InvokeElement;");
VerifyOrReturnError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
VerifyOrReturnError(invokeElementCtor != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

outObj =
env->CallStaticObjectMethod(invokeElementCls, invokeElementCtor, aPath.mEndpointId, aPath.mClusterId, aPath.mCommandId);
VerifyOrReturnError(outObj != nullptr, CHIP_JNI_ERROR_NULL_OBJECT);

return err;
}

CHIP_ERROR InvokeCallback::CreateInvokeElement(const app::ConcreteCommandPath & aPath, TLV::TLVReader * apData, jobject & outObj)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
Expand All @@ -459,34 +437,41 @@ CHIP_ERROR InvokeCallback::CreateInvokeElement(const app::ConcreteCommandPath &
VerifyOrReturnError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
VerifyOrReturnError(invokeElementCtor != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

TLV::TLVReader readerForJavaTLV;
TLV::TLVReader readerForJson;
readerForJavaTLV.Init(*apData);
readerForJson.Init(*apData);

// Create TLV byte array to pass to Java layer
size_t bufferLen = readerForJavaTLV.GetRemainingLength() + readerForJavaTLV.GetLengthRead();
std::unique_ptr<uint8_t[]> buffer = std::unique_ptr<uint8_t[]>(new uint8_t[bufferLen]);
uint32_t size = 0;
// The TLVReader's read head is not pointing to the first element in the container, instead of the container itself, use
// a TLVWriter to get a TLV with a normalized TLV buffer (Wrapped with an anonymous tag, no extra "end of container" tag
// at the end.)
TLV::TLVWriter writer;
writer.Init(buffer.get(), bufferLen);
err = writer.CopyElement(TLV::AnonymousTag(), readerForJavaTLV);
ReturnErrorOnFailure(err);
size = writer.GetLengthWritten();
chip::ByteArray jniByteArray(env, reinterpret_cast<jbyte *>(buffer.get()), size);

// Convert TLV to JSON
Json::Value json;
err = TlvToJson(readerForJson, json);
ReturnErrorOnFailure(err);

UtfString jsonString(env, JsonToString(json).c_str());

outObj = env->CallStaticObjectMethod(invokeElementCls, invokeElementCtor, aPath.mEndpointId, aPath.mClusterId, aPath.mCommandId,
jniByteArray.jniValue(), jsonString.jniValue());
if (apData != nullptr)
{
TLV::TLVReader readerForJavaTLV;
TLV::TLVReader readerForJson;
readerForJavaTLV.Init(*apData);
readerForJson.Init(*apData);

// Create TLV byte array to pass to Java layer
size_t bufferLen = readerForJavaTLV.GetRemainingLength() + readerForJavaTLV.GetLengthRead();
std::unique_ptr<uint8_t[]> buffer = std::unique_ptr<uint8_t[]>(new uint8_t[bufferLen]);
uint32_t size = 0;
// The TLVReader's read head is not pointing to the first element in the container, instead of the container itself, use
// a TLVWriter to get a TLV with a normalized TLV buffer (Wrapped with an anonymous tag, no extra "end of container" tag
// at the end.)
TLV::TLVWriter writer;
writer.Init(buffer.get(), bufferLen);
err = writer.CopyElement(TLV::AnonymousTag(), readerForJavaTLV);
ReturnErrorOnFailure(err);
size = writer.GetLengthWritten();
chip::ByteArray jniByteArray(env, reinterpret_cast<jbyte *>(buffer.get()), size);

// Convert TLV to JSON
Json::Value json;
err = TlvToJson(readerForJson, json);
ReturnErrorOnFailure(err);

UtfString jsonString(env, JsonToString(json).c_str());
outObj = env->CallStaticObjectMethod(invokeElementCls, invokeElementCtor, aPath.mEndpointId, aPath.mClusterId, aPath.mCommandId,
jniByteArray.jniValue(), jsonString.jniValue());
}
else
{
outObj = env->CallStaticObjectMethod(invokeElementCls, invokeElementCtor, aPath.mEndpointId, aPath.mClusterId, aPath.mCommandId,
nullptr, nullptr);
}
VerifyOrReturnError(outObj != nullptr, CHIP_JNI_ERROR_NULL_OBJECT);

return err;
Expand Down Expand Up @@ -980,15 +965,7 @@ void InvokeCallback::OnResponse(app::CommandSender * apCommandSender, const app:
jobject invokeElementObj = nullptr;
jmethodID onResponseMethod;

if (apData != nullptr)
{
err = CreateInvokeElement(aPath, apData, invokeElementObj);
}
else
{
err = CreateInvokeElement(aPath, invokeElementObj);
}

err = CreateInvokeElement(aPath, apData, invokeElementObj);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create Java InvokeElement: %s", ErrorStr(err)));
err = JniReferences::GetInstance().FindMethod(env, mJavaCallbackRef, "onResponse",
"(Lchip/devicecontroller/model/InvokeElement;J)V", &onResponseMethod);
Expand Down
1 change: 0 additions & 1 deletion src/controller/java/AndroidCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ struct InvokeCallback : public app::CommandSender::Callback

void OnDone(app::CommandSender * apCommandSender) override;

CHIP_ERROR CreateInvokeElement(const app::ConcreteCommandPath & aPath, jobject & outObj);
CHIP_ERROR CreateInvokeElement(const app::ConcreteCommandPath & aPath, TLV::TLVReader * apData, jobject & outObj);
void ReportError(CHIP_ERROR err);
void ReportError(Protocols::InteractionModel::Status status);
Expand Down
7 changes: 0 additions & 7 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1500,7 +1500,6 @@ JNI_METHOD(void, invoke)
jmethodID getEndpointIdMethod = nullptr;
jmethodID getClusterIdMethod = nullptr;
jmethodID getCommandIdMethod = nullptr;
jmethodID hasTlvMethod = nullptr;
jmethodID getTlvByteArrayMethod = nullptr;
jobject endpointIdObj = nullptr;
jobject clusterIdObj = nullptr;
Expand All @@ -1510,7 +1509,6 @@ JNI_METHOD(void, invoke)
jsize length = 0;
TLV::TLVReader reader;
TLV::TLVWriter * writer = nullptr;
bool hasTlv = false;

ChipLogDetail(Controller, "IM invoke() called");

Expand All @@ -1526,7 +1524,6 @@ JNI_METHOD(void, invoke)
"()Lchip/devicecontroller/model/ChipPathId;", &getClusterIdMethod));
SuccessOrExit(err = JniReferences::GetInstance().FindMethod(env, invokeElement, "getCommandId",
"()Lchip/devicecontroller/model/ChipPathId;", &getCommandIdMethod));
SuccessOrExit(err = JniReferences::GetInstance().FindMethod(env, invokeElement, "hasTlv", "()Z", &hasTlvMethod));
SuccessOrExit(JniReferences::GetInstance().FindMethod(env, invokeElement, "getTlvByteArray", "()[B", &getTlvByteArrayMethod));

endpointIdObj = env->CallObjectMethod(invokeElement, getEndpointIdMethod);
Expand All @@ -1545,10 +1542,6 @@ JNI_METHOD(void, invoke)
SuccessOrExit(err = GetChipPathIdValue(clusterIdObj, kInvalidClusterId, clusterId));
SuccessOrExit(err = GetChipPathIdValue(commandIdObj, kInvalidCommandId, commandId));

hasTlv = static_cast<bool>(env->CallBooleanMethod(invokeElement, hasTlvMethod));
VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN);
VerifyOrExit(hasTlv, err = CHIP_ERROR_INVALID_ARGUMENT);

tlvBytesObj = static_cast<jbyteArray>(env->CallObjectMethod(invokeElement, getTlvByteArrayMethod));
VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN);
VerifyOrExit(tlvBytesObj != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
package chip.devicecontroller;

/** JNI wrapper callback class for {@link InvokeCallback}. */
public class InvokeCallbackJni {
public final class InvokeCallbackJni {
private final InvokeCallback wrappedInvokeCallback;
private long callbackHandle;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
package chip.devicecontroller;

/** JNI wrapper callback class for {@link WriteAttributesCallback}. */
public class WriteAttributesCallbackJni {
public final class WriteAttributesCallbackJni {
private final WriteAttributesCallback wrappedWriteAttributesCallback;
private long callbackHandle;

Expand Down
110 changes: 31 additions & 79 deletions src/controller/java/src/chip/devicecontroller/model/InvokeElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,49 @@

import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONException;
import org.json.JSONObject;

/** An invoke element that should be used for interaction model invoke request and response. */
public final class InvokeElement {
private static final Logger logger = Logger.getLogger(InvokeElement.class.getName());
private final ChipPathId endpointId, clusterId, commandId;
private final Optional<byte[]> tlv;
private final Optional<JSONObject> json;
private static Logger logger = Logger.getLogger(InvokeElement.class.getName());
@Nullable private final byte[] tlv;
@Nullable private final JSONObject json;

private InvokeElement(
ChipPathId endpointId,
ChipPathId clusterId,
ChipPathId commandId,
Optional<byte[]> tlv,
Optional<String> jsonString) {
@Nullable byte[] tlv,
@Nullable String jsonString) {
this.endpointId = endpointId;
this.clusterId = clusterId;
this.commandId = commandId;
if (tlv.isPresent()) {
this.tlv = Optional.of(tlv.get().clone());
} else {
this.tlv = Optional.empty();

if (tlv != null)
{
this.tlv = tlv.clone();
}
else
{
this.tlv = null;
}


JSONObject jsonObject = null;
if (jsonString.isPresent()) {
if (jsonString != null) {
try {
jsonObject = new JSONObject(jsonString.get());
jsonObject = new JSONObject(jsonString);
} catch (JSONException ex) {
logger.log(Level.SEVERE, "Error parsing JSON string", ex);
}
}

this.json = Optional.ofNullable(jsonObject);
;
this.json = jsonObject;
}

public ChipPathId getEndpointId() {
Expand All @@ -72,20 +76,16 @@ public ChipPathId getCommandId() {
return commandId;
}

public boolean hasTlv() {
return tlv.isPresent();
}

public boolean hasJson() {
return json.isPresent();
}

public byte[] getTlvByteArray() {
return tlv.get().clone();
@Nullable public byte[] getTlvByteArray() {
if (tlv != null)
{
return tlv.clone();
}
return null;
}

public JSONObject getJson() {
return json.get();
@Nullable public JSONObject getJson() {
return json;
}

// check whether the current InvokeElement has same path as others.
Expand Down Expand Up @@ -115,10 +115,10 @@ public static InvokeElement newInstance(
ChipPathId endpointId,
ChipPathId clusterId,
ChipPathId commandId,
byte[] tlv,
String jsonString) {
@Nullable byte[] tlv,
@Nullable String jsonString) {
return new InvokeElement(
endpointId, clusterId, commandId, Optional.of(tlv), Optional.of(jsonString));
endpointId, clusterId, commandId, tlv, jsonString);
}

/** Create a new {@link InvokeElement} with only concrete ids. */
Expand All @@ -128,55 +128,7 @@ public static InvokeElement newInstance(
ChipPathId.forId(endpointId),
ChipPathId.forId(clusterId),
ChipPathId.forId(commandId),
Optional.of(tlv),
Optional.of(jsonString));
}

public static InvokeElement newInstance(
ChipPathId endpointId, ChipPathId clusterId, ChipPathId commandId, byte[] tlv) {
return new InvokeElement(endpointId, clusterId, commandId, Optional.of(tlv), Optional.empty());
}

/** Create a new {@link InvokeElement} with only concrete ids. */
public static InvokeElement newInstance(
long endpointId, long clusterId, long commandId, byte[] tlv) {
return new InvokeElement(
ChipPathId.forId(endpointId),
ChipPathId.forId(clusterId),
ChipPathId.forId(commandId),
Optional.of(tlv),
Optional.empty());
}

public static InvokeElement newInstance(
ChipPathId endpointId, ChipPathId clusterId, ChipPathId commandId, String jsonString) {
return new InvokeElement(
endpointId, clusterId, commandId, Optional.empty(), Optional.of(jsonString));
}

/** Create a new {@link InvokeElement} with only concrete ids. */
public static InvokeElement newInstance(
long endpointId, long clusterId, long commandId, String jsonString) {
return new InvokeElement(
ChipPathId.forId(endpointId),
ChipPathId.forId(clusterId),
ChipPathId.forId(commandId),
Optional.empty(),
Optional.of(jsonString));
}

public static InvokeElement newInstance(
ChipPathId endpointId, ChipPathId clusterId, ChipPathId commandId) {
return new InvokeElement(endpointId, clusterId, commandId, Optional.empty(), Optional.empty());
}

/** Create a new {@link InvokeElement} with only concrete ids. */
public static InvokeElement newInstance(long endpointId, long clusterId, long commandId) {
return new InvokeElement(
ChipPathId.forId(endpointId),
ChipPathId.forId(clusterId),
ChipPathId.forId(commandId),
Optional.empty(),
Optional.empty());
tlv,
jsonString);
}
}

0 comments on commit a63953c

Please sign in to comment.