Ejemplo n.º 1
0
/*************************************************************************
* FUNCTION                                                            
*	avrcpQueryCTCallback
* DESCRIPTION                                                           
*   The function is called by SDAP to indicate the profiles the search result
*   Modified by MTK Dlight mtk01239
*
* PARAMETERS
*	sqt  : SdpQueryToken contains information such as remote device information. uuid...
*	result  : The service search result.
*      serv_chn: It is not used in AVRCP profile
* RETURNS
*	None
* LOCAL AFFECTED
*   
*************************************************************************/
void avrcpQueryCTCallback(SdpQueryToken *sqt, U8 result, U8 attribute_index, U8 *attribute_value)
{
    SdpQueryToken *token;
    BtRemoteDevice *remDev;
    U16 feature = 0;
    BtStatus status = 0;
    
    AvrcpChannel *chnl = ContainingRecord(
                                                                    sqt, 
                                                                    AvrcpChannel, 
                                                                    sdpQueryToken
                                                                    );

    
    token  = sqt;
    if(chnl->cmgrHandler.bdc ==0)
    {
        /* 
            The remote side connects our AVRCP after we send avrcp connect req.
            We will reject the remote side avrcp connect req but will get a disconnect ind.
            The Avrcp connect req from our side will think the connect requestion is failed and 
            remove the cmgr and rem at the same time.
        */
        if (sqt->rm !=0)
            sqt->rm->discFlag = 1;
        return;
    }

    remDev = chnl->cmgrHandler.bdc->link;
    
    if( chnl ){
    	/// has do the search 
    	chnl->remoteCTSdp.ctValid = TRUE;
    }
    
	kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_CT_CALLBACK , result, attribute_index);
    switch (result) 
    {
        case BT_STATUS_SUCCESS:
        	{
        		/// remote has a TG record
        		chnl->remoteCTSdp.ctAvailable= TRUE;
        		
	        	switch( avrcp_sdp_attribute_id_list[attribute_index] ){
	        		case AID_PROTOCOL_DESC_LIST:
	        			{
	        				/// update the result
	        				chnl->remoteCTSdp.ctVersion = BEtoHost16(attribute_value);

	        			}
	        			break;
					case AID_SUPPORTED_FEATURES:
	        			{
	        				/// update the result
	        				chnl->remoteCTSdp.ctFeatureFlag = BEtoHost16(attribute_value);
                            OS_Report("[AVRCP] SDP attr_value[0]:0x%x attr_value[1]:0x%x attr_value[2]:0x%x attr_value[3]:0x%x", attribute_value[0], attribute_value[1], attribute_value[2], attribute_value[3]);

    						chnl->remoteCTSdp.ctSupportBrowse = chnl->remoteCTSdp.ctFeatureFlag && 0x40;
                            OS_Report("[AVRCP] SDP chnl->remoteCTSdp.ctFeatureFlag:%d", chnl->remoteCTSdp.ctFeatureFlag);
							/// search is finished. try to connect
							if( 2 == avrcp_sdp_attribute_num ){
                                if( chnl->connFlag == 1 ){
								if(chnl->conntimer.func!=0)
									EVM_CancelTimer(&chnl->conntimer);
								chnl->conntimer.func = AVRCP_Connect_Timeout;
								chnl->conntimer.context = remDev;
								EVM_StartTimer(&chnl->conntimer, 20);
                                
                                AVRCP_UtilAVRCPSDPQueryInd(chnl, 0, chnl->remoteTGSdp.tgVersion, chnl->remoteTGSdp.tgFeatureFlag, chnl->remoteCTSdp.ctVersion, chnl->remoteCTSdp.ctFeatureFlag);
							}

	        			}

	        			}
	        			break;

					case AID_BT_PROFILE_DESC_LIST: //case AID_ADDITIONAL_PROT_DESC_LISTS:
						{
   	        				chnl->remoteCTSdp.ctVersion = BEtoHost16(attribute_value);
   	        				status = parseAvrcpVersion(attribute_value, &feature);
							if( BT_STATUS_SUCCESS == status ){
							    chnl->remoteCTSdp.ctVersion = feature;
							}else{
							    OS_Report("[AVRCP] SDP error status:%d", status);    
							}
							kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_CT_INFO , chnl->remoteCTSdp.ctAvailable, chnl->remoteCTSdp.ctVersion, chnl->remoteCTSdp.ctFeatureFlag, chnl->remoteCTSdp.ctSupportBrowse);
                            OS_Report("[AVRCP] SDP ctVersion:%d", chnl->remoteCTSdp.ctVersion);

                            
                            if( chnl->connFlag == 1 ){
							if(chnl->conntimer.func!=0)
								EVM_CancelTimer(&chnl->conntimer);
							chnl->conntimer.func = AVRCP_Connect_Timeout;
							chnl->conntimer.context = remDev;
							EVM_StartTimer(&chnl->conntimer, 20);
						    }
                            
                            AVRCP_UtilAVRCPSDPQueryInd(chnl, 0, chnl->remoteTGSdp.tgVersion, chnl->remoteTGSdp.tgFeatureFlag, chnl->remoteCTSdp.ctVersion, chnl->remoteCTSdp.ctFeatureFlag);
						}
						break;
	        	}
	        }             
            break;
        case BT_STATUS_CONNECTION_FAILED:
        case BT_STATUS_FAILED:
        case BT_STATUS_NOSERVICES:
        	{
				kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_CT_INFO , chnl->remoteCTSdp.ctAvailable, chnl->remoteCTSdp.ctVersion, chnl->remoteCTSdp.ctFeatureFlag, chnl->remoteCTSdp.ctSupportBrowse);

	        	/// NO TG record available => search CT
	        	/// One of CT or TG is available => try to conne	ct
	        	if( FALSE == chnl->remoteCTSdp.ctAvailable && FALSE == chnl->remoteTGSdp.tgAvailable ){
	            	AvrcpReportFailedConnect(chnl);
	            }else{
	            	/// After a TG connect
		            if(chnl->conntimer.func!=0)
		                EVM_CancelTimer(&chnl->conntimer);
		            chnl->conntimer.func = AVRCP_Connect_Timeout;
		            chnl->conntimer.context = remDev;
		            EVM_StartTimer(&chnl->conntimer, 20);
	            }
                
                AVRCP_UtilAVRCPSDPQueryInd(chnl, 1, 0, 0, 0 , 0);
        	}
            break;
    }

}
Ejemplo n.º 2
0
/*---------------------------------------------------------------------------
 *            BipInitiatorCallback
 *---------------------------------------------------------------------------
 *
 * Synopsis:  This function processes Initiator events.
 *
 * Return:    void
 *
 */
