1099 lines
30 KiB
C
1099 lines
30 KiB
C
#include "dev_manager.h"
|
||
#include "dev_reg.h"
|
||
#include "app_config.h"
|
||
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
|
||
#include "dev_multiplex_api.h"
|
||
#endif
|
||
#include "spi/nor_fs.h"
|
||
#include "dev_update.h"
|
||
|
||
// *INDENT-OFF*
|
||
|
||
#if (TCFG_DEV_MANAGER_ENABLE)
|
||
|
||
#define DEV_MANAGER_TASK_NAME "dev_mg"
|
||
#define DEV_MANAGER_SCAN_DISK_MAX_DEEPTH 9
|
||
|
||
///设备管理总控制句柄
|
||
struct __dev_manager {
|
||
struct list_head list;
|
||
OS_MUTEX mutex;
|
||
OS_SEM sem;
|
||
u32 counter;
|
||
};
|
||
static struct __dev_manager dev_mg;
|
||
#define __this (&dev_mg)
|
||
|
||
|
||
///设备节点结构体
|
||
struct __dev {
|
||
struct list_head entry;
|
||
struct __dev_reg *parm;//设备参数
|
||
struct imount *fmnt;
|
||
volatile u8 valid: 1;//有效设备标记, 这里有效是指是否有可播放文件
|
||
volatile u32 active_stamp;///活动设备时间戳,通过时间戳记录当前最后活动设备
|
||
};
|
||
|
||
|
||
static u32 __dev_manager_get_time_stamp(void)
|
||
{
|
||
u32 counter = __this->counter;
|
||
__this->counter ++;
|
||
return counter;
|
||
}
|
||
|
||
int __dev_manager_add(char *logo, u8 need_mount)
|
||
{
|
||
if (logo == NULL) {
|
||
return DEV_MANAGER_ADD_ERR_PARM;
|
||
}
|
||
int i;
|
||
printf("%s add start\n", logo);
|
||
struct __dev_reg *p = NULL;
|
||
struct __dev_reg *n;
|
||
|
||
for(n=(struct __dev_reg *)dev_reg; n->logo != NULL; n++){
|
||
if (!strcmp(n->logo, logo)) {
|
||
p = n;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (p) {
|
||
///挂载文件系统
|
||
if (dev_manager_list_check_by_logo(logo)) {
|
||
printf("dev online aready, err!!!\n");
|
||
return DEV_MANAGER_ADD_IN_LIST_AREADY;
|
||
}
|
||
struct __dev *dev = (struct __dev *)zalloc(sizeof(struct __dev));
|
||
if(dev == NULL){
|
||
return DEV_MANAGER_ADD_ERR_NOMEM;
|
||
}
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
if(need_mount){
|
||
dev->fmnt = mount(p->name, p->storage_path, p->fs_type, 3, NULL);
|
||
}
|
||
dev->parm = p;
|
||
dev->valid = (dev->fmnt ? 1 : 0);
|
||
dev->active_stamp = __dev_manager_get_time_stamp();//timer_get_ms();
|
||
list_add_tail(&dev->entry, &__this->list);
|
||
os_mutex_post(&__this->mutex);
|
||
printf("%s, %s add ok, dev->fmnt = %x, %d\n", __FUNCTION__, logo, (int)dev->fmnt, dev->active_stamp);
|
||
if(dev->fmnt == NULL){
|
||
return DEV_MANAGER_ADD_ERR_MOUNT_FAIL;
|
||
}
|
||
return DEV_MANAGER_ADD_OK;
|
||
}
|
||
printf("dev_manager_add can not find logo %s\n",logo);
|
||
return DEV_MANAGER_ADD_ERR_NOT_FOUND;
|
||
}
|
||
|
||
static int __dev_manager_del(char *logo)
|
||
{
|
||
if (logo == NULL) {
|
||
return -1;
|
||
}
|
||
struct __dev *dev, *n;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry_safe(dev, n, &__this->list, entry) {
|
||
if (!strcmp(dev->parm->logo, logo)) {
|
||
///卸载文件系统
|
||
if(dev->fmnt){
|
||
unmount(dev->parm->storage_path);
|
||
}
|
||
list_del(&dev->entry);
|
||
free(dev);
|
||
printf("%s, %s del ok\n", __FUNCTION__, logo);
|
||
break;
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return 0;
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备增加接口
|
||
@param logo:逻辑盘符,如:sd0/sd1/udisk0等
|
||
@return 0:成功,非0是失败
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int dev_manager_add(char *logo)
|
||
{
|
||
if(logo == NULL){
|
||
return -1;
|
||
}
|
||
int ret = 0;
|
||
#if TCFG_RECORD_FOLDER_DEV_ENABLE
|
||
char rec_dev_logo[16] = {0};
|
||
sprintf(rec_dev_logo, "%s%s", logo, "_rec");
|
||
ret = __dev_manager_add(rec_dev_logo, 1);
|
||
if(ret == DEV_MANAGER_ADD_OK){
|
||
ret = __dev_manager_add(logo, 1);
|
||
if(ret){
|
||
__dev_manager_del(logo);
|
||
__dev_manager_del(rec_dev_logo);
|
||
}
|
||
}else if(ret == DEV_MANAGER_ADD_ERR_NOT_FOUND){
|
||
ret = __dev_manager_add(logo, 1);
|
||
}
|
||
else{
|
||
ret = __dev_manager_add(logo, 0);
|
||
}
|
||
#else
|
||
ret = __dev_manager_add(logo, 1);
|
||
#endif//TCFG_RECORD_FOLDER_DEV_ENABLE
|
||
|
||
return ret;
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备删除接口
|
||
@param logo:逻辑盘符,如:sd0/sd1/udisk0等
|
||
@return 0:成功,非0是失败
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int dev_manager_del(char *logo)
|
||
{
|
||
if(logo == NULL){
|
||
return -1;
|
||
}
|
||
__dev_manager_del(logo);
|
||
#if TCFG_RECORD_FOLDER_DEV_ENABLE
|
||
char rec_dev_logo[16] = {0};
|
||
sprintf(rec_dev_logo, "%s%s", logo, "_rec");
|
||
__dev_manager_del(rec_dev_logo);
|
||
#endif//TCFG_RECORD_FOLDER_DEV_ENABLE
|
||
|
||
return 0;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过设备节点检查设备是否在线
|
||
@param dev:设备节点
|
||
@return 成功返回设备节点, 失败返回NULL
|
||
@note 通过设备节点检查设备是否在设备链表中
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_check(struct __dev *dev)
|
||
{
|
||
if (dev == NULL) {
|
||
return NULL;
|
||
}
|
||
struct __dev *p;
|
||
list_for_each_entry(p, &__this->list, entry) {
|
||
if(!(p->fmnt)){
|
||
continue;
|
||
}
|
||
if (dev == p) {
|
||
return p;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过盘符检查设备是否在线
|
||
@param logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 成功返回设备节点, 失败返回NULL
|
||
@note 通过设备节点检查设备是否在设备链表中
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_check_by_logo(char *logo)
|
||
{
|
||
if (logo == NULL) {
|
||
return NULL;
|
||
}
|
||
struct __dev *dev;
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
if(!(dev->fmnt)){
|
||
continue;
|
||
}
|
||
if (!strcmp(dev->parm->logo, logo)) {
|
||
return dev;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取设备总数
|
||
@param valid:
|
||
1:有效可播放设备, 0;所有设备,包括有可播放设备及无可播放设备
|
||
@return 设备总数
|
||
@note 根据使用情景决定接口参数
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u32 dev_manager_get_total(u8 valid)
|
||
{
|
||
u32 total_valid = 0;
|
||
u32 total = 0;
|
||
struct __dev *dev;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
if(!(dev->fmnt)){
|
||
continue;
|
||
}
|
||
if (dev->valid) {
|
||
total_valid++;
|
||
}
|
||
total ++;
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return (valid ? total_valid : total);
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取设备列表第一个设备
|
||
@param valid:
|
||
1:有效可播放设备, 0;所有设备,包括有可播放设备及无可播放设备
|
||
@return 成功返回设备设备节点,失败返回NULL
|
||
@note 根据使用情景决定接口参数
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_find_first(u8 valid)
|
||
{
|
||
struct __dev *dev = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
if(!(dev->fmnt)){
|
||
continue;
|
||
}
|
||
if(valid){
|
||
if (dev->valid) {
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
}else{
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取设备列表最后一个设备
|
||
@param valid:
|
||
1:有效可播放设备中查找
|
||
0:所有设备,包括有可播放设备及无可播放设备中查找
|
||
@return 成功返回设备设备节点,失败返回NULL
|
||
@note 根据使用情景决定接口参数
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_find_last(u8 valid)
|
||
{
|
||
struct __dev *dev = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry_reverse(dev, &__this->list, entry) {
|
||
if(!(dev->fmnt)){
|
||
continue;
|
||
}
|
||
if(valid){
|
||
if (dev->valid) {
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
}else{
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取上一个设备节点
|
||
@param
|
||
dev:当前设备节点
|
||
valid:
|
||
1:有效可播放设备中查找,
|
||
0:所有设备,包括有可播放设备及无可播放设备中查找
|
||
@return 成功返回设备设备节点,失败返回NULL
|
||
@note 根据当前设置的参数设备节点,找链表中的上一个设备
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_find_prev(struct __dev *dev, u8 valid)
|
||
{
|
||
if (dev == NULL) {
|
||
return NULL;
|
||
}
|
||
struct __dev *p = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
if (dev_manager_check(dev) == NULL) {
|
||
///传入的参数无效, 返回活动设备
|
||
os_mutex_post(&__this->mutex);
|
||
return dev_manager_find_active(valid);
|
||
}
|
||
list_for_each_entry(p, &dev->entry, entry) {
|
||
if((void*)p == (void*)(&__this->list)){
|
||
continue;
|
||
}
|
||
if(!(p->fmnt)){
|
||
continue;
|
||
}
|
||
if(valid){
|
||
if (p->valid) {
|
||
os_mutex_post(&__this->mutex);
|
||
return p;
|
||
}
|
||
}else{
|
||
os_mutex_post(&__this->mutex);
|
||
return p;
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取下一个设备节点
|
||
@param
|
||
dev:当前设备节点
|
||
valid:
|
||
1:有效可播放设备中查找,
|
||
0:所有设备,包括有可播放设备及无可播放设备中查找
|
||
@return 成功返回设备设备节点,失败返回NULL
|
||
@note 根据当前设置的参数设备节点,找链表中的下一个设备
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_find_next(struct __dev *dev, u8 valid)
|
||
{
|
||
if (dev == NULL) {
|
||
return NULL;
|
||
}
|
||
struct __dev *p = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
if (dev_manager_check(dev) == NULL) {
|
||
///传入的参数无效, 返回活动设备
|
||
os_mutex_post(&__this->mutex);
|
||
return dev_manager_find_active(valid);
|
||
}
|
||
|
||
list_for_each_entry_reverse(p, &dev->entry, entry) {
|
||
if((void*)p == (void*)(&__this->list)){
|
||
continue;
|
||
}
|
||
if(!(p->fmnt)){
|
||
continue;
|
||
}
|
||
if(valid){
|
||
if (p->valid) {
|
||
os_mutex_post(&__this->mutex);
|
||
return p;
|
||
}
|
||
}else{
|
||
os_mutex_post(&__this->mutex);
|
||
return p;
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取当前活动设备节点
|
||
@param
|
||
valid:
|
||
1:有效可播放设备中查找,
|
||
0:所有设备,包括有可播放设备及无可播放设备中查找
|
||
@return 成功返回设备设备节点,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_find_active(u8 valid)
|
||
{
|
||
struct __dev *dev = NULL;
|
||
struct __dev *active = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
if(!(dev->fmnt)){
|
||
continue;
|
||
}
|
||
if(valid){
|
||
if (dev->valid) {
|
||
if (active) {
|
||
if (active->active_stamp < dev->active_stamp) {
|
||
active = dev;
|
||
}
|
||
} else {
|
||
active = dev;
|
||
}
|
||
}
|
||
}else{
|
||
if (active) {
|
||
if (active->active_stamp < dev->active_stamp) {
|
||
active = dev;
|
||
}
|
||
} else {
|
||
active = dev;
|
||
}
|
||
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return active;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取指定设备节点
|
||
@param
|
||
logo:指定逻辑盘符,如:sd0/sd1/udisk0
|
||
valid:
|
||
1:有效可播放设备中查找,
|
||
0:所有设备,包括有可播放设备及无可播放设备中查找
|
||
@return 成功返回设备设备节点,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_find_spec(char *logo, u8 valid)
|
||
{
|
||
if (logo == NULL) {
|
||
return NULL;
|
||
}
|
||
struct __dev *dev = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
if(!(dev->fmnt)){
|
||
continue;
|
||
}
|
||
if (!strcmp(dev->parm->logo, logo)) {
|
||
if(valid){
|
||
if (dev->valid) {
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
}else{
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取指定序号设备节点
|
||
@param
|
||
index:指定序号,指的是在设备链表中的顺序
|
||
valid:
|
||
1:有效可播放设备中查找,
|
||
0:所有设备,包括有可播放设备及无可播放设备中查找
|
||
@return 成功返回设备设备节点,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_find_by_index(u32 index, u8 valid)
|
||
{
|
||
struct __dev *dev = NULL;
|
||
u32 i = 0;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
if(!(dev->fmnt)){
|
||
continue;
|
||
}
|
||
if(valid){
|
||
if (dev->valid) {
|
||
if (i == index) {
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
i++;
|
||
}
|
||
}else{
|
||
if (i == index) {
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
i++;
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备扫盘释放
|
||
@param
|
||
fsn:扫描句柄
|
||
@return 无
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void dev_manager_scan_disk_release(struct vfscan *fsn)
|
||
{
|
||
if (fsn) {
|
||
fscan_release(fsn);
|
||
}
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备扫盘
|
||
@param
|
||
dev:设备节点
|
||
path:指定扫描目录
|
||
parm:扫描参数,包括文件后缀等
|
||
cycle_mode:播放循环模式
|
||
callback:扫描打断回调
|
||
@return 成功返回扫描控制句柄,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct vfscan *dev_manager_scan_disk(struct __dev *dev, const char *path, const char *parm, u8 cycle_mode, struct __scan_callback *callback)
|
||
{
|
||
if (dev_manager_check(dev) == NULL) {
|
||
return NULL;
|
||
}
|
||
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
|
||
|
||
#if (TCFG_DM_MULTIPLEX_WITH_SD_PORT == 0) //0:sd0 1:sd1 //dm 参与复用的sd配置
|
||
if(!memcmp(dev->parm->logo ,"sd0",strlen("sd0"))){
|
||
#else
|
||
if(!memcmp(dev->parm->logo ,"sd1",strlen("sd1"))){
|
||
#endif
|
||
dev_usb_change_sd();
|
||
}
|
||
|
||
if(!memcmp(dev->parm->logo ,"udisk",strlen("udisk")))
|
||
dev_sd_change_usb();
|
||
|
||
if (dev_manager_online_check(dev, 1) == NULL) {
|
||
printf("mult remount fail !!!\n");
|
||
return NULL;
|
||
}
|
||
#endif
|
||
char *fsn_path = NULL;
|
||
char *tmp_path = NULL;
|
||
if (path) {
|
||
if (*path == '/') {
|
||
path++;
|
||
}
|
||
tmp_path = zalloc(strlen(dev->parm->root_path) + strlen(path) + 1);
|
||
if (tmp_path == NULL) {
|
||
return NULL;
|
||
}
|
||
sprintf(tmp_path, "%s%s", dev->parm->root_path, path);
|
||
fsn_path = tmp_path;
|
||
} else {
|
||
fsn_path = dev->parm->root_path;
|
||
}
|
||
printf("fsn_path = %s, scan parm = %s\n", fsn_path, parm);
|
||
struct vfscan *fsn;
|
||
/* clock_add_set(SCAN_DISK_CLK); */
|
||
if(callback && callback->enter){
|
||
callback->enter(dev);//扫描前处理, 可以在注册的回调里提高系统时钟等处理
|
||
}
|
||
fsn = fscan_interrupt(
|
||
(const char *)fsn_path,
|
||
parm,
|
||
DEV_MANAGER_SCAN_DISK_MAX_DEEPTH,
|
||
((callback) ? callback->scan_break : NULL));
|
||
/* clock_remove_set(SCAN_DISK_CLK); */
|
||
if(callback && callback->exit){
|
||
callback->exit(dev);//扫描后处理, 可以在注册的回调里还原到enter前的状态
|
||
}
|
||
if (fsn) {
|
||
if (fsn->file_number == 0) {
|
||
printf("dev nofile\n");
|
||
#if (TCFG_DEV_UPDATE_IF_NOFILE_ENABLE)
|
||
///没有文件找升级文件
|
||
dev_update_check(dev->parm->logo);
|
||
#endif/*TCFG_DEV_UPDATE_IF_NOFILE_ENABLE*/
|
||
///没有文件,释放fsn, 减少外面流程的处理
|
||
dev_manager_scan_disk_release(fsn);
|
||
fsn = NULL;
|
||
} else {
|
||
fsn->cycle_mode = cycle_mode;
|
||
}
|
||
}
|
||
|
||
if (tmp_path) {
|
||
free(tmp_path);
|
||
}
|
||
return fsn;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过设备节点标记指定设备是否有效
|
||
@param
|
||
dev:设备节点
|
||
flag:
|
||
1:设备有效,
|
||
0:设备无效
|
||
@return
|
||
@note 这里有无效是指是否有可播放文件
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void dev_manager_set_valid(struct __dev *dev, u8 flag)
|
||
{
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
if (dev_manager_check(dev)) {
|
||
dev->valid = flag;
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过逻辑盘符标记指定设备是否有效
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
flag:
|
||
1:设备有效,
|
||
0:设备无效
|
||
@return
|
||
@note 这里有无效是指是否有可播放文件
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void dev_manager_set_valid_by_logo(char *logo, u8 flag)
|
||
{
|
||
if (logo == NULL) {
|
||
return ;
|
||
}
|
||
struct __dev *dev = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
dev = dev_manager_check_by_logo(logo);
|
||
if (dev) {
|
||
dev->valid = flag;
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 激活指定设备节点的设备
|
||
@param
|
||
dev:设备节点
|
||
@return
|
||
@note 该接口可以将设备变为最新活动设备
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void dev_manager_set_active(struct __dev *dev)
|
||
{
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
if (dev_manager_check(dev)) {
|
||
dev->active_stamp = __dev_manager_get_time_stamp();//timer_get_ms();
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 激活指定逻辑盘符的设备
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return
|
||
@note 该接口可以将设备变为最新活动设备
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void dev_manager_set_active_by_logo(char *logo)
|
||
{
|
||
if (logo == NULL) {
|
||
return ;
|
||
}
|
||
struct __dev *dev = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
dev = dev_manager_check_by_logo(logo);
|
||
if (dev) {
|
||
dev->active_stamp = __dev_manager_get_time_stamp();//timer_get_ms();
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取设备节点的逻辑盘符
|
||
@param
|
||
dev:设备节点
|
||
@return 成功返回逻辑盘符,如:sd0/sd1/udisk0,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
char *dev_manager_get_logo(struct __dev *dev)
|
||
{
|
||
char *logo = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
if (dev_manager_check(dev) == NULL) {
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
logo = dev->parm->logo;
|
||
os_mutex_post(&__this->mutex);
|
||
return logo;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取物理设备节点的逻辑盘符(去掉_rec后缀)
|
||
@param
|
||
dev:设备节点
|
||
@return 成功返回逻辑盘符,如:sd0/sd1/udisk0,失败返回NULL
|
||
@note 物理逻辑盘符是指非录音文件夹设备盘符(录音文件夹设备如:sd0_rec)
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
char *dev_manager_get_phy_logo(struct __dev *dev)
|
||
{
|
||
char *logo = dev_manager_get_logo(dev);
|
||
char phy_dev_logo[16] = {0};
|
||
if (logo) {
|
||
char *str = strstr(logo, "_rec");
|
||
if (str) {
|
||
strncpy(phy_dev_logo, logo, strlen(logo) - strlen(str));
|
||
struct __dev *phy_dev = dev_manager_find_spec(phy_dev_logo, 0);
|
||
return dev_manager_get_logo(phy_dev);
|
||
}
|
||
}
|
||
return logo;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 获取录音文件夹设备节点的逻辑盘符(追加_rec后缀)
|
||
@param
|
||
dev:设备节点
|
||
@return 成功返回逻辑盘符,如:sd0_rec/sd1_rec/udisk0_rec,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
char *dev_manager_get_rec_logo(struct __dev *dev)
|
||
{
|
||
char *logo = dev_manager_get_logo(dev);
|
||
char rec_dev_logo[16] = {0};
|
||
if (logo) {
|
||
char *str = strstr(logo, "_rec");
|
||
if (!str) {
|
||
sprintf(rec_dev_logo, "%s%s", logo, "_rec");
|
||
struct __dev *rec_dev = dev_manager_find_spec(rec_dev_logo, 0);
|
||
return dev_manager_get_logo(rec_dev);
|
||
}
|
||
}
|
||
return logo;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过设备节点获取设备文件系统根目录
|
||
@param
|
||
dev:设备节点
|
||
@return 成功返回根目录,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
char *dev_manager_get_root_path(struct __dev *dev)
|
||
{
|
||
char *path = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
if (dev_manager_check(dev) == NULL) {
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
path = dev->parm->root_path;
|
||
os_mutex_post(&__this->mutex);
|
||
return path;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过逻辑盘符获取设备文件系统根目录
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 成功返回根目录,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
char *dev_manager_get_root_path_by_logo(char *logo)
|
||
{
|
||
char *path = NULL;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
struct __dev *dev = dev_manager_check_by_logo(logo);
|
||
if (dev == NULL) {
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
path = dev->parm->root_path;
|
||
os_mutex_post(&__this->mutex);
|
||
return path;
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过设备节点获取设备mount信息
|
||
@param
|
||
dev:设备节点
|
||
@return 成功返回对应指针,失败返回NULL
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct imount *dev_manager_get_mount_hdl(struct __dev *dev)
|
||
{
|
||
if (dev == NULL) {
|
||
return NULL;
|
||
}else{
|
||
return dev->fmnt;
|
||
}
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过逻辑盘符判断设备是否在线
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
valid:
|
||
1:检查有效可播放设备
|
||
0:检查所有设备
|
||
@return 1:在线 0:不在线
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int dev_manager_online_check_by_logo(char *logo, u8 valid)
|
||
{
|
||
struct __dev *dev = dev_manager_find_spec(logo, valid);
|
||
return (dev ? 1 : 0);
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过设备节点判断设备是否在线
|
||
@param
|
||
dev:设备节点
|
||
valid:
|
||
1:检查有效可播放设备
|
||
0:检查所有设备
|
||
@return 1:在线 0:不在线
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int dev_manager_online_check(struct __dev *dev, u8 valid)
|
||
{
|
||
if (dev_manager_check(dev) == NULL) {
|
||
return 0;
|
||
}else{
|
||
if(valid){
|
||
return (dev->valid ? 1 : 0);
|
||
}else{
|
||
return 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 通过逻辑盘符判断设备是否在设备链表中
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 1:在设备链表中, 0:不在设备链表中
|
||
@note 该接口会检查所有在设备链表中的设备,忽略mount,valid等状态
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
struct __dev *dev_manager_list_check_by_logo(char *logo)
|
||
{
|
||
if (logo == NULL) {
|
||
return 0;
|
||
}
|
||
struct __dev *dev;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
if (!strcmp(dev->parm->logo, logo)) {
|
||
os_mutex_post(&__this->mutex);
|
||
return dev;
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
return NULL;
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 检查链表中没有挂载的设备并重新挂载
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 1:在设备链表中, 0:不在设备链表中
|
||
@note 该接口会检查所有在设备链表中的设备,忽略mount,valid等状态
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void dev_manager_list_check_mount(void)
|
||
{
|
||
struct __dev *dev;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
list_for_each_entry(dev, &__this->list, entry) {
|
||
|
||
if(dev->fmnt){
|
||
unmount(dev->parm->storage_path);
|
||
dev->fmnt = NULL;
|
||
}
|
||
|
||
if(dev->fmnt == NULL){
|
||
struct __dev_reg *p = dev->parm;
|
||
dev->fmnt = mount(p->name, p->storage_path, p->fs_type, 3, NULL);
|
||
dev->valid = (dev->fmnt ? 1 : 0);
|
||
}
|
||
}
|
||
os_mutex_post(&__this->mutex);
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备挂载
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 0:成功, -1:失败
|
||
@note 需要主动mount设备可以调用改接口
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
static int __dev_manager_mount(char *logo)
|
||
{
|
||
int ret = 0;
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
struct __dev *dev = dev_manager_list_check_by_logo(logo);
|
||
if (dev == NULL) {
|
||
os_mutex_post(&__this->mutex);
|
||
return -1;
|
||
}
|
||
if(dev->fmnt == NULL){
|
||
struct __dev_reg *p = dev->parm;
|
||
dev->fmnt = mount(p->name, p->storage_path, p->fs_type, 3, NULL);
|
||
dev->valid = (dev->fmnt ? 1 : 0);
|
||
}
|
||
ret = (dev->valid ? 0 : -1);
|
||
os_mutex_post(&__this->mutex);
|
||
return ret;
|
||
}
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备卸载
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 0:成功, -1:失败
|
||
@note 需要主动unmount设备可以调用改接口
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
static int __dev_manager_unmount(char *logo)
|
||
{
|
||
os_mutex_pend(&__this->mutex, 0);
|
||
struct __dev *dev = dev_manager_check_by_logo(logo);
|
||
if (dev == NULL) {
|
||
os_mutex_post(&__this->mutex);
|
||
return -1;
|
||
}
|
||
if(dev->fmnt){
|
||
unmount(dev->parm->storage_path);
|
||
dev->fmnt = NULL;
|
||
}
|
||
dev->valid = 0;
|
||
os_mutex_post(&__this->mutex);
|
||
return 0;
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备挂载
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 0:成功, -1:失败
|
||
@note 慎用
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int dev_manager_mount(char *logo)
|
||
{
|
||
int ret = __dev_manager_mount(logo);
|
||
if(ret == 0){
|
||
#if TCFG_RECORD_FOLDER_DEV_ENABLE
|
||
char rec_dev_logo[16] = {0};
|
||
sprintf(rec_dev_logo, "%s%s", logo, "_rec");
|
||
ret = __dev_manager_mount(rec_dev_logo);
|
||
if(ret){
|
||
__dev_manager_unmount(logo);
|
||
}
|
||
#endif
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备卸载
|
||
@param
|
||
logo:逻辑盘符,如:sd0/sd1/udisk0
|
||
@return 0:成功, -1:失败
|
||
@note 慎用
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int dev_manager_unmount(char *logo)
|
||
{
|
||
int err = 0;
|
||
#if TCFG_RECORD_FOLDER_DEV_ENABLE
|
||
char rec_dev_logo[16] = {0};
|
||
sprintf(rec_dev_logo, "%s%s", logo, "_rec");
|
||
__dev_manager_unmount(rec_dev_logo);
|
||
#endif
|
||
err = __dev_manager_unmount(logo);
|
||
return err;
|
||
}
|
||
|
||
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备检测线程处理
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
extern void hidden_file(u8 flag);
|
||
static void dev_manager_task(void *p)
|
||
{
|
||
int res = 0;
|
||
int msg[8] = {0};
|
||
///过滤隐藏 和 .开头名名的字文件
|
||
hidden_file(1);
|
||
///设备初始化,
|
||
devices_init();
|
||
|
||
#if SDFILE_STORAGE && TCFG_CODE_FLASH_ENABLE
|
||
dev_manager_add(SDFILE_DEV);
|
||
#endif
|
||
|
||
#if TCFG_NOR_REC
|
||
dev_manager_add("rec_nor");
|
||
#endif
|
||
|
||
#if TCFG_NOR_FAT
|
||
dev_manager_add("fat_nor");
|
||
#endif
|
||
|
||
#if TCFG_NOR_FS
|
||
dev_manager_add("res_nor");
|
||
#endif
|
||
|
||
#if TCFG_VIR_UDISK_ENABLE
|
||
dev_manager_add("vir_udisk0");
|
||
#endif
|
||
|
||
#if TCFG_VIRFAT_FLASH_ENABLE
|
||
dev_manager_add("virfat_flash");
|
||
dev_manager_set_valid_by_logo("virfat_flash", 0);///将设备设置为无效设备
|
||
#endif
|
||
|
||
#if FLASH_INSIDE_REC_ENABLE
|
||
set_rec_capacity(512*1024);//需要先设置容量,注意要小于Ini文件设置大小.
|
||
_sdfile_rec_init();
|
||
dev_manager_add("rec_sdfile");
|
||
#endif
|
||
|
||
os_sem_post(&__this->sem);
|
||
|
||
while (1) {
|
||
res = os_task_pend("taskq", msg, ARRAY_SIZE(msg));
|
||
switch (res) {
|
||
case OS_TASKQ:
|
||
switch (msg[0]) {
|
||
case Q_EVENT:
|
||
break;
|
||
case Q_MSG:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void dev_manager_var_init()
|
||
{
|
||
memset(__this, 0, sizeof(struct __dev_manager));
|
||
INIT_LIST_HEAD(&__this->list);
|
||
os_mutex_create(&__this->mutex);
|
||
}
|
||
|
||
#endif/*TCFG_DEV_MANAGER_ENABLE*/
|
||
//*----------------------------------------------------------------------------*/
|
||
/**@brief 设备管理器初始化
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void dev_manager_init(void)
|
||
{
|
||
#if (TCFG_DEV_MANAGER_ENABLE)
|
||
dev_manager_var_init();
|
||
|
||
os_sem_create(&__this->sem, 0);
|
||
|
||
int err = task_create(dev_manager_task, NULL, DEV_MANAGER_TASK_NAME);
|
||
if (err != OS_NO_ERR) {
|
||
ASSERT(0, "task_create fail!!! %x\n", err);
|
||
}
|
||
os_sem_pend(&__this->sem, 0);
|
||
#else
|
||
devices_init();
|
||
#endif
|
||
}
|
||
|