Skip to content
Snippets Groups Projects
common.c 4.17 KiB
Newer Older
  • Learn to ignore specific revisions
  • Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    /*
     * Copyright (C) 2025 iopsys Software Solutions AB
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU Lesser General Public License version 2.1
     * as published by the Free Software Foundation
     *
     *	  Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
     *
     */
    
    #include <string.h>
    #include <libubox/blobmsg_json.h>
    
    #include "common.h"
    
    int g_log_level = LOG_ERR;
    
    
    void init_rand_seed(void)
    {
    	srandom((unsigned int)time(NULL));
    }
    
    int rand_in_range(int min, int max)
    {
    	int range;
    
    	if (min >= max)
    		return -1;
    
    	if (min == (max - 1))
    		return min;
    
    	range = max - min;
    
    	return min + ((int)(((double)range) * ((double)random()) /
    			(((double)RAND_MAX) + 1.0)));
    }
    
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    unsigned int get_proto_type(const char *proto)
    {
    	int type = BBFDMD_BOTH;
    
    	if (proto) {
    		if (strcmp(proto, "cwmp") == 0)
    			type = BBFDMD_CWMP;
    		else if (strcmp(proto, "usp") == 0)
    			type = BBFDMD_USP;
    		else
    			type = BBFDMD_BOTH;
    	}
    
    	return type;
    }
    
    
    static bool is_raw_format_type(const char *format)
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    {
    
    	bool raw_format = false;
    
    	if (format) {
    		if (strcmp(format, "raw") == 0)
    			raw_format = true;
    		else
    			raw_format = false;
    	}
    
    	return raw_format;
    }
    
    void fill_optional_input(struct blob_attr *msg, unsigned int *proto, bool *raw_format)
    {
    	struct blob_attr *tb[2] = {0};
    	const struct blobmsg_policy p[2] = {
    			{ "proto", BLOBMSG_TYPE_STRING },
    			{ "format", BLOBMSG_TYPE_STRING }
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    	};
    
    
    	*proto = BBFDMD_BOTH;
    	*raw_format = false;
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    
    	if (!msg)
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    
    
    	blobmsg_parse(p, 2, tb, blobmsg_data(msg), blobmsg_len(msg));
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    
    	if (tb[0]) {
    		const char *val = blobmsg_get_string(tb[0]);
    
    		*proto = get_proto_type(val);
    
    	if (tb[1]) {
    		const char *val = blobmsg_get_string(tb[1]);
    		*raw_format = is_raw_format_type(val);
    	}
    }
    
    struct blob_attr *get_results_array(struct blob_attr *msg)
    {
    	struct blob_attr *tb[1] = {0};
    	const struct blobmsg_policy p[1] = {
    			{ "results", BLOBMSG_TYPE_ARRAY }
    	};
    
    	if (msg == NULL)
    		return NULL;
    
    	blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
    
    	return tb[0];
    
    bool str_match(const char *string, const char *pattern, size_t nmatch, regmatch_t pmatch[])
    {
    	regex_t re;
    
    	if (!string || !pattern)
    		return false;
    
    	if (regcomp(&re, pattern, REG_EXTENDED) != 0)
    		return false;
    
    	int status = regexec(&re, string, nmatch, pmatch, 0);
    
    	regfree(&re);
    
    	return (status != 0) ? false : true;
    }
    
    bool proto_match(unsigned int dm_type, const enum bbfdmd_type_enum type)
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    {
    	return (dm_type == BBFDMD_BOTH || type == BBFDMD_BOTH || dm_type == type) && type != BBFDMD_NONE;
    }
    
    
    void print_fault_message(struct blob_buf *blob_buf, const char *path, uint32_t fault_code, const char *fault_msg)
    {
    	if (!blob_buf || !path || !fault_msg)
    		return;
    
    	void *table = blobmsg_open_table(blob_buf, NULL);
    	blobmsg_add_string(blob_buf, "path", path);
    	blobmsg_add_u32(blob_buf, "fault", fault_code);
    	blobmsg_add_string(blob_buf, "fault_msg", fault_msg);
    	blobmsg_close_table(blob_buf, table);
    }
    
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    static void sync_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
    {
    	struct blob_attr *attr = NULL;
    	int remaining = 0;
    
    	if (!req || !msg)
    		return;
    
    	struct blob_buf *bb_response = (struct blob_buf *)req->priv;
    
    	if (!bb_response)
    		return;
    
    	blob_for_each_attr(attr, msg, remaining) {
    		blobmsg_add_field(bb_response, blobmsg_type(attr), blobmsg_name(attr), blobmsg_data(attr), blobmsg_len(attr));
    	}
    }
    
    void run_sync_call(const char *ubus_obj, const char *ubus_method, struct blob_attr *msg, struct blob_buf *bb_response)
    {
    	struct blob_buf req_buf = {0};
    	struct blob_attr *attr = NULL;
    	int remaining = 0;
    
    	if (!ubus_obj || !ubus_method || !msg || !bb_response)
    		return;
    
    	memset(&req_buf, 0, sizeof(struct blob_buf));
    	blob_buf_init(&req_buf, 0);
    
    	blob_for_each_attr(attr, msg, remaining) {
    
    		blobmsg_add_field(&req_buf, blobmsg_type(attr), blobmsg_name(attr), blobmsg_data(attr), blobmsg_len(attr));
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    	}
    
    	if (g_log_level == LOG_DEBUG) {
    		char *json_str = blobmsg_format_json_indent(req_buf.head, true, -1);
    		BBFDM_DEBUG("### ubus call %s %s '%s' ###", ubus_obj, ubus_method, json_str);
    		BBFDM_FREE(json_str);		
    	}
    
    
    	BBFDM_UBUS_INVOKE_SYNC(ubus_obj, ubus_method, req_buf.head, 5000, sync_callback, bb_response);
    
    Amin Ben Romdhane's avatar
    Amin Ben Romdhane committed
    
    	blob_buf_free(&req_buf);
    }