void BipInitiatorCallback(GoepClientEvent *event)
{
    BipObexClient      *client;
    BipCallbackParms    parms;
    BipImgHandlePtr     ih;
    U8                 *p;

    parms.obex.client = FindBipInitiator(event->handler);
    if (parms.obex.client == 0) {
		kal_trace(BT_TRACE_G6_OBEX,BT_BIP_INITIATOR_NOT_FOUND);	
        return;
    }
    client = parms.obex.client;

    switch (event->event) {
    case GOEP_EVENT_TP_CONNECTED:
        /* The transport layer connection is up. Send an OBEX Connect. */
        //Report(("BIP: Client: Transport Layer connection established.\n"));
        GOEP_Connect(&client->cApp, &client->connect);
        break;

    case GOEP_EVENT_TP_DISCONNECTED:
        /* The transport layer connection has been disconnected. */
        //Report(("BIP: Client: The transport connection has been disconnected.\n"));
       
        if (client->state == BIPCHS_CONNECTING) {
            BipAppCallBack(&parms, event->reason, BIPINITIATOR_FAILED);
        }

        client->data = &client->tData;
        client->data->bipOp = BIPOP_CONNECT;
        BipAppCallBack(&parms, OB_STATUS_DISCONNECT, BIPINITIATOR_COMPLETE);

        client->tData.offset = client->tData.totLen = 0;
        if (client->pushPull.object) {
            BIPOBS_Close((BipObStoreHandle *)&client->pushPull.object);
        }
        break;
        
    case GOEP_EVENT_COMPLETE:
        /* The requested operation has completed. */
        switch (event->oper) {
        case GOEP_OPER_CONNECT:
            /* OBEX connection is established. */
            client->state = BIPCHS_CONNECTED;
            //Report(("BIP: Client: OBEX Connect Operation is complete.\n"));
            client->data->bipOp = BIPOP_CONNECT;
            BipAppCallBack(&parms, OB_STATUS_SUCCESS, BIPINITIATOR_COMPLETE);
            break;

        case GOEP_OPER_PUSH:
            Assert(client->pushPull.object);
            BIPOBS_Close((BipObStoreHandle *)&client->pushPull.object);
            /* OBEX put is complete. */
            client->state = BIPCHS_COMPLETED;
            //Report(("BIP: Client: OBEX Put Operation is complete.\n"));
            BipAppCallBack(&parms, OB_STATUS_SUCCESS, BIPINITIATOR_COMPLETE);
            client->state = BIPCHS_CONNECTED;
            break;

        case GOEP_OPER_PULL:
            BIPOBS_Close((BipObStoreHandle *)&client->pushPull.object);

            client->state = BIPCHS_COMPLETED;
            //Report(("BIP: Client: OBEX Pull Operation is complete.\n"));
            BipAppCallBack(&parms, OB_STATUS_SUCCESS, BIPINITIATOR_COMPLETE);
            client->state = BIPCHS_CONNECTED;
            break;

        case GOEP_OPER_DISCONNECT:
            /* OBEX Disconnect is complete, disconnect link. */
            //Report(("BIP: Client: OBEX Disconnect Operation is complete.\n"));
            client->state = BIPCHS_INITIALIZED;
            GOEP_TpDisconnect(&client->cApp);
            client->b_TpDisconnect_called = KAL_TRUE;
            break;

        case GOEP_OPER_ABORT:
            //Report(("BIP: Client: OBEX Abort Operation is complete.\n"));
            client->state = BIPCHS_ABORTED;
            BipAppCallBack(&parms, event->reason, BIPINITIATOR_ABORT);

            if (client->pushPull.object) {
                /* close any objects associated with the aborted operation */
                BIPOBS_Close((BipObStoreHandle *)&client->pushPull.object);
            }
            client->state = BIPCHS_CONNECTED;
            break;

        default:
            //Report(("BIP: Client: OBEX Operation %d is complete.\n", event->oper));
            break;
        }

        client->tData.offset = client->tData.totLen = 0;
        client->data = &client->tData;
        client->tData.bipOp = BIPOP_NOP;
        break;
        
    case GOEP_EVENT_ABORTED:
        /* Handle the Partial Content special case on PutImage */
        if (event->oper == GOEP_OPER_PUSH &&
            ((BipObStoreHandle)client->pushPull.object)->bipOp == BIPOP_PUT_IMAGE &&
            event->reason == OBRC_PARTIAL_CONTENT) {
            BIPOBS_Close((BipObStoreHandle *)&client->pushPull.object);
            client->state = BIPCHS_COMPLETED;
			kal_trace(BT_TRACE_G6_OBEX,BT_BIP_I_PARTIALCONTENT_PUTIMG);	
            BipAppCallBack(&parms, OBRC_PARTIAL_CONTENT, BIPINITIATOR_COMPLETE);
            client->state = BIPCHS_CONNECTED;
            break;
        }
        if (event->oper == GOEP_OPER_PULL && client->pushPull.object &&
            ((BipObStoreHandle)client->pushPull.object)->bipOp == BIPOP_GET_IMAGES_LIST &&
            event->reason == OBRC_PARTIAL_CONTENT) {
            BIPOBS_Close((BipObStoreHandle *)&client->pushPull.object);
            client->state = BIPCHS_COMPLETED;
			kal_trace(BT_TRACE_G6_OBEX,BT_BIP_I_PARTIALCONTENT_GETIMGLIST);	
            BipAppCallBack(&parms, OBRC_PARTIAL_CONTENT, BIPINITIATOR_COMPLETE);
            client->state = BIPCHS_CONNECTED;
            break;
        }
        if(event->oper == GOEP_OPER_CONNECT)
        {
            //Report(("BIP: Client: Received failed connect response, disconnect the transport layer.\n"));
            if (event->reason == OBRC_LINK_DISCONNECT)
            {
                /* in case of TP_DISCONNECT, OBEX will invoke ABORT firtly */
                client->state = BIPCHS_INITIALIZED;
                client->b_TpDisconnect_called = KAL_TRUE;
                break;
            }
            if (client->state == BIPCHS_AUTHENTICATING)
            {
                client->data = &client->tData;
                client->data->bipOp = BIPOP_CONNECT;
                BipAppCallBack(&parms, (U16)(event->failed_rsp_code & 0x7F), BIPINITIATOR_ABORT);
            }
            else
            {                
                client->state = BIPCHS_INITIALIZED;
                GOEP_TpDisconnect(&client->cApp);
            }            
            break;
        }
        /* The requested operation has failed. Alert the user and cleanup. */
        //Report(("BIP: Client: The Operation was aborted, %d.\n", event->reason));
        client->state = BIPCHS_ABORTED;
        //BipAppCallBack(&parms, event->reason, BIPINITIATOR_ABORT);
        BipAppCallBack(&parms, (U16)(event->failed_rsp_code & 0x7F), BIPINITIATOR_ABORT);

        if (client->pushPull.object) {
            /* close any objects associated with the aborted operation */
            BIPOBS_Close((BipObStoreHandle *)&client->pushPull.object);
        }

        client->state = BIPCHS_CONNECTED;
        break;
        
    case GOEP_EVENT_CONTINUE:
        BipAppCallBack(&parms, event->reason, BIPINITIATOR_CONTINUE);
        /* Allways continue on sender side */
/*      GOEP_ClientContinue(&client->cApp);   */
        break;

    case GOEP_EVENT_HEADER_RX:
        switch (event->header.type) {
        case OBEXH_LENGTH:
            if (event->oper == GOEP_OPER_PULL) {
                /* Set the object length for Pull operations only */
                BIPOBS_SetObjectLen((BipObStoreHandle)client->pushPull.object,
                                    event->info.pull.objectLen);
            }
            break;

        case BIPH_IMG_DESCRIPTION:
            if (event->header.len == 0 ||
                event->header.len == event->header.totalLen) {
                /* reset the offset */
                client->data->offset = 0;
            }
            if (event->header.len != 0) {
                /* tell the initiator we have data */
                client->data->totLen = event->header.totalLen;
                client->data->len = event->header.len;

                switch (client->data->bipOp) {
                case BIPOP_GET_IMAGES_LIST:
                    client->data->i.iHDsc.buff = event->header.buffer;
                    client->data->dataType = BIPIND_HANDLES_DESCRIPTOR;
                    break;

                case BIPOP_PUT_IMAGE:
                case BIPOP_GET_IMAGE:
                    client->data->i.iIDsc.buff = event->header.buffer;
                    client->data->dataType = BIPIND_IMAGE_DESCRIPTOR;
                    break;

                default:
                    break;
                }

                BipAppCallBack(&parms, 0, BIPINITIATOR_DATA_IND);

                /* Check if we have the entire description */
                if (client->data->totLen >
                    event->header.len + client->data->offset) {
                    client->data->offset += event->header.len;
                }
                else {
                    /* Set the offset back to null */
                    client->data->offset = client->data->totLen = 0;
                }
            }
            break;

        case BIPH_IMG_HANDLE:
            /* GOEP indicates the entire Unicode header */
            if (event->header.len != 0) {
                int i;
                switch (client->data->bipOp) {
                case BIPOP_PUT_IMAGE:
                case BIPOP_REMOTE_DISPLAY:
                case BIPOP_GET_MONITORING_IMAGE:
                    ih = client->data->i.iHndl.imgHandle;
                    client->data->dataType = BIPIND_IMAGE_HANDLE;
                    break;

                default:
                    /* We don't expect an Image Handle for other ops,
                     * but this is the end of the op, so ignore it.
                     */
                    //Report(("BIP: Image Handle %s ignored.\n", event->header.buffer));
                    return;
                }

                /* copy the data from the buffer */
                for(i=0; i < (event->header.len/2); i++)
                {
                    ih[i] = event->header.buffer[2*i + 1];
                }
/*              OS_MemCopy((U8 *)ih, event->header.buffer, event->header.len); */

                /* Indicate the complete Image Handle header */
                BipAppCallBack(&parms, 0, BIPINITIATOR_DATA_IND);
            }
            break;

        case OBEXH_APP_PARAMS:
            /* Check for parameters */
            if (event->header.len == 0) {
                break;
            }

            /* Reassemble the parameters */
			ASSERT(client->appParms[0] + event->header.len <= sizeof(client->appParms));
            p = client->appParms + client->appParms[0] + 1;
            OS_MemCopy(p, event->header.buffer, event->header.len);
            client->appParms[0] += event->header.len;

            if (client->appParms[0] == event->header.totalLen) {
                /* Parse the App Parameters */
                p = client->appParms + 1;
                while (p - (client->appParms + 1) < event->header.totalLen) {
                    switch (p[0]) {
                    case BIPAPTAG_NB_RETURNED_HANDLES:
                        client->data->i.iList.nbReturnedHandles =
                            BEtoHost16(p + 2);
                        break;

                    case BIPAPTAG_LIST_START_OFFSET:
                        break;

                    case BIPAPTAG_LATEST_CAPTURED_IMAGES:
                        break;

                    case BIPAPTAG_PARTIAL_FILE_LENGTH:
                    case BIPAPTAG_PARTIAL_FILE_START_OFFSET:
                    case BIPAPTAG_TOTAL_FILE_SIZE:
                    case BIPAPTAG_END_FLAG:
                    case BIPAPTAG_REMOTE_DISPLAY:
                    case BIPAPTAG_SERVICE_ID:
                    case BIPAPTAG_STORE_FLAG:
                        break;

                    default:
                        break;
                    }
                    p += p[1] + 2;
                }
                /* Reset the App Param length */
                client->appParms[0] = 0;
            }
            break;

        default:
            break;
        }
        break;

    case GOEP_EVENT_DISCOVERY_FAILED:
    case GOEP_EVENT_NO_SERVICE_FOUND:
        client->data = &client->tData;
        client->data->bipOp = BIPOP_CONNECT;
        BipAppCallBack(&parms, BIP_NO_SERVICE_FOUND, BIPINITIATOR_FAILED);
        break;

    case GOEP_EVENT_SCO_REJECT:
        client->data = &client->tData;
        client->data->bipOp = BIPOP_CONNECT;
        BipAppCallBack(&parms, BIP_SCO_REJECT, BIPINITIATOR_FAILED);
        break;

    case GOEP_EVENT_BTCHIP_REJECT:
        client->data = &client->tData;
        client->data->bipOp = BIPOP_CONNECT;
        BipAppCallBack(&parms, BIP_BTCHIP_REJECT, BIPINITIATOR_FAILED);
        break;
        
#if OBEX_AUTHENTICATION == XA_ENABLED

    case GOEP_EVENT_AUTH_CHALLENGE:
        client->state = BIPCHS_AUTHENTICATING;
        parms.challenge = &event->challenge;
        BipAppCallBack(&parms, 0, BIP_OBAUTH_CHAL);
        break;

    case GOEP_EVENT_AUTH_RESPONSE:
        parms.response = &event->response;
        BipAppCallBack(&parms, 0, BIP_OBAUTH_RSP);
        break;
        
#endif /* OBEX_AUTHENTICATION == XA_ENABLED */

    default:
        //Report(("BIP: Client Event %d ignored.\n", event));
        break;
    }
}
Ejemplo n.º 3
0
/*************************************************************************
* FUNCTION                                                            
*	avrcpQueryTGCallback
* DESCRIPTION                                                           
*   The function is called by SDAP to indicate the profiles the search result
*
* PARAMETERS
*	sqt  : SdpQueryToken contains information such as remote device information. uuid...
*	result  : The service search result.
*   serv_chn: It is not used in AVRCP profile
* RETURNS
*	None
* LOCAL AFFECTED
*   
*************************************************************************/
void avrcpQueryTGCallback(SdpQueryToken *sqt, U8 result, U8 attribute_index, U8 *attribute_value)
{
    SdpQueryToken *token;
    BtRemoteDevice *remDev;
    AvrcpChannel *chnl = ContainingRecord(
                                                                    sqt, 
                                                                    AvrcpChannel, 
                                                                    sdpQueryToken
                                                                    );
    
    token  = sqt;
    if(chnl->cmgrHandler.bdc ==0)
    {
        /* 
            The remote side connects our AVRCP after we send avrcp connect req.
            We will reject the remote side avrcp connect req but will get a disconnect ind.
            The Avrcp connect req from our side will think the connect requestion is failed and 
            remove the cmgr and rem at the same time.
        */
        if (sqt->rm !=0)
            sqt->rm->discFlag = 1;
        return;
    }

    if( chnl ){
    	/// has do the search 
    	chnl->remoteTGSdp.tgValid = TRUE;
    }
    remDev = chnl->cmgrHandler.bdc->link;

    kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_TG_CALLBACK , result, attribute_index);
    switch (result) 
    {
        case BT_STATUS_SUCCESS:
        	{
        		/// remote has a TG record
        		chnl->remoteTGSdp.tgAvailable= TRUE;
        		
	        	switch( avrcp_sdp_attribute_id_list[attribute_index] ){
	        		case AID_PROTOCOL_DESC_LIST:
	        			{
	        				/// update the result
	        				chnl->remoteTGSdp.tgVersion = BEtoHost16(attribute_value);
	        			}
	        			break;
					case AID_SUPPORTED_FEATURES:
						{
	        				/// update the result
	        				chnl->remoteTGSdp.tgFeatureFlag = BEtoHost16(attribute_value);
	        				
							/// search is finished. try to connect
							if( 2 == avrcp_sdp_attribute_num ){
                                if( chnl->connFlag == 1 ){ // pending connect
								if(chnl->conntimer.func!=0)
									EVM_CancelTimer(&chnl->conntimer);
								chnl->conntimer.func = AVRCP_Connect_Timeout;
								chnl->conntimer.context = remDev;
								EVM_StartTimer(&chnl->conntimer, 20);
							}

                                AVRCP_UtilAVRCPSDPQueryInd(chnl, 0, chnl->remoteCTSdp.ctFeatureFlag, chnl->remoteTGSdp.tgFeatureFlag);
							}
	        			}
	        			break;
					case AID_BT_PROFILE_DESC_LIST: //AID_ADDITIONAL_PROT_DESC_LISTS:
						{
							chnl->remoteTGSdp.tgSupportBrowse = BEtoHost16(attribute_value);

							kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_TG_INFO , chnl->remoteTGSdp.tgVersion, chnl->remoteTGSdp.tgFeatureFlag, chnl->remoteTGSdp.tgSupportBrowse);
                            if( chnl->connFlag == 1 ){ // pending connect
							if(chnl->conntimer.func!=0)
								EVM_CancelTimer(&chnl->conntimer);
							chnl->conntimer.func = AVRCP_Connect_Timeout;
							chnl->conntimer.context = remDev;
							EVM_StartTimer(&chnl->conntimer, 20);
						}
                            AVRCP_UtilAVRCPSDPQueryInd(chnl, 0, chnl->remoteTGSdp.tgFeatureFlag, chnl->remoteCTSdp.ctFeatureFlag);

						}
						break;
	        	}
	        }
            /* AVRCP implementor shall handle the status report, ESI not handle it!*/                
            break;
        case BT_STATUS_CONNECTION_FAILED:
        case BT_STATUS_FAILED:
        case BT_STATUS_NOSERVICES:
        	/// NO CT or TG record available => report fail
        	/// One of CT or TG is available => try to connect
			kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_TG_INFO , chnl->remoteTGSdp.tgAvailable, chnl->remoteTGSdp.tgVersion, chnl->remoteTGSdp.tgFeatureFlag, chnl->remoteTGSdp.tgSupportBrowse);

        	if( FALSE == chnl->remoteCTSdp.ctAvailable && FALSE == chnl->remoteTGSdp.tgAvailable ){
				// search remote's CT role and try to connect it
                AvrcpStartMultiServiceQuery(chnl, BSQM_FIRST, AVRCP_TG); // local is TG
            }else{
            	/// After a TG connect
	            if(chnl->conntimer.func!=0)
	                EVM_CancelTimer(&chnl->conntimer);
	            chnl->conntimer.func = AVRCP_Connect_Timeout;
	            chnl->conntimer.context = remDev;
	            EVM_StartTimer(&chnl->conntimer, 20);
            }
            
            AVRCP_UtilAVRCPSDPQueryInd(chnl, 1, 0, 0);

            break;
    }
}
Ejemplo n.º 4
0
/*---------------------------------------------------------------------------
 *            BipResponderCallback
 *---------------------------------------------------------------------------
 *
 * Synopsis:  This function processes Responder events.
 *
 * Return:    void
 *
 */
