netopeer2开发(二)

netopeer2开发(一)主要介绍了sysrepo初始化时如何读取设备端口信息,并将端口信息写入sysrepo数据库。本节主要介绍当操作sysrepo数据库时,sysrepo如何将配置信息写入设备,以达到对设备的管理目的。

由于两种对sysrepo数据库访问方式差不多,本节仅以独立进程方式展开介绍。

独立进程方式

主要代码实现

netopeer2开发(一)基础上,继续进行项目开发。首先在sr_interfaces.c文件主函数中添加事件监听线程,监听模块数据变化,如下所示。

int main(int argc, char **argv)
{
    sr_conn_ctx_t *connection = NULL;
    sr_session_ctx_t *session = NULL;
    int rc = SR_ERR_OK;
    const char *xpath, *mod_name;

    unsigned int dev_count;
	char** devices, *msg = NULL;
	int i;

    /* turn logging on */
    sr_log_stderr(SR_LL_WRN);

    /* connect to sysrepo */
    rc = sr_connect(0, &connection);
    if (rc != SR_ERR_OK) {
        goto cleanup;
    }

    /* start session */
    rc = sr_session_start(connection, SR_DS_RUNNING, &session);
    if (rc != SR_ERR_OK) {
        goto cleanup;
    }
	/* 设备初始化 */
	devices = iface_get_ifcs(1, &dev_count, &msg);
	if (devices == NULL) {
		goto cleanup;
	}
	for(i = 0; i < dev_count; i++){
	   rc = parse_iface_config(session, devices[i], &msg);
	   free(devices[i]);
	   if(msg != NULL){
		free(msg);
		msg = NULL;
	   }
	}
	free(devices);

	/* apply the change */
    rc = sr_apply_changes(session, 0, 0);
    if (rc != SR_ERR_OK) {
       return -1;
    }
	printf("sr_apply_changes end\n");

    /*
     * 添加事件监听线程,监听模块ietf-interfaces的数据变化,通过回调函数interfaces_if_interface_cb对变化数据进行处理
     * sr_module_change_subscribe是sysrepo提供的API
     */
    mod_name = "ietf-interfaces";
    xpath = "/ietf-interfaces:interfaces/interface";
    rc = sr_module_change_subscribe(session, mod_name, xpath, interfaces_if_interface_cb, NULL, 0, 0, &subscription);
    if (rc != SR_ERR_OK) {
        goto cleanup;
    }

	/* loop until ctrl-c is pressed / SIGINT is received */
    signal(SIGINT, sigint_handler);
    signal(SIGPIPE, SIG_IGN);
    while (!exit_application) {
        sleep(1000);
    }
    
cleanup:
    sr_disconnect(connection);
    return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}

interfaces_if_interface_cb函数定义如下,此函数只是举例说明回调函数的使用方法,并不一定完全正确,只作为参考。

