检测到一个DTMF按键后调入该函数
processObservedEvent(RvMdmTerm *term, const RvMegacoObservedEvent *obsEvent)
//如果数图已经激活,并且上报事件是数图事件
if((rvMdmTermDigitMapGetActive(&term->state->activeDigitMap) == RV_TRUE) && isInDigitMapPkg(term, obsEvent))
//获取当前事件名
eventName = rvMegacoObservedEventGetName(obsEvent);
//获取按键值
newDigit=rvMdmDigitMapDataTranslateEvent(term->state->digitMapData,rvMegacoPackageItemGetItem(eventName), rvMegacoObservedEventGetParameterListNc(obsEvent));
//没有找到对应的按键值返回错误
if(newDigit == RV_MDM_NOTADIGITMAPEVENT)
return RV_FALSE;
rvMdmTermDigitMapProcessNewDigit(&term->state->activeDigitMap,obsEvent,newDigit);
streamId = rvMegacoObservedEventGetStreamId(obsEvent);
//如果是第一个按键
if(digitMap->gotFirstDigit == RV_FALSE)
digitMap->gotFirstDigit = RV_TRUE;
//停等待播号音
if(!rvMegacoRequestedEventGetKeepActiveFlag(digitMap->requestedEvent))
digitMap->stopSignalsCB(digitMap, digitMap->userData);
digitMap->streamId = streamId;
else
if(streamId != digitMap->streamId)
digitMap->streamId = RV_MEGACOSTREAMID_NONE;
// 将当前按键加入digitMap->dialString尾部
rvMdmTermDigitMapAddToDialString(digitMap, newDigit);
result = rvMdmTermDigitMapProcessEventDd(digitMap);
rvMdmTermDigitMapTimerStop(digitMap); //停止等待定时器
//保存一下老的结果,用以后面匹配失败后回卷
lastStatus = digitMap->matchResult;
digitMap->matchResult = rvMegacoDigitMapMatch(&digitMap->digitMap, rvMdmTermDigitMapGetDialString(digitMap), &waitForDigits, &timerDuration);
//遍历所有数图规则
for(i=0; i<rvMegacoDigitMapGetSize(digitMap); ++i)
// rvMegacoDigitStringMatch主函数放在后面分解
switch(rvMegacoDigitStringMatch(rvMegacoDigitMapGetElem(digitMap, i), dialString, &timerRequested, enhanced))
//匹配当前规则
case RV_MEGACODIGITSTRING_MATCHED:
numMatched++;break;
//匹配当前规则同时需要等待
case RV_MEGACODIGITSTRING_MATCHEDANDWAITING:
matchWaiting = RV_TRUE;break;
//不完全匹配
case RV_MEGACODIGITSTRING_MATCHPOSSIBLE:
matchPossible = RV_TRUE;break;
//如果请求定时器不等于不改变,同时正在使用定时器不等于长定时器则改变正在使用定时器为请求定时器
if((timerRequested != RV_MEGACODIGITPOSITION_NOCHANGE) && (timerToUse != RV_MEGACODIGITPOSITION_LONGTIMER))
timerToUse = timerRequested;
//如果所有规则对比后,没有任何匹配,同时没有匹配等待,则查看是否有部分匹配,如果连部分匹配都没有则直接返回没有匹配,否则设置等待定时器来等待下一个用户按键
if((numMatched == 0) && (matchWaiting == RV_FALSE))
if(matchPossible == RV_TRUE)
if(timerToUse == RV_MEGACODIGITPOSITION_SHORTTIMER)
*timerDuration=rvMegacoDigitMapGetShortTimeout(digitMap);
Else
*timerDuration = rvMegacoDigitMapGetLongTimeout(digitMap);
*waitForDigits = RV_TRUE;
return RV_MEGACODIGITMAP_PARTIALMATCH;
return RV_MEGACODIGITMAP_NOMATCH;
//如果仅有一个匹配结果,则返回明确完全匹配
if((numMatched == 1) && (matchWaiting == RV_FALSE) && (matchPossible == RV_FALSE))
return RV_MEGACODIGITMAP_UNAMBIGUOUSMATCH;
//否则返回完全匹配,并设置定时器
if(timerToUse == RV_MEGACODIGITPOSITION_LONGTIMER)
*timerDuration = rvMegacoDigitMapGetLongTimeout(digitMap);
Else
*timerDuration = rvMegacoDigitMapGetShortTimeout(digitMap);
*waitForDigits = RV_TRUE;
//如果开启增强模式,则有任意一个匹配关闭定时器,直接发送数图通知事件,这个缺点是永远匹配不到长的规则
if((enhanced == RV_TRUE) && (numMatched > 0))
*timerDuration = 0;
*waitForDigits = RV_FALSE;
return RV_MEGACODIGITMAP_FULLMATCH;
//如果需要等待再次按键则启动等待定时器
if(waitForDigits == RV_TRUE)
rvMdmTermDigitMapTimerStart(digitMap, timerDuration);
return RV_FALSE;
//处理完成,但是没有匹配
if(digitMap->matchResult == RV_MEGACODIGITMAP_NOMATCH)
//获得播号字符串
dialString = rvMdmTermDigitMapGetDialString(digitMap);
//去除最后一个按键码
rvMdmTermDigitMapUnAddFromDialString(digitMap);
//取上一次的匹配结果
digitMap->matchResult = lastStatus;
return RV_TRUE
//匹配完成,发送数图事件
if(result == RV_TRUE)
rvMdmTermDigitMapSendNotify(digitMap);
rvMegacoDigitStringMatch(const RvMegacoDigitString *digitMap, const char *dialString, RvMegacoDigitPositionTimerMode *timerToUse, RvBool enhanced)
curStrPos = dialString; //号码池
curMapPos = rvVectorBegin(&digitMap->elements);//数图规则开始
mapEnd = rvVectorEnd(&digitMap->elements); //数图规则结尾
//空数图规则直接返回匹配成功
if(rvVectorSize(&digitMap->elements) == 0)
return RV_MEGACODIGITSTRING_MATCHED;
//空号码池直接返回部分匹配
if((dialString == NULL) || (*dialString == '\0'))
return RV_MEGACODIGITSTRING_MATCHPOSSIBLE;
//如果规则中最后一个元素仅是一个定时器标识,则设置延时标记为TRUE,用于数图增强功能的延时定时器
if((!rvMegacoDigitPositionGetEvents(mapEnd-1))&&(rvMegacoDigitPositionGetTimerMode(mapEnd-1) != RV_MEGACODIGITPOSITION_NOCHANGE))
trailingEvent = RV_TRUE;
for(;;)
//如果规则没有到达结尾,则检测当前规则元素是否定时器指示符,如果有则设置最终超时定时器使用该值,检测当前规则元素是否无按键事件,如果无则跳过该元素,继续下一个元素
if(curMapPos != mapEnd)
if(rvMegacoDigitPositionGetTimerMode(curMapPos)!=RV_MEGACODIGITPOSITION_NOCHANGE)
*timerToUse = rvMegacoDigitPositionGetTimerMode(curMapPos);
if(!rvMegacoDigitPositionGetEvents(curMapPos))
curMapPos += 1;
continue;
//如果号码池到达未尾
if(*curStrPos == '\0')
//如果数图规则没有到达未尾,并且当前数图规则元素非多元素类型,则直接返回部分匹配,否则当前元素为多元素类型,则设置trailingDot标记为TRUE,用于非增强数图的延时定时器标记,同时规则元素后移一位
if(curMapPos != mapEnd)
if(rvMegacoDigitPositionIsMultiple(curMapPos) == RV_TRUE)
trailingDot = RV_TRUE;
curMapPos += 1;
continue;
return RV_MEGACODIGITSTRING_MATCHPOSSIBLE;
//如果未开启数图增强模式,则以号码池匹配完后,数图元素后面有多元素成员为延时定时器标记,如果开启数图增强模式,则以数图规则中最后元素为定时器指示符为延时定时器标记。如果满足这些需求,则返回匹配成功并且需要开启延时定时器
if(enhanced == RV_FALSE)
if(trailingDot == RV_TRUE)
return RV_MEGACODIGITSTRING_MATCHEDANDWAITING;
else
if(trailingEvent == RV_TRUE)
return RV_MEGACODIGITSTRING_MATCHEDANDWAITING;
//如果当前数图规则也到达未尾,则返回匹配成功
*timerToUse = RV_MEGACODIGITPOSITION_NOCHANGE;
return RV_MEGACODIGITSTRING_MATCHED;
//当前话机无法输入z,所以跳过
if((*curStrPos == 'Z') || (*curStrPos == 'z'))
curStrPos += 1;
continue;
//如果规则到达结尾则匹配失败
if(curMapPos == mapEnd)
break;
//如果当前号码池匹配当前规则元素,将号码池指针后移,查看当前规则元素为非(.)时规则元素也后移,如果规则元素为(.)时,则继续等待下一个号码池匹配该元素。
if(rvMegacoDigitPositionMatchEvent(curMapPos, *curStrPos))
curStrPos += 1;
if(rvMegacoDigitPositionIsMultiple(curMapPos) == RV_FALSE)
curMapPos += 1;
continue;
//如果上面号码池与当前规则元素没有匹配成功,则判断当前规则元素是否为(.),不是(.)则匹配失败,否则不是错误,因为(.)表示可以匹配0~N个前一个字符
if(rvMegacoDigitPositionIsMultiple(curMapPos) == RV_FALSE)
break;
//当规则元素为(.)匹配失败后,元素下移一位
curMapPos += 1;
//没有匹配成功
*timerToUse = RV_MEGACODIGITPOSITION_NOCHANGE;
return RV_MEGACODIGITSTRING_UNMATCHED;
友情提示:
数图中的三种定时器默认值是在收到数图请求事件,准备激活数图前从终端类对象中复值的,开始的定时器是在激活数图时启动的。
===============================================================================
数图匹配
最新推荐文章于 2022-07-04 15:01:20 发布