> For the complete documentation index, see [llms.txt](https://docs.medcrypt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.medcrypt.com/ko/guardian/understand-device-provisioning/begin-device-provisioning/device-provisioning-code-examples.md).

# 디바이스 프로비저닝 코드 예제

## 연결이 끊긴 환경에서의 프로비저닝 예제

Guardian은 연결이 끊긴 환경에서의 프로비저닝을 위해 C#, C++, C를 지원합니다.

### C# 예제

```csharp
public static void DisconnectedProvisioning()
{
    medcrypt.guardian.ProvisionFilesInput provisioningFilesInput =
        new medcrypt.guardian.ProvisionFilesInput();

    /* 프로비저닝 시스템에 대한 고객 데이터 */
    string componentHandle = "my_component_handle";
    string systemId = "my_system_name";
    string hardwareId = "my_serial_number";

    /* 입력 파일 저장소 버퍼에 프로비저닝 파일 로드 */
    provisioningFilesInput.trustStore =
        File.ReadAllBytes(@"TrustStore.mcts");
    provisioningFilesInput.privateIdentity =
        File.ReadAllBytes(@"PrivateIdentity.mcpip");
    provisioningFilesInput.certifiedProfile =
        File.ReadAllBytes(@"CertifiedProvisioningProfile.mcpp");

    /* Guardian 생성 */
    medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();

    /* 기본 옵션 생성 */
    medcrypt.guardian.ProvisioningGenerateOptions options =
            new medcrypt.guardian.ProvisioningGenerateOptions();

    /* 프로비저닝 요청 생성 호출 */
    medcrypt.guardian.ProvisionFilesOutput provisioningOutputFiles =
        gdn.GenerateProvisionRequest(
            provisioningFilesInput,
            options,
            componentHandle,
            systemId,
            hardwareId);

    /* 프로비저닝 요청 및 생성된 개인 ID 저장 */
    File.WriteAllBytes(
        @"GeneratedPrivateIdentity.mcpi",
        provisioningOutputFiles.generatedPrivateIdentity);
    File.WriteAllBytes(
        @"ProvisionRequest.mcpr",
        provisioningOutputFiles.provisionRequest);
}
```

### C++ 예제

```cpp
#include "medcrypt/guardian/GuardianSystem.h"
#include "medcrypt/guardian/Utilities/Files/FileHelpers.h"

#define MSG(x) { printf x; printf("\n"); }
#define MSG_INFO(x) { MSG(x); }
#define MSG_ERROR(x) { printf("ERROR: "); MSG(x); }
#define MSG_WARNING(x) { printf("WARNING: "); MSG(x); }
#define ARBITRARY_BUF_SIZE 2 * 1024

static const char kPrFilename[] = "ProvisionRequest.mcpr";
static const char kPiFilename[] = "PrivateIdentity.mcpi";

static bool WriteBufferToFile(
    const std::string& in_filepath,
    const char* in_file_contents,
    const size_t in_file_size);

bool DisconnectedProvisioning()
{
    medcrypt::guardian::utilities::ProvisionFiles files;
    std::string in_component_handle = "my_component_handle";
    std::string in_hardware_id = "my_serial_number";
    std::string in_provisioning_profile_folder =
        "/home/user/guardian/profiles/initial_profile";

    /* 프로비저닝 파일을 가져옵니다. 초기 프로비저닝의 경우 실제 프로비저닝 프로필 파일입니다. */
    if (!medcrypt::guardian::utilities::GetProvisionFilesFromPath(
            in_provisioning_profile_folder,
            true,
            &files)) {
        MSG_ERROR(("could not retrieve provisioning files"));
        return false;
    }

    /* 버퍼를 출력에 할당합니다. */
    char pr_buf[ARBITRARY_BUF_SIZE] = {0};
    char gpi_buf[ARBITRARY_BUF_SIZE] = {0};

    files.ProvisionRequest = pr_buf;
    files.ProvisionRequestSize = sizeof(pr_buf);
    files.GeneratedPrivateIdentity = gpi_buf;
    files.GeneratedPrivateIdentitySize = sizeof(gpi_buf);

    /* Guardian 생성 */
    medcrypt::guardian::Guardian guardian;
    medcrypt::guardian::Status status;

    /* 입력 옵션을 사용하거나 기본값을 생성하고, 하드웨어 ID를 시스템 이름에 연결한 후 실제로 프로비저닝 요청을 생성합니다. */
    status = guardian.GenerateProvisionRequest(
        files,
        medcrypt::guardian::ProvisioningGenerateOptions(),
        in_component_handle.c_str(),
        in_hardware_id.c_str(),
        in_hardware_id.c_str());

    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not generate provision request [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 프로비저닝 요청을 디스크에 씁니다. */
    if (!WriteBufferToFile(
            in_provisioning_profile_folder + kPrFilename,
            files.ProvisionRequest,
            files.ProvisionRequestSize))
    {
        MSG_ERROR(("could not write generated provision request"));
        return false;
    }

    /* 개인 ID를 디스크에 씁니다. */
    if (!WriteBufferToFile(
            in_provisioning_profile_folder + kPiFilename,
            files.GeneratedPrivateIdentity,
            files.GeneratedPrivateIdentitySize))
    {
        MSG_ERROR(("could not write generated private identity"));
        return false;
    }

    return true;
}

static bool
WriteBufferToFile(
    const std::string& in_filepath,
    const char* in_file_contents,
    const size_t in_file_size)
{
    bool return_value = false;

    std::ofstream output(in_filepath, std::ios::binary);
    if( output.good() &&
        in_file_size <= (std::numeric_limits<std::streamsize>::max)())
    {
        output.write(in_file_contents, static_cast<std::streamsize>(in_file_size));
        output.close();
        return_value = true;
    }

    return return_value;
}
```

### C 예제

C 인터페이스는 대용량 입력과 출력에 스트림을 사용합니다. 아래 예제에서는 버퍼를 기반으로 하는 이러한 스트림을 보여 줍니다. 출력 버퍼의 크기는 임의로 설정할 수 있습니다.

```c
#define MAX_GDN_SIZE 15 * 1024 /* 필요에 따라 늘리십시오. 이 메모리는 스택에 할당하지 않아도 됩니다. */
#define ARBITRARY_BUF_SIZE 5 * 1024 /* 필요에 따라 늘리십시오. */

static bool disconnected_provisioning()
{
    mcg_status status = 0;
    /* Guardian 메모리 영역을 생성합니다. 이 메모리는 어떤 출처에서 가져와도 되지만 연속된 블록이어야 합니다. */
    mcg_memory_t mcg_memory = {NULL, 0, 0};
    uint8_t memory_buffer[MAX_GDN_SIZE] = {0};

    /* 입력 및 출력 스트림과 함께 파일 포인터 저장 구조체를 초기화합니다. */
    mcg_provision_files_t prov_files = {0};
    mcg_provisioning_generate_options_t p_options = {0};
    mcg_guardian_istream_t ts, pi, cp;
    mcg_guardian_ostream_t pr = {0};
    mcg_guardian_ostream_t gpi = {0};

    /* 이 프로비저닝 시스템에 대한 고객 데이터 */
    char component_handle[] = "my_component";
    char system_name[] = "my_system_name";
    char hardware_id[] = "my_serial_number";

    mcg_memory.mem = &memory_buffer[0];
    mcg_memory.size = sizeof(memory_buffer);

    /* 신뢰 저장소를 이 버퍼에 읽어 들이고, in_ts_len을 실제 크기로 설정합니다. */
    uint8_t in_ts[ARBITRARY_BUF_SIZE] = {0};
    size_t in_ts_len = 1234;

    /* 개인 ID를 이 버퍼에 읽어 들이고, in_pi_len을 실제 크기로 설정합니다. */
    uint8_t in_pi[ARBITRARY_BUF_SIZE] = {0};
    size_t in_pi_len = 1234;

    /* 인증된 프로필을 이 버퍼에 읽어 들이고, in_cp_len을 실제 크기로 설정합니다. */
    uint8_t in_cp_prov[ARBITRARY_BUF_SIZE] = {0};
    size_t in_cp_prov_len = 1234;

    /* 프로비저닝 요청 및 생성된 개인 ID 출력을 위한 메모리를 할당합니다. */
    uint8_t io_pr[ARBITRARY_BUF_SIZE] = {0};
    size_t io_pr_len = sizeof(pr);
    uint8_t io_gpi[ARBITRARY_BUF_SIZE] = {0};
    size_t io_gpi_len = sizeof(gpi);

    /* 제공된 ts/pi/cp 바이트 버퍼에서 스트림을 생성합니다. */
    ts = mcg_istream_from_buffer(in_ts, in_ts_len);
    pi = mcg_istream_from_buffer(in_pi, in_pi_len);
    cp = mcg_istream_from_buffer(in_cp_prov, in_cp_prov_len);

    /* 프로비저닝 요청 및 생성된 개인 ID를 위한 출력 스트림을 생성합니다.
        identity */
    pr = mcg_ostream_from_buffer(io_pr, io_pr_len);
    gpi = mcg_ostream_from_buffer(io_gpi, io_gpi_len);

    /* 스트림을 mcg_provision_files_t에 로드 */
    prov_files.trust_store = &ts;
    prov_files.private_identity = &pi;
    prov_files.certified_profile = &cp;
    prov_files.provision_request = &pr;
    prov_files.generated_private_identity = &gpi;

    status = mcg_gdn_generate_provision_request(&mcg_memory,
            &prov_files,
            &p_options,
            component_handle,
            system_name,
            hardware_id);

    if (status != MCG_STATUS_OK) {
        return false;
    }

    io_pr_len = pr.bytes_written;
    io_gpi_len = gpi.bytes_written;

    /* PR (io_pr/io_pr_len) 및 GPI (io_gpi/io_gpi_len)를 저장소에 저장 */

    return true;
}
```

## 연결된 장치 프로비저닝 예제

Guardian은 연결된 프로비저닝에 C# 및 C++를 지원합니다.

### **C# 예제**

```csharp
public static void ConnectedProvisioning()
{
    public static void ConnectedProvisioning()
{
    medcrypt.guardian.ProvisionFilesInput provisioningFilesInput =
            new medcrypt.guardian.ProvisionFilesInput();
        medcrypt.guardian.ProvisionFilesOutput provisioningOutputFiles =
            new medcrypt.guardian.ProvisionFilesOutput();
    // DisconnectedProvisioning()에서와 같이 오프라인 프로비저닝을 완료합니다.
    // provisioningFilesInput 및 provisioningOutputFiles의 데이터는
    // DisconnectedProvisioning() 함수에서 가져와야 합니다.
    //
    // 가독성을 위해 이 함수에 정적 텍스트를 다시 표시합니다.
    string componentHandle = "my_component_handle";
    string hardwareId = "my_serial_number";

    /* 프로비저닝 프로필 파일을 초기화 파일 저장소에 복사 */
    medcrypt.guardian.InitializeFiles initializeFiles =
        new medcrypt.guardian.InitializeFiles();
    initializeFiles.trustStore = provisioningFilesInput.trustStore;
    initializeFiles.privateIdentity = provisioningFilesInput.privateIdentity;
    initializeFiles.certifiedProfile = provisioningFilesInput.certifiedProfile;

    /* 구성된 작업(백엔드 연결)을 위해 Guardian 초기화 */
    medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();

    gdn.Initialize(
        initializeFiles,
        componentHandle,
        hardwareId,
        new medcrypt.guardian.InitializeOptions());

    /* 기본 옵션 생성 */
    medcrypt.guardian.ProvisioningOnlineOptions options =
            new medcrypt.guardian.ProvisioningOnlineOptions();

    /* 프로비저닝 요청을 온라인 파일 구조체에 로드 */
    medcrypt.guardian.ProvisioningFilesOnline onlineFiles =
        new medcrypt.guardian.ProvisioningFilesOnline();
    onlineFiles.provisionRequest =
        provisioningOutputFiles.provisionRequest;

    /* 연결된 프로비저닝 상태 머신 시작 */
    gdn.StartProvisioningOnline(onlineFiles, options);
    gdn.Run();

    /* 프로비저닝 완료, 오류 또는 시간 초과가 발생할 때까지 대기 */
    DateTime start = DateTime.Now;
    TimeSpan timeout = TimeSpan.FromMinutes(2);
    while (gdn.IsProvisioningRunning() &&
            System.DateTime.Now - start < timeout)
    {
        gdn.Run();
        System.Threading.Thread.Sleep(500);
    }

    /* 프로비저닝된 프로필을 저장합니다 */
    File.WriteAllBytes(
        @"CertifiedProfile.mcp",
        gdn.GetProvisionedProfile());
}
}
```

### **C++ 예제**

```cpp
#define ARBITRARY_BUF_SIZE 10 * 1024

static const char kCpFilename[] = "CertifiedProfile.mcp";
bool ConnectedProvisioning()
{

    가독성을 위해 이 함수에서 정적 텍스트를 다시 표시합니다. */
    // DisconnectedProvisioning()에서와 같이 오프라인 프로비저닝을 완료합니다.
    // DisconnectedProvisioning()의 "files" 객체에 있는 데이터는 복사해야 합니다 
    // 이 함수의 "in_files"로 복사합니다.
    //
    // 가독성을 위해 이 함수에 정적 텍스트를 다시 표시합니다.
    medcrypt::guardian::utilities::ProvisionFiles in_files;
    std::string in_component_handle = "my_component_handle";
    std::string in_hardware_id = "my_serial_number";
    std::string in_provisioning_profile_folder = "/home/user/guardian/profiles/initial_profile";

     /* Guardian 생성 */
    medcrypt::guardian::Guardian guardian;
    medcrypt::guardian::Status status;

    /* 제공된 프로비저닝 프로필로 Guardian을 초기화하여 medcrypt 백엔드 인프라에 연결할 수 있도록 합니다 */
    medcrypt::guardian::utilities::InitializeFiles init_files;
    init_files.TrustStore           = in_files.TrustStore;
    init_files.TrustStoreSize       = in_files.TrustStoreSize;
    init_files.PrivateIdentity      = in_files.PrivateIdentity;
    init_files.PrivateIdentitySize  = in_files.PrivateIdentitySize;
    init_files.CertifiedProfile     = in_files.CertifiedProfile;
    init_files.CertifiedProfileSize = in_files.CertifiedProfileSize;

    /* 제공된 Guardian 초기화 */
    status = guardian.Initialize(
        init_files,
        in_component_handle.c_str(),
        in_hardware_id.c_str(),
        medcrypt::guardian::InitializeOptions());

    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("guardian을 초기화할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 생성된 프로비저닝 요청을 제공하여 내부 온라인 프로비저닝 상태 머신을 시작합니다 */
    medcrypt::guardian::utilities::ProvisionOnlineFiles online_files;
    online_files.ProvisionRequest       = in_files.ProvisionRequest;
    online_files.ProvisionRequestSize   = in_files.ProvisionRequestSize;

    status = guardian.StartProvisioningOnline(
        online_files,
        medcrypt::guardian::ProvisioningOptions());  
    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("온라인 프로비저닝을 시작할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 내부 상태 머신 실행 */
    status = guardian.Run();
    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("guardian을 실행할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 프로비저닝이 완료되거나 오류가 발생하거나 시간 초과될 때까지 대기합니다 */
    auto start = std::chrono::steady_clock::now();
    auto timeout = std::chrono::minutes(2);
    while (guardian.IsProvisioningRunning() &&
                ((std::chrono::steady_clock::now() - start) < timeout)) {
            guardian.Run();
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }

    /* 수신한 프로비저닝된 프로필을 가져옵니다 */
    char profile[ARBITRARY_BUF_SIZE] = {0};
    size_t profile_size = sizeof(profile);
    status = guardian.GetProvisionedProfile(
            profile,
            &profile_size);
    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("온라인 프로비저닝을 완료할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 프로비저닝된 프로필을 디스크에 기록 */
    if (!WriteBufferToFile(
            in_provisioning_profile_folder + kCpFilename,
            profile,
            profile_size))
    {
        MSG_ERROR(("프로비저닝된 프로필을 기록할 수 없습니다"));
        return false;
    }

    return true;
}
```

## 프록시 장치 프로비저닝 예제

Guardian은 프록시 프로비저닝에 C# 및 C++를 지원합니다. Guardian은 연결 프로비저닝을 지원하지 않으므로 프로비저닝 요청을 프록시할 수 없습니다.

### **C# 예제**

```csharp
public static void ConnectedProvisioning()
{
    public static void ConnectedProvisioning()
{
    medcrypt.guardian.ProvisionFilesInput provisioningFilesInput =
            new medcrypt.guardian.ProvisionFilesInput();
        medcrypt.guardian.ProvisionFilesOutput provisioningOutputFiles =
            new medcrypt.guardian.ProvisionFilesOutput();
    // DisconnectedProvisioning()에서와 같이 오프라인 프로비저닝을 완료합니다.
    // provisioningFilesInput 및 provisioningOutputFiles의 데이터는
    // DisconnectedProvisioning() 함수에서 가져와야 합니다.
    //
    // 가독성을 위해 이 함수에 정적 텍스트를 다시 표시합니다.
    string componentHandle = "my_component_handle";
    string hardwareId = "my_serial_number";

    /* 프로비저닝 프로필 파일을 초기화 파일 저장소에 복사 */
    medcrypt.guardian.InitializeFiles initializeFiles =
        new medcrypt.guardian.InitializeFiles();
    initializeFiles.trustStore = provisioningFilesInput.trustStore;
    initializeFiles.privateIdentity = provisioningFilesInput.privateIdentity;
    initializeFiles.certifiedProfile = provisioningFilesInput.certifiedProfile;

    /* 구성된 작업을 위해 Guardian 초기화(백엔드에 연결) */
    medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();

    gdn.Initialize(
        initializeFiles,
        componentHandle,
        hardwareId,
        new medcrypt.guardian.InitializeOptions());

    /* 기본 옵션 생성 */
    medcrypt.guardian.ProvisioningOnlineOptions options =
            new medcrypt.guardian.ProvisioningOnlineOptions();

    /* 프로비저닝 요청을 온라인 파일 구조에 로드 */
    medcrypt.guardian.ProvisioningFilesOnline onlineFiles =
        new medcrypt.guardian.ProvisioningFilesOnline();
    onlineFiles.provisionRequest =
        File.ReadAllBytes(@"ProxiedProvisionRequest.mcpr");

    /* 연결 프로비저닝 상태 머신 시작 */
    gdn.StartProvisioningOnline(onlineFiles, options);
    gdn.Run();

    /* 프로비저닝이 완료되거나 오류가 발생하거나 시간 초과될 때까지 대기합니다 */
    DateTime start = DateTime.Now;
    TimeSpan timeout = TimeSpan.FromMinutes(2);
    while (gdn.IsProvisioningRunning() &&
            System.DateTime.Now - start < timeout)
    {
        gdn.Run();
        System.Threading.Thread.Sleep(500);
    }

    /* 프로비저닝된 프로필 저장 */
    File.WriteAllBytes(
        @"CertifiedProfile.mcp",
        gdn.GetProvisionedProfile());
}
}
```

### **C++ 예제**

```cpp
#define ARBITRARY_BUF_SIZE 10 * 1024

static const char kCpFilename[] = "CertifiedProfile.mcp";
bool ConnectedProvisioning()
{
    /* DisconnectedProvisioning()에서와 같이 연결 해제 프로비저닝을 완료합니다. DisconnectedProvisioning()의 "files" 객체에 있는 데이터를 이 함수의 "in_files"에 복사해야 합니다.
    가독성을 위해 이 함수에서 정적 텍스트를 다시 표시합니다. */
    medcrypt::guardian::utilities::ProvisionFiles in_files;
    std::string in_component_handle = "my_component_handle";
    std::string in_hardware_id = "my_serial_number";
    std::string in_provisioning_profile_folder = "/home/user/guardian/profiles/initial_profile";

     /* Guardian 생성 */
    medcrypt::guardian::Guardian guardian;
    medcrypt::guardian::Status status;

    /* 제공된 프로비저닝 프로필로 Guardian을 초기화하여 medcrypt 백엔드 인프라에 연결할 수 있도록 합니다 */
    medcrypt::guardian::utilities::InitializeFiles init_files;
    init_files.TrustStore           = in_files.TrustStore;
    init_files.TrustStoreSize       = in_files.TrustStoreSize;
    init_files.PrivateIdentity      = in_files.PrivateIdentity;
    init_files.PrivateIdentitySize  = in_files.PrivateIdentitySize;
    init_files.CertifiedProfile     = in_files.CertifiedProfile;
    init_files.CertifiedProfileSize = in_files.CertifiedProfileSize;

    /* 제공된 Guardian 초기화 */
    status = guardian.Initialize(
        init_files,
        in_component_handle.c_str(),
        in_hardware_id.c_str(),
        medcrypt::guardian::InitializeOptions());

    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("guardian을 초기화할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 생성된 프로비저닝 요청을 제공하여 내부 온라인 프로비저닝 상태 머신을 시작합니다 */
    medcrypt::guardian::utilities::ProvisionOnlineFiles online_files;
    online_files.ProvisionRequest       = in_files.ProvisionRequest;
    online_files.ProvisionRequestSize   = in_files.ProvisionRequestSize;

    /* 프록시 프로비저닝 요청을 버퍼와 크기로 로드 */
    char pr_buf[2048] = {0};
    size_t pr_buf_size = sizeof(buf);

    /* 생성된 연결 해제 프로비저닝 요청을 제공하여 내부 온라인 프로비저닝 상태 머신을
    시작합니다 */
    medcrypt::guardian::utilities::ProvisionOnlineFiles online_files;
    online_files.ProvisionRequest       = pr_buf;
    online_files.ProvisionRequestSize   = pr_buf_size;

    status = guardian.StartProvisioningOnline(
        online_files,
        medcrypt::guardian::ProvisioningOptions());  
    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("온라인 프로비저닝을 시작할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 내부 상태 머신 실행 */
    status = guardian.Run();
    /* non_OK 오류 코드 확인 및 출력 */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("guardian을 실행할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 프로비저닝이 완료되거나 오류가 발생하거나 시간 초과될 때까지 대기합니다 */
    auto start = std::chrono::steady_clock::now();
    auto timeout = std::chrono::minutes(2);
    while (guardian.IsProvisioningRunning() &&
                ((std::chrono::steady_clock::now() - start) < timeout)) {
            guardian.Run();
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }

    /* 수신한 프로비저닝된 프로필 가져오기*/
    char profile[ARBITRARY_BUF_SIZE] = {0};
    size_t profile_size = sizeof(profile);
    status = guardian.GetProvisionedProfile(
            profile,
            &profile_size);
    /* OK가 아닌 오류 코드를 확인하고 출력합니다. */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("온라인 프로비저닝을 완료할 수 없습니다 [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* 프로비저닝된 프로필을 디스크에 기록 */
    if (!WriteBufferToFile(
            in_provisioning_profile_folder + kCpFilename,
            profile,
            profile_size))
    {
        MSG_ERROR(("프로비저닝된 프로필을 기록할 수 없습니다"));
        return false;
    }

    return true;
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.medcrypt.com/ko/guardian/understand-device-provisioning/begin-device-provisioning/device-provisioning-code-examples.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
