blob: eaf989d2f2e11f43212d6261daf21d97aea84398 [file] [log] [blame]
Nick Pellybc21fde2010-10-13 17:25:24 -07001/*
2 * Copyright (C) 2010 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#define LOG_TAG "NdefMessage"
18
Nick Pelly1af97f02010-10-22 06:59:54 -070019#include <stdlib.h>
20
Nick Pellybc21fde2010-10-13 17:25:24 -070021#include "jni.h"
22#include "JNIHelp.h"
23
24#include "android_nfc.h"
25
26#include <utils/Log.h>
27
28namespace android {
29
30static jint android_nfc_NdefMessage_parseNdefMessage(JNIEnv *e, jobject o,
31 jbyteArray array)
32{
33 uint16_t status;
34 uint32_t i;
35 jbyte *raw_msg;
36 jsize raw_msg_size;
37 uint32_t num_of_records = 0;
38 uint8_t **records = NULL;
39 uint8_t *is_chunked = NULL;
40 jint ret = -1;
41 phFriNfc_NdefRecord_t record;
42
43 jclass record_cls;
44 jobjectArray records_array;
45 jmethodID ctor;
46
47 jclass msg_cls;
48 jfieldID mrecords;
49
50 raw_msg_size = e->GetArrayLength(array);
51 raw_msg = e->GetByteArrayElements(array, NULL);
52 if (raw_msg == NULL)
53 return -1;
54
55 /* Get the number of records in the message so we can allocate buffers */
56 LOGD("phFriNfc_NdefRecord_GetRecords(NULL)");
57
58 status = phFriNfc_NdefRecord_GetRecords((uint8_t *)raw_msg,
59 (uint32_t)raw_msg_size, NULL, NULL, &num_of_records);
60
61 if (status) {
62 LOGE("phFriNfc_NdefRecord_GetRecords(NULL) returned 0x%04x", status);
63 goto end;
64 }
65 LOGD("phFriNfc_NdefRecord_GetRecords(NULL) returned 0x%04x", status);
66
67 LOGD("found %d records in message", num_of_records);
68
69 is_chunked = (uint8_t*)malloc(num_of_records);
70 if (is_chunked == NULL)
71 goto end;
72 records = (uint8_t**)malloc(num_of_records * sizeof(uint8_t *));
73 if (records == NULL)
74 goto end;
75
76 /* Now, actually retrieve records position in message */
77 LOGD("phFriNfc_NdefRecord_GetRecords()");
78
79 status = phFriNfc_NdefRecord_GetRecords((uint8_t *)raw_msg,
80 (uint32_t)raw_msg_size, records, is_chunked, &num_of_records);
81
82 if (status) {
83 LOGE("phFriNfc_NdefRecord_GetRecords() returned 0x%04x", status);
84 goto end;
85 }
86 LOGD("phFriNfc_NdefRecord_GetRecords() returned 0x%04x", status);
87
88 /* Build NDEF records array */
89 record_cls = e->FindClass("android/nfc/NdefRecord");
90 records_array = e->NewObjectArray((jsize)num_of_records, record_cls,
91 NULL);
92 if (records_array == NULL)
93 goto end;
94
95 ctor = e->GetMethodID(record_cls, "<init>", "(S[B[B[B)V");
96
97 LOGD("NFC_Number of records = %d\n", num_of_records);
98
99 for (i = 0; i < num_of_records; i++) {
100 jbyteArray type, id, payload;
101 jobject new_record;
102
103 LOGD("phFriNfc_NdefRecord_Parse()");
104
105 status = phFriNfc_NdefRecord_Parse(&record, records[i]);
106
107 if (status) {
108 LOGE("phFriNfc_NdefRecord_Parse() returned 0x%04x", status);
109 goto end;
110 }
111 LOGD("phFriNfc_NdefRecord_Parse() returned 0x%04x", status);
112
113 type = e->NewByteArray(record.TypeLength);
114 if (type == NULL) {
115 LOGD("NFC_Set Record Type Error\n");
116 goto end;
117 }
118
119 id = e->NewByteArray(record.IdLength);
120 if(id == NULL) {
121 LOGD("NFC_Set Record ID Error\n");
122 goto end;
123 }
124
125 payload = e->NewByteArray(record.PayloadLength);
126 if(payload == NULL) {
127 LOGD("NFC_Set Record Payload Error\n");
128 goto end;
129 }
130
131 e->SetByteArrayRegion(type, 0, record.TypeLength,
132 (jbyte *)record.Type);
133 e->SetByteArrayRegion(id, 0, record.IdLength,
134 (jbyte *)record.Id);
135 e->SetByteArrayRegion(payload, 0, record.PayloadLength,
136 (jbyte *)record.PayloadData);
137
138 new_record = e->NewObject(record_cls, ctor,
139 (jshort)record.Tnf, type, id, payload);
140
141 e->SetObjectArrayElement(records_array, i, new_record);
142
143 /* Try not to clutter the Java stack too much */
144 e->DeleteLocalRef(new_record);
145 e->DeleteLocalRef(type);
146 e->DeleteLocalRef(id);
147 e->DeleteLocalRef(payload);
148 }
149
150 /* Store built array in our NDEFMessage instance */
151 msg_cls = e->GetObjectClass(o);
152 mrecords = e->GetFieldID(msg_cls, "mRecords", "[Landroid/nfc/NdefRecord;");
153
154 e->SetObjectField(o, mrecords, (jobject)records_array);
155
156 ret = 0;
157
158end:
159 if(is_chunked)
160 free(is_chunked);
161 if(records)
162 free(records);
163 e->ReleaseByteArrayElements(array, raw_msg, JNI_ABORT);
164
165 return ret;
166}
167
168static JNINativeMethod gMethods[] = {
169 {"parseNdefMessage", "([B)I", (void *)android_nfc_NdefMessage_parseNdefMessage},
170};
171
172int register_android_nfc_NdefMessage(JNIEnv *e)
173{
174 return jniRegisterNativeMethods(e, "android/nfc/NdefMessage", gMethods, NELEM(gMethods));
175}
176
177} // namespace android