appl_sample_example_5.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. /**
  2. * \file appl_sample_example_5.c
  3. *
  4. * Source File for Generic OnOff Server and Light Lightness Server
  5. * Standalone application without CLI or menu based console input interface.
  6. * In this example, the server models are part of two different elements.
  7. */
  8. /*
  9. * Copyright (C) 2018. Mindtree Ltd.
  10. * All rights reserved.
  11. */
  12. #if (MESH_STANDALONE == 5)
  13. /* ----------------------------------------- Header File Inclusion */
  14. #include "MS_common.h"
  15. #include "MS_access_api.h"
  16. #include "MS_config_api.h"
  17. #include "MS_health_server_api.h"
  18. #include "MS_generic_onoff_api.h"
  19. #include "MS_light_lightness_api.h"
  20. #include "blebrr.h"
  21. #include "nvsto.h"
  22. #include "model_state_handler_pl.h"
  23. /* Console Input/Output */
  24. #define CONSOLE_OUT(...) printf(__VA_ARGS__)
  25. #define CONSOLE_IN(...) scanf(__VA_ARGS__)
  26. void appl_dump_bytes(UCHAR *buffer, UINT16 length);
  27. void appl_mesh_sample (void);
  28. /* ----------------------------------------- External Global Variables */
  29. /* ----------------------------------------- Exported Global Variables */
  30. /* ----------------------------------------- Static Global Variables */
  31. /* ----------------------------------------- Functions */
  32. /* Model Server - Foundation Models */
  33. /* Health Server - Test Routines */
  34. static void UI_health_self_test_00(UINT8 test_id, UINT16 company_id)
  35. {
  36. }
  37. static void UI_health_self_test_01(UINT8 test_id, UINT16 company_id)
  38. {
  39. }
  40. static void UI_health_self_test_FF(UINT8 test_id, UINT16 company_id)
  41. {
  42. }
  43. /* List of Self Tests */
  44. static MS_HEALTH_SERVER_SELF_TEST UI_health_server_self_tests[] =
  45. {
  46. {
  47. 0x00, /* Test ID: 0x00 */
  48. UI_health_self_test_00
  49. },
  50. {
  51. 0x01, /* Test ID: 0x01 */
  52. UI_health_self_test_01
  53. },
  54. {
  55. 0xFF, /* Test ID: 0xFF */
  56. UI_health_self_test_FF
  57. }
  58. };
  59. /**
  60. * \brief Health Server application Asynchronous Notification Callback.
  61. *
  62. * \par Description
  63. * Health Server calls the registered callback to indicate events occurred to the
  64. * application.
  65. *
  66. * \param handle Model Handle.
  67. * \param event_type Health Server Event type.
  68. * \param event_param Parameter associated with the event if any or NULL.
  69. * \param param_len Size of the event parameter data. 0 if event param is NULL.
  70. */
  71. static API_RESULT UI_health_server_cb
  72. (
  73. MS_ACCESS_MODEL_HANDLE * handle,
  74. UINT8 event_type,
  75. UINT8 * event_param,
  76. UINT16 param_len
  77. )
  78. {
  79. CONSOLE_OUT(
  80. "Health Server Callback. Not handled. Returning\n");
  81. return API_SUCCESS;
  82. }
  83. API_RESULT UI_register_foundation_model_servers
  84. (
  85. MS_ACCESS_ELEMENT_HANDLE element_handle
  86. )
  87. {
  88. /* Configuration Server */
  89. MS_ACCESS_MODEL_HANDLE UI_config_server_model_handle;
  90. MS_ACCESS_MODEL_HANDLE UI_health_server_model_handle;
  91. API_RESULT retval;
  92. /* Health Server */
  93. UINT16 company_id;
  94. MS_HEALTH_SERVER_SELF_TEST * self_tests;
  95. UINT32 num_self_tests;
  96. CONSOLE_OUT("In Model Server - Foundation Models\n");
  97. retval = MS_config_server_init(element_handle, &UI_config_server_model_handle);
  98. CONSOLE_OUT("Config Model Server Registration Status: 0x%04X\n", retval);
  99. /* Health Server */
  100. company_id = MS_DEFAULT_COMPANY_ID;
  101. self_tests = &UI_health_server_self_tests[0];
  102. num_self_tests = sizeof(UI_health_server_self_tests)/sizeof(MS_HEALTH_SERVER_SELF_TEST);
  103. retval = MS_health_server_init
  104. (
  105. element_handle,
  106. &UI_health_server_model_handle,
  107. company_id,
  108. self_tests,
  109. num_self_tests,
  110. UI_health_server_cb
  111. );
  112. if (API_SUCCESS == retval)
  113. {
  114. CONSOLE_OUT(
  115. "Health Server Initialized. Model Handle: 0x%04X\n",
  116. UI_health_server_model_handle);
  117. }
  118. else
  119. {
  120. CONSOLE_OUT(
  121. "[ERR] Sensor Server Initialization Failed. Result: 0x%04X\n",
  122. retval);
  123. }
  124. return retval;
  125. }
  126. /* ---- Generic OnOff States */
  127. static MS_STATE_GENERIC_ONOFF_STRUCT UI_generic_onoff;
  128. /** -- Light - Lightness */
  129. static MS_STATE_LIGHT_LIGHTNESS_STRUCT UI_light_lightness;
  130. /* Get/Set State Handlers */
  131. /* Generic OnOff Model state Initialization */
  132. void UI_generic_onoff_model_states_initialization(void)
  133. {
  134. EM_mem_set(&UI_generic_onoff, 0, sizeof(UI_generic_onoff));
  135. }
  136. /* Generic OnOff Model Get Handler */
  137. API_RESULT UI_generic_onoff_model_state_get(UINT16 state_t, UINT16 state_inst, void * param, UINT8 direction)
  138. {
  139. API_RESULT retval;
  140. retval = API_SUCCESS;
  141. switch(state_t)
  142. {
  143. case MS_STATE_GENERIC_ONOFF_T:
  144. {
  145. MS_STATE_GENERIC_ONOFF_STRUCT * param_p;
  146. param_p = (MS_STATE_GENERIC_ONOFF_STRUCT *)param;
  147. /* Ignoring Instance and direction right now */
  148. *param_p = UI_generic_onoff;
  149. }
  150. break;
  151. default:
  152. break;
  153. }
  154. return retval;
  155. }
  156. /* Generic OnOff Model Set Handler */
  157. API_RESULT UI_generic_onoff_model_state_set(UINT16 state_t, UINT16 state_inst, void * param, UINT8 direction)
  158. {
  159. API_RESULT retval;
  160. retval = API_SUCCESS;
  161. switch (state_t)
  162. {
  163. case MS_STATE_GENERIC_ONOFF_T:
  164. {
  165. MS_STATE_GENERIC_ONOFF_STRUCT * param_p;
  166. param_p = (MS_STATE_GENERIC_ONOFF_STRUCT *)param;
  167. /* Instantaneous Change */
  168. UI_generic_onoff.onoff = param_p->onoff;
  169. *param_p = UI_generic_onoff;
  170. CONSOLE_OUT("[state] current: 0x%02X\n", UI_generic_onoff.onoff);
  171. CONSOLE_OUT("[state] target: 0x%02X\n", UI_generic_onoff.target_onoff);
  172. CONSOLE_OUT("[state] remaining_time: 0x%02X\n", UI_generic_onoff.transition_time);
  173. generic_onoff_set_pl(param_p->onoff);
  174. /* Ignoring Instance and direction right now */
  175. }
  176. break;
  177. default:
  178. break;
  179. }
  180. return retval;
  181. }
  182. /* Light Lightness Model state Initialization */
  183. void UI_light_lightness_model_states_initialization(void)
  184. {
  185. /* Light Lightness States */
  186. EM_mem_set(&UI_light_lightness, 0, sizeof(UI_light_lightness));
  187. UI_light_lightness.light_lightness_last.lightness_last = 0xFFFF;
  188. }
  189. /* Light Lightness Model Get Handler */
  190. API_RESULT UI_light_lightness_model_state_get(UINT16 state_t, UINT16 state_inst, void * param, UINT8 direction)
  191. {
  192. MS_STATE_LIGHT_LIGHTNESS_STRUCT * param_p;
  193. API_RESULT retval;
  194. param_p = (MS_STATE_LIGHT_LIGHTNESS_STRUCT *)param;
  195. retval = API_SUCCESS;
  196. switch(state_t)
  197. {
  198. case MS_STATE_LIGHT_LIGHTNESS_DEFAULT_T:
  199. {
  200. /* Ignoring Instance and direction right now */
  201. param_p->light_lightness_default = UI_light_lightness.light_lightness_default;
  202. }
  203. break;
  204. case MS_STATE_LIGHT_LIGHTNESS_RANGE_T:
  205. {
  206. /* Ignoring Instance and direction right now */
  207. param_p->light_lightness_range = UI_light_lightness.light_lightness_range;
  208. param_p->range_status = 0x00;
  209. }
  210. break;
  211. case MS_STATE_LIGHT_LIGHTNESS_LINEAR_T:
  212. {
  213. /* Ignoring Instance and direction right now */
  214. param_p->light_lightness_linear = UI_light_lightness.light_lightness_linear;
  215. }
  216. break;
  217. case MS_STATE_LIGHT_LIGHTNESS_LAST_T:
  218. {
  219. /* Ignoring Instance and direction right now */
  220. param_p->light_lightness_last = UI_light_lightness.light_lightness_last;
  221. }
  222. break;
  223. case MS_STATE_LIGHT_LIGHTNESS_ACTUAL_T:
  224. {
  225. /* Ignoring Instance and direction right now */
  226. param_p->light_lightness_actual = UI_light_lightness.light_lightness_actual;
  227. }
  228. break;
  229. default:
  230. break;
  231. }
  232. return retval;
  233. }
  234. /* Light Lightness Model Set Handler */
  235. /* Todo: Remove the dependency */
  236. #include "math.h"
  237. static void UI_light_lightness_set_actual(UINT16 state_inst, UINT16 actual)
  238. {
  239. UINT16 min, max;
  240. /* Generic OnOff binding */
  241. min = UI_light_lightness.light_lightness_range.lightness_range_min;
  242. max = UI_light_lightness.light_lightness_range.lightness_range_max;
  243. if ((0 != min) && (actual < min))
  244. {
  245. actual = min;
  246. }
  247. else if ((0 != max) && (actual > max))
  248. {
  249. actual = max;
  250. }
  251. /* If Lightness Actual is non-zero, save as Lightness Last */
  252. if (0x0000 != actual)
  253. {
  254. UI_light_lightness.light_lightness_last.lightness_last = actual;
  255. }
  256. UI_light_lightness.light_lightness_actual.lightness_actual = actual;
  257. /* Light Lightness Linear = ((Actual)^2) / 65535 */
  258. UI_light_lightness.light_lightness_linear.lightness_linear = ((actual * actual) + 65534) / 65535;
  259. }
  260. static void UI_light_lightness_set_linear(UINT16 state_inst, UINT16 linear)
  261. {
  262. UINT16 actual;
  263. UINT32 mul_val;
  264. mul_val = linear * 65535;
  265. actual = (UINT16)sqrt(mul_val);
  266. /* Light Lightness actual = sqrt(Linear * 65535) */
  267. UI_light_lightness_set_actual(state_inst, actual);
  268. }
  269. API_RESULT UI_light_lightness_model_state_set(UINT16 state_t, UINT16 state_inst, void * param, UINT8 direction)
  270. {
  271. MS_STATE_LIGHT_LIGHTNESS_STRUCT * param_p;
  272. API_RESULT retval;
  273. param_p = (MS_STATE_LIGHT_LIGHTNESS_STRUCT *)param;
  274. retval = API_SUCCESS;
  275. switch (state_t)
  276. {
  277. case MS_STATE_LIGHT_LIGHTNESS_DEFAULT_T:
  278. {
  279. /* Ignoring Instance and direction right now */
  280. UI_light_lightness.light_lightness_default = param_p->light_lightness_default;
  281. }
  282. break;
  283. case MS_STATE_LIGHT_LIGHTNESS_RANGE_T:
  284. {
  285. /* Check range min and max */
  286. if (param_p->light_lightness_range.lightness_range_min > param_p->light_lightness_range.lightness_range_max)
  287. {
  288. /* TODO: add macro define */
  289. /**
  290. * Table 7.2:
  291. * 0x00 - Success
  292. * 0x01 - Cannot Set Range Min
  293. * 0x02 - Cannot Set Range Max
  294. */
  295. param_p->range_status = 0x01;
  296. }
  297. else
  298. {
  299. /* Ignoring Instance and direction right now */
  300. UI_light_lightness.light_lightness_range = param_p->light_lightness_range;
  301. param_p->range_status = 0x00;
  302. }
  303. }
  304. break;
  305. case MS_STATE_LIGHT_LIGHTNESS_LINEAR_T:
  306. {
  307. /* Instantaneous Change */
  308. UI_light_lightness_set_linear(0, param_p->light_lightness_linear.lightness_linear);
  309. *param_p = UI_light_lightness;
  310. CONSOLE_OUT("[state] current: 0x%02X\n", param_p->light_lightness_linear.lightness_linear);
  311. CONSOLE_OUT("[state] target: 0x%02X\n", param_p->light_lightness_linear.lightness_target);
  312. CONSOLE_OUT("[state] remaining_time: 0x%02X\n", param_p->light_lightness_linear.transition_time);
  313. /* Ignoring Instance and direction right now */
  314. }
  315. break;
  316. case MS_STATE_LIGHT_LIGHTNESS_LAST_T:
  317. {
  318. /* Ignoring Instance and direction right now */
  319. UI_light_lightness.light_lightness_last = param_p->light_lightness_last;
  320. }
  321. break;
  322. case MS_STATE_LIGHT_LIGHTNESS_ACTUAL_T:
  323. {
  324. /* Instantaneous Change */
  325. UI_light_lightness_set_actual(0, param_p->light_lightness_actual.lightness_actual);
  326. *param_p = UI_light_lightness;
  327. CONSOLE_OUT("[state] current: 0x%02X\n", param_p->light_lightness_actual.lightness_actual);
  328. CONSOLE_OUT("[state] target: 0x%02X\n", param_p->light_lightness_actual.lightness_target);
  329. CONSOLE_OUT("[state] remaining_time: 0x%02X\n", param_p->light_lightness_actual.transition_time);
  330. }
  331. break;
  332. default:
  333. break;
  334. }
  335. return retval;
  336. }
  337. /* Model state Initialization */
  338. void UI_model_states_initialization(void)
  339. {
  340. /* Generic OnOff States */
  341. UI_generic_onoff_model_states_initialization();
  342. /* Light Lightness States */
  343. UI_light_lightness_model_states_initialization();
  344. }
  345. /* Generic OnOff Model Server */
  346. /**
  347. * \brief Server Application Asynchronous Notification Callback.
  348. *
  349. * \par Description
  350. * Generic_Onoff server calls the registered callback to indicate events occurred to the application.
  351. *
  352. * \param [in] ctx Context of message received for a specific model instance.
  353. * \param [in] msg_raw Uninterpreted/raw received message.
  354. * \param [in] req_type Requested message type.
  355. * \param [in] state_params Model specific state parameters.
  356. * \param [in] ext_params Additional parameters.
  357. */
  358. API_RESULT UI_generic_onoff_server_cb
  359. (
  360. /* IN */ MS_ACCESS_MODEL_REQ_MSG_CONTEXT * ctx,
  361. /* IN */ MS_ACCESS_MODEL_REQ_MSG_RAW * msg_raw,
  362. /* IN */ MS_ACCESS_MODEL_REQ_MSG_T * req_type,
  363. /* IN */ MS_ACCESS_MODEL_STATE_PARAMS * state_params,
  364. /* IN */ MS_ACCESS_MODEL_EXT_PARAMS * ext_params
  365. )
  366. {
  367. MS_STATE_GENERIC_ONOFF_STRUCT param;
  368. MS_ACCESS_MODEL_STATE_PARAMS current_state_params;
  369. API_RESULT retval;
  370. retval = API_SUCCESS;
  371. /* Check message type */
  372. if (MS_ACCESS_MODEL_REQ_MSG_T_GET == req_type->type)
  373. {
  374. CONSOLE_OUT("[GENERIC_ONOFF] GET Request.\n");
  375. UI_generic_onoff_model_state_get(state_params->state_type, 0, &param, 0);
  376. current_state_params.state_type = state_params->state_type;
  377. current_state_params.state = &param;
  378. /* Using same as target state and remaining time as 0 */
  379. }
  380. else if (MS_ACCESS_MODEL_REQ_MSG_T_SET == req_type->type)
  381. {
  382. CONSOLE_OUT("[GENERIC_ONOFF] SET Request.\n");
  383. retval = UI_generic_onoff_model_state_set(state_params->state_type, 0, (MS_STATE_GENERIC_ONOFF_STRUCT *)state_params->state, 0);
  384. current_state_params.state_type = state_params->state_type;
  385. current_state_params.state = (MS_STATE_GENERIC_ONOFF_STRUCT *)state_params->state;
  386. }
  387. /* See if to be acknowledged */
  388. if (0x01 == req_type->to_be_acked)
  389. {
  390. CONSOLE_OUT("[GENERIC_ONOFF] Sending Response.\n");
  391. /* Parameters: Request Context, Current State, Target State (NULL: to be ignored), Remaining Time (0: to be ignored), Additional Parameters (NULL: to be ignored) */
  392. retval = MS_generic_onoff_server_state_update(ctx, &current_state_params, NULL, 0, NULL);
  393. }
  394. return retval;
  395. }
  396. API_RESULT UI_register_generic_onoff_model_server
  397. (
  398. MS_ACCESS_ELEMENT_HANDLE element_handle
  399. )
  400. {
  401. /* Generic OnOff Server */
  402. MS_ACCESS_MODEL_HANDLE UI_generic_onoff_server_model_handle;
  403. API_RESULT retval;
  404. CONSOLE_OUT("In Generic OnOff Model Server\n");
  405. retval = MS_generic_onoff_server_init
  406. (
  407. element_handle,
  408. &UI_generic_onoff_server_model_handle,
  409. UI_generic_onoff_server_cb
  410. );
  411. if (API_SUCCESS == retval)
  412. {
  413. CONSOLE_OUT(
  414. "Generic Onoff Server Initialized. Model Handle: 0x%04X\n",
  415. UI_generic_onoff_server_model_handle);
  416. }
  417. else
  418. {
  419. CONSOLE_OUT(
  420. "[ERR] Generic Onoff Server Initialization Failed. Result: 0x%04X\n",
  421. retval);
  422. }
  423. return retval;
  424. }
  425. /* Light Ligthness Model Server */
  426. /**
  427. * \brief Server Application Asynchronous Notification Callback.
  428. *
  429. * \par Description
  430. * Light_Lightness server calls the registered callback to indicate events occurred to the application.
  431. *
  432. * \param [in] ctx Context of message received for a specific model instance.
  433. * \param [in] msg_raw Uninterpreted/raw received message.
  434. * \param [in] req_type Requested message type.
  435. * \param [in] state_params Model specific state parameters.
  436. * \param [in] ext_params Additional parameters.
  437. */
  438. API_RESULT UI_light_lightness_server_cb
  439. (
  440. /* IN */ MS_ACCESS_MODEL_REQ_MSG_CONTEXT * ctx,
  441. /* IN */ MS_ACCESS_MODEL_REQ_MSG_RAW * msg_raw,
  442. /* IN */ MS_ACCESS_MODEL_REQ_MSG_T * req_type,
  443. /* IN */ MS_ACCESS_MODEL_STATE_PARAMS * state_params,
  444. /* IN */ MS_ACCESS_MODEL_EXT_PARAMS * ext_params
  445. )
  446. {
  447. MS_STATE_LIGHT_LIGHTNESS_STRUCT param;
  448. MS_ACCESS_MODEL_STATE_PARAMS current_state_params;
  449. API_RESULT retval;
  450. retval = API_SUCCESS;
  451. /* Check message type */
  452. if (MS_ACCESS_MODEL_REQ_MSG_T_GET == req_type->type)
  453. {
  454. CONSOLE_OUT(
  455. "[LIGHT_LIGHTNESS] GET Request.\n");
  456. UI_light_lightness_model_state_get(state_params->state_type, 0, &param, 0);
  457. current_state_params.state_type = state_params->state_type;
  458. current_state_params.state = &param;
  459. }
  460. else if (MS_ACCESS_MODEL_REQ_MSG_T_SET == req_type->type)
  461. {
  462. CONSOLE_OUT(
  463. "[LIGHT_LIGHTNESS] SET Request.\n");
  464. UI_light_lightness_model_state_set(state_params->state_type, 0, (MS_STATE_LIGHT_LIGHTNESS_STRUCT *)state_params->state, 0);
  465. current_state_params.state_type = state_params->state_type;
  466. current_state_params.state = (MS_STATE_LIGHT_LIGHTNESS_STRUCT *)state_params->state;
  467. }
  468. /* See if to be acknowledged */
  469. if (0x01 == req_type->to_be_acked)
  470. {
  471. CONSOLE_OUT(
  472. "[LIGHT_LIGHTNESS] Sending Response.\n");
  473. /* Parameters: Request Context, Current State, Target State (NULL: to be ignored), Remaining Time (0: to be ignored), Additional Parameters (NULL: to be ignored) */
  474. retval = MS_light_lightness_server_state_update(ctx, &current_state_params, NULL, 0, NULL);
  475. }
  476. return retval;
  477. }
  478. API_RESULT UI_register_light_lightness_model_server
  479. (
  480. MS_ACCESS_ELEMENT_HANDLE element_handle
  481. )
  482. {
  483. /* Generic OnOff Server */
  484. MS_ACCESS_MODEL_HANDLE UI_light_lightness_server_model_handle;
  485. API_RESULT retval;
  486. retval = MS_light_lightness_server_init
  487. (
  488. element_handle,
  489. &UI_light_lightness_server_model_handle,
  490. UI_light_lightness_server_cb
  491. );
  492. if (API_SUCCESS == retval)
  493. {
  494. CONSOLE_OUT(
  495. "Light Lightness Server Initialized. Model Handle: 0x%04X\n",
  496. UI_light_lightness_server_model_handle);
  497. }
  498. else
  499. {
  500. CONSOLE_OUT(
  501. "[ERR] Light Lightness Server Initialization Failed. Result: 0x%04X\n",
  502. retval);
  503. }
  504. return retval;
  505. }
  506. /* Provisionee */
  507. #define UI_PROV_OUTPUT_OOB_ACTIONS \
  508. (PROV_MASK_OOOB_ACTION_BLINK | PROV_MASK_OOOB_ACTION_BEEP | \
  509. PROV_MASK_OOOB_ACTION_VIBRATE | PROV_MASK_OOOB_ACTION_NUMERIC | \
  510. PROV_MASK_OOOB_ACTION_ALPHANUMERIC)
  511. /** Output OOB Maximum size supported */
  512. #define UI_PROV_OUTPUT_OOB_SIZE 0x08
  513. /** Input OOB Actions supported */
  514. #define UI_PROV_INPUT_OOB_ACTIONS \
  515. (PROV_MASK_IOOB_ACTION_PUSH | PROV_MASK_IOOB_ACTION_TWIST | \
  516. PROV_MASK_IOOB_ACTION_NUMERIC | PROV_MASK_IOOB_ACTION_ALPHANUMERIC)
  517. /** Input OOB Maximum size supported */
  518. #define UI_PROV_INPUT_OOB_SIZE 0x08
  519. /** Beacon setup timeout in seconds */
  520. #define UI_PROV_SETUP_TIMEOUT_SECS 30
  521. /** Attention timeout for device in seconds */
  522. #define UI_PROV_DEVICE_ATTENTION_TIMEOUT 30
  523. #define PROV_AUTHVAL_SIZE_PL 16
  524. /** Authentication values for OOB Display - To be made random */
  525. #define UI_DISPLAY_AUTH_DIGIT 3
  526. #define UI_DISPLAY_AUTH_NUMERIC 35007
  527. #define UI_DISPLAY_AUTH_STRING "f00l"
  528. /** Provisioning capabilities of local device */
  529. DECL_STATIC PROV_CAPABILITIES_S UI_prov_capab =
  530. {
  531. /** Number of Elements */
  532. 0x02,
  533. /** Supported algorithms */
  534. PROV_MASK_ALGO_EC_FIPS_P256,
  535. /** Public key type */
  536. PROV_MASK_PUBKEY_OOBINFO,
  537. /** Static OOB type */
  538. PROV_MASK_STATIC_OOBINFO,
  539. /** Output OOB information */
  540. { UI_PROV_OUTPUT_OOB_ACTIONS, UI_PROV_OUTPUT_OOB_SIZE },
  541. /** Input OOB information */
  542. { UI_PROV_INPUT_OOB_ACTIONS, UI_PROV_INPUT_OOB_SIZE },
  543. };
  544. /** Unprovisioned device identifier */
  545. PROV_DEVICE_S UI_lprov_device =
  546. {
  547. /** UUID */
  548. {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
  549. /** OOB Flag */
  550. 0x00,
  551. /**
  552. * Encoded URI Information
  553. * For example, to give a web address, "https://www.abc.com"
  554. * the URI encoded data would be -
  555. * 0x17 0x2F 0x2F 0x77 0x77 0x77 0x2E 0x61 0x62 0x63 0x2E 0x63 0x6F 0x6D
  556. * where 0x17 is the URI encoding for https:
  557. */
  558. NULL
  559. };
  560. /** Data exchanged during Provisiong procedure */
  561. DECL_STATIC PROV_DATA_S UI_prov_data =
  562. {
  563. /** NetKey */
  564. { 0x45, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x69, 0x6e, 0x64, 0x4e, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x00 },
  565. /** Index of the NetKey */
  566. 0x0000,
  567. /** Flags bitmask */
  568. 0x00,
  569. /** Current value of the IV index */
  570. 0x00000001,
  571. /** Unicast address of the primary element */
  572. 0x0002
  573. };
  574. /** Current role of application - Provisioner/Device */
  575. DECL_STATIC UCHAR UI_prov_role;
  576. /** Provisioning Handle */
  577. DECL_STATIC PROV_HANDLE UI_prov_handle;
  578. API_RESULT UI_prov_callback
  579. (
  580. PROV_HANDLE * phandle,
  581. UCHAR event_type,
  582. API_RESULT event_result,
  583. void * event_data,
  584. UINT16 event_datalen
  585. )
  586. {
  587. PROV_DATA_S * rdata;
  588. PROV_OOB_TYPE_S * oob_info;
  589. API_RESULT retval;
  590. UCHAR authstr[PROV_AUTHVAL_SIZE_PL << 1];
  591. UINT32 authnum;
  592. UCHAR authtype;
  593. UCHAR * pauth;
  594. UINT16 authsize;
  595. switch (event_type)
  596. {
  597. case PROV_EVT_PROVISIONING_SETUP:
  598. CONSOLE_OUT("Recvd PROV_EVT_PROVISIONING_SETUP\n");
  599. CONSOLE_OUT("Status - 0x%04X\n", event_result);
  600. /* Display the attention timeout */
  601. CONSOLE_OUT("Attention TImeout - %d\n", *((UCHAR *)event_data));
  602. break;
  603. case PROV_EVT_OOB_DISPLAY:
  604. CONSOLE_OUT("Recvd PROV_EVT_OOB_DISPLAY\n");
  605. CONSOLE_OUT("Status - 0x%04X\n", event_result);
  606. /* Reference the Authenticatio Type information */
  607. oob_info = (PROV_OOB_TYPE_S *)event_data;
  608. CONSOLE_OUT("Authenticaion Action - 0x%02X\n", oob_info->action);
  609. CONSOLE_OUT("Authenticaion Size - 0x%02X\n", oob_info->size);
  610. /* If role is Device, the action is of Output OOB, else Input OOB */
  611. if (PROV_ROLE_DEVICE == UI_prov_role)
  612. {
  613. if (PROV_OOOB_ACTION_ALPHANUMERIC == oob_info->action)
  614. {
  615. authtype = 1;
  616. }
  617. else if (PROV_OOOB_ACTION_NUMERIC == oob_info->action)
  618. {
  619. authtype = 2;
  620. }
  621. else
  622. {
  623. authtype = 0;
  624. }
  625. }
  626. else
  627. {
  628. if (PROV_IOOB_ACTION_ALPHANUMERIC == oob_info->action)
  629. {
  630. authtype = 1;
  631. }
  632. else if (PROV_IOOB_ACTION_NUMERIC == oob_info->action)
  633. {
  634. authtype = 2;
  635. }
  636. else
  637. {
  638. authtype = 0;
  639. }
  640. }
  641. if (1 == authtype)
  642. {
  643. EM_str_copy (authstr, UI_DISPLAY_AUTH_STRING);
  644. CONSOLE_OUT("\n\n>>> AuthVal - %s <<<\n\n", authstr);
  645. pauth = authstr;
  646. authsize = EM_str_len(authstr);
  647. }
  648. else if (2 == authtype)
  649. {
  650. authnum = (UINT32)UI_DISPLAY_AUTH_NUMERIC;
  651. CONSOLE_OUT("\n\n>>> AuthVal - %d <<<\n\n", authnum);
  652. pauth = (UCHAR *)&authnum;
  653. authsize = sizeof(UINT32);
  654. }
  655. else
  656. {
  657. authnum = (UINT32)UI_DISPLAY_AUTH_DIGIT;
  658. CONSOLE_OUT("\n\n>>> AuthVal - %d <<<\n\n", authnum);
  659. pauth = (UCHAR *)&authnum;
  660. authsize = sizeof(UINT32);
  661. }
  662. /* Call to input the oob */
  663. CONSOLE_OUT("Setting the Authval...\n");
  664. retval = MS_prov_set_authval(&UI_prov_handle, pauth, authsize);
  665. CONSOLE_OUT("Retval - 0x%04X\n", retval);
  666. break;
  667. case PROV_EVT_OOB_ENTRY:
  668. CONSOLE_OUT("Recvd PROV_EVT_OOB_ENTRY\n");
  669. CONSOLE_OUT("Status - 0x%04X\n", event_result);
  670. /* Reference the Authenticatio Type information */
  671. oob_info = (PROV_OOB_TYPE_S *)event_data;
  672. CONSOLE_OUT("Authenticaion Action - 0x%02X\n", oob_info->action);
  673. CONSOLE_OUT("Authenticaion Size - 0x%02X\n", oob_info->size);
  674. break;
  675. case PROV_EVT_DEVINPUT_COMPLETE:
  676. CONSOLE_OUT("Recvd PROV_EVT_DEVINPUT_COMPLETE\n");
  677. CONSOLE_OUT("Status - 0x%04X\n", event_result);
  678. break;
  679. case PROV_EVT_PROVDATA_INFO:
  680. CONSOLE_OUT("Recvd PROV_EVT_PROVDATA_INFO\n");
  681. CONSOLE_OUT("Status - 0x%04X\n", event_result);
  682. /* Reference the Provisioning Data */
  683. rdata = (PROV_DATA_S *)event_data;
  684. CONSOLE_OUT("NetKey : "); appl_dump_bytes(rdata->netkey, PROV_KEY_NETKEY_SIZE);
  685. CONSOLE_OUT("Key ID : 0x%04X\n", rdata->keyid);
  686. CONSOLE_OUT("Flags : 0x%02X\n", rdata->flags);
  687. CONSOLE_OUT("IVIndex : 0x%08X\n", rdata->ivindex);
  688. CONSOLE_OUT("UAddr : 0x%04X\n", rdata->uaddr);
  689. /* Provide Provisioning Data to Access Layer */
  690. MS_access_cm_set_prov_data
  691. (
  692. rdata
  693. );
  694. break;
  695. case PROV_EVT_PROVISIONING_COMPLETE:
  696. CONSOLE_OUT("Recvd PROV_EVT_PROVISIONING_COMPLETE\n");
  697. CONSOLE_OUT("Status - 0x%04X\n", event_result);
  698. if (API_SUCCESS == event_result)
  699. {
  700. /* Already Set while handling PROV_EVT_PROVDATA_INFO */
  701. }
  702. break;
  703. default:
  704. CONSOLE_OUT("Unknown Event - 0x%02X\n", event_type);
  705. }
  706. return API_SUCCESS;
  707. }
  708. void UI_register_prov(void)
  709. {
  710. API_RESULT retval;
  711. CONSOLE_OUT("Registering with Provisioning layer...\n");
  712. retval = MS_prov_register(&UI_prov_capab, UI_prov_callback);
  713. CONSOLE_OUT("Retval - 0x%04X\n", retval);
  714. }
  715. void UI_setup_prov(UCHAR role, UCHAR brr)
  716. {
  717. API_RESULT retval;
  718. if (PROV_ROLE_PROVISIONER != role)
  719. {
  720. CONSOLE_OUT("Setting up Device for Provisioning ...\n");
  721. retval = MS_prov_setup
  722. (
  723. brr,
  724. role,
  725. &UI_lprov_device,
  726. UI_PROV_SETUP_TIMEOUT_SECS
  727. );
  728. UI_prov_role = PROV_ROLE_DEVICE;
  729. }
  730. else
  731. {
  732. CONSOLE_OUT("Setting up Provisioner for Provisioning ...\n");
  733. retval = MS_prov_setup
  734. (
  735. brr,
  736. role,
  737. NULL,
  738. UI_PROV_SETUP_TIMEOUT_SECS
  739. );
  740. UI_prov_role = PROV_ROLE_PROVISIONER;
  741. }
  742. CONSOLE_OUT("Retval - 0x%04X\n", retval);
  743. }
  744. void UI_prov_bind(UCHAR brr, UCHAR index)
  745. {
  746. API_RESULT retval;
  747. /* Call to bind with the selected device */
  748. CONSOLE_OUT("Binding with the selected device...\n");
  749. retval = MS_prov_bind(brr, &UI_lprov_device, UI_PROV_DEVICE_ATTENTION_TIMEOUT, &UI_prov_handle);
  750. CONSOLE_OUT("Retval - 0x%04X\n", retval);
  751. }
  752. void appl_mesh_sample (void)
  753. {
  754. MS_ACCESS_NODE_ID node_id;
  755. MS_ACCESS_ELEMENT_DESC element;
  756. MS_ACCESS_ELEMENT_HANDLE element_handle;
  757. MS_ACCESS_ELEMENT_DESC element_1;
  758. MS_ACCESS_ELEMENT_HANDLE element_handle_1;
  759. API_RESULT retval;
  760. UCHAR role, brr;
  761. MS_CONFIG * config_ptr;
  762. #ifdef MS_HAVE_DYNAMIC_CONFIG
  763. MS_CONFIG config;
  764. /* Initialize dynamic configuration */
  765. MS_INIT_CONFIG(config);
  766. config_ptr = &config;
  767. #else
  768. config_ptr = NULL;
  769. #endif /* MS_HAVE_DYNAMIC_CONFIG */
  770. /* Initialize OSAL */
  771. EM_os_init();
  772. /* Initialize Debug Module */
  773. EM_debug_init();
  774. /* Initialize Timer Module */
  775. EM_timer_init();
  776. timer_em_init();
  777. /* Initialize utilities */
  778. nvsto_init();
  779. /* Initialize Mesh Stack */
  780. MS_init(config_ptr);
  781. /* Register with underlying BLE stack */
  782. blebrr_register();
  783. /* Create Node */
  784. retval = MS_access_create_node(&node_id);
  785. /* Register Element */
  786. /**
  787. * TBD: Define GATT Namespace Descriptions from
  788. * https://www.bluetooth.com/specifications/assigned-numbers/gatt-namespace-descriptors
  789. *
  790. * Using 'main' (0x0106) as Location temporarily.
  791. */
  792. element.loc = 0x0106;
  793. retval = MS_access_register_element
  794. (
  795. node_id,
  796. &element,
  797. &element_handle
  798. );
  799. if (API_SUCCESS == retval)
  800. {
  801. /* Register foundation model servers */
  802. retval = UI_register_foundation_model_servers(element_handle);
  803. }
  804. if (API_SUCCESS == retval)
  805. {
  806. /* Register Generic OnOff model server */
  807. retval = UI_register_generic_onoff_model_server(element_handle);
  808. }
  809. /* Register another Element */
  810. /**
  811. * TBD: Define GATT Namespace Descriptions from
  812. * https://www.bluetooth.com/specifications/assigned-numbers/gatt-namespace-descriptors
  813. *
  814. * Using 'main' (0x0106) as Location temporarily.
  815. */
  816. element_1.loc = 0x0106;
  817. retval = MS_access_register_element
  818. (
  819. node_id,
  820. &element_1,
  821. &element_handle_1
  822. );
  823. if (API_SUCCESS == retval)
  824. {
  825. /* Register Light Lightness model server */
  826. retval = UI_register_light_lightness_model_server(element_handle_1);
  827. }
  828. if (API_SUCCESS == retval)
  829. {
  830. /* Initialize model states */
  831. UI_model_states_initialization();
  832. }
  833. /* Configure as provisionee/device */
  834. UI_register_prov();
  835. /**
  836. * setup <role:[1 - Device, 2 - Provisioner]> <bearer:[1 - Adv, 2 - GATT]
  837. */
  838. role = PROV_ROLE_DEVICE;
  839. brr = PROV_BRR_ADV;
  840. UI_setup_prov(role, brr);
  841. UI_prov_bind(brr, 0x00);
  842. return;
  843. }
  844. #endif /* (MESH_STANDALONE == 5) */