Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a command to fetch the user properties list #575

Open
vkurkchi opened this issue Nov 10, 2023 · 2 comments
Open

Add a command to fetch the user properties list #575

vkurkchi opened this issue Nov 10, 2023 · 2 comments

Comments

@vkurkchi
Copy link

vkurkchi commented Nov 10, 2023

The current implementation lacks the functionality to retrieve the list of supported user properties.
My suggestion is to add 2 new structures GenericUserPropertiesGet and GenericUserPropertiesStatus, described in Mesh Models documentation, sections 3.2.8.1 and 3.2.8.2 respectively.

The implementation could look something like this:

public class GenericUserPropertiesGet extends ApplicationMessage {

    private static final String TAG = GenericUserPropertiesGet.class.getSimpleName();
    private static final int OP_CODE = ApplicationMessageOpCodes.GENERIC_USER_PROPERTIES_GET;


    /**
     * Constructs GenericLevelGet message.
     *
     * @param appKey {@link ApplicationKey} key for this message
     * @throws IllegalArgumentException if any illegal arguments are passed
     */
    public GenericUserPropertiesGet(@NonNull final ApplicationKey appKey) throws IllegalArgumentException {
        super(appKey);
        assembleMessageParameters();
    }

    @Override
    public int getOpCode() {
        return OP_CODE;
    }

    @Override
    void assembleMessageParameters() {
        mAid = SecureUtils.calculateK4(mAppKey.getKey());
    }
}

and

public class GenericUserPropertiesStatus extends ApplicationStatusMessage  implements Parcelable {

    private final int opCode;
    private ArrayList<Short> propertyIds;

    private static final Creator<GenericUserPropertiesStatus> CREATOR = new Creator<GenericUserPropertiesStatus>() {
        @Override
        public GenericUserPropertiesStatus createFromParcel(Parcel in) {
            final AccessMessage message = in.readParcelable(AccessMessage.class.getClassLoader());
            //noinspection ConstantConditions
            return new GenericUserPropertiesStatus(message);
        }

        @Override
        public GenericUserPropertiesStatus[] newArray(int size) {
            return new GenericUserPropertiesStatus[size];
        }
    };

    public GenericUserPropertiesStatus(@NonNull final AccessMessage message) {
        super(message);
        this.opCode = message.getOpCode();
        this.mMessage = message;
        this.mParameters = message.getParameters();
        parseStatusParameters();
    }

    @Override
    void parseStatusParameters() {
        BitReader bitReader = new BitReader(mParameters);
        propertyIds = new ArrayList<Short>(mParameters.length / 2);
        for(int i = 0; i < mParameters.length; i += 2) {
            int firstPropertyByte = bitReader.getBits(8);
            int secondPropertyByte = bitReader.getBits(8);

            propertyIds.add((short) (secondPropertyByte << 8 | firstPropertyByte));
        }
    }

    @Override
    public int getOpCode() {
        return opCode;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        final AccessMessage message = (AccessMessage) mMessage;
        dest.writeParcelable(message, flags);
    }

    public ArrayList<Short> getPropertyIds() {
        return propertyIds;
    }
}
@vkurkchi
Copy link
Author

Also, a slight change needs to be made in DefaultNoOperationMessageState, we need to handle a new single byte opCode inside of parseAccessMessage method

 else if (message.getOpCode() == ApplicationMessageOpCodes.GENERIC_USER_PROPERTIES_STATUS) {
                    final GenericUserPropertiesStatus propertiesStatus = new GenericUserPropertiesStatus(message);
                    mInternalTransportCallbacks.updateMeshNetwork(propertiesStatus);
                    mMeshStatusCallbacks.onMeshMessageReceived(message.getSrc(), propertiesStatus);
                }

If you are ok with the suggestion, I can proceed with a PR creation.

@roshanrajaratnam
Copy link
Member

Please send a PR so we can discuss it. Seems fine!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants