AppPlatformShellCommands-JNI.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. *
  3. * Copyright (c) 2022 Project CHIP Authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "AppPlatformShellCommands-JNI.h"
  18. #include "AppImpl.h"
  19. #include "TvApp-JNI.h"
  20. #include <access/AccessControl.h>
  21. #include <jni.h>
  22. #include <lib/core/CHIPError.h>
  23. #include <lib/support/CHIPJNIError.h>
  24. #include <lib/support/JniReferences.h>
  25. #include <lib/support/JniTypeWrappers.h>
  26. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  27. #include <app/app-platform/ContentAppPlatform.h>
  28. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  29. using namespace chip;
  30. char response[1024];
  31. using namespace ::chip::Controller;
  32. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  33. using namespace chip::AppPlatform;
  34. using namespace chip::Access;
  35. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  36. using namespace chip::app::Clusters;
  37. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  38. static CHIP_ERROR pairApp(bool printHeader, size_t index)
  39. {
  40. if (printHeader)
  41. {
  42. char str[64];
  43. sprintf(str, "udc-commission %ld\r\n", static_cast<long>(index));
  44. strcat(response, str);
  45. }
  46. DeviceCommissioner * commissioner = GetDeviceCommissioner();
  47. UDCClientState * state = commissioner->GetUserDirectedCommissioningServer()->GetUDCClients().GetUDCClientState(index);
  48. if (state == nullptr)
  49. {
  50. char str[64];
  51. sprintf(str, "udc client[%ld] null \r\n", static_cast<long>(index));
  52. strcat(response, str);
  53. }
  54. else
  55. {
  56. ContentApp * app = ContentAppPlatform::GetInstance().LoadContentAppByClient(state->GetVendorId(), state->GetProductId());
  57. if (app == nullptr)
  58. {
  59. char str[64];
  60. sprintf(str, "no app found for vendor id=%d \r\n", state->GetVendorId());
  61. strcat(response, str);
  62. return CHIP_ERROR_BAD_REQUEST;
  63. }
  64. if (app->GetAccountLoginDelegate() == nullptr)
  65. {
  66. char str[64];
  67. sprintf(str, "no AccountLogin cluster for app with vendor id=%d \r\n", state->GetVendorId());
  68. strcat(response, str);
  69. return CHIP_ERROR_BAD_REQUEST;
  70. }
  71. char rotatingIdString[chip::Dnssd::kMaxRotatingIdLen * 2 + 1] = "";
  72. Encoding::BytesToUppercaseHexString(state->GetRotatingId(), state->GetRotatingIdLength(), rotatingIdString,
  73. sizeof(rotatingIdString));
  74. CharSpan rotatingIdSpan = CharSpan(rotatingIdString, strlen(rotatingIdString));
  75. static const size_t kSetupPinSize = 12;
  76. char setupPin[kSetupPinSize];
  77. app->GetAccountLoginDelegate()->GetSetupPin(setupPin, kSetupPinSize, rotatingIdSpan);
  78. std::string pinString(setupPin);
  79. char * eptr;
  80. uint32_t pincode = (uint32_t) strtol(pinString.c_str(), &eptr, 10);
  81. if (pincode == 0)
  82. {
  83. char str[64];
  84. sprintf(str, "udc no pin returned for vendor id=%d rotating ID=%s \r\n", state->GetVendorId(), rotatingIdString);
  85. strcat(response, str);
  86. return CHIP_ERROR_BAD_REQUEST;
  87. }
  88. return CommissionerPairUDC(pincode, index);
  89. }
  90. return CHIP_NO_ERROR;
  91. }
  92. void DumpAccessControlEntry(const Access::AccessControl::Entry & entry)
  93. {
  94. CHIP_ERROR err;
  95. {
  96. FabricIndex fabricIndex;
  97. SuccessOrExit(err = entry.GetFabricIndex(fabricIndex));
  98. char str[64];
  99. sprintf(str, "fabricIndex: %u\n", fabricIndex);
  100. strcat(response, str);
  101. }
  102. {
  103. Privilege privilege;
  104. SuccessOrExit(err = entry.GetPrivilege(privilege));
  105. char str[64];
  106. sprintf(str, "privilege: %d\n", to_underlying(privilege));
  107. strcat(response, str);
  108. }
  109. {
  110. AuthMode authMode;
  111. SuccessOrExit(err = entry.GetAuthMode(authMode));
  112. char str[64];
  113. sprintf(str, "authMode: %d\n", to_underlying(authMode));
  114. strcat(response, str);
  115. }
  116. {
  117. size_t count;
  118. SuccessOrExit(err = entry.GetSubjectCount(count));
  119. if (count)
  120. {
  121. char str[64];
  122. sprintf(str, "subjects: %u\n", static_cast<unsigned>(count));
  123. strcat(response, str);
  124. for (size_t i = 0; i < count; ++i)
  125. {
  126. NodeId subject;
  127. SuccessOrExit(err = entry.GetSubject(i, subject));
  128. char buffer[64];
  129. sprintf(buffer, " %u: 0x" ChipLogFormatX64, static_cast<unsigned>(i), ChipLogValueX64(subject));
  130. strcat(response, buffer);
  131. }
  132. }
  133. }
  134. {
  135. size_t count;
  136. SuccessOrExit(err = entry.GetTargetCount(count));
  137. if (count)
  138. {
  139. char str[64];
  140. sprintf(str, "\ntargets: %u\n", static_cast<unsigned>(count));
  141. strcat(response, str);
  142. for (size_t i = 0; i < count; ++i)
  143. {
  144. Access::AccessControl::Entry::Target target;
  145. SuccessOrExit(err = entry.GetTarget(i, target));
  146. char buffer[64];
  147. if (target.flags & Access::AccessControl::Entry::Target::kCluster)
  148. {
  149. sprintf(buffer, " %u: cluster: 0x" ChipLogFormatMEI, static_cast<unsigned>(i),
  150. ChipLogValueMEI(target.cluster));
  151. strcat(buffer, "\n");
  152. strcat(response, buffer);
  153. }
  154. if (target.flags & Access::AccessControl::Entry::Target::kEndpoint)
  155. {
  156. sprintf(buffer, " %u: endpoint: %u", static_cast<unsigned>(i), target.endpoint);
  157. strcat(buffer, "\n");
  158. strcat(response, buffer);
  159. }
  160. if (target.flags & Access::AccessControl::Entry::Target::kDeviceType)
  161. {
  162. sprintf(buffer, " %u: deviceType: 0x" ChipLogFormatMEI, static_cast<unsigned>(i),
  163. ChipLogValueMEI(target.deviceType));
  164. strcat(buffer, "\n");
  165. strcat(response, buffer);
  166. }
  167. }
  168. }
  169. }
  170. strcat(response, "----- END ENTRY -----\n");
  171. exit:
  172. if (err != CHIP_NO_ERROR)
  173. {
  174. ChipLogError(DeviceLayer, "DumpAccessControlEntry: dump failed %" CHIP_ERROR_FORMAT, err.Format());
  175. strcpy(response, "Error occurred");
  176. }
  177. }
  178. char * AppPlatformHandler(int argc, char ** argv)
  179. {
  180. CHIP_ERROR err;
  181. if (argc == 0 || strcmp(argv[0], "help") == 0)
  182. {
  183. strcpy(response, "check usage instructions on the UI");
  184. }
  185. else if (strcmp(argv[0], "add-admin-vendor") == 0)
  186. {
  187. if (argc < 2)
  188. {
  189. strcpy(response, "check usage instructions on the UI");
  190. }
  191. char * eptr;
  192. uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10);
  193. ContentAppFactoryImpl * factory = GetContentAppFactoryImpl();
  194. factory->AddAdminVendorId(vid);
  195. ChipLogProgress(DeviceLayer, "added admin-vendor");
  196. strcpy(response, "added admin-vendor");
  197. return response;
  198. }
  199. else if (strcmp(argv[0], "add") == 0)
  200. {
  201. if (argc < 2)
  202. {
  203. strcpy(response, "check usage instructions on the UI");
  204. }
  205. char * eptr;
  206. uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10);
  207. uint16_t pid = 0;
  208. if (argc >= 3)
  209. {
  210. pid = (uint16_t) strtol(argv[2], &eptr, 10);
  211. }
  212. ContentAppPlatform::GetInstance().LoadContentAppByClient(vid, pid);
  213. ChipLogProgress(DeviceLayer, "added app");
  214. strcpy(response, "added app");
  215. return response;
  216. }
  217. else if (strcmp(argv[0], "print-app-access") == 0)
  218. {
  219. Access::AccessControl::EntryIterator iterator;
  220. SuccessOrExit(err = Access::GetAccessControl().Entries(GetDeviceCommissioner()->GetFabricIndex(), iterator));
  221. // clear entry
  222. strcpy(response, "");
  223. Access::AccessControl::Entry entry;
  224. while (iterator.Next(entry) == CHIP_NO_ERROR)
  225. {
  226. DumpAccessControlEntry(entry);
  227. }
  228. return response;
  229. }
  230. else if (strcmp(argv[0], "remove-app-access") == 0)
  231. {
  232. Access::GetAccessControl().DeleteAllEntriesForFabric(GetDeviceCommissioner()->GetFabricIndex());
  233. strcpy(response, "removed app access");
  234. return response;
  235. }
  236. else if (strcmp(argv[0], "remove") == 0)
  237. {
  238. if (argc < 2)
  239. {
  240. strcpy(response, "check usage instructions on the UI");
  241. }
  242. char * eptr;
  243. uint16_t endpoint = (uint16_t) strtol(argv[1], &eptr, 10);
  244. ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint);
  245. if (app == nullptr)
  246. {
  247. ChipLogProgress(DeviceLayer, "app not found");
  248. strcpy(response, "app not found");
  249. return response;
  250. }
  251. ContentAppPlatform::GetInstance().RemoveContentApp(app);
  252. ChipLogProgress(DeviceLayer, "removed app");
  253. strcpy(response, "removed app");
  254. return response;
  255. }
  256. else if (strcmp(argv[0], "setpin") == 0)
  257. {
  258. if (argc < 3)
  259. {
  260. strcpy(response, "check usage instructions on the UI");
  261. }
  262. char * eptr;
  263. uint16_t endpoint = (uint16_t) strtol(argv[1], &eptr, 10);
  264. char * pincode = argv[2];
  265. ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint);
  266. if (app == nullptr)
  267. {
  268. ChipLogProgress(DeviceLayer, "app not found");
  269. strcpy(response, "app not found");
  270. return response;
  271. }
  272. if (app->GetAccountLoginDelegate() == nullptr)
  273. {
  274. ChipLogProgress(DeviceLayer, "no AccountLogin cluster for app with endpoint id=%d ", endpoint);
  275. strcpy(response, "no AccountLogin cluster for app with endpoint");
  276. return response;
  277. }
  278. app->GetAccountLoginDelegate()->SetSetupPin(pincode);
  279. ChipLogProgress(DeviceLayer, "set pin success");
  280. strcpy(response, "set pin success");
  281. return response;
  282. }
  283. else if (strcmp(argv[0], "commission") == 0)
  284. {
  285. if (argc < 2)
  286. {
  287. strcpy(response, "check usage instructions on the UI");
  288. }
  289. char * eptr;
  290. size_t index = (size_t) strtol(argv[1], &eptr, 10);
  291. SuccessOrExit(err = pairApp(true, index));
  292. return response;
  293. }
  294. else
  295. {
  296. strcpy(response, "invalid argument");
  297. return response;
  298. }
  299. return response;
  300. exit:
  301. ChipLogError(DeviceLayer, "Error: %" CHIP_ERROR_FORMAT, err.Format());
  302. strcpy(response, "Error occurred");
  303. return response;
  304. }
  305. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  306. #define JNI_METHOD(RETURN, METHOD_NAME) \
  307. extern "C" JNIEXPORT RETURN JNICALL Java_com_matter_tv_server_tvapp_AppPlatformShellCommands_##METHOD_NAME
  308. JNI_METHOD(jstring, OnExecuteCommand)(JNIEnv * env, jobject, jobjectArray stringArray)
  309. {
  310. int argc = env->GetArrayLength(stringArray);
  311. char ** argv = new char *[(uint) argc];
  312. // Fill in argv
  313. for (int i = 0; i < argc; i++)
  314. {
  315. jstring string = (jstring)(env->GetObjectArrayElement(stringArray, i));
  316. argv[i] = (char *) env->GetStringUTFChars(string, 0);
  317. }
  318. // Store response to show it to the users
  319. char * buf = AppPlatformHandler(argc, argv);
  320. // Release UTF Chars
  321. for (int i = 0; i < argc; i++)
  322. {
  323. ChipLogProgress(DeviceLayer, " Value=%s ", argv[i]);
  324. jstring string = (jstring)(env->GetObjectArrayElement(stringArray, i));
  325. env->ReleaseStringUTFChars(string, argv[i]);
  326. }
  327. return env->NewStringUTF(buf);
  328. }