更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
telnet_dev.c 文件参考

浏览源代码.

函数

STATIC INLINE TELNET_DEV_SGetTelnetDevByFile (const struct file *file, BOOL isOpenOp)
 
INT32 TelnetTx (const CHAR *buf, UINT32 bufLen)
 
STATIC INT32 TelnetOpen (struct file *file)
 
STATIC INT32 TelnetClose (struct file *file)
 
STATIC ssize_t TelnetRead (struct file *file, CHAR *buf, size_t bufLen)
 
STATIC ssize_t TelnetWrite (struct file *file, const CHAR *buf, const size_t bufLen)
 
STATIC INT32 TelnetIoctl (struct file *file, const INT32 cmd, unsigned long arg)
 远程登录控制操作 更多...
 
STATIC INT32 TelnetPoll (struct file *file, poll_table *table)
 
INT32 TelnetedUnregister (VOID)
 
INT32 TelnetedRegister (VOID)
 
INT32 TelnetDevInit (INT32 clientFd)
 
INT32 TelnetDevDeinit (VOID)
 

变量

STATIC TELNET_DEV_S g_telnetDev
 远程登录设备 更多...
 
STATIC EVENT_CB_Sg_event
 
STATIC struct Vnodeg_currentVnode
 
STATIC const struct file_operations_vfs g_telnetOps
 

函数说明

◆ GetTelnetDevByFile()

STATIC INLINE TELNET_DEV_S * GetTelnetDevByFile ( const struct file file,
BOOL  isOpenOp 
)

在文件 telnet_dev.c60 行定义.

61{
62 struct Vnode *telnetInode = NULL;
63 TELNET_DEV_S *telnetDev = NULL;
64
65 if (file == NULL) {
66 return NULL;
67 }
68 telnetInode = file->f_vnode;
69 if (telnetInode == NULL) {
70 return NULL;
71 }
72 /*
73 * Check if the f_vnode is valid here for non-open ops (open is supposed to get invalid f_vnode):
74 * when telnet is disconnected, there still may be 'TelentShellTask' tasks trying to write
75 * to the file, but the file has illegal f_vnode because the file is used by others.
76 */
77 if (!isOpenOp) {
78 if (telnetInode != g_currentVnode) {
79 return NULL;
80 }
81 }
82 telnetDev = (TELNET_DEV_S *)((struct drv_data*)telnetInode->data)->priv;
83 return telnetDev;
84}
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
void * data
Definition: vnode.h:176
STATIC struct Vnode * g_currentVnode
Definition: telnet_dev.c:58
这是这个函数的调用关系图:

◆ TelnetClose()

STATIC INT32 TelnetClose ( struct file file)

在文件 telnet_dev.c174 行定义.

175{
176 struct wait_queue_head *wait = NULL;
177 TELNET_DEV_S *telnetDev = NULL;
178
179 TelnetLock();
180
181 telnetDev = GetTelnetDevByFile(file, FALSE);
182 if (telnetDev != NULL) {
183 wait = &telnetDev->wait;
184 LOS_ListDelete(&wait->poll_queue);
185 free(telnetDev->cmdFifo);
186 telnetDev->cmdFifo = NULL;
187 (VOID)LOS_EventDestroy(&telnetDev->eventTelnet);
188 g_event = NULL;
189 }
190 g_currentVnode = NULL;
191 TelnetUnlock();
192 return 0;
193}
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
销毁指定的事件控制块
Definition: los_event.c:334
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
EVENT_CB_S eventTelnet
远程登录事件
Definition: telnet_dev.h:67
wait_queue_head_t wait
等待队列
Definition: telnet_dev.h:68
TELNTE_FIFO_S * cmdFifo
Definition: telnet_dev.h:69
STATIC EVENT_CB_S * g_event
Definition: telnet_dev.c:57
STATIC INLINE TELNET_DEV_S * GetTelnetDevByFile(const struct file *file, BOOL isOpenOp)
Definition: telnet_dev.c:60
VOID TelnetLock(VOID)
Definition: telnet_loop.c:157
VOID TelnetUnlock(VOID)
Definition: telnet_loop.c:162
函数调用图:

◆ TelnetDevDeinit()

INT32 TelnetDevDeinit ( VOID  )

在文件 telnet_dev.c405 行定义.

406{
407 INT32 ret;
408
409 ret = system_console_deinit(TELNET);
410 if (ret != 0) {
411 PRINT_ERR("Telnet console deinit error.\n");
412 }
413 return ret;
414}
INT32 system_console_deinit(const CHAR *deviceName)
控制台结束前的处理 和 system_console_init成对出现,像控制台的析构函数
Definition: console.c:1375
signed int INT32
Definition: los_typedef.h:60
函数调用图:
这是这个函数的调用关系图:

