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