> 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/manage-devices/begin-device-provisioning/device-provisioning-code-examples.md).

# Device provisioning code examples

## Disconnected provisioning examples

Guardian supports C#, C++, and C for disconnected provisioning.

### C# example

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

    /* Customer data about the provisioning system */
    string componentHandle = "my_component_handle";
    string systemId = "my_system_name";
    string hardwareId = "my_serial_number";

    /* Load provisioning files to input file storage buffers */
    provisioningFilesInput.trustStore =
        File.ReadAllBytes(@"TrustStore.mcts");
    provisioningFilesInput.privateIdentity =
        File.ReadAllBytes(@"PrivateIdentity.mcpip");
    provisioningFilesInput.certifiedProfile =
        File.ReadAllBytes(@"CertifiedProvisioningProfile.mcpp");

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

    /* Create default options */
    medcrypt.guardian.ProvisioningGenerateOptions options =
            new medcrypt.guardian.ProvisioningGenerateOptions();

    /* Call generate provision request */
    medcrypt.guardian.ProvisionFilesOutput provisioningOutputFiles =
        gdn.GenerateProvisionRequest(
            provisioningFilesInput,
            options,
            componentHandle,
            systemId,
            hardwareId);

    /* Persist provision request and generated private identity */
    File.WriteAllBytes(
        @"GeneratedPrivateIdentity.mcpi",
        provisioningOutputFiles.generatedPrivateIdentity);
    File.WriteAllBytes(
        @"ProvisionRequest.mcpr",
        provisioningOutputFiles.provisionRequest);
}
```

### C++ example

```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";

    /* Retrieve provisioning files, for an initial provision these are the actual provisioning profile files */
    if (!medcrypt::guardian::utilities::GetProvisionFilesFromPath(
            in_provisioning_profile_folder,
            true,
            &files)) {
        MSG_ERROR(("could not retrieve provisioning files"));
        return false;
    }

    /* Assign buffers to outputs */
    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);

    /* Create Guardian */
    medcrypt::guardian::Guardian guardian;
    medcrypt::guardian::Status status;

    /* Accept input options, or create default, alias hardware id to system name, actually generate the provision request */
    status = guardian.GenerateProvisionRequest(
        files,
        medcrypt::guardian::ProvisioningGenerateOptions(),
        in_component_handle.c_str(),
        in_hardware_id.c_str(),
        in_hardware_id.c_str());

    /* Check and print non-OK error code */
    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;
    }

    /* Write the provision request to disk */
    if (!WriteBufferToFile(
            in_provisioning_profile_folder + kPrFilename,
            files.ProvisionRequest,
            files.ProvisionRequestSize))
    {
        MSG_ERROR(("could not write generated provision request"));
        return false;
    }

    /* Write the private identity to disk */
    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 example

The C interface uses streams for all large inputs and outputs. The example below will show these streams backed by buffers. Output buffers will be arbitrarily sized.

```c
#define MAX_GDN_SIZE 15 * 1024 /* Increase as necessary, this memory does not have to be on the stack */
#define ARBITRARY_BUF_SIZE 5 * 1024 /* Increase as necessary */

static bool disconnected_provisioning()
{
    mcg_status status = 0;
    /* Create Guardian memory region, this memory can come from any source but must be a continuous block */
    mcg_memory_t mcg_memory = {NULL, 0, 0};
    uint8_t memory_buffer[MAX_GDN_SIZE] = {0};

    /* Initialize file pointer storage structs along with input and output streams */
    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};

    /* Customer data about this provisioning system */
    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);

    /* Read trust store into this buffer, and set in_ts_len to actual size */
    uint8_t in_ts[ARBITRARY_BUF_SIZE] = {0};
    size_t in_ts_len = 1234;

    /* Read private identity into this buffer, and set in_pi_len to actual size */
    uint8_t in_pi[ARBITRARY_BUF_SIZE] = {0};
    size_t in_pi_len = 1234;

    /* Read certified profile into this buffer, and set in_cp_len to actual size */
    uint8_t in_cp_prov[ARBITRARY_BUF_SIZE] = {0};
    size_t in_cp_prov_len = 1234;

    /* Allocate memory for provision request and generated private identity output */
    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);

    /* Create streams from provided ts/pi/cp byte buffers */
    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);

    /* Create output streams for provision request and generated private
        identity */
    pr = mcg_ostream_from_buffer(io_pr, io_pr_len);
    gpi = mcg_ostream_from_buffer(io_gpi, io_gpi_len);

    /* Load streams into 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;

    /* Persist PR (io_pr/io_pr_len) and GPI (io_gpi/io_gpi_len) to storage */

    return true;
}
```

