// Returns TRUE, to say we're connected and registers tspec with FQTSS tspec should be initialized bool openavbTLRunTalkerInit(tl_state_t *pTLState) { openavb_tl_cfg_t *pCfg = &pTLState->cfg; talker_data_t *pTalkerData = pTLState->pPvtTalkerData; //avtp_stream_t *pStream = (avtp_stream_t *)(pTalkerData->avtpHandle); strncpy(pTalkerData->ifname, pCfg->ifname, IFNAMSIZ); // CORE_TODO: It would be good to have some parts of endpoint moved into non-endpoint general code to handle some the stream // configuration values. // strncpy(pTalkerData->ifname, pCfg->ifname, IFNAMSIZ); if (pCfg->stream_addr.mac) { memcpy(pTalkerData->streamID.addr, pCfg->stream_addr.mac, ETH_ALEN); }else { AVB_LOG_WARNING("Stream Address Not Set"); } pTalkerData->streamID.uniqueID = pCfg->stream_uid; if (pCfg->sr_class == SR_CLASS_A) { pTalkerData->classRate = 8000; pTalkerData->vlanID = pCfg->vlan_id == VLAN_NULL ? SR_CLASS_A_DEFAULT_VID : pCfg->vlan_id; pTalkerData->vlanPCP = SR_CLASS_A_DEFAULT_PRIORITY; } else if (pCfg->sr_class == SR_CLASS_B) { pTalkerData->classRate = 4000; pTalkerData->vlanID = pCfg->vlan_id == VLAN_NULL ? SR_CLASS_B_DEFAULT_VID : pCfg->vlan_id; pTalkerData->vlanPCP = SR_CLASS_B_DEFAULT_PRIORITY; } memcpy(&pTalkerData->destAddr, &pCfg->dest_addr.mac->ether_addr_octet, ETH_ALEN); unsigned int maxBitrate = 0; if (pCfg->intf_cb.intf_get_src_bitrate_cb != NULL) { maxBitrate = pCfg->intf_cb.intf_get_src_bitrate_cb(pTLState->pMediaQ); } if (maxBitrate > 0) { if (pCfg->map_cb.map_set_src_bitrate_cb != NULL) { pCfg->map_cb.map_set_src_bitrate_cb(pTLState->pMediaQ, maxBitrate); } if (pCfg->map_cb.map_get_max_interval_frames_cb != NULL) { unsigned int map_intv_frames = pCfg->map_cb.map_get_max_interval_frames_cb(pTLState->pMediaQ, pTLState->cfg.sr_class); pCfg->max_interval_frames = map_intv_frames > 0 ? map_intv_frames : pCfg->max_interval_frames; } } pTalkerData->tSpec.maxIntervalFrames = pCfg->max_interval_frames; pTalkerData->tSpec.maxFrameSize = pCfg->map_cb.map_max_data_size_cb(pTLState->pMediaQ); // TODO_COREAVB : This wakeRate should also be set in the endpoint case and removed from the tasker.c start stream if (!pCfg->map_cb.map_transmit_interval_cb(pTLState->pMediaQ)) { pTalkerData->wakeRate = pTalkerData->classRate / pCfg->batch_factor; } else { // Override the class observation interval with the one provided by the mapping module. pTalkerData->wakeRate = pCfg->map_cb.map_transmit_interval_cb(pTLState->pMediaQ) / pCfg->batch_factor; } if_info_t ifinfo; openavbCheckInterface(pTalkerData->ifname, &ifinfo); pTalkerData->fwmark = openavbQmgrAddStream((SRClassIdx_t)pCfg->sr_class, pTalkerData->wakeRate, pTalkerData->tSpec.maxIntervalFrames, pTalkerData->tSpec.maxFrameSize); if (pTalkerData->fwmark == INVALID_FWMARK) return FALSE; AVB_LOGF_INFO("Dest Addr: "ETH_FORMAT, ETH_OCTETS(pTalkerData->destAddr)); AVB_LOGF_INFO("Starting stream: "STREAMID_FORMAT, STREAMID_ARGS(&pTalkerData->streamID)); talkerStartStream(pTLState); return TRUE; }
/* SRP tells us about a listener peer (Listener Ready or Failed) */ openavbRC strmAttachCb(void* pv, openavbSrpLsnrDeclSubtype_t lsnrDecl) { AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT); openavbRC rc = OPENAVB_FAILURE; clientStream_t *ps = (clientStream_t*)pv; AVB_LOGF_INFO("SRP talker callback uid=%d: lsnrDecl=%x", ps->streamID.uniqueID, lsnrDecl); if (lsnrDecl == openavbSrp_LDSt_Ready || lsnrDecl == openavbSrp_LDSt_Ready_Failed) { // Somebody is listening - get ready to stream if (ps->fwmark != INVALID_FWMARK) { AVB_LOG_DEBUG("attach callback: already setup queues"); rc = OPENAVB_SUCCESS; } else { AVB_LOG_DEBUG("Attach callback: setting up queues for streaming"); rc = openavbSrpGetClassParams(ps->srClass, &ps->priority, &ps->vlanID, &ps->classRate); if (IS_OPENAVB_SUCCESS(rc)) { ps->fwmark = openavbQmgrAddStream(ps->srClass, ps->classRate, ps->tSpec.maxIntervalFrames, ps->tSpec.maxFrameSize); if (ps->fwmark == INVALID_FWMARK) { AVB_LOG_ERROR("Error in attach callback: unable to setup stream queues"); rc = OPENAVB_FAILURE; } else { rc = OPENAVB_SUCCESS; } } else { AVB_LOG_ERROR("Error in attach callback: unable to get class params"); rc = OPENAVB_FAILURE; } } } else { // Nobody listening if (ps->fwmark != INVALID_FWMARK) { AVB_LOG_DEBUG("Attach callback: tearing down queues"); openavbQmgrRemoveStream(ps->fwmark); ps->fwmark = INVALID_FWMARK; } rc = OPENAVB_SUCCESS; } if (IS_OPENAVB_SUCCESS(rc)) { openavbEptSrvrNotifyTlkrOfSrpCb(ps->clientHandle, &ps->streamID, x_cfg.ifname, ps->destAddr, lsnrDecl, ps->srClass, ps->classRate, ps->vlanID, ps->priority, ps->fwmark); rc = OPENAVB_SUCCESS; } AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT); return rc; }