static int
interfaces_if_interface_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event,
        uint32_t request_id, void *private_data)
{
    sr_change_iter_t *iter;
    sr_change_oper_t op;
    const struct lyd_node *node;
    const char *prev_val, *prev_list;
    char *xpath2, *node_value, *ifname, *ipxpath;
    char *ptr;
    bool prev_dflt;
    int rc, failed = 0;
    unsigned char enabled = 2;
    sr_val_t *val = NULL;
    unsigned char loopback = 0;
    char *xpath3;
    unsigned short mtu;

	/* 获取迭代路径 */
    if (asprintf(&xpath2, "%s//.", xpath) == -1) {
        printf("Memory allocation failed");
        return SR_ERR_NOMEM;
    }
    /* 获取迭代参数 */
    rc = sr_get_changes_iter(session, xpath2, &iter);
    free(xpath2);
    if (rc != SR_ERR_OK) {
        printf("Getting changes iter failed.");
        return rc;
    }
	
	printf("=============%s=================\n", __FUNCTION__);
    while ((rc = sr_get_change_tree_next(session, iter, &op, &node, &prev_val, &prev_list, &prev_dflt)) == SR_ERR_OK) {
    	printf("%s: node schema name: %s\n", __FUNCTION__, node->schema->name);
		if(!strcmp(node->schema->name, "address")){
			/* ipv4 address 
			* 当ipv4值发生变化时,会执行该段代码
			*/
			/* 获取端口名称 */
		    ifname = ((struct lyd_node_leaf_list *)node->parent->parent->child)->value_str;
			printf("%s: ipv4 address, ifname: %s, node schema name: %s\n", __FUNCTION__, ifname, node->schema->name);
			if (asprintf(&ipxpath, "%s[name='%s']/ietf-ip:ipv4", xpath, ifname) == -1) {
				printf("Memory allocation failed");
				return SR_ERR_NOMEM;
			}
			/* 执行具体的操作,将需要修改的数据写入设备 */
			interface_ipv4_address_cb(session, module_name, ipxpath, event, request_id, private_data);
			free(ipxpath);
		}else if(!strcmp(node->schema->name, "enabled") && !strcmp(node->parent->schema->name, "interface")){
			/* interface enabled
			 * 当将端口进行UP/DOWN操作时,会执行该段代码
			 */
		    ifname = ((struct lyd_node_leaf_list *)node->parent->child)->value_str;
		    node_value = ((struct lyd_node_leaf_list *)node)->value_str;
			printf("%s: interface enabled, ifname: %s, node schema name: %s, line[%d]\n", __FUNCTION__, ifname, node->schema->name, __LINE__);
			printf("iface_ignore[%d], node_value[%s], op[%d]\n", iface_ignore, node_value, op);
			if(iface_ignore){
				continue;
			}
			if(op == SR_OP_CREATED || op == SR_OP_MODIFIED){
				if(!strcmp(node_value, "false")){
					enabled = 0;
				}else{
					enabled = 1;
				}
			}
			printf("enabled[%d], \n", enabled);
			interface_if_enabled_cb(ifname, enabled);
			
		}else if(!strcmp(node->schema->name, "enabled") && !strcmp(node->parent->schema->name, "ipv4")){
			/* ipv4 enabled */
		    ifname = ((struct lyd_node_leaf_list *)node->parent->parent->child)->value_str;
		    node_value = ((struct lyd_node_leaf_list *)node)->value_str;
		    if (asprintf(&xpath3, "%s[name='%s']/type", xpath, ifname) == -1) {
				printf("Memory allocation failed");
				return SR_ERR_NOMEM;
			}
			sr_get_item(session, xpath3, 0, &val);
			printf("%s: ipv4 enabled, ifname: %s, node value: %s, xpath3: %s\n", __FUNCTION__, ifname, node_value, xpath3);
			free(xpath3);
			ptr = (val->data).string_val;
			if(strchr(ptr, ':') != NULL){
				ptr = strchr(ptr, ':')+1;
			}
			if(strcmp(ptr, "softwareLoopback") == 0){
				loopback = 1;
			}

			interface_ipv4_enabled_cb(node, ifname, node_value, op, loopback);
			if(val != NULL){
				free(val);
			}
			
		}else if(!strcmp(node->schema->name, "mtu")){
			/* ipv4 mtu
			 * 设置ipv4 mtu值时,会进入该段代码
			 */
		    ifname = ((struct lyd_node_leaf_list *)node->parent->parent->child)->value_str;
		    mtu = ((struct lyd_node_leaf_list *)node)->value.uint16;
			printf("%s: ipv4 mtu, ifname: %s, node schema name: %s, mtu: %d\n", __FUNCTION__, ifname, node->schema->name, mtu);

			interface_ipv4_mtu_cb(ifname, mtu, op);
			
		}else if(!strcmp(node->schema->name, "forwarding")){
			/* ipv4 forwarding
			 * 设置ipv4 forwarding值时,会进入该段代码
			 */
		    ifname = ((struct lyd_node_leaf_list *)node->parent->parent->child)->value_str;
		    node_value = ((struct lyd_node_leaf_list *)node)->value_str;
			printf("%s: ipv4 forwarding, ifname: %s, node schema name: %s, node_value: %s\n", __FUNCTION__, ifname, node->schema->name, node_value);

			interface_ipv4_forwarding_cb(ifname, node_value, op);
			
		}else if(!strcmp(node->schema->name, "interface")){
			/* interface */
			ifname = ((struct lyd_node_leaf_list *)node->child)->value_str;
			printf("%s: ifname: %s, node schema name: %s, line[%d]\n", __FUNCTION__, ifname, node->schema->name, __LINE__);
			
			iface_ignore = 0;

			if(op & SR_OP_DELETED)
				iface_ignore = 1;
				
		}else if(!strcmp(node->schema->name, "ipv4")){
			/* ipv4 */
			ifname = ((struct lyd_node_leaf_list *)node->parent->child)->value_str;
			printf("%s: ipv4, ifname: %s, node schema name: %s, line[%d]\n", __FUNCTION__, ifname, node->schema->name, __LINE__);
			interface_ipv4_cb(ifname, op, loopback);
		}
    }

    sr_free_change_iter(iter);
    if (rc != SR_ERR_NOT_FOUND) {
        printf("Getting next change failed.");
        return rc;
    }
	
    return failed? SR_ERR_CALLBACK_FAILED:SR_ERR_OK;
}

