Пример #1
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_ServerDeinit()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Deinitialize the OBEX Server transport. This function returns
 *            success if the server is not initialized.
 *
 * Return:    TRUE -  Server stack deinitialized.
 *            FALSE - Server cannot deinitialize.
 *
 */
BOOL TCPSTACK_ServerDeinit(ObTcpServerTransport *txp)
{
    ObexServerTransports *transport = ContainingRecord(txp, ObexServerTransports, ObexServerTcpTrans);
    ObexAppHandle *appHndl = (ObexAppHandle*)ContainingRecord(transport, ObexServerApp, trans);

    if (txp->server.state == OCS_UNINITIALIZED) {
        return TRUE;
    }
    
    ASSERT(txp->server.app == appHndl);

    if (txp->server.state != OCS_IDLE) {
        return FALSE;
    }

    /* Close registration socket */
    closesocket(txp->serverReg);
    txp->serverReg = INVALID_SOCKET;

    txp->server.state = OCS_UNINITIALIZED;
    txp->server.app = 0;
    RemoveEntryList(&txp->server.node);

    return TRUE;
}
Пример #2
0
static void _time_gatt_read_characteristic_value_cb(BtGattEvent *event) {
	// To be modified.
	BtStatus status;
	BtGattReadCharacteristicValueResultEvent *ptr;
	TimePacket *pkt;
	TimeCTransport *pChnl;
	U16 uuid = 0;

	ptr = (BtGattReadCharacteristicValueResultEvent *) event->parms;
	pkt = ContainingRecord(event->pGattOp, TimePacket, gatt_op);
	pChnl = (TimeCTransport *) pkt->chnl;

	switch (ptr->flag) {
		case BT_GATT_EVENT_RESULT_DONE_COMPLETED:
			OS_Report("[Time] Read Characteristic Value with result DONE_COMPLETED");
			_time_gatt_notify_query_result(pkt, ptr->data, ptr->length, BT_STATUS_SUCCESS);
			break;
		case BT_GATT_EVENT_RESULT_ERROR:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
		case BT_GATT_EVENT_RESULT_DISCONNECT:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
	}
}
Пример #3
0
U8 time_att_db_update_ctrl_point_callback(U8 type, BtRemoteDevice *link, U16 *len, U8 **raw) {
	TimeSTransport *pChnl;
	TimeSContext *pCntx;

	pChnl = times_find_server_tp(link->bdAddr.addr);
	if (pChnl == NULL) {
		return BT_STATUS_FAILED;
	}

	OS_Report("[Time] %s(), type: %d", __FUNCTION__, type);
	pCntx = ContainingRecord(pChnl, TimeSContext, chnl);
	if (type == ATT_OP_WRITE || type == ATT_OP_EXECUTE_WRITE) {
		if ((pChnl->update_status.cur_state == TIME_UPDATE_STATE_IDLE) &&
				(*raw[0] == TIME_UPDATE_CTRL_REQUEST)) {
			pChnl->update_status.cur_state = TIME_UPDATE_STATE_UPDATE_PENDING;
			times_notify_request_server_update(pCntx);
			return BT_STATUS_SUCCESS;

		} else if ((pChnl->update_status.cur_state == TIME_UPDATE_STATE_UPDATE_PENDING) &&
				(*raw[0] == TIME_UPDATE_CTRL_CANCEL)) {
			pChnl->update_status.cur_state = TIME_UPDATE_STATE_IDLE;
			pChnl->update_status.result = TIME_UPDATE_RESULT_CANCELED;
			times_notify_cancel_server_update(pCntx);
			return BT_STATUS_SUCCESS;
		}
	}
	return BT_STATUS_FAILED;
}
Пример #4
0
static void _time_gatt_write_characteristic_descriptor_cb(BtGattEvent *event) {
	BtStatus status;
	BtGattWriteCharDescriptorResultEvent *ptr;
	TimePacket *pkt;
	TimeCTransport *pChnl;
	U16 uuid = 0;

	ptr = (BtGattWriteCharDescriptorResultEvent *) event->parms;
	pkt = ContainingRecord(event->pGattOp, TimePacket, gatt_op);
	pChnl = (TimeCTransport *) pkt->chnl;

	switch (ptr->flag) {
		case BT_GATT_EVENT_RESULT_DONE_COMPLETED:
			OS_Report("[Time] Write Characteristic Descriptor with result DONE_COMPLETED");
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_SUCCESS);
			break;
		case BT_GATT_EVENT_RESULT_ERROR:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
		case BT_GATT_EVENT_RESULT_DISCONNECT:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
	}

}
Пример #5
0
BtStatus AvrcpCreateAclLink(BD_ADDR *Addr, CmgrHandler *Handler, CmgrCallback Callback)
{
    AvrcpChannel   *chnl = ContainingRecord(Handler, AvrcpChannel, cmgrHandler);
    BtStatus status;
       
    status = CMGR_CreateDataLink(Handler, Addr);
    kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_CREATEACL, status);

    if (status == BT_STATUS_SUCCESS) 
    {
#ifdef __BT_AVRCP_V14__
        status = AvrcpStartServiceQuery(chnl, BSQM_FIRST);
#else

#ifdef __BT_AVRCP_V13__
		status = AvrcpStartServiceQuery(chnl, BSQM_FIRST);
#else
		status = AvrcpStartMultiServiceQuery(chnl, BSQM_FIRST, chnl->role);
#endif
		
#endif
    }
    return status;

}
Пример #6
0
static void avrcpQueryCallback(SdpQueryToken *sqt, U8 result, U8 serv_chn)
{
    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;
    }

    remDev = chnl->cmgrHandler.bdc->link;
#if 1    
    kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_QUERY_CB, result);
    switch (result) 
    {
        case BT_STATUS_SUCCESS:
//            status = AVCTP_Connect(&chnl->chnl, remDev);
            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 implementor shall handle the status report, ESI not handle it!*/                
            break;
        case BT_STATUS_CONNECTION_FAILED:
            break;
        case BT_STATUS_FAILED:
            AvrcpReportFailedConnect(chnl);
            /* Do we not indicate this back somehow? */
            break;
        case BT_STATUS_NOSERVICES:
            AvrcpReportFailedConnect(chnl);
            break;
    }
#endif

