| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891 |
- /*
- * Copyright (c) 2018, Real-Thread Information Technology Ltd
- * All rights reserved
- *
- * This software is dual-licensed: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. For the terms of this
- * license, see <http://www.gnu.org/licenses/>.
- *
- * You are free to use this software under the terms of the GNU General
- * Public License, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * Alternatively, you can license this software under a commercial
- * license, please send mail to business@rt-thread.com for contact.
- *
- * Change Logs:
- * Date Author Notes
- * 2018-09-25 ZYH the first version
- */
- #include <rdbd.h>
- #include "rtdevice.h"
- #include <stdio.h>
- #include <string.h>
- //#include <dirent.h>
- #include <dstr.h>
- #include <rdbd_service.h>
- #include <rdbd_service_manager.h>
- #include <fcntl.h>
- #include <sys/time.h>
- #include <libc.h>
- #include <dfs_select.h>
- #include <dfs_posix.h>
- //select dfs
- //select libc
- //select dstr v0.2.0
- #define RDBD_FILE_HASH_FNV_SEED 0x811C9DC5
- #undef DBG_ENABLE
- #define DBG_SECTION_NAME "RDBD FILE"
- #define DBG_LEVEL DBG_LOG
- #define DBG_COLOR
- #include <rtdbg.h>
- #define RDBD_FILE_CTRL_NEW_FILE 0x40
- #define RDBD_FILE_CTRL_WRITE_FILE 0x41
- #define RDBD_FILE_CTRL_WRITE_DONE 0x42
- #define RDBD_FILE_CTRL_LIST_DIR 0x43
- #define RDBD_FILE_CTRL_READ_FILE 0x44
- #define RDBD_FILE_CTRL_RM_FILE 0x45
- #define RDBD_FTLE_CTRL_GET_HASH 0x46
- #define RDBD_FTLE_CTRL_DIR_SYNC_START 0x47
- #define RDBD_FTLE_CTRL_DIR_SYNC_STOP 0x48
- #define RDBD_FTLE_CTRL_CHECK_PATH 0x49
- #define RDBD_FTLE_CTRL_PATH_IS_DIR 0x01
- #define RDBD_FTLE_CTRL_PATH_IS_FILE 0x02
- #define RDBD_FTLE_CTRL_PATH_NONE 0x00
- #define RDBD_FILE_READ_BLOCK_SIZE 4096
- #define RDBD_FILE_HEADER_SIZE (sizeof(struct rdbd_file_control_msg_header))
- #define RDBD_FILE_MSG_SIZE(x) (RDBD_FILE_MSG_MSG(x)->header.pathlength + RDBD_FILE_MSG_MSG(x)->header.length + RDBD_FILE_HEADER_SIZE)
- #define RDBD_FILE_MSG_RAW(x) ((rt_uint8_t *)x)
- #define RDBD_FILE_MSG_MSG(x) ((rdbd_file_ctrl_msg_t)x)
- struct rdbd_file_control_msg_header
- {
- rt_uint16_t command;
- rt_uint16_t pathlength;
- rt_uint32_t offset;
- rt_uint32_t length;
- };
- struct rdbd_file_session
- {
- rt_list_t list;
- char * path;
- int flag;
- int fd;
- };
- static struct rdbd_file_session * create_session(rt_list_t * session_list, char * path, int flag)
- {
- struct rdbd_file_session * session;
- if(session_list )
- session = rt_calloc(sizeof(struct rdbd_file_session), 1);
- if(RT_NULL == session_list || RT_NULL == path)
- {
- LOG_E("Invalid args %s,%d", __FUNCTION__, __LINE__);
- return RT_NULL;
- }
- session->fd = -1;
- session->flag = flag;
- session->path = rt_strdup(path);
- if(RT_NULL == session->path)
- {
- LOG_E("No memory create session");
- goto _error;
- }
- session->fd = open(session->path, session->flag);
- if(session->fd < 0)
- {
- LOG_E("Open file %s error", session->path);
- goto _error;
- }
- rt_list_insert_before(session_list, &session->list);
- return session;
-
- _error:
- if(session)
- {
- if(session->path)
- {
- rt_free(session->path);
- }
- if(session->fd >= 0)
- {
- close(session->fd);
- }
- free(session);
- }
- return RT_NULL;
- }
- static struct rdbd_file_session * find_session(rt_list_t * session_list, char * path)
- {
- rt_list_t * node;
- if(RT_NULL == session_list || RT_NULL == path)
- {
- LOG_E("Invalid args %s,%d", __FUNCTION__, __LINE__);
- return RT_NULL;
- }
-
- for(node = session_list->next;
- node != session_list;
- node = node->next)
- {
- if(strcmp(path, rt_list_entry(node, struct rdbd_file_session, list)->path) == 0)
- {
- return rt_list_entry(node, struct rdbd_file_session, list);
- }
- }
- return RT_NULL;
- }
- static int delete_session(struct rdbd_file_session * session)
- {
- if(RT_NULL == session)
- {
- LOG_E("Invalid args %s,%d", __FUNCTION__, __LINE__);
- return -1;
- }
- fsync(session->fd);
- close(session->fd);
- rt_free(session->path);
- rt_list_remove(&session->list);
- rt_free(session);
- return 0;
- }
- static int read_session(struct rdbd_file_session * session, off_t offset, rt_uint8_t * buffer, rt_size_t len)
- {
- if(RT_NULL == session || RT_NULL == buffer)
- {
- LOG_E("Invalid args %s,%d", __FUNCTION__, __LINE__);
- return -1;
- }
- if((session->flag & 0xF) == O_WRONLY)
- {
- LOG_E("Invalid read %s,%d", __FUNCTION__, __LINE__);
- return -1;
- }
- LOG_I("seek to %d", offset);
-
- lseek(session->fd, offset, SEEK_SET);
-
- LOG_I("Read fd %d, 0x%08X %d", session->fd, buffer, len);
- return read(session->fd, buffer, len);
- }
- static int write_session(struct rdbd_file_session * session, off_t offset, const rt_uint8_t * buffer, rt_size_t len)
- {
- if(RT_NULL == session || RT_NULL == buffer)
- {
- LOG_E("Invalid args %s,%d", __FUNCTION__, __LINE__);
- return -1;
- }
- if((session->flag & 0xF) == O_RDONLY)
- {
- LOG_E("Invalid write %s,%d", __FUNCTION__, __LINE__);
- return -1;
- }
- lseek(session->fd, offset, SEEK_SET);
- return write(session->fd, buffer, len);
- }
- struct rdbd_file_control_msg
- {
- struct rdbd_file_control_msg_header header;
- rt_uint8_t msg[RT_UINT16_MAX];
- };
- typedef struct rdbd_file_control_msg * rdbd_file_ctrl_msg_t;
- struct file_request_send
- {
- rt_list_t list;
- char * msg;
- int msg_pos;
- int request_file_send;
- };
- static rt_uint32_t rdbd_file_calc_hash(const char * filename);
- static rt_dstr_t * get_file_list(const char *pathname);
- static int file_service_request_send(rt_list_t * header, struct rdbd_file_control_msg * msg, int request_file_send);
- static int file_service_delete_request(struct file_request_send * request);
- static void file_service_thread_entry(void * arg)
- {
- struct rdbd_service * file_service= (struct rdbd_service *)arg;
- fd_set readset, writeset;
- int result = 0;
- int res = 0;
- int max_fd = file_service->in_pipe_read_fd + 1;
- rt_list_t request_write_list;
- rt_list_t session_list;
- struct file_request_send * request;
- rdbd_file_ctrl_msg_t msg = RT_NULL;
- int msg_pos = 0;
- rt_dstr_t * file_list;
- char * path;
- struct rdbd_file_session * session = RT_NULL;
- rt_list_init(&request_write_list);
- rt_list_init(&session_list);
-
- while(1)
- {
- FD_ZERO(&readset);
- FD_ZERO(&writeset);
- FD_SET(file_service->in_pipe_read_fd, &readset);
- if(!rt_list_isempty(&request_write_list)) //need write data to pc
- {
- FD_SET(file_service->out_pipe_write_fd, &writeset);
- if(file_service->out_pipe_write_fd > (max_fd - 1))
- {
- max_fd = file_service->out_pipe_write_fd + 1;
- }
- }
- res = select(max_fd, &readset, &writeset, RT_NULL, RT_NULL);
- if(res > 0)
- {
- if(FD_ISSET(file_service->in_pipe_read_fd, &readset))
- {
- if(msg == RT_NULL)
- {
- msg = rt_calloc(RDBD_FILE_HEADER_SIZE, 1);
- msg_pos = read(file_service->in_pipe_read_fd, RDBD_FILE_MSG_RAW(msg), RDBD_FILE_HEADER_SIZE);
- if(msg_pos < 0)
- {
- msg_pos = 0;
- }
- }
- else if(msg_pos < RDBD_FILE_HEADER_SIZE)//continue read header
- {
- result = read(file_service->in_pipe_read_fd,
- RDBD_FILE_MSG_RAW(msg) + msg_pos,
- RDBD_FILE_HEADER_SIZE - msg_pos);//read header
- if(result > 0)
- {
- msg_pos += result;
- }
- }
- else if(msg_pos < (RDBD_FILE_MSG_SIZE(msg)))//read body
- {
- if(msg_pos == RDBD_FILE_HEADER_SIZE)
- {
- msg = rt_realloc(msg, RDBD_FILE_MSG_SIZE(msg));//realloc
- }
- result = read(file_service->in_pipe_read_fd,
- RDBD_FILE_MSG_RAW(msg) + msg_pos,
- RDBD_FILE_MSG_SIZE(msg) - msg_pos);//read body
- if(result > 0)
- {
- msg_pos += result;
- }
- if(msg_pos == RDBD_FILE_MSG_SIZE(msg))//read done
- {
- path = rt_calloc(1,msg->header.pathlength + 1);
- if(RT_NULL == path)
- {
- LOG_E("no memory");
- RT_ASSERT(0);
- }
- rt_strncpy(path, (const char *)msg->msg, msg->header.pathlength);
- LOG_D("path: %s", path);
- path[msg->header.pathlength] = '\0';
- if(RDBD_FILE_CTRL_NEW_FILE == msg->header.command || RDBD_FILE_CTRL_WRITE_FILE == msg->header.command)//Done
- {
- while (1) //replace '\\' to '/'
- {
- char *p;
- p = strchr(path, '\\');
- if (p)
- {
- *p = '/';
- }
- else
- {
- break;
- }
- }
- {
- char *begin, *end;
- begin = path;
- char *_path;
- while (1)
- {
- end = strchr(begin, '/'); //find '\\' since begin
- if (end == NULL) //if not find '\\' finsh
- {
- break;
- }
- if (begin == end) //if begin is '\\'
- {
- begin += 1;
- continue;
- }
- _path = rt_malloc(end - path + 1);
- if (_path == RT_NULL) //malloc fail
- {
- break;//???
- }
- strncpy(_path, path, end - path); //copy path
- _path[end - path] = '\0';
- {
- if (access(_path, 0) != 0) //dir not exist
- {
- if (mkdir(_path, 0777) != 0) //create fail
- {
- LOG_E("mkdir %s failed", _path);
- free(_path);
- _path = RT_NULL;
- break;
- }
- }
- }
- free(_path);
- _path = RT_NULL;
- begin = end + 1; //next
- }
- }
-
- switch(msg->header.command)
- {
- case RDBD_FILE_CTRL_NEW_FILE:
- session = create_session(&session_list, path, O_CREAT|O_TRUNC|O_WRONLY);
- if(session == RT_NULL)
- {
- LOG_E("Create file error %s", path);
- RT_ASSERT(0);
- }
- break;
- case RDBD_FILE_CTRL_WRITE_FILE:
- session = find_session(&session_list, path);
- if(session == RT_NULL)
- {
- LOG_E("Please open the file %s first", path);
- RT_ASSERT(0);
- }
- break;
- default:
- RT_ASSERT(0);
- }
- LOG_D("Offset %d", msg->header.offset);
- LOG_D("Write %d", msg->header.length);
- if(msg->header.length)
- {
- if(write_session(session, msg->header.offset, &msg->msg[msg->header.pathlength], msg->header.length) != msg->header.length)
- {
- LOG_W("Space not enought");
- }
- }
- session = RT_NULL;
- //end of function release mem
- }
- else if(RDBD_FILE_CTRL_WRITE_DONE == msg->header.command)
- {
- session = find_session(&session_list, path);
- if(session == RT_NULL)
- {
- LOG_W("Not need release session %s", path);
- RT_ASSERT(0);
- }
- delete_session(session);
- }
- else if(RDBD_FILE_CTRL_READ_FILE == msg->header.command)
- {
- msg = rt_realloc(msg, msg->header.pathlength + RDBD_FILE_READ_BLOCK_SIZE + RDBD_FILE_HEADER_SIZE);
- if(msg == RT_NULL)
- {
- LOG_E("No memory");
- RT_ASSERT(0);
- }
- session = create_session(&session_list, path, O_RDONLY);
- if(session == RT_NULL)
- {
- LOG_E("Open file error %s", path);
- RT_ASSERT(0);
- }
-
- msg->header.offset = 0;
- msg->header.length = read_session(session, msg->header.offset, &msg->msg[msg->header.pathlength], RDBD_FILE_READ_BLOCK_SIZE);
- file_service_request_send(&request_write_list, msg, 1);
- msg = RT_NULL;
- }
- else if(RDBD_FILE_CTRL_RM_FILE == msg->header.command)
- {
- remove(path);
- }
- else if(RDBD_FILE_CTRL_LIST_DIR == msg->header.command)
- {
- file_list = get_file_list(path);
- msg->header.offset = 0;
- msg->header.pathlength = 0;
- msg->header.length = rt_dstr_strlen(file_list);
- msg = rt_realloc(msg, RDBD_FILE_MSG_SIZE(msg));
- memcpy(msg->msg, file_list->str, msg->header.length);
- file_service_request_send(&request_write_list, msg, 0);
- rt_dstr_del(file_list);
- file_list = RT_NULL;
- msg = RT_NULL;
- }
- else if(RDBD_FTLE_CTRL_GET_HASH == msg->header.command)
- {
- msg->header.length = 4;
- msg->header.offset = 0;
- msg = rt_realloc(msg, RDBD_FILE_MSG_SIZE(msg));
- {
- rt_uint32_t hash = rdbd_file_calc_hash(path);
- memcpy(&msg->msg[msg->header.pathlength], &hash, 4);
- }
- file_service_request_send(&request_write_list, msg, 0);
- msg = RT_NULL;
- }
- else if(RDBD_FTLE_CTRL_DIR_SYNC_START == msg->header.command)
- {
- //TO DO
- }
- else if(RDBD_FTLE_CTRL_DIR_SYNC_STOP == msg->header.command)
- {
- //TO DO
- }
- else if(RDBD_FTLE_CTRL_CHECK_PATH == msg->header.command)
- {
- msg->header.length = 1;
- msg->header.offset = 0;
- msg = rt_realloc(msg, RDBD_FILE_MSG_SIZE(msg));
- {
- struct stat filestat;
- if (stat(path, &filestat) == -1)
- {
- msg->msg[msg->header.pathlength] = RDBD_FTLE_CTRL_PATH_NONE;
- }
- else
- {
- if((filestat.st_mode & S_IFMT) == S_IFDIR)
- {
- msg->msg[msg->header.pathlength] = RDBD_FTLE_CTRL_PATH_IS_DIR;
- }
- else
- {
- msg->msg[msg->header.pathlength] = RDBD_FTLE_CTRL_PATH_IS_FILE;
- }
- }
- }
- file_service_request_send(&request_write_list, msg, 0);
- msg = RT_NULL;
- }
- if(RT_NULL != path)
- {
- rt_free(path);
- path = RT_NULL;
- }
- if(RT_NULL != msg)
- {
- rt_free(msg);
- msg = RT_NULL;
- }
- }
- }
- }
- if(!rt_list_isempty(&request_write_list)) //need write data to pc
- {
- if(FD_ISSET(file_service->out_pipe_write_fd, &writeset))
- {
- request = rt_list_entry(request_write_list.next, struct file_request_send, list);
- result = write(file_service->out_pipe_write_fd,
- request->msg + request->msg_pos, RDBD_FILE_MSG_SIZE(request->msg) - request->msg_pos);
- if(result > 0)
- {
- request->msg_pos += result;
- }
- if(request->msg_pos == RDBD_FILE_MSG_SIZE(request->msg))
- {
- request->msg_pos = 0;
- if(request->request_file_send && 0 != RDBD_FILE_MSG_MSG(request->msg)->header.length)
- {
- RDBD_FILE_MSG_MSG(request->msg)->header.offset += RDBD_FILE_MSG_MSG(request->msg)->header.length;
- path = rt_calloc(1,RDBD_FILE_MSG_MSG(request->msg)->header.pathlength + 1);
- if(RT_NULL == path)
- {
- LOG_E("No memory");
- RT_ASSERT(0);
- }
- rt_strncpy(path, (const char *)RDBD_FILE_MSG_MSG(request->msg)->msg, RDBD_FILE_MSG_MSG(request->msg)->header.pathlength);
- path[RDBD_FILE_MSG_MSG(request->msg)->header.pathlength] = '\0';
-
- request->msg = rt_realloc(request->msg, RDBD_FILE_MSG_MSG(request->msg)->header.pathlength + RDBD_FILE_READ_BLOCK_SIZE + RDBD_FILE_HEADER_SIZE);
- if(request->msg == RT_NULL)
- {
- LOG_E("No memory");
- RT_ASSERT(0);
- }
- session = find_session(&session_list, path);
- if(session == RT_NULL)
- {
- LOG_E("Please open the file %s first", path);
- RT_ASSERT(0);
- }
- free(path);
- path = RT_NULL;
- RDBD_FILE_MSG_MSG(request->msg)->header.length = read_session(session, RDBD_FILE_MSG_MSG(request->msg)->header.offset, &RDBD_FILE_MSG_MSG(request->msg)->msg[RDBD_FILE_MSG_MSG(request->msg)->header.pathlength], RDBD_FILE_READ_BLOCK_SIZE);
- if(RDBD_FILE_MSG_MSG(request->msg)->header.length == 0)
- {
- RDBD_FILE_MSG_MSG(request->msg)->header.command = RDBD_FILE_CTRL_WRITE_DONE;
- request->request_file_send = 0;
- delete_session(session);
- session = RT_NULL;
- }
- }
- else
- {
- file_service_delete_request(request);
- }
- }
- }
- }
- }
- }
- }
- static int start(void * args);
- static int stop(void * args);
- static int resume(void * args);
- static int suspend(void * args);
- static struct rdbd_service_control_ops control_ops =
- {
- start,
- stop,
- resume,
- suspend,
- };
- static int file_service_request_send(rt_list_t * header, struct rdbd_file_control_msg * msg, int request_file_send)
- {
- struct file_request_send * request;
- if(RT_NULL == header || RT_NULL == msg)
- {
- LOG_E("Write request arg error");
- return -1;
- }
- request = rt_malloc(sizeof(struct file_request_send));
- if(RT_NULL == request)
- {
- LOG_E("No memory request send to file");
- return -1;
- }
- request->msg = (char *)msg;
- request->msg_pos = 0;
- request->request_file_send = request_file_send;
- rt_list_insert_before(header, &request->list);
- return 0;
- }
- static int file_service_delete_request(struct file_request_send * request)
- {
- if(RT_NULL == request)
- {
- LOG_E("Delete request arg error");
- return -1;
- }
- if(RT_NULL != request->msg)
- {
- rt_free(request->msg);
- }
- rt_list_remove(&request->list);
- rt_free(request);
- return 0;
- }
- int rdbd_file_service_init(void)
- {
- struct rdbd_service * file_service;
- rdbd_t usbrdbd = rdbd_find("usb");
- if(RT_NULL == usbrdbd)
- {
- LOG_E("rdbd usb find error");
- return -1;
- }
- file_service = rdbd_create_service(RDBD_SERVICE_ID_FILE, "file", &control_ops, RT_NULL, "filein", 1024,"fileout", 1024, RDBD_SERVICE_FLAG_WR|RDBD_SERVICE_FLAG_RD);
- if(RT_NULL == file_service)
- {
- LOG_E("file_service create error");
- goto _error;
- }
- LOG_I("Service %s created :", file_service->name);
- LOG_I("in_pipe_path %s", file_service->in_pipe_path);
- LOG_I("out_pipe_path %s", file_service->out_pipe_path);
- LOG_I("service_id %d", file_service->service_id);
- LOG_I("status %d", file_service->status);
- rdbd_service_install(usbrdbd, file_service);
-
- rdbd_service_control(file_service, RDBD_SERVICE_START, file_service);
-
- return 0;
- _error:
- if(RT_NULL != usbrdbd)
- {
- //TO DO
- }
- return -1;
- }
- INIT_APP_EXPORT(rdbd_file_service_init);
- static int start(void * args)
- {
- struct rdbd_service * file_service = (struct rdbd_service *)args;
- if(RT_NULL == file_service)
- {
- LOG_E("Start up service error, args is null");
- return -1;
- }
-
- if(file_service->flag & RDBD_SERVICE_FLAG_RD)
- {
- file_service->in_pipe_read_fd = open(file_service->in_pipe_path, O_RDONLY | O_NONBLOCK, 0);
- if(file_service->in_pipe_read_fd < 0)
- {
- LOG_E("Start up service %s error open in pipe failed",file_service->name);
- return -1;
- }
- }
- if(file_service->flag & RDBD_SERVICE_FLAG_WR)
- {
- file_service->out_pipe_write_fd = open(file_service->out_pipe_path, O_WRONLY | O_NONBLOCK, 0);
- if(file_service->out_pipe_write_fd < 0)
- {
- LOG_E("Start up service %s error open out pipe failed",file_service->name);
- goto _error;
- }
- }
-
-
- if(file_service->flag & RDBD_SERVICE_FLAG_RD)
- {
- file_service->in_pipe_write_fd = open(file_service->in_pipe_path, O_WRONLY | O_NONBLOCK, 0);
- if(file_service->in_pipe_write_fd < 0)
- {
- LOG_E("Start up transfer error open in pipe failed",file_service->name);
- return -1;
- }
- }
- if(file_service->flag & RDBD_SERVICE_FLAG_WR)
- {
- file_service->out_pipe_read_fd = open(file_service->out_pipe_path, O_RDONLY | O_NONBLOCK, 0);
- if(file_service->out_pipe_read_fd < 0)
- {
- LOG_E("Start up transfer error open out pipe failed",file_service->name);
- goto _error;
- }
- }
- file_service->service_thread = rt_thread_create(file_service->name,
- file_service_thread_entry,
- file_service,
- 2048,
- 21,
- 20);
- if(RT_NULL != file_service->service_thread)
- {
- if(RT_EOK != rt_thread_startup(file_service->service_thread))
- {
- rt_thread_delete(file_service->service_thread);
- file_service->service_thread = RT_NULL;
- goto _error;
- }
- }
- else
- {
- goto _error;
- }
- return 0;
-
- _error:
- stop(args);
- return -1;
- }
- static int stop(void * args)
- {
- struct rdbd_service * file_service = (struct rdbd_service *)args;
- if(RT_NULL == file_service)
- {
- LOG_E("Stop service error, args is null");
- return -1;
- }
- if(RT_NULL != file_service->service_thread)
- {
- if(RT_EOK != rt_thread_delete(file_service->service_thread))
- {
- LOG_E("Delete thread %s failed", file_service->service_thread->name);
- return -1;
- }
- file_service->service_thread = RT_NULL;
- }
-
- if(file_service->in_pipe_read_fd >= 0)
- {
- if(close(file_service->in_pipe_read_fd) < 0)
- {
- LOG_E("Close fd %d failed", file_service->in_pipe_read_fd);
- return -1;
- }
- file_service->in_pipe_read_fd = -1;
- }
-
- if(file_service->in_pipe_write_fd >= 0)
- {
- if(close(file_service->in_pipe_write_fd) < 0)
- {
- LOG_E("Close fd %d failed", file_service->in_pipe_write_fd);
- return -1;
- }
- file_service->in_pipe_write_fd = -1;
- }
-
- if(file_service->in_pipe_write_fd >= 0)
- {
- if(close(file_service->in_pipe_write_fd) < 0)
- {
- LOG_E("Close fd %d failed", file_service->in_pipe_write_fd);
- return -1;
- }
- file_service->in_pipe_write_fd = -1;
- }
-
- if(file_service->out_pipe_write_fd >= 0)
- {
- if(close(file_service->out_pipe_write_fd) < 0)
- {
- LOG_E("Close fd %d failed", file_service->out_pipe_write_fd);
- return -1;
- }
- file_service->out_pipe_write_fd = -1;
- }
-
- return 0;
- }
- static int resume(void * args)
- {
- //Not need
- return 0;
- }
- static int suspend(void * args)
- {
- //Not need
- return 0;
- }
- static rt_dstr_t * get_file_list(const char *pathname)
- {
- rt_dstr_t * list = RT_NULL, *fullpath = RT_NULL, *temp_list = RT_NULL;
- struct dirent * dir = NULL;
- DIR * root_dir = NULL;
- struct stat filestat;
- list = rt_dstr_new("");
- root_dir = opendir(pathname);
- if(root_dir == NULL)
- {
- return list;
- }
- while(1)
- {
- dir = readdir(root_dir);
- if(dir == NULL)
- {
- break;
- }
- if (strncmp(dir->d_name, ".", 1) == 0)
- continue; /* skip hide file*/
- if(strcmp("/", pathname) == 0)
- {
- fullpath = rt_dstr_sprintf(fullpath, "/%s", dir->d_name);
- }
- else
- {
- fullpath = rt_dstr_sprintf(fullpath, "%s/%s", pathname, dir->d_name);
- }
- if (stat(fullpath->str, &filestat) == -1)
- {
- LOG_E("cannot access the file %s", fullpath->str);
- return list;
- }
- if ((filestat.st_mode & S_IFMT) == S_IFDIR)
- {
- temp_list = get_file_list(fullpath->str);
- list = rt_dstr_append_printf(list, "%s", temp_list->str);
- rt_dstr_del(temp_list);
- temp_list = RT_NULL;
- }
- else
- {
- list = rt_dstr_append_printf(list, "%s\n", fullpath->str);
- }
- rt_dstr_del(fullpath);
- fullpath = RT_NULL;
- }
- closedir(root_dir);
- return list;
- }
- int list_dir(void)
- {
- int i = 0;
- rt_dstr_t * list = get_file_list("/");
- while(list->str[i] != '\0')
- {
- rt_kprintf("%c",list->str[i++]);
- }
-
- rt_dstr_del(list);
- return 0;
- }
- MSH_CMD_EXPORT(list_dir, list dir);
- /* hash a single byte */
- static rt_uint32_t fnv1a_r(unsigned char oneByte, rt_uint32_t hash)
- {
- return (oneByte ^ hash) * 0x01000193; // 0x01000193 = 16777619
- }
- static rt_uint32_t rdbd_file_calc_hash(const char * filename)
- {
- FILE * fp = NULL;
- int ch;
- uint32_t hash = RDBD_FILE_HASH_FNV_SEED;
- fp = fopen(filename, "r");
- if(fp == NULL)
- {
- LOG_W("%s not found!", filename);
- return 0;
- }
- while(1)
- {
- ch = fgetc(fp);
- if(ch == EOF)
- {
- break;
- }
- hash = fnv1a_r(ch, hash);
- }
- fclose(fp);
- return hash;
- }
|