例如,在端口ens32上增加一个地址,通过netopeer2-cli执行完相应操作会,interfaces_if_interface_cb函数监听到该变化后,会调用interface_ipv4_address_cb函数,interface_ipv4_address_cb函数实现如下:

static int interface_ipv4_address_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event,
		uint32_t request_id, void *private_data)
{
	sr_change_iter_t *iter;
	sr_change_oper_t op;
	const struct lyd_node *node;
	const char *prev_val, *prev_list;
	char *xpath2, *ifname;
	bool prev_dflt;
	int rc, failed = 0, i;
	char* msg = NULL, *netmask = NULL, *ip = NULL;
	unsigned char prefix_len = 0, octet, mask;

	if (iface_ignore || iface_ipv4addr_ignore) {
		return SR_ERR_OK;
	}
	if (asprintf(&xpath2, "%s//.", xpath) == -1) {
		printf("Memory allocation failed");
		return SR_ERR_NOMEM;
	}
	rc = sr_get_changes_iter(session, xpath2, &iter);
	free(xpath2);
	if (rc != SR_ERR_OK) {
		printf("Getting changes iter failed.");
		return rc;
	}
	
	printf("=============%s=================\n", __FUNCTION__);
	printf("%s: xpath: %s\n", __FUNCTION__, xpath);
	while ((rc = sr_get_change_tree_next(session, iter, &op, &node, &prev_val, &prev_list, &prev_dflt)) == SR_ERR_OK) {
		/* find name */
		
		if(!strcmp(node->schema->name, "address")){
			ifname = ((struct lyd_node_leaf_list *)node->parent->parent->child)->value_str;
			printf("ifname: %s, node schema name: %s\n", ifname, node->schema->name);
		}
		if(!strcmp(node->schema->name, "ip")){
			ip = ((struct lyd_node_leaf_list *)node)->value_str;
		}
		if(!strcmp(node->schema->name, "prefix-length")){
			prefix_len = ((struct lyd_node_leaf_list *)node)->value.uint16;
		}
		if(!strcmp(node->schema->name, "netmask")){
			netmask = ((struct lyd_node_leaf_list *)node)->value_str;
		}
	}
	
	sr_free_change_iter(iter);
	if (rc != SR_ERR_NOT_FOUND) {
		printf("Getting next change failed.");
		return rc;
	}
	if (ip == NULL) {
		printf("Missing ip address in an IPv4 address.\n");
		free(netmask);
		return SR_ERR_CALLBACK_FAILED;
	}
	if ((prefix_len == 0 && netmask == NULL) || (prefix_len != 0 && netmask != NULL)) {
		printf("Cannot get subnet for the IP \"%s\".", ip);
		free(ip);
		free(netmask);
		return SR_ERR_CALLBACK_FAILED;
	}

	if (netmask != NULL) {
		prefix_len = 0;
		mask = 0x80;
		octet = (unsigned)atoi(strtok(netmask, "."));
		i = 0;
		while (mask & octet) {
			++prefix_len;
			mask >>= 1;
			++i;
			if (i == 32) {
				break;
			}
			if (i % 8 == 0) {
				octet = (unsigned)atoi(strtok(NULL, "."));
				mask = 0x80;
			}
		}
		free(netmask);
	}
	printf("prefix_len: %d\n", prefix_len);
	/* 获取到ip, 掩码信息后,写入设备 */
	rc = iface_ipv4_ip(ifname, ip, prefix_len, op, &msg);
	return failed? SR_ERR_CALLBACK_FAILED:SR_ERR_OK;
}
功能验证

