Access-ONU4024

ONU4024i硬件接口,2GE1EPON24LAN/VOIP,就是一個24口交換機+VOIP,可以GE上行,或者EPON上行,LAN口和VOIP共用接用戶

 

1.        VOIP硬件參數

MPC8247 64MSDRAM 4MFLASH,這樣的硬件設計成本太高,臨時加班出來的產品,簡單的由switch+VOIP板合併而成,switch部分是NMS可見的,VOIPswitch之間用內部IP來管理,中間有FE來連接,管理包和業務包都經過這裏

VOIP板原來是iFXS產品,爲單獨一個盒子,24PORTVOIP,不支持NMS,只可以命令行配置,配置文件保存在板子FLASH

4024 

MPC8247MII,必須配置幾個IP,一個192.168.1.*內部管理用,另外是VOIP協議用的兩個IP

協議棧收到包後,會判斷是到哪個IP的,這樣互相不衝突

 

        if(edp == &fcc1Device)

        {

            if(source_ip == (u_long)(ip_config.primary_ip))

            ....

        }

 

原來的VOIP單板是早期的,VCP是沒有的,採用一個51來採集摘掛機和鈴聲控制,在VOIP一側需要做的工作有:去掉51代碼,移植vcp代碼;增加loop_test測試模塊;增加VOIPMIB管理模塊

 

2.        VCP代替51模塊

VCP51是最底層的任務了,它們上一層的任務是HIP,也只有HIP任務和它們通信,所以需要刪除51的任務,添加VCP的任務

VCP(或者51)檢測摘機,發包到HIP

-->HIP收到包,發包到VOIP協議棧

-->協議棧收到包,處理

下面代碼就是VCP的所有消息送到HIP去的,封裝數據格式一定要和hipAPI一樣,有些繁瑣

 

bool VcpSendFixMessageToHip(int8 lineNum, uint8 byte1, uint8 byte2){

    uint8 msgLen=2, i;

    //qbuf_t            *qbuf;

    OS_STATUS        rc;

    uint8 rx_buf[4];//slot,len,byte1,byte2

 

    vcp_debug_printf_notice("VCP module sending out message to 51 ctrl with message 0x%x 0x%x ",byte1,byte2);

 

    /*Convert content to sbus format, and send it to M8051_MSG_Q */

    rx_buf[0] = get_hip_id(0, 2);     /* Add old slot id for HIP */

    rx_buf[1] = 2;/*length of content*/

    rx_buf[2] = byte1;

    rx_buf[3] = byte2;

        rc = forward_msg(&rx_buf[0], rx_buf[1] + 2, POLL_TO_HIP_RX_DATA);

    return rc;

}

 

協議棧有陣鈴消息,送包到HIP

-->HIP收到包,發包到VCP

-->VCP收到包

UserBdTxProcHIP發送包的接口,所以在這裏做操作封裝函數fill_tx_bufsend_to_vcp,還是繁瑣的調試,還好消息格式沒有改變

 

void

UserBdTxProc (qbuf_t * DownMsgQ)

{

......

 

       cadence_type = DownMsgQ->digit;

       if (DownMsgQ->option == 0)   /* normal ring_on */

       {

          // fill_tx_buf (6,0x00,0x03,0x04,port,cadence_type,board_i);

          send_to_vcp(6,0x00,0x03,0x04,port,cadence_type,board_i);

           if( ( is_fx_debug_on() == TRUE ) || (is_fx_port_trace_on(port) == TRUE ) )

           {

              printf("UserBdTxProc(): Sent FXS port %d RING-ON Pattern %d message!/n", port, cadence_type);

           }

       }

......

}

 

這些接口都可以用測試命令先測試線程間通信是否正常

 

3.        添加loop_test的任務

NMS操作,switch發包到VOIP

-->MIB任務收到,發測試命令到loop_test

-->loop_test收到測試命令,判斷一下轉發包到VCP

-->VCP收到開始測試,測試結果發到loop_test

-->loop_test收到測試結果,發給MIB任務

-->MIB收到,更新MIB表項

(這裏並沒有發給NMS,只是等待NMS來取的;因爲VOIP測每次做的操作都是跟新MIB表,管理這一塊都是NMS發消息到MIB任務,MIB任務去MIB表中取)

這個真的挺繁瑣的

 

4.        MIB任務以及N多的MIB添加

switch之間通信起socket用內部管理IP,同步操作,不管是SET還是GET配置項都是去更新MIB表,另外再掉底層API使配置生效;所以有N多的MIB表要去更新,這是收到NMS的消息後解析MIB命令,定義了一個枚舉來操作的,有SET項有GET

 

    ......

    /* Command dispatch */

    switch (pCmdReq->cmd)

    {

    case COMM_CMD_MG_IPADDR_CFG_GET:

        memcpy(&commMsgBuf, &(pCmdReq->buffer), 4);

        result = mml_utsMgIpAddressCfgEntry_get(commMsgBuf, &msgLen);

        break;

    case COMM_CMD_MG_IPADDR_CFG_SET:

        result = mml_utsMgIpAddressCfgEntry(pCmdReq->buffer);

        break;

    case COMM_CMD_MG_CALL_SERVER_CFG_GET:

        result = mml_utsMgCallServerCfgScalars_get(commMsgBuf, &msgLen);

        break;

    case COMM_CMD_MG_CALL_SERVER_CFG_SET:

        result = mml_utsMgCallServerCfgScalars(pCmdReq->buffer);

        break;

    ......      

下面是代碼接口,還有N多的MIB*.cc表項,那些表項是實現底層的程序接口,比如媒體IP,信令IP,涉及到系統和VOIP協議相關

 

/*

* Function:    by hyg 4024i 080410

* Purpose:     

* Arguments:

* Returns:

*/

int mml_utsMgIpAddressCfgEntry_get(char* buf, int* length)

{

    mtbl_sel_t sel;

    int error_flag = 1;

    udl_utsMgIpAddressCfgEntry_t* udl_utsMgIpAddressCfgEntry_t_p_tmp = (udl_utsMgIpAddressCfgEntry_t*)buf;

    unsigned utsMgIpAddressCfgIpIndex_s = 1;

     sel.set(0,0);

     *length = sizeof (udl_utsMgIpAddressCfgEntry_t);

   

     if ((error_flag = CMmlTbl::get_mtbl(UDL_UTSMGIPADDRESSCFGENTRY_T)->get_row(sel, &(udl_utsMgIpAddressCfgEntry_t_p_tmp->utsMgIpAddressCfgIpIndex), udl_utsMgIpAddressCfgEntry_t_p_tmp))

             == RV_OK)

     

     {  

         hprintf("mml_utsMgIpAddressCfgEntry_get ok/n");

        return RV_OK;

     }    

     else

     {

         hprintf("error:%d/n",error_flag);

         return error_flag;

     }

}

 

 

int mml_utsMgIpAddressCfgEntry(char* buf)

{

    mtbl_sel_t sel;

    int error_flag = 1;

    udl_utsMgIpAddressCfgEntry_t* udl_utsMgIpAddressCfgEntry_p = (udl_utsMgIpAddressCfgEntry_t*)(buf);

    int mask = *(int*)(buf+sizeof(udl_utsMgIpAddressCfgEntry_t));

     udl_utsMgIpAddressCfgEntry_t udl_utsMgIpAddressCfgEntry_p_tmp;

 

     sel.set(0,0);

    hprintf("mask-----:%x----/n",mask);

    if (CMmlTbl::get_mtbl(UDL_UTSMGIPADDRESSCFGENTRY_T)->get_row(sel, &(udl_utsMgIpAddressCfgEntry_p->utsMgIpAddressCfgIpIndex),&udl_utsMgIpAddressCfgEntry_p_tmp)

             == RV_OK)

     {

        memcpy(&udl_utsMgIpAddressCfgEntry_p_tmp, udl_utsMgIpAddressCfgEntry_p, sizeof(udl_utsMgIpAddressCfgEntry_t));

         if ((error_flag = CMmlTbl::get_mtbl(UDL_UTSMGIPADDRESSCFGENTRY_T)->set_row(sel,

             &(udl_utsMgIpAddressCfgEntry_p->utsMgIpAddressCfgIpIndex), &udl_utsMgIpAddressCfgEntry_p_tmp, mask)) == RV_OK)

        {

            hprintf("mml_utsMgIpAddressCfgEntry ok /n");

            return RV_OK;

        }

        else

        {

            hprintf("error:%d/n",error_flag);

            return error_flag;

         }   

     }   

     else

         return error_flag;

}

寫了N多這樣的代碼,N多的MIB表,時間緊急下的編碼質量也不高

 

5.        其它更新

還有一個問題就是MIB配置項的保存,之前iFXS是基於命令行配置,現在需要所有的MIB表項全部保存,實現方法是起一個大的struct,直接保存,系統啓動的時候直接讀這個大的struct,解析出來對照每一個MIB表項即可

 

6.        小結

移植vcp代碼,去掉了一些宏控制以及looptest沒有移植,導致很多地方編譯不通過,修改了很多,如果一按開始就按照原樣子以及looptest移植過來,很少需要改動的,教訓

ss_send_test定義char buf[]過大,而任務的分配內存太小,直接crash

task中起task,沒有刪除已經的clienttask,起了n多的task,不重啓纔怪

rtems_task_create中參數拷貝過來的,taskname沒對上,導致taskname不是definename

get_task_id_from_task_name這個函數太爛了,只可以找m4中定義的函數的,導致無法取到自己起的taskid   

update_signal_ip((inaddr_t)utsMgIpAddressCfgEntry_p_tmp.utsMgIpAddressCfgIpAddress, inaddr_t)utsMgIpAddressCfgEntry_p_tmp.utsMgIpAddressCfgNetmask);少了強制轉換定義,肯定報錯

extern "C" void update_signal_ip(inaddr_t signal_ip, inaddr_t signal_ip_mask);C++調用一定切記加這個

../../vpm/nmgt/oam/oaminit.cc:2186: passing `void (*)()' as argument 3 of `rtems

_timer_fire_after(unsigned int, unsigned int, rtems_timer_service_routine (*)(un

signed int, void *), void *)'這個意思是子函數的參數不匹配

memcpy(&(udl_utsVoiceBandTestinEntry_t_mask_p->utsVoiceBandTestinVBat), &RcvBuf[i+5], 2);

0x4400

udl_utsVoiceBandTestinEntry_t_mask_p->utsVoiceBandTestinVBat = *((short *)&RcvBuf[i+5]);

0x0044取值剛好相反

儘量定義數組,只要不太大,指針出了問題找起來太麻煩了

malloc後沒釋放,導致大呼後crash,小問題大麻煩

BSP提供的I2C驅動有問題,導致讀出的MAC出錯,這個時候代碼中會採用一個默認的MAC,這個時候多臺ONU4024i連接OLT的時候就會出錯了,導致內部IP不通了,這個問題害死我了

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章