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不通了,这个问题害死我了

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值