Programming languages

Python Cloudflare DNS A record update example

This script updates a DNS A record (IPv4 address) using the Cloudflare Python API. It expects the A record to be present already.

Also see Python Cloudflare DNS A record create or update example for a variant of this script which creates the record if it doesn’t exist already.

#!/usr/bin/env python3
import CloudFlare
import argparse
import sys

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--email", required=True, help="The Cloudflare login email to use")
    parser.add_argument("-n", "--hostname", required=True, help="The hostname to update, e.g. mydyndns.mydomain.com")
    parser.add_argument("-k", "--api-key", required=True, help="The Cloudflare global API key to use. NOTE: Domain-specific API tokens will NOT work!")
    parser.add_argument("-i", "--ip-address", required=True, help="Which IP address to update the record to")
    parser.add_argument("-t", "--ttl", default=60, type=int, help="The TTL of the records in seconds (or 1 for auto)")
    args = parser.parse_args()

    # Initialize Cloudflare API client
    cf = CloudFlare.CloudFlare(
        email=args.email,
        token=args.api_key
    )
    # Get zone ID (for the domain). This is why we need the API key and the domain API token won't be sufficient
    zone = ".".join(args.hostname.split(".")[-2:]) # domain = test.mydomain.com => zone = mydomain.com
    zones = cf.zones.get(params={"name": zone})
    if len(zones) == 0:
        print(f"Could not find CloudFlare zone {zone}, please check domain {args.hostname}")
        sys.exit(2)
    zone_id = zones[0]["id"]

    # Fetch existing A record
    a_record = cf.zones.dns_records.get(zone_id, params={"name": args.hostname, "type": "A"})[0]

    # Update record & save to cloudflare
    a_record["ttl"] = args.ttl # 1 == auto
    a_record["content"] = args.ip_address
    cf.zones.dns_records.put(zone_id, a_record["id"], data=a_record)

Usage example:

./update-dns.py --api-key ... --email [email protected] --ttl 300 --ip 1.2.3.4 --hostname mysubdomain.domain.com

 

Posted by Uli Köhler in Networking, Python

How to get Jitsi meet list of participants using Tapermonkey script

Use this code in Javascript:

APP.conference.listMembers()

If no members are present, this will simply be an empty list:

> APP.conference.listMembers()
[]

But if there is another participant, it will show some info:

> APP.conference.listMembers()
[ci]
0: ci {_jid: '[email protected]/b009ae10', _id: 'b009ae10', _conference: nd, _displayName: 'Foo', _supportsDTMF: false, …}
length: 1

 

Posted by Uli Köhler in Audio/Video, Javascript

How to autojoin Jitsi Meet meeting using Tapermonkey script

This code clicks the join button:

document.querySelector(".prejoin-preview-dropdown-container div[role='button']").click()

By using the correct @match, you can activate this only for a specific conference:

Complete script:

// ==UserScript==
// @name         AutojoinJitsiMeet
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  ?
// @author       You
// @match        https://meet.jit.si/TestAutoJoin
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    document.querySelector(".prejoin-preview-dropdown-container div[role='button']").click()
})();

 

Posted by Uli Köhler in Audio/Video, Javascript

NodeJS typescript simple auto-reload on file change

First install ts-node-dev:

npm i --save-dev ts-node-dev

Then add

"start": "./node_modules/.bin/tsnd --respawn app.ts"

to package.json in the scripts section, example:

{
  "name": "myapp-backend",
  "version": "1.0.0",
  "description": "To make it easy for you to get started with GitLab, here's a list of recommended next steps.",
  "main": "index.js",
  "scripts": {
    "build": "./node_modules/.bin/tsc -b tsconfig.json",
    "start": "./node_modules/.bin/tsnd --respawn app.ts"
  }
  /* ... */
}

 

Posted by Uli Köhler in Javascript, NodeJS

How to find array index closest to a given value using NumPy

Let’s say you have an 1D array like

arr = np.linspace(0, 10, 100)

and you wanted to find the array index where the value is closest to 8.5.

You can do this by first computing the absolute difference to 8.5:

np.abs(arr - 8.5)

and now using np.argmin to find the array index where the value is minimal (i.e. the index where the value of arr is closest to 8.5)

np.argmin(np.abs(arr - 8.5))

 

Posted by Uli Köhler in Python

How to create NumPy XY array from X and Y array (zip equivalent)