◆ TelnetDevInit()

INT32 TelnetDevInit ( INT32  clientFd)

在文件 telnet_dev.c382 行定义.

383{
384 INT32 ret;
385
386 if (clientFd < 0) {
387 PRINT_ERR("Invalid telnet clientFd.\n");
388 return -1;
389 }
390 ret = system_console_init(TELNET);//创建一个带远程登录功能的控制台
391 if (ret != 0) {
392 PRINT_ERR("Telnet console init error.\n");
393 return ret;
394 }
395 ret = ioctl(STDIN_FILENO, CFG_TELNET_SET_FD, clientFd);//绑定FD,相当于shell和控制台绑定
396 if (ret != 0) {
397 PRINT_ERR("Telnet device ioctl error.\n");
398 (VOID)system_console_deinit(TELNET);
399 }
400 return ret;
401}
INT32 system_console_init(const CHAR *deviceName)
初始化系统控制台并返回 stdinfd stdoutfd stderrfd ,和system_console_deinit成对出现,像控制台的构造函数
Definition: console.c:1329
函数调用图:
这是这个函数的调用关系图:

◆ TelnetedRegister()

INT32 TelnetedRegister ( VOID  )

在文件 telnet_dev.c365 行定义.

366{
367 INT32 ret;
368
369 g_telnetDev.id = 0;
370 g_telnetDev.cmdFifo = NULL;
371 g_telnetDev.eventPend = TRUE;
372 //注册 telnet 驱动, g_telnetDev为私有数据
373 ret = register_driver(TELNET, &g_telnetOps, TELNET_DEV_DRV_MODE, &g_telnetDev);//翻译过来是当读TELNET时,真正要去操作的是 g_telnetDev
374 if (ret != 0) {
375 PRINT_ERR("Telnet register driver error.\n");
376 }
377 return ret;
378}
BOOL eventPend
任务是否处于挂起
Definition: telnet_dev.h:66
UINT32 id
Definition: telnet_dev.h:65
STATIC TELNET_DEV_S g_telnetDev
远程登录设备
Definition: telnet_dev.c:56
STATIC const struct file_operations_vfs g_telnetOps
Definition: telnet_dev.c:339
这是这个函数的调用关系图:

◆ TelnetedUnregister()

INT32 TelnetedUnregister ( VOID  )

在文件 telnet_dev.c354 行定义.

355{
357 g_telnetDev.cmdFifo = NULL;
358 (VOID)unregister_driver(TELNET);//注销字符设备驱动
359
360 return 0;
361}
函数调用图:
这是这个函数的调用关系图:

◆ TelnetIoctl()

STATIC INT32 TelnetIoctl ( struct file file,
const INT32  cmd,
unsigned long  arg 
)

远程登录控制操作

在文件 telnet_dev.c285 行定义.

286{
287 TELNET_DEV_S *telnetDev = NULL;
288
289 TelnetLock();
290
291 telnetDev = GetTelnetDevByFile(file, FALSE);
292 if (telnetDev == NULL) {
293 TelnetUnlock();
294 return -1;
295 }
296
297 if (cmd == CFG_TELNET_EVENT_PEND) {
298 if (arg == 0) {
299 telnetDev->eventPend = FALSE;
300 (VOID)LOS_EventWrite(&(telnetDev->eventTelnet), TELNET_EVENT_MORE_CMD);
301 (VOID)LOS_EventClear(&(telnetDev->eventTelnet), ~TELNET_EVENT_MORE_CMD);
302 } else {
303 telnetDev->eventPend = TRUE;
304 }
305 } else if (cmd == CFG_TELNET_SET_FD) {
306 if (arg >= (FD_SETSIZE - 1)) {
307 TelnetUnlock();
308 return -1;
309 }
310 telnetDev->clientFd = (INT32)arg;
311 }
312 TelnetUnlock();
313 return 0;
314}
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask)
清除指定的事件类型
Definition: los_event.c:355
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
写指定的事件类型
Definition: los_event.c:318
INT32 clientFd
打开终端文件句柄
Definition: telnet_dev.h:64
函数调用图:

◆ TelnetOpen()

STATIC INT32 TelnetOpen ( struct file file)

在文件 telnet_dev.c140 行定义.