当前系统配置如下:

[root@localhost examples]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:a8:fc:7f brd ff:ff:ff:ff:ff:ff
    inet 192.168.32.10/24 brd 192.168.32.255 scope global ens32
       valid_lft forever preferred_lft forever
    inet6 2408:84e5:288:66bb:3953:8a7a:883b:24ba/64 scope global noprefixroute dynamic 
       valid_lft 2477sec preferred_lft 2477sec
    inet6 fe80::4fe2:71fa:ac8c:9554/64 scope link 
       valid_lft forever preferred_lft forever
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:a8:fc:89 brd ff:ff:ff:ff:ff:ff
    inet 192.168.34.10/24 brd 192.168.34.255 scope global ens34
       valid_lft forever preferred_lft forever
    inet6 2408:84e5:288:66bb:8d5:9a1c:c7b4:183b/64 scope global noprefixroute dynamic 
       valid_lft 2477sec preferred_lft 2477sec
    inet6 fe80::6145:c454:ac17:75c3/64 scope link 
       valid_lft forever preferred_lft forever

分别启动编译生成的可执行程序ietf-interfaces, netopeer2-server, netopeer2-cli, 其中通过netopeer2-cli终端命令:get-config --source running得到如下信息:

   <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
  <interface>
    <name>ens32</name>
    <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
    <enabled>false</enabled>
    <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <enabled>true</enabled>
      <forwarding>false</forwarding>
      <mtu>1500</mtu>
      <address>
        <ip>192.168.32.10</ip>
        <prefix-length>24</prefix-length>
      </address>
    </ipv4>
    <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <enabled>true</enabled>
      <forwarding>false</forwarding>
      <mtu>1500</mtu>
      <dup-addr-detect-transmits>1</dup-addr-detect-transmits>
      <autoconf>
        <create-global-addresses>true</create-global-addresses>
      </autoconf>
    </ipv6>
  </interface>
  <interface>
    <name>lo</name>
    <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type>
    <enabled>true</enabled>
    <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <enabled>true</enabled>
      <forwarding>false</forwarding>
      <address>
        <ip>127.0.0.1</ip>
        <prefix-length>8</prefix-length>
      </address>
    </ipv4>
    <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <enabled>true</enabled>
      <forwarding>false</forwarding>
      <dup-addr-detect-transmits>1</dup-addr-detect-transmits>
      <autoconf>
        <create-global-addresses>true</create-global-addresses>
      </autoconf>
    </ipv6>
  </interface>
  <interface>
    <name>ens34</name>
    <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
    <enabled>true</enabled>
    <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <enabled>true</enabled>
      <forwarding>false</forwarding>
      <mtu>1500</mtu>
      <address>
        <ip>192.168.34.10</ip>
        <prefix-length>24</prefix-length>
      </address>
    </ipv4>
    <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <enabled>true</enabled>
      <forwarding>false</forwarding>
      <mtu>1500</mtu>
      <dup-addr-detect-transmits>1</dup-addr-detect-transmits>
      <autoconf>
        <create-global-addresses>true</create-global-addresses>
      </autoconf>
    </ipv6>
  </interface>
</interfaces>

通过netopeer2-cli终端edit-config --target running --config=data-ip.xml命令配置端口ip,其中data-ip.xml配置如下:

<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
  <interface>
    <name>ens34</name>
    <description>Wire Connection</description>
    <type xmlns:ift="urn:ietf:params:xml:ns:yang:iana-if-type">ift:ethernetCsmacd</type>
    <enabled>true</enabled>
    <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <address><ip>192.168.34.15</ip><prefix-length>24</prefix-length></address>
    </ipv4>
  </interface>
</interfaces>

分别为端口ens32、ens34添加IP地址为192.168.32.15,192.168.34.15,完成后,ietf-interfaces端输出如下:

=============interfaces_if_interface_cb=================
interfaces_if_interface_cb: node schema name: description
interfaces_if_interface_cb: node schema name: enabled
/* 先调用接口ens32使能函数 */
interfaces_if_interface_cb: interface enabled, ifname: ens32, node schema name: enabled, line[648]
iface_ignore[0], node_value[true], op[1]
enabled[1], 
enabled: 1
interfaces_if_interface_cb: node schema name: address
/* 由于ip地址信息发生改变,调用相应函数进行处理 */
interfaces_if_interface_cb: ipv4 address, ifname: ens32, node schema name: address
=============interface_ipv4_address_cb=================
interface_ipv4_address_cb: xpath: /ietf-interfaces:interfaces/interface[name='ens32']/ietf-ip:ipv4
ifname: ens32, node schema name: address
prefix_len: 24
interfaces_if_interface_cb: node schema name: ip
interfaces_if_interface_cb: node schema name: prefix-length
=============interfaces_if_interface_cb=================
interfaces_if_interface_cb: node schema name: description
interfaces_if_interface_cb: node schema name: enabled
interfaces_if_interface_cb: interface enabled, ifname: ens32, node schema name: enabled, line[648]
iface_ignore[0], node_value[true], op[1]
enabled[1], 
enabled: 1
interfaces_if_interface_cb: node schema name: address
interfaces_if_interface_cb: ipv4 address, ifname: ens32, node schema name: address
=============interface_ipv4_address_cb=================
interface_ipv4_address_cb: xpath: /ietf-interfaces:interfaces/interface[name='ens32']/ietf-ip:ipv4
ifname: ens32, node schema name: address
prefix_len: 24
interfaces_if_interface_cb: node schema name: ip
interfaces_if_interface_cb: node schema name: prefix-length
=============interfaces_if_interface_cb=================
interfaces_if_interface_cb: node schema name: description
interfaces_if_interface_cb: node schema name: address
/* 调用接口ens34地址变化回调函数 */
interfaces_if_interface_cb: ipv4 address, ifname: ens34, node schema name: address
=============interface_ipv4_address_cb=================
interface_ipv4_address_cb: xpath: /ietf-interfaces:interfaces/interface[name='ens34']/ietf-ip:ipv4
ifname: ens34, node schema name: address
prefix_len: 24
interfaces_if_interface_cb: node schema name: ip
interfaces_if_interface_cb: node schema name: prefix-length
=============interfaces_if_interface_cb=================
interfaces_if_interface_cb: node schema name: description
interfaces_if_interface_cb: node schema name: address
interfaces_if_interface_cb: ipv4 address, ifname: ens34, node schema name: address
=============interface_ipv4_address_cb=================
interface_ipv4_address_cb: xpath: /ietf-interfaces:interfaces/interface[name='ens34']/ietf-ip:ipv4
ifname: ens34, node schema name: address
prefix_len: 24
interfaces_if_interface_cb: node schema name: ip
interfaces_if_interface_cb: node schema name: prefix-length

分析输入打印信息可知:当相关信息发生变化时,会触发监听函数进行函数回调,以及时进行处理。配置后,系统配置信息如下:

[root@localhost examples]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:a8:fc:7f brd ff:ff:ff:ff:ff:ff
    inet 192.168.32.15/24 brd 192.168.32.255 scope global ens32
       valid_lft forever preferred_lft forever
    inet 192.168.32.10/24 scope global secondary ens32
       valid_lft forever preferred_lft forever
    inet6 2408:84e5:288:66bb:3953:8a7a:883b:24ba/64 scope global noprefixroute dynamic 
       valid_lft 2323sec preferred_lft 2323sec
    inet6 fe80::4fe2:71fa:ac8c:9554/64 scope link 
       valid_lft forever preferred_lft forever
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:a8:fc:89 brd ff:ff:ff:ff:ff:ff
    inet 192.168.34.10/24 brd 192.168.34.255 scope global ens34
       valid_lft forever preferred_lft forever
    inet 192.168.34.15/24 scope global secondary ens34
       valid_lft forever preferred_lft forever
    inet6 2408:84e5:288:66bb:8d5:9a1c:c7b4:183b/64 scope global noprefixroute dynamic 
       valid_lft 2323sec preferred_lft 2323sec
    inet6 fe80::6145:c454:ac17:75c3/64 scope link 
       valid_lft forever preferred_lft forever

端口地址添加成功。下面再将刚刚添加的ip地址删除,data-ip.xml文件修改如下:

<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
  <interface>
    <name>ens32</name>
    <description>Wire Connection</description>
    <type xmlns:ift="urn:ietf:params:xml:ns:yang:iana-if-type">ift:ethernetCsmacd</type>
    <enabled>true</enabled>
    <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
      <address nc:operation="delete"><ip>192.168.32.15</ip><prefix-length>24</prefix-length></address>
    </ipv4>
  </interface>
</interfaces>

可以发现,可以正确删除端口的地址,端口配置恢复成之前的配置。