If you have two 1D arrays x and y of the same length n = x.shape[0] in Python, this is how you can create a shape (n, 2) array using numpy similar to the way Python’s zip does it with list objects:

xy = np.stack((x, y), axis=1)
Posted by Uli Köhler in Python

How to DC-sweep resistive voltage divider using PySpice

The following code simulates a resistive 10kΩ / 1kΩ voltage divider using PySpice using a DC sweep and can serve as a suitable starting point for simulating simple circuits. We sweep from 0V to 5V in steps of 10mV.

Also see our previous post How to simulate resistive voltage divider using PySpice for an alternate version using transient analysis:

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

from PySpice.Probe.Plot import plot
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *

circuit = Circuit("MyCircuit")
# Create voltage source: 5V DC
source = circuit.VoltageSource('in', 'in', circuit.gnd, dc_value=5@u_V)
# Create resistor divider
r1 = circuit.R('R1', 'in', 'n1', 10@u_kΩ)
r2 = circuit.R('R2', 'n1', circuit.gnd, 1@u_kΩ)
# Simulate for 1 second with steps of 1 millisecond
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.dc(Vin=slice(0, 5.0, 0.01))

You can access the array of output voltages of the divider (i.e. node n1) using analysis['n1']Keep in mind that if the first argument of circuit.VoltageSource is 'in', the argument to simulator.dc will be valled Vin,  not just  in! A Vwill automatically be  prepended!

 

This is the code we used to plot this:

import matplotlib.ticker as mtick
import matplotlib.pyplot as plt
from UliEngineering.EngineerIO import format_value

def format_volts(value, pos=None):
    return format_value(value, 'V')

plt.style.use("ggplot")
plt.xlabel("Input voltage")
plt.xlabel("Divider output voltage")
plt.gca().yaxis.set_major_formatter(mtick.FuncFormatter(format_volts))
plt.gca().xaxis.set_major_formatter(mtick.FuncFormatter(format_volts))
plt.gcf().set_size_inches(8,5)
plt.plot(analysis["in"], analysis["n1"], label="Input voltage")
plt.savefig("/ram/PySpice-Voltage-Divider-Sweep.svg")
Posted by Uli Köhler in Electronics, Python, SPICE

How to simulate resistive voltage divider using PySpice

The following code simulates a resistive 10kΩ / 1kΩ voltage divider using PySpice and can serve as a good starting point for simulating simple circuits.

This post shows you how to simulate the voltage divider using transient analysis. Also see an alternative variant of this post using DC sweep analysis instead: How to DC-sweep resistive voltage divider using PySpice

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

from PySpice.Probe.Plot import plot
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *

circuit = Circuit("MyCircuit")
# Create voltage source: 5V DC
source = circuit.VoltageSource('V1', 'in', circuit.gnd, dc_value=5@u_V)
# Create resistor divider
r1 = circuit.R('R1', 'in', 'n1', 10@u_kΩ)
r2 = circuit.R('R2', 'n1', circuit.gnd, 1@u_kΩ)
# Simulate for 1 second with steps of 1 millisecond
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.transient(step_time=1@u_ms, end_time=1@u_s)

You can access the array of output voltages of the divider (i.e. node n1) using analysis['n1']:

This is the code we used to plot this:

import matplotlib.ticker as mtick
import matplotlib.pyplot as plt
from UliEngineering.EngineerIO import format_value

def format_volts(value, pos=None):
    return format_value(value, 'V')

plt.style.use("ggplot")
plt.xlabel("Time [ms]")
plt.ylim([0.0, 5.5])
plt.gca().yaxis.set_major_formatter(mtick.FuncFormatter(format_volts))
plt.gcf().set_size_inches(8,5)
plt.plot(analysis["in"], label="Input voltage")
plt.plot(analysis["n1"], label="Voltage divider output")
plt.gca().legend()
plt.savefig("/ram/PySpice-Voltage-Divider.svg")

 

Posted by Uli Köhler in Electronics, Python, SPICE

How to create resistor in PySpice: Minimal example

This creates a resistor named R1 which has its + pin connected to node n1 and its - pin connected to GND. The value of the resistor is set to 1kΩ.

r1 = circuit.R('R1', 'n1', circuit.gnd, 1@u_kΩ)

Full example:

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

from PySpice.Probe.Plot import plot
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *

circuit = Circuit("MyCircuit")
r1 = circuit.R('R1', 'n1', circuit.gnd, 1@u_kΩ)

 