//    AVCTP_Connect(&chnl->chnl, remDev);

}
Пример #7
0
static void _time_gatt_discovery_characteristic_descriptors_cb(BtGattEvent *event) {
	BtStatus status = BT_STATUS_FAILED;
	BtGattDiscoveryAllCharacteristicDescriptorsResultEvent *ptr;
	TimePacket *pkt;
	TimeCTransport *pChnl;
	U16 uuid = 0;

	ptr = (BtGattDiscoveryAllCharacteristicDescriptorsResultEvent *) event->parms;
	pkt = ContainingRecord(event->pGattOp, TimePacket, gatt_op);
	pChnl = (TimeCTransport *) pkt->chnl;

	switch (ptr->flag) {
		case BT_GATT_EVENT_RESULT_CONTINUE_DATA:
			OS_Report("[Time] Characteristic Descriptor found. type: %d, uuid: 0x%04x", ptr->type, ptr->uuid16);
			OS_Report("[Time] Char desc value handle: 0x%04x", ptr->attributeHandle);
			pkt->start_handle = ptr->attributeHandle;
			pkt->success_flag = 1;
			break;

		case BT_GATT_EVENT_RESULT_DONE_COMPLETED:
			OS_Report("[Time] Discovery Characteristic Descriptor with result DONE_COMPLETED");
			if (pkt->success_flag != 1) {
				_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
				return;
			}

			_time_access_value_handle_cache(pChnl, pkt->value_id, 1, &pkt->start_handle);
			if (pkt->value_id == GATT_TIME_CTTIME_NOTIFY) {
				switch (pkt->type) {
					case TIME_PKT_READ:
						status = _time_gatt_read_characteristic_descriptor(pkt, pkt->start_handle);
						break;
					case TIME_PKT_WRITE:
						status = _time_gatt_write_characteristic_descriptor(pkt, pkt->start_handle);
						break;
				}

				if (status != BT_STATUS_SUCCESS && status != BT_STATUS_PENDING) {
					_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
				}
			} else {
				_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			}
			break;

		case BT_GATT_EVENT_RESULT_ERROR:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
		case BT_GATT_EVENT_RESULT_DISCONNECT:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
	}
}
Пример #8
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_ClientDeinit()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Deinitialize the OBEX Client transport. This function returns
 *            success if the client is not initialized.
 *
 * Return:    TRUE -  Client stack deinitialized.
 *            FALSE - Client cannot deinitialize.
 *
 */
BOOL TCPSTACK_ClientDeinit(ObTcpClientTransport *txp)
{
    ObexClientTransports *transport = ContainingRecord(txp, ObexClientTransports, ObexClientTcpTrans);
    ObexAppHandle *appHndl = (ObexAppHandle*)ContainingRecord(transport, ObexClientApp, trans);

    if (txp->client.state == OCS_UNINITIALIZED) {
        return TRUE;
    }

    ASSERT(txp->client.app == appHndl);
    
    if (txp->client.state != OCS_IDLE) {
        return FALSE;
    }

    txp->client.state = OCS_UNINITIALIZED;
    txp->client.app = 0;
    RemoveEntryList(&txp->client.node);

    return TRUE;
}
Пример #9
0
void time_gatt_notify_value_callback(void *user_data, BtGattEvent *event) {
	BtGattValueNotificationResultEvent *ptr;
	TimePacket *pkt;
	TimeSContext *pCntx;

	OS_Report("[Time] %s(), event: 0x%02x (should be 0x12)",__FUNCTION__, event->eType);
	if (event->eType != BT_GATT_OPERATOR_NOTIFICATIONS) {
		return;
	}

	ptr = (BtGattValueNotificationResultEvent *) event->parms;
	pkt = ContainingRecord(user_data, TimePacket, gatt_op);
	pCntx = ContainingRecord(pkt->chnl, TimeSContext, chnl);

	OS_Report("[Time] Notify Value with result: %d", ptr->flag);

	if (pCntx != NULL) {
		times_notify_notify_value_result(pCntx);
	} else {
		OS_Report("[Time] ERROR: %s() with NULL context", __FUNCTION__);
	}
}
Пример #10
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_ClientInit()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Initialize the OBEX Client Tcp transport. This function is
 *            called by OBSTACK_ClientInit() in obstack.c.
 *
 * Return:    OB_STATUS_SUCCESS - Initialized successfully
 *            OB_STATUS_FAILED - Unable to bind to the stack.
 *
 */
ObStatus TCPSTACK_ClientInit(ObTcpClientTransport *txp)
{
    ObexClientTransports *transport = ContainingRecord(txp, ObexClientTransports, ObexClientTcpTrans);
    ObexAppHandle *appHndl = (ObexAppHandle*)ContainingRecord(transport, ObexClientApp, trans);

    /* Initialize the TCP client transport */
    InitTcpClientTransport(txp);

    ASSERT(txp->client.state == OCS_UNINITIALIZED);
        
    /* Only initialize the socket list once */
    if (flags == 0) {
        InitializeListHead(&clientList);
        InitializeListHead(&serverList);
        flags = 1;
    }


    /* The same Async event handler is used for all clients. */
    if (asyncEventHandle == 0) {
        if ((asyncEventHandle = InitAsyncCallback()) == 0)
           return OB_STATUS_FAILED;
    }

    txp->client.conn = INVALID_SOCKET;
    txp->client.state = OCS_IDLE;
    txp->client.transport.connected = &txp->client.state;
    txp->client.transport.funcTab = &TcpStkFuncTable;
    txp->client.transport.context = (ObexTransportContext)&txp->client.conn;
    txp->client.transport.tpType = OBEX_TP_TCP;

    txp->client.app = appHndl;
    InsertTailList(&clientList, &txp->client.node);

    return OB_STATUS_SUCCESS;

}
Пример #11
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_SendTxBuffer()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Send a buffer over the transport connection.
 *
 * Return:    Status of the Send operation.
 */
static ObStatus TCPSTACK_SendTxBuffer(ObexTransportContext con, U8 *buff, U16 len)
{
    ObexPacket             *obp;
    I32                     rcode;
    ObTcpCommonTransport   *txp;

    ASSERT(len <= TCPSTACK_MaxTxSize(con));

    /* Get the correct the TCP transport structure for this callback */
    txp = ContainingRecord((SOCKET *)con, ObTcpCommonTransport, conn);

    rcode = send(*(SOCKET *)con, buff, len, 0);
    if (rcode == len) {
        /* Complete the transmit now */
        obp = ContainingRecord(buff, ObexPacket, buffer);
        ASSERT(obp->buffer == buff);

        /* NOTE: While it is permitted to complete a transmit while in the
         *       context of the request, there is some risk in doing this.
         *       The risk is associated with a recursive loop that develops
         *       between the transmit code and the transmit done code. This
         *       code will recursively loop until the entire OBEX packet
         *       has been sent. If stack overflow is at risk, you must
         *       complete the packets asynchronously or use small OBEX
         *       packet size multiples.
         */
        ASSERT(txp);
        OBPROT_TxDone(txp->app, obp);

        return OB_STATUS_SUCCESS;
    }

    /* Tx Failed! Put the packet back into the queue. */
    OBPROT_ReturnTxBuffer(buff);

    return OB_STATUS_FAILED;
}
Пример #12
0
/*************************************************************************
* FUNCTION                                                            
*	AVRCP_Connect_Timeout
* DESCRIPTION                                                           
*   The function is called by Timer
*   It is used to delay the connect action
*
* PARAMETERS
*   Timer
* RETURNS
*	None
* LOCAL AFFECTED
*   
*************************************************************************/
void AVRCP_Connect_Timeout(EvmTimer *Timer)
{
    AvrcpChannel *channel;
    BtStatus status = BT_STATUS_FAILED;

    channel = ContainingRecord(Timer, AvrcpChannel, conntimer);
    kal_trace( BT_TRACE_G8_AVRCP, BT_AVRCP_SDP_CONNECT_TIMEOUT, channel->chnl.channelType);

    status = AVCTP_Connect(&channel->chnl, (BtRemoteDevice *)Timer->context);
    OS_Report("[AVRCP] status:%d", status);
    if( status != BT_STATUS_PENDING ){
        AvrcpReportFailedConnect(channel);
    }
    
}
Пример #13
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_DisconnectReq()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Disconnect the underlying transport connection.
 *
 * Return:    Status of the Disconnect operation.
 */
