#include "includes.h"

// 来自Win10的root CA——Sectigo（AddTrust）
const char *ca_cert = 
{
"-----BEGIN CERTIFICATE-----\n\
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU\n\
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\n\
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\n\
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux\n\
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h\n\
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v\n\
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt\n\
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9\n\
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX\n\
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX\n\
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN\n\
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0\n\
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD\n\
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0\n\
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\n\
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx\n\
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN\n\
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH\n\
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n\
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC\n\
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX\n\
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a\n\
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n\
-----END CERTIFICATE-----\n"
};

#if 0
// 来自LindeTelemTest.pem, for telemetry.test.linde.com
const char *client_cert = 
{
"Bag Attributes\n\
    localKeyID: 01 00 00 00 \n\
subject=/CN=LindeTelemTest\n\
issuer=/CN=RootLindeTelemTest\n\
-----BEGIN CERTIFICATE-----\n\
MIICBTCCAXKgAwIBAgIQsAePmD4yBrxNOjXTSoR8WDAJBgUrDgMCHQUAMB0xGzAZ\n\
BgNVBAMTElJvb3RMaW5kZVRlbGVtVGVzdDAeFw0xOTA0MDkxNDIwNTNaFw0zOTEy\n\
MzEyMzU5NTlaMBkxFzAVBgNVBAMTDkxpbmRlVGVsZW1UZXN0MIGfMA0GCSqGSIb3\n\
DQEBAQUAA4GNADCBiQKBgQDWXFoXZu9g6qmooWJD1FNu7gdWOmNwokbZVA0c5xIN\n\
+sV++jTpD1HP87LWWodoeikNHRSLm5D8+4k08+JC3JFVslJn0jMFmWk752pC0pcP\n\
L65Ityt9JLELF4EzeIcp3n6evVlbsmAGxwvzQdq/0Tzk5XRsFBxGKyEw1WeV0zOb\n\
aQIDAQABo1IwUDBOBgNVHQEERzBFgBCyJA+/vhUnVMhI87j0nOxvoR8wHTEbMBkG\n\
A1UEAxMSUm9vdExpbmRlVGVsZW1UZXN0ghAel9uqpF3bqkGSfrB2pm0gMAkGBSsO\n\
AwIdBQADgYEAO4lrYCGNlDqUCWCBaGVdh8RPav7gD3bcr+10DzJxaS7SaHE1N+dA\n\
qbByd6I9uZhbPt9UEwWlMbPrRuFowhFjfD2/t0gSgjQUJmSRUZaEhZEWQK9OYyy5\n\
EaKTEUZqZF/69zNjjRxMmSaezdlJYgON2K+y7pqwwWTrotwFoil8snE=\n\
-----END CERTIFICATE-----\n"
};

// 来自LindeTelemTest.pem, for telemetry.test.linde.com
const char *client_key =
{
"Bag Attributes\n\
    localKeyID: 01 00 00 00 \n\
    Microsoft CSP Name: Microsoft Strong Cryptographic Provider\n\
    friendlyName: PvkTmp:84aaec03-0e6d-4c65-a47d-b8f891f9f38d\n\
Key Attributes\n\
    X509v3 Key Usage: 10 \n\
-----BEGIN PRIVATE KEY-----\n\
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANZcWhdm72Dqqaih\n\
YkPUU27uB1Y6Y3CiRtlUDRznEg36xX76NOkPUc/zstZah2h6KQ0dFIubkPz7iTTz\n\
4kLckVWyUmfSMwWZaTvnakLSlw8vrki3K30ksQsXgTN4hynefp69WVuyYAbHC/NB\n\
2r/RPOTldGwUHEYrITDVZ5XTM5tpAgMBAAECgYAZRGeGLKb4yJBZBTTdA/EVuU76\n\
FgXUp/wr7+Ffz8jsBuwyrHGCK0EcfwBMjf06DnQ6THw4fIzZlRi2Oi0obnFe7lzh\n\
bFfA72qRh844diATnVXEgwOL9bMOZYawkAYbgWq14YP5y2HBYn8CS/ii8OeXBxh4\n\
OnWWTKTD1+ZnPKvF9QJBAOwOSzo33vNHQTu53+7gcPT/TVqbFxRJbxAd37tnne93\n\
/QqvVV7ZwW2kvct0YGmN8J1A3qVHsPcO3yKYoJntF2MCQQDoeM9fPa9onBlHYpES\n\
87PBjBdnkHdBUU28IEidDjKBwknwG+FuN2hNfj9WsBw2yRpvhWU8y+AOn0bn/RVE\n\
T3nDAkEA4J6xYtKral+RaV30AoC7u8X8O418pqdB8dobfV6Z4LcSqEozODCJaOXs\n\
XF9/JrIUFe8WbbwMXutd1LPbjt0W9QJBANRYXdt6RfpA89o/z5JHJv/5DfvcewIf\n\
2OipeIp1SG88YDtBzFXXqJ94XTS64tqsMUiCyamR9JSGqscHZuCh0+8CQFzGDwWg\n\
NZOyyV/ttOXI6m8WvLif/givfoZGNfZfr39Z2+yLJeEnm1JRK2iWRuPwwfCCxWIR\n\
47aQkh8VKyiXMho=\n\
-----END PRIVATE KEY-----\n"
};

