linux-ptp代码学习(2)传输层创建细节

时钟初始化时,clock_create()最后会调用port_dispatch(p, EV_INITIALIZE, 0)进行初始化
bc_dispatch中调用的重要函数是port_state_update
port_state_update初始化时调用port_initialize对端口进行初始化,包括创建实际传输层socket,对其进行软硬件时间戳设置,加入监听队列等

int port_initialize(struct port *p)
{
	// 初始化port相关属性
	...
	// 初始化poll监听的定时器fd
	for (i = 0; i < N_TIMER_FDS; i++) {
		fd[i] = -1;
	}
	for (i = 0; i < N_TIMER_FDS; i++) {
		fd[i] = timerfd_create(CLOCK_MONOTONIC, 0);
		if (fd[i] < 0) {
			pr_err("timerfd_create: %s", strerror(errno));
			goto no_timers;
		}
	}
	
	// 创建传输层接口
	transport_open(p->trp, p->iface, &p->fda, p->timestamping)
	{
		// 如果传输层配置的是IEEE802_3,则实际调用raw_open
		return t->open(t, iface, fda, tt);
	}
}

static int raw_open(struct transport *t, struct interface *iface,
		    struct fdarray *fda, enum timestamp_type ts_type)
{
	// 创建接收/发送event消息和general消息的raw_socket
	efd = open_socket(name, 1, ptp_dst_mac, p2p_dst_mac, socket_priority);
	{
		fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
		// 获取指定网卡的index
		index = sk_interface_index(fd, name);
		memset(&addr, 0, sizeof(addr));
		addr.sll_ifindex = index; 	 // 指定与该套接字关联的网络接口的index,如指定为eth0(对应的index)
		addr.sll_family = AF_PACKET; // 数据链路层
		addr.sll_protocol = htons(ETH_P_ALL);  // 捕获所有数据包
		bind(fd, (struct sockaddr *) &addr, sizeof(addr))
		//将一个套接字绑定到特定的网络设备。这意味着通过该套接字发送和接收的数据将仅限于指定的网络接口。
		setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name));
	}
	gfd = open_socket(name, 0, ptp_dst_mac, p2p_dst_mac, socket_priority);
	// 设置efd时间戳相关属性
	sk_timestamping_init(efd, name, ts_type, TRANS_IEEE_802_3, interface_get_vclock(iface))
	{
		// flag根据软硬时间戳的配置设置标志位
		// 如果是硬件时间戳,设置filter。
		// filter1 = HWTSTAMP_FILTER_PTP_V2_EVENT; filter2 = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
		// hwts_init中调用ioctl,对socket进行设置需要接收哪些报文
		err = hwts_init(fd, device, filter1, filter2, tx_type);	
		// 配置指定的套接字,以便在接收到数据包时,可以获取相关的时间戳信息。
		timestamping.flags = flags;
		timestamping.bind_phc = vclock;
		setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping, sizeof(timestamping))
	}
	// 设置gfd时间戳相关属性
	sk_general_init(gfd)
	//加入poll监听队列
	fda->fd[FD_EVENT] = efd;
	fda->fd[FD_GENERAL] = gfd;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值