完毕!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
一句句解释分析细致讲解一下这段代码void netconf_entry(void) { int state = 0; int event = 0; UINT8 * pPacket = NULL; UINT32 dataLen = 0; char *pData = NULL; UINT8 ret = 0; struct np_module netopeer_module; struct np_module server_module; memset(&netopeer_module,0,sizeof(struct np_module)); memset(&server_module,0,sizeof(struct np_module)); state = Ros_GetCurState(); event = Ros_GetMsgId(); switch( state ) { case NETCONF_PROCESS_INIT: switch( event ) { case MSG_MasterPowerOn: case MSG_SlavePowerOn: //printf("netconf_entry MSG_SlavePowerOn\n"); Ros_SetNextState(NETCONF_PROCESS_RUNNING); break; case MSG_INIT_PROTOCOL_OK: Ros_SetNextState(NETCONF_PROCESS_RUNNING); break; default: break; } break; case NETCONF_PROCESS_RUNNING: switch( event ) { case MSG_DriverOK: netconf_init(); break; case MSG_NETCONF_TO_DCN: nc_verb_verbose("netconf_entry recv netconf to dcn msg\n"); break; case MSG_ALARM_TO_NETCONF: NcProcessAlarmMsg(); break; case MSG_LIBNETCONF_TO_NETOPEER: ncRcvLibnetconfMsgProc(); break; case MSG_NETCONF_LLDP_TIMER: Ros_SetTimer(netconfLLDPTimerID, NETCONF_MSG_TIME_LLDP, 0); ncLldpchange(); break; case MSG_NETCONF_15MIN_PERF_TIMER: Ros_SetTimer(netconf15MINPerfTimerID, NETCONF_MSG_15MIN_TIME_PERF, 0); packageOptInfo15Min(); packageIfStatisInfo15Min(); break; case MSG_NETCONF_24H_PERF_TIMER: Ros_SetTimer(netconf24hPerfTimerID, NETCONF_MSG_24H_TIME_PERF, 0); packageOptInfo24H(); packageIfStatisInfo24H(); break; case MSG_NETCONF_MEM_CHECK_TIMER: printS("MSG_NETCONF_MEM_CHECK_TIMER TIMEROUT\n"); memory_line_check(0); break; case MSG_NETCONF_TIMER: oam_perf_netconf_show_value_entry(); break; default: break; } break; default: break; } return EXIT_SUCCESS; }
07-14
下面是对这段代码的逐句解释和分析: ```c++ void netconf_entry(void) { int state = 0; int event = 0; UINT8 * pPacket = NULL; UINT32 dataLen = 0; char *pData = NULL; UINT8 ret = 0; struct np_module netopeer_module; struct np_module server_module; memset(&netopeer_module,0,sizeof(struct np_module)); memset(&server_module,0,sizeof(struct np_module)); ``` 这段代码定义了一个名为netconf_entry的函数,没有参数,返回类型为void。 接下来,定义了一系列变量,包括state和event(int类型)、pPacket(UINT8指针类型)、dataLen(UINT32类型)、pData(char指针类型)和ret(UINT8类型)。 然后,定义了两个结构体变量netopeer_module和server_module,并使用memset函数将其内容初始化为0。 ```c++ state = Ros_GetCurState(); event = Ros_GetMsgId(); switch( state ) { case NETCONF_PROCESS_INIT: switch( event ) { case MSG_MasterPowerOn: case MSG_SlavePowerOn: //printf("netconf_entry MSG_SlavePowerOn\n"); Ros_SetNextState(NETCONF_PROCESS_RUNNING); break; case MSG_INIT_PROTOCOL_OK: Ros_SetNextState(NETCONF_PROCESS_RUNNING); break; default: break; } break; case NETCONF_PROCESS_RUNNING: switch( event ) { case MSG_DriverOK: netconf_init(); break; case MSG_NETCONF_TO_DCN: nc_verb_verbose("netconf_entry recv netconf to dcn msg\n"); break; case MSG_ALARM_TO_NETCONF: NcProcessAlarmMsg(); break; case MSG_LIBNETCONF_TO_NETOPEER: ncRcvLibnetconfMsgProc(); break; case MSG_NETCONF_LLDP_TIMER: Ros_SetTimer(netconfLLDPTimerID, NETCONF_MSG_TIME_LLDP, 0); ncLldpchange(); break; case MSG_NETCONF_15MIN_PERF_TIMER: Ros_SetTimer(netconf15MINPerfTimerID, NETCONF_MSG_15MIN_TIME_PERF, 0); packageOptInfo15Min(); packageIfStatisInfo15Min(); break; case MSG_NETCONF_24H_PERF_TIMER: Ros_SetTimer(netconf24hPerfTimerID, NETCONF_MSG_24H_TIME_PERF, 0); packageOptInfo24H(); packageIfStatisInfo24H(); break; case MSG_NETCONF_MEM_CHECK_TIMER: printS("MSG_NETCONF_MEM_CHECK_TIMER TIMEROUT\n"); memory_line_check(0); break; case MSG_NETCONF_TIMER: oam_perf_netconf_show_value_entry(); break; default: break; } break; default: break; } return EXIT_SUCCESS; } ``` 接下来,代码根据当前状态(state)和事件(event)进行switch语句的判断。 如果state为NETCONF_PROCESS_INIT,根据event的不同进行不同的操作。如果event是MSG_MasterPowerOn或MSG_SlavePowerOn,则将下一个状态设置为NETCONF_PROCESS_RUNNING。如果event是MSG_INIT_PROTOCOL_OK,则同样将下一个状态设置为NETCONF_PROCESS_RUNNING。 如果state为NETCONF_PROCESS_RUNNING,根据event的不同进行不同的操作。如果event是MSG_DriverOK,则调用netconf_init函数。如果event是MSG_NETCONF_TO_DCN,则打印一条调试信息。如果event是MSG_ALARM_TO_NETCONF,则调用NcProcessAlarmMsg函数。如果event是MSG_LIBNETCONF_TO_NETOPEER,则调用ncRcvLibnetconfMsgProc函数。如果event是MSG_NETCONF_LLDP_TIMER,则设置一个定时器,并调用ncLldpchange函数。如果event是MSG_NETCONF_15MIN_PERF_TIMER,则设置一个定时器,并依次调用packageOptInfo15Min和packageIfStatisInfo15Min函数。如果event是MSG_NETCONF_24H_PERF_TIMER,则设置一个定时器,并依次调用packageOptInfo24H和packageIfStatisInfo24H函数。如果event是MSG_NETCONF_MEM_CHECK_TIMER,则打印一条信息,并调用memory_line_check函数。如果event是MSG_NETCONF_TIMER,则调用oam_perf_netconf_show_value_entry函数。 最后,函数返回EXIT_SUCCESS(整数值,表示成功)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值