GR-MANGO sample using mbed-os library from my repository.

Dependencies:   mbed-http

Committer:
RyoheiHagimoto
Date:
Mon Oct 12 02:25:49 2020 +0000
Revision:
0:b4c1e32627f2
replaced mbed-os library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RyoheiHagimoto 0:b4c1e32627f2 1 /*******************************************************************************
RyoheiHagimoto 0:b4c1e32627f2 2 * DISCLAIMER
RyoheiHagimoto 0:b4c1e32627f2 3 * This software is supplied by Renesas Electronics Corporation and is only
RyoheiHagimoto 0:b4c1e32627f2 4 * intended for use with Renesas products. No other uses are authorized. This
RyoheiHagimoto 0:b4c1e32627f2 5 * software is owned by Renesas Electronics Corporation and is protected under
RyoheiHagimoto 0:b4c1e32627f2 6 * all applicable laws, including copyright laws.
RyoheiHagimoto 0:b4c1e32627f2 7 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
RyoheiHagimoto 0:b4c1e32627f2 8 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
RyoheiHagimoto 0:b4c1e32627f2 9 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
RyoheiHagimoto 0:b4c1e32627f2 10 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
RyoheiHagimoto 0:b4c1e32627f2 11 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
RyoheiHagimoto 0:b4c1e32627f2 12 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
RyoheiHagimoto 0:b4c1e32627f2 13 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
RyoheiHagimoto 0:b4c1e32627f2 14 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
RyoheiHagimoto 0:b4c1e32627f2 15 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
RyoheiHagimoto 0:b4c1e32627f2 16 * Renesas reserves the right, without notice, to make changes to this software
RyoheiHagimoto 0:b4c1e32627f2 17 * and to discontinue the availability of this software. By using this software,
RyoheiHagimoto 0:b4c1e32627f2 18 * you agree to the additional terms and conditions found by accessing the
RyoheiHagimoto 0:b4c1e32627f2 19 * following link:
RyoheiHagimoto 0:b4c1e32627f2 20 * http://www.renesas.com/disclaimer
RyoheiHagimoto 0:b4c1e32627f2 21 *
RyoheiHagimoto 0:b4c1e32627f2 22 * Copyright (C) 2019 Renesas Electronics Corporation. All rights reserved.
RyoheiHagimoto 0:b4c1e32627f2 23 *******************************************************************************/
RyoheiHagimoto 0:b4c1e32627f2 24 #include "sample_select.h"
RyoheiHagimoto 0:b4c1e32627f2 25
RyoheiHagimoto 0:b4c1e32627f2 26 #if (SAMPLE_PROGRAM_NO == 14)
RyoheiHagimoto 0:b4c1e32627f2 27 // SAMPLE_PROGRAM_NO 14 : Ether HTTPS sample
RyoheiHagimoto 0:b4c1e32627f2 28
RyoheiHagimoto 0:b4c1e32627f2 29 #if defined(TARGET_SEMB1402)
RyoheiHagimoto 0:b4c1e32627f2 30 #error "Ether is not supported."
RyoheiHagimoto 0:b4c1e32627f2 31 #endif
RyoheiHagimoto 0:b4c1e32627f2 32
RyoheiHagimoto 0:b4c1e32627f2 33 #include "mbed.h"
RyoheiHagimoto 0:b4c1e32627f2 34 #include "https_request.h"
RyoheiHagimoto 0:b4c1e32627f2 35 #include "EthernetInterface.h"
RyoheiHagimoto 0:b4c1e32627f2 36
RyoheiHagimoto 0:b4c1e32627f2 37 EthernetInterface eth;
RyoheiHagimoto 0:b4c1e32627f2 38
RyoheiHagimoto 0:b4c1e32627f2 39 /* List of trusted root CA certificates
RyoheiHagimoto 0:b4c1e32627f2 40 *
RyoheiHagimoto 0:b4c1e32627f2 41 * - Amazon, the CA for os.mbed.com
RyoheiHagimoto 0:b4c1e32627f2 42 * - Let's Encrypt, the CA for httpbin.org
RyoheiHagimoto 0:b4c1e32627f2 43 * - Comodo, the CA for reqres.in
RyoheiHagimoto 0:b4c1e32627f2 44 *
RyoheiHagimoto 0:b4c1e32627f2 45 * To add more root certificates, just concatenate them.
RyoheiHagimoto 0:b4c1e32627f2 46 */
RyoheiHagimoto 0:b4c1e32627f2 47 const char SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n"
RyoheiHagimoto 0:b4c1e32627f2 48 "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n"
RyoheiHagimoto 0:b4c1e32627f2 49 "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n"
RyoheiHagimoto 0:b4c1e32627f2 50 "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n"
RyoheiHagimoto 0:b4c1e32627f2 51 "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n"
RyoheiHagimoto 0:b4c1e32627f2 52 "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n"
RyoheiHagimoto 0:b4c1e32627f2 53 "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n"
RyoheiHagimoto 0:b4c1e32627f2 54 "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n"
RyoheiHagimoto 0:b4c1e32627f2 55 "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n"
RyoheiHagimoto 0:b4c1e32627f2 56 "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n"
RyoheiHagimoto 0:b4c1e32627f2 57 "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n"
RyoheiHagimoto 0:b4c1e32627f2 58 "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
RyoheiHagimoto 0:b4c1e32627f2 59 "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n"
RyoheiHagimoto 0:b4c1e32627f2 60 "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n"
RyoheiHagimoto 0:b4c1e32627f2 61 "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n"
RyoheiHagimoto 0:b4c1e32627f2 62 "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n"
RyoheiHagimoto 0:b4c1e32627f2 63 "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n"
RyoheiHagimoto 0:b4c1e32627f2 64 "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n"
RyoheiHagimoto 0:b4c1e32627f2 65 "rqXRfboQnoZsG4q5WTP468SQvvG5\n"
RyoheiHagimoto 0:b4c1e32627f2 66 "-----END CERTIFICATE-----\n"
RyoheiHagimoto 0:b4c1e32627f2 67 "-----BEGIN CERTIFICATE-----\n"
RyoheiHagimoto 0:b4c1e32627f2 68 "MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n"
RyoheiHagimoto 0:b4c1e32627f2 69 "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"
RyoheiHagimoto 0:b4c1e32627f2 70 "DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n"
RyoheiHagimoto 0:b4c1e32627f2 71 "SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n"
RyoheiHagimoto 0:b4c1e32627f2 72 "GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n"
RyoheiHagimoto 0:b4c1e32627f2 73 "AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n"
RyoheiHagimoto 0:b4c1e32627f2 74 "q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n"
RyoheiHagimoto 0:b4c1e32627f2 75 "SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n"
RyoheiHagimoto 0:b4c1e32627f2 76 "Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n"
RyoheiHagimoto 0:b4c1e32627f2 77 "a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n"
RyoheiHagimoto 0:b4c1e32627f2 78 "/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n"
RyoheiHagimoto 0:b4c1e32627f2 79 "AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n"
RyoheiHagimoto 0:b4c1e32627f2 80 "CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n"
RyoheiHagimoto 0:b4c1e32627f2 81 "bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n"
RyoheiHagimoto 0:b4c1e32627f2 82 "c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n"
RyoheiHagimoto 0:b4c1e32627f2 83 "VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n"
RyoheiHagimoto 0:b4c1e32627f2 84 "ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n"
RyoheiHagimoto 0:b4c1e32627f2 85 "MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n"
RyoheiHagimoto 0:b4c1e32627f2 86 "Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n"
RyoheiHagimoto 0:b4c1e32627f2 87 "AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n"
RyoheiHagimoto 0:b4c1e32627f2 88 "uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n"
RyoheiHagimoto 0:b4c1e32627f2 89 "wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n"
RyoheiHagimoto 0:b4c1e32627f2 90 "X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n"
RyoheiHagimoto 0:b4c1e32627f2 91 "PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n"
RyoheiHagimoto 0:b4c1e32627f2 92 "KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n"
RyoheiHagimoto 0:b4c1e32627f2 93 "-----END CERTIFICATE-----\n"
RyoheiHagimoto 0:b4c1e32627f2 94 "-----BEGIN CERTIFICATE-----\n"
RyoheiHagimoto 0:b4c1e32627f2 95 "MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL\n"
RyoheiHagimoto 0:b4c1e32627f2 96 "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n"
RyoheiHagimoto 0:b4c1e32627f2 97 "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT\n"
RyoheiHagimoto 0:b4c1e32627f2 98 "IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw\n"
RyoheiHagimoto 0:b4c1e32627f2 99 "MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy\n"
RyoheiHagimoto 0:b4c1e32627f2 100 "ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N\n"
RyoheiHagimoto 0:b4c1e32627f2 101 "T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv\n"
RyoheiHagimoto 0:b4c1e32627f2 102 "biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR\n"
RyoheiHagimoto 0:b4c1e32627f2 103 "FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J\n"
RyoheiHagimoto 0:b4c1e32627f2 104 "cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW\n"
RyoheiHagimoto 0:b4c1e32627f2 105 "BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\n"
RyoheiHagimoto 0:b4c1e32627f2 106 "BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm\n"
RyoheiHagimoto 0:b4c1e32627f2 107 "fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv\n"
RyoheiHagimoto 0:b4c1e32627f2 108 "GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=\n"
RyoheiHagimoto 0:b4c1e32627f2 109 "-----END CERTIFICATE-----\n";
RyoheiHagimoto 0:b4c1e32627f2 110
RyoheiHagimoto 0:b4c1e32627f2 111 void dump_response(HttpResponse* res) {
RyoheiHagimoto 0:b4c1e32627f2 112 mbedtls_printf("Status: %d - %s\n", res->get_status_code(), res->get_status_message().c_str());
RyoheiHagimoto 0:b4c1e32627f2 113
RyoheiHagimoto 0:b4c1e32627f2 114 mbedtls_printf("Headers:\n");
RyoheiHagimoto 0:b4c1e32627f2 115 for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
RyoheiHagimoto 0:b4c1e32627f2 116 mbedtls_printf("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str());
RyoheiHagimoto 0:b4c1e32627f2 117 }
RyoheiHagimoto 0:b4c1e32627f2 118 mbedtls_printf("\nBody (%d bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
RyoheiHagimoto 0:b4c1e32627f2 119 }
RyoheiHagimoto 0:b4c1e32627f2 120
RyoheiHagimoto 0:b4c1e32627f2 121 int main() {
RyoheiHagimoto 0:b4c1e32627f2 122 NetworkInterface* network = &eth;
RyoheiHagimoto 0:b4c1e32627f2 123 SocketAddress address;
RyoheiHagimoto 0:b4c1e32627f2 124
RyoheiHagimoto 0:b4c1e32627f2 125 printf("\nConnecting...\n");
RyoheiHagimoto 0:b4c1e32627f2 126 int ret = network->connect();
RyoheiHagimoto 0:b4c1e32627f2 127 if (ret != 0) {
RyoheiHagimoto 0:b4c1e32627f2 128 printf("\nConnection error\n");
RyoheiHagimoto 0:b4c1e32627f2 129 return -1;
RyoheiHagimoto 0:b4c1e32627f2 130 }
RyoheiHagimoto 0:b4c1e32627f2 131 printf("Success\n\n");
RyoheiHagimoto 0:b4c1e32627f2 132 printf("MAC: %s\n", network->get_mac_address());
RyoheiHagimoto 0:b4c1e32627f2 133 printf("IP: %s\n" , NSAPI_ERROR_OK == network->get_ip_address(&address) ? address.get_ip_address() : "NULL");
RyoheiHagimoto 0:b4c1e32627f2 134 printf("Netmask: %s\n", NSAPI_ERROR_OK == network->get_netmask(&address) ? address.get_ip_address() : "NULL");
RyoheiHagimoto 0:b4c1e32627f2 135 printf("Gateway: %s\n", NSAPI_ERROR_OK == network->get_gateway(&address) ? address.get_ip_address() : "NULL");
RyoheiHagimoto 0:b4c1e32627f2 136
RyoheiHagimoto 0:b4c1e32627f2 137 // GET request to developer.mbed.org
RyoheiHagimoto 0:b4c1e32627f2 138 {
RyoheiHagimoto 0:b4c1e32627f2 139 printf("\n----- HTTPS GET request -----\n");
RyoheiHagimoto 0:b4c1e32627f2 140
RyoheiHagimoto 0:b4c1e32627f2 141 HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt");
RyoheiHagimoto 0:b4c1e32627f2 142
RyoheiHagimoto 0:b4c1e32627f2 143 HttpResponse* get_res = get_req->send();
RyoheiHagimoto 0:b4c1e32627f2 144 if (!get_res) {
RyoheiHagimoto 0:b4c1e32627f2 145 printf("HttpRequest failed (error code %d)\n", get_req->get_error());
RyoheiHagimoto 0:b4c1e32627f2 146 return 1;
RyoheiHagimoto 0:b4c1e32627f2 147 }
RyoheiHagimoto 0:b4c1e32627f2 148 printf("\n----- HTTPS GET response -----\n");
RyoheiHagimoto 0:b4c1e32627f2 149 dump_response(get_res);
RyoheiHagimoto 0:b4c1e32627f2 150
RyoheiHagimoto 0:b4c1e32627f2 151 delete get_req;
RyoheiHagimoto 0:b4c1e32627f2 152 }
RyoheiHagimoto 0:b4c1e32627f2 153
RyoheiHagimoto 0:b4c1e32627f2 154 // POST request to httpbin.org
RyoheiHagimoto 0:b4c1e32627f2 155 {
RyoheiHagimoto 0:b4c1e32627f2 156 printf("\n----- HTTPS POST request -----\n");
RyoheiHagimoto 0:b4c1e32627f2 157
RyoheiHagimoto 0:b4c1e32627f2 158 HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://httpbin.org/post");
RyoheiHagimoto 0:b4c1e32627f2 159 post_req->set_header("Content-Type", "application/json");
RyoheiHagimoto 0:b4c1e32627f2 160
RyoheiHagimoto 0:b4c1e32627f2 161 const char body[] = "{\"hello\":\"world\"}";
RyoheiHagimoto 0:b4c1e32627f2 162
RyoheiHagimoto 0:b4c1e32627f2 163 HttpResponse* post_res = post_req->send(body, strlen(body));
RyoheiHagimoto 0:b4c1e32627f2 164 if (!post_res) {
RyoheiHagimoto 0:b4c1e32627f2 165 printf("HttpRequest failed (error code %d)\n", post_req->get_error());
RyoheiHagimoto 0:b4c1e32627f2 166 return 1;
RyoheiHagimoto 0:b4c1e32627f2 167 }
RyoheiHagimoto 0:b4c1e32627f2 168
RyoheiHagimoto 0:b4c1e32627f2 169 printf("\n----- HTTPS POST response -----\n");
RyoheiHagimoto 0:b4c1e32627f2 170 dump_response(post_res);
RyoheiHagimoto 0:b4c1e32627f2 171
RyoheiHagimoto 0:b4c1e32627f2 172 delete post_req;
RyoheiHagimoto 0:b4c1e32627f2 173 }
RyoheiHagimoto 0:b4c1e32627f2 174
RyoheiHagimoto 0:b4c1e32627f2 175 ThisThread::sleep_for(osWaitForever);
RyoheiHagimoto 0:b4c1e32627f2 176 }
RyoheiHagimoto 0:b4c1e32627f2 177
RyoheiHagimoto 0:b4c1e32627f2 178 #endif