#else

// 来自PraxairChina.pem, for telemetry.linde.com
const char *client_cert =
{
"Bag Attributes\n\
    localKeyID: 01 00 00 00 \n\
subject=/CN=PraxairChina\n\
issuer=/CN=RootLindeTelem\n\
-----BEGIN CERTIFICATE-----\n\
MIIB+zCCAWigAwIBAgIQHsNacaBKNbhGZR1hlXODrjAJBgUrDgMCHQUAMBkxFzAV\n\
BgNVBAMTDlJvb3RMaW5kZVRlbGVtMB4XDTE5MDUwNzAxMDgwOVoXDTM5MTIzMTIz\n\
NTk1OVowFzEVMBMGA1UEAxMMUHJheGFpckNoaW5hMIGfMA0GCSqGSIb3DQEBAQUA\n\
A4GNADCBiQKBgQCzjM8Enk1275ad4wdkQT7nDJrNQv4rzmivmapgSC7E74xHM2Bv\n\
tAVugDSsFNXqvYq2QHJ9XQbyoIoI81wHYwwrPMaSbli39tz1l+8TZK397BOutsLP\n\
ojxupuXDs7u4+b3Z5CnC6DegUeJm6qvQiBk+Zh2Rj8aYIrAQ3tyGfXL4NQIDAQAB\n\
o04wTDBKBgNVHQEEQzBBgBAQAXdJmRT6+eHp+YlqYGJFoRswGTEXMBUGA1UEAxMO\n\
Um9vdExpbmRlVGVsZW2CEGrbELsyedK8Rwv6ntamEAgwCQYFKw4DAh0FAAOBgQAs\n\
IiiFy/XNUEhV7+oK3Gs4YTP1KDzBtcilSHmdgK4QKfmeJOmlahRj2x5628LZq4nV\n\
tVF2/SCDzvhq6NqNCndTLgLUP0b7oEhe434uNEqmlJBjPeN3Cf4Niui7UkaLhTQ+\n\
Wo5uxCHHwXQGL4PdFrmsbQTX+yu4iUQHsVc1doNKEQ==\n\
-----END CERTIFICATE-----\n"
};

// 来自PraxairChina.pem, for telemetry.linde.com
const char *client_key = 
{
"Bag Attributes\n\
    localKeyID: 01 00 00 00 \n\
    Microsoft CSP Name: Microsoft Strong Cryptographic Provider\n\
    friendlyName: PvkTmp:ec094439-3ddc-47a6-93e0-90485b70a87c\n\
Key Attributes\n\
    X509v3 Key Usage: 10 \n\
-----BEGIN PRIVATE KEY-----\n\
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALOMzwSeTXbvlp3j\n\
B2RBPucMms1C/ivOaK+ZqmBILsTvjEczYG+0BW6ANKwU1eq9irZAcn1dBvKgigjz\n\
XAdjDCs8xpJuWLf23PWX7xNkrf3sE662ws+iPG6m5cOzu7j5vdnkKcLoN6BR4mbq\n\
q9CIGT5mHZGPxpgisBDe3IZ9cvg1AgMBAAECgYBXDOe5l357MYHWnqGQy8lRf9z1\n\
s4tDddlveZMPBzAVrwZV5uTUg3U2s9XVsGxeWPMNlYVsnlOmAoup90MhGbZl19dN\n\
C6ZnNkNiBXIXMtLk6KHoWg1wskPowk1GL3bssSDsaVqKhbnd8xkeXEemKH1Yk+D/\n\
0azuDWS3AAt1ivQoKQJBAOOtZUbyunheA76BR/ac3RJYpVK9DX7Fij15z6s128H/\n\
g8pnJZdi+3EBeIe8y9Kl4p1qy9YUpbIwppqrtDTBffsCQQDJ4sC/qYQm3T2LmSr2\n\
GVD4WztwxSsO0VjM09XD/4GHn2rq3IKpTvNQCgaYIBC2Y6OTxJSfBU5RV/MAgk/v\n\
onuPAkEA4bfNOWp5Pc4PLjYjbzYS4hZqSL3O/EjBhbMXFGk/5nP4Z5idJxnlqCJK\n\
KWAePkdhhKkVTreHkkIzWhIyhT7zMwJAP+OmpAD9dV8mjvsWAXPZj/8vPGzpR3Mw\n\
6wFO8Qv27fihWVoXb4Uwsu+5ToM3RsEZjzXy4rBHLK7slAipS2jcOQJAPIrm3Rnw\n\
07kj+9B9WBKaFMIEIZWWLCE35iXzMByBXzk5G4VlPtOkr9Do4Gba7BML/UYSl4OY\n\
KcCnGVc+oGzPbA==\n\
-----END PRIVATE KEY-----\n"
};
#endif

