/** * \file phy_model_server.c * * \brief This file defines the Mesh Configuration Model Application Interface * - includes Data Structures and Methods for both Server and Client. */ /* * Copyright (C) 2020. phyplus Ltd. * All rights reserved. */ /* --------------------------------------------- Header File Inclusion */ #include "phymodel_server.h" /* --------------------------------------------- Data Types/ Structures */ /* --------------------------------------------- Global Definitions */ /* --------------------------------------------- Static Global Variables */ static DECL_CONST UINT32 phy_model_server_opcode_list[] = { MS_ACCESS_PHY_MODEL_GET_OPCODE, MS_ACCESS_PHY_MODEL_SET_OPCODE, MS_ACCESS_PHY_MODEL_SET_UNACKNOWLEDGED_OPCODE, MS_ACCESS_PHY_MODEL_WRITECMD_OPCODE, MS_ACCESS_PHY_MODEL_CONFIRMATION_OPCODE, MS_ACCESS_PHY_MODEL_NOTIFY_OPCODE }; //static MS_ACCESS_MODEL_HANDLE phy_model_server_model_handle; static MS_PHY_MODEL_SERVER_CB phy_model_server_UI_cb; /* ----------------------------------------- Functions */ /** * \brief API to send reply or to update state change * * \par Description * This is to send reply for a request or to inform change in state. * * \param [in] ctx Context of the message. * \param [in] current_state_params Model specific current state parameters. * \param [in] target_state_params Model specific target state parameters (NULL: to be ignored). * \param [in] remaining_time Time from current state to target state (0: to be ignored). * \param [in] ext_params Additional parameters (NULL: to be ignored). * * \return API_SUCCESS or an error code indicating reason for failure */ API_RESULT MS_phy_model_server_state_update ( /* IN */ MS_ACCESS_MODEL_REQ_MSG_CONTEXT * ctx, /* IN */ MS_ACCESS_PHY_MODEL_STATE_PARAMS * current_state_params, /* IN */ MS_ACCESS_MODEL_STATE_PARAMS * target_state_params, /* IN */ UINT16 remaining_time, /* IN */ MS_ACCESS_MODEL_EXT_PARAMS * ext_params, /* IN */ UINT16 data_length ) { API_RESULT retval; /* TODO: Check what should be maximum length */ UCHAR buffer[256]; UCHAR * pdu_ptr; UINT16 marker; UINT32 opcode; // UINT16 ttl; // ACCESS_CM_GET_RX_TTL(ttl); retval = API_FAILURE; marker = 0; // printf( // "current_state_params->state_type 0x%04X.\n",current_state_params->phy_mode_type); switch (current_state_params->phy_mode_type) { case MS_STATE_PHY_MODEL_ONOFF_T: { buffer[marker] = ++vendor_tid; marker++; MS_PACK_LE_2_BYTE_VAL(&buffer[marker], current_state_params->phy_mode_type); marker += 2; EM_mem_copy(&buffer[marker], current_state_params->phy_mode_param, 1); marker++; /* Set Opcode */ opcode = MS_ACCESS_PHY_MODEL_STATUS_OPCODE; } break; case MS_STATE_PHYMODEL_NOTIFY_T: { EM_mem_copy(&buffer[marker], current_state_params->phy_mode_param, data_length); marker += data_length; /* Set Opcode */ opcode = MS_ACCESS_PHY_MODEL_NOTIFY_OPCODE; } break; default: break; } /* Publish - reliable */ if (0 == marker) { pdu_ptr = NULL; } else { pdu_ptr = buffer; } cfg_retry_flag = 1; retval = MS_access_reply ( &ctx->handle, ctx->daddr, ctx->saddr, ctx->subnet_handle, ctx->appkey_handle, ACCESS_INVALID_DEFAULT_TTL, opcode, pdu_ptr, marker ); return retval; } /** * \brief Access Layer Application Asynchronous Notification Callback. * * \par Description * Access Layer calls the registered callback to indicate events occurred to the application. * * \param [in] handle Model Handle. * \param [in] saddr 16 bit Source Address. * \param [in] daddr 16 bit Destination Address. * \param [in] appkey_handle AppKey Handle. * \param [in] subnet_handle Subnet Handle. * \param [in] opcode Opcode. * \param [in] data_param Data associated with the event if any or NULL. * \param [in] data_len Size of the event data. 0 if event data is NULL. */ API_RESULT phy_model_server_cb ( /* IN */ MS_ACCESS_MODEL_HANDLE * handle, /* IN */ MS_NET_ADDR saddr, /* IN */ MS_NET_ADDR daddr, /* IN */ MS_SUBNET_HANDLE subnet_handle, /* IN */ MS_APPKEY_HANDLE appkey_handle, /* IN */ UINT32 opcode, /* IN */ UCHAR * data_param, /* IN */ UINT16 data_len ) { MS_ACCESS_MODEL_REQ_MSG_CONTEXT req_context; MS_ACCESS_MODEL_REQ_MSG_RAW req_raw; MS_ACCESS_MODEL_REQ_MSG_T req_type; MS_ACCESS_MODEL_EXT_PARAMS * ext_params_p; MS_ACCESS_PHY_MODEL_STATE_PARAMS state_params; UINT16 marker; API_RESULT retval; retval = API_SUCCESS; ext_params_p = NULL; marker = 0; /* Request Context */ req_context.handle = *handle; req_context.saddr = saddr; req_context.daddr = daddr; req_context.subnet_handle = subnet_handle; req_context.appkey_handle = appkey_handle; /* Request Raw */ req_raw.opcode = opcode; req_raw.data_param = data_param; req_raw.data_len = data_len; state_params.phy_mode_param = NULL; switch(opcode) { case MS_ACCESS_PHY_MODEL_GET_OPCODE: { // printf( // "MS_ACCESS_PHY_MODEL_GET_OPCODE\n"); MODEL_OPCODE_HANDLER_CALL(vendor_example_get_handler); marker = 1; MS_UNPACK_LE_2_BYTE(&state_params.phy_mode_type, data_param+marker); marker += 2; /* Get Request Type */ req_type.type = MS_ACCESS_MODEL_REQ_MSG_T_GET; req_type.to_be_acked = 0x01; /* Assign reqeusted state type to the application */ } break; case MS_ACCESS_PHY_MODEL_SET_OPCODE: case MS_ACCESS_PHY_MODEL_SET_UNACKNOWLEDGED_OPCODE: { // printf( // "MS_ACCESS_PHY_MODEL_SET_OPCODE\n"); MODEL_OPCODE_HANDLER_CALL(vendor_example_set_handler); marker = 1; MS_UNPACK_LE_2_BYTE(&state_params.phy_mode_type, data_param+marker); marker += 2; state_params.phy_mode_param = &data_param[marker]; /* Set Request Type */ req_type.type = MS_ACCESS_MODEL_REQ_MSG_T_SET; if(MS_ACCESS_PHY_MODEL_SET_OPCODE == opcode) { req_type.to_be_acked = 0x01; } else { req_type.to_be_acked = 0x00; } } break; case MS_ACCESS_PHY_MODEL_STATUS_OPCODE: { // printf( // "MS_ACCESS_PHY_MODEL_STATUS\n"); MODEL_OPCODE_HANDLER_CALL(vendor_example_status_handler); /* Set Request Type */ req_type.type = MS_ACCESS_MODEL_REQ_MSG_T_OTHERS; req_type.to_be_acked = 0x00; } break; case MS_ACCESS_PHY_MODEL_CONFIRMATION_OPCODE: { // printf( // "MS_ACCESS_PHY_MODEL_CONFIRMATION\n"); MODEL_OPCODE_HANDLER_CALL(vendor_example_confirmation_handler); /* Set Request Type */ req_type.type = MS_ACCESS_MODEL_REQ_MSG_T_OTHERS; req_type.to_be_acked = 0x00; } break; case MS_ACCESS_PHY_MODEL_WRITECMD_OPCODE: { // printf( // "MS_ACCESS_PHY_MODEL_WRITECMD_OPCODE\n"); marker = 1; MS_UNPACK_LE_2_BYTE(&state_params.phy_mode_type, data_param+marker); marker += 2; state_params.phy_mode_param = &data_param[marker]; /* Set Request Type */ req_type.type = MS_ACCESS_MODEL_REQ_MSG_T_OTHERS; req_type.to_be_acked = 0x00; } break; case MS_ACCESS_PHY_MODEL_NOTIFY_OPCODE: { state_params.phy_mode_type = MS_STATE_PHYMODEL_NOTIFY_T; marker = 1; state_params.phy_mode_param = &data_param[marker]; /* Set Request Type */ req_type.type = MS_ACCESS_MODEL_REQ_MSG_T_OTHERS; req_type.to_be_acked = 0x00; } break; default: // printf( // "MS_ACCESS_PHY_MODEL_NONE_OPCODE\n"); break; } /* Application callback */ if (NULL != phy_model_server_UI_cb) { phy_model_server_UI_cb(&req_context, &req_raw, &req_type, &state_params, ext_params_p); } return retval; } /** * \brief API to initialize Vendor_Example_1 Server model * * \par Description * This is to initialize Vendor_Example_1 Server model and to register with Acess layer. * * \param [in] element_handle * Element identifier to be associated with the model instance. * * \param [in, out] model_handle * Model identifier associated with the model instance on successful initialization. * After power cycle of an already provisioned node, the model handle will have * valid value and the same will be reused for registration. * * \param [in] UI_cb Application Callback to be used by the Vendor_Example_1 Server. * * \return API_SUCCESS or an error code indicating reason for failure */ API_RESULT MS_phy_model_server_init ( /* IN */ MS_ACCESS_ELEMENT_HANDLE element_handle, /* INOUT */ MS_ACCESS_MODEL_HANDLE * model_handle, /* IN */ MS_PHY_MODEL_SERVER_CB UI_cb ) { API_RESULT retval; MS_ACCESS_NODE_ID node_id; MS_ACCESS_MODEL model; /* TBD: Initialize MUTEX and other data structures */ /* Using default node ID */ node_id = MS_ACCESS_DEFAULT_NODE_ID; /* Configure Model */ model.model_id.id = MS_MODEL_ID_PHY_MODEL_SERVER; model.model_id.type = MS_ACCESS_MODEL_TYPE_VENDOR; model.elem_handle = element_handle; /* Register Callback */ model.cb = phy_model_server_cb; /* List of Opcodes */ model.opcodes = phy_model_server_opcode_list; model.num_opcodes = sizeof(phy_model_server_opcode_list) / sizeof(UINT32); retval = MS_access_register_model ( node_id, &model, model_handle ); /* Save Application Callback */ phy_model_server_UI_cb = UI_cb; // /* TODO: Remove */ // phy_model_server_model_handle = *model_handle; return retval; }