static ObStatus TCPSTACK_DisconnectReq(ObexTransportContext con)
{
    I32     rcode;
    ObTcpCommonTransport   *txp;

    /* Get the correct the TCP transport structure for this callback */
    txp = ContainingRecord((SOCKET *)con, ObTcpCommonTransport, conn);

    rcode = closesocket(*(SOCKET *)con);
    ASSERT(rcode != SOCKET_ERROR);
    
    /* We want an asynchronous disconnect completion so post a
     * disconnect message to the event handler and return PENDING.
     */
    PostMessage(asyncEventHandle, WM_SELECT, txp->conn, FD_CLOSE);

    return OB_STATUS_PENDING;
}
Пример #14
0
BtStatus time_gatt_notify_value(TimePacket *pkt, U8 seq_num, U32 value_id) {
	BtStatus status = BT_STATUS_FAILED;
	TimeSTransport *pChnl = pkt->chnl;
	TimeSContext *pCntx = ContainingRecord(pChnl, TimeSContext, chnl);
	U8 *data = NULL;
	U16 value_handle = 0x0000, size = 0;
	time_t rawtime;
	struct tm *timeinfo;

	OS_Report("[Time] %s(), valud_id: %d, config: 0x%x",
			__FUNCTION__, value_id, pChnl->cttime_notify_config);

	if (pCntx != NULL && (pChnl->cttime_notify_config & GATT_CHAR_PROP_NOTIFY)) {
		switch (value_id) {
			case GATT_TIME_CTTIME:
				// TODO: Check don't-notify conditions. Within 15 min, Time adjust < 1min, etc.
				time(&rawtime);
				timeinfo = localtime(&rawtime);

				_time_server_info.ct_time.year = timeinfo->tm_year + 1900;
				_time_server_info.ct_time.month = (U8) timeinfo->tm_mon + 1;
				_time_server_info.ct_time.day = (U8) timeinfo->tm_mday;
				_time_server_info.ct_time.hours = (U8) timeinfo->tm_hour;
				_time_server_info.ct_time.minutes = (U8) timeinfo->tm_min;
				_time_server_info.ct_time.seconds = (U8) timeinfo->tm_sec;
				_time_server_info.ct_time.wday = (U8) timeinfo->tm_wday + 1;
				_time_server_info.ct_time.frac = 0;
				_time_server_info.ct_time.adj_reason = pCntx->adj_reason;

				value_handle = ATT_HANDLE_CHARACTERISTIC_CT_TIME_VALUE;
				data = (U8 *) &_time_server_info.ct_time;
				size = sizeof(_time_server_info.ct_time);
				break;
		}
		status = _time_gatt_notify_value(pkt, value_handle, size, data);
	}
	return status;
}
Пример #15
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_GetTpConnInfo()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Retrieves OBEX transport layer connection information. This
 *            function can be called when a transport connection is active
 *            to retrieve connection specific information. It should be used
 *            in conjunction with the receive flow control API to retrieve 
 *            the minimum amount of application storage space (low water mark)
 *            used when deciding to pause and resume data flow.
 *
 * Return:    TRUE  - The structure was successfully completed.
 *            FALSE - The transport is not connected.
 */
static BOOL TCPSTACK_GetTpConnInfo(ObexTransportContext  con,
                                   ObexTpConnInfo   *tpConnInfo)
{
    SOCKADDR             name;
    U32                  len;
    ObTcpCommonTransport *txp;

    tpConnInfo->tpType = OBEX_TP_TCP;
    tpConnInfo->minRxBuffs = 1;
    tpConnInfo->maxPduSize = 1450;

    /* Get the local device address for the transport being used */
    txp = ContainingRecord((SOCKET *)con, ObTcpCommonTransport, conn);
    /* We do not have a transport connection */
    if (txp->state != OCS_CONNECTED) return FALSE;
    len = sizeof(SOCKADDR);
    if (getsockname(txp->conn, &name, &len) != 0) return FALSE;
    ASSERT(len == 16);
    /* Get the server IP address and store it Big Endian */
    OS_MemCopy(txp->devAddr, name.sa_data+2, 4);
    tpConnInfo->devAddr = txp->devAddr;
    return TRUE;
}
Пример #16
0
static void _time_gatt_notify_query_result(TimePacket *pkt, U8 *data, U8 len, U8 result) {
	TimeCContext *pCntx;

	if (pkt == NULL) {
		OS_Report("[Time] Error: %s with NULL packet", __FUNCTION__);
		return;
	}

	if (pkt->chnl == NULL) {
		OS_Report("[Time] Error: %s with NULL channel", __FUNCTION__);
		return;
	}

	pCntx = ContainingRecord(pkt->chnl, TimeCContext, chnl);

	switch (pkt->value_id) {
		case GATT_TIME_CTTIME:
			if (result == BT_STATUS_SUCCESS && len > 9) {
				pCntx->date_time[0] = (0x00ff & data[0]) | (0xff00 & (data[1] << 8));
				pCntx->date_time[1] = (U16) data[2];
				pCntx->date_time[2] = (U16) data[3];
				pCntx->date_time[3] = (U16) data[4];
				pCntx->date_time[4] = (U16) data[5];
				pCntx->date_time[5] = (U16) data[6];
				pCntx->day_of_week = data[7];
				pCntx->frac = data[8];
				pCntx->adj_reason = data[9];
				timec_notify_read_remote_value_result(pCntx, result, pkt);
			} else {
				timec_notify_read_remote_value_result(pCntx, BT_STATUS_FAILED, pkt);
			}
			break;

		case GATT_TIME_CTTIME_NOTIFY:
			switch (pkt->type) {
				case TIME_PKT_READ:
					if (result == BT_STATUS_SUCCESS && len > 1) {
						pCntx->cttime_notify_config = (0x00ff & data[0]) | (0xff00 & (data[1] << 8));
						timec_notify_read_remote_value_result(pCntx, result, pkt);
					} else {
						timec_notify_read_remote_value_result(pCntx, BT_STATUS_FAILED, pkt);
					}
					break;

				case TIME_PKT_WRITE:
					timec_notify_write_remote_value_result(pCntx, result, pkt);
					break;
			}
			break;

		case GATT_TIME_LOCAL_TIME_INFO:
			if (result == BT_STATUS_SUCCESS && len > 1) {
				pCntx->time_zone = data[0];
				pCntx->dst = data[1];
				timec_notify_read_remote_value_result(pCntx, result, pkt);
			} else {
				timec_notify_read_remote_value_result(pCntx, BT_STATUS_FAILED, pkt);
			}
			break;

		case GATT_TIME_REF_TIME_INFO:
			if (result == BT_STATUS_SUCCESS && len > 3) {
				pCntx->time_source = data[0];
				pCntx->accuracy = data[1];
				pCntx->days_since_update = data[2];
				pCntx->hours_since_update = data[3];
				timec_notify_read_remote_value_result(pCntx, result, pkt);
			} else {
				timec_notify_read_remote_value_result(pCntx, BT_STATUS_FAILED, pkt);
			}
			break;

		case GATT_TIME_DST_INFO:
			if (result == BT_STATUS_SUCCESS && len > 7) {
				pCntx->date_time[0] = (0x00ff & data[0]) | (0xff00 & (data[1] << 8));
				pCntx->date_time[1] = (U16) data[2];
				pCntx->date_time[2] = (U16) data[3];
				pCntx->date_time[3] = (U16) data[4];
				pCntx->date_time[4] = (U16) data[5];
				pCntx->date_time[5] = (U16) data[6];
				pCntx->dst = data[7];
				timec_notify_read_remote_value_result(pCntx, result, pkt);
			} else {
				timec_notify_read_remote_value_result(pCntx, BT_STATUS_FAILED, pkt);
			}
			break;

		case GATT_TIME_SERVER_UPDATE_CTRL:
			timec_notify_write_remote_value_result(pCntx, result, pkt);
			break;

		case GATT_TIME_SERVER_UPDATE_STATE:
			if (result == BT_STATUS_SUCCESS && len > 1) {
				timec_notify_read_remote_value_result(pCntx, result, pkt);
			} else {
				timec_notify_read_remote_value_result(pCntx, BT_STATUS_FAILED, pkt);
			}
			break;
	}
}
Пример #17
0
/*---------------------------------------------------------------------------
 *            HidCmgrCallback()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Called by connection manager with link state events.
 *
 * Return:    (See header file)
 *
 */