void BipResponderCallback(GoepServerEvent *event)
{
    ObexRespCode        rcode;
    ObStatus            status;
    BipObexServer      *server;
    BipCallbackParms    parms;
    U8                 *p;
    BipImgHandlePtr     ih = NULL;

    parms.obex.server = FindBipResponder(event->handler);
    if (parms.obex.server == 0) {
		kal_trace(BT_TRACE_G6_OBEX,BT_BIP_RESPONDER_NOT_FOUND);
        return;
    }
    server = parms.obex.server;

    switch (event->event) {
    case GOEP_EVENT_TP_CONNECTED:
        //Report(("[BIP ADP] Server: Transport Connection has come up.\n"));
        break;

    case GOEP_EVENT_TP_DISCONNECTED:
        //Report(("[BIP ADP] Server: Transport Connection has been disconnected.\n"));

        if (server->object) {
            /* close any objects associated with the aborted operation */
            BIPOBS_Close(&server->object);
        }
        server->request.bipOp = BIPOP_CONNECT;
        BipAppCallBack(&parms, OB_STATUS_DISCONNECT, BIPRESPONDER_COMPLETE);

        server->request.offset = server->request.totLen = 0;
        break;

    case GOEP_EVENT_ABORTED:
		/*
        since OBEX do not updated now...
        if (event->abortReason != OBRC_LINK_DISCONNECT)
        */
		{
            /* Check if thumbnail is requested by Partial Content rspcode */		
        if ((event->oper == GOEP_OPER_PUSH) &&
			(server->object) && 
            (server->object->bipOp == BIPOP_PUT_IMAGE) &&
            (server->object->code == OBRC_PARTIAL_CONTENT)) {
            /* Handle the Partial Content special case on PutImage */
            BIPOBS_Close(&server->object);
            BipAppCallBack(&parms, OBRC_PARTIAL_CONTENT, BIPRESPONDER_COMPLETE);
            break;
        }
        if ((event->oper == GOEP_OPER_PULL) && server->object &&
            (server->object->bipOp == BIPOP_GET_IMAGES_LIST) &&
            (server->object->code == OBRC_PARTIAL_CONTENT)) {
            /* Handle the Partial Content special case on PutImage */
            BIPOBS_Close(&server->object);
            BipAppCallBack(&parms, OBRC_PARTIAL_CONTENT, BIPRESPONDER_COMPLETE);
            break;
        }
		}

        kal_trace(BT_TRACE_G6_OBEX,BT_BIP_SERVER_OPER_ABORTED, event->oper);
        if (server->object) {
            /* close any objects associated with the aborted operation */
            BIPOBS_Close(&server->object);
        }
            
        /* Tell the responder to abort */
        BipAppCallBack(&parms, 0, BIPRESPONDER_ABORT);
        break;

    case GOEP_EVENT_PRECOMPLETE:
        if ((event->oper == GOEP_OPER_PUSH) && 
            (server->object->bipOp == BIPOP_PUT_IMAGE) &&
            (server->object->code == OBRC_PARTIAL_CONTENT)) {
            /* Handle the Partial Content special case on PutImage */
            kal_trace(BT_TRACE_G6_OBEX,BT_BIP_SERVER_PARTIAL_CONTENT_PUTIMG);
            GOEP_ServerAbort(&server->sApp, OBRC_PARTIAL_CONTENT);
        }
        else if ((event->oper == GOEP_OPER_PULL) && 
            (server->object->bipOp == BIPOP_GET_IMAGES_LIST) &&
            (server->object->code == OBRC_PARTIAL_CONTENT)) {
            /* Handle the Partial Content special case on PutImage */
            kal_trace(BT_TRACE_G6_OBEX,BT_BIP_SERVER_PARTIAL_CONTENT_GETIMGLIST);
	        
            GOEP_ServerAbort(&server->sApp, OBRC_PARTIAL_CONTENT);
        }
        break;

    case GOEP_EVENT_CONTINUE:
        status = OB_STATUS_SUCCESS;

        switch(event->oper) {
        case GOEP_OPER_DISCONNECT:
            status = OB_STATUS_DISCONNECT;
            /* No break; fall through */
        case GOEP_OPER_ABORT:
            /* <!-- added by yfchu on 2007.8.16 */
            GOEP_ServerContinue(&server->sApp);
            /* -->    */
            return;

        case GOEP_OPER_CONNECT:
            server->request.bipOp = BIPOP_CONNECT;
            break;
            
        case GOEP_OPER_PUSH:
            if ((server->object->bipOp == BIPOP_PUT_IMAGE) &&
                (event->info.pushpull.finalBit)) {
                /* Queue the Image Handle header in the final Put Response packet */
/*            Avoid to abort operation for lack of image handle info
                if (server->request.r.rImg.imgHandle[0] == 0) {
                GOEP_ServerAbort(&server->sApp, OBRC_INTERNAL_SERVER_ERR);
                }
*/
                if (server->request.r.rImg.imgHandle != 0) {
                    int i = 0;
                    
                    server->request.r.rImg.imgHandle[7] = 0;

                    while (server->request.r.rImg.imgHandle[i] != 0)
                    {
                        server->request.r.rImg.imgHandleUni[2*i] = 0;
                        server->request.r.rImg.imgHandleUni[2*i + 1] = server->request.r.rImg.imgHandle[i];
                        i++;
                    }
                    server->request.r.rImg.imgHandleUni[2*i] = 0;
                    server->request.r.rImg.imgHandleUni[2*i + 1] = 0;
        
                    if (GOEP_ServerQueueHeader(&server->sApp, BIPH_IMG_HANDLE,
                        (U8 *)server->request.r.rImg.imgHandleUni, (U16)(2*i+2)) == FALSE) {
                        GOEP_ServerAbort(&server->sApp, OBRC_INTERNAL_SERVER_ERR);
                    }
                }
            }
            else if (server->request.bipOp == BIPOP_PUT_IMAGE && 
                (server->request.r.rImg.name[0] == 0 &&
                server->request.r.rImg.name[1] == 0))
            {
                OS_MemCopy(server->request.r.rImg.name, server->object->name,
                    GOEP_MAX_UNICODE_LEN*2);
                server->request.r.rImg.img_len = server->object->objLen;
            }
            break;
        }

		parms.FinalPacket = event->info.pushpull.finalBit;
        BipAppCallBack(&parms, status, BIPRESPONDER_CONTINUE);
        break;

    case GOEP_EVENT_COMPLETE:
        switch (event->oper) {
        case GOEP_OPER_CONNECT:
            server->request.bipOp = BIPOP_CONNECT;
            BipAppCallBack(&parms, OB_STATUS_SUCCESS, BIPRESPONDER_COMPLETE);
            break;

        case GOEP_OPER_PUSH:
        case GOEP_OPER_PULL:
            rcode = BIPOBS_Close(&server->object);
            if (rcode != OBRC_SUCCESS) {
                GOEP_ServerAbort(&server->sApp, rcode);
            }
            BipAppCallBack(&parms, OB_STATUS_SUCCESS, BIPRESPONDER_COMPLETE);
            break;

        default:
            break;
        }

        //Report(("BIP: Server: %d operation complete.\n", event->oper));
        server->request.offset = server->request.totLen = 0;
        server->request.bipOp = BIPOP_NOP;
        break;

    case GOEP_EVENT_START:
        if (event->oper == GOEP_OPER_PULL || event->oper == GOEP_OPER_PUSH) {
            BipObexServer  *rServer = parms.obex.server;

            rServer->object = BIPOBS_New(&rServer->sApp);
            Assert(rServer->object);

            /* New operation, initialize BipData */
            OS_MemSet((U8 *)&rServer->request, 0, sizeof(BipData));
        } 
		if (event->oper == GOEP_OPER_CONNECT)
		{
            BipObexServer  *rServer = parms.obex.server;
            /* New operation, initialize connect target */
            OS_MemSet(rServer->request.r.rConnect.targetUuid, 0, sizeof(rServer->request.r.rConnect.targetUuid));
			rServer->request.r.rConnect.targetLen = 0;
            rServer->request.r.rConnect.targetService = 0;
		}
        break;

    case GOEP_EVENT_HEADER_RX:
        switch (event->header.type) {
        case OBEXH_LENGTH:
            if (event->oper == GOEP_OPER_PUSH) {
                /* Set the object length for Put operations only */
                BIPOBS_SetObjectLen(server->object, event->info.pushpull.objectLen);
            }
            break;

        case BIPH_IMG_DESCRIPTION:
            if (event->header.len == 0 ||
                event->header.len == event->header.totalLen) {
                /* reset the offset */
                server->request.offset = 0;
            }
            if (event->header.len != 0) {
                /* tell the responder we have data */
                server->request.totLen = event->header.totalLen;
                server->request.len = event->header.len;

                switch (server->request.bipOp) {
                case BIPOP_GET_IMAGES_LIST:
                    server->request.i.iHDsc.buff = event->header.buffer;
                    server->request.dataType = BIPIND_HANDLES_DESCRIPTOR;
                    break;

                case BIPOP_PUT_IMAGE:
                case BIPOP_GET_IMAGE:
                    server->request.i.iIDsc.buff = event->header.buffer;
                    server->request.dataType = BIPIND_IMAGE_DESCRIPTOR;
                    break;

                default:
                    if (event->oper == GOEP_OPER_PULL || event->oper == GOEP_OPER_PUSH) {
                        BipResponderOp(event, &parms);
                    }
                    server->request.i.iIDsc.buff = event->header.buffer;
                    server->request.dataType = BIPIND_IMAGE_DESCRIPTOR;
                    break;
                }

                BipAppCallBack(&parms, 0, BIPRESPONDER_DATA_IND);

                /* Check if we have the entire description */
                if (server->request.totLen >
                    event->header.len + server->request.offset) {
                    server->request.offset += event->header.len;
                }
                else {
                    /* Set the offset back to null */
                    server->request.offset = server->request.totLen = 0;
                }
            }
            break;

        case BIPH_IMG_HANDLE:
            /* GOEP indicates the entire Unicode header */
            if (event->header.len != 0) {
                int i;
                switch (server->request.bipOp) {
                case BIPOP_GET_IMAGE_PROPERTIES:
                    ih = server->request.r.rProp.imgHandle;
                    break;

                case BIPOP_PUT_LINKED_THUMBNAIL:
                case BIPOP_GET_LINKED_THUMBNAIL:
                    ih = server->request.r.rThm.imgHandle;
                    break;

                case BIPOP_GET_IMAGE:
                    ih = server->request.r.rImg.imgHandle;
                    break;

                default:
                    /* We must not have the type header yet. Assume this is
                     * a PUT_LINKED_THUMBNAIL.
                     */
                    if (event->oper == GOEP_OPER_PULL || event->oper == GOEP_OPER_PUSH) {
                        BipResponderOp(event, &parms);
                    ih = server->request.r.rThm.imgHandle;
                    }
                    break;
                }

                /* copy the data from the buffer */
				if (ih != NULL)
				{
	                for(i = 0; i < (event->header.len/2); i++)
	                {
	                    ih[i] = event->header.buffer[2*i+1];
	                }
					/*OS_MemCopy((U8 *)ih, event->header.buffer, event->header.len); */
				}
            }
            break;

        case OBEXH_APP_PARAMS:
            /* Check for parameters */
            if (event->header.len == 0) {
                break;
            }

            /* Reassemble the parameters */
			ASSERT(server->appParms[0] + event->header.len <= sizeof(server->appParms));
            p = server->appParms + server->appParms[0] + 1;
            OS_MemCopy(p, event->header.buffer, event->header.len);
            server->appParms[0] += event->header.len;

            if (server->appParms[0] == event->header.totalLen) {
                /* Parse the App Parameters */
                p = server->appParms + 1;
                while (p - (server->appParms + 1) < event->header.totalLen) {
                    switch (p[0]) {
                    case BIPAPTAG_NB_RETURNED_HANDLES:
                        server->request.r.rList.nbReturnedHandles =
                            BEtoHost16(p + 2);
                        break;

                    case BIPAPTAG_LIST_START_OFFSET:
                        server->request.r.rList.listStartOffset =
                            BEtoHost16(p + 2);
                        break;

                    case BIPAPTAG_LATEST_CAPTURED_IMAGES:
                        server->request.r.rList.latestCapturedImages = p[2];
                        break;

                    case BIPAPTAG_STORE_FLAG:
                        server->request.r.rMon.storeFlag = p[2];
                        break;

                    case BIPAPTAG_PARTIAL_FILE_LENGTH:
                    case BIPAPTAG_PARTIAL_FILE_START_OFFSET:
                    case BIPAPTAG_TOTAL_FILE_SIZE:
                    case BIPAPTAG_END_FLAG:
                    case BIPAPTAG_REMOTE_DISPLAY:
                    case BIPAPTAG_SERVICE_ID:
                        break;

                    default:
                        break;
                    }
                    p += p[1] + 2;
                }
                /* Reset the App Param length */
                server->appParms[0] = 0;
            }
            break;

        case OBEXH_BODY:
            break;

        case OBEXH_END_BODY:
            break;

        case OBEXH_TARGET: /* CONNECT TARGET header */
			{    
				U8 len;

	            /* Reassemble the header */
				ASSERT (server->request.r.rConnect.targetLen + event->header.len <= sizeof(server->request.r.rConnect.targetUuid));
	            p = (U8*)(server->request.r.rConnect.targetUuid) + server->request.r.rConnect.targetLen;
	            OS_MemCopy(p, event->header.buffer, event->header.len);
	            server->request.r.rConnect.targetLen += event->header.len;

				len = server->request.r.rConnect.targetLen;
				p = (U8 *)(server->request.r.rConnect.targetUuid);
	            if (len == event->header.totalLen) 
				{
				    BipService targetService = 0;
				   
				    /* target header received */
	                if (OS_MemCmp(p, len, server->bipImgPullUuid, sizeof(server->bipImgPullUuid)))
	                {
	                    targetService = BIPSVC_IMAGE_PULL;
	                }
					else if (OS_MemCmp(p, len, server->bipImgPushUuid, sizeof(server->bipImgPushUuid)))
	                {
	                    targetService = BIPSVC_IMAGE_PUSH;
	                }

					server->request.r.rConnect.targetService = targetService;
	            }
        	}
			
            break;

        default:
            break;
        }
        break;

    case GOEP_EVENT_PROVIDE_OBJECT:
        /* If an operation has not yet been assigned, figure it out */
        if ((server->request.bipOp == BIPOP_NOP) &&
            (event->oper == GOEP_OPER_PULL || event->oper == GOEP_OPER_PUSH)) {
            BipResponderOp(event, &parms);
        }

        if (event->oper == GOEP_OPER_PULL &&
            server->request.bipOp & BIPOP_PULL_MASK) {
            BipAppCallBack(&parms, 0, BIPRESPONDER_REQUEST);
            if ((server->object->objLen != 0) &&
                (server->request.bipOp == BIPOP_GET_IMAGE ||
                server->request.bipOp == BIPOP_GET_MONITORING_IMAGE)) {
                /* Setup the LENGTH header for a Get Image response only */
                event->info.pushpull.objectLen = server->object->objLen;
            } else {
                /* Make sure we do not issue a LENGTH header for any other responses.  It
                 * is possible that we could have a value, if we received a LENGTH header 
                 * in a GET Request, so we always want to reset this value to zero.
                 */
                event->info.pushpull.objectLen = 0;
            }
        }
        else if (event->oper == GOEP_OPER_PUSH &&
            (server->request.bipOp == BIPOP_PUT_IMAGE ||
            server->request.bipOp == BIPOP_PUT_LINKED_THUMBNAIL)) {
            if (server->request.bipOp == BIPOP_PUT_IMAGE) {
                OS_MemCopy(server->request.r.rImg.name, server->object->name,
                    GOEP_MAX_UNICODE_LEN*2);
                server->request.r.rImg.img_len = server->object->objLen;
            }
            BipAppCallBack(&parms, 0, BIPRESPONDER_REQUEST);
        }
        GOEP_ServerAccept(&server->sApp, server->object);
        break;

    case GOEP_EVENT_AUTHORIZE_IND:
        BipAppCallBack(&parms, 0, BIPRESPONDER_AUTHORIZE_IND);
        break;

#if OBEX_AUTHENTICATION == XA_ENABLED

    case GOEP_EVENT_AUTH_CHALLENGE:
        parms.challenge = &event->challenge;
        BipAppCallBack(&parms, 0, BIP_OBAUTH_CHAL);
        break;

    case GOEP_EVENT_AUTH_RESPONSE:
        parms.response = &event->response;
        BipAppCallBack(&parms, 0, BIP_OBAUTH_RSP);
        break;
        
#endif /* OBEX_AUTHENTICATION == XA_ENABLED */

    default:
        //Report(("BIP: Server Event %d ignored.\n", event));
        break;
    }
}