141{
142 struct wait_queue_head *wait = NULL;
143 TELNET_DEV_S *telnetDev = NULL;
144
145 TelnetLock();
146
147 telnetDev = GetTelnetDevByFile(file, TRUE);//获取标准file私有数据
148 if (telnetDev == NULL) {
149 TelnetUnlock();
150 return -1;
151 }
152
153 if (telnetDev->cmdFifo == NULL) {
154 wait = &telnetDev->wait;
155 (VOID)LOS_EventInit(&telnetDev->eventTelnet);//初始化事件
156 g_event = &telnetDev->eventTelnet;
157 telnetDev->cmdFifo = (TELNTE_FIFO_S *)malloc(sizeof(TELNTE_FIFO_S));
158 if (telnetDev->cmdFifo == NULL) {
159 TelnetUnlock();
160 return -1;
161 }
162 (VOID)memset_s(telnetDev->cmdFifo, sizeof(TELNTE_FIFO_S), 0, sizeof(TELNTE_FIFO_S));
163 telnetDev->cmdFifo->fifoNum = FIFO_MAX;
164 LOS_ListInit(&wait->poll_queue);
165 }
166 g_currentVnode = file->f_vnode;
167 TelnetUnlock();
168 return 0;
169}
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
初始化一个事件控制块
Definition: los_event.c:95
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
UINT32 fifoNum
Definition: telnet_dev.h:58
函数调用图:

◆ TelnetPoll()

STATIC INT32 TelnetPoll ( struct file file,
poll_table *  table 
)

在文件 telnet_dev.c316 行定义.

317{
318 TELNET_DEV_S *telnetDev = NULL;
319
320 TelnetLock();
321
322 telnetDev = GetTelnetDevByFile(file, FALSE);
323 if ((telnetDev == NULL) || (telnetDev->cmdFifo == NULL)) {
324 TelnetUnlock();
325 return -1;
326 }
327
328 poll_wait(file, &telnetDev->wait, table);
329
330 /* check if there are some commands to run */
331 if (telnetDev->cmdFifo->fifoNum != FIFO_MAX) {
332 TelnetUnlock();
333 return POLLIN | POLLRDNORM;
334 }
335 TelnetUnlock();
336 return 0;
337}
void poll_wait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
函数调用图:

◆ TelnetRead()

STATIC ssize_t TelnetRead ( struct file file,
CHAR buf,
size_t  bufLen 
)

在文件 telnet_dev.c203 行定义.

204{
205 UINT32 i;
206 TELNET_DEV_S *telnetDev = NULL;
207
208 TelnetLock();
209
210 telnetDev = GetTelnetDevByFile(file, FALSE);//通过文件获取远程登录实体
211 if ((buf == NULL) || (telnetDev == NULL) || (telnetDev->cmdFifo == NULL)) {
212 TelnetUnlock();
213 return -1;
214 }
215
216 if (telnetDev->eventPend) {//挂起时,说明没有数据可读,等待事件发生
217 TelnetUnlock();
218 (VOID)LOS_EventRead(g_event, TELNET_EVENT_MORE_CMD, LOS_WAITMODE_OR, LOS_WAIT_FOREVER);//等待读取 TELNET_EVENT_MORE_CMD 事件
219 TelnetLock();
220 }
221
222 if (bufLen > (FIFO_MAX - telnetDev->cmdFifo->fifoNum)) {
223 bufLen = FIFO_MAX - telnetDev->cmdFifo->fifoNum;
224 }
225 //把远程终端过来的数据接走, 一般由 Shell Entry 任务中的 read(fd,&buf)读走数据
226 for (i = 0; i < bufLen; i++) {
227 *buf++ = telnetDev->cmdFifo->rxBuf[telnetDev->cmdFifo->rxOutIndex++];
228 if (telnetDev->cmdFifo->rxOutIndex >= FIFO_MAX) {
229 telnetDev->cmdFifo->rxOutIndex = 0;
230 }
231 }
232 telnetDev->cmdFifo->fifoNum += bufLen;
233 /* check if no more commands left to run | 检查是否没有更多命令可以运行 */
234 if (telnetDev->cmdFifo->fifoNum == FIFO_MAX) {
235 (VOID)LOS_EventClear(&telnetDev->eventTelnet, ~TELNET_EVENT_MORE_CMD);//清除读取内容事件
236 }
237
238 TelnetUnlock();
239 return (ssize_t)bufLen;
240}
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
读取指定事件类型,超时时间为相对时间:单位为Tick
Definition: los_event.c:313
INT64 ssize_t
Definition: los_typedef.h:79
unsigned int UINT32
Definition: los_typedef.h:57
UINT32 rxOutIndex
Definition: telnet_dev.h:57
CHAR rxBuf[FIFO_MAX]
Definition: telnet_dev.h:60
函数调用图:

◆ TelnetTx()

INT32 TelnetTx ( const CHAR buf,
UINT32  bufLen 
)

在文件 telnet_dev.c94 行定义.

