lighting_server.c 135 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597
  1. /* Bluetooth: Mesh Lighting Server Models
  2. *
  3. * SPDX-FileCopyrightText: 2018 Vikrant More
  4. * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. */
  8. #include <errno.h>
  9. #include "btc_ble_mesh_lighting_model.h"
  10. #include "mesh/config.h"
  11. #include "access.h"
  12. #include "transport.h"
  13. #include "mesh/model_opcode.h"
  14. #include "mesh/state_transition.h"
  15. #include "mesh/device_property.h"
  16. #if CONFIG_BLE_MESH_LIGHTING_SERVER
  17. static bt_mesh_mutex_t light_server_lock;
  18. void bt_mesh_light_server_lock(void)
  19. {
  20. bt_mesh_mutex_lock(&light_server_lock);
  21. }
  22. void bt_mesh_light_server_unlock(void)
  23. {
  24. bt_mesh_mutex_unlock(&light_server_lock);
  25. }
  26. /* message handlers (Start) */
  27. /* Light Lightness Server/Setup Server message handlers */
  28. static void send_light_lightness_status(struct bt_mesh_model *model,
  29. struct bt_mesh_msg_ctx *ctx,
  30. bool publish, uint16_t opcode)
  31. {
  32. struct net_buf_simple *msg = NULL;
  33. uint8_t length = 2 + 5;
  34. if (ctx == NULL && publish == false) {
  35. BT_ERR("%s, Invalid parameter", __func__);
  36. return;
  37. }
  38. if (publish == false) {
  39. msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
  40. if (msg == NULL) {
  41. BT_ERR("%s, Out of memory", __func__);
  42. return;
  43. }
  44. } else {
  45. msg = bt_mesh_server_get_pub_msg(model, length);
  46. if (msg == NULL) {
  47. return;
  48. }
  49. }
  50. bt_mesh_model_msg_init(msg, opcode);
  51. switch (opcode) {
  52. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS: {
  53. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  54. net_buf_simple_add_le16(msg, srv->state->lightness_actual);
  55. if (srv->actual_transition.counter) {
  56. bt_mesh_server_calc_remain_time(&srv->actual_transition);
  57. net_buf_simple_add_le16(msg, srv->state->target_lightness_actual);
  58. net_buf_simple_add_u8(msg, srv->actual_transition.remain_time);
  59. }
  60. break;
  61. }
  62. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS: {
  63. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  64. net_buf_simple_add_le16(msg, srv->state->lightness_linear);
  65. if (srv->linear_transition.counter) {
  66. bt_mesh_server_calc_remain_time(&srv->linear_transition);
  67. net_buf_simple_add_le16(msg, srv->state->target_lightness_linear);
  68. net_buf_simple_add_u8(msg, srv->linear_transition.remain_time);
  69. }
  70. break;
  71. }
  72. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS: {
  73. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  74. net_buf_simple_add_le16(msg, srv->state->lightness_last);
  75. break;
  76. }
  77. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS:
  78. if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
  79. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  80. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  81. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV) {
  82. struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
  83. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  84. }
  85. break;
  86. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS:
  87. if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
  88. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  89. net_buf_simple_add_u8(msg, srv->state->status_code);
  90. net_buf_simple_add_le16(msg, srv->state->lightness_range_min);
  91. net_buf_simple_add_le16(msg, srv->state->lightness_range_max);
  92. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV) {
  93. struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
  94. net_buf_simple_add_u8(msg, srv->state->status_code);
  95. net_buf_simple_add_le16(msg, srv->state->lightness_range_min);
  96. net_buf_simple_add_le16(msg, srv->state->lightness_range_max);
  97. }
  98. break;
  99. default:
  100. BT_WARN("Unknown Light Lightness status opcode 0x%04x", opcode);
  101. if (publish == false) {
  102. bt_mesh_free_buf(msg);
  103. }
  104. return;
  105. }
  106. if (publish == false) {
  107. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
  108. bt_mesh_free_buf(msg);
  109. } else {
  110. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
  111. }
  112. }
  113. static void light_lightness_get(struct bt_mesh_model *model,
  114. struct bt_mesh_msg_ctx *ctx,
  115. struct net_buf_simple *buf)
  116. {
  117. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  118. uint16_t opcode = 0U;
  119. if (srv == NULL || srv->state == NULL) {
  120. BT_ERR("%s, Invalid model user data", __func__);
  121. return;
  122. }
  123. /* Callback the received message to the application layer */
  124. if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  125. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
  126. model, ctx, NULL, 0);
  127. return;
  128. }
  129. switch (ctx->recv_op) {
  130. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET:
  131. opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS;
  132. break;
  133. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET:
  134. opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS;
  135. break;
  136. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET:
  137. opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS;
  138. break;
  139. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET:
  140. opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS;
  141. break;
  142. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET:
  143. opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS;
  144. break;
  145. default:
  146. BT_WARN("Unknown Light Lightness Get opcode 0x%04x", ctx->recv_op);
  147. return;
  148. }
  149. send_light_lightness_status(model, ctx, false, opcode);
  150. }
  151. void light_lightness_publish(struct bt_mesh_model *model, uint16_t opcode)
  152. {
  153. if (model->user_data == NULL) {
  154. BT_ERR("%s, Invalid model user data", __func__);
  155. return;
  156. }
  157. switch (model->id) {
  158. case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV: {
  159. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  160. if (srv->state == NULL) {
  161. BT_ERR("Invalid Light Lightness Server state");
  162. return;
  163. }
  164. break;
  165. }
  166. case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV: {
  167. struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
  168. if (srv->state == NULL) {
  169. BT_ERR("Invalid Light Lightness Setup Server state");
  170. return;
  171. }
  172. break;
  173. }
  174. default:
  175. BT_ERR("Invalid Light Lightness Server model 0x%04x", model->id);
  176. return;
  177. }
  178. send_light_lightness_status(model, NULL, true, opcode);
  179. }
  180. static void light_lightness_set(struct bt_mesh_model *model,
  181. struct bt_mesh_msg_ctx *ctx,
  182. struct net_buf_simple *buf)
  183. {
  184. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  185. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  186. bool optional = false;
  187. uint16_t actual = 0U;
  188. int64_t now = 0;
  189. if (srv == NULL || srv->state == NULL) {
  190. BT_ERR("%s, Invalid model user data", __func__);
  191. return;
  192. }
  193. actual = net_buf_simple_pull_le16(buf);
  194. tid = net_buf_simple_pull_u8(buf);
  195. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  196. return;
  197. }
  198. /* Callback the received message to the application layer */
  199. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  200. bt_mesh_light_server_recv_set_msg_t set = {
  201. .lightness_set.op_en = optional,
  202. .lightness_set.lightness = actual,
  203. .lightness_set.tid = tid,
  204. .lightness_set.trans_time = trans_time,
  205. .lightness_set.delay = delay,
  206. };
  207. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  208. model, ctx, (const uint8_t *)&set, sizeof(set));
  209. return;
  210. }
  211. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  212. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET) {
  213. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
  214. }
  215. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
  216. /* In this condition, no event will be callback to application layer */
  217. return;
  218. }
  219. bt_mesh_light_server_lock();
  220. bt_mesh_server_stop_transition(&srv->actual_transition);
  221. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  222. if (actual) {
  223. if (srv->state->lightness_range_min && actual < srv->state->lightness_range_min) {
  224. actual = srv->state->lightness_range_min;
  225. } else if (srv->state->lightness_range_max && actual > srv->state->lightness_range_max) {
  226. actual = srv->state->lightness_range_max;
  227. }
  228. }
  229. srv->state->target_lightness_actual = actual;
  230. /**
  231. * If the target state is equal to the current state, the transition shall not be
  232. * started and is considered complete.
  233. */
  234. if (srv->state->target_lightness_actual != srv->state->lightness_actual) {
  235. light_lightness_actual_tt_values(srv, trans_time, delay);
  236. } else {
  237. bt_mesh_light_server_state_change_t change = {
  238. .lightness_set.lightness = srv->state->lightness_actual,
  239. };
  240. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  241. model, ctx, (const uint8_t *)&change, sizeof(change));
  242. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET) {
  243. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
  244. }
  245. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
  246. bt_mesh_light_server_unlock();
  247. return;
  248. }
  249. /* Copy the ctx of the received message */
  250. if (srv->actual_transition.timer.work.user_data) {
  251. memcpy(srv->actual_transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  252. }
  253. /* For Instantaneous Transition */
  254. if (srv->actual_transition.counter == 0U) {
  255. srv->state->lightness_actual = srv->state->target_lightness_actual;
  256. /**
  257. * Whenever the Light Lightness Actual state is changed with a non-transactional
  258. * message or a completed sequence of transactional messages to a non-zero value,
  259. * the value of the Light Lightness Last shall be set to the value of the Light
  260. * Lightness Actual.
  261. */
  262. if (srv->state->lightness_actual) {
  263. srv->state->lightness_last = srv->state->lightness_actual;
  264. }
  265. }
  266. srv->actual_transition.just_started = true;
  267. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET) {
  268. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
  269. }
  270. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
  271. bt_mesh_light_server_unlock();
  272. bt_mesh_server_start_transition(&srv->actual_transition);
  273. }
  274. static void light_lightness_linear_set(struct bt_mesh_model *model,
  275. struct bt_mesh_msg_ctx *ctx,
  276. struct net_buf_simple *buf)
  277. {
  278. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  279. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  280. bool optional = false;
  281. uint16_t linear = 0U;
  282. int64_t now = 0;
  283. if (srv == NULL || srv->state == NULL) {
  284. BT_ERR("%s, Invalid model user data", __func__);
  285. return;
  286. }
  287. linear = net_buf_simple_pull_le16(buf);
  288. tid = net_buf_simple_pull_u8(buf);
  289. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  290. return;
  291. }
  292. /* Callback the received message to the application layer */
  293. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  294. bt_mesh_light_server_recv_set_msg_t set = {
  295. .lightness_linear_set.op_en = optional,
  296. .lightness_linear_set.lightness = linear,
  297. .lightness_linear_set.tid = tid,
  298. .lightness_linear_set.trans_time = trans_time,
  299. .lightness_linear_set.delay = delay,
  300. };
  301. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  302. model, ctx, (const uint8_t *)&set, sizeof(set));
  303. return;
  304. }
  305. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  306. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET) {
  307. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
  308. }
  309. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
  310. /* In this condition, no event will be callback to application layer */
  311. return;
  312. }
  313. bt_mesh_light_server_lock();
  314. bt_mesh_server_stop_transition(&srv->linear_transition);
  315. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  316. srv->state->target_lightness_linear = linear;
  317. /**
  318. * If the target state is equal to the current state, the transition shall not
  319. * be started and is considered complete.
  320. */
  321. if (srv->state->target_lightness_linear != srv->state->lightness_linear) {
  322. light_lightness_linear_tt_values(srv, trans_time, delay);
  323. } else {
  324. bt_mesh_light_server_state_change_t change = {
  325. .lightness_linear_set.lightness = srv->state->lightness_actual,
  326. };
  327. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  328. model, ctx, (const uint8_t *)&change, sizeof(change));
  329. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET) {
  330. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
  331. }
  332. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
  333. bt_mesh_light_server_unlock();
  334. return;
  335. }
  336. /* Copy the ctx of the received message */
  337. if (srv->linear_transition.timer.work.user_data) {
  338. memcpy(srv->linear_transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  339. }
  340. /* For Instantaneous Transition */
  341. if (srv->linear_transition.counter == 0U) {
  342. srv->state->lightness_linear = srv->state->target_lightness_linear;
  343. }
  344. srv->linear_transition.just_started = true;
  345. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET) {
  346. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
  347. }
  348. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
  349. bt_mesh_light_server_unlock();
  350. bt_mesh_server_start_transition(&srv->linear_transition);
  351. }
  352. static void light_lightness_default_set(struct bt_mesh_model *model,
  353. struct bt_mesh_msg_ctx *ctx,
  354. struct net_buf_simple *buf)
  355. {
  356. struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
  357. uint16_t lightness = 0U;
  358. if (srv == NULL || srv->state == NULL) {
  359. BT_ERR("%s, Invalid model user data", __func__);
  360. return;
  361. }
  362. lightness = net_buf_simple_pull_le16(buf);
  363. /* Callback the received message to the application layer */
  364. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  365. bt_mesh_light_server_recv_set_msg_t set = {
  366. .lightness_default_set.lightness = lightness,
  367. };
  368. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  369. model, ctx, (const uint8_t *)&set, sizeof(set));
  370. return;
  371. }
  372. if (srv->state->lightness_default != lightness) {
  373. srv->state->lightness_default = lightness;
  374. bt_mesh_light_server_state_change_t change = {
  375. .lightness_default_set.lightness = lightness,
  376. };
  377. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  378. model, ctx, (const uint8_t *)&change, sizeof(change));
  379. }
  380. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET) {
  381. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS);
  382. }
  383. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS);
  384. }
  385. static void light_lightness_range_set(struct bt_mesh_model *model,
  386. struct bt_mesh_msg_ctx *ctx,
  387. struct net_buf_simple *buf)
  388. {
  389. struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
  390. uint16_t range_min = 0U, range_max = 0U;
  391. if (srv == NULL || srv->state == NULL) {
  392. BT_ERR("%s, Invalid model user data", __func__);
  393. return;
  394. }
  395. range_min = net_buf_simple_pull_le16(buf);
  396. range_max = net_buf_simple_pull_le16(buf);
  397. if (range_min > range_max) {
  398. BT_ERR("Range min 0x%04x is greater than range max 0x%04x",
  399. range_min, range_max);
  400. return;
  401. }
  402. /* Callback the received message to the application layer */
  403. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  404. bt_mesh_light_server_recv_set_msg_t set = {
  405. .lightness_range_set.range_min = range_min,
  406. .lightness_range_set.range_max = range_max,
  407. };
  408. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  409. model, ctx, (const uint8_t *)&set, sizeof(set));
  410. return;
  411. }
  412. /**
  413. * When a Light Lightness Setup Server receives a Light Lightness Range Set
  414. * message or a Light Lightness Range Set Unacknowledged message with values
  415. * that cannot be accepted, it shall set the status of the operation to a
  416. * value representing the reason why the values cannot be accepted.
  417. *
  418. * TODO: 0x0000 for Light Range Min/Max is prohibited, but BQB test case
  419. * MMDL/SR/LLNS/BI-01-C requires 'SUCCESS' when it sends a set message with
  420. * Light Range Min set to 0x0000.
  421. */
  422. #if 0
  423. srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
  424. #else
  425. if (range_min == 0x0000) {
  426. srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MIN;
  427. } else if (range_max == 0x0000) {
  428. srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MAX;
  429. } else {
  430. srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
  431. }
  432. #endif
  433. if (range_min && srv->state->lightness_range_min != range_min) {
  434. srv->state->lightness_range_min = range_min;
  435. }
  436. if (range_max && srv->state->lightness_range_max != range_max) {
  437. srv->state->lightness_range_max = range_max;
  438. }
  439. bt_mesh_light_server_state_change_t change = {
  440. .lightness_range_set.range_min = srv->state->lightness_range_min,
  441. .lightness_range_set.range_max = srv->state->lightness_range_max,
  442. };
  443. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  444. model, ctx, (const uint8_t *)&change, sizeof(change));
  445. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET) {
  446. send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS);
  447. }
  448. send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS);
  449. }
  450. /* Light CTL Server/Temperature Server/Setup Server message handlers */
  451. static void send_light_ctl_status(struct bt_mesh_model *model,
  452. struct bt_mesh_msg_ctx *ctx,
  453. bool publish, uint16_t opcode)
  454. {
  455. struct net_buf_simple *msg = NULL;
  456. uint8_t length = 2 + 9;
  457. if (ctx == NULL && publish == false) {
  458. BT_ERR("%s, Invalid parameter", __func__);
  459. return;
  460. }
  461. if (publish == false) {
  462. msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
  463. if (msg == NULL) {
  464. BT_ERR("%s, Out of memory", __func__);
  465. return;
  466. }
  467. } else {
  468. msg = bt_mesh_server_get_pub_msg(model, length);
  469. if (msg == NULL) {
  470. return;
  471. }
  472. }
  473. bt_mesh_model_msg_init(msg, opcode);
  474. switch (opcode) {
  475. case BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS: {
  476. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  477. net_buf_simple_add_le16(msg, srv->state->lightness);
  478. net_buf_simple_add_le16(msg, srv->state->temperature);
  479. if (srv->transition.counter) {
  480. bt_mesh_server_calc_remain_time(&srv->transition);
  481. net_buf_simple_add_le16(msg, srv->state->target_lightness);
  482. net_buf_simple_add_le16(msg, srv->state->target_temperature);
  483. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  484. }
  485. break;
  486. }
  487. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS:
  488. if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SRV) {
  489. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  490. net_buf_simple_add_u8(msg, srv->state->status_code);
  491. net_buf_simple_add_le16(msg, srv->state->temperature_range_min);
  492. net_buf_simple_add_le16(msg, srv->state->temperature_range_max);
  493. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV) {
  494. struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
  495. net_buf_simple_add_u8(msg, srv->state->status_code);
  496. net_buf_simple_add_le16(msg, srv->state->temperature_range_min);
  497. net_buf_simple_add_le16(msg, srv->state->temperature_range_max);
  498. }
  499. break;
  500. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS: {
  501. if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SRV) {
  502. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  503. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  504. net_buf_simple_add_le16(msg, srv->state->temperature_default);
  505. net_buf_simple_add_le16(msg, srv->state->delta_uv_default);
  506. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV) {
  507. struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
  508. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  509. net_buf_simple_add_le16(msg, srv->state->temperature_default);
  510. net_buf_simple_add_le16(msg, srv->state->delta_uv_default);
  511. }
  512. break;
  513. }
  514. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS: {
  515. struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
  516. net_buf_simple_add_le16(msg, srv->state->temperature);
  517. net_buf_simple_add_le16(msg, srv->state->delta_uv);
  518. if (srv->transition.counter) {
  519. bt_mesh_server_calc_remain_time(&srv->transition);
  520. net_buf_simple_add_le16(msg, srv->state->target_temperature);
  521. net_buf_simple_add_le16(msg, srv->state->target_delta_uv);
  522. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  523. }
  524. break;
  525. }
  526. default:
  527. BT_WARN("Unknown Light CTL status opcode 0x%04x", opcode);
  528. if (publish == false) {
  529. bt_mesh_free_buf(msg);
  530. }
  531. return;
  532. }
  533. if (publish == false) {
  534. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
  535. bt_mesh_free_buf(msg);
  536. } else {
  537. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
  538. }
  539. }
  540. static void light_ctl_get(struct bt_mesh_model *model,
  541. struct bt_mesh_msg_ctx *ctx,
  542. struct net_buf_simple *buf)
  543. {
  544. struct bt_mesh_server_rsp_ctrl *rsp_ctrl = NULL;
  545. uint16_t opcode = 0U;
  546. if (model->user_data == NULL) {
  547. BT_ERR("%s, Invalid model user data", __func__);
  548. return;
  549. }
  550. switch (model->id) {
  551. case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
  552. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  553. if (srv->state == NULL) {
  554. BT_ERR("Invalid Light CTL Server state");
  555. return;
  556. }
  557. rsp_ctrl = &srv->rsp_ctrl;
  558. break;
  559. }
  560. case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
  561. struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
  562. if (srv->state == NULL) {
  563. BT_ERR("Invalid Light CTL Temperature Server state");
  564. return;
  565. }
  566. rsp_ctrl = &srv->rsp_ctrl;
  567. break;
  568. }
  569. default:
  570. BT_ERR("Invalid Light CTL Server model 0x%04x", model->id);
  571. return;
  572. }
  573. /* Callback the received message to the application layer */
  574. if (rsp_ctrl->get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  575. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
  576. model, ctx, NULL, 0);
  577. return;
  578. }
  579. switch (ctx->recv_op) {
  580. case BLE_MESH_MODEL_OP_LIGHT_CTL_GET:
  581. opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS;
  582. break;
  583. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET:
  584. opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS;
  585. break;
  586. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET:
  587. opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS;
  588. break;
  589. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET:
  590. opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS;
  591. break;
  592. default:
  593. BT_WARN("Unknown Light CTL Get opcode 0x%04x", ctx->recv_op);
  594. return;
  595. }
  596. send_light_ctl_status(model, ctx, false, opcode);
  597. }
  598. void light_ctl_publish(struct bt_mesh_model *model, uint16_t opcode)
  599. {
  600. if (model->user_data == NULL) {
  601. BT_ERR("%s, Invalid model user data", __func__);
  602. return;
  603. }
  604. switch (model->id) {
  605. case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
  606. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  607. if (srv->state == NULL) {
  608. BT_ERR("Invalid Light CTL Server state");
  609. return;
  610. }
  611. break;
  612. }
  613. case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
  614. struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
  615. if (srv->state == NULL) {
  616. BT_ERR("Invalid Light CTL Temperature Server state");
  617. return;
  618. }
  619. break;
  620. }
  621. case BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV: {
  622. struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
  623. if (srv->state == NULL) {
  624. BT_ERR("Invalid Light CTL Setup Server state");
  625. return;
  626. }
  627. break;
  628. }
  629. default:
  630. BT_ERR("Invalid Light CTL Server model 0x%04x", model->id);
  631. return;
  632. }
  633. send_light_ctl_status(model, NULL, true, opcode);
  634. }
  635. static void light_ctl_set(struct bt_mesh_model *model,
  636. struct bt_mesh_msg_ctx *ctx,
  637. struct net_buf_simple *buf)
  638. {
  639. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  640. uint16_t lightness = 0U, temperature = 0U;
  641. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  642. int16_t delta_uv = 0;
  643. bool optional = false;
  644. int64_t now = 0;
  645. if (srv == NULL || srv->state == NULL) {
  646. BT_ERR("%s, Invalid model user data", __func__);
  647. return;
  648. }
  649. lightness = net_buf_simple_pull_le16(buf);
  650. temperature = net_buf_simple_pull_le16(buf);
  651. delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
  652. tid = net_buf_simple_pull_u8(buf);
  653. if (temperature < BLE_MESH_TEMPERATURE_MIN || temperature > BLE_MESH_TEMPERATURE_MAX) {
  654. BT_ERR("Invalid temperature 0x%04x", temperature);
  655. return;
  656. }
  657. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  658. return;
  659. }
  660. /* Callback the received message to the application layer */
  661. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  662. bt_mesh_light_server_recv_set_msg_t set = {
  663. .ctl_set.op_en = optional,
  664. .ctl_set.lightness = lightness,
  665. .ctl_set.temperature = temperature,
  666. .ctl_set.delta_uv = delta_uv,
  667. .ctl_set.tid = tid,
  668. .ctl_set.trans_time = trans_time,
  669. .ctl_set.delay = delay,
  670. };
  671. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  672. model, ctx, (const uint8_t *)&set, sizeof(set));
  673. return;
  674. }
  675. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  676. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_SET) {
  677. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
  678. }
  679. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
  680. /* In this condition, no event will be callback to application layer */
  681. return;
  682. }
  683. bt_mesh_light_server_lock();
  684. bt_mesh_server_stop_transition(&srv->transition);
  685. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  686. srv->state->target_lightness = lightness;
  687. if (srv->state->temperature_range_min &&
  688. srv->state->temperature_range_min != BLE_MESH_TEMPERATURE_UNKNOWN &&
  689. temperature < srv->state->temperature_range_min) {
  690. temperature = srv->state->temperature_range_min;
  691. } else if (srv->state->temperature_range_max &&
  692. srv->state->temperature_range_max != BLE_MESH_TEMPERATURE_UNKNOWN &&
  693. temperature > srv->state->temperature_range_max) {
  694. temperature = srv->state->temperature_range_max;
  695. }
  696. srv->state->target_temperature = temperature;
  697. srv->state->target_delta_uv = delta_uv;
  698. if (srv->state->target_lightness != srv->state->lightness ||
  699. srv->state->target_temperature != srv->state->temperature ||
  700. srv->state->target_delta_uv != srv->state->delta_uv) {
  701. light_ctl_tt_values(srv, trans_time, delay);
  702. } else {
  703. bt_mesh_light_server_state_change_t change = {
  704. .ctl_set.lightness = srv->state->lightness,
  705. .ctl_set.temperature = srv->state->temperature,
  706. .ctl_set.delta_uv = srv->state->delta_uv,
  707. };
  708. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  709. model, ctx, (const uint8_t *)&change, sizeof(change));
  710. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_SET) {
  711. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
  712. }
  713. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
  714. bt_mesh_light_server_unlock();
  715. return;
  716. }
  717. /* Copy the ctx of the received message */
  718. if (srv->transition.timer.work.user_data) {
  719. memcpy(srv->transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  720. }
  721. /* For Instantaneous Transition */
  722. if (srv->transition.counter == 0U) {
  723. srv->state->lightness = srv->state->target_lightness;
  724. srv->state->temperature = srv->state->target_temperature;
  725. srv->state->delta_uv = srv->state->target_delta_uv;
  726. }
  727. srv->transition.just_started = true;
  728. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_SET) {
  729. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
  730. }
  731. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
  732. bt_mesh_light_server_unlock();
  733. bt_mesh_server_start_transition(&srv->transition);
  734. }
  735. static void light_ctl_default_set(struct bt_mesh_model *model,
  736. struct bt_mesh_msg_ctx *ctx,
  737. struct net_buf_simple *buf)
  738. {
  739. struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
  740. uint16_t lightness = 0U, temperature = 0U;
  741. int16_t delta_uv = 0;
  742. if (srv == NULL || srv->state == NULL) {
  743. BT_ERR("%s, Invalid model user data", __func__);
  744. return;
  745. }
  746. lightness = net_buf_simple_pull_le16(buf);
  747. temperature = net_buf_simple_pull_le16(buf);
  748. delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
  749. if (temperature < BLE_MESH_TEMPERATURE_MIN || temperature > BLE_MESH_TEMPERATURE_MAX) {
  750. BT_ERR("Invalid temperature 0x%04x", temperature);
  751. return;
  752. }
  753. /* Callback the received message to the application layer */
  754. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  755. bt_mesh_light_server_recv_set_msg_t set = {
  756. .ctl_default_set.lightness = lightness,
  757. .ctl_default_set.temperature = temperature,
  758. .ctl_default_set.delta_uv = delta_uv,
  759. };
  760. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  761. model, ctx, (const uint8_t *)&set, sizeof(set));
  762. return;
  763. }
  764. if (srv->state->temperature_range_min &&
  765. srv->state->temperature_range_min != BLE_MESH_TEMPERATURE_UNKNOWN &&
  766. temperature < srv->state->temperature_range_min) {
  767. temperature = srv->state->temperature_range_min;
  768. } else if (srv->state->temperature_range_max &&
  769. srv->state->temperature_range_max != BLE_MESH_TEMPERATURE_UNKNOWN &&
  770. temperature > srv->state->temperature_range_max) {
  771. temperature = srv->state->temperature_range_max;
  772. }
  773. srv->state->lightness_default = lightness;
  774. srv->state->temperature_default = temperature;
  775. srv->state->delta_uv_default = delta_uv;
  776. bt_mesh_light_server_state_change_t change = {
  777. .ctl_default_set.lightness = srv->state->lightness_default,
  778. .ctl_default_set.temperature = srv->state->temperature_default,
  779. .ctl_default_set.delta_uv = srv->state->delta_uv_default,
  780. };
  781. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  782. model, ctx, (const uint8_t *)&change, sizeof(change));
  783. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET) {
  784. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS);
  785. }
  786. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS);
  787. }
  788. static void light_ctl_temp_range_set(struct bt_mesh_model *model,
  789. struct bt_mesh_msg_ctx *ctx,
  790. struct net_buf_simple *buf)
  791. {
  792. struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
  793. uint16_t min = 0U, max = 0U;
  794. if (srv == NULL || srv->state == NULL) {
  795. BT_ERR("%s, Invalid model user data", __func__);
  796. return;
  797. }
  798. min = net_buf_simple_pull_le16(buf);
  799. max = net_buf_simple_pull_le16(buf);
  800. /* This is as per 6.1.3.1 in Mesh Model Specification */
  801. if (min > max ||
  802. min < BLE_MESH_TEMPERATURE_MIN || (min != BLE_MESH_TEMPERATURE_UNKNOWN && min > BLE_MESH_TEMPERATURE_MAX) ||
  803. max < BLE_MESH_TEMPERATURE_MIN || (max != BLE_MESH_TEMPERATURE_UNKNOWN && max > BLE_MESH_TEMPERATURE_MAX)) {
  804. BT_ERR("Invalid parameter, range min 0x%04x, range max 0x%04x",
  805. min, max);
  806. return;
  807. }
  808. /* Callback the received message to the application layer */
  809. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  810. bt_mesh_light_server_recv_set_msg_t set = {
  811. .ctl_temp_range_set.range_min = min,
  812. .ctl_temp_range_set.range_max = max,
  813. };
  814. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  815. model, ctx, (const uint8_t *)&set, sizeof(set));
  816. return;
  817. }
  818. if (min == BLE_MESH_TEMPERATURE_UNKNOWN) {
  819. srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MIN;
  820. } else if (max == BLE_MESH_TEMPERATURE_UNKNOWN ) {
  821. srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MAX;
  822. } else {
  823. srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
  824. }
  825. if (min != BLE_MESH_TEMPERATURE_UNKNOWN && srv->state->temperature_range_min != min) {
  826. srv->state->temperature_range_min = min;
  827. }
  828. if (max != BLE_MESH_TEMPERATURE_UNKNOWN && srv->state->temperature_range_max != max) {
  829. srv->state->temperature_range_max = max;
  830. }
  831. bt_mesh_light_server_state_change_t change = {
  832. .ctl_temp_range_set.range_min = srv->state->temperature_range_min,
  833. .ctl_temp_range_set.range_max = srv->state->temperature_range_max,
  834. };
  835. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  836. model, ctx, (const uint8_t *)&change, sizeof(change));
  837. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET) {
  838. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS);
  839. }
  840. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS);
  841. }
  842. static void light_ctl_temp_set(struct bt_mesh_model *model,
  843. struct bt_mesh_msg_ctx *ctx,
  844. struct net_buf_simple *buf)
  845. {
  846. struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
  847. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  848. uint16_t temperature = 0U;
  849. int16_t delta_uv = 0;
  850. bool optional = false;
  851. int64_t now = 0;
  852. if (srv == NULL || srv->state == NULL) {
  853. BT_ERR("%s, Invalid model user data", __func__);
  854. return;
  855. }
  856. temperature = net_buf_simple_pull_le16(buf);
  857. delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
  858. tid = net_buf_simple_pull_u8(buf);
  859. if (temperature < BLE_MESH_TEMPERATURE_MIN || temperature > BLE_MESH_TEMPERATURE_MAX) {
  860. BT_ERR("Invalid temperature 0x%04x", temperature);
  861. return;
  862. }
  863. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  864. return;
  865. }
  866. /* Callback the received message to the application layer */
  867. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  868. bt_mesh_light_server_recv_set_msg_t set = {
  869. .ctl_temp_set.op_en = optional,
  870. .ctl_temp_set.temperature = temperature,
  871. .ctl_temp_set.delta_uv = delta_uv,
  872. .ctl_temp_set.tid = tid,
  873. .ctl_temp_set.trans_time = trans_time,
  874. .ctl_temp_set.delay = delay,
  875. };
  876. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  877. model, ctx, (const uint8_t *)&set, sizeof(set));
  878. return;
  879. }
  880. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  881. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET) {
  882. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
  883. }
  884. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
  885. /* In this condition, no event will be callback to application layer */
  886. return;
  887. }
  888. bt_mesh_light_server_lock();
  889. bt_mesh_server_stop_transition(&srv->transition);
  890. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  891. if (srv->state->temperature_range_min &&
  892. srv->state->temperature_range_min != BLE_MESH_TEMPERATURE_UNKNOWN &&
  893. temperature < srv->state->temperature_range_min) {
  894. temperature = srv->state->temperature_range_min;
  895. } else if (srv->state->temperature_range_max &&
  896. srv->state->temperature_range_max != BLE_MESH_TEMPERATURE_UNKNOWN &&
  897. temperature > srv->state->temperature_range_max) {
  898. temperature = srv->state->temperature_range_max;
  899. }
  900. srv->state->target_temperature = temperature;
  901. srv->state->target_delta_uv = delta_uv;
  902. if (srv->state->target_temperature != srv->state->temperature ||
  903. srv->state->target_delta_uv != srv->state->delta_uv) {
  904. light_ctl_temp_tt_values(srv, trans_time, delay);
  905. } else {
  906. bt_mesh_light_server_state_change_t change = {
  907. .ctl_temp_set.temperature = srv->state->temperature,
  908. .ctl_temp_set.delta_uv = srv->state->delta_uv,
  909. };
  910. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  911. model, ctx, (const uint8_t *)&change, sizeof(change));
  912. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET) {
  913. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
  914. }
  915. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
  916. bt_mesh_light_server_unlock();
  917. return;
  918. }
  919. /* Copy the ctx of the received message */
  920. if (srv->transition.timer.work.user_data) {
  921. memcpy(srv->transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  922. }
  923. /* For Instantaneous Transition */
  924. if (srv->transition.counter == 0U) {
  925. srv->state->temperature = srv->state->target_temperature;
  926. srv->state->delta_uv = srv->state->target_delta_uv;
  927. }
  928. srv->transition.just_started = true;
  929. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET) {
  930. send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
  931. }
  932. send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
  933. bt_mesh_light_server_unlock();
  934. bt_mesh_server_start_transition(&srv->transition);
  935. }
  936. /* Light HSL Server/Hue Server/Saturation Server/Setup Server message handlers */
  937. static void send_light_hsl_status(struct bt_mesh_model *model,
  938. struct bt_mesh_msg_ctx *ctx,
  939. bool publish, uint16_t opcode)
  940. {
  941. struct net_buf_simple *msg = NULL;
  942. uint8_t length = 2 + 9;
  943. if (ctx == NULL && publish == false) {
  944. BT_ERR("%s, Invalid parameter", __func__);
  945. return;
  946. }
  947. if (publish == false) {
  948. msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
  949. if (msg == NULL) {
  950. BT_ERR("%s, Out of memory", __func__);
  951. return;
  952. }
  953. } else {
  954. msg = bt_mesh_server_get_pub_msg(model, length);
  955. if (msg == NULL) {
  956. return;
  957. }
  958. }
  959. bt_mesh_model_msg_init(msg, opcode);
  960. switch (opcode) {
  961. case BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS:
  962. case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS: {
  963. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  964. if (opcode == BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS) {
  965. net_buf_simple_add_le16(msg, srv->state->lightness);
  966. net_buf_simple_add_le16(msg, srv->state->hue);
  967. net_buf_simple_add_le16(msg, srv->state->saturation);
  968. if (srv->transition.counter) {
  969. bt_mesh_server_calc_remain_time(&srv->transition);
  970. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  971. }
  972. } else if (opcode == BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS) {
  973. net_buf_simple_add_le16(msg, srv->state->target_lightness);
  974. net_buf_simple_add_le16(msg, srv->state->target_hue);
  975. net_buf_simple_add_le16(msg, srv->state->target_saturation);
  976. if (srv->transition.counter) {
  977. bt_mesh_server_calc_remain_time(&srv->transition);
  978. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  979. }
  980. }
  981. break;
  982. }
  983. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS:
  984. if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SRV) {
  985. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  986. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  987. net_buf_simple_add_le16(msg, srv->state->hue_default);
  988. net_buf_simple_add_le16(msg, srv->state->saturation_default);
  989. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV) {
  990. struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
  991. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  992. net_buf_simple_add_le16(msg, srv->state->hue_default);
  993. net_buf_simple_add_le16(msg, srv->state->saturation_default);
  994. }
  995. break;
  996. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS:
  997. if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SRV) {
  998. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  999. net_buf_simple_add_u8(msg, srv->state->status_code);
  1000. net_buf_simple_add_le16(msg, srv->state->hue_range_min);
  1001. net_buf_simple_add_le16(msg, srv->state->hue_range_max);
  1002. net_buf_simple_add_le16(msg, srv->state->saturation_range_min);
  1003. net_buf_simple_add_le16(msg, srv->state->saturation_range_max);
  1004. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV) {
  1005. struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
  1006. net_buf_simple_add_u8(msg, srv->state->status_code);
  1007. net_buf_simple_add_le16(msg, srv->state->hue_range_min);
  1008. net_buf_simple_add_le16(msg, srv->state->hue_range_max);
  1009. net_buf_simple_add_le16(msg, srv->state->saturation_range_min);
  1010. net_buf_simple_add_le16(msg, srv->state->saturation_range_max);
  1011. }
  1012. break;
  1013. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS: {
  1014. struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
  1015. net_buf_simple_add_le16(msg, srv->state->hue);
  1016. if (srv->transition.counter) {
  1017. bt_mesh_server_calc_remain_time(&srv->transition);
  1018. net_buf_simple_add_le16(msg, srv->state->target_hue);
  1019. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  1020. }
  1021. break;
  1022. }
  1023. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS: {
  1024. struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
  1025. net_buf_simple_add_le16(msg, srv->state->saturation);
  1026. if (srv->transition.counter) {
  1027. bt_mesh_server_calc_remain_time(&srv->transition);
  1028. net_buf_simple_add_le16(msg, srv->state->target_saturation);
  1029. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  1030. }
  1031. break;
  1032. }
  1033. default:
  1034. BT_WARN("Unknown Light HSL status opcode 0x%04x", opcode);
  1035. if (publish == false) {
  1036. bt_mesh_free_buf(msg);
  1037. }
  1038. return;
  1039. }
  1040. if (publish == false) {
  1041. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
  1042. bt_mesh_free_buf(msg);
  1043. } else {
  1044. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
  1045. }
  1046. }
  1047. static void light_hsl_get(struct bt_mesh_model *model,
  1048. struct bt_mesh_msg_ctx *ctx,
  1049. struct net_buf_simple *buf)
  1050. {
  1051. struct bt_mesh_server_rsp_ctrl *rsp_ctrl = NULL;
  1052. uint16_t opcode = 0U;
  1053. if (model->user_data == NULL) {
  1054. BT_ERR("%s, Invalid model user data", __func__);
  1055. return;
  1056. }
  1057. switch (model->id) {
  1058. case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
  1059. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  1060. if (srv->state == NULL) {
  1061. BT_ERR("Invalid Light HSL Server state");
  1062. return;
  1063. }
  1064. rsp_ctrl = &srv->rsp_ctrl;
  1065. break;
  1066. }
  1067. case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
  1068. struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
  1069. if (srv->state == NULL) {
  1070. BT_ERR("Invalid Light HSL Hue Server state");
  1071. return;
  1072. }
  1073. rsp_ctrl = &srv->rsp_ctrl;
  1074. break;
  1075. }
  1076. case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
  1077. struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
  1078. if (srv->state == NULL) {
  1079. BT_ERR("Invalid Light HSL Saturation Server state");
  1080. return;
  1081. }
  1082. rsp_ctrl = &srv->rsp_ctrl;
  1083. break;
  1084. }
  1085. default:
  1086. BT_ERR("Invalid Light HSL Server model 0x%04x", model->id);
  1087. return;
  1088. }
  1089. /* Callback the received message to the application layer */
  1090. if (rsp_ctrl->get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1091. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
  1092. model, ctx, NULL, 0);
  1093. return;
  1094. }
  1095. switch (ctx->recv_op) {
  1096. case BLE_MESH_MODEL_OP_LIGHT_HSL_GET:
  1097. opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS;
  1098. break;
  1099. case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET:
  1100. opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS;
  1101. break;
  1102. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET:
  1103. opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS;
  1104. break;
  1105. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET:
  1106. opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS;
  1107. break;
  1108. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET:
  1109. opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS;
  1110. break;
  1111. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET:
  1112. opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS;
  1113. break;
  1114. default:
  1115. BT_WARN("Unknown Light HSL Get opcode 0x%04x", ctx->recv_op);
  1116. return;
  1117. }
  1118. send_light_hsl_status(model, ctx, false, opcode);
  1119. }
  1120. void light_hsl_publish(struct bt_mesh_model *model, uint16_t opcode)
  1121. {
  1122. if (model->user_data == NULL) {
  1123. BT_ERR("%s, Invalid model user data", __func__);
  1124. return;
  1125. }
  1126. switch (model->id) {
  1127. case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
  1128. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  1129. if (srv->state == NULL) {
  1130. BT_ERR("Invalid Light HSL Server state");
  1131. return;
  1132. }
  1133. break;
  1134. }
  1135. case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
  1136. struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
  1137. if (srv->state == NULL) {
  1138. BT_ERR("Invalid Light HSL Hue Server state");
  1139. return;
  1140. }
  1141. break;
  1142. }
  1143. case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
  1144. struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
  1145. if (srv->state == NULL) {
  1146. BT_ERR("Invalid Light HSL Saturation Server state");
  1147. return;
  1148. }
  1149. break;
  1150. }
  1151. case BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV: {
  1152. struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
  1153. if (srv->state == NULL) {
  1154. BT_ERR("Invalid Light HSL Setup Server state");
  1155. return;
  1156. }
  1157. break;
  1158. }
  1159. default:
  1160. BT_ERR("Invalid Light HSL Server model 0x%04x", model->id);
  1161. return;
  1162. }
  1163. send_light_hsl_status(model, NULL, true, opcode);
  1164. }
  1165. static void light_hsl_set(struct bt_mesh_model *model,
  1166. struct bt_mesh_msg_ctx *ctx,
  1167. struct net_buf_simple *buf)
  1168. {
  1169. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  1170. uint16_t lightness = 0U, hue = 0U, saturation = 0U;
  1171. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  1172. bool optional = false;
  1173. int64_t now = 0;
  1174. if (srv == NULL || srv->state == NULL) {
  1175. BT_ERR("%s, Invalid model user data", __func__);
  1176. return;
  1177. }
  1178. lightness = net_buf_simple_pull_le16(buf);
  1179. hue = net_buf_simple_pull_le16(buf);
  1180. saturation = net_buf_simple_pull_le16(buf);
  1181. tid = net_buf_simple_pull_u8(buf);
  1182. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  1183. return;
  1184. }
  1185. /* Callback the received message to the application layer */
  1186. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1187. bt_mesh_light_server_recv_set_msg_t set = {
  1188. .hsl_set.op_en = optional,
  1189. .hsl_set.lightness = lightness,
  1190. .hsl_set.hue = hue,
  1191. .hsl_set.saturation = saturation,
  1192. .hsl_set.tid = tid,
  1193. .hsl_set.trans_time = trans_time,
  1194. .hsl_set.delay = delay,
  1195. };
  1196. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1197. model, ctx, (const uint8_t *)&set, sizeof(set));
  1198. return;
  1199. }
  1200. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  1201. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SET) {
  1202. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
  1203. }
  1204. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
  1205. /* In this condition, no event will be callback to application layer */
  1206. return;
  1207. }
  1208. bt_mesh_light_server_lock();
  1209. bt_mesh_server_stop_transition(&srv->transition);
  1210. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  1211. srv->state->target_lightness = lightness;
  1212. if (srv->state->hue_range_min && hue < srv->state->hue_range_min) {
  1213. hue = srv->state->hue_range_min;
  1214. } else if (srv->state->hue_range_max && hue > srv->state->hue_range_max) {
  1215. hue = srv->state->hue_range_max;
  1216. }
  1217. srv->state->target_hue = hue;
  1218. if (srv->state->saturation_range_min && saturation < srv->state->saturation_range_min) {
  1219. saturation = srv->state->saturation_range_min;
  1220. } else if (srv->state->saturation_range_max && saturation > srv->state->saturation_range_max) {
  1221. saturation = srv->state->saturation_range_max;
  1222. }
  1223. srv->state->target_saturation = saturation;
  1224. /**
  1225. * If the target state is equal to the current state, the transition shall not
  1226. * be started and is considered complete.
  1227. */
  1228. if (srv->state->target_lightness != srv->state->lightness ||
  1229. srv->state->target_hue != srv->state->hue ||
  1230. srv->state->target_saturation != srv->state->saturation) {
  1231. light_hsl_tt_values(srv, trans_time, delay);
  1232. } else {
  1233. bt_mesh_light_server_state_change_t change = {
  1234. .hsl_set.lightness = srv->state->lightness,
  1235. .hsl_set.hue = srv->state->hue,
  1236. .hsl_set.saturation = srv->state->saturation,
  1237. };
  1238. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1239. model, ctx, (const uint8_t *)&change, sizeof(change));
  1240. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SET) {
  1241. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
  1242. }
  1243. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
  1244. bt_mesh_light_server_unlock();
  1245. return;
  1246. }
  1247. /* Copy the ctx of the received message */
  1248. if (srv->transition.timer.work.user_data) {
  1249. memcpy(srv->transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  1250. }
  1251. /* For Instantaneous Transition */
  1252. if (srv->transition.counter == 0U) {
  1253. srv->state->lightness = srv->state->target_lightness;
  1254. srv->state->hue = srv->state->target_hue;
  1255. srv->state->saturation = srv->state->target_saturation;
  1256. }
  1257. srv->transition.just_started = true;
  1258. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SET) {
  1259. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
  1260. }
  1261. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
  1262. bt_mesh_light_server_unlock();
  1263. bt_mesh_server_start_transition(&srv->transition);
  1264. }
  1265. static void light_hsl_default_set(struct bt_mesh_model *model,
  1266. struct bt_mesh_msg_ctx *ctx,
  1267. struct net_buf_simple *buf)
  1268. {
  1269. struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
  1270. uint16_t lightness = 0U, hue = 0U, saturation = 0U;
  1271. if (srv == NULL || srv->state == NULL) {
  1272. BT_ERR("%s, Invalid model user data", __func__);
  1273. return;
  1274. }
  1275. lightness = net_buf_simple_pull_le16(buf);
  1276. hue = net_buf_simple_pull_le16(buf);
  1277. saturation = net_buf_simple_pull_le16(buf);
  1278. /* Callback the received message to the application layer */
  1279. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1280. bt_mesh_light_server_recv_set_msg_t set = {
  1281. .hsl_default_set.lightness = lightness,
  1282. .hsl_default_set.hue = hue,
  1283. .hsl_default_set.saturation = saturation,
  1284. };
  1285. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1286. model, ctx, (const uint8_t *)&set, sizeof(set));
  1287. return;
  1288. }
  1289. if (srv->state->hue_range_min && hue < srv->state->hue_range_min) {
  1290. hue = srv->state->hue_range_min;
  1291. } else if (srv->state->hue_range_max && hue > srv->state->hue_range_max) {
  1292. hue = srv->state->hue_range_max;
  1293. }
  1294. if (srv->state->saturation_range_min && saturation < srv->state->saturation_range_min) {
  1295. saturation = srv->state->saturation_range_min;
  1296. } else if (srv->state->saturation_range_max && saturation > srv->state->saturation_range_max) {
  1297. saturation = srv->state->saturation_range_max;
  1298. }
  1299. srv->state->lightness_default = lightness;
  1300. srv->state->hue_default = hue;
  1301. srv->state->saturation_default = saturation;
  1302. bt_mesh_light_server_state_change_t change = {
  1303. .hsl_default_set.lightness = srv->state->lightness_default,
  1304. .hsl_default_set.hue = srv->state->hue_default,
  1305. .hsl_default_set.saturation = srv->state->saturation_default,
  1306. };
  1307. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1308. model, ctx, (const uint8_t *)&change, sizeof(change));
  1309. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET) {
  1310. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS);
  1311. }
  1312. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS);
  1313. }
  1314. static void light_hsl_range_set(struct bt_mesh_model *model,
  1315. struct bt_mesh_msg_ctx *ctx,
  1316. struct net_buf_simple *buf)
  1317. {
  1318. struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
  1319. uint16_t hue_min = 0U, hue_max = 0U, saturation_min = 0U, saturation_max = 0U;
  1320. if (srv == NULL || srv->state == NULL) {
  1321. BT_ERR("%s, Invalid model user data", __func__);
  1322. return;
  1323. }
  1324. hue_min = net_buf_simple_pull_le16(buf);
  1325. hue_max = net_buf_simple_pull_le16(buf);
  1326. saturation_min = net_buf_simple_pull_le16(buf);
  1327. saturation_max = net_buf_simple_pull_le16(buf);
  1328. if (hue_min > hue_max) {
  1329. BT_ERR("Invalid parameter, hue min 0x%04x, hue max 0x%04x",
  1330. hue_min, hue_max);
  1331. return;
  1332. }
  1333. if (saturation_min > saturation_max) {
  1334. BT_ERR("Invalid parameter, saturation min 0x%04x, saturation max 0x%04x",
  1335. saturation_min, saturation_max);
  1336. return;
  1337. }
  1338. /* Callback the received message to the application layer */
  1339. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1340. bt_mesh_light_server_recv_set_msg_t set = {
  1341. .hsl_range_set.hue_range_min = hue_min,
  1342. .hsl_range_set.hue_range_max = hue_max,
  1343. .hsl_range_set.sat_range_min = saturation_min,
  1344. .hsl_range_set.sat_range_max = saturation_max,
  1345. };
  1346. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1347. model, ctx, (const uint8_t *)&set, sizeof(set));
  1348. return;
  1349. }
  1350. srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
  1351. srv->state->hue_range_min = hue_min;
  1352. srv->state->hue_range_max = hue_max;
  1353. srv->state->saturation_range_min = saturation_min;
  1354. srv->state->saturation_range_max = saturation_max;
  1355. bt_mesh_light_server_state_change_t change = {
  1356. .hsl_range_set.hue_range_min = srv->state->hue_range_min,
  1357. .hsl_range_set.hue_range_max = srv->state->hue_range_max,
  1358. .hsl_range_set.sat_range_min = srv->state->saturation_range_min,
  1359. .hsl_range_set.sat_range_max = srv->state->saturation_range_max,
  1360. };
  1361. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1362. model, ctx, (const uint8_t *)&change, sizeof(change));
  1363. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET) {
  1364. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS);
  1365. }
  1366. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS);
  1367. }
  1368. static void light_hsl_hue_set(struct bt_mesh_model *model,
  1369. struct bt_mesh_msg_ctx *ctx,
  1370. struct net_buf_simple *buf)
  1371. {
  1372. struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
  1373. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  1374. bool optional = false;
  1375. uint16_t hue = 0U;
  1376. int64_t now = 0;
  1377. if (srv == NULL || srv->state == NULL) {
  1378. BT_ERR("%s, Invalid model user data", __func__);
  1379. return;
  1380. }
  1381. hue = net_buf_simple_pull_le16(buf);
  1382. tid = net_buf_simple_pull_u8(buf);
  1383. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  1384. return;
  1385. }
  1386. /* Callback the received message to the application layer */
  1387. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1388. bt_mesh_light_server_recv_set_msg_t set = {
  1389. .hsl_hue_set.op_en = optional,
  1390. .hsl_hue_set.hue = hue,
  1391. .hsl_hue_set.tid = tid,
  1392. .hsl_hue_set.trans_time = trans_time,
  1393. .hsl_hue_set.delay = delay,
  1394. };
  1395. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1396. model, ctx, (const uint8_t *)&set, sizeof(set));
  1397. return;
  1398. }
  1399. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  1400. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET) {
  1401. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
  1402. }
  1403. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
  1404. /* In this condition, no event will be callback to application layer */
  1405. return;
  1406. }
  1407. bt_mesh_light_server_lock();
  1408. bt_mesh_server_stop_transition(&srv->transition);
  1409. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  1410. if (srv->state->hue_range_min && hue < srv->state->hue_range_min) {
  1411. hue = srv->state->hue_range_min;
  1412. } else if (srv->state->hue_range_max && hue > srv->state->hue_range_max) {
  1413. hue = srv->state->hue_range_max;
  1414. }
  1415. srv->state->target_hue = hue;
  1416. /**
  1417. * If the target state is equal to the current state, the transition shall not
  1418. * be started and is considered complete.
  1419. */
  1420. if (srv->state->target_hue != srv->state->hue) {
  1421. light_hsl_hue_tt_values(srv, trans_time, delay);
  1422. } else {
  1423. bt_mesh_light_server_state_change_t change = {
  1424. .hsl_hue_set.hue = srv->state->hue,
  1425. };
  1426. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1427. model, ctx, (const uint8_t *)&change, sizeof(change));
  1428. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET) {
  1429. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
  1430. }
  1431. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
  1432. bt_mesh_light_server_unlock();
  1433. return;
  1434. }
  1435. /* Copy the ctx of the received message */
  1436. if (srv->transition.timer.work.user_data) {
  1437. memcpy(srv->transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  1438. }
  1439. /* For Instantaneous Transition */
  1440. if (srv->transition.counter == 0U) {
  1441. srv->state->hue = srv->state->target_hue;
  1442. }
  1443. srv->transition.just_started = true;
  1444. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET) {
  1445. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
  1446. }
  1447. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
  1448. bt_mesh_light_server_unlock();
  1449. bt_mesh_server_start_transition(&srv->transition);
  1450. }
  1451. static void light_hsl_sat_set(struct bt_mesh_model *model,
  1452. struct bt_mesh_msg_ctx *ctx,
  1453. struct net_buf_simple *buf)
  1454. {
  1455. struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
  1456. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  1457. uint16_t saturation = 0U;
  1458. bool optional = false;
  1459. int64_t now = 0;
  1460. if (srv == NULL || srv->state == NULL) {
  1461. BT_ERR("%s, Invalid model user data", __func__);
  1462. return;
  1463. }
  1464. saturation = net_buf_simple_pull_le16(buf);
  1465. tid = net_buf_simple_pull_u8(buf);
  1466. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  1467. return;
  1468. }
  1469. /* Callback the received message to the application layer */
  1470. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1471. bt_mesh_light_server_recv_set_msg_t set = {
  1472. .hsl_saturation_set.op_en = optional,
  1473. .hsl_saturation_set.saturation = saturation,
  1474. .hsl_saturation_set.tid = tid,
  1475. .hsl_saturation_set.trans_time = trans_time,
  1476. .hsl_saturation_set.delay = delay,
  1477. };
  1478. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1479. model, ctx, (const uint8_t *)&set, sizeof(set));
  1480. return;
  1481. }
  1482. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  1483. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET) {
  1484. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
  1485. }
  1486. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
  1487. /* In this condition, no event will be callback to application layer */
  1488. return;
  1489. }
  1490. bt_mesh_light_server_lock();
  1491. bt_mesh_server_stop_transition(&srv->transition);
  1492. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  1493. if (srv->state->saturation_range_min && saturation < srv->state->saturation_range_min) {
  1494. saturation = srv->state->saturation_range_min;
  1495. } else if (srv->state->saturation_range_max && saturation > srv->state->saturation_range_max) {
  1496. saturation = srv->state->saturation_range_max;
  1497. }
  1498. srv->state->target_saturation = saturation;
  1499. /**
  1500. * If the target state is equal to the current state, the transition shall not
  1501. * be started and is considered complete.
  1502. */
  1503. if (srv->state->target_saturation != srv->state->saturation) {
  1504. light_hsl_sat_tt_values(srv, trans_time, delay);
  1505. } else {
  1506. bt_mesh_light_server_state_change_t change = {
  1507. .hsl_saturation_set.saturation = srv->state->saturation,
  1508. };
  1509. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1510. model, ctx, (const uint8_t *)&change, sizeof(change));
  1511. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET) {
  1512. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
  1513. }
  1514. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
  1515. bt_mesh_light_server_unlock();
  1516. return;
  1517. }
  1518. /* Copy the ctx of the received message */
  1519. if (srv->transition.timer.work.user_data) {
  1520. memcpy(srv->transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  1521. }
  1522. /* For Instantaneous Transition */
  1523. if (srv->transition.counter == 0U) {
  1524. srv->state->saturation = srv->state->target_saturation;
  1525. }
  1526. srv->transition.just_started = true;
  1527. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET) {
  1528. send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
  1529. }
  1530. send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
  1531. bt_mesh_light_server_unlock();
  1532. bt_mesh_server_start_transition(&srv->transition);
  1533. }
  1534. /* Light xyL Server/Setup Server message handlers */
  1535. static void send_light_xyl_status(struct bt_mesh_model *model,
  1536. struct bt_mesh_msg_ctx *ctx,
  1537. bool publish, uint16_t opcode)
  1538. {
  1539. struct net_buf_simple *msg = NULL;
  1540. uint8_t length = 2 + 9;
  1541. if (ctx == NULL && publish == false) {
  1542. BT_ERR("%s, Invalid parameter", __func__);
  1543. return;
  1544. }
  1545. if (publish == false) {
  1546. msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
  1547. if (msg == NULL) {
  1548. BT_ERR("%s, Out of memory", __func__);
  1549. return;
  1550. }
  1551. } else {
  1552. msg = bt_mesh_server_get_pub_msg(model, length);
  1553. if (msg == NULL) {
  1554. return;
  1555. }
  1556. }
  1557. bt_mesh_model_msg_init(msg, opcode);
  1558. switch (opcode) {
  1559. case BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS:
  1560. case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS: {
  1561. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  1562. if (opcode == BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS) {
  1563. net_buf_simple_add_le16(msg, srv->state->lightness);
  1564. net_buf_simple_add_le16(msg, srv->state->x);
  1565. net_buf_simple_add_le16(msg, srv->state->y);
  1566. if (srv->transition.counter) {
  1567. bt_mesh_server_calc_remain_time(&srv->transition);
  1568. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  1569. }
  1570. } else if (opcode == BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS) {
  1571. net_buf_simple_add_le16(msg, srv->state->target_lightness);
  1572. net_buf_simple_add_le16(msg, srv->state->target_x);
  1573. net_buf_simple_add_le16(msg, srv->state->target_y);
  1574. if (srv->transition.counter) {
  1575. bt_mesh_server_calc_remain_time(&srv->transition);
  1576. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  1577. }
  1578. }
  1579. break;
  1580. }
  1581. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS:
  1582. if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SRV) {
  1583. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  1584. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  1585. net_buf_simple_add_le16(msg, srv->state->x_default);
  1586. net_buf_simple_add_le16(msg, srv->state->y_default);
  1587. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV) {
  1588. struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
  1589. net_buf_simple_add_le16(msg, srv->state->lightness_default);
  1590. net_buf_simple_add_le16(msg, srv->state->x_default);
  1591. net_buf_simple_add_le16(msg, srv->state->y_default);
  1592. }
  1593. break;
  1594. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS:
  1595. if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SRV) {
  1596. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  1597. net_buf_simple_add_u8(msg, srv->state->status_code);
  1598. net_buf_simple_add_le16(msg, srv->state->x_range_min);
  1599. net_buf_simple_add_le16(msg, srv->state->x_range_max);
  1600. net_buf_simple_add_le16(msg, srv->state->y_range_min);
  1601. net_buf_simple_add_le16(msg, srv->state->y_range_max);
  1602. } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV) {
  1603. struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
  1604. net_buf_simple_add_u8(msg, srv->state->status_code);
  1605. net_buf_simple_add_le16(msg, srv->state->x_range_min);
  1606. net_buf_simple_add_le16(msg, srv->state->x_range_max);
  1607. net_buf_simple_add_le16(msg, srv->state->y_range_min);
  1608. net_buf_simple_add_le16(msg, srv->state->y_range_max);
  1609. }
  1610. break;
  1611. default:
  1612. BT_WARN("Unknown Light xyL status opcode 0x%04x", opcode);
  1613. if (publish == false) {
  1614. bt_mesh_free_buf(msg);
  1615. }
  1616. return;
  1617. }
  1618. if (publish == false) {
  1619. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
  1620. bt_mesh_free_buf(msg);
  1621. } else {
  1622. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
  1623. }
  1624. }
  1625. static void light_xyl_get(struct bt_mesh_model *model,
  1626. struct bt_mesh_msg_ctx *ctx,
  1627. struct net_buf_simple *buf)
  1628. {
  1629. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  1630. uint16_t opcode = 0U;
  1631. if (srv == NULL || srv->state == NULL) {
  1632. BT_ERR("%s, Invalid model user data", __func__);
  1633. return;
  1634. }
  1635. /* Callback the received message to the application layer */
  1636. if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1637. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
  1638. model, ctx, NULL, 0);
  1639. return;
  1640. }
  1641. switch (ctx->recv_op) {
  1642. case BLE_MESH_MODEL_OP_LIGHT_XYL_GET:
  1643. opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS;
  1644. break;
  1645. case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET:
  1646. opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS;
  1647. break;
  1648. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET:
  1649. opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS;
  1650. break;
  1651. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET:
  1652. opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS;
  1653. break;
  1654. default:
  1655. BT_WARN("Unknown Light xyL Get opcode 0x%04x", ctx->recv_op);
  1656. return;
  1657. }
  1658. send_light_xyl_status(model, ctx, false, opcode);
  1659. }
  1660. void light_xyl_publish(struct bt_mesh_model *model, uint16_t opcode)
  1661. {
  1662. if (model->user_data == NULL) {
  1663. BT_ERR("%s, Invalid model user data", __func__);
  1664. return;
  1665. }
  1666. switch (model->id) {
  1667. case BLE_MESH_MODEL_ID_LIGHT_XYL_SRV: {
  1668. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  1669. if (srv->state == NULL) {
  1670. BT_ERR("Invalid Light xyL Server state");
  1671. return;
  1672. }
  1673. break;
  1674. }
  1675. case BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV: {
  1676. struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
  1677. if (srv->state == NULL) {
  1678. BT_ERR("Invalid Light xyL Setup Server state");
  1679. return;
  1680. }
  1681. break;
  1682. }
  1683. default:
  1684. BT_ERR("Invalid Light xyL Server model 0x%04x", model->id);
  1685. return;
  1686. }
  1687. send_light_xyl_status(model, NULL, true, opcode);
  1688. }
  1689. static void light_xyl_set(struct bt_mesh_model *model,
  1690. struct bt_mesh_msg_ctx *ctx,
  1691. struct net_buf_simple *buf)
  1692. {
  1693. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  1694. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  1695. uint16_t lightness = 0U, x = 0U, y = 0U;
  1696. bool optional = false;
  1697. int64_t now = 0;
  1698. if (srv == NULL || srv->state == NULL) {
  1699. BT_ERR("%s, Invalid model user data", __func__);
  1700. return;
  1701. }
  1702. lightness = net_buf_simple_pull_le16(buf);
  1703. x = net_buf_simple_pull_le16(buf);
  1704. y = net_buf_simple_pull_le16(buf);
  1705. tid = net_buf_simple_pull_u8(buf);
  1706. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  1707. return;
  1708. }
  1709. /* Callback the received message to the application layer */
  1710. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1711. bt_mesh_light_server_recv_set_msg_t set = {
  1712. .xyl_set.op_en = optional,
  1713. .xyl_set.lightness = lightness,
  1714. .xyl_set.x = x,
  1715. .xyl_set.y = y,
  1716. .xyl_set.tid = tid,
  1717. .xyl_set.trans_time = trans_time,
  1718. .xyl_set.delay = delay,
  1719. };
  1720. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1721. model, ctx, (const uint8_t *)&set, sizeof(set));
  1722. return;
  1723. }
  1724. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  1725. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_SET) {
  1726. send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
  1727. }
  1728. send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
  1729. /* In this condition, no event will be callback to application layer */
  1730. return;
  1731. }
  1732. bt_mesh_light_server_lock();
  1733. bt_mesh_server_stop_transition(&srv->transition);
  1734. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  1735. srv->state->target_lightness = lightness;
  1736. if (srv->state->x_range_min && x < srv->state->x_range_min) {
  1737. x = srv->state->x_range_min;
  1738. } else if (srv->state->x_range_max && x > srv->state->x_range_max) {
  1739. x = srv->state->x_range_max;
  1740. }
  1741. srv->state->target_x = x;
  1742. if (srv->state->y_range_min && y < srv->state->y_range_min) {
  1743. y = srv->state->y_range_min;
  1744. } else if (srv->state->y_range_max && y > srv->state->y_range_max) {
  1745. y = srv->state->y_range_max;
  1746. }
  1747. srv->state->target_y = y;
  1748. /**
  1749. * If the target state is equal to the current state, the transition shall not
  1750. * be started and is considered complete.
  1751. */
  1752. if (srv->state->target_lightness != srv->state->lightness ||
  1753. srv->state->target_x != srv->state->x ||
  1754. srv->state->target_y != srv->state->y) {
  1755. light_xyl_tt_values(srv, trans_time, delay);
  1756. } else {
  1757. bt_mesh_light_server_state_change_t change = {
  1758. .xyl_set.lightness = srv->state->lightness,
  1759. .xyl_set.x = srv->state->x,
  1760. .xyl_set.y = srv->state->y,
  1761. };
  1762. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1763. model, ctx, (const uint8_t *)&change, sizeof(change));
  1764. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_SET) {
  1765. send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
  1766. }
  1767. send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
  1768. bt_mesh_light_server_unlock();
  1769. return;
  1770. }
  1771. /* Copy the ctx of the received message */
  1772. if (srv->transition.timer.work.user_data) {
  1773. memcpy(srv->transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  1774. }
  1775. /* For Instantaneous Transition */
  1776. if (srv->transition.counter == 0U) {
  1777. srv->state->lightness = srv->state->target_lightness;
  1778. srv->state->x = srv->state->target_x;
  1779. srv->state->y = srv->state->target_y;
  1780. }
  1781. srv->transition.just_started = true;
  1782. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_SET) {
  1783. send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
  1784. }
  1785. send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
  1786. bt_mesh_light_server_unlock();
  1787. bt_mesh_server_start_transition(&srv->transition);
  1788. }
  1789. static void light_xyl_default_set(struct bt_mesh_model *model,
  1790. struct bt_mesh_msg_ctx *ctx,
  1791. struct net_buf_simple *buf)
  1792. {
  1793. struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
  1794. uint16_t lightness = 0U, x = 0U, y = 0U;
  1795. if (srv == NULL || srv->state == NULL) {
  1796. BT_ERR("%s, Invalid model user data", __func__);
  1797. return;
  1798. }
  1799. lightness = net_buf_simple_pull_le16(buf);
  1800. x = net_buf_simple_pull_le16(buf);
  1801. y = net_buf_simple_pull_le16(buf);
  1802. /* Callback the received message to the application layer */
  1803. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1804. bt_mesh_light_server_recv_set_msg_t set = {
  1805. .xyl_default_set.lightness = lightness,
  1806. .xyl_default_set.x = x,
  1807. .xyl_default_set.y = y,
  1808. };
  1809. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1810. model, ctx, (const uint8_t *)&set, sizeof(set));
  1811. return;
  1812. }
  1813. if (srv->state->x_range_min && x < srv->state->x_range_min) {
  1814. x = srv->state->x_range_min;
  1815. } else if (srv->state->x_range_max && x > srv->state->x_range_max) {
  1816. x = srv->state->x_range_max;
  1817. }
  1818. if (srv->state->y_range_min && y < srv->state->y_range_min) {
  1819. y = srv->state->y_range_min;
  1820. } else if (srv->state->y_range_max && y > srv->state->y_range_max) {
  1821. y = srv->state->y_range_max;
  1822. }
  1823. srv->state->lightness_default = lightness;
  1824. srv->state->x_default = x;
  1825. srv->state->y_default = y;
  1826. bt_mesh_light_server_state_change_t change = {
  1827. .xyl_default_set.lightness = srv->state->lightness_default,
  1828. .xyl_default_set.x = srv->state->x_default,
  1829. .xyl_default_set.y = srv->state->y_default,
  1830. };
  1831. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1832. model, ctx, (const uint8_t *)&change, sizeof(change));
  1833. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET) {
  1834. send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS);
  1835. }
  1836. send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS);
  1837. }
  1838. static void light_xyl_range_set(struct bt_mesh_model *model,
  1839. struct bt_mesh_msg_ctx *ctx,
  1840. struct net_buf_simple *buf)
  1841. {
  1842. struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
  1843. uint16_t x_min = 0U, x_max = 0U, y_min = 0U, y_max = 0U;
  1844. if (srv == NULL || srv->state == NULL) {
  1845. BT_ERR("%s, Invalid model user data", __func__);
  1846. return;
  1847. }
  1848. x_min = net_buf_simple_pull_le16(buf);
  1849. x_max = net_buf_simple_pull_le16(buf);
  1850. y_min = net_buf_simple_pull_le16(buf);
  1851. y_max = net_buf_simple_pull_le16(buf);
  1852. if (x_min > x_max) {
  1853. BT_ERR("Invalid parameter, x min 0x%04x, x max 0x%04x",
  1854. x_min, x_max);
  1855. return;
  1856. }
  1857. if (y_min > y_max) {
  1858. BT_ERR("Invalid parameter, y min 0x%04x, y max 0x%04x",
  1859. y_min, y_max);
  1860. return;
  1861. }
  1862. /* Callback the received message to the application layer */
  1863. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1864. bt_mesh_light_server_recv_set_msg_t set = {
  1865. .xyl_range_set.x_range_min = x_min,
  1866. .xyl_range_set.x_range_max = x_max,
  1867. .xyl_range_set.y_range_min = y_min,
  1868. .xyl_range_set.y_range_max = y_max,
  1869. };
  1870. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  1871. model, ctx, (const uint8_t *)&set, sizeof(set));
  1872. return;
  1873. }
  1874. srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
  1875. srv->state->x_range_min = x_min;
  1876. srv->state->x_range_max = x_max;
  1877. srv->state->y_range_min = y_min;
  1878. srv->state->y_range_max = y_max;
  1879. bt_mesh_light_server_state_change_t change = {
  1880. .xyl_range_set.x_range_min = srv->state->x_range_min,
  1881. .xyl_range_set.x_range_max = srv->state->x_range_max,
  1882. .xyl_range_set.y_range_min = srv->state->y_range_min,
  1883. .xyl_range_set.y_range_max = srv->state->y_range_max,
  1884. };
  1885. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  1886. model, ctx, (const uint8_t *)&change, sizeof(change));
  1887. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET) {
  1888. send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS);
  1889. }
  1890. send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS);
  1891. }
  1892. /* Light LC Server/Setup Server message handlers */
  1893. static void send_light_lc_status(struct bt_mesh_model *model,
  1894. struct bt_mesh_msg_ctx *ctx,
  1895. bool publish, uint16_t opcode)
  1896. {
  1897. struct bt_mesh_light_lc_srv *srv = model->user_data;
  1898. struct net_buf_simple *msg = NULL;
  1899. uint8_t length = 2 + 3;
  1900. if (ctx == NULL && publish == false) {
  1901. BT_ERR("%s, Invalid parameter", __func__);
  1902. return;
  1903. }
  1904. if (publish == false) {
  1905. msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
  1906. if (msg == NULL) {
  1907. BT_ERR("%s, Out of memory", __func__);
  1908. return;
  1909. }
  1910. } else {
  1911. msg = bt_mesh_server_get_pub_msg(model, length);
  1912. if (msg == NULL) {
  1913. return;
  1914. }
  1915. }
  1916. bt_mesh_model_msg_init(msg, opcode);
  1917. switch (opcode) {
  1918. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS:
  1919. net_buf_simple_add_u8(msg, srv->lc->state.mode);
  1920. break;
  1921. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS:
  1922. net_buf_simple_add_u8(msg, srv->lc->state.occupancy_mode);
  1923. break;
  1924. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS:
  1925. net_buf_simple_add_u8(msg, srv->lc->state.light_onoff);
  1926. if (srv->transition.counter) {
  1927. bt_mesh_server_calc_remain_time(&srv->transition);
  1928. net_buf_simple_add_u8(msg, srv->lc->state.target_light_onoff);
  1929. net_buf_simple_add_u8(msg, srv->transition.remain_time);
  1930. }
  1931. break;
  1932. default:
  1933. BT_WARN("Unknown Light LC status opcode 0x%04x", opcode);
  1934. if (publish == false) {
  1935. bt_mesh_free_buf(msg);
  1936. }
  1937. return;
  1938. }
  1939. if (publish == false) {
  1940. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
  1941. bt_mesh_free_buf(msg);
  1942. } else {
  1943. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
  1944. }
  1945. }
  1946. static void light_lc_get(struct bt_mesh_model *model,
  1947. struct bt_mesh_msg_ctx *ctx,
  1948. struct net_buf_simple *buf)
  1949. {
  1950. struct bt_mesh_light_lc_srv *srv = model->user_data;
  1951. uint16_t opcode = 0U;
  1952. if (srv == NULL || srv->lc == NULL) {
  1953. BT_ERR("%s, Invalid model user data", __func__);
  1954. return;
  1955. }
  1956. /* Callback the received message to the application layer */
  1957. if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  1958. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
  1959. model, ctx, NULL, 0);
  1960. return;
  1961. }
  1962. switch (ctx->recv_op) {
  1963. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET:
  1964. opcode = BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS;
  1965. break;
  1966. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET:
  1967. opcode = BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS;
  1968. break;
  1969. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET:
  1970. opcode = BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS;
  1971. break;
  1972. default:
  1973. BT_WARN("Unknown Light LC Get opcode 0x%04x", ctx->recv_op);
  1974. return;
  1975. }
  1976. send_light_lc_status(model, ctx, false, opcode);
  1977. }
  1978. void light_lc_publish(struct bt_mesh_model *model, uint16_t opcode)
  1979. {
  1980. struct bt_mesh_light_lc_srv *srv = model->user_data;
  1981. if (srv == NULL || srv->lc == NULL) {
  1982. BT_ERR("%s, Invalid model user data", __func__);
  1983. return;
  1984. }
  1985. send_light_lc_status(model, NULL, true, opcode);
  1986. }
  1987. static void light_lc_mode_set(struct bt_mesh_model *model,
  1988. struct bt_mesh_msg_ctx *ctx,
  1989. struct net_buf_simple *buf)
  1990. {
  1991. struct bt_mesh_light_lc_srv *srv = model->user_data;
  1992. uint8_t mode = 0U;
  1993. if (srv == NULL || srv->lc == NULL) {
  1994. BT_ERR("%s, Invalid model user data", __func__);
  1995. return;
  1996. }
  1997. mode = net_buf_simple_pull_u8(buf);
  1998. if (mode > BLE_MESH_STATE_ON) {
  1999. BT_ERR("Invalid LC Mode 0x%02x", mode);
  2000. return;
  2001. }
  2002. /* Callback the received message to the application layer */
  2003. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  2004. bt_mesh_light_server_recv_set_msg_t set = {
  2005. .lc_mode_set.mode = mode,
  2006. };
  2007. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  2008. model, ctx, (const uint8_t *)&set, sizeof(set));
  2009. return;
  2010. }
  2011. srv->lc->state.mode = mode;
  2012. bt_mesh_light_server_state_change_t change = {
  2013. .lc_mode_set.mode = srv->lc->state.mode,
  2014. };
  2015. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2016. model, ctx, (const uint8_t *)&change, sizeof(change));
  2017. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET) {
  2018. send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS);
  2019. }
  2020. send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS);
  2021. }
  2022. static void light_lc_om_set(struct bt_mesh_model *model,
  2023. struct bt_mesh_msg_ctx *ctx,
  2024. struct net_buf_simple *buf)
  2025. {
  2026. struct bt_mesh_light_lc_srv *srv = model->user_data;
  2027. uint8_t om = 0U;
  2028. if (srv == NULL || srv->lc == NULL) {
  2029. BT_ERR("%s, Invalid model user data", __func__);
  2030. return;
  2031. }
  2032. om = net_buf_simple_pull_u8(buf);
  2033. if (om > BLE_MESH_STATE_ON) {
  2034. BT_ERR("Invalid LC Occupancy Mode 0x%02x", om);
  2035. return;
  2036. }
  2037. /* Callback the received message to the application layer */
  2038. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  2039. bt_mesh_light_server_recv_set_msg_t set = {
  2040. .lc_om_set.mode = om,
  2041. };
  2042. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  2043. model, ctx, (const uint8_t *)&set, sizeof(set));
  2044. return;
  2045. }
  2046. srv->lc->state.occupancy_mode = om;
  2047. bt_mesh_light_server_state_change_t change = {
  2048. .lc_om_set.mode = srv->lc->state.occupancy_mode,
  2049. };
  2050. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2051. model, ctx, (const uint8_t *)&change, sizeof(change));
  2052. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET) {
  2053. send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS);
  2054. }
  2055. send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS);
  2056. }
  2057. static void light_lc_light_onoff_set(struct bt_mesh_model *model,
  2058. struct bt_mesh_msg_ctx *ctx,
  2059. struct net_buf_simple *buf)
  2060. {
  2061. struct bt_mesh_light_lc_srv *srv = model->user_data;
  2062. uint8_t tid = 0U, trans_time = 0U, delay = 0U;
  2063. bool optional = false;
  2064. uint8_t onoff = 0U;
  2065. int64_t now = 0;
  2066. if (srv == NULL || srv->lc == NULL) {
  2067. BT_ERR("%s, Invalid model user data", __func__);
  2068. return;
  2069. }
  2070. onoff = net_buf_simple_pull_u8(buf);
  2071. tid = net_buf_simple_pull_u8(buf);
  2072. if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
  2073. return;
  2074. }
  2075. /* Callback the received message to the application layer */
  2076. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  2077. bt_mesh_light_server_recv_set_msg_t set = {
  2078. .lc_light_onoff_set.op_en = optional,
  2079. .lc_light_onoff_set.light_onoff = onoff,
  2080. .lc_light_onoff_set.tid = tid,
  2081. .lc_light_onoff_set.trans_time = trans_time,
  2082. .lc_light_onoff_set.delay = delay,
  2083. };
  2084. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  2085. model, ctx, (const uint8_t *)&set, sizeof(set));
  2086. return;
  2087. }
  2088. if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
  2089. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET) {
  2090. send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
  2091. }
  2092. send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
  2093. /* In this condition, no event will be callback to application layer */
  2094. return;
  2095. }
  2096. bt_mesh_light_server_lock();
  2097. bt_mesh_server_stop_transition(&srv->transition);
  2098. bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
  2099. srv->lc->state.target_light_onoff = onoff;
  2100. if (srv->lc->state.target_light_onoff != srv->lc->state.light_onoff) {
  2101. light_lc_tt_values(srv, trans_time, delay);
  2102. } else {
  2103. bt_mesh_light_server_state_change_t change = {
  2104. .lc_light_onoff_set.onoff = srv->lc->state.light_onoff,
  2105. };
  2106. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2107. model, ctx, (const uint8_t *)&change, sizeof(change));
  2108. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET) {
  2109. send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
  2110. }
  2111. send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
  2112. bt_mesh_light_server_unlock();
  2113. return;
  2114. }
  2115. /* Copy the ctx of the received message */
  2116. if (srv->transition.timer.work.user_data) {
  2117. memcpy(srv->transition.timer.work.user_data, ctx, sizeof(struct bt_mesh_msg_ctx));
  2118. }
  2119. /* For Instantaneous Transition */
  2120. if (srv->transition.counter == 0U) {
  2121. srv->lc->state.light_onoff = srv->lc->state.target_light_onoff;
  2122. }
  2123. srv->transition.just_started = true;
  2124. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET) {
  2125. send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
  2126. }
  2127. send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
  2128. bt_mesh_light_server_unlock();
  2129. bt_mesh_server_start_transition(&srv->transition);
  2130. }
  2131. static void light_lc_sensor_status(struct bt_mesh_model *model,
  2132. struct bt_mesh_msg_ctx *ctx,
  2133. struct net_buf_simple *buf)
  2134. {
  2135. /**
  2136. * When a Light LC Server receives a Sensor Status message, and if the message
  2137. * Raw field contains a Raw Value for the Motion Sensed Property, and the value
  2138. * is greater than 0, or a Raw Value for the People Count Property, and the
  2139. * value is greater than 0, or a Raw Value for the Presence Detected Property,
  2140. * and the value is greater than 0, then it shall set the Light LC Occupancy
  2141. * state to 0b1.
  2142. * If the message Raw field contains a Raw Value for the Time Since Motion Sensed
  2143. * device property, which represents a value less than or equal to the value of
  2144. * the Light LC Occupancy Delay state, it shall delay setting the Light LC Occupancy
  2145. * state to 0b1 by the difference between the value of the Light LC Occupancy Delay
  2146. * state and the received Time Since Motion value.
  2147. * When a Light LC Server receives a Sensor Status message, and if the message Raw
  2148. * field contains a Raw Value for the Present Ambient Light Level device property,
  2149. * it shall set the Light LC Ambient LuxLevel state to the Represented Value of the
  2150. * received Present Ambient Light Level.
  2151. *
  2152. * Motion Sensed: 1 octet, 0x0042
  2153. * People Count: 2 octets, 0x004C
  2154. * Presence Detected: 1 octet, 0x004D
  2155. *
  2156. * Time Since Motion Sensed: 2 octets, 0x0068
  2157. *
  2158. * Present Ambient Light Level: 4 octets, 0x004E
  2159. */
  2160. struct bt_mesh_light_lc_srv *srv = model->user_data;
  2161. bt_mesh_light_server_state_change_t change = {0};
  2162. uint16_t mpid = 0U, prop_id = 0U;
  2163. uint8_t length = 0U;
  2164. if (srv == NULL || srv->lc == NULL) {
  2165. BT_ERR("%s, Invalid model user data", __func__);
  2166. return;
  2167. }
  2168. if (srv->rsp_ctrl.status_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  2169. bt_mesh_light_server_recv_status_msg_t status = {
  2170. .sensor_status.data = buf,
  2171. };
  2172. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_STATUS_MSG,
  2173. model, ctx, (const uint8_t *)&status, sizeof(status));
  2174. return;
  2175. }
  2176. mpid = net_buf_simple_pull_le16(buf);
  2177. if (mpid & BIT(0)) {
  2178. length = (uint8_t)((mpid & 0xff) >> 1);
  2179. uint8_t msb = net_buf_simple_pull_u8(buf);
  2180. prop_id = (uint16_t)(msb << 8) | (uint16_t)(mpid >> 8);
  2181. } else {
  2182. length = (uint8_t)((mpid & 0x1f) >> 1);
  2183. prop_id = (uint16_t)(mpid >> 5);
  2184. }
  2185. change.sensor_status.property_id = prop_id;
  2186. switch (prop_id) {
  2187. case BLE_MESH_MOTION_SENSED: {
  2188. if (length != BLE_MESH_MOTION_SENSED_LEN || length != buf->len) {
  2189. BT_WARN("Invalid Motion Sensed Property length %d", length);
  2190. return;
  2191. }
  2192. uint8_t val = net_buf_simple_pull_u8(buf);
  2193. if (val > 0) {
  2194. srv->lc->state.occupancy = BLE_MESH_STATE_ON;
  2195. change.sensor_status.state.occupancy = srv->lc->state.occupancy;
  2196. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2197. model, ctx, (const uint8_t *)&change, sizeof(change));
  2198. }
  2199. break;
  2200. }
  2201. case BLE_MESH_PEOPLE_COUNT: {
  2202. if (length != BLE_MESH_PEOPLE_COUNT_LEN || length != buf->len) {
  2203. BT_WARN("Invalid Motion Sensed Property length %d", length);
  2204. return;
  2205. }
  2206. uint16_t val = net_buf_simple_pull_le16(buf);
  2207. if (val > 0) {
  2208. srv->lc->state.occupancy = BLE_MESH_STATE_ON;
  2209. change.sensor_status.state.occupancy = srv->lc->state.occupancy;
  2210. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2211. model, ctx, (const uint8_t *)&change, sizeof(change));
  2212. }
  2213. break;
  2214. }
  2215. case BLE_MESH_PRESENCE_DETECTED: {
  2216. if (length != BLE_MESH_PRESENCE_DETECTED_LEN || length != buf->len) {
  2217. BT_WARN("Invalid Motion Sensed Property length %d", length);
  2218. return;
  2219. }
  2220. uint8_t val = net_buf_simple_pull_u8(buf);
  2221. if (val > 0) {
  2222. srv->lc->state.occupancy = BLE_MESH_STATE_ON;
  2223. change.sensor_status.state.occupancy = srv->lc->state.occupancy;
  2224. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2225. model, ctx, (const uint8_t *)&change, sizeof(change));
  2226. }
  2227. break;
  2228. }
  2229. case BLE_MESH_TIME_SINCE_MOTION_SENSED: {
  2230. if (length != BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN || length != buf->len) {
  2231. BT_WARN("Invalid Motion Sensed Property length %d", length);
  2232. return;
  2233. }
  2234. uint16_t val = net_buf_simple_pull_le16(buf);
  2235. if (val <= srv->lc->prop_state.time_occupancy_delay) {
  2236. srv->lc->prop_state.set_occupancy_to_1_delay =
  2237. srv->lc->prop_state.time_occupancy_delay - val;
  2238. change.sensor_status.state.set_occupancy_to_1_delay = srv->lc->prop_state.set_occupancy_to_1_delay;
  2239. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2240. model, ctx, (const uint8_t *)&change, sizeof(change));
  2241. }
  2242. break;
  2243. }
  2244. case BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL: {
  2245. /**
  2246. * Present Ambient Light Level device property is 4 octets, but ambient
  2247. * luxlevel length is 3 octets, and other devices may send Sensor Status
  2248. * which only contains 3 octets just for Light LC Server.
  2249. * Here we just check if the length is larger than 3.
  2250. */
  2251. if (buf->len < 3) {
  2252. BT_WARN("Invalid Motion Sensed Property length %d", buf->len);
  2253. return;
  2254. }
  2255. uint16_t lsb = net_buf_simple_pull_le16(buf);
  2256. uint8_t msb = net_buf_simple_pull_u8(buf);
  2257. srv->lc->state.ambient_luxlevel = (msb << 16) | lsb;
  2258. change.sensor_status.state.ambient_luxlevel = srv->lc->state.ambient_luxlevel;
  2259. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2260. model, ctx, (const uint8_t *)&change, sizeof(change));
  2261. break;
  2262. }
  2263. default:
  2264. break;
  2265. }
  2266. }
  2267. static uint8_t *get_light_lc_prop_val(struct bt_mesh_model *model, uint16_t prop_id)
  2268. {
  2269. struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
  2270. uint8_t *val = NULL;
  2271. switch (prop_id) {
  2272. case BLE_MESH_LIGHT_CONTROL_TIME_OCCUPANCY_DELAY:
  2273. val = (uint8_t *)&srv->lc->prop_state.time_occupancy_delay;
  2274. break;
  2275. case BLE_MESH_LIGHT_CONTROL_TIME_FADE_ON:
  2276. val = (uint8_t *)&srv->lc->prop_state.time_fade_on;
  2277. break;
  2278. case BLE_MESH_LIGHT_CONTROL_TIME_RUN_ON:
  2279. val = (uint8_t *)&srv->lc->prop_state.time_run_on;
  2280. break;
  2281. case BLE_MESH_LIGHT_CONTROL_TIME_FADE:
  2282. val = (uint8_t *)&srv->lc->prop_state.time_fade;
  2283. break;
  2284. case BLE_MESH_LIGHT_CONTROL_TIME_PROLONG:
  2285. val = (uint8_t *)&srv->lc->prop_state.time_prolong;
  2286. break;
  2287. case BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_AUTO:
  2288. val = (uint8_t *)&srv->lc->prop_state.time_fade_standby_auto;
  2289. break;
  2290. case BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_MANUAL:
  2291. val = (uint8_t *)&srv->lc->prop_state.time_fade_standby_manual;
  2292. break;
  2293. case BLE_MESH_LIGHT_CONTROL_LIGHTNESS_ON:
  2294. val = (uint8_t *)&srv->lc->prop_state.lightness_on;
  2295. break;
  2296. case BLE_MESH_LIGHT_CONTROL_LIGHTNESS_PROLONG:
  2297. val = (uint8_t *)&srv->lc->prop_state.lightness_prolong;
  2298. break;
  2299. case BLE_MESH_LIGHT_CONTROL_LIGHTNESS_STANDBY:
  2300. val = (uint8_t *)&srv->lc->prop_state.lightness_standby;
  2301. break;
  2302. case BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_ON:
  2303. val = (uint8_t *)&srv->lc->prop_state.ambient_luxlevel_on;
  2304. break;
  2305. case BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_PROLONG:
  2306. val = (uint8_t *)&srv->lc->prop_state.ambient_luxlevel_prolong;
  2307. break;
  2308. case BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_STANDBY:
  2309. val = (uint8_t *)&srv->lc->prop_state.ambient_luxlevel_standby;
  2310. break;
  2311. case BLE_MESH_LIGHT_CONTROL_REGULATOR_KIU:
  2312. val = (uint8_t *)&srv->lc->prop_state.regulator_kiu;
  2313. break;
  2314. case BLE_MESH_LIGHT_CONTROL_REGULATOR_KID:
  2315. val = (uint8_t *)&srv->lc->prop_state.regulator_kid;
  2316. break;
  2317. case BLE_MESH_LIGHT_CONTROL_REGULATOR_KPU:
  2318. val = (uint8_t *)&srv->lc->prop_state.regulator_kpu;
  2319. break;
  2320. case BLE_MESH_LIGHT_CONTROL_REGULATOR_KPD:
  2321. val = (uint8_t *)&srv->lc->prop_state.regulator_kpd;
  2322. break;
  2323. case BLE_MESH_LIGHT_CONTROL_REGULATOR_ACCURACY:
  2324. val = (uint8_t *)&srv->lc->prop_state.regulator_accuracy;
  2325. break;
  2326. }
  2327. return val;
  2328. }
  2329. uint8_t *bt_mesh_get_lc_prop_value(struct bt_mesh_model *model, uint16_t prop_id)
  2330. {
  2331. if (model == NULL) {
  2332. BT_ERR("%s, Invalid parameter", __func__);
  2333. return NULL;
  2334. }
  2335. return get_light_lc_prop_val(model, prop_id);
  2336. }
  2337. static void send_light_lc_prop_status(struct bt_mesh_model *model,
  2338. struct bt_mesh_msg_ctx *ctx,
  2339. uint16_t prop_id, bool publish)
  2340. {
  2341. struct net_buf_simple *msg = NULL;
  2342. uint8_t length = 1 + 2 + 4;
  2343. uint8_t *prop_val = NULL;
  2344. prop_val = get_light_lc_prop_val(model, prop_id);
  2345. if (prop_val == NULL) {
  2346. BT_ERR("Failed to get Light LC Property value");
  2347. return;
  2348. }
  2349. if (publish == false) {
  2350. msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
  2351. if (msg == NULL) {
  2352. BT_ERR("%s, Out of memory", __func__);
  2353. return;
  2354. }
  2355. } else {
  2356. msg = bt_mesh_server_get_pub_msg(model, length);
  2357. if (msg == NULL) {
  2358. return;
  2359. }
  2360. }
  2361. bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS);
  2362. net_buf_simple_add_le16(msg, prop_id);
  2363. net_buf_simple_add_mem(msg, prop_val, bt_mesh_get_dev_prop_len(prop_id));
  2364. if (publish == false) {
  2365. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
  2366. bt_mesh_free_buf(msg);
  2367. } else {
  2368. BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
  2369. }
  2370. }
  2371. static void light_lc_prop_get(struct bt_mesh_model *model,
  2372. struct bt_mesh_msg_ctx *ctx,
  2373. struct net_buf_simple *buf)
  2374. {
  2375. struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
  2376. uint16_t prop_id = 0U;
  2377. if (srv == NULL || srv->lc == NULL) {
  2378. BT_ERR("%s, Invalid model user data", __func__);
  2379. return;
  2380. }
  2381. prop_id = net_buf_simple_pull_le16(buf);
  2382. if (prop_id < 0x002B || prop_id > 0x003C) {
  2383. BT_ERR("Invalid Light LC Property ID 0x%04x", prop_id);
  2384. return;
  2385. }
  2386. /* Callback the received message to the application layer */
  2387. if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  2388. bt_mesh_light_server_recv_get_msg_t get = {
  2389. .lc_property_get.id = net_buf_simple_pull_le16(buf),
  2390. };
  2391. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
  2392. model, ctx, (const uint8_t *)&get, sizeof(get));
  2393. return;
  2394. }
  2395. send_light_lc_prop_status(model, ctx, prop_id, false);
  2396. }
  2397. static void light_lc_prop_set(struct bt_mesh_model *model,
  2398. struct bt_mesh_msg_ctx *ctx,
  2399. struct net_buf_simple *buf)
  2400. {
  2401. struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
  2402. uint8_t *prop_val = NULL, expect_len = 0U;
  2403. uint16_t prop_id = 0U;
  2404. if (srv == NULL || srv->lc == NULL) {
  2405. BT_ERR("%s, Invalid model user data", __func__);
  2406. return;
  2407. }
  2408. prop_id = net_buf_simple_pull_le16(buf);
  2409. if (prop_id < 0x002B || prop_id > 0x003C) {
  2410. BT_ERR("Invalid Light LC Property ID 0x%04x", prop_id);
  2411. return;
  2412. }
  2413. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
  2414. bt_mesh_light_server_recv_set_msg_t set = {
  2415. .lc_property_set.id = net_buf_simple_pull_le16(buf),
  2416. .lc_property_set.value = buf,
  2417. };
  2418. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
  2419. model, ctx, (const uint8_t *)&set, sizeof(set));
  2420. return;
  2421. }
  2422. expect_len = bt_mesh_get_dev_prop_len(prop_id);
  2423. if (buf->len != expect_len) {
  2424. BT_ERR("Invalid Light LC Property 0x%04x length, expect %d, actual %d",
  2425. prop_id, expect_len, buf->len);
  2426. return;
  2427. }
  2428. prop_val = get_light_lc_prop_val(model, prop_id);
  2429. if (prop_val == NULL) {
  2430. BT_ERR("Failed to get Light LC Property value");
  2431. return;
  2432. }
  2433. memcpy(prop_val, buf->data, buf->len);
  2434. bt_mesh_light_server_state_change_t change = {
  2435. .lc_property_set.id = prop_id,
  2436. .lc_property_set.value = buf,
  2437. };
  2438. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  2439. model, ctx, (const uint8_t *)&change, sizeof(change));
  2440. if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET) {
  2441. send_light_lc_prop_status(model, ctx, prop_id, false);
  2442. }
  2443. send_light_lc_prop_status(model, ctx, prop_id, true);
  2444. }
  2445. /* message handlers (End) */
  2446. /* Mapping of message handlers for Light Lightness Server (0x1300) */
  2447. const struct bt_mesh_model_op bt_mesh_light_lightness_srv_op[] = {
  2448. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET, 0, light_lightness_get },
  2449. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET, 3, light_lightness_set },
  2450. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK, 3, light_lightness_set },
  2451. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET, 0, light_lightness_get },
  2452. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET, 3, light_lightness_linear_set },
  2453. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK, 3, light_lightness_linear_set },
  2454. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET, 0, light_lightness_get },
  2455. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET, 0, light_lightness_get },
  2456. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET, 0, light_lightness_get },
  2457. BLE_MESH_MODEL_OP_END,
  2458. };
  2459. /* Mapping of message handlers for Light Lightness Setup Server (0x1301) */
  2460. const struct bt_mesh_model_op bt_mesh_light_lightness_setup_srv_op[] = {
  2461. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET, 2, light_lightness_default_set },
  2462. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK, 2, light_lightness_default_set },
  2463. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET, 4, light_lightness_range_set },
  2464. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK, 4, light_lightness_range_set },
  2465. BLE_MESH_MODEL_OP_END,
  2466. };
  2467. /* Mapping of message handlers for Light CTL Server (0x1303) */
  2468. const struct bt_mesh_model_op bt_mesh_light_ctl_srv_op[] = {
  2469. { BLE_MESH_MODEL_OP_LIGHT_CTL_GET, 0, light_ctl_get },
  2470. { BLE_MESH_MODEL_OP_LIGHT_CTL_SET, 7, light_ctl_set },
  2471. { BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK, 7, light_ctl_set },
  2472. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET, 0, light_ctl_get },
  2473. { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET, 0, light_ctl_get },
  2474. BLE_MESH_MODEL_OP_END,
  2475. };
  2476. /* Mapping of message handlers for Light CTL Setup Server (0x1304) */
  2477. const struct bt_mesh_model_op bt_mesh_light_ctl_setup_srv_op[] = {
  2478. { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET, 6, light_ctl_default_set },
  2479. { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK, 6, light_ctl_default_set },
  2480. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET, 4, light_ctl_temp_range_set },
  2481. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK, 4, light_ctl_temp_range_set },
  2482. BLE_MESH_MODEL_OP_END,
  2483. };
  2484. /* Mapping of message handlers for Light CTL Temperature Server (0x1306) */
  2485. const struct bt_mesh_model_op bt_mesh_light_ctl_temp_srv_op[] = {
  2486. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET, 0, light_ctl_get },
  2487. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET, 5, light_ctl_temp_set },
  2488. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK, 5, light_ctl_temp_set },
  2489. BLE_MESH_MODEL_OP_END,
  2490. };
  2491. /* Mapping of message handlers for Light HSL Server (0x1307) */
  2492. const struct bt_mesh_model_op bt_mesh_light_hsl_srv_op[] = {
  2493. { BLE_MESH_MODEL_OP_LIGHT_HSL_GET, 0, light_hsl_get },
  2494. { BLE_MESH_MODEL_OP_LIGHT_HSL_SET, 7, light_hsl_set },
  2495. { BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK, 7, light_hsl_set },
  2496. { BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET, 0, light_hsl_get },
  2497. { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET, 0, light_hsl_get },
  2498. { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET, 0, light_hsl_get },
  2499. BLE_MESH_MODEL_OP_END,
  2500. };
  2501. /* Mapping of message handlers for Light HSL Setup Server (0x1308) */
  2502. const struct bt_mesh_model_op bt_mesh_light_hsl_setup_srv_op[] = {
  2503. { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET, 6, light_hsl_default_set },
  2504. { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK, 6, light_hsl_default_set },
  2505. { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET, 8, light_hsl_range_set },
  2506. { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK, 8, light_hsl_range_set },
  2507. BLE_MESH_MODEL_OP_END,
  2508. };
  2509. /* Mapping of message handlers for Light HSL Hue Server (0x130A) */
  2510. const struct bt_mesh_model_op bt_mesh_light_hsl_hue_srv_op[] = {
  2511. { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET, 0, light_hsl_get },
  2512. { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET, 3, light_hsl_hue_set },
  2513. { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK, 3, light_hsl_hue_set },
  2514. BLE_MESH_MODEL_OP_END,
  2515. };
  2516. /* Mapping of message handlers for Light HSL Saturation Server (0x130B) */
  2517. const struct bt_mesh_model_op bt_mesh_light_hsl_sat_srv_op[] = {
  2518. { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET, 0, light_hsl_get },
  2519. { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET, 3, light_hsl_sat_set },
  2520. { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK, 3, light_hsl_sat_set },
  2521. BLE_MESH_MODEL_OP_END,
  2522. };
  2523. /* Mapping of message handlers for Light xyL Server (0x130C) */
  2524. const struct bt_mesh_model_op bt_mesh_light_xyl_srv_op[] = {
  2525. { BLE_MESH_MODEL_OP_LIGHT_XYL_GET, 0, light_xyl_get },
  2526. { BLE_MESH_MODEL_OP_LIGHT_XYL_SET, 7, light_xyl_set },
  2527. { BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK, 7, light_xyl_set },
  2528. { BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET, 0, light_xyl_get },
  2529. { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET, 0, light_xyl_get },
  2530. { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET, 0, light_xyl_get },
  2531. BLE_MESH_MODEL_OP_END,
  2532. };
  2533. /* Mapping of message handlers for Light xyL Setup Server (0x130D) */
  2534. const struct bt_mesh_model_op bt_mesh_light_xyl_setup_srv_op[] = {
  2535. { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET, 6, light_xyl_default_set },
  2536. { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK, 6, light_xyl_default_set },
  2537. { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET, 8, light_xyl_range_set },
  2538. { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK, 8, light_xyl_range_set },
  2539. BLE_MESH_MODEL_OP_END,
  2540. };
  2541. /* Mapping of message handlers for Light LC Server (0x130F) */
  2542. const struct bt_mesh_model_op bt_mesh_light_lc_srv_op[] = {
  2543. { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET, 0, light_lc_get },
  2544. { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET, 1, light_lc_mode_set },
  2545. { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK, 1, light_lc_mode_set },
  2546. { BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET, 0, light_lc_get },
  2547. { BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET, 1, light_lc_om_set },
  2548. { BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK, 1, light_lc_om_set },
  2549. { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET, 0, light_lc_get },
  2550. { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET, 2, light_lc_light_onoff_set },
  2551. { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK, 2, light_lc_light_onoff_set },
  2552. { BLE_MESH_MODEL_OP_SENSOR_STATUS, 3, light_lc_sensor_status },
  2553. BLE_MESH_MODEL_OP_END,
  2554. };
  2555. /* Mapping of message handlers for Light LC Setup Server (0x1310) */
  2556. const struct bt_mesh_model_op bt_mesh_light_lc_setup_srv_op[] = {
  2557. { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET, 2, light_lc_prop_get },
  2558. { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET, 3, light_lc_prop_set },
  2559. { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK, 3, light_lc_prop_set },
  2560. BLE_MESH_MODEL_OP_END,
  2561. };
  2562. static int light_server_init(struct bt_mesh_model *model)
  2563. {
  2564. if (model->user_data == NULL) {
  2565. BT_ERR("Invalid Lighting Server user data, model id 0x%04x", model->id);
  2566. return -EINVAL;
  2567. }
  2568. switch (model->id) {
  2569. case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV: {
  2570. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  2571. if (srv->state == NULL) {
  2572. BT_ERR("Invalid Light Lightness State");
  2573. return -EINVAL;
  2574. }
  2575. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2576. bt_mesh_server_alloc_ctx(&srv->actual_transition.timer.work);
  2577. bt_mesh_server_alloc_ctx(&srv->linear_transition.timer.work);
  2578. k_delayed_work_init(&srv->actual_transition.timer, light_lightness_actual_work_handler);
  2579. k_delayed_work_init(&srv->linear_transition.timer, light_lightness_linear_work_handler);
  2580. }
  2581. srv->model = model;
  2582. break;
  2583. }
  2584. case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV: {
  2585. struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
  2586. if (srv->state == NULL) {
  2587. BT_ERR("Invalid Light Lightness State");
  2588. return -EINVAL;
  2589. }
  2590. srv->model = model;
  2591. break;
  2592. }
  2593. case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
  2594. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  2595. if (srv->state == NULL) {
  2596. BT_ERR("Invalid Light CTL State");
  2597. return -EINVAL;
  2598. }
  2599. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2600. bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
  2601. k_delayed_work_init(&srv->transition.timer, light_ctl_work_handler);
  2602. }
  2603. srv->model = model;
  2604. break;
  2605. }
  2606. case BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV: {
  2607. struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
  2608. if (srv->state == NULL) {
  2609. BT_ERR("Invalid Light CTL State");
  2610. return -EINVAL;
  2611. }
  2612. srv->model = model;
  2613. break;
  2614. }
  2615. case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
  2616. struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
  2617. if (srv->state == NULL) {
  2618. BT_ERR("Invalid Light CTL State");
  2619. return -EINVAL;
  2620. }
  2621. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2622. bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
  2623. k_delayed_work_init(&srv->transition.timer, light_ctl_temp_work_handler);
  2624. }
  2625. srv->model = model;
  2626. break;
  2627. }
  2628. case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
  2629. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  2630. if (srv->state == NULL) {
  2631. BT_ERR("Invalid Light HSL State");
  2632. return -EINVAL;
  2633. }
  2634. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2635. bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
  2636. k_delayed_work_init(&srv->transition.timer, light_hsl_work_handler);
  2637. }
  2638. srv->model = model;
  2639. break;
  2640. }
  2641. case BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV: {
  2642. struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
  2643. if (srv->state == NULL) {
  2644. BT_ERR("Invalid Light HSL State");
  2645. return -EINVAL;
  2646. }
  2647. srv->model = model;
  2648. break;
  2649. }
  2650. case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
  2651. struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
  2652. if (srv->state == NULL) {
  2653. BT_ERR("Invalid Light HSL State");
  2654. return -EINVAL;
  2655. }
  2656. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2657. bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
  2658. k_delayed_work_init(&srv->transition.timer, light_hsl_hue_work_handler);
  2659. }
  2660. srv->model = model;
  2661. break;
  2662. }
  2663. case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
  2664. struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
  2665. if (srv->state == NULL) {
  2666. BT_ERR("Invalid Light HSL State");
  2667. return -EINVAL;
  2668. }
  2669. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2670. bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
  2671. k_delayed_work_init(&srv->transition.timer, light_hsl_sat_work_handler);
  2672. }
  2673. srv->model = model;
  2674. break;
  2675. }
  2676. case BLE_MESH_MODEL_ID_LIGHT_XYL_SRV: {
  2677. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  2678. if (srv->state == NULL) {
  2679. BT_ERR("Invalid Light xyL State");
  2680. return -EINVAL;
  2681. }
  2682. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2683. bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
  2684. k_delayed_work_init(&srv->transition.timer, light_xyl_work_handler);
  2685. }
  2686. srv->model = model;
  2687. break;
  2688. }
  2689. case BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV: {
  2690. struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
  2691. if (srv->state == NULL) {
  2692. BT_ERR("Invalid Light xyL State");
  2693. return -EINVAL;
  2694. }
  2695. srv->model = model;
  2696. break;
  2697. }
  2698. case BLE_MESH_MODEL_ID_LIGHT_LC_SRV: {
  2699. struct bt_mesh_light_lc_srv *srv = model->user_data;
  2700. if (srv->lc == NULL) {
  2701. BT_ERR("Invalid Light LC State");
  2702. return -EINVAL;
  2703. }
  2704. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2705. bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
  2706. k_delayed_work_init(&srv->transition.timer, light_lc_work_handler);
  2707. }
  2708. srv->model = model;
  2709. break;
  2710. }
  2711. case BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV: {
  2712. struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
  2713. if (srv->lc == NULL) {
  2714. BT_ERR("Invalid Light LC State");
  2715. return -EINVAL;
  2716. }
  2717. srv->model = model;
  2718. break;
  2719. }
  2720. default:
  2721. BT_WARN("Unknown Light Server, model id 0x%04x", model->id);
  2722. return -EINVAL;
  2723. }
  2724. bt_mesh_mutex_create(&light_server_lock);
  2725. return 0;
  2726. }
  2727. static int light_lightness_srv_init(struct bt_mesh_model *model)
  2728. {
  2729. if (model->pub == NULL) {
  2730. BT_ERR("Light Lightness Server has no publication support");
  2731. return -EINVAL;
  2732. }
  2733. /* When this model is present on an Element, the corresponding Light Lightness
  2734. * Setup Server model shall also be present.
  2735. */
  2736. struct bt_mesh_elem *element = bt_mesh_model_elem(model);
  2737. if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV) == NULL) {
  2738. BT_WARN("Light Lightness Setup Server not present");
  2739. /* Just give a warning here, continue with the initialization */
  2740. }
  2741. return light_server_init(model);
  2742. }
  2743. static int light_lightness_setup_srv_init(struct bt_mesh_model *model)
  2744. {
  2745. return light_server_init(model);
  2746. }
  2747. static int light_ctl_srv_init(struct bt_mesh_model *model)
  2748. {
  2749. if (model->pub == NULL) {
  2750. BT_ERR("Light CTL Server has no publication support");
  2751. return -EINVAL;
  2752. }
  2753. /**
  2754. * When this model is present on an Element, the corresponding Light CTL
  2755. * Temperature Server model and the corresponding Light CTL Setup Server
  2756. * model shall also be present.
  2757. * The model requires two elements: the main element and the Temperature
  2758. * element. The Temperature element contains the corresponding Light CTL
  2759. * Temperature Server model.
  2760. */
  2761. struct bt_mesh_elem *element = bt_mesh_model_elem(model);
  2762. if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV) == NULL) {
  2763. BT_WARN("Light CTL Setup Server not present");
  2764. /* Just give a warning here, continue with the initialization */
  2765. }
  2766. if (bt_mesh_elem_count() < 2) {
  2767. BT_WARN("Light CTL Server requires two elements");
  2768. /* Just give a warning here, continue with the initialization */
  2769. }
  2770. return light_server_init(model);
  2771. }
  2772. static int light_ctl_setup_srv_init(struct bt_mesh_model *model)
  2773. {
  2774. return light_server_init(model);
  2775. }
  2776. static int light_ctl_temp_srv_init(struct bt_mesh_model *model)
  2777. {
  2778. if (model->pub == NULL) {
  2779. BT_ERR("Light CTL Temperature Server has no publication support");
  2780. return -EINVAL;
  2781. }
  2782. return light_server_init(model);
  2783. }
  2784. static int light_hsl_srv_init(struct bt_mesh_model *model)
  2785. {
  2786. if (model->pub == NULL) {
  2787. BT_ERR("Light HSL Server has no publication support");
  2788. return -EINVAL;
  2789. }
  2790. /**
  2791. * When this model is present on an Element, the corresponding Light HSL Hue
  2792. * Server model and the corresponding Light HSL Saturation Server model and
  2793. * the corresponding Light HSL Setup Server model shall also be present.
  2794. * The model requires three elements: the main element and the Hue element
  2795. * and the Saturation element. The Hue element contains the corresponding
  2796. * Light HSL Hue Server model, and the Saturation element contains the
  2797. * corresponding Light HSL Saturation Server model.
  2798. */
  2799. struct bt_mesh_elem *element = bt_mesh_model_elem(model);
  2800. if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV) == NULL) {
  2801. BT_WARN("Light HSL Setup Server not present");
  2802. /* Just give a warning here, continue with the initialization */
  2803. }
  2804. if (bt_mesh_elem_count() < 3) {
  2805. BT_WARN("Light HSL Server requires three elements");
  2806. /* Just give a warning here, continue with the initialization */
  2807. }
  2808. return light_server_init(model);
  2809. }
  2810. static int light_hsl_setup_srv_init(struct bt_mesh_model *model)
  2811. {
  2812. return light_server_init(model);
  2813. }
  2814. static int light_hsl_hue_srv_init(struct bt_mesh_model *model)
  2815. {
  2816. if (model->pub == NULL) {
  2817. BT_ERR("Light HSL Hue Server has no publication support");
  2818. return -EINVAL;
  2819. }
  2820. return light_server_init(model);
  2821. }
  2822. static int light_hsl_sat_srv_init(struct bt_mesh_model *model)
  2823. {
  2824. if (model->pub == NULL) {
  2825. BT_ERR("Light HSL Saturation Server has no publication support");
  2826. return -EINVAL;
  2827. }
  2828. return light_server_init(model);
  2829. }
  2830. static int light_xyl_srv_init(struct bt_mesh_model *model)
  2831. {
  2832. if (model->pub == NULL) {
  2833. BT_ERR("Light xyL Server has no publication support");
  2834. return -EINVAL;
  2835. }
  2836. /**
  2837. * When this model is present on an Element, the corresponding Light xyL
  2838. * Setup Server model shall also be present.
  2839. */
  2840. struct bt_mesh_elem *element = bt_mesh_model_elem(model);
  2841. if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV) == NULL) {
  2842. BT_WARN("Light xyL Setup Server not present");
  2843. /* Just give a warning here, continue with the initialization */
  2844. }
  2845. return light_server_init(model);
  2846. }
  2847. static int light_xyl_setup_srv_init(struct bt_mesh_model *model)
  2848. {
  2849. return light_server_init(model);
  2850. }
  2851. static int light_lc_srv_init(struct bt_mesh_model *model)
  2852. {
  2853. if (model->pub == NULL) {
  2854. BT_ERR("Light LC Server has no publication support");
  2855. return -EINVAL;
  2856. }
  2857. return light_server_init(model);
  2858. }
  2859. static int light_lc_setup_srv_init(struct bt_mesh_model *model)
  2860. {
  2861. if (model->pub == NULL) {
  2862. BT_ERR("Light LC Setup Server has no publication support");
  2863. return -EINVAL;
  2864. }
  2865. /**
  2866. * When this model is present on an Element, the corresponding Light LC
  2867. * Setup Server model shall also be present.
  2868. */
  2869. struct bt_mesh_elem *element = bt_mesh_model_elem(model);
  2870. if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV) == NULL) {
  2871. BT_WARN("Light LC Setup Server not present");
  2872. /* Just give a warning here, continue with the initialization */
  2873. }
  2874. return light_server_init(model);
  2875. }
  2876. #if CONFIG_BLE_MESH_DEINIT
  2877. static int light_server_deinit(struct bt_mesh_model *model)
  2878. {
  2879. if (model->user_data == NULL) {
  2880. BT_ERR("Invalid Lighting Server user data, model id 0x%04x", model->id);
  2881. return -EINVAL;
  2882. }
  2883. switch (model->id) {
  2884. case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV: {
  2885. struct bt_mesh_light_lightness_srv *srv = model->user_data;
  2886. if (srv->state == NULL) {
  2887. BT_ERR("Invalid Light Lightness State");
  2888. return -EINVAL;
  2889. }
  2890. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2891. bt_mesh_server_free_ctx(&srv->actual_transition.timer.work);
  2892. bt_mesh_server_free_ctx(&srv->linear_transition.timer.work);
  2893. k_delayed_work_free(&srv->actual_transition.timer);
  2894. k_delayed_work_free(&srv->linear_transition.timer);
  2895. }
  2896. break;
  2897. }
  2898. case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
  2899. struct bt_mesh_light_ctl_srv *srv = model->user_data;
  2900. if (srv->state == NULL) {
  2901. BT_ERR("Invalid Light CTL State");
  2902. return -EINVAL;
  2903. }
  2904. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2905. bt_mesh_server_free_ctx(&srv->transition.timer.work);
  2906. k_delayed_work_free(&srv->transition.timer);
  2907. }
  2908. break;
  2909. }
  2910. case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
  2911. struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
  2912. if (srv->state == NULL) {
  2913. BT_ERR("Invalid Light CTL State");
  2914. return -EINVAL;
  2915. }
  2916. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2917. bt_mesh_server_free_ctx(&srv->transition.timer.work);
  2918. k_delayed_work_free(&srv->transition.timer);
  2919. }
  2920. break;
  2921. }
  2922. case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
  2923. struct bt_mesh_light_hsl_srv *srv = model->user_data;
  2924. if (srv->state == NULL) {
  2925. BT_ERR("Invalid Light HSL State");
  2926. return -EINVAL;
  2927. }
  2928. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2929. bt_mesh_server_free_ctx(&srv->transition.timer.work);
  2930. k_delayed_work_free(&srv->transition.timer);
  2931. }
  2932. break;
  2933. }
  2934. case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
  2935. struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
  2936. if (srv->state == NULL) {
  2937. BT_ERR("Invalid Light HSL State");
  2938. return -EINVAL;
  2939. }
  2940. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2941. bt_mesh_server_free_ctx(&srv->transition.timer.work);
  2942. k_delayed_work_free(&srv->transition.timer);
  2943. }
  2944. break;
  2945. }
  2946. case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
  2947. struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
  2948. if (srv->state == NULL) {
  2949. BT_ERR("Invalid Light HSL State");
  2950. return -EINVAL;
  2951. }
  2952. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2953. bt_mesh_server_free_ctx(&srv->transition.timer.work);
  2954. k_delayed_work_free(&srv->transition.timer);
  2955. }
  2956. break;
  2957. }
  2958. case BLE_MESH_MODEL_ID_LIGHT_XYL_SRV: {
  2959. struct bt_mesh_light_xyl_srv *srv = model->user_data;
  2960. if (srv->state == NULL) {
  2961. BT_ERR("Invalid Light xyL State");
  2962. return -EINVAL;
  2963. }
  2964. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2965. bt_mesh_server_free_ctx(&srv->transition.timer.work);
  2966. k_delayed_work_free(&srv->transition.timer);
  2967. }
  2968. break;
  2969. }
  2970. case BLE_MESH_MODEL_ID_LIGHT_LC_SRV: {
  2971. struct bt_mesh_light_lc_srv *srv = model->user_data;
  2972. if (srv->lc == NULL) {
  2973. BT_ERR("Invalid Light LC State");
  2974. return -EINVAL;
  2975. }
  2976. if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
  2977. bt_mesh_server_free_ctx(&srv->transition.timer.work);
  2978. k_delayed_work_free(&srv->transition.timer);
  2979. }
  2980. break;
  2981. }
  2982. case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV:
  2983. case BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV:
  2984. case BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV:
  2985. case BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV:
  2986. case BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV:
  2987. break;
  2988. default:
  2989. BT_WARN("Unknown Light Server, model id 0x%04x", model->id);
  2990. return -EINVAL;
  2991. }
  2992. bt_mesh_mutex_free(&light_server_lock);
  2993. return 0;
  2994. }
  2995. static int light_lightness_srv_deinit(struct bt_mesh_model *model)
  2996. {
  2997. if (model->pub == NULL) {
  2998. BT_ERR("Light Lightness Server has no publication support");
  2999. return -EINVAL;
  3000. }
  3001. return light_server_deinit(model);
  3002. }
  3003. static int light_lightness_setup_srv_deinit(struct bt_mesh_model *model)
  3004. {
  3005. return light_server_deinit(model);
  3006. }
  3007. static int light_ctl_srv_deinit(struct bt_mesh_model *model)
  3008. {
  3009. if (model->pub == NULL) {
  3010. BT_ERR("Light CTL Server has no publication support");
  3011. return -EINVAL;
  3012. }
  3013. return light_server_deinit(model);
  3014. }
  3015. static int light_ctl_setup_srv_deinit(struct bt_mesh_model *model)
  3016. {
  3017. return light_server_deinit(model);
  3018. }
  3019. static int light_ctl_temp_srv_deinit(struct bt_mesh_model *model)
  3020. {
  3021. if (model->pub == NULL) {
  3022. BT_ERR("Light CTL Temperature Server has no publication support");
  3023. return -EINVAL;
  3024. }
  3025. return light_server_deinit(model);
  3026. }
  3027. static int light_hsl_srv_deinit(struct bt_mesh_model *model)
  3028. {
  3029. if (model->pub == NULL) {
  3030. BT_ERR("Light HSL Server has no publication support");
  3031. return -EINVAL;
  3032. }
  3033. return light_server_deinit(model);
  3034. }
  3035. static int light_hsl_setup_srv_deinit(struct bt_mesh_model *model)
  3036. {
  3037. return light_server_deinit(model);
  3038. }
  3039. static int light_hsl_hue_srv_deinit(struct bt_mesh_model *model)
  3040. {
  3041. if (model->pub == NULL) {
  3042. BT_ERR("Light HSL Hue Server has no publication support");
  3043. return -EINVAL;
  3044. }
  3045. return light_server_deinit(model);
  3046. }
  3047. static int light_hsl_sat_srv_deinit(struct bt_mesh_model *model)
  3048. {
  3049. if (model->pub == NULL) {
  3050. BT_ERR("Light HSL Saturation Server has no publication support");
  3051. return -EINVAL;
  3052. }
  3053. return light_server_deinit(model);
  3054. }
  3055. static int light_xyl_srv_deinit(struct bt_mesh_model *model)
  3056. {
  3057. if (model->pub == NULL) {
  3058. BT_ERR("Light xyL Server has no publication support");
  3059. return -EINVAL;
  3060. }
  3061. return light_server_deinit(model);
  3062. }
  3063. static int light_xyl_setup_srv_deinit(struct bt_mesh_model *model)
  3064. {
  3065. return light_server_deinit(model);
  3066. }
  3067. static int light_lc_srv_deinit(struct bt_mesh_model *model)
  3068. {
  3069. if (model->pub == NULL) {
  3070. BT_ERR("Light LC Server has no publication support");
  3071. return -EINVAL;
  3072. }
  3073. return light_server_deinit(model);
  3074. }
  3075. static int light_lc_setup_srv_deinit(struct bt_mesh_model *model)
  3076. {
  3077. if (model->pub == NULL) {
  3078. BT_ERR("Light LC Setup Server has no publication support");
  3079. return -EINVAL;
  3080. }
  3081. return light_server_deinit(model);
  3082. }
  3083. #endif /* CONFIG_BLE_MESH_DEINIT */
  3084. const struct bt_mesh_model_cb bt_mesh_light_lightness_srv_cb = {
  3085. .init = light_lightness_srv_init,
  3086. #if CONFIG_BLE_MESH_DEINIT
  3087. .deinit = light_lightness_srv_deinit,
  3088. #endif /* CONFIG_BLE_MESH_DEINIT */
  3089. };
  3090. const struct bt_mesh_model_cb bt_mesh_light_lightness_setup_srv_cb = {
  3091. .init = light_lightness_setup_srv_init,
  3092. #if CONFIG_BLE_MESH_DEINIT
  3093. .deinit = light_lightness_setup_srv_deinit,
  3094. #endif /* CONFIG_BLE_MESH_DEINIT */
  3095. };
  3096. const struct bt_mesh_model_cb bt_mesh_light_ctl_srv_cb = {
  3097. .init = light_ctl_srv_init,
  3098. #if CONFIG_BLE_MESH_DEINIT
  3099. .deinit = light_ctl_srv_deinit,
  3100. #endif /* CONFIG_BLE_MESH_DEINIT */
  3101. };
  3102. const struct bt_mesh_model_cb bt_mesh_light_ctl_setup_srv_cb = {
  3103. .init = light_ctl_setup_srv_init,
  3104. #if CONFIG_BLE_MESH_DEINIT
  3105. .deinit = light_ctl_setup_srv_deinit,
  3106. #endif /* CONFIG_BLE_MESH_DEINIT */
  3107. };
  3108. const struct bt_mesh_model_cb bt_mesh_light_ctl_temp_srv_cb = {
  3109. .init = light_ctl_temp_srv_init,
  3110. #if CONFIG_BLE_MESH_DEINIT
  3111. .deinit = light_ctl_temp_srv_deinit,
  3112. #endif /* CONFIG_BLE_MESH_DEINIT */
  3113. };
  3114. const struct bt_mesh_model_cb bt_mesh_light_hsl_srv_cb = {
  3115. .init = light_hsl_srv_init,
  3116. #if CONFIG_BLE_MESH_DEINIT
  3117. .deinit = light_hsl_srv_deinit,
  3118. #endif /* CONFIG_BLE_MESH_DEINIT */
  3119. };
  3120. const struct bt_mesh_model_cb bt_mesh_light_hsl_setup_srv_cb = {
  3121. .init = light_hsl_setup_srv_init,
  3122. #if CONFIG_BLE_MESH_DEINIT
  3123. .deinit = light_hsl_setup_srv_deinit,
  3124. #endif /* CONFIG_BLE_MESH_DEINIT */
  3125. };
  3126. const struct bt_mesh_model_cb bt_mesh_light_hsl_hue_srv_cb = {
  3127. .init = light_hsl_hue_srv_init,
  3128. #if CONFIG_BLE_MESH_DEINIT
  3129. .deinit = light_hsl_hue_srv_deinit,
  3130. #endif /* CONFIG_BLE_MESH_DEINIT */
  3131. };
  3132. const struct bt_mesh_model_cb bt_mesh_light_hsl_sat_srv_cb = {
  3133. .init = light_hsl_sat_srv_init,
  3134. #if CONFIG_BLE_MESH_DEINIT
  3135. .deinit = light_hsl_sat_srv_deinit,
  3136. #endif /* CONFIG_BLE_MESH_DEINIT */
  3137. };
  3138. const struct bt_mesh_model_cb bt_mesh_light_xyl_srv_cb = {
  3139. .init = light_xyl_srv_init,
  3140. #if CONFIG_BLE_MESH_DEINIT
  3141. .deinit = light_xyl_srv_deinit,
  3142. #endif /* CONFIG_BLE_MESH_DEINIT */
  3143. };
  3144. const struct bt_mesh_model_cb bt_mesh_light_xyl_setup_srv_cb = {
  3145. .init = light_xyl_setup_srv_init,
  3146. #if CONFIG_BLE_MESH_DEINIT
  3147. .deinit = light_xyl_setup_srv_deinit,
  3148. #endif /* CONFIG_BLE_MESH_DEINIT */
  3149. };
  3150. const struct bt_mesh_model_cb bt_mesh_light_lc_srv_cb = {
  3151. .init = light_lc_srv_init,
  3152. #if CONFIG_BLE_MESH_DEINIT
  3153. .deinit = light_lc_srv_deinit,
  3154. #endif /* CONFIG_BLE_MESH_DEINIT */
  3155. };
  3156. const struct bt_mesh_model_cb bt_mesh_light_lc_setup_srv_cb = {
  3157. .init = light_lc_setup_srv_init,
  3158. #if CONFIG_BLE_MESH_DEINIT
  3159. .deinit = light_lc_setup_srv_deinit,
  3160. #endif /* CONFIG_BLE_MESH_DEINIT */
  3161. };
  3162. #endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */