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語言的表驅動編程,動態加載 實例就完了,希望對朋友們有所幫助, 歡迎聯系交流
摘自 dainiao01的專欄