95{
96 UINT32 i;
97 TELNET_DEV_S *telnetDev = NULL;
98
99 TelnetLock();
100
101 telnetDev = &g_telnetDev;
102 if ((buf == NULL) || (telnetDev->cmdFifo == NULL)) {
103 TelnetUnlock();
104 return -1;
105 }
106
107 /* size limited */
108 if (bufLen > telnetDev->cmdFifo->fifoNum) {//一次拿不完数据的情况
109 bufLen = telnetDev->cmdFifo->fifoNum;//只能装满
110 }
111
112 if (bufLen == 0) { //参数要先判断 @note_thinking
113 TelnetUnlock();
114 return 0;
115 }
116
117 /* copy commands to the fifo of the telnet device | 复制命令到telnet设备的fifo*/
118 for (i = 0; i < bufLen; i++) {
119 telnetDev->cmdFifo->rxBuf[telnetDev->cmdFifo->rxIndex] = *buf;
120 telnetDev->cmdFifo->rxIndex++;
121 telnetDev->cmdFifo->rxIndex %= FIFO_MAX;
122 buf++;
123 }
124 telnetDev->cmdFifo->fifoNum -= bufLen;
125
126 if (telnetDev->eventPend) {
127 /* signal that there are some works to do */
128 (VOID)LOS_EventWrite(&telnetDev->eventTelnet, TELNET_EVENT_MORE_CMD);
129 }
130 /* notify the command resolver task */
131 notify_poll(&telnetDev->wait);
132 TelnetUnlock();
133
134 return (INT32)bufLen;
135}
UINT32 rxIndex
Definition: telnet_dev.h:56
函数调用图:
这是这个函数的调用关系图:

◆ TelnetWrite()

STATIC ssize_t TelnetWrite ( struct file file,
const CHAR buf,
const size_t  bufLen 
)

在文件 telnet_dev.c248 行定义.

249{
250 INT32 ret = 0;
251 TELNET_DEV_S *telnetDev = NULL;
252
253 TelnetLock();
254
255 telnetDev = GetTelnetDevByFile(file, FALSE);
256 if ((buf == NULL) || (telnetDev == NULL) || (telnetDev->cmdFifo == NULL)) {
257 TelnetUnlock();
258 return -1;
259 }
260
261 if (OS_INT_ACTIVE) {
262 TelnetUnlock();
263 return ret;
264 }
265
266 if (!OsPreemptable()) {//@note_thinking 这里为何要有这个判断?
267 TelnetUnlock();
268 return ret;
269 }
270
271 if (telnetDev->clientFd != 0) {
272#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE
273 /* DO NOT call blocking API in software timer task | 不要在软件定时器任务中调用阻塞 API */
275 TelnetUnlock();
276 return ret;
277 }
278#endif
279 ret = send(telnetDev->clientFd, buf, bufLen, 0);//向 socket 发送
280 }
281 TelnetUnlock();
282 return ret;
283}
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
STATIC INLINE BOOL OsPreemptable(VOID)
BOOL OsIsSwtmrTask(const LosTaskCB *taskCB)
Definition: los_swtmr.c:383
ssize_t send(int s, const void *dataptr, size_t size, int flags)
相当于文件操作的 write 功能,区别是第四个参数 同 recv
Definition: socket.c:257
函数调用图:

变量说明

◆ g_currentVnode

STATIC struct Vnode* g_currentVnode

在文件 telnet_dev.c58 行定义.

◆ g_event

STATIC EVENT_CB_S* g_event

在文件 telnet_dev.c57 行定义.

◆ g_telnetDev

STATIC TELNET_DEV_S g_telnetDev

远程登录设备

在文件 telnet_dev.c56 行定义.

◆ g_telnetOps

STATIC const struct file_operations_vfs g_telnetOps
初始值:
= {
NULL,
NULL,
#ifndef CONFIG_DISABLE_POLL
#endif
NULL,
}
STATIC INT32 TelnetOpen(struct file *file)
Definition: telnet_dev.c:140
STATIC INT32 TelnetIoctl(struct file *file, const INT32 cmd, unsigned long arg)
远程登录控制操作
Definition: telnet_dev.c:285
STATIC INT32 TelnetPoll(struct file *file, poll_table *table)
Definition: telnet_dev.c:316
STATIC ssize_t TelnetWrite(struct file *file, const CHAR *buf, const size_t bufLen)
Definition: telnet_dev.c:248
STATIC INT32 TelnetClose(struct file *file)
Definition: telnet_dev.c:174
STATIC ssize_t TelnetRead(struct file *file, CHAR *buf, size_t bufLen)
Definition: telnet_dev.c:203

在文件 telnet_dev.c339 行定义.