## Connected device provisioning examples

Guardian supports C# and C++ for connected provisioning.

### **C# example**

```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();
    // Complete Disconnected Provisioning as in DisconnectedProvisioning()
    // The data in provisioningFilesInput and provisioningOutputFiles should
    // come from the DisconnectedProvisioning() function.
    //
    // The static text is reproduced in this function for readability.
    string componentHandle = "my_component_handle";
    string hardwareId = "my_serial_number";

    /* copy provisioning profile files to initialization file storage */
    medcrypt.guardian.InitializeFiles initializeFiles =
        new medcrypt.guardian.InitializeFiles();
    initializeFiles.trustStore = provisioningFilesInput.trustStore;
    initializeFiles.privateIdentity = provisioningFilesInput.privateIdentity;
    initializeFiles.certifiedProfile = provisioningFilesInput.certifiedProfile;

    /* initialize guardian for configured operations (connecting to backend)*/
    medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();

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

    /* create default options */
    medcrypt.guardian.ProvisioningOnlineOptions options =
            new medcrypt.guardian.ProvisioningOnlineOptions();

    /* load provision request into online files structure */
    medcrypt.guardian.ProvisioningFilesOnline onlineFiles =
        new medcrypt.guardian.ProvisioningFilesOnline();
    onlineFiles.provisionRequest =
        provisioningOutputFiles.provisionRequest;

    /* start connected provisioning state machine */
    gdn.StartProvisioningOnline(onlineFiles, options);
    gdn.Run();

    /* wait for provisioning to complete, error, or timeout to occur */
    DateTime start = DateTime.Now;
    TimeSpan timeout = TimeSpan.FromMinutes(2);
    while (gdn.IsProvisioningRunning() &&
            System.DateTime.Now - start < timeout)
    {
        gdn.Run();
        System.Threading.Thread.Sleep(500);
    }

    /* persist provisioned profile */
    File.WriteAllBytes(
        @"CertifiedProfile.mcp",
        gdn.GetProvisionedProfile());
}
}
```

### **C++ example**

```cpp
#define ARBITRARY_BUF_SIZE 10 * 1024

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

    The static text is reproduced in this function for readability. */
    // Complete Disconnected Provisioning as in DisconnectedProvisioning()
    // The data in DisconnectedProvisioning()'s "files" object should be copied 
    // to "in_files" in this function.
    //
    // The static text is reproduced in this function for readability.
    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";

     /* Create Guardian */
    medcrypt::guardian::Guardian guardian;
    medcrypt::guardian::Status status;

    /* Initialize Guardian with the provided provisioning profile to enable connecting to medcrypt backend infrastructure */
    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;

    /* Initialize provided Guardian */
    status = guardian.Initialize(
        init_files,
        in_component_handle.c_str(),
        in_hardware_id.c_str(),
        medcrypt::guardian::InitializeOptions());

    /* Check and print non-OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not initialize guardian [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Start the internal online provisioning state machine by providing it with the generated provision request */
    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());  
    /* Check and print non-OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not start online provisioning [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Engage internal state machine */
    status = guardian.Run();
    /* Check and print non-OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not run guardian [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Wait for provisioning to complete, error, or timeout to occur */
    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));
    }

    /* Retrieve the received provisioned profile */
    char profile[ARBITRARY_BUF_SIZE] = {0};
    size_t profile_size = sizeof(profile);
    status = guardian.GetProvisionedProfile(
            profile,
            &profile_size);
    /* Check and print non-OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not complete online provisioning [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Write the provisioned profile to disk */
    if (!WriteBufferToFile(
            in_provisioning_profile_folder + kCpFilename,
            profile,
            profile_size))
    {
        MSG_ERROR(("could not write provisioned profile"));
        return false;
    }

    return true;
}
```

## Proxy device provisioning examples

Guardian supports C# and C++ for proxy provisioning. Since Guardian does not support connected provisioning, it cannot proxy a provision request.

### **C# example**

