2020年9月

修改 /usr/share/thingsboard/conf/thingsboard.yml, 将 false 改成 true;

# Enable/disable SSL support
enabled: "${SSL_ENABLED:true}"

新建 /usr/share/thingsboard/conf/keystore 目录,且此目录下,增加自己的证书 keystore.p12,并授权 thingsboard 用户和组,命令行输入

mkdir /usr/share/thingsboard/conf/keystore 

keytool -genkey -alias tomcat \
-keystore keystore.p12 \
-storetype PKCS12 \
-keyalg RSA \
-validity 730 \
-keysize 2048

chown -R thingsboard:thingsboard /usr/share/thingsboard/conf/keystore

重启 thingsboard 即可

systemctl restart thingsboard

Chrome 下,无法访问自己制作的证书网站,方法在此

关于 Chrome 无法打开自定义的网站证书网站方法

Google Protocol Buffers ,一个非常高效的数据序列化工具,ava/Python/C++/C#等都是完美支持,可惜了,官方不支持C语言,还好世界强大,有人做了C语言版本:https://github.com/protobuf-c/protobuf-c

关于protobuf,请自行google或百度查询,这里不再啰嗦,进入正题。

1. 第一步:安装Protocol Buffers

https://developers.google.com/protocol-buffers/
很简单,download下来,编译即可;make && make install

2. 第二步:安装protobuf-c

https://github.com/protobuf-c/protobuf-c
也是很简单,download下来,编译即可;make && make install

当你输入 protoc-c 出现以下信息,代表安装成功。

jiekechoo:mqtt_protoc jiekechoo$ protoc-c 
Usage: protoc-c [OPTION] PROTO_FILES
Parse PROTO_FILES and generate output based on the options given:
  -IPATH, --proto_path=PATH   Specify the directory in which to search for
                              imports.  May be specified multiple times;
                              directories will be searched in order.  If not
                              given, the current working directory is used.
                              If not found in any of the these directories,
                              the --descriptor_set_in descriptors will be
                              checked for required proto file.
  --version                   Show version info and exit.
  -h, --help                  Show this text and exit.
  --encode=MESSAGE_TYPE       Read a text-format message of the given type
                              from standard input and write it in binary
                              to standard output.  The message type must
                              be defined in PROTO_FILES or their imports.
  --decode=MESSAGE_TYPE       Read a binary message of the given type from
                              standard input and write it in text format
                              to standard output.  The message type must
                              be defined in PROTO_FILES or their imports.
  --decode_raw                Read an arbitrary protocol message from
                              standard input and write the raw tag/value
                              pairs in text format to standard output.  No
                              PROTO_FILES should be given when using this
                              flag.
  --descriptor_set_in=FILES   Specifies a delimited list of FILES
                              each containing a FileDescriptorSet (a
                              protocol buffer defined in descriptor.proto).
                              The FileDescriptor for each of the PROTO_FILES
                              provided will be loaded from these
                              FileDescriptorSets. If a FileDescriptor
                              appears multiple times, the first occurrence
                              will be used.
  -oFILE,                     Writes a FileDescriptorSet (a protocol buffer,
    --descriptor_set_out=FILE defined in descriptor.proto) containing all of
                              the input files to FILE.
  --include_imports           When using --descriptor_set_out, also include
                              all dependencies of the input files in the
                              set, so that the set is self-contained.
  --include_source_info       When using --descriptor_set_out, do not strip
                              SourceCodeInfo from the FileDescriptorProto.
                              This results in vastly larger descriptors that
                              include information about the original
                              location of each decl in the source file as
                              well as surrounding comments.
  --dependency_out=FILE       Write a dependency output file in the format
                              expected by make. This writes the transitive
                              set of input file paths to FILE
  --error_format=FORMAT       Set the format in which to print errors.
                              FORMAT may be 'gcc' (the default) or 'msvs'
                              (Microsoft Visual Studio format).
  --print_free_field_numbers  Print the free field numbers of the messages
                              defined in the given proto files. Groups share
                              the same field number space with the parent 
                              message. Extension ranges are counted as 
                              occupied fields numbers.

  --c_out=OUT_DIR             Generate C/H files.
  @<filename>                 Read options and filenames from file. If a
                              relative file path is specified, the file
                              will be searched in the working directory.
                              The --proto_path option will not affect how
                              this argument file is searched. Content of
                              the file will be expanded in the position of
                              @<filename> as in the argument list. Note
                              that shell expansion is not applied to the
                              content of the file (i.e., you cannot use
                              quotes, wildcards, escapes, commands, etc.).
                              Each line corresponds to a single argument,
                              even if it contains spaces.

3. 测试protobuf

转换proto文件为 C 语言库

protoc-c --c_out=. kurapayload.proto

生成protoc文件

-rw-r--r--  1 jiekechoo  staff  14836  8 18 11:36 kurapayload.pb-c.c
-rw-r--r--  1 jiekechoo  staff   6427  8 18 11:36 kurapayload.pb-c.h
-rw-r--r--  1 jiekechoo  staff   1749  8 18 11:17 kurapayload.proto

完成protobuf集成工作

#include <stdio.h>
#include <stdlib.h>
#include "MQTTClient.h"
#include "kurapayload.pb-c.h"
 
void main()
{
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;

MQTTClient_create(&client, ADDRESS, CLIENTID,
    MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.username = "username";
conn_opts.password = "password";

if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
    printf("Failed to connect, return code %d\n", rc);
    exit(-1);
}
    Kuradatatypes__KuraPayload payload = KURADATATYPES__KURA_PAYLOAD__INIT;
    Kuradatatypes__KuraPayload__KuraMetric **metrics;
    Kuradatatypes__KuraPayload__KuraPosition position = KURADATATYPES__KURA_PAYLOAD__KURA_POSITION__INIT;
 
position.latitude = 1.1;
position.longitude = 1.1;

payload.position = &position;

metrics = malloc(sizeof (Kuradatatypes__KuraPayload__KuraMetric) * 2);
int i = 0;
for(i=0;i<2;i++)
{
    metrics[i] = malloc (sizeof (Kuradatatypes__KuraPayload__KuraMetric));
    kuradatatypes__kura_payload__kura_metric__init(metrics[i]);

    metrics[i]->name = (char*)EdcBirthPayloadNames[i];
    printf("%s, ", metrics[i]->name);
    metrics[i]->type = KURADATATYPES__KURA_PAYLOAD__KURA_METRIC__VALUE_TYPE__STRING;        
    metrics[i]->string_value = (char*)EdcBirthPayloadValues[i];
    printf("%s\r\n", metrics[i]->string_value);
}
    payload.n_metric = 2;
    payload.metric = metrics;

    size_t len = kuradatatypes__kura_payload__get_packed_size(&payload);
    void* data = malloc(len); 
    kuradatatypes__kura_payload__pack(&payload, data);
    pubmsg.payload = data;
    pubmsg.payloadlen = kuradatatypes__kura_payload__get_packed_size(&payload);
    MQTTClient_publishMessage(client, BIRTH_TOPIC, &pubmsg, &token);

}

编译,如果没有出错就上成功。

gcc kurapayload.pb-c.c main.c -lprotobuf-c

4. 注意事项

  • 系统要能够使用 malloc 功能,好多地方要用到;
  • 结构体初始化 INIT 或 使用 init 函数;
  • 数据准备完毕,要 pack 一下,再 packed_size 计算长度,后面该怎么处理都行了;

最终,C 语言版本的 Kura 模拟器成功连接 Kapua。
1761599121932_.pic_hd.jpg