Hi,


As I thought that libpmc could be nice for several application that need to 
communicate with the ptp4l.

I decided to make a short test.



First I patch the makefile to create the libpmc.so

diff --git a/makefile b/makefile

index a23945a..f5e12da 100644

--- a/makefile

+++ b/makefile

@@ -23,6 +23,7 @@ VER     = -DVER=$(version)

CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS)

LDLIBS = -lm -lrt $(EXTRA_LDFLAGS)

PRG    = ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster

+LIBS   = libpmc.so

FILTERS    = filter.o mave.o mmedian.o

SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o

TRANSP = raw.o transport.o udp.o udp6.o uds.o

@@ -46,7 +47,7 @@ sbindir   = $(prefix)/sbin

mandir = $(prefix)/man

man8dir    = $(mandir)/man8



-all: $(PRG)

+all: $(PRG) $(LIBS)



ptp4l: $(OBJ)



@@ -56,6 +57,18 @@ nsm: config.o $(FILTERS) hash.o interface.o msg.o nsm.o 
phc.o print.o \

pmc: config.o hash.o interface.o msg.o phc.o pmc.o pmc_common.o print.o sk.o \

  tlv.o $(TRANSP) util.o version.o



+.libs:

+   @mkdir -p $@

+# Generic rule to compile for shared libraries

+.libs/%.o: %.c | .libs

+   $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -DPIC -c $< -o $@

+

+LIBPMC_OBJS:=$(foreach n,config.o hash.o interface.o msg.o phc.o \

+ pmc_common.o print.o sk.o tlv.o $(TRANSP) util.o version.o,.libs/$n)

+

+libpmc.so: $(LIBPMC_OBJS)

+   $(CC) -shared $^ $(LDLIBS) -o $@

+

phc2sys: clockadj.o clockcheck.o config.o hash.o interface.o msg.o \

  phc.o phc2sys.o pmc_common.o print.o $(SERVOS) sk.o stats.o \

  sysoff.o tlv.o $(TRANSP) util.o version.o

@@ -83,7 +96,7 @@ install: $(PRG)

    done



clean:

-   rm -f $(OBJECTS) $(DEPEND) $(PRG)

+   rm -f $(OBJECTS) $(DEPEND) $(PRG) $(LIBS) $(LIBPMC_OBJS)



distclean: clean

    rm -f .version

diff --git a/.gitignore b/.gitignore

index 3dbcbfa..091fbf2 100644

--- a/.gitignore

+++ b/.gitignore

@@ -9,3 +9,5 @@

/phc_ctl

/snmp4lptp

/timemaster

+/libpmc.so

+/.libs/





Than I create a simple application

#include <poll.h>
#include <unistd.h>

extern "C"
{
#include "linuxptp/ds.h"
#include "linuxptp/fsm.h"
#include "linuxptp/notification.h"
#include "linuxptp/pmc_common.h"
#include "linuxptp/print.h"
#include "linuxptp/tlv.h"
#include "linuxptp/uds.h"
#include "linuxptp/util.h"
#include "linuxptp/version.h"
}

class My_Pmc
{
private:
    bool init_done;
    struct config *cfg;
    struct pmc *pmc;

    bool parse(struct ptp_message *msg);
    bool get(int id);

public:
    My_Pmc(const char *cfg_file, const char *uds_address, uint8_t 
boundary_hops);
    ~My_Pmc();

    bool get_port_data_set();
    bool get_time_status_np();

    // from TLV_PORT_DATA_SET - PORT_DATA_SET
    int64_t peerMeanPathDelay;
    std::string portState;

    // from TLV_TIME_STATUS_NP - TIME_STATUS_NP
    int64_t master_offset;
    std::string gmIdentity;
};