// HTTP头格式串
const char *http_header_fmt =
{
"POST %s HTTP/1.1\r\n\
Host:%s\r\n\
Content-Type:application/json\r\n\
Content-Length:%d\r\n\
Connection:Keep-Alive\r\n\
\r\n"
};

#if 0
// 范例记录，来自邮件
const char *json_data = 
{
"{\n\
    \"assets\":[\n\
        {\n\
            \"customerReference\":\"PRAXAIR-GOLD-CN-TEST\",\n\
            \"assetIntegrationId\":\"0\",\n\
            \"channels\":[\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Level\",\n\
                    \"channelNumber\":\"1\",\n\
                    \"scaledUnitName\":\"mm WC\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"scaledMeasurement\":300.45678,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Level\",\n\
                    \"channelNumber\":\"2\",\n\
                    \"displayUnitName\":\"%% Full\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"displayMeasurement\":50.34,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Level\",\n\
                    \"channelNumber\":\"3\",\n\
                    \"displayUnitName\":\"l\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"displayMeasurement\":3068,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Gps\",\n\
                    \"channelNumber\":\"4\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"longitude\":102.045678,\n\
                            \"latitude\":30.456789,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Pressure\",\n\
                    \"channelNumber\":\"5\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"scaledMeasurement\":1.36,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Temperature\",\n\
                    \"channelNumber\":\"6\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"scaledMeasurement\":-162,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"BatteryVoltage\",\n\
                    \"channelNumber\":\"7\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"scaledMeasurement\":3.61,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Diagnostic\",\n\
                    \"channelNumber\":\"8\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"scaledMeasurement\":1,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                },\n\
                {\n\
                    \"deviceId\":\"2019041580001\",\n\
                    \"channelType\":\"Diagnostic\",\n\
                    \"channelNumber\":\"9\",\n\
                    \"readings\":[\n\
                        {\n\
                            \"scaledMeasurement\":2,\n\
                            \"timestamp\":\"2019-04-22T11:00:00Z\"\n\
                        }\n\
                    ]\n\
                }\n\
            ]\n\
        }\n\
    ]\n\
}\n"
};
#endif

#define JSON_BUFF_SIZE 2048
char JSON_buff[JSON_BUFF_SIZE];

char *JSON_data()
{
	return JSON_buff;
}

void json_initialize()
{
	memset(JSON_buff, 0, JSON_BUFF_SIZE);
}

void json_finish()
{
	int offset = strlen(JSON_buff);

	// 去掉最后一行多余的','
	if(offset > 0 && JSON_buff[offset - 1] == ',')
		JSON_buff[--offset] = 0;
}

void json_new_object()
{
	int offset = strlen(JSON_buff);
	
	sprintf(JSON_buff + offset, "{");
}

void json_end_object()
{
	int offset = strlen(JSON_buff);

	// 去掉最后一行多余的','
	if(offset > 0 && JSON_buff[offset - 1] == ',')
		offset--;
	sprintf(JSON_buff + offset, "},");
}

void json_new_array(char *key)
{
	int offset = strlen(JSON_buff);

	sprintf(JSON_buff + offset, "\"%s\":[", key);
}

void json_end_array()
{
	int offset = strlen(JSON_buff);

	// 去掉最后一行多余的','
	if(offset > 0 && JSON_buff[offset - 1] == ',')
		offset--;
	sprintf(JSON_buff + offset, "],");
}

void json_new_intValue(char *key, int val)
{
	int offset = strlen(JSON_buff);

	sprintf(JSON_buff + offset, "\"%s\":%d,", key, val);
}

