diff --git a/driver/software/MiWi/MiWi_Mesh/inc/miwi_api.h b/driver/software/MiWi/MiWi_Mesh/inc/miwi_api.h index 388a9c9..3045363 100644 --- a/driver/software/MiWi/MiWi_Mesh/inc/miwi_api.h +++ b/driver/software/MiWi/MiWi_Mesh/inc/miwi_api.h @@ -1217,9 +1217,9 @@ typedef struct AppMessage_t { struct { uint8_t type; uint8_t size; - char text[APP_CAPTION_SIZE]; + char text[29]; }caption; - DataConf_callback_t ConfCallback; + DataConf_callback_t ConfCallback; }__attribute__((packed, aligned(1)))AppMessage_t; diff --git a/driver/software/MiWi/MiWi_Mesh/inc/miwi_api.h.bak b/driver/software/MiWi/MiWi_Mesh/inc/miwi_api.h.bak new file mode 100644 index 0000000..cd17672 --- /dev/null +++ b/driver/software/MiWi/MiWi_Mesh/inc/miwi_api.h.bak @@ -0,0 +1,1247 @@ +/** +* \file miwi_api.h +* +* \brief Application Program Interface for MiWi Protocols. +* +* Copyright (c) 2023 - 2024 Microchip Technology Inc. and its subsidiaries. +* +* \asf_license_start +* +* \page License +* +* Subject to your compliance with these terms, you may use Microchip +* software and any derivatives exclusively with Microchip products. +* It is your responsibility to comply with third party license terms applicable +* to your use of third party software (including open source software) that +* may accompany Microchip software. +* +* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, +* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, +* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, +* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE +* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL +* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE +* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE +* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT +* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY +* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, +* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. +* +* \asf_license_stop +* +*/ +/* +* Support and FAQ: visit Microchip Support +*/ + +#ifndef MIWI_API_H +#define MIWI_API_H + +#include +#include +#include "config/default/definitions.h" + +#define MIWI_MAJOR_VERSION '6' +#define MIWI_MINOR_VERSION '5' + +#define LONG_ADDR_LEN 8U + +#define COORDINATOR_ADDRESS_MASK 0xFF00U +#define ENDEVICE_ADDRESS_MASK 0x00FFU +#define RXON_ENDEVICE_ADDRESS_MASK 0x0080U + +#define MESH_BROADCAST_TO_ALL (0xFFFFU) +#define MESH_BROADCAST_TO_FFDS (0xFFFEU) +#define MESH_BROADCAST_TO_COORDINATORS (0xFFFDU) + +typedef union +{ + uint8_t v[4]; + uint16_t w[2]; + uint32_t Val; +}API_UINT32_UNION; + +typedef union +{ + uint8_t v[8]; + uint16_t w[4]; + uint32_t d[2]; + uint64_t Val; +}API_UINT64_UNION; + +typedef union +{ + uint8_t v[2]; + uint16_t Val; +}API_UINT16_UNION; + +typedef enum miwi_status { + SUCCESS = 0, + FAILURE, + CHANNEL_ACCESS_FAILURE, + NO_ACK, + TIMER_EXPIRED, + TRANSACTION_EXPIRED = 5, + ALREADY_EXISTS, + NO_ROUTE, + SCAN_NO_BEACON, + SCAN_MAX_REACHED, + MEMORY_UNAVAILABLE = 10, + ERR_TX_FAIL, + ERR_TRX_FAIL, + ERR_INVALID_INPUT, + RECONNECTION_IN_PROGRESS, + RECONNECTED, + ADDR_NOT_FOUND_IN_SCANNED_LIST, + ENTRY_NOT_EXIST = 0xF0, + NOT_ENOUGH_SPACE = 0xF1, + NOT_SAME_PAN = 0xF2, + NOT_PERMITTED = 0xF3, + ACTIVE_SCAN = 0xF4, +}miwi_status_t; + +enum miwi_params { + CHANNEL = 0x00U, + PANID = 0x01U, + SHORT_ADDRESS = 0x02U, + PARENT_SHORT_ADDRESS = 0x03U, + DEVICE_TIMEOUT = 0x04U, + CHANNELMAP = 0x05U, + CAPABILITYINFO = 0x06U, + BLOOM_AUTO_JOIN = 0x80U, + ROUTE_TEST_MODE = 0x81U +}; +typedef enum +{ + MIWI_START_NW, + MIWI_CONNECT_NW, + MIWI_SEND_DATA, + MIWI_TXDONE_CB, +} eAPI_ID; + +typedef enum miwi_params miwi_params_t; +miwi_status_t PhyToMiwi_Status(PHY_Retval_t status); + + +#if defined(PROTOCOL_MESH) +#define BLOOM_FILTER_SIZE 8U + +typedef struct +{ + /** coordinator hop */ + uint8_t coordinatorHop; + + /** connection permit */ + uint8_t connectionPermit; + + /** End device Capacity percentage */ + uint8_t enddeviceCapacity; + + /** Sleeping End device Capacity percentage */ + uint8_t sleepEnddeviceCapacity; + + /** The current logical channel used by the network */ + uint8_t logicalChannel; + + /** LQI at which the beacon was received */ + uint8_t LinkQuality; + + /** PANID */ + uint16_t panId; + + /** Short Address */ + uint16_t shortAddress; + + /** bloom filter value */ + uint8_t bloomFilterValue[BLOOM_FILTER_SIZE]; + +} beaconDescriptor_t; + +typedef struct +{ + /* status of the search request */ + uint8_t status; + + /* the number of results found */ + uint8_t resultSize; + + /* unscanned channels during search */ + uint32_t unscannedChannels; + + beaconDescriptor_t beaconList[MAX_BEACON_RESULTS]; +} searchConf_t; +#endif + + +#ifdef MESH_SECURITY +extern API_UINT32_UNION meshOutgoingFrameCounter; +#endif + +// Source address when sending a packet // can be MAC_Address or EUI based on Users choice +extern uint8_t myLongAddress[MY_ADDRESS_LENGTH]; + +// the no of connections on a device. +// In case of Star network conn_size will be shared by pan co to all the end devices. +// In case of p2p network every device will have all its on conn_size. +extern uint8_t conn_size ; + +#define SECURITY_KEY_SIZE 16U + + +#define HOP_TABLE_COUNT (((NUM_OF_COORDINATORS % 2) == 0)? \ + (NUM_OF_COORDINATORS / 2) : \ + ((NUM_OF_COORDINATORS / 2) + 1)) + +/* Table maintained by the PAN Coordinator to store the list of joiner which it + * wants to commission*/ +typedef struct +{ + uint64_t deviceAddress; +} CommDeviceTable_t; + +typedef struct _CoordHopCount_t +{ + uint8_t lsb : 4; + uint8_t msb : 4; +} CoordHopCount_t; + +typedef struct _CoordRouteTable_t +{ + uint8_t nextHopAddr; + uint8_t lqi : 4; + uint8_t score : 4; +} CoordRouteTable_t; + +typedef struct _RouteEntry_t +{ + uint8_t coordNextHop; + uint8_t coordHopCount; + uint8_t coordNextHopLQI; + uint8_t coordScore; +} RouteEntry_t; + +/* Coordinator Table - which holds the joined router details */ +typedef struct coordinatorTable_ +{ + uint8_t ieeeaddr[LONG_ADDR_LEN]; + uint32_t currentTimeOut; +}CoordinatorTable_t; + +/* Capability Information of a device */ +typedef union CapabilityInfo +{ + uint8_t Val; + struct + { + uint8_t rxonwhenIdle: 1; + uint8_t deviceType: 2; + uint8_t reserved: 5; + } bits; +} CapabilityInfo_t; + +/* Wish to Join As */ +typedef union JoinWish +{ + uint8_t Val; + struct + { + uint8_t ed: 1; + uint8_t coordinator: 2; + uint8_t reserved: 5; + } bits; +} JoinWish_t; + +/* Device Table - which holds the joined end device RxONdetails */ +typedef struct deviceTable_ +{ + uint8_t ieeeaddr[LONG_ADDR_LEN]; + uint32_t currentTimeOut; + CapabilityInfo_t capabilityInfo; +}DeviceTable_t; + +/* Device Table - which holds the joined end device details */ +typedef struct SleepDeviceTable_ +{ + uint8_t ieeeaddr[LONG_ADDR_LEN]; + uint32_t actualTimeOut; + uint32_t currentTimeOut; + CapabilityInfo_t capabilityInfo; +}SleepDeviceTable_t; + +typedef struct RebroadcastTable_ +{ + uint16_t nwkSrcAddr; + uint8_t nwkSeqNo; + uint8_t timeout; +}RebroadcastTable_t; + +typedef struct DuplicateRejectionTable_ +{ + uint16_t srcAddr; + uint8_t seqNo; + uint8_t timeout; +}DuplicateRejectionTable_t; + +typedef struct __defaultParametersRomOrRam +{ +#if defined(PROTOCOL_MESH) +#ifndef ENDDEVICE +#ifdef PAN_COORDINATOR + CoordinatorTable_t *coordTable; + CommDeviceTable_t *commDevTable; +#endif + DeviceTable_t *devTable; + SleepDeviceTable_t *sleepingDevTable; + CoordRouteTable_t *coordinatorRouteTable; + CoordHopCount_t *coordinatorHopCount; + RebroadcastTable_t *rebroadcastTable; + + uint32_t indirectDataWaitInterval; + + uint16_t keepAliveCoordSendInterval; + uint16_t keepAliveCoordTimeoutSec; + + const uint8_t maxNumOfDevicesInNetwork; + + const uint8_t roleUpgradeIntervalInSec; + const uint8_t numOfRxOnEnddevices; + const uint8_t numOfRxOffEnddevices; + + const uint8_t routeUpdateInterval; + const uint8_t routeReqWaitInterval; + + const uint8_t rebroadcastTableSize; + const uint8_t rebroadcastTimeout; +#endif + DuplicateRejectionTable_t *duplicateRejectionTable; + const uint32_t deviceTimeout; + const uint16_t keepAliveRxOnEdSendInterval; + const uint16_t keepAliveRxOnEdTimeoutSec; + uint16_t myPANID; + const uint8_t duplicateRejectionTableSize; + const uint8_t numOfCoordinators; + const uint32_t dataRequestInterval; + const uint32_t maxDataRequestInterval; + + const uint8_t edLinkFailureAttempts; + const uint8_t connRespWaitInSec; + uint8_t frameRetry; + uint8_t joinWish; +#ifndef PAN_COORDINATOR + searchConf_t* searchConfMem; + uint8_t maxNoOfBeacons; +#endif +#else + CONNECTION_ENTRY *ConnectionTable; + ACTIVE_SCAN_RESULT *ActiveScanResults; + uint8_t *AdditionalNodeID; + uint8_t networkFreezerRestore; +#endif +} defaultParametersRomOrRam_t; + +typedef struct __defaultParametersRamOnly +{ +#ifdef MESH_SECURITY + uint8_t miwiPublicKey[SECURITY_KEY_SIZE]; + uint8_t miwiNetworkKey[SECURITY_KEY_SIZE]; + uint8_t securityLevel; +#endif + uint8_t dummy; +} defaultParametersRamOnly_t; + +extern defaultParametersRomOrRam_t defaultParamsRomOrRam; + +extern defaultParametersRamOnly_t defaultParamsRamOnly; +/************************************************************************************ +* Function: +* miwi_status_t MiApp_ProtocolInit(defaultParametersRomOrRam_t *defaultRomOrRamParams, +* defaultParametersRamOnly_t *defaultRamOnlyParams) +* +* Summary: +* This function initialize the Microchip proprietary wireless protocol +* +* Description: +* This is the primary user interface function to initialize the Microchip +* proprietary wireless protocol, which is chosen by the application layer. +* Usually, this function must be called after the hardware initialization, +* before any other MiApp interface can be called. +* +* PreCondition: +* Hardware initialization has been done. +* +* Parameters: +* defaultParametersRomOrRam_t *defaultRomOrRamParams - Default parameters for MiWi Mesh. +* defaultParametersRamOnly_t *defaultRamOnlyParams - Default parameters for MiWi Mesh. +* Ignored in case of P2P / Star +* +* Returns: +* miwi_status_t status of Initialization +* In Mesh, when Network Freezer is enabled, stack try to restores the network freezer +* data and tries to reconnect to the network, this is indicated with reconnection progress status +* +* Example: +* +* HardwareInit(); +* MiApp_ProtocolInit(); +* +* +* Remarks: +* None +* +*********************************************************************************/ +miwi_status_t MiApp_ProtocolInit(void); + +/************************************************************************************ +* Function: +* bool MiApp_Set(set_params id, uint8_t *value ) +* +* Summary: +* This function sets the information base values +* +* Description: +* This is the primary user interface function to set the different values in the MiWi +* stack +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* set_params id - The identifier of the value to be set +* value - value to be set +* +* Returns: +* a boolean to indicate if set operation has been performed successfully +* +* Example: +* +* if( true == MiApp_Set(CHANNEL, 15) ) +* { +* // channel changes successfully +* } +* +* +* Remarks: +* None +* +*********************************************************************************/ +bool MiApp_Set(miwi_params_t id, uint8_t *value); + +bool MiTrxParam_Get(miwi_params_t id, uint8_t *value); + +#define START_CONN_DIRECT 0x00 +#define START_CONN_ENERGY_SCN 0x01 +#define START_CONN_CS_SCN 0x02 + +typedef void (*connectionConf_callback_t)(miwi_status_t status); + +/************************************************************************************ +* Function: +* bool MiApp_StartConnection(uint8_t Mode, uint8_t ScanDuration, uint32_t ChannelMap, +* connectionConf_callback_t ConfCallback) +* +* Summary: +* This function start a PAN without connected to any other devices +* +* Description: +* This is the primary user interface function for the application layer to +* a PAN. Usually, this fucntion is called by the PAN Coordinator who is the +* first in the PAN. The PAN Coordinator may start the PAN after a noise scan +* if specified in the input mode. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* uint8_t Mode - Whether to start a PAN after a noise scan. Possible modes are +* * START_CONN_DIRECT Start PAN directly without noise scan +* * START_CONN_ENERGY_SCN Perform an energy scan first, then +* start the PAN on the channel with least +* noise. +* * START_CONN_CS_SCN Perform a carrier-sense scan first, +* then start the PAN on the channel with +* least noise. +* uint8_t ScanDuration - The maximum time to perform scan on single channel. The +* value is from 5 to 14. The real time to perform scan can +* be calculated in following formula from IEEE 802.15.4 +* specification: +* 960 * (2^ScanDuration + 1) * 10^(-6) second +* ScanDuration is discarded if the connection mode is +* START_CONN_DIRECT. +* uint32_t ChannelMap - The bit map of channels to perform noise scan. The 32-bit +* double word parameter use one bit to represent corresponding +* channels from 0 to 31. For instance, 0x00000003 represent to +* scan channel 0 and channel 1. ChannelMap is discarded if the +* connection mode is START_CONN_DIRECT. +* +* connectionConf_callback_t ConfCallback - The callback routine which will be called upon +* the initiated connection procedure is performed +* Returns: +* a boolean to indicate if PAN has been started successfully. +* +* Example: +* +* // start the PAN on the least noisy channel after scanning all possible channels. +* MiApp_StartConnection(START_CONN_ENERGY_SCN, 10, 0xFFFFFFFF, callback); +* +* +* Remarks: +* None +* +*****************************************************************************************/ +bool MiApp_StartConnection( uint8_t Mode, uint8_t ScanDuration, uint32_t ChannelMap, +connectionConf_callback_t ConfCallback); + +typedef void (*SearchConnectionConf_callback_t)(uint8_t foundScanResults, void* ScanResults); +/************************************************************************************ +* Function: +* uint8_t MiApp_SearchConnection(uint8_t ScanDuartion, uint32_t ChannelMap, +* SearchConnectionConf_callback_t ConfCallback) +* +* Summary: +* This function perform an active scan to locate operating PANs in the +* neighborhood. +* +* Description: +* This is the primary user interface function for the application layer to +* perform an active scan. After this function call, all active scan response +* will be stored in the global variable ActiveScanResults in the format of +* structure ACTIVE_SCAN_RESULT. The return value indicates the total number +* of valid active scan response in the active scan result array. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* uint8_t ScanDuration - The maximum time to perform scan on single channel. The +* value is from 5 to 14. The real time to perform scan can +* be calculated in following formula from IEEE 802.15.4 +* specification +* 960 * (2^ScanDuration + 1) * 10^(-6) second +* uint32_t ChannelMap - The bit map of channels to perform noise scan. The 32-bit +* double word parameter use one bit to represent corresponding +* channels from 0 to 31. For instance, 0x00000003 represent to +* scan channel 0 and channel 1. +* SearchConnectionConf_callback_t ConfCallback - The callback routine which will be called upon +* the initiated connection procedure is performed +* +* Returns: +* The number of valid active scan response stored in the global variable ActiveScanResults. +* +* Example: +* +* // Perform an active scan on all possible channels +* NumOfActiveScanResponse = MiApp_SearchConnection(10, 0xFFFFFFFF, callback); +* +* +* Remarks: +* None +* +*****************************************************************************************/ +uint8_t MiApp_SearchConnection(uint8_t ScanDuration, uint32_t ChannelMap, +SearchConnectionConf_callback_t ConfCallback); + +#define CONN_MODE_DIRECT 0x00 +#define CONN_MODE_INDIRECT 0x01 +/************************************************************************************ +* Function: +* uint8_t MiApp_EstablishConnection(uint8_t Channel, uint8_t addr_len, uint8_t *addr, uint8_t Capability_info, +* connectionConf_callback_t ConfCallback) +* +* Summary: +* This function establish a connection with one or more nodes in an existing +* PAN. +* +* Description: +* This is the primary user interface function for the application layer to +* start communication with an existing PAN. For P2P protocol, this function +* call can establish one or more connections. For network protocol, this +* function can be used to join the network, or establish a virtual socket +* connection with a node out of the radio range. There are multiple ways to +* establish connection(s), all depends on the input parameters. +* +* PreCondition: +* Protocol initialization has been done. If only to establish connection with +* a predefined device, an active scan must be performed before and valid active +* scan result has been saved. +* +* Parameters: +* uint8_t channel - The selected channel to invoke join procedure. +* uint8_t addr_len - Address length +* uint8_t *addr - address of the parent +* uint8_t Capability_info - capability information of the device +* connectionConf_callback_t ConfCallback - The callback routine which will be called upon +* the initiated connection procedure is performed +* +* Returns: +* The index of the peer device on the connection table. +* +* Example: +* +* // Establish one or more connections with any device +* PeerIndex = MiApp_EstablishConnection(14, 8, 0x12345678901234567,0x80, callback); +* +* +* Remarks: +* If more than one connections have been established through this function call, the +* return value points to the index of one of the peer devices. +* +*****************************************************************************************/ +uint8_t MiApp_EstablishConnection(uint8_t Channel, uint8_t addr_len, uint8_t *addr, uint8_t Capability_info, +connectionConf_callback_t ConfCallback); + + +#define ENABLE_ALL_CONN 0x00 +#define ENABLE_PREV_CONN 0x01 +#define ENABLE_ACTIVE_SCAN_RSP 0x02 +#define DISABLE_ALL_CONN 0x03 + + +typedef void (*DataConf_callback_t)(uint8_t msgConfHandle, miwi_status_t status, uint8_t* msgPointer); + +/************************************************************************************ +* Function: +* bool MiApp_SendData(uint8_t addr_len, uint8_t *addr, uint8_t msglen, uint8_t *msgpointer, +uint8_t msghandle, DataConf_callback_t ConfCallback); +* +* Summary: +* This function unicast a message in the msgpointer to the device with DestinationAddress +* +* Description: +* This is one of the primary user interface functions for the application layer to +* unicast a message. The destination device is specified by the input parameter +* DestinationAddress. The application payload is filled using msgpointer. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* uint8_t addr_len - destionation address length +* uint8_t *addr - destionation address +* uint8_t msglen - length of the message +* uint8_t *msgpointer - message/frame pointer +* uint8_t msghandle - message handle +* bool ackReq - set to receive network level ack (Note- Discarded for broadcast data) +* DataConf_callback_t ConfCallback - The callback routine which will be called upon +* the initiated data procedure is performed +* +* Returns: +* A boolean to indicates if the unicast procedure is succcessful. +* +* Example: +* +* // Secure and then broadcast the message stored in msgpointer to the permanent address +* // specified in the input parameter. +* MiApp_SendData(SHORT_ADDR_LEN, 0x0004, len, frameptr,1, callback); +* +* +* Remarks: +* None +* +*****************************************************************************************/ +bool MiApp_SendData(uint8_t addr_len, uint8_t *addr, uint8_t msglen, uint8_t *msgpointer, uint8_t msghandle,bool ackReq, DataConf_callback_t ConfCallback); + +#define BROADCAST_TO_ALL 0x01 +#define MULTICAST_TO_COORDINATORS 0x02 +#define MULTICAST_TO_FFDS 0x03 +/*************************************************************************** +* Received Message information +* +* This structure contains information about the received application +* message. +**************************************************************************/ +typedef struct +{ +union +{ +uint8_t Val; +struct +{ +uint8_t broadcast: 2; // 1: broadcast message +uint8_t ackReq: 1; // 1: sender request acknowledgement in MAC. +uint8_t secEn: 1; // 1: application payload has been secured +uint8_t repeat: 1; // 1: message received through a repeater +uint8_t command: 1; // 1: message is a command frame +uint8_t srcPrsnt: 1; // 1: source address present in the packet +uint8_t altSrcAddr: 1; // 1: source address is alternative network address +} bits; +} flags; + +API_UINT16_UNION SourcePANID; // PAN Identifier of the sender +uint8_t *SourceAddress; // pointer to the source address +uint8_t *Payload; // pointer to the application payload +uint8_t PayloadSize; // application payload length +uint8_t PacketRSSI; // RSSI value of the receive message +uint8_t PacketLQI; // LQI value of the received message + +} RECEIVED_MESSAGE; + + +#if defined(PROTOCOL_MESH) +typedef struct +{ +uint16_t sourceAddress; // source address +uint8_t *payload; // pointer to the application payload +uint8_t payloadSize; // application payload length +uint8_t packetRSSI; // RSSI value of the receive message +uint8_t packetLQI; // LQI value of the received message +} RECEIVED_MESH_MESSAGE; +#endif + +#if defined(PROTOCOL_MESH) +typedef void (*PacketIndCallback_t)(RECEIVED_MESH_MESSAGE *ind); +#endif +/************************************************************************************ +* Function: +* bool MiApp_SubscribeDataIndicationCallback(PacketIndCallback_t callback) +* +* Summary: +* This function return a boolean if subscribtion for rx message is successful +* +* Description: +* This is the primary user interface functions for the application layer to +* call the Microchip proprietary protocol stack to register for message indication +* callback to the application. The function will call the protocol stack state machine +* to keep the stack running. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* None +* +* Returns: +* A boolean to indicates if the subscription operation is successful or not. +* +* Example: +* +* if( true == MiApp_SubscribeDataIndicationCallback(ind) ) +* { +* } +* +* uint8_t NoiseLevel; +* OptimalChannel = MiApp_NoiseDetection(0xFFFFFFFF, 10, NOISE_DETECT_ENERGY, &NoiseLevel); +* +* +* Remarks: +* None +* +*****************************************************************************************/ +uint8_t MiApp_NoiseDetection(uint32_t ChannelMap, uint8_t ScanDuration, uint8_t DetectionMode, uint8_t *NoiseLevel); + +#define POWER_STATE_SLEEP 0x00 +#define POWER_STATE_WAKEUP 0x01 +#define POWER_STATE_WAKEUP_DR 0x02 +/************************************************************************************ +* Function: +* uint8_t MiApp_TransceiverPowerState(uint8_t Mode) +* +* Summary: +* This function put the RF transceiver into different power state. i.e. Put the +* RF transceiver into sleep or wake it up. +* +* Description: +* This is the primary user interface functions for the application layer to +* put RF transceiver into sleep or wake it up. This function is only available +* to those wireless nodes that may have to disable the transceiver to save +* battery power. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* uint8_t Mode - The mode of power state for the RF transceiver to be set. The possible +* power states are following +* * POWER_STATE_SLEEP The deep sleep mode for RF transceiver +* * POWER_STATE_WAKEUP Wake up state, or operating state for RF transceiver +* * POWER_STATE_WAKEUP_DR Put device into wakeup mode and then transmit a +* data request to the device's associated device +* +* Returns: +* The status of the operation. The following are the possible status +* * SUCCESS Operation successful +* * ERR_TRX_FAIL Transceiver fails to go to sleep or wake up +* * ERR_TX_FAIL Transmission of Data Request command failed. Only available if the +* input mode is POWER_STATE_WAKEUP_DR. +* * ERR_RX_FAIL Failed to receive any response to Data Request command. Only available +* if input mode is POWER_STATE_WAKEUP_DR. +* * ERR_INVLAID_INPUT Invalid input mode. +* +* Example: +* +* // put RF transceiver into sleep +* MiApp_TransceiverPowerState(POWER_STATE_SLEEP; +* +* // Put the MCU into sleep +* Sleep(); +* +* // wakes up the MCU by WDT, external interrupt or any other means +* +* // make sure that RF transceiver to wake up and send out Data Request +* MiApp_TransceiverPowerState(POWER_STATE_WAKEUP_DR); +* +* +* Remarks: +* None +* +*****************************************************************************************/ +uint8_t MiApp_TransceiverPowerState(uint8_t Mode); + +/******************************************************************************************* +* Function: +* bool MiApp_InitChannelHopping(uint32_t ChannelMap) +* +* Summary: +* +* This function tries to start a channel hopping (frequency agility) procedure +* +* Description: +* This is the primary user interface function for the application to do energy +* scan to locate the channel with least noise. If the channel is not current +* operating channel, process of channel hopping will be started. +* +* PreCondition: +* Transceiver has been initialized +* +* Parameters: +* uint32_t ChannelMap - The bit map of the candidate channels +* which can be hopped to +* +* Returns: +* a boolean to indicate if channel hopping is initiated +* +* Example: +* +* // if condition meets, scan all possible channels and hop +* // to the one with least noise +* MiApp_InitChannelHopping(0xFFFFFFFF); +* +* +* Remark: The operating channel will change to the optimal +* channel with least noise +* +******************************************************************************************/ +bool MiApp_InitChannelHopping( uint32_t ChannelMap, uint8_t optimalChannel); + +typedef void (*resyncConnection_callback_t)(uint8_t channel, miwi_status_t status); +/******************************************************************************************** +* Function: +* bool MiApp_ResyncConnection(uint8_t ConnectionIndex, uint32_t ChannelMap) +* +* Summary: +* This function tries to resynchronize the lost connection with +* peers, probably due to channel hopping +* +* Description: +* This is the primary user interface function for the application to resynchronize a +* lost connection. For a RFD device that goes to sleep periodically, it may not +* receive the channel hopping command that is sent when it is sleep. The sleeping +* RFD device depends on this function to hop to the channel that the rest of +* the PAN has jumped to. This function call is usually triggered by continously +* communication failure with the peers. +* +* PreCondition: +* Transceiver has been initialized +* +* Parameters: +* uint32_t ChannelMap - The bit map of channels to perform noise scan. The 32-bit +* double word parameter use one bit to represent corresponding +* channels from 0 to 31. For instance, 0x00000003 represent to +* scan channel 0 and channel 1. +* +* Returns: +* a boolean to indicate if resynchronization of connection is successful +* +* Example: +* +* // Sleeping RFD device resync with its associated device, usually the first peer +* // in the connection table +* MiApp_ResyncConnection(0, 0xFFFFFFFF); +* +* +* Remark: +* If operation is successful, the wireless node will be hopped to the channel that +* the rest of the PAN is operating on. +* +*********************************************************************************************/ +bool MiApp_ResyncConnection(uint8_t ConnectionIndex, uint32_t ChannelMap, resyncConnection_callback_t callback); + + +/************************************************************************************ +* Function: +* bool MiApp_Get(set_params id, uint8_t *value ) +* +* Summary: +* This function gets the information base values +* +* Description: +* This is the primary user interface function to get the different values in the MiWi +* stack +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* get_params id - The identifier of the value to be set +* +* Returns: +* a boolean to indicate if get operation has been performed successfully +* +* Example: +* +* value = MiApp_get(CHANNEL) +* +* +* Remarks: +* None +* +*********************************************************************************/ +bool MiApp_Get(miwi_params_t id, uint8_t *value); + +#if defined(ENABLE_NETWORK_FREEZER) +/************************************************************************************ +* Function: +* bool MiApp_ResetToFactoryNew(void) +* +* Summary: +* This function makes the device to factory new device +* +* Description: +* This is used to erase all the persistent items in the non-volatile memory and resets the system. +* +* Returns: +* A boolean to indicate the operation is success or not +* +*****************************************************************************************/ +bool MiApp_ResetToFactoryNew(void); +#endif + +#if defined(PROTOCOL_MESH) +void MeshTasks(void); +#endif + +typedef void (*ReconnectionCallback_t)(miwi_status_t status); +/************************************************************************************ +* Function: +* bool MiApp_SubscribeReConnectionCallback(ReconnectionCallback_t callback) +* +* Summary: +* This function subscribes for reconnection notification +* +* Description: +* This is used to subscribe to notify the reconnection. Upon reconnection in +* coordinator or end device, this callback will be called. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* ReconnectionCallback_t callback - The callback routine which will be called upon +* reconnection +* +* Returns: +* A boolean to indicates if the subscription is success or not +* +*****************************************************************************************/ +bool MiApp_SubscribeReConnectionCallback(ReconnectionCallback_t callback); + +typedef void (*roleUpgrade_callback_t)(uint16_t newShortAddress); +#ifdef COORDINATOR +/************************************************************************************ +* Function: +* bool MiApp_RoleUpgradeNotification_Subscribe(roleUpgrade_callback_t callback) +* +* Summary: +* This function subscribes for role upgrade notification +* +* Description: +* This is used to subscribe to notify the role upgrade. Upon successful role +* upgrade, callback will be called with new short address +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* roleUpgrade_callback_t callback - The callback routine which will be called upon +* the role upgrade done +* +* Returns: +* A boolean to indicates if the subscription is success or not +* +*****************************************************************************************/ +bool MiApp_RoleUpgradeNotification_Subscribe(roleUpgrade_callback_t callback); +#endif + +/************************************************************************************ +* Function: +* bool MiApp_Commissioning_AddNewDevice(uint64_t joinerAddress, bool triggerBloomUpdate) +* +* Summary: +* This function adds the given address into the commissioning device address list +* if free entry available +* +* Parameters: +* uint64_t joinerAddress - the ieee address to be added. +* bool triggerBloomUpdate - if set to true then bloom update is sent immediately +* +* Returns: +* true if found, false otherwise. +*****************************************************************************************/ +bool MiApp_Commissioning_AddNewDevice(uint64_t joinerAddress, bool triggerBloomUpdate); + +#if defined(PROTOCOL_MESH) +/************************************************************************************ +* Function: +* uint16_t MiApp_MeshGetNextHopAddr(uint16_t destAddress) +* +* Summary: +* This function gets the next hop address for the given destination address +* +* Description: +* This is used to get the next hop address for the given destination address +* from the routing table. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* uint16_t destAddress - any valid network address +* +* Returns: +* the next hop address if available, otherwise 0xFFFF +* +*****************************************************************************************/ +uint16_t MiApp_MeshGetNextHopAddr(uint16_t destAddress); + +/************************************************************************************ +* Function: +* bool MiApp_ManuSpecSendData(uint8_t addr_len, uint8_t *addr, uint8_t msglen, +* uint8_t *msgpointer, uint8_t msghandle, DataConf_callback_t ConfCallback); +* +* Summary: +* This function unicast a message in the msgpointer to the device with DestinationAddress +* +* Description: +* This is one of the primary user interface functions for the application layer to +* unicast a message. The destination device is specified by the input parameter +* DestinationAddress. The application payload is filled using msgpointer. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* uint8_t addr_len - destination address length +* uint8_t *addr - destionation address +* uint8_t msglen - length of the message +* uint8_t *msgpointer - message/frame pointer +* uint8_t msghandle - message handle +* bool ackReq - set to receive network level ack (Note- Discarded for broadcast data) +* DataConf_callback_t ConfCallback - The callback routine which will be called upon +* the initiated data procedure is performed +* +* Returns: +* A boolean to indicates if the unicast procedure is successful. +* +* Example: +* +* // Secure and then broadcast the message stored in msgpointer to the permanent address +* // specified in the input parameter. +* MiApp_SendData(SHORT_ADDR_LEN, 0x0004, len, frameptr,1, callback); +* +* +* Remarks: +* None +* +*****************************************************************************************/ +bool MiApp_ManuSpecSendData(uint8_t addr_len, uint8_t *addr, uint8_t msglen, uint8_t *msgpointer, +uint8_t msghandle, bool ackReq, DataConf_callback_t ConfCallback); + +/************************************************************************************ +* Function: +* bool MiApp_SubscribeMAnuSpecDataIndicationCallback(PacketIndCallback_t callback) +* +* Summary: +* This function return a boolean if subscription for rx message is successful +* +* Description: +* This is the primary user interface functions for the application layer to +* call the Microchip proprietary protocol stack to register for message indication +* callback to the application. The function will call the protocol stack state machine +* to keep the stack running. +* +* PreCondition: +* Protocol initialization has been done. +* +* Parameters: +* None +* +* Returns: +* A boolean to indicates if the subscription operation is successful or not. +* +* Example: +* +* if( true == MiApp_SubscribeMAnuSpecDataIndicationCallback(ind) ) +* { +* } +* msgId = APP_STATE_SENDING_DONE; OSAL_QUEUE_Send(&appData.appQueue, p_appModes, 0); +#endif } /*************************************************************************//** *****************************************************************************/ void appCmdDataInd(RECEIVED_MESH_MESSAGE *ind) { - //appCmdHandle(ind->payload, ind->payloadSize); + appCmdHandle(ind->payload, ind->payloadSize); } /*************************************************************************//** diff --git a/driver/software/MiWi/MiWi_Mesh/src/commands.c.bak b/driver/software/MiWi/MiWi_Mesh/src/commands.c.bak new file mode 100644 index 0000000..ceb6e6f --- /dev/null +++ b/driver/software/MiWi/MiWi_Mesh/src/commands.c.bak @@ -0,0 +1,1080 @@ +/* ************************************************************************** */ +/** Descriptive File Name + + @Company + Microchip Technology pvt Ltd + + @File Name + MiWi_cmd_processor.c + + @Summary + Command Interface file for PHY & App layer functions + + @Description + Command Interface file for PHY & App layer functions + */ + /*******************************************************************************/ + +// DOM-IGNORE-BEGIN +/******************************************************************************* +* Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries. +* +* Subject to your compliance with these terms, you may use Microchip software +* and any derivatives exclusively with Microchip products. It is your +* responsibility to comply with third party license terms applicable to your +* use of third party software (including open source software) that may +* accompany Microchip software. +* +* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED +* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A +* PARTICULAR PURPOSE. +* +* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS +* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE +* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN +* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, +* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. +*******************************************************************************/ +// DOM-IGNORE-END +// ***************************************************************************** +// ***************************************************************************** +/*- Includes ---------------------------------------------------------------*/ +#include +#include +#include "config/default/definitions.h" +#ifdef CLI_ENABLED +#include "system/console/sys_console.h" +#endif +/*- Definitions ------------------------------------------------------------*/ +#define APP_CMD_UART_BUFFER_SIZE 16U +#define APP_CMD_PENDING_TABLE_SIZE 5U +#define APP_CMD_INVALID_ADDR 0xffffU + +/*- Types ------------------------------------------------------------------*/ +typedef enum { + APP_CMD_UART_STATE_IDLE, + APP_CMD_UART_STATE_SYNC, + APP_CMD_UART_STATE_DATA, + APP_CMD_UART_STATE_MARK, + APP_CMD_UART_STATE_CSUM, +} AppCmdUartState_t; + + +typedef struct { + uint8_t commandId; + uint64_t dstAddr; +} __attribute__((packed, aligned(1)))AppCmdUartHeader_t; + +typedef struct { + uint8_t commandId; + uint64_t dstAddr; + uint16_t duration; + uint16_t period; +} __attribute__((packed, aligned(1)))AppCmdUartIdentify_t; + +typedef struct { + uint8_t id; +} __attribute__((packed, aligned(1)))AppCmdHeader_t; + +typedef struct { + uint8_t id; + uint16_t duration; + uint16_t period; +} __attribute__((packed, aligned(1)))AppCmdIdentify_t; + +/*- Prototypes -------------------------------------------------------------*/ +//Commands definitions +#ifdef CLI_ENABLED +static void miwi_getParentAddress(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void miwi_broadcast_data(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void miwi_enable_sleep(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibgetChannel(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibsetChannel(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibgetChannelPage(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibsetChannelPage(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibgetPanId(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibsetPanId(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibgetTxPwr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibsetTxPwr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibgetIeeeAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibsetIeeeAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibgetSrcAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +static void phy_pibsetSrcAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv); +#endif +static void appCmdUartProcess(uint8_t *data, uint8_t size); +static void appCmdBuffer(uint16_t addr, uint8_t *data, uint8_t size); +static void appCmdDataConf(uint8_t msgConfHandle, miwi_status_t status, uint8_t* msgPointer); +static bool appCmdHandle(uint8_t *data, uint8_t size); +static void appCmdIdentifyDurationTimerHandler(uintptr_t context); +static void appCmdIdentifyPeriodTimerHandler(uintptr_t context); + +/*- Variables --------------------------------------------------------------*/ +static AppCmdUartState_t appCmdUartState = APP_CMD_UART_STATE_IDLE; +static uint8_t appCmdUartPtr; +static uint8_t appCmdUartBuf[APP_CMD_UART_BUFFER_SIZE]; +static uint8_t appCmdUartCsum; +static uint8_t wsnmsghandle; +SYS_Timer_t appCmdIdentifyDurationTimer; +SYS_Timer_t appCmdIdentifyPeriodTimer; + +SYS_TIME_HANDLE appCmdIdentifyDurationTimerHandle; +SYS_TIME_HANDLE appCmdIdentifyPeriodTimerHandle; + +SYS_TIME_HANDLE joinTimerHandle; +SYS_TIME_HANDLE keepAliveTimerHandle; +SYS_Timer_t joinTimer; +SYS_Timer_t keepAliveTimer; +/*- Implementations --------------------------------------------------------*/ +//CMD descriptor table definition +#ifdef CLI_ENABLED +static const SYS_CMD_DESCRIPTOR MiWiCmdsTbl[] = +{ + {"getParentAddress", miwi_getParentAddress, ":Get Parent device address if the device is ED/Coordinator: getParentAddr\r\n"}, + {"getChannel", phy_pibgetChannel, ":Get PHY PIB attribute: getChannel\r\n"}, + {"setChannel", phy_pibsetChannel, ":Set PHY PIB attribute: setChannel,\r\n"}, + {"getChannelPg", phy_pibgetChannelPage, ":Get PHY PIB attribute: getChannelPg\r\n"}, + {"setChannelPg", phy_pibsetChannelPage, ":Set PHY PIB attribute: setChannelPg,\r\n"}, + {"getPanId", phy_pibgetPanId, ":Get PHY PIB attribute: getPanId\r\n"}, + {"setPanId", phy_pibsetPanId, ":Set PHY PIB attribute: setPanId,\r\n"}, + {"getSrcAddr", phy_pibgetSrcAddr, ":Get PHY PIB attribute: getDestAddr\r\n"}, + {"setSrcAddr", phy_pibsetSrcAddr, ":Set PHY PIB attribute: setDestAddr,\r\n"}, + {"getTxPwr", phy_pibgetTxPwr, ":Get PHY PIB attribute: getTxPwr\r\n"}, + {"setTxPwr", phy_pibsetTxPwr, ":Set PHY PIB attribute: setTxPwr,\r\n"}, + {"getIeeeAddr", phy_pibgetIeeeAddr, ":Get PHY PIB attribute: getIeeeAddr\r\n"}, + {"setIeeeAddr", phy_pibsetIeeeAddr, ":Set PHY PIB attribute: setIeeeAddr,\r\n"}, + {"broadcastData", miwi_broadcast_data, ":broadcast data\r\n"}, + {"enableDeepSleep", miwi_enable_sleep, ":Enable Deep Sleep\r\n"}, +}; +//PHY commands init - registering the command table to sys commands +void MiWiCmdTable_Init(void) +{ + if(SYS_CMD_ADDGRP(MiWiCmdsTbl, (int)(sizeof(MiWiCmdsTbl)/sizeof(*MiWiCmdsTbl)), "MiWiCmds", ": MiWi commands")) + { + SYS_CONSOLE_MESSAGE("\r\nSYS CMD TBL INITIALISED\r\n"); + } +} +#endif +/*************************************************************************//** +*****************************************************************************/ +void APP_CommandsInit(void) +{ + appCmdIdentifyDurationTimer.mode = SYS_TIME_SINGLE; + appCmdIdentifyDurationTimer.handler = appCmdIdentifyDurationTimerHandler; + + appCmdIdentifyPeriodTimer.mode = SYS_TIME_PERIODIC; + appCmdIdentifyPeriodTimer.handler = appCmdIdentifyPeriodTimerHandler; +} + +void UartBytesReceived(uint16_t bytes, uint8_t *byte ) +{ + for (uint16_t i = 0; i < bytes; i++) { + APP_CommandsByteReceived(byte[i]); + } +} + +/*************************************************************************//** +*****************************************************************************/ +void APP_CommandsByteReceived(uint8_t byte) +{ + switch (appCmdUartState) { + case APP_CMD_UART_STATE_IDLE: + { + if (0x10U == byte) { + appCmdUartPtr = 0U; + appCmdUartCsum = byte; + appCmdUartState = APP_CMD_UART_STATE_SYNC; + } + } + break; + + case APP_CMD_UART_STATE_SYNC: + { + appCmdUartCsum += byte; + + if (0x02U == byte) { + appCmdUartState = APP_CMD_UART_STATE_DATA; + } else { + appCmdUartState = APP_CMD_UART_STATE_IDLE; + } + } + break; + + case APP_CMD_UART_STATE_DATA: + { + appCmdUartCsum += byte; + + if (0x10U == byte) { + appCmdUartState = APP_CMD_UART_STATE_MARK; + } else { + appCmdUartBuf[appCmdUartPtr++] = byte; + } + + if (appCmdUartPtr == APP_CMD_UART_BUFFER_SIZE) { + appCmdUartState = APP_CMD_UART_STATE_IDLE; + } + } + break; + + case APP_CMD_UART_STATE_MARK: + { + appCmdUartCsum += byte; + + if (0x10U == byte) { + appCmdUartBuf[appCmdUartPtr++] = byte; + + if (appCmdUartPtr == APP_CMD_UART_BUFFER_SIZE) { + appCmdUartState = APP_CMD_UART_STATE_IDLE; + } else { + appCmdUartState = APP_CMD_UART_STATE_DATA; + } + } else if (0x03U == byte) { + appCmdUartState = APP_CMD_UART_STATE_CSUM; + } else { + appCmdUartState = APP_CMD_UART_STATE_IDLE; + } + } + break; + + case APP_CMD_UART_STATE_CSUM: + { + if (byte == appCmdUartCsum) { + appCmdUartProcess(appCmdUartBuf, appCmdUartPtr); + } + + appCmdUartState = APP_CMD_UART_STATE_IDLE; + } + break; + + default: + //Handle exceptions if any + break; + } +} + +/*************************************************************************//** +*****************************************************************************/ +static void appCmdUartProcess(uint8_t *data, uint8_t size) +{ + AppCmdUartHeader_t *header = (AppCmdUartHeader_t *)data; + + if (size < (uint8_t)sizeof(AppCmdUartHeader_t)) { + return; + } + + if ((uint8_t)APP_COMMAND_ID_IDENTIFY == header->commandId) { + AppCmdUartIdentify_t *uartCmd = (AppCmdUartIdentify_t *)data; + AppCmdIdentify_t cmd; + + cmd.id = (uint8_t)APP_COMMAND_ID_IDENTIFY; + cmd.duration = uartCmd->duration; + cmd.period = uartCmd->period; + + appCmdBuffer(header->dstAddr, (uint8_t *)&cmd, + sizeof(AppCmdIdentify_t)); + } +} + +/*************************************************************************//** +*****************************************************************************/ +static void appCmdBuffer(uint16_t addr, uint8_t *data, uint8_t size) +{ + if (0U == addr) + { + appCmdHandle(data, size); + appCmdDataRequest(0xFFFFU, size, data); + } + else + { + appCmdDataRequest(addr, size, data); + } +} + + +/*************************************************************************//** +*****************************************************************************/ +void appCmdDataRequest(uint16_t addr, uint8_t size, uint8_t* payload) +{ + MiApp_SendData(SHORT_ADDR_LEN, (uint8_t*)&addr, size, payload, wsnmsghandle, true, appCmdDataConf); +} + +/*************************************************************************//** +*****************************************************************************/ +static void appCmdDataConf(uint8_t msgConfHandle, miwi_status_t status, uint8_t* msgPointer) +{ + APP_Msg_T *p_appModes; + APP_Msg_T appModes; + p_appModes = &appModes; + appStates = APP_STATE_SENDING_DONE; + p_appModes->msgId = APP_STATE_SENDING_DONE; + OSAL_QUEUE_Send(&appData.appQueue, p_appModes, 0); +} + +/*************************************************************************//** +*****************************************************************************/ +void appCmdDataInd(RECEIVED_MESH_MESSAGE *ind) +{ + //appCmdHandle(ind->payload, ind->payloadSize); +} + +/*************************************************************************//** +*****************************************************************************/ +static bool appCmdHandle(uint8_t *data, uint8_t size) +{ + AppCmdHeader_t *header = (AppCmdHeader_t *)data; + + if (size < sizeof(AppCmdHeader_t)) { + return false; + } + + if (APP_COMMAND_ID_IDENTIFY == header->id) { + AppCmdIdentify_t *req = (AppCmdIdentify_t *)data; + + if (sizeof(AppCmdIdentify_t) != size) { + return false; + } + + SYS_TIME_TimerStop(appCmdIdentifyDurationTimerHandle); + SYS_TIME_TimerStop(appCmdIdentifyDurationTimerHandle); + + + uint8_t myData = 0U; + appCmdIdentifyDurationTimer.interval = req->duration; + appCmdIdentifyDurationTimer.mode = SYS_TIME_SINGLE; + appCmdIdentifyDurationTimer.handler = appCmdIdentifyDurationTimerHandler; + + appCmdIdentifyDurationTimerHandle = SYS_TIME_CallbackRegisterMS(&appCmdIdentifyDurationTimerHandler, (uintptr_t)&myData, appCmdIdentifyDurationTimer.interval, SYS_TIME_SINGLE); + if(appCmdIdentifyDurationTimerHandle == SYS_TIME_HANDLE_INVALID) + { + return false; + } + appCmdIdentifyPeriodTimer.interval = req->period; + appCmdIdentifyPeriodTimer.mode = SYS_TIME_PERIODIC; + appCmdIdentifyPeriodTimer.handler = appCmdIdentifyPeriodTimerHandler; + appCmdIdentifyPeriodTimerHandle = SYS_TIME_CallbackRegisterMS(&appCmdIdentifyPeriodTimerHandler, (uintptr_t)&myData, appCmdIdentifyPeriodTimer.interval, SYS_TIME_PERIODIC); + if(appCmdIdentifyPeriodTimerHandle == SYS_TIME_HANDLE_INVALID) + { + return false; + } +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_On(); +#else + LED_On(1,LED_IDENTIFY); +#endif +#endif +#endif + return true; + } + return false; +} + +/*************************************************************************//** +*****************************************************************************/ +//static void appCmdIdentifyDurationTimerHandler(SYS_Timer_t *timer) //michp +static void appCmdIdentifyDurationTimerHandler(uintptr_t context) +{ +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_Off(); +#else + LED_Off(1,LED_IDENTIFY); +#endif +#endif +#endif + uint32_t isTimePending = 0U; + SYS_TIME_TimerCounterGet(appCmdIdentifyPeriodTimerHandle,&isTimePending); + if(isTimePending > 0U) + { + SYS_TIME_TimerStop(appCmdIdentifyPeriodTimerHandle); + } + + (void)context; +} + +/*************************************************************************//** +*****************************************************************************/ +static void appCmdIdentifyPeriodTimerHandler(uintptr_t context) +{ +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_Toggle(); +#else + LED_Toggle(1,LED_IDENTIFY); +#endif +#endif +#endif + (void)context; +} +#ifdef CLI_ENABLED +static void phy_pibgetChannel(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv){ + + PHY_Retval_t status; + PibValue_t pibValue; + status = PHY_PibGet(phyCurrentChannel,(uint8_t *)&pibValue); + appPhyCmdProcessor_PhyStatusPrint(status); + if(status == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n Channel - 0x%x\n ",pibValue.pib_value_8bit); + } + else + { + appPhyCmdProcessor_PhyStatusPrint(status); + } + +} + +static void phy_pibsetChannel(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t status; + uint8_t retcode, attribute_val = 0U; + PibValue_t pibValue; + if(argc<2) + { + retcode = ERR_MISSING_PARAM; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + if(appPhyCmdProcessor_StrToUint8(argv[1], &attribute_val)) + { + if((attribute_val < 11U) || (attribute_val > 26U)) + { + retcode = ERR_PARAM_OUT_OF_RANGE; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + } + pibValue.pib_value_8bit = attribute_val; + status = PHY_PibSet(phyCurrentChannel, &pibValue); + appPhyCmdProcessor_PhyStatusPrint(status); + if(status == PHY_SUCCESS) + { + if(PHY_PibGet(phyCurrentChannel,&attribute_val) == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n Channel - 0x%x\n ",attribute_val); + } + MiApp_Set(CHANNEL, &attribute_val); + } + +} + +static void phy_pibgetChannelPage(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t status; + uint8_t channelPage; + status = PHY_PibGet(phyCurrentPage,&channelPage); + appPhyCmdProcessor_PhyStatusPrint(status); + if(status == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n Channel Page - %d\n ",channelPage); + } + else + { + appPhyCmdProcessor_PhyStatusPrint(status); + } +} + +static void phy_pibsetChannelPage(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t status; + uint8_t retcode, attribute_val = 0U; + PibValue_t pibValue; + if(argc<2) + { + retcode = ERR_MISSING_PARAM; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + if(appPhyCmdProcessor_StrToUint8(argv[1], &attribute_val)) + { + if((attribute_val != 0x0U) && (attribute_val != 0x2U) && (attribute_val != 0x10U) && (attribute_val != 0x11U)) + { + retcode = ERR_PARAM_OUT_OF_RANGE; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + } + pibValue.pib_value_8bit = attribute_val; + status = PHY_PibSet(phyCurrentPage, &pibValue); + appPhyCmdProcessor_PhyStatusPrint(status); + if(status == PHY_SUCCESS) + { + if(PHY_PibGet(phyCurrentPage,&attribute_val) == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n Channel Page - %d\n ",attribute_val); + } + } + +} + +static void phy_pibgetPanId(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t status; + PibValue_t pibValue; + status = PHY_PibGet(macPANId,(uint8_t *)&pibValue); + appPhyCmdProcessor_PhyStatusPrint(status); + if(status == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n PAN ID - 0x%x\n ",pibValue.pib_value_16bit); + } + else + { + appPhyCmdProcessor_PhyStatusPrint(status); + } +} + +static void phy_pibsetPanId(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t status; + uint8_t retcode; + uint16_t attr_val_16 = 0U; + PibValue_t pibValue; + if(argc<2) + { + retcode = ERR_MISSING_PARAM; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + if(appPhyCmdProcessor_StrToUint16HexIp(argv[1],&attr_val_16)) + { + pibValue.pib_value_16bit = attr_val_16; + status = PHY_PibSet(macPANId , &pibValue); + appPhyCmdProcessor_PhyStatusPrint(status); + if(status == PHY_SUCCESS) + { + if(PHY_PibGet(macPANId, (uint8_t*)&attr_val_16) == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n PAN ID : 0x%x\n ",attr_val_16); + } + MiApp_Set(PANID, (uint8_t*)&attr_val_16); + } + } + + +} + +static void phy_pibgetTxPwr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + + PHY_Retval_t status; + PibValue_t pibValue; + status = PHY_PibGet(phyTransmitPower,(uint8_t *)&pibValue); + if(status == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n Tx Power - %d\r\n ",pibValue.pib_value_8bit); + } + else + { + appPhyCmdProcessor_PhyStatusPrint(status); + } +} +static void phy_pibsetTxPwr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t status; + uint8_t retcode = 0U; + int8_t attribute_val = 0; + PibValue_t pibValue; + if(argc<2){ + retcode = ERR_MISSING_PARAM; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + if(appPhyCmdProcessor_StrToInt8(argv[1], &attribute_val)) + { + if((attribute_val < -12) || (attribute_val > 14)) + { + retcode = ERR_PARAM_OUT_OF_RANGE; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + SYS_CONSOLE_PRINT("\r\n Tx Power - %d DBm\r\n ",attribute_val); + pibValue.pib_value_8bit = (uint8_t)CONV_DBM_TO_phyTransmitPower(attribute_val); + status = PHY_PibSet(phyTransmitPower, &pibValue); + if(status == PHY_SUCCESS) + { + if(PHY_PibGet(phyTransmitPower,&pibValue.pib_value_8bit) == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\nSet Tx Power - %d DBm\r\n ",pibValue.pib_value_8bit); + } + } + else + { + appPhyCmdProcessor_PhyStatusPrint(status); + } + } + +} + +static void phy_pibgetSrcAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PibValue_t pibValue; + PHY_Retval_t attr_stat; + attr_stat = PHY_PibGet(macShortAddress,(uint8_t *)&pibValue); + if(attr_stat == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n Source Address : 0x%x\r\n",pibValue.pib_value_16bit); + } + else + { + appPhyCmdProcessor_PhyStatusPrint(attr_stat); + } +} +static void phy_pibsetSrcAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + + PibValue_t pibValue; + uint8_t retcode; + PHY_Retval_t attr_stat; + uint16_t attr_val_16 = 0; + if(argc<2) + { + retcode = ERR_MISSING_PARAM; + appPhyCmdProcessor_PrintReturnCode(retcode); + return; + } + if(appPhyCmdProcessor_StrToUint16HexIp(argv[1],&attr_val_16)) + { + SYS_CONSOLE_PRINT("\r\n Existing Source Address - 0x%x\n ",attr_val_16); + attr_stat = PHY_PibSet(macShortAddress, &pibValue); + if(attr_stat != PHY_SUCCESS) + { + appPhyCmdProcessor_PhyStatusPrint(attr_stat); + return; + } + attr_stat = PHY_PibGet(macShortAddress,(uint8_t *)&attr_val_16); + if(attr_stat == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n New Source Address : %d \r\n",attr_val_16); + MiApp_Set(SHORT_ADDRESS, (uint8_t*)&attr_val_16); + } + } +} + +static void phy_pibgetIeeeAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t attributeStatus; + PibValue_t pibValue; + attributeStatus = PHY_PibGet(macIeeeAddress,(uint8_t *)&pibValue); + if(attributeStatus == PHY_SUCCESS) + { + SYS_CONSOLE_PRINT("\r\n IEEE Address : 0x%x\r\n",pibValue.pib_value_64bit); + } +} + +static void phy_pibsetIeeeAddr(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + PHY_Retval_t attributeStatus; + PibValue_t pibValue; + uint64_t ieeeaddr = 0U; + if(appPhyCmdProcessor_StrToUint64(argv[1], &ieeeaddr)) + { + pibValue.pib_value_64bit = ieeeaddr; + attributeStatus = PHY_PibSet(macIeeeAddress,&pibValue); + if(attributeStatus == PHY_SUCCESS) + { + attributeStatus = PHY_PibGet(macIeeeAddress,(uint8_t *)&ieeeaddr); + SYS_CONSOLE_PRINT("\r\n IEEE Address : 0x%x\r\n",ieeeaddr); + } + } +} + +static void miwi_getParentAddress(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ +#ifndef PAN_COORDINATOR + SYS_CONSOLE_PRINT("\r\n My Parent Address : 0x%x\r\n",myParentShortAddress); +#else + SYS_CONSOLE_PRINT("\r\n I'm parent PAN coordinator\r\n"); +#endif +} + +static void miwi_broadcast_data(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ + uint8_t pload = 0xac; + uint16_t address = 0xFFFF; + SYS_CONSOLE_PRINT("\r\n broadcast data\r\n"); +// appStates = APP_STATE_SEND; +#ifdef PAN_COORDINATOR +// address = getNextHopAddr(myShortAddress); +// address = 0x0001; + appCmdDataRequest(address, sizeof(pload), &pload); +#else + if(myParentShortAddress != 0xFFFF) + { + appCmdDataRequest(myParentShortAddress, sizeof(pload), &pload); + } + else + { + appCmdDataRequest(address, sizeof(pload), &pload); + } +#endif +} + +static void miwi_enable_sleep(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv) +{ +#if defined(PROTOCOL_MESH) +#if defined(ENABLE_SLEEP_FEATURE) && defined(ENDDEVICE) + if(CAPABILITY_INFO == CAPABILITY_INFO_ED) + { + deviceCanSleep = true; + APP_Msg_T sleepReq; + sleepReq.msgId = APP_STATE_DATA_RECEIVE_IND; + appStates = APP_STATE_DATA_RECEIVE_IND; + OSAL_QUEUE_Send(&appData.appQueue, &sleepReq, 0); + } +#endif +#elif defined(PROTOCOL_STAR) + #if defined(ENABLE_SLEEP_FEATURE) + if(role == END_DEVICE) + { + deviceCanSleep = true; + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; + appState->msgId = APP_STATE_PREPARE_TO_SLEEP; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); + } + #endif +#else + #if defined(ENABLE_SLEEP_FEATURE) + deviceCanSleep = true; + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; + appState->msgId = APP_STATE_PREPARE_TO_SLEEP; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); + #endif +#endif +} +void appPhyCmdProcessor_PrintReturnCode(uint8_t status) +{ + switch(status) + { + case AOK: + appPhyCmdProcessor_CmdDoneOk(); + break; + + case NO_PROMPT: + break; + + case PENDING: + break; + + default: + appPhyCmdProcessor_CmdDoneFail(status); + break; + } + //time_to_process_cmd = 0; +} + +/**************************************************************************************************/ + +bool appPhyCmdProcessor_StrToBool(const char *str, bool *res) +{ + if (strcmp(str, "true") == 0 || strcmp(str, "True") == 0) + { + *res = true; + return true; + } + else if (strcmp(str, "false") == 0 || strcmp(str, "False") == 0) + { + *res = false; + return true; + } + else + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input. Please enter either 'true' or 'false'\r\n"); + return false; + } +} + +bool appPhyCmdProcessor_StrToUint8HexIp(const char *str, uint8_t *res) +{ + char *end; + errno = 0; + uint16_t val1 = (uint16_t)strtol(str, &end, 16); + if (errno != 0 || (*end != '\0') || (val1 > 0xffU)) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + errno = 0; + uint8_t val = (uint8_t)strtol(str, &end, 16); + if(errno != 0) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = val; + return true; +} + +bool appPhyCmdProcessor_StrToUint8(const char *str, uint8_t *res) +{ + char *end; + errno = 0; + uint16_t val1 = (uint16_t)strtol(str, &end, 10); + if (errno != 0 || (*end != '\0') || (val1 > 255U)) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + errno = 0; + uint8_t val = (uint8_t)strtol(str, &end, 10); + if(errno != 0) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = val; + return true; +} + +bool appPhyCmdProcessor_StrToInt8(const char *str, int8_t *res) +{ + char *end; + errno = 0; + int8_t val = (int8_t)strtol(str, &end, 10); + if (errno != 0 || (*end != '\0')) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = val; + return true; +} + +bool appPhyCmdProcessor_StrToUint16(const char *str, uint16_t *res) +{ + char *end; + errno = 0; + uint32_t val1 = (uint32_t)strtoul(str, &end, 10); + if (errno != 0 || (*end != '\0') || (val1 > 65535U)) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + errno = 0; + uint16_t val = (uint16_t)strtoul(str, &end, 10); + if(errno != 0) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = val; + return true; +} + +bool appPhyCmdProcessor_StrToUint16HexIp(const char *str, uint16_t *res) +{ + char *end; + errno = 0; + uint32_t val1 = (uint32_t)strtoul(str, &end, 16); + if (errno != 0 || (*end != '\0') || (val1 > 0xffffU)) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + errno = 0; + uint16_t val = (uint16_t)strtoul(str, &end, 16); + if(errno != 0) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = val; + return true; +} + +bool appPhyCmdProcessor_StrToUint32(const char *str, uint32_t *res) +{ + char *end; + errno = 0; + uint64_t val1 = (uint64_t)strtoul(str, &end, 10); + if (errno != 0 || (*end != '\0') || (val1 > 4294967295U)) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + errno = 0; + uint32_t val = (uint32_t)strtoul(str, &end, 10); + if(errno != 0) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = val; + return true; +} + +bool appPhyCmdProcessor_StrToUint64(const char *str, uint64_t *res) +{ + char *endptr; + errno = 0; + uint64_t result = (uint64_t)strtoull(str, &endptr, 16); + if (errno != 0 || (*endptr != '\0')) //|| (result > 18446744073709551615U) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = result; + return true; +} + +bool appPhyCmdProcessor_StrToUint64DecIp(const char *str, uint64_t *res) +{ + char *endptr; + errno = 0; + uint64_t result = (uint64_t)strtoull(str, &endptr, 10); + if (errno != 0 || (*endptr != '\0')) //|| (result > 18446744073709551615U) + { + SYS_CONSOLE_MESSAGE("\r\nInvalid input\r\n"); + return false; + } + *res = result; + return true; +} + +void appPhyCmdProcessor_PhyStatusPrint(PHY_Retval_t status){ + + switch((uint8_t)status) + { + case 0x00: + SYS_CONSOLE_PRINT("\r\nPHY_SUCCESS\r\n"); + break; + case 0x81: + SYS_CONSOLE_PRINT("\r\nPHY_TRX_ASLEEP\r\n"); + break; + case 0x82: + SYS_CONSOLE_PRINT("\r\nPHY_TRX_AWAKE\r\n"); + break; +#ifdef CHIMERA_SOC + case 0x83: + SYS_CONSOLE_PRINT("\r\nPHY_RF_REQ_ABORTED\r\n"); + break; + case 0x84: + SYS_CONSOLE_PRINT("\r\nPHY_RF_UNAVAILABLE\r\n"); + break; +#endif + case 0x85: + SYS_CONSOLE_PRINT("\r\nPHY_FAILURE\r\n"); + break; + case 0x86: + SYS_CONSOLE_PRINT("PHY_BUSY\r\n"); + break; + case 0x87: + SYS_CONSOLE_PRINT("\r\nPHY_FRAME_PENDING\r\n"); + break; + case 0x88: + SYS_CONSOLE_PRINT("\r\nPHY_INVALID_PARAMETER\r\n"); + break; + case 0x89: + SYS_CONSOLE_PRINT("\r\nPHY_UNSUPPORTED_ATTRIBUTE\r\n"); + break; + case 0x8A: + SYS_CONSOLE_PRINT("\r\nPHY_CHANNEL_BUSY\r\n"); + break; + case 0x8B: + SYS_CONSOLE_PRINT("\r\nPHY_CHANNEL_IDLE\r\n"); + break; + case 0x8C: + SYS_CONSOLE_PRINT("\r\nPHY_NO_ACK\r\n"); + break; + case 0x8D: + SYS_CONSOLE_PRINT("\r\nPHY_CHANNEL_ACCESS_FAILURE\r\n"); + break; + default: + SYS_CONSOLE_PRINT("\r\nPHY_UNKNOWN_STATE\r\n"); + break; + + } +} + +void appPhyCmdProcessor_PhyTrxStatusPrint(PHY_TrxStatus_t status){ + + switch((uint8_t)status){ + case 0x08: + SYS_CONSOLE_PRINT("PHY_TRX_OFF\r\n"); + break; + case 0x16: + SYS_CONSOLE_PRINT("PHY_RX_ON\r\n"); + break; + case 0x19: + SYS_CONSOLE_PRINT("PHY_TX_ON\r\n"); + break; + case 0x11: + SYS_CONSOLE_PRINT("PHY_BUSY_RX\r\n"); + break; + case 0x12: + SYS_CONSOLE_PRINT("PHY_BUSY_TX\r\n"); + break; + case 0x0F: + SYS_CONSOLE_PRINT("PHY_TRX_SLEEP\r\n"); + break; + case 0x20: + SYS_CONSOLE_PRINT("PHY_TRX_DEEP_SLEEP\r\n"); + break; + default: + SYS_CONSOLE_PRINT("PHY_UNKNOWN_STATE\r\n"); + break; + + } +} +void appPhyCmdProcessor_CmdDoneOk(void) +{ + SYS_CONSOLE_PRINT("\r\nSuccess\r\n"); +} +void appPhyCmdProcessor_CmdDoneFail(uint8_t err_code) +{ + SYS_CONSOLE_PRINT("Err%d: ",err_code); + switch(err_code) + { + case ERR_UNKNOWN_CMD: + SYS_CONSOLE_PRINT("Unknown Command\r\n"); + break; + case ERR_INVALID_PARAM: + SYS_CONSOLE_PRINT("Invalid Parameter\r\n"); + break; + case ERR_MISSING_PARAM: + SYS_CONSOLE_PRINT("Missing Parameter\r\n"); + break; + case ERR_INVALID_PARAM_TYPE: + SYS_CONSOLE_PRINT("Invalid Parameter Type\r\n"); + break; + case ERR_PARAM_OUT_OF_RANGE: + SYS_CONSOLE_PRINT("Parameter Out of Range\r\n"); + break; + case ERR_INVALID_FORMAT: + SYS_CONSOLE_PRINT("Invalid Format\r\n"); + break; + case ERR_SCRIPT_PARSING: + SYS_CONSOLE_PRINT("Script Parsing Error\r\n"); + break; + case ERR_HEAP_FULL: + SYS_CONSOLE_PRINT("Heap Full\r\n"); + break; + case ERR_INVALID_STATE: + SYS_CONSOLE_PRINT("Invalid State\r\n"); + break; + case ERR_NO_RESOURCES: + SYS_CONSOLE_PRINT("No Resources\r\n"); + break; + case ERR_BLE_ERR: + SYS_CONSOLE_PRINT("BLE Err\r\n"); + break; + case ERR_HAL_ERR: + SYS_CONSOLE_PRINT("HAL Err\r\n"); + break; + case ERR_UNKNOWN_ERR: + SYS_CONSOLE_PRINT("Unknown Err\r\n"); + break; + default: + SYS_CONSOLE_PRINT("Unknown Err\r\n"); + break; + } +} +#endif diff --git a/driver/software/MiWi/MiWi_Mesh/src/mimac_task.c b/driver/software/MiWi/MiWi_Mesh/src/mimac_task.c index b7764b0..70fed67 100644 --- a/driver/software/MiWi/MiWi_Mesh/src/mimac_task.c +++ b/driver/software/MiWi/MiWi_Mesh/src/mimac_task.c @@ -93,12 +93,12 @@ void MiMAC_Tasks(void) } case MIWI_SEND_DATA: { -#ifndef PAN_COORDINATOR +//#ifndef PAN_COORDINATOR AppMessage_t *pAppMsg = NULL; pAppMsg = (AppMessage_t*)(pApiReqQueueData->parameters); appSendData(pAppMsg); pAppMsg = NULL; -#endif +//#endif break; } diff --git a/driver/software/MiWi/MiWi_Mesh/src/mimac_task.c.bak b/driver/software/MiWi/MiWi_Mesh/src/mimac_task.c.bak new file mode 100644 index 0000000..b7764b0 --- /dev/null +++ b/driver/software/MiWi/MiWi_Mesh/src/mimac_task.c.bak @@ -0,0 +1,151 @@ + +#include "config/default/definitions.h" +#include +//#include "config/default/MiWi/MiWi_Mesh/inc/miwi_init.h" + +/* Counting semaphore length to handle internal task processing */ +#define MIWI_STACK_INTERNAL_SEM_LENGTH 20 + +static STACK_API_Request *pApiReqQueueData, apiReqQueueData; +static QueueSetHandle_t xQueueSet; +static QueueSetMemberHandle_t xActivatedMember; + +OSAL_QUEUE_HANDLE_TYPE apiRequestQueueHandle; // Queue Pointer received from Aplication +OSAL_SEM_HANDLE_TYPE semStackInternalHandler; +OSAL_API_LIST_TYPE *mimac; +//extern OSAL_QUEUE_HANDLE_TYPE miwiRequestQueueHandle; +/************************************************************************** +\brief MiWi API CALL +***************************************************************************/ +void MIWI_API_CALL(STACK_API_Request *request) +{ + if(request != NULL) + { + if ( OSAL_RESULT_TRUE != mimac->OSAL_QUEUE_Send(&miwiRequestQueueHandle, &request, 0)) + { + while(true); // ERROR , Should not hang here, handle with assert + } + } +} + +/******************************************************************************* + OS Task Handler for MiWi Stack + Handles both API request from Applicaion layer and also internal scheduling + +*/ +void MiMAC_Tasks(void) +{ + + mimac->OSAL_SEM_Create(&semStackInternalHandler, OSAL_SEM_TYPE_COUNTING,MIWI_STACK_INTERNAL_SEM_LENGTH, 0); + + /* Create the queue set large enough to hold an event for every space in + every queue and semaphore that is to be added to the set. */ + mimac->OSAL_QUEUE_CreateSet(&xQueueSet, QUEUE_LENGTH + MIWI_STACK_INTERNAL_SEM_LENGTH); + + /* Add the queues and semaphores to the set. Reading from these queues and + semaphore can only be performed after a call to xQueueSelectFromSet() has + returned the queue or semaphore handle from this point on. */ + mimac->OSAL_QUEUE_AddToSet( &apiRequestQueueHandle, &xQueueSet ); + mimac->OSAL_QUEUE_AddToSet( &semStackInternalHandler, &xQueueSet ); + + pApiReqQueueData = &apiReqQueueData; + + while (1) + { + /* Block to wait for something to be available from the queues or + semaphore that have been added to the set.*/ + mimac->OSAL_QUEUE_SelectFromSet(&xActivatedMember, &xQueueSet, OSAL_WAIT_FOREVER ); + + /* Which set member was selected? Receives/takes can use a block time + of zero as they are guaranteed to pass because xQueueSelectFromSet() + would not have returned the handle unless something was available. */ + + if( xActivatedMember == semStackInternalHandler ) + { + /*Proses Internal Stack Events*/ + mimac->OSAL_SEM_Pend(&semStackInternalHandler, 0); + MiMac_TaskHandler(); + } + else if( xActivatedMember == apiRequestQueueHandle ) + { + mimac->OSAL_QUEUE_Receive(&apiRequestQueueHandle, &pApiReqQueueData, 0); + switch (pApiReqQueueData->uApiID) + { + case MIWI_START_NW: + { +#ifdef PAN_COORDINATOR + startNetworkReq_t *pStartNwReq = NULL; + pStartNwReq = (startNetworkReq_t*)(pApiReqQueueData->parameters); + MiApp_StartConnection(pStartNwReq->Mode, pStartNwReq->ScanDuration,pStartNwReq->ChannelMap,pStartNwReq->ConfCallback); + pStartNwReq = NULL; +#endif + break; + } + case MIWI_CONNECT_NW: + { +#ifndef PAN_COORDINATOR + searchNetworkReq_t *pSearchNwReq = NULL; + pSearchNwReq = (searchNetworkReq_t *)(pApiReqQueueData->parameters); + MiApp_SearchConnection(pSearchNwReq->ScanDuration,pSearchNwReq->ChannelMap,pSearchNwReq->ConfCallback); + pSearchNwReq = NULL; +#endif + break; + } + case MIWI_SEND_DATA: + { +#ifndef PAN_COORDINATOR + AppMessage_t *pAppMsg = NULL; + pAppMsg = (AppMessage_t*)(pApiReqQueueData->parameters); + appSendData(pAppMsg); + pAppMsg = NULL; +#endif + break; + } + +// case MIWI_TXDONE_CB: +// { +// TxDoneCallbackReq_t *pTxDoneCbReq = NULL; +// pTxDoneCbReq = (TxDoneCallbackReq_t *)(pApiReqQueueData->parameters); +// if(pTxDoneCbReq->dataConfCb != NULL) +// { +// pTxDoneCbReq->dataConfCb(pTxDoneCbReq->MsgHandle, pTxDoneCbReq->MiwiTxDoneStatus, pTxDoneCbReq->pMsg); +// } +// pTxDoneCbReq = NULL; +// break; +// } + default: + { + // ASSERT + break; + } + } + } + else + { + // ASSERT + } + + } +} +void MiMac_PostTask(bool isISRContext) +{ + OSAL_RESULT result = OSAL_RESULT_TRUE; + + if(semStackInternalHandler != NULL) + { + if(isISRContext) + { + result = OSAL_SEM_PostISR(&semStackInternalHandler); + } + else + { + result = OSAL_SEM_Post(&semStackInternalHandler); + } + } + else + { + MiMac_TaskHandler(); + } + + (void)result; +} \ No newline at end of file diff --git a/driver/software/MiWi/MiWi_Mesh/src/miwi_app.c b/driver/software/MiWi/MiWi_Mesh/src/miwi_app.c index 40879a4..b7936db 100644 --- a/driver/software/MiWi/MiWi_Mesh/src/miwi_app.c +++ b/driver/software/MiWi/MiWi_Mesh/src/miwi_app.c @@ -67,6 +67,9 @@ static SYS_Timer_t appNetworkStatusTimer; static SYS_TIME_HANDLE appNetworkStatusTimerHandle; static bool appNetworkStatus; #endif +#if defined(PAN_COORDINATOR) +static uint8_t rx_data[APP_RX_BUF_SIZE]; +#endif AppMessage_t appMsg; #ifndef PAN_COORDINATOR static uint8_t wsnmsghandle; @@ -104,6 +107,55 @@ static void appDataInd(RECEIVED_MESH_MESSAGE *ind); /***************************************************************************** *****************************************************************************/ +static void appUartSendMessage(uint8_t *data, uint8_t size) +{ + uint8_t cs = 0; + uint8_t val = 0; + ssize_t nr; + SYS_CONSOLE_HANDLE myConsoleHandle; + myConsoleHandle = SYS_CONSOLE_HandleGet(SYS_CONSOLE_INDEX_0); + val = 0x10; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + val = 0x02; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); +// SERCOM0_USART_Write(0x02,1); + //sio2host_putchar(0x10); + //sio2host_putchar(0x02); + + for (uint8_t i = 0; i < size; i++) { + if (data[i] == 0x10) + { + val = 0x10; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + //sio2host_putchar(0x10); + cs += 0x10; + } + //SERCOM0_USART_Write((uint8_t *)&0x10,1); + val = data[i]; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + //sio2host_putchar(data[i]); + cs += data[i]; + } + + val = 0x10; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + val = 0x03; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + //sio2host_putchar(0x10); + //sio2host_putchar(0x03); + cs += 0x10 + 0x02 + 0x10 + 0x03; + SYS_CONSOLE_Write( myConsoleHandle, &cs, 1); +// SERCOM0_USART_Write((uint8_t *)&cs,1); + //SERCOM0_USART_Write(cs); + //sio2host_putchar(cs); +} + static void appDataInd(RECEIVED_MESH_MESSAGE *ind) { AppMessage_t *msg = (AppMessage_t *)ind->payload; @@ -119,9 +171,10 @@ static void appDataInd(RECEIVED_MESH_MESSAGE *ind) #endif #endif #endif - - msg->lqi = ind->packetLQI; - msg->rssi = (int8_t)ind->packetRSSI; + + msg->lqi = ind->packetLQI; + msg->rssi = (int8_t)ind->packetRSSI; +#if !defined(WSN_MONITOR_SUPPORT) SYS_CONSOLE_PRINT("\r\nPayload received\r\n"); #if defined(PAN_COORDINATOR) for(uint8_t i=0U; ipayloadSize; i++) @@ -137,6 +190,12 @@ static void appDataInd(RECEIVED_MESH_MESSAGE *ind) } SYS_CONSOLE_PRINT("\n"); #endif +#else +#if defined(PAN_COORDINATOR) + appUartSendMessage(ind->payload, ind->payloadSize); +#else + appCmdDataInd(ind); +#endif #if defined(ENABLE_SLEEP_FEATURE) && defined(ENDDEVICE) #if (CAPABILITY_INFO == CAPABILITY_INFO_ED) deviceCanSleep = true; @@ -146,6 +205,7 @@ static void appDataInd(RECEIVED_MESH_MESSAGE *ind) OSAL_QUEUE_Send(&appData.appQueue, &sleepReq, 0); #endif #endif +#endif } /***************************************************************************** @@ -270,6 +330,7 @@ static void appDataConf(uint8_t msgConfHandle, miwi_status_t status, uint8_t* ms void appSendData(AppMessage_t *appMsg) { uint8_t myData = 0U; + AppMessage_t iappMsg; APP_Msg_T appMode; APP_Msg_T *appState; appState = &appMode; @@ -287,6 +348,12 @@ void appSendData(AppMessage_t *appMsg) #endif #if defined(PAN_COORDINATOR) + appMsg->caption.size = (uint8_t)APP_CAPTION_SIZE; + memcpy(appMsg->caption.text, APP_CAPTION, APP_CAPTION_SIZE); + sprintf(&(appMsg->caption.text[APP_CAPTION_SIZE - SHORT_ADDRESS_CAPTION_SIZE]), "-0x%04X", myShortAddress); +#if defined(WSN_MONITOR_SUPPORT) + appUartSendMessage((uint8_t *)appMsg, sizeof(AppMessage_t)); +#endif appDataSendingTimerHandle = SYS_TIME_CallbackRegisterMS(&appDataSendingTimerHandler, (uintptr_t)&myData,APP_SENDING_INTERVAL, SYS_TIME_SINGLE); if(appDataSendingTimerHandle == SYS_TIME_HANDLE_INVALID) { @@ -296,6 +363,7 @@ void appSendData(AppMessage_t *appMsg) appState->msgId = APP_STATE_WAIT_SEND_TIMER; OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); #else + appMsg->caption.type = 32; #if !defined(ENABLE_SLEEP_FEATURE) #if defined(LED_ENABLED) #if (LED_COUNT > 0U) @@ -327,6 +395,25 @@ void appSendData(AppMessage_t *appMsg) } #endif } +#if defined(PAN_COORDINATOR) +SERCOM_USART_RING_BUFFER_CALLBACK usartCb(SERCOM_USART_EVENT event, uintptr_t cb) +{ + ssize_t nUnreadBytes; + ssize_t nBytesRead; + SYS_CONSOLE_HANDLE myConsoleHandle; + myConsoleHandle = SYS_CONSOLE_HandleGet(SYS_CONSOLE_INDEX_0); + nUnreadBytes = SYS_CONSOLE_ReadCountGet(myConsoleHandle); + if (nUnreadBytes == -1) + { + + } + else + { + SYS_CONSOLE_Read( myConsoleHandle, (void*)&rx_data, nUnreadBytes ); + } + UartBytesReceived((uint16_t)nUnreadBytes,(uint8_t *)&rx_data); +} +#endif /*************************************************************************//** *****************************************************************************/ @@ -345,7 +432,12 @@ void MiApp_Init(void) #if defined(CHIMERA_SOC) EIC_CallbackRegister(EIC_PIN_0, eic_custom_cb, dummyVal); #else - EIC_CallbackRegister(EIC_PIN_2, eic_custom_cb, dummyVal); + EIC_CallbackRegister(EIC_PIN_8, eic_custom_cb, dummyVal); +#endif +#if defined(PAN_COORDINATOR) + SERCOM0_USART_ReadNotificationEnable(true, true); + SERCOM0_USART_ReadThresholdSet(19); + SERCOM0_USART_ReadCallbackRegister(usartCb, (uintptr_t)&dummyVal); #endif #endif } @@ -468,15 +560,17 @@ void MiAPP_TaskHandler(APP_Msg_T *appState) apiReq.paramSize = (uint8_t)sizeof(startNetworkReq_t); apiReq.uApiID = (uint8_t)MIWI_START_NW; MIWI_API_CALL((STACK_API_Request*)&apiReq); +#if defined(ADDRESS_CHECK) APP_Msg_T appMsg; APP_Msg_T *appState; appState = &appMsg; appStates = APP_ADD_ACCEPTED_ADDRESS; appState->msgId = (uint8_t)APP_ADD_ACCEPTED_ADDRESS; OSAL_QUEUE_Send(&appData.appQueue, appState, 0); +#endif break; } - +#if defined(ADDRESS_CHECK) case APP_ADD_ACCEPTED_ADDRESS: { if (deviceCountRem !=0) @@ -496,7 +590,7 @@ void MiAPP_TaskHandler(APP_Msg_T *appState) } break; } - +#endif #else case (uint8_t)APP_STATE_CONNECT_NETWORK: { @@ -512,7 +606,7 @@ void MiAPP_TaskHandler(APP_Msg_T *appState) } #endif -#if defined(COORDINATOR) || defined (ENDDEVICE) +#if defined(PAN_COORDINATOR) || defined(COORDINATOR) || defined (ENDDEVICE) case (uint8_t)APP_STATE_SEND: { AppMessage_t *p_appMsg = NULL; @@ -525,22 +619,23 @@ void MiAPP_TaskHandler(APP_Msg_T *appState) MiApp_Get(CHANNEL, (uint8_t *)&appMsg.workingChannel); MiApp_Get(PANID, (uint8_t *)&appMsg.panId); p_appMsg = &appMsg; - appMsg.caption.type = 32; #if defined(COORDINATOR) if (appMsg.shortAddr & RXON_ENDEVICE_ADDRESS_MASK) { appMsg.caption.size = APP_CAPTION_ED_SIZE; -// memcpy(appMsg.caption.text, APP_CAPTION_ED, APP_CAPTION_ED_SIZE); -// sprintf(&(appMsg.caption.text[APP_CAPTION_ED_SIZE - SHORT_ADDRESS_CAPTION_SIZE]), "-0x%04X", shortAddressLocal); + memcpy(appMsg.caption.text, APP_CAPTION_ED, APP_CAPTION_ED_SIZE); + sprintf(&(appMsg.caption.text[APP_CAPTION_ED_SIZE - SHORT_ADDRESS_CAPTION_SIZE]), "-0x%04X", appMsg.shortAddr); } else #endif { appMsg.caption.size = (uint8_t)APP_CAPTION_SIZE; -// memcpy(appMsg.caption.text, APP_CAPTION, APP_CAPTION_SIZE); -// sprintf(&(appMsg.caption.text[APP_CAPTION_SIZE - SHORT_ADDRESS_CAPTION_SIZE]), "-0x%04X", shortAddressLocal); + memcpy(appMsg.caption.text, APP_CAPTION, APP_CAPTION_SIZE); + sprintf(&(appMsg.caption.text[APP_CAPTION_SIZE - SHORT_ADDRESS_CAPTION_SIZE]), "-0x%04X", appMsg.shortAddr); } +#ifndef PAN_COORDINATOR appMsg.ConfCallback = appDataConf; +#endif apiReq.parameters = p_appMsg; apiReq.paramSize = (uint8_t)sizeof(appMsg); apiReq.uApiID = (uint8_t)MIWI_SEND_DATA; diff --git a/driver/software/MiWi/MiWi_Mesh/src/miwi_app.c.bak b/driver/software/MiWi/MiWi_Mesh/src/miwi_app.c.bak new file mode 100644 index 0000000..c174a50 --- /dev/null +++ b/driver/software/MiWi/MiWi_Mesh/src/miwi_app.c.bak @@ -0,0 +1,1399 @@ +/******************************************************************************* + MiWi Demo Source File + + Company: + Microchip Technology Inc. + + File Name: + wsndemo.c + + Summary: + This file contains the System Sleep functions for the project. + + Description: + This file contains the System Sleep functions for the project. + *******************************************************************************/ + +// DOM-IGNORE-BEGIN +/******************************************************************************* +* Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries. +* +* Subject to your compliance with these terms, you may use Microchip software +* and any derivatives exclusively with Microchip products. It is your +* responsibility to comply with third party license terms applicable to your +* use of third party software (including open source software) that may +* accompany Microchip software. +* +* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED +* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A +* PARTICULAR PURPOSE. +* +* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS +* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE +* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN +* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, +* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. +*******************************************************************************/ +// DOM-IGNORE-END +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +#include "config/default/definitions.h" +#include "config/default/driver/IEEE_802154_PHY/pal/inc/pal.h" +// ***************************************************************************** +// ***************************************************************************** +// Section: Macros +// ***************************************************************************** +// ***************************************************************************** +#define APP_SCAN_DURATION 10U + +// ***************************************************************************** +// ***************************************************************************** +// Section: Data Types +// ***************************************************************************** + +/*- Variables --------------------------------------------------------------*/ +AppState_t appStates; +static SYS_Timer_t appDataSendingTimer; +static SYS_TIME_HANDLE appDataSendingTimerHandle; +//SYS_TIME_HANDLE testtimehandle; +#if defined(COORDINATOR) || defined (ENDDEVICE) +static SYS_Timer_t appNetworkStatusTimer; +static SYS_TIME_HANDLE appNetworkStatusTimerHandle; +static bool appNetworkStatus; +#endif +#if defined(PAN_COORDINATOR) +static uint8_t rx_data[APP_RX_BUF_SIZE]; +#endif +AppMessage_t appMsg; +#ifndef PAN_COORDINATOR +static uint8_t wsnmsghandle; +#endif +static bool deviceCanSleep = false; +static STACK_API_Request apiReq; +uint8_t channelCount = 0U; +uint8_t maxRSSI; +uint8_t bloomFilterValue[BLOOM_FILTER_SIZE]; +uint8_t maxNumDevices = MAX_NUMBER_OF_DEVICES_IN_NETWORK; +uint8_t acceptedDeviceCount = 0; +// Increase the number of devices that can join the network by changing the parameter "numDevices". Also add the device address, which can form a part of the network, in the array "acceptedDeviceAddress". +//This Address filtering feature is activated only by enabling the macor "ADDRESS_CHECK" +uint8_t const numDevices = 1; +uint64_t acceptedDeviceAddress [1] = {0x22665544332211AB};//{0x33665544332211AB, 0x22665544332211AB,0x55665544332211AB,0x66665544332211AB,0x77665544332211AB,0x88665544332211AB, 0x99665544332211AB, 0x44665544332211AB, 0x11555544332211AB,0x22555544332211AB}; +uint8_t deviceCountRem = numDevices; +static uint8_t gOptimalChannel = 0xFFU; +static uint8_t minRSSI = 0xFFU; +// ***************************************************************************** +// ***************************************************************************** +// Section: Function Prototypes +// ***************************************************************************** +// ***************************************************************************** +static inline uint32_t miwi_app_scan_duration_ticks(uint8_t scan_duration); +static void Connection_Confirm(miwi_status_t status); +#ifdef ENABLE_SLEEP_FEATURE +static void MAC_ReadyToDeepSleep(void); +static void app_initiate_polling(void *parameter); +#endif +#if defined(ENABLE_NETWORK_FREEZER) +static void ReconnectionIndication (miwi_status_t status); +#endif +static void appDataInd(RECEIVED_MESH_MESSAGE *ind); +/*- Implementations --------------------------------------------------------*/ + +/***************************************************************************** +*****************************************************************************/ +static void appUartSendMessage(uint8_t *data, uint8_t size) +{ + uint8_t cs = 0; + uint8_t val = 0; + ssize_t nr; + SYS_CONSOLE_HANDLE myConsoleHandle; + myConsoleHandle = SYS_CONSOLE_HandleGet(SYS_CONSOLE_INDEX_0); + val = 0x10; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + val = 0x02; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); +// SERCOM0_USART_Write(0x02,1); + //sio2host_putchar(0x10); + //sio2host_putchar(0x02); + + for (uint8_t i = 0; i < size; i++) { + if (data[i] == 0x10) + { + val = 0x10; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + //sio2host_putchar(0x10); + cs += 0x10; + } + //SERCOM0_USART_Write((uint8_t *)&0x10,1); + val = data[i]; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + //sio2host_putchar(data[i]); + cs += data[i]; + } + + val = 0x10; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + val = 0x03; + SYS_CONSOLE_Write( myConsoleHandle, &val, 1); +// SERCOM0_USART_Write(&val,1); + //sio2host_putchar(0x10); + //sio2host_putchar(0x03); + cs += 0x10 + 0x02 + 0x10 + 0x03; + SYS_CONSOLE_Write( myConsoleHandle, &cs, 1); +// SERCOM0_USART_Write((uint8_t *)&cs,1); + //SERCOM0_USART_Write(cs); + //sio2host_putchar(cs); +} + +static void appDataInd(RECEIVED_MESH_MESSAGE *ind) +{ + AppMessage_t *msg = (AppMessage_t *)ind->payload; + +#if !defined(ENABLE_SLEEP_FEATURE) +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_Toggle(); +#else + LED_Toggle(1,LED_DATA); +#endif +#endif +#endif +#endif + + msg->lqi = ind->packetLQI; + msg->rssi = (int8_t)ind->packetRSSI; +#if !defined(WSN_MONITOR_SUPPORT) + SYS_CONSOLE_PRINT("\r\nPayload received\r\n"); +#if defined(PAN_COORDINATOR) + for(uint8_t i=0U; ipayloadSize; i++) + { + SYS_CONSOLE_PRINT("%x",ind->payload[i]); + } + SYS_CONSOLE_PRINT("\n"); +#else +// appCmdDataInd(ind); + for(uint8_t i=0U; ipayloadSize; i++) + { + SYS_CONSOLE_PRINT("%x",ind->payload[i]); + } + SYS_CONSOLE_PRINT("\n"); +#endif +#else +#if defined(PAN_COORDINATOR) + appUartSendMessage(ind->payload, ind->payloadSize); +#else + appCmdDataInd(ind); +#endif +#if defined(ENABLE_SLEEP_FEATURE) && defined(ENDDEVICE) +#if (CAPABILITY_INFO == CAPABILITY_INFO_ED) + deviceCanSleep = true; + APP_Msg_T sleepReq; + sleepReq.msgId = (uint8_t)APP_STATE_DATA_RECEIVE_IND; + appStates = APP_STATE_DATA_RECEIVE_IND; + OSAL_QUEUE_Send(&appData.appQueue, &sleepReq, 0); +#endif +#endif +#endif +} + +/***************************************************************************** +*****************************************************************************/ +static void appDataSendingTimerHandler(uintptr_t context) +{ + APP_Msg_T *p_appModes; + APP_Msg_T appModes; + p_appModes = &appModes; + if ((APP_STATE_WAIT_SEND_TIMER == appStates) || (APP_STATE_PREPARE_TO_SLEEP == appStates)) + { + appStates = APP_STATE_SEND; + p_appModes->msgId = (uint8_t)APP_STATE_SEND; + OSAL_QUEUE_Send(&appData.appQueue, p_appModes, 0); + } + else + { + appStates = APP_STATE_WAIT_SEND_TIMER; + uint8_t myData = 0U; + appDataSendingTimerHandle = SYS_TIME_CallbackRegisterMS(&appDataSendingTimerHandler, (uintptr_t)&myData,APP_SENDING_INTERVAL, SYS_TIME_SINGLE); + if(appDataSendingTimerHandle == SYS_TIME_HANDLE_INVALID) + { + return; + } + } + + (void)context; +} + +#if defined(COORDINATOR) || defined (ENDDEVICE) + +/***************************************************************************** +*****************************************************************************/ +static void appNetworkStatusTimerHandler(uintptr_t context) +{ +#if !defined(ENABLE_SLEEP_FEATURE) +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_Toggle(); +#else + LED_Toggle(1,LED_NETWORK); +#endif +#endif +#endif +#endif + (void)context; +} +#endif + +/***************************************************************************** +*****************************************************************************/ +#if defined(COORDINATOR) || defined (ENDDEVICE) +static void appDataConf(uint8_t msgConfHandle, miwi_status_t status, uint8_t* msgPointer) +{ + APP_Msg_T *p_appModes; + APP_Msg_T appModes; + p_appModes = &appModes; +#if !defined(ENABLE_SLEEP_FEATURE) +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_Off(); +#else + LED_Off(1,LED_DATA); +#endif +#endif +#endif +#endif + + if (SUCCESS == status) { + if (!appNetworkStatus) { +#if !defined(ENABLE_SLEEP_FEATURE) +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_On(); +#else + LED_On(1, LED_NETWORK); +#endif +#endif +#endif +#endif + + SYS_TIME_TimerStop(appNetworkStatusTimerHandle); + appNetworkStatus = true; + } + } else { + if (appNetworkStatus) { +#if !defined(ENABLE_SLEEP_FEATURE) +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_Off(); +#else + LED_Off(1,LED_NETWORK); +#endif +#endif +#endif +#endif + uint8_t myData = 0; + appNetworkStatusTimerHandle = SYS_TIME_CallbackRegisterMS(&appNetworkStatusTimerHandler, (uintptr_t)&myData,APP_NWKSTATUS_INTERVAL, SYS_TIME_PERIODIC); + if(appNetworkStatusTimerHandle == SYS_TIME_HANDLE_INVALID) + { + return; + } + appNetworkStatus = false; + } + } + if ((APP_STATE_WAIT_CONF == appStates) || (APP_STATE_PREPARE_TO_SLEEP == appStates)) + { + appStates = APP_STATE_SENDING_DONE; + p_appModes->msgId = (uint8_t)APP_STATE_SENDING_DONE; + OSAL_QUEUE_Send(&appData.appQueue, p_appModes, 0); + } +} + +#endif + +/***************************************************************************** +*****************************************************************************/ +void appSendData(AppMessage_t *appMsg) +{ + uint8_t myData = 0U; + APP_Msg_T appMode; + APP_Msg_T *appState; + appState = &appMode; +#ifndef PAN_COORDINATOR + uint16_t dstAddr = 0U; /* PAN Coordinator Address */ +#endif +#if defined(OTAU_ENABLED) + otau_log(LOG_INFO, MIWI_APP, ENTRY, 8, (uint8_t *)"App Data"); + otau_trace(TRACE_ENTRY); +#endif + +#ifndef PAN_COORDINATOR + /* Get Next Hop Short address to reach PAN Coordinator*/ + appMsg->nextHopAddr = MiApp_MeshGetNextHopAddr(PAN_COORDINATOR_SHORT_ADDRESS); +#endif + +#if defined(PAN_COORDINATOR) + appDataSendingTimerHandle = SYS_TIME_CallbackRegisterMS(&appDataSendingTimerHandler, (uintptr_t)&myData,APP_SENDING_INTERVAL, SYS_TIME_SINGLE); + if(appDataSendingTimerHandle == SYS_TIME_HANDLE_INVALID) + { + return; + } + appStates = APP_STATE_WAIT_SEND_TIMER; + appState->msgId = APP_STATE_WAIT_SEND_TIMER; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); +#else +#if !defined(ENABLE_SLEEP_FEATURE) +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_On(); +#else + LED_On(1, LED_DATA); +#endif +#endif +#endif +#endif + +#ifdef ENABLE_SECURITY + if (MiApp_SendData(2, (uint8_t *)&dstAddr, (uint8_t)sizeof(AppMessage_t), (uint8_t *)appMsg, wsnmsghandle, true, appMsg->ConfCallback)) +#else + if (MiApp_SendData(2, (uint8_t *)&dstAddr, (uint8_t)sizeof(AppMessage_t), (uint8_t *)appMsg, wsnmsghandle, true, appMsg->ConfCallback)) +#endif + { + ++wsnmsghandle; + appStates = APP_STATE_WAIT_CONF; + appState->msgId = (uint8_t)APP_STATE_WAIT_CONF; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); + } + else + { + appState->msgId = (uint8_t)APP_STATE_SENDING_DONE; + appStates = APP_STATE_SENDING_DONE; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); + } +#endif +} + +/*************************************************************************//** +*****************************************************************************/ +void MiApp_Init(void) +{ + Wsndemo_Init(); + Demomsg_Init(); + MiAppTimer_Init(); + MiApp_SubscribeDataIndicationCallback(appDataInd); +#ifndef PAN_COORDINATOR + MiApp_SubscribeLinkFailureCallback(appLinkFailureCallback); +#endif + Rx_On(false); + appInitialized = true; +#ifdef USER_BUTTON_ENABLED +#if defined(CHIMERA_SOC) + EIC_CallbackRegister(EIC_PIN_0, eic_custom_cb, dummyVal); +#else + EIC_CallbackRegister(EIC_PIN_2, eic_custom_cb, dummyVal); +#endif +#endif +} + +#if defined(ENABLE_NETWORK_FREEZER) +static void ReconnectionIndication (miwi_status_t status) +{ + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; + if(SUCCESS == status) + { + appStates = APP_STATE_RECONNECT_SUCCESS; +// appState->msgId = APP_STATE_RECONNECT_SUCCESS; +// OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } + else + { + appStates = APP_STATE_RECONNECT_FAILURE; +// appState->msgId = APP_STATE_RECONNECT_FAILURE; +// OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } +} +#endif + +void MiApp_StateInit(void) +{ + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; +#if defined(ENABLE_NETWORK_FREEZER) + if (appStates == APP_STATE_RECONNECT_SUCCESS) + { + appStates = APP_STATE_RECONNECT_SUCCESS; + appState->msgId = (uint8_t)APP_STATE_RECONNECT_SUCCESS; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } + else if(appStates == APP_STATE_WAIT_FOR_RECONNECT_CALLBACK) + { + appStates = APP_STATE_WAIT_FOR_RECONNECT_CALLBACK; + appState->msgId = (uint8_t)APP_STATE_WAIT_FOR_RECONNECT_CALLBACK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } + else +#endif + { +#if defined(PAN_COORDINATOR) + appStates = APP_STATE_START_NETWORK; + appState->msgId = (uint8_t)APP_STATE_START_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); +#else + appStates = APP_STATE_CONNECT_NETWORK; + appState->msgId = (uint8_t)APP_STATE_CONNECT_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); +#endif + } +} + +/*************************************************************************//** +*****************************************************************************/ +void MiAPP_TaskHandler(APP_Msg_T *appState) +{ + switch (appState->msgId) + { +#if defined(ENABLE_NETWORK_FREEZER) + case (uint8_t)APP_STATE_RECONNECT_SUCCESS: + { + appStates = APP_STATE_SEND; + appState->msgId = (uint8_t)APP_STATE_SEND; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + break; + } + case (uint8_t)APP_STATE_WAIT_FOR_RECONNECT_CALLBACK: + { + if(appStates == APP_STATE_RECONNECT_SUCCESS) + { + appStates = APP_STATE_RECONNECT_SUCCESS; + appState->msgId = (uint8_t)APP_STATE_RECONNECT_SUCCESS; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } + else if(appStates == APP_STATE_RECONNECT_FAILURE) + { + appStates = APP_STATE_RECONNECT_FAILURE; + appState->msgId = (uint8_t)APP_STATE_RECONNECT_FAILURE; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } + else + { + appStates = APP_STATE_WAIT_FOR_RECONNECT_CALLBACK; + appState->msgId = (uint8_t)APP_STATE_WAIT_FOR_RECONNECT_CALLBACK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } + + break; + } + case (uint8_t)APP_STATE_RECONNECT_FAILURE: + { +#if defined(PAN_COORDINATOR) + appStates = APP_STATE_START_NETWORK; + appState->msgId = (uint8_t)APP_STATE_START_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); +#else + appStates = APP_STATE_CONNECT_NETWORK; + appState->msgId = (uint8_t)APP_STATE_CONNECT_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); +#endif + break; + } +#endif + +#if defined(PAN_COORDINATOR) + case (uint8_t)APP_STATE_START_NETWORK: + { + startNetworkReq_t startNwReq; + startNwReq.ChannelMap = (uint32_t)CHANNEL_MAP; + startNwReq.Mode = START_CONN_DIRECT; + startNwReq.ScanDuration = APP_SCAN_DURATION; + startNwReq.ConfCallback = Connection_Confirm; + apiReq.parameters = (void*)&startNwReq; + apiReq.paramSize = (uint8_t)sizeof(startNetworkReq_t); + apiReq.uApiID = (uint8_t)MIWI_START_NW; + MIWI_API_CALL((STACK_API_Request*)&apiReq); + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; + appStates = APP_ADD_ACCEPTED_ADDRESS; + appState->msgId = (uint8_t)APP_ADD_ACCEPTED_ADDRESS; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + break; + } + + case APP_ADD_ACCEPTED_ADDRESS: + { + if (deviceCountRem !=0) + { + if (!bloomFilterAutoJoin) + { + if (acceptedDeviceAddress[acceptedDeviceCount]!= 0) + { + bool addNewDevice = MiApp_Commissioning_AddNewDevice(acceptedDeviceAddress[acceptedDeviceCount], true); + if (addNewDevice == true); + { + deviceCountRem--; + acceptedDeviceCount++; + } + } + } + } + break; + } + +#else + case (uint8_t)APP_STATE_CONNECT_NETWORK: + { + searchNetworkReq_t searchNwReq; + searchNwReq.ScanDuration = APP_SCAN_DURATION; + searchNwReq.ChannelMap = (uint32_t)CHANNEL_MAP; + searchNwReq.ConfCallback = searchConfim; + apiReq.uApiID = (uint8_t)MIWI_CONNECT_NW; + apiReq.paramSize = (uint8_t)sizeof(searchNetworkReq_t); + apiReq.parameters = (void*)&searchNwReq; + MIWI_API_CALL(&apiReq); + break; + } + +#endif +#if defined(COORDINATOR) || defined (ENDDEVICE) + case (uint8_t)APP_STATE_SEND: + { + AppMessage_t *p_appMsg = NULL; + appMsg.sensors.battery = rand() & 0xffff; + appMsg.sensors.temperature = rand() & 0x7f; //sensor data or any user data + appMsg.sensors.light = rand() & 0xff; + /* Get Short address */ + MiApp_Get(SHORT_ADDRESS, (uint8_t *)&appMsg.shortAddr); + appMsg.extAddr = appMsg.shortAddr; + MiApp_Get(CHANNEL, (uint8_t *)&appMsg.workingChannel); + MiApp_Get(PANID, (uint8_t *)&appMsg.panId); + p_appMsg = &appMsg; + appMsg.caption.type = 32; + #if defined(COORDINATOR) + if (appMsg.shortAddr & RXON_ENDEVICE_ADDRESS_MASK) + { + appMsg.caption.size = APP_CAPTION_ED_SIZE; +// memcpy(appMsg.caption.text, APP_CAPTION_ED, APP_CAPTION_ED_SIZE); +// sprintf(&(appMsg.caption.text[APP_CAPTION_ED_SIZE - SHORT_ADDRESS_CAPTION_SIZE]), "-0x%04X", shortAddressLocal); + } + else + #endif + { + appMsg.caption.size = (uint8_t)APP_CAPTION_SIZE; +// memcpy(appMsg.caption.text, APP_CAPTION, APP_CAPTION_SIZE); +// sprintf(&(appMsg.caption.text[APP_CAPTION_SIZE - SHORT_ADDRESS_CAPTION_SIZE]), "-0x%04X", shortAddressLocal); + } + appMsg.ConfCallback = appDataConf; + apiReq.parameters = p_appMsg; + apiReq.paramSize = (uint8_t)sizeof(appMsg); + apiReq.uApiID = (uint8_t)MIWI_SEND_DATA; + MIWI_API_CALL((STACK_API_Request*)&apiReq); + break; + } +#endif + case (uint8_t)APP_STATE_DATA_RECEIVE_IND: + case (uint8_t)APP_STATE_SENDING_DONE: + { + uint8_t myData = 0U; +#if defined(ENABLE_SLEEP_FEATURE) && defined(ENDDEVICE) && (CAPABILITY_INFO == CAPABILITY_INFO_ED) + deviceCanSleep = true; + appDataSendingTimerHandle = SYS_TIME_CallbackRegisterMS(&appDataSendingTimerHandler, (uintptr_t)&myData,APP_SENDING_INTERVAL, SYS_TIME_SINGLE); +// testtimehandle = appDataSendingTimerHandle; + if(appDataSendingTimerHandle == SYS_TIME_HANDLE_INVALID) + { + return; + } + appStates = APP_STATE_PREPARE_TO_SLEEP; + appState->msgId = (uint8_t)APP_STATE_PREPARE_TO_SLEEP; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); +#else + appDataSendingTimerHandle = SYS_TIME_CallbackRegisterMS(&appDataSendingTimerHandler, (uintptr_t)&myData,APP_SENDING_INTERVAL, SYS_TIME_SINGLE); + if(appDataSendingTimerHandle == SYS_TIME_HANDLE_INVALID) + { + return; + } + appStates = APP_STATE_WAIT_SEND_TIMER; + appState->msgId = (uint8_t)APP_STATE_WAIT_SEND_TIMER; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); +#endif + break; + } + +#if defined(COORDINATOR) || defined(ENDDEVICE) + case (uint8_t)APP_STATE_WAIT_SEND_TIMER: + case (uint8_t)APP_STATE_WAIT_CONF: + { + //do nothing just wait + break; + } +#endif +#if defined(ENABLE_SLEEP_FEATURE) && defined(ENDDEVICE) + case (uint8_t)APP_STATE_PREPARE_TO_SLEEP: + { + uint32_t sleepDuration; + if (APP_ReadyToSleep(&sleepDuration)) + { + /* Enter system sleep mode */ + DEVICE_EnterDeepSleep(true, sleepDuration); + } + else + { + APP_Msg_T sleepReq; + appStates = APP_STATE_PREPARE_TO_SLEEP; + sleepReq.msgId = (uint8_t)APP_STATE_PREPARE_TO_SLEEP; + OSAL_QUEUE_Send(&appData.appQueue, &sleepReq, 0); + } + break; + } +#endif +#if defined(ENABLE_FREQUENCY_AGILITY) + case (uint8_t)APP_STATE_FREQUENCY_AGILITY: + { +// MiApp_InitChannelHopping(FULL_CHANNEL_MAP); + if( appState->msgData[0] > maxRSSI ) + { + maxRSSI = appState->msgData[0]; + } + // if scan time exceed scan duration, prepare to scan the next channel + if( maxRSSI < minRSSI ) + { + minRSSI = maxRSSI; + gOptimalChannel = channelCount-1; + } + appStates = APP_STATE_NOISE_DETECTION; + appState->msgId = (uint8_t)APP_STATE_NOISE_DETECTION; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + break; + } + + case (uint8_t)APP_STATE_NOISE_DETECTION: + { + uint8_t ScanDuration = 3; + uint32_t channelMask = 0x00000001; + /* Check the given channel is within the range and callback is not NULL*/ + if (!(MiMAC_GetPHYChannelInfo() & FULL_CHANNEL_MAP)) + { + return; + } + if(channelCount < 32) + { + if(FULL_CHANNEL_MAP & MiMAC_GetPHYChannelInfo() & (channelMask << channelCount)) + { + maxRSSI = 0; + /* choose appropriate channel */ + MiApp_Set(CHANNEL, &channelCount); + PHY_EdStart(ScanDuration); + } + else + { + appStates = APP_STATE_NOISE_DETECTION; + appState->msgId = (uint8_t)APP_STATE_NOISE_DETECTION; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0); + } + channelCount++; + } + else + { + MiApp_InitChannelHopping(FULL_CHANNEL_MAP, gOptimalChannel); + } + break; + } +#endif + + default: + //Handle exceptions if any + break; + } +} + +static inline uint32_t miwi_app_scan_duration_ticks(uint8_t scan_duration) +{ + uint32_t scan_symbols; + + scan_symbols = ABASESUPERFRAMEDURATION *((1<> 2U; + for (k = 0U; k < size; k++) + { + *dst = *src; + src++; + dst++; + } +} + +static void MAC_ReadyToDeepSleep(void) +{ + MAC_Ds_Param_t param; + uint16_t mac_CoordShtAddr = 0; +// param.mac_CoordExtAddr = macPib.mac_CoordExtendedAddress; + MiApp_Get(PARENT_SHORT_ADDRESS, (uint8_t*)&mac_CoordShtAddr); + param.mac_CoordShtAddr = (uint32_t)mac_CoordShtAddr; +// param.mac_max_frame_total_wait_time = macPib.mac_MaxFrameTotalWaitTime; +// param.mac_response_wait_time = macPib.mac_ResponseWaitTime; + param.mesh_state = (uint32_t)meshCurrentState; + param.app_state = (uint32_t)appStates; +// param.mac_poll_state = macPollState; + macRadioSleepState = PHY_GetTrxStatus(); + param.mac_radio_sleep_state = (uint32_t)macRadioSleepState; +// param.mac_associated_PAN_coord = macPib.mac_AssociatedPANCoord; +// param.mac_auto_request = macPib.mac_AutoRequest; +// param.mac_batt_life_ext_periods = macPib.mac_BattLifeExtPeriods; + param.mac_dsn = (uint32_t)meshSequenceNumber; + + PHY_PibGet(macPANId, (uint8_t *)&panid); + param.panid = (uint32_t)panid; + + PHY_PibGet(macShortAddress, (uint8_t *)&macshortaddr); + param.mac_short_addr = (uint32_t)macshortaddr; + + PHY_PibGet(macIeeeAddress, (uint8_t *)&macieeeaddr); + memcpy(¶m.mac_ieee_addr, &macieeeaddr, sizeof(macieeeaddr)); +// param.mac_ieee_addr = macieeeaddr; + + uint8_t channelBeforeSleep; + PHY_PibGet(phyCurrentChannel, &channelBeforeSleep); + param.phy_current_channel = (uint32_t)channelBeforeSleep; + + memcpy4ByteAligned(&mdsParam,¶m,sizeof(mdsParam)); +#if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) + memcpy4ByteAligned(&macSecPibBackup, &macSecPib, sizeof(macSecPib) ); +#endif +} + +static void MAC_WakeUpFromDeepSleep(void) +{ + MAC_Ds_Param_t param1; + uint8_t channelAfterSleep; + + memset (¶m1, 0, sizeof(param1)); + memcpy4ByteAligned(¶m1,&mdsParam,sizeof(mdsParam)); + +// macPib.mac_CoordExtendedAddress = param1.mac_CoordExtAddr; +// macieeeaddr = param1.mac_ieee_addr; + memcpy(&macieeeaddr, ¶m1.mac_ieee_addr, sizeof(param1.mac_ieee_addr)); + myParentShortAddress = (uint16_t)param1.mac_CoordShtAddr; + macshortaddr = (uint16_t)param1.mac_short_addr; +// macPib.mac_MaxFrameTotalWaitTime = param1.mac_max_frame_total_wait_time; +// macPib.mac_ResponseWaitTime = param1.mac_response_wait_time; + meshCurrentState = (meshState_t)param1.mesh_state; + macRadioSleepState = (PHY_TrxStatus_t)param1.mac_radio_sleep_state; +// macPib.mac_AssociatedPANCoord = param1.mac_associated_PAN_coord; +// macPib.mac_AutoRequest = param1.mac_auto_request; +// macPib.mac_BattLifeExtPeriods = param1.mac_batt_life_ext_periods; + channelAfterSleep = (uint8_t)param1.phy_current_channel; + panid = (uint16_t)param1.panid; + appStates = (AppState_t)param1.app_state; + meshSequenceNumber = (uint8_t)param1.mac_dsn; + + MiApp_Set(CHANNEL, &channelAfterSleep); + MiApp_Set(PANID, (uint8_t*)&panid); + MiApp_Set(SHORT_ADDRESS, (uint8_t*)&macshortaddr); +// PibValue_t pibValue; +// pibValue.pib_value_64bit = macieeeaddr; +// PHY_PibSet(macIeeeAddress, &pibValue); +#if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) + memcpy4ByteAligned(&macSecPib, &macSecPibBackup, sizeof(macSecPibBackup) ); +#endif + +} + +/* + * @brief MAC Wakeup Callback Function from application + * + */ +void MAC_Wakeup(void) +{ + /* Retrieve MAC Parameters from Retention RAM after Deepsleep wakeup*/ + MAC_WakeUpFromDeepSleep(); +} + +#endif +/***************************************************************************** +*****************************************************************************/ + +/** + * Init function of the WSNDemo application + */ +void Wsndemo_Init(void) +{ + trx_cca_mode_t trxCcaMode; + bool invalidIEEEAddrFlag = false; + uint64_t invalidIEEEAddr; + PHY_Retval_t retVal = PHY_FAILURE; + PibValue_t pibValue; + +#if defined(ENABLE_NETWORK_FREEZER) + MiApp_SubscribeReConnectionCallback((ReconnectionCallback_t)ReconnectionIndication ); +#endif + + /* Initialize the Protocol */ + if (MiApp_ProtocolInit() == RECONNECTION_IN_PROGRESS) + { + appStates = APP_STATE_WAIT_FOR_RECONNECT_CALLBACK; + } + + /* Check if a valid IEEE address is available.0x0000000000000000 and 0xFFFFFFFFFFFFFFFF is persumed to be invalid */ + /* Check if IEEE address is 0x0000000000000000 */ + memset((uint8_t *)&invalidIEEEAddr, 0x00, LONG_ADDR_LEN); + if (0 == memcmp((uint8_t *)&invalidIEEEAddr, (uint8_t *)&myLongAddress, LONG_ADDR_LEN)) + { + invalidIEEEAddrFlag = true; + } +//memset(&pibValue.pib_value_64bit, 0, MY_ADDRESS_LENGTH); + /* Check if IEEE address is 0xFFFFFFFFFFFFFFFF */ + memset((uint8_t *)&invalidIEEEAddr, 0xFF, LONG_ADDR_LEN); + if (0 == memcmp((uint8_t *)&invalidIEEEAddr, (uint8_t *)&myLongAddress, LONG_ADDR_LEN)) + { + invalidIEEEAddrFlag = true; + } + + if (invalidIEEEAddrFlag) + { + /* + * In case no valid IEEE address is available, a random + * IEEE address will be generated to be able to run the + * applications for demonstration purposes. + * In production code this can be omitted. + */ + uint64_t randomNumber; + if (PAL_SUCCESS != PAL_GetRandomNumber((uint8_t*)&randomNumber, sizeof(randomNumber))) { + return; + } + PHY_PibSet(macIeeeAddress,(PibValue_t *) &randomNumber); + } + else + { + memcpy(&pibValue.pib_value_64bit, &myLongAddress, MY_ADDRESS_LENGTH); + retVal = PHY_PibSet(macIeeeAddress, &pibValue); + if(retVal != PHY_SUCCESS) + { + return; + } + } + trxCcaMode = TRX_CCA_MODE2; + PHY_PibGet(macIeeeAddress, (uint8_t*)&pibValue); + pibValue.pib_value_8bit = (uint8_t)trxCcaMode; + retVal = PHY_PibSet(phyCCAMode, &pibValue); + PHY_PibGet(phyCCAMode, (uint8_t*)&pibValue); + +} + +void Demomsg_Init(void) +{ + appMsg.commandId = APP_COMMAND_ID_NETWORK_INFO; + appMsg.nodeType = APP_NODE_TYPE; + appMsg.extAddr = 0; + appMsg.shortAddr = 0; + appMsg.softVersion = 0x01100000; + appMsg.channelMask = CHANNEL_MAP; + appMsg.nextHopAddr = 0; + appMsg.lqi = 0; + appMsg.rssi = 0; + + appMsg.sensors.type = 1U; + appMsg.sensors.size = (uint8_t)sizeof(int32_t) * 3U; + appMsg.sensors.battery = 0; + appMsg.sensors.temperature = 0; + appMsg.sensors.light = 0; + + appMsg.caption.type = 32U; + appMsg.caption.size = (uint8_t)APP_CAPTION_SIZE; + memcpy(&appMsg.caption.text, APP_CAPTION, APP_CAPTION_SIZE); +} + +void MiAppTimer_Init(void) +{ +#if defined(COORDINATOR) || defined (ENDDEVICE) + appDataSendingTimer.interval = APP_SENDING_INTERVAL; + appDataSendingTimer.mode = SYS_TIME_SINGLE; + appDataSendingTimer.handler = appDataSendingTimerHandler; + appNetworkStatus = false; + appNetworkStatusTimer.interval = APP_NWKSTATUS_INTERVAL; + appNetworkStatusTimer.mode = SYS_TIME_PERIODIC; + appNetworkStatusTimer.handler = appNetworkStatusTimerHandler; + +#else +#if !defined(ENABLE_SLEEP_FEATURE) +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_On(); +#else + LED_On(1, LED_NETWORK); +#endif +#endif +#endif +#endif +#endif +} +#ifndef PAN_COORDINATOR +/** + * Search confirmation + */ +void searchConfim(uint8_t foundScanResults, void* ScanResults) +{ + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; + searchConf_t* searchConfRes = (searchConf_t *)ScanResults; + uint8_t selectedParentIndex = 0xFFU; + if (foundScanResults != 0U) + { + for (uint8_t loopindex = 0U; loopindex < foundScanResults; loopindex++) + { + if (searchConfRes->beaconList[loopindex].connectionPermit) + { +#if defined(ENDDEVICE) + /* Select the parent which has the high end device capacity (holding less number of end devices) */ + if (loopindex == 0U) + { + selectedParentIndex = 0U; + } +#if (CAPABILITY_INFO == CAPABILITY_INFO_ED) + else if (searchConfRes->beaconList[loopindex].sleepEnddeviceCapacity > searchConfRes->beaconList[selectedParentIndex].sleepEnddeviceCapacity){} +#elif (CAPABILITY_INFO == CAPABILITY_INFO_ED_RXON) + else if (searchConfRes->beaconList[loopindex].enddeviceCapacity > searchConfRes->beaconList[selectedParentIndex].enddeviceCapacity) + { + selectedParentIndex = loopindex; + } +#endif +#else + { + selectedParentIndex = loopindex; + } +#endif + } + } + + if (selectedParentIndex != 0xFFU) + { + MiApp_EstablishConnection(searchConfRes->beaconList[selectedParentIndex].logicalChannel, + SHORT_ADDR_LEN, (uint8_t*)&searchConfRes->beaconList[selectedParentIndex].shortAddress, CAPABILITY_INFO, Connection_Confirm); + return; + } + /* Initiate the search again since no connection permit found to join */ + appStates = APP_STATE_CONNECT_NETWORK; + appState->msgId = (uint8_t)APP_STATE_CONNECT_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); + } + else + { + /* Initiate the search again since no beacon */ + appStates = APP_STATE_CONNECT_NETWORK; + appState->msgId = (uint8_t)APP_STATE_CONNECT_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); + } +} +#endif + +/** + * Connection confirmation + */ +static void Connection_Confirm(miwi_status_t status) +{ + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; + if (SUCCESS == status) + { + appStates = APP_STATE_SEND; + appState->msgId = (uint8_t)APP_STATE_SEND; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); + } + else + { +#if defined(PAN_COORDINATOR) + appStates = APP_STATE_START_NETWORK; + appState->msgId = (uint8_t)APP_STATE_START_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); +#else + appStates = APP_STATE_CONNECT_NETWORK; + appState->msgId = (uint8_t)APP_STATE_CONNECT_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); +#endif + } + +} + +/** + * Task of the WSNDemo application + * This task should be called in a while(1) + */ +void wsndemo_task(void) +{ + MeshTasks(); +} + +#ifndef PAN_COORDINATOR +void appLinkFailureCallback(void) +{ + APP_Msg_T appMsg; + APP_Msg_T *appState; + appState = &appMsg; + SYS_TIME_TimerStop(timerHandles.keepAliveTimerRxOffEdHandle); + SYS_TIME_TimerDestroy(timerHandles.keepAliveTimerRxOffEdHandle); + SYS_TIME_TimerStop(appDataSendingTimerHandle); + SYS_TIME_TimerDestroy(appDataSendingTimerHandle); + SYS_TIME_TimerStop(appNetworkStatusTimerHandle); + SYS_TIME_TimerDestroy(appNetworkStatusTimerHandle); + /* On link failure initiate search to establish connection */ + appStates = APP_STATE_CONNECT_NETWORK; + appState->msgId = (uint8_t)APP_STATE_CONNECT_NETWORK; + OSAL_QUEUE_Send(&appData.appQueue, appState, 0U); +} +#endif + +void MiMesh_TaskHandler(void) +{ + wsndemo_task(); +} + +void MiMac_TaskHandler(void) +{ +#ifdef PROTOCOL_MESH +MiMesh_TaskHandler(); +#endif +#ifdef PROTOCOL_STAR +Star_TaskHandler(); +#endif +#ifdef PROTOCOL_P2P +P2P_TaskHandler(); +#endif +} + +miwi_status_t PhyToMiwi_Status(PHY_Retval_t status) +{ + miwi_status_t dataStat = FAILURE; + switch(status) + { + case PHY_SUCCESS: + { + dataStat = SUCCESS; + break; + } + case PHY_FAILURE: + case PHY_BUSY: + { + dataStat = FAILURE; + break; + } + case PHY_CHANNEL_BUSY: + case PHY_CHANNEL_ACCESS_FAILURE: + { + dataStat = CHANNEL_ACCESS_FAILURE; + break; + } +#ifdef CHIMERA_SOC + case PHY_RF_REQ_ABORTED: + case PHY_RF_UNAVAILABLE: + { + dataStat = ERR_TRX_FAIL; + break; + } +#endif + case PHY_NO_ACK: + { + dataStat = NO_ACK; + break; + } + case PHY_INVALID_PARAMETER: + case PHY_UNSUPPORTED_ATTRIBUTE: + { + dataStat = ERR_INVALID_INPUT; + break; + } + case PHY_TRX_ASLEEP: + case PHY_TRX_AWAKE: + case PHY_FRAME_PENDING: + case PHY_CHANNEL_IDLE: + { + dataStat = FAILURE; + break; + } + default: + { + //Handle exceptions if any + break; + } + } + return dataStat; +} + +void MiMAC_FFDDemoInit(void) +{ + /* If Restored properly, valid short address will be available */ + if (myShortAddress != 0xFFFFU) + { +#ifndef ENDDEVICE + /* Change state since restoration is complete and all required network information available */ + meshCurrentState = IN_NETWORK_STATE; +#ifndef PAN_COORDINATOR + /* Update Parent short address */ + if (myShortAddress & RXON_ENDEVICE_ADDRESS_MASK) + { + myParentShortAddress = myShortAddress & COORD_MASK; + + /* Change state to partial since it is working as RX ON End device */ + meshCurrentState = IN_NETWORK_PARTIAL_STATE; + + /* Keep alive timer - load with rxon end device since it got address as rxonED*/ + timerHandles.keepAliveTimerSendKeepAliveRxOnEd.timeout = generateJitterTimeout(miwiDefaultRomOrRamParams->keepAliveRxOnEdSendInterval * 1000, 5); + } + else + { + myParentShortAddress = PAN_COORDINATOR_ADDRESS; + /* load Keep alive timer */ + timerHandles.keepAliveTimerSendKeepAliveRxOnEd.timeout = generateJitterTimeout(miwiDefaultRomOrRamParams->keepAliveCoordSendInterval * 1000, 5); + } + + /* Start the keep alive timer upon successful reconnection */ + timerHandles.keepAliveTimerSendKeepAliveRxOnEd.interval = timerHandles.keepAliveTimerSendKeepAliveRxOnEd.timeout; + timerHandles.keepAliveTimerSendKeepAliveRxOnEd.handler = sendKeepAlive; + timerHandles.keepAliveTimerSendKeepAliveRxOnEd.mode = SYS_TIME_PERIODIC; + uint8_t myData = 0U; + timerHandles.keepAliveTimerSendKeepAliveRxOnEdHandle = SYS_TIME_CallbackRegisterMS(timerHandles.keepAliveTimerSendKeepAliveRxOnEd.handler, (uintptr_t)&myData, timerHandles.keepAliveTimerSendKeepAliveRxOnEd.interval, SYS_TIME_PERIODIC); + if(timerHandles.keepAliveTimerSendKeepAliveRxOnEdHandle == SYS_TIME_HANDLE_INVALID) + { + return; + } +#endif +#if defined(ENABLE_NETWORK_FREEZER) + /* Inform application reconnection success */ + if (NULL != reconnectionCallback) + reconnectionCallback(SUCCESS); +#endif + +#if defined(ENABLE_FREQUENCY_AGILITY) + if (newChannelToUpdate != 0xFFU) + { + /* Start the timer for channel update time */ + timerHandles.joinTimerchannelUpdate.handler = channelUpdateTimerExpired; + timerHandles.joinTimerchannelUpdate.timeout = (CHANNEL_UPDATE_TIME_IN_SEC * 1000U); + timerHandles.joinTimerchannelUpdate.interval = (CHANNEL_UPDATE_TIME_IN_SEC * 1000U); //michp + timerHandles.joinTimerchannelUpdate.mode = SYS_TIME_SINGLE; + uint8_t myData = 0U; + timerHandles.joinTimerchannelUpdateHandle = SYS_TIME_CallbackRegisterMS(timerHandles.joinTimerchannelUpdate.handler, (uintptr_t)&myData, timerHandles.joinTimerchannelUpdate.interval, SYS_TIME_SINGLE); + if(timerHandles.joinTimerchannelUpdateHandle == SYS_TIME_HANDLE_INVALID) + { + return; + } + + } +#endif +#endif + } +} +#ifdef ENDDEVICE +void MiMAC_RFDDemoInit(void) +{ + +#ifdef ENABLE_SLEEP_FEATURE + DEVICE_DeepSleepWakeSrc_T wakeupSrc; + DEVICE_GetDeepSleepWakeUpSrc(&wakeupSrc); + + if(wakeupSrc == DEVICE_DEEP_SLEEP_WAKE_NONE || wakeupSrc == DEVICE_DEEP_SLEEP_WAKE_MCLR) +#endif + { + +#if defined(LED_ENABLED) +#if (LED_COUNT > 0U) +#if defined(CHIMERA_SOC) + RGB_LED_GREEN_Toggle(); + RGB_LED_BLUE_Off(); + RGB_LED_RED_Off(); +#else + LED_On(1,LED_IDENTIFY); /* indicating application is started */ + LED_Off(1,LED_IDENTIFY); /* indicating network is started */ + LED_Off(1,LED_DATA); /* indicating data transmission */ +#endif +#endif +#endif +// SYS_CONSOLE_PRINT("\nMAC RFD Demo Application\r\n\n"); + /* If Restored properly, valid short address will be available */ + if (myShortAddress != 0xFFFFU) + { + /* Incase of End device, try to rejoin using establish connection procedure */ + uint16_t parentNetworkAddress = 0xFFFF; + parentNetworkAddress = myShortAddress & COORD_MASK; +#if defined(ENABLE_FREQUENCY_AGILITY) + backupParentNwkAddress = parentNetworkAddress; +#endif + initStatus = RECONNECTION_IN_PROGRESS; + MiApp_EstablishConnection(currentChannel, SHORT_ADDR_LEN, (uint8_t *)&parentNetworkAddress, gCapabilityInfo, connectionConfirm); + } + + } +#ifdef ENABLE_SLEEP_FEATURE + else + { + MAC_Wakeup(); + app_initiate_polling(NULL); + } +#endif +} + + +#ifdef ENABLE_SLEEP_FEATURE +static void app_initiate_polling(void *parameter) +{ + /* + * initiate data polling + */ + uint8_t myData = 0U; + APP_Msg_T *p_appModes; + APP_Msg_T appModes; + p_appModes = &appModes; + /*Keep compiler happy*/ + parameter = parameter; + deviceCanSleep = false; +/* Poll immediately after join- small timer for context break */ +timerHandles.keepAliveTimerRxOffEd.handler = rxOffEdKeepAliveTimerHandler; +timerHandles.keepAliveTimerRxOffEd.timeout = 50; +timerHandles.keepAliveTimerRxOffEd.interval = 50; +timerHandles.keepAliveTimerRxOffEd.mode = SYS_TIME_SINGLE; +timerHandles.keepAliveTimerRxOffEdHandle = SYS_TIME_CallbackRegisterMS(&rxOffEdKeepAliveTimerHandler, (uintptr_t)&myData, timerHandles.keepAliveTimerRxOffEd.interval, SYS_TIME_SINGLE); +if(timerHandles.keepAliveTimerRxOffEdHandle == SYS_TIME_HANDLE_INVALID) +{ + return; +} +#if defined(ENABLE_NETWORK_FREEZER) + /* Indicate application with status of reconnection */ + if (NULL != reconnectionCallback) + { + reconnectionCallback(SUCCESS); + } +#endif +} +#endif +#endif + +void Rx_On(bool isProm) +{ +PHY_TrxStatus_t trxStatus; +PHY_TrxState_t trxState = PHY_STATE_RX_ON; +//bool promCtrl = true; +trxStatus = PHY_RxEnable(trxState); +if(PHY_RX_ON == trxStatus) +{ + //TRX is in receive state + +} + + +// Enable Promiscuous mode +PHY_ConfigRxPromiscuousMode(isProm); + +// To get the PDT level configured +PHY_GetTrxConfig(AACK_PROMSCS_MODE, (uint8_t*)&isProm); +} + +uint8_t MiApp_TransceiverPowerState(uint8_t Mode) +{ + if(MiMAC_PowerState(Mode)) + { + return 1U; + } + else + { + return 0U; + } +} \ No newline at end of file