Skip to content
Snippets Groups Projects
debug.c 5.38 KiB
Newer Older
  • Learn to ignore specific revisions
  • Anjan Chanda's avatar
    Anjan Chanda committed
    /*
     * debug.c - for debug and logging
     *
     * Copyright (C) 2019 IOPSYS Software Solutions AB. All rights reserved.
     *
     * Author: anjan.chanda@iopsys.eu
     *
     */
    
    
    #include <stdlib.h>
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdarg.h>
    #include <syslog.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <time.h>
    
    
    #include "utils.h"
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    #include "debug.h"
    
    
    #include <map1905/map2.h>
    #include <map1905/maputils.h>
    
    static int ffd, tfd;
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    extern const char *outfile_path;
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    const char *testfile_path = "/tmp/agent.test.log";
    static FILE *testfile;
    static FILE *outfile;
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    extern const char *PROG_NAME;
    extern int verbose;
    extern bool syslogging;
    extern bool usefifo;
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    static const int syslog_level[] = {LOG_ERR, LOG_WARNING, LOG_INFO, LOG_DEBUG};
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    
    void start_logging(void)
    {
    	if (syslogging)
    		openlog(PROG_NAME, 0, LOG_DAEMON);
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	if (!outfile)
    	{
    		if (outfile_path)
    		{
    			if (usefifo)
    			{
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    				struct stat st;
    				int rfd;
    
    				if (stat(outfile_path, &st))
    					unlink(outfile_path);
    
    				mkfifo(outfile_path, 0600);
    				if (stat(outfile_path, &st) == -1 ||
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    					!S_ISFIFO(st.st_mode))
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    					return;
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    				rfd = open(outfile_path,
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    						   O_RDONLY | O_NONBLOCK);
    				if (rfd)
    				{
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    					ffd = open(outfile_path,
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    							   O_WRONLY | O_NONBLOCK);
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    					close(rfd);
    				}
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    			}
    			else
    			{
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    				outfile = fopen(outfile_path, "w+");
    			}
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		}
    		else
    		{
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    			outfile = stderr;
    		}
    	}
    }
    
    void stop_logging(void)
    {
    	if (syslogging)
    		closelog();
    
    	if (outfile)
    		fclose(outfile);
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	if (ffd)
    	{
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    		close(ffd);
    		unlink(outfile_path);
    	}
    }
    
    void log_message(int level, const char *fmt, ...)
    {
    	va_list args;
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	if (level > verbose)
    	{
    		if (usefifo && ffd)
    		{
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    			time_t now = time(NULL);
    			struct tm *tm_now = localtime(&now);
    			const char *tm_fmt = "[%d-%02d-%02d %02d:%02d:%02d] ";
    
    			va_start(args, fmt);
    			dprintf(ffd, tm_fmt,
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    					tm_now->tm_year + 1900,
    					tm_now->tm_mon + 1,
    					tm_now->tm_mday,
    					tm_now->tm_hour,
    					tm_now->tm_min,
    					tm_now->tm_sec);
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    			vdprintf(ffd, fmt, args);
    			va_end(args);
    		}
    		return;
    	}
    
    	va_start(args, fmt);
    	if (syslogging && level >= 0)
    		vsyslog(syslog_level[level], fmt, args);
    
    	if (outfile)
    		vfprintf(outfile, fmt, args);
    
    	if (usefifo && ffd)
    		vdprintf(ffd, fmt, args);
    
    	va_end(args);
    }
    
    void dump(unsigned char *buf, int len, char *label)
    {
    	int i;
    
    	if (label)
    		printf("---- %s ----", label);
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	for (i = 0; i < len; i++)
    	{
    
    Anjan Chanda's avatar
    Anjan Chanda committed
    		if (!(i % 4))
    			printf("  ");
    		if (!(i % 16))
    			printf("\n ");
    		printf("%02x ", buf[i] & 0xff);
    	}
    
    	if (label)
    		printf("\n--------------\n");
    }
    
    
    // TODO: duplicate of start_logging
    void start_test_logging(void)
    {
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	if (!testfile)
    	{
    		if (testfile_path)
    		{
    			if (usefifo)
    			{
    
    				struct stat st;
    				int rfd;
    
    				if (stat(testfile_path, &st))
    					unlink(testfile_path);
    
    				mkfifo(testfile_path, 0600);
    				if (stat(testfile_path, &st) == -1 ||
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    					!S_ISFIFO(st.st_mode))
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    				rfd = open(testfile_path,
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    						   O_RDONLY | O_NONBLOCK);
    				if (rfd)
    				{
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    					tfd = open(testfile_path,
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    							   O_WRONLY | O_NONBLOCK);
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    			}
    			else
    			{
    
    				testfile = fopen(testfile_path, "w+");
    			}
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		}
    		else
    		{
    
    			testfile = stderr;
    		}
    	}
    }
    
    void stop_test_logging(void)
    {
    	if (testfile)
    		fclose(testfile);
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	if (tfd)
    	{
    
    		close(tfd);
    		unlink(testfile_path);
    	}
    }
    
    void log_test(int level, void *var, int len)
    {
    	char *bstr;
    
    	if (level > verbose)
    		return;
    
    	bstr = calloc(1, (len * 2) + 1);
    	if (!bstr)
    		return;
    
    	btostr(var, len, bstr);
    
    	fprintf(testfile, "%s\n", bstr);
    	fflush(testfile);
    	free(bstr);
    }
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    void _log_cmdu(int level, void *var, bool flag)
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	struct cmdu_cstruct *cmdu = (struct cmdu_cstruct *)var;
    	struct json_object *msgversion, *msgtype, *msgid, *msg;
    	struct json_object *intfname, *tlvarray, *direction;
    	struct json_object *main_object;
    	char *bstr;
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	main_object = json_object_new_object();
    
    	tlvarray = json_object_new_array();
    
    	if (level > verbose)
    		return;
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	for (i = 0; i < cmdu->num_tlvs; i++)
    	{
    
    		uint16_t len;
    		uint8_t *btlv;
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		struct json_object *tlv;
    		struct json_object *tlv_type;
    		struct json_object *tlv_object;
    		tlv_object = json_object_new_object();
    		uint8_t *type;
    
    
    		btlv = map_put_tlv_cstruct(cmdu->tlvs[i], &len);
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		type = cmdu->tlvs[i];
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		bstr = calloc(1, (len * 2) + 1);
    		if (!bstr)
    			return;
    		btostr(btlv, len, bstr);
    		tlv = json_object_new_string(bstr);
    		tlv_type = json_object_new_string(map_stringify_tlv_type(*type));
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		json_object_object_add(tlv_object, "data", tlv);
    		json_object_object_add(tlv_object, "type", tlv_type);
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		json_object_array_add(tlvarray, tlv_object);
    
    		free(btlv);
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    		free(bstr);
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	msgversion = json_object_new_int(cmdu->message_version);
    	msgtype = json_object_new_int(cmdu->message_type);
    	direction = json_object_new_boolean(flag);
    	msgid = json_object_new_int(cmdu->message_id);
    	intfname = json_object_new_string(cmdu->intf_name);
    	msg = json_object_new_string(map_stringify_cmdu_type(cmdu->message_type));
    
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    	json_object_object_add(main_object, "message_version", msgversion);
    	json_object_object_add(main_object, "message_type", msgtype);
    	json_object_object_add(main_object, "message_id", msgid);
    	json_object_object_add(main_object, "interface_name", intfname);
    	json_object_object_add(main_object, "message", msg);
    	json_object_object_add(main_object, "direction", direction);
    	json_object_object_add(main_object, "tlvs", tlvarray);
    
    Ozan Tanfener's avatar
    Ozan Tanfener committed
    
    	fprintf(testfile, "%s\n", json_object_to_json_string(main_object));
    
    	fflush(testfile);
    }