void json_new_doubleValue(char *key, double val)
{
	int offset = strlen(JSON_buff);

	sprintf(JSON_buff + offset, "\"%s\":%f,", key, val);
}

void json_new_stringValue(char *key, char *val)
{
	int offset = strlen(JSON_buff);

	sprintf(JSON_buff + offset, "\"%s\":\"%s\",", key, val);
}

void json_new_boolValue(char *key, uint32_t val)
{
	int offset = strlen(JSON_buff);

	sprintf(JSON_buff + offset, "\"%s\":%s,", key, val ? "true" : "false");
}

// 以内为JSON解析函数，只解析最简单的记录（无数组和嵌套，数据类型只支持字符型、整型和浮点型）
JSON_field JSON_Record[JSON_FIELD_COUNT];

int JSON_Parse_Symbol(char **src, char symbol)
{
    while(**src == ' ' || **src == '\t' || **src == '\r' || **src == '\n')
        (*src)++;

    if(**src == symbol)
    {
        (*src)++;
        return 1;
    }

    return 0;
}

int JSON_Parse_Name(char **src, JSON_field *fld)
{
    int len = 0;

    memset(fld->name, 0, JSON_NAME_LENGTH);

    while(**src != 0 && **src != '"' && len < JSON_NAME_LENGTH)
    {
        if(**src != '\r' && **src != '\n')
        {
            if(**src == '\\')
                (*src)++;
            fld->name[len++] = **src;
        }
        (*src)++;
    }

    if(len == 0)
        return 0;

    return 1;
}

int JSON_Parse_Val(char **src, JSON_field *fld)
{
    long len = 0;
    int signCount = 0, pointCount = 0, quotCount = 0;
    char c;

    memset(fld->val, 0, JSON_VAL_LENGTH + 2);

    while(**src == ' ' || **src == '\t' || **src == '\r' || **src == '\n')
        (*src)++;
        
    while(**src != 0 && len < JSON_VAL_LENGTH + 2)
    {
        if(**src == ',' || **src == '}')
        {
            if(quotCount != 1)
                break;
        }
        if(**src != '\r' && **src != '\n')
        {
            c = **src;

            if(**src == '\\')
                (*src)++;
            if((quotCount == 0 && **src != ' ') || quotCount == 1)
                fld->val[len++] = **src;

            if(c == '"')
                quotCount++;
        }
        (*src)++;
    }

    if(fld->val[0] == '"' && fld->val[len - 1] == '"')
    {
        fld->type = JSON_TYPE_STRING;
        len -= 2;
        memmove(fld->val, fld->val + 1, len);
        fld->val[len] = 0;

        return 1;
    }

    for(int i = 0; i < len; i++)
    {
        if(fld->val[i] == '+' || fld->val[i] == '-')
        {
            if(i > 0 || signCount > 0)
                return 0;
            signCount++;
        }
        else if(fld->val[i] == '.')
        {
            if(pointCount > 0)
                return 0;
            if(i > 0 && !isdigit(fld->val[i - 1]))
                return 0;
            pointCount++;
        }
        else if(!isdigit(fld->val[i]))
            return 0;
    }

    if(pointCount == 0)
        fld->type = JSON_TYPE_INTEGER;
    else
        fld->type = JSON_TYPE_FLOAT;

    len = atoi(fld->val);
    fld->f = atof(fld->val);
	fld->i = len;

    return 1;
}

int JSON_Parse_Field(char **src, JSON_field *fld)
{
    if(!JSON_Parse_Symbol(src, '"'))
        return 0;
    if(!JSON_Parse_Name(src, fld))
        return 0;
    if(!JSON_Parse_Symbol(src, '"'))
        return 0;
    if(!JSON_Parse_Symbol(src, ':'))
        return 0;
    if(!JSON_Parse_Val(src, fld))
        return 0;

   return 1;
}

int JSON_Parse_Record(char **src)
{
    int fld_count = 0;
    JSON_field fld;

	memset(JSON_Record, 0, sizeof(JSON_Record));
	
    // Object Begin
    if(!JSON_Parse_Symbol(src, '{'))
        return 0;

    while(1)
    {
        // Object End
        if(**src == '}')
            break;

        // 字段之间的分隔符(,)
        if(fld_count > 0)
        {
            if(!JSON_Parse_Symbol(src, ','))
                return 0;
        }
        if(!JSON_Parse_Field(src, &fld))
            return 0;
        JSON_Record[fld_count++] = fld;
    }

    if(!JSON_Parse_Symbol(src, '}'))
        return 0;

    return 1;
}

