/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "NdefRecord" #include #include "jni.h" #include "JNIHelp.h" #include "android_nfc.h" #include namespace android { static jbyteArray android_nfc_NdefRecord_generate( JNIEnv *e, jobject o, jshort flags, jshort tnf, jbyteArray type, jbyteArray id, jbyteArray payload) { uint32_t status; phFriNfc_NdefRecord_t record; uint32_t buf_size; uint32_t record_size; uint8_t *buf = NULL; jbyteArray result = NULL; /* Prepare NDEF record structure */ record.Flags = (uint8_t)flags; record.Tnf = (uint8_t)tnf; record.TypeLength = (uint32_t)e->GetArrayLength(type); record.Type = (uint8_t *)e->GetByteArrayElements(type, NULL); record.IdLength = (uint32_t)e->GetArrayLength(id); record.Id = (uint8_t *)e->GetByteArrayElements(id, NULL); record.PayloadLength = (uint32_t)e->GetArrayLength(payload); record.PayloadData = (uint8_t *)e->GetByteArrayElements(payload, NULL); buf_size = record.PayloadLength + record.IdLength + record.TypeLength + 8; buf = (uint8_t*)malloc(buf_size); if (buf == NULL) goto end; TRACE("phFriNfc_NdefRecord_Generate()"); status = phFriNfc_NdefRecord_Generate(&record, buf, buf_size, &record_size); if (status) { LOGE("phFriNfc_NdefRecord_Generate() returned 0x%04x", status); goto end; } TRACE("phFriNfc_NdefRecord_Generate() returned 0x%04x", status); result = e->NewByteArray(record_size); if (result == NULL) goto end; e->SetByteArrayRegion(result, 0, record_size, (jbyte *)buf); end: e->ReleaseByteArrayElements(type, (jbyte *)record.Type, JNI_ABORT); e->ReleaseByteArrayElements(id, (jbyte *)record.Id, JNI_ABORT); e->ReleaseByteArrayElements(payload, (jbyte *)record.PayloadData, JNI_ABORT); if(buf) free(buf); return result; } static jint android_nfc_NdefRecord_parseNdefRecord(JNIEnv *e, jobject o, jbyteArray array) { uint16_t status; jbyte *raw_record; jsize raw_record_size; jint ret = -1; phFriNfc_NdefRecord_t record; jfieldID mType, mId, mPayload, mTnf, mFlags; jbyteArray type = NULL; jbyteArray id = NULL; jbyteArray payload = NULL; jclass record_cls = e->GetObjectClass(o); raw_record_size = e->GetArrayLength(array); raw_record = e->GetByteArrayElements(array, NULL); if (raw_record == NULL) { goto clean_and_return; } TRACE("phFriNfc_NdefRecord_Parse()"); status = phFriNfc_NdefRecord_Parse(&record, (uint8_t *)raw_record); if (status) { LOGE("phFriNfc_NdefRecord_Parse() returned 0x%04x", status); goto clean_and_return; } TRACE("phFriNfc_NdefRecord_Parse() returned 0x%04x", status); /* Set TNF field */ mTnf = e->GetFieldID(record_cls, "mTnf", "S"); e->SetShortField(o, mTnf, record.Tnf); /* Set type field */ mType = e->GetFieldID(record_cls, "mType", "[B"); type = e->NewByteArray(record.TypeLength); if (type == NULL) { goto clean_and_return; } e->SetByteArrayRegion(type, 0, record.TypeLength, (jbyte *)record.Type); e->SetObjectField(o, mType, type); /* Set id field */ mId = e->GetFieldID(record_cls, "mId", "[B"); id = e->NewByteArray(record.IdLength); if (id == NULL) { goto clean_and_return; } e->SetByteArrayRegion(id, 0, record.IdLength, (jbyte *)record.Id); e->SetObjectField(o, mId, id); /* Set payload field */ mPayload = e->GetFieldID(record_cls, "mPayload", "[B"); payload = e->NewByteArray(record.PayloadLength); if (payload == NULL) { goto clean_and_return; } e->SetByteArrayRegion(payload, 0, record.PayloadLength, (jbyte *)record.PayloadData); e->SetObjectField(o, mPayload, payload); /* Set flags field */ mFlags = e->GetFieldID(record_cls, "mFlags", "B"); e->SetByteField(o, mFlags, record.Flags); ret = 0; clean_and_return: if (type != NULL) { e->DeleteLocalRef(type); } if (id != NULL) { e->DeleteLocalRef(id); } if (payload != NULL) { e->DeleteLocalRef(payload); } if (raw_record != NULL) { e->ReleaseByteArrayElements(array, raw_record, JNI_ABORT); } return ret; } static JNINativeMethod gMethods[] = { {"generate", "(SS[B[B[B)[B", (void *)android_nfc_NdefRecord_generate}, {"parseNdefRecord", "([B)I", (void *)android_nfc_NdefRecord_parseNdefRecord}, }; int register_android_nfc_NdefRecord(JNIEnv *e) { return jniRegisterNativeMethods(e, "android/nfc/NdefRecord", gMethods, NELEM(gMethods)); } } // namespace android