#ifndef JOINER_HPP_
#define JOINER_HPP_
#include "openthread-core-config.h"
#include <openthread/joiner.h>
#include "coap/coap.hpp"
#include "coap/coap_message.hpp"
#include "coap/coap_secure.hpp"
#include "common/locator.hpp"
#include "common/logging.hpp"
#include "common/message.hpp"
#include "mac/mac_types.hpp"
#include "meshcop/dtls.hpp"
#include "meshcop/meshcop_tlvs.hpp"
namespace ot {
namespace MeshCoP {
class Joiner : public InstanceLocator
{
public:
explicit Joiner(Instance &aInstance);
otError Start(const char * aPskd,
const char * aProvisioningUrl,
const char * aVendorName,
const char * aVendorModel,
const char * aVendorSwVersion,
const char * aVendorData,
otJoinerCallback aCallback,
void * aContext);
void Stop(void);
otJoinerState GetState(void) const { return mState; }
void GetJoinerId(Mac::ExtAddress &aJoinerId) const;
static bool IsPskdValid(const char *aPskd);
private:
enum
{
kJoinerUdpPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT,
kConfigExtAddressDelay = 100, kReponseTimeout = 4000, kPskdMinLength = 6, kPskdMaxLength = 32, };
struct JoinerRouter
{
Mac::ExtAddress mExtAddr;
Mac::PanId mPanId;
uint16_t mJoinerUdpPort;
uint8_t mChannel;
uint8_t mPriority;
};
static void HandleDiscoverResult(otActiveScanResult *aResult, void *aContext);
void HandleDiscoverResult(otActiveScanResult *aResult);
static void HandleSecureCoapClientConnect(bool aConnected, void *aContext);
void HandleSecureCoapClientConnect(bool aConnected);
static void HandleJoinerFinalizeResponse(void * aContext,
otMessage * aMessage,
const otMessageInfo *aMessageInfo,
otError aResult);
void HandleJoinerFinalizeResponse(Coap::Message &aMessage, const Ip6::MessageInfo *aMessageInfo, otError aResult);
static void HandleJoinerEntrust(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
static const char *JoinerStateToString(otJoinerState aState);
void SetState(otJoinerState aState);
void SaveDiscoveredJoinerRouter(const otActiveScanResult &aResult);
void TryNextJoinerRouter(otError aPrevError);
otError Connect(JoinerRouter &aRouter);
void Finish(otError aError);
uint8_t CalculatePriority(int8_t aRssi, bool aSteeringDataAllowsAny);
otError PrepareJoinerFinalizeMessage(const char *aProvisioningUrl,
const char *aVendorName,
const char *aVendorModel,
const char *aVendorSwVersion,
const char *aVendorData);
void FreeJoinerFinalizeMessage(void);
void SendJoinerFinalize(void);
void SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aRequestInfo);
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
void LogCertMessage(const char *aText, const Coap::Message &aMessage) const;
#endif
otJoinerState mState;
otJoinerCallback mCallback;
void * mContext;
JoinerRouter mJoinerRouters[OPENTHREAD_CONFIG_JOINER_MAX_CANDIDATES];
uint16_t mJoinerRouterIndex;
Coap::Message *mFinalizeMessage;
TimerMilli mTimer;
Coap::Resource mJoinerEntrust;
};
} }
#endif