bool My_Pmc::parse(struct ptp_message *msg)
{
    if (msg_type(msg) != MANAGEMENT)
        return false;
    int action = management_action(msg);
    if (action < GET || action > ACKNOWLEDGE)
        return false;
    if (msg_tlv_count(msg) != 1)
        return false;

    struct TLV *tlv = (struct TLV *)msg->management.suffix;
    if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS && tlv->type != TLV_MANAGEMENT)
        return false;

    struct management_tlv *mgt;
    mgt = (struct management_tlv *)msg->management.suffix;
    if (mgt->length == 2 && mgt->id != TLV_NULL_MANAGEMENT)
        return false;

    struct time_status_np *tsn;
    struct portDS *p;

    switch (mgt->id) {
    case TLV_PORT_DATA_SET:
        p = (struct portDS *)mgt->data;
        if (p->portState > PS_SLAVE)
            portState = "NONE";
        else
            portState = ps_str[p->portState];
        peerMeanPathDelay = p->peerMeanPathDelay >> 16;
        break;
    case TLV_TIME_STATUS_NP:
        tsn = (struct time_status_np *)mgt->data;
        master_offset = tsn->master_offset;
        gmIdentity = cid2str(&tsn->gmIdentity);
        break;
    }
    return true;
}

My_Pmc::My_Pmc(const char *cfg_file, const char *uds_address, uint8_t 
boundary_hops):
    init_done(false)
{
    cfg = config_create();
    if (cfg == nullptr)
        return;

    if (config_read(cfg_file, cfg))
        return;

    if (config_set_string(cfg, "uds_address", uds_address))
        return;

    if (config_set_int(cfg, "network_transport", TRANS_UDS))
        return;

    char uds_local[MAX_IFNAME_SIZE + 1];
    snprintf(uds_local, sizeof(uds_local), "/var/run/pmc.%d", getpid());

    pmc = pmc_create(cfg, TRANS_UDS, uds_local, boundary_hops,
            config_get_int(cfg, nullptr, "domainNumber"),
            config_get_int(cfg, nullptr, "transportSpecific") << 4, 0);

    if (pmc != nullptr)
        init_done = true;
}

bool My_Pmc::get(int id)
{
    if (!init_done)
        return false;
    if (pmc_send_get_action(pmc, id))
        return false;

    struct pollfd pd;
    pd.fd = pmc_get_transport_fd(pmc);
    pd.events = POLLIN | POLLPRI;
    int cnt = poll(&pd, 1, 200); // 200 milliseconds should be sufficient
    if (cnt == 1) {
        if (pd.revents & (POLLIN|POLLPRI)) {
            struct ptp_message *msg = pmc_recv(pmc);
            if (msg != nullptr) {
                bool ret = parse(msg);
                msg_put(msg);
                return ret;
            }
        }
    }
    return false;
}

bool My_Pmc::get_port_data_set()
{
    return get(TLV_PORT_DATA_SET); // PORT_DATA_SET
}

bool My_Pmc::get_time_status_np()
{
    return get(TLV_TIME_STATUS_NP); // TIME_STATUS_NP
}

My_Pmc::~My_Pmc()
{
    pmc_destroy(pmc);
    msg_cleanup();
    config_destroy(cfg);
}

#ifndef PIC
int main()
{
    My_Pmc p("/etc/linuxptp/ptp4l.enp7s0.conf", "/var/run/ptp4l.enp7s0", 0);
    if (!p.get_port_data_set())
        printf("get_port_data_set fail\n");
    if (!p.get_time_status_np())
        printf("get_time_status_np fail\n");
    printf("peerMeanPathDelay %ld portState %s master_offset %ld gmIdentity 
%s\n",
        p.peerMeanPathDelay,
        p.portState.c_str(),
        p.master_offset,
        p.gmIdentity.c_str());
}
#endif



build

g++ -std=gnu++11 -Wall -Wextra -Winline -g -I../.. -c -o my_pmc.o my_pmc.cpp
g++ my_pmc.o -L../../linuxptp -lpmc -o my_pmc



And run and get the proper answer

LD_LIBRARY_PATH=. ./my_pmc
peerMeanPathDelay 124 portState SLAVE master_offset -1 gmIdentity 
xxxxxx.fffe.xxxxxx





What do you think?



With best regards,
Erez Geva

AURELLY TECHNOLOGIES GmbH
External service provider at Siemens AG
Digital Industries
Process Automation
Software House Nbg
DI PA CI R&D 3
Nuremberg, Germany

_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to