tr069网管系统的相关记录

网管协议 TR069/TR135

Broadband Forum 发布,应用层管理协议,CPE广域网管理协议(CPE WAN Management Protocol)
TR069定义了一套全新的网管体系结构,包括管理模型,交互接口及基本的管理参数,能够有效地实施对家庭网络设备的管理.

ACS:自动配置服务器,负责完成对客户终端设备CPE的管理。
南向接口:ACS和CPE之间的接口 (TR069主要面向的)
北向接口:ACS与运营商的其他网管系统、业务管理系统、计费系统(OSS/BSS)之间的接口

使用的标准协议:
CPE/ACS Management Application
RPC Methods
SOAP
HTTP
SSL/TLS
TCP/IP


SOAP : Simple Object Access Protocol,简单对象访问协议,交换数据的一种协议规范,基于XML。
设计为在Web上交换结构化和固化的信息。基于类对象的传输协议,用于应用程序之间的通信
1,封装(envelop),定义了一个框架,描述信息内容,发送者,接受者,如何处理
2,编码规则,定义一种序列化机制,用于表示应用程序需要使用的数据类型的实例
3,RPC表示,定义一个协定,表示远程调用过程和应答
4,绑定,定义SOAP使用哪种协议交换信息。例如HTTP/TCP/UDP等
必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
可选的 Header 元素,包含头部信息
必需的 Body 元素,包含所有的调用和响应信息
可选的 Fault 元素,提供有关在处理此消息所发生错误的信息

实例:



    
    ...
    ...
    

    
        ...
        ...
        
        ...
        ...
        
    


cJSON 库


XML
XML Schema 描述 XML 文档的结构。
XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。
XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD。


ping/ICMP
在IP网络上,由于数据包被丢弃等原因,为了控制将必要的信息传递给发信方。ICMP协议是为了辅助IP 协议,
交换各种各样的控制信息而被制造出来的。用途:差错通知和信息查询
ICMP作为IP的上层协议(报文格式的角度),同层协议(功能角度)
所有ICMP用来交流错误通知和信息询问的报文,都是由类型和代码的组合来表示的

应用:
【路径MTU探索】向通信对方发送给IP数据包,设置分片禁止后再发送,收到ICMP通知返回的不分片即可传输的
MTU
【改变路由】改变路由是指路由器向送信方计算机指示路径改变这个功能。计算机根据自己的路由信息(路由表)
来决定传送目标。不知道发给谁好的时候,就将数据包发给设为默认网关的路由器。被指定为默认网关的路由器
接收到数据包,发现将数据包发给局域网内的其它路由器会比较快的时候,将这一信息通过ICMP 通知发送方。
这时使用的是,类型是5,代码是1 的ICMP 改变路由报文。在选项数据部分里写着应该发送给的路由器IP 地址。
Windows 收到这个报文后,重写自己的路由表,与对方的通信将在一段时间里经由被指定的路由器来实行。
【源点抑制】数据包集中到达某一路由器后,数据包因为来不及被处理,有可能被丢弃的情况。这时候,向送信
方发送的是ICMP 源点抑制报文,用来使送行方减慢发送速度。
【ping命令】ping 命令用来在IP 层次上调查与指定机器是否连通,调查数据包往复需要多少时间。为了实现这
个功能,ping 命令使用了两个ICMP 报文。向目标服务器发送回送请求报文,回送回答报文
【traceroute命令】调查到通信对方的路径现在是怎么样了。设置TTL为1,当到达第一个路由器时TTL被设置为0,
按规定将丢弃此包,错误通知报文用的ICMP报文是,类型为11,代码为0的ICMP超时报文。依次增加TTL发送,到达
目标服务器后,服务器回送ICMP回答报文,以此判断到达目标。
【端口扫描】检查服务器不需要的端口是否开着。服务器管理者用来检查有没有安全上有问题的漏洞开着。根据
ICMP 规格,UDP 数据包到达不存在的端口时,服务器需要返回ICMP 的“终点不可达”之一的“端口不可达”报文。
针对某个端口,发送UDP数据包,服务器回送ICMP 端口不可达报文。

安全:
【数据包攻击】ping洪水攻击;smurf攻击,源IP 地址被伪装成攻击对象服务器的地址,目标地址也不是攻击
对象服务器的地址,而是成为中转台的网络的广播地址。
【黑洞路由器】关闭ICMP后,路径MTU探索功能失效

ping实现:
// 创建ICMP socket
struct protoent *proto = getprotobyname("icmp");
sock = socket(AF_INET, SOCK_RAW, (proto ? proto->p_proto : 1)));
struct sockaddr_in pingaddr= ;
setsockopt(pingsock, IPPROTO_IP, IP_TOS, (char *)&nDscp, sizeof(int)); // 设置DSCP
setsockopt(pingsock, IPPROTO_IP, IP_TTL, (char *)&nTTL, sizeof(int));
// 发送ping报文
struct icmp *pkt;
char packet[datalen + 8];
pkt = (struct icmp *) packet;
pkt->icmp_type = ICMP_ECHO;
pkt->icmp_code = 0;
pkt->icmp_cksum = 0;
pkt->icmp_seq = ntransmitted++;
pkt->icmp_id = myid;
CLR(pkt->icmp_seq % MAX_DUP_CHK);
pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet));
i = sendto(pingsock, packet, sizeof(packet), 0,(struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
// 接收回复,并解析
recvfrom(pingsock, packet, sizeof(packet), MSG_DONTWAIT,(struct sockaddr *) &from, &fromlen))


libevent-2.0.12-stable

Reactor的事件处理机制,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果
相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”。

Reactor模式是编写高性能网络服务器的必备技术之一,它具有如下的优点:
1)响应快,不必为单个同步时间所阻塞,虽然Reactor本身依然是同步的;
2)编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销;
3)可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源;
4)可复用性,reactor框架本身与具体事件处理逻辑无关,具有很高的复用性;

【事件源】文件描述符;句柄;
【事件多路分发器】由操作系统提供的I/O多路复用机制,比如select和epoll。将事件注册到分发器后,事件到达
时,分发器通知程序,程序开始处理事件(同步非阻塞)。
【Reactor】事件管理的接口,内部使用“事件多路分发器”注册、销毁事件;运行事件循环;当事件就绪时,调用
事件处理函数。event_base结构
【事件处理程序】event结构,定义一组接口,每个接口对应一种类型的事件。

基本应用场景:
1,初始化libevent库,保存返回的指针。(相当于初始化一个Reactor)
struct event_base * base = event_init();
或者event_base_new();
2,初始化事件event,设置回调函数和关注的事件
void event_set(struct event ev, int fd, short event, void (cb)(int, short, void *), void *arg); // event_assign
ev 需初始化的事件对象
fd 句柄或信号
event 关注的事件类型,EV_READ,EV_WRITE,EV_SIGNAL等
cb 事件响应函数
arg 与fd event 一起被event_base传入cb
3,注册事件event到某个libevent实例上
event_base_set(base, &ev);
4,添加事件event
event_add(&ev, timeout);
5,程序进入无限循环,等待就绪事件并执行事件处理
event_base_dispatch(base);
或event_dispatch()

对于定时事件,libevent使用一个小根堆管理,key为超时时间;
对于Signal和I/O事件,libevent将其放入到等待链表(wait list)中,这是一个双向链表结构;Libevent将所有
的就绪事件,放入到激活链表中。对于激活链表中的事件调用事件回调函数处理事件。

源代码组织结构:
1,头文件 event.h
事件宏定义、接口函数声明,主要结构体event的声明
2,内部头文件 xxx-internal.h
内部数据结构和函数,对外不可见,以达到信息隐藏的目的
3,libevent框架 event.c
event整体框架的代码实现
4,对系统I/O多路复用机制的封装
epoll.c,select.c,devpoll.c,kqueue.c
5,定时事件管理 min-heap.h
6,信号管理 signal.c
7,辅助功能函数 evutil.h 和 evutil.c
8,日志 log.h和log.c
9,缓冲区管理 evbuffer.c和buffer.c
10,基本数据结构 compat/sys/queue.h
是libevent基本数据结构的实现,包括链表,双向链表,队列等
11,实用网络库 http和evdns
基于libevent实现的http服务器和异步dns查询库

主要数据结构 event:

struct event {
    struct event_callback ev_evcallback; // 事件回调函数

    /* for managing timeouts */
    union {
        TAILQ_ENTRY(event) ev_next_with_common_timeout; // 定时事件链表指针
        int min_heap_idx; // 在小根堆的索引值
    } ev_timeout_pos;
    evutil_socket_t ev_fd; // 文件描述符或者信号

    struct event_base *ev_base; // 事件所属的Reactor

    union {
        /* used for io events */
        struct {
            LIST_ENTRY (event) ev_io_next; // I/O事件链表指针
            struct timeval ev_timeout;
        } ev_io;

        /* used by signal events */
        struct {
            LIST_ENTRY (event) ev_signal_next; // 信号事件链表指针
            short ev_ncalls;    // 事件就绪时调用回调的次数,通常为1
            /* Allows deletes in callback */
            short *ev_pncalls;  // 通常指向ev_ncalls 或者NULL
        } ev_signal;
    } ev_;

    short ev_events;  // EV_READ EV_WRITE EV_SIGNAL EV_TIMEOUT(定时事件) EV_PERSIST(永久事件)
    short ev_res;       /* result passed to event callback */
    struct timeval ev_timeout;
};

struct event_callback {
    TAILQ_ENTRY(event_callback) evcb_active_next; // 激活事件链表指针
    short evcb_flags;   // libevent用来标记event信息的字段,表明其当前的状态。 
                        // EVLIST_TIMEOUT EVLIST_INSERTED EVLIST_SIGNAL EVLIST_ACTIVE 
                        // EVLIST_INTERNAL EVLIST_INIT
    ev_uint8_t evcb_pri;    /* smaller numbers are higher priority */
    ev_uint8_t evcb_closure;
    /* allows us to adopt for different types of events */
    union {
        void (*evcb_callback)(evutil_socket_t, short, void *);
        void (*evcb_selfcb)(struct event_callback *, void *);
        void (*evcb_evfinalize)(struct event *, void *);
        void (*evcb_cbfinalize)(struct event_callback *, void *);
    } evcb_cb_union;
    void *evcb_arg; // 在设置event时指定参数
};

事件设置接口函数:

void event_set(struct event *ev, int fd, short events,void (*callback)(int, short, void *), void *arg);
int event_base_set(struct event_base *base, struct event *ev);
int event_priority_set(struct event *ev, int pri);// ev处于就绪状态时不能设置,返回-1

全局event_base指针 current_base,默认注册其上。

struct event_base {
    const struct eventop *evsel; // 指向了全局变量static const struct eventop *eventops[]中的一个
                                 // libevent将系统提供的I/O demultiplex机制统一封装成了eventop结构;
                                 // 因此eventops[]包含了select、poll、kequeue和epoll等等其中的若干个
                                 // 全局实例对象。event_base_new中根据配置决定使用哪个。编译阶段决定
    void *evbase; // evbase实际上是一个eventop实例对象

    /** List of changes to tell backend about at next dispatch.  Only used
     * by the O(1) backends. */
    struct event_changelist changelist;

    const struct eventop *evsigsel; // 指向信号事件使用的后端
    /** Data to implement the common signal handelr code. */
    struct evsig_info sig;

    int virtual_event_count; // 虚拟事件数
    int event_count; // 事件数
    int event_count_active; // 就绪事件数

    int event_gotterm; // 是否一旦处理完事件就终止事件循环
    int event_break; // 是否立即终止事件循环

    int running_loop; // 设置是否正在执行event_base_loop, 避免重复调用

    // 就绪事件管理,数组索引为优先级,数字小的优先级高
    struct event_list *activequeues;
    int nactivequeues;

    /* common timeout logic */

    /** An array of common_timeout_list* for all of the common timeout
     * values we know. */
    struct common_timeout_list **common_timeout_queues;
    /** The number of entries used in common_timeout_queues */
    int n_common_timeouts;
    /** The total size of common_timeout_queues. */
    int n_common_timeouts_allocated;

    /** List of defered_cb that are active.  We run these after the active
     * events. */
    struct deferred_cb_queue defer_queue;

    /** Mapping from file descriptors to enabled (added) events */
    struct event_io_map io;

    /** Mapping from signal numbers to enabled (added) events. */
    struct event_signal_map sigmap;

    struct event_list eventqueue; // 保存所有添加事件的指针

    /** Stored timeval; used to detect when time is running backwards. */
    struct timeval event_tv;

    struct min_heap timeheap; // 定时事件小根堆

    /** Stored timeval: used to avoid calling gettimeofday/clock_gettime
     * too often. */
    struct timeval tv_cache;

#if defined(_EVENT_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
    /** Difference between internal time (maybe from clock_gettime) and
     * gettimeofday. */
    struct timeval tv_clock_diff;
    /** Second in which we last updated tv_clock_diff, in monotonic time. */
    time_t last_updated_clock_diff;
#endif

#ifndef _EVENT_DISABLE_THREAD_SUPPORT
    /* threading support */
    /** The thread currently running the event_loop for this base */
    unsigned long th_owner_id;
    /** A lock to prevent conflicting accesses to this event_base */
    void *th_base_lock;
    /** The event whose callback is executing right now */
    struct event *current_event;
    /** A condition that gets signalled when we're done processing an
     * event with waiters on it. */
    void *current_event_cond;
    /** Number of threads blocking on current_event_cond. */
    int current_event_waiters;
#endif

#ifdef WIN32
    /** IOCP support structure, if IOCP is enabled. */
    struct event_iocp_port *iocp;
#endif

    /** Flags that this base was configured with */
    enum event_base_config_flag flags;

    /* Notify main thread to wake up break, etc. */
    /** True if the base already has a pending notify, and we don't need
     * to add any more. */
    int is_notify_pending;
    /** A socketpair used by some th_notify functions to wake up the main
     * thread. */
    evutil_socket_t th_notify_fd[2];
    /** An event used by some th_notify functions to wake up the main
     * thread. */
    struct event th_notify;
    /** A function used to wake up the main thread from another thread. */
    int (*th_notify_fn)(struct event_base *base);
};


// 定义给定event_base的后端,统一了各个I/O多路复用机制
struct eventop {
    const char *name; // 后端名字
    /** Function to set up an event_base to use this backend.  It should
     * create a new structure holding whatever information is needed to
     * run the backend, and return it.  The returned pointer will get
     * stored by event_init into the event_base.evbase field.  On failure,
     * this function should return NULL. */
    void *(*init)(struct event_base *);
    /** Enable reading/writing on a given fd or signal.  'events' will be
     * the events that we're trying to enable: one or more of EV_READ,
     * EV_WRITE, EV_SIGNAL, and EV_ET.  'old' will be those events that
     * were enabled on this fd previously.  'fdinfo' will be a structure
     * associated with the fd by the evmap; its size is defined by the
     * fdinfo field below.  It will be set to 0 the first time the fd is
     * added.  The function should return 0 on success and -1 on error.
     */
    int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
    /** As "add", except 'events' contains the events we mean to disable. */
    int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
    /** Function to implement the core of an event loop.  It must see which
        added events are ready, and cause event_active to be called for each
        active event (usually via event_io_active or such).  It should
        return 0 on success and -1 on error.
     */
    int (*dispatch)(struct event_base *, struct timeval *);
    /** Function to clean up and free our data from the event_base. */
    void (*dealloc)(struct event_base *);
    /** Flag: set if we need to reinitialize the event base after we fork.
     */
    int need_reinit;
    /** Bit-array of supported event_method_features that this backend can
     * provide. */
    enum event_method_feature features;
    /** Length of the extra information we should record for each fd that
        has one or more active events.  This information is recorded
        as part of the evmap entry for each fd, and passed as an argument
        to the add and del functions above.
     */
    size_t fdinfo_len;
};

// 将事件注册到ev->ev_base上,注册成功ev将被插入到已注册链表中
// tv != NULL会同时注册定时事件,添加到,timer堆中
int event_add(struct event *ev, const struct timeval *tv);
// 删除事件
int event_del(struct event *ev):
// 进入事件循环
int event_loop(int flags); // 默认event_base
int event_base_loop(struct event_base *base, int flags);

【I/O和Timer事件的统一】
将Timer事件融合到系统I/O多路复用机制中,因为系统的I/O机制像select()和epoll_wait()都允许程序制定一个
最大等待时间(也称为最大超时时间)timeout,即使没有I/O事件发生,它们也保证能在timeout时间内返回。
那么根据所有Timer事件的最小超时时间来设置系统I/O的timeout时间;当系统I/O返回时,再激活所有就绪的
Timer事件就可以了,这样就能将Timer事件完美的融合到系统的I/O机制中了。

【I/O和Signal事件的统一】
当Signal发生时,并不立即调用event的callback函数处理信号,而是设法通知系统的I/O机制,让其返回,
然后再统一和I/O事件以及Timer一起处理。
创建socketpair,将读端在event_base上注册一个persist事件。信号到来时写读端,通知event_base

【缓冲事件IO】
bufferevent, 提供输入输出buffer,无需主动读写I/O socket。

bufferevent_new()
bufferevent_enable()/bufferevent_disable(),通过这两个接口重复使用bufferevent结构
bufferevent_read()/bufferevent_write()

【timer事件】

evtimer_set(); // 初始化事件为timer事件
evtimer_add()/evtimer_del()

【超时事件 timerout】

timeout_set();// 初始化事件为timeout事件
timeout_add()/timeout_del()

【evdns 异步DNS解析】

#include 
evdns_init()
evdns_resolve_ipv4(); //将主机名转换为IP
evdns_resolve_reverse(); // 反向查询

【evhttp事件驱动HTTP服务器】

#include 
evhttp_new()
evhttp_bind_socket(); //监听地址+端口
evhttp_set_gencb(); // 注册通用回调

【evrpc RPC框架】

在 libevent 中,如果需要处理信号,只能将信号注册到一个 libevent 实例上

TR135 相关概念
【RTP statistics】
基于Loss Event概念。一个丢包序列,中间可能含有收到的包岛(最多包含Gmin-1个包)。Gmin个收包终止Loss Event。
Gmin的值可配置。如果Gmin=1,表示不会有包岛,任何丢包序列都是一个Loss Event。
Loss Event 从第一个丢包,到最后一个丢包,数目即为length。
Gmin=2的情况
• R, L, R, R (length = 1)
• R, L, L, R, R (length = 2)
• R, L, R, L, R, R (length = 3)

Service Monitoring statistics 会收集Loss Event的length,以及分布。
相关参数:
maximum “non severe” length:A
minimum “non severe” distance:B 相邻Loss Event的距离
Loss Event的长度比A长,或者距离接近B,称为“severe(严重)”

ACS 在任何时候都可以改变这些参数,改变立即生效。但是数据得在下一次采样才会有效

Error Correction EC
STB数据模型提供一些错误校正前和错误校正后的统计数据。如果没使能EC,则数据一样。

Discarded packets:
Late:太晚而不能播放
Out of Sequence:参考RTP序列长度的定义

【Service Monitoring】

【linux 操作文件】
struct __dirstream
{
void *__fd;
char *__data;
int __entry_data;
char *__ptr;
int __entry_ptr;
size_t __allocation;
size_t __size;
__libc_lock_define (, __lock)
};
typedef struct __dirstream DIR;

struct dirent
{
  long d_ino; ///< inode number 索引节点号
off_t d_off; ///< offset to this dirent 在目录文件中的偏移
unsigned short d_reclen; ///< length of this d_name 文件名长
unsigned char d_type; ///< the type of d_name 文件类型
char d_name [NAME_MAX+1]; ///< file name (null-terminated) 文件名,最长255字符 int stat(const char *file_name, struct stat *buf);
}

struct stat
{
mode_t st_mode; ///< 文件访问权限
ino_t st_ino; ///< 索引节点号
dev_t st_dev; ///< 文件使用的设备号
dev_t st_rdev; ///< 设备文件的设备号
nlink_t st_nlink; ///< 文件的硬连接数
uid_t st_uid; ///< 所有者用户识别号
gid_t st_gid; ///< 组识别号
off_t st_size; ///< 以字节为单位的文件容量
time_t st_atime; ///< 最后一次访问该文件的时间
time_t st_mtime; ///< 最后一次修改该文件的时间
time_t st_ctime; ///< 最后一次改变该文件状态的时间
blksize_t st_blksize; ///< 包含该文件的磁盘块的大小
blkcnt_t st_blocks; ///< 该文件所占的磁盘块
};

DIR *opendir(const char *pathname); ///< 打开文件目录
struct dirent *readdir(DIR *dp);
void rewinddir(DIR *dp);
int closedir(DIR *dp);
long telldir(DIR *dp);
void seekdir(DIR *dp,long loc);


Android 相关

执行Linux命令
Process proc = Runtime.getRuntime().exec(cmdLine); // 如 "busybox ifconfig"
InputStreamReader is = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader (is);

你可能感兴趣的:(tr069网管系统的相关记录)