1 /*
2 * Copyright (C) 2016 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 "NanohubHAL"
18
19 #include <cassert>
20 #include <cerrno>
21 #include <cinttypes>
22
23 #include <endian.h>
24
25 #include <vector>
26
27 #include <utils/Log.h>
28
29 #include <endian.h>
30
31 #include <hardware/context_hub.h>
32 #include "nanohub_perdevice.h"
33 #include "system_comms.h"
34 #include "nanohubhal.h"
35
36 namespace android {
37
38 namespace nanohub {
39
readAppName(MessageBuf & buf,hub_app_name_t & name)40 static void readAppName(MessageBuf &buf, hub_app_name_t &name)
41 {
42 name.id = buf.readU64();
43 }
44
writeAppName(MessageBuf & buf,const hub_app_name_t & name)45 static void writeAppName(MessageBuf &buf, const hub_app_name_t &name)
46 {
47 buf.writeU64(name.id);
48 }
49
readNanohubAppInfo(MessageBuf & buf,NanohubAppInfo & info)50 static void readNanohubAppInfo(MessageBuf &buf, NanohubAppInfo &info)
51 {
52 size_t pos = buf.getPos();
53 readAppName(buf, info.name);
54 info.version = buf.readU32();
55 info.flashUse = buf.readU32();
56 info.ramUse = buf.readU32();
57 if ((buf.getPos() - pos) != sizeof(info)) {
58 ALOGE("%s: failed to read object", __func__);
59 }
60 }
61
readNanohubMemInfo(MessageBuf & buf,NanohubMemInfo & mi)62 static void readNanohubMemInfo(MessageBuf &buf, NanohubMemInfo &mi)
63 {
64 size_t pos = buf.getPos();
65 mi.flashSz = buf.readU32();
66 mi.blSz = buf.readU32();
67 mi.osSz = buf.readU32();
68 mi.sharedSz = buf.readU32();
69 mi.eeSz = buf.readU32();
70 mi.ramSz = buf.readU32();
71
72 mi.blUse = buf.readU32();
73 mi.osUse = buf.readU32();
74 mi.sharedUse = buf.readU32();
75 mi.eeUse = buf.readU32();
76 mi.ramUse = buf.readU32();
77 if ((buf.getPos() - pos) != sizeof(mi)) {
78 ALOGE("%s: failed to read object", __func__);
79 }
80 }
81
NanohubRsp(MessageBuf & buf,bool no_status)82 NanohubRsp::NanohubRsp(MessageBuf &buf, bool no_status)
83 {
84 // all responses start with command
85 // most of them have 4-byte status (result code)
86 buf.reset();
87 cmd = buf.readU8();
88 if (!buf.getSize()) {
89 status = -EINVAL;
90 } else if (no_status) {
91 status = 0;
92 } else {
93 status = buf.readU32();
94 }
95 }
96
sendToSystem(const void * data,size_t len)97 int SystemComm::sendToSystem(const void *data, size_t len)
98 {
99 if (NanoHub::messageTracingEnabled()) {
100 dumpBuffer("HAL -> SYS", getSystem()->mHostIfAppName, 0, data, len);
101 }
102 return NanoHub::sendToDevice(&getSystem()->mHostIfAppName, data, len);
103 }
104
setup(const hub_message_t *)105 int SystemComm::AppInfoSession::setup(const hub_message_t *)
106 {
107 std::lock_guard<std::mutex> _l(mLock);
108 int suggestedSize = mAppInfo.size() ? mAppInfo.size() : 20;
109
110 mAppInfo.clear();
111 mAppInfo.reserve(suggestedSize);
112 setState(SESSION_USER);
113
114 return requestNext();
115 }
116
deviceAppNameToHost(const hub_app_name_t src)117 inline hub_app_name_t deviceAppNameToHost(const hub_app_name_t src)
118 {
119 hub_app_name_t res = { .id = le64toh(src.id) };
120 return res;
121 }
122
hostAppNameToDevice(const hub_app_name_t src)123 inline hub_app_name_t hostAppNameToDevice(const hub_app_name_t src)
124 {
125 hub_app_name_t res = { .id = htole64(src.id) };
126 return res;
127 }
128
handleRx(MessageBuf & buf)129 int SystemComm::AppInfoSession::handleRx(MessageBuf &buf)
130 {
131 std::lock_guard<std::mutex> _l(mLock);
132
133 NanohubRsp rsp(buf, true);
134 if (rsp.cmd != NANOHUB_QUERY_APPS) {
135 return 1;
136 }
137 size_t len = buf.getRoom();
138 if (len != sizeof(NanohubAppInfo) && len) {
139 ALOGE("%s: Invalid data size; have %zu, need %zu", __func__,
140 len, sizeof(NanohubAppInfo));
141 return -EINVAL;
142 }
143 if (getState() != SESSION_USER) {
144 ALOGE("%s: Invalid state; have %d, need %d", __func__, getState(), SESSION_USER);
145 return -EINVAL;
146 }
147 if (len) {
148 NanohubAppInfo info;
149 readNanohubAppInfo(buf, info);
150 hub_app_info appInfo;
151 appInfo.num_mem_ranges = 0;
152 if (info.flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
153 mem_range_t &range = appInfo.mem_usage[appInfo.num_mem_ranges++];
154 range.type = HUB_MEM_TYPE_MAIN;
155 range.total_bytes = info.flashUse;
156 }
157 if (info.ramUse != NANOHUB_MEM_SZ_UNKNOWN) {
158 mem_range_t &range = appInfo.mem_usage[appInfo.num_mem_ranges++];
159 range.type = HUB_MEM_TYPE_RAM;
160 range.total_bytes = info.ramUse;
161 }
162
163 appInfo.app_name = info.name;
164 appInfo.version = info.version;
165
166 mAppInfo.push_back(appInfo);
167 return requestNext();
168 } else {
169 sendToApp(CONTEXT_HUB_QUERY_APPS,
170 static_cast<const void *>(mAppInfo.data()),
171 mAppInfo.size() * sizeof(mAppInfo[0]));
172 complete();
173 }
174
175 return 0;
176 }
177
requestNext()178 int SystemComm::AppInfoSession::requestNext()
179 {
180 char data[MAX_RX_PACKET];
181 MessageBuf buf(data, sizeof(data));
182 buf.writeU8(NANOHUB_QUERY_APPS);
183 buf.writeU32(mAppInfo.size());
184 return sendToSystem(buf.getData(), buf.getPos());
185 }
186
setup(const hub_message_t *)187 int SystemComm::MemInfoSession::setup(const hub_message_t *)
188 {
189 std::lock_guard<std::mutex> _l(mLock);
190 char data[MAX_RX_PACKET];
191 MessageBuf buf(data, sizeof(data));
192 buf.writeU8(NANOHUB_QUERY_MEMINFO);
193
194 setState(SESSION_USER);
195 return sendToSystem(buf.getData(), buf.getPos());
196 }
197
handleRx(MessageBuf & buf)198 int SystemComm::MemInfoSession::handleRx(MessageBuf &buf)
199 {
200 std::lock_guard<std::mutex> _l(mLock);
201 NanohubRsp rsp(buf, true);
202
203 if (rsp.cmd != NANOHUB_QUERY_MEMINFO)
204 return 1;
205
206 size_t len = buf.getRoom();
207
208 if (len != sizeof(NanohubMemInfo)) {
209 ALOGE("%s: Invalid data size: %zu", __func__, len);
210 return -EINVAL;
211 }
212 if (getState() != SESSION_USER) {
213 ALOGE("%s: Invalid state; have %d, need %d", __func__, getState(), SESSION_USER);
214 return -EINVAL;
215 }
216
217 NanohubMemInfo mi;
218 readNanohubMemInfo(buf, mi);
219 std::vector<mem_range_t> ranges;
220 ranges.reserve(4);
221
222 //if each is valid, copy to output area
223 if (mi.sharedSz != NANOHUB_MEM_SZ_UNKNOWN &&
224 mi.sharedUse != NANOHUB_MEM_SZ_UNKNOWN)
225 ranges.push_back({
226 .type = HUB_MEM_TYPE_MAIN,
227 .total_bytes = mi.sharedSz,
228 .free_bytes = mi.sharedSz - mi.sharedUse,
229 });
230
231 if (mi.osSz != NANOHUB_MEM_SZ_UNKNOWN &&
232 mi.osUse != NANOHUB_MEM_SZ_UNKNOWN)
233 ranges.push_back({
234 .type = HUB_MEM_TYPE_OS,
235 .total_bytes = mi.osSz,
236 .free_bytes = mi.osSz - mi.osUse,
237 });
238
239 if (mi.eeSz != NANOHUB_MEM_SZ_UNKNOWN &&
240 mi.eeUse != NANOHUB_MEM_SZ_UNKNOWN)
241 ranges.push_back({
242 .type = HUB_MEM_TYPE_EEDATA,
243 .total_bytes = mi.eeSz,
244 .free_bytes = mi.eeSz - mi.eeUse,
245 });
246
247 if (mi.ramSz != NANOHUB_MEM_SZ_UNKNOWN &&
248 mi.ramUse != NANOHUB_MEM_SZ_UNKNOWN)
249 ranges.push_back({
250 .type = HUB_MEM_TYPE_RAM,
251 .total_bytes = mi.ramSz,
252 .free_bytes = mi.ramSz - mi.ramUse,
253 });
254
255 //send it out
256 sendToApp(CONTEXT_HUB_QUERY_MEMORY,
257 static_cast<const void *>(ranges.data()),
258 ranges.size() * sizeof(ranges[0]));
259
260 complete();
261
262 return 0;
263 }
264
setup(const hub_message_t * appMsg)265 int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg)
266 {
267 std::lock_guard<std::mutex> _l(mLock);
268
269 char data[MAX_RX_PACKET];
270 MessageBuf buf(data, sizeof(data));
271 const uint8_t *msgData = static_cast<const uint8_t*>(appMsg->message);
272
273 mCmd = appMsg->message_type;
274 mLen = appMsg->message_len;
275 mPos = 0;
276
277 switch (mCmd) {
278 case CONTEXT_HUB_APPS_ENABLE:
279 return setupMgmt(appMsg, NANOHUB_EXT_APPS_ON);
280 case CONTEXT_HUB_APPS_DISABLE:
281 return setupMgmt(appMsg, NANOHUB_EXT_APPS_OFF);
282 case CONTEXT_HUB_UNLOAD_APP:
283 return setupMgmt(appMsg, NANOHUB_EXT_APP_DELETE);
284 case CONTEXT_HUB_LOAD_APP:
285 {
286 mData.clear();
287 mData = std::vector<uint8_t>(msgData, msgData + mLen);
288 const load_app_request_t *appReq = static_cast<const load_app_request_t*>(appMsg->message);
289 if (appReq == nullptr || mLen <= sizeof(*appReq)) {
290 ALOGE("%s: Invalid app header: too short\n", __func__);
291 return -EINVAL;
292 }
293 mAppName = appReq->app_binary.app_id;
294 setState(TRANSFER);
295
296 buf.writeU8(NANOHUB_START_UPLOAD);
297 buf.writeU8(0);
298 buf.writeU32(mLen);
299 return sendToSystem(buf.getData(), buf.getPos());
300 }
301
302 case CONTEXT_HUB_OS_REBOOT:
303 setState(REBOOT);
304 buf.writeU8(NANOHUB_REBOOT);
305 return sendToSystem(buf.getData(), buf.getPos());
306 }
307
308 return -EINVAL;
309 }
310
setupMgmt(const hub_message_t * appMsg,uint32_t cmd)311 int SystemComm::AppMgmtSession::setupMgmt(const hub_message_t *appMsg, uint32_t cmd)
312 {
313 const hub_app_name_t &appName = *static_cast<const hub_app_name_t*>(appMsg->message);
314 if (appMsg->message_len != sizeof(appName)) {
315 return -EINVAL;
316 }
317
318 char data[MAX_RX_PACKET];
319 MessageBuf buf(data, sizeof(data));
320 buf.writeU8(cmd);
321 writeAppName(buf, appName);
322 setState(MGMT);
323
324 return sendToSystem(buf.getData(), buf.getPos());
325 }
326
handleRx(MessageBuf & buf)327 int SystemComm::AppMgmtSession::handleRx(MessageBuf &buf)
328 {
329 int ret = 0;
330 std::lock_guard<std::mutex> _l(mLock);
331 NanohubRsp rsp(buf);
332
333 switch (getState()) {
334 case TRANSFER:
335 ret = handleTransfer(rsp);
336 break;
337 case FINISH:
338 ret = handleFinish(rsp);
339 break;
340 case RUN:
341 ret = handleRun(rsp);
342 break;
343 case RUN_FAILED:
344 ret = handleRunFailed(rsp);
345 break;
346 case REBOOT:
347 ret = handleReboot(rsp);
348 break;
349 case MGMT:
350 ret = handleMgmt(rsp);
351 break;
352 }
353
354 return ret;
355 }
356
handleTransfer(NanohubRsp & rsp)357 int SystemComm::AppMgmtSession::handleTransfer(NanohubRsp &rsp)
358 {
359 if (rsp.cmd != NANOHUB_CONT_UPLOAD && rsp.cmd != NANOHUB_START_UPLOAD)
360 return 1;
361
362 char data[MAX_RX_PACKET];
363 MessageBuf buf(data, sizeof(data));
364
365 static_assert(NANOHUB_UPLOAD_CHUNK_SZ_MAX <= (MAX_RX_PACKET-5),
366 "Invalid chunk size");
367
368 if (mPos < mLen) {
369 uint32_t chunkSize = mLen - mPos;
370
371 if (chunkSize > NANOHUB_UPLOAD_CHUNK_SZ_MAX) {
372 chunkSize = NANOHUB_UPLOAD_CHUNK_SZ_MAX;
373 }
374
375 buf.writeU8(NANOHUB_CONT_UPLOAD);
376 buf.writeU32(mPos);
377 buf.writeRaw(&mData[mPos], chunkSize);
378 mPos += chunkSize;
379 } else {
380 buf.writeU8(NANOHUB_FINISH_UPLOAD);
381 setState(FINISH);
382 }
383
384 return sendToSystem(buf.getData(), buf.getPos());
385 }
386
handleFinish(NanohubRsp & rsp)387 int SystemComm::AppMgmtSession::handleFinish(NanohubRsp &rsp)
388 {
389 if (rsp.cmd != NANOHUB_FINISH_UPLOAD)
390 return 1;
391
392 int ret = 0;
393 const bool success = rsp.status != 0;
394 mData.clear();
395
396 if (success) {
397 char data[MAX_RX_PACKET];
398 MessageBuf buf(data, sizeof(data));
399 buf.writeU8(NANOHUB_EXT_APPS_ON);
400 writeAppName(buf, mAppName);
401 setState(RUN);
402 ret = sendToSystem(buf.getData(), buf.getPos());
403 } else {
404 int32_t result = NANOHUB_APP_NOT_LOADED;
405
406 sendToApp(mCmd, &result, sizeof(result));
407 complete();
408 }
409
410 return ret;
411 }
412
handleRun(NanohubRsp & rsp)413 int SystemComm::AppMgmtSession::handleRun(NanohubRsp &rsp)
414 {
415 if (rsp.cmd != NANOHUB_EXT_APPS_ON)
416 return 1;
417
418 MgmtStatus sts = { .value = (uint32_t)rsp.status };
419
420 // op counter returns number of nanoapps that were started as result of the command
421 // for successful start command it must be > 0
422 int32_t result = sts.value > 0 && sts.op > 0 && sts.op <= 0x7F ? 0 : -1;
423
424 ALOGI("Nanohub NEW APP START: %08" PRIX32 "\n", rsp.status);
425 if (result != 0) {
426 // if nanoapp failed to start we have to unload it
427 char data[MAX_RX_PACKET];
428 MessageBuf buf(data, sizeof(data));
429 buf.writeU8(NANOHUB_EXT_APP_DELETE);
430 writeAppName(buf, mAppName);
431 if (sendToSystem(buf.getData(), buf.getPos()) == 0) {
432 setState(RUN_FAILED);
433 return 0;
434 }
435 ALOGE("%s: failed to send DELETE for failed app\n", __func__);
436 }
437
438 // it is either success, and we report it, or
439 // it is a failure to load, and also failure to send erase command
440 sendToApp(mCmd, &result, sizeof(result));
441 complete();
442 return 0;
443 }
444
handleRunFailed(NanohubRsp & rsp)445 int SystemComm::AppMgmtSession::handleRunFailed(NanohubRsp &rsp)
446 {
447 if (rsp.cmd != NANOHUB_EXT_APP_DELETE)
448 return 1;
449
450 int32_t result = -1;
451
452 ALOGI("%s: APP DELETE [because it failed]: %08" PRIX32 "\n", __func__, rsp.status);
453
454 sendToApp(mCmd, &result, sizeof(result));
455 complete();
456
457 return 0;
458 }
459
460 /* reboot notification, when triggered by App request */
handleReboot(NanohubRsp & rsp)461 int SystemComm::AppMgmtSession::handleReboot(NanohubRsp &rsp)
462 {
463 if (rsp.cmd != NANOHUB_REBOOT)
464 return 1;
465 ALOGI("Nanohub reboot status [USER REQ]: %08" PRIX32 "\n", rsp.status);
466
467 // reboot notification is sent by SessionManager
468 complete();
469
470 return 0;
471 }
472
handleMgmt(NanohubRsp & rsp)473 int SystemComm::AppMgmtSession::handleMgmt(NanohubRsp &rsp)
474 {
475 bool valid = false;
476
477 int32_t result = rsp.status;
478
479 // TODO: remove this when context hub service can handle non-zero success status
480 if (result > 0) {
481 // something happened; assume it worked
482 result = 0;
483 } else if (result == 0) {
484 // nothing happened; this is provably an error
485 result = -1;
486 }
487
488 switch (rsp.cmd) {
489 case NANOHUB_EXT_APPS_OFF:
490 valid = mCmd == CONTEXT_HUB_APPS_DISABLE;
491 break;
492 case NANOHUB_EXT_APPS_ON:
493 valid = mCmd == CONTEXT_HUB_APPS_ENABLE;
494 break;
495 case NANOHUB_EXT_APP_DELETE:
496 valid = mCmd == CONTEXT_HUB_UNLOAD_APP;
497 break;
498 default:
499 return 1;
500 }
501
502 ALOGI("Nanohub MGMT response: CMD=%02X; STATUS=%08" PRIX32, rsp.cmd, rsp.status);
503 if (!valid) {
504 ALOGE("Invalid response for this state: APP CMD=%02X", mCmd);
505 return -EINVAL;
506 }
507
508 sendToApp(mCmd, &result, sizeof(result));
509 complete();
510
511 return 0;
512 }
513
setup(const hub_message_t *)514 int SystemComm::KeyInfoSession::setup(const hub_message_t *) {
515 std::lock_guard<std::mutex> _l(mLock);
516 mRsaKeyData.clear();
517 setState(SESSION_USER);
518 mStatus = -EBUSY;
519 return requestRsaKeys();
520 }
521
handleRx(MessageBuf & buf)522 int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf)
523 {
524 std::lock_guard<std::mutex> _l(mLock);
525 NanohubRsp rsp(buf, true);
526
527 if (getState() != SESSION_USER) {
528 // invalid state
529 mStatus = -EFAULT;
530 return mStatus;
531 }
532
533 if (buf.getRoom()) {
534 mRsaKeyData.insert(mRsaKeyData.end(),
535 buf.getData() + buf.getPos(),
536 buf.getData() + buf.getSize());
537 return requestRsaKeys();
538 } else {
539 mStatus = 0;
540 complete();
541 return 0;
542 }
543 }
544
requestRsaKeys(void)545 int SystemComm::KeyInfoSession::requestRsaKeys(void)
546 {
547 char data[MAX_RX_PACKET];
548 MessageBuf buf(data, sizeof(data));
549
550 buf.writeU8(NANOHUB_QUERY_APPS);
551 buf.writeU32(mRsaKeyData.size());
552
553 return sendToSystem(buf.getData(), buf.getPos());
554 }
555
doHandleRx(const nano_message * msg)556 int SystemComm::doHandleRx(const nano_message *msg)
557 {
558 //we only care for messages from HostIF
559 if (msg->hdr.appId != mHostIfAppName.id)
560 return 1;
561
562 //they must all be at least 1 byte long
563 if (!msg->hdr.len) {
564 return -EINVAL;
565 }
566 MessageBuf buf(reinterpret_cast<const char*>(msg->data), msg->hdr.len);
567 if (NanoHub::messageTracingEnabled()) {
568 dumpBuffer("SYS -> HAL", mHostIfAppName, 0, buf.getData(), buf.getSize());
569 }
570 int status = mSessions.handleRx(buf);
571 if (status) {
572 // provide default handler for any system message, that is not properly handled
573 dumpBuffer(status > 0 ? "HAL (not handled)" : "HAL (error)",
574 mHostIfAppName, 0, buf.getData(), buf.getSize(), status);
575 status = status > 0 ? 0 : status;
576 }
577
578 return status;
579 }
580
handleRx(MessageBuf & buf)581 int SystemComm::SessionManager::handleRx(MessageBuf &buf)
582 {
583 int status = 1;
584 std::unique_lock<std::mutex> lk(lock);
585
586 // pass message to all active sessions, in arbitrary order
587 // 1st session that handles the message terminates the loop
588 for (auto pos = sessions_.begin(); pos != sessions_.end() && status > 0; next(pos)) {
589 if (!isActive(pos)) {
590 continue;
591 }
592 Session *session = pos->second;
593 status = session->handleRx(buf);
594 if (status < 0) {
595 session->complete();
596 }
597 }
598
599 NanohubRsp rsp(buf);
600 if (rsp.cmd == NANOHUB_REBOOT) {
601 // if this is reboot notification, kill all sessions
602 for (auto pos = sessions_.begin(); pos != sessions_.end(); next(pos)) {
603 if (!isActive(pos)) {
604 continue;
605 }
606 Session *session = pos->second;
607 session->abort(-EINTR);
608 }
609 lk.unlock();
610 // log the reboot event, if not handled
611 if (status > 0) {
612 ALOGW("Nanohub reboot status [UNSOLICITED]: %08" PRIX32, rsp.status);
613 status = 0;
614 }
615 // report to java apps
616 sendToApp(CONTEXT_HUB_OS_REBOOT, &rsp.status, sizeof(rsp.status));
617 }
618
619 return status;
620 }
621
setup_and_add(int id,Session * session,const hub_message_t * appMsg)622 int SystemComm::SessionManager::setup_and_add(int id, Session *session, const hub_message_t *appMsg)
623 {
624 std::lock_guard<std::mutex> _l(lock);
625
626 // scan sessions to release those that are already done
627 for (auto pos = sessions_.begin(); pos != sessions_.end(); next(pos)) {
628 continue;
629 }
630
631 if (sessions_.count(id) == 0 && !session->isRunning()) {
632 sessions_[id] = session;
633 int ret = session->setup(appMsg);
634 if (ret < 0) {
635 session->complete();
636 }
637 return ret;
638 }
639 return -EBUSY;
640 }
641
doHandleTx(const hub_message_t * appMsg)642 int SystemComm::doHandleTx(const hub_message_t *appMsg)
643 {
644 int status = 0;
645
646 switch (appMsg->message_type) {
647 case CONTEXT_HUB_LOAD_APP:
648 if (!mKeySession.haveKeys()) {
649 status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mKeySession, appMsg);
650 if (status < 0) {
651 break;
652 }
653 mKeySession.wait();
654 status = mKeySession.getStatus();
655 if (status < 0) {
656 break;
657 }
658 }
659 status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg);
660 break;
661 case CONTEXT_HUB_APPS_ENABLE:
662 case CONTEXT_HUB_APPS_DISABLE:
663 case CONTEXT_HUB_UNLOAD_APP:
664 // all APP-modifying commands share session key, to ensure they can't happen at the same time
665 status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg);
666 break;
667
668 case CONTEXT_HUB_QUERY_APPS:
669 status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_APPS, &mAppInfoSession, appMsg);
670 break;
671
672 case CONTEXT_HUB_QUERY_MEMORY:
673 status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_MEMORY, &mMemInfoSession, appMsg);
674 break;
675
676 default:
677 ALOGW("Unknown os message type %u\n", appMsg->message_type);
678 return -EINVAL;
679 }
680
681 return status;
682 }
683
684 }; // namespace nanohub
685
686 }; // namespace android
687