From 5e93de906b3930c83b1282047e7e8f5df84c8512 Mon Sep 17 00:00:00 2001
From: StevenCellist <47155822+StevenCellist@users.noreply.github.com>
Date: Fri, 7 Jun 2024 08:05:52 +0000
Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20=20@=2038abf?=
=?UTF-8?q?92aaf6773b370385e18575cbab0d029a84c=20=F0=9F=9A=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
_lo_ra_w_a_n_8h_source.html | 658 +++++++++++++++++----------------
_physical_layer_8h_source.html | 2 +-
2 files changed, 333 insertions(+), 327 deletions(-)
diff --git a/_lo_ra_w_a_n_8h_source.html b/_lo_ra_w_a_n_8h_source.html
index f338b8e3..e4e9019e 100644
--- a/_lo_ra_w_a_n_8h_source.html
+++ b/_lo_ra_w_a_n_8h_source.html
@@ -465,358 +465,364 @@ $(document).ready(function(){initNavTree('_lo_ra_w_a_n_8h_source.html',''); init
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 465 #define RADIOLIB_LORAWAN_NUM_SUPPORTED_BANDS (BandLast - BandEU868)
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ 471 #define RADIOLIB_LORAWAN_NUM_SUPPORTED_BANDS (BandLast - BandEU868)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
- 569 void beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey);
-
-
-
- 588 void beginABP(uint32_t addr, uint8_t* fNwkSIntKey, uint8_t* sNwkSIntKey, uint8_t* nwkSEncKey, uint8_t* appSKey);
-
- 596 int16_t
activateABP(uint8_t initialDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED);
-
-
-
-
-
-
-
- 618 #if defined(RADIOLIB_BUILD_ARDUINO)
- 628 int16_t
uplink(String& str, uint8_t fPort,
bool isConfirmed =
false,
LoRaWANEvent_t* event = NULL);
-
-
- 640 int16_t
uplink(
const char* str, uint8_t fPort,
bool isConfirmed =
false,
LoRaWANEvent_t* event = NULL);
-
- 652 int16_t
uplink(uint8_t* data,
size_t len, uint8_t fPort,
bool isConfirmed =
false,
LoRaWANEvent_t* event = NULL);
-
- 654 #if defined(RADIOLIB_BUILD_ARDUINO)
-
-
-
-
-
-
-
- 683 #if defined(RADIOLIB_BUILD_ARDUINO)
-
-
-
-
-
- 728 int16_t
sendReceive(uint8_t* dataUp,
size_t lenUp, uint8_t fPort, uint8_t* dataDown,
size_t* lenDown,
bool isConfirmed =
false,
LoRaWANEvent_t* eventUp = NULL,
LoRaWANEvent_t* eventDown = NULL);
-
-
-
-
-
-
+
+
+
+
+ 575 void beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey);
+
+
+
+ 594 void beginABP(uint32_t addr, uint8_t* fNwkSIntKey, uint8_t* sNwkSIntKey, uint8_t* nwkSEncKey, uint8_t* appSKey);
+
+ 602 int16_t
activateABP(uint8_t initialDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED);
+
+
+
+
+
+
+
+ 624 #if defined(RADIOLIB_BUILD_ARDUINO)
+ 634 int16_t
uplink(String& str, uint8_t fPort,
bool isConfirmed =
false,
LoRaWANEvent_t* event = NULL);
+
+
+ 646 int16_t
uplink(
const char* str, uint8_t fPort,
bool isConfirmed =
false,
LoRaWANEvent_t* event = NULL);
+
+ 658 int16_t
uplink(uint8_t* data,
size_t len, uint8_t fPort,
bool isConfirmed =
false,
LoRaWANEvent_t* event = NULL);
+
+ 660 #if defined(RADIOLIB_BUILD_ARDUINO)
+
+
+
+
+
+
+
+ 689 #if defined(RADIOLIB_BUILD_ARDUINO)
+
+
+
+
+
+ 734 int16_t
sendReceive(uint8_t* dataUp,
size_t lenUp, uint8_t fPort, uint8_t* dataDown,
size_t* lenDown,
bool isConfirmed =
false,
LoRaWANEvent_t* eventUp = NULL,
LoRaWANEvent_t* eventDown = NULL);
+
+
+
+
-
+
-
+
-
-
-
-
- 787 void setADR(
bool enable =
true);
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 850 int16_t
getMacDeviceTimeAns(uint32_t* gpsEpoch, uint8_t* fraction,
bool returnUnix =
true);
-
-
+ 793 void setADR(
bool enable =
true);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 856 int16_t
getMacDeviceTimeAns(uint32_t* gpsEpoch, uint8_t* fraction,
bool returnUnix =
true);
-
+
-
+
- 870 #if !RADIOLIB_GODMODE
-
-
-
-
+
- 876 static int16_t checkBufferCommon(uint8_t *buffer, uint16_t size);
-
- 878 void activateCommon(uint8_t initialDr);
-
-
- 881 uint8_t bufferNonces[RADIOLIB_LORAWAN_NONCES_BUF_SIZE] = { 0 };
-
-
- 884 uint8_t bufferSession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE] = { 0 };
+ 876 #if !RADIOLIB_GODMODE
+
+
+
+
+
+ 882 static int16_t checkBufferCommon(uint8_t *buffer, uint16_t size);
+
+ 884 void activateCommon(uint8_t initialDr);
-
-
-
- 889 .commands = { { .cid = 0, .payload = { 0 }, .len = 0, .repeat = 0, } },
-
-
-
-
- 894 .commands = { { .cid = 0, .payload = { 0 }, .len = 0, .repeat = 0, } },
-
-
- 897 uint16_t lwMode = RADIOLIB_LORAWAN_MODE_NONE;
- 898 uint8_t lwClass = RADIOLIB_LORAWAN_CLASS_A;
- 899 bool isActive =
false;
-
- 901 uint64_t joinEUI = 0;
-
- 903 uint8_t nwkKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
- 904 uint8_t appKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
-
-
-
- 908 uint32_t devAddr = 0;
- 909 uint8_t appSKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
- 910 uint8_t fNwkSIntKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
- 911 uint8_t sNwkSIntKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
- 912 uint8_t nwkSEncKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
- 913 uint8_t jSIntKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
-
- 915 uint16_t keyCheckSum = 0;
-
-
- 918 uint16_t devNonce = 0;
- 919 uint32_t joinNonce = 0;
+
+ 887 uint8_t bufferNonces[RADIOLIB_LORAWAN_NONCES_BUF_SIZE] = { 0 };
+
+
+ 890 uint8_t bufferSession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE] = { 0 };
+
+
+
+
+ 895 .commands = { { .cid = 0, .payload = { 0 }, .len = 0, .repeat = 0, } },
+
+
+
+
+ 900 .commands = { { .cid = 0, .payload = { 0 }, .len = 0, .repeat = 0, } },
+
+
+ 903 uint16_t lwMode = RADIOLIB_LORAWAN_MODE_NONE;
+ 904 uint8_t lwClass = RADIOLIB_LORAWAN_CLASS_A;
+ 905 bool isActive =
false;
+
+ 907 uint64_t joinEUI = 0;
+
+ 909 uint8_t nwkKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
+ 910 uint8_t appKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
+
+
+
+ 914 uint32_t devAddr = 0;
+ 915 uint8_t appSKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
+ 916 uint8_t fNwkSIntKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
+ 917 uint8_t sNwkSIntKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
+ 918 uint8_t nwkSEncKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
+ 919 uint8_t jSIntKey[RADIOLIB_AES128_KEY_SIZE] = { 0 };
-
- 922 uint32_t homeNetId = 0;
- 923 uint8_t adrLimitExp = RADIOLIB_LORAWAN_ADR_ACK_LIMIT_EXP;
- 924 uint8_t adrDelayExp = RADIOLIB_LORAWAN_ADR_ACK_DELAY_EXP;
-
- 926 uint8_t txPowerSteps = 0;
- 927 uint8_t txPowerMax = 0;
-
- 929 uint32_t aFCntDown = 0;
- 930 uint32_t nFCntDown = 0;
- 931 uint32_t confFCntUp = RADIOLIB_LORAWAN_FCNT_NONE;
- 932 uint32_t confFCntDown = RADIOLIB_LORAWAN_FCNT_NONE;
- 933 uint32_t adrFCnt = 0;
-
-
- 936 uint8_t modulation = RADIOLIB_LORAWAN_MODULATION_LORA;
-
-
- 939 bool adrEnabled =
true;
+ 921 uint16_t keyCheckSum = 0;
+
+
+ 924 uint16_t devNonce = 0;
+ 925 uint32_t joinNonce = 0;
+
+
+ 928 uint32_t homeNetId = 0;
+ 929 uint8_t adrLimitExp = RADIOLIB_LORAWAN_ADR_ACK_LIMIT_EXP;
+ 930 uint8_t adrDelayExp = RADIOLIB_LORAWAN_ADR_ACK_DELAY_EXP;
+
+ 932 uint8_t txPowerSteps = 0;
+ 933 uint8_t txPowerMax = 0;
+
+ 935 uint32_t aFCntDown = 0;
+ 936 uint32_t nFCntDown = 0;
+ 937 uint32_t confFCntUp = RADIOLIB_LORAWAN_FCNT_NONE;
+ 938 uint32_t confFCntDown = RADIOLIB_LORAWAN_FCNT_NONE;
+ 939 uint32_t adrFCnt = 0;
-
- 942 bool dutyCycleEnabled =
false;
- 943 uint32_t dutyCycle = 0;
-
-
- 946 bool dwellTimeEnabledUp =
false;
- 947 uint16_t dwellTimeUp = 0;
- 948 bool dwellTimeEnabledDn =
false;
- 949 uint16_t dwellTimeDn = 0;
-
-
-
-
-
-
-
-
-
-
-
-
-
- 963 LoRaWANChannel_t availableChannels[2][RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS];
-
-
- 966 LoRaWANChannel_t currentChannels[2] = { RADIOLIB_LORAWAN_CHANNEL_NONE, RADIOLIB_LORAWAN_CHANNEL_NONE };
+
+ 942 uint8_t modulation = RADIOLIB_LORAWAN_MODULATION_LORA;
+
+
+ 945 bool adrEnabled =
true;
+
+
+ 948 bool dutyCycleEnabled =
false;
+ 949 uint32_t dutyCycle = 0;
+
+
+ 952 bool dwellTimeEnabledUp =
false;
+ 953 uint16_t dwellTimeUp = 0;
+ 954 bool dwellTimeEnabledDn =
false;
+ 955 uint16_t dwellTimeDn = 0;
+
+
+
+
+
+
+
+
+
+
+
-
- 969 uint8_t dataRates[2] = { RADIOLIB_LORAWAN_DATA_RATE_UNUSED, RADIOLIB_LORAWAN_DATA_RATE_UNUSED };
+
+ 969 LoRaWANChannel_t availableChannels[2][RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS];
-
-
+
+ 972 LoRaWANChannel_t currentChannels[2] = { RADIOLIB_LORAWAN_CHANNEL_NONE, RADIOLIB_LORAWAN_CHANNEL_NONE };
-
- 975 uint8_t rx1DrOffset = 0;
+
+ 975 uint8_t dataRates[2] = { RADIOLIB_LORAWAN_DATA_RATE_UNUSED, RADIOLIB_LORAWAN_DATA_RATE_UNUSED };
-
-
+
+
-
-
+
+ 981 uint8_t rx1DrOffset = 0;
-
-
+
+
-
-
+
+
-
- 990 RadioLibTime_t rxDelays[2] = { RADIOLIB_LORAWAN_RECEIVE_DELAY_1_MS, RADIOLIB_LORAWAN_RECEIVE_DELAY_2_MS };
+
+
-
- 993 uint8_t battLevel = 0xFF;
+
+
-
- 996 bool isMACPayload =
false;
+
+ 996 RadioLibTime_t rxDelays[2] = { RADIOLIB_LORAWAN_RECEIVE_DELAY_1_MS, RADIOLIB_LORAWAN_RECEIVE_DELAY_2_MS };
-
-
+
+ 999 uint8_t battLevel = 0xFF;
-
-
+
+ 1002 bool isMACPayload =
false;
-
- 1005 int16_t downlinkCommon();
+
+ 1005 uint8_t subBand = 0;
-
- 1008 uint32_t generateMIC(uint8_t* msg,
size_t len, uint8_t* key);
+
+
-
-
- 1012 bool verifyMIC(uint8_t* msg,
size_t len, uint8_t* key);
-
-
-
- 1016 int16_t setPhyProperties(uint8_t dir);
-
-
-
-
- 1021 int16_t setupChannelsDyn(
bool joinRequest =
false);
-
-
-
- 1025 int16_t setupChannelsFix(uint8_t subBand);
-
-
- 1028 int16_t processCFList(uint8_t* cfList);
-
-
- 1031 int16_t selectChannels();
+
+ 1011 int16_t downlinkCommon();
+
+
+ 1014 uint32_t generateMIC(uint8_t* msg,
size_t len, uint8_t* key);
+
+
+
+ 1018 bool verifyMIC(uint8_t* msg,
size_t len, uint8_t* key);
+
+
+
+ 1022 int16_t setPhyProperties(uint8_t dir);
+
+
+
+
+ 1027 int16_t setupChannelsDyn(
bool joinRequest =
false);
+
+
+
+ 1031 int16_t setupChannelsFix(uint8_t subBand);
-
- 1034 int16_t findDataRate(uint8_t dr,
DataRate_t* dataRate);
+
+ 1034 int16_t processCFList(uint8_t* cfList);
-
- 1037 int16_t restoreChannels();
+
+ 1037 int16_t selectChannels();
-
-
+
+ 1040 int16_t findDataRate(uint8_t dr,
DataRate_t* dataRate);
-
-
-
-
-
-
-
-
- 1050 bool applyChannelMaskDyn(uint8_t chMaskCntl, uint16_t chMask);
+
+ 1043 int16_t restoreChannels();
+
+
+
+
+
+
+
-
- 1053 bool applyChannelMaskFix(uint8_t chMaskCntl, uint16_t chMask);
+
+
-
- 1056 uint8_t getMacPayloadLength(uint8_t cid);
-
- 1064 void setCSMA(uint8_t backoffMax, uint8_t difsSlots,
bool enableCSMA =
false);
-
-
-
-
-
-
+
+ 1056 bool applyChannelMaskDyn(uint8_t chMaskCntl, uint16_t chMask);
+
+
+ 1059 bool applyChannelMaskFix(uint8_t chMaskCntl, uint16_t chMask);
+
+
+ 1062 uint8_t getMacPayloadLength(uint8_t cid);
+
+ 1070 void setCSMA(uint8_t backoffMax, uint8_t difsSlots,
bool enableCSMA =
false);
-
- 1073 void processAES(
const uint8_t* in,
size_t len, uint8_t* key, uint8_t* out, uint32_t fCnt, uint8_t dir, uint8_t ctrId,
bool counter);
+
+
-
- 1076 static uint16_t checkSum16(uint8_t *key, uint16_t keyLen);
+
+
-
- 1079 template<
typename T>
- 1080 static T ntoh(uint8_t* buff,
size_t size = 0);
-
-
- 1083 template<
typename T>
- 1084 static void hton(uint8_t* buff, T val,
size_t size = 0);
-
-
-
-LoRaWAN-compatible node (class A device).
Definition: LoRaWAN.h:520
+
+ 1079 void processAES(
const uint8_t* in,
size_t len, uint8_t* key, uint8_t* out, uint32_t fCnt, uint8_t dir, uint8_t ctrId,
bool counter);
+
+
+ 1082 static uint16_t checkSum16(uint8_t *key, uint16_t keyLen);
+
+
+ 1085 template<
typename T>
+ 1086 static T ntoh(uint8_t* buff,
size_t size = 0);
+
+
+ 1089 template<
typename T>
+ 1090 static void hton(uint8_t* buff, T val,
size_t size = 0);
+
+
+
+LoRaWAN-compatible node (class A device).
Definition: LoRaWAN.h:526
void clearSession()
Clear an active session, so that the device will have to rejoin the network.
Definition: LoRaWAN.cpp:59
int16_t setBufferNonces(uint8_t *persistentBuffer)
Fill the internal buffer that holds the LW base parameters with a supplied buffer.
Definition: LoRaWAN.cpp:75
int16_t setDatarate(uint8_t drUp)
Set uplink datarate. This should not be used when ADR is enabled.
Definition: LoRaWAN.cpp:1999
@@ -831,7 +837,7 @@ $(document).ready(function(){initNavTree('_lo_ra_w_a_n_8h_source.html',''); init
uint32_t getAFCntDown()
Returns the last application downlink's frame counter; also 0 if no application downlink occured yet.
Definition: LoRaWAN.cpp:1696
RadioLibTime_t getLastToA()
Get the Time-on-air of the last uplink message.
Definition: LoRaWAN.cpp:2918
int16_t activateABP(uint8_t initialDr=RADIOLIB_LORAWAN_DATA_RATE_UNUSED)
Join network by restoring ABP session or performing over-the-air activation. In this procedure,...
Definition: LoRaWAN.cpp:791
-bool TS009
TS009 Protocol Specification Verification switch (allows FPort 224 and cuts off uplink payload instea...
Definition: LoRaWAN.h:868
+bool TS009
TS009 Protocol Specification Verification switch (allows FPort 224 and cuts off uplink payload instea...
Definition: LoRaWAN.h:874
uint8_t * getBufferNonces()
Returns the pointer to the internal buffer that holds the LW base parameters.
Definition: LoRaWAN.cpp:67
int16_t sendReceive(const char *strUp, uint8_t fPort, uint8_t *dataDown, size_t *lenDown, bool isConfirmed=false, LoRaWANEvent_t *eventUp=NULL, LoRaWANEvent_t *eventDown=NULL)
Send a message to the server and wait for a downlink during Rx1 and/or Rx2 window.
Definition: LoRaWAN.cpp:1660
uint8_t * getBufferSession()
Returns the pointer to the internal buffer that holds the LW session parameters.
Definition: LoRaWAN.cpp:111
@@ -884,19 +890,19 @@ $(document).ready(function(){initNavTree('_lo_ra_w_a_n_8h_source.html',''); init
uint8_t drMax
Maximum allowed datarate for all channels in this span (inclusive)
Definition: LoRaWAN.h:373
float freqStep
Frequency step between adjacent channels.
Definition: LoRaWAN.h:367
uint8_t drMin
Minimum allowed datarate for all channels in this span.
Definition: LoRaWAN.h:370
-Structure to save extra information about uplink/downlink event.
Definition: LoRaWAN.h:489
-float freq
Frequency in MHz.
Definition: LoRaWAN.h:504
-bool confirmed
Whether the event is confirmed or not (e.g., confirmed uplink sent by user application)
Definition: LoRaWAN.h:494
-uint8_t fPort
Port number.
Definition: LoRaWAN.h:513
-int16_t power
Transmit power in dBm for uplink, or RSSI for downlink.
Definition: LoRaWAN.h:507
-bool confirming
Whether the event is confirming a previous request (e.g., server downlink reply to confirmed uplink s...
Definition: LoRaWAN.h:498
-uint8_t datarate
Datarate.
Definition: LoRaWAN.h:501
-uint8_t dir
Event direction, one of RADIOLIB_LORAWAN_CHANNEL_DIR_*.
Definition: LoRaWAN.h:491
-uint32_t fCnt
The appropriate frame counter - for different events, different frame counters will be reported!
Definition: LoRaWAN.h:510
-Structure to save extra information about activation event.
Definition: LoRaWAN.h:474
-bool newSession
Whether a new session was started.
Definition: LoRaWAN.h:476
-uint32_t joinNonce
The received Join-Request JoinNonce value.
Definition: LoRaWAN.h:482
-uint16_t devNonce
The transmitted Join-Request DevNonce value.
Definition: LoRaWAN.h:479
+Structure to save extra information about uplink/downlink event.
Definition: LoRaWAN.h:495
+float freq
Frequency in MHz.
Definition: LoRaWAN.h:510
+bool confirmed
Whether the event is confirmed or not (e.g., confirmed uplink sent by user application)
Definition: LoRaWAN.h:500
+uint8_t fPort
Port number.
Definition: LoRaWAN.h:519
+int16_t power
Transmit power in dBm for uplink, or RSSI for downlink.
Definition: LoRaWAN.h:513
+bool confirming
Whether the event is confirming a previous request (e.g., server downlink reply to confirmed uplink s...
Definition: LoRaWAN.h:504
+uint8_t datarate
Datarate.
Definition: LoRaWAN.h:507
+uint8_t dir
Event direction, one of RADIOLIB_LORAWAN_CHANNEL_DIR_*.
Definition: LoRaWAN.h:497
+uint32_t fCnt
The appropriate frame counter - for different events, different frame counters will be reported!
Definition: LoRaWAN.h:516
+Structure to save extra information about activation event.
Definition: LoRaWAN.h:480
+bool newSession
Whether a new session was started.
Definition: LoRaWAN.h:482
+uint32_t joinNonce
The received Join-Request JoinNonce value.
Definition: LoRaWAN.h:488
+uint16_t devNonce
The transmitted Join-Request DevNonce value.
Definition: LoRaWAN.h:485
Structure to save information about MAC command.
Definition: LoRaWAN.h:248
uint8_t payload[RADIOLIB_LORAWAN_MAX_MAC_COMMAND_LEN_DOWN]
Payload buffer (5 bytes is the longest possible)
Definition: LoRaWAN.h:253
uint8_t len
Length of the payload.
Definition: LoRaWAN.h:256
diff --git a/_physical_layer_8h_source.html b/_physical_layer_8h_source.html
index 8d7ec85b..05463a6d 100644
--- a/_physical_layer_8h_source.html
+++ b/_physical_layer_8h_source.html
@@ -306,7 +306,7 @@ $(document).ready(function(){initNavTree('_physical_layer_8h_source.html',''); i
Client for Bell modem communication. The public interface is the same as Arduino Serial.
Definition: BellModem.h:57
Client for FSK-4 communication. The public interface is the same as Arduino Serial.
Definition: FSK4.h:15
Client for Hellschreiber transmissions.
Definition: Hellschreiber.h:90
-LoRaWAN-compatible node (class A device).
Definition: LoRaWAN.h:520
+LoRaWAN-compatible node (class A device).
Definition: LoRaWAN.h:526
Implements all common low-level methods to control the wireless module. Every module class contains o...
Definition: Module.h:65
Client for Morse Code communication. The public interface is the same as Arduino Serial.
Definition: Morse.h:93