| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883 |
- /*
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #ifdef ENABLE_JEFF
- #include "module_jeff.h"
- #include "jeff_export.h"
- #include "../vmcore_jeff/jeff-runtime.h"
- #include "../vmcore_jeff/jeff-thread.h"
- #include "../vmcore_jeff/jeff-buffer.h"
- #include "../vmcore_jeff/jeff-tool.h"
- #include "../vmcore_jeff/jeff-tool-priv.h"
- #include "app_manager-host.h"
- #include "bh_queue.h"
- #include "attr-container.h"
- #include "attr-container-util.h"
- #include "bh_thread.h"
- #include "ems_gc.h"
- #include "coap_ext.h"
- #include "libcore.h"
- #include "event.h"
- #include "watchdog.h"
- #define DEFAULT_APPLET_TIMEOUT (3 * 60 * 1000)
- #define DEFAULT_APPLET_HEAP_SIZE (48 * 1024)
- #define MIN_APPLET_HEAP_SIZE (2 * 1024)
- #define MAX_APPLET_HEAP_SIZE (1024 * 1024)
- typedef struct jeff_applet_data {
- /* Java Applet Object */
- JeffObjectRef applet_obj;
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- /* Whether the applet is in debug mode */
- bool debug_mode;
- /* Queue of the tool agent */
- bh_queue *tool_agent_queue;
- #endif
- /* VM instance */
- JeffInstanceLocalRoot *vm_instance;
- /* Applet Main file */
- JeffFileHeaderLinked *main_file;
- /* Permissions of the Java Applet */
- char *perms;
- } jeff_applet_data;
- /* Jeff class com.intel.aee.AEEApplet */
- static JeffClassHeaderLinked *class_AEEApplet;
- /* Jeff class com.intel.aee.Request */
- static JeffClassHeaderLinked *class_AEERequest;
- /* Jeff class com.intel.aee.Timer */
- static JeffClassHeaderLinked *class_Timer;
- /* Jeff class com.intel.aee.Sensor */
- static JeffClassHeaderLinked *class_Sensor;
- /* Jeff class com.intel.aee.ble.BLEManager */
- static JeffClassHeaderLinked *class_BLEManager;
- /* Jeff class com.intel.aee.ble.BLEDevice */
- static JeffClassHeaderLinked *class_BLEDevice;
- /* Jeff class com.intel.aee.ble.BLEGattService */
- JeffClassHeaderLinked *class_BLEGattService;
- /* Jeff class com.intel.aee.ble.BLEGattCharacteristic */
- JeffClassHeaderLinked *class_BLEGattCharacteristic;
- /* Jeff class com.intel.aee.ble.BLEGattDescriptor */
- JeffClassHeaderLinked *class_BLEGattDescriptor;
- /* Jeff class com.intel.aee.gpio.GPIOChannel */
- static JeffClassHeaderLinked *class_GPIOChannel;
- /* Jeff method void com.intel.aee.AEEApplet.onInit() */
- static JeffMethodLinked *method_AEEApplet_onInit;
- /* Jeff method void com.intel.aee.AEEApplet.onDestroy() */
- static JeffMethodLinked *method_AEEApplet_onDestroy;
- /* Jeff method void com.intel.aee.AEEApplet.callOnRequest(Request request) */
- static JeffMethodLinked *method_AEEApplet_callOnRequest;
- /* Jeff method void com.intel.aee.Timer.callOnTimer() */
- static JeffMethodLinked *method_callOnTimer;
- /* Jeff method void com.intel.aee.Sensor.callOnSensorEvent() */
- static JeffMethodLinked *method_callOnSensorEvent;
- /* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEStartDiscovery() */
- static JeffMethodLinked *method_callOnBLEStartDiscovery;
- /* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEConnected() */
- static JeffMethodLinked *method_callOnBLEConnected;
- /* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEDisonnected() */
- static JeffMethodLinked *method_callOnBLEDisconnected;
- /* Jeff method void com.intel.aee.ble.BLEManager.callOnBLENotification() */
- static JeffMethodLinked *method_callOnBLENotification;
- /* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEIndication() */
- static JeffMethodLinked *method_callOnBLEIndication;
- /* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEPasskeyEntry() */
- static JeffMethodLinked *method_callOnBLEPasskeyEntry;
- /* Jeff method void com.intel.aee.gpio.GPIOChannel.callOnGPIOInterrupt() */
- static JeffMethodLinked *method_callOnGPIOInterrupt;
- /* Jeff method void com.intel.aee.ble.BLEManager.getBLEDevice() */
- static JeffMethodLinked *method_callOnBLEManagerGetBLEDevice;
- static jeff_applet_data *
- app_manager_get_jeff_applet_data()
- {
- module_data *m_data = app_manager_get_module_data(Module_Jeff);
- return (jeff_applet_data *)m_data->internal_data;
- }
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- void *
- app_manager_get_tool_agent_queue()
- {
- return app_manager_get_jeff_applet_data()->tool_agent_queue;
- }
- #endif
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- static bool
- is_tool_agent_running(module_data *m_data)
- {
- jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
- return (applet_data->debug_mode && applet_data->tool_agent_queue
- && applet_data->vm_instance->tool_agent);
- }
- #endif
- static char *
- get_class_qname(const JeffString *pname, const JeffString *cname)
- {
- unsigned int length =
- pname->length ? pname->length + 2 + cname->length : cname->length + 1;
- char *buf = APP_MGR_MALLOC(length), *p;
- if (!buf)
- return NULL;
- p = buf;
- if (pname->length) {
- bh_memcpy_s(p, pname->length, pname->value, pname->length);
- p += pname->length;
- *p++ = '.';
- }
- bh_memcpy_s(p, cname->length, cname->value, cname->length);
- p += cname->length;
- *p = '\0';
- return buf;
- }
- static void
- send_exception_event_to_host(const char *applet_name, const char *exc_name)
- {
- attr_container_t *payload;
- bh_request_msg_t msg;
- char *url;
- int url_len;
- payload = attr_container_create("exception detail");
- if (!payload) {
- app_manager_printf("Send exception to host fail: allocate memory");
- return;
- }
- if (!attr_container_set_string(&payload, "exception name", exc_name)
- || !attr_container_set_string(&payload, "stack trace", "TODO")
- || !attr_container_set_string(&payload, "applet name", applet_name)) {
- app_manager_printf("Send exception to host fail: set attr");
- goto fail;
- }
- url_len = strlen("/exception/") + strlen(applet_name);
- url = APP_MGR_MALLOC(url_len + 1);
- if (!url) {
- app_manager_printf("Send exception to host fail: allocate memory");
- goto fail;
- }
- memset(url, 0, url_len + 1);
- bh_strcpy_s(url, url_len + 1, "/exception/");
- bh_strcat_s(url, url_len + 1, applet_name);
- memset(&msg, 0, sizeof(msg));
- msg.url = url;
- msg.action = COAP_PUT;
- msg.payload = (char *)payload;
- app_send_request_msg_to_host(&msg);
- APP_MGR_FREE(url);
- fail:
- attr_container_destroy(payload);
- }
- static bool
- check_exception()
- {
- if (jeff_runtime_get_exception()) {
- jeff_printf("V1.Exception thrown when running applet '%s':\n",
- app_manager_get_module_name(Module_Jeff));
- jeff_runtime_print_exception();
- jeff_printf("\n");
- jeff_printf(NULL);
- }
- if (!app_manager_is_interrupting_module(Module_Jeff)) {
- attr_container_t *payload;
- int payload_len;
- JeffClassHeaderLinked *exc_class =
- jeff_object_class_pointer(jeff_runtime_get_exception());
- char *qname_buf = get_class_qname(jeff_get_class_pname(exc_class),
- jeff_get_class_cname(exc_class));
- /* Send exception event to host */
- if (qname_buf) {
- send_exception_event_to_host(
- app_manager_get_module_name(Module_Jeff), qname_buf);
- APP_MGR_FREE(qname_buf);
- }
- /* Uninstall the applet */
- if ((payload = attr_container_create("uninstall myself"))) {
- if (attr_container_set_string(
- &payload, "name", app_manager_get_module_name(Module_Jeff))
- /* Set special flag to prevent app manager making response
- since this is an internal message */
- && attr_container_set_bool(&payload, "do not reply me", true)) {
- request_t request = { 0 };
- payload_len = attr_container_get_serialize_length(payload);
- init_request(request, "/applet", COAP_DELETE, (char *)payload, payload_len));
- app_mgr_lookup_resource(&request);
- // TODO: confirm this is right
- attr_container_destroy(payload);
- }
- }
- jeff_runtime_set_exception(NULL);
- return true;
- }
- return false;
- }
- static bool
- app_manager_initialize_class(JeffClassHeaderLinked *c)
- {
- jeff_runtime_initialize_class(c);
- return !check_exception();
- }
- static bool
- app_manager_initialize_object(JeffObjectRef obj)
- {
- jeff_runtime_initialize_object(obj);
- return !check_exception();
- }
- static bool
- app_manager_call_java(JeffMethodLinked *method, unsigned int argc,
- uint32 argv[], uint8 argt[])
- {
- module_data *m_data = app_manager_get_module_data(Module_Jeff);
- watchdog_timer *wd_timer = &m_data->wd_timer;
- bool is_wd_started = false;
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- /* Only start watchdog when debugger is not running */
- if (!is_tool_agent_running(m_data)) {
- #endif
- watchdog_timer_start(wd_timer);
- is_wd_started = true;
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- }
- #endif
- jeff_runtime_call_java(method, argc, argv, argt);
- if (is_wd_started) {
- os_mutex_lock(&wd_timer->lock);
- if (!wd_timer->is_interrupting) {
- wd_timer->is_stopped = true;
- watchdog_timer_stop(wd_timer);
- }
- os_mutex_unlock(&wd_timer->lock);
- }
- return !check_exception();
- }
- static AEEBLEDevice
- create_object_BLEDevice(ble_device_info *dev_info)
- {
- JeffLocalObjectRef ref;
- AEEBLEDevice dev_struct;
- jeff_runtime_push_local_object_ref(&ref);
- ref.val = jeff_runtime_new_object(class_BLEDevice);
- if (!ref.val) {
- jeff_runtime_pop_local_object_ref(1);
- return NULL;
- }
- dev_struct = (AEEBLEDevice)(ref.val);
- dev_struct->rssi = dev_info->rssi;
- dev_struct->mac =
- (jbyteArray)jeff_runtime_create_byte_array((int8 *)dev_info->mac, 6);
- app_manager_printf("adv_data_len:%d,scan_response_len:%d\n",
- dev_info->adv_data_len, dev_info->scan_response_len);
- dev_struct->advData = (jbyteArray)jeff_runtime_create_byte_array(
- (int8 *)dev_info->adv_data, dev_info->adv_data_len);
- dev_struct->scanResponse = (jbyteArray)jeff_runtime_create_byte_array(
- (int8 *)dev_info->scan_response, dev_info->scan_response_len);
- dev_struct->addressType = dev_info->address_type;
- jeff_runtime_initialize_object(ref.val);
- jeff_runtime_pop_local_object_ref(1);
- if ((dev_struct->mac == NULL) || (dev_struct->advData == NULL)
- || (dev_struct->scanResponse == NULL)) {
- return NULL;
- }
- return (AEEBLEDevice)ref.val;
- }
- static void
- app_instance_process_ble_msg(char *msg)
- {
- bh_queue_ble_sub_msg_t *ble_msg = (bh_queue_ble_sub_msg_t *)msg;
- unsigned int argv[5];
- uint8 argt[5];
- ble_device_info *dev_info;
- dev_info = (ble_device_info *)ble_msg->payload;
- AEEBLEDevice ble_dev;
- argv[0] = (unsigned int)(jbyteArray)jeff_runtime_create_byte_array(
- (int8 *)dev_info->mac, 6);
- argt[0] = 1;
- if (!app_manager_call_java(method_callOnBLEManagerGetBLEDevice, 1, argv,
- argt)) {
- app_manager_printf(
- "app_manager_call_java BLEManagerGetBLEDevice fail error\n");
- goto fail;
- }
- ble_dev = (AEEBLEDevice)argv[0];
- if (ble_dev == NULL) {
- ble_dev = create_object_BLEDevice(dev_info);
- if (ble_dev == NULL) {
- goto fail;
- }
- }
- switch (ble_msg->type) {
- case BLE_SUB_EVENT_DISCOVERY:
- {
- argv[0] = (unsigned int)ble_dev;
- argt[0] = 1;
- ble_dev->rssi = dev_info->rssi;
- if (!app_manager_call_java(method_callOnBLEStartDiscovery, 1, argv,
- argt)) {
- app_manager_printf(
- "app_manager_call_java method_callOnBLEStartDiscovery "
- "fail error\n");
- goto fail;
- }
- break;
- }
- case BLE_SUB_EVENT_CONNECTED:
- {
- if (ble_dev) {
- argv[0] = (unsigned int)ble_dev;
- argv[1] = 0;
- argt[0] = 1;
- argt[1] = 1;
- if (!app_manager_call_java(method_callOnBLEConnected, 2, argv,
- argt)) {
- app_manager_printf(
- "app_manager_call_java method_callOnBLEConnected "
- "fail error\n");
- goto fail;
- }
- }
- break;
- }
- case BLE_SUB_EVENT_DISCONNECTED:
- {
- app_manager_printf("app instance received disconnected\n");
- if (ble_dev) {
- argv[0] = (unsigned int)ble_dev;
- argv[1] = 0;
- argt[0] = 1;
- argt[1] = 1;
- ble_dev->rssi = dev_info->rssi;
- if (!app_manager_call_java(method_callOnBLEDisconnected, 2,
- argv, argt)) {
- app_manager_printf(
- "app_manager_call_java "
- "method_callOnBLEDisconnected fail error\n");
- goto fail;
- }
- }
- break;
- }
- case BLE_SUB_EVENT_NOTIFICATION:
- {
- if (ble_dev) {
- argv[0] = (unsigned int)ble_dev;
- argv[1] =
- (unsigned int)(jbyteArray)jeff_runtime_create_byte_array(
- (int8 *)dev_info->private_data,
- dev_info->private_data_length);
- argv[2] = dev_info->value_handle;
- argv[3] = dev_info->ccc_handle;
- argt[1] = 1;
- argt[2] = 0;
- argt[3] = 0;
- ble_dev->rssi = dev_info->rssi;
- if (!app_manager_call_java(method_callOnBLENotification, 4,
- argv, argt)) {
- app_manager_printf(
- "app_manager_call_java "
- "method_callOnBLENotification fail error\n");
- goto fail;
- }
- }
- break;
- }
- case BLE_SUB_EVENT_INDICATION:
- {
- if (ble_dev) {
- argv[0] = (unsigned int)ble_dev;
- argv[1] =
- (unsigned int)(jbyteArray)jeff_runtime_create_byte_array(
- (int8 *)dev_info->private_data,
- dev_info->private_data_length);
- argv[2] = dev_info->value_handle;
- argv[3] = dev_info->ccc_handle;
- argt[0] = 1;
- argt[1] = 1;
- argt[2] = 0;
- argt[3] = 0;
- ble_dev->rssi = dev_info->rssi;
- if (!app_manager_call_java(method_callOnBLEIndication, 4, argv,
- argt)) {
- app_manager_printf(
- "app_manager_call_java method_callOnBLEIndication "
- "fail error\n");
- goto fail;
- }
- }
- break;
- }
- case BLE_SUB_EVENT_PASSKEYENTRY:
- {
- if (ble_dev) {
- argv[0] = (unsigned int)ble_dev;
- argt[0] = 1;
- argt[1] = 1;
- ble_dev->rssi = dev_info->rssi;
- if (!app_manager_call_java(method_callOnBLEPasskeyEntry, 1,
- argv, argt)) {
- app_manager_printf(
- "app_manager_call_java "
- "method_callOnBLEPasskeyEntry fail error\n");
- goto fail;
- }
- }
- break;
- }
- case BLE_SUB_EVENT_SECURITY_LEVEL_CHANGE:
- {
- if (ble_dev) {
- ble_dev->securityLevel = dev_info->security_level;
- }
- break;
- }
- default:
- break;
- }
- fail:
- if (dev_info->scan_response != NULL) {
- APP_MGR_FREE(dev_info->scan_response);
- }
- if (dev_info->private_data != NULL) {
- APP_MGR_FREE(dev_info->private_data);
- }
- if (dev_info->adv_data != NULL) {
- APP_MGR_FREE(dev_info->adv_data);
- }
- if (dev_info != NULL) {
- APP_MGR_FREE(dev_info);
- }
- }
- static void
- app_instance_free_ble_msg(char *msg)
- {
- bh_queue_ble_sub_msg_t *ble_msg = (bh_queue_ble_sub_msg_t *)msg;
- ble_device_info *dev_info;
- dev_info = (ble_device_info *)ble_msg->payload;
- if (dev_info->scan_response != NULL)
- APP_MGR_FREE(dev_info->scan_response);
- if (dev_info->private_data != NULL)
- APP_MGR_FREE(dev_info->private_data);
- if (dev_info->adv_data != NULL)
- APP_MGR_FREE(dev_info->adv_data);
- if (dev_info != NULL)
- APP_MGR_FREE(dev_info);
- }
- static void
- app_instance_queue_free_callback(void *queue_msg)
- {
- bh_queue_msg_t *msg = (bh_queue_msg_t *)queue_msg;
- switch (msg->message_type) {
- case APPLET_REQUEST:
- {
- bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
- APP_MGR_FREE(req_msg);
- break;
- }
- case TIMER_EVENT:
- {
- break;
- }
- case SENSOR_EVENT:
- {
- if (msg->payload) {
- bh_sensor_event_t *sensor_event =
- (bh_sensor_event_t *)msg->payload;
- attr_container_t *event = sensor_event->event;
- attr_container_destroy(event);
- APP_MGR_FREE(sensor_event);
- }
- break;
- }
- case BLE_EVENT:
- {
- if (msg->payload) {
- app_instance_free_ble_msg(msg->payload);
- APP_MGR_FREE(msg->payload);
- }
- break;
- }
- case GPIO_INTERRUPT_EVENT:
- {
- break;
- }
- default:
- {
- break;
- }
- }
- APP_MGR_FREE(msg);
- }
- static void
- app_instance_queue_callback(void *queue_msg)
- {
- bh_queue_msg_t *msg = (bh_queue_msg_t *)queue_msg;
- unsigned int argv[5];
- uint8 argt[5];
- if (app_manager_is_interrupting_module(Module_Jeff)) {
- app_instance_queue_free_callback(queue_msg);
- return;
- }
- switch (msg->message_type) {
- case APPLET_REQUEST:
- {
- JeffLocalObjectRef ref;
- AEERequest req_obj;
- bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
- attr_container_t *attr_cont = (attr_container_t *)req_msg->payload;
- module_data *m_data = app_manager_get_module_data(Module_Jeff);
- jeff_applet_data *applet_data =
- (jeff_applet_data *)m_data->internal_data;
- app_manager_printf("Applet %s got request, url %s, action %d\n",
- m_data->module_name, req_msg->url,
- req_msg->action);
- /* Create Request object */
- req_obj =
- (AEERequest)jeff_object_new(m_data->heap, class_AEERequest);
- if (!req_obj) {
- app_manager_printf("Applet process request failed: create "
- "request obj failed.\n");
- goto fail1;
- }
- jeff_runtime_push_local_object_ref(&ref);
- ref.val = (JeffObjectRef)req_obj;
- req_obj->mid = req_msg->mid;
- req_obj->action = req_msg->action;
- req_obj->fmt = req_msg->fmt;
- /* Create Java url string */
- if (req_msg->url) {
- req_obj->url =
- (jstring)jeff_runtime_create_java_string(req_msg->url);
- if (!req_obj->url) {
- app_manager_printf("Applet process request failed: "
- "create url string failed.\n");
- goto fail2;
- }
- }
- /* Create Java AttributeObject payload */
- if (attr_cont
- && !attr_container_to_attr_obj(attr_cont, &req_obj->payload)) {
- app_manager_printf("Applet process request failed: convert "
- "payload failed.\n");
- goto fail2;
- }
- /* Call AEEApplet.callOnRequest(Request request) method */
- argv[0] = (unsigned int)applet_data->applet_obj;
- argv[1] = (unsigned int)req_obj;
- argt[0] = argt[1] = 1;
- app_manager_call_java(method_AEEApplet_callOnRequest, 2, argv,
- argt);
- app_manager_printf("Applet process request success.\n");
- fail2:
- jeff_runtime_pop_local_object_ref(1);
- fail1:
- APP_MGR_FREE(req_msg);
- break;
- }
- case TIMER_EVENT:
- {
- if (msg->payload) {
- /* Call Timer.callOnTimer() method */
- argv[0] = (unsigned int)msg->payload;
- argt[0] = 1;
- app_manager_call_java(method_callOnTimer, 1, argv, argt);
- }
- break;
- }
- case SENSOR_EVENT:
- {
- if (msg->payload) {
- bh_sensor_event_t *sensor_event =
- (bh_sensor_event_t *)msg->payload;
- AEESensor sensor = sensor_event->sensor;
- attr_container_t *event = sensor_event->event;
- bool ret = attr_container_to_attr_obj(event, &sensor->event);
- attr_container_destroy(event);
- APP_MGR_FREE(sensor_event);
- if (ret) {
- /* Call Sensor.callOnSensorEvent() method */
- argv[0] = (unsigned int)sensor;
- argt[0] = 1;
- app_manager_call_java(method_callOnSensorEvent, 1, argv,
- argt);
- }
- }
- break;
- }
- case BLE_EVENT:
- {
- if (msg->payload) {
- app_instance_process_ble_msg(msg->payload);
- APP_MGR_FREE(msg->payload);
- }
- break;
- }
- case GPIO_INTERRUPT_EVENT:
- {
- AEEGPIOChannel gpio_ch = (AEEGPIOChannel)msg->payload;
- if ((gpio_ch == NULL) || (gpio_ch->callback == 0)
- || (gpio_ch->listener == NULL)) {
- break;
- }
- argv[0] = (unsigned int)gpio_ch;
- argt[0] = 1;
- bool ret_value = app_manager_call_java(method_callOnGPIOInterrupt,
- 1, argv, argt);
- if (!ret_value) {
- app_manager_printf(
- "app_manager_call_java "
- "method_method_callOnGPIOInterrupt return false\n");
- }
- break;
- }
- default:
- {
- app_manager_printf(
- "Invalid message type of applet queue message.\n");
- break;
- }
- }
- APP_MGR_FREE(msg);
- }
- static JeffClassHeaderLinked *
- find_main_class(JeffFileHeaderLinked *main_file)
- {
- JeffClassHeaderLinked *c = NULL, *ci;
- unsigned int i;
- for (i = 0; i < main_file->internal_class_count; i++) {
- ci = main_file->class_header[i];
- if (jeff_is_super_class(class_AEEApplet, ci)
- && (ci->access_flag & JEFF_ACC_PUBLIC)) {
- if (c) {
- jeff_printe_more_than_one_main_class();
- return NULL;
- }
- c = ci;
- }
- }
- if (!c)
- jeff_printe_no_main_class();
- return c;
- }
- /* Java applet thread main routine */
- static void *
- app_instance_main(void *arg)
- {
- module_data *m_data = (module_data *)arg;
- jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
- JeffClassHeaderLinked *object_class;
- JeffMethodLinked *m;
- unsigned int argv[1];
- uint8 argt[1];
- app_manager_printf("Java Applet '%s' started\n", m_data->module_name);
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- if (applet_data->debug_mode)
- jeff_tool_suspend_self();
- #endif
- applet_data->vm_instance->applet_object = applet_data->applet_obj;
- object_class = jeff_object_class_pointer(applet_data->applet_obj);
- m = jeff_select_method_virtual(object_class, method_AEEApplet_onInit);
- bh_assert(m != NULL);
- /* Initialize applet class which call <clinit> */
- if (!app_manager_initialize_class(object_class)) {
- app_manager_printf("Call <clinit> fail\n");
- goto fail;
- }
- /* Initialize applet object which call <init> */
- if (!app_manager_initialize_object(applet_data->applet_obj)) {
- app_manager_printf("Call <init> fail\n");
- goto fail;
- }
- /* Call applet's onInit() method */
- argv[0] = (unsigned int)applet_data->applet_obj;
- argt[0] = 1;
- if (app_manager_call_java(m, 1, argv, argt))
- /* Enter queue loop run to receive and process applet queue message
- */
- bh_queue_enter_loop_run(m_data->queue, app_instance_queue_callback);
- fail:
- applet_data->vm_instance->applet_object = applet_data->applet_obj;
- object_class = jeff_object_class_pointer(applet_data->applet_obj);
- m = jeff_select_method_virtual(object_class, method_AEEApplet_onDestroy);
- bh_assert(m != NULL);
- /* Call User Applet or AEEApplet onDestroy() method */
- app_manager_call_java(m, 1, argv, argt);
- if (m != method_AEEApplet_onDestroy) {
- /*If 'm' is user onDestroy, then Call AEEApplet.onDestroy() method*/
- app_manager_call_java(method_AEEApplet_onDestroy, 1, argv, argt);
- }
- app_manager_printf("Applet instance main thread exit.\n");
- return NULL;
- }
- static bool
- verify_signature(JeffFileHeader *file, unsigned size)
- {
- uint8 *sig;
- unsigned sig_size;
- #if BEIHAI_ENABLE_NO_SIGNATURE != 0
- /* no signature */
- if (file->file_signature == 0)
- return true;
- #endif
- if (file->file_length != size
- #if BEIHAI_ENABLE_NO_SIGNATURE == 0
- || file->file_signature == 0
- #endif
- || file->file_signature >= file->file_length)
- return false;
- sig = (uint8 *)file + file->file_signature;
- sig_size = file->file_length - file->file_signature;
- if (0
- == app_manager_signature_verify((uint8_t *)file, file->file_signature,
- sig, sig_size))
- return false;
- return true;
- }
- /* Install Java Applet */
- static bool
- jeff_module_install(bh_request_msg_t *msg)
- {
- unsigned int size, bpk_file_len, main_file_len, heap_size, timeout;
- uint8 *bpk_file;
- JeffFileHeaderLinked *main_file;
- JeffClassHeaderLinked *main_class;
- module_data *m_data;
- jeff_applet_data *applet_data;
- char *applet_name, *applet_perm;
- attr_container_t *attr_cont;
- bool debug = false;
- /* Check url */
- if (!msg->url || strcmp(msg->url, "/applet") != 0) {
- SEND_ERR_RESPONSE(msg->mid, "Install Applet failed: invalid url.");
- return false;
- }
- /* Check payload */
- attr_cont = (attr_container_t *)msg->payload;
- if (!attr_cont
- || !(bpk_file = (uint8 *)attr_container_get_as_bytearray(
- attr_cont, "bpk", &bpk_file_len))) {
- SEND_ERR_RESPONSE(msg->mid, "Install Applet failed: invalid bpk file.");
- return false;
- }
- /* Check applet name */
- applet_name = attr_container_get_as_string(attr_cont, "name");
- if (!applet_name || strlen(applet_name) == 0) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: invalid applet name.");
- return false;
- }
- if (app_manager_lookup_module_data(applet_name)) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: applet already installed.");
- return false;
- }
- /* TODO: convert bpk file to Jeff file */
- main_file_len = bpk_file_len;
- main_file = APP_MGR_MALLOC(main_file_len);
- if (!main_file) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: allocate memory failed.");
- return false;
- }
- bh_memcpy_s(main_file, main_file_len, bpk_file, main_file_len);
- /* Verify signature */
- if (!verify_signature((JeffFileHeader *)main_file, main_file_len)) {
- SEND_ERR_RESPONSE(
- msg->mid,
- "Install Applet failed: verify Jeff file signature failed.");
- goto fail1;
- }
- /* Load Jeff main file */
- if (!jeff_runtime_load(main_file, main_file_len, false, NULL, NULL)) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: load Jeff file failed.");
- goto fail1;
- }
- /* Find main class */
- main_class = find_main_class(main_file);
- if (!main_class) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: find applet class failed.");
- goto fail2;
- }
- /* Create module data */
- size = offsetof(module_data, module_name) + strlen(applet_name) + 1;
- size = align_uint(size, 4);
- m_data = APP_MGR_MALLOC(size + sizeof(jeff_applet_data));
- if (!m_data) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: allocate memory failed.");
- goto fail2;
- }
- memset(m_data, 0, size + sizeof(jeff_applet_data));
- m_data->module_type = Module_Jeff;
- m_data->internal_data = (uint8 *)m_data + size;
- applet_data = (jeff_applet_data *)m_data->internal_data;
- bh_strcpy_s(m_data->module_name, strlen(applet_name) + 1, applet_name);
- applet_data->main_file = main_file;
- /* Set applet execution timeout */
- timeout = DEFAULT_APPLET_TIMEOUT;
- if (attr_container_contain_key(attr_cont, "execution timeout"))
- timeout = attr_container_get_as_int(attr_cont, "execution timeout");
- m_data->timeout = timeout;
- /* Create applet permissions */
- applet_perm = attr_container_get_as_string(attr_cont, "perm");
- if (applet_perm != NULL) {
- applet_data->perms = APP_MGR_MALLOC(strlen(applet_perm) + 1);
- if (!applet_data->perms) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: allocate memory for "
- "applet permissions failed.");
- goto fail3;
- }
- bh_strcpy_s(applet_data->perms, strlen(applet_perm) + 1, applet_perm);
- }
- /* Create applet queue */
- m_data->queue = bh_queue_create();
- if (!m_data->queue) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: create applet queue failed.");
- goto fail3_1;
- }
- /* Set heap size */
- heap_size = DEFAULT_APPLET_HEAP_SIZE;
- if (attr_container_contain_key(attr_cont, "heap size")) {
- heap_size = attr_container_get_as_int(attr_cont, "heap size");
- if (heap_size < MIN_APPLET_HEAP_SIZE)
- heap_size = MIN_APPLET_HEAP_SIZE;
- else if (heap_size > MAX_APPLET_HEAP_SIZE)
- heap_size = MAX_APPLET_HEAP_SIZE;
- }
- m_data->heap_size = heap_size;
- /* Create applet heap */
- m_data->heap = gc_init_for_instance(heap_size);
- if (!m_data->heap) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: create heap failed.");
- goto fail4;
- }
- /* Create applet object */
- applet_data->applet_obj = jeff_object_new(m_data->heap, main_class);
- if (!applet_data->applet_obj) {
- SEND_ERR_RESPONSE(
- msg->mid, "Install Applet failed: create applet object failed.");
- goto fail5;
- }
- /* Initialize watchdog timer */
- if (!watchdog_timer_init(m_data)) {
- SEND_ERR_RESPONSE(
- msg->mid,
- "Install Applet failed: create applet watchdog timer failed.");
- goto fail5;
- }
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- /* Check whether applet is debuggable */
- if (attr_container_contain_key(attr_cont, "debug"))
- debug = attr_container_get_as_bool(attr_cont, "debug");
- applet_data->debug_mode = debug;
- /* Create tool agent queue */
- if (debug && !(applet_data->tool_agent_queue = bh_queue_create())) {
- SEND_ERR_RESPONSE(
- msg->mid, "Install Applet failed: create tool agent queue failed.");
- goto fail5_1;
- }
- #endif
- /* Create applet instance */
- applet_data->vm_instance = jeff_runtime_create_instance(
- main_file, m_data->heap, 16, app_instance_main, m_data, NULL);
- if (!applet_data->vm_instance) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: create Java VM failed");
- goto fail6;
- }
- /* Add applet data to applet data list */
- applet_data->vm_instance->applet_object = applet_data->applet_obj;
- app_manager_add_module_data(m_data);
- app_manager_post_applets_update_event();
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- /* Start tool agent thread */
- if (debug
- && !jeff_tool_start_agent(applet_data->vm_instance,
- applet_data->tool_agent_queue)) {
- SEND_ERR_RESPONSE(msg->mid,
- "Install Applet failed: start tool agent failed");
- goto fail6;
- }
- #endif
- app_manager_printf("Install Applet success!\n");
- app_send_response_to_host(msg->mid, CREATED_2_01, NULL); /* CREATED */
- return true;
- fail6:
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- if (debug)
- bh_queue_destroy(applet_data->tool_agent_queue);
- #endif
- fail5_1:
- watchdog_timer_destroy(&m_data->wd_timer);
- fail5:
- gc_destroy_for_instance(m_data->heap);
- fail4:
- bh_queue_destroy(m_data->queue, NULL);
- fail3_1:
- APP_MGR_FREE(applet_data->perms);
- fail3:
- APP_MGR_FREE(applet_data);
- fail2:
- jeff_runtime_unload(main_file);
- fail1:
- APP_MGR_FREE(main_file);
- return false;
- }
- static void
- cleanup_applet_resource(module_data *m_data)
- {
- jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
- /* Unload Jeff main file and free it */
- jeff_runtime_unload(applet_data->main_file);
- APP_MGR_FREE(applet_data->main_file);
- /* Destroy queue */
- bh_queue_destroy(m_data->queue, app_instance_queue_free_callback);
- /* Destroy heap */
- gc_destroy_for_instance(m_data->heap);
- /* Destroy watchdog timer */
- watchdog_timer_destroy(&m_data->wd_timer);
- /* Remove module data from module data list and free it */
- app_manager_del_module_data(m_data);
- APP_MGR_FREE(applet_data->perms);
- APP_MGR_FREE(m_data);
- }
- /* Uninstall Java Applet */
- static bool
- jeff_module_uninstall(bh_request_msg_t *msg)
- {
- module_data *m_data;
- jeff_applet_data *applet_data;
- attr_container_t *attr_cont;
- char *applet_name;
- bool do_not_reply = false;
- /* Check payload and applet name*/
- attr_cont = (attr_container_t *)msg->payload;
- /* Check whether need to reply this request */
- if (attr_container_contain_key(attr_cont, "do not reply me"))
- do_not_reply = attr_container_get_as_bool(attr_cont, "do not reply me");
- /* Check url */
- if (!msg->url || strcmp(msg->url, "/applet") != 0) {
- if (!do_not_reply)
- SEND_ERR_RESPONSE(msg->mid,
- "Uninstall Applet failed: invalid url.");
- else
- app_manager_printf("Uninstall Applet failed: invalid url.");
- return false;
- }
- if (!attr_cont
- || !(applet_name = attr_container_get_as_string(attr_cont, "name"))
- || strlen(applet_name) == 0) {
- if (!do_not_reply)
- SEND_ERR_RESPONSE(msg->mid,
- "Uninstall Applet failed: invalid applet name.");
- else
- app_manager_printf("Uninstall Applet failed: invalid applet name.");
- return false;
- }
- m_data = app_manager_lookup_module_data(applet_name);
- if (!m_data) {
- if (!do_not_reply)
- SEND_ERR_RESPONSE(msg->mid,
- "Uninstall Applet failed: no applet found.");
- else
- app_manager_printf("Uninstall Applet failed: no applet found.");
- return false;
- }
- if (m_data->module_type != Module_Jeff) {
- if (!do_not_reply)
- SEND_ERR_RESPONSE(msg->mid,
- "Uninstall Applet failed: invlaid module type.");
- else
- app_manager_printf("Uninstall Applet failed: invalid module type.");
- return false;
- }
- if (m_data->wd_timer.is_interrupting) {
- if (!do_not_reply)
- SEND_ERR_RESPONSE(msg->mid,
- "Uninstall Applet failed: applet is being "
- "interrupted by watchdog.");
- else
- app_manager_printf("Uninstall Applet failed: applet is being "
- "interrupted by watchdog.");
- return false;
- }
- /* Exit applet queue loop run */
- bh_queue_exit_loop_run(m_data->queue);
- applet_data = (jeff_applet_data *)m_data->internal_data;
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- /* Exit tool agent queue loop run */
- if (is_tool_agent_running(m_data)) {
- bh_queue_exit_loop_run(applet_data->tool_agent_queue);
- }
- #endif
- /* Wait the end of the applet instance and then destroy it */
- if (applet_data->vm_instance->main_file)
- jeff_runtime_wait_for_instance(applet_data->vm_instance, -1);
- jeff_runtime_destroy_instance(applet_data->vm_instance);
- cleanup_applet_resource(m_data);
- app_manager_post_applets_update_event();
- app_manager_printf("Uninstall Applet success!\n");
- if (!do_not_reply)
- app_send_response_to_host(msg->mid, DELETED_2_02, NULL); /* DELETED */
- return true;
- }
- #define PERM_PREFIX "AEE.permission."
- static bool
- check_permission_format(const char *perm)
- {
- const char *prefix = PERM_PREFIX;
- const char *p;
- if (perm == NULL || strncmp(perm, prefix, strlen(prefix)) != 0
- || *(p = perm + strlen(prefix)) == '\0')
- return false;
- do {
- if (!(*p == '.' || ('A' <= *p && *p <= 'Z')
- || ('a' <= *p && *p <= 'z')))
- return false;
- } while (*++p != '\0');
- return true;
- }
- static bool
- match(const char *haystack, const char *needle, char delim)
- {
- const char *p = needle;
- if (haystack == NULL || *haystack == '\0' || needle == NULL
- || *needle == '\0')
- return false;
- while (true) {
- while (true) {
- if ((*haystack == '\0' || *haystack == delim) && *p == '\0') {
- return true;
- }
- else if (*p == *haystack) {
- ++p;
- ++haystack;
- }
- else {
- break;
- }
- }
- while (*haystack != '\0' && *haystack != delim) {
- ++haystack;
- }
- if (*haystack == '\0') {
- return false;
- }
- else {
- ++haystack;
- p = needle;
- }
- }
- }
- bool
- bh_applet_check_permission(const char *perm)
- {
- return check_permission_format(perm)
- && match(app_manager_get_jeff_applet_data()->perms,
- perm + strlen(PERM_PREFIX), ' ');
- }
- static bool
- jeff_module_init()
- {
- JeffDescriptorFull d[] = { { JEFF_TYPE_VOID, 0, NULL } };
- JeffDescriptorFull d1[] = { { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0, NULL },
- { JEFF_TYPE_VOID, 0, NULL } };
- /* Resolve class com.intel.aee.AEEApplet */
- class_AEEApplet =
- jeff_runtime_resolve_class_full_name("com.intel.aee.AEEApplet");
- if (!class_AEEApplet) {
- app_manager_printf(
- "App Manager start failed: resolve class AEEApplet failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.Request */
- class_AEERequest =
- jeff_runtime_resolve_class_full_name("com.intel.aee.Request");
- if (!class_AEERequest) {
- app_manager_printf(
- "App Manager start failed: resolve class Request failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.Timer */
- class_Timer = jeff_runtime_resolve_class_full_name("com.intel.aee.Timer");
- if (!class_Timer) {
- app_manager_printf(
- "App Manager start failed: resolve class Timer failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.Sensor */
- class_Sensor = jeff_runtime_resolve_class_full_name("com.intel.aee.Sensor");
- if (!class_Sensor) {
- app_manager_printf(
- "App Manager start failed: resolve class Sensor failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.ble.BLEManager */
- class_BLEManager =
- jeff_runtime_resolve_class_full_name("com.intel.aee.ble.BLEManager");
- if (!class_BLEManager) {
- app_manager_printf(
- "App Manager start failed: resolve class BLEManager failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.ble.BLEDevice */
- class_BLEDevice =
- jeff_runtime_resolve_class_full_name("com.intel.aee.ble.BLEDevice");
- if (!class_BLEDevice) {
- app_manager_printf(
- "App Manager start failed: resolve class BLEDevice failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.ble.BLEDevice */
- class_BLEGattService = jeff_runtime_resolve_class_full_name(
- "com.intel.aee.ble.BLEGattService");
- if (!class_BLEGattService) {
- app_manager_printf("App Manager start failed: resolve class "
- "BLEGattService failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.ble.BLEDevice */
- class_BLEGattCharacteristic = jeff_runtime_resolve_class_full_name(
- "com.intel.aee.ble.BLEGattCharacteristic");
- if (!class_BLEGattCharacteristic) {
- app_manager_printf("App Manager start failed: resolve class "
- "BLEGattCharacteristic failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.ble.BLEDevice */
- class_BLEGattDescriptor = jeff_runtime_resolve_class_full_name(
- "com.intel.aee.ble.BLEGattDescriptor");
- if (!class_BLEGattDescriptor) {
- app_manager_printf("App Manager start failed: resolve class "
- "BLEGattDescriptor failed.\n");
- return false;
- }
- /* Resolve class com.intel.aee.gpio.GPIOChannel */
- class_GPIOChannel =
- jeff_runtime_resolve_class_full_name("com.intel.aee.gpio.GPIOChannel");
- if (!class_GPIOChannel) {
- app_manager_printf("App Manager start failed: resolve class "
- "GPIOChannel failed.\n");
- return false;
- }
- /* Resolve method com.intel.aee.AEEApplet.onInit() */
- method_AEEApplet_onInit =
- jeff_lookup_method(class_AEEApplet, "onInit", 0, d);
- if (!method_AEEApplet_onInit) {
- app_manager_printf("App Manager start failed: resolve method "
- "Applet.onInit() failed.\n");
- return false;
- }
- /* Resolve method com.intel.aee.AEEApplet.onDestroy() */
- method_AEEApplet_onDestroy =
- jeff_lookup_method(class_AEEApplet, "onDestroy", 0, d);
- if (!method_AEEApplet_onDestroy) {
- app_manager_printf("App Manager start failed: resolve method "
- "AEEApplet.onDestroy() failed.\n");
- return false;
- }
- /* Resolve method com.intel.aee.AEEApplet.callOnRequest(Request) */
- d1[0].class_header = class_AEERequest;
- method_AEEApplet_callOnRequest =
- jeff_lookup_method(class_AEEApplet, "callOnRequest", 1, d1);
- if (!method_AEEApplet_callOnRequest) {
- app_manager_printf("App Manager start failed: resolve method "
- "AEEApplet.callOnRequest() failed.\n");
- return false;
- }
- /* Resolve method com.intel.aee.Timer.callOnTimer() */
- method_callOnTimer = jeff_lookup_method(class_Timer, "callOnTimer", 0, d);
- if (!method_callOnTimer) {
- app_manager_printf("App Manager start failed: resolve method "
- "Timer.callOnTimer() failed.\n");
- return false;
- }
- /* Resolve method com.intel.aee.Sensor.callOnSensorEvent() */
- method_callOnSensorEvent =
- jeff_lookup_method(class_Sensor, "callOnSensorEvent", 0, d);
- if (!method_callOnSensorEvent) {
- app_manager_printf("App Manager start failed: resolve method "
- "Sensor.callOnSensorEvent() failed.\n");
- return false;
- }
- /* Resovle method
- * com.intel.aee.ble.BLEManager.callOnBLEStartDiscovery(BLEDevice) */
- d1[0].class_header = class_BLEDevice;
- method_callOnBLEStartDiscovery =
- jeff_lookup_method(class_BLEManager, "callOnBLEStartDiscovery", 1, d1);
- if (!method_callOnBLEStartDiscovery) {
- app_manager_printf("App Manager start failed: resolve method "
- "BLEManager.callOnBLEStartDiscovery() failed.\n");
- return false;
- }
- /* Resovle method
- * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice) */
- JeffDescriptorFull d2_1[] = { { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0,
- class_BLEDevice },
- { JEFF_TYPE_INT, 0, NULL },
- { JEFF_TYPE_VOID, 0, NULL } };
- method_callOnBLEConnected =
- jeff_lookup_method(class_BLEManager, "callOnBLEConnected", 2, d2_1);
- if (!method_callOnBLEConnected) {
- app_manager_printf("App Manager start failed: resolve method "
- "BLEManager.callOnBLEConnected() failed.\n");
- return false;
- }
- /* Resovle method
- * com.intel.aee.ble.BLEManager.method_callOnBLENotification(BLEDevice,byte[])
- */
- JeffDescriptorFull d2_2[] = {
- { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0, class_BLEDevice },
- { JEFF_TYPE_BYTE | JEFF_TYPE_REF | JEFF_TYPE_MONO, 1, NULL },
- { JEFF_TYPE_INT, 0, NULL },
- { JEFF_TYPE_INT, 0, NULL },
- { JEFF_TYPE_VOID, 0, NULL }
- };
- method_callOnBLENotification =
- jeff_lookup_method(class_BLEManager, "callOnBLENotification", 4, d2_2);
- if (!method_callOnBLENotification) {
- app_manager_printf("App Manager start failed: resolve method "
- "BLEManager.callOnBLENotification() failed.\n");
- return false;
- }
- /* Resovle method
- * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice,byte[]) */
- method_callOnBLEIndication =
- jeff_lookup_method(class_BLEManager, "callOnBLEIndication", 4, d2_2);
- if (!method_callOnBLEIndication) {
- app_manager_printf("App Manager start failed: resolve method "
- "BLEManager.callOnBLEIndication() failed.\n");
- return false;
- }
- /* Resovle method
- * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice) */
- d1[0].class_header = class_BLEDevice;
- method_callOnBLEDisconnected =
- jeff_lookup_method(class_BLEManager, "callOnBLEDisconnected", 1, d1);
- if (!method_callOnBLEDisconnected) {
- app_manager_printf("App Manager start failed: resolve method "
- "BLEManager.callOnBLEDisconnected() failed.\n");
- return false;
- }
- /* Resovle method
- * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice) */
- method_callOnBLEPasskeyEntry =
- jeff_lookup_method(class_BLEManager, "callOnBLEPasskeyEntry", 1, d1);
- if (!method_callOnBLEPasskeyEntry) {
- app_manager_printf("App Manager start failed: resolve method "
- "BLEManager.callOnBLEPasskeyEntry() failed.\n");
- return false;
- }
- /* Resovle method void
- * com.intel.aee.gpio.GPIOChannel.callOnGPIOInterrupt() */
- method_callOnGPIOInterrupt =
- jeff_lookup_method(class_GPIOChannel, "callOnGPIOInterrupt", 0, d);
- if (!method_callOnGPIOInterrupt) {
- app_manager_printf("App Manager start failed: resolve method "
- "GPIOChannel.callOnGPIOInterrupt() failed.\n");
- return false;
- }
- JeffDescriptorFull d2[] = {
- { JEFF_TYPE_BYTE | JEFF_TYPE_REF | JEFF_TYPE_MONO, 1, NULL },
- { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0, class_BLEDevice }
- };
- /* Resovle method com.intel.aee.ble.BLEManager.getBLEDevice(byte []) */
- method_callOnBLEManagerGetBLEDevice =
- jeff_lookup_method(class_BLEManager, "getBLEDevice", 1, d2);
- if (!method_callOnBLEManagerGetBLEDevice) {
- app_manager_printf("App Manager start failed: resolve method "
- "BLEManager.getBLEDevice() failed.\n");
- return false;
- }
- return true;
- }
- static void
- jeff_module_watchdog_kill(module_data *m_data)
- {
- jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
- app_manager_printf("Watchdog interrupt the applet %s\n",
- m_data->module_name);
- jeff_runtime_interrupt_instance(applet_data->vm_instance, true);
- /* Exit applet queue loop run */
- bh_queue_exit_loop_run(m_data->queue);
- /* Wait the end of the applet instance. If timeout, it means applet
- * is busy executing native code, then try to cancle the main thread. */
- if (applet_data->vm_instance->main_file)
- jeff_runtime_wait_for_instance(applet_data->vm_instance, 3000);
- if (applet_data->vm_instance->main_file) {
- app_manager_printf("Watchdog cancel applet main thread.\n");
- os_thread_cancel(applet_data->vm_instance->main_tlr.handle);
- /* k_thread_abort(applet_data->vm_instance->main_tlr.handle); */
- }
- send_exception_event_to_host(m_data->module_name,
- "java.lang.InterruptedException");
- cleanup_applet_resource(m_data);
- app_manager_printf("Watchdog interrupt Jeff applet done.\n");
- }
- static bool
- jeff_module_handle_host_url(void *queue_msg)
- {
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- bh_queue_msg_t *msg = (bh_queue_msg_t *)queue_msg;
- if (msg->message_type == COAP_PARSED) {
- coap_packet_t *packet = (coap_packet_t *)msg->payload;
- attr_container_t *attr_cont = (attr_container_t *)packet->payload;
- const char *url = NULL;
- int url_len = 0, mid;
- bh_memcpy_s(&mid, sizeof(uint32), packet->token, sizeof(uint32));
- url_len = coap_get_header_uri_path(packet, &url);
- /* Send request to tool agent */
- if (url_len >= 12 && memcmp(url, "/tool_agent/", 12) == 0) {
- module_data *m_data;
- jeff_applet_data *applet_data;
- unsigned attr_cont_len = 0, req_msg_len;
- bh_queue_msg_t *tool_agent_msg;
- bh_request_msg_t *req_msg;
- char url_buf[256] = { 0 }, *p = url_buf;
- char applet_name[128] = { 0 };
- /* Resolve applet name */
- bh_memcpy_s(url_buf, sizeof(url_buf), url + 12, url_len - 12);
- while (*p != '/' && *p != '\0')
- p++;
- bh_memcpy_s(applet_name, sizeof(applet_name), url_buf, p - url_buf);
- app_manager_printf("Send request to tool agent of applet: %s\n",
- applet_name);
- /* Check applet name */
- if (!(m_data = app_manager_lookup_module_data(applet_name))) {
- SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
- "invalid applet name");
- return false;
- }
- applet_data = (jeff_applet_data *)m_data->internal_data;
- /* Attach debug: start the tool agent firstly */
- if (packet->code == COAP_PUT) {
- if (is_tool_agent_running(m_data)) {
- SEND_ERR_RESPONSE(mid, "Attach debug failed: tool "
- "agent is already exist.");
- return false;
- }
- applet_data->debug_mode = true;
- /* Create tool agent queue */
- if (!(applet_data->tool_agent_queue = bh_queue_create())) {
- SEND_ERR_RESPONSE(mid, "Attach debug failed: create "
- "tool agent queue failed.");
- return false;
- }
- /* Start tool agent thread */
- if (!jeff_tool_start_agent(applet_data->vm_instance,
- applet_data->tool_agent_queue)) {
- bh_queue_destroy(applet_data->tool_agent_queue, NULL);
- SEND_ERR_RESPONSE(
- mid, "Attach debug failed: start tool agent failed");
- return false;
- }
- app_manager_printf("Attach debug: start tool agent of "
- "applet %s success.\n",
- applet_name);
- app_send_response_to_host(mid, CREATED_2_01, NULL); /* OK */
- }
- else {
- /* Check tool agent running */
- if (!is_tool_agent_running(m_data)) {
- SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
- "tool agent is not running");
- return false;
- }
- /* Create queue message for tool agent */
- if (!(tool_agent_msg =
- APP_MGR_MALLOC(sizeof(bh_queue_msg_t)))) {
- SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
- "allocate memory failed");
- return false;
- }
- if (attr_cont)
- attr_cont_len =
- attr_container_get_serialize_length(attr_cont);
- req_msg_len =
- sizeof(bh_request_msg_t) + strlen(p) + 1 + attr_cont_len;
- /* Create request message */
- if (!(req_msg = APP_MGR_MALLOC(req_msg_len))) {
- SEND_ERR_RESPONSE(mid, "Send request to applet failed: "
- "allocate memory failed");
- APP_MGR_FREE(tool_agent_msg);
- return false;
- }
- /* Set request message */
- memset(req_msg, 0, req_msg_len);
- req_msg->mid = mid;
- req_msg->url = (char *)req_msg + sizeof(bh_request_msg_t);
- bh_strcpy_s(req_msg->url, strlen(p) + 1,
- p); /* Actual url sent to tool agent */
- req_msg->action = packet->code;
- req_msg->fmt = 0;
- if (attr_cont) {
- req_msg->payload = (char *)req_msg
- + sizeof(bh_request_msg_t) + strlen(p)
- + 1;
- attr_container_serialize(req_msg->payload, attr_cont);
- }
- /* Set queue message and send to tool agent's queue */
- tool_agent_msg->message_type = JDWP_REQUEST;
- tool_agent_msg->payload_size = req_msg_len;
- tool_agent_msg->payload = (char *)req_msg;
- if (!bh_queue_send_message(applet_data->tool_agent_queue,
- tool_agent_msg)) {
- APP_MGR_FREE(req_msg);
- APP_MGR_FREE(tool_agent_msg);
- SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
- "send queue msg failed.");
- return false;
- }
- /* app_manager_printf("Send request to tool agent of applet
- * %s success.\n", applet_name); */
- }
- return true;
- }
- }
- #endif /* BEIHAI_ENABLE_TOOL_AGENT != 0 */
- return false;
- }
- static module_data *
- jeff_module_get_module_data(void)
- {
- JeffThreadLocalRoot *self = jeff_runtime_get_tlr();
- return (module_data *)self->il_root->start_routine_arg;
- }
- #if BEIHAI_ENABLE_TOOL_AGENT != 0
- #define JDWP_HANDSHAKE_MAGIC "JDWP-Handshake"
- #define JDWP_HANDSHAKE_LEN (sizeof(JDWP_HANDSHAKE_MAGIC) - 1)
- #define JDWP_PAYLOAD_KEY "jdwp"
- static bool debug = true;
- static bool
- send_msg_to_host(int mid, const char *url, int code, const uint8 *msg,
- unsigned size)
- {
- bool ret;
- int payload_len = 0;
- attr_container_t *payload = NULL;
- if (msg) {
- if ((payload = attr_container_create(""))) {
- attr_container_set_bytearray(&payload, JDWP_PAYLOAD_KEY,
- (const int8_t *)msg, size);
- payload_len = attr_container_get_serialize_length(payload);
- }
- }
- ret = app_send_msg_to_host(mid, url, code, (char *)payload, payload_len);
- if (payload)
- attr_container_destroy(payload);
- return ret;
- }
- static bool
- send_response(int mid, int code, const uint8 *msg, unsigned size)
- {
- return send_msg_to_host(mid, NULL, code, msg, size);
- }
- static bool
- send_packet_response(int mid, int code, JeffBuffer *packet)
- {
- int size;
- if ((size = jeff_buffer_size(packet)) == 0)
- /* No data need to be written, succeed. */
- return true;
- return send_msg_to_host(mid, NULL, code, jeff_buffer_at(packet, 0), size);
- }
- void
- jeff_tool_event_publish(uint8 *evtbuf, unsigned size)
- {
- char *prefix = "/jdwp/", *url = NULL;
- int url_len;
- url_len = strlen(prefix) + strlen(app_manager_get_module_name(Module_Jeff));
- if (NULL == (url = jeff_runtime_malloc(url_len + 1)))
- return;
- bh_strcpy_s(url, url_len + 1, prefix);
- bh_strcat_s(url, url_len + 1, app_manager_get_module_name(Module_Jeff));
- /* Event is sent as request so we set code as COAP_PUT */
- if (event_is_registered(url))
- send_msg_to_host(0, url, COAP_PUT, evtbuf, size);
- jeff_runtime_free(url);
- }
- #define SEND_ERROR_RESPONSE(err_msg) \
- do { \
- app_manager_printf("%s\n", err_msg); \
- send_response(req_msg->mid, INTERNAL_SERVER_ERROR_5_00, \
- (uint8 *)err_msg, strlen(err_msg) + 1); \
- } while (0)
- /* Queue callback of tool agent */
- void
- tool_agent_queue_callback(void *arg)
- {
- bh_queue_msg_t *msg = (bh_queue_msg_t *)arg;
- if (msg->message_type == JDWP_REQUEST) {
- bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
- attr_container_t *attr_cont = (attr_container_t *)req_msg->payload;
- JeffThreadLocalRoot *self = jeff_runtime_get_tlr();
- JeffInstanceLocalRoot *cur_instance = self->il_root;
- JeffToolAgent *agent = cur_instance->tool_agent;
- bh_queue *queue = (bh_queue *)self->start_routine_arg;
- if (debug)
- app_manager_printf(
- "Tool Agent of applet %s got request, url %s, action %d\n",
- app_manager_get_module_name(Module_Jeff), req_msg->url,
- req_msg->action);
- /* Handshake or Process Request */
- if (req_msg->action == COAP_GET) {
- uint8 *buf;
- unsigned buf_len;
- if (!attr_cont
- || !(buf = (uint8 *)attr_container_get_as_bytearray(
- attr_cont, JDWP_PAYLOAD_KEY, &buf_len))) {
- SEND_ERROR_RESPONSE("Tool Agent fail: invalid JDWP payload.");
- goto fail;
- }
- if (!agent->connected) {
- if (buf_len != JDWP_HANDSHAKE_LEN
- || memcmp(buf, JDWP_HANDSHAKE_MAGIC, JDWP_HANDSHAKE_LEN)) {
- SEND_ERROR_RESPONSE("Tool Agent fail: handshake fail.");
- goto fail;
- }
- /* Handshake success and response */
- agent->connected = true;
- send_response(req_msg->mid, CONTENT_2_05, buf, buf_len);
- }
- else {
- /* TODO: tool-agent thread should reuse the request/reply
- * buffer to avoid allocating memory repeatedly */
- JeffBuffer request, reply;
- /* Initialize the package buffers. */
- jeff_buffer_init(&request);
- jeff_buffer_init(&reply);
- if (!jeff_buffer_resize(&request, buf_len)) {
- SEND_ERROR_RESPONSE("Tool Agent fail: resize buffer fail.");
- jeff_buffer_destroy(&request);
- jeff_buffer_destroy(&reply);
- goto fail;
- }
- /* Copy data from request to jeff buffer */
- bh_memcpy_s(jeff_buffer_at(&request, 0),
- jeff_buffer_size(&request), buf, buf_len);
- /* Handle JDWP request */
- if (!jeff_tool_handle_packet(agent, &request, &reply)) {
- SEND_ERROR_RESPONSE(
- "Tool agent fail: handle request fail.");
- jeff_buffer_destroy(&request);
- jeff_buffer_destroy(&reply);
- goto fail;
- }
- /* Response JDWP reply */
- send_packet_response(req_msg->mid, CONTENT_2_05, &reply);
- /* Destroy the package buffers. */
- jeff_buffer_destroy(&request);
- jeff_buffer_destroy(&reply);
- }
- }
- /* Debugger disconnect */
- else if (req_msg->action == COAP_DELETE) {
- send_response(req_msg->mid, DELETED_2_02, NULL, 0);
- bh_queue_exit_loop_run(queue);
- }
- else {
- SEND_ERROR_RESPONSE("Tool agent fail: invalid request.");
- goto fail;
- }
- APP_MGR_FREE(req_msg);
- APP_MGR_FREE(msg);
- return;
- fail:
- bh_queue_exit_loop_run(queue);
- APP_MGR_FREE(req_msg);
- }
- APP_MGR_FREE(msg);
- }
- void
- tool_agent_queue_free_callback(void *message)
- {
- bh_queue_msg_t *msg = (bh_queue_msg_t *)message;
- if (msg->message_type == JDWP_REQUEST) {
- bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
- APP_MGR_FREE(req_msg);
- }
- APP_MGR_FREE(msg);
- }
- #endif /* BEIHAI_ENABLE_TOOL_AGENT != 0 */
- /* clang-format off */
- module_interface jeff_module_interface = {
- jeff_module_init,
- jeff_module_install,
- jeff_module_uninstall,
- jeff_module_watchdog_kill,
- jeff_module_handle_host_url,
- jeff_module_get_module_data,
- NULL
- };
- /* clang-format on */
- #endif
|