```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();
    // Complete Disconnected Provisioning as in DisconnectedProvisioning()
    // The data in provisioningFilesInput and provisioningOutputFiles should
    // come from the DisconnectedProvisioning() function.
    //
    // The static text is reproduced in this function for readability.
    string componentHandle = "my_component_handle";
    string hardwareId = "my_serial_number";

    /* Copy provisioning profile files to initialization file storage */
    medcrypt.guardian.InitializeFiles initializeFiles =
        new medcrypt.guardian.InitializeFiles();
    initializeFiles.trustStore = provisioningFilesInput.trustStore;
    initializeFiles.privateIdentity = provisioningFilesInput.privateIdentity;
    initializeFiles.certifiedProfile = provisioningFilesInput.certifiedProfile;

    /* Initialize Guardian for configured operations (connecting to backend)*/
    medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();

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

    /* Create default options */
    medcrypt.guardian.ProvisioningOnlineOptions options =
            new medcrypt.guardian.ProvisioningOnlineOptions();

    /* Load provision request into online files structure */
    medcrypt.guardian.ProvisioningFilesOnline onlineFiles =
        new medcrypt.guardian.ProvisioningFilesOnline();
    onlineFiles.provisionRequest =
        File.ReadAllBytes(@"ProxiedProvisionRequest.mcpr");

    /* Start connected provisioning state machine */
    gdn.StartProvisioningOnline(onlineFiles, options);
    gdn.Run();

    /* Wait for provisioning to complete, error, or timeout to occur */
    DateTime start = DateTime.Now;
    TimeSpan timeout = TimeSpan.FromMinutes(2);
    while (gdn.IsProvisioningRunning() &&
            System.DateTime.Now - start < timeout)
    {
        gdn.Run();
        System.Threading.Thread.Sleep(500);
    }

    /* Persist provisioned profile */
    File.WriteAllBytes(
        @"CertifiedProfile.mcp",
        gdn.GetProvisionedProfile());
}
}
```

### **C++ example**

```cpp
#define ARBITRARY_BUF_SIZE 10 * 1024

static const char kCpFilename[] = "CertifiedProfile.mcp";
bool ConnectedProvisioning()
{
    /* Complete Disconnected Provisioning as in DisconnectedProvisioning(). The data in from DisconnectedProvisioning()'s "files" object should be copied to "in_files" in this function.
    The static text is reproduced in this function for readability. */
    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";

     /* Create Guardian */
    medcrypt::guardian::Guardian guardian;
    medcrypt::guardian::Status status;

    /* Initialize Guardian with the provided provisioning profile to enable connecting to medcrypt backend infrastructure */
    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;

    /* Initialize provided Guardian */
    status = guardian.Initialize(
        init_files,
        in_component_handle.c_str(),
        in_hardware_id.c_str(),
        medcrypt::guardian::InitializeOptions());

    /* Check and print non-OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not initialize guardian [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Start the internal online provisioning state machine by providing it with the generated provision request */
    medcrypt::guardian::utilities::ProvisionOnlineFiles online_files;
    online_files.ProvisionRequest       = in_files.ProvisionRequest;
    online_files.ProvisionRequestSize   = in_files.ProvisionRequestSize;

    /* Load proxy Provision Request to a buffer and size here */
    char pr_buf[2048] = {0};
    size_t pr_buf_size = sizeof(buf);

    /* Start the internal online provisioning state machine by
    providing it with the generated disconnected provision request */
    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());  
    /* Check and print non-OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not start online provisioning [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Engage internal state machine */
    status = guardian.Run();
    /* Check and print non_OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not run guardian [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Wait for provisioning to complete, error, or timeout to occur */
    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));
    }

    /* Retrieve the received provisioned profile*/
    char profile[ARBITRARY_BUF_SIZE] = {0};
    size_t profile_size = sizeof(profile);
    status = guardian.GetProvisionedProfile(
            profile,
            &profile_size);
    /* Check and print non-OK error code */
    if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
        MSG_ERROR(("could not complete online provisioning [%s]",
            medcrypt::guardian::GuardianStatusEnum::NameOf(
                EXTRACT_STATUS(status)).c_str()));
        return false;
    }

    /* Write the provisioned profile to disk */
    if (!WriteBufferToFile(
            in_provisioning_profile_folder + kCpFilename,
            profile,
            profile_size))
    {
        MSG_ERROR(("could not write provisioned profile"));
        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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.medcrypt.com/manage-devices/begin-device-provisioning/device-provisioning-code-examples.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
