obuspc: USP based controller

This commit is contained in:
Vivek Kumar Dutta 2023-05-15 15:56:18 +05:30
parent 69d2a50e2e
commit f2f3f34859
No known key found for this signature in database
GPG key ID: 65C818099F37097D
4 changed files with 471 additions and 0 deletions

72
obuspc/Makefile Normal file
View file

@ -0,0 +1,72 @@
#
# Copyright (C) 2023 IOPSYS Software Solutions AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=obuspc
PKG_VERSION:=1.0.1.1
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/obuspa-test-controller.git
PKG_SOURCE_VERSION:=f1f721bc1a4feaf63c7f7837eb7b0c86111e2f71
PKG_MAINTAINER:=Vivek Dutta <vivek.dutta@iopsys.eu>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_FIXUP:=autoreconf
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
define Package/obuspc
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=USP Controller
DEPENDS:=+libopenssl +libuci +libblobmsg-json +libcurl +libsqlite3 +libubox +libubus +libmosquitto-ssl +libwebsockets-openssl
endef
define Package/obuspc/description
OB-USP-Controller is a local usp controller based on User Services Platform (USP).
endef
TARGET_CFLAGS += \
-D_GNU_SOURCE \
-Wall \
-Werror
CONFIGURE_ARGS += \
--localstatedir="/tmp/" \
--enable-stomp \
--enable-coap \
--enable-mqtt \
--enable-websockets
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/obuspa-test-controller/* $(PKG_BUILD_DIR)/
$(Build/Patch)
endef
endif
define Package/obuspc/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/bbfdm/json
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/obuspc $(1)/usr/sbin/
$(INSTALL_BIN) ./files/etc/init.d/obuspc $(1)/etc/init.d/
$(INSTALL_BIN) ./files/etc/uci-defaults/99-fix-agent-endpoint $(1)/etc/uci-defaults/
$(INSTALL_DATA) ./files/etc/config/obuspc $(1)/etc/config/
endef
$(eval $(call BuildPackage,obuspc))

View file

@ -0,0 +1,19 @@
config obuspc 'global'
option enabled '1'
option debug '1'
option log_level '1'
option prototrace '1'
config mqtt 'mqtt'
option BrokerAddress '127.0.0.1'
option BrokerPort '1883'
option TransportProtocol 'TCP/IP'
config controller 'controller'
option EndpointID 'proto::interop-usp-controller'
option Protocol 'MQTT'
option ResponseTopicConfigured '/usp/controller'
option mqtt 'mqtt'
config agent 'agent'
option Topic '/usp/endpoint'

349
obuspc/files/etc/init.d/obuspc Executable file
View file

@ -0,0 +1,349 @@
#!/bin/sh /etc/rc.common
START=99
STOP=01
USE_PROCD=1
PROG=/usr/sbin/obuspc
CONFIGURATION=obuspc
RESET_FILE="/tmp/usp/obuspc_param_reset.txt"
SQL_DB_FILE="/tmp/usp/uspc.db"
BASEPATH=""
INSTANCE_COUNT=0
. /usr/share/libubox/jshn.sh
global_init()
{
BASEPATH=""
INSTANCE_COUNT=0
}
log()
{
echo "$*"|logger -t obuspc.init -p debug
}
db_set_reset_file()
{
local param value
param="${1}"
shift
value="$*"
if [ -n "${param}" ] && [ -n "${value}" ]; then
echo "${param} \"${value}\"">>${RESET_FILE}
else
echo >>${RESET_FILE}
fi
}
db_set()
{
db_set_reset_file "$@"
}
# if db present then check if it matches with existing instances
# fallback to max instance present + 1
# In case of no db get the count
get_base_path()
{
local refpath value path count
refpath="${1}"
value="${2}"
path=""
count=0
if [ -z "${path}" ]; then
INSTANCE_COUNT=$(( INSTANCE_COUNT + 1 ))
path="${refpath}${INSTANCE_COUNT}"
fi
BASEPATH="${path}"
}
get_refrence_path()
{
local dmref value path
dmref="${1}"
value="${2}"
path=""
path=$(grep "${dmref}\d.Alias " ${RESET_FILE}|grep -w "${value}")
path=${path%.*}
echo "${path}"
}
validate_global_section()
{
uci_validate_section ${CONFIGURATION} obuspc "${1}" \
'enabled:bool:1' \
'debug:bool:0' \
'prototrace:bool:0' \
'log_level:uinteger' \
'log_dest:string' \
'db_file:string'
}
validate_mqtt_client_section()
{
uci_validate_section ${CONFIGURATION} mqtt "${1}" \
'Enable:bool:1' \
'BrokerAddress:string' \
'BrokerPort:port:1883' \
'Username:string' \
'Password:string' \
'ProtocolVersion:or("3.1", "3.1.1","5.0"):5.0' \
'TransportProtocol:or("TCP/IP","TLS"):TCP/IP' \
'ClientID:string'
}
validate_controller_section()
{
uci_validate_section ${CONFIGURATION} mtp "${1}" \
'EndpointID:string' \
'Protocol:or("MQTT", "WebSocket")' \
'ResponseTopicConfigured:string' \
'Destination:string' \
'Port:port' \
'Path:string' \
'mqtt:string' \
'stomp:string' \
'Reference:string' \
'EnableEncryption:bool:0'
}
configure_controller() {
local EndpointID Protocol ResponseTopicConfigured
local Destination Path Port EnableEncryption Reference
local stomp mqtt dm_ref sec
sec="${1}"
validate_controller_section "${1}" || {
log "Validation of mtp section failed"
return 1;
}
if [ -z "${EndpointID}" ]; then
log "EndpointID not defined for controller"
return 1;
fi
db_set Device.LocalAgent.EndpointID "${EndpointID}"
sec="${sec/mtp_/cpe-}"
get_base_path "Device.LocalAgent.MTP." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
fi
if [ -z "${Protocol}" ]; then
log "Protocol not defined for the mtp[${1}] section"
return 1;
fi
dm_ref=""
if [ -z "${Reference}" ]; then
if [ "${Protocol}" = "STOMP" ]; then
stomp="${stomp/stomp_/cpe-}"
dm_ref=$(get_refrence_path "Device.STOMP.Connection." "${stomp}")
elif [ "${Protocol}" = "MQTT" ]; then
mqtt="${mqtt/mqtt_/cpe-}"
dm_ref=$(get_refrence_path "Device.MQTT.Client." "${mqtt}")
fi
else
dm_ref="${Reference}"
fi
db_set "${BASEPATH}.Alias" "${sec}"
db_set "${BASEPATH}.Enable" "1"
db_set "${BASEPATH}.Protocol" "${Protocol}"
if [ "${Protocol}" = "MQTT" ]; then
db_set "${BASEPATH}.MQTT.Reference" "${dm_ref}"
db_set "${BASEPATH}.MQTT.ResponseTopicConfigured" "${ResponseTopicConfigured}"
elif [ "${Protocol}" = "STOMP" ]; then
db_set "${BASEPATH}.STOMP.Reference" "${dm_ref}"
db_set "${BASEPATH}.STOMP.Destination" "${Destination}"
elif [ "${Protocol}" = "CoAP" ]; then
db_set "${BASEPATH}.CoAP.Path" "${Path}"
db_set "${BASEPATH}.CoAP.Port" "${Port}"
elif [ "${Protocol}" = "WebSocket" ]; then
db_set "${BASEPATH}.WebSocket.Path" "${Path}"
db_set "${BASEPATH}.WebSocket.Port" "${Port}"
db_set "${BASEPATH}.WebSocket.EnableEncryption" "${EnableEncryption}"
fi
db_set
}
validate_agent_section()
{
uci_validate_section ${CONFIGURATION} agent "${1}" \
'name:string' \
'EndpointID:string' \
'Topic:string'
}
configure_agent() {
local EndpointID Topic name
local stomp mqtt dm_ref sec
sec="${1}"
validate_agent_section "${1}" || {
log "Validation of agent section failed"
return 1;
}
if [ -z "${EndpointID}" ]; then
log "EndpointID not defined for agent"
return 1;
fi
if [ -z "${Topic}" ]; then
log "Topic not defined for agent"
return 1;
fi
sec="${sec/mtp_/cpe-}"
get_base_path "Device.LocalAgent.Controller." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
fi
db_set "${BASEPATH}.Alias" "${sec}"
db_set "${BASEPATH}.Enable" "1"
db_set "${BASEPATH}.EndpointID" "${EndpointID}"
db_set "${BASEPATH}.MTP.1.Enable" "1"
db_set "${BASEPATH}.MTP.1.Protocol" "MQTT"
db_set "${BASEPATH}.MTP.1.MQTT.Reference" "Device.MQTT.Client.1"
db_set "${BASEPATH}.MTP.1.MQTT.Topic" "${Topic}"
db_set
}
configure_mqtt_client() {
local BrokerAddress BrokerPort Enable Username Password ProtocolVersion
local TransportProtocol ClientID
local sec
sec="${1}"
validate_mqtt_client_section "${1}" || {
log "Validation of mqtt section failed"
return 1;
}
sec="${sec/mqtt_/cpe-}"
get_base_path "Device.MQTT.Client." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
fi
db_set "${BASEPATH}.Alias" "${sec}"
db_set "${BASEPATH}.Enable" "${Enable}"
db_set "${BASEPATH}.BrokerAddress" "${BrokerAddress}"
db_set "${BASEPATH}.BrokerPort" "${BrokerPort}"
db_set "${BASEPATH}.Username" "${Username}"
db_set "${BASEPATH}.Password" "${Password}"
db_set "${BASEPATH}.ProtocolVersion" "${ProtocolVersion}"
db_set "${BASEPATH}.TransportProtocol" "${TransportProtocol}"
db_set "${BASEPATH}.ClientID" "${ClientID}"
db_set
}
configure_obuspc() {
local enabled trust_cert ifname interface debug prototrace log_level db_file log_dest
local client_cert
validate_global_section "global"
if [ "${debug}" -ne "0" ]; then
# Forward stdout of the command to logd
procd_set_param stdout 1
# Same for stderr
procd_set_param stderr 1
fi
procd_append_param command -u
if [ "${prototrace}" -eq 1 ]; then
procd_append_param command -p
fi
if [ -n "${log_level}" ]; then
procd_append_param command -v "${log_level}"
fi
if [ -n "${log_dest}" ]; then
procd_append_param command -l "${log_dest}"
fi
if [ -f "${RESET_FILE}" ]; then
procd_append_param command -r ${RESET_FILE}
fi
}
# Create factory reset file
db_init()
{
# Load configuration
config_load $CONFIGURATION
config_get SQL_DB_FILE global db_file "/tmp/usp/uspc.db"
# Remove DB and generate from uci
[ -f "${SQL_DB_FILE}" ] && rm -f "${SQL_DB_FILE}"
# Remove reset file if present
[ -f "${RESET_FILE}" ] && rm -f ${RESET_FILE}
config_load $CONFIGURATION
global_init
config_foreach configure_mqtt_client mqtt
global_init
config_foreach configure_controller controller
global_init
config_foreach configure_agent agent
return 0;
}
register_service()
{
procd_open_instance ${CONFIGURATION}
procd_set_param command ${PROG}
configure_obuspc
procd_set_param respawn \
"${respawn_threshold:-5}" \
"${respawn_timeout:-10}" "${respawn_retry:-3}"
procd_close_instance
}
start_service() {
local enabled
config_load ${CONFIGURATION}
config_get_bool enabled global enabled 0
if [ "${enabled}" -eq 0 ]; then
return 0;
fi
mkdir -p /tmp/usp/
db_init
register_service
}
stop_service() {
${PROG} -c stop >/dev/null 2>&1
}
service_triggers() {
procd_add_reload_trigger "obuspc"
}

View file

@ -0,0 +1,31 @@
#!/bin/sh
. /lib/functions.sh
get_oui_from_db()
{
db -q get device.deviceinfo.ManufacturerOUI
}
get_serial_from_db()
{
db -q get device.deviceinfo.SerialNumber
}
fix_agent_endpoint()
{
local AgentEndpointID serial oui user pass
# Get endpoint id from obuspa config first
config_load obuspa
config_get AgentEndpointID localagent EndpointID ""
if [ -z "${AgentEndpointID}" ]; then
serial=$(get_serial_from_db)
oui=$(get_oui_from_db)
AgentEndpointID="os::${oui}-${serial//+/%2B}"
fi
uci -q set obuspc.agent.EndpointID="${AgentEndpointID}"
}
fix_agent_endpoint