C语言中表驱动编程(动态加载)

2 篇文章 0 订阅
2 篇文章 0 订阅
C 语言表驱动动态加载应用实例
目前手机终端功能越来越强大,客户需求也是各种各样,而且对于同一话机可能在不同的时间地点,要求的话机功能也不一样,如何能够通过一种远程的方式
调制话机功能,也成为各厂商的一个难题,介于此,产生了一种通过 命令+数据 修改终端参数的一种方式出现了。如何设置,设计公司机密,此处不便透露,
本文的重点在于描述,实现这个功能的一个重点技术应用,C 中的表驱动应用及链表应用。
废话少说,先做准备工作。
要处理的数据为  命令+ 数据 那么定义函数如下:
typedef  NMCMD_RETURN (* COMMAND_FUNCTION)(C_UINT16 cmd_id, const C_CHAR * p_cmd_data, C_UINT8 data_len);
其中  cmd_id 为命令 p_cmd_data 为数据 data_len 为数据长度。
定义结构体 用来扩展不同功能模块的处理,可根据应用来增加功能模块 如:加密卡处理,锁机锁卡处理,安防处理,计费处理等。
/*-----------------------------------------------------------------------------
*     文件_数据类型定义
*-----------------------------------------------------------------------------*/
typedef struct stnmcmd
{
    struct stnmcmd *pNext;    /* 链表 */
    COMMAND_FUNCTION fProc;    /* 指向下一个 */
}XNNM_CMDPROC;

定义全局 变量  指向链表头
static XNNM_CMDPROC *m_nmcmdproc = C_PNULL;


定义不同命令对应的处理函数
//命令与命令处理函数映射结构
typedef struct
{
    C_UINT16 cmd_id;    //命令
    COMMAND_FUNCTION cmd_fun;    //命令处理函数
}NMCMD_FUNCTION;


下面是基本框架函数实现 往链表中添加模块命令处理函数
/*---------------------------------------------------------------------------
*    函数名称:    xnnm_loadproc        
*    功能描述:     加载处理器
*
*    输入参数:     COMMAND_FUNCTION fProc    // 处理器
*    输出参数:     无
*    返 回 值:      
*
*    历史纪录:
*    修改人        日期             日志
*               2010-7-9       
*---------------------------------------------------------------------------*/
C_UINT16 xnnm_LoadProc( COMMAND_FUNCTION fProc )
{
    XNNM_CMDPROC *pNew = C_PNULL;
    
    if( fProc == C_PNULL )
    {
        return C_FALSE;
    }
    
    pNew = NM_MALLOC( sizeof(*pNew) );
    if( pNew == C_PNULL )
    {
        return C_FALSE;
    }
    memset( pNew, 0x00, sizeof(*pNew) );
    pNew->fProc = fProc;
    pNew->pNext = m_nmcmdproc;
    m_nmcmdproc = pNew;
    
    return C_TRUE;
}

将命令及数据传入进行处理
/*---------------------------------------------------------------------------
*    函数名称:    xnnm_ExecProc    
*    功能描述:     执行处理器
*
*    输入参数:     
*    输出参数:     
*    返 回 值:      
*
*    历史纪录:
*    修改人        日期             日志
*               2010-7-9       
*---------------------------------------------------------------------------*/
C_UINT16 xnnm_ExecProc( C_UINT16 cmd_id, const C_CHAR * p_cmd_data, C_UINT8 data_len )
{
    XNNM_CMDPROC *pList = m_nmcmdproc;
    
    while( pList )
    {
        if( pList->fProc( cmd_id, p_cmd_data, data_len ) == RET_NMCMD_SUCCESS )
        {
            break;
        }
        pList = pList->pNext;
    }
    
    return C_TRUE;
}


下面以锁机锁卡部分功能来实现锁机锁卡模块命令处理函数应用,加深对此框架的理解。

锁pin码命令处理函数
static NMCMD_RETURN nmcmd_lock_pin(C_UINT16 cmd_id, const C_CHAR * p_cmd_data, C_UINT8 data_len)
{
    if ((data_len < 1) || (data_len > 2) || (XINO_IsNumStr(p_cmd_data, data_len) == C_FALSE))
    {
            return RET_NMCMD_INVALID_DATA;
    }
      // 根据数据内容做相应的处理 begin
    if(XINO_STR2INT((const C_CHAR *)p_cmd_data, data_len) == 0)
    {
        locknv_enable_pin( 0 );
    }
    else
    {
        locknv_enable_pin( 1 );
    }
     // 根据数据内容做相应的处理 end
    return RET_NMCMD_SUCCESS;
}    

/*-----------------------------------------------------------------------------*/

//锁机锁卡功能模块 命令 与命令处理函数对应表

static const NMCMD_FUNCTION m_acstcmd[] =
{
    {ID_NMCMD_LOCK_PIN,            nmcmd_lock_pin            }, //修改开机自动锁Pin码
    {ID_NMCMD_ENABLE_RAND_PIN,          nmcmd_enable_rand_pin           }, //修改是否启用随机PIN码
    {ID_NMCMD_SET_FIXED_PIN ,           nmcmd_fix_pin            }, /* 设置固定PIN码 */
    {ID_NMCMD_INIT_PIN,            nmcmd_init_pin            }, //修改初始PIN码
    
    {ID_NMCMD_LOCK_IMSI,        nmcmd_lock_imsi            },  //修改开机自动绑定IMSI号
    
    {ID_NMCMD_CELL_LOCKED,        nmcmd_cell_locked        },  //修改是否锁定CELL
    {ID_NMCMD_CELL_AUTOINC,        nmcmd_cell_autoinc        },  //修改CELL是否自动增长
    {ID_NMCMD_CELL_LOCK_MAX,        nmcmd_cell_lock_max        },  //修改CELL最大锁定个数    
    {ID_NMCMD_CLEAN_CELL_LIST,        nmcmd_clean_cell_list        },  //清除CELL锁定列表
    {ID_NMCMD_CELL_LIST_TYPE,        nmcmd_cell_list_type        },  //锁定CELL类型- 黑白名单
    {ID_NMCMD_LOCK_CELL_APPEND,        nmcmd_lock_cell_append        },  //添加锁定的CELL
    
    {ID_NMCMD_LAC_LOCKED,        nmcmd_lac_locked        },  //修改是否锁定lAC
    {ID_NMCMD_LAC_LIST_TYPE,        nmcmd_lac_list_type        },  //锁定lac类型- 黑白名单    
    {ID_NMCMD_LAC_AUTOINC,        nmcmd_lac_autoinc        },  //修改lac是否自动增长
    {ID_NMCMD_LAC_LOCK_MAX,        nmcmd_lac_lock_max        },  //修改lac最大锁定个数
    {ID_NMCMD_CLEAN_LAC_LIST,        nmcmd_clean_lac_list        },  //清除lac锁定列表
    {ID_NMCMD_LOCK_LAC_APPEND,        nmcmd_lock_lac_append        },  //添加锁定的lac
    
    /* 锁运营商 */
    {ID_NMCMD_LOCK_SP_CLEAN,        nmcmd_lock_sp_clean        },  //锁定运营商表-清除
    {ID_NMCMD_LOCK_SP_APPEND_MODIFY,    nmcmd_lock_sp_append_modify    },  //锁定运营商表-添加/修改
    //{ID_NMCMD_LOCK_SP_DELETE,        nmcmd_lock_sp_delete            },    //锁定运营商表-删除
    
    {C_PNULL, C_PNULL },
};

其中 ID_NMCMD_LOCK_PIN   ID_NMCMD_CLEAN_LAC_LIST  等 为定义的命令
nmcmd_lock_pin  nmcmd_enable_rand_pin  等为 命令对应的处理函数。

/*-----------------------------------------------------------------------------
*    全局_函数实现
*-----------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------
*    函数名称:    locknm_handlercmd    
*    功能描述:     处理器   处理锁机锁卡根据命令查找对应树立函数
*
*    输入参数:     
*    输出参数:     
*    返 回 值:      
*
*    历史纪录:
*    修改人        日期             日志
*               2010-7-9       
*---------------------------------------------------------------------------*/
NMCMD_RETURN locknm_handlercmd(C_UINT16 cmd_id, const char * p_cmd_data, C_UINT8 data_len)
{
    NMCMD_RETURN bRet = RET_NMCMD_FAIL;
    C_UINT16 nTableSize = sizeof( m_acstcmd ) /sizeof(m_acstcmd[0]);
    NMCMD_FUNCTION *pTable = m_acstcmd;
    C_UINT16 i = 0;
    XINO_TRACE_LOW("[xjp] locknm_handlercmd enter");
    for( i = 0; i < nTableSize; i++ )
    {
        if( ( pTable[i].cmd_id == cmd_id ) && ( pTable[i].cmd_fun != C_PNULL ) )
        {
            /* 处理成功 */
            pTable[i].cmd_fun( cmd_id, p_cmd_data, data_len );
            bRet = RET_NMCMD_SUCCESS;
            break;
        }
    }
    XINO_TRACE_LOW("[xjp] locknm_handlercmd leave");
    return bRet;
}

开机初始化时 调用lock_init_proc 加载锁机锁卡命令处理函数locknm_handlercmd 到链表中。
C_VOID lock_init_proc( C_VOID )
{
    /* 加载命令处理 */
    xnnm_LoadProc(locknm_handlercmd); /* 加载开机处理器 */

}

命令接收处调用  xnnm_ExecProc( C_UINT16 cmd_id, const C_CHAR * p_cmd_data, C_UINT8 data_len ) 进行处理。

如果有新增一个模块
需要完成的工作就是
1.新增 命令与函数对应关系表  本例为  static const NMCMD_FUNCTION m_acstcmd[] =
2.新增 根据命令查找处理函数  本例为  NMCMD_RETURN locknm_handlercmd(C_UINT16 cmd_id, const char * p_cmd_data, C_UINT8 data_len)
3. 新增相应命令处理函数,    本例为  static NMCMD_RETURN nmcmd_lock_pin(C_UINT16 cmd_id, const C_CHAR * p_cmd_data, C_UINT8 data_len)
4. 在终端初始化部分加载根据命令查找对应处理函数  本例为 C_VOID lock_init_proc( C_VOID )


至此 C语言的表驱动编程,动态加载 实例就完了,希望对朋友们有所帮助, 欢迎联系交流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值