Posted by Uli Köhler in Electronics, Python, SPICE

How to create constant voltage source in PySpice

This creates a voltage source named V1 which has its + pin connected to node n1 and its - pin connected to GND. The voltage source is set to 5V DC.

source = circuit.VoltageSource('V1', 'n1', circuit.gnd, dc_value=5@u_V)

Full example:

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

from PySpice.Probe.Plot import plot
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *

circuit = Circuit("MyCircuit")
source = circuit.VoltageSource('V1', 'n1', circuit.gnd, dc_value=5@u_V)

 

Posted by Uli Köhler in Electronics, Python, SPICE

How to replace numpy NaNs by last non-NaN value

Use bottleneck.push:

import bottleneck

y = bottleneck.push(y, axis=0)

If not installed already, you can install bottleneck using

pip install bottleneck

 

Posted by Uli Köhler in Python

How to set matplotlib X axis timestamp format to hours and minutes

import matplotlib.dates as mdates

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

 

Posted by Uli Köhler in Python

How to change matplotlib X axis timestamp format

Sometimes you get weird timestamp format choices in Matplotlib such as 22 19:40 (meaning 19:40 o’clock on the 22nd of whatever month).

This is easy to fix:

import matplotlib.dates as mdates

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

which will result in this image, for example:

Posted by Uli Köhler in Python

How to get first day of next month in Javascript using DayJS

See the dayjs docs for more info about the library.

const now = dayjs();
const nextMonth = now.month(now.month() + 1).date(1).hour(0).minute(0).second(0);

// Example usage
console.info(nextMonth.format())
// Prints, for example, "2022-03-01T00:00:00+01:00"

This will also work in december as DayJS processes month(13) correctly:

const now = dayjs('2021-12-09');
const nextMonth = now.month(now.month() + 1).date(1).hour(0).minute(0).second(0);

// This prints '2022-01-01T00:00:00+01:00'
console.info(nextMonth.format());

 

Posted by Uli Köhler in Javascript

How to reverse std::string using std::reverse (C++)

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main(int argc, char** argv) {
    std::string s = "My string";
    // This reverses s in-place.
    std::reverse(std::begin(s), std::end(s));
    // Prints "gnirts yM"
    cout << s << endl;
}

 

Posted by Uli Köhler in C/C++

re2 C++ replace (GlobalReplace) minimal example

This minimal example shows how to replace strings using the re2 GlobalReplace() function:

#include <re2/re2.h>
#include <iostream>
#include <string>

using namespace re2;
using namespace std;

// Pre-compiled regex
RE2 myRegex("\\$[^\\$]+\\$");

int main(int argc, char** argv) {
    string myString = "This string $abc123$ contains two formulas $123 != 456$.";
    // NOTE: This will modify myString!
    RE2::GlobalReplace(&myString, myRegex, "FORMULA");
    // Prints "This string FORMULA contains two formulas FORMULA."
    cout << myString << endl;
}

 

Posted by Uli Köhler in C/C++

re2 C++ regular expressions library: How to #include?

#include <re2/re2.h>

using namespace re2;

 

Posted by Uli Köhler in C/C++

cpp-httplib: How to get query parameters

This example shows how to get a query parameter in cpp-httplib. See the cpp-httplib hello example for the full source code:

svr.Get("/hi", [](const httplib::Request& req, httplib::Response& res) {
    std::string id = req.get_param_value("id");
    res.set_content("id=" + id, "text/plain");
});

Access it at http://localhost:8080/hi?id=myid

and it will show you

id=myid

id will be empty (== "") if no such parameter is given.

Posted by Uli Köhler in C/C++

