接电话的流程:
static int
atCmdAnswer( atCMD* Cmd )
{
if( dectLineAnswerReq( -1 ) )
{
return atCmdSuspend( Cmd, 0 );
}
return -1;
}
/**************************************************************dectLineAnswerReq
Line == -1 select line
return nombre des lignes actives
*/
接电话时, Line 为-1
int
dectLineAnswerReq( const int Line )
{
int lineId = Line;
int lineState;
if( lineId < 0 )
{ /* selectionner la ligne a repondre */
lineState = mdmLineState( 0 );
switch ( lineState )
{
case mdmINCOMING:
case mdmWAITING:
lineId = 0;
break;
default:
lineState = mdmLineState( 1 );
lineId = 1;
break;
}
}
else
{
lineState = mdmLineState( lineId );
}
目前的值 lineId 0,lineState 4
/* executer la commande */
if( laLinkActive() )
{ /* il faut fermer la session */
if( lineState == mdmINCOMING )
{ /* basculer vers voice call */
dectLineReq( lineId, dectREQ_SWITCH_CALL );
}
else
{ /* fermer la session la et activer l'appel entrant */
laReleaseReq( !0 );
dectLineReq( lineId, DECT_DIGITS_CALL_WAITING_ACCEPTATION );
}
}
else
{ /* JBQ: if the active call has been released while the other call was */
/* waiting, picking up the call should be answered as call waiting. */
/* There is no way to handle MI_CALL_REQ in PTCC_RUN state. If the */
/* first call id is free and the second is initiated, this means that */
/* the active call has been released while CW */
/* This configuration doesn't appear in other cases as free call ids */
/* are assigned from 0. */
if( !lineId && ( lineState == mdmINCOMING ) )
{
dectLineReq( lineId, dectREQ_EXT );
}
else
{
if( ! ( ( lineState == mdmWAITING )
|| ( lineState == mdmINCOMING )
)
)
{
return 0;
}
dectLineReq( lineId, DECT_DIGITS_CALL_WAITING_ACCEPTATION );
}
}
/* anticiper les etats des lignes */
dectLineNotify( lineId, AP03_LINE_STATE_CALL_ACTIVE );
if( lineState == mdmWAITING )
{
dectLineNotify( dectLineNEXT( lineId ), AP03_LINE_STATE_HOLD );
}
return dectLineCount();
}
dectLineReq( lineId, dectREQ_EXT );
static void
dectLineReqNext( void )
{
int lineId, Req, reqId;
int gatewayWait = GATEWAY_WAIT;
dectTimerStop( DECT_REQ_TIMER );
reqId = dectLINE.Out;
lineId = dectLINE.Req[reqId] >> 7;
Req = dectLINE.Req[reqId] & ( ( 1 << 7 ) - 1 );
switch ( Req )
{
case dectREQ_CALL: G_hl_Call[lineId].CallPartyNumberPresentInd = AP03_CLI_PRESENT_IND_ALLOWED;
dectDigitPut( dectLINE.NUMBER[lineId] );
/* update caller id (invalidated after ) */
strcpy( ( void* )G_hl_Call[lineId].CallPartyNumber
, dectLINE.NUMBER[lineId]
);
strcpy( ( void* )G_hl_Call[lineId].CallPartyName
, dectLINE.NAME[lineId]
);
/* no break */
case dectREQ_DIAL: dect_send_digit( NULL, lineId );
break;
case dectREQ_EXT: if( laReleaseReq( 0 ) )
{
lineTRACE(( "%04X\tREQ(%d) Release %s\n"
, aClock()
, lineId
, "EXT"
));
return;
}
dect_initiate_call();
if( mmiLineState( lineId ) != mdmINCOMING )
{
mmiLineSET( lineId, mdmDIALING );
}
else
{
#ifdef AT_CMD /* force PSTN codec */
if( dect_is_line_PSTN_type( lineId ) )
{
mmiNotify( DECT_EVENT_AUDIO_COM_STARTED, HL00_CODEC_G726 );
}
#endif
gatewayWait = MsToClocks( 150 );
}
break;
case dectREQ_INT: if( laReleaseReq( 0 ) )
{
lineTRACE(( "%04X\tREQ(%d) Release %s\n"
, aClock()
, lineId
, "INT"
));
return;
}
mmiLineSET( lineId, mdmDIALING );
dect_initiate_internal_call();
break;
case dectREQ_RELEASE: dect_release_call();
break;
case dectREQ_NOTIFY: mmiNotify( msgAT_RESUME, 0 );
break;
case dectREQ_WAIT: break;
case dectREQ_SWITCH_CALL: dect_switch_to_call( HL00_NORMAL_CALL );
dectTimerStart( DECT_REQ_TIMER, gatewayWait );
laReleaseReq( !0 );
Req = DECT_DIGITS_CALL_WAITING_ACCEPTATION;
/* no break */
default: dect_send_digit( G_dect_digits[Req]
, lineId | ( Req << 8 )
);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'P':
case 'R':
case '*':
case '#':
dect_send_digit( &Req, lineId );
break;
}
dectTimerStart( DECT_REQ_TIMER, gatewayWait );
lineTRACE(( "%04X\tREQ(%d)<-0x%02X\n", aClock(), lineId, Req ));
dectLINE.Out = ( reqId + 1 ) & ( SizeOfArray( dectLINE.Req ) - 1 );
}
打电话流程:
dectLineReq( lineId, dectREQ_INT );
dectLineReq( lineId, dectREQ_EXT );
dectLineReq( lineId, dectREQ_CALL );
dectLineReq( lineId, dectREQ_DIAL );
1) ATD的处理
/*---------------------------------------------------------------------atCmdDial
*/
static int
atCmdDial( atCMD* Cmd )
{
int Length = 0;
if( Cmd->Length )
{
char DIGIT[HL00_KEYPAD_SIZE] = { 0 };
int lineId = mmiLineActive(); /* 获取活动的active line, 如果没有active 的则返回0,否则 ×/
int lineState;
if( lineId < 0 ) lineId = 0;
/* save phone number */
for( ; Cmd->String[Length]; Length++ )
{
DIGIT[Length] = Cmd->String[Length];
if( ( DIGIT[Length] == ';' )
|| ( DIGIT[Length] == '\r' )
)
{
break;
}
}
DIGIT[Length] = 0;
lineState = mmiLineState( lineId );
/× 如果lineState 为mdmIDLE 或者 linestae 为mdmDIALING 并且nexe line 为hold则可以 拨号 ×/
if( ( mdmIDLE == lineState )
|| ( ( mdmDIALING == lineState)
&& ( mdmHOLD == mmiLineState( dectLineNEXT( lineId ) ) )
)
)
{ /* internal android -> dect */
if( ( Length == 3 )
&& ( DIGIT[0] == '0' )
&& ( DIGIT[1] == '0' )
&& ( ( ( DIGIT[2] >= '1' ) && ( DIGIT[2] <= '7' ) )
|| ( DIGIT[2] == '*' )
)
)
{ /* internal call */
DIGIT[0] = DIGIT[2];
DIGIT[1] = 0;
}
dectLineCallReq( lineId, 0, DIGIT, "" );
return atCmdSuspend( Cmd, Length );
}
dectDigitPut( DIGIT );
dectLineReq( lineId, dectREQ_DIAL );
return atCmdSuspend( Cmd, Length );
}
return atCmdDiscard( Cmd, Length );
}
int
dectLineCallReq( const int Line
, const int callType
, const void* Number
, const void* Name
)
{
int lineId = Line;
int Type = callType;
int Second = 0;
if( lineId < 0 )
{
switch ( G_hl_Call[0].u8_LineState )
{
case AP03_LINE_STATE_IDLE:
case AP03_LINE_STATE_OVERLAP_SENDING: lineId = 0; break;
case AP03_LINE_STATE_HOLD: lineId = 1; break;
}
}
/* substituer le type d'appel pour les numeros internes */
if( dectNumberInternal( Number ) )
{
Type = fieldNumberINTERNAL;
}
if( mdmLineState( lineId ) == mdmIDLE )
{ /* start connection */
if( Type & fieldNumberINTERNAL )
{
dectLineReq( lineId, dectREQ_INT );
}
else
{
dectLineReq( lineId, dectREQ_EXT );
}
#ifndef AT_CMD
dectLineNotify( lineId, AP03_LINE_STATE_OVERLAP_SENDING );
#endif
Second = 0;
/* bloquer les requets pour garantir etablisement de communication */
dectLineReq( lineId, dectREQ_WAIT );
}
else
{
/* eviter "Invalid Session Number" -> fermer la session */
laReleaseReq( 0 );
if( ( mdmLineState( lineId ) == mdmDIALING )
&& ( mdmLineState( dectLineNEXT( lineId ) ) == mdmHOLD )
)
{
if( !( Type & fieldNumberINTERNAL ) )
{ /* switch to external call */
dectLineReq( lineId, DECT_DIGITS_RELEASE_INDICATED_CALL );
/* ??? required by vipdect fxo ??? */
dectLineReq( dectLineNEXT( lineId ), DECT_DIGITS_RESUMING_CALL );
dectLineReq( dectLineNEXT( lineId ), DECT_DIGITS_SECOND_EXTERNAL_CALL );
}
}
Second = !0;
}
/* save dial request */
if( Number )
{
strcpy( ( void* )G_hl_Call[lineId].CallPartyNumber, Number );
if( *G_hl_Call[lineId].CallPartyNumber )
{
dectReqNumber( lineId, G_hl_Call[lineId].CallPartyNumber, NULL );
dectLineReq( lineId, dectREQ_CALL );
}
}
/* save name */
if( Name )
{
strcpy( ( void* )G_hl_Call[lineId].CallPartyName, Name );
if( *G_hl_Call[lineId].CallPartyName )
G_hl_Call[lineId].CallPartyNamePresentInd = AP03_CLI_PRESENT_IND_ALLOWED;
dectReqNumber( lineId, NULL, G_hl_Call[lineId].CallPartyName );
}
return Second;
}