void HidCmgrCallback(CmgrHandler *Handler, CmgrEvent Event, BtStatus Status) 
{
    BtStatus ret;
    HidChannel *channel = ContainingRecord(Handler, HidChannel, cmgrHandler);
    kal_trace(BT_TRACE_G2_PROFILES,HIDCMGRCALLBACKx02X ,Event);
    switch (Event) {
    case CMEVENT_DATA_LINK_CON_CNF:
        if (channel == NULL)
        {
            kal_trace(BT_TRACE_G2_PROFILES,HID_NOT_THE_CONNECT_BD_ADDR);
            return;
        }

        if(channel->cmgrHandler.bdc == 0)
        {
            kal_trace(BT_TRACE_G2_PROFILES,HIDCHANNELCMGRHANDLERBDC0);
            return;
        }
		
        kal_trace(BT_TRACE_G2_PROFILES,HID_STATUSx02X ,Status);
        if (Status != BT_STATUS_SUCCESS) 
        {
            /* Indicate the query response failure to the application */
            HidClearConnection(channel, Status, 0);
            return;
        }
        else
        {
#ifdef __BT_4_0_BLE__
            kal_trace(BT_TRACE_BLE_PROFILES, HID_CMGRCALLBACK_DEVTYPE, channel->cmgrHandler.bdc->devType);
            if (channel->cmgrHandler.bdc->devType == BT_DEV_TYPE_LE)
            {
                ret = GattClientConnect(channel->cmgrHandler.remDev);
                Report(("[HID] GattClientConnect ret: %d", ret));
                /* Since HID Gatt callback will be called even if connection is existed, there is unnecessary
                to handle return success case here. */
/*
                if (ret == BT_STATUS_SUCCESS)
                {
                    ret = HidStartGattServiceQuery(channel);
                    if (ret != BT_STATUS_PENDING)
                    {
                        channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
                        HidAppCallback(channel, HIDEVENT_QUERY_CNF, ret,
                                       &channel->queryRsp, (U16)(sizeof(HidQueryRsp)));
                    }
                }
*/                
            }
            else
#endif
            {
                if (channel->flags & CHNL_FLAG_SERVICE_QUERY)
                {
                    HidStartServiceQuery(channel);
                }
                else
                {
                    kal_trace(BT_TRACE_G2_PROFILES,HID_START_L2CAP_CONNECTION);
                    /* Start the L2CAP connection */
                    if (L2CAP_ConnectReq(&HID(hidCtrlPsm), BT_PSM_HID_CTRL, 
                                          channel->cmgrHandler.remDev, 0, 
                                          &(channel->ctrlCid)) == BT_STATUS_PENDING) {
                        channel->state = HID_STATE_CONN_PENDING;
                        channel->flags |= CHNL_FLAG_INITIATOR;
                        break;
                    }
                }
            }
        }
        break;
	case CMEVENT_DATA_LINK_DIS:
	{
		HidClearConnection(channel, Status, 0);
		return;
	}
    default:
        break;
    }
}
Пример #18
0
void HidSdpEventHandler(SdpQueryToken *sqt, U8 result, U8 attr_idx, U8 *attr_val)
{
    HidChannel     *channel = ContainingRecord(sqt, 
                                               HidChannel, sdpQueryToken);
    ReportDescriptorList* reportDescriptorList = NULL;
    HidParseData*	hpd ;
    kal_trace(BT_TRACE_G2_PROFILES,BT_HID_SDP_QUERY_CALLBACK_x02X ,result);

    switch (result) 
    {
        case BT_STATUS_SDP_CONT_STATE:
            kal_trace(BT_TRACE_G2_PROFILES,HID_SDP_SUCCESSFULLY);
            HidVerifySdpQueryRsp(channel, bt_hid_attr_id_list[attr_idx], attr_val, sqt->availValueLen, result);  
            break;

        case BT_STATUS_SUCCESS:
            HidVerifySdpQueryRsp(channel, bt_hid_attr_id_list[attr_idx], attr_val, sqt->availValueLen, result);
            if (channel->bSDPDiscPending)
            {
                HidClearConnection(channel, result, 0);
            }
            else 
            {
				hpd = (HidParseData*)hid_malloc(sizeof(HidParseData));
				Hid_Init_Parser(hpd);
                		channel->reportCons[0] = (HidReportConstructor*)hid_malloc(HID_REPORT_ID_MAX * sizeof(HidReportConstructor));
				btmtk_os_memset((U8*) channel->reportCons[0], 0, HID_REPORT_ID_MAX * sizeof(HidReportConstructor));

				reportDescriptorList = HidFindReportDescriptorByAddr(channel->cmgrHandler.remDev->bdAddr);
				
				if(reportDescriptorList != NULL )
				{		
					btmtk_os_memset(reportDescriptorList->BtAddr.addr, 0, 6);
					reportDescriptorList->inUse = FALSE;
					hid_free(reportDescriptorList->reportDescriptor);
					reportDescriptorList->reportDescriptorLength = 0;
				}
				
				HidCacheReportDescriptor(channel->cmgrHandler.remDev->bdAddr, channel->queryRsp.descriptorList, channel->queryRsp.descriptorLen);
				
        		if(HidAddDescriptor(channel) == BT_STATUS_SUCCESS)
        			bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor Successed!");
        		else
        			bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor failed!");   
                
				Hid_Free_Parser(hpd);
                channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
                HidSdpCallback(channel, result);
            }
            break;
		case BT_STATUS_NOSERVICES:
			{
				static const U8 HidDescriptorList[] = 
				{
				    HID_DESCRIPTOR
				};
				channel->queryRsp.descriptorLen = HID_DESCRIPTOR_LEN;
				channel->queryRsp.descriptorList = (U8*)hid_malloc(HID_DESCRIPTOR_LEN);
				btmtk_os_memset((U8*) channel->queryRsp.descriptorList, 0, HID_DESCRIPTOR_LEN);				
				btmtk_os_memcpy((U8*) channel->queryRsp.descriptorList, HidDescriptorList, HID_DESCRIPTOR_LEN);
				hpd = (HidParseData*)hid_malloc(sizeof(HidParseData));
				Hid_Init_Parser(hpd);
                		channel->reportCons[0] = (HidReportConstructor*)hid_malloc(HID_REPORT_ID_MAX * sizeof(HidReportConstructor));
				btmtk_os_memset((U8*) channel->reportCons[0], 0, HID_REPORT_ID_MAX * sizeof(HidReportConstructor));

                if(HidAddDescriptor(channel) == BT_STATUS_SUCCESS)
                    bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor Successed!");
                else
                    bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor failed!");
                
				Hid_Free_Parser(hpd);
                channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
                HidSdpCallback(channel, BT_STATUS_SUCCESS);
				break;
			}
        case BT_STATUS_CONNECTION_FAILED:
        case BT_STATUS_FAILED:
        default:
            channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
            HidClearConnection(channel, result, 0);
            break;
    }

}
Пример #19
0
/*---------------------------------------------------------------------------
 *            ChnServiceConnectionCallback()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Called by device manager with link state events.
 *
 * Return:    (See header file)
 *
 */
void ChnServiceConnectionCallback(CmgrHandler *Handler, CmgrEvent Event,
                                  BtStatus Status) 
{
    ChnChannel *Channel = ContainingRecord(Handler, ChnChannel, cmgrHandler);
    BtStatus return_code;

    Report(("+ ChnServiceConnectionCallback: Event=%d, Status=%d.", Event, Status));

    switch (Event) 
    {
    case CMEVENT_DATA_LINK_CON_CNF:
        DBG_PRINT_EVENT(("[CHN][EVENT] CMGR Event : CMEVENT_DATA_LINK_CON_CNF, Status=%d.", Status));
        if(ChnGetSubstate(Channel) == CHN_SUBSTATE_CONN_OUT1)
        {
            if (Status == BT_STATUS_SUCCESS) 
            {
                Channel->linkFlags |= CHN_LINK_ACL;
                /* FLOW : Start SDP query */
                if ((return_code = ChnStartServiceQuery(Channel, BSQM_FIRST)) == BT_STATUS_PENDING)
                {
                    ChnChangeSubstate(Channel, CHN_SUBSTATE_CONN_OUT2);
                }
                else
                {
                    ChnChangeSubstate(Channel, CHN_SUBSTATE_CLOSED1);
                }
            }
            else
            {
                /* This event shall not be received in other substates other than C1 */
                ChnChangeSubstate(Channel, CHN_SUBSTATE_CLOSED1);
            }
        }
        else if(ChnGetSubstate(Channel) == CHN_SUBSTATE_DISC1)
        {
            ChnDisconnecting(Channel);
        }
        else
        {
            DBG_PRINT_ERROR( ("[CHN][ERR] Unexpected substate==0x%X - (%s,%d)", ChnGetSubstate(Channel), __FILE__, __LINE__) );
            ChnChangeSubstate(Channel, CHN_SUBSTATE_CLOSED1);
        }
        break;

        case CMEVENT_DATA_LINK_DIS:
            /* We shall never run into this case */
            DBG_PRINT_EVENT(("[CHN][EVENT] CMGR Event : CMEVENT_DATA_LINK_DIS, Status=%d.", Status));
            DBG_PRINT_ERROR( ("[CHN][ERR] Unexpected substate==0x%X - (%s,%d)", ChnGetSubstate(Channel), __FILE__, __LINE__) );
            ChnCloseChannel(Channel);
            break;

        case CMEVENT_AUDIO_LINK_CON:
            DBG_PRINT_EVENT(("[CHN][EVENT] CMGR Event : CMEVENT_AUDIO_LINK_CON, Status=%d.", Status));
            /* Clear SCO connecting flag */
            Channel->linkFlags &= ~CHN_LINK_SCO_CONNECTING;
            ChnAppCallback(Channel, CHN_EVENT_AUDIO_CONNECTED, Status, 
            (U32)&Channel->cmgrHandler.bdc->link->bdAddr);
            if(ChnGetSubstate(Channel) == CHN_SUBSTATE_SLC1)
            {
                /* Remote connect SCO link */
                /* It could happen in SLC1 but no action needed */
            }
            else if(ChnGetSubstate(Channel) == CHN_SUBSTATE_SLC2)
            {
                ChnChangeSubstate(Channel, CHN_SUBSTATE_SLC1);
            }
            else if(ChnGetSubstate(Channel) == CHN_SUBSTATE_DISC1)
            {
                ChnDisconnecting(Channel);
            }
            else
            {
                DBG_PRINT_ERROR( ("[CHN][ERR] Unexpected substate==0x%X - (%s,%d)", ChnGetSubstate(Channel), __FILE__, __LINE__) );
            }
            break;

        case CMEVENT_AUDIO_LINK_DIS:
            DBG_PRINT_EVENT(("[CHN][EVENT] CMGR Event : CMEVENT_AUDIO_LINK_DIS, Status=%d.", Status));
            /* Clear SCO disconnecting flag */
            Channel->linkFlags &= ~CHN_LINK_SCO_DISCONNECTING;
            ChnAppCallback(Channel, CHN_EVENT_AUDIO_DISCONNECTED, Status, 
            (U32)&Channel->cmgrHandler.bdc->link->bdAddr);

            if(ChnGetSubstate(Channel) == CHN_SUBSTATE_SLC1)
            {
                /* Remote disconnect SCO link */
                /* It could happen in SLC1 but no action needed */
            }
            else if(ChnGetSubstate(Channel) == CHN_SUBSTATE_SLC2)
            {
                ChnChangeSubstate(Channel, CHN_SUBSTATE_SLC1);
            }
            else if(ChnGetSubstate(Channel) == CHN_SUBSTATE_DISC1)
            {
                ChnDisconnecting(Channel);
            }
            else
            {
                DBG_PRINT_ERROR( ("[CHN][ERR] Unexpected substate==0x%X - (%s,%d)", ChnGetSubstate(Channel), __FILE__, __LINE__) );
            }
            break;

        #if BT_SCO_HCI_DATA == XA_ENABLED
        case CMEVENT_AUDIO_DATA:
            DBG_PRINT_EVENT(("[CHN][EVENT] CMGR Event : CMEVENT_AUDIO_DATA, Status=%d.", Status));
            ChnAppCallback(Channel, CHN_EVENT_AUDIO_DATA, Status, (U32)&Handler->audioData);
            break;

        case CMEVENT_AUDIO_DATA_SENT:
            DBG_PRINT_EVENT(("[CHN][EVENT] CMGR Event : CMEVENT_AUDIO_DATA_SENT, Status=%d.", Status));
            ChnAppCallback(Channel, CHN_EVENT_AUDIO_DATA_SENT, Status, (U32)&Handler->audioPacket);
            break;
        #endif
    }
    Report(("- ChnServiceConnectionCallback."));
}
Пример #20
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_ServerInit()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Initialize the OBEX Server Tcp transport. This function will
 *            usually perform service registration, where necessary. This
 *            function is called by OBSTACK_ServerInit() in obstack.c.
 *
 * Return:    OB_STATUS_SUCCESS - Initialized successfully
 *            OB_STATUS_FAILED - Unable to bind to the stack.
 *            OB_STATUS_NO_RESOURCES - Out of resources
 *
 */
ObStatus TCPSTACK_ServerInit(ObTcpServerTransport *txp)
{
    I32         rcode;
    I32         myAddrLen;
    SOCKADDR_IN myAddr = {AF_INET, htons(650), INADDR_ANY, 0};
    ObexServerTransports *transport = ContainingRecord(txp, ObexServerTransports, ObexServerTcpTrans);
    ObexAppHandle *appHndl = (ObexAppHandle*)ContainingRecord(transport, ObexServerApp, trans);

    /* Initialize the TCP server transport */
    InitTcpServerTransport(txp);

    ASSERT (txp->server.state == OCS_UNINITIALIZED);

    /* Only initialize the socket list once */
    if (flags == 0) {
        InitializeListHead(&clientList);
        InitializeListHead(&serverList);
        flags = 1;
    }

    /* The same Async event handler is used for all servers. */
    if (asyncEventHandle == 0) {
        if ((asyncEventHandle = InitAsyncCallback()) == 0)
           return OB_STATUS_FAILED;
    }
   
    txp->server.conn = INVALID_SOCKET;
    txp->server.transport.connected = &txp->server.state;
    txp->server.transport.funcTab = &TcpStkFuncTable;
    txp->server.transport.context = (ObexTransportContext)&txp->server.conn;
    txp->server.transport.tpType = OBEX_TP_TCP;

    /* Register TCP Server by opening OBEX Server port */
    txp->serverReg = socket(AF_INET, SOCK_STREAM, 0);
    if (txp->serverReg == INVALID_SOCKET) {
        return OB_STATUS_NO_RESOURCES;
    }

    /* Try for the OBEX TCP Port first, if it's busy, any port will do. */
    rcode = bind(txp->serverReg, (struct sockaddr *)&myAddr, sizeof(SOCKADDR_IN));
    if (rcode == SOCKET_ERROR) {
        myAddr.sin_port = 0;
        rcode = bind(txp->serverReg, (struct sockaddr *)&myAddr, sizeof(SOCKADDR_IN));
    }

    /* Record the port the server is listening on */
    myAddrLen = sizeof(struct sockaddr);
    getsockname(txp->serverReg, (struct sockaddr *)&myAddr, &myAddrLen);
    txp->serverPort = ntohs(myAddr.sin_port);

    if (rcode != SOCKET_ERROR) {

        rcode = listen(txp->serverReg, 1);
        if (rcode != SOCKET_ERROR) {

            rcode = WSAAsyncSelect(txp->serverReg, asyncEventHandle, 
                                   WM_SELECT, FD_ACCEPT|FD_CLOSE);
            ASSERT(rcode != SOCKET_ERROR);
            
            txp->server.state = OCS_IDLE;
            txp->server.app = appHndl;
            InsertTailList(&serverList, &txp->server.node);
            return OB_STATUS_SUCCESS;
        }
    }
    kal_trace(BT_TRACE_G6_OBEX,TCPSTACK_SOCKET_FAILURExD ,WSAGetLastError());
    closesocket(txp->serverReg);
    txp->serverReg = INVALID_SOCKET;

    return OB_STATUS_FAILED;

}
Пример #21
0
static void timec_gatt_connection_callback(void *handler, BtGattEvent *event) {
	TimeCContext *pCntx;

	switch (event->eType) {
		case BT_GATT_APP_EVENT_CONNECTED:
			OS_Report("[Time] BT_GATT_APP_EVENT_CONNECTED");
	
			if (event->link && _cur_timec_chnl) {
				pCntx = ContainingRecord(_cur_timec_chnl, TimeCContext, chnl);
				timec_notify_connect_result(pCntx, BT_STATUS_SUCCESS);
			} else {
				OS_Report("[Time] Ignore. event->link: 0x%x, _cur_timec_chnl: 0x%x",
						event->link, _cur_timec_chnl);
			}
			break;

		case BT_GATT_APP_EVENT_DISCONNECTED:
			OS_Report("[Time] BT_GATT_APP_EVENT_DISCONNECTED");
			if (event->link && _cur_timec_chnl) {
				pCntx = ContainingRecord(_cur_timec_chnl, TimeCContext, chnl);
				timec_notify_disconnect_result(pCntx, BT_STATUS_SUCCESS);
				_cur_timec_chnl = NULL;
			} else {
				OS_Report("[Time] Ignore. event->link: 0x%x, _cur_timec_chnl: 0x%x", event->link);
			}
			break;
	
		case BT_GATT_APP_EVENT_VALUE_NOTIFICATION:
			OS_Report("[Time] BT_GATT_APP_EVENT_VALUE_NOTIFICATION");
			if (event->link && _cur_timec_chnl) {
				BtGattValueNotificationEvent *ptr = (BtGattValueNotificationEvent *) event->parms;
				// TODO: Compare the handle value with the cached one
				if (ptr->attributeHandle != ATT_HANDLE_CHARACTERISTIC_CT_TIME_VALUE) {
					OS_Report("[Time] Unrecognized handle: %d, ignore", ptr->attributeHandle);
					return;
				}

				if (ptr->attributeValue && ptr->attributeValueLen > 9) {
					pCntx = ContainingRecord(_cur_timec_chnl, TimeCContext, chnl);
					pCntx->date_time[0] = (0x00ff & ptr->attributeValue[0]) | (0xff00 & (ptr->attributeValue[1] << 8));
					pCntx->date_time[1] = (U16) ptr->attributeValue[2];
					pCntx->date_time[2] = (U16) ptr->attributeValue[3];
					pCntx->date_time[3] = (U16) ptr->attributeValue[4];
					pCntx->date_time[4] = (U16) ptr->attributeValue[5];
					pCntx->date_time[5] = (U16) ptr->attributeValue[6];
					pCntx->day_of_week = ptr->attributeValue[7];
					pCntx->frac = ptr->attributeValue[8];
					pCntx->adj_reason = ptr->attributeValue[9];
					timec_notify_server_notification(pCntx, GATT_TIME_CTTIME);
				}
			} else {
				OS_Report("[Time] Ignore. event->link: 0x%x, _cur_timec_chnl: 0x%x", event->link);
			}
			break;

		case BT_GATT_APP_EVENT_VALUE_INDICATION:
			OS_Report("[Time] BT_GATT_APP_EVENT_VALUE_INDICATION");
			break;

		default:
			break;
	}
}
Пример #22
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;
    }

}
Пример #23
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;
    }
}
Пример #24
0
static void _time_gatt_discovery_primary_service_by_uuid_cb(BtGattEvent *event) {
	BtStatus status;
	BtGattDiscoveryAllPrimaryServiceResultEvent *ptr;
	TimePacket *pkt;
	TimeCTransport *pChnl;
	U16 uuid = 0;

	ptr = (BtGattDiscoveryAllPrimaryServiceResultEvent *) event->parms;
	pkt = ContainingRecord(event->pGattOp, TimePacket, gatt_op);
	pChnl = (TimeCTransport *) pkt->chnl;

	switch (ptr->flag) {
		case BT_GATT_EVENT_RESULT_CONTINUE_DATA:
			// There should be only one instance of any service of Time profile
			OS_Report("[Time] Primary Service found. type: %d, uuid: 0x%04x", ptr->type, ptr->uuid2);
			OS_Report("[Time] Handle reange: 0x%04x to 0x%04x", ptr->startHandle, ptr->endHandle);
			pkt->start_handle = ptr->startHandle;
			pkt->end_handle = ptr->endHandle;
			pkt->success_flag = 1;
			break;

		case BT_GATT_EVENT_RESULT_DONE_COMPLETED:
			OS_Report("[Time] Discovery Primary Service by UUID with result DONE_COMPLETED. success: %d",
					pkt->success_flag);
			if (pkt->success_flag == 1) {
				 _time_access_service_handle_cache(pChnl, pkt->value_id, 1, &pkt->start_handle, &pkt->end_handle);
				switch (pkt->value_id) {
					case GATT_TIME_CTTIME:
					case GATT_TIME_CTTIME_NOTIFY:
						uuid = BT_UUID_CT_TIME;
						break;
					case GATT_TIME_LOCAL_TIME_INFO:
						uuid = BT_UUID_LOCAL_TIME_INFO;
						break;
					case GATT_TIME_REF_TIME_INFO:
						uuid = BT_UUID_REF_TIME_INFO;
						break;
					case GATT_TIME_DST_INFO:
						uuid = BT_UUID_TIME_WITH_DST;
						break;
					case GATT_TIME_SERVER_UPDATE_CTRL:
						uuid = BT_UUID_TIME_UPDATE_CONTROL_POINT;
						break;
					case GATT_TIME_SERVER_UPDATE_STATE:
						uuid = BT_UUID_TIME_UPDATE_STATE;
						break;
					default:
						break;
				}

				status = _time_gatt_discovery_characteristic_by_uuid(
						pkt, uuid, pkt->start_handle, pkt->end_handle);
				OS_Report("[Time] Discovery Characteristic, status: %d", status);

				if (status != BT_STATUS_PENDING && status != BT_STATUS_SUCCESS)
					_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			} else {
				_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			}
			break;

		case BT_GATT_EVENT_RESULT_ERROR:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
		case BT_GATT_EVENT_RESULT_DISCONNECT:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
	}
}
Пример #25
0
static void _time_gatt_discovery_characteristic_by_uuid_cb(BtGattEvent *event) {
	BtStatus status = BT_STATUS_FAILED;
	BtGattDiscoveryCharacteristicByUUIDResultEvent *ptr;
	TimePacket *pkt;
	TimeCTransport *pChnl;
	U16 dsp_handle;

	ptr = (BtGattDiscoveryCharacteristicByUUIDResultEvent *) event->parms;
	pkt = ContainingRecord(event->pGattOp, TimePacket, gatt_op);
	pChnl = (TimeCTransport *) pkt->chnl;

	switch (ptr->flag) {
		case BT_GATT_EVENT_RESULT_CONTINUE_DATA:
			OS_Report("[Time] Characteristic found. type: %d, uuid: 0x%04x", ptr->type, ptr->charUUID);
			OS_Report("[Time] Char handle: 0x%04x, property: 0x%02x ", ptr->attributeHandle, ptr->charProperty);
			OS_Report("[Time] Char value handle: 0x%04x", ptr->charValueAttributeHandle);
			pkt->start_handle = ptr->charValueAttributeHandle;
			pkt->success_flag = 1;
			break;

		case BT_GATT_EVENT_RESULT_DONE_COMPLETED:
			OS_Report("[Time] Discovery Characteristic by UUID with result DONE_COMPLETED. success: %d",
					pkt->success_flag);
			if (pkt->success_flag == 1) {
				switch (pkt->value_id) {
					case GATT_TIME_CTTIME:
						dsp_handle = pkt->start_handle + 1;
						_time_access_value_handle_cache(pChnl, pkt->value_id, 1, &pkt->start_handle);
						_time_access_value_handle_cache(pChnl, GATT_TIME_CTTIME_NOTIFY, 1, &dsp_handle);
						status = _time_gatt_read_characteristic_value(pkt, pkt->start_handle);
						break;

					case GATT_TIME_CTTIME_NOTIFY:
						dsp_handle = pkt->start_handle + 1;
						_time_access_value_handle_cache(pChnl, GATT_TIME_CTTIME, 1, &pkt->start_handle);
						_time_access_value_handle_cache(pChnl, pkt->value_id, 1, &dsp_handle);
						if (pkt->type == TIME_PKT_READ) {
							status = _time_gatt_read_characteristic_descriptor(pkt, pkt->start_handle + 1);
						} else { // TIME_PKT_WRITE
							status = _time_gatt_write_characteristic_descriptor(pkt, pkt->start_handle + 1);
						}
						break;

					case GATT_TIME_LOCAL_TIME_INFO:
					case GATT_TIME_REF_TIME_INFO:
					case GATT_TIME_DST_INFO:
					case GATT_TIME_SERVER_UPDATE_STATE:
						_time_access_value_handle_cache(pChnl, pkt->value_id, 1, &pkt->start_handle);
						status = _time_gatt_read_characteristic_value(pkt, pkt->start_handle);
						break;

					case GATT_TIME_SERVER_UPDATE_CTRL:
						_time_access_value_handle_cache(pChnl, pkt->value_id, 1, &pkt->start_handle);
						status = _time_gatt_write_without_response(pkt, pkt->start_handle);
						break;

					default:
						break;
				}
				
				if (status != BT_STATUS_PENDING && status != BT_STATUS_SUCCESS)
					_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			} else {
				_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			}
			break;

		case BT_GATT_EVENT_RESULT_ERROR:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
		case BT_GATT_EVENT_RESULT_DISCONNECT:
			_time_gatt_notify_query_result(pkt, 0, 0, BT_STATUS_FAILED);
			break;
	}
}
Пример #26
0
/*****************************************************************************
 * FUNCTION
 *  RfL2Callback
 * DESCRIPTION
 *  Callback routine for L2CAP connections.
 * PARAMETERS
 *  L2ChannelId     [IN]
 *  info            [IN]
 * RETURNS
 *  void
 *****************************************************************************/