How to fix Paho MQTT undefined reference to `SHA1_Init’

Problem:

When trying to build your C++ application using Paho MQTT, you see a bunch of undefined reference error messages:

MQTTAsync.c:(.text+0x3482): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34a1): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34c0): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34df): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34fe): undefined reference to `OpenSSL_version'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(MQTTAsyncUtils.c.o): in function `MQTTAsync_closeOnly':
MQTTAsyncUtils.c:(.text+0x9b6): undefined reference to `SSL_SESSION_free'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(MQTTAsyncUtils.c.o): in function `MQTTAsync_receiveThread':
MQTTAsyncUtils.c:(.text+0x463b): undefined reference to `SSL_set_session'
/usr/bin/ld: MQTTAsyncUtils.c:(.text+0x5255): undefined reference to `SSL_get1_session'
/usr/bin/ld: MQTTAsyncUtils.c:(.text+0x55bb): undefined reference to `SSL_get1_session'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `call_ssl_psk_cb':
SSLSocket.c:(.text+0x11b): undefined reference to `SSL_get_SSL_CTX'
/usr/bin/ld: SSLSocket.c:(.text+0x129): undefined reference to `SSL_CTX_get_ex_data'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_error':
SSLSocket.c:(.text+0x1fa): undefined reference to `SSL_get_error'
/usr/bin/ld: SSLSocket.c:(.text+0x22d): undefined reference to `ERR_print_errors_cb'
/usr/bin/ld: SSLSocket.c:(.text+0x2f1): undefined reference to `ERR_get_error'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSL_CTX_info_callback':
SSLSocket.c:(.text+0x376): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x381): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x3bc): undefined reference to `SSL_get_verify_result'
/usr/bin/ld: SSLSocket.c:(.text+0x411): undefined reference to `SSL_state_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x461): undefined reference to `SSL_get_current_cipher'
/usr/bin/ld: SSLSocket.c:(.text+0x469): undefined reference to `SSL_CIPHER_get_name'
/usr/bin/ld: SSLSocket.c:(.text+0x474): undefined reference to `SSL_state_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x4d1): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x4dc): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x4e7): undefined reference to `SSL_state_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x503): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x50e): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x541): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x54c): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_initialize':
SSLSocket.c:(.text+0x8ee): undefined reference to `OPENSSL_init_ssl'
/usr/bin/ld: SSLSocket.c:(.text+0x90a): undefined reference to `OPENSSL_init_crypto'
/usr/bin/ld: SSLSocket.c:(.text+0x916): undefined reference to `OPENSSL_init_ssl'
/usr/bin/ld: SSLSocket.c:(.text+0x922): undefined reference to `OPENSSL_init_crypto'
/usr/bin/ld: SSLSocket.c:(.text+0xa11): undefined reference to `CRYPTO_get_ex_new_index'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_createContext':
SSLSocket.c:(.text+0xbee): undefined reference to `SSL_CTX_use_certificate_chain_file'
/usr/bin/ld: SSLSocket.c:(.text+0xc48): undefined reference to `SSL_CTX_set_default_passwd_cb'
/usr/bin/ld: SSLSocket.c:(.text+0xc55): undefined reference to `SSL_CTX_set_default_passwd_cb_userdata'
/usr/bin/ld: SSLSocket.c:(.text+0xc67): undefined reference to `SSL_CTX_use_PrivateKey_file'
/usr/bin/ld: SSLSocket.c:(.text+0xc9a): undefined reference to `SSL_CTX_load_verify_locations'
/usr/bin/ld: SSLSocket.c:(.text+0xce5): undefined reference to `SSL_CTX_set_default_verify_paths'
/usr/bin/ld: SSLSocket.c:(.text+0xd2e): undefined reference to `SSL_CTX_set_cipher_list'
/usr/bin/ld: SSLSocket.c:(.text+0xd56): undefined reference to `SSL_CTX_set_ex_data'
/usr/bin/ld: SSLSocket.c:(.text+0xd66): undefined reference to `SSL_CTX_set_psk_client_callback'
/usr/bin/ld: SSLSocket.c:(.text+0xd8f): undefined reference to `SSL_CTX_ctrl'
/usr/bin/ld: SSLSocket.c:(.text+0xdc5): undefined reference to `SSL_CTX_free'
/usr/bin/ld: SSLSocket.c:(.text+0xe51): undefined reference to `SSL_CTX_set_alpn_protos'
/usr/bin/ld: SSLSocket.c:(.text+0xeb9): undefined reference to `TLS_client_method'
/usr/bin/ld: SSLSocket.c:(.text+0xec1): undefined reference to `SSL_CTX_new'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_setSocketForSSL':
SSLSocket.c:(.text+0x1046): undefined reference to `SSL_CTX_set_info_callback'
/usr/bin/ld: SSLSocket.c:(.text+0x1056): undefined reference to `SSL_CTX_set_msg_callback'
/usr/bin/ld: SSLSocket.c:(.text+0x1075): undefined reference to `SSL_new'
/usr/bin/ld: SSLSocket.c:(.text+0x10ab): undefined reference to `SSL_get_cipher_list'
/usr/bin/ld: SSLSocket.c:(.text+0x10be): undefined reference to `SSL_set_fd'
/usr/bin/ld: SSLSocket.c:(.text+0x113b): undefined reference to `SSL_ctrl'
/usr/bin/ld: SSLSocket.c:(.text+0x121c): undefined reference to `SSL_CTX_set_verify'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_connect':
SSLSocket.c:(.text+0x12b7): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x12bf): undefined reference to `SSL_connect'
/usr/bin/ld: SSLSocket.c:(.text+0x135d): undefined reference to `SSL_get_peer_certificate'
/usr/bin/ld: SSLSocket.c:(.text+0x138c): undefined reference to `X509_check_host'
/usr/bin/ld: SSLSocket.c:(.text+0x13d4): undefined reference to `CRYPTO_free'
/usr/bin/ld: SSLSocket.c:(.text+0x13f6): undefined reference to `X509_free'
/usr/bin/ld: SSLSocket.c:(.text+0x144d): undefined reference to `X509_check_ip_asc'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_getch':
SSLSocket.c:(.text+0x1569): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1579): undefined reference to `SSL_read'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_destroyContext':
SSLSocket.c:(.text+0x1630): undefined reference to `SSL_CTX_free'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_close':
SSLSocket.c:(.text+0x16b8): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x16c1): undefined reference to `SSL_shutdown'
/usr/bin/ld: SSLSocket.c:(.text+0x16ce): undefined reference to `SSL_free'
/usr/bin/ld: SSLSocket.c:(.text+0x16fd): undefined reference to `SSL_CTX_free'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_putdatas':
SSLSocket.c:(.text+0x191f): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1930): undefined reference to `SSL_write'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_getdata':
SSLSocket.c:(.text+0x1ca5): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1cb8): undefined reference to `SSL_read'
/usr/bin/ld: SSLSocket.c:(.text+0x1d7f): undefined reference to `SSL_pending'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_continueWrite':
SSLSocket.c:(.text+0x1e2f): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1e3f): undefined reference to `SSL_write'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(Base64.c.o): in function `Base64_encodeDecode.part.0':
Base64.c:(.text+0x1f): undefined reference to `BIO_f_base64'
/usr/bin/ld: Base64.c:(.text+0x27): undefined reference to `BIO_new'
/usr/bin/ld: Base64.c:(.text+0x2f): undefined reference to `BIO_s_mem'
/usr/bin/ld: Base64.c:(.text+0x37): undefined reference to `BIO_new'
/usr/bin/ld: Base64.c:(.text+0x45): undefined reference to `BIO_push'
/usr/bin/ld: Base64.c:(.text+0x55): undefined reference to `BIO_set_flags'
/usr/bin/ld: Base64.c:(.text+0x78): undefined reference to `BIO_write'
/usr/bin/ld: Base64.c:(.text+0x8e): undefined reference to `BIO_ctrl'
/usr/bin/ld: Base64.c:(.text+0x9e): undefined reference to `BIO_free_all'
/usr/bin/ld: Base64.c:(.text+0xc1): undefined reference to `BIO_read'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `WebSocket_buildFrame.constprop.0':
WebSocket.c:(.text+0x441): undefined reference to `RAND_bytes'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `uuid_generate':
WebSocket.c:(.text+0x721): undefined reference to `RAND_bytes'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `WebSocket_connect':
WebSocket.c:(.text+0x929): undefined reference to `RAND_bytes'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `WebSocket_upgrade':
WebSocket.c:(.text+0x1dd9): undefined reference to `SHA1_Init'
/usr/bin/ld: WebSocket.c:(.text+0x1def): undefined reference to `SHA1_Update'
/usr/bin/ld: WebSocket.c:(.text+0x1dff): undefined reference to `SHA1_Final'
collect2: error: ld returned 1 exit status

Solution

In addition to linking the Paho MQTT libraries, you also need to link OpenSSL, i.e. the ssl and crypto libraries. You can link them, for example using

target_link_libraries(myexecutable ssl crypto)

in CMake or by adding these linker flags for GCC:

-lssl -lcrypto

 

Posted by Uli Köhler in C/C++

How to link Paho MQTT C++ binding using CMake

target_link_libraries(myexecutable paho-mqttpp3 paho-mqtt3as ssl crypto)

 

Posted by Uli Köhler in C/C++, MQTT