/******************************************************************************* NAME sinkUpgradeMsgHandler DESCRIPTION Handle messages specific to the Upgrade library. PARAMETERS task The task the message is delivered id The ID for the Upgrade message payload The message payload RETURNS void */ void sinkUpgradeMsgHandler(Task task, MessageId id, Message message) { switch (id) { case MESSAGE_DFU_SQIF_STATUS: { MessageDFUFromSQifStatus *msg = (MessageDFUFromSQifStatus *)message; UPGRADE_INFO(("MESSAGE_DFU_SQIF_STATUS: %u\n", msg->status)); UpgradeDfuStatus(msg); } break; case UPGRADE_APPLY_IND: { UPGRADE_INFO(("UPGRADE_APPLY_IND:\n")); UpgradeApplyResponse(NOW); } break; case UPGRADE_BLOCKING_IND: { UPGRADE_INFO(("UPGRADE_BLOCKING_IND:\n")); if(IsTonePlaying() || IsVpPlaying()) { UpgradeBlockingResponse(100); } else { VolumeUpdateMuteStatusAllOutputs(TRUE); UpgradeBlockingResponse(NOW); } } break; case UPGRADE_BLOCKING_IS_DONE_IND: { UPGRADE_INFO(("UPGRADE_BLOCKING_IS_DONE_IND:\n")); VolumeUpdateMuteStatusAllOutputs(FALSE); } break; case UPGRADE_INIT_CFM: { UPGRADE_INFO(("UPGRADE_INIT_CFM: status %u\n", ((UPGRADE_INIT_CFM_T *)message)->status)); } break; case UPGRADE_RESTARTED_IND: { UPGRADE_RESTARTED_IND_T *ind = (UPGRADE_RESTARTED_IND_T *)message; UPGRADE_INFO(("UPGRADE_RESTARTED_IND: reason %u\n", ind->reason)); if (theSink.SinkInitialising) { /* if not in a state to be able to power on yet, re-send this message with a delay. */ MESSAGE_MAKE(restarted, UPGRADE_RESTARTED_IND_T); restarted->reason = ind->reason; UPGRADE_INFO((" sink not initialised; delaying\n")); MessageSendLater(task, UPGRADE_RESTARTED_IND, restarted, UPGRADE_RESTARTED_DELAY); } else { /* The upgrade library is letting the application know that a restart of some sort has occurred. The reason indicates how important it is to make ourselves connectable. For our purposes we use any indication of an upgrade being in progress to send ourselves a power on event. */ if (ind->reason != upgrade_reconnect_not_required) { gaia_transport_type transport_type; transport_type = (gaia_transport_type)configManagerGetUpgradeTransportType(); UPGRADE_INFO(("transport type used some time ago was 0x%x\n", transport_type)); if ((transport_type == gaia_transport_spp) || (transport_type == gaia_transport_rfcomm)) { UPGRADE_INFO(("sending EventUsrPowerOn\n")); MessageSend(&theSink.task, EventUsrPowerOn, NULL); } else if (transport_type == gaia_transport_gatt) { /* Sink app starts in central mode but for upgrade we need it to be in peripheral mode so the host can connect. */ UPGRADE_INFO(("sending EventUsrBleSwitchPeripheral\n")); MessageSend(&theSink.task, EventUsrBleSwitchPeripheral, NULL); } else { UPGRADE_INFO(("sending nothing\n")); } } } } break; default: UPGRADE_INFO(("Unhandled 0x%04X\n", id)); break; } }
/**************************************************************************** NAME linkPolicyUseA2dpSettings DESCRIPTION set the link policy requirements based on current device audio state RETURNS void */ void linkPolicyUseA2dpSettings(uint16 DeviceId, uint16 StreamId, Sink sink ) { Sink sinkAG1,sinkAG2 = NULL; bool faster_poll = FALSE; /* obtain any sco sinks */ HfpLinkGetAudioSink(hfp_primary_link, &sinkAG1); HfpLinkGetAudioSink(hfp_secondary_link, &sinkAG2); /* determine if the connection is currently streaming and there are no scos currently open */ if ((!sinkAG1 && !sinkAG2) && (A2dpMediaGetState(DeviceId, StreamId) == a2dp_stream_streaming)) { /* is there a user power table available from ps ? */ if((theSink.user_power_table) && (theSink.user_power_table->A2DPStreamEntries)) { LP_DEBUG(("LP: SetLinkP - A2dp user table \n")) /* User supplied power table for A2DP role */ ConnectionSetLinkPolicy(sink, theSink.user_power_table->A2DPStreamEntries , &theSink.user_power_table->powertable[ theSink.user_power_table->normalEntries + theSink.user_power_table->SCOEntries ] ); } /* no user power table so use default A2DP table */ else { if (A2dpMediaGetRole(DeviceId, StreamId) == a2dp_source) { LP_DEBUG(("LP: SetLinkP - A2dp default source table \n" )); ConnectionSetLinkPolicy(sink, 1 ,lp_powertable_a2dp_stream_source); faster_poll = TRUE; } else { LP_DEBUG(("LP: SetLinkP - A2dp default sink table \n" )); ConnectionSetLinkPolicy(sink, 1 ,lp_powertable_a2dp_stream_sink); } } } /* if not streaming a2dp check for the prescence of sco data and if none found go to normal settings */ else if ((!sinkAG1 && !sinkAG2) && (A2dpMediaGetState(DeviceId, StreamId) != a2dp_stream_streaming)) { uint16 priority; if (getA2dpIndex(DeviceId, &priority) && (theSink.a2dp_link_data->peer_device[priority] == remote_device_peer)) { LP_DEBUG(("LP: SetLinkP - a2dp default table \n" )); ConnectionSetLinkPolicy(sink, 2 ,lp_powertable_a2dp_default); } else { /* set normal link policy settings */ linkPolicyUseDefaultSettings(sink); } } #ifdef ENABLE_PEER { /* Set a reasonable poll interval for the relay link to help if we ever get into a */ /* scatternet situation due to an AV SRC refusing to be slave. */ typed_bdaddr tbdaddr; if (A2dpDeviceGetBdaddr(DeviceId, &tbdaddr.addr)) { MESSAGE_MAKE(prim, DM_HCI_QOS_SETUP_REQ_T); prim->common.op_code = DM_HCI_QOS_SETUP_REQ; prim->common.length = sizeof(DM_HCI_QOS_SETUP_REQ_T); prim->bd_addr.lap = tbdaddr.addr.lap; prim->bd_addr.uap = tbdaddr.addr.uap; prim->bd_addr.nap = tbdaddr.addr.nap; /* latency is the only thing used in the request and sets the poll interval */ prim->service_type = HCI_QOS_GUARANTEED; prim->token_rate = 0xffffffff; prim->peak_bandwidth = 0x0000aaaa; prim->latency = faster_poll ? 10000 : 25000; prim->delay_variation = 0xffffffff; DEBUG(("LP: SetLinkP - Set QoS %lums\n",prim->latency)); VmSendDmPrim(prim); } /* Check connection role is suitable too */ linkPolicyGetRole(&sink); } #endif }