void A2MPMainChannelL2Callback(L2capChannelId L2ChannelId, L2capCallbackParms *info)
{
	A2MP_MAIN_CONN *main_channel;
	A2MP_CONN *amp_psm_channel;
	BtRxPacket *rxPacket;
	U8 i=0;

	Report(("A2MPMainChannelL2Callback:%d,L2ChannelId:%d", info->event,L2ChannelId));
    switch (info->event)
    {
        case L2EVENT_DISCONNECTED:
             break;
        case L2EVENT_NOTIFY_AMP_PAL_CHANNEL_DISCONNECTED:
            main_channel = A2MP_FindMainChannel(info->aclLink);
            if(main_channel !=0)
            {
                Report(("The L2ChannelId:%d",L2ChannelId));
                Report(("The main_channel->localCid:%d",main_channel->localCid));
                 if(info->ptrs.NotifyL2CAPA2MPPDisconnected.localCid != main_channel->localCid)
//                    ME_DisconnectPhysicalLink(&info->aclLink->remoteWifiAMP, 0x13);
                {
                    BTA2MP_PhysicalLinkClose(info->aclLink);
                }
            }
             break;
        case L2EVENT_NOTIFY_AMP_NORMAL_CHANNEL_DISCONNECTED:
            main_channel = A2MP_FindMainChannel(info->aclLink);
            if(main_channel !=0)
            {
                Report(("The L2ChannelId:%d",L2ChannelId));
                Report(("The main_channel->localCid:%d",main_channel->localCid));
                for(i=0; i< BT_AMP_SUPPORTED_LOGICAL_CHANNEL; i++)
                {
                    Report(("%d,%d,%d,%d",main_channel->remDev->remoteWifiAMP.logicalLink[i].l2cap_id,
                        main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_sate,
                        main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_type,
                        info->ptrs.NotifyL2CAPA2MPPDisconnected.localCid));
                    if((main_channel->remDev->remoteWifiAMP.logicalLink[i].l2cap_id == info->ptrs.NotifyL2CAPA2MPPDisconnected.localCid) &&
                        (main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_sate == BDS_CONNECTED) &&
                        (main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_type > 0x01))
                    {
                        ME_DisconnectLogicalLink(&info->aclLink->remoteWifiAMP, main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_handle);
                        break;
                    }
                }
            }
            break;
        case L2EVENT_AMP_CHANNEL_DETECTED:
            if(info->status == 0x00)
            {
                if(info->aclLink->remoteWifiAMP.detected == 0)
                {
                    BtA2MPDiscoveryReq discoveryReq;
                    U8 extendedFeatureMask[2];

                    /* Start AMP discovery procedure. */
                    info->aclLink->remoteWifiAMP.detected = 1;
                    info->aclLink->remoteWifiAMP.exists = 0;
                    discoveryReq.mtu = 670;
                    discoveryReq.extendedFeatureMaskSize = 0;
                    extendedFeatureMask[0] = 0x00;
                    extendedFeatureMask[1] = 0x00;
                    discoveryReq.extendedFeatureMask = (U8 *)extendedFeatureMask;
                    discoveryReq.extendedFeatureMaskSize = 2;
                    BTA2MP_SendDiscoveryRequest(info->aclLink, &discoveryReq);
                }
                else
                {
                    Report(("Remote A2MP feature detected before, no A2MP operation"));
                }
            }
            break;
        case L2EVENT_PACKET_HANDLED:
            {
                BtA2MPPacket *a2mptxPacket;
    			main_channel = A2MP_FindMainChannel(info->aclLink);
    			if	(info->ptrs.packet->flags & BTP_FLAG_LSYSTEM)
    				Assert(0);

                a2mptxPacket = ContainingRecord(info->ptrs.packet, BtA2MPPacket, btPacket);
    			InsertTailList(&main_channel->freeTtxPacketsList, &(a2mptxPacket->node));
            }
            break;
#if L2CAP_FLOW_NON_BASIC_MODE == XA_ENABLED
        case L2EVENT_FLOW_DATA_IND:
            Report(("L2EVENT_FLOW_DATA_IND"));
            main_channel = A2MP_FindMainChannel(info->aclLink);
            rxPacket = (BtRxPacket *)RemoveHeadList(&main_channel->receivedPacketsList);
            info->ptrs.data = rxPacket->data;
            info->dataLen = rxPacket->dataLen;
            BTA2MP_RecvDataInd(info->aclLink, info->ptrs.data, info->dataLen);
            rxPacket->dataLen = 0;
            InsertTailList(&main_channel->rxPacketsBufferList, &rxPacket->node);
            L2CAP_UpdateSduDataBufferSeq(main_channel->localCid);
			break;
#endif

        case L2EVENT_LOCKSTEP_CONFIG_REQ:
            Report(("info->ptrs.lockstepConfigReq.createChannelnitiator:%d",info->ptrs.lockstepConfigReq.createChannelnitiator));
            Assert(0);
            break;
		case L2EVENT_MOVE_CHANNEL_REQ:
/*
			info->ptrs.moveChannelReq;
*/
			amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId);
			break;
		case L2EVENT_MOVE_CHANNEL_RSP:
			amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId);
/*
			info->ptrs.moveChannelRsp.result;
*/

			break;
		case L2EVENT_MOVE_CHANNEL_CNF_REQ:
			amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId);
/*
			info->ptrs.moveChannelCnfReq.result;
*/
			break;
		case L2EVENT_MOVE_CHANNEL_CNF_RSP:
			amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId);
			break;
    }
}