From 75a72f02a060cb78555f3419b40b6dbe3b5e0801 Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Mon, 8 Dec 2014 12:43:16 -0800 Subject: [PATCH 01/82] Bug 1107733. Integrate paint times into telemetry. r=mattwoodrow --- layout/base/nsLayoutUtils.cpp | 9 ++++++++- layout/base/nsRefreshDriver.cpp | 4 +++- toolkit/components/telemetry/Histograms.json | 21 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index f10e164032f..d0c368adb4b 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -93,6 +93,7 @@ #include "nsFrameSelection.h" #include "FrameLayerBuilder.h" #include "mozilla/layers/APZCTreeManager.h" +#include "mozilla/Telemetry.h" #ifdef MOZ_XUL #include "nsXULPopupManager.h" @@ -2892,6 +2893,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram return NS_OK; } + TimeStamp startBuildDisplayList = TimeStamp::Now(); nsDisplayListBuilder builder(aFrame, nsDisplayListBuilder::PAINTING, !(aFlags & PAINT_HIDE_CARET)); @@ -2911,7 +2913,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram if (aFlags & PAINT_WIDGET_LAYERS) { // This layer tree will be reused, so we'll need to calculate it // for the whole "visible" area of the window - // + // // |ignoreViewportScrolling| and |usingDisplayPort| are persistent // document-rendering state. We rely on PresShell to flush // retained layers as needed when that persistent state changes. @@ -3066,6 +3068,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram } builder.LeavePresShell(aFrame); + Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_DISPLAYLIST_TIME, + startBuildDisplayList); if (builder.GetHadToIgnorePaintSuppression()) { willFlushRetainedLayers = true; @@ -3132,8 +3136,11 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram flags |= nsDisplayList::PAINT_COMPRESSED; } + TimeStamp paintStart = TimeStamp::Now(); nsRefPtr layerManager = list.PaintRoot(&builder, aRenderingContext, flags); + Telemetry::AccumulateTimeDelta(Telemetry::PAINT_RASTERIZE_TIME, + paintStart); #ifdef MOZ_DUMP_PAINTING if (gfxUtils::DumpPaintList() || gfxUtils::sDumpPainting) { diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 494054b254d..70d202e36a2 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -1180,7 +1180,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) while (etor.HasMore()) { nsRefPtr obs = etor.GetNext(); obs->WillRefresh(aNowTime); - + if (!mPresContext || !mPresContext->GetPresShell()) { StopTimer(); return; @@ -1386,6 +1386,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) } } + mozilla::Telemetry::AccumulateTimeDelta(mozilla::Telemetry::REFRESH_DRIVER_TICK, mTickStart); + for (uint32_t i = 0; i < mPostRefreshObservers.Length(); ++i) { mPostRefreshObservers[i]->DidRefresh(); } diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 28ffc944d0e..b82564909b8 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -2168,6 +2168,27 @@ "n_buckets": 20, "description": "The number of unusable addresses reported for each record" }, + "REFRESH_DRIVER_TICK" : { + "expires_in_version": "never", + "description": "Total time spent ticking the refresh driver in milliseconds", + "kind": "exponential", + "high": "1000", + "n_buckets": 50 + }, + "PAINT_BUILD_DISPLAYLIST_TIME" : { + "expires_in_version": "never", + "description": "Time spent in building displaylists in milliseconds", + "kind": "exponential", + "high": "1000", + "n_buckets": 50 + }, + "PAINT_RASTERIZE_TIME" : { + "expires_in_version": "never", + "description": "Time spent rasterizing each frame in milliseconds", + "kind": "exponential", + "high": "1000", + "n_buckets": 50 + }, "PREDICTOR_PREDICT_ATTEMPTS": { "expires_in_version": "never", "kind": "exponential", From 86d650039c010c6e7c7206b414950ece7da33e57 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Fri, 5 Dec 2014 15:58:00 -0800 Subject: [PATCH 02/82] Bug 1102048 - Make image/src files comply with the Mozilla Coding Style Guide. r=seth --- image/src/Orientation.h | 3 ++- image/src/OrientedImage.cpp | 20 +++++++++++------- image/src/OrientedImage.h | 5 +++-- image/src/ProgressTracker.cpp | 39 +++++++++++++++++++++++------------ image/src/ProgressTracker.h | 8 +++---- 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/image/src/Orientation.h b/image/src/Orientation.h index 1a395220c0d..ce1b27edd35 100644 --- a/image/src/Orientation.h +++ b/image/src/Orientation.h @@ -31,7 +31,8 @@ MOZ_END_ENUM_CLASS(Flip) */ struct Orientation { - explicit Orientation(Angle aRotation = Angle::D0, Flip mFlip = Flip::Unflipped) + explicit Orientation(Angle aRotation = Angle::D0, + Flip mFlip = Flip::Unflipped) : rotation(aRotation) , flip(mFlip) { } diff --git a/image/src/OrientedImage.cpp b/image/src/OrientedImage.cpp index 70ec7cb4546..958a03df378 100644 --- a/image/src/OrientedImage.cpp +++ b/image/src/OrientedImage.cpp @@ -141,12 +141,13 @@ OrientedImage::GetFrame(uint32_t aWhichFrame, gfxUtils::DrawPixelSnapped(ctx, drawable, size, ImageRegion::Create(size), surfaceFormat, GraphicsFilter::FILTER_FAST); - + return target->Snapshot(); } NS_IMETHODIMP -OrientedImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval) +OrientedImage::GetImageContainer(LayerManager* aManager, + ImageContainer** _retval) { // XXX(seth): We currently don't have a way of orienting the result of // GetImageContainer. We work around this by always returning null, but if it @@ -168,7 +169,8 @@ struct MatrixBuilder gfxMatrix Build() { return mMatrix; } - void Scale(gfxFloat aX, gfxFloat aY) { + void Scale(gfxFloat aX, gfxFloat aY) + { if (mInvert) { mMatrix *= gfxMatrix::Scaling(1.0 / aX, 1.0 / aY); } else { @@ -176,7 +178,8 @@ struct MatrixBuilder } } - void Rotate(gfxFloat aPhi) { + void Rotate(gfxFloat aPhi) + { if (mInvert) { mMatrix *= gfxMatrix::Rotation(-aPhi); } else { @@ -184,7 +187,8 @@ struct MatrixBuilder } } - void Translate(gfxPoint aDelta) { + void Translate(gfxPoint aDelta) + { if (mInvert) { mMatrix *= gfxMatrix::Translation(-aDelta); } else { @@ -310,11 +314,13 @@ OrientedImage::Draw(gfxContext* aContext, } nsIntSize -OrientedImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, +OrientedImage::OptimalImageSizeForDest(const gfxSize& aDest, + uint32_t aWhichFrame, GraphicsFilter aFilter, uint32_t aFlags) { if (!mOrientation.SwapsWidthAndHeight()) { - return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, aFlags); + return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, + aFlags); } // Swap the size for the calculation, then swap it back for the caller. diff --git a/image/src/OrientedImage.h b/image/src/OrientedImage.h index 128d5002d88..afd01389f64 100644 --- a/image/src/OrientedImage.h +++ b/image/src/OrientedImage.h @@ -45,12 +45,13 @@ public: GraphicsFilter aFilter, const Maybe& aSVGContext, uint32_t aFlags) MOZ_OVERRIDE; - NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect(const nsIntRect& aRect) MOZ_OVERRIDE; + NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect( + const nsIntRect& aRect) MOZ_OVERRIDE; nsIntSize OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, GraphicsFilter aFilter, uint32_t aFlags) MOZ_OVERRIDE; - + protected: OrientedImage(Image* aImage, Orientation aOrientation) : ImageWrapper(aImage) diff --git a/image/src/ProgressTracker.cpp b/image/src/ProgressTracker.cpp index d3a2df2f508..98da285f6df 100644 --- a/image/src/ProgressTracker.cpp +++ b/image/src/ProgressTracker.cpp @@ -107,7 +107,8 @@ ProgressTracker::ResetImage() mImage = nullptr; } -void ProgressTracker::SetIsMultipart() +void +ProgressTracker::SetIsMultipart() { if (mProgress & FLAG_IS_MULTIPART) { return; @@ -218,9 +219,11 @@ ProgressTracker::Notify(imgRequestProxy* proxy) nsRefPtr uri(mImage->GetURI()); nsAutoCString spec; uri->GetSpec(spec); - LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::Notify async", "uri", spec.get()); + LOG_FUNC_WITH_PARAM(GetImgLog(), + "ProgressTracker::Notify async", "uri", spec.get()); } else { - LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::Notify async", "uri", ""); + LOG_FUNC_WITH_PARAM(GetImgLog(), + "ProgressTracker::Notify async", "uri", ""); } #endif @@ -283,7 +286,8 @@ ProgressTracker::NotifyCurrentState(imgRequestProxy* proxy) proxy->GetURI(getter_AddRefs(uri)); nsAutoCString spec; uri->GetSpec(spec); - LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::NotifyCurrentState", "uri", spec.get()); + LOG_FUNC_WITH_PARAM(GetImgLog(), + "ProgressTracker::NotifyCurrentState", "uri", spec.get()); #endif proxy->SetNotificationsDeferred(true); @@ -311,31 +315,38 @@ ProgressTracker::SyncNotifyInternal(ProxyArray& aProxies, { MOZ_ASSERT(NS_IsMainThread()); - if (aProgress & FLAG_SIZE_AVAILABLE) + if (aProgress & FLAG_SIZE_AVAILABLE) { NOTIFY_IMAGE_OBSERVERS(aProxies, OnSizeAvailable()); + } - if (aProgress & FLAG_DECODE_STARTED) + if (aProgress & FLAG_DECODE_STARTED) { NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartDecode()); + } - if (aProgress & FLAG_ONLOAD_BLOCKED) + if (aProgress & FLAG_ONLOAD_BLOCKED) { NOTIFY_IMAGE_OBSERVERS(aProxies, BlockOnload()); + } if (aHasImage) { // OnFrameUpdate // If there's any content in this frame at all (always true for // vector images, true for raster images that have decoded at // least one frame) then send OnFrameUpdate. - if (!aDirtyRect.IsEmpty()) + if (!aDirtyRect.IsEmpty()) { NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameUpdate(&aDirtyRect)); + } - if (aProgress & FLAG_FRAME_COMPLETE) + if (aProgress & FLAG_FRAME_COMPLETE) { NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameComplete()); + } - if (aProgress & FLAG_HAS_TRANSPARENCY) + if (aProgress & FLAG_HAS_TRANSPARENCY) { NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageHasTransparency()); + } - if (aProgress & FLAG_IS_ANIMATED) + if (aProgress & FLAG_IS_ANIMATED) { NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageIsAnimated()); + } } // Send UnblockOnload before OnStopDecode and OnStopRequest. This allows @@ -358,7 +369,8 @@ ProgressTracker::SyncNotifyInternal(ProxyArray& aProxies, void ProgressTracker::SyncNotifyProgress(Progress aProgress, - const nsIntRect& aInvalidRect /* = nsIntRect() */) + const nsIntRect& aInvalidRect + /* = nsIntRect() */) { MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only"); @@ -390,7 +402,8 @@ ProgressTracker::SyncNotify(imgRequestProxy* proxy) proxy->GetURI(getter_AddRefs(uri)); nsAutoCString spec; uri->GetSpec(spec); - LOG_SCOPE_WITH_PARAM(GetImgLog(), "ProgressTracker::SyncNotify", "uri", spec.get()); + LOG_SCOPE_WITH_PARAM(GetImgLog(), + "ProgressTracker::SyncNotify", "uri", spec.get()); #endif nsIntRect r; diff --git a/image/src/ProgressTracker.h b/image/src/ProgressTracker.h index 9a90ef1cd32..02cbab401ba 100644 --- a/image/src/ProgressTracker.h +++ b/image/src/ProgressTracker.h @@ -103,7 +103,7 @@ public: // Get the current Progress. Progress GetProgress() const { return mProgress; } - + // Schedule an asynchronous "replaying" of all the notifications that would // have to happen to put us in the current state. // We will also take note of any notifications that happen between the time @@ -164,9 +164,9 @@ public: return mConsumers.Length(); } - // This is intentionally non-general because its sole purpose is to support an - // some obscure network priority logic in imgRequest. That stuff could probably - // be improved, but it's too scary to mess with at the moment. + // This is intentionally non-general because its sole purpose is to support + // some obscure network priority logic in imgRequest. That stuff could + // probably be improved, but it's too scary to mess with at the moment. bool FirstConsumerIs(imgRequestProxy* aConsumer); void AdoptConsumers(ProgressTracker* aTracker) { From e817eb8c413286985340df1af12e70fe48a738ac Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Fri, 5 Dec 2014 16:28:00 -0800 Subject: [PATCH 03/82] Bug 1102048 - Make image/src files comply with the Mozilla Coding Style Guide. r=seth --- image/src/DynamicImage.cpp | 7 +++++-- image/src/DynamicImage.h | 5 ++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/image/src/DynamicImage.cpp b/image/src/DynamicImage.cpp index cddf7232b5b..b71d8b1f279 100644 --- a/image/src/DynamicImage.cpp +++ b/image/src/DynamicImage.cpp @@ -216,7 +216,8 @@ DynamicImage::IsOpaque() } NS_IMETHODIMP -DynamicImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval) +DynamicImage::GetImageContainer(LayerManager* aManager, + ImageContainer** _retval) { *_retval = nullptr; return NS_OK; @@ -331,7 +332,9 @@ DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp& aTime) { } nsIntSize -DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, GraphicsFilter aFilter, uint32_t aFlags) +DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest, + uint32_t aWhichFrame, + GraphicsFilter aFilter, uint32_t aFlags) { gfxIntSize size(mDrawable->Size()); return nsIntSize(size.width, size.height); diff --git a/image/src/DynamicImage.h b/image/src/DynamicImage.h index 3238478b5d8..db49bb270b8 100644 --- a/image/src/DynamicImage.h +++ b/image/src/DynamicImage.h @@ -14,7 +14,6 @@ namespace mozilla { namespace image { /** - * An Image that is dynamically created. The content of the image is provided by * a gfxDrawable. It's anticipated that most uses of DynamicImage will be * ephemeral. @@ -36,8 +35,8 @@ public: virtual already_AddRefed GetProgressTracker() MOZ_OVERRIDE; virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE; - - virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; + virtual size_t SizeOfSourceWithComputedFallback( + MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; From 769737166dfb132c8bd1ad703393dbf27676298d Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Fri, 5 Dec 2014 16:35:00 -0800 Subject: [PATCH 04/82] Bug 1102048 - Make image/src files comply with the Mozilla Coding Style Guide. r=seth --- image/src/ImageFactory.cpp | 38 +++++++++++++++++++++++--------------- image/src/ImageFactory.h | 29 ++++++++++++++++------------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/image/src/ImageFactory.cpp b/image/src/ImageFactory.cpp index 328c6b06bda..9d524cf070d 100644 --- a/image/src/ImageFactory.cpp +++ b/image/src/ImageFactory.cpp @@ -29,8 +29,7 @@ namespace image { /*static*/ void ImageFactory::Initialize() -{ -} +{ } static uint32_t ComputeImageFlags(ImageURL* uri, bool isMultiPart) @@ -41,33 +40,39 @@ ComputeImageFlags(ImageURL* uri, bool isMultiPart) bool isDiscardable = gfxPrefs::ImageMemDiscardable(); bool doDecodeOnDraw = gfxPrefs::ImageMemDecodeOnDraw(); - // We want UI to be as snappy as possible and not to flicker. Disable discarding - // and decode-on-draw for chrome URLS. + // We want UI to be as snappy as possible and not to flicker. Disable + // discarding and decode-on-draw for chrome URLS. bool isChrome = false; rv = uri->SchemeIs("chrome", &isChrome); - if (NS_SUCCEEDED(rv) && isChrome) + if (NS_SUCCEEDED(rv) && isChrome) { isDiscardable = doDecodeOnDraw = false; + } // We don't want resources like the "loading" icon to be discardable or // decode-on-draw either. bool isResource = false; rv = uri->SchemeIs("resource", &isResource); - if (NS_SUCCEEDED(rv) && isResource) + if (NS_SUCCEEDED(rv) && isResource) { isDiscardable = doDecodeOnDraw = false; + } // For multipart/x-mixed-replace, we basically want a direct channel to the // decoder. Disable both for this case as well. - if (isMultiPart) + if (isMultiPart) { isDiscardable = doDecodeOnDraw = false; + } // We have all the information we need. uint32_t imageFlags = Image::INIT_FLAG_NONE; - if (isDiscardable) + if (isDiscardable) { imageFlags |= Image::INIT_FLAG_DISCARDABLE; - if (doDecodeOnDraw) + } + if (doDecodeOnDraw) { imageFlags |= Image::INIT_FLAG_DECODE_ON_DRAW; - if (isMultiPart) + } + if (isMultiPart) { imageFlags |= Image::INIT_FLAG_MULTIPART; + } return imageFlags; } @@ -145,10 +150,12 @@ ImageFactory::CreateAnonymousImage(const nsCString& aMimeType) int32_t SaturateToInt32(int64_t val) { - if (val > INT_MAX) + if (val > INT_MAX) { return INT_MAX; - if (val < INT_MIN) + } + if (val < INT_MIN) { return INT_MIN; + } return static_cast(val); } @@ -205,7 +212,8 @@ ImageFactory::CreateRasterImage(nsIRequest* aRequest, // Pass anything usable on so that the RasterImage can preallocate // its source buffer. if (len > 0) { - uint32_t sizeHint = std::min(len, 20000000); // Bound by something reasonable + // Bound by something reasonable + uint32_t sizeHint = std::min(len, 20000000); rv = newImage->SetSourceSizeHint(sizeHint); if (NS_FAILED(rv)) { // Flush memory, try to get some back, and try again. @@ -230,8 +238,8 @@ ImageFactory::CreateRasterImage(nsIRequest* aRequest, nsCOMPtr chan(do_QueryInterface(aRequest)); nsCOMPtr principal; if (chan) { - nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(chan, - getter_AddRefs(principal)); + nsContentUtils::GetSecurityManager() + ->GetChannelResultPrincipal(chan, getter_AddRefs(principal)); } if ((principal && diff --git a/image/src/ImageFactory.h b/image/src/ImageFactory.h index c440c90462f..895fa2aa692 100644 --- a/image/src/ImageFactory.h +++ b/image/src/ImageFactory.h @@ -59,23 +59,26 @@ public: * * @param aMimeType The mimetype of the image. */ - static already_AddRefed CreateAnonymousImage(const nsCString& aMimeType); + static already_AddRefed + CreateAnonymousImage(const nsCString& aMimeType); private: // Factory functions that create specific types of image containers. - static already_AddRefed CreateRasterImage(nsIRequest* aRequest, - ProgressTracker* aProgressTracker, - const nsCString& aMimeType, - ImageURL* aURI, - uint32_t aImageFlags, - uint32_t aInnerWindowId); + static already_AddRefed + CreateRasterImage(nsIRequest* aRequest, + ProgressTracker* aProgressTracker, + const nsCString& aMimeType, + ImageURL* aURI, + uint32_t aImageFlags, + uint32_t aInnerWindowId); - static already_AddRefed CreateVectorImage(nsIRequest* aRequest, - ProgressTracker* aProgressTracker, - const nsCString& aMimeType, - ImageURL* aURI, - uint32_t aImageFlags, - uint32_t aInnerWindowId); + static already_AddRefed + CreateVectorImage(nsIRequest* aRequest, + ProgressTracker* aProgressTracker, + const nsCString& aMimeType, + ImageURL* aURI, + uint32_t aImageFlags, + uint32_t aInnerWindowId); // This is a static factory class, so disallow instantiation. virtual ~ImageFactory() = 0; From 8f980a0f12da2e8b9d338a09fa7704b1119588d0 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Fri, 5 Dec 2014 17:17:00 -0800 Subject: [PATCH 05/82] Bug 1102048 - Make image/src files comply with the Mozilla Coding Style Guide. r=seth --- image/src/FrameBlender.cpp | 83 ++++++++++++++++++++++---------------- image/src/FrameBlender.h | 32 ++++++++------- 2 files changed, 65 insertions(+), 50 deletions(-) diff --git a/image/src/FrameBlender.cpp b/image/src/FrameBlender.cpp index a43f05716cc..5c16c9ab7c2 100644 --- a/image/src/FrameBlender.cpp +++ b/image/src/FrameBlender.cpp @@ -66,9 +66,9 @@ FrameBlender::GetTimeoutForFrame(uint32_t aFrameNum) const int32_t timeout = frame->GetRawTimeout(); // Ensure a minimal time between updates so we don't throttle the UI thread. - // consider 0 == unspecified and make it fast but not too fast. Unless we have - // a single loop GIF. See bug 890743, bug 125137, bug 139677, and bug 207059. - // The behavior of recent IE and Opera versions seems to be: + // consider 0 == unspecified and make it fast but not too fast. Unless we + // have a single loop GIF. See bug 890743, bug 125137, bug 139677, and bug + // 207059. The behavior of recent IE and Opera versions seems to be: // IE 6/Win: // 10 - 50ms go 100ms // >50ms go correct speed @@ -258,8 +258,10 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect, } else { if ((prevFrameRect.x >= nextFrameRect.x) && (prevFrameRect.y >= nextFrameRect.y) && - (prevFrameRect.x + prevFrameRect.width <= nextFrameRect.x + nextFrameRect.width) && - (prevFrameRect.y + prevFrameRect.height <= nextFrameRect.y + nextFrameRect.height)) { + (prevFrameRect.x + prevFrameRect.width <= + nextFrameRect.x + nextFrameRect.width) && + (prevFrameRect.y + prevFrameRect.height <= + nextFrameRect.y + nextFrameRect.height)) { // Optimization: No need to dispose prev.frame when // next frame fully overlaps previous frame. doDisposal = false; @@ -299,8 +301,10 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect, mAnim->compositingFrame->GetRect()); // destroy only if we don't need it for this frame's disposal - if (nextFrameDisposalMethod != FrameBlender::kDisposeRestorePrevious) + if (nextFrameDisposalMethod != + FrameBlender::kDisposeRestorePrevious) { mAnim->compositingPrevFrame.reset(); + } } else { ClearFrame(mAnim->compositingFrame->GetRawData(), mAnim->compositingFrame->GetRect()); @@ -308,12 +312,13 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect, break; default: - // Copy previous frame into compositingFrame before we put the new frame on top + // Copy previous frame into compositingFrame before we put the new + // frame on top // Assumes that the previous frame represents a full frame (it could be - // smaller in size than the container, as long as the frame before it erased - // itself) - // Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1) will - // always be a valid frame number. + // smaller in size than the container, as long as the frame before it + // erased itself) + // Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1) + // will always be a valid frame number. if (mAnim->lastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) { if (isFullPrevFrame && !prevFrame->GetIsPaletted()) { // Just copy the bits @@ -339,13 +344,13 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect, } } } else if (needToBlankComposite) { - // If we just created the composite, it could have anything in it's + // If we just created the composite, it could have anything in its // buffers. Clear them ClearFrame(mAnim->compositingFrame->GetRawData(), mAnim->compositingFrame->GetRect()); } - // Check if the frame we are composing wants the previous image restored afer + // Check if the frame we are composing wants the previous image restored after // it is done. Don't store it (again) if last frame wanted its image restored // too if ((nextFrameDisposalMethod == FrameBlender::kDisposeRestorePrevious) && @@ -400,15 +405,17 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect, void FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect) { - if (!aFrameData) + if (!aFrameData) { return; + } memset(aFrameData, 0, aFrameRect.width * aFrameRect.height * 4); } //****************************************************************************** void -FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect& aRectToClear) +FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, + const nsIntRect& aRectToClear) { if (!aFrameData || aFrameRect.width <= 0 || aFrameRect.height <= 0 || aRectToClear.width <= 0 || aRectToClear.height <= 0) { @@ -422,7 +429,8 @@ FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const uint32_t bytesPerRow = aFrameRect.width * 4; for (int row = toClear.y; row < toClear.y + toClear.height; ++row) { - memset(aFrameData + toClear.x * 4 + row * bytesPerRow, 0, toClear.width * 4); + memset(aFrameData + toClear.x * 4 + row * bytesPerRow, 0, + toClear.width * 4); } } @@ -430,8 +438,8 @@ FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const // Whether we succeed or fail will not cause a crash, and there's not much // we can do about a failure, so there we don't return a nsresult bool -FrameBlender::CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc, - uint8_t *aDataDest, const nsIntRect& aRectDest) +FrameBlender::CopyFrameImage(const uint8_t* aDataSrc, const nsIntRect& aRectSrc, + uint8_t* aDataDest, const nsIntRect& aRectDest) { uint32_t dataLengthSrc = aRectSrc.width * aRectSrc.height * 4; uint32_t dataLengthDest = aRectDest.width * aRectDest.height * 4; @@ -446,9 +454,9 @@ FrameBlender::CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc, } nsresult -FrameBlender::DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect, +FrameBlender::DrawFrameTo(const uint8_t* aSrcData, const nsIntRect& aSrcRect, uint32_t aSrcPaletteLength, bool aSrcHasAlpha, - uint8_t *aDstPixels, const nsIntRect& aDstRect, + uint8_t* aDstPixels, const nsIntRect& aDstRect, FrameBlender::FrameBlendMethod aBlendMethod) { NS_ENSURE_ARG_POINTER(aSrcData); @@ -480,9 +488,9 @@ FrameBlender::DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect, "FrameBlender::DrawFrameTo: source must be smaller than dest"); // Get pointers to image data - const uint8_t *srcPixels = aSrcData + aSrcPaletteLength; - uint32_t *dstPixels = reinterpret_cast(aDstPixels); - const uint32_t *colormap = reinterpret_cast(aSrcData); + const uint8_t* srcPixels = aSrcData + aSrcPaletteLength; + uint32_t* dstPixels = reinterpret_cast(aDstPixels); + const uint32_t* colormap = reinterpret_cast(aSrcData); // Skip to the right offset dstPixels += aSrcRect.x + (aSrcRect.y * aDstRect.width); @@ -499,8 +507,9 @@ FrameBlender::DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect, for (int32_t r = height; r > 0; --r) { for (int32_t c = 0; c < width; c++) { const uint32_t color = colormap[srcPixels[c]]; - if (color) + if (color) { dstPixels[c] = color; + } } // Go to the next row in the source resp. destination image srcPixels += aSrcRect.width; @@ -508,18 +517,22 @@ FrameBlender::DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect, } } } else { - pixman_image_t* src = pixman_image_create_bits(aSrcHasAlpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, - aSrcRect.width, - aSrcRect.height, - reinterpret_cast(const_cast(aSrcData)), - aSrcRect.width * 4); - pixman_image_t* dst = pixman_image_create_bits(PIXMAN_a8r8g8b8, - aDstRect.width, - aDstRect.height, - reinterpret_cast(aDstPixels), - aDstRect.width * 4); + pixman_image_t* src = + pixman_image_create_bits( + aSrcHasAlpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, + aSrcRect.width, aSrcRect.height, + reinterpret_cast(const_cast(aSrcData)), + aSrcRect.width * 4); + pixman_image_t* dst = + pixman_image_create_bits(PIXMAN_a8r8g8b8, + aDstRect.width, + aDstRect.height, + reinterpret_cast(aDstPixels), + aDstRect.width * 4); - pixman_image_composite32(aBlendMethod == FrameBlender::kBlendSource ? PIXMAN_OP_SRC : PIXMAN_OP_OVER, + auto op = aBlendMethod == FrameBlender::kBlendSource ? PIXMAN_OP_SRC + : PIXMAN_OP_OVER; + pixman_image_composite32(op, src, nullptr, dst, diff --git a/image/src/FrameBlender.h b/image/src/FrameBlender.h index 35b7260e66d..1cf48744be1 100644 --- a/image/src/FrameBlender.h +++ b/image/src/FrameBlender.h @@ -55,9 +55,10 @@ public: uint32_t GetNumFrames() const; /* - * Returns the frame's adjusted timeout. If the animation loops and the timeout - * falls in between a certain range then the timeout is adjusted so that - * it's never 0. If the animation does not loop then no adjustments are made. + * Returns the frame's adjusted timeout. If the animation loops and the + * timeout falls in between a certain range then the timeout is adjusted so + * that it's never 0. If the animation does not loop then no adjustments are + * made. */ int32_t GetTimeoutForFrame(uint32_t aFrameNum); @@ -130,9 +131,7 @@ private: */ RawAccessFrameRef compositingPrevFrame; - Anim() : - lastCompositedFrameIndex(-1) - {} + Anim() : lastCompositedFrameIndex(-1) { } }; /** Clears an area of with transparent black. @@ -140,19 +139,20 @@ private: * @param aFrameData Target Frame data * @param aFrameRect The rectangle of the data pointed ot by aFrameData * - * @note Does also clears the transparancy mask + * @note Does also clears the transparency mask */ static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect); //! @overload - static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect &aRectToClear); + static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, + const nsIntRect& aRectToClear); - //! Copy one frames's image and mask into another - static bool CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc, - uint8_t *aDataDest, const nsIntRect& aRectDest); + //! Copy one frame's image and mask into another + static bool CopyFrameImage(const uint8_t* aDataSrc, const nsIntRect& aRectSrc, + uint8_t* aDataDest, const nsIntRect& aRectDest); /** - * Draws one frames's image to into another, at the position specified by + * Draws one frame's image to into another, at the position specified by * aSrcRect. * * @aSrcData the raw data of the current frame being drawn @@ -164,11 +164,13 @@ private: * @aDstPixels the raw data of the composition frame where the current frame * is drawn into (32-bit ARGB) * @aDstRect the size of the composition frame - * @aBlendMethod the blend method for how to blend src on the composition frame. + * @aBlendMethod the blend method for how to blend src on the composition + * frame. */ - static nsresult DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect, + static nsresult DrawFrameTo(const uint8_t* aSrcData, + const nsIntRect& aSrcRect, uint32_t aSrcPaletteLength, bool aSrcHasAlpha, - uint8_t *aDstPixels, const nsIntRect& aDstRect, + uint8_t* aDstPixels, const nsIntRect& aDstRect, FrameBlendMethod aBlendMethod); private: // data From 509a9cac63135d747e1f8b3685506a92e8b30317 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 8 Dec 2014 13:39:55 -0800 Subject: [PATCH 06/82] Bug 1103813 - Debugger.prototype.findObjects should only find objects in the debuggee compartments. r=shu --- js/src/jit-test/tests/debug/bug-1103813.js | 6 ++++++ js/src/vm/Debugger.cpp | 2 +- js/src/vm/Debugger.h | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 js/src/jit-test/tests/debug/bug-1103813.js diff --git a/js/src/jit-test/tests/debug/bug-1103813.js b/js/src/jit-test/tests/debug/bug-1103813.js new file mode 100644 index 00000000000..07d7fe1f572 --- /dev/null +++ b/js/src/jit-test/tests/debug/bug-1103813.js @@ -0,0 +1,6 @@ +// Random chosen test: js/src/jit-test/tests/debug/Source-invisible.js +newGlobal({ + invisibleToDebugger: true +}) +// Random chosen test: js/src/jit-test/tests/debug/Debugger-findObjects-05.js +x = (new Debugger).findObjects() diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index ff76ca27bec..6b3ed5f769c 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -3605,7 +3605,7 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery */ for (Traversal::NodeMap::Range r = traversal.visited.all(); !r.empty(); r.popFront()) { JS::ubi::Node node = r.front().key(); - if (!node.is()) + if (!node.is() || !dbg->isDebuggee(node.compartment())) continue; JSObject *obj = node.as(); diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index 7748fa0b824..138b5192a74 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -232,6 +232,13 @@ class Debugger : private mozilla::LinkedListElement Observing = 1 }; + // Return true if the given compartment is a debuggee of this debugger, + // false otherwise. + bool isDebuggee(const JSCompartment *compartment) const { + MOZ_ASSERT(compartment); + return compartment->isDebuggee() && debuggees.has(compartment->maybeGlobal()); + } + private: HeapPtrNativeObject object; /* The Debugger object. Strong reference. */ GlobalObjectSet debuggees; /* Debuggee globals. Cross-compartment weak references. */ From 50e974859b6bc2782a871e78acbaab9bcd5f4008 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 11 Nov 2014 12:12:40 -0500 Subject: [PATCH 07/82] Bug 1097125 - part 0 - fix cut-and-pasted comment; r=ted.mielczarek --- layout/tools/reftest/mach_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/tools/reftest/mach_commands.py b/layout/tools/reftest/mach_commands.py index d0233b46782..1934958b8de 100644 --- a/layout/tools/reftest/mach_commands.py +++ b/layout/tools/reftest/mach_commands.py @@ -344,7 +344,7 @@ def ReftestCommand(func): return func def B2GCommand(func): - """Decorator that adds shared command arguments to b2g mochitest commands.""" + """Decorator that adds shared command arguments to b2g reftest commands.""" busybox = CommandArgument('--busybox', default=None, help='Path to busybox binary to install on device') From 316473b4de316de0aefa8dc418fe8364eae3c9cf Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 11 Nov 2014 12:16:53 -0500 Subject: [PATCH 08/82] Bug 1097125 - part 1 - add filtering support to |mach reftest-{remote,b2g-desktop}|; r=ted.mielczarek --- layout/tools/reftest/mach_commands.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/layout/tools/reftest/mach_commands.py b/layout/tools/reftest/mach_commands.py index 1934958b8de..8b87d9f860d 100644 --- a/layout/tools/reftest/mach_commands.py +++ b/layout/tools/reftest/mach_commands.py @@ -110,9 +110,12 @@ class ReftestRunner(MozbuildObject): return "'%s'" % re.sub("'", r"'\''", s) def run_b2g_test(self, b2g_home=None, xre_path=None, test_file=None, - suite=None, **kwargs): + suite=None, filter=None, **kwargs): """Runs a b2g reftest. + filter is a regular expression (in JS syntax, as could be passed to the + RegExp constructor) to select which reftests to run from the manifest. + test_file is a path to a test file. It can be a relative path from the top source directory, an absolute filename, or a directory containing test files. @@ -206,6 +209,7 @@ class ReftestRunner(MozbuildObject): options.httpdPath = os.path.join(self.topsrcdir, 'netwerk', 'test', 'httpserver') options.xrePath = xre_path options.ignoreWindowSize = True + options.filter = filter # Don't enable oop for crashtest until they run oop in automation if suite == 'reftest': @@ -376,6 +380,11 @@ def B2GCommand(func): help = 'Which chunk to run between 1 and --total-chunks.') func = thisChunk(func) + flter = CommandArgument('--filter', metavar='REGEX', + help='A JS regular expression to match test URLs against, to select ' + 'a subset of tests to run.') + func = flter(func) + oop = CommandArgument('--enable-oop', action='store_true', dest='oop', help = 'Run tests in out-of-process mode.') func = oop(func) From 0f3ee4a5933423674fedde69d9cf468e684d604e Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 11 Nov 2014 12:20:33 -0500 Subject: [PATCH 09/82] Bug 1097125 - part 2 - make |mach reftest| and related commands support single files; r=ted.mielczarek --- layout/tools/reftest/mach_commands.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/layout/tools/reftest/mach_commands.py b/layout/tools/reftest/mach_commands.py index 8b87d9f860d..b27754441fb 100644 --- a/layout/tools/reftest/mach_commands.py +++ b/layout/tools/reftest/mach_commands.py @@ -94,17 +94,24 @@ class ReftestRunner(MozbuildObject): return files[suite] def _find_manifest(self, suite, test_file): + """Return a tuple of (manifest-path, filter-string) for running test_file. + + test_file can be a relative path to a single test file or manifest from + the top source directory, an absolute path to the same, or a directory + containing a manifest. + """ assert test_file path_arg = self._wrap_path_argument(test_file) relpath = path_arg.relpath() if os.path.isdir(path_arg.srcdir_path()): - return mozpack.path.join(relpath, self._manifest_file(suite)) + return (mozpack.path.join(relpath, self._manifest_file(suite)), None) if relpath.endswith('.list'): - return relpath + return (relpath, None) - raise Exception('Running a single test is not currently supported') + return (self._find_manifest(suite, mozpack.path.dirname(test_file))[0], + mozpack.path.basename(test_file)) def _make_shell_string(self, s): return "'%s'" % re.sub("'", r"'\''", s) @@ -137,9 +144,13 @@ class ReftestRunner(MozbuildObject): test_file = mozpack.path.relpath(os.path.abspath(test_file), self.topsrcdir) - manifest = self._find_manifest(suite, test_file) + (manifest, single_file_filter) = self._find_manifest(suite, test_file) if not os.path.exists(mozpack.path.join(self.topsrcdir, manifest)): raise Exception('No manifest file was found at %s.' % manifest) + if single_file_filter: + if filter: + raise Exception('Cannot run single files in conjunction with --filter') + filter = single_file_filter # Need to chdir to reftest_dir otherwise imports fail below. os.chdir(self.reftest_dir) @@ -249,9 +260,13 @@ class ReftestRunner(MozbuildObject): extra_args = [] if test_file: - path = self._find_manifest(suite, test_file) + (path, single_file_filter) = self._find_manifest(suite, test_file) if not os.path.exists(mozpack.path.join(self.topsrcdir, path)): raise Exception('No manifest file was found at %s.' % path) + if single_file_filter: + if filter: + raise Exception('Cannot run single files in conjunction with --filter') + filter = single_file_filter env[b'TEST_PATH'] = path if filter: extra_args.extend(['--filter', self._make_shell_string(filter)]) From b323d54c5771dc382ae449c6363b097931d1fd21 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Fri, 28 Nov 2014 18:11:03 -0500 Subject: [PATCH 10/82] Bug 1105834 - Part 1: Add CreateDataSourceSurfaceByCloning to moz2d. r=mstange,bas --- gfx/2d/DataSurfaceHelpers.cpp | 82 +++++++++++++++++++++++++ gfx/2d/DataSurfaceHelpers.h | 30 +++++++++ gfx/2d/FilterNodeSoftware.cpp | 111 ++++------------------------------ gfx/2d/Rect.h | 8 +++ 4 files changed, 133 insertions(+), 98 deletions(-) diff --git a/gfx/2d/DataSurfaceHelpers.cpp b/gfx/2d/DataSurfaceHelpers.cpp index 9028b3497cf..8d9160066dc 100644 --- a/gfx/2d/DataSurfaceHelpers.cpp +++ b/gfx/2d/DataSurfaceHelpers.cpp @@ -9,11 +9,41 @@ #include "DataSurfaceHelpers.h" #include "Logging.h" #include "mozilla/MathAlgorithms.h" +#include "mozilla/PodOperations.h" #include "Tools.h" namespace mozilla { namespace gfx { +uint8_t* +DataAtOffset(DataSourceSurface* aSurface, IntPoint aPoint) +{ + if (!SurfaceContainsPoint(aSurface, aPoint)) { + MOZ_CRASH("sample position needs to be inside surface!"); + } + + MOZ_ASSERT(Factory::CheckSurfaceSize(aSurface->GetSize()), + "surface size overflows - this should have been prevented when the surface was created"); + + uint8_t* data = aSurface->GetData() + aPoint.y * aSurface->Stride() + + aPoint.x * BytesPerPixel(aSurface->GetFormat()); + + if (data < aSurface->GetData()) { + MOZ_CRASH("out-of-range data access"); + } + + return data; +} + +// This check is safe against integer overflow. +bool +SurfaceContainsPoint(SourceSurface* aSurface, const IntPoint& aPoint) +{ + IntSize size = aSurface->GetSize(); + return aPoint.x >= 0 && aPoint.x < size.width && + aPoint.y >= 0 && aPoint.y < size.height; +} + void ConvertBGRXToBGRA(uint8_t* aData, const IntSize &aSize, int32_t aStride) { @@ -196,5 +226,57 @@ BufferSizeFromStrideAndHeight(int32_t aStride, return requiredBytes.value(); } +/** + * aSrcRect: Rect relative to the aSrc surface + * aDestPoint: Point inside aDest surface + */ +void +CopyRect(DataSourceSurface* aSrc, DataSourceSurface* aDest, + IntRect aSrcRect, IntPoint aDestPoint) +{ + if (aSrcRect.Overflows() || + IntRect(aDestPoint, aSrcRect.Size()).Overflows()) { + MOZ_CRASH("we should never be getting invalid rects at this point"); + } + + MOZ_ASSERT(aSrc->GetFormat() == aDest->GetFormat(), "different surface formats"); + MOZ_ASSERT(IntRect(IntPoint(), aSrc->GetSize()).Contains(aSrcRect), "source rect too big for source surface"); + MOZ_ASSERT(IntRect(IntPoint(), aDest->GetSize()).Contains(aSrcRect - aSrcRect.TopLeft() + aDestPoint), "dest surface too small"); + + if (aSrcRect.IsEmpty()) { + return; + } + + uint8_t* sourceData = DataAtOffset(aSrc, aSrcRect.TopLeft()); + uint32_t sourceStride = aSrc->Stride(); + uint8_t* destData = DataAtOffset(aDest, aDestPoint); + uint32_t destStride = aDest->Stride(); + + if (BytesPerPixel(aSrc->GetFormat()) == 4) { + for (int32_t y = 0; y < aSrcRect.height; y++) { + PodCopy((int32_t*)destData, (int32_t*)sourceData, aSrcRect.width); + sourceData += sourceStride; + destData += destStride; + } + } else if (BytesPerPixel(aSrc->GetFormat()) == 1) { + for (int32_t y = 0; y < aSrcRect.height; y++) { + PodCopy(destData, sourceData, aSrcRect.width); + sourceData += sourceStride; + destData += destStride; + } + } +} + +TemporaryRef +CreateDataSourceSurfaceByCloning(DataSourceSurface* aSource) +{ + RefPtr copy = + Factory::CreateDataSourceSurface(aSource->GetSize(), aSource->GetFormat()); + if (copy) { + CopyRect(aSource, copy, IntRect(IntPoint(), aSource->GetSize()), IntPoint()); + } + return copy.forget(); +} + } } diff --git a/gfx/2d/DataSurfaceHelpers.h b/gfx/2d/DataSurfaceHelpers.h index f48e5f66a94..aa22b2f35ae 100644 --- a/gfx/2d/DataSurfaceHelpers.h +++ b/gfx/2d/DataSurfaceHelpers.h @@ -70,6 +70,36 @@ BufferSizeFromStrideAndHeight(int32_t aStride, int32_t aHeight, int32_t aExtraBytes = 0); +/** + * Copy aSrcRect from aSrc to aDest starting at aDestPoint. + */ +void +CopyRect(DataSourceSurface* aSrc, DataSourceSurface* aDest, + IntRect aSrcRect, IntPoint aDestPoint); + +/** + * Create a non aliasing copy of aSource. This creates a new DataSourceSurface + * using the factory and copies the bits. + * + * @return a dss allocated by Factory that contains a copy a aSource. + */ +TemporaryRef +CreateDataSourceSurfaceByCloning(DataSourceSurface* aSource); + +/** + * Return the byte at aPoint. + */ +uint8_t* +DataAtOffset(DataSourceSurface* aSurface, IntPoint aPoint); + +/** + * Check if aPoint is contained by the surface. + * + * @returns true if and only if aPoint is inside the surface. + */ +bool +SurfaceContainsPoint(SourceSurface* aSurface, const IntPoint& aPoint); + } } diff --git a/gfx/2d/FilterNodeSoftware.cpp b/gfx/2d/FilterNodeSoftware.cpp index bb111c511ef..13acd74ba84 100644 --- a/gfx/2d/FilterNodeSoftware.cpp +++ b/gfx/2d/FilterNodeSoftware.cpp @@ -180,101 +180,16 @@ NS_lround(double x) return x >= 0.0 ? int32_t(x + 0.5) : int32_t(x - 0.5); } -// This check is safe against integer overflow. -static bool -SurfaceContainsPoint(SourceSurface* aSurface, const IntPoint& aPoint) -{ - IntSize size = aSurface->GetSize(); - return aPoint.x >= 0 && aPoint.x < size.width && - aPoint.y >= 0 && aPoint.y < size.height; -} - -static uint8_t* -DataAtOffset(DataSourceSurface* aSurface, IntPoint aPoint) -{ - if (!SurfaceContainsPoint(aSurface, aPoint)) { - MOZ_CRASH("sample position needs to be inside surface!"); - } - - MOZ_ASSERT(Factory::CheckSurfaceSize(aSurface->GetSize()), - "surface size overflows - this should have been prevented when the surface was created"); - - uint8_t* data = aSurface->GetData() + aPoint.y * aSurface->Stride() + - aPoint.x * BytesPerPixel(aSurface->GetFormat()); - - if (data < aSurface->GetData()) { - MOZ_CRASH("out-of-range data access"); - } - - return data; -} - -static bool -IntRectOverflows(const IntRect& aRect) -{ - CheckedInt xMost = aRect.x; - xMost += aRect.width; - CheckedInt yMost = aRect.y; - yMost += aRect.height; - return !xMost.isValid() || !yMost.isValid(); -} - -/** - * aSrcRect: Rect relative to the aSrc surface - * aDestPoint: Point inside aDest surface - */ -static void -CopyRect(DataSourceSurface* aSrc, DataSourceSurface* aDest, - IntRect aSrcRect, IntPoint aDestPoint) -{ - if (IntRectOverflows(aSrcRect) || - IntRectOverflows(IntRect(aDestPoint, aSrcRect.Size()))) { - MOZ_CRASH("we should never be getting invalid rects at this point"); - } - - MOZ_ASSERT(aSrc->GetFormat() == aDest->GetFormat(), "different surface formats"); - MOZ_ASSERT(IntRect(IntPoint(), aSrc->GetSize()).Contains(aSrcRect), "source rect too big for source surface"); - MOZ_ASSERT(IntRect(IntPoint(), aDest->GetSize()).Contains(aSrcRect - aSrcRect.TopLeft() + aDestPoint), "dest surface too small"); - - if (aSrcRect.IsEmpty()) { - return; - } - - uint8_t* sourceData = DataAtOffset(aSrc, aSrcRect.TopLeft()); - uint32_t sourceStride = aSrc->Stride(); - uint8_t* destData = DataAtOffset(aDest, aDestPoint); - uint32_t destStride = aDest->Stride(); - - if (BytesPerPixel(aSrc->GetFormat()) == 4) { - for (int32_t y = 0; y < aSrcRect.height; y++) { - PodCopy((int32_t*)destData, (int32_t*)sourceData, aSrcRect.width); - sourceData += sourceStride; - destData += destStride; - } - } else if (BytesPerPixel(aSrc->GetFormat()) == 1) { - for (int32_t y = 0; y < aSrcRect.height; y++) { - PodCopy(destData, sourceData, aSrcRect.width); - sourceData += sourceStride; - destData += destStride; - } - } -} - TemporaryRef CloneAligned(DataSourceSurface* aSource) { - RefPtr copy = - Factory::CreateDataSourceSurface(aSource->GetSize(), aSource->GetFormat()); - if (copy) { - CopyRect(aSource, copy, IntRect(IntPoint(), aSource->GetSize()), IntPoint()); - } - return copy.forget(); + return CreateDataSourceSurfaceByCloning(aSource); } static void FillRectWithPixel(DataSourceSurface *aSurface, const IntRect &aFillRect, IntPoint aPixelPos) { - MOZ_ASSERT(!IntRectOverflows(aFillRect)); + MOZ_ASSERT(!aFillRect.Overflows()); MOZ_ASSERT(IntRect(IntPoint(), aSurface->GetSize()).Contains(aFillRect), "aFillRect needs to be completely inside the surface"); MOZ_ASSERT(SurfaceContainsPoint(aSurface, aPixelPos), @@ -307,8 +222,8 @@ FillRectWithVerticallyRepeatingHorizontalStrip(DataSourceSurface *aSurface, const IntRect &aFillRect, const IntRect &aSampleRect) { - MOZ_ASSERT(!IntRectOverflows(aFillRect)); - MOZ_ASSERT(!IntRectOverflows(aSampleRect)); + MOZ_ASSERT(!aFillRect.Overflows()); + MOZ_ASSERT(!aSampleRect.Overflows()); MOZ_ASSERT(IntRect(IntPoint(), aSurface->GetSize()).Contains(aFillRect), "aFillRect needs to be completely inside the surface"); MOZ_ASSERT(IntRect(IntPoint(), aSurface->GetSize()).Contains(aSampleRect), @@ -335,8 +250,8 @@ FillRectWithHorizontallyRepeatingVerticalStrip(DataSourceSurface *aSurface, const IntRect &aFillRect, const IntRect &aSampleRect) { - MOZ_ASSERT(!IntRectOverflows(aFillRect)); - MOZ_ASSERT(!IntRectOverflows(aSampleRect)); + MOZ_ASSERT(!aFillRect.Overflows()); + MOZ_ASSERT(!aSampleRect.Overflows()); MOZ_ASSERT(IntRect(IntPoint(), aSurface->GetSize()).Contains(aFillRect), "aFillRect needs to be completely inside the surface"); MOZ_ASSERT(IntRect(IntPoint(), aSurface->GetSize()).Contains(aSampleRect), @@ -367,7 +282,7 @@ FillRectWithHorizontallyRepeatingVerticalStrip(DataSourceSurface *aSurface, static void DuplicateEdges(DataSourceSurface* aSurface, const IntRect &aFromRect) { - MOZ_ASSERT(!IntRectOverflows(aFromRect)); + MOZ_ASSERT(!aFromRect.Overflows()); MOZ_ASSERT(IntRect(IntPoint(), aSurface->GetSize()).Contains(aFromRect), "aFromRect needs to be completely inside the surface"); @@ -475,7 +390,7 @@ GetDataSurfaceInRect(SourceSurface *aSurface, { MOZ_ASSERT(aSurface ? aSurfaceRect.Size() == aSurface->GetSize() : aSurfaceRect.IsEmpty()); - if (IntRectOverflows(aSurfaceRect) || IntRectOverflows(aDestRect)) { + if (aSurfaceRect.Overflows() || aDestRect.Overflows()) { // We can't rely on the intersection calculations below to make sense when // XMost() or YMost() overflow. Bail out. return nullptr; @@ -630,7 +545,7 @@ FilterNodeSoftware::Draw(DrawTarget* aDrawTarget, } IntRect outputRect = GetOutputRectInRect(renderIntRect); - if (IntRectOverflows(outputRect)) { + if (outputRect.Overflows()) { #ifdef DEBUG_DUMP_SURFACES printf("output rect overflowed, not painting anything\n"); printf("\n"); @@ -681,7 +596,7 @@ FilterNodeSoftware::GetOutput(const IntRect &aRect) { MOZ_ASSERT(GetOutputRectInRect(aRect).Contains(aRect)); - if (IntRectOverflows(aRect)) { + if (aRect.Overflows()) { return nullptr; } @@ -711,7 +626,7 @@ FilterNodeSoftware::RequestRect(const IntRect &aRect) void FilterNodeSoftware::RequestInputRect(uint32_t aInputEnumIndex, const IntRect &aRect) { - if (IntRectOverflows(aRect)) { + if (aRect.Overflows()) { return; } @@ -744,7 +659,7 @@ FilterNodeSoftware::GetInputDataSourceSurface(uint32_t aInputEnumIndex, ConvolveMatrixEdgeMode aEdgeMode, const IntRect *aTransparencyPaddedSourceRect) { - if (IntRectOverflows(aRect)) { + if (aRect.Overflows()) { return nullptr; } @@ -859,7 +774,7 @@ IntRect FilterNodeSoftware::GetInputRectInRect(uint32_t aInputEnumIndex, const IntRect &aInRect) { - if (IntRectOverflows(aInRect)) { + if (aInRect.Overflows()) { return IntRect(); } diff --git a/gfx/2d/Rect.h b/gfx/2d/Rect.h index b38f2e94fb6..db0f45d373b 100644 --- a/gfx/2d/Rect.h +++ b/gfx/2d/Rect.h @@ -91,6 +91,14 @@ struct IntRectTyped : IntRectTyped ToUnknownRect() const { return IntRectTyped(this->x, this->y, this->width, this->height); } + + bool Overflows() const { + CheckedInt xMost = this->x; + xMost += this->width; + CheckedInt yMost = this->y; + yMost += this->height; + return !xMost.isValid() || !yMost.isValid(); + } }; typedef IntRectTyped IntRect; From 6515991e7a45699c45c0bacf710b76c725c6af43 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Fri, 28 Nov 2014 17:41:47 -0500 Subject: [PATCH 11/82] Bug 1105834 - Part 2: Add layers.dump-texture feature. r=mstange --- gfx/layers/LayersLogging.cpp | 14 ++--- gfx/layers/composite/CompositableHost.cpp | 3 +- gfx/layers/composite/TextureHost.cpp | 13 +++++ gfx/layers/composite/TiledContentHost.cpp | 55 +++++++++++++------- gfx/layers/opengl/GrallocTextureHost.cpp | 43 +++++++++++----- gfx/thebes/gfxPrefs.h | 1 + gfx/thebes/gfxUtils.cpp | 62 +++++++++++++++++++---- gfx/thebes/gfxUtils.h | 2 + modules/libpref/init/all.js | 4 ++ 9 files changed, 144 insertions(+), 53 deletions(-) diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index 1f57fbb6cbe..407c3509dc9 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -327,17 +327,9 @@ print_stderr(std::stringstream& aStr) // we usually use std::stringstream to build up giant multi-line gobs // of output. So to avoid the truncation we find the newlines and // print the lines individually. - char line[1024]; - while (!aStr.eof()) { - aStr.getline(line, sizeof(line)); - if (!aStr.eof() || strlen(line) > 0) { - printf_stderr("%s\n", line); - } - if (aStr.fail()) { - // line was too long, skip to next newline - aStr.clear(); - aStr.ignore(std::numeric_limits::max(), '\n'); - } + std::string line; + while (std::getline(aStr, line)) { + printf_stderr("%s\n", line.c_str()); } #else printf_stderr("%s", aStr.str().c_str()); diff --git a/gfx/layers/composite/CompositableHost.cpp b/gfx/layers/composite/CompositableHost.cpp index c62669f80bb..514990326d0 100644 --- a/gfx/layers/composite/CompositableHost.cpp +++ b/gfx/layers/composite/CompositableHost.cpp @@ -223,8 +223,7 @@ CompositableHost::DumpTextureHost(std::stringstream& aStream, TextureHost* aText dSurf->GetSize(), dSurf->Stride(), dSurf->GetFormat()); - // TODO stream surface - gfxUtils::DumpAsDataURI(dt, stderr); + aStream << gfxUtils::GetAsDataURI(dt).get(); } #endif diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index b8d5834adbe..f968e2921d5 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -27,6 +27,7 @@ #include "SharedSurfaceEGL.h" #include "SharedSurfaceGL.h" #include "../opengl/CompositorOGL.h" +#include "gfxUtils.h" #ifdef MOZ_ENABLE_D3D10_LAYER #include "../d3d11/CompositorD3D11.h" @@ -326,6 +327,18 @@ TextureHost::PrintInfo(std::stringstream& aStream, const char* aPrefix) Unlock(); } AppendToString(aStream, mFlags, " [flags=", "]"); +#ifdef MOZ_DUMP_PAINTING + if (gfxPrefs::LayersDumpTexture()) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + aStream << "\n" << pfx.get() << "Surface: "; + RefPtr dSurf = GetAsSurface(); + if (dSurf) { + aStream << gfxUtils::GetAsDataURI(dSurf).get(); + } + } +#endif } TextureSource::TextureSource() diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index 5556ec3599b..fe2f5743d3c 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -606,6 +606,14 @@ TiledContentHost::PrintInfo(std::stringstream& aStream, const char* aPrefix) aStream << aPrefix; aStream << nsPrintfCString("TiledContentHost (0x%p)", this).get(); +#ifdef MOZ_DUMP_PAINTING + if (gfxPrefs::LayersDumpTexture()) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + Dump(aStream, pfx.get(), false); + } +#endif } #ifdef MOZ_DUMP_PAINTING @@ -614,24 +622,37 @@ TiledContentHost::Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml) { - TiledLayerBufferComposite::Iterator it = mTiledBuffer.TilesBegin(); - TiledLayerBufferComposite::Iterator stop = mTiledBuffer.TilesEnd(); - if (aDumpHtml) { - aStream << ""; + + for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { + int32_t tileStartY = mTiledBuffer.GetTileStart(y, scaledTileSize.height); + TileHost tileTexture = mTiledBuffer. + GetTile(nsIntPoint(mTiledBuffer.RoundDownToTileEdge(x, scaledTileSize.width), + mTiledBuffer.RoundDownToTileEdge(y, scaledTileSize.height))); + int32_t h = scaledTileSize.height - tileStartY; + if (y + h > visibleRect.y + visibleRect.height) { + h = visibleRect.y + visibleRect.height - y; + } + + aStream << "\n" << aPrefix << "Tile (x=" << + mTiledBuffer.RoundDownToTileEdge(x, scaledTileSize.width) << ", y=" << + mTiledBuffer.RoundDownToTileEdge(y, scaledTileSize.height) << "): "; + if (tileTexture != mTiledBuffer.GetPlaceholderTile()) { + DumpTextureHost(aStream, tileTexture.mTextureHost); + // TODO We should combine the OnWhite/OnBlack here an just output a single image. + } else { + aStream << "empty tile"; + } + y += h; + } + x += w; } } #endif diff --git a/gfx/layers/opengl/GrallocTextureHost.cpp b/gfx/layers/opengl/GrallocTextureHost.cpp index 8de2d4a17e9..601fae71722 100644 --- a/gfx/layers/opengl/GrallocTextureHost.cpp +++ b/gfx/layers/opengl/GrallocTextureHost.cpp @@ -8,6 +8,7 @@ #include "gfx2DGlue.h" #include #include "GrallocImages.h" // for GrallocImage +#include "mozilla/gfx/DataSurfaceHelpers.h" #include "mozilla/layers/GrallocTextureHost.h" #include "mozilla/layers/SharedBufferManagerParent.h" #include "EGLImageHelpers.h" @@ -385,29 +386,45 @@ GrallocTextureHostOGL::GetRenderState() TemporaryRef GrallocTextureHostOGL::GetAsSurface() { - return mTilingTextureSource ? mTilingTextureSource->GetAsSurface() - : nullptr; + if (mTilingTextureSource) { + return mTilingTextureSource->GetAsSurface(); + } else { + android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get(); + uint8_t* grallocData; + int32_t rv = graphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast(&grallocData)); + RefPtr grallocTempSurf = + Factory::CreateWrappingDataSourceSurface(grallocData, + graphicBuffer->getStride() * android::bytesPerPixel(graphicBuffer->getPixelFormat()), + GetSize(), GetFormat()); + RefPtr surf = CreateDataSourceSurfaceByCloning(grallocTempSurf); + + graphicBuffer->unlock(); + + return surf.forget(); + } } TemporaryRef GrallocTextureSourceOGL::GetAsSurface() { - if (!IsValid() || !gl()->MakeCurrent()) { + if (!IsValid()) { return nullptr; } - GLuint tex = GetGLTexture(); - gl()->fActiveTexture(LOCAL_GL_TEXTURE0); - gl()->fBindTexture(GetTextureTarget(), tex); - if (!mEGLImage) { - mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); + uint8_t* grallocData; + int32_t rv = mGraphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast(&grallocData)); + if (rv) { + return nullptr; } - BindEGLImage(); - RefPtr surf = - IsValid() ? ReadBackSurface(gl(), tex, false, GetFormat()) - : nullptr; + RefPtr grallocTempSurf = + Factory::CreateWrappingDataSourceSurface(grallocData, + mGraphicBuffer->getStride() * android::bytesPerPixel(mGraphicBuffer->getPixelFormat()), + GetSize(), GetFormat()); + + RefPtr surf = CreateDataSourceSurfaceByCloning(grallocTempSurf); + + mGraphicBuffer->unlock(); - gl()->fActiveTexture(LOCAL_GL_TEXTURE0); return surf.forget(); } diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index c3c54b6a8ce..c5bfc9fe7dd 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -270,6 +270,7 @@ private: DECL_GFX_PREF(Live, "layers.flash-borders", FlashLayerBorders, bool, false); DECL_GFX_PREF(Live, "layers.draw-layer-info", DrawLayerInfo, bool, false); DECL_GFX_PREF(Live, "layers.dump", LayersDump, bool, false); + DECL_GFX_PREF(Live, "layers.dump-texture", LayersDumpTexture, bool, false); // 0 is "no change" for contrast, positive values increase it, negative values // decrease it until we hit mid gray at -1 contrast, after that it gets weird. diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index bb3aa4ed6df..70253dedfcd 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -1110,14 +1110,15 @@ gfxUtils::GetColorForFrameNumber(uint64_t aFrameNumber) return colors[aFrameNumber % sNumFrameColors]; } -/* static */ nsresult -gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, - const nsACString& aMimeType, - const nsAString& aOutputOptions, - BinaryOrData aBinaryOrData, - FILE* aFile) +static nsresult +EncodeSourceSurfaceInternal(SourceSurface* aSurface, + const nsACString& aMimeType, + const nsAString& aOutputOptions, + gfxUtils::BinaryOrData aBinaryOrData, + FILE* aFile, + nsCString* aStrOut) { - MOZ_ASSERT(aBinaryOrData == eDataURIEncode || aFile, + MOZ_ASSERT(aBinaryOrData == gfxUtils::eDataURIEncode || aFile || aStrOut, "Copying binary encoding to clipboard not currently supported"); const IntSize size = aSurface->GetSize(); @@ -1130,8 +1131,8 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, if (aSurface->GetFormat() != SurfaceFormat::B8G8R8A8) { // FIXME bug 995807 (B8G8R8X8), bug 831898 (R5G6B5) dataSurface = - CopySurfaceToDataSourceSurfaceWithFormat(aSurface, - SurfaceFormat::B8G8R8A8); + gfxUtils::CopySurfaceToDataSourceSurfaceWithFormat(aSurface, + SurfaceFormat::B8G8R8A8); } else { dataSurface = aSurface->GetDataSurface(); } @@ -1214,7 +1215,7 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(!imgData.empty(), NS_ERROR_FAILURE); - if (aBinaryOrData == eBinaryEncode) { + if (aBinaryOrData == gfxUtils::eBinaryEncode) { if (aFile) { fwrite(imgData.begin(), 1, imgSize, aFile); } @@ -1247,6 +1248,8 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, } #endif fprintf(aFile, "%s", string.BeginReading()); + } else if (aStrOut) { + *aStrOut = string; } else { nsCOMPtr clipboard(do_GetService("@mozilla.org/widget/clipboardhelper;1", &rv)); if (clipboard) { @@ -1256,6 +1259,27 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, return NS_OK; } +static nsCString +EncodeSourceSurfaceAsPNGURI(SourceSurface* aSurface) +{ + nsCString string; + EncodeSourceSurfaceInternal(aSurface, NS_LITERAL_CSTRING("image/png"), + EmptyString(), gfxUtils::eDataURIEncode, + nullptr, &string); + return string; +} + +/* static */ nsresult +gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, + const nsACString& aMimeType, + const nsAString& aOutputOptions, + BinaryOrData aBinaryOrData, + FILE* aFile) +{ + return EncodeSourceSurfaceInternal(aSurface, aMimeType, aOutputOptions, + aBinaryOrData, aFile, nullptr); +} + /* static */ void gfxUtils::WriteAsPNG(SourceSurface* aSurface, const nsAString& aFile) { @@ -1337,6 +1361,12 @@ gfxUtils::DumpAsDataURI(SourceSurface* aSurface, FILE* aFile) EmptyString(), eDataURIEncode, aFile); } +/* static */ nsCString +gfxUtils::GetAsDataURI(SourceSurface* aSurface) +{ + return EncodeSourceSurfaceAsPNGURI(aSurface); +} + /* static */ void gfxUtils::DumpAsDataURI(DrawTarget* aDT, FILE* aFile) { @@ -1348,6 +1378,18 @@ gfxUtils::DumpAsDataURI(DrawTarget* aDT, FILE* aFile) } } +/* static */ nsCString +gfxUtils::GetAsDataURI(DrawTarget* aDT) +{ + RefPtr surface = aDT->Snapshot(); + if (surface) { + return EncodeSourceSurfaceAsPNGURI(surface); + } else { + NS_WARNING("Failed to get surface!"); + return nsCString(""); + } +} + /* static */ void gfxUtils::CopyAsDataURI(SourceSurface* aSurface) { diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index e03152a86bc..fae9de3b131 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -281,6 +281,8 @@ public: static inline void DumpAsDataURI(DrawTarget* aDT) { DumpAsDataURI(aDT, stdout); } + static nsCString GetAsDataURI(SourceSurface* aSourceSurface); + static nsCString GetAsDataURI(DrawTarget* aDT); /** * Copy to the clipboard as a PNG encoded Data URL. diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 1c653328347..a7471524267 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3893,6 +3893,10 @@ pref("layers.acceleration.force-enabled", false); pref("layers.acceleration.draw-fps", false); pref("layers.dump", false); +#ifdef MOZ_DUMP_PAINTING +// If we're dumping layers, also dump the texture data +pref("layers.dump-texture", false); +#endif pref("layers.draw-borders", false); pref("layers.draw-tile-borders", false); pref("layers.draw-bigimage-borders", false); From 908b93e06dd447432e3778062f7cae53dcf94c8d Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Mon, 8 Dec 2014 14:42:33 -0500 Subject: [PATCH 12/82] Bug 1105834 - Part 3: Add lz4 support. r=jrmuizel --- gfx/layers/composite/CompositableHost.cpp | 7 +----- gfx/layers/composite/TextureHost.cpp | 2 +- gfx/thebes/gfxUtils.cpp | 30 +++++++++++++++++++++++ gfx/thebes/gfxUtils.h | 1 + 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/gfx/layers/composite/CompositableHost.cpp b/gfx/layers/composite/CompositableHost.cpp index 514990326d0..84ea3aa5218 100644 --- a/gfx/layers/composite/CompositableHost.cpp +++ b/gfx/layers/composite/CompositableHost.cpp @@ -218,12 +218,7 @@ CompositableHost::DumpTextureHost(std::stringstream& aStream, TextureHost* aText if (!dSurf) { return; } - gfxPlatform *platform = gfxPlatform::GetPlatform(); - RefPtr dt = platform->CreateDrawTargetForData(dSurf->GetData(), - dSurf->GetSize(), - dSurf->Stride(), - dSurf->GetFormat()); - aStream << gfxUtils::GetAsDataURI(dt).get(); + aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); } #endif diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index f968e2921d5..8ae4d6de825 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -335,7 +335,7 @@ TextureHost::PrintInfo(std::stringstream& aStream, const char* aPrefix) aStream << "\n" << pfx.get() << "Surface: "; RefPtr dSurf = GetAsSurface(); if (dSurf) { - aStream << gfxUtils::GetAsDataURI(dSurf).get(); + aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); } } #endif diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 70253dedfcd..9dd8ee262dc 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -43,6 +43,10 @@ using namespace mozilla::gfx; #include "DeprecatedPremultiplyTables.h" +#undef compress +#include "mozilla/Compression.h" + +using namespace mozilla::Compression; extern "C" { /** @@ -1378,6 +1382,32 @@ gfxUtils::DumpAsDataURI(DrawTarget* aDT, FILE* aFile) } } +/* static */ nsCString +gfxUtils::GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface) +{ + int32_t dataSize = aSourceSurface->GetSize().height * aSourceSurface->Stride(); + auto compressedData = MakeUnique(LZ4::maxCompressedSize(dataSize)); + if (compressedData) { + int nDataSize = LZ4::compress((char*)aSourceSurface->GetData(), + dataSize, + compressedData.get()); + if (nDataSize > 0) { + nsCString encodedImg; + nsresult rv = Base64Encode(Substring(compressedData.get(), nDataSize), encodedImg); + if (rv == NS_OK) { + nsCString string(""); + string.AppendPrintf("data:image/lz4bgra;base64,%i,%i,%i,", + aSourceSurface->GetSize().width, + aSourceSurface->Stride(), + aSourceSurface->GetSize().height); + string.Append(encodedImg); + return string; + } + } + } + return nsCString(""); +} + /* static */ nsCString gfxUtils::GetAsDataURI(DrawTarget* aDT) { diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index fae9de3b131..1dc13ce1534 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -283,6 +283,7 @@ public: } static nsCString GetAsDataURI(SourceSurface* aSourceSurface); static nsCString GetAsDataURI(DrawTarget* aDT); + static nsCString GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface); /** * Copy to the clipboard as a PNG encoded Data URL. From 334ad4332823ea120ade1a32cd4257a48b9f1ffa Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Tue, 9 Dec 2014 07:19:04 +0900 Subject: [PATCH 13/82] Bug 1084025 - Disable insecure version fallback. r=dkeeler --- netwerk/base/public/security-prefs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwerk/base/public/security-prefs.js b/netwerk/base/public/security-prefs.js index 6b26e45abc4..5da6ed335b8 100644 --- a/netwerk/base/public/security-prefs.js +++ b/netwerk/base/public/security-prefs.js @@ -4,7 +4,7 @@ pref("security.tls.version.min", 1); pref("security.tls.version.max", 3); -pref("security.tls.version.fallback-limit", 1); +pref("security.tls.version.fallback-limit", 3); pref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", false); pref("security.ssl.renego_unrestricted_hosts", ""); From 587906641bb3bd99bc0fbdb1cebf24cfda0a5c4f Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Tue, 9 Dec 2014 07:19:05 +0900 Subject: [PATCH 14/82] Bug 1084025 - Add telemetry to measure failures due to not falling back. r=keeler --- security/manager/ssl/src/nsNSSIOLayer.cpp | 51 ++++++++++++++++++-- security/manager/ssl/src/nsNSSIOLayer.h | 4 +- toolkit/components/telemetry/Histograms.json | 6 +++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 0f9ba97defd..96b074ebb97 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -870,18 +870,21 @@ nsSSLIOLayerHelpers::rememberTolerantAtVersion(const nsACString& hostName, mTLSIntoleranceInfo.Put(key, entry); } -void nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName, - int16_t port) +uint16_t +nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName, + int16_t port) { nsCString key; getSiteKey(hostName, port, key); MutexAutoLock lock(mutex); + uint16_t tolerant = 0; IntoleranceEntry entry; if (mTLSIntoleranceInfo.Get(key, &entry)) { entry.AssertInvariant(); + tolerant = entry.tolerant; entry.intolerant = 0; entry.intoleranceReason = 0; if (entry.strongCipherStatus != StrongCiphersWorked) { @@ -891,6 +894,8 @@ void nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName, entry.AssertInvariant(); mTLSIntoleranceInfo.Put(key, entry); } + + return tolerant; } // returns true if we should retry the handshake @@ -903,7 +908,47 @@ nsSSLIOLayerHelpers::rememberIntolerantAtVersion(const nsACString& hostName, { if (intolerant <= minVersion || intolerant <= mVersionFallbackLimit) { // We can't fall back any further. Assume that intolerance isn't the issue. - forgetIntolerance(hostName, port); + uint32_t tolerant = forgetIntolerance(hostName, port); + // If we know the server is tolerant at the version, we don't have to + // gather the telemetry. + if (intolerant <= tolerant) { + return false; + } + + uint32_t fallbackLimitBucket = 0; + // added if the version has reached the min version. + if (intolerant <= minVersion) { + switch (minVersion) { + case SSL_LIBRARY_VERSION_TLS_1_0: + fallbackLimitBucket += 1; + break; + case SSL_LIBRARY_VERSION_TLS_1_1: + fallbackLimitBucket += 2; + break; + case SSL_LIBRARY_VERSION_TLS_1_2: + fallbackLimitBucket += 3; + break; + } + } + // added if the version has reached the fallback limit. + if (intolerant <= mVersionFallbackLimit) { + switch (mVersionFallbackLimit) { + case SSL_LIBRARY_VERSION_TLS_1_0: + fallbackLimitBucket += 4; + break; + case SSL_LIBRARY_VERSION_TLS_1_1: + fallbackLimitBucket += 8; + break; + case SSL_LIBRARY_VERSION_TLS_1_2: + fallbackLimitBucket += 12; + break; + } + } + if (fallbackLimitBucket) { + Telemetry::Accumulate(Telemetry::SSL_FALLBACK_LIMIT_REACHED, + fallbackLimitBucket); + } + return false; } diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 7404c3b6a90..e91b6e6def5 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -225,7 +225,9 @@ public: PRErrorCode intoleranceReason); bool rememberStrongCiphersFailed(const nsACString& hostName, int16_t port, PRErrorCode intoleranceReason); - void forgetIntolerance(const nsACString& hostname, int16_t port); + // returns the known tolerant version + // or 0 if there is no known tolerant version + uint16_t forgetIntolerance(const nsACString& hostname, int16_t port); void adjustForTLSIntolerance(const nsACString& hostname, int16_t port, /*in/out*/ SSLVersionRange& range, /*out*/ StrongCipherStatus& strongCipherStatus); diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index b82564909b8..01f34ae5398 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -6480,6 +6480,12 @@ "n_values": 64, "description": "TLS/SSL version intolerance was falsely detected, server rejected handshake" }, + "SSL_FALLBACK_LIMIT_REACHED": { + "expires_in_version": "default", + "kind": "enumerated", + "n_values": 16, + "description": "TLS/SSL version fallback reached the fallback limit (1=TLS 1.0, 2=TLS 1.1, 3=TLS 1.2) or the minimum version (4=TLS 1.0, 8=TLS 1.1, 12=TLS 1.2), stopped the fallback" + }, "SSL_WEAK_CIPHERS_FALLBACK": { "expires_in_version": "never", "kind": "enumerated", From 7b2afd6eae28fa2288727e46e0e6433baff73e36 Mon Sep 17 00:00:00 2001 From: "Byron Campen [:bwc]" Date: Wed, 19 Nov 2014 16:11:06 -0800 Subject: [PATCH 15/82] Bug 1091242 - Part 1: SDP wrapper code around sipcc sdp impl. See https://github.com/unicorn-wg/gecko-dev/tree/multistream_rebase for more history. r=jesup --- media/webrtc/signaling/src/sdp/Sdp.h | 195 ++ .../webrtc/signaling/src/sdp/SdpAttribute.cpp | 588 ++++++ media/webrtc/signaling/src/sdp/SdpAttribute.h | 1314 +++++++++++++ .../signaling/src/sdp/SdpAttributeList.h | 90 + media/webrtc/signaling/src/sdp/SdpEnum.h | 53 + .../webrtc/signaling/src/sdp/SdpErrorHolder.h | 50 + .../signaling/src/sdp/SdpMediaSection.h | 284 +++ media/webrtc/signaling/src/sdp/SipccSdp.cpp | 186 ++ media/webrtc/signaling/src/sdp/SipccSdp.h | 88 + .../src/sdp/SipccSdpAttributeList.cpp | 1116 +++++++++++ .../signaling/src/sdp/SipccSdpAttributeList.h | 133 ++ .../src/sdp/SipccSdpMediaSection.cpp | 332 ++++ .../signaling/src/sdp/SipccSdpMediaSection.h | 93 + .../signaling/src/sdp/SipccSdpParser.cpp | 83 + .../webrtc/signaling/src/sdp/SipccSdpParser.h | 35 + media/webrtc/signaling/test/sdp_unittests.cpp | 1717 ++++++++++++++++- 16 files changed, 6299 insertions(+), 58 deletions(-) create mode 100644 media/webrtc/signaling/src/sdp/Sdp.h create mode 100644 media/webrtc/signaling/src/sdp/SdpAttribute.cpp create mode 100644 media/webrtc/signaling/src/sdp/SdpAttribute.h create mode 100644 media/webrtc/signaling/src/sdp/SdpAttributeList.h create mode 100644 media/webrtc/signaling/src/sdp/SdpEnum.h create mode 100644 media/webrtc/signaling/src/sdp/SdpErrorHolder.h create mode 100644 media/webrtc/signaling/src/sdp/SdpMediaSection.h create mode 100644 media/webrtc/signaling/src/sdp/SipccSdp.cpp create mode 100644 media/webrtc/signaling/src/sdp/SipccSdp.h create mode 100644 media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp create mode 100644 media/webrtc/signaling/src/sdp/SipccSdpAttributeList.h create mode 100644 media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp create mode 100644 media/webrtc/signaling/src/sdp/SipccSdpMediaSection.h create mode 100644 media/webrtc/signaling/src/sdp/SipccSdpParser.cpp create mode 100644 media/webrtc/signaling/src/sdp/SipccSdpParser.h diff --git a/media/webrtc/signaling/src/sdp/Sdp.h b/media/webrtc/signaling/src/sdp/Sdp.h new file mode 100644 index 00000000000..3b00e5ab1b0 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/Sdp.h @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + + ,-----. ,--. ,--. + ' .--./ ,--,--.,--.,--.,-' '-.`--' ,---. ,--,--, + | | ' ,-. || || |'-. .-',--.| .-. || ` + ' '--'\\ '-' |' '' ' | | | |' '-' '| || | + `-----' `--`--' `----' `--' `--' `---' `--''--' + + :+o+- + -dNNNNNd. + yNNNNNNNs + :mNNNNNm- + `/sso/``-://- + .:+sydNNNNNNms: `://` + `-/+shmNNNNNNNNNNNNNNNms- :mNNNm/ + `-/oydmNNNNNNNNNNNNNNNNNNNNNNNNdo- +NNNNNN+ + .shmNNNNNNNNNNNmdyo/:dNNNNNNNNNNNNNNNNdo. `sNNNNNm+ + hNNNNNNNNmhs+:-` .dNNNNNNNNNNNNNNNNNNNNh+-` `hNNNNNm: + -yddyo/:. -dNNNNm::ymNNNNNNNNNNNNNNNmdy+/dNNNNNd. + :mNNNNd. `/ymNNNNNNNNNNNNNNNNNNNNNNh` + +NNNNNh` `+hNNNNNNNNNNNNNNNNNNNs + sNNNNNy` .yNNNNNm`-/oymNNNm+ + `yNNNNNo oNNNNNm` `-. + .dNNNNm/ oNNNNNm` + oNNNNm: +NNNNNm` + `+yho. +NNNNNm` + +NNNNNNs. + `yNNNNNNmy- + -smNNNNNNh: + .smNNNNNNh/ + `omNNNNNNd: + `+dNNNNNd + ````......```` /hmdy- + `.:/+osyhddmNNMMMMMMMMMMMMMMMMMMMMNNmddhyso+/:.` + `-+shmNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNmhs+-` + -smMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMds- + hMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh + yMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMs + .ohNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNh+. + ./oydmMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmhyo:. + `.:/+osyyhddmmNNMMMMMMMMMMMMMMNNmmddhyyso+/:.` + + ,--------.,--. ,--. ,--. + '--. .--'| ,---. `--' ,---. | | ,---. + | | | .-. |,--.( .-' | |( .-' + | | | | | || |.-' `) | |.-' `) + `--' `--' `--'`--'`----' `--'`----' + ,--. + ,---. ,------. ,------. ,--. | | + ' .-' | .-. \ | .--. ' ,--,--.,--.--.,-' '-. ,--,--.| | + `. `-. | | \ :| '--' |' ,-. || .--''-. .-'' ,-. || | + .-' || '--' /| | --' \ '-' || | | | \ '-' |`--' + `-----' `-------' `--' `--`--'`--' `--' `--`--'.--. + '__' +*/ + +#ifndef _SDP_H_ +#define _SDP_H_ + +#include +#include +#include +#include "mozilla/UniquePtr.h" +#include "mozilla/Maybe.h" +#include "signaling/src/sdp/SdpMediaSection.h" +#include "signaling/src/sdp/SdpAttributeList.h" +#include "signaling/src/sdp/SdpEnum.h" + +namespace mozilla +{ + +class SdpOrigin; +class SdpEncryptionKey; +class SdpMediaSection; + +/** + * Base class for an SDP + */ +class Sdp +{ +public: + Sdp(){}; + virtual ~Sdp(){}; + + virtual const SdpOrigin& GetOrigin() const = 0; + // Note: connection information is always retrieved from media sections + virtual uint32_t GetBandwidth(const std::string& type) const = 0; + + virtual const SdpAttributeList& GetAttributeList() const = 0; + virtual SdpAttributeList& GetAttributeList() = 0; + + virtual size_t GetMediaSectionCount() const = 0; + virtual const SdpMediaSection& GetMediaSection(size_t level) const = 0; + virtual SdpMediaSection& GetMediaSection(size_t level) = 0; + + virtual SdpMediaSection& AddMediaSection(SdpMediaSection::MediaType media, + SdpDirectionAttribute::Direction dir, + uint16_t port, + SdpMediaSection::Protocol proto, + sdp::AddrType addrType, + const std::string& addr) = 0; + + virtual void Serialize(std::ostream&) const = 0; + + std::string ToString() const; +}; + +inline std::ostream& operator<<(std::ostream& os, const Sdp& sdp) +{ + sdp.Serialize(os); + return os; +} + +inline std::string +Sdp::ToString() const +{ + std::stringstream s; + s << *this; + return s.str(); +} + +class SdpOrigin +{ +public: + SdpOrigin(const std::string& username, uint64_t sessId, uint64_t sessVer, + sdp::AddrType addrType, const std::string& addr) + : mUsername(username), + mSessionId(sessId), + mSessionVersion(sessVer), + mAddrType(addrType), + mAddress(addr) + { + } + + const std::string& + GetUsername() const + { + return mUsername; + } + + uint64_t + GetSessionId() const + { + return mSessionId; + } + + uint64_t + GetSessionVersion() const + { + return mSessionVersion; + } + + const sdp::AddrType + GetAddrType() const + { + return mAddrType; + } + + const std::string& + GetAddress() const + { + return mAddress; + } + + void + Serialize(std::ostream& os) const + { + sdp::NetType netType = sdp::kInternet; + os << "o=" << mUsername << " " << mSessionId << " " << mSessionVersion + << " " << netType << " " << mAddrType << " " << mAddress << "\r\n"; + } + +private: + std::string mUsername; + uint64_t mSessionId; + uint64_t mSessionVersion; + sdp::AddrType mAddrType; + std::string mAddress; +}; + +inline std::ostream& operator<<(std::ostream& os, const SdpOrigin& origin) +{ + origin.Serialize(os); + return os; +} + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/sdp/SdpAttribute.cpp b/media/webrtc/signaling/src/sdp/SdpAttribute.cpp new file mode 100644 index 00000000000..2694a33f83f --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SdpAttribute.cpp @@ -0,0 +1,588 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "signaling/src/sdp/SdpAttribute.h" + +#include + +#ifdef CRLF +#undef CRLF +#endif +#define CRLF "\r\n" + +namespace mozilla +{ + +void +SdpConnectionAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mType << ":" << mValue << CRLF; +} + +void +SdpDirectionAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mValue << CRLF; +} + +void +SdpExtmapAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mExtmaps.begin(); i != mExtmaps.end(); ++i) { + os << "a=" << mType << ":" << i->entry; + if (i->direction_specified) { + os << "/" << i->direction; + } + os << " " << i->extensionname; + if (i->extensionattributes.length()) { + os << " " << i->extensionattributes; + } + os << CRLF; + } +} + +void +SdpFingerprintAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mFingerprints.begin(); i != mFingerprints.end(); ++i) { + os << "a=" << mType << ":" << i->hashFunc << " " + << FormatFingerprint(i->fingerprint) << CRLF; + } +} + +// Format the fingerprint in RFC 4572 Section 5 attribute format +std::string +SdpFingerprintAttributeList::FormatFingerprint(const std::vector& fp) +{ + if (fp.empty()) { + MOZ_ASSERT(false, "Cannot format an empty fingerprint."); + return ""; + } + + std::ostringstream os; + for (auto i = fp.begin(); i != fp.end(); ++i) { + os << ":" << std::hex << std::uppercase << std::setw(2) << std::setfill('0') + << static_cast(*i); + } + return os.str().substr(1); +} + +static uint8_t +FromUppercaseHex(char ch) +{ + if ((ch >= '0') && (ch <= '9')) { + return ch - '0'; + } + if ((ch >= 'A') && (ch <= 'F')) { + return ch - 'A' + 10; + } + return 16; // invalid +} + +// Parse the fingerprint from RFC 4572 Section 5 attribute format +std::vector +SdpFingerprintAttributeList::ParseFingerprint(const std::string& str) +{ + size_t targetSize = (str.length() + 1) / 3; + std::vector fp(targetSize); + size_t fpIndex = 0; + + if (str.length() % 3 != 2) { + fp.clear(); + return fp; + } + + for (size_t i = 0; i < str.length(); i += 3) { + uint8_t high = FromUppercaseHex(str[i]); + uint8_t low = FromUppercaseHex(str[i + 1]); + if (high > 0xf || low > 0xf || + (i + 2 < str.length() && str[i + 2] != ':')) { + fp.clear(); // error + return fp; + } + fp[fpIndex++] = high << 4 | low; + } + return fp; +} + +void +SdpFmtpAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mFmtps.begin(); i != mFmtps.end(); ++i) { + os << "a=" << mType << ":" << i->format << " "; + if (i->parameters) { + i->parameters->Serialize(os); + } else { + os << i->parameters_string; + } + os << CRLF; + } +} + +void +SdpGroupAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mGroups.begin(); i != mGroups.end(); ++i) { + os << "a=" << mType << ":" << i->semantics; + for (auto j = i->tags.begin(); j != i->tags.end(); ++j) { + os << " " << (*j); + } + os << CRLF; + } +} + +// We're just using an SdpStringAttribute for this right now +#if 0 +void SdpIdentityAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mType << ":" << mAssertion; + for (auto i = mExtensions.begin(); i != mExtensions.end(); i++) { + os << (i == mExtensions.begin() ? " " : ";") << (*i); + } + os << CRLF; +} +#endif + +void +SdpImageattrAttributeList::Serialize(std::ostream& os) const +{ + MOZ_ASSERT(false, "Serializer not yet implemented"); +} + +void +SdpMsidAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mMsids.begin(); i != mMsids.end(); ++i) { + os << "a=" << mType << ":" << i->identifier; + if (i->appdata.length()) { + os << " " << i->appdata; + } + os << CRLF; + } +} + +void +SdpRemoteCandidatesAttribute::Serialize(std::ostream& os) const +{ + if (mCandidates.empty()) { + return; + } + + os << "a=" << mType; + for (auto i = mCandidates.begin(); i != mCandidates.end(); i++) { + os << (i == mCandidates.begin() ? ":" : " ") << i->id << " " << i->address + << " " << i->port; + } + os << CRLF; +} + +void +SdpRtcpAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mType << ":" << mPort; + if (mNetType != sdp::kNetTypeNone && mAddrType != sdp::kAddrTypeNone) { + os << " " << mNetType << " " << mAddrType << " " << mAddress; + } + os << CRLF; +} + +const char* SdpRtcpFbAttributeList::pli = "pli"; +const char* SdpRtcpFbAttributeList::sli = "sli"; +const char* SdpRtcpFbAttributeList::rpsi = "rpsi"; +const char* SdpRtcpFbAttributeList::app = "app"; + +const char* SdpRtcpFbAttributeList::fir = "fir"; +const char* SdpRtcpFbAttributeList::tmmbr = "tmmbr"; +const char* SdpRtcpFbAttributeList::tstr = "tstr"; +const char* SdpRtcpFbAttributeList::vbcm = "vbcm"; + +void +SdpRtcpFbAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mFeedbacks.begin(); i != mFeedbacks.end(); ++i) { + os << "a=" << mType << ":" << i->pt << " " << i->type; + if (i->parameter.length()) { + os << " " << i->parameter; + if (i->extra.length()) { + os << " " << i->extra; + } + } + os << CRLF; + } +} + +static bool +ShouldSerializeChannels(SdpRtpmapAttributeList::CodecType type) +{ + switch (type) { + case SdpRtpmapAttributeList::kOpus: + case SdpRtpmapAttributeList::kG722: + return true; + case SdpRtpmapAttributeList::kPCMU: + case SdpRtpmapAttributeList::kPCMA: + case SdpRtpmapAttributeList::kVP8: + case SdpRtpmapAttributeList::kVP9: + case SdpRtpmapAttributeList::kiLBC: + case SdpRtpmapAttributeList::kiSAC: + case SdpRtpmapAttributeList::kH264: + return false; + case SdpRtpmapAttributeList::kOtherCodec: + return true; + } + MOZ_CRASH(); +} + +void +SdpRtpmapAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mRtpmaps.begin(); i != mRtpmaps.end(); ++i) { + os << "a=" << mType << ":" << i->pt << " " << i->name << "/" << i->clock; + if (i->channels && ShouldSerializeChannels(i->codec)) { + os << "/" << i->channels; + } + os << CRLF; + } +} + +void +SdpSctpmapAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mSctpmaps.begin(); i != mSctpmaps.end(); ++i) { + os << "a=" << mType << ":" << i->pt << " " << i->name; + if (i->streams) { + os << " " << i->streams; + } + os << CRLF; + } +} + +void +SdpSetupAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mType << ":" << mRole << CRLF; +} + +void +SdpSsrcAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mSsrcs.begin(); i != mSsrcs.end(); ++i) { + os << "a=" << mType << ":" << i->ssrc << " " << i->attribute << CRLF; + } +} + +void +SdpSsrcGroupAttributeList::Serialize(std::ostream& os) const +{ + for (auto i = mSsrcGroups.begin(); i != mSsrcGroups.end(); ++i) { + os << "a=" << mType << ":" << i->semantics; + for (auto j = i->ssrcs.begin(); j != i->ssrcs.end(); ++j) { + os << " " << (*j); + } + os << CRLF; + } +} + +void +SdpMultiStringAttribute::Serialize(std::ostream& os) const +{ + for (auto i = mValues.begin(); i != mValues.end(); ++i) { + os << "a=" << mType << ":" << *i << CRLF; + } +} + +void +SdpOptionsAttribute::Serialize(std::ostream& os) const +{ + if (mValues.empty()) { + return; + } + + os << "a=" << mType << ":"; + + for (auto i = mValues.begin(); i != mValues.end(); ++i) { + if (i != mValues.begin()) { + os << " "; + } + os << *i; + } + os << CRLF; +} + +void +SdpOptionsAttribute::Load(const std::string& value) +{ + size_t start = 0; + size_t end = value.find(' '); + while (end != std::string::npos) { + PushEntry(value.substr(start, end)); + start = end + 1; + end = value.find(' ', start); + } + PushEntry(value.substr(start)); +} + +void +SdpFlagAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mType << CRLF; +} + +void +SdpStringAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mType << ":" << mValue << CRLF; +} + +void +SdpNumberAttribute::Serialize(std::ostream& os) const +{ + os << "a=" << mType << ":" << mValue << CRLF; +} + +bool +SdpAttribute::IsAllowedAtMediaLevel(AttributeType type) +{ + switch (type) { + case kBundleOnlyAttribute: + return true; + case kCandidateAttribute: + return true; + case kConnectionAttribute: + return true; + case kDirectionAttribute: + return true; + case kEndOfCandidatesAttribute: + return true; + case kExtmapAttribute: + return true; + case kFingerprintAttribute: + return true; + case kFmtpAttribute: + return true; + case kGroupAttribute: + return false; + case kIceLiteAttribute: + return false; + case kIceMismatchAttribute: + return true; + // RFC 5245 says this is session-level only, but + // draft-ietf-mmusic-ice-sip-sdp-03 updates this to allow at the media + // level. + case kIceOptionsAttribute: + return true; + case kIcePwdAttribute: + return true; + case kIceUfragAttribute: + return true; + case kIdentityAttribute: + return false; + case kImageattrAttribute: + return true; + case kInactiveAttribute: + return true; + case kLabelAttribute: + return true; + case kMaxptimeAttribute: + return true; + case kMidAttribute: + return true; + case kMsidAttribute: + return true; + case kMsidSemanticAttribute: + return false; + case kPtimeAttribute: + return true; + case kRecvonlyAttribute: + return true; + case kRemoteCandidatesAttribute: + return true; + case kRtcpAttribute: + return true; + case kRtcpFbAttribute: + return true; + case kRtcpMuxAttribute: + return true; + case kRtcpRsizeAttribute: + return true; + case kRtpmapAttribute: + return true; + case kSctpmapAttribute: + return true; + case kSendonlyAttribute: + return true; + case kSendrecvAttribute: + return true; + case kSetupAttribute: + return true; + case kSsrcAttribute: + return true; + case kSsrcGroupAttribute: + return true; + } + MOZ_CRASH("Unknown attribute type"); +} + +bool +SdpAttribute::IsAllowedAtSessionLevel(AttributeType type) +{ + switch (type) { + case kBundleOnlyAttribute: + return false; + case kCandidateAttribute: + return false; + case kConnectionAttribute: + return true; + case kDirectionAttribute: + return true; + case kEndOfCandidatesAttribute: + return true; + case kExtmapAttribute: + return true; + case kFingerprintAttribute: + return true; + case kFmtpAttribute: + return false; + case kGroupAttribute: + return true; + case kIceLiteAttribute: + return true; + case kIceMismatchAttribute: + return false; + case kIceOptionsAttribute: + return true; + case kIcePwdAttribute: + return true; + case kIceUfragAttribute: + return true; + case kIdentityAttribute: + return true; + case kImageattrAttribute: + return false; + case kInactiveAttribute: + return true; + case kLabelAttribute: + return false; + case kMaxptimeAttribute: + return false; + case kMidAttribute: + return false; + case kMsidSemanticAttribute: + return true; + case kMsidAttribute: + return false; + case kPtimeAttribute: + return false; + case kRecvonlyAttribute: + return true; + case kRemoteCandidatesAttribute: + return false; + case kRtcpAttribute: + return false; + case kRtcpFbAttribute: + return false; + case kRtcpMuxAttribute: + return false; + case kRtcpRsizeAttribute: + return false; + case kRtpmapAttribute: + return false; + case kSctpmapAttribute: + return false; + case kSendonlyAttribute: + return true; + case kSendrecvAttribute: + return true; + case kSetupAttribute: + return true; + case kSsrcAttribute: + return false; + case kSsrcGroupAttribute: + return false; + } + MOZ_CRASH("Unknown attribute type"); +} + +const std::string +SdpAttribute::GetAttributeTypeString(AttributeType type) +{ + switch (type) { + case kBundleOnlyAttribute: + return "bundle-only"; + case kCandidateAttribute: + return "candidate"; + case kConnectionAttribute: + return "connection"; + case kEndOfCandidatesAttribute: + return "end-of-candidates"; + case kExtmapAttribute: + return "extmap"; + case kFingerprintAttribute: + return "fingerprint"; + case kFmtpAttribute: + return "fmtp"; + case kGroupAttribute: + return "group"; + case kIceLiteAttribute: + return "ice-lite"; + case kIceMismatchAttribute: + return "ice-mismatch"; + case kIceOptionsAttribute: + return "ice-options"; + case kIcePwdAttribute: + return "ice-pwd"; + case kIceUfragAttribute: + return "ice-ufrag"; + case kIdentityAttribute: + return "identity"; + case kImageattrAttribute: + return "imageattr"; + case kInactiveAttribute: + return "inactive"; + case kLabelAttribute: + return "label"; + case kMaxptimeAttribute: + return "maxptime"; + case kMidAttribute: + return "mid"; + case kMsidAttribute: + return "msid"; + case kMsidSemanticAttribute: + return "msid-semantic"; + case kPtimeAttribute: + return "ptime"; + case kRecvonlyAttribute: + return "recvonly"; + case kRemoteCandidatesAttribute: + return "remote-candidates"; + case kRtcpAttribute: + return "rtcp"; + case kRtcpFbAttribute: + return "rtcp-fb"; + case kRtcpMuxAttribute: + return "rtcp-mux"; + case kRtcpRsizeAttribute: + return "rtcp-rsize"; + case kRtpmapAttribute: + return "rtpmap"; + case kSctpmapAttribute: + return "sctpmap"; + case kSendonlyAttribute: + return "sendonly"; + case kSendrecvAttribute: + return "sendrecv"; + case kSetupAttribute: + return "setup"; + case kSsrcAttribute: + return "ssrc"; + case kSsrcGroupAttribute: + return "ssrc-group"; + case kDirectionAttribute: + MOZ_CRASH("kDirectionAttribute not valid here"); + } + MOZ_CRASH("Unknown attribute type"); +} + +} // namespace mozilla diff --git a/media/webrtc/signaling/src/sdp/SdpAttribute.h b/media/webrtc/signaling/src/sdp/SdpAttribute.h new file mode 100644 index 00000000000..59ffa5c3b4f --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SdpAttribute.h @@ -0,0 +1,1314 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SDPATTRIBUTE_H_ +#define _SDPATTRIBUTE_H_ + +#include +#include +#include +#include +#include + +#include "mozilla/UniquePtr.h" +#include "mozilla/Attributes.h" +#include "mozilla/Assertions.h" + +#include "signaling/src/sdp/SdpEnum.h" + +namespace mozilla +{ + +/** + * Base class for SDP attributes +*/ +class SdpAttribute +{ +public: + enum AttributeType { + kFirstAttribute = 0, + kBundleOnlyAttribute = 0, + kCandidateAttribute, + kConnectionAttribute, + kDirectionAttribute, + kEndOfCandidatesAttribute, + kExtmapAttribute, + kFingerprintAttribute, + kFmtpAttribute, + kGroupAttribute, + kIceLiteAttribute, + kIceMismatchAttribute, + kIceOptionsAttribute, + kIcePwdAttribute, + kIceUfragAttribute, + kIdentityAttribute, + kImageattrAttribute, + kInactiveAttribute, + kLabelAttribute, + kMaxptimeAttribute, + kMidAttribute, + kMsidAttribute, + kMsidSemanticAttribute, + kPtimeAttribute, + kRecvonlyAttribute, + kRemoteCandidatesAttribute, + kRtcpAttribute, + kRtcpFbAttribute, + kRtcpMuxAttribute, + kRtcpRsizeAttribute, + kRtpmapAttribute, + kSctpmapAttribute, + kSendonlyAttribute, + kSendrecvAttribute, + kSetupAttribute, + kSsrcAttribute, + kSsrcGroupAttribute, + kLastAttribute = kSsrcGroupAttribute + }; + + explicit SdpAttribute(AttributeType type) : mType(type) {} + virtual ~SdpAttribute() {} + + AttributeType + GetType() const + { + return mType; + } + + virtual void Serialize(std::ostream&) const = 0; + + static bool IsAllowedAtSessionLevel(AttributeType type); + static bool IsAllowedAtMediaLevel(AttributeType type); + static const std::string GetAttributeTypeString(AttributeType type); + +protected: + AttributeType mType; +}; + +inline std::ostream& operator<<(std::ostream& os, const SdpAttribute& attr) +{ + attr.Serialize(os); + return os; +} + +inline std::ostream& operator<<(std::ostream& os, + const SdpAttribute::AttributeType type) +{ + os << SdpAttribute::GetAttributeTypeString(type); + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=candidate, RFC5245 +//------------------------------------------------------------------------- +// +// candidate-attribute = "candidate" ":" foundation SP component-id SP +// transport SP +// priority SP +// connection-address SP ;from RFC 4566 +// port ;port from RFC 4566 +// SP cand-type +// [SP rel-addr] +// [SP rel-port] +// *(SP extension-att-name SP +// extension-att-value) +// foundation = 1*32ice-char +// component-id = 1*5DIGIT +// transport = "UDP" / transport-extension +// transport-extension = token ; from RFC 3261 +// priority = 1*10DIGIT +// cand-type = "typ" SP candidate-types +// candidate-types = "host" / "srflx" / "prflx" / "relay" / token +// rel-addr = "raddr" SP connection-address +// rel-port = "rport" SP port +// extension-att-name = byte-string ;from RFC 4566 +// extension-att-value = byte-string +// ice-char = ALPHA / DIGIT / "+" / "/" + +// We use a SdpMultiStringAttribute for candidates + +/////////////////////////////////////////////////////////////////////////// +// a=connection, RFC4145 +//------------------------------------------------------------------------- +// connection-attr = "a=connection:" conn-value +// conn-value = "new" / "existing" +class SdpConnectionAttribute : public SdpAttribute +{ +public: + enum ConnValue { kNew, kExisting }; + + explicit SdpConnectionAttribute(SdpConnectionAttribute::ConnValue value) + : SdpAttribute(kConnectionAttribute), mValue(value) + { + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + ConnValue mValue; +}; + +inline std::ostream& operator<<(std::ostream& os, + SdpConnectionAttribute::ConnValue c) +{ + switch (c) { + case SdpConnectionAttribute::kNew: + os << "new"; + break; + case SdpConnectionAttribute::kExisting: + os << "existing"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=sendrecv / a=sendonly / a=recvonly / a=inactive, RFC 4566 +//------------------------------------------------------------------------- +class SdpDirectionAttribute : public SdpAttribute +{ +public: + static const unsigned kSendFlag = 1; + static const unsigned kRecvFlag = 1 << 1; + + enum Direction { + kInactive = 0, + kSendonly = kSendFlag, + kRecvonly = kRecvFlag, + kSendrecv = kSendFlag | kRecvFlag + }; + + explicit SdpDirectionAttribute(Direction value) + : SdpAttribute(kDirectionAttribute), mValue(value) + { + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + Direction mValue; +}; + +inline std::ostream& operator<<(std::ostream& os, + SdpDirectionAttribute::Direction d) +{ + switch (d) { + case SdpDirectionAttribute::kSendonly: + os << "sendonly"; + break; + case SdpDirectionAttribute::kRecvonly: + os << "recvonly"; + break; + case SdpDirectionAttribute::kSendrecv: + os << "sendrecv"; + break; + case SdpDirectionAttribute::kInactive: + os << "inactive"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=extmap, RFC5285 +//------------------------------------------------------------------------- +// RFC5285 +// extmap = mapentry SP extensionname [SP extensionattributes] +// +// extensionname = URI +// +// direction = "sendonly" / "recvonly" / "sendrecv" / "inactive" +// +// mapentry = "extmap:" 1*5DIGIT ["/" direction] +// +// extensionattributes = byte-string +// +// URI = +// +// byte-string = +// +// SP = +// +// DIGIT = +class SdpExtmapAttributeList : public SdpAttribute +{ +public: + SdpExtmapAttributeList() : SdpAttribute(kExtmapAttribute) {} + + struct Extmap { + uint16_t entry; + SdpDirectionAttribute::Direction direction; + bool direction_specified; + std::string extensionname; + std::string extensionattributes; + }; + + void + PushEntry(uint16_t entry, SdpDirectionAttribute::Direction direction, + bool direction_specified, const std::string& extensionname, + const std::string& extensionattributes = "") + { + mExtmaps.push_back({ entry, direction, direction_specified, extensionname, + extensionattributes }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mExtmaps; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=fingerprint, RFC4572 +//------------------------------------------------------------------------- +// fingerprint-attribute = "fingerprint" ":" hash-func SP fingerprint +// +// hash-func = "sha-1" / "sha-224" / "sha-256" / +// "sha-384" / "sha-512" / +// "md5" / "md2" / token +// ; Additional hash functions can only come +// ; from updates to RFC 3279 +// +// fingerprint = 2UHEX *(":" 2UHEX) +// ; Each byte in upper-case hex, separated +// ; by colons. +// +// UHEX = DIGIT / %x41-46 ; A-F uppercase +class SdpFingerprintAttributeList : public SdpAttribute +{ +public: + SdpFingerprintAttributeList() : SdpAttribute(kFingerprintAttribute) {} + + enum HashAlgorithm { + kSha1, + kSha224, + kSha256, + kSha384, + kSha512, + kMd5, + kMd2, + kUnknownAlgorithm + }; + + struct Fingerprint { + HashAlgorithm hashFunc; + std::vector fingerprint; + }; + + // For use by application programmers. Enforces that it's a known and + // non-crazy algorithm. + void + PushEntry(const std::string& algorithm_str, + const std::vector& fingerprint, + bool enforcePlausible = true) + { + SdpFingerprintAttributeList::HashAlgorithm algorithm = + SdpFingerprintAttributeList::kUnknownAlgorithm; + + if (algorithm_str == "sha-1") { + algorithm = SdpFingerprintAttributeList::kSha1; + } else if (algorithm_str == "sha-224") { + algorithm = SdpFingerprintAttributeList::kSha224; + } else if (algorithm_str == "sha-256") { + algorithm = SdpFingerprintAttributeList::kSha256; + } else if (algorithm_str == "sha-384") { + algorithm = SdpFingerprintAttributeList::kSha384; + } else if (algorithm_str == "sha-512") { + algorithm = SdpFingerprintAttributeList::kSha512; + } else if (algorithm_str == "md5") { + algorithm = SdpFingerprintAttributeList::kMd5; + } else if (algorithm_str == "md2") { + algorithm = SdpFingerprintAttributeList::kMd2; + } + + if ((algorithm == SdpFingerprintAttributeList::kUnknownAlgorithm) || + fingerprint.empty()) { + if (enforcePlausible) { + MOZ_ASSERT(false, "Unknown fingerprint algorithm"); + } else { + return; + } + } + + PushEntry(algorithm, fingerprint); + } + + void + PushEntry(HashAlgorithm hashFunc, const std::vector& fingerprint) + { + mFingerprints.push_back({ hashFunc, fingerprint }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mFingerprints; + + static std::string FormatFingerprint(const std::vector& fp); + static std::vector ParseFingerprint(const std::string& str); +}; + +inline std::ostream& operator<<(std::ostream& os, + SdpFingerprintAttributeList::HashAlgorithm a) +{ + switch (a) { + case SdpFingerprintAttributeList::kSha1: + os << "sha-1"; + break; + case SdpFingerprintAttributeList::kSha224: + os << "sha-224"; + break; + case SdpFingerprintAttributeList::kSha256: + os << "sha-256"; + break; + case SdpFingerprintAttributeList::kSha384: + os << "sha-384"; + break; + case SdpFingerprintAttributeList::kSha512: + os << "sha-512"; + break; + case SdpFingerprintAttributeList::kMd5: + os << "md5"; + break; + case SdpFingerprintAttributeList::kMd2: + os << "md2"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=group, RFC5888 +//------------------------------------------------------------------------- +// group-attribute = "a=group:" semantics +// *(SP identification-tag) +// semantics = "LS" / "FID" / semantics-extension +// semantics-extension = token +// identification-tag = token +class SdpGroupAttributeList : public SdpAttribute +{ +public: + SdpGroupAttributeList() : SdpAttribute(kGroupAttribute) {} + + enum Semantics { + kLs, // RFC5888 + kFid, // RFC5888 + kSrf, // RFC3524 + kAnat, // RFC4091 + kFec, // RFC5956 + kFecFr, // RFC5956 + kCs, // draft-mehta-rmt-flute-sdp-05 + kDdp, // RFC5583 + kDup, // RFC7104 + kBundle // draft-ietf-mmusic-bundle + }; + + struct Group { + Semantics semantics; + std::vector tags; + }; + + void + PushEntry(Semantics semantics, const std::vector& tags) + { + mGroups.push_back({ semantics, tags }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mGroups; +}; + +inline std::ostream& operator<<(std::ostream& os, + SdpGroupAttributeList::Semantics s) +{ + switch (s) { + case SdpGroupAttributeList::kLs: + os << "LS"; + break; + case SdpGroupAttributeList::kFid: + os << "FID"; + break; + case SdpGroupAttributeList::kSrf: + os << "SRF"; + break; + case SdpGroupAttributeList::kAnat: + os << "ANAT"; + break; + case SdpGroupAttributeList::kFec: + os << "FEC"; + break; + case SdpGroupAttributeList::kFecFr: + os << "FEC-FR"; + break; + case SdpGroupAttributeList::kCs: + os << "CS"; + break; + case SdpGroupAttributeList::kDdp: + os << "DDP"; + break; + case SdpGroupAttributeList::kDup: + os << "DUP"; + break; + case SdpGroupAttributeList::kBundle: + os << "BUNDLE"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=identity, draft-ietf-rtcweb-security-arch +//------------------------------------------------------------------------- +// identity-attribute = "identity:" identity-assertion +// [ SP identity-extension +// *(";" [ SP ] identity-extension) ] +// identity-assertion = base64 +// base64 = 1*(ALPHA / DIGIT / "+" / "/" / "=" ) +// identity-extension = extension-att-name [ "=" extension-att-value ] +// extension-att-name = token +// extension-att-value = 1*(%x01-09 / %x0b-0c / %x0e-3a / %x3c-ff) +// ; byte-string from [RFC4566] omitting ";" + +// We're just using an SdpStringAttribute for this right now +#if 0 +class SdpIdentityAttribute : public SdpAttribute +{ +public: + explicit SdpIdentityAttribute(const std::string &assertion, + const std::vector &extensions = + std::vector()) : + SdpAttribute(kIdentityAttribute), + mAssertion(assertion), + mExtensions(extensions) {} + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::string mAssertion; + std::vector mExtensions; +} +#endif + +/////////////////////////////////////////////////////////////////////////// +// a=imageattr, RFC6236 +//------------------------------------------------------------------------- +// image-attr = "imageattr:" PT 1*2( 1*WSP ( "send" / "recv" ) +// 1*WSP attr-list ) +// PT = 1*DIGIT / "*" +// attr-list = ( set *(1*WSP set) ) / "*" +// ; WSP and DIGIT defined in [RFC5234] +// +// set= "[" "x=" xyrange "," "y=" xyrange *( "," key-value ) "]" +// ; x is the horizontal image size range (pixel count) +// ; y is the vertical image size range (pixel count) +// +// key-value = ( "sar=" srange ) +// / ( "par=" prange ) +// / ( "q=" qvalue ) +// ; Key-value MAY be extended with other keyword +// ; parameters. +// ; At most, one instance each of sar, par, or q +// ; is allowed in a set. +// ; +// ; sar (sample aspect ratio) is the sample aspect ratio +// ; associated with the set (optional, MAY be ignored) +// ; par (picture aspect ratio) is the allowed +// ; ratio between the display's x and y physical +// ; size (optional) +// ; q (optional, range [0.0..1.0], default value 0.5) +// ; is the preference for the given set, +// ; a higher value means a higher preference +// +// onetonine = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" +// ; Digit between 1 and 9 +// xyvalue = onetonine *5DIGIT +// ; Digit between 1 and 9 that is +// ; followed by 0 to 5 other digits +// step = xyvalue +// xyrange = ( "[" xyvalue ":" [ step ":" ] xyvalue "]" ) +// ; Range between a lower and an upper value +// ; with an optional step, default step = 1 +// ; The rightmost occurrence of xyvalue MUST have a +// ; higher value than the leftmost occurrence. +// / ( "[" xyvalue 1*( "," xyvalue ) "]" ) +// ; Discrete values separated by ',' +// / ( xyvalue ) +// ; A single value +// spvalue = ( "0" "." onetonine *3DIGIT ) +// ; Values between 0.1000 and 0.9999 +// / ( onetonine "." 1*4DIGIT ) +// ; Values between 1.0000 and 9.9999 +// srange = ( "[" spvalue 1*( "," spvalue ) "]" ) +// ; Discrete values separated by ','. +// ; Each occurrence of spvalue MUST be +// ; greater than the previous occurrence. +// / ( "[" spvalue "-" spvalue "]" ) +// ; Range between a lower and an upper level (inclusive) +// ; The second occurrence of spvalue MUST have a higher +// ; value than the first +// / ( spvalue ) +// ; A single value +// +// prange = ( "[" spvalue "-" spvalue "]" ) +// ; Range between a lower and an upper level (inclusive) +// ; The second occurrence of spvalue MUST have a higher +// ; value than the first +// +// qvalue = ( "0" "." 1*2DIGIT ) +// / ( "1" "." 1*2("0") ) +// ; Values between 0.00 and 1.00 +// +// XXX TBD -- We don't use this yet, and it's a project unto itself. +// + +class SdpImageattrAttributeList : public SdpAttribute +{ +public: + SdpImageattrAttributeList() : SdpAttribute(kImageattrAttribute) {} + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=msid, draft-ietf-mmusic-msid +//------------------------------------------------------------------------- +// msid-attr = "msid:" identifier [ SP appdata ] +// identifier = 1*64token-char ; see RFC 4566 +// appdata = 1*64token-char ; see RFC 4566 +class SdpMsidAttributeList : public SdpAttribute +{ +public: + SdpMsidAttributeList() : SdpAttribute(kMsidAttribute) {} + + struct Msid { + std::string identifier; + std::string appdata; + }; + + void + PushEntry(const std::string& identifier, const std::string& appdata = "") + { + mMsids.push_back({ identifier, appdata }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mMsids; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=remote-candiate, RFC5245 +//------------------------------------------------------------------------- +// remote-candidate-att = "remote-candidates" ":" remote-candidate +// 0*(SP remote-candidate) +// remote-candidate = component-ID SP connection-address SP port +class SdpRemoteCandidatesAttribute : public SdpAttribute +{ +public: + struct Candidate { + std::string id; + std::string address; + uint16_t port; + }; + + explicit SdpRemoteCandidatesAttribute( + const std::vector& candidates) + : SdpAttribute(kRemoteCandidatesAttribute), mCandidates(candidates) + { + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mCandidates; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=rtcp, RFC3605 +//------------------------------------------------------------------------- +// rtcp-attribute = "a=rtcp:" port [nettype space addrtype space +// connection-address] CRLF +class SdpRtcpAttribute : public SdpAttribute +{ +public: + explicit SdpRtcpAttribute(uint16_t port, + sdp::NetType netType = sdp::kNetTypeNone, + sdp::AddrType addrType = sdp::kAddrTypeNone, + const std::string& address = "") + : SdpAttribute(kRtcpAttribute), + mPort(port), + mNetType(netType), + mAddrType(addrType), + mAddress(address) + { + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + uint16_t mPort; + sdp::NetType mNetType; + sdp::AddrType mAddrType; + std::string mAddress; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=rtcp-fb, RFC4585 +//------------------------------------------------------------------------- +// rtcp-fb-syntax = "a=rtcp-fb:" rtcp-fb-pt SP rtcp-fb-val CRLF +// +// rtcp-fb-pt = "*" ; wildcard: applies to all formats +// / fmt ; as defined in SDP spec +// +// rtcp-fb-val = "ack" rtcp-fb-ack-param +// / "nack" rtcp-fb-nack-param +// / "trr-int" SP 1*DIGIT +// / rtcp-fb-id rtcp-fb-param +// +// rtcp-fb-id = 1*(alpha-numeric / "-" / "_") +// +// rtcp-fb-param = SP "app" [SP byte-string] +// / SP token [SP byte-string] +// / ; empty +// +// rtcp-fb-ack-param = SP "rpsi" +// / SP "app" [SP byte-string] +// / SP token [SP byte-string] +// / ; empty +// +// rtcp-fb-nack-param = SP "pli" +// / SP "sli" +// / SP "rpsi" +// / SP "app" [SP byte-string] +// / SP token [SP byte-string] +// / ; empty +// +class SdpRtcpFbAttributeList : public SdpAttribute +{ +public: + SdpRtcpFbAttributeList() : SdpAttribute(kRtcpFbAttribute) {} + + enum Type { kAck, kApp, kCcm, kNack, kTrrInt }; + + static const char* pli; + static const char* sli; + static const char* rpsi; + static const char* app; + + static const char* fir; + static const char* tmmbr; + static const char* tstr; + static const char* vbcm; + + struct Feedback { + std::string pt; + Type type; + std::string parameter; + std::string extra; + }; + + void + PushEntry(const std::string& pt, Type type, const std::string& parameter = "", + const std::string& extra = "") + { + mFeedbacks.push_back({ pt, type, parameter, extra }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mFeedbacks; +}; + +inline std::ostream& operator<<(std::ostream& os, + SdpRtcpFbAttributeList::Type type) +{ + switch (type) { + case SdpRtcpFbAttributeList::kAck: + os << "ack"; + break; + case SdpRtcpFbAttributeList::kApp: + os << "app"; + break; + case SdpRtcpFbAttributeList::kCcm: + os << "ccm"; + break; + case SdpRtcpFbAttributeList::kNack: + os << "nack"; + break; + case SdpRtcpFbAttributeList::kTrrInt: + os << "trr-int"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=rtpmap, RFC4566 +//------------------------------------------------------------------------- +// a=rtpmap: / [/] +class SdpRtpmapAttributeList : public SdpAttribute +{ +public: + SdpRtpmapAttributeList() : SdpAttribute(kRtpmapAttribute) {} + + // Minimal set to get going + enum CodecType { + kOpus, + kG722, + kPCMU, + kPCMA, + kVP8, + kVP9, + kiLBC, + kiSAC, + kH264, + kOtherCodec + }; + + struct Rtpmap { + std::string pt; + CodecType codec; + std::string name; + uint32_t clock; + // Technically, this could mean something else in the future. + // In practice, that's probably not going to happen. + uint32_t channels; + }; + + void + PushEntry(const std::string& pt, CodecType codec, const std::string& name, + uint32_t clock, uint32_t channels = 0) + { + mRtpmaps.push_back({ pt, codec, name, clock, channels }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + bool + HasEntry(const std::string& pt) const + { + for (auto it = mRtpmaps.begin(); it != mRtpmaps.end(); ++it) { + if (it->pt == pt) { + return true; + } + } + return false; + } + + const Rtpmap& + GetEntry(const std::string& pt) const + { + for (auto it = mRtpmaps.begin(); it != mRtpmaps.end(); ++it) { + if (it->pt == pt) { + return *it; + } + } + MOZ_CRASH(); + } + + std::vector mRtpmaps; +}; + +inline std::ostream& operator<<(std::ostream& os, + SdpRtpmapAttributeList::CodecType c) +{ + switch (c) { + case SdpRtpmapAttributeList::kOpus: + os << "opus"; + break; + case SdpRtpmapAttributeList::kG722: + os << "G722"; + break; + case SdpRtpmapAttributeList::kPCMU: + os << "PCMU"; + break; + case SdpRtpmapAttributeList::kPCMA: + os << "PCMA"; + break; + case SdpRtpmapAttributeList::kVP8: + os << "VP8"; + break; + case SdpRtpmapAttributeList::kVP9: + os << "VP9"; + break; + case SdpRtpmapAttributeList::kiLBC: + os << "iLBC"; + break; + case SdpRtpmapAttributeList::kiSAC: + os << "iSAC"; + break; + case SdpRtpmapAttributeList::kH264: + os << "H264"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=fmtp, RFC4566, RFC5576 +//------------------------------------------------------------------------- +// a=fmtp: +// +class SdpFmtpAttributeList : public SdpAttribute +{ +public: + SdpFmtpAttributeList() : SdpAttribute(kFmtpAttribute) {} + + // Base class for format parameters + class Parameters + { + public: + explicit Parameters(SdpRtpmapAttributeList::CodecType aCodec) + : codec_type(aCodec) + { + } + + virtual ~Parameters() {} + virtual Parameters* Clone() const = 0; + virtual void Serialize(std::ostream& os) const = 0; + + SdpRtpmapAttributeList::CodecType codec_type; + }; + + class H264Parameters : public Parameters + { + public: + H264Parameters() + : Parameters(SdpRtpmapAttributeList::kH264), + packetization_mode(0), + level_asymmetry_allowed(false), + profile_level_id(0), + max_mbps(0), + max_fs(0), + max_cpb(0), + max_dpb(0), + max_br(0) + { + memset(sprop_parameter_sets, 0, sizeof(sprop_parameter_sets)); + } + + virtual Parameters* + Clone() const MOZ_OVERRIDE + { + return new H264Parameters(*this); + } + + virtual void + Serialize(std::ostream& os) const MOZ_OVERRIDE + { + // Note: don't move this, since having an unconditional param up top + // lets us avoid a whole bunch of conditional streaming of ';' below + os << "profile-level-id=" << std::hex << std::setfill('0') << std::setw(6) + << profile_level_id << std::dec << std::setfill(' '); + + os << ";level-asymmetry-allowed=" << (level_asymmetry_allowed ? 1 : 0); + + if (strlen(sprop_parameter_sets)) { + os << ";sprop-parameter-sets=" << sprop_parameter_sets; + } + + if (packetization_mode != 0) { + os << ";packetization-mode=" << packetization_mode; + } + + if (max_mbps != 0) { + os << ";max-mbps=" << max_mbps; + } + + if (max_fs != 0) { + os << ";max-fs=" << max_fs; + } + + if (max_cpb != 0) { + os << ";max-cpb=" << max_cpb; + } + + if (max_dpb != 0) { + os << ";max-dpb=" << max_dpb; + } + + if (max_br != 0) { + os << ";max-br=" << max_br; + } + } + + static const size_t max_sprop_len = 128; + char sprop_parameter_sets[max_sprop_len]; + unsigned int packetization_mode; + bool level_asymmetry_allowed; + unsigned int profile_level_id; + unsigned int max_mbps; + unsigned int max_fs; + unsigned int max_cpb; + unsigned int max_dpb; + unsigned int max_br; + }; + + class VP8Parameters : public Parameters + { + public: + VP8Parameters() + : Parameters(SdpRtpmapAttributeList::kVP8), max_fs(0), max_fr(0) + { + } + + virtual Parameters* + Clone() const MOZ_OVERRIDE + { + return new VP8Parameters(*this); + } + + virtual void + Serialize(std::ostream& os) const MOZ_OVERRIDE + { + // draft-ietf-payload-vp8-11 says these are mandatory, upper layer + // needs to ensure they're set properly. + os << "max-fs=" << max_fs; + os << ";max-fr=" << max_fr; + } + + unsigned int max_fs; + unsigned int max_fr; + }; + + class Fmtp + { + public: + Fmtp(const std::string& aFormat, const std::string& aParametersString, + UniquePtr aParameters) + : format(aFormat), + parameters_string(aParametersString), + parameters(Move(aParameters)) + { + } + + // TODO: Rip all of this out when we have move semantics in the stl. + Fmtp(const Fmtp& orig) { *this = orig; } + + Fmtp& operator=(const Fmtp& rhs) + { + if (this != &rhs) { + format = rhs.format; + parameters_string = rhs.parameters_string; + parameters.reset(rhs.parameters ? rhs.parameters->Clone() : nullptr); + } + return *this; + } + + // The contract around these is as follows: + // * |format| and |parameters_string| are always set + // * |parameters| is only set if we recognized the media type and had + // a subclass of Parameters to represent that type of parameters + // * |parameters| is a best-effort representation; it might be missing + // stuff + // * if |parameters| is set, it determines the serialized form, + // otherwise |parameters_string| is used + // * Parameters::codec_type tells you the concrete class, eg + // kH264 -> H264Parameters + std::string format; + std::string parameters_string; + UniquePtr parameters; + }; + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + void + PushEntry(const std::string& format, const std::string& parameters_string, + UniquePtr parameters) + { + mFmtps.push_back(Fmtp(format, parameters_string, Move(parameters))); + } + + std::vector mFmtps; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=sctpmap, draft-ietf-mmusic-sctp-sdp-05 +//------------------------------------------------------------------------- +// sctpmap-attr = "a=sctpmap:" sctpmap-number media-subtypes +// [streams] +// sctpmap-number = 1*DIGIT +// protocol = labelstring +// labelstring = text +// text = byte-string +// streams = 1*DIGIT +// +// We're going to pretend that there are spaces where they make sense. +// +// (draft-06 is not backward compatabile and draft-07 replaced sctpmap's with +// fmtp maps - we should carefully choose when to upgrade) +class SdpSctpmapAttributeList : public SdpAttribute +{ +public: + SdpSctpmapAttributeList() : SdpAttribute(kSctpmapAttribute) {} + + struct Sctpmap { + std::string pt; + std::string name; + uint32_t streams; + }; + + void + PushEntry(const std::string& pt, const std::string& name, + uint32_t streams = 0) + { + mSctpmaps.push_back({ pt, name, streams }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + bool + HasEntry(const std::string& pt) const + { + for (auto it = mSctpmaps.begin(); it != mSctpmaps.end(); ++it) { + if (it->pt == pt) { + return true; + } + } + return false; + } + + const Sctpmap& + GetEntry(const std::string& pt) const + { + for (auto it = mSctpmaps.begin(); it != mSctpmaps.end(); ++it) { + if (it->pt == pt) { + return *it; + } + } + MOZ_CRASH(); + } + + std::vector mSctpmaps; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=setup, RFC4145 +//------------------------------------------------------------------------- +// setup-attr = "a=setup:" role +// role = "active" / "passive" / "actpass" / "holdconn" +class SdpSetupAttribute : public SdpAttribute +{ +public: + enum Role { kActive, kPassive, kActpass, kHoldconn }; + + explicit SdpSetupAttribute(Role role) + : SdpAttribute(kSetupAttribute), mRole(role) + { + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + Role mRole; +}; + +inline std::ostream& operator<<(std::ostream& os, SdpSetupAttribute::Role r) +{ + switch (r) { + case SdpSetupAttribute::kActive: + os << "active"; + break; + case SdpSetupAttribute::kPassive: + os << "passive"; + break; + case SdpSetupAttribute::kActpass: + os << "actpass"; + break; + case SdpSetupAttribute::kHoldconn: + os << "holdconn"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// a=ssrc, RFC5576 +//------------------------------------------------------------------------- +// ssrc-attr = "ssrc:" ssrc-id SP attribute +// ; The base definition of "attribute" is in RFC 4566. +// ; (It is the content of "a=" lines.) +// +// ssrc-id = integer ; 0 .. 2**32 - 1 +//------------------------------------------------------------------------- +// TODO -- In the future, it might be nice if we ran a parse on the +// attribute section of this so that we could interpret it semantically. +// For WebRTC, the key use case for a=ssrc is assocaiting SSRCs with +// media sections, and we're not really going to care about the attribute +// itself. So we're just going to store it as a string for the time being. +// Issue 187. +class SdpSsrcAttributeList : public SdpAttribute +{ +public: + SdpSsrcAttributeList() : SdpAttribute(kSsrcAttribute) {} + + struct Ssrc { + uint32_t ssrc; + std::string attribute; + }; + + void + PushEntry(uint32_t ssrc, const std::string& attribute) + { + mSsrcs.push_back({ ssrc, attribute }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mSsrcs; +}; + +/////////////////////////////////////////////////////////////////////////// +// a=ssrc-group, RFC5576 +//------------------------------------------------------------------------- +// ssrc-group-attr = "ssrc-group:" semantics *(SP ssrc-id) +// +// semantics = "FEC" / "FID" / token +// +// ssrc-id = integer ; 0 .. 2**32 - 1 +class SdpSsrcGroupAttributeList : public SdpAttribute +{ +public: + enum Semantics { + kFec, // RFC5576 + kFid, // RFC5576 + kFecFr, // RFC5956 + kDup // RFC7104 + }; + + struct SsrcGroup { + Semantics semantics; + std::vector ssrcs; + }; + + SdpSsrcGroupAttributeList() : SdpAttribute(kSsrcGroupAttribute) {} + + void + PushEntry(Semantics semantics, const std::vector& ssrcs) + { + mSsrcGroups.push_back({ semantics, ssrcs }); + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::vector mSsrcGroups; +}; + +inline std::ostream& operator<<(std::ostream& os, + SdpSsrcGroupAttributeList::Semantics s) +{ + switch (s) { + case SdpSsrcGroupAttributeList::kFec: + os << "FEC"; + break; + case SdpSsrcGroupAttributeList::kFid: + os << "FID"; + break; + case SdpSsrcGroupAttributeList::kFecFr: + os << "FEC-FR"; + break; + case SdpSsrcGroupAttributeList::kDup: + os << "DUP"; + break; + default: + MOZ_ASSERT(false); + os << "?"; + } + return os; +} + +/////////////////////////////////////////////////////////////////////////// +class SdpMultiStringAttribute : public SdpAttribute +{ +public: + explicit SdpMultiStringAttribute(AttributeType type) : SdpAttribute(type) {} + + void + PushEntry(const std::string& entry) + { + mValues.push_back(entry); + } + + virtual void Serialize(std::ostream& os) const; + + std::vector mValues; +}; + +// otherwise identical to SdpMultiStringAttribute, this is used for +// ice-options and other places where the value is serialized onto +// a single line with space separating tokens +class SdpOptionsAttribute : public SdpAttribute +{ +public: + explicit SdpOptionsAttribute(AttributeType type) : SdpAttribute(type) {} + + void + PushEntry(const std::string& entry) + { + mValues.push_back(entry); + } + + void Load(const std::string& value); + + virtual void Serialize(std::ostream& os) const; + + std::vector mValues; +}; + +// Used for attributes that take no value (eg; a=ice-lite) +class SdpFlagAttribute : public SdpAttribute +{ +public: + explicit SdpFlagAttribute(AttributeType type) : SdpAttribute(type) {} + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; +}; + +// Used for any other kind of single-valued attribute not otherwise specialized +class SdpStringAttribute : public SdpAttribute +{ +public: + explicit SdpStringAttribute(AttributeType type, const std::string& value) + : SdpAttribute(type), mValue(value) + { + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + std::string mValue; +}; + +// Used for any purely (non-negative) numeric attribute +class SdpNumberAttribute : public SdpAttribute +{ +public: + explicit SdpNumberAttribute(AttributeType type, uint32_t value = 0) + : SdpAttribute(type), mValue(value) + { + } + + virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE; + + uint32_t mValue; +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/sdp/SdpAttributeList.h b/media/webrtc/signaling/src/sdp/SdpAttributeList.h new file mode 100644 index 00000000000..4343efb9650 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SdpAttributeList.h @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SDPATTRIBUTELIST_H_ +#define _SDPATTRIBUTELIST_H_ + +#include "mozilla/UniquePtr.h" +#include "mozilla/Attributes.h" + +#include "signaling/src/sdp/SdpAttribute.h" + +namespace mozilla +{ + +class SdpAttributeList +{ +public: + typedef SdpAttribute::AttributeType AttributeType; + + // Avoid default params on virtual functions + bool + HasAttribute(AttributeType type) const + { + return HasAttribute(type, true); + } + + const SdpAttribute* + GetAttribute(AttributeType type) const + { + return GetAttribute(type, true); + } + + virtual bool HasAttribute(AttributeType type, bool sessionFallback) const = 0; + virtual const SdpAttribute* GetAttribute(AttributeType type, + bool sessionFallback) const = 0; + // The setter takes an attribute of any type, and takes ownership + virtual void SetAttribute(SdpAttribute* attr) = 0; + virtual void RemoveAttribute(AttributeType type) = 0; + virtual void Clear() = 0; + + virtual const SdpConnectionAttribute& GetConnection() const = 0; + virtual const SdpOptionsAttribute& GetIceOptions() const = 0; + virtual const SdpRtcpAttribute& GetRtcp() const = 0; + virtual const SdpRemoteCandidatesAttribute& GetRemoteCandidates() const = 0; + virtual const SdpSetupAttribute& GetSetup() const = 0; + + // These attributes can appear multiple times, so the returned + // classes actually represent a collection of values. + virtual const std::vector& GetCandidate() const = 0; + virtual const SdpExtmapAttributeList& GetExtmap() const = 0; + virtual const SdpFingerprintAttributeList& GetFingerprint() const = 0; + virtual const SdpFmtpAttributeList& GetFmtp() const = 0; + virtual const SdpGroupAttributeList& GetGroup() const = 0; + virtual const SdpImageattrAttributeList& GetImageattr() const = 0; + virtual const SdpMsidAttributeList& GetMsid() const = 0; + virtual const SdpRtcpFbAttributeList& GetRtcpFb() const = 0; + virtual const SdpRtpmapAttributeList& GetRtpmap() const = 0; + virtual const SdpSctpmapAttributeList& GetSctpmap() const = 0; + virtual const SdpSsrcAttributeList& GetSsrc() const = 0; + virtual const SdpSsrcGroupAttributeList& GetSsrcGroup() const = 0; + + // These attributes are effectively simple types, so we'll make life + // easy by just returning their value. + virtual const std::string& GetIcePwd() const = 0; + virtual const std::string& GetIceUfrag() const = 0; + virtual const std::string& GetIdentity() const = 0; + virtual const std::string& GetLabel() const = 0; + virtual unsigned int GetMaxptime() const = 0; + virtual const std::string& GetMid() const = 0; + virtual const std::string& GetMsidSemantic() const = 0; + virtual unsigned int GetPtime() const = 0; + + // This is "special", because it's multiple things + virtual SdpDirectionAttribute::Direction GetDirection() const = 0; + + virtual void Serialize(std::ostream&) const = 0; +}; + +inline std::ostream& operator<<(std::ostream& os, const SdpAttributeList& al) +{ + al.Serialize(os); + return os; +} + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/sdp/SdpEnum.h b/media/webrtc/signaling/src/sdp/SdpEnum.h new file mode 100644 index 00000000000..0a90b30b15d --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SdpEnum.h @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SDPENUM_H_ +#define _SDPENUM_H_ + +#include + +#include "mozilla/Assertions.h" + +namespace mozilla +{ +namespace sdp +{ + +enum NetType { kNetTypeNone, kInternet }; + +inline std::ostream& operator<<(std::ostream& os, sdp::NetType t) +{ + switch (t) { + case sdp::kNetTypeNone: + MOZ_ASSERT(false); + return os << "NONE"; + case sdp::kInternet: + return os << "IN"; + } + MOZ_CRASH("Unknown NetType"); +} + +enum AddrType { kAddrTypeNone, kIPv4, kIPv6 }; + +inline std::ostream& operator<<(std::ostream& os, sdp::AddrType t) +{ + switch (t) { + case sdp::kAddrTypeNone: + MOZ_ASSERT(false); + return os << "NONE"; + case sdp::kIPv4: + return os << "IP4"; + case sdp::kIPv6: + return os << "IP6"; + } + MOZ_CRASH("Unknown AddrType"); +} + +} // namespace sdp + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/sdp/SdpErrorHolder.h b/media/webrtc/signaling/src/sdp/SdpErrorHolder.h new file mode 100644 index 00000000000..556fcefb68f --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SdpErrorHolder.h @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SDPERRORHOLDER_H_ +#define _SDPERRORHOLDER_H_ + +#include +#include + +namespace mozilla +{ + +class SdpErrorHolder +{ +public: + SdpErrorHolder() {} + virtual ~SdpErrorHolder() {} + + void + AddParseError(size_t line, const std::string& message) + { + mErrors.push_back(std::make_pair(line, message)); + } + + void + ClearParseErrors() + { + mErrors.clear(); + } + + /** + * Returns a reference to the list of parse errors. + * This gets cleared out when you call Parse. + */ + const std::vector >& + GetParseErrors() const + { + return mErrors; + } + +private: + std::vector > mErrors; +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/sdp/SdpMediaSection.h b/media/webrtc/signaling/src/sdp/SdpMediaSection.h new file mode 100644 index 00000000000..440cb180b77 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SdpMediaSection.h @@ -0,0 +1,284 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SDPMEDIASECTION_H_ +#define _SDPMEDIASECTION_H_ + +#include "mozilla/Maybe.h" +#include "signaling/src/sdp/SdpEnum.h" +#include "signaling/src/sdp/SdpAttributeList.h" +#include +#include + +#include "signaling/src/sdp/SdpEnum.h" + +namespace mozilla +{ + +class SdpAttributeList; + +class SdpConnection; + +class SdpMediaSection +{ +public: + enum MediaType { kAudio, kVideo, kText, kApplication, kMessage }; + + enum Protocol { + kRtpAvp, // RTP/AVP [RFC4566] + kUdp, // udp [RFC4566] + kVat, // vat [historic] + kRtp, // rtp [historic] + kUdptl, // udptl [ITU-T] + kTcp, // TCP [RFC4145] + kRtpAvpf, // RTP/AVPF [RFC4585] + kTcpRtpAvp, // TCP/RTP/AVP [RFC4571] + kRtpSavp, // RTP/SAVP [RFC3711] + kTcpBfcp, // TCP/BFCP [RFC4583] + kTcpTlsBfcp, // TCP/TLS/BFCP [RFC4583] + kTcpTls, // TCP/TLS [RFC4572] + kFluteUdp, // FLUTE/UDP [RFC-mehta-rmt-flute-sdp-05] + kTcpMsrp, // TCP/MSRP [RFC4975] + kTcpTlsMsrp, // TCP/TLS/MSRP [RFC4975] + kDccp, // DCCP [RFC5762] + kDccpRtpAvp, // DCCP/RTP/AVP [RFC5762] + kDccpRtpSavp, // DCCP/RTP/SAVP [RFC5762] + kDccpRtpAvpf, // DCCP/RTP/AVPF [RFC5762] + kDccpRtpSavpf, // DCCP/RTP/SAVPF [RFC5762] + kRtpSavpf, // RTP/SAVPF [RFC5124] + kUdpTlsRtpSavp, // UDP/TLS/RTP/SAVP [RFC5764] + kTcpTlsRtpSavp, // TCP/TLS/RTP/SAVP [JSEP-TBD] + kDccpTlsRtpSavp, // DCCP/TLS/RTP/SAVP [RFC5764] + kUdpTlsRtpSavpf, // UDP/TLS/RTP/SAVPF [RFC5764] + kTcpTlsRtpSavpf, // TCP/TLS/RTP/SAVPF [JSEP-TBD] + kDccpTlsRtpSavpf, // DCCP/TLS/RTP/SAVPF [RFC5764] + kUdpMbmsFecRtpAvp, // UDP/MBMS-FEC/RTP/AVP [RFC6064] + kUdpMbmsFecRtpSavp, // UDP/MBMS-FEC/RTP/SAVP [RFC6064] + kUdpMbmsRepair, // UDP/MBMS-REPAIR [RFC6064] + kFecUdp, // FEC/UDP [RFC6364] + kUdpFec, // UDP/FEC [RFC6364] + kTcpMrcpv2, // TCP/MRCPv2 [RFC6787] + kTcpTlsMrcpv2, // TCP/TLS/MRCPv2 [RFC6787] + kPstn, // PSTN [RFC7195] + kUdpTlsUdptl, // UDP/TLS/UDPTL [RFC7345] + kSctp, // SCTP [draft-ietf-mmusic-sctp-sdp-07] + kSctpDtls, // SCTP/DTLS [draft-ietf-mmusic-sctp-sdp-07] + kDtlsSctp // DTLS/SCTP [draft-ietf-mmusic-sctp-sdp-07] + }; + + explicit SdpMediaSection(size_t level) : mLevel(level) {} + + virtual MediaType GetMediaType() const = 0; + virtual unsigned int GetPort() const = 0; + virtual void SetPort(unsigned int port) = 0; + virtual unsigned int GetPortCount() const = 0; + virtual Protocol GetProtocol() const = 0; + virtual const SdpConnection& GetConnection() const = 0; + virtual SdpConnection& GetConnection() = 0; + virtual uint32_t GetBandwidth(const std::string& type) const = 0; + virtual const std::vector& GetFormats() const = 0; + + virtual const SdpAttributeList& GetAttributeList() const = 0; + virtual SdpAttributeList& GetAttributeList() = 0; + + virtual SdpDirectionAttribute GetDirectionAttribute() const = 0; + + virtual void Serialize(std::ostream&) const = 0; + + virtual void AddCodec(const std::string& pt, const std::string& name, + uint32_t clockrate, uint16_t channels) = 0; + + virtual void AddDataChannel(const std::string& pt, const std::string& name, + uint16_t streams) = 0; + + size_t + GetLevel() const + { + return mLevel; + } + +private: + size_t mLevel; +}; + +inline std::ostream& operator<<(std::ostream& os, const SdpMediaSection& ms) +{ + ms.Serialize(os); + return os; +} + +inline std::ostream& operator<<(std::ostream& os, SdpMediaSection::MediaType t) +{ + switch (t) { + case SdpMediaSection::kAudio: + return os << "audio"; + case SdpMediaSection::kVideo: + return os << "video"; + case SdpMediaSection::kText: + return os << "text"; + case SdpMediaSection::kApplication: + return os << "application"; + case SdpMediaSection::kMessage: + return os << "message"; + } + MOZ_ASSERT(false, "Unknown MediaType"); + return os << "?"; +} + +inline std::ostream& operator<<(std::ostream& os, SdpMediaSection::Protocol p) +{ + switch (p) { + case SdpMediaSection::kRtpAvp: + return os << "RTP/AVP"; + case SdpMediaSection::kUdp: + return os << "udp"; + case SdpMediaSection::kVat: + return os << "vat"; + case SdpMediaSection::kRtp: + return os << "rtp"; + case SdpMediaSection::kUdptl: + return os << "udptl"; + case SdpMediaSection::kTcp: + return os << "TCP"; + case SdpMediaSection::kRtpAvpf: + return os << "RTP/AVPF"; + case SdpMediaSection::kTcpRtpAvp: + return os << "TCP/RTP/AVP"; + case SdpMediaSection::kRtpSavp: + return os << "RTP/SAVP"; + case SdpMediaSection::kTcpBfcp: + return os << "TCP/BFCP"; + case SdpMediaSection::kTcpTlsBfcp: + return os << "TCP/TLS/BFCP"; + case SdpMediaSection::kTcpTls: + return os << "TCP/TLS"; + case SdpMediaSection::kFluteUdp: + return os << "FLUTE/UDP"; + case SdpMediaSection::kTcpMsrp: + return os << "TCP/MSRP"; + case SdpMediaSection::kTcpTlsMsrp: + return os << "TCP/TLS/MSRP"; + case SdpMediaSection::kDccp: + return os << "DCCP"; + case SdpMediaSection::kDccpRtpAvp: + return os << "DCCP/RTP/AVP"; + case SdpMediaSection::kDccpRtpSavp: + return os << "DCCP/RTP/SAVP"; + case SdpMediaSection::kDccpRtpAvpf: + return os << "DCCP/RTP/AVPF"; + case SdpMediaSection::kDccpRtpSavpf: + return os << "DCCP/RTP/SAVPF"; + case SdpMediaSection::kRtpSavpf: + return os << "RTP/SAVPF"; + case SdpMediaSection::kUdpTlsRtpSavp: + return os << "UDP/TLS/RTP/SAVP"; + case SdpMediaSection::kTcpTlsRtpSavp: + return os << "TCP/TLS/RTP/SAVP"; + case SdpMediaSection::kDccpTlsRtpSavp: + return os << "DCCP/TLS/RTP/SAVP"; + case SdpMediaSection::kUdpTlsRtpSavpf: + return os << "UDP/TLS/RTP/SAVPF"; + case SdpMediaSection::kTcpTlsRtpSavpf: + return os << "TCP/TLS/RTP/SAVPF"; + case SdpMediaSection::kDccpTlsRtpSavpf: + return os << "DCCP/TLS/RTP/SAVPF"; + case SdpMediaSection::kUdpMbmsFecRtpAvp: + return os << "UDP/MBMS-FEC/RTP/AVP"; + case SdpMediaSection::kUdpMbmsFecRtpSavp: + return os << "UDP/MBMS-FEC/RTP/SAVP"; + case SdpMediaSection::kUdpMbmsRepair: + return os << "UDP/MBMS-REPAIR"; + case SdpMediaSection::kFecUdp: + return os << "FEC/UDP"; + case SdpMediaSection::kUdpFec: + return os << "UDP/FEC"; + case SdpMediaSection::kTcpMrcpv2: + return os << "TCP/MRCPv2"; + case SdpMediaSection::kTcpTlsMrcpv2: + return os << "TCP/TLS/MRCPv2"; + case SdpMediaSection::kPstn: + return os << "PSTN"; + case SdpMediaSection::kUdpTlsUdptl: + return os << "UDP/TLS/UDPTL"; + case SdpMediaSection::kSctp: + return os << "SCTP"; + case SdpMediaSection::kSctpDtls: + return os << "SCTP/DTLS"; + case SdpMediaSection::kDtlsSctp: + return os << "DTLS/SCTP"; + } + MOZ_ASSERT(false, "Unknown Protocol"); + return os << "?"; +} + +class SdpConnection +{ +public: + SdpConnection(sdp::AddrType addrType, std::string addr, uint8_t ttl = 0, + uint32_t count = 0) + : mAddrType(addrType), mAddr(addr), mTtl(ttl), mCount(count) + { + } + ~SdpConnection() {} + + sdp::AddrType + GetAddrType() const + { + return mAddrType; + } + const std::string& + GetAddress() const + { + return mAddr; + } + void + SetAddress(const std::string& address) + { + mAddr = address; + } + uint8_t + GetTtl() const + { + return mTtl; + } + uint32_t + GetCount() const + { + return mCount; + } + + void + Serialize(std::ostream& os) const + { + sdp::NetType netType = sdp::kInternet; + + os << "c=" << netType << " " << mAddrType << " " << mAddr; + + if (mTtl) { + os << "/" << static_cast(mTtl); + if (mCount) { + os << "/" << mCount; + } + } + os << "\r\n"; + } + +private: + sdp::AddrType mAddrType; + std::string mAddr; + uint8_t mTtl; // 0-255; 0 when unset + uint32_t mCount; // 0 when unset +}; + +inline std::ostream& operator<<(std::ostream& os, const SdpConnection& c) +{ + c.Serialize(os); + return os; +} + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/sdp/SipccSdp.cpp b/media/webrtc/signaling/src/sdp/SipccSdp.cpp new file mode 100644 index 00000000000..282910bf646 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdp.cpp @@ -0,0 +1,186 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "signaling/src/sdp/SipccSdp.h" + +#include +#include "mozilla/Assertions.h" +#include "signaling/src/sdp/SdpErrorHolder.h" + +#ifdef CRLF +#undef CRLF +#endif +#define CRLF "\r\n" + +namespace mozilla +{ + +SipccSdp::~SipccSdp() +{ + for (auto i = mMediaSections.begin(); i != mMediaSections.end(); ++i) { + delete *i; + } +} + +const SdpOrigin& +SipccSdp::GetOrigin() const +{ + return mOrigin; +} + +uint32_t +SipccSdp::GetBandwidth(const std::string& type) const +{ + auto found = mBandwidths.find(type); + if (found == mBandwidths.end()) { + return 0; + } + return found->second; +} + +const SdpMediaSection& +SipccSdp::GetMediaSection(size_t level) const +{ + if (level > mMediaSections.size()) { + MOZ_CRASH(); + } + return *mMediaSections[level]; +} + +SdpMediaSection& +SipccSdp::GetMediaSection(size_t level) +{ + if (level > mMediaSections.size()) { + MOZ_CRASH(); + } + return *mMediaSections[level]; +} + +SdpMediaSection& +SipccSdp::AddMediaSection(SdpMediaSection::MediaType mediaType, + SdpDirectionAttribute::Direction dir, uint16_t port, + SdpMediaSection::Protocol protocol, + sdp::AddrType addrType, const std::string& addr) +{ + size_t level = mMediaSections.size(); + SipccSdpMediaSection* media = + new SipccSdpMediaSection(level, &mAttributeList); + media->mMediaType = mediaType; + media->mPort = port; + media->mPortCount = 0; + media->mProtocol = protocol; + media->mConnection = MakeUnique(addrType, addr); + media->GetAttributeList().SetAttribute(new SdpDirectionAttribute(dir)); + mMediaSections.push_back(media); + return *media; +} + +bool +SipccSdp::LoadOrigin(sdp_t* sdp, SdpErrorHolder& errorHolder) +{ + std::string username = sdp_get_owner_username(sdp); + uint64_t sessId = strtoul(sdp_get_owner_sessionid(sdp), nullptr, 10); + uint64_t sessVer = strtoul(sdp_get_owner_version(sdp), nullptr, 10); + + sdp_nettype_e type = sdp_get_owner_network_type(sdp); + if (type != SDP_NT_INTERNET) { + errorHolder.AddParseError(2, "Unsupported network type"); + return false; + } + + sdp::AddrType addrType; + switch (sdp_get_owner_address_type(sdp)) { + case SDP_AT_IP4: + addrType = sdp::kIPv4; + break; + case SDP_AT_IP6: + addrType = sdp::kIPv6; + break; + default: + errorHolder.AddParseError(2, "Unsupported address type"); + return false; + } + + std::string address = sdp_get_owner_address(sdp); + mOrigin = SdpOrigin(username, sessId, sessVer, addrType, address); + return true; +} + +bool +SipccSdp::Load(sdp_t* sdp, SdpErrorHolder& errorHolder) +{ + // Believe it or not, SDP_SESSION_LEVEL is 0xFFFF + if (!mAttributeList.Load(sdp, SDP_SESSION_LEVEL, errorHolder)) { + return false; + } + + if (!LoadOrigin(sdp, errorHolder)) { + return false; + } + + if (!mBandwidths.Load(sdp, SDP_SESSION_LEVEL, errorHolder)) { + return false; + } + + for (int i = 0; i < sdp_get_num_media_lines(sdp); ++i) { + // note that we pass a "level" here that is one higher + // sipcc counts media sections from 1, using 0xFFFF as the "session" + UniquePtr section( + new SipccSdpMediaSection(i, &mAttributeList)); + if (!section->Load(sdp, i + 1, errorHolder)) { + return false; + } + mMediaSections.push_back(section.release()); + } + return true; +} + +void +SipccSdp::Serialize(std::ostream& os) const +{ + os << "v=0" << CRLF << mOrigin << "s=-" << CRLF; + + // We don't support creating i=, u=, e=, p= + // We don't generate c= at the session level (only in media) + + mBandwidths.Serialize(os); + os << "t=0 0" << CRLF; + + // We don't support r= or z= + + // attributes + os << mAttributeList; + + // media sections + for (auto i = mMediaSections.begin(); i != mMediaSections.end(); ++i) { + os << (**i); + } +} + +bool +SipccSdpBandwidths::Load(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + size_t count = sdp_get_num_bw_lines(sdp, level); + for (size_t i = 1; i <= count; ++i) { + sdp_bw_modifier_e bwtype = sdp_get_bw_modifier(sdp, level, i); + uint32_t bandwidth = sdp_get_bw_value(sdp, level, i); + if (bwtype != SDP_BW_MODIFIER_UNSUPPORTED) { + const char* typeName = sdp_get_bw_modifier_name(bwtype); + (*this)[typeName] = bandwidth; + } + } + + return true; +} + +void +SipccSdpBandwidths::Serialize(std::ostream& os) const +{ + for (auto i = begin(); i != end(); ++i) { + os << "b=" << i->first << ":" << i->second << CRLF; + } +} + +} // namespace mozilla diff --git a/media/webrtc/signaling/src/sdp/SipccSdp.h b/media/webrtc/signaling/src/sdp/SipccSdp.h new file mode 100644 index 00000000000..e3819919d69 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdp.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SIPCCSDP_H_ +#define _SIPCCSDP_H_ + +#include +#include +#include "mozilla/Attributes.h" +#include "mozilla/UniquePtr.h" + +#include "signaling/src/sdp/Sdp.h" +#include "signaling/src/sdp/SipccSdpMediaSection.h" +#include "signaling/src/sdp/SipccSdpAttributeList.h" +extern "C" { +#include "signaling/src/sdp/sipcc/sdp.h" +} + +namespace mozilla +{ + +class SipccSdpParser; +class SdpErrorHolder; + +class SipccSdp MOZ_FINAL : public Sdp +{ + friend class SipccSdpParser; + +public: + explicit SipccSdp(const SdpOrigin& origin) + : mOrigin(origin), mAttributeList(nullptr) + { + } + ~SipccSdp(); + + virtual const SdpOrigin& GetOrigin() const MOZ_OVERRIDE; + + // Note: connection information is always retrieved from media sections + virtual uint32_t GetBandwidth(const std::string& type) const MOZ_OVERRIDE; + + virtual size_t + GetMediaSectionCount() const MOZ_OVERRIDE + { + return mMediaSections.size(); + } + + virtual const SdpAttributeList& + GetAttributeList() const MOZ_OVERRIDE + { + return mAttributeList; + } + + virtual SdpAttributeList& + GetAttributeList() MOZ_OVERRIDE + { + return mAttributeList; + } + + virtual const SdpMediaSection& GetMediaSection(size_t level) const + MOZ_OVERRIDE; + + virtual SdpMediaSection& GetMediaSection(size_t level) MOZ_OVERRIDE; + + virtual SdpMediaSection& AddMediaSection( + SdpMediaSection::MediaType media, SdpDirectionAttribute::Direction dir, + uint16_t port, SdpMediaSection::Protocol proto, sdp::AddrType addrType, + const std::string& addr) MOZ_OVERRIDE; + + virtual void Serialize(std::ostream&) const MOZ_OVERRIDE; + +private: + SipccSdp() : mOrigin("", 0, 0, sdp::kIPv4, ""), mAttributeList(nullptr) {} + + bool Load(sdp_t* sdp, SdpErrorHolder& errorHolder); + bool LoadOrigin(sdp_t* sdp, SdpErrorHolder& errorHolder); + + SdpOrigin mOrigin; + SipccSdpBandwidths mBandwidths; + SipccSdpAttributeList mAttributeList; + std::vector mMediaSections; +}; + +} // namespace mozilla + +#endif // _sdp_h_ diff --git a/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp b/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp new file mode 100644 index 00000000000..7fb309765f7 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp @@ -0,0 +1,1116 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "signaling/src/sdp/SipccSdpAttributeList.h" + +#include +#include "mozilla/Assertions.h" +#include "signaling/src/sdp/SdpErrorHolder.h" + +extern "C" { +#include "signaling/src/sdp/sipcc/sdp_private.h" +} + +namespace mozilla +{ + +/* static */ const std::string SipccSdpAttributeList::kEmptyString = ""; + +SipccSdpAttributeList::SipccSdpAttributeList( + const SipccSdpAttributeList* sessionLevel) + : mSessionLevel(sessionLevel) +{ + memset(&mAttributes, 0, sizeof(mAttributes)); +} + +SipccSdpAttributeList::~SipccSdpAttributeList() +{ + for (size_t i = 0; i < kNumAttributeTypes; ++i) { + delete mAttributes[i]; + } +} + +bool +SipccSdpAttributeList::HasAttribute(AttributeType type, + bool sessionFallback) const +{ + return !!GetAttribute(type, sessionFallback); +} + +const SdpAttribute* +SipccSdpAttributeList::GetAttribute(AttributeType type, + bool sessionFallback) const +{ + const SdpAttribute* value = mAttributes[static_cast(type)]; + // Only do fallback when the attribute can appear at both the media and + // session level + if (!value && !AtSessionLevel() && sessionFallback && + SdpAttribute::IsAllowedAtSessionLevel(type) && + SdpAttribute::IsAllowedAtMediaLevel(type)) { + return mSessionLevel->GetAttribute(type, false); + } + return value; +} + +void +SipccSdpAttributeList::RemoveAttribute(AttributeType type) +{ + delete mAttributes[static_cast(type)]; + mAttributes[static_cast(type)] = nullptr; +} + +void +SipccSdpAttributeList::Clear() +{ + for (size_t i = 0; i < kNumAttributeTypes; ++i) { + RemoveAttribute(static_cast(i)); + } +} + +void +SipccSdpAttributeList::SetAttribute(SdpAttribute* attr) +{ + if (!IsAllowedHere(attr->GetType())) { + MOZ_ASSERT(false, "This type of attribute is not allowed here"); + return; + } + RemoveAttribute(attr->GetType()); + mAttributes[attr->GetType()] = attr; +} + +void +SipccSdpAttributeList::LoadSimpleString(sdp_t* sdp, uint16_t level, + sdp_attr_e attr, + AttributeType targetType, + SdpErrorHolder& errorHolder) +{ + const char* value = sdp_attr_get_simple_string(sdp, attr, level, 0, 1); + if (value) { + if (!IsAllowedHere(targetType)) { + uint32_t lineNumber = sdp_attr_line_number(sdp, attr, level, 0, 1); + WarnAboutMisplacedAttribute(targetType, lineNumber, errorHolder); + } else { + SetAttribute(new SdpStringAttribute(targetType, std::string(value))); + } + } +} + +void +SipccSdpAttributeList::LoadSimpleStrings(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + LoadSimpleString(sdp, level, SDP_ATTR_MID, SdpAttribute::kMidAttribute, + errorHolder); + LoadSimpleString(sdp, level, SDP_ATTR_LABEL, SdpAttribute::kLabelAttribute, + errorHolder); + LoadSimpleString(sdp, level, SDP_ATTR_IDENTITY, + SdpAttribute::kIdentityAttribute, errorHolder); + LoadSimpleString(sdp, level, SDP_ATTR_MSID_SEMANTIC, + SdpAttribute::kMsidSemanticAttribute, errorHolder); +} + +void +SipccSdpAttributeList::LoadSimpleNumber(sdp_t* sdp, uint16_t level, + sdp_attr_e attr, + AttributeType targetType, + SdpErrorHolder& errorHolder) +{ + if (sdp_attr_valid(sdp, attr, level, 0, 1)) { + if (!IsAllowedHere(targetType)) { + uint32_t lineNumber = sdp_attr_line_number(sdp, attr, level, 0, 1); + WarnAboutMisplacedAttribute(targetType, lineNumber, errorHolder); + } else { + uint32_t value = sdp_attr_get_simple_u32(sdp, attr, level, 0, 1); + SetAttribute(new SdpNumberAttribute(targetType, value)); + } + } +} + +void +SipccSdpAttributeList::LoadSimpleNumbers(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + LoadSimpleNumber(sdp, level, SDP_ATTR_PTIME, SdpAttribute::kPtimeAttribute, + errorHolder); + LoadSimpleNumber(sdp, level, SDP_ATTR_MAXPTIME, + SdpAttribute::kMaxptimeAttribute, errorHolder); +} + +void +SipccSdpAttributeList::LoadFlags(sdp_t* sdp, uint16_t level) +{ + if (AtSessionLevel()) { + if (sdp_attr_valid(sdp, SDP_ATTR_ICE_LITE, level, 0, 1)) { + SetAttribute(new SdpFlagAttribute(SdpAttribute::kIceLiteAttribute)); + } + } else { // media-level + if (sdp_attr_valid(sdp, SDP_ATTR_RTCP_MUX, level, 0, 1)) { + SetAttribute(new SdpFlagAttribute(SdpAttribute::kRtcpMuxAttribute)); + } + if (sdp_attr_valid(sdp, SDP_ATTR_END_OF_CANDIDATES, level, 0, 1)) { + SetAttribute( + new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute)); + } + if (sdp_attr_valid(sdp, SDP_ATTR_BUNDLE_ONLY, level, 0, 1)) { + SetAttribute(new SdpFlagAttribute(SdpAttribute::kBundleOnlyAttribute)); + } + } +} + +static void +ConvertDirection(sdp_direction_e sipcc_direction, + SdpDirectionAttribute::Direction* dir_outparam) +{ + switch (sipcc_direction) { + case SDP_DIRECTION_SENDRECV: + *dir_outparam = SdpDirectionAttribute::kSendrecv; + return; + case SDP_DIRECTION_SENDONLY: + *dir_outparam = SdpDirectionAttribute::kSendonly; + return; + case SDP_DIRECTION_RECVONLY: + *dir_outparam = SdpDirectionAttribute::kRecvonly; + return; + case SDP_DIRECTION_INACTIVE: + *dir_outparam = SdpDirectionAttribute::kInactive; + return; + case SDP_MAX_QOS_DIRECTIONS: + // Nothing actually sets this value. + // Fall through to MOZ_CRASH below. + { + } + } + + MOZ_CRASH("Invalid direction from sipcc; this is probably corruption"); +} + +void +SipccSdpAttributeList::LoadDirection(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + SdpDirectionAttribute::Direction dir; + ConvertDirection(sdp_get_media_direction(sdp, level, 0), &dir); + SetAttribute(new SdpDirectionAttribute(dir)); +} + +void +SipccSdpAttributeList::LoadIceAttributes(sdp_t* sdp, uint16_t level) +{ + char* value; + sdp_result_e sdpres = + sdp_attr_get_ice_attribute(sdp, level, 0, SDP_ATTR_ICE_UFRAG, 1, &value); + if (sdpres == SDP_SUCCESS) { + SetAttribute(new SdpStringAttribute(SdpAttribute::kIceUfragAttribute, + std::string(value))); + } + sdpres = + sdp_attr_get_ice_attribute(sdp, level, 0, SDP_ATTR_ICE_PWD, 1, &value); + if (sdpres == SDP_SUCCESS) { + SetAttribute(new SdpStringAttribute(SdpAttribute::kIcePwdAttribute, + std::string(value))); + } + + const char* iceOptVal = + sdp_attr_get_simple_string(sdp, SDP_ATTR_ICE_OPTIONS, level, 0, 1); + if (iceOptVal) { + auto* iceOptions = + new SdpOptionsAttribute(SdpAttribute::kIceOptionsAttribute); + iceOptions->Load(iceOptVal); + SetAttribute(iceOptions); + } +} + +bool +SipccSdpAttributeList::LoadFingerprint(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + char* value; + UniquePtr fingerprintAttrs; + + for (uint16_t i = 1; i < UINT16_MAX; ++i) { + sdp_result_e result = sdp_attr_get_dtls_fingerprint_attribute( + sdp, level, 0, SDP_ATTR_DTLS_FINGERPRINT, i, &value); + + if (result != SDP_SUCCESS) { + break; + } + + std::string fingerprintAttr(value); + uint32_t lineNumber = + sdp_attr_line_number(sdp, SDP_ATTR_DTLS_FINGERPRINT, level, 0, i); + + // sipcc does not expose parse code for this + size_t start = fingerprintAttr.find_first_not_of(" \t"); + if (start == std::string::npos) { + errorHolder.AddParseError(lineNumber, "Empty fingerprint attribute"); + return false; + } + + size_t end = fingerprintAttr.find_first_of(" \t", start); + if (end == std::string::npos) { + // One token, no trailing ws + errorHolder.AddParseError(lineNumber, + "Only one token in fingerprint attribute"); + return false; + } + + std::string algorithmToken(fingerprintAttr.substr(start, end - start)); + + start = fingerprintAttr.find_first_not_of(" \t", end); + if (start == std::string::npos) { + // One token, trailing ws + errorHolder.AddParseError(lineNumber, + "Only one token in fingerprint attribute"); + return false; + } + + std::string fingerprintToken(fingerprintAttr.substr(start)); + + std::vector fingerprint = + SdpFingerprintAttributeList::ParseFingerprint(fingerprintToken); + if (fingerprint.size() == 0) { + errorHolder.AddParseError(lineNumber, "Malformed fingerprint token"); + return false; + } + + if (!fingerprintAttrs) { + fingerprintAttrs.reset(new SdpFingerprintAttributeList); + } + + // Don't assert on unknown algorithm, just skip + fingerprintAttrs->PushEntry(algorithmToken, fingerprint, false); + } + + if (fingerprintAttrs) { + SetAttribute(fingerprintAttrs.release()); + } + + return true; +} + +void +SipccSdpAttributeList::LoadCandidate(sdp_t* sdp, uint16_t level) +{ + char* value; + auto candidates = + MakeUnique(SdpAttribute::kCandidateAttribute); + + for (uint16_t i = 1; i < UINT16_MAX; ++i) { + sdp_result_e result = sdp_attr_get_ice_attribute( + sdp, level, 0, SDP_ATTR_ICE_CANDIDATE, i, &value); + + if (result != SDP_SUCCESS) { + break; + } + + candidates->mValues.push_back(value); + } + + if (!candidates->mValues.empty()) { + SetAttribute(candidates.release()); + } +} + +bool +SipccSdpAttributeList::LoadSctpmap(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + auto sctpmap = MakeUnique(); + for (uint16_t i = 0; i < UINT16_MAX; ++i) { + sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_SCTPMAP, i + 1); + + if (!attr) { + break; + } + + // Yeah, this is a little weird, but for now we'll just store this as a + // payload type. + uint16_t payloadType = attr->attr.sctpmap.port; + uint16_t streams = attr->attr.sctpmap.streams; + const char* name = attr->attr.sctpmap.protocol; + + std::ostringstream osPayloadType; + osPayloadType << payloadType; + sctpmap->PushEntry(osPayloadType.str(), name, streams); + } + + if (!sctpmap->mSctpmaps.empty()) { + SetAttribute(sctpmap.release()); + } + + return true; +} + +SdpRtpmapAttributeList::CodecType +SipccSdpAttributeList::GetCodecType(rtp_ptype type) +{ + switch (type) { + case RTP_PCMU: + return SdpRtpmapAttributeList::kPCMU; + case RTP_PCMA: + return SdpRtpmapAttributeList::kPCMA; + case RTP_G722: + return SdpRtpmapAttributeList::kG722; + case RTP_H264_P0: + case RTP_H264_P1: + return SdpRtpmapAttributeList::kH264; + case RTP_OPUS: + return SdpRtpmapAttributeList::kOpus; + case RTP_VP8: + return SdpRtpmapAttributeList::kVP8; + case RTP_NONE: + // Happens when sipcc doesn't know how to translate to the enum + case RTP_CELP: + case RTP_G726: + case RTP_GSM: + case RTP_G723: + case RTP_DVI4: + case RTP_DVI4_II: + case RTP_LPC: + case RTP_G728: + case RTP_G729: + case RTP_JPEG: + case RTP_NV: + case RTP_H261: + case RTP_AVT: + case RTP_L16: + case RTP_H263: + case RTP_ILBC: + case RTP_I420: + return SdpRtpmapAttributeList::kOtherCodec; + } + MOZ_CRASH("Invalid codec type from sipcc. Probably corruption."); +} + +bool +SipccSdpAttributeList::LoadRtpmap(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + auto rtpmap = MakeUnique(); + uint16_t count; + sdp_result_e result = + sdp_attr_num_instances(sdp, level, 0, SDP_ATTR_RTPMAP, &count); + if (result != SDP_SUCCESS) { + MOZ_ASSERT(false, "Unable to get rtpmap size"); + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "Unable to get rtpmap size"); + return false; + } + for (uint16_t i = 0; i < count; ++i) { + uint16_t pt = sdp_attr_get_rtpmap_payload_type(sdp, level, 0, i + 1); + const char* ccName = sdp_attr_get_rtpmap_encname(sdp, level, 0, i + 1); + + if (!ccName) { + // Probably no rtpmap attribute for a pt in an m-line + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "No rtpmap attribute for payload type"); + continue; + } + + std::string name(ccName); + + SdpRtpmapAttributeList::CodecType codec = + GetCodecType(sdp_get_known_payload_type(sdp, level, pt)); + + uint32_t clock = sdp_attr_get_rtpmap_clockrate(sdp, level, 0, i + 1); + uint16_t channels = 0; + + // sipcc gives us a channels value of "1" for video + if (sdp_get_media_type(sdp, level) == SDP_MEDIA_AUDIO) { + channels = sdp_attr_get_rtpmap_num_chan(sdp, level, 0, i + 1); + } + + std::ostringstream osPayloadType; + osPayloadType << pt; + rtpmap->PushEntry(osPayloadType.str(), codec, name, clock, channels); + } + + if (!rtpmap->mRtpmaps.empty()) { + SetAttribute(rtpmap.release()); + } + + return true; +} + +void +SipccSdpAttributeList::LoadSetup(sdp_t* sdp, uint16_t level) +{ + sdp_setup_type_e setupType; + auto sdpres = sdp_attr_get_setup_attribute(sdp, level, 0, 1, &setupType); + + if (sdpres != SDP_SUCCESS) { + return; + } + + switch (setupType) { + case SDP_SETUP_ACTIVE: + SetAttribute(new SdpSetupAttribute(SdpSetupAttribute::kActive)); + return; + case SDP_SETUP_PASSIVE: + SetAttribute(new SdpSetupAttribute(SdpSetupAttribute::kPassive)); + return; + case SDP_SETUP_ACTPASS: + SetAttribute(new SdpSetupAttribute(SdpSetupAttribute::kActpass)); + return; + case SDP_SETUP_HOLDCONN: + SetAttribute(new SdpSetupAttribute(SdpSetupAttribute::kHoldconn)); + return; + case SDP_SETUP_UNKNOWN: + return; + case SDP_SETUP_NOT_FOUND: + case SDP_MAX_SETUP: + // There is no code that will set these. + // Fall through to MOZ_CRASH() below. + { + } + } + + MOZ_CRASH("Invalid setup type from sipcc. This is probably corruption."); +} + +bool +SipccSdpAttributeList::LoadGroups(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + uint16_t attrCount = 0; + if (sdp_attr_num_instances(sdp, level, 0, SDP_ATTR_GROUP, &attrCount) != + SDP_SUCCESS) { + MOZ_ASSERT(false, "Could not get count of group attributes"); + errorHolder.AddParseError(0, "Could not get count of group attributes"); + return false; + } + + UniquePtr groups = MakeUnique(); + for (uint16_t attr = 1; attr <= attrCount; ++attr) { + SdpGroupAttributeList::Semantics semantics; + std::vector tags; + + switch (sdp_get_group_attr(sdp, level, 0, attr)) { + case SDP_GROUP_ATTR_FID: + semantics = SdpGroupAttributeList::kFid; + break; + case SDP_GROUP_ATTR_LS: + semantics = SdpGroupAttributeList::kLs; + break; + case SDP_GROUP_ATTR_ANAT: + semantics = SdpGroupAttributeList::kAnat; + break; + case SDP_GROUP_ATTR_BUNDLE: + semantics = SdpGroupAttributeList::kBundle; + break; + default: + continue; + } + + uint16_t idCount = sdp_get_group_num_id(sdp, level, 0, attr); + for (uint16_t id = 1; id <= idCount; ++id) { + const char* idStr = sdp_get_group_id(sdp, level, 0, attr, id); + if (!idStr) { + std::ostringstream os; + os << "bad a=group identifier at " << (attr - 1) << ", " << (id - 1); + errorHolder.AddParseError(0, os.str()); + return false; + } + tags.push_back(std::string(idStr)); + } + groups->PushEntry(semantics, tags); + } + + if (!groups->mGroups.empty()) { + SetAttribute(groups.release()); + } + + return true; +} + +void +SipccSdpAttributeList::LoadFmtp(sdp_t* sdp, uint16_t level) +{ + auto fmtps = MakeUnique(); + + for (uint16_t i = 1; i < UINT16_MAX; ++i) { + sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_FMTP, i); + + if (!attr) { + break; + } + + sdp_fmtp_t* fmtp = &(attr->attr.fmtp); + + // Get the payload type + std::stringstream osPayloadType; + // payload_num is the number in the fmtp attribute, verbatim + osPayloadType << fmtp->payload_num; + + // Get the serialized form of the parameters + flex_string fs; + flex_string_init(&fs); + + // Very lame, but we need direct access so we can get the serialized form + sdp_result_e sdpres = sdp_build_attr_fmtp_params(sdp, fmtp, &fs); + + if (sdpres != SDP_SUCCESS) { + flex_string_free(&fs); + continue; + } + + std::string paramsString(fs.buffer); + flex_string_free(&fs); + + // Get parsed form of parameters, if supported + UniquePtr parameters; + + rtp_ptype codec = sdp_get_known_payload_type(sdp, level, fmtp->payload_num); + + switch (codec) { + case RTP_H264_P0: + case RTP_H264_P1: { + SdpFmtpAttributeList::H264Parameters* h264Parameters( + new SdpFmtpAttributeList::H264Parameters); + + sstrncpy(h264Parameters->sprop_parameter_sets, fmtp->parameter_sets, + sizeof(h264Parameters->sprop_parameter_sets)); + + h264Parameters->level_asymmetry_allowed = + !!(fmtp->level_asymmetry_allowed); + + h264Parameters->packetization_mode = fmtp->packetization_mode; +// Copied from VcmSIPCCBinding +#ifdef _WIN32 + sscanf_s(fmtp->profile_level_id, "%x", + &h264Parameters->profile_level_id, sizeof(unsigned*)); +#else + sscanf(fmtp->profile_level_id, "%xu", + &h264Parameters->profile_level_id); +#endif + h264Parameters->max_mbps = fmtp->max_mbps; + h264Parameters->max_fs = fmtp->max_fs; + h264Parameters->max_cpb = fmtp->max_cpb; + h264Parameters->max_dpb = fmtp->max_dpb; + h264Parameters->max_br = fmtp->max_br; + + parameters.reset(h264Parameters); + } break; + case RTP_VP8: { + SdpFmtpAttributeList::VP8Parameters* vp8Parameters( + new SdpFmtpAttributeList::VP8Parameters); + + vp8Parameters->max_fs = fmtp->max_fs; + vp8Parameters->max_fr = fmtp->max_fr; + + parameters.reset(vp8Parameters); + } break; + default: { + } + } + + fmtps->PushEntry(osPayloadType.str(), paramsString, Move(parameters)); + } + + if (!fmtps->mFmtps.empty()) { + SetAttribute(fmtps.release()); + } +} + +void +SipccSdpAttributeList::LoadMsids(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + uint16_t attrCount = 0; + if (sdp_attr_num_instances(sdp, level, 0, SDP_ATTR_MSID, &attrCount) != + SDP_SUCCESS) { + MOZ_ASSERT(false, "Unable to get count of msid attributes"); + errorHolder.AddParseError(0, "Unable to get count of msid attributes"); + return; + } + auto msids = MakeUnique(); + for (uint16_t i = 1; i <= attrCount; ++i) { + uint32_t lineNumber = sdp_attr_line_number(sdp, SDP_ATTR_MSID, level, 0, i); + + const char* identifier = sdp_attr_get_msid_identifier(sdp, level, 0, i); + if (!identifier) { + errorHolder.AddParseError(lineNumber, "msid attribute with bad identity"); + continue; + } + + const char* appdata = sdp_attr_get_msid_appdata(sdp, level, 0, i); + if (!appdata) { + errorHolder.AddParseError(lineNumber, "msid attribute with bad appdata"); + continue; + } + + msids->PushEntry(identifier, appdata); + } + + if (!msids->mMsids.empty()) { + SetAttribute(msids.release()); + } +} + +void +SipccSdpAttributeList::LoadExtmap(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + auto extmaps = MakeUnique(); + + for (uint16_t i = 1; i < UINT16_MAX; ++i) { + sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_EXTMAP, i); + + if (!attr) { + break; + } + + sdp_extmap_t* extmap = &(attr->attr.extmap); + + SdpDirectionAttribute::Direction dir = SdpDirectionAttribute::kSendrecv; + + if (extmap->media_direction_specified) { + ConvertDirection(extmap->media_direction, &dir); + } + + extmaps->PushEntry(extmap->id, dir, extmap->media_direction_specified, + extmap->uri, extmap->extension_attributes); + } + + if (!extmaps->mExtmaps.empty()) { + if (!AtSessionLevel() && + mSessionLevel->HasAttribute(SdpAttribute::kExtmapAttribute)) { + uint32_t lineNumber = + sdp_attr_line_number(sdp, SDP_ATTR_EXTMAP, level, 0, 1); + errorHolder.AddParseError( + lineNumber, "extmap attributes in both session and media level"); + } + SetAttribute(extmaps.release()); + } +} + +void +SipccSdpAttributeList::LoadRtcpFb(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + auto rtcpfbs = MakeUnique(); + + for (uint16_t i = 1; i < UINT16_MAX; ++i) { + sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_RTCP_FB, i); + + if (!attr) { + break; + } + + sdp_fmtp_fb_t* rtcpfb = &attr->attr.rtcp_fb; + + SdpRtcpFbAttributeList::Type type; + std::string parameter; + + // Set type and parameter + switch (rtcpfb->feedback_type) { + case SDP_RTCP_FB_ACK: + type = SdpRtcpFbAttributeList::kAck; + switch (rtcpfb->param.ack) { + // TODO: sipcc doesn't seem to support ack with no following token. + // Issue 189. + case SDP_RTCP_FB_ACK_RPSI: + parameter = SdpRtcpFbAttributeList::rpsi; + break; + case SDP_RTCP_FB_ACK_APP: + parameter = SdpRtcpFbAttributeList::app; + break; + default: + // Type we don't care about, ignore. + continue; + } + break; + case SDP_RTCP_FB_CCM: + type = SdpRtcpFbAttributeList::kCcm; + switch (rtcpfb->param.ccm) { + case SDP_RTCP_FB_CCM_FIR: + parameter = SdpRtcpFbAttributeList::fir; + break; + case SDP_RTCP_FB_CCM_TMMBR: + parameter = SdpRtcpFbAttributeList::tmmbr; + break; + case SDP_RTCP_FB_CCM_TSTR: + parameter = SdpRtcpFbAttributeList::tstr; + break; + case SDP_RTCP_FB_CCM_VBCM: + parameter = SdpRtcpFbAttributeList::vbcm; + break; + default: + // Type we don't care about, ignore. + continue; + } + break; + case SDP_RTCP_FB_NACK: + type = SdpRtcpFbAttributeList::kNack; + switch (rtcpfb->param.nack) { + case SDP_RTCP_FB_NACK_BASIC: + break; + case SDP_RTCP_FB_NACK_SLI: + parameter = SdpRtcpFbAttributeList::sli; + break; + case SDP_RTCP_FB_NACK_PLI: + parameter = SdpRtcpFbAttributeList::pli; + break; + case SDP_RTCP_FB_NACK_RPSI: + parameter = SdpRtcpFbAttributeList::rpsi; + break; + case SDP_RTCP_FB_NACK_APP: + parameter = SdpRtcpFbAttributeList::app; + break; + default: + // Type we don't care about, ignore. + continue; + } + break; + case SDP_RTCP_FB_TRR_INT: { + type = SdpRtcpFbAttributeList::kTrrInt; + std::ostringstream os; + os << rtcpfb->param.trr_int; + parameter = os.str(); + } break; + default: + // Type we don't care about, ignore. + continue; + } + + std::stringstream osPayloadType; + osPayloadType << rtcpfb->payload_num; + + std::string pt(osPayloadType.str()); + std::string extra(rtcpfb->extra); + + rtcpfbs->PushEntry(pt, type, parameter, extra); + } + + if (!rtcpfbs->mFeedbacks.empty()) { + SetAttribute(rtcpfbs.release()); + } +} + +bool +SipccSdpAttributeList::Load(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + + LoadSimpleStrings(sdp, level, errorHolder); + LoadSimpleNumbers(sdp, level, errorHolder); + LoadFlags(sdp, level); + LoadDirection(sdp, level, errorHolder); + + if (AtSessionLevel()) { + if (!LoadGroups(sdp, level, errorHolder)) { + return false; + } + } else { + sdp_media_e mtype = sdp_get_media_type(sdp, level); + if (mtype == SDP_MEDIA_APPLICATION) { + if (!LoadSctpmap(sdp, level, errorHolder)) { + return false; + } + } else { + if (!LoadRtpmap(sdp, level, errorHolder)) { + return false; + } + } + LoadCandidate(sdp, level); + LoadFmtp(sdp, level); + LoadMsids(sdp, level, errorHolder); + LoadRtcpFb(sdp, level, errorHolder); + } + + LoadIceAttributes(sdp, level); + if (!LoadFingerprint(sdp, level, errorHolder)) { + return false; + } + LoadSetup(sdp, level); + LoadExtmap(sdp, level, errorHolder); + + return true; +} + +bool +SipccSdpAttributeList::IsAllowedHere(SdpAttribute::AttributeType type) const +{ + if (AtSessionLevel() && !SdpAttribute::IsAllowedAtSessionLevel(type)) { + return false; + } + + if (!AtSessionLevel() && !SdpAttribute::IsAllowedAtMediaLevel(type)) { + return false; + } + + return true; +} + +void +SipccSdpAttributeList::WarnAboutMisplacedAttribute( + SdpAttribute::AttributeType type, uint32_t lineNumber, + SdpErrorHolder& errorHolder) +{ + std::string warning = SdpAttribute::GetAttributeTypeString(type) + + (AtSessionLevel() ? " at session level. Ignoring." + : " at media level. Ignoring."); + errorHolder.AddParseError(lineNumber, warning); +} + +const std::vector& +SipccSdpAttributeList::GetCandidate() const +{ + if (!HasAttribute(SdpAttribute::kCandidateAttribute)) { + MOZ_CRASH(); + } + + return static_cast( + GetAttribute(SdpAttribute::kCandidateAttribute))->mValues; +} + +const SdpConnectionAttribute& +SipccSdpAttributeList::GetConnection() const +{ + if (!HasAttribute(SdpAttribute::kConnectionAttribute)) { + MOZ_CRASH(); + } + + return *static_cast( + GetAttribute(SdpAttribute::kConnectionAttribute)); +} + +SdpDirectionAttribute::Direction +SipccSdpAttributeList::GetDirection() const +{ + if (!HasAttribute(SdpAttribute::kDirectionAttribute)) { + MOZ_CRASH(); + } + + const SdpAttribute* attr = GetAttribute(SdpAttribute::kDirectionAttribute); + return static_cast(attr)->mValue; +} + +const SdpExtmapAttributeList& +SipccSdpAttributeList::GetExtmap() const +{ + if (!HasAttribute(SdpAttribute::kExtmapAttribute)) { + MOZ_CRASH(); + } + + return *static_cast( + GetAttribute(SdpAttribute::kExtmapAttribute)); +} + +const SdpFingerprintAttributeList& +SipccSdpAttributeList::GetFingerprint() const +{ + if (!HasAttribute(SdpAttribute::kFingerprintAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kFingerprintAttribute); + return *static_cast(attr); +} + +const SdpFmtpAttributeList& +SipccSdpAttributeList::GetFmtp() const +{ + if (!HasAttribute(SdpAttribute::kFmtpAttribute)) { + MOZ_CRASH(); + } + + return *static_cast( + GetAttribute(SdpAttribute::kFmtpAttribute)); +} + +const SdpGroupAttributeList& +SipccSdpAttributeList::GetGroup() const +{ + if (!HasAttribute(SdpAttribute::kGroupAttribute)) { + MOZ_CRASH(); + } + + return *static_cast( + GetAttribute(SdpAttribute::kGroupAttribute)); +} + +const SdpOptionsAttribute& +SipccSdpAttributeList::GetIceOptions() const +{ + if (!HasAttribute(SdpAttribute::kIceOptionsAttribute)) { + MOZ_CRASH(); + } + + const SdpAttribute* attr = GetAttribute(SdpAttribute::kIceOptionsAttribute); + return *static_cast(attr); +} + +const std::string& +SipccSdpAttributeList::GetIcePwd() const +{ + if (!HasAttribute(SdpAttribute::kIcePwdAttribute)) { + return kEmptyString; + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kIcePwdAttribute); + return static_cast(attr)->mValue; +} + +const std::string& +SipccSdpAttributeList::GetIceUfrag() const +{ + if (!HasAttribute(SdpAttribute::kIceUfragAttribute)) { + return kEmptyString; + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kIceUfragAttribute); + return static_cast(attr)->mValue; +} + +const std::string& +SipccSdpAttributeList::GetIdentity() const +{ + if (!HasAttribute(SdpAttribute::kIdentityAttribute)) { + return kEmptyString; + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kIdentityAttribute); + return static_cast(attr)->mValue; +} + +const SdpImageattrAttributeList& +SipccSdpAttributeList::GetImageattr() const +{ + MOZ_CRASH("Not yet implemented."); +} + +const std::string& +SipccSdpAttributeList::GetLabel() const +{ + if (!HasAttribute(SdpAttribute::kLabelAttribute)) { + return kEmptyString; + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kLabelAttribute); + return static_cast(attr)->mValue; +} + +uint32_t +SipccSdpAttributeList::GetMaxptime() const +{ + if (!HasAttribute(SdpAttribute::kMaxptimeAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kMaxptimeAttribute); + return static_cast(attr)->mValue; +} + +const std::string& +SipccSdpAttributeList::GetMid() const +{ + if (!HasAttribute(SdpAttribute::kMidAttribute)) { + return kEmptyString; + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kMidAttribute); + return static_cast(attr)->mValue; +} + +const SdpMsidAttributeList& +SipccSdpAttributeList::GetMsid() const +{ + if (!HasAttribute(SdpAttribute::kMsidAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kMsidAttribute); + return *static_cast(attr); +} + +const std::string& +SipccSdpAttributeList::GetMsidSemantic() const +{ + if (!HasAttribute(SdpAttribute::kMsidSemanticAttribute)) { + return kEmptyString; + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kMsidSemanticAttribute); + return static_cast(attr)->mValue; +} + +uint32_t +SipccSdpAttributeList::GetPtime() const +{ + if (!HasAttribute(SdpAttribute::kPtimeAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kPtimeAttribute); + return static_cast(attr)->mValue; +} + +const SdpRtcpAttribute& +SipccSdpAttributeList::GetRtcp() const +{ + MOZ_CRASH("Not yet implemented"); +} + +const SdpRtcpFbAttributeList& +SipccSdpAttributeList::GetRtcpFb() const +{ + if (!HasAttribute(SdpAttribute::kRtcpFbAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kRtcpFbAttribute); + return *static_cast(attr); +} + +const SdpRemoteCandidatesAttribute& +SipccSdpAttributeList::GetRemoteCandidates() const +{ + MOZ_CRASH("Not yet implemented"); +} + +const SdpRtpmapAttributeList& +SipccSdpAttributeList::GetRtpmap() const +{ + if (!HasAttribute(SdpAttribute::kRtpmapAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kRtpmapAttribute); + return *static_cast(attr); +} + +const SdpSctpmapAttributeList& +SipccSdpAttributeList::GetSctpmap() const +{ + if (!HasAttribute(SdpAttribute::kSctpmapAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kSctpmapAttribute); + return *static_cast(attr); +} + +const SdpSetupAttribute& +SipccSdpAttributeList::GetSetup() const +{ + if (!HasAttribute(SdpAttribute::kSetupAttribute)) { + MOZ_CRASH(); + } + const SdpAttribute* attr = GetAttribute(SdpAttribute::kSetupAttribute); + return *static_cast(attr); +} + +const SdpSsrcAttributeList& +SipccSdpAttributeList::GetSsrc() const +{ + MOZ_CRASH("Not yet implemented"); +} + +const SdpSsrcGroupAttributeList& +SipccSdpAttributeList::GetSsrcGroup() const +{ + MOZ_CRASH("Not yet implemented"); +} + +void +SipccSdpAttributeList::Serialize(std::ostream& os) const +{ + for (size_t i = 0; i < kNumAttributeTypes; ++i) { + if (mAttributes[i]) { + os << *mAttributes[i]; + } + } +} + +} // namespace mozilla diff --git a/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.h b/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.h new file mode 100644 index 00000000000..bf5db765fe3 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.h @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SIPCCSDPATTRIBUTELIST_H_ +#define _SIPCCSDPATTRIBUTELIST_H_ + +#include "signaling/src/sdp/SdpAttributeList.h" + +extern "C" { +#include "signaling/src/sdp/sipcc/sdp.h" +} + +namespace mozilla +{ + +class SipccSdp; +class SipccSdpMediaSection; +class SdpErrorHolder; + +class SipccSdpAttributeList : public SdpAttributeList +{ + friend class SipccSdpMediaSection; + friend class SipccSdp; + +public: + // Make sure we don't hide the default arg thunks + using SdpAttributeList::HasAttribute; + using SdpAttributeList::GetAttribute; + + virtual bool HasAttribute(AttributeType type, + bool sessionFallback) const MOZ_OVERRIDE; + virtual const SdpAttribute* GetAttribute( + AttributeType type, bool sessionFallback) const MOZ_OVERRIDE; + virtual void SetAttribute(SdpAttribute* attr) MOZ_OVERRIDE; + virtual void RemoveAttribute(AttributeType type) MOZ_OVERRIDE; + virtual void Clear() MOZ_OVERRIDE; + + virtual const SdpConnectionAttribute& GetConnection() const MOZ_OVERRIDE; + virtual const SdpFingerprintAttributeList& GetFingerprint() const + MOZ_OVERRIDE; + virtual const SdpGroupAttributeList& GetGroup() const MOZ_OVERRIDE; + virtual const SdpOptionsAttribute& GetIceOptions() const MOZ_OVERRIDE; + virtual const SdpRtcpAttribute& GetRtcp() const MOZ_OVERRIDE; + virtual const SdpRemoteCandidatesAttribute& GetRemoteCandidates() const + MOZ_OVERRIDE; + virtual const SdpSetupAttribute& GetSetup() const MOZ_OVERRIDE; + virtual const SdpSsrcAttributeList& GetSsrc() const MOZ_OVERRIDE; + virtual const SdpSsrcGroupAttributeList& GetSsrcGroup() const MOZ_OVERRIDE; + + // These attributes can appear multiple times, so the returned + // classes actually represent a collection of values. + virtual const std::vector& GetCandidate() const MOZ_OVERRIDE; + virtual const SdpExtmapAttributeList& GetExtmap() const MOZ_OVERRIDE; + virtual const SdpFmtpAttributeList& GetFmtp() const MOZ_OVERRIDE; + virtual const SdpImageattrAttributeList& GetImageattr() const MOZ_OVERRIDE; + virtual const SdpMsidAttributeList& GetMsid() const MOZ_OVERRIDE; + virtual const SdpRtcpFbAttributeList& GetRtcpFb() const MOZ_OVERRIDE; + virtual const SdpRtpmapAttributeList& GetRtpmap() const MOZ_OVERRIDE; + virtual const SdpSctpmapAttributeList& GetSctpmap() const MOZ_OVERRIDE; + + // These attributes are effectively simple types, so we'll make life + // easy by just returning their value. + virtual const std::string& GetIcePwd() const MOZ_OVERRIDE; + virtual const std::string& GetIceUfrag() const MOZ_OVERRIDE; + virtual const std::string& GetIdentity() const MOZ_OVERRIDE; + virtual const std::string& GetLabel() const MOZ_OVERRIDE; + virtual unsigned int GetMaxptime() const MOZ_OVERRIDE; + virtual const std::string& GetMid() const MOZ_OVERRIDE; + virtual const std::string& GetMsidSemantic() const MOZ_OVERRIDE; + virtual unsigned int GetPtime() const MOZ_OVERRIDE; + + virtual SdpDirectionAttribute::Direction GetDirection() const MOZ_OVERRIDE; + + virtual void Serialize(std::ostream&) const MOZ_OVERRIDE; + + virtual ~SipccSdpAttributeList(); + +private: + static const std::string kEmptyString; + static const size_t kNumAttributeTypes = SdpAttribute::kLastAttribute + 1; + + // Pass a session-level attribute list if constructing a media-level one, + // otherwise pass nullptr + explicit SipccSdpAttributeList(const SipccSdpAttributeList* sessionLevel); + + bool Load(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void LoadSimpleStrings(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder); + void LoadSimpleString(sdp_t* sdp, uint16_t level, sdp_attr_e attr, + AttributeType targetType, SdpErrorHolder& errorHolder); + void LoadSimpleNumbers(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder); + void LoadSimpleNumber(sdp_t* sdp, uint16_t level, sdp_attr_e attr, + AttributeType targetType, SdpErrorHolder& errorHolder); + void LoadFlags(sdp_t* sdp, uint16_t level); + void LoadDirection(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + bool LoadRtpmap(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + bool LoadSctpmap(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void LoadIceAttributes(sdp_t* sdp, uint16_t level); + bool LoadFingerprint(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void LoadCandidate(sdp_t* sdp, uint16_t level); + void LoadSetup(sdp_t* sdp, uint16_t level); + bool LoadGroups(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void LoadFmtp(sdp_t* sdp, uint16_t level); + void LoadMsids(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void LoadExtmap(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void LoadRtcpFb(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + static SdpRtpmapAttributeList::CodecType GetCodecType(rtp_ptype type); + + bool + AtSessionLevel() const + { + return !mSessionLevel; + } + bool IsAllowedHere(SdpAttribute::AttributeType type) const; + void WarnAboutMisplacedAttribute(SdpAttribute::AttributeType type, + uint32_t lineNumber, + SdpErrorHolder& errorHolder); + + const SipccSdpAttributeList* mSessionLevel; + + SdpAttribute* mAttributes[kNumAttributeTypes]; + + SipccSdpAttributeList(const SipccSdpAttributeList& orig) MOZ_DELETE; + SipccSdpAttributeList& operator=(const SipccSdpAttributeList& rhs) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp b/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp new file mode 100644 index 00000000000..354e22b66f6 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "signaling/src/sdp/SipccSdpMediaSection.h" + +#include +#include "signaling/src/sdp/SdpErrorHolder.h" + +#ifdef CRLF +#undef CRLF +#endif +#define CRLF "\r\n" + +namespace mozilla +{ + +unsigned int +SipccSdpMediaSection::GetPort() const +{ + return mPort; +} + +void +SipccSdpMediaSection::SetPort(unsigned int port) +{ + mPort = port; +} + +unsigned int +SipccSdpMediaSection::GetPortCount() const +{ + return mPortCount; +} + +SdpMediaSection::Protocol +SipccSdpMediaSection::GetProtocol() const +{ + return mProtocol; +} + +const SdpConnection& +SipccSdpMediaSection::GetConnection() const +{ + return *mConnection; +} + +SdpConnection& +SipccSdpMediaSection::GetConnection() +{ + return *mConnection; +} + +uint32_t +SipccSdpMediaSection::GetBandwidth(const std::string& type) const +{ + auto found = mBandwidths.find(type); + if (found == mBandwidths.end()) { + return 0; + } + return found->second; +} + +const std::vector& +SipccSdpMediaSection::GetFormats() const +{ + return mFormats; +} + +const SdpAttributeList& +SipccSdpMediaSection::GetAttributeList() const +{ + return mAttributeList; +} + +SdpAttributeList& +SipccSdpMediaSection::GetAttributeList() +{ + return mAttributeList; +} + +SdpDirectionAttribute +SipccSdpMediaSection::GetDirectionAttribute() const +{ + return SdpDirectionAttribute(mAttributeList.GetDirection()); +} + +bool +SipccSdpMediaSection::Load(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + switch (sdp_get_media_type(sdp, level)) { + case SDP_MEDIA_AUDIO: + mMediaType = kAudio; + break; + case SDP_MEDIA_VIDEO: + mMediaType = kVideo; + break; + case SDP_MEDIA_APPLICATION: + mMediaType = kApplication; + break; + case SDP_MEDIA_TEXT: + mMediaType = kText; + break; + + default: + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "Unsupported media section type"); + return false; + } + + mPort = sdp_get_media_portnum(sdp, level); + int32_t pc = sdp_get_media_portcount(sdp, level); + if (pc == SDP_INVALID_VALUE) { + // SDP_INVALID_VALUE (ie; -2) is used when there is no port count. :( + mPortCount = 0; + } else if (pc > static_cast(UINT16_MAX) || pc < 0) { + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "Invalid port count"); + return false; + } else { + mPortCount = pc; + } + + if (!LoadProtocol(sdp, level, errorHolder)) { + return false; + } + LoadFormats(sdp, level); + + if (!mAttributeList.Load(sdp, level, errorHolder)) { + return false; + } + + if (!mBandwidths.Load(sdp, level, errorHolder)) { + return false; + } + + return LoadConnection(sdp, level, errorHolder); +} + +bool +SipccSdpMediaSection::LoadProtocol(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + switch (sdp_get_media_transport(sdp, level)) { + case SDP_TRANSPORT_RTPAVP: + mProtocol = kRtpAvp; + break; + case SDP_TRANSPORT_RTPSAVP: + mProtocol = kRtpSavp; + break; + case SDP_TRANSPORT_RTPAVPF: + mProtocol = kRtpAvpf; + break; + case SDP_TRANSPORT_RTPSAVPF: + mProtocol = kRtpSavpf; + break; + case SDP_TRANSPORT_UDPTLSRTPSAVP: + mProtocol = kUdpTlsRtpSavp; + break; + case SDP_TRANSPORT_UDPTLSRTPSAVPF: + mProtocol = kUdpTlsRtpSavpf; + break; + case SDP_TRANSPORT_TCPTLSRTPSAVP: + mProtocol = kTcpTlsRtpSavp; + break; + case SDP_TRANSPORT_TCPTLSRTPSAVPF: + mProtocol = kTcpTlsRtpSavpf; + break; + case SDP_TRANSPORT_DTLSSCTP: + mProtocol = kDtlsSctp; + break; + + default: + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "Unsupported media transport type"); + return false; + } + return true; +} + +void +SipccSdpMediaSection::LoadFormats(sdp_t* sdp, uint16_t level) +{ + sdp_media_e mtype = sdp_get_media_type(sdp, level); + + if (mtype == SDP_MEDIA_APPLICATION) { + uint32_t ptype = sdp_get_media_sctp_port(sdp, level); + std::ostringstream osPayloadType; + osPayloadType << ptype; + mFormats.push_back(osPayloadType.str()); + } else if (mtype == SDP_MEDIA_AUDIO || mtype == SDP_MEDIA_VIDEO) { + uint16_t count = sdp_get_media_num_payload_types(sdp, level); + for (uint16_t i = 0; i < count; ++i) { + sdp_payload_ind_e indicator; // we ignore this, which is fine + uint32_t ptype = + sdp_get_media_payload_type(sdp, level, i + 1, &indicator); + + std::ostringstream osPayloadType; + // sipcc stores payload types in a funny way. When sipcc and the SDP it + // parsed differ on what payload type number should be used for a given + // codec, sipcc's value goes in the lower byte, and the SDP's value in + // the upper byte. When they do not differ, only the lower byte is used. + // We want what was in the SDP, verbatim. + osPayloadType << GET_DYN_PAYLOAD_TYPE_VALUE(ptype); + mFormats.push_back(osPayloadType.str()); + } + } +} + +bool +SipccSdpMediaSection::LoadConnection(sdp_t* sdp, uint16_t level, + SdpErrorHolder& errorHolder) +{ + if (!sdp_connection_valid(sdp, level)) { + level = SDP_SESSION_LEVEL; + if (!sdp_connection_valid(sdp, level)) { + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "Missing c= line"); + return false; + } + } + + sdp_nettype_e type = sdp_get_conn_nettype(sdp, level); + if (type != SDP_NT_INTERNET) { + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "Unsupported network type"); + return false; + } + + sdp::AddrType addrType; + switch (sdp_get_conn_addrtype(sdp, level)) { + case SDP_AT_IP4: + addrType = sdp::kIPv4; + break; + case SDP_AT_IP6: + addrType = sdp::kIPv6; + break; + default: + errorHolder.AddParseError(sdp_get_media_line_number(sdp, level), + "Unsupported address type"); + return false; + } + + std::string address = sdp_get_conn_address(sdp, level); + int16_t ttl = static_cast(sdp_get_mcast_ttl(sdp, level)); + if (ttl < 0) { + ttl = 0; + } + int32_t numAddr = + static_cast(sdp_get_mcast_num_of_addresses(sdp, level)); + if (numAddr < 0) { + numAddr = 0; + } + mConnection = MakeUnique(addrType, address, ttl, numAddr); + return true; +} + +void +SipccSdpMediaSection::AddCodec(const std::string& pt, const std::string& name, + uint32_t clockrate, uint16_t channels) +{ + mFormats.push_back(pt); + + SdpRtpmapAttributeList* rtpmap = new SdpRtpmapAttributeList(); + if (mAttributeList.HasAttribute(SdpAttribute::kRtpmapAttribute)) { + const SdpRtpmapAttributeList& old = mAttributeList.GetRtpmap(); + for (auto it = old.mRtpmaps.begin(); it != old.mRtpmaps.end(); ++it) { + rtpmap->mRtpmaps.push_back(*it); + } + } + SdpRtpmapAttributeList::CodecType codec = SdpRtpmapAttributeList::kOtherCodec; + if (name == "opus") { + codec = SdpRtpmapAttributeList::kOpus; + } else if (name == "G722") { + codec = SdpRtpmapAttributeList::kG722; + } else if (name == "PCMU") { + codec = SdpRtpmapAttributeList::kPCMU; + } else if (name == "PCMA") { + codec = SdpRtpmapAttributeList::kPCMA; + } else if (name == "VP8") { + codec = SdpRtpmapAttributeList::kVP8; + } else if (name == "H264") { + codec = SdpRtpmapAttributeList::kH264; + } + + rtpmap->PushEntry(pt, codec, name, clockrate, channels); + mAttributeList.SetAttribute(rtpmap); +} + +void +SipccSdpMediaSection::AddDataChannel(const std::string& pt, + const std::string& name, uint16_t streams) +{ + // Only one allowed, for now. This may change as the specs (and deployments) + // evolve. + mFormats.clear(); + mFormats.push_back(pt); + SdpSctpmapAttributeList* sctpmap = new SdpSctpmapAttributeList(); + sctpmap->PushEntry(pt, name, streams); + mAttributeList.SetAttribute(sctpmap); +} + +void +SipccSdpMediaSection::Serialize(std::ostream& os) const +{ + os << "m=" << mMediaType << " " << mPort; + if (mPortCount) { + os << "/" << mPortCount; + } + os << " " << mProtocol; + for (auto i = mFormats.begin(); i != mFormats.end(); ++i) { + os << " " << (*i); + } + os << CRLF; + + // We dont do i= + + if (mConnection) { + os << *mConnection; + } + + mBandwidths.Serialize(os); + + // We dont do k= because they're evil + + os << mAttributeList; +} + +} // namespace mozilla diff --git a/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.h b/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.h new file mode 100644 index 00000000000..ca43591bb0c --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SIPCCSDPMEDIASECTION_H_ +#define _SIPCCSDPMEDIASECTION_H_ + +#include "mozilla/Attributes.h" +#include "mozilla/UniquePtr.h" +#include "signaling/src/sdp/SdpMediaSection.h" +#include "signaling/src/sdp/SipccSdpAttributeList.h" + +#include + +extern "C" { +#include "signaling/src/sdp/sipcc/sdp.h" +} + +namespace mozilla +{ + +class SipccSdp; +class SdpErrorHolder; + +class SipccSdpBandwidths MOZ_FINAL : public std::map +{ +public: + bool Load(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void Serialize(std::ostream& os) const; +}; + +class SipccSdpMediaSection MOZ_FINAL : public SdpMediaSection +{ + friend class SipccSdp; + +public: + ~SipccSdpMediaSection() {} + + virtual MediaType + GetMediaType() const MOZ_OVERRIDE + { + return mMediaType; + } + + virtual unsigned int GetPort() const MOZ_OVERRIDE; + virtual void SetPort(unsigned int port) MOZ_OVERRIDE; + virtual unsigned int GetPortCount() const MOZ_OVERRIDE; + virtual Protocol GetProtocol() const MOZ_OVERRIDE; + virtual const SdpConnection& GetConnection() const MOZ_OVERRIDE; + virtual SdpConnection& GetConnection() MOZ_OVERRIDE; + virtual uint32_t GetBandwidth(const std::string& type) const MOZ_OVERRIDE; + virtual const std::vector& GetFormats() const MOZ_OVERRIDE; + + virtual const SdpAttributeList& GetAttributeList() const MOZ_OVERRIDE; + virtual SdpAttributeList& GetAttributeList() MOZ_OVERRIDE; + virtual SdpDirectionAttribute GetDirectionAttribute() const MOZ_OVERRIDE; + + virtual void AddCodec(const std::string& pt, const std::string& name, + uint32_t clockrate, uint16_t channels) MOZ_OVERRIDE; + + virtual void AddDataChannel(const std::string& pt, const std::string& name, + uint16_t streams) MOZ_OVERRIDE; + + virtual void Serialize(std::ostream&) const MOZ_OVERRIDE; + +private: + SipccSdpMediaSection(size_t level, const SipccSdpAttributeList* sessionLevel) + : SdpMediaSection(level), mAttributeList(sessionLevel) + { + } + + bool Load(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + bool LoadConnection(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + bool LoadProtocol(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder); + void LoadFormats(sdp_t* sdp, uint16_t level); + + // the following values are cached on first get + MediaType mMediaType; + uint16_t mPort; + uint16_t mPortCount; + Protocol mProtocol; + std::vector mFormats; + + UniquePtr mConnection; + SipccSdpBandwidths mBandwidths; + + SipccSdpAttributeList mAttributeList; +}; +} + +#endif diff --git a/media/webrtc/signaling/src/sdp/SipccSdpParser.cpp b/media/webrtc/signaling/src/sdp/SipccSdpParser.cpp new file mode 100644 index 00000000000..04fea305c91 --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdpParser.cpp @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "signaling/src/sdp/SipccSdpParser.h" +#include "signaling/src/sdp/SipccSdp.h" + +#include +extern "C" { +#include "signaling/src/sdp/sipcc/sdp.h" +} + +namespace mozilla +{ + +extern "C" { + +void +sipcc_sdp_parser_error_handler(void *context, uint32_t line, + const char *message) +{ + SdpErrorHolder *errorHolder = static_cast(context); + std::string err(message); + errorHolder->AddParseError(line, err); +} + +} // extern "C" + +UniquePtr +SipccSdpParser::Parse(const std::string &sdpText) +{ + ClearParseErrors(); + + sdp_conf_options_t *sipcc_config = sdp_init_config(); + if (!sipcc_config) { + return UniquePtr(); + } + + sdp_nettype_supported(sipcc_config, SDP_NT_INTERNET, true); + sdp_addrtype_supported(sipcc_config, SDP_AT_IP4, true); + sdp_addrtype_supported(sipcc_config, SDP_AT_IP6, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPAVP, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPAVPF, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPSAVP, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPSAVPF, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_UDPTLSRTPSAVP, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_UDPTLSRTPSAVPF, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_TCPTLSRTPSAVP, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_TCPTLSRTPSAVPF, true); + sdp_transport_supported(sipcc_config, SDP_TRANSPORT_DTLSSCTP, true); + sdp_require_session_name(sipcc_config, false); + + sdp_config_set_error_handler(sipcc_config, &sipcc_sdp_parser_error_handler, + this); + + // Takes ownership of |sipcc_config| iff it succeeds + sdp_t *sdp = sdp_init_description(sipcc_config); + if (!sdp) { + sdp_free_config(sipcc_config); + return UniquePtr(); + } + + const char *rawString = sdpText.c_str(); + sdp_result_e sdpres = sdp_parse(sdp, rawString, sdpText.length()); + if (sdpres != SDP_SUCCESS) { + sdp_free_description(sdp); + return UniquePtr(); + } + + UniquePtr sipccSdp(new SipccSdp); + + bool success = sipccSdp->Load(sdp, *this); + sdp_free_description(sdp); + if (!success) { + return UniquePtr(); + } + + return UniquePtr(Move(sipccSdp)); +} + +} // namespace mozilla diff --git a/media/webrtc/signaling/src/sdp/SipccSdpParser.h b/media/webrtc/signaling/src/sdp/SipccSdpParser.h new file mode 100644 index 00000000000..e188dc4bc2e --- /dev/null +++ b/media/webrtc/signaling/src/sdp/SipccSdpParser.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SIPCCSDPPARSER_H_ +#define _SIPCCSDPPARSER_H_ + +#include + +#include "mozilla/UniquePtr.h" + +#include "signaling/src/sdp/Sdp.h" +#include "signaling/src/sdp/SdpErrorHolder.h" + +namespace mozilla +{ + +class SipccSdpParser MOZ_FINAL : public SdpErrorHolder +{ +public: + SipccSdpParser() {} + virtual ~SipccSdpParser() {} + + /** + * This parses the provided text into an SDP object. + * This returns a nullptr-valued pointer if things go poorly. + */ + UniquePtr Parse(const std::string& sdpText); +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/test/sdp_unittests.cpp b/media/webrtc/signaling/test/sdp_unittests.cpp index eaa03b74889..676368c86d3 100644 --- a/media/webrtc/signaling/test/sdp_unittests.cpp +++ b/media/webrtc/signaling/test/sdp_unittests.cpp @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -7,6 +9,7 @@ #include "CSFLog.h" #include +#include #define GTEST_HAS_RTTI 0 #include "gtest/gtest.h" @@ -26,11 +29,22 @@ MtransportTestUtils *test_utils; nsCOMPtr gThread; +#include "signaling/src/sdp/SipccSdpParser.h" +#include "signaling/src/sdp/SdpMediaSection.h" +#include "signaling/src/sdp/SdpAttribute.h" + extern "C" { -#include "sdp.h" -#include "sdp_private.h" +#include "signaling/src/sdp/sipcc/sdp.h" +#include "signaling/src/sdp/sipcc/sdp_private.h" } +#ifdef CRLF +#undef CRLF +#endif +#define CRLF "\r\n" + +using namespace mozilla; + namespace test { static bool SetupGlobalThread() { @@ -51,32 +65,10 @@ static bool SetupGlobalThread() { class SdpTest : public ::testing::Test { public: SdpTest() : sdp_ptr_(nullptr) { - sdp_media_e supported_media[] = { - SDP_MEDIA_AUDIO, - SDP_MEDIA_VIDEO, - SDP_MEDIA_APPLICATION, - SDP_MEDIA_DATA, - SDP_MEDIA_CONTROL, - SDP_MEDIA_NAS_RADIUS, - SDP_MEDIA_NAS_TACACS, - SDP_MEDIA_NAS_DIAMETER, - SDP_MEDIA_NAS_L2TP, - SDP_MEDIA_NAS_LOGIN, - SDP_MEDIA_NAS_NONE, - SDP_MEDIA_IMAGE, - }; + } - config_p_ = sdp_init_config(); - unsigned int i; - for (i = 0; i < sizeof(supported_media) / sizeof(sdp_media_e); i++) { - sdp_media_supported(config_p_, supported_media[i], true); - } - sdp_nettype_supported(config_p_, SDP_NT_INTERNET, true); - sdp_addrtype_supported(config_p_, SDP_AT_IP4, true); - sdp_addrtype_supported(config_p_, SDP_AT_IP6, true); - sdp_transport_supported(config_p_, SDP_TRANSPORT_RTPSAVPF, true); - sdp_transport_supported(config_p_, SDP_TRANSPORT_UDPTL, true); - sdp_require_session_name(config_p_, false); + ~SdpTest() { + sdp_free_description(sdp_ptr_); } static void SetUpTestCase() { @@ -96,13 +88,44 @@ class SdpTest : public ::testing::Test { if (!sdp_ptr_) { sdp_free_description(sdp_ptr_); } - sdp_ptr_ = sdp_init_description("BogusPeerConnectionId", config_p_); + + sdp_media_e supported_media[] = { + SDP_MEDIA_AUDIO, + SDP_MEDIA_VIDEO, + SDP_MEDIA_APPLICATION, + SDP_MEDIA_DATA, + SDP_MEDIA_CONTROL, + SDP_MEDIA_NAS_RADIUS, + SDP_MEDIA_NAS_TACACS, + SDP_MEDIA_NAS_DIAMETER, + SDP_MEDIA_NAS_L2TP, + SDP_MEDIA_NAS_LOGIN, + SDP_MEDIA_NAS_NONE, + SDP_MEDIA_IMAGE, + }; + + sdp_conf_options_t *config_p = sdp_init_config(); + unsigned int i; + for (i = 0; i < sizeof(supported_media) / sizeof(sdp_media_e); i++) { + sdp_media_supported(config_p, supported_media[i], true); + } + sdp_nettype_supported(config_p, SDP_NT_INTERNET, true); + sdp_addrtype_supported(config_p, SDP_AT_IP4, true); + sdp_addrtype_supported(config_p, SDP_AT_IP6, true); + sdp_transport_supported(config_p, SDP_TRANSPORT_RTPSAVPF, true); + sdp_transport_supported(config_p, SDP_TRANSPORT_UDPTL, true); + sdp_require_session_name(config_p, false); + + sdp_ptr_ = sdp_init_description(config_p); + if (!sdp_ptr_) { + sdp_free_config(config_p); + } } void ParseSdp(const std::string &sdp_str) { - char *bufp = const_cast(sdp_str.data()); + const char *buf = sdp_str.data(); ResetSdp(); - ASSERT_EQ(sdp_parse(sdp_ptr_, &bufp, sdp_str.size()), SDP_SUCCESS); + ASSERT_EQ(sdp_parse(sdp_ptr_, buf, sdp_str.size()), SDP_SUCCESS); } void InitLocalSdp() { @@ -152,9 +175,9 @@ class SdpTest : public ::testing::Test { return final_level_; } - u16 AddNewRtcpFbAck(int level, sdp_rtcp_fb_ack_type_e type, - u16 payload = SDP_ALL_PAYLOADS) { - u16 inst_num = 0; + uint16_t AddNewRtcpFbAck(int level, sdp_rtcp_fb_ack_type_e type, + uint16_t payload = SDP_ALL_PAYLOADS) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_rtcp_fb_ack(sdp_ptr_, level, payload, inst_num, @@ -162,9 +185,9 @@ class SdpTest : public ::testing::Test { return inst_num; } - u16 AddNewRtcpFbNack(int level, sdp_rtcp_fb_nack_type_e type, - u16 payload = SDP_ALL_PAYLOADS) { - u16 inst_num = 0; + uint16_t AddNewRtcpFbNack(int level, sdp_rtcp_fb_nack_type_e type, + uint16_t payload = SDP_ALL_PAYLOADS) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_rtcp_fb_nack(sdp_ptr_, level, payload, inst_num, @@ -172,9 +195,9 @@ class SdpTest : public ::testing::Test { return inst_num; } - u16 AddNewRtcpFbTrrInt(int level, u32 interval, - u16 payload = SDP_ALL_PAYLOADS) { - u16 inst_num = 0; + uint16_t AddNewRtcpFbTrrInt(int level, uint32_t interval, + uint16_t payload = SDP_ALL_PAYLOADS) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_rtcp_fb_trr_int(sdp_ptr_, level, payload, inst_num, @@ -182,17 +205,17 @@ class SdpTest : public ::testing::Test { return inst_num; } - u16 AddNewRtcpFbCcm(int level, sdp_rtcp_fb_ccm_type_e type, - u16 payload = SDP_ALL_PAYLOADS) { - u16 inst_num = 0; + uint16_t AddNewRtcpFbCcm(int level, sdp_rtcp_fb_ccm_type_e type, + uint16_t payload = SDP_ALL_PAYLOADS) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_rtcp_fb_ccm(sdp_ptr_, level, payload, inst_num, type), SDP_SUCCESS); return inst_num; } - u16 AddNewExtMap(int level, const char* uri) { - u16 inst_num = 0; + uint16_t AddNewExtMap(int level, const char* uri) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_EXTMAP, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_extmap(sdp_ptr_, level, inst_num, @@ -200,8 +223,8 @@ class SdpTest : public ::testing::Test { return inst_num; } - u16 AddNewFmtpMaxFs(int level, u32 max_fs) { - u16 inst_num = 0; + uint16_t AddNewFmtpMaxFs(int level, uint32_t max_fs) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num, @@ -211,8 +234,8 @@ class SdpTest : public ::testing::Test { return inst_num; } - u16 AddNewFmtpMaxFr(int level, u32 max_fr) { - u16 inst_num = 0; + uint16_t AddNewFmtpMaxFr(int level, uint32_t max_fr) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num, @@ -222,8 +245,8 @@ class SdpTest : public ::testing::Test { return inst_num; } - u16 AddNewFmtpMaxFsFr(int level, u32 max_fs, u32 max_fr) { - u16 inst_num = 0; + uint16_t AddNewFmtpMaxFsFr(int level, uint32_t max_fs, uint32_t max_fr) { + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP, &inst_num), SDP_SUCCESS); EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num, @@ -237,7 +260,6 @@ class SdpTest : public ::testing::Test { protected: int final_level_; - void *config_p_; sdp_t *sdp_ptr_; }; @@ -245,9 +267,9 @@ static const std::string kVideoSdp = "v=0\r\n" "o=- 137331303 2 IN IP4 127.0.0.1\r\n" "s=SIP Call\r\n" + "c=IN IP4 198.51.100.7\r\n" "t=0 0\r\n" "m=video 56436 RTP/SAVPF 120\r\n" - "c=IN IP4 198.51.100.7\r\n" "a=rtpmap:120 VP8/90000\r\n"; TEST_F(SdpTest, parseRtcpFbAckRpsi) { @@ -752,13 +774,13 @@ TEST_F(SdpTest, parseExtMap) { } TEST_F(SdpTest, parseFmtpMaxFs) { - u32 val = 0; + uint32_t val = 0; ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n"); ASSERT_EQ(sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS); ASSERT_EQ(val, 300U); } TEST_F(SdpTest, parseFmtpMaxFr) { - u32 val = 0; + uint32_t val = 0; ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n"); ASSERT_EQ(sdp_attr_get_fmtp_max_fr(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS); ASSERT_EQ(val, 30U); @@ -802,19 +824,19 @@ static const std::string kBrokenFmtp = "a=fmtp:120 max-fs=300;max\0fr=30"; TEST_F(SdpTest, parseBrokenFmtp) { - u32 val = 0; - char *buf = const_cast(kBrokenFmtp.data()); + uint32_t val = 0; + const char *buf = kBrokenFmtp.data(); ResetSdp(); /* We need to manually invoke the parser here to be able to specify the length * of the string beyond the \0 in last line of the string. */ - ASSERT_EQ(sdp_parse(sdp_ptr_, &buf, 165), SDP_SUCCESS); + ASSERT_EQ(sdp_parse(sdp_ptr_, buf, 165), SDP_SUCCESS); ASSERT_EQ(sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, &val), SDP_INVALID_PARAMETER); } TEST_F(SdpTest, addIceLite) { InitLocalSdp(); - u16 inst_num = 0; + uint16_t inst_num = 0; EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, SDP_SESSION_LEVEL, 0, SDP_ATTR_ICE_LITE, &inst_num), SDP_SUCCESS); std::string body = SerializeSdp(); @@ -833,6 +855,1585 @@ TEST_F(SdpTest, parseIceLite) { SDP_SESSION_LEVEL, 0)); } +class NewSdpTest : public ::testing::Test, + public ::testing::WithParamInterface { + public: + NewSdpTest() {} + + void ParseSdp(const std::string &sdp, bool expectSuccess = true) { + mSdp = mozilla::Move(mParser.Parse(sdp)); + + // Are we configured to do a parse and serialize before actually + // running the test? + if (GetParam()) { + std::stringstream os; + + if (expectSuccess) { + ASSERT_TRUE(mSdp) << "Parse failed on first pass: " + << GetParseErrors(); + } + + if (mSdp) { + // Serialize and re-parse + mSdp->Serialize(os); + mSdp = mozilla::Move(mParser.Parse(os.str())); + + // Whether we expected the parse to work or not, it should + // succeed the second time if it succeeded the first. + ASSERT_TRUE(mSdp) << "Parse failed on second pass, SDP was: " + << std::endl << os.str() << std::endl + << "Errors were: " << GetParseErrors(); + + // Serialize again and compare + std::stringstream os2; + mSdp->Serialize(os2); + ASSERT_EQ(os.str(), os2.str()); + } + } + + if (expectSuccess) { + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(0U, mParser.GetParseErrors().size()) + << "Got unexpected parse errors/warnings: " + << GetParseErrors(); + } + } + + // For streaming parse errors + std::string GetParseErrors() const { + std::stringstream output; + for (auto e = mParser.GetParseErrors().begin(); + e != mParser.GetParseErrors().end(); + ++e) { + output << e->first << ": " << e->second << std::endl; + } + return output.str(); + } + + void CheckRtpmap(const std::string& expected_pt, + SdpRtpmapAttributeList::CodecType codec, + const std::string& name, + uint32_t clock, + uint16_t channels, + const std::string& search_pt, + const SdpRtpmapAttributeList& rtpmaps) const { + ASSERT_TRUE(rtpmaps.HasEntry(search_pt)); + auto attr = rtpmaps.GetEntry(search_pt); + ASSERT_EQ(expected_pt, attr.pt); + ASSERT_EQ(codec, attr.codec); + ASSERT_EQ(name, attr.name); + ASSERT_EQ(clock, attr.clock); + ASSERT_EQ(channels, attr.channels); + } + + void CheckSctpmap(const std::string& expected_pt, + const std::string& name, + uint16_t streams, + const std::string& search_pt, + const SdpSctpmapAttributeList& sctpmaps) const { + ASSERT_TRUE(sctpmaps.HasEntry(search_pt)); + auto attr = sctpmaps.GetEntry(search_pt); + ASSERT_EQ(expected_pt, search_pt); + ASSERT_EQ(expected_pt, attr.pt); + ASSERT_EQ(name, attr.name); + ASSERT_EQ(streams, attr.streams); + } + + void CheckRtcpFb(const SdpRtcpFbAttributeList::Feedback& feedback, + const std::string& pt, + SdpRtcpFbAttributeList::Type type, + const std::string& first_parameter, + const std::string& extra = "") const { + ASSERT_EQ(pt, feedback.pt); + ASSERT_EQ(type, feedback.type); + ASSERT_EQ(first_parameter, feedback.parameter); + ASSERT_EQ(extra, feedback.extra); + } + + void CheckSerialize(const std::string& expected, + const SdpAttribute& attr) const { + std::stringstream str; + attr.Serialize(str); + ASSERT_EQ(expected, str.str()); + } + + SipccSdpParser mParser; + mozilla::UniquePtr mSdp; +}; // class NewSdpTest + +TEST_P(NewSdpTest, CreateDestroy) { +} + +TEST_P(NewSdpTest, ParseEmpty) { + ParseSdp("", false); + ASSERT_FALSE(mSdp); + ASSERT_NE(0U, mParser.GetParseErrors().size()) + << "Expected at least one parse error."; +} + +const std::string kBadSdp = "This is SDPARTA!!!!"; + +TEST_P(NewSdpTest, ParseGarbage) { + ParseSdp(kBadSdp, false); + ASSERT_FALSE(mSdp); + ASSERT_NE(0U, mParser.GetParseErrors().size()) + << "Expected at least one parse error."; +} + +TEST_P(NewSdpTest, ParseGarbageTwice) { + ParseSdp(kBadSdp, false); + ASSERT_FALSE(mSdp); + size_t errorCount = mParser.GetParseErrors().size(); + ASSERT_NE(0U, errorCount) + << "Expected at least one parse error."; + ParseSdp(kBadSdp, false); + ASSERT_FALSE(mSdp); + ASSERT_EQ(errorCount, mParser.GetParseErrors().size()) + << "Expected same error count for same SDP."; +} + +TEST_P(NewSdpTest, ParseMinimal) { + ParseSdp(kVideoSdp); + ASSERT_EQ(0U, mParser.GetParseErrors().size()) << + "Got parse errors: " << GetParseErrors(); +} + +TEST_P(NewSdpTest, CheckOriginGetUsername) { + ParseSdp(kVideoSdp); + ASSERT_EQ("-", mSdp->GetOrigin().GetUsername()) + << "Wrong username in origin"; +} + +TEST_P(NewSdpTest, CheckOriginGetSessionId) { + ParseSdp(kVideoSdp); + ASSERT_EQ(137331303U, mSdp->GetOrigin().GetSessionId()) + << "Wrong session id in origin"; +} + +TEST_P(NewSdpTest, CheckOriginGetSessionVersion) { + ParseSdp(kVideoSdp); + ASSERT_EQ(2U , mSdp->GetOrigin().GetSessionVersion()) + << "Wrong version in origin"; +} + +TEST_P(NewSdpTest, CheckOriginGetAddrType) { + ParseSdp(kVideoSdp); + ASSERT_EQ(sdp::kIPv4, mSdp->GetOrigin().GetAddrType()) + << "Wrong address type in origin"; +} + +TEST_P(NewSdpTest, CheckOriginGetAddress) { + ParseSdp(kVideoSdp); + ASSERT_EQ("127.0.0.1" , mSdp->GetOrigin().GetAddress()) + << "Wrong address in origin"; +} + +TEST_P(NewSdpTest, CheckGetMissingBandwidth) { + ParseSdp(kVideoSdp); + ASSERT_EQ(0U, mSdp->GetBandwidth("CT")) + << "Wrong bandwidth in session"; +} + +TEST_P(NewSdpTest, CheckGetBandwidth) { + ParseSdp("v=0" CRLF + "o=- 137331303 2 IN IP4 127.0.0.1" CRLF + "s=SIP Call" CRLF + "c=IN IP4 198.51.100.7" CRLF + "b=CT:5000" CRLF + "t=0 0" CRLF + "m=video 56436 RTP/SAVPF 120" CRLF + "a=rtpmap:120 VP8/90000" CRLF + ); + ASSERT_EQ(5000U, mSdp->GetBandwidth("CT")) + << "Wrong bandwidth in session"; +} + +TEST_P(NewSdpTest, CheckGetMediaSectionsCount) { + ParseSdp(kVideoSdp); + ASSERT_EQ(1U, mSdp->GetMediaSectionCount()) + << "Wrong number of media sections"; +} + +TEST_P(NewSdpTest, CheckMediaSectionGetMediaType) { + ParseSdp(kVideoSdp); + ASSERT_EQ(SdpMediaSection::kVideo, mSdp->GetMediaSection(0).GetMediaType()) + << "Wrong type for first media section"; +} + +TEST_P(NewSdpTest, CheckMediaSectionGetProtocol) { + ParseSdp(kVideoSdp); + ASSERT_EQ(SdpMediaSection::kRtpSavpf, mSdp->GetMediaSection(0).GetProtocol()) + << "Wrong protocol for video"; +} + +TEST_P(NewSdpTest, CheckMediaSectionGetFormats) { + ParseSdp(kVideoSdp); + auto video_formats = mSdp->GetMediaSection(0).GetFormats(); + ASSERT_EQ(1U, video_formats.size()) << "Wrong number of formats for video"; + ASSERT_EQ("120", video_formats[0]); +} + +TEST_P(NewSdpTest, CheckMediaSectionGetPort) { + ParseSdp(kVideoSdp); + ASSERT_EQ(56436U, mSdp->GetMediaSection(0).GetPort()) + << "Wrong port number in media section"; +} + +TEST_P(NewSdpTest, CheckMediaSectionGetMissingPortCount) { + ParseSdp(kVideoSdp); + ASSERT_EQ(0U, mSdp->GetMediaSection(0).GetPortCount()) + << "Wrong port count in media section"; +} + +TEST_P(NewSdpTest, CheckMediaSectionGetPortCount) { + ParseSdp(kVideoSdp + + "m=audio 12345/2 RTP/SAVPF 0" CRLF + "a=rtpmap:0 PCMU/8000" CRLF + ); + ASSERT_EQ(2U, mSdp->GetMediaSectionCount()) + << "Wrong number of media sections"; + ASSERT_EQ(2U, mSdp->GetMediaSection(1).GetPortCount()) + << "Wrong port count in media section"; +} + +TEST_P(NewSdpTest, CheckMediaSectionGetMissingBandwidth) { + ParseSdp(kVideoSdp); + ASSERT_EQ(0U, mSdp->GetMediaSection(0).GetBandwidth("CT")) + << "Wrong bandwidth in media section"; +} + +TEST_P(NewSdpTest, CheckMediaSectionGetBandwidth) { + ParseSdp("v=0\r\n" + "o=- 137331303 2 IN IP4 127.0.0.1\r\n" + "c=IN IP4 198.51.100.7\r\n" + "t=0 0\r\n" + "m=video 56436 RTP/SAVPF 120\r\n" + "b=CT:1000\r\n" + "a=rtpmap:120 VP8/90000\r\n"); + ASSERT_EQ(1000U, mSdp->GetMediaSection(0).GetBandwidth("CT")) + << "Wrong bandwidth in media section"; +} + + +// SDP from a basic A/V apprtc call FFX/FFX +const std::string kBasicAudioVideoOffer = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=ice-ufrag:4a799b2e" CRLF +"a=ice-pwd:e4cc12a910f106a0a744719425510e17" CRLF +"a=ice-lite" CRLF +"a=ice-options:trickle foo" CRLF +"a=msid-semantic:WMS plus" CRLF +"a=fingerprint:sha-256 DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF +"a=identity:blahblahblah foo;bar" CRLF +"a=group:BUNDLE first second" CRLF +"a=group:BUNDLE third" CRLF +"a=group:LS first third" CRLF +"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=mid:first" CRLF +"a=rtpmap:109 opus/48000/2" CRLF +"a=ptime:20" CRLF +"a=maxptime:20" CRLF +"a=rtpmap:9 G722/8000" CRLF +"a=rtpmap:0 PCMU/8000" CRLF +"a=rtpmap:8 PCMA/8000" CRLF +"a=rtpmap:101 telephone-event/8000" CRLF +"a=fmtp:101 0-15" CRLF +"a=ice-ufrag:00000000" CRLF +"a=ice-pwd:0000000000000000000000000000000" CRLF +"a=sendonly" CRLF +"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF +"a=setup:actpass" CRLF +"a=rtcp-mux" CRLF +"a=msid:track stream" CRLF +"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF +"a=candidate:2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453" CRLF +"a=candidate:3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761" CRLF +"a=candidate:6 1 UDP 16515071 162.222.183.171 51858 typ relay raddr 162.222.183.171 rport 51858" CRLF +"a=candidate:3 2 UDP 100401150 162.222.183.171 62454 typ relay raddr 162.222.183.171 rport 62454" CRLF +"a=candidate:2 2 UDP 1694236670 24.6.134.204 55428 typ srflx raddr 10.0.0.36 rport 55428" CRLF +"a=candidate:6 2 UDP 16515070 162.222.183.171 50340 typ relay raddr 162.222.183.171 rport 50340" CRLF +"a=candidate:0 2 UDP 2130379006 10.0.0.36 55428 typ host" CRLF +"a=end-of-candidates" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP6 ::1" CRLF +"a=mid:second" CRLF +"a=rtpmap:120 VP8/90000" CRLF +"a=fmtp:120 max-fs=3600;max-fr=30" CRLF +"a=recvonly" CRLF +"a=rtcp-fb:120 nack" CRLF +"a=rtcp-fb:120 nack pli" CRLF +"a=rtcp-fb:120 ccm fir" CRLF +"a=setup:active" CRLF +"a=rtcp-mux" CRLF +"a=msid:tracka streama" CRLF +"a=msid:trackb streamb" CRLF +"a=candidate:0 1 UDP 2130379007 10.0.0.36 59530 typ host" CRLF +"a=candidate:0 2 UDP 2130379006 10.0.0.36 64378 typ host" CRLF +"a=candidate:2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378" CRLF +"a=candidate:6 2 UDP 16515070 162.222.183.171 64941 typ relay raddr 162.222.183.171 rport 64941" CRLF +"a=candidate:6 1 UDP 16515071 162.222.183.171 64800 typ relay raddr 162.222.183.171 rport 64800" CRLF +"a=candidate:2 1 UDP 1694236671 24.6.134.204 59530 typ srflx raddr 10.0.0.36 rport 59530" CRLF +"a=candidate:3 1 UDP 100401151 162.222.183.171 62935 typ relay raddr 162.222.183.171 rport 62935" CRLF +"a=candidate:3 2 UDP 100401150 162.222.183.171 61026 typ relay raddr 162.222.183.171 rport 61026" CRLF +"a=end-of-candidates" CRLF +"m=audio 9 RTP/SAVPF 0" CRLF +"a=mid:third" CRLF +"a=rtpmap:0 PCMU/8000" CRLF +"a=ice-lite" CRLF +"a=ice-options:foo bar" CRLF +"a=msid:noappdata" CRLF +"a=bundle-only" CRLF; + +TEST_P(NewSdpTest, BasicAudioVideoSdpParse) { + ParseSdp(kBasicAudioVideoOffer); +} + +TEST_P(NewSdpTest, CheckIceUfrag) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kIceUfragAttribute)); + auto ice_ufrag = mSdp->GetAttributeList().GetIceUfrag(); + ASSERT_EQ("4a799b2e", ice_ufrag) << "Wrong ice-ufrag value"; + + ice_ufrag = mSdp->GetMediaSection(0) + .GetAttributeList().GetIceUfrag(); + ASSERT_EQ("00000000", ice_ufrag) << "ice-ufrag isn't overridden"; + + ice_ufrag = mSdp->GetMediaSection(1) + .GetAttributeList().GetIceUfrag(); + ASSERT_EQ("4a799b2e", ice_ufrag) << "ice-ufrag isn't carried to m-section"; +} + +TEST_P(NewSdpTest, CheckIcePwd) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kIcePwdAttribute)); + auto ice_pwd = mSdp->GetAttributeList().GetIcePwd(); + ASSERT_EQ("e4cc12a910f106a0a744719425510e17", ice_pwd) << "Wrong ice-pwd value"; + + ice_pwd = mSdp->GetMediaSection(0) + .GetAttributeList().GetIcePwd(); + ASSERT_EQ("0000000000000000000000000000000", ice_pwd) + << "ice-pwd isn't overridden"; + + ice_pwd = mSdp->GetMediaSection(1) + .GetAttributeList().GetIcePwd(); + ASSERT_EQ("e4cc12a910f106a0a744719425510e17", ice_pwd) + << "ice-pwd isn't carried to m-section"; +} + +TEST_P(NewSdpTest, CheckIceOptions) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kIceOptionsAttribute)); + auto ice_options = mSdp->GetAttributeList().GetIceOptions(); + ASSERT_EQ(2U, ice_options.mValues.size()) << "Wrong ice-options size"; + ASSERT_EQ("trickle", ice_options.mValues[0]) << "Wrong ice-options value"; + ASSERT_EQ("foo", ice_options.mValues[1]) << "Wrong ice-options value"; + + ASSERT_TRUE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kIceOptionsAttribute)); + auto ice_options_media_level = + mSdp->GetMediaSection(2).GetAttributeList().GetIceOptions(); + ASSERT_EQ(2U, ice_options_media_level.mValues.size()) << "Wrong ice-options size"; + ASSERT_EQ("foo", ice_options_media_level.mValues[0]) << "Wrong ice-options value"; + ASSERT_EQ("bar", ice_options_media_level.mValues[1]) << "Wrong ice-options value"; +} + +TEST_P(NewSdpTest, CheckFingerprint) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kFingerprintAttribute)); + auto fingerprints = mSdp->GetAttributeList().GetFingerprint(); + ASSERT_EQ(1U, fingerprints.mFingerprints.size()); + ASSERT_EQ(SdpFingerprintAttributeList::kSha256, + fingerprints.mFingerprints[0].hashFunc) + << "Wrong hash function"; + ASSERT_EQ("DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:" + "3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C", + SdpFingerprintAttributeList::FormatFingerprint( + fingerprints.mFingerprints[0].fingerprint)) + << "Wrong fingerprint"; + ASSERT_EQ(0xdfU, fingerprints.mFingerprints[0].fingerprint[0]) + << "first fingerprint element is iffy"; +} + +TEST_P(NewSdpTest, CheckIdentity) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kIdentityAttribute)); + auto identity = mSdp->GetAttributeList().GetIdentity(); + ASSERT_EQ("blahblahblah", identity) << "Wrong identity assertion"; +} + +TEST_P(NewSdpTest, CheckNumberOfMediaSections) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; +} + +TEST_P(NewSdpTest, CheckMlines) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + ASSERT_EQ(SdpMediaSection::kAudio, mSdp->GetMediaSection(0).GetMediaType()) + << "Wrong type for first media section"; + ASSERT_EQ(SdpMediaSection::kRtpSavpf, + mSdp->GetMediaSection(0).GetProtocol()) + << "Wrong protocol for audio"; + auto audio_formats = mSdp->GetMediaSection(0).GetFormats(); + ASSERT_EQ(5U, audio_formats.size()) << "Wrong number of formats for audio"; + ASSERT_EQ("109", audio_formats[0]); + ASSERT_EQ("9", audio_formats[1]); + ASSERT_EQ("0", audio_formats[2]); + ASSERT_EQ("8", audio_formats[3]); + ASSERT_EQ("101", audio_formats[4]); + + ASSERT_EQ(SdpMediaSection::kVideo, mSdp->GetMediaSection(1).GetMediaType()) + << "Wrong type for second media section"; + ASSERT_EQ(SdpMediaSection::kRtpSavpf, + mSdp->GetMediaSection(1).GetProtocol()) + << "Wrong protocol for video"; + auto video_formats = mSdp->GetMediaSection(1).GetFormats(); + ASSERT_EQ(1U, video_formats.size()) << "Wrong number of formats for video"; + ASSERT_EQ("120", video_formats[0]); + + ASSERT_EQ(SdpMediaSection::kAudio, mSdp->GetMediaSection(2).GetMediaType()) + << "Wrong type for third media section"; +} + +TEST_P(NewSdpTest, CheckSetup) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kSetupAttribute)); + ASSERT_EQ(SdpSetupAttribute::kActpass, + mSdp->GetMediaSection(0).GetAttributeList().GetSetup().mRole); + ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kSetupAttribute)); + ASSERT_EQ(SdpSetupAttribute::kActive, + mSdp->GetMediaSection(1).GetAttributeList().GetSetup().mRole); + ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kSetupAttribute)); +} + +TEST_P(NewSdpTest, CheckRtpmap) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) + << "Wrong number of media sections"; + + const SdpMediaSection& audiosec = mSdp->GetMediaSection(0); + const SdpRtpmapAttributeList& rtpmap = audiosec.GetAttributeList().GetRtpmap(); + ASSERT_EQ(5U, rtpmap.mRtpmaps.size()) + << "Wrong number of rtpmap attributes for audio"; + + // Need to know name of type + CheckRtpmap("109", + SdpRtpmapAttributeList::kOpus, + "opus", + 48000, + 2, + audiosec.GetFormats()[0], + rtpmap); + + CheckRtpmap("9", + SdpRtpmapAttributeList::kG722, + "G722", + 8000, + 1, + audiosec.GetFormats()[1], + rtpmap); + + CheckRtpmap("0", + SdpRtpmapAttributeList::kPCMU, + "PCMU", + 8000, + 1, + audiosec.GetFormats()[2], + rtpmap); + + CheckRtpmap("8", + SdpRtpmapAttributeList::kPCMA, + "PCMA", + 8000, + 1, + audiosec.GetFormats()[3], + rtpmap); + + CheckRtpmap("101", + SdpRtpmapAttributeList::kOtherCodec, + "telephone-event", + 8000, + 1, + audiosec.GetFormats()[4], + rtpmap); + + const SdpMediaSection& videosec = mSdp->GetMediaSection(1); + CheckRtpmap("120", + SdpRtpmapAttributeList::kVP8, + "VP8", + 90000, + 0, + videosec.GetFormats()[0], + videosec.GetAttributeList().GetRtpmap()); +} + +const std::string kH264AudioVideoOffer = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=ice-ufrag:4a799b2e" CRLF +"a=ice-pwd:e4cc12a910f106a0a744719425510e17" CRLF +"a=ice-lite" CRLF +"a=msid-semantic:WMS plus" CRLF +"a=fingerprint:sha-256 DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF +"a=group:BUNDLE first second" CRLF +"a=group:BUNDLE third" CRLF +"a=group:LS first third" CRLF +"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=mid:first" CRLF +"a=rtpmap:109 opus/48000/2" CRLF +"a=ptime:20" CRLF +"a=maxptime:20" CRLF +"a=rtpmap:9 G722/8000" CRLF +"a=rtpmap:0 PCMU/8000" CRLF +"a=rtpmap:8 PCMA/8000" CRLF +"a=rtpmap:101 telephone-event/8000" CRLF +"a=fmtp:101 0-15" CRLF +"a=ice-ufrag:00000000" CRLF +"a=ice-pwd:0000000000000000000000000000000" CRLF +"a=sendonly" CRLF +"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF +"a=setup:actpass" CRLF +"a=rtcp-mux" CRLF +"a=msid:track stream" CRLF +"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF +"a=candidate:2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453" CRLF +"a=candidate:3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761" CRLF +"a=candidate:6 1 UDP 16515071 162.222.183.171 51858 typ relay raddr 162.222.183.171 rport 51858" CRLF +"a=candidate:3 2 UDP 100401150 162.222.183.171 62454 typ relay raddr 162.222.183.171 rport 62454" CRLF +"a=candidate:2 2 UDP 1694236670 24.6.134.204 55428 typ srflx raddr 10.0.0.36 rport 55428" CRLF +"a=candidate:6 2 UDP 16515070 162.222.183.171 50340 typ relay raddr 162.222.183.171 rport 50340" CRLF +"a=candidate:0 2 UDP 2130379006 10.0.0.36 55428 typ host" CRLF +"m=video 9 RTP/SAVPF 97 98 120" CRLF +"c=IN IP6 ::1" CRLF +"a=mid:second" CRLF +"a=rtpmap:97 H264/90000" CRLF +"a=fmtp:97 profile-level-id=42a01e" CRLF +"a=rtpmap:98 H264/90000" CRLF +"a=fmtp:98 PROFILE=0;LEVEL=0;profile-level-id=42a00d;packetization-mode=1;level-asymmetry-allowed=1;max-mbps=42000;max-fs=1400;max-cpb=1000;max-dpb=1000;max-br=180000;parameter-add=1;usedtx=0;stereo=0;useinbandfec=0;cbr=0" CRLF +"a=rtpmap:120 VP8/90000" CRLF +"a=fmtp:120 max-fs=3601;max-fr=31" CRLF +"a=recvonly" CRLF +"a=setup:active" CRLF +"a=rtcp-mux" CRLF +"a=msid:tracka streama" CRLF +"a=msid:trackb streamb" CRLF +"a=candidate:0 1 UDP 2130379007 10.0.0.36 59530 typ host" CRLF +"a=candidate:0 2 UDP 2130379006 10.0.0.36 64378 typ host" CRLF +"a=candidate:2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378" CRLF +"a=candidate:6 2 UDP 16515070 162.222.183.171 64941 typ relay raddr 162.222.183.171 rport 64941" CRLF +"a=candidate:6 1 UDP 16515071 162.222.183.171 64800 typ relay raddr 162.222.183.171 rport 64800" CRLF +"a=candidate:2 1 UDP 1694236671 24.6.134.204 59530 typ srflx raddr 10.0.0.36 rport 59530" CRLF +"a=candidate:3 1 UDP 100401151 162.222.183.171 62935 typ relay raddr 162.222.183.171 rport 62935" CRLF +"a=candidate:3 2 UDP 100401150 162.222.183.171 61026 typ relay raddr 162.222.183.171 rport 61026" CRLF +"m=audio 9 RTP/SAVPF 0" CRLF +"a=mid:third" CRLF +"a=rtpmap:0 PCMU/8000" CRLF +"a=ice-lite" CRLF +"a=msid:noappdata" CRLF; + +TEST_P(NewSdpTest, CheckFormatParameters) { + ParseSdp(kH264AudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) + << "Wrong number of media sections"; + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kFmtpAttribute)); + auto audio_format_params = + mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps; + ASSERT_EQ(1U, audio_format_params.size()); + ASSERT_EQ("101", audio_format_params[0].format); + ASSERT_EQ("0-15", audio_format_params[0].parameters_string); + + ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kFmtpAttribute)); + auto video_format_params = + mSdp->GetMediaSection(1).GetAttributeList().GetFmtp().mFmtps; + ASSERT_EQ(3U, video_format_params.size()); + ASSERT_EQ("97", video_format_params[0].format); + ASSERT_TRUE(video_format_params[0].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kH264, + video_format_params[0].parameters->codec_type); + const SdpFmtpAttributeList::H264Parameters *h264_parameters( + static_cast( + video_format_params[0].parameters.get())); + ASSERT_EQ((uint32_t)0x42a01e, h264_parameters->profile_level_id); + ASSERT_EQ(0U, h264_parameters->packetization_mode); + ASSERT_EQ(false, h264_parameters->level_asymmetry_allowed); + ASSERT_EQ(0U, h264_parameters->max_mbps); + ASSERT_EQ(0U, h264_parameters->max_fs); + ASSERT_EQ(0U, h264_parameters->max_cpb); + ASSERT_EQ(0U, h264_parameters->max_dpb); + ASSERT_EQ(0U, h264_parameters->max_br); + + ASSERT_EQ("98", video_format_params[1].format); + ASSERT_TRUE(video_format_params[1].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kH264, + video_format_params[1].parameters->codec_type); + h264_parameters = + static_cast( + video_format_params[1].parameters.get()); + ASSERT_EQ((uint32_t)0x42a00d, h264_parameters->profile_level_id); + ASSERT_EQ(1U, h264_parameters->packetization_mode); + ASSERT_EQ(true, h264_parameters->level_asymmetry_allowed); + ASSERT_EQ(42000U, h264_parameters->max_mbps); + ASSERT_EQ(1400U, h264_parameters->max_fs); + ASSERT_EQ(1000U, h264_parameters->max_cpb); + ASSERT_EQ(1000U, h264_parameters->max_dpb); + ASSERT_EQ(180000U, h264_parameters->max_br); + + ASSERT_EQ("120", video_format_params[2].format); + ASSERT_TRUE(video_format_params[2].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kVP8, + video_format_params[2].parameters->codec_type); + const SdpFmtpAttributeList::VP8Parameters *vp8_parameters = + static_cast( + video_format_params[2].parameters.get()); + ASSERT_EQ(3601U, vp8_parameters->max_fs); + ASSERT_EQ(31U, vp8_parameters->max_fr); + + ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kFmtpAttribute)); +} + +TEST_P(NewSdpTest, CheckPtime) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_EQ(20U, mSdp->GetMediaSection(0).GetAttributeList().GetPtime()); + ASSERT_FALSE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kPtimeAttribute)); +} + +TEST_P(NewSdpTest, CheckFlags) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kIceLiteAttribute)); + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kIceLiteAttribute)); + ASSERT_FALSE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kIceLiteAttribute)); + ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kIceLiteAttribute)); + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kBundleOnlyAttribute)); + ASSERT_TRUE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kBundleOnlyAttribute)); + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kEndOfCandidatesAttribute)); + ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kEndOfCandidatesAttribute)); + ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kEndOfCandidatesAttribute)); +} + +TEST_P(NewSdpTest, CheckConnectionLines) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) + << "Wrong number of media sections"; + + const SdpConnection& conn1 = mSdp->GetMediaSection(0).GetConnection(); + ASSERT_EQ(sdp::kIPv4, conn1.GetAddrType()); + ASSERT_EQ("0.0.0.0", conn1.GetAddress()); + ASSERT_EQ(0U, conn1.GetTtl()); + ASSERT_EQ(0U, conn1.GetCount()); + + const SdpConnection& conn2 = mSdp->GetMediaSection(1).GetConnection(); + ASSERT_EQ(sdp::kIPv6, conn2.GetAddrType()); + ASSERT_EQ("::1", conn2.GetAddress()); + ASSERT_EQ(0U, conn2.GetTtl()); + ASSERT_EQ(0U, conn2.GetCount()); + + // tests that we can fall through to session level as appropriate + const SdpConnection& conn3 = mSdp->GetMediaSection(2).GetConnection(); + ASSERT_EQ(sdp::kIPv4, conn3.GetAddrType()); + ASSERT_EQ("224.0.0.1", conn3.GetAddress()); + ASSERT_EQ(100U, conn3.GetTtl()); + ASSERT_EQ(12U, conn3.GetCount()); +} + +TEST_P(NewSdpTest, CheckDirections) { + ParseSdp(kBasicAudioVideoOffer); + + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(SdpDirectionAttribute::kSendonly, + mSdp->GetMediaSection(0).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpDirectionAttribute::kRecvonly, + mSdp->GetMediaSection(1).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpDirectionAttribute::kSendrecv, + mSdp->GetMediaSection(2).GetAttributeList().GetDirection()); +} + +TEST_P(NewSdpTest, CheckCandidates) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kCandidateAttribute)); + auto audio_candidates = + mSdp->GetMediaSection(0).GetAttributeList().GetCandidate(); + ASSERT_EQ(8U, audio_candidates.size()); + ASSERT_EQ("0 1 UDP 2130379007 10.0.0.36 62453 typ host", audio_candidates[0]); + ASSERT_EQ("2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453", audio_candidates[1]); + ASSERT_EQ("3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761", audio_candidates[2]); + ASSERT_EQ("6 1 UDP 16515071 162.222.183.171 51858 typ relay raddr 162.222.183.171 rport 51858", audio_candidates[3]); + ASSERT_EQ("3 2 UDP 100401150 162.222.183.171 62454 typ relay raddr 162.222.183.171 rport 62454", audio_candidates[4]); + ASSERT_EQ("2 2 UDP 1694236670 24.6.134.204 55428 typ srflx raddr 10.0.0.36 rport 55428", audio_candidates[5]); + ASSERT_EQ("6 2 UDP 16515070 162.222.183.171 50340 typ relay raddr 162.222.183.171 rport 50340", audio_candidates[6]); + ASSERT_EQ("0 2 UDP 2130379006 10.0.0.36 55428 typ host", audio_candidates[7]); + + ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kCandidateAttribute)); + auto video_candidates = + mSdp->GetMediaSection(1).GetAttributeList().GetCandidate(); + ASSERT_EQ(8U, video_candidates.size()); + ASSERT_EQ("0 1 UDP 2130379007 10.0.0.36 59530 typ host", video_candidates[0]); + ASSERT_EQ("0 2 UDP 2130379006 10.0.0.36 64378 typ host", video_candidates[1]); + ASSERT_EQ("2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378", video_candidates[2]); + ASSERT_EQ("6 2 UDP 16515070 162.222.183.171 64941 typ relay raddr 162.222.183.171 rport 64941", video_candidates[3]); + ASSERT_EQ("6 1 UDP 16515071 162.222.183.171 64800 typ relay raddr 162.222.183.171 rport 64800", video_candidates[4]); + ASSERT_EQ("2 1 UDP 1694236671 24.6.134.204 59530 typ srflx raddr 10.0.0.36 rport 59530", video_candidates[5]); + ASSERT_EQ("3 1 UDP 100401151 162.222.183.171 62935 typ relay raddr 162.222.183.171 rport 62935", video_candidates[6]); + ASSERT_EQ("3 2 UDP 100401150 162.222.183.171 61026 typ relay raddr 162.222.183.171 rport 61026", video_candidates[7]); + + ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kCandidateAttribute)); +} + +TEST_P(NewSdpTest, CheckMid) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_EQ("first", mSdp->GetMediaSection(0).GetAttributeList().GetMid()); + ASSERT_EQ("second", mSdp->GetMediaSection(1).GetAttributeList().GetMid()); + ASSERT_EQ("third", mSdp->GetMediaSection(2).GetAttributeList().GetMid()); +} + +TEST_P(NewSdpTest, CheckMsid) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kMsidSemanticAttribute)); + // note that we lose the extra pieces here + // it's not worth it to save them until they mean something + ASSERT_EQ("WMS", mSdp->GetAttributeList().GetMsidSemantic()); + + const SdpMsidAttributeList& msids1 = + mSdp->GetMediaSection(0).GetAttributeList().GetMsid(); + ASSERT_EQ(1U, msids1.mMsids.size()); + ASSERT_EQ("track", msids1.mMsids[0].identifier); + ASSERT_EQ("stream", msids1.mMsids[0].appdata); + const SdpMsidAttributeList& msids2 = + mSdp->GetMediaSection(1).GetAttributeList().GetMsid(); + ASSERT_EQ(2U, msids2.mMsids.size()); + ASSERT_EQ("tracka", msids2.mMsids[0].identifier); + ASSERT_EQ("streama", msids2.mMsids[0].appdata); + ASSERT_EQ("trackb", msids2.mMsids[1].identifier); + ASSERT_EQ("streamb", msids2.mMsids[1].appdata); + const SdpMsidAttributeList& msids3 = + mSdp->GetMediaSection(2).GetAttributeList().GetMsid(); + ASSERT_EQ(1U, msids3.mMsids.size()); + ASSERT_EQ("noappdata", msids3.mMsids[0].identifier); + ASSERT_EQ("", msids3.mMsids[0].appdata); +} + +TEST_P(NewSdpTest, CheckMediaLevelIceUfrag) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kIceUfragAttribute, true)); + ASSERT_EQ("00000000", + mSdp->GetMediaSection(0).GetAttributeList().GetIceUfrag()); + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kIceUfragAttribute, false)); + + ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kIceUfragAttribute, true)); + ASSERT_EQ("4a799b2e", + mSdp->GetMediaSection(1).GetAttributeList().GetIceUfrag()); +} + +TEST_P(NewSdpTest, CheckMediaLevelIcePwd) { + ParseSdp(kBasicAudioVideoOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kIcePwdAttribute)); + ASSERT_EQ("0000000000000000000000000000000", + mSdp->GetMediaSection(0).GetAttributeList().GetIcePwd()); + + ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kIcePwdAttribute)); + ASSERT_EQ("e4cc12a910f106a0a744719425510e17", + mSdp->GetMediaSection(1).GetAttributeList().GetIcePwd()); +} + +TEST_P(NewSdpTest, CheckGroups) { + ParseSdp(kBasicAudioVideoOffer); + const SdpGroupAttributeList& group = mSdp->GetAttributeList().GetGroup(); + const SdpGroupAttributeList::Group& group1 = group.mGroups[0]; + ASSERT_EQ(SdpGroupAttributeList::kBundle, group1.semantics); + ASSERT_EQ(2U, group1.tags.size()); + ASSERT_EQ("first", group1.tags[0]); + ASSERT_EQ("second", group1.tags[1]); + + const SdpGroupAttributeList::Group& group2 = group.mGroups[1]; + ASSERT_EQ(SdpGroupAttributeList::kBundle, group2.semantics); + ASSERT_EQ(1U, group2.tags.size()); + ASSERT_EQ("third", group2.tags[0]); + + const SdpGroupAttributeList::Group& group3 = group.mGroups[2]; + ASSERT_EQ(SdpGroupAttributeList::kLs, group3.semantics); + ASSERT_EQ(2U, group3.tags.size()); + ASSERT_EQ("first", group3.tags[0]); + ASSERT_EQ("third", group3.tags[1]); +} + +// SDP from a basic A/V call with data channel FFX/FFX +const std::string kBasicAudioVideoDataOffer = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 27987 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"t=0 0" CRLF +"a=ice-ufrag:8a39d2ae" CRLF +"a=ice-pwd:601d53aba51a318351b3ecf5ee00048f" CRLF +"a=fingerprint:sha-256 30:FF:8E:2B:AC:9D:ED:70:18:10:67:C8:AE:9E:68:F3:86:53:51:B0:AC:31:B7:BE:6D:CF:A4:2E:D3:6E:B4:28" CRLF +"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:109 opus/48000/2" CRLF +"a=ptime:20" CRLF +"a=rtpmap:9 G722/8000" CRLF +"a=rtpmap:0 PCMU/8000" CRLF +"a=rtpmap:8 PCMA/8000" CRLF +"a=rtpmap:101 telephone-event/8000" CRLF +"a=fmtp:101 0-15" CRLF +"a=sendrecv" CRLF +"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF +"a=extmap:2/sendonly some_extension" CRLF +"a=extmap:3 some_other_extension some_params some more params" CRLF +"a=setup:actpass" CRLF +"a=rtcp-mux" CRLF +"m=video 9 RTP/SAVPF 120 126 97" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF +"a=rtpmap:126 H264/90000" CRLF +"a=fmtp:126 profile-level-id=42e01f;packetization-mode=1" CRLF +"a=rtpmap:97 H264/90000" CRLF +"a=fmtp:97 profile-level-id=42e01f" CRLF +"a=sendrecv" CRLF +// sipcc barfs on this, despite that it is valid syntax +// Do we care about fixing? +//"a=rtcp-fb:120 ack" CRLF // Should be ignored by sipcc +"a=rtcp-fb:120 ack rpsi" CRLF +"a=rtcp-fb:120 ack app foo" CRLF +"a=rtcp-fb:120 ack foo" CRLF // Should be ignored +"a=rtcp-fb:120 nack" CRLF +"a=rtcp-fb:120 nack sli" CRLF +"a=rtcp-fb:120 nack pli" CRLF +"a=rtcp-fb:120 nack rpsi" CRLF +"a=rtcp-fb:120 nack app foo" CRLF +"a=rtcp-fb:120 nack foo" CRLF // Should be ignored +"a=rtcp-fb:120 ccm fir" CRLF +"a=rtcp-fb:120 ccm tmmbr" CRLF +"a=rtcp-fb:120 ccm tstr" CRLF +"a=rtcp-fb:120 ccm vbcm" CRLF +"a=rtcp-fb:120 ccm foo" CRLF // Should be ignored +"a=rtcp-fb:120 trr-int 10" CRLF +"a=rtcp-fb:120 foo" CRLF // Should be ignored +"a=rtcp-fb:126 nack" CRLF +"a=rtcp-fb:126 nack pli" CRLF +"a=rtcp-fb:126 ccm fir" CRLF +"a=rtcp-fb:97 nack" CRLF +"a=rtcp-fb:97 nack pli" CRLF +"a=rtcp-fb:97 ccm fir" CRLF +"a=setup:actpass" CRLF +"a=rtcp-mux" CRLF +"m=application 9 DTLS/SCTP 5000" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=sctpmap:5000 webrtc-datachannel 16" CRLF +"a=setup:actpass" CRLF; + +TEST_P(NewSdpTest, BasicAudioVideoDataSdpParse) { + ParseSdp(kBasicAudioVideoDataOffer); + ASSERT_EQ(0U, mParser.GetParseErrors().size()) << + "Got parse errors: " << GetParseErrors(); +} + +TEST_P(NewSdpTest, CheckApplicationParameters) { + ParseSdp(kBasicAudioVideoDataOffer); + ASSERT_TRUE(mSdp); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + ASSERT_EQ(SdpMediaSection::kAudio, mSdp->GetMediaSection(0).GetMediaType()) + << "Wrong type for first media section"; + ASSERT_EQ(SdpMediaSection::kVideo, mSdp->GetMediaSection(1).GetMediaType()) + << "Wrong type for second media section"; + ASSERT_EQ(SdpMediaSection::kApplication, mSdp->GetMediaSection(2).GetMediaType()) + << "Wrong type for third media section"; + + ASSERT_EQ(SdpMediaSection::kDtlsSctp, + mSdp->GetMediaSection(2).GetProtocol()) + << "Wrong protocol for application"; + auto app_formats = mSdp->GetMediaSection(2).GetFormats(); + ASSERT_EQ(1U, app_formats.size()) << "Wrong number of formats for audio"; + ASSERT_EQ("5000", app_formats[0]); + + const SdpConnection& conn3 = mSdp->GetMediaSection(2).GetConnection(); + ASSERT_EQ(sdp::kIPv4, conn3.GetAddrType()); + ASSERT_EQ("0.0.0.0", conn3.GetAddress()); + ASSERT_EQ(0U, conn3.GetTtl()); + ASSERT_EQ(0U, conn3.GetCount()); + + ASSERT_TRUE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kSetupAttribute)); + ASSERT_EQ(SdpSetupAttribute::kActpass, + mSdp->GetMediaSection(2).GetAttributeList().GetSetup().mRole); +} + +TEST_P(NewSdpTest, CheckExtmap) { + ParseSdp(kBasicAudioVideoDataOffer); + ASSERT_TRUE(mSdp); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kExtmapAttribute)); + + auto extmaps = + mSdp->GetMediaSection(0).GetAttributeList().GetExtmap().mExtmaps; + ASSERT_EQ(3U, extmaps.size()); + + ASSERT_EQ(1U, extmaps[0].entry); + ASSERT_FALSE(extmaps[0].direction_specified); + ASSERT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level", + extmaps[0].extensionname); + ASSERT_EQ("", + extmaps[0].extensionattributes); + + ASSERT_EQ(2U, extmaps[1].entry); + ASSERT_TRUE(extmaps[1].direction_specified); + ASSERT_EQ(SdpDirectionAttribute::kSendonly, extmaps[1].direction); + ASSERT_EQ("some_extension", + extmaps[1].extensionname); + ASSERT_EQ("", + extmaps[1].extensionattributes); + + ASSERT_EQ(3U, extmaps[2].entry); + ASSERT_FALSE(extmaps[2].direction_specified); + ASSERT_EQ("some_other_extension", + extmaps[2].extensionname); + ASSERT_EQ("some_params some more params", + extmaps[2].extensionattributes); +} + +TEST_P(NewSdpTest, CheckRtcpFb) { + ParseSdp(kBasicAudioVideoDataOffer); + ASSERT_TRUE(mSdp); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections"; + + auto& video_attrs = mSdp->GetMediaSection(1).GetAttributeList(); + ASSERT_TRUE(video_attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)); + auto& rtcpfbs = video_attrs.GetRtcpFb().mFeedbacks; + ASSERT_EQ(18U, rtcpfbs.size()); + CheckRtcpFb(rtcpfbs[0], "120", SdpRtcpFbAttributeList::kAck, "rpsi"); + CheckRtcpFb(rtcpfbs[1], "120", SdpRtcpFbAttributeList::kAck, "app", "foo"); + CheckRtcpFb(rtcpfbs[2], "120", SdpRtcpFbAttributeList::kNack, ""); + CheckRtcpFb(rtcpfbs[3], "120", SdpRtcpFbAttributeList::kNack, "sli"); + CheckRtcpFb(rtcpfbs[4], "120", SdpRtcpFbAttributeList::kNack, "pli"); + CheckRtcpFb(rtcpfbs[5], "120", SdpRtcpFbAttributeList::kNack, "rpsi"); + CheckRtcpFb(rtcpfbs[6], "120", SdpRtcpFbAttributeList::kNack, "app", "foo"); + CheckRtcpFb(rtcpfbs[7], "120", SdpRtcpFbAttributeList::kCcm, "fir"); + CheckRtcpFb(rtcpfbs[8], "120", SdpRtcpFbAttributeList::kCcm, "tmmbr"); + CheckRtcpFb(rtcpfbs[9], "120", SdpRtcpFbAttributeList::kCcm, "tstr"); + CheckRtcpFb(rtcpfbs[10], "120", SdpRtcpFbAttributeList::kCcm, "vbcm"); + CheckRtcpFb(rtcpfbs[11], "120", SdpRtcpFbAttributeList::kTrrInt, "10"); + CheckRtcpFb(rtcpfbs[12], "126", SdpRtcpFbAttributeList::kNack, ""); + CheckRtcpFb(rtcpfbs[13], "126", SdpRtcpFbAttributeList::kNack, "pli"); + CheckRtcpFb(rtcpfbs[14], "126", SdpRtcpFbAttributeList::kCcm, "fir"); + CheckRtcpFb(rtcpfbs[15], "97", SdpRtcpFbAttributeList::kNack, ""); + CheckRtcpFb(rtcpfbs[16], "97", SdpRtcpFbAttributeList::kNack, "pli"); + CheckRtcpFb(rtcpfbs[17], "97", SdpRtcpFbAttributeList::kCcm, "fir"); +} + +TEST_P(NewSdpTest, CheckSctpmap) { + ParseSdp(kBasicAudioVideoDataOffer); + ASSERT_TRUE(mSdp) << "Parse failed: " << GetParseErrors(); + ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) + << "Wrong number of media sections"; + + const SdpMediaSection& appsec = mSdp->GetMediaSection(2); + ASSERT_TRUE( + appsec.GetAttributeList().HasAttribute(SdpAttribute::kSctpmapAttribute)); + const SdpSctpmapAttributeList& sctpmap = + appsec.GetAttributeList().GetSctpmap(); + + ASSERT_EQ(1U, sctpmap.mSctpmaps.size()) + << "Wrong number of sctpmap attributes"; + ASSERT_EQ(1U, appsec.GetFormats().size()); + + // Need to know name of type + CheckSctpmap("5000", + "webrtc-datachannel", + 16, + appsec.GetFormats()[0], + sctpmap); +} + +const std::string kNewSctpmapOfferDraft07 = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 27987 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"t=0 0" CRLF +"a=ice-ufrag:8a39d2ae" CRLF +"a=ice-pwd:601d53aba51a318351b3ecf5ee00048f" CRLF +"a=fingerprint:sha-256 30:FF:8E:2B:AC:9D:ED:70:18:10:67:C8:AE:9E:68:F3:86:53:51:B0:AC:31:B7:BE:6D:CF:A4:2E:D3:6E:B4:28" CRLF +"m=application 9 DTLS/SCTP webrtc-datachannel" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=fmtp:webrtc-datachannel max-message-size=100000" CRLF +"a=sctp-port 5000" CRLF +"a=setup:actpass" CRLF; + +TEST_P(NewSdpTest, NewSctpmapSdpParse) { + ParseSdp(kNewSctpmapOfferDraft07, false); +} + +INSTANTIATE_TEST_CASE_P(RoundTripSerialize, + NewSdpTest, + ::testing::Values(false, true)); + +const std::string kCandidateInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF +"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:109 opus/48000/2" CRLF; + +// This may or may not parse, but if it does, the errant candidate attribute +// should be ignored. +TEST_P(NewSdpTest, CheckCandidateInSessionLevel) { + ParseSdp(kCandidateInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kCandidateAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kCandidateAttribute)); + } +} + +const std::string kBundleOnlyInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=bundle-only" CRLF +"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:109 opus/48000/2" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckBundleOnlyInSessionLevel) { + ParseSdp(kBundleOnlyInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kBundleOnlyAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kBundleOnlyAttribute)); + } +} + +const std::string kFmtpInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=fmtp:109 0-15" CRLF +"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:109 opus/48000/2" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckFmtpInSessionLevel) { + ParseSdp(kFmtpInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kFmtpAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kFmtpAttribute)); + } +} + +const std::string kIceMismatchInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=ice-mismatch" CRLF +"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:109 opus/48000/2" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckIceMismatchInSessionLevel) { + ParseSdp(kIceMismatchInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kIceMismatchAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kIceMismatchAttribute)); + } +} + +const std::string kImageattrInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=imageattr:120 send * recv *" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckImageattrInSessionLevel) { + ParseSdp(kImageattrInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kImageattrAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kImageattrAttribute)); + } +} + +const std::string kLabelInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=label:foobar" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckLabelInSessionLevel) { + ParseSdp(kLabelInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kLabelAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kLabelAttribute)); + } +} + +const std::string kMaxptimeInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=maxptime:100" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckMaxptimeInSessionLevel) { + ParseSdp(kMaxptimeInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kMaxptimeAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kMaxptimeAttribute)); + } +} + +const std::string kMidInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=mid:foobar" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckMidInSessionLevel) { + ParseSdp(kMidInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kMidAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kMidAttribute)); + } +} + +const std::string kMsidInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=msid:foobar" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckMsidInSessionLevel) { + ParseSdp(kMsidInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kMsidAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kMsidAttribute)); + } +} + +const std::string kPtimeInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=ptime:50" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckPtimeInSessionLevel) { + ParseSdp(kPtimeInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kPtimeAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kPtimeAttribute)); + } +} + +const std::string kRemoteCandidatesInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=remote-candidates:0 10.0.0.1 5555" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckRemoteCandidatesInSessionLevel) { + ParseSdp(kRemoteCandidatesInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRemoteCandidatesAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kRemoteCandidatesAttribute)); + } +} + +const std::string kRtcpInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=rtcp:5555" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckRtcpInSessionLevel) { + ParseSdp(kRtcpInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kRtcpAttribute)); + } +} + +const std::string kRtcpFbInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=rtcp-fb:120 nack" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckRtcpFbInSessionLevel) { + ParseSdp(kRtcpFbInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpFbAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kRtcpFbAttribute)); + } +} + +const std::string kRtcpMuxInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=rtcp-mux" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckRtcpMuxInSessionLevel) { + ParseSdp(kRtcpMuxInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + } +} + +const std::string kRtcpRsizeInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=rtcp-rsize" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckRtcpRsizeInSessionLevel) { + ParseSdp(kRtcpRsizeInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpRsizeAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kRtcpRsizeAttribute)); + } +} + +const std::string kRtpmapInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=rtpmap:120 VP8/90000" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckRtpmapInSessionLevel) { + ParseSdp(kRtpmapInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtpmapAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kRtpmapAttribute)); + } +} + +const std::string kSctpmapInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=sctpmap:5000" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckSctpmapInSessionLevel) { + ParseSdp(kSctpmapInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kSctpmapAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kSctpmapAttribute)); + } +} + +const std::string kSsrcInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=ssrc:5000" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckSsrcInSessionLevel) { + ParseSdp(kSsrcInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kSsrcAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kSsrcAttribute)); + } +} + +const std::string kSsrcGroupInSessionSDP = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"a=ssrc-group:FID 5000" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +// This may or may not parse, but if it does, the errant attribute +// should be ignored. +TEST_P(NewSdpTest, CheckSsrcGroupInSessionLevel) { + ParseSdp(kSsrcGroupInSessionSDP, false); + if (mSdp) { + ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kSsrcGroupAttribute)); + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kSsrcGroupAttribute)); + } +} + +const std::string kNoAttributes = +"v=0" CRLF +"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF +"s=SIP Call" CRLF +"c=IN IP4 224.0.0.1/100/12" CRLF +"t=0 0" CRLF +"m=video 9 RTP/SAVPF 120" CRLF +"c=IN IP4 0.0.0.0" CRLF +"a=rtpmap:120 VP8/90000" CRLF; + +TEST_P(NewSdpTest, CheckNoAttributes) { + ParseSdp(kNoAttributes); + + for (auto a = static_cast(SdpAttribute::kFirstAttribute); + a <= static_cast(SdpAttribute::kLastAttribute); + ++a) { + + SdpAttribute::AttributeType type = + static_cast(a); + + // rtpmap is a special case right now, we throw parse errors if it is + // missing, and then insert one. + // direction is another special case that gets a default if not present + if (type != SdpAttribute::kRtpmapAttribute && + type != SdpAttribute::kDirectionAttribute) { + ASSERT_FALSE( + mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(type)) + << "Attribute " << a << " should not have been present at media level"; + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(type)) + << "Attribute " << a << " should not have been present at session level"; + } + } + + ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kRtpmapAttribute)); + + ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kDirectionAttribute)); + ASSERT_EQ(SdpDirectionAttribute::kSendrecv, + mSdp->GetMediaSection(0).GetAttributeList().GetDirection()); + ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute( + SdpAttribute::kDirectionAttribute)); + ASSERT_EQ(SdpDirectionAttribute::kSendrecv, + mSdp->GetAttributeList().GetDirection()); +} + +TEST(NewSdpTestNoFixture, CheckAttributeTypeSerialize) { + for (auto a = static_cast(SdpAttribute::kFirstAttribute); + a <= static_cast(SdpAttribute::kLastAttribute); + ++a) { + + SdpAttribute::AttributeType type = + static_cast(a); + + // Direction attributes are handled a little differently + if (type != SdpAttribute::kDirectionAttribute) { + std::ostringstream os; + os << type; + ASSERT_NE("", os.str()); + } + } +} + } // End namespace test. int main(int argc, char **argv) { From 0b6f6af66916b484a2a4f84944dca303b0814dc7 Mon Sep 17 00:00:00 2001 From: "Byron Campen [:bwc]" Date: Wed, 19 Nov 2014 16:12:08 -0800 Subject: [PATCH 16/82] Bug 1091242 - Part 2: New JSEP handling code. See https://github.com/unicorn-wg/gecko-dev/tree/multistream_rebase for more history. r=ehugg, r=jesup --- .../signaling/src/jsep/JsepCodecDescription.h | 620 ++++++ media/webrtc/signaling/src/jsep/JsepSession.h | 164 ++ .../signaling/src/jsep/JsepSessionImpl.cpp | 1655 +++++++++++++++++ .../signaling/src/jsep/JsepSessionImpl.h | 302 +++ media/webrtc/signaling/src/jsep/JsepTrack.h | 120 ++ .../webrtc/signaling/src/jsep/JsepTrackImpl.h | 79 + .../webrtc/signaling/src/jsep/JsepTransport.h | 117 ++ .../signaling/test/jsep_session_unittest.cpp | 1130 +++++++++++ 8 files changed, 4187 insertions(+) create mode 100644 media/webrtc/signaling/src/jsep/JsepCodecDescription.h create mode 100644 media/webrtc/signaling/src/jsep/JsepSession.h create mode 100644 media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp create mode 100644 media/webrtc/signaling/src/jsep/JsepSessionImpl.h create mode 100644 media/webrtc/signaling/src/jsep/JsepTrack.h create mode 100644 media/webrtc/signaling/src/jsep/JsepTrackImpl.h create mode 100644 media/webrtc/signaling/src/jsep/JsepTransport.h create mode 100644 media/webrtc/signaling/test/jsep_session_unittest.cpp diff --git a/media/webrtc/signaling/src/jsep/JsepCodecDescription.h b/media/webrtc/signaling/src/jsep/JsepCodecDescription.h new file mode 100644 index 00000000000..5d1835454a8 --- /dev/null +++ b/media/webrtc/signaling/src/jsep/JsepCodecDescription.h @@ -0,0 +1,620 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JSEPCODECDESCRIPTION_H_ +#define _JSEPCODECDESCRIPTION_H_ + +#include +#include +#include "signaling/src/sdp/SdpMediaSection.h" + +namespace mozilla { + +#define JSEP_CODEC_CLONE(T) \ + virtual JsepCodecDescription* Clone() const MOZ_OVERRIDE \ + { \ + return new T(*this); \ + } + +// A single entry in our list of known codecs. +struct JsepCodecDescription { + JsepCodecDescription(mozilla::SdpMediaSection::MediaType type, + const std::string& defaultPt, + const std::string& name, + uint32_t clock, + uint32_t channels, + bool enabled) + : mType(type), + mDefaultPt(defaultPt), + mName(name), + mClock(clock), + mChannels(channels), + mEnabled(enabled) + { + } + virtual ~JsepCodecDescription() {} + + virtual JsepCodecDescription* Clone() const = 0; + virtual void AddFmtps(SdpFmtpAttributeList& fmtp) const = 0; + virtual void AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const = 0; + virtual bool LoadFmtps(const SdpFmtpAttributeList::Parameters& params) = 0; + virtual bool LoadRtcpFbs( + const SdpRtcpFbAttributeList::Feedback& feedback) = 0; + + static bool + GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam) + { + char* end; + unsigned long pt = strtoul(ptString.c_str(), &end, 10); + size_t length = static_cast(end - ptString.c_str()); + if ((pt > UINT16_MAX) || (length != ptString.size())) { + return false; + } + *ptOutparam = pt; + return true; + } + + bool + GetPtAsInt(uint16_t* ptOutparam) const + { + return GetPtAsInt(mDefaultPt, ptOutparam); + } + + virtual bool + Matches(const std::string& fmt, const SdpMediaSection& remoteMsection) const + { + auto& attrs = remoteMsection.GetAttributeList(); + if (!attrs.HasAttribute(SdpAttribute::kRtpmapAttribute)) { + return false; + } + + const SdpRtpmapAttributeList& rtpmap = attrs.GetRtpmap(); + if (!rtpmap.HasEntry(fmt)) { + return false; + } + + const SdpRtpmapAttributeList::Rtpmap& entry = rtpmap.GetEntry(fmt); + + if (mType == remoteMsection.GetMediaType() + && (mName == entry.name) + && (mClock == entry.clock) + && (mChannels == entry.channels)) { + return ParametersMatch(FindParameters(entry.pt, remoteMsection)); + } + return false; + } + + virtual bool + ParametersMatch(const SdpFmtpAttributeList::Parameters* fmtp) const + { + return true; + } + + static const SdpFmtpAttributeList::Parameters* + FindParameters(const std::string& pt, + const mozilla::SdpMediaSection& remoteMsection) + { + const SdpAttributeList& attrs = remoteMsection.GetAttributeList(); + + if (attrs.HasAttribute(SdpAttribute::kFmtpAttribute)) { + const SdpFmtpAttributeList& fmtps = attrs.GetFmtp(); + for (auto i = fmtps.mFmtps.begin(); i != fmtps.mFmtps.end(); ++i) { + if (i->format == pt && i->parameters) { + return i->parameters.get(); + } + } + } + return nullptr; + } + + virtual JsepCodecDescription* + MakeNegotiatedCodec(const mozilla::SdpMediaSection& remoteMsection, + const std::string& pt, + bool sending) const + { + UniquePtr negotiated(Clone()); + negotiated->mDefaultPt = pt; + + const SdpAttributeList& attrs = remoteMsection.GetAttributeList(); + + if (sending) { + auto* parameters = FindParameters(negotiated->mDefaultPt, remoteMsection); + if (parameters) { + if (!negotiated->LoadFmtps(*parameters)) { + // Remote parameters were invalid + return nullptr; + } + } + } else { + // If a receive track, we need to pay attention to remote end's rtcp-fb + if (attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) { + auto& rtcpfbs = attrs.GetRtcpFb().mFeedbacks; + for (auto i = rtcpfbs.begin(); i != rtcpfbs.end(); ++i) { + if (i->pt == negotiated->mDefaultPt) { + if (!negotiated->LoadRtcpFbs(*i)) { + // Remote parameters were invalid + return nullptr; + } + } + } + } + } + + return negotiated.release(); + } + + virtual void + AddToMediaSection(SdpMediaSection& msection) const + { + if (mEnabled && msection.GetMediaType() == mType) { + if (mType == SdpMediaSection::kApplication) { + // Hack: using mChannels for number of streams + msection.AddDataChannel(mDefaultPt, mName, mChannels); + } else { + msection.AddCodec(mDefaultPt, mName, mClock, mChannels); + } + AddFmtpsToMSection(msection); + AddRtcpFbsToMSection(msection); + } + } + + virtual void + AddFmtpsToMSection(SdpMediaSection& msection) const + { + SdpAttributeList& attrs = msection.GetAttributeList(); + + UniquePtr fmtps; + + if (attrs.HasAttribute(SdpAttribute::kFmtpAttribute)) { + fmtps.reset(new SdpFmtpAttributeList(attrs.GetFmtp())); + } else { + fmtps.reset(new SdpFmtpAttributeList); + } + + AddFmtps(*fmtps); + + if (!fmtps->mFmtps.empty()) { + attrs.SetAttribute(fmtps.release()); + } + } + + virtual void + AddRtcpFbsToMSection(SdpMediaSection& msection) const + { + SdpAttributeList& attrs = msection.GetAttributeList(); + + UniquePtr rtcpfbs; + + if (attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) { + rtcpfbs.reset(new SdpRtcpFbAttributeList(attrs.GetRtcpFb())); + } else { + rtcpfbs.reset(new SdpRtcpFbAttributeList); + } + + AddRtcpFbs(*rtcpfbs); + + if (!rtcpfbs->mFeedbacks.empty()) { + attrs.SetAttribute(rtcpfbs.release()); + } + } + + mozilla::SdpMediaSection::MediaType mType; + std::string mDefaultPt; + std::string mName; + uint32_t mClock; + uint32_t mChannels; + bool mEnabled; +}; + +struct JsepAudioCodecDescription : public JsepCodecDescription { + JsepAudioCodecDescription(const std::string& defaultPt, + const std::string& name, + uint32_t clock, + uint32_t channels, + uint32_t packetSize, + uint32_t bitRate, + bool enabled = true) + : JsepCodecDescription(mozilla::SdpMediaSection::kAudio, defaultPt, name, + clock, channels, enabled), + mPacketSize(packetSize), + mBitrate(bitRate) + { + } + + virtual void + AddFmtps(SdpFmtpAttributeList& fmtp) const MOZ_OVERRIDE + { + // TODO + } + + virtual void + AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const MOZ_OVERRIDE + { + // TODO: Do we want to add anything? + } + + virtual bool + LoadFmtps(const SdpFmtpAttributeList::Parameters& params) MOZ_OVERRIDE + { + // TODO + return true; + } + + virtual bool + LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) MOZ_OVERRIDE + { + // Nothing to do + return true; + } + + JSEP_CODEC_CLONE(JsepAudioCodecDescription) + + uint32_t mPacketSize; + uint32_t mBitrate; +}; + +struct JsepVideoCodecDescription : public JsepCodecDescription { + JsepVideoCodecDescription(const std::string& defaultPt, + const std::string& name, + uint32_t clock, + bool enabled = true) + : JsepCodecDescription(mozilla::SdpMediaSection::kVideo, defaultPt, name, + clock, 0, enabled), + mMaxFs(0), + mMaxFr(0), + mPacketizationMode(0), + mMaxMbps(0), + mMaxCpb(0), + mMaxDpb(0), + mMaxBr(0) + { + } + + virtual void + AddFmtps(SdpFmtpAttributeList& fmtp) const MOZ_OVERRIDE + { + if (mName == "H264") { + UniquePtr params = + MakeUnique(); + + params->packetization_mode = mPacketizationMode; + // Hard-coded, may need to change someday? + params->level_asymmetry_allowed = true; + params->profile_level_id = mProfileLevelId; + params->max_mbps = mMaxMbps; + params->max_fs = mMaxFs; + params->max_cpb = mMaxCpb; + params->max_dpb = mMaxDpb; + params->max_br = mMaxBr; + strncpy(params->sprop_parameter_sets, + mSpropParameterSets.c_str(), + sizeof(params->sprop_parameter_sets) - 1); + fmtp.PushEntry(mDefaultPt, "", mozilla::Move(params)); + } else if (mName == "VP8") { + UniquePtr params = + MakeUnique(); + + params->max_fs = mMaxFs; + params->max_fr = mMaxFr; + fmtp.PushEntry(mDefaultPt, "", mozilla::Move(params)); + } + } + + virtual void + AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const MOZ_OVERRIDE + { + // Just hard code for now + rtcpfb.PushEntry(mDefaultPt, SdpRtcpFbAttributeList::kNack); + rtcpfb.PushEntry( + mDefaultPt, SdpRtcpFbAttributeList::kNack, SdpRtcpFbAttributeList::pli); + rtcpfb.PushEntry( + mDefaultPt, SdpRtcpFbAttributeList::kCcm, SdpRtcpFbAttributeList::fir); + } + + virtual bool + LoadFmtps(const SdpFmtpAttributeList::Parameters& params) MOZ_OVERRIDE + { + switch (params.codec_type) { + case SdpRtpmapAttributeList::kH264: + LoadH264Parameters(params); + break; + case SdpRtpmapAttributeList::kVP8: + LoadVP8Parameters(params); + break; + case SdpRtpmapAttributeList::kVP9: + case SdpRtpmapAttributeList::kiLBC: + case SdpRtpmapAttributeList::kiSAC: + case SdpRtpmapAttributeList::kOpus: + case SdpRtpmapAttributeList::kG722: + case SdpRtpmapAttributeList::kPCMU: + case SdpRtpmapAttributeList::kPCMA: + case SdpRtpmapAttributeList::kOtherCodec: + MOZ_ASSERT(false, "Invalid codec type for video"); + } + return true; + } + + virtual bool + LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) MOZ_OVERRIDE + { + switch (feedback.type) { + case SdpRtcpFbAttributeList::kAck: + mAckFbTypes.push_back(feedback.parameter); + break; + case SdpRtcpFbAttributeList::kCcm: + mCcmFbTypes.push_back(feedback.parameter); + break; + case SdpRtcpFbAttributeList::kNack: + mNackFbTypes.push_back(feedback.parameter); + break; + case SdpRtcpFbAttributeList::kApp: + case SdpRtcpFbAttributeList::kTrrInt: + // We don't support these, ignore. + {} + } + return true; + } + + enum Subprofile { + kH264ConstrainedBaseline, + kH264Baseline, + kH264Main, + kH264Extended, + kH264High, + kH264High10, + kH264High42, + kH264High44, + kH264High10I, + kH264High42I, + kH264High44I, + kH264CALVC44, + kH264UnknownSubprofile + }; + + static Subprofile + GetSubprofile(uint32_t profileLevelId) + { + // Based on Table 5 from RFC 6184: + // Profile profile_idc profile-iop + // (hexadecimal) (binary) + + // CB 42 (B) x1xx0000 + // same as: 4D (M) 1xxx0000 + // same as: 58 (E) 11xx0000 + // B 42 (B) x0xx0000 + // same as: 58 (E) 10xx0000 + // M 4D (M) 0x0x0000 + // E 58 00xx0000 + // H 64 00000000 + // H10 6E 00000000 + // H42 7A 00000000 + // H44 F4 00000000 + // H10I 6E 00010000 + // H42I 7A 00010000 + // H44I F4 00010000 + // C44I 2C 00010000 + + if ((profileLevelId & 0xFF4F00) == 0x424000) { + // 01001111 (mask, 0x4F) + // x1xx0000 (from table) + // 01000000 (expected value, 0x40) + return kH264ConstrainedBaseline; + } + + if ((profileLevelId & 0xFF8F00) == 0x4D8000) { + // 10001111 (mask, 0x8F) + // 1xxx0000 (from table) + // 10000000 (expected value, 0x80) + return kH264ConstrainedBaseline; + } + + if ((profileLevelId & 0xFFCF00) == 0x58C000) { + // 11001111 (mask, 0xCF) + // 11xx0000 (from table) + // 11000000 (expected value, 0xC0) + return kH264ConstrainedBaseline; + } + + if ((profileLevelId & 0xFF4F00) == 0x420000) { + // 01001111 (mask, 0x4F) + // x0xx0000 (from table) + // 00000000 (expected value) + return kH264Baseline; + } + + if ((profileLevelId & 0xFFCF00) == 0x588000) { + // 11001111 (mask, 0xCF) + // 10xx0000 (from table) + // 10000000 (expected value, 0x80) + return kH264Baseline; + } + + if ((profileLevelId & 0xFFAF00) == 0x4D0000) { + // 10101111 (mask, 0xAF) + // 0x0x0000 (from table) + // 00000000 (expected value) + return kH264Main; + } + + if ((profileLevelId & 0xFF0000) == 0x580000) { + // 11001111 (mask, 0xCF) + // 00xx0000 (from table) + // 00000000 (expected value) + return kH264Extended; + } + + if ((profileLevelId & 0xFFFF00) == 0x640000) { + return kH264High; + } + + if ((profileLevelId & 0xFFFF00) == 0x6E0000) { + return kH264High10; + } + + if ((profileLevelId & 0xFFFF00) == 0x7A0000) { + return kH264High42; + } + + if ((profileLevelId & 0xFFFF00) == 0xF40000) { + return kH264High44; + } + + if ((profileLevelId & 0xFFFF00) == 0x6E1000) { + return kH264High10I; + } + + if ((profileLevelId & 0xFFFF00) == 0x7A1000) { + return kH264High42I; + } + + if ((profileLevelId & 0xFFFF00) == 0xF41000) { + return kH264High44I; + } + + if ((profileLevelId & 0xFFFF00) == 0x2C1000) { + return kH264CALVC44; + } + + return kH264UnknownSubprofile; + } + + virtual bool + ParametersMatch(const SdpFmtpAttributeList::Parameters* fmtp) const + MOZ_OVERRIDE + { + if (mName == "H264") { + if (!fmtp) { + // No fmtp means that we cannot assume level asymmetry is allowed, + // and since we have no way of knowing the profile-level-id, we can't + // say that we match. + return false; + } + + auto* h264Params = + static_cast(fmtp); + + if (!h264Params->level_asymmetry_allowed) { + if (GetSubprofile(h264Params->profile_level_id) != + GetSubprofile(mProfileLevelId)) { + return false; + } + } + + if (h264Params->packetization_mode != mPacketizationMode) { + return false; + } + } + return true; + } + + void + LoadH264Parameters(const SdpFmtpAttributeList::Parameters& params) + { + const SdpFmtpAttributeList::H264Parameters& h264Params = + static_cast(params); + + mMaxFs = h264Params.max_fs; + mProfileLevelId = h264Params.profile_level_id; + mPacketizationMode = h264Params.packetization_mode; + mMaxMbps = h264Params.max_mbps; + mMaxCpb = h264Params.max_cpb; + mMaxDpb = h264Params.max_dpb; + mMaxBr = h264Params.max_br; + mSpropParameterSets = h264Params.sprop_parameter_sets; + } + + void + LoadVP8Parameters(const SdpFmtpAttributeList::Parameters& params) + { + const SdpFmtpAttributeList::VP8Parameters& vp8Params = + static_cast(params); + + mMaxFs = vp8Params.max_fs; + mMaxFr = vp8Params.max_fr; + } + + JSEP_CODEC_CLONE(JsepVideoCodecDescription) + + std::vector mAckFbTypes; + std::vector mNackFbTypes; + std::vector mCcmFbTypes; + + uint32_t mMaxFs; + + // H264-specific stuff + uint32_t mProfileLevelId; + uint32_t mMaxFr; + uint32_t mPacketizationMode; + uint32_t mMaxMbps; + uint32_t mMaxCpb; + uint32_t mMaxDpb; + uint32_t mMaxBr; + std::string mSpropParameterSets; +}; + +struct JsepApplicationCodecDescription : public JsepCodecDescription { + JsepApplicationCodecDescription(const std::string& defaultPt, + const std::string& name, + uint16_t channels, + bool enabled = true) + : JsepCodecDescription(mozilla::SdpMediaSection::kApplication, defaultPt, + name, 0, channels, enabled) + { + } + + virtual void + AddFmtps(SdpFmtpAttributeList& fmtp) const MOZ_OVERRIDE + { + // TODO: Is there anything to do here? + } + + virtual void + AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const MOZ_OVERRIDE + { + // Nothing to do here. + } + + virtual bool + LoadFmtps(const SdpFmtpAttributeList::Parameters& params) MOZ_OVERRIDE + { + // TODO: Is there anything to do here? + return true; + } + + virtual bool + LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) MOZ_OVERRIDE + { + // Nothing to do + return true; + } + + JSEP_CODEC_CLONE(JsepApplicationCodecDescription) + + // Override, uses sctpmap instead of rtpmap + virtual bool + Matches(const std::string& fmt, + const SdpMediaSection& remoteMsection) const MOZ_OVERRIDE + { + auto& attrs = remoteMsection.GetAttributeList(); + if (!attrs.HasAttribute(SdpAttribute::kSctpmapAttribute)) { + return false; + } + + const SdpSctpmapAttributeList& sctpmap = attrs.GetSctpmap(); + if (!sctpmap.HasEntry(fmt)) { + return false; + } + + const SdpSctpmapAttributeList::Sctpmap& entry = sctpmap.GetEntry(fmt); + + if (mType == remoteMsection.GetMediaType() && (mName == entry.name)) { + return true; + } + return false; + } +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/jsep/JsepSession.h b/media/webrtc/signaling/src/jsep/JsepSession.h new file mode 100644 index 00000000000..73f051724f0 --- /dev/null +++ b/media/webrtc/signaling/src/jsep/JsepSession.h @@ -0,0 +1,164 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JSEPSESSION_H_ +#define _JSEPSESSION_H_ + +#include +#include +#include "mozilla/Maybe.h" +#include "mozilla/RefPtr.h" +#include "mozilla/UniquePtr.h" +#include "nsError.h" + +#include "signaling/src/jsep/JsepTransport.h" +#include "signaling/src/sdp/Sdp.h" + + +namespace mozilla { + +// Forward declarations +struct JsepCodecDescription; +class JsepTrack; +struct JsepTrackPair; + +enum JsepSignalingState { + kJsepStateStable, + kJsepStateHaveLocalOffer, + kJsepStateHaveRemoteOffer, + kJsepStateHaveLocalPranswer, + kJsepStateHaveRemotePranswer, + kJsepStateClosed +}; + +enum JsepSdpType { + kJsepSdpOffer, + kJsepSdpAnswer, + kJsepSdpPranswer, +}; + +struct JsepOAOptions {}; +struct JsepOfferOptions : public JsepOAOptions { + Maybe mOfferToReceiveAudio; + Maybe mOfferToReceiveVideo; + Maybe mDontOfferDataChannel; +}; +struct JsepAnswerOptions : public JsepOAOptions {}; + +class JsepSession +{ +public: + explicit JsepSession(const std::string& name) + : mName(name), mState(kJsepStateStable) + { + } + virtual ~JsepSession() {} + + virtual nsresult Init() = 0; + + // Accessors for basic properties. + virtual const std::string& + GetName() const + { + return mName; + } + virtual JsepSignalingState + GetState() const + { + return mState; + } + + // Set up the ICE And DTLS data. + virtual nsresult SetIceCredentials(const std::string& ufrag, + const std::string& pwd) = 0; + virtual bool RemoteIsIceLite() const = 0; + virtual std::vector GetIceOptions() const = 0; + + virtual nsresult AddDtlsFingerprint(const std::string& algorithm, + const std::vector& value) = 0; + + virtual nsresult AddAudioRtpExtension(const std::string& extensionName) = 0; + virtual nsresult AddVideoRtpExtension(const std::string& extensionName) = 0; + + // Kinda gross to be locking down the data structure type like this, but + // returning by value is problematic due to the lack of stl move semantics in + // our build config, since we can't use UniquePtr in the container. The + // alternative is writing a raft of accessor functions that allow arbitrary + // manipulation (which will be unwieldy), or allowing functors to be injected + // that manipulate the data structure (still pretty unwieldy). + virtual std::vector& Codecs() = 0; + + // Manage tracks. We take shared ownership of any track. + virtual nsresult AddTrack(const RefPtr& track) = 0; + virtual nsresult RemoveTrack(size_t track_index) = 0; + virtual nsresult ReplaceTrack(size_t track_index, + const RefPtr& track) = 0; + + virtual size_t GetLocalTrackCount() const = 0; + virtual nsresult GetLocalTrack(size_t index, + RefPtr* track) const = 0; + + virtual size_t GetRemoteTrackCount() const = 0; + virtual nsresult GetRemoteTrack(size_t index, + RefPtr* track) const = 0; + + // Access the negotiated track pairs. + virtual size_t GetNegotiatedTrackPairCount() const = 0; + virtual nsresult GetNegotiatedTrackPair(size_t index, + const JsepTrackPair** pair) const = 0; + + // Access transports. + virtual size_t GetTransportCount() const = 0; + virtual nsresult GetTransport(size_t index, + RefPtr* transport) const = 0; + + // Basic JSEP operations. + virtual nsresult CreateOffer(const JsepOfferOptions& options, + std::string* offer) = 0; + virtual nsresult CreateAnswer(const JsepAnswerOptions& options, + std::string* answer) = 0; + virtual std::string GetLocalDescription() const = 0; + virtual std::string GetRemoteDescription() const = 0; + virtual nsresult SetLocalDescription(JsepSdpType type, + const std::string& sdp) = 0; + virtual nsresult SetRemoteDescription(JsepSdpType type, + const std::string& sdp) = 0; + virtual nsresult AddRemoteIceCandidate(const std::string& candidate, + const std::string& mid, + uint16_t level) = 0; + virtual nsresult AddLocalIceCandidate(const std::string& candidate, + const std::string& mid, + uint16_t level) = 0; + virtual nsresult EndOfLocalCandidates(const std::string& defaultCandidateAddr, + uint16_t defaultCandidatePort, + uint16_t level) = 0; + virtual nsresult Close() = 0; + + // ICE controlling or controlled + virtual bool IsIceControlling() const = 0; + + virtual const std::string + GetLastError() const + { + return "Error"; + } + + static const char* + GetStateStr(JsepSignalingState state) + { + static const char* states[] = { "stable", "have-local-offer", + "have-remote-offer", "have-local-pranswer", + "have-remote-pranswer", "closed" }; + + return states[state]; + } + +protected: + const std::string mName; + JsepSignalingState mState; +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp new file mode 100644 index 00000000000..c218f9926e9 --- /dev/null +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp @@ -0,0 +1,1655 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "logging.h" + +#include "signaling/src/jsep/JsepSessionImpl.h" +#include +#include + +#include "nspr.h" +#include "nss.h" +#include "pk11pub.h" +#include "nsDebug.h" + +#include +#include + +#include "signaling/src/jsep/JsepTrack.h" +#include "signaling/src/jsep/JsepTrack.h" +#include "signaling/src/jsep/JsepTrackImpl.h" +#include "signaling/src/jsep/JsepTransport.h" +#include "signaling/src/sdp/Sdp.h" +#include "signaling/src/sdp/SipccSdp.h" +#include "signaling/src/sdp/SipccSdpParser.h" + +namespace mozilla { + +MOZ_MTLOG_MODULE("jsep") + +#define JSEP_SET_ERROR(error) \ + do { \ + std::ostringstream os; \ + os << error; \ + mLastError = os.str(); \ + MOZ_MTLOG(ML_ERROR, mLastError); \ + } while (0); + +JsepSessionImpl::~JsepSessionImpl() +{ + for (auto i = mCodecs.begin(); i != mCodecs.end(); ++i) { + delete *i; + } +} + +nsresult +JsepSessionImpl::Init() +{ + mLastError.clear(); + + MOZ_ASSERT(!mSessionId, "Init called more than once"); + + SECStatus rv = PK11_GenerateRandom( + reinterpret_cast(&mSessionId), sizeof(mSessionId)); + // RFC 3264 says that session-ids MUST be representable as a _signed_ + // 64 bit number, meaning the MSB cannot be set. + mSessionId = mSessionId >> 1; + if (rv != SECSuccess) { + JSEP_SET_ERROR("Failed to generate session id: " << rv); + return NS_ERROR_FAILURE; + } + + if (!mUuidGen->Generate(&mDefaultRemoteStreamId)) { + JSEP_SET_ERROR("Failed to generate default uuid for streams"); + return NS_ERROR_FAILURE; + } + + SetupDefaultCodecs(); + SetupDefaultRtpExtensions(); + + return NS_OK; +} + +nsresult +JsepSessionImpl::AddTrack(const RefPtr& track) +{ + mLastError.clear(); + MOZ_ASSERT(track->GetDirection() == JsepTrack::kJsepTrackSending); + + JsepSendingTrack strack; + strack.mTrack = track; + + mLocalTracks.push_back(strack); + + return NS_OK; +} + +nsresult +JsepSessionImpl::SetIceCredentials(const std::string& ufrag, + const std::string& pwd) +{ + mLastError.clear(); + mIceUfrag = ufrag; + mIcePwd = pwd; + + return NS_OK; +} + +nsresult +JsepSessionImpl::AddDtlsFingerprint(const std::string& algorithm, + const std::vector& value) +{ + mLastError.clear(); + JsepDtlsFingerprint fp; + + fp.mAlgorithm = algorithm; + fp.mValue = value; + + mDtlsFingerprints.push_back(fp); + + return NS_OK; +} + +nsresult +JsepSessionImpl::AddAudioRtpExtension(const std::string& extensionName) +{ + mLastError.clear(); + + if (mAudioRtpExtensions.size() + 1 > UINT16_MAX) { + JSEP_SET_ERROR("Too many audio rtp extensions have been added"); + return NS_ERROR_FAILURE; + } + + mAudioRtpExtensions.push_back( + { static_cast(mAudioRtpExtensions.size() + 1), + SdpDirectionAttribute::kSendrecv, + false, // don't actually specify direction + extensionName, "" }); + return NS_OK; +} + +nsresult +JsepSessionImpl::AddVideoRtpExtension(const std::string& extensionName) +{ + mLastError.clear(); + + if (mVideoRtpExtensions.size() + 1 > UINT16_MAX) { + JSEP_SET_ERROR("Too many video rtp extensions have been added"); + return NS_ERROR_FAILURE; + } + + mVideoRtpExtensions.push_back( + { static_cast(mVideoRtpExtensions.size() + 1), + SdpDirectionAttribute::kSendrecv, + false, // don't actually specify direction + extensionName, "" }); + return NS_OK; +} + +nsresult +JsepSessionImpl::GetLocalTrack(size_t index, RefPtr* track) const +{ + if (index >= mLocalTracks.size()) { + return NS_ERROR_INVALID_ARG; + } + + *track = mLocalTracks[index].mTrack; + + return NS_OK; +} + +nsresult +JsepSessionImpl::GetRemoteTrack(size_t index, RefPtr* track) const +{ + if (index >= mRemoteTracks.size()) { + return NS_ERROR_INVALID_ARG; + } + + *track = mRemoteTracks[index].mTrack; + + return NS_OK; +} + +nsresult +JsepSessionImpl::AddOfferMSectionsByType(SdpMediaSection::MediaType mediatype, + Maybe offerToReceive, + Sdp* sdp) +{ + + // TODO(bug 1094447): Use kUdpTlsRtpSavpf once it interops well + SdpMediaSection::Protocol proto = SdpMediaSection::kRtpSavpf; + + if (mediatype == SdpMediaSection::kApplication) { + proto = SdpMediaSection::kDtlsSctp; + } + + size_t added = 0; + + for (auto track = mLocalTracks.begin(); track != mLocalTracks.end(); + ++track) { + if (mediatype != track->mTrack->GetMediaType()) { + continue; + } + + SdpDirectionAttribute::Direction dir = SdpDirectionAttribute::kSendrecv; + + ++added; + + // spec says that if offerToReceive(Audio|Video) is set lower than the + // number of tracks, the remaining m-lines are sendonly + if (offerToReceive.isSome() && added > *offerToReceive) { + dir = SdpDirectionAttribute::kSendonly; + } + + nsresult rv = CreateOfferMSection(mediatype, dir, proto, sdp); + + NS_ENSURE_SUCCESS(rv, rv); + + track->mAssignedMLine = Some(sdp->GetMediaSectionCount() - 1); + } + + while (offerToReceive.isSome() && added < *offerToReceive) { + nsresult rv = CreateOfferMSection( + mediatype, SdpDirectionAttribute::kRecvonly, proto, sdp); + + NS_ENSURE_SUCCESS(rv, rv); + ++added; + } + + return NS_OK; +} + +nsresult +JsepSessionImpl::CreateOffer(const JsepOfferOptions& options, + std::string* offer) +{ + mLastError.clear(); + + switch (mState) { + case kJsepStateStable: + break; + default: + JSEP_SET_ERROR("Cannot create offer in state " << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + + UniquePtr sdp; + + // Make the basic SDP that is common to offer/answer. + nsresult rv = CreateGenericSDP(&sdp); + NS_ENSURE_SUCCESS(rv, rv); + + // TODO(bug 1017888): When doing renegotiation, we need to make sure we + // keep the old m-lines in the same order. + + // Now add all the m-lines that we are attempting to negotiate. + // First audio, then video, then datachannel, for interop + rv = AddOfferMSectionsByType( + SdpMediaSection::kAudio, options.mOfferToReceiveAudio, sdp.get()); + + NS_ENSURE_SUCCESS(rv, rv); + + rv = AddOfferMSectionsByType( + SdpMediaSection::kVideo, options.mOfferToReceiveVideo, sdp.get()); + + NS_ENSURE_SUCCESS(rv, rv); + + if (!(options.mDontOfferDataChannel.isSome() && + *options.mDontOfferDataChannel)) { + rv = AddOfferMSectionsByType( + SdpMediaSection::kApplication, Maybe(), sdp.get()); + + NS_ENSURE_SUCCESS(rv, rv); + } + + if (!sdp->GetMediaSectionCount()) { + JSEP_SET_ERROR("Cannot create an offer with no local tracks, " + "no offerToReceiveAudio/Video, and no DataChannel."); + return NS_ERROR_INVALID_ARG; + } + + *offer = sdp->ToString(); + mGeneratedLocalDescription = Move(sdp); + + return NS_OK; +} + +std::string +JsepSessionImpl::GetLocalDescription() const +{ + std::ostringstream os; + if (mPendingLocalDescription) { + mPendingLocalDescription->Serialize(os); + } else if (mCurrentLocalDescription) { + mCurrentLocalDescription->Serialize(os); + } + return os.str(); +} + +std::string +JsepSessionImpl::GetRemoteDescription() const +{ + std::ostringstream os; + if (mPendingRemoteDescription) { + mPendingRemoteDescription->Serialize(os); + } else if (mCurrentRemoteDescription) { + mCurrentRemoteDescription->Serialize(os); + } + return os.str(); +} + +void +JsepSessionImpl::AddCodecs(SdpMediaSection* msection) const +{ + for (auto c = mCodecs.begin(); c != mCodecs.end(); ++c) { + (*c)->AddToMediaSection(*msection); + } +} + +void +JsepSessionImpl::AddExtmap(SdpMediaSection* msection) const +{ + const auto* extensions = GetRtpExtensions(msection->GetMediaType()); + + if (extensions && !extensions->empty()) { + SdpExtmapAttributeList* extmap = new SdpExtmapAttributeList; + extmap->mExtmaps = *extensions; + msection->GetAttributeList().SetAttribute(extmap); + } +} + +JsepCodecDescription* +JsepSessionImpl::FindMatchingCodec(const std::string& fmt, + const SdpMediaSection& msection) const +{ + for (auto c = mCodecs.begin(); c != mCodecs.end(); ++c) { + auto codec = *c; + if (codec->mEnabled && codec->Matches(fmt, msection)) { + return codec; + } + } + + return nullptr; +} + +const std::vector* +JsepSessionImpl::GetRtpExtensions(SdpMediaSection::MediaType type) const +{ + switch (type) { + case SdpMediaSection::kAudio: + return &mAudioRtpExtensions; + case SdpMediaSection::kVideo: + return &mVideoRtpExtensions; + default: + return nullptr; + } +} + +void +JsepSessionImpl::AddCommonCodecs(const SdpMediaSection& remoteMsection, + SdpMediaSection* msection) +{ + const std::vector& formats = remoteMsection.GetFormats(); + + for (auto fmt = formats.begin(); fmt != formats.end(); ++fmt) { + JsepCodecDescription* codec = FindMatchingCodec(*fmt, remoteMsection); + if (codec) { + codec->mDefaultPt = *fmt; // Reflect the other side's PT + codec->AddToMediaSection(*msection); + // TODO(bug 1099351): Once bug 1073475 is fixed on all supported + // versions, we can remove this limitation. + break; + } + } +} + +void +JsepSessionImpl::AddCommonExtmaps(const SdpMediaSection& remoteMsection, + SdpMediaSection* msection) +{ + if (!remoteMsection.GetAttributeList().HasAttribute( + SdpAttribute::kExtmapAttribute)) { + return; + } + + auto* ourExtensions = GetRtpExtensions(remoteMsection.GetMediaType()); + + if (!ourExtensions) { + return; + } + + UniquePtr ourExtmap(new SdpExtmapAttributeList); + auto& theirExtmap = remoteMsection.GetAttributeList().GetExtmap().mExtmaps; + for (auto i = theirExtmap.begin(); i != theirExtmap.end(); ++i) { + for (auto j = ourExtensions->begin(); j != ourExtensions->end(); ++j) { + if (i->extensionname == j->extensionname) { + ourExtmap->mExtmaps.push_back(*i); + + // RFC 5285 says that ids >= 4096 can be used by the offerer to + // force the answerer to pick, otherwise the value in the offer is + // used. + if (ourExtmap->mExtmaps.back().entry >= 4096) { + ourExtmap->mExtmaps.back().entry = j->entry; + } + } + } + } + + if (!ourExtmap->mExtmaps.empty()) { + msection->GetAttributeList().SetAttribute(ourExtmap.release()); + } +} + +nsresult +JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options, + std::string* answer) +{ + mLastError.clear(); + + switch (mState) { + case kJsepStateHaveRemoteOffer: + break; + default: + JSEP_SET_ERROR("Cannot create answer in state " << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + + // This is the heart of the negotiation code. Depressing that it's + // so bad. + // + // Here's the current algorithm: + // 1. Walk through all the m-lines on the other side. + // 2. For each m-line, walk through all of our local tracks + // in sequence and see if any are unassigned. If so, assign + // them and mark it sendrecv, otherwise it's recvonly. + // 3. Just replicate their media attributes. + // 4. Profit. + UniquePtr sdp; + + // Make the basic SDP that is common to offer/answer. + nsresult rv = CreateGenericSDP(&sdp); + NS_ENSURE_SUCCESS(rv, rv); + + const Sdp& offer = *mPendingRemoteDescription; + + size_t numMsections = offer.GetMediaSectionCount(); + + for (size_t i = 0; i < numMsections; ++i) { + const SdpMediaSection& remoteMsection = offer.GetMediaSection(i); + SdpMediaSection& msection = + sdp->AddMediaSection(remoteMsection.GetMediaType(), + SdpDirectionAttribute::kSendrecv, + 9, + remoteMsection.GetProtocol(), + sdp::kIPv4, + "0.0.0.0"); + + rv = CreateAnswerMSection(options, i, remoteMsection, &msection, sdp.get()); + NS_ENSURE_SUCCESS(rv, rv); + } + + *answer = sdp->ToString(); + mGeneratedLocalDescription = Move(sdp); + + return NS_OK; +} + +static bool +HasRtcp(SdpMediaSection::Protocol proto) +{ + switch (proto) { + case SdpMediaSection::kRtpAvpf: + case SdpMediaSection::kDccpRtpAvpf: + case SdpMediaSection::kDccpRtpSavpf: + case SdpMediaSection::kRtpSavpf: + case SdpMediaSection::kUdpTlsRtpSavpf: + case SdpMediaSection::kTcpTlsRtpSavpf: + case SdpMediaSection::kDccpTlsRtpSavpf: + return true; + case SdpMediaSection::kRtpAvp: + case SdpMediaSection::kUdp: + case SdpMediaSection::kVat: + case SdpMediaSection::kRtp: + case SdpMediaSection::kUdptl: + case SdpMediaSection::kTcp: + case SdpMediaSection::kTcpRtpAvp: + case SdpMediaSection::kRtpSavp: + case SdpMediaSection::kTcpBfcp: + case SdpMediaSection::kTcpTlsBfcp: + case SdpMediaSection::kTcpTls: + case SdpMediaSection::kFluteUdp: + case SdpMediaSection::kTcpMsrp: + case SdpMediaSection::kTcpTlsMsrp: + case SdpMediaSection::kDccp: + case SdpMediaSection::kDccpRtpAvp: + case SdpMediaSection::kDccpRtpSavp: + case SdpMediaSection::kUdpTlsRtpSavp: + case SdpMediaSection::kTcpTlsRtpSavp: + case SdpMediaSection::kDccpTlsRtpSavp: + case SdpMediaSection::kUdpMbmsFecRtpAvp: + case SdpMediaSection::kUdpMbmsFecRtpSavp: + case SdpMediaSection::kUdpMbmsRepair: + case SdpMediaSection::kFecUdp: + case SdpMediaSection::kUdpFec: + case SdpMediaSection::kTcpMrcpv2: + case SdpMediaSection::kTcpTlsMrcpv2: + case SdpMediaSection::kPstn: + case SdpMediaSection::kUdpTlsUdptl: + case SdpMediaSection::kSctp: + case SdpMediaSection::kSctpDtls: + case SdpMediaSection::kDtlsSctp: + return false; + } + MOZ_CRASH("Unknown protocol, probably corruption."); +} + +nsresult +JsepSessionImpl::CreateOfferMSection(SdpMediaSection::MediaType mediatype, + SdpDirectionAttribute::Direction dir, + SdpMediaSection::Protocol proto, + Sdp* sdp) +{ + + nsresult rv; + + SdpMediaSection* msection = + &sdp->AddMediaSection(mediatype, dir, 9, proto, sdp::kIPv4, "0.0.0.0"); + + // We don't do this in AddTransportAttributes because that is also used for + // making answers, and we don't want to unconditionally set rtcp-mux there. + if (HasRtcp(proto)) { + // Set RTCP-MUX. + msection->GetAttributeList().SetAttribute( + new SdpFlagAttribute(SdpAttribute::kRtcpMuxAttribute)); + } + + rv = AddTransportAttributes(msection, SdpSetupAttribute::kActpass); + NS_ENSURE_SUCCESS(rv, rv); + + AddCodecs(msection); + + AddExtmap(msection); + + return NS_OK; +} + +nsresult +JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options, + size_t mlineIndex, + const SdpMediaSection& remoteMsection, + SdpMediaSection* msection, + Sdp* sdp) +{ + SdpSetupAttribute::Role role; + nsresult rv = DetermineAnswererSetupRole(remoteMsection, &role); + NS_ENSURE_SUCCESS(rv, rv); + + rv = AddTransportAttributes(msection, role); + NS_ENSURE_SUCCESS(rv, rv); + + SdpDirectionAttribute::Direction remoteDirection = + remoteMsection.GetDirectionAttribute().mValue; + SdpDirectionAttribute::Direction localDirection = + SdpDirectionAttribute::kInactive; + + // Only attempt to match up local tracks if the offerer has elected to + // receive traffic. + if (remoteDirection & SdpDirectionAttribute::kRecvFlag) { + bool found = false; + for (auto track = mLocalTracks.begin(); track != mLocalTracks.end(); + ++track) { + if (track->mAssignedMLine.isSome()) + continue; + + // TODO(bug 1095218): Pay attention to msid + if (track->mTrack->GetMediaType() != remoteMsection.GetMediaType()) + continue; + + localDirection = SdpDirectionAttribute::kSendonly; + track->mAssignedMLine = Some(mlineIndex); + found = true; + break; + } + + if (!found && + remoteMsection.GetMediaType() == SdpMediaSection::kApplication) { + // If we are offered datachannel, we need to play along even if no track + // for it has been added yet. + std::string streamId; + std::string trackId; + + if (!mUuidGen->Generate(&streamId) || !mUuidGen->Generate(&trackId)) { + JSEP_SET_ERROR("Failed to generate UUIDs for datachannel track"); + return NS_ERROR_FAILURE; + } + + AddTrack(RefPtr( + new JsepTrack(SdpMediaSection::kApplication, streamId, trackId))); + localDirection = SdpDirectionAttribute::kSendonly; + mLocalTracks.back().mAssignedMLine = Some(mlineIndex); + found = true; + } + } + + if (remoteDirection & SdpDirectionAttribute::kSendFlag) { + localDirection = static_cast( + localDirection | SdpDirectionAttribute::kRecvFlag); + } + + msection->GetAttributeList().SetAttribute( + new SdpDirectionAttribute(localDirection)); + + if (remoteMsection.GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)) { + // If we aren't using a protocol with RTCP, just smile and nod. + msection->GetAttributeList().SetAttribute( + new SdpFlagAttribute(SdpAttribute::kRtcpMuxAttribute)); + } + + // Now add the codecs. + AddCommonCodecs(remoteMsection, msection); + + // Add extmap attributes. + AddCommonExtmaps(remoteMsection, msection); + + if (msection->GetFormats().empty()) { + // Could not negotiate anything. Disable m-section. + + // Clear out attributes. + msection->GetAttributeList().Clear(); + + // We need to have something here to fit the grammar + // TODO(bcampen@mozilla.com): What's the accepted way of doing this? Just + // add the codecs we do support? Does it matter? + msection->AddCodec("111", "NULL", 0, 0); + + auto* direction = + new SdpDirectionAttribute(SdpDirectionAttribute::kInactive); + msection->GetAttributeList().SetAttribute(direction); + msection->SetPort(0); + } + + return NS_OK; +} + +nsresult +JsepSessionImpl::DetermineAnswererSetupRole( + const SdpMediaSection& remoteMsection, + SdpSetupAttribute::Role* rolep) +{ + // Determine the role. + // RFC 5763 says: + // + // The endpoint MUST use the setup attribute defined in [RFC4145]. + // The endpoint that is the offerer MUST use the setup attribute + // value of setup:actpass and be prepared to receive a client_hello + // before it receives the answer. The answerer MUST use either a + // setup attribute value of setup:active or setup:passive. Note that + // if the answerer uses setup:passive, then the DTLS handshake will + // not begin until the answerer is received, which adds additional + // latency. setup:active allows the answer and the DTLS handshake to + // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever + // party is active MUST initiate a DTLS handshake by sending a + // ClientHello over each flow (host/port quartet). + // + // We default to assuming that the offerer is passive and we are active. + SdpSetupAttribute::Role role = SdpSetupAttribute::kActive; + + if (remoteMsection.GetAttributeList().HasAttribute( + SdpAttribute::kSetupAttribute)) { + switch (remoteMsection.GetAttributeList().GetSetup().mRole) { + case SdpSetupAttribute::kActive: + role = SdpSetupAttribute::kPassive; + break; + case SdpSetupAttribute::kPassive: + case SdpSetupAttribute::kActpass: + role = SdpSetupAttribute::kActive; + break; + case SdpSetupAttribute::kHoldconn: + // This should have been caught by ParseSdp + MOZ_ASSERT(false); + JSEP_SET_ERROR("The other side used an illegal setup attribute" + " (\"holdconn\")."); + return NS_ERROR_INVALID_ARG; + } + } + + *rolep = role; + return NS_OK; +} + +static void +appendSdpParseErrors( + const std::vector >& aErrors, + std::string* aErrorString) +{ + std::ostringstream os; + for (auto i = aErrors.begin(); i != aErrors.end(); ++i) { + os << "SDP Parse Error on line " << i->first << ": " + i->second + << std::endl; + } + *aErrorString += os.str(); +} + +nsresult +JsepSessionImpl::SetLocalDescription(JsepSdpType type, const std::string& sdp) +{ + mLastError.clear(); + + switch (mState) { + case kJsepStateStable: + if (type != kJsepSdpOffer) { + JSEP_SET_ERROR("Cannot set local answer in state " + << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + mIsOfferer = true; + break; + case kJsepStateHaveRemoteOffer: + if (type != kJsepSdpAnswer && type != kJsepSdpPranswer) { + JSEP_SET_ERROR("Cannot set local offer in state " + << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + break; + default: + JSEP_SET_ERROR("Cannot set local offer or answer in state " + << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + + UniquePtr parsed; + nsresult rv = ParseSdp(sdp, &parsed); + NS_ENSURE_SUCCESS(rv, rv); + + // Check that content hasn't done anything unsupported with the SDP + rv = ValidateLocalDescription(*parsed); + NS_ENSURE_SUCCESS(rv, rv); + + // Create transport objects. + size_t numMsections = parsed->GetMediaSectionCount(); + for (size_t t = 0; t < numMsections; ++t) { + if (t < mTransports.size()) + continue; // This transport already exists (assume we are renegotiating). + + // TODO(bug 1016476): Deal with bundle-only and the like. + RefPtr transport; + nsresult rv = CreateTransport(parsed->GetMediaSection(t), &transport); + NS_ENSURE_SUCCESS(rv, rv); + + mTransports.push_back(transport); + } + + switch (type) { + case kJsepSdpOffer: + rv = SetLocalDescriptionOffer(Move(parsed)); + break; + case kJsepSdpAnswer: + case kJsepSdpPranswer: + rv = SetLocalDescriptionAnswer(type, Move(parsed)); + break; + } + + return rv; +} + +nsresult +JsepSessionImpl::SetLocalDescriptionOffer(UniquePtr offer) +{ + MOZ_ASSERT(mState == kJsepStateStable); + mPendingLocalDescription = Move(offer); + SetState(kJsepStateHaveLocalOffer); + return NS_OK; +} + +nsresult +JsepSessionImpl::SetLocalDescriptionAnswer(JsepSdpType type, + UniquePtr answer) +{ + MOZ_ASSERT(mState == kJsepStateHaveRemoteOffer); + mPendingLocalDescription = Move(answer); + + nsresult rv = HandleNegotiatedSession(mPendingLocalDescription, + mPendingRemoteDescription); + NS_ENSURE_SUCCESS(rv, rv); + + mCurrentRemoteDescription = Move(mPendingRemoteDescription); + mCurrentLocalDescription = Move(mPendingLocalDescription); + + SetState(kJsepStateStable); + return NS_OK; +} + +nsresult +JsepSessionImpl::SetRemoteDescription(JsepSdpType type, const std::string& sdp) +{ + mLastError.clear(); + + MOZ_MTLOG(ML_DEBUG, "SetRemoteDescription type=" << type << "\nSDP=\n" + << sdp); + switch (mState) { + case kJsepStateStable: + if (type != kJsepSdpOffer) { + JSEP_SET_ERROR("Cannot set remote answer in state " + << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + mIsOfferer = false; + break; + case kJsepStateHaveLocalOffer: + case kJsepStateHaveRemotePranswer: + if (type != kJsepSdpAnswer && type != kJsepSdpPranswer) { + JSEP_SET_ERROR("Cannot set remote offer in state " + << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + break; + default: + JSEP_SET_ERROR("Cannot set remote offer or answer in current state " + << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + + // Parse. + UniquePtr parsed; + nsresult rv = ParseSdp(sdp, &parsed); + NS_ENSURE_SUCCESS(rv, rv); + + bool iceLite = + parsed->GetAttributeList().HasAttribute(SdpAttribute::kIceLiteAttribute); + + std::vector iceOptions; + if (parsed->GetAttributeList().HasAttribute( + SdpAttribute::kIceOptionsAttribute)) { + iceOptions = parsed->GetAttributeList().GetIceOptions().mValues; + } + + switch (type) { + case kJsepSdpOffer: + rv = SetRemoteDescriptionOffer(Move(parsed)); + break; + case kJsepSdpAnswer: + case kJsepSdpPranswer: + rv = SetRemoteDescriptionAnswer(type, Move(parsed)); + break; + } + + if (NS_SUCCEEDED(rv)) { + mRemoteIsIceLite = iceLite; + mIceOptions = iceOptions; + } + + return rv; +} + +// Helper function to find the track for a given m= section. +template +nsresult +FindTrackForMSection(const SdpMediaSection& msection, + const std::vector& tracks, + size_t mLine, + RefPtr* mst) +{ + for (auto t = tracks.begin(); t != tracks.end(); ++t) { + if (t->mAssignedMLine.isSome() && + (*t->mAssignedMLine == msection.GetLevel())) { + *mst = t->mTrack; + return NS_OK; + } + } + + return NS_ERROR_NOT_AVAILABLE; +} + +nsresult +JsepSessionImpl::HandleNegotiatedSession(const UniquePtr& local, + const UniquePtr& remote) +{ + bool remoteIceLite = + remote->GetAttributeList().HasAttribute(SdpAttribute::kIceLiteAttribute); + + mIceControlling = remoteIceLite || mIsOfferer; + + if (local->GetMediaSectionCount() != remote->GetMediaSectionCount()) { + JSEP_SET_ERROR("Local and remote SDP have different number of m-lines " + << "(" << local->GetMediaSectionCount() << " vs " + << remote->GetMediaSectionCount() << ")"); + return NS_ERROR_INVALID_ARG; + } + + std::vector trackPairs; + + // Now walk through the m-sections, make sure they match, and create + // track pairs that describe the media to be set up. + for (size_t i = 0; i < local->GetMediaSectionCount(); ++i) { + const SdpMediaSection& lm = local->GetMediaSection(i); + const SdpMediaSection& rm = remote->GetMediaSection(i); + const SdpMediaSection& offer = mIsOfferer ? lm : rm; + const SdpMediaSection& answer = mIsOfferer ? rm : lm; + + if (lm.GetMediaType() != rm.GetMediaType()) { + JSEP_SET_ERROR("Answer and offer have different media types at m-line " + << i); + return NS_ERROR_INVALID_ARG; + } + + RefPtr transport; + + // Transports are created in SetLocal. + // TODO(bug 1016476): This will need to be changed for bundle. + MOZ_ASSERT(mTransports.size() > i); + if (mTransports.size() < i) { + JSEP_SET_ERROR("Fewer transports set up than m-lines"); + return NS_ERROR_FAILURE; + } + transport = mTransports[i]; + + // If the answer says it's inactive we're not doing anything with it. + // TODO(bug 1017888): Need to handle renegotiation somehow. + // Note: the SDP engine guarantees the presence of an SDP direction + // attribute (with sendrecv as the default if one isn't in the SDP). + if (answer.GetDirectionAttribute().mValue == + SdpDirectionAttribute::kInactive && + answer.GetPort() == 0) { + transport->mState = JsepTransport::kJsepTransportClosed; + continue; + } + + bool sending; + bool receiving; + + nsresult rv = DetermineSendingDirection( + offer.GetDirectionAttribute().mValue, + answer.GetDirectionAttribute().mValue, &sending, &receiving); + NS_ENSURE_SUCCESS(rv, rv); + + MOZ_MTLOG(ML_DEBUG, "Negotiated m= line" + << " index=" << i << " type=" << lm.GetMediaType() + << " sending=" << sending + << " receiving=" << receiving); + + JsepTrackPair jpair; + + // TODO(bug 1016476): Set the bundle level. + jpair.mLevel = i; + + RefPtr track; + if (sending) { + rv = FindTrackForMSection(lm, mLocalTracks, i, &track); + if (NS_FAILED(rv)) { + JSEP_SET_ERROR("Failed to find local track for level " << i + << " in local SDP. This should never happen."); + NS_ASSERTION(false, "Failed to find local track for level"); + return NS_ERROR_FAILURE; + } + + rv = NegotiateTrack(rm, lm, JsepTrack::kJsepTrackSending, &track); + NS_ENSURE_SUCCESS(rv, rv); + + jpair.mSending = track; + } + + if (receiving) { + rv = FindTrackForMSection(lm, mRemoteTracks, i, &track); + if (NS_FAILED(rv)) { + JSEP_SET_ERROR("Failed to find remote track for level " << i + << " in remote SDP. This should never happen."); + NS_ASSERTION(false, "Failed to find remote track for level"); + return NS_ERROR_FAILURE; + } + + rv = NegotiateTrack(rm, lm, JsepTrack::kJsepTrackReceiving, &track); + NS_ENSURE_SUCCESS(rv, rv); + + jpair.mReceiving = track; + } + + rv = SetupTransport( + rm.GetAttributeList(), answer.GetAttributeList(), transport); + NS_ENSURE_SUCCESS(rv, rv); + jpair.mRtpTransport = transport; + + if (HasRtcp(lm.GetProtocol())) { + // RTCP MUX or not. + // TODO(bug 1095743): verify that the PTs are consistent with mux. + if (offer.GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute) && + answer.GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)) { + jpair.mRtcpTransport = nullptr; // We agree on mux. + MOZ_MTLOG(ML_DEBUG, "RTCP-MUX is on"); + } else { + MOZ_MTLOG(ML_DEBUG, "RTCP-MUX is off"); + rv = SetupTransport( + rm.GetAttributeList(), answer.GetAttributeList(), transport); + NS_ENSURE_SUCCESS(rv, rv); + + jpair.mRtcpTransport = transport; + } + } + + trackPairs.push_back(jpair); + } + + // Ouch, this probably needs some dirty bit instead of just clearing + // stuff for renegotiation. + mNegotiatedTrackPairs = trackPairs; + return NS_OK; +} + +nsresult +JsepSessionImpl::NegotiateTrack(const SdpMediaSection& remoteMsection, + const SdpMediaSection& localMsection, + JsepTrack::Direction direction, + RefPtr* track) +{ + UniquePtr negotiatedDetails = + MakeUnique(); + negotiatedDetails->mProtocol = remoteMsection.GetProtocol(); + + // Insert all the codecs we jointly support. + const std::vector& formats = remoteMsection.GetFormats(); + + for (auto fmt = formats.begin(); fmt != formats.end(); ++fmt) { + JsepCodecDescription* codec = FindMatchingCodec(*fmt, remoteMsection); + + if (!codec) { + continue; + } + + bool sending = (direction == JsepTrack::kJsepTrackSending); + + // We need to take the remote side's parameters into account so we can + // configure our send media. + // |codec| is assumed to have the necessary state about our own config + // in order to negotiate. + JsepCodecDescription* negotiated = + codec->MakeNegotiatedCodec(remoteMsection, *fmt, sending); + + if (!negotiated) { + continue; + } + + negotiatedDetails->mCodecs.push_back(negotiated); + } + + if (negotiatedDetails->mCodecs.empty()) { + JSEP_SET_ERROR("Failed to negotiate codec details for all codecs"); + return NS_ERROR_INVALID_ARG; + } + + auto& answerMsection = mIsOfferer ? remoteMsection : localMsection; + + if (answerMsection.GetAttributeList().HasAttribute( + SdpAttribute::kExtmapAttribute)) { + auto& extmap = answerMsection.GetAttributeList().GetExtmap().mExtmaps; + for (auto i = extmap.begin(); i != extmap.end(); ++i) { + negotiatedDetails->mExtmap[i->extensionname] = *i; + } + } + + (*track)->SetNegotiatedDetails(Move(negotiatedDetails)); + return NS_OK; +} + +nsresult +JsepSessionImpl::CreateTransport(const SdpMediaSection& msection, + RefPtr* transport) +{ + size_t components; + + if (HasRtcp(msection.GetProtocol())) { + components = 2; + } else { + components = 1; + } + + *transport = new JsepTransport("transport-id", components); + + return NS_OK; +} + +nsresult +JsepSessionImpl::SetupTransport(const SdpAttributeList& remote, + const SdpAttributeList& answer, + const RefPtr& transport) +{ + UniquePtr ice = MakeUnique(); + + // We do sanity-checking for these in ParseSdp + ice->mUfrag = remote.GetIceUfrag(); + ice->mPwd = remote.GetIcePwd(); + if (remote.HasAttribute(SdpAttribute::kCandidateAttribute)) { + ice->mCandidates = remote.GetCandidate(); + } + + // RFC 5763 says: + // + // The endpoint MUST use the setup attribute defined in [RFC4145]. + // The endpoint that is the offerer MUST use the setup attribute + // value of setup:actpass and be prepared to receive a client_hello + // before it receives the answer. The answerer MUST use either a + // setup attribute value of setup:active or setup:passive. Note that + // if the answerer uses setup:passive, then the DTLS handshake will + // not begin until the answerer is received, which adds additional + // latency. setup:active allows the answer and the DTLS handshake to + // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever + // party is active MUST initiate a DTLS handshake by sending a + // ClientHello over each flow (host/port quartet). + UniquePtr dtls = MakeUnique(); + dtls->mFingerprints = remote.GetFingerprint(); + if (!answer.HasAttribute(mozilla::SdpAttribute::kSetupAttribute)) { + dtls->mRole = mIsOfferer ? JsepDtlsTransport::kJsepDtlsServer + : JsepDtlsTransport::kJsepDtlsClient; + } else { + if (mIsOfferer) { + dtls->mRole = (answer.GetSetup().mRole == SdpSetupAttribute::kActive) + ? JsepDtlsTransport::kJsepDtlsServer + : JsepDtlsTransport::kJsepDtlsClient; + } else { + dtls->mRole = (answer.GetSetup().mRole == SdpSetupAttribute::kActive) + ? JsepDtlsTransport::kJsepDtlsClient + : JsepDtlsTransport::kJsepDtlsServer; + } + } + + transport->mIce = Move(ice); + transport->mDtls = Move(dtls); + + // TODO(bug 1016476): If we are doing bundle, and this is not the bundle + // level, we should be marking this Closed, right? + + if (answer.HasAttribute(SdpAttribute::kRtcpMuxAttribute)) { + transport->mComponents = 1; + } + + transport->mState = JsepTransport::kJsepTransportAccepted; + + return NS_OK; +} + +nsresult +JsepSessionImpl::DetermineSendingDirection( + SdpDirectionAttribute::Direction offer, + SdpDirectionAttribute::Direction answer, bool* sending, bool* receiving) +{ + + if (!(offer & SdpDirectionAttribute::kSendFlag) && + answer & SdpDirectionAttribute::kRecvFlag) { + JSEP_SET_ERROR("Answer tried to set recv when offer did not set send"); + return NS_ERROR_INVALID_ARG; + } + + if (!(offer & SdpDirectionAttribute::kRecvFlag) && + answer & SdpDirectionAttribute::kSendFlag) { + JSEP_SET_ERROR("Answer tried to set send when offer did not set recv"); + return NS_ERROR_INVALID_ARG; + } + + if (mIsOfferer) { + *receiving = answer & SdpDirectionAttribute::kSendFlag; + *sending = answer & SdpDirectionAttribute::kRecvFlag; + } else { + *sending = answer & SdpDirectionAttribute::kSendFlag; + *receiving = answer & SdpDirectionAttribute::kRecvFlag; + } + + return NS_OK; +} + +nsresult +JsepSessionImpl::AddTransportAttributes(SdpMediaSection* msection, + SdpSetupAttribute::Role dtlsRole) +{ + if (mIceUfrag.empty() || mIcePwd.empty()) { + JSEP_SET_ERROR("Missing ICE ufrag or password"); + return NS_ERROR_FAILURE; + } + + SdpAttributeList& attrList = msection->GetAttributeList(); + attrList.SetAttribute( + new SdpStringAttribute(SdpAttribute::kIceUfragAttribute, mIceUfrag)); + attrList.SetAttribute( + new SdpStringAttribute(SdpAttribute::kIcePwdAttribute, mIcePwd)); + + msection->GetAttributeList().SetAttribute(new SdpSetupAttribute(dtlsRole)); + + return NS_OK; +} + +nsresult +JsepSessionImpl::ParseSdp(const std::string& sdp, UniquePtr* parsedp) +{ + UniquePtr parsed = mParser.Parse(sdp); + if (!parsed) { + std::string error = "Failed to parse SDP: "; + appendSdpParseErrors(mParser.GetParseErrors(), &error); + JSEP_SET_ERROR(error); + return NS_ERROR_INVALID_ARG; + } + + // Verify that the JSEP rules for all SDP are followed + if (!parsed->GetMediaSectionCount()) { + JSEP_SET_ERROR("Description has no media sections"); + return NS_ERROR_INVALID_ARG; + } + + for (size_t i = 0; i < parsed->GetMediaSectionCount(); ++i) { + if (parsed->GetMediaSection(i).GetPort() == 0) { + // Disabled, let this stuff slide. + continue; + } + + auto& mediaAttrs = parsed->GetMediaSection(i).GetAttributeList(); + + if (mediaAttrs.GetIceUfrag().empty()) { + JSEP_SET_ERROR("Invalid description, no ice-ufrag attribute"); + return NS_ERROR_INVALID_ARG; + } + + if (mediaAttrs.GetIcePwd().empty()) { + JSEP_SET_ERROR("Invalid description, no ice-pwd attribute"); + return NS_ERROR_INVALID_ARG; + } + + if (!mediaAttrs.HasAttribute(SdpAttribute::kFingerprintAttribute)) { + JSEP_SET_ERROR("Invalid description, no fingerprint attribute"); + return NS_ERROR_INVALID_ARG; + } + + if (mediaAttrs.HasAttribute(SdpAttribute::kSetupAttribute) && + mediaAttrs.GetSetup().mRole == SdpSetupAttribute::kHoldconn) { + JSEP_SET_ERROR("Description has illegal setup attribute " + "\"holdconn\" at level " + << i); + return NS_ERROR_INVALID_ARG; + } + + auto& formats = parsed->GetMediaSection(i).GetFormats(); + for (auto f = formats.begin(); f != formats.end(); ++f) { + uint16_t pt; + if (!JsepCodecDescription::GetPtAsInt(*f, &pt)) { + JSEP_SET_ERROR("Payload type \"" + << *f << "\" is not a 16-bit unsigned int at level " + << i); + return NS_ERROR_INVALID_ARG; + } + } + } + + *parsedp = Move(parsed); + return NS_OK; +} + +nsresult +JsepSessionImpl::SetRemoteDescriptionOffer(UniquePtr offer) +{ + MOZ_ASSERT(mState == kJsepStateStable); + + // TODO(bug 1095780): Note that we create remote tracks even when + // They contain only codecs we can't negotiate or other craziness. + nsresult rv = SetRemoteTracksFromDescription(*offer); + NS_ENSURE_SUCCESS(rv, rv); + + mPendingRemoteDescription = Move(offer); + + SetState(kJsepStateHaveRemoteOffer); + return NS_OK; +} + +nsresult +JsepSessionImpl::SetRemoteDescriptionAnswer(JsepSdpType type, + UniquePtr answer) +{ + MOZ_ASSERT(mState == kJsepStateHaveLocalOffer || + mState == kJsepStateHaveRemotePranswer); + mPendingRemoteDescription = Move(answer); + + // TODO(bug 1095780): Note that this creates remote tracks even if + // we offered sendonly and other side offered sendrecv or recvonly. + nsresult rv = SetRemoteTracksFromDescription(*mPendingRemoteDescription); + NS_ENSURE_SUCCESS(rv, rv); + + rv = HandleNegotiatedSession(mPendingLocalDescription, + mPendingRemoteDescription); + NS_ENSURE_SUCCESS(rv, rv); + + mCurrentRemoteDescription = Move(mPendingRemoteDescription); + mCurrentLocalDescription = Move(mPendingLocalDescription); + + SetState(kJsepStateStable); + return NS_OK; +} + +nsresult +JsepSessionImpl::SetRemoteTracksFromDescription(const Sdp& remoteDescription) +{ + size_t numMlines = remoteDescription.GetMediaSectionCount(); + + for (size_t i = 0; i < numMlines; ++i) { + const SdpMediaSection& msection = remoteDescription.GetMediaSection(i); + auto direction = msection.GetDirectionAttribute().mValue; + + // TODO(bug 1017888): Suppress new track creation on renegotiation + // of existing tracks. + if (direction & SdpDirectionAttribute::kSendFlag) { + nsresult rv = CreateReceivingTrack(i, msection); + NS_ENSURE_SUCCESS(rv, rv); + } + } + + return NS_OK; +} + +nsresult +JsepSessionImpl::ValidateLocalDescription(const Sdp& description) +{ + // TODO(bug 1095226): Better checking. + // (Also, at what point do we clear out the generated offer?) + + if (description.GetMediaSectionCount() != + mGeneratedLocalDescription->GetMediaSectionCount()) { + JSEP_SET_ERROR("Changing the number of m-sections is not allowed"); + return NS_ERROR_INVALID_ARG; + } + + for (size_t i = 0; i < description.GetMediaSectionCount(); ++i) { + auto& origMsection = mGeneratedLocalDescription->GetMediaSection(i); + auto& finalMsection = description.GetMediaSection(i); + if (origMsection.GetMediaType() != finalMsection.GetMediaType()) { + JSEP_SET_ERROR("Changing the media-type of m-sections is not allowed"); + return NS_ERROR_INVALID_ARG; + } + + if (finalMsection.GetAttributeList().HasAttribute( + SdpAttribute::kCandidateAttribute)) { + JSEP_SET_ERROR("Adding your own candidate attributes is not supported"); + return NS_ERROR_INVALID_ARG; + } + + if (finalMsection.GetAttributeList().HasAttribute( + SdpAttribute::kEndOfCandidatesAttribute)) { + JSEP_SET_ERROR("Why are you trying to set a=end-of-candidates?"); + return NS_ERROR_INVALID_ARG; + } + + // TODO(bug 1095218): Check msid + // TODO(bug 1095226): Check ice-ufrag and ice-pwd + // TODO(bug 1095226): Check fingerprints + // TODO(bug 1095226): Check payload types (at least ensure that payload + // types we don't actually support weren't added) + // TODO(bug 1095226): Check ice-options? + } + + if (description.GetAttributeList().HasAttribute( + SdpAttribute::kIceLiteAttribute)) { + JSEP_SET_ERROR("Running ICE in lite mode is unsupported"); + return NS_ERROR_INVALID_ARG; + } + + return NS_OK; +} + +nsresult +JsepSessionImpl::CreateReceivingTrack(size_t mline, + const SdpMediaSection& msection) +{ + std::string streamId; + std::string trackId; + + // Generate random track ids. + // TODO(bug 1095218): Pull track and stream IDs out of SDP if available. + if (!mUuidGen->Generate(&trackId)) { + JSEP_SET_ERROR("Failed to generate UUID for JsepTrack"); + return NS_ERROR_FAILURE; + } + + JsepTrack* remote = new JsepTrack(msection.GetMediaType(), + mDefaultRemoteStreamId, + trackId, + JsepTrack::kJsepTrackReceiving); + JsepReceivingTrack rtrack; + rtrack.mTrack = remote; + rtrack.mAssignedMLine = Some(mline); + mRemoteTracks.push_back(rtrack); + + return NS_OK; +} + +nsresult +JsepSessionImpl::CreateGenericSDP(UniquePtr* sdpp) +{ + // draft-ietf-rtcweb-jsep-08 Section 5.2.1: + // o The second SDP line MUST be an "o=" line, as specified in + // [RFC4566], Section 5.2. The value of the field SHOULD + // be "-". The value of the field SHOULD be a + // cryptographically random number. To ensure uniqueness, this + // number SHOULD be at least 64 bits long. The value of the field SHOULD be zero. The value of the + // tuple SHOULD be set to a non- + // meaningful address, such as IN IP4 0.0.0.0, to prevent leaking the + // local address in this field. As mentioned in [RFC4566], the + // entire o= line needs to be unique, but selecting a random number + // for is sufficient to accomplish this. + + auto origin = + SdpOrigin("-", mSessionId, mSessionVersion, sdp::kIPv4, "0.0.0.0"); + + UniquePtr sdp = MakeUnique(origin); + + if (mDtlsFingerprints.empty()) { + JSEP_SET_ERROR("Missing DTLS fingerprint"); + return NS_ERROR_FAILURE; + } + + UniquePtr fpl = + MakeUnique(); + for (auto fp = mDtlsFingerprints.begin(); fp != mDtlsFingerprints.end(); + ++fp) { + fpl->PushEntry(fp->mAlgorithm, fp->mValue); + } + sdp->GetAttributeList().SetAttribute(fpl.release()); + + auto* iceOpts = new SdpOptionsAttribute(SdpAttribute::kIceOptionsAttribute); + iceOpts->PushEntry("trickle"); + sdp->GetAttributeList().SetAttribute(iceOpts); + + *sdpp = Move(sdp); + return NS_OK; +} + +void +JsepSessionImpl::SetupDefaultCodecs() +{ + // Supported audio codecs. + mCodecs.push_back(new JsepAudioCodecDescription( + "109", + "opus", + 48000, + 2, + 960, + 16000)); + + mCodecs.push_back(new JsepAudioCodecDescription( + "9", + "G722", + 8000, + 1, + 320, + 64000)); + + // packet size and bitrate values below copied from sipcc. + // May need reevaluation from a media expert. + mCodecs.push_back( + new JsepAudioCodecDescription("0", + "PCMU", + 8000, + 1, + 8000 / 50, // frequency / 50 + 8 * 8000 * 1 // 8 * frequency * channels + )); + + mCodecs.push_back( + new JsepAudioCodecDescription("8", + "PCMA", + 8000, + 1, + 8000 / 50, // frequency / 50 + 8 * 8000 * 1 // 8 * frequency * channels + )); + + // Supported video codecs. + JsepVideoCodecDescription* vp8 = new JsepVideoCodecDescription( + "120", + "VP8", + 90000 + ); + // Defaults for mandatory params + vp8->mMaxFs = 12288; + vp8->mMaxFr = 60; + mCodecs.push_back(vp8); + + JsepVideoCodecDescription* h264_1 = new JsepVideoCodecDescription( + "126", + "H264", + 90000 + ); + h264_1->mPacketizationMode = 1; + // Defaults for mandatory params + h264_1->mProfileLevelId = 0x42E00D; + mCodecs.push_back(h264_1); + + JsepVideoCodecDescription* h264_0 = new JsepVideoCodecDescription( + "97", + "H264", + 90000 + ); + h264_0->mPacketizationMode = 0; + // Defaults for mandatory params + h264_0->mProfileLevelId = 0x42E00D; + mCodecs.push_back(h264_0); + + mCodecs.push_back(new JsepApplicationCodecDescription( + "5000", + "webrtc-datachannel", + 16 + )); +} + +void +JsepSessionImpl::SetupDefaultRtpExtensions() +{ + AddAudioRtpExtension("urn:ietf:params:rtp-hdrext:ssrc-audio-level"); +} + +void +JsepSessionImpl::SetState(JsepSignalingState state) +{ + if (state == mState) + return; + + MOZ_MTLOG(ML_NOTICE, "[" << mName << "]: " << + GetStateStr(mState) << " -> " << GetStateStr(state)); + mState = state; +} + +nsresult +JsepSessionImpl::AddCandidateToSdp(Sdp* sdp, + const std::string& candidateUntrimmed, + const std::string& mid, + uint16_t level) +{ + + if (level >= sdp->GetMediaSectionCount()) { + // Ignore + return NS_OK; + } + + // Trim off a=candidate: + size_t begin = candidateUntrimmed.find(':'); + if (begin == std::string::npos) { + JSEP_SET_ERROR("Invalid candidate, no ':' (" << candidateUntrimmed << ")"); + return NS_ERROR_INVALID_ARG; + } + ++begin; + + std::string candidate = candidateUntrimmed.substr(begin); + + // TODO(bug 1095793): mid + + SdpMediaSection& msection = sdp->GetMediaSection(level); + SdpAttributeList& attrList = msection.GetAttributeList(); + + UniquePtr candidates; + if (!attrList.HasAttribute(SdpAttribute::kCandidateAttribute)) { + // Create new + candidates.reset( + new SdpMultiStringAttribute(SdpAttribute::kCandidateAttribute)); + } else { + // Copy existing + candidates.reset(new SdpMultiStringAttribute( + *static_cast( + attrList.GetAttribute(SdpAttribute::kCandidateAttribute)))); + } + candidates->PushEntry(candidate); + attrList.SetAttribute(candidates.release()); + + return NS_OK; +} + +nsresult +JsepSessionImpl::AddRemoteIceCandidate(const std::string& candidate, + const std::string& mid, + uint16_t level) +{ + mLastError.clear(); + + mozilla::Sdp* sdp = 0; + + if (mPendingRemoteDescription) { + sdp = mPendingRemoteDescription.get(); + } else if (mCurrentRemoteDescription) { + sdp = mCurrentRemoteDescription.get(); + } else { + JSEP_SET_ERROR("Cannot add ICE candidate in state " << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + + return AddCandidateToSdp(sdp, candidate, mid, level); +} + +nsresult +JsepSessionImpl::AddLocalIceCandidate(const std::string& candidate, + const std::string& mid, + uint16_t level) +{ + mLastError.clear(); + + mozilla::Sdp* sdp = 0; + + if (mPendingLocalDescription) { + sdp = mPendingLocalDescription.get(); + } else if (mCurrentLocalDescription) { + sdp = mCurrentLocalDescription.get(); + } else { + JSEP_SET_ERROR("Cannot add ICE candidate in state " << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + + return AddCandidateToSdp(sdp, candidate, mid, level); +} + +nsresult +JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr, + uint16_t defaultCandidatePort, + uint16_t level) +{ + mLastError.clear(); + + mozilla::Sdp* sdp = 0; + + if (mPendingLocalDescription) { + sdp = mPendingLocalDescription.get(); + } else if (mCurrentLocalDescription) { + sdp = mCurrentLocalDescription.get(); + } else { + JSEP_SET_ERROR("Cannot add ICE candidate in state " << GetStateStr(mState)); + return NS_ERROR_UNEXPECTED; + } + + if (level < sdp->GetMediaSectionCount()) { + SdpMediaSection& msection = sdp->GetMediaSection(level); + msection.GetConnection().SetAddress(defaultCandidateAddr); + msection.SetPort(defaultCandidatePort); + + // TODO(bug 1095793): Will this have an mid someday? + + SdpAttributeList& attrs = msection.GetAttributeList(); + // We verify that content has not set this in VerifyLocalDescription + MOZ_ASSERT(!attrs.HasAttribute(SdpAttribute::kEndOfCandidatesAttribute)); + attrs.SetAttribute( + new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute)); + if (!mIsOfferer) { + attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute); + } + } + + return NS_OK; +} + +nsresult +JsepSessionImpl::Close() +{ + mLastError.clear(); + SetState(kJsepStateClosed); + return NS_OK; +} + +const std::string +JsepSessionImpl::GetLastError() const +{ + return mLastError; +} + +} // namespace mozilla diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h new file mode 100644 index 00000000000..5f0a2a74910 --- /dev/null +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h @@ -0,0 +1,302 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JSEPSESSIONIMPL_H_ +#define _JSEPSESSIONIMPL_H_ + +#include +#include + +#include "signaling/src/jsep/JsepCodecDescription.h" +#include "signaling/src/jsep/JsepTrack.h" +#include "signaling/src/jsep/JsepSession.h" +#include "signaling/src/jsep/JsepTrack.h" +#include "signaling/src/jsep/JsepTrackImpl.h" +#include "signaling/src/sdp/SipccSdpParser.h" + +namespace mozilla { + +class JsepUuidGenerator +{ +public: + virtual ~JsepUuidGenerator() {} + virtual bool Generate(std::string* id) = 0; +}; + +class JsepSessionImpl : public JsepSession +{ +public: + JsepSessionImpl(const std::string& name, UniquePtr uuidgen) + : JsepSession(name), + mIsOfferer(false), + mIceControlling(false), + mRemoteIsIceLite(false), + mSessionId(0), + mSessionVersion(0), + mUuidGen(Move(uuidgen)) + { + } + + virtual ~JsepSessionImpl(); + + // Implement JsepSession methods. + virtual nsresult Init() MOZ_OVERRIDE; + + virtual nsresult AddTrack(const RefPtr& track) MOZ_OVERRIDE; + + virtual nsresult + RemoveTrack(size_t trackIndex) MOZ_OVERRIDE + { + mLastError.clear(); + MOZ_CRASH(); // Stub + } + + virtual nsresult SetIceCredentials(const std::string& ufrag, + const std::string& pwd) MOZ_OVERRIDE; + + virtual bool + RemoteIsIceLite() const MOZ_OVERRIDE + { + return mRemoteIsIceLite; + } + + virtual std::vector + GetIceOptions() const MOZ_OVERRIDE + { + return mIceOptions; + } + + virtual nsresult AddDtlsFingerprint(const std::string& algorithm, + const std::vector& value) MOZ_OVERRIDE; + + virtual nsresult AddAudioRtpExtension( + const std::string& extensionName) MOZ_OVERRIDE; + + virtual nsresult AddVideoRtpExtension( + const std::string& extensionName) MOZ_OVERRIDE; + + virtual std::vector& + Codecs() MOZ_OVERRIDE + { + return mCodecs; + } + + virtual nsresult + ReplaceTrack(size_t trackIndex, const RefPtr& track) MOZ_OVERRIDE + { + mLastError.clear(); + MOZ_CRASH(); // Stub + } + + virtual size_t + GetLocalTrackCount() const MOZ_OVERRIDE + { + return mLocalTracks.size(); + } + + virtual nsresult GetLocalTrack(size_t index, + RefPtr* track) const MOZ_OVERRIDE; + + virtual size_t + GetRemoteTrackCount() const MOZ_OVERRIDE + { + return mRemoteTracks.size(); + } + + virtual nsresult GetRemoteTrack(size_t index, + RefPtr* track) const MOZ_OVERRIDE; + + virtual nsresult CreateOffer(const JsepOfferOptions& options, + std::string* offer) MOZ_OVERRIDE; + + virtual nsresult CreateAnswer(const JsepAnswerOptions& options, + std::string* answer) MOZ_OVERRIDE; + + virtual std::string GetLocalDescription() const MOZ_OVERRIDE; + + virtual std::string GetRemoteDescription() const MOZ_OVERRIDE; + + virtual nsresult SetLocalDescription(JsepSdpType type, + const std::string& sdp) MOZ_OVERRIDE; + + virtual nsresult SetRemoteDescription(JsepSdpType type, + const std::string& sdp) MOZ_OVERRIDE; + + virtual nsresult AddRemoteIceCandidate(const std::string& candidate, + const std::string& mid, + uint16_t level) MOZ_OVERRIDE; + + virtual nsresult AddLocalIceCandidate(const std::string& candidate, + const std::string& mid, + uint16_t level) MOZ_OVERRIDE; + + virtual nsresult EndOfLocalCandidates(const std::string& defaultCandidateAddr, + uint16_t defaultCandidatePort, + uint16_t level) MOZ_OVERRIDE; + + virtual nsresult Close() MOZ_OVERRIDE; + + virtual const std::string GetLastError() const MOZ_OVERRIDE; + + virtual bool + IsIceControlling() const + { + return mIceControlling; + } + + virtual bool + IsOfferer() const + { + return mIsOfferer; + } + + // Access transports. + virtual size_t + GetTransportCount() const MOZ_OVERRIDE + { + return mTransports.size(); + } + + virtual nsresult + GetTransport(size_t index, + RefPtr* transport) const MOZ_OVERRIDE + { + if (index >= mTransports.size()) + return NS_ERROR_INVALID_ARG; + + *transport = mTransports[index]; + + return NS_OK; + } + + // Access the negotiated track pairs. + virtual size_t + GetNegotiatedTrackPairCount() const MOZ_OVERRIDE + { + return mNegotiatedTrackPairs.size(); + } + + virtual nsresult + GetNegotiatedTrackPair(size_t index, const JsepTrackPair** pair) const + { + if (index >= mNegotiatedTrackPairs.size()) + return NS_ERROR_INVALID_ARG; + + *pair = &mNegotiatedTrackPairs[index]; + + return NS_OK; + } + +private: + struct JsepDtlsFingerprint { + std::string mAlgorithm; + std::vector mValue; + }; + + struct JsepSendingTrack { + RefPtr mTrack; + Maybe mAssignedMLine; + }; + + struct JsepReceivingTrack { + RefPtr mTrack; + Maybe mAssignedMLine; + }; + + // Non-const so it can set mLastError + nsresult CreateGenericSDP(UniquePtr* sdp); + void AddCodecs(SdpMediaSection* msection) const; + void AddExtmap(SdpMediaSection* msection) const; + JsepCodecDescription* FindMatchingCodec( + const std::string& pt, + const SdpMediaSection& msection) const; + const std::vector* GetRtpExtensions( + SdpMediaSection::MediaType type) const; + void AddCommonCodecs(const SdpMediaSection& remoteMsection, + SdpMediaSection* msection); + void AddCommonExtmaps(const SdpMediaSection& remoteMsection, + SdpMediaSection* msection); + void SetupDefaultCodecs(); + void SetupDefaultRtpExtensions(); + void SetState(JsepSignalingState state); + // Non-const so it can set mLastError + nsresult ParseSdp(const std::string& sdp, UniquePtr* parsedp); + nsresult SetLocalDescriptionOffer(UniquePtr offer); + nsresult SetLocalDescriptionAnswer(JsepSdpType type, UniquePtr answer); + nsresult SetRemoteDescriptionOffer(UniquePtr offer); + nsresult SetRemoteDescriptionAnswer(JsepSdpType type, UniquePtr answer); + nsresult ValidateLocalDescription(const Sdp& description); + nsresult SetRemoteTracksFromDescription(const Sdp& remoteDescription); + // Non-const because we use our Uuid generator + nsresult CreateReceivingTrack(size_t mline, const SdpMediaSection& msection); + nsresult HandleNegotiatedSession(const UniquePtr& local, + const UniquePtr& remote); + nsresult DetermineSendingDirection(SdpDirectionAttribute::Direction offer, + SdpDirectionAttribute::Direction answer, + bool* sending, bool* receiving); + nsresult AddTransportAttributes(SdpMediaSection* msection, + SdpSetupAttribute::Role dtlsRole); + // Non-const so it can assign m-line index to tracks + nsresult AddOfferMSectionsByType(SdpMediaSection::MediaType type, + Maybe offerToReceive, + Sdp* sdp); + nsresult CreateOfferMSection(SdpMediaSection::MediaType type, + SdpDirectionAttribute::Direction direction, + SdpMediaSection::Protocol proto, + Sdp* sdp); + nsresult CreateAnswerMSection(const JsepAnswerOptions& options, + size_t mlineIndex, + const SdpMediaSection& remoteMsection, + SdpMediaSection* msection, + Sdp* sdp); + nsresult DetermineAnswererSetupRole(const SdpMediaSection& remoteMsection, + SdpSetupAttribute::Role* rolep); + nsresult NegotiateTrack(const SdpMediaSection& remoteMsection, + const SdpMediaSection& localMsection, + JsepTrack::Direction, + RefPtr* track); + + nsresult CreateTransport(const SdpMediaSection& msection, + RefPtr* transport); + + nsresult SetupTransport(const SdpAttributeList& remote, + const SdpAttributeList& answer, + const RefPtr& transport); + + nsresult AddCandidateToSdp(Sdp* sdp, + const std::string& candidate, + const std::string& mid, + uint16_t level); + + std::vector mLocalTracks; + std::vector mRemoteTracks; + std::vector > mTransports; + std::vector mNegotiatedTrackPairs; + + bool mIsOfferer; + bool mIceControlling; + std::string mIceUfrag; + std::string mIcePwd; + bool mRemoteIsIceLite; + std::vector mIceOptions; + std::vector mDtlsFingerprints; + uint64_t mSessionId; + uint64_t mSessionVersion; + std::vector mAudioRtpExtensions; + std::vector mVideoRtpExtensions; + UniquePtr mUuidGen; + std::string mDefaultRemoteStreamId; + UniquePtr mGeneratedLocalDescription; // Created but not set. + UniquePtr mCurrentLocalDescription; + UniquePtr mCurrentRemoteDescription; + UniquePtr mPendingLocalDescription; + UniquePtr mPendingRemoteDescription; + std::vector mCodecs; + std::string mLastError; + SipccSdpParser mParser; +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/jsep/JsepTrack.h b/media/webrtc/signaling/src/jsep/JsepTrack.h new file mode 100644 index 00000000000..c97f36075dc --- /dev/null +++ b/media/webrtc/signaling/src/jsep/JsepTrack.h @@ -0,0 +1,120 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JSEPTRACK_H_ +#define _JSEPTRACK_H_ + +#include + +#include +#include +#include +#include "nsISupportsImpl.h" +#include "nsError.h" + +#include "signaling/src/jsep/JsepTransport.h" +#include "signaling/src/sdp/Sdp.h" +#include "signaling/src/sdp/SdpMediaSection.h" + +namespace mozilla { + +// Forward reference. +struct JsepCodecDescription; + +class JsepTrackNegotiatedDetails +{ +public: + virtual ~JsepTrackNegotiatedDetails() {} + + virtual mozilla::SdpMediaSection::Protocol GetProtocol() const = 0; + virtual Maybe GetBandwidth(const std::string& type) const = 0; + virtual size_t GetCodecCount() const = 0; + virtual nsresult GetCodec(size_t index, + const JsepCodecDescription** config) const = 0; + virtual const SdpExtmapAttributeList::Extmap* GetExt( + const std::string& ext_name) const = 0; +}; + +class JsepTrack +{ +public: + enum Direction { kJsepTrackSending, kJsepTrackReceiving }; + + JsepTrack(mozilla::SdpMediaSection::MediaType type, + const std::string& streamid, + const std::string& trackid, + Direction direction = kJsepTrackSending) + : mType(type), + mStreamId(streamid), + mTrackId(trackid), + mDirection(direction) + { + } + + virtual mozilla::SdpMediaSection::MediaType + GetMediaType() const + { + return mType; + } + + virtual const std::string& + GetStreamId() const + { + return mStreamId; + } + + virtual const std::string& + GetTrackId() const + { + return mTrackId; + } + + virtual Direction + GetDirection() const + { + return mDirection; + } + + // This will be set when negotiation is carried out. + virtual const JsepTrackNegotiatedDetails* + GetNegotiatedDetails() const + { + if (mNegotiatedDetails) { + return mNegotiatedDetails.get(); + } + return nullptr; + } + + // This is for JsepSession's use. + virtual void + SetNegotiatedDetails(UniquePtr details) + { + mNegotiatedDetails = Move(details); + } + + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(JsepTrack); + +protected: + virtual ~JsepTrack() {} + +private: + const mozilla::SdpMediaSection::MediaType mType; + const std::string mStreamId; + const std::string mTrackId; + const Direction mDirection; + UniquePtr mNegotiatedDetails; +}; + +// Need a better name for this. +struct JsepTrackPair { + size_t mLevel; + RefPtr mSending; + RefPtr mReceiving; + RefPtr mRtpTransport; + RefPtr mRtcpTransport; +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/jsep/JsepTrackImpl.h b/media/webrtc/signaling/src/jsep/JsepTrackImpl.h new file mode 100644 index 00000000000..113970a3b50 --- /dev/null +++ b/media/webrtc/signaling/src/jsep/JsepTrackImpl.h @@ -0,0 +1,79 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JSEPTRACKIMPL_H_ +#define _JSEPTRACKIMPL_H_ + +#include + +#include +#include + +#include "signaling/src/jsep/JsepCodecDescription.h" +#include "signaling/src/jsep/JsepTrack.h" +#include "signaling/src/sdp/Sdp.h" +#include "signaling/src/sdp/SdpMediaSection.h" + +namespace mozilla { + +class JsepTrackNegotiatedDetailsImpl : public JsepTrackNegotiatedDetails +{ +public: + virtual ~JsepTrackNegotiatedDetailsImpl() + { + for (auto c = mCodecs.begin(); c != mCodecs.end(); ++c) { + delete *c; + } + } + + // Implement JsepTrackNegotiatedDetails. + virtual mozilla::SdpMediaSection::Protocol + GetProtocol() const MOZ_OVERRIDE + { + return mProtocol; + } + virtual Maybe + GetBandwidth(const std::string& type) const MOZ_OVERRIDE + { + return mBandwidth; + } + virtual size_t + GetCodecCount() const MOZ_OVERRIDE + { + return mCodecs.size(); + } + virtual nsresult + GetCodec(size_t index, const JsepCodecDescription** config) const MOZ_OVERRIDE + { + if (index >= mCodecs.size()) { + return NS_ERROR_INVALID_ARG; + } + *config = mCodecs[index]; + return NS_OK; + } + + virtual const SdpExtmapAttributeList::Extmap* + GetExt(const std::string& ext_name) const MOZ_OVERRIDE + { + auto it = mExtmap.find(ext_name); + if (it != mExtmap.end()) { + return &it->second; + } + return nullptr; + } + +private: + // Make these friends to JsepSessionImpl to avoid having to + // write setters. + friend class JsepSessionImpl; + + mozilla::SdpMediaSection::Protocol mProtocol; + Maybe mBandwidth; + std::vector mCodecs; + std::map mExtmap; +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/src/jsep/JsepTransport.h b/media/webrtc/signaling/src/jsep/JsepTransport.h new file mode 100644 index 00000000000..23d4484e442 --- /dev/null +++ b/media/webrtc/signaling/src/jsep/JsepTransport.h @@ -0,0 +1,117 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JSEPTRANSPORT_H_ +#define _JSEPTRANSPORT_H_ + +#include +#include + +#include +#include +#include "nsISupportsImpl.h" + +#include "signaling/src/sdp/SdpAttribute.h" + +namespace mozilla { + +class JsepDtlsTransport +{ +public: + JsepDtlsTransport() : mRole(kJsepDtlsInvalidRole) {} + + virtual ~JsepDtlsTransport() {} + + enum Role { + kJsepDtlsClient, + kJsepDtlsServer, + kJsepDtlsInvalidRole + }; + + virtual const SdpFingerprintAttributeList& + GetFingerprints() const + { + return mFingerprints; + } + + virtual Role + GetRole() const + { + return mRole; + } + +private: + friend class JsepSessionImpl; + + SdpFingerprintAttributeList mFingerprints; + Role mRole; +}; + +class JsepIceTransport +{ +public: + JsepIceTransport() {} + + virtual ~JsepIceTransport() {} + + const std::string& + GetUfrag() const + { + return mUfrag; + } + const std::string& + GetPassword() const + { + return mPwd; + } + const std::vector& + GetCandidates() const + { + return mCandidates; + } + +private: + friend class JsepSessionImpl; + + std::string mUfrag; + std::string mPwd; + std::vector mCandidates; +}; + +class JsepTransport +{ +public: + JsepTransport(const std::string& id, size_t components) + : mTransportId(id), mState(kJsepTransportOffered), mComponents(components) + { + } + + enum State { + kJsepTransportOffered, + kJsepTransportAccepted, + kJsepTransportClosed + }; + + // Unique identifier for this transport within this call. Group? + std::string mTransportId; + + // State. + State mState; + + // ICE stuff. + UniquePtr mIce; + UniquePtr mDtls; + + // Number of required components. + size_t mComponents; + + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(JsepTransport); + +protected: + ~JsepTransport() {} +}; + +} // namespace mozilla + +#endif diff --git a/media/webrtc/signaling/test/jsep_session_unittest.cpp b/media/webrtc/signaling/test/jsep_session_unittest.cpp new file mode 100644 index 00000000000..b56ce8b18a8 --- /dev/null +++ b/media/webrtc/signaling/test/jsep_session_unittest.cpp @@ -0,0 +1,1130 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include + +#include "nspr.h" +#include "nss.h" +#include "ssl.h" + +#include "mozilla/RefPtr.h" + +#define GTEST_HAS_RTTI 0 +#include "gtest/gtest.h" +#include "gtest_utils.h" + +#include "FakeMediaStreams.h" +#include "FakeMediaStreamsImpl.h" + +#include "signaling/src/sdp/SdpMediaSection.h" +#include "signaling/src/sdp/SipccSdpParser.h" +#include "signaling/src/jsep/JsepCodecDescription.h" +#include "signaling/src/jsep/JsepTrack.h" +#include "signaling/src/jsep/JsepSession.h" +#include "signaling/src/jsep/JsepSessionImpl.h" +#include "signaling/src/jsep/JsepTrack.h" + +namespace mozilla { +static const char* kCandidates[] = { + "0 1 UDP 9999 192.168.0.1 2000 typ host", + "0 1 UDP 9999 192.168.0.1 2001 typ host", + "0 1 UDP 9999 192.168.0.2 2002 typ srflx raddr 10.252.34.97 rport 53594", + // Mix up order + "0 1 UDP 9999 192.168.1.2 2012 typ srflx raddr 10.252.34.97 rport 53594", + "0 1 UDP 9999 192.168.1.1 2010 typ host", + "0 1 UDP 9999 192.168.1.1 2011 typ host" +}; + +static std::string kAEqualsCandidate("a=candidate:"); + +class JsepSessionTestBase : public ::testing::Test +{ +}; + +class FakeUuidGenerator : public mozilla::JsepUuidGenerator +{ +public: + bool + Generate(std::string* str) + { + std::ostringstream os; + os << "FAKE_UUID_" << ++ctr; + *str = os.str(); + + return true; + } + +private: + static uint64_t ctr; +}; + +uint64_t FakeUuidGenerator::ctr = 1000; + +class JsepSessionTest : public JsepSessionTestBase, + public ::testing::WithParamInterface +{ +public: + JsepSessionTest() + : mSessionOff("Offerer", MakeUnique()), + mSessionAns("Answerer", MakeUnique()) + { + EXPECT_EQ(NS_OK, mSessionOff.Init()); + EXPECT_EQ(NS_OK, mSessionAns.Init()); + + AddTransportData(&mSessionOff, &mOffererTransport); + AddTransportData(&mSessionAns, &mAnswererTransport); + } + +protected: + struct TransportData { + std::string mIceUfrag; + std::string mIcePwd; + std::map > mFingerprints; + }; + + void + AddDtlsFingerprint(const std::string& alg, JsepSessionImpl* session, + TransportData* tdata) + { + std::vector fp; + fp.assign((alg == "sha-1") ? 20 : 32, + (session->GetName() == "Offerer") ? 0x4f : 0x41); + session->AddDtlsFingerprint(alg, fp); + tdata->mFingerprints[alg] = fp; + } + + void + AddTransportData(JsepSessionImpl* session, TransportData* tdata) + { + // Values here semi-borrowed from JSEP draft. + tdata->mIceUfrag = session->GetName() + "-ufrag"; + tdata->mIcePwd = session->GetName() + "-1234567890"; + session->SetIceCredentials(tdata->mIceUfrag, tdata->mIcePwd); + AddDtlsFingerprint("sha-1", session, tdata); + AddDtlsFingerprint("sha-256", session, tdata); + } + + std::string + CreateOffer(const Maybe options = Nothing()) + { + JsepOfferOptions defaultOptions; + const JsepOfferOptions& optionsRef = options ? *options : defaultOptions; + std::string offer; + nsresult rv = mSessionOff.CreateOffer(optionsRef, &offer); + EXPECT_EQ(NS_OK, rv) << mSessionOff.GetLastError(); + + std::cerr << "OFFER: " << offer << std::endl; + + ValidateTransport(mOffererTransport, offer); + + return offer; + } + + void + AddTracks(JsepSessionImpl* side) + { + // Add tracks. + if (types.empty()) { + types = BuildTypes(GetParam()); + } + AddTracks(side, types); + + // Now that we have added streams, we expect audio, then video, then + // application in the SDP, regardless of the order in which the streams were + // added. + std::sort(types.begin(), types.end()); + } + + void + AddTracks(JsepSessionImpl* side, const std::string& mediatypes) + { + AddTracks(side, BuildTypes(mediatypes)); + } + + std::vector + BuildTypes(const std::string& mediatypes) + { + std::vector result; + size_t ptr = 0; + + for (;;) { + size_t comma = mediatypes.find(',', ptr); + std::string chunk = mediatypes.substr(ptr, comma - ptr); + + SdpMediaSection::MediaType type; + if (chunk == "audio") { + type = SdpMediaSection::kAudio; + } else if (chunk == "video") { + type = SdpMediaSection::kVideo; + } else if (chunk == "datachannel") { + type = SdpMediaSection::kApplication; + } else { + MOZ_CRASH(); + } + result.push_back(type); + + if (comma == std::string::npos) + break; + ptr = comma + 1; + } + + return result; + } + + void + AddTracks(JsepSessionImpl* side, + const std::vector& mediatypes) + { + FakeUuidGenerator uuid_gen; + std::string stream_id; + std::string track_id; + + ASSERT_TRUE(uuid_gen.Generate(&stream_id)); + + for (auto track = mediatypes.begin(); track != mediatypes.end(); ++track) { + ASSERT_TRUE(uuid_gen.Generate(&track_id)); + + RefPtr mst(new JsepTrack(*track, stream_id, track_id)); + side->AddTrack(mst); + } + } + + void + EnsureNegotiationFailure(SdpMediaSection::MediaType type, + const std::string& codecName) + { + for (auto i = mSessionOff.Codecs().begin(); i != mSessionOff.Codecs().end(); + ++i) { + auto* codec = *i; + if (codec->mType == type && codec->mName != codecName) { + codec->mEnabled = false; + } + } + + for (auto i = mSessionAns.Codecs().begin(); i != mSessionAns.Codecs().end(); + ++i) { + auto* codec = *i; + if (codec->mType == type && codec->mName == codecName) { + codec->mEnabled = false; + } + } + } + + std::string + CreateAnswer() + { + JsepAnswerOptions options; + std::string answer; + nsresult rv = mSessionAns.CreateAnswer(options, &answer); + EXPECT_EQ(NS_OK, rv); + + std::cerr << "ANSWER: " << answer << std::endl; + + ValidateTransport(mAnswererTransport, answer); + + return answer; + } + + static const uint32_t NO_CHECKS = 0; + static const uint32_t CHECK_SUCCESS = 1; + static const uint32_t CHECK_TRACKS = 1 << 2; + static const uint32_t ALL_CHECKS = CHECK_SUCCESS | CHECK_TRACKS; + + void + SetLocalOffer(const std::string& offer, uint32_t checkFlags = ALL_CHECKS) + { + nsresult rv = mSessionOff.SetLocalDescription(kJsepSdpOffer, offer); + + if (checkFlags & CHECK_SUCCESS) { + ASSERT_EQ(NS_OK, rv); + } + + if (checkFlags & CHECK_TRACKS) { + // Check that the transports exist. + ASSERT_EQ(types.size(), mSessionOff.GetTransportCount()); + } + } + + void + SetRemoteOffer(const std::string& offer, uint32_t checkFlags = ALL_CHECKS) + { + nsresult rv = mSessionAns.SetRemoteDescription(kJsepSdpOffer, offer); + + if (checkFlags & CHECK_SUCCESS) { + ASSERT_EQ(NS_OK, rv); + } + + if (checkFlags & CHECK_TRACKS) { + // Now verify that the right stuff is in the tracks. + ASSERT_EQ(types.size(), mSessionAns.GetRemoteTrackCount()); + for (size_t i = 0; i < types.size(); ++i) { + RefPtr rtrack; + ASSERT_EQ(NS_OK, mSessionAns.GetRemoteTrack(i, &rtrack)); + ASSERT_EQ(types[i], rtrack->GetMediaType()); + } + } + } + + void + SetLocalAnswer(const std::string& answer, uint32_t checkFlags = ALL_CHECKS) + { + nsresult rv = mSessionAns.SetLocalDescription(kJsepSdpAnswer, answer); + if (checkFlags & CHECK_SUCCESS) { + ASSERT_EQ(NS_OK, rv); + } + + if (checkFlags & CHECK_TRACKS) { + // Verify that the right stuff is in the tracks. + ASSERT_EQ(types.size(), mSessionAns.GetNegotiatedTrackPairCount()); + for (size_t i = 0; i < types.size(); ++i) { + const JsepTrackPair* pair; + ASSERT_EQ(NS_OK, mSessionAns.GetNegotiatedTrackPair(i, &pair)); + ASSERT_TRUE(pair->mSending); + ASSERT_EQ(types[i], pair->mSending->GetMediaType()); + ASSERT_TRUE(pair->mReceiving); + ASSERT_EQ(types[i], pair->mReceiving->GetMediaType()); + } + } + DumpTrackPairs(mSessionOff); + } + + void + SetRemoteAnswer(const std::string& answer, uint32_t checkFlags = ALL_CHECKS) + { + nsresult rv = mSessionOff.SetRemoteDescription(kJsepSdpAnswer, answer); + if (checkFlags & CHECK_SUCCESS) { + ASSERT_EQ(NS_OK, rv); + } + + if (checkFlags & CHECK_TRACKS) { + // Verify that the right stuff is in the tracks. + ASSERT_EQ(types.size(), mSessionAns.GetNegotiatedTrackPairCount()); + for (size_t i = 0; i < types.size(); ++i) { + const JsepTrackPair* pair; + ASSERT_EQ(NS_OK, mSessionAns.GetNegotiatedTrackPair(i, &pair)); + ASSERT_TRUE(pair->mSending); + ASSERT_EQ(types[i], pair->mSending->GetMediaType()); + ASSERT_TRUE(pair->mReceiving); + ASSERT_EQ(types[i], pair->mReceiving->GetMediaType()); + } + } + DumpTrackPairs(mSessionAns); + } + + void + GatherCandidates(JsepSession& session) + { + session.AddLocalIceCandidate(kAEqualsCandidate + kCandidates[0], "", 0); + session.AddLocalIceCandidate(kAEqualsCandidate + kCandidates[1], "", 0); + session.AddLocalIceCandidate(kAEqualsCandidate + kCandidates[2], "", 0); + session.EndOfLocalCandidates("192.168.0.2", 2002, 0); + + session.AddLocalIceCandidate(kAEqualsCandidate + kCandidates[3], "", 1); + session.AddLocalIceCandidate(kAEqualsCandidate + kCandidates[4], "", 1); + session.AddLocalIceCandidate(kAEqualsCandidate + kCandidates[5], "", 1); + session.EndOfLocalCandidates("192.168.1.2", 2012, 1); + + std::cerr << "local SDP after candidates: " + << session.GetLocalDescription(); + } + + void + TrickleCandidates(JsepSession& session) + { + session.AddRemoteIceCandidate(kAEqualsCandidate + kCandidates[0], "", 0); + session.AddRemoteIceCandidate(kAEqualsCandidate + kCandidates[1], "", 0); + session.AddRemoteIceCandidate(kAEqualsCandidate + kCandidates[2], "", 0); + + session.AddRemoteIceCandidate(kAEqualsCandidate + kCandidates[3], "", 1); + session.AddRemoteIceCandidate(kAEqualsCandidate + kCandidates[4], "", 1); + session.AddRemoteIceCandidate(kAEqualsCandidate + kCandidates[5], "", 1); + + std::cerr << "remote SDP after candidates: " + << session.GetRemoteDescription(); + } + + void + GatherOffererCandidates() + { + GatherCandidates(mSessionOff); + } + + void + TrickleOffererCandidates() + { + TrickleCandidates(mSessionAns); + } + + // For streaming parse errors + std::string + GetParseErrors(const SipccSdpParser& parser) const + { + std::stringstream output; + for (auto e = parser.GetParseErrors().begin(); + e != parser.GetParseErrors().end(); + ++e) { + output << e->first << ": " << e->second << std::endl; + } + return output.str(); + } + + void + ValidateCandidates(JsepSession& session, bool local) + { + std::string sdp = + local ? session.GetLocalDescription() : session.GetRemoteDescription(); + SipccSdpParser parser; + UniquePtr parsed = parser.Parse(sdp); + ASSERT_TRUE(parsed) << "Parse failed on " << std::endl << sdp << std::endl + << "Errors were: " << GetParseErrors(parser); + ASSERT_LT(0U, parsed->GetMediaSectionCount()); + + auto& msection_0 = parsed->GetMediaSection(0); + + // We should not be doing things like setting the c-line on remote SDP + if (local) { + ASSERT_EQ("192.168.0.2", msection_0.GetConnection().GetAddress()); + ASSERT_EQ(2002U, msection_0.GetPort()); + // TODO: Check end-of-candidates. Issue 200 + } + + auto& attrs_0 = msection_0.GetAttributeList(); + ASSERT_TRUE(attrs_0.HasAttribute(SdpAttribute::kCandidateAttribute)); + + auto& candidates_0 = attrs_0.GetCandidate(); + ASSERT_EQ(3U, candidates_0.size()); + ASSERT_EQ(kCandidates[0], candidates_0[0]); + ASSERT_EQ(kCandidates[1], candidates_0[1]); + ASSERT_EQ(kCandidates[2], candidates_0[2]); + + if (parsed->GetMediaSectionCount() > 1) { + auto& msection_1 = parsed->GetMediaSection(1); + + if (local) { + ASSERT_EQ("192.168.1.2", msection_1.GetConnection().GetAddress()); + ASSERT_EQ(2012U, msection_1.GetPort()); + // TODO: Check end-of-candidates. Issue 200 + } + + auto& attrs_1 = msection_1.GetAttributeList(); + ASSERT_TRUE(attrs_1.HasAttribute(SdpAttribute::kCandidateAttribute)); + + auto& candidates_1 = attrs_1.GetCandidate(); + ASSERT_EQ(3U, candidates_1.size()); + ASSERT_EQ(kCandidates[3], candidates_1[0]); + ASSERT_EQ(kCandidates[4], candidates_1[1]); + ASSERT_EQ(kCandidates[5], candidates_1[2]); + } + } + + void + ValidateOffererCandidates() + { + ValidateCandidates(mSessionOff, true); + } + + void + ValidateAnswererCandidates() + { + ValidateCandidates(mSessionAns, false); + } + + void + DumpTrack(const JsepTrack& track) + { + std::cerr << " type=" << track.GetMediaType() << std::endl; + std::cerr << " protocol=" << track.GetNegotiatedDetails()->GetProtocol() + << std::endl; + std::cerr << " codecs=" << std::endl; + size_t num_codecs = track.GetNegotiatedDetails()->GetCodecCount(); + for (size_t i = 0; i < num_codecs; ++i) { + const JsepCodecDescription* codec; + ASSERT_EQ(NS_OK, track.GetNegotiatedDetails()->GetCodec(i, &codec)); + std::cerr << " " << codec->mName << std::endl; + } + } + + void + DumpTrackPairs(const JsepSessionImpl& session) + { + size_t count = mSessionAns.GetNegotiatedTrackPairCount(); + for (size_t i = 0; i < count; ++i) { + std::cerr << "Track pair " << i << std::endl; + const JsepTrackPair* pair; + ASSERT_EQ(NS_OK, mSessionAns.GetNegotiatedTrackPair(i, &pair)); + if (pair->mSending) { + std::cerr << "Sending-->" << std::endl; + DumpTrack(*pair->mSending); + } + if (pair->mReceiving) { + std::cerr << "Receiving-->" << std::endl; + DumpTrack(*pair->mReceiving); + } + } + } + + JsepSessionImpl mSessionOff; + JsepSessionImpl mSessionAns; + std::vector types; + +private: + void + ValidateTransport(TransportData& source, const std::string& sdp_str) + { + SipccSdpParser parser; + auto sdp = mozilla::Move(parser.Parse(sdp_str)); + ASSERT_TRUE(sdp) << "Should have valid SDP" << std::endl + << "Errors were: " << GetParseErrors(parser); + size_t num_m_sections = sdp->GetMediaSectionCount(); + for (size_t i = 0; i < num_m_sections; ++i) { + auto& msection = sdp->GetMediaSection(i); + + if (msection.GetMediaType() == SdpMediaSection::kApplication) { + ASSERT_EQ(SdpMediaSection::kDtlsSctp, msection.GetProtocol()); + } else { + ASSERT_EQ(SdpMediaSection::kRtpSavpf, msection.GetProtocol()); + } + + if (msection.GetPort() == 0) { + ASSERT_EQ(SdpDirectionAttribute::kInactive, + msection.GetDirectionAttribute().mValue); + // Maybe validate that no attributes are present except rtpmap and + // inactive? + continue; + } + const SdpAttributeList& attrs = msection.GetAttributeList(); + ASSERT_EQ(source.mIceUfrag, attrs.GetIceUfrag()); + ASSERT_EQ(source.mIcePwd, attrs.GetIcePwd()); + const SdpFingerprintAttributeList& fps = attrs.GetFingerprint(); + for (auto fp = fps.mFingerprints.begin(); fp != fps.mFingerprints.end(); + ++fp) { + std::string alg_str = "None"; + + if (fp->hashFunc == SdpFingerprintAttributeList::kSha1) { + alg_str = "sha-1"; + } else if (fp->hashFunc == SdpFingerprintAttributeList::kSha256) { + alg_str = "sha-256"; + } + + ASSERT_EQ(source.mFingerprints[alg_str], fp->fingerprint); + } + ASSERT_EQ(source.mFingerprints.size(), fps.mFingerprints.size()); + } + } + + TransportData mOffererTransport; + TransportData mAnswererTransport; +}; + +TEST_F(JsepSessionTestBase, CreateDestroy) {} + +TEST_P(JsepSessionTest, CreateOffer) +{ + AddTracks(&mSessionOff); + CreateOffer(); +} + +TEST_P(JsepSessionTest, CreateOfferSetLocal) +{ + AddTracks(&mSessionOff); + std::string offer = CreateOffer(); + SetLocalOffer(offer); +} + +TEST_P(JsepSessionTest, CreateOfferSetLocalSetRemote) +{ + AddTracks(&mSessionOff); + std::string offer = CreateOffer(); + SetLocalOffer(offer); + SetRemoteOffer(offer); +} + +TEST_P(JsepSessionTest, CreateOfferSetLocalSetRemoteCreateAnswer) +{ + AddTracks(&mSessionOff); + std::string offer = CreateOffer(); + SetLocalOffer(offer); + SetRemoteOffer(offer); + AddTracks(&mSessionAns); + std::string answer = CreateAnswer(); +} + +TEST_P(JsepSessionTest, CreateOfferSetLocalSetRemoteCreateAnswerSetLocal) +{ + AddTracks(&mSessionOff); + std::string offer = CreateOffer(); + SetLocalOffer(offer); + SetRemoteOffer(offer); + AddTracks(&mSessionAns); + std::string answer = CreateAnswer(); + SetLocalAnswer(answer); +} + +TEST_P(JsepSessionTest, FullCall) +{ + AddTracks(&mSessionOff); + std::string offer = CreateOffer(); + SetLocalOffer(offer); + SetRemoteOffer(offer); + AddTracks(&mSessionAns); + std::string answer = CreateAnswer(); + SetLocalAnswer(answer); + SetRemoteAnswer(answer); +} + +TEST_P(JsepSessionTest, FullCallWithCandidates) +{ + AddTracks(&mSessionOff); + std::string offer = CreateOffer(); + SetLocalOffer(offer); + GatherOffererCandidates(); + ValidateOffererCandidates(); + SetRemoteOffer(offer); + TrickleOffererCandidates(); + ValidateAnswererCandidates(); + AddTracks(&mSessionAns); + std::string answer = CreateAnswer(); + SetLocalAnswer(answer); + SetRemoteAnswer(answer); +} + +INSTANTIATE_TEST_CASE_P(Variants, JsepSessionTest, + ::testing::Values("audio", + "video", + "datachannel", + "audio,video", + "video,audio", + "audio,datachannel", + "video,datachannel", + "video,audio,datachannel", + "audio,video,datachannel", + "datachannel,audio", + "datachannel,video", + "datachannel,audio,video", + "datachannel,video,audio")); + +// offerToReceiveXxx variants + +TEST_F(JsepSessionTest, OfferAnswerRecvOnlyLines) +{ + JsepOfferOptions options; + options.mOfferToReceiveAudio = Some(static_cast(1U)); + options.mOfferToReceiveVideo = Some(static_cast(2U)); + options.mDontOfferDataChannel = Some(true); + std::string offer = CreateOffer(Some(options)); + + SipccSdpParser parser; + auto outputSdp = mozilla::Move(parser.Parse(offer)); + ASSERT_TRUE(outputSdp) << "Should have valid SDP" << std::endl + << "Errors were: " << GetParseErrors(parser); + + ASSERT_EQ(3U, outputSdp->GetMediaSectionCount()); + ASSERT_EQ(SdpMediaSection::kAudio, + outputSdp->GetMediaSection(0).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kRecvonly, + outputSdp->GetMediaSection(0).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(1).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kRecvonly, + outputSdp->GetMediaSection(1).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(2).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kRecvonly, + outputSdp->GetMediaSection(2).GetAttributeList().GetDirection()); + + ASSERT_TRUE(outputSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + ASSERT_TRUE(outputSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + ASSERT_TRUE(outputSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + + SetLocalOffer(offer, CHECK_SUCCESS); + + AddTracks(&mSessionAns, "audio,video"); + SetRemoteOffer(offer, CHECK_SUCCESS); + + std::string answer = CreateAnswer(); + outputSdp = mozilla::Move(parser.Parse(answer)); + + ASSERT_EQ(3U, outputSdp->GetMediaSectionCount()); + ASSERT_EQ(SdpMediaSection::kAudio, + outputSdp->GetMediaSection(0).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kSendonly, + outputSdp->GetMediaSection(0).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(1).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kSendonly, + outputSdp->GetMediaSection(1).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(2).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kInactive, + outputSdp->GetMediaSection(2).GetAttributeList().GetDirection()); +} + +TEST_F(JsepSessionTest, OfferAnswerSendOnlyLines) +{ + AddTracks(&mSessionOff, "audio,video,video"); + + JsepOfferOptions options; + options.mOfferToReceiveAudio = Some(static_cast(0U)); + options.mOfferToReceiveVideo = Some(static_cast(1U)); + options.mDontOfferDataChannel = Some(true); + std::string offer = CreateOffer(Some(options)); + + SipccSdpParser parser; + auto outputSdp = mozilla::Move(parser.Parse(offer)); + ASSERT_TRUE(outputSdp) << "Should have valid SDP" << std::endl + << "Errors were: " << GetParseErrors(parser); + + ASSERT_EQ(3U, outputSdp->GetMediaSectionCount()); + ASSERT_EQ(SdpMediaSection::kAudio, + outputSdp->GetMediaSection(0).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kSendonly, + outputSdp->GetMediaSection(0).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(1).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kSendrecv, + outputSdp->GetMediaSection(1).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(2).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kSendonly, + outputSdp->GetMediaSection(2).GetAttributeList().GetDirection()); + + ASSERT_TRUE(outputSdp->GetMediaSection(0).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + ASSERT_TRUE(outputSdp->GetMediaSection(1).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + ASSERT_TRUE(outputSdp->GetMediaSection(2).GetAttributeList().HasAttribute( + SdpAttribute::kRtcpMuxAttribute)); + + SetLocalOffer(offer, CHECK_SUCCESS); + + AddTracks(&mSessionAns, "audio,video"); + SetRemoteOffer(offer, CHECK_SUCCESS); + + std::string answer = CreateAnswer(); + outputSdp = mozilla::Move(parser.Parse(answer)); + + ASSERT_EQ(3U, outputSdp->GetMediaSectionCount()); + ASSERT_EQ(SdpMediaSection::kAudio, + outputSdp->GetMediaSection(0).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kRecvonly, + outputSdp->GetMediaSection(0).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(1).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kSendrecv, + outputSdp->GetMediaSection(1).GetAttributeList().GetDirection()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(2).GetMediaType()); + ASSERT_EQ(SdpDirectionAttribute::kRecvonly, + outputSdp->GetMediaSection(2).GetAttributeList().GetDirection()); +} + +TEST_F(JsepSessionTest, CreateOfferNoDatachannelDefault) +{ + RefPtr msta( + new JsepTrack(SdpMediaSection::kAudio, "offerer_stream", "a1")); + mSessionOff.AddTrack(msta); + + RefPtr mstv1( + new JsepTrack(SdpMediaSection::kVideo, "offerer_stream", "v1")); + mSessionOff.AddTrack(mstv1); + + std::string offer = CreateOffer(); + + SipccSdpParser parser; + auto outputSdp = mozilla::Move(parser.Parse(offer)); + ASSERT_TRUE(outputSdp) << "Should have valid SDP" << std::endl + << "Errors were: " << GetParseErrors(parser); + + ASSERT_EQ(2U, outputSdp->GetMediaSectionCount()); + ASSERT_EQ(SdpMediaSection::kAudio, + outputSdp->GetMediaSection(0).GetMediaType()); + ASSERT_EQ(SdpMediaSection::kVideo, + outputSdp->GetMediaSection(1).GetMediaType()); +} + +TEST_F(JsepSessionTest, ValidateOfferedCodecParams) +{ + types.push_back(SdpMediaSection::kAudio); + types.push_back(SdpMediaSection::kVideo); + + RefPtr msta( + new JsepTrack(SdpMediaSection::kAudio, "offerer_stream", "a1")); + mSessionOff.AddTrack(msta); + RefPtr mstv1( + new JsepTrack(SdpMediaSection::kVideo, "offerer_stream", "v2")); + mSessionOff.AddTrack(mstv1); + + std::string offer = CreateOffer(); + + SipccSdpParser parser; + auto outputSdp = mozilla::Move(parser.Parse(offer)); + ASSERT_TRUE(outputSdp) << "Should have valid SDP" << std::endl + << "Errors were: " << GetParseErrors(parser); + + ASSERT_EQ(2U, outputSdp->GetMediaSectionCount()); + auto& video_section = outputSdp->GetMediaSection(1); + ASSERT_EQ(SdpMediaSection::kVideo, video_section.GetMediaType()); + auto& video_attrs = video_section.GetAttributeList(); + ASSERT_EQ(SdpDirectionAttribute::kSendrecv, video_attrs.GetDirection()); + + ASSERT_EQ(3U, video_section.GetFormats().size()); + ASSERT_EQ("120", video_section.GetFormats()[0]); + ASSERT_EQ("126", video_section.GetFormats()[1]); + ASSERT_EQ("97", video_section.GetFormats()[2]); + + // Validate rtpmap + ASSERT_TRUE(video_attrs.HasAttribute(SdpAttribute::kRtpmapAttribute)); + auto& rtpmaps = video_attrs.GetRtpmap(); + ASSERT_TRUE(rtpmaps.HasEntry("120")); + ASSERT_TRUE(rtpmaps.HasEntry("126")); + ASSERT_TRUE(rtpmaps.HasEntry("97")); + + auto& vp8_entry = rtpmaps.GetEntry("120"); + auto& h264_1_entry = rtpmaps.GetEntry("126"); + auto& h264_0_entry = rtpmaps.GetEntry("97"); + + ASSERT_EQ("VP8", vp8_entry.name); + ASSERT_EQ("H264", h264_1_entry.name); + ASSERT_EQ("H264", h264_0_entry.name); + + // Validate fmtps + ASSERT_TRUE(video_attrs.HasAttribute(SdpAttribute::kFmtpAttribute)); + auto& fmtps = video_attrs.GetFmtp().mFmtps; + + ASSERT_EQ(3U, fmtps.size()); + + // VP8 + ASSERT_EQ("120", fmtps[0].format); + ASSERT_TRUE(fmtps[0].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kVP8, fmtps[0].parameters->codec_type); + + auto& parsed_vp8_params = + *static_cast( + fmtps[0].parameters.get()); + + ASSERT_EQ((uint32_t)12288, parsed_vp8_params.max_fs); + ASSERT_EQ((uint32_t)60, parsed_vp8_params.max_fr); + + // H264 packetization mode 1 + ASSERT_EQ("126", fmtps[1].format); + ASSERT_TRUE(fmtps[1].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kH264, fmtps[1].parameters->codec_type); + + auto& parsed_h264_1_params = + *static_cast( + fmtps[1].parameters.get()); + + ASSERT_EQ((uint32_t)0x42e00d, parsed_h264_1_params.profile_level_id); + ASSERT_TRUE(parsed_h264_1_params.level_asymmetry_allowed); + ASSERT_EQ(1U, parsed_h264_1_params.packetization_mode); + + // H264 packetization mode 0 + ASSERT_EQ("97", fmtps[2].format); + ASSERT_TRUE(fmtps[2].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kH264, fmtps[2].parameters->codec_type); + + auto& parsed_h264_0_params = + *static_cast( + fmtps[2].parameters.get()); + + ASSERT_EQ((uint32_t)0x42e00d, parsed_h264_0_params.profile_level_id); + ASSERT_TRUE(parsed_h264_0_params.level_asymmetry_allowed); + ASSERT_EQ(0U, parsed_h264_0_params.packetization_mode); +} + +TEST_F(JsepSessionTest, ValidateAnsweredCodecParams) +{ + + for (auto i = mSessionAns.Codecs().begin(); i != mSessionAns.Codecs().end(); + ++i) { + auto* codec = *i; + if (codec->mName == "H264") { + JsepVideoCodecDescription* h264 = + static_cast(codec); + h264->mProfileLevelId = 0x42a00d; + // Switch up the pts + if (h264->mDefaultPt == "126") { + h264->mDefaultPt = "97"; + } else { + h264->mDefaultPt = "126"; + } + } + } + + types.push_back(SdpMediaSection::kAudio); + types.push_back(SdpMediaSection::kVideo); + + RefPtr msta( + new JsepTrack(SdpMediaSection::kAudio, "offerer_stream", "a1")); + mSessionOff.AddTrack(msta); + RefPtr mstv1( + new JsepTrack(SdpMediaSection::kVideo, "offerer_stream", "v1")); + mSessionOff.AddTrack(mstv1); + + std::string offer = CreateOffer(); + SetLocalOffer(offer); + SetRemoteOffer(offer); + + RefPtr msta_ans( + new JsepTrack(SdpMediaSection::kAudio, "answerer_stream", "a1")); + mSessionAns.AddTrack(msta); + RefPtr mstv1_ans( + new JsepTrack(SdpMediaSection::kVideo, "answerer_stream", "v1")); + mSessionAns.AddTrack(mstv1); + + std::string answer = CreateAnswer(); + + SipccSdpParser parser; + auto outputSdp = mozilla::Move(parser.Parse(answer)); + ASSERT_TRUE(outputSdp) << "Should have valid SDP" << std::endl + << "Errors were: " << GetParseErrors(parser); + + ASSERT_EQ(2U, outputSdp->GetMediaSectionCount()); + auto& video_section = outputSdp->GetMediaSection(1); + ASSERT_EQ(SdpMediaSection::kVideo, video_section.GetMediaType()); + auto& video_attrs = video_section.GetAttributeList(); + ASSERT_EQ(SdpDirectionAttribute::kSendrecv, video_attrs.GetDirection()); + + // TODO(bug 1099351): Once fixed, this stuff will need to be updated. + ASSERT_EQ(1U, video_section.GetFormats().size()); + // ASSERT_EQ(3U, video_section.GetFormats().size()); + ASSERT_EQ("120", video_section.GetFormats()[0]); + // ASSERT_EQ("126", video_section.GetFormats()[1]); + // ASSERT_EQ("97", video_section.GetFormats()[2]); + + // Validate rtpmap + ASSERT_TRUE(video_attrs.HasAttribute(SdpAttribute::kRtpmapAttribute)); + auto& rtpmaps = video_attrs.GetRtpmap(); + ASSERT_TRUE(rtpmaps.HasEntry("120")); + // ASSERT_TRUE(rtpmaps.HasEntry("126")); + // ASSERT_TRUE(rtpmaps.HasEntry("97")); + + auto& vp8_entry = rtpmaps.GetEntry("120"); + // auto& h264_1_entry = rtpmaps.GetEntry("126"); + // auto& h264_0_entry = rtpmaps.GetEntry("97"); + + ASSERT_EQ("VP8", vp8_entry.name); + // ASSERT_EQ("H264", h264_1_entry.name); + // ASSERT_EQ("H264", h264_0_entry.name); + + // Validate fmtps + ASSERT_TRUE(video_attrs.HasAttribute(SdpAttribute::kFmtpAttribute)); + auto& fmtps = video_attrs.GetFmtp().mFmtps; + + ASSERT_EQ(1U, fmtps.size()); + // ASSERT_EQ(3U, fmtps.size()); + + // VP8 + ASSERT_EQ("120", fmtps[0].format); + ASSERT_TRUE(fmtps[0].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kVP8, fmtps[0].parameters->codec_type); + + auto& parsed_vp8_params = + *static_cast( + fmtps[0].parameters.get()); + + ASSERT_EQ((uint32_t)12288, parsed_vp8_params.max_fs); + ASSERT_EQ((uint32_t)60, parsed_vp8_params.max_fr); + +#if 0 + // H264 packetization mode 1 + ASSERT_EQ("126", fmtps[1].format); + ASSERT_TRUE(fmtps[1].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kH264, fmtps[1].parameters->codec_type); + + auto& parsed_h264_1_params = + *static_cast( + fmtps[1].parameters.get()); + + ASSERT_EQ((uint32_t)0x42a00d, parsed_h264_1_params.profile_level_id); + ASSERT_TRUE(parsed_h264_1_params.level_asymmetry_allowed); + ASSERT_EQ(1U, parsed_h264_1_params.packetization_mode); + + // H264 packetization mode 0 + ASSERT_EQ("97", fmtps[2].format); + ASSERT_TRUE(fmtps[2].parameters); + ASSERT_EQ(SdpRtpmapAttributeList::kH264, fmtps[2].parameters->codec_type); + + auto& parsed_h264_0_params = + *static_cast( + fmtps[2].parameters.get()); + + ASSERT_EQ((uint32_t)0x42a00d, parsed_h264_0_params.profile_level_id); + ASSERT_TRUE(parsed_h264_0_params.level_asymmetry_allowed); + ASSERT_EQ(0U, parsed_h264_0_params.packetization_mode); +#endif +} + +TEST_P(JsepSessionTest, TestRejectMline) +{ + AddTracks(&mSessionOff); + AddTracks(&mSessionAns); + + switch (types.front()) { + case SdpMediaSection::kAudio: + // Sabotage audio + EnsureNegotiationFailure(types.front(), "opus"); + break; + case SdpMediaSection::kVideo: + // Sabotage video + EnsureNegotiationFailure(types.front(), "H264"); + break; + case SdpMediaSection::kApplication: + // Sabotage datachannel + EnsureNegotiationFailure(types.front(), "webrtc-datachannel"); + break; + default: + ASSERT_TRUE(false) << "Unknown media type"; + } + + std::string offer = CreateOffer(); + mSessionOff.SetLocalDescription(kJsepSdpOffer, offer); + mSessionAns.SetRemoteDescription(kJsepSdpOffer, offer); + + std::string answer = CreateAnswer(); + + SipccSdpParser parser; + auto outputSdp = mozilla::Move(parser.Parse(answer)); + ASSERT_TRUE(outputSdp) << "Should have valid SDP" << std::endl + << "Errors were: " << GetParseErrors(parser); + + ASSERT_NE(0U, outputSdp->GetMediaSectionCount()); + SdpMediaSection* failed_section = nullptr; + + for (size_t i = 0; i < outputSdp->GetMediaSectionCount(); ++i) { + if (outputSdp->GetMediaSection(i).GetMediaType() == types.front()) { + failed_section = &outputSdp->GetMediaSection(i); + } + } + + ASSERT_TRUE(failed_section) << "Failed type was entirely absent from SDP"; + auto& failed_attrs = failed_section->GetAttributeList(); + ASSERT_EQ(SdpDirectionAttribute::kInactive, failed_attrs.GetDirection()); + ASSERT_EQ(0U, failed_section->GetPort()); + + mSessionAns.SetLocalDescription(kJsepSdpAnswer, answer); + mSessionOff.SetRemoteDescription(kJsepSdpAnswer, answer); + + ASSERT_EQ(types.size() - 1, mSessionOff.GetNegotiatedTrackPairCount()); + ASSERT_EQ(types.size() - 1, mSessionAns.GetNegotiatedTrackPairCount()); + + ASSERT_EQ(types.size(), mSessionOff.GetTransportCount()); + ASSERT_EQ(types.size(), mSessionOff.GetLocalTrackCount()); + ASSERT_EQ(types.size() - 1, mSessionOff.GetRemoteTrackCount()); + + ASSERT_EQ(types.size(), mSessionAns.GetTransportCount()); + ASSERT_EQ(types.size(), mSessionAns.GetLocalTrackCount()); + ASSERT_EQ(types.size(), mSessionAns.GetRemoteTrackCount()); +} + +TEST_F(JsepSessionTest, CreateOfferNoMlines) +{ + JsepOfferOptions options; + std::string offer; + nsresult rv = mSessionOff.CreateOffer(options, &offer); + ASSERT_NE(NS_OK, rv); + ASSERT_NE("", mSessionOff.GetLastError()); +} + +TEST_F(JsepSessionTest, TestIceLite) +{ + AddTracks(&mSessionOff, "audio"); + AddTracks(&mSessionAns, "audio"); + std::string offer = CreateOffer(); + SetLocalOffer(offer, CHECK_SUCCESS); + + SipccSdpParser parser; + UniquePtr parsedOffer = parser.Parse(offer); + parsedOffer->GetAttributeList().SetAttribute( + new SdpFlagAttribute(SdpAttribute::kIceLiteAttribute)); + + std::ostringstream os; + parsedOffer->Serialize(os); + SetRemoteOffer(os.str(), CHECK_SUCCESS); + + ASSERT_TRUE(mSessionAns.RemoteIsIceLite()); + ASSERT_FALSE(mSessionOff.RemoteIsIceLite()); +} + +TEST_F(JsepSessionTest, TestIceOptions) +{ + AddTracks(&mSessionOff, "audio"); + AddTracks(&mSessionAns, "audio"); + std::string offer = CreateOffer(); + SetLocalOffer(offer, CHECK_SUCCESS); + SetRemoteOffer(offer, CHECK_SUCCESS); + std::string answer = CreateAnswer(); + SetLocalAnswer(answer, CHECK_SUCCESS); + SetRemoteAnswer(answer, CHECK_SUCCESS); + + ASSERT_EQ(1U, mSessionOff.GetIceOptions().size()); + ASSERT_EQ("trickle", mSessionOff.GetIceOptions()[0]); + + ASSERT_EQ(1U, mSessionAns.GetIceOptions().size()); + ASSERT_EQ("trickle", mSessionAns.GetIceOptions()[0]); +} + +TEST_F(JsepSessionTest, TestExtmap) +{ + AddTracks(&mSessionOff, "audio"); + AddTracks(&mSessionAns, "audio"); + // ssrc-audio-level will be extmap 1 for both + mSessionOff.AddAudioRtpExtension("foo"); // Default mapping of 2 + mSessionOff.AddAudioRtpExtension("bar"); // Default mapping of 3 + mSessionAns.AddAudioRtpExtension("bar"); // Default mapping of 2 + std::string offer = CreateOffer(); + SetLocalOffer(offer, CHECK_SUCCESS); + SetRemoteOffer(offer, CHECK_SUCCESS); + std::string answer = CreateAnswer(); + SetLocalAnswer(answer, CHECK_SUCCESS); + SetRemoteAnswer(answer, CHECK_SUCCESS); + + SipccSdpParser parser; + UniquePtr parsedOffer = parser.Parse(offer); + ASSERT_EQ(1U, parsedOffer->GetMediaSectionCount()); + + auto& offerMediaAttrs = parsedOffer->GetMediaSection(0).GetAttributeList(); + ASSERT_TRUE(offerMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute)); + auto& offerExtmap = offerMediaAttrs.GetExtmap().mExtmaps; + ASSERT_EQ(3U, offerExtmap.size()); + ASSERT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level", + offerExtmap[0].extensionname); + ASSERT_EQ(1U, offerExtmap[0].entry); + ASSERT_EQ("foo", offerExtmap[1].extensionname); + ASSERT_EQ(2U, offerExtmap[1].entry); + ASSERT_EQ("bar", offerExtmap[2].extensionname); + ASSERT_EQ(3U, offerExtmap[2].entry); + + UniquePtr parsedAnswer = parser.Parse(answer); + ASSERT_EQ(1U, parsedAnswer->GetMediaSectionCount()); + + auto& answerMediaAttrs = parsedAnswer->GetMediaSection(0).GetAttributeList(); + ASSERT_TRUE(answerMediaAttrs.HasAttribute(SdpAttribute::kExtmapAttribute)); + auto& answerExtmap = answerMediaAttrs.GetExtmap().mExtmaps; + ASSERT_EQ(2U, answerExtmap.size()); + ASSERT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level", + answerExtmap[0].extensionname); + ASSERT_EQ(1U, answerExtmap[0].entry); + // We ensure that the entry for "bar" matches what was in the offer + ASSERT_EQ("bar", answerExtmap[1].extensionname); + ASSERT_EQ(3U, answerExtmap[1].entry); +} + +} // namespace mozilla + +int +main(int argc, char** argv) +{ + NSS_NoDB_Init(nullptr); + NSS_SetDomesticPolicy(); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 18e8f88a545df6d2cedaec29fdee9c6b78739a14 Mon Sep 17 00:00:00 2001 From: "Byron Campen [:bwc]" Date: Wed, 19 Nov 2014 16:18:10 -0800 Subject: [PATCH 17/82] Bug 1091242 - Part 3: Mochitest work. See https://github.com/unicorn-wg/gecko-dev/tree/multistream_rebase for more history. r=jib --- .../mochitest/identity/test_fingerprints.html | 12 +-- dom/media/tests/mochitest/mochitest.ini | 7 ++ dom/media/tests/mochitest/pc.js | 87 ++++++++++----- dom/media/tests/mochitest/templates.js | 76 ++++++++++--- ...t_peerConnection_addSecondAudioStream.html | 102 ++++++++++++++++++ ...rConnection_offerRequiresReceiveAudio.html | 2 +- ...rConnection_offerRequiresReceiveVideo.html | 1 + ...ection_offerRequiresReceiveVideoAudio.html | 6 +- .../test_peerConnection_twoAudioStreams.html | 30 ++++++ ...t_peerConnection_twoAudioVideoStreams.html | 33 ++++++ ...nnection_twoAudioVideoStreamsCombined.html | 33 ++++++ .../test_peerConnection_twoVideoStreams.html | 30 ++++++ 12 files changed, 372 insertions(+), 47 deletions(-) create mode 100644 dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html create mode 100644 dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html create mode 100644 dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html create mode 100644 dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html create mode 100644 dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html diff --git a/dom/media/tests/mochitest/identity/test_fingerprints.html b/dom/media/tests/mochitest/identity/test_fingerprints.html index 05db74fc6d1..84ddbd8a4c6 100644 --- a/dom/media/tests/mochitest/identity/test_fingerprints.html +++ b/dom/media/tests/mochitest/identity/test_fingerprints.html @@ -53,7 +53,7 @@ var fingerprintRegex = /^a=fingerprint:(\S+) (\S+)/m; var identityRegex = /^a=identity:(\S+)/m; function fingerprintSdp(fingerprints) { - return fingerprints.map(fp => "a=fInGeRpRiNt=" + fp.algorithm + + return fingerprints.map(fp => "a=fInGeRpRiNt:" + fp.algorithm + " " + fp.digest + "\n").join(""); } @@ -78,20 +78,20 @@ function testMultipleFingerprints() { pcDouble.createOffer(function(offer) { ok(offer, "Got offer"); - var m = offer.sdp.match(fingerprintRegex); - if (!m) { + var fp = offer.sdp.match(fingerprintRegex); + if (!fp) { finished(false, "No fingerprint in offer SDP"); return; } - var fingerprints = makeFingerprints(m[1], m[2]); + var fingerprints = makeFingerprints(fp[1], fp[2]); getIdentityAssertion(fingerprints, function(assertion) { ok(assertion, "Should have assertion"); - var sdp = offer.sdp.slice(0, m.index) + + var sdp = offer.sdp.slice(0, fp.index) + "a=identity:" + assertion + "\n" + fingerprintSdp(fingerprints.slice(1)) + - offer.sdp.slice(m.index); + offer.sdp.slice(fp.index); var desc = new mozRTCSessionDescription({ type: "offer", sdp: sdp }); pcStrict.setRemoteDescription(desc, function() { diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index d86ca64b860..c036c9a9353 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -128,5 +128,12 @@ skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabl [test_peerConnection_toJSON.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867) +# multistream is not ready quite yet (bug 1056650) +# [test_peerConnection_twoAudioStreams.html] +# [test_peerConnection_twoAudioVideoStreams.html] +# [test_peerConnection_twoAudioVideoStreamsCombined.html] +# [test_peerConnection_twoVideoStreams.html] +# [test_peerConnection_addSecondAudioStream.html] + # Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases [test_zmedia_cleanup.html] diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js index 44effabf6cf..9a6cba86179 100644 --- a/dom/media/tests/mochitest/pc.js +++ b/dom/media/tests/mochitest/pc.js @@ -1755,11 +1755,13 @@ PeerConnectionWrapper.prototype = { * * @param {function} onSuccess * Callback to execute if all media has been requested successfully + * @param {array} constraintsList + * Array of constraints for GUM calls */ - getAllUserMedia : function PCW_GetAllUserMedia(onSuccess) { + getAllUserMedia : function PCW_GetAllUserMedia(constraintsList, onSuccess) { var self = this; - function _getAllUserMedia(constraintsList, index) { + function _getAllUserMedia(index) { if (index < constraintsList.length) { var constraints = constraintsList[index]; @@ -1776,20 +1778,20 @@ PeerConnectionWrapper.prototype = { self.attachMedia(stream, type, 'local'); - _getAllUserMedia(constraintsList, index + 1); + _getAllUserMedia(index + 1); }, generateErrorCallback()); } else { onSuccess(); } } - if (this.constraints.length === 0) { + if (constraintsList.length === 0) { info("Skipping GUM: no UserMedia requested"); onSuccess(); } else { - info("Get " + this.constraints.length + " local streams"); - _getAllUserMedia(this.constraints, 0); + info("Get " + constraintsList.length + " local streams"); + _getAllUserMedia(0); } }, @@ -2174,13 +2176,13 @@ PeerConnectionWrapper.prototype = { if ((!constraints) || (constraints.length === 0)) { return 0; } - var audioTracks = 0; + var numAudioTracks = 0; for (var i = 0; i < constraints.length; i++) { if (constraints[i].audio) { - audioTracks++; + numAudioTracks++; } } - return audioTracks; + return numAudioTracks; }, /** @@ -2223,13 +2225,13 @@ PeerConnectionWrapper.prototype = { if ((!constraints) || (constraints.length === 0)) { return 0; } - var videoTracks = 0; + var numVideoTracks = 0; for (var i = 0; i < constraints.length; i++) { if (constraints[i].video) { - videoTracks++; + numVideoTracks++; } } - return videoTracks; + return numVideoTracks; }, /** @@ -2272,11 +2274,11 @@ PeerConnectionWrapper.prototype = { if (!streams || (streams.length === 0)) { return 0; } - var audioTracks = 0; + var numAudioTracks = 0; streams.forEach(function(st) { - audioTracks += st.getAudioTracks().length; + numAudioTracks += st.getAudioTracks().length; }); - return audioTracks; + return numAudioTracks; }, /* @@ -2290,11 +2292,11 @@ PeerConnectionWrapper.prototype = { if (!streams || (streams.length === 0)) { return 0; } - var videoTracks = 0; + var numVideoTracks = 0; streams.forEach(function(st) { - videoTracks += st.getVideoTracks().length; + numVideoTracks += st.getVideoTracks().length; }); - return videoTracks; + return numVideoTracks; }, /** @@ -2367,10 +2369,9 @@ PeerConnectionWrapper.prototype = { }, verifySdp : function PCW_verifySdp(desc, expectedType, offerConstraintsList, - answerConstraintsList, offerOptions, trickleIceCallback) { + offerOptions, trickleIceCallback) { info("Examining this SessionDescription: " + JSON.stringify(desc)); info("offerConstraintsList: " + JSON.stringify(offerConstraintsList)); - info("answerConstraintsList: " + JSON.stringify(answerConstraintsList)); info("offerOptions: " + JSON.stringify(offerOptions)); ok(desc, "SessionDescription is not null"); is(desc.type, expectedType, "SessionDescription type is " + expectedType); @@ -2390,8 +2391,7 @@ PeerConnectionWrapper.prototype = { //TODO: how can we check for absence/presence of m=application? var audioTracks = - Math.max(this.countAudioTracksInMediaConstraint(offerConstraintsList), - this.countAudioTracksInMediaConstraint(answerConstraintsList)) || + this.countAudioTracksInMediaConstraint(offerConstraintsList) || this.audioInOfferOptions(offerOptions); info("expected audio tracks: " + audioTracks); @@ -2407,8 +2407,7 @@ PeerConnectionWrapper.prototype = { } var videoTracks = - Math.max(this.countVideoTracksInMediaConstraint(offerConstraintsList), - this.countVideoTracksInMediaConstraint(answerConstraintsList)) || + this.countVideoTracksInMediaConstraint(offerConstraintsList) || this.videoInOfferOptions(offerOptions); info("expected video tracks: " + videoTracks); @@ -2636,6 +2635,46 @@ PeerConnectionWrapper.prototype = { } }, + /** + * Compares amount of established ICE connection according to ICE candidate + * pairs in the stats reporting with the expected amount of connection based + * on the constraints. + * + * @param {object} stats + * The stats to check for ICE candidate pairs + * @param {object} counters + * The counters for media and data tracks based on constraints + * @param {object} answer + * The SDP answer to check for SDP bundle support + */ + checkStatsIceConnections : function PCW_checkStatsIceConnections(stats, + offerConstraintsList, offerOptions, numDataTracks, answer) { + var numIceConnections = 0; + Object.keys(stats).forEach(function(key) { + if ((stats[key].type === "candidatepair") && stats[key].selected) { + numIceConnections += 1; + } + }); + info("ICE connections according to stats: " + numIceConnections); + if (answer.sdp.contains('a=group:BUNDLE')) { + is(numIceConnections, 1, "stats reports exactly 1 ICE connection"); + } else { + // This code assumes that no media sections have been rejected due to + // codec mismatch or other unrecoverable negotiation failures. + var numAudioTracks = + this.countAudioTracksInMediaConstraint(offerConstraintsList) || + this.audioInOfferOptions(offerOptions); + + var numVideoTracks = + this.countVideoTracksInMediaConstraint(offerConstraintsList) || + this.videoInOfferOptions(offerOptions); + + var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks; + info("expected audio + video + data tracks: " + numAudioVideoDataTracks); + is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks"); + } + }, + /** * Property-matching function for finding a certain stat in passed-in stats * diff --git a/dom/media/tests/mochitest/templates.js b/dom/media/tests/mochitest/templates.js index daa3a74fdd6..409e98f7003 100644 --- a/dom/media/tests/mochitest/templates.js +++ b/dom/media/tests/mochitest/templates.js @@ -111,7 +111,7 @@ var commandsPeerConnection = [ [ 'PC_LOCAL_GUM', function (test) { - test.pcLocal.getAllUserMedia(function () { + test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () { test.next(); }); } @@ -119,7 +119,7 @@ var commandsPeerConnection = [ [ 'PC_REMOTE_GUM', function (test) { - test.pcRemote.getAllUserMedia(function () { + test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () { test.next(); }); } @@ -232,7 +232,7 @@ var commandsPeerConnection = [ 'PC_LOCAL_SANE_LOCAL_SDP', function (test) { test.pcLocal.verifySdp(test._local_offer, "offer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function(trickle) { test.pcLocal.localRequiresTrickleIce = trickle; }); @@ -243,7 +243,7 @@ var commandsPeerConnection = [ 'PC_REMOTE_SANE_REMOTE_SDP', function (test) { test.pcRemote.verifySdp(test._local_offer, "offer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function (trickle) { test.pcRemote.remoteRequiresTrickleIce = trickle; }); @@ -356,7 +356,7 @@ var commandsPeerConnection = [ 'PC_REMOTE_SANE_LOCAL_SDP', function (test) { test.pcRemote.verifySdp(test._remote_answer, "answer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function (trickle) { test.pcRemote.localRequiresTrickleIce = trickle; }); @@ -367,7 +367,7 @@ var commandsPeerConnection = [ 'PC_LOCAL_SANE_REMOTE_SDP', function (test) { test.pcLocal.verifySdp(test._remote_answer, "answer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function (trickle) { test.pcLocal.remoteRequiresTrickleIce = trickle; }); @@ -522,6 +522,32 @@ var commandsPeerConnection = [ }); } ], + [ + 'PC_LOCAL_CHECK_ICE_CONNECTIONS', + function (test) { + test.pcLocal.getStats(null, function(stats) { + test.pcLocal.checkStatsIceConnections(stats, + test._offer_constraints, + test._offer_options, + 0, + test.originalAnswer); + test.next(); + }); + } + ], + [ + 'PC_REMOTE_CHECK_ICE_CONNECTIONS', + function (test) { + test.pcRemote.getStats(null, function(stats) { + test.pcRemote.checkStatsIceConnections(stats, + test._offer_constraints, + test._offer_options, + 0, + test.originalAnswer); + test.next(); + }); + } + ], [ 'PC_LOCAL_CHECK_GETSTATS_AUDIOTRACK_OUTBOUND', function (test) { @@ -728,7 +754,7 @@ var commandsDataChannel = [ [ 'PC_LOCAL_GUM', function (test) { - test.pcLocal.getAllUserMedia(function () { + test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () { test.next(); }); } @@ -752,7 +778,7 @@ var commandsDataChannel = [ [ 'PC_REMOTE_GUM', function (test) { - test.pcRemote.getAllUserMedia(function () { + test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () { test.next(); }); } @@ -867,7 +893,7 @@ var commandsDataChannel = [ 'PC_LOCAL_SANE_LOCAL_SDP', function (test) { test.pcLocal.verifySdp(test._local_offer, "offer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function(trickle) { test.pcLocal.localRequiresTrickleIce = trickle; }); @@ -878,7 +904,7 @@ var commandsDataChannel = [ 'PC_REMOTE_SANE_REMOTE_SDP', function (test) { test.pcRemote.verifySdp(test._local_offer, "offer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function (trickle) { test.pcRemote.remoteRequiresTrickleIce = trickle; }); @@ -971,7 +997,7 @@ var commandsDataChannel = [ 'PC_REMOTE_SANE_LOCAL_SDP', function (test) { test.pcRemote.verifySdp(test._remote_answer, "answer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function (trickle) { test.pcRemote.localRequiresTrickleIce = trickle; }); @@ -982,7 +1008,7 @@ var commandsDataChannel = [ 'PC_LOCAL_SANE_REMOTE_SDP', function (test) { test.pcLocal.verifySdp(test._remote_answer, "answer", - test._offer_constraints, test._answer_constraints, test._offer_options, + test._offer_constraints, test._offer_options, function (trickle) { test.pcLocal.remoteRequiresTrickleIce = trickle; }); @@ -1129,6 +1155,32 @@ var commandsDataChannel = [ }); } ], + [ + 'PC_LOCAL_CHECK_ICE_CONNECTIONS', + function (test) { + test.pcLocal.getStats(null, function(stats) { + test.pcLocal.checkStatsIceConnections(stats, + test._offer_constraints, + test._offer_options, + 1, + test.originalAnswer); + test.next(); + }); + } + ], + [ + 'PC_REMOTE_CHECK_ICE_CONNECTIONS', + function (test) { + test.pcRemote.getStats(null, function(stats) { + test.pcRemote.checkStatsIceConnections(stats, + test._offer_constraints, + test._offer_options, + 1, + test.originalAnswer); + test.next(); + }); + } + ], [ 'SEND_MESSAGE', function (test) { diff --git a/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html new file mode 100644 index 00000000000..dea87914f05 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html @@ -0,0 +1,102 @@ + + + + + + + + + + + + +
+
+
+ + diff --git a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html index fe01f789cbe..9e53abbe81d 100644 --- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html +++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html @@ -18,7 +18,7 @@ runNetworkTest(function() { var test = new PeerConnectionTest(); - + test.setMediaConstraints([], [{audio: true}]); // TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223). // Watch out for case-difference when fixing: { offerToReceiveAudio: true } test.setOfferOptions({ mandatory: { OfferToReceiveAudio: true } }); diff --git a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html index c4095d59a2e..7d2c2c98ea1 100644 --- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html +++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html @@ -18,6 +18,7 @@ runNetworkTest(function() { var test = new PeerConnectionTest(); + test.setMediaConstraints([], [{video: true}]); // TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223). // Watch out for case-difference when fixing: { offerToReceiveVideo: true } test.setOfferOptions({ optional: [{ OfferToReceiveVideo: true }] }); diff --git a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html index 65880476e87..25c0ec428a0 100644 --- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html +++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html @@ -18,10 +18,8 @@ runNetworkTest(function() { var test = new PeerConnectionTest(); - test.setOfferOptions({ - offerToReceiveVideo: true, - offerToReceiveAudio: true - }); + test.setMediaConstraints([], [{audio: true, video: true}]); + test.setOfferOptions({ offerToReceiveVideo: true, offerToReceiveAudio: true }); test.run(); }); diff --git a/dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html b/dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html new file mode 100644 index 00000000000..e22ffc90d15 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + +
+
+
+ + diff --git a/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html new file mode 100644 index 00000000000..396e489dfa0 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + +
+
+
+ + diff --git a/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html new file mode 100644 index 00000000000..2377faf591a --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + +
+
+
+ + diff --git a/dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html b/dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html new file mode 100644 index 00000000000..e87952d1a48 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + +
+
+
+ + From 421b4ef146c97a9e681e63de0a0f4cbc13fb01f8 Mon Sep 17 00:00:00 2001 From: "Byron Campen [:bwc]" Date: Fri, 14 Nov 2014 17:36:59 -0800 Subject: [PATCH 18/82] Bug 1091242 - Part 4: Remove most of sipcc, and move just the sdp stuff into a new location. r=ehugg --- .../src/callcontrol/CC_CallTypes.cpp | 94 - .../src/callcontrol/CallControlManager.cpp | 20 - .../callcontrol/CallControlManagerImpl.cpp | 537 - .../src/callcontrol/CallControlManagerImpl.h | 122 - .../signaling/src/callcontrol/ECC_Types.cpp | 151 - .../src/callcontrol/PhoneDetailsImpl.cpp | 76 - .../src/callcontrol/PhoneDetailsImpl.h | 48 - .../src/callcontrol/debug-psipcc-types.cpp | 479 - .../src/{sipcc/core/sdp => sdp/sipcc}/ccsdp.c | 0 .../src/{sipcc/include => sdp/sipcc}/ccsdp.h | 0 .../include => sdp/sipcc}/ccsdp_rtcp_fb.h | 0 .../android => sdp/sipcc}/cpr_android_types.h | 0 .../darwin => sdp/sipcc}/cpr_darwin_types.h | 0 .../cpr/linux => sdp/sipcc}/cpr_linux_types.h | 0 .../cpr/common => sdp/sipcc}/cpr_string.c | 0 .../cpr/include => sdp/sipcc}/cpr_string.h | 0 .../cpr/include => sdp/sipcc}/cpr_strings.h | 0 .../cpr/include => sdp/sipcc}/cpr_types.h | 0 .../cpr/win32 => sdp/sipcc}/cpr_win_types.h | 0 .../src/{sipcc/core/sdp => sdp/sipcc}/sdp.h | 0 .../core/sdp => sdp/sipcc}/sdp_access.c | 0 .../{sipcc/core/sdp => sdp/sipcc}/sdp_attr.c | 0 .../core/sdp => sdp/sipcc}/sdp_attr_access.c | 0 .../core/sdp => sdp/sipcc}/sdp_base64.c | 0 .../core/sdp => sdp/sipcc}/sdp_base64.h | 0 .../core/sdp => sdp/sipcc}/sdp_config.c | 0 .../{sipcc/core/sdp => sdp/sipcc}/sdp_main.c | 0 .../core/sdp => sdp/sipcc}/sdp_os_defs.h | 0 .../core/sdp => sdp/sipcc}/sdp_private.h | 0 .../sdp => sdp/sipcc}/sdp_services_unix.c | 0 .../sdp => sdp/sipcc}/sdp_services_win32.c | 0 .../{sipcc/core/sdp => sdp/sipcc}/sdp_token.c | 0 .../{sipcc/core/sdp => sdp/sipcc}/sdp_utils.c | 0 .../src/sipcc/core/ccapp/CCProvider.h | 149 - .../src/sipcc/core/ccapp/call_logger.c | 304 - .../src/sipcc/core/ccapp/call_logger.h | 20 - .../src/sipcc/core/ccapp/capability_set.c | 281 - .../src/sipcc/core/ccapp/capability_set.h | 33 - .../signaling/src/sipcc/core/ccapp/cc_blf.c | 50 - .../src/sipcc/core/ccapp/cc_call_feature.c | 531 - .../src/sipcc/core/ccapp/cc_config.c | 154 - .../src/sipcc/core/ccapp/cc_device_feature.c | 62 - .../src/sipcc/core/ccapp/cc_device_manager.c | 593 - .../src/sipcc/core/ccapp/cc_device_manager.h | 48 - .../signaling/src/sipcc/core/ccapp/cc_info.c | 43 - .../src/sipcc/core/ccapp/cc_service.c | 229 - .../src/sipcc/core/ccapp/ccapi_call.c | 344 - .../src/sipcc/core/ccapp/ccapi_call_info.c | 732 - .../src/sipcc/core/ccapp/ccapi_config.c | 108 - .../src/sipcc/core/ccapp/ccapi_device.c | 285 - .../src/sipcc/core/ccapp/ccapi_device_info.c | 469 - .../src/sipcc/core/ccapp/ccapi_feature_info.c | 154 - .../src/sipcc/core/ccapp/ccapi_line.c | 81 - .../src/sipcc/core/ccapp/ccapi_line_info.c | 425 - .../src/sipcc/core/ccapp/ccapi_service.c | 166 - .../src/sipcc/core/ccapp/ccapi_snapshot.c | 706 - .../src/sipcc/core/ccapp/ccapi_snapshot.h | 115 - .../src/sipcc/core/ccapp/ccapp_task.c | 149 - .../src/sipcc/core/ccapp/ccapp_task.h | 24 - .../src/sipcc/core/ccapp/ccprovider.c | 2253 --- .../src/sipcc/core/ccapp/conf_roster.c | 401 - .../src/sipcc/core/ccapp/conf_roster.h | 49 - .../src/sipcc/core/ccapp/sessionHash.c | 305 - .../src/sipcc/core/ccapp/sessionHash.h | 28 - .../src/sipcc/core/common/cfgfile_utils.c | 418 - .../src/sipcc/core/common/cfgfile_utils.h | 96 - .../src/sipcc/core/common/config_api.c | 494 - .../src/sipcc/core/common/config_parser.c | 636 - .../src/sipcc/core/common/config_parser.h | 173 - .../signaling/src/sipcc/core/common/init.c | 461 - .../signaling/src/sipcc/core/common/logger.c | 87 - .../signaling/src/sipcc/core/common/logger.h | 17 - .../signaling/src/sipcc/core/common/logmsg.h | 42 - .../signaling/src/sipcc/core/common/misc.c | 389 - .../signaling/src/sipcc/core/common/plat.c | 89 - .../src/sipcc/core/common/platform_api.c | 396 - .../sipcc/core/common/prot_cfgmgr_private.h | 429 - .../src/sipcc/core/common/prot_configmgr.c | 975 -- .../src/sipcc/core/common/prot_configmgr.h | 300 - .../src/sipcc/core/common/resource_manager.c | 300 - .../src/sipcc/core/common/resource_manager.h | 23 - .../src/sipcc/core/common/sip_socket_api.c | 100 - .../sipcc/core/common/subscription_handler.c | 342 - .../sipcc/core/common/subscription_handler.h | 23 - .../src/sipcc/core/common/text_strings.c | 361 - .../src/sipcc/core/common/text_strings.h | 302 - .../signaling/src/sipcc/core/common/ui.c | 1547 -- .../signaling/src/sipcc/core/gsm/ccapi.c | 1630 -- .../src/sipcc/core/gsm/ccapi_strings.c | 60 - .../signaling/src/sipcc/core/gsm/dcsm.c | 723 - .../webrtc/signaling/src/sipcc/core/gsm/fim.c | 759 - .../webrtc/signaling/src/sipcc/core/gsm/fsm.c | 1383 -- .../signaling/src/sipcc/core/gsm/fsmb2bcnf.c | 1284 -- .../signaling/src/sipcc/core/gsm/fsmcac.c | 707 - .../signaling/src/sipcc/core/gsm/fsmcnf.c | 1749 --- .../signaling/src/sipcc/core/gsm/fsmdef.c | 8672 ----------- .../signaling/src/sipcc/core/gsm/fsmxfr.c | 3040 ---- .../webrtc/signaling/src/sipcc/core/gsm/gsm.c | 552 - .../signaling/src/sipcc/core/gsm/gsm_sdp.c | 7609 ---------- .../src/sipcc/core/gsm/gsm_sdp_crypto.c | 1914 --- .../signaling/src/sipcc/core/gsm/h/fim.h | 68 - .../signaling/src/sipcc/core/gsm/h/fsm.h | 785 - .../signaling/src/sipcc/core/gsm/h/gsm.h | 59 - .../signaling/src/sipcc/core/gsm/h/gsm_sdp.h | 131 - .../signaling/src/sipcc/core/gsm/h/lsm.h | 181 - .../src/sipcc/core/gsm/h/lsm_private.h | 58 - .../signaling/src/sipcc/core/gsm/h/sm.h | 44 - .../webrtc/signaling/src/sipcc/core/gsm/lsm.c | 6553 -------- .../src/sipcc/core/gsm/media_cap_tbl.c | 158 - .../webrtc/signaling/src/sipcc/core/gsm/sm.c | 78 - .../signaling/src/sipcc/core/gsm/subapi.c | 280 - .../src/sipcc/core/includes/ccSession.h | 207 - .../signaling/src/sipcc/core/includes/ccapi.h | 1533 -- .../src/sipcc/core/includes/check_sync.h | 46 - .../signaling/src/sipcc/core/includes/ci.h | 34 - .../src/sipcc/core/includes/config.h | 194 - .../src/sipcc/core/includes/configapp.h | 13 - .../src/sipcc/core/includes/configmgr.h | 62 - .../signaling/src/sipcc/core/includes/debug.h | 107 - .../src/sipcc/core/includes/dialplan.h | 111 - .../src/sipcc/core/includes/dialplanint.h | 93 - .../src/sipcc/core/includes/digcalc.h | 42 - .../src/sipcc/core/includes/dns_utils.h | 77 - .../signaling/src/sipcc/core/includes/dtmf.h | 27 - .../src/sipcc/core/includes/embedded.h | 24 - .../sipcc/core/includes/intelpentiumtypes.h | 19 - .../sipcc/core/includes/kpml_common_util.h | 49 - .../src/sipcc/core/includes/kpmlmap.h | 177 - .../signaling/src/sipcc/core/includes/md5.h | 57 - .../src/sipcc/core/includes/memory.h | 35 - .../src/sipcc/core/includes/misc_apps_task.h | 14 - .../src/sipcc/core/includes/misc_util.h | 9 - .../src/sipcc/core/includes/phntask.h | 309 - .../signaling/src/sipcc/core/includes/phone.h | 504 - .../src/sipcc/core/includes/phone_debug.h | 382 - .../core/includes/phone_platform_constants.h | 198 - .../src/sipcc/core/includes/phone_types.h | 32 - .../src/sipcc/core/includes/platform_api.h | 52 - .../core/includes/pres_sub_not_handler.h | 20 - .../src/sipcc/core/includes/publish_int.h | 70 - .../src/sipcc/core/includes/rcc_int_types.h | 72 - .../src/sipcc/core/includes/regexp.h | 83 - .../src/sipcc/core/includes/ringlist.h | 22 - .../src/sipcc/core/includes/rtp_defs.h | 123 - .../src/sipcc/core/includes/scSession.h | 24 - .../src/sipcc/core/includes/session.h | 168 - .../sipcc/core/includes/sessionConstants.h | 382 - .../src/sipcc/core/includes/sessionTypes.h | 437 - .../src/sipcc/core/includes/sessuri.h | 171 - .../sipcc/core/includes/singly_link_list.h | 117 - .../src/sipcc/core/includes/sip_socket_api.h | 80 - .../signaling/src/sipcc/core/includes/sntp.h | 92 - .../src/sipcc/core/includes/string_lib.h | 56 - .../src/sipcc/core/includes/subapi.h | 43 - .../signaling/src/sipcc/core/includes/task.h | 28 - .../signaling/src/sipcc/core/includes/time2.h | 192 - .../signaling/src/sipcc/core/includes/timer.h | 49 - .../src/sipcc/core/includes/tnpphone.h | 65 - .../signaling/src/sipcc/core/includes/uart.h | 119 - .../signaling/src/sipcc/core/includes/uiapi.h | 146 - .../src/sipcc/core/includes/upgrade.h | 37 - .../src/sipcc/core/includes/util_ios_queue.h | 59 - .../src/sipcc/core/includes/util_parse.h | 12 - .../src/sipcc/core/includes/util_string.h | 28 - .../signaling/src/sipcc/core/includes/www.h | 25 - .../src/sipcc/core/includes/xml_defs.h | 51 - .../src/sipcc/core/sipstack/ccsip_callinfo.c | 677 - .../src/sipcc/core/sipstack/ccsip_cc.c | 305 - .../sipcc/core/sipstack/ccsip_common_util.c | 260 - .../src/sipcc/core/sipstack/ccsip_core.c | 12295 ---------------- .../src/sipcc/core/sipstack/ccsip_debug.c | 391 - .../src/sipcc/core/sipstack/ccsip_info.c | 898 -- .../src/sipcc/core/sipstack/ccsip_messaging.c | 7640 ---------- .../src/sipcc/core/sipstack/ccsip_platform.c | 122 - .../sipcc/core/sipstack/ccsip_platform_tcp.c | 1220 -- .../core/sipstack/ccsip_platform_timers.c | 989 -- .../sipcc/core/sipstack/ccsip_platform_tls.c | 176 - .../sipcc/core/sipstack/ccsip_platform_udp.c | 455 - .../src/sipcc/core/sipstack/ccsip_pmh.c | 5765 -------- .../src/sipcc/core/sipstack/ccsip_publish.c | 896 -- .../src/sipcc/core/sipstack/ccsip_register.c | 3079 ---- .../src/sipcc/core/sipstack/ccsip_reldev.c | 284 - .../src/sipcc/core/sipstack/ccsip_sdp.c | 358 - .../src/sipcc/core/sipstack/ccsip_spi_utils.c | 134 - .../sipcc/core/sipstack/ccsip_subsmanager.c | 5290 ------- .../src/sipcc/core/sipstack/ccsip_task.c | 2994 ---- .../sipcc/core/sipstack/h/ccsip_callinfo.h | 86 - .../src/sipcc/core/sipstack/h/ccsip_cc.h | 41 - .../sipcc/core/sipstack/h/ccsip_common_cb.h | 56 - .../src/sipcc/core/sipstack/h/ccsip_core.h | 866 -- .../sipcc/core/sipstack/h/ccsip_credentials.h | 23 - .../src/sipcc/core/sipstack/h/ccsip_macros.h | 24 - .../sipcc/core/sipstack/h/ccsip_messaging.h | 290 - .../sipcc/core/sipstack/h/ccsip_platform.h | 65 - .../core/sipstack/h/ccsip_platform_tcp.h | 99 - .../core/sipstack/h/ccsip_platform_timers.h | 164 - .../core/sipstack/h/ccsip_platform_tls.h | 12 - .../core/sipstack/h/ccsip_platform_udp.h | 46 - .../src/sipcc/core/sipstack/h/ccsip_pmh.h | 827 -- .../sipcc/core/sipstack/h/ccsip_protocol.h | 645 - .../src/sipcc/core/sipstack/h/ccsip_publish.h | 44 - .../sipcc/core/sipstack/h/ccsip_register.h | 157 - .../src/sipcc/core/sipstack/h/ccsip_reldev.h | 63 - .../src/sipcc/core/sipstack/h/ccsip_sdp.h | 159 - .../src/sipcc/core/sipstack/h/ccsip_sim.h | 14 - .../sipcc/core/sipstack/h/ccsip_spi_utils.h | 22 - .../sipcc/core/sipstack/h/ccsip_subsmanager.h | 433 - .../src/sipcc/core/sipstack/h/ccsip_task.h | 89 - .../src/sipcc/core/sipstack/h/httpish.h | 302 - .../sipcc/core/sipstack/h/httpish_protocol.h | 32 - .../src/sipcc/core/sipstack/h/pmhdefs.h | 12 - .../src/sipcc/core/sipstack/h/pmhutils.h | 163 - .../src/sipcc/core/sipstack/h/regmgrapi.h | 17 - .../sipcc/core/sipstack/h/sip_ccm_transport.h | 20 - .../sipcc/core/sipstack/h/sip_common_regmgr.h | 157 - .../core/sipstack/h/sip_common_transport.h | 223 - .../core/sipstack/h/sip_csps_transport.h | 47 - .../core/sipstack/h/sip_interface_regmgr.h | 64 - .../sipcc/core/sipstack/h/sip_platform_task.h | 20 - .../src/sipcc/core/sipstack/httpish.c | 1642 --- .../src/sipcc/core/sipstack/pmhutils.c | 308 - .../sipcc/core/sipstack/sip_common_regmgr.c | 3471 ----- .../core/sipstack/sip_common_transport.c | 2184 --- .../sipcc/core/sipstack/sip_csps_transport.c | 206 - .../core/sipstack/sip_interface_regmgr.c | 313 - .../sipcc/core/sipstack/sip_platform_task.c | 278 - .../core/sipstack/sip_platform_win32_task.c | 340 - .../src/sipcc/core/src-common/configapp.c | 145 - .../src/sipcc/core/src-common/dialplan.c | 1207 -- .../src/sipcc/core/src-common/dialplanint.c | 1349 -- .../src/sipcc/core/src-common/digcalc.c | 144 - .../sipcc/core/src-common/kpml_common_util.c | 388 - .../src/sipcc/core/src-common/kpmlmap.c | 1931 --- .../signaling/src/sipcc/core/src-common/md5.c | 438 - .../sipcc/core/src-common/misc_apps_task.c | 69 - .../core/src-common/pres_sub_not_handler.c | 1393 -- .../src/sipcc/core/src-common/publish_int.c | 174 - .../sipcc/core/src-common/singly_link_list.c | 306 - .../src/sipcc/core/src-common/sll_lite.c | 258 - .../src/sipcc/core/src-common/string_lib.c | 401 - .../sipcc/core/src-common/util_ios_queue.c | 217 - .../src/sipcc/core/src-common/util_parse.c | 86 - .../src/sipcc/core/src-common/util_string.c | 366 - .../src/sipcc/cpr/android/cpr_android_align.h | 82 - .../sipcc/cpr/android/cpr_android_assert.h | 85 - .../src/sipcc/cpr/android/cpr_android_errno.c | 184 - .../src/sipcc/cpr/android/cpr_android_errno.h | 19 - .../src/sipcc/cpr/android/cpr_android_in.h | 11 - .../src/sipcc/cpr/android/cpr_android_init.c | 196 - .../sipcc/cpr/android/cpr_android_private.h | 13 - .../src/sipcc/cpr/android/cpr_android_rand.h | 15 - .../sipcc/cpr/android/cpr_android_socket.c | 992 -- .../sipcc/cpr/android/cpr_android_socket.h | 348 - .../src/sipcc/cpr/android/cpr_android_stdio.c | 148 - .../src/sipcc/cpr/android/cpr_android_stdio.h | 11 - .../sipcc/cpr/android/cpr_android_string.c | 173 - .../sipcc/cpr/android/cpr_android_string.h | 30 - .../sipcc/cpr/android/cpr_android_strings.h | 10 - .../sipcc/cpr/android/cpr_android_threads.c | 218 - .../src/sipcc/cpr/android/cpr_android_time.h | 12 - .../sipcc/cpr/android/cpr_android_timers.h | 55 - .../android/cpr_android_timers_using_select.c | 1235 -- .../src/sipcc/cpr/android/cpr_android_tst.c | 61 - .../src/sipcc/cpr/android/cpr_android_tst.h | 13 - .../signaling/src/sipcc/cpr/common/cpr_ipc.c | 246 - .../src/sipcc/cpr/darwin/cpr_darwin_align.h | 82 - .../src/sipcc/cpr/darwin/cpr_darwin_assert.h | 86 - .../src/sipcc/cpr/darwin/cpr_darwin_errno.c | 146 - .../src/sipcc/cpr/darwin/cpr_darwin_errno.h | 19 - .../src/sipcc/cpr/darwin/cpr_darwin_in.h | 11 - .../src/sipcc/cpr/darwin/cpr_darwin_init.c | 193 - .../src/sipcc/cpr/darwin/cpr_darwin_private.h | 13 - .../src/sipcc/cpr/darwin/cpr_darwin_rand.h | 15 - .../src/sipcc/cpr/darwin/cpr_darwin_socket.c | 1017 -- .../src/sipcc/cpr/darwin/cpr_darwin_socket.h | 310 - .../src/sipcc/cpr/darwin/cpr_darwin_stdio.c | 154 - .../src/sipcc/cpr/darwin/cpr_darwin_stdio.h | 11 - .../src/sipcc/cpr/darwin/cpr_darwin_string.c | 174 - .../src/sipcc/cpr/darwin/cpr_darwin_string.h | 49 - .../src/sipcc/cpr/darwin/cpr_darwin_strings.h | 10 - .../src/sipcc/cpr/darwin/cpr_darwin_threads.c | 214 - .../src/sipcc/cpr/darwin/cpr_darwin_time.h | 12 - .../src/sipcc/cpr/darwin/cpr_darwin_timers.h | 55 - .../darwin/cpr_darwin_timers_using_select.c | 1240 -- .../src/sipcc/cpr/darwin/cpr_darwin_tst.h | 14 - .../signaling/src/sipcc/cpr/include/cpr.h | 58 - .../src/sipcc/cpr/include/cpr_assert.h | 39 - .../src/sipcc/cpr/include/cpr_debug.h | 24 - .../src/sipcc/cpr/include/cpr_errno.h | 181 - .../signaling/src/sipcc/cpr/include/cpr_in.h | 30 - .../signaling/src/sipcc/cpr/include/cpr_ipc.h | 68 - .../src/sipcc/cpr/include/cpr_locks.h | 63 - .../src/sipcc/cpr/include/cpr_memory.h | 16 - .../src/sipcc/cpr/include/cpr_rand.h | 20 - .../src/sipcc/cpr/include/cpr_socket.h | 725 - .../src/sipcc/cpr/include/cpr_stddef.h | 13 - .../src/sipcc/cpr/include/cpr_stdio.h | 70 - .../src/sipcc/cpr/include/cpr_stdlib.h | 25 - .../src/sipcc/cpr/include/cpr_threads.h | 132 - .../src/sipcc/cpr/include/cpr_time.h | 31 - .../src/sipcc/cpr/include/cpr_timers.h | 165 - .../src/sipcc/cpr/linux/cpr_linux_align.h | 82 - .../src/sipcc/cpr/linux/cpr_linux_assert.h | 85 - .../src/sipcc/cpr/linux/cpr_linux_errno.c | 184 - .../src/sipcc/cpr/linux/cpr_linux_errno.h | 19 - .../src/sipcc/cpr/linux/cpr_linux_in.h | 11 - .../src/sipcc/cpr/linux/cpr_linux_init.c | 199 - .../src/sipcc/cpr/linux/cpr_linux_private.h | 13 - .../src/sipcc/cpr/linux/cpr_linux_rand.h | 15 - .../src/sipcc/cpr/linux/cpr_linux_socket.c | 998 -- .../src/sipcc/cpr/linux/cpr_linux_socket.h | 348 - .../src/sipcc/cpr/linux/cpr_linux_stdio.c | 148 - .../src/sipcc/cpr/linux/cpr_linux_stdio.h | 11 - .../src/sipcc/cpr/linux/cpr_linux_string.c | 173 - .../src/sipcc/cpr/linux/cpr_linux_string.h | 30 - .../src/sipcc/cpr/linux/cpr_linux_strings.h | 10 - .../src/sipcc/cpr/linux/cpr_linux_threads.c | 218 - .../src/sipcc/cpr/linux/cpr_linux_time.h | 12 - .../src/sipcc/cpr/linux/cpr_linux_timers.h | 55 - .../cpr/linux/cpr_linux_timers_using_select.c | 1235 -- .../src/sipcc/cpr/linux/cpr_linux_tst.c | 61 - .../src/sipcc/cpr/linux/cpr_linux_tst.h | 13 - .../src/sipcc/cpr/win32/cpr_win_assert.h | 10 - .../src/sipcc/cpr/win32/cpr_win_debug.c | 11 - .../src/sipcc/cpr/win32/cpr_win_debug.h | 31 - .../src/sipcc/cpr/win32/cpr_win_defines.h | 76 - .../src/sipcc/cpr/win32/cpr_win_errno.c | 175 - .../src/sipcc/cpr/win32/cpr_win_errno.h | 28 - .../src/sipcc/cpr/win32/cpr_win_in.h | 29 - .../src/sipcc/cpr/win32/cpr_win_init.c | 80 - .../src/sipcc/cpr/win32/cpr_win_locks.c | 48 - .../src/sipcc/cpr/win32/cpr_win_locks.h | 24 - .../src/sipcc/cpr/win32/cpr_win_rand.c | 65 - .../src/sipcc/cpr/win32/cpr_win_rand.h | 15 - .../src/sipcc/cpr/win32/cpr_win_socket.c | 1086 -- .../src/sipcc/cpr/win32/cpr_win_socket.h | 71 - .../src/sipcc/cpr/win32/cpr_win_stdio.c | 80 - .../src/sipcc/cpr/win32/cpr_win_stdio.h | 15 - .../src/sipcc/cpr/win32/cpr_win_string.c | 71 - .../src/sipcc/cpr/win32/cpr_win_string.h | 21 - .../src/sipcc/cpr/win32/cpr_win_strings.h | 15 - .../src/sipcc/cpr/win32/cpr_win_threads.c | 296 - .../src/sipcc/cpr/win32/cpr_win_threads.cpp | 219 - .../src/sipcc/cpr/win32/cpr_win_time.h | 21 - .../src/sipcc/cpr/win32/cpr_win_timers.c | 612 - .../src/sipcc/cpr/win32/cpr_win_timers.h | 15 - .../signaling/src/sipcc/include/cc_blf.h | 44 - .../src/sipcc/include/cc_blf_listener.h | 20 - .../src/sipcc/include/cc_call_feature.h | 330 - .../src/sipcc/include/cc_call_listener.h | 201 - .../signaling/src/sipcc/include/cc_config.h | 287 - .../src/sipcc/include/cc_constants.h | 602 - .../signaling/src/sipcc/include/cc_debug.h | 42 - .../src/sipcc/include/cc_device_feature.h | 35 - .../src/sipcc/include/cc_device_listener.h | 76 - .../signaling/src/sipcc/include/cc_info.h | 39 - .../src/sipcc/include/cc_info_listener.h | 24 - .../signaling/src/sipcc/include/cc_service.h | 77 - .../src/sipcc/include/cc_service_listener.h | 125 - .../signaling/src/sipcc/include/cc_types.h | 22 - .../signaling/src/sipcc/include/ccapi_call.h | 236 - .../src/sipcc/include/ccapi_call_info.h | 298 - .../src/sipcc/include/ccapi_call_listener.h | 22 - .../src/sipcc/include/ccapi_calllog.h | 87 - .../src/sipcc/include/ccapi_conf_roster.h | 97 - .../src/sipcc/include/ccapi_device.h | 136 - .../src/sipcc/include/ccapi_device_info.h | 203 - .../src/sipcc/include/ccapi_device_listener.h | 36 - .../src/sipcc/include/ccapi_feature_info.h | 67 - .../signaling/src/sipcc/include/ccapi_line.h | 43 - .../src/sipcc/include/ccapi_line_info.h | 165 - .../src/sipcc/include/ccapi_line_listener.h | 23 - .../src/sipcc/include/ccapi_service.h | 85 - .../signaling/src/sipcc/include/ccapi_types.h | 160 - .../signaling/src/sipcc/include/config_api.h | 120 - .../signaling/src/sipcc/include/dns_util.h | 82 - .../src/sipcc/include/fsmdef_states.h | 44 - .../src/sipcc/include/peer_connection_types.h | 22 - .../signaling/src/sipcc/include/plat_api.h | 720 - .../signaling/src/sipcc/include/reset_api.h | 51 - .../signaling/src/sipcc/include/sll_lite.h | 137 - .../webrtc/signaling/src/sipcc/include/vcm.h | 1108 -- .../src/sipcc/include/xml_parser_defines.h | 636 - .../src/sipcc/plat/common/dns_utils.c | 165 - .../src/sipcc/plat/common/plat_debug.h | 26 - .../signaling/src/sipcc/plat/common/tnp_blf.h | 19 - .../signaling/src/sipcc/plat/csf2g/model.c | 14 - .../src/sipcc/plat/csf2g/reset_api.c | 30 - .../signaling/src/sipcc/plat/darwin/netif.c | 253 - .../src/sipcc/plat/darwin/plat_api_stub.c | 448 - .../src/sipcc/plat/unix-common/random.c | 76 - .../src/sipcc/plat/win32/dns_utils.c | 136 - .../signaling/src/sipcc/plat/win32/mystub.c | 254 - .../src/sipcc/plat/win32/plat_api_stub.c | 519 - .../src/sipcc/plat/win32/plat_api_win.c | 51 - .../signaling/src/sipcc/stub/cc_blf_stub.c | 52 - .../signaling/src/sipcc/stub/vcm_stub.c | 517 - .../src/softphonewrapper/CC_SIPCCCall.cpp | 898 -- .../src/softphonewrapper/CC_SIPCCCall.h | 163 - .../src/softphonewrapper/CC_SIPCCCallInfo.cpp | 529 - .../src/softphonewrapper/CC_SIPCCCallInfo.h | 96 - .../CC_SIPCCCallServerInfo.cpp | 41 - .../softphonewrapper/CC_SIPCCCallServerInfo.h | 34 - .../src/softphonewrapper/CC_SIPCCDevice.cpp | 94 - .../src/softphonewrapper/CC_SIPCCDevice.h | 42 - .../softphonewrapper/CC_SIPCCDeviceInfo.cpp | 134 - .../src/softphonewrapper/CC_SIPCCDeviceInfo.h | 37 - .../softphonewrapper/CC_SIPCCFeatureInfo.cpp | 66 - .../softphonewrapper/CC_SIPCCFeatureInfo.h | 36 - .../src/softphonewrapper/CC_SIPCCLine.cpp | 55 - .../src/softphonewrapper/CC_SIPCCLine.h | 41 - .../src/softphonewrapper/CC_SIPCCLineInfo.cpp | 181 - .../src/softphonewrapper/CC_SIPCCLineInfo.h | 47 - .../src/softphonewrapper/CC_SIPCCService.cpp | 1019 -- .../src/softphonewrapper/CC_SIPCCService.h | 149 - .../softphonewrapper/ccapi_plat_api_impl.cpp | 615 - 416 files changed, 161612 deletions(-) delete mode 100644 media/webrtc/signaling/src/callcontrol/CC_CallTypes.cpp delete mode 100644 media/webrtc/signaling/src/callcontrol/CallControlManager.cpp delete mode 100755 media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.cpp delete mode 100755 media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.h delete mode 100644 media/webrtc/signaling/src/callcontrol/ECC_Types.cpp delete mode 100644 media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.cpp delete mode 100644 media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.h delete mode 100644 media/webrtc/signaling/src/callcontrol/debug-psipcc-types.cpp rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/ccsdp.c (100%) rename media/webrtc/signaling/src/{sipcc/include => sdp/sipcc}/ccsdp.h (100%) rename media/webrtc/signaling/src/{sipcc/include => sdp/sipcc}/ccsdp_rtcp_fb.h (100%) rename media/webrtc/signaling/src/{sipcc/cpr/android => sdp/sipcc}/cpr_android_types.h (100%) rename media/webrtc/signaling/src/{sipcc/cpr/darwin => sdp/sipcc}/cpr_darwin_types.h (100%) rename media/webrtc/signaling/src/{sipcc/cpr/linux => sdp/sipcc}/cpr_linux_types.h (100%) rename media/webrtc/signaling/src/{sipcc/cpr/common => sdp/sipcc}/cpr_string.c (100%) rename media/webrtc/signaling/src/{sipcc/cpr/include => sdp/sipcc}/cpr_string.h (100%) rename media/webrtc/signaling/src/{sipcc/cpr/include => sdp/sipcc}/cpr_strings.h (100%) mode change 100755 => 100644 rename media/webrtc/signaling/src/{sipcc/cpr/include => sdp/sipcc}/cpr_types.h (100%) rename media/webrtc/signaling/src/{sipcc/cpr/win32 => sdp/sipcc}/cpr_win_types.h (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp.h (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_access.c (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_attr.c (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_attr_access.c (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_base64.c (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_base64.h (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_config.c (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_main.c (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_os_defs.h (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_private.h (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_services_unix.c (100%) mode change 100755 => 100644 rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_services_win32.c (100%) mode change 100755 => 100644 rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_token.c (100%) rename media/webrtc/signaling/src/{sipcc/core/sdp => sdp/sipcc}/sdp_utils.c (100%) delete mode 100755 media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_blf.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_config.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_feature.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_info.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/cc_service.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call_info.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_config.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device_info.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_feature_info.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line_info.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_service.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/config_api.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/config_parser.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/config_parser.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/init.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/logger.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/logger.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/logmsg.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/misc.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/plat.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/platform_api.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/prot_cfgmgr_private.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/resource_manager.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/common/resource_manager.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/sip_socket_api.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/subscription_handler.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/subscription_handler.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/text_strings.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/text_strings.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/common/ui.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/gsm/ccapi_strings.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/dcsm.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/fim.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/fsm.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/fsmb2bcnf.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/fsmcac.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/fsmcnf.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/fsmxfr.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/gsm.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/h/fim.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/h/gsm.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/h/lsm.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/gsm/h/lsm_private.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/h/sm.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/lsm.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/sm.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/gsm/subapi.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/ccSession.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/ccapi.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/check_sync.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/ci.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/config.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/configapp.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/configmgr.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/debug.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/dialplan.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/dialplanint.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/digcalc.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/dns_utils.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/dtmf.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/embedded.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/intelpentiumtypes.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/kpml_common_util.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/kpmlmap.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/md5.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/memory.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/misc_apps_task.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/misc_util.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/phntask.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/phone.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/phone_debug.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/phone_platform_constants.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/phone_types.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/platform_api.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/pres_sub_not_handler.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/publish_int.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/rcc_int_types.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/regexp.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/ringlist.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/rtp_defs.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/scSession.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/session.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/sessionConstants.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/sessuri.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/singly_link_list.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/sip_socket_api.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/sntp.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/string_lib.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/subapi.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/task.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/time2.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/timer.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/tnpphone.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/includes/uart.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/uiapi.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/upgrade.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/util_ios_queue.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/util_parse.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/util_string.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/www.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/includes/xml_defs.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_callinfo.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_cc.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_common_util.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_core.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_debug.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_info.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_messaging.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tcp.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_timers.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tls.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_udp.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_pmh.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_publish.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_register.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_reldev.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_spi_utils.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_subsmanager.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_task.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_callinfo.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_cc.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_common_cb.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_core.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_credentials.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_macros.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_messaging.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tcp.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_timers.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tls.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_udp.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_pmh.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_protocol.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_publish.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_register.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_reldev.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sdp.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sim.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_spi_utils.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_subsmanager.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_task.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish_protocol.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhdefs.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhutils.h delete mode 100755 media/webrtc/signaling/src/sipcc/core/sipstack/h/regmgrapi.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_ccm_transport.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_regmgr.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_transport.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_csps_transport.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_interface_regmgr.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_platform_task.h delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/httpish.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/pmhutils.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_regmgr.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_transport.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/sip_csps_transport.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/sip_interface_regmgr.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_win32_task.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/configapp.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/src-common/dialplan.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/src-common/dialplanint.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/digcalc.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/src-common/kpml_common_util.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/src-common/kpmlmap.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/md5.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/src-common/misc_apps_task.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/src-common/pres_sub_not_handler.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/publish_int.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/singly_link_list.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/sll_lite.c delete mode 100755 media/webrtc/signaling/src/sipcc/core/src-common/string_lib.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/util_ios_queue.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/util_parse.c delete mode 100644 media/webrtc/signaling/src/sipcc/core/src-common/util_string.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_align.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_assert.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_errno.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_errno.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_in.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_init.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_private.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_rand.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_socket.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_socket.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_stdio.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_stdio.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_string.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_string.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_strings.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_time.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_timers.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_timers_using_select.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_tst.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_tst.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/common/cpr_ipc.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_align.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_assert.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_errno.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_errno.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_in.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_init.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_private.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_rand.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_socket.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_socket.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_stdio.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_stdio.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_string.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_string.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_strings.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_threads.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_time.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_timers.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_timers_using_select.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_tst.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_assert.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_debug.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_errno.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_in.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_ipc.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_locks.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_memory.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_rand.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_socket.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_stddef.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_stdio.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_stdlib.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_threads.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_time.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/include/cpr_timers.h delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_align.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_assert.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_errno.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_errno.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_in.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_init.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_private.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_rand.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_socket.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_socket.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_stdio.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_stdio.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_string.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_string.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_strings.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_threads.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_time.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_timers.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_timers_using_select.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_tst.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_tst.h delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_assert.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_debug.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_debug.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_defines.h delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_errno.c delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_errno.h delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_in.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_init.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_locks.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_locks.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_rand.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_rand.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_socket.c delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_socket.h delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_stdio.c delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_stdio.h delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_string.c delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_string.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_strings.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.c delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.cpp delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_time.h delete mode 100644 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_timers.c delete mode 100755 media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_timers.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_blf.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_blf_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_call_feature.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_call_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_config.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_constants.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_debug.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_device_feature.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_device_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_info.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_info_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_service.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_service_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/cc_types.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_call.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_call_info.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_call_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_calllog.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_conf_roster.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_device.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_device_info.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_device_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_feature_info.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_line.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_line_info.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_line_listener.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_service.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/ccapi_types.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/config_api.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/dns_util.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/fsmdef_states.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/peer_connection_types.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/plat_api.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/reset_api.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/sll_lite.h delete mode 100755 media/webrtc/signaling/src/sipcc/include/vcm.h delete mode 100644 media/webrtc/signaling/src/sipcc/include/xml_parser_defines.h delete mode 100644 media/webrtc/signaling/src/sipcc/plat/common/dns_utils.c delete mode 100644 media/webrtc/signaling/src/sipcc/plat/common/plat_debug.h delete mode 100755 media/webrtc/signaling/src/sipcc/plat/common/tnp_blf.h delete mode 100644 media/webrtc/signaling/src/sipcc/plat/csf2g/model.c delete mode 100644 media/webrtc/signaling/src/sipcc/plat/csf2g/reset_api.c delete mode 100644 media/webrtc/signaling/src/sipcc/plat/darwin/netif.c delete mode 100755 media/webrtc/signaling/src/sipcc/plat/darwin/plat_api_stub.c delete mode 100644 media/webrtc/signaling/src/sipcc/plat/unix-common/random.c delete mode 100644 media/webrtc/signaling/src/sipcc/plat/win32/dns_utils.c delete mode 100755 media/webrtc/signaling/src/sipcc/plat/win32/mystub.c delete mode 100644 media/webrtc/signaling/src/sipcc/plat/win32/plat_api_stub.c delete mode 100644 media/webrtc/signaling/src/sipcc/plat/win32/plat_api_win.c delete mode 100755 media/webrtc/signaling/src/sipcc/stub/cc_blf_stub.c delete mode 100755 media/webrtc/signaling/src/sipcc/stub/vcm_stub.c delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallInfo.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallInfo.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallServerInfo.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallServerInfo.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDevice.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDevice.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDeviceInfo.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDeviceInfo.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCFeatureInfo.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCFeatureInfo.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLine.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLine.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLineInfo.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLineInfo.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCService.cpp delete mode 100644 media/webrtc/signaling/src/softphonewrapper/CC_SIPCCService.h delete mode 100644 media/webrtc/signaling/src/softphonewrapper/ccapi_plat_api_impl.cpp diff --git a/media/webrtc/signaling/src/callcontrol/CC_CallTypes.cpp b/media/webrtc/signaling/src/callcontrol/CC_CallTypes.cpp deleted file mode 100644 index 1a6b81345b3..00000000000 --- a/media/webrtc/signaling/src/callcontrol/CC_CallTypes.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CC_CallTypes.h" - -using namespace std; - -namespace CSF -{ -namespace CC_CallCapabilityEnum -{ - -std::string toString(CC_CallCapability cap) -{ - switch(cap) - { - case canSetRemoteWindow: - return "canSetRemoteWindow"; - case canSetLocalWindow: - return "canSetLocalWindow"; - case canSendIFrame: - return "canSendIFrame"; - case canOriginateCall: - return "canOriginateCall"; - case canAnswerCall: - return "canAnswerCall"; - case canHold: - return "canHold"; - case canResume: - return "canResume"; - case canEndCall: - return "canEndCall"; - case canSendDigit: - return "canSendDigit"; - case canBackspace: - return "canBackspace"; - case canRedial: - return "canRedial"; - case canInitiateCallForwardAll: - return "canInitiateCallForwardAll"; - case canEndConsultativeCall: - return "canEndConsultativeCall"; - case canConferenceStart: - return "canConferenceStart"; - case canConferenceComplete: - return "canConferenceComplete"; - case canTransferStart: - return "canTransferStart"; - case canTransferComplete: - return "canTransferComplete"; - case canCancelTransferOrConferenceFeature: - return "canCancelTransferOrConferenceFeature"; - case canDirectTransfer: - return "canDirectTransfer"; - case canJoinAcrossLine: - return "canJoinAcrossLine"; - case canBlfCallPickup: - return "canBlfCallPickup"; - case canSelect: - return "canSelect"; - case canUpdateVideoMediaCap: - return "canUpdateVideoMediaCap"; - case canSendInfo: - return "canSendInfo"; - case canMuteAudio: - return "canMuteAudio"; - case canUnmuteAudio: - return "canUnmuteAudio"; - case canMuteVideo: - return "canMuteVideo"; - case canUnmuteVideo: - return "canUnmuteVideo"; - case canSetVolume: - return "canSetVolume"; - default: - return ""; - } -} - -std::string toString(std::set& caps) -{ - string result; - for(std::set::iterator it = caps.begin(); it != caps.end(); it++) - { - if(!result.empty()) - result += ","; - result += toString(*it); - } - return result; -} - -} -} diff --git a/media/webrtc/signaling/src/callcontrol/CallControlManager.cpp b/media/webrtc/signaling/src/callcontrol/CallControlManager.cpp deleted file mode 100644 index 6ec3686ab2e..00000000000 --- a/media/webrtc/signaling/src/callcontrol/CallControlManager.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CallControlManager.h" -#include "CallControlManagerImpl.h" - -namespace CSF -{ -CallControlManagerPtr CallControlManager::create() -{ - CallControlManagerPtr instance(new CallControlManagerImpl()); - return instance; -} - -CallControlManager::~CallControlManager() -{ -} - -} diff --git a/media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.cpp b/media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.cpp deleted file mode 100755 index bb6af5c6d67..00000000000 --- a/media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include -#include - -#include "CSFLog.h" - -#include "CC_SIPCCDevice.h" -#include "CC_SIPCCDeviceInfo.h" -#include "CC_SIPCCFeatureInfo.h" -#include "CC_SIPCCLine.h" -#include "CC_SIPCCLineInfo.h" -#include "CC_SIPCCCallInfo.h" -#include "CallControlManagerImpl.h" -#include "csf_common.h" - -#include "base/platform_thread.h" - -extern "C" -{ -#include "config_api.h" -} - - -static const char logTag[] = "CallControlManager"; - -using namespace std; -using namespace CSFUnified; - -namespace CSF -{ - - -CallControlManagerImpl::CallControlManagerImpl() -: m_lock("CallControlManagerImpl"), - multiClusterMode(false), - sipccLoggingMask(0xFFFFFFFF), - authenticationStatus(AuthenticationStatusEnum::eNotAuthenticated), - connectionState(ConnectionStatusEnum::eIdle) -{ - CSFLogInfo(logTag, "CallControlManagerImpl()"); -} - -CallControlManagerImpl::~CallControlManagerImpl() -{ - CSFLogInfo(logTag, "~CallControlManagerImpl()"); - destroy(); -} - -bool CallControlManagerImpl::destroy() -{ - CSFLogInfo(logTag, "destroy()"); - bool retval = disconnect(); - if(retval == false) - { - return retval; - } - return retval; -} - -// Observers -void CallControlManagerImpl::addCCObserver ( CC_Observer * observer ) -{ - mozilla::MutexAutoLock lock(m_lock); - if (observer == nullptr) - { - CSFLogError(logTag, "NULL value for \"observer\" passed to addCCObserver()."); - return; - } - - ccObservers.insert(observer); -} - -void CallControlManagerImpl::removeCCObserver ( CC_Observer * observer ) -{ - mozilla::MutexAutoLock lock(m_lock); - ccObservers.erase(observer); -} - -void CallControlManagerImpl::addECCObserver ( ECC_Observer * observer ) -{ - mozilla::MutexAutoLock lock(m_lock); - if (observer == nullptr) - { - CSFLogError(logTag, "NULL value for \"observer\" passed to addECCObserver()."); - return; - } - - eccObservers.insert(observer); -} - -void CallControlManagerImpl::removeECCObserver ( ECC_Observer * observer ) -{ - mozilla::MutexAutoLock lock(m_lock); - eccObservers.erase(observer); -} - -void CallControlManagerImpl::setMultiClusterMode(bool allowMultipleClusters) -{ - CSFLogInfo(logTag, "setMultiClusterMode(%s)", - allowMultipleClusters ? "TRUE" : "FALSE"); - multiClusterMode = allowMultipleClusters; -} - -void CallControlManagerImpl::setSIPCCLoggingMask(const cc_int32_t mask) -{ - CSFLogInfo(logTag, "setSIPCCLoggingMask(%u)", mask); - sipccLoggingMask = mask; -} - -void CallControlManagerImpl::setAuthenticationString(const std::string &authString) -{ - CSFLogInfo(logTag, "setAuthenticationString()"); - this->authString = authString; -} - -void CallControlManagerImpl::setSecureCachePath(const std::string &secureCachePath) -{ - CSFLogInfo(logTag, "setSecureCachePath(%s)", secureCachePath.c_str()); - this->secureCachePath = secureCachePath; -} - -// Add local codecs -void CallControlManagerImpl::setAudioCodecs(int codecMask) -{ - CSFLogDebug(logTag, "setAudioCodecs %X", codecMask); - - VcmSIPCCBinding::setAudioCodecs(codecMask); -} - -void CallControlManagerImpl::setVideoCodecs(int codecMask) -{ - CSFLogDebug(logTag, "setVideoCodecs %X", codecMask); - - VcmSIPCCBinding::setVideoCodecs(codecMask); -} - -AuthenticationStatusEnum::AuthenticationStatus CallControlManagerImpl::getAuthenticationStatus() -{ - return authenticationStatus; -} - -bool CallControlManagerImpl::registerUser( const std::string& deviceName, const std::string& user, const std::string& password, const std::string& domain ) -{ - setConnectionState(ConnectionStatusEnum::eRegistering); - - CSFLogInfo(logTag, "registerUser(%s, %s )", user.c_str(), domain.c_str()); - if(phone != nullptr) - { - setConnectionState(ConnectionStatusEnum::eReady); - - CSFLogError(logTag, "registerUser() failed - already connected!"); - return false; - } - - softPhone = CC_SIPCCServicePtr(new CC_SIPCCService()); - phone = softPhone; - phone->init(user, password, domain, deviceName); - softPhone->setLoggingMask(sipccLoggingMask); - phone->addCCObserver(this); - - phone->setP2PMode(false); - - bool bStarted = phone->startService(); - if (!bStarted) { - setConnectionState(ConnectionStatusEnum::eFailed); - } else { - setConnectionState(ConnectionStatusEnum::eReady); - } - - return bStarted; -} - -bool CallControlManagerImpl::startP2PMode(const std::string& user) -{ - setConnectionState(ConnectionStatusEnum::eRegistering); - - CSFLogInfo(logTag, "startP2PMode(%s)", user.c_str()); - if(phone != nullptr) - { - setConnectionState(ConnectionStatusEnum::eReady); - - CSFLogError(logTag, "startP2PMode() failed - already started in p2p mode!"); - return false; - } - - softPhone = CC_SIPCCServicePtr(new CC_SIPCCService()); - phone = softPhone; - phone->init(user, "", "127.0.0.1", "sipdevice"); - softPhone->setLoggingMask(sipccLoggingMask); - phone->addCCObserver(this); - - phone->setP2PMode(true); - - bool bStarted = phone->startService(); - if (!bStarted) { - setConnectionState(ConnectionStatusEnum::eFailed); - } else { - setConnectionState(ConnectionStatusEnum::eReady); - } - - return bStarted; -} - -bool CallControlManagerImpl::startSDPMode() -{ - CSFLogInfo(logTag, "startSDPMode"); - if(phone != nullptr) - { - CSFLogError(logTag, "%s failed - already started in SDP mode!",__FUNCTION__); - return false; - } - softPhone = CC_SIPCCServicePtr(new CC_SIPCCService()); - phone = softPhone; - phone->init("JSEP", "", "127.0.0.1", "sipdevice"); - softPhone->setLoggingMask(sipccLoggingMask); - phone->addCCObserver(this); - phone->setSDPMode(true); - - return phone->startService(); -} - -bool CallControlManagerImpl::disconnect() -{ - CSFLogInfo(logTag, "disconnect()"); - if(phone == nullptr) - return true; - - connectionState = ConnectionStatusEnum::eIdle; - phone->removeCCObserver(this); - phone->stop(); - phone->destroy(); - phone = nullptr; - softPhone = nullptr; - - return true; -} - -std::string CallControlManagerImpl::getPreferredDeviceName() -{ - return preferredDevice; -} - -std::string CallControlManagerImpl::getPreferredLineDN() -{ - return preferredLineDN; -} - -ConnectionStatusEnum::ConnectionStatus CallControlManagerImpl::getConnectionStatus() -{ - return connectionState; -} - -std::string CallControlManagerImpl::getCurrentServer() -{ - return ""; -} - -// Currently controlled device -CC_DevicePtr CallControlManagerImpl::getActiveDevice() -{ - if(phone != nullptr) - return phone->getActiveDevice(); - - return CC_DevicePtr(); -} - -// All known devices -PhoneDetailsVtrPtr CallControlManagerImpl::getAvailablePhoneDetails() -{ - PhoneDetailsVtrPtr result = PhoneDetailsVtrPtr(new PhoneDetailsVtr()); - for(PhoneDetailsMap::iterator it = phoneDetailsMap.begin(); it != phoneDetailsMap.end(); it++) - { - PhoneDetailsPtr details = it->second.get(); - result->push_back(details); - } - return result; -} - -PhoneDetailsPtr CallControlManagerImpl::getAvailablePhoneDetails(const std::string& deviceName) -{ - PhoneDetailsMap::iterator it = phoneDetailsMap.find(deviceName); - if(it != phoneDetailsMap.end()) - { - return it->second.get(); - } - return PhoneDetailsPtr(); -} -// Media setup -VideoControlPtr CallControlManagerImpl::getVideoControl() -{ - if(phone != nullptr) - return phone->getVideoControl(); - - return VideoControlPtr(); -} - -AudioControlPtr CallControlManagerImpl::getAudioControl() -{ - if(phone != nullptr) - return phone->getAudioControl(); - - return AudioControlPtr(); -} - -bool CallControlManagerImpl::setProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key, std::string& value) -{ - unsigned long strtoul_result; - char *strtoul_end; - - CSFLogInfo(logTag, "setProperty( %s )", value.c_str()); - - if (key == ConfigPropertyKeysEnum::eLocalVoipPort) { - errno = 0; - strtoul_result = strtoul(value.c_str(), &strtoul_end, 10); - - if (errno || value.c_str() == strtoul_end || strtoul_result > USHRT_MAX) { - return false; - } - - CCAPI_Config_set_local_voip_port((int) strtoul_result); - } else if (key == ConfigPropertyKeysEnum::eRemoteVoipPort) { - errno = 0; - strtoul_result = strtoul(value.c_str(), &strtoul_end, 10); - - if (errno || value.c_str() == strtoul_end || strtoul_result > USHRT_MAX) { - return false; - } - - CCAPI_Config_set_remote_voip_port((int) strtoul_result); - } else if (key == ConfigPropertyKeysEnum::eTransport) { - if (value == "tcp") - CCAPI_Config_set_transport_udp(false); - else - CCAPI_Config_set_transport_udp(true); - } - - return true; -} - -std::string CallControlManagerImpl::getProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key) -{ - std::string retValue = "NONESET"; - char tmpString[11]; - - CSFLogInfo(logTag, "getProperty()"); - - if (key == ConfigPropertyKeysEnum::eLocalVoipPort) { - csf_sprintf(tmpString, sizeof(tmpString), "%u", CCAPI_Config_get_local_voip_port()); - retValue = tmpString; - } else if (key == ConfigPropertyKeysEnum::eRemoteVoipPort) { - csf_sprintf(tmpString, sizeof(tmpString), "%u", CCAPI_Config_get_remote_voip_port()); - retValue = tmpString; - } else if (key == ConfigPropertyKeysEnum::eVersion) { - const char* version = CCAPI_Config_get_version(); - retValue = version; - } - - return retValue; -} -/* - There are a number of factors that determine PhoneAvailabilityType::PhoneAvailability. The supported states for this enum are: - { eUnknown, eAvailable, eUnAvailable, eNotAllowed }. eUnknown is the default value, which is set when there is no information - available that would otherwise determine the availability value. The factors that can influence PhoneAvailability are: - phone mode, and for a given device (described by DeviceInfo) the model, and the name of the device. For phone control mode, the - device registration and whether CUCM says the device is CTI controllable (or not) is a factor. - - For Phone Control mode the state machine is: - - is blacklisted model name? -> Yes -> NOT_ALLOWED - (see Note1 below) - || - \/ - No - || - \/ - is CTI Controllable? - (determined from CUCM) -> No -> NOT_ALLOWED - || - \/ - Yes - || - \/ - Can we tell if it's registered? -> No -> ?????? TODO: Seems to depends on other factors (look at suggestedAvailability parameter - || in DeviceSubProviderImpl.addOrUpdateDevice() in CSF1G Java code. - \/ - Yes - || - \/ - is Registered? - (determined from CUCM) -> No -> NOT_AVAILABLE - || - \/ - Yes - || - \/ - AVAILABLE - - ======== - - For Softphone mode the state machine is: - - is device excluded? - (based on "ExcludedDevices" -> Yes -> NOT_ALLOWED - config settings - (see Note2 below)) - || - \/ - No - || - \/ - isSoftphone? - - - - Note1: model name has to match completely, ie it's not a sub-string match, but we are ignoring case. So, if the blacklist - contains a string "Cisco Unified Personal Communicator" then the model has to match this completely (but can be a - different case) to be a match. In CSF1G the blacklist is hard-wired to: - { "Cisco Unified Personal Communicator", - "Cisco Unified Client Services Framework", - "Client Services Framework", - "Client Services Core" } - - Note2: The "ExcludedDevices" is a comma-separated list of device name prefixes (not model name). Unlike the above, this is - a sub-string match, but only a "starts with" sub-string match, not anywhere in the string. If the device name - is a complete match then this is also excluded, ie doesn't have to be a sub-string. For example, if the - ExcludeDevices list contains { "ECP", "UPC" } then assuming we're in softphone mode, then any device whose - name starts with the strings ECP or UPC, or whose complete name is either of these will be deemed to be excluded - and will be marked as NOT_ALLOWED straightaway. In Phone Control mode the "ExcludedDevices" list i not taken into - account at all in the determination of availability. - - Note3: isSoftphone() function - - The config service provides a list of "blacklisted" device name prefixes, that is, if the name of the device starts with a - sub-string that matches an entry in the blacklist, then it is straightaway removed from the list? marked as NOT_ALLOWED. - */ - -// CC_Observers -void CallControlManagerImpl::onDeviceEvent(ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info) -{ - notifyDeviceEventObservers(deviceEvent, devicePtr, info); -} -void CallControlManagerImpl::onFeatureEvent(ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info) -{ - notifyFeatureEventObservers(deviceEvent, devicePtr, info); -} -void CallControlManagerImpl::onLineEvent(ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info) -{ - notifyLineEventObservers(lineEvent, linePtr, info); -} -void CallControlManagerImpl::onCallEvent(ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info) -{ - notifyCallEventObservers(callEvent, callPtr, info); -} - - -void CallControlManagerImpl::notifyDeviceEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info) -{ - mozilla::MutexAutoLock lock(m_lock); - set::const_iterator it = ccObservers.begin(); - for ( ; it != ccObservers.end(); it++ ) - { - (*it)->onDeviceEvent(deviceEvent, devicePtr, info); - } -} - -void CallControlManagerImpl::notifyFeatureEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info) -{ - mozilla::MutexAutoLock lock(m_lock); - set::const_iterator it = ccObservers.begin(); - for ( ; it != ccObservers.end(); it++ ) - { - (*it)->onFeatureEvent(deviceEvent, devicePtr, info); - } -} - -void CallControlManagerImpl::notifyLineEventObservers (ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info) -{ - mozilla::MutexAutoLock lock(m_lock); - set::const_iterator it = ccObservers.begin(); - for ( ; it != ccObservers.end(); it++ ) - { - (*it)->onLineEvent(lineEvent, linePtr, info); - } -} - -void CallControlManagerImpl::notifyCallEventObservers (ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info) -{ - mozilla::MutexAutoLock lock(m_lock); - set::const_iterator it = ccObservers.begin(); - for ( ; it != ccObservers.end(); it++ ) - { - (*it)->onCallEvent(callEvent, callPtr, info); - } -} - -void CallControlManagerImpl::notifyAvailablePhoneEvent (AvailablePhoneEventType::AvailablePhoneEvent event, - const PhoneDetailsPtr availablePhoneDetails) -{ - mozilla::MutexAutoLock lock(m_lock); - set::const_iterator it = eccObservers.begin(); - for ( ; it != eccObservers.end(); it++ ) - { - (*it)->onAvailablePhoneEvent(event, availablePhoneDetails); - } -} - -void CallControlManagerImpl::notifyAuthenticationStatusChange (AuthenticationStatusEnum::AuthenticationStatus status) -{ - mozilla::MutexAutoLock lock(m_lock); - set::const_iterator it = eccObservers.begin(); - for ( ; it != eccObservers.end(); it++ ) - { - (*it)->onAuthenticationStatusChange(status); - } -} - -void CallControlManagerImpl::notifyConnectionStatusChange(ConnectionStatusEnum::ConnectionStatus status) -{ - mozilla::MutexAutoLock lock(m_lock); - set::const_iterator it = eccObservers.begin(); - for ( ; it != eccObservers.end(); it++ ) - { - (*it)->onConnectionStatusChange(status); - } -} - -void CallControlManagerImpl::setConnectionState(ConnectionStatusEnum::ConnectionStatus status) -{ - connectionState = status; - notifyConnectionStatusChange(status); -} -} diff --git a/media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.h b/media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.h deleted file mode 100755 index d7a684c38e7..00000000000 --- a/media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.h +++ /dev/null @@ -1,122 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "CallControlManager.h" -#include "PhoneDetailsImpl.h" -#include "CC_SIPCCService.h" -#include "mozilla/Mutex.h" - - -#include -#include - -namespace CSF -{ - class CallControlManagerImpl: public CallControlManager, public CC_Observer - { - public: - CallControlManagerImpl(); - virtual bool destroy(); - virtual ~CallControlManagerImpl(); - - // Observers - virtual void addCCObserver ( CC_Observer * observer ); - virtual void removeCCObserver ( CC_Observer * observer ); - - virtual void addECCObserver ( ECC_Observer * observer ); - virtual void removeECCObserver ( ECC_Observer * observer ); - - // Config and global setup - virtual void setMultiClusterMode(bool allowMultipleClusters); - virtual void setSIPCCLoggingMask(const cc_int32_t mask); - virtual void setAuthenticationString(const std::string &authString); - virtual void setSecureCachePath(const std::string &secureCachePath); - - // Add local codecs - virtual void setAudioCodecs(int codecMask); - virtual void setVideoCodecs(int codecMask); - - virtual AuthenticationStatusEnum::AuthenticationStatus getAuthenticationStatus(); - - virtual bool registerUser( const std::string& deviceName, const std::string& user, const std::string& password, const std::string& domain ); - - virtual bool startP2PMode(const std::string& user); - - virtual bool startSDPMode(); - - virtual bool disconnect(); - virtual std::string getPreferredDeviceName(); - virtual std::string getPreferredLineDN(); - virtual ConnectionStatusEnum::ConnectionStatus getConnectionStatus(); - virtual std::string getCurrentServer(); - - // Currently controlled device - virtual CC_DevicePtr getActiveDevice(); - - // All known devices - virtual PhoneDetailsVtrPtr getAvailablePhoneDetails(); - virtual PhoneDetailsPtr getAvailablePhoneDetails(const std::string& deviceName); - - // Media setup - virtual VideoControlPtr getVideoControl(); - virtual AudioControlPtr getAudioControl(); - - virtual bool setProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key, std::string& value); - virtual std::string getProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key); - - private: // Data Storage - - // Observers - mozilla::Mutex m_lock; - std::set ccObservers; - std::set eccObservers; - - // Config and global setup - std::string username; - std::string password; - std::string authString; - std::string secureCachePath; - bool multiClusterMode; - cc_int32_t sipccLoggingMask; - - AuthenticationStatusEnum::AuthenticationStatus authenticationStatus; - - std::string preferredDevice; - std::string preferredLineDN; - CC_ServicePtr phone; // The generic handle, for simple operations. - CC_SIPCCServicePtr softPhone; // For setup operations not available on the generic API. - - // All known devices - typedef std::map PhoneDetailsMap; - PhoneDetailsMap phoneDetailsMap; - - // store connection state - ConnectionStatusEnum::ConnectionStatus connectionState; - - public: // Listeners for stacks controlled by CallControlManager - // CC_Observers - void onDeviceEvent (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info); - void onFeatureEvent (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info); - void onLineEvent (ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info); - void onCallEvent (ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info); - - private: //member functions - - // CC_Observers - void notifyDeviceEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info); - void notifyFeatureEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info); - void notifyLineEventObservers (ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info); - void notifyCallEventObservers (ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info); - - // ECC_Observers - void notifyAvailablePhoneEvent (AvailablePhoneEventType::AvailablePhoneEvent event, - const PhoneDetailsPtr phoneDetails); - void notifyAuthenticationStatusChange (AuthenticationStatusEnum::AuthenticationStatus); - void notifyConnectionStatusChange(ConnectionStatusEnum::ConnectionStatus status); - void setConnectionState(ConnectionStatusEnum::ConnectionStatus status); - }; - -} diff --git a/media/webrtc/signaling/src/callcontrol/ECC_Types.cpp b/media/webrtc/signaling/src/callcontrol/ECC_Types.cpp deleted file mode 100644 index eeedfebd4d6..00000000000 --- a/media/webrtc/signaling/src/callcontrol/ECC_Types.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "ECC_Types.h" - -using namespace std; - -namespace CSF -{ - -namespace AuthenticationFailureCodeType -{ -std::string ECC_API toString(AuthenticationFailureCode value) -{ - switch(value) - { - case eNoError: - return "eNoError"; - case eNoServersConfigured: - return "eNoServersConfigured"; - case eNoCredentialsConfigured: - return "eNoCredentialsConfigured"; - case eCouldNotConnect: - return "eCouldNotConnect"; - case eServerCertificateRejected: - return "eServerCertificateRejected"; - case eCredentialsRejected: - return "eCredentialsRejected"; - case eResponseEmpty: - return "eResponseEmpty"; - case eResponseInvalid: - return "eResponseInvalid"; - default: - return ""; - } -} -} - -namespace AuthenticationStatusEnum -{ -std::string ECC_API toString(AuthenticationStatus value) -{ - switch(value) - { - case eNotAuthenticated: - return "eNotAuthenticated"; - case eInProgress: - return "eInProgress"; - case eAuthenticated: - return "eAuthenticated"; - case eFailed: - return "eFailed"; - default: - return ""; - } -} -} - -namespace DeviceRetrievalFailureCodeType -{ -std::string ECC_API toString(DeviceRetrievalFailureCode value) -{ - switch(value) - { - case eNoError: - return "eNoError"; - case eNoServersConfigured: - return "eNoServersConfigured"; - case eNoDeviceNameConfigured: - return "eNoDeviceNameConfigured"; - case eCouldNotConnect: - return "eCouldNotConnect"; - case eFileNotFound: - return "eFileNotFound"; - case eFileEmpty: - return "eFileEmpty"; - case eFileInvalid: - return "eFileInvalid"; - default: - return ""; - } -} -} - -namespace ConnectionStatusEnum -{ -std::string ECC_API toString(ConnectionStatus value) -{ - switch(value) - { - case eIdle: - return "eIdle"; - case eNone: - return "eNone"; - case eFetchingDeviceConfig: - return "eFetchingDeviceConfig"; - case eRegistering: - return "eRegistering"; - case eReady: - return "eReady"; - case eConnectedButNoDeviceReady: - return "eConnectedButNoDeviceReady"; - case eRetrying: - return "eRetrying"; - case eFailed: - return "eFailed"; - default: - return ""; - } -} -} - -namespace ServiceStateType -{ -std::string ECC_API toString(ServiceState value) -{ - switch(value) - { - case eUnknown: - return "eUnknown"; - case eInService: - return "eInService"; - case eOutOfService: - return "eOutOfService"; - default: - return ""; - } -} -} - -namespace AvailablePhoneEventType -{ -std::string ECC_API toString(AvailablePhoneEvent value) -{ - switch(value) - { - case eFound: - return "eFound"; - case eUpdated: - return "eUpdated"; - case eLost: - return "eLost"; - default: - return ""; - } -} -} - -} diff --git a/media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.cpp b/media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.cpp deleted file mode 100644 index f3edaccd2ad..00000000000 --- a/media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PhoneDetailsImpl.h" - -#include "csf_common.h" - -namespace CSF -{ - -PhoneDetailsImpl::PhoneDetailsImpl() -: model(-1), - state(ServiceStateType::eUnknown) -{ -} - -PhoneDetailsImpl::~PhoneDetailsImpl() -{ -} - -static const char * _softphoneSupportedModelNames[] = { "Cisco Unified Client Services Framework", - "Client Services Framework", - "Client Services Core" }; - -bool PhoneDetailsImpl::isSoftPhone() -{ - if(model == -1 && modelDescription != "") - { - // Evaluate based on model description. - for(int i = 0; i < (int) csf_countof(_softphoneSupportedModelNames); i++) - { - if(modelDescription == _softphoneSupportedModelNames[i]) - return true; - } - return false; - } - else - { - } - return false; -} - -void PhoneDetailsImpl::setName(const std::string& name) -{ - this->name = name; -} -void PhoneDetailsImpl::setDescription(const std::string& description) -{ - this->description = description; -} -// Note that setting model and model description are mutually exclusive. -void PhoneDetailsImpl::setModel(int model) -{ - this->model = model; - this->modelDescription = ""; -} -void PhoneDetailsImpl::setModelDescription(const std::string& description) -{ - this->model = -1; - this->modelDescription = description; -} -void PhoneDetailsImpl::setLineDNs(const std::vector & lineDNs) -{ - this->lineDNs.assign(lineDNs.begin(), lineDNs.end()); -} -void PhoneDetailsImpl::setServiceState(ServiceStateType::ServiceState state) -{ - this->state = state; -} -void PhoneDetailsImpl::setConfig(const std::string& config) -{ - this->config = config; -} - -} diff --git a/media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.h b/media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.h deleted file mode 100644 index 609b7fe91ea..00000000000 --- a/media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "PhoneDetails.h" - -namespace CSF -{ - DECLARE_NS_PTR(PhoneDetailsImpl); - class PhoneDetailsImpl: public PhoneDetails - { - public: - virtual std::string getName() const {return name; } - virtual std::string getDescription() const {return description; } - virtual int getModel() const {return model;} - virtual std::string getModelDescription() const {return modelDescription; } - virtual bool isSoftPhone(); - virtual std::vector getLineDNs() const {return lineDNs; } - virtual ServiceStateType::ServiceState getServiceState() const { return state; } - virtual std::string getConfig() const { return config; } - - protected: - PhoneDetailsImpl(); - virtual ~PhoneDetailsImpl(); - - public: - virtual void setName(const std::string& name); - virtual void setDescription(const std::string& description); - // Note that setting model and model description are mutually exclusive. - virtual void setModel(int model); - virtual void setModelDescription(const std::string& description); - virtual void setLineDNs(const std::vector & lineDNs); - virtual void setServiceState(ServiceStateType::ServiceState state); - virtual void setConfig(const std::string& config); - - private: - std::string name; - std::string description; - int model; - std::string modelDescription; - std::vector lineDNs; - ServiceStateType::ServiceState state; - std::string config; - - }; -} diff --git a/media/webrtc/signaling/src/callcontrol/debug-psipcc-types.cpp b/media/webrtc/signaling/src/callcontrol/debug-psipcc-types.cpp deleted file mode 100644 index 5537a012857..00000000000 --- a/media/webrtc/signaling/src/callcontrol/debug-psipcc-types.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CC_Common.h" -#include - -#include "debug-psipcc-types.h" - -struct ename { - int v; - cc_string_t name; -}; - -#define ENAME_DECL(v) \ - { v, #v } - -/* - * Get a symbolic representation of a numeric identifier. - */ -static cc_string_t -egetname(const struct ename *index, int event) -{ - const struct ename *ename; - - for (ename = index; !(ename->v == 0 && ename->name == nullptr); ename++) { - if (event == ename->v) - return ename->name; - } - - return "UNKNOWN"; -} - -#define CC_EVENT _e -#define CC_TYPE _t - -#define DEFINE_NO_PREPEND_TYPE_NAME_FUNCTION(typeName, eventOrType, ...)\ - DEFINE_TYPE_NAME_FUNCTION_HELPER(, typeName, eventOrType, __VA_ARGS__) - -#define DEFINE_CCAPI_TYPE_NAME_FUNCTION(typeName, eventOrType, ...)\ - DEFINE_TYPE_NAME_FUNCTION_HELPER(ccapi_, typeName, eventOrType, __VA_ARGS__) - -#define DEFINE_CC_TYPE_NAME_FUNCTION(typeName, eventOrType, ...)\ - DEFINE_TYPE_NAME_FUNCTION_HELPER(cc_, typeName, eventOrType, __VA_ARGS__) - -#define DEFINE_TYPE_NAME_FUNCTION_HELPER(tokenPrepend, typeName, eventOrType, ...)\ - static struct ename tokenPrepend##typeName##_names[] = {\ - __VA_ARGS__, \ - { 0, nullptr } \ - };\ - \ - ECC_API cc_string_t typeName##_getname(tokenPrepend##typeName##eventOrType ev) \ - {\ - return egetname(&tokenPrepend##typeName##_names[0], (int) ev);\ - } - -//stringizing enums from ccapi_types.h - -//define device_event_getname(ccapi_device_event_e); -DEFINE_CCAPI_TYPE_NAME_FUNCTION(device_event, CC_EVENT, - ENAME_DECL(CCAPI_DEVICE_EV_CONFIG_CHANGED), - ENAME_DECL(CCAPI_DEVICE_EV_STATE), - ENAME_DECL(CCAPI_DEVICE_EV_IDLE_SET), - ENAME_DECL(CCAPI_DEVICE_EV_MWI_LAMP), - ENAME_DECL(CCAPI_DEVICE_EV_NOTIFYPROMPT), - ENAME_DECL(CCAPI_DEVICE_EV_SERVER_STATUS), - ENAME_DECL(CCAPI_DEVICE_EV_BLF), - ENAME_DECL(CCAPI_DEVICE_EV_CAMERA_ADMIN_CONFIG_CHANGED), - ENAME_DECL(CCAPI_DEVICE_EV_VIDEO_CAP_ADMIN_CONFIG_CHANGED) - ); - -//define call_event_getname(ccapi_call_event_e); -DEFINE_CCAPI_TYPE_NAME_FUNCTION(call_event, CC_EVENT, - ENAME_DECL(CCAPI_CALL_EV_CREATED), - ENAME_DECL(CCAPI_CALL_EV_STATE), - ENAME_DECL(CCAPI_CALL_EV_CALLINFO), - ENAME_DECL(CCAPI_CALL_EV_ATTR), - ENAME_DECL(CCAPI_CALL_EV_SECURITY), - ENAME_DECL(CCAPI_CALL_EV_LOG_DISP), - ENAME_DECL(CCAPI_CALL_EV_PLACED_CALLINFO), - ENAME_DECL(CCAPI_CALL_EV_STATUS), - ENAME_DECL(CCAPI_CALL_EV_SELECT), - ENAME_DECL(CCAPI_CALL_EV_LAST_DIGIT_DELETED), - ENAME_DECL(CCAPI_CALL_EV_GCID), - ENAME_DECL(CCAPI_CALL_EV_XFR_OR_CNF_CANCELLED), - ENAME_DECL(CCAPI_CALL_EV_PRESERVATION), - ENAME_DECL(CCAPI_CALL_EV_CAPABILITY), - ENAME_DECL(CCAPI_CALL_EV_VIDEO_AVAIL), - ENAME_DECL(CCAPI_CALL_EV_VIDEO_OFFERED), - ENAME_DECL(CCAPI_CALL_EV_RECEIVED_INFO), - ENAME_DECL(CCAPI_CALL_EV_RINGER_STATE), - ENAME_DECL(CCAPI_CALL_EV_CONF_PARTICIPANT_INFO), - ENAME_DECL(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_BEGIN), - ENAME_DECL(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_SUCCESSFUL), - ENAME_DECL(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_FAIL) - ); - -//define line_event_getname(ccapi_line_event_e); -DEFINE_CCAPI_TYPE_NAME_FUNCTION(line_event, CC_EVENT, - ENAME_DECL(CCAPI_LINE_EV_CONFIG_CHANGED), - ENAME_DECL(CCAPI_LINE_EV_REG_STATE), - ENAME_DECL(CCAPI_LINE_EV_CAPSET_CHANGED), - ENAME_DECL(CCAPI_LINE_EV_CFWDALL), - ENAME_DECL(CCAPI_LINE_EV_MWI) - ); - -// -// -//stringizing enums from cc_constants.h -// -// - - -//define digit_getname(cc_digit_t); -DEFINE_CC_TYPE_NAME_FUNCTION(digit, CC_TYPE, - ENAME_DECL(KEY_1), - ENAME_DECL(KEY_2), - ENAME_DECL(KEY_3), - ENAME_DECL(KEY_4), - ENAME_DECL(KEY_5), - ENAME_DECL(KEY_6), - ENAME_DECL(KEY_7), - ENAME_DECL(KEY_8), - ENAME_DECL(KEY_9), - ENAME_DECL(KEY_0), - ENAME_DECL(KEY_STAR), - ENAME_DECL(KEY_POUND), - ENAME_DECL(KEY_A), - ENAME_DECL(KEY_B), - ENAME_DECL(KEY_C), - ENAME_DECL(KEY_D) - ); - -//define cucm_mode_getname(cc_cucm_mode_t); -DEFINE_CC_TYPE_NAME_FUNCTION(cucm_mode, CC_TYPE, - ENAME_DECL(CC_MODE_INVALID), - ENAME_DECL(CC_MODE_CCM), - ENAME_DECL(CC_MODE_NONCCM) - ); - -//define line_feature_getname(cc_line_feature_t); -DEFINE_CC_TYPE_NAME_FUNCTION(line_feature, CC_TYPE, - ENAME_DECL(CC_LINE_FEATURE_NONE), - ENAME_DECL(CC_LINE_FEATURE_REDIAL), - ENAME_DECL(CC_LINE_FEATURE_SPEEDDIAL), - ENAME_DECL(CC_LINE_FEATURE_DN), - ENAME_DECL(CC_LINE_FEATURE_SERVICE), - ENAME_DECL(CC_LINE_FEATURE_SPEEDDIALBLF), - ENAME_DECL(CC_LINE_FEATURE_MALICIOUSCALLID), - ENAME_DECL(CC_LINE_FEATURE_QUALREPORTTOOL), - ENAME_DECL(CC_LINE_FEATURE_ALLCALLS), - ENAME_DECL(CC_LINE_FEATURE_ANSWEROLDEST), - ENAME_DECL(CC_LINE_FEATURE_SERVICES), - ENAME_DECL(CC_LINE_FEATURE_BLF) - ); - -//define feature_option_mask_getname(cc_feature_option_mask_t); -DEFINE_CC_TYPE_NAME_FUNCTION(feature_option_mask, CC_TYPE, - ENAME_DECL(CC_FEATUREOPTIONMASK_NONE), - ENAME_DECL(CC_FEATUREOPTIONMASK_BLF_PICKUP) - ); - -//define service_cause_getname(cc_service_cause_t); -DEFINE_CC_TYPE_NAME_FUNCTION(service_cause, CC_TYPE, - ENAME_DECL(CC_CAUSE_NONE), - ENAME_DECL(CC_CAUSE_FAILOVER), - ENAME_DECL(CC_CAUSE_FALLBACK), - ENAME_DECL(CC_CAUSE_REG_ALL_FAILED), - ENAME_DECL(CC_CAUSE_SHUTDOWN), - ENAME_DECL(CC_CAUSE_UNREG_ALL), - ENAME_DECL(CC_CAUSE_LOGOUT_RESET) - ); - -//define service_state_getname(cc_service_state_t); -DEFINE_CC_TYPE_NAME_FUNCTION(service_state, CC_TYPE, - ENAME_DECL(CC_STATE_IDLE), - ENAME_DECL(CC_STATE_INS), - ENAME_DECL(CC_STATE_OOS), - ENAME_DECL(CC_STATE_PRO_BASE) - ); - -//define ccm_status_getname(cc_ccm_status_t); -DEFINE_CC_TYPE_NAME_FUNCTION(ccm_status, CC_TYPE, - ENAME_DECL(CC_CCM_STATUS_NONE), - ENAME_DECL(CC_CCM_STATUS_STANDBY), - ENAME_DECL(CC_CCM_STATUS_ACTIVE) - ); - -//define reg_state_getname(cc_line_reg_state_t); -DEFINE_CC_TYPE_NAME_FUNCTION(line_reg_state, CC_TYPE, - ENAME_DECL(CC_UNREGISTERED), - ENAME_DECL(CC_REGISTERED) - ); - -//define shutdown_reason_getname(cc_shutdown_reason_t); -DEFINE_CC_TYPE_NAME_FUNCTION(shutdown_reason, CC_TYPE, - ENAME_DECL(CC_SHUTDOWN_NORMAL), - ENAME_DECL(CC_SHUTDOWN_UNSPECIFIED), - ENAME_DECL(CC_SHUTDOWN_VERMISMATCH) - ); - -//define kpml_config_getname(cc_kpml_config_t); -DEFINE_CC_TYPE_NAME_FUNCTION(kpml_config, CC_TYPE, - ENAME_DECL(CC_KPML_NONE), - ENAME_DECL(CC_KPML_SIGNAL_ONLY), - ENAME_DECL(CC_KPML_DTMF_ONLY), - ENAME_DECL(CC_KPML_BOTH) - ); - -//define upgrade_getname(cc_upgrade_t); -DEFINE_CC_TYPE_NAME_FUNCTION(upgrade, CC_TYPE, - ENAME_DECL(CC_UPGRADE_NONE), - ENAME_DECL(CC_UPGRADE_NOW), - ENAME_DECL(CC_UPGRADE_LATER) - ); - -//define sdp_direction_getname(cc_sdp_direction_t); -DEFINE_CC_TYPE_NAME_FUNCTION(sdp_direction, CC_TYPE, - ENAME_DECL(CC_SDP_DIRECTION_INACTIVE), - ENAME_DECL(CC_SDP_DIRECTION_SENDONLY), - ENAME_DECL(CC_SDP_DIRECTION_RECVONLY), - ENAME_DECL(CC_SDP_DIRECTION_SENDRECV), - ENAME_DECL(CC_SDP_MAX_QOS_DIRECTIONS) - ); - -//define blf_state_getname(cc_blf_state_t); -DEFINE_CC_TYPE_NAME_FUNCTION(blf_state, CC_TYPE, - ENAME_DECL(CC_SIP_BLF_UNKNOWN), - ENAME_DECL(CC_SIP_BLF_IDLE), - ENAME_DECL(CC_SIP_BLF_INUSE), - ENAME_DECL(CC_SIP_BLF_EXPIRED), - ENAME_DECL(CC_SIP_BLF_REJECTED), - ENAME_DECL(CC_SIP_BLF_ALERTING) - ); - -//define blf_feature_mask_getname(cc_blf_feature_mask_t); -DEFINE_CC_TYPE_NAME_FUNCTION (blf_feature_mask, CC_TYPE, - ENAME_DECL(CC_BLF_FEATURE_MASK_NONE), - ENAME_DECL(CC_BLF_FEATURE_MASK_PICKUP) - ); - -//define call_state_getname(cc_call_state_t); -DEFINE_CC_TYPE_NAME_FUNCTION (call_state, CC_TYPE, - ENAME_DECL(OFFHOOK), - ENAME_DECL(ONHOOK), - ENAME_DECL(RINGOUT), - ENAME_DECL(RINGIN), - ENAME_DECL(PROCEED), - ENAME_DECL(CONNECTED), - ENAME_DECL(HOLD), - ENAME_DECL(REMHOLD), - ENAME_DECL(RESUME), - ENAME_DECL(BUSY), - ENAME_DECL(REORDER), - ENAME_DECL(CONFERENCE), - ENAME_DECL(DIALING), - ENAME_DECL(REMINUSE), - ENAME_DECL(HOLDREVERT), - ENAME_DECL(WHISPER), - ENAME_DECL(PRESERVATION), - ENAME_DECL(WAITINGFORDIGITS), - ENAME_DECL(MAX_CALL_STATES) - ); - -//define call_attr_getname(cc_call_attr_t); -DEFINE_CC_TYPE_NAME_FUNCTION (call_attr, CC_TYPE, - ENAME_DECL(CC_ATTR_NOT_DEFINED), - ENAME_DECL(CC_ATTR_NORMAL), - ENAME_DECL(CC_ATTR_XFR_CONSULT), - ENAME_DECL(CC_ATTR_CONF_CONSULT), - ENAME_DECL(CC_ATTR_BARGING), - ENAME_DECL(CC_ATTR_RIUHELD_LOCKED), - ENAME_DECL(CC_ATTR_LOCAL_CONF_CONSULT), - ENAME_DECL(CC_ATTR_LOCAL_XFER_CONSULT), - ENAME_DECL(CC_ATTR_CFWDALL), - ENAME_DECL(CC_ATTR_CFWD_ALL), - ENAME_DECL(CC_ATTR_MAX) - ); - -//define hold_reason_getname(cc_hold_reason_t); -DEFINE_CC_TYPE_NAME_FUNCTION (hold_reason, CC_TYPE, - ENAME_DECL(CC_HOLD_REASON_NONE), - ENAME_DECL(CC_HOLD_REASON_XFER), - ENAME_DECL(CC_HOLD_REASON_CONF), - ENAME_DECL(CC_HOLD_REASON_SWAP), - ENAME_DECL(CC_HOLD_REASON_INTERNAL) - ); - -//define call_type_getname(cc_call_type_t); -DEFINE_CC_TYPE_NAME_FUNCTION (call_type, CC_TYPE, - ENAME_DECL(CC_CALL_TYPE_NONE), - ENAME_DECL(CC_CALL_TYPE_INCOMING), - ENAME_DECL(CC_CALL_TYPE_OUTGOING), - ENAME_DECL(CC_CALL_TYPE_FORWARDED) - ); - -//define call_security_getname(cc_call_security_t); -DEFINE_CC_TYPE_NAME_FUNCTION (call_security, CC_TYPE, - ENAME_DECL(CC_SECURITY_NONE), - ENAME_DECL(CC_SECURITY_UNKNOWN), - ENAME_DECL(CC_SECURITY_AUTHENTICATED), - ENAME_DECL(CC_SECURITY_NOT_AUTHENTICATED), - ENAME_DECL(CC_SECURITY_ENCRYPTED) - ); - -//define call_policy_getname(cc_call_policy_t); -DEFINE_CC_TYPE_NAME_FUNCTION (call_policy, CC_TYPE, - ENAME_DECL(CC_POLICY_NONE), - ENAME_DECL(CC_POLICY_UNKNOWN), - ENAME_DECL(CC_POLICY_CHAPERONE) - ); - -//define log_disposition_getname(cc_log_disposition_t); -DEFINE_CC_TYPE_NAME_FUNCTION (log_disposition, CC_TYPE, - ENAME_DECL(CC_LOGD_MISSED), - ENAME_DECL(CC_LOGD_RCVD), - ENAME_DECL(CC_LOGD_SENT), - ENAME_DECL(CC_LOGD_UNKNWN), - ENAME_DECL(CC_LOGD_DELETE) - ); - -//define call_priority_getname(cc_call_priority_t); -DEFINE_CC_TYPE_NAME_FUNCTION (call_priority, CC_TYPE, - ENAME_DECL(CC_PRIORITY_NORMAL), - ENAME_DECL(CC_PRIORITY_URGENT) - ); - -//define call_selection_getname(cc_call_selection_t); -DEFINE_CC_TYPE_NAME_FUNCTION (call_selection, CC_TYPE, - ENAME_DECL(CC_CALL_SELECT_NONE), - ENAME_DECL(CC_CALL_SELECT_LOCKED), - ENAME_DECL(CC_CALL_SELECT_UNLOCKED), - ENAME_DECL(CC_CALL_SELECT_REMOTE_LOCKED) - ); - -//cc_string_t call_capability_getname(ccapi_call_capability_e); -DEFINE_CCAPI_TYPE_NAME_FUNCTION(call_capability, CC_EVENT, - ENAME_DECL(CCAPI_CALL_CAP_NEWCALL), - ENAME_DECL(CCAPI_CALL_CAP_ANSWER), - ENAME_DECL(CCAPI_CALL_CAP_ENDCALL), - ENAME_DECL(CCAPI_CALL_CAP_HOLD), - ENAME_DECL(CCAPI_CALL_CAP_RESUME), - ENAME_DECL(CCAPI_CALL_CAP_CALLFWD), - ENAME_DECL(CCAPI_CALL_CAP_DIAL), - ENAME_DECL(CCAPI_CALL_CAP_BACKSPACE), - ENAME_DECL(CCAPI_CALL_CAP_SENDDIGIT), - ENAME_DECL(CCAPI_CALL_CAP_TRANSFER), - ENAME_DECL(CCAPI_CALL_CAP_CONFERENCE), - ENAME_DECL(CCAPI_CALL_CAP_SWAP), - ENAME_DECL(CCAPI_CALL_CAP_REDIAL), - ENAME_DECL(CCAPI_CALL_CAP_JOIN), - ENAME_DECL(CCAPI_CALL_CAP_SELECT), - ENAME_DECL(CCAPI_CALL_CAP_RMVLASTPARTICIPANT), - ENAME_DECL(CCAPI_CALL_CAP_MAX) - ); - -//define srv_ctrl_req_getname(cc_srv_ctrl_req_t); -DEFINE_CC_TYPE_NAME_FUNCTION (srv_ctrl_req, CC_TYPE, - ENAME_DECL(CC_DEVICE_RESET), - ENAME_DECL(CC_DEVICE_RESTART), - ENAME_DECL(CC_DEVICE_ICMP_UNREACHABLE) - ); - -//define srv_ctrl_cmd_getname(cc_srv_ctrl_cmd_t); -DEFINE_CC_TYPE_NAME_FUNCTION (srv_ctrl_cmd, CC_TYPE, - ENAME_DECL(CC_ACTION_RESET), - ENAME_DECL(CC_ACTION_RESTART) - ); - -//define message_type_getname(cc_message_type_t); -DEFINE_CC_TYPE_NAME_FUNCTION (message_type, CC_TYPE, - ENAME_DECL(CC_VOICE_MESSAGE), - ENAME_DECL(CC_TEXT_MESSAGE) - ); - -//define lamp_state_getname(cc_lamp_state_t); -DEFINE_CC_TYPE_NAME_FUNCTION (lamp_state, CC_TYPE, - ENAME_DECL(CC_LAMP_NONE), - ENAME_DECL(CC_LAMP_ON), - ENAME_DECL(CC_LAMP_BLINK), - ENAME_DECL(CC_LAMP_FRESH) - ); - -//define cause_getname(cc_cause_t); -DEFINE_CC_TYPE_NAME_FUNCTION (cause, CC_TYPE, - ENAME_DECL(CC_CAUSE_MIN), - ENAME_DECL(CC_CAUSE_BASE), - ENAME_DECL(CC_CAUSE_OK), - ENAME_DECL(CC_CAUSE_ERROR), - ENAME_DECL(CC_CAUSE_UNASSIGNED_NUM), - ENAME_DECL(CC_CAUSE_NO_RESOURCE), - ENAME_DECL(CC_CAUSE_NO_ROUTE), - ENAME_DECL(CC_CAUSE_NORMAL), - ENAME_DECL(CC_CAUSE_BUSY), - ENAME_DECL(CC_CAUSE_NO_USER_RESP), - ENAME_DECL(CC_CAUSE_NO_USER_ANS), - ENAME_DECL(CC_CAUSE_REJECT), - ENAME_DECL(CC_CAUSE_INVALID_NUMBER), - ENAME_DECL(CC_CAUSE_FACILITY_REJECTED), - ENAME_DECL(CC_CAUSE_CALL_ID_IN_USE), - ENAME_DECL(CC_CAUSE_XFER_LOCAL), - ENAME_DECL(CC_CAUSE_XFER_REMOTE), - ENAME_DECL(CC_CAUSE_XFER_BY_REMOTE), - ENAME_DECL(CC_CAUSE_XFER_CNF), - ENAME_DECL(CC_CAUSE_CONGESTION), - ENAME_DECL(CC_CAUSE_ANONYMOUS), - ENAME_DECL(CC_CAUSE_REDIRECT), - ENAME_DECL(CC_CAUSE_PAYLOAD_MISMATCH), - ENAME_DECL(CC_CAUSE_CONF), - ENAME_DECL(CC_CAUSE_REPLACE), - ENAME_DECL(CC_CAUSE_NO_REPLACE_CALL), - ENAME_DECL(CC_CAUSE_NO_RESUME), - ENAME_DECL(CC_CAUSE_NO_MEDIA), - ENAME_DECL(CC_CAUSE_REQUEST_PENDING), - ENAME_DECL(CC_CAUSE_INVALID_PARTICIPANT), - ENAME_DECL(CC_CAUSE_NO_CNF_BRIDE), - ENAME_DECL(CC_MAXIMUM_PARTICIPANT), - ENAME_DECL(CC_KEY_NOT_ACTIVE), - ENAME_DECL(CC_TEMP_NOT_AVAILABLE), - ENAME_DECL(CC_CAUSE_REMOTE_SERVER_ERROR), - ENAME_DECL(CC_CAUSE_NOT_FOUND), - ENAME_DECL(CC_CAUSE_SECURITY_FAILURE), - ENAME_DECL(CC_CAUSE_MONITOR), - ENAME_DECL(CC_CAUSE_UI_STATE_BUSY), - ENAME_DECL(CC_SIP_CAUSE_ANSWERED_ELSEWHERE), - ENAME_DECL(CC_CAUSE_RETRIEVED), - ENAME_DECL(CC_CAUSE_FORWARDED), - ENAME_DECL(CC_CAUSE_ABANDONED), - ENAME_DECL(CC_CAUSE_XFER_LOCAL_WITH_DIALSTRING), - ENAME_DECL(CC_CAUSE_BW_OK), - ENAME_DECL(CC_CAUSE_XFER_COMPLETE), - ENAME_DECL(CC_CAUSE_RESP_TIMEOUT), - ENAME_DECL(CC_CAUSE_SERV_ERR_UNAVAIL), - ENAME_DECL(CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE), - ENAME_DECL(CC_CAUSE_OUT_OF_MEM), - ENAME_DECL(CC_CAUSE_VALUE_NOT_FOUND), - ENAME_DECL(CC_CAUSE_BAD_ICE_ATTRIBUTE), - ENAME_DECL(CC_CAUSE_DTLS_ATTRIBUTE_ERROR), - ENAME_DECL(CC_CAUSE_DTLS_DIGEST_ALGORITHM_EMPTY), - ENAME_DECL(CC_CAUSE_DTLS_DIGEST_ALGORITHM_TOO_LONG), - ENAME_DECL(CC_CAUSE_DTLS_DIGEST_EMPTY), - ENAME_DECL(CC_CAUSE_DTLS_DIGEST_TOO_LONG), - ENAME_DECL(CC_CAUSE_DTLS_FINGERPRINT_PARSE_ERROR), - ENAME_DECL(CC_CAUSE_DTLS_FINGERPRINT_TOO_LONG), - ENAME_DECL(CC_CAUSE_INVALID_SDP_POINTER), - ENAME_DECL(CC_CAUSE_NO_AUDIO), - ENAME_DECL(CC_CAUSE_NO_DTLS_FINGERPRINT), - ENAME_DECL(CC_CAUSE_MISSING_ICE_ATTRIBUTES), - ENAME_DECL(CC_CAUSE_NO_MEDIA_CAPABILITY), - ENAME_DECL(CC_CAUSE_NO_M_LINE), - ENAME_DECL(CC_CAUSE_NO_PEERCONNECTION), - ENAME_DECL(CC_CAUSE_NO_SDP), - ENAME_DECL(CC_CAUSE_NULL_POINTER), - ENAME_DECL(CC_CAUSE_SDP_CREATE_FAILED), - ENAME_DECL(CC_CAUSE_SDP_ENCODE_FAILED), - ENAME_DECL(CC_CAUSE_SDP_PARSE_FAILED), - ENAME_DECL(CC_CAUSE_SETTING_ICE_SESSION_PARAMETERS_FAILED), - ENAME_DECL(CC_CAUSE_MAX) - ); - -//define subscriptions_ext_getname(cc_subscriptions_ext_t); -DEFINE_CC_TYPE_NAME_FUNCTION (subscriptions_ext, CC_TYPE, - ENAME_DECL(CC_SUBSCRIPTIONS_KPML_EXT), - ENAME_DECL(CC_SUBSCRIPTIONS_PRESENCE_EXT), - ENAME_DECL(CC_SUBSCRIPTIONS_REMOTECC_EXT), - ENAME_DECL(CC_SUBSCRIPTIONS_REMOTECC_OPTIONSIND_EXT), - ENAME_DECL(CC_SUBSCRIPTIONS_CONFIGAPP_EXT), - ENAME_DECL(CC_SUBSCRIPTIONS_MEDIA_INFO_EXT) - ); - -//define apply_config_result_getname(cc_apply_config_result_t); -DEFINE_CC_TYPE_NAME_FUNCTION (apply_config_result, CC_TYPE, - ENAME_DECL(APPLY_CONFIG_NONE), - ENAME_DECL(APPLY_DYNAMICALLY), - ENAME_DECL(RESTART_NEEDED) - ); - - - diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/ccsdp.c b/media/webrtc/signaling/src/sdp/sipcc/ccsdp.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/ccsdp.c rename to media/webrtc/signaling/src/sdp/sipcc/ccsdp.c diff --git a/media/webrtc/signaling/src/sipcc/include/ccsdp.h b/media/webrtc/signaling/src/sdp/sipcc/ccsdp.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/include/ccsdp.h rename to media/webrtc/signaling/src/sdp/sipcc/ccsdp.h diff --git a/media/webrtc/signaling/src/sipcc/include/ccsdp_rtcp_fb.h b/media/webrtc/signaling/src/sdp/sipcc/ccsdp_rtcp_fb.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/include/ccsdp_rtcp_fb.h rename to media/webrtc/signaling/src/sdp/sipcc/ccsdp_rtcp_fb.h diff --git a/media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_types.h b/media/webrtc/signaling/src/sdp/sipcc/cpr_android_types.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_types.h rename to media/webrtc/signaling/src/sdp/sipcc/cpr_android_types.h diff --git a/media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_types.h b/media/webrtc/signaling/src/sdp/sipcc/cpr_darwin_types.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_types.h rename to media/webrtc/signaling/src/sdp/sipcc/cpr_darwin_types.h diff --git a/media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_types.h b/media/webrtc/signaling/src/sdp/sipcc/cpr_linux_types.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_types.h rename to media/webrtc/signaling/src/sdp/sipcc/cpr_linux_types.h diff --git a/media/webrtc/signaling/src/sipcc/cpr/common/cpr_string.c b/media/webrtc/signaling/src/sdp/sipcc/cpr_string.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/common/cpr_string.c rename to media/webrtc/signaling/src/sdp/sipcc/cpr_string.c diff --git a/media/webrtc/signaling/src/sipcc/cpr/include/cpr_string.h b/media/webrtc/signaling/src/sdp/sipcc/cpr_string.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/include/cpr_string.h rename to media/webrtc/signaling/src/sdp/sipcc/cpr_string.h diff --git a/media/webrtc/signaling/src/sipcc/cpr/include/cpr_strings.h b/media/webrtc/signaling/src/sdp/sipcc/cpr_strings.h old mode 100755 new mode 100644 similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/include/cpr_strings.h rename to media/webrtc/signaling/src/sdp/sipcc/cpr_strings.h diff --git a/media/webrtc/signaling/src/sipcc/cpr/include/cpr_types.h b/media/webrtc/signaling/src/sdp/sipcc/cpr_types.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/include/cpr_types.h rename to media/webrtc/signaling/src/sdp/sipcc/cpr_types.h diff --git a/media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_types.h b/media/webrtc/signaling/src/sdp/sipcc/cpr_win_types.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_types.h rename to media/webrtc/signaling/src/sdp/sipcc/cpr_win_types.h diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h b/media/webrtc/signaling/src/sdp/sipcc/sdp.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp.h rename to media/webrtc/signaling/src/sdp/sipcc/sdp.h diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_access.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_access.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_access.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_access.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_attr.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_attr.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr_access.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr_access.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_base64.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_base64.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_base64.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_base64.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_base64.h b/media/webrtc/signaling/src/sdp/sipcc/sdp_base64.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_base64.h rename to media/webrtc/signaling/src/sdp/sipcc/sdp_base64.h diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_config.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_config.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_config.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_config.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_main.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_main.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_os_defs.h b/media/webrtc/signaling/src/sdp/sipcc/sdp_os_defs.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_os_defs.h rename to media/webrtc/signaling/src/sdp/sipcc/sdp_os_defs.h diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_private.h b/media/webrtc/signaling/src/sdp/sipcc/sdp_private.h similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_private.h rename to media/webrtc/signaling/src/sdp/sipcc/sdp_private.h diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_services_unix.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_services_unix.c old mode 100755 new mode 100644 similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_services_unix.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_services_unix.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_services_win32.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_services_win32.c old mode 100755 new mode 100644 similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_services_win32.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_services_win32.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_token.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_token.c diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_utils.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_utils.c similarity index 100% rename from media/webrtc/signaling/src/sipcc/core/sdp/sdp_utils.c rename to media/webrtc/signaling/src/sdp/sipcc/sdp_utils.c diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h b/media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h deleted file mode 100755 index d7ba0e898b2..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h +++ /dev/null @@ -1,149 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CCPROVIDER_H__ -#define __CCPROVIDER_H__ - -#if defined(__cplusplus) && __cplusplus >= 201103L -typedef struct Timecard Timecard; -#else -#include "timecard.h" -#endif - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_socket.h" -#include "cpr_memory.h" -#include "cpr_errno.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_string.h" -#include "cpr_threads.h" -#include "phone_types.h" -#include "session.h" -#include "fsmdef_states.h" - -#include "cc_constants.h" -#include "ccapi_types.h" -#include "conf_roster.h" - -#define CC_DEVICE_ID 0 -#include "ccapi_service.h" - -typedef enum { - FAILOVER, - FALLBACK, - NO_CUCM_SRST_AVAILABLE, - NONE_AVAIL, -} Cucm_mode_t; - -typedef struct -{ - cc_reg_state_t state; - Cucm_mode_t cucm_mode; - cc_boolean inPreservation; - session_id_t preservID; - unsigned int mode; - unsigned int cause; -} CCAppGlobal_t; - -typedef struct cc_call_log_t_ { - string_t localPartyName; - string_t localPartyNumber; - string_t remotePartyName[2]; - string_t remotePartyNumber[2]; - string_t altPartyNumber[2]; - cc_log_disposition_t logDisp; - cc_call_state_t callState; - time_t startTime; - cc_uint32_t duration; -} cc_call_log_t; - -typedef struct cc_call_info_t_{ - uint32_t ref_count; - session_id_t sess_id; - line_t line; - callid_t id; - uint16_t inst; - cc_call_state_t state; - fsmdef_states_t fsm_state; - cc_call_attr_t attr; - cc_call_type_t type; - cc_call_security_t security; - cc_call_policy_t policy; - unsigned int callref; - int isSelected; - unsigned int log_disp; - string_t clg_name; - string_t clg_number; - string_t alt_number; - string_t cld_name; - string_t cld_number; - string_t orig_called_name; - string_t orig_called_number; - string_t last_redir_name; - string_t last_redir_number; - string_t plcd_name; - string_t plcd_number; - string_t status; - char gci[CC_MAX_GCID]; - cc_int32_t cause; - cc_int32_t vid_dir; - cc_int32_t vid_offer; - cc_boolean is_conf; - cc_boolean ringer_start; - cc_boolean ringer_once; - cc_int32_t ringer_mode; - cc_boolean allowed_features[CCAPI_CALL_CAP_MAX]; - cc_string_t info_package; - cc_string_t info_type; - cc_string_t info_body; - cc_call_log_t call_log; - cc_boolean audio_mute; - cc_boolean video_mute; - cc_call_conference_Info_t call_conference; -} session_data_t; - -typedef enum { - NO_ACTION=0, - RESET_ACTION, - RESTART_ACTION, - RE_REGISTER_ACTION, - STOP_ACTION, - DESTROY_ACTION -} cc_action_t; - -#define CCAPP_SERVICE_CMD 1 -#define CCAPP_CREATE_SESSION 2 -#define CCAPP_CLOSE_SESSION 3 -#define CCAPP_INVOKE_FEATURE 4 -#define CCAPP_SESSION_UPDATE 5 -#define CCAPP_FEATURE_UPDATE 6 -#define CCAPP_UPDATELINES 7 -#define CCAPP_FAILOVER_IND 8 -#define CCAPP_FALLBACK_IND 9 -#define CCAPP_MODE_NOTIFY 10 -#define CCAPP_SHUTDOWN_ACK 11 -#define CCAPP_REG_ALL_FAIL 12 -#define CCAPP_INVOKEPROVIDER_FEATURE 13 -#define CCAPP_SEND_INFO 14 -#define CCAPP_RCVD_INFO 15 -#define CCAPP_LOGOUT_RESET 16 -#define CCAPP_THREAD_UNLOAD 17 -#define CCAPP_SESSION_MGMT 18 - -extern cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId); -extern void ccappSyncSessionMgmt(session_mgmt_t *sessMgmt); -extern void CCApp_prepare_task(); -extern void GSM_prepare_task(); -extern void *findhash(unsigned int key); -extern session_id_t createSessionId(line_t line, callid_t call); -extern void getLineIdAndCallId (line_t *line_id, callid_t *call_id); -extern void ccp_handler(void* msg, int type); -extern session_data_t * getDeepCopyOfSessionData(session_data_t *data); -extern void cleanSessionData(session_data_t *data); -extern cc_call_handle_t ccappGetConnectedCall(); - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.c b/media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.c deleted file mode 100644 index 7395be36059..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.c +++ /dev/null @@ -1,304 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdio.h" -#include -#include "sessionHash.h" -#include "CCProvider.h" -#include "call_logger.h" - - - -void calllogger_init_call_log (cc_call_log_t *log) -{ - log->localPartyName = strlib_empty(); - log->localPartyNumber = strlib_empty(); - log->remotePartyName[0] = strlib_empty(); - log->remotePartyName[1] = strlib_empty(); - log->remotePartyNumber[0] = strlib_empty(); - log->remotePartyNumber[1] = strlib_empty(); - log->altPartyNumber[0] = strlib_empty(); - log->altPartyNumber[1] = strlib_empty(); - log->startTime = 0; - log->duration = 0; - - log->logDisp = CC_LOGD_UNKNWN; - log->callState = MAX_CALL_STATES; -} - -void calllogger_copy_call_log (cc_call_log_t *dest, cc_call_log_t * src) -{ - dest->localPartyName = strlib_copy(src->localPartyName); - dest->localPartyNumber = strlib_copy(src->localPartyNumber); - dest->remotePartyName[0] = strlib_copy(src->remotePartyName[0]); - dest->remotePartyName[1] = strlib_copy(src->remotePartyName[1]); - dest->remotePartyNumber[0] = strlib_copy(src->remotePartyNumber[0]); - dest->remotePartyNumber[1] = strlib_copy(src->remotePartyNumber[1]); - dest->altPartyNumber[0] = strlib_copy(src->altPartyNumber[0]); - dest->altPartyNumber[1] = strlib_copy(src->altPartyNumber[1]); - dest->startTime = src->startTime; - dest->duration = src->duration; - - dest->logDisp = src->logDisp; - dest->callState = src->callState; -} - -void calllogger_free_call_log (cc_call_log_t *log) -{ - strlib_free(log->localPartyName); - strlib_free(log->localPartyNumber); - strlib_free(log->remotePartyName[0]); - strlib_free(log->remotePartyName[1]); - strlib_free(log->remotePartyNumber[0]); - strlib_free(log->remotePartyNumber[1]); - strlib_free(log->altPartyNumber[0]); - strlib_free(log->altPartyNumber[1]); - - calllogger_init_call_log(log); -} - -void calllogger_print_call_log(cc_call_log_t *log) -{ - static const char *fname = "calllogger_print_call_log"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - CCLOG_DEBUG("Remote ID %s:%s %s:%s\n LocalID %s:%s \n alt %s:%s", - log->remotePartyName[0], log->remotePartyNumber[0], - log->remotePartyName[1], log->remotePartyNumber[1], - log->localPartyName, log->localPartyNumber, - log->altPartyNumber[0], log->altPartyNumber[1] ); - CCLOG_DEBUG("state %d \n Disp %d", log->callState, log->logDisp); -} - -/** - * Call logger update to be called placed call num update - */ -void calllogger_setPlacedCallInfo (session_data_t *data) -{ - static const char *fname = "calllogger_setPlacedCallInfo"; - - CCLOG_DEBUG(DEB_F_PREFIX"updating placed number for session %x to %s:%s", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id, - data->cld_name, data->cld_number); - if ( data->call_log.logDisp == CC_LOGD_RCVD ) { return;} - data->call_log.remotePartyName[0] = strlib_copy(data->plcd_name); - data->call_log.remotePartyNumber[0] = strlib_copy(data->plcd_number); - data->call_log.logDisp = CC_LOGD_SENT; - data->call_log.startTime = time(NULL); -} - -/** - * call logger api to be called for log disp update - */ -void calllogger_updateLogDisp (session_data_t *data) -{ - static const char *fname = "calllogger_updateLogDisp"; - - CCLOG_DEBUG(DEB_F_PREFIX"updating log disposition for session %x to %d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id, data->log_disp); - data->call_log.logDisp = data->log_disp; -} - -cc_boolean partyInfoPassedTheNumberFilter (cc_string_t partyString) -{ - static const char *fname = "partyInfoPassedTheNumberFilter"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - // check if partyString is something we should not be logging at this point - // Uris: CfwdALL 105 - // Conference 152 - if (partyString && strlen(partyString) > 1 && - (partyString[1] == 17 || - partyString[1] == 91 || - partyString[1] == 05 || - partyString[1] == 18 || - partyString[1] == 16 || - partyString[1] == 52 )) { - - CCLOG_DEBUG(DEB_F_PREFIX"Filtering out the partyName=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), partyString); - return FALSE; - } - return TRUE; -} - -/** - * partyInfoPassedTheNameFilter - * - * @param partyString String - * @return boolean - */ -cc_boolean partyInfoPassedTheNameFilter(cc_string_t partyString) { - static const char *fname = "partyInfoPassedTheNameFilter"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - // If the name String has Conference, filter it out - if (partyString && strlen(partyString) > 1 && - (partyString[1] == 52 || partyString[1] == 53)) { - CCLOG_DEBUG(DEB_F_PREFIX"Filtering out the partyName=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), partyString); - return FALSE; - } - return TRUE; -} - -static cc_string_t missedCallMask=NULL; -void calllogger_setMissedCallLoggingConfig(cc_string_t mask) { - static const char *fname = "calllogger_setMissedCallLoggingConfig"; - - - CCLOG_DEBUG(DEB_F_PREFIX"Entering... mask=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), mask); - if ( missedCallMask == NULL) { - missedCallMask = strlib_empty(); - } - missedCallMask = strlib_update(missedCallMask, mask); -} - -cc_boolean isMissedCallLoggingEnabled (unsigned int line) -{ - static const char *fname = "isMissedCallLoggingEnabled"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering... mask=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), missedCallMask); - if (missedCallMask == NULL) { - return TRUE; - } - - if ((line > 0) && strlen(missedCallMask) > (line-1)) { - if ( missedCallMask[line-1] == '0' ) { - return FALSE; - } - } - return TRUE; -} - - -void handlePlacedCall (session_data_t *data) -{ - static const char *fname = "handlePlacedCall"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - //populate calling party if not already populated - if ( data->call_log.localPartyNumber == strlib_empty() ) { - data->call_log.localPartyNumber = strlib_update(data->call_log.localPartyNumber, data->clg_number); - data->call_log.localPartyName = strlib_update(data->call_log.localPartyName, data->clg_name); - } - - // first update or update with the same number we update name and number - if ( data->call_log.remotePartyNumber[0] == strlib_empty() || - (data->cld_number[0] != 0 && strncmp(data->call_log.remotePartyNumber[0], - data->cld_number, strlen(data->cld_number)) == 0 )) { - if ( partyInfoPassedTheNameFilter(data->cld_name) && - partyInfoPassedTheNumberFilter(data->cld_number) ) { - data->call_log.remotePartyNumber[0] = strlib_update(data->call_log.remotePartyNumber[0], data->cld_number); - data->call_log.remotePartyName[0] = strlib_update(data->call_log.remotePartyName[0], data->cld_name); - } - } - - // Start the duration count once the call reaches connected state. - if ( data->state == CONNECTED && - data->call_log.startTime == 0 ) { - data->call_log.startTime = time(NULL); - } - - if (data->state == ONHOOK ) { - // only set the duration if the call entered the connected state - if ( data->call_log.startTime != 0 ) { - data->call_log.duration = (cc_uint32_t) (time(NULL) - data->call_log.startTime); - } else { - data->call_log.startTime = time(NULL); - } - } - - data->call_log.callState = data->state; -} - - -void handleMissedOrReceviedCall ( session_data_t *data ) -{ - static const char *fname = "handleMissedOrReceviedCall"; - int line = GET_LINE_ID(data->sess_id); - cc_string_t localName = strlib_empty(), localNumber = strlib_empty(); - cc_string_t remoteName = strlib_empty(), remoteNumber = strlib_empty(); - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (data->type == CC_CALL_TYPE_INCOMING || data->type == CC_CALL_TYPE_FORWARDED ) { - localName = data->cld_name; - localNumber = data->cld_number; - remoteName = data->clg_name; - remoteNumber = data->clg_number; - } else { - localName = data->clg_name; - localNumber = data->clg_number; - remoteName = data->cld_name; - remoteNumber = data->cld_number; - } - - if ( data->call_log.localPartyNumber == strlib_empty() ) { - data->call_log.localPartyNumber = strlib_update(data->call_log.localPartyNumber, localNumber); - data->call_log.localPartyName = strlib_update(data->call_log.localPartyName, localName); - } - - // first update or update with the same number we update name and number - if ( data->call_log.remotePartyNumber[0] == strlib_empty() || - (remoteNumber[0] != 0 && strncmp(data->call_log.remotePartyNumber[0], - remoteNumber, strlen(remoteNumber)) == 0 )) { - data->call_log.remotePartyNumber[0] = strlib_update(data->call_log.remotePartyNumber[0], remoteNumber); - data->call_log.altPartyNumber[0] = strlib_update(data->call_log.altPartyNumber[0], data->alt_number); - if (data->call_log.remotePartyName[0] == strlib_empty() ) { - data->call_log.remotePartyName[0] = strlib_update(data->call_log.remotePartyName[0], remoteName); - } - } else { - // since number doesn't match this is a new leg - data->call_log.remotePartyName[1] = strlib_update(data->call_log.remotePartyName[1], remoteName); - data->call_log.remotePartyNumber[1] = strlib_update(data->call_log.remotePartyNumber[1], remoteNumber); - data->call_log.altPartyNumber[1] = strlib_update(data->call_log.altPartyNumber[1], data->alt_number); - } - - if ( data->state == ONHOOK ) { - if ( data->call_log.callState == RINGIN ) { - data->call_log.startTime = time(NULL); - if (isMissedCallLoggingEnabled(line)) { - data->call_log.logDisp = CC_LOGD_MISSED; - } else { - data->call_log.logDisp = CC_LOGD_DELETE; - } - data->call_log.startTime = time(NULL); - data->call_log.duration = 0; //missed call duration is 0 - } else if ( data->call_log.startTime != 0 ){ - //connected call going onhook update duration - data->call_log.duration = (cc_uint32_t) (time(NULL) - data->call_log.startTime); - } - } - - if ( data->state == CONNECTED && data->call_log.startTime == 0 ) { - data->call_log.logDisp = CC_LOGD_RCVD; - data->call_log.startTime = time(NULL); - } - - data->call_log.callState = data->state; -} - - -/** - * Call logger update to be called on attr or callinfo or state events - */ -void calllogger_update (session_data_t *data) -{ - static const char *fname = "calllogger_update"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - if (data->call_log.logDisp == CC_LOGD_DELETE) { - CCLOG_DEBUG(DEB_F_PREFIX"log disposition set to delete. Ignoring call logging for sess_id=%x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id); - } - - if (data->call_log.logDisp == CC_LOGD_RCVD || data->call_log.logDisp == CC_LOGD_MISSED || - data->type == CC_CALL_TYPE_INCOMING || data->type == CC_CALL_TYPE_FORWARDED ) { - handleMissedOrReceviedCall(data); - } else if ( data->call_log.logDisp == CC_LOGD_SENT || - data->type == CC_CALL_TYPE_OUTGOING ) { - handlePlacedCall (data); - } - -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.h b/media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.h deleted file mode 100644 index 6ccec2e274b..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.h +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CALL_LOGGER_H__ -#define __CALL_LOGGER_H__ - -#include "cc_types.h" -#include "CCProvider.h" - -void calllogger_init_call_log(cc_call_log_t *log); -void calllogger_copy_call_log(cc_call_log_t *dest, cc_call_log_t * src); -void calllogger_free_call_log(cc_call_log_t *log); -void calllogger_print_call_log(cc_call_log_t *log); -void calllogger_setPlacedCallInfo(session_data_t *data); -void calllogger_updateLogDisp(session_data_t *data); -void calllogger_setMissedCallLoggingConfig(cc_string_t mask); -void calllogger_update(session_data_t *data); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.c b/media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.c deleted file mode 100644 index 888b700e841..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.c +++ /dev/null @@ -1,281 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "capability_set.h" -#include "CCProvider.h" - -// -------------------------------------------------------------------------------- -// Data Structures Used to Store the Capability Set Information -// Settings on kept on a per call state, per feature basis. -// Includes all general endpoint capabilities, plus fcp-controlled ones -// -------------------------------------------------------------------------------- -static cc_boolean capability_set[MAX_CALL_STATES][CCAPI_CALL_CAP_MAX]; -static cc_boolean capability_idleset[CCAPI_CALL_CAP_MAX]; - - -// -------------------------------------------------------------------------------- -// Data Structures Used to Store the Parsed FCP information from UCM/FCP file -// (after parse will be used to selectively set capabilities in the above also) -// -------------------------------------------------------------------------------- - -// maximum number of features -#define FCP_FEATURE_MAX 9 - -char g_fp_version_stamp[MAX_FP_VERSION_STAMP_LEN]; -static cc_feature_control_policy_info_t cc_feat_control_policy[FCP_FEATURE_MAX]; -static ccapi_call_capability_e cc_fcp_id_to_capability_map[FCP_FEATURE_MAX+1]; // 0th entry of map is not used/null entry - - -static const unsigned int CALL_FORWARD_ALL_FCP_INDEX = 1; -static const unsigned int CONFERENCE_LIST_FCP_INDEX = 4; -static const unsigned int SPEED_DIAL_FCP_INDEX = 5; -static const unsigned int CALL_BACK_FCP_INDEX = 6; -static const unsigned int REDIAL_FCP_INDEX = 7; - -static int fcp_index = -1; - -// -------------------------------------------------------------------------------- - - -/* - * capset_set_fcp_forwardall - sets the fcp-controlled call forward all feature - * - */ -static void capset_set_fcp_forwardall (cc_boolean state) -{ - CONFIG_DEBUG(DEB_F_PREFIX"FCP Setting CALLFWD Capability to [%d]", DEB_F_PREFIX_ARGS(JNI, "capset_set_fcp_forwardall"), (unsigned int)state); - - capability_idleset[CCAPI_CALL_CAP_CALLFWD] = state; - capability_set[OFFHOOK][CCAPI_CALL_CAP_CALLFWD] = state; -} - -/* - * capset_set_fcp_redial - sets the fcp-controlled redial feature - * - */ -static void capset_set_fcp_redial (cc_boolean state) -{ - CONFIG_DEBUG(DEB_F_PREFIX"FCP Setting REDIAL capability to [%d]", DEB_F_PREFIX_ARGS(JNI, "capset_set_fcp_redial"), (unsigned int)state); - - capability_idleset[CCAPI_CALL_CAP_REDIAL] = state; - capability_set[OFFHOOK][CCAPI_CALL_CAP_REDIAL] = state; - capability_set[ONHOOK][CCAPI_CALL_CAP_REDIAL] = state; -} - -// -------------------------------------------------------------------------------- - - -/* - * fcp_set_index - sets a given feture index number (from fcp xml file), maps it to the internal - * call capability, and sets the appropriate state-based capability for the feature index - * - */ -static void fcp_set_index (unsigned int fcpCapabilityId, cc_boolean state) -{ - ccapi_call_capability_e capabilityId = CCAPI_CALL_CAP_MAX; - - // range check the capability index - if ((fcpCapabilityId <= 0) || (fcpCapabilityId > FCP_FEATURE_MAX)) - { - CONFIG_ERROR(CFG_F_PREFIX "Unable to set capability of unknown feature [%d] in FCP", "fcp_set_index", fcpCapabilityId); - return; - } - - // convert the fcp index to an fcp capability id - capabilityId = cc_fcp_id_to_capability_map[fcpCapabilityId]; - - - // based on the capability id, invoke the appropate method specific to that capability - switch (capabilityId) - { - case CCAPI_CALL_CAP_CALLFWD : capset_set_fcp_forwardall (state); break; - case CCAPI_CALL_CAP_REDIAL : capset_set_fcp_redial (state); break; - default : - { - CONFIG_ERROR(CFG_F_PREFIX "Unable to update settings for capability [%d]", "fcp_set_index", (int)capabilityId); - break; - } - } -} - -/* - * capset_init - initialize the internal capability data structures to defaults - * - */ -static void capset_init () -{ - // initialize the 4 tables related to capability set to false - memset(capability_idleset, 0, sizeof(capability_idleset)); - memset(capability_set, 0, sizeof(capability_set)); - - // ---------------------------------------------------------------------- - // FCP based capabilities - // ---------------------------------------------------------------------- - - CONFIG_DEBUG(DEB_F_PREFIX"FCP Initializing Capabilities to default", DEB_F_PREFIX_ARGS(JNI, "capset_init")); - - // ---------------------------------------------------------------------- - // Non-FCP-based Capabilities - // ---------------------------------------------------------------------- - - // Now, set all the non-FCP based capabilities to appropriate default settings - // (some of which may be enabled by default) - - capability_idleset[CCAPI_CALL_CAP_NEWCALL] = TRUE; - - // call-state based settings - // offhook - capability_set[OFFHOOK][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // onhook - capability_set[ONHOOK][CCAPI_CALL_CAP_NEWCALL] = TRUE; - - // ringout - capability_set[RINGOUT][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // ringing - capability_set[RINGIN][CCAPI_CALL_CAP_ANSWER] = TRUE; - - // proceed - capability_set[PROCEED][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // connected - capability_set[CONNECTED][CCAPI_CALL_CAP_ENDCALL] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_HOLD] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_TRANSFER] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_CONFERENCE] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_SELECT] = TRUE; - - // hold - capability_set[HOLD][CCAPI_CALL_CAP_RESUME] = TRUE; - capability_set[REMHOLD][CCAPI_CALL_CAP_RESUME] = TRUE; - - // busy - capability_set[BUSY][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // reorder - capability_set[REORDER][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // dialing - capability_set[DIALING][CCAPI_CALL_CAP_ENDCALL] = TRUE; - capability_set[DIALING][CCAPI_CALL_CAP_DIAL] = TRUE; - capability_set[DIALING][CCAPI_CALL_CAP_SENDDIGIT] = TRUE; - capability_set[DIALING][CCAPI_CALL_CAP_BACKSPACE] = TRUE; - - // holdrevert - capability_set[HOLDREVERT][CCAPI_CALL_CAP_ANSWER] = TRUE; - - // preservation - capability_set[PRESERVATION][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // waiting for digits - capability_set[WAITINGFORDIGITS][CCAPI_CALL_CAP_SENDDIGIT] = TRUE; - capability_set[WAITINGFORDIGITS][CCAPI_CALL_CAP_BACKSPACE] = TRUE; -} - - -/* - * capset_get_idleset - get the set of features associated with idle state - * - */ -void capset_get_idleset ( cc_cucm_mode_t mode, cc_boolean features[]) -{ - static const char fname[] = "capset_get_idleset"; - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"updating idleset", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=0;i < CCAPI_CALL_CAP_MAX; i++) { - CCAPP_DEBUG(DEB_F_PREFIX"updating line features %d=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), i, capability_idleset[i]); - features[i] = capability_idleset[i]; - } - -} - -/* - * capset_get_allowed_features - get the set of features - * - */ -void capset_get_allowed_features ( cc_cucm_mode_t mode, cc_call_state_t state, cc_boolean features[]) -{ - static const char fname[] = "capset_get_allowed_features"; - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"updating idleset", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=0;i < CCAPI_CALL_CAP_MAX; i++) { - features[i] = capability_set[state][i]; - } - -} - -// -------------------------------------------------------------------------------------------------------- -// ---------------------------- XML Parse Logic for Feature Control Policy -------------------------------- -// -------------------------------------------------------------------------------------------------------- - -/* - * fcp_set_capabilities - updates the capabilities structure, based on the now parsed information - * from fcp xml file - * - */ - -static void fcp_set_capabilities() -{ - int my_fcp_index = 0; - - if ( (fcp_index+1) >= FCP_FEATURE_MAX) { - fcp_index = (FCP_FEATURE_MAX -1); - CONFIG_ERROR(CFG_F_PREFIX "Received more than the maximum supported features [%d] in FCP", "fcp_set_capabilities", FCP_FEATURE_MAX); - - } - // loop over all the FCP features parsed, and for each one, based on ID, and enabled settings, - // update the corresponding call capability flags - for (my_fcp_index = 0; my_fcp_index <= fcp_index; my_fcp_index++) - { // set the capability if fcp file has it marked as 'enabled' - fcp_set_index(cc_feat_control_policy[my_fcp_index].featureId, (cc_feat_control_policy[my_fcp_index].featureEnabled == TRUE)); - } -} - -/* - * fcp_init - initialize the data structure used to store the fcp parse info - * - */ -static void fcp_init() -{ - // master index; set to null - fcp_index = -1; - - // initialize the map of fcp xml feature indexes to internal call capabilities - cc_fcp_id_to_capability_map[CALL_FORWARD_ALL_FCP_INDEX] = CCAPI_CALL_CAP_CALLFWD; - cc_fcp_id_to_capability_map[REDIAL_FCP_INDEX] = CCAPI_CALL_CAP_REDIAL; - - // initialize the capability set data structures - capset_init(); - - // initialize the version - g_fp_version_stamp[0] = '\0'; -} - -/* - * capset_set_fcp_forwardall - sets the fcp-controlled call forward all feature - * - */ -int fcp_init_template (const char* fcp_plan_string) -{ - fcp_init(); - - if (fcp_plan_string == NULL) - { // set up the default fcp - return (0); - } - - // update the fcp capabilities structure, based on the parsed feature information - fcp_set_capabilities(); - - return (0); -} -// ---------------------------- End Of XML Parse Logic for Feature Control Policy -------------------------- diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.h b/media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.h deleted file mode 100644 index bad517a70a8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.h +++ /dev/null @@ -1,33 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CC_CAPABILITY_SET_H_ -#define _CC_CAPABILITY_SET_H_ - -#include "ccapi_types.h" - -extern void capset_get_idleset( cc_cucm_mode_t mode, cc_boolean features[]); -extern void capset_get_allowed_features( cc_cucm_mode_t mode, cc_call_state_t state, cc_boolean features[]); - -// FCP (feature control policy) methods -int fcp_init_template (const char* fcp_plan_string); - -// FCP Definitions -#define FCP_MAX_SIZE 0x5000 -#define FCP_FEATURE_NAME_MAX 24 -#define MAX_FP_VERSION_STAMP_LEN (64+1) - -extern char g_fp_version_stamp[MAX_FP_VERSION_STAMP_LEN]; - - -// for each feature in the XML FCP file, we'll receive the -// feature name, featureId, and whether or not it is enabled -typedef struct cc_feature_control_policy_info_t_ -{ - char featureName[FCP_FEATURE_NAME_MAX]; - unsigned int featureId; - cc_boolean featureEnabled; -} cc_feature_control_policy_info_t; - -#endif /* _CC_CAPABILITY_SET_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_blf.c b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_blf.c deleted file mode 100644 index 49c500248ab..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_blf.c +++ /dev/null @@ -1,50 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_blf.h" -#include "pres_sub_not_handler.h" - -/** - * Initialize the BLF stack - * @return - */ -int CC_BLF_init() { - pres_sub_handler_initialized(); - return CC_SUCCESS; -} -/** - * Start BLF subscription - * @param request_id the request id - * @param duration the subscription duration - * @param watcher the name of subscription watcher - * @param presentity - * @param app_id the application id for the BLF - * @param feature_mask - * @return void - */ -void CC_BLF_subscribe(int request_id, - int duration, - const char *watcher, - const char *presentity, - int app_id, - cc_blf_feature_mask_t feature_mask) { - pres_get_state(request_id, duration, watcher, presentity, app_id, feature_mask); -} -/** - * Unsubscribe the BLF subscription - * @param request_id the request id - * @return void - */ -void CC_BLF_unsubscribe(int request_id) { - pres_terminate_req(request_id); -} - -/** - * Unsubscribe all BLF subscription - * @return void - */ -void CC_BLF_unsubscribe_All() { - pres_terminate_req_all(); -} - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c deleted file mode 100644 index 01464d47831..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c +++ /dev/null @@ -1,531 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "timecard.h" -#include "cc_call_feature.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "sessionTypes.h" -#include "lsm.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "ccapi.h" -#include "ccapp_task.h" -#include "sessionHash.h" -#include "cpr_rand.h" - -extern cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId); - -/** - * Internal method: create call handle - * @param line - * @paran call_id - */ -cc_call_handle_t cc_createCallHandle(cc_lineid_t line, cc_callid_t call_id) -{ - return (CREATE_CALL_HANDLE(line, call_id)); -} - -/** - * Internal method: assign a valid call id. - * @param line_id line number - * @param call_id call id - * @return void - */ -void cc_getLineIdAndCallId (cc_lineid_t *line_id, cc_callid_t *call_id) -{ - // assign proper line_id and call_id if not already there - if ((*line_id) == 0 || (*line_id) == CC_ALL_LINES) { - /* - * If the filter is the All Calls Complex Filter and the primary line - * is at its configured call capacity, the next available line should - * be used. In this scenario, sessionUI/Mgr send the line_id as zero. - */ - (*line_id) = lsm_get_available_line(FALSE); - } - - if ((*call_id) == 0) { - (*call_id) = cc_get_new_call_id(); - } -} - -/** - * Invoke a call feature. - */ -cc_return_t cc_invokeFeature(cc_call_handle_t call_handle, group_cc_feature_t featureId, cc_sdp_direction_t video_pref, string_t data) { - session_feature_t callFeature; - callFeature.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + call_handle; - callFeature.featureID = featureId; - callFeature.featData.ccData.state = video_pref; - - CCAPP_DEBUG(DEB_F_PREFIX"cc_invokeFeature:sid=%d, line=%d, cid=%d, fid=%d, video_pref=%s data=%s", - DEB_F_PREFIX_ARGS("cc_call_feature", "cc_invokeFeature"), - callFeature.session_id, - GET_LINE_ID(call_handle), - GET_CALL_ID(call_handle), - featureId, SDP_DIRECTION_PRINT(video_pref), - ((featureId == CC_FEATURE_KEYPRESS) ? "...": data)); - - switch (featureId) { - case CC_FEATURE_KEYPRESS: - case CC_FEATURE_DIALSTR: - case CC_FEATURE_SPEEDDIAL: - case CC_FEATURE_BLIND_XFER_WITH_DIALSTRING: - case CC_FEATURE_END_CALL: - case CC_FEATURE_B2BCONF: - case CC_FEATURE_CONF: - case CC_FEATURE_XFER: - case CC_FEATURE_HOLD: - callFeature.featData.ccData.info = strlib_malloc(data, strlen(data)); - callFeature.featData.ccData.info1 = NULL; - break; - - default: - callFeature.featData.ccData.info = NULL; - callFeature.featData.ccData.info1 = NULL; - break; - } - - if (ccappTaskPostMsg(CCAPP_INVOKE_FEATURE, &callFeature, sizeof(session_feature_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG(DEB_F_PREFIX"ccappTaskSendMsg failed", - DEB_F_PREFIX_ARGS("cc_call_feature", "cc_invokeFeature")); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/***********************************Basic Call Feature Control Methods************************************ - * This section defines all the call related methods that an upper layer can use to control - * a call in progress. - */ - -/** - * Used to create any outgoing call regular call. The incoming/reverting/consultation call will be - * created by the stack. It creates a call place holder and initialize the memory for a call. An user needs - * other methods to start the call, such as the method OriginateCall, etc - * @param line line number that is invoked and is assigned - * @return call handle wich includes the assigned line and call id - */ -cc_call_handle_t CC_createCall(cc_lineid_t line) { - static const char fname[] = "CC_CreateCall"; - //Create call handle to initialize the memory. - cc_call_handle_t call_handle = CC_EMPTY_CALL_HANDLE; - cc_lineid_t lineid = line; - cc_callid_t callid = CC_NO_CALL_ID; - - - //Assign line and call id. - cc_getLineIdAndCallId(&lineid, &callid); - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, callid, lineid, fname)); - - if (lineid == CC_NO_LINE) { - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return call_handle; - } - - call_handle = cc_createCallHandle(lineid, callid); - - return call_handle; -} - -/** - * Start the call that was created. - * @param the call handle - * @return SUCCESS or FAILURE - */ - /*move it up...*/ -cc_return_t CC_CallFeature_originateCall(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_originateCall:"; - //CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - // GET_LINE_ID(call_handle), fname)); - CCAPP_DEBUG(DEB_F_PREFIX"CC_CallFeature_originateCall:cHandle=%d", - DEB_F_PREFIX_ARGS("cc_call_feature", fname), - call_handle); - return cc_invokeFeature(call_handle, CC_FEATURE_OFFHOOK, video_pref, NULL); -} - -/** - * Terminate or end a normal call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_terminateCall(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_TerminateCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_ONHOOK, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Answer an incoming or reverting call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_answerCall(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_AnswerCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_ANSWER, video_pref, NULL); -} - -/** - * Send a keypress to a call, it could be a single digit. - * @param call handle - * @param cc_digit digit pressed - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_sendDigit(cc_call_handle_t call_handle, cc_digit_t cc_digit) { - static const char fname[] = "CC_CallFeature_SendDigit"; - char digit; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - //Demote to eliminate the endian issue - digit = cc_digit; - return cc_invokeFeature(call_handle, CC_FEATURE_KEYPRESS, CC_SDP_MAX_QOS_DIRECTIONS, (string_t)&digit); -} - -/** - * Send a backspace action. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_backSpace(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_BackSpace"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_BKSPACE, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Send a dial digit string on an active call, e.g."9191234567". - * @param call handle - * @param numbers dialed string - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_dial(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref, const string_t numbers) { - static const char fname[] = "CC_CallFeature_Dial"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - if (cpr_strcasecmp(numbers, "DIAL") == 0) { - return cc_invokeFeature(call_handle, CC_FEATURE_DIAL, video_pref, numbers); - } - - return cc_invokeFeature(call_handle, CC_FEATURE_DIALSTR, video_pref, numbers); -} - -/** - * Initiate a speed dial. - * @param call handle - * @param callid call id - * @param speed dial numbers. - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_speedDial(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref, const string_t speed_dial_number) { - static const char fname[] = "CC_CallFeature_SpeedDial"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_SPEEDDIAL, video_pref, speed_dial_number); -} - -/** - * Initiate a BLF call pickup. - * @param call handle - * @param speed dial number configured. - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_blfCallPickup(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref, const string_t speed_dial_number) { - static const char fname[] = "CC_CallFeature_BLFCallPickup"; - cc_return_t ret = CC_SUCCESS; - string_t blf_sd = strlib_malloc(CISCO_BLFPICKUP_STRING, sizeof(CISCO_BLFPICKUP_STRING)); - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - blf_sd = strlib_append(blf_sd, "-"); - blf_sd = strlib_append(blf_sd, speed_dial_number); - - ret = cc_invokeFeature(call_handle, CC_FEATURE_SPEEDDIAL, video_pref, blf_sd); - //free memory - strlib_free(blf_sd); - return ret; -} - -/** - * Redial the last dial numbers. - * @param call handle - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - * @Notice: if there is no active dial made, this method should not be called. - */ -cc_return_t CC_CallFeature_redial(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_Redial"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_REDIAL, video_pref, NULL); -} - -/** - * Update a media capability for a call. - * @param call_handle - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_updateCallMediaCapability(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_updateCallMediaCapability"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_UPD_SESSION_MEDIA_CAP, video_pref, NULL); -} - -/** - * Make a call forward all on particular line - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_callForwardAll(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_CallForwardAll"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_CFWD_ALL, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Resume a held call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_resume(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_Resume"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_RESUME, video_pref, NULL); -} - -/** - * End a consultation call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_endConsultativeCall(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_EndConsultativeCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_END_CALL, CC_SDP_MAX_QOS_DIRECTIONS, "ACTIVECALLS"); -} - -/** - * Initiate a conference. Steps to make a conference or transfer: - * 1. Create a call handle, e.g. chandle1. - * 2. Start the call on this call handle. - * 3. When the call is answered, invoke: - * CC_CallFeature_Conference(chandle1, FALSE, CC_EMPTY_CALL_HANDLE) to start a conference operation. - * 4. Upon receiving the consultative call (cHandle2) created from pSipcc system, - * invoke: - * CC_CallFeature_Dial(cHandle2) - * to dial the consultative call. - * 5. When the consultative call is in ringout or connected state, invoke: - * CC_CallFeature_Conference(cHandle2, FALSE, CC_EMPTY_CALL_HANDLE) to - * finish the conference. - * Note: 1. in the step 4, a user could kill the consultative call and pickup a hold call (not the parent call that - * initiated the conference). In this scenario, a parent call handle should be supplied. - * For instance, - * CC_CallFeature_Conference(cHandle2, FALSE, cHandle1) - * 2. If it's a B2bConf, substitute the "FALSE" with "TRUE" - * - * @param call_handle the call handle for - * 1. the original connected call. - * 2. the consultative call or a held call besides the parent call initiated the transfer. This is used - * on the second time to finish the transfer. - * @param is locall conference or not. If it's a local conference, it's a b2bconf. - * @param parent_call_handle if supplied, it will be the targeted parent call handle, which initiated the conference. - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_conference(cc_call_handle_t call_handle, - boolean is_local, - cc_call_handle_t parent_call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_Conference"; - char call_handle_str[10]; - cc_return_t ret = CC_SUCCESS; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (parent_call_handle == CC_EMPTY_CALL_HANDLE) { - if (is_local == FALSE) { - return cc_invokeFeature(call_handle, CC_FEATURE_B2BCONF, video_pref, ""); - } else { - return cc_invokeFeature(call_handle, CC_FEATURE_CONF, video_pref, ""); - } - } else { - cc_call_handle_t parent = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + parent_call_handle; - string_t parent_call_handle_str; - snprintf(call_handle_str, sizeof(call_handle_str), "%d", parent); - parent_call_handle_str = strlib_malloc(call_handle_str, strlen(call_handle_str)); - - if (is_local == FALSE) { - ret = cc_invokeFeature(call_handle, CC_FEATURE_B2BCONF, video_pref, parent_call_handle_str); - } else { - ret = cc_invokeFeature(call_handle, CC_FEATURE_CONF, video_pref, parent_call_handle_str); - } - strlib_free(parent_call_handle_str); - return ret; - } -} - -/** - * Initiate a call transfer. Please refer to Conference feature. - * @param call_handle the call handle for - * 1. the original connected call. - * 2. the consultative call or a held call besides the parent call initiated the transfer. This is used - * on the second time to finish the transfer. - * @param parent_call_handle if supplied, it will be the parent call handle, which initiated the transfer. - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_transfer(cc_call_handle_t call_handle, cc_call_handle_t parent_call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_transfer"; - char call_handle_str[10]; - cc_return_t ret = CC_SUCCESS; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (parent_call_handle == CC_EMPTY_CALL_HANDLE) { - return cc_invokeFeature(call_handle, CC_FEATURE_XFER, video_pref, ""); - } else { - cc_call_handle_t parent = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + parent_call_handle; - string_t parent_call_handle_str; - snprintf(call_handle_str, sizeof(call_handle_str), "%d", parent); - parent_call_handle_str = strlib_malloc(call_handle_str, strlen(call_handle_str)); - - ret = cc_invokeFeature(call_handle, CC_FEATURE_XFER, video_pref, parent_call_handle_str); - strlib_free(parent_call_handle_str); - return ret; - } -} - -/** - * Put a connected call on hold. - * @param call handle - * @param reason the reason to hold. The following values should be used. - * CC_HOLD_REASON_NONE, - * CC_HOLD_REASON_XFER, //Hold for transfer - * CC_HOLD_REASON_CONF, //Hold for conference - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_holdCall(cc_call_handle_t call_handle, cc_hold_reason_t reason) { - static const char fname[] = "CC_CallFeature_HoldCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - switch (reason) { - case CC_HOLD_REASON_XFER: - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, "TRANSFER"); - case CC_HOLD_REASON_CONF: - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, "CONFERENCE"); - case CC_HOLD_REASON_SWAP: - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, "SWAP"); - default: - break; - } - - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, ""); -} - -/********************************End of basic call feature methods******************************************/ - -/*************************************Additional call feature methods*************************************** - * - */ - -/** - * Join a call. - * @param call_handle call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_b2bJoin(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_b2bJoin"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_B2B_JOIN, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Initiate a direct transfer - * @param call_handle the call handle for the call to initialize a transfer - * @param target_call_handle the call handle for the target transfer call. - * @retrun SUCCESS or FAILURE. If the target call handle is empty, a FAILURE will be returned. - */ -cc_return_t CC_CallFeature_directTransfer(cc_call_handle_t call_handle, - cc_call_handle_t target_call_handle) { - static const char fname[] = "CC_CallFeature_directTransfer"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (target_call_handle == CC_EMPTY_CALL_HANDLE) { - CCAPP_DEBUG(DEB_L_C_F_PREFIX"target call handle is empty.", DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - return CC_FAILURE; - } - return CC_CallFeature_transfer(call_handle, target_call_handle, CC_SDP_MAX_QOS_DIRECTIONS); -} - -/** - * Initiate a join across line - * @param call_handle the call handle for the call that initializes a join across line (conference). - * @param target_call_handle the call handle for the call will be joined. - */ -cc_return_t CC_CallFeature_joinAcrossLine(cc_call_handle_t call_handle, cc_call_handle_t target_call_handle) { - static const char fname[] = "CC_CallFeature_joinAcrossLine"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (target_call_handle == CC_EMPTY_CALL_HANDLE) { - CCAPP_DEBUG(DEB_L_C_F_PREFIX"target call handle is empty.", DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - return CC_FAILURE; - } - return CC_CallFeature_conference(call_handle, TRUE, target_call_handle, CC_SDP_MAX_QOS_DIRECTIONS); -} - -/** - * Select or locked a call. - * @param call_handle call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_select(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_select"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_SELECT, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Cancel a call feature, e.g. when the consultative call is connected and the - * user wishes not to make the conference, thie method can be invoked. - * @param call_handle call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_cancelXfrerCnf(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_cancelXfrerCnf"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_CANCEL, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -void CC_CallFeature_mute(boolean mute) { -} - -void CC_CallFeature_speaker(boolean mute) { -} - -cc_call_handle_t CC_CallFeature_getConnectedCall() { - return ccappGetConnectedCall(); -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_config.c b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_config.c deleted file mode 100644 index 5a6a5623527..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_config.c +++ /dev/null @@ -1,154 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_config.h" -#include "CCProvider.h" -#include "phone_debug.h" -#include "cpr_types.h" -#include "dialplan.h" -#include "capability_set.h" -#include "configmgr.h" -#include "dialplanint.h" -#include "ccapp_task.h" -#include "cc_device_manager.h" -#include "config_api.h" - -extern int config_parser_main( char *config, int complete_config); -/** - * Set the maximum line available for registration - * @param lines the maximum line could be configured. - * @return - */ -int CC_Config_SetAvailableLines(cc_lineid_t lines) { - ccappTaskPostMsg(CCAPP_UPDATELINES, &lines, sizeof(unsigned short), CCAPP_CCPROVIER); - return CC_SUCCESS; -} - -/** - * The following section defines the configuration methods. - */ -/** - * Defines the CFGID parameter setting methods. - * see cfgid.h for all possible configuration parameters - * @todo - */ -void CC_Config_setIntValue(int cfgid, int value) { - config_set_value(cfgid, &value, sizeof(int)); - return; -} - -void CC_Config_setBooleanValue(int cfgid, cc_boolean value) { - int temp = (int) value; - - // For Now, convert all numeric parameters to Integer. This simplifies - // the required SIP and GSM code changes. We will go to the right size - // when we implement the "full" JNI. - - // config_set_value(cfg_id, &bool_value, sizeof(boolean)); - config_set_value(cfgid, &temp, sizeof(int)); - return; -} - -void CC_Config_setStringValue(int cfgid, const char* value) { - config_set_string(cfgid, (char *) value); - return; -} - -void CC_Config_setByteValue(int cfgid, unsigned char value) { - int temp = (int) value; - -// For Now, convert all numeric parameters to Integer. This simplifies -// the required SIP and GSM code changes. We will go to the right size -// when we implement the "full" JNI. - -// config_set_value(cfg_id, &byte_value, sizeof(unsigned char)); - config_set_value(cfgid, &temp, sizeof(int)); - return; -} - -void CC_Config_setArrayValue(int cfgid, char *byte_array, int length) { - unsigned char *byte_ptr; - int i; - - byte_ptr = cpr_malloc(length); - if (byte_ptr == NULL) { - TNP_DEBUG(DEB_F_PREFIX"setPropertyCacheByteArray():malloc failed.", DEB_F_PREFIX_ARGS(JNI, "nSetPropertyCacheByteArray")); - return; - } - - for (i = 0; i < length; i++) { - byte_ptr[i] = (unsigned char) byte_array[i]; - } - config_set_value(cfgid, byte_ptr, length); - cpr_free(byte_ptr); - - return; -} - -/** - * Set the dialplan file - * @param dial_plan_string the dial plan content string - * @param length the length of dial plan string, the maximum size will be 0x2000. - * @return string dial plan version stamp - */ -char* CC_Config_setDialPlan(const char *dial_plan_string, int length) { - const char fname[] = "CC_Config_setDialPlan"; - int ret; - - /** - * If the string is null, empty or oversized, we will reset the dial - * plan by setting the length to 0. - */ - if (dial_plan_string == NULL || length == 0 || length >= DIALPLAN_MAX_SIZE) { - TNP_DEBUG(DEB_F_PREFIX"Setting NULL dialplan string (length [%d] is 0, or length is larger than maximum [%d])", - DEB_F_PREFIX_ARGS(JNI, fname), length, DIALPLAN_MAX_SIZE); - - dp_init_template (NULL, 0); - return (NULL); - } - - ret = dp_init_template(dial_plan_string, length); - TNP_DEBUG(DEB_F_PREFIX"Parsed dial_plan_string. Version=[%s], Length=[%d]", DEB_F_PREFIX_ARGS(JNI, fname), g_dp_version_stamp, length); - if (ret != 0) - { - return (NULL); - } - - return (g_dp_version_stamp); -} - -/** - * Set the feature control plan - * @param fcp plan string - * @param length the length of fcp string - * @return string feature version stamp - */ - -char* CC_Config_setFcp(const char *fcp_plan_string, int len) { - const char fname[] = "CC_Config_setFcp"; - int ret = 0; - - /** - * If the string is null, return null (version) - */ - - TNP_DEBUG(DEB_F_PREFIX"FCP Parsing FCP doc", DEB_F_PREFIX_ARGS(JNI, fname)); - if (fcp_plan_string == NULL) - { - TNP_DEBUG(DEB_F_PREFIX"Null FCP xml document", - DEB_F_PREFIX_ARGS(JNI, fname)); - - fcp_init_template (NULL); - return (NULL); - } - - ret = fcp_init_template (fcp_plan_string); - TNP_DEBUG(DEB_F_PREFIX"Parsed FCP xml. Version=[%s]", DEB_F_PREFIX_ARGS(JNI, fname), g_fp_version_stamp); - if (ret != 0) - { - return (NULL); - } - - return (g_fp_version_stamp); -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_feature.c b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_feature.c deleted file mode 100644 index 83225e70603..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_feature.c +++ /dev/null @@ -1,62 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_device_feature.h" -#include "sessionConstants.h" -#include "sessionTypes.h" -#include "CCProvider.h" -#include "phone_debug.h" -#include "ccapp_task.h" - -/** - * Internal method - */ -void cc_invokeDeviceFeature(session_feature_t *feature) { - - if (ccappTaskPostMsg(CCAPP_INVOKEPROVIDER_FEATURE, feature, - sizeof(session_feature_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG(DEB_F_PREFIX"cc_invokeDeviceFeature failed", - DEB_F_PREFIX_ARGS("cc_device_feature", "cc_invokeDeviceFeature")); - } - -} - -void CC_DeviceFeature_supportsVideo(boolean enable) { - session_feature_t feat; - - feat.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT); - feat.featureID = DEVICE_SUPPORTS_NATIVE_VIDEO; - feat.featData.ccData.info = NULL; - feat.featData.ccData.info1 = NULL; - feat.featData.ccData.state = enable; - cc_invokeDeviceFeature(&feat); -} - -/** - * Enable video/camera. - * @param enable true or false - * @return void - */ -void CC_DeviceFeature_enableVideo(boolean enable) { - session_feature_t feat; - - feat.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT); - feat.featureID = DEVICE_ENABLE_VIDEO; - feat.featData.ccData.info = NULL; - feat.featData.ccData.info1 = NULL; - feat.featData.ccData.state = enable; - cc_invokeDeviceFeature(&feat); -} - -void CC_DeviceFeature_enableCamera(boolean enable) { - session_feature_t feat; - - feat.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT); - feat.featureID = DEVICE_ENABLE_CAMERA; - feat.featData.ccData.info = NULL; - feat.featData.ccData.info1 = NULL; - feat.featData.ccData.state = enable; - cc_invokeDeviceFeature(&feat); -} - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.c b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.c deleted file mode 100644 index 35a11b4e4ee..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.c +++ /dev/null @@ -1,593 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_constants.h" -#include "session.h" -#include "ccSession.h" -#include "scSession.h" -#include "cpr_types.h" -#include "cpr_string.h" -#include "phone_debug.h" -#include "sessuri.h" -#include "config_api.h" -#include "CCProvider.h" -#include "ccapp_task.h" -#include "cc_device_manager.h" -#include "ccapi_service.h" -#include "cc_service.h" -#include "subscription_handler.h" -#include "ccapi_snapshot.h" -#include "util_string.h" - - -#define STARTUP_NORMAL 0 -#define STARTUP_UNSPECIFIED 1 -#define SHUTDOWN_NORMAL 2 -#define SHUTDOWN_UNSPECIFIED 3 -#define SHUTDOWN_VERMISMATHC 4 -#define RSP_TYPE_COMPLETE 5 - - -mgmt_state_t mgmtState = MGMT_STATE_IDLE; -//int parse_config_properties (int device_handle, const char *device_name, const char *cfg, int from_memory); -static boolean isStartRequestPending = FALSE; -static boolean isServiceStopped = TRUE; - -extern cc_boolean is_action_to_be_deferred(cc_action_t action); - - -char *mgmt_event_to_str (int evt) { - - switch (evt) { - case EV_CC_CREATE: - return "EV_CC_CREATE"; - case EV_CC_START: - return "EV_CC_START"; - case EV_CC_CONFIG_RECEIVED: - return "EV_CC_CONFIG_RECEIVED"; - case EV_CC_DO_SOFT_RESET: - return "EV_CC_DO_SOFT_RESET"; - case EV_CC_INSERVICE: - return "EV_CC_INSERVICE"; - case EV_CC_OOS_FAILOVER: - return "EV_CC_OOS_FAILOVER"; - case EV_CC_OOS_FALLBACK: - return "EV_CC_OOS_FALLBACK"; - case EV_CC_OOS_REG_ALL_FAILED: - return "EV_CC_OOS_REG_ALL_FAILED"; - case EV_CC_OOS_SHUTDOWN_ACK: - return "EV_CC_OOS_SHUTDOWN_ACK"; - case EV_CC_RE_REGISTER: - return "EV_CC_RE_REGISTER"; - case EV_CC_STOP: - return "EV_CC_STOP"; - case EV_CC_DESTROY: - return "EV_CC_DESTROY"; - case EV_CC_IP_VALID: - return "EV_CC_IP_VALID"; - case EV_CC_IP_INVALID: - return "EV_CC_IP_INVALID"; - } - - return "EV_INVALID"; -} - -char *mgmt_state_to_str (int state) { - - switch (state) { - case MGMT_STATE_IDLE: - return "MGMT_STATE_IDLE"; - case MGMT_STATE_CREATED: - return "MGMT_STATE_CREATED"; - case MGMT_STATE_REGISTERING: - return "MGMT_STATE_REGISTERING"; - case MGMT_STATE_REGISTERED: - return "MGMT_STATE_REGISTERED"; - case MGMT_STATE_OOS: - return "MGMT_STATE_OOS"; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - return "MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK"; - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - return "MGMT_STATE_WAITING_FOR_CONFIG_FILE"; - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - return "MGMT_STATE_OOS_AWAIT_UN_REG_ACK"; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - return "MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK"; - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - return "MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK"; - } - - return "MGMT_STATE_INVALID"; -} - -void updateMediaConfigProperties( void ) -{ - //TODO: check Java code - - -} - -void updateVideoConfigProperties( void ) -{ - //TODO: check Java code - -} - -/* - * action for handled events for device manager - */ -int action(int cmd) -{ - int retVal = 0; - sessionProvider_cmd_t proCmd; - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; - proCmd.cmd = cmd; - - if (cmd == CMD_INSERVICE ) { - CCAPP_DEBUG("CC_device_manager_action: CMD_INSERVICE"); - updateMediaConfigProperties(); - updateVideoConfigProperties(); - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed"); - } - } else if (cmd == CMD_INIT) { - - CCAPP_DEBUG("CC_device_manager_action: CMD_INIT"); - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed"); - } - } else if (cmd == CMD_RESTART) { - - CCAPP_DEBUG("CC_device_manager_action: CMD_RESTART"); - updateMediaConfigProperties(); - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed"); - } - - } else if (cmd == CMD_SHUTDOWN) { - - CCAPP_DEBUG("CC_device_manager_action: CMD_SHUTDOWN"); - proCmd.cmdData.ccData.reason = CC_CAUSE_REG_ALL_FAILED; - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed"); - } - } else { - - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - CCAPP_DEBUG("CC_device_manager_action: Default"); - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed"); - } - - } - - return retVal; - -} - - -cc_boolean is_phone_registered() { - if (mgmtState == MGMT_STATE_REGISTERED) { - return TRUE; - } else { - return FALSE; - } -} -/* - * Wrapper function for settting state for handled events for device manager - */ -void setState(int st) { - DEF_DEBUG("setState: new registration state= %s", mgmt_state_to_str(st)); - mgmtState = st; -} - -void processInsToOos (void ) -{ - //CCAPP_DEBUG("CC_device_manager: processInsToOoS"); - DEF_DEBUG("CC_device_manager: processInsToOoS"); - sub_hndlr_stop(); -} - -void prepareForSoftReset() -{ - CCAPP_DEBUG("CC_device_manager: prepareForSoftReset"); - -} - - -void processInserviceEvent( void) -{ - CCAPP_DEBUG("CC_device_manager: process Inservice Event"); - if (g_deviceInfo.cucm_mode == CC_MODE_CCM ) { - if (sub_hndlr_isAvailable() == FALSE) { - sub_hndlr_start(); - } - } - setState(MGMT_STATE_REGISTERED); - //TODO: check Java code -} - - -/* - * Event handler for device manager - */ -void registration_processEvent(int event) { - - boolean ignored=0; - - DEF_DEBUG("registration_processEvent: Event %s, current State %s", - mgmt_event_to_str(event) , mgmt_state_to_str(mgmtState)); - - switch (event) { - case EV_CC_CREATE: - switch ( mgmtState) { - case MGMT_STATE_IDLE: - setState(MGMT_STATE_CREATED); - init_empty_str(g_cfg_p); - CC_Service_create(); - CC_Service_init(); - break; - case MGMT_STATE_REGISTERED: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_START: - isServiceStopped = FALSE; - switch ( mgmtState) { - case MGMT_STATE_CREATED: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - configFetchReq(0); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - DEF_DEBUG("registration_processEvent: delaying start until SHUTDOWN_ACK is received."); - isStartRequestPending = TRUE; - break; - case MGMT_STATE_IDLE: - case MGMT_STATE_REGISTERED: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_IP_INVALID: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - break; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_CREATED: - case MGMT_STATE_IDLE: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - - break; - - case EV_CC_IP_VALID: - if (isServiceStopped == TRUE) { - ignored = 1; - DEF_DEBUG("registration_processEvent: "\ - "Ignoring IP_VALID as service was not Started "); - break; - } - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - if (is_action_to_be_deferred(RE_REGISTER_ACTION) - == FALSE) { - processInsToOos(); - prepareForSoftReset(); - setState(MGMT_STATE_OOS_AWAIT_UN_REG_ACK); - action(CMD_SHUTDOWN); - } - break; - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - if (is_action_to_be_deferred(RE_REGISTER_ACTION) - == FALSE) { - prepareForSoftReset(); - setState(MGMT_STATE_OOS_AWAIT_UN_REG_ACK); - action(CMD_SHUTDOWN); - } - break; - case MGMT_STATE_IDLE: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_DO_SOFT_RESET: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); /* FALL THROUGH */ - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - prepareForSoftReset(); - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - action(CMD_SHUTDOWN); - break; - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_CONFIG_RECEIVED: - switch ( mgmtState) { - case MGMT_STATE_CREATED: // This state is only at init - // needs handler to be added on receiving message - setState(MGMT_STATE_REGISTERING); - action(CMD_INSERVICE); - break; - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - setState(MGMT_STATE_REGISTERING); - action(CMD_RESTART); - break; - case MGMT_STATE_REGISTERING: - case MGMT_STATE_REGISTERED: - case MGMT_STATE_OOS: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_INSERVICE: - switch (mgmtState) { - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - setState(MGMT_STATE_REGISTERED); - case MGMT_STATE_REGISTERED: - processInserviceEvent(); - break; - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_OOS_FAILOVER: - case EV_CC_OOS_FALLBACK: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - case MGMT_STATE_REGISTERING: - setState(MGMT_STATE_OOS); - break; - case MGMT_STATE_OOS: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - case EV_CC_OOS_REG_ALL_FAILED: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); /* FALL THROUGH */ - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - action(CMD_SHUTDOWN); - break; - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - /* - *This event shutdown sip stack to facilitate re-registration of - * all lines. - */ - case EV_CC_RE_REGISTER: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - setState(MGMT_STATE_OOS_AWAIT_UN_REG_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_DESTROY: - isStartRequestPending = FALSE; - isServiceStopped = TRUE; - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - CC_Service_destroy(); - processInsToOos(); - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - setState(MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - //setState(MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK); - setState(MGMT_STATE_IDLE); - CC_Service_destroy(); - break; - case MGMT_STATE_CREATED: - CC_Service_destroy(); - break; - case MGMT_STATE_IDLE: - CC_Service_destroy(); - break; - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_IDLE); - - default: - ignored = 1; - break; - } - - break; - case EV_CC_STOP: - isStartRequestPending = FALSE; - isServiceStopped = TRUE; - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - setState(MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - setState(MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_CREATED: - case MGMT_STATE_IDLE: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_IDLE); - //action(CMD_SHUTDOWN); - CC_Service_destroy(); - - default: - ignored = 1; - break; - } - break; - case EV_CC_OOS_SHUTDOWN_ACK: - switch ( mgmtState) { - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - setState(MGMT_STATE_REGISTERING); - action(CMD_RESTART); - break; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_WAITING_FOR_CONFIG_FILE); - configFetchReq(0); - setState(MGMT_STATE_IDLE); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_WAITING_FOR_CONFIG_FILE); - if (isStartRequestPending == TRUE) { - isStartRequestPending = FALSE; - configFetchReq(0); - } - setState(MGMT_STATE_IDLE); - break; - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - CC_Service_destroy(); - break; - case MGMT_STATE_REGISTERED: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_CREATED: - case MGMT_STATE_IDLE: - default: - ignored = 1; - break; - } - break; - default: - break; - } - - if (ignored) { - DEF_DEBUG("registration_processEvent: IGNORED Event %s in State %s", - mgmt_event_to_str(event) , mgmt_state_to_str(mgmtState)); - } - -} - - - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.h b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.h deleted file mode 100644 index ac0e553c94e..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CC_DEVICE_MANAGER_H__ -#define __CC_DEVICE_MANAGER_H__ - -/** - * Management Events - */ - typedef enum { - EV_CC_CREATE=0, - EV_CC_START, - EV_CC_CONFIG_RECEIVED , - EV_CC_DO_SOFT_RESET , - EV_CC_INSERVICE, - EV_CC_OOS_FAILOVER, - EV_CC_OOS_FALLBACK, - EV_CC_OOS_REG_ALL_FAILED, - EV_CC_OOS_SHUTDOWN_ACK, - EV_CC_RE_REGISTER, - EV_CC_STOP, - EV_CC_DESTROY, - EV_CC_IP_VALID, - EV_CC_IP_INVALID -} mgmt_event_t; - - -/** - * Management states - */ -typedef enum { -MGMT_STATE_CREATED=0, -MGMT_STATE_IDLE, -MGMT_STATE_REGISTERING, -MGMT_STATE_REGISTERED, -MGMT_STATE_OOS, -MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK, -MGMT_STATE_WAITING_FOR_CONFIG_FILE, -MGMT_STATE_OOS_AWAIT_UN_REG_ACK, -MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK, -MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK -} mgmt_state_t; - -extern void registration_processEvent(int event); -cc_boolean is_phone_registered(); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_info.c b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_info.c deleted file mode 100644 index e93b0fd6d08..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_info.c +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_info.h" -#include "sessionTypes.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "ccapp_task.h" - -/** - * Send call information. - * @param call_handle call handle - * @param info_package the Info-Package header of the Info Package - * @param info_type the Content-Type header of the Info Package - * @param info_body the message body of the Info Package - * @return void - */ -void CC_Info_sendInfo(cc_call_handle_t call_handle, - string_t info_package, - string_t info_type, - string_t info_body) { - static const char *fname = "CC_Info_sendInfo"; - session_send_info_t send_info; - - CCAPP_DEBUG(DEB_F_PREFIX"entry... call_handle=0x%x", - DEB_F_PREFIX_ARGS(SIP_CC_SES, fname), call_handle); - - send_info.sessionID= (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + call_handle;; - send_info.generic_raw.info_package = strlib_malloc(info_package, strlen(info_package)); - send_info.generic_raw.content_type = strlib_malloc(info_type, strlen(info_type)); - send_info.generic_raw.message_body = strlib_malloc(info_body, strlen(info_body)); - - /* Once the msg is posted to ccapp_msgq, ccapp 'owns' these strings */ - // ccappTaskPostMsg does a shallow copy of *send_info - if (ccappTaskPostMsg(CCAPP_SEND_INFO, &send_info, - sizeof(session_send_info_t), CCAPP_CCPROVIER) != CPR_SUCCESS) { - CCAPP_ERROR(DEB_F_PREFIX"ccappTaskPostMsg failed", - DEB_F_PREFIX_ARGS(SIP_CC_SES, fname)); - } - -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_service.c b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_service.c deleted file mode 100644 index 03fa271900f..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_service.c +++ /dev/null @@ -1,229 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_service.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "ccsip_messaging.h" -#include "ccapp_task.h" - -/** - * External init.c methods - */ -extern int ccPreInit (); -extern int ccInit (); -extern int ccUnload (); -extern void protCfgTblInit(); - -extern cc_int32_t SipDebugMessage; -extern cc_int32_t SipDebugState; -extern cc_int32_t SipDebugTask; -extern cc_int32_t SipDebugRegState; -extern cc_int32_t GSMDebug; -extern cc_int32_t FIMDebug; -extern cc_int32_t LSMDebug; -extern cc_int32_t FSMDebugSM; -extern int32_t CSMDebugSM; -extern cc_int32_t CCDebug; -extern cc_int32_t CCDebugMsg; -extern cc_int32_t AuthDebug; -extern cc_int32_t ConfigDebug; -extern cc_int32_t DpintDebug; -extern cc_int32_t KpmlDebug; -extern cc_int32_t VCMDebug; -extern cc_int32_t PLATDebug; -extern cc_int32_t CCEVENTDebug; -extern cc_int32_t g_CCAppDebug; -extern cc_int32_t g_CCLogDebug; -extern cc_int32_t TNPDebug; - -/** - * Initialize all the debug variables - */ -void dbg_init(void) -{ - /* This is for the RT/TNP products */ - SipDebugMessage = 1; - SipDebugState = 1; - SipDebugTask = 1; - SipDebugRegState = 1; - GSMDebug = 1; - FIMDebug = 1; - LSMDebug = 1; - FSMDebugSM = 1; - CSMDebugSM = 0; - VCMDebug = 1; - PLATDebug = 1; - CCEVENTDebug = 0; - CCDebug = 0; - CCDebugMsg = 0; - AuthDebug = 1; - TNPDebug = 1; - ConfigDebug = 1; - DpintDebug = 0; - KpmlDebug = 0; - g_CCAppDebug = 1; - g_CCLogDebug = 1; - TNPDebug = 1; - g_NotifyCallDebug = 0; - g_NotifyLineDebug = 0; -} -/** - * Defines the management methods. - */ -/** - * The following methods are defined to bring up the pSipcc stack - */ -/** - * Initialize the pSipcc stack. - * @return - */ -cc_return_t CC_Service_init() { - //Initialize stack - return ccInit(); -} - -/** - * Pre-initialize the pSipcc stack. - * @return - */ -cc_return_t CC_Service_create() { - //Preinitialize memory - ccPreInit(); - - //Initialize debug settings - dbg_init(); - - //Prepopulate the Configuration data table - protCfgTblInit(); - - return CC_SUCCESS; -} - -/** - * Gracefully unload the pSipcc stack - * @return - */ -cc_return_t CC_Service_destroy() { - ccUnload(); - return CC_SUCCESS; -} - -/** - * Bring up the pSipcc stack in service - * @return - */ -cc_return_t CC_Service_start() { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_start"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_INSERVICE; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_start: ccappTaskSendMsg failed"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Shutdown pSipcc stack for restarting - * @param mgmt_reason the reason to shutdown pSipcc stack - * @param reason_string literal string for shutdown - * @return - */ -cc_return_t CC_Service_shutdown(cc_shutdown_reason_t mgmt_reason, string_t reason_string) { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_shutdown"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_SHUTDOWN; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_shutdown: ccappTaskSendMsg failed"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Unregister all lines of a phone - * @param mgmt_reason the reason to bring down the registration - * @param reason_string the literal string for unregistration - * @return - */ -cc_return_t CC_Service_unregisterAllLines(cc_shutdown_reason_t mgmt_reason, string_t reason_string) { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_shutdown"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_SHUTDOWN; - proCmd.cmdData.ccData.reason = mgmt_reason; - proCmd.cmdData.ccData.reason_info = reason_string; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_shutdown: ccappTaskSendMsg failed"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Register all lines for a phone. - * @param mgmt_reason the reason of registration - * @param reason_string the literal string of the registration - * @return - */ -cc_return_t CC_Service_registerAllLines(cc_shutdown_reason_t mgmt_reason, string_t reason_string) { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_registerAllLines"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_REGISTER_ALL_LINES; - proCmd.cmdData.ccData.reason = mgmt_reason; - proCmd.cmdData.ccData.reason_info = reason_string; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_registerAllLines: ccappTaskSendMsg failed"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Restart pSipcc stack - * @return - */ -cc_return_t CC_Service_restart() { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_restart"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_RESTART; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_restart: ccappTaskSendMsg failed"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c deleted file mode 100644 index 15251aa9da6..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c +++ /dev/null @@ -1,344 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "timecard.h" -#include "cpr_stdio.h" -#include "ccapi_call.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "cc_call_feature.h" -#include "cc_info.h" -#include "lsm.h" -#include "prot_configmgr.h" -#include "ccapi_call_info.h" -#include "util_string.h" - -/** - * Get call info snapshot - * @param [in] handle - call handle - * @return cc_call_info_snap_t - */ -cc_callinfo_ref_t CCAPI_Call_getCallInfo(cc_call_handle_t handle) { - unsigned int session_id = ccpro_get_sessionId_by_callid(GET_CALL_ID(handle)); - cc_callinfo_ref_t snapshot=NULL; - session_data_t * data; - - if ( session_id != 0 ) { - data = findhash(session_id); - if ( data != NULL ) { - snapshot = getDeepCopyOfSessionData(data); - if (snapshot == NULL) { - return NULL; - } - snapshot->ref_count = 1; - } - } - return snapshot; -} -/** - * Retain the snapshot - * @param cc_callinfo_ref_t - refrence to the block to be retained - * @return void - */ -void CCAPI_Call_retainCallInfo(cc_callinfo_ref_t ref) { - if (ref != NULL ) { - ref->ref_count++; - } -} -/** - * Free the snapshot - * @param cc_callinfo_ref_t - refrence to the block to be freed - * @return void - */ -void CCAPI_Call_releaseCallInfo(cc_callinfo_ref_t ref) { - if (ref != NULL ) { - DEF_DEBUG(DEB_F_PREFIX"ref=%p: count=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_releaseCallInfo"), ref, ref->ref_count); - ref->ref_count--; - if ( ref->ref_count == 0 ) { - cleanSessionData(ref); - cpr_free(ref); - } - } -} - -/** - * get the line associated with this call - * @param [in] handle - call handle - * @return cc_lineid_t - */ -cc_lineid_t CCAPI_Call_getLine(cc_call_handle_t call_handle){ - static const char *fname="CCAPI_Call_getLine"; - - if ( call_handle != 0 ) { - cc_lineid_t lineid = GET_LINE_ID(call_handle); - CCAPP_DEBUG(DEB_F_PREFIX"returned %u", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), lineid); - return lineid; - } - return 0; -} - -/** - * Originate call - * Goes offhook and dials digits if specified - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @param [in] digits - digits to be dialed - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_originateCall(cc_call_handle_t handle, cc_sdp_direction_t video_pref, cc_string_t digits){ - return CC_CallFeature_dial(handle, video_pref, digits); -} - -/** - * Dial digits on the call - * @param [in] handle - call handle - * @paraqm [in] digits - digits to be dialed - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_sendDigit(cc_call_handle_t handle, cc_digit_t digit){ - return CC_CallFeature_sendDigit(handle, digit); -} - -/** - * Send Backspace - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_backspace(cc_call_handle_t handle){ - return CC_CallFeature_backSpace(handle); -} - -/** - * Answer Call - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_answerCall(cc_call_handle_t handle, cc_sdp_direction_t video_pref) { - return CC_CallFeature_answerCall(handle, video_pref); -} - -/** - * Redial - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_redial(cc_call_handle_t handle, cc_sdp_direction_t video_pref){ - return CC_CallFeature_redial(handle, video_pref); -} - -/** - * Initiate Call Forward All - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_initiateCallForwardAll(cc_call_handle_t handle){ - return CC_CallFeature_callForwardAll(handle); -} -/** - * Hold - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_hold(cc_call_handle_t handle, cc_hold_reason_t reason){ - return CC_CallFeature_holdCall(handle, reason); -} - -/** - * Resume - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_resume(cc_call_handle_t handle, cc_sdp_direction_t video_pref) { - return CC_CallFeature_resume(handle, video_pref); -} - -/** - * end Consult leg - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_endConsultativeCall(cc_call_handle_t handle){ - cc_callinfo_ref_t info_handle = CCAPI_Call_getCallInfo(handle); - cc_call_attr_t attr = CCAPI_CallInfo_getCallAttr(info_handle); - if (attr != CC_ATTR_CONF_CONSULT && - attr != CC_ATTR_XFR_CONSULT && - attr != CC_ATTR_LOCAL_CONF_CONSULT && - attr != CC_ATTR_LOCAL_XFER_CONSULT) { - DEF_DEBUG(DEB_F_PREFIX"This method only calls on a consultative call, handle %u", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_endConsultativeCall"), handle); - return CC_FAILURE; - } - - return CC_CallFeature_endConsultativeCall(handle); -} - -/** - * end Call - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_endCall(cc_call_handle_t handle){ - return CC_CallFeature_terminateCall(handle); -} - -/** - * Initiate a conference - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_conferenceStart(cc_call_handle_t handle, cc_sdp_direction_t video_pref){ - return CC_CallFeature_conference(handle, TRUE,//not used - CC_EMPTY_CALL_HANDLE, video_pref); -} - -/** - * complete conference - * @param [in] handle - call handle - * @param [in] phandle - call handle of the other leg - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_conferenceComplete(cc_call_handle_t handle, cc_call_handle_t phandle, - cc_sdp_direction_t video_pref){ - return CC_CallFeature_conference(handle, TRUE,//not used - phandle, video_pref); - -} - -/** - * start transfer - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_transferStart(cc_call_handle_t handle, cc_sdp_direction_t video_pref){ - return CC_CallFeature_transfer(handle, CC_EMPTY_CALL_HANDLE, video_pref); -} - -/** - * complete transfer - * @param [in] handle - call handle - * @param [in] phandle - call handle of the other leg - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_transferComplete(cc_call_handle_t handle, cc_call_handle_t phandle, - cc_sdp_direction_t video_pref){ - return CC_CallFeature_transfer(handle, phandle, video_pref); -} - -/** - * cancel conference or transfer - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_cancelTransferOrConferenceFeature(cc_call_handle_t handle){ - return CC_CallFeature_cancelXfrerCnf(handle); -} - -/** - * direct Transfer - * @param [in] handle - call handle - * @param [in] handle - transfer target call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_directTransfer(cc_call_handle_t handle, cc_call_handle_t target){ - return CC_CallFeature_directTransfer(handle, target); -} - -/** - * Join Across line - * @param [in] handle - call handle - * @param [in] handle - join target - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_joinAcrossLine(cc_call_handle_t handle, cc_call_handle_t target){ - return CC_CallFeature_joinAcrossLine(handle, target); -} - -/** - * BLF Call Pickup - * @param [in] handle - call handle - * @param [in] speed - speedDial Number - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_blfCallPickup(cc_call_handle_t handle, - cc_sdp_direction_t video_pref, cc_string_t speed){ - return CC_CallFeature_blfCallPickup(handle, video_pref, speed); -} - -/** - * Select a call - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_select(cc_call_handle_t handle){ - return CC_CallFeature_select(handle); -} - -/** - * Update Video Media Cap for the call - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_updateVideoMediaCap (cc_call_handle_t handle, cc_sdp_direction_t video_pref) { - return CC_CallFeature_updateCallMediaCapability(handle, video_pref); -} - -/** - * send INFO method for the call - * @param [in] handle - call handle - * @param [in] infopackage - Info-Package header value - * @param [in] infotype - Content-Type header val - * @param [in] infobody - Body of the INFO message - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_sendInfo (cc_call_handle_t handle, cc_string_t infopackage, cc_string_t infotype, cc_string_t infobody) -{ - CC_Info_sendInfo(handle, infopackage, infotype, infobody); - return CC_SUCCESS; -} - -/** - * API to mute/unmute audio - * @param [in] val - TRUE=> mute FALSE => unmute - * @return SUCCESS or FAILURE - * NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume. - * This API doesn't perform the mute operation but simply caches the mute state of the session. - */ -cc_return_t CCAPI_Call_setAudioMute (cc_call_handle_t handle, cc_boolean val) { - unsigned int session_id = ccpro_get_sessionId_by_callid(GET_CALL_ID(handle)); - session_data_t * sess_data_p = (session_data_t *)findhash(session_id); - DEF_DEBUG(DEB_F_PREFIX": val=%d, handle=%d datap=%p", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_setAudioMute"), val, handle, sess_data_p); - if ( sess_data_p != NULL ) { - sess_data_p->audio_mute = val; - } - return CC_SUCCESS; -} - -/** - * API to mute/unmute Video - * @param [in] val - TRUE=> mute FALSE => unmute - * @return SUCCESS or FAILURE - * NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume - * This API doesn't perform the mute operation but simply caches the mute state of the session. - */ -cc_return_t CCAPI_Call_setVideoMute (cc_call_handle_t handle, cc_boolean val){ - unsigned int session_id = ccpro_get_sessionId_by_callid(GET_CALL_ID(handle)); - session_data_t * sess_data_p = (session_data_t *)findhash(session_id); - DEF_DEBUG(DEB_F_PREFIX": val=%d, handle=%d datap=%p", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_setVideoMute"), val, handle, sess_data_p); - if ( sess_data_p != NULL ) { - sess_data_p->video_mute = val; - lsm_set_video_mute(GET_CALL_ID(handle), val); - } - return CC_SUCCESS; -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call_info.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call_info.c deleted file mode 100644 index 256c8538463..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call_info.c +++ /dev/null @@ -1,732 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdio.h" -#include "ccapi_call.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "text_strings.h" -#include "phone_debug.h" -#include "peer_connection_types.h" - -/** - * get Line on which this call is - * @param [in] handle - call handle - * @return cc_line_id_t - line ID - */ -cc_lineid_t CCAPI_CallInfo_getLine(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getLine"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %u", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), GET_LINE_ID(CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id))); - return GET_LINE_ID(CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id)); - } - - return 0; -} - -/** - * get Call state - * @param handle - call handle - * @return call state - */ -cc_call_state_t CCAPI_CallInfo_getCallState(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallState"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->state); - return data->state; - } - - return ONHOOK; -} - -/** - * get FSM state - * @param handle - call handle - * @return call state - */ -fsmdef_states_t CCAPI_CallInfo_getFsmState(cc_callinfo_ref_t handle){ - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__)); - - if ( data ){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__), data->state); - return data->fsm_state; - } - - return FSMDEF_S_IDLE; -} - -/** - * get call attributes - * @param handle - call handle - * @return call attributes - */ -cc_call_attr_t CCAPI_CallInfo_getCallAttr(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallAttr"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->attr); - return data->attr; - } - - return 0; -} - -/** - * get Call Type - * @param handle - call handle - * @return call type - */ -cc_call_type_t CCAPI_CallInfo_getCallType(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallType"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->type); - return data->type; - } - - return 0; -} - -/** - * get Called party name - * @param handle - call handle - * @return called party name - */ -cc_string_t CCAPI_CallInfo_getCalledPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCalledPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cld_name); - return data->cld_name; - } - - return strlib_empty(); -} - -/** - * get Called party number - * @param handle - call handle - * @return called party number - */ -cc_string_t CCAPI_CallInfo_getCalledPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCalledPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cld_number); - return data->cld_number; - } - - return strlib_empty(); -} - -/** - * get Calling party name - * @param handle - call handle - * @return calling party name - */ -cc_string_t CCAPI_CallInfo_getCallingPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallingPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->clg_name); - return data->clg_name; - } - - return strlib_empty(); -} - -/** - * get Calling party number - * @param handle - call handle - * @return calling party number - */ -cc_string_t CCAPI_CallInfo_getCallingPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallingPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->clg_number); - return data->clg_number; - } - - return strlib_empty(); -} - -/** - * get alternate number - * @param handle - call handle - * @return calling party number - */ -cc_string_t CCAPI_CallInfo_getAlternateNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getAlternateNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->alt_number); - return data->alt_number; - } - - return strlib_empty(); -} - -/** - * get Original Called party name - * @param handle - call handle - * @return original called party name - */ -cc_string_t CCAPI_CallInfo_getOriginalCalledPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getOriginalCalledPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->orig_called_name); - return data->orig_called_name; - } - - return strlib_empty(); -} - -/** - * get Original Called party number - * @param handle - call handle - * @return original called party number - */ -cc_string_t CCAPI_CallInfo_getOriginalCalledPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getOriginalCalledPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->orig_called_number); - return data->orig_called_number; - } - - return strlib_empty(); -} - -/** - * get last redirecting party name - * @param handle - call handle - * @return last redirecting party name - */ -cc_string_t CCAPI_CallInfo_getLastRedirectingPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getLastRedirectingPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->last_redir_name); - return data->last_redir_name; - } - - return strlib_empty(); -} - -/** - * get past redirecting party number - * @param handle - call handle - * @return last redirecting party number - */ -cc_string_t CCAPI_CallInfo_getLastRedirectingPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getLastRedirectingPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->last_redir_number); - return data->last_redir_number; - } - - return strlib_empty(); -} - -/** - * get placed call party name - * @param handle - call handle - * @return placed party name - */ -cc_string_t CCAPI_CallInfo_getPlacedCallPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getPlacedCallPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->plcd_name); - return data->plcd_name; - } - - return strlib_empty(); -} - -/** - * get placed call party number - * @param handle - call handle - * @return placed party number - */ -cc_string_t CCAPI_CallInfo_getPlacedCallPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getPlacedCallPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->plcd_number); - return data->plcd_number; - } - - return strlib_empty(); -} - - -/** - * get call instance number - * @param handle - call handle - * @return - */ -cc_int32_t CCAPI_CallInfo_getCallInstance(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallInstance"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->inst); - return data->inst; - } - - return 0; -} - -/** - * get call status prompt - * @param handle - call handle - * @return call status - */ -cc_string_t CCAPI_CallInfo_getStatus(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getStatus"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (data && data->status){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->status); - return data->status; - } - - return strlib_empty(); - -} - -/** - * get call security - * @param handle - call handle - * @return call security status - */ -cc_call_security_t CCAPI_CallInfo_getSecurity(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getSecurity"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->security); - return data->security; - } - - return CC_SECURITY_NONE; -} - -/** - * * get Call Selection Status - * * @param [in] handle - call info handle - * * @return cc_boolean - TRUE => selected - * */ -cc_boolean CCAPI_CallInfo_getSelectionStatus(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getSelectionStatus"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->isSelected); - return data->isSelected; - } - - return FALSE; -} - -/** - * get call policy - * @param handle - call handle - * @return call policy - */ -cc_call_policy_t CCAPI_CallInfo_getPolicy(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getPolicy"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->policy); - return data->policy; - } - - return CC_POLICY_NONE; -} - -/** - * get GCID - * @param handle - call handle - * @return GCID - */ -cc_string_t CCAPI_CallInfo_getGCID(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getGCID"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->gci); - return data->gci; - } - - return strlib_empty(); -} - -/** - * get ringer state. - * @param handle - call handle - * @return ringer state - */ -cc_boolean CCAPI_CallInfo_getRingerState(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getRingerState"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->ringer_start); - return data->ringer_start; - } - - return FALSE; -} - -/** - * get ringer mode - * @param handle - call handle - * @return ringer mode - */ -int CCAPI_CallInfo_getRingerMode(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getRingerMode"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->ringer_mode); - return (int)(data->ringer_mode); - } - - return -1; -} - -/** - * get ringer loop count - * @param handle - call handle - * @return once Vs continuous - */ -cc_boolean CCAPI_CallInfo_getIsRingOnce(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getIsRingOnce"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->ringer_once); - return (int)(data->ringer_once); - } - - return TRUE; -} - -/** - * get onhook reason - * @param handle - call handle - * @return onhook reason - */ -cc_int32_t CCAPI_CallInfo_getOnhookReason(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getOnhookReason"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cause); - return data->cause; - } - - return CC_CAUSE_NORMAL; -} - -/** - * is Conference Call? - * @param handle - call handle - * @return boolean - is Conference - */ -cc_boolean CCAPI_CallInfo_getIsConference(cc_callinfo_ref_t handle){ - session_data_t *data = (session_data_t *)handle; - char isConf[32]; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__)); - - memset(isConf, 0, sizeof(isConf)); - - if(platGetPhraseText(CONFERENCE_LOCALE_CODE, isConf, sizeof(isConf)) == CC_FAILURE){ - return FALSE; - } - - if( data != NULL){ - if( (strcasecmp(data->cld_name, isConf) == 0 && strcasecmp(data->cld_number, "") == 0) || - (strcasecmp(data->clg_name, isConf) == 0 && strcasecmp(data->clg_number, "") == 0) ) - { - return TRUE; - } - } - - return FALSE; -} - -/** - * getStream Statistics - * @param handle - call handle - * @return stream stats - */ -cc_return_t CCAPI_CallInfo_getStreamStatistics(cc_callinfo_ref_t handle, cc_int32_t stats[], cc_int32_t *count) -{ - static const char *fname="CCAPI_CallInfo_getStreamStatistics"; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - CCAPP_DEBUG(DEB_F_PREFIX"returned CC_SUCCESS (default)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - // todo - return CC_SUCCESS; -} - - -/** - * has capability - is the feature allowed - * @param handle - call handle - * @param feat_id - feature id - * @return boolean - is Allowed - */ -cc_boolean CCAPI_CallInfo_hasCapability(cc_callinfo_ref_t handle, cc_int32_t feat_id){ - static const char *fname="CCAPI_CallInfo_hasCapability"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, data->allowed_features[feat_id]); - return data->allowed_features[feat_id]; - } - - return FALSE; -} - -/** - * get Allowed Feature set - * @param handle - call handle - * @return boolean array that can be indexed using CCAPI_CALL_CAP_XXXX to check if feature is enabled - */ -cc_boolean CCAPI_CallInfo_getCapabilitySet(cc_callinfo_ref_t handle, cc_int32_t feat_set[]){ - static const char *fname="CCAPI_CallInfo_getCapabilitySet"; - session_data_t *data = (session_data_t *)handle; - int feat_id; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - for (feat_id = 0; feat_id < CCAPI_CALL_CAP_MAX; feat_id++) { - feat_set[feat_id] = data->allowed_features[feat_id]; - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, feat_set[feat_id]); - } - - CCAPP_DEBUG(DEB_F_PREFIX"returned CC_SUCCESS", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return CC_SUCCESS; - } - - return CC_FAILURE; -} - -/** - * Call selection status - * @param [in] handle - call handle - * @return cc_boolean - selection status - */ -cc_boolean CCAPI_CallInfo_isCallSelected(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_isCallSelected"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->isSelected); - return data->isSelected; - } - - return FALSE; -} - -/** - * Call negotiated video direction - * @param [in] handle - call handle - * @return cc_sdp_direction_t - video direction - */ -cc_sdp_direction_t CCAPI_CallInfo_getVideoDirection(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getVideoDirection"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->vid_dir); - return (data->vid_dir); - } - - return CC_SDP_DIRECTION_INACTIVE; -} - -/** - * INFO Package for RECEIVED_INFO event - * @param [in] handle - call info handle - * @return cc_string_t - Info package header - */ -cc_string_t CCAPI_CallInfo_getINFOPack (cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getINFOPackage"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->info_package); - return data->info_package; - } - - return strlib_empty(); -} - -/** - * INFO type for RECEIVED_INFO event - * @param [in] handle - call info handle - * @return cc_string_t - content-type header - */ -cc_string_t CCAPI_CallInfo_getINFOType (cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getINFOType"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->info_type); - return data->info_type; - } - - return strlib_empty(); -} - -/** - * INFO body for RECEIVED_INFO event - * @param [in] handle - call info handle - * @return cc_string_t - INFO body - */ -cc_string_t CCAPI_CallInfo_getINFOBody (cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getINFOBody"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->info_body); - return data->info_body; - } - - return strlib_empty(); -} - -/** - * Get the call log reference - * @param [in] handle - call info handle - * @return cc_string_t - INFO body - * NOTE: Memory associated with the call log is tied to the cc_callinfo_ref_t handle - * this would be freed when the callinfo ref is freed. - */ -cc_calllog_ref_t CCAPI_CallInfo_getCallLogRef(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getCallLogRef"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %p", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), &data->call_log); - return &data->call_log; - } - - return NULL; -} - - -/** - * Returns the Audio mute state for this call - * @return boolean true=muted false=not muted - */ -cc_boolean CCAPI_CallInfo_isAudioMuted (cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_isAudioMuted"; - session_data_t *data = (session_data_t *)handle; - session_data_t * sess_data_p; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - if ( data != NULL){ - sess_data_p = (session_data_t *)findhash(data->sess_id); - if ( sess_data_p != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sess_data_p->audio_mute); - return sess_data_p->audio_mute; - } - } - - return FALSE; -} - -/** - * Returns the Video mute state for this call - * @return boolean true=muted false=not muted - */ -cc_boolean CCAPI_CallInfo_isVideoMuted (cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_isVideoMuted"; - session_data_t *data = (session_data_t *)handle; - session_data_t * sess_data_p; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - if ( data != NULL){ - sess_data_p = (session_data_t *)findhash(data->sess_id); - if ( sess_data_p != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sess_data_p->video_mute); - return sess_data_p->video_mute; - } - } - - return FALSE; -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_config.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_config.c deleted file mode 100644 index 8ba492fd0ac..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_config.c +++ /dev/null @@ -1,108 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "prot_configmgr.h" -#include "cc_types.h" -#include "config_parser.h" -#include "config_api.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "ccapi_device_info.h" -#include "cc_device_manager.h" -#include "ccapi_service.h" -#include "util_string.h" - -extern boolean apply_config; -extern cc_apply_config_result_t apply_config_result; -cc_boolean parse_setup_properties (int device_handle, const char *device_name, const char *sipUser, const char *sipPassword, const char *sipDomain); - -/** - * - * @return - */ - -void CCAPI_Start_response(int device_handle, const char *device_name, const char *sipUser, const char *sipPassword, const char *sipDomain) { - static const char fname[] = "CCAPI_Start_response"; - - if (is_empty_str((char*)sipUser) || is_empty_str((char*)sipDomain)) { - CCAPP_ERROR(DEB_F_PREFIX" invalid registration details user=%s, domain=%s", DEB_F_PREFIX_ARGS(CC_API, fname), sipUser, sipDomain); - return; - } - - g_dev_hdl = device_handle; - sstrncpy(g_dev_name, device_name, sizeof(g_dev_name)); - - if (is_phone_registered() == FALSE) { - - if (parse_setup_properties(device_handle, device_name, sipUser, sipPassword, sipDomain)) { - registration_processEvent(EV_CC_CONFIG_RECEIVED); - } - return; - } - - } - -/* New Function - Register without using config file downloaded from cucm - */ -cc_boolean parse_setup_properties (int device_handle, const char *device_name, const char *sipUser, const char *sipPassword, const char *sipDomain) { - CC_Config_setStringValue(CFGID_DEVICE_NAME, device_name); - - config_setup_main(sipUser, sipPassword, sipDomain); - - ccsnap_device_init(); - ccsnap_line_init(); - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CONFIG_CHANGED, CC_DEVICE_ID); - return TRUE; -} - -cc_boolean CCAPI_Config_set_server_address(const char *ip_address) { - config_setup_server_address(ip_address); - return TRUE; -} - -cc_boolean CCAPI_Config_set_transport_udp(const cc_boolean is_udp) { - config_setup_transport_udp(is_udp); - return TRUE; -} - -cc_boolean CCAPI_Config_set_local_voip_port(const int port) { - config_setup_local_voip_control_port(port); - return TRUE; -} - -cc_boolean CCAPI_Config_set_remote_voip_port(const int port) { - config_setup_remote_voip_control_port(port); - return TRUE; -} - -int CCAPI_Config_get_local_voip_port() { - return config_get_local_voip_control_port(); -} - -int CCAPI_Config_get_remote_voip_port() { - return config_get_remote_voip_control_port(); -} - -const char* CCAPI_Config_get_version() { - return config_get_version(); -} - -cc_boolean CCAPI_Config_set_p2p_mode(const cc_boolean is_p2p) { - config_setup_p2p_mode(is_p2p); - return TRUE; -} - -cc_boolean CCAPI_Config_set_sdp_mode(const cc_boolean is_sdp) { - config_setup_sdp_mode(is_sdp); - return TRUE; -} - -cc_boolean CCAPI_Config_set_avp_mode(const cc_boolean is_rtpsavpf) { - config_setup_avp_mode(is_rtpsavpf); - return TRUE; -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device.c deleted file mode 100644 index b016bbc6777..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device.c +++ /dev/null @@ -1,285 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdlib.h" -#include "string_lib.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "CCProvider.h" -#include "cc_config.h" -#include "cc_call_feature.h" -#include "cc_device_feature.h" -#include "ccsip_messaging.h" -#include "ccapi_call_info.h" -#include "cc_device_manager.h" -#include "cc_service_listener.h" -#include "platform_api.h" -#include "util_string.h" -#include "ccapi_service.h" -#include "ccapi_device_info.h" - -char g_new_signaling_ip[MAX_IPADDR_STR_LEN]; - -dock_undock_event_t g_dock_undock_event = MEDIA_INTERFACE_UPDATE_NOT_REQUIRED; -extern accessory_cfg_info_t g_accessoryCfgInfo; - -extern void escalateDeescalate(); - -int signaling_interface_type; - -/** - * Get device reference handle - * @return cc_deviceinfo_ref_t - reference handle of the device - */ -cc_device_handle_t CCAPI_Device_getDeviceID() -{ - return CC_DEVICE_ID; -} - -/** - * Get device reference handle - * @param handle - device handle - * @return cc_deviceinfo_ref_t - reference handle of the device - */ -cc_deviceinfo_ref_t CCAPI_Device_getDeviceInfo(cc_device_handle_t handle) -{ - cc_device_info_t *device_info = (cc_device_info_t*)cpr_malloc(sizeof(cc_device_info_t)); - - if (device_info) { - *device_info = g_deviceInfo; - device_info->not_prompt = strlib_copy(g_deviceInfo.not_prompt); - if (device_info->not_prompt == NULL) { - device_info->not_prompt = strlib_empty(); - } - device_info->ref_count = 1; - } - return device_info; -} - -/** - * Retain the deviceInfo snapshot - * @param handle - device handle - * @param cc_deviceinfo_ref_t - refrence to the block to be retained - * @return void - */ -void CCAPI_Device_retainDeviceInfo(cc_deviceinfo_ref_t ref){ - cc_device_info_t *device_info = ref; - if (device_info) { - device_info->ref_count++; - } -} - -/** - * Set device configuration file location - * @param [in] ref - refrence to the block to be freed - * @param [in] file_path - device config file full path - * @return void - */ -void CCAPI_Device_configUpdate(cc_device_handle_t handle, file_path_t file_path) { - CC_Config_setStringValue(CFGID_CONFIG_FILE, file_path); -} - -/** - * Release the deviceInfo snapshot - * @param handle - device handle - * @param cc_deviceinfo_ref_t - refrence to the block to be released - * @return void - */ -void CCAPI_Device_releaseDeviceInfo(cc_deviceinfo_ref_t ref){ - cc_device_info_t *device_info = ref; - - if (device_info) { - device_info->ref_count--; - if ( device_info->ref_count == 0 ) { - strlib_free(device_info->not_prompt); - cpr_free(device_info); - } - } -} - - -/** - * Create a call on the device - * @param handle - device handle - * @return cc_call_handle_t - handle of the call created - */ -cc_call_handle_t CCAPI_Device_CreateCall(cc_device_handle_t handle) -{ - return CC_createCall(0); -} - -/** - * Enable or disable video capability of the device. - * @param handle - device handle - * @param enable - a flag to indicate that application wants to enable of - * disable video capability of the device. - * @return void - */ -void CCAPI_Device_enableVideo(cc_device_handle_t handle, cc_boolean enable) -{ - CC_DeviceFeature_enableVideo(enable); - g_accessoryCfgInfo.video = ACCSRY_CFGD_APK; -} - -/** - * Enable or disable camera capability of the device. - * @param handle - device handle - * @param enable - a flag to indicate that application wants to enable of - * disable camera capability of the device. - * @return void - */ -void CCAPI_Device_enableCamera(cc_device_handle_t handle, cc_boolean enable) -{ - CC_DeviceFeature_enableCamera(enable); - g_accessoryCfgInfo.camera = ACCSRY_CFGD_APK; -} - -/** - * CCAPI_Device_setDigestNamePasswd - * - * @param handle - device handle - * @param name - The Digest auth name - * @param passwd - The password for that name for the line - * @return void - */ -void CCAPI_Device_setDigestNamePasswd (cc_device_handle_t handle, - char *name, char *pw) -{ - int line; - - for(line = 0; line < MAX_CONFIG_LINES; line++) { - CC_Config_setStringValue(CFGID_LINE_AUTHNAME + line, name); - CC_Config_setStringValue(CFGID_LINE_PASSWORD + line, pw); - } -} - -/** - * CCAPI_Device_IP_Update - * - * There is a change in the IP address and the values of new set - * of signaling and media IP addresses are provided. - * These value are compared with the current IP address values - * and depending on what changed, restart and/or re-invite - * action is taken. - * - * The case being addressed. - * 1) If the signaling IP change happens during a call, - * the change is deferred till phone is idle. - * 2)If media IP change happens during a call, it is applied immediately. - * 3) If both change, and call is active, that is treated same - * combination of case 1) and 2). - * 4) If no call is present, and signaling IP change, - * sipcc will re-register with new IP. - * - * @param handle - device handle - * @param signaling_ip - IP address that Must be used for signalling - * @param signaling_interface - Interface Name associaed with signaling IP - * @param signaling_int_type - Interface type associaed with signaling IP - * @param media_ip - IP address that Must be used for media - * @param media_interface - Interface nmae associaed with media IP - * @param media_interface - Interface Type associaed with media IP - * @return void - */ -void CCAPI_Device_IP_Update (cc_device_handle_t handle, - const char *signaling_ip, - const char *signaling_interface, - int signaling_int_type, - const char *media_ip, - const char *media_interface, - int media_int_type) -{ - static const char fname[] = "CCAPI_Device_IP_Update"; - char curr_signaling_ip[MAX_IPADDR_STR_LEN]; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t sig_ip; - - signaling_interface_type = signaling_int_type; - - // init the ip addr string to empty string - init_empty_str(curr_signaling_ip); - init_empty_str(curr_media_ip); - init_empty_str(g_new_signaling_ip); - - config_get_value(CFGID_MY_IP_ADDR, &sig_ip, sizeof(cpr_ip_addr_t)); - sig_ip.type = CPR_IP_ADDR_IPV4; - util_ntohl(&sig_ip, &sig_ip); - ipaddr2dotted(curr_signaling_ip, &sig_ip); - - config_get_string(CFGID_MEDIA_IP_ADDR, curr_media_ip, - MAX_IPADDR_STR_LEN); - - DEF_DEBUG(DEB_F_PREFIX"New sig_ip=%s media_ip=%s Current: sig_ip: %s,"\ - "media_ip: %s \n", - DEB_F_PREFIX_ARGS(CC_API, fname), - signaling_ip, - media_ip, - curr_signaling_ip, - curr_media_ip); - - /* - * If signaling and media IP are empty, stop the - * SIP service and return; - */ - if ((is_empty_str((char *)signaling_ip) || - (strncmp(signaling_ip, "0.0.0.0", MAX_IPADDR_STR_LEN) == 0)) - && (is_empty_str((char *)media_ip) || - (strncmp(media_ip, "0.0.0.0", MAX_IPADDR_STR_LEN) == 0))) { - CC_Config_setStringValue(CFGID_MY_IP_ADDR, "0.0.0.0"); - CC_Config_setStringValue(CFGID_MEDIA_IP_ADDR, EMPTY_STR); - DEF_DEBUG(DEB_F_PREFIX"Media and Signaling IP Not provided."\ - "Shutdown sip stack", DEB_F_PREFIX_ARGS(CC_API, fname)); - if ((strncmp(curr_signaling_ip, signaling_ip, - MAX_IPADDR_STR_LEN) != 0)) { - registration_processEvent(EV_CC_IP_INVALID); - return; - } - } - - /* - * There is a change in the signaling IP, set the - * new IP as the platform signaling IP and re-register - */ - if ((signaling_ip != NULL) && - (strncmp(curr_signaling_ip, signaling_ip, MAX_IPADDR_STR_LEN) != 0)) { - CC_Config_setStringValue(CFGID_MY_IP_ADDR, signaling_ip); - DEF_DEBUG(DEB_F_PREFIX"Signaling IP changed. Re-register, if needed.", - DEB_F_PREFIX_ARGS(CC_API, fname)); - registration_processEvent(EV_CC_IP_VALID); - - } - - /* - * There is a change in the media IP, set the - * new IP as the platform media IP and post the call to GSM - * to initiate re-inivite for all relevane calls - */ - if ((media_ip != NULL) && - (strncmp(curr_media_ip, media_ip, MAX_IPADDR_STR_LEN) != 0)) { - CC_Config_setStringValue(CFGID_MEDIA_IP_ADDR, media_ip); - if (g_dock_undock_event != MEDIA_INTERFACE_UPDATE_IN_PROCESS) { - g_dock_undock_event = MEDIA_INTERFACE_UPDATE_STARTED; - DEF_DEBUG(DEB_F_PREFIX" MEDIA_INTERFACE_UPDATE received. escalateDeescalate.", - DEB_F_PREFIX_ARGS(CC_API, fname)); - escalateDeescalate(); - }else { - DEF_DEBUG(DEB_F_PREFIX"MEDIA_INTERFACE_UPDATE received but escalateDeescalate already in progress:%d", - DEB_F_PREFIX_ARGS(CC_API, fname), g_dock_undock_event); - } - } -} - -/** - * CCAPI_Device_setVideoAutoTxPreference - * - * @param handle - device handle - * @param txPref - TRUE=> auto Tx Video prefered - * @return void - */ -void CCAPI_Device_setVideoAutoTxPreference (cc_device_handle_t handle, cc_boolean txPref) -{ - CCAPP_DEBUG("CCAPI_Device_setVideoAutoTxPreference: updated to %d", txPref); - cc_media_setVideoAutoTxPref(txPref); -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device_info.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device_info.c deleted file mode 100644 index e54287cf649..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device_info.c +++ /dev/null @@ -1,469 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "string_lib.h" -#include "cc_constants.h" -#include "ccapi_snapshot.h" -#include "ccapi_device_info.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "phone_debug.h" -#include "ccapi_snapshot.h" -#include "ccapi_device_info.h" -#include "util_string.h" -#include "CSFLog.h" - -static const char* logTag = "ccapi_device_info"; - -/** - * gets the device name - * @returns - a pointer to the device name - */ -cc_deviceinfo_ref_t CCAPI_DeviceInfo_getDeviceHandle () -{ - static const char *fname="CCAPI_DeviceInfo_getDeviceHandle"; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - CCAPP_DEBUG(DEB_F_PREFIX"returned 0 (default)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return 0; -} - -/** - * gets the device name - * @returns - a pointer to the device name - */ -cc_string_t CCAPI_DeviceInfo_getDeviceName (cc_deviceinfo_ref_t handle) -{ - CSFLogDebug(logTag, "Call to deprecated function %s, returning empty string", __FUNCTION__); - return strlib_empty(); -} - -/** - * gets the device idle status - * @param [in] handle - reference to device info - * @returns boolean - idle status - */ -cc_boolean CCAPI_DeviceInfo_isPhoneIdle(cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isPhoneIdle"; - boolean ret = TRUE; - hashItr_t itr; - session_data_t * session_data; - cc_call_state_t call_state; - - hashItrInit(&itr); - - while ((session_data = hashItrNext(&itr)) != NULL) { - call_state = session_data->state; - if (call_state != ONHOOK && - call_state != REMINUSE) { - ret = FALSE; - break; - } - } - CCAPP_DEBUG(DEB_F_PREFIX"idle state=%d session_id=0x%x call-state=%d handle=%p", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ret, - (session_data != NULL)? session_data->sess_id: 0, - (session_data != NULL)? session_data->state: 0, - (handle)? handle:0); - return ret; - -} - -/** - * gets the service state - * @param [in] handle - reference to device info - * @returns cc_service_state_t - INS/OOS - */ -cc_service_state_t CCAPI_DeviceInfo_getServiceState (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getServiceState"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->ins_state); - return device->ins_state; - } - - return CC_STATE_IDLE; -} - -/** - * gets the service cause - * @param [in] handle - reference to device info - * @returns cc_service_cause_t - reason for service state - */ -cc_service_cause_t CCAPI_DeviceInfo_getServiceCause (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getServiceCause"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->ins_cause); - return device->ins_cause; - } - - return CC_CAUSE_NONE; - -} - -/** - * gets the cucm mode - * @returns cc_cucm_mode_t - CUCM mode - */ -cc_cucm_mode_t CCAPI_DeviceInfo_getCUCMMode (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getCUCMMode"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->cucm_mode); - return device->cucm_mode; - } - - return CC_MODE_INVALID; -} - -/** - * gets list of handles to calls on the device - * @param handle - device handle - * @param handles - array of call handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getCalls (cc_deviceinfo_ref_t handle, cc_call_handle_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getCalls"; - hashItr_t itr; - session_data_t *data; - int i=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets list of handles to calls on the device by State - * @param handle - device handle - * @param state - state for whcih calls are requested - * @param handles - array of call handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getCallsByState (cc_deviceinfo_ref_t handle, cc_call_state_t state, - cc_call_handle_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getCallsByState"; - hashItr_t itr; - session_data_t *data; - int i=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - if ( data->state == state ) { - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets list of handles to lines on the device - * @param handles[in,out] - array of line handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getLines (cc_deviceinfo_ref_t handle, cc_lineid_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getLines"; - cc_line_info_t *line; - int i=1, j=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - CCAPP_DEBUG(" LINES Start "); - - while ( (line = ccsnap_getLineInfo(i++)) != NULL && - j<*count ) { - CCAPP_DEBUG(" LINE handle[%d]=%d", j, line->button ); - /* We will use button as line handles */ - handles[j++] = line->button; - } - *count=j; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets list of handles to features on the device - * @param handles[in,out] - array of feature handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getFeatures (cc_deviceinfo_ref_t handle, cc_featureinfo_ref_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getFeatures"; - cc_featureinfo_ref_t feature; - int i=0, j=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=1;i<=MAX_CONFIG_LINES && j<*count;i++) { - feature = (cc_featureinfo_ref_t) ccsnap_getFeatureInfo(i); - if(feature != NULL){ - handles[j++] = feature; - } - } - *count=j; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets handles of call agent servers - * @param handles - array of handles to call agent servers - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getCallServers (cc_deviceinfo_ref_t handle, cc_callserver_ref_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getCallServers"; - int i, j=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=0;iname != 0) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ref->name); - return ref->name; - } - return strlib_empty(); -} - -/** - * gets call server mode - * @param handle - handle of call server - * @returns - mode of the call server - */ -cc_cucm_mode_t CCAPI_DeviceInfo_getCallServerMode (cc_callserver_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getCallServerMode"; - cc_call_server_t *ref = (cc_call_server_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ref->type); - return ref->type; - } - - return CC_MODE_INVALID; -} - -/** - * gets calls erver name - * @param handle - handle of call server - * @returns status of the call server - */ -cc_ccm_status_t CCAPI_DeviceInfo_getCallServerStatus (cc_callserver_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getCallServerStatus"; - cc_call_server_t *ref = (cc_call_server_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->status)); - return ref->status; - } - - return CC_CCM_STATUS_NONE; -} - -/** - * get the NOTIFICATION PROMPT - * @param [in] handle - reference to device info - * @returns - */ -cc_string_t CCAPI_DeviceInfo_getNotifyPrompt (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getNotifyPrompt"; - cc_device_info_t *ref = (cc_device_info_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %p", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->not_prompt)); - return ref->not_prompt; - } - - return strlib_empty(); -} - -/** - * get the NOTIFICATION PROMPT PRIORITY - * @param [in] handle - reference to device info - * @returns - */ -cc_uint32_t CCAPI_DeviceInfo_getNotifyPromptPriority (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getNotifyPromptPriority"; - cc_device_info_t *ref = (cc_device_info_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->not_prompt_prio)); - return ref->not_prompt_prio; - } - - return 0; -} - -/** - * get the NOTIFICATION PROMPT PROGRESS - * @param [in] handle - reference to device info - * @returns - */ -cc_uint32_t CCAPI_DeviceInfo_getNotifyPromptProgress (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getNotifyPromptProgress"; - cc_device_info_t *ref = (cc_device_info_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->not_prompt_prog)); - return ref->not_prompt_prog; - } - - return 0; -} - -/** - * gets provisioing for missed call logging - * @param [in] handle - reference to device info - * @returns boolean - false => disabled true => enabled - */ -cc_boolean CCAPI_DeviceInfo_isMissedCallLoggingEnabled (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isMissedCallLoggingEnabled"; - - CCAPP_DEBUG(DEB_F_PREFIX" return val %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ccsnap_isMissedCallLoggingEnabled()); - return ccsnap_isMissedCallLoggingEnabled(); -} - -/** - * gets provisioing for placed call logging - * @param [in] handle - reference to device info - * @returns boolean - false => disabled true => enabled - */ -cc_boolean CCAPI_DeviceInfo_isPlacedCallLoggingEnabled (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isPlacedCallLoggingEnabled"; - - CCAPP_DEBUG(DEB_F_PREFIX" return val %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ccsnap_isPlacedCallLoggingEnabled()); - return ccsnap_isPlacedCallLoggingEnabled(); -} - - -/** - * gets provisioing for received call logging - * @param [in] handle - reference to device info - * @returns boolean - false => disabled true => enabled - */ -cc_boolean CCAPI_DeviceInfo_isReceivedCallLoggingEnabled (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isReceivedCallLoggingEnabled"; - - CCAPP_DEBUG(DEB_F_PREFIX" return val %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ccsnap_isReceivedCallLoggingEnabled()); - return ccsnap_isReceivedCallLoggingEnabled(); -} - -/** - * gets time registration completed successfully - * @param [in] handle - reference to device info - * @returns long - the time registration completed successfully - */ -long long CCAPI_DeviceInfo_getRegTime (cc_deviceinfo_ref_t handle) -{ - return (g_deviceInfo.reg_time); -} - -/** - * Returns dot notation IP address phone used for registration purpose. If phone is not - * registered, then "0.0.0.0" is returned. - * @return char IP address used to register phone. - */ -cc_string_t CCAPI_DeviceInfo_getSignalingIPAddress(cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getSignalingIPAddress"; - cpr_ip_addr_t ip_addr = {0,{0}}; - - sip_config_get_net_device_ipaddr(&ip_addr); - ipaddr2dotted(g_deviceInfo.registration_ip_addr, &ip_addr); - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), g_deviceInfo.registration_ip_addr); - return g_deviceInfo.registration_ip_addr; -} - -/** - * Returns camera admin enable/disable status - * @param [in] handle - reference to device info - * @return cc_boolean - TRUE => enabled - */ -cc_boolean CCAPI_DeviceInfo_isCameraEnabled(cc_deviceinfo_ref_t handle) { - // returns the current status not the snapshot status - return cc_media_isTxCapEnabled(); -} - -/** - * Returns Video Capability admin enable/disable status - * @param [in] handle - reference to device info - * @return cc_boolean - TRUE => enabled - */ -cc_boolean CCAPI_DeviceInfo_isVideoCapEnabled(cc_deviceinfo_ref_t handle) { - // returns the current status not the snapshot status - return cc_media_isVideoCapEnabled(); -} - -/** - * gets the device mwi_lamp state - * @param [in] handle - reference to device info - * @returns boolean - mwi_lamp state - */ -cc_boolean CCAPI_DeviceInfo_getMWILampState(cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getMWILampState"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->mwi_lamp); - return device->mwi_lamp; - } - - return FALSE; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_feature_info.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_feature_info.c deleted file mode 100644 index f378bb65ce5..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_feature_info.c +++ /dev/null @@ -1,154 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapi_snapshot.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "phone_debug.h" - -/** - * Get the physical button number on which this feature is configured - * @param feature - feature reference handle - * @return cc_int32_t - button assigned to the feature - */ -cc_int32_t CCAPI_featureInfo_getButton(cc_featureinfo_ref_t feature) -{ - static const char *fname="CCAPI_featureInfo_getButton"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->button); - return info->button; - } - return -1; -} - -/** - * Get the featureID - * @param feature - feature reference handle - * @return cc_int32_t - type of to the feature - */ -cc_int32_t CCAPI_featureInfo_getFeatureID(cc_featureinfo_ref_t feature) -{ - static const char *fname="CCAPI_featureInfo_getFeatureID"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->feature_id); - return info->feature_id; - } - return -1; -} - -/** - * Get the feature Label Name - * @param feature - feature reference handle - * @return cc_string_t - name of the feature created - */ -cc_string_t CCAPI_featureInfo_getDisplayName(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getDisplayName"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - return ccsnap_get_line_label(info->button); - } - return NULL; -} - -/** - * Get the speeddial Number - * @param feature - feature reference handle - * @return cc_string_t - speeddial number of the feature created - */ -cc_string_t CCAPI_featureInfo_getSpeedDialNumber(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getSpeedDialNumber"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->speedDialNumber); - return info->speedDialNumber; - } - return NULL; -} - -/** - * Get the contact - * @param feature - feature reference handle - * @return cc_string_t - contact of the feature created - */ -cc_string_t CCAPI_featureInfo_getContact(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getContact"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->contact); - return info->contact; - } - return NULL; -} - -/** - * Get the retrieval prefix - * @param feature - feature reference handle - * @return cc_string_t - retrieval prefix of the feature created - */ -cc_string_t CCAPI_featureInfo_getRetrievalPrefix(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getRetrievalPrefix"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->retrievalPrefix); - return info->retrievalPrefix; - } - return NULL; -} - -/** - * Get BLF state - * @param feature - feature reference handle - * @return cc_string_t - handle of the feature created - */ -cc_blf_state_t CCAPI_featureInfo_getBLFState(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getBLFState"; - cc_feature_info_t *info = (cc_feature_info_t *)feature; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->blf_state); - return info->blf_state; - } - return CC_SIP_BLF_UNKNOWN; -} - -/** - * Get the feature option mask - * @param feature - feature reference handle - * @return cc_int32_t - feature option mask for the feature - */ -cc_int32_t CCAPI_featureInfo_getFeatureOptionMask(cc_featureinfo_ref_t feature) -{ - static const char *fname="CCAPI_featureInfo_getFeatureOptionMask"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->featureOptionMask); - return info->featureOptionMask; - } - return -1; -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line.c deleted file mode 100644 index 0931e11432a..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line.c +++ /dev/null @@ -1,81 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdlib.h" -#include "string_lib.h" -#include "cc_call_feature.h" -#include "ccapi_snapshot.h" -#include "ccapi_line.h" - -extern cc_line_info_t lineInfo[MAX_CONFIG_LINES+1]; - -/** - * Get reference handle for the line - * @return cc_call_handle_t - handle of the call created - */ -cc_lineinfo_ref_t CCAPI_Line_getLineInfo(cc_uint32_t lineID) -{ - cc_line_info_t *line_info = NULL; - int i; - - for (i=1;i<=MAX_CONFIG_LINES;i++) { - if ( (cc_uint32_t)lineInfo[i].button == lineID ) { - line_info = (cc_line_info_t*)cpr_malloc(sizeof(cc_line_info_t)); - - if (line_info) { - *line_info = lineInfo[i]; - line_info->ref_count = 1; - line_info->name = strlib_copy(lineInfo[i].name); - line_info->dn = strlib_copy(lineInfo[i].dn); - line_info->cfwd_dest = strlib_copy(lineInfo[i].cfwd_dest); - line_info->externalNumber = - strlib_copy(lineInfo[i].externalNumber); - } - } - } - return line_info; -} - -/** - * Create a call on the line - * @param [in] line - lineID - * @return cc_call_handle_t - handle of the call created - */ -cc_call_handle_t CCAPI_Line_CreateCall(cc_lineid_t line) -{ - // do we need to check the line on which this gets created? - return CC_createCall(line); -} - -/** - * Reatin the lineInfo snapshot - * @param cc_callinfo_ref_t - refrence to the block to be retained - * @return void - */ -void CCAPI_Line_retainLineInfo(cc_lineinfo_ref_t ref){ - cc_line_info_t *line_info = ref; - - line_info->ref_count++; -} -/** - * Free the lineInfo snapshot - * @param cc_callinfo_ref_t - refrence to the block to be freed - * @return void - */ -void CCAPI_Line_releaseLineInfo(cc_lineinfo_ref_t ref){ - cc_line_info_t *line_info = ref; - - if (line_info) { - line_info->ref_count--; - if ( line_info->ref_count == 0) { - strlib_free(line_info->name); - strlib_free(line_info->dn); - strlib_free(line_info->cfwd_dest); - strlib_free(line_info->externalNumber); - cpr_free(line_info); - } - } -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line_info.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line_info.c deleted file mode 100644 index 5b47582e738..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line_info.c +++ /dev/null @@ -1,425 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapi_snapshot.h" -#include "ccapi_line.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "phone_debug.h" - -/** - * Get the line ID - * @param line - line reference handle - * @return line ID - */ -cc_int32_t CCAPI_lineInfo_getID(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getID"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - /* We will use button as line ID */ - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->button); - return info->button; - } - return -1; -} - -/** - * Get the line Name - * @param line - line reference handle - * @return cc_string_t - handle of the call created - */ -cc_string_t CCAPI_lineInfo_getName(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getName"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->dn); - return info->dn; - } - return NULL; -} - -/** - * Get the line Label - * @param [in] line - line reference handle - * @return cc_string_t - line Label - * NOTE: The memory for return string doesn't need to be freed it will be freed when the info reference is freed - */ -cc_string_t CCAPI_lineInfo_getLabel(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getLabel"; - cc_line_info_t *info = (cc_line_info_t *) line; - cc_string_t label = strlib_empty(); - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - label = ccsnap_get_line_label(info->button); - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), label); - } - return label; -} - -/** - * Get the line DN Number - * @param line - line reference handle - * @return cc_string_t - handle of the call created - */ -cc_string_t CCAPI_lineInfo_getNumber(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getNumber"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - return info->name; - } - return NULL; -} - -/** - * Get the line External Number - * @param line - line reference handle - * @return cc_string_t - handle of the call created - */ -cc_string_t CCAPI_lineInfo_getExternalNumber(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getExternalNumber"; - cc_line_info_t *info = (cc_line_info_t *) line; - char externalNumberMask[MAX_EXTERNAL_NUMBER_MASK_SIZE]; - memset(externalNumberMask, 0, sizeof(externalNumberMask)); - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - config_get_string(CFGID_CCM_EXTERNAL_NUMBER_MASK, externalNumberMask, MAX_EXTERNAL_NUMBER_MASK_SIZE); - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - if (strlen(externalNumberMask) > 0) { - CCAPP_DEBUG(DEB_F_PREFIX"number with mask applied == %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->externalNumber); - return info->externalNumber; - } else { - CCAPP_DEBUG(DEB_F_PREFIX"number without mask == %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - return info->name; - } - } - return NULL; -} - -/** - * Get the physical button number on which this line is configured - * @param line - line reference handle - * @return cc_uint32_t - button number - */ -cc_uint32_t CCAPI_lineInfo_getButton(cc_lineinfo_ref_t line){ - static const char *fname="CCAPI_lineInfo_getButton"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->button); - return info->button; - } - return 0; - -} - -/** - * Get the Line Type - * @param [in] line - line reference handle - * @return cc_uint32_t - line featureID ( Line ) - */ -cc_line_feature_t CCAPI_lineInfo_getLineType(cc_lineinfo_ref_t line){ - static const char *fname="CCAPI_lineInfo_getLineType"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->line_type); - return info->line_type; - } - return 0; -} - - - -/** - * Get the CFWDAll status for the line - * @param line - line reference handle - * @return cc_boolean - isForwarded - */ -cc_boolean CCAPI_lineInfo_isCFWDActive(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_isCFWDActive"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->isCFWD); - return info->isCFWD; - } - return FALSE; -} - -/** - * Get the CFWDAll destination - * @param line - line reference handle - * @return cc_string_t - cfwd target - */ -cc_string_t CCAPI_lineInfo_getCFWDName(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getCFWDName"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cfwd_dest); - return info->cfwd_dest; - } - return NULL; -} - -/** - * Get the MWI Status - * @param line - line reference handle - * @return cc_uint32_t - MWI status (boolean 0 => no MWI) - */ -cc_uint32_t CCAPI_lineInfo_getMWIStatus(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIStatus"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned status %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi.status); - return info->mwi.status; - } - return 0; -} - -/** - * Get the MWI Type - * @param line - line reference handle - * @return cc_uint32_t - MWI Type - */ -cc_uint32_t CCAPI_lineInfo_getMWIType(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIType"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned type %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi.type); - return info->mwi.type; - } - return 0; -} - -/** - * Get the MWI new msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI new msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWINewMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWINewMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned new count %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi.new_count); - return info->mwi.new_count; - } - return 0; -} -/** - * Get the MWI old msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI old msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWIOldMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIOldMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned old_count %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi.old_count); - return info->mwi.old_count; - } - return 0; -} - -/** - * Get the MWI high priority new msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI new msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWIPrioNewMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIPrioNewMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned pri_new count %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi.pri_new_count); - return info->mwi.pri_new_count; - } - return 0; -} -/** - * Get the MWI high priority old msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI old msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWIPrioOldMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIPrioOldMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned pri old_count %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi.pri_old_count); - return info->mwi.pri_old_count; - } - return 0; -} - -/** - * Get calls on line - * @param [in] line - lineID - * @param [out] callref[] - Array of callinfo references - * @param [in/out] count - count of call references populated - * @return void - */ - -void CCAPI_LineInfo_getCalls(cc_lineid_t line, cc_call_handle_t handles[], int *count) -{ - static const char *fname="CCAPI_Line_getCalls"; - hashItr_t itr; - session_data_t *data; - int i=0; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - if ( GET_LINE_ID(data->sess_id) == line ){ - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * Get calls on line - * @param [in] line - lineID - * @param [out] callref[] - Array of callinfo references - * @param [in/out] count - count of call references populated - * @return void - */ -void CCAPI_LineInfo_getCallsByState(cc_lineid_t line, cc_call_state_t state, - cc_call_handle_t handles[], int *count) -{ - static const char *fname="CCAPI_Line_getCallsByState"; - hashItr_t itr; - session_data_t *data; - int i=0; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - if ( GET_LINE_ID(data->sess_id) == line && data->state ==state ){ - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return)", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * Get the physical button number on which this line is configured - * @param [in] line - line reference handle - * @return cc_uint32_t - button number - */ -cc_boolean CCAPI_lineInfo_getRegState(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getRegState"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->reg_state); - return info->reg_state; - } - return 0; -} - -/** - * has capability - is the feature allowed - * @param [in] line - line reference handle - * @param [in] feat_id - feature id - * @return boolean - is Allowed - */ -cc_boolean CCAPI_LineInfo_hasCapability (cc_lineinfo_ref_t line, cc_int32_t feat_id){ - static const char *fname="CCAPI_LineInfo_hasCapability"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value returned %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, info->allowed_features[feat_id]); - return info->allowed_features[feat_id]; - } - - return FALSE; -} - - -/** - * get Allowed Feature set - * @param [in] line - line reference handle - * @param [in,out] feat_set - array of len CC_CALL_CAP_MAX - * @return cc_return_t - CC_SUCCESS or CC_FAILURE - */ -cc_return_t CCAPI_LineInfo_getCapabilitySet (cc_lineinfo_ref_t line, cc_int32_t feat_set[]){ - static const char *fname="CCAPI_LineInfo_getCapabilitySet"; - cc_line_info_t *info = (cc_line_info_t *) line; - int feat_id; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL){ - for (feat_id = 0; feat_id < CCAPI_CALL_CAP_MAX; feat_id++) { - feat_set[feat_id] = info->allowed_features[feat_id]; - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value %d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, feat_set[feat_id]); - } - - CCAPP_DEBUG(DEB_F_PREFIX"returned CC_SUCCESS", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return CC_SUCCESS; - } - - return CC_FAILURE; -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_service.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_service.c deleted file mode 100644 index 630f23fd6fa..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_service.c +++ /dev/null @@ -1,166 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapi_service.h" -#include "cc_device_manager.h" -#include "cc_service.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "ccsip_messaging.h" -#include "ccapp_task.h" -#include "config_api.h" -#include "ccapi_device.h" -#include "ccapi_device_info.h" -#include "cc_device_listener.h" -#include "cc_service_listener.h" -#include "plat_api.h" -#include "util_string.h" - -int sendResetUpdates = 0; // default is not to send updates - -// Global Variables -int g_dev_hdl; -char g_dev_name[G_DEV_NAME_SIZE]; -char g_cfg_p[G_CFG_P_SIZE]; -int g_compl_cfg; - -// Externs -extern void setState(); -extern void resetReady(); -extern void resetNotReady(); -extern void ccpro_handleserviceControlNotify(); - - -extern cc_srv_ctrl_cmd_t reset_type; -boolean isServiceStartRequestPending = FALSE; -cc_boolean is_action_to_be_deferred(cc_action_t action); -extern cc_action_t pending_action_type; -//cc_boolean parse_config_properties (int device_handle, const char *device_name, const char *cfg, int from_memory); - - - -/** - * Defines the management methods. - */ - -/** - * Pre-initialize the Sipcc stack. - * @return - */ -cc_return_t CCAPI_Service_create() { - CCAPP_ERROR("CCAPI_Service_create - calling CC_Service_create"); - - registration_processEvent(EV_CC_CREATE); - return (CC_SUCCESS); - //return (service_processEvent(EV_SRVC_CREATE)); -} - -/** - * Gracefully unload the Sipcc stack - * @return - */ -cc_return_t CCAPI_Service_destroy() { - CCAPP_ERROR("CCAPI_Service_destroy - calling CC_Service_destroy"); - - // if (is_action_to_be_deferred(STOP_ACTION) == TRUE) { - // return CC_SUCCESS; - // } - // initialize the config to empty - init_empty_str(g_cfg_p); - isServiceStartRequestPending = FALSE; - registration_processEvent(EV_CC_DESTROY); - return (CC_SUCCESS); -} - -/** - * Bring up the Sipcc stack in service - * @return - */ -cc_return_t CCAPI_Service_start() { - - if (isServiceStartRequestPending == TRUE) { - DEF_DEBUG("CCAPI_Service_start request is already pending. Ignoring this."); - return CC_SUCCESS; - } - - DEF_DEBUG("CCAPI_Service_start -"); - isServiceStartRequestPending = TRUE; - - registration_processEvent(EV_CC_START); - - return (CC_SUCCESS); -} - -/** - * Stop Sipcc stack service - * @return - */ -cc_return_t CCAPI_Service_stop() { - - int sdpmode = 0; - - CCAPP_ERROR("CCAPI_Service_stop - calling registration stop"); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - if (is_action_to_be_deferred(STOP_ACTION) == TRUE) { - return CC_SUCCESS; - } - } - sendResetUpdates = 0; // reset to default is not to send updates - isServiceStartRequestPending = FALSE; - registration_processEvent(EV_CC_STOP); - return CC_SUCCESS; -} - - -/** - * reregister the Sipcc stack service, without downloading the config file - * - */ -cc_return_t CCAPI_Service_reregister(int device_handle, const char *device_name, - const char *cfg, - int complete_config) -{ - CCAPP_ERROR("CCAPI_Service_reregister - initiate reregister"); - - if (is_action_to_be_deferred(RE_REGISTER_ACTION) == TRUE) { - return CC_SUCCESS; - } - if (pending_action_type != NO_ACTION) { - CCAPP_ERROR("Reset/Restart is pending, reregister Ignored!"); - return CC_FAILURE; - } - - if (is_empty_str((char*)cfg)) { - CCAPP_ERROR("Reregister request with empty config. Exiting."); - return CC_FAILURE; - } - - g_dev_hdl = device_handle; - sstrncpy(g_dev_name, device_name, sizeof(g_dev_name)); - sstrncpy(g_cfg_p, cfg, sizeof(g_cfg_p)); - CCAPP_DEBUG("CCAPI_Service_reregister - devce name [%s], cfg [%s]", g_dev_name, g_cfg_p); - g_compl_cfg = complete_config; - - registration_processEvent(EV_CC_RE_REGISTER); - - return (CC_SUCCESS); -} - -/** - * Reset Manager has request a reset, send the current state and - * start sending updates. - */ -void CCAPI_Service_reset_request() { - cc_deviceinfo_ref_t handle = 0; - sendResetUpdates = 1; - if (CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) { - resetReady(); - } else { - resetNotReady(); - } - -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c deleted file mode 100644 index 6e60a536a4c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c +++ /dev/null @@ -1,706 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "string.h" -#include "string_lib.h" -#include "text_strings.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "ccapi_device_listener.h" -#include "ccapi_line.h" -#include "ccapi_line_listener.h" -#include "ccapi_line_info.h" -#include "ccapi_call.h" -#include "ccapi_call_listener.h" -#include "CCProvider.h" -#include "capability_set.h" -#include "phone_debug.h" - -cc_device_info_t g_deviceInfo; -accessory_cfg_info_t g_accessoryCfgInfo; -cc_line_info_t lineInfo[MAX_CONFIG_LINES+1]; -cc_feature_info_t featureInfo[MAX_CONFIG_LINES+1]; - -static void printCallInfo(cc_callinfo_ref_t info, const char* fname); -static void printFeatureInfo (ccapi_device_event_e type, cc_featureinfo_ref_t feature_info, const char* fname); - -cc_string_t lineLabels[MAX_CONFIG_LINES+1] = {0}; - - -void ccsnap_set_line_label(int btn, cc_string_t label) { - - CCAPP_DEBUG(DEB_F_PREFIX"btn=%d label=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_set_line_label"), btn, label); - if ( btn > 0 && btn < MAX_CONFIG_LINES+1 ) { - if ( label == NULL ) { - label = strlib_empty(); - } - if ( lineLabels[btn] == NULL ) { - lineLabels[btn] = strlib_empty(); - } - lineLabels[btn] = strlib_update(lineLabels[btn], label); - } -} - -cc_string_t ccsnap_get_line_label(int btn) { - if ( btn > 0 && btn < MAX_CONFIG_LINES+1 ) { - return lineLabels[btn]; - } - return strlib_empty(); -} - -/* - * The below two functions are borrowed from CUCM/CUP as they both perform - * identical functions. That is, taking a DN 1555 and - * a mask 919476XXXX to build a true external number 9194761555. - */ -static void stringInsert(char *string, int num, char ch) -{ - - int len = strlen(string); - int k, j; - char tempString[100]; - sstrncpy(tempString, string, 100); - - for (k = 0; k < num; k++) - string[k] = ch; - - for (j = 0; j < len; j++) - string[k++] = tempString[j]; - - string[k] = 0; - -} - -/* - * Taken from CUCM/CUP code as they have done this already. - */ -cc_string_t CCAPI_ApplyTranslationMask (const char *ext, const char *mask) -{ - - char translationMask[100] = {'\0'}; - char dn[100] = {'\0'}; - char translatedString[100] = {'\0'}; - cc_string_t result; - unsigned int maskLen, - dnLen, - i, j = 0; - - if ((ext == NULL) || (mask == NULL)) { - return NULL; - } - - maskLen = strlen(mask); - dnLen = strlen(ext); - - if ((dnLen == 0) || (maskLen == 0)) { - CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask DN or mask has len=0", -DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask")); - return NULL; - } - - /* make sure there's enough space in the buffer to - * hold the translated string. - */ - if (dnLen + maskLen > 99) { - CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask length overflow", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask")); - return NULL; - } - - sstrncpy(translationMask, mask, 100); - sstrncpy(dn, ext, 100); - - /* make sure DN is numeric only */ - for (i=0; i< dnLen; i++) { - if (isalpha(dn[i])) { - return 0; - } - } - - if (maskLen > dnLen) { - stringInsert(dn, maskLen - dnLen, '?'); - } - - /* if the digit string is longer than the translation mask - * prepad the translation mask with '%'. - */ - if (dnLen > maskLen) { - stringInsert(translationMask, dnLen - maskLen, '%'); - } - - dnLen = strlen(dn); - - for (i=0; i < dnLen; i++) { - if (translationMask[i] == '%') - continue; - else if (translationMask[i] == 'X') - translatedString[j++] = dn[i]; - else - translatedString[j++] = translationMask[i]; - } - - translatedString[j] = 0; - result = strlib_malloc(translatedString, strlen(translatedString)); - return result; -} - -/** - * Before initing the line_info release any memory which has been used - * so we do not leak any here. - */ -void ccsnap_line_free () { - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__)); - - for (i=1;i<=MAX_CONFIG_LINES;i++) { - if (lineInfo[i].name) { - strlib_free(lineInfo[i].name); - } - if (lineInfo[i].dn) { - strlib_free(lineInfo[i].dn); - } - if (lineInfo[i].cfwd_dest) { - strlib_free(lineInfo[i].cfwd_dest); - } - if (lineInfo[i].externalNumber) { - strlib_free(lineInfo[i].externalNumber); - } - if (featureInfo[i].speedDialNumber) { - strlib_free(featureInfo[i].speedDialNumber); - } - if (featureInfo[i].contact) { - strlib_free(featureInfo[i].contact); - } - if (featureInfo[i].name) { - strlib_free(featureInfo[i].name); - } - if (featureInfo[i].retrievalPrefix) { - strlib_free(featureInfo[i].retrievalPrefix); - } - } -} - -/** - * Initialize lineinfo and featureinfo arrays - */ -void ccsnap_line_init() { - int i; - cc_uint32_t tmpInt; - char tempStr[MAX_URL_LENGTH]; - char maskStr[MAX_EXTERNAL_NUMBER_MASK_SIZE]; - - /* clean up structure if need be */ - ccsnap_line_free(); - - memset(lineInfo, 0, MAX_CONFIG_LINES*sizeof(cc_line_info_t)); - memset(featureInfo, 0, MAX_CONFIG_LINES*sizeof(cc_feature_info_t)); - for (i=1;i<=MAX_CONFIG_LINES;i++) { - config_get_line_value(CFGID_LINE_FEATURE, &tmpInt, sizeof(tmpInt), i); - if ( tmpInt == cfgLineFeatureDN ) { - lineInfo[i].button = i; - lineInfo[i].line_type = tmpInt; - config_get_line_value(CFGID_LINE_INDEX, &tmpInt, sizeof(tmpInt), i); - lineInfo[i].line_id = tmpInt; - config_get_line_value(CFGID_LINE_DISPLAYNAME_STRING, tempStr, - MAX_URL_LENGTH, i); - lineInfo[i].dn = strlib_malloc(tempStr, strlen(tempStr)); - config_get_line_value(CFGID_LINE_NAME_STRING, tempStr, - MAX_URL_LENGTH, i); - lineInfo[i].name = strlib_malloc(tempStr, strlen(tempStr)); - config_get_line_value(CFGID_LINE_CFWDALL, tempStr, - MAX_URL_LENGTH, i); - lineInfo[i].cfwd_dest = strlib_malloc(tempStr, strlen(tempStr)); - config_get_line_value(CFGID_LINE_SPEEDDIAL_NUMBER_STRING, tempStr, - MAX_URL_LENGTH, i); - memset(maskStr, 0, sizeof(maskStr)); - config_get_string(CFGID_CCM_EXTERNAL_NUMBER_MASK, maskStr, MAX_EXTERNAL_NUMBER_MASK_SIZE); - if (strlen(maskStr) > 0) { - lineInfo[i].externalNumber = CCAPI_ApplyTranslationMask(lineInfo[i].name, maskStr); - CCAPP_DEBUG("Setting lineInfo[i].externalNumber to %s", lineInfo[i].externalNumber); - } else { - lineInfo[i].externalNumber = strlib_empty(); - } - } else { - lineInfo[i].line_id = MAX_CONFIG_LINES+1; // invalid line id - lineInfo[i].button = i; - lineInfo[i].dn = strlib_empty(); - lineInfo[i].name = strlib_empty(); - lineInfo[i].cfwd_dest = strlib_empty(); - lineInfo[i].externalNumber = strlib_empty(); - } - capset_get_idleset(CC_MODE_CCM, lineInfo[i].allowed_features); - - // get feature again because it might have been changed if it is a DN - // and the tmpInt might have a different value - config_get_line_value(CFGID_LINE_FEATURE, &tmpInt, sizeof(tmpInt), i); - - // features which have no properties - if ( tmpInt == cfgLineFeatureAllCalls || - tmpInt == cfgLineFeatureMaliciousCallID || - tmpInt == cfgLineFeatureRedial || tmpInt == cfgLineFeatureAnswerOldest || tmpInt == cfgLineFeatureServices ) { - featureInfo[i].feature_id = tmpInt; - featureInfo[i].button = i; - featureInfo[i].speedDialNumber = strlib_empty(); - featureInfo[i].contact = strlib_empty(); - featureInfo[i].name = strlib_empty(); - featureInfo[i].retrievalPrefix = strlib_empty(); - featureInfo[i].featureOptionMask = 0; - } else if ( tmpInt == cfgLineFeatureSpeedDialBLF || tmpInt == cfgLineFeatureSpeedDial){ - featureInfo[i].feature_id = tmpInt; - featureInfo[i].button = i; - config_get_line_value(CFGID_LINE_SPEEDDIAL_NUMBER_STRING, tempStr, - MAX_URL_LENGTH, i); - featureInfo[i].speedDialNumber = strlib_malloc(tempStr, strlen(tempStr)); - featureInfo[i].contact = strlib_empty(); - config_get_line_value(CFGID_LINE_NAME_STRING, tempStr, - MAX_URL_LENGTH, i); - featureInfo[i].name = strlib_malloc(tempStr, strlen(tempStr)); - featureInfo[i].retrievalPrefix = strlib_empty(); - config_get_line_value(CFGID_LINE_FEATURE_OPTION_MASK, &tmpInt, sizeof(tmpInt), i); - featureInfo[i].featureOptionMask = tmpInt; - featureInfo[i].blf_state = CC_SIP_BLF_UNKNOWN; - } else { - featureInfo[i].feature_id = 0; - featureInfo[i].button = MAX_CONFIG_LINES+1; // invalid button value - featureInfo[i].speedDialNumber = strlib_empty(); - featureInfo[i].contact = strlib_empty(); - featureInfo[i].name = strlib_empty(); - featureInfo[i].retrievalPrefix = strlib_empty(); - featureInfo[i].featureOptionMask = 0; - } - } -} - -cc_line_info_t* ccsnap_getLineInfo(int lineID) -{ - int i; - cc_lineid_t line = (cc_lineid_t)lineID; - - for (i=1;i<=MAX_CONFIG_LINES;i++) { - if ( lineInfo[i].line_id == line ) { - return &lineInfo[i]; - } - } - - return NULL; -} - -cc_line_info_t* ccsnap_getLineInfoFromBtn(int btnID) -{ - int i; - - for (i=1;i<=MAX_CONFIG_LINES;i++) { - if ( lineInfo[i].button == btnID ) { - return &lineInfo[i]; - } - } - - return NULL; -} - -cc_boolean allowedFeature(int fid){ - return TRUE; -} - -cc_feature_info_t* ccsnap_getFeatureInfo(int featureIndex) -{ - if ( ( featureIndex<=MAX_CONFIG_LINES ) && - ( featureIndex>= 1 ) && - ( featureInfo[featureIndex].button == featureIndex ) ) { - if ( allowedFeature(featureInfo[featureIndex].feature_id) ){ - return &featureInfo[featureIndex]; - } - } - - return NULL; -} - -/** - * Release any used mem to avoid a leak. - */ -void ccsnap_device_free () { - int i = 0; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__)); - if (g_deviceInfo.not_prompt) { - strlib_free(g_deviceInfo.not_prompt); - } - - i = 0; - while (i < CCAPI_MAX_SERVERS) { - if (g_deviceInfo.ucm[i].name) { - strlib_free(g_deviceInfo.ucm[i].name); - } - i++; - } -} - -void ccsnap_device_init() { - char temp[MAX_SIP_URL_LENGTH]; - - /* clean up structure if need be */ - ccsnap_device_free(); - - memset (&g_deviceInfo, 0, sizeof(g_deviceInfo)); - g_deviceInfo.not_prompt =strlib_empty(); - - g_deviceInfo.not_prompt_prio = 0; - g_deviceInfo.not_prompt_prog = 0; - g_deviceInfo.mwi_lamp = FALSE; - g_deviceInfo.cucm_mode = CC_MODE_CCM; - g_deviceInfo.ins_state = CC_STATE_IDLE; - g_deviceInfo.ins_cause = CC_CAUSE_NONE; - g_deviceInfo.reg_time = 0; - - config_get_string(CFGID_CCM1_ADDRESS, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[0].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[0].type = CC_MODE_CCM; - g_deviceInfo.ucm[0].status = CC_CCM_STATUS_NONE; - - config_get_string(CFGID_CCM2_ADDRESS, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[1].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[1].type = CC_MODE_CCM; - g_deviceInfo.ucm[1].status = CC_CCM_STATUS_NONE; - - config_get_string(CFGID_CCM3_ADDRESS, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[2].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[2].type = CC_MODE_CCM; - g_deviceInfo.ucm[2].status = CC_CCM_STATUS_NONE; - - config_get_string(CFGID_CCM_TFTP_IP_ADDR, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[3].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[3].type = CC_MODE_CCM; - g_deviceInfo.ucm[3].status = CC_CCM_STATUS_NONE; - - g_accessoryCfgInfo.camera = ACCSRY_CFGD_CFG; - g_accessoryCfgInfo.video = ACCSRY_CFGD_CFG; -} - -void ccsnap_gen_deviceEvent(ccapi_device_event_e event, cc_device_handle_t handle){ - const char* fname = "ccsnap_gen_deviceEvent"; - - cc_device_info_t *device_info = CCAPI_Device_getDeviceInfo(handle); - if ( device_info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ref_count); - - switch (event) { - case CCAPI_DEVICE_EV_NOTIFYPROMPT: - CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt); - CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt_prio=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt_prio); - CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt_prog=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt_prog); - break; - case CCAPI_DEVICE_EV_STATE: - CCAPP_DEBUG(DEB_F_PREFIX"setting property %s to %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), "FullyRegistered", ((device_info->ins_state == CC_STATE_INS) ? "1" : "0")); - //intentional follow through to let the debugs get printed. - default: - CCAPP_DEBUG(DEB_F_PREFIX"data->mwi_lamp=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->mwi_lamp); - CCAPP_DEBUG(DEB_F_PREFIX"data->ins_state=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ins_state); - CCAPP_DEBUG(DEB_F_PREFIX"data->cucm_mode=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->cucm_mode); - CCAPP_DEBUG(DEB_F_PREFIX"data->ins_cause=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ins_cause); - break; - - } - - CCAPI_DeviceListener_onDeviceEvent(event, handle, device_info); - } - CCAPI_Device_releaseDeviceInfo(device_info); -} - -void ccsnap_gen_lineEvent(ccapi_line_event_e event, cc_lineid_t handle){ - const char* fname = "ccsnap_gen_lineEvent"; - cc_line_info_t *line_info = CCAPI_Line_getLineInfo(handle); - - if ( line_info != NULL ) { - if (g_CCAppDebug) { - CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->ref_count); - CCAPP_DEBUG(DEB_F_PREFIX"data->line_id=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->line_id); - CCAPP_DEBUG(DEB_F_PREFIX"data->button=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->button); - CCAPP_DEBUG(DEB_F_PREFIX"data->reg_state=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->reg_state); - CCAPP_DEBUG(DEB_F_PREFIX"data->isCFWD=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->isCFWD); - CCAPP_DEBUG(DEB_F_PREFIX"data->isLocalCFWD=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->isLocalCFWD); - CCAPP_DEBUG(DEB_F_PREFIX"data->mwi=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->mwi.status); - CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->name); - CCAPP_DEBUG(DEB_F_PREFIX"data->dn=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->dn); - CCAPP_DEBUG(DEB_F_PREFIX"data->cfwd_dest=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->cfwd_dest); - } - CCAPI_LineListener_onLineEvent(event, handle, line_info); - } - CCAPI_Line_releaseLineInfo(line_info); -} - -void ccsnap_gen_callEvent(ccapi_call_event_e event, cc_call_handle_t handle){ - - session_data_t *call_info = CCAPI_Call_getCallInfo(handle); - - if ( call_info == NULL ) { - call_info = getDeepCopyOfSessionData(NULL); - } - - //print all info - if (g_CCAppDebug) { - printCallInfo(call_info, "ccsnap_gen_callEvent"); - } - - CCAPI_CallListener_onCallEvent(event, handle, call_info); - CCAPI_Call_releaseCallInfo(call_info); -} - -void ccsnap_update_ccm_status(cc_string_t addr, cc_ccm_status_t status) -{ - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"entry ccm %s status=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_update_ccm_status"), addr, status); - - for (i=0;i< CCAPI_MAX_SERVERS;i++) { - if ( g_deviceInfo.ucm[i].status == status ) { - //move the status to the new addr - g_deviceInfo.ucm[i].status = CC_CCM_STATUS_NONE; - } - if ( !strcmp(addr, g_deviceInfo.ucm[i].name) ) { - g_deviceInfo.ucm[i].status = status; - CCAPP_DEBUG(DEB_F_PREFIX"server %s is now status=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_update_ccm_status"), - g_deviceInfo.ucm[i].name, status); - } - } -} - -void ccsnap_handle_mnc_reached (cc_line_info_t *line_info, cc_boolean mnc_reached, cc_cucm_mode_t mode) -{ - cc_call_handle_t handles[MAX_CALLS]; - int count = MAX_CALLS, i; - session_data_t *cinfo; - - if (mnc_reached) { - line_info->allowed_features[CCAPI_CALL_CAP_NEWCALL] = FALSE; - line_info->allowed_features[CCAPI_CALL_CAP_REDIAL] = FALSE; - line_info->allowed_features[CCAPI_CALL_CAP_CALLFWD] = FALSE; - } else { - capset_get_idleset(mode, line_info->allowed_features); - } - - // update connected calls caps on this line - CCAPI_LineInfo_getCallsByState(line_info->line_id, CONNECTED, handles, &count); - for ( i=0; iattr == (cc_call_attr_t) CONF_CONSULT || - cinfo->attr == (cc_call_attr_t) XFR_CONSULT ) { - CCAPI_Call_releaseCallInfo(cinfo); - continue; - } - cinfo->allowed_features[CCAPI_CALL_CAP_TRANSFER] = mnc_reached?FALSE:TRUE; - cinfo->allowed_features[CCAPI_CALL_CAP_CONFERENCE] = mnc_reached?FALSE:TRUE; - //print call info - if (g_CCAppDebug) { - printCallInfo(cinfo, "ccsnap_handle_mnc_reached"); - } - CCAPI_CallListener_onCallEvent(CCAPI_CALL_EV_CAPABILITY, handles[i], cinfo); - } - } - // update RIU call caps on this line - CCAPI_LineInfo_getCallsByState(line_info->line_id, REMINUSE, handles, &count); - for ( i=0; iallowed_features[CCAPI_CALL_CAP_BARGE] = mnc_reached?FALSE:TRUE; - //print call info - if (g_CCAppDebug) { - printCallInfo(cinfo, "ccsnap_handle_mnc_reached"); - } - CCAPI_CallListener_onCallEvent(CCAPI_CALL_EV_CAPABILITY, handles[i], cinfo); - } - } -} - -void ccsnap_gen_blfFeatureEvent(cc_blf_state_t state, int appId) -{ - cc_feature_info_t *feature_info = NULL; - - feature_info = ccsnap_getFeatureInfo(appId); - - // if the feature exists - if (feature_info != NULL) { - feature_info->blf_state = state; - printFeatureInfo(CCAPI_DEVICE_EV_BLF, feature_info, "ccsnap_gen_blfFeatureEvent"); - CCAPI_DeviceListener_onFeatureEvent(CCAPI_DEVICE_EV_BLF, CC_DEVICE_ID, feature_info); - } -} - -/** - * Inserts localized strings into existing strings with escape characters. - * @param destination the return phrase holder - * @param source the phrase with escape characters. - * @param len the input length to cap the maximum value - * @return pointer to the new string - */ -cc_string_t ccsnap_EscapeStrToLocaleStr(cc_string_t destination, cc_string_t source, int len) -{ - static const char *fname="ccsnap_EscapeStrToLocaleStr"; - char phrase_collector[MAX_LOCALE_STRING_LEN] = { '\0' }; - char* phrase_collector_ptr = phrase_collector; - char* esc_string_itr = (char*)source; - int remaining_length = 0; - cc_string_t ret_str = strlib_empty(); - - if(destination == NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"Error: destination is NULL", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return NULL; - } - - if(source == NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"Error: source is NULL", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - strlib_free(destination); - return strlib_empty(); - } - - if(source[0] == '\0'){ - strlib_free(destination); - return strlib_empty(); - } - - if (len == LEN_UNKNOWN) { - len = strlen(source) + MAX_LOCALE_PHRASE_LEN; - } - - if (len <= 0){ - CCAPP_DEBUG(DEB_F_PREFIX"Error: cannot write string of length <= 0", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - strlib_free(destination); - return strlib_empty(); - } - - if (len > MAX_LOCALE_STRING_LEN){ - len = MAX_LOCALE_STRING_LEN; - } - - remaining_length = len; - while( *esc_string_itr != NUL && - remaining_length > 0 && - strlen(phrase_collector_ptr) < (size_t)(len-1)) - { - int rtn = CC_SUCCESS; - int phrase_index = 0; - char* phrase_bucket_ptr = (char*)cpr_malloc(remaining_length * sizeof(char)); - - if (phrase_bucket_ptr == NULL) { - CCAPP_ERROR(DEB_F_PREFIX"Error: phrase_bucket_ptr is NULL", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - strlib_free(destination); - return NULL; - } - phrase_bucket_ptr[0] = '\0'; - switch(*esc_string_itr){ - case OLD_CUCM_DICTIONARY_ESCAPE_TAG: - phrase_index += CALL_CONTROL_PHRASE_OFFSET; - // Do not set break to combine common code - case NEW_CUCM_DICTIONARY_ESCAPE_TAG: - esc_string_itr++; - phrase_index += (int)(*esc_string_itr); - rtn = platGetPhraseText(phrase_index, phrase_bucket_ptr, remaining_length-1); - if(rtn == CC_FAILURE) break; - sstrncat(phrase_collector_ptr, (cc_string_t)phrase_bucket_ptr, remaining_length); - remaining_length--; - break; - default: - // We need length 2 to concat 1 char and a terminating char - sstrncat(phrase_collector_ptr, esc_string_itr, 1 + sizeof(char)); - remaining_length--; - break; - } - esc_string_itr++; - cpr_free(phrase_bucket_ptr); - } - - ret_str = strlib_malloc(phrase_collector_ptr, len); - - if (!ret_str) { - /* - * If a malloc error occurred, give them back what they had. - * It's not right, but it's better than nothing. - */ - ret_str = destination; - } else { - strlib_free(destination); - } - - CCAPP_DEBUG(DEB_F_PREFIX"Localization String returning %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ret_str); - return (ret_str); -} - -static boolean missed, placed, received; -void ccsnap_set_phone_services_provisioning(boolean misd, boolean plcd, boolean rcvd) { - CCAPP_ERROR(DEB_F_PREFIX"missed=%d placed=%d received=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_set_phone_services_provisioning"), misd, plcd, rcvd); - missed = misd; - placed = plcd; - received = rcvd; -} - -boolean ccsnap_isMissedCallLoggingEnabled() -{ - return missed; -} - -boolean ccsnap_isReceivedCallLoggingEnabled() -{ - return received; -} - -boolean ccsnap_isPlacedCallLoggingEnabled() -{ - return placed; -} - -/** - * Helper method - */ - -static void printCallInfo(cc_callinfo_ref_t info, const char* fname) { - CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ref_count); - CCAPP_DEBUG(DEB_F_PREFIX"data->sess_id=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->sess_id); - CCAPP_DEBUG(DEB_F_PREFIX"data->line=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->line); - CCAPP_DEBUG(DEB_F_PREFIX"data->id=%u", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->id); - CCAPP_DEBUG(DEB_F_PREFIX"data->inst=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->inst); - CCAPP_DEBUG(DEB_F_PREFIX"data->state=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->state); - CCAPP_DEBUG(DEB_F_PREFIX"data->attr=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->attr); - CCAPP_DEBUG(DEB_F_PREFIX"data->type=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->type); - CCAPP_DEBUG(DEB_F_PREFIX"data->security=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->security); - CCAPP_DEBUG(DEB_F_PREFIX"data->policy=%02X", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->policy); - CCAPP_DEBUG(DEB_F_PREFIX"data->isSelected=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->isSelected); - CCAPP_DEBUG(DEB_F_PREFIX"data->log_disp=%u", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->log_disp); - CCAPP_DEBUG(DEB_F_PREFIX"data->clg_name=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->clg_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->clg_number=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->clg_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->alt_number=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->alt_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->cld_name=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cld_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->cld_number=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cld_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->orig_called_name=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->orig_called_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->orig_called_number=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->orig_called_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->last_redir_name=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->last_redir_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->last_redir_number=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->last_redir_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->plcd_name=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->plcd_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->plcd_number=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->plcd_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->status=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->status); - CCAPP_DEBUG(DEB_F_PREFIX"data->gci=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->gci); - CCAPP_DEBUG(DEB_F_PREFIX"data->cause=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cause); - CCAPP_DEBUG(DEB_F_PREFIX"data->vid_dir=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->vid_dir); - CCAPP_DEBUG(DEB_F_PREFIX"data->vid_offer=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->vid_offer); - CCAPP_DEBUG(DEB_F_PREFIX"data->is_conf=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->is_conf); - CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_start=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_start); - CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_mode=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_mode); - CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_once=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_once); -} - -static void printFeatureInfo (ccapi_device_event_e type, cc_featureinfo_ref_t feature_info, const char* fname) { - CCAPP_DEBUG(DEB_F_PREFIX"data->button=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->button); - CCAPP_DEBUG(DEB_F_PREFIX"data->contact=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->contact); - CCAPP_DEBUG(DEB_F_PREFIX"data->featureOptionMask=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->featureOptionMask); - CCAPP_DEBUG(DEB_F_PREFIX"data->feature_id=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->feature_id); - CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->name); - CCAPP_DEBUG(DEB_F_PREFIX"data->retrievalPrefix=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->retrievalPrefix); - CCAPP_DEBUG(DEB_F_PREFIX"data->speedDialNumber=%s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->speedDialNumber); - if (type == CCAPI_DEVICE_EV_BLF) { - CCAPP_DEBUG(DEB_F_PREFIX"data->blf_state=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->blf_state); - } - -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h deleted file mode 100644 index 171b589f5e8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h +++ /dev/null @@ -1,115 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCAPI_SNAPSHOT_H_ -#define _CCAPI_SNAPSHOT_H_ - -#include "ccsip_platform.h" -#include "prot_configmgr.h" -#include "ccapi_line.h" - -/* - * MWI info - */ -typedef struct cc_mwi_info_t_ { - cc_uint32_t status; - cc_uint32_t type; - cc_uint32_t new_count; - cc_uint32_t old_count; - cc_uint32_t pri_new_count; - cc_uint32_t pri_old_count; -} cc_mwi_info_t; - -/* - * line reference data structure - */ -typedef struct cc_line_info_t_ { - cc_uint32_t ref_count; - cc_uint32_t line_id; - cc_uint32_t line_type; - cc_int32_t button; - cc_boolean reg_state; - cc_boolean isCFWD; - cc_boolean isLocalCFWD; - cc_mwi_info_t mwi; - cc_string_t name; - cc_string_t dn; - cc_string_t cfwd_dest; - cc_boolean allowed_features[CCAPI_CALL_CAP_MAX]; - cc_string_t externalNumber; - cc_boolean fwd_caller_name_display; - cc_boolean fwd_caller_number_display; - cc_boolean fwd_redirected_number_display; - cc_boolean fwd_dialed_number_display; -} cc_line_info_t; - -typedef struct cc_feature_info_t_ { - cc_int32_t feature_id; - cc_int32_t button; - cc_string_t speedDialNumber; - cc_string_t contact; - cc_string_t name; - cc_string_t retrievalPrefix; - cc_uint32_t featureOptionMask; - cc_blf_state_t blf_state; -} cc_feature_info_t; - -typedef struct cc_call_server_t_ { - cc_string_t name; - cc_ccm_status_t status; - cc_int32_t type; -} cc_call_server_t; - -typedef struct cc_device_info_t_ { - cc_uint32_t ref_count; - cc_string_t not_prompt; - char registration_ip_addr[MAX_IPADDR_STR_LEN]; - cc_int32_t not_prompt_prio; - cc_boolean not_prompt_prog; - cc_boolean mwi_lamp; - cc_cucm_mode_t cucm_mode; - cc_service_state_t ins_state; - cc_service_cause_t ins_cause; - long long reg_time; - cc_call_server_t ucm[CCAPI_MAX_SERVERS]; -} cc_device_info_t; - -typedef enum { - ACCSRY_CFGD_CFG, //accessory last configured by configuration file. - ACCSRY_CFGD_APK, //accessory last configured by another application. -} accsry_cfgd_by_t; - -typedef struct accessory_cfg_info_t_ { - accsry_cfgd_by_t camera; - accsry_cfgd_by_t video; -} accessory_cfg_info_t; - -extern accessory_cfg_info_t g_accessoryCfgInfo; -extern cc_device_info_t g_deviceInfo; -extern cc_line_info_t lineInfo[MAX_CONFIG_LINES+1]; - -cc_line_info_t* ccsnap_getLineInfo(int lineID); -cc_line_info_t* ccsnap_getLineInfoFromBtn(int btnID); -void ccsnap_line_init(); -void ccsnap_line_free(); -void ccsnap_device_init(); -void ccsnap_device_free(); -void ccsnap_gen_deviceEvent(ccapi_device_event_e event, cc_device_handle_t handle); -void ccsnap_gen_lineEvent(ccapi_line_event_e event, cc_lineid_t handle); -void ccsnap_gen_callEvent(ccapi_call_event_e event, cc_call_handle_t handle); -void ccsnap_update_ccm_status(cc_string_t addr, cc_ccm_status_t status); -void ccsnap_handle_mnc_reached (cc_line_info_t *line_info, - cc_boolean mnc_reached, cc_cucm_mode_t mode); -cc_feature_info_t* ccsnap_getFeatureInfo(int featureIndex); -void ccsnap_gen_blfFeatureEvent(cc_blf_state_t state, int appId); -cc_string_t ccsnap_EscapeStrToLocaleStr(cc_string_t destination, cc_string_t source, int len); -void ccsnap_set_phone_services_provisioning(boolean misd, boolean plcd, boolean rcvd); -boolean ccsnap_isMissedCallLoggingEnabled(); -boolean ccsnap_isReceivedCallLoggingEnabled(); -boolean ccsnap_isPlacedCallLoggingEnabled(); -void ccsnap_set_line_label(int btn, cc_string_t label); -cc_string_t ccsnap_get_line_label(int btn); - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.c deleted file mode 100644 index 33318e770fe..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.c +++ /dev/null @@ -1,149 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapp_task.h" -#include "phone.h" -#include "CCProvider.h" -#include "platform_api.h" - -#include -#include - -extern cprMsgQueue_t ccapp_msgq; -extern void CCAppInit(); -static sll_lite_list_t sll_list; - -PRCondVar *ccAppReadyToStartCond = NULL; -PRLock *ccAppReadyToStartLock = NULL; -char ccAppReadyToStart = 0; - -/** - * Add/Get ccapp task listener - */ -void addCcappListener(appListener* listener, int type) { - - listener_t *alistener = NULL; - - CCAPP_DEBUG(DEB_F_PREFIX"Entered: listenr=%p, type=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"), - listener, type); - - if (listener == NULL) - { - CCAPP_ERROR(DEB_F_PREFIX"listener is NULL, returning", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener")); - return; - } - - alistener = cpr_malloc(sizeof(listener_t)); - if (alistener == NULL) { - CCAPP_ERROR(DEB_F_PREFIX"alistener is NULL, returning", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener")); - return; - } - - alistener->type = type; - alistener->listener_p = listener; - - sll_lite_link_tail(&sll_list, (sll_lite_node_t *)alistener); - CCAPP_DEBUG(DEB_F_PREFIX"Added: listenr=%p, type=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"), - alistener->listener_p, alistener->type); -} - -appListener *getCcappListener(int type) { - static const char fname[] ="getCcappListener"; - listener_t *temp_info; - sll_lite_node_t *iterator; - - CCAPP_DEBUG(DEB_F_PREFIX"entered: for app[%d]", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - type); - - iterator = sll_list.head_p; - while (iterator) { - temp_info = (listener_t *)iterator; - CCAPP_DEBUG(DEB_F_PREFIX"appid=%d, listener=%p", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), temp_info->type, temp_info->listener_p); - if (temp_info->type == type) { - { - return temp_info->listener_p; - } - } - iterator = iterator->next_p; - } - return NULL; -} - -/** - * - * CC Provider wrapper for posting msg to CCAPP - * - * @param msgId - message ID - * @param data - ptr to data - * @param len - len of data - * - * @return CPR_SUCCESS/CPR_FAILURE - * - * @pre None - */ - -cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId) -{ - cprBuffer_t *msg; - static const char fname[] = "ccappPostMsg"; - cpr_status_e retval = CPR_SUCCESS; - - msg = (cprBuffer_t *) cpr_malloc(len); - if (msg == NULL) { - CCAPP_ERROR(DEB_F_PREFIX"failed to allocate message.", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return CPR_FAILURE; - } - - memcpy(msg, data, len); - - if ((retval=ccappTaskSendMsg(msgId, msg, len, appId)) == CPR_FAILURE) { - cpr_free(msg); - } - - return retval; -} - -/** - * - * CC Provider wrapper for cprSendMessage - * - * @param cmd - Command - * @param msg - msg ptr - * @param len - len of msg - * @param usr - - * - * @return CPR_SUCCESS/CPR_FAILURE - * - * @pre msg is a malloc mem ptr - */ -cpr_status_e -ccappTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, uint32_t UsrInfo) -{ - appListener *listener = NULL; - - CCAPP_DEBUG(DEB_F_PREFIX"Received Cmd[%d] for app[%d]", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__), - cmd, UsrInfo); - - listener = getCcappListener(UsrInfo); - if (listener != NULL) { - (* ((appListener)(listener)))(msg, cmd); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"Event[%d] doesn't have a dedicated listener.", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__), - UsrInfo); - } - cpr_free(msg); - - return CPR_SUCCESS; -} - -void CCApp_prepare_task() -{ - //initialize the listener list - sll_lite_init(&sll_list); - - CCAppInit(); -} - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.h b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.h deleted file mode 100644 index d33dce2edb2..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.h +++ /dev/null @@ -1,24 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CCAPP_TASK_H__ -#define __CCAPP_TASK_H__ -#include "sll_lite.h" - -//Define app id for ccapp task -#define CCAPP_CCPROVIER 1 -#define CCAPP_MSPROVIDER 2 - -typedef void(* appListener) (void *message, int type); -typedef struct { - sll_lite_node_t node; - int type; - appListener *listener_p; -} listener_t; - -extern void addCcappListener(appListener* listener, int type); -appListener *getCcappListener(int type); -cpr_status_e ccappTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, uint32_t usrInfo); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c b/media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c deleted file mode 100755 index e74509a8172..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c +++ /dev/null @@ -1,2253 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "timecard.h" -#include "CCProvider.h" -#include "ccSession.h" -#include "ccsip_task.h" -#include "cpr.h" -#include "cpr_stdlib.h" -#include "cpr_ipc.h" -#include "phone.h" -#include "phntask.h" -#include "ccapi.h" -#include "debug.h" -#include "phone_debug.h" -#include "dialplanint.h" -#include "configmgr.h" -#include "prot_configmgr.h" -#include "lsm.h" -#include "sip_common_regmgr.h" -#include "sessionHash.h" -#include "pres_sub_not_handler.h" -#include "cc_call_listener.h" -#include "cc_service_listener.h" -#include "cc_config.h" -#include "cc_device_listener.h" -#include "cc_service_listener.h" -#include "plat_api.h" -#include "cc_info_listener.h" -#include "cc_blf_listener.h" -#include "platform_api.h" -#include "ccapp_task.h" -#include "ccapi.h" -#include "capability_set.h" -#include "plat_debug.h" - -#include "config_api.h" -#include "ccapi_call_info.h" -#include "ccapi_call_listener.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "ccapi_line_listener.h" -#include "ccapi_device_listener.h" -#include "cc_device_manager.h" -#include "call_logger.h" -#include "subscription_handler.h" -#include "ccapi_device_info.h" -#include "conf_roster.h" -#include "reset_api.h" -#include "prlog.h" -#include "prlock.h" -#include "prcvar.h" - -/*--------------------------------------------------------- - * - * Definitions - * - */ -#define NOTIFY_CALL_STATUS (data->state == OFFHOOK? "OFFHOOK" : \ - data->state == ONHOOK? "ONHOOK" : \ - data->state == RINGOUT? "RINGOUT" : \ - data->state == RINGIN? "RINGIN" : \ - data->state == PROCEED ? "PROCEED" : \ - data->state == CONNECTED ? "CONNECTED" : \ - data->state == HOLD ? "HOLD" : \ - data->state == REMHOLD ? "REMHOLD" : \ - data->state == RESUME ? "RESUME" : \ - data->state == BUSY ? "BUSY" : \ - data->state == REORDER ? "REORDER" : \ - data->state == CONFERENCE ? "CONFERENCE" : \ - data->state == DIALING ? "DIALING" : \ - data->state == REMINUSE ? "REMINUSE" : \ - data->state == HOLDREVERT ? "HOLDREVERT" :\ - data->state == WHISPER ? "WHISPER" : \ - data->state == PRESERVATION ? "PRESERVATION" : \ - data->state == WAITINGFORDIGITS ? "WAITINGFORDIGITS" : \ - "Unknown state") - -#define CCAPP_TASK_CMD_PRINT(arg) ((arg) == CCAPP_SERVICE_CMD ? "CCAPP_SERVICE_CMD" : \ - (arg) == CCAPP_CREATE_SESSION ? "CCAPP_CREATE_SESSION" : \ - (arg) == CCAPP_CLOSE_SESSION ? "CCAPP_CLOSE_SESSION" : \ - (arg) == CCAPP_INVOKE_FEATURE ? "CCAPP_INVOKE_FEATURE" : \ - (arg) == CCAPP_SESSION_UPDATE ? "CCAPP_SESSION_UPDATE" : \ - (arg) == CCAPP_FEATURE_UPDATE ? "CCAPP_FEATURE_UPDATE" : \ - (arg) == CCAPP_UPDATELINES ? "CCAPP_UPDATELINES" : \ - (arg) == CCAPP_FAILOVER_IND ? "CCAPP_FAILOVER_IND" : \ - (arg) == CCAPP_FALLBACK_IND ? "CCAPP_FALLBACK_IND" : \ - (arg) == CCAPP_MODE_NOTIFY ? "CCAPP_MODE_NOTIFY" : \ - (arg) == CCAPP_SHUTDOWN_ACK ? "CCAPP_SHUTDOWN_ACK" : \ - (arg) == CCAPP_REG_ALL_FAIL ? "CCAPP_REG_ALL_FAIL" : \ - (arg) == CCAPP_INVOKEPROVIDER_FEATURE ? "CCAPP_INVOKEPROVIDER_FEATURE" : \ - (arg) == CCAPP_SEND_INFO ? "CCAPP_SEND_INFO" : \ - (arg) == CCAPP_RCVD_INFO ? "CCAPP_RCVD_INFO" : \ - (arg) == CCAPP_LOGOUT_RESET ? "CCAPP_LOGOUT_RESET" : \ - (arg) == CCAPP_SESSION_MGMT ? "CCAPP_SESSION_MGMT" : \ - (arg) == CCAPP_THREAD_UNLOAD ? "CCAPP_THREAD_UNLOAD" : \ - (arg) == CCAPP_SESSION_MGMT ? "CCAPP_SESSION_MGMT" : \ - "Unknown Cmd") - -#define APP_ERR_MSG(format, ...) CSFLogError("app" , format , ## __VA_ARGS__ ) - -#define MAX_REASON_LENGTH MAX_SIP_REASON_LENGTH -#define MAX_SESSION_PARAM_LEN 128 - -/* UNKNOWN_PHRASE_STR should equal the value returned - * if the phrase code is not found in the dictionary. - * For CIUS, this is found in LocalizedStrings.java */ -#define UNKNOWN_PHRASE_STR "???" -#define UNKNOWN_PHRASE_STR_SIZE 3 - -/*--------------------------------------------------------- - * - * Local Variables - * - */ - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -static CCAppGlobal_t gCCApp; -cc_int32_t g_CCAppDebug=TRUE; -cc_int32_t g_CCLogDebug=TRUE; -cc_int32_t g_NotifyCallDebug=TRUE; -cc_int32_t g_NotifyLineDebug=TRUE; - -cc_srv_ctrl_req_t reset_type; - -extern cprMsgQueue_t ccapp_msgq; -extern cprThread_t ccapp_thread; -extern boolean platform_initialized; -extern void resetReady(); -extern void resetNotReady(); -extern int sendResetUpdates; - -extern boolean apply_config; - -extern char g_new_signaling_ip[]; - -extern int configFileDownloadNeeded; -cc_action_t pending_action_type = NO_ACTION; -/* - * Bug 845357. Guard to avoid races related to gCCApp.state - */ -static PRLock *gAppStateLock = NULL; -static PRCondVar *gAppStateCondVar = NULL; -static int canReadCCAppState = 0; - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ -extern void send_protocol_config_msg(void); -extern void gsm_shutdown(void); -extern void sip_shutdown(void); -extern void dp_shutdown(void); -extern void MiscAppTaskShutdown(void); -extern void lsm_init(void); -extern void fsm_init(void); -extern void fim_init(void); -extern void SIPTaskPostRestart(boolean restart); -extern void ccsip_register_cancel(boolean cancel_reg, boolean backup_proxy); -extern void notify_register_update(int last_available_line); -extern void getLineIdAndCallId (line_t *line_id, callid_t *call_id); -extern void set_default_video_pref(int pref); -extern void set_next_sess_video_pref(int pref); -extern void cc_media_update_native_video_support(boolean val); -extern void cc_media_update_video_cap(boolean val); -extern void cc_media_update_video_txcap(boolean val); - -session_data_t * getDeepCopyOfSessionData(session_data_t *data); -static void ccappUpdateSessionData(session_update_t *sessUpd); -static void ccappFeatureUpdated (feature_update_t *featUpd); -void ccapp_shutdown(); -void ccpro_handleserviceControlNotify(); -/* Sets up mutex needed for protecting state variables. */ -static cc_int32_t InitInternal(); -static void ccapp_set_state(cc_reg_state_t state); - -/* Handy macro for executing memory barrier on CCApp State updates. */ -#define ENTER_CCAPPSTATE_PROTECT \ - PR_Lock(gAppStateLock); \ - canReadCCAppState = 0; - -#define EXIT_CCAPPSTATE_PROTECT \ - canReadCCAppState = 1; \ - PR_NotifyAllCondVar(gAppStateCondVar); \ - PR_Unlock(gAppStateLock); - -/*--------------------------------------------------------- - * - * Function declarations - * - */ - -cc_service_state_t mapProviderState(cc_reg_state_t state) -{ - switch(state) { - case CC_INSERVICE: - return CC_STATE_INS; - case CC_CREATED_IDLE: - return CC_STATE_IDLE; - case CC_OOS_REGISTERING: - case CC_OOS_FAILOVER: - case CC_OOS_IDLE: - default: - return CC_STATE_OOS; - - } -} - -static void ccapp_hlapi_update_device_reg_state() { - g_deviceInfo.ins_state = mapProviderState(gCCApp.state); - g_deviceInfo.ins_cause = gCCApp.cause; - g_deviceInfo.cucm_mode = gCCApp.mode; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_STATE, CC_DEVICE_ID); -} - -void ccpro_handleINS() { - registration_processEvent(EV_CC_INSERVICE); -} - -void ccpro_handleOOS() { - switch(gCCApp.cause){ - case CC_CAUSE_REG_ALL_FAILED: - registration_processEvent(EV_CC_OOS_REG_ALL_FAILED); - break; - case CC_CAUSE_FAILOVER: - registration_processEvent(EV_CC_OOS_FAILOVER); - break; - case CC_CAUSE_FALLBACK: - registration_processEvent(EV_CC_OOS_FALLBACK); - break; - case CC_CAUSE_SHUTDOWN: - registration_processEvent(EV_CC_OOS_SHUTDOWN_ACK); - break; - } -} - -cc_boolean is_action_to_be_deferred(cc_action_t action) { - if (CCAPI_DeviceInfo_isPhoneIdle(CC_DEVICE_ID) == FALSE) { - pending_action_type = action; - DEF_DEBUG("Action deferred=%d", action); - return TRUE; - } else { - return FALSE; - } -} - -void perform_deferred_action() { - cc_action_t temp_action = pending_action_type; - - if (is_action_to_be_deferred(pending_action_type) == TRUE) { - return; - } - - pending_action_type = NO_ACTION; - DEF_DEBUG("Perform deferred action=%d", temp_action); - - if (temp_action == RESET_ACTION || temp_action == RESTART_ACTION) { - ccpro_handleserviceControlNotify(); - } else if (temp_action == RE_REGISTER_ACTION) { - CCAPI_Service_reregister(g_dev_hdl, g_dev_name, g_cfg_p, g_compl_cfg); - } else if (temp_action == STOP_ACTION) { - CCAPI_Service_stop(); - } else if (temp_action == DESTROY_ACTION) { - CCAPI_Service_destroy(); - } -} - -void ccpro_handleserviceControlNotify() { - cc_action_t temp_action = NO_ACTION; - if (reset_type == CC_DEVICE_RESET) { - temp_action = RESET_ACTION; - } else if (reset_type == CC_DEVICE_RESTART) { - temp_action = RESTART_ACTION; - } - - if ((reset_type != CC_DEVICE_ICMP_UNREACHABLE) && - is_action_to_be_deferred(temp_action) == TRUE) { - return; - } - - - if (reset_type == CC_DEVICE_RESET) { - resetRequest(); - } else if (reset_type == CC_DEVICE_RESTART) { - registration_processEvent(EV_CC_DO_SOFT_RESET); - } -} - -/** - * Initializes guard to protect gCCApp.state - */ - -static cc_int32_t InitInternal() { - gAppStateLock = PR_NewLock(); - if(!gAppStateLock) { - return FALSE; - } - gAppStateCondVar = PR_NewCondVar(gAppStateLock); - if(!gAppStateCondVar) { - return FALSE; - } - return TRUE; -} - -/** - * Setter for the CCApp state - */ - -static void ccapp_set_state(cc_reg_state_t state) { - ENTER_CCAPPSTATE_PROTECT; - gCCApp.state = state; - EXIT_CCAPPSTATE_PROTECT; -} - -/** - * Returns the registration state - */ - -cc_reg_state_t ccapp_get_state() { - /* wait till the ongoing modification is completed */ - cc_reg_state_t state; - if (gAppStateCondVar) { - PR_Lock(gAppStateLock); - while (!canReadCCAppState) { - PR_WaitCondVar(gAppStateCondVar, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(gAppStateLock); - } - state = gCCApp.state; - return state; -} - -/** - * - * CCApp Provider init routine. - * - * @param none - * - * @return void - * - * @pre None - */ -void CCAppInit() -{ - ccProvider_state_t srvcState; - if(InitInternal() == FALSE) { - return; - } - ccapp_set_state(CC_CREATED_IDLE); - gCCApp.cause = CC_CAUSE_NONE; - gCCApp.mode = CC_MODE_INVALID; - gCCApp.cucm_mode = NONE_AVAIL; - if (platThreadInit("CCApp_Task") != 0) { - return; - } - - debug_bind_keyword("cclog", &g_CCLogDebug); - srvcState.cause = gCCApp.cause; // XXX set but not used - srvcState.mode = gCCApp.mode; // XXX set but not used - (void) srvcState; - - //Add listeners - //CCProvider lister - DEF_DEBUG(DEB_F_PREFIX"Add ccp listener: type%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAppInit"), - CCAPP_CCPROVIER); - - addCcappListener((appListener *)ccp_handler, CCAPP_CCPROVIER); -} - -/* - * Function: processProviderEvent - * - * Description: inform session events to CCApp - * - * Parameters: - * call_id - call identifier - * line_id - line identifier - * - * Returns: none - */ -void -processProviderEvent (line_t line_id, unsigned int event, int data) -{ - static const char fname[] = "processProviderEvent"; - callid_t call_id = 0; - - DEF_DEBUG(DEB_F_PREFIX"line=%d event=%d data=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - line_id, event, data); - switch(event) { - case DEVICE_FEATURE_CFWD: - getLineIdAndCallId(&line_id, &call_id); - if (lsm_is_line_available(line_id, FALSE) == FALSE) { - //Send onhook to indicate session closure. - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATE, CREATE_CALL_HANDLE(line_id, call_id)); - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - break; - } - - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_CFWD_ALL, NULL); - - break; - case DEVICE_SUPPORTS_NATIVE_VIDEO: - cc_media_update_native_video_support(data); - break; - case DEVICE_ENABLE_VIDEO: - cc_media_update_video_cap(data); - break; - case DEVICE_ENABLE_CAMERA: - cc_media_update_native_video_txcap(data); - break; - } -} - - -/* - * Function: CheckAndGetAvailableLine - * - * Parameters: - * line - line identifier - * call - call identifier - * - * Returns: TRUE if a line is available. - */ -static boolean CheckAndGetAvailableLine(line_t *line, callid_t *call) -{ - /* - * case 1: line>0 & call>0: invoking this in an offhook session. - * case 2: line>0 & call=0: invoking this onhook with simple filter active - * case 3: line=0 & call=0: invoking this in onhook with all calls filter active - */ - if ((*line > 0) && (*call == 0)) { - if (lsm_is_line_available(*line, FALSE) == FALSE) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return FALSE; - } - } - else if ((*line == 0) && (*call == 0)) { - *line = lsm_get_available_line(FALSE); - if (*line == 0 ) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return FALSE; - } - } - *call = (*call == 0) ? cc_get_new_call_id() : *call; - return TRUE; -} - -/* - * Function: getVideoPref - * - * Description: get video direction if specified - * - * Parameters: - * data - urn param - * - * Returns: sdp_direction_e - requested video direction - */ -sdp_direction_e getVideoPref( string_t data) -{ - if ( data == NULL ) { - return SDP_MAX_QOS_DIRECTIONS; - } - - if ( strstr(data, "video=sendrecv")) { - return SDP_DIRECTION_SENDRECV; - } else if (strstr(data, "video=sendonly")) { - return SDP_DIRECTION_SENDONLY; - } else if (strstr(data, "video=recvonly")){ - return SDP_DIRECTION_RECVONLY; - } else if (strstr(data, "video=none")){ - return SDP_DIRECTION_INACTIVE; - } else { - return SDP_MAX_QOS_DIRECTIONS; - } -} - -/* - * Function: updateSessionVideoPref - * - * Description: update video direction for the session only - * - * Parameters: - * line_id - line at which the session needs the video pref updated - * call_id - callid for which the session needs the video pref updated - * dir - video pref - * - * Returns: - */ -static void updateSessionVideoPref( line_t line_id, callid_t call_id, sdp_direction_e video_pref) -{ - static const char fname[] = "updateSessionVideoPref"; - cc_feature_data_t featdata; - - DEF_DEBUG(DEB_L_C_F_PREFIX"updating to %d video capapbility %s", - DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, call_id, line_id, fname), video_pref, - (video_pref == SDP_DIRECTION_INACTIVE ? "disabled" : "enabled")); - featdata.caps.support_direction = video_pref; - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_UPD_SESSION_MEDIA_CAP, &featdata); -} - -/* - * Function: updateVideoPref - * - * Description: update video direction if specified - * - * Parameters: - * line_id - line at which the session needs the video pref updated - * call_id - callid for which the session needs the video pref updated - * data - urn param - * - * Returns: - */ - -static void updateVideoPref( unsigned int event, line_t line_id, callid_t call_id, sdp_direction_e video_pref/*string_t data*/) -{ - static const char fname[] = "updateVideoPref"; - - if ( video_pref == SDP_MAX_QOS_DIRECTIONS ) { - // we are done no updates needed - return; - } - - switch (event) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - if ( call_id == CC_NO_CALL_ID ) { - // This is the only means to update the default behavior - set_default_video_pref(video_pref); - } else { - updateSessionVideoPref(line_id, call_id, video_pref); - } - break; - case CC_FEATURE_DIALSTR: - case CC_FEATURE_DIAL: - case CC_FEATURE_SPEEDDIAL: - case CC_FEATURE_REDIAL: - if ( call_id == CC_NO_CALL_ID ) { - set_next_sess_video_pref(video_pref); - } else { - updateSessionVideoPref(line_id, call_id, video_pref); - } - break; - case CC_FEATURE_NEW_CALL: - case CC_FEATURE_OFFHOOK: - case CC_FEATURE_CONF: - case CC_FEATURE_B2BCONF: - case CC_FEATURE_XFER: - set_next_sess_video_pref(video_pref); - break; - case CC_FEATURE_RESUME: - case CC_FEATURE_ANSWER: - updateSessionVideoPref(line_id, call_id, video_pref); - break; - default: - CCAPP_DEBUG(DEB_L_C_F_PREFIX"event=%d. update to %d not supported", - DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, call_id, line_id, fname), event, video_pref); - - } -} - -/* - * Function: getDigits - * - * Description: returns the first param before the ; - * - * Parameters: - * data - urn param - * digits - memory to return the first param - * Returns: - */ -static void getDigits(string_t data, char *digits, unsigned int buffer_length) { - char *endptr; - unsigned int len=0; - - digits[0]=0; - - if ( data !=NULL ) { - endptr = strchr(data,';'); - if ( endptr ) { - len = endptr - data; - } else { - len = strlen(data); - } - - /* prevent len from writing past buffer size */ - if (len >= buffer_length) { - len = buffer_length - 1; - } - - if ( len) { - memcpy(digits, data, len); - digits[len] = 0; - } - } -} - -/* - * Function: processSessionEvent - * - * Description: inform session events to CCApp - * - * Parameters: - * call_id - call identifier - * line_id - line identifier - * - * Returns: none - */ -void -processSessionEvent (line_t line_id, callid_t call_id, unsigned int event, sdp_direction_e video_pref, ccSession_feature_t ccData) -{ - static const char fname[] = "processSessionEvent"; - cc_feature_data_t featdata; - int instance = line_id; - boolean incoming = FALSE; - session_data_t * sess_data_p; - char digits[CC_MAX_DIALSTRING_LEN]; - char* data = (char*)ccData.info; - char* data1 =(char*)ccData.info1; - long strtol_result; - char *strtol_end; - Timecard *timecard = ccData.timecard; - int sdpmode = 0; - - - CCAPP_DEBUG(DEB_L_C_F_PREFIX"event=%d data=%s", - DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, call_id, line_id, fname), event, - ((event == CC_FEATURE_KEYPRESS) ? "..." : data)); - - memset(&featdata, 0, sizeof(cc_feature_data_t)); - - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - updateVideoPref(event, line_id, call_id, video_pref); - } - - switch(event) { - case CC_FEATURE_ONHOOK: - getLineIdAndCallId(&line_id, &call_id); - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_ONHOOK = %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data); - cc_onhook_ext(CC_SRC_UI, call_id, line_id, FALSE, - (data && (strncasecmp(data, "ACTIVECALLS", sizeof("ACTIVECALLS")) == 0))? - CC_REASON_ACTIVECALL_LIST: CC_REASON_NULL ); - break; - case CC_FEATURE_KEYPRESS: - dp_int_update_keypress(line_id, call_id, (unsigned char)*data); - break; - case CC_FEATURE_BKSPACE: - dp_int_update_keypress(line_id, call_id, BKSP_KEY); - break; - case CC_FEATURE_DIALSTR: - if (CheckAndGetAvailableLine(&line_id, &call_id) == TRUE) { - getDigits(data, digits, sizeof(digits)); - if (strlen(digits) == 0) { - //if dial string is empty then go offhook - cc_offhook(CC_SRC_UI, call_id, line_id); - } else { - dp_int_init_dialing_data(line_id, call_id); - dp_int_dial_immediate(line_id, call_id, TRUE, - (char *)digits, NULL, CC_MONITOR_NONE); - } - } - break; - - case CC_FEATURE_DIAL: - dp_int_dial_immediate(line_id, call_id, FALSE, NULL, NULL, CC_MONITOR_NONE); - break; - case CC_FEATURE_SPEEDDIAL: - /* - * BLF Pickup Line Selection: - * ------------------------- - * - * case 1: line_id>0 & call_id>0 : BLF key press after going offhook on a given line. - * Check if the given line has available call capacity. If not, end the session - * and display STR_INDEX_NO_LINE_FOR_PICKUP toast. - * - * case 2: line_id>0 & call_id=0 : BLF key press w/o offhook when a simple filter is active. - * Check if the given line has available call capacity. If not, find the next available line. - * If no available line is found, display STR_INDEX_NO_LINE_FOR_PICKUP toast. - * - * case 3: line_id=0 & call_id=0 : BLF key press w/o offhook when a AllCalls filter is active. - * Find an available line. If no available line is found, - * display STR_INDEX_NO_LINE_FOR_PICKUP toast. - */ - if (strncmp(data, CISCO_BLFPICKUP_STRING, (sizeof(CISCO_BLFPICKUP_STRING) - 1)) == 0) { - if ((instance > 0) && (call_id > 0)) { - if (lsm_is_line_available(instance, incoming) == FALSE) { - session_update_t sessUpd; - sessUpd.eventID = CALL_STATE; - sessUpd.sessionID = createSessionId(line_id, call_id); - sessUpd.sessType = SESSIONTYPE_CALLCONTROL; - sessUpd.update.ccSessionUpd.data.state_data.state = evOnHook; - sessUpd.update.ccSessionUpd.data.state_data.line_id = line_id; - sessUpd.update.ccSessionUpd.data.state_data.cause = CC_CAUSE_NORMAL; - ccappUpdateSessionData(&sessUpd); - // Pass this update to Session Manager - lsm_ui_display_notify_str_index(STR_INDEX_NO_LINE_FOR_PICKUP); - break; - } - } - else if ((instance > 0) && (call_id == 0)) { - if (lsm_is_line_available(instance, incoming) == FALSE) { - line_id = lsm_get_available_line(incoming); - if (line_id == 0 ) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_NO_LINE_FOR_PICKUP); - break; - } - } - } - else if ((instance == 0) && (call_id == 0)) { - line_id = lsm_get_available_line(incoming); - if (line_id == 0 ) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_NO_LINE_FOR_PICKUP); - break; - } - } - call_id = (call_id == 0) ? cc_get_new_call_id() : call_id; - } - /* - * SpeedDial Line Selection: - * ------------------------ - * - * case 1: line_id>0 & call_id>0 : speeddial key press after going offhook on a given line. - * Simply use this line to make an outgoing call. - * - * case 2: line_id>0 & call_id=0 : SD key press w/o offhook when a simple filter is active. - * Check if the given line has available call capacity. If not, - * display STR_INDEX_ERROR_PASS_LIMIT toast. - * - * case 3: line_id=0 & call_id=0 : SD key press w/o offhook when a AllCalls filter is active. - * Find an available line. If no available line is found, - * display STR_INDEX_ERROR_PASS_LIMIT toast. - */ - else if (CheckAndGetAvailableLine(&line_id, &call_id) == FALSE) { - break; - } - - getDigits(data, digits, sizeof(digits)); - - dp_int_init_dialing_data(line_id, call_id); - dp_int_dial_immediate(line_id, call_id, TRUE, - digits, NULL, CC_MONITOR_NONE); - break; - case CC_FEATURE_BLIND_XFER_WITH_DIALSTRING: - featdata.xfer.cause = CC_CAUSE_XFER_LOCAL_WITH_DIALSTRING; - sstrncpy(featdata.xfer.dialstring, (char *)data, CC_MAX_DIALSTRING_LEN); - cc_feature(CC_SRC_UI, call_id, (line_t)instance, CC_FEATURE_BLIND_XFER, - &featdata); - break; - case CC_FEATURE_REDIAL: - if (line_id == 0) { - /* - * If line_id is zero, get the last dialed line. - */ - line_id = dp_get_redial_line(); - if (line_id == 0) { - break; - } - } - - /* if not an existing call, check capacity on the line */ - if (call_id == CC_NO_CALL_ID) { - if (lsm_is_line_available(line_id, FALSE) == FALSE) { - /* - * since the session is not created yet, no - * need to close the session. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - break; - } else { - /* we have capacity and call does not exist */ - call_id = cc_get_new_call_id(); - } - } - dp_int_do_redial(line_id, call_id); - break; - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - /* handled in updateVideoPref() just outside of the switch */ - break; - - case CC_FEATURE_NEW_CALL: - case CC_FEATURE_OFFHOOK: - if (lsm_is_line_available(line_id, FALSE) == FALSE) { - //close the session - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_OFFHOOK: no available line.", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATE, CREATE_CALL_HANDLE(line_id, call_id)); - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - break; - } - - if (call_id == 0) { - call_id = cc_get_new_call_id(); - } else { - if (event == CC_FEATURE_NEW_CALL) { - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_NEW_CALL called with callid=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), call_id); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_OFFHOOK called with callid=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), call_id); - } - } - cc_offhook(CC_SRC_UI, call_id, line_id); - break; - - case CC_FEATURE_CFWD_ALL: - getLineIdAndCallId(&line_id, &call_id); - - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_CFWD_ALL, NULL); - - break; - - case CC_FEATURE_RESUME: - case CC_FEATURE_ANSWER: - - sess_data_p = (session_data_t *)findhash(createSessionId(line_id, call_id)); - if ( sess_data_p == NULL ) { - break; - } - if (sess_data_p->state == HOLD || sess_data_p->state == HOLDREVERT) { - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_RESUME, NULL); - } else { - cc_feature(CC_SRC_UI, call_id, line_id, event, NULL); - } - break; - - case CC_FEATURE_END_CALL: - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_ONHOOK = %s", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data); - if (data && (strcmp(data, "ACTIVECALLS") == 0)) { - getLineIdAndCallId(&line_id, &call_id); - cc_onhook_ext(CC_SRC_UI, call_id, line_id, TRUE, CC_REASON_ACTIVECALL_LIST); - } else { - cc_feature(CC_SRC_UI, call_id, line_id, event, NULL); - } - break; - - case CC_FEATURE_CONF: - // for CUCM mode we will translate CONF to B2BCONF - if ( gCCApp.mode == CC_MODE_CCM ) { - if ( gCCApp.mode == CC_MODE_CCM && platGetFeatureAllowed(CC_SIS_B2B_CONF) ) { - //CUCME can't support B2BCONF currently. - event = CC_FEATURE_B2BCONF; - } - }// DON'T ADD BREAK HERE. EVENT IS PASSED BELOW - case CC_FEATURE_B2BCONF: - case CC_FEATURE_XFER: - getDigits(data, digits, sizeof(digits)); - if ( strlen(digits)) { - cc_feature_data_t ftr_data; - CCAPP_DEBUG(DEB_F_PREFIX"conf: sid=%s.", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),data); - // if data is received we need to extract the call id - // and send target_call_id in feature_data - // Post the event on the original call ( received call id as string in data). - if ( event == CC_FEATURE_B2BCONF ) { - ftr_data.b2bconf.target_call_id = call_id; - } else if ( event == CC_FEATURE_XFER ) { - ftr_data.xfer.target_call_id = call_id; - } else if ( event == CC_FEATURE_CONF) { - //Legacy local conference. - ftr_data.cnf.target_call_id = call_id; - } - - errno = 0; - strtol_result = strtol(digits, &strtol_end, 10); - - if (errno || digits == strtol_end || strtol_result < INT_MIN || strtol_result > INT_MAX) { - CCAPP_ERROR(DEB_F_PREFIX"digits parse error %s.",DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__), digits); - } else { - cc_feature(CC_SRC_UI, GET_CALLID((int) strtol_result), line_id, event, &ftr_data); - } - break; - } else { - CCAPP_DEBUG(DEB_F_PREFIX"conf: no sid.",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - }// DON'T ADD BREAK HERE. EVENT IS PASSED BELOW - - case CC_FEATURE_B2B_JOIN: - case CC_FEATURE_DIRTRXFR: - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - cc_feature(CC_SRC_UI, call_id, line_id, event, NULL); - break; - - case CC_FEATURE_HOLD: - if (data && ((strcmp(data, "TRANSFER") == 0) || - (strcmp(data, "CONFERENCE") == 0) || (strcmp(data, "SWAP") == 0))) { - featdata.hold.call_info.data.hold_resume_reason = CC_REASON_SWAP; - } else { - - featdata.hold.call_info.data.hold_resume_reason = CC_REASON_NONE; - } - featdata.hold.call_info.type = CC_FEAT_HOLD; - featdata.hold.msg_body.num_parts = 0; - cc_feature(CC_SRC_UI, call_id, line_id, event, &featdata); - break; - - default: - break; - } -} - -void CCAppShutdown() -{ -} - - -static char * ccapp_cmd_to_str(unsigned int cmd) { - switch (cmd) { - case CMD_INSERVICE: - return "CMD_INSERVICE"; - case CMD_SHUTDOWN: - return "CMD_SHUTDOWN"; - case CMD_RESTART: - return "CMD_RESTART"; - case CMD_UNREGISTER_ALL_LINES: - return "CMD_UNREGISTER_ALL_LINES"; - case CMD_REGISTER_ALL_LINES: - return "CMD_REGISTER_ALL_LINES"; - default: - return "CMD_UNKNOWN"; - } -} -/** - * - * CC Provider process service Cmds - * - * @param cmd - Command - * @param reason - reason - * @param reasonStr - reason string - * - * @return void - * - * @pre None - */ -void CCApp_processCmds(unsigned int cmd, unsigned int reason, string_t reasonStr) -{ - static const char fname[] = "CCApp_processCmds"; - CCAPP_DEBUG(DEB_F_PREFIX" Received Cmd %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, - fname), ccapp_cmd_to_str(cmd)); - switch (cmd) { - case CMD_INSERVICE: - ccsnap_device_init(); - ccsnap_line_init(); - ccapp_set_state(CC_OOS_REGISTERING); - send_protocol_config_msg(); - break; - case CMD_SHUTDOWN: - case CMD_UNREGISTER_ALL_LINES: - /* send a shutdown message to the SIP Task */ - SIPTaskPostShutdown(SIP_EXTERNAL, reason, reasonStr); - ccsnap_line_free(); - ccsnap_device_free(); - break; - case CMD_RESTART: - SIPTaskPostRestart(TRUE); - break; - case CMD_BLF_INIT: - pres_sub_handler_initialized(); - break; - default: - APP_ERR_MSG("CCApp_processCmds: Error: Unknown message %d", cmd); - break; - } -} - -boolean isNoCallExist() -{ - hashItr_t itr; - - hashItrInit(&itr); - - return (hashItrNext(&itr)?FALSE:TRUE); -} - -/** - * Make deep copy of session_data_t - */ -session_data_t * getDeepCopyOfSessionData(session_data_t *data) -{ - session_data_t *newData = (session_data_t *) cpr_malloc(sizeof(session_data_t)); - - if ( newData != NULL ) { - memset(newData, 0, sizeof(session_data_t)); - - if ( data != NULL ) { - *newData = *data; - newData->ref_count = 1; - newData->clg_name = strlib_copy(data->clg_name); - newData->clg_number = strlib_copy(data->clg_number); - newData->cld_name = strlib_copy(data->cld_name); - newData->cld_number = strlib_copy(data->cld_number); - newData->alt_number = strlib_copy(data->alt_number); - newData->orig_called_name = strlib_copy(data->orig_called_name); - newData->orig_called_number = strlib_copy(data->orig_called_number); - newData->last_redir_name = strlib_copy(data->last_redir_name); - newData->last_redir_number = strlib_copy(data->last_redir_number); - newData->plcd_name = strlib_copy(data->plcd_name); - newData->plcd_number = strlib_copy(data->plcd_number); - newData->status = strlib_copy(data->status); - - calllogger_copy_call_log(&newData->call_log, &data->call_log); - } else { - newData->ref_count = 1; - newData->state = ONHOOK; - newData->security = CC_SECURITY_NONE; - newData->policy = CC_POLICY_NONE; - newData->clg_name = strlib_empty(); - newData->clg_number = strlib_empty(); - newData->cld_name = strlib_empty(); - newData->cld_number = strlib_empty(); - newData->alt_number = strlib_empty(); - newData->orig_called_name = strlib_empty(); - newData->orig_called_number = strlib_empty(); - newData->last_redir_name = strlib_empty(); - newData->last_redir_number = strlib_empty(); - newData->plcd_name = strlib_empty(); - newData->plcd_number = strlib_empty(); - newData->status = strlib_empty(); - calllogger_init_call_log(&newData->call_log); - } - - } - return newData; -} - - -/** - * - * CCApp Provider search for session and deepfree data - * - * @return ptr to session data - * - * @pre None - */ - -void cleanSessionData(session_data_t *data) -{ - if ( data != NULL ) { - strlib_free(data->clg_name); - data->clg_name = strlib_empty(); - strlib_free(data->clg_number); - data->clg_number = strlib_empty(); - strlib_free(data->alt_number); - data->alt_number = strlib_empty(); - strlib_free(data->cld_name); - data->cld_name = strlib_empty(); - strlib_free(data->cld_number); - data->cld_number = strlib_empty(); - strlib_free(data->orig_called_name); - data->orig_called_name = strlib_empty(); - strlib_free(data->orig_called_number); - data->orig_called_number = strlib_empty(); - strlib_free(data->last_redir_name); - data->last_redir_name = strlib_empty(); - strlib_free(data->last_redir_number); - data->last_redir_number = strlib_empty(); - strlib_free(data->plcd_name); - data->plcd_name = strlib_empty(); - strlib_free(data->plcd_number); - data->plcd_number = strlib_empty(); - strlib_free(data->status); - data->status = strlib_empty(); - calllogger_free_call_log(&data->call_log); - } -} - -/** - * - * CCApp Provider check for CONNECTED calls for preservation - * - * @return boolean - do we need to move in call preservation phase - * - * @pre None - */ - -boolean ccappPreserveCall() -{ - static const char fname[] = "ccappPreserveCall"; - hashItr_t itr; - session_data_t *data; - boolean retVal = FALSE; - - CCAPP_DEBUG(DEB_F_PREFIX"called", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL ) { - if ( data->state == CONNECTED || data->state == PRESERVATION ) { - // need to wait for this call to end. - CCAPP_DEBUG(DEB_F_PREFIX"inPreservation = true", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - gCCApp.inPreservation = TRUE; - gCCApp.preservID = data->sess_id; - capset_get_allowed_features(gCCApp.mode, PRESERVATION, data->allowed_features); - ccsnap_gen_callEvent(CCAPI_CALL_EV_PRESERVATION, CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id)); - retVal = TRUE; - } else { - // End this call now - CCAPP_DEBUG(DEB_F_PREFIX"ending call %x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id); - /* - * Note that for calls in state such as RIU, HOLD etc. - * we must send ON hook event (cc_onhook) instead of - * CC_FEATURE_END_CALL because corrsponding state machines - * handle only onhook event to clean up calls. - */ - cc_onhook(CC_SRC_UI, GET_CALLID(data->sess_id), - GET_LINEID(data->sess_id), TRUE); - - } - } - - return retVal; -} - -/** - * - * CCApp Provider check if its safe to proceed with failover/fallback - * - * @return void - do we need to move in call preservation phase - * - * @pre None - */ - -void proceedWithFOFB() -{ - static const char fname[] = "proceedWithFOFB"; - - CCAPP_DEBUG(DEB_F_PREFIX"called. preservation=%d in cucm mode=%s", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - gCCApp.inPreservation, - gCCApp.cucm_mode == FAILOVER ? "FAILOVER": - gCCApp.cucm_mode == FALLBACK ? "FALLBACK": - gCCApp.cucm_mode == NO_CUCM_SRST_AVAILABLE ? - "NO_CUCM_SRST_AVAILABLE": "NONE"); - ccapp_set_state(CC_OOS_REGISTERING); - - switch(gCCApp.cucm_mode) - { - case FAILOVER: - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FAILOVER_RSP, TRUE); - gCCApp.cause = CC_CAUSE_FAILOVER; - break; - - case FALLBACK: - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FALLBACK_RSP, TRUE); - gCCApp.cause = CC_CAUSE_FALLBACK; - break; - - case NO_CUCM_SRST_AVAILABLE: - gCCApp.cause = CC_CAUSE_REG_ALL_FAILED; - ccapp_set_state(CC_OOS_IDLE); - break; - default: - break; - } - - // Notify OOS state to Session Manager - switch (mapProviderState(ccapp_get_state())) { - case CC_STATE_OOS: - ccpro_handleOOS(); - break; - default: - break; - } - ccapp_hlapi_update_device_reg_state(); -} -/** - * - * ccappHandleRegUpdates handles reg state changes. - * - * @param featUpd - feature update with reg state msg - * - * @return void - * - * @pre None - */ -void ccappHandleRegStateUpdates(feature_update_t *featUpd) -{ - static const char fname[] = "ccappHandleRegStateUpdates"; - - CCAPP_DEBUG(DEB_F_PREFIX"called. feature=%d=%s, state=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), featUpd->featureID, CCAPP_TASK_CMD_PRINT(featUpd->featureID), gCCApp.state); - gCCApp.cause = CC_CAUSE_NONE; - - // Update state varaibles to track state - switch (featUpd->featureID) - { - case CCAPP_MODE_NOTIFY: - gCCApp.mode = featUpd->update.ccFeatUpd.data.line_info.info; - CCAPP_DEBUG(DEB_F_PREFIX"called. gCCApp.mode= %d gCCApp.state=%d. Returning", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), gCCApp.mode, gCCApp.state); - return; - - case CCAPP_FAILOVER_IND: - ccapp_set_state(CC_OOS_FAILOVER); - gCCApp.cucm_mode = FAILOVER; - gCCApp.cause = CC_CAUSE_FAILOVER; - if ( featUpd->update.ccFeatUpd.data.line_info.info == CC_TYPE_CCM ){ - gCCApp.mode = CC_MODE_CCM; - } - - else if (featUpd->update.ccFeatUpd.data.line_info.info == 3) { - gCCApp.mode = CC_MODE_NONCCM; - } - - if ( ccappPreserveCall() == FALSE) { - ccapp_set_state(CC_OOS_REGISTERING); - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FAILOVER_RSP, FALSE); - } - break; - - case CCAPP_FALLBACK_IND: - gCCApp.cucm_mode = FALLBACK; - if ( featUpd->update.ccFeatUpd.data.line_info.info == CC_TYPE_CCM ){ - gCCApp.mode = CC_MODE_CCM; - } - if ( isNoCallExist() ) { - ccapp_set_state(CC_OOS_REGISTERING); - gCCApp.cause = CC_CAUSE_FALLBACK; - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FALLBACK_RSP, FALSE); - } - break; - - case CCAPP_SHUTDOWN_ACK: - ccapp_set_state(CC_OOS_IDLE); - gCCApp.cucm_mode = NONE_AVAIL; - gCCApp.inPreservation = FALSE; - gCCApp.cause = CC_CAUSE_SHUTDOWN; - - break; - case CCAPP_REG_ALL_FAIL: - ccapp_set_state(CC_OOS_IDLE); - gCCApp.cucm_mode = NO_CUCM_SRST_AVAILABLE; - gCCApp.inPreservation = FALSE; - if (ccappPreserveCall() == FALSE) { - gCCApp.cause = CC_CAUSE_REG_ALL_FAILED; - } else { - gCCApp.cause = CC_CAUSE_FAILOVER; - } - break; - - case CCAPP_LOGOUT_RESET: - ccapp_set_state(CC_OOS_IDLE); - gCCApp.cucm_mode = NONE_AVAIL; - /*gCCApp.inFailover = FALSE; - gCCApp.inFallback = FALSE;*/ - gCCApp.inPreservation = FALSE; - gCCApp.cause = CC_CAUSE_LOGOUT_RESET; - break; - } - // Notify INS/OOS state to Session Manager if required - CCAPP_DEBUG(DEB_F_PREFIX"called. service_state=%d, mode=%d, cause=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - mapProviderState(gCCApp.state), - gCCApp.mode, - gCCApp.cause); - switch (mapProviderState(ccapp_get_state())) { - case CC_STATE_INS: - ccpro_handleINS(); - break; - case CC_STATE_OOS: - ccpro_handleOOS(); - break; - default: - break; - } - ccapp_hlapi_update_device_reg_state(); -} - -/* - * this function determine if the called number (i.e., dialed number) contains - * string x-cisco-serviceuri-cfwdall. - */ -static boolean ccappCldNumIsCfwdallString(string_t cld_number) { - static char cfwdAllString[STATUS_LINE_MAX_LEN] = "x-cisco-serviceuri-cfwdall"; - - if (strncmp(cld_number, cfwdAllString, strlen(cfwdAllString)) == 0) { - /* The Called Party number is the Call Forward all URI */ - return ((int) TRUE); - } - return ((int) FALSE); -} - -/** - * Api to update mute state of connected call - */ -cc_call_handle_t ccappGetConnectedCall(){ - session_data_t * data; - hashItr_t itr; - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL ) { - if( data->state == CONNECTED ) { - return CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - return 0; -} - -/** - * - * CCApp Provider cache session data to hashTable routine - * - * @param sessUpd - Session update from CC - * - * @return void - * - * @pre None - */ - -static void ccappUpdateSessionData (session_update_t *sessUpd) -{ - static const char fname[] = "ccappUpdateSessionData"; - /* TODO -- I don't think the hash handling is synchronized; we could - end up with data integrity issues here if we end up in a race. - */ - session_data_t *data = (session_data_t *)findhash(sessUpd->sessionID); - session_data_t *sess_data_p; - boolean createdSessionData = TRUE; - cc_deviceinfo_ref_t handle = 0; - boolean previouslyInConference = FALSE; - - if ( data == NULL ) { - cc_call_state_t call_state = sessUpd->update.ccSessionUpd.data.state_data.state; - - if ( sessUpd->eventID == CALL_INFORMATION || - sessUpd->eventID == CALL_STATE || - sessUpd->eventID == CALL_NEWCALL ) { - - CCAPP_DEBUG(DEB_F_PREFIX"CALL_SESSION_CREATED for session id 0x%x event is 0x%x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->sessionID, - sessUpd->eventID); - - if (sessUpd->eventID == CALL_INFORMATION ) { - call_state = RINGIN; - - } else { - if ( sessUpd->update.ccSessionUpd.data.state_data.state == ONHOOK ) { - CCAPP_DEBUG(DEB_F_PREFIX"NOT CREATING Session Ignoring event %d sessid %x as state is ONHOOK", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID, sessUpd->sessionID ); - //Even session data is not created, we need to send ONHOOK to application to terminate call. - createdSessionData = FALSE; - } - call_state = sessUpd->update.ccSessionUpd.data.state_data.state; - } - //Create a new call. - if (createdSessionData == TRUE) { - cc_call_handle_t callHandle = CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID); - // - NOTIFY_CALL_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][call.ref=%d]", - "CallBegin", GET_LINE_ID(callHandle), GET_CALL_ID(callHandle)); - //> - data = cpr_malloc(sizeof(session_data_t)); - if ( data == NULL ) { - APP_ERR_MSG("ccappUpdateSessionData Error: cpr_malloc failed for session data"); - return; - } - //Populate the session hash data the first time. - memset(data, 0, sizeof(session_data_t)); - data->sess_id = sessUpd->sessionID; - data->state = call_state; - data->fsm_state = - sessUpd->update.ccSessionUpd.data.state_data.fsm_state; - data->line = sessUpd->update.ccSessionUpd.data.state_data.line_id; - if (sessUpd->eventID == CALL_NEWCALL ) { - data->attr = sessUpd->update.ccSessionUpd.data.state_data.attr; - data->inst = sessUpd->update.ccSessionUpd.data.state_data.inst; - } - data->cause = sessUpd->update.ccSessionUpd.data.state_data.cause; - data->clg_name = strlib_empty(); - data->clg_number = strlib_empty(); - data->alt_number = strlib_empty(); - data->cld_name = strlib_empty(); - data->cld_number = strlib_empty(); - data->orig_called_name = strlib_empty(); - data->orig_called_number = strlib_empty(); - data->last_redir_name = strlib_empty(); - data->last_redir_number = strlib_empty(); - data->plcd_name = strlib_empty(); - data->plcd_number = strlib_empty(); - data->status = strlib_empty(); - data->gci[0] = 0; - data->vid_dir = SDP_DIRECTION_INACTIVE; - data->callref = 0; - calllogger_init_call_log(&data->call_log); - - /* - * If phone was idle, we not going to active state - * send notification to resetmanager that we - * are no longer resetReady. - */ - if ((CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) && (sendResetUpdates)) { - resetNotReady(); - } - /* Increment the refcount before putting it in the hashtable */ - CCAPI_Call_retainCallInfo(data); - (void) addhash(data->sess_id, data); - } - - //The update accordingly - switch (sessUpd->eventID) { - case CALL_INFORMATION: - data->clg_name = ccsnap_EscapeStrToLocaleStr(data->clg_name, sessUpd->update.ccSessionUpd.data.call_info.clgName, LEN_UNKNOWN); - data->cld_name = ccsnap_EscapeStrToLocaleStr(data->cld_name, sessUpd->update.ccSessionUpd.data.call_info.cldName, LEN_UNKNOWN); - data->orig_called_name = ccsnap_EscapeStrToLocaleStr(data->orig_called_name, sessUpd->update.ccSessionUpd.data.call_info.origCalledName, LEN_UNKNOWN); - data->last_redir_name = ccsnap_EscapeStrToLocaleStr(data->last_redir_name, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingName, LEN_UNKNOWN); - - data->clg_number = strlib_update(data->clg_number, sessUpd->update.ccSessionUpd.data.call_info.clgNumber); - data->cld_number = strlib_update(data->cld_number, sessUpd->update.ccSessionUpd.data.call_info.cldNumber); - data->alt_number = strlib_update(data->alt_number, sessUpd->update.ccSessionUpd.data.call_info.altClgNumber); - data->orig_called_number = strlib_update(data->orig_called_number, sessUpd->update.ccSessionUpd.data.call_info.origCalledNumber); - data->last_redir_number = strlib_update(data->last_redir_number, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingNumber); - data->type = sessUpd->update.ccSessionUpd.data.call_info.call_type; - data->inst = sessUpd->update.ccSessionUpd.data.call_info.instance_id; - data->security = sessUpd->update.ccSessionUpd.data.call_info.security; - data->policy = sessUpd->update.ccSessionUpd.data.call_info.policy; - break; - case CALL_STATE: - if (createdSessionData == FALSE) { - return; - } - data->state = - sessUpd->update.ccSessionUpd.data.state_data.state; - data->line = - sessUpd->update.ccSessionUpd.data.state_data.line_id; - data->fsm_state = - sessUpd->update.ccSessionUpd.data.state_data.fsm_state; - break; - default: - break; - } - } else if (sessUpd->eventID == CALL_DELETE_LAST_DIGIT) { - CCAPP_DEBUG(DEB_F_PREFIX"CALL_DELETE_LAST_DIGIT: event %d sessid %x.", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID, sessUpd->sessionID ); - return; - } else { - CCAPP_DEBUG(DEB_F_PREFIX"NOT CREATING Session Ignoring event %d sessid %x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID, sessUpd->sessionID ); - return; - } - - // send event to csf2g API - if (data != NULL) { - capset_get_allowed_features(gCCApp.mode, data->state, data->allowed_features); - ccsnap_gen_callEvent(CCAPI_CALL_EV_CREATED, CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id)); - } - return; - - } - - CCAPP_DEBUG(DEB_F_PREFIX"Found data for sessid %x event %d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->sessionID, sessUpd->eventID); - switch(sessUpd->eventID) { - case CALL_SESSION_CLOSED: - // find and deep free then delete - sess_data_p = (session_data_t *)findhash(sessUpd->sessionID); - if ( sess_data_p != NULL ){ - if ( 0 > delhash(sessUpd->sessionID) ) { - APP_ERR_MSG (DEB_F_PREFIX"failed to delete hash sessid=0x%08x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),sessUpd->sessionID); - } - CCAPI_Call_releaseCallInfo(sess_data_p); - } - if ( (gCCApp.inPreservation || (gCCApp.cucm_mode == FALLBACK)) && isNoCallExist()) { - /* The phone is now Idle. Clear the inPreservation Flag */ - gCCApp.inPreservation = FALSE; - proceedWithFOFB(); - } - if ((CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) && (sendResetUpdates)) { - resetReady(); - } - if (pending_action_type != NO_ACTION) { - perform_deferred_action(); - } - break; - - case CALL_STATE: - DEF_DEBUG(DEB_F_PREFIX"Call_STATE:. state=%d, attr=%d, cause=%d, instance=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - sessUpd->update.ccSessionUpd.data.state_data.state, - data->attr, - sessUpd->update.ccSessionUpd.data.state_data.cause, - data->inst); - if ( sessUpd->update.ccSessionUpd.data.state_data.state == HOLD && - (data->state == REMHOLD || data->state == REMINUSE)){ - data->state = REMHOLD; - } else { - data->state = sessUpd->update.ccSessionUpd.data.state_data.state; - } - data->line = sessUpd->update.ccSessionUpd.data.state_data.line_id; - data->fsm_state = - sessUpd->update.ccSessionUpd.data.state_data.fsm_state; - sessUpd->update.ccSessionUpd.data.state_data.attr = data->attr; - sessUpd->update.ccSessionUpd.data.state_data.inst = data->inst; - - data->cause = sessUpd->update.ccSessionUpd.data.state_data.cause; - - //Update call state - if ( data != NULL ){ - capset_get_allowed_features(gCCApp.mode, data->state, data->allowed_features); - } - calllogger_update(data); - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATE, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - - // - if (data->state == ONHOOK) { - NOTIFY_CALL_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][call.ref=%d]", - "CallEND", data->line, data->id); - } - //> - - if (data->state == ONHOOK) { - // find and deep free then delete - sess_data_p = (session_data_t *)findhash(sessUpd->sessionID); - if ( sess_data_p != NULL ){ - if ( 0 > delhash(sessUpd->sessionID) ) { - APP_ERR_MSG (DEB_F_PREFIX"failed to delete hash sessid=0x%08x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),sessUpd->sessionID); - } - CCAPI_Call_releaseCallInfo(sess_data_p); - data = NULL; - } - if ((gCCApp.inPreservation || (gCCApp.cucm_mode == FALLBACK)) && isNoCallExist()) { - /* The phone is now Idle. Clear the inPreservation Flag */ - gCCApp.inPreservation = FALSE; - proceedWithFOFB(); - } - if ((CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) && (sendResetUpdates)) { - resetReady(); - } - if (pending_action_type != NO_ACTION) { - perform_deferred_action(); - } - } - break; - - case CALL_CALLREF: - data->callref = sessUpd->update.ccSessionUpd.data.callref; - break; - case CALL_GCID: - if ( ! strncasecmp(data->gci, sessUpd->update.ccSessionUpd.data.gcid, CC_MAX_GCID)) { - // No change in gci we can ignore the update - return; - } - sstrncpy(data->gci, sessUpd->update.ccSessionUpd.data.gcid, CC_MAX_GCID); - ccsnap_gen_callEvent(CCAPI_CALL_EV_GCID, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_NEWCALL: - data->state = sessUpd->update.ccSessionUpd.data.state_data.state; - data->line = sessUpd->update.ccSessionUpd.data.state_data.line_id; - data->fsm_state = - sessUpd->update.ccSessionUpd.data.state_data.fsm_state; - data->attr = sessUpd->update.ccSessionUpd.data.state_data.attr; - data->inst = sessUpd->update.ccSessionUpd.data.state_data.inst; - return; - break; - - case CALL_ATTR: - data->attr = sessUpd->update.ccSessionUpd.data.state_data.attr; - calllogger_update(data); - ccsnap_gen_callEvent(CCAPI_CALL_EV_ATTR, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case CALL_INFORMATION: - // check conference state, if it changes, we'll send a conference event notification - previouslyInConference = CCAPI_CallInfo_getIsConference(data); - - data->clg_name = ccsnap_EscapeStrToLocaleStr(data->clg_name, sessUpd->update.ccSessionUpd.data.call_info.clgName, LEN_UNKNOWN); - data->cld_name = ccsnap_EscapeStrToLocaleStr(data->cld_name, sessUpd->update.ccSessionUpd.data.call_info.cldName, LEN_UNKNOWN); - data->orig_called_name = ccsnap_EscapeStrToLocaleStr(data->orig_called_name, sessUpd->update.ccSessionUpd.data.call_info.origCalledName, LEN_UNKNOWN); - data->last_redir_name = ccsnap_EscapeStrToLocaleStr(data->last_redir_name, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingName, LEN_UNKNOWN); - data->clg_number = strlib_update(data->clg_number, sessUpd->update.ccSessionUpd.data.call_info.clgNumber); - data->cld_number = strlib_update(data->cld_number, sessUpd->update.ccSessionUpd.data.call_info.cldNumber); - data->alt_number = strlib_update(data->alt_number, sessUpd->update.ccSessionUpd.data.call_info.altClgNumber); - data->orig_called_number = strlib_update(data->orig_called_number, sessUpd->update.ccSessionUpd.data.call_info.origCalledNumber); - data->last_redir_number = strlib_update(data->last_redir_number, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingNumber); - data->type = sessUpd->update.ccSessionUpd.data.call_info.call_type; - data->inst = sessUpd->update.ccSessionUpd.data.call_info.instance_id; - data->security = sessUpd->update.ccSessionUpd.data.call_info.security; - data->policy = sessUpd->update.ccSessionUpd.data.call_info.policy; - if ((data->cld_number[0]) && ccappCldNumIsCfwdallString(data->cld_number)) { - DEF_DEBUG(DEB_F_PREFIX"Not updating the UI. Called Number = %s", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cld_number); - return; - } - /* - * For 3rd Gen and 4th Gen phones... Use sessUpd->update structure to pass call information - * For 5th Gen phones, the information will be localized by a 5th Gen Application, and the - * dictionaries might not be equivalent. - */ - calllogger_update(data); - - ccsnap_gen_callEvent(CCAPI_CALL_EV_CALLINFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - - // if we're entering a conference, then indicate conference participant info (in case the info came earlier, app - // will receive the notification now. If info comes later, then app will receive an additional subsequent info notice - // at that time. - if ((!previouslyInConference) && (CCAPI_CallInfo_getIsConference(data))) { - ccsnap_gen_callEvent(CCAPI_CALL_EV_CONF_PARTICIPANT_INFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - } - - break; - - case CALL_PLACED_INFO: - data->plcd_number = strlib_update(data->plcd_number, sessUpd->update.ccSessionUpd.data.plcd_info.cldNum); - data->plcd_name = ccsnap_EscapeStrToLocaleStr(data->plcd_name, sessUpd->update.ccSessionUpd.data.plcd_info.cldName, LEN_UNKNOWN); - calllogger_setPlacedCallInfo(data); - - break; - - case CALL_SELECTED: - data->isSelected = sessUpd->update.ccSessionUpd.data.action; - ccsnap_gen_callEvent(CCAPI_CALL_EV_SELECT, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case CALL_SELECT_FEATURE_SET: - // Not quite perfect but should do for now - if ( strcmp("CONNECTEDNOFEAT", sessUpd->update.ccSessionUpd.data.feat_set.featSet ) ) { - data->allowed_features[CCAPI_CALL_CAP_HOLD] = FALSE; - data->allowed_features[CCAPI_CALL_CAP_CONFERENCE] = FALSE; - data->allowed_features[CCAPI_CALL_CAP_TRANSFER] = FALSE; - } else if ( sessUpd->update.ccSessionUpd.data.feat_set.featMask[0] == skConfrn ) { - data->allowed_features[CCAPI_CALL_CAP_CONFERENCE] = FALSE; - } - ccsnap_gen_callEvent(CCAPI_CALL_EV_CAPABILITY, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case CALL_STATUS: - /* - * For 5th Gen Phones, data->status is localized. - * 3rd Gen and 4th Gen phones should use sessUpd->update struct to pass the status to the application. - */ - data->status = ccsnap_EscapeStrToLocaleStr(data->status, sessUpd->update.ccSessionUpd.data.status.status, LEN_UNKNOWN); - if (data->status != NULL) { - if(strncmp(data->status, UNKNOWN_PHRASE_STR, UNKNOWN_PHRASE_STR_SIZE) == 0){ - strlib_free(data->status); - data->status = strlib_empty(); - } - if(strcmp(data->status, strlib_empty()) != 0){ - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATUS, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - } - } - // - NOTIFY_CALL_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][call.ref=%d][status=%s]", - "callStatusChange", data->line, data->id, - NOTIFY_CALL_STATUS); - //> - - break; - if(strcmp(data->status, strlib_empty()) != 0){ - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATUS, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - } - - case CALL_PRESERVATION_ACTIVE: - data->state = PRESERVATION; - ccsnap_gen_callEvent(CCAPI_CALL_EV_PRESERVATION, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case RINGER_STATE: - data->ringer_start = sessUpd->update.ccSessionUpd.data.ringer.start; - data->ringer_mode = sessUpd->update.ccSessionUpd.data.ringer.mode; - data->ringer_once = sessUpd->update.ccSessionUpd.data.ringer.once; - ccsnap_gen_callEvent(CCAPI_CALL_EV_RINGER_STATE, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case VIDEO_AVAIL: - if ( data->vid_dir == sessUpd->update.ccSessionUpd.data.action ) { - // no change don't update - return; - } - data->vid_dir = sessUpd->update.ccSessionUpd.data.action; - ccsnap_gen_callEvent(CCAPI_CALL_EV_VIDEO_AVAIL, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case VIDEO_OFFERED: - data->vid_offer = sessUpd->update.ccSessionUpd.data.action; - ccsnap_gen_callEvent(CCAPI_CALL_EV_VIDEO_OFFERED, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_ENABLE_BKSP: - data->allowed_features[CCAPI_CALL_CAP_BACKSPACE] = TRUE; - ccsnap_gen_callEvent(CCAPI_CALL_EV_CAPABILITY, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_SECURITY: - data->security = sessUpd->update.ccSessionUpd.data.security; - ccsnap_gen_callEvent(CCAPI_CALL_EV_SECURITY, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_LOGDISP: - data->log_disp = sessUpd->update.ccSessionUpd.data.action; - calllogger_updateLogDisp(data); - // No need to generate this event anymore - // ccsnap_gen_callEvent(CCAPI_CALL_EV_LOG_DISP, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_DELETE_LAST_DIGIT: - ccsnap_gen_callEvent(CCAPI_CALL_EV_LAST_DIGIT_DELETED, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_FEATURE_CANCEL: - ccsnap_gen_callEvent(CCAPI_CALL_EV_XFR_OR_CNF_CANCELLED, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_RECV_INFO_LIST: - //Should not come here. It's dealed in CCAPP_RCVD_INFO. - break; - case MEDIA_INTERFACE_UPDATE_BEGIN: - ccsnap_gen_callEvent(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_BEGIN, - CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case MEDIA_INTERFACE_UPDATE_SUCCESSFUL: - ccsnap_gen_callEvent(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_SUCCESSFUL, - CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case MEDIA_INTERFACE_UPDATE_FAIL: - ccsnap_gen_callEvent(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_FAIL, - CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - default: - DEF_DEBUG(DEB_F_PREFIX"Unknown event, id = %d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID); - break; - } - return; -} - -static void freeSessionData(session_update_t *sessUpd) -{ - switch(sessUpd->eventID) { - case CALL_INFORMATION: - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.clgName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.clgNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.cldName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.cldNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.altClgNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.origCalledName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.origCalledNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingNumber); - break; - case CALL_PLACED_INFO: - strlib_free(sessUpd->update.ccSessionUpd.data.plcd_info.cldName); - strlib_free(sessUpd->update.ccSessionUpd.data.plcd_info.cldNum); - break; - case CALL_SELECT_FEATURE_SET: - strlib_free(sessUpd->update.ccSessionUpd.data.feat_set.featSet); - break; - case CALL_STATUS: - strlib_free(sessUpd->update.ccSessionUpd.data.status.status); - break; - case CALL_RECV_INFO_LIST: - strlib_free(sessUpd->update.ccSessionUpd.data.recv_info_list); - break; - } -} - -static void freeSessionMgmtData(session_mgmt_t *sessMgmt) -{ - switch(sessMgmt->func_id) { - case SESSION_MGMT_APPLY_CONFIG: - strlib_free(sessMgmt->data.config.log_server); - strlib_free(sessMgmt->data.config.load_server); - strlib_free(sessMgmt->data.config.load_id); - strlib_free(sessMgmt->data.config.inactive_load_id); - strlib_free(sessMgmt->data.config.cucm_result); - strlib_free(sessMgmt->data.config.fcp_version_stamp); - strlib_free(sessMgmt->data.config.dialplan_version_stamp); - strlib_free(sessMgmt->data.config.config_version_stamp); - break; - case SESSION_MGMT_EXECUTE_URI: - strlib_free(sessMgmt->data.uri.uri); - break; - default: - break; - } -} - -static void freeRcvdInfo(session_rcvd_info_t *rcvdInfo) -{ - switch(rcvdInfo->packageID) { - case INFO_PKG_ID_GENERIC_RAW: - strlib_free(rcvdInfo->info.generic_raw.info_package); - strlib_free(rcvdInfo->info.generic_raw.content_type); - strlib_free(rcvdInfo->info.generic_raw.message_body); - break; - } -} - -void dump_msg(char * name, unsigned int *msg, int len, unsigned int cmd) { -int i,j; - CCAPP_DEBUG(DEB_F_PREFIX"%s %p %d cmd=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "dump_msg"), name, msg, len, cmd); - for ( j=0;j<10;j++) { - for(i=0;i<16;i++) { - CCAPP_DEBUG(DEB_F_PREFIX"%08X ", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "dump_msg"), msg[i+j]); - if ( (i+j+1)*4 >= len ) return; - } - CCAPP_DEBUG(DEB_F_PREFIX, DEB_F_PREFIX_ARGS(SIP_CC_PROV, "dump_msg")); - } -} - - -/** - * A ccapp task listener - */ -void ccp_handler(void* msg, int type) { - static const char fname[] = "ccp_handler"; - sessionProvider_cmd_t *cmdMsg; - session_feature_t *featMsg; - session_update_t *sessUpd; - feature_update_t *featUpd; - session_mgmt_t *sessMgmt; - session_send_info_t *sendInfo; - session_rcvd_info_t *rcvdInfo; - session_id_t sess_id; - session_data_t *data; - int length; - cc_reg_state_t state; - - CCAPP_DEBUG(DEB_F_PREFIX"Received Cmd %s", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - CCAPP_TASK_CMD_PRINT(type) ); - - - switch (type) { - case CCAPP_SERVICE_CMD: - cmdMsg = (sessionProvider_cmd_t *) msg; - CCApp_processCmds (cmdMsg->cmd, cmdMsg->cmdData.ccData.reason, - cmdMsg->cmdData.ccData.reason_info); - break; - - case CCAPP_INVOKEPROVIDER_FEATURE: - featMsg = (session_feature_t *) msg; - processProviderEvent(GET_LINEID(featMsg->session_id), featMsg->featureID, - featMsg->featData.ccData.state); - if (featMsg->featData.ccData.info != NULL) { - strlib_free(featMsg->featData.ccData.info); - } - if (featMsg->featData.ccData.info1 != NULL) { - strlib_free(featMsg->featData.ccData.info1); - } - break; - case CCAPP_INVOKE_FEATURE: - featMsg = (session_feature_t *) msg; - CCAPP_DEBUG(DEB_F_PREFIX"CCAPP_INVOKE_FEATURE:sid=%d, fid=%d, line=%d, cid=%d, info=%s info1=%s", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - featMsg->session_id, - featMsg->featureID, - GET_LINEID(featMsg->session_id), - GET_CALLID(featMsg->session_id), - ((featMsg->featureID == CC_FEATURE_KEYPRESS) ? "..." : featMsg->featData.ccData.info), - ((featMsg->featureID == CC_FEATURE_KEYPRESS) ? "..." : featMsg->featData.ccData.info1)); - processSessionEvent(GET_LINEID(featMsg->session_id), GET_CALLID(featMsg->session_id), - featMsg->featureID, featMsg->featData.ccData.state, - featMsg->featData.ccData); - if (featMsg->featData.ccData.info != NULL) { - strlib_free(featMsg->featData.ccData.info); - } - if (featMsg->featData.ccData.info1 != NULL) { - strlib_free(featMsg->featData.ccData.info1); - } - break; - - case CCAPP_CLOSE_SESSION: - sess_id = *(session_id_t*)msg; - cc_feature(CC_SRC_UI, GET_CALLID(sess_id), - GET_LINEID(sess_id), CC_FEATURE_END_CALL, NULL); - break; - - case CCAPP_SESSION_UPDATE: - sessUpd = (session_update_t *) msg; - // Udpate the local cache - CCAPP_DEBUG(DEB_F_PREFIX"CCAPP_SESSION_UPDATE:type:%d.", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), GET_SESS_TYPE(sessUpd->sessionID)); - // XXX Why do this when sessType is in session_update_t already? - if (GET_SESS_TYPE(sessUpd->sessionID) == SESSIONTYPE_CALLCONTROL) { - ccappUpdateSessionData(sessUpd); - } - else { - CCAPP_DEBUG(DEB_F_PREFIX"Unknown type:%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->sessType); - } - freeSessionData(sessUpd); - break; - - case CCAPP_FEATURE_UPDATE: - state = ccapp_get_state(); - featUpd = (feature_update_t *) msg; - // Update Registration state - if (featUpd->featureID == DEVICE_REG_STATE) - CCAPP_DEBUG(DEB_F_PREFIX"DEVICE_REG_STATE", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if(featUpd->update.ccFeatUpd.data.line_info.info == CC_REGISTERED) - CCAPP_DEBUG(DEB_F_PREFIX"CC_REGISTERED", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if(state == (int) CC_INSERVICE) - CCAPP_DEBUG(DEB_F_PREFIX"CC_INSERVICE", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( featUpd->featureID == DEVICE_REG_STATE && - featUpd->update.ccFeatUpd.data.line_info.info == CC_REGISTERED && - state != (int) CC_INSERVICE ) - { - cc_uint32_t major_ver=0, minor_ver=0,addtnl_ver=0; - char name[CC_MAX_LEN_REQ_SUPP_PARAM_CISCO_SISTAG]={0}; - platGetSISProtocolVer( &major_ver, &minor_ver, &addtnl_ver, name); - CCAPP_DEBUG(DEB_F_PREFIX"The SIS version is: %s, sis ver: %d.%d.%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), name, major_ver, minor_ver, addtnl_ver); - if(!strncmp(name, REQ_SUPP_PARAM_CISCO_CME_SISTAG, strlen(REQ_SUPP_PARAM_CISCO_CME_SISTAG))){ - CCAPP_DEBUG(DEB_F_PREFIX"This is CUCME mode.", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - } else if(!strncmp(name, REQ_SUPP_PARAM_CISCO_SISTAG, strlen(REQ_SUPP_PARAM_CISCO_SISTAG))){ - CCAPP_DEBUG(DEB_F_PREFIX"This is CUCM mode.",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"This is unknown mode.",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - } - ccapp_set_state(CC_INSERVICE); - gCCApp.cause = CC_CAUSE_NONE; - - // Notify INS/OOS state to Session Manager if required - ccapp_hlapi_update_device_reg_state(); - ccpro_handleINS(); - - if (gCCApp.cucm_mode == FAILOVER) { - cc_fail_fallback_sip(CC_SRC_UI, RSP_COMPLETE, CC_REG_FAILOVER_RSP, FALSE); - } - if (gCCApp.cucm_mode == FALLBACK) { - cc_fail_fallback_sip(CC_SRC_UI, RSP_COMPLETE, CC_REG_FALLBACK_RSP, FALSE); - } - gCCApp.cucm_mode = NONE_AVAIL; - } - - ccappFeatureUpdated(featUpd); - break; - - case CCAPP_SESSION_MGMT: - sessMgmt = (session_mgmt_t *) msg; - ccappSyncSessionMgmt(sessMgmt); - break; - - case CCAPP_SEND_INFO: - sendInfo = (session_send_info_t *) msg; - data = (session_data_t *)findhash(sendInfo->sessionID); - - if ( data != NULL && data->state == CONNECTED ) { - cc_int_info(CC_SRC_UI, CC_SRC_SIP, - GET_CALLID(sendInfo->sessionID), - GET_LINEID(sendInfo->sessionID), - sendInfo->generic_raw.info_package, - sendInfo->generic_raw.content_type, - sendInfo->generic_raw.message_body); - } - strlib_free(sendInfo->generic_raw.message_body); - strlib_free(sendInfo->generic_raw.content_type); - strlib_free(sendInfo->generic_raw.info_package); - break; - - case CCAPP_RCVD_INFO: - sendInfo = (session_send_info_t *) msg; - data = (session_data_t *)findhash(sendInfo->sessionID); - rcvdInfo = (session_rcvd_info_t *) msg; - - length = strlen((const char*)rcvdInfo->info.generic_raw.message_body); - if (data != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"rcvdInfo: addr=%p length=%d, xml=%s", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"), - &data->call_conference, length, rcvdInfo->info.generic_raw.message_body); - - data->info_package = rcvdInfo->info.generic_raw.info_package; - data->info_type = rcvdInfo->info.generic_raw.content_type; - data->info_body = rcvdInfo->info.generic_raw.message_body; - - ccsnap_gen_callEvent(CCAPI_CALL_EV_RECEIVED_INFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(rcvdInfo->sessionID)); - - // most of the time isConference will be true at this point, we can notify the app of - // the updated participant info. However, if we're transitioning from non conference into - // conference, then we'll delay this notification until we're fully in conference state - if (CCAPI_CallInfo_getIsConference(data)) - { // in conference - send the info - ccsnap_gen_callEvent(CCAPI_CALL_EV_CONF_PARTICIPANT_INFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(rcvdInfo->sessionID)); - } - - // one shot notify cleanup after event generation - data->info_package = strlib_empty(); - data->info_type = strlib_empty(); - data->info_body = strlib_empty(); - } - freeRcvdInfo(rcvdInfo); - break; - - case CCAPP_UPDATELINES: - notify_register_update(*(int *)msg); - break; - - case CCAPP_MODE_NOTIFY: - case CCAPP_FAILOVER_IND: - case CCAPP_SHUTDOWN_ACK: - case CCAPP_FALLBACK_IND: - case CCAPP_REG_ALL_FAIL: - featUpd = (feature_update_t *) msg; - ccappHandleRegStateUpdates(featUpd); - break; - - case CCAPP_THREAD_UNLOAD: - ccapp_shutdown(); - break; - default: - APP_ERR_MSG("CCApp_Task: Error: Unknown message %d msg =%p", - type, msg); - break; - } -} - -/* - * Function: ccapp_shutdown - * Description: shutdown ccapp - * Parameters: none - * Returns: none - */ -void ccapp_shutdown() -{ - static const char fname[] = "ccapp_shutdown"; - TNP_DEBUG(DEB_F_PREFIX"Unloading ccapp", - DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - platform_initialized = FALSE; - CCAppShutdown(); -} - -/** - * CCAPP wrapper to update device features. - * @param featUpd - feature_update_t - * @return void - */ -static -void ccappFeatureUpdated (feature_update_t *featUpd) { - cc_line_info_t *line_info; - - switch(featUpd->featureID) { - case DEVICE_FEATURE_CFWD: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.cfwd.line); - if ( line_info != NULL ) { - line_info->isCFWD = featUpd->update.ccFeatUpd.data.cfwd.isFwd; - line_info->isLocalCFWD = featUpd->update.ccFeatUpd.data.cfwd.isLocal; - line_info->cfwd_dest = strlib_update(line_info->cfwd_dest, featUpd->update.ccFeatUpd.data.cfwd.cfa_num); - ccsnap_gen_lineEvent(CCAPI_LINE_EV_CFWDALL, line_info->button); - } - CC_Config_setStringValue(CFGID_LINE_CFWDALL+featUpd->update.ccFeatUpd.data.cfwd.line-1, featUpd->update.ccFeatUpd.data.cfwd.cfa_num); - - break; - case DEVICE_FEATURE_MWI: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.mwi_status.line); - if ( line_info != NULL ) { - line_info->mwi.status = featUpd->update.ccFeatUpd.data.mwi_status.status; - line_info->mwi.type = featUpd->update.ccFeatUpd.data.mwi_status.type; - line_info->mwi.new_count = featUpd->update.ccFeatUpd.data.mwi_status.newCount; - line_info->mwi.old_count = featUpd->update.ccFeatUpd.data.mwi_status.oldCount; - line_info->mwi.pri_new_count = featUpd->update.ccFeatUpd.data.mwi_status.hpNewCount; - line_info->mwi.pri_old_count = featUpd->update.ccFeatUpd.data.mwi_status.hpOldCount; - ccsnap_gen_lineEvent(CCAPI_LINE_EV_MWI, line_info->button); - } - //Added for automation test - NOTIFY_LINE_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][state=%s]", - "MWIChanged", featUpd->update.ccFeatUpd.data.mwi_status.line, - (featUpd->update.ccFeatUpd.data.mwi_status.status)?"ON":"OFF"); - - break; - case DEVICE_FEATURE_MWILAMP: - g_deviceInfo.mwi_lamp = - featUpd->update.ccFeatUpd.data.mwi_status.status; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_MWI_LAMP, CC_DEVICE_ID); - break; - case DEVICE_FEATURE_BLF: - sub_hndlr_NotifyBLFStatus(featUpd->update.ccFeatUpd.data.blf_data.request_id, - featUpd->update.ccFeatUpd.data.blf_data.state, - featUpd->update.ccFeatUpd.data.blf_data.app_id); - break; - case DEVICE_FEATURE_MNC_REACHED: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.line_info.line); - if ( line_info != NULL ) { - ccsnap_handle_mnc_reached(line_info, - featUpd->update.ccFeatUpd.data.line_info.info, gCCApp.mode); - ccsnap_gen_lineEvent(CCAPI_LINE_EV_CAPSET_CHANGED, line_info->button); - } - break; - case DEVICE_SERVICE_CONTROL_REQ: - reset_type = (cc_srv_ctrl_req_t) featUpd->update.ccFeatUpd.data.reset_type; - ccpro_handleserviceControlNotify(); - break; - case DEVICE_NOTIFICATION: - g_deviceInfo.not_prompt = ccsnap_EscapeStrToLocaleStr(g_deviceInfo.not_prompt, featUpd->update.ccFeatUpd.data.notification.prompt, LEN_UNKNOWN); - g_deviceInfo.not_prompt_prio = featUpd->update.ccFeatUpd.data.notification.priority; - g_deviceInfo.not_prompt_prog = featUpd->update.ccFeatUpd.data.notification.notifyProgress; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_NOTIFYPROMPT, CC_DEVICE_ID); - break; - case DEVICE_LABEL_N_SPEED: - // todo - break; - case DEVICE_REG_STATE: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.line_info.line); - if ( line_info != NULL ) { - line_info->reg_state = featUpd->update.ccFeatUpd.data.line_info.info; - ccsnap_gen_lineEvent(CCAPI_LINE_EV_REG_STATE, line_info->button); - } - break; - case DEVICE_CCM_CONN_STATUS: - ccsnap_update_ccm_status(featUpd->update.ccFeatUpd.data.ccm_conn.addr, - featUpd->update.ccFeatUpd.data.ccm_conn.status); - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_SERVER_STATUS, CC_DEVICE_ID); - break; - default: - DEF_DEBUG(DEB_F_PREFIX"Unknown event: id= %d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccappFeatureUpdated"), featUpd->featureID); - break; - - } - if ( featUpd->featureID == DEVICE_NOTIFICATION) { - strlib_free(featUpd->update.ccFeatUpd.data.notification.prompt); - } - - if ( featUpd->featureID == DEVICE_CCM_CONN_STATUS) { - strlib_free(featUpd->update.ccFeatUpd.data.ccm_conn.addr); - } - - if ( featUpd->featureID == DEVICE_FEATURE_CFWD) { - strlib_free(featUpd->update.ccFeatUpd.data.cfwd.cfa_num); - } - - if (featUpd->featureID == DEVICE_SYNC_CONFIG_VERSION) { - strlib_free(featUpd->update.ccFeatUpd.data.cfg_ver_data.cfg_ver); - strlib_free(featUpd->update.ccFeatUpd.data.cfg_ver_data.dp_ver); - strlib_free(featUpd->update.ccFeatUpd.data.cfg_ver_data.softkey_ver); - } - - if (featUpd->featureID == DEVICE_LABEL_N_SPEED) { - strlib_free(featUpd->update.ccFeatUpd.data.cfg_lbl_n_spd.speed); - strlib_free(featUpd->update.ccFeatUpd.data.cfg_lbl_n_spd.label); - } - -} - -/** - * - * CCApp Provider wrapper for synchronous calls. - * - * @param sessMgmt - session management message - * - * @return void - * - * @pre None - */ -void ccappSyncSessionMgmt(session_mgmt_t *sessMgmt) -{ - cc_line_info_t *line_info; - CCAPP_DEBUG(DEB_F_PREFIX"ccappSyncSessionMgmt: func_id=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccappSyncSessionMgmt"), - sessMgmt->func_id); - - //sessionMgmt(sessMgmt); - switch (sessMgmt->func_id) { - case SESSION_MGMT_SET_TIME: - g_deviceInfo.reg_time = sessMgmt->data.time.gmt_time; - CCAPP_DEBUG(DEB_F_PREFIX"Setting reg_time to == %lld", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, - "ccappSyncSessionMgmt"), g_deviceInfo.reg_time); - platSetCucmRegTime(); - break; - case SESSION_MGMT_GET_PHRASE_TEXT: - sessMgmt->data.phrase_text.ret_val = - platGetPhraseText(sessMgmt->data.phrase_text.ndx, - sessMgmt->data.phrase_text.outstr, - sessMgmt->data.phrase_text.len); - break; - case SESSION_MGMT_GET_UNREG_REASON: - sessMgmt->data.unreg_reason.unreg_reason = platGetUnregReason(); - break; - case SESSION_MGMT_UPDATE_KPMLCONFIG: - platSetKPMLConfig(sessMgmt->data.kpmlconfig.kpml_val); - break; - case SESSION_MGMT_GET_AUDIO_DEVICE_STATUS: - //Noop - break; - case SESSION_MGMT_CHECK_SPEAKER_HEADSET_MODE: - //Noop - break; - case SESSION_MGMT_LINE_HAS_MWI_ACTIVE: - line_info = ccsnap_getLineInfoFromBtn(sessMgmt->data.line_mwi_active.line); - if (line_info != NULL) { - sessMgmt->data.line_mwi_active.ret_val = line_info->mwi.status; - } - break; - case SESSION_MGMT_APPLY_CONFIG: - // save the proposed versions of fcp and dialplan to apply. Will check against - // current versions and redownload if necessary - - if (pending_action_type == NO_ACTION) { - configApplyConfigNotify(sessMgmt->data.config.config_version_stamp, - sessMgmt->data.config.dialplan_version_stamp, - sessMgmt->data.config.fcp_version_stamp, - sessMgmt->data.config.cucm_result, - sessMgmt->data.config.load_id, - sessMgmt->data.config.inactive_load_id, - sessMgmt->data.config.load_server, - sessMgmt->data.config.log_server, - sessMgmt->data.config.ppid); - } - break; - default: - break; - } - freeSessionMgmtData(sessMgmt); - -} - -/** - * ccCreateSession - * - * Called to create a CC session - * - * @param param - ccSession_create_param_t - * Contains the type of session and specific data - * - * @return ccSession_id_t - id of the session created - */ -session_id_t createSessionId(line_t line, callid_t call) -{ - return ( SESSIONTYPE_CALLCONTROL << SID_TYPE_SHIFT ) + - (line << SID_LINE_SHIFT ) + call; -} - -/** - * getLineIdAndCallId - * - * get Line and call_id - * - * @param *line_id - * @param *call_id - * - */ -void getLineIdAndCallId (line_t *line_id, callid_t *call_id) -{ - // assign proper line_id and call_id if not already there - if ((*line_id) == 0 || (*line_id) == CC_ALL_LINES) { - /* - * If the filter is the All Calls Complex Filter and the primary line - * is at its configured call capacity, the next available line should - * be used. In this scenario, sessionUI/Mgr send the line_id as zero. - */ - (*line_id) = lsm_get_available_line(FALSE); - } - - if ((*call_id) == 0) { - (*call_id) = cc_get_new_call_id(); - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.c b/media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.c deleted file mode 100644 index 9bfa7f24814..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.c +++ /dev/null @@ -1,401 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "sll_lite.h" -#include "cc_constants.h" -#include "cc_types.h" -#include "cc_config.h" -#include "phone_debug.h" -#include "debug.h" -#include "CCProvider.h" -#include "ccapi_call_info.h" -#include "conf_roster.h" -#include "ccapi.h" -#include "ccapp_task.h" - -cc_conf_participant_status_t -convertStringToParticipantStatus(const char *data) -{ - if (strcmp(data, "connected") == 0) { - return CCAPI_CONFPARTICIPANT_CONNECTED; - } else if (strcmp(data, "alerting") == 0) { - return CCAPI_CONFPARTICIPANT_ALERTING; - } else if (strcmp(data, "dialing-out") == 0) { - return CCAPI_CONFPARTICIPANT_DIALING_OUT; - } else if (strcmp(data, "on-hold") == 0) { - return CCAPI_CONFPARTICIPANT_ON_HOLD; - } else if (strcmp(data, "disconnected") == 0) { - return CCAPI_CONFPARTICIPANT_DISCONNECTED; - } else { - return CCAPI_CONFPARTICIPANT_UNKNOWN; - } -} - -cc_call_security_t -convertStringToParticipantSecurity(const char *data) -{ - - if (strcmp(data, "NotAuthenticated") == 0) { - return CC_SECURITY_NOT_AUTHENTICATED; - } else if (strcmp(data, "Authenticated") == 0) { - return CC_SECURITY_AUTHENTICATED; - } else if (strcmp(data, "Encrypted") == 0) { - return CC_SECURITY_ENCRYPTED; - } else if (strcmp(data, "Unknown") == 0) { - return CC_SECURITY_UNKNOWN; - } else { - return CC_SECURITY_NONE; - } -} - - -void conf_roster_init_call_conference (cc_call_conference_Info_t *info) -{ - CCAPP_DEBUG(DEB_F_PREFIX"in init_call_conference", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - - info->participantMax = 0; - info->participantCount = 0; - info->myParticipantId = strlib_empty(); - - sll_lite_init(&info->currentParticipantsList); -} - -void conf_roster_free_call_conference (cc_call_conference_Info_t *confInfo) -{ - cc_call_conferenceParticipant_Info_t *participant; - - CCAPP_DEBUG(DEB_F_PREFIX"in free_call_confrerence", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - - while((participant=(cc_call_conferenceParticipant_Info_t *) - sll_lite_unlink_head(&confInfo->currentParticipantsList)) != NULL) - { - strlib_free(participant->participantName); - strlib_free(participant->endpointUri); - strlib_free(participant->callid); - strlib_free(participant->participantNumber); - - participant->participantSecurity = CC_SECURITY_NONE; - participant->participantStatus = CCAPI_CONFPARTICIPANT_UNKNOWN; - participant->canRemoveOtherParticipants = FALSE; - - cpr_free(participant); - participant = NULL; - } - - strlib_free(confInfo->myParticipantId); - conf_roster_init_call_conference(confInfo); -} - -void conf_roster_copy_call_conferance (cc_call_conference_Info_t *dest, cc_call_conference_Info_t * src) -{ - cc_call_conferenceParticipant_Info_t *destParticipant; - cc_call_conferenceParticipant_Info_t *srcParticipant; - sll_lite_node_t *iterator; - sll_lite_return_e sll_ret_val; - - CCAPP_DEBUG(DEB_F_PREFIX"in copy_call_confrerence", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - - iterator = src->currentParticipantsList.head_p; - conf_roster_init_call_conference(dest); - - dest->participantMax = src->participantMax; - dest->participantCount = src->participantCount; - dest->myParticipantId = strlib_copy(src->myParticipantId); - - while (iterator) { - srcParticipant = (cc_call_conferenceParticipant_Info_t *)iterator; - - destParticipant = cpr_malloc(sizeof(cc_call_conferenceParticipant_Info_t)); - if (destParticipant == NULL) { - CCAPP_ERROR(DEB_F_PREFIX" Malloc failure for participant", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - return; - } else { - destParticipant->participantName = strlib_copy(srcParticipant->participantName); - destParticipant->endpointUri = strlib_copy(srcParticipant->endpointUri); - destParticipant->callid = strlib_copy(srcParticipant->callid); - - destParticipant->participantNumber = strlib_copy(srcParticipant->participantNumber); - destParticipant->participantSecurity = srcParticipant->participantSecurity; - destParticipant->participantStatus = srcParticipant->participantStatus; - destParticipant->canRemoveOtherParticipants = srcParticipant->canRemoveOtherParticipants; - } - - sll_ret_val = sll_lite_link_tail(&dest->currentParticipantsList, (sll_lite_node_t *)destParticipant); - if (sll_ret_val != SLL_LITE_RET_SUCCESS) { - CCAPP_ERROR(DEB_F_PREFIX" Error while trying to insert in the linked list", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - cpr_free(destParticipant); - return; - } - - iterator = iterator->next_p; - } -} - -// ------------------- -// API Implementation -// ------------------- - -/** -* Get Conference Participants -* @param [in] handle - call handle -* @param [in/out] participantHandles - array of participant handles to be returned -* @param [in/out] count - in: size of array provided in participantHandles; out: number of entries populated (up to original value provided) -* @return void -*/ -void CCAPI_CallInfo_getConfParticipants (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandles[], int* count) -{ - cc_call_conference_ref_t callConference = NULL; // conference reference (from call info) - cc_call_conference_participant_ref_t participant = NULL; // participant reference - cc_uint16_t participantIndex = 0; // participant index - cc_uint16_t nodeCount = 0; // linked list node count - - CCAPP_DEBUG(DEB_F_PREFIX"Entering: CCAPI_CallInfo_getConfParticipants", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference handle", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - *count = 0; - return; - } - - nodeCount = SLL_LITE_NODE_COUNT(&(callConference->currentParticipantsList)); - CCAPP_DEBUG(DEB_F_PREFIX"SLL NODE COUNT = [%d]", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF"), nodeCount); - if (nodeCount <= 0) - { - *count = 0; - return; - } - - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_HEAD(&callConference->currentParticipantsList); - while (participant != NULL) - { - if (participantIndex >= *count) - { - CCAPP_ERROR(DEB_F_PREFIX"Not Enough Room Provided To List All Participants. Listed [%d] of [%d]", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF"), *count, nodeCount); - return; - } - - // add this participant to our list of particpiants - participantHandles[participantIndex] = (participant->callid); - - // step to the next stored participant in the list - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_NEXT_NODE(participant); - participantIndex++; - } - - // sanity check - if (participantIndex != nodeCount) - { // did not find the expected number of participants! - CCAPP_ERROR(DEB_F_PREFIX"Detected mismatch between counted participants [%d] and SLL returned nodecount [%d]", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF"), - participantIndex, nodeCount); - *count = 0; - return; - } - - // return number of participants - *count = nodeCount; - return; -} - -/** -* Get Maximum Number of Conference Participants ( in case gui wants to show %full conference info ) -* @param [in] handle - call handle -* @return maximum number of conference participants -*/ -cc_uint16_t CCAPI_CallInfo_getConfParticipantMax (cc_callinfo_ref_t handle) -{ // - cc_call_conference_ref_t callConference; // conference reference (from call info) - - CCAPP_DEBUG(DEB_F_PREFIX"Entering: CCAPI_CallInfo_getConfParticipantMax", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // no conference reference available - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (0); - } - - // return the max - return (callConference->participantMax); -} - -/** -* Get Participant Name -* @param [in] handle - call info handle -* @param [in] participantHandle - specific handle for conference participant -* @return display name of the conference participant -*/ -cc_string_t CCAPI_CallInfo_getConfParticipantName (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return strlib_empty(); - } - - return (participant->participantName); -} - -/** -* Get Participant Number -* @param [in] handle - handle of call -* @param [in] participantHandle - handle of conference participant -* @return display number of the conference participant -*/ -cc_string_t CCAPI_CallInfo_getConfParticipantNumber (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return strlib_empty(); - } - - return (participant->participantNumber); -} - -/** -* Get Conference Participant Status -* @param [in] handle - call handle -* @param [in] participantHandle - handle of conference participant -* @return conference participant status -*/ -cc_conf_participant_status_t CCAPI_CallInfo_getConfParticipantStatus (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return (CCAPI_CONFPARTICIPANT_UNKNOWN); - } - - return (participant->participantStatus); -} - -/** -* Get Participant Security -* @param [in] handle - call handle -* @param [in] participantHandle - handle of conference participant -* @return security setting of the specific conference participant -*/ -cc_call_security_t CCAPI_CallInfo_getConfParticipantSecurity (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return (CC_SECURITY_NONE); - } - - return (participant->participantSecurity); -} - -/** -*/ -cc_boolean CCAPI_CallInfo_isConfSelfParticipant (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_ref_t callConference; // conference reference (from call info) - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // error - log - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (FALSE); - } - - return (strcmp((callConference->myParticipantId), participantHandle) == 0); -} - -/** -*/ -cc_participant_ref_t CCAPI_CallInfo_getConfSelfParticipant (cc_callinfo_ref_t handle) -{ - cc_call_conference_ref_t callConference; // conference reference (from call info) - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // unexpected error - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return strlib_empty(); - } - - return (callConference->myParticipantId); -} - -// ----- -/** - * Get the call conference reference - * @param [in] handle - call info handle - * @return cc_call_conference_Info_t - */ -cc_call_conference_ref_t getCallConferenceRef(cc_callinfo_ref_t handle) -{ - session_data_t *data = (session_data_t *)handle; - - if (!CCAPI_CallInfo_getIsConference(handle)) - { - CCAPP_ERROR(DEB_F_PREFIX"Conference API Invoked, but Not In Conference Call", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - }; - - if (data == NULL) - { - return (NULL); - } - - return (&data->call_conference); -} - -// ------------------------------------------------------------------------------------------------------------------ -// getConferenceParticipantRef: returns participant ref (pointer) to a specific participant handle -// ------------------------------------------------------------------------------------------------------------------ -cc_call_conference_participant_ref_t getConferenceParticipantRef(cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_ref_t callConference; // conference reference (from call info) - cc_call_conference_participant_ref_t participant; - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // no conference reference available - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - } - - // see if participantHandle is legit... - if (participantHandle == NULL) - { - CCAPP_DEBUG(DEB_F_PREFIX"Received query for null participant", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - } - - if (SLL_LITE_NODE_COUNT(&(callConference->currentParticipantsList)) <= 0) - { - CCAPP_ERROR(DEB_F_PREFIX"Participant list node count is 0, returning NULL", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - } - - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_HEAD(&callConference->currentParticipantsList); - while (participant != NULL) - { - // see if we've found the participant we're looking for - if (strcmp(participant->callid, participantHandle) == 0) - { - return (participant); - } - - // no match so far, so look at the next item in the list... - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_NEXT_NODE(participant); - } - - CCAPP_ERROR(DEB_F_PREFIX" Did Not Find participant!", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); -} diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.h b/media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.h deleted file mode 100644 index 4eda1bca14c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.h +++ /dev/null @@ -1,49 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CONFROSTER_H__ -#define __CONFROSTER_H__ - -#include "sll_lite.h" -#include "cpr_string.h" -#include "cc_constants.h" -#include "cpr_stdio.h" -#include "ccapi_conf_roster.h" - -// structure for individual participant/user info -typedef struct cc_call_conferenceParticipant_Info_t_ { - sll_lite_node_t node; - cc_participant_ref_t callid; - string_t participantName; - string_t participantNumber; - cc_conf_participant_status_t participantStatus; - cc_call_security_t participantSecurity; - string_t endpointUri; - cc_boolean canRemoveOtherParticipants; -} cc_call_conferenceParticipant_Info_t; - -// reference to above structure -typedef struct cc_call_conferenceParticipant_Info_t_* cc_call_conference_participant_ref_t; - -// main structure (one instance kept per conference (per call)) -typedef struct cc_call_conference_Info_t_ { - int32_t participantMax; - int32_t participantCount; - cc_participant_ref_t myParticipantId; - sll_lite_list_t currentParticipantsList; -} cc_call_conference_Info_t; - -// reference to above structure -typedef struct cc_call_conference_Info_t_* cc_call_conference_ref_t; - -void conf_roster_init_call_conference (cc_call_conference_Info_t *info); -cc_call_conference_ref_t getCallConferenceRef(cc_callinfo_ref_t handle); -cc_call_conference_participant_ref_t getConferenceParticipantRef(cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle); -void conf_roster_free_call_conference (cc_call_conference_Info_t *confInfo); -void conf_roster_copy_call_conferance (cc_call_conference_Info_t *dest, cc_call_conference_Info_t * src); - -#endif - - - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.c b/media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.c deleted file mode 100755 index d2e6497bb53..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.c +++ /dev/null @@ -1,305 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef UNIT_TEST -#define cpr_malloc malloc -#define cpr_free free -#define CCAPP_DEBUG printf -#else -#include "cpr_stdlib.h" -#endif - -#include "sessionHash.h" - -#define HASHBUCKETS 67 - -hash_table_t *hashtable[HASHBUCKETS]={0}; - -void hashItrInit(hashItr_t *itr) -{ - itr->bucket = 0; - itr->node = NULL; -} - -void * hashItrNext(hashItr_t *itr) -{ - int i; - - if ( itr->node != NULL ) { - if ( itr->node->next != NULL ) { - itr->node = itr->node->next; - return itr->node->data; - } - // We just iterated to the end of the list. - // Increment the bucket to search next - itr->bucket++; - } - - for(i=itr->bucket; i< HASHBUCKETS; i++) { - if (hashtable[i] != NULL) { - itr->bucket = i; - itr->node = hashtable[i]; - return itr->node->data; - } - } - return NULL; -} - - -/** - * sessionHash - * function to add generate hash given the key - * - * @param key - - * - * @return the hash index - */ -unsigned int sessionHash (unsigned int key) -{ - // since the key is session_id create the hashval to be line_id + call_id - unsigned int hashval = key + ((key & 0xFFFF0000)>>16); - - return hashval%67; -} - -/** - * addhash - * function to add data for a given key in the table - * - * @param key - * @param data - pointer to data stored - * - * @return - 0 for success - */ - -int addhash (unsigned int key, void *data) -{ - hash_table_t *newhash; - hash_table_t *cur_hash; - unsigned int hashval; - - newhash = (hash_table_t *)(cpr_malloc(sizeof(hash_table_t))); - if (newhash == NULL) { - return -1; - } - - newhash->key = key; - - newhash->data = data; - - hashval = sessionHash(key); - - if (hashtable[hashval] == NULL) { - hashtable[hashval] = newhash; - hashtable[hashval]->prev = NULL; - hashtable[hashval]->next = NULL; - } - else { - cur_hash=hashtable[hashval]; - while(cur_hash->next != NULL) { - cur_hash=cur_hash->next; - } - cur_hash->next = newhash; - newhash->next = NULL; - newhash->prev = cur_hash; - } - - return 0; -} - -/** - * returns the session id given a callid - * @param call_id - * @return sessionID or 0 - */ - -unsigned int ccpro_get_sessionId_by_callid(unsigned short call_id) { - int i; - hash_table_t *cur_hash; - - for ( i=0; ikey & 0xffff) == call_id ) { - return cur_hash->key; - } - cur_hash = cur_hash->next; - } - } - return 0; -} - - -/** - * findhash - * function retrieve the data for the given key - * - * @param key - * - * @return the data ptr or NULL - */ - -void *findhash(unsigned int key) -{ - unsigned int hashval; - hash_table_t *cur_hash; - - hashval = 0; - - hashval = sessionHash(key); - - - cur_hash = hashtable[hashval]; - while ( cur_hash != NULL ) { - if ( cur_hash->key == key) { - return cur_hash->data; - } - cur_hash = cur_hash->next; - } - - return NULL; -} - -/** - * delhash - * function to remove the hash entry for a given key - * - * @param key - * - * @return - 0 for success - */ - -int delhash(unsigned int key) -{ - unsigned int hashval; - hash_table_t *cur_hash; - - hashval = 0; - - hashval = sessionHash(key); - - - if (hashtable[hashval] == NULL) { - return -1; - } - - if (hashtable[hashval]->key == key) { - cur_hash = hashtable[hashval]; - hashtable[hashval] = cur_hash->next; - if ( hashtable[hashval] != NULL ) { - hashtable[hashval]->prev = NULL; - } - cpr_free(cur_hash); - return 0; - } - else { - - cur_hash = hashtable[hashval]->next; - - while (cur_hash != NULL) { - if (cur_hash->key == key) { - cur_hash->prev->next = cur_hash->next; - if (cur_hash->next != NULL) { - cur_hash->next->prev = cur_hash->prev; - } - cpr_free(cur_hash); - return 0; - } - cur_hash = cur_hash->next; - } - } - return -1; -} - -#ifdef UNIT_TEST - -void hashstats(int detail) -{ - static const char *fname="hashstats"; - int max, total, i, nodes, used; - double avg; - hash_table_t *cur_hash; - - max = total = i = nodes = used = 0; - avg = 0; - - if (detail > 0) { - for (i = 0; i < HASHBUCKETS; i++) { - if (hashtable[i] != NULL) { - used++; - nodes = 0; - cur_hash = hashtable[i]; - while(cur_hash != NULL) { - nodes++; - if (detail > 3) { - CCAPPDEBUG(DEB_F_PREFIX"%lx -> %lx: (%lx) (%lx) -> %lx", - DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), - cur_hash->prev, cur_hash, cur_hash->key, cur_hash->data, cur_hash->next); - } - cur_hash = cur_hash->next; - } - if (nodes != 0) total += nodes; - if (nodes > max) { - max = nodes; - } - if (detail > 1) { - CCAPPDEBUG(DEB_F_PREFIX"i: %d", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), i); - } - } - } - avg = (double)(total) / (double)(used); - CCAPPDEBUG(DEB_F_PREFIX"total: %d", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), total); - CCAPPDEBUG(DEB_F_PREFIX"max: %d", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), max); - CCAPPDEBUG(DEB_F_PREFIX"used: %lf", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), 100 * ((double)(used) / (double)(HASHBUCKETS))); - CCAPPDEBUG(DEB_F_PREFIX"average: %lf", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), avg); - } -} - -int main() -{ - static const char *fname="main"; - hashItr_t itr; - void * data; - - addhash(0x01010001,0x1234); - addhash(0x01060001,0x4567); - addhash(0x01060002,0x9324); - addhash(0x01070002,0x4321); - addhash(0x01070004,0x2134); - addhash(0x01080005,0x1324); - addhash(0x01030001,0x1243); - hashstats(7); - - hashItrInit(&itr); - while ( data = hashItrNext(&itr) ) { - CCAPPDEBUG(DEB_F_PREFIX"Itr found %lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), data); - } - - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01010001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070004)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01080005)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01030001)); - - delhash(0x01030001); - delhash(0x01060001); - hashstats(7); - - hashItrInit(&itr); - while ( data = hashItrNext(&itr) ) { - CCAPPDEBUG(DEB_F_PREFIX"Itr found %lx", DEB_F_PREFIX_ARGS(SIP_SES_HAS, fname), data); - } - - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01010001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070004)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01080005)); - CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01030001)); -} -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.h b/media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.h deleted file mode 100755 index afa3d6e601b..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SESSIONHASH_H__ -#define __SESSIONHASH_H__ - -typedef struct hash_table { - struct hash_table *next; - struct hash_table *prev; - unsigned int key; - void *data; -} hash_table_t; - -typedef struct { - unsigned int bucket; - hash_table_t *node; -} hashItr_t; - - -extern void hashItrInit(hashItr_t *itr) ; -extern void * hashItrNext(hashItr_t *itr); -extern int addhash (unsigned int key, void *data) ; -extern int delhash(unsigned int key); -extern void *findhash(unsigned int key); -extern unsigned int ccpro_get_sessionId_by_callid(unsigned short call_id); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.c b/media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.c deleted file mode 100755 index b0a93a48d47..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.c +++ /dev/null @@ -1,418 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include -#include -#include -#include -#include "util_string.h" - -#define IN6ADDRSZ 16 -#define INT16SZ 2 -#define INADDRSZ 4 -#define IS_DIGIT(ch) ((ch >= '0') && (ch <= '9')) - -/* - * Parse ascii dotted ip address notation into binary representation - * only parses and makes sure the address is in the form: - * digits.digits.digits.digits - * Requires minimum of 1 digit per each section and digits cannot - * exceed 255. It does NOT attempt to validate if the end result - * is a valid ip address or not (eg. 0.0.0.0) is accepted. - * The parsed address is returned in the Telecaster "byte reversed" - * order. Eg. 0xf8332ca1 = 161.44.51.248 - */ -int -str2ip (const char *str, cpr_ip_addr_t *cpr_addr) -{ - uint32_t ip_addr; - unsigned int num; - int dot_cnt; - char ch; - int digit_flag; - uint32_t *addr = (uint32_t *)&(cpr_addr->u.ip4); - - dot_cnt = 0; - num = 0; - ip_addr = 0; - digit_flag = 0; - cpr_addr->type = CPR_IP_ADDR_INVALID; - - while (1) { - ch = *str++; - if (!ch) - break; /* end of string */ - /* - * Check for digits 0 through 9 - */ - if (IS_DIGIT(ch)) { - digit_flag = 1; - num = num * 10 + (ch - '0'); - if (num > 255) { - return (1); - } - continue; - } else if (ch == ':') { - //must be ipv6 address - cpr_addr->type = CPR_IP_ADDR_IPV6; - return(cpr_inet_pton(AF_INET6, str, addr)); - } - - /* - * Check for DOT. Must also have seen at least 1 digit prior - */ - if ((ch == '.') && (digit_flag)) { - dot_cnt++; - ip_addr = ((ip_addr << 8) | num); - num = 0; - digit_flag = 0; - continue; - } - - /* if get here invalid dotted IP character or missing digit */ - return (1); - } - - /* - * Must have seen 3 dots exactly and at least 1 trailing digit - */ - if ((dot_cnt != 3) || (!digit_flag)) { - return (1); - } - - ip_addr = ((ip_addr << 8) | num); - - ip_addr = ntohl(ip_addr); /* convert to Telecaster format */ - cpr_addr->type = CPR_IP_ADDR_IPV4; - *addr = ip_addr; - return (0); -} - - -/* - * Parse an IP address. - * If the IP address value is set to "" or to "UNPROVISIONED" it - * is set to its' default value. - */ -int -cfgfile_parse_ip (const var_t *entry, const char *value) -{ -// RAC - Defaults will need to be handled on the Java Side. -// if ((*value == NUL) || (cpr_strcasecmp(value, "UNPROVISIONED") == 0)) { -// cfgfile_set_default(entry); -// return (0); -// } else { - return (str2ip(value, (cpr_ip_addr_t *) entry->addr)); -// } -} - -/* - * Print (format) an IP address. - * The IP address to be printed is in the Telecaster "byte reversed" - * order. Eg. 0xf8332ca1 = 248.51.44.161 - */ -int -cfgfile_print_ip (const var_t *entry, char *buf, int len) -{ - // RT phones receive the IP address in this order: 0xf8332ca1 = 161.44.51.248 - cpr_ip_addr_t *cprIpAddrPtr = (cpr_ip_addr_t *)entry->addr; - - if (cprIpAddrPtr->type == CPR_IP_ADDR_IPV4) { - sprint_ip(buf, cprIpAddrPtr->u.ip4); - return 1; - } - - return 0; -} - -/* - * Print (format) an IP address. - * The IP address to be printed is in the non-Telecaster "byte reversed" - * order - which is really network order. Eg. 0xa12c33f8 = 161.44.51.248 - */ -int -cfgfile_print_ip_ntohl (const var_t *entry, char *buf, int len) -{ - uint32_t ip; - - ip = *(uint32_t *) entry->addr; - return (snprintf(buf, len, get_debug_string(DEBUG_IP_PRINT), - ((ip >> 24) & (0xff)), ((ip >> 16) & (0xff)), - ((ip >> 8) & (0xff)), ((ip >> 0) & (0xff)))); -} - -/* - * parse (copy) an ascii string - */ -int -cfgfile_parse_str (const var_t *entry, const char *value) -{ - int str_len; - - /* fixme: this could use malloc, or offer a different */ - /* fixme: parser routine that does like parse_str_ptr */ - /* fixme: in that case, free the old string and */ - /* fixme: strdup the new string */ - - str_len = strlen(value); - if (str_len + 1 > entry->length) { - CSFLogError("common", get_debug_string(DEBUG_PARSER_STRING_TOO_LARGE), - entry->length, str_len); - return (1); - } - - /* - * Copy string into config block - */ - sstrncpy((char *)entry->addr, value, entry->length); - return (0); - - -} - -/* - * Print (format) at string - */ -int -cfgfile_print_str (const var_t *entry, char *buf, int len) -{ - return (snprintf(buf, len, "%s", (char *)entry->addr)); -} - -/* - * Parse an ascii integer into binary - */ -int -cfgfile_parse_int (const var_t *entry, const char *value) -{ - unsigned int num; - char ch; - - num = 0; - - if (strcmp(value, "UNPROVISIONED") == 0) { - num = 0; - } else { - while (1) { - ch = *value++; - if (!ch) - break; /* end of string */ - /* - * Check for digits 0 through 9 - */ - if (IS_DIGIT(ch)) { - num = num * 10 + (ch - '0'); - continue; - } - - /* if get here invalid decimal character */ - return (1); - } - } - switch (entry->length) { - case 1: - *(uint8_t *) entry->addr = (uint8_t) num; - break; - case 2: - *(uint16_t *) entry->addr = (uint16_t) num; - break; - case 4: - *(uint32_t *) entry->addr = num; - break; - default: - *(unsigned int *) entry->addr = num; - break; - } - - return (0); -} - -/* - * print (format) an Integer - */ -int -cfgfile_print_int (const var_t *entry, char *buf, int len) -{ - unsigned int value; - - switch (entry->length) { - case 1: - value = *(uint8_t *) entry->addr; - break; - case 2: - value = *(uint16_t *) entry->addr; - break; - case 4: - value = *(uint32_t *) entry->addr; - break; - default: - value = *(unsigned int *) entry->addr; - break; - } - return (snprintf(buf, len, "%u", value)); -} - -/* - * Parse a keytable. A key table is a list of keywords. For each - * keyword there is an associated enum value (key value). - * search the keyword table for a matching keyword, and if found - * set the variable to the matching emum value. - */ -int -cfgfile_parse_key (const var_t *entry, const char *value) -{ - const key_table_entry_t *keytable; - - keytable = entry->key_table; - - if (keytable == NULL) { - CSFLogError("common", "%s", - get_debug_string(DEBUG_PARSER_NULL_KEY_TABLE)); - return (1); - } - -// RAC - This (If Needed) Will need to be moved to the Java Side. -// /* check for nulled out keys and set to the default value */ -// if ((cpr_strcasecmp(value,"UNPROVISIONED") == 0) || -// (value[0] == 0)) { -// CSFLogError("common", get_debug_string(DEBUG_PARSER_SET_DEFAULT), -// entry->name, entry->default_value); -// cfgfile_set_default(entry); -// return(0); -// } - - while (keytable->name) { - if (cpr_strcasecmp(value, keytable->name) == 0) { - *(unsigned int *) entry->addr = keytable->value; - return (0); - } - keytable++; - } - - CSFLogError("common", get_debug_string(DEBUG_PARSER_UNKNOWN_KEY), value); - return (1); -} - -/* - * print (format) a key value. Search the table for the matching - * enum type, then format as output the keyname associated with it. - */ -int -cfgfile_print_key (const var_t *entry, char *buf, int len) -{ - const key_table_entry_t *keytable; - int value; - - keytable = entry->key_table; - value = *(int *) entry->addr; - - while (keytable->name) { - if (value == keytable->value) { - return (snprintf(buf, len, "%s", keytable->name)); - } - keytable++; - } - - CSFLogError("common", get_debug_string(DEBUG_PARSER_UNKNOWN_KEY_ENUM), - value); - return (0); -} - -/* - * Sprintf an IP address in dotted notation. - */ -int -sprint_ip (char *buf, uint32_t ip) -{ - return (sprintf(buf, get_debug_string(DEBUG_IP_PRINT), - ((ip >> 0) & (0xff)), ((ip >> 8) & (0xff)), - ((ip >> 16) & (0xff)), ((ip >> 24) & (0xff)))); -} - -/* - * print (format) a MAC address - */ -int -cfgfile_print_mac (const var_t *entry, char *buf, int len) -{ - return (snprintf(buf, len, get_debug_string(DEBUG_MAC_PRINT), - ((uint8_t *) entry->addr)[0] * 256 + - ((uint8_t *) entry->addr)[1], - ((uint8_t *) entry->addr)[2] * 256 + - ((uint8_t *) entry->addr)[3], - ((uint8_t *) entry->addr)[4] * 256 + - ((uint8_t *) entry->addr)[5])); -} - -/** - * Parse a keytable. A key table is a list of keywords. For each - * keyword there is an associated enum value (key value). - * search the keyword table for a matching keyword, and if found - * save the entire key etnry into the table. - * - * @param[in] entry - pointer ot var_t. - * @param[in] value - pointer to const. string of configuration value. - * - * @return 1 - failed to parsed the configuration. - * 0 - succesfull parsed the configuration value. - * - * @pre (entry != NULL) - * @pre (value != NULL) - */ -int -cfgfile_parse_key_entry (const var_t *entry, const char *value) -{ - const key_table_entry_t *keytable; - - keytable = entry->key_table; - - if (keytable == NULL) { - CSFLogError("common", "%s", - get_debug_string(DEBUG_PARSER_NULL_KEY_TABLE)); - return (1); - } - - while (keytable->name) { - if (cpr_strcasecmp(value, keytable->name) == 0) { - /* keep the entire entry */ - *(key_table_entry_t *)entry->addr = *keytable; - return (0); - } - keytable++; - } - - CSFLogError("common", get_debug_string(DEBUG_PARSER_UNKNOWN_KEY), value); - return (1); -} - -/** - * print (format) a key value. Print the name of the key out. - * - * @param[in] entry - pointer ot var_t. - * @param[in] value - pointer to const. string of configuration value. - * - * @return always return 0. - * - * @pre (entry != NULL) - * @pre (value != NULL) - */ -int -cfgfile_print_key_entry (const var_t *entry, char *buf, int len) -{ - key_table_entry_t *key; - - key = (key_table_entry_t *) entry->addr; - if (key->name != NULL) { - return (snprintf(buf, len, "%s", key->name)); - } else { - /* the entry is not even configured */ - return (0); - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.h b/media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.h deleted file mode 100755 index 63e5465326a..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.h +++ /dev/null @@ -1,96 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CFGFILE_UTILS_H_ -#define _CFGFILE_UTILS_H_ - -#include "cpr_types.h" - -//============================================================================= -// -// Structure/Type definitions -// -//----------------------------------------------------------------------------- - -struct var_struct; - -typedef int (*parse_func_t)(const struct var_struct *, const char *); -typedef int (*print_func_t)(const struct var_struct *, char *, int); - -typedef struct { - const char *name; - int value; -} key_table_entry_t; - -#define NULL_KEY (-1) - -typedef struct var_struct { - const char *name; - void *addr; - int length; - parse_func_t parse_func; - print_func_t print_func; - const key_table_entry_t *key_table; -} var_t; - -/********************************************************* - * - * Config Table "Helper" Routines - * - * These #defines are routines that are called from the - * config table entries to parse (PA), print (PR), - * and export (XP), different config entries. These are the - * "common" helper routines. Protocol-specific routines - * are located in prot_configmgr_private.h - * - *********************************************************/ -#define PA_IP cfgfile_parse_ip -#define PR_IP cfgfile_print_ip -#define PR_IPN cfgfile_print_ip_ntohl -#define PA_STR cfgfile_parse_str -#define PR_STR cfgfile_print_str -#define PA_INT cfgfile_parse_int -#define PR_INT cfgfile_print_int -#define PA_KEY cfgfile_parse_key -#define PA_KEYE cfgfile_parse_key_entry -#define PR_KEY cfgfile_print_key -#define PR_KEYE cfgfile_print_key_entry -#define PR_MAC cfgfile_print_mac -#define XP_NONE 0 - -/********************************************************* - * - * Config Table "Helper" Macros - * - * These macros are used to help build the actual config - * table. They provide the address and length of the - * entries. They also tell which table the entry is - * stored in. - * - *********************************************************/ -#define CFGADDR(field) ((void*)&(prot_cfg_block.field)) -#define CFGLEN(field) (sizeof(prot_cfg_block.field)) -#define CFGVAR(field) CFGADDR(field),CFGLEN(field) - -/* generic config file parsing functions */ -int cfgfile_parse_ip(const var_t *, const char *value); -int cfgfile_parse_str(const var_t *, const char *value); -int cfgfile_parse_int(const var_t *, const char *value); -int cfgfile_parse_key(const var_t *, const char *value); -int cfgfile_parse_key_entry(const var_t *, const char *value); - -/* generic config file printing functions */ -int cfgfile_print_ip(const var_t *, char *buf, int); -int cfgfile_print_ip_ntohl(const var_t *, char *buf, int); -int cfgfile_print_str(const var_t *, char *buf, int); -int cfgfile_print_int(const var_t *, char *buf, int); -int cfgfile_print_key(const var_t *, char *buf, int); -int cfgfile_print_key_entry(const var_t *, char *buf, int); - -/* generic config file export (print) functions */ -int sprint_ip(char *, uint32_t ip); -int sprint_mac(char *, const unsigned char *ptr); -int cfgfile_print_mac(const var_t *entry, char *buf, int); - -#endif /* _CFGFILE_UTILS_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/common/config_api.c b/media/webrtc/signaling/src/sipcc/core/common/config_api.c deleted file mode 100755 index 38b43893d16..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/config_api.c +++ /dev/null @@ -1,494 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "config.h" -#include "dns_utils.h" -#include "phone_debug.h" -#include "ccapi.h" -#include "debug.h" - -cc_int32_t ConfigDebug; - -/* - * This file contains the API routines that are used to - * access the config table. - * - * Avoid writing more of these routines. - * Try and reuse these routines as much as possible. - * - * We should be able to set and retrieve any type of value - * using one of these routines. - */ - - -/* - * Function: config_get_string() - * - * Description: Get any arbitrary config entry as a string - * - * Parameters: id - The id of the config string to get - * buffer - Empty buffer where string will be copied - * buffer_len - length of the buffer where string will be copied - * - * Returns: None - */ -void -config_get_string (int id, char *buffer, int buffer_len) -{ - const var_t *entry; - char *buf_start; - - /* - * Set the result to be empty in case we can't find anything - */ - buffer[0] = 0; - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (entry->length > buffer_len) { - CONFIG_ERROR(CFG_F_PREFIX"insufficient buffer: %d", "config_get_string", - id); - } else { - buf_start = buffer; - entry->print_func(entry, buffer, buffer_len); - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: get str: %s = %s", DEB_F_PREFIX_ARGS(CONFIG_API, "config_get_string"), id, entry->name, - buf_start); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d", "config_get_string", id); - } -} - - -/* - * Function: config_set_string() - * - * Parameters: id - The id of the config string to set - * buffer - The new value for the string - * - * Description: Set any arbitrary config entry as a string - * - * Returns: None - */ -void -config_set_string (int id, char *buffer) -{ - const var_t *entry; - - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (entry->parse_func(entry, buffer)) { - /* Parse function returned an error */ - CONFIG_ERROR(CFG_F_PREFIX"Parse function failed. ID: %d %s:%s", "config_set_string", id, entry->name, buffer); - } else { - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s set str to %s", DEB_F_PREFIX_ARGS(CONFIG_API, "config_set_string"), id, entry->name, - buffer); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d", "config_set_string", id); - } -} - -#define MAX_CONFIG_VAL_PRINT_LEN 258 -/* - * Function: print_config_value() - * - * Description: If debug is enabled then print value contained in - * the buffer. Cast and dereference the buffer ptr - * according to length. If no match to char, short, - * int or long then just print each byte (ex: MacAddr). - * Called by config_set/get_value() function. - * - * Parameters: id - the id of the config value to get - * get_set - config action (get val or set val) - * entry_name - config id name - * buffer - buffer containing the value - * length - number of bytes in the buffer - * - * Returns: none - */ -/* - * Some logical upper limit to avoid long print out in case - * of large length value - */ -void -print_config_value (int id, char *get_set, const char *entry_name, - void *buffer, int length) -{ - long long_val = 0; - int int_val = 0; - short short_val = 0; - char char_val = 0; - char str[MAX_CONFIG_VAL_PRINT_LEN]; - char *in_ptr; - char *str_ptr; - - if (length == sizeof(char)) { - char_val = *(char *) buffer; - long_val = (long) char_val; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length == sizeof(short)) { - short_val = *(short *) buffer; - long_val = (long) short_val; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length == sizeof(int)) { - int_val = *(int *) buffer; - long_val = (long) int_val; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length == sizeof(long)) { - long_val = *(long *) buffer; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length < MAX_CONFIG_VAL_PRINT_LEN / 2) { - - in_ptr = (char *) buffer; - str_ptr = &str[0]; - while (length--) { - sprintf(str_ptr++, "%02x", *in_ptr++); - str_ptr++; - } - *str_ptr = '\0'; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %s", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, str); - } else { - CONFIG_ERROR(CFG_F_PREFIX"cfg_id = %d length too long -> %d", "print_config_value", - id, length); - } -} - -/* - * Function: config_get_value() - * - * Description: Get any arbitrary config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Parameters: id - The id of the config value to get - * buffer - Empty buffer where value will be copied - * length - The number of bytes to get - * - * Returns: None - */ -void -config_get_value (int id, void *buffer, int length) -{ - const var_t *entry; - - /* - * Retrieve raw entry from table..... - */ - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (length == entry->length) { - memcpy(buffer, entry->addr, entry->length); - - if (ConfigDebug) { - print_config_value(id, "Get Val", entry->name, buffer, length); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"%s size error", "config_get_value", - entry->name); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d", "config_get_value", id); - } -} - - -/* - * Function: config_set_value() - * - * Description: Set arbitrary config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Parameters: id - The id of the config value to set - * buffer - The new value to be set - * length - The number of bytes to set - * - * Returns: None - */ -void -config_set_value (int id, void *buffer, int length) -{ - const var_t *entry; - - /* - * Retrieve entry from table..... - */ - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (entry->length != length) { - CONFIG_ERROR(CFG_F_PREFIX" %s size error entry size=%d, len=%d", - "config_set_value", entry->name, entry->length, length); - return; - } - memcpy(entry->addr, buffer, entry->length); - if (ConfigDebug) { - print_config_value(id, "Set Val", entry->name, buffer, length); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d", "config_set_value", id); - } -} - -/* Function: get_printable_cfg() - * - * Description: prints the config value in the buf - * - * Parameters: indx, buf, len - * - * Returns: buf - */ -char * -get_printable_cfg(unsigned int indx, char *buf, unsigned int len) -{ - const var_t *table; - buf[0]=0; - - table = &prot_cfg_table[indx]; - // If this field has a password, print the param name, but NOT the - // real password - if (indx>=CFGID_LINE_PASSWORD && indx < CFGID_LINE_PASSWORD+MAX_CONFIG_LINES) { - // and add an invisible one - sstrncpy(buf, "**********", MAX_CONFIG_VAL_PRINT_LEN); - } else if ( table->print_func ) { - table->print_func(table, buf, len); - } - - if ( buf[0] == 0 ) { - sstrncpy(buf,"EMPTY", len); - } - return buf; -} - -/* - * Function: show_config_cmd() - * - * Description: Callback passed in the config init routine for show config - * - * Parameters: argc, argv - * - * Returns: zero(0) - */ - -cc_int32_t -show_config_cmd (cc_int32_t argc, const char *argv[]) -{ - const var_t *table; - char buf[MAX_CONFIG_VAL_PRINT_LEN]; - int i, feat; - - debugif_printf("\n------ Current *Cache* Configuration ------\n"); - table = prot_cfg_table; - - for ( i=0; i < CFGID_LINE_FEATURE; i++ ) { - if (table->print_func) { - table->print_func(table, buf, sizeof(buf)); - - // If this field has a password, print the param name, but NOT the - // real password - if (strstr(table->name, "Password") != 0) { - // and add an invisible one - sstrncpy(buf, "**********", sizeof(buf)); - } - debugif_printf("%s : %s\n", table->name, buf); - } - table++; - } - - debugif_printf("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", - prot_cfg_table[CFGID_LINE_INDEX].name, - prot_cfg_table[CFGID_LINE_FEATURE].name, - prot_cfg_table[CFGID_PROXY_ADDRESS].name, - prot_cfg_table[CFGID_PROXY_PORT].name, - prot_cfg_table[CFGID_LINE_CALL_WAITING].name, - prot_cfg_table[CFGID_LINE_MSG_WAITING_LAMP].name, - prot_cfg_table[CFGID_LINE_MESSAGE_WAITING_AMWI].name, - prot_cfg_table[CFGID_LINE_RING_SETTING_IDLE].name, - prot_cfg_table[CFGID_LINE_RING_SETTING_ACTIVE].name, - prot_cfg_table[CFGID_LINE_NAME].name, - prot_cfg_table[CFGID_LINE_AUTOANSWER_ENABLED].name, - prot_cfg_table[CFGID_LINE_AUTOANSWER_MODE].name, - prot_cfg_table[CFGID_LINE_AUTHNAME].name, - prot_cfg_table[CFGID_LINE_PASSWORD].name, - prot_cfg_table[CFGID_LINE_DISPLAYNAME].name, - prot_cfg_table[CFGID_LINE_CONTACT].name); - - for (i=0; i< MAX_CONFIG_LINES; i++) { - config_get_value(CFGID_LINE_FEATURE+i, &feat, sizeof(feat)); - if ( feat != CC_FEATURE_NONE ){ - debugif_printf("%3s ", get_printable_cfg(CFGID_LINE_INDEX+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%4s ", get_printable_cfg(CFGID_LINE_FEATURE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%12s ", get_printable_cfg(CFGID_PROXY_ADDRESS+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_PROXY_PORT+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%3s ", get_printable_cfg(CFGID_LINE_CALL_WAITING+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_MSG_WAITING_LAMP+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_MESSAGE_WAITING_AMWI+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_RING_SETTING_IDLE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_RING_SETTING_ACTIVE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf(" %s ", get_printable_cfg(CFGID_LINE_NAME+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_AUTOANSWER_ENABLED+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_AUTOANSWER_MODE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_AUTHNAME+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_PASSWORD+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_DISPLAYNAME+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s\n", get_printable_cfg(CFGID_LINE_CONTACT+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - } - } - - return (0); -} - - -/********************************************** - * Line-Based Config API - **********************************************/ - -/* - * Function: config_get_line_id() - * - * Description: Given the line and the line-specific ID, this function - * will return the actual ID used to access the value in the - * config table. - * - * Parameters: id - The id config value to get - * line - The line that the ID is associated with - * - * Returns: TRUE if the entry is found - * FALSE otherwise. - */ -static int -config_get_line_id (int id, int line) -{ - int line_id = 0; - const var_t *entry; - - if ((line == 0) || (line > MAX_REG_LINES)) { - entry = &prot_cfg_table[id]; // XXX set but not used - (void) entry; - CONFIG_ERROR(CFG_F_PREFIX"ID=%d- line %d out of range", "config_get_line_id", id, line); - return (0); - } - line_id = id + line - 1; - - return (line_id); -} - - -/* - * Function: config_get_line_string() - * - * Description: Get any arbitrary line config entry as a string - * - * Parameters: id - The id of the config string to get - * buffer - Empty buffer where string will be copied - * line - The line that the ID is associated with - * buffer_len - length of the output buffer - * - * Returns: None - */ -void -config_get_line_string (int id, char *buffer, int line, int buffer_len) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_get_string(line_id, buffer, buffer_len); - } -} - - -/* - * Function: config_set_line_string() - * - * Description: Set any arbitrary line config entry as a string - * - * Parameters: id - The id of the config string to set - * buffer - The new value for the string - * line - The line that the ID is associated with - * - * Returns: None - */ -void -config_set_line_string (int id, char *buffer, int line) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_set_string(line_id, buffer); - } -} - -/* - * Function: config_get_line_value() - * - * Parameters: id - The id of the config value to get - * *buffer - Empty buffer where value will be copied - * length - The number of bytes to get - * line - The line that the ID is associated with - * - * Description: Get any arbitrary line config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Returns: None - */ -void -config_get_line_value (int id, void *buffer, int length, int line) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_get_value(line_id, buffer, length); - } -} - -/* - * Function: config_set_line_value() - * - * Description: Set arbitrary config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Parameters: id - The id of the config value to set - * buffer - The new value to be set - * length - The number of bytes to set - * line - The line that the ID is associated with - * - * Returns: None - */ -void -config_set_line_value (int id, void *buffer, int length, int line) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_set_value(line_id, buffer, length); - } -} - -/* - * Function: config_init() - * - * Description: Initialize the Config Debug command - * - * Parameters: none - * - * Returns: none - * - */ -void -config_init (void) -{ - /* Place holder for future init related actions */ -} diff --git a/media/webrtc/signaling/src/sipcc/core/common/config_parser.c b/media/webrtc/signaling/src/sipcc/core/common/config_parser.c deleted file mode 100644 index 3c64cfca821..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/config_parser.c +++ /dev/null @@ -1,636 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "cc_constants.h" -#include "cc_types.h" -#include "cc_config.h" -#include "phone_debug.h" -#include "debug.h" -#include "ccapi.h" -#include "prot_configmgr.h" -#include "call_logger.h" -#include "sip_common_transport.h" -#include "sip_ccm_transport.h" -#include "config_parser.h" -#include "cc_device_feature.h" -#include "ccapi_snapshot.h" -#include "config_api.h" -#include "capability_set.h" -#include "util_string.h" - -#define MAC_ADDR_SIZE 6 -#define FILE_PATH 256 -#define MAX_MULTI_LEVEL_CONFIG 2 - -#define MLCFG_VIDEO_CAPABILITY 0 -#define MLCFG_CISCO_CAMERA 1 -#define MLCFG_CAPABILITY_MAX 2 -#define MLCFG_NOT_SET -1 - -#define VERSION_LENGTH_MAX 100 - -#define ID_BLOCK_PREF1 1 -#define ID_BLOCK_PREF3 3 -/* - * File location is hardcoded for getting mac and IP addr - */ -#define IP_ADDR_FILE "/sdcard/myip.txt" -static char autoreg_name[MAX_LINE_NAME_SIZE]; - -static char fcpTemplateFile[FILE_PATH] = ""; - -char g_cfg_version_stamp[MAX_CFG_VERSION_STAMP_LEN + 1] = {0}; -int line = -1; //initialize line to -1, as 0 is valid line -boolean apply_config = FALSE; -cc_apply_config_result_t apply_config_result = APPLY_CONFIG_NONE; -extern var_t prot_cfg_table[]; -void print_config_value (int id, char *get_set, const char *entry_name, void *buffer, int length); - -static int sip_port[MAX_CCM]; -static int secured_sip_port[MAX_CCM]; -static int security_mode = 3; /*SECURE*/ -extern accessory_cfg_info_t g_accessoryCfgInfo; - -// Configurable settings -static int gTransportLayerProtocol = 4; // 4 = tcp, 2 = udp -static boolean gP2PSIP = FALSE; -static boolean gSDPMODE = FALSE; -static int gVoipControlPort = 5060; -static int gCcm1_sip_port = 5060; - -/* - * This function determine whether the passed config parameter should be used - * in comparing the new and old config value for apply-config purpose. Only - * those config ids on whose change phone needs to restart are part of this - * function. For remaining parameters, it is assumed that any change can be - * applied dynamically. - * - */ -boolean is_cfgid_in_restart_list(int cfgid) { - - if ((cfgid >= CFGID_LINE_FEATURE && cfgid < (CFGID_LINE_FEATURE + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_INDEX && cfgid < (CFGID_LINE_INDEX + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_PROXY_ADDRESS && cfgid < (CFGID_PROXY_ADDRESS + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_PROXY_PORT && cfgid < (CFGID_PROXY_PORT + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_NAME && cfgid < (CFGID_LINE_NAME + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_DISPLAYNAME && cfgid < (CFGID_LINE_DISPLAYNAME + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_SPEEDDIAL_NUMBER && cfgid < (CFGID_LINE_SPEEDDIAL_NUMBER + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_MESSAGES_NUMBER && cfgid < (CFGID_LINE_MESSAGES_NUMBER + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_CALLER_NAME_DIPLAY && cfgid < (CFGID_LINE_FWD_CALLER_NAME_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY && cfgid < (CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY && cfgid < (CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY && cfgid < (CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_CALL_WAITING && cfgid < (CFGID_LINE_CALL_WAITING + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_AUTHNAME && cfgid < (CFGID_LINE_AUTHNAME + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_PASSWORD && cfgid < (CFGID_LINE_PASSWORD + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FEATURE_OPTION_MASK && cfgid < (CFGID_LINE_FEATURE_OPTION_MASK + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_MSG_WAITING_LAMP && cfgid < (CFGID_LINE_MSG_WAITING_LAMP + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_MESSAGE_WAITING_AMWI && cfgid < (CFGID_LINE_MESSAGE_WAITING_AMWI + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_RING_SETTING_IDLE && cfgid < (CFGID_LINE_RING_SETTING_IDLE + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_RING_SETTING_ACTIVE && cfgid < (CFGID_LINE_RING_SETTING_ACTIVE + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_CONTACT && cfgid < (CFGID_LINE_CONTACT + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_AUTOANSWER_ENABLED && cfgid < (CFGID_LINE_AUTOANSWER_ENABLED + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_AUTOANSWER_MODE && cfgid < (CFGID_LINE_AUTOANSWER_MODE + MAX_CONFIG_LINES)) - ) - { - return TRUE; - } - switch (cfgid) { - case CFGID_CCM1_ADDRESS: - case CFGID_CCM2_ADDRESS: - case CFGID_CCM3_ADDRESS: - case CFGID_CCM1_SIP_PORT: - case CFGID_CCM2_SIP_PORT: - case CFGID_CCM3_SIP_PORT: - - case CFGID_PROXY_BACKUP: - case CFGID_PROXY_BACKUP_PORT: - case CFGID_PROXY_EMERGENCY: - case CFGID_PROXY_EMERGENCY_PORT: - case CFGID_OUTBOUND_PROXY: - case CFGID_OUTBOUND_PROXY_PORT: - - case CFGID_PROXY_REGISTER: - case CFGID_REMOTE_CC_ENABLED: - - case CFGID_SIP_INVITE_RETX: - case CFGID_SIP_RETX: - case CFGID_TIMER_INVITE_EXPIRES: - case CFGID_TIMER_KEEPALIVE_EXPIRES: - case CFGID_TIMER_SUBSCRIBE_EXPIRES: - case CFGID_TIMER_SUBSCRIBE_DELTA: - case CFGID_TIMER_T1: - case CFGID_TIMER_T2: - - case CFGID_SIP_MAX_FORWARDS: - case CFGID_REMOTE_PARTY_ID: - case CFGID_REG_USER_INFO: - - case CFGID_PREFERRED_CODEC: - case CFGID_VOIP_CONTROL_PORT: - case CFGID_NAT_ENABLE: - case CFGID_NAT_ADDRESS: - case CFGID_NAT_RECEIVED_PROCESSING: - - case CFGID_DTMF_AVT_PAYLOAD: - case CFGID_DTMF_DB_LEVEL: - case CFGID_DTMF_OUTOFBAND: - - case CFGID_KPML_ENABLED: - case CFGID_MEDIA_PORT_RANGE_START: - case CFGID_TRANSPORT_LAYER_PROT: - - case CFGID_TIMER_REGISTER_EXPIRES: - case CFGID_TIMER_REGISTER_DELTA: - case CFGID_DSCP_FOR_CALL_CONTROL: - return TRUE; - default: - return FALSE; - } -} - - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_byte_value(int cfgid, unsigned char value, const unsigned char * config_name) { - int temp_value ; - const var_t *entry; - if (apply_config == TRUE) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_value(cfgid, &temp_value, sizeof(temp_value)); - if (((int)value) != temp_value) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. Old value=%d new value=%d", "compare_or_set_byte_value", config_name, cfgid, temp_value, value); - } - } - } else { - CC_Config_setByteValue(cfgid, value); - } -} - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_boolean_value(int cfgid, cc_boolean value, const unsigned char * config_name) { - int temp_value ; - const var_t *entry; - if (apply_config == TRUE) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_value(cfgid, &temp_value, sizeof(temp_value)); - if (((int)value) != temp_value) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. Old value=%d new value=%d", "compare_or_set_boolean_value", config_name, cfgid, temp_value, value); - } - } - } else { - CC_Config_setBooleanValue(cfgid, value); - } -} - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_int_value(int cfgid, int value, const unsigned char * config_name) { - int temp_value; - const var_t *entry; - if (apply_config == TRUE) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_value(cfgid, &temp_value, sizeof(temp_value)); - if (value != temp_value) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. new value=%d Old value=%d", "compare_or_set_int_value", config_name, cfgid, value, temp_value); - } - } - } else { - CC_Config_setIntValue(cfgid, value); - } -} - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_string_value (int cfgid, const char* value, const unsigned char * config_name) { - static char temp_value[MAX_SIP_URL_LENGTH]; - const var_t *entry; - if (apply_config == TRUE ) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_string(cfgid, temp_value, MAX_SIP_URL_LENGTH); - if (strcmp(value, temp_value) != 0) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. new value=%s Old value=%s", "compare_or_set_string_value", config_name, cfgid, value, temp_value); - } - } - } else { - CC_Config_setStringValue(cfgid, value); - } -} - -int lineConfig = 0; -int portConfig = 0; -int proxyConfig = 0; - -/* - * config_set_autoreg_properties - * - */ -void config_set_autoreg_properties () -{ - CC_Config_setIntValue(CFGID_LINE_INDEX + 0, 1); - CC_Config_setIntValue(CFGID_LINE_FEATURE + 0, 9); - CC_Config_setStringValue(CFGID_PROXY_ADDRESS + 0, "USECALLMANAGER"); - CC_Config_setIntValue(CFGID_PROXY_PORT + 0, 5060); - CC_Config_setStringValue(CFGID_LINE_NAME + 0, autoreg_name); - CC_Config_setBooleanValue(CFGID_PROXY_REGISTER, 1); - CC_Config_setIntValue(CFGID_TRANSPORT_LAYER_PROT, 2); - - /* timerRegisterExpires = 3600 */ - CC_Config_setIntValue(CFGID_TIMER_REGISTER_EXPIRES, 3600); - /* sipRetx = 10 */ - CC_Config_setIntValue(CFGID_SIP_RETX, 10); - /* sipInviteRetx = 6 */ - CC_Config_setIntValue(CFGID_SIP_INVITE_RETX, 6); - /* timerRegisterDelta = 5 */ - CC_Config_setIntValue(CFGID_TIMER_REGISTER_DELTA, 5); - /* MaxRedirects = 70 */ - CC_Config_setIntValue(CFGID_SIP_MAX_FORWARDS, 70); - /* timerInviteExpires = 180 */ - CC_Config_setIntValue(CFGID_TIMER_INVITE_EXPIRES, 180); - /* timerSubscribeDelta = 5 */ - CC_Config_setIntValue(CFGID_TIMER_SUBSCRIBE_DELTA, 5); - /* timerSubscribeExpires = 120 */ - CC_Config_setIntValue(CFGID_TIMER_SUBSCRIBE_EXPIRES, 120); - - CC_Config_setIntValue(CFGID_REMOTE_CC_ENABLED, 1); - CC_Config_setIntValue(CFGID_VOIP_CONTROL_PORT, 5060); -} - -/* - * update_security_mode_and_ports - * - */ -void update_security_mode_and_ports(void) { - sec_level_t sec_level = NON_SECURE; - - // convert security mode (from UCM xml) into internal enum - switch (security_mode) - { - case 1: sec_level = NON_SECURE; break; - case 2: sec_level = AUTHENTICATED; break; - case 3: sec_level = ENCRYPTED; break; - default: - CONFIG_ERROR(CFG_F_PREFIX "unable to translate securite mode [%d]", "update_security_mode_and_ports", (int)security_mode); - break; - } - - compare_or_set_int_value(CFGID_CCM1_SEC_LEVEL, sec_level, - (const unsigned char *)"deviceSecurityMode"); - compare_or_set_int_value(CFGID_CCM2_SEC_LEVEL, sec_level, - (const unsigned char *)"deviceSecurityMode"); - compare_or_set_int_value(CFGID_CCM3_SEC_LEVEL, sec_level, - (const unsigned char *)"deviceSecurityMode"); - - if (sec_level == NON_SECURE) { - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, sip_port[0], - (const unsigned char *)"ccm1_sip_port"); - compare_or_set_int_value(CFGID_CCM2_SIP_PORT, sip_port[1], - (const unsigned char *)"ccm2_sip_port"); - compare_or_set_int_value(CFGID_CCM3_SIP_PORT, sip_port[2], - (const unsigned char *)"ccm3_sip_port"); - } else { - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, secured_sip_port[0], - (const unsigned char *)"ccm1_secured_sip_port"); - compare_or_set_int_value(CFGID_CCM2_SIP_PORT, secured_sip_port[1], - (const unsigned char *)"ccm2_secured_sip_port"); - compare_or_set_int_value(CFGID_CCM3_SIP_PORT, secured_sip_port[2], - (const unsigned char *)"ccm3_secured_sip_port"); - } -} - - -#define MISSEDCALLS "Application:Cisco/MissedCalls" -#define PLACEDCALLS "Application:Cisco/PlacedCalls" -#define RECEIVEDCALLS "Application:Cisco/ReceivedCalls" - -/* - * config_get_mac_addr - * - * Get the filename that has the mac address and parse the string - * convert it into an mac address stored in the bytearray maddr -*/ -void config_get_mac_addr (char *maddr) -{ - platGetMacAddr(maddr); - -} - -/* - * Set the MAC address in the config table - */ -void config_set_ccm_ip_mac () -{ - - char macaddr[MAC_ADDR_SIZE]; - - compare_or_set_int_value(CFGID_DSCP_FOR_CALL_CONTROL , 1, (const unsigned char *) "DscpCallControl"); - compare_or_set_int_value(CFGID_SPEAKER_ENABLED, 1, (const unsigned char *) "speakerEnabled"); - - if (apply_config == FALSE) { - config_get_mac_addr(macaddr); - - CONFIG_DEBUG(CFG_F_PREFIX ": MAC Address IS: %x:%x:%x:%x:%x:%x", - "config_get_mac_addr", macaddr[0], macaddr[1], - macaddr[2], macaddr[3], macaddr[4], macaddr[5]); - - CC_Config_setArrayValue(CFGID_MY_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - CC_Config_setArrayValue(CFGID_MY_ACTIVE_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - } -} - -/* - * config_setup_element - * Setup elements that once were downloaded from CUCM in an XML file. - * Settings are stored in config.h - */ -void config_setup_elements (const char *sipUser, const char *sipPassword, const char *sipDomain) -{ - unsigned int i; - char buf[MAX_SIP_URL_LENGTH] = {'\0'}; - char ip[MAX_SIP_URL_LENGTH] = {'\0'}; - char option[MAX_SIP_URL_LENGTH] = {'\0'}; - int line = 0; - cc_boolean isSecure = FALSE, isValid = TRUE; - char macaddr[MAC_ADDR_SIZE]; - - compare_or_set_int_value(CFGID_MEDIA_PORT_RANGE_START, gStartMediaPort, (const unsigned char *) "startMediaPort"); - compare_or_set_int_value(CFGID_MEDIA_PORT_RANGE_END, gStopMediaPort, (const unsigned char *) "stopMediaPort"); - compare_or_set_boolean_value(CFGID_CALLERID_BLOCKING, gCallerIdBlocking, (const unsigned char *) "callerIdBlocking"); - compare_or_set_boolean_value(CFGID_ANONYMOUS_CALL_BLOCK, gAnonblock, (const unsigned char *) "anonymousCallBlock"); - compare_or_set_string_value(CFGID_PREFERRED_CODEC, gPreferredCodec, (const unsigned char *) "preferredCodec"); - compare_or_set_string_value(CFGID_DTMF_OUTOFBAND, gDtmfOutOfBand, (const unsigned char *) "dtmfOutofBand"); - compare_or_set_int_value(CFGID_DTMF_AVT_PAYLOAD, gDtmfAvtPayload, (const unsigned char *) "dtmfAvtPayload"); - compare_or_set_int_value(CFGID_DTMF_DB_LEVEL, gDtmfDbLevel, (const unsigned char *) "dtmfDbLevel"); - compare_or_set_int_value(CFGID_SIP_RETX, gSipRetx, (const unsigned char *) "sipRetx"); - compare_or_set_int_value(CFGID_SIP_INVITE_RETX, gSipInviteRetx, (const unsigned char *) "sipInviteRetx"); - compare_or_set_int_value(CFGID_TIMER_T1, gTimerT1, (const unsigned char *) "timerT1"); - compare_or_set_int_value(CFGID_TIMER_T2, gTimerT2, (const unsigned char *) "timerT2"); - compare_or_set_int_value(CFGID_TIMER_INVITE_EXPIRES, gTimerInviteExpires, (const unsigned char *) "timerInviteExpires"); - compare_or_set_int_value(CFGID_TIMER_REGISTER_EXPIRES, gTimerRegisterExpires, (const unsigned char *) "timerRegisterExpires"); - compare_or_set_boolean_value(CFGID_PROXY_REGISTER, gRegisterWithProxy, (const unsigned char *) "registerWithProxy"); - compare_or_set_string_value(CFGID_PROXY_BACKUP, gBackupProxy, (const unsigned char *) "backupProxy"); - compare_or_set_int_value(CFGID_PROXY_BACKUP_PORT, gBackupProxyPort, (const unsigned char *) "backupProxyPort"); - compare_or_set_string_value(CFGID_PROXY_EMERGENCY, gEmergencyProxy, (const unsigned char *) "emergencyProxy"); - compare_or_set_int_value(CFGID_PROXY_EMERGENCY_PORT, gEmergencyProxyPort, (const unsigned char *) "emergencyProxyPort"); - compare_or_set_string_value(CFGID_OUTBOUND_PROXY, gOutboundProxy, (const unsigned char *) "outboundProxy"); - compare_or_set_int_value(CFGID_OUTBOUND_PROXY_PORT, gOutboundProxyPort, (const unsigned char *) "outboundProxyPort"); - compare_or_set_boolean_value(CFGID_NAT_RECEIVED_PROCESSING, gNatRecievedProcessing, (const unsigned char *) "natRecievedProcessing"); - compare_or_set_string_value(CFGID_REG_USER_INFO, gUserInfo, (const unsigned char *) "userInfo"); - compare_or_set_boolean_value(CFGID_REMOTE_PARTY_ID, gRemotePartyID, (const unsigned char *) "remotePartyID"); - compare_or_set_boolean_value (CFGID_SEMI_XFER, gSemiAttendedTransfer, (const unsigned char *) "semiAttendedTransfer"); - compare_or_set_int_value(CFGID_CALL_HOLD_RINGBACK, gCallHoldRingback, (const unsigned char *) "callHoldRingback"); - compare_or_set_boolean_value(CFGID_STUTTER_MSG_WAITING, gStutterMsgWaiting, (const unsigned char *) "stutterMsgWaiting"); - compare_or_set_string_value(CFGID_CALL_FORWARD_URI, gCallForwardURI, (const unsigned char *) "callForwardURI"); - compare_or_set_boolean_value(CFGID_CALL_STATS, gCallStats, (const unsigned char *) "callStats"); - compare_or_set_int_value(CFGID_TIMER_REGISTER_DELTA, gTimerRegisterDelta, (const unsigned char *) "timerRegisterDelta"); - compare_or_set_int_value(CFGID_SIP_MAX_FORWARDS, gMaxRedirects, (const unsigned char *) "maxRedirects"); - compare_or_set_boolean_value(CFGID_2543_HOLD, gRfc2543Hold, (const unsigned char *) "rfc2543Hold"); - compare_or_set_boolean_value(CFGID_LOCAL_CFWD_ENABLE, gLocalCfwdEnable, (const unsigned char *) "localCfwdEnable"); - compare_or_set_int_value(CFGID_CONN_MONITOR_DURATION, gConnectionMonitorDuration, (const unsigned char *) "connectionMonitorDuration"); - compare_or_set_int_value(CFGID_CALL_LOG_BLF_ENABLED, gCallLogBlfEnabled, (const unsigned char *) "callLogBlfEnabled"); - compare_or_set_boolean_value(CFGID_RETAIN_FORWARD_INFORMATION, gRetainForwardInformation, (const unsigned char *) "retainForwardInformation"); - compare_or_set_int_value(CFGID_REMOTE_CC_ENABLED, gRemoteCcEnable, (const unsigned char *) "remoteCcEnable"); - compare_or_set_int_value(CFGID_TIMER_KEEPALIVE_EXPIRES, gTimerKeepAliveExpires, (const unsigned char *) "timerKeepAliveExpires"); - compare_or_set_int_value(CFGID_TIMER_SUBSCRIBE_EXPIRES, gTimerSubscribeExpires, (const unsigned char *) "timerSubscribeExpires"); - compare_or_set_int_value(CFGID_TIMER_SUBSCRIBE_DELTA, gTimerSubscribeDelta, (const unsigned char *) "timerSubscribeDelta"); - compare_or_set_int_value(CFGID_TRANSPORT_LAYER_PROT, gTransportLayerProtocol, (const unsigned char *) "transportLayerProtocol"); - compare_or_set_int_value(CFGID_KPML_ENABLED, gKpml, (const unsigned char *) "kpml"); - compare_or_set_boolean_value(CFGID_NAT_ENABLE, gNatEnabled, (const unsigned char *) "natEnabled"); - compare_or_set_string_value(CFGID_NAT_ADDRESS, gNatAddress, (const unsigned char *) "natAddress"); - compare_or_set_int_value(CFGID_VOIP_CONTROL_PORT, gVoipControlPort, (const unsigned char *) "voipControlPort"); - compare_or_set_boolean_value(CFGID_ENABLE_VAD, gAnableVad, (const unsigned char *) "enableVad"); - compare_or_set_boolean_value(CFGID_AUTOANSWER_IDLE_ALTERNATE, gAutoAnswerAltBehavior, (const unsigned char *) "autoAnswerAltBehavior"); - compare_or_set_int_value(CFGID_AUTOANSWER_TIMER, gAutoAnswerTimer, (const unsigned char *) "autoAnswerTimer"); - compare_or_set_boolean_value(CFGID_AUTOANSWER_OVERRIDE, gAutoAnswerOverride, (const unsigned char *) "autoAnswerOverride"); - compare_or_set_int_value(CFGID_OFFHOOK_TO_FIRST_DIGIT_TIMER, gOffhookToFirstDigitTimer, (const unsigned char *) "offhookToFirstDigitTimer"); - compare_or_set_int_value(CFGID_CALL_WAITING_SILENT_PERIOD, gSilentPeriodBetweenCallWaitingBursts, (const unsigned char *) "silentPeriodBetweenCallWaitingBursts"); - compare_or_set_int_value(CFGID_RING_SETTING_BUSY_POLICY, gRingSettingBusyStationPolicy, (const unsigned char *) "ringSettingBusyStationPolicy"); - compare_or_set_int_value (CFGID_BLF_ALERT_TONE_IDLE, gBlfAudibleAlertSettingOfIdleStation, (const unsigned char *) "blfAudibleAlertSettingOfIdleStation"); - compare_or_set_int_value (CFGID_BLF_ALERT_TONE_BUSY, gBlfAudibleAlertSettingOfBusyStation, (const unsigned char *) "blfAudibleAlertSettingOfBusyStation"); - compare_or_set_int_value (CFGID_JOIN_ACROSS_LINES, gJoinAcrossLines, (const unsigned char *) "joinAcrossLines"); - compare_or_set_boolean_value(CFGID_CNF_JOIN_ENABLE, gCnfJoinEnabled, (const unsigned char *) "cnfJoinEnabled"); - compare_or_set_int_value (CFGID_ROLLOVER, gRollover, (const unsigned char *) "rollover"); - compare_or_set_boolean_value(CFGID_XFR_ONHOOK_ENABLED, gTransferOnhookEnabled, (const unsigned char *) "transferOnhookEnabled"); - compare_or_set_int_value(CFGID_DSCP_AUDIO, gDscpForAudio, (const unsigned char *) "dscpForAudio"); - compare_or_set_int_value(CFGID_DSCP_VIDEO, gDscpVideo, (const unsigned char *) "dscpVideo"); - compare_or_set_int_value(CFGID_INTER_DIGIT_TIMER, gT302Timer, (const unsigned char *) "T302Timer"); - - // TODO(emannion): You had line=1; line<= .... - // Debugging suggests that alghouth *line* is 1-indexed, the config entries - // are 1-indexed. See. config_get_line_id(). - // You may want to rewrite this in terms of config_get_line_id(). - // Please check -- EKR - for(line = 0; line < MAX_REG_LINES; line++) { - - compare_or_set_int_value(CFGID_LINE_INDEX + line, gLineIndex, (const unsigned char *)"lineIndex"); - compare_or_set_int_value(CFGID_LINE_FEATURE + line, gFeatureID, (const unsigned char *) "featureID"); - compare_or_set_string_value(CFGID_PROXY_ADDRESS + line, gProxy, (const unsigned char *) "proxy"); - compare_or_set_int_value(CFGID_PROXY_PORT + line, gPort, (const unsigned char *) "port"); - - if ( apply_config == FALSE ) { - ccsnap_set_line_label(line+1, "LINELABEL"); - } - - compare_or_set_string_value(CFGID_LINE_NAME + line, sipUser, (const unsigned char *) "name"); - compare_or_set_string_value(CFGID_LINE_DISPLAYNAME + line, gDisplayName, (const unsigned char *) "displayName"); - compare_or_set_string_value(CFGID_LINE_MESSAGES_NUMBER + line, gMessagesNumber, (const unsigned char *) "messagesNumber"); - compare_or_set_boolean_value(CFGID_LINE_FWD_CALLER_NAME_DIPLAY + line, gCallerName, (const unsigned char *) "callerName"); - compare_or_set_boolean_value(CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY + line, gCallerNumber, (const unsigned char *) "callerNumber"); - compare_or_set_boolean_value(CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY + line, gRedirectedNumber, (const unsigned char *) "redirectedNumber"); - compare_or_set_boolean_value(CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY + line, gDialedNumber, (const unsigned char *) "dialedNumber"); - compare_or_set_byte_value(CFGID_LINE_MSG_WAITING_LAMP + line, gMessageWaitingLampPolicy, (const unsigned char *) "messageWaitingLampPolicy"); - compare_or_set_byte_value(CFGID_LINE_MESSAGE_WAITING_AMWI + line, gMessageWaitingAMWI, (const unsigned char *) "messageWaitingAMWI"); - compare_or_set_byte_value(CFGID_LINE_RING_SETTING_IDLE + line, gRingSettingIdle, (const unsigned char *) "ringSettingIdle"); - compare_or_set_byte_value(CFGID_LINE_RING_SETTING_ACTIVE + line, gRingSettingActive, (const unsigned char *) "ringSettingActive"); - compare_or_set_string_value(CFGID_LINE_CONTACT + line, sipUser, (const unsigned char *) "contact"); - compare_or_set_byte_value(CFGID_LINE_AUTOANSWER_ENABLED + line, gAutoAnswerEnabled, (const unsigned char *) "autoAnswerEnabled"); - compare_or_set_byte_value(CFGID_LINE_CALL_WAITING + line, gCallWaiting, (const unsigned char *) "callWaiting"); - compare_or_set_string_value(CFGID_LINE_AUTHNAME + line, sipUser, (const unsigned char *)"authName"); - compare_or_set_string_value(CFGID_LINE_PASSWORD + line, sipPassword, (const unsigned char *)"authPassword"); - } - - compare_or_set_int_value(CFGID_CCM1_SEC_LEVEL, gDeviceSecurityMode,(const unsigned char *)"deviceSecurityMode"); - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, gCcm1_sip_port,(const unsigned char *)"ccm1_sip_port"); - compare_or_set_int_value(CFGID_CCM2_SIP_PORT, gCcm2_sip_port,(const unsigned char *)"ccm2_sip_port"); - compare_or_set_int_value(CFGID_CCM3_SIP_PORT, gCcm3_sip_port, (const unsigned char *)"ccm3_sip_port"); - - - isSecure = FALSE; - sstrncpy(ip, "", MAX_SIP_URL_LENGTH); - sstrncpy(option, "User Specific", MAX_SIP_URL_LENGTH); - - compare_or_set_string_value(CFGID_CCM1_ADDRESS+0, sipDomain, (const unsigned char *) "ccm1_addr"); - compare_or_set_boolean_value(CFGID_CCM1_IS_VALID + 0, gCcm1_isvalid, (const unsigned char *)"ccm1_isvalid"); - compare_or_set_int_value(CFGID_DSCP_FOR_CALL_CONTROL , gDscpCallControl, (const unsigned char *) "DscpCallControl"); - compare_or_set_int_value(CFGID_SPEAKER_ENABLED, gSpeakerEnabled, (const unsigned char *) "speakerEnabled"); - - if (apply_config == FALSE) { - config_get_mac_addr(macaddr); - - CONFIG_DEBUG(CFG_F_PREFIX ": MAC Address IS: %x:%x:%x:%x:%x:%x", - "config_get_mac_addr", macaddr[0], macaddr[1], - macaddr[2], macaddr[3], macaddr[4], macaddr[5]); - - CC_Config_setArrayValue(CFGID_MY_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - CC_Config_setArrayValue(CFGID_MY_ACTIVE_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - } - - CONFIG_DEBUG(CFG_F_PREFIX "%s", "config_parse_element", "phoneServices"); - CONFIG_DEBUG(CFG_F_PREFIX "%s", "config_parse_element", "versionStamp"); - CONFIG_ERROR(CFG_F_PREFIX "%s new=%s old=%s", "config_parser_element", "versionStamp", - "1284570837-bbc096ed-7392-427d-9694-5ce49d5c3acb", g_cfg_version_stamp); - - if (apply_config == FALSE) { - memset(g_cfg_version_stamp, 0, sizeof(g_cfg_version_stamp)); - i = strlen("1284570837-bbc096ed-7392-427d-9694-5ce49d5c3acb"); - if (i > MAX_CFG_VERSION_STAMP_LEN) { - CONFIG_ERROR(CFG_F_PREFIX "config version %d, bigger than allocated space %d", "config_parser_element", i, MAX_CFG_VERSION_STAMP_LEN); - } - - sstrncpy(g_cfg_version_stamp, "1284570837-bbc096ed-7392-427d-9694-5ce49d5c3acb", sizeof(g_cfg_version_stamp)); - } - else { - CONFIG_ERROR(CFG_F_PREFIX "got NULL value for %s", "config_parser_element", "versionStamp"); - } - - CONFIG_DEBUG(CFG_F_PREFIX "%s", "config_parser_element", "externalNumberMask"); - compare_or_set_string_value(CFGID_CCM_EXTERNAL_NUMBER_MASK, gExternalNumberMask, (const unsigned char *) "externalNumberMask"); - - /* Set SIP P2P boolean */ - compare_or_set_boolean_value(CFGID_P2PSIP, gP2PSIP, (const unsigned char *) "p2psip"); - - /* Set product version */ - compare_or_set_string_value(CFGID_VERSION, gVersion, (const unsigned char *) "version"); - - /* Set rtcp-mux, right now to always true */ - compare_or_set_boolean_value(CFGID_RTCPMUX, gRTCPMUX, (const unsigned char *) "rtcpmux"); - - /* Set RTP/SAVPF, right now to always true */ - compare_or_set_boolean_value(CFGID_RTPSAVPF, gRTPSAVPF, (const unsigned char *) "rtpsavpf"); - - compare_or_set_boolean_value(CFGID_MAXAVBITRATE, gMAXAVBITRATE, (const unsigned char *) "maxavbitrate"); - - compare_or_set_boolean_value(CFGID_MAXCODEDAUDIOBW, gMAXCODEDAUDIOBW, (const unsigned char *) "maxcodedaudiobw"); - - compare_or_set_boolean_value(CFGID_USEDTX, gUSEDTX, (const unsigned char *) "usedtx"); - - compare_or_set_boolean_value(CFGID_STEREO, gSTEREO, (const unsigned char *) "stereo"); - - compare_or_set_boolean_value(CFGID_USEINBANDFEC, gUSEINBANDFEC, (const unsigned char *) "useinbandfec"); - - compare_or_set_boolean_value(CFGID_CBR, gCBR, (const unsigned char *) "cbr"); - - compare_or_set_boolean_value(CFGID_MAXPTIME, gMAXPTIME, (const unsigned char *) "maxptime"); - - compare_or_set_int_value(CFGID_SCTP_PORT, gSCTPPort, (const unsigned char *) "sctp_port"); - - compare_or_set_int_value(CFGID_NUM_DATA_STREAMS, gNumDataStreams, (const unsigned char *) "num_data_streams"); - - (void) isSecure; // XXX set but not used - (void) isValid; // XXX set but not used -} - -void config_setup_server_address (const char *sipDomain) { - compare_or_set_string_value(CFGID_CCM1_ADDRESS+0, sipDomain, (const unsigned char *) "ccm1_addr"); -} - -void config_setup_transport_udp(const cc_boolean is_udp) { - gTransportLayerProtocol = is_udp ? 2 : 4; - compare_or_set_int_value(CFGID_TRANSPORT_LAYER_PROT, gTransportLayerProtocol, (const unsigned char *) "transportLayerProtocol"); -} - -void config_setup_local_voip_control_port(const int voipControlPort) { - gVoipControlPort = voipControlPort; - compare_or_set_int_value(CFGID_VOIP_CONTROL_PORT, voipControlPort, (const unsigned char *) "voipControlPort"); -} - -void config_setup_remote_voip_control_port(const int voipControlPort) { - gCcm1_sip_port = voipControlPort; - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, voipControlPort,(const unsigned char *)"ccm1_sip_port"); -} - -int config_get_local_voip_control_port() { - return gVoipControlPort; -} - -int config_get_remote_voip_control_port() { - return gCcm1_sip_port; -} - -const char* config_get_version() { - return gVersion; -} - -void config_setup_p2p_mode(const cc_boolean is_p2p) { - gP2PSIP = is_p2p; - compare_or_set_boolean_value(CFGID_P2PSIP, is_p2p, (const unsigned char *) "p2psip"); -} - -void config_setup_sdp_mode(const cc_boolean is_sdp) { - gSDPMODE = is_sdp; - compare_or_set_boolean_value(CFGID_SDPMODE, is_sdp, (const unsigned char *) "sdpsip"); -} - -void config_setup_avp_mode(const cc_boolean is_rtpsavpf) { - gRTPSAVPF = is_rtpsavpf; - compare_or_set_boolean_value(CFGID_RTPSAVPF, is_rtpsavpf, (const unsigned char *) "rtpsavpf"); -} - -/** - * Process/Parse the FCP file if specified in the master config file. -*/ -void config_parser_handle_fcp_file (char* fcpTemplateFile) -{ - - // if no fcp file specified in master config file, then set the default dialplan - if (strcmp (fcpTemplateFile, "") == 0) - { - CC_Config_setFcp(NULL, 0); - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CONFIG_CHANGED, CC_DEVICE_ID); - - return; - } - - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CONFIG_CHANGED, CC_DEVICE_ID); -} - - -/** - * Function called as part of registration without using cnf device file download. - */ -int config_setup_main( const char *sipUser, const char *sipPassword, const char *sipDomain) -{ - config_setup_elements(sipUser, sipPassword, sipDomain); - update_security_mode_and_ports(); - - // Take care of Fetch and apply of FCP and DialPlan if configured and necessary - if (apply_config == FALSE) { - config_parser_handle_fcp_file (fcpTemplateFile); - } - - return 0; -} diff --git a/media/webrtc/signaling/src/sipcc/core/common/config_parser.h b/media/webrtc/signaling/src/sipcc/core/common/config_parser.h deleted file mode 100644 index 35730eaaf8e..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/config_parser.h +++ /dev/null @@ -1,173 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CONFIG_PARSER_H_ -#define CONFIG_PARSER_H_ - -#include "cc_constants.h" -#include "cc_types.h" -#include "cc_config.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "debug.h" -#include "prot_configmgr.h" -#include "call_logger.h" -#include "sip_common_transport.h" -#include "sip_ccm_transport.h" - -#define MAX_CFG_VERSION_STAMP_LEN 80 - -/* - * This function determine whether the passed config parameter should be used - * in comparing the new and old config value for apply-config purpose. Only - * those config ids on whose change phone needs to restart are part of this - * function. For remaining parameters, it is assumed that any change can be - * applied dynamically. - * - */ -boolean is_cfgid_in_restart_list(int cfgid); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_byte_value(int cfgid, unsigned char value, const unsigned char * config_name); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_boolean_value(int cfgid, cc_boolean value, const unsigned char * config_name); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_int_value(int cfgid, int value, const unsigned char * config_name); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_string_value (int cfgid, const char* value, const unsigned char * config_name); - -/* - * config_fetch_dialplan() called to retrieve the dialplan - * - */ -void config_fetch_dialplan(char *filename); - -/* - * config_fetch_fcp() called to retrieve the fcp - * - */ -void config_fetch_fcp(char *filename); - -/* - * config_set_autoreg_properties - * - */ -void config_set_autoreg_properties (); - -/* - * update_security_mode_and_ports - * - */ -void update_security_mode_and_ports(void); - -/* - * config_get_mac_addr - * - * Get the filename that has the mac address and parse the string - * convert it into an mac address stored in the bytearray maddr -*/ -void config_get_mac_addr (char *maddr); - -/* - * Set the IP and MAC address in the config table - */ -void config_set_ccm_ip_mac (); - - -/* - * Set up configuration without XML config file. - */ -void config_setup_elements ( const char *sipUser, const char *sipPassword, const char *sipDomain); - -/* - * Set server ip address into config - * Same ip address is also used to make a P2P call - */ -void config_setup_server_address (const char *sipDomain); - -/* - * set transport protocol, limited to udp or tcp for now - */ -void config_setup_transport_udp(const cc_boolean is_udp); - -/* - * set local voip port defaults to 5060 - */ -void config_setup_local_voip_control_port(const int voipControlPort); - -/* - * set remote voip port defaults to 5060 - */ -void config_setup_remote_voip_control_port(const int voipControlPort); - -/* - * get local voip port defaults to 5060 - */ -int config_get_local_voip_control_port(); - -/* - * get remote voip port defaults to 5060 - */ -int config_get_remote_voip_control_port(); - -/* - * get ikran version - */ -const char* config_get_version(); - -/* - * set p2p mode on or off - */ -void config_setup_p2p_mode(const cc_boolean is_p2p); - -/* - * set sdp mode on or off - */ -void config_setup_sdp_mode(const cc_boolean is_sdp); - -/* - * set avp mode (true == RTP/SAVPF, false = RTP/SAVP) - */ -void config_setup_avp_mode(const cc_boolean is_rtpsavpf); - -/** -* config_minimum_check: -* -* @a_node: the initial xml node to consider. -* @doc: The DOM tree of the xml file -* -* Check if minimum set of elements are present in the config file and -* have values that can be used by sipstack -* -*/ - -/** - * Parse the file that is passed in, - * walk down the DOM that is created , and get the - * xml elements nodes. - */ -int config_parser_main( char *config, int complete_config); - -/* - * Set up configuration without XML config file. - */ -int config_setup_main( const char *sipUser, const char *sipPassword, const char *sipDomain); - - -#endif /* CONFIG_PARSER_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/common/init.c b/media/webrtc/signaling/src/sipcc/core/common/init.c deleted file mode 100755 index a1e1c080a55..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/init.c +++ /dev/null @@ -1,461 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr.h" -#include "cpr_in.h" -#include "cpr_stdlib.h" -#include "cpr_ipc.h" -#include "phntask.h" -#include -#include "configmgr.h" -#include "debug.h" -#include "config.h" -#include "vcm.h" -#include "dialplan.h" -#include "debug.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "ccsip_task.h" -#include "gsm.h" -#include "misc_apps_task.h" -#include "plat_api.h" -#include "ccapp_task.h" -#include "uiapi.h" -#include "mozilla/Assertions.h" - -#include "phone_platform_constants.h" -/** The following defines are used to tune the total memory that pSIPCC - * allocates and uses. */ -/** Block size for emulated heap space, i.e. 1kB */ -#define BLK_SZ 1024 - -/** 5 MB Heap Based on 0.5 MB initial use + 4 MB for calls (20K * 200) + 0.5 MB misc */ -/** The number of supported blocks for the emulated heap space */ -#define MEM_BASE_BLK 500 //500 blocks, ~ 0.5M -#define MEM_MISC_BLK 500 //500 blocks, ~ 0.5M -/** Size of the emulated heap space. This is the value passed to the memory - * management pre-init procedure. The total memory allocated is - * "PRIVATE_SYS_MEM_SIZE + 2*64" where the additional numbers are for a gaurd - * band. */ -#define MEM_PER_CALL_BLK 20 //20 block, ~20k -#define PRIVATE_SYS_MEM_SIZE ((MEM_BASE_BLK + MEM_MISC_BLK + (MEM_PER_CALL_BLK) * MAX_CALLS) * BLK_SZ) - -// used in early init code where config has not been setup -const boolean gHardCodeSDPMode = TRUE; -boolean gStopTickTask = FALSE; - - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ -#define GSMSTKSZ 61440 - -/* - * CNU thread queue sizes. - * - * On CNU, the message queue size can hold up to 31 entries only. - * This is too small for a phone that can support the MAX_CALLS that - * is close to or higher than 31 calls simultaneously. In a scenario when - * the number of active calls on the phone reaches its MAC_CALLS then - * there can be a potential MAX_CALLS that is great ther than 31 events on - * a queue to GSM or SIP thread. - * - * One known scenario is a 7970 phone having 50 held calls where all - * calls are not from the same CCM that this phone registers with but - * still within the same cluster. If that CCM is restarted, the CCM that - * this phone registers with will terminate these calls on the phone by - * sending BYEs, SUBSCRIBE (to terminate) DTMF digi collection and etc. to - * all these calls very quickly together. Handling these SIP messages - * can generate many internal events between SIP and GSM threads including - * events that are sent to self (such as GSM which includes applications - * that runs as part of GSM). The amount of the events posted on the queues - * during this time can be far exceeding than 31 and MAX_CALLS entries. - * - * The followings define queue sizes for GSM, SIP and the other threads. - * The GSM's queue size is defined to be larger than SIP's queue size to - * account for self sending event. The formular below is based on the - * testing with the above scenario and with 8-3-x phone load. The maximum - * queue depth observed for GSM under - * this condition is 129 entries and the maximum queue depth of - * SIP under the same condition is about 67 entries. Therefore, the queue - * depth of GSM thread is given to 3 times MAX_CALLS (or 153) and - * 2 times (or 102) for SIP thread for 7970 case. - * - */ -#define GSMQSZ (MAX_CALLS*3) /* GSM message queue size */ -#define SIPQSZ (MAX_CALLS*2) /* SIP message queue size */ -#define DEFQSZ 0 /* default message queue size */ -#define DEFAPPQSZ MAX_REG_LINES - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ - -cprMsgQueue_t ccapp_msgq = NULL; -cprThread_t ccapp_thread = NULL; - -cprMsgQueue_t sip_msgq = NULL; -cprThread_t sip_thread = NULL; -#ifdef NO_SOCKET_POLLING -cprThread_t sip_msgqwait_thread = NULL; -#endif - -cprMsgQueue_t gsm_msgq = NULL; -cprThread_t gsm_thread = NULL; - -cprMsgQueue_t misc_app_msgq = NULL; -cprThread_t misc_app_thread = NULL; - -#ifdef JINDO_DEBUG_SUPPORTED -cprMsgQueue_t debug_msgq = NULL; -cprThread_t debug_thread = NULL; -#endif - -#ifdef EXTERNAL_TICK_REQUIRED -cprMsgQueue_t ticker_msgq = NULL; -cprThread_t ticker_thread = NULL; -#endif - -/* Platform initialized flag */ -boolean platform_initialized = FALSE; - -static int thread_init(void); - -/*-------------------------------------------------------------------------- - * External data references - * ------------------------------------------------------------------------- - */ - - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ -extern void gsm_set_initialized(void); -extern void vcm_init(void); -extern void dp_init(void *); -extern cprBuffer_t SIPTaskGetBuffer(uint16_t size); - -extern void sip_platform_task_loop(void *arg); -#ifdef NO_SOCKET_POLLING -extern void sip_platform_task_msgqwait(void *arg); -#endif -extern void GSMTask(void *); -#ifndef VENDOR_BUILD -extern void debug_task(void *); -#endif -extern void MiscAppTask(void *); -extern void cpr_timer_tick(void); - -extern void cprTimerSystemInit(void); -extern int32_t ui_clear_mwi(int32_t argc, const char *argv[]); -void gsm_shutdown(void); -void dp_shutdown(void); -void MiscAppTaskShutdown(void); -void CCAppShutdown(void); -cprBuffer_t gsm_get_buffer (uint16_t size); - - - - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ -#ifdef EXTERNAL_TICK_REQUIRED -int TickerTask(void *); -#endif - -void send_protocol_config_msg(void); - -/** - * ccMemInit() - */ -extern -int ccMemInit(size_t size) { - return CPR_SUCCESS; -} - -/** - * ccPreInit - * - * Initialization routine to call before any application level - * code initializes. - * - * Parameters: None - * - * Return Value: CPR_SUCCESS or CPR_FAILURE - */ - -int -ccPreInit () -{ - static boolean ccPreInit_called = FALSE; - - if (ccPreInit_called == FALSE) { - ccPreInit_called = TRUE; - //Initializes the memory first - ccMemInit(PRIVATE_SYS_MEM_SIZE); - cprPreInit(); - } - - return CPR_SUCCESS; -} - -int -ccInit () -{ - - TNP_DEBUG(DEB_F_PREFIX"started init of SIP call control", DEB_F_PREFIX_ARGS(SIP_CC_INIT, "ccInit")); - - platInit(); - - strlib_init(); - - /* Initialize threads, queues etc. */ - (void) thread_init(); - - platform_initialized = TRUE; - - return 0; -} - -static int -thread_init () -{ - gStopTickTask = FALSE; - /* - * This will have already been called for CPR CNU code, - * but may be called here for Windows emulation. - */ - (void) cprPreInit(); - - - PHNChangeState(STATE_FILE_CFG); - - /* - * Initialize the command parser and debug infrastructure - */ - debugInit(); - - CCApp_prepare_task(); - GSM_prepare_task(); - - config_init(); - vcmInit(); - - if (sip_minimum_config_check() != 0) { - PHNChangeState(STATE_UNPROVISIONED); - } else { - PHNChangeState(STATE_CONNECTED); - } - - (void) cprPostInit(); - - if ( vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX) ) { - cc_media_update_native_video_support(TRUE); - } - - return (0); -} - - -#ifdef EXTERNAL_TICK_REQUIRED - -uint16_t SecTimer = 50; - -unsigned long timeofday_in_seconds = 0; - -void -MAIN0Timer (void) -{ - if (SecTimer-- == 0) { - SecTimer = 50; - timeofday_in_seconds++; - } - //gtick +=2; - cpr_timer_tick(); -} - -int -TickerTask (void *a) -{ - TNP_DEBUG(DEB_F_PREFIX"Ticker Task initialized..", DEB_F_PREFIX_ARGS(SIP_CC_INIT, "TickerTask")); - while (FALSE == gStopTickTask) { - cprSleep(20); - MAIN0Timer(); - } - return 0; -} -#endif - -void -send_protocol_config_msg (void) -{ - const char *fname = "send_protocol_config_msg"; - gsm_set_initialized(); - PHNChangeState(STATE_CONNECTED); - ui_set_sip_registration_state(CC_ALL_LINES, TRUE); -} - - - - - -/* - * Function: send_task_unload_msg - * - * Description: - * - send shutdown and thread destroy msg to sip, gsm, ccapp, misc - * threads - * Parameters: destination thread - * - * Returns: none - * - */ -void -send_task_unload_msg(cc_srcs_t dest_id) -{ - const char *fname = "send_task_unload_msg"; - uint16_t len = 4; - cprBuffer_t msg; - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - DEF_DEBUG(DEB_F_PREFIX"send Unload message to %s task ..", - DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname), - dest_id == CC_SRC_SIP ? "SIP" : - dest_id == CC_SRC_GSM ? "GSM" : - dest_id == CC_SRC_MISC_APP ? "Misc App" : - dest_id == CC_SRC_CCAPP ? "CCApp" : "Unknown"); - - switch(dest_id) { - case CC_SRC_SIP: - { - /* send this msg so phone can send unRegister msg */ - SIPTaskPostShutdown(SIP_EXTERNAL, CC_CAUSE_SHUTDOWN, ""); - /* allow unRegister msg to sent out and shutdown to complete */ - - if (!sdpmode) { - cprSleep(2000); - } - /* send a unload message to the SIP Task to kill sip thread*/ - msg = SIPTaskGetBuffer(len); - if (msg == NULL) { - CSFLogError("common", - "%s: failed to allocate sip msg buffer\n", fname); - return; - } - - if (SIPTaskSendMsg(THREAD_UNLOAD, (cprBuffer_t)msg, len, NULL) == CPR_FAILURE) - { - cpr_free(msg); - CSFLogError("common", - "%s: Unable to send THREAD_UNLOAD msg to sip thread", fname); - } - } - break; - case CC_SRC_GSM: - { - msg = gsm_get_buffer(len); - if (msg == NULL) { - CSFLogError("common", - "%s: failed to allocate gsm msg cprBuffer_t\n", fname); - return; - } - if (CPR_FAILURE == gsm_send_msg(THREAD_UNLOAD, msg, len)) { - CSFLogError("common", - "%s: Unable to send THREAD_UNLOAD msg to gsm thread", fname); - } - } - break; - case CC_SRC_MISC_APP: - { - msg = cpr_malloc(len); - if (msg == NULL) { - CSFLogError("common", - "%s: failed to allocate misc msg cprBuffer_t\n", fname); - return; - } - if (CPR_FAILURE == MiscAppTaskSendMsg(THREAD_UNLOAD, msg, len)) { - CSFLogError("common", - "%s: Unable to send THREAD_UNLOAD msg to Misc App thread", - fname); - } - } - break; - case CC_SRC_CCAPP: - { - msg = cpr_malloc(len); - if (msg == NULL) { - CSFLogError("common", - "%s: failed to allocate ccapp msg cprBuffer_t\n", fname); - return; - } - if (ccappTaskPostMsg(CCAPP_THREAD_UNLOAD, msg, len, CCAPP_CCPROVIER) == CPR_FAILURE ) - { - CSFLogError("common", - "%s: Unable to send THREAD_UNLOAD msg to CCapp thread", - fname); - } - CSFLogError("common", "%s: send UNLOAD msg to CCapp thread good", - fname); - /* Unlike other similar functions, ccappTaskPostMsg does not take - * ownership. */ - cpr_free(msg); - msg = NULL; - } - break; - - default: - CSFLogError("common", "%s: Unknown destination task passed=%d.", - fname, dest_id); - break; - } -} - -/* - * Function: ccUnload - * - * Description: - * - deinit portable runtime. - * - Cleanup call control modules, GSM and SIp Stack - * - * Parameters: none - * - * Returns: none - * - */ -void -ccUnload (void) -{ - static const char fname[] = "ccUnload"; - - DEF_DEBUG(DEB_F_PREFIX"ccUnload called..", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - if (platform_initialized == FALSE) - { - TNP_DEBUG(DEB_F_PREFIX"system is not loaded, ignore unload", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - return; - } - /* - * We are going to send an unload msg to each of the thread, which on - * receiving the msg, will notify us back with async dispatch before - * killing itself. Main thread is assumed here. We have to do this to - * avoid deadlock because the threads use SyncRunnable to main. - */ - send_task_unload_msg(CC_SRC_SIP); - send_task_unload_msg(CC_SRC_GSM); - - if (!gHardCodeSDPMode) { - send_task_unload_msg(CC_SRC_MISC_APP); - } - - send_task_unload_msg(CC_SRC_CCAPP); - - gStopTickTask = TRUE; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/common/logger.c b/media/webrtc/signaling/src/sipcc/core/common/logger.c deleted file mode 100755 index 5c111f6ae95..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/logger.c +++ /dev/null @@ -1,87 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_string.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "stdarg.h" -#include "logger.h" -#include "logmsg.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "uiapi.h" -#include "platform_api.h" -#include "prot_configmgr.h" - -#define MAX_LOG_CACHE_ENTRIES 20 - -/* - * Log a message. - * Cause the message to be printed to the console port - * as well, the log is stored in a local data area for - * later viewing - */ -void -log_msg (int phrase_index, ...) -{ - char phrase_buf[LOG_MAX_LEN * 4]; - char status_msg[LOG_MAX_LEN * 4]; - va_list ap; - - /* - * Make sure that the phrase index is valid. - */ - if (phrase_index == 0) { - return; - } - - /* - * Get the translated phrase index from the Java code. - */ - if (platGetPhraseText(phrase_index, phrase_buf, (LOG_MAX_LEN * 4)) == CPR_FAILURE) { - return; - } - - /* - * If extra data is required, sprintf this into the status message buffer - */ - va_start(ap, phrase_index); - vsprintf(status_msg, phrase_buf, ap); - va_end(ap); - - CSFLogError("common", "%%%s", status_msg); - - /* - * For now, do not send the Registration messages over to the Java Status - * Logs. They come out too fast and will overwhelm the existing logging - * mechanism. We will need to implement a new mechanism in order to put - * these in the phone's status menu. - */ - switch (phrase_index) { - case LOG_REG_MSG: - case LOG_REG_RED_MSG: - case LOG_REG_AUTH_MSG: - case LOG_REG_AUTH_HDR_MSG: - case LOG_REG_AUTH_SCH_MSG: - case LOG_REG_CANCEL_MSG: - case LOG_REG_AUTH: - case LOG_REG_AUTH_ACK_TMR: - case LOG_REG_AUTH_NO_CRED: - case LOG_REG_AUTH_UNREG_TMR: - case LOG_REG_RETRY: - case LOG_REG_UNSUPPORTED: - case LOG_REG_AUTH_SERVER_ERR: - case LOG_REG_AUTH_GLOBAL_ERR: - case LOG_REG_AUTH_UNKN_ERR: - return; - - default: - break; - } - - ui_log_status_msg(status_msg); -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/common/logger.h b/media/webrtc/signaling/src/sipcc/core/common/logger.h deleted file mode 100644 index 3a1465b1a19..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/logger.h +++ /dev/null @@ -1,17 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LOGGER_INCLUDED_H -#define _LOGGER_INCLUDED_H - -#define LOG_MAX_LEN 64 - -/* - * short form helper macros - */ -void log_msg(int log, ...); -void log_clear(int msg); -char *get_device_name(); - -#endif /* _LOGGER_INCLUDED_H */ diff --git a/media/webrtc/signaling/src/sipcc/core/common/logmsg.h b/media/webrtc/signaling/src/sipcc/core/common/logmsg.h deleted file mode 100644 index 29ee709b218..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/logmsg.h +++ /dev/null @@ -1,42 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LOGMSG_INCLUDED_H -#define _LOGMSG_INCLUDED_H - -#include "logger.h" - -/* - * Config messages - * The number denotes the string location in the Phone dictionary file - */ -#define LOG_CFG_PARSE_DIAL 1074 //"%d Error(s) Parsing: %s" - -/* - * SIP messages - * The number denotes the string location in the Phone dictionary file - */ -#define LOG_REG_MSG 1058 //"REG send failure: REGISTER" -#define LOG_REG_RED_MSG 1059 //"REG send failure: REGISTER Redirected" -#define LOG_REG_AUTH_MSG 1060 //"REG send failure: REGISTER auth" -#define LOG_REG_AUTH_HDR_MSG 1061 //"REG send failure: REGISTER auth hdr" -#define LOG_REG_AUTH_SCH_MSG 1062 //"REG send failure: REGISTER auth scheme" -#define LOG_REG_CANCEL_MSG 1063 //"REG send failure: CANCEL REGISTER" - -#define LOG_REG_AUTH 1064 //"REG auth failed: %s" -#define LOG_REG_AUTH_ACK_TMR 1065 //"REG auth failed: ack timer" -#define LOG_REG_AUTH_NO_CRED 1066 //"REG auth failed: no more credentials" -#define LOG_REG_AUTH_UNREG_TMR 1067 //"REG auth failed: unreg ack timer" -#define LOG_REG_RETRY 1068 //"REG retries exceeded" -#define LOG_REG_UNSUPPORTED 1069 //"REG msg unsupported: %s" - -#define LOG_REG_AUTH_SERVER_ERR 1070 //"REG auth failed: in %d, server error" -#define LOG_REG_AUTH_GLOBAL_ERR 1071 //"REG auth failed: in %d, global error" -#define LOG_REG_AUTH_UNKN_ERR 1072 //"REG auth failed: in %d, ??? error" - -#define LOG_REG_BACKUP 1073 //"REG Not Registered to Backup Proxy" - -#define LOG_REG_EXPIRE 1076 //"REG Expires time too small" - -#endif /* _LOGMSG_INCLUDED_H */ diff --git a/media/webrtc/signaling/src/sipcc/core/common/misc.c b/media/webrtc/signaling/src/sipcc/core/common/misc.c deleted file mode 100644 index 33f59fca9d2..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/misc.c +++ /dev/null @@ -1,389 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include -#include -#include - -#include "cpr.h" -#include "phone_debug.h" -#include "cc_debug.h" -#include "phone.h" -#include "cpr_socket.h" -#include "prot_configmgr.h" -#include "debug.h" -#include "cpr_string.h" -#include "cpr_stdlib.h" - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ - -/* NTP related local data */ -#define MAX_NTP_MONTH_STR_LEN 4 -#define MAX_NTP_MONTH_ARRAY_SIZE 12 -#define MAX_NTP_DATE_HDR_STR_LEN 128 -#define MAX_NTP_TOKEN_BUF_LEN 16 - -/* The number of arguments (argc) used in the show command */ -#define NUM_OF_SHOW_ARGUMENTS 2 - -static int last_month = 99; -static char last_month_str[MAX_NTP_MONTH_STR_LEN] = ""; -static const char *month_ar[MAX_NTP_MONTH_ARRAY_SIZE] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ - -extern void platform_set_time(int32_t gmt_time); -void SipNtpUpdateClockFromCCM(void); - - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ - - -/* - * This function finds month (0 to 11) from month name - * listed above in month_ar[]. This is used to convert the - * date header from CCM to derive time/date. - */ -static boolean -set_month_from_str (char *month_str) -{ - boolean ret_val = FALSE; - const char * fname = "set_month_from_str"; - int i; - - if (month_str) { - if (strncmp(month_str, last_month_str, 3) != 0) { - for (i = 0; i < 12; i++) { - if (strncmp(month_str, month_ar[i], 3) == 0) { - sstrncpy(last_month_str, month_str, sizeof(last_month_str)); - last_month = i; - ret_val = TRUE; - break; - } - } - } else { - ret_val = TRUE; - } - } else { - TNP_DEBUG(DEB_F_PREFIX "Input month_str is NULL!!!!", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } - return (ret_val); -} - - - -/* - * MISC platform stubs - * These stubs are mostly NOPs for TNP but they are referred from common code - * and this avoids ifdefs in the code. - * - */ -static uint16_t PHNState = STATE_CONNECTED; - -/* ccsip_core.o */ -uint16_t -PHNGetState (void) -{ - return (PHNState); -} - -void -PHNChangeState (uint16_t state) -{ - PHNState = state; -} - -/* ccsip_platform.o */ -void -phone_reset (DeviceResetType resetType) -{ - return; -} - - -/* - * Methods below should be moved to plat as they are exported as an external API. - * For now keeping all miscellaneous methods here. - */ -extern void config_get_value (int id, void *buffer, int length); - -/*logger.c */ - -/* - * Clear an entry or multiple entries in the - * log table. The passed in log message is used - * for partial matching, in order to figure out - * what logs need to be cleared. - * - * The TNP Status Message screen does not have any - * facility to "clear" log messages. - */ -void -log_clear (int msg) -{ -} - - -/** - * - * Indicates if the (preferred) network interface has changed (e.g., dock/undock) - * - * @param none - * - * - * @return true if the (preferred) network interface has changed since last query - * @return false if the (preferred) network interface has not changed - */ -boolean plat_is_network_interface_changed (void) -{ - return(FALSE); -} - - -/** - * give the platform IPV6 IP address. - * - * @param[in/out] ip_addr - pointer to the cpr_ip_addr_t. The - * result IP address will be populated in this - * structure. - * - * @return None. - */ -void -platform_get_ipv6_address (cpr_ip_addr_t *ip_addr) -{ - //config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - //Todo IPv6: Hack to get the IPV6 address - //if (ip_mode == CPR_IP_MODE_IPV6 || ip_mode == CPR_IP_MODE_DUAL) { - //} - ip_addr->type = CPR_IP_ADDR_IPV6; - ip_addr->u.ip6.addr.base8[15] = 0x65; - ip_addr->u.ip6.addr.base8[14] = 0xfb; - ip_addr->u.ip6.addr.base8[13] = 0xb1; - ip_addr->u.ip6.addr.base8[12] = 0xfe; - ip_addr->u.ip6.addr.base8[11] = 0xff; - ip_addr->u.ip6.addr.base8[10] = 0x11; - ip_addr->u.ip6.addr.base8[9] = 0x11; - ip_addr->u.ip6.addr.base8[8] = 0x02; - ip_addr->u.ip6.addr.base8[7] = 0x01; - ip_addr->u.ip6.addr.base8[6] = 0x00; - ip_addr->u.ip6.addr.base8[5] = 0x18; - ip_addr->u.ip6.addr.base8[4] = 0x0c; - ip_addr->u.ip6.addr.base8[3] = 0xb8; - ip_addr->u.ip6.addr.base8[2] = 0x0d; - ip_addr->u.ip6.addr.base8[1] = 0x01; - ip_addr->u.ip6.addr.base8[0] = 0x20; - - return; -} - -/** - * give the mac address string - * - * @param addr - mac address string (OUTPUT) - * - * @return none - */ -void -platform_get_wired_mac_address (unsigned char *addr) -{ - config_get_value(CFGID_MY_MAC_ADDR, addr, 6); - TNP_DEBUG(DEB_F_PREFIX"Wired MacAddr:from Get Val: %04x:%04x:%04x", - DEB_F_PREFIX_ARGS(PLAT_API, "platform_get_wired_mac_address"), - addr[0] * 256 + addr[1], addr[2] * 256 + addr[3], - addr[4] * 256 + addr[5]); -} - -/** - * Get active mac address if required - * - * @param addr - mac address string (OUTPUT) - * - * @return none - */ -void -platform_get_active_mac_address (unsigned char *addr) -{ - config_get_value(CFGID_MY_ACTIVE_MAC_ADDR, addr, 6); - TNP_DEBUG(DEB_F_PREFIX"ActiveMacAddr:from Get Val: %04x:%04x:%04x", - DEB_F_PREFIX_ARGS(PLAT_API, "platform_get_mac_address"), - addr[0] * 256 + addr[1], addr[2] * 256 + addr[3], - addr[4] * 256 + addr[5]); -} - -/** - * give the platform IPV4 IP address. - * - * @param[in/out] ip_addr - pointer to the cpr_ip_addr_t. The - * result IP address will be populated in this - * structure. - * - * @return None. - */ -void -platform_get_ipv4_address (cpr_ip_addr_t *ip_addr) -{ - config_get_value(CFGID_MY_IP_ADDR, ip_addr, sizeof(cpr_ip_addr_t)); - ip_addr->type = CPR_IP_ADDR_IPV4; - - return; -} - -uint32_t -IPNameCk (char *name, char *addr_error) -{ - char *namePtr = name; - char string[4] = { 0, 0, 0, 0 }; - int x = 0; - int i = 0; - uint32_t temp, ip_addr = 0; - char ip_addr_out[MAX_IPADDR_STR_LEN]; - unsigned long strtoul_result; - char *strtoul_end; - - /* Check if valid IPv6 address */ - if (cpr_inet_pton(AF_INET6, name, ip_addr_out)) { - *addr_error = FALSE; - return TRUE; - } - *addr_error = TRUE; - while (*namePtr != 0) { - if ((*namePtr >= 0x30) && (*namePtr <= 0x39)) { - if (x > 2) - return (0); - string[x++] = *namePtr++; - } else { - if (*namePtr == 0x2e) { - if (i > 3) - return (0); - namePtr++; - x = 0; - - errno = 0; - strtoul_result = strtoul(string, &strtoul_end, 10); - - if (errno || string == strtoul_end || strtoul_result > 255) { - return 0; - } - - temp = (uint32_t) strtoul_result; - - ip_addr |= temp << (24 - (i * 8)); - string[0] = 0; - string[1] = 0; - string[2] = 0; - i++; - } else - return (0); // not an IP address - } - } - - if (i == 3) { - errno = 0; - strtoul_result = strtoul(string, &strtoul_end, 10); - - if (errno || string == strtoul_end || strtoul_result > 255) { - return 0; - } - - temp = (uint32_t) strtoul_result; - - ip_addr |= temp; - *addr_error = FALSE; - return (ntohl(ip_addr)); - } else { - return 0; - } -} - -/** - * @brief Given a msg buffer, returns a pointer to the buffer's header - * - * The cprGetSysHeader function retrieves the system header buffer for the - * passed in message buffer. - * - * @param[in] buffer pointer to the buffer whose sysHdr to return - * - * @return Abstract pointer to the msg buffer's system header - * or #NULL if failure - */ -void * -cprGetSysHeader (void *buffer) -{ - phn_syshdr_t *syshdr; - - /* - * Stinks that an external structure is necessary, - * but this is a side-effect of porting from IRX. - */ - syshdr = cpr_calloc(1, sizeof(phn_syshdr_t)); - if (syshdr) { - syshdr->Data = buffer; - } - return (void *)syshdr; -} - -/** - * @brief Called when the application is done with this system header - * - * The cprReleaseSysHeader function returns the system header buffer to the - * system. - * @param[in] syshdr pointer to the sysHdr to be released - * - * @return none - */ -void -cprReleaseSysHeader (void *syshdr) -{ - if (syshdr == NULL) { - CPR_ERROR("cprReleaseSysHeader: Sys header pointer is NULL"); - return; - } - - cpr_free(syshdr); -} - -/** - * @brief An internal function to update the system header - * - * A CPR-only function. Given a sysHeader and data, this function fills - * in the data. The purpose for this function is to help prevent CPR - * code from having to know about the phn_syshdr_t layout. - * - * @param[in] buffer pointer to a syshdr from a successful call to - * cprGetSysHeader - * @param[in] cmd command to place in the syshdr buffer - * @param[in] len length to place in the syshdr buffer - * @param[in] timerMsg msg being sent to the calling thread - * - * @return none - * - * @pre (buffer != NULL) - */ -void -fillInSysHeader (void *buffer, uint16_t cmd, uint16_t len, void *timerMsg) -{ - phn_syshdr_t *syshdr; - - syshdr = (phn_syshdr_t *) buffer; - syshdr->Cmd = cmd; - syshdr->Len = len; - syshdr->Usr.UsrPtr = timerMsg; - return; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/common/plat.c b/media/webrtc/signaling/src/sipcc/core/common/plat.c deleted file mode 100644 index 215109b3a7a..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/plat.c +++ /dev/null @@ -1,89 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "cpr.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "ccsip_pmh.h" -#include "sessionTypes.h" -#include "ccapp_task.h" - -// Why don't we modify strlib_malloc to handle NULL? -#define STRLIB_CREATE(str) (str)?strlib_malloc((str), strlen((str))):strlib_empty() - -void -platform_apply_config (char * configVersionStamp, - char * dialplanVersionStamp, - char * fcpVersionStamp, - char * cucmResult, - char * loadId, - char * inactiveLoadId, - char * loadServer, - char * logServer, - boolean ppid); -/** - * This function calls the JNI function to sends the information received - * in apply-config NOTIFY message to Java side. - * - * @param configVersionStamp - version stamp for config file - * @param dialplanVersionStamp - version stamp for the dialplan file - * @param fcpVersionStamp - version stamp for the softkey file (?) - * @param cucmResult - CUCM result after applying config by CUCM - * @param loadId - loadId to upgrade as requested by CUCM - * @param inactiveLoadId - inactive loadId for inactive partition as requested by CUCM - * @param loadServer - load server form where to pick loadId - * @param logServer - log server for logging output of peer to peer upgrade. - * @param ppid - specify whether peer to peer upgrade is enabled/disabled. - * - * @return none - */ -void -platform_apply_config (char * configVersionStamp, - char * dialplanVersionStamp, - char * fcpVersionStamp, - char * cucmResult, - char * loadId, - char * inactiveLoadId, - char * loadServer, - char * logServer, - boolean ppid) -{ - static const char fname[] = "platform_apply_config"; - session_mgmt_t msg; - - fcpVersionStamp = (fcpVersionStamp != NULL) ? fcpVersionStamp : ""; - - /// Print the arguments - CCAPP_DEBUG(DEB_F_PREFIX" configVersionStamp=%s \ndialplanVersionStamp=%s" - "\nfcpVersionStamp=%s \ncucmResult=%s " - "\nloadId=%s \ninactiveLoadId=%s \nloadServer=%s \nlogServer=%s " - "\nppid=%s\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), - (configVersionStamp != NULL) ? configVersionStamp : "", - (dialplanVersionStamp != NULL) ? dialplanVersionStamp:"", - fcpVersionStamp, - cucmResult != NULL ? cucmResult: "", - (loadId != NULL) ? loadId : "", - (inactiveLoadId != NULL) ? inactiveLoadId : "", - (loadServer != NULL) ? loadServer : "", - (logServer != NULL) ? logServer : "", - ppid == TRUE? "True": "False"); - - - // following data is freed in function freeSessionMgmtData() - msg.func_id = SESSION_MGMT_APPLY_CONFIG; - msg.data.config.config_version_stamp = STRLIB_CREATE(configVersionStamp); - msg.data.config.dialplan_version_stamp = STRLIB_CREATE(dialplanVersionStamp); - msg.data.config.fcp_version_stamp = STRLIB_CREATE(fcpVersionStamp); - msg.data.config.cucm_result = STRLIB_CREATE(cucmResult); - msg.data.config.load_id = STRLIB_CREATE(loadId); - msg.data.config.inactive_load_id = STRLIB_CREATE(inactiveLoadId); - msg.data.config.load_server = STRLIB_CREATE(loadServer); - msg.data.config.log_server = STRLIB_CREATE(logServer); - msg.data.config.ppid = ppid; - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_apply_config msg", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/common/platform_api.c b/media/webrtc/signaling/src/sipcc/core/common/platform_api.c deleted file mode 100755 index 53905326246..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/platform_api.c +++ /dev/null @@ -1,396 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include "cpr.h" -#include "cpr_string.h" -#include "phone_debug.h" -#include "prot_configmgr.h" -#include "phone.h" -#include "CCProvider.h" -#include "cpr_stdlib.h" -#include "ccsip_pmh.h" -#include "platform_api.h" -#include -#include "ccapp_task.h" - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ -#define PLT_F_PREFIX "PLT : %s : " // requires 1 arg: fname -// Why don't we modify strlib_malloc to handle NULL? -#define STRLIB_CREATE(str) (str)?strlib_malloc((str), strlen((str))):strlib_empty() - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ - -void platform_sync_cfg_vers(char *cfg_ver, char *dp_ver, char *softkey_ver); -void platform_reg_fallback_ind(int fallback_to); -void platform_reg_failover_ind(int failover_to); - - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ - - -/** - * give the platform IP address mode. This is a temporary function - * until config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)) - * is fully implemented (P2). - * - * @param none - * - * @return CPR_IP_MODE_IPV4, - * CPR_IP_MODE_IPV6, - * CPR_IP_MODE_DUAL - */ -cpr_ip_mode_e -platform_get_ip_address_mode (void) -{ - cpr_ip_mode_e ip_mode; - - //config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - - /* fake mode to what ever mode under test here */ - ip_mode = CPR_IP_MODE_IPV4; - - return (ip_mode); -} - - -/** - * Send a reset or restart request to the adapter - * - * @param action - reset or restart - * @return none - * - */ -void -platform_reset_req (DeviceResetType action) -{ - static const char fname[] = "platform_reset_req"; - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********%s, requested***********", - DEB_F_PREFIX_ARGS(PLAT_API, fname), - (action==1)? "RESET":"RESTART"); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_SERVICE_CONTROL_REQ; - msg.update.ccFeatUpd.data.reset_type = action; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_reset_req(%d) msg", DEB_F_PREFIX_ARGS(PLAT_API, fname), action); - } -} - -/** - * Ask the platform to sync with versions got from call control - * or outside entity. As part of the sync, platform downloads - * the files if required. - * - * @param cfg_ver - version stamp for config file - * @param dp_ver - version stamp for the dialplan file - * @param softkey_ver - version stamp for the softkey file. - * - * @return none - */ -void -platform_sync_cfg_vers (char *cfg_ver, char *dp_ver, char *softkey_ver) -{ - static const char fname[] = "platform_sync_cfg_vers"; - char empty_string[] = ""; - feature_update_t msg; - - if (cfg_ver == NULL) { - cfg_ver = empty_string; - } - if (dp_ver == NULL) { - dp_ver = empty_string; - } - if (softkey_ver == NULL) { - softkey_ver = empty_string; - } - - CCAPP_DEBUG(DEB_F_PREFIX"cfg_ver=%s dp_ver=%s sk_ver=%s", DEB_F_PREFIX_ARGS(PLAT_API, fname), - cfg_ver, dp_ver, softkey_ver); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_SYNC_CONFIG_VERSION; - msg.update.ccFeatUpd.data.cfg_ver_data.cfg_ver = strlib_malloc(cfg_ver, strlen(cfg_ver)); - msg.update.ccFeatUpd.data.cfg_ver_data.dp_ver = strlib_malloc(dp_ver, strlen(dp_ver)); - msg.update.ccFeatUpd.data.cfg_ver_data.softkey_ver = strlib_malloc(softkey_ver, strlen(softkey_ver)); - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_sync_cfg_vers msg", - DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} - - -/** - * - * Tell platform to adjust the time to the gmt_time received from outside - * For sip the "outside" is from the "Date" header coming from a CCM or - * any other Server - * - * @param gmt_time - GMT time in seconds - * - * @return none - */ -void -platform_set_time (long gmt_time) -{ - static const char fname[] = "platform_set_time"; - session_mgmt_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"setting time to=%ld", DEB_F_PREFIX_ARGS(PLAT_API, fname), gmt_time); - - msg.func_id = SESSION_MGMT_SET_TIME; - msg.data.time.gmt_time = gmt_time; - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_set_time msg", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} - - -/** - * - * Indicate to the platform that reg manager wants to failover to a Call - * control indicated in failover_to. A corresponding ccRegFailoverRsp() - * will be issued by the platform once the failover indication is processed. - * - * @param failover_to - type of call control, - * e.g. cip_sipcc_CcMgmtConst_CC_TYPE_CCM - * @return none - */ -void -platform_reg_failover_ind (int failover_to) -{ - static const char fname[] = "platform_reg_failover_ind"; - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********Failover to %s=%d ***********", - DEB_F_PREFIX_ARGS(PLAT_API, fname), - failover_to == CC_TYPE_CCM ? "CC_TYPE_CCM" : - "Other", failover_to); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_FAILOVER_IND; - msg.update.ccFeatUpd.data.line_info.info = failover_to; - - if ( ccappTaskPostMsg(CCAPP_FAILOVER_IND, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send platform_reg_failover_ind(%d) msg", fname, failover_to); - } - -} - - -/** - * Indicate to the platform that reg manager intends to fallback to - * primary CCM. Currently the fallback_to is always to CC_TYPE_CCM. - * - * @param fallback_to - type of call control, - * e.g. cip_sipcc_CcMgmtConst_CC_TYPE_CCM - * - * @return none - */ -void -platform_reg_fallback_ind (int fallback_to) -{ - static const char fname[] = "platform_reg_fallback_ind"; - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********Fallback to %d CUCM.***********", - DEB_F_PREFIX_ARGS(PLAT_API, fname), - fallback_to); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_FALLBACK_IND; - msg.update.ccFeatUpd.data.line_info.info = fallback_to; - - if ( ccappTaskPostMsg(CCAPP_FALLBACK_IND, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send platform_reg_fallback_ind(%d) msg", fname, fallback_to); - } -} - -/** - * - * Indicate to the platform that current fallback activity - * is complete i.e. either success or encountered an error - * and that the platform should put the User interaction back - * in service. - * - * @param none - * - * @return none - */ -void -platform_reg_fallback_cfm (void) -{ - static const char fname[] = "platform_reg_fallback_cfm"; - - DEF_DEBUG(DEB_F_PREFIX"***********Fallback completed.***********", - DEB_F_PREFIX_ARGS(PLAT_API, fname)); -} - -/** - * - * Indicate to the platform that current failover activity - * is complete i.e. either success or encountered an error - * and that the platform should put the User interaction back - * in service. - * - * @param none - * - * @return none - */ -void -platform_reg_failover_cfm (void) -{ - static const char fname[] = "platform_reg_failover_cfm"; - - DEF_DEBUG(DEB_F_PREFIX"***********Failover completed.***********", - DEB_F_PREFIX_ARGS(PLAT_API, fname)); -} - - -/** - * - * Notify the platform that call control has shut down. - * - * @param none - * - * @return none - */ -void -shutdownCCAck (void) -{ - static const char fname[] = "shutdownCCAck"; - feature_update_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_SHUTDOWN_ACK; - - if ( ccappTaskPostMsg(CCAPP_SHUTDOWN_ACK, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send shutdownCCAck msg", fname); - } -} - -/** - * Notify the platform about the change in call control mode. - * - * @param mode - the call control mode. - * cip_sipcc_CcMgmtConst_CC_TYPE_CCM - * or cip_sipcc_CcMgmtConst_CC_TYPE_OTHER - * - * @return none - */ -void -platform_cc_mode_notify (int mode) -{ - static const char fname[] = "platform_cc_mode_notify"; - feature_update_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"mode =%d", DEB_F_PREFIX_ARGS(PLAT_API, fname), mode); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_MODE_NOTIFY; - msg.update.ccFeatUpd.data.line_info.info = mode; - - if ( ccappTaskPostMsg(CCAPP_MODE_NOTIFY, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send platform_cc_mode_notify(%d) msg", fname, mode); - } -} - - -int -platform_get_phrase_text (int ndx, char *outstr, uint32_t len) -{ - static const char fname[] = "platform_get_phrase_text"; - session_mgmt_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX "index=%d", DEB_F_PREFIX_ARGS(PLAT_API, fname), ndx); - - msg.func_id = SESSION_MGMT_GET_PHRASE_TEXT; - msg.data.phrase_text.ndx = ndx; - msg.data.phrase_text.outstr = outstr; - msg.data.phrase_text.len = len; - - ccappSyncSessionMgmt(&msg); - - return msg.data.phrase_text.ret_val; -} - - -/*called from configapp.c. This routine will set the kpml - value on the java side and trigger it down to c-side. - Also, it will reinitialize the dialplan. */ -void -update_kpmlconfig(int kpmlVal) -{ - static const char fname[] = "update_kpmlconfig"; - session_mgmt_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX "kpml=%d", DEB_F_PREFIX_ARGS(PLAT_API, fname), kpmlVal); - - msg.func_id = SESSION_MGMT_UPDATE_KPMLCONFIG; - msg.data.kpmlconfig.kpml_val = kpmlVal; - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send update_kpmlconfig msg", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} - - -boolean -check_speaker_headset_mode() -{ - static const char fname[] = "check_speaker_headset_mode"; - - CCAPP_DEBUG(DEB_F_PREFIX "checking SPEAKER and HEADSET active or not", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - - return platGetSpeakerHeadsetMode(); -} - - -/** - * - * Notify the platform to logout and reset. - * - * @param none - * - * @return none - */ - -void -platform_logout_reset_req(void){ - static const char fname[] = "platform_logout_reset_req"; - feature_update_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_LOGOUT_RESET; - - if ( ccappTaskPostMsg(CCAPP_FALLBACK_IND, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send Logout_Reset msg", fname); - } - return; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/common/prot_cfgmgr_private.h b/media/webrtc/signaling/src/sipcc/core/common/prot_cfgmgr_private.h deleted file mode 100755 index 6cca96b2a64..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/prot_cfgmgr_private.h +++ /dev/null @@ -1,429 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PROT_CFGMGR_PRIVATE_H_ -#define _PROT_CFGMGR_PRIVATE_H_ - -#include "cpr_types.h" -#include "ccapi.h" -#include "ccsip_protocol.h" -//TEMPORARY REMOVAL #include "sntp.h" -#include "configmgr.h" -#include "dtmf.h" -#include "phone_platform_constants.h" - -#ifdef SAPP_SAPP_GSM -#define DEFAULT_PROTOCOL "sip" -#define SCCP_WELL_KNOWN_PORT_STR "2000" -#endif - -#define SIP_PLATFORM_CONFIG_DATE_TEMPLATE_24HOUR "M/D/Y" -#define SIP_PLATFORM_CONFIG_DATE_TEMPLATE_12HOUR "M/D/YA" - -#define DYNAMIC_DTMF_PAYLOAD_MIN 96 -#define DYNAMIC_DTMF_PAYLOAD_MAX 127 - -// Includes 3 CCMS -#define MAX_CCMS 4 - -#define MAX_CODEC_ENTRIES 10 -// updated MAX_LOAD_FILE_NAME to be in sync with XmlDefaultConfigParmObject -#define MAX_LOAD_FILE_NAME 65 - -/********************************************************* - * - * Config Block Definition - * This structure holds all of the parsed configuration - * information obtained from the TFTP config file - * - * To add new entries to the config table, please see - * the instructions in configmgr.h and prot_configmgr.h - * - * note: IP addresses are internally stored in the - * Telecaster "Byte Reversed" order. - * Eg. 0xf8332ca1 = 161.44.51.248 - * - ********************************************************/ -typedef struct -{ - int feature; - int index; - char name[MAX_LINE_NAME_SIZE]; - char authname[AUTH_NAME_SIZE]; - char password[MAX_LINE_PASSWORD_SIZE]; - char displayname[MAX_LINE_NAME_SIZE]; // Actually we allow upto 32 UTF-8 chars which typically needs 32*3 octets. - char contact[MAX_LINE_CONTACT_SIZE]; - int autoanswer; - char autoanswer_mode[MAX_LINE_AUTO_ANS_MODE_SIZE]; - int call_waiting; - int msg_waiting_lamp; - int msg_waiting_amwi; - int ring_setting_idle; - int ring_setting_active; - char proxy_address[MAX_IPADDR_STR_LEN]; - int proxy_port; - char cfwdall[MAX_URL_LENGTH]; - char speeddial_number[MAX_LINE_NAME_SIZE]; - char retrieval_prefix[MAX_LINE_NAME_SIZE]; - char messages_number[MAX_LINE_NAME_SIZE]; - int fwd_caller_name_display; - int fwd_caller_number_display; - int fwd_redirected_number_display; - int fwd_dialed_number_display; - int feature_option_mask; -} line_cfg_t; - -typedef struct -{ - char address[MAX_IPADDR_STR_LEN]; - char ipv6address[MAX_IPADDR_STR_LEN]; - int sip_port; - int sec_level; - int is_valid; -} ccm_cfg_t; - -typedef struct -{ - cpr_ip_addr_t my_ip_addr; - uint8_t my_mac_addr[6]; - - line_cfg_t line[MAX_CONFIG_LINES]; - ccm_cfg_t ccm[MAX_CCMS]; - int proxy_register; - int sip_retx; /* SIP retransmission count */ - int sip_invite_retx; /* SIP INVITE request retransmission count */ - int timer_t1; /* SIP T1 timer value */ - int timer_t2; /* SIP T2 timer value */ - int timer_invite_expires; /* SIP Expires timer value */ - int timer_register_expires; - /* - * preferred codec is kept as key_table_entry structure. The - * name field of the key is a primary indication whether the - * parameter is configured or not. This is because the - * zero value is a designated value for G711 and the -1 is - * for no codec. The -1 is not natural value of uninitialized - * variable therefore keep the codec as name and value pair. - * The missing of the name indiates there the parameter is not - * configured. - */ - key_table_entry_t preferred_codec; - int dtmf_db_level; - DtmfOutOfBandTransport_t dtmf_outofband; - int dtmf_avt_payload; - int callerid_blocking; - int dnd_call_alert; - int dnd_reminder_timer; - int blf_alert_tone_idle; - int blf_alert_tone_busy; - int auto_pickup_enabled; - int call_hold_ringback; - int stutter_msg_waiting; - int call_stats; - int auto_answer; - int anonymous_call_block; - int nat_enable; - char nat_address[MAX_IPADDR_STR_LEN]; - int voip_control_port; - unsigned int media_port_start; - unsigned int media_port_end; - char sync[MAX_SYNC_LEN]; - char proxy_backup[MAX_IPADDR_STR_LEN]; - char proxy_emergency[MAX_IPADDR_STR_LEN]; - int proxy_backup_port; - int proxy_emergency_port; - int nat_received_processing; - - char proxy_outbound[MAX_IPADDR_STR_LEN]; - int proxy_outbound_port; - char reg_user_info[MAX_REG_USER_INFO_LEN]; - int cnf_join_enable; - int remote_party_id; - int semi_xfer; - char cfwd_uri[MAX_URL_LENGTH]; - int local_cfwd_enable; - int timer_register_delta; - int rfc_2543_hold; - int sip_max_forwards; - int conn_monitor_duration; - char call_pickup_uri[MAX_URL_LENGTH]; - char call_pickup_list_uri[MAX_URL_LENGTH]; - char call_pickup_group_uri[MAX_URL_LENGTH]; - char meet_me_service_uri[MAX_URL_LENGTH]; - char call_forward_uri[MAX_URL_LENGTH]; - char abbreviated_dial_uri[MAX_URL_LENGTH]; - int call_log_blf_enabled; - int remote_cc_enabled; - int timer_keepalive_expires; - int timer_subscribe_expires; - int timer_subscribe_delta; - int transport_layer_prot; - int kpml; - int enable_vad; - int autoanswer_idle_alt; - int autoanswer_timer; - int autoanswer_override; - int offhook_to_first_digit; - int call_waiting_period; - int ring_setting_busy_pol; - int dscp_for_call_control; - int speaker_enabled; - int xfr_onhook_enabled; - int retain_forward_information; - int rollover; - int join_across_lines; - int emcc_mode; - int visiting_em_port; - char visiting_em_ip[MAX_IPADDR_STR_LEN]; - int ip_addr_mode; - char load_file[MAX_LOAD_FILE_NAME]; - int inter_digit_timer; - int dscp_audio; - int dscp_video; - char deviceName[MAX_REG_USER_INFO_LEN]; - uint8_t my_active_mac_addr[6]; - char userAgent[MAX_REG_USER_INFO_LEN]; - char modelNumber[MAX_REG_USER_INFO_LEN]; - int srst_is_secure; - char join_dxfer_policy[MAX_JOIN_DXFER_POLICY_SIZE]; - char external_number_mask[MAX_EXTERNAL_NUMBER_MASK_SIZE]; - char media_ip_addr[MAX_IPADDR_STR_LEN]; - int p2psip; - int sdpmode; - char version[4]; - int rtcpmux; - int rtpsavpf; - int maxavbitrate; - int maxcodedaudiobw; - int usedtx; - int stereo; - int useinbandfec; - int cbr; - int maxptime; - int sctp_port; - int num_data_streams; -} prot_cfg_t; - -static prot_cfg_t prot_cfg_block; - - -/********************************************************* - * return (1); - * Config Table Keytable Structures - * - * Some config table entries can only contain special return (1); - * values. Those entries must specify a key table - * that contains valid values for the entry. - * - *********************************************************/ -/* - * codec_table table is used for parsing configured preferred - * codec, J-side caches string and it is converted to the enumerated - * value during reset/restart. The "none" value is currently used - * by CUCM' TFTP when there is no preferred codec configured and - * therefore the "none" is included in the table. - */ -static const key_table_entry_t codec_table[] = { - {"g711ulaw", RTP_PCMU}, - {"g711alaw", RTP_PCMA}, - {"g729a", RTP_G729}, - {"L16", RTP_L16}, -#ifdef CISCOWB_SUPPORTED - {"CiscoWb", RTP_CISCOWB}, -#endif - {"g722", RTP_G722}, - {"iLBC", RTP_ILBC}, - {"iSAC", RTP_ISAC}, - {"opus", RTP_OPUS}, - {"none", RTP_NONE}, - {0, RTP_NONE} -}; - -static const key_table_entry_t dtmf_outofband_table[] = { - {"none", DTMF_OUTOFBAND_NONE}, - {"avt", DTMF_OUTOFBAND_AVT}, - {"avt_always", DTMF_OUTOFBAND_AVT_ALWAYS}, - {0, 0} -}; - -static const key_table_entry_t user_info_table[] = { - {"none", 0,}, - {"phone", 1,}, - {"ip", 2,}, - {0, 0,} -}; - -/********************************************************* - *!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * SIP Protocol Config table Variable Name and Type Definitions - * - * This table defines all the possible variables that can - * be set in the TFTP config file (if used). - * var: Is the name as it is defined in the ascii - * configuration file. - * addr: Is the address of where the parsed variable - * is stored into memory - * len: Is the length of the item in kazoo memory. - * (Important for things like strings) - * parser: Is a function pointer to a routine that is - * used to parse (convert) this particular - * variable from ascii form to internal form. - * print: Is a function pointer to a routine that is - * used to print (convert) this particular - * variable from internal form to ascii form. - * keytable: Defines the table of values that this entry - * can have. - * - *!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Before changing any these, please read the following: - * - * This table MUST be kept in sync with the configuration - * ID enums located in the prot_configmgr.h - * file. There is a one-to-one correspondence between those - * enums and this table. - * - * To add or remove config properties, please refer to the - * file prot_configmgr.h. - * - *!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - *********************************************************/ - /********************************************************* - * - * Platform-Specific Configuration Section - * (Common across all IP Phone protocols.) - * - ********************************************************/ - -/* name {addr & len} parser print */ -/* ------------------------ ----------------- ------ ------ */ -var_t prot_cfg_table[CFGID_PROTOCOL_MAX+1] = { - /* 0 */{"startMediaPort",CFGVAR(media_port_start), PA_INT, PR_INT, 0}, - {"endMediaPort", CFGVAR(media_port_end), PA_INT, PR_INT, 0}, - {"callerIdBlocking", CFGVAR(callerid_blocking), PA_INT, PR_INT, 0}, - {"anonymousCallBlock", CFGVAR(anonymous_call_block), PA_INT, PR_INT, 0}, - {"dndCallAlert", CFGVAR(dnd_call_alert), PA_INT, PR_INT, 0}, - {"dndReminderTimer", CFGVAR(dnd_reminder_timer), PA_INT, PR_INT, 0}, - {"preferredCode", CFGVAR(preferred_codec), PA_KEYE, PR_KEYE, codec_table}, - {"dtmfOutofBand",CFGVAR(dtmf_outofband), PA_KEY, PR_KEY, dtmf_outofband_table}, - {"dtmfAvtPayload", CFGVAR(dtmf_avt_payload), PA_INT, PR_INT, 0}, - {"dtmfDbLevel", CFGVAR(dtmf_db_level), PA_INT, PR_INT, 0}, - {"sipRetx", CFGVAR(sip_retx), PA_INT, PR_INT, 0}, - /*11*/ {"sipInviteRetx", CFGVAR(sip_invite_retx), PA_INT, PR_INT, 0}, - {"timerT1", CFGVAR(timer_t1), PA_INT, PR_INT, 0}, - {"timerT2", CFGVAR(timer_t2), PA_INT, PR_INT, 0}, - {"timerInviteExpires", CFGVAR(timer_invite_expires), PA_INT, PR_INT, 0}, - {"timerRegisterExpires", CFGVAR(timer_register_expires), PA_INT, PR_INT, 0}, - {"registerWithProxy", CFGVAR(proxy_register), PA_INT, PR_INT, 0}, - {"backupProxy", CFGVAR(proxy_backup), PA_STR, PR_STR, 0}, - {"backupProxyPort", CFGVAR(proxy_backup_port), PA_INT, PR_INT, 0}, - {"emergencyProxy", CFGVAR(proxy_emergency), PA_STR, PR_STR, 0}, - {"emergencyProxyPort", CFGVAR(proxy_emergency_port), PA_INT, PR_INT, 0}, - {"outboundProxy", CFGVAR(proxy_outbound), PA_STR, PR_STR, 0}, - {"outboundProxyPort", CFGVAR(proxy_outbound_port), PA_INT, PR_INT, 0}, - {"natReceivedProcessing", CFGVAR(nat_received_processing),PA_INT, PR_INT, 0}, - {"userInfo", CFGVAR(reg_user_info), PA_KEY, PR_KEY, user_info_table}, - {"cnfJoinEnable", CFGVAR(cnf_join_enable), PA_INT, PR_INT, 0}, - {"remotePartyID", CFGVAR(remote_party_id), PA_INT, PR_INT, 0}, - {"semiAttendedTransfer", CFGVAR(semi_xfer), PA_INT, PR_INT, 0}, - {"callHoldRingback", CFGVAR(call_hold_ringback), PA_INT, PR_INT, 0}, - {"stutterMsgWaiting", CFGVAR(stutter_msg_waiting), PA_INT, PR_INT, 0}, - {"callForwardUri", CFGVAR(cfwd_uri), PA_STR, PR_STR, 0}, - /*31*/ {"callStats", CFGVAR(call_stats), PA_INT, PR_INT, 0}, - {"autoAnswer", CFGVAR(auto_answer), PA_INT, PR_INT, 0}, - {"localCfwdEnable", CFGVAR(local_cfwd_enable), PA_INT, PR_INT, 0}, - {"timerRegisterDelta", CFGVAR(timer_register_delta), PA_INT, PR_INT, 0}, - {"MaxRedirects", CFGVAR(sip_max_forwards), PA_INT, PR_INT, 0}, - {"rfc2543Hold", CFGVAR(rfc_2543_hold), PA_INT, PR_INT, 0}, - {"ccm1_address", CFGVAR(ccm[0].address), PA_STR, PR_STR, 0}, - {"ccm2_address", CFGVAR(ccm[1].address), PA_STR, PR_STR, 0}, - {"ccm3_address", CFGVAR(ccm[2].address), PA_STR, PR_STR, 0}, - {"ccm1_ipv6address", CFGVAR(ccm[0].ipv6address), PA_STR, PR_STR, 0}, - {"ccm2_ipv6address", CFGVAR(ccm[1].ipv6address), PA_STR, PR_STR, 0}, - {"ccm3_ipv6address", CFGVAR(ccm[2].ipv6address), PA_STR, PR_STR, 0}, - {"ccm1_sipPort", CFGVAR(ccm[0].sip_port), PA_INT, PR_INT, 0}, - {"ccm2_sipPort", CFGVAR(ccm[1].sip_port), PA_INT, PR_INT, 0}, - {"ccm3_sipPort", CFGVAR(ccm[2].sip_port), PA_INT, PR_INT, 0}, - {"ccm1_securityLevel", CFGVAR(ccm[0].sec_level), PA_INT, PR_INT, 0}, - {"ccm2_securityLevel", CFGVAR(ccm[1].sec_level), PA_INT, PR_INT, 0}, - {"ccm3_securityLevel", CFGVAR(ccm[2].sec_level), PA_INT, PR_INT, 0}, - {"ccm1_isValid", CFGVAR(ccm[0].is_valid), PA_INT, PR_INT, 0}, - /*50*/ {"ccm2_isValid", CFGVAR(ccm[1].is_valid), PA_INT, PR_INT, 0}, - {"ccm3_isValid", CFGVAR(ccm[2].is_valid), PA_INT, PR_INT, 0}, - {"ccmTftp_ipAddr", CFGVAR(ccm[3].address), PA_STR, PR_STR, 0}, - {"ccmTftp_port", CFGVAR(ccm[3].sip_port), PA_INT, PR_INT, 0}, - {"ccmTftp_isValid", CFGVAR(ccm[3].is_valid), PA_INT, PR_INT, 0}, - {"ccmTftp_securityLevel", CFGVAR(ccm[3].sec_level), PA_INT, PR_INT, 0}, - {"ccmSrstIpAddr", CFGVAR(ccm[4].address), PA_STR, PR_STR, 0}, - {"ccmSrst_sipPort", CFGVAR(ccm[4].sip_port), PA_INT, PR_INT, 0}, - {"ccmSrst_isValid", CFGVAR(ccm[4].is_valid), PA_INT, PR_INT, 0}, - {"ccmSrst_securityLevel", CFGVAR(ccm[4].sec_level), PA_INT, PR_INT, 0}, - {"connectionMonitorDuration", CFGVAR(conn_monitor_duration), PA_INT, PR_INT, 0}, - {"callPickupURI", CFGVAR(call_pickup_uri), PA_STR, PR_STR, 0}, - {"callPickupListURI", CFGVAR(call_pickup_list_uri), PA_STR, PR_STR, 0}, - {"callPickupGroupURI", CFGVAR(call_pickup_group_uri), PA_STR, PR_STR, 0}, - {"meetMeServiceURI", CFGVAR(meet_me_service_uri), PA_STR, PR_STR, 0}, - {"callForwardURI", CFGVAR(call_forward_uri), PA_STR, PR_STR, 0}, - {"abbreviatedDialURI", CFGVAR(abbreviated_dial_uri), PA_STR, PR_STR, 0}, - {"callLogBlfEnabled", CFGVAR(call_log_blf_enabled), PA_INT, PR_INT, 0}, - {"remoteCcEnabled", CFGVAR(remote_cc_enabled), PA_INT, PR_INT, 0}, - {"retainForwardInformation", CFGVAR(retain_forward_information), PA_INT, PR_INT, 0}, - /*70*/ {"timerKeepaliveExpires", CFGVAR(timer_keepalive_expires),PA_INT, PR_INT, 0}, - {"timerSubscribeExpires", CFGVAR(timer_subscribe_expires),PA_INT, PR_INT, 0}, - {"timerSubscribeDelta", CFGVAR(timer_subscribe_delta), PA_INT, PR_INT, 0}, - {"transportLayerProtocol", CFGVAR(transport_layer_prot), PA_INT, PR_INT, 0}, - {"kpml", CFGVAR(kpml), PA_INT, PR_INT, 0}, - {"natEnable", CFGVAR(nat_enable), PA_INT, PR_INT, 0}, - {"natAddress", CFGVAR(nat_address), PA_STR, PR_STR, 0}, - {"voipControlPort", CFGVAR(voip_control_port), PA_INT, PR_INT, 0}, - {"myIpAddr", CFGVAR(my_ip_addr), PA_IP, PR_IP, 0}, - {"myMacAddr", CFGVAR(my_mac_addr), PA_STR, PR_MAC, 0}, - {"enableVad", CFGVAR(enable_vad), PA_INT, PR_INT, 0}, - {"autoAnswerAltBehavior", CFGVAR(autoanswer_idle_alt), PA_INT, PR_INT, 0}, - {"autoAnswerTimer", CFGVAR(autoanswer_timer), PA_INT, PR_INT, 0}, - {"autoAnswerOverride", CFGVAR(autoanswer_override), PA_INT, PR_INT, 0}, - {"offhookToFirstDigitTimer", CFGVAR(offhook_to_first_digit), PA_INT, PR_INT, 0}, - {"silentPeriodBetweenCallWaitingBursts", CFGVAR(call_waiting_period), PA_INT, PR_INT, 0}, - {"ringSettingBusyStationPolicy", CFGVAR(ring_setting_busy_pol), PA_INT, PR_INT, 0}, - {"DscpForCm2Dvce", CFGVAR(dscp_for_call_control), PA_INT, PR_INT, 0}, - {"speakerEnabled", CFGVAR(speaker_enabled), PA_INT, PR_INT, 0}, - {"transferOnhookEnable", CFGVAR(xfr_onhook_enabled), PA_INT, PR_INT, 0}, - /*90*/ {"rollover", CFGVAR(rollover), PA_INT, PR_INT, 0}, - {"loadFileName", CFGVAR(load_file), PA_STR, PR_STR, 0}, - {"blfAlertToneIdle", CFGVAR(blf_alert_tone_idle),PA_INT, PR_INT, 0}, - {"blfAlertToneBusy", CFGVAR(blf_alert_tone_busy),PA_INT, PR_INT, 0}, - {"autoPickupEnable", CFGVAR(auto_pickup_enabled),PA_INT, PR_INT, 0}, - {"joinAcrossLines", CFGVAR(join_across_lines), PA_INT, PR_INT, 0}, - /*96*/ {"myActiveMacAddr", CFGVAR(my_active_mac_addr), PA_STR, PR_MAC, 0}, - /*97*/ {"DscpAudio", CFGVAR(dscp_audio), PA_INT, PR_INT, 0}, - {"deviceName", CFGVAR(deviceName), PA_STR, PR_STR, 0}, - {"userAgent", CFGVAR(userAgent), PA_STR, PR_STR, 0}, - {"modelNumber", CFGVAR(modelNumber), PA_STR, PR_STR, 0}, - {"DscpVideo", CFGVAR(dscp_video), PA_INT, PR_INT, 0}, - {"IPAddrMode", CFGVAR(ip_addr_mode), PA_INT, PR_INT, 0}, - {"interDigitTimer", CFGVAR(inter_digit_timer), PA_INT, PR_INT, 0}, - {"emccMode", CFGVAR(emcc_mode), PA_INT, PR_INT, 0}, - {"visitingEMPort", CFGVAR(visiting_em_port), PA_INT, PR_INT, 0}, - {"visitingEMIpAddress", CFGVAR(visiting_em_ip), PA_STR, PR_STR, 0}, - {"isSRSTSecure", CFGVAR(srst_is_secure), PA_INT, PR_INT, 0}, -/*108*/ {"joinDxferPolicy", CFGVAR(join_dxfer_policy), PA_STR, PR_STR, 0}, - {"externalNumberMask", CFGVAR(external_number_mask), PA_STR, PR_STR, 0}, - {"mediaIpAddr", CFGVAR(media_ip_addr), PA_STR, PR_STR, 0}, - {"p2psip", CFGVAR(p2psip), PA_INT, PR_INT, 0}, - {"version", CFGVAR(version), PA_STR, PR_STR, 0}, - {"sdpmode", CFGVAR(sdpmode), PA_INT, PR_INT, 0}, - {"rtcpmux", CFGVAR(rtcpmux), PA_INT, PR_INT, 0}, - {"rtpsavpf", CFGVAR(rtpsavpf), PA_INT, PR_INT, 0}, - {"maxavbitrate", CFGVAR(maxavbitrate), PA_INT, PR_INT, 0}, - {"maxcodedaudiobw", CFGVAR(maxcodedaudiobw), PA_INT, PR_INT, 0}, - {"usedtx", CFGVAR(usedtx), PA_INT, PR_INT, 0}, - {"stereo", CFGVAR(stereo), PA_INT, PR_INT, 0}, - {"useinbandfec", CFGVAR(useinbandfec), PA_INT, PR_INT, 0}, - {"cbr", CFGVAR(cbr), PA_INT, PR_INT, 0}, - {"maxptime", CFGVAR(maxptime), PA_INT, PR_INT, 0}, - {"sctp_port", CFGVAR(sctp_port), PA_INT, PR_INT, 0}, - {"num_data_streams", CFGVAR(num_data_streams), PA_INT, PR_INT, 0}, - {0, 0, 0, 0, 0, 0} - }; - -#endif /* _PROT_CFGMGR_PRIVATE_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c b/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c deleted file mode 100755 index b8e6eedbbd7..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c +++ /dev/null @@ -1,975 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "util_string.h" -#include "task.h" -#include "upgrade.h" -#include "ccsip_task.h" -#include "config.h" -#include "ccsip_core.h" -#include "prot_configmgr.h" -#include "prot_cfgmgr_private.h" -#include "sip_common_transport.h" -#include "phone_debug.h" -#include "regmgrapi.h" -#include "rtp_defs.h" -#include "vcm.h" -#include "plat_api.h" - -#define MAX_TOS_VALUE 5 -#define MIN_VOIP_PORT_RANGE 1024 -#define MAX_VOIP_PORT_RANGE 65535 -#define MAX_AUTO_ANSWER_7960 63 -#define MIN_KEEPALIVE_EXPIRES 120 -#define MAX_KEEPALIVE_EXPIRES 7200 - -extern void platform_get_ipv4_address(cpr_ip_addr_t *ip_addr); -extern void platform_get_ipv6_address(cpr_ip_addr_t *ip_addr); -extern boolean Is794x; - -static cpr_ip_addr_t redirected_nat_ipaddr = {0,{0}}; -static void config_set_current_codec_table(int codec_mask, - rtp_ptype *codec_table); - -/********************************************************* - * - * Network Configuration Settings - * Look at making these generic and moving them to the - * network library... - * - *********************************************************/ - -static void initCfgTblEntry(int index, const char * name, void *addr, int length, - parse_func_t parse, print_func_t print, - const key_table_entry_t *key) -{ - var_t *table; - table = &prot_cfg_table[index]; - - table->name = name; - table->addr = addr; - table->length = length; - table->parse_func = parse; - table->print_func = print; - table->key_table = key; - -} - -/* Function: protCfgTblInit() - * - * Description: Initializes line specific params in prot_cfg_table - * - * Parameters: - * - * Returns: - */ -void protCfgTblInit() -{ -int i; - memset(&prot_cfg_block, 0, sizeof(prot_cfg_block)); - for (i=0; i< MAX_CONFIG_LINES; i++) { - initCfgTblEntry(CFGID_LINE_INDEX+i, "Index", CFGVAR(line[i].index), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FEATURE+i, "Feat", CFGVAR(line[i].feature), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_PROXY_ADDRESS+i, "ProxyAddr", CFGVAR(line[i].proxy_address), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_PROXY_PORT+i, "ProxyPort", CFGVAR(line[i].proxy_port), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_CALL_WAITING+i, "CWait", CFGVAR(line[i].call_waiting), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_AUTOANSWER_ENABLED+i, "AAns", CFGVAR(line[i].autoanswer), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_AUTOANSWER_MODE+i, "AAnsMode", CFGVAR(line[i].autoanswer_mode), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_MSG_WAITING_LAMP+i, "MWILamp", CFGVAR(line[i].msg_waiting_lamp), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_MESSAGE_WAITING_AMWI+i, "AMWI", CFGVAR(line[i].msg_waiting_amwi), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_RING_SETTING_IDLE+i, "RingIdle", CFGVAR(line[i].ring_setting_idle), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_RING_SETTING_ACTIVE+i, "RingActive", CFGVAR(line[i].ring_setting_active), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_NAME+i, "Name", CFGVAR(line[i].name), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_AUTHNAME+i, "AuthName", CFGVAR(line[i].authname), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_PASSWORD+i, "Passwd", CFGVAR(line[i].password), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_DISPLAYNAME+i, "DisplayName", CFGVAR(line[i].displayname), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_CONTACT+i, "Contact", CFGVAR(line[i].contact), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_CFWDALL+i, "CfwdAll", CFGVAR(line[i].cfwdall), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_SPEEDDIAL_NUMBER+i, "speedDialNumber", CFGVAR(line[i].speeddial_number), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_RETRIEVAL_PREFIX+i, "retrievalPrefix", CFGVAR(line[i].retrieval_prefix), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_MESSAGES_NUMBER+i, "messagesNumber", CFGVAR(line[i].messages_number), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_FWD_CALLER_NAME_DIPLAY+i, "callerName", CFGVAR(line[i].fwd_caller_name_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY+i, "callerName", CFGVAR(line[i].fwd_caller_number_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY+i, "redirectedNumber", CFGVAR(line[i].fwd_redirected_number_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY+i, "dialedNumber", CFGVAR(line[i].fwd_dialed_number_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FEATURE_OPTION_MASK+i, "featureOptionMask", CFGVAR(line[i].feature_option_mask), PA_INT, PR_INT, 0); - } - - initCfgTblEntry(CFGID_PROTOCOL_MAX, 0, 0, 0, 0, 0, 0); -} - -/* - * sip_config_get_net_device_ipaddr() - * - * Get the device IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sip_config_get_net_device_ipaddr (cpr_ip_addr_t *ip_addr) -{ - cpr_ip_addr_t ip_addr1 = {0,{0}}; - - platform_get_ipv4_address(&ip_addr1); - util_ntohl(ip_addr, &ip_addr1); -} - -/* - * sip_config_get_net_device_ipaddr() - * - * Get the device IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * - */ -void -sip_config_get_net_ipv6_device_ipaddr (cpr_ip_addr_t *ip_addr) -{ - cpr_ip_addr_t ip_addr1 = {0,{0}}; - - platform_get_ipv6_address(&ip_addr1); - util_ntohl(ip_addr, &ip_addr1); -} - - -/* - * sip_config_get_nat_ipaddr() - * - * Get the nat IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sip_config_get_nat_ipaddr (cpr_ip_addr_t *ip_addr) -{ - cpr_ip_addr_t IPAddress; - char address[MAX_IPADDR_STR_LEN]; - int dnsErrorCode = 1; - - if (redirected_nat_ipaddr.type == CPR_IP_ADDR_INVALID) { - config_get_string(CFGID_NAT_ADDRESS, address, sizeof(address)); - if ((cpr_strcasecmp(address, UNPROVISIONED) != 0) && (address[0] != 0)) { - dnsErrorCode = dnsGetHostByName(address, &IPAddress, 100, 1); - } - - if (dnsErrorCode == 0) { - util_ntohl(ip_addr, &IPAddress); - return ; - } else { - /* - * If the NAT address is not provisioned or - * unavailable, return the local address instead. - */ - sip_config_get_net_device_ipaddr(ip_addr); - return; - } - } else { - *ip_addr = redirected_nat_ipaddr; - return ; - } - -} - -/* - * sip_config_set_nat_ipaddr() - * - * Set the device NAT IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sip_config_set_nat_ipaddr (cpr_ip_addr_t *ip_address) -{ - redirected_nat_ipaddr = *ip_address; -} - -/********************************************************* - * - * SIP Configuration Settings - * These should probably be turned into generic config - * table "gets/sets" or should be moved to a SIP platform - * file. Maybe ccsip_platform_ui.c since that's where we - * have the other SIP Platform code. In the long run, we - * should rename ccsip_platform_ui.c to ccsip_platform.c - * - *********************************************************/ - -/* - * sip_config_get_line_from_button() - * Some cases CCM sends down line number instead of button number - * that has to be mapped to correct button number. This function is - * called to get actual line number for a given button number - * - * Returns: actual line number from given button number - * - */ -line_t -sip_config_get_line_from_button (line_t button) -{ - line_t max_lines_allowed; - uint32_t line = 0; - line_t button_no = 0; - - if (Is794x) { - max_lines_allowed = MAX_REG_LINES_794X; - } else { - max_lines_allowed = MAX_REG_LINES; - } - - if ((button < 1) || (button > max_lines_allowed)) { - return (button); - } - - config_get_line_value(CFGID_LINE_INDEX, &line, - sizeof(line), button); - - /* Look for the line number through the configuration - * max_lines_allowed)) { - if (line != 0) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"Invalid Line: %d", fname, line); - } - return FALSE; - } - - config_get_line_string(CFGID_LINE_NAME, temp, line, sizeof(temp)); - if (temp[0] == '\0') { - return FALSE; - } - - config_get_line_value(CFGID_LINE_FEATURE, &line_feature, - sizeof(line_feature), line); - - if (line_feature != cfgLineFeatureDN) { - return FALSE; - } - - return TRUE; -} -/* - * sip_config_local_line_get() - * - * Get the Line setting. - * Note: The UI has serious problems if there are gaps in the - * line names. Therefore, lines must be sequential. In - * other words, if lines 1, 2, and 4 have names, this routine - * will return that two lines are active. Once Line three is - * found to be unprovisioned, line 4 will be ignored. - */ -line_t -sip_config_local_line_get (void) -{ - if (Is794x) { - return (MAX_REG_LINES_794X); - } - return (MAX_REG_LINES); -} -/* - * sip_config_get_keepalive_expires() - * - * Returns the keepalive expires configured. - * The minimum allowed value is returned if - * configured value is less than the minimum - * allowed value.If the configured value is - * greater than the maximum allowed then the - * maximum allowed value is returned. - * - */ -int -sip_config_get_keepalive_expires() -{ - int keepalive_interval = 0; - - config_get_value(CFGID_TIMER_KEEPALIVE_EXPIRES, &keepalive_interval, - sizeof(keepalive_interval)); - - if (keepalive_interval < MIN_KEEPALIVE_EXPIRES) { - keepalive_interval = MIN_KEEPALIVE_EXPIRES; - TNP_DEBUG(DEB_F_PREFIX"Keepalive interval less than minimum acceptable.Resetting it to %d", - DEB_F_PREFIX_ARGS(SIP_KA, "sip_config_get_keepalive_expires"), - keepalive_interval); - } else if (keepalive_interval > MAX_KEEPALIVE_EXPIRES) { - keepalive_interval = MAX_KEEPALIVE_EXPIRES; - TNP_DEBUG(DEB_F_PREFIX"Keepalive interval more than maximum acceptable.Resetting it to %d", - DEB_F_PREFIX_ARGS(SIP_KA, "sip_config_get_keepalive_expires"), - keepalive_interval); - } - - return keepalive_interval; -} -/* - * sip_config_get_display_name() - * - * Get the display name - */ -void -sip_config_get_display_name (line_t line, char *buffer, int buffer_len) -{ - - config_get_line_string(CFGID_LINE_DISPLAYNAME, buffer, line, buffer_len); - - if ((strcmp(buffer, UNPROVISIONED) == 0) || (buffer[0] == '\0')) { - config_get_line_string(CFGID_LINE_NAME, buffer, line, buffer_len); - } -} - -/** - * Returns the configured value of preferred codec. The codec may - * or may not be available by the platform. - * - * @param[in] none. - * - * @return rtp_ptype of the codec. - */ -rtp_ptype -sip_config_preferred_codec (void) -{ -#if 1 - uint32_t codec; - - if(vcmGetVideoPreferredCodec((int32_t *) &codec) == 0) { - return (rtp_ptype) codec; - } -#else - key_table_entry_t cfg_preferred_codec; - - config_get_value(CFGID_PREFERRED_CODEC, &cfg_preferred_codec, - sizeof(cfg_preferred_codec)); - if ((cfg_preferred_codec.name != NULL) && - (cfg_preferred_codec.name[0] != '\0')) { - /* The configuration has preferred codec configured */ - return (cfg_preferred_codec.value); - } -#endif - /* No preferred codec configured */ - return (RTP_NONE); -} - -/** - * sip_config_local_supported_codecs_get() - * Get the locally supported codec list. The returned list - * of codecs will be in the ordered of preference. If there is - * preferred condec configured and it is available, the - * preferred codec will be put on the first entry of the - * returned list. - * - * @param[in,out] aSupportedCodecs - pointer to arrary fo the - * rtp_ptype to store the result of - * currenlty available codecs. - * @param[in] supportedCodecsLen - indicates the number of entry - * of the aSupportedCodecs. - * - * @return number of current codecs available. - * - * @pre (aSupportedCodecs != NULL) - * @pre (supportedCodecsLen != 0) - */ -uint16_t -sip_config_local_supported_codecs_get (rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen) -{ - rtp_ptype current_codec_table[MAX_CODEC_ENTRIES+1]; - rtp_ptype *codec; - rtp_ptype pref_codec; - uint16_t count = 0; - int codec_mask; - boolean preferred_codec_available = FALSE; - - codec_mask = vcmGetAudioCodecList(VCM_DSP_FULLDUPLEX); - - if (!codec_mask) { - codec_mask = VCM_CODEC_RESOURCE_G711 | VCM_CODEC_RESOURCE_OPUS; - } - - /* - * convert the current available codec into the enumerated - * preferred list. - */ - current_codec_table[0] = RTP_NONE; - current_codec_table[MAX_CODEC_ENTRIES] = RTP_NONE; - config_set_current_codec_table(codec_mask, ¤t_codec_table[0]); - - /* - * Get the configured preferred codec. If one is configured, - * check it to see if currently it can be supported by the - * platform. If it is configured and is availble to support, - * put the preferred codec in the first one of the list. - */ - pref_codec = sip_config_preferred_codec(); - if (pref_codec != RTP_NONE) { - /* - * There is a configured preferred codec, check to see if - * the codec is currently avaible or not. - */ - codec = ¤t_codec_table[0]; - while (*codec != RTP_NONE) { - if (pref_codec == *codec) { - preferred_codec_available = TRUE; - break; - } - codec++; - } - } - - if (preferred_codec_available) { - /* - * The preferred codec is configured and the platform - * currently can support the preferred codec, put it in - * the first entry. - */ - aSupportedCodecs[count] = pref_codec; - count++; - } else { - /* - * Must init or comparison will be made to uninitialized memory. - * Do not increment count here since we are not adding RTP_NONE - * as a supported codec. We are only initializing memory to a - * known value. - */ - aSupportedCodecs[count] = RTP_NONE; - } - - codec = ¤t_codec_table[0]; - while (*codec != RTP_NONE) { - if (count < supportedCodecsLen) { - if (*codec != aSupportedCodecs[0]) { - aSupportedCodecs[count] = *codec; - count++; - } - } - codec++; - } - return count; -} - -uint32_t -config_get_video_max_fs(const rtp_ptype codec) -{ - uint32_t max_fs; - - if(vcmGetVideoMaxFs(codec, (int32_t *) &max_fs) == 0) { - return max_fs; - } - return 0; -} - -uint32_t -config_get_video_max_fr(const rtp_ptype codec) -{ - uint32_t max_fr; - - if(vcmGetVideoMaxFr(codec, (int32_t *) &max_fr) == 0) { - return max_fr; - } - return 0; -} - -uint32_t -config_get_video_max_mbps(const rtp_ptype codec) -{ - uint32_t max_mbps; - - if(vcmGetVideoMaxMbps(codec, (int32_t *) &max_mbps) == 0) { - return max_mbps; - } - return 0; -} - -uint32_t -config_get_video_max_br(const rtp_ptype codec) -{ - uint32_t max_br; - - if(vcmGetVideoMaxBr(codec, (int32_t *) &max_br) == 0) { - return max_br; - } - return 0; -} - -uint16_t -sip_config_video_add_codecs (rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen, - uint16_t codec_mask) -{ - uint16_t count = 0; - - // All things being equal, prefer VP8 > H.264 p1 > H.264 p0 -> H.263 - if ( codec_mask & VCM_CODEC_RESOURCE_VP8) { - aSupportedCodecs[count] = RTP_VP8; - count++; - } - if ( codec_mask & VCM_CODEC_RESOURCE_H264) { - int modes = vcmGetH264SupportedPacketizationModes(); - // prefer mode 1 to mode 0 - if (modes & VCM_H264_MODE_1) { - aSupportedCodecs[count] = RTP_H264_P1; - count++; - } - if (modes & VCM_H264_MODE_0) { - aSupportedCodecs[count] = RTP_H264_P0; - count++; - } - } - if ( codec_mask & VCM_CODEC_RESOURCE_H263) { - aSupportedCodecs[count] = RTP_H263; - count++; - } - return count; -} - -/* - * sip_config_local_supported_codecs_get() - * - * Get the locally supported codec list. - */ -uint16_t -sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen, boolean isOffer) -{ - uint16_t count = 0; - rtp_ptype pref_codec; - int codec_mask; - int hw_codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX_HW); - int gmp_codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX_GMP); - - if ( isOffer ) { - codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX); - } else { - /* we are trying to match the answer then we - already have the rx stream open */ - //codec_mask = vcmGetVideoCodecList(DSP_ENCODEONLY); - codec_mask = vcmGetVideoCodecList(VCM_DSP_IGNORE); - } - // prefer HW codecs over SW - count = sip_config_video_add_codecs(aSupportedCodecs, - supportedCodecsLen, hw_codec_mask); - // Now add any codecs that weren't in the initial list - codec_mask &= ~hw_codec_mask; - count += sip_config_video_add_codecs(&aSupportedCodecs[count], - supportedCodecsLen, codec_mask); - // Now add any GMP codecs that aren't already in - gmp_codec_mask &= ~(hw_codec_mask | codec_mask); - count += sip_config_video_add_codecs(&aSupportedCodecs[count], - supportedCodecsLen, gmp_codec_mask); - - // Now promote the preferred codec if any - pref_codec = sip_config_preferred_codec(); - if (pref_codec != RTP_NONE) { - int i,j; - for (i = 1; i < count; i++) { - if (aSupportedCodecs[i] == pref_codec) { - // bump it to the front; bump all the rest down - for (j = i; j > 0; j--) { - aSupportedCodecs[j] = aSupportedCodecs[j-1]; - } - aSupportedCodecs[0] = pref_codec; - return count; - } - } - // preferred not found, oh well - } - return count; -} - -/** - * The function fills in the given codec array based on the - * platform bit mask of codecs. Note, that the enumerated list - * produced is also in the preferred order. - * - * @param[in] codec_mask - platform bit mask corresponding to the - * codecs. - * @param[in/out] codecs - pointer to array of for storing the - * output of the enumerated codec based on - * bit set in the codec_mask. - * - * @return None. - * - * @pre (codec_table != NULL) - * @pre storge of codec_table must be last enough to holds - * supported codec in the bit mask. - */ -static void -config_set_current_codec_table (int codec_mask, rtp_ptype *codecs) -{ - int idx = 0; - - if (codec_mask & VCM_CODEC_RESOURCE_OPUS) { - codecs[idx] = RTP_OPUS; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_G722) { - codecs[idx] = RTP_G722; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_G711) { - codecs[idx] = RTP_PCMU; - idx++; - codecs[idx] = RTP_PCMA; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_G729A) { - codecs[idx] = RTP_G729; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_LINEAR) { - codecs[idx] = RTP_L16; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_iLBC) { - codecs[idx] = RTP_ILBC; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_iSAC) { - codecs[idx] = RTP_ISAC; - idx++; - } - - codecs[idx] = RTP_NONE; - - return; -} - -/* - * sip_config_local_dtmf_dblevels_get() - * - * Get the DTMF DB levels - */ -uint32_t -sip_config_local_dtmf_dblevels_get (void) -{ - int value; - - config_get_value(CFGID_DTMF_DB_LEVEL, &value, sizeof(value)); - switch (value) { - case 0: - return 0; // Mute - case 1: - return 2900; // 6 dB down - case 2: - return 4096; // 3 dB down - case 3: - return 5786; // Nominal amplitude - // (-8.83 dBm0 to network, -11.83 dBm0 local) - case 4: - return 8173; // 3 dB up - case 5: - return 11544; // 6 dB up - default: - return 5786; // Nominal amplitude - } -} - -/* - * sip_config_get_line_by_called_number - * - * Return the line by the given called_number - */ -line_t sip_config_get_line_by_called_number (line_t start_line, const char *called_number) -{ - int i; - line_t max_lines; - line_t line = 0; - char line_name[MAX_LINE_NAME_SIZE]; - char contact[MAX_LINE_CONTACT_SIZE]; - char *name; - - max_lines = sip_config_local_line_get(); - - /* - * Check the called number for the E.164 "+" - * and ignore it if present. - */ - if (called_number[0] == '+') { - called_number++; - } - - for (i = start_line; i <= max_lines; i++) { - if (sip_config_check_line((line_t)i)) { - config_get_line_string(CFGID_LINE_NAME, line_name, i, - sizeof(line_name)); - /* - * Check the configured line name for the E.164 "+" - * and ignore it if present. - */ - name = &line_name[0]; - if (line_name[0] == '+') { - name++; - } - - if (cpr_strcasecmp(called_number, name) == 0) { - line = (line_t)i; - break; - } - } - } - - // If line not found - check with contact list - if (line == 0) { - for (i = start_line; i <= max_lines; i++) { - if (sip_config_check_line((line_t)i)) { - config_get_line_string(CFGID_LINE_CONTACT, contact, i, - sizeof(contact)); - if (cpr_strcasecmp(called_number, contact) == 0) { - line = (line_t)i; - break; - } - } - } - } - - return (line); -} - -/********************************************************* - * - * SIP Config API - * The routines below with the "prot" prefix are called - * by the config system. The calls that start with "sip" - * are helper functions for the SIP implementation of the - * "prot" API. - * - *********************************************************/ - -/* - * sip_minimum_config_check() - * - * Return indication if the SIP minimum configuration - * requirements have been met. - * Returns 0 if minimum config is met - * Returns non-zero if minimum config has not been met - * (eg. missing at least 1 required parameter) - */ -int -sip_minimum_config_check (void) -{ - char str_val[MAX_IPADDR_STR_LEN]; - char line_name[MAX_LINE_NAME_SIZE]; - int value; - - /* - * Make sure that line 1 is configured - */ - config_get_line_string(CFGID_LINE_NAME, line_name, 1, sizeof(line_name)); - if ((strcmp(line_name, UNPROVISIONED) == 0) || (line_name[0] == '\0')) { - return -1; - } - - config_get_line_string(CFGID_PROXY_ADDRESS, str_val, 1, MAX_IPADDR_STR_LEN); - if ((strcmp(str_val, UNPROVISIONED) == 0) || (str_val[0] == '\0')) { - return -1; - } - - config_get_line_value(CFGID_PROXY_PORT, &value, sizeof(value), 1); - if (value == 0) { - return -1; - } - - return 0; -} - -/* - * prot_config_change_notify() - * Let the SIP stack know that a config change has occurred. - * - */ -int -prot_config_change_notify (int notify_type) -{ - if (SIPTaskProcessConfigChangeNotify(notify_type) < 0) { -//CPR TODO: need reference for - CCSIP_DEBUG_ERROR(PLAT_COMMON_F_PREFIX"SIPTaskProcessConfigChangeNotify() " - "returned error.\n", "prot_config_change_notify"); - } - - return (TRUE); -} - -/* - * prot_config_check_line_name() - * Makes sure that there are no spaces in the SIP Line Names - * - * Returns: TRUE if the Name is Valid - * FALSE if the Name is Invalid - * - */ -boolean -prot_config_check_line_name (char *line_name) -{ - while ((*line_name != ' ') && (*line_name != NUL)) { - line_name++; - } - - if (*line_name == ' ') { - return (FALSE); - } - return (TRUE); -} - -/* - * prot_sanity_check_config_settings() - * - , Louis* Checks the sanity of the protocol config block values - * and sets them to defaults if they are incorrect. - */ -int -prot_sanity_check_config_settings (void) -{ - int retval = 0; - return retval; -} - - -/* - * prot_shutdown() - * - * Shut down the protocol stack. - */ - -void -prot_shutdown (void) -{ - sip_shutdown(); -} diff --git a/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h b/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h deleted file mode 100755 index dd4310e14fc..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h +++ /dev/null @@ -1,300 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PROT_CONFIGMGR_H_ -#define _PROT_CONFIGMGR_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "rtp_defs.h" -#include "ccsip_platform.h" -#include "configmgr.h" -#include "cfgfile_utils.h" -#include "phone_platform_constants.h" -#include "cc_config.h" -#include "cc_constants.h" -#include "ccsdp.h" - -#define UNPROVISIONED "UNPROVISIONED" - -/********************************************************* - * - * The following parameters set Config system settings - * for SIP - * - *********************************************************/ -#define HWTYPE "SIP" -#define MAX_LINE_NAME_SIZE 128 -#define AUTH_NAME_SIZE 129 -#define MAX_LINE_PASSWORD_SIZE 32 -#define MAX_LINE_DISPLAY_SIZE 32 -#define MAX_LINE_CONTACT_SIZE 128 -#define MAX_LINE_AUTO_ANS_MODE_SIZE 32 -#define MAX_REG_USER_INFO_LEN 32 -#define MAX_JOIN_DXFER_POLICY_SIZE 40 -#define MAX_EXTERNAL_NUMBER_MASK_SIZE 40 - -/********************************************************* - *!!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * TNP SIP Phone Configuration IDs - * - *!!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * The following macro definitions are defined in cc_config.h. - * Change should be made in the cc_config.h and add reference here. - * - * <------ Original notes ------> - * Before changing this code, please read the following: - * - * The Configuration system for the TNP phones is simply a cache - * that exists for the GSM/SIP DLL to use. The property values are - * sent from Java across the JNI to the cache. This prevents - * the SIP and GSM code from having to suffer through a JNI call - * every time they wish to retrieve a configuration parameter. - * - * These ID's need to match the definitions in JplatConfigConstants.java - * - * To add a new value to the table, - * In general, you will have to: - * - * 1) Create an index for the new CFG param below - * 2) Update prot_cfg_table either in prot_cfgmgr_private.h - * or in prot_configmgr.c (for line specific params) - * 3) Update JPlatConfigConstants.h with the new ID - * 4) Create a property on JAVA side and update it from XML config - * 5) Update show_cfg_cmd if adding a new line param - * - *!!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - *********************************************************/ - -/* Keep non line specific params here */ - -#define CFGID_MEDIA_PORT_RANGE_START CFGID_MEDIA_PORT_RANGE_START_INT -#define CFGID_MEDIA_PORT_RANGE_END CFGID_MEDIA_PORT_RANGE_END_INT -#define CFGID_CALLERID_BLOCKING CFGID_CALLERID_BLOCKING_BOOL -#define CFGID_ANONYMOUS_CALL_BLOCK CFGID_ANONYMOUS_CALL_BLOCK_BOOL -#define CFGID_DND_CALL_ALERT CFGID_DND_CALL_ALERT_BYTE -#define CFGID_DND_REMINDER_TIMER CFGID_DND_REMINDER_TIMER_INT -#define CFGID_PREFERRED_CODEC CFGID_PREFERRED_CODEC_STRING -#define CFGID_DTMF_OUTOFBAND CFGID_DTMF_OUTOFBAND_STRING -#define CFGID_DTMF_AVT_PAYLOAD CFGID_DTMF_AVT_PAYLOAD_INT -#define CFGID_DTMF_DB_LEVEL CFGID_DTMF_DB_LEVEL_INT - -#define CFGID_SIP_RETX CFGID_SIP_RETX_INT -#define CFGID_SIP_INVITE_RETX CFGID_SIP_INVITE_RETX_INT -#define CFGID_TIMER_T1 CFGID_TIMER_T1_INT -#define CFGID_TIMER_T2 CFGID_TIMER_T2_INT -#define CFGID_TIMER_INVITE_EXPIRES CFGID_TIMER_INVITE_EXPIRES_INT -#define CFGID_TIMER_REGISTER_EXPIRES CFGID_TIMER_REGISTER_EXPIRES_INT - -#define CFGID_PROXY_REGISTER CFGID_PROXY_REGISTER_BOOL -#define CFGID_PROXY_BACKUP CFGID_PROXY_BACKUP_STRING -#define CFGID_PROXY_BACKUP_PORT CFGID_PROXY_BACKUP_PORT_INT -#define CFGID_PROXY_EMERGENCY CFGID_PROXY_EMERGENCY_STRING -#define CFGID_PROXY_EMERGENCY_PORT CFGID_PROXY_EMERGENCY_PORT_INT -#define CFGID_OUTBOUND_PROXY CFGID_OUTBOUND_PROXY_STRING -#define CFGID_OUTBOUND_PROXY_PORT CFGID_OUTBOUND_PROXY_PORT_INT - -#define CFGID_NAT_RECEIVED_PROCESSING CFGID_NAT_RECEIVED_PROCESSING_BOOL -#define CFGID_REG_USER_INFO CFGID_REG_USER_INFO_STRING -#define CFGID_CNF_JOIN_ENABLE CFGID_CNF_JOIN_ENABLE_BOOL -#define CFGID_REMOTE_PARTY_ID CFGID_REMOTE_PARTY_ID_BOOL -#define CFGID_SEMI_XFER CFGID_SEMI_XFER_BOOL -#define CFGID_CALL_HOLD_RINGBACK CFGID_CALL_HOLD_RINGBACK_BOOL -#define CFGID_STUTTER_MSG_WAITING CFGID_STUTTER_MSG_WAITING_BOOL -/** - * The CFGID_CFWD_URL was consolidated for RT and CIUS and should be for TNP as well. - */ -#define CFGID_CFWD_URL CFGID_CFWD_URL_STRING - -#define CFGID_CALL_STATS CFGID_CALL_STATS_BOOL -#define CFGID_LOCAL_CFWD_ENABLE CFGID_LOCAL_CFWD_ENABLE_BOOL -#define CFGID_TIMER_REGISTER_DELTA CFGID_TIMER_REGISTER_DELTA_INT -#define CFGID_SIP_MAX_FORWARDS CFGID_SIP_MAX_FORWARDS_INT -#define CFGID_2543_HOLD CFGID_2543_HOLD_BOOL - -#define CFGID_CCM1_ADDRESS CFGID_CCM1_ADDRESS_STRING -#define CFGID_CCM2_ADDRESS CFGID_CCM2_ADDRESS_STRING -#define CFGID_CCM3_ADDRESS CFGID_CCM3_ADDRESS_STRING - -// Note: IPv6 Not currently supported on Cius -#define CFGID_CCM1_IPV6_ADDRESS CFGID_CCM1_IPV6_ADDRESS_STRING -#define CFGID_CCM2_IPV6_ADDRESS CFGID_CCM2_IPV6_ADDRESS_STRING -#define CFGID_CCM3_IPV6_ADDRESS CFGID_CCM3_IPV6_ADDRESS_STRING - -#define CFGID_CCM1_SIP_PORT CFGID_CCM1_SIP_PORT_INT -#define CFGID_CCM2_SIP_PORT CFGID_CCM2_SIP_PORT_INT -#define CFGID_CCM3_SIP_PORT CFGID_CCM3_SIP_PORT_INT - -#define CFGID_CCM1_SEC_LEVEL CFGID_CCM1_SEC_LEVEL_INT -#define CFGID_CCM2_SEC_LEVEL CFGID_CCM2_SEC_LEVEL_INT -#define CFGID_CCM3_SEC_LEVEL CFGID_CCM3_SEC_LEVEL_INT - -#define CFGID_CCM1_IS_VALID CFGID_CCM1_IS_VALID_BOOL -#define CFGID_CCM2_IS_VALID CFGID_CCM2_IS_VALID_BOOL -#define CFGID_CCM3_IS_VALID CFGID_CCM3_IS_VALID_BOOL - -#define CFGID_CCM_TFTP_IP_ADDR CFGID_CCM_TFTP_IP_ADDR_STRING -#define CFGID_CCM_TFTP_PORT CFGID_CCM_TFTP_PORT_INT -#define CFGID_CCM_TFTP_IS_VALID CFGID_CCM_TFTP_IS_VALID_BOOL -#define CFGID_CCM_TFTP_SEC_LEVEL CFGID_CCM_TFTP_SEC_LEVEL_INT - -#define CFGID_CONN_MONITOR_DURATION CFGID_CONN_MONITOR_DURATION_INT -#define CFGID_CALL_PICKUP_URI CFGID_CALL_PICKUP_URI_STRING -#define CFGID_CALL_PICKUP_LIST_URI CFGID_CALL_PICKUP_LIST_URI_STRING -#define CFGID_CALL_PICKUP_GROUP_URI CFGID_CALL_PICKUP_GROUP_URI_STRING -#define CFGID_MEET_ME_SERVICE_URI CFGID_MEET_ME_SERVICE_URI_STRING -#define CFGID_CALL_FORWARD_URI CFGID_CALL_FORWARD_URI_STRING -#define CFGID_ABBREVIATED_DIAL_URI CFGID_ABBREVIATED_DIAL_URI_STRING -#define CFGID_CALL_LOG_BLF_ENABLED CFGID_CALL_LOG_BLF_ENABLED_BOOL -#define CFGID_REMOTE_CC_ENABLED CFGID_REMOTE_CC_ENABLED_BOOL -#define CFGID_RETAIN_FORWARD_INFORMATION CFGID_RETAIN_FORWARD_INFORMATION_BOOL - -#define CFGID_TIMER_KEEPALIVE_EXPIRES CFGID_TIMER_KEEPALIVE_EXPIRES_INT -#define CFGID_TIMER_SUBSCRIBE_EXPIRES CFGID_TIMER_SUBSCRIBE_EXPIRES_INT -#define CFGID_TIMER_SUBSCRIBE_DELTA CFGID_TIMER_SUBSCRIBE_DELTA_INT -#define CFGID_TRANSPORT_LAYER_PROT CFGID_TRANSPORT_LAYER_PROT_INT -#define CFGID_KPML_ENABLED CFGID_KPML_ENABLED_INT - -#define CFGID_NAT_ENABLE CFGID_NAT_ENABLE_BOOL -#define CFGID_NAT_ADDRESS CFGID_NAT_ADDRESS_STRING -#define CFGID_VOIP_CONTROL_PORT CFGID_VOIP_CONTROL_PORT_INT -#define CFGID_MY_IP_ADDR CFGID_MY_IP_ADDR_STRING -#define CFGID_MY_MAC_ADDR CFGID_MY_MAC_ADDR_STRING -#define CFGID_ENABLE_VAD CFGID_ENABLE_VAD_BOOL - -#define CFGID_AUTOANSWER_IDLE_ALTERNATE CFGID_AUTOANSWER_IDLE_ALTERNATE_BOOL -#define CFGID_AUTOANSWER_TIMER CFGID_AUTOANSWER_TIMER_INT -#define CFGID_AUTOANSWER_OVERRIDE CFGID_AUTOANSWER_OVERRIDE_BOOL - -#define CFGID_OFFHOOK_TO_FIRST_DIGIT_TIMER CFGID_OFFHOOK_TO_FIRST_DIGIT_TIMER_INT -#define CFGID_CALL_WAITING_SILENT_PERIOD CFGID_CALL_WAITING_SILENT_PERIOD_INT -#define CFGID_RING_SETTING_BUSY_POLICY CFGID_RING_SETTING_BUSY_POLICY_INT -#define CFGID_DSCP_FOR_CALL_CONTROL CFGID_DSCP_FOR_CALL_CONTROL_INT -#define CFGID_SPEAKER_ENABLED CFGID_SPEAKER_ENABLED_BOOL -#define CFGID_XFR_ONHOOK_ENABLED CFGID_XFR_ONHOOK_ENABLED_BOOL -#define CFGID_ROLLOVER CFGID_ROLLOVER_INT -#define CFGID_LOAD_FILE CFGID_LOAD_FILE_STRING - -#define CFGID_BLF_ALERT_TONE_IDLE CFGID_BLF_ALERT_TONE_IDLE_INT -#define CFGID_BLF_ALERT_TONE_BUSY CFGID_BLF_ALERT_TONE_BUSY_INT -#define CFGID_AUTO_PICKUP_ENABLED CFGID_AUTO_PICKUP_ENABLED_BOOL - -#define CFGID_JOIN_ACROSS_LINES CFGID_JOIN_ACROSS_LINES_INT - -#define CFGID_MY_ACTIVE_MAC_ADDR CFGID_MY_ACTIVE_MAC_ADDR_STRING -#define CFGID_DSCP_AUDIO CFGID_DSCP_AUDIO_INT -#define CFGID_DEVICE_NAME CFGID_DEVICE_NAME_STRING -#define CFGID_USER_AGENT CFGID_USER_AGENT_STRING -#define CFGID_MODEL_NUMBER CFGID_MODEL_NUMBER_STRING -#define CFGID_DSCP_VIDEO CFGID_DSCP_VIDEO_INT - -#define CFGID_IP_ADDR_MODE CFGID_IP_ADDR_MODE_INT -#define CFGID_INTER_DIGIT_TIMER CFGID_INTER_DIGIT_TIMER_INT - -// Note - EMCC not currently supported on CIUS -#define CFGID_EMCC_MODE CFGID_EMCC_MODE_BOOL -#define CFGID_VISITING_EM_PORT CFGID_VISITING_EM_PORT_INT -#define CFGID_VISITING_EM_IP CFGID_VISITING_EM_IP_STRING - -#define CFGID_CCM_EXTERNAL_NUMBER_MASK CFGID_CCM_EXTERNAL_NUMBER_MASK_STRING -#define CFGID_MEDIA_IP_ADDR CFGID_MEDIA_IP_ADDR_STRING - -/* All non Line specific params should be added above */ -/* All Line specific params should be added below */ - -#define CFGID_LINE_FEATURE CFGID_LINE_FEATURE_INT -#define CFGID_LINE_INDEX CFGID_LINE_INDEX_INT -#define CFGID_LINE_NAME CFGID_LINE_NAME_STRING -#define CFGID_LINE_AUTHNAME CFGID_LINE_AUTHNAME_STRING -#define CFGID_LINE_PASSWORD CFGID_LINE_PASSWORD_STRING -#define CFGID_LINE_DISPLAYNAME CFGID_LINE_DISPLAYNAME_STRING -#define CFGID_LINE_CONTACT CFGID_LINE_CONTACT_STRING -#define CFGID_PROXY_ADDRESS CFGID_PROXY_ADDRESS_STRING -#define CFGID_PROXY_PORT CFGID_PROXY_PORT_INT -#define CFGID_LINE_AUTOANSWER_ENABLED CFGID_LINE_AUTOANSWER_ENABLED_BYTE -#define CFGID_LINE_AUTOANSWER_MODE CFGID_LINE_AUTOANSWER_MODE_STRING -#define CFGID_LINE_CALL_WAITING CFGID_LINE_CALL_WAITING_BYTE -#define CFGID_LINE_MSG_WAITING_LAMP CFGID_LINE_MSG_WAITING_LAMP_BYTE -#define CFGID_LINE_MESSAGE_WAITING_AMWI CFGID_LINE_MESSAGE_WAITING_AMWI_BYTE -#define CFGID_LINE_RING_SETTING_IDLE CFGID_LINE_RING_SETTING_IDLE_BYTE -#define CFGID_LINE_RING_SETTING_ACTIVE CFGID_LINE_RING_SETTING_ACTIVE_BYTE -#define CFGID_LINE_CFWDALL CFGID_LINE_CFWDALL_STRING - -#define CFGID_LINE_SPEEDDIAL_NUMBER CFGID_LINE_SPEEDDIAL_NUMBER_STRING -#define CFGID_LINE_RETRIEVAL_PREFIX CFGID_LINE_RETRIEVAL_PREFIX_STRING -#define CFGID_LINE_MESSAGES_NUMBER CFGID_LINE_MESSAGES_NUMBER_STRING -#define CFGID_LINE_FWD_CALLER_NAME_DIPLAY CFGID_LINE_FWD_CALLER_NAME_DIPLAY_BOOL -#define CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY_BOOL -#define CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY_BOOL -#define CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY_BOOL -#define CFGID_LINE_FEATURE_OPTION_MASK CFGID_LINE_FEATURE_OPTION_MASK_INT -#define CFGID_P2PSIP CFGID_P2PSIP_BOOL -#define CFGID_VERSION CFGID_VERSION_STRING -#define CFGID_SDPMODE CFGID_SDPMODE_BOOL -#define CFGID_RTCPMUX CFGID_RTCPMUX_BOOL -#define CFGID_RTPSAVPF CFGID_RTPSAVPF_BOOL -#define CFGID_MAXAVBITRATE CFGID_MAXAVBITRATE_BOOL -#define CFGID_MAXCODEDAUDIOBW CFGID_MAXCODEDAUDIOBW_BOOL -#define CFGID_USEDTX CFGID_USEDTX_BOOL -#define CFGID_STEREO CFGID_STEREO_BOOL -#define CFGID_USEINBANDFEC CFGID_USEINBANDFEC_BOOL -#define CFGID_CBR CFGID_CBR_BOOL -#define CFGID_MAXPTIME CFGID_MAXPTIME_BOOL -#define CFGID_SCTP_PORT CFGID_SCTP_PORT_INT -#define CFGID_NUM_DATA_STREAMS CFGID_NUM_DATA_STREAMS_INT - -/********************************************************* - * - * Value Definitions - * - *********************************************************/ -// Line feature -typedef enum { - cfgLineFeatureNone = CC_LINE_FEATURE_NONE, - cfgLineFeatureRedial = CC_LINE_FEATURE_REDIAL, - cfgLineFeatureSpeedDial = CC_LINE_FEATURE_SPEEDDIAL, - cfgLineFeatureDN = CC_LINE_FEATURE_DN, - cfgLineFeatureService = CC_LINE_FEATURE_SERVICE, - cfgLineFeatureSpeedDialBLF = CC_LINE_FEATURE_SPEEDDIALBLF, - cfgLineFeatureMaliciousCallID = CC_LINE_FEATURE_MALICIOUSCALLID, - cfgLineFeatureAllCalls = CC_LINE_FEATURE_ALLCALLS, - cfgLineFeatureAnswerOldest = CC_LINE_FEATURE_ANSWEROLDEST, - cfgLineFeatureServices = CC_LINE_FEATURE_SERVICES, - cfgLineFeatureBLF = CC_LINE_FEATURE_BLF -} cfgLineFeatureType_e; - -/********************************************************* - * - * Function Prototypes - * - *********************************************************/ -void protocol_cfg_init(void); -void sip_config_get_net_device_ipaddr(cpr_ip_addr_t *ip_addr); -void sip_config_get_net_ipv6_device_ipaddr(cpr_ip_addr_t *ip_addr); -void sip_config_get_nat_ipaddr(cpr_ip_addr_t *ip_addr); -void sip_config_set_nat_ipaddr(cpr_ip_addr_t *ip_address); -uint16_t sip_config_local_supported_codecs_get(rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen); -uint16_t sip_config_video_supported_codecs_get(rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen, boolean isOffer); - -boolean prot_config_check_line_name(char *line_name); -//const key_table_entry_t * sip_config_local_codec_entry_find(const rtp_ptype codec); -line_t sip_config_get_button_from_line(line_t line); -line_t sip_config_get_line_from_button(line_t button); -boolean sip_config_check_line(line_t line); -line_t sip_config_local_line_get(void); -void sip_config_get_display_name(line_t line, char *buffer, int buffer_len); -line_t sip_config_get_line_by_called_number(line_t start_line, const char *called_number); -int sip_minimum_config_check(void); -void config_set_codec_table(int codec_mask); -int sip_config_get_keepalive_expires(); -rtp_ptype sip_config_preferred_codec(void); -uint32_t config_get_video_max_fs(const rtp_ptype codec); -uint32_t config_get_video_max_fr(const rtp_ptype codec); -uint32_t config_get_video_max_mbps(const rtp_ptype codec); -uint32_t config_get_video_max_br(const rtp_ptype codec); - -#endif /* PROT_CONFIGMGR_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/common/resource_manager.c b/media/webrtc/signaling/src/sipcc/core/common/resource_manager.c deleted file mode 100644 index c1cb043b015..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/resource_manager.c +++ /dev/null @@ -1,300 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "resource_manager.h" -#include "phone_debug.h" - -#define RM_NUM_ELEMENTS_PER_MAP 32 -#define rm_get_table_index(a) (a / RM_NUM_ELEMENTS_PER_MAP) -#define rm_get_map_offset(a) (a % RM_NUM_ELEMENTS_PER_MAP) - -/* - * rm_clear_all_elements - * - * Description: - * This function clears all members of the specified resource manager - * - * Parameters: - * rm_p - pointer to the resource manager to be cleared - * - * Returns: - * None - */ -void -rm_clear_all_elements (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_clear_all_elements"; - uint16_t i; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.", fname); - return; - } - - for (i = 0; i < rm_p->max_index; i++) { - rm_p->table[i] = 0; - } -} - -/* - * rm_clear_element - * - * Description: - * This function clears a single element from the specified resource manager - * - * Parameters: - * rm_p - pointer to the resource manager to be cleared - * element - element id of element to be cleared - * - * Returns: - * None - */ -void -rm_clear_element (resource_manager_t * rm_p, int16_t element) -{ - static const char fname[] = "rm_clear_elements"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.", fname); - return; - } - - if (element < 0 || element >= rm_p->max_element) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"element value %d invalid. Max value is %d.", - fname, element, rm_p->max_element - 1); - return; - } - - rm_p->table[rm_get_table_index(element)] &= - (~(1 << rm_get_map_offset(element))); -} - -/* - * rm_set_element - * - * Description: - * This function sets the bit representing the specified element - * in the specified resource manager. - * - * Parameters: - * rm_p - pointer to the resource manager - * element - element id of element to be set - * - * Returns: - * None - */ -void -rm_set_element (resource_manager_t *rm_p, int16_t element) -{ - static const char fname[] = "rm_set_element"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.", fname); - return; - } - - if (element < 0 || element >= rm_p->max_element) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"element value %d invalid. Max value %d.", - fname, element, rm_p->max_element - 1); - return; - } - - rm_p->table[rm_get_table_index(element)] |= - (1 << rm_get_map_offset(element)); -} - -/* - * rm_is_element_set - * - * Description: - * This function checks if the specified element in the specified - * resource manager is set. - * - * Parameters: - * rm_p - pointer to the resource manager. - * element - element id of element to be checked. - * - * Returns: - * TRUE if element is set, else FALSE - */ -boolean -rm_is_element_set (resource_manager_t *rm_p, int16_t element) -{ - static const char fname[] = "rm_is_element_set"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.", fname); - return FALSE; - } - - if (element < 0 || element >= rm_p->max_element) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"element value %d invalid. Max value %d.", - fname, element, rm_p->max_element - 1); - return FALSE; - } - - if (rm_p->table[rm_get_table_index(element)] & - (1 << rm_get_map_offset(element))) { - return TRUE; - } - - return FALSE; -} - -/* - * rm_get_free_element - * - * Description: - * This function walks through the members of the resource manager and - * attempts to locate a free element. If a free element is found, the - * element's associated bit is set in the resource manager and the - * element id is returned. - * - * Parameters: - * rm_p - pointer to the resource manager. - * - * Returns: - * If an element is available, a element id (from zero to max element) - * If no element is available, -1 is returned. - */ -int16_t -rm_get_free_element (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_get_free_element"; - int16_t element = -1; - uint16_t i, j; - uint32_t max_map = 0; - - max_map = ~max_map; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.", fname); - return -1; - } - - for (i = 0; i < rm_p->max_index && element == -1; i++) { - if (rm_p->table[i] != max_map) { - for (j = 0; j < RM_NUM_ELEMENTS_PER_MAP && element == -1; j++) { - if (!(rm_p->table[i] & (1 << j))) { - element = i * RM_NUM_ELEMENTS_PER_MAP + j; - if (element < rm_p->max_element) { - rm_set_element(rm_p, element); - } - } - } - } - } - - if (element >= rm_p->max_element) { - element = -1; - } - return (element); -} - -/* - * rm_show - * - * Description: - * Utility function used to dump the contents of the resource manager. - * - * Parameters: - * rm_p - pointer to the resource manager. - * - * Returns: - * none - */ -void -rm_show (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_show"; - int16_t element = 0; - uint16_t i, j; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.", fname); - return; - } - - for (i = 0; i < rm_p->max_index; i++) { - for (j = 0; j < RM_NUM_ELEMENTS_PER_MAP; j++) { - if (rm_p->table[i] & (1 << j)) { - element = (i * RM_NUM_ELEMENTS_PER_MAP) + j; - TNP_DEBUG(DEB_F_PREFIX"rm map: %d", DEB_F_PREFIX_ARGS(RM, fname), element); - } - } - } -} - -/* - * rm_create - * - * Description: - * Allocates and initializes a new resource manager - * - * Parameters: - * max_element - Maximum number of elements the resource manager - * is required to track - * - * Returns: - * If successful, pointer to the newly allocated resource manager - * If not successful, NULL - */ -resource_manager_t * -rm_create (int16_t max_element) -{ - static const char fname[] = "rm_create"; - resource_manager_t *rm_p; - - if (max_element < 0) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"invalid max element %d received.", fname, - max_element); - return NULL; - } - - rm_p = (resource_manager_t *) cpr_malloc(sizeof(resource_manager_t)); - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"unable to allocate resource manager.", fname); - return NULL; - } - - rm_p->max_element = max_element; - rm_p->max_index = max_element / RM_NUM_ELEMENTS_PER_MAP + 1; - - rm_p->table = (uint32_t *) - cpr_malloc(rm_p->max_index * RM_NUM_ELEMENTS_PER_MAP); - if (!rm_p->table) { - free(rm_p); - return NULL; - } - rm_clear_all_elements(rm_p); - return rm_p; -} - -/* - * rm_free - * - * Description: - * This function frees the memory allocated for the specified resource manager. - * - * Parameters: - * rm_p - pointer to the resource manager. - * - * Returns: - * none - */ -void -rm_destroy (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_destroy"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.", fname); - return; - } - - cpr_free(rm_p->table); - cpr_free(rm_p); -} diff --git a/media/webrtc/signaling/src/sipcc/core/common/resource_manager.h b/media/webrtc/signaling/src/sipcc/core/common/resource_manager.h deleted file mode 100644 index a0dfd925cb0..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/resource_manager.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _RM_MGR_H__ -#define _RM_MGR_H__ - -typedef struct resource_manager { - int16_t max_element; - int16_t max_index; - uint32_t *table; -} resource_manager_t; - -void rm_clear_all_elements(resource_manager_t *rm); -void rm_clear_element(resource_manager_t *rm, int16_t element); -void rm_set_element(resource_manager_t *rm, int16_t element); -boolean rm_is_element_set(resource_manager_t *rm, int16_t element); -int16_t rm_get_free_element(resource_manager_t *rm); -void rm_show(resource_manager_t *rm); -resource_manager_t *rm_create(int16_t max_element); -void rm_destroy(resource_manager_t *rm); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/common/sip_socket_api.c b/media/webrtc/signaling/src/sipcc/core/common/sip_socket_api.c deleted file mode 100755 index 15952840f18..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/sip_socket_api.c +++ /dev/null @@ -1,100 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr.h" -#include "cpr_socket.h" -#include "errno.h" -#include "plat_api.h" - -/** - * sipSocketSend - * - * @brief The sipSocketSend() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the send. - * - * - */ -ssize_t -sipSocketSend (cpr_socket_t soc, - CONST void *buf, - size_t len, - int32_t flags, - boolean secure) -{ -// if (secure) { -// return platSecSocSend (soc, buf, len); -// } else { - return cprSend(soc, buf, len, flags); -// } -} - -/** - * sipSocketRecv - * - * @brief The sipSocketRecv() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the recv. - */ -ssize_t -sipSocketRecv (cpr_socket_t soc, - void * RESTRICT buf, - size_t len, - int32_t flags, - boolean secure) -{ -// if (secure) { -// return platSecSocRecv (soc, buf, len); -// } else { - return cprRecv(soc, buf, len, flags); -// } -} - -/** - * sipSocketClose - * - * @brief The sipSocketClose() function is a wrapper used by the sipstack to - * close a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc - The socket that needs to be destroyed - * - * @return CPR_SUCCESS on success otherwise, CPR_FAILURE. cpr_errno needs to be set in this case. - * - * @note The possible error values this function should return are - * @li [CPR_EBADF] socket is not a valid socket descriptor. - */ -cpr_status_e -sipSocketClose (cpr_socket_t soc, - boolean secure) -{ -// if (secure) { -// return platSecSocClose (soc); -// } else { - return cprCloseSocket(soc); -// } -} - diff --git a/media/webrtc/signaling/src/sipcc/core/common/subscription_handler.c b/media/webrtc/signaling/src/sipcc/core/common/subscription_handler.c deleted file mode 100755 index dd177cbb160..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/subscription_handler.c +++ /dev/null @@ -1,342 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cc_types.h" -#include "phone_platform_constants.h" -#include "cc_constants.h" -#include "phone_debug.h" -#include "prot_configmgr.h" -#include "cc_blf.h" -#include "ccapi_snapshot.h" - -#define SPEEDDIAL_START_BUTTON_NUMBER 2 - -static unsigned char transactionIds[MAX_REG_LINES]; -static boolean displayBLFState = TRUE; -static cc_blf_state_t blfStates[MAX_REG_LINES]; -static boolean isBLFHandlerRunning = FALSE; -static boolean isAvailable = FALSE; - -#ifndef INT_MAX -#define INT_MAX 2147483647 -#endif - -static void ccBLFHandlerInitialized(); - -/* - * Function: sub_hndlr_isAlertingBLFState - * - * Description: returns if the BLF state is "alerting" - * - * Parameters: - * inst - line button number. - * - * Returns: TRUE/FALSE - */ -boolean sub_hndlr_isAlertingBLFState(int inst) -{ - static const char fname[] = "sub_hndlr_isAlertingBLFState"; - - if ((displayBLFState == TRUE) && (blfStates[inst - 1] == CC_SIP_BLF_ALERTING)) { - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isAlerting=TRUE", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - - return TRUE; - } - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isAlerting=FALSE", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - return FALSE; -} - -/* - * Function: sub_hndlr_isInUseBLFState - * - * Description: returns if the BLF state is "in use" - * - * Parameters: - * inst - line button number. - * - * Returns: TRUE/FALSE - */ -boolean sub_hndlr_isInUseBLFState(int inst) -{ - static const char fname[] = "sub_hndlr_isInUseBLFState"; - - if ((displayBLFState == TRUE) && (blfStates[inst - 1] == CC_SIP_BLF_INUSE)) { - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isInUse=TRUE", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - return TRUE; - } - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isInUse=FALSE", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - return FALSE; -} - -/* - * Function: sub_hndlr_isAvailable - * - * Description: returns if the subscription handler is available. - * - * Parameters: none. - * - * Returns: TRUE/FALSE - */ -boolean sub_hndlr_isAvailable() -{ - static const char fname[] = "sub_hndlr_isAvailable"; - - CCAPP_DEBUG(DEB_F_PREFIX"isAvailable=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - isAvailable); - return isAvailable; -} - -static unsigned short get_new_trans_id() -{ - static unsigned short curr_trans_id = 0; - - if (++curr_trans_id == 0) { - curr_trans_id = 1; - } - - return curr_trans_id; -} - -/* - * Function: sub_hndlr_start - * - * Description: does blf subscriptions upon registration. - * - * Parameters: none. - * - * Returns: void - */ -void sub_hndlr_start() -{ - static const char fname[] = "sub_hndlr_start"; - int i; - cc_uint32_t lineFeature = 0; - cc_uint32_t featureOptionMask = 0; - char speedDialNumber[MAX_LINE_NAME_SIZE] = {0}; - char primaryLine[MAX_LINE_NAME_SIZE] = {0}; - int transId; - - CCAPP_DEBUG(DEB_F_PREFIX"entering", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - /* let the system know that subscription handler is available. */ - isAvailable = TRUE; - - /* get primary DN */ - config_get_line_string(CFGID_LINE_NAME, primaryLine, 1, sizeof(primaryLine)); - - /* - * for speeddial/BLF buttons, make presence subscriptions. - */ - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - // first line must always be a calling line. - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), i); - - - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, lineFeature=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - i, lineFeature); - switch (lineFeature) { - case cfgLineFeatureSpeedDialBLF: - config_get_line_string(CFGID_LINE_SPEEDDIAL_NUMBER, speedDialNumber, i, sizeof(speedDialNumber)); - if (speedDialNumber[0] == 0) { - break; - } - config_get_line_value(CFGID_LINE_FEATURE, &featureOptionMask, sizeof(featureOptionMask), i); - - transId = get_new_trans_id(); - transactionIds[i - 1] = transId; - CC_BLF_subscribe(transId, - INT_MAX, - primaryLine, - speedDialNumber, - i, - featureOptionMask ); - break; - default: - break; - } - - //Initializes native BLF handler - ccBLFHandlerInitialized(); - } -} - -static void ccBLFHandlerInitialized() -{ - if (!isBLFHandlerRunning) { - CC_BLF_init(); - isBLFHandlerRunning = TRUE; - } -} - -/* - * Function: sub_hndlr_stop - * - * Description: terminates blf subscriptions upon unregistration. - * - * Parameters: none. - * - * Returns: void - */ -void sub_hndlr_stop() -{ - static const char fname[] = "sub_hndlr_stop"; - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"entering", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - isAvailable = FALSE; - isBLFHandlerRunning = FALSE; - - // should clean up blf susbcription list. - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - //first, reset the transaction ids - transactionIds[i - 1] = 0; - //reset blf states. - blfStates[i - 1] = CC_SIP_BLF_UNKNOWN; - } - CC_BLF_unsubscribe_All(); -} - - -/* - * Function: hideBLFButtonsDisplay - * - * Description: hides BLF states - * - * Parameters: none. - * - * Returns: void - */ -static void hideBLFButtonsDisplay() -{ - static const char fname[] = "hideBLFButtonsDisplay"; - int i; - cc_uint32_t lineFeature = 0; - - CCAPP_DEBUG(DEB_F_PREFIX"entering", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - displayBLFState = FALSE; - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - // first line must always be a calling line. - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), i); - - switch (lineFeature) { - case cfgLineFeatureSpeedDialBLF: - ccsnap_gen_blfFeatureEvent(CC_SIP_BLF_UNKNOWN, i); - break; - default: - break; - } - } -} - -/* - * Function: unhideBLFButtonsDisplay - * - * Description: unhides BLF states. - * - * Parameters: none. - * - * Returns: void - */ -static void unhideBLFButtonsDisplay() -{ - static const char fname[] = "unhideBLFButtonsDisplay"; - int i; - cc_uint32_t lineFeature = 0; - char speedDialNumber[MAX_LINE_NAME_SIZE] = {0}; - - CCAPP_DEBUG(DEB_F_PREFIX"entering", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - displayBLFState = TRUE; - - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - // first line must always be a calling line. - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), i); - config_get_line_string(CFGID_LINE_SPEEDDIAL_NUMBER, speedDialNumber, i, sizeof(speedDialNumber)); - - switch (lineFeature) { - case cfgLineFeatureSpeedDialBLF: - ccsnap_gen_blfFeatureEvent(blfStates[i - 1], i); - break; - default: - break; - } - } -} - -/* - * Function: sub_hndlr_controlBLFButtons - * - * Description: hides/unhides BLF states. - * - * Parameters: none. - * - * Returns: void - */ -void sub_hndlr_controlBLFButtons(boolean state) -{ - static const char fname[] = "sub_hndlr_controlBLFButtons"; - - if (state == TRUE) { - CCAPP_DEBUG(DEB_F_PREFIX"going to hide", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - hideBLFButtonsDisplay(); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"going to unhide", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - unhideBLFButtonsDisplay(); - } -} - -/* - * Function: sub_hndlr_NotifyBLFStatus - * - * Description: notifies the app of BLF state. - * - * Parameters: - * requestId - requestId of the subscription - * status - BLF status - * appId - button number of the BLF feature key. - * - * Returns: void - */ -void sub_hndlr_NotifyBLFStatus(int requestId, cc_blf_state_t status, int appId) -{ - static const char fname[] = "sub_hndlr_NotifyBLFStatus"; - cc_uint32_t lineFeature = 0; - char speedDialNumber[MAX_LINE_NAME_SIZE] = {0}; - - - CCAPP_DEBUG(DEB_F_PREFIX"requestId=%d, status=%d, appId=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - requestId, status, appId); - if (appId == 0) { - // call list BLF. - } else { - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), appId); - config_get_line_string(CFGID_LINE_SPEEDDIAL_NUMBER, speedDialNumber, appId, sizeof(speedDialNumber)); - - blfStates[appId - 1] = status; - if (displayBLFState == FALSE) { - return; // ignore the notify - } - if (lineFeature == cfgLineFeatureSpeedDialBLF) { - ccsnap_gen_blfFeatureEvent(status, appId); - } - } -} - diff --git a/media/webrtc/signaling/src/sipcc/core/common/subscription_handler.h b/media/webrtc/signaling/src/sipcc/core/common/subscription_handler.h deleted file mode 100755 index 3bcf7317d29..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/subscription_handler.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SUB_HANDLER_H__ -#define __SUB_HANDLER_H__ - -boolean sub_hndlr_isAlertingBLFState(int inst); - -boolean sub_hndlr_isInUseBLFState(int inst); - -boolean sub_hndlr_isAvailable(); - -void sub_hndlr_start(); - -void sub_hndlr_stop(); - -void sub_hndlr_controlBLFButtons(boolean state); - -void sub_hndlr_NotifyBLFStatus(int requestId, int status, int appId); - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/common/text_strings.c b/media/webrtc/signaling/src/sipcc/core/common/text_strings.c deleted file mode 100755 index b8576c9c7d8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/text_strings.c +++ /dev/null @@ -1,361 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "text_strings.h" - - -#define dcl_str(x,p) char str_##x[] = p -#define use_str(x) str_##x - - -/* - * Debug strings. No localization needed. Keep it separate. - */ - -dcl_str(DEBUG_START, "SIPCC-START:\0"); -dcl_str(DEBUG_SEPARATOR_BAR, "===============\n"); -dcl_str(DEBUG_CONSOLE_PASSWORD, "CONSOLE-PWD:cisco"); -dcl_str(DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL, "CONSOLE-STALL"); -dcl_str(DEBUG_CONSOLE_KEYWORD_MEMORYMAP, "CONSOLE-MEMORYMAP"); -dcl_str(DEBUG_CONSOLE_KEYWORD_MALLOCTABLE, "CONSOLE-MALLOCTABLE"); -dcl_str(DEBUG_CONSOLE_KEYWORD_MEMORYDUMP, "CONSOLE-DUMP"); -dcl_str(DEBUG_CONSOLE_KEYWORD_DNS, "CONSOLE-DNS"); -dcl_str(DEBUG_CONSOLE_KEYWORD_DSPSTATE, "CONSOLE-DSPSTATE"); -dcl_str(DEBUG_CONSOLE_USAGE_MEMORYDUMP, "CONSOLE-MEMORYDUMP: addr bytes [cnt blk [1/0 char output]]\n"); -dcl_str(DEBUG_CONSOLE_BREAK, "CONSOLE-BREAK\r\n"); - -dcl_str(DEBUG_FUNCTION_ENTRY, "SIPCC-FUNC_ENTRY: LINE %d/%d: %-35s: %s <- %s\n"); -dcl_str(DEBUG_FUNCTION_ENTRY2, "SIPCC-FUNC_ENTRY: LINE %d/%d: %-35s: %s <- %s(%d)\n"); -dcl_str(DEBUG_SIP_ENTRY, "SIPCC-ENTRY: LINE %d/%d: %-35s: %s\n"); -dcl_str(DEBUG_SIP_URL_ERROR, "SIPCC-%s: Error: URL is not SIP.\n"); -dcl_str(DEBUG_LINE_NUMBER_INVALID, "SIPCC-LINE_NUM: %s: Error: Line number (%d) is invalid\n"); -dcl_str(DEBUG_SIP_SPI_SEND_ERROR, "SIPCC-SPI_SEND_ERR: %s: Error: sipSPISendErrorResponse(%d) failed.\n"); -dcl_str(DEBUG_SIP_SDP_CREATE_BUF_ERROR, "SIPCC-SDP_BUF: %s: Error: sipsdp_src_dest_create() returned null\n"); -dcl_str(DEBUG_SIP_PARSE_SDP_ERROR, "SIPCC-SDP_PARSE: %s: Error: sdp_parse()\n"); -dcl_str(DEBUG_SIP_FEATURE_UNSUPPORTED, "SIPCC-FEATURE: LINE %d/%d: %-35s: This feature is unsupported in the current state.\n"); -dcl_str(DEBUG_SIP_DEST_SDP, "SIPCC-SDP_DEST: LINE %d/%d: %-35s: Process SDP: Dest=<%s>:<%d>\n"); -dcl_str(DEBUG_SIP_MSG_SENDING_REQUEST, "SIPCC-MSG_SEND_REQ: %s: Sending %s...\n"); -dcl_str(DEBUG_SIP_MSG_SENDING_RESPONSE, "SIPCC-MSG_SEND_RESP: %s: Sending response %d...\n"); -dcl_str(DEBUG_SIP_MSG_RECV, "SIPCC-MSG_RECV: %s: Received SIP message %s.\n"); -dcl_str(DEBUG_SIP_STATE_UNCHANGED, "SIPCC-SIP_STATE: LINE %d/%d: %-35s: State unchanged -> %s\n"); -dcl_str(DEBUG_SIP_FUNCTIONCALL_FAILED, "SIPCC-FUNC_CALL: LINE %d/%d: %-35s: Error: %s returned error.\n"); -dcl_str(DEBUG_SIP_BUILDFLAG_ERROR, "SIPCC-BUILD_FLAG: %s: Error: Build flag is not successful. Will not send message.\n"); -dcl_str(DEBUG_GENERAL_FUNCTIONCALL_FAILED, "SIPCC-FUNC_CALL: %s: Error: %s returned error.\n"); -dcl_str(DEBUG_GENERAL_SYSTEMCALL_FAILED, "SIPCC-SYS_CALL: %s: Error: %s failed: errno = %d\n"); -dcl_str(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT, "SIPCC-FUNC_CALL: %s: Error: invalid argument: %s\n"); -dcl_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM, "SIPCC-FUNC_NAME: sippmh_parse_from_or_to(FROM)"); -dcl_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO, "SIPCC-FUNC_NAME: sippmh_parse_from_or_to(TO)"); -dcl_str(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE, "SIPCC-SM_REQ: sip_sm_request_check_and_store()"); -dcl_str(DEBUG_SNTP_LI_ERROR, "SIPCC-SNTP: Leap indicator == 3\n"); -dcl_str(DEBUG_SNTP_MODE_ERROR, "SIPCC-SNTP: Mode is not server (4/5) in response\n"); -dcl_str(DEBUG_SNTP_STRATUM_ERROR, "SIPCC-SNTP: Invalid stratum > 15\n"); -dcl_str(DEBUG_SNTP_TIMESTAMP_ERROR, "SIPCC-SNTP: Server did not echo our transmit timestamp\n"); -dcl_str(DEBUG_SNTP_TIMESTAMP1, "SIPCC-SNTP: %-15s: 0x%08x %08x, "); -dcl_str(DEBUG_SNTP_TIMESTAMP2, "SIPCC-SNTP: (%+03d:%02d) %s"); -dcl_str(DEBUG_SNTP_TIME_UPDATE, "SIPCC-SNTP: Updating date and time to:\n%s %lu %02lu:%02lu:%02lu " - "%04lu, %s, week %lu and day %lu. " - "Daylight saving is: %d\n\n"); -dcl_str(DEBUG_SNTP_TS_HEADER, "SIPCC-SNTP: Settings:\nMode : %lu\nTimezone " - ": %d\nServer Addr : %s\nTimeStruct : TZ/Offset: %d/%lu," - " AutoAdjust: %d\nMo Day DoW WoM Time\n"); -dcl_str(DEBUG_SNTP_TS_PRINT, "SIPCC-SNTP: %3lu %3lu %3lu %3lu %4lu\n"); -dcl_str(DEBUG_SNTP_SOCKET_REOPEN, "SIPCC-SNTP: Re-opening listening port due to IP change\n"); -dcl_str(DEBUG_SNTP_DISABLED, "SIPCC-SNTP: Unicast w/server addr 0.0.0.0, SNTP disabled\n"); -dcl_str(DEBUG_SNTP_REQUEST, "SIPCC-SNTP: Sending NTP request packet [%s]\n"); -dcl_str(DEBUG_SNTP_RESPONSE, "SIPCC-SNTP: Receiving NTP response packet\n"); -dcl_str(DEBUG_SNTP_RETRANSMIT, "SIPCC-SNTP: Waiting %d msec to retransmit\n"); -dcl_str(DEBUG_SNTP_UNICAST_MODE, "SIPCC-SNTP: Unicast mode [%s]\n"); -dcl_str(DEBUG_SNTP_MULTICAST_MODE, "SIPCC-SNTP: Multicast/Directed broadcast mode [%s]\n"); -dcl_str(DEBUG_SNTP_ANYCAST_MODE, "SIPCC-SNTP: Anycast mode [%s]\n"); -dcl_str(DEBUG_SNTP_VALIDATION, "SIPCC-SNTP: Dropping unauthorized SNTP response: %s\n"); -dcl_str(DEBUG_SNTP_VALIDATION_PACKET, "SIPCC-SNTP: Semantic check failed for NTP packet\n"); -dcl_str(DEBUG_SNTP_WRONG_SERVER, "SIPCC-SNTP: Unauthorized server"); -dcl_str(DEBUG_SNTP_NO_REQUEST, "SIPCC-SNTP: No request sent"); -dcl_str(DEBUG_SNTP_ANYCAST_RESET, "SIPCC-SNTP: Reset to Unicast to server: %s\n"); -dcl_str(DEBUG_SOCKET_UDP_RTP, "SIPCC-SOC_TASK: UDP_RTP event received.\n"); -dcl_str(DEBUG_MAC_PRINT, "SIPCC-MAC_PRINT: %04x:%04x:%04x"); -dcl_str(DEBUG_IP_PRINT, "SIPCC-IP_PRINT: %u.%u.%u.%u"); -dcl_str(DEBUG_SYSBUF_UNAVAILABLE, "SIPCC-SYS_BUF: %s: Error: IRXLstGet() failed\n"); -dcl_str(DEBUG_MSG_BUFFER_TOO_BIG, "SIPCC-MSG_BUF: %s: Error: Args Check: message buffer length (%d) too big.\n"); -dcl_str(DEBUG_UNKNOWN_TIMER_BLOCK, "SIPCC-TIMER: %s: Error: Unknown timer block\n"); -dcl_str(DEBUG_CREDENTIALS_BAG_CORRUPTED, "SIPCC-CRED: %-35s: Error: credentials bags corrupted"); -dcl_str(DEBUG_INPUT_NULL, "SIPCC-INPUT: %s: Error: Input is null\n"); -dcl_str(DEBUG_INPUT_EMPTY, "SIPCC-INPUT: %s: Error: Input is empty\n"); -dcl_str(DEBUG_STRING_DUP_FAILED, "SIPCC-STR_DUP: %s: Unable to duplicate string.\n"); -dcl_str(DEBUG_PARSER_STRING_TOO_LARGE, "SIPCC-PARSE: Parse error: string too big (%d,%d)\n"); -dcl_str(DEBUG_PARSER_NULL_KEY_TABLE, "SIPCC-PARSE: Parse error: NULL key table passed into parser\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_KEY, "SIPCC-PARSE: Parse error: Unknown key name: %s\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_KEY_ENUM, "SIPCC-PARSE: Print error: Unknown key enum: %d\n"); -dcl_str(DEBUG_PARSER_INVALID_START_VAR, "SIPCC-PARSE: Parse error: Invalid start variable ch=0x%02x(%c)\n"); -dcl_str(DEBUG_PARSER_INVALID_VAR_CHAR, "SIPCC-PARSE: Parse error: Invalid variable ch=0x%02x(%c)\n"); -dcl_str(DEBUG_PARSER_MISSING_COLON, "SIPCC-PARSE: Parse error: Missing colon separator\n"); -dcl_str(DEBUG_PARSER_NO_VALUE, "SIPCC-PARSE: Parse error: no value for variable\n"); -dcl_str(DEBUG_PARSER_EARLY_EOL, "SIPCC-PARSE: Parse error: early EOL for value\n"); -dcl_str(DEBUG_PARSER_INVALID_VAR_NAME, "SIPCC-PARSE: Parse error: parse_var_name failed: %d\n"); -dcl_str(DEBUG_PARSER_INVALID_VAR_VALUE, "SIPCC-PARSE: Parse error: var: %s parse_var_value failed: %d\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_VAR, "SIPCC-PARSE: Parse error: var: %s not found in table\n"); -dcl_str(DEBUG_PARSER_NAME_VALUE, "SIPCC-PARSE: Name: [%s] Value: [%s]\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_NAME_VALUE, "SIPCC-PARSE: Parse error: Name: [%s] Value: [%s] rc:%d\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_ERROR, "SIPCC-PARSE: Default error: Name: [%s] Value: [%s] rc:%d\n"); -dcl_str(DEBUG_PARSER_NUM_ERRORS, "SIPCC-PARSE: Parse error: %d Errors found\n"); -dcl_str(DEBUG_PARSER_SET_DEFAULT, "SIPCC-PARSE: Parser Info: Setting var: %s to default value: %s\n\n"); -dcl_str(DEBUG_SDP_ERROR_BODY_FIELD, "SIPCC-SDP: \n%s: Error in one of the SDP body fields \n"); -dcl_str(DEBUG_UDP_OPEN_FAIL, "SIPCC-UDP: %s: UdpOpen(R IP=%d, R Port=%d, L Port=%d) failed\n"); -dcl_str(DEBUG_UDP_PAYLOAD_TOO_LARGE, "SIPCC-UDP: %s: Error: payload size=<%d> > allowed size=<%d>\n"); -dcl_str(DEBUG_RTP_TRANSPORT, "SIPCC-RTP: %s: transport= %d\n"); -dcl_str(DEBUG_RTP_INVALID_VOIP_TYPE, "SIPCC-RTP: %s: Error: Unexpected voipCodec_t type: <%d>\n"); -dcl_str(DEBUG_RTP_INVALID_RTP_TYPE, "SIPCC-RTP: %s: Error: Unexpected rtp_ptype in SDP body: <%d>\n"); -dcl_str(DEBUG_MEMORY_ALLOC, "SIPCC-MEM: Malloc Addr:0x%lx, Size:%d\n"); -dcl_str(DEBUG_MEMORY_FREE, "SIPCC-MEM: Free Addr:0x%lx, Size:%d\n"); -dcl_str(DEBUG_MEMORY_MALLOC_ERROR, "SIPCC-MEM: 0x%lx:Malloc error for size %d\n"); -dcl_str(DEBUG_MEMORY_REALLOC_ERROR, "SIPCC-MEM: %s: Error: malloc_tagged() returned null.\n"); -dcl_str(DEBUG_MEMORY_OUT_OF_MEM, "SIPCC-MEM: %s: Error: malloc failed\n"); -dcl_str(DEBUG_MEMORY_ENTRY, "SIPCC-MEM: >> Used: %1d size: %6d addr:0x%08x\n"); -dcl_str(DEBUG_MEMORY_SUMMARY, "===== MEMORY MAP START =====\n" - "free blocks : %6d, free block space:%6d, largest free block: %6d\n" - "used blocks : %6d, used block space:%6d, largest used block: %6d\n" - "wasted block: %6d, str_lib space :%6d\n" - "used space excluding str_lib space :%6d\n \n" - "===== MEMORY MAP END =====\n"); -dcl_str(DEBUG_MEMORY_ADDRESS_HEADER, "SIPCC-MEM: 0x%08x: "); -dcl_str(DEBUG_MEMORY_DUMP, "SIPCC-MEM: DUMP: 0x%08x - 0x%08x\n"); -dcl_str(DEBUG_DNS_GETHOSTBYNAME, "SIPCC-DNS: gethostbyname('%s',%08x,%d,%d)\n"); -dcl_str(DEBUG_PMH_INCORRECT_SYNTAX, "SIPCC-PMH: INCORRECT SYNTAX"); -dcl_str(DEBUG_PMH_INVALID_FIELD_VALUE, "SIPCC-PMH: INVALID FIELD VALUE"); -dcl_str(DEBUG_PMH_INVALID_SCHEME, "SIPCC-PMH: INVALID SCHEME"); -dcl_str(DEBUG_PMH_UNKNOWN_SCHEME, "SIPCC-PMH: UNKNOWN SCHEME"); -dcl_str(DEBUG_PMH_NOT_ENOUGH_PARAMETERS, "SIPCC-PMH: NOT ENOUGH PARAMETERS"); -dcl_str(DEBUG_REG_DISABLED, "SIPCC-REG: LINE %d/%d: %-35s: registration disabled\n"); -dcl_str(DEBUG_REG_PROXY_EXPIRES, "SIPCC-REG: LINE %d/%d: %-35s: Using proxy expires value\n"); -dcl_str(DEBUG_REG_SIP_DATE, "SIPCC-REG: LINE %d/%d: %-35s: SIP-date= %s\n"); -dcl_str(DEBUG_REG_SIP_RESP_CODE, "SIPCC-REG: LINE %d/%d: %-35s: Error: SIP response code\n"); -dcl_str(DEBUG_REG_SIP_RESP_FAILURE, "SIPCC-REG: LINE %d/%d: %-35s: SIP failure %d resp\n"); -dcl_str(DEBUG_REG_INVALID_LINE, "SIPCC-REG: %-35s: Line %d: Invalid line\n"); -dcl_str(CC_NO_MSG_BUFFER, "SIPCC-MSG_BUF: %s : no msg buffer available\n"); -dcl_str(CC_SEND_FAILURE, "SIPCC-MSG_SEND: %s : unable to send msg\n"); -dcl_str(GSM_UNDEFINED, "SIPCC-GSM: UNDEFINED"); -dcl_str(GSM_DBG_PTR, "SIPCC-GSM_DBG_PTR: %s %-4d: %-35s: %s= %p\n"); -dcl_str(GSM_FUNC_ENTER, "SIPCC-GSM_FUNC_ENT: %s %-4d: %-35s\n"); -dcl_str(GSM_DBG1, "SIPCC-GSM: %s %-4d: %-35s: %s\n"); -dcl_str(FSM_DBG_SM_DEFAULT_EVENT, "SIPCC-FSM: default - ignoring.\n"); -dcl_str(FSM_DBG_SM_FTR_ENTRY, "SIPCC-FSM: feature= %s, src= %s\n"); -dcl_str(FSM_DBG_FAC_ERR, "SIPCC-FSM_FAC_ERR: %-4d: %-35s:\n %s, rc= %s\n"); -dcl_str(FSM_DBG_FAC_FOUND, "SIPCC-FSM: %-4d: %-35s: facility found(%d)\n"); -dcl_str(FSM_DBG_IGNORE_FTR, "SIPCC-FSM: %s %-4d: %8d: ignoring feature= %s\n"); -dcl_str(FSM_DBG_IGNORE_SRC, "SIPCC-FSM: %s %-4d: %8d: ignoring src= %s\n"); -dcl_str(FSM_DBG_CHANGE_STATE, "SIPCC-FSM: %s %-4d: %8d: %s -> %s\n"); -dcl_str(FSM_DBG_SDP_BUILD_ERR, "SIPCC-FSM: Unable to build SDP. \n"); -dcl_str(FSMDEF_DBG_PTR, "SIPCC-FSM: DEF %-4d/%d: %-35s: dcb= %p\n"); -dcl_str(FSMDEF_DBG1, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s\n"); -dcl_str(FSMDEF_DBG2, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s %d\n"); -dcl_str(FSMDEF_DBG_SDP, "SIPCC-FSM: DEF %-4d/%d: %-35s: addr= %s, port= %d,\n media_type(s)="); -dcl_str(FSMDEF_DBG_CLR_SPOOF_APPLD, "SIPCC-FSM: DEF %-4d/%d: %-35s: clearing spoof_ringout_applied.\n"); -dcl_str(FSMDEF_DBG_CLR_SPOOF_RQSTD, "SIPCC-FSM: DEF %-4d/%d: %-35s: clearing spoof_ringout_requested.\n"); -dcl_str(FSMDEF_DBG_INVALID_DCB, "SIPCC-FSM: DEF 0 : %-35s: invalid dcb\n"); -dcl_str(FSMDEF_DBG_FTR_REQ_ACT, "SIPCC-FSM: DEF %-4d/%d: feature requested %s but %s is active.\n"); -dcl_str(FSMDEF_DBG_TMR_CREATE_FAILED, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s:\n cprCreateTimer failed.\n"); -dcl_str(FSMDEF_DBG_TMR_START_FAILED, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s:\n cprStartTimer failed, errno= %d.\n"); -dcl_str(FSMDEF_DBG_TMR_CANCEL_FAILED, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s:\n cprCancelTimer failed, errno= %d.\n"); -dcl_str(FSMXFR_DBG_XFR_INITIATED, "SIPCC-FSM: XFR %-4d/%d/%d: %8d: xfer initiated\n"); -dcl_str(FSMXFR_DBG_PTR, "SIPCC-FSM: XFR %-4d/%d/%d: %-35s: xcb= %p\n"); -dcl_str(FSMCNF_DBG_CNF_INITIATED, "SIPCC-FSM: CNF %-4d/%d/%d: %8d: conf initiated\n"); -dcl_str(FSMCNF_DBG_PTR, "SIPCC-FSM: CNF %-4d/%d/%d: %-35s: ncb= %p\n"); -dcl_str(FSMB2BCNF_DBG_CNF_INITIATED, "SIPCC-FSM: B2BCNF %-4d/%d/%d: %8d: b2bconf initiated\n"); -dcl_str(FSMB2BCNF_DBG_PTR, "SIPCC-FSM: B2BCNF %-4d/%d/%d: %-35s: ncb= %p\n"); -dcl_str(FSMSHR_DBG_BARGE_INITIATED, "SIPCC-FSM: SHR %-4d/%d/%d: %8d: Barge initiated\n"); -dcl_str(LSM_DBG_ENTRY, "SIPCC-LSM: %-4d/%d: %-35s\n"); -dcl_str(LSM_DBG_INT1, "SIPCC-LSM: %-4d/%d: %-35s: %s= %d\n"); -dcl_str(LSM_DBG_CC_ERROR, "SIPCC-LSM: %-4d/%d: %-35s: (%d:%p) failure\n"); -dcl_str(VCM_DEBUG_ENTRY, "SIPCC-VCM: %-4d: %-35s\n"); -dcl_str(SM_PROCESS_EVENT_ERROR, "SIPCC-SM: %s: Error: sip_sm_process_event() returned error processing %d\n"); -dcl_str(REG_SM_PROCESS_EVENT_ERROR, "SIPCC-SM: %s: Error: sip_reg_sm_process_event() returned error processing %d\n"); -dcl_str(DEBUG_END, "SIPCC-END: \0"); - -/* - * Debug string table NOT subject to localization - */ -debug_string_table_entry debug_string_table [] = { - {0}, // DEBUG_START - {use_str(DEBUG_SEPARATOR_BAR)}, // DEBUG_SEPARATOR_BAR - {use_str(DEBUG_CONSOLE_PASSWORD)}, // DEBUG_CONSOLE_PASSWORD - {use_str(DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL)}, // DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL - {use_str(DEBUG_CONSOLE_KEYWORD_MEMORYMAP)}, // DEBUG_CONSOLE_KEYWORD_MEMORYMAP - {use_str(DEBUG_CONSOLE_KEYWORD_MALLOCTABLE)}, // DEBUG_CONSOLE_KEYWORD_MALLOCTABLE - {use_str(DEBUG_CONSOLE_KEYWORD_MEMORYDUMP)}, // DEBUG_CONSOLE_KEYWORD_MEMORYDUMP - {use_str(DEBUG_CONSOLE_KEYWORD_DNS)}, // DEBUG_CONSOLE_KEYWORD_DNS - {use_str(DEBUG_CONSOLE_KEYWORD_DSPSTATE)}, // DEBUG_CONSOLE_KEYWORD_DSPSTATE - {use_str(DEBUG_CONSOLE_USAGE_MEMORYDUMP)}, // DEBUG_CONSOLE_USAGE_MEMORYDUMP - {use_str(DEBUG_CONSOLE_BREAK)}, // DEBUG_CONSOLE_BREAK - {use_str(DEBUG_FUNCTION_ENTRY)}, // DEBUG_FUNCTION_ENTRY - {use_str(DEBUG_FUNCTION_ENTRY2)}, // DEBUG_FUNCTION_ENTRY2 - {use_str(DEBUG_SIP_ENTRY)}, // DEBUG_SIP_ENTRY - {use_str(DEBUG_SIP_URL_ERROR)}, // DEBUG_SIP_URL_ERROR - {use_str(DEBUG_LINE_NUMBER_INVALID)}, // DEBUG_LINE_NUMBER_INVALID - {use_str(DEBUG_SIP_SPI_SEND_ERROR)}, // DEBUG_SIP_SPI_SEND_ERROR - {use_str(DEBUG_SIP_SDP_CREATE_BUF_ERROR)}, // DEBUG_SIP_SDP_CREATE_BUF_ERROR - {use_str(DEBUG_SIP_PARSE_SDP_ERROR)}, // DEBUG_SIP_PARSE_SDP_ERROR - {use_str(DEBUG_SIP_FEATURE_UNSUPPORTED)}, // DEBUG_SIP_FEATURE_UNSUPPORTED - {use_str(DEBUG_SIP_DEST_SDP)}, // DEBUG_SIP_DEST_SDP - {use_str(DEBUG_SIP_MSG_SENDING_REQUEST)}, // DEBUG_SIP_MSG_SENDING_REQUEST - {use_str(DEBUG_SIP_MSG_SENDING_RESPONSE)}, // DEBUG_SIP_MSG_SENDING_RESPONSE - {use_str(DEBUG_SIP_MSG_RECV)}, // DEBUG_SIP_MSG_RECV - {use_str(DEBUG_SIP_STATE_UNCHANGED)}, // DEBUG_SIP_STATE_UNCHANGED - {use_str(DEBUG_SIP_FUNCTIONCALL_FAILED)}, // DEBUG_SIP_FUNCTIONCALL_FAILED - {use_str(DEBUG_SIP_BUILDFLAG_ERROR)}, // DEBUG_SIP_BUILDFLAG_ERROR - {use_str(DEBUG_GENERAL_FUNCTIONCALL_FAILED)}, // DEBUG_GENERAL_FUNCTIONCALL_FAILED - {use_str(DEBUG_GENERAL_SYSTEMCALL_FAILED)}, // DEBUG_GENERAL_SYSTEMCALL_FAILED - {use_str(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT)}, // DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT - {use_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)},// DEBUG_FUNCTIONNAME_SIP_PARSE_FROM - {use_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)}, // DEBUG_FUNCTIONNAME_SIP_PARSE_TO - {use_str(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)}, // DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE - {use_str(DEBUG_SNTP_LI_ERROR)}, // DEBUG_SNTP_LI_ERROR - {use_str(DEBUG_SNTP_MODE_ERROR)}, // DEBUG_SNTP_MODE_ERROR - {use_str(DEBUG_SNTP_STRATUM_ERROR)}, // DEBUG_SNTP_STRATUM_ERROR - {use_str(DEBUG_SNTP_TIMESTAMP_ERROR)}, // DEBUG_SNTP_TIMESTAMP_ERROR - {use_str(DEBUG_SNTP_TIMESTAMP1)}, // DEBUG_SNTP_TIMESTAMP1 - {use_str(DEBUG_SNTP_TIMESTAMP2)}, // DEBUG_SNTP_TIMESTAMP2 - {use_str(DEBUG_SNTP_TIME_UPDATE)}, // DEBUG_SNTP_TIME_UPDATE - {use_str(DEBUG_SNTP_TS_HEADER)}, // DEBUG_SNTP_TS_HEADER - {use_str(DEBUG_SNTP_TS_PRINT)}, // DEBUG_SNTP_TS_PRINT - {use_str(DEBUG_SNTP_SOCKET_REOPEN)}, // DEBUG_SNTP_SOCKET_REOPEN - {use_str(DEBUG_SNTP_DISABLED)}, // DEBUG_SNTP_DISABLED - {use_str(DEBUG_SNTP_REQUEST)}, // DEBUG_SNTP_REQUEST - {use_str(DEBUG_SNTP_RESPONSE)}, // DEBUG_SNTP_RESPONSE - {use_str(DEBUG_SNTP_RETRANSMIT)}, // DEBUG_SNTP_RETRANSMIT - {use_str(DEBUG_SNTP_UNICAST_MODE)}, // DEBUG_SNTP_UNICAST_MODE - {use_str(DEBUG_SNTP_MULTICAST_MODE)}, // DEBUG_SNTP_MULTICAST_MODE - {use_str(DEBUG_SNTP_ANYCAST_MODE)}, // DEBUG_SNTP_ANYCAST_MODE - {use_str(DEBUG_SNTP_VALIDATION)}, // DEBUG_SNTP_VALIDATION - {use_str(DEBUG_SNTP_VALIDATION_PACKET)}, // DEBUG_SNTP_VALIDATION_PACKET - {use_str(DEBUG_SNTP_WRONG_SERVER)}, // DEBUG_SNTP_WRONG_SERVER - {use_str(DEBUG_SNTP_NO_REQUEST)}, // DEBUG_SNTP_NO_REQUEST - {use_str(DEBUG_SNTP_ANYCAST_RESET)}, // DEBUG_SNTP_ANYCAST_RESET - {use_str(DEBUG_SOCKET_UDP_RTP)}, // DEBUG_SOCKET_UDP_RTP - {use_str(DEBUG_MAC_PRINT)}, // DEBUG_MAC_PRINT - {use_str(DEBUG_IP_PRINT)}, // DEBUG_IP_PRINT - {use_str(DEBUG_SYSBUF_UNAVAILABLE)}, // DEBUG_SYSBUF_UNAVAILABLE - {use_str(DEBUG_MSG_BUFFER_TOO_BIG)}, // DEBUG_MSG_BUFFER_TOO_BIG - {use_str(DEBUG_UNKNOWN_TIMER_BLOCK)}, // DEBUG_UNKNOWN_TIMER_BLOCK - {use_str(DEBUG_CREDENTIALS_BAG_CORRUPTED)}, // DEBUG_CREDENTIALS_BAG_CORRUPTED - {use_str(DEBUG_INPUT_NULL)}, // DEBUG_INPUT_NULL - {use_str(DEBUG_INPUT_EMPTY)}, // DEBUG_INPUT_EMPTY - {use_str(DEBUG_STRING_DUP_FAILED)}, // DEBUG_STRING_DUP_FAILED - {use_str(DEBUG_PARSER_STRING_TOO_LARGE)}, // DEBUG_PARSER_STRING_TOO_LARGE - {use_str(DEBUG_PARSER_NULL_KEY_TABLE)}, // DEBUG_PARSER_NULL_KEY_TABLE - {use_str(DEBUG_PARSER_UNKNOWN_KEY)}, // DEBUG_PARSER_UNKNOWN_KEY - {use_str(DEBUG_PARSER_UNKNOWN_KEY_ENUM)}, // DEBUG_PARSER_UNKNOWN_KEY_ENUM - {use_str(DEBUG_PARSER_INVALID_START_VAR)}, // DEBUG_PARSER_INVALID_START_VAR - {use_str(DEBUG_PARSER_INVALID_VAR_CHAR)}, // DEBUG_PARSER_INVALID_VAR_CHAR - {use_str(DEBUG_PARSER_MISSING_COLON)}, // DEBUG_PARSER_MISSING_COLON - {use_str(DEBUG_PARSER_NO_VALUE)}, // DEBUG_PARSER_NO_VALUE - {use_str(DEBUG_PARSER_EARLY_EOL)}, // DEBUG_PARSER_EARLY_EOL - {use_str(DEBUG_PARSER_INVALID_VAR_NAME)}, // DEBUG_PARSER_INVALID_VAR_NAME - {use_str(DEBUG_PARSER_INVALID_VAR_VALUE)}, // DEBUG_PARSER_INVALID_VAR_VALUE - {use_str(DEBUG_PARSER_UNKNOWN_VAR)}, // DEBUG_PARSER_UNKNOWN_VAR - {use_str(DEBUG_PARSER_NAME_VALUE)}, // DEBUG_PARSER_NAME_VALUE - {use_str(DEBUG_PARSER_UNKNOWN_NAME_VALUE)}, // DEBUG_PARSER_UNKNOWN_NAME_VALUE - {use_str(DEBUG_PARSER_UNKNOWN_ERROR)}, // DEBUG_PARSER_UNKNOWN_ERROR - {use_str(DEBUG_PARSER_NUM_ERRORS)}, // DEBUG_PARSER_NUM_ERRORS - {use_str(DEBUG_PARSER_SET_DEFAULT)}, // DEBUG_PARSER_SET_DEFAULT - {use_str(DEBUG_SDP_ERROR_BODY_FIELD)}, // DEBUG_SDP_ERROR_BODY_FIELD - {use_str(DEBUG_UDP_OPEN_FAIL)}, // DEBUG_UDP_OPEN_FAIL - {use_str(DEBUG_UDP_PAYLOAD_TOO_LARGE)}, // DEBUG_UDP_PAYLOAD_TOO_LARGE - {use_str(DEBUG_RTP_TRANSPORT)}, // DEBUG_RTP_TRANSPORT - {use_str(DEBUG_RTP_INVALID_VOIP_TYPE)}, // DEBUG_RTP_INVALID_VOIP_TYPE - {use_str(DEBUG_RTP_INVALID_RTP_TYPE)}, // DEBUG_RTP_INVALID_RTP_TYPE - {use_str(DEBUG_MEMORY_ALLOC)}, // DEBUG_MEMORY_ALLOC - {use_str(DEBUG_MEMORY_FREE)}, // DEBUG_MEMORY_FREE - {use_str(DEBUG_MEMORY_MALLOC_ERROR)}, // DEBUG_MEMORY_MALLOC_ERROR - {use_str(DEBUG_MEMORY_REALLOC_ERROR)}, // DEBUG_MEMORY_REALLOC_ERROR - {use_str(DEBUG_MEMORY_OUT_OF_MEM)}, // DEBUG_MEMORY_OUT_OF_MEM - {use_str(DEBUG_MEMORY_ENTRY)}, // DEBUG_MEMORY_ENTRY - {use_str(DEBUG_MEMORY_SUMMARY)}, // DEBUG_MEMORY_SUMMARY - {use_str(DEBUG_MEMORY_ADDRESS_HEADER)}, // DEBUG_MEMORY_ADDRESS_HEADER - {use_str(DEBUG_MEMORY_DUMP)}, // DEBUG_MEMORY_DUMP - {use_str(DEBUG_DNS_GETHOSTBYNAME)}, // DEBUG_DNS_GETHOSTBYNAME - {use_str(DEBUG_PMH_INCORRECT_SYNTAX)}, // DEBUG_PMH_INCORRECT_SYNTAX - {use_str(DEBUG_PMH_INVALID_FIELD_VALUE)}, // DEBUG_PMH_INVALID_FIELD_VALUE - {use_str(DEBUG_PMH_INVALID_SCHEME)}, // DEBUG_PMH_INVALID_SCHEME - {use_str(DEBUG_PMH_UNKNOWN_SCHEME)}, // DEBUG_PMH_UNKNOWN_SCHEME - {use_str(DEBUG_PMH_NOT_ENOUGH_PARAMETERS)}, // DEBUG_PMH_NOT_ENOUGH_PARAMETERS - {use_str(DEBUG_REG_DISABLED)}, // DEBUG_REG_DISABLED - {use_str(DEBUG_REG_PROXY_EXPIRES)}, // DEBUG_REG_PROXY_EXPIRES - {use_str(DEBUG_REG_SIP_DATE)}, // DEBUG_REG_SIP_DATE - {use_str(DEBUG_REG_SIP_RESP_CODE)}, // DEBUG_REG_SIP_RESP_CODE - {use_str(DEBUG_REG_SIP_RESP_FAILURE)}, // DEBUG_REG_SIP_RESP_FAILURE - {use_str(DEBUG_REG_INVALID_LINE)}, // DEBUG_REG_INVALID_LINE - {use_str(CC_NO_MSG_BUFFER)}, // CC_NO_MSG_BUFFER^M - {use_str(CC_SEND_FAILURE)}, // CC_SEND_FAILURE^M - {use_str(GSM_UNDEFINED)}, // GSM_UNDEFINED - {use_str(GSM_DBG_PTR)}, // GSM_DBG_PTR - {use_str(GSM_FUNC_ENTER)}, // GSM_FUNC_ENTER - {use_str(GSM_DBG1)}, // GSM_DBG1 - {use_str(FSM_DBG_SM_DEFAULT_EVENT)}, // FSM_DBG_SM_DEFAULT_EVENT - {use_str(FSM_DBG_SM_FTR_ENTRY)}, // FSM_DBG_SM_FTR_ENTRY - {use_str(FSM_DBG_FAC_ERR)}, // FSM_DBG_FAC_ERR - {use_str(FSM_DBG_FAC_FOUND)}, // FSM_DBG_FAC_FOUND - {use_str(FSM_DBG_IGNORE_FTR)}, // FSM_DBG_IGNORE_FTR - {use_str(FSM_DBG_IGNORE_SRC)}, // FSM_DBG_IGNORE_SRC - {use_str(FSM_DBG_CHANGE_STATE)}, // FSM_DBG_CHANGE_STATE - {use_str(FSM_DBG_SDP_BUILD_ERR)}, // FSM_DBG_SDP_BUILD_ERR - {use_str(FSMDEF_DBG_PTR)}, // FSMDEF_DBG_PTR - {use_str(FSMDEF_DBG1)}, // FSMDEF_DBG1 - {use_str(FSMDEF_DBG2)}, // FSMDEF_DBG2 - {use_str(FSMDEF_DBG_SDP)}, // FSMDEF_DBG_SDP - {use_str(FSMDEF_DBG_CLR_SPOOF_APPLD)}, // FSMDEF_DBG_CLEAR_SPOOF - {use_str(FSMDEF_DBG_CLR_SPOOF_RQSTD)}, // FSMDEF_DBG_CLEAR_SPOOF - {use_str(FSMDEF_DBG_INVALID_DCB)}, // FSMDEF_DBG_INVALID_DCB - {use_str(FSMDEF_DBG_FTR_REQ_ACT)}, // FSMDEF_DBG_FTR_REQ_ACT - {use_str(FSMDEF_DBG_TMR_CREATE_FAILED)}, // FSMDEF_DBG_TMR_CREATE_FAILED - {use_str(FSMDEF_DBG_TMR_START_FAILED)}, // FSMDEF_DBG_TMR_START_FAILED - {use_str(FSMDEF_DBG_TMR_CANCEL_FAILED)}, // FSMDEF_DBG_TMR_CANCEL_FAILED - {use_str(FSMXFR_DBG_XFR_INITIATED)}, // FSMXFR_DBG_XFR_INITIATED - {use_str(FSMXFR_DBG_PTR)}, // FSMXFR_DBG_PTR - {use_str(FSMCNF_DBG_CNF_INITIATED)}, // FSMCNF_DBG_CNF_INITIATED - {use_str(FSMCNF_DBG_PTR)}, // FSMCNF_DBG_PTR - {use_str(FSMB2BCNF_DBG_CNF_INITIATED)}, // FSMB2BCNF_DBG_CNF_INITIATED - {use_str(FSMB2BCNF_DBG_PTR)}, // FSMB2BCNF_DBG_PTR - {use_str(FSMSHR_DBG_BARGE_INITIATED)}, // FSMSHR_DBG_BARGE_INITIATED - {use_str(LSM_DBG_ENTRY)}, // LSM_DBG_ENTRY - {use_str(LSM_DBG_INT1)}, // LSM_DBG_INT1 - {use_str(LSM_DBG_CC_ERROR)}, // LSM_DBG_CC_ERROR - {use_str(VCM_DEBUG_ENTRY)}, // VCM_DEBUG_ENTRY - {use_str(SM_PROCESS_EVENT_ERROR)}, // SM_PROCESS_EVENT_ERROR - {use_str(REG_SM_PROCESS_EVENT_ERROR)}, // REG_SM_PROCESS_EVENT_ERROR - {0}, -}; - - - -//************************************************************************ - -/* - * Phrase string table subject to localization - */ -tnp_phrase_index_str_table_entry tnp_phrase_index_str_table [] = { - {"\0"}, // LOCALE_START - {"\x80\x13"}, // IDLE_PROMPT sccp 119 - {"Anonymous"}, // ANONYMOUS - used for messaging; keep English - {"\x80\x1e"}, // CALL_PROCEEDING_IN - {"\x80\x1e"}, // CALL_PROCEEDING_OUT - {"\x80\x16"}, // CALL_ALERTING sccp 122 - {"\x80\x1b"}, // CALL_ALERTING_SECONDARY sccp 127 - {"\x80\x16"}, // CALL_ALERTING_LOCAL - {"\x80\x18"}, // CALL_CONNECTED sccp 124 - {"\x80\x03"}, // CALL_INITIATE_HOLD sccp 103 or phone 786? - {"\x80\x20"}, // PROMPT_DIAL sccp 132 - {"\x80\x19"}, // LINE_BUSY sccp 125 - {"\x80\x1b"}, // CALL_WAITING - {"\x80\x52"}, // TRANSFER_FAILED sccp 182 - {"\x80\x26"}, // Cannot complete the b2b conf - {"\x80\x34"}, // UI_CONFERENCE - {"\x80\x38"}, // UI_UNKNOWN - {"\x80\x1f"}, // REMOTE_IN_USE - {"\x80\x55"}, // NUM_NOT_CONFIGURED - {"\x80\x17"}, // UI_FROM - {"\x80\x29"}, // INVALID_CONF_PARTICIPANT - {"\x80\x36"}, // UI_PRIVATE - {"\0"} // LOCALE_END -}; diff --git a/media/webrtc/signaling/src/sipcc/core/common/text_strings.h b/media/webrtc/signaling/src/sipcc/core/common/text_strings.h deleted file mode 100755 index 0502a38e050..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/text_strings.h +++ /dev/null @@ -1,302 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TEXT_STRINGS_H -#define TEXT_STRINGS_H - -#include "cpr_types.h" -#include "phone_types.h" -#include "string_lib.h" - - -#define DEF_NOTIFY_PRI 20 -#define HR_NOTIFY_PRI 1 - -/* - * Define hard coded Anonymous string to be used in From header - * when call id blocking is enabled. This is also used to - * compare to when anonymous call block is enabled. We can - * can not use the localized version of Anonymous for these - * actions. - */ -#define SIP_HEADER_ANONYMOUS_STR "Anonymous" - -/* - * Define special strings that are not localized to be used for - * comparing special display names whether the names are special - * and not to display the number associated with the name. - */ -#define CONFERENCE_STR "conference" -#define CONFERENCE_STR_LEN (sizeof(CONFERENCE_STR)-1) -#define CONFERENCE_LOCALE_CODE 964 -/* - * Constants for dictionary index - */ - -// Hardcoding phrases that need to be dropped on floor for RT to 1 - -#define STR_INDEX_GRP_CALL_PICKUP 47 -#define STR_INDEX_LST_CALL_PICKUP 49 -#define STR_INDEX_FEAT_UNAVAIL 148 -#define STR_INDEX_CNFR_FAIL_NOCODEC 1054 -#define STR_INDEX_REORDER 1055 -#define STR_INDEX_ANONYMOUS_SPACE 1056 -#define STR_INDEX_NO_FREE_LINES 1057 -#define STR_INDEX_REGISTRATION_REJECTED 1058 -#define STR_INDEX_REGISTERING 1 -#define STR_INDEX_WHISPER 1 -#define STR_INDEX_PROXY_UNAVAIL 1 -#define STR_INDEX_CALL_REDIRECTED 1 -#define STR_INDEX_TRANSFERRING 1 -#define STR_INDEX_SESSION_PROGRESS 1 -#define STR_INDEX_CALLING 1 -#define STR_INDEX_USE_LINE_OR_JOIN_TO_COMPLETE 1 -#define STR_INDEX_CONF_LOCAL_MIXED 1 -#define STR_INDEX_NO_CALL_FOR_PICKUP 195 - -#define STR_INDEX_CALL_FORWARD 105 -#define STR_INDEX_CALL_PICKUP 117 -#define STR_INDEX_NO_LINE_FOR_PICKUP 198 - - -#define STR_INDEX_ERROR_PASS_LIMIT 149 -#define STR_INDEX_TRANS_COMPLETE 918 -#define STR_INDEX_END_CALL 877 -#define STR_INDEX_NO_BAND_WIDTH 1158 - -#define STR_INDEX_RESP_TIMEOUT 1160 - -#define CALL_BUBBLE_STR_MAX_LEN 32 - -#define STATUS_LINE_MAX_LEN 128 - -/* - * Escape codes definitions - */ -#define OLD_CUCM_DICTIONARY_ESCAPE_TAG '\x80' -#define NEW_CUCM_DICTIONARY_ESCAPE_TAG '\x1E' -#define CALL_CONTROL_PHRASE_OFFSET '\x64' // offset 100 -#define MAX_LOCALE_PHRASE_LEN 256 -#define MAX_LOCALE_STRING_LEN 1024 - -/* - * Escaped index string codes for Call Mgr dictionary phrases - */ -#define INDEX_STR_KEY_NOT_ACTIVE (char *) "\x80\x2D" -#define INDEX_STR_BARGE (char *) "\x80\x43" -#define INDEX_STR_PRIVATE (char *) "\x80\x36" -#define INDEX_STR_HOLD_REVERSION (char *) "\x1E\x23" -#define INDEX_STR_MONITORING (char *) "\x1E\x27" -#define INDEX_STR_COACHING (char *) "\x1E\x46" - - -/* - * Index value for phrase strings subject to localization - */ -enum PHRASE_STRINGS_ENUM { - LOCALE_START, - IDLE_PROMPT, - ANONYMOUS, /* fsmdef.o */ - CALL_PROCEEDING_IN, - CALL_PROCEEDING_OUT, - CALL_ALERTING, - CALL_ALERTING_SECONDARY, - CALL_ALERTING_LOCAL, - CALL_CONNECTED, - CALL_INITIATE_HOLD, - PROMPT_DIAL, - LINE_BUSY, - CALL_WAITING, - TRANSFER_FAILED, - CONF_CANNOT_COMPLETE, - UI_CONFERENCE, - UI_UNKNOWN, - REMOTE_IN_USE, - NUM_NOT_CONFIGURED, - UI_FROM, - INVALID_CONF_PARTICIPANT, - UI_PRIVATE, - LOCALE_END -}; - -/* - * Index value for Debug strings NOT subject to localization - */ -enum DEBUG_STRINGS_ENUM { - DEBUG_START, - DEBUG_SEPARATOR_BAR, - DEBUG_CONSOLE_PASSWORD, - DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL, - DEBUG_CONSOLE_KEYWORD_MEMORYMAP, - DEBUG_CONSOLE_KEYWORD_MALLOCTABLE, - DEBUG_CONSOLE_KEYWORD_MEMORYDUMP, - DEBUG_CONSOLE_KEYWORD_DNS, - DEBUG_CONSOLE_KEYWORD_DSPSTATE, - DEBUG_CONSOLE_USAGE_MEMORYDUMP, - DEBUG_CONSOLE_BREAK, - - DEBUG_FUNCTION_ENTRY, - DEBUG_FUNCTION_ENTRY2, - DEBUG_SIP_ENTRY, - DEBUG_SIP_URL_ERROR, - DEBUG_LINE_NUMBER_INVALID, - DEBUG_SIP_SPI_SEND_ERROR, - DEBUG_SIP_SDP_CREATE_BUF_ERROR, - DEBUG_SIP_PARSE_SDP_ERROR, - DEBUG_SIP_FEATURE_UNSUPPORTED, - DEBUG_SIP_DEST_SDP, - DEBUG_SIP_MSG_SENDING_REQUEST, - DEBUG_SIP_MSG_SENDING_RESPONSE, - DEBUG_SIP_MSG_RECV, - DEBUG_SIP_STATE_UNCHANGED, - DEBUG_SIP_FUNCTIONCALL_FAILED, - DEBUG_SIP_BUILDFLAG_ERROR, - DEBUG_GENERAL_FUNCTIONCALL_FAILED, - DEBUG_GENERAL_SYSTEMCALL_FAILED, - DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT, - DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM, - DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO, - DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE, - - DEBUG_SNTP_LI_ERROR, - DEBUG_SNTP_MODE_ERROR, - DEBUG_SNTP_STRATUM_ERROR, - DEBUG_SNTP_TIMESTAMP_ERROR, - DEBUG_SNTP_TIMESTAMP1, - DEBUG_SNTP_TIMESTAMP2, - DEBUG_SNTP_TIME_UPDATE, - DEBUG_SNTP_TS_HEADER, - DEBUG_SNTP_TS_PRINT, - DEBUG_SNTP_SOCKET_REOPEN, - DEBUG_SNTP_DISABLED, - DEBUG_SNTP_REQUEST, - DEBUG_SNTP_RESPONSE, - DEBUG_SNTP_RETRANSMIT, - DEBUG_SNTP_UNICAST_MODE, - DEBUG_SNTP_MULTICAST_MODE, - DEBUG_SNTP_ANYCAST_MODE, - DEBUG_SNTP_VALIDATION, - DEBUG_SNTP_VALIDATION_PACKET, - DEBUG_SNTP_WRONG_SERVER, - DEBUG_SNTP_NO_REQUEST, - DEBUG_SNTP_ANYCAST_RESET, - DEBUG_SOCKET_UDP_RTP, - DEBUG_MAC_PRINT, - DEBUG_IP_PRINT, - DEBUG_SYSBUF_UNAVAILABLE, - DEBUG_MSG_BUFFER_TOO_BIG, - DEBUG_UNKNOWN_TIMER_BLOCK, - DEBUG_CREDENTIALS_BAG_CORRUPTED, - DEBUG_INPUT_EMPTY, - DEBUG_INPUT_NULL, - DEBUG_STRING_DUP_FAILED, - DEBUG_PARSER_STRING_TOO_LARGE, - DEBUG_PARSER_NULL_KEY_TABLE, - DEBUG_PARSER_UNKNOWN_KEY, - DEBUG_PARSER_UNKNOWN_KEY_ENUM, - DEBUG_PARSER_INVALID_START_VAR, - DEBUG_PARSER_INVALID_VAR_CHAR, - DEBUG_PARSER_MISSING_COLON, - DEBUG_PARSER_NO_VALUE, - DEBUG_PARSER_EARLY_EOL, - DEBUG_PARSER_INVALID_VAR_NAME, - DEBUG_PARSER_INVALID_VAR_VALUE, - DEBUG_PARSER_UNKNOWN_VAR, - DEBUG_PARSER_NAME_VALUE, - DEBUG_PARSER_UNKNOWN_NAME_VALUE, - DEBUG_PARSER_UNKNOWN_ERROR, - DEBUG_PARSER_NUM_ERRORS, - DEBUG_PARSER_SET_DEFAULT, - DEBUG_SDP_ERROR_BODY_FIELD, - DEBUG_UDP_OPEN_FAIL, - DEBUG_UDP_PAYLOAD_TOO_LARGE, - DEBUG_TCP_PAYLOAD_TOO_LARGE = DEBUG_UDP_PAYLOAD_TOO_LARGE, - DEBUG_RTP_TRANSPORT, - DEBUG_RTP_INVALID_VOIP_TYPE, - DEBUG_RTP_INVALID_RTP_TYPE, - DEBUG_MEMORY_ALLOC, - DEBUG_MEMORY_FREE, - DEBUG_MEMORY_MALLOC_ERROR, - DEBUG_MEMORY_REALLOC_ERROR, - DEBUG_MEMORY_OUT_OF_MEM, - DEBUG_MEMORY_ENTRY, - DEBUG_MEMORY_SUMMARY, - DEBUG_MEMORY_ADDRESS_HEADER, - DEBUG_MEMORY_DUMP, - DEBUG_DNS_GETHOSTBYNAME, - DEBUG_PMH_INCORRECT_SYNTAX, - DEBUG_PMH_INVALID_FIELD_VALUE, - DEBUG_PMH_INVALID_SCHEME, - DEBUG_PMH_UNKNOWN_SCHEME, - DEBUG_PMH_NOT_ENOUGH_PARAMETERS, - DEBUG_REG_DISABLED, - DEBUG_REG_PROXY_EXPIRES, - DEBUG_REG_SIP_DATE, - DEBUG_REG_SIP_RESP_CODE, - DEBUG_REG_SIP_RESP_FAILURE, - DEBUG_REG_INVALID_LINE, - CC_NO_MSG_BUFFER, - CC_SEND_FAILURE, - GSM_UNDEFINED, - GSM_DBG_PTR, - GSM_FUNC_ENTER, - GSM_DBG1, - FSM_DBG_SM_DEFAULT_EVENT, - FSM_DBG_SM_FTR_ENTRY, - FSM_DBG_FAC_ERR, - FSM_DBG_FAC_FOUND, - FSM_DBG_IGNORE_FTR, - FSM_DBG_IGNORE_SRC, - FSM_DBG_CHANGE_STATE, - FSM_DBG_SDP_BUILD_ERR, - FSMDEF_DBG_PTR, - FSMDEF_DBG1, - FSMDEF_DBG2, - FSMDEF_DBG_SDP, - FSMDEF_DBG_CLR_SPOOF_APPLD, - FSMDEF_DBG_CLR_SPOOF_RQSTD, - FSMDEF_DBG_INVALID_DCB, - FSMDEF_DBG_FTR_REQ_ACT, - FSMDEF_DBG_TMR_CREATE_FAILED, - FSMDEF_DBG_TMR_START_FAILED, - FSMDEF_DBG_TMR_CANCEL_FAILED, - FSMXFR_DBG_XFR_INITIATED, - FSMXFR_DBG_PTR, - FSMCNF_DBG_CNF_INITIATED, - FSMCNF_DBG_PTR, - FSMB2BCNF_DBG_CNF_INITIATED, - FSMB2BCNF_DBG_PTR, - FSMSHR_DBG_BARGE_INITIATED, - LSM_DBG_ENTRY, - LSM_DBG_INT1, - LSM_DBG_CC_ERROR, - VCM_DEBUG_ENTRY, - SM_PROCESS_EVENT_ERROR, - REG_SM_PROCESS_EVENT_ERROR, - DEBUG_END -}; - - -typedef struct { - const char *text; -} debug_string_table_entry; - -extern debug_string_table_entry debug_string_table[]; - -#define get_debug_string(index) ((char*)debug_string_table[(index)].text) - - - -typedef struct { - const char *index_str; -} tnp_phrase_index_str_table_entry; - - -extern tnp_phrase_index_str_table_entry tnp_phrase_index_str_table[]; - -#define platform_get_phrase_index_str(index) ((char*)tnp_phrase_index_str_table[(index)].index_str) -#define get_info_string(index) "NotImplemented" - - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/common/ui.c b/media/webrtc/signaling/src/sipcc/core/common/ui.c deleted file mode 100755 index b85a11b6255..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/common/ui.c +++ /dev/null @@ -1,1547 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** @file tnp_ui.c - * API provided by Platform to the Call Control for User Interface activities - */ - -#include -#include "timecard.h" -#include "cpr.h" -#include "cpr_in.h" -#include "phone.h" -#include "time2.h" -#include "debug.h" -#include "phone_debug.h" -#include "dialplan.h" -#include "ccapi.h" -#include "cfgfile_utils.h" -#include "prot_configmgr.h" -#include "dns_utils.h" -#include "uiapi.h" -#include "lsm.h" -#include "fsm.h" -#include "CCProvider.h" -#include "ccSession.h" -#include "platform_api.h" -#include "vcm.h" -#include "ccapp_task.h" -#include "peer_connection_types.h" - -/* - * Note: Do not include "msprovider.h" here unless the dependencies on - * /vob/ip_phone/ip_g4/infra have been removed, as those dependencies - * break CSF builds. - */ - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ -#define CCAPP_F_PREFIX "CCAPP : %s : " // requires 1 arg: __FUNCTION__ -// Why don't we modify strlib_malloc to handle NULL? -#define STRLIB_CREATE(str) (str)?strlib_malloc((str), strlen((str))):strlib_empty() -// Define default display timeout and priority -#define DEFAULT_DISPLAY_NOTIFY_TIMEOUT 0 -#define DEFAULT_DISPLAY_NOTIFY_PRIORITY 0 - - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ - -/*-------------------------------------------------------------------------- - * External data references - * ------------------------------------------------------------------------- - */ - - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ - -extern int Basic_Get_Line_By_Name(char *name); -extern char *Basic_is_phone_forwarded(line_t line); -extern void dp_int_dial_immediate(line_t line, callid_t call_id, - boolean collect_more, char *digit_str, - char *g_call_id, - monitor_mode_t monitor_mode); -extern void dp_int_init_dialing_data(line_t line, callid_t call_id); -extern callid_t dp_get_dialing_call_id(void); -extern void dp_int_update_key_string(line_t line, callid_t call_id, - char *digits); -extern void platform_set_time(int32_t gmt_time); -extern session_id_t createSessionId(line_t line, callid_t call); -// XXX need to either make msprovider.h platform-independent and include that file instead, -// or move ui_keypad_button out of this file (ccmedia.c, perhaps?) - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ - -/** - * wrapper to post Call State change to CCAPP - * - * @param event - new state change event - * @param nLine - line identifier for which call state change - * @param nCallID - call identifier - * - * - * @return none (Side effect: Call bubble changes accordingly) - * - */ -void -ui_call_state (call_events event, line_t nLine, callid_t nCallID, cc_causes_t cause) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"event=%d", DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), - event); - - if (nCallID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(nLine, nCallID); - msg.eventID = CALL_STATE; - msg.update.ccSessionUpd.data.state_data.state = event; - msg.update.ccSessionUpd.data.state_data.line_id = nLine; - msg.update.ccSessionUpd.data.state_data.cause = cause; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d) msg", __FUNCTION__, event); - } -} - -/** - * wrapper to post presentation for new call to CCAPP - * Function: ui_new_call - * - * @param nLine line identifier - * @param nCallID - call identifier - * @param call_attr - call attribute(normal, transfer consult, conf consult) - * @param call_instance_id - call instance identifier - * - * @return none - */ -void -ui_new_call (call_events event, line_t nLine, callid_t nCallID, - int call_attr, uint16_t call_instance_id, boolean dialed_digits) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"state=%d attr=%d call_instance=%d, dialed_digits=%s", - DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), event, call_attr, call_instance_id, (dialed_digits)? "true" : "false"); - - if (nCallID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID= createSessionId(nLine, nCallID); - - msg.eventID = CALL_NEWCALL; - msg.update.ccSessionUpd.data.state_data.state = event; - msg.update.ccSessionUpd.data.state_data.attr = call_attr; - msg.update.ccSessionUpd.data.state_data.inst = call_instance_id; - msg.update.ccSessionUpd.data.state_data.line_id = nLine; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d) msg", __FUNCTION__, event); - } - - return; -} - -/** - * set or change the attribute on the call and reflect the changes - * to call plane (such as change in softkeys or other visual aspects). - * used to change the call attribute back to normal from consult - * - * Posts the update to CCAPP - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param attr - call attribute has to be one of call_attr_t - * - * @return none - */ -void -ui_set_call_attr (line_t line_id, callid_t call_id, call_attr_t attr) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"attr=%d", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__), attr); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_ATTR; - msg.update.ccSessionUpd.data.state_data.attr = attr; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_ATTR(%d) msg", __FUNCTION__, attr); - } -} - -/** - * Wrapper for ui_update_callref - * - * @param line - line for the session - * @param call_id - callid for the session - * @param callref - callref for the session - * - * @return none - */ -void -ui_update_callref (line_t line, callid_t call_id, unsigned int callref) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"callref = %d", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), callref); - - if ( callref == 0 ) return; - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_CALLREF; - msg.update.ccSessionUpd.data.callref = callref; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_REF() msg", __FUNCTION__); - } - - return; -} - - -/** - * Wrapper for ui_update_gcid - global_call_id - * - * @param line - line for the session - * @param call_id - callid for the session - * @param gcid - Global CallId for the session - * - * @return none - */ -void -ui_update_gcid (line_t line, callid_t call_id, char *gcid) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"gcid = %s", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), gcid); - - if ( *gcid == '\0' ) return; - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_GCID; - sstrncpy(msg.update.ccSessionUpd.data.gcid, gcid, CC_MAX_GCID); - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_GCID() msg", __FUNCTION__); - } - - return; -} - -/** - * Wrapper for ui_update_video_avail - * indicates video stream is avail for this session to UI - * @param line - line for the session - * @param call_id - callid for the session - * - * @return none - */ -void -ui_update_video_avail (line_t line, callid_t call_id, int avail) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = VIDEO_AVAIL; - msg.update.ccSessionUpd.data.action = avail; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send VIDEO_AVAIL() msg", __FUNCTION__); - } - - return; -} - -void ui_update_media_interface_change(line_t line, callid_t call_id, group_call_event_t event) { - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - if (event != MEDIA_INTERFACE_UPDATE_BEGIN && - event != MEDIA_INTERFACE_UPDATE_SUCCESSFUL && - event != MEDIA_INTERFACE_UPDATE_FAIL) { - // un-related event. ignore. - return; - } - - if (event != MEDIA_INTERFACE_UPDATE_BEGIN) { - /* we are sending final result */ - g_dock_undock_event = MEDIA_INTERFACE_UPDATE_NOT_REQUIRED; - } - - DEF_DEBUG(DEB_L_C_F_PREFIX "event=%s", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - event == MEDIA_INTERFACE_UPDATE_BEGIN ? "MEDIA_INTERFACE_UPDATE_BEGIN" : - event == MEDIA_INTERFACE_UPDATE_SUCCESSFUL ? "MEDIA_INTERFACE_UPDATE_SUCCESSFUL" : - event == MEDIA_INTERFACE_UPDATE_FAIL ? "MEDIA_INTERFACE_UPDATE_FAIL" : "unknown"); - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - msg.sessionID = createSessionId(line, call_id); - msg.eventID = event; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send media update () msg", __FUNCTION__); - } -} - -void -ui_call_stop_ringer (line_t line, callid_t call_id) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = RINGER_STATE; - msg.update.ccSessionUpd.data.ringer.start = FALSE; - msg.update.ccSessionUpd.data.ringer.mode = VCM_RING_OFF; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send RINGER_STATE() msg", __FUNCTION__); - } - - return; -} - -void -ui_call_start_ringer (vcm_ring_mode_t ringMode, short once, line_t line, callid_t call_id) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = RINGER_STATE; - msg.update.ccSessionUpd.data.ringer.start = TRUE; - msg.update.ccSessionUpd.data.ringer.mode = ringMode; - msg.update.ccSessionUpd.data.ringer.once = (cc_boolean) once; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send RINGER_STATE() msg", __FUNCTION__); - } - - return; -} - -/** - * Wrapper for ui_update_video_avail - * indicates video stream is avail for this session to UI - * @param line - line for the session - * @param call_id - callid for the session - * - * @return none - */ -void -ui_update_video_offered (line_t line, callid_t call_id, int avail) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = VIDEO_OFFERED; - msg.update.ccSessionUpd.data.action = avail; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send VIDEO_OFFERED() msg", __FUNCTION__); - } - - return; -} - - -/** - * Wrapper for ui call info post to CCAPP - * call bubble with appropriate party information - * - * @param pCallingPartyNameStr/NumberStr - Calling party information - * @param displayCallingNumber - * @param pCalledPartyNameStr/NumberStr - called party information - * @param displayCalledNumber - * @param pOrigCalledNameStr/NumberStr - * @param pLastRedirectingNameStr/NumberStr - * @param call_type - * @param line - line identifier - * @param call_id - call identifier - * @param call_instance_id - call instance displayed in call bubble - * @param cc_security - * - * @return none - */ -void -ui_call_info (string_t pCallingPartyNameStr, - string_t pCallingPartyNumberStr, - string_t pAltCallingPartyNumberStr, - boolean displayCallingNumber, - string_t pCalledPartyNameStr, - string_t pCalledPartyNumberStr, - boolean displayCalledNumber, - string_t pOrigCalledNameStr, - string_t pOrigCalledNumberStr, - string_t pLastRedirectingNameStr, - string_t pLastRedirectingNumberStr, - calltype_t call_type, - line_t line, - callid_t call_id, - uint16_t call_instance_id, - cc_security_e call_security, - cc_policy_e call_policy) -{ - session_update_t msg; - const char *uiCalledName; - const char *uiCalledNumber; - const char *uiCallingName; - const char *uiCallingNumber; - int inbound; - char lineName[MAX_LINE_NAME_SIZE]; - char lineNumber[MAX_LINE_NAME_SIZE]; - - memset( &msg, 0, sizeof(session_update_t)); - - - TNP_DEBUG(DEB_L_C_F_PREFIX"call instance=%d callednum=%s calledname=%s clngnum=%s clngname = %s", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), call_instance_id, pCalledPartyNumberStr, - pCalledPartyNameStr, pCallingPartyNumberStr, pCallingPartyNameStr); - - TNP_DEBUG(DEB_F_PREFIX"calltype=%d displayClng=%d displayCld=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), call_type, - displayCallingNumber, displayCalledNumber); - - - inbound = (call_type == FSMDEF_CALL_TYPE_INCOMING) || (call_type == FSMDEF_CALL_TYPE_FORWARD); - uiCalledNumber = pCalledPartyNumberStr; - uiCalledName = pCalledPartyNameStr; - uiCallingNumber = pCallingPartyNumberStr; - uiCallingName = pCallingPartyNameStr; - - config_get_line_string(CFGID_LINE_DISPLAYNAME, lineName, line, sizeof(lineName)); - config_get_line_string(CFGID_LINE_NAME, lineNumber, line, sizeof(lineNumber)); - - if (inbound) { - uiCalledNumber = lineNumber; - uiCalledName = lineName; - } else { - uiCallingNumber = lineNumber; - uiCallingName = lineName; - } - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_INFORMATION; - msg.update.ccSessionUpd.data.call_info.clgName = uiCallingName?strlib_malloc(uiCallingName, strlen(uiCallingName)):strlib_empty(); - - if ( uiCallingNumber== NULL || (inbound && !displayCallingNumber)) { - msg.update.ccSessionUpd.data.call_info.clgNumber = strlib_empty(); - } else { - msg.update.ccSessionUpd.data.call_info.clgNumber = strlib_malloc(uiCallingNumber, strlen(uiCallingNumber)); - } - - if ( pAltCallingPartyNumberStr == NULL || (inbound && !displayCallingNumber)) { - msg.update.ccSessionUpd.data.call_info.altClgNumber = strlib_empty(); - } else { - msg.update.ccSessionUpd.data.call_info.altClgNumber = strlib_malloc(pAltCallingPartyNumberStr,strlen(pAltCallingPartyNumberStr)); - } - - msg.update.ccSessionUpd.data.call_info.cldName = uiCalledName?strlib_malloc(uiCalledName,strlen(uiCalledName)):strlib_empty(); - - if (uiCalledNumber == NULL || (!inbound && !displayCalledNumber)) { - msg.update.ccSessionUpd.data.call_info.cldNumber = strlib_empty(); - } else { - msg.update.ccSessionUpd.data.call_info.cldNumber = strlib_malloc(uiCalledNumber,strlen(uiCalledNumber)); - } - msg.update.ccSessionUpd.data.call_info.origCalledName = pOrigCalledNameStr?strlib_malloc(pOrigCalledNameStr, strlen(pOrigCalledNameStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.origCalledNumber = pOrigCalledNumberStr?strlib_malloc(pOrigCalledNumberStr,strlen(pOrigCalledNumberStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.lastRedirectingName = pLastRedirectingNameStr?strlib_malloc(pLastRedirectingNameStr,strlen(pLastRedirectingNameStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.lastRedirectingNumber = pLastRedirectingNumberStr?strlib_malloc(pLastRedirectingNumberStr, strlen(pLastRedirectingNumberStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.call_type = call_type; - msg.update.ccSessionUpd.data.call_info.instance_id = call_instance_id; - msg.update.ccSessionUpd.data.call_info.security = call_security; - msg.update.ccSessionUpd.data.call_info.policy = call_policy; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_INFO() msg", __FUNCTION__); - } - - return; -} - -/** - * Wrapper for ui cc capability post to CCAPP - * - * @param line - line identifier - * @param callID - call identifier - * @param capability - cc capability - * - * @return none - */ -void -ui_cc_capability (line_t line, callid_t call_id, string_t recv_info_list) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"recv_info_list:%s", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - recv_info_list); - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_RECV_INFO_LIST; - msg.update.ccSessionUpd.data.recv_info_list = strlib_copy(recv_info_list); - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_RECV_INFO_LIST msg", __FUNCTION__); - } -} - -/** - * Wrapper for ui info received post to CCAPP - * - * @param line - line identifier - * @param callID - call identifier - * @param info_package - the Info-Package header of the Info Package - * @param content_type - the Content-Type header of the Info Package - * @param message_body - the message body of the Info Package - * - * @return none - */ -void -ui_info_received (line_t line, callid_t call_id, const char *info_package, - const char *content_type, const char *message_body) -{ - session_rcvd_info_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"info_package:%s content_type:%s message_body:%s", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - info_package, content_type, message_body); - - msg.sessionID = createSessionId(line, call_id); - msg.packageID = INFO_PKG_ID_GENERIC_RAW; - msg.info.generic_raw.info_package = info_package?strlib_malloc(info_package, strlen(info_package)):strlib_empty(); - msg.info.generic_raw.content_type = content_type?strlib_malloc(content_type, strlen(content_type)):strlib_empty(); - msg.info.generic_raw.message_body = message_body?strlib_malloc(message_body, strlen(message_body)):strlib_empty(); - - if ( ccappTaskPostMsg(CCAPP_RCVD_INFO, &msg, sizeof(session_rcvd_info_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_INFO_RECEIVED msg", __FUNCTION__); - } -} - - -/** - * An internal wrapper for ui call status post to CCAPP - * - * @param pString - status string - * @param line - line identifier - * @param callID - call identifier - * @param timeout - timeout for the status line - * - * @return none - */ -static void -ui_set_call_status_display (string_t status, line_t line, callid_t callID, int timeout, char priority) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"the stat string =%s, timeout= %d, priority=%d", DEB_L_C_F_PREFIX_ARGS(UI_API, line, callID, __FUNCTION__), - status, - timeout, - priority); - - if (callID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, callID); - msg.eventID = CALL_STATUS; - msg.update.ccSessionUpd.data.status.timeout = timeout; - msg.update.ccSessionUpd.data.status.priority = priority; - if ( status ) { - msg.update.ccSessionUpd.data.status.status = strlib_malloc(status, strlen(status)); - } else { - msg.update.ccSessionUpd.data.status.status = strlib_empty(); - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATUS(%s) msg", __FUNCTION__, status); - } -} - - -/** - * Wrapper for ui call status post to CCAPP - * - * @param pString - status string - * @param line - line identifier - * @param callID - call identifier - * @param timeout - timeout for the status line - * - * @return none - */ -void -ui_set_call_status (string_t status, line_t line, callid_t callID) -{ - - TNP_DEBUG(DEB_L_C_F_PREFIX"the stat string =%s", DEB_L_C_F_PREFIX_ARGS(UI_API, line, callID, __FUNCTION__), - status); - - if (callID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - ui_set_call_status_display(status, line, callID, DEFAULT_DISPLAY_NOTIFY_TIMEOUT, DEFAULT_DISPLAY_NOTIFY_PRIORITY); -} - - -/** - * Wrapper for sending notification CCAPP - * - * @param promptString - notification string - * @param timeout - timeout of this notify - * @param notifyProgress- the type of notification - * TRUE - Progress, FALSE- Normal - * @param priority - priority of this notification - * Pri 1..5 Low .. High - * - * @return none - */ -void -ui_set_notification (line_t line, callid_t call_id, char *promptString, int timeout, - boolean notifyProgress, char priority) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d callid=%d str=%s tout=%d notifyProgress=%d pri=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - line, call_id, promptString, timeout, notifyProgress, priority); - - if (line > 0 && call_id > 0) { - ui_set_call_status_display(promptString, line, call_id, timeout, priority); - return; - } - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_NOTIFICATION; - msg.update.ccFeatUpd.data.notification.timeout = timeout; - msg.update.ccFeatUpd.data.notification.notifyProgress = notifyProgress; - msg.update.ccFeatUpd.data.notification.priority = priority; - if ( promptString != NULL ) { - msg.update.ccFeatUpd.data.notification.prompt = strlib_malloc(promptString, strlen(promptString)); - } else { - msg.update.ccFeatUpd.data.notification.prompt = strlib_empty(); - } - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_NOTIFICATION(%s) msg", __FUNCTION__, promptString); - } -} - -/** - * CCAPPPost to clear the previous notify of given priority - * - * @param priority - notification of the given pri - * - * @return none - */ -/* TBD: the API should have priority param */ -void -ui_clear_notification () -{ - TNP_DEBUG(DEB_F_PREFIX"called..", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__)); - - // A promptString of NULL shall act as a clear - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, NULL, 0, FALSE, 1); -} - -/** - * - * CCAPP Post to set the MWI lamp indication of the device - * - * @param 1 - on or else off - * - * @return none - */ -void -ui_change_mwi_lamp (int status) -{ - feature_update_t msg; - - - TNP_DEBUG(DEB_F_PREFIX"status=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), status); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_MWILAMP; - msg.update.ccFeatUpd.data.mwi_status.status = status; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_MWILAMP(%d) msg", __FUNCTION__, status); - } -} - -/** - * - * CCAPP post to set the MWI lamp indication for given line - * - * @param line - line identifier - * @param on - TRUE -> on, otherwise off - * - * @return none - */ -void -ui_set_mwi (line_t line, boolean status, int type, int newCount, int oldCount, int hpNewCount, int hpOldCount) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d count=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), line, status); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_MWI; - msg.update.ccFeatUpd.data.mwi_status.line = line; - msg.update.ccFeatUpd.data.mwi_status.status = status; - msg.update.ccFeatUpd.data.mwi_status.type = type; - msg.update.ccFeatUpd.data.mwi_status.newCount = newCount; - msg.update.ccFeatUpd.data.mwi_status.oldCount = oldCount; - msg.update.ccFeatUpd.data.mwi_status.hpNewCount = hpNewCount; - msg.update.ccFeatUpd.data.mwi_status.hpOldCount = hpOldCount; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_MWI(%d,%d) msg", __FUNCTION__, line, status); - } -} - -/* - * Function: ui_mnc_reached - * - * @param line - line number - * @param boolean - maximum number of calls reached on this line - * - * Description: - * post mnc_reached status to CCAPP - * - * @return none - * - */ -void ui_mnc_reached (line_t line, boolean mnc_reached) -{ - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"line %d: Max number of calls reached =%d", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - line, mnc_reached); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_MNC_REACHED; - msg.update.ccFeatUpd.data.line_info.line = line; - msg.update.ccFeatUpd.data.line_info.info = mnc_reached; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_MNC_REACHED(%d,%d) msg", __FUNCTION__, - line, mnc_reached); - } - -} - -/** - * - * Check if MWI is active on a given line - * - * @param line - line identifier - * - * @return true if active; false otherwise. - */ -boolean -ui_line_has_mwi_active (line_t line) -{ - session_mgmt_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), line); - - msg.func_id = SESSION_MGMT_LINE_HAS_MWI_ACTIVE; - msg.data.line_mwi_active.line = line; - - ccappSyncSessionMgmt(&msg); - - return msg.data.line_mwi_active.ret_val; -} - - -/** - * CCAPP msg post to Set linekey values - * - * @param line - line identifier - * @param SpeedDial - Speeddial string to be changed - * @param label - Feature lable to be changed - * - * @return none - */ -void -ui_update_label_n_speeddial (line_t line, line_t button_no, string_t speed_dial, string_t label) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d speeddial=%s displayname=%s", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), line, - speed_dial, label); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_LABEL_N_SPEED; - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.line = line; - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.button = (unsigned char) button_no; - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.speed = strlib_malloc(speed_dial, sizeof(speed_dial)); - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.label = strlib_malloc(label, sizeof(label)); - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_LABEL_N_SPEED(%d) msg", __FUNCTION__, button_no); - } -} - -/** - * Inform CCAPP of registration state of given line in Line Plane - * - * @param line - line identifier - * @param registered - whether the line was registered or not - * - * @return none - */ -void -ui_set_sip_registration_state (line_t line, boolean registered) -{ - feature_update_t msg; - int value; - - TNP_DEBUG(DEB_F_PREFIX"%s %d: %s", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - (line==CC_ALL_LINES) ? "ALL LINES":"LINE" ,line, - (registered)? "REGISTERED":"UN-REGISTERED"); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_REG_STATE; - msg.update.ccFeatUpd.data.line_info.line = line; - msg.update.ccFeatUpd.data.line_info.info = registered ? CC_REGISTERED : CC_UNREGISTERED; - config_get_value(CFGID_PROXY_REGISTER, &value, sizeof(value)); - if (value == 0) { - msg.update.ccFeatUpd.data.line_info.info = CC_REGISTERED; - } - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d, %d) msg", __FUNCTION__, line, registered); - } -} - -/** - * Inform CCAPP of registration state of given line in Line Plane - * - * @param registered - line registered true/false - * - * @return none - */ -void -ui_update_registration_state_all_lines (boolean registered) -{ - DEF_DEBUG(DEB_F_PREFIX"***********ALL LINES %s****************", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - (registered)? "REGISTERED":"UN-REGISTERED"); - - ui_set_sip_registration_state(CC_ALL_LINES, registered); - -} - -/** - * Inform the CCAPP that all registration attempts with - * all call controls have failed. - * - * @param none - * - * @return none - */ -void -ui_reg_all_failed (void) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"***********Registration to all CUCMs failed.***********", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__)); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_REG_ALL_FAIL; - msg.update.ccFeatUpd.data.line_info.line = CC_ALL_LINES; - msg.update.ccFeatUpd.data.line_info.info = FALSE; - - if ( ccappTaskPostMsg(CCAPP_REG_ALL_FAIL, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE() msg", __FUNCTION__); - } -} - -/** - * - * inform CCAPP about the status of the CCMs - * - * @param ccm_addr - IP address string - * @param status - status (notconnected, active, standby, notavail) - * - * @return none - */ -void -ui_set_ccm_conn_status (char * ccm_addr, int status) -{ - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********CUCM %s %s***********", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), ccm_addr, - ((status == 0) ?"Not connected":((status == 1)?"STAND BY": - ((status == 2)?"ACTIVE":"UNKNOWN")))); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_CCM_CONN_STATUS; - msg.update.ccFeatUpd.data.ccm_conn.addr = ccm_addr?strlib_malloc(ccm_addr, strlen(ccm_addr)):strlib_empty(); - msg.update.ccFeatUpd.data.ccm_conn.status = status; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_CCM_CONN_STATUS(%d) msg", __FUNCTION__, status); - } -} - -/** - * Treat given line and callid as being put on hold by user. - * - * @param line - line identifier - * @param call_id - call identifier - * - * @return none - */ -void -ui_set_local_hold (line_t line, callid_t call_id) -{ - /* THIS IS A NOP FOR TNP */ - TNP_DEBUG(DEB_L_C_F_PREFIX"called", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, "ui_set_local_hold")); - return; -} - -/** - * Sets the call forward status as a flashing arrow and status line - * accordingly. - * - * @param line - line identifier - * @param cfa - call forward all true/false - * @param cfa_number - string representing call forwarded to number - * - * @return none - */ -void -ui_cfwd_status (line_t line, boolean cfa, char *cfa_number, boolean lcl_fwd) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d cfa=%d cfa_number=%s lcl_fwd=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - line, cfa, cfa_number, lcl_fwd); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_CFWD; - msg.update.ccFeatUpd.data.cfwd.line = line; - msg.update.ccFeatUpd.data.cfwd.isFwd = cfa; - msg.update.ccFeatUpd.data.cfwd.isLocal = lcl_fwd; - msg.update.ccFeatUpd.data.cfwd.cfa_num = cfa_number?strlib_malloc(cfa_number, strlen(cfa_number)):strlib_empty(); - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_CFWD(%d) msg", __FUNCTION__, cfa); - } -} - -/** - * Get the Idle prompt string. - * - * @return the idle prompt phrase from locale - */ -char * -ui_get_idle_prompt_string (void) -{ - TNP_DEBUG(DEB_F_PREFIX"called", DEB_F_PREFIX_ARGS(UI_API, "ui_get_idle_prompt_string")); - return platform_get_phrase_index_str(IDLE_PROMPT); -} - -/** - * Set the Appropriate Idle prompt string. - * - * @param pString - New Idle Prompt String - * @param prompt - The Idle Prompt To Be Modified - * - * @return the idle prompt phrase from locale - */ -void -ui_set_idle_prompt_string (string_t pString, int prompt) -{ - TNP_DEBUG(DEB_F_PREFIX"Prompt=%d, Prompt string=%s NOP operation", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), prompt, pString); -} - -/** - * Updates placed call information for call history - * - * @param line - line identifier - * @param call_id - call identifier - * @param cldName - called name - * @param cldNumber - called number - * - * @return none - */ -void -ui_update_placed_call_info (line_t line, callid_t call_id, string_t cldName, - string_t cldNumber) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"calledName:calledNumber %s:%s", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), cldName, cldNumber); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - TNP_DEBUG(DEB_F_PREFIX"invalid callid", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__)); - return; - } - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_PLACED_INFO; - msg.update.ccSessionUpd.data.plcd_info.cldName = strlib_empty(); - msg.update.ccSessionUpd.data.plcd_info.cldNum = strlib_empty(); - - if ( cldName) { - msg.update.ccSessionUpd.data.plcd_info.cldName = strlib_update( - msg.update.ccSessionUpd.data.plcd_info.cldName, cldName); - } - if ( cldNumber) { - msg.update.ccSessionUpd.data.plcd_info.cldNum = strlib_update( - msg.update.ccSessionUpd.data.plcd_info.cldNum, cldNumber); - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_PLACED_INFO(%s) msg", __FUNCTION__, cldNumber); - } -} - - -/** - * Description: remove last digit from input box - * - * @param line - line identifier - * @param call_id - call identifier - * - * @return none - */ -void -ui_delete_last_digit (line_t line_id, callid_t call_id) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"called", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_DELETE_LAST_DIGIT; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_DELETE_LAST_DIGIT() msg", __FUNCTION__); - } -} - -/** - * Keep/Remove BackSpace key if presented - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param enable - TRUE -> enable backspace softkey - * - * @return none - */ -void -ui_control_featurekey_bksp (line_t line_id, callid_t call_id, boolean enable) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"enable=%d", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__), - enable); - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_ENABLE_BKSP; - msg.update.ccSessionUpd.data.action = enable; - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_ENABLE_BKSP(%d) msg", __FUNCTION__, enable); - } -} - - -/** - * Select(lock-down) the call specified. - * For tnp this visually places a check box on the bubble. - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param selected - TRUE -> call is locked-down in signaling, - * mark as such on UI - * - * @return none - */ -void -ui_call_selected (line_t line_id, callid_t call_id, int selected) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"selected=%d", - DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__), selected); - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_SELECTED; - msg.update.ccSessionUpd.data.action = selected; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_SELECTED(%d) msg", __FUNCTION__, selected); - } -} - -/** - * Send the BLF state to the UI apps. - * - * @param[in] state - TRUE/FALSE - * - * @return none - */ -void ui_BLF_notification (int request_id, cc_blf_state_t blf_state, int app_id) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"state=%d app_id=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), blf_state, app_id); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_BLF; - msg.update.ccFeatUpd.data.blf_data.state = blf_state; - msg.update.ccFeatUpd.data.blf_data.request_id = request_id; - msg.update.ccFeatUpd.data.blf_data.app_id = app_id; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_BLF(state=%d, app_id=%d) msg", - __FUNCTION__, blf_state, app_id); - } -} - -/** - * - * Change the softkey set to preservation key set (with just the EndCall key) - * From the platform perspective, this is strictly a softkey set change - * operation. There is no underlying state change in the call or its status. - * In other words, after this invocation, the clients can still issue - * ui_call_state() or any other call operation if they deem fit and - * the softkey set will adhere to that state. - * - * @param line_id - line identifier - * @param call_id - call identifier - * - * @return none - */ -void -ui_call_in_preservation (line_t line_id, callid_t call_id) -{ - TNP_DEBUG(DEB_L_C_F_PREFIX"called", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__)); - - /* simply update the state . A Preservation event from - CUCM is just for the session */ - ui_call_state (evCallPreservation , line_id, call_id, CC_CAUSE_NORMAL); -} - -/** - * request ui to present a named softkey set for given call. - * The softkey set passed(set_name param) must be known to the platform. - * enable_mask is a set of bits (starting from LSB) one for each softkey. - * (so least significant bit represents left most softkey and so on). - * This function is typically used to mask certain softkeys in a given set. - * Use of this API as general purpose mechanism to present softkeys is - * discouraged because it breaks encapsulation. This API is introduced - * for the tough cases where adapter can not determine which keys to - * mask based on its state alone. - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param set_name - name of the softkey set - * @param sk_mask_list - the softkey events that need to be masked - * @param len - length of the softkey list array - * - * @return none - */ -void -ui_select_feature_key_set (line_t line_id, callid_t call_id, char *set_name, - int sk_mask_list[], int len) -{ - int i; - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"called", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - if (len <= 0 || len > MAX_SOFT_KEYS) { - TNP_DEBUG(DEB_F_PREFIX"Incorrect softkey array length passed in : %d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), len); - return; - } - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_SELECT_FEATURE_SET; - - if ( set_name == NULL ) { - // No point continuing here - return; - } - - msg.update.ccSessionUpd.data.feat_set.featSet = set_name?strlib_malloc(set_name, sizeof(set_name)):strlib_empty(); - for (i = 0; i < len; i++) { - msg.update.ccSessionUpd.data.feat_set.featMask[i] = sk_mask_list[i]; - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_SELECT_FEATURE_SET() msg", __FUNCTION__); - } -} - - -/* Test Interface Operations */ - -/** - * Inject a simulated keypress into the Java Infrastructure - * - * @param uri - string - * - * @return none - */ -void -ui_execute_uri (char *uri) -{ - session_mgmt_t msg; - - TNP_DEBUG(DEB_F_PREFIX"uri=%s", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), uri); - - msg.func_id = SESSION_MGMT_EXECUTE_URI; - msg.data.uri.uri = STRLIB_CREATE(uri); - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(DEB_F_PREFIX"failed to send EXECUTE_URI() msg", DEB_F_PREFIX_ARGS(PLAT_API, __FUNCTION__)); - } -} - -/* Log Message Interface Operations */ - -/** - * - * Update Security (mainly lock) Icon on the call bubble. - * NOTE: Only used to indicate media security (ENCRYPTED or not). - * For updating the signaling security(shield icon), use uiCallInfo or - * uiUpdateCallInfo. - * - * @param line - line identifier - * @param call_id - call identifier - * @param call_security - follows the cc_security_e enum - * - * @return none - */ -void -ui_update_call_security (line_t line, callid_t call_id, - cc_security_e call_security) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"security=%d", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - call_security); - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_SECURITY; - msg.update.ccSessionUpd.data.security = call_security; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_SECURITY(%d) msg", __FUNCTION__, call_security); - } -} - -/* - *Just for TNP currently. - */ -void -ui_update_conf_invoked (line_t line, callid_t call_id, - boolean invoked) -{ - //Nothing to do here -} - - -/** - * - * Cancel the feature plane given by call_id. - * - * @param line - line identifier - * @param call_id - call identifier - * @param target_call_id - target call id - * - * @return none - */ -void -ui_terminate_feature (line_t line, callid_t call_id, - callid_t target_call_id) -{ - session_update_t msg; - memset( &msg, 0, sizeof(session_update_t)); - - TNP_DEBUG(DEB_L_C_F_PREFIX"target_call_id=%d", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - target_call_id); - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_FEATURE_CANCEL; - if (target_call_id != CC_NO_CALL_ID) { - msg.update.ccSessionUpd.data.target_sess_id = createSessionId(line, target_call_id); - } else { - msg.update.ccSessionUpd.data.target_sess_id = 0; - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_FEATURE_CANCEL(%d) msg", __FUNCTION__, target_call_id); - } -} - -/* APIs required for CTI operations */ - -/* NOP for TNP: the speaker mode is set by media manager. if call control - * need to set the mode explicitely use vcm_set_speaker_mode. - */ -void -ui_set_speaker_mode (boolean mode) -{ - return; -} - -void -ui_cfwdall_req (unsigned int line) -{ - lsm_clear_cfwd_all_ccm(line); - return; -} - - -/***********************************************************/ - -char * -Basic_is_phone_forwarded (line_t line) -{ - TNP_DEBUG(DEB_F_PREFIX"called for line %d", DEB_F_PREFIX_ARGS(UI_API, "Basic_is_phone_forwarded"), line); - return ((char *) lsm_is_phone_forwarded(line)); -} - -void -ui_sip_config_done (void) -{ -} - -/** - * convert to numeric dtmf tone code that ms - * understands from ascii code - */ -static int map_digit(char k) -{ - switch(k) { - case '1': - return 1; - case '2': - return 2; - case '3': - return 3; - case '4': - return 4; - case '5': - return 5; - case '6': - return 6; - case '7': - return 7; - case '8': - return 8; - case '9': - return 9; - case '0': - return 0; - case '*': - return 10; - case'#': - return 11; - case 'A': - return 12; - case 'B': - return 13; - case 'C': - return 14; - case 'D': - return 15; - default: - return -1; - } -} - - -/** - * Emulate keypad button press - * - * @param digitstr - one or more digits to be pressed - * @param direction - either VCM_PLAY_TONE_TO_EAR or VCM_PLAY_TONE_TO_NET - * or VCM_PLAY_TONE_TO_ALL - * - * @return none - */ -void -ui_keypad_button (char *digitstr, int direction) -{ - int digit; - unsigned int i; - - - for (i=0; iline, call_id, __FUNCTION__)); - - msg.sessionID = createSessionId(dcb->line, call_id); - msg.eventID = CALL_LOGDISP; - msg.update.ccSessionUpd.data.action = logdisp; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR("%s: failed to send CALL_PRESERVATION_ACTIVE(%d) msg", __FUNCTION__, call_id); - } -} - -/** - * Stub for ui_control_feature - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param feature - name of the softkey set - * @param enable - enable/disable - * - * @return none - */ -void -ui_control_feature (line_t line_id, callid_t call_id, - int feat_list[], int len, int enable) -{ - // do nothing. -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c b/media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c deleted file mode 100755 index b703973fb38..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c +++ /dev/null @@ -1,1630 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "timecard.h" -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "cpr_stdlib.h" -#include "ccapi.h" -#include "ccsip_task.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" -#include "phone.h" -#include "text_strings.h" -#include "string_lib.h" -#include "gsm.h" -#include "vcm.h" -#include "sip_common_regmgr.h" -#include "util_string.h" - -static const char *cc_src_names[] = { - "GSM", - "UI", - "SIP", - "MISC_APP", - "RCC", - "CCAPP" -}; - -#define CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, msg) \ - DEF_DEBUG(DEB_L_C_F_PREFIX"%s -> %s: %-20s",\ - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),\ - cc_src_name(src_id), cc_src_name(dst_id), msg) - - -callid_t cc_get_new_call_id (void) -{ - static callid_t call_id = CC_NO_CALL_ID; - - if (++call_id == 0) { - call_id = 1; - } - - return call_id; -} - - -const char * -cc_src_name (cc_srcs_t id) -{ - if ((id <= CC_SRC_MIN) || (id >= CC_SRC_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_src_names[id]; -} - - -static void -cc_print_msg (char *pData, int len) -{ - int row = 0; - int col; -#define BYTES_PER_LINE 24 - char buffer[3 * BYTES_PER_LINE + 1]; - int msg_id = *((int *) pData); - - CSFLogDebug("gsm", CCA_F_PREFIX "cc_msg=%s, len=%d", - __FUNCTION__, cc_msg_name((cc_msgs_t) msg_id),len); - - while (len) { - buffer[0] = '\0'; - for (col = 0; (col < BYTES_PER_LINE) && len; col++) { - snprintf(buffer + (3 * col), 4, "%02X ", *pData); - pData++; - len--; - } - CSFLogObnoxious("gsm", "%04X %s",row * BYTES_PER_LINE, buffer); - row++; - } -} - - -/* - * Return a SysBuf and initialize - * Parameters supplied by application: - * - MinSize: size of buffer requested - */ -cprBuffer_t -cc_get_msg_buf (int min_size) -{ - cprBuffer_t buf; - - if (min_size > CPR_MAX_MSG_SIZE) { - /* Size requested exceeds maximum ethernet buffer */ - GSM_ERR_MSG(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG), - __FUNCTION__, min_size); - return (cprBuffer_t)NULL; - } - - buf = gsm_get_buffer((uint16_t) min_size); - if (!buf) { - GSM_ERR_MSG(get_debug_string(DEBUG_SYSBUF_UNAVAILABLE), __FUNCTION__); - return (cprBuffer_t)NULL; - } - - /* Clean out the data region of the message */ - memset(buf, 0, min_size); - - CC_DEBUG(DEB_F_PREFIX "Msg id = %p", DEB_F_PREFIX_ARGS(CC_API, __FUNCTION__), buf); - - return buf; -} - -static cc_rcs_t -cc_send_cmd_msg (uint32_t cmd, cprBuffer_t buf, uint16_t len, cc_srcs_t dst_id) -{ - cpr_status_e rc; - - CC_DEBUG_MSG cc_print_msg((char *) buf, len); - - switch (dst_id) { - case CC_SRC_GSM: - rc = gsm_send_msg(cmd, buf, len); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - case CC_SRC_SIP: - rc = SIPTaskSendMsg(cmd, buf, len, NULL); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - default: - rc = CPR_FAILURE; - break; - } - - return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR; -} - -static cc_rcs_t -cc_send_msg (cprBuffer_t buf, uint16_t len, cc_srcs_t dst_id) -{ - cpr_status_e rc; - - CC_DEBUG_MSG cc_print_msg((char *) buf, len); - - switch (dst_id) { - case CC_SRC_GSM: - rc = gsm_send_msg(GSM_SIP, buf, len); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - case CC_SRC_SIP: - rc = SIPTaskSendMsg(SIP_GSM, buf, len, NULL); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - default: - rc = CPR_FAILURE; - break; - } - - return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR; -} - - -/* - * ROUTINE: cc_initialize_msg_body_parts_info - * - * DESCRIPTION: Initializes the msg body part. - * - * PARAMETERS: - * msg_body - pointer to cc_msgbody_info_t to be initialized. - * - * RETURNS: - * None. - * - * NOTES: None - */ -void -cc_initialize_msg_body_parts_info (cc_msgbody_info_t *msg_body) -{ - if (msg_body == NULL) { - return; - } - msg_body->num_parts = 0; - memset(&msg_body->parts[0], 0, sizeof(msg_body->parts)); -} - -/* - * ROUTINE: cc_mv_msg_body_parts - * - * DESCRIPTION: Move the body parts from source to destination. - * - * PARAMETERS: - * dst_msg - pointer to destination cc_msgbody_info_t - * src_msg - pointer to source cc_msgbody_info_t - * - * RETURNS: - * None - * - * NOTES: The function attempts to free the message bodies - * that might be in the destination to prevent - * memory leak from overridden the destination by - * moving the new message source. - * - * The dst_msg must be pointed to the initialized - * message block either with all zero or at least - * number of parts is set to zero to prevent - * freeing an invalid address. - */ -void -cc_mv_msg_body_parts (cc_msgbody_info_t *dst_msg, cc_msgbody_info_t *src_msg) -{ - if (dst_msg == NULL) { - GSM_ERR_MSG(CCA_F_PREFIX "dst is NULL", __FUNCTION__); - return; - } - - /* Free the msg. bodies that might be in the dest first */ - cc_free_msg_body_parts(dst_msg); - - if (src_msg != NULL) { - /* copy all of the parts */ - *dst_msg = *src_msg; - src_msg->num_parts = 0; - } -} - -/* - * ROUTINE: cc_free_msg_body_parts - * - * DESCRIPTION: Free elements in the msg body part structure. - * - * PARAMETERS: - * msg_body - pointer to cc_msgbody_info_t for freeing. - * - * RETURNS: - * None - * - * NOTES: None - */ -void -cc_free_msg_body_parts (cc_msgbody_info_t *msg_body) -{ - cc_msgbody_t *part; - - if ((msg_body == NULL) || (msg_body->num_parts == 0)) { - /* Nothing to be freed */ - return; - } - - /* Free all of the bodies and their contents */ - part = &msg_body->parts[0]; - for (; msg_body->num_parts; msg_body->num_parts--, part++) { - if (part->body != NULL) { - cpr_free(part->body); - part->body = NULL; - } - if (part->content_id != NULL) { - cpr_free(part->content_id); - part->content_id = NULL; - } - } -} - -/* - * ROUTINE: cc_get_msg_body_info_ptr_from_feature_data - * - * DESCRIPTION: The function gets msg pointer from a cc_feature_data_t - * structure if there is one. The msg body - * info does not aways attach to all features - * i.e. only certain feature IDs have msg body - * in the feature data. The function returns - * pointer to the msg body if the feature has - * valid data and for those features that contain - * msg body. - * - * PARAMETERS: - * id - cc_feature_t. - * data - pointer to cc_feature_data_t of the feature data to - * whose embedded resources need to be freed. - * - * RETURNS: - * msg_body - pointer to msg_body_info_t if there is - * a msg. - * - * NOTES: None - */ -static cc_msgbody_info_t * -cc_get_msg_body_info_ptr_from_feature_data (cc_features_t id, - cc_feature_data_t *data) -{ - cc_msgbody_info_t *msg_body = NULL; - - if (data == NULL) { - return (NULL); - } - - switch (id) { - case CC_FEATURE_HOLD: - msg_body = &data->hold.msg_body; - break; - case CC_FEATURE_RESUME: - case CC_FEATURE_MEDIA: - msg_body = &data->resume.msg_body; - break; - case CC_FEATURE_UPDATE: - msg_body = &data->update.msg_body; - break; - default: - /* - * Other ones do not have msg body info yet, add the handling here - * when adding feature that needs msg body info. - */ - break; - } - return (msg_body); -} - -/* - * ROUTINE: cc_cp_caller - * - * DESCRIPTION: Copy caller ID and other fields from source to destination. - * - * PARAMETERS: - * dst_caller - pointer to destination cc_caller_id_t - * src_caller - pointer to source cc_caller_id_t - * - * RETURNS: - * None - * - * Note: See also cc_mv_caller_id() cc_free_caller(). - */ -static void -cc_cp_caller (cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller) -{ - if ((src_caller == NULL) || (dst_caller == NULL)) { - return; - } - - dst_caller->calling_name = strlib_empty(); - if (src_caller->calling_name != NULL) { - dst_caller->calling_name = strlib_update(dst_caller->calling_name, - src_caller->calling_name); - } - - dst_caller->calling_number = strlib_empty(); - if (src_caller->calling_number != NULL) { - dst_caller->calling_number = strlib_update(dst_caller->calling_number, - src_caller->calling_number); - } - - dst_caller->alt_calling_number = strlib_empty(); - if (src_caller->alt_calling_number != NULL) { - dst_caller->alt_calling_number = strlib_update(dst_caller->alt_calling_number, - src_caller->alt_calling_number); - } - - dst_caller->called_name = strlib_empty(); - if (src_caller->called_name != NULL) { - dst_caller->called_name = strlib_update(dst_caller->called_name, - src_caller->called_name); - } - - dst_caller->called_number = strlib_empty(); - if (src_caller->called_number != NULL) { - dst_caller->called_number = strlib_update(dst_caller->called_number, - src_caller->called_number); - } - - dst_caller->orig_called_name = strlib_empty(); - if (src_caller->orig_called_name != NULL) { - dst_caller->orig_called_name = - strlib_update(dst_caller->orig_called_name, - src_caller->orig_called_name); - } - - dst_caller->orig_called_number = strlib_empty(); - if (src_caller->orig_called_number != NULL) { - dst_caller->orig_called_number = - strlib_update(dst_caller->orig_called_number, - src_caller->orig_called_number); - } - - dst_caller->last_redirect_name = strlib_empty(); - if (src_caller->last_redirect_name != NULL) { - dst_caller->last_redirect_name = - strlib_update(dst_caller->last_redirect_name, - src_caller->last_redirect_name); - } - - dst_caller->last_redirect_number = strlib_empty(); - if (src_caller->last_redirect_number) { - dst_caller->last_redirect_number = - strlib_update(dst_caller->last_redirect_number, - src_caller->last_redirect_number); - } - - dst_caller->orig_rpid_number = strlib_empty(); - if (src_caller->orig_rpid_number != NULL) { - dst_caller->orig_rpid_number = - strlib_update(dst_caller->orig_rpid_number, - src_caller->orig_rpid_number); - } - dst_caller->display_calling_number = src_caller->display_calling_number; - dst_caller->display_called_number = src_caller->display_called_number; - dst_caller->call_type = src_caller->call_type; - dst_caller->call_instance_id = src_caller->call_instance_id; -} - -/* - * ROUTINE: cc_mv_caller_id - * - * DESCRIPTION: Move caller ID fields from source to destination. - * The caller ID fields from the destination will be - * freed if necessary prior to the move. This allows - * caller to replace the older IDs with the new IDs - * without data duplication. - * - * PARAMETERS: - * dst_caller - pointer to destination cc_caller_id_t - * src_caller - pointer to source cc_caller_id_t - * - * RETURNS: - * None - * - * Note: See also cc_cp_caller() cc_free_caller(). - */ -void -cc_mv_caller_id (cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller) -{ - if ((src_caller == NULL) || (dst_caller == NULL)) { - return; - } - - /* - * Move the IDs from the source to the destination. - * After moved the IDs from the source to the destination then - * the source needs to be NULL. - */ - if (src_caller->calling_name != NULL) { - if (dst_caller->calling_name != NULL) { - strlib_free(dst_caller->calling_name); - } - dst_caller->calling_name = src_caller->calling_name; - src_caller->calling_name = NULL; - } - - if (src_caller->calling_number != NULL) { - if (dst_caller->calling_number != NULL) { - strlib_free(dst_caller->calling_number); - } - dst_caller->calling_number = src_caller->calling_number; - src_caller->calling_number = NULL; - } - - if (src_caller->alt_calling_number != NULL) { - if (dst_caller->alt_calling_number != NULL) { - strlib_free(dst_caller->alt_calling_number); - } - dst_caller->alt_calling_number = src_caller->alt_calling_number; - src_caller->alt_calling_number = NULL; - } - - if (src_caller->called_name != NULL) { - if (dst_caller->called_name != NULL) { - strlib_free(dst_caller->called_name); - } - dst_caller->called_name = src_caller->called_name; - src_caller->called_name = NULL; - } - - if (src_caller->called_number != NULL) { - if (dst_caller->called_number != NULL) { - strlib_free(dst_caller->called_number); - } - dst_caller->called_number = src_caller->called_number; - src_caller->called_number = NULL; - } - - if (src_caller->orig_called_name != NULL) { - if (dst_caller->orig_called_name != NULL) { - strlib_free(dst_caller->orig_called_name); - } - dst_caller->orig_called_name = src_caller->orig_called_name; - src_caller->orig_called_name = NULL; - } - - if (src_caller->orig_called_number != NULL) { - if (dst_caller->orig_called_number != NULL) { - strlib_free(dst_caller->orig_called_number); - } - dst_caller->orig_called_number = src_caller->orig_called_number; - src_caller->orig_called_number = NULL; - } - - if (src_caller->last_redirect_name != NULL) { - if (dst_caller->last_redirect_name != NULL) { - strlib_free(dst_caller->last_redirect_name); - } - dst_caller->last_redirect_name = src_caller->last_redirect_name; - src_caller->last_redirect_name = NULL; - } - - if (src_caller->last_redirect_number != NULL) { - if (dst_caller->last_redirect_number != NULL) { - strlib_free(dst_caller->last_redirect_number); - } - dst_caller->last_redirect_number = src_caller->last_redirect_number; - src_caller->last_redirect_number = NULL; - } - - if (src_caller->orig_rpid_number != NULL) { - if (dst_caller->orig_rpid_number != NULL) { - strlib_free(dst_caller->orig_rpid_number); - } - dst_caller->orig_rpid_number = src_caller->orig_rpid_number; - src_caller->orig_rpid_number = NULL; - } - dst_caller->display_calling_number = src_caller->display_calling_number; - dst_caller->display_called_number = src_caller->display_called_number; -} - -/* - * ROUTINE: cc_free_caller_id - * - * DESCRIPTION: Free caller ID fields. The IDs that are not NULL IDs will be - * freed because others might have been moved already. - * - * PARAMETERS: - * caller - pointer to destination cc_caller_id_t - * - * RETURNS: - * None - * - * Note: See also cc_cp_caller() cc_mv_caller(). - */ -static void -cc_free_caller_id (cc_caller_id_t *caller) -{ - if (caller == NULL) { - return; - } - - if (caller->calling_name != NULL) { - strlib_free(caller->calling_name); - } - - if (caller->calling_number != NULL) { - strlib_free(caller->calling_number); - } - - if (caller->alt_calling_number != NULL) { - strlib_free(caller->alt_calling_number); - } - - if (caller->called_name != NULL) { - strlib_free(caller->called_name); - } - - if (caller->called_number != NULL) { - strlib_free(caller->called_number); - } - - if (caller->orig_called_name != NULL) { - strlib_free(caller->orig_called_name); - } - - if (caller->orig_called_number != NULL) { - strlib_free(caller->orig_called_number); - } - - if (caller->last_redirect_name != NULL) { - strlib_free(caller->last_redirect_name); - } - - if (caller->last_redirect_number) { - strlib_free(caller->last_redirect_number); - } - - if (caller->orig_rpid_number != NULL) { - strlib_free(caller->orig_rpid_number); - } -} - -/* - * ROUTINE: cc_free_msg_data - * - * DESCRIPTION: Free resources embedded in CCAPI msg. data - * structure. - * - * PARAMETERS: - * data - pointer to cc_msg_t whose embedded resources - * need to be freed. - * - * RETURNS: - * None - */ -void -cc_free_msg_data (cc_msg_t *msg) -{ - cc_msgbody_info_t *msg_body = NULL; - cc_caller_id_t *caller_id = NULL; - - if (msg == NULL) { - return; - } - switch (msg->msg.setup.msg_id) { - case CC_MSG_SETUP: - msg_body = &msg->msg.setup.msg_body; - caller_id = &msg->msg.setup.caller_id; - strlib_free(msg->msg.setup.recv_info_list); - break; - case CC_MSG_SETUP_ACK: - msg_body = &msg->msg.setup_ack.msg_body; - caller_id = &msg->msg.setup_ack.caller_id; - break; - case CC_MSG_PROCEEDING: - caller_id = &msg->msg.proceeding.caller_id; - break; - case CC_MSG_ALERTING: - msg_body = &msg->msg.alerting.msg_body; - caller_id = &msg->msg.alerting.caller_id; - break; - case CC_MSG_CONNECTED: - msg_body = &msg->msg.connected.msg_body; - caller_id = &msg->msg.connected.caller_id; - strlib_free(msg->msg.connected.recv_info_list); - break; - case CC_MSG_CONNECTED_ACK: - msg_body = &msg->msg.connected_ack.msg_body; - caller_id = &msg->msg.connected_ack.caller_id; - break; - case CC_MSG_FEATURE: - if (msg->msg.feature.data_valid) { - msg_body = cc_get_msg_body_info_ptr_from_feature_data( - msg->msg.feature.feature_id, - &msg->msg.feature.data); - - if (msg->msg.feature.feature_id == CC_FEATURE_CALLINFO) { - caller_id = &msg->msg.feature.data.call_info.caller_id; - } - } - cpr_free(msg->msg.feature.sdp); - break; - case CC_MSG_FEATURE_ACK: - if (msg->msg.feature_ack.data_valid) { - msg_body = cc_get_msg_body_info_ptr_from_feature_data( - msg->msg.feature_ack.feature_id, - &msg->msg.feature_ack.data); - } - break; - case CC_MSG_OPTIONS_ACK: - msg_body = &msg->msg.options_ack.msg_body; - break; - case CC_MSG_AUDIT_ACK: - msg_body = &msg->msg.audit_ack.msg_body; - break; - case CC_MSG_INFO: - strlib_free(msg->msg.info.message_body); - strlib_free(msg->msg.info.content_type); - strlib_free(msg->msg.info.info_package); - break; - default: - return; - } - cc_free_msg_body_parts(msg_body); - cc_free_caller_id(caller_id); -} - -/* - * ROUTINE: cc_cp_msg_body_parts - * - * DESCRIPTION: Copy elements in the msg body part structure. - * - * PARAMETERS: - * dst_msg - pointer to destination cc_msgbody_info_t - * src_msg - pointer to source cc_msgbody_info_t - * - * RETURNS: - * CC_RC_ERROR - * CC_RC_SUCCESS - * - * NOTES: The function attempts to free the message bodies - * that might be in the destination to prevent - * memory leak from overridden the destination by - * moving the new message source. - * - * The dst_msg must be pointed to the initialized - * message block either with all zero or at least - * number of parts is set to zero to prevent - * freeing an invalid address. - */ -cc_rcs_t -cc_cp_msg_body_parts (cc_msgbody_info_t *dst_msg, cc_msgbody_info_t *src_msg) -{ - uint32_t i, body_length; - cc_msgbody_t *src_part, *dst_part; - cc_rcs_t status; - int len; - - if ((dst_msg == NULL) || (src_msg == NULL)) { - return CC_RC_ERROR; - } - /* Free the msg. bodies that might be in the dest first */ - cc_free_msg_body_parts(dst_msg); - - src_part = &src_msg->parts[0]; - dst_part = &dst_msg->parts[0]; - - /* Copy all of the fields of all body parts */ - status = CC_RC_SUCCESS; - for (i = 0; i < src_msg->num_parts; i++, src_part++, dst_part++) { - dst_part->content_type = src_part->content_type; - dst_part->content_disposition = src_part->content_disposition; - - /* Copy body */ - dst_part->body = NULL; - dst_part->body_length = 0; - if ((src_part->body != NULL) && (src_part->body_length > 0)) { - body_length = src_part->body_length; - dst_part->body = (char *) cpr_malloc(body_length); - - if (dst_part->body == NULL) { - /* Unable to allocate memory for body */ - status = CC_RC_ERROR; - break; - } else { - /* - * Copy body including NULL char but the length field - * does not include the extra NULL char. - */ - memcpy(dst_part->body, src_part->body, body_length); - dst_part->body_length = src_part->body_length; - } - } - - dst_part->content_id = NULL; - /* Copy content ID */ - if (src_part->content_id != NULL) { - len = strlen(src_part->content_id) + 1; - dst_part->content_id = (char *) cpr_malloc(len); - if (dst_part->content_id != NULL) { - memcpy(dst_part->content_id, src_part->content_id, len); - } else { - /* Unable to allocate memory for content ID */ - status = CC_RC_ERROR; - break; - } - } - } - dst_msg->num_parts = i; /* number of part copied */ - dst_msg->content_type = src_msg->content_type; - - if (status != CC_RC_SUCCESS) { - /* - * Unable to duplicate the body parts, free all of the allocated - * resources - */ - cc_free_msg_body_parts(dst_msg); - } - return status; -} - -void -cc_int_setup (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_alerting_type alert_info, vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_redirect_t *redirect, - cc_call_info_t *call_info_p, boolean replaces, - string_t recv_info_list, cc_msgbody_info_t *msg_body) -{ - cc_setup_t *pmsg; - - if (caller_id == NULL) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG("%s: caller id is NULL", __FUNCTION__); - return; - } - - CC_DEBUG(DEB_L_C_F_PREFIX " CGPD= %s, CGPN= %s,\n CDPD= %s, CDPN= %s", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), - caller_id->calling_name, caller_id->calling_number, - caller_id->called_name, caller_id->called_number); - - pmsg = (cc_setup_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_SETUP; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->alert_info = alert_info; - pmsg->alerting_ring = alerting_ring; - pmsg->alerting_tone = alerting_tone; - cc_cp_caller(&pmsg->caller_id, caller_id); - - pmsg->call_info.type = CC_FEAT_NONE; - if (call_info_p) { - pmsg->call_info = *call_info_p; - } - - pmsg->replaces = replaces; - - if (redirect != NULL) { - pmsg->redirect = *redirect; - } - - /* Info Package */ - if (recv_info_list && (*recv_info_list != '\0')) { - pmsg->recv_info_list = strlib_copy(recv_info_list); - } else { - pmsg->recv_info_list = strlib_empty(); - } - - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_setup_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body) -{ - cc_setup_ack_t *pmsg; - - pmsg = (cc_setup_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_SETUP_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } -} - - -void -cc_int_proceeding (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id) -{ - cc_proceeding_t *pmsg; - - pmsg = (cc_proceeding_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_PROCEEDING; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg(pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_alerting (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body, boolean inband) -{ - cc_alerting_t *pmsg; - - - pmsg = (cc_alerting_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_ALERTING; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - pmsg->inband = inband; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " inband= %d", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), inband); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_connected (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - string_t recv_info_list, cc_msgbody_info_t *msg_body) -{ - cc_connected_t *pmsg; - - pmsg = (cc_connected_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_CONNECTED; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - - /* Info Package */ - if (recv_info_list && (*recv_info_list != '\0')) { - pmsg->recv_info_list = strlib_copy(recv_info_list); - } else { - pmsg->recv_info_list = strlib_empty(); - } - - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_connected_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body) -{ - cc_connected_ack_t *pmsg; - - pmsg = (cc_connected_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_CONNECTED_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_release (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_causes_t cause, const char *dialstring, - cc_kfact_t *kfactor) -{ - cc_release_t *pmsg; - - if (dialstring == NULL) { - CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause)); - } else { - CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s, dialstring= %s", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause), dialstring); - } - - pmsg = (cc_release_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_RELEASE; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->cause = cause; - - if (dialstring) { - sstrncpy(pmsg->dialstring, dialstring, CC_MAX_DIALSTRING_LEN); - } - if (kfactor != NULL) { - sstrncpy(pmsg->kfactor.rxstats, kfactor->rxstats, CC_KFACTOR_STAT_LEN); - sstrncpy(pmsg->kfactor.txstats, kfactor->txstats, CC_KFACTOR_STAT_LEN); - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_release_complete (cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_causes_t cause, - cc_kfact_t *kfactor) -{ - cc_release_complete_t *pmsg; - - - pmsg = (cc_release_complete_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_RELEASE_COMPLETE; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->cause = cause; - if (kfactor != NULL) { - sstrncpy(pmsg->kfactor.rxstats, kfactor->rxstats, CC_KFACTOR_STAT_LEN); - sstrncpy(pmsg->kfactor.txstats, kfactor->txstats, CC_KFACTOR_STAT_LEN); - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_feature2 (cc_msgs_t msg_id, cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_features_t feature_id, - cc_feature_data_t *data, Timecard *timecard) -{ - cc_feature_t *pmsg; - cc_msgbody_info_t *msg_body; - - pmsg = (cc_feature_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG("%s: no buffer available for feat=%s", __FUNCTION__, - cc_feature_name(feature_id)); - return; - } - - pmsg->msg_id = msg_id; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->feature_id = feature_id; - pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE); - pmsg->timecard = timecard; - - if (pmsg->data_valid == TRUE) { - pmsg->data = *data; - /* - * For call Info feature, need to copy the caller ID - */ - if (feature_id == CC_FEATURE_CALLINFO) { - /* Copy the caller ID */ - cc_cp_caller(&pmsg->data.call_info.caller_id, - &data->call_info.caller_id); - } - /* - * Clear the msg body from the source now since the msg. bodies - * has been transferred to to the CCAPI msg. - */ - msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data); - cc_initialize_msg_body_parts_info(msg_body); - } - - if ((feature_id == CC_FEATURE_XFER) || - (feature_id == CC_FEATURE_BLIND_XFER)) { - if (data != NULL) { - CC_DEBUG(DEB_L_C_F_PREFIX - "method= %d, call_id= %d, cause= %s dialstring= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), - data->xfer.method, data->xfer.target_call_id, - cc_cause_name(data->xfer.cause), data->xfer.dialstring); - } - } - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_feature_name(feature_id)); - CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data); - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG("%s: unable to send msg for feat=%s", __FUNCTION__, - cc_feature_name(feature_id)); - } - return; -} - -void -cc_int_feature_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, - cc_feature_data_t *data, cc_causes_t cause) -{ - cc_feature_ack_t *pmsg; - cc_msgbody_info_t *msg_body; - - pmsg = (cc_feature_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_FEATURE_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->feature_id = feature_id; - pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE); - - if (pmsg->data_valid == TRUE) { - pmsg->data = *data; - /* - * Clear the msg body from the source now since the msg. bodies - * has been transferred to to the CCAPI msg. - */ - msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data); - cc_initialize_msg_body_parts_info(msg_body); - } - pmsg->cause = cause; - - if ((feature_id == CC_FEATURE_XFER) || - (feature_id == CC_FEATURE_BLIND_XFER)) { - if (data != NULL) { - CC_DEBUG(DEB_L_C_F_PREFIX - "method= %d, call_id= %d, cause= %s dialstring= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), - data->xfer.method, data->xfer.target_call_id, - cc_cause_name(data->xfer.cause), data->xfer.dialstring); - } - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p, cause= %s", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data, - cc_cause_name(cause)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_offhook (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, char *global_call_id, monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode) -{ - cc_offhook_t *pmsg; - - pmsg = (cc_offhook_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_OFFHOOK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (global_call_id != NULL) { - sstrncpy(pmsg->global_call_id, global_call_id, CC_GCID_LEN); - } - pmsg->prim_call_id = prim_call_id; - pmsg->hold_resume_reason = consult_reason; - pmsg->monitor_mode = monitor_mode; - pmsg->cfwdall_mode = cfwdall_mode; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_line (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line) -{ - cc_line_t *pmsg; - - pmsg = (cc_line_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_LINE; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_onhook (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, boolean softkey, cc_onhook_reason_e active_list, - const char *filename, int fileline) -{ - cc_onhook_t *pmsg; - - pmsg = (cc_onhook_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_ONHOOK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->softkey = softkey; - pmsg->prim_call_id = prim_call_id; - pmsg->hold_resume_reason = consult_reason; - pmsg->active_list = active_list; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - DEF_DEBUG("(%u/%u) On-hook called from %s:%d", - line, call_id, filename, fileline); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_digit_begin (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, int digit) -{ - cc_digit_begin_t *pmsg; - - pmsg = (cc_digit_begin_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_DIGIT_BEGIN; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->digit = digit; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_dialstring (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, const char *dialstring, const char *g_call_id, - monitor_mode_t monitor_mode) -{ - cc_dialstring_t *pmsg; - - if (dialstring == NULL) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG("%s: no dialstring", __FUNCTION__); - return; - } - - CC_DEBUG(DEB_L_C_F_PREFIX "dialstring= %s", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),dialstring); - - pmsg = (cc_dialstring_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_DIALSTRING; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - sstrncpy(pmsg->dialstring, dialstring, CC_MAX_DIALSTRING_LEN); - sstrncpy(pmsg->g_call_id, g_call_id, CC_GCID_LEN); - pmsg->monitor_mode = monitor_mode; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_mwi (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - boolean on, int type, int newCount, int oldCount, int hpNewCount, int hpOldCount) -{ - cc_mwi_t *pmsg; - - pmsg = (cc_mwi_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_MWI; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->msgSummary.on = on; - pmsg->msgSummary.type = type; - pmsg->msgSummary.newCount = newCount; - pmsg->msgSummary.oldCount = oldCount; - pmsg->msgSummary.hpNewCount = hpNewCount; - pmsg->msgSummary.hpOldCount = hpOldCount; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " mwi status= %d\n new count= %d old count= %d", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), on, newCount, oldCount); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_options_sdp_req (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, void *pMessage) -{ - cc_options_sdp_req_t *pmsg; - - pmsg = (cc_options_sdp_req_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_OPTIONS; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->pMessage = pMessage; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " message ptr=%p", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), pMessage); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_options_sdp_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, void *pMessage, cc_msgbody_info_t *msg_body) -{ - cc_options_sdp_ack_t *pmsg; - - pmsg = (cc_options_sdp_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_OPTIONS_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->pMessage = pMessage; - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " message ptr=%p", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), pMessage); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_audit_sdp_req (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, boolean apply_ringout) -{ - cc_audit_sdp_req_t *pmsg; - - pmsg = (cc_audit_sdp_req_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_AUDIT; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->apply_ringout = apply_ringout; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX "", DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_audit_sdp_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_msgbody_info_t *msg_body) -{ - cc_audit_sdp_ack_t *pmsg; - - pmsg = (cc_audit_sdp_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_AUDIT_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_fail_fallback (cc_srcs_t src_id, cc_srcs_t dst_id, int rsp_type, - cc_regmgr_rsp_e rsp_id, boolean waited) -{ - cc_regmgr_t *pmsg; - - - pmsg = (cc_regmgr_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_FAILOVER_FALLBACK; - pmsg->src_id = src_id; - pmsg->rsp_type = rsp_type; - pmsg->rsp_id = rsp_id; - pmsg->wait_flag = waited; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, 0, 0, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_F_PREFIX "rsp_type= %s rsp_id= %s waited = %d", - DEB_F_PREFIX_ARGS(CC_API, __FUNCTION__), - rsp_type == RSP_START ? "RSP_START" : "RSP_COMPLETE", - rsp_id == CC_REG_FAILOVER_RSP ? "REG_FAILOVER_RSP" : "REG_FALLBACK_RSP", - waited); - - if (cc_send_cmd_msg(REG_MGR_STATE_CHANGE, (cprBuffer_t) pmsg, - sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_info (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, string_t info_package, string_t content_type, - string_t message_body) -{ - cc_info_t *pmsg; - - - pmsg = (cc_info_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_INFO; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->info_package = strlib_copy(info_package); - pmsg->content_type = strlib_copy(content_type); - pmsg->message_body = strlib_copy(message_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_init (void) -{ - /* Placeholder function for any initialization tasks */ -} - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/ccapi_strings.c b/media/webrtc/signaling/src/sipcc/core/gsm/ccapi_strings.c deleted file mode 100644 index 23e6da7d595..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/ccapi_strings.c +++ /dev/null @@ -1,60 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#define __CC_FEATURE_STRINGS__ // this is required to include feature strings. -#define __CC_MESSAGES_STRINGS__ // this is required to include message strings. -#define __CC_CAUSE_STRINGS__ // this is required to include cause strings. -#include "text_strings.h" -#include "ccapi.h" - -/** - * This function will be invoked by debug print functions. - * - * @param id - feature id - * - * @return feature name string. - */ -const char *cc_feature_name (cc_features_t id) -{ - if ((id <= CC_FEATURE_MIN) || (id >= CC_FEATURE_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_feature_names[id - CC_FEATURE_NONE]; -} - - -/** - * This function will be invoked by debug print functions. - * - * @param id - cc msg id - * - * @return cc msg name string. - */ -const char *cc_msg_name (cc_msgs_t id) -{ - if ((id <= CC_MSG_MIN) || (id >= CC_MSG_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_msg_names[id]; -} - -/** - * This function will be invoked by debug print functions. - * - * @param id - cc cause id - * - * @return cc cause name string. - */ -const char *cc_cause_name (cc_causes_t id) -{ - if ((id <= CC_CAUSE_MIN) || (id >= CC_CAUSE_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_cause_names[id - CC_CAUSE_OK]; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/dcsm.c b/media/webrtc/signaling/src/sipcc/core/gsm/dcsm.c deleted file mode 100755 index 46330d045c3..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/dcsm.c +++ /dev/null @@ -1,723 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_errno.h" -#include "phone.h" -#include "phntask.h" -#include "lsm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "fim.h" -#include "sdp.h" -#include "debug.h" -#include "gsm_sdp.h" -#include "uiapi.h" -#include "gsm.h" -#include "prot_configmgr.h" -#include "singly_link_list.h" - -typedef enum dcsm_state { - DCSM_S_MIN = -1, - DCSM_S_READY, - DCSM_S_WAITING, - DCSM_S_MAX -} dcsm_state_e; - -#define DCSM_MAX_CALL_IDS (LSM_MAX_CALLS) - -static struct dcsm_icb_t { - callid_t call_ids[DCSM_MAX_CALL_IDS]; - line_t line; - int gsm_state; - sll_handle_t s_msg_list; - - dcsm_state_e state; -} dcsm_cb; - -static const char *dcsm_state_names[] = { - "DCSM_READY", - "DCSM_WAITING" -}; - -extern cc_int32_t g_dcsmDebug; - -static sm_rcs_t dcsm_wait_ev_feature_handling(void *event, int event_id); -static sm_rcs_t dcsm_wait_ev_offhook_handling(void *event, int event_id); -static sm_rcs_t dcsm_wait_ev_dialstring_handling(void *event, int event_id); - -typedef sm_rcs_t (*pdcsm_sm_evt_handler)(void *event, int event_id); - -typedef struct _dcsm_table_t { - int min_state; - int max_state; - int min_event; - int max_event; - pdcsm_sm_evt_handler *table; -} dcsm_table_t; - - -static pdcsm_sm_evt_handler dcsm_function_table[DCSM_S_MAX][CC_MSG_MAX] = -{ -/* DCSM_S_READY ------------------------------------------------------------ */ - { - /* DCSM_E_SETUP */ NULL, - /* DCSM_E_SETUP_ACK */ NULL, - /* DCSM_E_PROCEEDING */ NULL, - /* DCSM_E_ALERTING */ NULL, - /* DCSM_E_CONNECTED */ NULL, - /* DCSM_E_CONNECTED_ACK */ NULL, - /* DCSM_E_RELEASE */ NULL, - /* DCSM_E_RELEASE_COMPLETE */ NULL, - /* DCSM_E_FEATURE */ NULL, - /* DCSM_E_FEATURE_ACK */ NULL, - /* DCSM_E_OFFHOOK */ NULL, - /* DCSM_E_ONHOOK */ NULL, - /* DCSM_E_LINE */ NULL, - /* DCSM_E_DIGIT_BEGIN */ NULL, - /* DCSM_E_DIGIT_END */ NULL, - /* DCSM_E_DIALSTRING */ NULL, - /* DCSM_E_MWI */ NULL, - /* DCSM_E_SESSION_AUDIT */ NULL - }, - -/* DCSM_S_WAITING----------------------------------------------------- */ - { - /* DCSM_E_SETUP */ NULL, - /* DCSM_E_SETUP_ACK */ NULL, - /* DCSM_E_PROCEEDING */ NULL, - /* DCSM_E_ALERTING */ NULL, - /* DCSM_E_CONNECTED */ NULL, - /* DCSM_E_CONNECTED_ACK */ NULL, - /* DCSM_E_RELEASE */ NULL, - /* DCSM_E_RELEASE_COMPLETE */ NULL, - /* DCSM_E_FEATURE */ dcsm_wait_ev_feature_handling, - /* DCSM_E_FEATURE_ACK */ NULL, - /* DCSM_E_OFFHOOK */ dcsm_wait_ev_offhook_handling, - /* DCSM_E_ONHOOK */ NULL, - /* DCSM_E_LINE */ NULL, - /* DCSM_E_DIGIT_BEGIN */ NULL, - /* DCSM_E_DIGIT_END */ NULL, - /* DCSM_E_DIALSTRING */ dcsm_wait_ev_dialstring_handling, - /* DCSM_E_MWI */ NULL, - /* DCSM_E_SESSION_AUDIT */ NULL - }, -}; - -static dcsm_table_t dcsm_sm_table; -static dcsm_table_t *pdcsm_sm_table = &dcsm_sm_table; - -/* - * Adds event to the dcsm queue. - * - * @param event - Call control event to add - * - * @return TRUE if the event is added. - - * - */ -static boolean -dcsm_add_event_to_queue (void *event) -{ - (void) sll_append(dcsm_cb.s_msg_list, event); - - return TRUE; -} - -/* - * Get a event from the queue. - * - * @param none - * - * @return pointer to the event. - - * - */ -static void * -dcsm_get_first_event_from_queue (void) -{ - void *msg_ptr = NULL; - - msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL); - - sll_remove(dcsm_cb.s_msg_list, msg_ptr); - - return(msg_ptr); -} - -/* - * Get dcsm state name. - * - * @param int - state id - * - * @return ponter to the state name either - * DCSM_READY or DCSM_WAITING. - * - */ -const char *dcsm_get_state_name (int state) -{ - if ((state <= DCSM_S_MIN) || - (state >= DCSM_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return dcsm_state_names[state]; -} - -/** - * Feed the event to FIM state machine a direct function call - * to process message retrieved from the queue. - * - * @param void * - pointer to the message to be processed - * - * @return none. - */ -static void dcsm_process_event_to_gsm (void *msg_ptr) -{ - if (fim_process_event(msg_ptr, FALSE) == TRUE) { - - fim_free_event(msg_ptr); - - /* Release buffer too */ - cpr_free(msg_ptr); - } -} - - -/** - * Process ready state events. - * - * @param none - * - * @return none. - */ - -static void dcsm_do_ready_state_job (void) -{ - static const char fname[] = "dcsm_do_ready_state_job"; - void *msg_ptr; - int event_id; - cc_feature_t *feat_msg = NULL; - callid_t call_id = CC_NO_CALL_ID; - - if (dcsm_cb.state != DCSM_S_READY) { - DEF_DEBUG(DEB_F_PREFIX": not in ready state.", - DEB_F_PREFIX_ARGS("DCSM", fname)); - return; - } - - msg_ptr = dcsm_get_first_event_from_queue(); - - /* Check if there is any msg available */ - if (msg_ptr != NULL) { - event_id = (int)(((cc_setup_t *)msg_ptr)->msg_id); - if (event_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) msg_ptr; - if (feat_msg != NULL) { - call_id = feat_msg->call_id; - } - } - - DEF_DEBUG(DEB_F_PREFIX"%d: event (%s%s)", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - dcsm_process_event_to_gsm(msg_ptr); - } -} - -/** - * Function process events based on the state of DCSM. - * - * @param none - * - * @return none. - */ -void dcsm_process_jobs (void) -{ - dcsm_do_ready_state_job(); -} - -/** - * Adds call_id to the list of call_id's which made DCSM to move - * to waiting state. - * - * @param callid_t - call id that has to be added to the list - * - * @return none. - */ -static void dcsm_add_call_id_to_list (callid_t call_id) -{ - static const char fname[] = "dcsm_add_call_id_to_list"; - int i, loc = -1; - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - if (dcsm_cb.call_ids[i] == CC_NO_CALL_ID) { - loc = i; - } else if (dcsm_cb.call_ids[i] == call_id) { - //Call_id already present so do not try to add again - return; - } - } - - if (loc == -1) { - - /* Should never happen as there is a space to store call_id - * for each calls - */ - DCSM_ERROR(DEB_F_PREFIX"DCSM No space to store call_id.", - DEB_F_PREFIX_ARGS("DCSM", fname)); - return; - } - - dcsm_cb.call_ids[loc] = call_id; -} - -/** - * Remove call_id from the list and see if the call_ids list is null. - * - * @param callid_t - call id that to be removed from the list. - * - * @return TRUE - if the call_ids list is empty. - * FALSE - call_ids list is not empty. - */ -static boolean dcsm_remove_check_for_empty_list (callid_t call_id) -{ - int i; - boolean call_id_present = FALSE; - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - if (dcsm_cb.call_ids[i] == call_id) { - dcsm_cb.call_ids[i] = CC_NO_CALL_ID; - - /* Found out that other call_id exist by setting - * call_id_preset, so return true, don't have to - * continue - */ - if (call_id_present == TRUE) { - return FALSE; - } - - } else if (dcsm_cb.call_ids[i] != CC_NO_CALL_ID) { - call_id_present = TRUE; - } - } - - if (call_id_present == TRUE) { - return(FALSE); - } - - return(TRUE); -} - - -/* - * The function responsible for setting gsm state machine. - * - * @param callid_t - call id of the call - * state - current GSM state - * - * @return void - * - */ -void -dcsm_update_gsm_state (fsm_fcb_t *fcb, callid_t call_id, int state) -{ - int last_state; - static const char fname[] = "dcsm_update_gsm_state"; - fsmdef_dcb_t *dcb; - - if (fcb->fsm_type != FSM_TYPE_DEF) { - DEF_DEBUG(DEB_F_PREFIX"%d: Not handling for %s", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - fsm_type_name(fcb->fsm_type)); - return; - } - - last_state = dcsm_cb.state; - - switch (state) { - case FSMDEF_S_RELEASING: - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb && dcb->send_release == FALSE) { - /* This call is already released from SIP persepctive. so no need to wait */ - break; - } - case FSMDEF_S_CONNECTING: - case FSMDEF_S_HOLD_PENDING: - case FSMDEF_S_RESUME_PENDING: - dcsm_add_call_id_to_list(call_id); - - dcsm_cb.state = DCSM_S_WAITING; - break; - case FSMDEF_S_MIN: - case FSMDEF_S_IDLE: - case FSMDEF_S_COLLECT_INFO: - case FSMDEF_S_CALL_SENT: - case FSMDEF_S_OUTGOING_PROCEEDING: - case FSMDEF_S_KPML_COLLECT_INFO: - case FSMDEF_S_OUTGOING_ALERTING: - case FSMDEF_S_INCOMING_ALERTING: - case FSMDEF_S_JOINING: - case FSMDEF_S_CONNECTED: - case FSMDEF_S_CONNECTED_MEDIA_PEND: - case FSMDEF_S_HOLDING: - case FSMDEF_S_PRESERVED: - case FSMDEF_S_MAX: - /* If there are no other call_id then move it to - * ready state else, it will remain in waiting - * state - */ - if (dcsm_remove_check_for_empty_list(call_id) == TRUE) { - dcsm_cb.state = DCSM_S_READY; - /* Check if there are any pending events in the queue - * if so send a DCSM_EV_READY to the GSM so dcsm will - * get a chance to execute. - */ - if (sll_count(dcsm_cb.s_msg_list) > 0 ) { - if (gsm_send_msg(DCSM_EV_READY, NULL, 0) == CPR_FAILURE) { - DCSM_ERROR(DEB_F_PREFIX"send DCSM_EV_READY ERROR.", - DEB_F_PREFIX_ARGS(DCSM, fname)); - } - } - } - - break; - default: - break; - } - - DEF_DEBUG(DEB_F_PREFIX"%d : %s --> %s", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - dcsm_get_state_name(last_state), - dcsm_get_state_name(dcsm_cb.state)); - return; -} - -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -static sm_rcs_t -dcsm_wait_ev_offhook_handling (void *event, int event_id) -{ - static const char fname[] = "dcsm_wait_ev_offhook_handling"; - - DEF_DEBUG(DEB_F_PREFIX": offhook", - DEB_F_PREFIX_ARGS("DCSM", fname)); - - dcsm_add_event_to_queue(event); - return (SM_RC_END); -} -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -static sm_rcs_t -dcsm_wait_ev_feature_handling (void *event, int event_id) -{ - static const char fname[] = "dcsm_wait_ev_feature_handling"; - cc_feature_t *feat_msg = (cc_feature_t *) event; - sm_rcs_t rc = SM_RC_END; - cc_features_t ftr_id = CC_FEATURE_UNDEFINED; - callid_t call_id = CC_NO_CALL_ID; - - if (feat_msg != NULL) { - ftr_id = feat_msg->feature_id; - call_id = feat_msg->call_id; - } - - DEF_DEBUG(DEB_F_PREFIX"%d: id= %s%s", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - - switch (ftr_id) { - case CC_FEATURE_ANSWER: - case CC_FEATURE_NEW_CALL: - case CC_FEATURE_REDIAL: - case CC_FEATURE_RESUME: - case CC_FEATURE_JOIN: - dcsm_add_event_to_queue(event); - DEF_DEBUG(DEB_F_PREFIX"%d: Event queued", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id); - rc = SM_RC_END; - break; - default: - DEF_DEBUG(DEB_F_PREFIX"%d: Feature msg not handled", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id); - - rc = SM_RC_CONT; - break; - } - - - return (rc); - -} - -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -static sm_rcs_t -dcsm_wait_ev_dialstring_handling (void *event, int event_id) -{ - static const char fname[] = "dcsm_wait_ev_dialstring_handling"; - - DEF_DEBUG(DEB_F_PREFIX": dialstring", - DEB_F_PREFIX_ARGS("DCSM", fname)); - - dcsm_add_event_to_queue(event); - return (SM_RC_END); -} - -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -sm_rcs_t -dcsm_process_event (void *event, int event_id) -{ - static const char fname[] = "dcsm_process_event"; - callid_t call_id; - int state_id; - sm_rcs_t rc = SM_RC_CONT; - fsm_fcb_t *fcb = (fsm_fcb_t *) event; - cc_feature_t *feat_msg = NULL; - pdcsm_sm_evt_handler hdlr; /* cached handler in order to compute its addr once */ - - call_id = fcb->call_id; - - if (event_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) event; - - if (feat_msg != NULL){ - call_id = feat_msg->call_id; - } - } - - DEF_DEBUG(DEB_F_PREFIX"DCSM %-4d:(%s:%s%s)", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - dcsm_get_state_name(dcsm_cb.state), - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - - state_id = dcsm_cb.state; // Get current state; - - /* - * validate the state and event - * and that there is a valid function for this state-event pair. - */ - if ((state_id > pdcsm_sm_table->min_state) && - (state_id < pdcsm_sm_table->max_state) && - (event_id > pdcsm_sm_table->min_event) && - (event_id < pdcsm_sm_table->max_event)) { - - if ((hdlr = pdcsm_sm_table->table[pdcsm_sm_table->max_event * state_id + - event_id]) != NULL) { - DEF_DEBUG(DEB_F_PREFIX"%-4d: dcsm entry: (%s)", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - cc_msg_name((cc_msgs_t)(event_id))); - - rc = hdlr(event, event_id); - } - - } - - return (rc); - -} - -/* - * Function responsible for searching the list. - * - * @param cac_data_t *key_p - pointer to the key. - * @param cac_data_t *cac_data - cac data. - * - * @return void - * - */ -static sll_match_e -dcsm_match_event (void *key_p, void *msg_data) -{ - return SLL_MATCH_FOUND; -} - -/** - * - * Show function for DCSM - * - * @param argc - number of parameter passed - * argv - argument passed - * - * @return 0 - if function successful - */ -cc_int32_t -dcsm_show_cmd (cc_int32_t argc, const char *argv[]) -{ - void *msg_ptr; - int i; - cc_setup_t *msg; - cc_msgs_t msg_id; - line_t line; - callid_t call_id; - cc_feature_t *feat_msg = NULL; - - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("show dcsm\n"); - return (0); - } - - - if (dcsm_cb.s_msg_list == NULL) { - return(0); - } - - debugif_printf("\n-------------------------- DCSM Data --------------------------"); - debugif_printf("\nDCSM State = %s",dcsm_get_state_name(dcsm_cb.state)); - debugif_printf("\nDCSM waiting calls \n"); - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - if (dcsm_cb.call_ids[i] != CC_NO_CALL_ID) { - debugif_printf("%d ", dcsm_cb.call_ids[i]); - } - } - debugif_printf("\n"); - - debugif_printf("\nDCSM waiting events \n"); - i = 0; - msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL); - while (msg_ptr) { - msg_ptr = sll_next(dcsm_cb.s_msg_list, msg_ptr); - - if (msg_ptr) { - msg = (cc_setup_t *) msg_ptr; - msg_id = msg->msg_id; - call_id = msg->call_id; - line = msg->line; - if ((int)msg_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) msg_ptr; - } - - debugif_printf("Event %d (%d/%d): (%s%s)\n", - i++, line, call_id, cc_msg_name(msg_id), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - } - } - debugif_printf("\n-------------------------- DCSM Data Done-----------------------"); - - return (0); -} - - -/** - * - * Initialize dcsm state machine. - * - * @param none - * - * @return none - * - * @pre none - */ -void -dcsm_init (void) -{ - static const char fname[] = "dcsm_init"; - int i; - - /* - * Initialize the state/event table. - */ - dcsm_sm_table.min_state = DCSM_S_MIN; - dcsm_sm_table.max_state = DCSM_S_MAX; - dcsm_sm_table.min_event = CC_MSG_MIN; - dcsm_sm_table.max_event = CC_MSG_MAX; - dcsm_sm_table.table = (&(dcsm_function_table[0][0])); - - dcsm_cb.state = DCSM_S_READY; - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - dcsm_cb.call_ids[i] = CC_NO_CALL_ID; - } - - /* allocate and initialize cac list */ - dcsm_cb.s_msg_list = sll_create((sll_match_e(*)(void *, void *)) - dcsm_match_event); - - if (dcsm_cb.s_msg_list == NULL) { - DCSM_ERROR(DEB_F_PREFIX"DCSM CB creation failed.", - DEB_F_PREFIX_ARGS("DCSM", fname)); - - } - -} - -/** - * - * Shut down routine for dcsm state machine. - * - * @param none - * - * @return none - * - * @pre none - */ -void -dcsm_shutdown (void) -{ - void *msg_ptr; - - if (dcsm_cb.s_msg_list == NULL) { - return; - } - - msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL); - while (msg_ptr) { - msg_ptr = sll_next(dcsm_cb.s_msg_list, msg_ptr); - - if (msg_ptr) { - fim_free_event(msg_ptr); - - /* Release buffer too */ - cpr_free(msg_ptr); - } - } - - sll_destroy(dcsm_cb.s_msg_list); - dcsm_cb.s_msg_list = NULL; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/fim.c b/media/webrtc/signaling/src/sipcc/core/gsm/fim.c deleted file mode 100755 index 850b3160552..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/fim.c +++ /dev/null @@ -1,759 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mozilla/Assertions.h" -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "phone.h" -#include "fim.h" -#include "lsm.h" -#include "fsm.h" -#include "sm.h" -#include "ccapi.h" -#include "debug.h" -#include "phone_debug.h" -#include "util_string.h" -#include "sdp.h" -#include "gsm_sdp.h" -#include "ccsip_sdp.h" -#include "platform_api.h" - -extern void set_next_sess_video_pref(int pref); -extern sm_rcs_t dcsm_process_event(void *event, int event_id); - -#define FIM_MAX_CHNS (LSM_MAX_CALLS) -#define FIM_MAX_SCBS (FSM_TYPE_MAX) -#define FIM_MAX_ICBS (FSM_TYPE_MAX * FIM_MAX_CHNS) - -static fim_scb_t *fim_scbs; -static fim_icb_t *fim_icbs; - -static const char* logTag = "fim.c"; - -static void -fim_mwi (cc_mwi_t *msg) -{ - cc_action_data_t data; - - data.mwi.on = msg->msgSummary.on; - data.mwi.type = msg->msgSummary.type; - data.mwi.newCount = msg->msgSummary.newCount; - data.mwi.oldCount = msg->msgSummary.oldCount; - data.mwi.hpNewCount = msg->msgSummary.hpNewCount; - data.mwi.hpOldCount = msg->msgSummary.hpOldCount; - - (void)cc_call_action(msg->call_id, msg->line, CC_ACTION_MWI, &data); -} - - -static void -fim_init_call_chns (void) -{ - int chn; - fsm_types_t type; - fim_icb_t *icb = NULL; - static const char fname[] = "fim_init_call_chns"; - - fim_scbs = (fim_scb_t *) cpr_calloc(FIM_MAX_SCBS, sizeof(fim_scb_t)); - if (fim_scbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate FIM SCBs.", fname); - return; - } - - fim_icbs = (fim_icb_t *) cpr_calloc(FIM_MAX_ICBS, sizeof(fim_icb_t)); - if (fim_icbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate FIM ICBs.", fname); - cpr_free(fim_scbs); - fim_scbs = NULL; - return; - } - - /* - * Initialize the icbs (fim control blocks). - */ - icb = fim_icbs; - for (chn = 0; chn < FIM_MAX_CHNS; chn++) { - for (type = FSM_TYPE_HEAD; type < FSM_TYPE_MAX; type++, icb++) { - icb->call_id = CC_NO_CALL_ID; - icb->scb = &(fim_scbs[type]); - icb->cb = NULL; - - /* - * Set the next_chn pointers if this is the head of the chain, - * Set non-head icbs and the last head to NULL. - */ - if ((type == FSM_TYPE_HEAD) && (chn < (FIM_MAX_CHNS - 1))) { - icb->next_chn = icb + FSM_TYPE_MAX; - } else { - icb->next_chn = NULL; - } - - /* - * Set the next_icb pointers if this icb is not the last - * one on the chain. - */ - if (type < (FSM_TYPE_MAX - 1)) { - icb->next_icb = icb + 1; - } else { - icb->next_icb = NULL; - } - } /* for (jscb = FSM_TYPE_HEAD; i < FSM_TYPE_MAX; i++) { */ - } /* for (ichn = 0; ichn < FIM_MAX_CHNS; ichn++) { */ - - /* - * Initialize the scbs (state machine control blocks). - */ - icb = fim_icbs; - for (type = FSM_TYPE_HEAD; type < FSM_TYPE_MAX; type++, icb++) { - icb->scb->type = type; - fsm_init_scb(icb, CC_NO_CALL_ID); - } -} - -static void -fim_free_call_chn (fim_icb_t *call_chn, line_t line, boolean update_call_cnt) -{ - static const char fname[] = "fim_free_call_chn"; - fim_icb_t *icb = call_chn; - - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "FIM", call_chn->call_id, fname, - "call_chn", call_chn); - - /* - * Go through the chain and free each icb. - */ - for (icb = call_chn; icb != NULL; icb = icb->next_icb) { - if (icb->scb->free_cb != NULL) { - icb->scb->free_cb(icb, icb->call_id); - } - icb->call_id = CC_NO_CALL_ID; - icb->cb = NULL; - } - if (update_call_cnt == TRUE) { - lsm_decrement_call_chn_cnt(line); - } - else { - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "lsm not decremented", call_chn->call_id, fname, - "call_chn", call_chn); - } -} - - -fim_icb_t * -fim_get_call_chn_by_call_id (callid_t call_id) -{ - static const char fname[] = "fim_get_call_chn_by_call_id"; - fim_icb_t *call_chn = NULL; - fim_icb_t *icb = NULL; - - for (icb = fim_icbs; icb != NULL; icb = icb->next_chn) { - if (icb->call_id == call_id) { - call_chn = icb; - break; - } - } - - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "FIM", call_id, fname, "chn", - call_chn); - - return call_chn; -} - -fim_icb_t * -fim_get_new_call_chn (callid_t call_id) -{ - static const char fname[] = "fim_get_new_call_chn"; - fim_icb_t *call_chn = NULL; - fim_icb_t *icb = NULL; - - /* - * Verify that this call_id is not already used. - */ - call_chn = fim_get_call_chn_by_call_id(call_id); - if (call_chn != NULL) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "call_id in use"); - - return NULL; - } - - /* - * Construct a new call chain. - */ - call_chn = fim_get_call_chn_by_call_id(CC_NO_CALL_ID); - if (call_chn == NULL) { - /* - * No more free call_chns are available. - */ - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "no free call_chns"); - - return NULL; - } - - call_chn->call_id = call_id; - call_chn->ui_locked = FALSE; - - /* - * Set the control blocks for the icbs. - */ - for (icb = call_chn; icb != NULL; icb = icb->next_icb) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - fsm_type_name(icb->scb->type)); - - if (icb->scb->get_cb) { - icb->scb->get_cb(icb, call_id); - if (!icb->cb) { - CSFLogError(logTag, "%s - unable to get control block for call %d", __FUNCTION__, call_id); - fim_free_call_chn(call_chn, 0, FALSE); - return NULL; - } - icb->call_id = call_id; - icb->ui_locked = FALSE; - } - } - - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "FIM", call_chn->call_id, fname, - "call_chn", call_chn); - - return call_chn; -} - -void -fim_free_event (void *data) -{ - cc_msg_t *msg = (cc_msg_t *) data; - - /* Free CCAPI msg. data that are not consumed */ - cc_free_msg_data(msg); -} - -static void -fim_process_options_msg (void *data) -{ - static const char fname[] = "fim_process_options_msg"; - cc_sdp_t *local_sdp_p = NULL; - cc_causes_t cause = CC_CAUSE_MIN; - cc_msgbody_info_t msg_body; - cc_options_sdp_req_t *options_msg = (cc_options_sdp_req_t *) data; - - gsmsdp_create_options_sdp(&local_sdp_p); - - cause = gsmsdp_encode_sdp(local_sdp_p, &msg_body); - if (cause != CC_CAUSE_OK) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", options_msg->call_id, - fname, "Unable to build SDP\n"); - } else { - cc_int_options_sdp_ack(CC_SRC_GSM, CC_SRC_SIP, - options_msg->call_id, - options_msg->line, - options_msg->pMessage, &msg_body); - } - sipsdp_src_dest_free(CCSIP_SRC_SDP_BIT, &local_sdp_p); -} - -void -fim_lock_ui (callid_t call_id) -{ - fim_icb_t *call_chn = fim_get_call_chn_by_call_id(call_id); - - if (call_chn == NULL) { - FIM_DEBUG(DEB_F_PREFIX"unknown call id", DEB_F_PREFIX_ARGS(FIM, "fim_lock_ui")); - return; - } - call_chn->ui_locked = TRUE; -} - -void -fim_unlock_ui (callid_t call_id) -{ - fim_icb_t *call_chn = fim_get_call_chn_by_call_id(call_id); - - if (call_chn == NULL) { - FIM_DEBUG(DEB_F_PREFIX"unknown call id", DEB_F_PREFIX_ARGS(FIM, "fim_unlock_ui")); - return; - } - call_chn->ui_locked = FALSE; -} - -static boolean -fsm_event_filtered_by_ui_lock (int event_id, cc_features_t feature_id) -{ - /* - * If UI has been locked by GSM due to pending states, we want - * to filter the events that come in from the UI. We will still - * allow all GSM and SIP stack originated events through to the - * GSM sm. - */ - if (event_id == CC_MSG_ONHOOK) { - return FALSE; - } - - if ((event_id == CC_MSG_FEATURE) && - (feature_id == CC_FEATURE_END_CALL || - feature_id == CC_FEATURE_REQ_PEND_TIMER_EXP || - feature_id == CC_FEATURE_RESUME || - feature_id == CC_FEATURE_HOLD)) { - return FALSE; - } - - return TRUE; -} - -/** - * - * Check if the feature event is generic feature - * - * @param cc_features_t feature_id - * - * @return TRUE if the feature is generic or else FALSE - * - * @pre None - */ -boolean fim_is_app_generic_features (cc_features_t feat_id) -{ - return(FALSE); -} - -/** - * - * Check if the message is the feature event that may requires a new - * call chain. - * - * @param msg - pointer to cc_setup_t. - * - * @return TRUE if the feature that may requires a new call chain. - * - * @pre (msg != NULL) - */ -static boolean -fim_check_feature_event (cc_setup_t *msg) -{ - - if ((((cc_feature_t *)msg)->feature_id == CC_FEATURE_SELECT) || - (((cc_feature_t *)msg)->feature_id == CC_FEATURE_DIRTRXFR) || - (((cc_feature_t *)msg)->feature_id == CC_FEATURE_B2BCONF) || - (((cc_feature_t *)msg)->feature_id == CC_FEATURE_CFWD_ALL)) { - return (TRUE); - } - return (FALSE); -} - -/* - * fim_feature_need_outgoing_call_context - * - * Description: - * This function determines whther a new feature invokation needs - * an early outgoing call context created in the FIM main module or not. - * - * Parameters: - msg - pointer to the cc_setup_t. - * - * Returns: - * TRUE - the feature requires outgoing call context to be created. - * FALSE - the feature does not requries outgoing call context to - * be created during initial FIM displacthing. - */ -static boolean -fim_feature_need_outgoing_call_context (cc_setup_t *msg) -{ - if (((cc_feature_t *)msg)->feature_id == CC_FEATURE_NOTIFY) { - /* - * these features do not need outgoing context to be created early - */ - return (FALSE); - } - return (TRUE); -} - -/** - * - * Process events received for GSM - * - * @param void event data - * cac_passed indicate if the event passed cac request. - * Usually set to true once the cac response is - * received so that it won't do another request. - * - * @return true if message memory has to be released by caller - * false if the message memory is not to be released by - * caller. - * - * @pre (data not_eq NULL) - * @pre (CC_MSG_MIN < msg->msg_id msg_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - int event_id = msg_id; - sm_event_t event; - fim_icb_t *call_chn = NULL; - fim_icb_t *icb = NULL; - boolean done = FALSE; - sm_rcs_t rc = SM_RC_ERROR; - fim_cb_hdr_t *cb_hdr = NULL; - fsm_fcb_t *fcb = NULL; - cc_feature_t *feat_msg = (cc_feature_t *) data; - cc_feature_data_t * feat_data = &(feat_msg->data); - boolean update_call_cnt = TRUE; - uint32_t no_of_session = 1; - callid_t bw_call_id; - - FIM_DEBUG(DEB_L_C_F_PREFIX"Msg name = %s", DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), - cc_msg_name(msg_id)); - - /* - * Validate the incoming event. - */ - if ((event_id <= CC_MSG_MIN) || (event_id >= CC_MSG_MAX)) { - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - - /* Make sure to process the device events - */ - - if (dcsm_process_event(data, event_id) == SM_RC_END) { - /* Keep the message in the dcsm state handler */ - return(FALSE); - } - - /* - * Grab non-call control events and hand them off to other functions that - * are not implemented by the fsms. - */ - if (msg_id == CC_MSG_MWI) { - fim_mwi((cc_mwi_t *) msg); - } - - if (event_id == CC_MSG_OPTIONS) { - fim_process_options_msg(data); - return(TRUE); - } - - - if (platWlanISActive() && cac_passed == FALSE) { - /* The WLAN will request for bandwidth only for the events received from - * UI or other external entity. For internal events there is allocated bandwidth - * and do not need to request again. - */ - - if ((msg->src_id != CC_SRC_GSM) && - ((event_id == CC_MSG_SETUP) || - (event_id == CC_MSG_OFFHOOK) || - (event_id == CC_MSG_DIALSTRING) || - (event_id == CC_MSG_LINE) || - ((event_id == CC_MSG_FEATURE) && - ((((cc_feature_t *) msg)->feature_id == CC_FEATURE_NEW_CALL))))) { - - bw_call_id = call_id; - - if ((event_id == CC_MSG_SETUP) && - ((((cc_setup_t *)msg)->call_info.type == CC_FEAT_MONITOR))) { - no_of_session = 2; - bw_call_id = msg->call_info.data.join.join_call_id; - } - - if (fsm_cac_call_bandwidth_req (bw_call_id, no_of_session, msg) != CC_CAUSE_OK) { - return(TRUE); - } - /* Do not release the msg once it returns from the call - */ - return(FALSE); - } - } - - if ((event_id == CC_MSG_FEATURE) && ((call_id == CC_NO_CALL_ID) || - fim_is_app_generic_features(((cc_feature_t *) msg)->feature_id))) { - if (((cc_feature_t *)msg)->feature_id == CC_FEATURE_BLF_ALERT_TONE) { - (void)cc_call_action(0, 0, CC_ACTION_PLAY_BLF_ALERTING_TONE, NULL); - } else if (((cc_feature_t *)msg)->feature_id == CC_FEATURE_UPD_MEDIA_CAP) { - fsmdef_update_media_cap_feature_event(feat_msg); - } - return(TRUE); - } - - /* - * Throw away any messages with call_id < 1 (which means they are invalid). - * - * The GSM will send messages back to itself with a call_id < 1 because - * it uses the NULL_DCB. The fsmxfr will use a NULL_DCB that has invalid - * data in it, but the DCB points to a valid DCB. This way, the fsmxfr does - * not have to keep checking for the NULL. - */ - if (call_id < 1) { - return(TRUE); - } - - - /* - * Get the call chain associated with this call_id. - */ - call_chn = fim_get_call_chn_by_call_id(call_id); - - if (call_chn == NULL) { - /* - * No call chain, so get a new call chain, - * but only if the event is a call establishment event. - */ - if ((event_id == CC_MSG_SETUP) || - (event_id == CC_MSG_OFFHOOK) || - (event_id == CC_MSG_DIALSTRING) || - (event_id == CC_MSG_LINE) || - ((event_id == CC_MSG_FEATURE) && - ((((cc_feature_t *) msg)->feature_id == CC_FEATURE_NEW_CALL)))) { - call_chn = fim_get_new_call_chn(call_id); - - /* - * Make sure we got a new call chain. - */ - if (call_chn == NULL) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "no call_chn"); - - fsm_display_no_free_lines(); - - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - - } else if ((event_id == CC_MSG_FEATURE) && - (fim_check_feature_event(msg))) { - - call_chn = fim_get_new_call_chn(call_id); - - /* - * Make sure we got a new call chain. - */ - if (call_chn == NULL) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "no call_chn"); - - fsm_display_no_free_lines(); - - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - - if (fim_feature_need_outgoing_call_context(msg)) { - /* Get new outgoing call context using DEF state m/c fsm */ - if (fsm_get_new_outgoing_call_context(call_id, line, - fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF), - FALSE) != CC_CAUSE_OK) { - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - } - - } else { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "not a call establishment event\n"); - if( feat_msg->feature_id == CC_FEATURE_UPD_SESSION_MEDIA_CAP) { - FIM_DEBUG(DEB_L_C_F_PREFIX"set_next_sess_video_pref = %d", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), - feat_data->caps.support_direction); - set_next_sess_video_pref(feat_data->caps.support_direction); - } - return(TRUE); - } - if (event_id != CC_MSG_SETUP) { - /* - * Increment the call chain cnt for this line - * For incoming calls, we don't know the line number - * when SETUP msg is received, so it's an exception, it'll be - * added in fsmdef_idle_setup - */ - lsm_increment_call_chn_cnt(line); - } - } /* if (call_chn == NULL) */ - - - /* - * Pass the event to the call chain unless UI lock has been enabled. - */ - if (call_chn->ui_locked && ((cc_feature_t *) msg)->src_id == CC_SRC_UI) { - if (fsm_event_filtered_by_ui_lock(event_id, - ((cc_feature_t *)msg)->feature_id)) { - FIM_DEBUG(DEB_L_C_F_PREFIX" %s filtered by UI lock", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), - cc_feature_name(((cc_feature_t *)msg)->feature_id)); - return(TRUE); - } - } - - /* - * Skip the head. - */ - icb = call_chn->next_icb; - MOZ_ASSERT(icb); - while (icb && !done) { - /* - * Set the required event data so the entity can process the event. - */ - cb_hdr = (fim_cb_hdr_t *) (icb->cb); - - MOZ_ASSERT(cb_hdr); - if (!cb_hdr) { - done = TRUE; - break; - } - - event.data = cb_hdr; - event.state = cb_hdr->state; - event.event = event_id; - event.msg = data; - - fcb = (fsm_fcb_t *) icb->cb; - - /* - * For example, if we receive INVITE and CANCEL messages back to back, - * we may be decrementing the call count of wrong line because SIP stack did - * not get the correct value for line yet. - * so set the line value to correct value from DCB. - * For RIU calls, there will be no DCB. However, line value cames from SIP stack - * correctly. - */ - - if ((fcb->fsm_type == FSM_TYPE_DEF) && (event_id == CC_MSG_RELEASE)) { - if (fcb->dcb != NULL) { - line = fcb->dcb->line; - } - } - - /* - * This update_call_cnt is only used when RC_CLEANUP is returned. - */ - update_call_cnt = TRUE; // by default, always update call count - if (fcb->dcb != NULL) { - update_call_cnt = (fcb->dcb->call_not_counted_in_mnc_bt) ? FALSE: TRUE; - } - - FIM_DEBUG(DEB_L_C_F_PREFIX" %s(%s:%s)", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), fsm_type_name(icb->scb->type), - fsm_state_name(fcb->fsm_type, event.state), - cc_msg_name((cc_msgs_t) (event.event))); - - rc = sm_process_event(icb->scb->sm, &event); - - - switch (rc) { - case SM_RC_CONT: - case SM_RC_DEF_CONT: - icb = icb->next_icb; - break; - - case SM_RC_END: - done = TRUE; - break; - - case SM_RC_ERROR: - FIM_DEBUG(DEB_L_C_F_PREFIX" fsm sm error(%d:%d)", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), event.state, event.event); - done = TRUE; - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - break; - - case SM_RC_CLEANUP: - done = TRUE; - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - break; - - default: - done = TRUE; - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - break; - } /* switch (rc) */ - - if ((rc == SM_RC_END) && (fcb->fsm_type == FSM_TYPE_DEF) && - (event_id == CC_MSG_FEATURE)) - { - if ( ((cc_feature_t *) msg)->feature_id == CC_FEATURE_CFWD_ALL){ - lsm_decrement_call_chn_cnt(line); - } - } - - if (icb == NULL) { - done = TRUE; - FIM_DEBUG("icb is null and get here!"); - } - - } /* while (done != TRUE) { */ - - if (rc == SM_RC_CLEANUP) { - fim_free_call_chn(call_chn, line, update_call_cnt); - - } - - return(TRUE); -} - - -cc_int32_t -fim_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fim_icb_t *icb = NULL; - fim_scb_t *scb = NULL; - int i = 0; - - /* - * Check if need help. - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("show fim\n"); - } - - /* - * Print the icbs. - */ - debugif_printf("\n---------------------------------- FIM icbs -----------------------------------"); - debugif_printf("\ni call_id type icb next_chn next_icb cb scb"); - debugif_printf("\n-------------------------------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(icb, fim_icbs, FIM_MAX_ICBS) { - debugif_printf("%-3d %-7d %-6s 0x%8p 0x%8p 0x%8p 0x%8p 0x%8p\n", - i++, icb->call_id, fsm_type_name(icb->scb->type), - icb, icb->next_chn, icb->next_icb, icb->cb, icb->scb); - } - - /* - * Print the scbs. - */ - i = 0; - debugif_printf - ("\n------------------------ FIM scbs ------------------------"); - debugif_printf("\ni type scb sm get_cb free_cb"); - debugif_printf - ("\n----------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(scb, fim_scbs, FIM_MAX_SCBS) { - debugif_printf("%-2d %-6s 0x%8p 0x%8p 0x%8p 0x%8p\n", - i++, fsm_type_name(scb->type), scb, - scb->sm, scb->get_cb, scb->free_cb); - } - - return (0); -} - - -void -fim_init (void) -{ - - fim_init_call_chns(); -} - -void -fim_shutdown (void) -{ - cpr_free(fim_scbs); - cpr_free(fim_icbs); - fim_scbs = NULL; - fim_icbs = NULL; -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/fsm.c b/media/webrtc/signaling/src/sipcc/core/gsm/fsm.c deleted file mode 100755 index 484473f1ba6..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/fsm.c +++ /dev/null @@ -1,1383 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "gsm.h" /* for GSM_ERR_MSG */ -#include "ccapi.h" -#include "phone_debug.h" -#include "debug.h" -#include "text_strings.h" -#include "sip_interface_regmgr.h" -#include "resource_manager.h" -#include "platform_api.h" - -#define FSM_MAX_FCBS (LSM_MAX_CALLS * (FSM_TYPE_MAX - 1)) -#define FSM_S_IDLE 0 - -extern sm_table_t *pfsmcnf_sm_table; -extern sm_table_t *pfsmb2bcnf_sm_table; -extern sm_table_t *pfsmxfr_sm_table; -extern sm_table_t *pfsmdef_sm_table; - -static fsm_fcb_t *fsm_fcbs; -static fsmdef_dcb_t fsm_dcb; -extern uint16_t g_numofselected_calls; -extern void dcsm_update_gsm_state(fsm_fcb_t *fcb, callid_t call_id, int state); - - -static const char *fsm_type_names[] = { - "HEAD", - "CNF", - "B2BCNF", - "XFR", - "DEF" -}; - -static resource_manager_t *ci_map_p[MAX_REG_LINES + 1]; -static resource_manager_t *shown_calls_ci_map_p[MAX_REG_LINES + 1]; - -const char * -fsm_type_name (fsm_types_t type) -{ - if ((type <= FSM_TYPE_MIN) || (type >= FSM_TYPE_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsm_type_names[type]); -} - - -const char * -fsm_state_name (fsm_types_t type, int id) -{ - switch (type) { - case FSM_TYPE_DEF: - return (fsmdef_state_name(id)); - - case FSM_TYPE_XFR: - return (fsmxfr_state_name(id)); - - case FSM_TYPE_CNF: - return (fsmcnf_state_name(id)); - - case FSM_TYPE_B2BCNF: - return (fsmb2bcnf_state_name(id)); - - case FSM_TYPE_NONE: - return ("IDLE"); - - default: - return (get_debug_string(GSM_UNDEFINED)); - } -} - - -void -fsm_sm_ftr (cc_features_t ftr_id, cc_srcs_t src_id) -{ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SM_FTR_ENTRY), - cc_feature_name(ftr_id), cc_src_name(src_id)); -} - - -void -fsm_sm_ignore_ftr (fsm_fcb_t *fcb, int fname, cc_features_t ftr_id) -{ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_IGNORE_FTR), - fsm_type_name(fcb->fsm_type), fcb->call_id, fname, - cc_feature_name(ftr_id)); -} - - -void -fsm_sm_ignore_src (fsm_fcb_t *fcb, int fname, cc_srcs_t src_id) -{ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_IGNORE_SRC), - fsm_type_name(fcb->fsm_type), fcb->call_id, fname, - cc_src_name(src_id)); -} - - -void -fsm_init_fcb (fsm_fcb_t *fcb, callid_t call_id, fsmdef_dcb_t *dcb, - fsm_types_t type) -{ - fcb->call_id = call_id; - - fcb->state = FSM_S_IDLE; - fcb->old_state = FSM_S_IDLE; - - fcb->fsm_type = type; - - fcb->dcb = dcb; - - fcb->xcb = NULL; - - fcb->ccb = NULL; - - fcb->b2bccb = NULL; -} - - -/* - * ROUTINE: fsm_get_fcb_by_call_id_and_type - * - * DESCRIPTION: return the fcb referenced by the given call_id and type - * - * PARAMETERS: fsm_id - * - * RETURNS: fcb - * !NULL: fcb found - * NULL: fcb not found - * - * NOTES: - */ -fsm_fcb_t * -fsm_get_fcb_by_call_id_and_type (callid_t call_id, fsm_types_t type) -{ - static const char fname[] = "fsm_get_fcb_by_call_id_and_type"; - fsm_fcb_t *fcb; - fsm_fcb_t *fcb_found = NULL; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - if ((fcb->call_id == call_id) && (fcb->fsm_type == type)) { - fcb_found = fcb; - break; - } - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", fcb_found); - - return (fcb_found); -} - -/* - * DESCRIPTION: return the fcb referenced by the given call_id and type - * - * PARAMETERS: fsm_id - * - * @return void - * !NULL: fcb found - * NULL: fcb not found - * - */ -void -fsm_get_fcb_by_selected_or_connected_call_fcb (callid_t call_id, fsm_fcb_t **con_fcb_found, - fsm_fcb_t **sel_fcb_found) -{ - static const char fname[] = "fsm_get_fcb_by_selected_or_connected_call_fcb"; - fsm_fcb_t *fcb; - - *con_fcb_found = NULL; - *sel_fcb_found = NULL; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - - if (fcb->call_id == call_id) { - /* Do not count current call_id */ - continue; - } - if (fcb->fsm_type == FSM_TYPE_DEF && - (fcb->state == FSMDEF_S_CONNECTED || - fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND || - fcb->state == FSMDEF_S_OUTGOING_ALERTING)) { - *con_fcb_found = fcb; - } else if (fcb->fsm_type == FSM_TYPE_DEF && fcb->dcb->selected) { - *sel_fcb_found = fcb; - break; - } - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", con_fcb_found); - -} - -/* - * ROUTINE: fsm_get_fcb_by_call_id - * - * DESCRIPTION: return the fcb referenced by the given call_id - * - * PARAMETERS: fsm_id - * - * RETURNS: fcb - * !NULL: fcb found - * NULL: fcb not found - * - * NOTES: - */ -fsm_fcb_t * -fsm_get_fcb_by_call_id (callid_t call_id) -{ - static const char fname[] = "fsm_get_fcb_by_call_id"; - fsm_fcb_t *fcb; - fsm_fcb_t *fcb_found = NULL; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - if (fcb->call_id == call_id) { - fcb_found = fcb; - break; - } - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", fcb_found); - - return (fcb_found); -} - - -/* - * ROUTINE: fsm_get_new_fcb - * - * DESCRIPTION: return a new fcb initialized with the given data - * - * PARAMETERS: - * call_id: call_id - * type: feature type - * - * RETURNS: - * fcb: the new fcb - */ -fsm_fcb_t * -fsm_get_new_fcb (callid_t call_id, fsm_types_t fsm_type) -{ - static const char fname[] = "fsm_get_new_fcb"; - fsm_fcb_t *fcb; - - /* - * Get free fcb by using CC_NO_CALL_ID as the call_id because a free fcb - * will have a call_id of CC_NO_CALL_ID. - */ - fcb = fsm_get_fcb_by_call_id(CC_NO_CALL_ID); - if (fcb != NULL) { - fsm_init_fcb(fcb, call_id, FSMDEF_NO_DCB, fsm_type); - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", fcb); - - return (fcb); -} - - -fsmdef_dcb_t * -fsm_get_dcb (callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - /* - * Return the fsm default dcb if a dcb was not found. - */ - if (dcb == NULL) { - dcb = &fsm_dcb; - } - - return (dcb); -} - - -void -fsm_get_fcb (fim_icb_t *icb, callid_t call_id) -{ - icb->cb = fsm_get_new_fcb(call_id, icb->scb->type); -} - - -void -fsm_init_scb (fim_icb_t *icb, callid_t call_id) -{ - icb->scb->get_cb = &fsm_get_fcb; - - switch (icb->scb->type) { - - case FSM_TYPE_B2BCNF: - icb->scb->sm = pfsmb2bcnf_sm_table; - icb->scb->free_cb = fsmb2bcnf_free_cb; - - break; - - case FSM_TYPE_CNF: - icb->scb->sm = pfsmcnf_sm_table; - icb->scb->free_cb = fsmcnf_free_cb; - - break; - case FSM_TYPE_XFR: - icb->scb->sm = pfsmxfr_sm_table; - icb->scb->free_cb = fsmxfr_free_cb; - - break; - - case FSM_TYPE_DEF: - icb->scb->sm = pfsmdef_sm_table; - icb->scb->free_cb = fsmdef_free_cb; - - break; - - case FSM_TYPE_HEAD: - default: - icb->scb->get_cb = NULL; - icb->scb->free_cb = NULL; - icb->scb->sm = NULL; - } - -} - - -void -fsm_change_state (fsm_fcb_t *fcb, int fname, int new_state) -{ - - DEF_DEBUG(DEB_L_C_F_PREFIX"%s: %s -> %s", - DEB_L_C_F_PREFIX_ARGS(FSM, ((fcb->dcb == NULL)? CC_NO_LINE: fcb->dcb->line), - fcb->call_id, "fsm_change_state"), - fsm_type_name(fcb->fsm_type), - fsm_state_name(fcb->fsm_type, fcb->state), - fsm_state_name(fcb->fsm_type, new_state)); - - fcb->old_state = fcb->state; - fcb->state = new_state; - NOTIFY_STATE_CHANGE(fcb, fcb->call_id, new_state); - -} - - -void -fsm_release (fsm_fcb_t *fcb, int fname, cc_causes_t cause) -{ - fsm_change_state(fcb, fname, FSM_S_IDLE); - - /* Cleanup any pending cac request for that call */ - fsm_cac_call_release_cleanup(fcb->call_id); - - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); -} - - -cc_int32_t -fsm_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsm_fcb_t *fcb; - int i = 0; - void *cb = NULL; - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("show fsm\n"); - return 0; - } - - /* - * Print the fcbs - */ - debugif_printf("\n----------------------------- FSM fcbs -------------------------------"); - debugif_printf("\ni call_id fcb type state dcb cb "); - debugif_printf("\n----------------------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - switch (fcb->fsm_type) { - case FSM_TYPE_CNF: - cb = fcb->ccb; - break; - - case FSM_TYPE_B2BCNF: - cb = fcb->ccb; - break; - - case FSM_TYPE_XFR: - cb = fcb->xcb; - break; - - case FSM_TYPE_DEF: - cb = fcb->dcb; - break; - - default: - cb = NULL; - } - - debugif_printf("%-3d %-7d 0x%8p %-9s %-9s 0x%8p 0x%8p\n", - i++, fcb->call_id, fcb, fsm_type_name(fcb->fsm_type), - fsm_state_name(fcb->fsm_type, fcb->state), - fcb->dcb, cb); - } - - return (0); -} - - -void -fsm_init (void) -{ - fsm_fcb_t *fcb; - - fsmdef_init_dcb(&fsm_dcb, 0, FSMDEF_CALL_TYPE_NONE, NULL, LSM_NO_LINE, - NULL); - - fsmdef_init(); - fsmb2bcnf_init(); - fsmcnf_init(); - fsmxfr_init(); - - fsm_cac_init(); - - /* - * Initialize the fcbs. - */ - fsm_fcbs = (fsm_fcb_t *) cpr_calloc(FSM_MAX_FCBS, sizeof(fsm_fcb_t)); - if (fsm_fcbs == NULL) { - GSM_ERR_MSG(GSM_F_PREFIX"Failed to allcoate FSM FCBs.", "fsm_init"); - return; - } - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - - /* - * Init call instance id map. - */ - fsmutil_init_ci_map(); -} - -void -fsm_shutdown (void) -{ - fsmdef_shutdown(); - - fsmb2bcnf_shutdown(); - - fsmcnf_shutdown(); - fsmxfr_shutdown(); - - fsm_cac_shutdown(); - - cpr_free(fsm_fcbs); - fsm_fcbs = NULL; - - /* - * Free call instance id map. - */ - fsmutil_free_ci_map(); -} - -/* - * ROUTINE: fsm_set_fcb_dcbs - * - * DESCRIPTION: Set the dcbs for the fsms. The fsm call chain is setup before - * the dcb is known, so this function is called after the dcb - * is known to set the dcb in the fcbs. - * - * PARAMETERS: - * dcb - * - * RETURNS: NONE - * - * NOTES: - */ -cc_causes_t -fsm_set_fcb_dcbs (fsmdef_dcb_t *dcb) -{ - callid_t call_id = dcb->call_id; - fsm_fcb_t *fcb; - fsm_types_t i; - - for (i = FSM_TYPE_CNF; i < FSM_TYPE_MAX; i++) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, i); - if (fcb == NULL) { - return CC_CAUSE_ERROR; - } - fcb->dcb = dcb; - } - - return CC_CAUSE_OK; -} - - -/* - * ROUTINE: fsm_get_new_outgoing_call_context - * - * DESCRIPTION: get a new outgoing call context - * - * PARAMETERS: - * fcb - * call_id - * line - * - * RETURNS: rc - * FSM_SUCCESS: context successfully created - * FSM_SUCCESS: context unsuccessfully created - * - * NOTES: - */ -cc_causes_t -fsm_get_new_outgoing_call_context (callid_t call_id, line_t line, - fsm_fcb_t *fcb, boolean expline) -{ - static const char fname[] = "fsm_get_new_outgoing_call_context"; - fsmdef_dcb_t *dcb; - cc_causes_t cause = CC_CAUSE_OK; - cc_causes_t lsm_rc; - - /* - * Get a dcb to handle the call. - */ - dcb = fsmdef_get_new_dcb(call_id); - if (dcb == NULL) { - return CC_CAUSE_NO_RESOURCE; - } - - /* - * Get a free facility associated with this line. - */ - lsm_rc = lsm_get_facility_by_line(call_id, line, expline, dcb); - if (lsm_rc != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_ERR), call_id, fname, - "lsm_get_facility_by_line failed", cc_cause_name(lsm_rc)); - } - - /* - * If no line was returned, then init the dcb with an invalid line to - * indicate that no line was returned. - */ - if (lsm_rc != CC_CAUSE_OK) { - line = LSM_NO_LINE; - } - fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_OUTGOING, NULL, line, fcb); - - cause = fsm_set_fcb_dcbs(dcb); - if (cause == CC_CAUSE_OK) { - cause = lsm_rc; - } - - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_FOUND), call_id, fname, - dcb->line); - - return cause; -} - - -/* - * ROUTINE: fsm_get_new_incoming_call_context - * - * DESCRIPTION: get a new incoming call context - * - * PARAMETERS: - * fcb - * call_id - * - * RETURNS: rc - * FSM_SUCCESS: context successfully created - * FSM_SUCCESS: context unsuccessfully created - * - * NOTES: - */ -cc_causes_t -fsm_get_new_incoming_call_context (callid_t call_id, fsm_fcb_t *fcb, - const char *called_number, boolean expline) -{ - static const char fname[] = "fsm_get_new_incoming_call_context"; - fsmdef_dcb_t *dcb; - line_t free_line; - cc_causes_t cause; - cc_causes_t lsm_rc; - - - /* - * Get a dcb to handle the call. - */ - dcb = fsmdef_get_new_dcb(call_id); - if (dcb == NULL) { - return CC_CAUSE_NO_RESOURCE; - } - - /* - * Get a free facility associated with this called_number. - */ - if ((lsm_rc = lsm_get_facility_by_called_number(call_id, called_number, - &free_line, expline, dcb)) - != CC_CAUSE_OK) { - /* - * Set a default free line (This should really be changed - * to a special invalid value and GSM modified to recognize it.) - * The dcb is needed in order for GSM to clean up the call correctly. - */ - free_line = 1; - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_ERR), call_id, fname, - "lsm_get_facility_by_called_number", - cc_cause_name(lsm_rc)); - } - - fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_INCOMING, called_number, - free_line, fcb); - - cause = fsm_set_fcb_dcbs(dcb); - if (cause == CC_CAUSE_OK) { - cause = lsm_rc; - } - - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_FOUND), call_id, fname, - dcb->line); - - return cause; -} - -/* - * fsmutil_is_cnf_leg - * - * Description: - * - * Returns TRUE if conferencing is active for the call_id - * - * - * Parameters: - * - * call_id - ccapi call identifier associated with the call. - * fsmxcb_ccbs - pointer to all conf ccbs - * max_ccbs - Max number of ccbs to check - * - * Returns TRUE if the conferencing is active for the call_id - */ -int -fsmutil_is_cnf_leg (callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - unsigned short max_ccbs) -{ - fsmcnf_ccb_t *ccb; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, max_ccbs) { - if ((ccb->cnf_call_id == call_id) || (ccb->cns_call_id == call_id)) { - return TRUE; - } - } - return FALSE; -} - -/* - * fsmutil_is_xfr_leg - * - * Description: - * - * Returns transfer mode if the specified leg identified by call_id is - * participating in a xfer - * - * Parameters: - * - * call_id - ccapi call identifier associated with the call. - * fsmxfr_xcbs - pointer to all xfr ccbs - * max_xcbs - Max number of ccbs to check - * - * Returns: fsmxfr_modes_t - */ -int -fsmutil_is_xfr_leg (callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - unsigned short max_xcbs) -{ - fsmxfr_xcb_t *xcb; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, max_xcbs) { - if ((xcb->xfr_call_id == call_id) || (xcb->cns_call_id == call_id)) { - return xcb->mode; - } - } - return FSMXFR_MODE_MIN; -} - -void -fsm_display_no_free_lines (void) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_NO_FREE_LINES, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -/* - * Function: fsm_display_use_line_or_join_to_complete - * - * Description: - * The function is used to put up the status line - * "Use Line or Join to Complete" - * - * @param None - * - * @return None - */ -void -fsm_display_use_line_or_join_to_complete (void) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_USE_LINE_OR_JOIN_TO_COMPLETE, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -void -fsm_display_feature_unavailable (void) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_FEAT_UNAVAIL, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -void -fsm_set_call_status_feature_unavailable (callid_t call_id, line_t line) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_FEAT_UNAVAIL, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - ui_set_call_status(tmp_str, line, lsm_get_ui_id(call_id)); - } -} - -/** - * - * Get total number of selected calls. - * - * @param void - * - * @return uint16_t - * - * @pre (none) - */ -uint16_t fsmutil_get_num_selected_calls (void) -{ - return(g_numofselected_calls); -} - -/** - * This function will hide/unhide ringingin calls. - * - * @param[in] hide - indicates whether calls should be hidden or unhidden - * - * @return none - */ -void fsm_display_control_ringin_calls (boolean hide) -{ - fsm_fcb_t *fcb; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - if ((fcb->state == FSMDEF_S_INCOMING_ALERTING) && - (lsm_is_it_priority_call(fcb->call_id) == FALSE)) { /* priority call should not be hidden */ - lsm_display_control_ringin_call (fcb->call_id, fcb->dcb->line, hide); - if (hide == TRUE) { - fsmutil_clear_shown_calls_ci_element(fcb->dcb->caller_id.call_instance_id, fcb->dcb->line); - } else { - fsmutil_set_shown_calls_ci_element(fcb->dcb->caller_id.call_instance_id, fcb->dcb->line); - } - } - } -} - -/* - * fsmutil_init_groupid - * - * Description: - * - * Assign the group id to the default control block. - * - * Parameters: - * dcb - default control block - * call_id - ccapi call identifier associated with the call - * call_type - incoming or outgoing call - * - * Returns: None. groupid will be assigned in the dcb. - */ -void -fsmutil_init_groupid (fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type) -{ - fsmcnf_ccb_t *ccb = NULL; - - /* if this was a consult leg of a conference then there will be - * a ccb on the primary leg - */ - dcb->group_id = CC_NO_GROUP_ID; - if (call_type != FSMDEF_CALL_TYPE_NONE) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb) { - /* consult leg of a conference */ - fsmdef_dcb_t *other_dcb = NULL; - - other_dcb = - fsmdef_get_dcb_by_call_id(fsmcnf_get_other_call_id(ccb, call_id)); - if (other_dcb) { - dcb->group_id = other_dcb->group_id; - } - } else { - /* either a primary or some other leg; not part of any conference */ - - dcb->group_id = dcb->call_id; - } - } - return; -} - -/** - * - * Find out if the call pointed by call_id is a consult call - * of a conference, transfer. - * - * @param line line related to that call - * @param call_id call_id - * - * @return call attributes - * - * @pre none - */ -int -fsmutil_get_call_attr (fsmdef_dcb_t *dcb, - line_t line, callid_t call_id) -{ - int call_attr; - - if (fsmutil_is_cnf_consult_call(call_id) == TRUE) { - call_attr = LOCAL_CONF_CONSULT; - } else if (fsmutil_is_b2bcnf_consult_call(call_id) == TRUE) { - call_attr = CONF_CONSULT; - } else if (fsmutil_is_xfr_consult_call(call_id) == TRUE) { - call_attr = XFR_CONSULT; - } else { - if (dcb == NULL) { - return(NORMAL_CALL); - } - - switch (dcb->active_feature) { - case CC_FEATURE_CFWD_ALL: - call_attr = CC_ATTR_CFWD_ALL; - break; - default: - call_attr = NORMAL_CALL; - break; - } - } - return call_attr; -} - -/* - * fsmutil_is_cnf_consult_leg - * - * Description: - * Returns TRUE if the specified call_id is for a call that is - * the consultative call of a conference. - * - * Parameters: - * call_id - ccapi call identifier associated with the call. - * fsmxcb_ccbs - pointer to all conf ccbs - * max_ccbs - Max number of ccbs to check - * - * Returns: TRUE if consultative call; otherwise, FALSE. - */ -int -fsmutil_is_cnf_consult_leg (callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - uint16_t max_ccbs) -{ - fsmcnf_ccb_t *ccb; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, max_ccbs) { - if (ccb->cns_call_id == call_id) { - return TRUE; - } - } - - return FALSE; -} - - -/* - * fsmutil_is_xfr_consult_leg - * - * Description: - * Returns TRUE if the specified call_id is for a call that is - * the consultative call of a transfer only when that consult - * was an initiated transfer. - * - * Parameters: - * call_id - ccapi call identifier associated with the call. - * fsmxfr_xcbs - pointer to all xfr ccbs - * max_xcbs - Max number of ccbs to check - * - * Returns: TRUE if consultative call; otherwise, FALSE. - */ -int -fsmutil_is_xfr_consult_leg (callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - uint16_t max_xcbs) -{ - fsmxfr_xcb_t *xcb; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, max_xcbs) { - if ((xcb->mode == FSMXFR_MODE_TRANSFEROR) && - (xcb->cns_call_id == call_id)) { - return TRUE; - } - } - return FALSE; -} - -/* - * fsmutil_clear_feature_invocation_state - * - * Description: - * This function clears the feature invocation state of the feature id - * supplied. This function is used by the code that would receive the - * feature ack (from SIP stack). - * - * Note: Code responsible for invoking features and receiving feature acks - * must call this function to clear the feature invocation state. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with the call - * cc_features_t feature_id - feature id in question - * - * Returns: None - */ -static void -fsmutil_clear_feature_invocation_state (fsmdef_dcb_t *dcb, - cc_features_t feature_id) -{ - if ((feature_id < CC_FEATURE_NONE) || (feature_id >= CC_FEATURE_MAX)) { - /* Log Error */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Invalid feature id -> %d", dcb->line, dcb->call_id, "fsmutil_clear_feature_invocation_state", feature_id); - return; - } - - rm_clear_element((resource_manager_t *) dcb->feature_invocation_state, - (int16_t) feature_id); -} - -/* - * fsmutil_process_feature_ack - * - * Description: - * This function implements the generic feature ack processing. - * Feature invocation state is Cleared when feature ack is received. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with the call - * cc_features_t feature_id - feature id in question - * - * Returns: None - */ -void -fsmutil_process_feature_ack (fsmdef_dcb_t *dcb, cc_features_t feature_id) -{ - /* clear the feature invocation state (was set when invoked) */ - fsmutil_clear_feature_invocation_state(dcb, feature_id); -} - -/* - * fsmutil_clear_all_feature_invocation_state - * - * Description: - * This function clears the feature invocation state of ALL features. - * - * This function may be used by the code that would initialize/reset - * the state machine. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with the call - * - * Returns: None - */ -void -fsmutil_clear_all_feature_invocation_state (fsmdef_dcb_t *dcb) -{ - rm_clear_all_elements((resource_manager_t *) dcb->feature_invocation_state); -} - -/* - * fsmutil_init_feature_invocation_state - * - * Description: - * Utility function to allocate and init a feature invocation state table. - * - * Parameters: - * dcb - dcb whose feature invocation state table is being created - * - * Returns: - * none - */ -void -fsmutil_init_feature_invocation_state (fsmdef_dcb_t *dcb) -{ - static const char fname[] = "fsmutil_init_feature_invocation_state"; - - dcb->feature_invocation_state = rm_create(CC_FEATURE_MAX); - - if (!dcb->feature_invocation_state) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"failed to allocate feature invocation state table", dcb->line, dcb->call_id, - fname); - } -} - - -/* - * fsmutil_free_feature_invocation_state - * - * Description: - * Utility function to free the feature invocation state table of the - * specified dcb. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_free_feature_invocation_state (fsmdef_dcb_t *dcb) -{ - rm_destroy((resource_manager_t *) dcb->feature_invocation_state); - dcb->feature_invocation_state = NULL; -} - -/* - * fsmutil_free_all_ci_id - * - * Description: - * This function clears the entire call instance map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_free_all_ci_id (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_clear_all_elements((resource_manager_t *) ci_map_p[line]); - } -} - -/* - * fsmutil_free_ci_id - * - * Description: - * This function clears a specified call instance id from - * the call instance map. - * - * Note that call instance ids are one based. The resource manager - * used to implement the call instance map is zero based so we have - * to adjust the call instance id when using the resource manager API. - * - * Parameters: - * id - the call instance id to be freed - * line - line from where to free the call instance id - * - * Returns: - * None - */ -void -fsmutil_free_ci_id (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_free_ci_id"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid", fname, line); - return; - } - - rm_clear_element((resource_manager_t *) ci_map_p[line], (int16_t) --id); -} - -#ifdef LOCAL_UI_CALLINSTANCE_ID -/*This routine is not needed now as the local assignment - *of call instance id is no longer supported. - */ -/* - * fsmutil_get_ci_id - * - * Description: - * This function locates the next available call instance id in - * the call instance map. This function is utilized when operating in - * the peer to peer mode to assign call instance ids for inbound - * and outbound calls. - * - * Note that call instance ids are one based. The resource manager - * used to implement the call instance map is zero based so we have - * to adjust the call instance id when using the resource manager API. - * - * Parameters: - * line - line from where to retrieve the call instance id - * - * Returns: - * uint16_t - Non-zero call instance id. 0 if no call instance ids - * are available. - */ -uint16_t -fsmutil_get_ci_id (line_t line) -{ - static const char fname[] = "fsmutil_get_ci_id"; - int16_t id; - uint16_t return_id = 0; - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG("specified line %d is invalid", fname, line); - return 0; - } - - id = rm_get_free_element(ci_map_p[line]); - if (id >= 0) { - return_id = ++id; - } - return (return_id); -} -#endif - -/* - * fsmutil_set_ci_id - * - * Description: - * This function marks a specified call instance id as being in - * use in the call instance map. This function is used when in - * CCM mode to store the call instance id specified by the CCM - * for inbound and outbound calls. - * - * Note that call instance ids are one based. The resource manager - * used to implement the call instance map is zero based so we have - * to adjust the call instance id when using the resource manager API. - * Parameters: - * - * Parameters: - * id - The call instance id to set. - * line - Line being used for the call. - * - * Returns: - * None - */ -void -fsmutil_set_ci_id (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_set_ci_id"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid", fname, line); - return; - } - - rm_set_element(ci_map_p[line], (int16_t) --id); -} - -/* - * fsmutil_init_ci_map - * - * Description: - * Utility function to allocate and init the call instance id map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_init_ci_map (void) -{ - static const char fname[] = "fsmutil_init_ci_map"; - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - ci_map_p[line] = rm_create(MAX_CALLS); - - if (!ci_map_p[line]) { - GSM_ERR_MSG(GSM_F_PREFIX"failed to allocate call instance id map for line %d", - fname, line); - } - } -} - -/** - * This function will allocate and initialize the shown_calls_call_instnace map. - * - * @return none - */ -void fsmutil_init_shown_calls_ci_map (void) -{ - static const char fname[] = "fsmutil_init_shown_calls_ci_map"; - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - shown_calls_ci_map_p[line] = rm_create(MAX_CALLS); - - if (!shown_calls_ci_map_p[line]) { - GSM_ERR_MSG(GSM_F_PREFIX"failed to allocate shown calls call instance id map for line %d", - fname, line); - } - } -} - -/** - * This function will set the shown_calls_call_instnace map to zeros. - * - * @return none - */ -void fsmutil_free_all_shown_calls_ci_map (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_clear_all_elements((resource_manager_t *) shown_calls_ci_map_p[line]); - } -} - -/** - * This function marks a given call to be hidden. - * - * @param[in] id - call instance id of the call to be hidden. - * @param[in] line - the line being used for the call. - * - * @return none - */ -void fsmutil_clear_shown_calls_ci_element (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_clear_shown_calls_ci_element"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid", fname, line); - return; - } - - rm_clear_element((resource_manager_t *) shown_calls_ci_map_p[line], (int16_t)(id - 1)); -} - -/** - * This function marks a given call to be shown. - * - * @param[in] id - call instance id of the call to be shown. - * @param[in] line - the line being used for the call. - * - * @return none - */ -void fsmutil_set_shown_calls_ci_element (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_set_shown_calls_ci_element"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid", fname, line); - return; - } - - rm_set_element(shown_calls_ci_map_p[line], (int16_t)(id - 1)); -} - -/** - * This function checks if a given call is to be shown. - * - * @param[in] id - call instance id of the call. - * @param[in] line - the line being used for the call. - * - * @return none - */ -boolean fsmutil_is_shown_calls_ci_element_set (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_is_shown_calls_ci_element_set"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid", fname, id); - return FALSE; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid", fname, line); - return FALSE; - } - - if (rm_is_element_set(shown_calls_ci_map_p[line], (int16_t)(id - 1))) { - return (TRUE); - } - - return (FALSE); -} - -/* - * fsmutil_free_ci_map - * - * Description: - * Utility function to free the call instance id map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_free_ci_map (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_destroy((resource_manager_t *) ci_map_p[line]); - ci_map_p[line] = NULL; - } -} - -/* - * fsmutil_show_ci_map - * - * Description: - * Utility function to display the current state of the call - * instance map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_show_ci_map (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_show(ci_map_p[line]); - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/fsmb2bcnf.c b/media/webrtc/signaling/src/sipcc/core/gsm/fsmb2bcnf.c deleted file mode 100755 index 383b43b02d5..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmb2bcnf.c +++ /dev/null @@ -1,1284 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "debug.h" -#include "config.h" -#include "uiapi.h" -#include "phntask.h" -#include "regmgrapi.h" -#include "subapi.h" -#include "rcc_int_types.h" - -static fsmcnf_ccb_t *fsmb2bcnf_ccbs; - -typedef enum { - FSMB2BCNF_S_MIN = -1, - FSMB2BCNF_S_IDLE, - FSMB2BCNF_S_ACTIVE, - FSMB2BCNF_S_MAX -} fsmb2bcnf_states_t; - -static const char *fsmb2bcnf_state_names[] = { - "IDLE", - "ACTIVE" -}; - - -static sm_rcs_t fsmb2bcnf_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_release(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_release_complete(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_feature(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_feature_ack(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_onhook(sm_event_t *event); - -static sm_function_t fsmb2bcnf_function_table[FSMB2BCNF_S_MAX][CC_MSG_MAX] = -{ -/* FSMB2BCNF_S_IDLE ------------------------------------------------------------ */ - { - /* FSMB2BCNF_E_SETUP */ NULL, - /* FSMB2BCNF_E_SETUP_ACK */ NULL, - /* FSMB2BCNF_E_PROCEEDING */ NULL, - /* FSMB2BCNF_E_ALERTING */ NULL, - /* FSMB2BCNF_E_CONNECTED */ NULL, - /* FSMB2BCNF_E_CONNECTED_ACK */ NULL, - /* FSMB2BCNF_E_RELEASE */ NULL, - /* FSMB2BCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMB2BCNF_E_FEATURE */ fsmb2bcnf_ev_idle_feature, - /* FSMB2BCNF_E_FEATURE_ACK */ NULL, - /* FSMB2BCNF_E_OFFHOOK */ NULL, - /* FSMB2BCNF_E_ONHOOK */ NULL, - /* FSMB2BCNF_E_LINE */ NULL, - /* FSMB2BCNF_E_DIGIT_BEGIN */ NULL, - /* FSMB2BCNF_E_DIGIT */ NULL, - /* FSMB2BCNF_E_DIALSTRING */ NULL, - /* FSMB2BCNF_E_MWI */ NULL, - /* FSMB2BCNF_E_SESSION_AUDIT */ NULL - }, - -/* FSMB2BCNF_S_ACTIVE --------------------------------------------------- */ - { - /* FSMB2BCNF_E_SETUP */ NULL, - /* FSMB2BCNF_E_SETUP_ACK */ NULL, - /* FSMB2BCNF_E_PROCEEDING */ NULL, - /* FSMB2BCNF_E_ALERTING */ fsmb2bcnf_ev_active_feature, - /* FSMB2BCNF_E_CONNECTED */ NULL, - /* FSMB2BCNF_E_CONNECTED_ACK */ NULL, - /* FSMB2BCNF_E_RELEASE */ fsmb2bcnf_ev_active_release, - /* FSMB2BCNF_E_RELEASE_COMPLETE */ fsmb2bcnf_ev_active_release_complete, - /* FSMB2BCNF_E_FEATURE */ fsmb2bcnf_ev_active_feature, - /* FSMB2BCNF_E_FEATURE_ACK */ fsmb2bcnf_ev_active_feature_ack, - /* FSMB2BCNF_E_OFFHOOK */ NULL, - /* FSMB2BCNF_E_ONHOOK */ fsmb2bcnf_ev_active_onhook, - /* FSMB2BCNF_E_LINE */ NULL, - /* FSMB2BCNF_E_DIGIT_BEGIN */ NULL, - /* FSMB2BCNF_E_DIGIT */ NULL, - /* FSMB2BCNF_E_DIALSTRING */ NULL, - /* FSMB2BCNF_E_MWI */ NULL, - /* FSMB2BCNF_E_SESSION_AUDIT */ NULL - } -}; - -static sm_table_t g_fsmb2bcnf_sm_table; -sm_table_t *pfsmb2bcnf_sm_table = &g_fsmb2bcnf_sm_table; - -const char * -fsmb2bcnf_state_name (int state) -{ - if ((state <= FSMB2BCNF_S_MIN) || (state >= FSMB2BCNF_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmb2bcnf_state_names[state]); -} - - -static int -fsmb2bcnf_get_new_b2bcnf_id (void) -{ - static int b2bcnf_id = FSM_NO_ID; - - if (++b2bcnf_id < FSM_NO_ID) { - b2bcnf_id = 1; - } - - return (b2bcnf_id); -} - - -static void -fsmb2bcnf_init_ccb (fsmcnf_ccb_t *ccb) -{ - if (ccb != NULL) { - ccb->cnf_id = FSM_NO_ID; - ccb->cnf_call_id = CC_NO_CALL_ID; - ccb->cns_call_id = CC_NO_CALL_ID; - ccb->cnf_line = CC_NO_LINE; - ccb->cns_line = CC_NO_LINE; - ccb->bridged = FALSE; - ccb->active = FALSE; - ccb->cnf_ftr_ack = FALSE; - ccb->cnf_orig = CC_SRC_MIN; - } -} - -/** - * - * Get active trasnfer state machine information (in active state). - * - * @param none - * - * @return fsm_fcb_t if there is a active trasnfer pending - * else NULL - * - * @pre (none) - */ - -fsm_fcb_t *fsmb2bcnf_get_active_cnf(void) -{ - fsm_fcb_t *fcb; - fsmcnf_ccb_t *b2bccb; - - FSM_FOR_ALL_CBS(b2bccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - fcb = fsm_get_fcb_by_call_id_and_type(b2bccb->cnf_call_id, - FSM_TYPE_B2BCNF); - if (fcb && fcb->state == FSMB2BCNF_S_ACTIVE) { - return(fcb); - } - } - - return(NULL); -} - -static fsmcnf_ccb_t * -fsmb2bcnf_get_ccb_by_b2bcnf_id (int b2bcnf_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - if (ccb->cnf_id == b2bcnf_id) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -/* - * Function: fsmb2bcnf_get_new_b2bcnf_context - * - * Parameters: - * b2bcnf_call_id: call_id for the call initiating the conference - * - * Description: This function creates a new conference context by: - * - getting a free ccb - * - creating new b2bcnf_id and cns_call_id - * - * Returns: ccb - * - */ -static fsmcnf_ccb_t * -fsmb2bcnf_get_new_b2bcnf_context (callid_t b2bcnf_call_id, line_t line) -{ - const char fname[] = "fsmb2bcnf_get_new_b2bcnf_context"; - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_b2bcnf_id(FSM_NO_ID); - if (ccb != NULL) { - ccb->cnf_id = fsmb2bcnf_get_new_b2bcnf_id(); - ccb->cnf_call_id = b2bcnf_call_id; - ccb->cnf_line = line; - ccb->cns_line = line; - ccb->cns_call_id = cc_get_new_call_id(); - - FSM_DEBUG_SM(get_debug_string(FSMB2BCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } else { - - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get new b2bccb.", fname); - } - - return (ccb); -} - - -static fsmcnf_ccb_t * -fsmb2bcnf_get_ccb_by_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - if ((ccb->cnf_call_id == call_id) || (ccb->cns_call_id == call_id)) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -static void -fsmb2bcnf_update_b2bcnf_context (fsmcnf_ccb_t *ccb, callid_t old_call_id, - callid_t new_call_id) -{ - const char fname[] = "fsmb2bcnf_update_b2bcnf_context"; - - if (ccb != NULL) { - if (old_call_id == ccb->cnf_call_id) { - ccb->cnf_call_id = new_call_id; - } else if (old_call_id == ccb->cns_call_id) { - ccb->cns_call_id = new_call_id; - } - - FSM_DEBUG_SM(get_debug_string(FSMB2BCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } -} - -/* - * Function to get line number of other call associated in - * transfer. - * - * @param xcb and call_id. - * - * @return void - * - */ -line_t -fsmb2bcnf_get_other_line (fsmcnf_ccb_t *ccb, callid_t call_id) -{ - line_t other_line = CC_NO_LINE; - - if (ccb != NULL) { - if (ccb->cnf_call_id == call_id) { - other_line = ccb->cns_line; - } else if (ccb->cns_call_id == call_id) { - other_line = ccb->cnf_line; - } - } - - return (other_line); -} - -static callid_t -fsmb2bcnf_get_other_call_id (fsmcnf_ccb_t *ccb, callid_t call_id) -{ - callid_t other_call_id = CC_NO_CALL_ID; - - if (ccb != NULL) { - if (ccb->cnf_call_id == call_id) { - other_call_id = ccb->cns_call_id; - } else if (ccb->cns_call_id == call_id) { - other_call_id = ccb->cnf_call_id; - } - } - - return (other_call_id); -} - -/* - * Function: fsmb2bcnf_remove_fcb - * - * Parameters: - * b2bcnf_id: b2bcnf_id for the conference - * call_id: call_id that identifies the fcb to be removed - * - * Description: This function will remove the fcb identified by the given - * call_id from the ccb. And the function will free the ccb - * if both fcbs have been removed. - * - * Returns: none - * - * Note: This is a helper function for fsmb2bcnf_cleanup. It allows fsmb2bcnf_cleanup - * to cleanup one fcb (one call involved in the conference) independent - * of the other involved fcb. - */ -static void -fsmb2bcnf_remove_fcb (fsm_fcb_t *fcb, callid_t call_id) -{ - fsmcnf_ccb_t *ccb = fcb->b2bccb; - - if (ccb != NULL) { - fsmb2bcnf_update_b2bcnf_context(ccb, call_id, CC_NO_CALL_ID); - - /* - * Free the ccb if both fcb references have been removed. - */ - if ((ccb->cnf_call_id == CC_NO_CALL_ID) && - (ccb->cns_call_id == CC_NO_CALL_ID)) { - fsmb2bcnf_init_ccb(ccb); - } - } -} - - -static void -fsmb2bcnf_cleanup (fsm_fcb_t *fcb, int fname, boolean both) -{ - fsm_fcb_t *other_fcb = NULL; - callid_t call_id = fcb->call_id; - callid_t other_call_id = CC_NO_CALL_ID; - line_t other_line; - - other_call_id = fsmb2bcnf_get_other_call_id(fcb->b2bccb, call_id); - other_line = fsmb2bcnf_get_other_line(fcb->b2bccb, call_id); - - if (other_call_id != CC_NO_CALL_ID) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - } - - if (fcb->b2bccb && (call_id == fcb->b2bccb->cnf_call_id)) { - - if (other_call_id != CC_NO_CALL_ID) { - /* - * Not clearing consulation call, so change consultation - * call attribute to display connected softkey set. - * Do not change softkey set if it is a transfer o - */ - cc_call_attribute(other_call_id, other_line, NORMAL_CALL); - } - - } - /* - * Check if the user wanted to cleanup the whole ccb. - * If so, then we will grab the other fcb first and call this function - * again with this other fcb. The whole ccb will be freed after this block - * of code because both call_ids will be -1, which tells - * fsmb2bcnf_remove_fcb to free the ccb. - */ - if (both) { - if (other_call_id != CC_NO_CALL_ID) { - if (other_fcb != NULL) { - fsmb2bcnf_cleanup(other_fcb, fname, FALSE); - } - } - } - /* - * Remove the reference to this fcb from the ccb. - */ - fsmb2bcnf_remove_fcb(fcb, fcb->call_id); - - /* - * Move this fcb to the IDLE state - */ - fsm_change_state(fcb, fname, FSMB2BCNF_S_IDLE); - - /* - * Reset the data for this fcb. The fcb is still included in a call - * so set the call_id and dcb values accordingly. - */ - fsm_init_fcb(fcb, fcb->call_id, fcb->dcb, FSM_TYPE_B2BCNF); -} - - -void -fsmb2bcnf_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_B2BCNF); - - if (fcb != NULL) { - fsmb2bcnf_cleanup(fcb, __LINE__, FALSE); - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } -} - - -/* - * fsmb2bcnf_check_if_ok_to_setup_conf - * - * Description: - * Checks if the requested call is ok to setup conference. - * - * Parameters: - * call_id - * - * Returns: TRUE - if the call is ok to setup conference - * FALSE - other cases - */ -boolean -fsmb2bcnf_check_if_ok_to_setup_conf (callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - if (call_id == CC_NO_CALL_ID) { - return (FALSE); - } - - dcb = fsm_get_dcb(call_id); - - if(dcb && dcb->policy == CC_POLICY_CHAPERONE - && dcb->is_conf_call == TRUE){ - return (FALSE); - } - - return (TRUE); -} - - -/* - * fsmb2bcnf_b2bcnf_invoke - * - * Description: - * This function implements the conference feature invocation. - * If the feature is already invoked and waiting for the - * feature ack back from the SIP stack then no action taken. - * Otherwise, the conf feature is invoked and state is SET. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void -fsmb2bcnf_cnf_invoke (callid_t call_id, callid_t target_call_id, - line_t line, fsmcnf_ccb_t *ccb) -{ - sipspi_msg_t subscribe_msg; - ccsip_event_data_t *evt_data; - - /* - * post SIPSPI_EV_CC_SUBSCRIBE to SIP stack - */ - evt_data = (ccsip_event_data_t *) - cpr_malloc(sizeof(ccsip_event_data_t)); - if (evt_data == NULL) { - return; - } - memset(evt_data, 0, sizeof(ccsip_event_data_t)); - evt_data->type = EVENT_DATA_REMOTECC_REQUEST; - evt_data->u.remotecc_data.line = 0; - evt_data->u.remotecc_data.rcc_request_type = RCC_SOFTKEY_EVT; - evt_data->u.remotecc_data.rcc_int.rcc_softkey_event_msg.softkeyevent = RCC_SOFTKEY_CONFERENCE; - evt_data->u.remotecc_data.consult_gsm_id = target_call_id; - evt_data->u.remotecc_data.gsm_id = call_id; - - memset(&subscribe_msg, 0, sizeof(sipspi_msg_t)); - subscribe_msg.msg.subscribe.eventPackage = CC_SUBSCRIPTIONS_REMOTECC; - subscribe_msg.msg.subscribe.sub_id = CCSIP_SUBS_INVALID_SUB_ID; - subscribe_msg.msg.subscribe.auto_resubscribe = TRUE; - subscribe_msg.msg.subscribe.request_id = (long)ccb; - subscribe_msg.msg.subscribe.duration = 60; - subscribe_msg.msg.subscribe.subsNotCallbackTask = CC_SRC_GSM; - subscribe_msg.msg.subscribe.subsResCallbackMsgID = SUB_MSG_B2BCNF_SUBSCRIBE_RESP; - subscribe_msg.msg.subscribe.subsNotIndCallbackMsgID = SUB_MSG_B2BCNF_NOTIFY; - subscribe_msg.msg.subscribe.subsTermCallbackMsgID = SUB_MSG_B2BCNF_TERMINATE; - subscribe_msg.msg.subscribe.norefersub = FALSE; - subscribe_msg.msg.subscribe.eventData = evt_data; - subscribe_msg.msg.subscribe.dn_line = line; - - (void)sub_int_subscribe(&subscribe_msg); -} - -/** - * - * Cancel b2b conference feature by sending cancel event to SIP stack. - * This routine is used in roundtable phone. - * - * @param line, call_id, target_call_id, cause (implicit or explicit) - * - * @return void - * - * @pre (none) - */ -void -fsmb2bcnf_feature_cancel (fsmcnf_ccb_t *ccb, line_t line, callid_t call_id, - callid_t target_call_id, - cc_rcc_skey_evt_type_e cause) -{ - cc_feature_data_t data; - fsm_fcb_t *fcb_def; - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - fcb_def = fsm_get_fcb_by_call_id_and_type(target_call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, target_call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - data.cancel.target_call_id = target_call_id; - data.cancel.call_id = call_id; - data.cancel.cause = cause; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, CC_FEATURE_CANCEL, &data); -} - -/******************************************************************* - * event functions - */ - - -static sm_rcs_t -fsmb2bcnf_ev_idle_feature (sm_event_t *event) -{ - const char *fname = "fsmb2bcnf_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *ftr_data = &(msg->data); - fsmdef_dcb_t *dcb = fcb->dcb; - callid_t cns_call_id; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb; - int free_lines; - cc_feature_data_t data; - fsm_fcb_t *other_fcb, *cns_fcb; - fsm_fcb_t *fcb_def; - callid_t other_call_id; - line_t newcall_line = 0; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_RCC: - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_B2BCONF: - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - if (ftr_data && msg->data_valid && - (ftr_data->b2bconf.target_call_id != CC_NO_CALL_ID) - && (cns_fcb = fsm_get_fcb_by_call_id_and_type(ftr_data->b2bconf.target_call_id, - FSM_TYPE_B2BCNF)) != NULL) { - /* - * Get a new ccb and new b2bcnf id - This is the handle that will - * identify the b2bcnf. - */ - ccb = fsmb2bcnf_get_new_b2bcnf_context(call_id, line); - - if (ccb==NULL || ccb->cnf_id == FSM_NO_ID) { - return(SM_RC_END); - } - - /* Conference origination id, required later. This indicates conf is - * because of UI or because of CTI - */ - ccb->cnf_orig = src_id; - - ccb->cns_call_id = ftr_data->b2bconf.target_call_id; - fcb->b2bccb = ccb; - cns_fcb->b2bccb = ccb; - - /* Find line information for target call. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if (fcb_def != NULL && fcb_def->dcb) { - - ccb->cns_line = fcb_def->dcb->line; - - } else { - - return(SM_RC_END); - } - - fsm_change_state(fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - fsm_change_state(cns_fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, ccb->cns_call_id, - ccb->cns_line, CC_FEATURE_B2BCONF, NULL); - return(SM_RC_END); - - } - - - /* - * This call is the conference and we are initiating a local - * conference. So: - * 1. Make sure we have a free line to open a new call plane to - * collect digits (and place call) for the consultation call, - * 2. Create a new conference context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check for any other active features which may block - * the conference. - */ - - /* - * The call must be in the connected state to initiate a conference - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && (fcb_def->state != FSMDEF_S_CONNECTED)) { - break; - } - - /* - * Make sure we have a free line to start the consultation call. - */ - //CSCsz38962 don't use expline for b2bcnf call - //free_lines = lsm_get_instances_available_cnt(line, TRUE); - free_lines = lsm_get_instances_available_cnt(line, FALSE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this request. - */ - fsm_display_no_free_lines(); - - break; - } - - newcall_line = lsm_get_newcall_line(line); - if (newcall_line == NO_LINES_AVAILABLE) { - /* - * Error Pass Limit- let the user know and end this request. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - - break; - } - - /* - * Get a new ccb and new b2bcnf id - This is the handle that will - * identify the b2bcnf. - */ - ccb = fsmb2bcnf_get_new_b2bcnf_context(call_id, line); - - if (ccb==NULL || ccb->cnf_id == FSM_NO_ID) { - break; - } - - ccb->cnf_orig = src_id; - fcb->b2bccb = ccb; - ccb->cns_line = newcall_line; - - /* - * This call needs to go on hold so we can start the consultation - * call. Indicate feature indication should be send by setting - * call info type to hold and feature reason to conference. - */ - memset(&data, 0, sizeof(data)); - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = CC_REASON_CONF; - data.hold.msg_body.num_parts = 0; - data.hold.call_info.data.call_info_feat_data.protect = TRUE; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - - /* - * Initiate the consultation call. - */ - data.newcall.cause = CC_CAUSE_CONF; - cns_call_id = ccb->cns_call_id; - sstrncpy(data.newcall.global_call_id, - ftr_data->b2bconf.global_call_id, CC_GCID_LEN); - data.newcall.prim_call_id = ccb->cnf_call_id; - data.newcall.hold_resume_reason = CC_REASON_CONF; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMB2BCNF_DBG_CNF_INITIATED), - ccb->cnf_id, call_id, cns_call_id, __LINE__); - - fsm_change_state(fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - sm_rc = SM_RC_END; - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_NOTIFY: - - /* Since this message is specifically for conference, msg is - * consumed here and not forwarded - */ - if ((msg->data.notify.subscription == CC_SUBSCRIPTIONS_REMOTECC) - && (msg->data.notify.data.rcc.feature == CC_FEATURE_B2BCONF)) { - sm_rc = SM_RC_END; - } - break; - case CC_FEATURE_NEW_CALL: - /* - * If this is the consultation call involved in a conference, - * then set the rest of the data required to make the conference - * happen. The data is the b2bcnf_id in the fcb. The data is set now - * because we did not have the fcb when the conference was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a conference event is received. - * - * Or this could be the call that originated the conference and - * the person he was talking to (the conference target) has - * decided to conference the trasnferor to another party. - */ - - /* - * Ignore this event if this call is not involved in a conference. - */ - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - if (ccb == NULL) { - break; - } - fcb->b2bccb = ccb; - - /* - * Determine what state this b2bcnf should be in (b2bcnfing or b2bcnfed). - * If the cnfrn key has only been hit once, then this call will - * be in the cnfing state. If it has been hit the second time, - * then this call should go to the cnfed state. The latter - * case only happens when the calls are conferenced and one - * of the remote ends has decided to transfer one leg of the cnf. - * And it just so happens that the other call involved in the cnf - * should match this call, so we can just use it's state to - * assign the state to this call. - */ - other_call_id = fsmb2bcnf_get_other_call_id(ccb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - - if (other_fcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"FCP not found", fname); - } else { - fsm_change_state(fcb, __LINE__, other_fcb->state); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmb2bcnf_ev_active_release (sm_event_t *event) -{ - - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - - /* For round table phone wait for NOTIFY response, so do not - * clear the conf state machine - */ - if (ccb->active == FALSE) { - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - } - - return (SM_RC_CONT); -} - -static sm_rcs_t -fsmb2bcnf_ev_active_release_complete (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - - if (ccb->active == FALSE) { - - - fsmb2bcnf_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - } - - return (SM_RC_CONT); -} - -static sm_rcs_t -fsmb2bcnf_ev_active_feature (sm_event_t *event) -{ - static const char fname[] = "fsmb2bcnf_ev_active_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *feat_data = &(msg->data); - sm_rcs_t sm_rc = SM_RC_CONT; - callid_t other_call_id; - fsmdef_dcb_t *other_dcb; - fsm_fcb_t *other_fcb; - cc_action_data_t action_data; - fsm_fcb_t *cnf_fcb = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - memset(&action_data, 0, sizeof(cc_action_data_t)); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_RCC: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, - CC_SK_EVT_TYPE_EXPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_HOLD: - /* Do not send out protect parameter for CTI generated conference - * and send protect=true for swap or hold call - */ - if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_SWAP || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_CONF || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_INTERNAL)) - { - feat_data->hold.call_info.data.call_info_feat_data.protect = TRUE; - } else if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_RCC)) { - //Do nothing remote-cc will terminate the feature layer. - - } else { - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(ccb->cnf_line, ccb->cnf_call_id, ccb->cns_call_id); - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_FEATURE_B2BCONF: - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - DEF_DEBUG(DEB_F_PREFIX"ACTIVE CNF call_id = %d, t_id = %d, cns_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, - feat_data->b2bconf.target_call_id, ccb->cns_call_id); - - if (feat_data && msg->data_valid && - (feat_data->b2bconf.target_call_id != CC_NO_CALL_ID)) { - /* End existing consult call and then link another - * call with the trasfer. This is the case where User can - * select active call instead of consultative call - */ - cnf_fcb = fsm_get_fcb_by_call_id_and_type(ccb->cns_call_id, - FSM_TYPE_DEF); - - /* If the call_id is different then active call has been picked - */ - - if (ccb->cns_call_id != feat_data->b2bconf.target_call_id) { - - cnf_fcb = fsm_get_fcb_by_call_id_and_type(ccb->cns_call_id, - FSM_TYPE_B2BCNF); - - if (cnf_fcb != NULL) { - DEF_DEBUG(DEB_F_PREFIX"INVOKE ACTIVE CNF call_id = %d, t_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, - feat_data->b2bconf.target_call_id); - - cnf_fcb->b2bccb = ccb; - fsm_change_state(cnf_fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, ccb->cns_call_id, - ccb->cnf_line, CC_FEATURE_B2BCONF, NULL); - } - - return(SM_RC_END); - } - } - /* - * This is the second conference event for a local - * attended conference with consultation. - * - * The user is attempting to complete the conference, so - * resume the other leg of the conference call. - */ - ccb->active = TRUE; - - if (dcb) { - dcb->active_feature = CC_FEATURE_B2BCONF; - } - - other_call_id = fsmb2bcnf_get_other_call_id(ccb, call_id); - other_dcb = fsm_get_dcb(other_call_id); - - //Update confinvoked value through JPlatUi method. - ui_update_conf_invoked(other_dcb->line, other_call_id, TRUE); - - fsmb2bcnf_cnf_invoke(fsmb2bcnf_get_other_call_id(ccb, call_id), - call_id, other_dcb->line, ccb); - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - - fsm_change_state(other_fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - fsm_change_state(fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - sm_rc = SM_RC_END; - - break; - - case CC_FEATURE_END_CALL: - /* Release ccbs related to conference and allow event to pass through - * fsmdef - */ - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - - break; - - - case CC_FEATURE_RESUME: - /* to achieve SCCP phone behaviour, if the 1st call is resumed - * then conference should be terminated. - */ - if (ccb->cnf_orig == CC_SRC_RCC) { - if (ccb->cnf_call_id == call_id) { - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - ((cc_state_data_t *) (&(dcb->caller_id)))); - } - } - break; - - case CC_FEATURE_NOTIFY: - - if ((msg->data.notify.subscription == CC_SUBSCRIPTIONS_REMOTECC) - && (msg->data.notify.data.rcc.feature == CC_FEATURE_B2BCONF)) { - - if (msg->data.notify.cause_code != RCC_SUCCESS) { - fsmb2bcnf_feature_cancel(fcb->b2bccb, fcb->b2bccb->cnf_line, - fcb->b2bccb->cnf_call_id, - fcb->b2bccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - } - /* - * Conference key press has been accepted, so now terminate the - * conference data structures. This call is now same as any other - * regular call. All the future events are handled by fsmdef. - */ - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - sm_rc = SM_RC_END; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALL_PRESERVATION: - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(ccb->cnf_line, ccb->cnf_call_id, ccb->cns_call_id); - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -static sm_rcs_t -fsmb2bcnf_ev_active_feature_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - callid_t call_id = msg->call_id; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc = SM_RC_CONT; - cc_action_data_t data; - callid_t other_call_id; - callid_t other_ui_id; - - fsm_sm_ftr(ftr_id, src_id); - - memset(&data, 0, sizeof(cc_action_data_t)); - - switch (src_id) { - case CC_SRC_GSM: - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_B2BCONF: - /* Handle 2nd conference key press completion NOTIFY */ - if (msg->cause == CC_CAUSE_ERROR) { - other_call_id = - fsmb2bcnf_get_other_call_id(fcb->b2bccb, call_id); - - other_ui_id = lsm_get_ui_id(other_call_id); - ui_set_call_status(platform_get_phrase_index_str(CONF_CANNOT_COMPLETE), - msg->line, other_ui_id); - fsmb2bcnf_feature_cancel(fcb->b2bccb, fcb->b2bccb->cnf_line, fcb->b2bccb->cnf_call_id, - fcb->b2bccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - break; - } - - sm_rc = SM_RC_END; - break; - - case CC_FEATURE_NOTIFY: - - if ((msg->data.notify.subscription == CC_SUBSCRIPTIONS_REMOTECC) && - (msg->data.notify.data.rcc.feature == CC_FEATURE_B2BCONF)) { - - /* - * Conference key press has been accepted, so now terminate the - * conference data structures. This call is now same as any other - * regular call. All the future events are handled by fsmdef. - */ - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - sm_rc = SM_RC_END; - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -void -fsmb2bcnf_get_sub_call_id_from_ccb(fsmcnf_ccb_t *ccb, callid_t *cnf_call_id, - callid_t *cns_call_id) -{ - static const char fname[] = "fsmb2bcnf_get_sub_call_id_from_ccb"; - - DEF_DEBUG(DEB_F_PREFIX"call_id = %d t_call_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - - *cnf_call_id = ccb->cnf_call_id; - *cns_call_id = ccb->cns_call_id; -} - -static sm_rcs_t -fsmb2bcnf_ev_active_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - cc_onhook_t *msg = (cc_onhook_t *) event->msg; - - /* For RT phone active call list can be invoked during - * conf and that genertes onhook event for existing - * consult call. Conf state machine is not terminated - */ - if (msg->active_list == CC_REASON_ACTIVECALL_LIST) { - - ccb->cns_line = CC_NO_LINE; - ccb->cns_call_id = CC_NO_CALL_ID; - - } else { - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - } - - return (SM_RC_CONT); -} - -cc_int32_t -fsmb2bcnf_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmcnf_ccb_t *ccb; - int i = 0; - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("show fsmb2bcnf\n"); - return (0); - } - - debugif_printf("\n-------------------------- FSMB2BCNF ccbs --------------------------"); - debugif_printf("\ni b2bcnf_id ccb cnf_call_id cns_call_id active bridged"); - debugif_printf("\n--------------------------------------------------------------------" - "\n"); - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - debugif_printf("%-2d %-6d %p %-11d %-11d %-6d %-7d\n", - i++, ccb->cnf_id, ccb, ccb->cnf_call_id, - ccb->cns_call_id, ccb->active, ccb->bridged); - } - - return (0); -} - - -void -fsmb2bcnf_init (void) -{ - fsmcnf_ccb_t *ccb; - static const char *fname = "fsmb2bcnf_init"; - - - /* - * Initialize the ccbs. - */ - fsmb2bcnf_ccbs = (fsmcnf_ccb_t *) - cpr_malloc(sizeof(fsmcnf_ccb_t) * FSMCNF_MAX_CCBS); - - if (fsmb2bcnf_ccbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate memory \ - forb2bcnf ccbs.\n", fname); - return; - } - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - fsmb2bcnf_init_ccb(ccb); - } - - /* - * Initialize the state/event table. - */ - g_fsmb2bcnf_sm_table.min_state = FSMB2BCNF_S_MIN; - g_fsmb2bcnf_sm_table.max_state = FSMB2BCNF_S_MAX; - g_fsmb2bcnf_sm_table.min_event = CC_MSG_MIN; - g_fsmb2bcnf_sm_table.max_event = CC_MSG_MAX; - g_fsmb2bcnf_sm_table.table = (&(fsmb2bcnf_function_table[0][0])); -} - - -callid_t -fsmb2bcnf_get_primary_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - - if (ccb && (ccb->cns_call_id == call_id)) { - return (fsmb2bcnf_get_other_call_id(ccb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} - -callid_t -fsmb2bcnf_get_consult_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - - if (ccb && ccb->cnf_call_id == call_id) { - return (fsmb2bcnf_get_other_call_id(ccb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} - -int -fsmutil_is_b2bcnf_consult_call (callid_t call_id) -{ - return fsmutil_is_cnf_consult_leg(call_id, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS); -} - -boolean -fsmb2bcnf_is_rcc_orig_b2bcnf (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - if (ccb && ccb->cnf_orig == CC_SRC_RCC) { - return TRUE; - } - - return FALSE; -} - -void -fsmb2bcnf_shutdown (void) -{ - cpr_free(fsmb2bcnf_ccbs); - fsmb2bcnf_ccbs = NULL; -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/fsmcac.c b/media/webrtc/signaling/src/sipcc/core/gsm/fsmcac.c deleted file mode 100755 index 22311a5b4b4..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmcac.c +++ /dev/null @@ -1,707 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "phntask.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "gsm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "debug.h" -#include "text_strings.h" -#include "sip_interface_regmgr.h" -#include "resource_manager.h" -#include "singly_link_list.h" -#include "platform_api.h" - -#define CAC_FAILURE_TIMEOUT 5 -cc_int32_t g_cacDebug = 0; - -/* CAC key */ -typedef struct { - callid_t call_id; -} cac_key_t; - - -typedef enum { - FSM_CAC_IDLE = 0, - FSM_CAC_REQ_PENDING = 1, - FSM_CAC_REQ_RESP = 2 -} fsm_cac_state_e; - -/* CAC structure to hold the data - */ -typedef struct cac_data_t { - void *msg_ptr; - callid_t call_id; - void *cac_fail_timer; - fsm_cac_state_e cac_state; - uint32_t sessions; -} cac_data_t; - -static sll_handle_t s_cac_list = NULL; - - - -/* - * Function responsible for searching the list waiting for - * bandwidth allocation. - * - * @param cac_data_t *key_p - pointer to the key. - * @param cac_data_t *cac_data - cac data. - * - * @return void - * - */ -static sll_match_e -fsm_cac_match_call_id (cac_data_t *key_p, cac_data_t *cac_data) -{ - if (cac_data->call_id == key_p->call_id) { - - return SLL_MATCH_FOUND; - } - - return SLL_MATCH_NOT_FOUND; - -} - -/* - * Function responsible to create new data information - * for cac. - * - * @param none. - * - * @return cac_data_t * - * - */ -static cac_data_t * -fsm_get_new_cac_data (void) -{ - static const char *fname="fsm_get_new_cac_data"; - cac_data_t *cac_mem; - - cac_mem = (cac_data_t *) cpr_malloc(sizeof(cac_data_t)); - - if (cac_mem == NULL) { - CAC_ERROR(DEB_F_PREFIX"No memory for CAC data.", - DEB_F_PREFIX_ARGS("CAC", fname)); - return (NULL); - } - - memset(cac_mem, 0, sizeof(cac_data_t)); - return (cac_mem); -} - -/** - * - * Release all cac related data. This includes timer, cac_data - * and message buffers - * - * @param cac_data cac data structure - * - * @return none. - * - * @pre (cac_data not_eq NULL) - */ - -static void -fsm_clear_cac_data (cac_data_t *cac_data) -{ - - if (cac_data->cac_fail_timer) { - (void) cprCancelTimer(cac_data->cac_fail_timer); - - (void) cprDestroyTimer(cac_data->cac_fail_timer); - } - - (void) sll_remove(s_cac_list, cac_data); - - fim_free_event(cac_data->msg_ptr); - - /* Release buffer too */ - cpr_free(cac_data->msg_ptr); - - cpr_free(cac_data); - -} - -/** - * - * Notifies the SIP stack and UI that CAC has failed. - * - * @param cac_data cac data structure - * - * @return none. - * - * @pre (cac_data not_eq NULL) - */ - -static void fsm_cac_notify_failure (cac_data_t *cac_data) -{ - const char fname[] = "fsm_cac_notify_failure"; - cc_setup_t *msg = (cc_setup_t *) cac_data->msg_ptr; - cc_msgs_t msg_id = msg->msg_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - int event_id = msg_id; - cc_srcs_t src_id = msg->src_id; - - /* Notify UI about the failure */ - lsm_ui_display_notify_str_index(STR_INDEX_NO_BAND_WIDTH); - - /* Send response from network side regarding the failure */ - if (event_id == CC_MSG_SETUP && - src_id == CC_SRC_SIP) { - DEF_DEBUG(DEB_F_PREFIX"Send CAC failure to SIP %d.", - DEB_F_PREFIX_ARGS("CAC", fname), cac_data->call_id); - cc_int_release(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_CAUSE_CONGESTION, NULL, NULL); - } else { - /* If the cac failed, GSM is not spinning yet, so just send the - * information to UI in this case. Other case, where GSM receives event - * will send the information from GSM. - * If the UI is not cleaned up, session infomation is not cleared. - */ - ui_call_state(evOnHook, line, call_id, CC_CAUSE_CONGESTION); - } - -} - -/** - * - * Initialize the cac timer. This timer is responsible for cleanup if the - * cac response is not received from lower layer. - * - * @param cac_data cac data structure - * timeout specify the time out in sec - * - * @return true if the timer is created scuccessfully. - * false if the timer is not created. - * - * @pre (cac_data not_eq NULL) - */ - -static boolean -fsm_init_cac_failure_timer(cac_data_t *cac_data, uint32_t timeout) -{ - const char fname[] = "fsm_init_cac_failure_timer"; - - CAC_DEBUG(DEB_F_PREFIX"cac_data call_id=%x", - DEB_F_PREFIX_ARGS("CAC", fname), - cac_data->call_id); - - cac_data->cac_fail_timer = - cprCreateTimer("CAC failure timer", GSM_CAC_FAILURE_TIMER, TIMER_EXPIRATION, - gsm_msgq); - - if (cac_data->cac_fail_timer == NULL) { - CAC_ERROR(DEB_F_PREFIX"CAC Timer allocation failed.", - DEB_F_PREFIX_ARGS("CAC", fname)); - return(FALSE); - } - - (void) cprStartTimer(cac_data->cac_fail_timer, timeout * 1000, - (void *)(long)cac_data->call_id); - - return(TRUE); -} - -/** - * - * Serches through cac link list and returns cac_data - * based on call_id. This search is a singly link list search. - * - * @param call_id call_id of the call - * - * @return cac_data if found in the list - * NULL if there is no cac_data - * - * @pre (call_id not_eq CC_NO_CALL_ID) - */ - -static cac_data_t * -fsm_cac_get_data_by_call_id (callid_t call_id) -{ - const char fname[] = "fsm_cac_get_data_by_call_id"; - cac_data_t *cac_data; - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - while (cac_data != NULL) { - - if (cac_data->call_id == call_id) { - CAC_DEBUG(DEB_F_PREFIX"cac_data found call_id=%x", - DEB_F_PREFIX_ARGS("CAC", fname), - cac_data->call_id); - return(cac_data); - } - - cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - } - - CAC_DEBUG(DEB_F_PREFIX"cac_data NOT found.", - DEB_F_PREFIX_ARGS("CAC", fname)); - return(NULL); -} - -/** - * - * Initialize cac module by enabling debugs and creating a cac list. - * - * @param void - * - * @return void - * - * @pre (NULL) - */ -void fsm_cac_init (void) -{ - const char fname[] = "fsm_cac_init"; - - - /* allocate and initialize cac list */ - s_cac_list = sll_create((sll_match_e(*)(void *, void *)) - fsm_cac_match_call_id); - - if (s_cac_list == NULL) { - CAC_ERROR(DEB_F_PREFIX"CAC list creation failed.", - DEB_F_PREFIX_ARGS("CAC", fname)); - - } -} - -/** - * - * clears all the entries in the cac list - * - * @param void - * - * @return void - * - * @pre (NULL) - */ -void fsm_cac_clear_list (void) -{ - const char fname[] = "fsm_cac_clear_list"; - cac_data_t *cac_data; - cac_data_t *prev_cac_data; - - DEF_DEBUG(DEB_F_PREFIX"Clear all pending CAC dat.", - DEB_F_PREFIX_ARGS("CAC", fname)); - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - while (cac_data != NULL) { - - prev_cac_data = cac_data; - cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - fsm_cac_notify_failure(prev_cac_data); - fsm_clear_cac_data(prev_cac_data); - } - -} - -/** - * - * Shutdown cac module, clears all the pending cac requests - * - * @param void - * - * @return void - * - * @pre (NULL) - */ -void fsm_cac_shutdown (void) -{ - - fsm_cac_clear_list(); - - sll_destroy(s_cac_list); - - s_cac_list = NULL; -} - -/** - * - * Check if there are pending CAC requests - * - * @param none - * - * @return cac_data returns first pending request. - * - * @pre (NULL) - */ -static cac_data_t * -fsm_cac_check_if_pending_req (void) -{ - cac_data_t *cac_data; - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - while (cac_data != NULL) { - - if (cac_data->cac_state == FSM_CAC_REQ_PENDING || - cac_data->cac_state == FSM_CAC_IDLE) { - - return(cac_data); - } - - cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - } - - return(NULL); -} - -/** - * - * Check if there are pending CAC requests - * - * @param none - * - * @return cac_data returns first pending request. - * - * @pre (NULL) - */ -static cc_causes_t -fsm_cac_process_bw_allocation (cac_data_t *cac_data) -{ - const char fname[] = "fsm_cac_process_bw_allocation"; - - if (lsm_allocate_call_bandwidth(cac_data->call_id, cac_data->sessions) == - CC_CAUSE_CONGESTION) { - - DEF_DEBUG(DEB_F_PREFIX"CAC Allocation failed.", - DEB_F_PREFIX_ARGS("CAC", fname)); - - fsm_cac_notify_failure(cac_data); - - fsm_clear_cac_data(cac_data); - - return(CC_CAUSE_CONGESTION); - } - - cac_data->cac_state = FSM_CAC_REQ_PENDING; - - return(CC_CAUSE_OK); -} - -/** - * - * Check if there are pending CAC requests - * - * @param call_id request a cac for this call_id - * sessions number of sessions in the request - * msg ccapi msg, that is held to process - * till cac response is received. - * - * @return CC_CAUSE_BW_OK if the bandwidth is received. - * CC_CAUSE_Ok Call returned successfully, not sure about BW yet - * CC_CAUSE_ERROR: Call returned with failure. - * - * @pre (NULL) - */ -cc_causes_t -fsm_cac_call_bandwidth_req (callid_t call_id, uint32_t sessions, - void *msg) -{ - const char fname[] = "fsm_cac_call_bandwidth_req"; - cac_data_t *cac_data, *cac_pend_data; - - /* If wlan not connected return OK */ - cac_data = fsm_get_new_cac_data(); - - if (cac_data == NULL) { - - return(CC_CAUSE_CONGESTION); - } - - cac_data->msg_ptr = msg; - cac_data->call_id = call_id; - cac_data->cac_state = FSM_CAC_IDLE; - cac_data->sessions = sessions; - - fsm_init_cac_failure_timer(cac_data, CAC_FAILURE_TIMEOUT); - - /* Make sure there is no pending requests before submitting - * another one - */ - if ((cac_pend_data = fsm_cac_check_if_pending_req()) == NULL) { - - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - DEF_DEBUG(DEB_F_PREFIX"CAC request for %d sessions %d.", - DEB_F_PREFIX_ARGS("CAC", fname), call_id, sessions); - - if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { - - return(CC_CAUSE_CONGESTION); - } - - cac_data->cac_state = FSM_CAC_REQ_PENDING; - - } else if (cac_pend_data->cac_state == FSM_CAC_IDLE) { - - if (fsm_cac_process_bw_allocation(cac_pend_data) == - CC_CAUSE_CONGESTION) { - - /* Clear all remaining data */ - fsm_cac_clear_list(); - - return(CC_CAUSE_CONGESTION); - } - - } - - (void) sll_append(s_cac_list, cac_data); - - return(CC_CAUSE_OK); - -} - -/** - * - * This is called by gsm to cleanup the cac data. If there are any - * pending CAC requests and far end cancels the call, the pending - * request has to be canceled. - * - * @param call_id - call_id of the request - * - * @return none. - * - * @pre (NULL) - */ -void fsm_cac_call_release_cleanup (callid_t call_id) -{ - cac_data_t *cac_data; - - cac_data = fsm_cac_get_data_by_call_id(call_id); - - if (cac_data) { - - sll_remove(s_cac_list, cac_data); - - fsm_clear_cac_data(cac_data); - } - -} - - -/** - * - * Called when the bandwidth response with available bw is received. This - * also process held ccapi messages through fim event chain - * - * @param none - * - * @return CC_CAUSE_NO_RESOURCE No bandwidth - * CC_CAUSE_OK if ok - * - * - * @pre (NULL) - */ - -cc_causes_t -fsm_cac_process_bw_avail_resp (void) -{ - const char fname[] = "fsm_cac_process_bw_avail_resp"; - cac_data_t *cac_data = NULL; - cac_data_t *next_cac_data = NULL; - - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - if (cac_data != NULL) { - - switch (cac_data->cac_state) { - default: - case FSM_CAC_IDLE: - DEF_DEBUG(DEB_F_PREFIX"No Pending CAC request.", - DEB_F_PREFIX_ARGS("CAC", fname)); - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { - - sll_remove(s_cac_list, cac_data); - - return(CC_CAUSE_NO_RESOURCE); - } - - - break; - case FSM_CAC_REQ_PENDING: - - next_cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - sll_remove(s_cac_list, cac_data); - - /* Request for the next bandwidth */ - DEF_DEBUG(DEB_F_PREFIX"Process pending responses %d.", - DEB_F_PREFIX_ARGS("CAC", fname), cac_data->call_id); - - /* Let GSM process completed request */ - fim_process_event(cac_data->msg_ptr, TRUE); - - fsm_clear_cac_data(cac_data); - - if (next_cac_data != NULL) { - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - DEF_DEBUG(DEB_F_PREFIX"Requesting next allocation %d.", - DEB_F_PREFIX_ARGS("CAC", fname), next_cac_data->call_id); - - if (fsm_cac_process_bw_allocation(next_cac_data) == - CC_CAUSE_CONGESTION) { - - /* If the next data was in idle state and the request fialed - * then clean up the remaining list - */ - if (next_cac_data->cac_state == FSM_CAC_IDLE) { - /* Clear all remaining data */ - fsm_cac_clear_list(); - } else { - - sll_remove(s_cac_list, next_cac_data); - } - - return(CC_CAUSE_NO_RESOURCE); - } - - } - - break; - } - - } - - return(CC_CAUSE_NO_RESOURCE); - -} - -/** - * - * Called when the bandwidth response with failed bw is received. This - * also process held ccapi messages through fim event chain - * - * @param none - * - * @return CC_CAUSE_NO_RESOURCE No bandwidth - * CC_CAUSE_OK if ok - * - * - * @pre (NULL) - */ -cc_causes_t -fsm_cac_process_bw_failed_resp (void) -{ - const char fname[] = "fsm_cac_process_bw_avail_resp"; - cac_data_t *cac_data = NULL; - cac_data_t *next_cac_data = NULL; - - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - if (cac_data != NULL) { - - switch (cac_data->cac_state) { - default: - case FSM_CAC_IDLE: - DEF_DEBUG(DEB_F_PREFIX"No Pending request.", - DEB_F_PREFIX_ARGS("CAC", fname)); - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { - - sll_remove(s_cac_list, cac_data); - - return(CC_CAUSE_NO_RESOURCE); - } - - break; - case FSM_CAC_REQ_PENDING: - - next_cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - sll_remove(s_cac_list, cac_data); - - /* Request for the next bandwidth */ - DEF_DEBUG(DEB_F_PREFIX"Process pending responses even after failure.", - DEB_F_PREFIX_ARGS("CAC", fname)); - - /* Let GSM process completed request */ - fsm_cac_notify_failure(cac_data); - - fsm_clear_cac_data(cac_data); - - if (next_cac_data != NULL) { - - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - if (fsm_cac_process_bw_allocation(next_cac_data) == CC_CAUSE_CONGESTION) { - - /* If the next data was in idle state and the request fialed - * then clean up the remaining list - */ - if (next_cac_data->cac_state == FSM_CAC_IDLE) { - /* Clear all remaining data */ - fsm_cac_clear_list(); - } else { - - sll_remove(s_cac_list, next_cac_data); - } - - return(CC_CAUSE_NO_RESOURCE); - } - - } - - break; - } - - } - - return(CC_CAUSE_NO_RESOURCE); -} - -/** - * - * Process time-out event. This cause cac data to send failure notifications. - * - * @param void *tmr_data - timer data - * - * @return none - * - * - * @pre (NULL) - */ -void -fsm_cac_process_bw_fail_timer (void *tmr_data) -{ - const char fname[] = "fsm_cac_process_bw_fail_timer"; - - DEF_DEBUG(DEB_F_PREFIX"CAC request timedout %d.", - DEB_F_PREFIX_ARGS("CAC", fname), (callid_t)(long)tmr_data); - - /* Time-out causes same set of processing as bw failure - */ - fsm_cac_process_bw_failed_resp(); - -} - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/fsmcnf.c b/media/webrtc/signaling/src/sipcc/core/gsm/fsmcnf.c deleted file mode 100755 index 25d0f12f46f..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmcnf.c +++ /dev/null @@ -1,1749 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_stdio.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "config.h" -#include "debug.h" -#include "gsm_sdp.h" -#include "regmgrapi.h" -#include "platform_api.h" - -static fsmcnf_ccb_t *fsmcnf_ccbs; - -static int softkey_mask_list[MAX_SOFT_KEYS]; - -#define FSMCNF_CONNECTED_SET "CONNECTED" - -typedef enum { - FSMCNF_S_MIN = -1, - FSMCNF_S_IDLE, - FSMCNF_S_CNFING, - FSMCNF_S_CNFED, - FSMCNF_S_MAX -} fsmcnf_states_t; - -static const char *fsmcnf_state_names[] = { - "IDLE", - "CNFING", - "CNFED" -}; - - -static sm_rcs_t fsmcnf_ev_idle_setup(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfing_release(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfing_feature(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfing_onhook(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_release(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_feature(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_feature_ack(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_onhook(sm_event_t *event); - -static sm_function_t fsmcnf_function_table[FSMCNF_S_MAX][CC_MSG_MAX] = -{ -/* FSMCNF_S_IDLE ------------------------------------------------------------ */ - { - /* FSMCNF_E_SETUP */ fsmcnf_ev_idle_setup, - /* FSMCNF_E_SETUP_ACK */ NULL, - /* FSMCNF_E_PROCEEDING */ NULL, - /* FSMCNF_E_ALERTING */ NULL, - /* FSMCNF_E_CONNECTED */ NULL, - /* FSMCNF_E_CONNECTED_ACK */ NULL, - /* FSMCNF_E_RELEASE */ NULL, - /* FSMCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMCNF_E_FEATURE */ fsmcnf_ev_idle_feature, - /* FSMCNF_E_FEATURE_ACK */ NULL, - /* FSMCNF_E_OFFHOOK */ NULL, - /* FSMCNF_E_ONHOOK */ NULL, - /* FSMCNF_E_LINE */ NULL, - /* FSMCNF_E_DIGIT_BEGIN */ NULL, - /* FSMCNF_E_DIGIT */ NULL, - /* FSMCNF_E_DIALSTRING */ NULL, - /* FSMCNF_E_MWI */ NULL, - /* FSMCNF_E_SESSION_AUDIT */ NULL - }, - -/* FSMCNF_S_CNFING --------------------------------------------------- */ - { - /* FSMCNF_E_SETUP */ NULL, - /* FSMCNF_E_SETUP_ACK */ NULL, - /* FSMCNF_E_PROCEEDING */ NULL, - /* FSMCNF_E_ALERTING */ NULL, - /* FSMCNF_E_CONNECTED */ NULL, - /* FSMCNF_E_CONNECTED_ACK */ NULL, - /* FSMCNF_E_RELEASE */ fsmcnf_ev_cnfing_release, - /* FSMCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMCNF_E_FEATURE */ fsmcnf_ev_cnfing_feature, - /* FSMCNF_E_FEATURE_ACK */ NULL, - /* FSMCNF_E_OFFHOOK */ NULL, - /* FSMCNF_E_ONHOOK */ fsmcnf_ev_cnfing_onhook, - /* FSMCNF_E_LINE */ NULL, - /* FSMCNF_E_DIGIT_BEGIN */ NULL, - /* FSMCNF_E_DIGIT */ NULL, - /* FSMCNF_E_DIALSTRING */ NULL, - /* FSMCNF_E_MWI */ NULL, - /* FSMCNF_E_SESSION_AUDIT */ NULL - }, - -/* FSMCNF_S_CNFED ---------------------------------------------------- */ - { - /* FSMCNF_E_SETUP */ NULL, - /* FSMCNF_E_SETUP_ACK */ NULL, - /* FSMCNF_E_PROCEEDING */ NULL, - /* FSMCNF_E_ALERTING */ NULL, - /* FSMCNF_E_CONNECTED */ NULL, - /* FSMCNF_E_CONNECTED_ACK */ NULL, - /* FSMCNF_E_RELEASE */ fsmcnf_ev_cnfed_release, - /* FSMCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMCNF_E_FEATURE */ fsmcnf_ev_cnfed_feature, - /* FSMCNF_E_FEATURE_ACK */ fsmcnf_ev_cnfed_feature_ack, - /* FSMCNF_E_OFFHOOK */ NULL, - /* FSMCNF_E_ONHOOK */ fsmcnf_ev_cnfed_onhook, - /* FSMCNF_E_LINE */ NULL, - /* FSMCNF_E_DIGIT_BEGIN */ NULL, - /* FSMCNF_E_DIGIT */ NULL, - /* FSMCNF_E_DIALSTRING */ NULL, - /* FSMCNF_E_MWI */ NULL, - /* FSMCNF_E_SESSION_AUDIT */ NULL - } -}; - -static sm_table_t fsmcnf_sm_table; -sm_table_t *pfsmcnf_sm_table = &fsmcnf_sm_table; - - -const char * -fsmcnf_state_name (int state) -{ - if ((state <= FSMCNF_S_MIN) || (state >= FSMCNF_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmcnf_state_names[state]); -} - - -static int -fsmcnf_get_new_cnf_id (void) -{ - static int cnf_id = 0; - - if (++cnf_id < 0) { - cnf_id = 1; - } - - return (cnf_id); -} - - -static void -fsmcnf_init_ccb (fsmcnf_ccb_t *ccb) -{ - if (ccb != NULL) { - ccb->cnf_id = FSM_NO_ID; - ccb->cnf_call_id = CC_NO_CALL_ID; - ccb->cns_call_id = CC_NO_CALL_ID; - ccb->cnf_line = CC_NO_LINE; - ccb->cns_line = CC_NO_LINE; - ccb->bridged = FALSE; - ccb->active = FALSE; - ccb->flags = 0; - ccb->cnf_ftr_ack = FALSE; - } -} - - -static fsmcnf_ccb_t * -fsmcnf_get_ccb_by_cnf_id (int cnf_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - if (ccb->cnf_id == cnf_id) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -/* - * Function: fsmcnf_get_new_cnf_context - * - * Parameters: - * cnf_call_id: call_id for the call initiating the conference - * - * Description: This function creates a new conference context by: - * - getting a free ccb - * - creating new cnf_id and cns_call_id - * - * Returns: ccb - * - */ -static fsmcnf_ccb_t * -fsmcnf_get_new_cnf_context (callid_t cnf_call_id) -{ - static const char fname[] = "fsmcnf_get_new_cnf_context"; - fsmcnf_ccb_t *ccb; - - ccb = fsmcnf_get_ccb_by_cnf_id(FSM_NO_ID); - if (ccb != NULL) { - ccb->cnf_id = fsmcnf_get_new_cnf_id(); - ccb->cnf_call_id = cnf_call_id; - ccb->cns_call_id = cc_get_new_call_id(); - - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } else { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get new ccb.", fname); - } - - return (ccb); -} - - -fsmcnf_ccb_t * -fsmcnf_get_ccb_by_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - if ((ccb->cnf_call_id == call_id) || (ccb->cns_call_id == call_id)) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -static void -fsmcnf_update_cnf_context (fsmcnf_ccb_t *ccb, callid_t old_call_id, - callid_t new_call_id) -{ - static const char fname[] = "fsmcnf_update_cnf_context"; - - if (ccb != NULL) { - if (old_call_id == ccb->cnf_call_id) { - ccb->cnf_call_id = new_call_id; - } else if (old_call_id == ccb->cns_call_id) { - ccb->cns_call_id = new_call_id; - } - - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } -} - - -callid_t -fsmcnf_get_other_call_id (fsmcnf_ccb_t *ccb, callid_t call_id) -{ - callid_t other_call_id = CC_NO_CALL_ID; - - if (ccb != NULL) { - if (ccb->cnf_call_id == call_id) { - other_call_id = ccb->cns_call_id; - } else if (ccb->cns_call_id == call_id) { - other_call_id = ccb->cnf_call_id; - } - } - - return (other_call_id); -} - -static void -fsmcnf_cnf_xfer (fsmcnf_ccb_t *ccb) -{ - fsmdef_dcb_t *dcb; - cc_feature_data_t ftr_data; - - dcb = fsm_get_dcb(ccb->cnf_call_id); - - /* - * Pretending attended transfer - */ - ftr_data.xfer.cause = CC_CAUSE_XFER_CNF; - ftr_data.xfer.target_call_id = ccb->cns_call_id; - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_XFER, &(ftr_data)); -} - - -/* - * Function: fsmcnf_remove_fcb - * - * Parameters: - * cnf_id: cnf_id for the conference - * call_id: call_id that identifies the fcb to be removed - * - * Description: This function will remove the fcb identified by the given - * call_id from the ccb. And the function will free the ccb - * if both fcbs have been removed. - * - * Returns: none - * - * Note: This is a helper function for fsmcnf_cleanup. It allows fsmcnf_cleanup - * to cleanup one fcb (one call involved in the conference) independent - * of the other involved fcb. - */ -static void -fsmcnf_remove_fcb (fsm_fcb_t *fcb, callid_t call_id) -{ - fsmcnf_ccb_t *ccb = fcb->ccb; - - if (ccb != NULL) { - fsmcnf_update_cnf_context(ccb, call_id, CC_NO_CALL_ID); - - /* - * Free the ccb if both fcb references have been removed. - */ - if ((ccb->cnf_call_id == CC_NO_CALL_ID) && - (ccb->cns_call_id == CC_NO_CALL_ID)) { - fsmcnf_init_ccb(ccb); - } - } -} - - -static void -fsmcnf_cleanup (fsm_fcb_t *fcb, int fname, boolean both) -{ - fsmcnf_ccb_t *ccb; - fsm_fcb_t *other_fcb, *fcb_def; - callid_t call_id = fcb->call_id; - callid_t other_call_id = CC_NO_CALL_ID; - - /* stop the channel mixing if we are currently doing it */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, call_id); - /* Set session to be primary */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - if (fcb->ccb && (call_id == fcb->ccb->cnf_call_id)) { - - if (other_call_id != CC_NO_CALL_ID) { - /* - * Not clearing consulation call, so change consultation - * call attribute to display connected softkey set. - * Do not change softkey set if it is a transfer o - */ - if (ccb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get CCB.", __FUNCTION__); - } else { - cc_call_attribute(other_call_id, ccb->cnf_line, NORMAL_CALL); - } - } - - } - - if (fcb_def && fcb_def->dcb) { - fcb_def->dcb->session = PRIMARY; - } - /* - * Check if the user wanted to cleanup the whole ccb. - * If so, then we will grab the other fcb first and call this function - * again with this other fcb. The whole ccb will be freed after this block - * of code because both call_ids will be -1, which tells - * fsmcnf_remove_fcb to free the ccb. - */ - if (both) { - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, call_id); - if (other_call_id != CC_NO_CALL_ID) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - if (other_fcb != NULL) { - fsmcnf_cleanup(other_fcb, fname, FALSE); - } - } - } - - /* - * Remove the reference to this fcb from the ccb. - */ - fsmcnf_remove_fcb(fcb, fcb->call_id); - - /* - * Move this fcb to the IDLE state - */ - fsm_change_state(fcb, fname, FSMCNF_S_IDLE); - - /* - * Reset the data for this fcb. The fcb is still included in a call - * so set the call_id and dcb values accordingly. - */ - fsm_init_fcb(fcb, fcb->call_id, fcb->dcb, FSM_TYPE_CNF); -} - - -void -fsmcnf_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_CNF); - - if (fcb != NULL) { - fsmcnf_cleanup(fcb, __LINE__, FALSE); - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } -} - - -/** - * - * Cancel conference feature by sending cancel event to SIP stack. - * This routine is used in roundtable phone. - * - * Copied and pasted from fsmb2bcnf_feature_cancel(). - * See also fsmxfr_feature_cancel(). - * - * @param line, call_id, target_call_id, cause (implicit or explicit) - * - * @return void - * - * @pre (none) - */ -void -fsmcnf_feature_cancel (fsmcnf_ccb_t *ccb, line_t line, callid_t call_id, - callid_t target_call_id) -{ - cc_feature_data_t data; - fsm_fcb_t *fcb_def; - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - // 'cause' will always be CC_SK_EVT_TYPE_EXPLI for now since it's only - // called by fsmcnf_ev_cnfing_feature in the case of CC_FEAURE_CANCEL. - // Thus 'cause' is ignored (for now) until the whole SM is refactored. - if (/*(cause == CC_SK_EVT_TYPE_EXPLI) && */ - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - fcb_def = fsm_get_fcb_by_call_id_and_type(target_call_id, FSM_TYPE_DEF); - - if (/* (cause == CC_SK_EVT_TYPE_EXPLI) && */ - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, target_call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - data.cancel.target_call_id = target_call_id; - data.cancel.call_id = call_id; - data.cancel.cause = CC_SK_EVT_TYPE_EXPLI; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, CC_FEATURE_CANCEL, &data); -} - -/******************************************************************* - * event functions - */ - - -static sm_rcs_t -fsmcnf_ev_idle_setup (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - callid_t call_id = msg->call_id; - fsmcnf_ccb_t *ccb; - - if (!msg->replaces) { - return (SM_RC_DEF_CONT); - } - - /* - * Check to see if this new setup call is a new call that replaces - * one of the conferenced call i.e. the this new call replacing the - * existing leg of a conferenced by XFER feature from SIP. The - * call id of this setup should match call id of a conference. - */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb == NULL) { - return (SM_RC_DEF_CONT); - } - - /* This new call is part of a conference */ - fcb->ccb = ccb; /* attach ccb to the new call chain */ - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFING); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmcnf_ev_idle_feature (sm_event_t *event) -{ - static const char *fname = "fsmcnf_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - fsmdef_dcb_t *dcb = fcb->dcb; - callid_t cns_call_id; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb; - int free_lines; - cc_feature_data_t data; - cc_action_data_t action_data; - fsmdef_dcb_t *other_dcb; - fsm_fcb_t *other_fcb; - fsm_fcb_t *fcb_def, *join_fcb_cnf; - cc_feature_data_t ftr_data = msg->data; - cc_feature_data_t *feat_data = &(msg->data); - fsm_fcb_t *cns_fcb; - callid_t other_call_id; - fsmxfr_xcb_t *xcb; - cc_causes_t cause; - - memset(&data, 0, sizeof(cc_feature_data_t)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_CONF: - - /* Connect the existing call to active conference state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - if (feat_data && msg->data_valid && - (feat_data->cnf.target_call_id != CC_NO_CALL_ID) - && (cns_fcb = fsm_get_fcb_by_call_id_and_type(feat_data->cnf.target_call_id, - FSM_TYPE_CNF)) != NULL) { - /* - * Get a new ccb and new b2bcnf id - This is the handle that will - * identify the b2bcnf. - */ - ccb = fsmcnf_get_new_cnf_context(feat_data->cnf.target_call_id); - - if (ccb == NULL || ccb->cnf_id == FSM_NO_ID) { - return(SM_RC_END); - } - - ccb->cns_call_id = call_id; - fcb->ccb = ccb; - cns_fcb->ccb = ccb; - ccb->cnf_line = line; - ccb->cns_line = line; - - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFING); - - fsm_change_state(cns_fcb, __LINE__, FSMCNF_S_CNFING); - - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, ccb->cns_call_id, - cns_fcb->dcb->line, CC_FEATURE_CONF, NULL); - return(SM_RC_END); - - } - - /* - * This call is the conference and we are initiating a local - * conference. So: - * 1. Make sure we have a free line to open a new call plane to - * collect digits (and place call) for the consultation call, - * 2. Create a new conference context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check for any other active features which may block - * the conference. - */ - - /* - * The call must be in the connected state to initiate a conference. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && (fcb_def->state != FSMDEF_S_CONNECTED)) { - break; - } - - /* - * Make sure we have a free line to start the consultation call. - */ - //CSCsz38962 don't use expline for local conf call - //free_lines = lsm_get_instances_available_cnt(line, TRUE); - free_lines = lsm_get_instances_available_cnt(line, FALSE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this request. - */ - fsm_display_no_free_lines(); - - break; - } - - /* - * Get a new ccb and new cnf id - This is the handle that will - * identify the cnf. - */ - ccb = fsmcnf_get_new_cnf_context(call_id); - if (ccb == NULL || ccb->cnf_id == 0) { - break; - } - fcb->ccb = ccb; - ccb->cnf_line = line; - ccb->cns_line = line; - - /* - * This call needs to go on hold so we can start the consultation - * call. Indicate feature indication should be send by setting - * call info type to hold and feature reason to conference. - */ - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = CC_REASON_CONF; - data.hold.msg_body.num_parts = 0; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - - /* - * Initiate the consultation call. - */ - data.newcall.cause = CC_CAUSE_CONF; - cns_call_id = ccb->cns_call_id; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, line, - CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_CNF_INITIATED), - ccb->cnf_id, call_id, cns_call_id, __LINE__); - - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFING); - - sm_rc = SM_RC_END; - - break; - - case CC_FEATURE_JOIN: - /* - * The call must be in the connected state to initiate a conference - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && (fcb_def->state != FSMDEF_S_CONNECTED)) { - break; - } - - /* - * Make sure that we have another active call on this line. - */ - other_dcb = fsmdef_get_other_dcb_by_line(call_id, dcb->line); - if (other_dcb == NULL) { - break; - } - - /* get other calls FCB */ - other_fcb = fsm_get_fcb_by_call_id_and_type(other_dcb->call_id, - FSM_TYPE_DEF); - if (other_fcb == NULL) { - break; - } - - if (other_fcb->state == FSMDEF_S_HOLDING) { - /* - * Get a new ccb and new cnf id - This is the handle that will - * identify the cnf. - */ - ccb = fsmcnf_get_new_cnf_context(call_id); - if (ccb == NULL) { - break; - } - fcb->ccb = ccb; - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_dcb->call_id, - FSM_TYPE_CNF); - if (other_fcb == NULL) { - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - } - other_fcb->ccb = ccb; - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFED); - - ccb->cnf_call_id = dcb->call_id; - ccb->cns_call_id = other_dcb->call_id; - ccb->bridged = TRUE; - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - sm_rc = SM_RC_END; - break; - } - data.resume.cause = CC_CAUSE_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_dcb->call_id, - other_dcb->line, CC_FEATURE_RESUME, &data); - - /* - * Update the UI for this call. - */ - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - (void)cc_call_action(other_dcb->call_id, other_dcb->line, - CC_ACTION_UPDATE_UI, &action_data); - } else { - fsm_display_feature_unavailable(); - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_NEW_CALL: - - /* - * If this is the consultation call involved in a conference, - * then set the rest of the data required to make the conference - * happen. The data is the cnf_id in the fcb. The data is set now - * because we did not have the fcb when the conference was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a conference event is received. - * - * Or this could be the call that originated the conference and - * the person he was talking to (the conference target) has - * decided to conference the trasnferor to another party. - */ - - /* - * Ignore this event if this call is not involved in a conference. - */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb == NULL) { - break; - } - fcb->ccb = ccb; - - /* - * Determine what state this cnf should be in (cnfing or cnfed). - * If the cnfrn key has only been hit once, then this call will - * be in the cnfing state. If it has been hit the second time, - * then this call should go to the cnfed state. The latter - * case only happens when the calls are conferenced and one - * of the remote ends has decided to transfer one leg of the cnf. - * And it just so happens that the other call involved in the cnf - * should match this call, so we can just use it's state to - * assign the state to this call. - */ - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - - if(other_fcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get FCB.", fname); - } else { - fsm_change_state(fcb, __LINE__, other_fcb->state); - } - - break; - - case CC_FEATURE_JOIN: - if (fsm_is_joining_call(ftr_data)) { - /* - * The join target call must be in the - * connected state to initiate a conference. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, - FSM_TYPE_DEF); - if ((fcb_def == NULL) || - ((fcb_def->state != FSMDEF_S_CONNECTED) && - (fcb_def->state != FSMDEF_S_RESUME_PENDING))) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Join target \ - call is not at connected state\n", - DEB_L_C_F_PREFIX_ARGS(FSM, line, call_id, fname)); - break; - } - - /* Get the joining call fcb */ - join_fcb_cnf = fsm_get_fcb_by_call_id_and_type( - ftr_data.newcall.join.join_call_id, - FSM_TYPE_CNF); - - /* Create a conference context for the join target call */ - ccb = fsmcnf_get_new_cnf_context(call_id); - if (ccb == NULL || join_fcb_cnf == NULL) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Could not \ - find the conference context\n", - DEB_L_C_F_PREFIX_ARGS(FSM, line, call_id, fname)); - break; - } - - fcb->ccb = ccb; - join_fcb_cnf->ccb = ccb; - ccb->cnf_call_id = fcb_def->dcb->call_id; - /* Joining call is the consultative call of the conference */ - ccb->cns_call_id = join_fcb_cnf->dcb->call_id; - - join_fcb_cnf->dcb->group_id = fcb_def->dcb->group_id; - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - fsm_change_state(join_fcb_cnf, __LINE__, FSMCNF_S_CNFED); - - softkey_mask_list[0] = skConfrn; - ui_select_feature_key_set(line, call_id, - FSMCNF_CONNECTED_SET, - softkey_mask_list, 1); - - ccb->flags |= JOINED; - - ccb->bridged = FALSE; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_NOTIFY: - if ((msg->data_valid == TRUE) && - (msg->data.notify.subscription == CC_SUBSCRIPTIONS_XFER) && - (msg->data.notify.method == CC_XFER_METHOD_REFER)) { - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb != NULL) && (call_id == xcb->cns_call_id)) { - /* - * One leg of the conference has decided to transfer us. - * We need to - * 1. remove the transferred call from the conference - * context and associate the new call - * with the context, - * 2. cleanup this transferred fcb. - */ - ccb = fsmcnf_get_ccb_by_call_id(xcb->xfr_call_id); - if (ccb == NULL) { - break; - } - - other_fcb = - fsm_get_fcb_by_call_id_and_type(xcb->xfr_call_id, - FSM_TYPE_CNF); - if (other_fcb == NULL) { - break; - } - - fcb->ccb = ccb; - - fsmcnf_update_cnf_context(ccb, xcb->xfr_call_id, - xcb->cns_call_id); - - fsmcnf_cleanup(other_fcb, __LINE__, FALSE); - - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - - fsm_change_state(fcb, __LINE__, other_fcb->state); - - if (other_fcb->state == FSMCNF_S_CNFED) { - ccb->bridged = TRUE; - - /* - * Resume the other leg of the conference that was - * not transferred. - */ - other_dcb = fsm_get_dcb(other_call_id); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - fsmcnf_cleanup(fcb, __LINE__, TRUE); - sm_rc = SM_RC_END; - break; - } - data.resume.cause = CC_CAUSE_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - other_dcb->call_id, other_dcb->line, - CC_FEATURE_RESUME, &data); - } - - /* - * Update the UI for the just transferred leg. - */ - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - (void)cc_call_action(fcb->call_id, dcb->line, - CC_ACTION_UPDATE_UI, &action_data); - } - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static void -fsmcnf_update_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - callid_t other_call_id; - cc_action_data_t action_data; - fsm_fcb_t *other_fcb; - - /* - * Update the UI for the other call. - */ - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, fcb->call_id); - if (other_call_id != CC_NO_CALL_ID) { - action_data.update_ui.action = CC_UPDATE_CONF_RELEASE; - (void)cc_call_action(other_call_id, fcb->dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - - /* Far end released its original call. Set the attribute of - * other call so it can display connected softkey set. - * - * Check only for the consultation leg since only that leg - * will need its attribute reset - the other leg does not - * have an atribute set. - */ - if (fcb->ccb && (fcb->call_id == fcb->ccb->cnf_call_id)) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - if (other_fcb != NULL) { - fsm_fcb_t *b2bcnf_fcb, *xfr_fcb; - b2bcnf_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - if ((b2bcnf_fcb != NULL && b2bcnf_fcb->b2bccb == NULL) && - (xfr_fcb != NULL && xfr_fcb->xcb == NULL)) { - cc_call_attribute(other_call_id, other_fcb->dcb->line, NORMAL_CALL); - } - } - } - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); -} - - -static sm_rcs_t -fsmcnf_ev_cnfing_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - callid_t call_id = msg->call_id; - fsmcnf_ccb_t *ccb = fcb->ccb; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb != NULL) { - /* - * One leg of the conference has decided to transfer us. - * We need to - * 1. remove this call from the conference context and - * associate the new (transferred) call with the context, - * 2. cleanup this fcb. - */ - fsmcnf_update_cnf_context(ccb, call_id, xcb->cns_call_id); - - fsmcnf_cleanup(fcb, __LINE__, FALSE); - - other_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_CNF); - - if (other_fcb != NULL) { - other_fcb->ccb = ccb; - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFING); - } - - return (SM_RC_CONT); - } - - fsmcnf_update_release(event); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmcnf_ev_cnfing_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->ccb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - static const char fname[] = "fsmcnf_ev_cnfing_feature"; - cc_feature_data_t *feat_data = &(msg->data); - sm_rcs_t sm_rc = SM_RC_CONT; - callid_t other_call_id; - fsmdef_dcb_t *other_dcb; - fsm_fcb_t *other_fcb; - cc_action_data_t action_data; - cc_feature_data_t data; - cc_causes_t cause; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id /*, - CC_SK_EVT_TYPE_EXPLI */); - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_ANSWER: - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - if (other_call_id == CC_NO_CALL_ID) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - return (sm_rc); - } - other_dcb = fsm_get_dcb(other_call_id); - if (other_dcb == NULL) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - return (sm_rc); - } - /* - * The answer to the a setup with replaced we have received. - * The setup with replaced is automatically answered - * by xfer state machine as UI source (simulate user pressing - * the answer key). - * - * Set the group ID to the new call so that the voice can be - * mixed with the new call. - */ - dcb->group_id = other_dcb->group_id; - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - return (sm_rc); - - default: - break; - } - /* Fall through */ - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_CONF: - /* - * This is the second conference event for a local - * attended conference with consultation. - * - * The user is attempting to complete the conference, so - * resume the other leg of the conference call. - */ - ccb->bridged = TRUE; - ccb->active = TRUE; - ccb->flags |= LCL_CNF; - - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - other_dcb = fsm_get_dcb(other_call_id); - - /* - * Since we are resuming the other leg, allocate the src_sdp - * because src_sdp was freed and set to null when this other-leg - * was put on hold. - */ - gsmsdp_update_local_sdp_media_capability(other_dcb, TRUE, FALSE); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - sm_rc = SM_RC_END; - break; - } - data.resume.cause = CC_CAUSE_CONF; - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_DEF); - if (other_fcb && other_fcb->state == FSMDEF_S_HOLDING) { - - other_dcb->session = LOCAL_CONF; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_dcb->call_id, - other_dcb->line, CC_FEATURE_RESUME, &data); - - } else { - /* Other call must be on hold */ - - dcb->session = LOCAL_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - ccb->cnf_line, CC_FEATURE_RESUME, &data); - - - } - - /* - * Update the UI for this call. - */ - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFED); - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - - sm_rc = SM_RC_END; - - break; - - case CC_FEATURE_END_CALL: - fsmcnf_update_release(event); - - break; - - case CC_FEATURE_HOLD: - if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason != CC_REASON_SWAP && - feat_data->hold.call_info.data.hold_resume_reason != CC_REASON_CONF && - feat_data->hold.call_info.data.hold_resume_reason != CC_REASON_INTERNAL)) { - sm_rc = SM_RC_END; - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(dcb->line, ccb->cnf_call_id, ccb->cns_call_id); - - fsmcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id /*, - CC_SK_EVT_TYPE_EXPLI */); - fsmcnf_cleanup(fcb, __LINE__, TRUE); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmcnf_ev_cnfing_onhook (sm_event_t *event) -{ - fsmcnf_update_release(event); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->ccb; - callid_t other_call_id; - fsmdef_dcb_t *other_dcb; - cc_feature_data_t data; - cc_action_data_t action_data; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - cc_causes_t cause; - - /* Conference is not active any more, clear that flag - */ - ccb->active = FALSE; - - if( ccb->flags & JOINED ){ - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - if(other_call_id != CC_NO_CALL_ID ){ - fsm_fcb_t *b2bcnf_fcb, *xfr_fcb; - b2bcnf_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - if ((b2bcnf_fcb != NULL && b2bcnf_fcb->b2bccb == NULL) && - (xfr_fcb != NULL && xfr_fcb->xcb == NULL)) { - cc_call_attribute(other_call_id, dcb->line, NORMAL_CALL); - } - } - } - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb != NULL) && (!(ccb->flags & JOINED))) { - /* - * One leg of the conference has decided to transfer us. - * We need to: - * 1. remove this call from the conference context and - * associate the new (transferred) call with the context, - * 2. Resume the other leg of the conference that was not transferred. - * More than likely this leg was put on hold when the transfer - * was intitated if this was a REFER transfer. - * 3. - */ - fsmcnf_update_cnf_context(ccb, call_id, xcb->cns_call_id); - - fsmcnf_cleanup(fcb, __LINE__, FALSE); - - /* NOTE: - * Normally, we would reset the ccb->bridged flag to indicate - * that the bridge is not active. We do not want to do that in - * this case because we want the conference to bridge as soon as - * the target we are transferred to answers. - */ - - ccb->bridged = TRUE; - - /* - * Resume the other leg of the conference that was not transferred. - */ - other_call_id = fsmcnf_get_other_call_id(ccb, xcb->cns_call_id); - other_dcb = fsm_get_dcb(other_call_id); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (SM_RC_END); - } - data.resume.cause = CC_CAUSE_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_dcb->call_id, - other_dcb->line, CC_FEATURE_RESUME, &data); - - /* - * Update the UI for the just transferred leg. - */ - other_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_CNF); - - if (other_fcb != NULL) { - other_fcb->ccb = ccb; - - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFED); - - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - cc_call_action(other_fcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - return (SM_RC_CONT); - } - } - - fsmcnf_update_release(event); - - return (SM_RC_CONT); -} - - -static void -fsmcnf_other_feature (fsm_fcb_t *fcb, cc_features_t ftr_id) -{ - callid_t other_call_id; - - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, fcb->call_id); - if (other_call_id != CC_NO_CALL_ID) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - fcb->dcb->line, ftr_id, NULL); - } -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb = fcb->ccb; - fsmxfr_xcb_t *xcb; - int join = 1; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_END_CALL: - if ((ccb->flags & JOINED) && (ccb->bridged == FALSE)) { - /* Something went wrong during the barge/monitor call setup, clean up */ - fsmcnf_cleanup(fcb, __LINE__, TRUE); - return (sm_rc); - } - /* - * If bridge of conference call ends the call, other 2 - * users should still be able to talk to each other. - * So we simulate attended transfer when bridge tries - * to end the call. - */ - config_get_value(CFGID_CNF_JOIN_ENABLE, &join, sizeof(join)); - if (((ccb->bridged == TRUE) && (join) && !(ccb->flags & JOINED)) || - ((ccb->bridged == TRUE) && (ccb->flags & XFER))) { - - fsmcnf_cnf_xfer(ccb); - sm_rc = SM_RC_END; - } else { - /* - * The user is attempting to clear the call, therefore - * we need to also clear the other leg of this - * conference if it is active. - */ - fsmcnf_other_feature(fcb, ftr_id); - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_HOLD: - /* Don't process the Hold if we are still waiting - * on an ack from a previous Resume. - */ - if ((ccb->cnf_ftr_ack) && (src_id == CC_SRC_UI)) { - return (SM_RC_END); - } - - /* - * The user is attempting to hold the call, therefore we need - * to also hold the other leg of this conference. Only update - * the other leg if the conference is bridged and not involved - * in a transfer. - */ - if (ccb->bridged == TRUE) { - - if ((ccb->flags & XFER) && (src_id == CC_SRC_GSM)) { - fsmcnf_cleanup(fcb, __LINE__, TRUE); - return (sm_rc); - } - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb == NULL) || (!(ccb->flags & XFER))) { - fsmcnf_other_feature(fcb, ftr_id); - ccb->cnf_ftr_ack = TRUE; - ccb->bridged = FALSE; - } - } - break; - - case CC_FEATURE_RESUME: - /* Don't process the Resume if we are still waiting - * on an ack from a previous Hold. - */ - if ((ccb->cnf_ftr_ack) && (src_id == CC_SRC_UI)) { - return (SM_RC_END); - } - - /* - * The user is attempting to resume the call, therefore we need - * to also resume the other leg of this conference. Only do this - * if the conference is not bridged. - */ - if (ccb->bridged == FALSE) { - fsmcnf_other_feature(fcb, ftr_id); - ccb->cnf_ftr_ack = TRUE; - ccb->bridged = TRUE; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALLINFO: - if ((ccb->flags & JOINED) && - (call_id == ccb->cns_call_id)) { - /* - * Call is already joined into, eat this call - * info event that came for the virtual bubble - */ - return (SM_RC_END); - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_FEATURE_XFER: - if (msg->data_valid == FALSE) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - switch (msg->data.xfer.method) { - case CC_XFER_METHOD_BYE: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_XFER_METHOD_REFER: - if ((msg->data.xfer.cause == CC_CAUSE_XFER_REMOTE) && - (msg->data.xfer.target_call_id != CC_NO_CALL_ID)) { - /* - * This operation is replacing this call leg with the - * new leg. This call is a target of a transfer. - * Replace the call id of this call with the new - * replacing call id. - */ - fsmcnf_update_cnf_context(ccb, call_id, - msg->data.xfer.target_call_id); - /* Drop this call from conferenced */ - fsmcnf_cleanup(fcb, __LINE__, FALSE); - } else { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_feature_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->ccb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc = SM_RC_CONT; - cc_feature_data_t ftr_data; - cc_causes_t cause; - char tmp_str[STATUS_LINE_MAX_LEN]; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_HOLD: - /* - * HOLD request is pending. Let this event drop through - * to the default sm for handling. - */ - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } else { - ccb->cnf_ftr_ack = FALSE; - } - break; - - case CC_FEATURE_RESUME: - /* - * Resume request is pending. Let this event drop through - * to the default sm for handling. - */ - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - ccb->cnf_ftr_ack = FALSE; - - /* - * Check the status of the cause code - */ - if (msg->cause != CC_CAUSE_NORMAL) { - if ((platGetPhraseText(STR_INDEX_CNFR_FAIL_NOCODEC, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, ccb->cns_call_id, - fcb->dcb->line, CC_FEATURE_END_CALL, NULL); - - dcb = fsmdef_get_dcb_by_call_id(ccb->cnf_call_id); - if (dcb != NULL) { - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &ftr_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (SM_RC_END); - } - ftr_data.resume.cause = CC_CAUSE_OK; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_RESUME, &ftr_data); - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb = fcb->ccb; - int join = 1; - fsmdef_dcb_t *other_dcb; - boolean conf_id_valid = FALSE; - - /* If call_id of the ONHOOK received is of cnf_call_id, - * flag to dcb of cns_call_id to know of the event, - * and vice versa. We do not want to process more than - * one onhook for calls in a conf call. Note that this is - * needed because when in Speaker mode, onhook event is - * sent to each call_id in active state. - */ - if (fcb->call_id == ccb->cnf_call_id) { - other_dcb = fsm_get_dcb(ccb->cns_call_id); - } else { - other_dcb = fsm_get_dcb(ccb->cnf_call_id); - } - other_dcb->onhook_received = TRUE; - - // CSCtc04202, when conf_id_valid is FALSE,which mean at least one call is dropped - // Need release the whole conference session. - conf_id_valid = fsmcnd_conf_call_id_valid(ccb); - config_get_value(CFGID_CNF_JOIN_ENABLE, &join, sizeof(join)); - if (((ccb->bridged == TRUE) && (join) && !(ccb->flags & JOINED) && (conf_id_valid)) || - ((ccb->bridged == TRUE) && (ccb->flags & XFER) && (conf_id_valid))) { - /* - * If bridge of conference call ends the call other 2 - * users should still be able to talk to each other - * So we simulate attended transfer when bridge tries - * to end the call - */ - fsmcnf_cnf_xfer(ccb); - sm_rc = SM_RC_END; - } else { - /* - * The user is attempting to clear the call, therefore - * we need to also clear the other leg of this - * conference if it is active. - */ - fsmcnf_other_feature(fcb, CC_FEATURE_END_CALL); - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); - return (sm_rc); -} - - -cc_int32_t -fsmcnf_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmcnf_ccb_t *ccb; - int i = 0; - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("show fsmcnf\n"); - return (0); - } - - debugif_printf("\n-------------------------- FSMCNF ccbs --------------------------"); - debugif_printf("\ni cnf_id ccb cnf_call_id cns_call_id active bridged"); - debugif_printf("\n-----------------------------------------------------------------" - "\n"); - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - debugif_printf("%-2d %-6d 0x%8p %-11d %-11d %-6d %-7d\n", - i++, ccb->cnf_id, ccb, ccb->cnf_call_id, - ccb->cns_call_id, ccb->active, ccb->bridged); - } - - return (0); -} - - -void -fsmcnf_init (void) -{ - fsmcnf_ccb_t *ccb; - static const char *fname = "fsmcnf_init"; - - - /* - * Initialize the ccbs. - */ - fsmcnf_ccbs = (fsmcnf_ccb_t *) - cpr_calloc(FSMCNF_MAX_CCBS, sizeof(fsmcnf_ccb_t)); - - if (fsmcnf_ccbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate memory for " \ - "cnf ccbs.\n", fname); - return; - } - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - fsmcnf_init_ccb(ccb); - } - - /* - * Initialize the state/event table. - */ - fsmcnf_sm_table.min_state = FSMCNF_S_MIN; - fsmcnf_sm_table.max_state = FSMCNF_S_MAX; - fsmcnf_sm_table.min_event = CC_MSG_MIN; - fsmcnf_sm_table.max_event = CC_MSG_MAX; - fsmcnf_sm_table.table = (&(fsmcnf_function_table[0][0])); -} - -int -cc_is_cnf_call (callid_t call_id) -{ - if (call_id == CC_NO_CALL_ID) { - return FALSE; - } - return fsmutil_is_cnf_leg(call_id, fsmcnf_ccbs, FSMCNF_MAX_CCBS); -} - -void -fsmcnf_shutdown (void) -{ - cpr_free(fsmcnf_ccbs); - fsmcnf_ccbs = NULL; -} - -int -fsmutil_is_cnf_consult_call (callid_t call_id) -{ - return fsmutil_is_cnf_consult_leg(call_id, fsmcnf_ccbs, FSMCNF_MAX_CCBS); -} - -boolean -fsmcnd_conf_call_id_valid(fsmcnf_ccb_t *ccb){ - - static const char fname[] = "fsmcnd_conf_call_id_valid"; - if( ccb != NULL){ - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - if((ccb->cnf_call_id != CC_NO_CALL_ID) && (ccb->cns_call_id != CC_NO_CALL_ID) ){ - return TRUE; - } - } - return FALSE; -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c b/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c deleted file mode 100755 index ae196ea2dad..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c +++ /dev/null @@ -1,8672 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "CCProvider.h" -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_rand.h" -#include "cpr_timers.h" -#include "cpr_errno.h" -#include "phone.h" -#include "lsm.h" -#include "fsm.h" -#include "sm.h" -#include "ccapi.h" -#include "ccsip_cc.h" -#include "phone_debug.h" -#include "fim.h" -#include "config.h" -#include "sdp.h" -#include "ccsip_sdp.h" // Temporary include -#include "rtp_defs.h" -#include "debug.h" -#include "gsm_sdp.h" -#include "vcm.h" -#include "uiapi.h" -#include "gsm.h" -#include "phntask.h" -#include "prot_configmgr.h" -#include "sip_interface_regmgr.h" -#include "dialplanint.h" -#include "subapi.h" -#include "text_strings.h" -#include "platform_api.h" -#include "peer_connection_types.h" -#include "prlog.h" -#include "prprf.h" -#include "sessionHash.h" - -extern void update_kpmlconfig(int kpmlVal); -extern boolean g_disable_mass_reg_debug_print; -void escalateDeescalate(); - -#define FSMDEF_NO_NUMBER (NULL) -#define DIGIT_POUND ('#') -#define FSMDEF_MAX_DCBS (LSM_MAX_CALLS) -#define FSMDEF_CC_CALLER_ID ((cc_state_data_t *)(&(dcb->caller_id))) -#define RINGBACK_DELAY 90 - -// Minimum and maximum hold reversion timer in seconds -#define MIN_HOLD_REVERSION_INTERVAL_TIMER 10 -#define MAX_HOLD_REVERSION_INTERVAL_TIMER 1200 - -fsmdef_dcb_t *fsmdef_dcbs; - -static const char *fsmdef_state_names[] = { - "IDLE", - - /* SIP states */ - "COLLECTING_INFO", - "CALL_SENT", - "OUTGOING_PROCEEDING", - "KPML_COLLECTING_INFO", - "OUTGOING_ALERTING", - "INCOMING_ALERTING", - "CONNECTING", - "JOINING", - "CONNECTED", - "CONNECTED MEDIA PEND", - "RELEASING", - "HOLD_PENDING", - "HOLDING", - "RESUME_PENDING", - "PRESERVED", - - /* WebRTC States */ - "STABLE", - "HAVE_LOCAL_OFFER", - "HAVE_REMOTE_OFFER", - "HAVE_REMOTE_PRANSWER", - "HAVE_LOCAL_PRANSWER", - "CLOSED" -}; - - -static sm_rcs_t fsmdef_ev_default_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_setup(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_dialstring(sm_event_t *event); -static sm_rcs_t fsmdef_ev_onhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_collectinginfo_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_collectinginfo_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_digit_begin(sm_event_t *event); -static sm_rcs_t fsmdef_ev_dialstring(sm_event_t *event); -static sm_rcs_t fsmdef_ev_proceeding(sm_event_t *event); -static sm_rcs_t fsmdef_ev_callsent_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_callsent_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_out_alerting(sm_event_t *event); -static sm_rcs_t fsmdef_ev_inalerting_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_inalerting_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_handle_inalerting_offhook_answer(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_line(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connecting_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_media_pend_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_media_pend_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_release_complete(sm_event_t *event); -static sm_rcs_t fsmdef_ev_releasing_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_releasing_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_releasing_onhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_hold_pending_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_hold_pending_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_onhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_session_audit(sm_event_t *event); -static sm_rcs_t fsmdef_ev_resume_pending_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_resume_pending_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_preserved_feature(sm_event_t *event); -static void fsmdef_ev_join(cc_feature_data_t *data); - -static sm_rcs_t fsmdef_cfwd_clear_ccm(fsm_fcb_t *fcb); -static sm_rcs_t fsmdef_process_dialstring_for_callfwd(sm_event_t *event); -static sm_rcs_t fsmdef_process_cfwd_softkey_event(sm_event_t *event); -static sm_rcs_t fsmdef_cfwd_clear_ccm(fsm_fcb_t *fcb); -static sm_rcs_t fsmdef_ev_joining_connected_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_joining_offhook(sm_event_t *event); - -static void fsmdef_b2bjoin_invoke(fsmdef_dcb_t *dcb, - cc_feature_data_t *join_data); -static void fsmdef_select_invoke(fsmdef_dcb_t *dcb, - cc_feature_data_t *select_data); -static void fsmdef_handle_join_pending(fsmdef_dcb_t *dcb); -static void fsmdef_append_dialstring_to_feature_uri(fsmdef_dcb_t *dcb, - const char *dialstring); -static boolean fsmdef_is_feature_uri_configured(cc_features_t ftr_id); -static void fsmdef_set_call_info_cc_call_state(fsmdef_dcb_t *dcb, - cc_states_t state, - cc_causes_t cause); -static boolean fsmdef_extract_join_target(sm_event_t *event); -static void fsmdef_ev_notify_feature(cc_feature_t *msg, fsmdef_dcb_t *dcb); -static void fsmdef_notify_hook_event(fsm_fcb_t *fcb, cc_msgs_t msg, - char *global_call_id, - callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode); -static void fsmdef_update_callinfo_security_status(fsmdef_dcb_t *dcb, - cc_feature_data_call_info_t *call_info); -static void fsmdef_update_calltype (fsm_fcb_t *fcb, cc_feature_t *msg); - -static sm_function_t fsmdef_function_table[FSMDEF_S_MAX][CC_MSG_MAX] = -{ -/* FSMDEF_S_IDLE ------------------------------------------------------------ */ - { - /* CC_MSG_SETUP */ fsmdef_ev_idle_setup, // New incoming - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ NULL, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete, - /* CC_MSG_FEATURE */ fsmdef_ev_idle_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_idle_offhook, - /* CC_MSG_ONHOOK */ NULL, - /* CC_MSG_LINE */ fsmdef_ev_idle_offhook, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ fsmdef_ev_idle_dialstring, // new outgoing - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_COLLECT_INFO ---------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_collectinginfo_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_collectinginfo_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_digit_begin, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ fsmdef_ev_dialstring, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_CALL_SENT ------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ fsmdef_ev_proceeding, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_OUTGOING_PROCEEDING --------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_KPML_COLLECT_INFO ----------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_collectinginfo_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_digit_begin, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_OUTGOING_ALERTING ----------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_INCOMING_ALERTING ----------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_inalerting_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_inalerting_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_inalerting_offhook, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_CONNECTING ------------------------------------------------------ */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_connected_ack, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_connecting_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_JOINING --------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_joining_connected_ack, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_connecting_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_joining_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_CONNECTED ------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_connected_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_CONNECTED_MEDIA_PEND ------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_connected_media_pend_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_connected_media_pend_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_RELEASING ------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_releasing_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete, - /* CC_MSG_FEATURE */ fsmdef_ev_releasing_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_releasing_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_HOLD_PENDING ---------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_holding_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_hold_pending_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_hold_pending_feature_ack, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_HOLDING --------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_holding_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_holding_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_holding_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_holding_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_holding_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_RESUME_PENDING -------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_resume_pending_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_resume_pending_feature_ack, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - -/* FSMDEF_S_PRESERVED ------------------------------------------------------ */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ fsmdef_ev_preserved_feature, - /* CC_MSG_FEATURE_ACK */ NULL, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit - }, - - -/* FSMDEF_S_STABLE --------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ NULL, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ NULL, - /* CC_MSG_FEATURE_ACK */ NULL, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ NULL - }, - -/* FSMDEF_S_HAVE_LOCAL_OFFER ----------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ NULL, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ NULL, - /* CC_MSG_FEATURE_ACK */ NULL, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ NULL - }, - -/* FSMDEF_S_HAVE_REMOTE_OFFER ---------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ NULL, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ NULL, - /* CC_MSG_FEATURE_ACK */ NULL, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ NULL - }, - -/* FSMDEF_S_HAVE_LOCAL_PRANSWER -------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ NULL, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ NULL, - /* CC_MSG_FEATURE_ACK */ NULL, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ NULL - }, - -/* FSMDEF_S_HAVE_REMOTE_PRANSWER ------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ NULL, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ NULL, - /* CC_MSG_FEATURE_ACK */ NULL, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ NULL - }, - -/* FSMDEF_S_CLOSED --------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ NULL, - /* CC_MSG_SETUP_ACK */ NULL, - /* CC_MSG_PROCEEDING */ NULL, - /* CC_MSG_ALERTING */ NULL, - /* CC_MSG_CONNECTED */ NULL, - /* CC_MSG_CONNECTED_ACK */ NULL, - /* CC_MSG_RELEASE */ NULL, - /* CC_MSG_RELEASE_COMPLETE */ NULL, - /* CC_MSG_FEATURE */ NULL, - /* CC_MSG_FEATURE_ACK */ NULL, - /* CC_MSG_OFFHOOK */ NULL, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ NULL, - /* CC_MSG_DIGIT_BEGIN */ NULL, - /* CC_MSG_DIGIT_END */ NULL, - /* CC_MSG_DIALSTRING */ NULL, - /* CC_MSG_MWI */ NULL, - /* CC_MSG_SESSION_AUDIT */ NULL - } -}; - -static sm_table_t fsmdef_sm_table; -sm_table_t *pfsmdef_sm_table = &fsmdef_sm_table; - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ -uint16_t g_numofselected_calls = 0; -boolean g_b2bjoin_pending = FALSE; -callid_t g_b2bjoin_callid = CC_NO_CALL_ID; - -static sdp_direction_e s_default_video_dir = SDP_DIRECTION_SENDRECV; -static sdp_direction_e s_session_video_dir = SDP_MAX_QOS_DIRECTIONS; - - -void set_default_video_pref(int pref) { - s_default_video_dir = pref; -} - -void set_next_sess_video_pref(int pref) { - s_session_video_dir = pref; -} - -const char * -fsmdef_state_name (int state) -{ - if ((state <= FSMDEF_S_MIN) || (state >= FSMDEF_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmdef_state_names[state]); -} - -/* - * fsmdef_get_dcb_by_call_id - * - * return the dcb referenced by the given call_id - */ -fsmdef_dcb_t * -fsmdef_get_dcb_by_call_id (callid_t call_id) -{ - static const char fname[] = "fsmdef_get_dcb_by_call_id"; - fsmdef_dcb_t *dcb; - fsmdef_dcb_t *dcb_found = NULL; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id == call_id) { - dcb_found = dcb; - break; - } - } - - if (dcb_found) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_PTR), - dcb->call_id, dcb->line, fname, dcb_found); - } - - return (dcb_found); -} - - -/* - * fsmdef_check_if_chaperone_call_exist - * - * return the dcb referenced by the given call_id - */ -boolean -fsmdef_check_if_chaperone_call_exist (void) -{ - static const char fname[] = "fsmdef_check_if_chaperone_call_exist"; - fsmdef_dcb_t *dcb; - boolean result = FALSE; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if(dcb->policy == CC_POLICY_CHAPERONE){ - result = TRUE; - break; - } - } - - if (result) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_PTR), - dcb->call_id, dcb->line, fname, dcb); - } - - return result; -} - - -void fsmdef_get_rtp_stat (fsmdef_dcb_t *dcb , cc_kfact_t *kfactor) -{ - static const char fname[] ="fsmdef_get_rtp_stat"; - - int call_stats_flag; - fsmdef_media_t *media; - media = gsmsdp_find_audio_media(dcb); - - if (!media) { - GSM_ERR_MSG(GSM_F_PREFIX"dcb media pointer invalid", fname); - return; - } - - memset(kfactor, 0, sizeof(cc_kfact_t)); - config_get_value(CFGID_CALL_STATS, &call_stats_flag, sizeof(call_stats_flag)); - - if (call_stats_flag) { - vcmGetRtpStats(media->cap_index, dcb->group_id, - media->refid, - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), &(kfactor->rxstats[0]), &(kfactor->txstats[0])); - } -} - -/** - * The function sets or clears the local hold status to the given media or - * for all of the media. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * @param[in]media - specify which media to use. The value of - * NULL indicates for all media. - * @param[in]set - set local hold or clear local hold. - * - * @return none - * - * @pre (dcb not_eq NULL) - */ -static void -fsmdef_update_media_hold_status (fsmdef_dcb_t *dcb, fsmdef_media_t *media, - boolean set) -{ - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (GSMSDP_MEDIA_ENABLED(media)) { - if (set) { - FSM_SET_FLAGS(media->hold, FSM_HOLD_LCL); - } else { - FSM_RESET_FLAGS(media->hold, FSM_HOLD_LCL); - } - } - } -} - -/** - * The function checks to see whether all media streams are - * in locally held or not. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * - * @return TRUE - all media streams are in local hold. - * FALSE - not all media streams are in local hold. - * - * @pre (dcb not_eq NULL) - */ -static boolean -fsmdef_all_media_are_local_hold (fsmdef_dcb_t *dcb) -{ - fsmdef_media_t *media; - /* - * Check the local hold status of each media to see if the - * media is already locally held or not. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - if (!FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - /* found one media that is not on hold */ - return (FALSE); - } - } - /* all media streams are local held */ - return (TRUE); -} - -/** - * The function gets the numbmer of media in local hold. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * - * @return uint16_t for the number of media in local hold. - * - * @pre (dcb not_eq NULL) - */ -static unsigned int -fsmdef_num_media_in_local_hold (fsmdef_dcb_t *dcb) -{ - fsmdef_media_t *media; - unsigned int num_local_hold = 0; - - /* Check the local hold status of the media(s) */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - if (FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - num_local_hold++; - } - } - return (num_local_hold); -} - -/** - * The function is a convenient function to set each local hold in - * SDP for each media if it is marked as locally held. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * - * @return None - * - * @pre (dcb not_eq NULL) - */ -static void -fsmdef_set_per_media_local_hold_sdp (fsmdef_dcb_t *dcb) -{ - fsmdef_media_t *media; - - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - if (FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - /* set local hold to this media entry */ - gsmsdp_set_local_hold_sdp(dcb, media); - } - } -} - -/** - * This function deallocates an options structure - * - * @param[in]options - pointer to cc_media_options_t - * @return None - */ -void -fsmdef_free_options(cc_media_options_t *options) { - if (!options) { - return; - } - cpr_free(options); -} - -void -fsmdef_init_dcb (fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type, - string_t called_number, line_t line, fsm_fcb_t *fcb) -{ - string_t calling_name; - int blocking; - char name[MAX_LINE_NAME_SIZE]; - - dcb->call_id = call_id; - dcb->line = line; - - dcb->spoof_ringout_requested = FALSE; - dcb->spoof_ringout_applied = FALSE; - - dcb->log_disp = CC_CALL_LOG_DISP_UNKNWN; - - fsmutil_init_groupid(dcb, call_id, call_type); - - /* - * Fill in as much of the caller_id data as possible. - * Different data is available based on the call_type. - */ - switch (call_type) { - case FSMDEF_CALL_TYPE_OUTGOING: - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - if (line != 0) { - sip_config_get_display_name(line, name, sizeof(name)); - } - if (blocking & 1 || line == 0) { - calling_name = SIP_HEADER_ANONYMOUS_STR; - } else { - calling_name = name; - } - dcb->caller_id.calling_name = strlib_update(dcb->caller_id.calling_name, - calling_name); - dcb->caller_id.calling_number = - strlib_update(dcb->caller_id.calling_number, name); - - /* - * called_xxx data will be set when the fsmdef receives the dialstring. - */ - dcb->caller_id.called_name = strlib_empty(); - dcb->caller_id.called_number = strlib_empty(); - dcb->caller_id.orig_rpid_number = strlib_empty(); - - dcb->inbound = FALSE; - - break; - - case FSMDEF_CALL_TYPE_INCOMING: - case FSMDEF_CALL_TYPE_FORWARD: - /* - * calling_xxx data will be set when the fsmdef receives the setup. - */ - dcb->caller_id.calling_name = strlib_empty(); - dcb->caller_id.calling_number = strlib_empty(); - - dcb->caller_id.last_redirect_name = strlib_empty(); - dcb->caller_id.last_redirect_number = strlib_empty(); - dcb->caller_id.orig_called_name = strlib_empty(); - dcb->caller_id.orig_called_number = strlib_empty(); - dcb->caller_id.orig_rpid_number = strlib_empty(); - - sip_config_get_display_name(line, name, sizeof(name)); - dcb->caller_id.called_name = - strlib_update(dcb->caller_id.called_name, name); - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, called_number); - - dcb->inbound = TRUE; - - break; - - case FSMDEF_CALL_TYPE_NONE: - dcb->caller_id.calling_name = strlib_empty(); - dcb->caller_id.calling_number = strlib_empty(); - dcb->caller_id.called_name = strlib_empty(); - dcb->caller_id.called_number = strlib_empty(); - dcb->caller_id.alt_calling_number = strlib_empty(); - dcb->caller_id.last_redirect_name = strlib_empty(); - dcb->caller_id.last_redirect_number = strlib_empty(); - dcb->caller_id.orig_called_name = strlib_empty(); - dcb->caller_id.orig_called_number = strlib_empty(); - dcb->caller_id.orig_rpid_number = strlib_empty(); - dcb->inbound = FALSE; - - break; - default: - break; - } /* switch (call_type) { */ - - dcb->caller_id.display_calling_number = TRUE; - dcb->caller_id.display_called_number = TRUE; - - /* Initially, assume ui update is required for a new call. */ - dcb->ui_update_required = TRUE; - dcb->placed_call_update_required = TRUE; - - dcb->is_conf_call = FALSE; /*Initially, set to conf call false*/ - - dcb->digit_cnt = 0; - - dcb->call_type = call_type; - dcb->orientation = CC_ORIENTATION_NONE; - - dcb->caller_id.call_instance_id = 0; - - dcb->msgs_sent = FSMDEF_MSG_NONE; - dcb->msgs_rcvd = FSMDEF_MSG_NONE; - - dcb->send_release = FALSE; - - dcb->inband = FALSE; - dcb->inband_received = FALSE; - dcb->outofband = 0; - - dcb->remote_sdp_present = FALSE; - dcb->remote_sdp_in_ack = FALSE; - dcb->local_sdp_complete = FALSE; - - dcb->sdp = NULL; - dcb->src_sdp_version = 0; - - dcb->dial_mode = DIAL_MODE_NUMERIC; - - dcb->hold_reason = CC_REASON_NONE; - - dcb->pd_updated = FALSE; - - dcb->alerting_tone = VCM_NO_TONE; - dcb->tone_direction = VCM_PLAY_TONE_TO_EAR; - - dcb->alert_info = ALERTING_NONE; - - dcb->dialplan_tone = FALSE; - - dcb->active_tone = VCM_NO_TONE; - - dcb->monrec_tone_action = FSMDEF_MRTONE_NO_ACTION; - dcb->monitor_tone_direction = VCM_PLAY_TONE_TO_EAR; - dcb->recorder_tone_direction = VCM_PLAY_TONE_TO_EAR; - - dcb->play_tone_action = FSMDEF_PLAYTONE_NO_ACTION; - - dcb->fcb = fcb; - - dcb->early_error_release = FALSE; - - dcb->active_feature = CC_FEATURE_NONE; - - FSM_SET_SECURITY_STATUS(dcb, CC_SECURITY_UNKNOWN); - FSM_SET_POLICY(dcb, CC_POLICY_UNKNOWN); - dcb->session = PRIMARY; - - dcb->dsp_out_of_resources = FALSE; - - if (dcb->selected) { - g_numofselected_calls--; - } - - dcb->selected = FALSE; - - dcb->select_pending = FALSE; - dcb->call_not_counted_in_mnc_bt = FALSE; - if (g_disable_mass_reg_debug_print == FALSE) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"call_not_counted_in_mnc_bt = FALSE", - DEB_L_C_F_PREFIX_ARGS(FSM, line, call_id, "fsmdef_init_dcb")); - } - - /* clear all bit flags */ - dcb->flags = 0; - dcb->onhook_received = FALSE; - - dcb->cur_video_avail = SDP_DIRECTION_INACTIVE; - - if ( s_session_video_dir != SDP_MAX_QOS_DIRECTIONS && - call_type == FSMDEF_CALL_TYPE_OUTGOING ) { - dcb->video_pref = s_session_video_dir; - s_session_video_dir = SDP_MAX_QOS_DIRECTIONS; - } else { - dcb->video_pref = s_default_video_dir; - } - - gsmsdp_init_media_list(dcb); - - dcb->join_call_id = CC_NO_CALL_ID; - dcb->callref = 0; - - dcb->ice_ufrag = NULL; - dcb->ice_pwd = NULL; - dcb->peer_ice_lite = FALSE; - dcb->ice_default_candidate_addr[0] = '\0'; - - dcb->digest_alg[0] = '\0'; - dcb->digest[0] = '\0'; -} - - -static void -fsmdef_free_dcb (fsmdef_dcb_t *dcb) -{ - if (dcb == NULL) { - return; - } - - strlib_free(dcb->caller_id.calling_name); - strlib_free(dcb->caller_id.calling_number); - strlib_free(dcb->caller_id.alt_calling_number); - strlib_free(dcb->caller_id.called_name); - strlib_free(dcb->caller_id.called_number); - - strlib_free(dcb->caller_id.last_redirect_name); - strlib_free(dcb->caller_id.last_redirect_number); - strlib_free(dcb->caller_id.orig_called_name); - strlib_free(dcb->caller_id.orig_called_number); - strlib_free(dcb->caller_id.orig_rpid_number); - - if (dcb->ice_ufrag) - cpr_free(dcb->ice_ufrag); - - if (dcb->ice_pwd) - cpr_free(dcb->ice_pwd); - - // Free the call instance id - if (dcb->caller_id.call_instance_id != 0) { - fsmutil_free_ci_id(dcb->caller_id.call_instance_id, dcb->line); - } - - /* clean media list */ - gsmsdp_clean_media_list(dcb); - - gsmsdp_free(dcb); - - fsmdef_init_dcb(dcb, CC_NO_CALL_ID, FSMDEF_CALL_TYPE_NONE, NULL, - LSM_NO_LINE, NULL); - - /* - * Cache random numbers for SRTP keys - */ - gsmsdp_cache_crypto_keys(); - -} - -void -fsmdef_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - fsmdef_dcb_t *dcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb != NULL) { - fcb = dcb->fcb; - fsmdef_init_dcb(dcb, CC_NO_CALL_ID, FSMDEF_CALL_TYPE_NONE, - NULL, LSM_NO_LINE, NULL); - /* fsmdef_init_dcb(...,NULL) will always set the fcb ptr to NULL, - so if fsmdef_free_cb were called on that we'd have fcb==NULL here */ - if (fcb != NULL) { - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } else { - - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if (fcb != NULL) { - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } - } -} - - -/* - * ROUTINE: fsmdef_get_new_dcb - * - * DESCRIPTION: return a new dcb initialized with the given data - * - * PARAMETERS: - * call_id: call_id - * - * RETURNS: - * dcb: the new dcb - * - * NOTES: None - */ -fsmdef_dcb_t * -fsmdef_get_new_dcb (callid_t call_id) -{ - static const char fname[] = "fsmdef_get_new_dcb"; - fsmdef_dcb_t *dcb = NULL; - - /* - * Get a free dcb. - */ - if ((dcb = fsmdef_get_dcb_by_call_id(CC_NO_CALL_ID)) == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), call_id, 0, fname, - "no dcbs available"); - - return (NULL); - } - - dcb->call_id = call_id; - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_PTR), - dcb->call_id, dcb->line, fname, dcb); - - return (dcb); -} - - -/** - * - * Returns dcb related to connected call. - * - * @param none - * - * @return dcb of connected call. - * - * @pre none - */ - -fsmdef_dcb_t * -fsmdef_get_connected_call (void) -{ - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != CC_NO_CALL_ID) { - fcb = dcb->fcb; - if ((fcb != NULL) && (fcb->state == FSMDEF_S_RESUME_PENDING || - fcb->state == FSMDEF_S_CONNECTED || - fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND)) { - - return (dcb); - } - } - } - - return (NULL); -} - -/** - * - * Returns dcb related to alerting out call. - * - * @param none - * - * @return dcb of outgoing alerting call. - * - * @pre none - */ -static fsmdef_dcb_t * -fsmdef_get_alertingout_call (void) -{ - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != CC_NO_CALL_ID) { - fcb = dcb->fcb; - if ((fcb != NULL) && (fcb->state == FSMDEF_S_OUTGOING_ALERTING)) { - return (dcb); - } - } - } - - return (NULL); -} - -/* - * fsmdef_get_active_call_cnt - * - * Return the count of active calls aside from the - * callid passed in. - */ -int -fsmdef_get_active_call_cnt (callid_t callId) -{ - fsmdef_dcb_t *dcb; - int cnt = 0; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && (dcb->call_id != callId)) { - cnt++; - } - } - - return (cnt); -} - - -/* - * return the dcbs and count of calls that are ringing and - * are in error state not including the given call_id - * - * @param pointer to dcbs array - * @param call_id that should be ignored from search - * - * @return int number of ringing or error state calls - * - * @pre none -*/ -static int -fsmdef_get_ringing_n_error_call_dcbs (fsmdef_dcb_t **dcbs, callid_t ignore_call_id) -{ - fsmdef_dcb_t *dcb; - int cnt = 0; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->spoof_ringout_applied || - ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->call_id != ignore_call_id) && - (dcb->fcb && ((dcb->fcb->state <= FSMDEF_S_CONNECTING) || - (dcb->fcb->state == FSMDEF_S_RELEASING))))) { - dcbs[cnt++] = dcb; - } - } - - return (cnt); -} - - -int -fsmdef_get_dcbs_in_held_state (fsmdef_dcb_t **dcbs, callid_t ignore_call_id) -{ - fsmdef_dcb_t *dcb; - int cnt = 0; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->call_id != ignore_call_id) && - (dcb->fcb && (dcb->fcb->state == FSMDEF_S_HOLDING || - dcb->fcb->state == FSMDEF_S_HOLD_PENDING))) { - dcbs[cnt++] = dcb; - } - } - - return (cnt); -} - -void fsmdef_call_cc_state_dialing (fsmdef_dcb_t *dcb, boolean suppress) -{ - cc_state_data_dialing_t data; - - if ( dcb->caller_id.called_number[0] == '\0' ) { - data.play_dt = TRUE; - } else { - data.play_dt = FALSE; - } - - data.suppress_stutter = suppress; - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_DIALING, - (cc_state_data_t *)(&data)); -} - -/* - * fsmdef_get_other_dcb_by_line - * - * return the dcb of the call that is active on a given line, - * not including the given call_id - */ -fsmdef_dcb_t * -fsmdef_get_other_dcb_by_line (callid_t call_id, line_t line) -{ - fsmdef_dcb_t *dcb; - fsmdef_dcb_t *dcb_found = NULL; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->line == line) && (dcb->call_id != call_id)) { - dcb_found = dcb; - } - } - - return (dcb_found); -} - -/* - * fsmdef_are_there_selected_calls_onotherline - * - * @param line - line number - * - * loop thru the dcbs and check if there are selected calls - * on a line other than this one - * - * @return TRUE, there are - * FALSE there are not - */ -boolean fsmdef_are_there_selected_calls_onotherline (line_t line) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->selected) { - if (dcb->line != line) { - return (TRUE); - } - } - } - return (FALSE); -} - -/* - * fsmdef_are_join_calls_on_same_line - * - * @param line - line number - * - * loop thru the dcbs and check if the line passed is the - * same as where the initial join started - * - * @return TRUE, they are on the same line - * FALSE not on the same line - */ -boolean fsmdef_are_join_calls_on_same_line (line_t line) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id == g_b2bjoin_callid) { - if (dcb->line != line) { - return (FALSE); - } else { - return (TRUE); - } - } - } - return (FALSE); -} - -/** - * - * Handles media capability update feature event from platform when - * media stream capability changes. - * - * @param[in]msg - pointer to the cc_feature_t. - * - * @return None. - * - * @pre (msg not_eq NULL) - */ -void -fsmdef_update_media_cap_feature_event (cc_feature_t *msg) -{ - static const char fname[] = "fsmdef_update_media_cap_feature_event"; - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"", DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, msg->call_id, fname)); - - /* - * Find the connected call to send the media capability update - * event to. There can be more than one call chains in - * connected state for an example, a call that participates in - * local conference, barged, monitored. All calls that - * are active are sent the update event. Each call leg will handle - * the event. - * - */ - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != CC_NO_CALL_ID) { - fcb = dcb->fcb; - if ((fcb != NULL) && (fcb->state == FSMDEF_S_RESUME_PENDING || - fcb->state == FSMDEF_S_CONNECTED)) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_UPD_MEDIA_CAP, NULL); - - } - } - } -} - -/** - * - * Function to find and hold any connected call. - * - * @param call_id call id of the call - * @param wait flag to indicate if the caller has to wait ton invoke the event - * @param src_id source id of the caller where to post hold or endcall event. - * - * @return none - * - * @pre (wait == FALSE) - */ - -static void -fsmdef_find_and_hold_connected_call (callid_t call_id, boolean *wait, - cc_srcs_t src_id) -{ - fsmdef_dcb_t *con_dcb; - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *con_ccb; - fsmxfr_xcb_t *xcb; - cc_feature_data_t data; - callid_t other_call_id; - callid_t other_call_id2; - - *wait = FALSE; - - /* - * Place the connected call, if there is one, on hold, - * but there are some restrictions to ignore the hold request: - * 1. the connected call must be different than the one requesting the hold, - * 2. the connected call is involved with this call in a conference and - * the conference is active. - * NOTE: for case 2, why do we not send a hold for each of the calls - * involved in the conference? Because, the fsmcnf will generate the - * second hold for the other leg of the conference when it receives - * this hold. - * 3. the connected call is in a conference with another call that is - * involved with a transfer. This is the case when two calls are in a - * conference and a bridge decides to transfer one leg of the bridge - * using REFER. I.E., cnf between A-B and A-C. B initiates transfer to D. - * B holds A-B, sends REFER to A, A holds A-B, initiates A-D, D answers, - * A hangs up A-B and connects conference. So, when A initiates A-D, - * we do not want to hold the active bridge between A-C. - */ - con_dcb = fsmdef_get_connected_call(); - if ((con_dcb != NULL) && ((con_dcb->call_id != call_id) || - (con_dcb->spoof_ringout_applied == FALSE))) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - con_ccb = fsmcnf_get_ccb_by_call_id(con_dcb->call_id); - - - if ((ccb == NULL) || (con_ccb == NULL) || - ((ccb == con_ccb) && (ccb->active != TRUE)) || (ccb != con_ccb)) { - other_call_id = fsmcnf_get_other_call_id(con_ccb, con_dcb->call_id); - xcb = fsmxfr_get_xcb_by_call_id(other_call_id); - - other_call_id2 = fsmxfr_get_other_call_id(xcb, other_call_id); - - if (call_id != other_call_id2) { - *wait = TRUE; - - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = - CC_REASON_INTERNAL; - data.hold.msg_body.num_parts = 0; - data.hold.call_info.data.call_info_feat_data.swap = FALSE; - data.hold.call_info.data.call_info_feat_data.protect = FALSE; - cc_int_feature(src_id, CC_SRC_GSM, con_dcb->call_id, - con_dcb->line, CC_FEATURE_HOLD, &data); - } - } - } -} - -/* - * Function post a event to end the call which are in ringing - * reorder or busy and connecting state. This would indicate call function to - * wait on the existing event. - * - * @param call_id that should be ignored from search - * @param pointer to boolean to indicate if the caller has to wait - * - * @return none - * - * @pre none -*/ -static void -fsmdef_find_and_handle_ring_connecting_releasing_calls (callid_t call_id, boolean *wait) -{ - int i; - int act_dcb_cnt; - fsmdef_dcb_t *act_dcb; - fsmdef_dcb_t *act_dcbs[LSM_MAX_CALLS]; - cc_feature_data_t data; - - *wait = FALSE; - - data.endcall.cause = CC_CAUSE_NORMAL; - data.endcall.dialstring[0] = '\0'; - - act_dcb_cnt = fsmdef_get_ringing_n_error_call_dcbs(act_dcbs, call_id); - for (i = 0; i < act_dcb_cnt; i++) { - act_dcb = act_dcbs[i]; - /* - * Clear all the outgoing ringing lines (if there are any). - */ - if (act_dcb->call_type == FSMDEF_CALL_TYPE_OUTGOING || - act_dcb->spoof_ringout_applied) { - *wait = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, act_dcb->call_id, - act_dcb->line, CC_FEATURE_END_CALL, &data); - - } - else if (act_dcb->fcb->state == FSMDEF_S_CONNECTING) { - /* If the call is in connecting state, then wait till SIP - * response to get the call in connected state. - * The call can be put on hold only when call is connected. - */ - *wait = TRUE; - } - } -} - -void -fsmdef_end_call (fsmdef_dcb_t *dcb, cc_causes_t cause) -{ - cc_feature_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - data.endcall.cause = cause; - data.endcall.dialstring[0] = '\0'; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); -} - -/* - * fsmdef_clear_preserved_calls - * - * Release any calls in the preserved state - */ -static void -fsmdef_clear_preserved_calls (boolean *wait) -{ - fsmdef_dcb_t *dcb; - - *wait = FALSE; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->fcb->state == FSMDEF_S_PRESERVED)) { - *wait = TRUE; - fsmdef_end_call(dcb, CC_CAUSE_NORMAL); - } - } -} - -/** - * - * Checks to see if actions are required for existing calls before the new - * call can be activated. - * - * 1. Place the currently active connected call on hold. - * 2. Clear any ringing calls. - * 3. Release any call in the preserved state. - * - * @param is_newcall To indicate if this is a new call - * @param src_id source of the caller - * @param call_id call-id - * @param line line number - * @param feature feature which is waiting on hodling call. - * @param feature data - * - * @return TRUE if actions require delay before the new call may begin - * FALSE if no actions are required an the new call may begin - * - * @pre (wait, wait2, wait3 all FALSE) - */ -static boolean -fsmdef_wait_to_start_new_call (boolean is_newcall, cc_srcs_t src_id, callid_t call_id, - line_t line, cc_features_t feature, - cc_feature_data_t *data) -{ - boolean wait = FALSE; - boolean wait2 = FALSE; - boolean wait3 = FALSE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsmdef_find_and_hold_connected_call(call_id, &wait, src_id); - - fsmdef_find_and_handle_ring_connecting_releasing_calls(call_id, &wait2); - - fsmdef_clear_preserved_calls(&wait3); - - /* - * Requeue the message because we need to wait for call actions to complete - */ - if ((wait) || (wait2) || (wait3)) { - cc_int_feature(src_id, CC_SRC_GSM, call_id, line, feature, data); - } - - return (wait | wait2 | wait3); -} - -static cc_causes_t -fsmdef_get_cause (boolean data_valid, cc_feature_data_t *data) -{ - cc_causes_t cause; - - if (data_valid) { - cause = data->endcall.cause; - } else { - cause = CC_CAUSE_NORMAL; - } - - return (cause); -} - - -/** - * common function to release a call given cause code - * i.e onhooks the given call. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * @param[in] cause release cause code. - * - * @param[in] send_release When set to TRUE the function sends release - * and waits for release complete. - * When set to FALSE the function cleans up - * dcb and release fcb. - * - * @pre (fcb not_eq NULL) - * - * @return sm_rcs_t indicates whether the execution of - * next statmachine to end (SM_RC_END) or clean up - * (SM_RC_CLEANUP) - * - * @Usage Note: The function uses send_release flag to - * as an indicator for sending release out or not. - * If release is sent, the function transitions fsmdef's - * state to FSMDEF_S_RELEASING and - * return the SM_RC_END to waite for release complete. - * - * Otherwise, it cleans up dcb and releases fcb and - * return SM_RC_CLEANUP to the caller. - * - * If the SM_RC_CLEANUP is returned, the caller should - * terminate any access or perform any operation - * afterward. - */ -sm_rcs_t -fsmdef_release (fsm_fcb_t *fcb, cc_causes_t cause, boolean send_release) -{ - fsmdef_dcb_t *dcb = fcb->dcb; - cc_state_data_t state_data; - cc_kfact_t kfactor; - fsmdef_media_t *media; - char tmp_str[STATUS_LINE_MAX_LEN]; - int sdpmode = 0; - - if (!dcb) { - /* Already been released */ - return SM_RC_CLEANUP; - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Entered. cause= %s", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, __FUNCTION__), cc_cause_name(cause)); - - if (g_dock_undock_event != MEDIA_INTERFACE_UPDATE_NOT_REQUIRED) { - ui_update_media_interface_change(dcb->line, dcb->call_id, MEDIA_INTERFACE_UPDATE_FAIL); - } - memset(&kfactor, 0, sizeof(cc_kfact_t)); - - /* - * Let Dialog Manager know that there is ONHOOK event - */ - fsmdef_notify_hook_event(fcb, CC_MSG_ONHOOK, NULL, CC_NO_CALL_ID, - CC_REASON_NONE, CC_MONITOR_NONE,CFWDALL_NONE); - - media = gsmsdp_find_audio_media(dcb); - if ((media) && (media->direction != SDP_DIRECTION_INACTIVE)) { - fsmdef_get_rtp_stat(dcb, &kfactor); - } - - if ( cause == CC_SIP_CAUSE_ANSWERED_ELSEWHERE ) { - ui_log_disposition(dcb->call_id, CC_CALL_LOG_DISP_IGNORE ); - } - - if ( cause == CC_CAUSE_RESP_TIMEOUT) { - if ((platGetPhraseText(STR_INDEX_RESP_TIMEOUT, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - lsm_ui_display_status(tmp_str, dcb->line, dcb->call_id); - } - } - - if (send_release) { - cc_int_release(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - cause, NULL, &kfactor); - /* - * Wait around for the release_complete. - */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_RELEASING); - - /* - * Only move the UI if we changed the UI's state when the call was - * received. - */ - if ((dcb->line != LSM_NO_LINE) || (cause != CC_CAUSE_BUSY)) { - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = FALSE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, - &state_data); - } - return (SM_RC_END); - } else { - /* - * Only move the UI if we changed the UI's state when the call was - * initiated. - */ - if ((dcb->line != LSM_NO_LINE) || (cause != CC_CAUSE_BUSY)) { - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = FALSE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, - &state_data); - } - - /* - * Only send a release complete to the remote end if they are waiting - * for it. This is the case when we have sent a proceeding or we - * have received a release. - */ - if (FSM_CHK_FLAGS(dcb->msgs_sent, FSMDEF_MSG_PROCEEDING) || - FSM_CHK_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE)) { - cc_int_release_complete(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, cause, &kfactor); - } - - // TODO: Get rid of this setting when we simplify teardown - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - fsm_change_state(fcb, __LINE__, - sdpmode ? FSMDEF_S_CLOSED : FSMDEF_S_IDLE); - - fsmdef_free_dcb(dcb); - fsm_release(fcb, __LINE__, cause); - /* - * fsmdef has been released, indiate cleanup FSM chain. - */ - return (SM_RC_CLEANUP); - } -} - -/* - * fsmdef_convert_esc_plus - * - * replaces an escaped "+" (%2B) with a real "+" - */ -static void -fsmdef_convert_esc_plus (const char *src_number) -{ - int i, len; - char *number; - - len = strlen(src_number) - 2; - number = (char *) src_number; - number[0] = '+'; - for (i = 1; i < len; i++) { - number[i] = number[i + 2]; - } - number[i] = '\0'; -} - -static boolean -fsmdef_compare_caller_id_string (string_t dest, string_t src) -{ - if ((dest == NULL) && (src == NULL)) { - /* - * Strings are same. - */ - return (FALSE); - } - - if ((dest == NULL) || (src == NULL)) { - /* - * Strings differ. - */ - return (TRUE); - } - - if (strncmp(dest, src, FSMDEF_MAX_CALLER_ID_LEN) != 0) { - /* - * Strings differ. - */ - return (TRUE); - } - - /* - * Strings are same. - */ - return (FALSE); -} - -static boolean -fsmdef_compare_caller_id (cc_caller_id_t *dest_caller_id, - cc_caller_id_t *src_caller_id) -{ - if (fsmdef_compare_caller_id_string(dest_caller_id->calling_name, - src_caller_id->calling_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->calling_number, - src_caller_id->calling_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->called_name, - src_caller_id->called_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->called_number, - src_caller_id->called_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->orig_called_name, - src_caller_id->orig_called_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->orig_called_number, - src_caller_id->orig_called_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->last_redirect_name, - src_caller_id->last_redirect_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->last_redirect_number, - src_caller_id->last_redirect_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->orig_rpid_number, - src_caller_id->orig_rpid_number)) { - return (TRUE); - } - - if (dest_caller_id->display_calling_number != src_caller_id->display_calling_number || - dest_caller_id->display_called_number != src_caller_id->display_called_number || - dest_caller_id->call_type != src_caller_id->call_type || - dest_caller_id->call_instance_id != src_caller_id->call_instance_id) { - return (TRUE); - } - - return (FALSE); -} - -static void -fsmdef_mv_caller_id (fsmdef_dcb_t *dcb, cc_caller_id_t *caller_id) -{ - /* - * Move the caller ID from the source to the storage in dcb if there - * is a change in what is already stored in the dcb. - */ - if (fsmdef_compare_caller_id(&dcb->caller_id, caller_id)) { - cc_mv_caller_id(&dcb->caller_id, caller_id); - dcb->ui_update_required = TRUE; - } -} - -static void -fsmdef_update_callinfo (fsm_fcb_t *fcb, cc_feature_t *msg) -{ - static const char fname[] = "fsmdef_update_callinfo"; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t *feat_data = &(msg->data); - cc_action_data_t action_data; - cc_caller_id_t *caller_id; - - if (msg->data_valid == FALSE) { - /* No data to use for update. Just ignore the event. */ - return; - } - - if ((feat_data->call_info.feature_flag & CC_UI_STATE) && - (feat_data->call_info.ui_state == CC_UI_STATE_RINGOUT)) { - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, - "setting spoof_ringout_requested"); - - dcb->spoof_ringout_requested = TRUE; - } else { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_RQSTD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_requested = FALSE; - } - - caller_id = &feat_data->call_info.caller_id; - - if (feat_data->call_info.feature_flag & CC_CALLER_ID) { - fsmdef_mv_caller_id(dcb, caller_id); - } - - /* - * If CCM provides a call instance id and it does not match - * the current call instance id, free the current call instance - * id and set the call instance id to the newly provided value. - */ - if (feat_data->call_info.feature_flag & CC_CALL_INSTANCE && - feat_data->call_info.caller_id.call_instance_id != dcb->caller_id.call_instance_id) { - if (dcb->caller_id.call_instance_id != 0) { - fsmutil_free_ci_id(dcb->caller_id.call_instance_id, dcb->line); - } - dcb->caller_id.call_instance_id = - feat_data->call_info.caller_id.call_instance_id; - fsmutil_set_ci_id(dcb->caller_id.call_instance_id, dcb->line); - dcb->ui_update_required = TRUE; - } - - /* - * Update security status - */ - fsmdef_update_callinfo_security_status(dcb, &feat_data->call_info); - - /* - * Update call policy - */ - if (feat_data->call_info.feature_flag & CC_POLICY) { - if (dcb->policy != feat_data->call_info.policy) { - dcb->policy = feat_data->call_info.policy; - dcb->ui_update_required = TRUE; - } - } - - /* - * Save orientation so that UI call update can be done at - * any time that UI needs to be updated. - */ - if (feat_data->call_info.feature_flag & CC_ORIENTATION) { - if (dcb->orientation != feat_data->call_info.orientation) { - dcb->orientation = feat_data->call_info.orientation; - dcb->ui_update_required = TRUE; - } - } - - /* - * This call info. event may be as part of media effecting - * signaling event (such as INVITE, re-INVITE, 180 etc.) - * which will be followed by actual media effected event. It is - * indicated by SIP stack to improve media cutting through as soonest. - * If SIP indicates that UI can be delayed then do not update call - * information now. The UI will be updated as part of media - * manipulation event that will follow. - * (Note: call info event is sent separately from the SIP signaling - * event currently and it is sent before SIP signaling event). - */ - if (feat_data->call_info.feature_flag & CC_DELAY_UI_UPDATE) { - /* Delay UI update */ - } else { - /* - * Only perform a UI update if something changed. - */ - if (dcb->ui_update_required == TRUE - || dcb->spoof_ringout_requested == TRUE) { - - action_data.update_ui.action = CC_UPDATE_CALLER_INFO; - action_data.update_ui.data.caller_info = feat_data->call_info; - - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, - dcb->line, fname, "UI update"); - } else { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, "No UI update"); - } - } - /* update callref */ - if ( dcb->callref == 0 ) { - dcb->callref = feat_data->call_info.callref; - ui_update_callref(dcb->line, dcb->call_id, feat_data->call_info.callref); - } - /* update gcid */ - if (feat_data->call_info.global_call_id[0] != '\0') { - ui_update_gcid(dcb->line, dcb->call_id, feat_data->call_info.global_call_id); - /* - * store the gcid lcb, this is used to prevent short ringing - * in scenarios where a call is routed to the calling phone. - */ - lsm_update_gcid(dcb->call_id, feat_data->call_info.global_call_id); - } -} - -/** - * Function: fsmdef_set_feature_timer - * - * Description: This function is called to set (start) timer for a - * given timer. The context of the timer is set so that upon - * expiration the corresponding context (dcb) can be obtained. - * - * Parameters: - * dcb - pointer to the fsmdef_dcb_t. The caller must ensure - * dcb is not NULL. - * timer - pointer to cprTimer_t. The caller must ensure that - * timer is not NULL. - * duration - the time duration for the timer to be set. - * - * Returns: - * N/A. - */ -static void -fsmdef_set_feature_timer (fsmdef_dcb_t *dcb, cprTimer_t *timer, - uint32_t duration) -{ - static const char fname[] = "fsmdef_set_feature_timer"; - -} - -static void -fsmdef_set_req_pending_timer (fsmdef_dcb_t *dcb) -{ -} - -static void -fsmdef_set_ringback_delay_timer (fsmdef_dcb_t *dcb) -{ -} - - -/******************************************************************* - * event functions - */ - -/* - * Default event handler for feature_ack event - */ -static sm_rcs_t -fsmdef_ev_default_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_default_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_features_t ftr_id = msg->feature_id; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, "fsmdef_ev_default_feature_ack")); - - if (ftr_id == CC_FEATURE_SELECT) { - /* Reeceived the response for select, so turn the flag off */ - dcb->select_pending = FALSE; - if (dcb->selected) { - dcb->selected = FALSE; - g_numofselected_calls--; - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"call is unselected and number of selected \ - calls on the phone is %d\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, msg->call_id, fname), - g_numofselected_calls); - - } else { - dcb->selected = TRUE; - if ((g_b2bjoin_pending == FALSE) && - (dcb->active_feature == CC_FEATURE_B2B_JOIN)) { - g_b2bjoin_pending = TRUE; - g_b2bjoin_callid = dcb->call_id; - } - g_numofselected_calls++; - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"call is selected and number of selected \ - calls on the phone is %d\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), - g_numofselected_calls); - } - ui_call_selected(dcb->line, lsm_get_ui_id(dcb->call_id), (dcb->selected)?CC_DIALOG_LOCKED:CC_DIALOG_UNLOCKED); - - } else if (dcb->active_feature != ftr_id) { - // check if we are getting feature_ack for the active feature - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"feature_ack rcvd for %s but %s is active", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), - cc_feature_name(ftr_id), cc_feature_name(dcb->active_feature)); - - } - - // reset active feature - dcb->active_feature = CC_FEATURE_NONE; - - return (SM_RC_END); -} - - -static void -fsmdef_sm_ignore_ftr (fsm_fcb_t *fcb, int fname, cc_features_t ftr_id) -{ - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - if (fcb->dcb) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - } -} - -static void -fsmdef_sm_ignore_src (fsm_fcb_t *fcb, int fname, cc_srcs_t src_id) -{ - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - if (fcb->dcb) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - } -} - -/* - * fsmdef_error_onhook_timeout - * - * Timer is started immediately after the call error. This function is called - * when there is a timeout event generated by the timer . - * - * @param[in] data The gsm ID (callid_t) of the call onhook timeout - * has occured. - * - * @return N/A - */ -void -fsmdef_error_onhook_timeout (void *data) -{ - static const char fname[] = "fsmdef_error_onhook_timeout"; - fsmdef_dcb_t *dcb; - callid_t call_id; - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "invalid data"); - return; - } - - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - - return; - } - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, "timeout"); - - cc_int_onhook(CC_SRC_GSM, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, - dcb->call_id, dcb->line, FALSE, FALSE, __FILE__, __LINE__); -} - -/** - * Function: fsmdef_feature_timer_timeout - * - * Description: This function is called when receives time out - * notification. The function then converts the timer event - * into the CCAPI event suitable for GSM's call state machine. - * - * Parameters: - * feature_id - corresponding feature ID of the timer event. - * data - the opaque data for the caller which is actually - * is the GSM's call id. - * - * Returns: - * NULL or - * pointer to the cc_feature_t. - */ -void * -fsmdef_feature_timer_timeout (cc_features_t feature_id, void *data) -{ - static const char fname[] = "fsmdef_feature_timer_timeout"; - cc_feature_t *pmsg; - callid_t call_id; - fsmdef_dcb_t *dcb; - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "timeout"); - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "invalid data"); - return NULL; - } - - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - /* The corresponding dcb for the call ID is not found */ - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - return (NULL); - } - - if (dcb->inband_received && feature_id == CC_FEATURE_RINGBACK_DELAY_TIMER_EXP) { - /* Double check if inbound ringback indication is received*/ - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "inband received!"); - return (NULL); - } - - pmsg = (cc_feature_t *) gsm_get_buffer(sizeof(*pmsg)); - if (!pmsg) { - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), - call_id, dcb->line, fname, - "failed to allocate feature timer message"); - return NULL; - } - - memset(pmsg, 0, sizeof(*pmsg)); - - pmsg->msg_id = CC_MSG_FEATURE; - pmsg->src_id = CC_SRC_GSM; - pmsg->call_id = call_id; - pmsg->line = dcb->line; - pmsg->feature_id = feature_id; - pmsg->data_valid = FALSE; - - return (void *) pmsg; -} - -/** - * - * Function handles idle setup request received from the network - * - * @sm_eent_t event - * - * @return SM_RC_END - * - * @pre (called_number and called_number not NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_idle_setup (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_idle_setup"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - callid_t call_id = msg->call_id; - int temp; - string_t called_number = msg->caller_id.called_number; - string_t calling_number = msg->caller_id.calling_number; - fsmdef_dcb_t *dcb; - cc_causes_t cause; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - callid_t other_call_id; - boolean alerting = TRUE; - boolean replaces = msg->replaces; - int other_active_calls; - boolean transfer_target = FALSE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Make sure we have a valid called_number. - */ - if ((called_number == NULL) || (called_number[0] == '\0')) { - return (SM_RC_CLEANUP); - } - - /* - * Check the called/calling number for the E.164 escaped "+" - * and convert it to a real "+" if present. - */ - if (cpr_strncasecmp(called_number, "%2B", 3) == 0) { - fsmdef_convert_esc_plus(called_number); - } - if (cpr_strncasecmp(calling_number, "%2B", 3) == 0) { - fsmdef_convert_esc_plus(calling_number); - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"called_number= %s calling_number= %s", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, msg->call_id, fname), - msg->caller_id.called_number, msg->caller_id.calling_number); - - //idle = lsm_is_phone_idle(); - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb && replaces) { - transfer_target = TRUE; - } - - /* - * Get a new incoming call context. - * if we the target of a transfer, request that the line - * availability be increased by one to account for the third - * instance of a line to become available to allow completion - * of transfer. - */ - cause = fsm_get_new_incoming_call_context(call_id, fcb, called_number, - transfer_target); - dcb = fcb->dcb; - if ((msg->call_info.type != CC_FEAT_MONITOR) && - (replaces != TRUE)) { - if (lsm_is_line_available(dcb->line, TRUE) == FALSE) { - /* increment it to compensate for decrementing while ending the call. */ - lsm_increment_call_chn_cnt(dcb->line); - fsmdef_end_call(dcb, CC_CAUSE_BUSY); - return (SM_RC_END); - } - lsm_increment_call_chn_cnt(dcb->line); - } - else { - /* - * join calls (barged, M & R) are not counted by CUCM. so we should not count either - */ - dcb->call_not_counted_in_mnc_bt = TRUE; - dcb->join_call_id = msg->call_info.data.join.join_call_id; - } - /* - * Set default orientation for the incoming setup as "from" to - * avoid updating UI when call info is received in "ACK" which - * shoule be "from" for typicall incoming call. - */ - dcb->orientation = CC_ORIENTATION_FROM; - - switch (cause) { - case CC_CAUSE_OK: - break; - - case CC_CAUSE_NO_RESOURCE: - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_CLEANUP); - - default: - fsmdef_end_call(dcb, cause); - return (SM_RC_END); - } - - /* - * Check for Anonymous call blocking. If low bit is set, - * then do not allow call. Note that we must allow both upper and lowercase - * ANON strings, hence the use of strcasestr - */ - config_get_value(CFGID_ANONYMOUS_CALL_BLOCK, &temp, sizeof(temp)); - if (temp & 1) { - /* - * We compare the calling name to the hardcoded Anonymous string we use in - * our SIP headers. This handles the case where calling name was pulled from - * the From header and was set to Anonymous. We also compare the calling name - * to the localized string index for Private which is what the calling name will - * be set to if an RPID header was received. - */ - char tmp_str[STATUS_LINE_MAX_LEN]; - sstrncpy(tmp_str, platform_get_phrase_index_str(UI_PRIVATE), sizeof(tmp_str)); - if (strcasestr(msg->caller_id.calling_name, SIP_HEADER_ANONYMOUS_STR) || - strcasestr(msg->caller_id.calling_name, tmp_str)) { - fsmdef_end_call(dcb, CC_CAUSE_ANONYMOUS); - return (SM_RC_END); - } - } - - /* - * Check if Call Waiting is disabled. - * If call-waiting is disabled and there is another call active - * then the GSM will return busy. - * unless this is a barge/monitor target call - * - */ - config_get_line_value(CFGID_LINE_CALL_WAITING, &temp, sizeof(temp), - dcb->line); - other_active_calls = fsmdef_get_active_call_cnt(call_id); - - if ((msg->call_info.type != CC_FEAT_MONITOR)) { - if ((!(temp & 1)) && (other_active_calls > 0) && - (!((xcb != NULL) && (xcb->mode == FSMXFR_MODE_TARGET)))) { - - fsmdef_end_call(dcb, CC_CAUSE_BUSY); - - return (SM_RC_END); - } - } - - /* - * If this is a call to replace another call, - * check that we have a call to replace - */ - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - if (replaces) { - if ((xcb == NULL) || (other_call_id == CC_NO_CALL_ID)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, "", - "No call to replace"); - - fsmdef_end_call(dcb, CC_CAUSE_NO_REPLACE_CALL); - return (SM_RC_END); - } - } - - - /* - * The called name and number will not be obtained from - * the setup. Remove it before getting from the setup message. - */ - if (msg->caller_id.called_name != NULL) { - strlib_free(msg->caller_id.called_name); - msg->caller_id.called_name = NULL; - } - if (msg->caller_id.called_number != NULL) { - strlib_free(msg->caller_id.called_number); - msg->caller_id.called_number = NULL; - } - /* Get the caller ID from the setup message */ - fsmdef_mv_caller_id(dcb, &msg->caller_id); - - if (msg->caller_id.call_type == CC_CALL_FORWARDED) { - - dcb->call_type = FSMDEF_CALL_TYPE_FORWARD; - } - - /* - * If a call instance id is provided, use it in the dcb. We will - * check to see that the call instance id provided differs from - * what is currently stored in the dcb before assigning it. - */ - if (msg->call_info.type == CC_FEAT_CALLINFO) { - cc_feature_data_call_info_t *data; - - data = &msg->call_info.data.call_info_feat_data; - if (data->feature_flag & CC_CALL_INSTANCE) { - if (data->caller_id.call_instance_id != 0 && - data->caller_id.call_instance_id != - dcb->caller_id.call_instance_id) { - if (dcb->caller_id.call_instance_id != 0) { - fsmutil_free_ci_id(dcb->caller_id.call_instance_id, - dcb->line); - } - dcb->caller_id.call_instance_id = - data->caller_id.call_instance_id; - fsmutil_set_ci_id(dcb->caller_id.call_instance_id, dcb->line); - } - } - - if (data->feature_flag & CC_SECURITY) { - FSM_SET_SECURITY_STATUS(dcb, data->security); - } - - if (data->feature_flag & CC_POLICY) { - FSM_SET_POLICY(dcb, data->policy); - } - } - dcb->alert_info = msg->alert_info; - dcb->alerting_ring = msg->alerting_ring; - dcb->alerting_tone = msg->alerting_tone; - - /* - * This is an incoming call, so we know we will need to send a - * RELEASE when we clear the call. - */ - dcb->send_release = TRUE; - - cause = gsmsdp_negotiate_offer_sdp(fcb, &msg->msg_body, TRUE); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - if (transfer_target) { - /* - * Send a proceeding event to the transfer call. - * - * The proceeding event will end the other call - * and answer the current call. - * - */ - cc_int_proceeding(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, &(dcb->caller_id)); - } - - cc_int_setup_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_SETUP_ACK); - - - - cc_int_proceeding(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id)); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_PROCEEDING); - - - alerting = fsmdef_extract_join_target(event); - - /* - * This might be the transfer call from the transferee to the target. - * In such a case we want this new call to match the state of the call - * that it is replacing. - */ - if (xcb != NULL) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_DEF); - if (other_fcb && (other_fcb->old_state == FSMDEF_S_CONNECTED || - other_fcb->old_state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->old_state == FSMDEF_S_RESUME_PENDING || - other_fcb->state == FSMDEF_S_CONNECTED || - other_fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->state == FSMDEF_S_RESUME_PENDING)) { - alerting = FALSE; - } - } - - - if (alerting == TRUE) { - /* - * set the call priority in lcb. This is used by ringer logic. - */ - if ((msg->call_info.type == CC_FEAT_CALLINFO) && - (msg->call_info.data.call_info_feat_data.priority == CC_CALL_PRIORITY_URGENT)) { - lsm_set_lcb_call_priority(call_id); - } - if ((msg->call_info.type == CC_FEAT_CALLINFO) && - (msg->call_info.data.call_info_feat_data.dusting == TRUE)) { - lsm_set_lcb_dusting_call(call_id); - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ALERTING, - FSMDEF_CC_CALLER_ID); - /* - * Currently we do not send SDP in the 180 response. - */ - cc_int_alerting(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL, FALSE); - - /* update callref */ - if ( dcb->callref == 0 ) { - dcb->callref = msg->call_info.data.call_info_feat_data.callref; - ui_update_callref(dcb->line, dcb->call_id, msg->call_info.data.call_info_feat_data.callref); - } - /* update gcid */ - ui_update_gcid(dcb->line, dcb->call_id, msg->call_info.data.call_info_feat_data.global_call_id); - /* - * store the gcid lcb, this is used to prevent short ringing - * in scenarios where a call is routed to the calling phone. - */ - lsm_update_gcid(dcb->call_id, msg->call_info.data.call_info_feat_data.global_call_id); - } - - ui_cc_capability(dcb->line, lsm_get_ui_id(dcb->call_id), msg->recv_info_list); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_ALERTING); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_INCOMING_ALERTING); - - return (SM_RC_END); -} - - -sm_rcs_t -fsmdef_dialstring (fsm_fcb_t *fcb, const char *dialstring, - cc_redirect_t *redirect, boolean replace, - cc_call_info_t *call_info) -{ - static const char fname[] = "fsmdef_dialstring"; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dialstring) { - if (strlen(dialstring) > MAX_SIP_URL_LENGTH) { - FSM_DEBUG_SM(DEB_F_PREFIX"Dial string too long", DEB_F_PREFIX_ARGS(FSM, fname)); - /* Force clean up call without sending release */ - return (fsmdef_release(fcb, CC_CAUSE_INVALID_NUMBER, FALSE)); - } - } - - /* - * If there is active feature which is waiting for digit collection - * then use service URI preceded with dialed number. - */ - switch (dcb->active_feature) { - - case CC_FEATURE_CFWD_ALL: - fsmdef_append_dialstring_to_feature_uri(dcb, dialstring); - break; - - default: - if (dialstring) { - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, dialstring); - } - break; - } - - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - /* Force clean up call without sending release */ - return (fsmdef_release(fcb, cause, FALSE)); - } - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - /* Force clean up call without sending release */ - return (fsmdef_release(fcb, cause, FALSE)); - } - - /* - * Since we are sending setup to UI we will also have to send - * release to it to for sip stack to clean up the call - */ - dcb->send_release = TRUE; - - /* - * lsm_parse_displaystr will free present called number and return - * pointer to parsed called number - */ - dcb->caller_id.called_number = - lsm_parse_displaystr(dcb->caller_id.called_number); - - /* set default orientation for outgoing call */ - dcb->orientation = CC_ORIENTATION_TO; - dcb->inbound = FALSE; - - /* - * Invoke cc_call_state with modified caller_id for features such as - * pickups - */ - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_DIALING_COMPLETED, CC_CAUSE_MIN); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_SETUP); - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_SENT, CC_CAUSE_MIN); - - /* - * Send setup or INVITE out after finishing all UI activities and media - * preparation. This is done as the final step in order to minimize - * UI activities/media activities to run concurrently while processing - * the response from the network. On the platform that uses Java VM to - * support UI and media, the time to process the UI and media activities - * may take longer than the network response time to the INVITE (such as - * voice mail case) and JNI calls may be blocked while invoking the - * UI or media calls in the LSM. - */ - cc_int_setup(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), dcb->alert_info, VCM_INSIDE_RING, - VCM_INSIDE_DIAL_TONE, redirect, call_info, replace, NULL, &msg_body); - fsm_change_state(fcb, __LINE__, FSMDEF_S_CALL_SENT); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_dialstring (sm_event_t *event) -{ - sm_rcs_t sm_rc; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // handle dialstring event if from callfwdall - if (fsmdef_process_dialstring_for_callfwd(event) == SM_RC_END) { - // release the call started to collect callfwd info - dcb->send_release = FALSE; - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - } - - sm_rc = fsmdef_dialstring(fcb, ((cc_dialstring_t *)event->msg)->dialstring, - NULL, FALSE, NULL); - - return (sm_rc); -} - -pc_error -fsmdef_createoffer(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - cc_msgbody_info_t msg_body; - line_t line = msg->line; - callid_t call_id = msg->call_id; - int sdpmode = 0; - char *ufrag = NULL; - char *ice_pwd = NULL; - short vcm_res; - char *local_sdp = NULL; - uint32_t local_sdp_len = 0; - boolean has_stream = FALSE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - *error_outparam = strlib_printf("sdpmode is not set!"); - /* Force clean up call without sending release */ - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf("dcb is NULL"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* For now, if the local SDP has been set, we don't allow it to be set - again. This will change when we allow renegotiation of ongoing - sessions. See bug 840728. */ - if (dcb->local_sdp_complete) { - FSM_DEBUG_SM(DEB_F_PREFIX"local SDP already created: returning " - "prevously created SDP.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - local_sdp = sipsdp_write_to_buf(dcb->sdp->src_sdp, &local_sdp_len); - if (!local_sdp) { - *error_outparam = strlib_printf( - "Could not re-create local SDP for offer"); - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - *sdp_outparam = strlib_malloc(local_sdp, -1); - free(local_sdp); - return (PC_NO_ERROR); - } - - dcb->inbound = FALSE; - - if (msg->data.session.options) { - gsmsdp_process_cap_options(dcb, msg->data.session.options); - fsmdef_free_options(msg->data.session.options); - msg->data.session.options = 0; - } - - if (dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled || - dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled || - dcb->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled) { - has_stream = TRUE; - } - - if (!has_stream) { - *error_outparam = strlib_printf( - "Cannot create SDP without any streams."); - return (PC_INVALID_STATE); - } - - vcm_res = vcmGetIceParams(dcb->peerconnection, &ufrag, &ice_pwd); - if (vcm_res) { - FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetIceParams returned an error", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf( - "Failed to get ICE parameters for local SDP"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - dcb->ice_ufrag = (char *)cpr_malloc(strlen(ufrag) + 1); - if (!dcb->ice_ufrag) { - *error_outparam = strlib_printf( - "Failed to allocate string for ICE ufrag"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - sstrncpy(dcb->ice_ufrag, ufrag, strlen(ufrag) + 1); - free(ufrag); - - dcb->ice_pwd = (char *)cpr_malloc(strlen(ice_pwd) + 1); - if (!dcb->ice_pwd) { - *error_outparam = strlib_printf( - "Failed to allocate string for ICE password"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - sstrncpy(dcb->ice_pwd, ice_pwd, strlen(ice_pwd) + 1); - free(ice_pwd); - - vcm_res = vcmGetDtlsIdentity(dcb->peerconnection, - dcb->digest_alg, FSMDEF_MAX_DIGEST_ALG_LEN, - dcb->digest, FSMDEF_MAX_DIGEST_LEN); - - if (vcm_res) { - FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf("Failed to get DTLS identity"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not create local SDP for offer; cause = %s", - cc_cause_name(cause)); - - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not encode local SDP for offer; cause = %s", - cc_cause_name(cause)); - - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - dcb->local_sdp_complete = TRUE; - - *sdp_outparam = strlib_malloc(msg_body.parts[0].body, -1); - cc_free_msg_body_parts(&msg_body); - - return (PC_NO_ERROR); -} - -pc_error -fsmdef_createanswer(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - cc_msgbody_info_t msg_body; - line_t line = msg->line; - callid_t call_id = msg->call_id; - int sdpmode = 0; - char *ufrag = NULL; - char *ice_pwd = NULL; - short vcm_res; - boolean has_audio; - boolean has_video; - boolean has_data; - char *local_sdp = NULL; - uint32_t local_sdp_len = 0; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - *error_outparam = strlib_printf("sdpmode is false!"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - if (dcb == NULL) { - *error_outparam = strlib_printf("dcb is NULL!"); - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* For now, if the local SDP has been set, we don't allow it to be set - again. This will change when we allow renegotiation of ongoing - sessions. See bug 840728. */ - if (dcb->local_sdp_complete) { - FSM_DEBUG_SM(DEB_F_PREFIX"local SDP already created: returning " - "prevously created SDP.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - local_sdp = sipsdp_write_to_buf(dcb->sdp->src_sdp, &local_sdp_len); - if (!local_sdp) { - *error_outparam = strlib_printf( - "Could not re-create local SDP for answer"); - - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - *sdp_outparam = strlib_malloc(local_sdp, -1); - - free(local_sdp); - return (PC_NO_ERROR); - } - - dcb->inbound = TRUE; - - vcm_res = vcmGetIceParams(dcb->peerconnection, &ufrag, &ice_pwd); - if (vcm_res) { - FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetIceParams returned an error", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - *error_outparam = strlib_printf( - "Could not get ICE parameters for answer"); - - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - dcb->ice_ufrag = (char *)cpr_malloc(strlen(ufrag) + 1); - if (!dcb->ice_ufrag) { - *error_outparam = strlib_printf( - "Could not alloc buffer for ICE ufrag"); - - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - sstrncpy(dcb->ice_ufrag, ufrag, strlen(ufrag) + 1); - free(ufrag); - - - dcb->ice_pwd = (char *)cpr_malloc(strlen(ice_pwd) + 1); - if (!dcb->ice_pwd) { - *error_outparam = strlib_printf( - "Could not alloc buffer for ICE password"); - - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - sstrncpy(dcb->ice_pwd, ice_pwd, strlen(ice_pwd) + 1); - free(ice_pwd); - - vcm_res = vcmGetDtlsIdentity(dcb->peerconnection, - dcb->digest_alg, FSMDEF_MAX_DIGEST_ALG_LEN, - dcb->digest, FSMDEF_MAX_DIGEST_LEN); - - if (vcm_res) { - FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - *error_outparam = strlib_printf("Could not get DTLS identity"); - - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* - * Determine what media types are offered, used to create matching local SDP - * for negotiation. - */ - gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, &has_video, &has_data); - - /* - * The sdp member of the dcb has local and remote sdp - * this next function fills in the local part - */ - cause = gsmsdp_create_local_sdp(dcb, TRUE, has_audio, has_video, has_data, FALSE); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not create local SDP for answer; cause = %s", - cc_cause_name(cause)); - - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - // Force clean up call without sending release - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* TODO(ekr@rtfm.com): The second true is because we are acting as if we are - processing an offer. The first, however, is for an initial offer and we may - want to set that conditionally. */ - cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, - /* initial_offer */ TRUE, - /* offer */ TRUE, - /* notify_stream_added */ FALSE, - /* create_answer */ TRUE); - - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not negotiate media lines; cause = %s", - cc_cause_name(cause)); - - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not encode SDP for answer; cause = %s", - cc_cause_name(cause)); - - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - dcb->local_sdp_complete = TRUE; - - *sdp_outparam = strlib_malloc(msg_body.parts[0].body, -1); - - cc_free_msg_body_parts(&msg_body); - - return (PC_NO_ERROR); -} - -pc_error -fsmdef_setlocaldesc(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - int action = msg->action; - string_t sdp = msg->sdp; - int sdpmode = 0; - callid_t call_id = msg->call_id; - line_t line = msg->line; - char *local_sdp = NULL; - uint32_t local_sdp_len = 0; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - fsm_change_state(fcb, __LINE__, FSMDEF_S_CLOSED); - - *error_outparam = strlib_printf( - "Unrecoverable error: dcb is NULL."); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - fsm_change_state(fcb, __LINE__, FSMDEF_S_CLOSED); - *error_outparam = strlib_printf( - "'sdpmode' configuration is false. This should never ever happen. " - "Run for your lives!"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - if (!dcb->sdp) { - *error_outparam = strlib_printf( - "Setting of local SDP before calling createOffer or createAnswer " - "is not currently supported."); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - switch (action) { - - case JSEP_OFFER: - if (fcb->state != FSMDEF_S_STABLE && - fcb->state != FSMDEF_S_HAVE_LOCAL_OFFER) { - - *error_outparam = strlib_printf( - "Cannot set local offer in state %s", - fsmdef_state_name(fcb->state)); - - return (PC_INVALID_STATE); - } - /* TODO: Parse incoming SDP and act on it. */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_HAVE_LOCAL_OFFER); - break; - - case JSEP_ANSWER: - if (fcb->state != FSMDEF_S_HAVE_REMOTE_OFFER && - fcb->state != FSMDEF_S_HAVE_LOCAL_PRANSWER) { - - *error_outparam = strlib_printf( - "Cannot set local answer in state %s", - fsmdef_state_name(fcb->state)); - - return (PC_INVALID_STATE); - } - /* TODO: Parse incoming SDP and act on it. */ - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ANSWERED, - FSMDEF_CC_CALLER_ID); - - /* - * Now that we have negotiated the media, time to set up ICE. - * There also needs to be an ICE check in negotiate_media_lines. - */ - cause = gsmsdp_install_peer_ice_attributes(fcb); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not configure local ICE state from SDP; cause = %s", - cc_cause_name(cause)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - STAMP_TIMECARD(msg->timecard, "ICE Attributes Installed"); - - /* taken from fsmdef_ev_connected_ack start rx and tx */ - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, - CC_STATE_UNKNOWN, NULL); - *error_outparam = strlib_printf( - "Cannot start media channels cause = %s", - cc_cause_name(cause)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - /* we may want to use the functionality in the following method - * to handle media capability changes, needs discussion - * fsmdef_transition_to_connected(fcb); - */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_STABLE); - break; - - case JSEP_PRANSWER: - if (fcb->state != FSMDEF_S_HAVE_REMOTE_OFFER && - fcb->state != FSMDEF_S_HAVE_LOCAL_PRANSWER) { - - *error_outparam = strlib_printf( - "Cannot set local pranswer in state %s", - fsmdef_state_name(fcb->state)); - - return (PC_INVALID_STATE); - } - *error_outparam = strlib_printf( - "Provisional answers are not yet supported"); - return (PC_INTERNAL_ERROR); - - default: - *error_outparam = strlib_printf( - "Unknown session description type: %d", - action); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* Encode the current local SDP structure into a char buffer */ - local_sdp = sipsdp_write_to_buf(dcb->sdp->src_sdp, &local_sdp_len); - if (!local_sdp) { - *error_outparam = strlib_printf( - "Could not encode local SDP for local description"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - *sdp_outparam = strlib_malloc(local_sdp,-1); - - free(local_sdp); - return (PC_NO_ERROR); -} - -pc_error -fsmdef_setremotedesc(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - int action = msg->action; - int sdpmode = 0; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_msgbody_t *part; - uint32_t body_length; - cc_msgbody_info_t msg_body; - boolean has_audio; - boolean has_video; - boolean has_data; - char *remote_sdp = 0; - uint32_t remote_sdp_len = 0; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - fsm_change_state(fcb, __LINE__, FSMDEF_S_CLOSED); - *error_outparam = strlib_printf( - "Unrecoverable error: dcb is NULL."); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - fsm_change_state(fcb, __LINE__, FSMDEF_S_CLOSED); - *error_outparam = strlib_printf( - "'sdpmode' configuration is false. This should never ever happen. " - "Run for your lives!"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - // XXX We don't currently support renegotiation. If the remote SDP - // has already been set, return an error to the application. This is - // temporary until Bug 840728 is implemented. - if (dcb->sdp && dcb->sdp->dest_sdp) { - FSM_DEBUG_SM(DEB_F_PREFIX"Renegotiation not currently supported.", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf( - "Renegotiation of session description is not currently supported. " - "See Bug 840728 for status."); - return (PC_INVALID_STATE); - } - - cc_initialize_msg_body_parts_info(&msg_body); - - /* !!! NOTE !!! The following code sets up the pointers inside - msg_body.parts[0] to point directly to the buffers from the - event->msg structure. While this is more efficient than - copying them, we must take exceptional care not to call - cc_free_msg_body_parts() on this particular msg_body, since - doing so would result in the buffers being freed twice. */ - - msg_body.num_parts = 1; - msg_body.content_type = cc_content_type_SDP; - part = &msg_body.parts[0]; - body_length = strlen(msg->sdp); - part->body = msg->sdp; - part->body_length = body_length; - part->content_type = cc_content_type_SDP; - part->content_disposition.required_handling = FALSE; - part->content_disposition.disposition = cc_disposition_session; - part->content_id = NULL; - - switch (action) { - case JSEP_OFFER: - if (fcb->state != FSMDEF_S_STABLE && - fcb->state != FSMDEF_S_HAVE_REMOTE_OFFER) { - - *error_outparam = strlib_printf( - "Cannot set remote offer in state %s", - fsmdef_state_name(fcb->state)); - - return (PC_INVALID_STATE); - } - cause = gsmsdp_process_offer_sdp(fcb, &msg_body, TRUE); - if (cause != CC_CAUSE_OK) { - - *error_outparam = strlib_printf( - "Could not process offer SDP; cause = %s", - cc_cause_name(cause)); - - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* - * Determine what media types are offered, used to create matching - * local SDP for negotiation. - */ - gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, - &has_video, &has_data); - - /* - * The sdp member of the dcb has local and remote sdp - * this next function fills in the local part - */ - cause = gsmsdp_create_local_sdp(dcb, TRUE, has_audio, has_video, - has_data, FALSE); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not create local SDP; cause = %s", - cc_cause_name(cause)); - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - // Force clean up call without sending release - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, - TRUE, TRUE, TRUE, FALSE); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not negotiate media lines; cause = %s", - cc_cause_name(cause)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* Now that the SDP is digested we need to sanity check - for ICE parameters */ - cause = gsmsdp_check_ice_attributes_exist(fcb); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "ICE attributes missing; cause = %s", - cc_cause_name(cause)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - gsmsdp_clean_media_list(dcb); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_HAVE_REMOTE_OFFER); - break; - - case JSEP_ANSWER: - if (fcb->state != FSMDEF_S_HAVE_LOCAL_OFFER && - fcb->state != FSMDEF_S_HAVE_REMOTE_PRANSWER) { - - *error_outparam = strlib_printf( - "Cannot set remote answer in state %s", - fsmdef_state_name(fcb->state)); - - return (PC_INVALID_STATE); - } - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg_body); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not negotiate answer SDP; cause = %s", - cc_cause_name(cause)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* - * Now that we have negotiated the media, time to set up ICE. - * There also needs to be an ICE check in negotiate_media_lines. - */ - cause = gsmsdp_install_peer_ice_attributes(fcb); - if (cause != CC_CAUSE_OK) { - *error_outparam = strlib_printf( - "Could not configure local ICE state from SDP; cause = %s", - cc_cause_name(cause)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - STAMP_TIMECARD(msg->timecard, "ICE Attributes Installed"); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - - /* we may want to use the functionality in the following method - * to handle media capability changes, needs discussion - * fsmdef_transition_to_connected(fcb); - */ - - fsm_change_state(fcb, __LINE__, FSMDEF_S_STABLE); - break; - - case JSEP_PRANSWER: - if (fcb->state != FSMDEF_S_HAVE_LOCAL_OFFER && - fcb->state != FSMDEF_S_HAVE_REMOTE_PRANSWER) { - - *error_outparam = strlib_printf( - "Cannot set remote pranswer in state %s", - fsmdef_state_name(fcb->state)); - - return (PC_INVALID_STATE); - } - *error_outparam = strlib_printf( - "Provisional answers are not yet supported"); - return (PC_INTERNAL_ERROR); - - default: - *error_outparam = strlib_printf( - "Unknown session description type: %d", - action); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - /* For the sake of accuracy, we regenerate the SDP text from our parsed - version: if we have any local variation in how we've interpreted the - received SDP, then remoteDescription will reflect that variation. In - practice, this shouldn't happen; but, if it does, at least this will - allow the WebRTC application to figure out what's going on. */ - - remote_sdp = sipsdp_write_to_buf(dcb->sdp->dest_sdp, &remote_sdp_len); - - if (!remote_sdp) { - *error_outparam = strlib_printf( - "Could not serialize remote description; cause = %s", - cc_cause_name(cause)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - *sdp_outparam = strlib_malloc(remote_sdp,-1); - - free(remote_sdp); - - return (PC_NO_ERROR); -} - -pc_error -fsmdef_setpeerconnection(fsm_fcb_t *fcb, cc_feature_t *msg) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - callid_t call_id = msg->call_id; - int sdpmode = 0; - line_t line = msg->line; - cc_causes_t lsm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - FSM_DEBUG_SM(DEB_F_PREFIX"sdpmode is false; cannot set peerconnection.", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - if (!msg) { - fsmdef_release(fcb, cause, FALSE); - return PC_INTERNAL_ERROR; - } - - if (dcb == NULL) { - dcb = fsmdef_get_new_dcb(call_id); - if (dcb == NULL) { - fsmdef_release(fcb, cause, FALSE); - return PC_INTERNAL_ERROR; - } - - lsm_rc = lsm_get_facility_by_line(call_id, line, FALSE, dcb); - if (lsm_rc != CC_CAUSE_OK) { - FSM_DEBUG_SM(DEB_F_PREFIX"lsm_get_facility_by_line failed.", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - fsmdef_release(fcb, cause, FALSE); - return PC_INTERNAL_ERROR; - } - - fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_NONE, NULL, line, fcb); - - fsm_set_fcb_dcbs(dcb); - } - - PR_ASSERT(strlen(msg->data.pc.pc_handle) < PC_HANDLE_SIZE); - sstrncpy(dcb->peerconnection, msg->data.pc.pc_handle, - sizeof(dcb->peerconnection)); - dcb->peerconnection_set = TRUE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Setting peerconnection handle for (%d/%d) to %s", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__), - line, call_id, dcb->peerconnection); - - /* WebRTC connections always start in state "STABLE". */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_STABLE); - - return (PC_NO_ERROR); -} - -pc_error -fsmdef_addstream(fsm_fcb_t *fcb, cc_feature_t *msg, string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - int sdpmode = 0; - cc_media_cap_name cap_index = CC_INVALID_INDEX; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (sdpmode == FALSE) { - *error_outparam = strlib_printf("sdpmode is false"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf("dcb is NULL"); - fsmdef_release(fcb, cause, FALSE); - return PC_INTERNAL_ERROR; - } - - - /* - * This is temporary code to allow configuration of the two - * default streams. When multiple streams > 2 are supported this - * will be re-implemented. - */ - switch (msg->data.track.media_type) { - case VIDEO: - cap_index = CC_VIDEO_1; - break; - case AUDIO: - cap_index = CC_AUDIO_1; - break; - case DATA: - cap_index = CC_DATACHANNEL_1; - break; - default: - break; - } - - if (cap_index != CC_INVALID_INDEX) { - dcb->media_cap_tbl->cap[cap_index].enabled = TRUE; - dcb->media_cap_tbl->cap[cap_index].support_direction = SDP_DIRECTION_SENDRECV; - dcb->media_cap_tbl->cap[cap_index].pc_stream = msg->data.track.stream_id; - dcb->media_cap_tbl->cap[cap_index].pc_track = msg->data.track.track_id; - } - return (PC_NO_ERROR); -} - -pc_error -fsmdef_removestream(fsm_fcb_t *fcb, cc_feature_t *msg, string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - int sdpmode = 0; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (sdpmode == FALSE) { - *error_outparam = strlib_printf("sdpmode is false"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf("dcb is NULL"); - fsmdef_release(fcb, cause, FALSE); - return PC_INTERNAL_ERROR; - } - - /* - * This is temporary code to allow configuration of the two - * default streams. When multiple streams > 2 are supported this - * will be re-implemented. - */ - if (msg->data.track.media_type == AUDIO) { - PR_ASSERT(dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled); - dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY; - dcb->video_pref = SDP_DIRECTION_SENDRECV; - } else if (msg->data.track.media_type == VIDEO) { - PR_ASSERT(dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled); - dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY; - } else { - /* Why weren't we doing the same thing for DATA? */ - return (PC_NO_ERROR); - } - - return (PC_NO_ERROR); -} - -pc_error -fsmdef_addcandidate(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - int sdpmode = 0; - short vcm_res; - uint16_t level; - line_t line = msg->line; - callid_t call_id = msg->call_id; - char *remote_sdp = 0; - uint32_t remote_sdp_len = 0; - char *candidate = NULL; - char candidate_tmp[CANDIDATE_SIZE]; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (!dcb) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf("DCB has not been created."); - fsmdef_release(fcb, cause, FALSE); - return PC_INTERNAL_ERROR; - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (sdpmode == FALSE) { - *error_outparam = strlib_printf( - "'sdpmode' configuration is false. This should never ever happen. " - "Run for your lives!"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - if (!dcb->sdp) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb->sdp is NULL. Has the " - "remote description been set yet?\n", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - *error_outparam = strlib_printf( - "Cannot add remote ICE candidates before setting remote SDP."); - - return PC_INVALID_STATE; - } - - /* Perform level lookup based on mid value */ - /* comment until mid is properly updated - cause = gsmsdp_find_level_from_mid(dcb, (const char *)msg->data.candidate.mid, &level); - */ - - /* XXX: Bug 833043. Need to sanity check that this is actually a valid candidate */ - /* Update remote SDP with new candidate information */ - candidate = (char *)msg->data.candidate.candidate; - if (!strncasecmp(candidate, "a=", 2)) { - char *cr; - - /* Strip off Chrome's inappropriate leading a=. - TODO(ekr@rtfm.com): remove once Chrome conforms to the specification - or revisit if the specification changes. */ - sstrncpy(candidate_tmp, candidate + 2, sizeof(candidate_tmp)); - - /* Strip off \r\n if it exists */ - cr = strchr(candidate_tmp, '\r'); - if (cr) - *cr = '\0'; - - candidate = candidate_tmp; - } - - level = msg->data.candidate.level; - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, - dcb->sdp->dest_sdp, candidate); - - vcm_res = vcmSetIceCandidate(dcb->peerconnection, candidate, msg->data.candidate.level); - if(vcm_res) { - *error_outparam = strlib_printf( - "ICE failure; cannot add remote candidate"); - FSM_DEBUG_SM(DEB_F_PREFIX"failure setting ice candidate.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return (PC_INTERNAL_ERROR); - } - - /* Serialize the updated SDP and inform the PeerConnection of the - new SDP contents. */ - - remote_sdp = sipsdp_write_to_buf(dcb->sdp->dest_sdp, &remote_sdp_len); - - if (!remote_sdp) { - *error_outparam = strlib_printf( - "Could not serialize new SDP after adding ICE candidate."); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - *sdp_outparam = strlib_malloc(remote_sdp,-1); - - cpr_free(remote_sdp); - return (PC_NO_ERROR); -} - -pc_error -fsmdef_foundcandidate(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - int sdpmode = 0; - uint16_t level; - line_t line = msg->line; - callid_t call_id = msg->call_id; - char *local_sdp = 0; - uint32_t local_sdp_len = 0; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (!dcb) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - *error_outparam = strlib_printf("DCB has not been created."); - fsmdef_release(fcb, cause, FALSE); - return PC_INTERNAL_ERROR; - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - fsm_change_state(fcb, __LINE__, FSMDEF_S_CLOSED); - *error_outparam = strlib_printf( - "'sdpmode' configuration is false. This should never ever happen. " - "Run for your lives!"); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - MOZ_ASSERT(dcb->sdp && dcb->sdp->src_sdp); - if (!dcb->sdp || !dcb->sdp->src_sdp) { - FSM_DEBUG_SM(DEB_F_PREFIX"Has the " - "local description been set yet?\n", - DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - *error_outparam = strlib_printf( - "Cannot add found ICE candidates without local SDP."); - - return PC_INVALID_STATE; - } - - /* Store the candidate in the SDP for future reference */ - level = msg->data.candidate.level; - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, - dcb->sdp->src_sdp, - (char *)msg->data.candidate.candidate); - - local_sdp = sipsdp_write_to_buf(dcb->sdp->src_sdp, &local_sdp_len); - - if (!local_sdp) { - *error_outparam = strlib_printf( - "Could not serialize new SDP after adding ICE candidate."); - fsmdef_release(fcb, cause, FALSE); - return (PC_INTERNAL_ERROR); - } - - *sdp_outparam = strlib_malloc(local_sdp,-1); - - cpr_free(local_sdp); - return PC_NO_ERROR; -} - -static void -fsmdef_check_active_feature (fsmdef_dcb_t *dcb, cc_features_t ftr_id) -{ - if ((dcb) && (dcb->active_feature != ftr_id)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_FTR_REQ_ACT), - dcb->call_id, dcb->line, - cc_feature_name(ftr_id), - cc_feature_name(dcb->active_feature)); - lsm_ui_display_notify(INDEX_STR_KEY_NOT_ACTIVE, NO_FREE_LINES_TIMEOUT); - } -} - -static sm_rcs_t -fsmdef_ev_idle_feature (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - line_t line = msg->line; - cc_causes_t cause = CC_CAUSE_NORMAL; - callid_t call_id = fcb->call_id; - boolean expline; - sm_rcs_t sm_rc = SM_RC_END; - fsmcnf_ccb_t *ccb; - fsmxfr_xcb_t *xcb; - char *global_call_id = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - if (dcb) { - dcb->video_pref = data->caps.support_direction; - } - break; - case CC_FEATURE_CFWD_ALL: - if (fsmdef_is_feature_uri_configured(ftr_id) == FALSE) { - fsm_display_feature_unavailable(); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - // handle cfwd event for ccm and non-ccm cases - // process feature event only if no other active feature - if ((dcb->active_feature == CC_FEATURE_NONE) && - (fsmdef_get_connected_call() == NULL)) { - dcb->active_feature = ftr_id; - (void) fsmdef_process_cfwd_softkey_event(event); - } else { - fsmdef_check_active_feature(dcb, ftr_id); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - case CC_FEATURE_NEW_CALL: - - /* fetch the global_call_id from feature data */ - global_call_id = data->newcall.global_call_id; - - /* - * Set the expanded parameter. This parameter is used when - * requesting a free line. A transfer can request that the line - * availability be increased by one to account for the third - * instance of a line to become available for transfers. - */ - if (data != NULL) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((ccb != NULL) || (xcb != NULL)) { - expline = TRUE; - } else { - expline = FALSE; - } - } else { - expline = FALSE; - } - - /* - * Get a new outgoing call context if we have not already - * grabbed one. - */ - if (fcb->dcb == NULL) { - cause = fsm_get_new_outgoing_call_context(call_id, line, fcb, - expline); - switch (cause) { - case CC_CAUSE_OK: - break; - - case CC_CAUSE_NO_RESOURCE: - GSM_ERR_MSG("%s No Resource! Return SM_RC_CLEANUP.", fname); - return (SM_RC_CLEANUP); - - default: - /* - * No free lines. - */ - fsm_display_no_free_lines(); - - /* - * Send an endcall message. This behaviour is different - * than an offhook or line event because the new_call - * feature may have been generated by a transfer (as the - * consultation call) and will need this end_call message - * so that it can cleanup the transfer. The offhook can - * only come from the UI so it can just be cleaned up here - * without regard for a transfer. - */ - fsmdef_end_call(fcb->dcb, cause); - - return (SM_RC_END); - } - - dcb = fcb->dcb; - /* - * Let Dialog Manager know that there is OFFHOOK event - */ - fsmdef_notify_hook_event(fcb, CC_MSG_OFFHOOK, global_call_id, - data->newcall.prim_call_id, - data->newcall.hold_resume_reason, - CC_MONITOR_NONE,CFWDALL_NONE); - } - - - /* - * The user is attempting to start a new call on a specific line: - * 1. need to place the connected call (if there is one) on hold, - * 2. clear any outgoing ringing calls, - * 3. initiate this call. - */ - if (fsmdef_wait_to_start_new_call(TRUE, CC_SRC_GSM, call_id, line, - ftr_id, data)) { - return (SM_RC_END); - } - - //lsm_set_active_call_id(call_id); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - FSMDEF_CC_CALLER_ID); - - if ( data->newcall.cause == CC_CAUSE_CONF || - data->newcall.cause == CC_CAUSE_XFER_LOCAL ) { - /* suppress stutter dial tone for conf and transfer features */ - fsmdef_call_cc_state_dialing(dcb, TRUE); - } else { - fsmdef_call_cc_state_dialing(dcb, FALSE); - } - - switch (data->newcall.cause) { - case CC_CAUSE_XFER_REMOTE: - /* - * This newcall feature is really the consultation part of - * a local transfer that has been transferred by the - * consultation call, so proceed as though this is a - * dialstring call since we already have the called_number. - */ - if (data->newcall.redirect.redirects[0].number[0] != '\0') { - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - - } else if (data->newcall.redirect.redirects[0].redirect_reason - == CC_REDIRECT_REASON_DEFLECTION) { - /* - * CC_REDIRECT_REASON_DEFLECTION shows that transferee is - * going to initiate a new call for replacing the call leg - * between transferor and target. - */ - - memset(data->newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - - } else { - sm_rc = - fsmdef_dialstring(fcb, data->newcall.dialstring, NULL, - FALSE, NULL); - } - - return (sm_rc); - - case CC_CAUSE_REDIRECT: - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - return (sm_rc); - - case CC_CAUSE_XFER_BY_REMOTE: - - /* CC_REDIRECT_REASON_DEFLECTION shows that transferee is - * going to initiate a new call for replacing the call leg - * between transferor and target. - */ - - memset(data->newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - return (sm_rc); - - default: - fsm_change_state(fcb, __LINE__, FSMDEF_S_COLLECT_INFO); - - return (SM_RC_END); - } - - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, data); - - /* - * There has to be a dcb to process this event. - */ - if (fcb->dcb == NULL) { - // commented out following line due to klocwork error - // call is dereferencing fcb->dcb when it is NULL (sorry, can't do that!) - // cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, NULL); - return (SM_RC_CLEANUP); - } - - if (dcb->call_type == FSMDEF_CALL_TYPE_INCOMING || - dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) { - dcb->send_release = TRUE; - } - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - } /* switch (src_id) { */ - - return (sm_rc); -} - -sm_rcs_t -fsmdef_offhook (fsm_fcb_t *fcb, cc_msgs_t msg_id, callid_t call_id, - line_t line, const char *dial_string, - sm_event_t *event, char *global_call_id, - callid_t prim_call_id, cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode) -{ - boolean wait = FALSE; - boolean wait2 = FALSE; - boolean wait3 = FALSE; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Get a new outgoing call context if we have not already - * grabbed one. - */ - if (fcb->dcb == NULL) { - cause = fsm_get_new_outgoing_call_context(call_id, line, fcb, FALSE); - switch (cause) { - case CC_CAUSE_OK: - break; - - default: - /* - * No free lines - */ - fsm_display_no_free_lines(); - - if (fsmdef_get_connected_call() != NULL) { - lsm_speaker_mode(ON); - } else { - lsm_speaker_mode(OFF); - } - return (SM_RC_CLEANUP); - } - - /* - * Let Dialog Manager know that there is OFFHOOK event - */ - fsmdef_notify_hook_event(fcb, CC_MSG_OFFHOOK, global_call_id, - prim_call_id, consult_reason, monitor_mode,CFWDALL_NONE); - } - - - /* - * The user is attempting to start a new call on a specific line: - * 1. need to place the connected call (if there is one) on hold, - * 2. clear any outgoing ringing calls, or calls are in reorder/busy state - * 3. initiate this call. - */ - fsmdef_find_and_hold_connected_call(call_id, &wait, CC_SRC_GSM); - - fsmdef_find_and_handle_ring_connecting_releasing_calls(call_id, &wait2); - - fsmdef_clear_preserved_calls(&wait3); - - /* - * Requeue the message if we need to wait for the connected line to - * hold - */ - if ((wait == TRUE) || (wait2 == TRUE) || (wait3 == TRUE)) { - switch (msg_id) { - case CC_MSG_OFFHOOK: - cc_int_offhook(CC_SRC_GSM, CC_SRC_GSM, prim_call_id, consult_reason, - call_id, line, global_call_id, monitor_mode,CFWDALL_NONE); - break; - - case CC_MSG_LINE: - cc_int_line(CC_SRC_GSM, CC_SRC_GSM, call_id, line); - break; - - case CC_MSG_DIALSTRING: - cc_int_dialstring(CC_SRC_GSM, CC_SRC_GSM, call_id, line, - dial_string, global_call_id, monitor_mode); - break; - - case CC_MSG_FEATURE: - if (dial_string != NULL) { - cc_int_dialstring(CC_SRC_GSM, CC_SRC_GSM, call_id, line, - dial_string, global_call_id, monitor_mode); - break; - } - - /*FALLTHROUGH*/ - default: - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_CLEANUP); - } - - return (SM_RC_END); - } - - //lsm_set_active_call_id(call_id); - - return (SM_RC_SUCCESS); -} - - -static sm_rcs_t -fsmdef_ev_idle_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_offhook_t *msg = (cc_offhook_t *) event->msg; - fsmdef_dcb_t *dcb; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - sm_rc = fsmdef_offhook(fcb, msg->msg_id, msg->call_id, msg->line, NULL, - event, msg->global_call_id, msg->prim_call_id, - msg->hold_resume_reason, msg->monitor_mode); - - if (sm_rc != SM_RC_SUCCESS) { - return (sm_rc); - } - - dcb = fcb->dcb; - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - FSMDEF_CC_CALLER_ID); - - fsmdef_call_cc_state_dialing(dcb, FALSE); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_COLLECT_INFO); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_idle_dialstring (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_dialstring_t *msg = (cc_dialstring_t *) event->msg; - fsmdef_dcb_t *dcb; - cc_action_data_t data; - sm_rcs_t sm_rc; - cc_call_info_t call_info; - cc_call_info_t *call_info_p = NULL; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - sm_rc = fsmdef_offhook(fcb, msg->msg_id, msg->call_id, msg->line, - msg->dialstring, event, msg->g_call_id, - CC_NO_CALL_ID, CC_REASON_NONE, msg->monitor_mode); - - if (sm_rc != SM_RC_SUCCESS) { - return (sm_rc); - } - - dcb = fcb->dcb; - - if (msg->dialstring) { - lsm_set_lcb_dialed_str_flag(dcb->call_id); - } - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - FSMDEF_CC_CALLER_ID); - - data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, &data); - - dcb->send_release = TRUE; - - /* Set call_info with global call_id, sent in the Initcallreq, - * If this call is not because Initcallreq, then don't set call_info - * Also, if this is a monitor call, add the mode to the call_info - */ - if (msg->g_call_id != NULL) { - - call_info.type = CC_FEAT_INIT_CALL; - call_info.data.initcall.monitor_mode = msg->monitor_mode; - sstrncpy(call_info.data.initcall.gcid, msg->g_call_id, CC_GCID_LEN); - - call_info_p = &call_info; - } - - if ( strncmp(CISCO_BLFPICKUP_STRING, msg->dialstring, strlen(CISCO_BLFPICKUP_STRING)) == 0 ) { - dcb->log_disp = CC_CALL_LOG_DISP_RCVD; - } - - sm_rc = fsmdef_dialstring(fcb, msg->dialstring, NULL, FALSE, call_info_p); - - return (sm_rc); -} - -static sm_rcs_t -fsmdef_ev_session_audit (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_session_audit"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_audit_sdp_req_t *audit_msg = (cc_audit_sdp_req_t *) event->msg; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (gsmsdp_encode_sdp_and_update_version(dcb, &msg_body) != CC_CAUSE_OK) { - /* - * Failed to encode our local sdp. Send ack to SIP stack with - * no message body. SIP stack will include previously send - * SDP in response to session audit request. - */ - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - - cc_int_audit_sdp_ack(CC_SRC_GSM, CC_SRC_SIP, audit_msg->call_id, - audit_msg->line, NULL); - } else { - cc_int_audit_sdp_ack(CC_SRC_GSM, CC_SRC_SIP, audit_msg->call_id, - audit_msg->line, &msg_body); - } - - /* - * If we are currently performing a spoofed ringout and the current session audit - * does not indicate that we should continue to do so, go back to connected state. - * But only change to connected state if not locally held. - */ - if (dcb->spoof_ringout_applied && - !dcb->spoof_ringout_requested) { - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - if ((fcb->state != FSMDEF_S_HOLDING) && - (fcb->state != FSMDEF_S_HOLD_PENDING)) { - /* - * If is at least one media entry that is not in loally held - * then go to connected state. - */ - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - } - - return (SM_RC_SUCCESS); -} - -static sm_rcs_t -fsmdef_ev_collectinginfo_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_FAILED, CC_CAUSE_INVALID_NUMBER); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_collectinginfo_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_action_data_t data; - sm_rcs_t sm_rc = SM_RC_END; - cc_causes_t cause; - cc_feature_data_t *feature_data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (msg->feature_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = feature_data->caps.support_direction; - break; - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - if (fcb->state == FSMDEF_S_KPML_COLLECT_INFO) { - /* Clean up and send release */ - return (fsmdef_release(fcb, cause, TRUE)); - } - else { - /* Clean up without sending release */ - return (fsmdef_release(fcb, cause, FALSE)); - } - - case CC_FEATURE_NUMBER: - case CC_FEATURE_URL: - dcb->dial_mode = ((msg->feature_id == CC_FEATURE_NUMBER) ? - (DIAL_MODE_NUMERIC) : (DIAL_MODE_URL)); - - data.dial_mode.mode = dcb->dial_mode; - data.dial_mode.digit_cnt = dcb->digit_cnt; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_DIAL_MODE, - &data); - - break; - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - /* - * lsm_set_lcb_prevent_ringing() will check if there is a RINGIN call - * with the same GCID. If so, it will set a flag to prevent ringing. - */ - lsm_set_lcb_prevent_ringing(dcb->call_id); - break; - - case CC_FEATURE_SELECT: - fsmdef_select_invoke(dcb, feature_data); - return (SM_RC_END); - - case CC_FEATURE_CFWD_ALL: - if (fsmdef_is_feature_uri_configured(msg->feature_id) == FALSE) { - fsm_set_call_status_feature_unavailable(dcb->call_id, dcb->line); - - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - // handle cfwd event for ccm and non-ccm cases - // process feature event only if no other active feature - if (dcb->active_feature == CC_FEATURE_NONE) { - dcb->active_feature = ftr_id; - (void) fsmdef_process_cfwd_softkey_event(event); - } else { - fsmdef_check_active_feature(dcb, ftr_id); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - - default: - dcb->active_feature = CC_FEATURE_NONE; - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - return (sm_rc); -} - -/* - * Function: fsmdef_ev_digit_begin - * - * Parameters: event - * - * Description: This function is called each time a digit is - * received from the platform code. Currently, the platform code - * parses the dialplan. This function simply turns the - * dialtone off every time a digit is received and - * displays the appropriate keyset. (Eventually, this - * interface should be changed and GSM should have - * better knowledge of the dialplan.) - * - * Returns: SM_RC_END - */ -static sm_rcs_t -fsmdef_ev_digit_begin (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_digit_begin"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_digit_begin_t *msg = (cc_digit_begin_t *) event->msg; - char digit; - cc_action_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - digit = lsm_digit2ch(msg->digit); - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Digit Received= %c: stopping dial tone..", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, msg->call_id, fname), digit); - data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, &data); - - /* - * Increment digit_cnt so that the proper keyset will be - * displayed. - */ - if (dcb->digit_cnt < CC_MAX_DIALSTRING_LEN) { - dcb->digit_cnt++; - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_proceeding (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - fcb->dcb->send_release = TRUE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - -#ifdef SAPP_SAPP_GSM - if ((event->msg != NULL) && - (((cc_proceeding_t *)(event->msg))->caller_id.called_name != NULL)) { - dcb->caller_id.called_name = - strlib_update(dcb->caller_id.called_name, - ((cc_proceeding_t *) (event->msg))->caller_id. - called_name); - } -#endif - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_FAR_END_PROCEEDING, - FSMDEF_CC_CALLER_ID); - - - fsm_change_state(fcb, __LINE__, FSMDEF_S_OUTGOING_PROCEEDING); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_out_alerting (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_out_alerting"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_alerting_t *msg = (cc_alerting_t *) event->msg; - cc_causes_t cause = CC_CAUSE_ERROR; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb->send_release = TRUE; - - dcb->inband = FALSE; - if (msg->inband) { - dcb->inband = TRUE; - - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * Record fact that we have successfully negotiated media that may be - * used for inband ringback. - */ - dcb->inband_received = TRUE; - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_FAR_END_ALERTING, - FSMDEF_CC_CALLER_ID); - - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - (void)fsmdef_release(fcb, CC_CAUSE_NO_MEDIA, dcb->send_release); - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_END); - } -// fsmdef_update_pd(dcb, FSMDEF_CALL_TYPE_OUTGOING); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_OUTGOING_ALERTING); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_callsent_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_release_t *msg = (cc_release_t *) event->msg; - cc_causes_t cause = msg->cause; - cc_srcs_t src_id = msg->src_id; - sm_rcs_t sm_rc = SM_RC_END; - char tmp_str[STATUS_LINE_MAX_LEN]; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* if UI_STATE of BUSY in 183 Call-Info is causing the release, - do not modify dcb->send_release */ - if (cause != CC_CAUSE_UI_STATE_BUSY) { - dcb->send_release = FALSE; - } else { - // CSCti63677 - if ((fcb->state == FSMDEF_S_OUTGOING_ALERTING) && - (dcb->inband_received == TRUE) && - (dcb->placed_call_update_required)) { - - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - } - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - /* For 500 response from the CCM, disconnect the call and clear the UI. - * There are several cases in which CCM sends down 500 response code to - * clear the call and UI. Some of the cases are CFWDALL, early conference - * and CTI transfer of ringing call - * - * Non-auto pickups do receive 480 response, it is OK release the call. - */ - if ((cause == CC_CAUSE_REMOTE_SERVER_ERROR) || - (((strncmp(dcb->caller_id.called_number, CISCO_BLFPICKUP_STRING, - (sizeof(CISCO_BLFPICKUP_STRING) - 1)) == 0)) && - ((cause == CC_TEMP_NOT_AVAILABLE) || (cause == CC_CAUSE_CONGESTION) ))) { - if (cause == CC_CAUSE_CONGESTION) { - if (platGetPhraseText(STR_INDEX_NO_CALL_FOR_PICKUP, (char *)tmp_str, STATUS_LINE_MAX_LEN - 1) == CPR_SUCCESS) - { - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, tmp_str, 2, FALSE, DEF_NOTIFY_PRI); - } - } - cause = CC_CAUSE_OK; - } - - switch (cause) { - case CC_CAUSE_ERROR: - case CC_CAUSE_NOT_FOUND: - case CC_CAUSE_BUSY: - case CC_CAUSE_CONGESTION: - case CC_CAUSE_INVALID_NUMBER: - case CC_CAUSE_PAYLOAD_MISMATCH: - case CC_CAUSE_REMOTE_SERVER_ERROR: - case CC_TEMP_NOT_AVAILABLE: - case CC_CAUSE_UI_STATE_BUSY: - case CC_CAUSE_NO_USER_ANS: - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_FAILED, cause); - - if (cause != CC_CAUSE_UI_STATE_BUSY) { - cc_int_release_complete(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, cause, NULL); - } - /* see if the SIP stack has aborted this call early for some reason - * If SIP brought this down, we are still offhook on the UI, so - * when we get the release_complete from the 200 for the BYE, we - * need to ignore it, so that reorder can be played AND when the user - * hangs up, then the UI will be driven to a clean state. - */ - if (src_id == CC_SRC_SIP) { - dcb->early_error_release = TRUE; - } - break; - - default: - sm_rc = fsmdef_release(fcb, cause, dcb->send_release); - if (sm_rc == SM_RC_CLEANUP) { - /* - * FSM release indicates clean up, do not continue - * on since fcb and dcb have been freed or re-initialized. - */ - return (sm_rc); - } - } /* switch (cause) */ - - /*UI_STATE of BUSY in 183 is causing the release, so - *don't change state. This is needed to support - *callback feature. Since the callee is busy, we need - *update call UI status to "Busy" from "Ringout" to - *reflect this change. - */ - if (cause != CC_CAUSE_UI_STATE_BUSY) { - fsm_change_state(fcb, __LINE__, FSMDEF_S_RELEASING); - } else { - cc_action_data_t action_data; - action_data.update_ui.action = CC_UPDATE_SET_CALL_STATUS; - action_data.update_ui.data.set_call_status_parms.phrase_str_p = platform_get_phrase_index_str(LINE_BUSY); - action_data.update_ui.data.set_call_status_parms.timeout = 0; - action_data.update_ui.data.set_call_status_parms.call_id = dcb->call_id; - action_data.update_ui.data.set_call_status_parms.line = dcb->line; - /*Update UI status to "Busy".*/ - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - } - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_callsent_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_causes_t cause; - cc_feature_data_redirect_t *data = &(msg->data.redirect); - cc_action_data_t action_data; - cc_feature_data_t *select_data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = select_data->caps.support_direction; - break; - case CC_FEATURE_NOTIFY: - if (src_id == CC_SRC_SIP) { - fsmdef_ev_notify_feature(msg, dcb); - } else { - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - - break; - - case CC_FEATURE_END_CALL: - /** - * In case of earlier attandence, there might a waiting call. - */ - lsm_remove_lcb_prevent_ringing(dcb->call_id); - /* - * Since user press the end call, no need to wait to play the busy tone. - * So, clear the early_error_release and clean the fcb/dcb. - */ - dcb->early_error_release = FALSE; - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - case CC_FEATURE_REDIRECT: - /* - * The outgoing call has been redirected, so we need to: - * 1. ACK the redirect request, - * 2. release the current call, - * 3. start a new call to the redirect number. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_FEATURE_REDIRECT, NULL, CC_CAUSE_REDIRECT); - /* - * May need to update an xcb if this call is involved in a transfer. - */ - //xcb = fsmxfr_get_xcb_by_call_id(call_id); - // fsmxfr_update_xfr_context(xcb, call_id, redirect_call_id); - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, data->redirect_number); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_DIALING_COMPLETED, - FSMDEF_CC_CALLER_ID); - - break; - - - case CC_FEATURE_CALLINFO: - fsmdef_update_calltype(fcb, msg); - fsmdef_update_callinfo(fcb, msg); - /* - * lsm_set_lcb_prevent_ringing() will check if there is a RINGIN call - * with the same GCID. If so, it will set a flag to prevent ringing. - */ - lsm_set_lcb_prevent_ringing(dcb->call_id); - break; - - case CC_FEATURE_UPDATE: - /* Simply reply with a 200OK to a received UPDATE */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_FEATURE_UPDATE, NULL, CC_CAUSE_OK); - break; - - case CC_FEATURE_RINGBACK_DELAY_TIMER_EXP: - if (!dcb->inband_received) { - /* - * Ringback delay timer expired and we have not received - * a response from the far end indicating that they are - * playing inband ringback. Start local ringback tone now. - */ - action_data.tone.tone = VCM_ALERTING_TONE; - (void)cc_call_action(call_id, line, CC_ACTION_PLAY_TONE, - &action_data); - } - break; - - - case CC_FEATURE_SELECT: - fsmdef_select_invoke(dcb, select_data); - return (SM_RC_END); - - - case CC_FEATURE_SUBSCRIBE: - /* KPML subscription received so collect digits for KPML */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_KPML_COLLECT_INFO); - break; - - case CC_FEATURE_CFWD_ALL: - fsm_set_call_status_feature_unavailable(call_id, line); - - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) { */ - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_release_call (fsm_fcb_t *fcb, cc_feature_t *msg) -{ - cc_feature_data_t *data = &(msg->data); - cc_state_data_t state_data; - cc_causes_t cause; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - cause = fsmdef_get_cause(msg->data_valid, data); - - /* - * Do things a little different depending on the value of the - * release cause. - */ - switch (cause) { - case CC_CAUSE_XFER_LOCAL: - /* - * Send release and then wait for the release_complete. - */ - cc_int_release(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, data->endcall.cause, - data->endcall.dialstring, NULL); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_RELEASING); - - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = TRUE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, &state_data); - - break; - - case CC_CAUSE_XFER_REMOTE: - /* - * No need to send release because the remote end initiated - * the transfer. - */ - dcb->send_release = FALSE; - return (fsmdef_release(fcb, cause, dcb->send_release)); - - case CC_CAUSE_XFER_CNF: - case CC_CAUSE_REPLACE: - /* - * We are the target of a transfer and this is the consultation - * call that is being replaced, so we just need to onhook this call - * but leave the signaling up until the stack notifies the FSM that - * the transfer is accepted - and then we will release the call. - * Same has to happen when bridge of conference ends the call. We are - * initiating transfer in this case so we want signaling to remain - * up while UI should be cleared up. - */ - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = TRUE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, &state_data); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLDING); - - break; - - default: - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_inalerting_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t *data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - /* force an update to media cap */ - dcb->media_cap_tbl->id--; - gsmsdp_update_local_sdp_media_capability(dcb, FALSE, FALSE); - break; - - case CC_FEATURE_END_CALL: - return (fsmdef_release_call(fcb, msg)); - - case CC_FEATURE_ANSWER: - /* - * The user wants to answer this call, so... - * 1. need to place the connected call (if there is one) on hold, - * 2. clear all the outgoing ringing lines, - * 3. answer this call. - */ - if (fsmdef_wait_to_start_new_call(TRUE, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_ANSWER, NULL)) { - - /* - * Inform the LSM that the answering of this call has - * been delayed while waiting for other calls to clear. - */ - (void)cc_call_action(dcb->call_id, dcb->line, - CC_ACTION_ANSWER_PENDING, NULL); - - return (SM_RC_END); - } - - return (fsmdef_handle_inalerting_offhook_answer(event)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) { */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_UPDATE: - /* Simply reply with a 200 OK to a received UPDATE */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_FEATURE_UPDATE, NULL, CC_CAUSE_OK); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) { */ - - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (src_id) { */ - - return (SM_RC_END); -} - - -/* - * This function contains the common code for fsmdef_ev_inalerting_offhook() - * and the ANSWER event handling in the fsmdef_ev_inalerting_feature(). - */ -static sm_rcs_t -fsmdef_handle_inalerting_offhook_answer (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* Build our response SDP to include in the connected */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* For CCM, call_type indicate if the call is forwarded or not - * for forwarded call display will be shown as "Forward", only - * during ringing state. Once the call is connected then the call - * is shown as normal incoming call "From". so change call type now - * Do this only if Retain Forward Information is disabled or not configured. - * If configured/enabled then leave the call type as Forward. - */ - - if (dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) { - if (!fsmdef_check_retain_fwd_info_state()) { - dcb->call_type = FSMDEF_CALL_TYPE_INCOMING; - /* - * Force us to update the UI so that any possible callinfo received - * prior to the call is answered takes effect. - */ - dcb->ui_update_required = TRUE; - } - } - - cc_int_connected(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL, &msg_body); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ANSWERED, - FSMDEF_CC_CALLER_ID); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTING); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_inalerting_offhook (sm_event_t *event) -{ - return (fsmdef_handle_inalerting_offhook_answer(event)); -} - - -static sm_rcs_t -fsmdef_ev_connecting_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - cc_feature_data_t *data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } - - return (SM_RC_END); -} - -/** - * - * Function to handle transition to FSMDEF_S_CONNECTED. It checks - * whether there is any media capability that needs to be updated - * or not. If there is not then it transition to FSMDEF_S_CONNECTED - * otherwise it transitions to the FSMDEF_S_CONNECTED_MEDIA_PEND state - * and sends out the media update request. - * - * @param[in] fcb - The pointer to the fsm_fcb_t structure of this - * call. - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb not_eq NULL) - */ -static sm_rcs_t -fsmdef_transition_to_connected (fsm_fcb_t *fcb) -{ - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t feature_data; - sm_rcs_t sm_rc = SM_RC_END; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Update the media capability without effecting the existing media line. - */ - if (!gsmsdp_update_local_sdp_media_capability(dcb, FALSE, FALSE)) { - /* not thing is changed, transition to connected state */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED); - return (sm_rc); - } - - - feature_data.resume.call_info.type = CC_FEAT_NONE; - feature_data.resume.call_info.data.hold_resume_reason = CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return(fsmdef_release(fcb, cause, dcb->send_release)); - } - - fsmdef_get_rtp_stat(dcb, &(feature_data.resume.kfactor)); - - /* Send feature request to SIP */ - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_MEDIA, &feature_data); - - - if (g_dock_undock_event == MEDIA_INTERFACE_UPDATE_STARTED) { - g_dock_undock_event = MEDIA_INTERFACE_UPDATE_IN_PROCESS; - ui_update_media_interface_change(dcb->line, dcb->call_id, MEDIA_INTERFACE_UPDATE_BEGIN); - } else if (g_dock_undock_event == MEDIA_INTERFACE_UPDATE_IN_PROCESS) { - DEF_DEBUG(DEB_F_PREFIX" MEDIA_INTERFACE_UPDATE is already in process. " - " Ignore another update event.\n", DEB_F_PREFIX_ARGS(FSM, "fsmdef_transition_to_connected")); - } - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED_MEDIA_PEND); - return (sm_rc); -} - -static sm_rcs_t -fsmdef_ev_connected (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_connected"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_connected_t *msg = (cc_connected_t *) event->msg; - cc_causes_t cause; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb->send_release = TRUE; - - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - // Reset dcb->active_feature flag - dcb->active_feature = CC_FEATURE_NONE; - - /* Reset spoof ring out in case t was set before going to connected state. */ - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - - if ( dcb->log_disp != CC_CALL_LOG_DISP_UNKNWN ) { - ui_log_disposition(dcb->call_id, dcb->log_disp ); - } - - - ui_cc_capability(dcb->line, lsm_get_ui_id(dcb->call_id), msg->recv_info_list); - - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - (void)fsmdef_release(fcb, CC_CAUSE_NO_MEDIA, dcb->send_release); - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_END); - } - cc_int_connected_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED_ACK); - -// fsmdef_update_pd(dcb, FSMDEF_CALL_TYPE_OUTGOING); - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - sm_rc = fsmdef_transition_to_connected(fcb); - fsmutil_set_shown_calls_ci_element(dcb->caller_id.call_instance_id, dcb->line); - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_connected_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_connected_ack_t *msg = (cc_connected_ack_t *) event->msg; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check the remote SDP. The far end may not have included the SDP in an - * earlier message, which means that the SDP must be in this message. - */ - if (dcb->remote_sdp_in_ack == TRUE) { - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - (void)fsmdef_release(fcb, CC_CAUSE_NO_MEDIA, dcb->send_release); - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_END); - } - -// fsmdef_update_pd(dcb, FSMDEF_CALL_TYPE_INCOMING); - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - return (fsmdef_transition_to_connected(fcb)); -} - -/** - * The function handles local hold event but not sending any hold request - * out to the remote end. The local SDP is updated by the way. - * - * @param[in]fcb - pointer to fsm_fcb_t - * - * @return SM_RC_END or failrue. - * - * @pre (fcb not_eq NULL) - */ -static sm_rcs_t -fsm_hold_local_only (fsm_fcb_t *fcb) -{ - static const char fname[] = "fsm_hold_local_only"; - cc_state_data_t state_data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check local hold status, and allow request if the media is not - * locally held. - */ - if (fsmdef_all_media_are_local_hold(dcb)) { - /* - * a new hold request is not allowed. Ignore the request - * but we should still ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_HOLD, NULL, CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - fname, "already hold"); - - return (SM_RC_END); - } - - state_data.hold.caller_id = dcb->caller_id; - state_data.hold.local = TRUE; - - /* - * Update the SDP so that offer indicates hold. Reinitialize the local - * sdp media to include all available codecs. We do this because our local - * list has been shortened to the one negotiated codec. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, TRUE); - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD, &state_data); - - /* set all the media to local hold */ - fsmdef_update_media_hold_status(dcb, NULL, TRUE); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLDING); - - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT | CCSIP_SRC_SDP_BIT, - &dcb->sdp); - - return (SM_RC_END); -} - -/** - * The function handles local hold event. The function also supports - * re-sending hold request out such as during a glare condition. - * - * @param[in]fcb - pointer to fsm_fcb_t - * @param[in]data_p - pointer to the cc_feature_data_t of the - * hold feature. - * @param[in]resend - TRUE indicates to resend hold request. - * - * @return SM_RC_END or failrue. - * - * @pre (fcb not_eq NULL) - * @pre (data_p not_eq NULL) - */ -static sm_rcs_t -fsm_hold_local (fsm_fcb_t *fcb, cc_feature_data_t *data_p, - boolean resend) -{ - static const char fname[] = "fsm_hold_local"; - cc_state_data_t state_data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check local hold status, and allow request if the media is not - * locally held or the caller indicates that to resend the hold - * request (such as in glare resolution). - */ - if (!resend && fsmdef_all_media_are_local_hold(dcb)) { - /* - * a new hold request is not allowed. Ignore the request - * but we should still ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_HOLD, NULL, - CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - fname, "already hold"); - return (SM_RC_END); - } - - state_data.hold.caller_id = dcb->caller_id; - state_data.hold.local = TRUE; - state_data.hold.reason = data_p->hold.call_info.data.hold_resume_reason; - - /* Store hold reason in case we need to resend the hold request due to - * request pending response. - */ - dcb->hold_reason = data_p->hold.call_info.data.hold_resume_reason; - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - - fsmdef_get_rtp_stat(dcb, &(data_p->hold.kfactor)); - - /* put the call on hold before building the SDP as DSP - * will then be able to give us a full set of codecs - * CUCM doesn't like to see a change in codecs on the fly - * ( i.e. without going to inactive state ) */ - cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD, &state_data); - - /* - * Update the SDP so that offer indicates hold. Reinitialize the local - * sdp to include all available codecs. We do this because our - * local list has been shortened to the one negotiated codec. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, TRUE); - - /* - * Do not expect any msg. body from local hold but free them - * just in case before build new SDP body to send out. - */ - cc_free_msg_body_parts(&data_p->hold.msg_body); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &data_p->hold.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* set all the media to local hold */ - fsmdef_update_media_hold_status(dcb, NULL, TRUE); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, data_p); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLDING); - - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT | CCSIP_SRC_SDP_BIT, - &dcb->sdp); - - return (SM_RC_END); -} - -/** - * Handles hold feature in connected media update pending state. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * @param[in] data_p pointer to the cc_feature_data_t. - * - * @return sm_rsc_t indicates whether the execution of - * next statmachine to end or to clean up. - */ -static sm_rcs_t -fsm_connected_media_pend_local_hold (fsm_fcb_t *fcb, cc_feature_data_t *data_p) -{ - static const char fname[] = "fsm_hold_local_connected_media_pend"; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check local hold status, and allow request if the media is not - * locally held. - */ - if (fsmdef_all_media_are_local_hold(dcb)) { - /* - * a new hold request is not allowed. Ignore the request - * but we should still ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_HOLD, NULL, - CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - fname, "already hold"); - return (SM_RC_END); - } - - /* - * We have sent media capability update out but have not received - * any response yet. The glare condition may occur but we can only - * assume that the media update was sent out at this point. - * We can not send out any more request until the result is - * known. We can not do any thing now but simply remember - * to re-send media with the hold feature pending when - * the result is known. - */ - FSM_SET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - return (SM_RC_END); -} - -/** - * common function to handles media feature from remote end. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * @param[in] msg The pointer to cc_feature_t. - * - * @return sm_rsc_t indicates whether the execution of - * next statmachine to end or to clean up. - */ -static sm_rcs_t -fsmdef_remote_media (fsm_fcb_t *fcb, cc_feature_t *msg) -{ - static const char fname[] = "fsmdef_remote_media"; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - cc_causes_t cause; - boolean send_ack = TRUE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - memset(&feature_data, 0 , sizeof(cc_feature_data_t)); - /* - * Determine what type of RESUME/MEDIA this is: - * 1. third-party control is just trying to change the media - - * midcall-invite with no SDP, so we need to wait for the SDP - * in the SIP ACK before we can truly resume the media. - * 2. remote end wants to resume a held call or just a media - * changes. - * - * We can distinguish between the two because case 1 will not - * have any data and case 2 will have data. - */ - if (msg->data_valid == FALSE) { - /* - * Case 1. - * - * negotiate offer without SDP will reset all local media entries - * to have all codecs included. This is to re-advertise the - * capabilities again. - */ - (void) gsmsdp_negotiate_offer_sdp(fcb, NULL, FALSE); - - /* - * Update the media direction based on whether each media - * stream is locally held or not before sending out the - * offer SDP. - */ - fsmdef_set_per_media_local_hold_sdp(dcb); - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_MEDIA, - NULL); - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_START_RCV, - NULL); - } else { - /* - * SIP may send MEDIA feature when answer SDP is received in - * ACK. The secnario is found when remote resumes and the - * resume INVITE is a delayed media INVITE. We sent an offer in - * the 200 OK and gets the answer back in the ACK. In this - * case, SIP will send MEDIA feature to GSM. We need to check - * whether we are waiting for an answer in ACK or not and - * use the corresponding offer/answer SDP negotiation function. - */ - if (dcb->remote_sdp_in_ack) { - cause = gsmsdp_negotiate_answer_sdp(fcb, - &data->resume.msg_body); - if (cause != CC_CAUSE_OK) { - /* - * There is some thing wrong the answer SDP for some - * reason, can not go on. - */ - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * This is the answer to our previous offer, no need to - * to ack to SIP this one. - */ - send_ack = FALSE; - } else { - /* This is a new offer */ - - /* - * get k factor to be included in the feature ack. Getting - * the k factor needs to be done before maniputate media - * stream by the LSM. - */ - fsmdef_media_t *media = gsmsdp_find_audio_media(dcb); - if ((media) && (media->direction != SDP_DIRECTION_INACTIVE)) { - fsmdef_get_rtp_stat(dcb, &(feature_data.resume.kfactor)); - } - - cause = gsmsdp_negotiate_offer_sdp(fcb, - &data->resume.msg_body, FALSE); - if (cause != CC_CAUSE_OK) { - /* - * Received a sdp that cannot be accepted. - * It should just reject the new sdp offer rather than - * tearing down the call. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, msg->feature_id, NULL, cause); - return (SM_RC_END); - } - /* - * Update the media based on local hold. - */ - fsmdef_set_per_media_local_hold_sdp(dcb); - } - - /* - * If spoof ringout is not being requested and we are currently - * playing spoof ringout, transition the LSM from the far end alerting - * to the connected state. - */ - if ((!dcb->spoof_ringout_requested) && (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } else { - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_MEDIA, - NULL); - } - } - - if (send_ack) { - /* Build SDP from our current SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, msg->feature_id, &feature_data, - CC_CAUSE_NORMAL); - } - return (SM_RC_END); -} - -/** - * - * Function to handles connected state feature events. Function handles - * feature events generated by GSM, UI and SIP stack. - * - * @param sm_event_t event - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb->dcb not_eq NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_connected_feature (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_connected_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - sm_rcs_t sm_rc; - cc_feature_data_t feature_data; - cc_action_data_t action_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (msg->feature_id) { - case CC_FEATURE_HOLD: - /* If the line number is 0xFF, then this request - * came from GSM during a Transfer. We want to - * put the call on local hold only. We do not want - * to send a cc_feature to the SIP stack because - * that will cause an Invite Hold to go via SIP. - * We don't want to put the other end on hold, just - * ourselves. - */ - if (msg->line == 0xFF) { - sm_rc = fsm_hold_local_only(fcb); - } else { - if (msg->data_valid) { - sm_rc = fsm_hold_local(fcb, data, FALSE); - } else { - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_hold_local(fcb, &feature_data, FALSE); - } - - } - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_JOIN: - /* - * Send offhook to the new call that triggers the - * completion of the setup of the join in call - */ - fsmdef_ev_join(data); - break; - - case CC_FEATURE_SELECT: - if (msg->data_valid == FALSE) { - fsmdef_select_invoke(dcb, NULL); - } else { - fsmdef_select_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_B2B_JOIN: - if (msg->data_valid == FALSE) { - fsmdef_b2bjoin_invoke(dcb, NULL); - } else { - fsmdef_b2bjoin_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_DIRTRXFR: - case CC_FEATURE_UNDEFINED: - fsm_display_feature_unavailable(); - - fsmdef_handle_join_pending(dcb); - return (SM_RC_END); - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - // Force an re-INVITE by mismatching the id - dcb->media_cap_tbl->id--; - /* FALL THRU */ - case CC_FEATURE_UPD_MEDIA_CAP: - /* - * Media capability update request, check to see if - * there is any change in media capability and transition - * the pending state or stay in the connected state. - */ - sm_rc = fsmdef_transition_to_connected(fcb); - return (sm_rc); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsmdef_handle_join_pending(dcb); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (msg->feature_id) */ - - break; - - case CC_SRC_SIP: - switch (msg->feature_id) { - - case CC_FEATURE_MEDIA: - /* - * remote send media update which can be resume or - * or just media changes. - */ - sm_rc = fsmdef_remote_media(fcb, msg); - return (sm_rc); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - action_data.update_ui.action = CC_UPDATE_CALL_PRESERVATION; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - fsm_change_state(fcb, __LINE__, FSMDEF_S_PRESERVED); - break; - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - case CC_FEATURE_UPDATE: - /* - * We only get an UPDATE feature event if we receive a medialess UPDATE. - * This type of event only conveys UI updates that are processed with - * a call info event. We do perform one check to see if we are currently - * spoofing ringout. If we are and the spoof ringout requested flag - * has been cleared, we tell the LSM to go connected. - */ - if ((!dcb->spoof_ringout_requested) && (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - - /* - * For chaperone call, we will update call state here, to update - * the related key's status. - */ - if(dcb->policy == CC_POLICY_CHAPERONE){ - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - break; - - case CC_FEATURE_FAST_PIC_UPD: - - vcmMediaControl(CREATE_CALL_HANDLE(dcb->line, dcb->call_id), VCM_MEDIA_CONTROL_PICTURE_FAST_UPDATE); - - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (msg->feature_id) */ - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -/** - * - * Function to handles connected state media update pending feature. - * - * @param sm_event_t event - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb->dcb not_eq NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_connected_media_pend_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - sm_rcs_t sm_rc = SM_RC_END; - cc_feature_data_t feature_data; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (msg->feature_id) { - case CC_FEATURE_HOLD: - /* If the line number is 0xFF, then this request - * came from GSM during a Transfer. We want to - * put the call on local hold only. We do not want - * to send a cc_feature to the SIP stack because - * that will cause an Invite Hold to go via SIP. - * We don't want to put the other end on hold, just - * ourselves. - */ - if (msg->line == 0xFF) { - sm_rc = fsm_hold_local_only(fcb); - } else { - if (msg->data_valid) { - sm_rc = fsm_connected_media_pend_local_hold(fcb, data); - } else { - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_connected_media_pend_local_hold(fcb, - &feature_data); - } - } - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - /* FALL THRU */ - case CC_FEATURE_UPD_MEDIA_CAP: - /* We are already in the media update state */ - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - return (SM_RC_END); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - /* - * Glare resolution timer expires. - */ - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING)) { - /* There is a hold feature pending, send out hold instead */ - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - return (fsm_hold_local(fcb, &feature_data, FALSE)); - } - - /* - * Check the possible media capbility changes. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, FALSE, FALSE); - feature_data.resume.call_info.type = CC_FEAT_NONE; - feature_data.resume.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &feature_data.resume.msg_body); - - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return(fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* Send feature request to SIP */ - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_MEDIA, &feature_data); - return (SM_RC_END); - - default: - /* - * The rest of the feature handles the same way as the - * connected feature handling. - */ - break; - } /* switch (msg->feature_id) */ - break; - - default: - /* - * The rest of the feature handles the same way as the - * connected feature handling. - */ - break; - } - - /* - * Unhandled features are handled by the normal connected feature - */ - return (fsmdef_ev_connected_feature(event)); -} - -/** - * - * Function to handles connected media update pending state feature ack - * events. - * - * @param sm_event_t event - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb->dcb not_eq NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_connected_media_pend_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_connected_media_pend_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_features_t ftr_id = msg->feature_id; - cc_srcs_t src_id = msg->src_id; - cc_feature_data_t feature_data; - sm_rcs_t sm_rc = SM_RC_END; - cc_msgbody_info_t *msg_body; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - switch (src_id) { - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_MEDIA: - /* Media update feature ack from SIP */ - - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - /* - * The glare condition occurs from the previously sent - * media update. Starts a request pending timer so that - * we retry. - */ - fsmdef_set_req_pending_timer(dcb); - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING)) { - /* - * Feature hold is pending, abort the media capability - * update and retry with hold instead. - */ - FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING); - } - return (SM_RC_END); - } - - /* Check for error code reported */ - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - /* Unable to send media request */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG2), - dcb->call_id, dcb->line, fname, - " Media request failed, cause= ", msg->cause); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - msg_body = &msg->data.resume.msg_body; - cause = gsmsdp_negotiate_answer_sdp(fcb, msg_body); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * Check to see if we have a feature request pending - */ - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING)) { - /* There is a hold feature pending, send out hold instead */ - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - sm_rc = fsm_hold_local(fcb, &feature_data, FALSE); - } else { - /* - * If spoof ringout is not being requested and we are - * currently playing spoof ringout, transition the LSM from - * the far end alerting to the connected state. - */ - if ((!dcb->spoof_ringout_requested) && - (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } else { - (void)cc_call_action(dcb->call_id, dcb->line, - CC_ACTION_MEDIA, NULL); - } - - /* - * Check any media capability changes that might occurs - * while we were in the middle of the previous transaction. - */ - sm_rc = fsmdef_transition_to_connected(fcb); - if (g_dock_undock_event != MEDIA_INTERFACE_UPDATE_NOT_REQUIRED) { - if (is_gsmsdp_media_ip_updated_to_latest(dcb) == TRUE) { - ui_update_media_interface_change(dcb->line, dcb->call_id, MEDIA_INTERFACE_UPDATE_SUCCESSFUL); - } else { - DEF_DEBUG("We must have received another MEDIA_INTERFACE_UPDATE events " - " while current MEDIA_INTERFACE_UPDATE event is in procoess. Sending re-invite again"); - escalateDeescalate(); - } - } - } - return (sm_rc); - - default: - break; - } - break; - - default: - break; - } - - /* call default feature ack handler to take common/default actions*/ - (void) fsmdef_ev_default_feature_ack(event); - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_action_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * User has gone offhook while using the speaker. - */ - data.speaker.on = FALSE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_SPEAKER, &data); - - //lsm_set_active_call_id(dcb->call_id); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_connected_line (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - return (fsmdef_transition_to_connected(fcb)); -} - - -static sm_rcs_t -fsmdef_ev_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - sm_rcs_t sm_rc; - cc_action_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* currently this flag is only set by conference case. It signals - * that onhook has been received, do not process it anymore. - */ - if (dcb->onhook_received) { - dcb->onhook_received = FALSE; - return SM_RC_END; - } - - /* - * If the user presses the ENDCALL softkey for an - * incoming call set the release cause to Busy. - */ - if (fcb->state == FSMDEF_S_INCOMING_ALERTING) { - sm_rc = fsmdef_release(fcb, CC_CAUSE_BUSY, dcb->send_release); - } else { - dcb->early_error_release = FALSE; - sm_rc = fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release); - } - - if (sm_rc == SM_RC_CLEANUP) { - /* This dcb has been cleaned up, do nothing more */ - return (sm_rc); - } else if (fcb->state == FSMDEF_S_HOLDING || - fcb->state == FSMDEF_S_HOLD_PENDING) { - data.ringer.on = TRUE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_RINGER, &data); - sm_rc = SM_RC_END; - } else { - sm_rc = SM_RC_END; - } - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb->send_release = FALSE; - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - if (msg->cause == CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE) { - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_FAILED, CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE); - - /* what to return for return code */ - return(SM_RC_SUCCESS); - } else { - return (fsmdef_release(fcb, msg->cause, dcb->send_release)); - } -} - - -static sm_rcs_t -fsmdef_ev_releasing_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* see if the SIP stack has aborted this call early for some reason - * If SIP brought this down, we are still offhook on the UI. We - * need to ignore it, so that reorder can be played AND when the user - * hangs up, then the UI will be driven to a clean state. - */ - if (fcb->dcb->early_error_release == FALSE) { - - cc_int_release_complete(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - msg->cause, NULL); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_IDLE); - - fsmdef_free_dcb(dcb); - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - fsm_release(fcb, __LINE__, msg->cause); - - return (SM_RC_CLEANUP); - } else { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SM_DEFAULT_EVENT)); - return (SM_RC_END); - } -} - - -static sm_rcs_t -fsmdef_ev_releasing_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - sm_rcs_t sm_rc = SM_RC_END; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (ftr_id) { - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - /* Clean up call chain, no release sent */ - return (fsmdef_release(fcb, cause, FALSE)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_releasing_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* Clean up call chain, no release sent */ - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, FALSE)); -} - - -static sm_rcs_t -fsmdef_ev_release_complete (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (fcb->dcb == NULL) { - return (SM_RC_CLEANUP); - } - /* see if the SIP stack has aborted this call early for some reason - * If SIP brought this down, we are still offhook on the UI. We - * need to ignore it, so that reorder can be played AND when the user - * hangs up, then the UI will be driven to a clean state. - */ - if (fcb->dcb->early_error_release == FALSE) { - - fsm_change_state(fcb, __LINE__, FSMDEF_S_IDLE); - - fsmdef_free_dcb(fcb->dcb); - - fsm_release(fcb, __LINE__, - ((cc_release_complete_t *) (event->msg))->cause); - - return (SM_RC_CLEANUP); - - } else { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SM_DEFAULT_EVENT)); - return (SM_RC_END); - } -} - -static sm_rcs_t -fsmdef_ev_hold_pending_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = NULL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_UI): - case (CC_SRC_GSM): - switch (ftr_id) { - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - - case CC_FEATURE_RESUME: - /* - * We will not be able to resume this call since we are in the - * hold pending state but we can place any other active call - * on hold. Find the connected call (if there is one) and place - * it on hold but not call if it is involved in a conference. - */ - if (msg->data.resume.cause != CC_CAUSE_CONF) { - if (fsmdef_wait_to_start_new_call(TRUE, src_id, call_id, line, - CC_FEATURE_RESUME, NULL)) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb != NULL) { - ccb->cnf_ftr_ack = FALSE; - } - } - } - return (SM_RC_END); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_hold_local(fcb, &feature_data, TRUE); - return sm_rc; - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_MEDIA: - return (fsmdef_remote_media(fcb, msg)); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -/** - * feature ack event handler in hold pending state. - * - * @param[in] event Pointer to sm_event_t structure for feature ack event. - * - * @return Value of type sm_rcs_t to state machine - * - * @pre (event not_eqs NULL) and - * (event->data not_eqs NULL) and - * ((fsm_fcb_t *)(event->data)->dcb not_eqs NULL) - */ -static sm_rcs_t -fsmdef_ev_hold_pending_feature_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - cc_msgbody_info_t *msg_body; - cc_feature_data_t feature_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_RESUME: - /* - * This is feature ack for resume. We received resume - * feature ack because the hold request was received while - * we are waiting to resume i.e. was in the - * resume pending state and resume request has been sent out. - * - * If the resume ack indicates glare, then ignore sending the - * resume and transition to holding (we were in hold and - * unable to send RESUME). Otherwise send hold out right away - * if there is no other error. - */ - fsm_sm_ftr(ftr_id, src_id); - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - /* - * The glare condition occurs from the previously sent - * resume transition to holding. - */ - (void)fsm_hold_local_only(fcb); - break; - } - - /* call default feature ack handler to take common/default actions*/ - (void) fsmdef_ev_default_feature_ack(event); - - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - if (msg->data_valid != TRUE) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - msg_body = &msg->data.resume.msg_body; - cause = gsmsdp_negotiate_answer_sdp(fcb, msg_body); - if (cause != CC_CAUSE_OK) { - return(fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * HOLD can be sent now. - */ - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - fsm_hold_local(fcb, &feature_data, FALSE); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_holding_release (sm_event_t *event) -{ - cc_release_t *msg = (cc_release_t *) event->msg; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (msg->cause != CC_CAUSE_XFER_LOCAL) { - fcb->dcb->send_release = FALSE; - } - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - return (fsmdef_release(fcb, msg->cause, fcb->dcb->send_release)); -} - -static sm_rcs_t -fsmdef_ev_holding_onhook (sm_event_t *event) -{ - cc_onhook_t *msg = (cc_onhook_t *) event->msg; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (!(msg->softkey)) { - /* Meaning Hangup, ignore, a held call can't be hung up */ - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SM_DEFAULT_EVENT)); - return (SM_RC_END); - } - - /* - * Meaning EndCall softkey is sent, take down - * the call, this happens during failover. - */ - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); -} - -/** - * - * fsmdef_reversion_timeout - Triggers LSM for doing Reversion alerts. - * - * @param fsmdef_dcb_t dcb for this call - * - * @return none - * - * @pre (dcb not_eq NULL) - */ - -void fsmdef_reversion_timeout(callid_t call_id) -{ - - int ret = CPR_SUCCESS; - - fsmdef_dcb_t *dcb = fsmdef_get_dcb_by_call_id(call_id) ; - - if ( (dcb == NULL ) || (dcb->fcb == NULL)) { - return; - } - - // check that we are in HOLDING state before proceeding - if ((dcb->fcb->state != FSMDEF_S_HOLDING) && - (dcb->fcb->state != FSMDEF_S_HOLD_PENDING)) { - return; - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD_REVERT, NULL); - -} - - -/** - * - * fsmdef_resume - Performs Resume Operation. - * - * @param sm_event_t event - * - * @return sm_rcs_t SM_RC_END - indicating the event has been consumed - * - * @pre (event not_eq NULL) - */ - -static void -fsmdef_resume (sm_event_t *event) -{ - - static const char fname[] = "fsmdef_resume"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = NULL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_feature_data_t *data = &(msg->data); - cc_srcs_t src_id = msg->src_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t feature_data; - cc_causes_t cause; - boolean req_pending_tmr_running = FALSE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Ignore the request if local hold is not active. - */ - if (fsmdef_num_media_in_local_hold(dcb) == 0) { - /* - * No media in local held, should not happen here. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_RESUME, NULL, - CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), call_id, dcb->line, - fname, "resume media not in hold state\n"); - return; - } - - /* - * Make sure the connected call (if there is one) goes on hold, - * but do not hold the connected call if it is involved in a - * conference. - */ - if (msg->data.resume.cause != CC_CAUSE_CONF) { - if (fsmdef_wait_to_start_new_call(TRUE, src_id, call_id, line, - CC_FEATURE_RESUME, (msg->data_valid ? - data : NULL))) { - - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb != NULL) { - ccb->cnf_ftr_ack = FALSE; - } - return ; - } - } - - /* Clear all media holding status */ - fsmdef_update_media_hold_status(dcb, NULL, FALSE); - - if (!req_pending_tmr_running) { - /* - * Reinitialize the local sdp to include all available codecs. - * We do this because it is possible that our local list - * may have been shortened to the one negotiated codec. This is - * the case when we receive an incoming call, we negotiate a - * single codec, copy it into the local sdp and send it back - * in the connected msg. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, FALSE); - - if (msg->data_valid) { - feature_data.resume.call_info = data->resume.call_info; - } else { - feature_data.resume.call_info.type = CC_FEAT_RESUME; - feature_data.resume.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - } - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - (void)fsmdef_release(fcb, cause, dcb->send_release); - return ; - } - } - - /* - * If spoof ringout is currently requested, transition to the - * far end alerting state instead of the connected state. - */ - if (dcb->spoof_ringout_requested) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, - "setting spoof_ringout_applied"); - - dcb->spoof_ringout_applied = TRUE; - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_FAR_END_ALERTING, FSMDEF_CC_CALLER_ID); - } else { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - /* Start receiving but not transmit, before sending resume */ - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_START_RCV, - NULL); - } - - if (!req_pending_tmr_running) { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_RESUME, &feature_data); - } - - /* - * We lock the UI until we learn the result of the resume request - */ - fim_lock_ui(call_id); - - /* Wait for feature ack */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_RESUME_PENDING); - - return ; - -} - -/** - * - * fsmdef_ev_holding_offhook - Handles offhook in for holding state. - * - * @param sm_event_t event - * - * @return sm_rcs_t SM_RC_END - indicating the event has been consumed - * - * @pre (event not_eq NULL) - */ - -static sm_rcs_t -fsmdef_ev_holding_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - return SM_RC_END; - -} - -static sm_rcs_t -fsmdef_ev_holding_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_UI): - case (CC_SRC_GSM): - switch (ftr_id) { - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - - case CC_FEATURE_HOLD: - if (msg->data_valid) { - sm_rc = fsm_hold_local(fcb, data, FALSE); - } else { - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_hold_local(fcb, &feature_data, FALSE); - } - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_HOLD_REVERSION: - - // Do not revert if alertInterval is negative - if ( data->hold_reversion.alertInterval < 0 ) - return SM_RC_END; - // interval timer of 0 implies continue to revert - // Clamp the interval to be in MIN/MAX_HOLD_REVERSION_INTERVAL_TIMER - if ( data->hold_reversion.alertInterval > 0 && - data->hold_reversion.alertInterval < MIN_HOLD_REVERSION_INTERVAL_TIMER ) - data->hold_reversion.alertInterval = MIN_HOLD_REVERSION_INTERVAL_TIMER; - - if ( data->hold_reversion.alertInterval > MAX_HOLD_REVERSION_INTERVAL_TIMER ) - data->hold_reversion.alertInterval = MAX_HOLD_REVERSION_INTERVAL_TIMER; - - fsmdef_reversion_timeout(fcb->dcb->call_id); - - fsmdef_handle_join_pending(dcb); - return SM_RC_END; - - case CC_FEATURE_RESUME: - fsmdef_resume(event); - break; - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_SELECT: - if (msg->data_valid == FALSE) { - fsmdef_select_invoke(dcb, NULL); - } else { - fsmdef_select_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_B2B_JOIN: - if (msg->data_valid == FALSE) { - fsmdef_b2bjoin_invoke(dcb, NULL); - } else { - fsmdef_b2bjoin_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_DIRTRXFR: - case CC_FEATURE_UNDEFINED: - fsm_display_feature_unavailable(); - - fsmdef_handle_join_pending(dcb); - return (SM_RC_END); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - /* Ignore the request pending timer when in holding state */ - default: - fsmdef_handle_join_pending(dcb); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_MEDIA: - return (fsmdef_remote_media(fcb, msg)); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_holding_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_holding_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause = msg->cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - switch (src_id) { - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_HOLD: - if (cause == CC_CAUSE_REQUEST_PENDING) { - /* - * If this is feature ack for hold and request is pending, - * set a request pending timer so that we retry the hold - * feature request. - */ - fsmdef_set_req_pending_timer(dcb); - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING); - return (SM_RC_END); - } - - /* Check for error code reported */ - if ((cause != CC_CAUSE_NORMAL) && - (cause != CC_CAUSE_OK)) { - /* Unable to send hold request */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG2), - dcb->call_id, dcb->line, fname, - "HOLD request failed, cause= ", cause); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - // update video_avail as we are not negotiating the answer below - dcb->cur_video_avail = SDP_DIRECTION_INACTIVE; - lsm_update_video_avail(dcb->line, dcb->call_id, dcb->cur_video_avail); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - /* call default feature ack handler to take common/default actions */ - (void) fsmdef_ev_default_feature_ack(event); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_resume_pending_feature (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_resume_pending_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - sm_rcs_t sm_rc; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_UI): - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - - case CC_FEATURE_END_CALL: - fim_unlock_ui(call_id); - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - case CC_FEATURE_HOLD: - /* - * The UI should be locked but the hold event from UI here - * can be the result of other call chain wants to put this - * other call that may be in conected state or in resume - * pending state on hold. One example, the user want to - * resume a call that is on hold, that call chain will look - * for any other call in connected state or call in resume - * pending (about to be connected) and puts this call on hold. - * - * There are 2 choices here. If we are in this state and has - * not sent a resume out to the network, then simply - * transition to holding state. If resume has already - * been sent and we are here waiting for resume pending ack, - * then we can not send out hold immediately. In the later - * case, go to hold pending state and wait for resume - * feature ack to send hold out. - * - * In either case, UI can be unlocked since we are now - * about to hold again. - */ - fim_unlock_ui(dcb->call_id); - /* - * We have sent resume to the network and wait for - * for the feature ack. The glare condition can - * occur but we can only assume that resume was sent out - * at this point. We can not send out any more request - * until the result is known. - */ - if (msg->data_valid) { - dcb->hold_reason = - data->hold.call_info.data.hold_resume_reason; - } else { - dcb->hold_reason = CC_REASON_NONE; - } - // since we are going to hold stop the media now - // else the next new call or resume will result in 2 sets of media ports open - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_MEDIA, - NULL); - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - case (CC_SRC_GSM): - switch (ftr_id) { - - case CC_FEATURE_HOLD: - sm_rc = fsm_hold_local_only(fcb); - fim_unlock_ui(call_id); - return (sm_rc); - - case CC_FEATURE_END_CALL: - fim_unlock_ui(call_id); - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - - /* - * Reinitialize the local sdp to include all available codecs. - * We do this because it is possible that our local list - * may have been shortened to the one negotiated codec. This is - * the case when we receive an incoming call, we negotiate a - * single codec, copy it into the local sdp and send it back - * in the connected msg. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, FALSE); - - feature_data.resume.call_info.type = CC_FEAT_RESUME; - feature_data.resume.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * We lock the UI until we learn the result of the resume request. - */ - fim_lock_ui(call_id); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_RESUME, &feature_data); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_MEDIA: - return (fsmdef_remote_media(fcb, msg)); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - fim_unlock_ui(call_id); - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - case CC_FEATURE_UPDATE: - /* - * We only get an UPDATE feature event if we receive a medialess UPDATE. - * This type of event only conveys UI updates that are processed with - * a call info event. We do perform one check to see if we are currently - * spoofing ringout. If we are and the spoof ringout requested flag - * has been cleared, we tell the LSM to go connected which halts the - * spoofed ringout. - */ - if ((!dcb->spoof_ringout_requested) && (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -/** - * feature ack event handler in resume pending state. - * - * @param[in] event Pointer to sm_event_t structure for feature ack event. - * - * @return Value of type sm_rcs_t to state machine - * - * @pre (event not_eqs NULL) and - * (event->data not_eqs NULL) and - * ((fsm_fcb_t *)(event->data)->dcb not_eqs NULL) - */ -static sm_rcs_t -fsmdef_ev_resume_pending_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_resume_pending_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - cc_msgbody_info_t *msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_HOLD: - /* - * This can occur because SIP stack has not sent HOLD out yet - * but the user has pressed resume since we already moved - * to HOLD state as soon as the user pressed HOLD. Ignore the - * HOLD feature ACK except if it indicates error. If we get - * REQUEST_PENDING, we'll just move to connected state. - */ - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED); - return (SM_RC_END); - } - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_FEATURE_RESUME: - /* - * If this is feature ack for resume and request is pending, - * set a request pending timer so that we retry the resume - * feature request. Otherwise, unlock the UI and continue - * processing. - */ - fsm_sm_ftr(ftr_id, src_id); - if ( msg->cause == CC_CAUSE_REQUEST_PENDING ) { - fsmdef_set_req_pending_timer(dcb); - return (SM_RC_END); - } else { - fim_unlock_ui(dcb->call_id); - } - /* call default feature ack handler to take common/default actions*/ - (void) fsmdef_ev_default_feature_ack(event); - - if ((msg->cause == CC_CAUSE_SERV_ERR_UNAVAIL) && - (dcb->hold_reason == CC_REASON_MONITOR_UPDATE)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, - "msg->cause == CC_CAUSE_SERV_ERR_UNAVAIL, unable to monitor update\n"); - return (fsmdef_transition_to_connected(fcb)); - } - - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - if (msg->data_valid != TRUE) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - msg_body = &msg->data.resume.msg_body; - cause = gsmsdp_negotiate_answer_sdp(fcb, msg_body); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - if (!dcb->spoof_ringout_applied) { - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - /* - * Handle media capability changes if there is before transition - * to connected state to catch any changes during resume - * transaction. - */ - return (fsmdef_transition_to_connected(fcb)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - /* call default feature ack handler to take common/default actions */ - (void) fsmdef_ev_default_feature_ack(event); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_preserved_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (msg->feature_id) { - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } - - break; - - case CC_SRC_SIP: - switch (msg->feature_id) { - case CC_FEATURE_HOLD: - case CC_FEATURE_RESUME: - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - case CC_FEATURE_MEDIA: - sm_rc = fsmdef_remote_media(fcb, msg); - return (sm_rc); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (msg->feature_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -cc_int32_t -fsmdef_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - int i = 0; - callid_t call_id; - unsigned long strtoul_result; - char *strtoul_end; - - /* - * Check if need help. - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("show fsmdef [all|rel]\n"); - } else if ((argc == 1) || (strcmp(argv[1], "all") == 0)) { - debugif_printf("\n-------- FSMDEF dcbs --------"); - debugif_printf("\ni call_id dcb line"); - debugif_printf("\n-----------------------------\n"); - - /* - * Print info for all dcbs. - */ - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - debugif_printf("%-2d %-7d 0x%8p %-4d\n", - i++, dcb->call_id, dcb, dcb->line); - } - } else if (strcmp(argv[1], "rel") == 0) { - errno = 0; - strtoul_result = strtoul(argv[2], &strtoul_end, 10); - - if (errno || argv[2] == strtoul_end || strtoul_result > USHRT_MAX) { - debugif_printf("%s parse error of call_id %s", __FUNCTION__, argv[2]); - return 0; - } - - call_id = (callid_t) strtoul_result; - - debugif_printf("\nDEF %-4d/%d: releasing\n", call_id, 0); - - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if (fcb == NULL) { - return (0); - } - - (void)fsmdef_release(fcb, CC_CAUSE_NORMAL, fcb->dcb->send_release); - } - return (0); -} - -/** - * - * This function is called to determine if the phone - * is in a state where autoAnswer is supported. Even - * if the feature is enabled on the line being called, - * the phone may be in a state that does not allow it. - * - * @param autoAnswerAlt to indicate what states auto answer enabled. - * @param myCallId call_id - * - * @return TRUE or FALSE - * - */ -static int -fsmdef_check_auto_answer_allowed (int autoAnswerAlt, callid_t myCallId) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != myCallId && dcb->fcb != NULL) { - /* - * autoAnswer is disabled if there is an incoming or an - * outgoing call that has not reached the connected state - * regardless of the value of autoAnswerAlt. - */ - if ((dcb->fcb->state == FSMDEF_S_COLLECT_INFO) || - (dcb->fcb->state == FSMDEF_S_CALL_SENT) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_PROCEEDING) || - (dcb->fcb->state == FSMDEF_S_KPML_COLLECT_INFO) || - (dcb->fcb->state == FSMDEF_S_CONNECTING) || - (dcb->fcb->state == FSMDEF_S_JOINING)) { - return (FALSE); - } - - /* - * If autoAnswerAlt is 1, then autoAnswer is also - * disabled if there is a connected call or a call - * on hold. - */ - if (autoAnswerAlt == 1) { - if ((dcb->fcb->state == FSMDEF_S_CONNECTED) || - (dcb->fcb->state == FSMDEF_S_PRESERVED) || - (dcb->fcb->state == FSMDEF_S_RESUME_PENDING) || - (dcb->fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND) || - (dcb->fcb->state == FSMDEF_S_HOLDING) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_ALERTING) || - (dcb->fcb->state == FSMDEF_S_INCOMING_ALERTING) || - (dcb->fcb->state == FSMDEF_S_HOLD_PENDING)) { - - return (FALSE); - } - } else if (autoAnswerAlt == 0) { - if ((dcb->fcb->state == FSMDEF_S_CONNECTED) || - (dcb->fcb->state == FSMDEF_S_PRESERVED) || - (dcb->fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_ALERTING)) { - - return (FALSE); - } - } - } - } - - return (TRUE); -} - -/** - * - * This function is called when a call is received on a - * line that has auto answer enabled and the autoAnswer - * timer has expired. - * - * @param data pointer to opaque data - * - * @return none - * - * @pre (fcb and fcb->dcb not_eq NULL) - * @pre (data should be fcb data) - */ - -void -fsmdef_auto_answer_timeout (void *data) -{ - static const char fname[] = "fsmdef_auto_answer_timeout"; - int autoAnswerAlternate = 0; - int autoAnswerOverride = 0; - int headSetActive = 0; - int speakerEnabled = 1; - callid_t call_id; - char autoAnswerMode[MAX_LINE_AUTO_ANS_MODE_SIZE]; - fsmdef_dcb_t *dcb; - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "invalid data"); - return; - } - - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - /* - * The only way this should happen is for the - * call to be released without cancelling the - * autoAnswer timer. - */ - FSM_DEBUG_SM(DEB_F_PREFIX"AutoAnswer timer expired but no dcb was found.", DEB_F_PREFIX_ARGS(FSM, fname)); - return; - } - - /* - * The device-based config parameter autoAnswerIdleAlternate - * determines what state the phone must be in for autoAnswer - * feature to be enabled. - */ - config_get_value(CFGID_AUTOANSWER_IDLE_ALTERNATE, &autoAnswerAlternate, - sizeof(autoAnswerAlternate)); - - if (fsmdef_check_auto_answer_allowed(autoAnswerAlternate, dcb->call_id)) { - /* - * Is headset active? No need to check if headset has been disabled - * on the phone because the headset will never be active if it has. - */ - headSetActive = platGetAudioDeviceStatus(VCM_AUDIO_DEVICE_HEADSET); - - /* - * If function call fails, just assume headset is not active - * and drive on - */ - if (headSetActive == -1) { - FSM_DEBUG_SM(DEB_F_PREFIX"platGetAudioDeviceStatus() for headset failed.", DEB_F_PREFIX_ARGS(FSM, fname)); - headSetActive = 0; - } - - /* - * Determine where the audio should be sent - */ - config_get_line_string(CFGID_LINE_AUTOANSWER_MODE, autoAnswerMode, - dcb->line, sizeof(autoAnswerMode)); - - /* - * Check to see if the speaker has been disabled - */ - config_get_value(CFGID_SPEAKER_ENABLED, &speakerEnabled, - sizeof(speakerEnabled)); - - /* - * autoAnswer using speaker - */ - if (strcasestr(autoAnswerMode, "speaker")) { - /* - * Speaker has not been disabled, normal processing. - */ - if (speakerEnabled) { - /* - * Enable audio path to speaker if headset is not being used. - */ - if (!headSetActive) { - platSetSpeakerMode(TRUE); - } - /* Send offhook event to GSM */ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_ANSWER, NULL); - } else { - - /* - * Speaker is disabled, but autoAnswer is enabled and says to - * use the speaker. Check the device-based override - * parameter to see what action to take. If override is - * set just return and let normal call processing happen. - * If not, terminate the call. The best SIP response we - * could come up in this situation is to send a 480 - * Temporarily Unavailable. - */ - config_get_value(CFGID_AUTOANSWER_OVERRIDE, &autoAnswerOverride, - sizeof(autoAnswerOverride)); - if (!autoAnswerOverride) { - fsmdef_end_call(dcb, CC_TEMP_NOT_AVAILABLE); - } - - } - } else if (strcasestr(autoAnswerMode, "headset")) { - /* - * autoAnswer using headset. If headset is not enabled just let - * the phone ring normally. - */ - if (headSetActive) { - /* Send offhook event to GSM */ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_ANSWER, NULL); - } - } else { - /* - * Unknown autoAnswer mode - */ - FSM_DEBUG_SM(DEB_F_PREFIX"Unknown autoAnswer Mode: %s AutoAnswer is disabled.", - DEB_F_PREFIX_ARGS(FSM, fname), autoAnswerMode); - } - } -} - -/* - * fsmdef_b2bjoin_invoke - * - * Description: - * This function implements the b2bjoin feature invocation. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void -fsmdef_b2bjoin_invoke (fsmdef_dcb_t *dcb, cc_feature_data_t *join_data) -{ - cc_feature_data_t feature_data; - int join_across_lines; - cc_uint32_t major_ver; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // Disable Join if the CUCM doesn't support it - platGetSISProtocolVer(&major_ver, NULL, NULL, NULL); - - if ( major_ver < SIS_PROTOCOL_MAJOR_VERSION_UNISON ) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - "fsmdef_b2bjoin_invoke", "Major sis is small than SIS_PROTOCOL_MAJOR_VERSION_UNISON, so, B2BJOIN is disabled"); - fsm_display_feature_unavailable(); - fsmdef_sm_ignore_ftr(dcb->fcb, __LINE__, CC_FEATURE_B2B_JOIN); - return; - } - - config_get_value(CFGID_JOIN_ACROSS_LINES, - &join_across_lines, sizeof(join_across_lines)); - /* - * Invoke B2BJoin feature towards SIP. It will send a REFER to CCM - */ - if (join_data) { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, join_data); - } else { - - if ((g_b2bjoin_pending == FALSE) && (dcb->fcb->state == FSMDEF_S_HOLDING) - && ((fsmdef_get_connected_call() != NULL) || - (fsmdef_get_alertingout_call() != NULL))) { - /* Single Button Join case - * If Join is pressed on a held call while there is - * an active(connected or alerting) call, that completes the Join - */ - feature_data.b2bjoin.b2bjoin_callid = dcb->call_id; - feature_data.b2bjoin.b2bjoin_joincallid = dcb->call_id; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, &feature_data); - return; - } - - if ((g_numofselected_calls == 0) || - ((g_b2bjoin_pending == FALSE) && (join_across_lines == JOIN_ACROSS_LINES_DISABLED) && - (fsmdef_are_there_selected_calls_onotherline(dcb->line) == TRUE))) { - dcb->active_feature = CC_FEATURE_B2B_JOIN; - feature_data.select.select = TRUE; - fsmdef_select_invoke(dcb,&feature_data); - fsm_display_use_line_or_join_to_complete(); - return; - } - if (g_b2bjoin_pending) { - if (join_across_lines == JOIN_ACROSS_LINES_DISABLED) { - if (fsmdef_are_join_calls_on_same_line(dcb->line) == FALSE) { - - fsm_display_use_line_or_join_to_complete(); - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - return; - } - } - if (dcb->call_id== g_b2bjoin_callid) { - /* If join is pending, pressing Join on the same call will cancel it */ - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - /* Remove the check mark from it*/ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_SELECT, NULL); - return; - } - feature_data.b2bjoin.b2bjoin_callid = dcb->call_id; - if( g_b2bjoin_callid == CC_NO_CALL_ID ){ - feature_data.b2bjoin.b2bjoin_joincallid = dcb->call_id; - } - else{ - feature_data.b2bjoin.b2bjoin_joincallid = g_b2bjoin_callid; - } - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, &feature_data); - - } else { - if ((g_numofselected_calls == 1) && (dcb->selected)) { - /* - * If this is only one selected call, pressing - * Join on it will start a new join operation - */ - g_b2bjoin_pending = TRUE; - g_b2bjoin_callid = dcb->call_id; - fsm_display_use_line_or_join_to_complete(); - return; - } - feature_data.b2bjoin.b2bjoin_callid = dcb->call_id; - feature_data.b2bjoin.b2bjoin_joincallid = dcb->call_id; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, &feature_data); - } - } - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; -} - -/* - * fsmdef_select_invoke - * - * - * Description: - * This function implements the join feature invocation. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void -fsmdef_select_invoke (fsmdef_dcb_t *dcb, cc_feature_data_t *select_data) -{ - cc_feature_data_t feature_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dcb->select_pending) { - /* We have sent a select but have not received a - * response yet, so diallow further selects till then - */ - return; - } - if (select_data) { - feature_data.select.select = select_data->select.select; - } else { - if (dcb->selected == TRUE) { - feature_data.select.select = FALSE; - } else { - feature_data.select.select = TRUE; - } - } - if ((g_b2bjoin_pending) && (dcb->call_id== g_b2bjoin_callid)) { - /* If join is pending, pressing Select on the same call cancels join*/ - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - } - dcb->select_pending = TRUE;; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_SELECT, &feature_data); -} - -/* - * handle_join_pending - * - * - * Description: - * This function checks if the join_pending flag - * needs to be cleared.due to the invocation of other features - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void fsmdef_handle_join_pending (fsmdef_dcb_t *dcb) -{ - if ((g_b2bjoin_pending) && (dcb->call_id == g_b2bjoin_callid)) { - /* If join is pending, invoking any other feature cancels join*/ - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - } -} - - -/* - * fsmdef_process_dialstring_for_callfwd - * - * Description: - * This function processes the dialstring event for callfwd. - * - * Parameters: - * sm_event_t *event - data associated with this call/dialstring - * - * Returns: sm_rcs_t - */ -static sm_rcs_t -fsmdef_process_dialstring_for_callfwd (sm_event_t *event) -{ - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * For ccm case just return success. - * It will continue the call by sending INVITE - */ - return (SM_RC_SUCCESS); -} - - -/* - * fsmdef_process_cfwd_softkey_event - * - * Description: - * This function processes the cfwd softkey press event for callfwd. - * - * Parameters: - * sm_event_t *event - data associated with this call/dialstring - * - * Returns: sm_rcs_t - */ -static sm_rcs_t -fsmdef_process_cfwd_softkey_event (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *ftr_data = &(msg->data); - cc_action_data_t cc_data; - int skMask[MAX_SOFT_KEYS]; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // check if callfwd is active (i.e. set previously) - if (lsm_check_cfwd_all_ccm(dcb->line)) { - // call fsmdef_dialstring() version of the function specific - // to cfwd feature - return (fsmdef_cfwd_clear_ccm(fcb)); - } - - - // code from here on is common to both modes/feature_id - if (fcb->state == FSMDEF_S_IDLE) { - - /* - * The user is attempting to start a cfwdall call on a specific line: - * 1. need to place the connected call (if there is one) on hold, - * 2. clear any outgoing ringing calls, - * 3. initiate this call. - */ - if (fsmdef_wait_to_start_new_call(TRUE, CC_SRC_GSM, dcb->call_id, dcb->line, ftr_id, ftr_data)) - { - dcb->active_feature = CC_FEATURE_NONE; - return (SM_RC_END); - } - - - // go offhook and then move to dialing state to collect digits - //only contains in initial NOTIFY to CUCM - fsmdef_notify_hook_event(fcb,CC_MSG_OFFHOOK, - ftr_data->newcall.global_call_id, - ftr_data->newcall.prim_call_id, - ftr_data->newcall.hold_resume_reason, - CC_MONITOR_NONE, - (ftr_id == CC_FEATURE_CFWD_ALL) ? CFWDALL_SET:CFWDALL_NONE); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - ((cc_state_data_t *) (&(dcb->caller_id)))); - - fsmdef_call_cc_state_dialing(dcb, FALSE); - - // stop the dial tone for parity with SCCP phone behavior - cc_data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, - &cc_data); - - // give different (zip-zip) tone rather than dial tone. zip_zip - // is not a permanent tone so it will end on it's own without - // us telling media termination to stop playing the tone. - cc_data.tone.tone = VCM_ZIP_ZIP; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_PLAY_TONE, - &cc_data); - - // move to collect digit info state - fsm_change_state(fcb, __LINE__, FSMDEF_S_COLLECT_INFO); - } else { // we must be in FSMDEF_S_COLLECT_INFO state - // stop the dial tone for parity with SCCP phone behavior - cc_data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, - &cc_data); - - // give different (zip-zip) tone rather than dial tone. zip_zip - // is not a permanent tone so it will end on it's own without - // us telling media termination to stop playing the tone. - cc_data.tone.tone = VCM_ZIP_ZIP; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_PLAY_TONE, - &cc_data); - } - ui_control_feature(dcb->line, dcb->call_id, skMask, 1, FALSE); - - return (SM_RC_END); -} - -/** - * This function is a reduced version of the fsmdef_dialstring() function. - * It is customized for sending INVITE out to CCM to clear CFA state. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * - * @pre (fcb not_eq NULL) - * - * @return sm_rsc_t indicates whether the execution of - * next statmachine. - */ -static sm_rcs_t -fsmdef_cfwd_clear_ccm (fsm_fcb_t *fcb) -{ - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // to clear CFA in CCM mode... only put service uri... no dialstring. - fsmdef_append_dialstring_to_feature_uri(dcb, NULL); - - // From here on all we need to do is send INVITE out. - // Since, its not a real call there is no need to update UI etc. - // Response to this call will be 5xx so it will be released by the SIP stack. - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - cc_int_setup(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), dcb->alert_info, VCM_INSIDE_RING, - VCM_INSIDE_DIAL_TONE, NULL, NULL, FALSE, NULL, &msg_body); - - /* - * Since we are sending setup to UI we will also have to send - * release to it to for sip stack to clean up the call - */ - dcb->send_release = TRUE; - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_SETUP); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_CALL_SENT); - return (SM_RC_END); -} - -/* - * fsmdef_append_dialstring_to_feature_uri - * - * Description: - * This function appends dialstring to feature URI. - * - * Parameters: - * fsmdef_dcb_t *dcb, char *dialstring - * - * Return Value: none - * - * Note: TNP specific implementation. - */ -static void -fsmdef_append_dialstring_to_feature_uri (fsmdef_dcb_t *dcb, - const char *dialstring) -{ - char service_uri[MAX_URL_LENGTH]; - - service_uri[0] = '\0'; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dcb == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), - __FUNCTION__); - return; - } - - switch (dcb->active_feature) { - case CC_FEATURE_CFWD_ALL: - config_get_string(CFGID_CALL_FORWARD_URI, service_uri, - sizeof(service_uri)); - break; - default: - // do nothing - break; - } - - if (service_uri[0] != NUL) { - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, service_uri); - if (dialstring && dialstring[0]) { - dcb->caller_id.called_number = - strlib_append(dcb->caller_id.called_number, "-"); - dcb->caller_id.called_number = - strlib_append(dcb->caller_id.called_number, dialstring); - } - } else { - FSM_DEBUG_SM(DEB_F_PREFIX"Configured Feature/Service URI Not Found For Feature[%d]", DEB_F_PREFIX_ARGS(FSM, "fsmdef_append_dialstring_to_feature_uri"), (int)dcb->active_feature); - - if (dialstring && dialstring[0]) { - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, dialstring); - } - } -} - - -/* - * fsmdef_is_feature_uri_configured - * - * Description: - * This function checks is a feature URI is configured. - * - * Parameters: - * cc_features_t ftr_id - * - * Return Value: TRUE or FALSE - * - * Note: TNP specific implementation. - */ -static boolean -fsmdef_is_feature_uri_configured (cc_features_t ftr_id) -{ - char service_uri[MAX_URL_LENGTH]; - - service_uri[0] = '\0'; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - switch (ftr_id) { - case CC_FEATURE_CFWD_ALL: - config_get_string(CFGID_CALL_FORWARD_URI, service_uri, - sizeof(service_uri)); - break; - default: - break; - } - - if (service_uri[0] != NUL) { - return TRUE; - } - - FSM_DEBUG_SM(DEB_F_PREFIX"Configured Feature/Service URI Not Found For Feature[%d]", DEB_F_PREFIX_ARGS(FSM, "fsmdef_is_feature_uri_configured"), (int)ftr_id); - return FALSE; -} - -/* - * fsmdef_check_if_ok_for_dial_call - * - * Description: - * This function checks if there is a call in collecting info state - * on a given line. - * - * Parameters: - * line_t line - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_for_dial_call (line_t line) -{ - - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (((dcb->line == line) && (dcb->call_id != CC_NO_CALL_ID)) && - (dcb->fcb != NULL) && - ((dcb->fcb->state == FSMDEF_S_COLLECT_INFO) || - (dcb->fcb->state == FSMDEF_S_CALL_SENT) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_PROCEEDING) || - (dcb->fcb->state == FSMDEF_S_KPML_COLLECT_INFO))) { - return (TRUE); - } - } - return (FALSE); -} - -/* - * fsmdef_check_if_ok_to_ans_call - * - * Description: - * Checks if given call is in ringing state. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ - -boolean -fsmdef_check_if_ok_to_ans_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || ((dcb->fcb != NULL) && (dcb->fcb->state != FSMDEF_S_INCOMING_ALERTING))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_hold_call - * - * Description: - * Checks if the requested call is in connected state. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE - if there is a connected or resume pending call - * FALSE - if the call is not in above state - */ -boolean -fsmdef_check_if_ok_to_hold_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - - return (FALSE); - } - - if ((dcb->line != line) || - ((dcb->fcb != NULL) && - ((dcb->fcb->state != FSMDEF_S_CONNECTED) && - (dcb->fcb->state != FSMDEF_S_CONNECTED_MEDIA_PEND) && - (dcb->fcb->state != FSMDEF_S_RESUME_PENDING)))) { - - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_resume_call - * - * Description: - * Checks if the requested call is in held state. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_to_resume_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || ((dcb->fcb != NULL) &&(dcb->fcb->state != FSMDEF_S_HOLDING))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_run_feature - * - * Description: - * Checks if it is ok to run features on the call. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_to_run_feature (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || - ((dcb->fcb != NULL) && - (dcb->fcb->state != FSMDEF_S_CONNECTED) && - (dcb->fcb->state != FSMDEF_S_CONNECTED_MEDIA_PEND))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_monitor_update_call - * - * Description: - * Checks if it is ok to update the monitoring call. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_to_monitor_update_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || - ((dcb->fcb != NULL) && - (dcb->fcb->state != FSMDEF_S_CONNECTED))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_set_call_info_cc_call_state - * - * Description: - * Sets the called number to readable localized values - * if it is service URI based feature and invokes cc_call_state() - * - * Parameters: - * dcb - * state - * - * Returns: none - */ -static void -fsmdef_set_call_info_cc_call_state (fsmdef_dcb_t *dcb, cc_states_t state, cc_causes_t cause) -{ - cc_state_data_t temp_data; - char tmp_str[CALL_BUBBLE_STR_MAX_LEN]; - int rc = CPR_FAILURE; - - tmp_str[0] = '\0'; - - switch (dcb->active_feature) { - case CC_FEATURE_CFWD_ALL: - rc = platGetPhraseText(STR_INDEX_CALL_FORWARD, - (char *) tmp_str, - CALL_BUBBLE_STR_MAX_LEN); - break; - default: - rc = CPR_FAILURE; - break; - } - - switch (state) { - - case CC_STATE_DIALING_COMPLETED: - temp_data.dialing_completed.caller_id = dcb->caller_id; - break; - - case CC_STATE_CALL_SENT: - temp_data.call_sent.caller_id = dcb->caller_id; - break; - - case CC_STATE_CALL_FAILED: - temp_data.call_failed.caller_id = dcb->caller_id; - temp_data.call_failed.cause = cause; - break; - - default: - /* Set the call id for other states */ - temp_data.offhook.caller_id = dcb->caller_id; - break; - } - - if ((rc == CPR_SUCCESS) && strlen(tmp_str) > 0) { - temp_data.offhook.caller_id.called_number = tmp_str; - } - - cc_call_state(dcb->call_id, dcb->line, state, &temp_data); -} - -/* - * fsmdef_get_dcb_by_call_instance_id - * - * Description: - * This function returns fsmdef DCB that has a match for a given call - * instance ID of a given line. - * - * Parameters: - * line - the dn line - * call_instance_id - for call instance ID. - * - * Returns: pointer to fsmdef_dcb_t if a matching dcb is found otherwise - * returns NULL - */ -fsmdef_dcb_t * -fsmdef_get_dcb_by_call_instance_id (line_t line, uint16_t call_instance_id) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->caller_id.call_instance_id == call_instance_id) && - (dcb->line == line)) { - return (dcb); - } - } - return (NULL); -} - -/* - * fsmdef_ev_join - * - * Description: - * The fsmdef_ev_join function sends an offhook event - * to the barging call and sets its state to FSMDEF_S_JOINING. - * - * Parameters: - * data - pointer to the cc_feature_data_t - * - * Returns: - * none - */ -static void -fsmdef_ev_join (cc_feature_data_t *data) -{ - fsm_fcb_t *fcb = NULL; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fcb = fsm_get_fcb_by_call_id_and_type(data->newcall.join.join_call_id, - FSM_TYPE_DEF); - if (fcb) { - fsmdef_dcb_t *dcb = fcb->dcb; - - cc_int_offhook(CC_SRC_GSM, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, - dcb->call_id, dcb->line, NULL, CC_MONITOR_NONE,CFWDALL_NONE); - fsm_change_state(fcb, __LINE__, FSMDEF_S_JOINING); - } -} - -/* - * fsmdef_ev_joining_connected_ack - * - * Description: - * The fsmdef_ev_joining_connected_ack negotiates the sdp in the - * ack(if there is one) and sets the fsm/ccapi state to connected - * - * Parameters: - * event - pointer to the sm_event_t - * - * Returns: - * sm_rcs_t value - */ -static sm_rcs_t -fsmdef_ev_joining_connected_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_connected_ack_t *msg = (cc_connected_ack_t *) event->msg; - cc_causes_t cause; - fsmcnf_ccb_t *ccb; - fsm_fcb_t *join_target_fcb; - cc_feature_data_t data; - cc_uint32_t major_sis_ver = SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - memset(&data, 0, sizeof(data)); - - /* Check the remote SDP. The far end may not have included the SDP in an - * earlier message, which means that the SDP must be in this message. - */ - if (dcb->remote_sdp_in_ack == TRUE) { - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - data.endcall.cause = cause; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - } - - platGetSISProtocolVer(&major_sis_ver, NULL, NULL,NULL); - - ccb = fsmcnf_get_ccb_by_call_id(dcb->call_id); - - if (ccb) { - join_target_fcb = fsm_get_fcb_by_call_id_and_type(ccb->cnf_call_id, - FSM_TYPE_CNF); - if ((gsmsdp_is_media_encrypted(dcb) == FALSE) && - (gsmsdp_is_media_encrypted((join_target_fcb!= NULL)?join_target_fcb->dcb:NULL) == TRUE) && - (major_sis_ver < SIS_PROTOCOL_MAJOR_VERSION_MUSTER)) { - /* - * Target Call was secure, a non-secure is trying to Barge/Monitor, - * fail it - */ - data.endcall.cause = CC_CAUSE_SECURITY_FAILURE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - (cc_state_data_t *) &(dcb->caller_id)); - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - data.endcall.cause = CC_CAUSE_NO_MEDIA; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - - if (ccb) { - /* - * Bridge the conference legs for the join call, even though - * it's done here, ccb should only be accessed from fsmcnf - */ - ccb->active = TRUE; - ccb->bridged = TRUE; - } - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - return(fsmdef_transition_to_connected(fcb)); -} - -/* - * fsmdef_ev_joining_offhook - * - * Description: - * The fsmdef_ev_joining_offhook creates the local sdp - * for the sip stack to send 200 Ok out - * - * Parameters: - * event - pointer to the sm_event_t - * - * Returns: - * sm_rcs_t value - */ -static sm_rcs_t -fsmdef_ev_joining_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - cc_feature_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* Build our response SDP to include in the connected */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM("%s", get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - memset(&data, 0, sizeof(data)); - data.endcall.cause = cause; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - cc_int_connected(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL, &msg_body); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED); - - return (SM_RC_END); -} - -/* - * fsmdef_extract_join_target - * - * Description: - * The fsmdef_extract_join_target extract join target call id from - * the setup message and sends a JOIN event to that call - * - * Parameters: - * event - pointer to the sm_event_t - * - * Returns: - * TRUE or FALSE - */ -static boolean -fsmdef_extract_join_target (sm_event_t *event) -{ - static const char fname[] = "fsmdef_extract_join_target"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - fsmdef_dcb_t *dcb; - fsmdef_dcb_t *join_dcb; - cc_feature_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb = fcb->dcb; - - if ((msg->call_info.type == CC_FEAT_MONITOR) || - (dcb->session == WHISPER_COACHING)) { - - /* For now, null out the ui id */ - lsm_set_ui_id(dcb->call_id, CC_NO_CALL_ID); - join_dcb = - fsmdef_get_dcb_by_call_id(msg->call_info.data.join.join_call_id); - if (join_dcb) { - dcb->group_id = join_dcb->group_id; - memset(&data, 0, sizeof(data)); - data.newcall.join.join_call_id = call_id; - - if (dcb->session == WHISPER_COACHING) { - data.newcall.cause = CC_CAUSE_MONITOR; - } else if (msg->call_info.type == CC_FEAT_MONITOR) { - data.newcall.cause = CC_CAUSE_MONITOR; - // set the session leg of this dcb to monitor - dcb->session = MONITOR; - } - FSM_DEBUG_SM(DEB_L_C_F_PREFIX" dcb-session type is = %s", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), - dcb->session == WHISPER_COACHING ? "WHISPER_COACHING" : - dcb->session == MONITOR ? "MONITOR" : "PRIMARY"); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, join_dcb->call_id, line, - CC_FEATURE_JOIN, &data); - } else { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Unable to find join target dcb", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname)); - return (TRUE); - } - } else { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Unable to find join target call information", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname)); - return (TRUE); - } - return (FALSE); -} - - -/* - * fsmdef_ev_notify_feature - * - * Description: - * Handles NOTIFY event in different states. - * - * Parameters: - * msg - message pointer - * dcb - pointer to the fsmdef_dcb_t - * - * Returns: - * none - */ -static void -fsmdef_ev_notify_feature (cc_feature_t *msg, fsmdef_dcb_t *dcb) -{ - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - -} - -/* - * fsmdef_notify_hook_event - * - * Description: - * Send offhook/onhook events to SIP (DialogManager) task. - * - * Parameters: - * dcb - pointer to the fsmdef_dcb_t - * - * Returns: - * none - */ -static void -fsmdef_notify_hook_event (fsm_fcb_t *fcb, cc_msgs_t msg, char *global_call_id, - callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode) -{ - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (msg == CC_MSG_OFFHOOK) { - cc_int_offhook(CC_SRC_GSM, CC_SRC_SIP, prim_call_id, consult_reason, - fcb->dcb->call_id, fcb->dcb->line, - global_call_id, monitor_mode,cfwdall_mode); - } else if (msg == CC_MSG_ONHOOK) { - cc_int_onhook(CC_SRC_GSM, CC_SRC_SIP, prim_call_id, - consult_reason, fcb->dcb->call_id, fcb->dcb->line, FALSE, - FALSE, __FILE__, __LINE__); - } - return; -} - -/* - * fsmdef_update_callinfo_security_status - * - * Description: - * The fsmdef_update_callinfo_security_status function updates the call - * information that applies to TNP platform. - * - * Parameters: - * dcb - pointer to the fsmdef_dcb_t - * call_info - pointer to the cc_feature_data_call_info_t - * - * Returns: - * none - */ -static void -fsmdef_update_callinfo_security_status (fsmdef_dcb_t *dcb, - cc_feature_data_call_info_t *call_info) -{ - /* - * Update security information - */ - if (call_info->feature_flag & CC_SECURITY) { - if (sip_regmgr_get_sec_level(dcb->line) != AUTHENTICATED && - sip_regmgr_get_sec_level(dcb->line) != ENCRYPTED ) { - // Signaling security can't be trusted downgrade security level to NOT_AUTHENTICATED - call_info->security = CC_SECURITY_NOT_AUTHENTICATED; - } - - if (dcb->security != call_info->security) { - FSM_SET_SECURITY_STATUS(dcb, call_info->security); - if ( call_info->security == CC_SECURITY_ENCRYPTED ) - ui_update_call_security(dcb->line, lsm_get_ui_id(dcb->call_id), CC_SECURITY_ENCRYPTED); - else - ui_update_call_security(dcb->line, lsm_get_ui_id(dcb->call_id), CC_SECURITY_UNKNOWN); - - dcb->ui_update_required = TRUE; - } - } -} - -/* - * fsmdef_check_retain_fwd_info_state - * - * Description: This function checks the "Retain Forward Information" config - * parameter (only for TNP). It returns TRUE if forward info is - * to be retained; FALSE otherwise. This config parameter is - * is used to change call bubble display from "Forward " to - * "From " when an incoming call is answered AND the config - * parameter value is set to TRUE. For non-TNP, this function - * will always return FALSE (i.e. not to retain fwd info). - * - * Parameters: none - * - * Return Value: TRUE or FALSE - */ -boolean -fsmdef_check_retain_fwd_info_state (void) -{ - int retain_fwd_info_cfg = 0; /* default to Disabled (or 0) for no-op */ - - config_get_value(CFGID_RETAIN_FORWARD_INFORMATION, - &retain_fwd_info_cfg, - sizeof(retain_fwd_info_cfg)); - - if (!retain_fwd_info_cfg) { - return (FALSE); /* do NOT retain forward information */ - } else { - return (TRUE); /* retain forward information */ - } -} - -void -fsmdef_init (void) -{ - static const char fname[] = "fsmdef_init"; - fsmdef_dcb_t *dcb; - - - /* - * Initialize the dcbs. - */ - fsmdef_dcbs = (fsmdef_dcb_t *) - cpr_calloc(FSMDEF_MAX_DCBS, sizeof(fsmdef_dcb_t)); - if (fsmdef_dcbs == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"cpr_calloc returned NULL", - DEB_F_PREFIX_ARGS(FSM, fname)); - return; - } - - /* Create free media structure list */ - if (!gsmsdp_create_free_media_list()) { - FSM_DEBUG_SM(DEB_F_PREFIX"Unable to create free media list", - DEB_F_PREFIX_ARGS(FSM, fname)); - return; - } - - DEF_DEBUG(DEB_F_PREFIX"Disabling mass registration print", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - fsmdef_init_dcb(dcb, CC_NO_CALL_ID, FSMDEF_CALL_TYPE_NONE, - FSMDEF_NO_NUMBER, LSM_NO_LINE, NULL); - if (dcb == fsmdef_dcbs) { - g_disable_mass_reg_debug_print = TRUE; - } - } - g_disable_mass_reg_debug_print = FALSE; - - /* - * Initialize the state/event table. - */ - fsmdef_sm_table.min_state = FSMDEF_S_MIN; - fsmdef_sm_table.max_state = FSMDEF_S_MAX; - fsmdef_sm_table.min_event = CC_MSG_MIN; - fsmdef_sm_table.max_event = CC_MSG_MAX; - fsmdef_sm_table.table = (&(fsmdef_function_table[0][0])); -} - -void -fsmdef_shutdown (void) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - /* clean media list */ - gsmsdp_clean_media_list(dcb); - gsmsdp_free(dcb); - } - - /* destroy free media structure list */ - gsmsdp_destroy_free_media_list(); - - cpr_free(fsmdef_dcbs); - fsmdef_dcbs = NULL; -} - -static void -fsmdef_update_calltype (fsm_fcb_t *fcb, cc_feature_t *msg) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t *feat_data = &(msg->data); - cc_caller_id_t *caller_id; - - if (msg->data_valid == FALSE) { - /* No data to use for update. Just ignore the event. */ - return; - } - - if (feat_data->call_info.feature_flag & CC_CALLER_ID) { - caller_id = &feat_data->call_info.caller_id; - if (caller_id->call_type == CC_CALL_FORWARDED) { - if (fsmdef_check_retain_fwd_info_state()) { - dcb->call_type = FSMDEF_CALL_TYPE_FORWARD; - } - } - } -} - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/fsmxfr.c b/media/webrtc/signaling/src/sipcc/core/gsm/fsmxfr.c deleted file mode 100755 index bc4c8cbeb54..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmxfr.c +++ /dev/null @@ -1,3040 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "fsm.h" -#include "uiapi.h" -#include "debug.h" -#include "regmgrapi.h" -#include "platform_api.h" - -extern fsmdef_dcb_t *fsmdef_dcbs; - -#define FSMXFR_NULL_DIALSTRING "" -static fsmxfr_xcb_t *fsmxfr_xcbs; - -typedef enum fsmxfr_states_t_ { - FSMXFR_S_MIN = -1, - FSMXFR_S_IDLE, - FSMXFR_S_ACTIVE, - FSMXFR_S_MAX -} fsmxfr_states_t; - -static const char *const fsmxfr_state_names[] = { - "IDLE", - "ACTIVE" -}; - -static sm_rcs_t fsmxfr_ev_idle_setup(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_idle_dialstring(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_connected_ack(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_release(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_release_complete(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_feature(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_feature_ack(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_onhook(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_dialstring(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_proceeding(sm_event_t *event); - -static sm_function_t fsmxfr_function_table[FSMXFR_S_MAX][CC_MSG_MAX] = -{ -/* FSMXFR_S_IDLE ------------------------------------------------------------ */ - { - /* FSMXFR_E_SETUP */ fsmxfr_ev_idle_setup, - /* FSMXFR_E_SETUP_ACK */ NULL, - /* FSMXFR_E_PROCEEDING */ NULL, - /* FSMXFR_E_ALERTING */ NULL, - /* FSMXFR_E_CONNECTED */ NULL, - /* FSMXFR_E_CONNECTED_ACK */ NULL, - /* FSMXFR_E_RELEASE */ NULL, - /* FSMXFR_E_RELEASE_COMPLETE */ NULL, - /* FSMXFR_E_FEATURE */ fsmxfr_ev_idle_feature, - /* FSMXFR_E_FEATURE_ACK */ NULL, - /* FSMXFR_E_OFFHOOK */ NULL, - /* FSMXFR_E_ONHOOK */ NULL, - /* FSMXFR_E_LINE */ NULL, - /* FSMXFR_E_DIGIT_BEGIN */ NULL, - /* FSMXFR_E_DIGIT */ NULL, - /* FSMXFR_E_DIALSTRING */ fsmxfr_ev_idle_dialstring, - /* FSMXFR_E_MWI */ NULL, - /* FSMXFR_E_SESSION_AUDIT */ NULL - }, - -/* FSMXFR_S_ACTIVE ---------------------------------------------------- */ - { - /* FSMXFR_E_SETUP */ NULL, - /* FSMXFR_E_SETUP_ACK */ NULL, - /* FSMXFR_E_PROCEEDING */ fsmxfr_ev_active_proceeding, - /* FSMXFR_E_ALERTING */ NULL, - /* FSMXFR_E_CONNECTED */ NULL, - /* FSMXFR_E_CONNECTED_ACK */ fsmxfr_ev_active_connected_ack, - /* FSMXFR_E_RELEASE */ fsmxfr_ev_active_release, - /* FSMXFR_E_RELEASE_COMPLETE */ fsmxfr_ev_active_release_complete, - /* FSMXFR_E_FEATURE */ fsmxfr_ev_active_feature, - /* FSMXFR_E_FEATURE_ACK */ fsmxfr_ev_active_feature_ack, - /* FSMXFR_E_OFFHOOK */ NULL, - /* FSMXFR_E_ONHOOK */ fsmxfr_ev_active_onhook, - /* FSMXFR_E_LINE */ NULL, - /* FSMXFR_E_DIGIT_BEGIN */ NULL, - /* FSMXFR_E_DIGIT */ NULL, - /* FSMXFR_E_DIALSTRING */ fsmxfr_ev_active_dialstring, - /* FSMXFR_E_MWI */ NULL, - /* FSMXFR_E_SESSION_AUDIT */ NULL - } -}; - -static sm_table_t fsmxfr_sm_table; -sm_table_t *pfsmxfr_sm_table = &fsmxfr_sm_table; - -const char * -fsmxfr_state_name (int state) -{ - if ((state <= FSMXFR_S_MIN) || (state >= FSMXFR_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmxfr_state_names[state]); -} - - -static int -fsmxfr_get_new_xfr_id (void) -{ - static int xfr_id = 0; - - if (++xfr_id < 0) { - xfr_id = 1; - } - - return (xfr_id); -} - -/** - * - * Sets/rest transfer complete flag in the DCB so it can be used in - * UI to indicate if the call is ended because of xfer or endcall. - * - * @cns_call_id consult call id - * @Xfr_call_id transfer call id - * - * @return none - * - * @pre (none) - */ -void fsmxfr_mark_dcb_for_xfr_complete(callid_t cns_call_id, callid_t xfr_call_id, - boolean set_flag) -{ - fsm_fcb_t *cns_fcb, *xfr_fcb; - - cns_fcb = fsm_get_fcb_by_call_id_and_type(cns_call_id, - FSM_TYPE_DEF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(xfr_call_id, - FSM_TYPE_DEF); - if (set_flag) { - if (cns_fcb && cns_fcb->dcb) { - FSM_SET_FLAGS(cns_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - if (xfr_fcb && xfr_fcb->dcb) { - FSM_SET_FLAGS(xfr_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - } else { - if (cns_fcb && cns_fcb->dcb) { - FSM_RESET_FLAGS(cns_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - if (xfr_fcb && xfr_fcb->dcb) { - FSM_RESET_FLAGS(xfr_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - } -} - -/** - * - * Get active trasnfer state machine information (in active state). - * - * @param none - * - * @return fsm_fcb_t if there is a active trasnfer pending - * else NULL - * - * @pre (none) - */ - - -fsm_fcb_t *fsmxfr_get_active_xfer(void) -{ - fsm_fcb_t *fcb; - fsmxfr_xcb_t *xcb; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - fcb = fsm_get_fcb_by_call_id_and_type(xcb->xfr_call_id, - FSM_TYPE_XFR); - if (fcb && fcb->state == FSMXFR_S_ACTIVE) { - return(fcb); - } - } - - return(NULL); -} - - -static void -fsmxfr_init_xcb (fsmxfr_xcb_t *xcb) -{ - if (xcb != NULL) { - xcb->xfr_id = FSM_NO_ID; - xcb->xfr_call_id = CC_NO_CALL_ID; - xcb->cns_call_id = CC_NO_CALL_ID; - xcb->xfr_line = CC_NO_LINE; - xcb->cns_line = CC_NO_LINE; - xcb->type = FSMXFR_TYPE_NONE; - xcb->method = CC_XFER_METHOD_NONE; - xcb->cnf_xfr = FALSE; - xcb->active = FALSE; - xcb->mode = FSMXFR_MODE_TRANSFEROR; - xcb->xfer_comp_req = FALSE; - xcb->xfr_orig = CC_SRC_MIN; - - if (xcb->xcb2 != NULL) { - fsmxfr_init_xcb(xcb->xcb2); - xcb->xcb2 = NULL; - } - - if (xcb->dialstring != NULL) { - cpr_free(xcb->dialstring); - xcb->dialstring = NULL; - } - if (xcb->queued_dialstring != NULL) { - cpr_free(xcb->queued_dialstring); - xcb->queued_dialstring = NULL; - } - if (xcb->referred_by != NULL) { - cpr_free(xcb->referred_by); - xcb->referred_by = NULL; - } - } -} - - -static fsmxfr_xcb_t * -fsmxfr_get_xcb_by_xfr_id (int xfr_id) -{ - static const char fname[] = "fsmxfr_get_xcb_by_xfr_id"; - fsmxfr_xcb_t *xcb; - fsmxfr_xcb_t *xcb_found = NULL; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - if (xcb->xfr_id == xfr_id) { - xcb_found = xcb; - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_PTR), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, fname, xcb); - - break; - } - } - - - return (xcb_found); -} - - -/* - * Function: fsmxfr_get_new_xfr_context - * - * Parameters: - * xfr_call_id: call_id for the call initiating the transfer - * type: attended or unattended transfer - * method: BYE/ALSO or REFER method of transfer - * local: local or remote initiated transfer - * - * Description: This function creates a new transfer context by: - * - getting a free xcb - * - creating new xfr_id and cns_call_id - * - * Returns: xcb - * - */ -static fsmxfr_xcb_t * -fsmxfr_get_new_xfr_context (callid_t xfr_call_id, line_t line, fsmxfr_types_t type, - cc_xfer_methods_t method, fsmxfr_modes_t mode) -{ - static const char fname[] = "fsmxfr_get_new_xfr_context"; - fsmxfr_xcb_t *xcb; - - xcb = fsmxfr_get_xcb_by_xfr_id(FSM_NO_ID); - if (xcb != NULL) { - xcb->xfr_id = fsmxfr_get_new_xfr_id(); - xcb->xfr_call_id = xfr_call_id; - xcb->cns_call_id = cc_get_new_call_id(); - xcb->xfr_line = line; - xcb->cns_line = line; - xcb->type = type; - xcb->method = method; - xcb->mode = mode; - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_PTR), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, fname, xcb); - } - - return (xcb); -} - - -fsmxfr_xcb_t * -fsmxfr_get_xcb_by_call_id (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - fsmxfr_xcb_t *xcb_found = NULL; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - if ((xcb->xfr_call_id == call_id) || (xcb->cns_call_id == call_id)) { - xcb_found = xcb; - break; - } - } - - return (xcb_found); -} - -/** - * - * Cancel tranfer operation by sending cancel event to SIP stack. - * This routine is used in roundtable phone. - * - * @param line, call_id, target_call_id, cause (implicit or explicit) - * - * @return void - * - * @pre (none) - */ -void -fsmxfr_feature_cancel (fsmxfr_xcb_t *xcb, line_t line, callid_t call_id, - callid_t target_call_id, - cc_rcc_skey_evt_type_e cause) -{ - static const char fname[] = "fsmxfr_feature_cancel"; - cc_feature_data_t data; - fsm_fcb_t *fcb_def; - - DEF_DEBUG(DEB_F_PREFIX"Sending cancel call_id = %d, t_id=%d, cause = %d", - DEB_F_PREFIX_ARGS(GSM, fname), call_id, target_call_id, cause); - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - fcb_def = fsm_get_fcb_by_call_id_and_type(target_call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, target_call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - data.cancel.target_call_id = target_call_id; - data.cancel.call_id = call_id; - data.cancel.cause = cause; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, CC_FEATURE_CANCEL, &data); -} - - -void -fsmxfr_update_xfr_context (fsmxfr_xcb_t *xcb, callid_t old_call_id, - callid_t new_call_id) -{ - static const char fname[] = "fsmxfr_update_xfr_context"; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_update_xfr_context")); - - if (xcb != NULL) { - if (old_call_id == xcb->xfr_call_id) { - xcb->xfr_call_id = new_call_id; - } else if (old_call_id == xcb->cns_call_id) { - xcb->cns_call_id = new_call_id; - } - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_PTR), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, fname, xcb); - } -} - -/* - * Function to get line number of other call associated in - * transfer. - * - * @param xcb and call_id. - * - * @return void - * - */ -line_t -fsmxfr_get_other_line (fsmxfr_xcb_t *xcb, callid_t call_id) -{ - line_t other_line = CC_NO_LINE; - - if (xcb != NULL) { - if (xcb->xfr_call_id == call_id) { - other_line = xcb->cns_line; - } else if (xcb->cns_call_id == call_id) { - other_line = xcb->xfr_line; - } - } - - return (other_line); -} - -callid_t -fsmxfr_get_other_call_id (fsmxfr_xcb_t *xcb, callid_t call_id) -{ - callid_t other_call_id = CC_NO_CALL_ID; - - if (xcb != NULL) { - if (xcb->xfr_call_id == call_id) { - other_call_id = xcb->cns_call_id; - } else if (xcb->cns_call_id == call_id) { - other_call_id = xcb->xfr_call_id; - } - } - - return (other_call_id); -} - - -/* - * Function: fsmxfr_remove_fcb - * - * Parameters: - * xfr_id: xfr_id for the transfer - * call_id: call_id that identifies the fcb to be removed - * - * Description: This function will remove the fcb identified by the given - * call_id from the xcb. And the function will free the xcb - * if both fcbs have been removed. - * - * Returns: none - * - * Note: This is a helper function for fsmxfr_cleanup. It allows fsmxfr_cleanup - * to cleanup one fcb (one call involved in the transfer) independent - * of the other involved fcb. - */ -static void -fsmxfr_remove_fcb (fsm_fcb_t *fcb, callid_t call_id) -{ - fsmxfr_xcb_t *xcb = fcb->xcb; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_remove_fcb")); - - if (xcb != NULL) { - fsmxfr_update_xfr_context(xcb, call_id, CC_NO_CALL_ID); - - /* - * Free the xcb if both fcb references have been removed. - */ - if ((xcb->xfr_call_id == CC_NO_CALL_ID) && - (xcb->cns_call_id == CC_NO_CALL_ID)) { - fsmxfr_init_xcb(xcb); - } - } -} - - -static void -fsmxfr_cnf_cleanup (fsmxfr_xcb_t *xcb) -{ - fsmdef_dcb_t *xfr_dcb; - fsmdef_dcb_t *cns_dcb; - cc_feature_data_t ftr_data; - - cns_dcb = fsm_get_dcb(xcb->cns_call_id); - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - - ftr_data.endcall.cause = CC_CAUSE_NORMAL; - ftr_data.endcall.dialstring[0] = '\0'; - /* - * This is a conference transfer hence we are cleaning - * up both the lines - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - cns_dcb->call_id, cns_dcb->line, - CC_FEATURE_END_CALL, &ftr_data); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xfr_dcb->call_id, xfr_dcb->line, - CC_FEATURE_END_CALL, &ftr_data); -} - - -static void -fsmxfr_cleanup (fsm_fcb_t *fcb, int fname, boolean both) -{ - fsm_fcb_t *other_fcb = NULL; - callid_t call_id = fcb->call_id; - callid_t other_call_id = CC_NO_CALL_ID; - line_t other_line; - - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_cleanup")); - other_call_id = fsmxfr_get_other_call_id(fcb->xcb, call_id); - other_line = fsmxfr_get_other_line(fcb->xcb, call_id); - - if (other_call_id != CC_NO_CALL_ID) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - } - - if (fcb->xcb && (fcb->xcb->cnf_xfr != TRUE) && - (call_id == fcb->xcb->xfr_call_id)) { - - if (other_call_id != CC_NO_CALL_ID) { - /* - * Not clearing consulation call, so change consultation call - * attribute to display connected softkey set. Do not change - * softkey set if it is a transfer o - */ - cc_call_attribute(other_call_id, other_line, NORMAL_CALL); - } - } - /* - * Check if the user wanted to cleanup the whole xcb. - * If so, then we will grab the other fcb first and call this function - * again with this other fcb. The whole xcb will be freed after this block - * of code because both call_ids will be -1, which tells - * fsmxfr_remove_fcb to free the xcb. - */ - if (both) { - FSM_DEBUG_SM(DEB_F_PREFIX"clean both.", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_cleanup")); - - if (other_call_id != CC_NO_CALL_ID) { - if (other_fcb != NULL) { - fsmxfr_cleanup(other_fcb, fname, FALSE); - } else { - /* - * If there is no other FCB, we need to clean up so that the - * XCB will be deleted. - */ - fsmxfr_update_xfr_context(fcb->xcb, other_call_id, - CC_NO_CALL_ID); - } - } - } - - /* - * Remove the reference to this fcb from the xcb - */ - fsmxfr_remove_fcb(fcb, fcb->call_id); - - /* - * Move this fcb to the IDLE state - */ - fsm_change_state(fcb, fname, FSMXFR_S_IDLE); - - /* - * Reset the data for this fcb. The fcb is still included in a call - * so set the call_id and dcb values accordingly. - */ - fsm_init_fcb(fcb, fcb->call_id, fcb->dcb, FSM_TYPE_XFR); -} - - -void -fsmxfr_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_XFR); - - if (fcb != NULL) { - fsmxfr_cleanup(fcb, __LINE__, FALSE); - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } -} - - -fsmxfr_types_t -fsmxfr_get_xfr_type (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - fsmxfr_types_t type = FSMXFR_TYPE_BLND_XFR; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb != NULL) { - type = xcb->type; - } - - return (type); -} - - -cc_features_t -fsmxfr_type_to_feature (fsmxfr_types_t type) -{ - cc_features_t feature; - - if (type == FSMXFR_TYPE_XFR) { - feature = CC_FEATURE_XFER; - } else { - feature = CC_FEATURE_BLIND_XFER; - } - - return (feature); -} - - -/******************************************************************* - * event functions - */ - - -static sm_rcs_t -fsmxfr_ev_idle_setup (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - fsmxfr_xcb_t *xcb; - - /* - * If this is the consultation call involved in a transfer, - * then set the rest of the data required to make the transfer - * happen. The data is the xcb in the fcb. The data is set now - * because we did not have the fcb when the transfer was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a transfer event is received. - */ - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(msg->call_id); - if (xcb == NULL) { - return (SM_RC_DEF_CONT); - } - fcb->xcb = xcb; - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - return (SM_RC_CONT); -} - - -static boolean -fsmxfr_copy_dialstring (char **saved_dialstring, char *dialstring) -{ - char *tempstring; - int len; - - if (saved_dialstring == NULL) { - return (FALSE); - } - - /* - * Make sure we have a valid dialstring. - */ - if ((dialstring == NULL) || (dialstring[0] == '\0')) { - return (FALSE); - } - - /* - * Copy the dialstring to the xcb. We will need it later when - * SIP sends the RELEASE so that we can send out the - * NEWCALL to start the call to the target. - */ - len = (strlen(dialstring) + 1) * sizeof(char); - tempstring = (char *) cpr_malloc(len); - if (tempstring != NULL) { - sstrncpy(tempstring, dialstring, len); - - *saved_dialstring = tempstring; - } - - return (TRUE); -} - -static void -fsmxfr_set_xfer_data (cc_causes_t cause, cc_xfer_methods_t method, - callid_t target_call_id, char *dialstring, - cc_feature_data_xfer_t *xfer) -{ - xfer->cause = cause; - xfer->method = method; - xfer->target_call_id = target_call_id; - sstrncpy(xfer->dialstring, dialstring, CC_MAX_DIALSTRING_LEN); -} - - -static boolean -fsmxfr_remote_transfer (fsm_fcb_t *fcb, cc_features_t ftr_id, - callid_t call_id, line_t line, char *dialstring, - char *referred_by) -{ - fsmxfr_types_t type; - int free_lines; - cc_feature_data_t data; - fsmxfr_xcb_t *xcb; - fsmxfr_xcb_t *primary_xcb; - callid_t cns_call_id; - line_t newcall_line = 0; - - memset(&data, 0, sizeof(cc_feature_data_t)); - - /* - * Make sure we have a free line for the consultation - * call if this is an attended transfer. We do not need this - * check for an unattended transfer, because the stack will - * send up a release for the call being transferred, which will - * then trigger the fsmxfr to send out the newcall in the same - * plane of the call being released. - */ - if (ftr_id == CC_FEATURE_XFER) { - /* - * Make sure we have a free line to start the - * consultation call. - */ - free_lines = lsm_get_instances_available_cnt(line, TRUE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this - * request. - */ - fsm_display_no_free_lines(); - - return (FALSE); - } - } - - newcall_line = lsm_get_newcall_line(line); - if (newcall_line == NO_LINES_AVAILABLE) { - /* - * Error Pass Limit - let the user know and end this request. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return (FALSE); - } - - /* - * Get a new xcb and new xfr id - This is the handle that will - * identify the xfr. - */ - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - primary_xcb = fsmxfr_get_xcb_by_call_id(call_id); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEREE); - if (xcb == NULL) { - return (FALSE); - } - - if (primary_xcb) { - fcb->xcb->xcb2 = xcb; - fcb->xcb->active = TRUE; - } else { - fcb->xcb = xcb; - } - - xcb->cns_line = newcall_line; - cns_call_id = xcb->cns_call_id; - fsmxfr_set_xfer_data(CC_CAUSE_OK, CC_XFER_METHOD_REFER, cns_call_id, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, ftr_id, &data, CC_CAUSE_NORMAL); - - if (ftr_id == CC_FEATURE_XFER) { - /* - * This call needs to go on hold so we can start the - * consultation call. The call may already be on hold, - * so the event will just be silently ignored. We set - * the line number to 0xFF so that GSM will know this - * came from a transfer and we only want to put the call - * on local hold. We don't want to send an Invite Hold - * to the SIP stack. - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - 0xFF, CC_FEATURE_HOLD, NULL); - - /* - * Initiate the consultation call. - */ - - /* - * Make sure we have a valid dialstring. - */ - if ((dialstring == NULL) || (dialstring[0] == '\0')) { - return (FALSE); - } - - /* - * memset is done because if redirects[0].number is - * corrupted we might think that it is a blind - * transfer - */ - memset(data.newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - data.newcall.cause = CC_CAUSE_XFER_REMOTE; - data.newcall.redirect.redirects[0].redirect_reason = - CC_REDIRECT_REASON_DEFLECTION; - sstrncpy(data.newcall.dialstring, dialstring, CC_MAX_DIALSTRING_LEN); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), - xcb->xfr_id, call_id, cns_call_id, __LINE__); - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - } else { /* CC_FEATURE_BLIND_XFER */ - /* - * Make sure we have a valid dialstring. - */ - if ((fsmxfr_copy_dialstring(&xcb->dialstring, dialstring) == TRUE) && - (fsmxfr_copy_dialstring(&xcb->referred_by, referred_by) == TRUE)) { - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - } else { - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - } - - return (TRUE); -} - - -static sm_rcs_t -fsmxfr_ev_idle_feature (sm_event_t *event) -{ - const char *fname = "fsmxfr_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *ftr_data = &(msg->data); - fsmdef_dcb_t *dcb = fcb->dcb; - fsm_fcb_t *other_fcb; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmxfr_types_t type; - int free_lines; - cc_feature_data_t data; - cc_causes_t cause = msg->data.xfer.cause; - cc_xfer_methods_t method; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *fcb_def; - fsm_fcb_t *cns_fcb, *con_fcb, *sel_fcb; - boolean int_rc = FALSE; - callid_t cns_call_id; - line_t newcall_line = 0; - - memset(&data, 0, sizeof(data)); - fsm_sm_ftr(ftr_id, src_id); - - /* - * Consume the XFER events and don't pass them along to the other FSMs. - */ - if ((ftr_id == CC_FEATURE_BLIND_XFER) || (ftr_id == CC_FEATURE_XFER)) { - sm_rc = SM_RC_END; - } - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_DIRTRXFR: - - /* If there is a active xfer pending - * then link this transfer to active transfer - */ - other_fcb = fsmxfr_get_active_xfer(); - if (other_fcb) { - if (other_fcb->xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - return (SM_RC_END); - } - /* End existing consult call and then link another - * call with the trasfer - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_fcb->xcb->cns_call_id, - other_fcb->xcb->cns_line, CC_FEATURE_END_CALL, NULL); - other_fcb->xcb->cns_call_id = call_id; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_fcb->xcb->xfr_call_id, - other_fcb->xcb->xfr_line, CC_FEATURE_DIRTRXFR, NULL); - - return(SM_RC_END); - } - fsm_get_fcb_by_selected_or_connected_call_fcb(call_id, &con_fcb, &sel_fcb); - - /* If there is a call selected use that for direct transfer */ - if (sel_fcb) { - other_fcb = sel_fcb; - } else if (con_fcb) { - other_fcb = con_fcb; - } else { - /* No connected call or selected call */ - return(SM_RC_CONT); - } - - /* Make sure atleast one call has been selected, connected and this call - * is not in the focus - */ - if ((fsmutil_get_num_selected_calls() > 1) && (dcb->selected == FALSE)) { - //return error - return(SM_RC_CONT); - } - - if (other_fcb->xcb == NULL || other_fcb->xcb->xfr_line != line) { - //Not on same line display a message - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - return(SM_RC_CONT); - } - - xcb = fsmxfr_get_new_xfr_context(call_id, line, FSMXFR_TYPE_XFR, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEROR); - if (xcb == NULL) { - break; - } - - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - - xcb->type = FSMXFR_TYPE_DIR_XFR; - xcb->cns_call_id = other_fcb->dcb->call_id; - - other_fcb->xcb = xcb; - /* - * Emulating user hitting transfer key for second time - * in attended transfer - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_DIRTRXFR, NULL); - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - return(SM_RC_END); - - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - if ((cause != CC_CAUSE_XFER_CNF) && - (ftr_data && msg->data_valid) && - (ftr_data->xfer.target_call_id != CC_NO_CALL_ID) && - ((cns_fcb = fsm_get_fcb_by_call_id_and_type(ftr_data->xfer.target_call_id, - FSM_TYPE_XFR)) != NULL)) { - /* In this case there is no active xcb but upper layer - * wants to complete a trasnfer with 2 different call_ids - */ - xcb = fsmxfr_get_new_xfr_context(call_id, line, FSMXFR_TYPE_XFR, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEROR); - if (xcb == NULL) { - return(SM_RC_END); - } - - fcb->xcb = xcb; - cns_fcb->xcb = xcb; - xcb->type = FSMXFR_TYPE_DIR_XFR; - - xcb->cns_call_id = ftr_data->xfer.target_call_id; - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - /* Find line information for target call. - */ - if (fcb_def && fcb_def->dcb) { - - xcb->cns_line = fcb_def->dcb->line; - - } else { - - return(SM_RC_END); - } - - fsm_change_state(cns_fcb, __LINE__, FSMXFR_S_ACTIVE); - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->xfr_call_id, - line, CC_FEATURE_DIRTRXFR, NULL); - - return(SM_RC_END); - } - - /* - * This call is the transferor and we are initiating a local - * transfer. So: - * 1. Make sure we have a free line to open a new call plane to - * collect digits (and place call) for the transfer target, - * 2. Create a new transfer context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check for any other active features which may block - * the transfer. - */ - - /* - * The call must be in the connected state to initiate a transfer. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && - (fcb_def->state != FSMDEF_S_CONNECTED) && - (cause != CC_CAUSE_XFER_CNF)) { - break; - } - - /* - * If it's not a conference transfer make sure we have a free - * line to start the consultation call. - */ - if (cause != CC_CAUSE_XFER_CNF) { - //CSCsz38962 don't use expline for local-initiated transfer - //free_lines = lsm_get_instances_available_cnt(line, TRUE); - free_lines = lsm_get_instances_available_cnt(line, FALSE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this request. - */ - fsm_display_no_free_lines(); - - break; - } - - newcall_line = lsm_get_newcall_line(line); - if (newcall_line == NO_LINES_AVAILABLE) { - /* - * Error Pass Limit - let the user know and end this request. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return (FALSE); - } - } - - /* - * Get a new xcb and new xfr id - This is the handle that will - * identify the xfr. - */ - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEROR); - if (xcb == NULL) { - break; - } - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - /* - * If not conference transfer initiate the consultation call. - * For conference transfer we already have both calls setup. - */ - if (cause != CC_CAUSE_XFER_CNF) { - /* - * Set the consultative line to new line id. - */ - xcb->cns_line = newcall_line; - /* - * Record the active feature if it is a blind xfer. - */ - if (ftr_id == CC_FEATURE_BLIND_XFER) { - dcb->active_feature = ftr_id; - } - - /* - * This call needs to go on hold so we can start the - * consultation call. Indicate feature indication should - * be send and set the feature reason. - */ - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = CC_REASON_XFER; - data.hold.msg_body.num_parts = 0; - data.hold.call_info.data.call_info_feat_data.protect = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - - cns_call_id = xcb->cns_call_id; - if (ftr_data->xfer.cause == CC_CAUSE_XFER_LOCAL_WITH_DIALSTRING) { - cc_int_dialstring(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - ftr_data->xfer.dialstring, NULL, 0); - } else { - data.newcall.cause = CC_CAUSE_XFER_LOCAL; - if (ftr_data->xfer.dialstring[0] != 0) { - data.newcall.cause = CC_CAUSE_XFER_BY_REMOTE; - sstrncpy(data.newcall.dialstring, ftr_data->xfer.dialstring, - CC_MAX_DIALSTRING_LEN); - } - - if (ftr_data->xfer.global_call_id[0] != 0) { - sstrncpy(data.newcall.global_call_id, - ftr_data->xfer.global_call_id, CC_GCID_LEN); - } - data.newcall.prim_call_id = xcb->xfr_call_id; - data.newcall.hold_resume_reason = CC_REASON_XFER; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - CC_FEATURE_NEW_CALL, &data); - } - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), - xcb->xfr_id, call_id, cns_call_id, __LINE__); - } else { - other_fcb = - fsm_get_fcb_by_call_id_and_type(msg->data.xfer.target_call_id, - FSM_TYPE_XFR); - if (other_fcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - break; - } - - other_fcb->xcb = xcb; - /* - * The xfr_call_id is the call that is being replaced by - * the cns_call_id. - */ - fsmxfr_update_xfr_context(xcb, xcb->cns_call_id, - msg->data.xfer.target_call_id); - xcb->cnf_xfr = TRUE; - fsm_change_state(other_fcb, __LINE__, FSMXFR_S_ACTIVE); - /* - * Emulating user hitting transfer key for second time - * in attended transfer - */ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_XFER, NULL); - } - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_NEW_CALL: - - /* - * If this is the consultation call involved in a transfer, - * then set the rest of the data required to make the transfer - * happen. The data is the xcb in the fcb. The data is set now - * because we did not have the fcb when the transfer was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a transfer event is received. - * - * Or this could be the call that originated the - * transfer (the transferor) and - * the person he was talking to (the transfer target) has - * decided to transfer the transferor to another target. - */ - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb == NULL) { - break; - } - fcb->xcb = xcb; - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - if (msg->data_valid == FALSE) { - break; - } - - method = msg->data.xfer.method; - - switch (method) { - case CC_XFER_METHOD_BYE: - /* - * This is a remote initiated transfer using the - * BYE/ALSO method. - * - * The transferor has sent us, the transferee, a BYE with - * the transfer target. - * - * 1. Create a new transfer context - * 2. Ack the feature request. - * - * We need to wait for the RELEASE from SIP and then we will - * send out the NEWCALL to initiate the call to the target. - */ - - /* - * Transfer is valid only for a remote originated transfer. - */ - if (msg->data.xfer.cause != CC_CAUSE_XFER_REMOTE) { - break; - } - - /* - * Check for any other active features which may block - * the transfer. - */ - - /* - * Get a new xcb and new xfr id - This is the handle that will - * identify the xfr. - */ - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, method, - FSMXFR_MODE_TRANSFEREE); - if (xcb == NULL) { - break; - } - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - - fsmxfr_set_xfer_data(CC_CAUSE_OK, method, - xcb->cns_call_id, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, ftr_id, &data, CC_CAUSE_NORMAL); - - /* - * Make sure we have a valid dialstring. - */ - if (fsmxfr_copy_dialstring(&xcb->dialstring, - msg->data.xfer.dialstring) == TRUE) { - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - } else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - - break; - - case CC_XFER_METHOD_REFER: - /* - * This event is because: - * 1. we are the target involved in a transfer or - * 2. it is a remote initiated transfer using the REFER method. - * - * Case 1: - * The transferee has attempted to setup a call with us, - * the target. The call has been setup successfully so the - * SIP stack is informing us that we are the target. - * - * 1. Ack the request, - * 2. Create a new transfer context. - * - * Case 2: - * The transferor has sent us, the transferee, a REFER with - * the transfer target. We will attempt to contact the target - * and then report the result to the transferor. - * - * 1. Verify that we have a free line to start the - * consultation call, - * 2. Create a new transfer context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check if this is case 1. - * We know this because the target_call_id can only be set - * for this case. - */ - if ((msg->data.xfer.cause == CC_CAUSE_XFER_REMOTE) && - (msg->data.xfer.target_call_id != CC_NO_CALL_ID)) { - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TARGET); - if (xcb == NULL) { - break; - } - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - - /* - * The xfr_call_id is the call that is being replaced by - * the cns_call_id (which the stack supplied). - */ - fsmxfr_update_xfr_context(xcb, xcb->cns_call_id, - msg->data.xfer.target_call_id); - cns_call_id = xcb->cns_call_id; - /* - * Set the correct xfer_data. The target_call_id must be - * CC_NO_CALL_ID so that the stack can tell that this is - * a case 1 transfer. - */ - fsmxfr_set_xfer_data(CC_CAUSE_XFER_REMOTE, - method, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, ftr_id, &data, - CC_CAUSE_NORMAL); - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - break; - } - - /* - * I guess we are at case 2... - * Transfer should be done only if call's present state - * is either on hold or connected - */ - fcb_def = - fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def->state == FSMDEF_S_CONNECTED) || - (fcb_def->state == FSMDEF_S_CONNECTED_MEDIA_PEND) || - (fcb_def->state == FSMDEF_S_RESUME_PENDING) || - (fcb_def->state == FSMDEF_S_HOLD_PENDING) || - (fcb_def->state == FSMDEF_S_HOLDING)) { - int_rc = - fsmxfr_remote_transfer(fcb, ftr_id, call_id, dcb->line, - msg->data.xfer.dialstring, - msg->data.xfer.referred_by); - } - - if (int_rc == FALSE) { - fsmxfr_set_xfer_data(CC_CAUSE_ERROR, CC_XFER_METHOD_REFER, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, ftr_id, &data, CC_CAUSE_ERROR); - } - break; - - default: - break; - } /* switch (xfr_data->method) */ - - break; - case CC_FEATURE_NOTIFY: - if (ftr_data->notify.subscription != CC_SUBSCRIPTIONS_XFER) { - /* This notify is not for XFER subscription */ - break; - } - data.notify.cause = msg->data.notify.cause; - data.notify.cause_code = msg->data.notify.cause_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = - msg->data.notify.blind_xferror_gsm_id; - data.notify.final = TRUE; - - if (data.notify.blind_xferror_gsm_id == CC_NO_CALL_ID) { - if (msg->data.notify.cause == CC_CAUSE_OK) { - data.endcall.cause = CC_CAUSE_OK; - sm_rc = SM_RC_END; - /* - * If dcb is NULL, we received a final NOTIFY after the - * the dcb was cleared. This can happen when we receive - * BYE before final NOTIFY on the result of the REFER - * sent for xfer. If dcb is NULL, just quietly ignore - * the NOTIFY event. Otherwise, kick off the release of - * the call. - */ - if (dcb) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - } - } - } else { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - data.notify.blind_xferror_gsm_id, - line, CC_FEATURE_NOTIFY, &data); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -static sm_rcs_t -fsmxfr_ev_idle_dialstring (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - fsmxfr_xcb_t *xcb; - sm_rcs_t sm_rc = SM_RC_CONT; - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb == NULL) { - return sm_rc; - } - fcb->xcb = xcb; - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - return (fsmxfr_ev_active_dialstring(event)); -} - - - - -static sm_rcs_t -fsmxfr_ev_active_proceeding (sm_event_t *event) -{ - cc_proceeding_t *msg = (cc_proceeding_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t data; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - callid_t other_call_id; - line_t other_line; - - /* - * Ignore this event if this call is not involved in a transfer - * or we are not the target of the transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb == NULL) || (xcb->mode != FSMXFR_MODE_TARGET)) { - return (SM_RC_CONT); - } - - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - other_line = fsmxfr_get_other_line(xcb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, FSM_TYPE_DEF); - - /* - * Release the transfer call. - * - * We need to release the transfer call (which is really - * the consultation call from the transferor to us - * the target), because we want the next call coming in - * to replace this one. - */ - data.endcall.cause = CC_CAUSE_REPLACE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - other_line, CC_FEATURE_END_CALL, &data); - - /* - * Only answer the call if the call being replaced was connected - * or is currently connected, otherwise just let this call be setup - * normally so that it will ring. - */ - - if (other_fcb && (other_fcb->old_state == FSMDEF_S_CONNECTED || - other_fcb->old_state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->old_state == FSMDEF_S_RESUME_PENDING || - other_fcb->state == FSMDEF_S_CONNECTED || - other_fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->state == FSMDEF_S_RESUME_PENDING)) { - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, call_id, - line, CC_FEATURE_ANSWER, NULL); - } - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmxfr_ev_active_connected_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_connected_ack_t *msg = (cc_connected_ack_t *) event->msg; - fsmxfr_xcb_t *xcb; - - /* - * If we are the target and this is the call from the transferree - * to the target, then we need to cleanup the rest of the transfer. - * We need to do this because the consultation call is already cleared - * from the transfer but the transfer call was not. - */ - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(msg->call_id); - if ((xcb == NULL) || (xcb->mode != FSMXFR_MODE_TARGET)) { - return (SM_RC_CONT); - } - - /* - * Remove this call from the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, FALSE); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmxfr_ev_active_release (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_release"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - callid_t new_call_id; - callid_t other_call_id; - line_t other_line; - fsmxfr_xcb_t *xcb = fcb->xcb; - cc_feature_data_t data; - boolean secondary = FALSE; - cc_action_data_t action_data; - fsm_fcb_t *other_fcb; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_ev_active_release")); - - /* - * Complete a transfer if we have a pending transfer. - */ - memset(&data, 0, sizeof(cc_feature_data_t)); - - /* - * Check if this is a transfer of a transfer. - */ - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find a transfer call to cancel.", fname); - return (SM_RC_CONT); - } - - if ((xcb->active == TRUE) && (xcb->xcb2 != NULL)) { - xcb = xcb->xcb2; - secondary = TRUE; - } - - if ((xcb->dialstring != NULL) && (xcb->dialstring[0] != '\0')) { - /* - * Grab the call_id for the call to the target. - * This will either already be in the xcb or we will need to - * get a new one. The call_id will be in the xcb if we are the - * transferee. - */ - if (xcb->active == TRUE) { - new_call_id = cc_get_new_call_id(); - fsmxfr_update_xfr_context(xcb, call_id, new_call_id); - } else { - new_call_id = fsmxfr_get_other_call_id(xcb, call_id); - if (secondary == TRUE) { - fsmxfr_update_xfr_context(fcb->xcb, call_id, new_call_id); - } - } - - data.newcall.cause = CC_CAUSE_XFER_REMOTE; - sstrncpy(data.newcall.dialstring, xcb->dialstring, - CC_MAX_DIALSTRING_LEN); - - cpr_free(xcb->dialstring); - xcb->dialstring = NULL; - memset(data.newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - if (xcb->referred_by != NULL) { - sstrncpy(data.newcall.redirect.redirects[0].number, - xcb->referred_by, CC_MAX_DIALSTRING_LEN); - - cpr_free(xcb->referred_by); - xcb->referred_by = NULL; - } - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, new_call_id, - dcb->line, CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, __LINE__); - - if (secondary == TRUE) { - fsmxfr_init_xcb(xcb); - fcb->xcb->active = FALSE; - fcb->xcb->xcb2 = NULL; - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else if (xcb->active == TRUE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, FALSE); - fcb->xcb->active = FALSE; - } else { - /* - * Reset the xcb call_id that was used for the call to the target. - * The value was just temporary and it needs to be reset so that - * the cleanup function works properly. - */ - fsmxfr_update_xfr_context(xcb, new_call_id, CC_NO_CALL_ID); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - - xcb->active = FALSE; - } else { - if (secondary == TRUE) { - /* - * This is the secondary transfer of a primary transfer. - * We need to: - * 1. update the primary xcb to point to this just transferred - * call, - * 2. mark the primary xcb as inactive since we just completed the - * secondary transfer, - * 3. point the newly transferred call to the primary xcb and - * update the UI to show that this is a local transfer (the - * UI was set as though the call was a remote transfer). - * 4. blow away this secondary xcb and cleanup the fcb, - */ - new_call_id = fsmxfr_get_other_call_id(xcb, call_id); - fsmxfr_update_xfr_context(fcb->xcb, call_id, new_call_id); - - fcb->xcb->active = FALSE; - - other_fcb = fsm_get_fcb_by_call_id_and_type(new_call_id, - FSM_TYPE_XFR); - if (other_fcb == NULL) { - return (SM_RC_CONT); - } - other_fcb->xcb = fcb->xcb; - - fsmxfr_init_xcb(xcb); - - action_data.update_ui.action = CC_UPDATE_XFER_PRIMARY; - (void)cc_call_action(other_fcb->dcb->call_id, dcb->line, - CC_ACTION_UPDATE_UI, &action_data); - - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else { - /* - * One of the parties in the transfer has decided to release - * the call, so go ahead and cleanup this transfer. - */ - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - other_line = fsmxfr_get_other_line(xcb, call_id); - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - if (xcb->cnf_xfr) { - /* - * This is the transfer for bridging a transfer call so - * clear the second line also. - */ - xcb->cnf_xfr = FALSE; - if (other_fcb == NULL) { - return (SM_RC_CONT); - } - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - other_line, CC_FEATURE_END_CALL, NULL); - } - - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - - } - } - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmxfr_ev_active_release_complete (sm_event_t *event) -{ - fsmxfr_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - - return (SM_RC_CONT); -} - -static char *fsmxfr_get_dialed_num (fsmdef_dcb_t *dcb) -{ - static const char fname[] = "fsmxfr_get_dialed_num"; - char *tmp_called_number; - /* Get the dialed number only if the call is outgoing type */ - - tmp_called_number = lsm_get_gdialed_digits(); - - DEF_DEBUG(DEB_F_PREFIX"called_dialed_num = %s", - DEB_F_PREFIX_ARGS(GSM, fname), tmp_called_number); - - /* Get dialed number to put in the refer-to header. If there - * is no dialed number then use RPID or from header value - */ - if (tmp_called_number == NULL || (*tmp_called_number) == NUL) { - - if (dcb->caller_id.called_number[0] != NUL) { - DEF_DEBUG(DEB_F_PREFIX"called_dcb_num = %s", - DEB_F_PREFIX_ARGS(GSM, fname), (char *)dcb->caller_id.called_number); - return((char *)dcb->caller_id.called_number); - - } else { - DEF_DEBUG(DEB_F_PREFIX"calling_dcb_num = %s", - DEB_F_PREFIX_ARGS(GSM, fname), (char *)dcb->caller_id.calling_number); - return((char *)dcb->caller_id.calling_number); - } - } - - /* - * if tmp_called_number is same as what we receive in RPID, - * then get the called name from RPID if provided. - */ - if (dcb->caller_id.called_number != NULL && - dcb->caller_id.called_number[0] != NUL) { - /* if Cisco PLAR string is used, use the RPID value */ - if (strncmp(tmp_called_number, CC_CISCO_PLAR_STRING, sizeof(CC_CISCO_PLAR_STRING)) == 0) { - tmp_called_number = (char *)dcb->caller_id.called_number; - } - } - - return(tmp_called_number); -} - -static void -fsmxfr_initiate_xfr (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_initiate_xfr"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsm_fcb_t *cns_fcb = NULL; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmdef_dcb_t *xfr_dcb; - fsmdef_dcb_t *cns_dcb; - cc_feature_data_t data; - fsmxfr_xcb_t *xcb = fcb->xcb; - char *called_num = NULL; - - /* - * Place the consultation call on hold. - */ - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - return; - } - - cns_dcb = fsm_get_dcb(xcb->cns_call_id); - cns_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_DEF); - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - - /* - * If the consultation call is not connected - * treat it like a blind xfer. - */ - if (cns_fcb != NULL) { - /* - * If the transfer key is pressed twice, before the sofkey gets - * updated in response to first transfer key, the 2nd transfer key - * press is treated as a transfer complete and we try to initate - * the transfer to the connected call itself. To prevent this, check - * the state of the call to see if we should - * ignore the 2nd transfer key press. - */ - if ((cns_fcb->state == FSMDEF_S_COLLECT_INFO) || - (cns_fcb->state == FSMDEF_S_OUTGOING_PROCEEDING) || - (cns_fcb->state == FSMDEF_S_KPML_COLLECT_INFO)) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Ignore the xfer xid %d cid %d %d", - DEB_L_C_F_PREFIX_ARGS(FSM, xcb->xfr_line, xcb->xfr_call_id, "fsmxfr_initiate_xfr"), - xcb->xfr_id, xcb->xfr_call_id, xcb->cns_call_id); - return; - } - - /* - * Indicate that xfer completion has been requested - */ - xcb->xfer_comp_req = TRUE; - - if (cns_fcb->state < FSMDEF_S_CONNECTED) { - data.endcall.cause = CC_CAUSE_NO_USER_RESP; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_dcb->call_id, - cns_dcb->line, CC_FEATURE_END_CALL, &data); - /* - * Instruct the stack to transfer the call. - */ - called_num = fsmxfr_get_dialed_num(cns_dcb); - if (called_num && called_num[0] != '\0') { - - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, cns_dcb->call_id, - called_num, - &(data.xfer)); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - if (xcb->cnf_xfr) { - /* - * If it is a conference transfer clear up the - * calls. - */ - fsmxfr_cnf_cleanup(xcb); - } - } - } else { - /* - * If the consulation call is already on hold and - * the intial call isn't then place ourselves on - * hold (user hit the rocker arm switch). Otherwise, - * place the consulation call on hold. Make sure we - * do not send feature indication by setting the - * call info type to none. - */ - data.hold.call_info.type = CC_FEAT_NONE; - data.hold.msg_body.num_parts = 0; - if (((cns_fcb->state == FSMDEF_S_HOLDING) || - (cns_fcb->state == FSMDEF_S_HOLD_PENDING)) && - ((fcb->state != FSMDEF_S_HOLDING) && - (fcb->state != FSMDEF_S_HOLD_PENDING))) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - } else { - /* just place on hold */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - cns_dcb->call_id, cns_dcb->line, - CC_FEATURE_HOLD, &data); - } - } - } -} - -static sm_rcs_t -fsmxfr_ev_active_feature (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *feat_data = &(msg->data); - fsmdef_dcb_t *xfr_dcb, *cns_dcb; - cc_feature_data_t data; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmxfr_xcb_t *xcb = fcb->xcb; - boolean int_rc; - char tmp_str[STATUS_LINE_MAX_LEN]; - char *called_num = NULL; - fsm_fcb_t *cns_fcb = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - return (SM_RC_CONT); - } - - /* - * Consume the XFER and NOTIFY events and don't pass them along - * to the other FSMs. - */ - if ((ftr_id == CC_FEATURE_BLIND_XFER) || - (ftr_id == CC_FEATURE_XFER) || (ftr_id == CC_FEATURE_NOTIFY)) { - if (ftr_id == CC_FEATURE_NOTIFY) { - if (msg->data_valid && - (msg->data.notify.subscription != CC_SUBSCRIPTIONS_XFER)) { - /* The subscription is not XFER, let the event flow through */ - return (SM_RC_CONT); - } - } - sm_rc = SM_RC_END; - } - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_EXPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_XFER: - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - DEF_DEBUG(DEB_F_PREFIX"ACTIVE XFER call_id = %d, cns_id = %d, t_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, - feat_data->xfer.target_call_id, xcb->cns_call_id); - - if (feat_data && msg->data_valid && - (xcb->cns_call_id != feat_data->xfer.target_call_id)) { - - cns_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_DEF); - - if (cns_fcb != NULL) { - DEF_DEBUG(DEB_F_PREFIX"INVOKE ACTIVE XFER call_id = %d, t_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, - feat_data->xfer.target_call_id); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->xfr_call_id, - xcb->xfr_line, CC_FEATURE_DIRTRXFR, NULL); - } - - return(SM_RC_END); - } - switch (xcb->method) { - case CC_XFER_METHOD_BYE: - case CC_XFER_METHOD_REFER: - /* - * This is the second transfer event for a local - * attended transfer with consultation. - * - * The user is attempting to complete the transfer, so - * 1. place the consultation call on hold, - * 2. instruct the stack to transfer the call. - */ - fsmxfr_initiate_xfr(event); - lsm_set_hold_ringback_status(xcb->cns_call_id, FALSE); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) { */ - break; - case CC_FEATURE_RESUME: - break; - - case CC_FEATURE_END_CALL: - if (xcb->mode == FSMXFR_MODE_TRANSFEREE) { - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (call_id == xcb->cns_call_id) { - /* - * Transferee ended call before transfer was completed. - * Notify the transfer call of the status of the - * transfer. - */ - data.notify.cause = CC_CAUSE_ERROR; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.final = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_NOTIFY, &data); - } - } - lsm_set_hold_ringback_status(xcb->cns_call_id, TRUE); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_HOLD: - if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_SWAP || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_XFER || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_INTERNAL)) - { - feat_data->hold.call_info.data.call_info_feat_data.protect = TRUE; - } else { - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, xcb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_DIRTRXFR: - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - called_num = fsmxfr_get_dialed_num(xfr_dcb); - - if (called_num && called_num[0] != '\0') { - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, xcb->cns_call_id, - called_num, - &(data.xfer)); - - data.xfer.method = CC_XFER_METHOD_DIRXFR; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - call_id, line, - CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - return(SM_RC_END); - case CC_FEATURE_END_CALL: - /* - * Only cleanup the whole xfer if we know that we don't have - * an outstanding blind transfer and if we are not the target. - * We need the xcb to hang around because other users (lsm,...) - * may still want to do something special and the xcb is the only - * way they know that the call is involved in a transfer. - */ - if (xcb->type == FSMXFR_TYPE_BLND_XFR) { - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else if ((xcb->type == FSMXFR_TYPE_XFR) && - (msg->data.endcall.cause == CC_CAUSE_NO_USER_RESP)) { - - DEF_DEBUG(DEB_F_PREFIX"Xfer type =%d", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->type); - - if ((platGetPhraseText(STR_INDEX_TRANSFERRING, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - lsm_ui_display_status(tmp_str, xcb->xfr_line, xcb->xfr_call_id); - } - - if (xcb->xfer_comp_req == FALSE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - } else { - // Mark it as transfer complete. - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - } - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else if (xcb->mode == FSMXFR_MODE_TARGET) { - break; - } else { - /* Early attended transfer generates internal END_CALL event - * do not send cancel in that case - */ - if (xcb->xfer_comp_req == FALSE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - } - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - break; - - case CC_FEATURE_HOLD: - ui_set_local_hold(dcb->line, dcb->call_id); - if(msg->data_valid) { - feat_data->hold.call_info.data.call_info_feat_data.protect = TRUE; - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALL_PRESERVATION: - DEF_DEBUG(DEB_F_PREFIX"Preservation call_id = %d t_call_id=%d", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, xcb->cns_call_id); - ui_terminate_feature(xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - if (msg->data_valid == FALSE) { - break; - } - - /* - * Transfer is valid only for a remote originated transfer. - */ - if (msg->data.xfer.cause != CC_CAUSE_XFER_REMOTE) { - break; - } - - /* - * This call is already involved in a transfer as the transferor, - * but one of the parties, the transferee or target has decided to - * transfer that leg also. So, now we have a transfer of a transfer. - */ - switch (msg->data.xfer.method) { - case CC_XFER_METHOD_BYE: - /* - * Check for any other active features which may block - * the transfer. - */ - - fsmxfr_set_xfer_data(CC_CAUSE_OK, CC_XFER_METHOD_BYE, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, ftr_id, &data, CC_CAUSE_NORMAL); - - /* - * Make sure we have a valid dialstring. - */ - if (fsmxfr_copy_dialstring(&xcb->dialstring, - msg->data.xfer.dialstring) == FALSE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - } - - /* - * Mark the active flag in the xcb. This flag is used later - * when the RELEASE comes from SIP, so that the GSM - * knows that this call is still involved in a transfer. - */ - xcb->active = TRUE; - - break; - - case CC_XFER_METHOD_REFER: - int_rc = fsmxfr_remote_transfer(fcb, ftr_id, call_id, dcb->line, - msg->data.xfer.dialstring, - msg->data.xfer.referred_by); - - if (int_rc == FALSE) { - fsmxfr_set_xfer_data(CC_CAUSE_ERROR, CC_XFER_METHOD_REFER, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, - dcb->line, ftr_id, &data, - CC_CAUSE_ERROR); - } - break; - - default: - break; - } /* switch (msg->data.xfer.method) */ - - break; - - case CC_FEATURE_NOTIFY: - /* - * This could be: - * 1. for an unattended transfer. - * The transferee is notifying us, the transferor, of the status - * of the transfer, ie. was the transferee able to connect to - * the target? - * - * 2. Or this is an attended transfer, and this is the call from - * the transferee to the target. The stack will NOTIFY the GSM - * of the status of the call after it receives a message - * from the network indicating success of failure. - */ - if (msg->data_valid == FALSE) { - break; - } - - /* - * Ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_NOTIFY, NULL, - CC_CAUSE_NORMAL); - - switch (xcb->type) { - case FSMXFR_TYPE_BLND_XFR: - switch (msg->data.notify.method) { - case CC_XFER_METHOD_BYE: - /* - * This notification is really from the SIP stack. - * The network will not send a NOTIFY for a BYE/Also - * transfer, so the SIP stack just sends one up when - * it uses that method. - */ - - /* - * Release the transfer call. - */ - data.endcall.cause = CC_CAUSE_OK; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_END_CALL, &data); - break; - - case CC_XFER_METHOD_REFER: - if (msg->data.notify.cause == CC_CAUSE_OK) { - /* - * Release the transfer call. - */ - /* Set the dcb flag to indicate transfer is complete, so that - * it won't display endcall in this case - */ - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - - data.endcall.cause = CC_CAUSE_OK; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_END_CALL, &data); - } else { - fsmxfr_cleanup(fcb, __LINE__, TRUE); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_RESUME, NULL); - } - break; - - default: - break; - } /* switch (msg->data.notify.method) { */ - - break; - case FSMXFR_TYPE_DIR_XFR: - /* - * Clear the transfer call if the transfer was OK, - * else just cleanup the transfer. The consultation - * call will be released by the target. - */ - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (msg->data.notify.cause == CC_CAUSE_OK) { - data.endcall.cause = CC_CAUSE_OK; - - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_END_CALL, - &data); - } else { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->xfr_call_id); - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->cns_call_id); - } - if (xcb->cnf_xfr) { - /* - * If it is a conference transfer clear up the - * calls. - */ - fsmxfr_cnf_cleanup(xcb); - } - break; - - case FSMXFR_TYPE_XFR: - switch (msg->data.notify.method) { - case CC_XFER_METHOD_BYE: - /* - * Release the consultation call. - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->cns_call_id, - dcb->line, CC_FEATURE_END_CALL, NULL); - - /* - * Release the call being transferred. - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->xfr_call_id, - dcb->line, CC_FEATURE_END_CALL, NULL); - break; - - case CC_XFER_METHOD_REFER: - /* - * This notification is from either the target (which is - * the consultation call) or the transferee (which is the - * transfer call). - * - * So, do the following based on each case: - * - * 1. consultation call: this is the transferee receiving - * notification of the status of the call from the - * transferee to the target. - * - notify the transfer call. - * - the transfer call will be released by the transferor - * after receiving the above notification and the - * consultation call will remain. - * - * 2. transfer call: this is the transferor receiving - * notification of the status of the call from the - * transferee to the target. - * - release the transfer call. - * - the consultation call will be released by the target. - */ - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (call_id == xcb->cns_call_id) { - /* - * Notify the transfer call of the status of the - * transfer. - */ - data.notify.cause = msg->data.notify.cause; - data.notify.cause_code = msg->data.notify.cause_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = - msg->data.notify.blind_xferror_gsm_id; - data.notify.final = TRUE; - if (data.notify.blind_xferror_gsm_id == CC_NO_CALL_ID) { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - xfr_dcb->call_id, xfr_dcb->line, - CC_FEATURE_NOTIFY, &data); - } else { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - data.notify.blind_xferror_gsm_id, - msg->line, CC_FEATURE_NOTIFY, &data); - } - } else { - /* - * Clear the transfer call if the transfer was OK, - * else just cleanup the transfer. The consultation - * call will be released by the target. - */ - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - break; - } - - if (msg->data.notify.cause == CC_CAUSE_OK) { - data.endcall.cause = CC_CAUSE_OK; - - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_END_CALL, - &data); - } else { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->xfr_call_id); - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, FALSE); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - /* - * Resume the consultation call. - * if xcb->cns_call_id == 0, then cns call is already ended. - */ - if (xcb->cns_call_id != CC_NO_CALL_ID) { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->cns_call_id); - cns_dcb = fsm_get_dcb (xcb->cns_call_id); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xcb->cns_call_id, cns_dcb->line, - CC_FEATURE_RESUME, NULL); - } - - if (xcb->cnf_xfr) { - /* - * If it is a conference transfer clear up the - * calls. - */ - fsmxfr_cnf_cleanup(xcb); - } - } - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } /* if (call_id == xcb->cns_call_id) */ - break; - - default: - break; - } /* switch (msg->data.notify.method) { */ - - break; - - default: - break; - } /* switch (xcb->type) { */ - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -static void -fsmxfr_requeue_blind_xfer_dialstring (fsmdef_dcb_t *dcb, fsmxfr_xcb_t *xcb) -{ - /* - * This is the result of the feature hold so we - * can clear the active feature. - */ - dcb->active_feature = CC_FEATURE_NONE; - - /* - * If there is a dialstring on the xcb, it is because the - * dialstring event for the consultative call has already - * been received. We delayed handling the dialstring until - * the result of the hold request has been received. We - * are now ready to process the dial string so requeue it - * for processing - */ - if (xcb->queued_dialstring && xcb->queued_dialstring[0] != '\0') { - cc_dialstring(CC_SRC_UI, xcb->cns_call_id, dcb->line, - xcb->queued_dialstring); - cpr_free(xcb->queued_dialstring); - xcb->queued_dialstring = NULL; - } -} - -static sm_rcs_t -fsmxfr_ev_active_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t data; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmxfr_xcb_t *xcb = fcb->xcb; - fsmdef_dcb_t *xfr_dcb = NULL; - char *called_num = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - /* - * Consume the XFER events and don't pass them along to the other FSMs. - */ - if ((ftr_id == CC_FEATURE_BLIND_XFER) || (ftr_id == CC_FEATURE_XFER)) { - sm_rc = SM_RC_END; - } - - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - return (sm_rc); - } - - switch (src_id) { - case CC_SRC_SIP: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_BLIND_XFER: - switch (xcb->type) { - case FSMXFR_TYPE_BLND_XFR: - switch (msg->data.xfer.method) { - case CC_XFER_METHOD_REFER: - /* - * Clear the call if the transfer was OK, else just cleanup - * the transfer. - */ - if (msg->cause == CC_CAUSE_OK) { - // This does not indicate that transfer was successful. So wait for the NOTIFYs. - //data.endcall.cause = CC_CAUSE_OK; - - //cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - //dcb->line, CC_FEATURE_END_CALL, &data); - } else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (msg->data.xfer.method) { */ - - break; - - default: - break; - } /* switch (xcb->type) { */ - break; - - case CC_FEATURE_HOLD: - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - /* - * HOLD request is pending. Let this event drop through - * to the default sm for handling. - */ - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - /* - * If this is the hold response during a blind transfer, - * check to see if a dialstring has been queued for processing. - */ - if (xcb->type == FSMXFR_TYPE_BLND_XFR && - xcb->xfr_call_id == fcb->call_id) { - fsmxfr_requeue_blind_xfer_dialstring(dcb, xcb); - break; - } - - /* - * If xfer soft key has not been pressed a second time then - * don't transfer the call. - */ - if (!xcb->xfer_comp_req) { - break; - } - - - /* If there is any error reported from SIP stack then clear the - * transfer data. One such case is where digest authentication - * fails due to maximum retry (of 2). SIP stack generates a valid - * ACK event by setting cause code to ERROR - */ - if (msg->cause == CC_CAUSE_ERROR) { - - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->xfr_line, xcb->xfr_call_id); - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->cns_line, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - - break; - } - - /* - * Instruct the stack to transfer the call. - */ - if (xcb->type == FSMXFR_TYPE_XFR) { - /* - * Check to see which side of the transfer - * the request is coming from. if it is from - * the XFR side, make sure the CNS side is - * indeed in the Held state. - */ - if (xcb->cns_call_id == fcb->call_id) { - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - - called_num = fsmxfr_get_dialed_num(fcb->dcb); - - if (called_num && called_num[0] != '\0') { - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, fcb->dcb->call_id, - called_num, - &(data.xfer)); - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - } else { - /* - * This is hold response on the xfer call leg. - * - * Check to see if dialstring has been queued for - * processing. If so, it is requeued to GSM and - * we delay until the consultative call is setup. - */ - //if (fsmxfr_requeue_blind_xfer_dialstring(dcb, xcb)) { - // break; - //} - - /* - * Get the dcb of the consultative call. - */ - xfr_dcb = fsm_get_dcb(xcb->cns_call_id); - - /* - * We must wait for the hold request on the consultative - * call to complete before completing the xfer. The state - * of the consultative call must be FSMDEF_S_HOLDING. - * FSMDEF_S_HOLDING is not a completed hold request which - * is why it is not checked for here. - */ - if (xfr_dcb->fcb->state != FSMDEF_S_HOLDING) { - break; - } else { - - called_num = fsmxfr_get_dialed_num(xfr_dcb); - - if (called_num && called_num[0] != '\0') { - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, xfr_dcb->call_id, - called_num, - &(data.xfer)); - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - fcb->dcb->call_id, fcb->dcb->line, - CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - } - } - } - break; - - case CC_FEATURE_XFER: - - if (msg->cause != CC_CAUSE_OK) { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->xfr_line, xcb->xfr_call_id); - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->cns_line, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } else { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmxfr_ev_active_onhook (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_onhook"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_onhook_t *msg = (cc_onhook_t *) event->msg; - callid_t call_id = msg->call_id; - callid_t other_call_id; - fsmxfr_xcb_t *xcb = fcb->xcb; - fsm_fcb_t *other_fcb; - fsmdef_dcb_t *xfr_dcb; - cc_feature_data_t data; - fsm_fcb_t *cns_fcb, *xfr_fcb; - int onhook_xfer = 0; - - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer", fname); - return (SM_RC_CONT); - } - - cns_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, FSM_TYPE_DEF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(xcb->xfr_call_id, FSM_TYPE_DEF); - - if (xcb->cnf_xfr) { - /* - * This is the conference transfer so clear the - * second line also. - */ - xcb->cnf_xfr = FALSE; - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - other_fcb ? other_fcb->dcb->line:CC_NO_LINE, CC_FEATURE_END_CALL, NULL); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - return (SM_RC_CONT); - } - - if (xcb->mode == FSMXFR_MODE_TRANSFEREE) { - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (call_id == xcb->cns_call_id) { - /* - * Transferee ended call before transfer was completed. - * Notify the transfer call of the status of the - * transfer. - * - * Note: This must be changed when fix is put in for configurable - * onhook xfer (CSCsb86757) so that 200 NOTIFY is sent when - * xfer is completed. fsmxfr_initiate_xfr will take care - * of this for us so just need to make sure the NOTIFY is - * sent to SIP stack only when xfer is abandoned due to - * onhook. - */ - data.notify.cause = CC_CAUSE_ERROR; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.final = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_NOTIFY, &data); - if (cns_fcb && cns_fcb->state != FSMDEF_S_HOLDING && - cns_fcb->state != FSMDEF_S_HOLD_PENDING) { - fsmxfr_feature_cancel(xcb, xfr_dcb->line, - xcb->xfr_call_id, xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - /* - * fix bug CSCtb23681. - */ - if( xfr_dcb->fcb->state == FSMDEF_S_HOLDING ) - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xfr_dcb->call_id,xfr_dcb->line, CC_FEATURE_END_CALL, NULL); - return (SM_RC_CONT); - } - } - - if (msg->softkey) { - /* - * Softkey set to TRUE indicates endcall softkey was pressed. - * This causes the call with focus to release. - */ - if ((call_id == xcb->cns_call_id) && - (cns_fcb->state == FSMDEF_S_HOLDING || - cns_fcb->state == FSMDEF_S_HOLD_PENDING)) { - /* ignore the onhook event for the held consultation call */ - } if (msg->active_list == CC_REASON_ACTIVECALL_LIST) { - /* Active call list has been requested also - * existing consult call is canceled - * But transfer state machine will remain - * intact as feature layer is still running.*/ - xcb->cns_call_id = CC_NO_CALL_ID; - xcb->cns_line = CC_NO_LINE; - - }else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, - xcb->xfr_call_id, xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - return (SM_RC_CONT); - } else { - /* - * Softkey set to FALSE indicates handset, speaker button, or - * headset went onhook. This causes the transfer to complete - * if onhook xfer is enabled by config. - */ - config_get_value(CFGID_XFR_ONHOOK_ENABLED, &onhook_xfer, - sizeof(onhook_xfer)); - if (onhook_xfer && ((cns_fcb->state == FSMDEF_S_OUTGOING_ALERTING)|| - (cns_fcb->state == FSMDEF_S_CONNECTED))) { - fsmxfr_initiate_xfr(event); - return (SM_RC_END); - } else if (onhook_xfer && xfr_fcb && - ((xfr_fcb->state == FSMDEF_S_OUTGOING_ALERTING)|| - (xfr_fcb->state == FSMDEF_S_CONNECTED))) { - fsmxfr_initiate_xfr(event); - return (SM_RC_END); - } else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, - xcb->xfr_call_id, xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - - fsmxfr_cleanup(fcb, __LINE__, TRUE); - return (SM_RC_CONT); - } - } -} - - -/* - * This event can only happen if the user initiated a blind transfer. - */ -static sm_rcs_t -fsmxfr_ev_active_dialstring (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_dialstring"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_dialstring_t *msg = (cc_dialstring_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - fsmdef_dcb_t *xfr_dcb; - fsmxfr_xcb_t *xcb = fcb->xcb; - cc_feature_data_t data; - char *dialstring; - - /* - * Make sure we have a valid dialstring. - */ - dialstring = msg->dialstring; - if ((dialstring == NULL) || (dialstring[0] == '\0')) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"dialstring= %c", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, call_id, fname), '\0'); - return (SM_RC_END); - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"dialstring= %s", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, call_id, fname), dialstring); - - /* - * If this is a blind xfer and we have received the dialstring - * before the original call has received a response to the hold - * request, defer processing the dialstring event. active_feature - * will be set to CC_FEATURE_BLIND_XFER if we are still waiting - * for the hold response. The dial string is saved on the xcb - * until needed. - */ - if (xcb == NULL) { - return (SM_RC_END); - } - - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (xfr_dcb == NULL) { - return (SM_RC_END); - } - - if (xfr_dcb->active_feature == CC_FEATURE_BLIND_XFER) { - if (!fsmxfr_copy_dialstring(&xcb->queued_dialstring, dialstring)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX"unable to copy dialstring", - msg->line, call_id, fname); - } - return (SM_RC_END); - } - - if (xcb->type == FSMXFR_TYPE_BLND_XFR) { - lsm_set_hold_ringback_status(xcb->cns_call_id, FALSE); - } - /* - * Make sure that this event came from the consultation call and that - * this is a blind transfer. We ignore the event if this is a transfer - * with consultation, because we want to talk to the target. For an - * unattended transfer this event is the final event needed to complete - * the transfer. - */ - if ((xcb->cns_call_id != call_id) || (xcb->type != FSMXFR_TYPE_BLND_XFR)) { - return (SM_RC_CONT); - } - - switch (xcb->method) { - case CC_XFER_METHOD_BYE: - case CC_XFER_METHOD_REFER: - /* - * This is an unattended transfer so: - * 1. clear the consultation call, - * 2. instruct the stack to initiate the transfer. - */ - - /* - * Release this call because it was only used to collect digits. - */ - data.endcall.cause = CC_CAUSE_NORMAL; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, &data); - - - /* - * Send an event to the transferer call leg so it can send the called - * number to the transferee. - */ - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, xcb->method, CC_NO_CALL_ID, - dialstring, &(data.xfer)); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xcb->xfr_call_id, - line, fsmxfr_type_to_feature(xcb->type), &data); - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), - xcb->xfr_id, xcb->xfr_call_id, xcb->cns_call_id, __LINE__); - - break; - - default: - break; - } /* switch (xcb->method) */ - - return (SM_RC_END); -} - - -cc_int32_t -fsmxfr_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmxfr_xcb_t *xcb; - int i = 0; - - /* - * Check if need help. - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("show fsmxfr\n"); - return (0); - } - - debugif_printf("\n------------------------ FSMXFR xcbs -------------------------"); - debugif_printf("\ni xfr_id xcb type method xfr_call_id cns_call_id"); - debugif_printf("\n--------------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - debugif_printf("%-2d %-6d 0x%8p %-4d %-6d %-11d %-11d\n", - i++, xcb->xfr_id, xcb, xcb->type, xcb->method, - xcb->xfr_call_id, xcb->cns_call_id); - } - - return (0); -} - - -void -fsmxfr_init (void) -{ - fsmxfr_xcb_t *xcb; - - - /* - * Initialize the xcbs. - */ - fsmxfr_xcbs = (fsmxfr_xcb_t *) - cpr_calloc(FSMXFR_MAX_XCBS, sizeof(fsmxfr_xcb_t)); - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - fsmxfr_init_xcb(xcb); - } - - /* - * Initialize the state/event table. - */ - fsmxfr_sm_table.min_state = FSMXFR_S_MIN; - fsmxfr_sm_table.max_state = FSMXFR_S_MAX; - fsmxfr_sm_table.min_event = CC_MSG_MIN; - fsmxfr_sm_table.max_event = CC_MSG_MAX; - fsmxfr_sm_table.table = (&(fsmxfr_function_table[0][0])); -} - -cc_transfer_mode_e -cc_is_xfr_call (callid_t call_id) -{ - static const char fname[] = "cc_is_xfr_call"; - int mode; - - if (call_id == CC_NO_CALL_ID) { - return CC_XFR_MODE_NONE; - } - mode = fsmutil_is_xfr_leg(call_id, fsmxfr_xcbs, FSMXFR_MAX_XCBS); - - switch (mode) { - case FSMXFR_MODE_TRANSFEROR: - FSM_DEBUG_SM(DEB_F_PREFIX"xfer mode is transferor for call id = %d", DEB_F_PREFIX_ARGS(FSM, fname), call_id); - return CC_XFR_MODE_TRANSFEROR; - case FSMXFR_MODE_TRANSFEREE: - FSM_DEBUG_SM(DEB_F_PREFIX"xfer mode is transferee for call id = %d", DEB_F_PREFIX_ARGS(FSM, fname), call_id); - return CC_XFR_MODE_TRANSFEREE; - case FSMXFR_MODE_TARGET: - FSM_DEBUG_SM(DEB_F_PREFIX"xfer mode is target for call id = %d", DEB_F_PREFIX_ARGS(FSM, fname), call_id); - return CC_XFR_MODE_TARGET; - default: - FSM_DEBUG_SM(DEB_F_PREFIX"invalid xfer mode %d for call id = %d", DEB_F_PREFIX_ARGS(FSM, fname), mode, call_id); - return CC_XFR_MODE_NONE; - } -} - -void -fsmxfr_shutdown (void) -{ - cpr_free(fsmxfr_xcbs); - fsmxfr_xcbs = NULL; -} - -int -fsmutil_is_xfr_consult_call (callid_t call_id) -{ - return fsmutil_is_xfr_consult_leg(call_id, fsmxfr_xcbs, FSMXFR_MAX_XCBS); -} - -callid_t -fsmxfr_get_consult_call_id (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - - if (xcb && call_id == xcb->xfr_call_id) { - return (fsmxfr_get_other_call_id(xcb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} - -callid_t -fsmxfr_get_primary_call_id (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - - if (xcb && (xcb->cns_call_id == call_id)) { - return (fsmxfr_get_other_call_id(xcb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/gsm.c b/media/webrtc/signaling/src/sipcc/core/gsm/gsm.c deleted file mode 100755 index 506a9164e34..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm.c +++ /dev/null @@ -1,552 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_time.h" -#include "cpr_rand.h" -#include "cpr_timers.h" -#include "cpr_threads.h" -#include "phone.h" -#include "phntask.h" -#include "gsm.h" -#include "lsm.h" -#include "vcm.h" -#include "fsm.h" -#include "phone_debug.h" -#include "debug.h" -#include "fim.h" -#include "gsm_sdp.h" -#include "ccsip_subsmanager.h" -#include "dialplanint.h" -#include "kpmlmap.h" -#include "subapi.h" -#include "platform_api.h" - -static void sub_process_feature_msg(uint32_t cmd, void *msg); -static void sub_process_feature_notify(ccsip_sub_not_data_t *msg, callid_t call_id, - callid_t other_call_id); -static void sub_process_b2bcnf_msg(uint32_t cmd, void *msg); -void fsmb2bcnf_get_sub_call_id_from_ccb(fsmcnf_ccb_t *ccb, callid_t *cnf_call_id, - callid_t *cns_call_id); -extern cprMsgQueue_t gsm_msgq; -void destroy_gsm_thread(void); -void dp_shutdown(); -extern void dcsm_process_jobs(void); -extern void dcsm_init(void); -extern void dcsm_shutdown(void); - -/* Flag to see whether we can start processing events */ - -static boolean gsm_initialized = FALSE; -static media_timer_callback_fp* media_timer_callback = NULL; - -/** - * Add media falsh one time timer call back. It's for ROUNDTABLE only. - */ -void -gsm_set_media_callback(media_timer_callback_fp* callback) { - media_timer_callback = callback; -} - -void -gsm_set_initialized (void) -{ - gsm_initialized = TRUE; -} - -boolean -gsm_get_initialize_state (void) -{ - return gsm_initialized; -} - -cprBuffer_t -gsm_get_buffer (uint16_t size) -{ - return cpr_malloc(size); -} - - -boolean -gsm_process_msg (uint32_t cmd, void *msg) -{ - static const char fname[] = "gsm_process_msg"; - boolean release_msg = TRUE; - cc_msgs_t msg_id = ((cc_setup_t *)msg)->msg_id; - int event_id = msg_id; - - GSM_DEBUG(DEB_F_PREFIX"cmd= 0x%x", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - - switch (cmd) { - case GSM_GSM: - case GSM_SIP: - if (gsm_initialized) { - - if (event_id == CC_MSG_FEATURE && - (((cc_feature_t *) msg)->feature_id == CC_FEATURE_CAC_RESP_PASS)) { - - fsm_cac_process_bw_avail_resp (); - - /* Release all memory for CC_FEATURE_CAC_..message */ - release_msg = TRUE; - - GSM_DEBUG(DEB_F_PREFIX"CAC Message Processed: 0x%x", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - } else if (event_id == CC_MSG_FEATURE && - (((cc_feature_t *) msg)->feature_id == CC_FEATURE_CAC_RESP_FAIL)) { - - fsm_cac_process_bw_failed_resp (); - - /* Release all memory for CC_FEATURE_CAC_..message */ - release_msg = TRUE; - - GSM_DEBUG(DEB_F_PREFIX"CAC Message Processed: 0x%x", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - } else { - - release_msg = fim_process_event(msg, FALSE); - GSM_DEBUG(DEB_F_PREFIX"Message Processed: 0x%x", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - } - } - if (release_msg == TRUE) { - fim_free_event(msg); - } - break; - - default: - GSM_DEBUG(DEB_F_PREFIX"Unknown Cmd received: 0x%x", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - break; - } - - return(release_msg); -} - - -void -gsm_process_timer_expiration (void *msg) -{ - static const char fname[] = "gsm_process_timer_expiration"; - cprCallBackTimerMsg_t *timerMsg; - void *timeout_msg = NULL; - - timerMsg = (cprCallBackTimerMsg_t *) msg; - TMR_DEBUG(DEB_F_PREFIX"Timer %s expired", DEB_F_PREFIX_ARGS(GSM, fname), timerMsg->expiredTimerName); - - switch (timerMsg->expiredTimerId) { - - case GSM_MULTIPART_TONES_TIMER: - case GSM_CONTINUOUS_TONES_TIMER: - lsm_tmr_tones_callback(timerMsg->usrData); - break; - - case GSM_ERROR_ONHOOK_TIMER: - fsmdef_error_onhook_timeout(timerMsg->usrData); - break; - - case GSM_AUTOANSWER_TIMER: - fsmdef_auto_answer_timeout(timerMsg->usrData); - break; - - case GSM_REVERSION_TIMER: - fsmdef_reversion_timeout((callid_t)(long)timerMsg->usrData); - break; - - case GSM_CAC_FAILURE_TIMER: - fsm_cac_process_bw_fail_timer(timerMsg->usrData); - break; - - case GSM_DIAL_TIMEOUT_TIMER: - dp_dial_timeout(timerMsg->usrData); - break; - - case GSM_KPML_INTER_DIGIT_TIMER: - kpml_inter_digit_timer_callback(timerMsg->usrData); - break; - case GSM_KPML_CRITICAL_DIGIT_TIMER: - case GSM_KPML_EXTRA_DIGIT_TIMER: - break; - - case GSM_KPML_SUBSCRIPTION_TIMER: - kpml_subscription_timer_callback(timerMsg->usrData); - break; - - case GSM_REQ_PENDING_TIMER: - timeout_msg = fsmdef_feature_timer_timeout( - CC_FEATURE_REQ_PEND_TIMER_EXP, - timerMsg->usrData); - break; - - case GSM_RINGBACK_DELAY_TIMER: - timeout_msg = fsmdef_feature_timer_timeout( - CC_FEATURE_RINGBACK_DELAY_TIMER_EXP, - timerMsg->usrData); - break; - case GSM_FLASH_ONCE_TIMER: - if (media_timer_callback != NULL) { - (* ((media_timer_callback_fp)(media_timer_callback)))(); - } - break; - case GSM_TONE_DURATION_TIMER: - lsm_tone_duration_tmr_callback(timerMsg->usrData); - break; - default: - GSM_ERR_MSG(GSM_F_PREFIX"unknown timer %s", fname, - timerMsg->expiredTimerName); - break; - } - - /* - * If there is a timer message to be processed by state machine, - * hands it to GSM state machine here. - */ - if (timeout_msg != NULL) { - /* Let state machine handle glare timer expiration */ - gsm_process_msg(GSM_GSM, timeout_msg); - cpr_free(timeout_msg); - } -} - -static void -gsm_init (void) -{ - /* Placeholder for any initialization tasks */ -} - -void -gsm_shutdown (void) -{ - gsm_initialized = FALSE; - - lsm_shutdown(); - fsm_shutdown(); - fim_shutdown(); - dcsm_shutdown(); -} - -void -gsm_reset (void) -{ - dp_reset(); - lsm_reset(); - fsmutil_free_all_shown_calls_ci_map(); -} - -void -GSM_prepare_task() -{ - /* - * Initialize all the GSM modules - */ - lsm_init(); - fsm_init(); - fim_init(); - gsm_init(); - dcsm_init(); - - cc_init(); - - fsmutil_init_shown_calls_ci_map(); - /* - * On Win32 platform, the random seed is stored per thread; therefore, - * each thread needs to seed the random number. It is recommended by - * MS to do the following to ensure randomness across application - * restarts. - */ - cpr_srand((unsigned int)time(NULL)); - - /* - * Cache random numbers for SRTP keys - */ - gsmsdp_cache_crypto_keys(); -} - -cpr_status_e -gsm_send_msg (uint32_t cmd, cprBuffer_t msg, uint16_t len) -{ - boolean release_msg = TRUE; - - switch (cmd) { - case TIMER_EXPIRATION: - gsm_process_timer_expiration(msg); - break; - - case GSM_SIP: - case GSM_GSM: - release_msg = gsm_process_msg(cmd, msg); - break; - - case DP_MSG_INIT_DIALING: - case DP_MSG_DIGIT_STR: - case DP_MSG_STORE_DIGIT: - case DP_MSG_DIGIT: - case DP_MSG_DIAL_IMMEDIATE: - case DP_MSG_REDIAL: - case DP_MSG_ONHOOK: - case DP_MSG_OFFHOOK: - case DP_MSG_UPDATE: - case DP_MSG_DIGIT_TIMER: - case DP_MSG_CANCEL_OFFHOOK_TIMER: - dp_process_msg(cmd, msg); - break; - - case SUB_MSG_B2BCNF_SUBSCRIBE_RESP: - case SUB_MSG_B2BCNF_NOTIFY: - case SUB_MSG_B2BCNF_TERMINATE: - sub_process_b2bcnf_msg(cmd, msg); - break; - - case SUB_MSG_FEATURE_SUBSCRIBE_RESP: - case SUB_MSG_FEATURE_NOTIFY: - case SUB_MSG_FEATURE_TERMINATE: - sub_process_feature_msg(cmd, msg); - break; - - case REG_MGR_STATE_CHANGE: - gsm_reset(); - break; - case THREAD_UNLOAD: - destroy_gsm_thread(); - break; - - default: - GSM_ERR_MSG(GSM_F_PREFIX"Unknown message", __FUNCTION__); - break; - } - - if (release_msg == TRUE) { - cpr_free(msg); - } - - /* Check if there are pending messages for dcsm - * if it in the right state perform its operation - */ - dcsm_process_jobs(); - return CPR_SUCCESS; -} - - -/** - * This function will process SUBSCRIBED feature NOTIFY messages. - * - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_b2bcnf_sub_resp (ccsip_sub_not_data_t *msg) -{ - static const char fname[] = "sub_process_b2bcnf_sub_resp"; - - callid_t call_id = CC_NO_CALL_ID; - callid_t other_call_id = CC_NO_CALL_ID; - cc_causes_t cause; - - fsmb2bcnf_get_sub_call_id_from_ccb ((fsmcnf_ccb_t *)(msg->request_id), - &call_id, &other_call_id); - - if (msg->u.subs_result_data.status_code == 200 || - msg->u.subs_result_data.status_code == 202 ) { - - cause = CC_CAUSE_OK; - - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs response = OK", - DEB_F_PREFIX_ARGS(GSM,fname)); - - } else { - - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs response = ERROR", - DEB_F_PREFIX_ARGS(GSM,fname)); - - cause = CC_CAUSE_ERROR; - } - - cc_feature_ack(CC_SRC_GSM, call_id, msg->line_id, CC_FEATURE_B2BCONF, NULL, cause); -} - -/** - * This function will process b2bcnf feature NOTIFY messages. - * - * @param[in] cmd - command - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_b2bcnf_msg (uint32_t cmd, void *msg) -{ - static const char fname[] = "sub_process_b2bcnf_msg"; - cc_feature_data_t data; - callid_t call_id, other_call_id = CC_NO_CALL_ID; - - fsmb2bcnf_get_sub_call_id_from_ccb((fsmcnf_ccb_t *)((ccsip_sub_not_data_t *)msg)->request_id, - &call_id, &other_call_id); - switch (cmd) { - case SUB_MSG_B2BCNF_SUBSCRIBE_RESP: - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs response", - DEB_F_PREFIX_ARGS(GSM,fname)); - sub_process_b2bcnf_sub_resp((ccsip_sub_not_data_t *)msg); - break; - - case SUB_MSG_B2BCNF_NOTIFY: - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs notify", - DEB_F_PREFIX_ARGS(GSM,fname)); - sub_process_feature_notify((ccsip_sub_not_data_t *)msg, call_id, other_call_id); - break; - case SUB_MSG_B2BCNF_TERMINATE: - /* - * This is posted by SIP stack if it is shutting down or rolling over. - * if so, notify b2bcnf to cleanup state machine. - */ - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs terminate", - DEB_F_PREFIX_ARGS(GSM,fname)); - - data.notify.subscription = CC_SUBSCRIPTIONS_REMOTECC; - data.notify.method = CC_RCC_METHOD_REFER; - data.notify.data.rcc.feature = CC_FEATURE_B2BCONF; - - data.notify.cause = CC_CAUSE_ERROR; - - cc_feature(CC_SRC_GSM, call_id, 0, CC_FEATURE_NOTIFY, &data); - - break; - default: - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs unknown event", - DEB_F_PREFIX_ARGS(GSM,fname)); - break; - } -} - -/** - * This function will process SUBSCRIBED feature NOTIFY messages. - * - * @param[in] cmd - command - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_feature_msg (uint32_t cmd, void *msg) -{ - callid_t call_id; - cc_feature_ack_t temp_msg; - - switch (cmd) { - case SUB_MSG_FEATURE_SUBSCRIBE_RESP: - /* - * if the response in non-2xx final, we should reset the active feature. - */ - call_id = (callid_t)(((ccsip_sub_not_data_t *)msg)->request_id); - if (((ccsip_sub_not_data_t *)msg)->u.subs_result_data.status_code > 299) { - memset(&temp_msg, 0, sizeof(temp_msg)); - temp_msg.msg_id = CC_MSG_FEATURE_ACK; - temp_msg.src_id = CC_SRC_GSM; - temp_msg.call_id = call_id; - fim_process_event((void *)&temp_msg, FALSE); - } - break; - case SUB_MSG_FEATURE_NOTIFY: - call_id = (callid_t)(((ccsip_sub_not_data_t *)msg)->request_id); - sub_process_feature_notify((ccsip_sub_not_data_t *)msg, call_id, - CC_NO_CALL_ID); - break; - case SUB_MSG_FEATURE_TERMINATE: - /* - * This is posted by SIP stack if it is shutting down or rolling over. - * if so, sip stack already cleaned up the subscription. so do nothing. - */ - break; - } -} - -/** - * This function will process SUBSCRIBED feature NOTIFY messages. - * - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_feature_notify (ccsip_sub_not_data_t *msg, callid_t call_id, - callid_t other_call_id) -{ - static const char fname[] = "sub_process_feature_notify"; - ccsip_event_data_t *ev_data; - cc_feature_ack_t temp_msg; - - - /* - * send response to NOTIFY. - */ - (void)sub_int_notify_ack(msg->sub_id, SIP_STATUS_SUCCESS, msg->u.notify_ind_data.cseq); - - /* - * if the subscription state is terminated, clean up the subscription. - */ - if (msg->u.notify_ind_data.subscription_state == SUBSCRIPTION_STATE_TERMINATED) { - /* - * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED. - * do not force SUB/NOT mgr to cleanup SCB immediately, because we may have to handle digest - * challenges to terminating SUBSCRIBE sent. - */ - (void)sub_int_subscribe_term(msg->sub_id, FALSE, msg->request_id, CC_SUBSCRIPTIONS_REMOTECC); - - } - ev_data = msg->u.notify_ind_data.eventData; - msg->u.notify_ind_data.eventData = NULL; - if (ev_data == NULL) { - GSM_ERR_MSG(DEB_F_PREFIX"No body in the NOTIFY message", - DEB_F_PREFIX_ARGS(GSM, fname)); - /* - * if (no content & subscription state is TERMINATED - * then reset active_feature to NONE. - */ - if (msg->u.notify_ind_data.subscription_state == SUBSCRIPTION_STATE_TERMINATED) { - memset(&temp_msg, 0, sizeof(temp_msg)); - temp_msg.msg_id = CC_MSG_FEATURE_ACK; - temp_msg.src_id = CC_SRC_GSM; - temp_msg.call_id = call_id; - fim_process_event((void *)&temp_msg, FALSE); - } - return; - } - - // other types of event data is not supported as of now. - free_event_data(ev_data); -} - -/* - * return TRUE if GSM is considered idle, - * currently this means lsm is idle - * FALSE otherwise. - */ -boolean -gsm_is_idle (void) -{ - if (lsm_is_phone_idle()) { - return (TRUE); - } - return (FALSE); -} - -/* - * Function: destroy_gsm_thread - * Description: shutdown gsm and kill gsm thread - * Parameters: none - * Returns: none - */ -void destroy_gsm_thread() -{ - static const char fname[] = "destroy_gsm_thread"; - DEF_DEBUG(DEB_F_PREFIX"Unloading GSM and destroying GSM thread", - DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - gsm_shutdown(); - dp_shutdown(); -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c deleted file mode 100644 index 38533b21065..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c +++ /dev/null @@ -1,7609 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_stdlib.h" -#include "lsm.h" -#include "fsm.h" -#include "ccapi.h" -#include "ccsip_sdp.h" -#include "sdp.h" -#include "gsm.h" -#include "gsm_sdp.h" -#include "util_string.h" -#include "rtp_defs.h" -#include "debug.h" -#include "dtmf.h" -#include "prot_configmgr.h" -#include "dns_utils.h" -#include "sip_interface_regmgr.h" -#include "platform_api.h" -#include "vcm.h" -#include "prlog.h" -#include "plstr.h" -#include "sdp_private.h" - -static const char* logTag = "gsm_sdp"; - -//TODO Need to place this in a portable location -#define MULTICAST_START_ADDRESS 0xe1000000 -#define MULTICAST_END_ADDRESS 0xefffffff - -/* Only first octet contains codec type */ -#define GET_CODEC_TYPE(a) ((uint8_t)((a) & 0XFF)) - -#define GSMSDP_SET_MEDIA_DIABLE(media) \ - (media->src_port = 0) - -#define CAST_DEFAULT_BITRATE 320000 -/* - * The maximum number of media lines per call. This puts the upper limit - * on * the maximum number of media lines per call to resource hogging. - * The value of 8 is intended up to 2 audio and 2 video streams with - * each stream can offer IPV4 and IPV6 alternate network address type - * in ANAT group (RFC-4091). - */ -#define GSMSDP_MAX_MLINES_PER_CALL (8) - -/* - * Permanent number of free media structure elements for media structure - * that represents media line in the SDP. The maximum number of elements - * is set to equal number of call or LSM_MAX_CALLS. This should be enough - * to minimumly allow typical a single audio media stream per call scenario - * without using dynamic memory. - * - * If more media structures are needed than this number, the addition - * media structures are allocated from heap and they will be freed back - * from heap after thehy are not used. The only time where the heap - * is used when phone reaches the maximum call capacity and each one - * of the call is using more than one media lines. - */ -#define GSMSDP_PERM_MEDIA_ELEMS (LSM_MAX_CALLS) - -/* - * The permanent free media structure elements use static array. - * It is to ensure a low overhead for this a typical single audio call. - */ -static fsmdef_media_t gsmsdp_free_media_chunk[GSMSDP_PERM_MEDIA_ELEMS]; -static sll_lite_list_t gsmsdp_free_media_list; - -typedef enum { - MEDIA_TABLE_GLOBAL, - MEDIA_TABLE_SESSION -} media_table_e; - -/* Forward references */ -static cc_causes_t -gsmsdp_init_local_sdp (const char *peerconnection, cc_sdp_t **sdp_pp); - -static void -gsmsdp_set_media_capability(fsmdef_media_t *media, - const cc_media_cap_t *media_cap); -static fsmdef_media_t * -gsmsdp_add_media_line(fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap, - uint8_t cap_index, uint16_t level, - cpr_ip_type addr_type, boolean offer); -static boolean -gsmsdp_add_remote_stream(uint16_t idx, int pc_stream_id, - fsmdef_dcb_t *dcb_p); - -static boolean -gsmsdp_add_remote_track(uint16_t idx, uint16_t track, - fsmdef_dcb_t *dcb_p, fsmdef_media_t *media); - - - -extern cc_media_cap_table_t g_media_table; - -extern boolean g_disable_mass_reg_debug_print; - -/** - * A wraper function to return the media capability supported by - * the platform and session. This is a convient place if policy - * to get the capability table as it applies to the session - * updates the media_cap_tbl ptr in dcb - * - * @param[in]dcb - pointer to the fsmdef_dcb_t - - * - * @return - pointer to the the media capability table for session - */ -static const cc_media_cap_table_t *gsmsdp_get_media_capability (fsmdef_dcb_t *dcb_p) -{ - static const char *fname = "gsmsdp_get_media_capability"; - int sdpmode = 0; - - if (g_disable_mass_reg_debug_print == FALSE) { - GSM_DEBUG(DEB_F_PREFIX"dcb video pref %x", - DEB_F_PREFIX_ARGS(GSM, fname), dcb_p->video_pref); - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if ( dcb_p->media_cap_tbl == NULL ) { - dcb_p->media_cap_tbl = (cc_media_cap_table_t*) cpr_calloc(1, sizeof(cc_media_cap_table_t)); - if ( dcb_p->media_cap_tbl == NULL ) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"media table malloc failed.", - dcb_p->line, dcb_p->call_id, fname); - return NULL; - } - } - - if (sdpmode) { - /* Here we are copying only what we need from the g_media_table - in order to avoid a data race with its values being set in - media_cap_tbl.c */ - dcb_p->media_cap_tbl->id = g_media_table.id; - - /* This needs to change when we handle more than one stream - of each media type at a time. */ - - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].name = CC_AUDIO_1; - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].name = CC_VIDEO_1; - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].name = CC_DATACHANNEL_1; - - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].type = SDP_MEDIA_AUDIO; - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].type = SDP_MEDIA_VIDEO; - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].type = SDP_MEDIA_APPLICATION; - - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = FALSE; - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE; - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE; - - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].support_security = TRUE; - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_security = TRUE; - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].support_security = TRUE; - - /* By default, all channels are "bundle only" */ - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].bundle_only = TRUE; - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].bundle_only = TRUE; - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].bundle_only = TRUE; - - /* We initialize as RECVONLY to allow the application to - display incoming media streams, even if it doesn't - plan to send media for those streams. This will be - upgraded to SENDRECV when and if a stream is added. */ - - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].support_direction = - SDP_DIRECTION_RECVONLY; - - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = - SDP_DIRECTION_RECVONLY; - - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].support_direction = - SDP_DIRECTION_SENDRECV; - } else { - *(dcb_p->media_cap_tbl) = g_media_table; - - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE; - - if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) { - // do not enable video - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE; - } - - if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) { - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; - } - - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; - DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly", - dcb_p->line, dcb_p->call_id, fname); - } - } else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) { - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; - } - - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; - DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly", - dcb_p->line, dcb_p->call_id, fname); - } - } // else if requested is SENDRECV just go by capability - } - - return (dcb_p->media_cap_tbl); -} - -/* - * Process a single constraint for one media capablity - */ -void gsmsdp_process_cap_constraint(cc_media_cap_t *cap, - cc_boolean constraint) { - if (!constraint) { - cap->support_direction &= ~SDP_DIRECTION_FLAG_RECV; - } else { - cap->support_direction |= SDP_DIRECTION_FLAG_RECV; - cap->enabled = TRUE; - } -} - -/* - * Process options only related to media capabilities., i.e - * OfferToReceiveAudio, OfferToReceiveVideo - */ -void gsmsdp_process_cap_options(fsmdef_dcb_t *dcb, - cc_media_options_t* options) { - if (options->offer_to_receive_audio.was_passed) { - gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_AUDIO_1], - options->offer_to_receive_audio.value); - } - if (options->offer_to_receive_video.was_passed) { - gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_VIDEO_1], - options->offer_to_receive_video.value); - } - if (options->moz_dont_offer_datachannel.was_passed) { - /* Hack to suppress data channel */ - if (options->moz_dont_offer_datachannel.value) { - dcb->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE; - } - } -} - -/** - * Copy an fsmdef_media_t's payload list to its previous_sdp's payload list - * - * @param[in]media - pointer to the fsmdef_media_t to update - */ -void gsmsdp_copy_payloads_to_previous_sdp (fsmdef_media_t *media) -{ - static const char *fname = "gsmsdp_copy_payloads_to_previous_sdp"; - - if ((!media->payloads) && (NULL != media->previous_sdp.payloads)) - { - cpr_free(media->previous_sdp.payloads); - media->previous_sdp.payloads = NULL; - media->previous_sdp.num_payloads = 0; - } - - /* Ensure that there is enough space to hold all the payloads */ - if (media->num_payloads > media->previous_sdp.num_payloads) - { - media->previous_sdp.payloads = - cpr_realloc(media->previous_sdp.payloads, - media->num_payloads * sizeof(vcm_payload_info_t)); - } - - /* Copy the payloads over */ - media->previous_sdp.num_payloads = media->num_payloads; - memcpy(media->previous_sdp.payloads, media->payloads, - media->num_payloads * sizeof(vcm_payload_info_t)); - media->previous_sdp.num_payloads = media->num_payloads; -} - -/** - * Find an entry for the specified codec type in the vcm_payload_info_t - * list array. - * - * @param[in]codec - Codec type to find - * @param[in]payload_info - Array of payload info entries - * @param[in]num_payload_info - Total number of elements in payload_info - * @param[in]instance - Which instance of the codec to find - * (e.g., if more than one entry for a codec type) - * - * @return Pointer to the payload info if found; - * NULL when no match is found. - */ -vcm_payload_info_t *gsmsdp_find_info_for_codec(rtp_ptype codec, - vcm_payload_info_t *payload_info, - int num_payload_info, - int instance) { - int i; - for (i = 0; i < num_payload_info; i++) { - if (payload_info[i].codec_type == codec) - { - instance--; - if (instance == 0) { - return &(payload_info[i]); - } - } - } - return NULL; -} - - -/** - * Sets up the media track table - * - * @param[in]dcb - pointer to the fsmdef_dcb_t - * - * @return - pointer to the the media track table for session - */ -static const cc_media_remote_stream_table_t *gsmsdp_get_media_stream_table (fsmdef_dcb_t *dcb_p) -{ - static const char *fname = "gsmsdp_get_media_stream_table"; - if ( dcb_p->remote_media_stream_tbl == NULL ) { - dcb_p->remote_media_stream_tbl = (cc_media_remote_stream_table_t*) cpr_malloc(sizeof(cc_media_remote_stream_table_t)); - if ( dcb_p->remote_media_stream_tbl == NULL ) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"media track table malloc failed.", - dcb_p->line, dcb_p->call_id, fname); - return NULL; - } - } - - memset(dcb_p->remote_media_stream_tbl, 0, sizeof(cc_media_remote_stream_table_t)); - - return (dcb_p->remote_media_stream_tbl); -} - -/** - * The function creates a free media structure elements list. The - * free list is global for all calls. The function must be called once - * during GSM initializtion. - * - * @param None. - * - * @return TRUE - free media structure list is created - * successfully. - * FALSE - failed to create free media structure - * list. - */ -boolean -gsmsdp_create_free_media_list (void) -{ - uint32_t i; - fsmdef_media_t *media; - - /* initialize free media_list structure */ - (void)sll_lite_init(&gsmsdp_free_media_list); - - /* - * Populate the free list: - * Break the entire chunk into multiple free elements and link them - * onto to the free media list. - */ - media = &gsmsdp_free_media_chunk[0]; /* first element */ - for (i = 0; i < GSMSDP_PERM_MEDIA_ELEMS; i++) { - (void)sll_lite_link_head(&gsmsdp_free_media_list, - (sll_lite_node_t *)media); - media = media + 1; /* next element */ - } - - /* Successful create media free list */ - return (TRUE); -} - -/** - * The function destroys the free media structure list. It should be - * call during GSM shutdown. - * - * @param None. - * - * @return None. - */ -void -gsmsdp_destroy_free_media_list (void) -{ - /* - * Although the free chunk is not allocated but, - * NULL out the free list header to indicate that the - * there is not thing from the free chunk. - */ - (void)sll_lite_init(&gsmsdp_free_media_list); -} - -/** - * The function allocates a media structure. The function - * attempts to obtain a free media structure from the free media - * structure list first. If free list is empty then the media structure - * is allocated from a memory pool. - * - * @param None. - * - * @return pointer to the fsmdef_media_t if successful or - * NULL when there is no free media structure - * is available. - */ -static fsmdef_media_t * -gsmsdp_alloc_media (void) -{ - static const char fname[] = "gsmsdp_alloc_media"; - fsmdef_media_t *media = NULL; - - /* Get a media element from the free list */ - media = (fsmdef_media_t *)sll_lite_unlink_head(&gsmsdp_free_media_list); - if (media == NULL) { - /* no free element from cache, allocate it from the pool */ - media = cpr_malloc(sizeof(fsmdef_media_t)); - GSM_DEBUG(DEB_F_PREFIX"get from dynamic pool, media %p", - DEB_F_PREFIX_ARGS(GSM, fname), media); - } - return (media); -} - -/** - * The function frees a media structure back to the free list or - * heap. If the media structure is from the free list then it - * is put back to the free list otherwise it will be freed - * back to the dynamic pool. - * - * @param[in]media - pointer to fsmdef_media_t to free back to - * free list. - * - * @return pointer to the fsmdef_media_t if successful - * NULL when there is no free media structure - * is available. - */ -static void -gsmsdp_free_media (fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_free_media"; - - if (media == NULL) { - return; - } - - if (media-> video != NULL ) { - vcmFreeMediaPtr(media->video); - } - - if(media->payloads != NULL) { - cpr_free(media->payloads); - media->payloads = NULL; - media->num_payloads = 0; - } - - if (media->previous_sdp.payloads != NULL) { - cpr_free(media->previous_sdp.payloads); - media->previous_sdp.payloads = NULL; - media->previous_sdp.num_payloads = 0; - } - - /* - * Check to see if the element is part of the - * free chunk space. - */ - if ((media >= &gsmsdp_free_media_chunk[0]) && - (media <= &gsmsdp_free_media_chunk[GSMSDP_PERM_MEDIA_ELEMS-1])) { - /* the element is part of free chunk, put it back to the list */ - (void)sll_lite_link_head(&gsmsdp_free_media_list, - (sll_lite_node_t *)media); - } else { - /* this element is from the dynamic pool, free it back */ - cpr_free(media); - GSM_DEBUG(DEB_F_PREFIX"free media %p to dynamic pool", - DEB_F_PREFIX_ARGS(GSM, fname), media); - } -} - -/** - * Initialize the media entry. The function initializes media - * entry. - * - * @param[in]media - pointer to fsmdef_media_t of the media entry to be - * initialized. - * - * @return none - * - * @pre (media not_eq NULL) - */ -static void -gsmsdp_init_media (fsmdef_media_t *media) -{ - media->refid = CC_NO_MEDIA_REF_ID; - media->type = SDP_MEDIA_INVALID; /* invalid (free entry) */ - media->packetization_period = ATTR_PTIME; - media->max_packetization_period = ATTR_MAXPTIME; - media->mode = (uint16_t)vcmGetILBCMode(); - media->vad = VCM_VAD_OFF; - /* Default to audio codec */ - media->level = 0; - media->dest_port = 0; - media->dest_addr = ip_addr_invalid; - media->is_multicast = FALSE; - media->multicast_port = 0; - media->avt_payload_type = RTP_NONE; - media->src_port = 0; - media->src_addr = ip_addr_invalid; - media->rcv_chan = FALSE; - media->xmit_chan = FALSE; - - media->direction = SDP_DIRECTION_INACTIVE; - media->direction_set = FALSE; - media->transport = SDP_TRANSPORT_INVALID; - media->tias_bw = SDP_INVALID_VALUE; - media->profile_level = 0; - - media->previous_sdp.avt_payload_type = RTP_NONE; - media->previous_sdp.dest_addr = ip_addr_invalid; - media->previous_sdp.dest_port = 0; - media->previous_sdp.direction = SDP_DIRECTION_INACTIVE; - media->previous_sdp.packetization_period = media->packetization_period; - media->previous_sdp.max_packetization_period = media->max_packetization_period; - media->previous_sdp.payloads = NULL; - media->previous_sdp.num_payloads = 0; - media->previous_sdp.tias_bw = SDP_INVALID_VALUE; - media->previous_sdp.profile_level = 0; - media->hold = FSM_HOLD_NONE; - media->flags = 0; /* clear all flags */ - media->cap_index = CC_MAX_MEDIA_CAP; /* max is invalid value */ - media->video = NULL; - media->candidate_ct = 0; - media->rtcp_mux = FALSE; - media->audio_level = TRUE; - media->audio_level_id = 1; - /* ACTPASS is the value we put in every offer */ - media->setup = SDP_SETUP_ACTPASS; - media->local_datachannel_port = 0; - media->remote_datachannel_port = 0; - media->datachannel_streams = WEBRTC_DATACHANNEL_STREAMS_DEFAULT; - sstrncpy(media->datachannel_protocol, WEBRTC_DATA_CHANNEL_PROT, SDP_MAX_STRING_LEN); - - media->payloads = NULL; - media->num_payloads = 0; -} - -/** - * - * Returns a pointer to a new the fsmdef_media_t for a given dcb. - * The default media parameters will be intialized for the known or - * supported media types. The new media is also added to the media list - * in the dcb. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media_type - sdp_media_e. - * @param[in]level - uint16_t for media line level. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_get_new_media (fsmdef_dcb_t *dcb_p, sdp_media_e media_type, - uint16_t level) -{ - static const char fname[] = "gsmsdp_get_new_media"; - fsmdef_media_t *media; - static media_refid_t media_refid = CC_NO_MEDIA_REF_ID; - sll_lite_return_e sll_lite_ret; - - /* check to ensue we do not handle too many media lines */ - if (GSMSDP_MEDIA_COUNT(dcb_p) >= GSMSDP_MAX_MLINES_PER_CALL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"exceeding media lines per call", - dcb_p->line, dcb_p->call_id, fname); - return (NULL); - } - - /* allocate new media entry */ - media = gsmsdp_alloc_media(); - if (media != NULL) { - /* initialize the media entry */ - gsmsdp_init_media(media); - - /* assigned media reference id */ - if (++media_refid == CC_NO_MEDIA_REF_ID) { - media_refid = 1; - } - media->refid = media_refid; - media->type = media_type; - media->level = level; - - /* append the media to the active list */ - sll_lite_ret = sll_lite_link_tail(&dcb_p->media_list, - (sll_lite_node_t *)media); - if (sll_lite_ret != SLL_LITE_RET_SUCCESS) { - /* fails to put the new media entry on to the list */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"error %d when add media to list", - dcb_p->line, dcb_p->call_id, fname, sll_lite_ret); - gsmsdp_free_media(media); - media = NULL; - } - } - return (media); -} - -/** - * The function removes the media entry from the list of a given call and - * then deallocates the media entry. - * - * @param[in]dcb - pointer to fsmdef_def_t for the dcb whose - * media to be removed from. - * @param[in]media - pointer to fsmdef_media_t for the media - * entry to be removed. - * - * @return none - * - * @pre (dcb not_eq NULL) - */ -static void gsmsdp_remove_media (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_remove_media"; - cc_action_data_t data; - - if (media == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"removing NULL media", - dcb_p->line, dcb_p->call_id, fname); - return; - } - - if (media->rcv_chan || media->xmit_chan) { - /* stop media, if it is opened */ - data.stop_media.media_refid = media->refid; - (void)cc_call_action(dcb_p->call_id, dcb_p->line, CC_ACTION_STOP_MEDIA, - &data); - } - /* remove this media off the list */ - (void)sll_lite_remove(&dcb_p->media_list, (sll_lite_node_t *)media); - - /* Release the port */ - vcmRxReleasePort(media->cap_index, dcb_p->group_id, media->refid, - lsm_get_ms_ui_call_handle(dcb_p->line, dcb_p->call_id, CC_NO_CALL_ID), media->src_port); - - /* free media structure */ - gsmsdp_free_media(media); -} - -/** - * The function performs cleaning media list of a given call. It walks - * through the list and deallocates each media entries. - * - * @param[in]dcb - pointer to fsmdef_def_t for the dcb whose - * media list to be cleaned. - * - * @return none - * - * @pre (dcb not_eq NULL) - */ -void gsmsdp_clean_media_list (fsmdef_dcb_t *dcb_p) -{ - fsmdef_media_t *media = NULL; - - while (TRUE) { - /* unlink head and free the media */ - media = (fsmdef_media_t *)sll_lite_unlink_head(&dcb_p->media_list); - if (media != NULL) { - gsmsdp_free_media(media); - } else { - break; - } - } -} - -/** - * - * The function is used for per call media list initialization. It is - * an interface function to other module for initializing the media list - * used during a call. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t where the media list - * will be attached to. - * - * @return None. - * @pre (dcb not_eq NULL) - */ -void gsmsdp_init_media_list (fsmdef_dcb_t *dcb_p) -{ - const cc_media_cap_table_t *media_cap_tbl; - const cc_media_remote_stream_table_t *media_track_tbl; - const char fname[] = "gsmsdp_init_media_list"; - - /* do the actual media element list initialization */ - (void)sll_lite_init(&dcb_p->media_list); - - media_cap_tbl = gsmsdp_get_media_capability(dcb_p); - - if (media_cap_tbl == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available", - dcb_p->line, dcb_p->call_id, fname); - } - - media_track_tbl = gsmsdp_get_media_stream_table(dcb_p); - - if (media_track_tbl == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media tracks available", - dcb_p->line, dcb_p->call_id, fname); - } -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * correspoinding media level in the SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]level - uint16_t for media line level. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_find_media_by_level (fsmdef_dcb_t *dcb_p, uint16_t level) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * the level. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->level == level) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * correspoinding reference ID. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]refid - media reference ID to look for. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -fsmdef_media_t * -gsmsdp_find_media_by_refid (fsmdef_dcb_t *dcb_p, media_refid_t refid) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * the reference ID. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->refid == refid) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * correspoinding capability index. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]cap_index - capability table index. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_find_media_by_cap_index (fsmdef_dcb_t *dcb_p, uint8_t cap_index) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * the reference ID. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->cap_index == cap_index) { - /* found a match */ - return (media); - } - } - return (NULL); - -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * first audio type in the SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -fsmdef_media_t *gsmsdp_find_audio_media (fsmdef_dcb_t *dcb_p) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * SDP_MEDIA_AUDIO type. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == SDP_MEDIA_AUDIO) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/** - * - * The function finds an unused media line given type. - * - * @param[in]sdp - void pointer of thd SDP libray handle. - * @param[in]media_type - media type of the unused line. - * - * @return level (line) of the unused one if found or - * 0 if there is no unused one found. - */ -static uint16_t -gsmsdp_find_unused_media_line_with_type (void *sdp, sdp_media_e media_type) -{ - uint16_t num_m_lines, level; - int32_t port; - - num_m_lines = sdp_get_num_media_lines(sdp); - for (level = 1; level <= num_m_lines; level++) { - port = sdp_get_media_portnum(sdp, level); - if (port == 0) { - /* This slot is not used, check the type */ - if (sdp_get_media_type(sdp, level) == media_type) { - /* Found an empty slot that has the same media type */ - return (level); - } - } - } - /* no unused media line of the given type found */ - return (0); -} - -/** - * - * The function returns the media cap entry pointer to the caller based - * on the index. - * - * @param[in]cap_index - uint8_t for index of the media cap table. - * - * @return pointer to the media cap entry if one is available. - * NULL if none is available. - * - */ -static const cc_media_cap_t * -gsmsdp_get_media_cap_entry_by_index (uint8_t cap_index, fsmdef_dcb_t *dcb_p) -{ - const cc_media_cap_table_t *media_cap_tbl; - - media_cap_tbl = dcb_p->media_cap_tbl; - - if (media_cap_tbl == NULL) { - return (NULL); - } - - if (cap_index >= CC_MAX_MEDIA_CAP) { - return (NULL); - } - return (&media_cap_tbl->cap[cap_index]); -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * corresponding media line. It looks for another media line - * with the same type and cap_index but different level - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - current media level. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -fsmdef_media_t * -gsmsdp_find_anat_pair (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - fsmdef_media_t *searched_media = NULL; - - /* - * search the all entries that has a the same capability index - * but at a different level. The only time that this is true is - * both media are in the same ANAT group. - */ - GSMSDP_FOR_ALL_MEDIA(searched_media, dcb_p) { - if ((searched_media->cap_index == media->cap_index) && - (searched_media->level != media->level)) { - /* found a match */ - return (searched_media); - } - } - return (NULL); -} - -/** - * - * The function queries platform to see if the platform is capable - * of handle mixing additional media or not. - * - * P2: This may go away when integrate with the platform. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t structure. - * @param[in]media_type - media type to be mixed. - * - * @return TRUE the media can be mixed. - * FALSE the media can not be mixed - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_platform_addition_mix (fsmdef_dcb_t *dcb_p, sdp_media_e media_type) -{ - return (FALSE); -} - - -/** - * - * The function updates the local time stamp during SDP offer/answer - * processing. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]offer - boolean indicates this is procssing an offered - * SDP - * @param[in]initial_offer - boolean indicates this is processin an - * initial offered SDP. - * - * @return none. - * @pre (dcb not_eq NULL) - */ -static void -gsmsdp_update_local_time_stamp (fsmdef_dcb_t *dcb_p, boolean offer, - boolean initial_offer) -{ - const char fname[] = "gsmsdp_update_local_time_stamp"; - void *local_sdp_p; - void *remote_sdp_p; - - local_sdp_p = dcb_p->sdp->src_sdp; - remote_sdp_p = dcb_p->sdp->dest_sdp; - - /* - * If we are processing an offer sdp, need to set the - * start time and stop time based on the remote SDP - */ - if (initial_offer) { - /* - * Per RFC3264, time description of answer must equal that - * of the offer. - */ - (void) sdp_set_time_start(local_sdp_p, - sdp_get_time_start(remote_sdp_p)); - (void) sdp_set_time_stop(local_sdp_p, sdp_get_time_stop(remote_sdp_p)); - } else if (offer) { - /* - * Set t= line based on remote SDP - */ - if (sdp_timespec_valid(remote_sdp_p) != TRUE) { - GSM_DEBUG(DEB_L_C_F_PREFIX"\nTimespec is invalid.", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - (void) sdp_set_time_start(local_sdp_p, "0"); - (void) sdp_set_time_stop(local_sdp_p, "0"); - } else { - if (sdp_get_time_start(local_sdp_p) != - sdp_get_time_start(remote_sdp_p)) { - (void) sdp_set_time_start(local_sdp_p, - sdp_get_time_start(remote_sdp_p)); - } - if (sdp_get_time_stop(local_sdp_p) != - sdp_get_time_stop(remote_sdp_p)) { - (void) sdp_set_time_stop(local_sdp_p, - sdp_get_time_stop(remote_sdp_p)); - } - } - } -} - -/** - * - * The function gets the local source address address and puts it into - * the media entry. - * - * @param[in]media - pointer to fsmdef_media_t structure to - * get the local address into. - * - * @return none. - * @pre (media not_eq NULL) - */ -static void -gsmsdp_get_local_source_v4_address (fsmdef_media_t *media) -{ - int nat_enable = 0; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t addr; - const char fname[] = "gsmsdp_get_local_source_v4_address"; - - /* - * Get device address. - */; - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - init_empty_str(curr_media_ip); - config_get_value(CFGID_MEDIA_IP_ADDR, curr_media_ip, - MAX_IPADDR_STR_LEN); - if (is_empty_str(curr_media_ip) == FALSE) { - - str2ip(curr_media_ip, &addr); - util_ntohl(&addr, &addr); - if (util_check_if_ip_valid(&media->src_addr) == FALSE) { - // Update the media Src address only if it is invalid - media->src_addr = addr; - GSM_ERR_MSG("%s: Update IP %s", fname, curr_media_ip); - } - } else { - sip_config_get_net_device_ipaddr(&media->src_addr); - } - } else { - sip_config_get_nat_ipaddr(&media->src_addr); - } -} - -/* - * - * The function gets the local source address address and puts it into - * the media entry. - * - * @param[in]media - pointer to fsmdef_media_t structure to - * get the local address into. - * - * @return none. - * @pre (media not_eq NULL) - */ -static void -gsmsdp_get_local_source_v6_address (fsmdef_media_t *media) -{ - int nat_enable = 0; - - /* - * Get device address. - */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_ipv6_device_ipaddr(&media->src_addr); - } else { - sip_config_get_nat_ipaddr(&media->src_addr); - } -} - -/** - * Set the connection address into the SDP. - * - * @param[in]sdp_p - pointer to SDP (type void) - * @param[in]level - media level or line. - * @param[in]addr - string representation of IP address. - * Assumed to be IPV6 if larger than 15. - * - * @return none. - * @pre (sdp_p not_eq NULL) and (addr not_eq NULL) - * - */ -static void -gsmsdp_set_connection_address (void *sdp_p, uint16_t level, char *addr) -{ - /* - * c= line
- */ - - (void) sdp_set_conn_nettype(sdp_p, level, SDP_NT_INTERNET); - - if (addr && (strlen(addr) > strlen("123.123.123.123"))) - { - // Long IP address, must be IPV6 - (void) sdp_set_conn_addrtype(sdp_p, level, SDP_AT_IP6); - } - else - { - (void) sdp_set_conn_addrtype(sdp_p, level, SDP_AT_IP4); - } - - (void) sdp_set_conn_address(sdp_p, level, addr); -} - -/* - * gsmsdp_set_2543_hold_sdp - * - * Description: - * - * Manipulates the local SDP of the specified DCB to indicate hold - * to the far end using 2543 style signaling. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * - */ -static void -gsmsdp_set_2543_hold_sdp (fsmdef_dcb_t *dcb_p, uint16 level) -{ - (void) sdp_set_conn_nettype(dcb_p->sdp->src_sdp, level, SDP_NT_INTERNET); - (void) sdp_set_conn_addrtype(dcb_p->sdp->src_sdp, level, SDP_AT_IP4); - (void) sdp_set_conn_address(dcb_p->sdp->src_sdp, level, "0.0.0.0"); -} - - -/* - * gsmsdp_set_video_media_attributes - * - * Description: - * - * Add the specified video media format to the SDP. - * - * Parameters: - * - * media_type - The media type (format) to add to the specified SDP. - * sdp_p - Pointer to the SDP the media attribute is to be added to. - * level - The media level of the SDP where the media attribute is to be added. - * payload_number - AVT payload type if the media attribute being added is - * RTP_AVT. - * - */ -static void -gsmsdp_set_video_media_attributes (uint32_t media_type, void *cc_sdp_p, uint16_t level, - uint16_t payload_number) -{ - uint16_t a_inst; - int added_fmtp = 0; - void *sdp_p = ((cc_sdp_t*)cc_sdp_p)->src_sdp; - int max_fs = 0; - int max_fr = 0; - int max_br = 0; - int max_mbps = 0; - - switch (media_type) { - case RTP_H263: - case RTP_H264_P0: - case RTP_H264_P1: - case RTP_VP8: - /* - * add a=rtpmap line - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, &a_inst) - != SDP_SUCCESS) { - return; - } - - (void) sdp_attr_set_rtpmap_payload_type(sdp_p, level, 0, a_inst, - payload_number); - - switch (media_type) { - case RTP_H263: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_H263v2); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_VIDEO_CLOCKRATE); - break; - case RTP_H264_P0: - case RTP_H264_P1: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_H264); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_VIDEO_CLOCKRATE); - // we know we haven't added it yet - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst) - != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - added_fmtp = 1; - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst, - payload_number); - { - char buffer[32]; - uint32_t profile_level_id = vcmGetVideoH264ProfileLevelID(); - snprintf(buffer, sizeof(buffer), "%06x", profile_level_id); - (void) sdp_attr_set_fmtp_profile_level_id(sdp_p, level, 0, a_inst, - buffer); - } - if (media_type == RTP_H264_P1) { - (void) sdp_attr_set_fmtp_pack_mode(sdp_p, level, 0, a_inst, - 1); - } - // TODO: other parameters we may want/need to set for H.264 - //(void) sdp_attr_set_fmtp_max_mbps(sdp_p, level, 0, a_inst, max_mbps); - //(void) sdp_attr_set_fmtp_max_fs(sdp_p, level, 0, a_inst, max_fs); - //(void) sdp_attr_set_fmtp_max_cpb(sdp_p, level, 0, a_inst, max_cpb); - //(void) sdp_attr_set_fmtp_max_dpb(sdp_p, level, 0, a_inst, max_dpb); - //(void) sdp_attr_set_fmtp_max_br(sdp_p, level, 0, a_inst, max_br); - //(void) sdp_add_new_bw_line(sdp_p, level, &a_inst); - //(void) sdp_set_bw(sdp_p, level, a_inst, SDP_BW_MODIFIER_TIAS, tias_bw); - break; - case RTP_VP8: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_VP8); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_VIDEO_CLOCKRATE); - break; - } - - switch (media_type) { - case RTP_H264_P0: - case RTP_H264_P1: - max_br = config_get_video_max_br((rtp_ptype) media_type); // H264 only - max_mbps = config_get_video_max_mbps((rtp_ptype) media_type); // H264 only - // fall through - case RTP_VP8: - max_fs = config_get_video_max_fs((rtp_ptype) media_type); - max_fr = config_get_video_max_fr((rtp_ptype) media_type); - - if (max_fs || max_fr || max_br || max_mbps) { - if (!added_fmtp) { - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst) - != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - added_fmtp = 1; - - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst, - payload_number); - } - - if (max_fs) { - (void) sdp_attr_set_fmtp_max_fs(sdp_p, level, 0, a_inst, - max_fs); - } - if (max_fr) { - (void) sdp_attr_set_fmtp_max_fr(sdp_p, level, 0, a_inst, - max_fr); - } - if (max_br) { - (void) sdp_attr_set_fmtp_max_br(sdp_p, level, 0, a_inst, - max_br); - } - if (max_mbps) { - (void) sdp_attr_set_fmtp_max_mbps(sdp_p, level, 0, a_inst, - max_mbps); - } - } - break; - } - break; - - default: - break; - } -} - -/* - * gsmsdp_set_media_attributes - * - * Description: - * - * Add the specified media format to the SDP. - * - * Parameters: - * - * media_type - The media type (format) to add to the specified SDP. - * sdp_p - Pointer to the SDP the media attribute is to be added to. - * level - The media level of the SDP where the media attribute is to be added. - * payload_number - AVT payload type if the media attribute being added is - * RTP_AVT. - * - */ -static void -gsmsdp_set_media_attributes (uint32_t media_type, void *sdp_p, uint16_t level, - uint16_t payload_number) -{ - uint16_t a_inst, a_inst2, a_inst3, a_inst4; - int maxavbitrate = 0; - int maxcodedaudiobw = 0; - int usedtx = 0; - int stereo = 0; - int useinbandfec = 0; - int cbr = 0; - int maxptime = 0; - - - config_get_value(CFGID_MAXAVBITRATE, &maxavbitrate, sizeof(maxavbitrate)); - config_get_value(CFGID_MAXCODEDAUDIOBW, &maxcodedaudiobw, sizeof(maxcodedaudiobw)); - config_get_value(CFGID_USEDTX, &usedtx, sizeof(usedtx)); - config_get_value(CFGID_STEREO, &stereo, sizeof(stereo)); - config_get_value(CFGID_USEINBANDFEC, &useinbandfec, sizeof(useinbandfec)); - config_get_value(CFGID_CBR, &cbr, sizeof(cbr)); - config_get_value(CFGID_MAXPTIME, &maxptime, sizeof(maxptime)); - - - - switch (media_type) { - case RTP_PCMU: // type 0 - case RTP_PCMA: // type 8 - case RTP_G729: // type 18 - case RTP_G722: // type 9 - case RTP_ILBC: - case RTP_L16: - case RTP_ISAC: - case RTP_OPUS: - /* - * add a=rtpmap line - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, &a_inst) - != SDP_SUCCESS) { - return; - } - - (void) sdp_attr_set_rtpmap_payload_type(sdp_p, level, 0, a_inst, - payload_number); - - switch (media_type) { - case RTP_PCMU: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_PCMU); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - case RTP_PCMA: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_PCMA); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - case RTP_G729: - { - - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_G729); - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst2) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst2, - payload_number); - (void) sdp_attr_set_fmtp_annexb(sdp_p, level, 0, a_inst2, FALSE); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - } - break; - - case RTP_G722: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_G722); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - - case RTP_L16: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_L16_256K); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_L16_CLOCKRATE); - break; - - case RTP_ILBC: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_ILBC); - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst2) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst2, - payload_number); - (void) sdp_attr_set_fmtp_mode(sdp_p, level, 0, a_inst2, vcmGetILBCMode()); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - - case RTP_ISAC: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_ISAC); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_ISAC_CLOCKRATE); - break; - - case RTP_OPUS: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_OPUS); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_OPUS_CLOCKRATE); - (void) sdp_attr_set_rtpmap_num_chan (sdp_p, level, 0, a_inst, 2); - - /* a=fmtp options */ - if (maxavbitrate || maxcodedaudiobw || usedtx || stereo || useinbandfec || cbr) { - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst2) - != SDP_SUCCESS) { - return; - } - - (void) sdp_attr_set_fmtp_payload_type (sdp_p, level, 0, a_inst2, payload_number); - - if (maxavbitrate) - sdp_attr_set_fmtp_max_average_bitrate (sdp_p, level, 0, a_inst2, FMTP_MAX_AVERAGE_BIT_RATE); - - if(usedtx) - sdp_attr_set_fmtp_usedtx (sdp_p, level, 0, a_inst2, FALSE); - - if(stereo) - sdp_attr_set_fmtp_stereo (sdp_p, level, 0, a_inst2, FALSE); - - if(useinbandfec) - sdp_attr_set_fmtp_useinbandfec (sdp_p, level, 0, a_inst2, FALSE); - - if(maxcodedaudiobw) { - sdp_attr_set_fmtp_maxcodedaudiobandwidth (sdp_p, level, 0, a_inst2, - max_coded_audio_bandwidth_table[opus_fb].name); - } - - if(cbr) - sdp_attr_set_fmtp_cbr (sdp_p, level, 0, a_inst2, FALSE); - } - - /* a=ptime attribute */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_PTIME, &a_inst3) - != SDP_SUCCESS) { - return; - } - - sdp_attr_set_simple_u32(sdp_p, SDP_ATTR_PTIME, level, 0, a_inst3, ATTR_PTIME); - - if(maxptime) { - /* a=maxptime attribute */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_MAXPTIME, &a_inst4) - != SDP_SUCCESS) { - return; - } - - sdp_attr_set_simple_u32(sdp_p, SDP_ATTR_MAXPTIME, level, 0, a_inst4, ATTR_MAXPTIME); - } - - break; - } - break; - - case RTP_AVT: - /* - * add a=rtpmap line - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, &a_inst) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_TEL_EVENT); - (void) sdp_attr_set_rtpmap_payload_type(sdp_p, level, 0, a_inst, - payload_number); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - - /* - * Malloc the mediainfo structure - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst, - payload_number); - (void) sdp_attr_set_fmtp_range(sdp_p, level, 0, a_inst, - SIPSDP_NTE_DTMF_MIN, - SIPSDP_NTE_DTMF_MAX); - - - break; - - default: - /* The remaining coded types aren't supported, but are listed below - * as a reminder - * RTP_CELP = 1, - * RTP_GSM = 3, - * RTP_G726 = 2, - * RTP_G723 = 4, - * RTP_DVI4 = 5, - * RTP_DVI4_II = 6, - * RTP_LPC = 7, - * RTP_G722 = 9, - * RTP_G728 = 15, - * RTP_JPEG = 26, - * RTP_NV = 28, - * RTP_H261 = 31 - */ - - break; - } -} - -/* - * gsmsdp_set_sctp_attributes - * - * Description: - * - * Add the specified SCTP media format to the SDP. - * - * Parameters: - * - * sdp_p - Pointer to the SDP the media attribute is to be added to. - * level - The media level of the SDP where the media attribute is to be added. - */ -static void -gsmsdp_set_sctp_attributes (void *sdp_p, uint16_t level, fsmdef_media_t *media) -{ - uint16_t a_inst; - - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_SCTPMAP, &a_inst) - != SDP_SUCCESS) { - return; - } - - sdp_attr_set_sctpmap_port(sdp_p, level, 0, a_inst, - media->local_datachannel_port); - - sdp_attr_set_sctpmap_protocol (sdp_p, level, 0, a_inst, - media->datachannel_protocol); - - sdp_attr_set_sctpmap_streams (sdp_p, level, 0, a_inst, - media->datachannel_streams); -} - -/* - * gsmsdp_set_remote_sdp - * - * Description: - * - * Sets the specified SDP as the remote SDP in the DCB. - * - * Parameters: - * - * dcb_p - Pointer to the DCB. - * sdp_p - Pointer to the SDP to be set as the remote SDP in the DCB. - */ -static void -gsmsdp_set_remote_sdp (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p) -{ - dcb_p->remote_sdp_present = TRUE; -} - -/* - * gsmsdp_get_sdp_direction_attr - * - * Description: - * - * Given a sdp_direction_e enumerated type, returns a sdp_attr_e - * enumerated type. - * - * Parameters: - * - * direction - The SDP direction used to determine which sdp_attr_e to return. - * - */ -static sdp_attr_e -gsmsdp_get_sdp_direction_attr (sdp_direction_e direction) -{ - sdp_attr_e sdp_attr = SDP_ATTR_SENDRECV; - - switch (direction) { - case SDP_DIRECTION_INACTIVE: - sdp_attr = SDP_ATTR_INACTIVE; - break; - case SDP_DIRECTION_SENDONLY: - sdp_attr = SDP_ATTR_SENDONLY; - break; - case SDP_DIRECTION_RECVONLY: - sdp_attr = SDP_ATTR_RECVONLY; - break; - case SDP_DIRECTION_SENDRECV: - sdp_attr = SDP_ATTR_SENDRECV; - break; - default: - GSM_ERR_MSG("\nFSMDEF ERROR: replace with formal error text"); - } - - return sdp_attr; -} - -/* - * gsmsdp_set_sdp_direction - * - * Description: - * - * Adds a direction attribute to the given media line in the - * specified SDP. - * - * Parameters: - * - * media - pointer to the fsmdef_media_t for the media entry. - * direction - The direction to use when setting the direction attribute. - * sdp_p - Pointer to the SDP to set the direction attribute against. - */ -static void -gsmsdp_set_sdp_direction (fsmdef_media_t *media, - sdp_direction_e direction, void *sdp_p) -{ - sdp_attr_e sdp_attr = SDP_ATTR_SENDRECV; - uint16_t a_instance = 0; - - /* - * Convert the direction to an SDP direction attribute. - */ - sdp_attr = gsmsdp_get_sdp_direction_attr(direction); - if (media->level) { - (void) sdp_add_new_attr(sdp_p, media->level, 0, sdp_attr, &a_instance); - } else { - /* Just in case that there is no level defined, add to the session */ - (void) sdp_add_new_attr(sdp_p, SDP_SESSION_LEVEL, 0, sdp_attr, - &a_instance); - } -} - -/* - * gsmsdp_get_ice_attributes - * - * Description: - * - * Returns the ice attribute strings at a given level - * - * Parameters: - * - * session - true = session level attributes, false = media line attribs - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP whose ice candidates are being searched. - * ice_attribs - return ice attribs at this level in an array - * attributes_ctp - count of array of media line attributes - */ - -static cc_causes_t -gsmsdp_get_ice_attributes (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, char ***ice_attribs, int *attributes_ctp) -{ - uint16_t num_a_lines = 0; - uint16_t i; - sdp_result_e result; - char* ice_attrib; - - result = sdp_attr_num_instances(sdp_p, level, 0, sdp_attr, &num_a_lines); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("enumerating ICE attributes failed"); - return result; - } - - if (num_a_lines < 1) { - GSM_DEBUG("enumerating ICE attributes returned 0 attributes"); - return CC_CAUSE_OK; - } - - *ice_attribs = (char **)cpr_malloc(num_a_lines * sizeof(char *)); - - if (!(*ice_attribs)) - return CC_CAUSE_OUT_OF_MEM; - - *attributes_ctp = 0; - - for (i = 0; i < num_a_lines; i++) { - result = sdp_attr_get_ice_attribute (sdp_p, level, 0, sdp_attr, (uint16_t) (i + 1), - &ice_attrib); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to retrieve ICE attribute"); - cpr_free(*ice_attribs); - return result == SDP_INVALID_SDP_PTR ? - CC_CAUSE_INVALID_SDP_POINTER : - result == SDP_INVALID_PARAMETER ? - CC_CAUSE_BAD_ICE_ATTRIBUTE : - /* otherwise */ - CC_CAUSE_ERROR; - } - (*ice_attribs)[i] = (char *) cpr_calloc(1, strlen(ice_attrib) + 1); - if(!(*ice_attribs)[i]) - return CC_CAUSE_OUT_OF_MEM; - - sstrncpy((*ice_attribs)[i], ice_attrib, strlen(ice_attrib) + 1); - (*attributes_ctp)++; - } - - return CC_CAUSE_OK; -} - -/* - * gsmsdp_set_ice_attribute - * - * Description: - * - * Adds an ice attribute attributes to the specified SDP. - * - * Parameters: - * - * session - true = session level attribute, false = media line attribute - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * ice_attrib - ice attribute to set - */ -void -gsmsdp_set_ice_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, char *ice_attrib) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, sdp_attr, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_ice_attribute(sdp_p, level, 0, sdp_attr, a_instance, ice_attrib); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_rtcp_fb_ack_attribute - * - * Description: - * - * Adds an rtcp-fb:...ack attribute attributes to the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * ack_type - Type of ack feedback mechanism in use - */ -void -gsmsdp_set_rtcp_fb_ack_attribute (uint16_t level, - void *sdp_p, - u16 payload_type, - sdp_rtcp_fb_ack_type_e ack_type) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - result = sdp_attr_set_rtcp_fb_ack(sdp_p, level, payload_type, - a_instance, ack_type); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_audio_level_attribute - * - * Description: - * - * Adds an audio level extension attributesto the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the attribute against. - */ -void -gsmsdp_set_extmap_attribute (uint16_t level, - void *sdp_p, - u16 id, - const char* uri) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_EXTMAP, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_extmap(sdp_p, level, id, uri, a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_rtcp_fb_nack_attribute - * - * Description: - * - * Adds an rtcp-fb:...nack attribute attributes to the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * nack_type - Type of nack feedback mechanism in use - */ -void -gsmsdp_set_rtcp_fb_nack_attribute (uint16_t level, - void *sdp_p, - u16 payload_type, - sdp_rtcp_fb_nack_type_e nack_type) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_rtcp_fb_nack(sdp_p, level, payload_type, - a_instance, nack_type); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_rtcp_fb_trr_int_attribute - * - * Description: - * - * Adds an rtcp-fb:...trr-int attribute attributes to the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * trr_interval - Interval to set trr-int value to - */ -void -gsmsdp_set_rtcp_fb_trr_int_attribute (uint16_t level, - void *sdp_p, - u16 payload_type, - u32 trr_interval) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_rtcp_fb_trr_int(sdp_p, level, payload_type, - a_instance, trr_interval); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_rtcp_fb_ccm_attribute - * - * Description: - * - * Adds an rtcp-fb:...ccm attribute attributes to the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * ccm_type - Type of ccm feedback mechanism in use - */ -void -gsmsdp_set_rtcp_fb_ccm_attribute (uint16_t level, - void *sdp_p, - u16 payload_type, - sdp_rtcp_fb_ccm_type_e ccm_type) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTCP_FB, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_rtcp_fb_ccm(sdp_p, level, payload_type, - a_instance, ccm_type); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_rtcp_mux_attribute - * - * Description: - * - * Adds an ice attribute attributes to the specified SDP. - * - * Parameters: - * - * session - true = session level attribute, false = media line attribute - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * rtcp_mux - ice attribute to set - */ -static void -gsmsdp_set_rtcp_mux_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, boolean rtcp_mux) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, sdp_attr, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_rtcp_mux_attribute(sdp_p, level, 0, sdp_attr, a_instance, rtcp_mux); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_setup_attribute - * - * Description: - * - * Adds a setup attribute to the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * setup_type - Value for the a=setup line - */ -static void -gsmsdp_set_setup_attribute(uint16_t level, - void *sdp_p, sdp_setup_type_e setup_type) { - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_SETUP, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_setup_attribute(sdp_p, level, 0, - a_instance, setup_type); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute"); - } -} - -/* - * gsmsdp_set_dtls_fingerprint_attribute - * - * Description: - * - * Adds an dtls fingerprint attribute attributes to the specified SDP. - * - * Parameters: - * - * sdp_attr - The attribute to set - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the attribute against. - * hash_func - hash function string, e.g. "sha-256" - * fingerprint - fingerprint attribute to set - */ -static void -gsmsdp_set_dtls_fingerprint_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, - char *hash_func, char *fingerprint) -{ - uint16_t a_instance = 0; - sdp_result_e result; - char hash_and_fingerprint[FSMDEF_MAX_DIGEST_ALG_LEN + FSMDEF_MAX_DIGEST_LEN + 2]; - - snprintf(hash_and_fingerprint, sizeof(hash_and_fingerprint), - "%s %s", hash_func, fingerprint); - - result = sdp_add_new_attr(sdp_p, level, 0, sdp_attr, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_dtls_fingerprint_attribute(sdp_p, level, 0, sdp_attr, - a_instance, hash_and_fingerprint); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set dtls fingerprint attribute"); - } -} - -/* - * gsmsdp_set_identity_attribute - * - * Description: - * - * Adds an identity attribute to the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * identity - attribute value to set - * identity_len - string len of fingerprint - */ -static void -gsmsdp_set_identity_attribute (uint16_t level, void *sdp_p, - char *identity) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_IDENTITY, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute"); - return; - } - - result = sdp_attr_set_simple_string(sdp_p, level, 0, SDP_ATTR_IDENTITY, - a_instance, identity); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set identity attribute"); - } -} - -/* - * gsmsdp_remove_sdp_direction - * - * Description: - * - * Removes the direction attribute corresponding to the passed in direction - * from the media line of the specified SDP. - * - * Parameters: - * - * media - pointer to the fsmdef_media_t for the media entry. - * direction - The direction whose corresponding direction attribute - * is to be removed. - * sdp_p - Pointer to the SDP where the direction attribute is to be - * removed. - */ -static void -gsmsdp_remove_sdp_direction (fsmdef_media_t *media, - sdp_direction_e direction, void *sdp_p) -{ - sdp_attr_e sdp_attr = SDP_ATTR_SENDRECV; - - sdp_attr = gsmsdp_get_sdp_direction_attr(direction); - (void) sdp_delete_attr(sdp_p, media->level, 0, sdp_attr, 1); -} - -/* - * gsmsdp_set_local_sdp_direction - * - * Description: - * - * Sets the direction attribute for the local SDP. - * - * Parameters: - * - * dcb_p - The DCB where the local SDP is located. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * direction - The media direction to set into the local SDP. - */ -void -gsmsdp_set_local_sdp_direction (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - sdp_direction_e direction) -{ - /* - * If media direction was previously set, remove the direction attribute - * before adding the specified direction. Save the direction in previous - * direction before clearing it. - */ - if (media->type != SDP_MEDIA_APPLICATION) { - if (media->direction_set) { - media->previous_sdp.direction = media->direction; - gsmsdp_remove_sdp_direction(media, media->direction, - dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL ); - media->direction_set = FALSE; - } - gsmsdp_set_sdp_direction(media, direction, dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL); - } - - /* - * We could just get the direction from the local SDP when we need it in - * GSM, but setting the direction in the media structure gives a quick way - * to access the media direction. - */ - media->direction = direction; - media->direction_set = TRUE; -} - -/* - * gsmsdp_get_remote_sdp_direction - * - * Description: - * - * Returns the media direction from the specified SDP. We will check for the - * media direction attribute at the session level and the first AUDIO media line. - * If the direction attribute is specified at the media level, the media level setting - * overrides the session level attribute. - * - * Parameters: - * - * dcb_p - pointer to the fsmdef_dcb_t. - * level - media line level. - * dest_addr - pointer to the remote address. - */ -static sdp_direction_e -gsmsdp_get_remote_sdp_direction (fsmdef_dcb_t *dcb_p, uint16_t level, - cpr_ip_addr_t *dest_addr) -{ - sdp_direction_e direction = SDP_DIRECTION_SENDRECV; - cc_sdp_t *sdp_p = dcb_p->sdp; - uint16_t media_attr; - uint16_t i; - uint32 port; - int sdpmode = 0; - static const sdp_attr_e dir_attr_array[] = { - SDP_ATTR_INACTIVE, - SDP_ATTR_RECVONLY, - SDP_ATTR_SENDONLY, - SDP_ATTR_SENDRECV, - SDP_MAX_ATTR_TYPES - }; - - if (!sdp_p->dest_sdp) { - return direction; - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - media_attr = 0; /* media level attr. count */ - /* - * Now check for direction as a media attribute. If found, the - * media attribute takes precedence over direction specified - * as a session attribute. - * - * In order to find out whether there is a direction attribute - * associated with a media line (or even at the - * session level) or not is to get the number of instances of - * that attribute via the sdp_attr_num_instances() first. The is - * because the sdp_get_media_direction() always returns a valid - * direction value even when there is no direction attribute with - * the media line (or session level). - * - * Note: there is no single attribute value to pass to the - * sdp_attr_num_instances() to get number a direction attribute that - * represents inactive, recvonly, sendonly, sendrcv. We have to - * look for each one of them individually. - */ - for (i = 0; (dir_attr_array[i] != SDP_MAX_ATTR_TYPES); i++) { - if (sdp_attr_num_instances(sdp_p->dest_sdp, level, 0, - dir_attr_array[i], &media_attr) == - SDP_SUCCESS) { - if (media_attr) { - /* There is direction attribute in the media line */ - direction = sdp_get_media_direction(sdp_p->dest_sdp, - level, 0); - break; - } - } - } - - /* - * Check for the direction attribute. The direction can be specified - * as a session attribute or a media stream attribute. If the direction - * is specified as a session attribute, the direction is applicable to - * all media streams in the SDP. - */ - if (media_attr == 0) { - /* no media level direction, get the direction from session */ - direction = sdp_get_media_direction(sdp_p->dest_sdp, - SDP_SESSION_LEVEL, 0); - } - - /* - * To support legacy way of signaling remote hold, we will interpret - * c=0.0.0.0 to be a=inactive - */ - if (dest_addr->type == CPR_IP_ADDR_IPV4 && - dest_addr->u.ip4 == 0) { - - /* - * For WebRTC, we allow active media sections with IP=0.0.0.0, iff - * port != 0. This is to allow interop with existing Trickle ICE - * implementations. TODO: This may need to be updated to match the - * spec once the Trickle ICE spec is finalized. - */ - port = sdp_get_media_portnum(sdp_p->dest_sdp, level); - if (sdpmode && port != 0) { - return direction; - } - - direction = SDP_DIRECTION_INACTIVE; - } else { - - //todo IPv6: reject the request. - } - return direction; -} - -/** - * - * The function overrides direction for some special feature - * processing. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - pointer to fsmdef_media_t for the media to - * override the direction. - * - * @return None. - * @pre (dcb_p not_eq NULL) and (media not_eq NULL) - */ -static void -gsmsdp_feature_overide_direction (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - /* - * Disable video if this is a BARGE with video - */ - if ( CC_IS_VIDEO(media->cap_index) && - dcb_p->join_call_id != CC_NO_CALL_ID ){ - media->support_direction = SDP_DIRECTION_INACTIVE; - } - - if (CC_IS_VIDEO(media->cap_index) && media->support_direction == SDP_DIRECTION_INACTIVE) { - DEF_DEBUG(GSM_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE", "gsmsdp_feature_overide_direction"); - } -} - -/* - * gsmsdp_negotiate_local_sdp_direction - * - * Description: - * - * Given an offer SDP, return the corresponding answer SDP direction. - * - * local hold remote direction support direction new local direction - * enabled inactive any inactive - * enabled sendrecv sendonly sendonly - * enabled sendrecv recvonly inactive - * enabled sendrecv sendrecv sendonly - * enabled sendrecv inactive inactive - * enabled sendonly any inactive - * enabled recvonly sendrecv sendonly - * enabled recvonly sendonly sendonly - * enabled recvonly recvonly inactive - * enabled recvonly inactive inactive - * disabled inactive any inactive - * disabled sendrecv sendrecv sendrecv - * disabled sendrecv sendonly sendonly - * disabled sendrecv recvonly recvonly - * disabled sendrecv inactive inactive - * disabled sendonly sendrecv recvonly - * disabled sendonly sendonly inactive - * disabled sendonly recvonly recvonly - * disabled sendonly inactive inactive - * disabled recvonly sendrecv sendonly - * disabled recvonly sendonly sendonly - * disabled recvonly recvonly inactive - * disabled recvonly inactive inactive - * - * Parameters: - * - * dcb_p - pointer to the fsmdef_dcb_t. - * media - pointer to the fsmdef_media_t for the current media entry. - * local_hold - Boolean indicating if local hold feature is enabled - */ -static sdp_direction_e -gsmsdp_negotiate_local_sdp_direction (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - boolean local_hold) -{ - sdp_direction_e direction = SDP_DIRECTION_SENDRECV; - sdp_direction_e remote_direction = gsmsdp_get_remote_sdp_direction(dcb_p, - media->level, &media->dest_addr); - - if (remote_direction == SDP_DIRECTION_SENDRECV) { - if (local_hold) { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_SENDONLY)) { - direction = SDP_DIRECTION_SENDONLY; - } else { - direction = SDP_DIRECTION_INACTIVE; - } - } else { - direction = media->support_direction; - } - } else if (remote_direction == SDP_DIRECTION_SENDONLY) { - if (local_hold) { - direction = SDP_DIRECTION_INACTIVE; - } else { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_RECVONLY)) { - direction = SDP_DIRECTION_RECVONLY; - } else { - direction = SDP_DIRECTION_INACTIVE; - } - } - } else if (remote_direction == SDP_DIRECTION_INACTIVE) { - direction = SDP_DIRECTION_INACTIVE; - } else if (remote_direction == SDP_DIRECTION_RECVONLY) { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_SENDONLY)) { - direction = SDP_DIRECTION_SENDONLY; - } else { - direction = SDP_DIRECTION_INACTIVE; - } - } - - return direction; -} - -/* - * gsmsdp_add_default_audio_formats_to_local_sdp - * - * Description: - * - * Add all supported media formats to the local SDP of the specified DCB - * at the specified media level. If the call is involved in a conference - * call, only add G.711 formats. - * - * Parameters - * - * dcb_p - The DCB whose local SDP is to be updated with the default media formats. - * sdp_p - Pointer to the local sdp structure. This is added so call to this - * routine can be made irrespective of whether we have a dcb or not(To - * handle out-of-call options request for example) - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * - */ -static void -gsmsdp_add_default_audio_formats_to_local_sdp (fsmdef_dcb_t *dcb_p, - cc_sdp_t * sdp_p, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_add_default_audio_formats_to_local_sdp"; - int local_media_types[CC_MAX_MEDIA_TYPES]; - int16_t local_avt_payload_type = RTP_NONE; - DtmfOutOfBandTransport_t transport = DTMF_OUTOFBAND_NONE; - int type_cnt; - void *local_sdp_p = NULL; - uint16_t media_format_count; - uint16_t level; - int i; - - if (media) { - level = media->level; - } else { - level = 1; - } - local_sdp_p = (void *) sdp_p->src_sdp; - - /* - * Create list of supported codecs. Get all the codecs that the phone - * supports. - */ - media_format_count = sip_config_local_supported_codecs_get( - (rtp_ptype *) local_media_types, - CC_MAX_MEDIA_TYPES); - /* - * If there are no media payloads, it's because we are making an - * initial offer. We will be opening our receive port so we need to specify - * the media payload type to be used initially. We set the media payload - * type in the dcb to do this. Until we receive an answer from the far - * end, we will use our first choice payload type. i.e. the first payload - * type sent in our AUDIO media line. - */ - - if (dcb_p && media && media->num_payloads == 0) { - - if (media->payloads && - (media->num_payloads < media_format_count)) { - cpr_free(media->payloads); - media->payloads = NULL; - } - - if (!media->payloads) { - media->payloads = cpr_calloc(media_format_count, - sizeof(vcm_payload_info_t)); - } - - media->num_payloads = 0; - for (i = 0; i < media_format_count; i++) { - if (local_media_types[i] > RTP_NONE) { - media->payloads[i].codec_type = local_media_types[i]; - media->payloads[i].local_rtp_pt = local_media_types[i]; - media->payloads[i].remote_rtp_pt = local_media_types[i]; - media->num_payloads++; - } - } - gsmsdp_copy_payloads_to_previous_sdp(media); - } - - /* - * Get configured OOB DTMF setting and avt payload type if applicable - */ - config_get_value(CFGID_DTMF_OUTOFBAND, &transport, sizeof(transport)); - - if ((transport == DTMF_OUTOFBAND_AVT) || - (transport == DTMF_OUTOFBAND_AVT_ALWAYS)) { - int temp_payload_type = RTP_NONE; - - config_get_value(CFGID_DTMF_AVT_PAYLOAD, - &(temp_payload_type), - sizeof(temp_payload_type)); - local_avt_payload_type = (uint16_t) temp_payload_type; - } - - /* - * add all the audio media types - */ - for (type_cnt = 0; - (type_cnt < media_format_count) && - (local_media_types[type_cnt] > RTP_NONE); - type_cnt++) { - - if (sdp_add_media_payload_type(local_sdp_p, level, - (uint16_t)local_media_types[type_cnt], - SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { - GSM_ERR_MSG(DEB_L_C_F_PREFIX"Adding media payload type failed", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p, - level, (uint16_t)local_media_types[type_cnt]); - } - } - - /* - * add the avt media type - */ - if (local_avt_payload_type > RTP_NONE) { - if (sdp_add_media_payload_type(local_sdp_p, level, - local_avt_payload_type, - SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding AVT payload type failed", - dcb_p->line, dcb_p->call_id, fname); - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level, - local_avt_payload_type); - if (media) { - media->avt_payload_type = local_avt_payload_type; - } - } - } -} - -/* - * gsmsdp_add_default_video_formats_to_local_sdp - * - * Description: - * - * Add all supported media formats to the local SDP of the specified DCB - * at the specified media level. If the call is involved in a conference - * call, only add G.711 formats. - * - * Parameters - * - * dcb_p - The DCB whose local SDP is to be updated with the default media formats. - * sdp_p - Pointer to the local sdp structure. This is added so call to this - * routine can be made irrespective of whether we have a dcb or not(To - * handle out-of-call options request for example) - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * - */ -static void -gsmsdp_add_default_video_formats_to_local_sdp (fsmdef_dcb_t *dcb_p, - cc_sdp_t * sdp_p, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_add_default_video_formats_to_local_sdp"; - int video_media_types[CC_MAX_MEDIA_TYPES]; - int type_cnt; - void *local_sdp_p = NULL; - uint16_t video_format_count; - uint16_t level; - line_t line = 0; - callid_t call_id = 0; - int i; - - if (dcb_p && media) { - line = dcb_p->line; - call_id = dcb_p->call_id; - } - GSM_DEBUG(DEB_L_C_F_PREFIX"", DEB_L_C_F_PREFIX_ARGS(GSM, line, call_id, fname)); - - if (media) { - level = media->level; - } else { - level = 2; - } - local_sdp_p = (void *) sdp_p->src_sdp; - - /* - * Create list of supported codecs. Get all the codecs that the phone supports. - */ - - video_format_count = sip_config_video_supported_codecs_get( (rtp_ptype *) video_media_types, - CC_MAX_MEDIA_TYPES, TRUE /*offer*/); - - GSM_DEBUG(DEB_L_C_F_PREFIX"video_count=%d", DEB_L_C_F_PREFIX_ARGS(GSM, line, call_id, fname), video_format_count); - /* - * If the there are no media payloads, its because we are making an - * initial offer. We will be opening our receive port so we need to specify - * the media payload type to be used initially. We set the media payload - * type in the dcb to do this. Until we receive an answer from the far - * end, we will use our first choice payload type. i.e. the first payload - * type sent in our video media line. - */ - if (dcb_p && media && media->num_payloads == 0) { - if (media->payloads && - (media->num_payloads < video_format_count)) { - cpr_free(media->payloads); - media->payloads = NULL; - } - - if (!media->payloads) { - media->payloads = cpr_calloc(video_format_count, - sizeof(vcm_payload_info_t)); - } - - media->num_payloads = 0; - for (i = 0; i < video_format_count; i++) { - if (video_media_types[i] > RTP_NONE) { - media->payloads[i].codec_type = video_media_types[i]; - media->payloads[i].local_rtp_pt = video_media_types[i]; - media->payloads[i].remote_rtp_pt = video_media_types[i]; - media->num_payloads++; - } - } - gsmsdp_copy_payloads_to_previous_sdp(media); - } - - - /* - * add all the video media types - */ - for (type_cnt = 0; - (type_cnt < video_format_count) && - (video_media_types[type_cnt] > RTP_NONE); - type_cnt++) { - - if (sdp_add_media_payload_type(local_sdp_p, level, - (uint16_t)video_media_types[type_cnt], - SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR(1)", - line, call_id, fname); - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p, - level, (uint16_t)video_media_types[type_cnt]); - } - } -} - -/** - * This function sets the mid attr at the media level - * and labels the relevant media streams when phone is - * operating in a dual stack mode - * - * @param[in]src_sdp_p - Our source sdp. - * @param[in]level - The level of the media that we are operating on. - * - * @return - None - * - */ -static void gsmsdp_set_mid_attr (void *src_sdp_p, uint16_t level) -{ - uint16 inst_num; - - if (platform_get_ip_address_mode() == CPR_IP_MODE_DUAL) { - /* - * add a=mid line - */ - (void) sdp_add_new_attr(src_sdp_p, level, 0, SDP_ATTR_MID, &inst_num); - - (void) sdp_attr_set_simple_u32(src_sdp_p, SDP_ATTR_MID, level, 0, - inst_num, level); - } -} - -/** - * This function sets the anat attr to the session level - * and labels the relevant media streams - * - * @param[in]media - The media line that we are operating on. - * @param[in]dcb_p - Pointer to the DCB whose local SDP is to be updated. - * - * @return - None - * - */ -static void gsmsdp_set_anat_attr (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - void *src_sdp_p = (void *) dcb_p->sdp->src_sdp; - void *dest_sdp_p = (void *) dcb_p->sdp->dest_sdp; - uint16 inst_num; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - u32 group_id_1, group_id_2; - uint16_t i; - fsmdef_media_t *group_media; - - - if (dest_sdp_p == NULL) { - /* If this is our initial offer */ - if (media->addr_type == SDP_AT_IP4) { - group_media = gsmsdp_find_anat_pair(dcb_p, media); - if (group_media != NULL) { - /* - * add a=group line - */ - (void) sdp_add_new_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, &inst_num); - - (void) sdp_set_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, SDP_GROUP_ATTR_ANAT); - - (void) sdp_set_group_num_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, 2); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, group_media->level); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, media->level); - } - } - } else { - /* This is an answer, check if the offer rcvd had anat grouping */ - (void) sdp_attr_num_instances(dest_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(dest_sdp_p, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - for (i = 1; i <= num_anat_lines; i++) { - group_id_1 = sdp_get_group_id(dest_sdp_p, SDP_SESSION_LEVEL, 0, i, 1); - group_id_2 = sdp_get_group_id(dest_sdp_p, SDP_SESSION_LEVEL, 0, i, 2); - - if ((media->level == group_id_1) || (media->level == group_id_2)) { - - group_media = gsmsdp_find_anat_pair(dcb_p, media); - if (group_media != NULL) { - if (sdp_get_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, i) != SDP_GROUP_ATTR_ANAT) { - /* - * add a=group line - */ - (void) sdp_add_new_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, &inst_num); - (void) sdp_set_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, SDP_GROUP_ATTR_ANAT); - - } - (void) sdp_set_group_num_id(src_sdp_p, SDP_SESSION_LEVEL, 0, i, 2); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, i, group_media->level); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, i, media->level); - - } else { - /* - * add a=group line - */ - (void) sdp_add_new_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, &inst_num); - (void) sdp_set_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, SDP_GROUP_ATTR_ANAT); - - (void) sdp_set_group_num_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, 1); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, media->level); - } - - } - } - } - gsmsdp_set_mid_attr (src_sdp_p, media->level); -} - -/* - * gsmsdp_update_local_sdp_media - * - * Description: - * - * Adds an AUDIO media line to the local SDP of the specified DCB. If all_formats - * is TRUE, sets all media formats supported by the phone into the local SDP, else - * only add the single negotiated media format. If an AUDIO media line already - * exists in the local SDP, remove it as this function completely rebuilds the - * AUDIO media line and will do so at the same media level as the pre-existing - * AUDIO media line. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * cc_sdp_p - Pointer to the SDP being updated. - * all_formats - If true, all supported media formats will be added to the - * AUDIO media line of the SDP. Otherwise, only the single - * negotiated media format is added. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * transport - transport type to for this media line. - * - */ -static void -gsmsdp_update_local_sdp_media (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - boolean all_formats, fsmdef_media_t *media, - sdp_transport_e transport) -{ - static const char fname[] = "gsmsdp_update_local_sdp_media"; - uint16_t port; - sdp_result_e result; - uint16_t level; - void *sdp_p; - int sdpmode = 0; - int i = 0; - - if (!dcb_p || !media) { - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - return; - } - level = media->level; - port = media->src_port; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - sdp_p = cc_sdp_p ? (void *) cc_sdp_p->src_sdp : NULL; - - if (sdp_p == NULL) { - - gsmsdp_init_local_sdp(dcb_p->peerconnection, &(dcb_p->sdp)); - - cc_sdp_p = dcb_p->sdp; - if ((cc_sdp_p == NULL) || (cc_sdp_p->src_sdp == NULL)) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"sdp is NULL and init failed", - dcb_p->line, dcb_p->call_id, fname); - return; - } - sdp_p = (void *) cc_sdp_p->src_sdp; - } else { - - /* - * Remove the audio stream. Reset direction_set flag since - * all media attributes have just been removed. - */ - sdp_delete_media_line(sdp_p, level); - media->direction_set = FALSE; - } - - result = sdp_insert_media_line(sdp_p, level); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Inserting media line to Sdp failed", - dcb_p->line, dcb_p->call_id, fname); - return; - } - - gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr); - - (void) sdp_set_media_type(sdp_p, level, media->type); - - - (void) sdp_set_media_portnum(sdp_p, level, port, media->local_datachannel_port); - - /* Set media transport and crypto attributes if it is for SRTP */ - gsmsdp_update_local_sdp_media_transport(dcb_p, sdp_p, media, transport, - all_formats); - - if (all_formats) { - /* - * Add all supported media formats to the local sdp. - */ - switch (media->type) { - case SDP_MEDIA_AUDIO: - gsmsdp_add_default_audio_formats_to_local_sdp(dcb_p, cc_sdp_p, - media); - break; - case SDP_MEDIA_VIDEO: - gsmsdp_add_default_video_formats_to_local_sdp(dcb_p, cc_sdp_p, - media); - break; - case SDP_MEDIA_APPLICATION: - gsmsdp_set_sctp_attributes (sdp_p, level, media); - break; - default: - GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR media %d for level %d is not" - " supported\n", - dcb_p->line, dcb_p->call_id, fname, media->type, - media->level); - break; - } - } else { - /* - * Add negotiated codec list to the sdp - */ - for(i = 0; i < media->num_payloads; i++) { - result = - sdp_add_media_payload_type(sdp_p, level, - (uint16_t)(media->payloads[i].local_rtp_pt), - SDP_PAYLOAD_NUMERIC); - - if (result != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding dynamic payload type failed", - dcb_p->line, dcb_p->call_id, fname); - } - - switch (media->type) { - case SDP_MEDIA_AUDIO: - gsmsdp_set_media_attributes(media->payloads[i].codec_type, - sdp_p, level, - (uint16_t)(media->payloads[i].local_rtp_pt)); - break; - case SDP_MEDIA_VIDEO: - gsmsdp_set_video_media_attributes(media->payloads[i].codec_type, - cc_sdp_p, level, - (uint16_t)(media->payloads[i].local_rtp_pt)); - break; - case SDP_MEDIA_APPLICATION: - gsmsdp_set_sctp_attributes (sdp_p, level, media); - break; - default: - GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR media %d for level %d is" - " not supported\n", - dcb_p->line, dcb_p->call_id, fname, media->type, - media->level); - break; - } - - }//end for - - /* - * add the avt media type - */ - if (media->avt_payload_type > RTP_NONE) { - result = sdp_add_media_payload_type(sdp_p, level, - (uint16_t)media->avt_payload_type, - SDP_PAYLOAD_NUMERIC); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding AVT payload type failed", - dcb_p->line, dcb_p->call_id, fname); - } - gsmsdp_set_media_attributes(RTP_AVT, sdp_p, level, - (uint16_t) media->avt_payload_type); - } - } - - if (!sdpmode) - gsmsdp_set_anat_attr(dcb_p, media); -} - -/* - * gsmsdp_update_local_sdp - * - * Description: - * - * Updates the local SDP of the DCB based on the remote SDP. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * offer - Indicates whether the remote SDP was received in an offer - * or an answer. - * initial_offer - this media line is initial offer. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * - * Return: - * TRUE - update the local SDP was successfull. - * FALSE - update the local SDP failed. - */ -static boolean -gsmsdp_update_local_sdp (fsmdef_dcb_t *dcb_p, boolean offer, - boolean initial_offer, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_update_local_sdp"; - cc_action_data_t data; - sdp_direction_e direction; - boolean local_hold = (boolean)FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL); - sdp_result_e sdp_res; - - if (media->src_port == 0) { - GSM_DEBUG(DEB_L_C_F_PREFIX"allocate receive port for media line", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - /* - * Source port has not been allocated, this could mean we - * processing an initial offer SDP, SDP that requets to insert - * a media line or re-insert a media line. - */ - data.open_rcv.is_multicast = FALSE; - data.open_rcv.listen_ip = ip_addr_invalid; - data.open_rcv.port = 0; - data.open_rcv.keep = FALSE; - /* - * Indicate type of media (audio/video etc) becase some for supporting - * video over vieo, the port is obtained from other entity. - */ - data.open_rcv.media_type = media->type; - data.open_rcv.media_refid = media->refid; - if (cc_call_action(dcb_p->call_id, dcb_p->line, CC_ACTION_OPEN_RCV, - &data) == CC_RC_SUCCESS) { - /* allocate port successful, save the port */ - media->src_port = data.open_rcv.port; - media->rcv_chan = FALSE; /* mark no RX chan yet */ - } else { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - } - - /* - * Negotiate direction based on remote SDP. - */ - direction = gsmsdp_negotiate_local_sdp_direction(dcb_p, media, local_hold); - - /* - * Update Transmit SRTP transmit key if this SRTP session. - */ - if (media->transport == SDP_TRANSPORT_RTPSAVP) { - gsmsdp_update_crypto_transmit_key(dcb_p, media, offer, - initial_offer, direction); - } - - if (offer == TRUE) { - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, FALSE, media, - media->transport); - } - - /* - * Set local sdp direction. - */ - if (media->direction_set) { - if (media->direction != direction) { - gsmsdp_set_local_sdp_direction(dcb_p, media, direction); - } - } else { - gsmsdp_set_local_sdp_direction(dcb_p, media, direction); - } - return (TRUE); -} - -/* - * gsmsdp_update_local_sdp_for_multicast - * - * Description: - * - * Updates the local SDP of the DCB based on the remote SDP for - * multicast. Populates the local sdp with the same addr:port as - * in the offer and the same direction as in the offer (as per - * rfc3264). - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * portnum - Remote port. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * offer - boolean indicating an offer SDP if true. - * initial_offer - boolean indicating an initial offer SDP if true. - * - */ -static boolean -gsmsdp_update_local_sdp_for_multicast (fsmdef_dcb_t *dcb_p, - uint16_t portnum, - fsmdef_media_t *media, - boolean offer, - boolean initial_offer) -{ - static const char fname[] = "gsmsdp_update_local_sdp_for_multicast"; - sdp_direction_e direction; - char addr_str[MAX_IPADDR_STR_LEN]; - uint16_t level; - char *p_addr_str; - char *strtok_state; - - level = media->level; - - GSM_DEBUG(DEB_L_C_F_PREFIX"%d %d %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - portnum, level, initial_offer); - - direction = gsmsdp_get_remote_sdp_direction(dcb_p, media->level, - &media->dest_addr); - GSM_DEBUG(DEB_L_C_F_PREFIX"sdp direction: %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), direction); - /* - * Update Transmit SRTP transmit key any way to clean up the - * tx condition that we may have offered prior. - */ - gsmsdp_update_crypto_transmit_key(dcb_p, media, offer, initial_offer, - direction); - - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, FALSE, - media, media->transport); - - /* - * Set local sdp direction same as on remote SDP for multicast - */ - if ((direction == SDP_DIRECTION_RECVONLY) || (direction == SDP_DIRECTION_INACTIVE)) { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_RECVONLY)) { - /* - * Echo same direction back in our local SDP but set the direction - * in DCB to recvonly so that LSM operations on rcv port work - * without modification. - */ - } else { - direction = SDP_DIRECTION_INACTIVE; - GSM_DEBUG(DEB_L_C_F_PREFIX"media line" - " does not support receive stream\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - gsmsdp_set_local_sdp_direction(dcb_p, media, direction); - media->direction_set = TRUE; - } else { - /* - * return FALSE indicating error - */ - return (FALSE); - } - - /* - * Set the ip addr to the multicast ip addr. - */ - ipaddr2dotted(addr_str, &media->dest_addr); - p_addr_str = PL_strtok_r(addr_str, "[ ]", &strtok_state); - - /* - * Set the local SDP port number to match far ends port number. - */ - (void) sdp_set_media_portnum(dcb_p->sdp->src_sdp, level, portnum, 0); - - /* - * c= line
- */ - (void) sdp_set_conn_nettype(dcb_p->sdp->src_sdp, level, SDP_NT_INTERNET); - (void) sdp_set_conn_addrtype(dcb_p->sdp->src_sdp, level, media->addr_type); - (void) sdp_set_conn_address(dcb_p->sdp->src_sdp, level, p_addr_str); - - return (TRUE); -} - -/* - * gsmsdp_get_remote_avt_payload_type - * - * Description: - * - * Returns the AVT payload type of the given audio line in the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute is to be found. - * sdp_p - Pointer to the SDP whose AVT payload type is being searched. - * - */ -static int -gsmsdp_get_remote_avt_payload_type (uint16_t level, void *sdp_p) -{ - uint16_t i; - uint16_t ptype; - int remote_avt_payload_type = RTP_NONE; - uint16_t num_a_lines = 0; - const char *encname = NULL; - - /* - * Get number of RTPMAP attributes for the media line - */ - (void) sdp_attr_num_instances(sdp_p, level, 0, SDP_ATTR_RTPMAP, - &num_a_lines); - - /* - * Loop through AUDIO media line RTPMAP attributes. The last - * NET dynamic payload type will be returned. - */ - for (i = 0; i < num_a_lines; i++) { - ptype = sdp_attr_get_rtpmap_payload_type(sdp_p, level, 0, - (uint16_t) (i + 1)); - if (sdp_media_dynamic_payload_valid(sdp_p, ptype, level)) { - encname = sdp_attr_get_rtpmap_encname(sdp_p, level, 0, - (uint16_t) (i + 1)); - if (encname) { - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_TEL_EVENT) == 0) { - remote_avt_payload_type = ptype; - } - } - } - } - return (remote_avt_payload_type); -} - - -#define MIX_NEAREND_STRING "X-mix-nearend" - -/* - * gsmsdp_negotiate_codec - * - * Description: - * - * Negotiates an acceptable codec from the local and remote SDPs - * - * Parameters: - * - * dcb_p - Pointer to DCB whose codec is being negotiated - * sdp_p - Pointer to local and remote SDP - * media - Pointer to the fsmdef_media_t for a given media entry whose - * codecs are being negotiated. - * offer - Boolean indicating if the remote SDP came in an OFFER. - * - * Returns: - * - * codec > 0: most preferred negotiated codec - * <= 0: negotiation failed - */ -static int -gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p, - fsmdef_media_t *media, boolean offer, - boolean initial_offer, uint16 media_level) -{ - static const char fname[] = "gsmsdp_negotiate_codec"; - rtp_ptype pref_codec = RTP_NONE; - uint16_t i; - uint16_t j; - int *master_list_p = NULL; - int *slave_list_p = NULL; - DtmfOutOfBandTransport_t transport = DTMF_OUTOFBAND_NONE; - int avt_payload_type; - uint16_t num_remote_types; - uint16_t num_local_types; - uint16_t num_master_types; - uint16_t num_slave_types; - int remote_codecs[CC_MAX_MEDIA_TYPES]; - int remote_payload_types[CC_MAX_MEDIA_TYPES]; - int local_codecs[CC_MAX_MEDIA_TYPES]; - sdp_payload_ind_e pt_indicator; - uint32 ptime = 0; - uint32 maxptime = 0; - const char* attr_label; - uint16_t level; - boolean explicit_reject = FALSE; - boolean found_codec = FALSE; - int32_t num_match_payloads = 0; - int codec = RTP_NONE; - int remote_pt = RTP_NONE; - int32_t payload_types_count = 0; /* count for allocating right amout - of memory for media->payloads */ - int temp; - u16 a_inst; - vcm_payload_info_t *payload_info = NULL; - vcm_payload_info_t *previous_payload_info; - - if (!dcb_p || !sdp_p || !media) { - return (RTP_NONE); - } - - level = media_level; - attr_label = sdp_attr_get_simple_string(sdp_p->dest_sdp, - SDP_ATTR_LABEL, level, 0, 1); - - if (attr_label != NULL) { - if (strcmp(attr_label, MIX_NEAREND_STRING) == 0) { - dcb_p->session = WHISPER_COACHING; - } - } - /* - * Obtain list of payload types from the remote SDP - */ - num_remote_types = sdp_get_media_num_payload_types(sdp_p->dest_sdp, level); - - if (num_remote_types > CC_MAX_MEDIA_TYPES) { - num_remote_types = CC_MAX_MEDIA_TYPES; - } - - for (i = 0; i < num_remote_types; i++) { - temp = sdp_get_media_payload_type(sdp_p->dest_sdp, level, - (uint16_t) (i + 1), &pt_indicator); - remote_codecs[i] = GET_CODEC_TYPE(temp); - remote_payload_types[i] = GET_DYN_PAYLOAD_TYPE_VALUE(temp); - } - - /* - * Get all the codecs that the phone supports. - */ - if (media->type == SDP_MEDIA_AUDIO) { - num_local_types = sip_config_local_supported_codecs_get( - (rtp_ptype *)local_codecs, - CC_MAX_MEDIA_TYPES); - } else if (media->type == SDP_MEDIA_VIDEO) { - num_local_types = sip_config_video_supported_codecs_get( - (rtp_ptype *)local_codecs, CC_MAX_MEDIA_TYPES, offer); - } else { - GSM_DEBUG(DEB_L_C_F_PREFIX"unsupported media type %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - media->type); - return (RTP_NONE); - } - - /* - * Set the AVT payload type to whatever value the farend wants to use, - * but only if we have AVT turned on and the farend wants it - * or if we are configured to always send it - */ - config_get_value(CFGID_DTMF_OUTOFBAND, &transport, sizeof(transport)); - - /* - * Save AVT payload type for use by gsmsdp_compare_to_previous_sdp - */ - media->previous_sdp.avt_payload_type = media->avt_payload_type; - - switch (transport) { - case DTMF_OUTOFBAND_AVT: - avt_payload_type = gsmsdp_get_remote_avt_payload_type( - media->level, sdp_p->dest_sdp); - if (avt_payload_type > RTP_NONE) { - media->avt_payload_type = avt_payload_type; - } else { - media->avt_payload_type = RTP_NONE; - } - break; - - case DTMF_OUTOFBAND_AVT_ALWAYS: - avt_payload_type = gsmsdp_get_remote_avt_payload_type( - media->level, sdp_p->dest_sdp); - if (avt_payload_type > RTP_NONE) { - media->avt_payload_type = avt_payload_type; - } else { - /* - * If we are AVT_ALWAYS and the remote end is not using AVT, - * then send DTMF as out-of-band and use our configured - * payload type. - */ - config_get_value(CFGID_DTMF_AVT_PAYLOAD, - &media->avt_payload_type, - sizeof(media->avt_payload_type)); - - GSM_DEBUG(DEB_L_C_F_PREFIX"AVT_ALWAYS forcing out-of-band DTMF," - " payload_type = %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), - media->avt_payload_type); - } - break; - - case DTMF_OUTOFBAND_NONE: - default: - media->avt_payload_type = RTP_NONE; - break; - } - - /* - * Find a matching codec in our local list with the remote list. - * The local list was created with our preferred codec first in the list, - * so this will ensure that we will match the preferred codec with the - * remote list first, before matching other codecs. - */ - pref_codec = sip_config_preferred_codec(); - if (pref_codec != RTP_NONE) { - /* - * If a preferred codec was configured and the platform - * currently can do this codec, then it would be the - * first element of the local_codecs because of the - * logic in sip_config_local_supported_codec_get(). - */ - if (local_codecs[0] != pref_codec) { - /* - * preferred codec is configured but it is not avaible - * currently, treat it as there is no codec available. - */ - pref_codec = RTP_NONE; - } - } - - if (pref_codec == RTP_NONE) { - master_list_p = remote_codecs; - slave_list_p = local_codecs; - num_master_types = num_remote_types; - num_slave_types = num_local_types; - GSM_DEBUG(DEB_L_C_F_PREFIX"Remote Codec list is Master", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } else { - master_list_p = local_codecs; - slave_list_p = remote_codecs; - num_master_types = num_local_types; - num_slave_types = num_remote_types; - GSM_DEBUG(DEB_L_C_F_PREFIX"Local Codec list is Master", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - - /* - * Save payload information for use by gsmspd_compare_to_previous_sdp - */ - gsmsdp_copy_payloads_to_previous_sdp(media); - - /* - * Setup payload info structure list to store matched payload details - * in the SDP. - */ - media->num_payloads = 0; - if(num_master_types <= num_slave_types ) { - payload_types_count = num_master_types; - } else { - payload_types_count = num_slave_types; - } - - /* Remove any previously allocated lists */ - if (media->payloads) { - cpr_free(media->payloads); - } - - /* Allocate memory for PT value, local PT and remote PT. */ - media->payloads = cpr_calloc(payload_types_count, - sizeof(vcm_payload_info_t)); - - /* Store the ptime and maxptime parameter for this m= section */ - if (media->type == SDP_MEDIA_AUDIO) { - ptime = sdp_attr_get_simple_u32(sdp_p->dest_sdp, - SDP_ATTR_PTIME, level, 0, 1); - if (ptime != 0) { - media->packetization_period = (uint16_t) ptime; - } - maxptime = sdp_attr_get_simple_u32(sdp_p->dest_sdp, - SDP_ATTR_MAXPTIME, level, 0, 1); - if (maxptime != 0) { - media->max_packetization_period = (uint16_t) maxptime; - } - } - - for (i = 0; i < num_master_types; i++) { - for (j = 0; j < num_slave_types; j++) { - if (master_list_p[i] == slave_list_p[j]) { - - /* We've found a codec in common. Configure the coresponding - payload information structure */ - codec = slave_list_p[j]; - payload_info = &(media->payloads[media->num_payloads]); - - if (master_list_p == remote_codecs) { - remote_pt = remote_payload_types[i]; - } else { - remote_pt = remote_payload_types[j]; - } - - payload_info->codec_type = codec; - payload_info->local_rtp_pt = remote_pt; - payload_info->remote_rtp_pt = remote_pt; - - /* If the negotiated payload type in an answer is different from - what we sent in our offer, we set the local payload type to - our default (since that's what we put in our offer) */ - if (!offer) { - previous_payload_info = - gsmsdp_find_info_for_codec(codec, - media->previous_sdp.payloads, - media->previous_sdp.num_payloads, 0); - if ((previous_payload_info == NULL) || - (previous_payload_info->local_rtp_pt - != payload_info->local_rtp_pt)) { - payload_info->local_rtp_pt = codec; - } - } - - if (media->type == SDP_MEDIA_AUDIO) { - - if (sdp_attr_rtpmap_payload_valid(sdp_p->dest_sdp, level, 0, - &a_inst, remote_pt) ) { - /* Set the number of channels -- if omitted, - default is 1 */ - payload_info->audio.channels = - sdp_attr_get_rtpmap_num_chan(sdp_p->dest_sdp, - level, 0, a_inst); - if (payload_info->audio.channels == 0) { - payload_info->audio.channels = 1; - } - - /* Set frequency = clock rate. This is generally - correct. Codecs can override this assumption on a - case-by-case basis in the switch construct below. */ - payload_info->audio.frequency = - sdp_attr_get_rtpmap_clockrate(sdp_p->dest_sdp, - level, 0, a_inst); - } else { - GSM_DEBUG(DEB_L_C_F_PREFIX"Could not find rtpmap " - "entry for payload %d -- setting defaults\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - payload_info->audio.channels = 1; - /* See http://www.iana.org/assignments/rtp-parameters/ - rtp-parameters.xml */ - switch (codec) { - case STATIC_RTP_AVP_DVI4_16000_1: - codec = RTP_DVI4; - payload_info->audio.frequency = 16000; - break; - case STATIC_RTP_AVP_L16_44100_2: - codec = RTP_L16; - payload_info->audio.frequency = 44100; - payload_info->audio.channels = 2; - break; - case STATIC_RTP_AVP_L16_44100_1: - codec = RTP_L16; - payload_info->audio.frequency = 44100; - break; - case STATIC_RTP_AVP_DVI4_11025_1: - codec = RTP_DVI4; - payload_info->audio.frequency = 11025; - break; - case STATIC_RTP_AVP_DVI4_22050_1: - codec = RTP_DVI4; - payload_info->audio.frequency = 22050; - break; - default: - payload_info->audio.frequency = 8000; - } - } - - - switch (codec) { - case RTP_PCMA: - case RTP_PCMU: - /* 20 ms = 1/50th of a second */ - payload_info->audio.packet_size = - payload_info->audio.frequency / 50; - - payload_info->audio.bitrate = 8 * - payload_info->audio.frequency * - payload_info->audio.channels; - break; - - - case RTP_OPUS: - if (!sdp_attr_rtpmap_payload_valid(sdp_p->dest_sdp, - level, 0, &a_inst, remote_pt) || - (payload_info->audio.frequency - != RTPMAP_OPUS_CLOCKRATE) || - (payload_info->audio.channels != 2)) { - - /* Be conservative in what we accept: any - implementation that does not use a 48 kHz - clockrate or 2 channels is broken. */ - explicit_reject = TRUE; - continue; // keep looking - } - - /* ********************************************* */ - /* TODO !! FIXME !! XXX - * We can't support two-channel Opus until we merge - * in webrtc.org upstream, rev 3050 or later. See - http://code.google.com/p/webrtc/issues/detail?id=1013 - * for details. We also need to have proper - * handling of the sprop-stereo and stereo SDP - * values before we use stereo encoding/decoding. - * Details in Mozilla Bug 818618. - */ - payload_info->audio.channels = 1; - /* ********************************************* */ - - /* Store fmtp options */ - sdp_attr_get_fmtp_max_average_bitrate ( - sdp_p->dest_sdp, level, 0, 1, - &payload_info->opus.max_average_bitrate); - - payload_info->opus.maxcodedaudiobandwidth = - sdp_attr_get_fmtp_maxcodedaudiobandwidth( - sdp_p->dest_sdp, level, 0, 1); - - sdp_attr_get_fmtp_usedtx (sdp_p->dest_sdp, level, 0, - 1, &payload_info->opus.usedtx); - - sdp_attr_get_fmtp_stereo (sdp_p->dest_sdp, level, 0, - 1, &payload_info->opus.stereo); - - sdp_attr_get_fmtp_useinbandfec (sdp_p->dest_sdp, - level, 0, 1, &payload_info->opus.useinbandfec); - - sdp_attr_get_fmtp_cbr (sdp_p->dest_sdp, level, 0, 1, - &payload_info->opus.cbr); - - /* Copied from media/webrtc/trunk/src/modules/ - audio_coding/main/source/acm_codec_database.cc */ - payload_info->audio.frequency = 48000; - payload_info->audio.packet_size = 960; - payload_info->audio.bitrate = 16000; // Increase when we have higher capture rates - break; - - case RTP_ISAC: - /* TODO: Update these from proper SDP constructs */ - payload_info->audio.frequency = 16000; - payload_info->audio.packet_size = 480; - payload_info->audio.bitrate = 32000; - break; - - case RTP_G722: - /* RFC 3551 - - G722 is specified in ITU-T Recommendation G.722, "7 kHz audio-coding - within 64 kbit/s". The G.722 encoder produces a stream of octets, - each of which SHALL be octet-aligned in an RTP packet. The first bit - transmitted in the G.722 octet, which is the most significant bit of - the higher sub-band sample, SHALL correspond to the most significant - bit of the octet in the RTP packet. - - Even though the actual sampling rate for G.722 audio is 16,000 Hz, - the RTP clock rate for the G722 payload format is 8,000 Hz because - that value was erroneously assigned in RFC 1890 and must remain - unchanged for backward compatibility. The octet rate or sample-pair - rate is 8,000 Hz. - */ - payload_info->audio.frequency = 16000; - payload_info->audio.packet_size = 320; - payload_info->audio.bitrate = 64000; - break; - - case RTP_ILBC: - payload_info->ilbc.mode = - (uint16_t)sdp_attr_get_fmtp_mode_for_payload_type( - sdp_p->dest_sdp, level, 0, remote_pt); - - /* TODO -- These should be updated to reflect the - actual frequency */ - if (payload_info->ilbc.mode == SIPSDP_ILBC_MODE20) - { - payload_info->audio.packet_size = 160; - payload_info->audio.bitrate = 15200; - } - else /* mode = 30 */ - { - payload_info->audio.packet_size = 240; - payload_info->audio.bitrate = 13300; - } - break; - - default: - GSM_DEBUG(DEB_L_C_F_PREFIX"codec=%d not setting " - "codec parameters (not implemented)\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - payload_info->audio.packet_size = -1; - payload_info->audio.bitrate = -1; - MOZ_ASSERT(0); - } /* end switch */ - - - } else if (media->type == SDP_MEDIA_VIDEO) { - if ( media->video != NULL ) { - vcmFreeMediaPtr(media->video); - media->video = NULL; - } - - if (!vcmCheckAttribs(codec, sdp_p, level, remote_pt, - &media->video)) { - GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d ignored - " - "attribs not accepted\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - explicit_reject = TRUE; - continue; /* keep looking */ - } - - /* cache the negotiated profile_level and bandwidth */ - media->previous_sdp.tias_bw = media->tias_bw; - media->tias_bw = ccsdpGetBandwidthValue(sdp_p,level, 1); - if ( (attr_label = - ccsdpAttrGetFmtpProfileLevelId(sdp_p,level,0,1)) - != NULL ) { - media->previous_sdp.profile_level = - media->profile_level; - sscanf(attr_label,"%x", &media->profile_level); - } - - /* This should ultimately use RFC 6236 a=imageattr - if present */ - - payload_info->video.width = 0; - payload_info->video.height = 0; - - /* Set maximum frame size */ - payload_info->video.max_fs = 0; - sdp_attr_get_fmtp_max_fs(sdp_p->dest_sdp, level, 0, 1, - &payload_info->video.max_fs); - - /* Set maximum frame rate */ - payload_info->video.max_fr = 0; - sdp_attr_get_fmtp_max_fr(sdp_p->dest_sdp, level, 0, 1, - &payload_info->video.max_fr); - } /* end video */ - - GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - - - found_codec = TRUE; - - /* Incrementing this number serves as a "commit" for the - payload_info. If we bail out of the loop before this - happens, then the collected information is abandoned. */ - media->num_payloads++; - if(media->num_payloads >= payload_types_count) { - /* We maxed our allocated memory -- processing is done. */ - return codec; - } - - if(offer) { - /* If we are creating an answer, return after the first match. - TODO -- Eventually, we'll (probably) want to answer with - all the codecs we can receive. See bug 814227. */ - return codec; - } - } - } - } - - /* Return the most preferred codec */ - if(found_codec) { - return (media->payloads[0].codec_type); - } - - /* - * CSCsv84705 - we could not negotiate a common codec because - * the local list is empty. This condition could happen when - * using g729 in locally mixed conference in which another call - * to vcm_get_codec_list() would return 0 or no codec. So if - * this is a not an init offer, we should just go ahead and use - * the last negotiated codec if the remote list matches with - * currently used. - */ - if (!initial_offer && !explicit_reject) { - for (i = 0; i < num_remote_types; i++) { - if (media->num_payloads != 0 && media->payloads[0].codec_type == - remote_payload_types[i]) { - GSM_DEBUG(DEB_L_C_F_PREFIX"local codec list was empty codec= %d" - " local=%d remote =%d\n", DEB_L_C_F_PREFIX_ARGS(GSM, - dcb_p->line, dcb_p->call_id, fname), - media->payloads[0].codec_type, - media->payloads[0].local_rtp_pt, - media->payloads[0].remote_rtp_pt); - return (media->payloads[0].codec_type); - } - } - } - - return (RTP_NONE); -} - -/* - * gsmsdp_negotiate_datachannel_attribs - * - * dcb_p - a pointer to the current dcb - * sdp_p - the sdp we are analyzing - * media - the media info - * offer - Boolean indicating if the remote SDP came in an OFFER. - */ -static void -gsmsdp_negotiate_datachannel_attribs(fsmdef_dcb_t* dcb_p, cc_sdp_t* sdp_p, uint16_t level, - fsmdef_media_t* media, boolean offer) -{ - uint32 num_streams; - char *protocol; - - sdp_attr_get_sctpmap_streams (sdp_p->dest_sdp, level, 0, 1, &num_streams); - - media->datachannel_streams = num_streams; - - sdp_attr_get_sctpmap_protocol(sdp_p->dest_sdp, level, 0, 1, media->datachannel_protocol); - - media->remote_datachannel_port = sdp_get_media_sctp_port(sdp_p->dest_sdp, level); -} - -/* - * gsmsdp_add_unsupported_stream_to_local_sdp - * - * Description: - * - * Adds a rejected media line to the local SDP. If there is already a media line at - * the specified level, check to see if it matches the corresponding media line in the - * remote SDP. If it does not, remove the media line from the local SDP so that - * the corresponding remote SDP media line can be added. Note that port will be set - * to zero indicating the media line is rejected. - * - * Parameters: - * - * scp_p - Pointer to the local and remote SDP. - * level - The media line level being rejected. - */ -static void -gsmsdp_add_unsupported_stream_to_local_sdp (cc_sdp_t *sdp_p, - uint16_t level) -{ - static const char fname[] = "gsmsdp_add_unsupported_stream_to_local_sdp"; - uint32_t remote_pt; - sdp_payload_ind_e remote_pt_indicator; - cpr_ip_addr_t addr; - - if (sdp_p == NULL) { - GSM_ERR_MSG(GSM_F_PREFIX"sdp is null.", fname); - return; - } - - if (sdp_get_media_type(sdp_p->src_sdp, level) != SDP_MEDIA_INVALID) { - sdp_delete_media_line(sdp_p->src_sdp, level); - } - - if (sdp_p->dest_sdp == NULL) { - GSM_ERR_MSG(GSM_F_PREFIX"no remote SDP available", fname); - return; - } - - /* - * Insert media line at the specified level. - */ - if (sdp_insert_media_line(sdp_p->src_sdp, level) != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_F_PREFIX"failed to insert a media line", fname); - return; - } - - /* - * Set the attributes of the media line. Specify port = 0 to - * indicate media line is rejected. - */ - (void) sdp_set_media_type(sdp_p->src_sdp, level, - sdp_get_media_type(sdp_p->dest_sdp, level)); - (void) sdp_set_media_portnum(sdp_p->src_sdp, level, 0, 0); - (void) sdp_set_media_transport(sdp_p->src_sdp, level, - sdp_get_media_transport(sdp_p->dest_sdp, level)); - - remote_pt = sdp_get_media_payload_type(sdp_p->dest_sdp, level, 1, - &remote_pt_indicator); - /* - * Don't like having to cast the payload type but sdp_get_media_payload_type - * returns a uint32_t but sdp_add_media_payload_type takes a uint16_t payload type. - * This needs to be fixed in Rootbeer. - */ - (void) sdp_add_media_payload_type(sdp_p->src_sdp, level, - (uint16_t) remote_pt, - remote_pt_indicator); - /* - * The rejected media line needs to have "c=" line since - * we currently do not include the "c=" at the session level. - * The sdp parser in other end point such as the SDP parser - * in the CUCM and in the phone ensures that there - * is at least one "c=" line that can be used with each media - * line. Such the parser will flag unsupported media line without - * "c=" in that media line and at the session as error. - * - * The solution to have "c=" at the session level and - * omitting "c=" at the media level all together can also - * resolve this problem. Since the phone is also supporting - * ANAT group for IPV4/IPV6 offering therefore selecting - * session level and determining not to include "c=" line - * at the media level can become complex. For this reason, the - * unsupported media line will have "c=" with 0.0.0.0 address instead. - */ - gsmsdp_set_connection_address(sdp_p->src_sdp, level, "0.0.0.0"); -} - -/* - * gsmsdp_get_remote_media_address - * - * Description: - * - * Extract the remote address from the given sdp. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing thhe DCB whose media lines are - * being negotiated - * sdp_p - Pointer to the the remote SDP - * level - media line level. - * dest_addr - pointer to the cpr_ip_addr_t structure to return - * remote address. - * - * Returns: - * FALSE - fails. - * TRUE - success. - * - */ -static boolean -gsmsdp_get_remote_media_address (fsmdef_dcb_t *dcb_p, - cc_sdp_t * sdp_p, uint16_t level, - cpr_ip_addr_t *dest_addr) -{ - const char fname[] = "gsmsdp_get_remote_media_address"; - const char *addr_str = NULL; - int dns_err_code; - boolean stat; - - *dest_addr = ip_addr_invalid; - - stat = sdp_connection_valid(sdp_p->dest_sdp, level); - if (stat) { - addr_str = sdp_get_conn_address(sdp_p->dest_sdp, level); - } else { - /* Address not at the media level. Try the session level. */ - stat = sdp_connection_valid(sdp_p->dest_sdp, SDP_SESSION_LEVEL); - if (stat) { - addr_str = sdp_get_conn_address(sdp_p->dest_sdp, SDP_SESSION_LEVEL); - } - } - - if (stat && addr_str) { - /* Assume that this is dotted address */ - if (str2ip(addr_str, dest_addr) != 0) { - /* It could be Fully Qualify DN, need to add DNS look up here */ - dns_err_code = dnsGetHostByName(addr_str, dest_addr, 100, 1); - if (dns_err_code) { - *dest_addr = ip_addr_invalid; - stat = FALSE; - GSM_ERR_MSG(GSM_L_C_F_PREFIX"DNS remote address error %d" - " with media at %d\n", dcb_p->line, dcb_p->call_id, - fname, dns_err_code, level); - } - } - } else { - /* - * No address the media level or the session level. - */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"No remote address from SDP with at %d", - dcb_p->line, dcb_p->call_id, fname, level); - } - /* - * Convert the remote address to host address to be used. It was - * found out that without doing so, the softphone can crash when - * in attempt to setup remote address to transmit API of DSP - * implementation on win32. - */ - util_ntohl(dest_addr, dest_addr); - return (stat); -} - -/* Function gsmsdp_is_multicast_address - * - * Inputs: - IP Address - * - * Returns: YES if is multicast address, no if otherwise - * - * Purpose: This is a utility function that tests to see if the passed - * address is a multicast address. It does so by verifying that the - * address is between 225.0.0.0 and 239.255.255.255. - * - * Note: Addresses passed are not in network byte order. - * - * Note2: Addresses between 224.0.0.0 and 224.255.255.225 are also multicast - * addresses, but 224.0.0.0 to 224.0.0.255 are reserved and it is recommended - * to start at 225.0.0.0. We need to research to see if this is a reasonable - * restriction. - * - */ -int -gsmsdp_is_multicast_address (cpr_ip_addr_t theIpAddress) -{ - if (theIpAddress.type == CPR_IP_ADDR_IPV4) { - /* - * Address already in host format - */ - if ((theIpAddress.u.ip4 >= MULTICAST_START_ADDRESS) && - (theIpAddress.u.ip4 <= MULTICAST_END_ADDRESS)) { - return (TRUE); - } - } else { - //todo IPv6: Check IPv6 multicast address here. - - } - return (FALSE); -} - -/** - * - * The function assigns or associate the new media line in the - * offered SDP to an entry in the media capability table. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]sdp_p - pointer to cc_sdp_t that contains the retmote SDP. - * @param[in]level - uint16_t for media line level. - * - * @return Pointer to the fsmdef_media_t if successfully - * found the anat pair media line otherwise return NULL. - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (media not_eq NULL) - */ -static fsmdef_media_t* -gsmsdp_find_anat_media_line (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p, uint16_t level) -{ - fsmdef_media_t *anat_media = NULL; - u32 group_id_1, group_id_2; - u32 dst_mid, group_mid; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - uint16_t i; - - /* - * Get number of ANAT groupings at the session level for the media line - */ - (void) sdp_attr_num_instances(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - for (i = 1; i <= num_anat_lines; i++) { - - dst_mid = sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, level, 0, 1); - group_id_1 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 1); - group_id_2 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 2); - - if (dst_mid == group_id_1) { - GSMSDP_FOR_ALL_MEDIA(anat_media, dcb_p) { - group_mid = sdp_attr_get_simple_u32(sdp_p->src_sdp, - SDP_ATTR_MID, (uint16_t) group_id_2, 0, 1); - if (group_mid == group_id_2) { - /* found a match */ - return (anat_media); - } - } - } else if (dst_mid == group_id_2) { - GSMSDP_FOR_ALL_MEDIA(anat_media, dcb_p) { - group_mid = sdp_attr_get_simple_u32(sdp_p->src_sdp, - SDP_ATTR_MID, (uint16_t) group_id_1, 0, 1); - if (group_mid == group_id_1) { - /* found a match */ - return (anat_media); - } - } - } - } - return (anat_media); -} - -/** - * - * The function validates if all the anat groupings - * have the right number of ids and their media type - * is not the same - * - * @param[in]sdp_p - pointer to the cc_sdp_t. - * - * @return TRUE - anat validation passes - * FALSE - anat validation fails - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - */ -static boolean -gsmsdp_validate_anat (cc_sdp_t *sdp_p) -{ - u16 i, num_group_id; - u32 group_id_1, group_id_2; - sdp_media_e media_type_gid1, media_type_gid2; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - - /* - * Get number of ANAT groupings at the session level for the media line - */ - (void) sdp_attr_num_instances(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - for (i = 1; i <= num_anat_lines; i++) { - num_group_id = sdp_get_group_num_id (sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i); - if ((num_group_id <=0) || (num_group_id > 2)) { - /* This anat line has zero or more than two grouping, this is invalid */ - return (FALSE); - } else if (num_group_id == 2) { - /* Make sure that these anat groupings are not of same type */ - group_id_1 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 1); - group_id_2 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 2); - media_type_gid1 = sdp_get_media_type(sdp_p->dest_sdp, (u16) group_id_1); - media_type_gid2 = sdp_get_media_type(sdp_p->dest_sdp, (u16) group_id_2); - if (media_type_gid1 != media_type_gid2) { - /* Group id types do not match */ - return (FALSE); - } - if (group_id_1 != sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, (u16) group_id_1, 0, 1)) { - /* Group id does not match the mid at the corresponding line */ - return (FALSE); - } - if (group_id_2 != sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, (u16) group_id_2, 0, 1)) { - return (FALSE); - } - } - } - - return (TRUE); -} - -/** - * - * The function validates if all the destination - * Sdp m lines have mid values and if those mid values match - * the source Sdp mid values - * - * @param[in]sdp_p - pointer to the cc_sdp_t - * @param[in]level - uint16_t for media line level. - * - * @return TRUE - mid validation passes - * FALSE - mid validation fails - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - */ -static boolean -gsmsdp_validate_mid (cc_sdp_t *sdp_p, uint16_t level) -{ - int32 src_mid, dst_mid; - u16 i; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - - /* - * Get number of ANAT groupings at the session level for the media line - */ - (void) sdp_attr_num_instances(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - - if (num_anat_lines > 0) { - dst_mid = sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, level, 0, 1); - if (dst_mid == 0) { - return (FALSE); - } - if (sdp_get_group_attr(sdp_p->src_sdp, SDP_SESSION_LEVEL, 0, 1) == SDP_GROUP_ATTR_ANAT) { - src_mid = sdp_attr_get_simple_u32(sdp_p->src_sdp, SDP_ATTR_MID, level, 0, 1); - if (dst_mid != src_mid) { - return (FALSE); - } - } - - } - return (TRUE); -} - -/** - * - * The function negotiates the type of the media lines - * based on anat attributes and ipv4/ipv6 settinsg. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - pointer to the fsmdef_media_t - * - * @return TRUE - this media line can be kept - * FALSE - this media line can not be kept - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - */ -static boolean -gsmsdp_negotiate_addr_type (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_negotiate_addr_type"; - cpr_ip_type media_addr_type; - cpr_ip_mode_e ip_mode; - fsmdef_media_t *group_media; - - media_addr_type = media->dest_addr.type; - if ((media_addr_type != CPR_IP_ADDR_IPV4) && - (media_addr_type != CPR_IP_ADDR_IPV6)) { - /* Unknown/unsupported address type */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"address type is not IPv4 or IPv6", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - ip_mode = platform_get_ip_address_mode(); - /* - * find out whether this media line is part of an ANAT group or not. - */ - group_media = gsmsdp_find_anat_pair(dcb_p, media); - - /* - * It is possible that we have a media sink/source device that - * attached to the phone, then we only accept IPV4 for these device. - * - * The code below is using FSM_MEDIA_F_SUPPORT_SECURITY as indication - * whether this media line is mapped to the off board device or not. - * When we get a better API to find out then use the better API than - * checking the FSM_MEDIA_F_SUPPORT_SECURITY. - */ - if (!FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY)) { - if (media_addr_type != CPR_IP_ADDR_IPV4) { - /* off board device we do not allow other address type but IPV4 */ - GSM_DEBUG(DEB_L_C_F_PREFIX"offboard device does not support IPV6", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return (FALSE); - } - - /* - * P2: - * Need an API to get address from the off board device. For now, - * use our local address. - */ - if ((ip_mode == CPR_IP_MODE_DUAL) || (ip_mode == CPR_IP_MODE_IPV4)) { - if (group_media != NULL) { - /* - * this media line is part of ANAT group, keep the previous - * one negotiated media line. - */ - return (FALSE); - } - gsmsdp_get_local_source_v4_address(media); - return (TRUE); - } - /* phone is IPV6 only mode */ - return (FALSE); - } - - if (ip_mode == CPR_IP_MODE_DUAL) { - /* - * In dual mode, IPV6 is preferred address type. If there is an - * ANAT then select the media line that has IPV6 address. - */ - if (group_media == NULL) { - /* - * no pair media line found, this can be the first media - * line negotiate. Keep this media line for now. - */ - if (media_addr_type == CPR_IP_ADDR_IPV4) { - gsmsdp_get_local_source_v4_address(media); - } else { - gsmsdp_get_local_source_v6_address(media); - } - return (TRUE); - } - - /* - * Found a ANAT pair media structure that this media line - * is part of. - */ - if (media_addr_type == CPR_IP_ADDR_IPV4) { - /* - * This media line is IPV4, keep the other line that have - * been accepted before i.e. it shows up first therefore - * the other one has preference. - */ - return (FALSE); - } - - /* This media line is IPV6 */ - if (group_media->src_addr.type == CPR_IP_ADDR_IPV4) { - /* - * The previous media line part of ANAT group is IPV4. The - * phone policy is to select IPV6 for media stream. Remove - * the previous media line and keep this media line (IPV6). - */ - gsmsdp_add_unsupported_stream_to_local_sdp(dcb_p->sdp, - group_media->level); - gsmsdp_remove_media(dcb_p, group_media); - /* set this media line source address to IPV6 */ - gsmsdp_get_local_source_v6_address(media); - return (TRUE); - } - /* - * keep the previous one is also IPV6, remove this one i.e. - * the one found has higher preferecne although this is not - * a valid ANAT grouping. - */ - return (FALSE); - } - - /* - * The phone is not in dual mode, the address type must be from the media - * line must match the address type that the phone is supporting. - */ - if ((ip_mode == CPR_IP_MODE_IPV6) && - (media_addr_type == CPR_IP_ADDR_IPV4)) { - /* incompatible address type */ - return (FALSE); - } - if ((ip_mode == CPR_IP_MODE_IPV4) && - (media_addr_type == CPR_IP_ADDR_IPV6)) { - /* incompatible address type */ - return (FALSE); - } - - if (group_media != NULL) { - /* - * This meida line is part of an ANAT group, keep the previous - * media line and throw away this line. - */ - return (FALSE); - } - - /* - * We have a compatible address type, set the source address based on - * the address type from the remote media line. - */ - if (media_addr_type == CPR_IP_ADDR_IPV4) { - gsmsdp_get_local_source_v4_address(media); - } else { - gsmsdp_get_local_source_v6_address(media); - } - /* keep this media line */ - return (TRUE); -} - -/** - * - * The function finds the best media capability that matches the offer - * media line according to the media table specified. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]sdp_p - pointer to cc_sdp_t that contains the retmote SDP. - * @param[in]media - pointer to the fsmdef_media_t. - * @param[in]media_table - media table to use (global or session) - * - * @return cap_index - the best match for the offer - * - * @pre (dcb_p not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (media not_eq NULL) - */ -static uint8_t -gsmdsp_find_best_match_media_cap_index (fsmdef_dcb_t *dcb_p, - cc_sdp_t *sdp_p, - fsmdef_media_t *media, - media_table_e media_table) -{ - const cc_media_cap_t *media_cap; - uint8_t cap_index, candidate_cap_index; - boolean srtp_fallback; - sdp_direction_e remote_direction, support_direction; - sdp_transport_e remote_transport; - sdp_media_e media_type; - - remote_transport = sdp_get_media_transport(sdp_p->dest_sdp, media->level); - remote_direction = gsmsdp_get_remote_sdp_direction(dcb_p, media->level, - &media->dest_addr); - srtp_fallback = sip_regmgr_srtp_fallback_enabled(dcb_p->line); - media_type = media->type; - - - /* - * Select the best suitable media capability entry that - * match this media line. - * - * The following rules are used: - * - * 1) rule out entry that is invalid or not enabled or with - * different media type. - * 2) rule out entry that has been used by other existing - * media line. - * - * After the above rules applies look for the better match for - * direction support and security support. The platform should - * arrange the capability table in preference order with - * higher prefered entry placed at the lower index in the table. - */ - candidate_cap_index = CC_MAX_MEDIA_CAP; - for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP; cap_index++) { - /* Find the cap entry that has the same media type and enabled */ - if (media_table == MEDIA_TABLE_GLOBAL) { - media_cap = &g_media_table.cap[cap_index]; - } else { - media_cap = gsmsdp_get_media_cap_entry_by_index(cap_index,dcb_p); - } - if ((media_cap == NULL) || !media_cap->enabled || - (media_cap->type != media_type)) { - /* does not exist, not enabled or not the same type */ - continue; - } - - /* Check for already in used */ - if (gsmsdp_find_media_by_cap_index(dcb_p, cap_index) != NULL) { - /* this capability entry has been used */ - continue; - } - - /* - * Check for security support. The rules below attempts to - * use entry that support security unless there is no entry - * and the SRTP fallback is enabled. If the remote offer is not - * SRTP just ignore the supported security and proceed on i.e. - * any entry is ok. - */ - if (remote_transport == SDP_TRANSPORT_RTPSAVP) { - if (!media_cap->support_security && !srtp_fallback) { - /* - * this entry does not support security and SRTP fallback - * is not enabled. - */ - continue; - } - if (!media_cap->support_security) { - /* - * this entry is not support security but srtp fallback - * is enabled, it potentially can be used - */ - candidate_cap_index = cap_index; - } - } - - /* - * Check for suitable direction support. The rules for matching - * directions are not exact rules. Try to match the closely - * offer as much as possible. This is the best we know. We can - * not guess what the real capability of the offer may have or will - * change in the future (re-invite). - */ - support_direction = media_cap->support_direction; - if (remote_direction == SDP_DIRECTION_INACTIVE) { - if (support_direction != SDP_DIRECTION_SENDRECV) { - /* prefer send and receive for inactive */ - candidate_cap_index = cap_index; - } - } else if (remote_direction == SDP_DIRECTION_RECVONLY) { - if ((support_direction != SDP_DIRECTION_SENDRECV) && - (support_direction != SDP_DIRECTION_SENDONLY)) { - /* incompatible direction */ - continue; - } else if (support_direction != SDP_DIRECTION_SENDONLY) { - candidate_cap_index = cap_index; - } - } else if (remote_direction == SDP_DIRECTION_SENDONLY) { - if ((support_direction != SDP_DIRECTION_SENDRECV) && - (support_direction != SDP_DIRECTION_RECVONLY)) { - /* incompatible direction */ - continue; - } else if (support_direction != SDP_DIRECTION_RECVONLY) { - candidate_cap_index = cap_index; - } - } else if (remote_direction == SDP_DIRECTION_SENDRECV) { - if (support_direction != SDP_DIRECTION_SENDRECV) { - candidate_cap_index = cap_index; - } - } - - if (candidate_cap_index == cap_index) { - /* this entry is not exactly best match, try other ones */ - continue; - } - /* this is the first best match found, use it */ - break; - } - - if (cap_index == CC_MAX_MEDIA_CAP) { - if (candidate_cap_index != CC_MAX_MEDIA_CAP) { - /* We have a candidate entry to use */ - cap_index = candidate_cap_index; - } - } - - return cap_index; -} - -/** - * - * The function finds the best media capability that matches the offer - * media line. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]sdp_p - pointer to cc_sdp_t that contains the retmote SDP. - * @param[in]media - pointer to the fsmdef_media_t. - * - * @return TRUE - successful assigning a capability entry - * to the media line. - * FALSE - failed to assign a capability entry to the - * media line. - * - * @pre (dcb_p not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (media not_eq NULL) - */ -static boolean -gsmsdp_assign_cap_entry_to_incoming_media (fsmdef_dcb_t *dcb_p, - cc_sdp_t *sdp_p, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_assign_cap_entry_to_incoming_media"; - const cc_media_cap_t *media_cap; - uint8_t cap_index; - fsmdef_media_t *anat_media; - - /* - * Find an existing media line that this media line belongs to the - * same media group. If found, the same cap_index will be used. - */ - anat_media = gsmsdp_find_anat_media_line(dcb_p, sdp_p, media->level); - if (anat_media != NULL) { - media_cap = gsmsdp_get_media_cap_entry_by_index(anat_media->cap_index, dcb_p); - if (media_cap == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capability", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - gsmsdp_set_media_capability(media, media_cap); - /* found the existing media line in the same ANAT group */ - media->cap_index = anat_media->cap_index; - return (TRUE); - } - - - cap_index = gsmdsp_find_best_match_media_cap_index(dcb_p, - sdp_p, - media, - MEDIA_TABLE_SESSION); - - if (cap_index == CC_MAX_MEDIA_CAP) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"reached max streams supported or" - " no suitable media capability\n", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - - /* set the capabilities to the media and associate with it */ - media_cap = gsmsdp_get_media_cap_entry_by_index(cap_index,dcb_p); - if (media_cap == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media cap", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - gsmsdp_set_media_capability(media, media_cap); - - /* override the direction for special feature */ - gsmsdp_feature_overide_direction(dcb_p, media); - if (media->support_direction == SDP_DIRECTION_INACTIVE) { - GSM_DEBUG(DEB_L_C_F_PREFIX"feature overrides direction to inactive," - " no capability assigned\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return (FALSE); - } - - media->cap_index = cap_index; - GSM_DEBUG(DEB_L_C_F_PREFIX"assign media cap index %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), cap_index); - return (TRUE); -} - -/** - * - * The function handles negotiate adding of a media line. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media_type - media type. - * @param[in]level - media line. - * @param[in]remote_port - remote port - * @param[in]offer - boolean indicates offer or answer. - * - * @return pointer to fsmdef_media_t if media is successfully - * added or return NULL. - * - * @pre (dcb_p not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (remote_addr not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_negotiate_add_media_line (fsmdef_dcb_t *dcb_p, - sdp_media_e media_type, - uint16_t level, - uint16_t remote_port, - boolean offer) -{ - static const char fname[] = "gsmsdp_negotiate_add_media_line"; - fsmdef_media_t *media; - - if (remote_port == 0) { - /* - * This media line is new but marked as disbaled. - */ - return (NULL); - } - - if (!offer) { - /* - * This is not an offer, the remote end wants to add - * a new media line in the answer. - */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"remote trying add media in answer SDP", - dcb_p->line, dcb_p->call_id, fname); - return (NULL); - } - - /* - * Allocate a new raw media structure but not filling completely yet. - */ - media = gsmsdp_get_new_media(dcb_p, media_type, level); - if (media == NULL) { - /* unable to add another media */ - return (NULL); - } - - /* - * If this call is locally held, mark the media with local hold so - * that the negotiate direction will have the correct direction. - */ - if ((dcb_p->fcb->state == FSMDEF_S_HOLDING) || - (dcb_p->fcb->state == FSMDEF_S_HOLD_PENDING)) { - /* the call is locally held, set the local held status */ - FSM_SET_FLAGS(media->hold, FSM_HOLD_LCL); - } - return (media); -} - -/** - * - * The function handles negotiate remove of a media line. Note the - * removal of a media line does not actaully removed from the offer/answer - * SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - pointer to the fsmdef_media_t for the media entry - * to deactivate. - * @param[in]remote_port - remote port from the remote's SDP. - * @param[in]offer - boolean indicates offer or answer. - * - * @return TRUE - when line is inactive. - * FALSE - when line remains to be further processed. - * - * @pre (dcb not_eq NULL) and (media not_eq NULL) - */ -static boolean -gsmsdp_negotiate_remove_media_line (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - uint16_t remote_port, - boolean offer) -{ - static const char fname[] = "gsmsdp_negotiate_remove_media_line"; - - if (offer) { - /* This is an offer SDP from the remote */ - if (remote_port != 0) { - /* the remote quests media is not for removal */ - return (FALSE); - } - /* - * Remote wants to remove the media line or to keep the media line - * disabled. Fall through. - */ - } else { - /* This is an answer SDP from the remote */ - if ((media->src_port != 0) && (remote_port != 0)) { - /* the media line is not for removal */ - return (FALSE); - } - /* - * There are 3 possible causes: - * 1) our offered port is 0 and remote's port is 0 - * 2) our offered port is 0 and remote's port is not 0. - * 3) our offered port is not 0 and remote's port is 0. - * - * In any of these cases, the media line will not be used. - */ - if ((media->src_port == 0) && (remote_port != 0)) { - /* we offer media line removal but the remote does not comply */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"remote insists on keeping media line", - dcb_p->line, dcb_p->call_id, fname); - } - } - - /* - * This media line is to be removed. - */ - return (TRUE); -} - -/* - * Find a media line based on the media type. - */ -fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb_p, sdp_media_e media_type) { - - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches the media type - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == media_type) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/* - * gsmsdp_add_rtcp_fb - * - * Description: - * Adds a=rtcp-fb attributes to local SDP for supported video codecs - * - * Parameters: - * level - SDP media level (between 1 and the # of m-lines) - * sdp_p - pointer to local SDP - * codec - the codec type that the attributes should be added for - * types - a bitmask of rtcp-fb types to add, taken from - * sdp_rtcp_fb_bitmask_e - * - * returns - * CC_CAUSE_OK - success - * any other code - failure - */ -cc_causes_t -gsmsdp_add_rtcp_fb (int level, sdp_t *sdp_p, - rtp_ptype codec, unsigned int types) -{ - int num_pts; - int pt_codec; - sdp_payload_ind_e indicator; - - int pt_index; - unsigned int j; - num_pts = sdp_get_media_num_payload_types(sdp_p, level); - for (pt_index = 1; pt_index <= num_pts; pt_index++) { - pt_codec = sdp_get_media_payload_type (sdp_p, level, pt_index, - &indicator); - if (codec == RTP_NONE || (pt_codec & 0xFF) == codec) { - int pt = GET_DYN_PAYLOAD_TYPE_VALUE(pt_codec); - - /* Add requested a=rtcp-fb:nack attributes */ - for (j = 0; j < SDP_MAX_RTCP_FB_NACK; j++) { - if (types & sdp_rtcp_fb_nack_to_bitmap(j)) { - gsmsdp_set_rtcp_fb_nack_attribute(level, sdp_p, pt, j); - } - } - - /* Add requested a=rtcp-fb:ack attributes */ - for (j = 0; j < SDP_MAX_RTCP_FB_ACK; j++) { - if (types & sdp_rtcp_fb_ack_to_bitmap(j)) { - gsmsdp_set_rtcp_fb_nack_attribute(level, sdp_p, pt, j); - } - } - - /* Add requested a=rtcp-fb:ccm attributes */ - for (j = 0; j < SDP_MAX_RTCP_FB_CCM; j++) { - if (types & sdp_rtcp_fb_ccm_to_bitmap(j)) { - gsmsdp_set_rtcp_fb_ccm_attribute(level, sdp_p, pt, j); - } - } - - } - } - return CC_CAUSE_OK; -} - - -/* - * gsmsdp_negotiate_rtcp_fb - * - * Description: - * Negotiates a=rtcp-fb attributes to local SDP for supported video codecs - * - * Parameters: - * cc_sdp_p - local and remote SDP - * media - The media structure for the current level to be negotiated - * offer - True if the remote SDP is an offer - * - * returns - * CC_CAUSE_OK - success - * any other code - failure - */ -cc_causes_t -gsmsdp_negotiate_rtcp_fb (cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, - boolean offer) -{ - int level = media->level; - int pt_codec; - int remote_pt; - sdp_payload_ind_e indicator; - int pt_index, i; - sdp_rtcp_fb_nack_type_e nack_type; - sdp_rtcp_fb_ack_type_e ack_type; - sdp_rtcp_fb_ccm_type_e ccm_type; - uint32_t fb_types = 0; - - int num_pts = sdp_get_media_num_payload_types(cc_sdp_p->dest_sdp, level); - - /* - * Remove any previously negotiated rtcp-fb attributes from the - * local SDP - */ - sdp_result_e result = SDP_SUCCESS; - while (result == SDP_SUCCESS) { - result = sdp_delete_attr (cc_sdp_p->src_sdp, level, 0, - SDP_ATTR_RTCP_FB, 1); - } - - /* - * For each remote payload type, determine what feedback types are - * requested. - */ - for (pt_index = 1; pt_index <= num_pts; pt_index++) { - int pt_codec = sdp_get_media_payload_type (cc_sdp_p->dest_sdp, - level, pt_index, &indicator); - int codec = pt_codec & 0xFF; - remote_pt = GET_DYN_PAYLOAD_TYPE_VALUE(pt_codec); - fb_types = 0; - - /* a=rtcp-fb:nack */ - i = 1; - do { - nack_type = sdp_attr_get_rtcp_fb_nack(cc_sdp_p->dest_sdp, - level, remote_pt, i); - if (nack_type >= 0 && nack_type < SDP_MAX_RTCP_FB_NACK) { - fb_types |= sdp_rtcp_fb_nack_to_bitmap(nack_type); - } - i++; - } while (nack_type != SDP_RTCP_FB_NACK_NOT_FOUND); - - /* a=rtcp-fb:ack */ - i = 1; - do { - ack_type = sdp_attr_get_rtcp_fb_ack(cc_sdp_p->dest_sdp, - level, remote_pt, i); - if (ack_type >= 0 && ack_type < SDP_MAX_RTCP_FB_ACK) { - fb_types |= sdp_rtcp_fb_ack_to_bitmap(ack_type); - } - i++; - } while (ack_type != SDP_RTCP_FB_ACK_NOT_FOUND); - - /* a=rtcp-fb:ccm */ - i = 1; - do { - ccm_type = sdp_attr_get_rtcp_fb_ccm(cc_sdp_p->dest_sdp, - level, remote_pt, i); - if (ccm_type >= 0 && ccm_type < SDP_MAX_RTCP_FB_CCM) { - fb_types |= sdp_rtcp_fb_ccm_to_bitmap(ccm_type); - } - i++; - } while (ccm_type != SDP_RTCP_FB_CCM_NOT_FOUND); - - /* - * Mask out the types that we do not support - */ - switch (codec) { - /* Really should be all video codecs... */ - case RTP_VP8: - case RTP_H263: - case RTP_H264_P0: - case RTP_H264_P1: - case RTP_I420: - fb_types &= - sdp_rtcp_fb_nack_to_bitmap(SDP_RTCP_FB_NACK_BASIC) | - sdp_rtcp_fb_nack_to_bitmap(SDP_RTCP_FB_NACK_PLI) | - sdp_rtcp_fb_ccm_to_bitmap(SDP_RTCP_FB_CCM_FIR); - break; - default: - fb_types = 0; - break; - } - - /* - * Now, in our local SDP, set rtcp-fb types that both we and the - * remote party support - */ - if (fb_types) { - gsmsdp_add_rtcp_fb (level, cc_sdp_p->src_sdp, codec, fb_types); - } - - /* - * Finally, update the media record for this payload type to - * reflect the expected feedback types - */ - for (i = 0; i < media->num_payloads; i++) { - if (media->payloads[i].remote_rtp_pt == remote_pt) { - media->payloads[i].video.rtcp_fb_types = fb_types; - } - } - } - return CC_CAUSE_OK; -} - -/* - * gsmsdp_negotiate_extmap - * - * Description: - * Negotiates extmaps header extension to local SDP for supported audio codecs - * - * Parameters: - * cc_sdp_p - local and remote SDP - * media - The media structure for the current level to be negotiated - * offer - True if the remote SDP is an offer - * - * returns - * CC_CAUSE_OK - success - * any other code - failure - */ -cc_causes_t -gsmsdp_negotiate_extmap (cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, - boolean offer) -{ - boolean audio_level = FALSE; - u16 audio_level_id = 0xFFFF; - int level = media->level; - int i; - const char* uri; - - /* - * Remove any previously negotiated extmap attributes from the - * local SDP - */ - sdp_result_e result = SDP_SUCCESS; - while (result == SDP_SUCCESS) { - result = sdp_delete_attr (cc_sdp_p->src_sdp, level, 0, - SDP_ATTR_EXTMAP, 1); - } - - i = 1; - do { - uri = sdp_attr_get_extmap_uri(cc_sdp_p->dest_sdp, level, i); - - if (uri != NULL && strcmp(uri, SDP_EXTMAP_AUDIO_LEVEL) == 0) { - audio_level = TRUE; - audio_level_id = sdp_attr_get_extmap_id(cc_sdp_p->dest_sdp, level, i); - } - i++; - } while (uri != NULL); - - media->audio_level = audio_level; - media->audio_level_id = audio_level_id; - - /* - * Now, in our local SDP, set extmap types that both we and the - * remote party support - */ - if (media->audio_level) { - gsmsdp_set_extmap_attribute (level, cc_sdp_p->src_sdp, audio_level_id, SDP_EXTMAP_AUDIO_LEVEL); - } - - return CC_CAUSE_OK; -} - -/* - * gsmsdp_negotiate_media_lines - * - * Description: - * - * Walk down the media lines provided in the remote sdp. Compare each - * media line to the corresponding media line in the local sdp. If - * the media line does not exist in the local sdp, add it. If the media - * line exists in the local sdp but is different from the remote sdp, - * change the local sdp to match the remote sdp. If the media line - * is an AUDIO format, negotiate the codec and update the local sdp - * as needed. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing thhe DCB whose media lines are being negotiated - * sdp_p - Pointer to the local and remote SDP - * initial_offer - Boolean indicating if the remote SDP came in the first OFFER of this session - * offer - Boolean indicating if the remote SDP came in an OFFER. - * notify_stream_added - Boolean indicating the UI should be notified of streams added - * create_answer - indicates whether the provided offer is supposed to generate - * an answer (versus simply setting the remote description) - * - * In practice, the initial_offer, offer, and create_answer flags only make - * sense in a limited number of configurations: - * - * Phase | i_o | offer | c_a - * ------------------------------+-------+-------+------- - * SetRemote (initial offer) | true | true | false - * SetRemote (reneg. offer) | false | true | false - * SetRemote (answer) | false | false | false - * CreateAnswer (initial) | true | true | true - * CreateAnswer (renegotitaion) | false | true | true - * - * TODO(adam@nostrum.com): These flags make the code very hard to read at - * the calling site. They should be replaced by an enumeration that - * contains only those five valid combinations described above. - */ -cc_causes_t -gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer, - boolean offer, boolean notify_stream_added, boolean create_answer) -{ - static const char fname[] = "gsmsdp_negotiate_media_lines"; - cc_causes_t cause = CC_CAUSE_OK; - uint16_t num_m_lines = 0; - uint16_t num_local_m_lines = 0; - uint16_t i = 0; - sdp_media_e media_type; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - uint16_t port; - boolean update_local_ret_value = TRUE; - sdp_transport_e transport; - uint16_t crypto_inst; - boolean media_found = FALSE; - cpr_ip_addr_t remote_addr; - boolean new_media; - sdp_direction_e video_avail = SDP_DIRECTION_INACTIVE; - boolean unsupported_line; - fsmdef_media_t *media; - uint8_t cap_index; - sdp_direction_e remote_direction; - boolean result; - int sdpmode = 0; - char *session_pwd; - cc_action_data_t data; - int j=0; - int rtcpmux = 0; - tinybool rtcp_mux = FALSE; - sdp_result_e sdp_res; - boolean created_media_stream = FALSE; - int lsm_rc; - int sctp_port; - u32 datachannel_streams; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - num_m_lines = sdp_get_num_media_lines(sdp_p->dest_sdp); - if (num_m_lines == 0) { - GSM_DEBUG(DEB_L_C_F_PREFIX"no media lines found.", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return CC_CAUSE_NO_MEDIA; - } - - /* - * Validate the anat values - */ - if (!gsmsdp_validate_anat(sdp_p)) { - /* Failed anat validation */ - GSM_DEBUG(DEB_L_C_F_PREFIX"failed anat validation", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return (CC_CAUSE_NO_MEDIA); - } - - /* - * Process each media line in the remote SDP - */ - for (i = 1; i <= num_m_lines; i++) { - unsupported_line = FALSE; /* assume line will be supported */ - new_media = FALSE; - media = NULL; - media_type = sdp_get_media_type(sdp_p->dest_sdp, i); - - /* - * Only perform these checks when called from createanswer - * because at this point we are concerned as to which m= lines - * have been created in the answer. - */ - if (create_answer) { - - /* Since the incoming SDP might not be in the same order as - our media, we find them by type rather than location - for this check. Note that we're not checking for the - value of any _particular_ m= section; we're just checking - whether (at least) one of the specified type exists. */ - media = gsmsdp_find_media_by_media_type(dcb_p, media_type); - - if (media_type == SDP_MEDIA_AUDIO && !media) { - /* continue if answer will not add this m= line */ - continue; - } - - if (media_type == SDP_MEDIA_VIDEO && !media) { - continue; - } - - if (media_type == SDP_MEDIA_APPLICATION && !media) { - continue; - } - } - - port = (uint16_t) sdp_get_media_portnum(sdp_p->dest_sdp, i); - GSM_DEBUG(DEB_L_C_F_PREFIX"Port is %d at %d %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - port, i, initial_offer); - - switch (media_type) { - case SDP_MEDIA_AUDIO: - case SDP_MEDIA_VIDEO: - case SDP_MEDIA_APPLICATION: - /* - * Get remote address before other negotiations process in case - * the address 0.0.0.0 (old style hold) to be used - * for direction negotiation. - */ - if (!gsmsdp_get_remote_media_address(dcb_p, sdp_p, i, - &remote_addr)) { - /* failed to get the remote address */ - GSM_DEBUG(DEB_L_C_F_PREFIX"unable to get remote addr at %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - unsupported_line = TRUE; - break; - } - - /* - * Find the corresponding media entry in the dcb to see - * this has been negiotiated previously (from the - * last offer/answer session). - */ - if(!create_answer) - media = gsmsdp_find_media_by_level(dcb_p, i); - - if (media == NULL) { - /* No previous media, negotiate adding new media line. */ - media = gsmsdp_negotiate_add_media_line(dcb_p, media_type, i, - port, offer); - if (media == NULL) { - /* new one can not be added */ - unsupported_line = TRUE; - break; - } - /* - * This media is a newly added, it is by itself an - * initial offer of this line. - */ - new_media = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"new media entry at %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - } else if (media->type == media_type) { - /* - * Use the remote port to determine whether the - * media line is to be removed from the SDP. - */ - if (gsmsdp_negotiate_remove_media_line(dcb_p, media, port, - offer)) { - /* the media line is to be removed from the SDP */ - unsupported_line = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"media at %d is removed", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - break; - } - } else { - /* The media at the same level but not the expected type */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"mismatch media type at %d", - dcb_p->line, dcb_p->call_id, fname, i); - unsupported_line = TRUE; - break; - } - - /* Do not negotiate if media is set to inactive */ - if (SDP_DIRECTION_INACTIVE == media->direction) { - break; - } - - /* Reset multicast flag and port */ - media->is_multicast = FALSE; - media->multicast_port = 0; - - /* Update remote address */ - media->previous_sdp.dest_addr = media->dest_addr; - media->dest_addr = remote_addr; - - /* - * Associate the new media (for adding new media line) to - * the capability table. - */ - if (media->cap_index == CC_MAX_MEDIA_CAP) { - if (!gsmsdp_assign_cap_entry_to_incoming_media(dcb_p, sdp_p, - media)) { - unsupported_line = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"unable to assign capability entry at %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - // Check if we need to update the UI that video has been offered - if ( offer && media_type == SDP_MEDIA_VIDEO && - ( ( g_media_table.cap[CC_VIDEO_1].support_direction != - SDP_DIRECTION_INACTIVE) ) ) { - // passed basic checks, now on to more expensive checks... - remote_direction = gsmsdp_get_remote_sdp_direction(dcb_p, - media->level, - &media->dest_addr); - cap_index = gsmdsp_find_best_match_media_cap_index(dcb_p, - sdp_p, - media, - MEDIA_TABLE_GLOBAL); - - GSM_DEBUG(DEB_L_C_F_PREFIX"remote_direction: %d global match %sfound", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - remote_direction, (cap_index != CC_MAX_MEDIA_CAP) ? "" : "not "); - if ( cap_index != CC_MAX_MEDIA_CAP && - remote_direction != SDP_DIRECTION_INACTIVE ) { - // this is an offer and platform can support video - GSM_DEBUG(DEB_L_C_F_PREFIX"\n\n\n\nUpdate video Offered Called %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), remote_direction); - lsm_update_video_offered(dcb_p->line, dcb_p->call_id, remote_direction); - } - } - break; - } - } - - /* - * Negotiate address type and take only address type - * that can be accepted. - */ - if (!gsmsdp_negotiate_addr_type(dcb_p, media)) { - unsupported_line = TRUE; - break; - } - - /* - * Negotiate RTP/SRTP. The result is the media transport - * which could be RTP/SRTP or fail. - */ - transport = gsmsdp_negotiate_media_transport(dcb_p, sdp_p, - offer, media, - &crypto_inst, i); - if (transport == SDP_TRANSPORT_INVALID) { - /* unable to negotiate transport */ - unsupported_line = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"transport mismatch at %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - break; - } - - /* Don't need to negotiate a codec for an m= applicaton line */ - if (SDP_MEDIA_APPLICATION != media_type) { - - /* - * Negotiate to a single codec - */ - if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer, i) == - RTP_NONE) { - /* unable to negotiate codec */ - unsupported_line = TRUE; - /* Failed codec negotiation */ - cause = CC_CAUSE_PAYLOAD_MISMATCH; - GSM_DEBUG(DEB_L_C_F_PREFIX"codec mismatch at %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - break; - } - } else { - gsmsdp_negotiate_datachannel_attribs(dcb_p, sdp_p, i, media, offer); - } - - /* - * Both media transport (RTP/SRTP) and codec are - * now negotiated to common ones, update transport - * parameters to be used for SRTP, if there is any. - */ - gsmsdp_update_negotiated_transport(dcb_p, sdp_p, media, - crypto_inst, transport, i); - GSM_DEBUG(DEB_F_PREFIX"local transport after updating negotiated: %d",DEB_F_PREFIX_ARGS(GSM, fname), sdp_get_media_transport(dcb_p->sdp->src_sdp, 1)); - /* - * Add to or update media line to the local SDP as needed. - */ - if (gsmsdp_is_multicast_address(media->dest_addr)) { - /* - * Multicast, if the address is multicast - * then change the local sdp and do the necessary - * call to set up reception of multicast packets - */ - GSM_DEBUG(DEB_L_C_F_PREFIX"Got multicast offer", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - media->is_multicast = TRUE; - media->multicast_port = port; - update_local_ret_value = - gsmsdp_update_local_sdp_for_multicast(dcb_p, port, - media, offer, - new_media); - } else { - update_local_ret_value = gsmsdp_update_local_sdp(dcb_p, - offer, - new_media, - media); - } - GSM_DEBUG(DEB_F_PREFIX"local transport after updateing local SDP: %d",DEB_F_PREFIX_ARGS(GSM, fname), sdp_get_media_transport(dcb_p->sdp->src_sdp, 1)); - - /* - * Successful codec negotiated cache direction for ui video update - */ - if (media_type == SDP_MEDIA_VIDEO ) { - video_avail = media->direction; - } - - if (update_local_ret_value == TRUE) { - media->previous_sdp.dest_port = media->dest_port; - media->dest_port = port; - if (media_type == SDP_MEDIA_AUDIO || sdpmode) { - /* at least found one workable audio media line */ - media_found = TRUE; - } - } else { - /* - * Rejecting multicast because direction is not RECVONLY - */ - unsupported_line = TRUE; - update_local_ret_value = TRUE; - } - /* Negotiate rtcp feedback mechanisms */ - if (media && media_type == SDP_MEDIA_VIDEO) { - gsmsdp_negotiate_rtcp_fb (dcb_p->sdp, media, offer); - } - /* Negotiate redundancy mechanisms */ - if (media && media_type == SDP_MEDIA_AUDIO) { - gsmsdp_negotiate_extmap (dcb_p->sdp, media, offer); - } - - /* - * Negotiate rtcp-mux - */ - if(SDP_MEDIA_APPLICATION != media_type) { - sdp_res = sdp_attr_get_rtcp_mux_attribute(sdp_p->dest_sdp, i, - 0, SDP_ATTR_RTCP_MUX, - 1, &rtcp_mux); - if (SDP_SUCCESS == sdp_res) { - media->rtcp_mux = TRUE; - } - } - - /* - Negotiate datachannel attributes. - We are using our port from config and reflecting the - number of streams from the other side. - */ - if (media_type == SDP_MEDIA_APPLICATION) { - config_get_value(CFGID_SCTP_PORT, &sctp_port, sizeof(sctp_port)); - media->local_datachannel_port = sctp_port; - - sdp_res = sdp_attr_get_sctpmap_streams(sdp_p->dest_sdp, - media->level, 0, 1, &datachannel_streams); - - /* If no streams value from the other side we will use our default - */ - if (sdp_res == SDP_SUCCESS) { - media->datachannel_streams = datachannel_streams; - } - - gsmsdp_set_sctp_attributes(sdp_p->src_sdp, i, media); - } - - if (!unsupported_line) { - - if (sdpmode) { - sdp_setup_type_e remote_setup_type; - int j; - - sdp_res = sdp_attr_get_setup_attribute( - sdp_p->dest_sdp, i, 0, 1, &remote_setup_type); - - /* - * Although a=setup is required for DTLS per RFC 5763, - * there are several implementations (including older - * versions of Firefox) that don't signal direction. - * To work with these cases, we assume that an omitted - * direction in SDP means "PASSIVE" in an offer, and - * "ACTIVE" in an answer. - */ - if (sdp_res != SDP_SUCCESS) { - remote_setup_type = - offer ? SDP_SETUP_PASSIVE : SDP_SETUP_ACTIVE; - } - - /* The DTLS role will be set based on the media->setup - value when the TransportFlow is created */ - switch (remote_setup_type) { - case SDP_SETUP_ACTIVE: - media->setup = SDP_SETUP_PASSIVE; - break; - case SDP_SETUP_PASSIVE: - media->setup = SDP_SETUP_ACTIVE; - break; - case SDP_SETUP_ACTPASS: - /* - * This should only happen in an offer. If the - * remote side is ACTPASS, we choose to be ACTIVE; - * this allows us to start setting up the DTLS - * association immediately, saving 1/2 RTT in - * association establishment. - */ - media->setup = SDP_SETUP_ACTIVE; - break; - case SDP_SETUP_HOLDCONN: - media->setup = SDP_SETUP_HOLDCONN; - media->direction = SDP_DIRECTION_INACTIVE; - break; - default: - /* - * If we don't recognize the remote endpoint's setup - * attribute, we fall back to being active if they - * sent an offer, and passive if they sent an answer. - */ - media->setup = - offer ? SDP_SETUP_ACTIVE : SDP_SETUP_PASSIVE; - } - - if (create_answer) { - gsmsdp_set_setup_attribute(media->level, - dcb_p->sdp->src_sdp, - media->setup); - } - - /* Set ICE */ - for (j=0; jcandidate_ct; j++) { - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, media->level, - sdp_p->src_sdp, media->candidatesp[j]); - } - - /* Set RTCPMux if we have it turned on in our config - and the other side requests it */ - config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux)); - if (rtcpmux && media->rtcp_mux) { - gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, media->level, - sdp_p->src_sdp, TRUE); - } - - if (notify_stream_added) { - /* - * Add track to remote streams in dcb - */ - if (SDP_MEDIA_APPLICATION != media_type && - /* Do not expect to receive media if we're sendonly! */ - (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_RECVONLY)) { - int pc_stream_id = -1; - - /* This is a hack to keep all the media in a single - stream. - TODO(ekr@rtfm.com): revisit when we have media - assigned to streams in the SDP */ - if (!created_media_stream){ - lsm_rc = lsm_add_remote_stream (dcb_p->line, - dcb_p->call_id, - media, - &pc_stream_id); - if (lsm_rc) { - return (CC_CAUSE_NO_MEDIA); - } else { - MOZ_ASSERT(pc_stream_id == 0); - /* Use index 0 because we only have one stream */ - result = gsmsdp_add_remote_stream(0, - pc_stream_id, - dcb_p); - MOZ_ASSERT(result); /* TODO(ekr@rtfm.com) - add real error checking, - but this "can't fail" */ - created_media_stream = TRUE; - } - } - - if (created_media_stream) { - /* Now add the track to the single media stream. - use index 0 because we only have one stream */ - result = gsmsdp_add_remote_track(0, i, dcb_p, media); - MOZ_ASSERT(result); /* TODO(ekr@rtfm.com) add real - error checking, but this - "can't fail" */ - } - } - } - } - } - - break; - - default: - /* Not a support media type stream */ - unsupported_line = TRUE; - break; - } - - if (unsupported_line) { - /* add this line to unsupported line */ - gsmsdp_add_unsupported_stream_to_local_sdp(sdp_p, i); - gsmsdp_set_mid_attr(sdp_p->src_sdp, i); - /* Remove the media if one to be removed */ - if (media != NULL) { - /* remove this media off the list */ - gsmsdp_remove_media(dcb_p, media); - } - } - if (!gsmsdp_validate_mid(sdp_p, i)) { - /* Failed mid validation */ - cause = CC_CAUSE_NO_MEDIA; - GSM_DEBUG(DEB_L_C_F_PREFIX"failed mid validation at %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - } - } - - /* - * Must have at least one media found and at least one audio - * line. - */ - if (!media_found) { - if (cause != CC_CAUSE_PAYLOAD_MISMATCH) { - cause = CC_CAUSE_NO_MEDIA; - } - } else { - if (cause == CC_CAUSE_PAYLOAD_MISMATCH) { - /* - * some media lines have codec mismatch but there are some - * that works, do not return error. - */ - cause = CC_CAUSE_OK; - } - - /* - * If we are processing an offer sdp, need to set the - * start time and stop time based on the remote SDP - */ - gsmsdp_update_local_time_stamp(dcb_p, offer, initial_offer); - - /* - * workable media line was found. Need to make sure we don't - * advertise more than workable media lines. Loop through - * remaining media lines in local SDP and set port to zero. - */ - num_local_m_lines = sdp_get_num_media_lines(sdp_p->src_sdp); - if (num_local_m_lines > num_m_lines) { - for (i = num_m_lines + 1; i <= num_local_m_lines; i++) { - (void) sdp_set_media_portnum(sdp_p->src_sdp, i, 0, 0); - } - } - - /* - * Update UI for Remote Stream Added - */ - if (sdpmode) { - - /* Fail negotiation if DTLS is not in SDP */ - cause = gsmsdp_configure_dtls_data_attributes(fcb_p); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG("gsmsdp_negotiate_media_lines- DTLS negotiation failed"); - return cause; - } - - /* ToDO(emannion) - * Fail negotiation if ICE is not negotiated. - */ - - /* - * Bubble the stream added event up to the PC UI - */ - if (notify_stream_added) { - for (j=0; j < CC_MAX_STREAMS; j++ ) { - if (dcb_p->remote_media_stream_tbl->streams[j]. - num_tracks && - (!dcb_p->remote_media_stream_tbl->streams[j]. - num_tracks_notified)) { - /* Note that we only notify when the number of tracks - changes from 0 -> !0 (i.e. on creation). - TODO(adam@nostrum.com): Figure out how to notify - when streams gain tracks */ - vcmOnRemoteStreamAdded( - CREATE_CALL_HANDLE(dcb_p->line, dcb_p->call_id), - dcb_p->peerconnection, - &dcb_p->remote_media_stream_tbl->streams[j]); - - dcb_p->remote_media_stream_tbl->streams[j].num_tracks_notified = - dcb_p->remote_media_stream_tbl->streams[j].num_tracks; - } - } - } - } - } - /* - * We have negotiated the line, clear flag that we have set - * that we are waiting for an answer SDP in ack. - */ - dcb_p->remote_sdp_in_ack = FALSE; - - /* - * check to see if UI needs to be updated for video - */ - GSM_DEBUG(DEB_L_C_F_PREFIX"Update video Avail Called %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname),video_avail); - - // update direction but preserve the cast attrib - dcb_p->cur_video_avail &= CC_ATTRIB_CAST; - dcb_p->cur_video_avail |= (uint8_t)video_avail; - - lsm_update_video_avail(dcb_p->line, dcb_p->call_id, dcb_p->cur_video_avail); - - return cause; -} - -/* - * This function returns boolean parameters indicating what media types - * exist in the offered SDP. - */ -cc_causes_t -gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, - boolean *has_video, boolean *has_data) -{ - cc_causes_t cause = CC_CAUSE_OK; - uint16_t num_m_lines = 0; - uint16_t i = 0; - sdp_media_e media_type; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - boolean result; - - num_m_lines = sdp_get_num_media_lines(sdp_p->dest_sdp); - if (num_m_lines == 0) { - GSM_DEBUG(DEB_L_C_F_PREFIX"no media lines found.", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, __FUNCTION__)); - return CC_CAUSE_NO_MEDIA; - } - - *has_audio = FALSE; - *has_video = FALSE; - *has_data = FALSE; - - /* - * Process each media line in the remote SDP - */ - for (i = 1; i <= num_m_lines; i++) { - media_type = sdp_get_media_type(sdp_p->dest_sdp, i); - - if(SDP_MEDIA_AUDIO == media_type) - *has_audio = TRUE; - else if(SDP_MEDIA_VIDEO == media_type) - *has_video = TRUE; - else if(SDP_MEDIA_APPLICATION == media_type) - *has_data = TRUE; - } - - return cause; -} - -/* - * gsmsdp_init_local_sdp - * - * Description: - * - * This function initializes the local sdp for generation of an offer sdp or - * an answer sdp. The following sdp values are initialized. - * - * v= line - * o= line
- * s= line - * t= line - * - * Parameters: - * - * peerconnection - handle to peerconnection object - * sdp_pp - Pointer to the local sdp - * - * returns cc_causes_t - * CC_CAUSE_OK - indicates success - * Any other code - indicates failure - */ -static cc_causes_t -gsmsdp_init_local_sdp (const char *peerconnection, cc_sdp_t **sdp_pp) -{ - char addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t ipaddr; - unsigned long session_id = 0; - char session_version_str[GSMSDP_VERSION_STR_LEN]; - void *local_sdp_p = NULL; - cc_sdp_t *sdp_p = NULL; - int nat_enable = 0; - char *p_addr_str; - cpr_ip_mode_e ip_mode; - char *strtok_state; - - if (!peerconnection) { - return CC_CAUSE_NO_PEERCONNECTION; - } - if (!sdp_pp) { - return CC_CAUSE_NULL_POINTER; - } - - ip_mode = platform_get_ip_address_mode(); - /* - * Get device address. We will need this later. - */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - if ((ip_mode == CPR_IP_MODE_DUAL) || (ip_mode == CPR_IP_MODE_IPV6)) { - sip_config_get_net_ipv6_device_ipaddr(&ipaddr); - } else if (ip_mode == CPR_IP_MODE_IPV4) { - sip_config_get_net_device_ipaddr(&ipaddr); - } - } else { - sip_config_get_nat_ipaddr(&ipaddr); - } - - - ipaddr2dotted(addr_str, &ipaddr); - - p_addr_str = PL_strtok_r(addr_str, "[ ]", &strtok_state); - - /* - * Create the local sdp struct - */ - if (*sdp_pp == NULL) { - sipsdp_src_dest_create(peerconnection, - CCSIP_SRC_SDP_BIT, sdp_pp); - } else { - sdp_p = *sdp_pp; - if (sdp_p->src_sdp != NULL) { - sipsdp_src_dest_free(CCSIP_SRC_SDP_BIT, sdp_pp); - } - sipsdp_src_dest_create(peerconnection, - CCSIP_SRC_SDP_BIT, sdp_pp); - } - sdp_p = *sdp_pp; - - if ( sdp_p == NULL ) - return CC_CAUSE_NO_SDP; - - local_sdp_p = sdp_p->src_sdp; - - /* - * v= line - */ - (void) sdp_set_version(local_sdp_p, SIPSDP_VERSION); - - /* - * o= line - *
- */ - (void) sdp_set_owner_username(local_sdp_p, SIPSDP_ORIGIN_USERNAME); - - session_id = abs(cpr_rand() % 28457); - snprintf(session_version_str, sizeof(session_version_str), "%d", - (int) session_id); - (void) sdp_set_owner_sessionid(local_sdp_p, session_version_str); - - snprintf(session_version_str, sizeof(session_version_str), "%d", 0); - (void) sdp_set_owner_version(local_sdp_p, session_version_str); - - (void) sdp_set_owner_network_type(local_sdp_p, SDP_NT_INTERNET); - - if ((ip_mode == CPR_IP_MODE_DUAL) || (ip_mode == CPR_IP_MODE_IPV6)) { - (void) sdp_set_owner_address_type(local_sdp_p, SDP_AT_IP6); - } else if (ip_mode == CPR_IP_MODE_IPV4) { - (void) sdp_set_owner_address_type(local_sdp_p, SDP_AT_IP4); - } - (void) sdp_set_owner_address(local_sdp_p, p_addr_str); - - /* - * s= line - */ - (void) sdp_set_session_name(local_sdp_p, SIPSDP_SESSION_NAME); - - /* - * t= line - * We init these to zero. If we are building an answer sdp, these will - * be reset from the offer sdp. - */ - (void) sdp_set_time_start(local_sdp_p, "0"); - (void) sdp_set_time_stop(local_sdp_p, "0"); - - return CC_CAUSE_OK; -} - -/** - * The function sets the capabilities from media capability to the - * media structure. - * - * @param[in]media - pointer to the fsmdef_media_t to be set with - * capabilites from the media_cap. - * @param[in]media_cap - media capability to be used with this new media - * line. - * - * @return None. - * - * @pre (media not_eq NULL) - * @pre (media_cap not_eq NULL) - */ -static void -gsmsdp_set_media_capability (fsmdef_media_t *media, - const cc_media_cap_t *media_cap) -{ - /* set default direction */ - media->direction = media_cap->support_direction; - media->support_direction = media_cap->support_direction; - if (media_cap->support_security) { - /* support security */ - FSM_SET_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY); - } -} - -/** - * The function adds a media line into the local SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media_cap - media capability to be used with this new media - * line. - * @param[in]cap_index - media capability entry index to associate with - * the media line. - * @param[in]level - media line order in the SDP so called level. - * @param[in]addr_type - cpr_ip_type for address of the media line to add. - * - * @return Pointer to the fsmdef_media_t if successfully - * add a new line otherwise return NULL. - * - * @pre (dcb_p not_eq NULL) - * @pre (media_cap not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap, - uint8_t cap_index, uint16_t level, - cpr_ip_type addr_type, boolean offer) -{ - static const char fname[] = "gsmsdp_add_media_line"; - cc_action_data_t data; - fsmdef_media_t *media = NULL; - int i=0; - int rtcpmux = 0; - int sctp_port = 0; - - switch (media_cap->type) { - case SDP_MEDIA_AUDIO: - case SDP_MEDIA_VIDEO: - case SDP_MEDIA_APPLICATION: - media = gsmsdp_get_new_media(dcb_p, media_cap->type, level); - if (media == NULL) { - /* should not happen */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media entry available", - dcb_p->line, dcb_p->call_id, fname); - return (NULL); - } - - /* set capabilities */ - gsmsdp_set_media_capability(media, media_cap); - - /* associate this media line to the capability entry */ - media->cap_index = cap_index; /* keep the media cap entry index */ - - /* override the direction for special feature */ - gsmsdp_feature_overide_direction(dcb_p, media); - if (media->support_direction == SDP_DIRECTION_INACTIVE) { - GSM_DEBUG(DEB_L_C_F_PREFIX"feature overrides direction to inactive" - " no media added\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - - /* - * For an answer, SDP_DIRECTION_INACTIVE will now add an m= - * line but it is disabled. - */ - if (!offer) { - media->src_port = 0; - } else { - gsmsdp_remove_media(dcb_p, media); - return (NULL); - } - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - /* - * Get the local RTP port. The src port will be set in the dcb - * within the call to cc_call_action(CC_ACTION_OPEN_RCV) - */ - data.open_rcv.is_multicast = FALSE; - data.open_rcv.listen_ip = ip_addr_invalid; - data.open_rcv.port = 0; - data.open_rcv.keep = FALSE; - /* - * Indicate type of media (audio/video etc) becase some for - * supporting video over vieo, the port is obtained from other - * entity. - */ - data.open_rcv.media_type = media->type; - data.open_rcv.media_refid = media->refid; - if (cc_call_action(dcb_p->call_id, dcb_p->line, - CC_ACTION_OPEN_RCV, - &data) != CC_RC_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed", - dcb_p->line, dcb_p->call_id, fname); - gsmsdp_remove_media(dcb_p, media); - return (NULL); - } - - /* allocate port successful, save the port */ - - media->src_port = data.open_rcv.port; - - if(media_cap->type == SDP_MEDIA_APPLICATION) { - config_get_value(CFGID_SCTP_PORT, &sctp_port, sizeof(sctp_port)); - media->local_datachannel_port = sctp_port; - } - - /* - * Setup the local source address. - */ - if (addr_type == CPR_IP_ADDR_IPV6) { - gsmsdp_get_local_source_v6_address(media); - } else if (addr_type == CPR_IP_ADDR_IPV4) { - gsmsdp_get_local_source_v4_address(media); - } else { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode", - dcb_p->line, dcb_p->call_id, fname); - gsmsdp_remove_media(dcb_p, media); - return (NULL); - } - - } - - /* - * Initialize the media transport for RTP or SRTP (or do not thing - * and leave to the gsmsdp_update_local_sdp_media to set default) - */ - gsmsdp_init_sdp_media_transport(dcb_p, dcb_p->sdp->src_sdp, media); - - - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, TRUE, media, - media->transport); - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - - gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction); - - /* Add supported rtcp-fb types */ - if (media_cap->type == SDP_MEDIA_VIDEO) { - gsmsdp_add_rtcp_fb (level, dcb_p->sdp->src_sdp, RTP_NONE, /* RTP_NONE == all */ - sdp_rtcp_fb_nack_to_bitmap(SDP_RTCP_FB_NACK_BASIC) | - sdp_rtcp_fb_nack_to_bitmap(SDP_RTCP_FB_NACK_PLI) | - sdp_rtcp_fb_ccm_to_bitmap(SDP_RTCP_FB_CCM_FIR)); - } - /* Add supported audio level rtp extension */ - if (media_cap->type == SDP_MEDIA_AUDIO) { - gsmsdp_set_extmap_attribute(level, dcb_p->sdp->src_sdp, 1, - SDP_EXTMAP_AUDIO_LEVEL); - } - - /* Add a=setup attribute */ - gsmsdp_set_setup_attribute(level, dcb_p->sdp->src_sdp, media->setup); - /* - * wait until here to set ICE candidates as SDP is now initialized - */ - for (i=0; icandidate_ct; i++) { - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]); - } - - config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux)); - if (SDP_MEDIA_APPLICATION != media_cap->type && rtcpmux) { - gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE); - } - - - /* - * Since we are initiating an initial offer and opening a - * receive port, store initial media settings. - */ - media->previous_sdp.avt_payload_type = media->avt_payload_type; - media->previous_sdp.direction = media->direction; - media->previous_sdp.packetization_period = media->packetization_period; - gsmsdp_copy_payloads_to_previous_sdp(media); - break; - } - - default: - /* Unsupported media type, not added */ - GSM_DEBUG(DEB_L_C_F_PREFIX"media type %d is not supported", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), media_cap->type); - break; - } - return (media); -} - -/* - * gsmsdp_create_local_sdp - * - * Description: - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * force_streams_enabled - temporarily generate SDP even when no - * streams are added - * - * returns cc_causes_t - * CC_CAUSE_OK - indicates success - * Any other code- indicates failure - */ -cc_causes_t -gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled, - boolean audio, boolean video, boolean data, boolean offer) -{ - static const char fname[] = "gsmsdp_create_local_sdp"; - uint16_t level; - const cc_media_cap_table_t *media_cap_tbl; - const cc_media_cap_t *media_cap; - cpr_ip_mode_e ip_mode; - uint8_t cap_index; - fsmdef_media_t *media; - boolean has_audio; - int sdpmode = 0; - boolean media_enabled; - cc_causes_t cause; - - cause = gsmsdp_init_local_sdp(dcb_p->peerconnection, &(dcb_p->sdp)); - if ( cause != CC_CAUSE_OK) { - return cause; - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - dcb_p->src_sdp_version = 0; - - media_cap_tbl = dcb_p->media_cap_tbl; - - if (media_cap_tbl == NULL) { - /* should not happen */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available", - dcb_p->line, dcb_p->call_id, fname); - return (CC_CAUSE_NO_MEDIA_CAPABILITY); - } - - media_cap = &media_cap_tbl->cap[0]; - level = 0; - for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP-1; cap_index++) { - - /* Build local m lines based on m lines that were in the offered SDP */ - media_enabled = TRUE; - if (FALSE == audio && SDP_MEDIA_AUDIO == media_cap->type) { - media_enabled = FALSE; - } else if (FALSE == video && SDP_MEDIA_VIDEO == media_cap->type) { - media_enabled = FALSE; - } else if (FALSE == data && SDP_MEDIA_APPLICATION == media_cap->type) { - media_enabled = FALSE; - } - - /* - * Add each enabled media line to the SDP - */ - if (media_enabled && ( media_cap->enabled || force_streams_enabled)) { - level = level + 1; /* next level */ - - /* Only audio and video use two ICE components */ - if (media_cap->type != SDP_MEDIA_AUDIO && - media_cap->type != SDP_MEDIA_VIDEO) { - vcmDisableRtcpComponent(dcb_p->peerconnection, level); - } - - ip_mode = platform_get_ip_address_mode(); - if (ip_mode >= CPR_IP_MODE_IPV6) { - if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level, CPR_IP_ADDR_IPV6, offer) - == NULL) { - /* fail to add a media line, go back one level */ - level = level - 1; - } - - if (ip_mode == CPR_IP_MODE_DUAL) { - level = level + 1; /* next level */ - if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level, CPR_IP_ADDR_IPV4, offer) == - NULL) { - /* fail to add a media line, go back one level */ - level = level - 1; - } - } - } else { - if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, level, - CPR_IP_ADDR_IPV4, offer) == NULL) { - /* fail to add a media line, go back one level */ - level = level - 1; - } - } - } - /* next capability */ - media_cap++; - } - - if (level == 0) { - /* - * Did not find media line for the SDP and we do not - * support SDP without any media line. - */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media line for SDP", - dcb_p->line, dcb_p->call_id, fname); - return (CC_CAUSE_NO_M_LINE); - } - - /* - * - * This is a suitable place to add ice ufrag and pwd to the SDP - */ - - if (dcb_p->ice_ufrag) - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_UFRAG, SDP_SESSION_LEVEL, dcb_p->sdp->src_sdp, dcb_p->ice_ufrag); - if (dcb_p->ice_pwd) - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_PWD, SDP_SESSION_LEVEL, dcb_p->sdp->src_sdp, dcb_p->ice_pwd); - - if(strlen(dcb_p->digest_alg) > 0) - gsmsdp_set_dtls_fingerprint_attribute (SDP_ATTR_DTLS_FINGERPRINT, SDP_SESSION_LEVEL, - dcb_p->sdp->src_sdp, dcb_p->digest_alg, dcb_p->digest); - - if (!sdpmode) { - - /* - * Ensure that there is at least one audio line. - */ - has_audio = FALSE; - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == SDP_MEDIA_AUDIO) { - has_audio = TRUE; /* found one audio line, done */ - break; - } - } - if (!has_audio) { - /* No audio, do not allow */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no audio media line for SDP", - dcb_p->line, dcb_p->call_id, fname); - return (CC_CAUSE_NO_AUDIO); - } - } - - return CC_CAUSE_OK; -} - -/** - * The function creates a SDP that contains phone's current - * capability for an option. - * - * @param[in/out]sdp_pp - pointer to a pointer to cc_sdp_t to return - * the created SDP. - * @return none. - * @pre (sdp_pp not_eq NULL) - */ -void -gsmsdp_create_options_sdp (cc_sdp_t ** sdp_pp) -{ - cc_sdp_t *sdp_p; - - /* This empty string represents to associated peerconnection object */ - if (gsmsdp_init_local_sdp("", sdp_pp) != CC_CAUSE_OK) { - return; - } - - sdp_p = *sdp_pp; - - /* - * Insert media line at level 1. - */ - if (sdp_insert_media_line(sdp_p->src_sdp, 1) != SDP_SUCCESS) { - // Error - return; - } - - (void) sdp_set_media_type(sdp_p->src_sdp, 1, SDP_MEDIA_AUDIO); - (void) sdp_set_media_portnum(sdp_p->src_sdp, 1, 0, 0); - gsmsdp_set_media_transport_for_option(sdp_p->src_sdp, 1); - - /* - * Add all supported media formats to the local sdp. - */ - gsmsdp_add_default_audio_formats_to_local_sdp(NULL, sdp_p, NULL); - - /* Add Video m line if video caps are enabled */ - if ( g_media_table.cap[CC_VIDEO_1].enabled == TRUE ) { - if (sdp_insert_media_line(sdp_p->src_sdp, 2) != SDP_SUCCESS) { - // Error - return; - } - - (void) sdp_set_media_type(sdp_p->src_sdp, 2, SDP_MEDIA_VIDEO); - (void) sdp_set_media_portnum(sdp_p->src_sdp, 2, 0, 0); - gsmsdp_set_media_transport_for_option(sdp_p->src_sdp, 2); - - gsmsdp_add_default_video_formats_to_local_sdp(NULL, sdp_p, NULL); - } -} - -/** - * The function checks and removes media capability for the media - * lines that is to be removed. - * - * @param[in]dcb_p - Pointer to DCB - * - * @return TRUE - if there is a media line removed. - * FALSE - if there is no media line to remove. - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_check_remove_local_sdp_media (fsmdef_dcb_t *dcb_p) -{ - static const char fname[] = "gsmsdp_check_remove_local_sdp_media"; - fsmdef_media_t *media, *media_to_remove; - const cc_media_cap_t *media_cap; - boolean removed = FALSE; - - media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - while (media) { - media_cap = gsmsdp_get_media_cap_entry_by_index(media->cap_index,dcb_p); - if (media_cap != NULL) { - /* found the corresponding capability of the media line */ - if (!media_cap->enabled) { - GSM_DEBUG(DEB_L_C_F_PREFIX"remove media at level %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), media->level); - /* set the media line to unused */ - gsmsdp_add_unsupported_stream_to_local_sdp(dcb_p->sdp, - media->level); - /* - * remember the media to remove and get the next media to - * work on before removing this media off the linked list. - */ - media_to_remove = media; - media = GSMSDP_NEXT_MEDIA_ENTRY(media); - - /* remove the media from the list */ - gsmsdp_remove_media(dcb_p, media_to_remove); - removed = TRUE; - continue; - } - } - media = GSMSDP_NEXT_MEDIA_ENTRY(media); - } - return (removed); -} - -/** - * The function checks and adds media capability for the media - * lines that is to be added. - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]hold - TRUE indicates the newly media line - * should have direction that indicates hold. - * - * @return TRUE - if there is a media line added. - * FALSE - if there is no media line to added. - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_check_add_local_sdp_media (fsmdef_dcb_t *dcb_p, boolean hold) -{ - static const char fname[] = "gsmsdp_check_add_local_sdp_media"; - fsmdef_media_t *media; - const cc_media_cap_t *media_cap; - uint8_t cap_index; - uint16_t num_m_lines, level_to_use; - void *src_sdp; - boolean need_mix = FALSE; - boolean added = FALSE; - cpr_ip_mode_e ip_mode; - cpr_ip_type ip_addr_type[2]; /* for 2 IP address types */ - uint16_t i, num_ip_addrs; - - if (fsmcnf_get_ccb_by_call_id(dcb_p->call_id) != NULL) { - /* - * This call is part of a local conference. The mixing - * support will be needed for additional media line. - * If platform does not have capability to support mixing - * of a particular media type for the local conference, either - * leg in the conference will not see addition media line - * added. - */ - need_mix = TRUE; - } - - /* - * Find new media entries to be added. - */ - src_sdp = dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL; - for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP; cap_index++) { - media_cap = gsmsdp_get_media_cap_entry_by_index(cap_index, dcb_p); - if (media_cap == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available", - dcb_p->line, dcb_p->call_id, fname); - continue; - } - if (!media_cap->enabled) { - /* this entry is disabled, skip it */ - continue; - } - media = gsmsdp_find_media_by_cap_index(dcb_p, cap_index); - if (media != NULL) { - /* this media entry exists, skip it */ - continue; - } - - /* - * This is a new entry the capability table to be added. - */ - if (CC_IS_AUDIO(cap_index) && need_mix) { - if (!gsmsdp_platform_addition_mix(dcb_p, media_cap->type)) { - /* platform can not support additional mixing of this type */ - GSM_DEBUG(DEB_L_C_F_PREFIX"no support addition mixing for %d " - "media type\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - media_cap->type); - continue; - } - } - - /* - * It depends on current address mode, if the mode is dual mode then - * we need to add 2 media lines. - */ - ip_mode = platform_get_ip_address_mode(); - switch (ip_mode) { - case CPR_IP_MODE_DUAL: - /* add both addresses, IPV6 line is first as it is prefered */ - num_ip_addrs = 2; - ip_addr_type[0] = CPR_IP_ADDR_IPV6; - ip_addr_type[1] = CPR_IP_ADDR_IPV4; - break; - case CPR_IP_MODE_IPV6: - /* add IPV6 address only */ - num_ip_addrs = 1; - ip_addr_type[0] = CPR_IP_ADDR_IPV6; - break; - default: - /* add IPV4 address only */ - num_ip_addrs = 1; - ip_addr_type[0] = CPR_IP_ADDR_IPV4; - break; - } - /* add media line or lines */ - for (i = 0; i < num_ip_addrs; i++) { - /* - * This is a new stream to add, find an unused media line - * in the SDP. Find the unused media line that has the same - * media type as the one to be added. The RFC-3264 allows reuse - * any unused slot in the SDP body but it was recomended to use - * the same type to increase the chance of interoperability by - * using the unuse slot that has the same media type. - */ - level_to_use = gsmsdp_find_unused_media_line_with_type(src_sdp, - media_cap->type); - if (level_to_use == 0) { - /* no empty slot is found, add a new line to the SDP */ - num_m_lines = sdp_get_num_media_lines(src_sdp); - level_to_use = num_m_lines + 1; - } - GSM_DEBUG(DEB_L_C_F_PREFIX"add media at level %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), level_to_use); - - /* add a new media */ - media = gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level_to_use, ip_addr_type[i], FALSE); - if (media != NULL) { - /* successfully add a new media line */ - if (hold) { - /* this new media needs to be sent out with hold */ - gsmsdp_set_local_hold_sdp(dcb_p, media); - } - added = TRUE; - } else { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Unable to add a new media", - dcb_p->line, dcb_p->call_id, fname); - } - } - } - return (added); -} - -/** - * The function checks support direction changes and updates the support - * direction of media lines. - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]no_sdp_update - TRUE indicates do not update SDP. - * - * @return TRUE - if there is a media line support direction - * changes. - * FALSE - if there is no media line that has - * support direction change. - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_check_direction_change_local_sdp_media (fsmdef_dcb_t *dcb_p, - boolean no_sdp_update) -{ - static const char fname[] = "gsmsdp_check_direction_change_local_sdp_media"; - fsmdef_media_t *media; - const cc_media_cap_t *media_cap; - boolean direction_change = FALSE; - sdp_direction_e save_supported_direction; - - media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - while (media) { - media_cap = gsmsdp_get_media_cap_entry_by_index(media->cap_index, dcb_p); - if (media_cap != NULL) { - if (media->support_direction != - media_cap->support_direction) { - /* - * There is a possibility that supported direction has - * been overrided due to some feature. Check to see - * the supported direction remains the same after override - * take place. If it is different then there is a direction - * change. - */ - save_supported_direction = media->support_direction; - media->support_direction = media_cap->support_direction; - gsmsdp_feature_overide_direction(dcb_p, media); - if (media->support_direction == save_supported_direction) { - /* nothing change after override */ - } else { - /* there is no override, this is a change */ - direction_change = TRUE; - } - if (direction_change) { - /* Support direction changed */ - GSM_DEBUG(DEB_L_C_F_PREFIX"change support direction at level %d" - " from %d to %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - media->level, media->support_direction, - media_cap->support_direction); - if (no_sdp_update) { - /* - * The caller does not want to update SDP. - */ - media->direction = media_cap->support_direction; - } else { - /* - * Need to update direction in the SDP. - * The direction in the media structure will - * be set by the gsmsdp_set_local_sdp_direction. - */ - gsmsdp_set_local_sdp_direction(dcb_p, media, - media->support_direction); - } - } - } - } - media = GSMSDP_NEXT_MEDIA_ENTRY(media); - } - return (direction_change); -} - -/** - * The function resets media specified takes the hold state into account - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]media - Media to be updated - * @param[in]hold - Set media line will be set to hold. - */ -static void gsmsdp_reset_media(fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, boolean hold){ - gsmsdp_reset_local_sdp_media(dcb_p, media, hold); - if (hold) { - gsmsdp_set_local_hold_sdp(dcb_p, media); - } else { - gsmsdp_set_local_resume_sdp(dcb_p, media); - } -} - -/** - * - * This functions checks if the media IP Address has changed - * - * Convert the configMedia IP String to Ip address format, - * check if it is valid and then compare to current media source - * address, if the address is valid and the media source and - * config media ip differ, then - * - * 1) Stop the media to close the socket - * 2) Set flag to true, to initiate re-invite - * 3) Update the media src addr - * 4) Update the c= line to reflect the new IP address source - * - * @param[in]dcb_p - Pointer to DCB - * @return TRUE - if IP changed - * FALSE - if no no IP changed - * - * @pre (dcb_p not_eq NULL) - */ -boolean -gsmsdp_media_ip_changed (fsmdef_dcb_t *dcb_p) -{ - static const char fname[] = "gsmsdp_media_ip_changed"; - boolean ip_changed = FALSE; - cpr_ip_addr_t addr ; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - char addr_str[MAX_IPADDR_STR_LEN]; - fsmdef_media_t *media; - - /* - * Check if media IP has changed - */ - init_empty_str(curr_media_ip); - config_get_value(CFGID_MEDIA_IP_ADDR, curr_media_ip, - MAX_IPADDR_STR_LEN); - if (!is_empty_str(curr_media_ip)) { - str2ip(curr_media_ip, &addr); - util_ntohl(&addr, &addr); - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if ((util_check_if_ip_valid(&media->src_addr) == TRUE) && - (util_check_if_ip_valid(&addr) == TRUE) && - (util_compare_ip(&media->src_addr, &addr) == FALSE)) { - ipaddr2dotted(curr_media_ip, &media->src_addr); // for logging - - (void)cc_call_action(dcb_p->call_id, dcb_p->line, - CC_ACTION_STOP_MEDIA, - NULL); - ip_changed = TRUE; - media->src_addr = addr; - if (dcb_p->sdp != NULL) { - gsmsdp_set_connection_address(dcb_p->sdp->src_sdp, - media->level, - dcb_p->ice_default_candidate_addr); - } - ipaddr2dotted(addr_str, &media->src_addr); // for logging - GSM_ERR_MSG("%s MEDIA IP_CHANGED: after Update IP %s"\ - " before %s" ,fname, addr_str, curr_media_ip ); - } - } - } - - return (ip_changed); -} - -/** - * this function will check whether the media ip addres in local sdp is same as to - * media IP provided by application. If IP differs, then re-INVITE request is posted. - */ -boolean is_gsmsdp_media_ip_updated_to_latest( fsmdef_dcb_t * dcb ) { - cpr_ip_addr_t media_ip_in_host_order ; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - fsmdef_media_t *media; - - init_empty_str(curr_media_ip); - config_get_value(CFGID_MEDIA_IP_ADDR, curr_media_ip, MAX_IPADDR_STR_LEN); - if (is_empty_str(curr_media_ip) == FALSE) { - str2ip(curr_media_ip, &media_ip_in_host_order); - util_ntohl(&media_ip_in_host_order, &media_ip_in_host_order); - - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (util_check_if_ip_valid(&media->src_addr) == TRUE) { - if (util_compare_ip(&media->src_addr, &media_ip_in_host_order) == FALSE) { - return FALSE; - } - } - } - } - return TRUE; -} - - -/** - * - * The function checks for media capability changes and updates the - * local SDP for the changes. The function also provides a couple of options - * 1) reset the unchange media lines to initialize the codec list, - * crypto etc. and 2) an option to update media directions for all - * media lines for hold. 3) - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]reset - Reset the unchanged media lines to include all - * codecs etc. again. - * @param[in]hold - Set media line will be set to hold. - * - * @return TRUE - if media changes occur. - * FALSE - if no media change occur. - * - * @pre (dcb_p not_eq NULL) - */ -boolean -gsmsdp_update_local_sdp_media_capability (fsmdef_dcb_t *dcb_p, boolean reset, - boolean hold) -{ - static const char fname[] = "gsmsdp_update_local_sdp_media_capability"; - fsmdef_media_t *media; - boolean change_found = FALSE; - boolean check_for_change = FALSE; - - change_found = gsmsdp_media_ip_changed(dcb_p); - - /* - * check to see if media capability table has changed, by checking - * the ID. - */ - if ((g_media_table.id != dcb_p->media_cap_tbl->id) || reset) { - - /* - * capabilty table ID different or we are doing a reset for - * the full offer again, need to check for various changes. - * Update capabilities to match platform caps - */ - check_for_change = TRUE; - } - - /* - * Find any capability changes. The changes allowed are: - * 1) media entry is disabled (to be removed). - * 2) supported direction change. - * 3) new media entry is enabled (to be added) keep it the last one. - * - * Find a media to be removed first so that if there is another - * media line to add then there might be an unused a media line in the - * SDP to use. - */ - if (check_for_change && gsmsdp_check_remove_local_sdp_media(dcb_p)) { - /* there were some media lines removed */ - change_found = TRUE; - } - - /* - * Find media lines that may have direction changes - */ - if ( check_for_change && - gsmsdp_check_direction_change_local_sdp_media(dcb_p, reset)) { - /* there were media lines that directions changes */ - change_found = TRUE; - } - - /* - * Reset all the existing media lines to have full codec etc. - * again if the caller requested. - */ - if (reset) { - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - gsmsdp_reset_media(dcb_p, media, hold); - } - } - - /* - * Find new media entries to be added. - */ - if ( check_for_change && gsmsdp_check_add_local_sdp_media(dcb_p, hold)) { - change_found = TRUE; - } - - if (change_found) { - GSM_DEBUG(DEB_L_C_F_PREFIX"media capability change found", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - - - /* report back any changes made */ - return (change_found); -} - -/* - * gsmsdp_reset_local_sdp_media - * - * Description: - * - * This function initializes the media portion of the local sdp. The following - * lines are initialized. - * - * m= line - * a= session level line - * - * Parameters: - * - * dcb_p - Pointer to DCB whose local SDP media is to be initialized - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * If the value is NULL, it indicates all medie entries i the - * dcb is reset. - * hold - Boolean indicating if SDP is being initialized for sending hold - * - */ -void -gsmsdp_reset_local_sdp_media (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, - boolean hold) -{ - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - - /* - * Reset media transport in preparation for hold or resume. - * It is possible that transport media may - * change from the current media transport (for SRTP re-offer - * to a different end point). - */ - gsmsdp_reset_sdp_media_transport(dcb_p, dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL, - media, hold); - - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, TRUE, media, - media->transport); - - - /* - * a= line - * If hold is being signaled, do not alter the media direction. This - * will be taken care of by the state machine handler function. - */ - if (!hold) { - /* - * We are not locally held, set direction to the supported - * direction. - */ - gsmsdp_set_local_sdp_direction(dcb_p, media, - media->support_direction); - } - } -} - -/* - * gsmsdp_set_local_hold_sdp - * - * Description: - * - * Manipulates the local SDP of the specified DCB to indicate hold - * to the far end. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * media - Pointer to the fsmdef_media_t for the current media entry. - * If the value is NULL, it indicates all medie entries i the - * dcb is reset. - */ -void -gsmsdp_set_local_hold_sdp (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - int old_style_hold = 0; - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - /* - * Check if configuration indicates that the old style hold should be - * signaled per RFC 2543. That is, c=0.0.0.0. Although - * 2543 does not speak to the SDP direction attribute, we set - * the direction to INACTIVE to be consistent with the connection - * address setting. - */ - config_get_value(CFGID_2543_HOLD, &old_style_hold, - sizeof(old_style_hold)); - if (old_style_hold) { - gsmsdp_set_2543_hold_sdp(dcb_p, media->level); - gsmsdp_set_local_sdp_direction(dcb_p, media, - SDP_DIRECTION_INACTIVE); - } else { - /* - * RFC3264 states that hold is signaled by setting the media - * direction attribute to SENDONLY if in SENDRECV mode. - * INACTIVE if RECVONLY mode (mutual hold). - */ - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_SENDONLY) { - gsmsdp_set_local_sdp_direction(dcb_p, media, - SDP_DIRECTION_SENDONLY); - } else { - gsmsdp_set_local_sdp_direction(dcb_p, media, - SDP_DIRECTION_INACTIVE); - } - } - } -} - -/* - * gsmsdp_set_local_resume_sdp - * - * Description: - * - * Manipulates the local SDP of the specified DCB to indicate hold - * to the far end. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * media - Pointer to the fsmdef_media_t for the current media entry. - * - */ -void -gsmsdp_set_local_resume_sdp (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - /* - * We are not locally held, set direction to the supported - * direction. - */ - gsmsdp_set_local_sdp_direction(dcb_p, media, media->support_direction); - } -} - -/* - * gsmsdp_encode_sdp - * - * Description: - * The function encodes SDP from the internal SDP representation - * to the SDP body to be sent out. - * - * Parameters: - * sdp_p - pointer to the internal SDP info. block. - * msg_body - pointer to the msg body info. block. - * - * Returns: - * cc_causes_t to indicate failure or success. - */ -cc_causes_t -gsmsdp_encode_sdp (cc_sdp_t *sdp_p, cc_msgbody_info_t *msg_body) -{ - char *sdp_body; - cc_msgbody_t *part; - uint32_t body_length; - - if (!msg_body || !sdp_p) { - return CC_CAUSE_NULL_POINTER; - } - - /* Support single SDP encoding for now */ - sdp_body = sipsdp_write_to_buf(sdp_p->src_sdp, &body_length); - - if (sdp_body == NULL) { - return CC_CAUSE_SDP_ENCODE_FAILED; - } else if (body_length == 0) { - cpr_free(sdp_body); - return CC_CAUSE_SDP_ENCODE_FAILED; - } - - /* Clear off the bodies info */ - cc_initialize_msg_body_parts_info(msg_body); - - /* Set up for one SDP entry */ - msg_body->num_parts = 1; - msg_body->content_type = cc_content_type_SDP; - part = &msg_body->parts[0]; - part->body = sdp_body; - part->body_length = body_length; - part->content_type = cc_content_type_SDP; - part->content_disposition.required_handling = FALSE; - part->content_disposition.disposition = cc_disposition_session; - part->content_id = NULL; - return CC_CAUSE_OK; -} - -/* - * gsmsdp_encode_sdp_and_update_version - * - * Description: - * The function encodes SDP from the internal SDP representation - * to the SDP body to be sent out. It also post-increments the owner - * version number to prepare for the next SDP to be sent out. - * - * Parameters: - * sdp_p - pointer to DCB whose local SDP is to be encoded. - * msg_body - pointer to the msg body info. block. - * - * Returns: - * cc_causes_t to indicate failure or success. - */ -cc_causes_t -gsmsdp_encode_sdp_and_update_version (fsmdef_dcb_t *dcb_p, cc_msgbody_info_t *msg_body) -{ - char version_str[GSMSDP_VERSION_STR_LEN]; - cc_causes_t cause; - - snprintf(version_str, sizeof(version_str), "%d", dcb_p->src_sdp_version); - - if ( dcb_p->sdp == NULL || dcb_p->sdp->src_sdp == NULL ) { - cause = gsmsdp_init_local_sdp(dcb_p->peerconnection, &(dcb_p->sdp)); - if ( cause != CC_CAUSE_OK) { - return cause; - } - } - (void) sdp_set_owner_version(dcb_p->sdp->src_sdp, version_str); - - if (gsmsdp_encode_sdp(dcb_p->sdp, msg_body) != CC_CAUSE_OK) { - return CC_CAUSE_SDP_ENCODE_FAILED; - } - - dcb_p->src_sdp_version++; - return CC_CAUSE_OK; -} - -/* - * gsmsdp_get_sdp - * - * Description: - * The function searches the SDP from the the all of msg. body parts. - * All body parts having the content type SDP will be stored at the - * given destination arrays. The number of SDP body are returned to - * indicate the number of SDP bodies found. The function searches - * the msg body in backward to order to form SDP in the destination array - * to be from the highest to the lowest preferences. - * - * Parameters: - * msg_body - pointer to the incoming message body or cc_msgbody_info_t. - * part_array - pointer to pointer of cc_msgbody_t to store the - * sorted order of the incoming SDP. - * max_part - the maximum number of SDP can be written to the - * part_array or the part_array size. - * Returns: - * The number of SDP parts found. - */ -static uint32_t -gsmsdp_get_sdp_body (cc_msgbody_info_t *msg_body, - cc_msgbody_t **part_array, - uint32_t max_parts) -{ - uint32_t i, count; - cc_msgbody_t *part; - - if ((msg_body == NULL) || (msg_body->num_parts == 0)) { - /* No msg. body or no body parts in the msg. */ - return (0); - } - /* - * Extract backward. The SDP are sent from the lowest - * preference to the highest preference. The highest - * preference will be extracted first into the given array - * so that when we negotiate, the SDP we will attempt to - * negotiate from the remote's highest to the lowest - * preferences. - */ - count = 0; - part = &msg_body->parts[msg_body->num_parts - 1]; - for (i = 0; (i < msg_body->num_parts) && (i < max_parts); i++) { - if (part->content_type == cc_content_type_SDP) { - /* Found an SDP, keep the pointer to the part */ - *part_array = part; /* save pointer to SDP entry */ - part_array++; /* next entry */ - count++; - } - /* next one backward */ - part--; - } - /* return the number of SDP bodies found */ - return (count); -} - -/* - * gsmsdp_realloc_dest_sdp - * - * Description: - * The function re-allocates the internal SDP info. block for the - * remote or destination SDP. If there the SDP info. or the - * SDP block does not exist, the new one is allocated. If SDP block - * exists, the current one is released and is replaced by a new one. - * - * Parameters: - * dcb_p - pointer to fsmdef_dcb_t. - * - * Returns: - * cc_causes_t to indicate failure or success. - */ -static cc_causes_t -gsmsdp_realloc_dest_sdp (fsmdef_dcb_t *dcb_p) -{ - /* There are SDPs to process, prepare for parsing the SDP */ - if (dcb_p->sdp == NULL) { - /* Create internal SDP information block with dest sdp block */ - sipsdp_src_dest_create(dcb_p->peerconnection, - CCSIP_DEST_SDP_BIT, &dcb_p->sdp); - } else { - /* - * SDP info. block exists, remove the previously received - * remote or destination SDP and create a new one for - * the new SDP. - */ - if (dcb_p->sdp->dest_sdp) { - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT, &dcb_p->sdp); - } - sipsdp_src_dest_create(dcb_p->peerconnection, - CCSIP_DEST_SDP_BIT, &dcb_p->sdp); - } - - /* No SDP info block and parsed control block are available */ - if ((dcb_p->sdp == NULL) || (dcb_p->sdp->dest_sdp == NULL)) { - /* Unable to create internal SDP structure to parse SDP. */ - return CC_CAUSE_SDP_CREATE_FAILED; - } - return CC_CAUSE_OK; -} - -/* - * gsmsdp_negotiate_answer_sdp - * - * Description: - * - * Interface function used to negotiate an ANSWER SDP. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing the DCB whose local SDP is being negotiated. - * msg_body - Pointer to the cc_msgbody_info_t that contain the remote - * - */ -cc_causes_t -gsmsdp_negotiate_answer_sdp (fsm_fcb_t *fcb_p, cc_msgbody_info_t *msg_body) -{ - static const char fname[] = "gsmsdp_negotiate_answer_sdp"; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - cc_msgbody_t *sdp_bodies[CC_MAX_BODY_PARTS]; - uint32_t i, num_sdp_bodies; - cc_causes_t status; - char *sdp_body; - - /* Get just the SDP bodies */ - num_sdp_bodies = gsmsdp_get_sdp_body(msg_body, &sdp_bodies[0], - CC_MAX_BODY_PARTS); - GSM_DEBUG(DEB_F_PREFIX"",DEB_F_PREFIX_ARGS(GSM, fname)); - if (num_sdp_bodies == 0) { - /* - * Clear the call - we don't have any remote SDP info! - */ - return CC_CAUSE_NO_SDP; - } - - /* There are SDPs to process, prepare for parsing the SDP */ - status = gsmsdp_realloc_dest_sdp(dcb_p); - if (status != CC_CAUSE_OK) { - /* Unable to create internal SDP structure to parse SDP. */ - return status; - } - - /* - * Parse the SDP into internal structure, - * now just parse one - */ - status = CC_CAUSE_SDP_PARSE_FAILED; - for (i = 0; (i < num_sdp_bodies); i++) { - if ((sdp_bodies[i]->body != NULL) && (sdp_bodies[i]->body_length > 0)) { - /* Found a body */ - sdp_body = sdp_bodies[i]->body; - if (sdp_parse(dcb_p->sdp->dest_sdp, &sdp_body, - (uint16_t)sdp_bodies[i]->body_length) - == SDP_SUCCESS) { - status = CC_CAUSE_OK; - break; - } - } - } - if (status != CC_CAUSE_OK) { - /* Error parsing SDP */ - return status; - } - - gsmsdp_set_remote_sdp(dcb_p, dcb_p->sdp); - - status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE, TRUE); - GSM_DEBUG(DEB_F_PREFIX"returns with %d",DEB_F_PREFIX_ARGS(GSM, fname), status); - return (status); -} - - - - -/* - * gsmsdp_negotiate_offer_sdp - * - * Description: - * - * Interface function used to negotiate an OFFER SDP. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing the DCB whose local SDP is being negotiated. - * msg_body - Pointer to remote SDP body infostructure. - * init - Boolean indicating if the local SDP should be initialized as if this is the - * first local SDP of this session. - * - */ -cc_causes_t -gsmsdp_negotiate_offer_sdp (fsm_fcb_t *fcb_p, - cc_msgbody_info_t *msg_body, boolean init) -{ - cc_causes_t status; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - - status = gsmsdp_process_offer_sdp(fcb_p, msg_body, init); - if (status != CC_CAUSE_OK) - return status; - - /* - * If a new error code has been added to sdp processing please make sure - * the sip side is aware of it - */ - status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE, FALSE); - return (status); -} - - -/* - * gsmsdp_process_offer_sdp - * - * Description: - * - * Interface function used to process an OFFER SDP. - * Does not negotiate. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing the DCB whose local SDP is being negotiated. - * msg_body - Pointer to remote SDP body infostructure. - * init - Boolean indicating if the local SDP should be initialized as if this is the - * first local SDP of this session. - * - */ -cc_causes_t -gsmsdp_process_offer_sdp (fsm_fcb_t *fcb_p, - cc_msgbody_info_t *msg_body, boolean init) -{ - static const char fname[] = "gsmsdp_process_offer_sdp"; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - cc_causes_t status; - cc_msgbody_t *sdp_bodies[CC_MAX_BODY_PARTS]; - uint32_t i, num_sdp_bodies; - char *sdp_body; - - /* Get just the SDP bodies */ - num_sdp_bodies = gsmsdp_get_sdp_body(msg_body, &sdp_bodies[0], - CC_MAX_BODY_PARTS); - GSM_DEBUG(DEB_L_C_F_PREFIX"Init is %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), init); - if (num_sdp_bodies == 0) { - /* - * No remote SDP. So we will offer in our response and receive far end - * answer in the ack. Only need to create local sdp if this is first offer - * of a session. Otherwise, we will send what we have. - */ - if (init) { - status = gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, - TRUE, TRUE, TRUE); - if ( status != CC_CAUSE_OK) { - return status; - } - } else { - /* - * Reset all media entries that we have to offer all capabilities - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb_p, TRUE, FALSE); - } - dcb_p->remote_sdp_in_ack = TRUE; - return CC_CAUSE_OK; - } - - /* There are SDPs to process, prepare for parsing the SDP */ - status = gsmsdp_realloc_dest_sdp(dcb_p); - if (status != CC_CAUSE_OK) { - /* Unable to create internal SDP structure to parse SDP. */ - return status; - } - - /* - * Parse the SDP into internal structure, - * now just parse one - */ - status = CC_CAUSE_SDP_PARSE_FAILED; - for (i = 0; (i < num_sdp_bodies); i++) { - if ((sdp_bodies[i]->body != NULL) && (sdp_bodies[i]->body_length > 0)) { - /* Found a body */ - sdp_body = sdp_bodies[i]->body; - if (sdp_parse(dcb_p->sdp->dest_sdp, &sdp_body, - (uint16_t)sdp_bodies[i]->body_length) - == SDP_SUCCESS) { - status = CC_CAUSE_OK; - break; - } - } - } - if (status != CC_CAUSE_OK) { - /* Error parsing SDP */ - return status; - } - - if (init) { - (void)gsmsdp_init_local_sdp(dcb_p->peerconnection, &(dcb_p->sdp)); - /* Note that there should not a previous version here as well */ - } - - gsmsdp_set_remote_sdp(dcb_p, dcb_p->sdp); - - return (status); -} - - -/* - * gsmsdp_check_peer_ice_attributes_exist - * - * Read ICE parameters from the SDP and return failure - * if they are not complete. - * - * fcb_p - pointer to the fcb - * - */ -cc_causes_t -gsmsdp_check_ice_attributes_exist(fsm_fcb_t *fcb_p) { - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - sdp_result_e sdp_res; - char *ufrag; - char *pwd; - fsmdef_media_t *media; - boolean has_session_ufrag = FALSE; - boolean has_session_pwd = FALSE; - - /* Check for valid ICE parameters */ - sdp_res = sdp_attr_get_ice_attribute(dcb_p->sdp->dest_sdp, - SDP_SESSION_LEVEL, 0, SDP_ATTR_ICE_UFRAG, 1, &ufrag); - if (sdp_res == SDP_SUCCESS && ufrag) { - has_session_ufrag = TRUE; - } - - sdp_res = sdp_attr_get_ice_attribute(dcb_p->sdp->dest_sdp, - SDP_SESSION_LEVEL, 0, SDP_ATTR_ICE_PWD, 1, &pwd); - if (sdp_res == SDP_SUCCESS && pwd) { - has_session_pwd = TRUE; - } - - if (has_session_ufrag && has_session_pwd) { - /* Both exist at session level, success */ - return CC_CAUSE_OK; - } - - /* Incomplete ICE params at session level, check all media levels */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - - if (!has_session_ufrag) { - sdp_res = sdp_attr_get_ice_attribute(dcb_p->sdp->dest_sdp, - media->level, 0, SDP_ATTR_ICE_UFRAG, 1, &ufrag); - - if (sdp_res != SDP_SUCCESS || !ufrag) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"missing ICE ufrag parameter.", - dcb_p->line, dcb_p->call_id, __FUNCTION__); - return CC_CAUSE_MISSING_ICE_ATTRIBUTES; - } - } - - if (!has_session_pwd) { - sdp_res = sdp_attr_get_ice_attribute(dcb_p->sdp->dest_sdp, - media->level, 0, SDP_ATTR_ICE_PWD, 1, &pwd); - - if (sdp_res != SDP_SUCCESS || !pwd) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"missing ICE pwd parameter.", - dcb_p->line, dcb_p->call_id, __FUNCTION__); - return CC_CAUSE_MISSING_ICE_ATTRIBUTES; - } - } - } - - return CC_CAUSE_OK; -} - -/* - * gsmsdp_install_peer_ice_attributes - * - * Read ICE parameters from the SDP and set them into - * the ice engine. Check SESSION_LEVEL first then each media line. - * - * fcb_p - pointer to the fcb - * - */ -cc_causes_t -gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p) -{ - char *ufrag; - char *pwd; - char **candidates; - int candidate_ct; - sdp_result_e sdp_res; - short vcm_res; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - cc_sdp_t *sdp_p = dcb_p->sdp; - fsmdef_media_t *media; - int level; - cc_causes_t result; - - /* Tolerate missing ufrag/pwd here at the session level - because it might be at the media level */ - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, - SDP_ATTR_ICE_UFRAG, 1, &ufrag); - if (sdp_res != SDP_SUCCESS) - ufrag = NULL; - - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, - SDP_ATTR_ICE_PWD, 1, &pwd); - if (sdp_res != SDP_SUCCESS) - pwd = NULL; - - /* ice-lite is a session level attribute only, RFC 5245 15.3 */ - dcb_p->peer_ice_lite = sdp_attr_is_present(sdp_p->dest_sdp, - SDP_ATTR_ICE_LITE, SDP_SESSION_LEVEL, 0); - - if ((ufrag && pwd) || dcb_p->peer_ice_lite) { - vcm_res = vcmSetIceSessionParams(dcb_p->peerconnection, ufrag, pwd, - dcb_p->peer_ice_lite); - if (vcm_res) - return (CC_CAUSE_SETTING_ICE_SESSION_PARAMETERS_FAILED); - } - - /* Now process all the media lines */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) - continue; - - /* If we are muxing, disable the second - component of the ICE stream */ - if (media->rtcp_mux) { - vcm_res = vcmDisableRtcpComponent(dcb_p->peerconnection, - media->level); - - if (vcm_res) { - return (CC_CAUSE_SETTING_ICE_SESSION_PARAMETERS_FAILED); - } - } - - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, media->level, 0, - SDP_ATTR_ICE_UFRAG, 1, &ufrag); - if (sdp_res != SDP_SUCCESS) - ufrag = NULL; - - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, media->level, 0, - SDP_ATTR_ICE_PWD, 1, &pwd); - if (sdp_res != SDP_SUCCESS) - pwd = NULL; - - candidate_ct = 0; - candidates = NULL; - result = gsmsdp_get_ice_attributes (SDP_ATTR_ICE_CANDIDATE, media->level, sdp_p->dest_sdp, - &candidates, &candidate_ct); - if(result != CC_CAUSE_OK) - return (result); - - /* Set ICE parameters into ICE engine */ - - vcm_res = vcmSetIceMediaParams(dcb_p->peerconnection, media->level, ufrag, pwd, - candidates, candidate_ct); - - /* Clean up */ - if(candidates) { - int i; - - for (i=0; idcb; - cc_sdp_t *sdp_p = dcb_p->sdp; - fsmdef_media_t *media; - int level = SDP_SESSION_LEVEL; - short result; - char *token; - char line_to_split[FSMDEF_MAX_DIGEST_ALG_LEN + FSMDEF_MAX_DIGEST_LEN + 2]; - char *delim = " "; - char digest_alg[FSMDEF_MAX_DIGEST_ALG_LEN]; - char digest[FSMDEF_MAX_DIGEST_LEN]; - char *strtok_state; - cc_causes_t cause = CC_CAUSE_OK; - - /* First check for session level algorithm and key */ - sdp_session_res = sdp_attr_get_dtls_fingerprint_attribute (sdp_p->dest_sdp, SDP_SESSION_LEVEL, - 0, SDP_ATTR_DTLS_FINGERPRINT, 1, &session_fingerprint); - - /* Now process all the media lines */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) - continue; - - /* check for media level algorithm and key */ - sdp_res = sdp_attr_get_dtls_fingerprint_attribute (sdp_p->dest_sdp, media->level, - 0, SDP_ATTR_DTLS_FINGERPRINT, 1, &fingerprint); - - if (SDP_SUCCESS == sdp_res ) { - if (strlen(fingerprint) >= sizeof(line_to_split)) - return CC_CAUSE_DTLS_FINGERPRINT_TOO_LONG; - sstrncpy(line_to_split, fingerprint, sizeof(line_to_split)); - } else if (SDP_SUCCESS == sdp_session_res) { - if (strlen(session_fingerprint) >= sizeof(line_to_split)) - return CC_CAUSE_DTLS_FINGERPRINT_TOO_LONG; - sstrncpy(line_to_split, session_fingerprint, sizeof(line_to_split)); - } else { - cause = CC_CAUSE_NO_DTLS_FINGERPRINT; - continue; - } - - if (SDP_SUCCESS == sdp_res || SDP_SUCCESS == sdp_session_res) { - if(!(token = PL_strtok_r(line_to_split, delim, &strtok_state))) - return CC_CAUSE_DTLS_FINGERPRINT_PARSE_ERROR; - - if (strlen(token) >= sizeof(digest_alg)) - return CC_CAUSE_DTLS_DIGEST_ALGORITHM_TOO_LONG; - - sstrncpy(digest_alg, token, sizeof(digest_alg)); - if(!(token = PL_strtok_r(NULL, delim, &strtok_state))) - return CC_CAUSE_DTLS_FINGERPRINT_PARSE_ERROR; - - if (strlen(token) >= sizeof(digest)) - return CC_CAUSE_DTLS_DIGEST_TOO_LONG; - - sstrncpy(digest, token, sizeof(digest)); - - if (strlen(digest_alg) >= sizeof(media->negotiated_crypto.algorithm)) - return CC_CAUSE_DTLS_DIGEST_ALGORITHM_TOO_LONG; - - sstrncpy(media->negotiated_crypto.algorithm, digest_alg, sizeof(media->negotiated_crypto.algorithm)); - if (strlen(media->negotiated_crypto.algorithm) == 0) { - return CC_CAUSE_DTLS_DIGEST_ALGORITHM_EMPTY; - } - - if (strlen(digest) >= sizeof(media->negotiated_crypto.digest)) - return CC_CAUSE_DTLS_DIGEST_TOO_LONG; - - sstrncpy(media->negotiated_crypto.digest, digest, sizeof(media->negotiated_crypto.digest)); - if (strlen(media->negotiated_crypto.digest) == 0) { - return CC_CAUSE_DTLS_DIGEST_EMPTY; - } - - /* Here we have DTLS data */ - cause = CC_CAUSE_OK; - - } else { - GSM_DEBUG(DEB_F_PREFIX"DTLS attribute error", - DEB_F_PREFIX_ARGS(GSM, __FUNCTION__)); - return CC_CAUSE_DTLS_ATTRIBUTE_ERROR; - } - } - - return cause; -} - -/* - * gsmsdp_free - * - * Description: - * The function frees SDP resources that were allocated during the - * course of the call. - * - * Parameters: - * dcb_p - pointer to fsmdef_dcb_t. - */ -void -gsmsdp_free (fsmdef_dcb_t *dcb_p) -{ - if (dcb_p != NULL) { - if (dcb_p->sdp != NULL) { - sipsdp_free(&dcb_p->sdp); - dcb_p->sdp = NULL; - } - - if (dcb_p->media_cap_tbl) { - cpr_free(dcb_p->media_cap_tbl); - dcb_p->media_cap_tbl = NULL; - } - - if (dcb_p->remote_media_stream_tbl) { - cpr_free(dcb_p->remote_media_stream_tbl); - dcb_p->remote_media_stream_tbl = NULL; - } - - if (dcb_p->local_media_track_tbl) { - cpr_free(dcb_p->local_media_track_tbl); - dcb_p->local_media_track_tbl = NULL; - } - } -} - -/* - * gsmsdp_sdp_differs_from_previous_sdp - * - * Description: - * - * Interface function used to compare newly received SDP to previously - * received SDP. Returns FALSE if attributes of interest are the same. - * Otherwise, returns TRUE. - * - * Parameters: - * - * rcv_only - If TRUE, check for receive port perspective. - * media - Pointer to the fsmdef_media_t for the current media entry. - */ -boolean -gsmsdp_sdp_differs_from_previous_sdp (boolean rcv_only, fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_sdp_differs_from_previous_sdp"; - char prev_addr_str[MAX_IPADDR_STR_LEN]; - char dest_addr_str[MAX_IPADDR_STR_LEN]; - int i; - - /* Consider attributes of interest for both directions */ - - if ((0 == media->num_payloads) || (0 == media->previous_sdp.num_payloads) || - (media->num_payloads != media->previous_sdp.num_payloads)){ - GSM_DEBUG(DEB_F_PREFIX"previous # payloads: %d new # payloads: %d", - DEB_F_PREFIX_ARGS(GSM, fname), - media->previous_sdp.num_payloads, media->num_payloads); - } - - if (media->previous_sdp.avt_payload_type != media->avt_payload_type){ - GSM_DEBUG(DEB_F_PREFIX"previous avt PT: %d new avt PT: %d", - DEB_F_PREFIX_ARGS(GSM, fname), - media->previous_sdp.avt_payload_type, - media->avt_payload_type); - return TRUE; - } - - for (i = 0; i < media->num_payloads; i++) { - if ((media->previous_sdp.payloads[i].remote_rtp_pt != - media->payloads[i].remote_rtp_pt) || - (media->previous_sdp.payloads[i].codec_type != - media->payloads[i].codec_type)){ - GSM_DEBUG(DEB_F_PREFIX"previous dynamic payload (PT) #%d: " - "%d; new dynamic payload: %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), i, - media->previous_sdp.payloads[i].remote_rtp_pt, - media->payloads[i].remote_rtp_pt); - GSM_DEBUG(DEB_F_PREFIX"previous codec #%d: %d; new codec: %d", - DEB_F_PREFIX_ARGS(GSM, fname), i, - media->previous_sdp.payloads[i].codec_type, - media->payloads[i].codec_type); - return TRUE; - } - } - - /* - * Consider attributes of interest for transmit directions. - * If previous dest port is 0 then this is the first time - * we received sdp for comparison. We treat this situation - * as if addr and port did not change. - */ - if ( (media->previous_sdp.dest_port != 0) && (rcv_only == FALSE)) { - if ((util_compare_ip(&(media->previous_sdp.dest_addr), - &(media->dest_addr)) == FALSE) || - (media->previous_sdp.dest_port != media->dest_port)) { - prev_addr_str[0] = '\0'; /* ensure valid string if convesion fails */ - dest_addr_str[0] = '\0'; - ipaddr2dotted(prev_addr_str, &media->previous_sdp.dest_addr); - ipaddr2dotted(dest_addr_str, &media->dest_addr); - GSM_DEBUG(DEB_F_PREFIX"previous address: %s new address: %s", - DEB_F_PREFIX_ARGS(GSM, fname), prev_addr_str, dest_addr_str); - GSM_DEBUG(DEB_F_PREFIX"previous port: %d new port: %d", - DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.dest_port, media->dest_port); - return TRUE; - } else if ( media->tias_bw != media->previous_sdp.tias_bw) { - GSM_DEBUG(DEB_F_PREFIX"previous bw: %d new bw: %d", - DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.tias_bw, media->tias_bw); - return TRUE; - } else if ( media->profile_level != media->previous_sdp.profile_level) { - GSM_DEBUG(DEB_F_PREFIX"previous prof_level: %X new prof_level: %X", - DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.profile_level, media->profile_level); - return TRUE; - } - } - - - /* Check crypto parameters if we are doing SRTP */ - if (gsmsdp_crypto_params_change(rcv_only, media)) { - return TRUE; - } - return FALSE; -} - - -/* - * gsmsdp_add_remote_stream - * - * Description: - * - * Add a media stream with no tracks to the dcb for the - * current session. - * - * Parameters: - * - * idx - Stream index - * pc_stream_id - stream id from vcm layer, will be set as stream id - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * - * returns TRUE for success and FALSE for failure - */ -static boolean gsmsdp_add_remote_stream(uint16_t idx, int pc_stream_id, fsmdef_dcb_t *dcb_p) { - PR_ASSERT(idx < CC_MAX_STREAMS); - if (idx >= CC_MAX_STREAMS) - return FALSE; - - PR_ASSERT(!dcb_p->remote_media_stream_tbl->streams[idx].created); - if (dcb_p->remote_media_stream_tbl->streams[idx].created) - return FALSE; - - dcb_p->remote_media_stream_tbl->streams[idx].media_stream_id = pc_stream_id; - dcb_p->remote_media_stream_tbl->streams[idx].created = TRUE; - - return TRUE; -} - - -/* - * gsmsdp_add_remote_track - * - * Description: - * - * Add a track to a media stream - * - * Parameters: - * - * idx - Stream index - * track - the track id - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * media - the media object to add. - * - * returns TRUE for success and FALSE for failure - */ -static boolean gsmsdp_add_remote_track(uint16_t idx, uint16_t track, - fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media) { - cc_media_remote_track_table_t *stream; - int vcm_ret; - - PR_ASSERT(idx < CC_MAX_STREAMS); - if (idx >= CC_MAX_STREAMS) - return FALSE; - - stream = &dcb_p->remote_media_stream_tbl->streams[idx]; - - PR_ASSERT(stream->created); - if (!stream->created) - return FALSE; - - PR_ASSERT(stream->num_tracks < (CC_MAX_TRACKS - 1)); - if (stream->num_tracks > (CC_MAX_TRACKS - 1)) - return FALSE; - - stream->track[stream->num_tracks].media_stream_track_id = track; - stream->track[stream->num_tracks].video = - (media->type == SDP_MEDIA_VIDEO) ? TRUE : FALSE; - - ++stream->num_tracks; - - if (media->type == SDP_MEDIA_VIDEO) { - vcm_ret = vcmAddRemoteStreamHint(dcb_p->peerconnection, idx, TRUE); - } else if (media->type == SDP_MEDIA_AUDIO) { - vcm_ret = vcmAddRemoteStreamHint(dcb_p->peerconnection, idx, FALSE); - } else { - // No other track types should be valid here - MOZ_ASSERT(FALSE); - // Not setting a hint for this track type will simply cause the - // onaddstream callback not to wait for the track to be ready. - vcm_ret = 0; - } - - if (vcm_ret) { - CSFLogError(logTag, "%s: vcmAddRemoteStreamHint returned error: %d", - __FUNCTION__, vcm_ret); - return FALSE; - } - - return TRUE; -} - -cc_causes_t -gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb_p, const char * mid, uint16_t *level) { - - fsmdef_media_t *media; - u32 mid_id; - char buf[5]; - - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) - continue; - - mid_id = sdp_attr_get_simple_u32(dcb_p->sdp->dest_sdp, SDP_ATTR_MID, media->level, 0, 1); - snprintf(buf, sizeof(buf), "%u", mid_id); - if (strcmp(mid, buf) == 0) { - *level = media->level; - return CC_CAUSE_OK; - } - } - return CC_CAUSE_VALUE_NOT_FOUND; -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c deleted file mode 100644 index f45b580238f..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c +++ /dev/null @@ -1,1914 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "cpr_types.h" -#include "cpr_rand.h" -#include "sdp.h" -#include "fsm.h" -#include "gsm_sdp.h" -#include "util_string.h" -#include "lsm.h" -#include "sip_interface_regmgr.h" -#include "plat_api.h" - -static const char *gsmsdp_crypto_suite_name[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] = -{ - "SDP_SRTP_UNKNOWN_CRYPTO_SUITE", - "SDP_SRTP_AES_CM_128_HMAC_SHA1_32", - "SDP_SRTP_AES_CM_128_HMAC_SHA1_80", - "SDP_SRTP_F8_128_HMAC_SHA1_80" -}; - -/* - * Cached random number pool. The size of the pool is for 10 key sets - * ahead. The number of cached keys are arbitrary picked to be large - * enough to sustain the number of basic calls. - */ -#define RAND_POOL_SIZE ((VCM_SRTP_MAX_KEY_SIZE+VCM_SRTP_MAX_SALT_SIZE)*10) -#define RAND_REQ_LIMIT 256 /* limit random number request */ -static unsigned char rand_pool[RAND_POOL_SIZE]; /* random number pool */ -static int rand_pool_bytes = 0; /* current numbers in rand pool */ - -/* - * Default key life time that phone supports, - * should be "2^48" but CCM does not support the value. Leave the - * life time to blank. - */ -#define GSMSDP_DEFALT_KEY_LIFETIME NULL - -/* Default algorithmID */ -#define GSMSDP_DEFAULT_ALGORITHM_ID VCM_AES_128_COUNTER - -/* - * Function: gsmsdp_cache_crypto_keys - * - * Parameters: - * N/A - * - * Description: - * The function fills the crypto graphically random number pool - * so that when SRTP key (and salt) is needed it is first obtained from - * cached pool during the call for a better response to the real time - * signalling event. - * - * Returns: - * N/A - */ -void -gsmsdp_cache_crypto_keys (void) -{ - int number_to_fill; - int accumulate_bytes; - int bytes; - - /* - * Only attempt to fill the cache when the pool needs to be - * filled and the phone is idle. - */ - if ((rand_pool_bytes == RAND_POOL_SIZE) || !lsm_is_phone_idle()) { - return; - } - - number_to_fill = RAND_POOL_SIZE - rand_pool_bytes; - accumulate_bytes = 0; - - while (accumulate_bytes < number_to_fill) { - bytes = number_to_fill - accumulate_bytes; - /* - * Limit the request the number bytes for each request to - * crypto graphic random number generator to prevent - * error. There is a maximum limit to per request. - */ - if (bytes > RAND_REQ_LIMIT) { - bytes = RAND_REQ_LIMIT; - } - - if (platGenerateCryptoRand(&rand_pool[accumulate_bytes], &bytes)) { - accumulate_bytes += bytes; - } else { - /* - * Failed to get the crypto random number, uses the - * cpr_rand(), to keep the call going. - */ - rand_pool[accumulate_bytes] = (uint8_t) (cpr_rand() & 0xff); - accumulate_bytes++; - } - } - rand_pool_bytes = RAND_POOL_SIZE; -} - -/* - * Function: gsmsdp_get_rand_from_cached_pool - * - * Parameters: - * dst_buf - pointer to the unsigned char for the buffer to - * store random number obtained from the cached pool. - * req_bytes - number of random number requested. - * - * Description: - * The function gets the random number from the cache pool. - * - * Returns: - * The number of random number obtained from the pool. - */ -static int -gsmsdp_get_rand_from_cached_pool (unsigned char *dst_buf, int req_bytes) -{ - int bytes; - - if (rand_pool_bytes == 0) { - /* the pool is empty */ - return 0; - } - - if (rand_pool_bytes >= req_bytes) { - /* There are enough bytes from the pool */ - bytes = req_bytes; - } else { - /* - * pool does not have enough random bytes, give whatever - * remains in the pool - */ - bytes = rand_pool_bytes; - } - - memcpy(dst_buf, &rand_pool[RAND_POOL_SIZE - rand_pool_bytes], bytes); - rand_pool_bytes -= bytes; - - /* Returns the actual number of bytes gotten from the pool */ - return (bytes); -} - -/* - * Function: gsmsdp_generate_key - * - * Description: - * The function generates key and salt for SRTP. - * - * Parameters: - * algorithmID - algorithm ID - * key - pointer to vcm_crypto_key_t to store key output. - * - * Returns: - * None - */ -static void -gsmsdp_generate_key (uint32_t algorithmID, vcm_crypto_key_t * key) -{ - int accumulate_len, len, total_bytes, bytes_from_cache; - uint8_t random[sizeof(key->key) + sizeof(key->salt)]; - uint8_t key_len, salt_len; - - if (algorithmID == VCM_AES_128_COUNTER) { - key_len = VCM_AES_128_COUNTER_KEY_SIZE; - salt_len = VCM_AES_128_COUNTER_SALT_SIZE; - } else { - /* Unsupported algorithm */ - key_len = VCM_SRTP_MAX_KEY_SIZE; - salt_len = VCM_SRTP_MAX_SALT_SIZE; - } - - /* - * Request random bytes one time for both key and salt to avoid - * the overhead of platGenerateCryptoRand(). - * - * The size of random byes should be based on the algorithmID - * used but since at this time only AES128 is used. - */ - accumulate_len = 0; - total_bytes = key_len + salt_len; - - while (accumulate_len < total_bytes) { - len = total_bytes - accumulate_len; - - /* Attempt to get random number from cached pool first */ - bytes_from_cache = - gsmsdp_get_rand_from_cached_pool(&random[accumulate_len], len); - if (bytes_from_cache) { - /* There are some random number from the cache */ - accumulate_len += bytes_from_cache; - } else { - /* - * The cached random number in the pool is empty. - * - * Attempt to get all of the random bytes in one request but - * if the number of random bytes is not enough then requesting - * until all bytes are accumulated. - */ - if (len > RAND_REQ_LIMIT) { - len = RAND_REQ_LIMIT; - } - if (platGenerateCryptoRand(&random[accumulate_len], &len)) { - accumulate_len += len; - } else { - /* - * Failed to get the crypto random number, uses the - * cpr_rand(), to keep the call going. - */ - random[accumulate_len] = (uint8_t) (cpr_rand() & 0xff); - accumulate_len++; - } - } - } - - /* - * Filled in key and salt from the random bytes generated. - */ - key->key_len = key_len; - memcpy(&key->key[0], &random[0], key->key_len); - - key->salt_len = salt_len; - memcpy(&key->salt[0], &random[key->key_len], key->salt_len); -} - -/* - * Function: gsmsdp_is_supported_crypto_suite - * - * Description: - * The function checks whether the given crypto suite from SDP - * is supported or not. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type to be checked - * - * Returns: - * TRUE - the crypto suite is supported. - * FALSE - the crypto suite is not supported. - */ -static boolean -gsmsdp_is_supported_crypto_suite (sdp_srtp_crypto_suite_t crypto_suite) -{ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - /* These are the supported crypto suites */ - return (TRUE); - default: - return (FALSE); - } -} - -/* - * Function: gsmsdp_is_valid_keysize - * - * Description: - * The function checks whether the given key size is valid. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type - * key_size - key size to check - * - * Returns: - * TRUE - the key size is valid - * FALSE - the key size is not valid - */ -static boolean -gsmsdp_is_valid_key_size (sdp_srtp_crypto_suite_t crypto_suite, - unsigned char key_size) -{ - /* - * Make sure the size fits the maximum key size currently supported. - * This to make sure that when a longer key size is added but - * the maximum key size is not updated. - */ - if (key_size > VCM_SRTP_MAX_KEY_SIZE) { - return (FALSE); - } - - /* Check key size against crypto suite */ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - if (key_size == VCM_AES_128_COUNTER_KEY_SIZE) { - return (TRUE); - } - break; - - default: - break; - } - return (FALSE); -} - -/* - * Function: gsmsdp_is_valid_salt_size - * - * Description: - * The function checks whether the given salt size is valid. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type - * salt_size - salt size to check - * - * Returns: - * TRUE - the salt size is valid - * FALSE - the salt size is not valid - */ -static boolean -gsmsdp_is_valid_salt_size (sdp_srtp_crypto_suite_t crypto_suite, - unsigned char salt_size) -{ - /* - * Make sure the size fits the maximum salt size currently supported. - * This to make sure that when a longer salt size is added but - * the maximum salt size is not updated. - */ - if (salt_size > VCM_SRTP_MAX_SALT_SIZE) { - return (FALSE); - } - - /* Check salt size against crypter suite */ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - if (salt_size == VCM_AES_128_COUNTER_SALT_SIZE) { - return (TRUE); - } - break; - - default: - break; - } - return (FALSE); -} - -/* - * Function: gsmdsp_cmp_key - * - * Description: - * The function compares 2 keys. - * - * Parameters: - * key1 - pointer to vcm_crypto_key_t - * key2 - pointer to vcm_crypto_key_t - * - * Returns: - * TRUE - the 2 keys are different - * FALSE - the 2 keys are the same - */ -static boolean -gsmdsp_cmp_key (vcm_crypto_key_t *key1, vcm_crypto_key_t *key2) -{ - if ((key1 == NULL) && (key2 != NULL)) { - /* No key 1 but has key 2 -> different */ - return (TRUE); - } - if ((key1 != NULL) && (key2 == NULL)) { - /* Has key 1 but no key 2 -> different */ - return (TRUE); - } - if ((key1 == NULL) && (key2 == NULL)) { - /* No key 1 and no key 2 -> same */ - return (FALSE); - } - /* - * At this point pointer to key1 and key2 should not be NULL. Compare - * the key content - */ - if ((key1->key_len != key2->key_len) || (key1->salt_len != key2->salt_len)) { - /* Key length or salt length are not the same */ - return (TRUE); - } - if (key1->key_len != 0) { - if (memcmp(key1->key, key2->key, key1->key_len)) { - return (TRUE); - } - } - if (key1->salt_len != 0) { - if (memcmp(key1->salt, key2->salt, key1->salt_len)) { - return (TRUE); - } - } - /* Both keys are the same */ - return (FALSE); -} - -/* - * Function: gsmsdp_is_supported_session_parm - * - * Description: - * The function checks to see whether the session parameters given - * is supported or not. - * - * Parameters: - * session_parms - pointer to string of session parameters - * - * Returns: - * TRUE - the session parameters are supported - * FALSE - the session parameters are not supported - */ -static boolean -gsmsdp_is_supported_session_parm (const char *session_parms) -{ - int len, wsh; - const char *parm_ptr; - long strtol_result; - char *strtol_end; - - if (session_parms == NULL) { - /* No session parameters, this is acceptable */ - return (TRUE); - } - /* - * Only WSH is allowed even though the phone does not support it. - * The session param string can only have "WSH=nn" or (size of 6). - */ - len = strlen(session_parms); - if (strcmp(session_parms, "WSH=") && (len == 6)) { - parm_ptr = &session_parms[sizeof("WSH=") - 1]; /* point the wsh value */ - - errno = 0; - strtol_result = strtol(parm_ptr, &strtol_end, 10); - - /* minimum value of WSH is 64 */ - if (errno || parm_ptr == strtol_end || strtol_result < 64 || strtol_result > INT_MAX) { - return FALSE; - } - - return TRUE; - } - /* Other parameters are not supported */ - return (FALSE); -} - -/* - * Function: gsmsdp_crypto_suite_to_algorithmID - * - * Description: - * The function converts the given crypto suite from SDP into - * internal enumeration suitable for using with SRTP lib. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type to converted into - * internal algorithm ID - * - * Returns: - * value VCM algorithmID - */ -static vcm_crypto_algorithmID -gsmsdp_crypto_suite_to_algorithmID (sdp_srtp_crypto_suite_t crypto_suite) -{ - /* Convert the supported crypto suite into the algorithm ID */ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - return (VCM_AES_128_COUNTER); - default: - return (VCM_INVLID_ALGORITM_ID); - } -} - -/* - * Function: gsmsdp_algorithmID_to_crypto_suite - * - * Description: - * The function converts the given crypto suite from SDP into - * internal enumeration suitable for using with SRTP lib. - * - * Parameters: - * algorithmID - algorithm ID to be converted into crypto suite - * - * Returns: - * crypto suite that is corresponding to the internal algorithmID - */ -static sdp_srtp_crypto_suite_t -gsmsdp_algorithmID_to_crypto_suite (vcm_crypto_algorithmID algorithmID) -{ - /* Convert the supported crypto suite into the crypto suite */ - switch (algorithmID) { - case VCM_AES_128_COUNTER: - return (SDP_SRTP_AES_CM_128_HMAC_SHA1_32); - default: - return (SDP_SRTP_UNKNOWN_CRYPTO_SUITE); - } -} - - -/* - * Function: gsmsdp_crypto_suite_string - * - * Description: - * The function converts crypto suite to string name. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t - * - * Returns: - * string constant of the corresponding crypto suite - */ -static const char * -gsmsdp_crypto_suite_string (sdp_srtp_crypto_suite_t crypto_suite) -{ - if (crypto_suite >= SDP_SRTP_MAX_NUM_CRYPTO_SUITES) { - return (gsmsdp_crypto_suite_name[SDP_SRTP_UNKNOWN_CRYPTO_SUITE]); - } - return (gsmsdp_crypto_suite_name[crypto_suite]); -} - -/* - * Function: gsmsdp_get_key_from_sdp - * - * Description: - * The function checks the key from the SDP. - * - * Parameters: - * dcb_p - pointer to the DCB. - * sdp_p - pointer to remote's SDP (void) - * level - the media level of the SDP of the media line. - * inst_num - instance number of the crypto attribute. - * key_st - pointer to fsmdef_crypto_key_t for the key to be returned. - * If pointer is NULL, the function acts as key validation. - * - * Returns: - * TRUE - The key is valid. - * FALSE - The key is not valid. - */ -static boolean -gsmsdp_get_key_from_sdp (fsmdef_dcb_t *dcb_p, void *sdp_p, uint16_t level, - uint16_t inst_num, vcm_crypto_key_t *key_st) -{ - const char *fname = "gsmsdp_get_key_from_sdp"; - unsigned char key_size; - unsigned char salt_size; - const char *key, *salt; - sdp_srtp_crypto_suite_t crypto_suite; - - /* Get the crypto suite */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(sdp_p, - level, 0, inst_num); - - /* Get key */ - key_size = sdp_attr_get_sdescriptions_key_size(sdp_p, level, 0, inst_num); - if (!gsmsdp_is_valid_key_size(crypto_suite, key_size)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has invalid key size %d at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, key_size, level); - return (FALSE); - } - - key = sdp_attr_get_sdescriptions_key(sdp_p, level, 0, inst_num); - if (key == NULL) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has no key at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); - } - - /* Get salt */ - salt_size = sdp_attr_get_sdescriptions_salt_size(sdp_p, level, 0, inst_num); - if (!gsmsdp_is_valid_salt_size(crypto_suite, salt_size)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has invalid salt size %d at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, salt_size, level); - return (FALSE); - } - salt = sdp_attr_get_sdescriptions_salt(sdp_p, level, 0, inst_num); - if (salt == NULL) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has no salt at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); - } - - /* - * Key and salt have been sanity check including their sizes, - * copy key and salt if the caller requests for it. - */ - if (key_st != NULL) { - /* The caller needs to copy of the key */ - key_st->key_len = key_size; - memcpy(key_st->key, key, key_size); - key_st->salt_len = salt_size; - memcpy(key_st->salt, salt, salt_size); - } - return (TRUE); -} - -/* - * Function: gsmsdp_local_offer_srtp - * - * Description: - * The function checks whether the local (phone) SRTP has been offered. - * - * Parameters: - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * TRUE - local has offered SRTP - * FALSE - local has not offered SRTP - */ -static boolean -gsmsdp_local_offer_srtp (fsmdef_media_t *media) -{ - /* - * Use the local tag as an indication whether we have offered, - * SRTP or not. - */ - if (media->local_crypto.tag == SDP_INVALID_VALUE) { - return (FALSE); - } - return (TRUE); -} - -/* - * Function: gsmsdp_clear_local_offer_srtp - * - * Description: - * The function clears the flag to mark that the local SRTP has - * been offered. - * - * Parameters: - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * none - */ -static void -gsmsdp_clear_local_offer_srtp (fsmdef_media_t *media) -{ - /* - * Use the local tag as an indication whether we have offered, - * SRTP or not. - */ - media->local_crypto.tag = SDP_INVALID_VALUE; -} - -/* - * Function: gsmsdp_check_common_crypto_param - * - * Description: - * The function checks common crypto parameters that can be shared - * by selecting an offer and checking the answer SDP. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * level - the media level of the SDP of the media line - * inst - crypto attribute instance number of the - * answer crypto line - * offer - boolean indicates offer if it is set to TRUE - * - * Returns: - * TRUE - when crypto parameters are valid and acceptable - * FALSE - when crypto parameters are not valid or not acceptable - */ -static boolean -gsmsdp_check_common_crypto_param (fsmdef_dcb_t *dcb_p, void *sdp_p, - uint16_t level, uint16_t inst, boolean offer) -{ - const char *fname = "gsmsdp_check_common_crypto_param"; - const char *dir_str; /* direction string */ - const char *session_parms; - const char *mki_value = NULL; - uint16_t mki_length = 0; - - if (offer) { - dir_str = "Offer"; /* the caller is working on an offer SDP */ - } else { - dir_str = "Answer"; /* the caller is working on an answer SDP */ - } - - /* Validate the key */ - if (!gsmsdp_get_key_from_sdp(dcb_p, sdp_p, level, inst, NULL)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "%s SDP has invalid key at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, level); - return (FALSE); - } - - /* Check MKI, we do not support it */ - if (sdp_attr_get_sdescriptions_mki(sdp_p, level, 0, inst, - &mki_value, &mki_length) - != SDP_SUCCESS) { - /* something is wrong with decoding MKI field, do not use it */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Fail to obtain MKI from %s SDP at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, level); - return (FALSE); - } - if (mki_length) { - /* this crypto line has MKI specified, we do not support it */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "%s SDP has MKI %d (not supported) at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, mki_length, - level); - return (FALSE); - } - - /* Check session parameters */ - session_parms = sdp_attr_get_sdescriptions_session_params(sdp_p, - level, 0, inst); - if (!gsmsdp_is_supported_session_parm(session_parms)) { - /* some unsupported session parameters are found */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "%s SDP has unsupported session param at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, level); - return (FALSE); - } - - /* This is good and acceptable one */ - return (TRUE); -} - -/* - * Function: gsmsdp_select_offer_crypto - * - * Description: - * Select remote the crypto attributes from the remote offered SDP. - * - * Parameters: - * dcb_p - pointer to the DCB - * sdp_p - pointer to remote's SDP (void) - * level - the media level of the SDP of the media line - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line - * - * Returns: - * TRUE - when matching crypto parameters are found. - * FALSE - when matching crypto parameters are not found. - */ -static boolean -gsmsdp_select_offer_crypto (fsmdef_dcb_t *dcb_p, void *sdp_p, uint16_t level, - uint16_t *crypto_inst) -{ - const char *fname = "gsmsdp_select_offer_crypto"; - uint16_t num_attrs = 0; /* number of attributes */ - uint16_t attr; - int32_t tag; - sdp_attr_e attr_type; - sdp_result_e rc; - sdp_srtp_crypto_suite_t crypto_suite; - - /* Find the number of attributes at this level of media line */ - rc = sdp_get_total_attrs(sdp_p, level, 0, &num_attrs); - if (rc != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed finding attributes for media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); - } - - /* - * Search all crypto attributes to find a valid one that phone - * can support. - * - * The search starts from the first attributes to the higher. The - * attributes are listed from the most preferred attribute to the - * least in the SDP. - */ - for (attr = 1; attr <= num_attrs; attr++) { - rc = sdp_get_attr_type(sdp_p, level, 0, attr, &attr_type, crypto_inst); - if ((rc != SDP_SUCCESS) || (attr_type != SDP_ATTR_SDESCRIPTIONS)) { - /* Can't not get the attribute or it is not sdescription */ - continue; - } - /* - * Found a crypto attribute, try to match the supported crypto suite - */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(sdp_p, - level, 0, - *crypto_inst); - if (!gsmsdp_is_supported_crypto_suite(crypto_suite)) { - /* this one is we can not support, look further */ - continue; - } - /* get crypto tag */ - tag = sdp_attr_get_sdescriptions_tag(sdp_p, level, 0, *crypto_inst); - if (tag == SDP_INVALID_VALUE) { - /* no tag associated with this crypto attribute */ - continue; - } - - /* Check common crypto parameters */ - if (!gsmsdp_check_common_crypto_param(dcb_p, sdp_p, level, - *crypto_inst, TRUE)) { - /* Some thing is wrong with the common crypto parameters */ - continue; - } - - /* Found a good crypto attribute to use */ - return (TRUE); - } - - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed finding supported crypto attribute for media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); -} - -/* - * Function: gsmsdp_check_answer_crypto_param - * - * Description: - * The function processes the answer crypto attributes. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * media - pointer to the media for the SDP of the media line - * crypto_inst - pointer to crypto attribute instance number of the - * answer crypto line. - * - * Returns: - * TRUE - when matching crypto parameters are found - * FALSE - when matching crypto parameters are not found - */ -static boolean -gsmsdp_check_answer_crypto_param (fsmdef_dcb_t *dcb_p, cc_sdp_t * cc_sdp_p, - fsmdef_media_t *media, uint16_t *crypto_inst) -{ - const char *fname = "gsmsdp_check_answer_crypto_param"; - uint16_t num_attrs = 0; /* number of attributes */ - uint16_t attr; - uint16_t num_crypto_attr = 0; - int32_t dest_crypto_tag, offered_tag; - sdp_attr_e attr_type; - sdp_result_e rc; - sdp_srtp_crypto_suite_t crypto_suite; - vcm_crypto_algorithmID algorithmID; - void *dest_sdp = cc_sdp_p->dest_sdp; - uint16_t temp_inst, inst = 0; - uint16_t level; - - level = media->level; - /* Clear the crypto instance */ - *crypto_inst = 0; - - /* Find the number of attributes at this level of media line */ - if (sdp_get_total_attrs(dest_sdp, level, 0, &num_attrs) != SDP_SUCCESS) { - GSM_DEBUG(DEB_L_C_F_PREFIX - "Failed finding attributes for media level %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), level); - return (FALSE); - } - - /* - * Check to make sure that there is only crypto attribute in the - * answer SDP. - */ - for (attr = 1, num_crypto_attr = 0; attr <= num_attrs; attr++) { - rc = sdp_get_attr_type(dest_sdp, level, 0, attr, &attr_type, - &temp_inst); - if ((rc == SDP_SUCCESS) && (attr_type == SDP_ATTR_SDESCRIPTIONS)) { - num_crypto_attr++; - inst = temp_inst; - } - } - if (num_crypto_attr != 1) { - /* The remote answers with zero or more than one crypto attribute */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Answer SDP contains invalid number of" - " crypto attributes %d for media level %d\n", - dcb_p->line, dcb_p->call_id, fname, - num_crypto_attr, level); - return (FALSE); - } - - /* - * Check to make sure that the tag in the answer SDP is one of the - * offered SDP. - * Note: At this time of implementation there is only one crypto - * line sent out. When more than one cypher suites are supported, - * then the answer tag should be used to find the corresponding - * local crypto parameter. - */ - dest_crypto_tag = sdp_attr_get_sdescriptions_tag(dest_sdp, level, 0, inst); - - /* - * Selecting tag, if we have made an offer and have not received an answer - * before this one then tag to match is from the offered tag otherwise - * use the negotiated tag to match. The later case can occur as the - * following: - * phone --- INVITE+SDP ----> CCM - * <--- 100 ----- - * <--- 183+SDP ----- - * <--- 200+SDP ----- - * The first 183+SDP will conclude the offer/answer. The 200+SDP - * is also an answer which also contains negotiated tag. - */ - if (gsmsdp_local_offer_srtp(media)) { - /* - * We have made an offered and has not received an answer before - * this one, use the tag from the local crypto. - */ - offered_tag = media->local_crypto.tag; - algorithmID = media->local_crypto.algorithmID; - } else { - /* offer/answer has complete, use negotiated crypto */ - offered_tag = media->negotiated_crypto.tag; - algorithmID = media->negotiated_crypto.algorithmID; - } - if (dest_crypto_tag != offered_tag) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Answer SDP contains wrong tag %d vs %d" - " for the media level %d\n", - dcb_p->line, dcb_p->call_id, fname, - dest_crypto_tag, offered_tag, level); - return (FALSE); - } - - /* Check make sure that crypto suite is the same one that is offered */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(dest_sdp, level, - 0, inst); - if (gsmsdp_crypto_suite_to_algorithmID(crypto_suite) != algorithmID) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Answer SDP mismatch crypto suite %s at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, - gsmsdp_crypto_suite_string(crypto_suite), level); - return (FALSE); - } - - /* Check common crypto parameters */ - if (!gsmsdp_check_common_crypto_param(dcb_p, dest_sdp, level, - inst, FALSE)) { - /* Some thing is wrong with the common crypto parameters */ - return (FALSE); - } - - *crypto_inst = inst; - return (TRUE); -} - -/* - * - * Function: gsmsdp_negotiate_offer_crypto - * - * Description: - * The function handles crypto parameters negotiation for - * an offer SDP. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * media - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line - * - * Returns: - * transport - sdp_transport_e for RTP or SRTP or invalid - */ -static sdp_transport_e -gsmsdp_negotiate_offer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, uint16_t *crypto_inst, uint16 dest_level) -{ - sdp_transport_e remote_transport; - sdp_transport_e negotiated_transport = SDP_TRANSPORT_INVALID; - void *sdp_p = cc_sdp_p->dest_sdp; - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - *crypto_inst = 0; - remote_transport = sdp_get_media_transport(sdp_p, dest_level); - - /* negotiate media transport */ - switch (remote_transport) { - case SDP_TRANSPORT_RTPAVP: - /* Remote offers RTP for media transport, negotiated transport to RTP */ - negotiated_transport = SDP_TRANSPORT_RTPAVP; - break; - - case SDP_TRANSPORT_RTPSAVP: - - /* Remote offer SRTP for media transport */ - if (((sip_regmgr_get_sec_level(dcb_p->line) == ENCRYPTED) && - FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY)) || sdpmode) { - /* The signalling with this line is encrypted, try to use SRTP */ - if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, dest_level, crypto_inst)) { - /* Found a suitable crypto line from the remote offer */ - negotiated_transport = SDP_TRANSPORT_RTPSAVP; - } - } - - if (negotiated_transport == SDP_TRANSPORT_INVALID) { - /* - * Unable to find a suitable crypto or the signaling is - * not secure. Fall back to RTP if fallback is enabled. - */ - if (sip_regmgr_srtp_fallback_enabled(dcb_p->line)) { - negotiated_transport = SDP_TRANSPORT_RTPAVP; - } - } - break; - - case SDP_TRANSPORT_RTPSAVPF: - /* Remote offers Extended SRTP for media transport */ - negotiated_transport = SDP_TRANSPORT_RTPSAVPF; - break; - - case SDP_TRANSPORT_DTLSSCTP: - negotiated_transport = SDP_TRANSPORT_DTLSSCTP; - break; - - default: - /* Unknown */ - break; - } - return (negotiated_transport); -} - -/* - * - * Function: gsmsdp_negotiate_answer_crypto - * - * Description: - * The function handles crypto parameters negotiation for - * an answer SDP. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * media - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * answer crypto line - * - * Returns: - * transport - sdp_transport_e for RTP or SRTP or invalid - */ -static sdp_transport_e -gsmsdp_negotiate_answer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, uint16_t *crypto_inst) -{ - const char *fname = "gsmsdp_check_answer_crypto"; - sdp_transport_e remote_transport, local_transport; - sdp_transport_e negotiated_transport = SDP_TRANSPORT_INVALID; - uint16_t level; - - level = media->level; - *crypto_inst = 0; - remote_transport = sdp_get_media_transport(cc_sdp_p->dest_sdp, level); - local_transport = sdp_get_media_transport(cc_sdp_p->src_sdp, level); - GSM_DEBUG(GSM_F_PREFIX "remote transport %d", fname, remote_transport); - GSM_DEBUG(GSM_F_PREFIX "local transport %d", fname, local_transport); - - /* negotiate media transport */ - switch (remote_transport) { - case SDP_TRANSPORT_RTPAVP: - /* Remote answer with RTP */ - if (local_transport == SDP_TRANSPORT_RTPSAVP) { - if (sip_regmgr_srtp_fallback_enabled(dcb_p->line)) { - /* Fall back allows, falls back to RTP */ - negotiated_transport = SDP_TRANSPORT_RTPAVP; - } - } else { - /* local and remote are using RTP */ - negotiated_transport = SDP_TRANSPORT_RTPAVP; - } - break; - - case SDP_TRANSPORT_RTPSAVP: - GSM_DEBUG(GSM_F_PREFIX "remote SAVP case", fname); - /* Remote answer with SRTP */ - if (local_transport == SDP_TRANSPORT_RTPSAVP) { - GSM_DEBUG(GSM_F_PREFIX "local SAVP case", fname); - /* Remote and local media transport are using SRTP */ - if (gsmsdp_check_answer_crypto_param(dcb_p, cc_sdp_p, media, - crypto_inst)) { - /* Remote's answer crypto parameters are ok */ - negotiated_transport = SDP_TRANSPORT_RTPSAVP; - GSM_DEBUG(GSM_F_PREFIX "crypto params verified", fname); - } - } else { - /* we offered RTP but remote comes back with SRTP, fail */ - } - break; - - case SDP_TRANSPORT_RTPSAVPF: - negotiated_transport = SDP_TRANSPORT_RTPSAVPF; - break; - - case SDP_TRANSPORT_DTLSSCTP: - negotiated_transport = SDP_TRANSPORT_DTLSSCTP; - break; - - default: - /* Unknown */ - break; - } - GSM_DEBUG(GSM_F_PREFIX "negotiated transport %d", fname, negotiated_transport); - return (negotiated_transport); -} - -/* - * - * Function: gsmsdp_negotiate_media_transport - * - * Description: - * The function is a wrapper for negotiation RTP or SRTP for offer - * or answer SDP. The negotiated crypto attributes instance number - * will be returned via pointer crypto_inst. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated. - * cc_sdp_p - pointer to cc_sdp_t structure that contains remote SDP. - * offer - boolean indicates the remote SDP is an offer SDP. - * media - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line. - * - * Returns: - * transport - sdp_transport_e for RTP or SRTP or invalid - */ -sdp_transport_e -gsmsdp_negotiate_media_transport (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - boolean offer, fsmdef_media_t *media, - uint16_t *crypto_inst, uint16 level) -{ - sdp_transport_e transport; - - /* negotiate media transport based on offer or answer from the remote */ - if (offer) { - transport = gsmsdp_negotiate_offer_crypto(dcb_p, cc_sdp_p, media, - crypto_inst, level); - } else { - transport = gsmsdp_negotiate_answer_crypto(dcb_p, cc_sdp_p, media, - crypto_inst); - } - return (transport); -} - -/* - * - * Function: gsmsdp_add_single_crypto_attr - * - * Description: - * The function adds a single crypto attributes to the SDP. - * - * Parameters: - * cc_sdp_p - pointer to SDP - * level - the media level of the SDP where the media transport is - * crypto_suite - crypto suite - * key - pointer to SRTP key (fsmdef_crypto_key_t) - * lifetime - pointer to string const for the life time - * - * Returns: - * sdp_result_e - */ -static sdp_result_e -gsmsdp_add_single_crypto_attr (void *sdp_p, uint16_t level, int32_t tag, - sdp_srtp_crypto_suite_t crypto_suite, - vcm_crypto_key_t * key, char *lifetime) -{ - sdp_result_e rc; - uint16 inst_num; - - if (key == NULL) { - return (SDP_INVALID_PARAMETER); - } - - /* - * Add crypto attributes tag to the SDP, the tag is using - * from the remote tag which should have been negotiated. - */ - rc = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_SDESCRIPTIONS, &inst_num); - if (rc != SDP_SUCCESS) { - return (rc); - } - - rc = sdp_attr_set_sdescriptions_tag(sdp_p, level, 0, inst_num, tag); - if (rc != SDP_SUCCESS) { - return (rc); - } - - /* Add crypto suite */ - rc = sdp_attr_set_sdescriptions_crypto_suite(sdp_p, level, 0, inst_num, - crypto_suite); - if (rc != SDP_SUCCESS) { - return (rc); - } - - /* Add local key */ - rc = sdp_attr_set_sdescriptions_key(sdp_p, level, 0, inst_num, - (char *) key->key); - if (rc != SDP_SUCCESS) { - return (rc); - } - - rc = sdp_attr_set_sdescriptions_key_size(sdp_p, level, 0, inst_num, - key->key_len); - if (rc != SDP_SUCCESS) { - return (rc); - } - - /* Add salt */ - rc = sdp_attr_set_sdescriptions_salt(sdp_p, level, 0, inst_num, - (char *) key->salt); - if (rc != SDP_SUCCESS) { - return (rc); - } - - rc = sdp_attr_set_sdescriptions_salt_size(sdp_p, level, 0, inst_num, - key->salt_len); - if (rc != SDP_SUCCESS) { - return (rc); - } - - if (lifetime != NULL) { - rc = sdp_attr_set_sdescriptions_lifetime(sdp_p, level, 0, inst_num, - lifetime); - } - return (rc); -} - -/* - * - * Function: gsmsdp_add_all_crypto_lines - * - * Parameters: - * - * dcb_p - pointer to the DCB whose local SDP is to be updated. - * sdp_p - pointer to SDP. - * media - pointer to fsmdef_media_t where the media transport is. - * - * Description: - * The function adds all crypto lines to the SDP. - * - * Returns: - * N/A. - */ -static void -gsmsdp_add_all_crypto_lines (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media) -{ - const char *fname = "gsmsdp_add_all_crypto_lines"; - sdp_srtp_crypto_suite_t crypto_suite; - - /* - * Add all crypto lines, currently there is only one crypto - * line to add. - */ - media->local_crypto.tag = 1; - media->local_crypto.algorithmID = GSMSDP_DEFAULT_ALGORITHM_ID; - - /* Generate key */ - gsmsdp_generate_key(media->local_crypto.algorithmID, - &media->local_crypto.key); - - /* Get the crypto suite based on the algorithm ID */ - crypto_suite = - gsmsdp_algorithmID_to_crypto_suite(media->local_crypto.algorithmID); - if (gsmsdp_add_single_crypto_attr(sdp_p, media->level, - media->local_crypto.tag, crypto_suite, &media->local_crypto.key, - GSMSDP_DEFALT_KEY_LIFETIME) != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed to add crypto attributes\n", - dcb_p->line, dcb_p->call_id, fname); - } -} - -/* - * Function: gsmsdp_init_crypto_context - * - * Description: - * Initializes crypto context. - * - * Parameters: - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * none - */ -static void -gsmsdp_init_crypto_context (fsmdef_media_t *media) -{ - /* initialize local crypto parameters */ - media->local_crypto.tag = SDP_INVALID_VALUE; - media->local_crypto.algorithmID = VCM_NO_ENCRYPTION; - media->local_crypto.key.key_len = 0; - media->local_crypto.key.salt_len = 0; - - /* Initialized negotiated crypto parameter */ - media->negotiated_crypto.tag = SDP_INVALID_VALUE; - media->negotiated_crypto.algorithmID = VCM_NO_ENCRYPTION; - media->negotiated_crypto.tx_key.key_len = 0; - media->negotiated_crypto.tx_key.salt_len = 0; - media->negotiated_crypto.rx_key.key_len = 0; - media->negotiated_crypto.rx_key.salt_len = 0; - - media->negotiated_crypto.flags = 0; -} - -/* - * Function: gsmsdp_init_sdp_media_transport - * - * Description: - * The prepares or initializes crypto context for a fresh negotiation. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to SDP (void) - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * N/A - */ -void -gsmsdp_init_sdp_media_transport (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media) -{ - int rtpsavpf = 0; - int sdpmode = 0; - - /* Initialize crypto context */ - gsmsdp_init_crypto_context(media); - - config_get_value(CFGID_RTPSAVPF, &rtpsavpf, sizeof(rtpsavpf)); - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (SDP_MEDIA_APPLICATION == media->type) { - media->transport = SDP_TRANSPORT_DTLSSCTP; - } else if (rtpsavpf) { - media->transport = SDP_TRANSPORT_RTPSAVPF; - } else if (sdpmode) { - media->transport = SDP_TRANSPORT_RTPSAVP; - } else if ((sip_regmgr_get_sec_level(dcb_p->line) != ENCRYPTED) || - (!FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY))) { - /* - * The signaling is not encrypted or this media can not support - * security. - */ - media->transport = SDP_TRANSPORT_RTPAVP; - } else { - media->transport = SDP_TRANSPORT_RTPSAVP; - } -} - -/* - * Function: gsmsdp_reset_sdp_media_transport - * - * Description: - * The function resets media transport during mid call such as resume. - * The media transport may change from the current negotiated media. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to SDP (void) - * media - pointer to fsmdef_media_t where the media transport is. - * hold - indicates call is being hold - * - * Returns: - * N/A. - */ -void -gsmsdp_reset_sdp_media_transport (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media, boolean hold) -{ - if (hold) { - /* We are sending out hold, uses the same transport as negotiated */ - } else { - /* Resuming a call */ - if ((sip_regmgr_get_cc_mode(dcb_p->line) == REG_MODE_CCM)) { - /* - * In CCM mode, try to resume with full SRTP offer again - * if the current signalling is encrypted. In CCM mode, - * CCM will assist in crypto negotiation and fall back to - * RTP if necessary. This is useful when resuming a different - * end point and the new end point support SRTP even when the - * current media is not SRTP. For an example, when holding - * a call that was transferred to a new end point which - * it may be able to support SRTP. - */ - gsmsdp_init_sdp_media_transport(dcb_p, - dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL, - media); - } else { - /* - * In non CCM mode, we do not know whether the new end - * point supports SRTP fall back and no assistance from - * CCM in negotiating of the crypto parameter, play safe by - * resuming with the same media transport. - */ - } - } -} - -/* - * Function: gsmsdp_set_media_transport_for_option - * - * Parameters: - * sdp - pointer to SDP (void). - * level - the media level of the SDP where the media transport is. - * - * Description: - * The function sets media transport for OPTION message. - * - * Returns: - * N/A. - */ -void -gsmsdp_set_media_transport_for_option (void *sdp_p, uint16_t level) -{ - const char *fname = "gsmsdp_set_media_transport_for_option"; - uint32_t algorithmID; - vcm_crypto_key_t key; - sdp_srtp_crypto_suite_t crypto_suite; - - - /* Use line 1 to determine whether to have RTP or SRTP */ - if (sip_regmgr_get_sec_level(1) != ENCRYPTED) { - /* line one is none secure, use RTP */ - (void) sdp_set_media_transport(sdp_p, level, SDP_TRANSPORT_RTPAVP); - return; - } - - /* Advertise SRTP with default attributes */ - (void) sdp_set_media_transport(sdp_p, level, SDP_TRANSPORT_RTPSAVP); - - /* Generate dummy key */ - crypto_suite = SDP_SRTP_AES_CM_128_HMAC_SHA1_32; - algorithmID = gsmsdp_crypto_suite_to_algorithmID(crypto_suite); - gsmsdp_generate_key(algorithmID, &key); - - /* Add crypto attributes */ - if (gsmsdp_add_single_crypto_attr(sdp_p, level, 1, crypto_suite, &key, - GSMSDP_DEFALT_KEY_LIFETIME) != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_F_PREFIX - "Failed to add crypto attributes\n", - fname); - } -} - -/* - * Function: gsmsdp_update_local_sdp_media_transport - * - * Description: - * The function updates the crypto attributes to the local SDP. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to SDP (void) - * media - pointer to fsmdef_media_t where the media transport is. - * sdp_transport_e - current media transport - * all - indicates that the update for new offer SDP - * - * Returns: - * none - */ -void -gsmsdp_update_local_sdp_media_transport (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media, - sdp_transport_e transport, boolean all) -{ - const char *fname = "gsmsdp_update_local_sdp_media_transport"; - sdp_srtp_crypto_suite_t crypto_suite; - uint16_t level; - - level = media->level; - /* Get the current transport before delete the media line */ - if (transport == SDP_TRANSPORT_INVALID) { - /* - * The transport is not specified, get it from the negotiated - * transport. This condition can occur when receive initial - * offered SDP. - */ - transport = media->transport; - } - - /* - * set media transport in local SDP only first time so that we remember what we offered. - */ - if (sdp_get_media_transport(sdp_p, level) == SDP_TRANSPORT_INVALID) { - (void) sdp_set_media_transport(sdp_p, level, transport); - } - - if (transport != SDP_TRANSPORT_RTPSAVP) { - /* - * transport is not SRTP, if this is the fall back to RTP then - * the existing crypto lines should have been removed by the - * media transport negotiation and thus no code is added here. - * The reason for this is not to call to the remove all crypto - * line all the time i.e. only removed them when related to - * SRTP media transport. - */ - return; - } - - /* Add crypto attributes to local SDP. */ - if (all || (media->negotiated_crypto.tag == SDP_INVALID_VALUE)) { - /* This is new offer or mid call media change occurs , - * or could be the result of sending full offer during mid-call invite - * without SDP (delayed media invite) as well - */ - if (media->negotiated_crypto.tag == SDP_INVALID_VALUE) { - /* - * This is the first time or fresh offering add all crypto - * lines. - */ - gsmsdp_add_all_crypto_lines(dcb_p, sdp_p, media); - return; - } else { - /* Fall through below and use existing crypto parameters */ - } - } - - /* - * tag and algorithm ID are from the negotiated crypto parameters. - */ - crypto_suite = - gsmsdp_algorithmID_to_crypto_suite( - media->negotiated_crypto.algorithmID); - if (gsmsdp_add_single_crypto_attr(sdp_p, level, - media->negotiated_crypto.tag, - crypto_suite, - &media->negotiated_crypto.tx_key, - GSMSDP_DEFALT_KEY_LIFETIME) - != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed to add crypto attributes\n", - dcb_p->line, dcb_p->call_id, fname); - } -} - -/* - * Function: gsmsdp_update_crypto_transmit_key - * - * Description: - * The function updates transmit key for SRTP session. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * media - pointer to fsmdef_media_t where the media transport is. - * offer - boolean indicates it is an offer - * initial_offer - boolean indicates it is an initial offer - * direction - new offered media direction - * - * Returns: - * none - */ -void -gsmsdp_update_crypto_transmit_key (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - boolean offer, - boolean initial_offer, - sdp_direction_e direction) -{ - const char *fname = "gsmsdp_update_crypto_transmit_key"; - boolean generate_key = FALSE; - - if (media->transport != SDP_TRANSPORT_RTPSAVP) { - return; - } - - if (initial_offer || offer) { - /* This is an offer SDP, see if a new key needs to be generated */ - if (initial_offer) { - /* An initial offer always needs new key */ - generate_key = TRUE; - } else if ((util_compare_ip(&(media->previous_sdp.dest_addr), - &(media->dest_addr)) == FALSE) && - media->dest_addr.type != CPR_IP_ADDR_INVALID) { - //Todo IPv6: IPv6 does not support 0.0.0.0 hold. - - GSM_DEBUG(DEB_L_C_F_PREFIX - "Received offer with dest. address changes\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - /* - * This is just an offer and the destination address changes to - * is not 0.0.0.0 (hold) address, new key may be needed. There - * is a scenario where we get a delay media INVITE during the - * resume call (from the CCM for an example) and we have sent - * out 200 OK (offer SDP) with crypto parameters. Upon receiving - * ACK with SDP, the SIP stack in this notify GSM as a - * FEATURE MEDIA to GSM. GSM treats this as an offer SDP. - * This code path is entered with offer flag set where it should - * be an answer to our 200 OK offer early on. Check for this - * condition to see if we have an offer sent prior and if so - * do not generate new key if we already sent an offer out - * and has not get and answer SDP. Otherwise we will be generating - * a new key and do not sent out the key to the remote end which - * result in wrong local transmit key is being used. - */ - if (gsmsdp_local_offer_srtp(media)) { - /* - * We have sent out an offer but has not got an answer, - * use the already generated key - */ - media->negotiated_crypto.tx_key = media->local_crypto.key; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Local offered SDP has been sent, use offered key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } else { - generate_key = TRUE; - } - } else if ((media->direction == SDP_DIRECTION_INACTIVE) && - (direction != SDP_DIRECTION_INACTIVE)) { - if (!gsmsdp_local_offer_srtp(media)) { - /* - * Received an offer that changes the direction from - * inactive to some thing other than inactive, then - * generate a new key. The phone could be transferred - * to a new endpoint without destination address changes. - * This is possible if there is a passthrough MTP in - * between. The remote end point may be changed - * behind MTP but from this phone the destination addr. - * stays the same. - */ - generate_key = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Received direction changes from inactive\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - } else if (media->negotiated_crypto.tx_key.key_len == 0) { - if (gsmsdp_local_offer_srtp(media)) { - /* - * This an answer to our offer sent similar to - * the address change scenario above (delayed media, we - * sent SDP in 200OK and got SDP in ACK but GSM treats - * SDP in ACK case as an offer rather than an answer). - * Use the key in the offered SDP. - */ - media->negotiated_crypto.tx_key = media->local_crypto.key; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Local offered SDP has been sent, use offered key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } else { - /* - * Do not have negotiated transmit key. - * - * The scenario that this can occur is when the - * call transition from RTP to SRTP in mid-call. - */ - generate_key = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Received offer but no tx key, generate new key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - } else { - /* No need to generate new key */ - } - if (generate_key) { - /* - * This is an initial offer or mid-call offer and - * some conditions changes , generate a new transmit key. - */ - gsmsdp_generate_key(media->negotiated_crypto.algorithmID, - &media->negotiated_crypto.tx_key); - GSM_DEBUG(DEB_L_C_F_PREFIX - "Generate tx key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - media->negotiated_crypto.flags |= FSMDEF_CRYPTO_TX_CHANGE; - } - } else { - /* This is an answer to our offer, set the tx key to the local key - * - * Note that when adding support to offer multiple crypto suite to - * the remote end, we need to select the corresponding local offer - * SDP from the matching tag. At this point, we only support one - * crypto to offer and just get to that entry - */ - if (gsmdsp_cmp_key(&media->local_crypto.key, - &media->negotiated_crypto.tx_key)) { - media->negotiated_crypto.flags |= FSMDEF_CRYPTO_TX_CHANGE; - GSM_DEBUG(DEB_L_C_F_PREFIX - "tx key changes in answered SDP\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - media->negotiated_crypto.tx_key = media->local_crypto.key; /* tx key */ - } - /* Complete offer/answer, clear condition that we have made an offered */ - gsmsdp_clear_local_offer_srtp(media); -} - -/* - * Function: gsmsdp_update_negotiated_transport - * - * Description: - * The function updates the transport and crypto parameters after the - * all negotiated parameters has been done. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to cc_sdp_t structure - * level - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line - * sdp_transport_e - negotiated media transport - * - * Returns: - * none - */ -void -gsmsdp_update_negotiated_transport (fsmdef_dcb_t *dcb_p, - cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, - uint16_t crypto_inst, - sdp_transport_e transport, - uint16 dest_level) -{ - const char *fname = "gsmsdp_update_negotiated_transport"; - sdp_srtp_crypto_suite_t crypto_suite; - void *dest_sdp = cc_sdp_p->dest_sdp; - vcm_crypto_algorithmID algorithmID; - vcm_crypto_key_t key; - uint16_t level; - - level = dest_level; - /* - * Also detect changes of the crypto parameters for Tx and Rx. - * It is done here to avoid adding last crypto parameters for Tx and - * Rx into the dcb structure since the parameters include key which - * are rather long. This minimize the dcb's increasing. - */ - /* reset changes flags */ - media->negotiated_crypto.flags &= ~(FSMDEF_CRYPTO_TX_CHANGE | - FSMDEF_CRYPTO_RX_CHANGE); - /* - * Detect the transport change between RTP to SRTP or ignore - * the first time transition from invalid transport. This - * prevents the change bits to be set for first time in RTP - * connection and causes the RX to be closed unnecessary. - */ - if ((media->transport != SDP_TRANSPORT_INVALID) && - (transport != media->transport)) { - /* We could fallback to RTP or resume from RTP to SRTP */ - media->negotiated_crypto.flags |= (FSMDEF_CRYPTO_TX_CHANGE | - FSMDEF_CRYPTO_RX_CHANGE); - GSM_DEBUG(DEB_L_C_F_PREFIX - "SDP media transport changed to %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), transport); - } - /* Update the negotiated media transport */ - media->transport = transport; - - if (media->transport != SDP_TRANSPORT_RTPSAVP) { - /* - * negotiate media transport to RTP, clear local offer SDP - * condition. - */ - GSM_DEBUG(DEB_L_C_F_PREFIX - "SDP media transport is RTP\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return; - } - - GSM_DEBUG(DEB_L_C_F_PREFIX "SDP media transport is SRTP", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - - /* - * Get the crypto parameters from the remote's SDP, - * the parameters should already be validated during the - * media transport negotiation. Update the negotiated crypto parameter. - */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(dest_sdp, level, - 0, crypto_inst); - - /* Save the negotiated algorithm ID */ - algorithmID = gsmsdp_crypto_suite_to_algorithmID(crypto_suite); - if (algorithmID != media->negotiated_crypto.algorithmID) { - media->negotiated_crypto.flags |= (FSMDEF_CRYPTO_TX_CHANGE | - FSMDEF_CRYPTO_RX_CHANGE); - GSM_DEBUG(DEB_L_C_F_PREFIX "SDP algorithm ID change to %d", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), algorithmID); - } - media->negotiated_crypto.algorithmID = algorithmID; - - /* Save the negotiated crypto line tag */ - media->negotiated_crypto.tag = sdp_attr_get_sdescriptions_tag(dest_sdp, - level, 0, - crypto_inst); - - /* Get the remote's key */ - (void) gsmsdp_get_key_from_sdp(dcb_p, dest_sdp, level, crypto_inst, &key); - if (gsmdsp_cmp_key(&key, &media->negotiated_crypto.rx_key)) { - media->negotiated_crypto.flags |= FSMDEF_CRYPTO_RX_CHANGE; - GSM_DEBUG(DEB_L_C_F_PREFIX "SDP rx key changes", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - media->negotiated_crypto.rx_key = key; -} - -/* - * Function: gsmsdp_is_crypto_ready - * - * Parameters: - * media - pointer to fsmdef_media_t where the media transport is. - * rx - boolean indicates receiver. - * - * Description: - * The function returns to the caller whether receiver/transmitter is - * ready for open. - * - * Returns: - * TRUE - when the receiver is ready to received. - * FALSE - when the receive is not ready. - */ -boolean -gsmsdp_is_crypto_ready (fsmdef_media_t *media, boolean rx) -{ - /* - * If we offered SRTP then we need to wait for the negotiated key before - * allowing the Rx/Tx to be opened. If we did not offer (we received - * an offered SDP instead then we should have key negotiated). - */ - if (media->transport == SDP_TRANSPORT_RTPAVP || media->transport == SDP_TRANSPORT_RTPSAVPF) { - return (TRUE); - } - - /* - * Local has offered SRTP, check to see if the key is available. - */ - if (rx) { - if (media->negotiated_crypto.rx_key.key_len == 0) { - /* Have not received remote's crypto parameter yet, can't open Rx */ - return (FALSE); - } - } else { - if (media->negotiated_crypto.tx_key.key_len == 0) { - /* Have not received remote's crypto parameter yet, can't open Tx */ - return (FALSE); - } - } - /* Have remote's key */ - return (TRUE); -} - -/* - * Function: gsmsdp_is_media_encrypted - * - * Description: - * The function returns to the caller whether the media is - * encrypted or not. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t. - * - * Returns: - * TRUE - when the media is encrypted. - * FALSE - when the media is not encrypted. - */ -boolean -gsmsdp_is_media_encrypted (fsmdef_dcb_t *dcb_p) -{ - fsmdef_media_t *media; - uint8_t num_encrypted; - - if (dcb_p == NULL) { - return(FALSE); - } - num_encrypted = 0; - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - - if (media->transport == SDP_TRANSPORT_RTPSAVP || media->transport == SDP_TRANSPORT_RTPSAVPF) { - num_encrypted++; - } - } - - if ((num_encrypted == 0) || - (num_encrypted != GSMSDP_MEDIA_COUNT(dcb_p))) { - /* - * the call does not have any media that is encrypted or - * there are some medias that are not encrypted. This is - * considered as non secure leg. - */ - return (FALSE); - } - return (TRUE); -} - -/* - * Function: gsmsdp_crypto_params_change - * - * Description: - * The function returns to the caller whether the crypto parameters - * change from the previous SDP or not. - * - * Parameters: - * rcv_only - If TRUE, check for receive port perspective. - * media - pointer to fsmdef_media_t where the media transport is. - * - * Returns: - * TRUE - when crypto parameters changed - * FALSE - when crypto parameters did not change - */ -boolean -gsmsdp_crypto_params_change (boolean rcv_only, fsmdef_media_t *media) -{ - if (rcv_only) { - if (media->negotiated_crypto.flags & FSMDEF_CRYPTO_RX_CHANGE) { - return (TRUE); - } - } else { - if (media->negotiated_crypto.flags & FSMDEF_CRYPTO_TX_CHANGE) { - return (TRUE); - } - } - return (FALSE); -} - -/** - * The function resets crypto parameters change status. - * - * @param[in] media - pointer to fsmdef_media_t. - * - * @return None. - * - * @pre (media not_eq NULL) - */ -void -gsmsdp_crypto_reset_params_change (fsmdef_media_t *media) -{ - media->negotiated_crypto.flags &= ~(FSMDEF_CRYPTO_RX_CHANGE | - FSMDEF_CRYPTO_TX_CHANGE); -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/fim.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/fim.h deleted file mode 100755 index d4b5ff75680..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/fim.h +++ /dev/null @@ -1,68 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _FIM_H_ -#define _FIM_H_ - -#include "sm.h" -#include "fsm.h" - -/* - * This is an overlay structure. - * Every entity cb must have these two fields at the start of the cb - */ -typedef struct fim_cb_hdr_ { - callid_t call_id; - int state; -} fim_cb_hdr_t; - -#ifndef fim_icb_t__ -#define fim_icb_t__ -struct fim_icb_t_; -typedef struct fim_icb_t_ fim_icb_t; -#endif - -typedef void (*fim_func_t)(fim_icb_t *elem, callid_t call_id); - -typedef struct fim_scb_t_ { - fsm_types_t type; - sm_table_t *sm; - fim_func_t get_cb; - fim_func_t free_cb; -} fim_scb_t; - -struct fim_icb_t_ { - struct fim_icb_t_ *next_chn; - struct fim_icb_t_ *next_icb; - callid_t call_id; - boolean ui_locked; - void *cb; - fim_scb_t *scb; -}; - - -const char *fim_event_name(int event); -boolean fim_process_event(void *data, boolean cac_passed); -void fim_free_event(void *data); -void fim_init(void); -void fim_shutdown(void); -void fsmcnf_free_cb(fim_icb_t *icb, callid_t call_id); -void fsmxfr_free_cb(fim_icb_t *icb, callid_t call_id); -void fsmdef_free_cb(fim_icb_t *icb, callid_t call_id); -void fsmb2bcnf_free_cb(fim_icb_t *icb, callid_t call_id); - -void fim_lock_ui(callid_t call_id); -void fim_unlock_ui(callid_t call_id); - -cc_causes_t -fsm_cac_process_bw_avail_resp(void); -cc_causes_t -fsm_cac_process_bw_failed_resp(void); -cc_causes_t -fsm_cac_call_bandwidth_req(callid_t call_id, uint32_t sessions, - void *msg); - -fim_icb_t *fim_get_call_chn_by_call_id (callid_t call_id); -fim_icb_t *fim_get_new_call_chn (callid_t call_id); -#endif /* _FIM_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h deleted file mode 100755 index bae3873a351..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h +++ /dev/null @@ -1,785 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _FSM_H_ -#define _FSM_H_ - -#include "cpr_types.h" -#include "sm.h" -#include "ccapi.h" -#include "vcm.h" -#include "ccsip_core.h" -#include "sll_lite.h" -#include "sessionConstants.h" -#include "ccsdp.h" -#include "fsmdef_states.h" - -/* TODO: BLASBERG - * fsm.h only needs the following from ccsip_core.h - * should put basic sip types into a separate hdr file -typedef enum { - ALERTING_NONE, - ALERTING_OLD, - ALERTING_TONE, - ALERTING_RING -} alertingType; -*/ - - -#define FSMCNF_MAX_CCBS (LSM_MAX_LINES) -#define FSMXFR_MAX_XCBS (LSM_MAX_LINES) -#define FSM_NO_ID (0) -#define FSMDEF_NO_DCB (NULL) -#define FSMDEF_ERR_ONHOOK_TMR_SECS (20) - -#define FSMDEF_MAX_DIGEST_ALG_LEN 10 -#define FSMDEF_MAX_DIGEST_LEN 32 * 3 - -// Should match define for SIP stack MAX_SIP_URL_LENGTH -#define FSMDEF_MAX_CALLER_ID_LEN (256) - -#ifndef fim_icb_t__ -#define fim_icb_t__ -struct fim_icb_t_; -typedef struct fim_icb_t_ fim_icb_t; -#endif - -typedef enum { - PRIMARY, - MONITOR, - LOCAL_CONF, - WHISPER_COACHING -} fsm_session_t; - -typedef enum { - DIAL_MODE_NUMERIC, - DIAL_MODE_URL -} dialMode_t; - -typedef enum { - FSMDEF_CALL_TYPE_MIN = -1, - FSMDEF_CALL_TYPE_NONE = CC_CALL_TYPE_NONE, - FSMDEF_CALL_TYPE_INCOMING = CC_CALL_TYPE_INCOMING, - FSMDEF_CALL_TYPE_OUTGOING = CC_CALL_TYPE_OUTGOING, - FSMDEF_CALL_TYPE_FORWARD = CC_CALL_TYPE_FORWARDED, - FSMDEF_CALL_TYPE_MAX -} fsmdef_call_types_t; - -typedef enum { - FSMDEF_MRTONE_NO_ACTION = 0, - FSMDEF_MRTONE_PLAYED_MONITOR_TONE, - FSMDEF_MRTONE_PLAYED_RECORDER_TONE, - FSMDEF_MRTONE_PLAYED_BOTH_TONES, - FSMDEF_MRTONE_RESUME_MONITOR_TONE, - FSMDEF_MRTONE_RESUME_RECORDER_TONE, - FSMDEF_MRTONE_RESUME_BOTH_TONES -} fsmdef_monrec_tone_action_e; - -typedef enum { - FSMDEF_PLAYTONE_NO_ACTION = 0, - FSMDEF_PLAYTONE_ZIP -} fsmdef_play_tone_action_e; - -/* Local crypto parameter is the local parameters to offer */ -typedef struct fsmdef_crypto_param_t_ { - int32_t tag; /* crypto attribute tag */ - vcm_crypto_algorithmID algorithmID; /* encryption algorithm. */ - vcm_crypto_key_t key; /* local key */ -} fsmdef_crypto_param_t; - -/* Negotiated crypto parameter */ -#define FSMDEF_CRYPTO_TX_CHANGE (1 << 0) /* crypto Tx parms. change */ -#define FSMDEF_CRYPTO_RX_CHANGE (1 << 1) /* crypto Tx parms. change */ -typedef struct fsmdef_negotiated_crypto_t_ { - int32_t tag; /* crypto attribute tag */ - vcm_crypto_algorithmID algorithmID; /* algorithm ID */ - vcm_crypto_key_t tx_key; /* tx key */ - vcm_crypto_key_t rx_key; /* rx key */ - uint32_t flags; /* misc. flags. */ - char algorithm[FSMDEF_MAX_DIGEST_ALG_LEN]; - char digest[FSMDEF_MAX_DIGEST_LEN]; -} fsmdef_negotiated_crypto_t; - -/* - * Saved attributes of interest from previously received SDP - */ -typedef struct fsmdef_previous_sdp_ { - uint16_t dest_port; - cpr_ip_addr_t dest_addr; - int32_t avt_payload_type; - - /* - * This field contains the number of elements in the payloads field. - */ - int32_t num_payloads; - vcm_payload_info_t* payloads; - - uint16_t packetization_period; - uint16_t max_packetization_period; - sdp_direction_e direction; - int32_t tias_bw; - int32_t profile_level; -} fsmdef_previous_sdp_t; - -typedef struct fsmdef_media_t_ { - sll_lite_node_t node; /* link node, must be first member of struct */ - media_refid_t refid; /* media reference id */ - sdp_media_e type; /* audio, video etc. media */ - sdp_addrtype_e addr_type;/* ipv4, ipv6 */ - int32_t avt_payload_type; - vcm_vad_t vad; - uint16_t packetization_period; - uint16_t max_packetization_period; - uint16_t mode; - uint16_t level; - boolean direction_set; - sdp_direction_e direction; /* current negotiated direction */ - sdp_direction_e support_direction; /* supported direction */ - sdp_transport_e transport; - uint16_t src_port; /* source port for this media stream */ - cpr_ip_addr_t src_addr; /* source addr for this media stream */ - uint16_t dest_port; /* destination port for this media stream */ - cpr_ip_addr_t dest_addr; /* destination addr for this media straam */ - /* Flag to indicate if Multicast */ - boolean is_multicast; - uint16_t multicast_port; - /* - * rcv_chan indicates if the receive media stream has been opened - */ - boolean rcv_chan; - /* - * xmit_chan indicates if the transmit media stream has been opened - */ - boolean xmit_chan; - - /* - * SRTP support. - */ - fsmdef_negotiated_crypto_t negotiated_crypto; - - /* - * Local crypto holds the local offered crypto set, keeps it in the - * dcb for fast access. The alternative to be kept in the - * SDP structure but is slower in retrieving it. In the future, - * it is possible that more than 1 crypto lines are offered but - * for now it is one. - */ - fsmdef_crypto_param_t local_crypto; - - /* - * Used to track previously received SDP for comparisons to - * newly received media to determine if RTP port recycling is - * required. Eliminates unnecessary recycling of ports which - * causes breaks in the audio stream. - */ - fsmdef_previous_sdp_t previous_sdp; - - /* - * hold tracks the hold state. The flag is a bit map so it is possible that - * the phone may have multiple holding states, ie. local and remote - */ - uint32_t hold; - /* - * Flags fields for various bit flags - */ -#define FSM_MEDIA_F_SUPPORT_SECURITY (1 << 0) /* supported security */ - uint32_t flags; - - /* - * capability index. The index into the media capbilty table - * that this media entry is coresponding to. - */ - uint8_t cap_index; - - /* Values cached from attributes */ - int32_t tias_bw; - int32_t profile_level; - - void *video; - - /* ICE Candidates */ - char **candidatesp; - int candidate_ct; - /* - * rtcp-mux indicates media stream is muxed for RTP and RTCP - */ - boolean rtcp_mux; - /* - * Flag to indicate if RTP Header extension for audio level is used - * and the id to be used for it - */ - boolean audio_level; - uint8_t audio_level_id; - - /* - * The value of the a=setup line - */ - sdp_setup_type_e setup; - /* - * port number used in m= data channel line - */ - uint16_t local_datachannel_port; - uint16_t remote_datachannel_port; - - /* - * Data Channel properties - */ -#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 256 - uint32 datachannel_streams; - char datachannel_protocol[SDP_MAX_STRING_LEN + 1]; - - /* - * This field contains the number of elements in the payloads field. - */ - int32_t num_payloads; - - /* - * List of active lists of payloads negotiated - */ - vcm_payload_info_t* payloads; - -} fsmdef_media_t; - -struct fsm_fcb_t_; - -typedef struct { - callid_t call_id; - callid_t join_call_id; - line_t line; - cc_caller_id_t caller_id; - groupid_t group_id; - int digit_cnt; - fsmdef_call_types_t call_type; - fsm_session_t session; - boolean send_release; - int msgs_sent; - int msgs_rcvd; - boolean onhook_received; - - /* - * inband indicates if inband alerting is active - */ - boolean inband; - - /* - * inband_received indicates if inband alerting has been received. - * Once set, this bool stays set until dcb is reset. - */ - boolean inband_received; - - /* - * outofband tracks the payload type for outofband DTMF - */ - int outofband; - - /* - * Boolean indication of whether call was originated by phone or - * far end party. - */ - boolean inbound; - - /* - * The following data tracks the RTP info - */ - boolean remote_sdp_present; - boolean remote_sdp_in_ack; - boolean local_sdp_complete; - uint16_t src_sdp_version; - cc_sdp_t *sdp; - - /* media list corresponding to m lines */ - sll_lite_list_t media_list; - - /* - * dial_mode tracks the state of the dialing mode icon, ie. alphanumeric or - * numeric - */ - dialMode_t dial_mode; - - /* - * pd_updated tracks whether or not the personal directory has - * been updated - */ - boolean pd_updated; - - /* tracks the ringing pattern to play */ - vcm_ring_mode_t alerting_ring; - - /* tracks the tone to play */ - vcm_tones_t alerting_tone; - - /* tracks the direction to play the tone. */ - uint16_t tone_direction; - - /* Was an alert-info header present, if so what did it contain */ - cc_alerting_type alert_info; - - /* used to determine when SIP stack releases the call early. */ - boolean early_error_release; - - /* used to determine when we are played a tone via the dialplan */ - boolean dialplan_tone; - - /* active tone (i.e. tone currently being played or requested to be played) */ - vcm_tones_t active_tone; - - /* indicates the action of monitor and recorder tones */ - fsmdef_monrec_tone_action_e monrec_tone_action; - - /* monitor/recorder tone direction to play out to */ - uint16_t monitor_tone_direction; - uint16_t recorder_tone_direction; - - /* indicates the action of play tone for a single time */ - fsmdef_play_tone_action_e play_tone_action; - - struct fsm_fcb_t_ *fcb; - - /* Feature that is currently active */ - cc_features_t active_feature; - - /* Reason for hold */ - cc_hold_resume_reason_e hold_reason; - - /* Feature invocation state. - * Each feature will correspond to unique bit in variable. - * Bit will be Set if feature is invoked and awaiting feature ACK. - * Bit will be Cleared if feature is ACKed or not yet invoked. - * Each array element will hold invocation state for 32 features. - * The resource manager utility is utilized to maintain the bit settings. - */ - void *feature_invocation_state; - - /* TRUE if CCM has requested phone to show ringout UI */ - boolean spoof_ringout_requested; - /* TRUE if GSM has applied ringout due to CCMs request to show ringout UI */ - boolean spoof_ringout_applied; - - /* - * save of orientation from callInfo to update UI at any time - * other than during call info. update such as after Tx start in - * order to update security icon. - */ - cc_orientation_e orientation; - - /* - * This boolean is used to short circuit sending UI update requests to the platform - * so that requests are only made when one of the call ui components requires - * updating. The same is done for placed call history. - */ - boolean ui_update_required; - boolean placed_call_update_required; - - boolean is_conf_call; - - cc_security_e security; - cc_policy_e policy; - - boolean dsp_out_of_resources; - - boolean selected; - - boolean select_pending; - - boolean call_not_counted_in_mnc_bt; - - /* - * The media_cap holds the current media caps of the call - */ - cc_media_cap_table_t *media_cap_tbl; - - /* - * Holds the remote stream track information to be passed to UI - */ - cc_media_remote_stream_table_t *remote_media_stream_tbl; - - /* - * Holds the local stream track information passed in from the UI - */ - cc_media_local_track_table_t *local_media_track_tbl; - -#define FSMDEF_F_HOLD_REQ_PENDING (1 << 0)/* hold feature pending */ -#define FSMDEF_F_XFER_COMPLETE (1 << 1)/* hold feature pending */ - uint32_t flags; /* misc. flags. */ - - int log_disp; - - uint8_t cur_video_avail; - sdp_direction_e video_pref; - unsigned int callref; /* Callref (CI) from CUCM */ - - char peerconnection[PC_HANDLE_SIZE]; /* A handle to the peerconnection */ - boolean peerconnection_set; - - char *ice_ufrag; - char *ice_pwd; - boolean peer_ice_lite; - char ice_default_candidate_addr[MAX_IPADDR_STR_LEN]; - - char digest_alg[FSMDEF_MAX_DIGEST_ALG_LEN]; - char digest[FSMDEF_MAX_DIGEST_LEN]; -} fsmdef_dcb_t; - -typedef enum fsm_types_t_ { - FSM_TYPE_MIN = -1, - FSM_TYPE_NONE = FSM_TYPE_MIN, - FSM_TYPE_HEAD, - FSM_TYPE_CNF, - FSM_TYPE_B2BCNF, - FSM_TYPE_XFR, - FSM_TYPE_DEF, - FSM_TYPE_MAX -} fsm_types_t; - -typedef enum fsm_hold_t_ { - FSM_HOLD_MIN = -1, - FSM_HOLD_NONE = 0, - FSM_HOLD_LCL = 1, - FSM_HOLD_MAX = 2 -} fsm_hold_t; - -typedef struct fsm_data_def_t_ { - int hold; -} fsm_data_def_t; - -typedef struct fsm_data_xfr_t_ { - int xfr_id; -} fsm_data_xfr_t; - -typedef struct fsm_data_t_ { - union { - fsm_data_def_t def; - fsm_data_xfr_t xfr; - } data; -} fsm_data_t; - -typedef struct fsmcnf_ccb_t_ { - cc_srcs_t cnf_orig; - int cnf_id; - callid_t cnf_call_id; - callid_t cns_call_id; - line_t cnf_line; - line_t cns_line; - boolean active; - boolean bridged; - -/* The following field encodes flags */ -#define JOINED 0x1 -#define XFER 0x2 -#define LCL_CNF 0x4 - uint32_t flags; - boolean cnf_ftr_ack; -} fsmcnf_ccb_t; - -typedef enum fsmxfr_types_t_ { - FSMXFR_TYPE_MIN = -1, - FSMXFR_TYPE_NONE, - FSMXFR_TYPE_XFR, - FSMXFR_TYPE_BLND_XFR, - FSMXFR_TYPE_DIR_XFR, - FSMXFR_TYPE_MAX -} fsmxfr_types_t; - -typedef enum fsmxfr_modes_t_ { - FSMXFR_MODE_MIN = -1, - FSMXFR_MODE_TRANSFEROR, - FSMXFR_MODE_TRANSFEREE, - FSMXFR_MODE_TARGET -} fsmxfr_modes_t; - -typedef struct fsmdef_candidate_t_ { - sll_lite_node_t node; /* link node, must be first member of struct */ - string_t candidate; /* the candidate value */ -} fsmdef_candidate_t; - -struct fsmxfr_xcb_t_; -typedef struct fsmxfr_xcb_t_ { - cc_srcs_t xfr_orig; - int xfr_id; - callid_t xfr_call_id; - callid_t cns_call_id; - line_t xfr_line; - line_t cns_line; - fsmxfr_types_t type; - cc_xfer_methods_t method; - char *dialstring; - char *queued_dialstring; - char *referred_by; - boolean active; - boolean cnf_xfr; - boolean xfer_comp_req; - fsmxfr_modes_t mode; - struct fsmxfr_xcb_t_ *xcb2; -} fsmxfr_xcb_t; - - -typedef struct fsm_fcb_t_ { - callid_t call_id; - - int state; - int old_state; - - fsm_types_t fsm_type; - - - /* - * fsmdef specific data - */ - fsmdef_dcb_t *dcb; - - /* - * fsmxfr specific data - */ - - fsmxfr_xcb_t *xcb; - /* - * fsmcnf specific data - */ - fsmcnf_ccb_t *ccb; - - /* - * fsmb2bcnf specific data - */ - fsmcnf_ccb_t *b2bccb; - -} fsm_fcb_t; - -typedef enum { - FSMDEF_MSG_MIN = -1, - FSMDEF_MSG_NONE = 0, - FSMDEF_MSG_SETUP = 1, - FSMDEF_MSG_SETUP_ACK = 2, - FSMDEF_MSG_PROCEEDING = 4, - FSMDEF_MSG_ALERTING = 8, - FSMDEF_MSG_CONNECTED = 16, - FSMDEF_MSG_CONNECTED_ACK = 32, - FSMDEF_MSG_RELEASE = 64, - FSMDEF_MSG_RELEASE_COMPLETE = 128, - FSMDEF_MSG_MAX -} fsmdef_msgs_t; - -#define FSM_FOR_ALL_CBS(cb, cbs, max_cbs) \ - for ((cb) = (cbs); (cb) <= &((cbs)[(max_cbs-1)]); (cb)++) - -#define FSM_CHK_FLAGS(flags, flag) ((flags) & (flag)) -#define FSM_SET_FLAGS(flags, flag) ((flags) |= (flag)) -#define FSM_RESET_FLAGS(flags, flag) ((flags) &= ~(flag)) -void *fsmdef_feature_timer_timeout(cc_features_t feature_id, void *); -void fsmdef_end_call(fsmdef_dcb_t *dcb, cc_causes_t cause); -void fsm_sm_ftr(cc_features_t ftr_id, cc_srcs_t src_id); -void fsm_sm_ignore_ftr(fsm_fcb_t *fcb, int fname, - cc_features_t ftr_id); -void fsm_sm_ignore_src(fsm_fcb_t *fcb, int fname, cc_srcs_t src_id); -const char *fsm_state_name(fsm_types_t type, int id); -const char *fsm_type_name(fsm_types_t type); -fsmdef_dcb_t *fsm_get_dcb(callid_t call_id); -void fsm_init_scb(fim_icb_t *icb, callid_t call_id); -fsm_fcb_t *fsm_get_fcb_by_call_id(callid_t call_id); -fsm_fcb_t *fsm_get_fcb_by_call_id_and_type(callid_t call_id, fsm_types_t type); -void -fsm_get_fcb_by_selected_or_connected_call_fcb(callid_t call_id, fsm_fcb_t **con_fcb_found, - fsm_fcb_t **sel_fcb_found); -fsm_fcb_t *fsm_get_new_fcb(callid_t call_id, fsm_types_t fsm_type); -void fsm_init(void); -void fsm_shutdown(void); -void fsm_release(fsm_fcb_t *fcb, int fname, cc_causes_t cause); -void fsm_change_state(fsm_fcb_t *fcb, int fname, int new_state); -void fsm_init_fcb(fsm_fcb_t *fcb, callid_t call_id, fsmdef_dcb_t *dcb, - fsm_types_t type); -void fsm_display_no_free_lines(void); -void fsm_display_use_line_or_join_to_complete(void); -void fsm_display_feature_unavailable(void); -void fsm_set_call_status_feature_unavailable(callid_t call_id, line_t line); - -cc_causes_t fsm_get_new_outgoing_call_context(callid_t call_id, line_t line, - fsm_fcb_t *fcb, boolean expline); -cc_causes_t fsm_get_new_incoming_call_context(callid_t call_id, fsm_fcb_t *fcb, - const char *called_number, - boolean expline); -sm_rcs_t fsmdef_release(fsm_fcb_t *fcb, cc_causes_t cause, - boolean send_release); -int fsmdef_get_call_type_by_call_id(callid_t call_id); -fsmdef_call_types_t fsmdef_get_call_id_by_call_ref(int call_ref); -fsmdef_dcb_t *fsmdef_get_dcb_by_call_id(callid_t call_id); -void fsmdef_init_dcb(fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type, - const char *called_number, line_t line, - fsm_fcb_t *fcb); -cc_causes_t fsm_set_fcb_dcbs (fsmdef_dcb_t *dcb); -fsmdef_dcb_t *fsmdef_get_new_dcb(callid_t call_id); -void fsmdef_init(void); -int fsmdef_get_active_call_cnt(callid_t callId); -fsmdef_dcb_t *fsmdef_get_connected_call(void); -boolean fsmdef_are_join_calls_on_same_line(line_t line); -boolean fsmdef_are_there_selected_calls_onotherline(line_t line); -fsmdef_dcb_t *fsmdef_get_other_dcb_by_line(callid_t call_id, line_t line); -int fsmdef_get_dcbs_in_held_state(fsmdef_dcb_t **dcb, - callid_t ignore_call_id); -sm_rcs_t fsmdef_offhook(fsm_fcb_t *fcb, cc_msgs_t msg_id, callid_t call_id, - line_t line, const char *dial_string, sm_event_t *event, - char *global_call_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode); - -sm_rcs_t fsmdef_dialstring(fsm_fcb_t *fcb, const char *dialstring, - cc_redirect_t *redirect, boolean replace, - cc_call_info_t *call_info); - -fsmcnf_ccb_t *fsmcnf_get_ccb_by_call_id(callid_t call_id); -callid_t fsmcnf_get_other_call_id(fsmcnf_ccb_t *ccb, callid_t call_id); - -void fsmxfr_update_xfr_context(fsmxfr_xcb_t *xcb, callid_t old_call_id, - callid_t new_call_id); -fsmxfr_xcb_t *fsmxfr_get_xcb_by_call_id(callid_t call_id); -callid_t fsmxfr_get_other_call_id(fsmxfr_xcb_t *xcb, callid_t call_id); -fsmxfr_types_t fsmxfr_get_xfr_type(callid_t call_id); -cc_features_t fsmxfr_type_to_feature(fsmxfr_types_t type); - -#ifdef _WIN32 -extern void NotifyStateChange(callid_t callid, int32_t state); -#define NOTIFY_STATE_CHANGE(fcb,callid,state) NotifyStateChange(callid,state);dcsm_update_gsm_state(fcb,callid,state) -#else -#define NOTIFY_STATE_CHANGE(fcb,callid,state) dcsm_update_gsm_state(fcb,callid,state) -#endif - -const char *fsmdef_state_name(int id); -const char *fsmxfr_state_name(int id); -const char *fsmcnf_state_name(int id); - -void fsm_cac_init(void); -void fsmcnf_init(void); -void fsmxfr_init(void); -void fsmdef_init(void); -void fsmcnf_shutdown(void); -void fsmxfr_shutdown(void); -void fsmdef_shutdown(void); -void fsm_cac_shutdown(void); -void fsm_cac_call_release_cleanup(callid_t call_id); - -void fsmdef_reversion_timeout(callid_t call_id); -void fsm_cac_process_bw_fail_timer(void *tmr_data); -void fsmdef_auto_answer_timeout(void *); -const char *fsmb2bcnf_state_name(int id); -void fsmb2bcnf_init(void); -void fsmb2bcnf_shutdown(void); -int fsmutil_is_b2bcnf_consult_call(callid_t call_id); -callid_t fsmxfr_get_consult_call_id(callid_t call_id); -callid_t fsmb2bcnf_get_consult_call_id(callid_t call_id); -callid_t fsmb2bcnf_get_primary_call_id(callid_t call_id); -boolean fsmdef_check_if_ok_for_dial_call(line_t line); -boolean fsmdef_check_if_ok_to_ans_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_resume_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_hold_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_monitor_update_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_run_feature(line_t line, callid_t call_id); -fsmdef_dcb_t *fsmdef_get_dcb_by_call_instance_id(line_t line, - uint16 call_instance_id); -boolean fsmb2bcnf_check_if_ok_to_setup_conf (callid_t call_id); -boolean fsmdef_check_if_chaperone_call_exist (void); -void fsmdef_call_cc_state_dialing(fsmdef_dcb_t *dcb, boolean suppressStutter); -/* This macro is to identify incoming joining call */ -#define fsm_is_joining_call(feat_data) \ - ((feat_data.newcall.join.join_call_id != CC_NO_CALL_ID) && \ - ((feat_data.newcall.cause == CC_CAUSE_BARGE) || \ - (feat_data.newcall.cause == CC_CAUSE_MONITOR))) -/* These macros are for SRTP support */ -#define FSM_GET_SECURITY_STATUS(dcb) (dcb->security) -#define FSM_SET_SECURITY_STATUS(dcb, status) (dcb->security = status) -#define FSM_GET_POLICY(dcb) (dcb->policy) -#define FSM_SET_POLICY(dcb, status) (dcb->policy = status) -#define FSM_GET_CACHED_ORIENTATION(dcb) (dcb->orientation) -#define FSM_SET_CACHED_ORIENTATION(dcb, value) (dcb->orientation = value) -#define FSM_NEGOTIATED_CRYPTO_ALGORITHM_ID(media) \ - ((media->transport == SDP_TRANSPORT_RTPSAVP || \ - media->transport == SDP_TRANSPORT_RTPSAVPF) ? \ - media->negotiated_crypto.algorithmID : VCM_NO_ENCRYPTION) -#define FSM_NEGOTIATED_CRYPTO_RX_KEY(media) \ - &media->negotiated_crypto.rx_key -#define FSM_NEGOTIATED_CRYPTO_TX_KEY(media) \ - &media->negotiated_crypto.tx_key - -#define FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media) \ - media->negotiated_crypto.algorithm - -#define FSM_NEGOTIATED_CRYPTO_DIGEST(media) \ - media->negotiated_crypto.digest - -int fsmutil_get_call_attr(fsmdef_dcb_t *dcb, line_t line, callid_t call_id); -uint16_t fsmutil_get_ci_id(line_t line); -void fsmutil_init_ci_map(void); -void fsmdef_platform_dcb_init(fsmdef_dcb_t *dcb); -void fsmutil_free_all_ci_id(void); -void fsmutil_free_ci_id(uint16_t id, line_t line); -void fsmutil_set_ci_id(uint16_t id, line_t line); -void fsmutil_free_ci_map(void); -void fsmutil_show_ci_map(void); -void fsmutil_init_shown_calls_ci_map(void); -void fsmutil_free_all_shown_calls_ci_map(void); -void fsmutil_clear_shown_calls_ci_element(uint16_t id, line_t line); -void fsmutil_set_shown_calls_ci_element(uint16_t id, line_t line); -boolean fsmutil_is_shown_calls_ci_element_set(uint16_t id, line_t line); - - -callid_t fsmxfr_get_primary_call_id(callid_t call_id); -uint16_t fsmutil_get_num_selected_calls(void); -int fsmutil_is_cnf_consult_call(callid_t call_id); -int fsmutil_is_cnf_consult_leg(callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - uint16_t max_ccbs); -int fsmutil_is_xfr_consult_call(callid_t call_id); -int fsmutil_is_xfr_consult_leg(callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - uint16_t max_xcbs); -void fsmutil_init_groupid(fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type); -void fsmutil_process_feature_ack(fsmdef_dcb_t *dcb, cc_features_t feature_id); -void fsmutil_clear_all_feature_invocation_state(fsmdef_dcb_t *dcb); -void fsmutil_init_feature_invocation_state(fsmdef_dcb_t *dcb); -void fsmutil_free_feature_invocation_state(fsmdef_dcb_t *dcb); - -void fsmdef_error_onhook_timeout(void *data); - -int fsmutil_is_xfr_leg(callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - unsigned short max_xcbs); -int fsmutil_is_cnf_leg(callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - unsigned short max_ccbs); - -void fsm_display_control_ringin_calls(boolean hide); -void fsmdef_update_media_cap_feature_event(cc_feature_t *msg); -boolean fsmcnd_conf_call_id_valid(fsmcnf_ccb_t *ccb); - -boolean fsmdef_check_retain_fwd_info_state(void); - - -pc_error fsmdef_setpeerconnection(fsm_fcb_t *fcb, cc_feature_t *msg); -pc_error fsmdef_createoffer(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam); -pc_error fsmdef_createanswer(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam); -pc_error fsmdef_setlocaldesc(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam); -pc_error fsmdef_setremotedesc(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam); -pc_error fsmdef_addcandidate(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam); -pc_error fsmdef_foundcandidate(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *sdp_outparam, - string_t *error_outparam); -pc_error fsmdef_removestream(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *error_outparam); -pc_error fsmdef_addstream(fsm_fcb_t *fcb, - cc_feature_t *msg, - string_t *error_outparam); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm.h deleted file mode 100755 index 944df9194fc..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm.h +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _GSM_H_ -#define _GSM_H_ - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "cpr_ipc.h" -#include "cpr_stdio.h" - -#define GSM_ERR_MSG(format, ...) CSFLogError("gsm" , format , ## __VA_ARGS__ ) -typedef void(* media_timer_callback_fp) (void); -void gsm_set_media_callback(media_timer_callback_fp* callback); - -void gsm_set_initialized(void); -cpr_status_e gsm_send_msg(uint32_t cmd, cprBuffer_t buf, uint16_t len); -cprBuffer_t gsm_get_buffer(uint16_t size); -boolean gsm_is_idle(void); - -/* - * List of timers that the GSM task is responsible for. - * CPR will send a msg to the GSM task when these - * timers expire. CPR expects a timer id when the timer - * is created, this enum serves that purpose. - */ -typedef enum { - GSM_ERROR_ONHOOK_TIMER, - GSM_AUTOANSWER_TIMER, - GSM_DIAL_TIMEOUT_TIMER, - GSM_KPML_INTER_DIGIT_TIMER, - GSM_KPML_CRITICAL_DIGIT_TIMER, - GSM_KPML_EXTRA_DIGIT_TIMER, - GSM_KPML_SUBSCRIPTION_TIMER, - GSM_MULTIPART_TONES_TIMER, - GSM_CONTINUOUS_TONES_TIMER, - GSM_REQ_PENDING_TIMER, - GSM_RINGBACK_DELAY_TIMER, - GSM_REVERSION_TIMER, - GSM_FLASH_ONCE_TIMER, - GSM_CAC_FAILURE_TIMER, - GSM_TONE_DURATION_TIMER -} gsmTimerList_t; - -/* - * The common code creating the GSM timers needs to have - * access to the gsm_msgq variable since CPR - * needs to know where to send the timer expiration - * message. - */ -extern cprMsgQueue_t gsm_msgq; - -extern void kpml_process_msg(uint32_t cmd, void *msg); -extern void dp_process_msg(uint32_t cmd, void *msg); -extern void kpml_init(void); -extern void kpml_shutdown(void); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h deleted file mode 100644 index ebacbccbc6c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h +++ /dev/null @@ -1,131 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _GSM_SDP_H_ -#define _GSM_SDP_H_ - - -#define GSMSDP_VERSION_STR_LEN (20) - -#define GSMSDP_MEDIA_VALID(media) \ - ((media != NULL) && (media->refid != CC_NO_MEDIA_REF_ID)) - -#define GSMSDP_MEDIA_ENABLED(media) \ - (GSMSDP_MEDIA_VALID(media) && (media->src_port != 0)) - -#define GSMSDP_MEDIA_COUNT(dcb) \ - (SLL_LITE_NODE_COUNT(&dcb->media_list)) - -#define GSMSDP_FIRST_MEDIA_ENTRY(dcb) \ - ((fsmdef_media_t *)SLL_LITE_LINK_HEAD(&dcb->media_list)) - -#define GSMSDP_NEXT_MEDIA_ENTRY(media) \ - ((fsmdef_media_t *)SLL_LITE_LINK_NEXT_NODE(media)) - -#define GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) \ - for (media = start_media; (media != NULL); \ - media = (media != end_media ? \ - GSMSDP_NEXT_MEDIA_ENTRY(media) : NULL)) - -#define GSMSDP_FOR_ALL_MEDIA(media, dcb) \ - for (media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); (media != NULL); \ - media = GSMSDP_NEXT_MEDIA_ENTRY(media)) - -typedef struct { - const char *name; - int value; -} gsmsdp_key_table_entry_t; - -cc_causes_t gsmsdp_create_local_sdp(fsmdef_dcb_t *dcb_p, boolean force_streams_enabled, - boolean audio, boolean video, boolean data, boolean offer); -void gsmsdp_create_options_sdp(cc_sdp_t **sdp_pp); -void gsmsdp_reset_local_sdp_media(fsmdef_dcb_t *dcb, fsmdef_media_t *media, - boolean hold); -void gsmsdp_set_local_sdp_direction(fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, - sdp_direction_e direction); -void gsmsdp_set_local_hold_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media); -void gsmsdp_set_local_resume_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media); -cc_causes_t gsmsdp_negotiate_answer_sdp(fsm_fcb_t *fcb, - cc_msgbody_info_t *msg_body); -cc_causes_t gsmsdp_negotiate_offer_sdp(fsm_fcb_t *fcb, - cc_msgbody_info_t *msg_body, - boolean init); -cc_causes_t gsmsdp_process_offer_sdp(fsm_fcb_t *fcb, - cc_msgbody_info_t *msg_body, - boolean init); -cc_causes_t -gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer, - boolean offer, boolean notify_stream_added, boolean create_answer); - -boolean gsmsdp_sdp_differs_from_previous_sdp(boolean rcv_only, - fsmdef_media_t *media); -cc_causes_t gsmsdp_encode_sdp(cc_sdp_t *sdp_p, cc_msgbody_info_t *msg_body); -cc_causes_t gsmsdp_encode_sdp_and_update_version(fsmdef_dcb_t *dcb_p, - cc_msgbody_info_t *msg_body); -void gsmsdp_free(fsmdef_dcb_t *dcb_p); -fsmdef_media_t *gsmsdp_find_audio_media(fsmdef_dcb_t *dcb_p); - -#define gsmsdp_is_srtp_supported() (TRUE) -extern void gsmsdp_init_sdp_media_transport(fsmdef_dcb_t *dcb, - void *sdp, - fsmdef_media_t *media); -extern void gsmsdp_reset_sdp_media_transport(fsmdef_dcb_t *dcb, - void *sdp, - fsmdef_media_t *media, - boolean hold); -extern sdp_transport_e gsmsdp_negotiate_media_transport(fsmdef_dcb_t *dcb_p, - cc_sdp_t *cc_sdp_p, - boolean offer, - fsmdef_media_t *media, - uint16_t *inst_num, - uint16 level); -extern void gsmsdp_update_local_sdp_media_transport(fsmdef_dcb_t *dcb_p, - void *sdp_p, - fsmdef_media_t *media, - sdp_transport_e transport, - boolean all); -extern void gsmsdp_update_negotiated_transport(fsmdef_dcb_t *dcb_p, - cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, - uint16_t crypto_inst, - sdp_transport_e transport, - uint16 level); -extern void gsmsdp_update_crypto_transmit_key(fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - boolean offer, - boolean initial_offer, - sdp_direction_e direction); -extern void gsmsdp_set_media_transport_for_option(void *sdp, uint16 level); -extern boolean gsmsdp_is_crypto_ready(fsmdef_media_t *media, boolean rx); -extern boolean gsmsdp_is_media_encrypted(fsmdef_dcb_t *dcb_p); -extern boolean gsmsdp_crypto_params_change(boolean rcv_only, - fsmdef_media_t *media); -extern void gsmsdp_crypto_reset_params_change(fsmdef_media_t *media); -extern void gsmsdp_cache_crypto_keys(void); -extern boolean gsmsdp_create_free_media_list(void); -extern void gsmsdp_destroy_free_media_list(void); -extern void gsmsdp_init_media_list(fsmdef_dcb_t *dcb_p); -extern void gsmsdp_clean_media_list(fsmdef_dcb_t *dcb); -extern fsmdef_media_t *gsmsdp_find_media_by_refid(fsmdef_dcb_t *dcb_p, - media_refid_t refid); -extern boolean gsmsdp_handle_media_cap_change(fsmdef_dcb_t *dcb_p, - boolean refresh, boolean hold); -extern boolean gsmsdp_update_local_sdp_media_capability(fsmdef_dcb_t *dcb_p, - boolean refresh, boolean hold); -boolean is_gsmsdp_media_ip_updated_to_latest( fsmdef_dcb_t * dcb ); - -cc_causes_t gsmsdp_check_ice_attributes_exist(fsm_fcb_t *fcb_p); -cc_causes_t gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p); -cc_causes_t gsmsdp_configure_dtls_data_attributes(fsm_fcb_t *fcb_p); -cc_causes_t gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb, const char * mid, uint16_t *level); -void gsmsdp_process_cap_options(fsmdef_dcb_t *dcb, cc_media_options_t* options); -cc_causes_t -gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, boolean *has_video, boolean *has_data); -fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb, sdp_media_e media_type); - -extern void gsmsdp_set_ice_attribute (sdp_attr_e sdp_attr, uint16_t level, - void *sdp_p, char *ice_attrib); - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/lsm.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/lsm.h deleted file mode 100755 index 07b8d3fe72b..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/lsm.h +++ /dev/null @@ -1,181 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LSM_H_ -#define _LSM_H_ - -#include "cpr_types.h" -#include "ccapi.h" -#include "uiapi.h" -#include "fsm.h" - - -#define LSM_NO_LINE (0) -#define LSM_NO_INSTANCE (0) -#define NO_LINES_AVAILABLE (0) - -/* FIXME GS - Breaking my own rule - need to figure out how to do a platform - * specific include file here - */ -#define LSM_MAX_LINES MAX_REG_LINES -#define LSM_MAX_INSTANCES (MAX_CALLS_PER_LINE-1) -#define LSM_MAX_EXP_INSTANCES MAX_CALLS_PER_LINE -#define LSM_MAX_CALLS MAX_CALLS - -#define NO_FREE_LINES_TIMEOUT (10) -#define CALL_ALERT_TIMEOUT (10) - -/* - * Used to play busy verfication tone - */ -#define BUSY_VERIFICATION_DELAY (10000) - -/* - * Temp until added to config - */ -#define TOH_DELAY (10000) - -/* - * Used to play msg waiting and stutter dialtones. - * Both tones are 100ms on/off repeating 10 and - * 3 times respectively, followed by steady dialtone. - * Due to DSP limitations we first tell the DSP to - * play the 100ms on/off pairs the correct number of - * times, set a timer, and then tell it to play dialtone. - */ -#define MSG_WAITING_DELAY (2050) -#define STUTTER_DELAY (650) - -/* - * Used to play the busy verfication tone which - * is two seconds of dialtone followed by the - * callwaiting tone every ten seconds. - */ -#define BUSY_VERIFY_DELAY (12000) - - -/* LSM states */ -typedef enum { - LSM_S_MIN = -1, - LSM_S_NONE = LSM_S_MIN, - LSM_S_IDLE, - LSM_S_PENDING, - LSM_S_OFFHOOK, - LSM_S_ONHOOK, - LSM_S_PROCEED, - LSM_S_RINGOUT, - LSM_S_RINGIN, - LSM_S_CONNECTED, - LSM_S_BUSY, - LSM_S_CONGESTION, - LSM_S_HOLDING, - LSM_S_CWT, - LSM_S_XFER, - LSM_S_ATTN_XFER, - LSM_S_CONF, - LSM_S_INVALID_NUMBER, - LSM_S_MAX -} lsm_states_t; - -boolean lsm_is_phone_idle(void); -int lsm_get_instances_available_cnt(line_t line, boolean expline); -void lsm_increment_call_chn_cnt(line_t line); -void lsm_decrement_call_chn_cnt(line_t line); -line_t lsm_get_newcall_line(line_t line); -callid_t lsm_get_active_call_id(void); -line_t lsm_get_line_by_call_id(callid_t call_id); -/* - * The lsm_get_facility_by_called_number() and the lsm_get_facility_by_line() - * below are defined to allow be used by fsm state mechine to bind the - * LSM to the FSM default state machine only. - */ -cc_causes_t lsm_get_facility_by_called_number(callid_t call_id, - const char *called_number, - line_t *free_line, - boolean expline, void *dcb); -cc_causes_t lsm_get_facility_by_line(callid_t call_id, line_t line, - boolean exp, void *dcb); -char lsm_digit2ch(int digit); -void lsm_set_active_call_id(callid_t call_id); -void lsm_init(void); -void lsm_shutdown(void); -void lsm_reset(void); -void lsm_ui_display_notify(const char *pNotifyStr, unsigned long timeout); -void lsm_ui_display_status(const char *pStatusStr, line_t line, - callid_t call_id); -string_t lsm_parse_displaystr(string_t displaystr); -void lsm_speaker_mode(short mode); -cc_rcs_t lsm_add_remote_stream (line_t line, callid_t call_id, fsmdef_media_t *media, - int *pc_stream_id); - -#ifdef _WIN32 -void terminate_active_calls(void); -#endif - -const char *lsm_state_name(lsm_states_t id); -void lsm_set_cfwd_all_nonccm(line_t line, char *callfwd_dialstring); -void lsm_set_cfwd_all_ccm(line_t line, char *callfwd_dialstring); -void lsm_clear_cfwd_all_nonccm(line_t line); -void lsm_clear_cfwd_all_ccm(line_t line); -int lsm_check_cfwd_all_nonccm(line_t line); -int lsm_check_cfwd_all_ccm(line_t line); -char *lsm_is_phone_forwarded(line_t line); -void lsm_tmr_tones_callback(void *); -void lsm_update_placed_callinfo(void *dcb); -void lsm_start_multipart_tone_timer(vcm_tones_t tone, uint32_t delay, - callid_t callId); -void lsm_start_continuous_tone_timer(vcm_tones_t tone, uint32_t delay, - callid_t callId); -void lsm_start_tone_duration_timer(vcm_tones_t tone, uint32_t delay, - cc_call_handle_t call_handle); -void lsm_stop_multipart_tone_timer(void); -void lsm_stop_continuous_tone_timer(void); -void lsm_stop_tone_duration_timer(void); -void lsm_tone_duration_tmr_callback(void *data); -void lsm_tone_start_with_duration (vcm_tones_t tone, short alert_info, cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction, uint32_t duration); -void lsm_update_active_tone(vcm_tones_t tone, callid_t call_id); -boolean lsm_is_tx_channel_opened(callid_t call_id); -void lsm_update_monrec_tone_action (vcm_tones_t tone, callid_t call_id, uint16_t direction); -void lsm_downgrade_monrec_tone_action(vcm_tones_t tone, callid_t call_id); -char *lsm_get_gdialed_digits(); -void lsm_set_hold_ringback_status(callid_t call_id, boolean ringback_status); - -extern callid_t lsm_get_ui_id(callid_t call_id); -extern cc_call_handle_t lsm_get_ms_ui_call_handle(line_t line, callid_t call_id, callid_t ui_id); -extern void lsm_set_ui_id(callid_t call_id, callid_t ui_id); -extern lsm_states_t lsm_get_state(callid_t call_id); - -extern void lsm_set_lcb_dusting_call(callid_t call_id); -extern void lsm_set_lcb_call_priority(callid_t call_id); -extern boolean lsm_is_it_priority_call(callid_t call_id); -extern void lsm_play_tone(cc_features_t feature_id); -extern boolean lsm_callwaiting(void); -extern void lsm_display_control_ringin_call (callid_t call_id, line_t line, boolean hide); -extern line_t lsm_find_next_available_line(line_t line, boolean same_dn, boolean incoming); -extern line_t lsm_get_available_line (boolean incoming); -extern boolean lsm_is_line_available(line_t line, boolean incoming); -extern void lsm_ui_display_notify_str_index(int str_index); -extern cc_causes_t lsm_allocate_call_bandwidth(callid_t call_id, int sessions); -extern void lsm_update_gcid(callid_t call_id, char * gcid); -extern void lsm_set_lcb_prevent_ringing(callid_t call_id); -extern void lsm_remove_lcb_prevent_ringing(callid_t call_id); -extern void lsm_set_lcb_dialed_str_flag(callid_t call_id); -void lsm_update_video_avail(line_t line, callid_t call_id, int dir); -void lsm_update_video_offered(line_t line, callid_t call_id, int dir); -callid_t lsm_get_callid_from_ui_id (callid_t uid); -void lsm_set_video_mute (callid_t call_id, int mute); -int lsm_get_video_mute (callid_t call_id); -void lsm_set_video_window (callid_t call_id, int flags, int x, int y, int h, int w); -void lsm_get_video_window (callid_t call_id, int *flags, int *x, int *y, int *h, int *w); -boolean lsm_is_kpml_subscribed (callid_t call_id); -void -lsm_util_tone_start_with_speaker_as_backup (vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction); - -void lsm_initialize_datachannel (fsmdef_dcb_t *dcb, fsmdef_media_t *media, int track_id); - -#endif //_LSM_H_ - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/lsm_private.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/lsm_private.h deleted file mode 100644 index 75f7cb4ec45..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/lsm_private.h +++ /dev/null @@ -1,58 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LSM_PRIV_H_ -#define _LSM_PRIV_H_ - -#include "phone_types.h" -#include "ccapi.h" - -#define LSM_ERR_MSG(format, ...) CSFLogError("lsm" , format , ## __VA_ARGS__ ) - -#define LSM_DEFAULT_LINE (1) -#define LSM_DEFAULT_INSTANCE (1) -#define LSM_DEFAULT_PLANE (1) -#define LSM_DEFAULT_SPEAKER (0) - -#define LSM_MAX_LCBS (LSM_MAX_CALLS) - -#define LSM_FLAGS_SECURE_MEDIA (1 << 0) /* encrypted tx media */ -#define LSM_FLAGS_SECURE_MEDIA_UPDATE (1 << 1) /* update secure media icon needed */ -#define LSM_FLAGS_ANSWER_PENDING (1 << 2) /* answer is pending */ -#define LSM_FLAGS_DIALED_STRING (1 << 3) /* dialed a string */ -#define LSM_FLAGS_CALL_PRIORITY_URGENT (1 << 4) -#define LSM_FLAGS_PREVENT_RINGING (1 << 5) -#define LSM_FLAGS_DUSTING (1 << 6) /* the call is a dusting call */ - - -typedef struct lsm_lcb_t_ { - callid_t call_id; - line_t line; - call_events previous_call_event; - lsm_states_t state; - int mru; - boolean enable_ringback; - callid_t ui_id; - uint32_t flags; - fsmdef_dcb_t *dcb; /* the corresponding DCB chain for this lcm */ - char *gcid; /*global call identifier */ - int vid_mute; - int vid_flags; - int vid_x; - int vid_y; - int vid_h; - int vid_w; -} lsm_lcb_t; - -typedef struct lsm_info_t_ { - int call_in_progress; - callid_t active_call_id; - int active_call_plane; - line_t primary_line; - int speaker; -} lsm_info_t; - -lsm_lcb_t *lsm_get_lcb_by_call_id(callid_t call_id); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/sm.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/sm.h deleted file mode 100755 index 840aced0dfc..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/sm.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SM_H_ -#define _SM_H_ - -#include "phone_debug.h" - -typedef enum { - SM_RC_MIN = -2, - SM_RC_ERROR = -1, - SM_RC_SUCCESS, - SM_RC_CONT, - SM_RC_DEF_CONT, - SM_RC_END, - SM_RC_CLEANUP, - SM_RC_FSM_ERROR, - SM_RC_CSM_ERROR, - SM_RC_MAX -} sm_rcs_t; - -typedef struct _sm_event_t { - int state; - int event; - void *data; - void *msg; -} sm_event_t; - -typedef sm_rcs_t (*sm_function_t)(sm_event_t *event); - -typedef struct _sm_table_t { - int min_state; - int max_state; - int min_event; - int max_event; - sm_function_t *table; -} sm_table_t; - -sm_rcs_t sm_process_event(sm_table_t *tbl, sm_event_t *event ); -sm_rcs_t sm_process_event2(int state_id, int event_id, sm_table_t *tbl, - void *msg, void *cb); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c b/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c deleted file mode 100755 index b2af9dc059a..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c +++ /dev/null @@ -1,6553 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_locks.h" -#include "cpr_stdio.h" -#include "cpr_timers.h" -#include "cpr_in.h" -#include "cpr_errno.h" -#include "phone_types.h" -#include "phone.h" -#include "sdp.h" -#include "lsm.h" -#include "phone_debug.h" -#include "fsm.h" -#include "gsm_sdp.h" -#include "vcm.h" -#include "ccsip_pmh.h" -#include "dtmf.h" -#include "debug.h" -#include "rtp_defs.h" -#include "lsm_private.h" -#include "dialplanint.h" -#include "kpmlmap.h" -#include "prot_configmgr.h" -#include "dialplan.h" -#include "sip_interface_regmgr.h" -#include "gsm.h" -#include "phntask.h" -#include "fim.h" -#include "util_string.h" -#include "platform_api.h" - -static const char* logTag = "lsm"; - -#ifndef NO -#define NO (0) -#endif - -#ifndef YES -#define YES (1) -#endif - -#define CALL_INFO_NONE (string_t)"" - -#define FROM_NOTIFY_PRI 1 // Same as SCCP phone behavior -#define LSM_DISPLAY_STR_LEN 256 - -static cc_rcs_t lsm_stop_tone (lsm_lcb_t *lcb, cc_action_data_tone_t *data); - -static lsm_lcb_t *lsm_lcbs; -static uint32_t lsm_call_perline[MAX_REG_LINES]; - -/* This variable is used locally to reflect the CFA state (set/clear) - * when in CCM mode. - */ -static boolean cfwdall_state_in_ccm_mode[MAX_REG_LINES+1] ; - -static const char *lsm_state_names[LSM_S_MAX] = { - "IDLE", - "PENDING", - "OFFHOOK", - "ONHOOK", - "PROCEED", - "RINGOUT", - "RINGIN", - "CONNECTED", - "BUSY", - "CONGESTION", - "HOLDING", - "CWT", - "XFER", - "ATTN_XFER", - "CONF", - "INVALID_NUMBER" -}; - -static const char *cc_state_names[] = { - "OFFHOOK", - "DIALING", - "DIALING_COMPLETED", - "CALL_SENT", - "FAR_END_PROCEEDING", - "FAR_END_ALERTING", - "CALL_RECEIVED", - "ALERTING", - "ANSWERED", - "CONNECTED", - "HOLD", - "RESUME", - "ONHOOK", - "CALL_FAILED", - "HOLD_REVERT", - "STATE_UNKNOWN" -}; - - -static const char *cc_action_names[] = { - "SPEAKER", - "DIAL_MODE", - "MWI", - "MWI_LAMP", - "OPEN_RCV", - "UPDATE_UI", - "MEDIA", - "RINGER", - "LINE_RINGER", - "PLAY_TONE", - "STOP_TONE", - "STOP_MEDIA", - "START_RCV", - "ANSWER_PENDING", - "PLAY_BLF_ALERT_TONE" -}; - -/* names are corresponds to vcm_ring_mode_t structure */ -static const char *vm_alert_names[] = { - "NONE", -// "RINGER_OFF", - "VCM_RING_OFF", - "VCM_INSIDE_RING", - "VCM_OUTSIDE_RING", - "VCM_FEATURE_RING", - "VCM_BELLCORE_DR1", - "VCM_RING_OFFSET", - "VCM_BELLCORE_DR2", - "VCM_BELLCORE_DR3", - "VCM_BELLCORE_DR4", - "VCM_BELLCORE_DR5", - "VCM_BELLCORE_MAX", - "VCM_FLASHONLY_RING", - "VCM_STATION_PRECEDENCE_RING", - "VCM_MAX_RING" -}; - -/* Enum just to make code read better */ -/* the following values must be in sync with the values listed in edcs-387610 */ -typedef enum { - DISABLE = 1, - FLASH_ONLY = 2, - RING_ONCE = 3, - RING = 4, - BEEP_ONLY = 5 -} config_value_type_t; - -cprTimer_t lsm_tmr_tones; -cprTimer_t lsm_continuous_tmr_tones; -cprTimer_t lsm_tone_duration_tmr; -static uint32_t lsm_tmr_tones_ticks; -static int callWaitingDelay; -static int ringSettingIdle; -static int ringSettingActive; - -/* Ring mode set by remote-cc app */ -static cc_rcc_ring_mode_e cc_line_ringer_mode[MAX_REG_LINES+1] = - {CC_RING_DEFAULT}; -// Following data has to be non-stack b/c the way SIP stack uses it. -// It is used by the lsm_is_phone_forwarded() function only. -static char cfwdall_url[MAX_URL_LENGTH]; - -static void lsm_update_inalert_status(line_t line, callid_t call_id, - cc_state_data_alerting_t * data, - boolean notify); -static void lsm_util_start_tone(vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction); - -const char * -lsm_state_name (lsm_states_t id) -{ - if ((id <= LSM_S_MIN) || (id >= LSM_S_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return (lsm_state_names[id]); -} - - -static const char * -cc_state_name (cc_states_t id) -{ - if ((id <= CC_STATE_MIN) || (id >= CC_STATE_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (cc_state_names[id]); -} - - -static const char * -cc_action_name (cc_actions_t id) -{ - if ((id <= CC_ACTION_MIN) || (id >= CC_ACTION_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (cc_action_names[id]); -} - - -char -lsm_digit2ch (int digit) -{ - switch (digit) { - case 0x0: - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - case 0x8: - case 0x9: - return (char)(digit + '0'); - case 0x0e: - return ('*'); - case 0x0f: - return ('#'); - default: - return ('x'); - } -} - - -void -lsm_debug_entry (callid_t call_id, line_t line, const char *fname) -{ - LSM_DEBUG(get_debug_string(LSM_DBG_ENTRY), call_id, line, fname); -} - -static void -lsm_ui_call_state (call_events event, line_t line, lsm_lcb_t *lcb, cc_causes_t cause) -{ - if (lcb->previous_call_event != event) { - lcb->previous_call_event = event; - - /* For local conference case, the second call is hidden - * so do not show that when the call is held, resumed, - * or moved to other state. This should be done only - * when local bridge is active - */ - ui_call_state(event, line, lcb->ui_id, cause); - } - else if(event == evConnected) { - //This is for Chaperone Conference case, if conference changed to a normal call, - //then need to update the call state to refresh the key's status. like re-enable - //Confrn key - ui_call_state(event, line, lcb->ui_id, cause); - } -} - -/** - * This function will control the display of the ringingin call based on the hide arg. - * - * @param[in] call_id - call id - * @param[in] line - line on which call is ringing. - * @param[in] hide - whether to hide or not - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) and (line != 0) - */ -void lsm_display_control_ringin_call (callid_t call_id, line_t line, boolean hide) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - ui_call_state(evRingIn, line, lcb->ui_id, CC_CAUSE_NORMAL); - } -} - -/** - * This function will be invoked by DEF SM to set if it is a dusting call. - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_dusting_call (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_DUSTING); - } -} - -/** - * This function will be invoked by DEF SM to set call priority. - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_call_priority (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_CALL_PRIORITY_URGENT); - } -} - - -/** - * This function sets the LSM_FLAGS_DIALED_STRING bit in lcb->flags - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_dialed_str_flag (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_DIALED_STRING); - } -} - -/** - * This function will be invoked by DEF SM to set gcid in lcb. - * - * @param[in] call_id - GSM call id. - * @param[in] gcid - GCID provided by CUCM. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_update_gcid (callid_t call_id, char * gcid) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - if (lcb->gcid == NULL) { - lcb->gcid = (char *)cpr_malloc(CC_GCID_LEN); - sstrncpy(lcb->gcid, gcid, CC_GCID_LEN); - } - } - -} -/** - * This function will be invoked by DEF SM. - * it will check if there is a RINGIN call - * with the same GCID. If so, it will set a flag to prevent ringing. - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_prevent_ringing (callid_t call_id) -{ - lsm_lcb_t *lcb; - char *gcid; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return; - } - - gcid = lcb->gcid; - if (gcid == NULL) { - return; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"gcid=%s", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, call_id, "lsm_set_lcb_prevent_ringing"), gcid); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->state == LSM_S_RINGIN) { - if ((lcb->gcid != NULL) && (strncmp(gcid, lcb->gcid, CC_GCID_LEN) == 0)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"found ringing call, gcid %s", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, "lsm_set_lcb_prevent_ringing"), gcid); - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_PREVENT_RINGING); - } - break; - } - } -} - -void lsm_remove_lcb_prevent_ringing (callid_t call_id) -{ - lsm_lcb_t *lcb; - char *gcid; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return; - } - - gcid = lcb->gcid; - if (gcid == NULL) { - return; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"gcid=%s", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, call_id, "lsm_remove_lcb_prevent_ringing"), gcid); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->state == LSM_S_RINGIN) { - if ((lcb->gcid != NULL) && (strncmp(gcid, lcb->gcid, CC_GCID_LEN) == 0)) { - //FSM_RESET_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING); - lcb->flags = 0; - LSM_DEBUG(DEB_L_C_F_PREFIX"found ringing call, gcid=%s, lcb->flags=%d.", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, "lsm_remove_lcb_prevent_ringing"), gcid, lcb->flags); - } - break; - } - } -} - -/** - * This function finds if the call is a priority call. - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -boolean lsm_is_it_priority_call (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return FALSE; - } - if (FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_CALL_PRIORITY_URGENT)) { - return TRUE; - } - return FALSE; -} - -/* - * Function: lsm_internal_update_call_info - * - * Parameters: - * lcb - pointer to lsm_lcb_t. - * dcb - pointer to fsmdef_dcb_t. - * - * Description: This is an internal function of LSM for updating call - * information to the UI that is not directly driven by the - * the explicit CALL INFO event from call control. - * - * It is a convenient function that used by some of the - * LSM handling function that needs to update call information - * to the UI during media changes. - * - * Returns: - * None. - * - */ -static void -lsm_internal_update_call_info (lsm_lcb_t *lcb, fsmdef_dcb_t *dcb) -{ - boolean inbound; - calltype_t call_type; - fsmcnf_ccb_t *ccb; - - if ((lcb == NULL) || (dcb == NULL)) { - return; - } - - if (!dcb->ui_update_required) { - return; - } - - /* For local conference, do not update the primary - * call bubbles call-info. Primary call is already - * displaying To conference in this case - * But dcb-> caller_id should be updated to - * refresh the UI when the call is dropped - */ - ccb = fsmcnf_get_ccb_by_call_id(lcb->call_id); - if (ccb && (ccb->flags & LCL_CNF) && (ccb->active) - && (ccb->cnf_call_id == lcb->call_id)) { - return; - } - dcb->ui_update_required = FALSE; - - /* Derive orientation of the call */ - switch (dcb->orientation) { - case CC_ORIENTATION_FROM: - inbound = TRUE; - break; - - case CC_ORIENTATION_TO: - inbound = FALSE; - break; - - default: - /* - * No orientation available, use the direction when call was started - */ - inbound = dcb->inbound; - break; - } - - if ((dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) - && fsmdef_check_retain_fwd_info_state()) { - call_type = (inbound) ? (calltype_t)dcb->call_type:FSMDEF_CALL_TYPE_OUTGOING; - } else { - if (inbound) { - call_type = FSMDEF_CALL_TYPE_INCOMING; - } else { - call_type = FSMDEF_CALL_TYPE_OUTGOING; - } - } - - ui_call_info(dcb->caller_id.calling_name, - dcb->caller_id.calling_number, - dcb->caller_id.alt_calling_number, - dcb->caller_id.display_calling_number, - dcb->caller_id.called_name, - dcb->caller_id.called_number, - dcb->caller_id.display_called_number, - dcb->caller_id.orig_called_name, - dcb->caller_id.orig_called_number, - dcb->caller_id.last_redirect_name, - dcb->caller_id.last_redirect_number, - call_type, - lcb->line, lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - -} - -/** - * The function opens receive channel or allocates receive port. It depends - * on the "keep" member of the cc_action_data_open_rcv_t structure set - * up by the caller to whether opens a receive channel or just - * to allocate a receive port. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in/out] data - pointer to the cc_action_data_open_rcv_t. - * Upon a successful return, the port element - * of this structure will be filled with the actual - * receive port. - * @param[in] media - pointer to the fsmdef_media_t if a specific - * media to be operated on. - * - * @return CC_RC_ERROR or CC_RC_SUCCESS. - * - * @pre (lcb is_not NULL) and (data is_not NULL) - */ -static cc_rcs_t -lsm_open_rx (lsm_lcb_t *lcb, cc_action_data_open_rcv_t *data, - fsmdef_media_t *media) -{ - static const char fname[] = "lsm_open_rx"; - int port_allocated = 0; - cc_rcs_t rc = CC_RC_ERROR; - fsmdef_dcb_t *dcb; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (rc); - } - - /* - * P2: At this point, it is a guess that refid from media structure - * may be needed. If it turns out to be not the case, then the - * code below that looks up media should be removed including - * the media parameter that is passed in. - */ - if (media == NULL) { - /* no explicit media parameter specified, look up based on refID */ - if (data->media_refid != CC_NO_MEDIA_REF_ID) { - media = gsmsdp_find_media_by_refid(dcb, - data->media_refid); - } - if (media == NULL) { - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, - lcb->line, fname, "no media refID %d found", - data->media_refid); - return (rc); - } - } - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, fname, - "requested port", data->port); - - - sdpmode = 0; - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (data->keep == TRUE) { - if (sdpmode && strlen(dcb->peerconnection)) { - /* If we are doing ICE, don't try to re-open */ - port_allocated = data->port; - } - else { - //Todo IPv6: Add interface call for IPv6 - (void) vcmRxOpen(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), data->port, - media->is_multicast ? &media->dest_addr:&media->src_addr, data->is_multicast, - &port_allocated); - } - if (port_allocated != -1) { - data->port = (uint16_t)port_allocated; - rc = CC_RC_SUCCESS; - } - } else { - - if (sdpmode) { - if (!strlen(dcb->peerconnection)) { - vcmRxAllocPort(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), - data->port, - &port_allocated); - if (port_allocated != -1) { - data->port = (uint16_t)port_allocated; - rc = CC_RC_SUCCESS; - } - } else { - char **candidates; - int candidate_ct; - char *default_addr; - short status; - - status = vcmRxAllocICE(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), - dcb->peerconnection, - media->level, - &default_addr, &port_allocated, - &candidates, &candidate_ct); - - if (!status) { - sstrncpy(dcb->ice_default_candidate_addr, default_addr, sizeof(dcb->ice_default_candidate_addr)); - cpr_free(default_addr); - - data->port = (uint16_t)port_allocated; - media->candidate_ct = candidate_ct; - media->candidatesp = candidates; - rc = CC_RC_SUCCESS; - } - } - } - } - - if (rc == CC_RC_SUCCESS) { - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, fname, - "allocated port", port_allocated); - } - - return (rc); -} -/* - * This function updates the dscp value based on whether video is enable or not - * and video is active or not. - * @param[in] dcb - pointer to the fsmdef_dcb. - */ - -void lsm_update_dscp_value(fsmdef_dcb_t *dcb) -{ - static const char fname[] = "lsm_update_dscp_value"; - int dscp = 184; /* default 184 used for DSCP */ - // depending upon video is enabled or disabled ,set the dscp value. - if (dcb != NULL && dcb->cur_video_avail != SDP_DIRECTION_INACTIVE ) { - config_get_value(CFGID_DSCP_VIDEO, (int *)&dscp, sizeof(dscp)); - } else { - config_get_value(CFGID_DSCP_AUDIO, (int *)&dscp, sizeof(dscp)); - } - // We would use DSCP for video for both audio and video streams if this is a video call - if (dcb != NULL) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Setting dscp=%d for Rx group_id=%d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), dscp, dcb->group_id); - vcmSetRtcpDscp(dcb->group_id, dscp); - } -} - -/** - * The function closes receive channel for a given media entry. - * The receive channel may not be closed if the caller intents to - * fresh the channel i.e close if needed but otherwise leave it open. - * When the caller indicates refreshing, the receive channel - * will be closed only when there is a difference in current SDP and - * the previous SDP. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] refresh - channel to be refreshed i.e. close if necessary. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ -static void -lsm_close_rx (lsm_lcb_t *lcb, boolean refresh, fsmdef_media_t *media) -{ - static const char fname[] = "lsm_close_rx"; - fsmdef_media_t *start_media, *end_media; - fsmdef_dcb_t *dcb; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"Called with refresh set to %d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), refresh); - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* close receive port on the media(s) */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (media->rcv_chan) { - /* - * If caller is releasing the port or if the caller is - * recycling the receive port and the codec has changed, close the - * receive port. Also stop bridging of media streams. - */ - if (!refresh || - (refresh && - gsmsdp_sdp_differs_from_previous_sdp(TRUE, media))) { - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), dcb->call_id, - dcb->line, fname, "port closed", - media->src_port); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - - vcmRxClose(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - } - media->rcv_chan = FALSE; - } - } - } -} - -/** - * The function closes transmit channel for a given media entry. - * The transmit channel may not be closed if the caller intents to - * fresh the port i.e close if needed but otherwise leave it open. - * When the caller indicates refreshing, the transmit channel - * will be closed only when there is a difference in current SDP and - * the previous SDP. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] refresh - channel to be refreshed i.e. close if necessary. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ -static void -lsm_close_tx (lsm_lcb_t *lcb, boolean refresh, fsmdef_media_t *media) -{ - fsmdef_media_t *start_media, *end_media; - fsmdef_dcb_t *dcb; - static const char fname[] = "lsm_close_tx"; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - LSM_DEBUG(DEB_L_C_F_PREFIX"called with refresh set to %d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), refresh); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* - * Close the RTP, but only if this call is using it and the capabilities - * have changed. - */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (media->xmit_chan == TRUE) { - - if (!refresh || - (refresh && - gsmsdp_sdp_differs_from_previous_sdp(FALSE, media))) { - - if (!sdpmode) { - vcmTxClose(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - } - - if (dcb->active_tone == VCM_MONITORWARNING_TONE || dcb->active_tone == VCM_RECORDERWARNING_TONE) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Found active_tone: %d being played, current monrec_tone_action: %d. Need stop tone.", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, - dcb->active_tone, dcb->monrec_tone_action); - (void) lsm_stop_tone(lcb, NULL); - } - media->xmit_chan = FALSE; - LSM_DEBUG(DEB_L_C_F_PREFIX"closed", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname)); - } - } - } -} - -/** - * The function starts receive channel for a given media entry. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] fname - pointer to to const. char for the name - * of the function that calls to this function. - * It is for debuging purpose. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ -static void -lsm_rx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media) -{ - static const char fname1[] = "lsm_rx_start"; - cc_action_data_open_rcv_t open_rcv; - uint16_t port; - groupid_t group_id = CC_NO_GROUP_ID; - callid_t call_id = lcb->call_id; - vcm_mixing_mode_t mix_mode = VCM_NO_MIX; - vcm_mixing_party_t mix_party = VCM_PARTY_NONE; - int ret_val; - fsmdef_media_t *start_media, *end_media; - boolean has_checked_conference = FALSE; - fsmdef_dcb_t *dcb, *grp_id_dcb; - vcm_mediaAttrs_t attrs; - int sdpmode = 0; - int pc_stream_id = 0; - int pc_track_id = 0; - attrs.video.opaque = NULL; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - group_id = dcb->group_id; - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* Start receive channel for the media(s) */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not enabled */ - continue; - } - - /* - * Check to see if the receive port can be opened. - * For SRTP, the receive can not be opened if the remote's crypto - * parameters are not received yet. - */ - if (media->type != SDP_MEDIA_APPLICATION && - !gsmsdp_is_crypto_ready(media, TRUE)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Not ready to open receive port (%d)", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname, media->src_port); - continue; - } - - /* TODO(ekr@rtfm.com): Needs changing for when we - have > 2 streams. (adam@nostrum.com): For now, - we use all the same stream so pc_stream_id == 0 - and the tracks are assigned in order and are - equal to the level in the media objects bug 1056650 */ - /* See also ReplaceTrack in PeerConnectionMedia.cpp */ - /* Possible solution is a map from MediaStreamTrack->GetTrackID to this, or - to find a way to make them match */ - pc_stream_id = 0; - // note: not a TrackID! (on receive, we may use it to create a TrackID though) - pc_track_id = media->level; - - /* - * Open the RTP receive channel if it is not already open. - */ - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), dcb->call_id, dcb->line, - fname1, "rcv chan", media->rcv_chan); - if (media->rcv_chan == FALSE) { - - memset(&open_rcv, 0, sizeof(open_rcv)); - port = media->src_port; - - if (media->is_multicast && - (media->direction == SDP_DIRECTION_RECVONLY)) { - open_rcv.is_multicast = media->is_multicast; - open_rcv.listen_ip = media->dest_addr; - port = media->multicast_port; - } - open_rcv.port = port; - open_rcv.keep = TRUE; - open_rcv.media_type = media->type; - - if (!has_checked_conference) { - switch(dcb->session) - { - case WHISPER_COACHING: - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_TxBOTH_RxNONE; - grp_id_dcb = fsmdef_get_dcb_by_call_id(dcb->join_call_id); - if (grp_id_dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - } else { - group_id = grp_id_dcb->group_id; - } - break; - - case MONITOR: - case LOCAL_CONF: - //AgentGreeting is MIX RXBOTH, SilentMonitoring is MIX TXBOTH - //so we have to use VCM_PARTY_BOTH for case MONITOR - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_BOTH; - break; - case PRIMARY: - default: - mix_mode = VCM_NO_MIX; - mix_party = VCM_PARTY_NONE; - break; - } - has_checked_conference = TRUE; - } - - if (lsm_open_rx(lcb, &open_rcv, media) != CC_RC_SUCCESS) { - LSM_ERR_MSG(LSM_L_C_F_PREFIX"%s: open receive port (%d) failed.", - dcb->line, dcb->call_id, fname1, - fname, media->src_port); - } else { - /* successful open receive channel */ - media->rcv_chan = TRUE; /* recevied channel is created */ - /* save the source RX port */ - if (media->is_multicast) { - media->multicast_port = open_rcv.port; - } else { - media->src_port = open_rcv.port; - } - - attrs.rtcp_mux = media->rtcp_mux; - - attrs.is_video = FALSE; - attrs.bundle_level = 0; - attrs.bundle_stream_correlator = 0; - attrs.num_ssrcs = 0; - attrs.num_unique_payload_types = 0; - /* TODO(bcampen@mozilla.com): Bug 784491: Fill in - * attrs.bundle_stream_correlator, attrs.ssrcs, and - * attrs.unique_payload_types - */ - - if ( media->cap_index == CC_VIDEO_1 ) { - attrs.is_video = TRUE; - attrs.video.opaque = media->video; - } else { - attrs.audio.packetization_period = media->packetization_period; - attrs.audio.max_packetization_period = media->max_packetization_period; - attrs.audio.avt_payload_type = media->avt_payload_type; - attrs.audio.mixing_mode = mix_mode; - attrs.audio.mixing_party = mix_party; - } - dcb->cur_video_avail &= ~CC_ATTRIB_CAST; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (dcb->peerconnection) { - ret_val = vcmRxStartICE(media->cap_index, group_id, media->refid, - media->level, - pc_stream_id, - pc_track_id, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - dcb->peerconnection, - media->num_payloads, - media->payloads, - media->setup, - FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media), - FSM_NEGOTIATED_CRYPTO_DIGEST(media), - &attrs); - } else if (!sdpmode) { - if (media->payloads == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - ret_val = vcmRxStart(media->cap_index, group_id, media->refid, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - media->payloads, - media->is_multicast ? &media->dest_addr:&media->src_addr, - port, - FSM_NEGOTIATED_CRYPTO_ALGORITHM_ID(media), - FSM_NEGOTIATED_CRYPTO_RX_KEY(media), - &attrs); - if (ret_val == -1) { - dcb->dsp_out_of_resources = TRUE; - return; - } - } else { - ret_val = CC_RC_ERROR; - } - - lsm_update_dscp_value(dcb); - - if (dcb->play_tone_action == FSMDEF_PLAYTONE_ZIP) - { - vcm_tones_t tone = VCM_ZIP; - uint16_t direction = dcb->tone_direction; - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Found play_tone_action: %d. Need to play tone.", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, dcb->play_tone_action); - - // reset to initialized values - dcb->play_tone_action = FSMDEF_PLAYTONE_NO_ACTION; - dcb->tone_direction = VCM_PLAY_TONE_TO_EAR; - - lsm_util_tone_start_with_speaker_as_backup(tone, VCM_ALERT_INFO_OFF, - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - direction); - } - } - } - - if (media->type == SDP_MEDIA_APPLICATION) { - /* Enable datachannels - Datachannels are always two-way so initializing only here in rx_start. - */ - lsm_initialize_datachannel(dcb, media, pc_track_id); - } - } -} - -/** - * The function starts transmit channel for a given media entry. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] fname - pointer to to const. char for the name - * of the function that calls to this function. - * It is for debuging purpose. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ - -#define LSM_TMP_VAD_LEN 64 - -static void -lsm_tx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media) -{ - static const char fname1[] = "lsm_tx_start"; - int dscp = 184; /* default 184 used for DSCP */ - char tmp[LSM_TMP_VAD_LEN]; - fsmcnf_ccb_t *ccb = NULL; - groupid_t group_id; - callid_t call_id = lcb->call_id; - vcm_mixing_mode_t mix_mode = VCM_NO_MIX; - vcm_mixing_party_t mix_party = VCM_PARTY_NONE; - fsmdef_media_t *start_media, *end_media; - boolean has_checked_conference = FALSE; - fsmdef_dcb_t *dcb; - vcm_mediaAttrs_t attrs; - int sdpmode; - long strtol_result; - char *strtol_end; - - attrs.video.opaque = NULL; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - // Set the DSCP value for RTP stream. - if ( media != NULL ){ - // We would use DSCP for video for both audio and video streams if this - // is a video call - if ( dcb->cur_video_avail != SDP_DIRECTION_INACTIVE ) { - config_get_value(CFGID_DSCP_VIDEO, (int *)&dscp, sizeof(dscp)); - } else if ( CC_IS_AUDIO(media->cap_index)){ - // audio stream for audio only call shall use the DSCP for audio - // value. - config_get_value(CFGID_DSCP_AUDIO, (int *)&dscp, sizeof(dscp)); - } - } - group_id = dcb->group_id; - LSM_DEBUG(DEB_L_C_F_PREFIX"invoked", DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1)); - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* Start receive channel for the media(s) */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not enabled */ - continue; - } - /* - * Check to see if the transmit port can be opened. - * For SRTP, the transmit port can not be opened if the remote's crypto - * parameters are not received yet. - */ - if (!gsmsdp_is_crypto_ready(media, FALSE)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Not ready to open transmit port", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - continue; - } - if (media->xmit_chan == FALSE && dcb->remote_sdp_present && - media->dest_addr.type != CPR_IP_ADDR_INVALID && media->dest_port) { - - /* evaluate the mode and group id once for all media entries */ - if (!has_checked_conference) { - switch(dcb->session) - { - case WHISPER_COACHING: - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_TxBOTH_RxNONE; - group_id = fsmdef_get_dcb_by_call_id(dcb->join_call_id)->group_id; - break; - - case MONITOR: - case LOCAL_CONF: - //AgentGreeting is MIX RXBOTH, SilentMonitoring is MIX TXBOTH - //so we have to use VCM_PARTY_BOTH for case MONITOR - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_BOTH; - break; - case PRIMARY: - default: - mix_mode = VCM_NO_MIX; - mix_party = VCM_PARTY_NONE; - break; - } - has_checked_conference = TRUE; - } - - /* - * Set the VAD value. - */ - /* can't use vad on conference calls - the dsp can't handle it. */ - ccb = fsmcnf_get_ccb_by_call_id(lcb->call_id); - if (ccb != NULL) { - media->vad = VCM_VAD_OFF; - } else { - config_get_string(CFGID_ENABLE_VAD, tmp, sizeof(tmp)); - - errno = 0; - - strtol_result = strtol(tmp, &strtol_end, 10); - - if (errno || tmp == strtol_end || - strtol_result < VCM_VAD_OFF || strtol_result > VCM_VAD_ON) { - LSM_ERR_MSG("%s parse error of vad: %s", __FUNCTION__, tmp); - return; - } - - media->vad = (vcm_vad_t) strtol_result; - } - - /* - * Open the transmit port and start sending, but only if we have - * the SDP for the remote end. - */ - - sdpmode = 0; - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - - if (vcmTxOpen(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)) != 0) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxOpen failed", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - continue; - } - } - media->xmit_chan = TRUE; - attrs.mute = FALSE; - attrs.rtcp_mux = media->rtcp_mux; - attrs.audio_level = media->audio_level; - attrs.audio_level_id = (uint8_t)media->audio_level_id; - attrs.is_video = FALSE; - attrs.bundle_level = 0; - attrs.bundle_stream_correlator = 0; - attrs.num_ssrcs = 0; - attrs.num_unique_payload_types = 0; - /* TODO(bcampen@mozilla.com): Bug 784491: Fill in - * attrs.bundle_stream_correlator, attrs.ssrcs, and - * attrs.unique_payload_types - */ - - if ( CC_IS_VIDEO(media->cap_index)) { - attrs.is_video = TRUE; - attrs.video.opaque = media->video; - if (lcb->vid_mute) { - attrs.mute = TRUE; - } - - } else if ( CC_IS_AUDIO(media->cap_index)){ - attrs.audio.packetization_period = media->packetization_period; - attrs.audio.max_packetization_period = media->max_packetization_period; - attrs.audio.avt_payload_type = media->avt_payload_type; - attrs.audio.vad = media->vad; - attrs.audio.mixing_mode = mix_mode; - attrs.audio.mixing_party = mix_party; - } - - dcb->cur_video_avail &= ~CC_ATTRIB_CAST; - - if (media->payloads == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - if (!strlen(dcb->peerconnection)){ - if (vcmTxStart(media->cap_index, group_id, - media->refid, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - media->payloads, - (short)dscp, - &media->src_addr, - media->src_port, - &media->dest_addr, - media->dest_port, - FSM_NEGOTIATED_CRYPTO_ALGORITHM_ID(media), - FSM_NEGOTIATED_CRYPTO_TX_KEY(media), - &attrs) == -1) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxStart failed", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - dcb->dsp_out_of_resources = TRUE; - return; - } - } - else { - if (vcmTxStartICE(media->cap_index, group_id, - media->refid, - media->level, - /* TODO(emannion): his perhaps needs some error checking for validity. - See gsmsdp_get_media_cap_entry_by_index. */ - dcb->media_cap_tbl->cap[media->cap_index].pc_stream, - dcb->media_cap_tbl->cap[media->cap_index].pc_track, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - dcb->peerconnection, - media->payloads, - (short)dscp, - media->setup, - FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media), - FSM_NEGOTIATED_CRYPTO_DIGEST(media), - &attrs) == -1) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxStartICE failed", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - dcb->dsp_out_of_resources = TRUE; - return; - } - } - - lsm_update_dscp_value(dcb); - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxStart started", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - - if ( dcb->monrec_tone_action != FSMDEF_MRTONE_NO_ACTION) - { - vcm_tones_t tone = VCM_NO_TONE; - uint16_t direction = VCM_PLAY_TONE_TO_EAR; - boolean play_both_tones = FALSE; - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Found monrec_tone_action: %d. Need to restart playing tone.", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, dcb->monrec_tone_action); - - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - tone = VCM_MONITORWARNING_TONE; - direction = dcb->monitor_tone_direction; - break; - - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - tone = VCM_RECORDERWARNING_TONE; - direction = dcb->recorder_tone_direction; - break; - - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - play_both_tones = TRUE; - tone = VCM_MONITORWARNING_TONE; - direction = dcb->monitor_tone_direction; - break; - - default: - break; - } - - if (play_both_tones == TRUE) { - lsm_util_tone_start_with_speaker_as_backup(VCM_RECORDERWARNING_TONE, VCM_ALERT_INFO_OFF, - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->recorder_tone_direction); - } - - lsm_util_tone_start_with_speaker_as_backup(tone, VCM_ALERT_INFO_OFF, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - direction); - } - } - } -} - - -static cc_rcs_t -lsm_start_tone (lsm_lcb_t *lcb, cc_action_data_tone_t *data) -{ - callid_t call_id = lcb->call_id; - fsmdef_media_t *media; - - if (lcb->dcb == NULL) { - /* No dcb to work with */ - return (CC_RC_ERROR); - } - media = gsmsdp_find_audio_media(lcb->dcb); - - lsm_util_start_tone(data->tone, VCM_ALERT_INFO_OFF, lsm_get_ms_ui_call_handle(lcb->line, call_id, CC_NO_CALL_ID), lcb->dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - - return (CC_RC_SUCCESS); -} - -static cc_rcs_t -lsm_stop_tone (lsm_lcb_t *lcb, cc_action_data_tone_t *data) -{ - /* NOTE: For now, ignore data input parameter that may contain the tone type. - * We'll check active_tone in the dcb for the call_id and see if there - * is a valid tone playing. If so, then and only then issue tone stop. - */ - static const char fname[] = "lsm_stop_tone"; - callid_t call_id; - fsmdef_dcb_t *dcb; - - if (lcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"NULL lcb passed", DEB_F_PREFIX_ARGS(LSM, fname)); - return (CC_RC_ERROR); - } - call_id = lcb->call_id; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX" NULL dcb passed for call_id = %d", DEB_F_PREFIX_ARGS(LSM, fname), call_id); - return (CC_RC_ERROR); - } - - /* for tnp do call stop only if active_tone is other than VCM_NO_TONE */ - if (dcb->active_tone != VCM_NO_TONE) { - fsmdef_media_t *media = gsmsdp_find_audio_media(lcb->dcb); - vcmToneStop(dcb->active_tone, dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - /* - * Both periodic tones, recording and monitoring, can be active at the - * same time. And because we only keep track of last tone, requested to - * play, through active_tone, so when the tone to be stopped is of - * periodic type, then it could be that both type of periodic tones - * could be playing and both should be stopped. If the second periodic - * tone is not playing then media server will ignore the stop request. - */ - if (dcb->active_tone == VCM_RECORDERWARNING_TONE || - dcb->active_tone == VCM_MONITORWARNING_TONE) - { - vcmToneStop(dcb->active_tone == VCM_RECORDERWARNING_TONE ? - VCM_MONITORWARNING_TONE : VCM_RECORDERWARNING_TONE, - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - - /* in case need to play back the tone again when tx channel active */ - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_MONITOR_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_RECORDER_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_BOTH_TONES; - break; - - default: - break; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Setting monrec_tone_action: %d so resume to play correct tone.", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, - dcb->monrec_tone_action); - } - dcb->active_tone = VCM_NO_TONE; - } else { - LSM_DEBUG(DEB_L_C_F_PREFIX"Ignoring tone stop request", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname)); - } - - return (CC_RC_SUCCESS); -} - -/* - * Function - * - * @param[in] tone - tone type - * @param[in] alert_info - alertinfo header - * @param[in] call_handle- call handle - * @param[in] direction - network, speaker, both - * @param[in] duration - length of time for tone to be played - * - * @return none - */ -void -lsm_tone_start_with_duration (vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction, - uint32_t duration) -{ - - static const char *fname = "lsm_tone_start_with_duration"; - - DEF_DEBUG(DEB_L_C_F_PREFIX"tone=%-2d: direction=%-2d duration=%-2d", - DEB_L_C_F_PREFIX_ARGS(LSM, GET_LINE_ID(call_handle), GET_CALL_ID(call_handle), fname), - tone, direction, duration); - - /* - * play the tone. audio path is always set by MSUI module. - */ - vcmToneStart (tone, alert_info, call_handle, group_id, stream_id, direction); - - lsm_update_active_tone (tone, GET_CALL_ID(call_handle)); - - lsm_start_tone_duration_timer (tone, duration, call_handle); -} - -/* - * Function: lsm_get_used_instances_cnt - * - * @param line - line number - * - * Description: find the number of used instances for this particular line - * - * @return number of used instances - * - */ -int lsm_get_used_instances_cnt (line_t line) -{ - static const char fname[] = "lsm_get_used_instances_cnt"; - int used_instances = 0; - lsm_lcb_t *lcb; - - if (!sip_config_check_line(line)) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)", fname, line); - - return (-1); - } - - /* - * Count home many instances are already in use for this particular line. - */ - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - (lcb->line == line) && - (lcb->state != LSM_S_IDLE)) { - used_instances++; - } - } - - return (used_instances); -} - -/* - * Function: lsm_get_all_used_instances_cnt - * - * Description: find the number of used instances for all lines - * - * @return number of used instances for all lines - * - */ -int lsm_get_all_used_instances_cnt () -{ - int used_instances = 0; - lsm_lcb_t *lcb; - - /* - * Count home many instances are already in use for all lines. - */ - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - (lcb->state != LSM_S_IDLE)) { - used_instances++; - } - } - - return (used_instances); -} - -/* - * Function: lsm_increment_call_chn_cnt - * - * @param line - line number - * - * Description: - * - * @return none - * - */ -void lsm_increment_call_chn_cnt (line_t line) -{ - if ( line <=0 || line > MAX_REG_LINES ) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)", __FUNCTION__, line); - return; - } - lsm_call_perline[line-1]++; - - LSM_DEBUG(DEB_F_PREFIX"number of calls on line[%d]=%d", - DEB_F_PREFIX_ARGS(LSM, __FUNCTION__), - line, lsm_call_perline[line-1]); -} - -/* - * Function: lsm_decrement_call_chn_cnt - * - * @param line - line number - * - * Description: - * - * @return none - * - */ -void lsm_decrement_call_chn_cnt (line_t line) -{ - if ( line <=0 || line > MAX_REG_LINES ) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)", __FUNCTION__, line); - return; - } - - lsm_call_perline[line-1]--; - - LSM_DEBUG(DEB_F_PREFIX"number of calls on line[%d]=%d", - DEB_F_PREFIX_ARGS(LSM, __FUNCTION__), - line, lsm_call_perline[line-1]); -} - -#define NO_ROLLOVER 0 -#define ROLLOVER_ACROSS_SAME_DN 1 -#define ROLLOVER_NEXT_AVAILABLE_LINE 2 - -/* - * Function: lsm_find_next_available_line - * - * @param line - line number - * @param same_dn - whether lines with same DN to be looked at. - * @param incoming - whether we are looking for an available line for an anticipated incoming call. - * - * Description: - * - * - * @return found line number - * - */ -line_t lsm_find_next_available_line (line_t line, boolean same_dn, boolean incoming) -{ - char current_line_dn_name[MAX_LINE_NAME_SIZE]; - char dn_name[MAX_LINE_NAME_SIZE]; - uint32_t line_feature; - line_t i, j; - - config_get_line_string(CFGID_LINE_NAME, current_line_dn_name, line, sizeof(current_line_dn_name)); - /* This line has exhausted its limit, start rollover */ - /* First, search the lines on top of the current one */ - for (i=line+1; i <= MAX_REG_LINES; i++) { - config_get_line_value(CFGID_LINE_FEATURE, &line_feature, sizeof(line_feature), i); - - /* if it is not a DN, skip it */ - if (line_feature != cfgLineFeatureDN) { - continue; - } - - if (same_dn == TRUE) { - config_get_line_string(CFGID_LINE_NAME, dn_name, i, sizeof(dn_name)); - /* Does this line have the same DN */ - if (cpr_strcasecmp(dn_name, current_line_dn_name) == 0) { - return (i); - } - } else { - return (i); - } - } - /* - * We went up to the top and couldn't find an available line, - * start from line 1 and search up to the current line, thus - * we are treating the available lines as a circular pool - */ - - for (j=1; j <= line; j++) { - config_get_line_value(CFGID_LINE_FEATURE, &line_feature, sizeof(line_feature), j); - - /* if it is not a DN, skip it */ - if (line_feature != cfgLineFeatureDN) { - continue; - } - - if (same_dn == TRUE) { - config_get_line_string(CFGID_LINE_NAME, dn_name, j, sizeof(dn_name)); - /* Does this line have the same DN */ - if (cpr_strcasecmp(dn_name, current_line_dn_name) == 0) { - return (j); - } - } else { - return (j); - } - } - - return (NO_LINES_AVAILABLE); -} -/* - * Function: lsm_get_newcall_line - * - * @param line - line number - * - * Description: find out a line that has room to make a - * new call based on the rollover settings - * - * @return found line number - * - */ -line_t lsm_get_newcall_line (line_t line) -{ - return line; -} - -/* - * Function: lsm_get_available_line - * - * @param incoming - whether we are looking for an available line for an anticipated incoming call. - * - * Description: find out a line that has room to make a - * new call starting from the first line. - * - * @return found line number - * - */ -line_t lsm_get_available_line (boolean incoming) -{ - return 1; -} - -/* - * Function: lsm_is_line_available_for_outgoing_call - * - * @param line - * @param incoming - whether we are looking for an available line for an anticipated incoming call. - * - * Description: find out if the line has room to make a new call - * - * @return TRUE/FALSE - * - */ -boolean lsm_is_line_available (line_t line, boolean incoming) -{ - return TRUE; -} - -/* - * lsm_get_instances_available_cnt - * - * return the number of available instances for this particular line - * - * NOTE: The function can return negative values, which the user should read - * as no available lines. - */ -int -lsm_get_instances_available_cnt (line_t line, boolean expline) -{ - static const char fname[] = "lsm_get_instances_available_cnt"; - int max_instances; - int used_instances = 0; - int free_instances; - - if (!sip_config_check_line(line)) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)", fname, line); - - return (-1); - } - - used_instances = lsm_get_used_instances_cnt(line); - - max_instances = (expline) ? (LSM_MAX_EXP_INSTANCES) : (LSM_MAX_INSTANCES); - - free_instances = max_instances - used_instances; - - if(free_instances > 0){ - int all_used_instances = lsm_get_all_used_instances_cnt(); - int all_max_instances = (expline) ? (LSM_MAX_CALLS) : (LSM_MAX_CALLS - 1); - int all_free_instances = all_max_instances - all_used_instances; - free_instances = ((free_instances < all_free_instances) ? free_instances : all_free_instances); - LSM_DEBUG("lsm_get_instances_available_cnt: line=%d, expline=%d, free=%d, all_used=%d, all_max=%d, all_free=%d", - line, expline, free_instances, all_used_instances, all_max_instances, all_free_instances); - - } - LSM_DEBUG("lsm_get_instances_available_cnt: line=%d, expline=%d, free_instances=%d", - line, expline, free_instances); - return (free_instances); -} - - -static void -lsm_init_lcb (lsm_lcb_t *lcb) -{ - lcb->call_id = CC_NO_CALL_ID; - lcb->line = LSM_NO_LINE; - lcb->previous_call_event = evMaxEvent; - lcb->state = LSM_S_IDLE; - lcb->mru = 0; - lcb->enable_ringback = TRUE; - lcb->flags = 0; - lcb->dcb = NULL; - lcb->gcid = NULL; - lcb->vid_flags = 0; //set to not visible - lcb->ui_id = CC_NO_CALL_ID; -} - -/** - * Return the port back to Media service component - * @param [in] lcb - lsm control block - * - */ -static void lsm_release_port (lsm_lcb_t *lcb) -{ - static const char fname[] = "lsm_release_port"; - fsmdef_media_t *start_media, *end_media; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - LSM_DEBUG(DEB_L_C_F_PREFIX, - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname)); - - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (!sdpmode) { - vcmRxReleasePort(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), media->src_port); - } - } -} - -static void -lsm_free_lcb (lsm_lcb_t *lcb) -{ - lsm_release_port(lcb); - cpr_free(lcb->gcid); - lsm_init_lcb(lcb); -} - - -/** - * lsm_get_free_lcb - * return a free instance of the given line - * - * @param[in]call_id - gsm call id to allocate the lcb instance with. - * @param[in]line - line that the lcb instnce will be associated with - * @param[in]dcb - fsmdef_dcb_t structure that the lcb instance will - * be associated with. - * @return pointer to lsm_lcb_t if there is an available lcb otherwise - * returns NULL. - * @pre (dcb not_eq NULL) - */ -static lsm_lcb_t * -lsm_get_free_lcb (callid_t call_id, line_t line, fsmdef_dcb_t *dcb) -{ - static const char fname[] = "lsm_get_free_lcb"; - static int mru = 0; - lsm_lcb_t *lcb; - lsm_lcb_t *lcb_found = NULL; - - if (!sip_config_check_line(line)) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)", fname, line); - - return (NULL); - } - - - /* - * Set mru (most recently used). - * Used to determine which call came in first. - */ - if (++mru < 0) { - mru = 1; - } - - /* - * Find a free lcb. - */ - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id == CC_NO_CALL_ID) && (lcb->state == LSM_S_IDLE)) { - lcb_found = lcb; - lcb->call_id = call_id; - lcb->line = line; - lcb->state = LSM_S_PENDING; - lcb->mru = mru; - lcb->dcb = dcb; - // start unmuted if txPref is true - lcb->vid_mute = cc_media_getVideoAutoTxPref() ? FALSE : TRUE; - - lcb->ui_id = call_id; /* default UI ID is the same as call_id */ - break; - } - } - - return (lcb_found); -} - - -lsm_lcb_t * -lsm_get_lcb_by_call_id (callid_t call_id) -{ - lsm_lcb_t *lcb; - lsm_lcb_t *lcb_found = NULL; - LSM_DEBUG(DEB_L_C_F_PREFIX"call_id=%d.", - DEB_L_C_F_PREFIX_ARGS(LSM, 0, call_id, "lsm_get_lcb_by_call_id"), call_id); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id == call_id) { - lcb_found = lcb; - break; - } - } - - return (lcb_found); -} - -/** - * This function returns the LSM state for the given call_id. - * - * @param[in] call_id - call id - * - * @return lsm_states_t of the given call_id. If the - * there is no call associated with the given - * call ID it returns the LSM_S_NONE. - */ -lsm_states_t -lsm_get_state (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - - if (lcb == NULL) { - /* there is no call for this call id */ - return (LSM_S_NONE); - } - return (lcb->state); -} - -static void -lsm_change_state (lsm_lcb_t *lcb, int line_num, lsm_states_t new_state) -{ - static const char fname1[] = "lsm_change_state"; - LSM_DEBUG(DEB_L_C_F_PREFIX"%d: %s -> %s", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname1), - line_num, lsm_state_name(lcb->state), lsm_state_name(new_state)); - - lcb->state = new_state; -} - -boolean -lsm_is_phone_idle (void) -{ - static const char fname[] = "lsm_is_phone_idle"; - boolean idle = TRUE; - lsm_lcb_t *lcb; - - if(!lsm_lcbs){ - LSM_DEBUG(DEB_F_PREFIX"No lsm line cb", DEB_F_PREFIX_ARGS(LSM, fname)); - return (idle); - } - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && (lcb->state != LSM_S_IDLE)) { - idle = FALSE; - break; - } - } - - return (idle); -} - - - -/* - * Function: lsm_is_phone_inactive - * - * Parameters: None. - * - * Description: Determines if the phone is inactive. Inactive means the phone - * as active at some point, but now it is not - there are still - * calls on the phone but they are probably in a holding state. - * This is different from idle, which means that there are not - * any calls on the phone. - * - * Returns: - * inactive: FALSE: phone is not inactive - * TRUE: phone is inactive - */ -boolean -lsm_is_phone_inactive (void) -{ - boolean inactive = TRUE; - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - ((lcb->state == LSM_S_OFFHOOK) || - (lcb->state == LSM_S_PENDING) || - (lcb->state == LSM_S_PROCEED) || - (lcb->state == LSM_S_RINGOUT) || - (lcb->state == LSM_S_RINGIN) || - (lcb->state == LSM_S_CONNECTED))) { - inactive = FALSE; - break; - } - } - - return (inactive); -} - -/* - * Function: lsm_callwaiting - * - * Parameters: None. - * - * Description: Determines if the phone is in a state that this - * call will be handled by the callwaiting code. TNP - * phones allow call-waiting when dialing digits while - * the legacy phones do not. - * - * Returns: - * inactive: FALSE: Treat as a normal call on an idle phone - * TRUE: Display incoming call and play call waiting tone - */ -boolean -lsm_callwaiting (void) -{ - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id != CC_NO_CALL_ID) { - switch (lcb->state) { - case LSM_S_OFFHOOK: - case LSM_S_PROCEED: - case LSM_S_RINGOUT: - case LSM_S_CONNECTED: - return (TRUE); - - default: - break; - } - } - } - - return (FALSE); -} - -static callid_t -lsm_find_state (lsm_states_t state) -{ - callid_t found_callid = CC_NO_CALL_ID; - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && (lcb->state == state)) { - found_callid = lcb->call_id; - break; - } - } - - return (found_callid); -} - -/** - * lsm_get_facility_by_called_number - * return facility by the given called_number. - * - * @param[in]call_id - gsm's call_id for a new call. - * @param[in]called_number - pointer to the called number. - * @paran[in/out]free_line - pointer to the line_t to store - * the result line number corresponding - * to the called number given. - * @param[in]expline - boolean indicating extra instance - * is needed. - * @param[in]dcb - pointer to void but it must be - * a pointer to fsmdef_dcb_t to bind with - * the new LCB. The reason to use a void - * pointer is the declaration of the function - * is in lsm.h. The lsm.h file is used by - * components outside gsm environment. Those - * modules would need to include the fsm.h - * which is not desirable. Using void pointer - * avoids this problem. - * - * @return cc_cause_t - * - * @pre (called_number not_eq NULL) - * @pre (free_line not_eq NULL) - * @pre (dcb not_eq NULL) - */ -cc_causes_t -lsm_get_facility_by_called_number (callid_t call_id, - const char *called_number, - line_t *free_line, boolean expline, - void *dcb) -{ - static const char fname[] = "lsm_get_facility_by_called_number"; - line_t line; - lsm_lcb_t *lcb; - int free_instances; - line_t madn_line; - - lsm_debug_entry(call_id, 0, fname); - LSM_DEBUG(DEB_F_PREFIX"called_number= %s", DEB_F_PREFIX_ARGS(LSM, fname), called_number); - - //line = sip_config_get_line_by_called_number(1, called_number); - line = 1; - if (line == 0) { - return (CC_CAUSE_UNASSIGNED_NUM); - } - *free_line = line; - - /* check for a MADN line */ - madn_line = sip_config_get_line_by_called_number((line_t)(line + 1), - called_number); - - /* - * Check to see if we even have any available instances. - */ - free_instances = lsm_get_instances_available_cnt(line, expline); - - /* if it is a MADN line and it already has a call, then go to next - * line with this MADN number. - */ - if ((madn_line) && (free_instances < 2)) { - while (madn_line) { - free_instances = lsm_get_instances_available_cnt(madn_line, expline); - if (free_instances == 2) { - *free_line = line = madn_line; - break; - } - madn_line = sip_config_get_line_by_called_number((line_t)(madn_line + 1), - called_number); - } - if (madn_line == 0) { - return (CC_CAUSE_BUSY); - } - } - - if (free_instances <= 0) { - return (CC_CAUSE_BUSY); - } - - lcb = lsm_get_free_lcb(call_id, line, (fsmdef_dcb_t *)dcb); - if (lcb == NULL) { - return (CC_CAUSE_NO_RESOURCE); - } - - return (CC_CAUSE_OK); -} - -/** - * lsm_allocate_call_bandwidth - * - * @param[in] none. - * - * The wlan interface puts into unique situation where call control - * has to allocate the worst case bandwith before creating a - * inbound or outbound call. The function call will interface through - * media API into wlan to get the call bandwidth. The function - * return is asynchronous and will block till the return media - * callback signals to continue the execution. - * - * @return true if the bandwidth can be allocated else false. - * @pre none - */ - -cc_causes_t lsm_allocate_call_bandwidth (callid_t call_id, int sessions) -{ - //get line for vcm - line_t line = lsm_get_line_by_call_id(call_id); - //cc_feature(CC_SRC_GSM, call_id, 0, CC_FEATURE_CAC_RESP_PASS, NULL); - - /* Activate the wlan before allocating bandwidth */ - vcmActivateWlan(TRUE); - - if (vcmAllocateBandwidth(lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), sessions)) { - return(CC_CAUSE_OK); - } - - return(CC_CAUSE_CONGESTION); -} - -/** - * lsm_get_facility_by_line - * return facility by the given line - * - * @param[in]call_id - gsm's call_id for a new call. - * @param[in]line - line - * @param[in]expline - boolean indicating extra instance - * is needed. - * @param[in]dcb - pointer to void but it must be - * a pointer to fsmdef_dcb_t to bind with - * the new LCB. The reason to use a void - * pointer is the declaration of the function - * is in lsm.h. The lsm.h file is used by - * components outside gsm environment. Those - * modules would need to include the fsm.h - * which is not desirable. Using void pointer - * avoids this problem. - * - * @return cc_cause_t - * @pre (dcb not_eq NULL) - */ -cc_causes_t -lsm_get_facility_by_line (callid_t call_id, line_t line, boolean expline, - void *dcb) -{ - static const char fname[] = "lsm_get_facility_by_line"; - lsm_lcb_t *lcb; - int free_instances; - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), call_id, line, fname, - "exp", expline); - - /* - * Check to see if we even have any available instances - */ - free_instances = lsm_get_instances_available_cnt(line, expline); - if (free_instances <= 0) { - return (CC_CAUSE_BUSY); - } - - lcb = lsm_get_free_lcb(call_id, line, (fsmdef_dcb_t *)dcb); - if (lcb == NULL) { - return (CC_CAUSE_NO_RESOURCE); - } - - return (CC_CAUSE_OK); -} - - -#ifdef _WIN32 -/* This function enumerates over the lcbs - * and attempts to terminate the call - * This is used by softphone when - * it exits and the softphone is - * still engaged in a call - */ -void -terminate_active_calls (void) -{ - callid_t call_id = CC_NO_CALL_ID; - lsm_lcb_t *lcb; - line_t line; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id != CC_NO_CALL_ID) { - line = lsm_get_line_by_call_id(lcb->call_id); - /* Currently cc_feature does a better job of releasing the call - * compared to cc_onhook. - */ - //cc_onhook(CC_SRC_UI, call_id, line); - cc_feature(CC_SRC_UI, call_id, line, CC_FEATURE_END_CALL, NULL); - call_id = lcb->call_id; - } - } -} - - -#endif - -line_t -lsm_get_line_by_call_id (callid_t call_id) -{ - fsmdef_dcb_t *dcb; - line_t line; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb != NULL) { - line = dcb->line; - } else { - line = LSM_DEFAULT_LINE; - } - - return (line); -} - -/* - * This is a callback function for those tones that are - * played in two parts (stutter and msgwaiting) or played - * every x seconds, but are not steady tones (call waiting). - * - * @param[in] data The gsm ID (callid_t) of the call of the - * tones timer has timeout. - * - * @return N/A - */ -void -lsm_tmr_tones_callback (void *data) -{ - static const char fname[] = "lsm_tmr_tones_callback"; - callid_t call_id; - fsmdef_dcb_t *dcb = NULL; - fsmdef_media_t *media; - - LSM_DEBUG(DEB_F_PREFIX"invoked", DEB_F_PREFIX_ARGS(LSM, fname)); - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - LSM_DEBUG(DEB_F_PREFIX"invalid call id", DEB_F_PREFIX_ARGS(LSM, fname)); - return; - } - - /* - * A call-waiting tone should be played if these conditions are met: - * 1. A line must be ringing for an incoming call - * 2. The phone must be in a state that we handle callwaiting - */ - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"no dcb found for call_id %d", DEB_F_PREFIX_ARGS(LSM, fname), call_id); - return; - } - - media = gsmsdp_find_audio_media(dcb); - - if ((lsm_find_state(LSM_S_RINGIN) > CC_NO_CALL_ID) && (lsm_callwaiting())) { - - /* Determine what tone/ringing pattern to play */ - switch (dcb->alert_info) { - - case ALERTING_RING: - - /* Need to map the alerting patterns to the call waiting patterns */ - switch (dcb->alerting_ring) { - case VCM_BELLCORE_DR2: - lsm_util_start_tone(VCM_CALL_WAITING_2_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - case VCM_BELLCORE_DR3: - lsm_util_start_tone(VCM_CALL_WAITING_3_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - case VCM_BELLCORE_DR4: - lsm_util_start_tone(VCM_CALL_WAITING_4_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - default: - lsm_util_start_tone(VCM_CALL_WAITING_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - } - break; - - case ALERTING_TONE: - - /* Busy verify is just 2 secs of dialtone followed by - * a call waiting tone every 10 secs. The rest of the - * tones are just played once. - */ - switch (dcb->alerting_tone) { - case VCM_BUSY_VERIFY_TONE: - lsm_util_start_tone(VCM_CALL_WAITING_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - if (cprStartTimer(lsm_tmr_tones, BUSY_VERIFICATION_DELAY, - (void *)(long)dcb->call_id) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } - break; - - case VCM_CALL_WAITING_TONE: - case VCM_CALL_WAITING_2_TONE: - case VCM_CALL_WAITING_3_TONE: - case VCM_CALL_WAITING_4_TONE: - lsm_util_start_tone(dcb->alerting_tone, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - - case VCM_MSG_WAITING_TONE: - case VCM_STUTTER_TONE: - lsm_util_start_tone(VCM_INSIDE_DIAL_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - lsm_tmr_tones_ticks = 0; - break; - default: - break; - } - break; - - default: - lsm_util_start_tone(VCM_CALL_WAITING_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - - break; - } - - } else if (dcb->dialplan_tone) { - dcb->dialplan_tone = FALSE; - switch (dcb->alert_info) { - - case ALERTING_TONE: - /* - * Currently the only supported multi-part tones - * played via the dialplan are Message Waiting and - * Stutter dialtones. - */ - switch (dcb->alerting_tone) { - case VCM_MSG_WAITING_TONE: - case VCM_STUTTER_TONE: - lsm_util_start_tone(VCM_INSIDE_DIAL_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - - case VCM_HOLD_TONE: - lsm_util_start_tone(dcb->alerting_tone, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - - default: - break; - } - - break; - - default: - break; - } - } -} - -/* - * Function : lsm_start_multipart_tone_timer - * Parameters : Tone: 2nd part of tone to play - * Delay: Time to delay between playing the 1st and 2nd parts of the tone - * CallId: Used to retrieve the dcb for this call - * Purpose : This function is used to set up the dcb to play the 2nd part of - * the tone. A timer is started to allow the 1st tone to played to - * completion before the 2nd part is started. - */ -void -lsm_start_multipart_tone_timer (vcm_tones_t tone, - uint32_t delay, - callid_t callId) -{ - static const char fname[] = "lsm_start_multipart_tone_timer"; - fsmdef_dcb_t *dcb; - - /* Set up dcb for timer callback function */ - dcb = fsmdef_get_dcb_by_call_id(callId); - dcb->alert_info = ALERTING_TONE; - dcb->alerting_tone = tone; - dcb->dialplan_tone = TRUE; - - if (cprCancelTimer(lsm_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_tmr_tones, delay, (void *)(long)dcb->call_id) == - CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } -} - -/* - * Function : lsm_stop_multipart_tone_timer - * Parameters : None - * Purpose : Called from vcm_stop_tones. That function - * will stop the 1st part of the tone, this - * function cancels the timer so the 2nd part - * will never be played. - */ -void -lsm_stop_multipart_tone_timer (void) -{ - static const char fname[] = "lsm_stop_multipart_tone_timer"; - - if (cprCancelTimer(lsm_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } -} - -/* - * Function : lsm_start_continuous_tone_timer - * Parameters : Tone: tone to play - * Delay: Time to delay between playing the tone - * CallId: Used to retrieve the dcb for this call - * Purpose : This function is used to set up the dcb to play a tone continuously. - * An example being the tone on hold tone. - */ -void -lsm_start_continuous_tone_timer (vcm_tones_t tone, - uint32_t delay, - callid_t callId) -{ - static const char fname[] = "lsm_start_continuous_tone_timer"; - fsmdef_dcb_t *dcb; - - /* Set up dcb for timer callback function */ - dcb = fsmdef_get_dcb_by_call_id(callId); - dcb->alert_info = ALERTING_TONE; - dcb->alerting_tone = tone; - dcb->dialplan_tone = TRUE; - - if (cprCancelTimer(lsm_continuous_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_continuous_tmr_tones, delay, (void *)(long)dcb->call_id) - == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } -} - -/* - * Function : lsm_stop_continuous_tone_timer - * Parameters : None - * Purpose : Called from vcm_stop_tones. That function - * will stop the the tone, this function cancels - * the timer subsequent playing of the tone is not - * performed - */ -void -lsm_stop_continuous_tone_timer (void) -{ - static const char fname[] = "lsm_stop_continuous_tone_timer"; - - if (cprCancelTimer(lsm_continuous_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } -} - -/* - * Function : lsm_start_tone_duration_timer - * Parameters : Tone: tone type to play - * Duration: length of time for tone to play - * call_handle: Used to retrieve the dcb for this call - * Purpose : This function is used to set up the dcb to play the tone for - * a specified length of time. - */ -void -lsm_start_tone_duration_timer (vcm_tones_t tone, - uint32_t duration, - cc_call_handle_t call_handle) -{ - static const char fname[] = "lsm_start_tone_duration_timer"; - fsmdef_dcb_t *dcb; - - /* Set up dcb for timer callback function */ - dcb = fsmdef_get_dcb_by_call_id(GET_CALL_ID(call_handle)); - - if (cprCancelTimer(lsm_tone_duration_tmr) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_tone_duration_tmr, duration*1000, (void *)(long)dcb->call_id) == - CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } -} - -/* - * Function : lsm_stop_tone_duration_timer - * Parameters : None - * Purpose : Called from vcm_stop_tones. That function - * will stop the tone. - */ -void -lsm_stop_tone_duration_timer (void) -{ - static const char fname[] = "lsm_stop_tone_duration_timer"; - - if (cprCancelTimer(lsm_tone_duration_tmr) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } -} - -/* - * This is a callback function for those tones that are - * played in two parts (stutter and msgwaiting) or played - * every x seconds, but are not steady tones (call waiting). - * - * @param[in] data The gsm ID (callid_t) of the call of the - * tones timer has timeout. - * - * @return N/A - */ -void -lsm_tone_duration_tmr_callback (void *data) -{ - static const char fname[] = "lsm_tone_duration_tmr_callback"; - callid_t call_id; - fsmdef_dcb_t *dcb = NULL; - fsmdef_media_t *media; - - LSM_DEBUG(DEB_F_PREFIX"invoked", DEB_F_PREFIX_ARGS(LSM, fname)); - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - LSM_DEBUG(DEB_F_PREFIX"invalid call id", DEB_F_PREFIX_ARGS(LSM, fname)); - return; - } - - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"no dcb found for call_id %d", DEB_F_PREFIX_ARGS(LSM, fname), call_id); - return; - } - - media = gsmsdp_find_audio_media(dcb); - - vcmToneStop(dcb->active_tone, dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID)); - - /* Up until this point, only sip core has started the call release procedure */ - /* since upon receipt of the BYE. Now that tone is completed playing as requested */ - /* in the BYE, need to continue processing with call clearing. */ - - cc_int_release(CC_SRC_GSM, CC_SRC_GSM, call_id, dcb->line, CC_CAUSE_NORMAL, NULL, NULL); -} - -/* - * LSM internal function that checks if any calls are in a pending - * answer condition. Such a condition occurs when the GSM has delayed - * answering an incoming call while trying to clear other calls. - * - * @return call_id if found, else CC_NO_CALL_ID. - */ -static callid_t -lsm_answer_pending (void) -{ - callid_t found_callid = CC_NO_CALL_ID; - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - (FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING))) { - - found_callid = lcb->call_id; - break; - } - } - - return (found_callid); -} - -/** - * - * Hold Reversion Alert - plays the ringer once. - * - * @param lsm_lcb_t lcb for this call - * @param callid_t gsm_id - * @param line_t line - * - * @return none - * - * @pre (lcb not_eq NULL) - */ -static void -lsm_reversion_ringer (lsm_lcb_t *lcb, callid_t call_id, line_t line) -{ - vcm_ring_mode_t ringerMode = VCM_INSIDE_RING; - vcm_tones_t toneMode = VCM_CALL_WAITING_TONE; - - if (!lsm_callwaiting()) { - config_get_line_value(CFGID_LINE_RING_SETTING_IDLE, - &ringSettingIdle, sizeof(ringSettingIdle), - line); - if (cc_line_ringer_mode[line] == CC_RING_DISABLE) { - ringerMode = VCM_FLASHONLY_RING; - } else if (ringSettingIdle == DISABLE) { - ringerMode = VCM_RING_OFF; - } else if (ringSettingIdle == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - } - - vcmControlRinger(ringerMode, YES, NO, line, call_id); - - } else { - lsm_tmr_tones_ticks = 0; - - config_get_line_value(CFGID_LINE_RING_SETTING_ACTIVE, - &ringSettingActive, sizeof(ringSettingActive), - line); - if (ringSettingActive == DISABLE) { - ringerMode = VCM_RING_OFF; - } else if (ringSettingActive == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - } - - if (ringSettingActive == BEEP_ONLY) { - fsmdef_media_t *media = gsmsdp_find_audio_media(lcb->dcb); - - lsm_util_start_tone(toneMode, NO, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), lcb->dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - vcmControlRinger(ringerMode, YES, NO, line, call_id); - } - } -} - -/** - * This function will set beep only settings. - * - * @param[in] dcb - DEF S/M control block - * @param[out] toneMode_p - pointer to tone mode - * - * @return none - */ -static void -lsm_set_beep_only_settings (fsmdef_dcb_t *dcb, vcm_tones_t *toneMode_p) -{ - switch (dcb->alert_info) { - /* - * Map BTS requested ring pattern to corresponding call waiting - * pattern if phone is already offhook. All call waiting tones - * must be played every ten seconds and msg waiting and stutter - * dialtone are multi-part tones that play and then after - * 100 ms give steady dialtone. Set a timer to call the tone - * callback function for those tones. - */ - case ALERTING_RING: - lsm_tmr_tones_ticks = callWaitingDelay; - switch (dcb->alerting_ring) { - case VCM_BELLCORE_DR2: - *toneMode_p = VCM_CALL_WAITING_2_TONE; - break; - - case VCM_BELLCORE_DR3: - *toneMode_p = VCM_CALL_WAITING_3_TONE; - break; - - case VCM_BELLCORE_DR4: - *toneMode_p = VCM_CALL_WAITING_4_TONE; - break; - - default: - break; - } - break; - - /* BTS wishes to override call waiting tone */ - case ALERTING_TONE: - /* - * In violation of the spec, BTS will send tones in the - * Alert-Info header and if the phone is offhook, wants - * the phone to play the tone specified in the Alert-Info - * header instead of the normal call waiting tone. If this - * line is connected to a call manager follow the spec and - * always play the call waiting tone regardless of what was - * received in the Alert-Info header. - */ - if (sip_regmgr_get_cc_mode(dcb->line) == REG_MODE_CCM) { - dcb->alerting_tone = VCM_CALL_WAITING_TONE; - LSM_DEBUG(DEB_F_PREFIX" - Overriding value in Alert-Info header as line %d is \ - connected to a Call Manager.", - DEB_F_PREFIX_ARGS(LSM, __FUNCTION__), dcb->line); - } - *toneMode_p = dcb->alerting_tone; - switch (dcb->alerting_tone) { - case VCM_MSG_WAITING_TONE: - lsm_tmr_tones_ticks = MSG_WAITING_DELAY; - break; - - case VCM_STUTTER_TONE: - lsm_tmr_tones_ticks = STUTTER_DELAY; - break; - - case VCM_BUSY_VERIFY_TONE: - lsm_tmr_tones_ticks = BUSY_VERIFY_DELAY; - break; - - case VCM_CALL_WAITING_TONE: - case VCM_CALL_WAITING_2_TONE: - case VCM_CALL_WAITING_3_TONE: - case VCM_CALL_WAITING_4_TONE: - lsm_tmr_tones_ticks = callWaitingDelay; - break; - - default: - break; - } - break; - - default: - lsm_tmr_tones_ticks = callWaitingDelay; - } -} - -/** - * - * Set ringer mode based on remote-cc input and configuration parameters. If there - * any other call pending then it should play call waiting tone. - * - * @param lsm_lcb_t lcb for this call - * @param callid_t gsm_id - * @param line_t line - * - * @return none - * - * @pre (lcb not_eq NULL) - */ -static void -lsm_set_ringer (lsm_lcb_t *lcb, callid_t call_id, line_t line, int alerting) -{ - static const char fname[] = "lsm_set_ringer"; - fsmdef_dcb_t *dcb; - boolean ringer_set = FALSE; - callid_t other_call_id = CC_NO_CALL_ID; - callid_t priority_call_id = CC_NO_CALL_ID; - int callHoldRingback = 0; - int dcb_cnt = 0; - int i = 0; - fsmxfr_xcb_t *xcb; - fsmcnf_ccb_t *ccb; - lsm_lcb_t *lcb2; - fsmdef_dcb_t *dcbs[LSM_MAX_CALLS]; - vcm_ring_mode_t ringerMode = VCM_INSIDE_RING; - short ringOnce = NO; - boolean alertInfo = NO; - vcm_tones_t toneMode = VCM_CALL_WAITING_TONE; - fsmdef_media_t *media; - boolean isDusting = FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_DUSTING) ? TRUE : FALSE; - int sdpmode = 0; - - - LSM_DEBUG(DEB_L_C_F_PREFIX"Entered, state=%d.", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), lcb->state); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - /* - * The ringer (or call-waiting tone) should be on if these - * conditions are met: - * 1. A line is ringing for an incoming call and no calls - * with a pending answer - * 2. A line is on hold - * and - * 3. No lines are connected - * - * Otherwise, turn on the call-waiting tones. - * - */ - - if (priority_call_id == CC_NO_CALL_ID) { - /* get the call_id of the line that triggers this if it is ringing and - pass down the correct line variable and its ring type and let the ring - manager decides. Originally we only find line first line in ringing state - which results in issue where Flash only line follows by audio ring line - ringing simultaneously, the phone does not ring audibly. - */ - if (lcb->state == LSM_S_RINGIN) { - other_call_id = call_id; - } else { - other_call_id = lsm_find_state(LSM_S_RINGIN); - } - } - - if (((priority_call_id != CC_NO_CALL_ID) || (other_call_id != CC_NO_CALL_ID)) && - (lsm_answer_pending() == CC_NO_CALL_ID)) { - /*sam - * may need to add (ringout and rtp open) to this check. - * It is possible that inband alerting is active for an outgoing call. - */ - dcb = fsmdef_get_dcb_by_call_id((priority_call_id != CC_NO_CALL_ID) ? - priority_call_id : other_call_id); - lcb = lsm_get_lcb_by_call_id((priority_call_id != CC_NO_CALL_ID) ? - priority_call_id : other_call_id); - isDusting = ((lcb != NULL) && FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_DUSTING)) ? TRUE : FALSE; - - /* - * TNP has line-based ringing so update the line parameter so - * if reflects what line is ringing, not which line had an action - * taken against it, i.e. if line 1 hangs up and line 2 is ringing, - * line will be equal to 1 (since that line hung-up), but it needs - * to be 2 since that is the line actually ringing. 40/60 can - * get away with this since it is device-based ringing. If there - * are multiple lines in the RINGIN state, the ringing will be - * based on the first line in the RINGIN state found. Could add - * the check if (other_call_id != callid) but line will equal - * dcb->line if the callids are the same so save a few CPU cycles - * by not having the check. No need to do a #ifdef TNP since - * it does matter which line we use on the 40/60 as it is device based. - */ - line = dcb->line; - - if (!lsm_callwaiting()) { - - LSM_DEBUG(DEB_L_C_F_PREFIX"No call waiting, lcb->line=%d, lcb->flag=%d.", - DEB_L_C_F_PREFIX_ARGS(LSM, line, lcb->call_id, fname), - lcb->line, - lcb->flags); - - ringer_set = TRUE; - lsm_tmr_tones_ticks = 0; - - /* - * CFGID_LINE_RING_SETTING_IDLE is a config parameter that - * tells the phone what action to take for an incoming - * call on a phone with no active calls. - * - */ - - if (isDusting) { - ringSettingIdle = FLASH_ONLY; - } - else if (FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_PREVENT_RINGING)) { - /* - * If this phone is both calling and called device, do not play ring. - */ - ringSettingIdle = DISABLE; - } else if (cc_line_ringer_mode[line] == CC_RING_DISABLE) { - /* - * Disable - no ring or flash - */ - ringSettingIdle = FLASH_ONLY; - } else if (cc_line_ringer_mode[line] == CC_RING_ENABLE) { - ringSettingIdle = RING; - } else { - config_get_line_value(CFGID_LINE_RING_SETTING_IDLE, - &ringSettingIdle, sizeof(ringSettingIdle), - line); - } - LSM_DEBUG(DEB_L_C_F_PREFIX"Ring set mode=%d.", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), ringSettingIdle); - - /* - * Disable - no ring or flash - */ - if (ringSettingIdle == DISABLE) { - ringerMode = VCM_RING_OFF; - - /* - * Flash Only - No ringing, just flash. - */ - } else if (ringSettingIdle == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - - /* - * Ring once - ring the phone once - */ - } else if (ringSettingIdle == RING_ONCE) { - ringOnce = YES; - - /* - * Ring - normal operation. Ring the phone until answered, - * forwarded, or disconnected. - */ - } else if (ringSettingIdle == RING) { - - /* Determine what tone/ringing pattern to play */ - switch (dcb->alert_info) { - case ALERTING_NONE: - /* This is the default case nothing to do */ - break; - - case ALERTING_RING: - ringerMode = dcb->alerting_ring; - break; - - case ALERTING_OLD: - default: - alertInfo = YES; - } - } else if (ringSettingIdle == BEEP_ONLY) { - lsm_set_beep_only_settings (dcb, &toneMode); - - } - LSM_DEBUG(DEB_L_C_F_PREFIX"Alert info=%d, ringSettingIdle=%d, ringerMode=%d", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - dcb->alert_info, - ringSettingIdle, - ringerMode); - - /* - * If an active call is being held while there is an incoming - * call AND ringSettingBusyStationPolicy is 0, this flag will - * be false. - */ - if (alerting) { - /* - * If the line is connected to a CCM, Bellcore-Dr1 means - * play the defined ringer once. Bellcore-dr2 means play - * the defined ringer twice. - */ - if (sip_regmgr_get_cc_mode(line) == REG_MODE_CCM) { - if (ringerMode == VCM_BELLCORE_DR1) { - ringerMode = VCM_INSIDE_RING; - } else if (ringerMode == VCM_BELLCORE_DR2) { - ringerMode = VCM_OUTSIDE_RING; - } - } - if (ringSettingIdle == BEEP_ONLY) { - - LSM_DEBUG(DEB_L_C_F_PREFIX"Idle phone RING SETTING: Beep_only", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname)); - - media = gsmsdp_find_audio_media(lcb->dcb); - lsm_util_tone_start_with_speaker_as_backup(toneMode, NO, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), - lcb->dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - LSM_DEBUG(DEB_L_C_F_PREFIX"Idle phone RING SETTING: ringer Mode = %s," - " Ring once = %d, alertInfo = %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - vm_alert_names[ringerMode], ringOnce, alertInfo); - - vcmControlRinger(ringerMode, ringOnce, alertInfo, line, lcb->ui_id); - } - } - - if ( lcb->state != LSM_S_HOLDING && - lcb->state != LSM_S_RINGIN ) { - ui_set_call_status(platform_get_phrase_index_str(CALL_ALERTING), - line, lcb->ui_id); - } - } else { - - // Ring off all lines. - FSM_FOR_ALL_CBS(lcb2, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb2->call_id != CC_NO_CALL_ID) && - (lcb2->state == LSM_S_RINGIN) ) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"Call waiting RING SETTING: " - "ringer Mode = RING_OFF, Ring once = NO, alertInfo = NO\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb2->line, lcb2->call_id, fname)); - vcmControlRinger(VCM_RING_OFF, NO, NO, lcb2->line, call_id); - } - } - ringer_set = TRUE; - lsm_tmr_tones_ticks = 0; - - /* - * ringSettingActive is a TNP only config parameter that - * tells the phone what action to take for an incoming - * call on a phone with an active call. - */ - if (isDusting) { - ringSettingActive = FLASH_ONLY; - } else { - config_get_line_value(CFGID_LINE_RING_SETTING_ACTIVE, - &ringSettingActive, sizeof(ringSettingActive), - line); - } - - /* - * Disable - no ring or flash - */ - if (ringSettingActive == DISABLE) { - ringerMode = VCM_RING_OFF; - - /* - * Flash Only - No ringing, just flash. - */ - } else if (ringSettingActive == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - - /* - * Ring once - ring the phone once - */ - } else if (ringSettingActive == RING_ONCE) { - ringOnce = YES; - - /* - * Ring - Ring the phone until answered, forwarded or - * disconnected. - * - * NOTE: This code is replicated above under checking - * RING_SETTING_IDLE above. Putting this common code - * in a function call saved a miniscule amount of memory - * at the cost of an additional function call for every - * call. It was decided it was not worth the cost, but - * has been documented in case the phone gets very, - * very low on memory in the future. - */ - } else if (ringSettingActive == RING) { - - /* Determine what tone/ringing pattern to play */ - switch (dcb->alert_info) { - case ALERTING_NONE: - /* This is the default case nothing to do */ - break; - - case ALERTING_RING: - ringerMode = dcb->alerting_ring; - break; - - case ALERTING_OLD: - default: - alertInfo = YES; - } - - /* - * BeepOnly - normal operation. Play call waiting tone. - */ - } else if (ringSettingActive == BEEP_ONLY) { - lsm_set_beep_only_settings (dcb, &toneMode); - - } - - /* - * If an active call is being held while there is an incoming - * call AND ringSettingBusyStationPolicy is 0, this flag will - * be false. - */ - if (alerting) { - /* - * The code above has set the variables to play either the ringer - * or a tone based on the ringSettingBusy. If the config variable - * is beeponly then call start_tone else call control_ringer. - */ - if (ringSettingActive == BEEP_ONLY) { - media = gsmsdp_find_audio_media(dcb); - - lsm_util_start_tone(toneMode, NO, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - - LSM_DEBUG(DEB_L_C_F_PREFIX"Active call RING SETTING: " - "ringer Mode = %s, Ring once = %d, alertInfo = %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - vm_alert_names[ringerMode], ringOnce, alertInfo); - - vcmControlRinger(ringerMode, ringOnce, alertInfo, line, lcb->ui_id); - } - } - - /* - * Start a timer to play multiple part tones if needed. - */ - if (lsm_tmr_tones_ticks > 0) { - if (cprCancelTimer(lsm_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_tmr_tones, lsm_tmr_tones_ticks, - (void *)(long)dcb->call_id) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } - } - } - } else if (lcb->state == LSM_S_IDLE) { - /* - * This line just hungup so let's check to see if call hold ringback - * is enabled and if we have any other holding lines. If so ring to - * alert the user that a line is still around. - */ - config_get_value(CFGID_CALL_HOLD_RINGBACK, &callHoldRingback, - sizeof(callHoldRingback)); - if (callHoldRingback & 0x1) { - callid_t ui_id; - - dcb_cnt = fsmdef_get_dcbs_in_held_state(dcbs, call_id); - for (i = 0, dcb = dcbs[i]; i < dcb_cnt; i++, dcb = dcbs[i]) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((lsm_is_phone_inactive() == TRUE) && - (ccb == NULL) && (xcb == NULL) && - (lcb->enable_ringback == TRUE)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Applying ringback", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname)); - ringer_set = TRUE; - - LSM_DEBUG(DEB_L_C_F_PREFIX"Hold RINGBACK SETTING: ringer Mode = " - "VCM_INSIDE_RING, Ring once = YES, alertInfo = YES\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, dcb->call_id, fname)); - vcmControlRinger(VCM_INSIDE_RING, YES, YES, line, call_id); - - /* Find the corresponding LCB to get to the UI ID */ - ui_id = lsm_get_ui_id(dcb->call_id); - ui_set_call_status(platform_get_phrase_index_str(CALL_INITIATE_HOLD), - dcb->line, ui_id); - } - } - } - } - - if (ringer_set == FALSE) { - - LSM_DEBUG(DEB_L_C_F_PREFIX"Ringer_set = False : " - "ringer Mode = VCM_RING_OFF, Ring once = NO, alertInfo = NO\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname)); - - - if (!sdpmode) { - vcmControlRinger(VCM_RING_OFF, NO, NO, line, call_id); - } - - } -} - -static cc_rcs_t -lsm_offhook (lsm_lcb_t *lcb, cc_state_data_offhook_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmxfr_xcb_t *xcb; - lsm_lcb_t *lcb2; - callid_t call_id2; - int attr; - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_OFFHOOK); - - /* - * Disable the ringer since the user is going offhook. Only calls - * in the RINGIN state should have ringing enabled. - */ - FSM_FOR_ALL_CBS(lcb2, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb2->call_id != CC_NO_CALL_ID) && - (lcb2->state == LSM_S_RINGIN)) { - - vcmControlRinger(VCM_RING_OFF, NO, NO, lcb2->line, lcb2->call_id); - } - } - - dp_offhook(line, call_id); - - attr = fsmutil_get_call_attr(dcb, line, call_id); - - ui_new_call(evOffHook, line, lcb->ui_id, attr, - dcb->caller_id.call_instance_id, - (boolean)FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_DIALED_STRING)); - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb != NULL) { - call_id2 = ((lcb->call_id == xcb->xfr_call_id) ? - (xcb->cns_call_id) : (xcb->xfr_call_id)); - lcb2 = lsm_get_lcb_by_call_id(call_id2); - } - - //vcmActivateWlan(TRUE); - - vcmEnableSidetone(YES); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_dialing (lsm_lcb_t *lcb, cc_state_data_dialing_t *data) -{ - fsmxfr_xcb_t *xcb = NULL; - int stutterMsgWaiting = 0; - fsmdef_dcb_t *dcb = lcb->dcb; - fsmdef_media_t *media = gsmsdp_find_audio_media(dcb); - - - if ( dcb == NULL) { - return (CC_RC_ERROR); - } - - /* don't provide dial tone on transfer unless we are the transferor. */ - xcb = fsmxfr_get_xcb_by_call_id(lcb->call_id); - if ((xcb != NULL) && (xcb->mode != FSMXFR_MODE_TRANSFEROR)) { - return (CC_RC_SUCCESS); - } - - /* - * Start dial tone if no digits have been entered - */ - if ((data->play_dt == TRUE) - && (dp_check_for_plar_line(lcb->line) == FALSE) - ) { - - /* get line based AMWI config */ - config_get_value(CFGID_LINE_MESSAGE_WAITING_AMWI + lcb->line - 1, &stutterMsgWaiting, - sizeof(stutterMsgWaiting)); - if ( stutterMsgWaiting != 1 && stutterMsgWaiting != 0) { - /* AMWI is not configured. Fallback on config for stutter dial tone */ - config_get_value(CFGID_STUTTER_MSG_WAITING, &stutterMsgWaiting, - sizeof(stutterMsgWaiting)); - stutterMsgWaiting &= 0x1; /* LSB indicates on/off */ - } - - if ( (data->suppress_stutter == FALSE) && - (ui_line_has_mwi_active(lcb->line)) && /* has msgs waiting */ - stutterMsgWaiting ) { - lsm_util_start_tone(VCM_STUTTER_TONE, FALSE, lsm_get_ms_ui_call_handle(lcb->line, CC_NO_CALL_ID, lcb->ui_id), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - lsm_util_start_tone(VCM_INSIDE_DIAL_TONE, FALSE, lsm_get_ms_ui_call_handle(lcb->line, CC_NO_CALL_ID, lcb->ui_id), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } - } - - /* - * For round table phone, post WAITINGFORDIGITS event, - * so that UI can pop up dialing screen. - * For TNP, this event gets ignored. - */ - ui_call_state(evWaitingForDigits, lcb->line, lcb->ui_id, CC_CAUSE_NORMAL); - - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_dialing_completed (lsm_lcb_t *lcb, cc_state_data_dialing_completed_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb = lcb->dcb; - - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_PROCEED); - - /* If KPML is enabled then do not change UI state to - * proceed, more digit to collect - */ - if (dp_get_kpml_state()) { - return (CC_RC_SUCCESS); - } - - ui_call_info(data->caller_id.calling_name, - data->caller_id.calling_number, - data->caller_id.alt_calling_number, - data->caller_id.display_calling_number, - data->caller_id.called_name, - data->caller_id.called_number, - data->caller_id.display_called_number, - data->caller_id.orig_called_name, - data->caller_id.orig_called_number, - data->caller_id.last_redirect_name, - data->caller_id.last_redirect_number, - (calltype_t)dcb->call_type, - line, lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - - lsm_ui_call_state(evProceed, line, lcb, CC_CAUSE_NORMAL); - - (void) lsm_stop_tone(lcb, NULL); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_call_sent (lsm_lcb_t *lcb, cc_state_data_call_sent_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - char tmp_str[STATUS_LINE_MAX_LEN]; - fsmdef_media_t *media; - static const char fname[] = "lsm_call_sent"; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_PROCEED); - - (void) lsm_stop_tone(lcb, NULL); - - /* - * We go ahead and start a rx port if our local SDP indicates - * the need in an attempt to be 3264 compliant. Since we have - * not yet locked down the codec, we will use preferred codec if - * configured. If not, we use the first codec in our local - * list of supported codecs. The codec list was initialized - * in fsmdef_init_local_sdp. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - LSM_DEBUG(DEB_F_PREFIX"%d %d %d", DEB_F_PREFIX_ARGS(LSM, fname), media->direction_set, - media->direction, media->is_multicast); - if ((media->direction_set) && - ((media->direction == SDP_DIRECTION_SENDRECV) || - (media->direction == SDP_DIRECTION_RECVONLY))) { - - lsm_rx_start(lcb, cc_state_name(CC_STATE_FAR_END_ALERTING), - media); - } - } - - if (!dp_get_kpml_state()) { - if ((platGetPhraseText(STR_INDEX_CALLING, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - ui_set_call_status(tmp_str, line, lcb->ui_id); - } - } - - /* - * cancel offhook to first digit timer. - */ - dp_int_cancel_offhook_timer(line, lcb->call_id); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_far_end_proceeding (lsm_lcb_t *lcb, - cc_state_data_far_end_proceeding_t * data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - lsm_change_state(lcb, __LINE__, LSM_S_PROCEED); - - if (!dp_get_kpml_state()) { - ui_set_call_status(platform_get_phrase_index_str(CALL_PROCEEDING_IN), - line, lcb->ui_id); - /* - * update placed call info in call history with dialed digits - */ - dcb = lcb->dcb; - if (dcb != NULL && dcb->placed_call_update_required) { - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - } - - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_far_end_alerting (lsm_lcb_t *lcb, cc_state_data_far_end_alerting_t *data) -{ - static const char fname[] = "lsm_far_end_alerting"; - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - const char *status = NULL; - fsmcnf_ccb_t *ccb; - boolean rcv_port_started = FALSE; - char tmp_str[STATUS_LINE_MAX_LEN]; - boolean spoof_ringout; - fsmdef_media_t *media; - call_events call_state; - fsmdef_media_t *audio_media; - boolean is_session_progress = FALSE; - - - /* - * Need to check if rcv_chan is already open and if we will be - * receiving inband ringing. The recv_chan should always be - * open since we always open a receive channel when initiating a - * call. If inband ringing will be sent by the far end, we - * will close the receive port and reopen it using the codec - * negotiated when we received the SDP in the far ends call - * proceeding message. We want to close the receive port well - * ahead of reopening it due to some issue in the dsp where - * a close followed immediately by an open causes a reset of - * the DSP. - */ - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - audio_media = gsmsdp_find_audio_media(dcb); - - if (dcb->inband) { - /* close (with refresh) all media entries */ - lsm_close_rx(lcb, TRUE, NULL); - lsm_close_tx(lcb, TRUE, NULL); - } - - /* - * Check to see if we need to spoof ring out in connected or holding - * state. - * - * The LSM can be in holding state when the user is resuming - * currently held call that was early transferred to another party - * and the other party has not answered the call yet. - */ - if (dcb->spoof_ringout_requested && - ((lcb->state == LSM_S_CONNECTED) || (lcb->state == LSM_S_HOLDING))) { - /* Spoof ring out is requested in the connected/holding state */ - spoof_ringout = TRUE; - } else { - spoof_ringout = FALSE; - } - lsm_change_state(lcb, __LINE__, LSM_S_RINGOUT); - - /* Don't send the dialplan update msg if CFWD_ALL. Otherwise the invalid - * redial numer is saved. (CSCsv08816) - */ - if (dcb->active_feature != CC_FEATURE_CFWD_ALL) { - dp_int_update(line, call_id, data->caller_id.called_number); - } - - - /* - * Check for inband alerting or spoof ringout. - * If no inband alerting and this is not a spoof ringout case, - * just update the status line to show we are alerting. The local - * ringback tone will not be started until the ringback delay timer - * expires. - */ - if (dcb->inband != TRUE || spoof_ringout) { - status = platform_get_phrase_index_str(CALL_ALERTING_LOCAL); - - if (spoof_ringout) { - - if (audio_media) { - - /* - * Ringback delay timer is not used for spoof ringout case - * so start local ringback tone now. - */ - lsm_util_start_tone(VCM_ALERTING_TONE, FALSE, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), - dcb->group_id,audio_media->refid, - VCM_PLAY_TONE_TO_EAR); - } - - } - } else { - is_session_progress = TRUE; - (void) lsm_stop_tone(lcb, NULL); - - if ((platGetPhraseText(STR_INDEX_SESSION_PROGRESS, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - status = tmp_str; - } - - /* start receive and transmit for all media entries that are active */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not active */ - continue; - } - LSM_DEBUG(DEB_L_C_F_PREFIX"direction_set:%d direction:%d" - " dest_addr:%p is_multicast:%d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), - media->direction_set, - media->direction, &media->dest_addr, - media->is_multicast); - - if (media->direction_set) { - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_RECVONLY) { - lsm_rx_start(lcb, - cc_state_name(CC_STATE_FAR_END_ALERTING), - media); - rcv_port_started = TRUE; - } - - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_SENDONLY) { - lsm_tx_start(lcb, - cc_state_name(CC_STATE_FAR_END_ALERTING), - media); - } - } - } - - if (!rcv_port_started) { - /* - * Since we had SDP we thought inband ringback was in order but - * media attributes indicate the receive port is to remain - * closed. In this case, go ahead and apply local ringback tone - * or user will hear silence. We do not depend on ringback delay - * timer to start the local ringback tone so we have to start it - * here. - */ - status = platform_get_phrase_index_str(CALL_ALERTING_LOCAL); - lsm_util_start_tone(VCM_ALERTING_TONE, FALSE, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), dcb->group_id, - ((audio_media != NULL) ? audio_media->refid : - CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - lsm_set_ringer(lcb, call_id, line, YES); - } - } - - ccb = fsmcnf_get_ccb_by_call_id(call_id); - - /* Update call information */ - lsm_internal_update_call_info(lcb, dcb); - - /* This is the case where remote end of the call has been early trasnfered - * to another endpoint. - */ - - ccb = fsmcnf_get_ccb_by_call_id(lcb->call_id); - - if ((ccb != NULL) && (ccb->active == TRUE) && - (ccb->flags & LCL_CNF)) { - call_state = evConference; - } else { - call_state = evRingOut; - } - - /* If an invalid DN is dialed during CFA then CCM sends 183/Session Progress - * (a.k.a. far end alerting) so it can play the invalid DN announcement. In - * this case CCM sends 404 Not Found after playing the announcement. If we - * are here due to that situation then don't propagate call info or status - * to UI side as it will display "Session Progress" on the status line and - * will log the DN in Placed calls; and we don't want either. Just skip the - * update and following 404 Not Found will take care of playing/displaying - * Reorder. Note that this condition may occur only in TNP/CCM mode. - */ - if (dcb->active_feature != CC_FEATURE_CFWD_ALL) { - if(!is_session_progress) {//CSCtc18750 - /* - * update placed call info in call history with dialed digits - */ - if (dcb->placed_call_update_required) { - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - - if (status) { - ui_set_call_status(status, line, lcb->ui_id); - } - } - - lsm_ui_call_state(call_state, line, lcb, CC_CAUSE_NORMAL); - - } - /* For roundtable phones, UI will be in dial state, which is different from TNP UI, - * TNP UI does not have different dialing layer. In this case offhook dialing screen - * does not vanish untill GSM provides procced call status, hence all the softkeys are - * available during CFWD, which is not correct - */ - if (dcb->active_feature == CC_FEATURE_CFWD_ALL) { - lsm_ui_call_state(evReorder, line, lcb, CC_CAUSE_NORMAL); - } - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_call_received (lsm_lcb_t *lcb, cc_state_data_call_received_t *data) -{ - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_alerting (lsm_lcb_t *lcb, cc_state_data_alerting_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_RINGIN); - - dcb->ui_update_required = TRUE; - lsm_internal_update_call_info(lcb, dcb); - - ui_new_call(evRingIn, line, lcb->ui_id, NORMAL_CALL, - dcb->caller_id.call_instance_id, FALSE); - - fsmutil_set_shown_calls_ci_element(dcb->caller_id.call_instance_id, line); - lsm_ui_call_state(evRingIn, line, lcb, CC_CAUSE_NORMAL); - lsm_update_inalert_status(line, lcb->ui_id, data, TRUE); - - - lsm_set_ringer(lcb, call_id, line, YES); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_answered (lsm_lcb_t *lcb, cc_state_data_answered_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_OFFHOOK); - - - lsm_internal_update_call_info(lcb, dcb); - - vcmControlRinger(VCM_RING_OFF, NO, NO, line, dcb->call_id); - - lsm_ui_call_state(evOffHook, line, lcb, CC_CAUSE_NORMAL); - - //vcmActivateWlan(TRUE); - - (void) lsm_stop_tone(lcb, NULL); - - return (CC_RC_SUCCESS); -} - -/** - * - * Function updates media paths based on the negotated parameters. - * - * @param lcb line control block - * @param caller_fname caller function name - * - * @return none - * - * @pre (dcb not_eq NULL) - * @pre (fname not_eq NULL) - */ -static void -lsm_update_media (lsm_lcb_t *lcb, const char *caller_fname) -{ - static const char fname[] = "lsm_update_media"; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - boolean rx_refresh; - boolean tx_refresh; - char addr_str[MAX_IPADDR_STR_LEN]; - int i; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), - fname); - return; - } - - addr_str[0] = '\0'; - - /* - * Close rx and tx port for media change. Check media direction - * to see if port should be closed or remain open. If the port - * needs to be kept open, lsm_close_* functions will check to - * see if any media attributes have changed. If anything has - * changed, the port is closed, otherwise the port remains - * open. If media direction is not set, treat as if set to inactive. - * Also, if multicast leave rx_refresh and tx_refresh to FALSE to - * force a socket close. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media) || - FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - /* this entry is not active or locally held */ - continue; - } - - rx_refresh = FALSE; - tx_refresh = FALSE; - - if ((media->direction_set) && (media->is_multicast == FALSE)) { - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_RECVONLY) { - rx_refresh = TRUE; - } - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_SENDONLY) { - tx_refresh = TRUE; - } - } - - lsm_close_rx(lcb, rx_refresh, media); - lsm_close_tx(lcb, tx_refresh, media); - - if (LSMDebug) { - /* debug is enabled, format the dest addr into string */ - ipaddr2dotted(addr_str, &media->dest_addr); - for (i = 0; i < media->num_payloads; i++) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"%d rx, tx refresh's are %d %d" - ", dir=%d, payload=%p addr=%s, multicast=%d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, - dcb->call_id, fname), media->refid, rx_refresh, - tx_refresh, media->direction, - &media->payloads[i], addr_str, media->is_multicast ); - } - } - if (rx_refresh || - (media->is_multicast && - media->direction_set && - media->direction == SDP_DIRECTION_RECVONLY)) { - lsm_rx_start(lcb, caller_fname, media); - } - if (tx_refresh) { - lsm_tx_start(lcb, caller_fname, media); - } - if ( rx_refresh && - (media->cap_index == CC_VIDEO_1)) { - // force an additional update so UI can refresh the remote view - ui_update_video_avail(dcb->line, lcb->ui_id, dcb->cur_video_avail); - LSM_DEBUG(DEB_L_C_F_PREFIX"Video Avail Called %d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, lcb->ui_id, fname), dcb->cur_video_avail); - } - } -} - -/** - * - * Function to set media attributes and set the ui state. - * - * @param lcb line control block - * @param line line - * @param fname caller function name - * - * @return none - * - * @pre (dcb not_eq NULL) - * @pre (fname not_eq NULL) - */ -static void -lsm_call_state_media (lsm_lcb_t *lcb, line_t line, const char *fname) -{ - fsmcnf_ccb_t *ccb; - fsmdef_dcb_t *dcb; - call_events call_state; - callid_t call_id = lcb->call_id; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), - "lsm_call_state_media"); - return; - } - - ccb = fsmcnf_get_ccb_by_call_id(call_id); - - /* Update media parametes to the platform */ - lsm_update_media(lcb, fname); - - if ((ccb != NULL) && (ccb->active == TRUE)) { - /* For joined call leg, do not change UI state to conf. */ - if ((ccb->flags & JOINED) || - (fname == cc_state_name(CC_STATE_RESUME))) { - call_state = evConnected; - } else { - call_state = evConference; - } - } else { - call_state = evConnected; - } - - /* - * Possible media changes, update call information and followed - * by the state update. This is important sequence for 7940/60 - * SIP to force the BTXML update. - */ - // Commenting out original code for CSCsv72370. Leaving here for reference. - // lsm_internal_update_call_info(lcb, dcb); - - lsm_ui_call_state(call_state, line, lcb, CC_CAUSE_NORMAL); - // CSCsv72370 - Important sequence for TNP this follows state change - lsm_internal_update_call_info(lcb, dcb); -} - - -static cc_rcs_t -lsm_connected (lsm_lcb_t *lcb, cc_state_data_connected_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - int alerting = YES; - call_events original_call_event; - int ringSettingBusyStationPolicy; - boolean tone_stop_bool = TRUE; - int sdpmode = 0; - boolean start_ice = FALSE; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - original_call_event = lcb->previous_call_event; - /* - * If a held call is being resumed, check the - * policy to see if the phone should resume alerting. - */ - if (lcb->state == LSM_S_HOLDING) { - config_get_value(CFGID_RING_SETTING_BUSY_POLICY, - &ringSettingBusyStationPolicy, - sizeof(ringSettingBusyStationPolicy)); - if (0 == ringSettingBusyStationPolicy) { - alerting = NO; - } - - /* - * CSCtd31671: When agent phone resumes from a held call with - * monitor warning tone, the tone should not be stopped. - */ - if(lcb->dcb->active_tone == VCM_MONITORWARNING_TONE || lcb->dcb->active_tone == VCM_RECORDERWARNING_TONE) - tone_stop_bool = FALSE; - } - - /* Don't try to start ICE unless this is the first time connecting. - * TODO(ekr@rtfm.com): Is this the right ICE start logic? What about restarts - */ - if (strlen(dcb->peerconnection) && lcb->state != LSM_S_CONNECTED) - start_ice = TRUE; - - lsm_change_state(lcb, __LINE__, LSM_S_CONNECTED); - - if (!sdpmode) { - if (tone_stop_bool == TRUE) - (void) lsm_stop_tone(lcb, NULL); - } - - /* Start ICE */ - if (start_ice) { - short res = vcmStartIceChecks(dcb->peerconnection, - !dcb->inbound || dcb->peer_ice_lite); - - /* TODO(emannion): Set state to dead here. */ - if (res) - return CC_RC_SUCCESS; - } - - /* - * Open the RTP receive channel. - */ - lsm_call_state_media(lcb, line, cc_state_name(CC_STATE_CONNECTED)); - - - if (!sdpmode) { - vcmEnableSidetone(YES); - - lsm_set_ringer(lcb, call_id, line, alerting); - } - - FSM_RESET_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING); - FSM_RESET_FLAGS(lcb->flags, LSM_FLAGS_DUSTING); - - /* - * update placed call info in call history with dialed digits - */ - if (dcb->placed_call_update_required) { - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - - /* - * If UI state was changed, update status line. - */ - if (lcb->previous_call_event != original_call_event) { - if (lcb->previous_call_event == evConference) { - } else { - - ui_set_call_status(platform_get_phrase_index_str(CALL_CONNECTED), - line, lcb->ui_id); - } - } - ui_update_video_avail(line, lcb->ui_id, dcb->cur_video_avail); - return (CC_RC_SUCCESS); -} - -/** - * Function: lsm_hold_reversion - * Perform Hold Reversion on the given call - * any other call pending then it should play call waiting tone. - * - * @param lsm_lcb_t lcb for this call - * - * @return cc_rcs_t SUCCESS or FAILURE of the operation - * - * @pre (lcb not_eq NULL) - */ - -static cc_rcs_t -lsm_hold_reversion (lsm_lcb_t *lcb) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - - // Update call state on the JAVA side - lsm_ui_call_state(evHoldRevert, line, lcb, CC_CAUSE_NORMAL); - - if (lsm_find_state(LSM_S_RINGIN) > CC_NO_CALL_ID) { - // No Reversion ringing if we have calls in ringing state - return CC_RC_SUCCESS; - } - ui_set_notification(line, call_id, - (char *)INDEX_STR_HOLD_REVERSION, CALL_ALERT_TIMEOUT, - FALSE, HR_NOTIFY_PRI); - lsm_reversion_ringer(lcb, call_id, line); - - return (CC_RC_SUCCESS); -} - -/* - * lsm_hold_local - * - * Move the phone into the Hold state. - * - * Function is used when the local side initiated the hold. - */ -static cc_rcs_t -lsm_hold_local (lsm_lcb_t *lcb, cc_state_data_hold_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - cc_causes_t cause; - int ringSettingBusyStationPolicy; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - /* - * Stop ringer if spoofing ringout for CCM - */ - if (dcb->spoof_ringout_applied) { - (void) lsm_stop_tone(lcb, NULL); - } - - /* hard close receive and transmit channels for all media entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - /* - * Note that local hold does not have any newer UI information from the - * network. Note need to update the call information and the UI will - * be collapsed with "blocked" icon to indicate hold. - */ - - lsm_change_state(lcb, __LINE__, LSM_S_HOLDING); - /* Round table phones need cause for the transfer or conference - Do not set the cause if the conference or transfer is created by - remote-cc - */ - cause = CC_CAUSE_NORMAL; - if (data->reason == CC_REASON_XFER) { - cause = CC_CAUSE_XFER_LOCAL; - } else if (data->reason == CC_REASON_CONF) { - cause = CC_CAUSE_CONF; - } - - lsm_ui_call_state(evHold, line, lcb, cause); - - ui_set_call_status(platform_get_phrase_index_str(CALL_INITIATE_HOLD), - line, lcb->ui_id); - - config_get_value(CFGID_RING_SETTING_BUSY_POLICY, - &ringSettingBusyStationPolicy, - sizeof(ringSettingBusyStationPolicy)); - if (ringSettingBusyStationPolicy) { - lsm_set_ringer(lcb, call_id, line, YES); - } else { - /* - * If the hold reason is internal this means the phone logic is placing - * a call on hold, not the user. Thus don't update the alerting for the - * hold state as the user should not hear the alerting pattern change - * as they did not place the call on hold. The phone places calls on hold - * in cases such as the phone has an active call, another call comes in - * for that line and the new call is answered. Therefore the phone places the - * active call on hold before answering the incoming call. - * - */ - if (data->reason == CC_REASON_INTERNAL) { - lsm_set_ringer(lcb, call_id, line, NO); - } else { - lsm_set_ringer(lcb, call_id, line, YES); - } - } - - vcmActivateWlan(FALSE); - - return (CC_RC_SUCCESS); -} - - -/* - * lsm_hold_remote - * - * Move the phone into the Hold state. - * - * Function is used when the remote side initiated the hold. - */ -static cc_rcs_t -lsm_hold_remote (lsm_lcb_t *lcb, cc_state_data_hold_t *data) -{ - static const char fname[] = "lsm_hold_remote"; - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - const char *prompt_status; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - /* close and re-open receive channel for all media entries */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not active */ - continue; - } - if (media->direction_set && - media->direction == SDP_DIRECTION_INACTIVE) { - lsm_close_rx(lcb, FALSE, media); - } else { - lsm_close_rx(lcb, TRUE, media); - } - - /* reopen the receive channel if the direction is RECVONLY */ - if (media->direction_set && - media->direction == SDP_DIRECTION_RECVONLY) { - lsm_rx_start(lcb, fname, media); - } - /* close tx if media is not inactive or receive only */ - if ((media->direction == SDP_DIRECTION_INACTIVE) || - (media->direction == SDP_DIRECTION_RECVONLY)) { - lsm_close_tx(lcb, FALSE, media); - } - } - - lsm_internal_update_call_info(lcb, dcb); - - lsm_ui_call_state(evRemHold, line, lcb, CC_CAUSE_NORMAL); - - prompt_status = ((lcb->state == LSM_S_CONNECTED) ? - platform_get_phrase_index_str(CALL_CONNECTED) : - platform_get_phrase_index_str(CALL_INITIATE_HOLD)); - ui_set_call_status(prompt_status, line, lcb->ui_id); - - lsm_set_ringer(lcb, call_id, line, YES); - - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_hold (lsm_lcb_t *lcb, cc_state_data_hold_t *data) -{ - cc_rcs_t cc_rc; - - if (data == NULL) { - return (CC_RC_ERROR); - } - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, - "lsm_hold", "local", data->local); - - switch (data->local) { - case (TRUE): - cc_rc = lsm_hold_local(lcb, data); - break; - - case (FALSE): - cc_rc = lsm_hold_remote(lcb, data); - break; - - default: - cc_rc = CC_RC_ERROR; - break; - } - vcmEnableSidetone(NO); - return (cc_rc); -} - - -static cc_rcs_t -lsm_resume_local (lsm_lcb_t *lcb, cc_state_data_resume_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - lsm_change_state(lcb, __LINE__, LSM_S_HOLDING); - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - ui_set_call_status(platform_get_phrase_index_str(CALL_CONNECTED), - line, lcb->ui_id); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_resume_remote (lsm_lcb_t *lcb, cc_state_data_resume_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - const char *prompt_status; - - if (lcb->dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_update_media(lcb, cc_state_name(CC_STATE_RESUME)); - - prompt_status = ((lcb->state == LSM_S_CONNECTED) ? - platform_get_phrase_index_str(CALL_CONNECTED) : - platform_get_phrase_index_str(CALL_INITIATE_HOLD)); - ui_set_call_status(prompt_status, line, lcb->ui_id); - - lsm_set_ringer(lcb, call_id, line, YES); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_resume (lsm_lcb_t *lcb, cc_state_data_resume_t *data) -{ - cc_rcs_t cc_rc; - - if (data == NULL) { - return (CC_RC_ERROR); - } - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, - "lsm_resume", "local", data->local); - - switch (data->local) { - case (TRUE): - cc_rc = lsm_resume_local(lcb, data); - break; - - case (FALSE): - cc_rc = lsm_resume_remote(lcb, data); - break; - - default: - cc_rc = CC_RC_ERROR; - break; - } - - vcmActivateWlan(TRUE); - - vcmEnableSidetone(YES); - return (cc_rc); -} - - -static cc_rcs_t -lsm_onhook (lsm_lcb_t *lcb, cc_state_data_onhook_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - cc_causes_t cause; - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - dp_int_onhook(line, call_id); - - /* hard close receive and transmit channels for all media entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - - lsm_change_state(lcb, __LINE__, LSM_S_IDLE); - - if (lsm_is_phone_inactive()) { - vcmEnableSidetone(NO); - } - - ui_set_call_status(ui_get_idle_prompt_string(), line, lcb->ui_id); - - - (void) lsm_stop_tone(lcb, NULL); - - if (!sdpmode) { - vcmControlRinger(VCM_RING_OFF, NO, NO, line, dcb->call_id); - } - - lsm_set_ringer(lcb, call_id, line, YES); - - cause = data->cause; - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_XFER_COMPLETE)) { - DEF_DEBUG(DEB_F_PREFIX"Transfer complete.", DEB_F_PREFIX_ARGS(LSM, "lsm_onhook")); - cause = CC_CAUSE_XFER_COMPLETE; - } - lsm_ui_call_state(evOnHook, line, lcb, cause); - - - lsm_free_lcb(lcb); - - vcmActivateWlan(FALSE); - - vcmRemoveBandwidth(lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID)); - - return (CC_RC_SUCCESS); -} - -static cc_rcs_t -lsm_call_failed (lsm_lcb_t *lcb, cc_state_data_call_failed_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - vcm_tones_t tone; - lsm_states_t line_state; - const char *status = NULL; - call_events state; - boolean send_call_info = TRUE; - fsmdef_dcb_t *dcb; - boolean must_log = FALSE; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - /* For busy generated by UI-STATE in 183, do not manipulate the - * media port - */ - if (data->cause != CC_CAUSE_UI_STATE_BUSY) { - /* hard close receive and transmit channels for all media entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - } - - switch (data->cause) { - case (CC_CAUSE_BUSY): - line_state = LSM_S_BUSY; - state = evBusy; - tone = VCM_LINE_BUSY_TONE; - status = platform_get_phrase_index_str(LINE_BUSY); - dp_int_update(line, call_id, data->caller_id.called_number); - send_call_info = FALSE; - break; - - case (CC_CAUSE_UI_STATE_BUSY): - line_state = LSM_S_BUSY; - state = evBusy; - tone = VCM_LINE_BUSY_TONE; - dp_int_update(line, call_id, data->caller_id.called_number); - break; - - case (CC_CAUSE_INVALID_NUMBER): - line_state = LSM_S_INVALID_NUMBER; - state = evReorder; - tone = VCM_REORDER_TONE; - send_call_info = FALSE; - break; - - case (CC_CAUSE_CONGESTION): - case (CC_CAUSE_PAYLOAD_MISMATCH): - dp_int_update(line, call_id, data->caller_id.called_number); - - /* FALLTHROUGH */ - /*sa_ignore FALL_THROUGH*/ - default: - send_call_info = FALSE; - line_state = LSM_S_CONGESTION; - state = evReorder; - tone = VCM_REORDER_TONE; - if ( (data->cause == CC_CAUSE_NO_USER_ANS)|| - (data->cause == CC_TEMP_NOT_AVAILABLE) ) { - must_log = TRUE; - } - break; - } - - lsm_change_state(lcb, __LINE__, line_state); - - if (status) { - ui_set_call_status(status, line, lcb->ui_id); - } - - if (state == evReorder && !must_log) { - ui_log_disposition(dcb->call_id, CC_CALL_LOG_DISP_IGNORE); - } - - /* Send call info only if not error */ - if (send_call_info == TRUE) { - ui_call_info(data->caller_id.calling_name, - data->caller_id.calling_number, - data->caller_id.alt_calling_number, - data->caller_id.display_calling_number, - data->caller_id.called_name, - data->caller_id.called_number, - data->caller_id.display_called_number, - data->caller_id.orig_called_name, - data->caller_id.orig_called_number, - data->caller_id.last_redirect_name, - data->caller_id.last_redirect_number, - (calltype_t)dcb->call_type, - line, lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - } - - lsm_ui_call_state(state, line, lcb, CC_CAUSE_NORMAL); - - /* Tone played in remote-cc play tone request, so don't start tone again - */ - if ((data->cause != CC_CAUSE_UI_STATE_BUSY) && (data->cause != CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE)) { - fsmdef_media_t *audio_media = gsmsdp_find_audio_media(dcb); - - lsm_util_start_tone(tone, FALSE, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), dcb->group_id, - ((audio_media != NULL) ? audio_media->refid : - CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } - - return (CC_RC_SUCCESS); -} - -static void -lsm_ringer (lsm_lcb_t *lcb, cc_action_data_ringer_t *data) -{ - vcm_ring_mode_t ringer; - line_t line = lcb->line; - - ringer = (data->on == FALSE) ? (VCM_RING_OFF) : (VCM_FEATURE_RING); - - LSM_DEBUG(DEB_F_PREFIX"CTI RING SETTING: line = %d, ringer Mode = %s," - "Ring once = NO, alertInfo = NO\n", DEB_F_PREFIX_ARGS(LSM, "lsm_ringer"), - line, vm_alert_names[ringer]); - - vcmControlRinger(ringer, NO, NO, line, lcb->call_id); -} - -static cc_rcs_t -lsm_dial_mode (lsm_lcb_t *lcb, cc_action_data_dial_mode_t *data) -{ - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_mwi (lsm_lcb_t *lcb, callid_t call_id, line_t line, - cc_action_data_mwi_t *data) -{ - ui_set_mwi(line, data->on, data->type, data->newCount, data->oldCount, data->hpNewCount, data->hpOldCount); - - return (CC_RC_SUCCESS); -} - - -/* - * Function: lsm_update_ui - * - * Parameters: - * call_id: - * line: - * data: - * - * Description: This function is used to hide the UI platform details from - * the FSMs. This function is provided to allow the FSMs - * to update the UI in certain cases. - * - * Returns: rc - * - */ -cc_rcs_t -lsm_update_ui (lsm_lcb_t *lcb, cc_action_data_update_ui_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - lsm_states_t instance_state; - call_events call_state = evMaxEvent; - fsmcnf_ccb_t *ccb; - fsmdef_dcb_t *dcb; - boolean update = FALSE; - boolean inbound; - cc_feature_data_call_info_t *call_info; - call_events original_call_event; - lsm_lcb_t *lcb_tmp; - const char *conf_str;//[] = {(char)0x80, (char)0x34, (char)0x00}; - - instance_state = lcb->state; - - switch (data->action) { - case CC_UPDATE_CONF_ACTIVE: - - switch (instance_state) { - case LSM_S_RINGOUT: - call_state = evRingOut; - break; - - case LSM_S_CONNECTED: - default: - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if ((ccb != NULL) && (ccb->active == TRUE)) { - - conf_str = platform_get_phrase_index_str(UI_CONFERENCE); - lcb_tmp = lsm_get_lcb_by_call_id(ccb->cnf_call_id); - dcb = lcb_tmp->dcb; - ui_call_info(CALL_INFO_NONE, - CALL_INFO_NONE, - CALL_INFO_NONE, - 0, - conf_str, - CALL_INFO_NONE, - 0, - CALL_INFO_NONE, - CALL_INFO_NONE, - CALL_INFO_NONE, - CALL_INFO_NONE, - FSMDEF_CALL_TYPE_OUTGOING, - dcb->line, lcb_tmp->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - - call_state = evConference; - - } else if (instance_state == LSM_S_CONNECTED) { - - call_state = evConnected; - - } else { - - call_state = evRingOut; - } - break; - } /* switch (instance_state) { */ - - break; - - case CC_UPDATE_CALLER_INFO: - - /* For local conference, do not update the primary - * call bubbles call-info. Primary call is already - * displaying To conference in this case - * But dcb-> caller_id should be updated to - * refresh the UI when the call is dropped - */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb && (ccb->flags & LCL_CNF) && - (ccb->cnf_call_id == call_id)) { - break; - } - - call_info = &data->data.caller_info; - dcb = lcb->dcb; - if (dcb == NULL || call_info == NULL) { - return (CC_RC_ERROR); - } - - inbound = dcb->inbound; - if (call_info->feature_flag & CC_ORIENTATION) { - inbound = - (call_info->orientation == CC_ORIENTATION_FROM) ? TRUE : FALSE; - update = TRUE; - } - - if (call_info->feature_flag & CC_CALLER_ID) { - update = TRUE; - /* - * This "if" block, without the "&& inbound" condition, was put in by Serhad - * to fix CSCsm58054 and it results in CSCso98110. The "inbound" condition - * is added to narrow the scope of CSCsm58054's fix. Note that "inbound" here - * refers to the perceived orientation set in call info. So for example, in case - * of a 3-way conf, and phone is the last party to receive the call, is ringing - * and then be joined into a conference, direction would be outbound. The display - * would say "To Conference". - */ - if ( (instance_state == LSM_S_RINGIN) && inbound ) { - cc_state_data_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - lsm_update_inalert_status(line, lcb->ui_id, &alerting_data, TRUE); - } - } - - if (call_info->feature_flag & CC_CALL_INSTANCE) { - update = TRUE; - } - - if (call_info->feature_flag & CC_SECURITY) { - update = TRUE; - } - - if (call_info->feature_flag & CC_POLICY) { - update = TRUE; - } - - /* - * If we are going to spoof ring out, skip the explicit UI update. - * the far end alerting handling will update the UI. Do not - * update UI twice. - */ - if (dcb->spoof_ringout_requested && - !dcb->spoof_ringout_applied && - lcb->state == LSM_S_CONNECTED) { - cc_state_data_far_end_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - (void) lsm_far_end_alerting(lcb, &alerting_data); - dcb->spoof_ringout_applied = TRUE; - } else if (update && dcb->ui_update_required) { - - calltype_t call_type; - - if (dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) { - call_type = (inbound) ? (calltype_t)dcb->call_type:FSMDEF_CALL_TYPE_OUTGOING; - } else { - if (inbound) { - call_type = FSMDEF_CALL_TYPE_INCOMING; - } else { - call_type = FSMDEF_CALL_TYPE_OUTGOING; - } - } - - ui_call_info(dcb->caller_id.calling_name, - dcb->caller_id.calling_number, - dcb->caller_id.alt_calling_number, - dcb->caller_id.display_calling_number, - dcb->caller_id.called_name, - dcb->caller_id.called_number, - dcb->caller_id.display_called_number, - dcb->caller_id.orig_called_name, - dcb->caller_id.orig_called_number, - dcb->caller_id.last_redirect_name, - dcb->caller_id.last_redirect_number, - call_type, - line, - lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - - dcb->ui_update_required = FALSE; - - conf_str = platform_get_phrase_index_str(UI_CONFERENCE); - if(cpr_strncasecmp(dcb->caller_id.called_name, conf_str, strlen(conf_str)) == 0){ - dcb->is_conf_call = TRUE; - } else { - dcb->is_conf_call = FALSE; - } - } - - break; - - case CC_UPDATE_SET_CALL_STATUS: - { - /* set call status line */ - cc_set_call_status_data_t *call_status_p = - &data->data.set_call_status_parms; - ui_set_call_status(call_status_p->phrase_str_p, call_status_p->line, - lcb->ui_id); - break; - } - case CC_UPDATE_SET_NOTIFICATION: - { - /* set status line notification */ - cc_set_notification_data_t *call_notification_p = - &data->data.set_notification_parms; - ui_set_notification(line, lcb->ui_id, - call_notification_p->phrase_str_p, - call_notification_p->timeout, FALSE, - (char)call_notification_p->priority); - break; - } - case CC_UPDATE_CLEAR_NOTIFICATION: - /* clear status line notification */ - ui_clear_notification(); - break; - - case CC_UPDATE_SECURITY_STATUS: - /* update security status */ - break; - - case CC_UPDATE_XFER_PRIMARY: - call_state = evConnected; - break; - - case CC_UPDATE_CALL_PRESERVATION: - - /* Call is in preservation mode. Update UI so that only endcall softkey is available */ - ui_call_in_preservation(line, lcb->ui_id); - break; - - case CC_UPDATE_CALL_CONNECTED: - if (instance_state == LSM_S_CONNECTED) { - call_state = evConnected; - } - break; - - case CC_UPDATE_CONF_RELEASE: - dcb = lcb->dcb; - - if (instance_state == LSM_S_CONNECTED) { - call_state = evConnected; - - } else if (instance_state == LSM_S_RINGOUT) { - call_state = evRingOut; - } - - /* - * If we are going to spoof ring out, skip the explicit UI update. - * the far end alerting handling will update the UI. Do not - * update UI twice. - */ - if (dcb->spoof_ringout_requested && - !dcb->spoof_ringout_applied && - lcb->state == LSM_S_CONNECTED) { - cc_state_data_far_end_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - (void) lsm_far_end_alerting(lcb, &alerting_data); - dcb->spoof_ringout_applied = TRUE; - - call_state = evRingOut; - - } else { - calltype_t call_type; - if (dcb->orientation == CC_ORIENTATION_FROM) { - call_type = FSMDEF_CALL_TYPE_INCOMING; - } else if (dcb->orientation == CC_ORIENTATION_TO) { - call_type = FSMDEF_CALL_TYPE_OUTGOING; - } else { - call_type = (calltype_t)(dcb->call_type); - } - ui_call_info(dcb->caller_id.calling_name, - dcb->caller_id.calling_number, - dcb->caller_id.alt_calling_number, - dcb->caller_id.display_calling_number, - dcb->caller_id.called_name, - dcb->caller_id.called_number, - dcb->caller_id.display_called_number, - dcb->caller_id.orig_called_name, - dcb->caller_id.orig_called_number, - dcb->caller_id.last_redirect_name, - dcb->caller_id.last_redirect_number, - call_type, - line, - lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - } - - - break; - - default: - break; - } - - if (call_state != evMaxEvent) { - original_call_event = lcb->previous_call_event; - - lsm_ui_call_state(call_state, line, lcb, CC_CAUSE_NORMAL); - if (original_call_event != call_state) { - /* Call state changed, take care of special event */ - switch (call_state) { - case evConference: - break; - - case evConnected: - case evWhisper: - ui_set_call_status( - platform_get_phrase_index_str(CALL_CONNECTED), - line, lcb->ui_id); - break; - - default: - break; - } - } - } - - return (CC_RC_SUCCESS); -} - - -/* - * Function: lsm_update_placed_callinfo - * - * Description: this helps log dialed digits (as opposed to RPID provided - * value) into placed calls. This also decides whether to - * log called party name received in RPID. - * - * Parameters: dcb - pointer to default SM control block - * - * Returns: none - * - */ -#define CISCO_PLAR_STRING "x-cisco-serviceuri-offhook" -void -lsm_update_placed_callinfo (void *data) -{ - const char *tmp_called_number = NULL; - const char *called_name = NULL; - fsmdef_dcb_t *dcb = NULL; - lsm_lcb_t *lcb; - static const char fname[] = "lsm_update_placed_callinfo"; - boolean has_called_number = FALSE; - - LSM_DEBUG(DEB_F_PREFIX"Entering ...", DEB_F_PREFIX_ARGS(LSM, fname)); - dcb = (fsmdef_dcb_t *) data; - lcb = lsm_get_lcb_by_call_id(dcb->call_id); - if (lcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"Exiting: lcb not found", DEB_F_PREFIX_ARGS(LSM, fname)); - return; - } - - if (dcb->caller_id.called_number != NULL && - dcb->caller_id.called_number[0] != NUL) { - has_called_number = TRUE; - } - - - tmp_called_number = lsm_get_gdialed_digits(); - - - /* if tmp_called_number is NULL or empty, return */ - if (tmp_called_number == NULL || (*tmp_called_number) == NUL) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Exiting : dialed digits is empty", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname)); - return; - } - - /* - * if tmp_called_number is same as what we receive in RPID, - * then get the called name from RPID if provided. - */ - if (has_called_number) { - if (strcmp(tmp_called_number, CISCO_PLAR_STRING) == 0) { - tmp_called_number = dcb->caller_id.called_number; - } - /* if RPID number matches, dialed digits, use RPID name */ - if (strcmp(dcb->caller_id.called_number, tmp_called_number) == 0) { - called_name = dcb->caller_id.called_name; - } else { - char tmp_str[STATUS_LINE_MAX_LEN]; - platGetPhraseText(STR_INDEX_ANONYMOUS_SPACE, (char *)tmp_str, STATUS_LINE_MAX_LEN - 1); - if(strcmp(dcb->caller_id.called_number,tmp_str) == 0 - && strcmp(dcb->caller_id.orig_rpid_number, tmp_called_number) == 0 - && strcmp(dcb->caller_id.called_name, platform_get_phrase_index_str(UI_UNKNOWN)) != 0) { - called_name = dcb->caller_id.called_name; - } - } - } - ui_update_placed_call_info(lcb->line, lcb->call_id, called_name, - tmp_called_number); - LSM_DEBUG(DEB_L_C_F_PREFIX"Exiting: invoked ui_update_placed_call_info()", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname)); -} - -cc_int32_t -lsm_show_cmd (cc_int32_t argc, const char *arv[]) -{ - int i = 0; - lsm_lcb_t *lcb; - - debugif_printf("\n------------------ LSM lcbs -------------------"); - debugif_printf("\ni call_id line state lcb"); - debugif_printf("\n-----------------------------------------------\n"); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - debugif_printf("%-2d %-7d %-4d %-16s 0x%8p\n", - i++, lcb->call_id, lcb->line, - lsm_state_name(lcb->state), lcb); - - } - - return (0); -} - -void -lsm_init_config (void) -{ - /* - * The silent period between call waiting bursts is now configurable - * for TNP phones. Store away the value for the callwaiting code to use. - * The config is in seconds, but CPR expects the duration in milliseconds - * thus multiply the config value by 1000. Non-TNP phones default to - * 10 seconds. - */ - config_get_value(CFGID_CALL_WAITING_SILENT_PERIOD, &callWaitingDelay, - sizeof(callWaitingDelay)); - callWaitingDelay = callWaitingDelay * 1000; -} - -void -lsm_init (void) -{ - static const char fname[] = "lsm_init"; - lsm_lcb_t *lcb; - int i; - - /* - * Init the lcbs. - */ - lsm_lcbs = (lsm_lcb_t *) cpr_calloc(LSM_MAX_LCBS, sizeof(lsm_lcb_t)); - if (lsm_lcbs == NULL) { - LSM_ERR_MSG(LSM_F_PREFIX"lsm_lcbs cpr_calloc returned NULL", fname); - return; - } - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - lsm_init_lcb(lcb); - } - - /* - * Create tones and continous tone timer. The same call back function - * is utilized for each of these timers. - */ - lsm_tmr_tones = cprCreateTimer("lsm_tmr_tones", - GSM_MULTIPART_TONES_TIMER, - TIMER_EXPIRATION, gsm_msgq); - lsm_continuous_tmr_tones = cprCreateTimer("lsm_continuous_tmr_tones", - GSM_CONTINUOUS_TONES_TIMER, - TIMER_EXPIRATION, - gsm_msgq); - lsm_tone_duration_tmr = cprCreateTimer("lsm_tone_duration_tmr", - GSM_TONE_DURATION_TIMER, - TIMER_EXPIRATION, gsm_msgq); - lsm_init_config(); - - for (i=0 ; ioffhook)); -#ifdef TEST - test_dial_calls(line, call_id, 500, "10011234"); -#endif - break; - - case CC_STATE_DIALING: - result = lsm_dialing(lcb, &(data->dialing)); - break; - - case CC_STATE_DIALING_COMPLETED: - result = lsm_dialing_completed(lcb, &(data->dialing_completed)); - break; - - case CC_STATE_CALL_SENT: - result = lsm_call_sent(lcb, &(data->call_sent)); - break; - - case CC_STATE_FAR_END_PROCEEDING: - result = lsm_far_end_proceeding(lcb, &(data->far_end_proceeding)); - break; - - case CC_STATE_FAR_END_ALERTING: - result = lsm_far_end_alerting(lcb, &(data->far_end_alerting)); - break; - - case CC_STATE_CALL_RECEIVED: - result = lsm_call_received(lcb, &(data->call_received)); - break; - - case CC_STATE_ALERTING: - result = lsm_alerting(lcb, &(data->alerting)); - break; - - case CC_STATE_ANSWERED: - result = lsm_answered(lcb, &(data->answered)); - break; - - case CC_STATE_CONNECTED: - result = lsm_connected(lcb, &(data->connected)); -#ifdef TEST - test_disc_call(line, call_id); - test_line_offhook(line, cc_get_new_call_id()); -#endif - break; - - case CC_STATE_HOLD: - result = lsm_hold(lcb, &(data->hold)); - break; - - case CC_STATE_HOLD_REVERT: - result = lsm_hold_reversion(lcb); - break; - - case CC_STATE_RESUME: - result = lsm_resume(lcb, &(data->resume)); - break; - - case CC_STATE_ONHOOK: - result = lsm_onhook(lcb, &(data->onhook)); - break; - - case CC_STATE_CALL_FAILED: - result = lsm_call_failed(lcb, &(data->call_failed)); - break; - - default: - break; - } - - if (result == CC_RC_ERROR) { - LSM_DEBUG(get_debug_string(LSM_DBG_CC_ERROR), call_id, line, fname, - state, data); - } - - return; -} - -static cc_rcs_t -lsm_media (lsm_lcb_t *lcb, callid_t call_id, line_t line) -{ - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - if (!dcb->spoof_ringout_requested) { - lsm_update_media(lcb, "MEDIA"); - vcmEnableSidetone(YES); - } else if (!dcb->spoof_ringout_applied && - (lcb->state == LSM_S_CONNECTED)) { - cc_state_data_far_end_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - (void) lsm_far_end_alerting(lcb, &alerting_data); - dcb->spoof_ringout_applied = TRUE; - } - - return (CC_RC_SUCCESS); -} - -/* - * Function: lsm_stop_media - * - * Parameters: - * lcb - pointer to lsm_lcb_t, - * call_id - gsm call id for the call in used. - * line - line_t for the line number (dn line). - * data - action data. - * - * Description: - * The function simply stops media (close Rx and Tx) and set the - * proper ringer. - * - * Returns: None. - */ -static void -lsm_stop_media (lsm_lcb_t *lcb, callid_t call_id, line_t line, - cc_action_data_t *data) -{ - static const char fname[] = "lsm_stop_media"; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_DEBUG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - /* hard close receive and transmit channels */ - if ((data == NULL) || - (data->stop_media.media_refid == CC_NO_MEDIA_REF_ID)) { - /* no data provided or no specific ref ID, defaul to all entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - } else { - /* look up the media entry for the given reference ID */ - media = gsmsdp_find_media_by_refid(dcb, - data->stop_media.media_refid); - if (media != NULL) { - lsm_close_rx(lcb, FALSE, media); - lsm_close_tx(lcb, FALSE, media); - } else { - /* no entry found */ - LSM_DEBUG(DEB_L_C_F_PREFIX"no media with reference ID %d found", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), - data->stop_media.media_refid); - return; - } - } - lsm_set_ringer(lcb, call_id, line, YES); -} - - - -/* - * lsm_add_remote_stream - * - * Description: - * The function adds a remote stream to the media subsystem - * - * Parameters: - * [in] line - line - * [in] call_id - GSM call ID - * [in] media - media line to add as remote stream - * [out] pc_stream_id - * - * Returns: CC_RC_SUCCESS or CC_RC_ERROR if unable to create or add stream - */ -cc_rcs_t -lsm_add_remote_stream (line_t line, callid_t call_id, fsmdef_media_t *media, int *pc_stream_id) -{ - lsm_lcb_t *lcb; - fsmdef_dcb_t *dcb; - int vcm_ret; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (!lcb) { - CSFLogError(logTag, "%s: lcb is null", __FUNCTION__); - return CC_RC_ERROR; - } - - dcb = lcb->dcb; - if (!dcb) { - CSFLogError(logTag, "%s: dcb is null", __FUNCTION__); - return CC_RC_ERROR; - } - - vcm_ret = vcmCreateRemoteStream(media->cap_index, dcb->peerconnection, - pc_stream_id); - - if (vcm_ret) { - CSFLogError(logTag, "%s: vcmCreateRemoteStream returned error: %d", - __FUNCTION__, vcm_ret); - return CC_RC_ERROR; - } - - return CC_RC_SUCCESS; -} - -/* - * lsm_initialize_datachannel - * - * Description: - * The function initializes the datachannel with port and - * protocol info. - * - * Parameters: - * [in] dcb - pointer to get the peerconnection id - * [in] media - pointer to get the datachannel info - * [in] track_id - track ID (aka m-line number) - * Returns: None - */ -void lsm_initialize_datachannel (fsmdef_dcb_t *dcb, fsmdef_media_t *media, - int track_id) -{ - if (!dcb) { - CSFLogError(logTag, "%s DCB is NULL", __FUNCTION__); - return; - } - - if (!media) { - CSFLogError(logTag, "%s media is NULL", __FUNCTION__); - return; - } - - /* - * have access to media->cap_index, media->streams, media->protocol, - * media->local/remote_datachannel_port - */ - vcmInitializeDataChannel(dcb->peerconnection, - track_id, media->datachannel_streams, - media->local_datachannel_port, media->remote_datachannel_port, - media->datachannel_protocol); -} - -/** - * - * Peform non call related action - * - * @param line_t line - * @param callid_t gsm_id - * @param action type of action - * @param cc_action_data_t line - * - * @return true if the action has been peformed, else false - * - * @pre (action == CC_ACTION_MWI_LAMP_ONLY || CC_ACTION_SET_LINE_RINGER || - CC_ACTION_PLAY_BLF_ALERTING_TONE) - */ -static boolean -cc_call_non_call_action (callid_t call_id, line_t line, - cc_actions_t action, cc_action_data_t *data) -{ - /* Certain requests are device based and does not contain any - * line number and call_id associated with it. So handle thoese - * requests here - */ - switch (action) { - - case CC_ACTION_MWI_LAMP_ONLY: - if (data != NULL) { - ui_change_mwi_lamp(data->mwi.on); - return(TRUE); - } - break; - - case CC_ACTION_SET_LINE_RINGER: - - if (data != NULL) { - return(TRUE); - } - break; - - case CC_ACTION_PLAY_BLF_ALERTING_TONE: - lsm_play_tone(CC_FEATURE_BLF_ALERT_TONE); - return TRUE; - - default: - break; - } - - return(FALSE); -} - -/* - * LSM API supports various actions such as play tone, stop tone, - * direct media operation etc. - * - * @param[in] call_id GSM call ID of an active call. - * @param[in] line line number of the line_t type. - * @param[in] action cc_actions_t for the desired action. - * @param[in] data cc_action_data_t data or parameters that may be - * required for certain action. - * - * @return cc_rcs_t status. - * - * @pre line not_eqs CC_NO_LINE - * @pre ((action equals CC_ACTION_PLAY_TONE) or - * (action equals CC_ACTION_STOP_TONE) or - * (action equals CC_ACTION_DIAL_MODE) or - * (action equals CC_ACTION_MWI) or - * (action equals CC_ACTION_OPEN_RCV) or - * (action equals CC_ACTION_UPDATE_UI) or - * (action equals CC_ACTION_RINGER)) - */ -cc_rcs_t -cc_call_action (callid_t call_id, line_t line, cc_actions_t action, - cc_action_data_t *data) -{ - static const char fname[] = "cc_call_action"; - cc_rcs_t result = CC_RC_SUCCESS; - lsm_lcb_t *lcb; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - - LSM_DEBUG(get_debug_string(LSM_DBG_ENTRY), call_id, line, - cc_action_name(action)); - - /* perform non call related actions. lcb is not required - * for these actions - */ - if (cc_call_non_call_action(call_id, line, action, data)) { - return (result); - } - - lcb = lsm_get_lcb_by_call_id(call_id); - - if ((lcb == NULL) && (action != CC_ACTION_MWI)) { - LSM_DEBUG(get_debug_string(DEBUG_INPUT_NULL), fname); - return (CC_RC_ERROR); - } - - switch (action) { - case CC_ACTION_PLAY_TONE: - if (data != NULL) { - result = lsm_start_tone(lcb, &(data->tone)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_STOP_TONE: - if (data != NULL) { - result = lsm_stop_tone(lcb, &(data->tone)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_SPEAKER: - break; - - case CC_ACTION_DIAL_MODE: - if (data != NULL) { - result = lsm_dial_mode(lcb, &(data->dial_mode)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_MWI: - if (data != NULL) { - result = lsm_mwi(NULL, call_id, line, &(data->mwi)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_OPEN_RCV: - if (data != NULL) { - result = lsm_open_rx(lcb, &(data->open_rcv), NULL); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_UPDATE_UI: - if (data != NULL) { - result = lsm_update_ui(lcb, &(data->update_ui)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_MEDIA: - result = lsm_media(lcb, call_id, line); - break; - - case CC_ACTION_RINGER: - if (data != NULL) { - lsm_ringer(lcb, &(data->ringer)); - } - break; - - case CC_ACTION_STOP_MEDIA: - lsm_stop_media(lcb, call_id, line, data); - break; - - case CC_ACTION_START_RCV: - /* start receiving */ - dcb = lcb->dcb; - if (dcb == NULL) { - /* No call ID */ - result = CC_RC_ERROR; - break; - } - - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not active */ - continue; - } - - /* only support starting all receive channels for now */ - lsm_rx_start(lcb, fname, media); - } - break; - - case CC_ACTION_ANSWER_PENDING: - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING); - break; - - default: - break; - } - - - if (result == CC_RC_ERROR) { - LSM_DEBUG(get_debug_string(LSM_DBG_CC_ERROR), call_id, line, fname, - action, data); - } - - return (result); -} - - -void -lsm_ui_display_notify (const char *notify_str, unsigned long timeout) -{ - /* - * add 0 as (default) priority; it is don't care in legacy mode - */ - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, - (char *)notify_str, (int)timeout, FALSE, - DEF_NOTIFY_PRI); -} - -void -lsm_ui_display_status (const char *status_str, line_t line, callid_t call_id) -{ - lsm_lcb_t *lcb; - - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - return; - } - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return; - } - - ui_set_call_status((char *) status_str, line, lcb->ui_id); -} - -/** - * This function will display notification status line. - * - * @param[in] str_index - index into phrase dictionary - * - * @return none - */ -void lsm_ui_display_notify_str_index (int str_index) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(str_index, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -/* - * Function: lsm_parse_displaystr - * - * Parameters:string to be parsed - * - * Description:Wrapper function for parsing string to be displayed - * - * Returns: Pointer to parsed number - * - */ -string_t -lsm_parse_displaystr (string_t displaystr) -{ - return (sippmh_parse_displaystr(displaystr)); -} - -void -lsm_speaker_mode (short mode) -{ - ui_set_speaker_mode((boolean)mode); -} - -/* - * Function:lsm_update_active_tone - * - * Parameters: - * tone - tone type - * call_id - call identifier - * - * Description: Update dcb->active_tone if starting infinite duration tone. - * - * Returns:none - * - */ -void -lsm_update_active_tone (vcm_tones_t tone, callid_t call_id) -{ - static const char fname[] = "lsm_update_active_tone"; - fsmdef_dcb_t *dcb; - - /* if tone is any of following then set active_tone in dcb b/c these - * tones have infinite duration and need to be stopped. Other tones - * only play for a finite/short duration so no need to stop them as - * they will stop automatically. - */ - switch (tone) { - /* for all tones with infinite playing duration */ - case VCM_INSIDE_DIAL_TONE: - case VCM_LINE_BUSY_TONE: - case VCM_ALERTING_TONE: - case VCM_STUTTER_TONE: - case VCM_REORDER_TONE: - case VCM_OUTSIDE_DIAL_TONE: - case VCM_PERMANENT_SIGNAL_TONE: - case VCM_RECORDERWARNING_TONE: - case VCM_MONITORWARNING_TONE: - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - /* Possibibly the ui_id was passed in and the dcb is no longer existed. - * Try to retrieve the corresponding dcb. - */ - dcb = fsmdef_get_dcb_by_call_id(lsm_get_callid_from_ui_id(call_id)); - } - - if (dcb != NULL) { - /* Ideally a call should not make a infinite tone start request - * (without making a stop request) while there is already one playing. - * However, DSP will start playing the new request tone by overriding - * the current one. Technically its okay. So, just printing a log msg. - */ - if (dcb->active_tone != VCM_NO_TONE) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Active Tone current = %d new = %d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname), - dcb->active_tone, tone); - } - dcb->active_tone = tone; - } - break; - - default: - /* do nothing */ - break; - } -} - -/* - * Function: lsm_is_tx_channel_opened - * - * Parameters: call_id - * - * Description: check to see tx channel is openned - * - * Returns: TRUE or FALSE - * - */ -boolean -lsm_is_tx_channel_opened(callid_t call_id) -{ - fsmdef_dcb_t *dcb_p = fsmdef_get_dcb_by_call_id(call_id); - fsmdef_media_t *media = NULL; - - if (dcb_p == NULL) { - return (FALSE); - } - - /* - * search the all entries that has a valid media and matches - * SDP_MEDIA_AUDIO type. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == SDP_MEDIA_AUDIO) { - /* found a match */ - if (media->xmit_chan) - return (TRUE); - } - } - return (FALSE); -} - -/* - * Function:lsm_update_monrec_tone_action - * - * Parameters: - * tone - tone type - * call_id - call identifier - * - * Description: Update dcb->monrec_tone_action. - * - * Returns:none - * - */ -void -lsm_update_monrec_tone_action (vcm_tones_t tone, callid_t call_id, uint16_t direction) -{ - static const char fname[] = "lsm_update_monrec_tone_action"; - fsmdef_dcb_t *dcb; - boolean tx_opened = lsm_is_tx_channel_opened(call_id); - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb != NULL) { - switch(tone) { - case VCM_MONITORWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_NO_ACTION: - if (!tx_opened) { - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_MONITOR_TONE; - } else { - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_MONITOR_TONE; - } - break; - - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_BOTH_TONES; - break; - - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_BOTH_TONES; - break; - - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->monitor_tone_direction = direction; - break; - - case VCM_RECORDERWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_NO_ACTION: - if (!tx_opened) { - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_RECORDER_TONE; - } else { - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_RECORDER_TONE; - } - break; - - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_BOTH_TONES; - break; - - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_BOTH_TONES; - break; - - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->recorder_tone_direction = direction; - break; - - default: - break; - } /* end of switch */ - - LSM_DEBUG(DEB_L_C_F_PREFIX"Start request for tone: %d. Set monrec_tone_action: %d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname), - tone, dcb->monrec_tone_action); - - } /* end of if */ -} - -/* - * Function:lsm_downgrade_monrec_tone_action - * - * Parameters: - * tone - tone type - * call_id - call identifier - * - * Description: Update dcb->monrec_tone_action. - * - * Returns:none - * - */ -void -lsm_downgrade_monrec_tone_action (vcm_tones_t tone, callid_t call_id) -{ - static const char fname[] = "lsm_downgrade_monrec_tone_action"; - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - /* Need to downgrade the monrec_tone_action */ - - if (dcb != NULL) { - switch (tone){ - case VCM_MONITORWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_NO_ACTION; - break; - - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_RECORDER_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_RECORDER_TONE; - break; - - case FSMDEF_MRTONE_NO_ACTION: - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->monitor_tone_direction = VCM_PLAY_TONE_TO_EAR; - break; - - case VCM_RECORDERWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_NO_ACTION; - break; - - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_MONITOR_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_MONITOR_TONE; - break; - - case FSMDEF_MRTONE_NO_ACTION: - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->recorder_tone_direction = VCM_PLAY_TONE_TO_EAR; - break; - - default: - break; - } /* end of switch */ - - LSM_DEBUG(DEB_L_C_F_PREFIX"Stop request for tone: %d Downgrade monrec_tone_action: %d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname), - tone, dcb->monrec_tone_action); - } /* end of if */ -} - -/* - * Function: lsm_set_hold_ringback_status - * - * Parameters: - * callid_t - callid of the lcb - * ringback_status - status of call hold ringback - * - * Description: Function used to set the ringback status - * - * Returns:None - * - */ -void -lsm_set_hold_ringback_status(callid_t call_id, boolean ringback_status) -{ - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id == call_id) { - LSM_DEBUG(DEB_F_PREFIX"Setting ringback to %d for lcb %d", - DEB_F_PREFIX_ARGS(LSM, "lsm_set_hold_ringback_status"), ringback_status, call_id); - lcb->enable_ringback = ringback_status; - break; - } - } -} - -void lsm_play_tone (cc_features_t feature_id) -{ - int play_tone; - - switch (feature_id) { - case CC_FEATURE_BLF_ALERT_TONE: - if (lsm_find_state(LSM_S_RINGIN) > CC_NO_CALL_ID) { - // No tone if we have calls in ringing state - return; - } - - if (!lsm_callwaiting()) { - config_get_value(CFGID_BLF_ALERT_TONE_IDLE, &play_tone, sizeof(play_tone)); - if (play_tone == 0) { - return; - } - lsm_util_tone_start_with_speaker_as_backup(VCM_CALL_WAITING_TONE, VCM_ALERT_INFO_OFF, - CC_NO_CALL_ID, CC_NO_GROUP_ID, - CC_NO_MEDIA_REF_ID, VCM_PLAY_TONE_TO_EAR); - } else { - config_get_value(CFGID_BLF_ALERT_TONE_BUSY, &play_tone, sizeof(play_tone)); - if (play_tone == 0) { - return; - } - lsm_util_tone_start_with_speaker_as_backup(VCM_CALL_WAITING_TONE, VCM_ALERT_INFO_OFF, - CC_NO_CALL_ID, CC_NO_GROUP_ID, - CC_NO_MEDIA_REF_ID, VCM_PLAY_TONE_TO_EAR); - } - break; - - default: - break; - } -} - -/* - * lsm_update_inalert_status - * - * Description: - * - * TNP specific implementation of status line update for inalert state. - * - * Parameters: - * - * line_t line - Line facility of the call - * callid_t call_id - Call id of call whose state is being reported - * cc_state_data_alerting_t * data - alerting callinfo. - * boolean notify - whether the msg be displayed at notify level. - * - * Returns: None - */ -static void -lsm_update_inalert_status (line_t line, callid_t call_id, - cc_state_data_alerting_t * data, - boolean notify) -{ - static const char fname[] = "lsm_update_inalert_status"; - char disp_str[LSM_DISPLAY_STR_LEN]; - - // get localized tag index for From and append one space character - sstrncpy(disp_str, platform_get_phrase_index_str(UI_FROM), - sizeof(disp_str)); - - LSM_DEBUG(DEB_L_C_F_PREFIX"+++ calling number = %s", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - data->caller_id.calling_number); - - // append calling number if present or localized tag for Unknown Number - // otherwise - if ((data->caller_id.calling_number) && - (data->caller_id.calling_number[0] != '\0') && - data->caller_id.display_calling_number) { - - sstrncat(disp_str, data->caller_id.calling_number, - sizeof(disp_str) - strlen(disp_str)); - } else { - sstrncat(disp_str, platform_get_phrase_index_str(UI_UNKNOWN), - sizeof(disp_str) - strlen(disp_str)); - } - - // we display (via notification) the "From ..." info for 10 seconds. - // Note that this will remain displayed for 10 sec even if the user - // answers the call or switches to another call. This happens because - // notification has higher priority than call status (e.g. connected). - // This is done to have parity with SCCP phone behavior. - if (notify == TRUE) { - ui_set_notification(line, call_id, - (char *)disp_str, (unsigned long)CALL_ALERT_TIMEOUT, - FALSE, FROM_NOTIFY_PRI); - } - // After the notification we wish to set the call status to From XXXX. Same as SCCP phone behavior - lsm_ui_display_status((char *)disp_str, line, call_id); - - return; -} - - - -/* - * lsm_set_cfwd_all_nonccm - * This function calls JNI API to set the CFA state and DN in non-ccm mode. - * - * @param[in] line - line on which to set the CFA - * @param[in] callfwd_dialstring: CFA DN (will be stored in flash) - * - * @return: None - */ -void -lsm_set_cfwd_all_nonccm (line_t line, char *callfwd_dialstring) -{ - // call Java API - ui_cfwd_status(line, TRUE, callfwd_dialstring, TRUE); -} - -/* - * lsm_set_cfwd_all_ccm - * - * Description: - * This function calls JNI API to set the CFA state and DN in ccm mode. - * - * Parameters: - * char * callfwd_dialstring: CFA DN (will NOT be stored in flash) - * - * Returns: None - */ -void -lsm_set_cfwd_all_ccm (line_t line, char *callfwd_dialstring) -{ - // set locally maintained variable - cfwdall_state_in_ccm_mode[line] = TRUE; - - // call Java API - ui_cfwd_status((line_t)line, TRUE, callfwd_dialstring, FALSE); -} - -/* - * lsm_clear_cfwd_all_nonccm - * This function calls JNI API to clear the CFA state and DN in non-ccm mode. - * - * @param[in] line - line on which to clear the CFA - * - * @return: None - */ -void -lsm_clear_cfwd_all_nonccm (line_t line) -{ - // call Java API - ui_cfwd_status(line, FALSE, "", TRUE); -} - - -/* - * lsm_clear_cfwd_all_ccm - * - * Description: - * This function calls JNI API to clear the CFA state and DN in ccm mode. - * - * Parameters: None - * - * Returns: None - */ -void -lsm_clear_cfwd_all_ccm (line_t line) -{ - // clear locally maintained variable - cfwdall_state_in_ccm_mode[line] = FALSE; - - // call Java API - ui_cfwd_status((line_t)line, FALSE, "", FALSE); -} - -/* - * lsm_check_cfwd_all_nonccm - * - * Description: - * This function returns the CFA state in non-ccm mode. - * - * @param[in] line - line on which to check the CFA - * - * @return: TRUE (if CFA set) or FALSE (if CFA clear) - */ -int -lsm_check_cfwd_all_nonccm (line_t line) -{ - char cfg_cfwd_url[MAX_URL_LENGTH]; - - cfg_cfwd_url[0] = '\0'; - - // get the callfwdall url value from the config/flash table - config_get_string(CFGID_LINE_CFWDALL+line-1, cfg_cfwd_url, MAX_URL_LENGTH); - - // return appropriate value: TRUE if non-NULL and FALSE otherwise - if (cfg_cfwd_url[0]) { - return ((int) TRUE); - } else { - return ((int) FALSE); - } -} - -/* - * lsm_check_cfwd_all_ccm - * - * Description: - * This function returns the CFA state in ccm mode. - * - * Parameters: None - * - * Returns: TRUE or FALSE - */ -int -lsm_check_cfwd_all_ccm (line_t line) -{ - return ((int) cfwdall_state_in_ccm_mode[line]); -} - -/* - * lsm_is_phone_forwarded - * - * Description: - * This function is called from SIP stack to check if received INVITE - * should be responded with 302 or not. In the CCM mode this function - * will always return NULL... that is process the INVITE as normal and - * DO NOT 302 it. In the non-CCM mode, if the cfwdall_url is non-NULL - * then it will form a proper string to use in 302 response; otherwise - * a NULL will be returned and the INVITE will be processed as normal. - * NOTE: most all code is reused from the legacy phone code. - * - * Parameters: line - line for which to check the CFA status - * - * Returns: NULL if forwarding is not set; - * string to use in 302 response if forwarding is set (non-CCM only) - */ -char * -lsm_is_phone_forwarded (line_t line) -{ - static const char fname[] = "lsm_is_phone_forwarded"; - char proxy_ipaddr_str[MAX_IPADDR_STR_LEN]; - int port_number = 5060; // use this value only if none found - char *domain = NULL; - char *port = NULL; - cpr_ip_addr_t proxy_ipaddr; - - - LSM_DEBUG(DEB_F_PREFIX"called", DEB_F_PREFIX_ARGS(LSM, fname)); - - // check if running in CCM mode. if so, return NULL that is cfwdall - // not applicable - if (sip_regmgr_get_cc_mode(TEL_CCB_START) == REG_MODE_CCM) { - return (NULL); - } - // get stored callfwdall url value from the config/flash table - - config_get_string(CFGID_LINE_CFWDALL+line-1, cfwdall_url, sizeof(cfwdall_url)); - - if (cfwdall_url[0]) { - // find domain and port - domain = strchr(cfwdall_url, '@'); - if (!domain) { - (void) sipTransportGetServerAddress(&proxy_ipaddr, - 1, TEL_CCB_START); - if (proxy_ipaddr.type != CPR_IP_ADDR_INVALID) { - ipaddr2dotted(proxy_ipaddr_str, &proxy_ipaddr); - port_number = sipTransportGetServerPort(1, TEL_CCB_START); - } - } else { - port = strchr(domain + 1, ':'); - } - - // handle 3 cases - if (domain == NULL) { - /* case (1): no domain or port present - * We have proxy's dotted ip address format. So, not FQDN check. - * Append domain/ip-addr and port. - */ - snprintf(cfwdall_url + strlen(cfwdall_url), - MAX_URL_LENGTH - strlen(cfwdall_url), - "@%s:%d", proxy_ipaddr_str, port_number); - } else if (port == NULL) { - /* case (2): domain present but no port - * Check if the domain is dotted IP address and add port - * only if dotted IP address is used - */ - if (!str2ip((const char *) domain + 1, &proxy_ipaddr)) { - port_number = sipTransportGetServerPort(1, TEL_CCB_START); - snprintf(cfwdall_url + strlen(cfwdall_url), - MAX_URL_LENGTH - strlen(cfwdall_url), - ":%d", port_number); - } - } else { - /* case (3): both domain and port present - * Both domain and port exists, but strip the port if the - * domain is FQDN - */ - memcpy(proxy_ipaddr_str, domain + 1, (port - domain - 1)); - *(proxy_ipaddr_str + (port - domain - 1)) = '\0'; - if (str2ip((const char *) proxy_ipaddr_str, &proxy_ipaddr) != 0) { - *port = '\0'; - } - } - return ((char *)cfwdall_url); - } else { - return ((char *)NULL); - } -} - -/* - * lsm_get_callid_from_ui_id() - * - * Description: - * The function gets the UI id from LSM's LCB for a given GSM call ID. - * - * Parameters: - * ui_id - UI ID. - * - * Returns: callid_t - */ -callid_t -lsm_get_callid_from_ui_id (callid_t uid) -{ - lsm_lcb_t *lcb; - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->ui_id == uid) { - return lcb->call_id; - } - } - return (CC_NO_CALL_ID); -} - -/* - * lsm_get_ui_id - * - * Description: - * The function gets the UI id from LSM's LCB for a given GSM call ID. - * - * Parameters: - * call_id - GSM call ID - * ui_id - UI ID. - * - * Returns: None - */ -callid_t -lsm_get_ui_id (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - return (lcb->ui_id); - } - return (CC_NO_CALL_ID); -} - -/* - * lsm_get_ms_ui_id - * - * Description: - * The function gets the UI id from LSM's LCB for a given GSM call ID. During - * certain features like barge ui_id is set to CC_NO_CALL_ID. - * - * Parameters: - * call_id - GSM call ID - * ui_id - UI ID. - * - * Returns: None - */ -cc_call_handle_t -lsm_get_ms_ui_call_handle (line_t line, callid_t call_id, callid_t ui_id) -{ - callid_t lsm_ui_id; - - if (ui_id != CC_NO_CALL_ID) { - return CREATE_CALL_HANDLE(line, ui_id); - } - - /* If ui_id present use that */ - lsm_ui_id = lsm_get_ui_id(call_id); - - if (lsm_ui_id != CC_NO_CALL_ID) { - return CREATE_CALL_HANDLE(line, lsm_ui_id); - } - - return CREATE_CALL_HANDLE(line, call_id); -} -/* - * lsm_set_ui_id - * - * Description: - * The function sets the UI id to LSM's LCB for a given GSM call ID. - * - * Parameters: - * call_id - GSM call ID - * ui_id - UI ID. - * - * Returns: None - */ -void -lsm_set_ui_id (callid_t call_id, callid_t ui_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - lcb->ui_id = ui_id; - } -} - -char * -lsm_get_gdialed_digits (void) -{ - return (dp_get_gdialed_digits()); -} - -/* - * lsm_update_video_avail - * - * Description: - * The function updates session about the video availability - * - * Parameters: - * line - line - * call_id - GSM call ID - * dir - video avail dir - * - * Returns: None - */ -void lsm_update_video_avail (line_t line, callid_t call_id, int dir) -{ - static const char fname[] = "lsm_update_video_avail"; - fsmdef_dcb_t *dcb; - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - dir &= ~CC_ATTRIB_CAST; - - - ui_update_video_avail (line, lcb->ui_id, dir); - - lsm_update_dscp_value(dcb); - } -} - -/* - * lsm_update_video_offered - * - * Description: - * The function updates session about the video availability - * - * Parameters: - * line - line - * call_id - GSM call ID - * dir - video avail dir - * - * Returns: None - */ -void lsm_update_video_offered (line_t line, callid_t call_id, int dir) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - ui_update_video_offered (line, lcb->ui_id, dir); - } -} - -/* - * lsm_set_video_mute - * - * Description: - * The function sets the video mute state for the call - * - * Parameters: - * line - line - * call_id - This is the UI_ID coming from UI - * mute - mute state - * - * Returns: None - */ -void lsm_set_video_mute (callid_t call_id, int mute) -{ - lsm_lcb_t *lcb; - callid_t cid = lsm_get_callid_from_ui_id(call_id); // get GSM_ID from UI_ID - - lcb = lsm_get_lcb_by_call_id(cid); - if (lcb != NULL) { - lcb->vid_mute = mute; - } -} - -/* - * lsm_get_video_mute - * - * Description: - * The function gets the video mute state for the call - * - * Parameters: - * line - line - * call_id - GSM call ID - * - * Returns: t_video_mute - */ -int lsm_get_video_mute (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - return lcb->vid_mute; - } - return (-1); -} - - -/* - * lsm_set_video_window - * - * Description: - * The function sets the video window state for the call - * - * Parameters: - * call_id - This is the UI_ID coming from UI - * flags - video window flags - * x - video window x coordinate - * y - video window y coordinate - * h - video window height - * w - video window width - * - * Returns: None - */ -void lsm_set_video_window (callid_t call_id, int flags, int x, int y, int h, int w) -{ - lsm_lcb_t *lcb; - callid_t cid = lsm_get_callid_from_ui_id(call_id); // get GSM_ID from UI_ID - - lcb = lsm_get_lcb_by_call_id(cid); - if (lcb != NULL) { - lcb->vid_flags = flags; - lcb->vid_x = x; - lcb->vid_y = y; - lcb->vid_h = h; - lcb->vid_w = w; - } -} - -/* - * lsm_get_video_window - * - * Description: - * The function gets the video window for the call - * - * Parameters: - * call_id - GSM call ID - * *flags - video window flag - * *x - video window x coordinate - * *y - video window y coordinate - * *h - video window height - * *w - video window width - * - * Returns: void - */ -void lsm_get_video_window (callid_t call_id, int *flags, int *x, int *y, int *h, int *w) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - *flags = lcb->vid_flags; - *x = lcb->vid_x; - *y = lcb->vid_y; - *h = lcb->vid_h; - *w = lcb->vid_w; - } -} - -/* - * lsm_is_kpml_subscribed - * - * Description: - * check if kpml is subscribed for this call - * - * Parameters: - * call_id - GSM call ID - * - * Returns: true/false - */ -boolean lsm_is_kpml_subscribed (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return FALSE; - } - return kpml_is_subscribed(call_id, lcb->line); -} - -/** - * A helper method to start the tone. - */ -static void lsm_util_start_tone(vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction) { - - int sdpmode = 0; - static const char fname[] = "lsm_util_start_tone"; - line_t line = GET_LINE_ID(call_handle); - callid_t call_id = GET_CALL_ID(call_handle); - DEF_DEBUG(DEB_F_PREFIX"Enter, line=%d, call_id=%d.", - DEB_F_PREFIX_ARGS(MED_API, fname), line, call_id); - - sdpmode = 0; - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - vcmToneStart(tone, alert_info, call_handle, group_id, stream_id, direction); - } - /* - * Set delay value for multi-part tones and repeated tones. - * Currently the only multi-part tones are stutter and message - * waiting tones. The only repeated tones are call waiting and - * tone on hold tones. If the DSP ever supports stutter and - * message waiting tones, these tones can be removed from this - * switch statement. - */ - switch (tone) { - case VCM_MSG_WAITING_TONE: - lsm_start_multipart_tone_timer(tone, MSG_WAITING_DELAY, call_id); - break; - - case VCM_HOLD_TONE: - lsm_start_continuous_tone_timer(tone, TOH_DELAY, call_id); - break; - - default: - break; - } - - /* - * Update dcb->active_tone if start request - * is for an infinite duration tone. - */ - lsm_update_active_tone(tone, call_id); -} - -/* - * Plays a short tone. uses the open audio path. - * If no audio path is open, plays on speaker. - * - * @param[in] tone - tone type - * @param[in] alert_info - alertinfo header - * @param[in] call_id - call identifier - * @param[in] direction - network, speaker, both - * - * @return none - */ -void -lsm_util_tone_start_with_speaker_as_backup (vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction) { - static const char *fname = "lsm_util_tone_start_with_speaker_as_backup"; - line_t line = GET_LINE_ID(call_handle); - callid_t call_id = GET_CALL_ID(call_handle); - DEF_DEBUG(DEB_L_C_F_PREFIX"tone=%-2d: direction=%-2d", - DEB_L_C_F_PREFIX_ARGS(MED_API, line, call_id, fname), - tone, direction); - - //vcmToneStart - vcmToneStart(tone, alert_info, call_handle, group_id, stream_id, direction); - - /* - * Set delay value for multi-part tones and repeated tones. - * Currently the only multi-part tones are stutter and message - * waiting tones. The only repeated tones are call waiting and - * tone on hold tones. If the DSP ever supports stutter and - * message waiting tones, these tones can be removed from this - * switch statement. - */ - switch (tone) { - case VCM_MSG_WAITING_TONE: - lsm_start_multipart_tone_timer(tone, MSG_WAITING_DELAY, call_id); - break; - - case VCM_HOLD_TONE: - lsm_start_continuous_tone_timer(tone, TOH_DELAY, call_id); - break; - - default: - break; - } - - /* - * Update dcb->active_tone if start request - * is for an infinite duration tone. - */ - lsm_update_active_tone(tone, call_id); - -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c b/media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c deleted file mode 100644 index 7fa28b97b30..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c +++ /dev/null @@ -1,158 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "ccapi.h" -#include "phone_debug.h" -#include "cc_debug.h" -#include "CCProvider.h" -#include "ccapi_snapshot.h" - -/** - * global media cap table for interaction between what platform - * can do and the GSM-SDP module - * AUDIO_1 is used for audio cannot be turned off - * VIDEO_1 is used for video - */ -cc_media_cap_table_t g_media_table = { - 1, - { - {CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_RECVONLY}, - {CC_VIDEO_1,SDP_MEDIA_VIDEO,TRUE,TRUE,SDP_DIRECTION_RECVONLY}, - {CC_DATACHANNEL_1,SDP_MEDIA_APPLICATION,FALSE,TRUE,SDP_DIRECTION_SENDRECV}, - } -}; - -static boolean g_nativeVidSupported = FALSE; -static boolean g_vidCapEnabled = FALSE; -static boolean g_natve_txCap_enabled = FALSE; - -/** - * Simple method to trigger escalation and deescalation - * based on media capability changes - */ -void escalateDeescalate() { - g_media_table.id++; - if ( ccapp_get_state() != CC_INSERVICE ) { - VCM_DEBUG(MED_F_PREFIX"Ignoring video cap update", "escalateDeescalate"); - return; - } - - //post the event - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, CC_NO_CALL_ID, - CC_NO_LINE, CC_FEATURE_UPD_MEDIA_CAP, NULL); -} - -cc_boolean cc_media_isTxCapEnabled() { - return g_natve_txCap_enabled; -} - -cc_boolean cc_media_isVideoCapEnabled() { - if ( g_nativeVidSupported ) { - return g_vidCapEnabled; - } - return FALSE; -} - -/** - * API to update the local video cap in the table - * called when native video support or vidCap cfg changes - * - * This method looks at video cap in cfg & native vid support on platform - */ -static void updateVidCapTbl(){ - - if ( g_vidCapEnabled ) { - if ( g_media_table.cap[CC_VIDEO_1].enabled == FALSE ) { - // cfg is enabled but cap tbl is not - if ( g_nativeVidSupported ) { - // we can do native now enable cap - g_media_table.cap[CC_VIDEO_1].enabled = TRUE; - g_media_table.cap[CC_VIDEO_1].support_direction = - g_natve_txCap_enabled?SDP_DIRECTION_SENDRECV:SDP_DIRECTION_RECVONLY; - if ( g_natve_txCap_enabled == FALSE ) { - - } - escalateDeescalate(); - } else { - - } - } - } else { - // disable vid cap - DEF_DEBUG(MED_F_PREFIX"video capability disabled", "updateVidCapTbl"); - - if ( g_media_table.cap[CC_VIDEO_1].enabled ) { - g_media_table.cap[CC_VIDEO_1].enabled = FALSE; - escalateDeescalate(); - } - } -} - - -/** - * API to update video capability on the device - * expected to be called once in the beginning only - */ -void cc_media_update_native_video_support(boolean val) { - DEF_DEBUG(MED_F_PREFIX"Setting native video support val=%d", "cc_media_update_native_video_support", val); - g_nativeVidSupported = val; - updateVidCapTbl(); -} - -/** - * - * API to update video capability on the device based on config - */ -void cc_media_update_video_cap(boolean val) { - DEF_DEBUG(MED_F_PREFIX"Setting video cap val=%d", "cc_media_update_video_cap", val); - g_vidCapEnabled = val; - updateVidCapTbl(); - if ( g_nativeVidSupported ) { - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_VIDEO_CAP_ADMIN_CONFIG_CHANGED, CC_DEVICE_ID); - } -} - -/** - * - * API to update video tx capability based on camera plugin events - */ - -void cc_media_update_native_video_txcap(boolean enable) { - - VCM_DEBUG(MED_F_PREFIX"Setting txcap val=%d", "cc_media_update_video_txcap", enable); - - if ( g_natve_txCap_enabled == enable ) { - // nothing to do - return; - } - - g_natve_txCap_enabled = enable; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CAMERA_ADMIN_CONFIG_CHANGED, CC_DEVICE_ID); - - if ( g_nativeVidSupported && g_vidCapEnabled ) { - // act on camera events only iof native video is enabled - if ( g_natve_txCap_enabled ) { - - } else if (g_media_table.cap[CC_VIDEO_1].enabled) { - - } - - g_media_table.cap[CC_VIDEO_1].support_direction = - g_natve_txCap_enabled?SDP_DIRECTION_SENDRECV:SDP_DIRECTION_RECVONLY; - - escalateDeescalate(); - } -} - -static cc_boolean vidAutoTxPref=FALSE; -void cc_media_setVideoAutoTxPref(cc_boolean txPref){ - vidAutoTxPref = txPref; -} - -cc_boolean cc_media_getVideoAutoTxPref(){ - return vidAutoTxPref; -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/sm.c b/media/webrtc/signaling/src/sipcc/core/gsm/sm.c deleted file mode 100755 index 7531ff677e8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/sm.c +++ /dev/null @@ -1,78 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdio.h" -#include "sm.h" -#include "gsm.h" -#include "fsm.h" -#include "text_strings.h" -#include "ccapi.h" - -sm_rcs_t -sm_process_event (sm_table_t *tbl, sm_event_t *event) -{ - static const char fname[] = "sm_process_event"; - int state_id = event->state; - int event_id = event->event; - sm_rcs_t rc = SM_RC_ERROR; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *feat_msg = NULL; - line_t line_id; - fsm_types_t fsm_type; - callid_t call_id; - sm_function_t hdlr; /* cached handler in order to compute its addr once */ - - /* - * validate the state and event - * and that there is a valid function for this state-event pair. - */ - if ((state_id > tbl->min_state) && - (state_id < tbl->max_state) && - (event_id > tbl->min_event) && - (event_id < tbl->max_event)) { - rc = SM_RC_DEF_CONT; - /* - * Save some paramters for debuging, the event handler may - * free the fcb once returned. - */ - fsm_type = fcb->fsm_type; - call_id = fcb->call_id; - if ((hdlr = tbl->table[tbl->max_event * state_id + event_id]) != NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"%s %-4d: %px: sm entry: (%s:%s)", - DEB_F_PREFIX_ARGS(FSM, fname), fsm_type_name(fsm_type), call_id, - tbl->table[tbl->max_event * state_id + event_id], - fsm_state_name(fsm_type, state_id), - cc_msg_name((cc_msgs_t)(event_id))); - - rc = hdlr(event); - } - - if (rc != SM_RC_DEF_CONT) { - /* For event_id == CC_MSG_FEATURE then display the - * feature associated with it. - */ - if (event_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) event->msg; - } - line_id = ((cc_feature_t *) event->msg)->line; - - DEF_DEBUG(DEB_L_C_F_PREFIX"%-5s :(%s:%s%s)", - DEB_L_C_F_PREFIX_ARGS(GSM, line_id, call_id, fname), - fsm_type_name(fsm_type), - fsm_state_name(fsm_type, state_id), - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - } - } - /* - * Invalid state-event pair. - */ - else { - GSM_ERR_MSG(GSM_F_PREFIX"illegal state-event pair: (%d <-- %d)", - fname, state_id, event_id); - rc = SM_RC_ERROR; - } - - return rc; -} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/subapi.c b/media/webrtc/signaling/src/sipcc/core/gsm/subapi.c deleted file mode 100755 index e6111c91bc0..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/gsm/subapi.c +++ /dev/null @@ -1,280 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "cpr_stdlib.h" -#include "ccapi.h" -#include "ccsip_task.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" -#include "phone.h" -#include "text_strings.h" -#include "string_lib.h" -#include "gsm.h" -#include "vcm.h" -#include "subapi.h" -#include "misc_apps_task.h" - - -static void -sub_print_msg (char *pData, int len) -{ - int row = 0; - int col; -#define BYTES_PER_LINE 24 - char buffer[3 * BYTES_PER_LINE + 1]; - int msg_id = *((int *)pData); - - CSFLogDebug("gsm", "CCAPI: cc_msg=%s, len=%d", - cc_msg_name((cc_msgs_t)msg_id), len); - - while (len) { - buffer[0] = '\0'; - for (col = 0; (col < BYTES_PER_LINE) && len; col++) { - snprintf(buffer + (3 * col), 4, "%02X ", *pData); - pData++; - len--; - } - CSFLogObnoxious("gsm", "%04X %s", row * BYTES_PER_LINE, buffer); - row++; - } -} - -cc_rcs_t -sub_send_msg (cprBuffer_t buf, uint32_t cmd, uint16_t len, cc_srcs_t dst_id) -{ - cpr_status_e rc; - - /* This buffer is assumed to be at least of size int */ - MOZ_ASSERT(len >= sizeof(int)); - if (len < sizeof(int)) { - return CC_RC_ERROR; - } - - CC_DEBUG_MSG sub_print_msg((char *)buf, len); - - switch (dst_id) { - case CC_SRC_GSM: - rc = gsm_send_msg(cmd, buf, len); - if (rc == CPR_FAILURE) { - cpr_free(buf); - } - break; - case CC_SRC_SIP: - rc = SIPTaskSendMsg(cmd, buf, len, NULL); - if (rc == CPR_FAILURE) { - cpr_free(buf); - } - break; - case CC_SRC_MISC_APP: - rc = MiscAppTaskSendMsg(cmd, buf, len); - if (rc == CPR_FAILURE) { - cpr_free(buf); - } - break; - default: - rc = CPR_FAILURE; - break; - } - - return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR; -} - -cc_rcs_t -sub_int_subnot_register (cc_srcs_t src_id, cc_srcs_t dst_id, - cc_subscriptions_t evt_pkg, void *callback_fun, - cc_srcs_t dest_task, int msg_id, void *term_callback, - int term_msg_id, long min_duration, long max_duration) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.subs_reg.eventPackage = evt_pkg; - pmsg->msg.subs_reg.max_duration = max_duration; - pmsg->msg.subs_reg.min_duration = min_duration; - pmsg->msg.subs_reg.subsIndCallback = (ccsipSubsIndCallbackFn_t) - callback_fun; - pmsg->msg.subs_reg.subsIndCallbackMsgID = msg_id; - pmsg->msg.subs_reg.subsIndCallbackTask = dest_task; - pmsg->msg.subs_reg.subsTermCallback = (ccsipSubsTerminateCallbackFn_t) - term_callback; - pmsg->msg.subs_reg.subsTermCallbackMsgID = term_msg_id; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIBE_REGISTER, - sizeof(*pmsg), dst_id); -} - -/* - * Function: sub_int_subscribe() - * - * Parameters: msg_p - pointer to sipspi_msg_t (input parameter) - * - * Description: posts SIPSPI_EV_CC_SUBSCRIBE to SIP task message queue. - * - * Returns: CC_RC_ERROR - failed to post msg. - * CC_RC_SUCCESS - successful posted msg. - */ -cc_rcs_t -sub_int_subscribe (sipspi_msg_t *msg_p) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - memcpy(pmsg, msg_p, sizeof(sipspi_msg_t)); - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIBE, - sizeof(*pmsg), CC_SRC_SIP); -} - - -cc_rcs_t -sub_int_subscribe_ack (cc_srcs_t src_id, cc_srcs_t dst_id, sub_id_t sub_id, - uint16_t response_code, int duration) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.subscribe_resp.response_code = response_code; - pmsg->msg.subscribe_resp.sub_id = sub_id; - pmsg->msg.subscribe_resp.duration = duration; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIBE_RESPONSE, - sizeof(*pmsg), dst_id); -} - - -cc_rcs_t -sub_int_notify (cc_srcs_t src_id, cc_srcs_t dst_id, sub_id_t sub_id, - ccsipNotifyResultCallbackFn_t notifyResultCallback, - int subsNotResCallbackMsgID, ccsip_event_data_t * eventData, - subscriptionState subState) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.notify.eventData = eventData; - pmsg->msg.notify.notifyResultCallback = notifyResultCallback; - pmsg->msg.notify.sub_id = sub_id; - pmsg->msg.notify.subsNotResCallbackMsgID = subsNotResCallbackMsgID; - pmsg->msg.notify.subState = subState; - - return sub_send_msg((cprBuffer_t) pmsg, SIPSPI_EV_CC_NOTIFY, - sizeof(*pmsg), dst_id); -} - -/* - * Function: sub_int_notify_ack() - * - * Parameters: sub_id - subcription id for sip stack to track the subscription. - * response_code - response code to be sent in response to NOTIFY. - * cseq : CSeq for which response is being sent. - * - * Description: posts SIPSPI_EV_CC_NOTIFY_RESPONSE to SIP task message queue. - * - * Returns: CC_RC_ERROR - failed to post msg. - * CC_RC_SUCCESS - successful posted msg. - */ -cc_rcs_t -sub_int_notify_ack (sub_id_t sub_id, uint16_t response_code, uint32_t cseq) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.notify_resp.sub_id = sub_id; - pmsg->msg.notify_resp.response_code = response_code; - pmsg->msg.notify_resp.cseq = cseq; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_NOTIFY_RESPONSE, - sizeof(*pmsg), CC_SRC_SIP); -} - - -/* - * Function: sub_int_subscribe_term() - * - * Parameters: sub_id - subcription id for sip stack to track the subscription. - * immediate - boolean flag to indicate if the termination be immediate. - * request_id - request id significant for out going subscriptions - * event_package - event package type - * - * Description: posts SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED to SIP task message queue. - * - * Returns: CC_RC_ERROR - failed to post msg. - * CC_RC_SUCCESS - successful posted msg. - */ -cc_rcs_t -sub_int_subscribe_term (sub_id_t sub_id, boolean immediate, int request_id, - cc_subscriptions_t event_package) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.subs_term.immediate = immediate; - pmsg->msg.subs_term.sub_id = sub_id; - pmsg->msg.subs_term.request_id = request_id; - pmsg->msg.subs_term.eventPackage = event_package; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED, - sizeof(*pmsg), CC_SRC_SIP); -} - -cc_rcs_t -sip_send_message (ccsip_sub_not_data_t * msg_data, cc_srcs_t dest_id, int msg_id) -{ - ccsip_sub_not_data_t *pmsg; - - pmsg = (ccsip_sub_not_data_t *) cc_get_msg_buf(sizeof(*pmsg)); - - if (!pmsg) { - return CC_RC_ERROR; - } - - memcpy(pmsg, msg_data, sizeof(*pmsg)); - - return sub_send_msg((cprBuffer_t)pmsg, msg_id, sizeof(*pmsg), dest_id); -} - - -cc_rcs_t -app_send_message (void *msg_data, int msg_len, cc_srcs_t dest_id, int msg_id) -{ - void *pmsg; - - pmsg = (void *) cc_get_msg_buf(msg_len); - - if (!pmsg) { - return CC_RC_ERROR; - } - - memcpy(pmsg, msg_data, msg_len); - - return sub_send_msg((cprBuffer_t)pmsg, msg_id, (uint16_t)msg_len, dest_id); -} diff --git a/media/webrtc/signaling/src/sipcc/core/includes/ccSession.h b/media/webrtc/signaling/src/sipcc/core/includes/ccSession.h deleted file mode 100755 index 398f4976a32..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/ccSession.h +++ /dev/null @@ -1,207 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSESSION_H_ -#define _CCSESSION_H_ - -#include "session.h" -#include "sessuri.h" - -#define SID_TYPE_SHIFT 28 -#define SID_LINE_SHIFT 16 - -#define GET_SESS_TYPE(x) ( (x & 0xF0000000) >> SID_TYPE_SHIFT ) -#define GET_LINEID(x) (line_t)( (x & 0xFFF0000) >> SID_LINE_SHIFT ) -#define GET_CALLID(x) (callid_t)(x & 0xFFFF) - - - - -/** - * ccSessionProviderCmd - * CallControl Provider Management Interface - * Called by Application to issue cmds to sipStack - * - * @param data - command and data - * data->cmd - see Session Provider Commands in session.h - * data->cmdData.ccData.reason - reason for SHUTDOWN/UNREGISTER_ALL_LINES CMD - CC_CAUSE_NORMAL/CC_CAUSE_NONE - * data->cmdData.ccData.reason_info - Descriptive stringa "notused" - * - * @return none - * - */ -void ccSessionProviderCmd(sessionProvider_cmd_t *data); - - -/** - * ccSessionProviderState - * Method to report provider state updates to Application - * - * @param state - indicates the Session Provider state CCApp_states_t - * @param data - ccProvider_state_t indicating - * data->stateData.ccData.mode - REGMODE CCM - * data->stateData.ccData.cause - FAILOVER/FALLBACK - * - * @return none - * - */ -void ccSessionProviderState(unsigned int state, ccProvider_state_t *data); - - -/** - * ccSessionCmd - * Method to Handle session lifecycle command such as realize, start etc. - * - * @param sCmd - session liefcycle command - * sCmd->cmd - REQUEST CMD - * sCmd->sessID - session ID - * - * @return none - * - */ - -void ccSessionCmd (sessionCmd_t *sCmd); - - -/** - * ccCreateSession - * - * Called by Application to create a new session - * - * @param param - uri_t - * param->param.call_session_param.line_id - line on which to create the session - * @return ccSession_id_t - id of the session created - */ - -session_id_t ccCreateSession(uri_t *param); - -/** - * ccCloseSession - * - * Called by Application to close a session - * - * @param sess_id - ID of the session to be closed - * - * @return 0 success -1 failure - * - */ - -int ccCloseSession(session_id_t sess_id); - -/* Need to document IDs and data for the following 4 methods */ - -/** - * ccInvokeFeature - * - * Called by Application to invoke feature on session - * - * @param featData - featID and Additional info if needed for the feature - * - * @return none - * - */ - -void ccInvokeFeature(session_feature_t *featData); - -/** - * ccInvokeProviderFeature - * - * Called by Application to invoke device specific features - * - * @param featData - Additional info if needed for the feature - * - * @return none - * - */ - -void ccInvokeProviderFeature(session_feature_t *featData); - - -/** - * ccSessionUpdate - * - * Called by sipstack to update session state and data - * - * @param eventID - ID of the event updating the session data - * @param session_data - event specific data - * - * @return none - * - */ - -void ccSessionUpdate(session_update_t *session); - - - -/** - * ccFeatureUpdate - * - * Called by sipstack to update feature state and data - * - * @param featureID - ID of the feature updated - * @param session_data - feature specific data - * - * @return none - * - */ - -void ccFeatureUpdate(feature_update_t *session); - -/***** Internal APIs below this line ***************/ - -/** - * ccCreateSession - * - * Called to create a CC session - * - * @param param - ccSession_create_param_t - * Contains the type of session and specific data - * - * @return ccSession_id_t - id of the session created - */ -session_id_t createSessionId(line_t line, callid_t call); - -void platform_sync_cfg_vers (char *cfg_ver, char *dp_ver, char *softkey_ver); -/********************************************************************************/ - -/* Misc getter/setter function to get set the following */ - -#define PROPERTY_ID_MWI 1 // per line -#define PROPERTY_ID_TIME 2 // unsigned long -#define PROPERTY_ID_KPML 3 -#define PROPERTY_ID_REGREASON 4 -#define PROPERTY_ID_SPKR_HDST 5 1 - -void setIntProperty(unsigned int id, int val); -int getIntProperty(unsigned int id); -void setStrProperty(unsigned int id, char * val); -char * getStrProperty(unsigned int id); - - -/* Preserved API's from TNP Platform */ -char *ccSetDP(const char *dp_file_name); -// update_label_n_speed_dial method here -void setPropertyCacheBoolean(int cfg_id, int bool_value); -void setPropertyCacheInteger(int cfg_id, int int_value); -void setPropertyCacheString(int cfg_id, const char *string_value); -void setPropertyCacheByte(int cfg_id, char byte_value); -void setPropertyCacheByteArray(int cfg_id, char *byte_value, int length); - -/* BLF */ -void ccBLFSubscribe(int request_id, int duration, const char *watcher, - const char *presentity, int app_id, int feature_mask); -void ccBLFUnsubscribe(int request_id); -void ccBLFUnsubscribeAll(); -void blf_notification(int request_id, int status, int app_id); - - -/********************************************************************** - -MID_JPlatUi_ui_log_status_msg, Ask RCDN team if log is changing? - -**********************************************************************/ - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/includes/ccapi.h b/media/webrtc/signaling/src/sipcc/core/includes/ccapi.h deleted file mode 100755 index 4d157fbd4c2..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/ccapi.h +++ /dev/null @@ -1,1533 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCAPI_H_ -#define _CCAPI_H_ - -#include "mozilla/ArrayUtils.h" - -#if defined(__cplusplus) && __cplusplus >= 201103L -typedef struct Timecard Timecard; -#else -#include "timecard.h" -#endif - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "phone_types.h" -#include "string_lib.h" -#include "vcm.h" -#include "sdp.h" -#include "cc_constants.h" - -typedef unsigned int cc_security_e; -typedef unsigned int cc_select_state_e; -typedef unsigned int cc_call_type_e; -typedef unsigned int cc_policy_e; -typedef int cc_causes_t; -#define CC_CALL_OUTGOMING CC_CALL_TYPE_OUTGOING -#define CC_CALL_FORWARDED CC_CALL_TYPE_FORWARDED -#define CC_CALL_NONE CC_CALL_TYPE_NONE -#define CC_CALL_INCOMING CC_CALL_TYPE_INCOMING -#define CANDIDATE_SIZE 150 -#define MID_SIZE 150 - -#include "sessionConstants.h" - -typedef int cc_features_t; -typedef unsigned int softkey_events; -typedef unsigned int cc_call_priority_e; -extern cc_reg_state_t ccapp_get_state(); - -/* Session FEATURES */ -/* please update cc_feature_names whenever this enum list is changed */ - -typedef enum { - CC_FEATURE_MIN = -1L, - CC_FEATURE_NONE, - CC_FEATURE_HOLD = 1L, - CC_FEATURE_RESUME, - CC_FEATURE_OFFHOOK, - CC_FEATURE_NEW_CALL, - CC_FEATURE_REDIAL, - CC_FEATURE_ONHOOK, - CC_FEATURE_KEYPRESS, - CC_FEATURE_DIAL, - CC_FEATURE_XFER, - CC_FEATURE_CFWD_ALL, - CC_FEATURE_END_CALL, - CC_FEATURE_ANSWER, - CC_FEATURE_INFO, - CC_FEATURE_CONF, - CC_FEATURE_JOIN, - CC_FEATURE_DIRTRXFR, - CC_FEATURE_SELECT, - CC_FEATURE_SPEEDDIAL, - CC_FEATURE_SWAP, - CC_FEATURE_SPEEDDIAL_BLF, - CC_FEATURE_BLIND_XFER_WITH_DIALSTRING, - CC_FEATURE_BKSPACE, - CC_FEATURE_CANCEL, - CC_FEATURE_DIALSTR, - CC_FEATURE_UPD_SESSION_MEDIA_CAP, - /* Not used in the session API */ - CC_FEATURE_MEDIA, - CC_FEATURE_UPDATE, - CC_FEATURE_CALLINFO, - CC_FEATURE_BLIND_XFER, - CC_FEATURE_NOTIFY, - CC_FEATURE_SUBSCRIBE, - CC_FEATURE_B2BCONF, - CC_FEATURE_B2B_JOIN, - CC_FEATURE_HOLD_REVERSION, - CC_FEATURE_BLF_ALERT_TONE, - CC_FEATURE_REQ_PEND_TIMER_EXP, - CC_FEATURE_NUMBER, - CC_FEATURE_URL, - CC_FEATURE_REDIRECT, - CC_FEATURE_RINGBACK_DELAY_TIMER_EXP, - CC_FEATURE_CALL_PRESERVATION, - CC_FEATURE_UPD_MEDIA_CAP, - CC_FEATURE_CAC_RESP_PASS, - CC_FEATURE_CAC_RESP_FAIL, - CC_FEATURE_FAST_PIC_UPD, - CC_FEATURE_UNDEFINED, - CC_FEATURE_MAX -} group_cc_feature_t; - -#define skNewCall CC_FEATURE_NEW_CALL -#define skConfrn CC_FEATURE_CONF - -/* please update the following cc_feature_names whenever this feature list is changed */ - -#ifdef __CC_FEATURE_STRINGS__ -static const char *const cc_feature_names[] = { - "NONE", - "HOLD", - "RESUME", - "OFFHOOK", - "NEW_CALL", - "REDIAL", - "ONHOOK", - "KEYPRESS", - "DIAL", - "XFER", - "CFWD_ALL", //10 - "END_CALL", - "ANSWER", - "INFO", - "CONF", - "JOIN", - "DIR_XFER", - "SELECT", - "SPEEDDIAL", - "SWAP", - "SDBLF", //45 - "BLIND_XFER_WITH_DIALSTRING", - "BSPACE", - "CANCEL", - "DIALSTR", - "UPD_SESSION_MEDIA_CAP", - "NEW_MEDIA", - "UPDATE", - "CALLINFO", - "BLIND_XFER", - "NOTIFY", - "SUBSCRIBE", - "B2BCONF", - "B2BJOIN", - "HOLD_REVERSION", //jni_max + 10 - "BLF_ALERT_TONE", - "REQPENDTMREXP", - "NUMBER", - "URL", - "REDIRECT", //jni_max + 20 - "RINGBACKDELAYTMREXP", - "CALL_PRESERVATION", - "UPD_MEDIA_CAP", - "CAC PASSED", - "CAC FAILED", - "FAST_PIC_UPD", - "UNDEFINED", - "MAX" -}; - -/* This checks at compile-time that the cc_feature_names list - * is the same size as the cc_group_feature_t enum - */ -MOZ_STATIC_ASSERT(MOZ_ARRAY_LENGTH(cc_feature_names) == CC_FEATURE_MAX + 1, - "cc_feature_names size == cc_group_feature_t size?"); - -#endif - -/* - * Constants - */ -#define CC_MAX_DIALSTRING_LEN (512) -#define CC_MAX_MEDIA_TYPES (15) -#define CC_MAX_MEDIA_CAP (4) -#define CC_NO_CALL_ID (0) -#define CC_NO_LINE (0) -#define CC_NO_DATA (NULL) -#define CC_NO_MEDIA_REF_ID (0) -#define CC_MAX_REDIRECTS (1) -#define CC_MAX_BODY_PARTS 3 -#define CC_NO_GROUP_ID (0) -#define CC_NO_CALL_INST_ID (0) -#define CC_SHORT_DIALSTRING_LEN (64) -#define CC_CISCO_PLAR_STRING "x-cisco-serviceuri-offhook" -#define CISCO_BLFPICKUP_STRING "x-cisco-serviceuri-blfpickup" -#define JOIN_ACROSS_LINES_DISABLED 0 -#define CC_MAX_TRACKS 8 // query this figure -#define CC_MAX_STREAMS 2 // TODO: expand signaling to handle more than one of each a/v. - - -/* - * - * Support type definintions - * - */ -typedef enum cc_rcs_t_ { - CC_RC_MIN = -1, - CC_RC_SUCCESS, - CC_RC_ERROR, - CC_RC_MAX -} cc_rcs_t; - -typedef enum cc_msgs_t_ { - CC_MSG_MIN = -1, - CC_MSG_SETUP, - CC_MSG_SETUP_ACK, - CC_MSG_PROCEEDING, - CC_MSG_ALERTING, - CC_MSG_CONNECTED, - CC_MSG_CONNECTED_ACK, - CC_MSG_RELEASE, - CC_MSG_RELEASE_COMPLETE, - CC_MSG_FEATURE, - CC_MSG_FEATURE_ACK, - CC_MSG_OFFHOOK, - CC_MSG_ONHOOK, - CC_MSG_LINE, - CC_MSG_DIGIT_BEGIN, - CC_MSG_DIGIT_END, - CC_MSG_DIALSTRING, - CC_MSG_MWI, - CC_MSG_AUDIT, - CC_MSG_AUDIT_ACK, - CC_MSG_OPTIONS, - CC_MSG_OPTIONS_ACK, - CC_MSG_SUBSCRIBE, - CC_MSG_NOTIFY, - CC_MSG_FAILOVER_FALLBACK, - CC_MSG_INFO, - /* update the following strings table if this is changed */ - CC_MSG_MAX -} cc_msgs_t; - -#ifdef __CC_MESSAGES_STRINGS__ -static const char *const cc_msg_names[] = { - "SETUP", - "SETUP_ACK", - "PROCEEDING", - "ALERTING", - "CONNECTED", - "CONNECTED_ACK", - "RELEASE", - "RELEASE_COMPLETE", - "FEAT:", - "FEATURE_ACK", - "OFFHOOK", - "ONHOOK", - "LINE", - "DIGIT_BEGIN", - "DIGIT_END", - "DIALSTRING", - "MWI", - "AUDIT", - "AUDIT_ACK", - "OPTIONS", - "OPTIONS_ACK", - "SUBSCRIBE", - "NOTIFY", - "FAILOVER_FALLBACK", - "INFO", - "INVALID", -}; - -/* This checks at compile-time that the cc_msg_names list - * is the same size as the cc_msgs_t enum - */ -MOZ_STATIC_ASSERT(MOZ_ARRAY_LENGTH(cc_msg_names) == CC_MSG_MAX + 1, - "cc_msg_names size == cc_msgs_t size?"); - -#endif //__CC_MESSAGES_STRINGS__ - -typedef enum cc_srcs_t_ { - CC_SRC_MIN = -1, - CC_SRC_GSM, - CC_SRC_UI, - CC_SRC_SIP, - CC_SRC_MISC_APP, - CC_SRC_RCC, - CC_SRC_CCAPP, - CC_SRC_MAX -} cc_srcs_t; - - -typedef enum cc_transfer_mode_e_ { - CC_XFR_MODE_MIN = -1, - CC_XFR_MODE_NONE, - CC_XFR_MODE_TRANSFEROR, - CC_XFR_MODE_TRANSFEREE, - CC_XFR_MODE_TARGET, - CC_XFR_MODE_MAX -} cc_transfer_mode_e; - -typedef enum cc_regmgr_rsp_type_e_ { - CC_FAILOVER_RSP=0, - CC_RSP_START =1, - CC_RSP_COMPLETE=2 -} cc_regmgr_rsp_type_e; - -typedef enum cc_regmgr_rsp_e_ { - CC_REG_FAILOVER_RSP, - CC_REG_FALLBACK_RSP -} cc_regmgr_rsp_e; - -/* - * Identifies what was in the Alert-Info header - */ -typedef enum { - ALERTING_NONE, /* No alert-info header present */ - ALERTING_OLD, /* Unrecognized pattern or an error, mimic old behavior */ - ALERTING_TONE, /* Play tone */ - ALERTING_RING /* Play ringing pattern */ -} cc_alerting_type; - -typedef enum { - CC_MONITOR_NONE = 0, - CC_MONITOR_SILENT = 1, - CC_MONITOR_COACHING = 2 -} monitor_mode_t; - -typedef enum { - CFWDALL_NONE = -1, - CFWDALL_CLEAR, - CFWDALL_SET -} cfwdall_mode_t; - -/* Do not change enum values unless remote-cc xml has been changed */ - -typedef enum { - CC_RING_DEFAULT = 0, - CC_RING_ENABLE = 1, - CC_RING_DISABLE = 2 -} cc_rcc_ring_mode_e; - -/* Do not change enum values unless remote-cc xml has been changed */ - -typedef enum { - CC_SK_EVT_TYPE_DEF = 0, - CC_SK_EVT_TYPE_EXPLI = CC_SK_EVT_TYPE_DEF, - CC_SK_EVT_TYPE_IMPLI = 1 -} cc_rcc_skey_evt_type_e; - -/* media name with media capability table */ -typedef enum { - CC_INVALID_INDEX = -1, - CC_AUDIO_1, - CC_VIDEO_1, - CC_DATACHANNEL_1, -} cc_media_cap_name; - -typedef struct cc_sdp_addr_t_ { - cpr_ip_addr_t addr; - unsigned int port; -} cc_sdp_addr_t; - -typedef struct cc_sdp_data_t_ { - cc_sdp_addr_t addr; - int media_types[CC_MAX_MEDIA_TYPES]; - int32_t avt_payload_type; -} cc_sdp_data_t; - -typedef struct cc_sdp_t_ { - sdp_t *src_sdp; /* pointer to source SDP */ - sdp_t *dest_sdp; /* pointer to received SDP */ -} cc_sdp_t; - -typedef enum -{ - cc_disposition_unknown = 0, - cc_disposition_render, - cc_disposition_session, - cc_dispostion_icon, - cc_disposition_alert, - cc_disposition_precondition -} cc_disposition_type_t; - -typedef struct -{ - cc_disposition_type_t disposition; - boolean required_handling; -} cc_content_disposition_t; - -typedef enum -{ - cc_content_type_unknown = 0, - cc_content_type_SDP, - cc_content_type_sipfrag, - cc_content_type_CMXML -} cc_content_type_t; - -typedef struct cc_msgbody_t_ { - cc_content_type_t content_type; - cc_content_disposition_t content_disposition; - uint32_t body_length; - char *body; - char *content_id; -} cc_msgbody_t; - -typedef struct cc_msgbody_info_t_ { - uint32_t num_parts; /* number of body parts */ - cc_content_type_t content_type; /* top level content type */ - cc_msgbody_t parts[CC_MAX_BODY_PARTS]; /* parts */ -} cc_msgbody_info_t; - -/* - * Message definitions - */ - -typedef enum cc_redirect_reasons_t { - CC_REDIRECT_REASON_MIN = -1, - CC_REDIRECT_REASON_NONE, - CC_REDIRECT_REASON_BUSY, - CC_REDIRECT_REASON_NOANSWER, - CC_REDIRECT_REASON_UNCONDITIONAL, - CC_REDIRECT_REASON_DEFLECTION, - CC_REDIRECT_REASON_UNAVAILABLE -} cc_redirect_reasons_t; - -typedef struct cc_redirect_t_ { - int count; - struct { - char number[CC_MAX_DIALSTRING_LEN]; - cc_redirect_reasons_t redirect_reason; - } redirects[CC_MAX_REDIRECTS]; -} cc_redirect_t; - -typedef enum { - CC_FEAT_NONE, - CC_FEAT_HOLD, - CC_FEAT_RESUME, - CC_FEAT_BARGE, - CC_FEAT_CBARGE, - CC_FEAT_REPLACE, - CC_FEAT_CALLINFO, - CC_FEAT_INIT_CALL, - CC_FEAT_MONITOR, - CC_FEAT_TOGGLE_TO_SILENT_MONITORING, - CC_FEAT_TOGGLE_TO_WHISPER_COACHING -} cc_call_info_e; - -typedef enum { - CC_REASON_NONE, - CC_REASON_XFER, - CC_REASON_CONF, - CC_REASON_SWAP, - CC_REASON_RCC, - CC_REASON_INTERNAL, - CC_REASON_MONITOR_UPDATE -} cc_hold_resume_reason_e; - -typedef enum { - CC_PURPOSE_NONE, - CC_PURPOSE_INFO, - CC_PURPOSE_ICON, - CC_PURPOSE_CARD -} cc_purpose_e; - -typedef enum { - CC_ORIENTATION_NONE = CC_CALL_TYPE_NONE, - CC_ORIENTATION_FROM = CC_CALL_TYPE_INCOMING, - CC_ORIENTATION_TO = CC_CALL_TYPE_OUTGOING -} cc_orientation_e; - -typedef enum { - CC_UI_STATE_NONE, - CC_UI_STATE_RINGOUT, - CC_UI_STATE_CONNECTED, - CC_UI_STATE_BUSY -} cc_ui_state_e; - -typedef enum { - CC_REASON_NULL, - CC_REASON_ACTIVECALL_LIST -} cc_onhook_reason_e; - -typedef enum { - CC_CALL_LOG_DISP_MISSED, - CC_CALL_LOG_DISP_RCVD, - CC_CALL_LOG_DISP_PLACED, - CC_CALL_LOG_DISP_UNKNWN, - CC_CALL_LOG_DISP_IGNORE -} cc_call_logdisp_e; - -/* - * The cc_caller_id_t structure contains caller IDs fields. - * Sending these fields accross components needs special care. - * There are CCAPI API that provide access or transport these fields - * by the source or by the destination. Any new caller IDs added, - * please update the APIs in ccapi.c to support the new fields. - * See cc_cp_caller(), cc_mv_caller_id() and cc_free_caller_id() functions. - */ -// mostly overlap with sessionTypes.h:cc_callinfo_t -typedef struct cc_caller_id_t_ { - string_t calling_name; - string_t calling_number; - string_t alt_calling_number; - boolean display_calling_number; - string_t called_name; - string_t called_number; - boolean display_called_number; - string_t orig_called_name; - string_t orig_called_number; - string_t last_redirect_name; - string_t last_redirect_number; - string_t orig_rpid_number; - cc_call_type_e call_type; - uint16_t call_instance_id; -} cc_caller_id_t; - -/* - * The followings are definitions of bits in the feature_flag of the - * cc_feature_data_call_info_t strucure. - * - * The CC_DELAY_UI_UPDATE flag is not related to call information but - * it indicates that the call info event signaled by SIP stack - * to GSM that UI update can be delayed due to media manipulation - * event will follow. This allows GSM to defer UI update to after the - * media manipulation event. - */ -#define CC_SECURITY 1 -#define CC_ORIENTATION (1<<1) -#define CC_UI_STATE (1<<2) -#define CC_CALLER_ID (1<<3) -#define CC_CALL_INSTANCE (1<<4) -#define CC_DELAY_UI_UPDATE (1<<5) -#define CC_POLICY (1<<6) - -typedef struct cc_feature_data_call_info_t_{ - uint16_t feature_flag; - cc_security_e security; - cc_policy_e policy; - cc_orientation_e orientation; - cc_ui_state_e ui_state; - cc_caller_id_t caller_id; - cc_call_priority_e priority; - boolean swap; //Indicate if hold/resume is because of swap - boolean protect; //indicate if the call has to be protected - boolean dusting; //indicate if it is a dusting call - uint32_t callref; - char global_call_id[CC_GCID_LEN]; -} cc_feature_data_call_info_t; - -typedef struct cc_replace_info_t_ { - callid_t remote_call_id; /* remote call ID to replace */ -} cc_replace_info_t; - -typedef struct cc_join_info_t_ { - callid_t join_call_id; -} cc_join_info_t; - -typedef struct cc_initcall_t { - char gcid[CC_GCID_LEN]; // Global call id used for CTI - monitor_mode_t monitor_mode; -} cc_initcall_t; - -typedef union { - cc_initcall_t initcall; - cc_hold_resume_reason_e hold_resume_reason; - cc_feature_data_call_info_t call_info_feat_data; - cc_purpose_e purpose; // Used for Barge, CBARGE - cc_replace_info_t replace; - cc_join_info_t join; -} cc_call_info_data_t; - -typedef struct { - cc_call_info_data_t data; - cc_call_info_e type; -} cc_call_info_t; - -typedef enum cc_xfer_methods_t_ { - CC_XFER_METHOD_MIN = -1, - CC_XFER_METHOD_NONE, - CC_XFER_METHOD_BYE, - CC_XFER_METHOD_REFER, - CC_XFER_METHOD_DIRXFR, - CC_RCC_METHOD_REFER, - CC_XFER_METHOD_MAX -} cc_xfer_methods_t; - -typedef enum cc_subscriptions_t_ { - CC_SUBSCRIPTIONS_MIN = -1, - CC_SUBSCRIPTIONS_NONE, - CC_SUBSCRIPTIONS_XFER, - CC_SUBSCRIPTIONS_DIALOG = CC_SUBSCRIPTIONS_DIALOG_EXT, - CC_SUBSCRIPTIONS_CONFIG, - CC_SUBSCRIPTIONS_KPML = CC_SUBSCRIPTIONS_KPML_EXT, - CC_SUBSCRIPTIONS_PRESENCE = CC_SUBSCRIPTIONS_PRESENCE_EXT, - CC_SUBSCRIPTIONS_REMOTECC = CC_SUBSCRIPTIONS_REMOTECC_EXT, - CC_SUBSCRIPTIONS_REMOTECC_OPTIONSIND = CC_SUBSCRIPTIONS_REMOTECC_OPTIONSIND_EXT, - CC_SUBSCRIPTIONS_CONFIGAPP = CC_SUBSCRIPTIONS_CONFIGAPP_EXT, - CC_SUBSCRIPTIONS_MEDIA_INFO = CC_SUBSCRIPTIONS_MEDIA_INFO_EXT, - CC_SUBSCRIPTIONS_MAX -} cc_subscriptions_t; - -typedef struct cc_feature_data_newcall_t_ { - char dialstring[CC_MAX_DIALSTRING_LEN]; - cc_causes_t cause; - cc_redirect_t redirect; - cc_replace_info_t replace; - cc_join_info_t join; - char global_call_id[CC_GCID_LEN]; - callid_t prim_call_id; /* For internal new call event - * refer primary call's call_id - */ - cc_hold_resume_reason_e hold_resume_reason; /* Reason for new consult call */ -} cc_feature_data_newcall_t; - -typedef struct cc_feature_data_xfer_t_ { - cc_causes_t cause; - char dialstring[CC_MAX_DIALSTRING_LEN]; - char referred_by[CC_MAX_DIALSTRING_LEN]; - cc_xfer_methods_t method; - callid_t target_call_id; - char global_call_id[CC_GCID_LEN]; -} cc_feature_data_xfer_t; - -typedef enum cc_app_type_t_ { - CC_APP_MIN = -1, - CC_APP_NONE, - CC_APP_CMXML, - CC_APP_REMOTECC, - CC_APP_MAX -} cc_app_type_t; - -typedef struct cc_refer_body_t_ { - struct cc_refer_body_t_ *next; - char refer_body[200]; - int refer_body_len; - cc_app_type_t app_type; -} cc_refer_body_t; - -typedef struct cc_feature_data_ind_t__ { - cc_causes_t cause; - char to[CC_MAX_DIALSTRING_LEN]; - char referred_by[CC_MAX_DIALSTRING_LEN]; - char referred_to[CC_MAX_DIALSTRING_LEN]; - cc_refer_body_t refer_body; -} cc_feature_data_ind_t; - -typedef struct cc_feature_data_endcall_t_ { - cc_causes_t cause; - char dialstring[CC_MAX_DIALSTRING_LEN]; -} cc_feature_data_endcall_t; - -typedef struct cc_kfact_t { - char rxstats[CC_KFACTOR_STAT_LEN]; - char txstats[CC_KFACTOR_STAT_LEN]; -} cc_kfact_t; - -typedef struct cc_feature_data_hold_t_ { - cc_msgbody_info_t msg_body; - cc_call_info_t call_info; - cc_kfact_t kfactor; -} cc_feature_data_hold_t; - -typedef struct cc_feature_data_hold_reversion_t_ { - int alertInterval; -} cc_feature_data_hold_reversion_t; - -typedef struct cc_feature_data_resume_t_ { - cc_causes_t cause; - cc_msgbody_info_t msg_body; - cc_call_info_t call_info; - cc_kfact_t kfactor; -} cc_feature_data_resume_t; - -typedef struct cc_feature_data_redirect_t_ { - char redirect_number[CC_MAX_DIALSTRING_LEN]; - cc_redirect_t redirect; -} cc_feature_data_redirect_t; - -typedef struct cc_feature_data_subscribe_t_ { - cc_subscriptions_t event_package; - boolean subscribe; - char subscribe_uri[CC_MAX_DIALSTRING_LEN]; - cc_srcs_t component; - int component_id; - int *callBack; -} cc_feature_data_subscribe_t; - -typedef enum cc_dialog_lock_e_ { - CC_DIALOG_UNLOCKED, /* unlocked */ - CC_DIALOG_LOCKED /* local selected or locked */ -} cc_dialog_lock_e; - -typedef struct cc_notify_data_config_t { - boolean config_state; -} cc_notify_data_config_t; - -typedef struct cc_notify_data_kpml_t { - boolean kpml_state; -} cc_notify_data_kpml_t; - - -typedef struct cc_notify_data_rcc_t { - cc_features_t feature; - cc_select_state_e select; -} cc_notify_data_rcc_t; - - -typedef union cc_notify_data_t { - cc_notify_data_config_t config; - cc_notify_data_kpml_t kpml; - cc_notify_data_rcc_t rcc; -} cc_notify_data_t; - -typedef struct cc_feature_data_notify_t_ { - cc_subscriptions_t subscription; - cc_xfer_methods_t method; - cc_causes_t cause; - // The refer data above should have been in a cc_notify_data_refer_t - int cause_code; - callid_t blind_xferror_gsm_id; - boolean final; - cc_notify_data_t data; -} cc_feature_data_notify_t; - -typedef struct cc_feature_data_update_t_ { - cc_msgbody_info_t msg_body; -} cc_feature_data_update_t; - -typedef struct cc_feature_data_b2bcnf_t_ { - cc_causes_t cause; - callid_t call_id; - callid_t target_call_id; - char global_call_id[CC_GCID_LEN]; -} cc_feature_data_b2bcnf_t; - -typedef struct cc_feature_data_record_t_ { - boolean subref_flag; -} cc_feature_data_record_t; - -typedef struct cc_feature_data_select_t_ { - boolean select; /* TRUE when select, FALSE when unselect */ -} cc_feature_data_select_t; - -typedef struct cc_feature_data_b2b_join_t_ { - callid_t b2bjoin_callid; - callid_t b2bjoin_joincallid; -} cc_feature_data_b2b_join_t; - - -typedef struct cc_media_cap_t_ { - cc_media_cap_name name; /* media channel name designator */ - sdp_media_e type; /* media type: audio, video etc */ - boolean enabled; /* this media is enabled or disabled */ - boolean support_security; /* security is supported */ - sdp_direction_e support_direction;/* supported direction */ - cc_media_stream_id_t pc_stream; /* The media stream in the PC */ - cc_media_track_id_t pc_track; /* The track ID in the media stream */ - boolean bundle_only; /* this media is only available bundled */ -} cc_media_cap_t; - -typedef struct cc_media_cap_table_t_ { - uint32_t id; - cc_media_cap_t cap[CC_MAX_MEDIA_CAP];/* capability table. */ -} cc_media_cap_table_t; - -typedef struct cc_media_track_t_ { - unsigned int media_stream_track_id; - boolean video; -} cc_media_track_t; - -typedef struct cc_media_remote_track_table_t_ { - boolean created; - uint32_t num_tracks; - uint32_t num_tracks_notified; - uint32_t media_stream_id; - cc_media_track_t track[CC_MAX_TRACKS]; -} cc_media_remote_track_table_t; - -typedef struct cc_media_remote_stream_table_t_ { - cc_media_remote_track_table_t streams[CC_MAX_STREAMS]; -} cc_media_remote_stream_table_t; - -typedef struct cc_media_local_track_table_t_ { - uint32_t media_stream_id; - cc_media_track_t track[CC_MAX_TRACKS]; -} cc_media_local_track_table_t; - -typedef struct cc_feature_data_generic_t { - boolean subref_flag; - uint32_t eventid; -} cc_feature_data_generic_t; - -typedef struct cc_feature_data_cnf_t_ { - cc_causes_t cause; - callid_t call_id; - callid_t target_call_id; -} cc_feature_data_cnf_t; - -typedef struct cc_feature_data_cancel_t_ { - cc_rcc_skey_evt_type_e cause; - callid_t call_id; - callid_t target_call_id; -} cc_feature_data_cancel_t; - -typedef struct cc_feature_data_pc_t_ { - char pc_handle[PC_HANDLE_SIZE]; -} cc_feature_data_pc_t; - -typedef struct cc_feature_data_track_t_ { - cc_media_stream_id_t stream_id; - cc_media_track_id_t track_id; - cc_media_type_t media_type; -} cc_feature_data_track_t; - - -typedef struct cc_feature_candidate_t_ { - uint16_t level; - char candidate[CANDIDATE_SIZE]; - char mid[MID_SIZE]; -} cc_feature_candidate_t; - -typedef struct cc_feature_session_t_ { - cc_media_options_t *options; -} cc_feature_session_t; - - -typedef union cc_feature_data_t { - cc_feature_data_newcall_t newcall; - cc_feature_data_xfer_t xfer; - cc_feature_data_ind_t indication; - cc_feature_data_endcall_t endcall; - cc_feature_data_hold_t hold; - cc_feature_data_hold_reversion_t hold_reversion; - cc_feature_data_resume_t resume; - cc_feature_data_redirect_t redirect; - cc_feature_data_subscribe_t subscribe; - cc_feature_data_notify_t notify; - cc_feature_data_update_t update; - cc_feature_data_b2bcnf_t b2bconf; - cc_feature_data_call_info_t call_info; - cc_feature_data_record_t record; - cc_feature_data_select_t select; - cc_feature_data_b2b_join_t b2bjoin; - cc_feature_data_generic_t generic; - cc_feature_data_cnf_t cnf; - cc_feature_data_b2bcnf_t cancel; - cc_media_cap_t caps; - cc_feature_data_pc_t pc; - cc_feature_data_track_t track; - cc_feature_candidate_t candidate; - cc_feature_session_t session; -} cc_feature_data_t; - -typedef struct cc_setup_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_alerting_type alert_info; - vcm_ring_mode_t alerting_ring; - vcm_tones_t alerting_tone; - cc_caller_id_t caller_id; - cc_redirect_t redirect; - cc_call_info_t call_info; - boolean replaces; - string_t recv_info_list; - cc_msgbody_info_t msg_body; -} cc_setup_t; - -typedef struct cc_setup_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - cc_msgbody_info_t msg_body; -} cc_setup_ack_t; - -typedef struct cc_proceeding_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; -} cc_proceeding_t; - -typedef struct cc_alerting_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - cc_msgbody_info_t msg_body; - boolean inband; -} cc_alerting_t; - -typedef struct cc_connected_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - string_t recv_info_list; - cc_msgbody_info_t msg_body; -} cc_connected_t; - -typedef struct cc_connected_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - cc_msgbody_info_t msg_body; -} cc_connected_ack_t; - -typedef struct cc_release_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_causes_t cause; - char dialstring[CC_MAX_DIALSTRING_LEN]; - cc_kfact_t kfactor; -} cc_release_t; - -typedef struct cc_release_complete_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_causes_t cause; - cc_kfact_t kfactor; -} cc_release_complete_t; - -typedef struct cc_feature_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_features_t feature_id; - cc_feature_data_t data; - boolean data_valid; - cc_jsep_action_t action; - char *sdp; - Timecard *timecard; -} cc_feature_t; - -typedef struct cc_feature_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_features_t feature_id; - cc_feature_data_t data; - boolean data_valid; - cc_causes_t cause; -} cc_feature_ack_t; - -typedef struct cc_offhook_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - char global_call_id[CC_GCID_LEN]; - callid_t prim_call_id; /* For internal new call event - * refer primary call's call_id - */ - cc_hold_resume_reason_e hold_resume_reason; /* Reason for new consult call */ - monitor_mode_t monitor_mode; - cfwdall_mode_t cfwdall_mode; -} cc_offhook_t; - -typedef struct cc_onhook_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - boolean softkey; - callid_t prim_call_id; /* For internal new call event - * refer primary call's call_id - */ - cc_hold_resume_reason_e hold_resume_reason; /* Reason for new consult call */ - cc_onhook_reason_e active_list; /* onhook is because of active call - * press - */ -} cc_onhook_t; - -typedef struct cc_line_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; -} cc_line_t; - -typedef struct cc_digit_begin_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - int digit; -} cc_digit_begin_t; - -typedef struct cc_digit_end_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - int digit; -} cc_digit_end_t; - -typedef struct cc_dialstring_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - char dialstring[CC_MAX_DIALSTRING_LEN]; - char g_call_id[CC_GCID_LEN]; - monitor_mode_t monitor_mode; -} cc_dialstring_t; - -// mostly overlap with sessionTypes.h:cc_mwi_status_t -typedef struct cc_action_data_mwi_ { - boolean on; - int type; - int newCount; - int oldCount; - int hpNewCount; - int hpOldCount; -} cc_action_data_mwi_t; - -typedef struct cc_mwi_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_action_data_mwi_t msgSummary; -} cc_mwi_t; - -typedef struct cc_options_sdp_req_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - void * pMessage; -} cc_options_sdp_req_t; - -typedef struct cc_options_sdp_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - void * pMessage; - cc_msgbody_info_t msg_body; -} cc_options_sdp_ack_t; - -typedef struct cc_audit_sdp_req_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - boolean apply_ringout; -} cc_audit_sdp_req_t; - -typedef struct cc_audit_sdp_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_msgbody_info_t msg_body; -} cc_audit_sdp_ack_t; - -typedef struct cc_feature_tmr_t_ { - callid_t call_id; - line_t line; - cc_features_t feature_id; -} cc_feature_tmr_t; - -typedef struct cc_regmgr_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - int rsp_type; - cc_regmgr_rsp_e rsp_id; - boolean wait_flag; -} cc_regmgr_t; - -// mostly overlap with sessionTypes.h:session_send_info_t -typedef struct cc_info_t { - cc_msgs_t msg_id; - cc_srcs_t not_used; // why not share a common struct?? why cast everything to cc_setup_t?? - callid_t call_id; - line_t line; - string_t info_package; - string_t content_type; - string_t message_body; -} cc_info_t; - -typedef struct cc_msg_t_ { - union { - cc_setup_t setup; - cc_setup_ack_t setup_ack; - cc_proceeding_t proceeding; - cc_alerting_t alerting; - cc_connected_t connected; - cc_connected_ack_t connected_ack; - cc_release_t release; - cc_release_complete_t release_complete; - cc_feature_t feature; - cc_feature_ack_t feature_ack; - cc_offhook_t offhook; - cc_onhook_t onhook; - cc_line_t line; - cc_digit_begin_t digit_begin; - cc_digit_end_t digit_end; - cc_dialstring_t dialstring; - cc_mwi_t mwi; - cc_options_sdp_ack_t options_ack; - cc_audit_sdp_ack_t audit_ack; - cc_info_t info; - } msg; -} cc_msg_t; - - -callid_t cc_get_new_call_id(void); -const char *cc_msg_name(cc_msgs_t id); -const char *cc_src_name(cc_srcs_t id); -const char *cc_cause_name(cc_causes_t id); -const char *cc_feature_name(cc_features_t id); - -void cc_int_setup(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_alerting_type alert_info, vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_redirect_t *redirect, - cc_call_info_t *call_info_p, boolean replaces, - string_t recv_info_list, cc_msgbody_info_t *msg_body); - -void cc_int_setup_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body); - -void cc_int_proceeding(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id); - -void cc_int_alerting(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body, boolean inband); - -void cc_int_connected(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - string_t recv_info_list, cc_msgbody_info_t *msg_body); - -void cc_int_connected_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body); - -void cc_int_release(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_causes_t cause, const char *dialstring, - cc_kfact_t *kfactor); - -void cc_int_release_complete(cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_causes_t cause, - cc_kfact_t *kfactor); - -void cc_int_feature2(cc_msgs_t msg_id, cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_features_t feature_id, - cc_feature_data_t *data, Timecard *); - -void cc_int_feature_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, - cc_feature_data_t *data, cc_causes_t cause); - -void cc_int_offhook(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, char *global_call_id, - monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode); - -void cc_int_onhook(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, boolean softkey, cc_onhook_reason_e active_list, - const char *filename, int fileline); - -void cc_int_line(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line); - -void cc_int_digit_begin(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, int digit); - -void cc_int_digit_end(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, int digit); - -void cc_int_dialstring(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, const char *dialstring, - const char *g_call_id, monitor_mode_t monitor_mode); - -void cc_int_mwi(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, boolean on, int type, int newCount, - int oldCount, int hpNewCount, int hpOldCount); - -void cc_int_options_sdp_req(cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, void *pMessage); - -void cc_int_options_sdp_ack(cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, void *pMessage, - cc_msgbody_info_t *msg_body); - -void cc_int_audit_sdp_req(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, boolean apply_ringout); - -void cc_int_audit_sdp_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_msgbody_info_t *msg_body); - -void cc_int_info(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, string_t info_package, string_t content_type, - string_t message_body); - -void cc_int_fail_fallback(cc_srcs_t src_id, cc_srcs_t dst_id, int rsp_type, - cc_regmgr_rsp_e rsp_id, boolean waited); -#define cc_fail_fallback_sip(a, b, c, d) cc_int_fail_fallback(a, CC_SRC_SIP, b, c, d) -#define cc_fail_fallback_gsm(a, b, c) cc_int_fail_fallback(a, CC_SRC_GSM, b, c, FALSE) - -#define cc_setup(a, b, c, d, e, f, g, h, i, j, k, l) cc_int_setup(a, CC_SRC_GSM, b, c, d, e, f, g, h, i, j, k, l) -#define cc_setup_ack(a, b, c, d, e) \ - cc_int_setup_ack(a, CC_SRC_GSM, b, c, d, e) -#define cc_proceeding(a, b, c, d) cc_int_proceeding(a, CC_SRC_GSM, b, c, d) -#define cc_alerting(a, b, c, d, e, f) \ - cc_int_alerting(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_connected(a, b, c, d, e, f) \ - cc_int_connected(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_connected_ack(a, b, c, d, e) \ - cc_int_connected_ack(a, CC_SRC_GSM, b, c, d, e) -#define cc_release(a, b, c, d, e, f) cc_int_release(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_release_complete(a, b, c, d, e) \ - cc_int_release_complete(a, CC_SRC_GSM, b, c, d, e) -#define cc_feature(a, b, c, d, e) cc_int_feature2(CC_MSG_FEATURE, a, CC_SRC_GSM, b, c, d, e, NULL) -#define cc_int_feature(a, b, c, d, e, f) cc_int_feature2(CC_MSG_FEATURE, a, b, c, d, e, f, NULL) -#define cc_feature_ack(a, b, c, d, e, f) \ - cc_int_feature_ack(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_offhook(a, b, c) cc_int_offhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, NULL, CC_MONITOR_NONE,CFWDALL_NONE) -#define cc_offhook_ext(a, b, c, d, e) cc_int_offhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, d, e,CFWDALL_NONE) -#define cc_onhook(a, b, c, d) cc_int_onhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, d, CC_REASON_NULL,__FILE__,__LINE__) -#define cc_onhook_ext(a, b, c, d, e) cc_int_onhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, d, e,__FILE__,__LINE__) -#define cc_line(a, b, c) cc_int_line(a, CC_SRC_GSM, b, c) -#define cc_digit_begin(a, b, c, d) cc_int_digit_begin(a, CC_SRC_GSM, b, c, d) -#define cc_dialstring(a, b, c, d) cc_int_dialstring(a, CC_SRC_GSM, b, c, d, NULL, CC_MONITOR_NONE) -#define cc_dialstring_ext(a, b, c, d, e, f) cc_int_dialstring(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_mwi(a, b, c, d, e, f, g, h, i) cc_int_mwi(a, CC_SRC_GSM, b, c, d, e, f, g, h, i ) -#define cc_options_sdp_req(a, b, c, d) cc_int_options_sdp_req(a, CC_SRC_GSM, b, c, d) -#define cc_audit_sdp_req(a, b, c, d) cc_int_audit_sdp_req(a, CC_SRC_GSM, b, c, d) - -typedef enum cc_types_t_ { - CC_TYPE_INVALID, - CC_TYPE_CCM, - CC_TYPE_OTHER -} cc_types_t; - -typedef enum cc_states_t_ { - CC_STATE_MIN = -1, - CC_STATE_OFFHOOK, - CC_STATE_DIALING, - CC_STATE_DIALING_COMPLETED, - CC_STATE_CALL_SENT, - CC_STATE_FAR_END_PROCEEDING, - CC_STATE_FAR_END_ALERTING, - CC_STATE_CALL_RECEIVED, - CC_STATE_ALERTING, - CC_STATE_ANSWERED, - CC_STATE_CONNECTED, - CC_STATE_HOLD, - CC_STATE_RESUME, - CC_STATE_ONHOOK, - CC_STATE_CALL_FAILED, - CC_STATE_HOLD_REVERT, - CC_STATE_UNKNOWN, - CC_STATE_MAX -} cc_states_t; - -/* Update cc_action_names structure in lsm.c with the - * corresponding change for the following structure. - */ -typedef enum cc_actions_t_ { - CC_ACTION_MIN = -1, - CC_ACTION_SPEAKER, - CC_ACTION_DIAL_MODE, - CC_ACTION_MWI, - CC_ACTION_MWI_LAMP_ONLY, - CC_ACTION_OPEN_RCV, - CC_ACTION_UPDATE_UI, - CC_ACTION_MEDIA, - CC_ACTION_RINGER, - CC_ACTION_SET_LINE_RINGER, - CC_ACTION_PLAY_TONE, - CC_ACTION_STOP_TONE, - CC_ACTION_STOP_MEDIA, - CC_ACTION_START_RCV, - CC_ACTION_ANSWER_PENDING, - CC_ACTION_PLAY_BLF_ALERTING_TONE, - CC_ACTION_MAX -} cc_actions_t; - -typedef enum cc_services_t_ { - CC_SERVICE_MIN = -1, - CC_SERVICE_MAX -} cc_services_t; - -typedef enum cc_update_ui_actions_t_ { - CC_UPDATE_MIN = -1, - CC_UPDATE_CONF_ACTIVE, - CC_UPDATE_CONF_RELEASE, - CC_UPDATE_XFER_PRIMARY, - CC_UPDATE_CALLER_INFO, - CC_UPDATE_SECURITY_STATUS, - CC_UPDATE_SET_CALL_STATUS, - CC_UPDATE_CLEAR_CALL_STATUS, - CC_UPDATE_SET_NOTIFICATION, - CC_UPDATE_CLEAR_NOTIFICATION, - CC_UPDATE_CALL_PRESERVATION, - CC_UPDATE_CALL_CONNECTED, - CC_UPDATE_MAX -} cc_update_ui_actions_t; - -typedef struct cc_state_data_offhook_t_ { - cc_caller_id_t caller_id; - int dial_mode; -} cc_state_data_offhook_t; - -/* - * This structure is passed in CC_STATE_DIALING to lsm to indicate - * wether a dialtone needs to be played or not - * should the stutter dial tone be suppressed or not - */ -typedef struct cc_state_data_dialing_t_ { - boolean play_dt; - boolean suppress_stutter; -} cc_state_data_dialing_t; - -typedef struct cc_state_data_dialing_completedt_ { - cc_caller_id_t caller_id; -} cc_state_data_dialing_completed_t; - -typedef struct cc_state_data_call_sent_t_ { - cc_caller_id_t caller_id; -} cc_state_data_call_sent_t; - -typedef struct cc_state_data_far_end_proceeding_t_ { - cc_caller_id_t caller_id; -} cc_state_data_far_end_proceeding_t; - -typedef struct cc_state_data_far_end_alerting_t_ { - cc_caller_id_t caller_id; -} cc_state_data_far_end_alerting_t; - -typedef struct cc_state_data_call_received_t_ { - cc_caller_id_t caller_id; -} cc_state_data_call_received_t; - -typedef struct cc_state_data_alerting_t_ { - cc_caller_id_t caller_id; -} cc_state_data_alerting_t; - -typedef struct cc_state_data_answered_t_ { - cc_caller_id_t caller_id; -} cc_state_data_answered_t; - -typedef struct cc_state_data_connected_t_ { - cc_caller_id_t caller_id; -} cc_state_data_connected_t; - -typedef struct cc_state_data_hold_t_ { - cc_caller_id_t caller_id; - boolean local; - cc_hold_resume_reason_e reason; -} cc_state_data_hold_t; - -typedef struct cc_state_data_resume_t_ { - cc_caller_id_t caller_id; - boolean local; -} cc_state_data_resume_t; - -typedef struct cc_state_data_onhook_t_ { - cc_caller_id_t caller_id; - boolean local; - cc_causes_t cause; -} cc_state_data_onhook_t; - -typedef struct cc_state_data_call_failed_t_ { - cc_caller_id_t caller_id; - cc_causes_t cause; -} cc_state_data_call_failed_t; - -typedef union cc_state_data_t_ { - cc_state_data_offhook_t offhook; - cc_state_data_dialing_t dialing; - cc_state_data_dialing_completed_t dialing_completed; - cc_state_data_call_sent_t call_sent; - cc_state_data_far_end_proceeding_t far_end_proceeding; - cc_state_data_far_end_alerting_t far_end_alerting; - cc_state_data_call_received_t call_received; - cc_state_data_alerting_t alerting; - cc_state_data_answered_t answered; - cc_state_data_connected_t connected; - cc_state_data_hold_t hold; - cc_state_data_resume_t resume; - cc_state_data_onhook_t onhook; - cc_state_data_call_failed_t call_failed; -} cc_state_data_t; - -typedef struct cc_action_data_digit_begin_ { - int tone; -} cc_action_data_digit_begin_t; - -typedef struct cc_action_data_tone_ { - vcm_tones_t tone; -} cc_action_data_tone_t; - -typedef struct cc_action_data_speaker_ { - boolean on; -} cc_action_data_speaker_t; - -typedef struct cc_action_data_dial_mode_ { - int mode; - int digit_cnt; -} cc_action_data_dial_mode_t; - -/* -typedef struct cc_action_data_mwi_ { - boolean on; - int32_t type; - int32_t newCount; - int32_t oldCount; - int32_t hpNewCount; - int32_t hpOldCount; -} cc_action_data_mwi_t; -*/ - -typedef struct cc_action_data_open_rcv_ { - boolean is_multicast; - cpr_ip_addr_t listen_ip; - uint16_t port; - boolean rcv_chan; - boolean keep; - media_refid_t media_refid; /* the ID of the media to reference to */ - sdp_media_e media_type; -} cc_action_data_open_rcv_t; - -typedef struct cc_set_call_status_data_ { - char *phrase_str_p; - int timeout; - callid_t call_id; - line_t line; -} cc_set_call_status_data_t; - -typedef struct cc_clear_call_status_data_ { - callid_t call_id; - line_t line; -} cc_clear_call_status_data_t; - -// mostly overlap with sessionTypes.h:cc_notification_data_t -typedef struct cc_set_notification_data_ { - char *phrase_str_p; - unsigned long timeout; - unsigned long priority; -} cc_set_notification_data_t; - -typedef union cc_update_ui_data_ { - cc_feature_data_call_info_t caller_info; - cc_set_call_status_data_t set_call_status_parms; - cc_clear_call_status_data_t clear_call_status_parms; - cc_set_notification_data_t set_notification_parms; - string_t security_status; -} cc_update_ui_data_t; - -typedef struct cc_action_data_update_ui_ { - cc_update_ui_actions_t action; - cc_update_ui_data_t data; -} cc_action_data_update_ui_t; - -typedef struct cc_action_data_ringer_ { - boolean on; -} cc_action_data_ringer_t; - -typedef struct cc_action_data_stop_media_ { - media_refid_t media_refid; /* the ID of the media to reference to */ -} cc_action_data_stop_media_t; - -typedef union cc_action_data_t_ { - cc_action_data_digit_begin_t digit_begin; - cc_action_data_tone_t tone; - cc_action_data_speaker_t speaker; - cc_action_data_dial_mode_t dial_mode; - cc_action_data_mwi_t mwi; - cc_action_data_open_rcv_t open_rcv; - cc_action_data_update_ui_t update_ui; - cc_action_data_ringer_t ringer; - cc_action_data_stop_media_t stop_media; -} cc_action_data_t; - -typedef struct cc_service_data_get_facility_by_line_ { - line_t line; -} cc_service_data_get_facility_by_line_t; - -typedef union cc_service_data_t_ { - cc_service_data_get_facility_by_line_t get_facility_by_line; -} cc_service_data_t; - - -typedef enum { - MEDIA_INTERFACE_UPDATE_NOT_REQUIRED, - MEDIA_INTERFACE_UPDATE_STARTED, - MEDIA_INTERFACE_UPDATE_IN_PROCESS -} dock_undock_event_t; - -extern dock_undock_event_t g_dock_undock_event; - -void cc_call_state(callid_t call_id, line_t line, cc_states_t state, - cc_state_data_t *data); -cc_rcs_t cc_call_action(callid_t call_id, line_t line, cc_actions_t action, - cc_action_data_t *data); -cc_rcs_t cc_call_service(callid_t call_id, line_t line, cc_services_t service, - cc_service_data_t *data); -void cc_call_attribute(callid_t call_id, line_t line, call_attr_t attr); -void cc_init(void); -void cc_free_msg_body_parts(cc_msgbody_info_t *msg_body); -void cc_free_msg_data(cc_msg_t *msg); -void cc_initialize_msg_body_parts_info(cc_msgbody_info_t *msg_body); -void cc_mv_msg_body_parts(cc_msgbody_info_t *dst_msg, - cc_msgbody_info_t *src_msg); -cc_rcs_t cc_cp_msg_body_parts(cc_msgbody_info_t *dst_msg, - cc_msgbody_info_t *src_msg); -void cc_mv_caller_id(cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller); - //function that will be invoked by modules external to gsm: - -int cc_is_cnf_call(callid_t call_id); -cc_transfer_mode_e cc_is_xfr_call(callid_t call_id); - -extern cprBuffer_t cc_get_msg_buf(int min_size); -extern const char *cc_feature_name(cc_features_t id); -extern const char *cc_msg_name(cc_msgs_t id); -extern const char *cc_cause_name(cc_causes_t id); -extern void cc_media_update_native_video_support(boolean val); -extern void cc_media_update_video_cap(boolean val); -extern void cc_media_update_native_video_txcap(boolean val); -extern cc_boolean cc_media_isTxCapEnabled(); -extern cc_boolean cc_media_isVideoCapEnabled(); -extern void cc_media_setVideoAutoTxPref(cc_boolean txPref); -extern cc_boolean cc_media_getVideoAutoTxPref(); -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/check_sync.h b/media/webrtc/signaling/src/sipcc/core/includes/check_sync.h deleted file mode 100644 index c5dd8051df8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/check_sync.h +++ /dev/null @@ -1,46 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CHECK_SYNC_H -#define CHECK_SYNC_H - -#include "util_parse.h" - -typedef enum { - SYNCS_ANY, - SYNCS_GOT_VERSION, - SYNCS_GOT_VERSION_EQ, - SYNCS_GOT_SYNC, - SYNCS_GOT_SYNC_EQ, - SYNCS_GOT_GENERIC, - SYNCS_GOT_GENERIC_EQ -} sync_states; - -typedef enum { - SYNCF_NONE, - SYNCF_MY, - SYNCF_WILD -} SyncVersionFound_t; - -typedef struct { - char myVersion[MAX_LOAD_ID_STRING]; - char resetSync[MAX_SYNC_LEN]; - SyncVersionFound_t versionFound; -} VersionSync_t; - -#define SYNCINFO_XML "syncinfo.xml" -#define SYNC_BUF_SIZE 4096 - -extern int CheckSync; -extern int SyncInfoInProgress; -extern char *SyncBuffer; - -int check_sync_get(void); -void add_sync_info(char *version, char *sync, VersionSync_t *versionSync); -int parse_sync_entry(char **parseptr, VersionSync_t *versionSync); -int parse_sync_info(char *parseptr, VersionSync_t *versionSync); -void process_sync_info(char *syncInfo); -short handle_sync_message(short cmd, void *pData); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/ci.h b/media/webrtc/signaling/src/sipcc/core/includes/ci.h deleted file mode 100644 index e5d014cf4a0..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/ci.h +++ /dev/null @@ -1,34 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CI_INCLUDED_H -#define _CI_INCLUDED_H - -#include "plat_api.h" -#include "plat_debug.h" - - -/* return codes for CI command processing */ -#define CI_OK (0) -#define CI_ERROR (1) -#define CI_INVALID (2) -#define CI_AMBIGUOUS (3) - -/* flags for CI processing */ -#define CI_PROMPT (0x0001) - -/* - * Prototypes for public functions - */ -void ci_init(); -int ci_process_input(const char *str, char *wkspace, int wklen); -int32_t ci_show_cmds(int32_t argc, const char *argv[]); -ci_callback ci_set_interceptor(ci_callback func); - -int ci_err_too_few(void); /* "Too few arguments" */ -int ci_err_too_many(void); /* "Too many arguments" */ -int ci_err_inv_arg(void); /* "Invalid argument" */ -uint32_t ci_streval(const char *str); - -#endif /* _CI_INCLUDED_H */ diff --git a/media/webrtc/signaling/src/sipcc/core/includes/config.h b/media/webrtc/signaling/src/sipcc/core/includes/config.h deleted file mode 100755 index 0b6e8a54d99..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/config.h +++ /dev/null @@ -1,194 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#include "cpr_types.h" -#include "cpr_timers.h" -#include "cfgfile_utils.h" -#include "configmgr.h" -#include "prot_configmgr.h" -#include "phone.h" - -/* - * List of timers that the CFG task is responsible for. - * CPR will send a msg to the CFG task when these - * timers expire. CPR expects a timer id when the timer - * is created, this enum serves that purpose. - */ -typedef enum { - CFG_TFTP_RETRY_TIMER -} cfgTimerList_t; - -#define MAX_REQ_FIELDS 20 -#define MAX_FIELD_NAME_SIZE 30 -#define MAX_FIELD_VALUE_SIZE 30 -#define MAX_FIELDDESC_STR (MAX_FIELD_VALUE_SIZE+2) -#define MAX_TFTP_PATH_LEN 64 - -/* - * Definition of bits used in pDHCPInfo->extFields.ext.appStatus (32bits). - * Please note that some of these flags correspond to status flags - * asserted by Little App. Please see little_app.c, and make sure these - * flags are kept consistent. - */ - -#define APPSTATUS_UPGRADE_FAILED 0x80000000L - -/* maximum length of config file including comments */ -#define MAX_CFG_FILE_LENGTH 0x2000 - -/* minimum length of a registrion in seconds */ -#define MIN_REGISTRATION_PERIOD 20 - -#define BUF_TEST(); - -typedef enum { - ERASE_PROGRAM, - ERASE_ONLY, - PROGRAM_ONLY -} flash_mode_t; - -extern var_t prot_cfg_table[]; -extern cfg_rom_t *const prot_startup_config; -extern cfg_rom_t *const prot_running_config; -extern cfg_rom_t *const prot_temp_config; -extern int config_commit(int); -extern int prot_sanity_check_config_settings(void); -extern boolean prot_option_allowed_in_cfg_file(const char *); -extern void prot_shutdown(void); -extern int prot_config_change_notify(int); -extern void prot_disconnected(int); -extern int FlashaProgram(uint16_t *Source, uint16_t *Dest, uint32_t Size, - flash_mode_t mode); - -extern uint16_t g_NewVlan; -extern uint16_t g_NewRelease; -extern uint16_t g_NewErase; -extern char local_media_type_string[]; -extern char local_net_dev_type_string[]; - -void CFGTftpTimeout(int /*cpr_timer_t*/ *tmr); -int CFGProgramFlash(uint8_t *src, uint8_t *dst, uint32_t len); -int CFGEraseFlash(uint8_t *src, uint8_t *dst, uint32_t len); -int CFGEraseProgramFlash(uint8_t *src, uint8_t *dst, uint32_t len); -int CFGChksum(uint8_t *ptr, uint32_t len, uint32_t *csum, int dspmode, - int cmpmode); -int CFGGetUISettings(uint8_t *pData); -int CFGSetUISettings(void); -void CFGSetLockState(boolean); -boolean CFGIsLocked(void); -void cfg_set_running_config(void); -void cfg_get_stored_prot_settings(void); -void LoadTempConfigData(void); -void config_handle_cdp(int); -void cfg_sanity_check_media_range(void); -void cfg_check_la_appStatus(unsigned long appStatus); -void cfg_set_inhibitLoading(int yesno); -int cfg_get_inhibitLoading(void); - - -///////////////////////////////////////////////////////////// -// Configuration Variables replacing CUCM config file -// -//// -////// - -static const int gStartMediaPort = 16384; -static const int gStopMediaPort = 32766; -static const boolean gCallerIdBlocking = FALSE; -static const boolean gAnonblock = FALSE; -static const char gPreferredCodec[] = "none"; -static const char gDtmfOutOfBand[] = "avt"; -static const int gDtmfAvtPayload = 101; -static const int gDtmfDbLevel = 3; -static const int gSipRetx = 10; -static const int gSipInviteRetx = 6; -static const int gTimerT1 = 500; -static const int gTimerT2 = 4000; -static const int gTimerInviteExpires = 180; -static const int gTimerRegisterExpires = 3600; -static const boolean gRegisterWithProxy = TRUE; -static const char gBackupProxy[] = "USECALLMANAGER"; -static const int gBackupProxyPort = 5060; -static const char gEmergencyProxy[] = "USECALLMANAGER"; -static const int gEmergencyProxyPort = 5060; -static const char gOutboundProxy[] = "USECALLMANAGER"; -static const int gOutboundProxyPort = 5060; -static const boolean gNatRecievedProcessing = FALSE; -static const char gUserInfo[] = "None"; -static const boolean gRemotePartyID = TRUE; -static const boolean gSemiAttendedTransfer = TRUE; -static const int gCallHoldRingback = 2; -static const boolean gStutterMsgWaiting = FALSE; -static const char gCallForwardURI[] = "x-cisco-serviceuri-cfwdall"; -static const boolean gCallStats = TRUE; -static const int gTimerRegisterDelta = 5; -static const int gMaxRedirects = 70; -static const boolean gRfc2543Hold = FALSE; -static const boolean gLocalCfwdEnable = TRUE; -static const int gConnectionMonitorDuration = 120; -static const int gCallLogBlfEnabled = 3 & 0x1; -static const boolean gRetainForwardInformation = FALSE; -static const int gRemoteCcEnable = 1; -static const int gTimerKeepAliveExpires = 120; -static const int gTimerSubscribeExpires = 120; -static const int gTimerSubscribeDelta = 5; -static const int gKpml = 3; -static const boolean gNatEnabled = FALSE; -static const char gNatAddress[] = ""; -static const boolean gAnableVad = FALSE; -static const boolean gAutoAnswerAltBehavior = FALSE; -static const int gAutoAnswerTimer = 1; -static const boolean gAutoAnswerOverride = TRUE; -static const int gOffhookToFirstDigitTimer = 15000; -static const int gSilentPeriodBetweenCallWaitingBursts = 10; -static const int gRingSettingBusyStationPolicy = 0; -static const int gBlfAudibleAlertSettingOfIdleStation = 0; -static const int gBlfAudibleAlertSettingOfBusyStation = 0; -static const int gJoinAcrossLines = 0; -static const boolean gCnfJoinEnabled = TRUE; -static const int gRollover = 0; -static const boolean gTransferOnhookEnabled = FALSE; -static const int gDscpForAudio = 184; -static const int gDscpVideo = 136; -static const int gT302Timer = 5000; -static const int gLineIndex = 1; -static const int gFeatureID = 9; -static const char gProxy[] = "USECALLMANAGER"; -static const int gPort = 5060; -static const char gDisplayName[] = ""; -static const char gMessagesNumber[] = ""; -static const boolean gCallerName = TRUE; -static const boolean gCallerNumber = FALSE; -static const boolean gRedirectedNumber = FALSE; -static const boolean gDialedNumber = TRUE; -static const unsigned char gMessageWaitingLampPolicy = 3; -static const unsigned char gMessageWaitingAMWI = 1; -static const unsigned char gRingSettingIdle = 4; -static const unsigned char gRingSettingActive = 5; -static const unsigned char gAutoAnswerEnabled = 2 & 0x1; -static const unsigned char gCallWaiting = 3 & 0x1; -static const int gDeviceSecurityMode = 1; -static const int gCcm2_sip_port = 5060; -static const int gCcm3_sip_port = 5060; -static const boolean gCcm1_isvalid = TRUE; -static const int gDscpCallControl = 1; -static const int gSpeakerEnabled = 1; -static const char gExternalNumberMask[] = ""; -static const char gVersion[] = "0.1"; -static const boolean gRTCPMUX = TRUE; -static boolean gRTPSAVPF = TRUE; /* TRUE = RTP/SAVPF , FALSE = RTP/SAVP */ -static const boolean gMAXAVBITRATE = FALSE; /* Following six are OPUS fmtp options */ -static const boolean gMAXCODEDAUDIOBW = FALSE; -static const boolean gUSEDTX = FALSE; -static const boolean gSTEREO = FALSE; -static const boolean gUSEINBANDFEC = FALSE; -static const boolean gCBR = FALSE; -static const boolean gMAXPTIME = FALSE; -static const int gSCTPPort = 5000; -static const int gNumDataStreams = 16; - -#endif /* _CONFIG_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/includes/configapp.h b/media/webrtc/signaling/src/sipcc/core/includes/configapp.h deleted file mode 100644 index fae40922e51..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/configapp.h +++ /dev/null @@ -1,13 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CONFIGAPP_H -#define CONFIGAPP_H - -extern void configapp_init(); -extern void configapp_shutdown(); -extern void configapp_process_msg(uint32_t cmd, void *msg); - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/includes/configmgr.h b/media/webrtc/signaling/src/sipcc/core/includes/configmgr.h deleted file mode 100755 index 3c0b4bee8aa..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/configmgr.h +++ /dev/null @@ -1,62 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CONFIGMGR_H_ -#define _CONFIGMGR_H_ - -/* - * #defines for maximum length of the image names - * The MAX_LOAD_ID_LENGTH must be larger (or the same as) - * MAX_OLD_LOAD_ID_LENGTH or strange things may - * happen because they are used as indexes into - * arrays. - */ -#include "cpr_types.h" -#define MAX_LOAD_ID_LENGTH 60 -#define MAX_LOAD_ID_STRING MAX_LOAD_ID_LENGTH + 1 -#define MAX_OLD_LOAD_ID_LENGTH 8 -#define MAX_OLD_LOAD_ID_STRING MAX_OLD_LOAD_ID_LENGTH + 1 -#define MAX_URL_LENGTH 128 - -#define MAX_SYNC_LEN 33 -#define MAX_PHONE_LABEL 32 - -/* Start of section for new "protocol-inspecific" calls */ - -#define MAX_CONFIG_STRING_NAME 64 -#define DEFAULT_LINE 1 - -#define YESSTR "YES" -#define NOSTR "NO" -#define IPOFZEROS "0.0.0.0" - -enum ACTIONATTR { - AA_IGNORE = 0, - AA_COMMIT = 1, - AA_RELOAD = 1 << 1, - AA_REGISTER = 1 << 2, - AA_FORCE = 1 << 3, - AA_RESET = 1 << 4, - AA_SETTINGS = 1 << 5, - AA_BU_REG = 1 << 6 -}; - -/********************************************************* - * - * External Function Prototypes - * - *********************************************************/ -void config_get_string(int id, char *buffer, int buffer_len); -void config_set_string(int id, char *buffer); -void config_get_value(int id, void *buffer, int length); -void config_set_value(int id, void *buffer, int length); - -void config_get_line_string(int id, char *buffer, int line, int buffer_len); -void config_set_line_string(int id, char *buffer, int line); -void config_get_line_value(int id, void *buffer, int length, int line); -void config_set_line_value(int id, void *buffer, int length, int line); - -void config_init(void); - -#endif /* _CONFIGMGR_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/includes/debug.h b/media/webrtc/signaling/src/sipcc/core/includes/debug.h deleted file mode 100644 index b9197c8eb19..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/debug.h +++ /dev/null @@ -1,107 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _DEBUG_INCLUDED_H /* allows multiple inclusion */ -#define _DEBUG_INCLUDED_H - -#include "cpr_types.h" -#include "plat_api.h" -#include "phone_debug.h" -#include "CSFLog.h" - -typedef cc_int32_t (*debug_callback)(cc_int32_t argc, const char *argv[]); -typedef cc_int32_t (*show_callback)(cc_int32_t argc, const char *argv[]); -typedef cc_int32_t (*clear_callback)(cc_int32_t argc, const char *argv[]); - -typedef enum { - TEST_OPEN, - TEST_CLOSE, - TEST_KEY, - TEST_ONHOOK, - TEST_OFFHOOK, - TEST_SHOW, - TEST_HIDE, - TEST_PROFILE, - TEST_C3PO -} test_command_t; - - -typedef int32_t (*test_callback)(int32_t argc, const char *argv[], - test_command_t command); - -extern int32_t TestMode; -extern int32_t TestShow; - -typedef enum { - DEBUG_ENTRY_TYPE_FLAG, - DEBUG_ENTRY_TYPE_DEBUG_FUNC, - DEBUG_ENTRY_TYPE_SHOW_FUNC -} debug_entry_type_e; - -typedef struct { - const char *keyw; - union { - int32_t *flag; - debug_callback func; - show_callback show_func; - } u; - debug_entry_type_e type; - boolean show_tech; -} debug_entry_t; - -typedef struct { - const char *keyw; - union { - int32_t *flag; - clear_callback func; - } u; -} clear_entry_t; - -typedef struct { - const char *keyw; - const char *abrv; - const char *help; - boolean hidden; - union { - int32_t *flag; - test_callback func; - } u; - test_command_t command; -} test_entry_t; - - -typedef struct { - unsigned char flag; - unsigned char hookevent; - unsigned char keyevent; // keyevent and key will double as a timer value internally - unsigned char key; -} testevent_t; - -// The next 4 defines are used as flag values to specify the event types in the queue. -// Note that we cannot use the HOOKSCAN and KEYSCAN that are defined in phone.h, because -// HOOKSCAN requires a full integer. In order to minimize space in the test event queue -// we need short numbers. -#define TEST_NONE 0 -#define TEST_KEYSCAN 1 -#define TEST_HOOKSCAN 2 -#define TEST_TIMER 0x80 - - -#define MAX_DEBUG_NAME 50 -#define MAX_SHOW_NAME 50 -#define MAX_CLEAR_NAME 50 - -/* - * Prototypes for public functions - */ -void bind_test_keyword(const char *keyword, const char *abrv, boolean hidden, - test_callback func, test_command_t command, - const char *help); -testevent_t TESTGetEvent(void); - -// Send debug output to CSFLog -#define debugif_printf(format, ...) CSFLogDebug("debugif", format, ## __VA_ARGS__ ) - - -#endif /* _DEBUG_INCLUDED_H */ diff --git a/media/webrtc/signaling/src/sipcc/core/includes/dialplan.h b/media/webrtc/signaling/src/sipcc/core/includes/dialplan.h deleted file mode 100755 index ec1f93e6101..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/dialplan.h +++ /dev/null @@ -1,111 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef DIALPLAN_H -#define DIALPLAN_H - -#include -#include "phone_types.h" - -#define DIALPLAN_MAX_SIZE 0x2000 -#define MAX_SUBTITUTIONS 5 -#define MAX_TONES 3 -#define MAX_TEMPLATE_LENGTH 196 -#define DIAL_ESCAPE '\\' -#define MAX_DIALSTRING 256 -#define DIAL_TIMEOUT 10 -#define MAX_DP_VERSION_STAMP_LEN (64+1) -extern char g_dp_version_stamp[MAX_DP_VERSION_STAMP_LEN]; - -typedef enum { - DIAL_NOMATCH = 0, - DIAL_GIVETONE, - DIAL_WILDPATTERN, - DIAL_FULLPATTERN, - DIAL_FULLMATCH, - DIAL_IMMEDIATELY -} DialMatchAction; - -/* Set enum values to match DialMatchAction */ -typedef enum { - DIALTONE_NOMATCH = 0, - DIALTONE_WILD = 2, - DIALTONE_FULL, - DIALTONE_EXACT -} DialToneMatch; - -typedef enum { - UserUnspec, - UserPhone, - UserIP -} UserMode; - -typedef enum { - RouteDefault, // Route using the default proxy - RouteEmergency, // Route using the emergency proxy - RouteFQDN // Route according to the FQDN in the entry -} RouteMode; - -struct DialTemplate { - struct DialTemplate *next; - char *pattern; - line_t line; - char *rewrite; - int timeout; - UserMode userMode; - RouteMode routeMode; - int tones_defined; - vcm_tones_t tone[MAX_TONES]; -}; - -struct StoredDialTemplate { - short size; // Size of header part of structure - short nextOffset; // total Number of bytes used in the entry - // A zero here is used as a last entry - int timeout; - line_t line; - UserMode userMode; - short pattern_offset; // Offset to the pattern string - short rewrite_offset; // Offset to the rewrite string - RouteMode routeMode; - int tones_defined; - vcm_tones_t tone[MAX_TONES]; - -}; - -typedef enum { - STATE_ANY, - STATE_GOT_MATCH, - STATE_GOT_MATCH_EQ, - STATE_GOT_LINE, - STATE_GOT_LINE_EQ, - STATE_GOT_TIMEOUT, - STATE_GOT_TIMEOUT_EQ, - STATE_GOT_USER, - STATE_GOT_USER_EQ, - STATE_GOT_REWRITE, - STATE_GOT_REWRITE_EQ, - STATE_GOT_ROUTE, - STATE_GOT_ROUTE_EQ, - STATE_GOT_TONE, - STATE_GOT_TONE_EQ, - STATE_START_TAG_COMPLETED, /* start tag parsing is complete when self-terminating () format is not used */ - STATE_END_TAG_STARTED, /* end tag started when we see ">3) -#define MILLISECONDS_TO_SAMPLES(PERIOD) ((PERIOD)<<3) - -#define MAX_TX_RTP_PORTS 2 -#define MAX_FRAMES_PER_PACKET 6 -#define MAX_VOICE_FRAME_SIZE 320 - -#define GSM_EFR_FRAME_SIZE 32 -#define GSM_FR_FRAME_SIZE 33 -#define G729_FRAME_SIZE 10 -#define G723_FRAME_SIZE63 24 -#define G723_FRAME_SIZE53 20 -#define G723_SID_FRAME_SIZE 4 -#define G729_SID_FRAME_SIZE 2 - -#define GSM_SAMPLES_PER_FRAME 160 -#define G729_SAMPLES_PER_FRAME 80 -#define G723_SAMPLES_PER_FRAME 240 -#define LINEAR_16KHZ_SAMPLES_PER_FRAME 160 // 10 ms = 160 samples @ 16 kHz - -#define MAX_ARM_TO_DSP_CHANNEL 3 -#define MAX_DSP_TO_ARM_CHANNEL 2 -#define HALF_SIZE_DATA_INGRESS 240 -#define RX_MAX MAX_ARM_TO_DSP_CHANNEL - -#define OPEN_OK 0 -#define OPEN_ERROR_DUPLICATE -1 - -#define ASSIGN_TX_CHANNEL (0x1) -#define ASSIGN_RX_CHANNEL (0x2) -#define CHANNEL_CLOSE_IN_PROGRESS (0x80000000) - -#define RTP_START_PORT 0x4000 -#define RTP_END_PORT 0x7FFE - -#define GET_DYN_PAYLOAD_TYPE_VALUE(a) ((a & 0XFF00) ? ((a & 0XFF00) >> 8) : a) -#define SET_PAYLOAD_TYPE_WITH_DYNAMIC(a,b) ((a << 8) | b) - - -//============================================================================= -// -// Enumeration Types -// -//----------------------------------------------------------------------------- -enum RTP_PAYLOAD_TYPES -{ - G711_MULAW_PAYLOAD_TYPE = 0, - GSM_FR_PAYLOAD_TYPE = 3, - G723_PAYLOAD_TYPE = 4, - G711_ALAW_PAYLOAD_TYPE = 8, - LINEAR_8KHZ_PAYLOAD_TYPE = 12, - TYPE13_SID_PAYLOAD_TYPE = 13, - G729_PAYLOAD_TYPE = 18, - GSM_EFR_PAYLOAD_TYPE = 20, - LINEAR_16KHZ_PAYLOAD_TYPE = 25, - AVT_PAYLOAD_TYPE = 101, - MASK_PAYLOAD_TYPE = 0x7f -}; - -enum RTP_TRANSMIT_STATES -{ - RTP_TX_FRAME, - RTP_TX_START, - RTP_TX_NO_FRAME, - RTP_TX_END = RTP_TX_NO_FRAME, - RTP_TX_SID -}; - -enum RTP_RX_STATES -{ - RTP_RX_NORMAL, - RTP_RX_FLUSH_SOON, - RTP_RX_FLUSH_NOW -}; - -enum RTP_TALKERS_TYPES -{ - FIRST_TALKER = 0, - LAST_TALKER = RX_MAX - 1, - NO_TALKER -}; - -typedef enum -{ - RTP_INGRESS = 0, - RTP_EGRESS -} t_RtpDirection; - -//============================================================================= -// -// Structure/Type definitions -// -//----------------------------------------------------------------------------- -typedef uint16_t rtp_channel_t; - -/********************************/ -/* RTP Call Stats Descriptor */ -/* */ -/********************************/ - -typedef struct -{ - int call_id; - unsigned long Rxduration; - unsigned long Rxpackets; - unsigned long Rxoctets; - unsigned long Rxlatepkts; - unsigned long Rxlostpkts; - unsigned long Txduration; - unsigned long Txpackets; - unsigned long Txoctets; -} t_callstats; - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/scSession.h b/media/webrtc/signaling/src/sipcc/core/includes/scSession.h deleted file mode 100755 index 0525d1928b1..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/scSession.h +++ /dev/null @@ -1,24 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "string_lib.h" -#include "sessionConstants.h" -#include "sessionTypes.h" - -/* CallControl Provider Management Interfaces */ -void scSessionProviderCmd(sessionProvider_cmd_t *data); - -/* CallControl Provider Management Updates */ -void scSessionProviderState(unsigned int state, scProvider_state_t *data); - -/* Session mgmt */ -session_id_t scCreateSession(session_create_param_t *param); -void scCloseSession(session_id_t sess_id); -void scInvokeFeature(session_feature_t *featData); - -/* Session Updates */ -void scSessionUpdate(session_update_t *session); -void scFeatureUpdate(feature_update_t *data); - - diff --git a/media/webrtc/signaling/src/sipcc/core/includes/session.h b/media/webrtc/signaling/src/sipcc/core/includes/session.h deleted file mode 100755 index 2b2390a262e..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/session.h +++ /dev/null @@ -1,168 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSION_H_ -#define _SESSION_H_ - -#include "sessionConstants.h" -#include "sessionTypes.h" -#include "sessuri.h" - -/** - * sessionProviderCmd - * Session Provider Management Interfaces - * Called by Application to issue cmds to Session Provider - * - * @param data - sessionProvider_cmd_t - * Contains the command session provider type and provider specific data - * - * @return none - * - */ -void sessionProviderCmd(sessionProvider_cmd_t *); - -/** - * sessionProviderState - * Method to report session provider state updates to Application - * - * @param state - provider_state_t - * Contains the INS/OOS state along with provider specific data - * - * @return none - * - */ -void sessionProviderState(provider_state_t *state); - -/** - * createSession - * - * Called to create a session of requested type - * - * @param param - uri - * indicates type of session and specific params - * - * @return ccSession_id_t - id of the session created - */ - -session_id_t createSession(uri_t uri_info); - -/** - * closeSession - * - * Called to close an existing session - * - * @param sess_id - session id of the session to be closed - * - * @return >=0 success, -1 failure - */ - -int closeSession(session_id_t sess_id); - -/** - * sessionCmd - * Session Lifecycle Management Interfaces - * Called by Application to manage Session States - * - * @param data - sessionCmd_t - * Contains the command session type and session specific data - * - * @return none - * - */ -void sessionCmd(sessionCmd_t *sCmd); - -/** - * invokeFeature - * - * Called to invoke a feature on session or device - * - * @param feat - feature specific data along with its id - * @param featData - Additional info if needed for the feature - * - * @return none - * - */ - -void invokeFeature(session_feature_t *feat); - -/** - * invokeProviderFeature - * - * Called to invoke a feature on session or device - * - * @param feat - feature specific data along with its id - * @param featData - Additional info if needed for the feature - * - * @return none - * - */ - -void invokeProviderFeature(session_feature_t *feat); - -/** - * sessionUpdate - * - * Called by session provider to update session state and data - * - * @param session - session_update_t - * Contains session specific event state and data - * - * @return none - * - */ -void sessionUpdate(session_update_t *session); - -/** - * featureUpdate - * - * Called by session provider to update feature state and data - * not specific to a session - * - * @param feature - feature specific events and data - * - * @return none - * - */ -void featureUpdate(feature_update_t *feature); - - -/** - * sessionMgmt - * - * Called to manage various misc. functions of the device - * - * @param sessMgmt - the data - * - * @return none - * - */ -void sessionMgmt (session_mgmt_t *sess_mgmt); - -/** - * sessionSendInfo - * - * Called to send an Info Package - * - * @param send_info - the session ID and the Info Package to be sent - * - * @return none - * - */ -void sessionSendInfo (session_send_info_t *send_info); - -/** - * sessionRcvdInfo - * - * Called to forward a received Info Package (either parsed or unparsed) - * to the Java side - * - * @param rcvd_info - the session ID and Info Package received - * - * @return none - * - */ -void sessionRcvdInfo (session_rcvd_info_t *rcvd_info); - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/includes/sessionConstants.h b/media/webrtc/signaling/src/sipcc/core/includes/sessionConstants.h deleted file mode 100755 index 54ba1994b22..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/sessionConstants.h +++ /dev/null @@ -1,382 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSION_CONSTANTS_H_ -#define _SESSION_CONSTANTS_H_ - -#include "cc_constants.h" - -typedef enum { - GROUP_TAG, - GROUP_SESSION_TYPE, - GROUP_CMD, - GROUP_STATE, - GROUP_CC_MODE, - GROUP_CC_REG_CAUSE, - GROUP_CC_FEATURE, - GROUP_DEVICE_FEATURE, - GROUP_RINGER_RESERVATION, - GROUP_CALL_STATE, - GROUP_CC_ATTR, - GROUP_CC_CALL_TYPE, - GROUP_CC_SECURITY, - GROUP_INFO_PKG_ID, - GROUP_CC_POLICY, - GROUP_UI_PRIVACY, - GROUP_SIP_BLF, - GROUP_SESSION_EVENT, - GROUP_CALL_EVENT, - GROUP_FILEPLAYER, - GROUP_MEDIA_EVENT, - GROUP_MEDIA_DIRECTION, - GROUP_PRIORITY, - GROUP_SESSION, - GROUP_CC_CAUSE -} group_t; - -typedef enum { - TAG_LINE = 1L, - TAG_STATE, - TAG_CCM_ADDR, - TAG_STATUS, - TAG_LCLCFWD, - TAG_CFANUM, - TAG_COUNT, - TAG_INSTANCE, - TAG_TIMEOUT, - TAG_PRIORITY, - TAG_NOTPROG, - TAG_RESET_TYPE, - TAG_ATTR, - TAG_INST, - TAG_SECURITY, - TAG_CLD_NAME, - TAG_CLD_NUMB, - TAG_CLG_NAME, - TAG_CLG_NUMB, - TAG_PRIVACY, - TAG_FEAT_SET, - TAG_FEATURE, - TAG_PROMPT, - TAG_ORIG_NAME, - TAG_ORIG_NUMB, - TAG_REDIR_NAME, - TAG_REDIR_NUMB, - TAG_ALT_CLG, - TAG_DISP_CLG, - TAG_DISP_CLD, - TAG_CALL_TYPE, - TAG_MODE, - TAG_CAUSE, - TAG_CALL_SELECTED, - TAG_BUTTON_NUMB, - TAG_SPEED_DIAL, - TAG_LABEL, - TAG_GCID, - TAG_LOGDISP, - TAG_MWI_TYPE, - TAG_NEW_COUNT, - TAG_OLD_COUNT, - TAG_HP_NEW_COUNT, - TAG_HP_OLD_COUNT, - TAG_MEDIA_TYPE, - TAG_MEDIA_DIRECTION, - TAG_MEDIA_MODE, - TAG_DURATION, - TAG_SESSION_HANDLE, - TAG_MCAP_ID, - TAG_GROUP_ID, - TAG_STREAM_ID, - TAG_REF_COUNT, - TAG_SESSION_ID, - TAG_RECV_INFO_LIST, - TAG_INFO_PACKAGE, - TAG_CONTENT_TYPE, - TAG_MESSAGE_BODY, - TAG_POLICY, - TAG_CFG_VER, - TAG_DP_VER, - TAG_SK_VER, - TAG_METHOD, - TAG_SIS_VER_NAME, - TAG_SIS_VER_MAJOR, - TAG_SIS_VER_MINOR, - TAG_SIS_VER_ADDTNL -} group_tag_t; - - -/* Session types supported */ -/* SESSIONTYPE_* is encoded into the MSB of session_feature_t.session_id */ -// XXX TODO figure out how to decouple this from the Java side constant -typedef enum { - SESSIONTYPE_CALLCONTROL = 1L, - SESSIONTYPE_RSTP, - SESSIONTYPE_RTP, - SESSIONTYPE_FILEPLAYER, - SESSIONTYPE_TONE, - SESSIONTYPE_CAPTURE -} group_session_type_t; - -/* Session Provider Management Commands */ -typedef enum { - CMD_INIT = 1L, - CMD_INSERVICE, - CMD_RESTART, - CMD_SHUTDOWN, - CMD_UNLOAD, - CMD_PRE_INIT, - CMD_PRO_BASE, - CMD_UNREGISTER_ALL_LINES = 10L, - CMD_REGISTER_ALL_LINES, - CMD_BLF_INIT -} group_cmd_t; - -/* Other provider specific cmds can be defined beginning with CMD_PRO_BASE */ -/* TBD from JNI */ -#define CC_CMD_UPDATELINES CMD_PRO_BASE - -/** - * Defines registration state - */ -typedef enum { - CC_CREATED_IDLE, - CC_OOS_FAILOVER, - CC_OOS_REGISTERING, - CC_OOS_AWAIT_CFG_SYNC, - CC_OOS_AWAIT_RESTART, - CC_INSERVICE, - CC_OOS_IDLE -} cc_reg_state_t; - -/* Other provider specific cmds can be defined beginning with STATE_PRO_BASE */ - - - -/* Device specific feature update IDs */ -typedef enum { - DEVICE_FEATURE_CFWD = 1L, - DEVICE_FEATURE_MWI, - DEVICE_FEATURE_MWILAMP, - DEVICE_FEATURE_MNC_REACHED, - DEVICE_SERVICE_CONTROL_REQ, - DEVICE_NOTIFICATION, - DEVICE_LABEL_N_SPEED, - DEVICE_REG_STATE, - DEVICE_CCM_CONN_STATUS, - DEVICE_CONDITIONAL_RESTART = 14L, - DEVICE_SYNC_CONFIG_VERSION, - DEVICE_ENABLE_VIDEO, - DEVICE_ENABLE_CAMERA, - DEVICE_FEATURE_BLF, - DEVICE_SUPPORTS_NATIVE_VIDEO -} group_device_feature_t; - -/* Ringer Reservation feature update IDs */ -typedef enum { - RINGER_RESERVATION_CREATED = 100L, - RINGER_RESERVATION_UPDATE -} group_ringer_reservation_t; - -/* Info Package */ -typedef enum { - INFO_PKG_ID_GENERIC_RAW = 0L -} group_info_pkg_id_t; - -/* Session Events */ -typedef enum { - SESSION_CREATED = 1L, - SESSION_CLOSED -} group_session_event_t; - -/* Call Session Events */ -typedef enum { - CALL_SESSION_CREATED = SESSION_CREATED, - CALL_SESSION_CLOSED = SESSION_CLOSED, - CALL_STATE = 3L, - CALL_NEWCALL, - CALL_INFORMATION, - CALL_ATTR, - CALL_SECURITY, - CALL_LOGDISP, - CALL_PLACED_INFO, - CALL_STATUS, - CALL_DELETE_LAST_DIGIT, - CALL_ENABLE_BKSP, - CALL_SELECT_FEATURE_SET, - CALL_SELECTED, - CALL_PRESERVATION_ACTIVE, - CALL_GCID, - CALL_FEATURE_CANCEL, - VIDEO_AVAIL = 20L, - CALL_RECV_INFO_LIST, - VIDEO_OFFERED, - RINGER_STATE, - CALL_CALLREF, - MEDIA_INTERFACE_UPDATE_BEGIN, - MEDIA_INTERFACE_UPDATE_SUCCESSFUL, - MEDIA_INTERFACE_UPDATE_FAIL -} group_call_event_t; - -/* File Player Session Events */ -typedef enum { - FILEPLAYER_PLAYED = 300L, - FILEPLAYER_ALLOCATED -} group_fileplayer_t; - -typedef enum { - TONE_STARTED = 101L, - TONE_STOPPED, - MEDIA_INFO, - MEDIA_UPDATE -} group_media_event_t; - -//#include "com_cisco_sessionapi_MediaDirection.h" -typedef enum { - RX_DIRECTION = 0L, - TX_DIRECTION, - BI_DIRECTION -} group_media_direction_t; - -typedef enum { - PROMPTSTATUS_PROMPT = 10L, - PROMPTSTATUS_HIGH = 11L, - PROMPTSTATUS_NORMAL = 15L, - PROMPTSTATUS_MEDIA_MANAGER = 16L, - PROMPTSTATUS_NOTIFICATION = 20L, - PROMPTSTATUS_STATUS = 30L, - PROMPTSTATUS_LOW = 31L, - SOFTKEYBAR_APPLICATION_MANAGER = 100L, - SOFTKEYBAR_MEDIA_MANAGER = 50L -} group_priority_t; - -/* Session Features that can be invoked TBD should come from JNI */ -#define FEATURE_NONE 0 -#define FEATURE_VOLUME_CTRL 1 -#define FEATURE_PRO_BASE 0 - -/* Call Priority TBD should come from JNI */ -#define CC_CALL_PRIORITY_NORMAL 0 -#define CC_CALL_PRIORITY_URGENT 1 - -/* Session Commands TBD should come from JNI */ -typedef enum { - SESSION_REALIZE = 1, - SESSION_PREFETCH, - SESSION_START, - SESSION_STOP, - SESSION_DEALLOCATE, - SESSION_CLOSE, - SESSION_ALLOCATE -} group_session_t; - -/* - * CC Provider specific constants. - * These do not come from JNI Files - */ - -#include "phone_types.h" - -#define CC_ALL_LINES 255 -#define CC_SESSION_INVALID 0x01FFFFFF -#define CC_MAX_GCID CC_GCID_LEN - -/* 1-9 * # A B C D are number 1 thru 16 */ -#define BKSP_KEY 90 - -#ifdef __CC_CAUSE_STRINGS__ -static const char *cc_cause_names[] = { - "OK", - "ERR", - "UNASSIGNED_NUM", - "NO_RESOURCE", - "NO_ROUTE", - "NORMAL", - "BUSY", - "NO_USER_RESP", - "NO_USER_ANS", - "REJECT", - "INVALID_NUMBER", - "FACILITY_REJECTED", - "CALL_ID_IN_USE", - "XFER_LOCAL", - "XFER_REMOTE", - "XFER_BY_REMOTE", - "XFER_CONFERENCE", - "CONGESTION", - "ANONYMOUS", - "REDIRECT", - "PAYLOAD_MISMATCH", - "CONF", - "REPLACE", - "NO_REPLACE_CALL", - "NO_RESUME", - "NO_MEDIA", - "REQUEST_PENDING", - "INVALID_PARTICIPANT", - "NO_CONF_BRIDGE", - "MAX_PARTICIPANT", - "KEY_NOT_ACTIVE", - "TEMP_NOT_AVAILABLE", - "REMOTE_SERVER_ERROR", - "BARGE", - "CBARGE", - "NOT_FOUND", - "SECURITY_FAILURE", - "MONITOR", - "UI_STATE_BUSY", - "SIP_CAUSE_ANSWERED_ELSEWHERE", - "RETRIEVED", - "FORWARDED", - "ABANDONED", - "XFER_LOCAL_WITH_DIALSTRING", - "CAC_BW_OK", - "ONHOOK_FEAT_COMP", - "RESP_TIMEOUT", - "SERV_ERR_UNAVAIL", - "REMOTE_DISCONN_REQ_PLAYTONE", - "OUT_OF_MEM", - "VALUE_NOT_FOUND", - "BAD_ICE_ATTRIBUTE", - "DTLS_ATTRIBUTE_ERROR", - "DTLS_DIGEST_ALGORITHM_EMPTY", - "DTLS_DIGEST_ALGORITHM_TOO_LONG", - "DTLS_DIGEST_EMPTY", - "DTLS_DIGEST_TOO_LONG", - "DTLS_FINGERPRINT_PARSE_ERROR", - "DTLS_FINGERPRINT_TOO_LONG", - "INVALID_SDP_POINTER", - "NO_AUDIO", - "NO_DTLS_FINGERPRINT", - "MISSING_ICE_ATTRIBUTES", - "NO_MEDIA_CAPABILITY", - "NO_M_LINE", - "NO_PEERCONNECTION", - "NO_SDP", - "NULL_POINTER", - "SDP_CREATE_FAILED", - "SDP_ENCODE_FAILED", - "SDP_PARSE_FAILED", - "SETTING_ICE_SESSION_PARAMETERS_FAILED", - "MAX_CAUSE" -}; -#endif //__CC_CAUSE_STRINGS__ - -#define MAX_SOFT_KEYS 16 - - -// eventually these should come from the Java side -typedef enum { - SESSION_MGMT_APPLY_CONFIG, - SESSION_MGMT_SET_TIME, - SESSION_MGMT_GET_PHRASE_TEXT, - SESSION_MGMT_SET_UNREG_REASON, - SESSION_MGMT_GET_UNREG_REASON, - SESSION_MGMT_UPDATE_KPMLCONFIG, - SESSION_MGMT_GET_AUDIO_DEVICE_STATUS, - SESSION_MGMT_CHECK_SPEAKER_HEADSET_MODE, - SESSION_MGMT_LINE_HAS_MWI_ACTIVE, - SESSION_MGMT_EXECUTE_URI -} session_mgmt_func_e; - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h b/media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h deleted file mode 100755 index 48b0dab915e..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h +++ /dev/null @@ -1,437 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSIONTYPES_H_ -#define _SESSIONTYPES_H_ - -#if defined(__cplusplus) && __cplusplus >= 201103L -typedef struct Timecard Timecard; -#else -#include "timecard.h" -#endif - -#include "string_lib.h" -#include "sessionConstants.h" -#include "ccsip_pmh.h" -#include "cc_constants.h" -#include "sip_ccm_transport.h" -#include "plat_api.h" - -/*********************** SESSION ID *****************/ -typedef unsigned int session_id_t ; - -typedef struct { - unsigned int reason; - string_t reason_info; -} ccSessionProvider_cmd_t; - -typedef struct { - string_t sis_ver_name ; //could be "cme" now. - unsigned int sis_ver_major; - unsigned int sis_ver_minor; - unsigned int sis_ver_addtnl; -}sis_ver; - -typedef struct { - unsigned int cause; - unsigned int mode; - sis_ver sis_ver_info; -} ccProvider_state_t; - -typedef struct { - line_t line_id; - string_t dial; -} ccSession_create_param_t; - -typedef struct { - string_t info; - string_t info1; - unsigned int state; - cc_jsep_action_t action; - cc_media_stream_id_t stream_id; - cc_media_track_id_t track_id; - cc_media_type_t media_type; - cc_level_t level; - cc_media_options_t * options; - Timecard * timecard; -} ccSession_feature_t; - -typedef struct { - int state; - int fsm_state; - int attr; - int inst; - line_t line_id; - int cause; - string_t reason_text; - string_t sdp; - string_t extra; - unsigned int media_stream_id; - unsigned int media_stream_track_id; - Timecard * timecard; -} cc_call_state_data_t; -/* CALL_SESSION_CREATED shall use the call_state as data*/ - -typedef struct -{ - string_t cldNum; - string_t cldName; -} cc_placed_call_info_t; - -typedef struct -{ - string_t clgName; - string_t clgNumber; - string_t altClgNumber; - boolean dispClgNumber; - string_t cldName; - string_t cldNumber; - boolean dispCldNumber; - string_t origCalledName; - string_t origCalledNumber; - string_t lastRedirectingName; - string_t lastRedirectingNumber; - unsigned short call_type; - unsigned short instance_id; - int security; - int policy; -} cc_callinfo_t; - -typedef struct { - string_t featSet; - int featMask[MAX_SOFT_KEYS]; -} cc_featurekey_set_t; - -typedef struct { - cc_boolean start; - vcm_ring_mode_t mode; - cc_boolean once; -} cc_ringer_state_t; - -/** - * Define call status to carry over timeout/priority that might be sent from CUCM. - * Note: if the values of timeout and priority are zero, then 2 second is the - * derfault value for the timeout. It's mostly the application based on UI - * design. - */ -typedef struct { - string_t status; - int timeout; - int priority; -} cc_call_status_t; - -typedef struct -{ - union { - cc_call_state_data_t state_data; - cc_placed_call_info_t plcd_info; - cc_callinfo_t call_info; - cc_call_status_t status; - char gcid[CC_MAX_GCID]; - int action; - int security; - cc_featurekey_set_t feat_set; - unsigned int target_sess_id; - unsigned int callref; - string_t recv_info_list; - cc_ringer_state_t ringer; - } data; -} ccSession_update_t; - -typedef struct { - line_t line; - unsigned int info; -} cc_line_data_t; - -typedef struct { - int state; - int info; -} cc_feature_state_t; - -typedef struct { - cc_blf_state_t state; - int request_id; - int app_id; -} cc_feature_blf_state_t; - -typedef struct { - int timeout; - boolean notifyProgress; - char priority; - string_t prompt; -} cc_notification_data_t; - -typedef struct { - line_t line; - unsigned char button; - string_t speed; - string_t label; -} cc_label_n_speed_t; - -typedef struct { - string_t cfg_ver; - string_t dp_ver; - string_t softkey_ver; -} cc_cfg_version_t; - -typedef struct { - line_t line; - boolean isFwd; - boolean isLocal; - string_t cfa_num; -} cc_cfwd_status_t; - -typedef struct { - string_t addr; - int status; -} cc_ccm_conn_t; - -typedef struct { - line_t line; - boolean status; - int type; - int newCount; - int oldCount; - int hpNewCount; - int hpOldCount; -} cc_mwi_status_t; - -typedef struct { - union { - cc_line_data_t line_info; // For line specific features - cc_feature_state_t state_data; // For device specific feature - cc_feature_blf_state_t blf_data; // For blf state updates. - cc_notification_data_t notification; - cc_label_n_speed_t cfg_lbl_n_spd; - cc_cfwd_status_t cfwd; // For CFWD ALL feature - cc_ccm_conn_t ccm_conn; - cc_mwi_status_t mwi_status; - unsigned int reset_type; - cc_cfg_version_t cfg_ver_data; - } data; -} ccFeature_update_t; - -typedef struct { - int data; -} ccSessionCmd_t; - -/*********************** STREAM SESSION TYPES *****************/ - -typedef struct { - unsigned int reason; -} scSessionProvider_cmd_t; - -typedef struct { - unsigned int mode; -} scSession_state_t; - -typedef struct { - line_t line_id; -} scSession_create_param_t; - -typedef struct { - string_t info; -} scSession_feature_t; - -typedef struct { - string_t info; -} scProvider_state_t; - -typedef struct { - int type; - int mcap_id; - int group_id; - int stream_id; - int call_id; - int direction; - int ref_count; - int session_handle;//session handle for ms rtp session -} rtp_session_info; - -typedef struct { - int refcount; -} rtp_session_update; - -typedef struct { - union { - int state; - rtp_session_info rtp_info; - rtp_session_update rtp_update; - } data; -} scSession_update_t; - -typedef struct { - string_t info; -} scFeature_update_t; - -typedef struct { - string_t info; -} scSessionCmd_t; - -typedef struct { - int id; - int data; -} rcFeature_update_t; - -/********************** SESSION TYPES ****************************/ - - -typedef struct { - unsigned int sessionType; - unsigned int cmd; - union { - ccSessionProvider_cmd_t ccData; - scSessionProvider_cmd_t scData; - } cmdData; -} sessionProvider_cmd_t; - -typedef struct { - unsigned int sessionType; - unsigned int state; - union { - ccProvider_state_t ccData; - scProvider_state_t scData; - } stateData; -} provider_state_t; - -typedef struct { - unsigned int sessionType; - string_t uri; - union { - ccSession_create_param_t ccData; - scSession_create_param_t scData; - } createData; -} session_create_param_t; - -typedef struct { - unsigned int session_id; - unsigned int featureID; - union { - ccSession_feature_t ccData; - scSession_feature_t scData; - } featData; -} session_feature_t; - -typedef struct { - unsigned int sessionID; - unsigned int eventID; - unsigned int sessType; - union { - ccSession_update_t ccSessionUpd; - scSession_update_t scSessionUpd; - } update; -}session_update_t; - -typedef struct { - unsigned int sessID; - unsigned int cmd; - union { - ccSessionCmd_t ccCmd; - scSessionCmd_t scCmd; - } cmdData; -}sessionCmd_t; - - -typedef struct { - unsigned int sessionType; - unsigned int featureID; - union { - ccFeature_update_t ccFeatUpd; - scFeature_update_t scFeatUpd; - rcFeature_update_t rcFeatUpd; - } update; -}feature_update_t; - - -typedef struct { - string_t config_version_stamp; - string_t dialplan_version_stamp; - string_t fcp_version_stamp; - string_t cucm_result; - string_t load_id; - string_t inactive_load_id; - string_t load_server; - string_t log_server; - boolean ppid; -} session_mgmt_config_t; - -typedef struct { - int result; -} session_mgmt_apply_config_result_t; - -typedef struct { - long gmt_time; -} session_mgmt_time_t; - -typedef struct { - int ret_val; - int ndx; - char *outstr; - uint32_t len; -} session_mgmt_phrase_text_t; - -typedef struct { - int unreg_reason; -} session_mgmt_unreg_reason_t; - -typedef struct { - int kpml_val; -} session_mgmt_kpmlconfig_t; - -typedef struct { - int enabled; - plat_audio_device_t device_type; -} session_mgmt_audio_device_status_t; - -typedef struct { - boolean enabled; -} session_mgmt_speaker_headset_mode_t; - -typedef struct { - boolean ret_val; - line_t line; -} session_mgmt_line_mwi_active_t; - -typedef struct { - string_t uri; -} session_mgmt_uri_t; - -typedef struct { - session_mgmt_func_e func_id; - union { - session_mgmt_config_t config; - session_mgmt_apply_config_result_t apply_config_result; - session_mgmt_time_t time; - session_mgmt_phrase_text_t phrase_text; - session_mgmt_unreg_reason_t unreg_reason; - session_mgmt_kpmlconfig_t kpmlconfig; - session_mgmt_audio_device_status_t audio_device_status; - session_mgmt_speaker_headset_mode_t speaker_headset_mode; - session_mgmt_line_mwi_active_t line_mwi_active; - session_mgmt_uri_t uri; - } data; -} session_mgmt_t; - - -typedef struct { - string_t info_package; - string_t content_type; - string_t message_body; -} info_generic_raw_t; - -typedef struct { - unsigned int sessionID; - info_generic_raw_t generic_raw; -} session_send_info_t; - -typedef struct { - unsigned int sessionID; - int packageID; - union { - info_generic_raw_t generic_raw; - } info; -} session_rcvd_info_t; - -#endif - diff --git a/media/webrtc/signaling/src/sipcc/core/includes/sessuri.h b/media/webrtc/signaling/src/sipcc/core/includes/sessuri.h deleted file mode 100644 index 8c5ffbf55a5..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/sessuri.h +++ /dev/null @@ -1,171 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSURI_H_ -#define _SESSURI_H_ - -#define MAX_LEN_SCHEME_INFO 256 -#define MAX_STR_LEN_PARAM_TYPE 64 -#define MAX_STR_LEN_PARAM_VAL 64 - -/* - * Scheme names - */ -#define SCHEME_SIP "sip" -#define SCHEME_FILE "file" -#define SCHEME_RTP "rtp" -#define SCHEME_RTSP "rtsp" -#define SCHEME_CAPTURE "capture" - -/** - * - * Different URI types. - * - */ -typedef enum { - SCHEME_NONE=0, - SIP_URI, - FILE_URI, - CAPTURE_URI, - RTP_URI, - RTSP_URI -} scheme_e; - -/** - * parameter tags/names - * - */ - -#define LINE_TAG "line" - -/** - * Definitions for file player session - */ -#define CADENCE_TAG "cadence" -#define MEDIA_TYPE_TAG "media_type" -#define LOOP_COUNT_TAG "loop_count" -#define PRIORITY_TAG "priority" -#define FILEPTYPE_TAG "type" - -/** - * Definitions for raw rtp session - */ -#define DIRECTION_TAG "direction" -#define MULTICAST_TAG "mcast" -#define PAYLOADTYPE_TAG "payloadtype" -#define FRAMESIZE_TAG "framesize" -#define VADENABLE_TAG "vad" -#define PRECEDENCE_TAG "precedence" -#define MIXINGMODE_TAG "mode" -#define MIXINGPARTY_TAG "party" -#define CHANNELTYPE_TAG "channeltype" -#define LOCALADDRESS_TAG "localaddress" -#define LOCALPORT_TAG "localport" -#define ALGORITHM_TAG "algorithm" - -/** - * Param types required for various URIs. - * - */ -typedef enum { - LINE_PARAM=0, - MEDIA_TYPE_PARAM, - CADENCE_PARAM, - LOOP_COUNT_PARAM, - PRIORITY_PARAM, - MAX_QUERY_PARAM, - DIRECTION_PARAM, - MULTICAST_PARAM, - PAYLOADTYPE_PARAM, - FRAMESIZE_PARAM, - VADENABLE_PARAM, - PRECEDENCE_PARAM, - MIXINGMODE_PARAM, - MIXINGPARTY_PARAM, - CHANNELTYPE_PARAM, - LOCALADDRESS_PARAM, - LOCALPORT_PARAM, - ALGORITHM_PARAM, - FILETYPE_PARAM -} param_e; - -typedef enum { - MEDIA_TYPE_AUDIO, - MEDIA_TYPE_VIDEO, - MEDIA_TYPE_AUDIO_VIDEO, -} media_type_e; - -/** - * params related to call sessions. - * - */ -typedef struct { - int line_id; - media_type_e media_type; -} call_session_param_t; - -/** - * params related to capture sessions. - * - */ -typedef struct { - media_type_e media_type; -} capture_session_param_t; - -/** - * - * params related file sessions - */ -typedef struct { - int type; - int loop_count; - int cadence; - int priority; -} file_session_param_t; - -typedef struct { - int direction; - int multicast; - int payloadtype; - int framesize; - int vadenable; - int precedence; - int mixingmode; - int mixingparty; - int channeltype; - int localaddress; - int localport; - int algorithm; -} raw_rtp_session_param_t; - -/* - * generic param type - */ -typedef union params { - call_session_param_t call_session_param; - file_session_param_t file_session_param; - raw_rtp_session_param_t raw_session_param; - capture_session_param_t capture_session_param; -} param_t; - - -/* - * URI information. This is output of the Parser. - * - */ -typedef struct uri_s { - scheme_e scheme; - char scheme_specific[MAX_LEN_SCHEME_INFO]; - union - { - call_session_param_t call_session_param; - file_session_param_t file_session_param; - raw_rtp_session_param_t raw_session_param; - }param; - -} uri_t; - -int parse_uri(const char *uri, uri_t *uri_info); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/singly_link_list.h b/media/webrtc/signaling/src/sipcc/core/includes/singly_link_list.h deleted file mode 100644 index a0046abc6d7..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/singly_link_list.h +++ /dev/null @@ -1,117 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SINGLY_LINK_LIST_H -#define _SINGLY_LINK_LIST_H - -typedef enum { - SLL_MATCH_FOUND, - SLL_MATCH_NOT_FOUND -} sll_match_e; - -/* - * type definition for find function pointer. The find function takes two arguments: - * 1. find_by_p - pointer to the key - * 2. data_p - pointer to the linked list node data. - */ -typedef sll_match_e(*sll_find_callback_t)(void *find_by_p, void *data_p); - -typedef void *sll_handle_t; - -typedef enum { - SLL_RET_SUCCESS, - SLL_RET_INVALID_ARGS, - SLL_RET_MALLOC_FAILURE, - SLL_RET_NODE_NOT_FOUND, - SLL_RET_LIST_NOT_EMPTY, - SLL_RET_OTHER_FAILURE -} sll_return_e; - -/* - * sll_create(): creates a signly linked list control block and initializes it. - * Applications shall call this first before performing any singly - * linked list primitives, such as append, remove, find or destroy. - * - * Parameters: find_fp - function pointer which will be used to find the matching node. - * - * Returns: list handle or NULL if it can not create the list. - */ -extern sll_handle_t sll_create(sll_find_callback_t find_fp); - -/* - * sll_destroy(): if the list is empty, it frees the list. - * It is the responsibility of the applications to empty - * the list before destroying the list. - * - * Parameters: list_handle - handle to the list. - * - * Returns: SLL_RET_SUCCESS if it successfully destroys. - * SLL_RET_INVALID_ARGS if the arguments are invalid. - * SLL_RET_LIST_NOT_EMPTY if the list is not empty. - */ -extern sll_return_e sll_destroy(sll_handle_t list_handle); - -/* - * sll_append(): creates a list node and appends it to the list. - * Applications are responsible for memory management of the - * data that the node will point to. - * - * Parameters: list_handle - handle to the list. - * data_p - pointer to the data that the list node will point to. - * - * Returns: SLL_RET_SUCCESS if it successfully appends. - * SLL_RET_INVALID_ARGS if the arguments are invalid. - * SLL_RET_MALLOC_FAILURE if memory allocation fails. - */ -extern sll_return_e sll_append(sll_handle_t list_handle, void *data_p); - -/* - * sll_remove(): removes the node from the list and frees the node. - * Applications are responsible for memory management of the - * data that the node points to. - * - * Parameters: list_handle - handle to the list. - * data_p - pointer to the data that the list node points to. - * - * Returns: SLL_RET_SUCCESS if it successfully removes. - * SLL_RET_INVALID_ARGS if the arguments are invalid. - * SLL_RET_NODE_NOT_FOUND if the node is not found in the list. - */ -extern sll_return_e sll_remove(sll_handle_t list_handle, void *data_p); - -/* - * sll_find(): finds the matching node data using find_fp function. - * - * Parameters: list_handle - handle to the list. - * find_by_p - pointer to the opaque data that will be used by find_fp function. - * - * Returns: pointer to the data or NULL if it can not find. - */ -extern void *sll_find(sll_handle_t list_handle, void *find_by_p); - -/* - * sll_next(): returns pointer to the data in the next node to the node holding data_p. - * if data_p is NULL, then returns pointer to the data in the first node. - * Applications can use this primitive to walk through the list. Typically, - * it can be used to remove the individual nodes and to destroy the list - * before shutting down/resetting the application. - * - * Parameters: list_handle - handle to the list. - * data_p - pointer to the data that the list node points to. - * - * Returns: pointer to the data or NULL if it can not find. - */ -extern void *sll_next(sll_handle_t list_handle, void *data_p); - -/* - * sll_count(): returns the number of elements in the list. - * count of the linked list. - * - * Parameters: list_handle - handle to the list. - * - * Returns: returns the number of elements in the list. - */ -extern unsigned int sll_count(sll_handle_t list_handle); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/sip_socket_api.h b/media/webrtc/signaling/src/sipcc/core/includes/sip_socket_api.h deleted file mode 100755 index 2969d7d8d0f..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/sip_socket_api.h +++ /dev/null @@ -1,80 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_SOCKET_API_H__ -#define __SIP_SOCKET_API_H__ - -#include "cpr.h" -#include "cpr_socket.h" - -/** - * sipSocketSend - * - * @brief The sipSocketSend() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the send. - * - * - */ -ssize_t -sipSocketSend (cpr_socket_t soc, - CONST void *buf, - size_t len, - int32_t flags, - boolean secure); - -/** - * sipSocketRecv - * - * @brief The sipSocketRecv() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the recv. - */ -ssize_t -sipSocketRecv (cpr_socket_t soc, - void * RESTRICT buf, - size_t len, - int32_t flags, - boolean secure); - -/** - * sipSocketClose - * - * @brief The sipSocketClose() function is a wrapper used by the sipstack to - * close a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc - The socket that needs to be destroyed - * - * @return CPR_SUCCESS on success otherwise, CPR_FAILURE. cpr_errno needs to be set in this case. - * - * @note The possible error values this function should return are - * @li [CPR_EBADF] socket is not a valid socket descriptor. - */ -cpr_status_e -sipSocketClose (cpr_socket_t soc, - boolean secure); -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/sntp.h b/media/webrtc/signaling/src/sipcc/core/includes/sntp.h deleted file mode 100644 index 93f53ea147c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/sntp.h +++ /dev/null @@ -1,92 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef SNTP_H -#define SNTP_H - -#include -#include -#include -#include - -#include -// Begin system specific includes -//#include -#include -#include -#include -#include -#include -#include -// End system specific includes - -#define MAX_IPADDR_STR_LEN 48 - -#define NTP_UTC_OFFSET (2208963600) -#define PORT_NTP (123) -#define MULTICAST_ADDR_NTP (0xE0000101L) -#define BROADCAST_ADDR (0xFFFFFFFF) -#define TIMEPORT (37) - -typedef enum { unicast, multicast, anycast, directed_broadcast } SNTP_Mode; - -typedef struct { - unsigned int precision:8; - unsigned int poll:8; - unsigned int stratum:8; - unsigned int mode:3; - unsigned int versionNumber:3; - unsigned int leapIndicator:2; -} NTPHeader_s; - -typedef struct { - union { - NTPHeader_s header; - unsigned long rawheader; - } u; - unsigned long rootDelay; - unsigned long rootDispersion; - unsigned long referenceIdentifier; - unsigned long referenceTimestamp[2]; - unsigned long originateTimestamp[2]; - unsigned long receiveTimestamp[2]; - unsigned long transmitTimestamp[2]; - // Removed the following fields since they are version 4 - // specific. - //unsigned long keyIdentifier; - //unsigned long messageDigest[4]; -} NTPStruct_s; - -typedef struct { - Socket *server_socket; // Socket to SNTP server - Socket *lsocket; // Local listening socket - Socket *bsocket; // Broadcast listening socket - Socket *msocket; // Multicast listening socket - char address[MAX_IPADDR_STR_LEN]; - unsigned long sntp_server_addr; - SNTP_Mode mode; - - unsigned long destinationTimestamp[2]; - long roundtripDelay[2]; - long timeOffset[2]; - long time_zone; -} SNTP_State; - -typedef union { - unsigned long NTPDataBuffer[17]; - NTPStruct_s NTPData; -} NTPPacket_u; - -void SNTPInit(void); -void SNTPStop(void); -int SNTPSend(void); -void SNTPCallback(irx_tmr_buf *pTmrBlk); -int SNTPRecv(SysHdr *pSm); -long NTPSemanticCheck(const NTPStruct_s *ntpdata); -void SNTPSecondUpdate(void); -void printNTPStruct(const NTPStruct_s *ntpdata, const SNTP_State *state); -long sntp_get_rand_seed(void); -void SNTPDebugInit(void); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/string_lib.h b/media/webrtc/signaling/src/sipcc/core/includes/string_lib.h deleted file mode 100755 index 1efb231c7d0..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/string_lib.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _STRING_LIB_INCLUDED_H /* allows multiple inclusion */ -#define _STRING_LIB_INCLUDED_H - -#include "cpr_types.h" - -#define LEN_UNKNOWN -1 - -typedef struct string_block_t_ -{ - struct string_block_t_ *next; - uint16_t refcount; - uint16_t length; - const char *fname; - int line; - short signature; - char data[1]; -} string_block_t; - - -/* - * Prototypes for functions - */ - -string_t strlib_malloc(const char *str, int length, const char *fname, - int line); -string_t strlib_copy(string_t str); -string_t strlib_update(string_t destination, const char *source, - const char *fname, int line); -string_t strlib_append(string_t str, const char *toappend_str, - const char *fname, int line); -string_t strlib_prepend(string_t str, const char *toprepend_str, - const char *fname, int line); -void strlib_free(string_t str); -char *strlib_open(string_t str, int length, const char *fname, int line); -string_t strlib_close(char *str); -string_t strlib_printf(const char *format, ...); -string_t strlib_empty(void); -void strlib_debug_init(void); -long strlib_mem_used(void); -int strlib_test_memory_is_string(void *mem); -void strlib_init (void); - -#ifndef __STRINGLIB_INTERNAL__ -#define strlib_malloc(x,y) strlib_malloc(x,y,__FILE__,__LINE__) -#define strlib_update(x,y) strlib_update(x,y,__FILE__,__LINE__) -#define strlib_append(x,y) strlib_append(x,y,__FILE__,__LINE__) -#define strlib_prepend(x,y) strlib_prepend(x,y,__FILE__,__LINE__) -#define strlib_open(x,y) strlib_open(x,y,__FILE__,__LINE__) -#endif - - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/subapi.h b/media/webrtc/signaling/src/sipcc/core/includes/subapi.h deleted file mode 100755 index 367842732a4..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/subapi.h +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SUBAPI_H_ -#define _SUBAPI_H_ - -#include "ccsip_subsmanager.h" - -cc_rcs_t sub_int_subnot_register(cc_srcs_t src_id, cc_srcs_t dst_id, - cc_subscriptions_t evt_pkg, void *callback_fun, - cc_srcs_t dest_task, int msg_id, - void *term_callback, int term_msg_id, - long min_duration, long max_duration); - -cc_rcs_t sub_int_subscribe(sipspi_msg_t *msg_p); - -cc_rcs_t sub_int_subscribe_ack(cc_srcs_t src_id, cc_srcs_t dst_id, - sub_id_t sub_id, uint16_t response_code, - int duration); - -cc_rcs_t sub_int_notify(cc_srcs_t src_id, cc_srcs_t dst_id, sub_id_t sub_id, - ccsipNotifyResultCallbackFn_t notifyResultCallback, - int subsNotResCallbackMsgID, - ccsip_event_data_t *eventData, - subscriptionState subState); - -cc_rcs_t sub_int_notify_ack(sub_id_t sub_id, uint16_t response_code, - uint32_t cseq); - -cc_rcs_t sub_int_subscribe_term(sub_id_t sub_id, boolean immediate, - int request_id, - cc_subscriptions_t event_package); - -cc_rcs_t sip_send_message(ccsip_sub_not_data_t *msg_data, - cc_srcs_t dest_task, int msg_id); - -cc_rcs_t app_send_message(void *msg_data, int msg_len, cc_srcs_t dest_id, - int msg_id); -extern cc_rcs_t -sub_send_msg (cprBuffer_t buf, uint32_t cmd, uint16_t len, cc_srcs_t dst_id); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/task.h b/media/webrtc/signaling/src/sipcc/core/includes/task.h deleted file mode 100755 index 6cbc937603b..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/task.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TASK_H -#define TASK_H - -/* - *--------------------DEPRECATED FILE------------------------------- - * - * As part of Skittles project this file is deprecated. - * DO NOT add anything to this file. - * The contents of this file are really platform specific and - * have moved to phntask.h under - * src-bcm-tnp/h/phntask.h for CNU phones. - * src-arm-79xx/phntask.h for IRX phones. - * - * If you are doing SYNC merges _DO_ _NOT_ merge anything from parent - * This file is kept here because it comes from parent/grand parent branches - * and will not be removed from clearcase till Skittles collapses. - * [The fAQ on cc tools contains details of why ] - * - * If you have questions send email to skittles-dev - *--------------------------------------------------------------- - */ -#define SIP_TMR 0xffff //TODO CPR a temporary bogus number - -#endif /* TASK_H */ diff --git a/media/webrtc/signaling/src/sipcc/core/includes/time2.h b/media/webrtc/signaling/src/sipcc/core/includes/time2.h deleted file mode 100644 index cc02ce7dbe5..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/time2.h +++ /dev/null @@ -1,192 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TIME2_H -#define TIME2_H - -#include -#include -#include -#include -#include -#include - -// System specific includes - -// End system specific - -#define EPOCH_YEAR (1900) -#define EPOCH_SECONDS (0x80000000) -#define DAYS_PER_LEAP_YEAR (366) -#define DAYS_PER_YEAR (365) -#define DAYS_PER_WEEK (7) -#define LEAP_FOUR_CENTURY (400) -#define LEAP_CENTURY (100) -#define LEAP_YEAR (4) -// Calculated with 365.2425 days/year for the Gregorian calendar -#define SECONDS_PER_GREGORIAN_YEAR (31556952) -#define SECONDS_PER_YEAR (31536000) -#define SECONDS_PER_LEAP_YEAR (31622400) -#define SECONDS_PER_DAY (86400) -#define SECONDS_PER_HOUR (3600) -#define SECONDS_PER_MINUTE (60) -#define MINUTES_PER_HOUR (60) -#define HOURS_PER_DAY (24) -#define MAX_WEEKS_PER_MONTH (6) -#define MONTHS_PER_YEAR (12) - -#define STARTING_TIME (101 * SECONDS_PER_GREGORIAN_YEAR) - -//If 30 minutes have elapsed, clear time display -#define SNTP_MAX_TIME_SINCE_UPDATE 30*60 - -typedef enum { - SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY -} DAYS_NAMES_TO_NUMBER; - -typedef enum { - JANUARY = 0, - FEBRUARY, - MARCH, - APRIL, - MAY, - JUNE, - JULY, - AUGUST, - SEPTEMBER, - OCTOBER, - NOVEMBER, - DECEMBER -} MONTH_NAMES_TO_NUMBER; - -typedef struct { - time_t time; - unsigned short millitm; - short timezone; - short dstflag; -} timeb; - -typedef struct { - // Standard Gregorian calendar date - unsigned long year; // Range >= EPOCH_YEAR - unsigned long month; // Range 0-11, use MONTH_NAME_x for text - unsigned long day; // Range 1-31 - - // Standard 24 hour time format - unsigned long hour; // Range 0-23 - unsigned long minute; // Range 0-59 - unsigned long seconds; // Range 0-59 - - // Specifics about a year and the current date - unsigned long day_of_year; // Range 0-365 - unsigned long day_of_january_first; // Range 0-6, use DAY_NAME_x for text - unsigned long day_of_week; // Range 0-6, use DAY_NAME_x for text - unsigned long week_of_year; // Range 1-53 - - // Variables that are associated with leap years and calculations - unsigned long leap_years; // Non negative integer - unsigned long leap_flag; // Range 0-1, boolean - - // Time zone specifics set by user - long time_zone; // Timezone offset in seconds - unsigned long daylight_saving_offset; // Number of seconds to add (adjust) when DST starts - // e.g. daylight_saving_offset = 3600; // 1 hour - // when DST starts the code will add 1 hour to the GMT time and - // when DST stops it will stop adding 1 hour - unsigned long daylight_saving_start_month; // Range 0-11, use MONTH_NAME_x for text - unsigned long daylight_saving_start_day; // Range 1-31, if set to 0, only then will week of month is used - unsigned long daylight_saving_start_day_of_week; // Range 0-6, use DAY_NAME_x for text - unsigned long daylight_saving_start_week_of_month;// Range 0-6, First, second, etc. DAY_NAME of the month, zero denotes last week in month, e.g. day_of_week = 0, week_of_month = 1 => First Sunday of month - unsigned long daylight_saving_start_time; // Range 0-86399, number of seconds past midnight - unsigned long daylight_saving_stop_month; // Range 0-11, use MONTH_NAME_x for text - unsigned long daylight_saving_stop_day; // Range 1-31, if set to 0, only then will week of month is used - unsigned long daylight_saving_stop_day_of_week; // Range 0-6, use DAY_NAME_x for text - unsigned long daylight_saving_stop_week_of_month; // Range 0-6, First, second, etc. DAY_NAME of the month, zero denotes last week in month, e.g. day_of_week = 0, week_of_month = 1 => First Sunday of month - unsigned long daylight_saving_stop_time; // Range 0-86399, number of seconds past midnight - unsigned long daylight_saving_year_calc; // Non negative integer, non 0 means daylight saving start and stop second is calculated for given year - unsigned long daylight_saving_auto_adjust; // Range 0-1, boolean - - // Time zone specifics set by make_date - unsigned long is_daylight_saving; // Range 0-1, boolean - unsigned long daylight_saving_start_second; // Second in the year that daylight saving starts - unsigned long daylight_saving_stop_second; // Second in the year that daylight saving stops -} time2_s; - -typedef struct { - const char *TZ_NAME; - const long offset; -} TZ_STRUCT; - -// Time date externs -extern const char *const MONTH_NAMES_LONG[]; -extern const char *const MONTH_NAMES_SHORT[]; -extern const unsigned long DAYS_IN_MONTH[]; -extern const char *const DAY_NAMES_LONG[]; -extern const char *const DAY_NAMES_SHORT[]; -extern const char *const DAY_NAMES_ABBREV[]; -extern const TZ_STRUCT TZ_TABLE[]; - -long make_date(unsigned long secondsPastEpoch, time2_s *timeStruct); -const char *get_month_name_long(unsigned long month); -const char *get_month_name_short(unsigned long month); -const char *get_day_name_long(unsigned long day); -const char *get_day_name_short(unsigned long day); -const char *get_day_name_abrrev(unsigned long day); -long get_leap_years(unsigned long year); -unsigned long get_seconds_past_epoch(unsigned long nth, unsigned long day_name, unsigned long month, unsigned long year); -long is_leap_year(unsigned long year); -long range_check_time_struct(time2_s *ts); -unsigned long date_to_seconds(const time2_s *ts); -unsigned long time_to_seconds(const time2_s *ts); -unsigned long date_time_to_seconds(const time2_s *ts); -unsigned long get_local_time(void); -void get_precise_local_time(unsigned long *local_time); -long get_local_timezone(void); -long get_local_dst_active(void); -unsigned long time_to_short_string(const time2_s *ts, char *time_string); -unsigned long gmt_string_to_seconds(char *gmt_string, unsigned long *seconds); -unsigned long seconds_to_gmt_string(unsigned long seconds, char *gmt_string); -unsigned long diff_time(unsigned long t1, unsigned long t2); - -// This function is similar to the strcmp function in the string.h library -// It includes support for handling the NTP most significant bit rollover -// If t1 < t2 cmp_time returns -1 -// If t1 == t2 cmp_time returns 0 -// If t1 > t2 cmp_time returns 1 -long cmp_time(unsigned long t1, unsigned long t2); - -long diff_current_time(unsigned long t1, unsigned long *difference); -long parse_month(char *pString); -long parse_day_of_week(char *pString); -long parse_timezone(char *pString); -long parse_time(char *pString); - -/* - * Formats ulMilliseconds into elasped time in the form of - * HRS:MIN:SEC for less than 24 hours and then - * DAY(S) HRS:MIN:SEC for greater than 24 hours -*/ -void ascTimeDuration(unsigned long ulMilliseconds, char *ptimStr, int length); -void ascFormatDate(time2_s *ts, char * pDateStr, int length); -void ascFormatHrMinTime(time2_s *ts, char * pTimeStr, int length, char bFlashColon); -void FormatDateTime(char * ptimeStr, int length); -void FormatDebugTime(char *timeStr, int length,long ts); -char *GetDateTimeString(void); - -// Called once a second to update the time. Returns true indicating -// a roll-over indicating the display needs updated. -// Once a minute we need to update the time/date display and -// update the minute/hour/day etc. -// -int TimeOfDayUpdate(void); - -// Set the time of day clock -void SetTimeOfDay(time2_s *time); - -// Blank "turn off" the display of time -// called when there is a change to -// the time keeping systems on the phone -void ClearTimeDisplay(void); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/timer.h b/media/webrtc/signaling/src/sipcc/core/includes/timer.h deleted file mode 100755 index eb02e9e63f2..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/timer.h +++ /dev/null @@ -1,49 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MGCP_TIMER_H -#define MGCP_TIMER_H - -#define TIMER_FREE 0x1 /* Indicates timer is free */ -#define TIMER_INITIALIZED 0x2 /* Indicates timer is initialized */ -#define TIMER_ACTIVE 0x4 /* Indicates timer is in list */ - -/* Timer event structure */ -typedef struct timer_struct -{ - unsigned int expiration_time; /* Expiration time */ - int interval; /* Timer period */ - void *parameter1; /* Timer expiration callback param */ - void *parameter2; /* Second timer expiration callback param */ - void (*expiration_callback) - (void *timer, void *parameter1, void *parameter2); /* Expiry handler */ - int flags; /* Debugging flags */ - struct timer_struct *pred; /* List predecessor */ - struct timer_struct *next; /* List successor */ -} timer_struct_type; - -extern unsigned long current_time(void); -extern void timer_event_activate(timer_struct_type *timer); -extern void *timer_event_allocate(void); -extern void timer_event_cancel(timer_struct_type *timer); -extern void timer_event_free(timer_struct_type *timer); -extern void timer_event_initialize(timer_struct_type *timer, - int period, - void (*expiration)(void *timer_event, - void *param1, - void *param2), - void *param1, void *param2); -extern void timer_event_process(void); -extern void timer_event_system_init(void); -extern boolean timer_expired(void); -extern void platform_timer_tick(void); -extern void platform_timer_init(void); - -#ifdef _WIN32 -extern void platform_timer_stop(void); -#endif -extern int timer_ms_to_ticks(int milliseconds); -extern boolean is_timer_active(timer_struct_type *timer); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/tnpphone.h b/media/webrtc/signaling/src/sipcc/core/includes/tnpphone.h deleted file mode 100644 index 80d4d62ac0b..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/tnpphone.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TNPPHONE_H -#define TNPPHONE_H - -#include "phone.h" - - -#ifdef SIP_OS_WINDOWS - - -#ifndef MAX_FILE_NAME -#define MAX_FILE_NAME 256 -#endif - -/* Defined in net_config.h */ -typedef struct -{ - uint8_t fName[MAX_FILE_NAME]; // Name of file being transfered - uint32_t rcvLen; - uint32_t maxSize; // The maximum size of the file to be read - uint8_t *fDest; // The destination address for transfer - uint32_t fHost; // Foreign IP address - uint16_t rtCode; - uint8_t taskId; - irx_lst_blk *pTaskList; -} TftpOpen; // TFTP Request - -#define CFG_PROGRAMMED 0x12300000L -#define CFG_PROGRAM_TFTP 0x12200000L -#define CFG_DHCP_DISABLE 0x00000001L -#define CFG_DHCP_TIMEOUT 0x00000002L -#define CFG_TFTP_TIMEOUT 0x00000004L -#define CFG_TFTP_NTFOUND 0x00000008L -#define CFG_TFTP_ACCESS 0x00000010L -#define CFG_TFTP_ERR 0x00000020L -#define CFG_DNS_ERROR 0x00000040L -#define CFG_DNS_TIMEOUT 0x00000080L -#define CFG_DNS_IP 0x00000100L -#define CFG_VER_ERR 0x00000200L -#define CFG_CKSUM_ERR 0x00000400L -//#define CFG_TFTP_FILE 0x00000800L -#define CFG_DFLT_GWY 0x00001000L -#define CFG_DUP_IP 0x00002000L -#define CFG_PATCHED 0x00004000L -#define CFG_LINK_DOWN 0x00008000L -#define CFG_FIXED_TFTP 0x00010000L -#define CFG_PROG_ERR 0x00020000L -#define CFG_BOOTP 0x00040000L -#define CFG_DHCP_RELEASE 0x00080000L - - -#ifndef ERROR -#define ERROR (-1) -#endif - -#ifndef PHONE_TICK_TO -#define PHONE_TICK_TO 10 -#endif - - -#endif -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/uart.h b/media/webrtc/signaling/src/sipcc/core/includes/uart.h deleted file mode 100755 index 30596cf4eaa..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/uart.h +++ /dev/null @@ -1,119 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UART_H_ -#define _UART_H_ - -#include "cpr_types.h" - - -/* - * Telecaster specific defines - */ -#define SYSCLOCK ((unsigned long)25000000) /* 25 MHZ */ -#define UART_BASE_ADDRESS (UART_16550_REGS *)0xFFFE4000 - -/* - * 16550 register definition - */ -typedef struct { - volatile uint8_t dc; /* RBR/THR */ - volatile uint8_t ier; /* Interrupt Enable Reg */ - volatile uint8_t iir; /* Interrupt ID Reg */ - volatile uint8_t lcr; /* Line Control Reg / FIFO Control Reg */ - volatile uint8_t mcr; /* Modem Control Register */ - volatile uint8_t lsr; /* Line Status Register */ - volatile uint8_t msr; /* Modem Status Register */ - volatile uint8_t scr; /* Scratch Register */ -} UART_16550_REGS; - -/* - * UART register bit symbols - */ -#define UART_IER_MASK 0xF0 -#define IER_RX_IE 0x01 -#define IER_TX_IE 0x02 -#define IER_LS_IE 0x04 -#define IER_MS_IE 0x08 - -#define UART_IIR_RV 0x01 -#define IIR_IPEND 0x01 -#define IIR_MODEM_STAT 0x00 -#define IIR_TX_EMPTY 0x02 -#define IIR_RX_AVAIL 0x04 -#define IIR_RX_LINE_STAT 0x06 -#define IIR_CHAR_TIMOUT 0x0C - -#define UART_FCR_MASK 0x30 -#define FCR_FIFO_EN 0x01 -#define FCR_CLR_RXF 0x02 -#define FCR_CLR_TXF 0x04 -#define FCR_TRIGR_1BYT 0x00 -#define FCR_TRIGR_4BYT 0x40 -#define FCR_TRIGR_8BYT 0x80 -#define FCR_TRIGR_14BYT 0xC0 - -#define LCR_CHR_LEN_5BIT 0x00 -#define LCR_CHR_LEN_6BIT 0x01 -#define LCR_CHR_LEN_7BIT 0x02 -#define LCR_CHR_LEN_8BIT 0x03 -#define LCR_STOP1 0x00 -#define LCR_STOP2 0x04 -#define LCR_PAR_EN 0x08 -#define LCR_PAR_ODD 0x10 -#define LCR_FIX_PAR 0x20 -#define LCR_BRK_CTL 0x40 -#define LCR_DLAB 0x80 - -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 -#define MCR_OUT1 0x04 -#define MCR_OUT2 0x08 -#define MCR_LPBK 0x10 -#define MCR_AUTO_FLW_EN 0x20 - -#define UART_LSR_RV 0x60 -#define LSR_RX_AVAIL 0x01 -#define LSR_OVRUN 0x02 -#define LSR_PAR_ERR 0x04 -#define LSR_FRAM_ERR 0x08 -#define LSR_BRK_INT 0x10 -#define LSR_TX_EMPTY 0x20 -#define LSR_XMITR_EMPTY 0x40 -#define LSR_RX_FIFO_ERR 0x80 - -#define UART_MSR_RV 0x00 -#define MSR_CTS_CHG 0x01 -#define MSR_DSR_CHG 0x02 -#define MSR_TERI 0x04 -#define MSR_CD_CHG 0x08 -#define MSR_CTS_IN 0x10 -#define MSR_DSR_IN 0x20 -#define MSR_RI_IN 0x40 -#define MSR_CD_IN 0x80 - - -#define DATAREADY 0x01 -#define XMITFIFOEMPTY 0x20 - - -#define RXLINESTATUS (3<<1) -#define RXDATAAVAIL (2<<1) -#define CHARTIMEOUT (6<<1) -#define TXEMPTY (1<<1) -#define MODEMSTATUS (0<<1) -#define RXERRORS 0x8E -#define DATAREADY 0x01 -#define XMITFIFOEMPTY 0x20 - - -#define TX_EMPTY 0x01 - -//extern int uart_init(int speed, char *buf, int buf_size); -extern int32_t uart_init(); -extern void uart_flush(int32_t dev); -extern int32_t uart_outc(int8_t c, void *); -extern int32_t uart_outs(int8_t *s, void *); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/uiapi.h b/media/webrtc/signaling/src/sipcc/core/includes/uiapi.h deleted file mode 100644 index 3033689e2f1..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/uiapi.h +++ /dev/null @@ -1,146 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UIAPI_H_ -#define _UIAPI_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "string_lib.h" -#include "vcm.h" -#include "fsm.h" -#include "ccapi.h" - -#include "sessionConstants.h" -typedef enum { - evMinEvent = 0, - evOffHook = OFFHOOK, - evOnHook = ONHOOK, - evRingOut = RINGOUT, - evRingIn = RINGIN, - evProceed = PROCEED, - evConnected = CONNECTED, - evHold = HOLD, - evRemHold = REMHOLD, - evResume = RESUME, - evBusy = BUSY, - evReorder = REORDER, - evConference = CONFERENCE, - evRemInUse = REMINUSE, - evCallPreservation = PRESERVATION, - evHoldRevert = HOLDREVERT, - evWhisper = WHISPER, - evWaitingForDigits = WAITINGFORDIGITS, - evMaxEvent -} call_events; - -#define MWI_STATUS_YES 1 - -/* call operations : dialing, state change and info related */ -void ui_new_call(call_events event, line_t nLine, callid_t nCallID, - int call_attr, uint16_t call_instance_id, boolean dialed_digits); -void ui_set_call_attr(line_t line_id, callid_t call_id, call_attr_t attr); -void ui_call_info(string_t clgName, string_t clgNumber, string_t altClgNumber, boolean dispClgNumber, - string_t cldName, string_t cldNumber, boolean dispCldNumber, - string_t pOrigCalledNameStr, string_t pOrigCalledNumberStr, - string_t pLastRedirectingNameStr, - string_t pLastRedirectingNumberStr, - calltype_t call_type, - line_t line, callid_t call_id, uint16_t call_instance_id, - cc_security_e call_security, cc_policy_e call_policy); -void ui_cc_capability(line_t line_id, callid_t call_id, - string_t recv_info_list); -void ui_info_received(line_t line_id, callid_t call_id, - const char *info_package, const char *content_type, - const char *message_body); -void ui_update_placed_call_info(line_t line, callid_t call_id, string_t cldName, - string_t cldNumber); -void ui_log_disposition( callid_t nCallID, int logDisp); -void ui_call_state(call_events event, line_t nLine, callid_t nCallID, cc_causes_t cause); -void ui_set_local_hold(line_t line, callid_t call_id); -void ui_delete_last_digit(line_t line_id, callid_t call_id); -void ui_update_label_n_speeddial(line_t line, line_t button_no, string_t - speed_dial, string_t label); -void ui_mnc_reached(line_t line, boolean mnc_reached); - -void ui_call_selected(line_t line_id, callid_t call_id, int selected); -void ui_call_in_preservation(line_t line_id, callid_t call_id); -void ui_update_call_security(line_t line, callid_t call_id, - cc_security_e call_security); -void ui_update_conf_invoked(line_t line, callid_t call_id, - boolean invoked); -void ui_terminate_feature(line_t line, callid_t call_id, - callid_t target_call_id); - -void ui_update_gcid(line_t line, callid_t call_id, char *gcid); -void ui_update_callref(line_t line, callid_t call_id, unsigned int callref); - -/* status line related */ -void ui_set_call_status(string_t pString, line_t line, callid_t callID); -char *ui_get_idle_prompt_string(void); -void ui_set_idle_prompt_string(string_t pString, int prompt); -void ui_set_notification(line_t line, callid_t callID, - char *promptString, int timeout, - boolean notifyProgress, char priority); -void ui_clear_notification(); - -/* softkey manipulation */ -void ui_control_feature(line_t line_id, callid_t call_id, int list[], int len, int enable); -void ui_select_feature_key_set(line_t line_id, callid_t call_id, char *set_name, - int sk_list[], int len); -void ui_control_featurekey_bksp(line_t line_id, callid_t call_id, - boolean enable); - -/* speaker */ -void ui_set_speaker_mode(boolean mode); - -/* mwi */ -void ui_set_mwi(line_t line, boolean status, int type, int newCount, int oldCount, int hpNewCount, int hpOldCount); -void ui_change_mwi_lamp(int status); -boolean ui_line_has_mwi_active(line_t line); - -/* call forward */ -void ui_cfwd_status(line_t line, boolean cfa, char *cfa_number, - boolean lcl_fwd); - -/* registration, stack init related */ -void ui_sip_config_done(void); -void ui_set_sip_registration_state(line_t line, boolean registered); -void ui_reg_all_failed(void); - -void ui_keypad_button(char *digitstr, int direction); - -void ui_offhook(line_t line, callid_t call_id); -void ui_dial_call(line_t line, callid_t call_id, char *to, - char *global_call_id); -int ui_dial_digits(line_t line, char *digitstr); -int ui_dial_dtmf(line_t line, char *digitstr); -void ui_answer_call(line_t line, callid_t call_id); -void ui_disconnect_call(line_t line, callid_t call_id); -int ui_xfer_setup(line_t line, callid_t call_id, char *to, - char *global_call_id, boolean media); -void ui_xfer_complete(line_t line, callid_t call_id, callid_t consult_call_id); -int ui_conf_setup(line_t line, callid_t call_id, char *to, - char *global_call_id); -void ui_conf_complete(line_t line, callid_t call_id, callid_t consult_call_id); -int ui_hold_call(line_t line, callid_t call_id); -void ui_hold_retrieve_call(line_t line, callid_t call_id); -void ui_cfwdall_req(unsigned int line); - -/* Test Interface */ -void ui_execute_uri(char *); - -/* Status Message Interface */ -void ui_log_status_msg(char *msg); - -void ui_init_ccm_conn_status(void); -void ui_update_video_avail (line_t line, callid_t call_id, int avail); -void ui_update_video_offered (line_t line, callid_t call_id, int dir); -void ui_call_stop_ringer(line_t line, callid_t call_id); -void ui_call_start_ringer(vcm_ring_mode_t ringMode, short once, line_t line, callid_t call_id); -void ui_BLF_notification (int request_id, cc_blf_state_t blf_state, int app_id); -void ui_update_media_interface_change(line_t line, callid_t call_id, group_call_event_t event); - - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/upgrade.h b/media/webrtc/signaling/src/sipcc/core/includes/upgrade.h deleted file mode 100644 index 96f2bd987ed..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/upgrade.h +++ /dev/null @@ -1,37 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UPGRADE_INCLUDED_H -#define _UPGRADE_INCLUDED_H - -#include "cpr_types.h" -#include "phone.h" - -/* - * Telecaster has these extra 32 bytes of data - * in front of the load header. I have no idea what - * they are for, but having a structure makes it easier - * to deal with this as opposed to adding 0x20 to the - * address. - */ -typedef struct -{ - uint8_t vectors[0x20]; - LoadHdr hdr; -} BigLoadHdr; - -/* - * Prototypes for public functions - */ -void upgrade_bootup_init(void); -int upgrade_done(int tftp_rc); -void upgrade_start(const char *fname); -void upgrade_memcpy(void *dst, const void *src, int len); -int upgrade_check(const char *loadid); -int upgrade_validate_app_image(const BigLoadHdr *load); -int upgrade_validate_dsp_image(const DSPLoadHdr *dsp); -void upgrade_erase_dir_storage(void); -void upgrade_write_dir_storage(char *buffer, char *flash, int size); - -#endif /* _UPGRADE_INCLUDED_H */ diff --git a/media/webrtc/signaling/src/sipcc/core/includes/util_ios_queue.h b/media/webrtc/signaling/src/sipcc/core/includes/util_ios_queue.h deleted file mode 100644 index 98ad646c732..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/util_ios_queue.h +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UTIL_IOS_QUEUE_H -#define _UTIL_IOS_QUEUE_H - -/* - * Define the queue data type and a basic enqueue structure - */ - -typedef struct queuetype_ { - void *qhead; /* head of queue */ - void *qtail; /* tail of queue */ - int count; /* possible count */ - int maximum; /* maximum entries */ -} queuetype; - -typedef queuetype *queue_ptr_t; - -typedef struct nexthelper_ -{ - struct nexthelper_ *next; - unsigned char data[4]; -} queue_node, nexthelper, *node_ptr_t; - -typedef enum get_node_status_ { - GET_NODE_FAIL_EMPTY_LIST, - GET_NODE_FAIL_END_OF_LIST, - GET_NODE_SUCCESS -} get_node_status; - -void queue_init(queuetype *q, int maximum); -void *peekqueuehead(queuetype* q); - -/*Functions used by SIP */ -int queryqueuedepth(queuetype const *q); -boolean checkqueue(queuetype *q, void *e); -void *p_dequeue(queuetype *qptr); -void p_enqueue(queuetype *qptr, void *eaddr); -void p_requeue(queuetype *qptr, void *eaddr); -void p_swapqueue(queuetype *qptr, void *enew, void *eold); -void p_unqueue(queuetype *q, void *e); -void p_unqueuenext(queuetype *q, void **prev); -void enqueue(queuetype *qptr, void *eaddr); -void *dequeue(queuetype *qptr); -void unqueue(queuetype *q, void *e); -void requeue(queuetype *qptr, void *eaddr); -void *remqueue(queuetype *qptr, void *eaddr, void *paddr); -void insqueue(queuetype *qptr, void *eaddr, void *paddr); -boolean queueBLOCK(queuetype *qptr); -boolean validqueue(queuetype *qptr, boolean print_message); - -boolean queue_create_init(queue_ptr_t *queue); -void add_list(queue_ptr_t queue, node_ptr_t node); -get_node_status get_node(queue_ptr_t queue, node_ptr_t *node); -void queue_delete(queue_ptr_t queue); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/util_parse.h b/media/webrtc/signaling/src/sipcc/core/includes/util_parse.h deleted file mode 100644 index e3341124a23..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/util_parse.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UTIL_PARSE_H_ -#define _UTIL_PARSE_H_ - -#include "xml_defs.h" - -XMLToken parse_xml_tokens(char **parseptr, char *value, int maxlen); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/util_string.h b/media/webrtc/signaling/src/sipcc/core/includes/util_string.h deleted file mode 100644 index 04a53d9ecc9..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/util_string.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UTIL_STRING_H_ -#define _UTIL_STRING_H_ - -#include "cpr_types.h" -#include "cpr_socket.h" - -#define EMPTY_STR "" -#define EMPTY_STR_LEN 1 - -boolean is_empty_str(char *str); -void init_empty_str(char *str); - -void ipaddr2dotted(char *addr_str, cpr_ip_addr_t *addr); -uint32_t dotted2ipaddr(const char *addr_str); -int str2ip(const char *str, cpr_ip_addr_t *addr); -void util_ntohl(cpr_ip_addr_t *ip_addr_out, cpr_ip_addr_t *ip_addr_in); -boolean util_compare_ip(cpr_ip_addr_t *ip_add1, cpr_ip_addr_t *ip_addr2); -void util_extract_ip(cpr_ip_addr_t *ip_addr, cpr_sockaddr_storage *from); -uint16_t util_get_port(cpr_sockaddr_storage *sock_storage); -void util_get_ip_using_mode(cpr_ip_addr_t *ip_addr, cpr_ip_mode_e ip_mode, - uint32_t ip4, char *ip6); -boolean util_check_if_ip_valid(cpr_ip_addr_t *ip_addr); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/www.h b/media/webrtc/signaling/src/sipcc/core/includes/www.h deleted file mode 100644 index e5c40b01ead..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/www.h +++ /dev/null @@ -1,25 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _WWW_H_ -#define _WWW_H_ - -#define MAXCHARSPERLINE 400 - -typedef struct { - int soc; - unsigned char buf[MAXCHARSPERLINE]; - unsigned char text[MAXCHARSPERLINE]; - int idx, n, clen, send; -} WWWRBuf; - -extern int Connect2WWW(char *hostName); -extern int Connect2WWWIPPort(unsigned long nIPAddr, unsigned short nPort, - char *hostName); -extern void wwwSend(WWWRBuf *wrb, char *fmt, ...); -extern boolean www_proxy_used(int connection); -extern boolean www_socket_open(int connection); -extern void HTTP_Init_ConnTbl(); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/includes/xml_defs.h b/media/webrtc/signaling/src/sipcc/core/includes/xml_defs.h deleted file mode 100644 index b91558f30ae..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/includes/xml_defs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _XML_DEFS_H_ -#define _XML_DEFS_H_ - -#include "cpr_types.h" - -#define TOK_MAX_LEN (24) - -#define TOK_NONE (0) -#define TOK_PROC (1) -#define TOK_ELEMENT (2) -#define TOK_ATTRIBUTE (3) -#define TOK_CONTENT (4) - -#define XML_START (1199) -#define XML_END (1200) -#define XML_CONTENT (1201) -#define XML_ALL_CONTENT (1202) - -typedef struct XMLTokenStruc { - const int8_t strTok[TOK_MAX_LEN]; - int16_t TokType; - void *pData; // This may be another XMLTable, - // or an array of valid attribute values. -} XMLTokenStruc; - -typedef void (*XmlFunc)(int16_t, void *); - -typedef struct XMLTableStruc { - void (*xml_func)( int16_t TokID, void *pData ); - uint8_t nNumTok; - const XMLTokenStruc *pTok; -} XMLTableStruc; - -typedef enum { - TOK_ERR, - TOK_EOF, /* reached end of the input */ - TOK_LBRACKET, /* "<" */ - TOK_ENDLBRACKET, /* "" */ - TOK_RBRACKET, /* ">" */ - TOK_EQ, /* "=" */ - TOK_STR, /* string on the rhs of = */ - TOK_KEYWORD, /* string on lhs of = */ - TOK_CONTENT_STR -} XMLToken; - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_callinfo.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_callinfo.c deleted file mode 100644 index f6b09edf3a0..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_callinfo.c +++ /dev/null @@ -1,677 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "ccsip_callinfo.h" -#include "ccsip_protocol.h" -#include "ccsip_core.h" -#include "cpr_string.h" -#include "cpr_strings.h" -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_memory.h" -#include "cpr_stdlib.h" -#include "phone_debug.h" - - -#define FEAT_STRING_SIZE 80 - -/* - * which_feature - * - * Description: - * - * A quick determination of the feature based on the string. - */ -static cc_call_info_e -which_feature (char *feat_string_p) -{ - if (cpr_strcasecmp(feat_string_p, SIP_CI_HOLD_STR) == 0) - return CC_FEAT_HOLD; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_RESUME_STR) == 0) - return CC_FEAT_RESUME; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_BARGE_STR) == 0) - return CC_FEAT_BARGE; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_CBARGE_STR) == 0) - return CC_FEAT_CBARGE; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_CALL_INFO_STR) == 0) - return CC_FEAT_CALLINFO; - - return CC_FEAT_NONE; -} - -/* - * parse_call_info_parm - * - * Description: - * - * Parse potential callinfo feature parms. - */ -static void -parse_call_info_parm (char *parm_p, cc_call_info_data_t * feature_data_p) -{ - static const char fname[] = "parse_call_info_parm"; - char *temp_p; - uint16_t instance_id; - unsigned long strtoul_result; - char *strtoul_end; - - if (!parm_p) - return; - - while (parm_p) { - parm_p++; - SKIP_LWS(parm_p); - - if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY, - sizeof(SIP_CI_SECURITY) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_SECURITY) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_SECURITY; - if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_UNKNOWN, - sizeof(SIP_CI_SECURITY_UNKNOWN) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_UNKNOWN; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_AUTH, - sizeof(SIP_CI_SECURITY_AUTH) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_AUTHENTICATED; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_ENCRYPTED, - sizeof(SIP_CI_SECURITY_ENCRYPTED) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_ENCRYPTED; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_NOT_AUTH, - sizeof(SIP_CI_SECURITY_NOT_AUTH) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_NOT_AUTHENTICATED; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Unknown security" - " value %s\n", fname, parm_p); - feature_data_p->call_info_feat_data.security = CC_SECURITY_UNKNOWN; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY, - sizeof(SIP_CI_POLICY) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_POLICY) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_POLICY; - if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY_CHAPERONE , - sizeof(SIP_CI_POLICY_CHAPERONE) - 1)) { - feature_data_p->call_info_feat_data.policy = CC_POLICY_CHAPERONE; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY_UNKNOWN, - sizeof(SIP_CI_POLICY_UNKNOWN) - 1)) { - feature_data_p->call_info_feat_data.policy = CC_POLICY_UNKNOWN; - } else { - CCSIP_DEBUG_ERROR("%s ERROR: Unknown policy" - " value %s\n", fname, parm_p) ; - feature_data_p->call_info_feat_data.policy = CC_POLICY_UNKNOWN; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION, - sizeof(SIP_CI_ORIENTATION) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_ORIENTATION) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_ORIENTATION; - if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION_FROM, - sizeof(SIP_CI_ORIENTATION_FROM) - 1)) { - feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_FROM; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION_TO, - sizeof(SIP_CI_ORIENTATION_TO) - 1)) { - feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_TO; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Unknown orientation info" - " value %s\n", fname, parm_p); - feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_NONE; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE, - sizeof(SIP_CI_UI_STATE) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_UI_STATE) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_UI_STATE; - if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_RINGOUT, - sizeof(SIP_CI_UI_STATE_RINGOUT) - 1)) { - feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_RINGOUT; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_CONNECTED, - sizeof(SIP_CI_UI_STATE_CONNECTED) - 1)) { - feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_CONNECTED; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_BUSY, - sizeof(SIP_CI_UI_STATE_BUSY) - 1)) { - feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_BUSY; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Unknown call state" - " value %s\n", fname, parm_p); - /* Unknown value, ignore the call state */ - feature_data_p->call_info_feat_data.feature_flag &= - ~(CC_UI_STATE); - feature_data_p->call_info_feat_data.ui_state = - CC_UI_STATE_NONE; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_CALL_INSTANCE, - sizeof(SIP_CI_CALL_INSTANCE) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_CALL_INSTANCE) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - int idx=0; - char tempbuf[4]; - - feature_data_p->call_info_feat_data.feature_flag |= CC_CALL_INSTANCE; - /* Initialized the call instance id, just in case */ - feature_data_p->call_info_feat_data.caller_id.call_instance_id - = 0; - /* Parse instance id from line */ - temp_p = parm_p; - while (isdigit((int) *parm_p)&&idx<3) { - tempbuf[idx++] = *parm_p++; - } - tempbuf[idx] = 0; - if (idx == 0) { - /* Did not find any digit after "call_instance=" */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "no digits found for" - " call_instance parameter.\n", fname); - feature_data_p->call_info_feat_data.feature_flag &= - ~(CC_CALL_INSTANCE); - break; - } else { - errno = 0; - strtoul_result = strtoul(tempbuf, &strtoul_end, 10); - - if (errno || tempbuf == strtoul_end || strtoul_result > USHRT_MAX) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "parse error for call_instance_id: %s", - __FUNCTION__, tempbuf); - strtoul_result = 0; - } - - feature_data_p->call_info_feat_data.caller_id.call_instance_id = - (uint16_t) strtoul_result; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY, - sizeof(SIP_CI_PRIORITY) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_PRIORITY) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - temp_p = parm_p; - if ((!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY_URGENT, - sizeof(SIP_CI_PRIORITY_URGENT) - 1)) || - (!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY_EMERGENCY, - sizeof(SIP_CI_PRIORITY_EMERGENCY) - 1))) { - feature_data_p->call_info_feat_data.priority = CC_CALL_PRIORITY_URGENT; - } // otherwise, it will be defaulted to normal priority - else { - errno = 0; - strtoul_result = strtoul(temp_p, &strtoul_end, 10); - - if (errno || temp_p == strtoul_end || strtoul_result > (MAX_CALLS - 1)) { - /* - * Call instance ID should not exceed max instances - * or calls. - */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "invalid call_instance" - " value %u\n", fname, (unsigned) strtoul_result); - feature_data_p->call_info_feat_data.feature_flag &= - ~(CC_CALL_INSTANCE); - } else { - instance_id = (uint16_t) strtoul_result; - feature_data_p->call_info_feat_data.caller_id.call_instance_id = instance_id; - } - } - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_GCID, - sizeof(SIP_CI_GCID) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_GCID) - 1; - SKIP_LWS(parm_p); - memset(feature_data_p->call_info_feat_data.global_call_id, 0, CC_GCID_LEN); - if (*parm_p) { - temp_p = strchr(parm_p, SEMI_COLON); - if (temp_p) { - unsigned int length = ((temp_p - parm_p)call_info_feat_data.global_call_id, parm_p, length); - } else { - // No Semicolon found this could be the last parameter - sstrncpy(feature_data_p->call_info_feat_data.global_call_id, parm_p, CC_GCID_LEN); - } - feature_data_p->call_info_feat_data.global_call_id[CC_GCID_LEN-1] = 0; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_DUSTINGCALL, - sizeof(SIP_CI_DUSTINGCALL) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_DUSTINGCALL) - 1; - SKIP_LWS(parm_p); - feature_data_p->call_info_feat_data.dusting = TRUE; - } - - parm_p = strchr(parm_p, SEMI_COLON); - } -} - -/* - * parse_gen_parm - * - * Description: - * - * Parse feature parms where the only expected parm is the purpose. - */ -static void -parse_gen_parm (char *parm_p, cc_call_info_data_t * feature_data_p) -{ - if (!parm_p) - return; - - while (parm_p) { - parm_p++; - SKIP_LWS(parm_p); - - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC, - sizeof(SIP_CI_GENERIC) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_GENERIC) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_ICON, - sizeof(SIP_CI_GENERIC_ICON) - 1)) { - feature_data_p->purpose = CC_PURPOSE_ICON; - } else { - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_INFO, - sizeof(SIP_CI_GENERIC_INFO) - 1)) { - feature_data_p->purpose = CC_PURPOSE_INFO; - } else { - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_CARD, - sizeof(SIP_CI_GENERIC_CARD) - 1)) { - feature_data_p->purpose = CC_PURPOSE_CARD; - } - } - } - } - } else { - break; - } - parm_p = strchr(parm_p, SEMI_COLON); - } -} - -/* - * set_parm_defaults - * - * Description: - * - * A quick determination of the feature based on the string. - */ -static void -set_parm_defaults (cc_call_info_t *call_info_p) -{ - switch (call_info_p->type) { - case CC_FEAT_HOLD: - case CC_FEAT_RESUME: - case CC_FEAT_NONE: - call_info_p->data.hold_resume_reason = CC_REASON_NONE; - break; - - case CC_FEAT_BARGE: - case CC_FEAT_CBARGE: - call_info_p->data.purpose = CC_PURPOSE_NONE; - break; - - case CC_FEAT_CALLINFO: - call_info_p->data.call_info_feat_data.policy = CC_POLICY_NONE; - call_info_p->data.call_info_feat_data.security = CC_SECURITY_NONE; - call_info_p->data.call_info_feat_data.orientation = CC_ORIENTATION_NONE; - call_info_p->data.call_info_feat_data.ui_state = CC_UI_STATE_NONE; - call_info_p->data.call_info_feat_data.priority = CC_CALL_PRIORITY_NORMAL; - call_info_p->data.call_info_feat_data.global_call_id[0] = 0; - call_info_p->data.call_info_feat_data.dusting = FALSE; - break; - - default: - break; - } - -} - -/* - * ccsip_decode_call_info_hdr - * - * Description: - * - * Main method which decodes a single call info header and stores the - * related parms. - * - * Example Input: - * --------------- - * ; reason= conference - * ; seCuRity=unsecure; orienTation= to - */ -static void -ccsip_decode_call_info_hdr (const char *call_info_hdr_p, - cc_call_info_t *call_info_p) -{ - char *ptr = NULL; - char *laq_ptr = NULL; - char *raq_ptr = NULL; - boolean ret_val = FALSE; - char feat_string[FEAT_STRING_SIZE]; - - memset(feat_string, '\0', sizeof(feat_string)); - - /* - * call_info_hdr_p and call_info_p are verified by caller so they - * are not checked here. - */ - - ptr = laq_ptr = strchr(call_info_hdr_p, LAQUOT); - raq_ptr = strchr(call_info_hdr_p, RAQUOT); - - // Parse out the remotecc string and the feature string. - if (laq_ptr && raq_ptr) { - ptr++; - - // Verify the remotecc string. - if (!cpr_strncasecmp(ptr, URN_REMOTECC, sizeof(URN_REMOTECC) - 1)) { - ptr += sizeof(URN_REMOTECC) - 1; - sstrncpy(feat_string, ptr, raq_ptr - ptr + 1); - - // Which feature do we have in this header? - call_info_p->type = which_feature(feat_string); - - if (call_info_p->type != CC_FEAT_NONE) { - ret_val = TRUE; - set_parm_defaults(call_info_p); - } - } - } - - if (!ret_val) { - return; - } - - if (!(ptr = strchr(raq_ptr, SEMI_COLON))) { - return; - } - - switch (call_info_p->type) { - case CC_FEAT_CALLINFO: - parse_call_info_parm(ptr, &call_info_p->data); - break; - default: - parse_gen_parm(ptr, &call_info_p->data); - } -} - -/* - * ccsip_encode_call_info_hdr - * - * Description: - * - * Encode the call info header using the passed in feature id and - * feature specific data. - * - * The miscParms parameter will usually be null. It exists in case - * you want to toss in an additional string parm without using the - * encoding mechanism. An example would be "extraParm= text". - * - * Remember to delete the store in the return parm. It is the - * caller's responsibility. - */ -char * -ccsip_encode_call_info_hdr (cc_call_info_t *call_info_p, - const char *misc_parms_p) -{ - static const char *fname = "ccsip_encode_call_info_hdr"; - char *header; - - header = (char *) cpr_malloc(MAX_SIP_HEADER_LENGTH); - if (!header) { - return NULL; - } - - if (!call_info_p) { - cpr_free(header); - return NULL; - } - - snprintf(header, MAX_SIP_HEADER_LENGTH, "<%s", URN_REMOTECC); - - switch (call_info_p->type) { - case CC_FEAT_HOLD: - case CC_FEAT_RESUME: - if (call_info_p->type == CC_FEAT_HOLD) { - sstrncat(header, SIP_CI_HOLD_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } else { - sstrncat(header, SIP_CI_RESUME_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - sstrncat(header, ">", MAX_SIP_HEADER_LENGTH - strlen(header)); - - switch (call_info_p->data.hold_resume_reason) { - case CC_REASON_NONE: - case CC_REASON_INTERNAL: - case CC_REASON_SWAP: - break; - case CC_REASON_XFER: - sstrncat(header, "; reason= ", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_HOLD_REASON_XFER, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - case CC_REASON_CONF: - sstrncat(header, "; reason= ", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_HOLD_REASON_CONF, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "unsupported hold_resume_reason", - fname); - cpr_free(header); - return NULL; - } - - /* Add swap information */ - if (call_info_p->data.call_info_feat_data.swap == TRUE) { - sstrncat(header, "; operation= swap", - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - - if (call_info_p->data.call_info_feat_data.protect == TRUE) { - sstrncat(header, "; protect= true; noholdreversion", - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - - break; - - case CC_FEAT_INIT_CALL: - /* Add global call id here */ - if (call_info_p->data.initcall.gcid[0] != '\0') { - sstrncat(header, "callinfo>; gci= ", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, call_info_p->data.initcall.gcid, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } else { - cpr_free(header); - return NULL; - } - /* Add the monitor mode here if it exists */ - if (call_info_p->data.initcall.monitor_mode != CC_MONITOR_NONE) { - sstrncat(header, "; mode=", - MAX_SIP_HEADER_LENGTH - strlen(header)); - - switch (call_info_p->data.initcall.monitor_mode) { - - case CC_MONITOR_SILENT : - sstrncat(header, SIP_CI_SILENT_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - - case CC_MONITOR_COACHING : - sstrncat(header, SIP_CI_COACHING_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - - default: - break; - } - } - break; - - case CC_FEAT_TOGGLE_TO_WHISPER_COACHING: - sstrncat(header, "callinfo>", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, "; mode=", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_COACHING_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - - break; - - case CC_FEAT_TOGGLE_TO_SILENT_MONITORING: - sstrncat(header, "callinfo>", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, "; mode=", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_SILENT_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - - break; - - default: - cpr_free(header); - return NULL; - } - - - if (misc_parms_p) { - sstrncat(header, misc_parms_p, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - sstrncat(header, "\0", MAX_SIP_HEADER_LENGTH - strlen(header)); - return (header); -} - -/* - * ccsip_free_call_info_header - * - * Description: - * - * Frees the memory allocated to a call info structure. - */ -void -ccsip_free_call_info_header (cc_call_info_t *call_info_p) -{ - if(call_info_p->type == CC_FEAT_CALLINFO) { - - } - cpr_free(call_info_p); -} - -/* - * ccsip_process_call_info_header - * - * Description: - * - * Checks if there is a call info header in the provided SIP message. If there is, - * the call info in the CCB is cleared and the new call info is parsed into the - * CCB call info structure. - */ -void -ccsip_process_call_info_header (sipMessage_t *request_p, ccsipCCB_t *ccb) -{ - char *call_info_hdrs[MAX_CALL_INFO_HEADERS]; - uint16_t num_call_info_headers; - int i = 0; - - if (!ccb) { - return; - } - - if (ccb->in_call_info) { - ccsip_free_call_info_header(ccb->in_call_info); - ccb->in_call_info = NULL; - } - - if (!request_p) { - return; - } - - memset(call_info_hdrs, 0, MAX_CALL_INFO_HEADERS * sizeof(char *)); - - num_call_info_headers = sippmh_get_num_particular_headers(request_p, - SIP_HEADER_CALL_INFO, - SIP_HEADER_CALL_INFO, - call_info_hdrs, - MAX_CALL_INFO_HEADERS); - - if (num_call_info_headers > 0) { - ccb->in_call_info = (cc_call_info_t *) - cpr_calloc(1, sizeof(cc_call_info_t)); - if (ccb->in_call_info) { - - ccb->in_call_info->data.call_info_feat_data.feature_flag = 0; - - // Parse each Call-Info header - for (i = 0; i < MAX_CALL_INFO_HEADERS; i++) { - if (call_info_hdrs[i]) { - ccsip_decode_call_info_hdr(call_info_hdrs[i], ccb->in_call_info); - } - } - - } else { - ccb->in_call_info = NULL; - } - } - -} - -/* - * ccsip_store_call_info - * - * Description: Used for storing call_info received from GSM - * - * Store specified call info structure in ccb. - */ -void -ccsip_store_call_info (cc_call_info_t *call_info_p, ccsipCCB_t *ccb) -{ - if (!ccb) { - return; - } - - if (ccb->out_call_info) { - ccsip_free_call_info_header(ccb->out_call_info); - ccb->out_call_info = NULL; - } - - if (call_info_p->type != CC_FEAT_NONE) { - ccb->out_call_info = (cc_call_info_t *) - cpr_malloc(sizeof(cc_call_info_t)); - if (ccb->out_call_info) { - memcpy(ccb->out_call_info, call_info_p, sizeof(cc_call_info_t)); - } else { - ccb->out_call_info = NULL; - } - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_cc.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_cc.c deleted file mode 100755 index 0a97efcc8b5..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_cc.c +++ /dev/null @@ -1,305 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "ccapi.h" -#include "string_lib.h" -#include "ccsip_pmh.h" -#include "ccsip_messaging.h" - -/* - * Function: sip_cc_mv_msg_body_to_cc_msg - * - * Parameters: cc_msg - pointer to cc_msgbody_info structure to - * move the content from the SIP body msg. to. - * sip_msg - pointer to sipMessage_t structure of the source - * body. - * - * Description: This routine moves the body parts from sipMessage_t to - * CCAPI body msg. Once the content is moved, - * the all pointers from the sipMessage_t structure, - * will be NULL so that they are not own by SIP stack. - * The destination of the msg. needs to free the - * memory for of the parts. - * - * Returns: N/A - * - */ -void sip_cc_mv_msg_body_to_cc_msg (cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg) -{ - int i; - uint32_t num_parts = 0; - cc_msgbody_t *part; - - if (cc_msg == NULL) { - /* destination to move msg. to */ - return; - } - if (sip_msg == NULL) { - /* No SIP message to move from, set number of part to zero */ - cc_msg->num_parts = 0; - return; - } - - part = &cc_msg->parts[0]; - for (i = 0; (i < sip_msg->num_body_parts) && - (i < CC_MAX_BODY_PARTS); i++) { - if ((sip_msg->mesg_body[i].msgBody != NULL) && - (sip_msg->mesg_body[i].msgLength)) { - /* Body */ - part->body = sip_msg->mesg_body[i].msgBody; - part->body_length = sip_msg->mesg_body[i].msgLength; - sip_msg->mesg_body[i].msgBody = NULL; - - /* Content type */ - part->content_type = - sip2cctype(sip_msg->mesg_body[i].msgContentTypeValue); - /* Disposition */ - part->content_disposition.disposition = - sip2ccdisp(sip_msg->mesg_body[i].msgContentDisp); - part->content_disposition.required_handling = - sip_msg->mesg_body[i].msgRequiredHandling; - /* Content ID */ - part->content_id = sip_msg->mesg_body[i].msgContentId; - sip_msg->mesg_body[i].msgContentId = NULL; - - /* Next part */ - part++; - num_parts++; - } - } - /* Set the number of parts */ - cc_msg->num_parts = num_parts; -} - -/* - * Function: sip_cc_create_cc_msg_body_from_sip_msg - * - * Parameters: cc_msg - pointer to cc_msgbody_info structure to - * store the content of the SIP body msg. - * sip_msg - pointer to sipMessage_t structure of the source - * body. - * - * Description: This routine creates the cc_msgbody_info_t content - * from the SIP message. The original msg. body in the - * SIP message remains in the SIP message. - * - * Returns: TRUE - success - * FALSE - fail. - * - */ -boolean sip_cc_create_cc_msg_body_from_sip_msg (cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg) -{ - int i, len; - uint32_t num_parts = 0; - cc_msgbody_t *part; - boolean status = TRUE; - - if (cc_msg == NULL) { - /* destination to move msg. to */ - return (FALSE); - } - - if (sip_msg == NULL) { - /* No SIP message to move from, set number of part to zero */ - cc_msg->num_parts = 0; - return (FALSE); - } - - memset(cc_msg, 0, sizeof(cc_msgbody_info_t)); - part = &cc_msg->parts[0]; - for (i = 0; (i < sip_msg->num_body_parts) && - (i < CC_MAX_BODY_PARTS) ; i++) { - if ((sip_msg->mesg_body[i].msgBody != NULL) && - (sip_msg->mesg_body[i].msgLength)) { - /* Body */ - part->body = (char *) cpr_malloc(sip_msg->mesg_body[i].msgLength); - if (part->body != NULL) { - part->body_length = sip_msg->mesg_body[i].msgLength; - memcpy(part->body, - sip_msg->mesg_body[i].msgBody, - sip_msg->mesg_body[i].msgLength); - } else { - /* Unable to allocate memory for msg. body */ - status = FALSE; - break; - } - - /* Content type */ - part->content_type = - sip2cctype(sip_msg->mesg_body[i].msgContentTypeValue); - /* Disposition */ - part->content_disposition.disposition = - sip2ccdisp(sip_msg->mesg_body[i].msgContentDisp); - part->content_disposition.required_handling = - sip_msg->mesg_body[i].msgRequiredHandling; - - /* Content ID */ - if (sip_msg->mesg_body[i].msgContentId != NULL) { - /* Get length of the msgContentID with NULL */ - len = strlen(sip_msg->mesg_body[i].msgContentId) + 1; - part->content_id = (char *) cpr_malloc(len); - if (part->content_id != NULL) { - memcpy(part->content_id, - sip_msg->mesg_body[i].msgContentId, - len); - } else { - /* Unable to allocate allocate memory for content ID */ - status = FALSE; - break; - } - } else { - /* No content ID */ - part->content_id = NULL; - } - /* Next part */ - part++; - num_parts++; - } - } - /* Set the number of parts */ - cc_msg->num_parts = num_parts; - - if (!status) { - /* - * Faied for some reason, free the resources that mighe be - * created before failure - */ - cc_free_msg_body_parts(cc_msg); - } - return (status); -} - -void sip_cc_setup (callid_t call_id, line_t line, - string_t calling_name, string_t calling_number, string_t alt_calling_number, - boolean display_calling_number, - string_t called_name, string_t called_number, - boolean display_called_number, - string_t orig_called_name, string_t orig_called_number, - string_t last_redirect_name, string_t last_redirect_number, - cc_call_type_e call_type, - cc_alerting_type alert_info, - vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_call_info_t *call_info_p, - boolean replaces, string_t recv_info_list, sipMessage_t *sip_msg) -{ - cc_caller_id_t caller_id; - cc_msgbody_info_t cc_body_info; - - caller_id.calling_name = calling_name; - caller_id.calling_number = calling_number; - caller_id.alt_calling_number = alt_calling_number; - caller_id.display_calling_number = display_calling_number; - caller_id.called_name = called_name; - caller_id.called_number = called_number; - caller_id.display_called_number = display_called_number; - caller_id.last_redirect_name = last_redirect_name; - caller_id.last_redirect_number = last_redirect_number; - caller_id.orig_called_name = orig_called_name; - caller_id.orig_called_number = orig_called_number; - caller_id.orig_rpid_number = strlib_empty(); - caller_id.call_type = call_type; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - -// Check with CraigB - cc_setup(CC_SRC_SIP, call_id, line, &caller_id, alert_info, - alerting_ring, alerting_tone, NULL, call_info_p, replaces, - recv_info_list, &cc_body_info); -} - - -#ifdef REMOVED_UNUSED_FUNCTION -void sip_cc_setup_ack (callid_t call_id, line_t line, - cc_msgbody_info_t *msg_body) -{ - cc_setup_ack(CC_SRC_SIP, call_id, line, NULL, msg_body); -} -#endif - -void sip_cc_proceeding (callid_t call_id, line_t line) -{ - cc_proceeding(CC_SRC_SIP, call_id, line, NULL); -} - -void sip_cc_alerting (callid_t call_id, line_t line, - sipMessage_t *sip_msg, int inband) -{ - cc_msgbody_info_t cc_body_info; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - - cc_alerting(CC_SRC_SIP, call_id, line, NULL, &cc_body_info, - (boolean)inband); -} - - -void sip_cc_connected (callid_t call_id, line_t line, string_t recv_info_list, sipMessage_t *sip_msg) -{ - cc_msgbody_info_t cc_body_info; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - - cc_connected(CC_SRC_SIP, call_id, line, NULL, recv_info_list, &cc_body_info); -} - - -void sip_cc_connected_ack (callid_t call_id, line_t line, - sipMessage_t *sip_msg) -{ - cc_msgbody_info_t cc_body_info; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - - cc_connected_ack(CC_SRC_SIP, call_id, line, NULL, &cc_body_info); -} - - -void sip_cc_release (callid_t call_id, line_t line, cc_causes_t cause, - const char *dialstring) -{ - cc_release(CC_SRC_SIP, call_id, line, cause, dialstring, NULL); -} - - -void sip_cc_release_complete (callid_t call_id, line_t line, cc_causes_t cause) -{ - cc_release_complete(CC_SRC_SIP, call_id, line, cause, NULL); -} - - -void sip_cc_feature (callid_t call_id, line_t line, cc_features_t feature, void *data) -{ - cc_feature(CC_SRC_SIP, call_id, line, feature, (cc_feature_data_t *)data); -} - - -void sip_cc_feature_ack (callid_t call_id, line_t line, cc_features_t feature, - void *data, cc_causes_t cause) -{ - cc_feature_ack(CC_SRC_SIP, call_id, line, feature, (cc_feature_data_t *)data, cause); -} - - -void sip_cc_mwi (callid_t call_id, line_t line, boolean on, int type, - int newCount, int oldCount, int hpNewCount, int hpOldCount) -{ - cc_mwi(CC_SRC_SIP, call_id, line, on, type, newCount, oldCount, hpNewCount, hpOldCount); -} - -void sip_cc_options (callid_t call_id, line_t line, sipMessage_t *pSipMessage) -{ - cc_options_sdp_req(CC_SRC_SIP, call_id, line, pSipMessage); -} - -void sip_cc_audit (callid_t call_id, line_t line, boolean apply_ringout) -{ - cc_audit_sdp_req(CC_SRC_SIP, call_id, line, apply_ringout); -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_common_util.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_common_util.c deleted file mode 100644 index d866550e6bb..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_common_util.c +++ /dev/null @@ -1,260 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "ccsip_common_cb.h" -#include "sip_common_transport.h" -#include "prot_configmgr.h" -#include "ccsip_register.h" -#include "util_string.h" - -/** - * This function will set dest ip and port in common control block of SCB and PCB. - * - * @param[in] cb_p - pointer to the header control block. - * - * @return none - * - * @pre (cb_p != NULL) - */ -void ccsip_common_util_set_dest_ipaddr_port (ccsip_common_cb_t *cb_p) -{ - char addr[MAX_IPADDR_STR_LEN]; - - if (cb_p->dest_sip_addr.type == CPR_IP_ADDR_INVALID) { - sipTransportGetPrimServerAddress(cb_p->dn_line, addr); - dns_error_code = sipTransportGetServerAddrPort(addr, - &cb_p->dest_sip_addr, - (uint16_t *)&cb_p->dest_sip_port, - &cb_p->SRVhandle, - FALSE); - if (dns_error_code == 0) { - util_ntohl(&(cb_p->dest_sip_addr), &(cb_p->dest_sip_addr)); - } else { - sipTransportGetServerIPAddr(&(cb_p->dest_sip_addr), cb_p->dn_line); - } - - cb_p->dest_sip_port = ((dns_error_code == 0) && (cb_p->dest_sip_port)) ? - ntohs((uint16_t)cb_p->dest_sip_port) : - (sipTransportGetPrimServerPort(cb_p->dn_line)); - } -} - -/** - * This function will set source ip in common control block of SCB and PCB. - * - * @param[in] cb_p - pointer to the header control block. - * - * @return none - * - * @pre (cb_p != NULL) - */ -void ccsip_common_util_set_src_ipaddr (ccsip_common_cb_t *cb_p) -{ - int nat_enable = 0; - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(cb_p->src_addr)); - } else { - sip_config_get_nat_ipaddr(&(cb_p->src_addr)); - } -} - -/* - * This function will set retry settings in common control block of SCB and PCB. - * - * Description: Based on transport used, determines the value to be - * used to set either TimerE or TimerF - * 1. For reliable tranport: we SHOULD start timer F (= 64*T1), - * no retransmits are required. - * 2. To prevent retransmits for TCP/TLS, we set scbp->retx_counter - * to Max value. - * 3. For unreliable tranport: we SHOULD start timer E (= T1), - * retransmits are required. - * This routine must only be invoked before sending a request for - * the first time with valid args. - * - * @param[in] cb_p - pointer to header control block. - * @param[out] timeout_p - returns the value to be used to set a timer. - * - * @return none - * - * @pre (cb_p != NULL) and (timeout_p != NULL) - */ -void ccsip_common_util_set_retry_settings (ccsip_common_cb_t *cb_p, int *timeout_p) -{ - uint32_t max_retx = 0; - const char *transport = NULL; - - *timeout_p = 0; - cb_p->retx_flag = TRUE; - config_get_value(CFGID_TIMER_T1, timeout_p, sizeof(*timeout_p)); - - transport = sipTransportGetTransportType(cb_p->dn_line, TRUE, NULL); - if (transport) { - if (strcmp(transport, "UDP") == 0) { - cb_p->retx_counter = 0; - } else { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - cb_p->retx_counter = max_retx; - (*timeout_p) = (64 * (*timeout_p)); - } - } -} - - -/** - * This function will generate authorization header value. - * - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[in] cb_p - pointer to header control block. - * @param[in] rsp_method - response method - * @param[in] response_code - response code - * @param[in] uri - uri - * - * @return TRUE if it is successful. - * - * @pre (cb_p != NULL) and (pSipMessage != NULL) and (rsp_method != NULL) and (uri != NULL) - */ -boolean ccsip_common_util_generate_auth (sipMessage_t *pSipMessage, ccsip_common_cb_t *cb_p, - const char *rsp_method, int response_code, char *uri) -{ - static const char fname[] = "ccsip_common_util_generate_auth"; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - - if (!(cb_p->authen.cred_type & CRED_LINE)) { - cb_p->authen.cred_type |= CRED_LINE; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "configured credentials for line %d not accepeted. Verify the config\n", - fname, cb_p->dn_line); - return FALSE; - } - - /* - * get authname & password from configuration. - */ - cred_get_line_credentials(cb_p->dn_line, &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - /* - * Extract Authenticate/Proxy-Authenticate header from the message. - */ - authenticate = sippmh_get_header_val(pSipMessage, AUTH_HDR(response_code), NULL); - if (authenticate == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s header missing in the %d response", - fname, AUTH_HDR_STR(response_code), response_code); - return FALSE; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authenticate header %s = %s", DEB_F_PREFIX_ARGS(SIP_AUTH, fname), AUTH_HDR_STR(response_code), authenticate); - /* - * Parse Authenticate header. - */ - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s:%s header formatted incorrectly in the %d response", - fname, AUTH_HDR_STR(response_code), authenticate, response_code); - return FALSE; - } - cb_p->authen.new_flag = FALSE; - cb_p->authen.cnonce[0] = '\0'; - /* - * Generate Authorization string. - */ - if (sipSPIGenerateAuthorizationResponse(sip_authen, - uri, - rsp_method, - credentials.id, - credentials.pw, - &author_str, - &(cb_p->authen.nc_count), - NULL) == TRUE) { - - if (cb_p->authen.authorization != NULL) { - cpr_free(cb_p->authen.authorization); - cb_p->authen.authorization = NULL; - } - - if (cb_p->authen.sip_authen != NULL) { - sippmh_free_authen(cb_p->authen.sip_authen); - cb_p->authen.sip_authen = NULL; - } - - cb_p->authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - - /* - * Cache the Authorization header so that it can be - * used for later requests - */ - if (cb_p->authen.authorization != NULL) { - memcpy(cb_p->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - cb_p->authen.status_code = response_code; - cb_p->authen.sip_authen = sip_authen; - } - - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Authorization header build unsuccessful", fname); - sippmh_free_authen(sip_authen); - return FALSE; - } - return TRUE; -} - -/** - * This function will extract user part from sip From header. - * - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[out] entity - pointer to user buffer. - * - * @return void - * - * @pre (pSipMessage != NULL) and (entity != NULL) - */ -void ccsip_util_get_from_entity (sipMessage_t *pSipMessage, char *entity) -{ - const char *sip_from = NULL; - sipLocation_t *from_loc = NULL; - - sip_from = sippmh_get_cached_header_val(pSipMessage, FROM); - if (sip_from != NULL) { - from_loc = sippmh_parse_from_or_to((char *) sip_from, TRUE); - if ((from_loc) && (from_loc->genUrl->schema == URL_TYPE_SIP) && (from_loc->genUrl->u.sipUrl->user)) { - sstrncpy(entity, from_loc->genUrl->u.sipUrl->user, CC_MAX_DIALSTRING_LEN); - } - } - if (from_loc) { - sippmh_free_location(from_loc); - } -} - -/** - * This function will extract user part from sip URL. - * - * @param[in] url - pointer to URL - * @param[out] user - pointer to user buffer. - * - * @return void - * - * @pre (url != NULL) and (user != NULL) - */ -void ccsip_util_extract_user (char *url, char *user) -{ - genUrl_t *genUrl = NULL; - - genUrl = sippmh_parse_url(url, TRUE); - if (genUrl != NULL) { - sstrncpy(user, genUrl->u.sipUrl->user, CC_MAX_DIALSTRING_LEN); - sippmh_genurl_free(genUrl); - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_core.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_core.c deleted file mode 100644 index 3ee627ff4f0..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_core.c +++ /dev/null @@ -1,12295 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "cpr_rand.h" - -#include "ccsip_core.h" -#include "text_strings.h" -#include "util_string.h" -#include "ccsip_messaging.h" -#include "ccsip_platform_udp.h" -#include "ccsip_platform.h" -#include "ccsip_macros.h" -#include "ccsip_pmh.h" -#include "ccsip_spi_utils.h" -#include "phone_debug.h" -#include "ccsip_register.h" -#include "ccsip_credentials.h" -#include "ccsip_callinfo.h" -#include "ccsip_cc.h" -#include "ccsip_task.h" -#include "config.h" -#include "string_lib.h" -#include "dialplan.h" -#include "fsm.h" -#include "sip_interface_regmgr.h" -#include "ccsip_subsmanager.h" -#include "ccsip_publish.h" -#include "sdp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "rtp_defs.h" -#include "uiapi.h" -#include "text_strings.h" -#include "platform_api.h" -#include "misc_util.h" - - -/* - * OS specific hooks - */ - -extern void sip_platform_handle_service_control_notify(sipServiceControl_t *scp); -extern uint32_t IPNameCk(char *name, char *addr_error); - - -#define ADD_TO_ARP_CACHE(dest_sip_addr) -#define UNBIND_UDP_ICMP_HANDLER(udp_id) - - -extern boolean sip_mode_quiet; - -extern void ccsip_debug_init(void); -extern void shutdownCCAck(int action); -void ccsip_remove_wlan_classifiers(void); - -#define USECALLMANAGER_LEN 14 -/* - * Needed to parse the alert-info header - */ -//CPR TODO: need reference for -extern const char *tone_names[]; -const char *ring_names[] = { - "Bellcore-dr1", - "Bellcore-dr2", - "Bellcore-dr3", - "Bellcore-dr4", - "Bellcore-dr5" -}; - - -/* Forward function declarations */ -static int sip_sm_request_check_and_store(ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t request_method, - boolean midcall, - uint16_t *request_check_reason_code, - char *request_check_reason_phrase, - boolean store_invite); -void sip_sm_update_to_from_on_callsetup_finalresponse(ccsipCCB_t *ccb, - sipMessage_t *response); -void sip_sm_update_contact_recordroute(ccsipCCB_t *ccb, sipMessage_t *response, - int response_code, boolean midcall); -static boolean ccsip_set_replace_info(ccsipCCB_t *ccb, cc_setup_t * setup); -static boolean ccsip_handle_cc_select_event(sipSMEvent_t *sip_sm_event); -static boolean ccsip_handle_cc_b2bjoin_event(sipSMEvent_t *sip_sm_event); -static void ccsip_set_join_info(ccsipCCB_t *ccb, cc_setup_t * setup); -static boolean ccsip_get_join_info(ccsipCCB_t *ccb, sipMessage_t *request); -static char *ccsip_find_preallocated_sip_call_id(line_t dn_line); -static void ccsip_free_preallocated_sip_call_id(line_t dn_line); -static boolean ccsip_handle_cc_hook_event(sipSMEvent_t *sip_sm_event); - -extern cc_int32_t dnsGetHostByName (const char *hname, cpr_ip_addr_t *ipaddr_ptr, cc_int32_t timeout, cc_int32_t retries); - -//CPR TODO: need reference for -extern char *Basic_is_phone_forwarded(line_t line); - -/* External Declarations */ -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern sipGlobal_t sip; -extern sipCallHistory_t gCallHistory[]; - -/* Globals */ -int dns_error_code; // Global DNS error code value -uint16_t server_caps = 0; // Server capabilities -boolean sip_reg_all_failed; - -ccsipGlobInfo_t gGlobInfo; -sipCallHistory_t gCallHistory[MAX_TEL_LINES]; - -typedef struct { - int16_t sipValidEvent; - int16_t actionIndex; -} subStateEvent_t; - -#define MAX_STATE_EVENTS 13 -typedef struct { - int16_t sipState; - subStateEvent_t validEvent[MAX_STATE_EVENTS]; -} sipSMfunctable_t; - -static char *preAllocatedSipCallID[MAX_REG_LINES] = { NULL }; -static char *preAllocatedTag[MAX_REG_LINES] = { NULL }; -boolean g_disable_mass_reg_debug_print = FALSE; - -static const sipSMfunctable_t g_sip_table[SIP_STATE_END - SIP_STATE_BASE + 1] = -{ - /* - * SIP_STATE_IDLE - */ - { SIP_STATE_IDLE, - { - /* E_SIP_INVITE ccsip_handle_idle_ev_sip_invite, */ - {E_SIP_INVITE, H_IDLE_EV_SIP_INVITE}, - /* E_CC_SETUP ccsip_handle_idle_ev_cc_setup, */ - {E_CC_SETUP, H_IDLE_EV_CC_SETUP}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE ccsip_handle_default_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_EV_CC_FEATURE}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_SENT_INVITE - */ - {SIP_STATE_SENT_INVITE, - { - /* E_SIP_1xx ccsip_handle_sentinvite_ev_sip_1xx, */ - {E_SIP_1xx, H_SENTINVITE_EV_SIP_1XX}, - /* E_SIP_2xx ccsip_handle_sentinvite_ev_sip_2xx, */ - {E_SIP_2xx, H_SENTINVITE_EV_SIP_2XX}, - /* E_SIP_3xx ccsip_handle_sentinvite_ev_sip_3xx */ - {E_SIP_3xx, H_SENTINVITE_EV_SIP_3XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_early */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_EARLY}, - /* E_SIP_INV_EXPIRES_TIMER ccsip_handle_disconnect_local_early */ - {E_SIP_INV_EXPIRES_TIMER, H_DISCONNECT_LOCAL_EARLY}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_SENT_INVITE_CONNECTED - */ - {SIP_STATE_SENT_INVITE_CONNECTED, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_CONNECTED_ACK ccsip_handle_sentinviteconnected_ev_cc_connected_ack, */ - {E_CC_CONNECTED_ACK, H_SENTINVITECONNECTED_EV_CC_CONNECTED_ACK}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_INVITE - */ - {SIP_STATE_RECV_INVITE, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_CANCEL ccsip_handle_disconnect_remote, */ - {E_SIP_CANCEL, H_DISCONNECT_REMOTE}, - /* E_CC_SETUP_ACK ccsip_handle_recvinvite_ev_cc_setup_ack, */ - {E_CC_SETUP_ACK, H_RECVINVITE_EV_CC_SETUP_ACK}, - /* E_CC_PROCEEDING ccsip_handle_recvinvite_ev_cc_proceeding, */ - {E_CC_PROCEEDING, H_RECVINVITE_EV_CC_PROCEEDING}, - /* E_CC_ALERTING ccsip_handle_recvinvite_ev_cc_alerting, */ - {E_CC_ALERTING, H_RECVINVITE_EV_CC_ALERTING}, - /* E_CC_CONNECTED ccsip_handle_recvinvite_ev_cc_connected, */ - {E_CC_CONNECTED, H_RECVINVITE_EV_CC_CONNECTED}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_unanswered, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_UNANSWERED}, - /* E_SIP_INV_LOCALEXPIRES_TIMER ccsip_handle_localexpires_timer */ - {E_SIP_INV_LOCALEXPIRES_TIMER, H_HANDLE_LOCALEXPIRES_TIMER}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY} - - /* Initializing any events which are not used to Invalid events */ - } - }, - - /* - * SIP_STATE_RECV_INVITE_PROCEEDING - */ - {SIP_STATE_RECV_INVITE_PROCEEDING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_CANCEL ccsip_handle_disconnect_remote */ - {E_SIP_CANCEL, H_DISCONNECT_REMOTE}, - /* E_CC_ALERTING ccsip_handle_recvinvite_ev_cc_alerting, */ - {E_CC_ALERTING, H_RECVINVITE_EV_CC_ALERTING}, - /* E_CC_CONNECTED ccsip_handle_recvinvite_ev_cc_connected, */ - {E_CC_CONNECTED, H_RECVINVITE_EV_CC_CONNECTED}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_unanswered, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_UNANSWERED}, - /* E_SIP_INV_LOCALEXPIRES_TIMER ccsip_handle_localexpires_timer */ - {E_SIP_INV_LOCALEXPIRES_TIMER, H_HANDLE_LOCALEXPIRES_TIMER}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_INVITE_ALERTING - */ - {SIP_STATE_RECV_INVITE_ALERTING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_CANCEL ccsip_handle_disconnect_remote, */ - {E_SIP_CANCEL, H_DISCONNECT_REMOTE}, - /* E_CC_CONNECTED ccsip_handle_recvinvite_ev_cc_connected, */ - {E_CC_CONNECTED, H_RECVINVITE_EV_CC_CONNECTED}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_unanswered, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_UNANSWERED}, - /* E_SIP_INV_LOCALEXPIRES_TIMER ccsip_handle_localexpires_timer */ - {E_SIP_INV_LOCALEXPIRES_TIMER, H_HANDLE_LOCALEXPIRES_TIMER}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_SIP_2xx ccsip_handle_recvinvite_ev_sip_2xx */ - {E_SIP_2xx, H_RECVINVITE_EV_SIP_2XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_INVITE_CONNECTED - */ - {SIP_STATE_RECV_INVITE_CONNECTED, - { - /* E_SIP_ACK ccsip_handle_recvinvite_ev_sip_ack, */ - {E_SIP_ACK, H_RECVINVITE_EV_SIP_ACK}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_INV_EXPIRES_TIMER ccsip_handle_recvinvite_ev_expires_timer */ - {E_SIP_INV_EXPIRES_TIMER, H_RECVINVITE_SENTOK_NO_SIP_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_ACTIVE - */ - {SIP_STATE_ACTIVE, - { - /* E_SIP_INVITE ccsip_handle_active_ev_sip_invite, */ - {E_SIP_INVITE, H_ACTIVE_EV_SIP_INVITE}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_2xx ccsip_handle_active_2xx, */ - {E_SIP_2xx, H_ACTIVE_2xx}, - /* E_SIP_REFER ccsip_handle_refer_sip_message, */ - {E_SIP_REFER, H_REFER_SIP_MESSAGE}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_CC_FEATURE ccsip_handle_active_ev_cc_feature, */ - {E_CC_FEATURE, H_ACTIVE_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_active_ev_cc_feature_ack, */ - {E_CC_FEATURE_ACK, H_ACTIVE_EV_CC_FEATURE_ACK}, - /* E_SIP_UPDATE ccsip_handle_active_ev_sip_update */ - {E_SIP_UPDATE, H_CONFIRM_EV_SIP_UPDATE}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_SENT_MIDCALL_INVITE - */ - {SIP_STATE_SENT_MIDCALL_INVITE, - { - /* E_SIP_INVITE ccsip_handle_active_ev_sip_invite, */ - {E_SIP_INVITE, H_ACTIVE_EV_SIP_INVITE}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_2xx ccsip_handle_sentinvite_midcall_ev_sip_2xx, */ - {E_SIP_2xx, H_SENTINVITE_MIDCALL_EV_SIP_2XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - /* E_SIP_INV_EXPIRES_TIMER ccsip_handle_disconnect_local */ - {E_SIP_INV_EXPIRES_TIMER, H_DISCONNECT_LOCAL}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_CC_FEATURE ccsip_handle_sentinvite_midcall_ev_cc_feature, */ - {E_CC_FEATURE, H_SENTINVITE_MIDCALL_EV_CC_FEATURE}, - /* E_SIP_UPDATE ccsip_handle_active_ev_sip_update */ - {E_SIP_UPDATE, H_CONFIRM_EV_SIP_UPDATE}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING - */ - {SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_media_change, */ - {E_CC_RELEASE, H_DISCONNECT_MEDIA_CHANGE}, - /* E_CC_FEATURE_ACK ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack, */ - {E_CC_FEATURE_ACK, H_RECVMIDCALLINVITE_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE, ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_RECV_MIDCALLINVITE_SIPACK_PENDING - */ - {SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING, - { - /* E_SIP_ACK ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack, */ - {E_SIP_ACK, H_RECVMIDCALLINVITE_SIPACKPENDING_EV_SIP_ACK}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE, ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RELEASE - */ - {SIP_STATE_RELEASE, - { - /* E_SIP_BYE, ccsip_handle_release_ev_sip_bye */ - {E_SIP_BYE, H_BYE_RELEASE}, - /* E_SIP_ACK ccsip_handle_recv_error_response_ev_sip_ack, */ - {E_SIP_ACK, H_RECV_ERR_EV_SIP_ACK}, - /* E_SIP_INVITE ccsip_handle_sentbye_recvd_invite, */ - {E_SIP_INVITE, H_SENTBYE_EV_SIP_INVITE}, - /* E_SIP_1xx ccsip_handle_sentbye_ev_sip_1xx, */ - {E_SIP_1xx, H_SENTBYE_EV_SIP_1XX}, - /* E_SIP_2xx ccsip_handle_sentbye_ev_sip_2xx, */ - {E_SIP_2xx, H_SENTBYE_EV_SIP_2XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentbye_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTBYE_EV_SIP_FXX}, - /* E_SIP_SUPERVISION_DISCONNECT_TIMER - * ccsip_handle_sendbye_ev_supervision_disconnect, */ - {E_SIP_SUPERVISION_DISCONNECT_TIMER, H_SENTBYE_SUPERVISION_DISCONNECT_TIMER}, - /* E_CC_RELEASE_COMPLETE, ccsip_handle_release_complete, */ - {E_CC_RELEASE_COMPLETE, H_RELEASE_COMPLETE}, - /* E_SIP_UPDATE ccsip_handle_sentbye_recvd_invite, */ - {E_SIP_UPDATE, H_SENTBYE_EV_SIP_INVITE}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE ccsip_handle_release_ev_cc_feature, */ - {E_CC_FEATURE, H_RELEASE_EV_CC_FEATURE}, - /* E_CC_RELEASE, ccsip_handle_release_ev_release, */ - {E_CC_RELEASE, H_RELEASE_EV_RELEASE}, - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_BLIND_XFER_PENDING, - */ - - {SIP_STATE_BLIND_XFER_PENDING, - { - /* E_SIP_BYE, ccsip_handle_release_ev_sip_bye */ - {E_SIP_BYE, H_BYE_RELEASE}, - /* E_SIP_2xx ccsip_handle_sentblindntfy_ev_sip_2xx, */ - {E_SIP_2xx, H_SENT_BLINDNTFY}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentbye_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTBYE_EV_SIP_FXX}, - /* E_CC_FEATURE ccsip_handle_send_blind_notify, */ - {E_CC_FEATURE, H_BLIND_NOTIFY}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - - } - }, - - {SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING, - { - /* E_SIP_TIMER, ccsip_handle_default_sip_timer */ - {E_SIP_TIMER, H_DEFAULT_SIP_TIMER}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE ccsip_handle_default_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_EV_CC_FEATURE}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - {SIP_STATE_SENT_OOD_REFER, - { - {E_SIP_1xx, H_OOD_REFER_RESPONSE_EV_SIP_1xx}, - {E_SIP_2xx, H_OOD_REFER_RESPONSE_EV_SIP_2xx}, - {E_SIP_3xx, H_OOD_REFER_RESPONSE_EV_SIP_fxx}, - {E_SIP_FAILURE_RESPONSE, H_OOD_REFER_RESPONSE_EV_SIP_fxx}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - {SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_media_change, */ - {E_CC_RELEASE, H_DISCONNECT_MEDIA_CHANGE}, - /* E_CC_FEATURE_ACK ccsip_handle_recvupdatenewmedia_ccfeatureackpending_ev_cc_feature_ack, */ - {E_CC_FEATURE_ACK, H_RECVUPDATEMEDIA_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE, ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - -}; - -static const sipSMEventActionFn_t - gSIPHandlerTable[SIPSPI_EV_INDEX_END - SIPSPI_EV_INDEX_BASE + 1] = { - - /*0*//* H_IDLE_EV_SIP_INVITE, */ - ccsip_handle_idle_ev_sip_invite, - - /*1*//* H_IDLE_EV_CC_SETUP, */ - ccsip_handle_idle_ev_cc_setup, - - /*2*//* H_SENTINVITE_EV_SIP_1XX, */ - ccsip_handle_sentinvite_ev_sip_1xx, - - /*3*//* H_SENTINVITE_EV_SIP_2XX, */ - ccsip_handle_sentinvite_ev_sip_2xx, - - /*4*//* H_SENTINVITE_EV_SIP_FXX, */ - ccsip_handle_sentinvite_ev_sip_fxx, - - /*5*//* H_DISCONNECT_LOCAL_EARLY, */ - ccsip_handle_disconnect_local_early, - - /*6*//* H_DISCONNECT_REMOTE, */ - ccsip_handle_disconnect_remote, - - /*7*//* H_SENTINVITECONNECTED_EV_CC_CONNECTED_ACK, */ - ccsip_handle_sentinviteconnected_ev_cc_connected_ack, - - /*8*//* H_DISCONNECT_LOCAL, */ - ccsip_handle_disconnect_local, - - /*9*//* H_RECVINVITE_EV_CC_SETUP_ACK, */ - ccsip_handle_recvinvite_ev_cc_setup_ack, - - /*10*//* H_RECVINVITE_EV_CC_PROCEEDING, */ - ccsip_handle_recvinvite_ev_cc_proceeding, - - /*11*//* H_RECVINVITE_EV_CC_ALERTING, */ - ccsip_handle_recvinvite_ev_cc_alerting, - - /*12*//* H_RECVINVITE_EV_CC_CONNECTED, */ - ccsip_handle_recvinvite_ev_cc_connected, - - /*13*//* H_DISCONNECT_LOCAL_UNANSWERED, */ - ccsip_handle_disconnect_local_unanswered, - - /*14*//* H_RECVINVITE_EV_SIP_ACK, */ - ccsip_handle_recvinvite_ev_sip_ack, - - /*15*//* H_ACTIVE_EV_SIP_INVITE, */ - ccsip_handle_active_ev_sip_invite, - - /*16*//* H_ACTIVE_EV_CC_FEATURE, */ - ccsip_handle_active_ev_cc_feature, - - /*17*//* H_ACCEPT_2XX, */ - ccsip_handle_accept_2xx, - - /*18*//* H_REFER_SIP_MESSAGE, */ - ccsip_handle_refer_sip_message, - - /*19*//* H_ACTIVE_EV_CC_FEATURE_ACK, */ - ccsip_handle_active_ev_cc_feature_ack, - - /*20*//* H_SENTINVITE_MIDCALL_EV_SIP_2XX, */ - ccsip_handle_sentinvite_midcall_ev_sip_2xx, - - /*21*//* H_SENTINVITE_MIDCALL_EV_CC_FEATURE, */ - ccsip_handle_sentinvite_midcall_ev_cc_feature, - - /*22*//* H_RECVMIDCALLINVITE_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK */ - ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack, - - /*23*//* H_RECVMIDCALLINVITE__SIPACKPENDING_EV_SIP_ACK, */ - ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack, - - /*24*//* H_DEFAULT_SIP_MESSAGE, */ - ccsip_handle_default_sip_message, - - /*25*//* H_DEFAULT_SIP_RESPONSE, */ - ccsip_handle_default_sip_response, - - /*26*//* H_DEFAULT, */ - ccsip_handle_default, - - /*27*//* H_SIP_INV_EXPIRES_TIMER */ - ccsip_handle_disconnect_local_early, - - /*28*//* H_SIP_OPTIONS, */ - ccsip_handle_process_in_call_options_request, - - /*29*//* H_SENTINVITE_EV_SIP_3XX, */ - ccsip_handle_sentinvite_ev_sip_3xx, - - /*30*//*H_RECV_ERR_EV_SIP_ACK */ - ccsip_handle_recv_error_response_ev_sip_ack, - - /*31*//*H_SENTBYE_EV_SIP_2XX */ - ccsip_handle_sentbye_ev_sip_2xx, - - /*32*//*H_SENTBYE_EV_SIP_1XX */ - ccsip_handle_sentbye_ev_sip_1xx, - - /*33*//*H_SENTBYE_EV_SIP_FXX */ - ccsip_handle_sentbye_ev_sip_fxx, - - /*34*//*H_SENTBYE_EV_SIP_INVITE */ - ccsip_handle_sentbye_recvd_invite, - - /*35*//*H_SENTBYE_SUPERVISION_DISCONNECT_TIMER */ - ccsip_handle_sendbye_ev_supervision_disconnect, - - /*36*//*H_RELEASE_COMPLETE */ - ccsip_handle_release_complete, - - /*37*//*H_ACTIVE_2xx */ - ccsip_handle_active_2xx, - - /*38*//*H_BLIND_NOTIFY */ - ccsip_handle_send_blind_notify, - - /*39*//*H_SENT_BLINDNTFY */ - ccsip_handle_sentblindntfy_ev_sip_2xx, - - /*40*//*H_BYE_RELEASE, */ - ccsip_handle_release_ev_sip_bye, - - /*41*//*H_HANDLE_LOCALEXPIRES_TIMER, */ - ccsip_handle_localexpires_timer, - - /*42*//*H_DEFAULT_SIP_TIMER */ - ccsip_handle_default_sip_timer, - - /*43*//*H_EARLY_EV_SIP_UPDATE */ - ccsip_handle_early_ev_sip_update, - - /*44*//*H_EARLY_EV_SIP_UPDATE_RESPONSE */ - ccsip_handle_early_ev_sip_update_response, - - /*45*//*H_EARLY_EV_CC_FEATURE */ - ccsip_handle_early_ev_cc_feature, - - /*46*//*H_EARLY_EV_CC_FEATURE_ACK */ - ccsip_handle_early_ev_cc_feature_ack, - - /*47*//*H_CONFIRM_EV_SIP_UPDATE */ - ccsip_handle_active_ev_sip_update, - - /*48*//*H_RECVUPDATEMEDIA_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK */ - ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack, - - /*49*//*H_SIP_GLARE_AVOIDANCE_TIMER */ - ccsip_handle_timer_glare_avoidance, - - /*50*//*H_RECVINVITE_SENTOK_NO_SIP_ACK */ - ccsip_handle_recvinvite_ev_expires_timer, - - /*51*//*H_EV_SIP_UNSOLICITED_NOTIFY */ - ccsip_handle_unsolicited_notify, - - /*52*//*H_RECVINVITE_EV_SIP_2XX, */ - ccsip_handle_recvinvite_ev_sip_2xx, - - /*53*//*H_ICMP_UNREACHABLE, */ - ccsip_handle_icmp_unreachable, - - /*54*//*H_DISCONNECT_MEDIA_CHANGE, */ - ccsip_handle_disconnect_media_change, - - /*55*//*H_DEFAULT_EV_CC_FEATURE, */ - ccsip_handle_default_ev_cc_feature, - - /*56*//*H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE */ - ccsip_handle_default_recvreq_ack_pending_ev_cc_feature, - - /*57*//*H_OOD_REFER_RESPONSE_EV_SIP_1xx */ - ccsip_handle_sent_ood_refer_ev_sip_1xx, - - /*58*//*H_OOD_REFER_RESPONSE_EV_SIP_2xx */ - ccsip_handle_sent_ood_refer_ev_sip_2xx, - - /*59*//*H_OOD_REFER_RESPONSE_EV_SIP_fxx */ - ccsip_handle_sent_ood_refer_ev_sip_fxx, - - /*60*//* H_RELEASE_EV_CC_FEATURE, */ - ccsip_handle_release_ev_cc_feature, - - /*61*//* H_EV_CC_INFO, */ - ccsip_handle_ev_cc_info, - - /*62*//* H_RELEASE_EV_RELEASE, */ - ccsip_handle_release_ev_release, -}; - -static uint32_t get_callref(const char *tag) { - int32_t i, callref = 0; - const char * ref; - - for ( i = (strlen(tag)-1); i >= 0; i--) { - ref = &tag[i]; - if ( *ref == '-' ) { - sscanf ( ref, "-%d", &callref); - break; - } - } - return callref; -} - -sipSMAction_t -get_handler_index (sipSMStateType_t isipsmstate, sipSMEventType_t isipsmevent) -{ - int16_t i; - - if ((isipsmstate < SIP_STATE_BASE) || (isipsmstate > SIP_STATE_END) || - (isipsmevent < SIPSPI_EV_BASE) || (isipsmevent > SIPSPI_EV_END)) { - CSFLogDebug("sipstack", "value of event passed isipsmevent=%d " - "value of state = %d, " - "SIP_STATE_BASE = %d, SIP_STATE_END = %d, SIPSPI_EV_BASE = %d," - " SIPSPI_EV_END = %d", - isipsmstate, isipsmevent, SIP_STATE_BASE, SIP_STATE_END, - SIPSPI_EV_BASE, SIPSPI_EV_END); - - return H_INVALID_EVENT; - } - - for (i = 0; i < MAX_STATE_EVENTS; i++) { - if (g_sip_table[isipsmstate].validEvent[i].sipValidEvent == (int16_t)isipsmevent) { - return ((sipSMAction_t) g_sip_table[isipsmstate].validEvent[i].actionIndex); - } - } - switch (isipsmevent) { - case E_SIP_INVITE: - case E_SIP_UPDATE: - case E_SIP_ACK: - case E_SIP_BYE: - case E_SIP_REFER: - case E_SIP_CANCEL: - return H_DEFAULT_SIP_MESSAGE; - case E_SIP_1xx: - case E_SIP_2xx: - case E_SIP_3xx: - case E_SIP_FAILURE_RESPONSE: - return H_DEFAULT_SIP_RESPONSE; - case E_SIP_TIMER: - return H_DEFAULT_SIP_TIMER; - - case E_SIP_OPTIONS: - return H_SIP_OPTIONS; - - case E_SIP_GLARE_AVOIDANCE_TIMER: - return H_SIP_GLARE_AVOIDANCE_TIMER; - - case E_SIP_ICMP_UNREACHABLE: - return H_ICMP_UNREACHABLE; - - default: - break; - } - return H_DEFAULT; -} - - -void -sip_sm_change_state (ccsipCCB_t *ccb, sipSMStateType_t new_state) -{ - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Change state %s -> %s", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, "sip_sm_change_state"), - sip_util_state2string(ccb->state), - sip_util_state2string(new_state)); - - if (ccb->state == SIP_STATE_RELEASE && - new_state == SIP_STATE_IDLE) { - /* Just add call marker in the log */ - DEF_DEBUG("==================================================="); - } - - /* - * If we are moving out of SIP_STATE_RELEASE, then stop the - * supervision timer if it has been started - */ - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - - ccb->state = new_state; - - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_start(SUPERVISION_DISCONNECT_TIMEOUT, - ccb->index); - } -} - -/* - * Function: sip_util_extract_sdp() - * - * Parameters: ccb - The current call control block - * message - The sip message to parse - * - * Description: This routine parses the indicated message for SDP. - * - * Returns: sip_sdp_status_t - An enum which contains several return codes - * - * Note: The SIP_SDP_DNS_FAIL will not be returned from this - * function because GSM also handles DNS look up. The rest of - * this module should still check for the SIP_SDP_DNS_FAIL value - * for the return code of this function. They should be kept just - * in case that there is a need for SIP to check DNS for some - * reason in the future. - */ -static sipsdp_status_t -sip_util_extract_sdp (ccsipCCB_t *ccb, sipMessage_t *message) -{ - const char *fname = "sip_util_extract_sdp"; - // const char *content_type; - uint8_t content_type = 0; - int content_length = 0; - cc_sdp_t *sip_msg_sdp = NULL; - u16 i = 0; - sipsdp_status_t retval = SIP_SDP_NOT_PRESENT; - char *sdp_data = NULL; // message->mesg_body; - uint16_t num_m_lines; - - /* - * Check to see if SDP is present in this message - */ - // Go through the different body types to see if there is an - // SDP body - if (message->num_body_parts == 0) { - content_length = 0; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"\nmultipart/mixed No SDP Found!", DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - } else { - for (i = 0; i < message->num_body_parts; i++) { - if (message->mesg_body[i].msgContentTypeValue == - SIP_CONTENT_TYPE_SDP_VALUE) { - content_type = SIP_CONTENT_TYPE_SDP_VALUE; - content_length = message->mesg_body[i].msgLength; - sdp_data = message->mesg_body[i].msgBody; - break; - } - } - } - - /* - * Check for content - */ - if ((content_type != SIP_CONTENT_TYPE_SDP_VALUE) || - (content_length <= 0)) { - /* there is no SDP content or no content */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), ccb->index, - ccb->dn_line, fname, "No SDP"); - return (SIP_SDP_NOT_PRESENT); - } - - /* - * Allocate a SDP buffer to work with (only destination buffer is needed). - * - * Here we are handing in an empty string to designate that we are not - * in the context of a peerconnection object - */ - sipsdp_src_dest_create("", CCSIP_DEST_SDP_BIT, &sip_msg_sdp); - if ((sip_msg_sdp == NULL) || (sip_msg_sdp->dest_sdp == NULL)) { - /* Unable to get SDP */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SDP_CREATE_BUF_ERROR), - fname); - return (SIP_SDP_ERROR); - } - /* - * Pasrse the SDP body - */ - if (sdp_parse(sip_msg_sdp->dest_sdp, &sdp_data, - (uint16_t)content_length) != SDP_SUCCESS) { - /* unable to parse the SDP */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_PARSE_SDP_ERROR), fname); - - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT, &sip_msg_sdp); - return (SIP_SDP_ERROR); - } - - /* - * Verify that there are media lines present - */ - num_m_lines = sdp_get_num_media_lines(sip_msg_sdp->dest_sdp); - if (num_m_lines == 0) { - /* No media lines in the SDP body */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Process SDP, no media"); - retval = SIP_SDP_NO_MEDIA; - } else { - /* There is at least a media line in the SDP */ - retval = SIP_SDP_SUCCESS; - - /* - * Check to see if the sdp->session_id and version_id are - * the same. If they are, it could be a session audit. - * In most cases, this is handled the same as - * SIP_SDP_SUCCESS. - */ - if (sip_msg_sdp->dest_sdp) { - const char *new_session_id = NULL; - const char *new_version_id = NULL; - - new_session_id = sdp_get_owner_sessionid(sip_msg_sdp->dest_sdp); - new_version_id = sdp_get_owner_version(sip_msg_sdp->dest_sdp); - - if ((ccb->old_session_id) && (ccb->old_version_id) && - (new_session_id) && (new_version_id)) { - if ((!(strcmp(ccb->old_session_id, new_session_id))) && - (!(strcmp(ccb->old_version_id, new_version_id)))) { - retval = SIP_SDP_SESSION_AUDIT; - } - } - - if (ccb->old_session_id != NULL) { - cpr_free(ccb->old_session_id); - ccb->old_session_id = NULL; - } - if (ccb->old_version_id != NULL) { - cpr_free(ccb->old_version_id); - ccb->old_version_id = NULL; - } - if ((new_session_id) && (new_version_id)) { - ccb->old_session_id = cpr_strdup(new_session_id); - ccb->old_version_id = cpr_strdup(new_version_id); - } - } - } - /* free the SDP buffer */ - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT, &sip_msg_sdp); - return (retval); -} - -/* - * Function: ccsip_save_local_msg_body - * - * Parameters: ccb - The pointer to ccsipCCB to save message body sent - * by GSM. - * msg_body - pointer to a new msg body to be saved. - * - * Description: This routine saves the message bodies sent by GSM via CCAPI. - * If there is a previous message, the previous messages will - * be freed before the current one is saved. - * - * Returns: void - * - */ -static void -ccsip_save_local_msg_body (ccsipCCB_t *ccb, cc_msgbody_info_t *msg_body) -{ - if ((msg_body == NULL) || (msg_body->num_parts == 0)) { - return; - } - - /* - * Move the new bodies to the local_msg_body, the previous - * msg. bodies will be freed by the move function - */ - cc_mv_msg_body_parts(&ccb->local_msg_body, msg_body); -} - -/* - * Function: sip_redirect - * - * Parameters: ccb, response to invite request, status code of - * response. - * - * Description: Will create a new invite with contact information - * received in Redirection response to previous invite - * Will clear up the call if all the contacts have been - * used and no 2xx final response has been received. - * - * Returns: - * - */ -void -sip_redirect (ccsipCCB_t *ccb, sipMessage_t *response, uint16_t status_code) -{ - const char *fname = "sip_redirect"; - sipRedirectInfo_t *redirect_info; - const char *contact; - sipLocation_t *sipLocation; - sipUrl_t *pContactURL = NULL; - char *diversion[MAX_DIVERSION_HEADERS]; - char *str_temp = NULL; - char ui_str[STATUS_LINE_MAX_LEN]; - int i = 0; - boolean sent_invite = FALSE; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t diversion_count, cc_diversion_count, max_headers; - size_t to_length; - char tmp_str[STATUS_LINE_MAX_LEN]; - char stored_to_header[MAX_SIP_URL_LENGTH]; - char *temp = NULL; - - - CPR_IP_ADDR_INIT(cc_remote_ipaddr); - - while (!sent_invite) { - if (ccb->redirect_info == NULL) { - - /* Redirected for the first time allocating redirect_info */ - redirect_info = (sipRedirectInfo_t *) - cpr_malloc(sizeof(sipRedirectInfo_t)); - if (redirect_info == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "malloc(redirect_info)"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - redirect_info->sipContact = NULL; - redirect_info->next_choice = 0; - ccb->redirect_info = redirect_info; - } else { - redirect_info = ccb->redirect_info; - } - - /* - * Now we are clearing the record-route information since we - * want redirected invite to use contact header. New transaction - * will start now and that will be using new record-route information, - * if any. - */ - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - if (redirect_info->next_choice >= SIP_MAX_LOCATIONS) { - /* Exhausted all Choices */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Exhausted all Contacts"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - - if ((status_code >= SIP_RED_MULT_CHOICES && - status_code <= SIP_RED_USE_PROXY) && - (ccb->first_pass_3xx == TRUE)) { - /* 300, 301, 302 and 305 must have contact header */ - - /* - * We have already initialized the redirect_info with the - * contact info once, so the next time through the loop - * skip this part. - */ - ccb->first_pass_3xx = FALSE; - - if ((platGetPhraseText(STR_INDEX_CALL_REDIRECTED, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - memset(ui_str, 0, sizeof(ui_str)); - snprintf(ui_str, sizeof(ui_str), "%s (in %d)", - tmp_str, status_code); - ui_set_call_status(ui_str, ccb->dn_line, ccb->gsm_id); - } - - if (redirect_info->sipContact) { - /* Delete previously stored contact */ - sippmh_free_contact(redirect_info->sipContact); - redirect_info->sipContact = NULL; - } - - contact = sippmh_get_cached_header_val(response, CONTACT); - redirect_info->sipContact = sippmh_parse_contact(contact); - if ((redirect_info->sipContact == NULL) - || (contact == NULL)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_contact()"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - /* - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = redirect_info->sipContact; - */ - - sipLocation = redirect_info->sipContact->locations[0]; - redirect_info->next_choice = 1; - - //if we are a part of a transfer we are going to need this. - //save the Contact value returned in 30x as the AOR for - //value to be populated in a later REFER's Refer-To - ccb->sip_referTo = strlib_update(ccb->sip_referTo, contact); - - } else { - /* We should try next location in previous Contact */ - - if ((redirect_info->sipContact == NULL) || - (redirect_info->next_choice >= - redirect_info->sipContact->num_locations)) { - /* Exhausted all Choices */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Exhausted all Contacts"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - sipLocation = redirect_info->sipContact->locations - [redirect_info->next_choice++]; - } - - /* - * Get the CC-Diversion parameter (if any). - */ - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - diversion[i] = NULL; - } - /* - * We need to to compliment to old CC-Diversion and CC_Redirect. - * We will either be getting CC_Diversion or Diversion or - * CC_Redirect, which are all basically same. - * - * So instead of changing it on the parser level I would prefer - * to do it at SIP level. The following code first looks for - * Diversion then looks for CC_Diversion and then at last - * priority looks for CC_Redirect - */ - diversion_count = sippmh_get_num_particular_headers(response, - SIP_HEADER_DIVERSION, - SIP_HEADER_DIVERSION, - diversion, MAX_DIVERSION_HEADERS); - max_headers = MAX_DIVERSION_HEADERS - diversion_count; - cc_diversion_count = sippmh_get_num_particular_headers(response, - SIP_HEADER_CC_DIVERSION, - SIP_HEADER_CC_DIVERSION, - &diversion[diversion_count], - max_headers); - max_headers = MAX_DIVERSION_HEADERS - diversion_count - cc_diversion_count; - (void) sippmh_get_num_particular_headers(response, - SIP_HEADER_CC_REDIRECT, - SIP_HEADER_CC_REDIRECT, - &diversion[diversion_count + cc_diversion_count], - max_headers); - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - if (diversion[i]) { - int len = 0; - - len = strlen(diversion[i]); - if (ccb->diversion[i]) { - cpr_free(ccb->diversion[i]); - ccb->diversion[i] = NULL; - } - ccb->diversion[i] = (char *) cpr_malloc(len + 2); - if (ccb->diversion[i]) { - sstrncpy(ccb->diversion[i], diversion[i], len + 1); - } else { - CCSIP_DEBUG_ERROR(DEB_L_C_F_PREFIX"No memory left;" - "Ignoring CC-Diversion header #%d %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, i + 1); - } - } - } - - /* - * Ignore TEL URLs so loop through until we hit SIP URL. - */ - while ((sipLocation) && - (redirect_info->next_choice < SIP_MAX_LOCATIONS) && - (sipLocation->genUrl->schema != URL_TYPE_SIP)) { - sipLocation = redirect_info->sipContact->locations - [redirect_info->next_choice++]; - } - - if (!sipLocation) { - /* Exhausted all Choices */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Exhausted all Contacts"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - - pContactURL = sipLocation->genUrl->u.sipUrl; - - /* - * Initially, set the port to the port contained in the ContactURL. Then - * do a DNS Lookup on the host. If we get a new port in the response, we - * will use that when building the Request URI. - */ - ccb->dest_sip_port = pContactURL->port; - - if (!pContactURL->port_present) { - /* Set the IP-level destination ipaddr and port in the ccb */ - dns_error_code = sipTransportGetServerAddrPort(pContactURL->host, - &cc_remote_ipaddr, - (uint16_t *) &ccb->dest_sip_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(pContactURL->host, &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code == 0) { - util_ntohl(&(ccb->dest_sip_addr), &cc_remote_ipaddr); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportGetServerAddrPort or dnsGetHostByName()"); - - /* - * If DNS Lookup fails and there are more contacts, loop back up and try the next one. - * If we're out of contacts, then just release the call. - */ - if (redirect_info->next_choice < SIP_MAX_LOCATIONS) { - continue; - } else { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - return; - } - - /* - * Get rid of transaction block for the ccb, we may have - * tried previous proxy in the Contact list - */ - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - - /* - * Make new Req-URI and To values - */ - - temp = strstr(ccb->sip_to, ";tag"); - to_length = (temp != NULL) ? (strlen(ccb->sip_to) - strlen(temp)) : MAX_SIP_URL_LENGTH; - if (to_length < MAX_SIP_URL_LENGTH) { - sstrncpy(stored_to_header, ccb->sip_to, to_length + 1); - } else { - sstrncpy(stored_to_header, ccb->sip_to, MAX_SIP_URL_LENGTH); - } - - str_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - snprintf(str_temp, MAX_SIP_URL_LENGTH, "%s", stored_to_header); - ccb->sip_to = strlib_close(str_temp); - - if (pContactURL->maddr) { - if (pContactURL->user) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - "sip:%s%s%s@%s:%d;maddr=%s%s", - pContactURL->user, - (pContactURL->password ? ":" : ""), - (pContactURL->password ? pContactURL->password : ""), - pContactURL->host, - ccb->dest_sip_port, - pContactURL->maddr, - (pContactURL->is_phone ? ";user=phone" : "")); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - pContactURL->is_phone ? "sip:%s:%d;maddr=%s;user=phone" - : "sip:%s:%d;maddr=%s", - pContactURL->host, ccb->dest_sip_port, - pContactURL->maddr); - } - } else { - if (pContactURL->user) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - "sip:%s%s%s@%s:%d%s", - pContactURL->user, - (pContactURL->password ? ":" : ""), - (pContactURL->password ? pContactURL->password : ""), - pContactURL->host, - ccb->dest_sip_port, - (pContactURL->is_phone ? ";user=phone" : "")); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - pContactURL->is_phone ? "sip:%s:%d;user=phone" : "sip:%s:%d", - pContactURL->host, ccb->dest_sip_port); - } - } - - - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, ""); // Removing To Tag - ccb->authen.cred_type = 0; - - ccb->last_recv_request_cseq = 0; - ccb->last_recv_request_cseq_method = sipMethodInvalid; - - /* - * Send out a new INVITE - */ - if (sipSPISendInvite(ccb, SIP_INVITE_TYPE_REDIRECTED, FALSE) == TRUE) { - sent_invite = TRUE; - } else { - status_code = SIP_1XX_TRYING; - } - } - return; - -} - -/* - * Function: parseAlertingHeader - * - * Parameters: ccb: call control block - * header: The Alert-Info header - * - * Description: Parses the alert-info header to - * determine if the value is a known - * internal ringer or tone. - * - * Note: Defaults to inside ring so that is what will be - * played if any errors are encountered - * during processing or if the header is not a - * recognized value. - * - */ -void -parseAlertingHeader (ccsipCCB_t *ccb, const char *header) -{ - char alertHeader[MAX_SIP_URL_LENGTH]; - char *pAlertHeader; - char *input = NULL; - unsigned int counter = 0; - - /* - * Since alertHeader is a const char and - * we need to modify it, copy the header - * into a char * Easier to do this than - * modify SIP core to pass around a char * - */ - sstrncpy(alertHeader, header, MAX_SIP_URL_LENGTH); - pAlertHeader = alertHeader; - - /* - * Check for malformed url. - * Is opening < present? - */ - if (*pAlertHeader == '<') { - pAlertHeader++; - - /* Eat any leading white space */ - while (isspace((int)*pAlertHeader)) { - pAlertHeader++; - } - - /* Is trailing > present? */ - input = pAlertHeader; - pAlertHeader = strchr(input, '>'); - if (pAlertHeader != NULL) { - /* - * Overwrite > with NULL to terminate - * ringer name - */ - *pAlertHeader = NUL; - - /* - * Check input against the list of - * internal ringers. The bellcore - * ringers were added to the end of - * the ringer list so add the offset - * to match them up correctly - */ - for (counter = 0; counter <= VCM_BELLCORE_MAX - VCM_RING_OFFSET; counter++) { - if (strstr(input, ring_names[counter]) != NULL) { - ccb->alert_info = ALERTING_RING; - ccb->alerting_ring = (vcm_ring_mode_t) (counter + - VCM_RING_OFFSET); - return; - } - } - - /* - * Check input against the list of internal - * tones. - */ - for (counter = 0; counter < VCM_MAX_DIALTONE; counter++) { - if (strstr(input, tone_names[counter]) != NULL) { - ccb->alert_info = ALERTING_TONE; - ccb->alerting_tone = (vcm_tones_t) counter; - return; - } - } - } - } - - /* - * Error case. Malformed URL, external tone/ring pattern - * or unknown internal tone/ring pattern. Mimic old - * behavior. - */ - ccb->alert_info = ALERTING_OLD; - ccb->alerting_ring = VCM_INSIDE_RING; -} - -/* - * Function: ccsip_is_special_name_to_mask_display_number - * - * Parameters: name - name to be checked for special string. - * - * Description: The function checks the given name whether it matches - * a special display name or not. It is used to determined - * whether its associated number should be displayed or not. - * - * Return: TRUE - the given name is a special name. - * FALSE - the given name is not a special name. - */ -boolean -ccsip_is_special_name_to_mask_display_number (const char *name) -{ - const char *special_string; - - if (name == NULL) { - /* No name given ? */ - return (FALSE); - } - /* - * Check for special name such as Conference or Barge. The CCM may - * sends string that is longer than the key words to match. Compare - * exactly (not even including NULL character). - */ - special_string = platform_get_phrase_index_str(UI_CONFERENCE); - if ((cpr_strncasecmp(name, special_string, strlen(special_string)) == 0) || - (cpr_strncasecmp(name, CONFERENCE_STR, CONFERENCE_STR_LEN) == 0)) { - return (TRUE); - } - - /* - * The Barge 2 byte code is not in the phrase index table currently. Just - * use the define value. - */ - if (cpr_strncasecmp(name, INDEX_STR_BARGE, 2) == 0) { - return (TRUE); - } - - /* - * Detect private display name for restricted call party number. - */ - if (cpr_strncasecmp(name, INDEX_STR_PRIVATE, 2) == 0) { - return (TRUE); - } - - /* - * Detect monitoring display number. - */ - if (cpr_strncasecmp(name, INDEX_STR_MONITORING, 2) == 0) { - return (TRUE); - } - - /* - * Detect coaching display number. - */ - if (cpr_strncasecmp(name, INDEX_STR_COACHING, 2) == 0) { - return (TRUE); - } - - return (FALSE); -} - - -/* - * Function: unescape_UserInfo - * - * Parameters: esc_str: input escaped string containing "userinfo@host" or "userinfo" - * unesc_str: output unescaped string with escape chars unescaped - * unesc_str_len: length of unescaped string - * Description: Parses the input string to check if escaped chars are present and - * unescape them. - * Return: TRUE if escaped input exists and unescaped in output. Else FALSE. - * - * Note: -memory must be allocated by caller and freed as needed by caller. This - * function expects enough space for the string. - * -CSCsz30816: This function previously unescapes only up to @ and returns - * the unescaped data (along with the un-inspected host data). However, - * various usages in the code calls this with possible input string of - * "userinfo@host" or "userinfo" where "userinfo" could contain '@' which - * correctly needs not be escaped. Since the input is flexible as described, - * we've changed to escape the entire input string although the - * host portion, when present, should never has an escaped character anyway. - */ - -static boolean -unescape_UserInfo (const char *esc_str, char *unesc_str, - unsigned int unesc_str_len) -{ - char *user_info; - - /* Look for esc char % in the provided string */ - user_info = strpbrk(esc_str, "%"); - - if (user_info) { - if (unesc_str_len > strlen(esc_str)) { - unesc_str_len = strlen(esc_str); - } - sippmh_convertEscCharToChar(esc_str, unesc_str_len, unesc_str); - return TRUE; - } - - return (FALSE); -} - -/* - * Function: ccsip_identify_best_rpid - * - * Parameters: ccb: call control block - * calling: boolean value indicating if message is a - * request or response. - * - * Returns: boolean indicating if screened RPID found. - * - * Description: Identify the "best" Remote-Party-Id - * The top-most screened Remote-Party-ID header - * takes precedence. If none are screened, just - * use the top-most Remote-Party-Id header. - */ -static boolean -ccsip_identify_best_rpid (ccsipCCB_t *ccb, boolean request) -{ - unsigned int j; - sipRemotePartyId_t *rpid; - - ccb->best_rpid = ccb->rpid_info->rpid[0]; - - if (!ccb->best_rpid) { - return FALSE; - } - - for (j = 0; j < ccb->rpid_info->num_rpid; j++) { - rpid = ccb->rpid_info->rpid[j]; - if (rpid && - // screen check is disabled so that mid call party updates can be displayed - //rpid->screen && - //!cpr_strncasecmp(rpid->screen, SCREEN_YES, strlen(SCREEN_YES)) && - rpid->loc->genUrl->schema == URL_TYPE_SIP) { - /* party_type check is disabled so that the phone is more liberal in what it accepts for RPID */ - /* - * If RPID in a request, party must be set to calling. - * If RPID in a response, party must be set to called - */ - //if (rpid->party_type) { - // if ((request && (!cpr_strncasecmp(rpid->party_type, PARTY_TYPE_CALLING, - // strlen(PARTY_TYPE_CALLING)))) || - // (!request && (!cpr_strncasecmp(rpid->party_type, PARTY_TYPE_CALLED, - // strlen(PARTY_TYPE_CALLED))))) - // { - ccb->best_rpid = rpid; - return TRUE; - // } - //} - } - } - return FALSE; -} - -static void -ccsip_phrase_specifier (int16_t phrase, string_t * string, uint16_t len) -{ - char *temp_str; - char tmp_str[STATUS_LINE_MAX_LEN]; - - temp_str = strlib_open(*string, len); - if (temp_str) { - if (phrase == STR_INDEX_ANONYMOUS_SPACE) { - if ((platGetPhraseText(STR_INDEX_ANONYMOUS_SPACE, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - sstrncpy(temp_str, tmp_str, len); - } - } else { - sstrncpy(temp_str, platform_get_phrase_index_str(phrase), len); - } - } - *string = strlib_close(temp_str); -} - -/* - * Function: ccsip_check_set_privacy_screen - * - * Parameters: - * name : name returned here based on privacy and screen - * number : number returned here based on privacy and screen - * input_name: input name - * input_num: input number - * privacy: privacy - * screen: screen information - * connected_party: indicates that name/number are of the - * called/calling party - * - * Returns: TRUE if Number should be private - * - * Description: This function checkes privacy and screen information - * and based on that name and number parameter is calculated. - * - * Note: To align with SCCP display the number is not displayed if - * it is private. The Java UI code does not display anything - * if the string is an empty string. So at the beginning of - * the function set the number to "" and only update the number - * string if the number is to be displayed. In the case where - * the name and number represent the calling or called party, - * we need to provide the number to GSM in the event that this - * is the consultative call leg of an xfer. The xfer state machine - * requires a DN in order to complete the xfer. The connected_party - * boolean indicates whether the name/number are from the - * called or calling party. - */ -static boolean -ccsip_check_set_privacy_screen (string_t *name, string_t *number, - char *input_name, char *input_num, - char *privacy, char *screen, - boolean connected_party) -{ - char *name_str; - boolean number_private = FALSE; - - /* Initialize to empty required by UI */ - *name = strlib_update(*name, ""); - - *number = strlib_update(*number, ""); - - if (!privacy || cpr_strncasecmp(privacy, PRIVACY_FULL, sizeof(PRIVACY_FULL)) == 0) { - /* Ignore screen parameter now - * (cpr_strcasecmp(screen, SCREEN_NO) == 0)) { - */ - ccsip_phrase_specifier(UI_PRIVATE, name, MAX_SIP_DISPLAYNAME_LENGTH); - if (connected_party) { - /* - * name/number from connected party. number is required. - */ - ccsip_phrase_specifier(STR_INDEX_ANONYMOUS_SPACE, number, - MAX_SIP_URL_LENGTH * 2); - } - return TRUE; - } - - if (cpr_strncasecmp(privacy, PRIVACY_URI, sizeof(PRIVACY_URI)) == 0) { - - if ((input_name != NULL) && (*input_name != NUL)) { - *name = strlib_update(*name, input_name); - } else { - ccsip_phrase_specifier(UI_UNKNOWN, name, MAX_SIP_DISPLAYNAME_LENGTH); - } - if (connected_party) { - /* - * name/number from connected party. number is required. - */ - ccsip_phrase_specifier(STR_INDEX_ANONYMOUS_SPACE, number, - MAX_SIP_URL_LENGTH * 2); - } - number_private = TRUE; - } else if (cpr_strncasecmp(privacy, PRIVACY_NAME, sizeof(PRIVACY_NAME)) == 0) { - - if (input_num) { - *number = strlib_update(*number, input_num); - } - ccsip_phrase_specifier(UI_PRIVATE, name, MAX_SIP_DISPLAYNAME_LENGTH); - - } else { - - if ((input_name != NULL) && (*input_name != NUL)) { - *name = strlib_update(*name, input_name); - } else { - if (!input_num || (*input_num == NUL)) { - ccsip_phrase_specifier(UI_UNKNOWN, name, MAX_SIP_DISPLAYNAME_LENGTH); - } - } - - if (input_num) { - *number = strlib_update(*number, input_num); - } - } - - name_str = strlib_open(*name, MAX_SIP_DISPLAYNAME_LENGTH); - if (name_str) { - sip_sm_dequote_string(name_str, MAX_SIP_DISPLAYNAME_LENGTH); - } - *name = strlib_close(name_str); - return number_private; -} - -/* - * Function: ccsip_parse_diversion_header - * - * Parameters: ccb: call control block - * msg: SIP message to examine for RPID header - * - * Returns: boolean - * - * Description: Diversion header is used when the call is forwarded to this - * number. There are 2 different items that are extracted from diversion - * header, 1) originally called party 2) last redirecting party. - * On the Screen originally called party is shown as "By:.." and - * last redirecting party is shown as "From:..." - */ -static boolean -ccsip_parse_diversion_header (ccsipCCB_t *ccb, sipMessage_t *msg) -{ - char *diversion_headers[MAX_DIVERSION_HEADERS]; - unsigned int diversion_count; - sipDiversion_t *diversion_header; - - /* - * Free up previous diversion header info. - */ - sippmh_free_diversion_info(ccb->div_info); - - ccb->div_info = (sipDiversionInfo_t *) - cpr_malloc(sizeof(sipDiversionInfo_t)); - - if (!ccb->div_info) { - return FALSE; - } - - memset(ccb->div_info, 0, sizeof(sipDiversionInfo_t)); - memset(diversion_headers, 0, MAX_DIVERSION_HEADERS * sizeof(char *)); - - ccb->div_info->last_redirect_name = strlib_empty(); - ccb->div_info->last_redirect_number = strlib_empty(); - ccb->div_info->orig_called_name = strlib_empty(); - ccb->div_info->orig_called_number = strlib_empty(); - - - diversion_count = sippmh_get_num_particular_headers(msg, - SIP_HEADER_DIVERSION, - SIP_HEADER_DIVERSION, - diversion_headers, - MAX_DIVERSION_HEADERS); - - if (diversion_count < 1) { - return FALSE; - } - - ccb->call_type = CC_CALL_FORWARDED; - - /* We need 1st and last diversion headers only */ - diversion_header = sippmh_parse_diversion(diversion_headers[0], SIP_HEADER_DIVERSION); - - if (diversion_header) { - (void) ccsip_check_set_privacy_screen(&(ccb->div_info->last_redirect_name), - &(ccb->div_info->last_redirect_number), - diversion_header->locations->name, - diversion_header->locations->genUrl->u.sipUrl->user, - diversion_header->privacy, - diversion_header->screen, FALSE); - - sippmh_free_diversion(diversion_header); - } - - /* Parse last diversion header */ - diversion_header = sippmh_parse_diversion(diversion_headers[diversion_count - 1], - SIP_HEADER_DIVERSION); - - if (diversion_header) { - (void) ccsip_check_set_privacy_screen(&(ccb->div_info->orig_called_name), - &(ccb->div_info->orig_called_number), - diversion_header->locations->name, - diversion_header->locations->genUrl->u.sipUrl->user, - diversion_header->privacy, - diversion_header->screen, FALSE); - - sippmh_free_diversion(diversion_header); - } - - return TRUE; -} - -/* - * Function: ccsip_parse_rpid - * - * Parameters: ccb: call control block - * msg: SIP message to examine for RPID header - * - * Returns: boolean - * - * Description: Gets number of RPID headers from the SIP message, - * parses each RPID header, and sets the parsed RPID - * header into the CCB. - */ -static boolean -ccsip_parse_rpid (ccsipCCB_t *ccb, sipMessage_t *msg) -{ - char *rpid_headers[MAX_REMOTE_PARTY_ID_HEADERS]; - unsigned int rpid_line_count; - const char *rpid_str = NULL; - unsigned int j; - - /* - * Free up the previous RPID info and its associated data before, - * parsing a new one. - */ - sippmh_free_remote_party_id_info(ccb->rpid_info); - ccb->best_rpid = NULL; - ccb->rpid_info = (sipRemotePartyIdInfo_t *) - cpr_malloc(sizeof(sipRemotePartyIdInfo_t)); - if (!ccb->rpid_info) { - return FALSE; - } - - /* Parse Remote-Party-ID */ - memset(ccb->rpid_info, 0, sizeof(sipRemotePartyIdInfo_t)); - memset(rpid_headers, 0, MAX_REMOTE_PARTY_ID_HEADERS * sizeof(char *)); - - rpid_line_count = sippmh_get_num_particular_headers(msg, - SIP_HEADER_REMOTE_PARTY_ID, - SIP_HEADER_REMOTE_PARTY_ID, - rpid_headers, - MAX_REMOTE_PARTY_ID_HEADERS); - - if (rpid_line_count < 1) { - return FALSE; - } - - for (j = 0; (j < rpid_line_count) && (j < MAX_REMOTE_PARTY_ID_HEADERS); j++) { - rpid_str = rpid_headers[j]; - if ((rpid_str) && (rpid_str[0])) { - ccb->rpid_info->rpid[j] = sippmh_parse_remote_party_id(rpid_str); - } - } - ccb->rpid_info->num_rpid = rpid_line_count; - return TRUE; -} - - -/* - * Function: ccsip_set_url_domain - * - * Parameters: host: domain name from SIP header to be checked - * callingNumber: calling number to receive appended domain - * calledNumber: the called (destination) number - * line: line used for outbound call. 0 if inbound call. - * - * Returns: string_t: The updated calling number string - * - * Description: Determines if host string received in a SIP URL should - * be appended to the calling number for UI display and - * storage in the missed/received calls directory. - * Domain from the receive SIP URL will be appended to the - * calling number under the following conditions. - * 1. Received domain is FQDN and receiving line's proxy address - * is a dotted ip address. - * 2. Received domain is FQDN and receiving line's proxy address - * is a FQDN that differs from the received domain. - * 3. If received domain is dotted ip, it is NOT appended to - * the calling number under any condtion. - * - */ -static string_t ccsip_set_url_domain (char *host, string_t callingNumber, string_t calledNumber, line_t line) -{ - char *target; - char addr_error; - uint32_t address; - char buffer[MAX_SIP_URL_LENGTH]; - boolean include_domain = FALSE; - - if (host == NULL) { - return callingNumber; - } - - /* - * First check if host is dotted ip. - */ - address = IPNameCk(host, &addr_error); - if (!address) { - /* - * Host is not a dotted ip. Treat as a domain name. - * Validate the domain name and then compare the domain name - * to what is configured for the line. - */ - target = cpr_strdup(host); - if (target != NULL) { - if (sipSPI_validate_hostname(target)) { - /* - * Get proxy address config for the receiving line. Need to first determine - * the line based on the called number. - */ - if (line == 0) { - /* - * Incoming call, line needs to be dermined based on the called number. - * Otherwise, this is an outbound call and the line was provided by GSM. - */ - line = sip_config_get_line_by_called_number(1, calledNumber); - } - - if (line == 0) { - /* - * Line not found based on called number. This call will be released by - * GSM. Use full URL until release occurs. - */ - include_domain = TRUE; - } else { - buffer[0] = '\0'; - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, line, MAX_SIP_URL_LENGTH); - address = IPNameCk(buffer, &addr_error); - if (address) { - /* Configured domain is dotted ip. */ - include_domain = TRUE; - } else { - if (strncmp(host, buffer, MAX_SIP_URL_LENGTH) != 0) { - /* - * Configured domain differs from received domain - */ - include_domain = TRUE; - } - } - } - if (include_domain == TRUE) { - callingNumber = strlib_append(callingNumber, "@"); - callingNumber = strlib_append(callingNumber, host); - } - } - cpr_free(target); - } - } - return callingNumber; -} - -/* - * Function: ccsip_set_alt_callback_number - * - * Parameters: ccb: call control block - * - * Returns: char *: pointer to alt_callback_number. - * - * Description: Checks to see the x-cisco-callback-number params - * Copies the value to ccb->altCallingNumber - * - * assumes ccb->best_rpid->loc->genUrl valid - */ - -void ccsip_set_alt_callback_number(ccsipCCB_t *ccb) -{ - int param_idx=0; - char *ptr; - - while ( (ptr = ccb->best_rpid->loc->genUrl->other_params[param_idx++]) != NULL ) - { - if ( ! strncasecmp ( ptr, RPID_CALLBACK, RPID_CALLBACK_LEN)) { - ccb->altCallingNumber = - strlib_update(ccb->altCallingNumber, ptr + RPID_CALLBACK_LEN); - return; - } - } - - ccb->altCallingNumber = strlib_update(ccb->altCallingNumber, ""); -} - -/* - * Function: ccsip_set_caller_id_from_rpid - * - * Parameters: ccb: call control block - * calling: boolean value indicating if message is a - * request or response. - * display_enabled: boolean indicating if callerid is blocked. - * - * Returns: boolean: TRUE indicates call id was obtained from RPID. - * - * Description: Determines if RPID support is enabled. If so, uses utilities - * to parse out the RPID header(s) and identifies the best - * RPID header to use for UI updates. Depending on the direction - * of the call (inbound or outbound) and the RPID parameter - * settings (privacy, screen), sets the calling/called display - * name and number of the CCB based on the RPID. - */ -static boolean -ccsip_set_caller_id_from_rpid (ccsipCCB_t *ccb, boolean request, boolean update_ccb, boolean *display_enabled) -{ - int rpid_flag = RPID_DISABLED; - char *sip_rpid_user = NULL; - char *pUser = NULL; - string_t *name; - string_t *number; - boolean display_number = TRUE; - boolean private_num = FALSE; - line_t line = 0; - - - *display_enabled = TRUE; - - /* If RPID is not enabled in config, return */ - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - if (rpid_flag == RPID_DISABLED) { - return FALSE; - } - - /* If a screened RPID is not found, return */ - if (!ccsip_identify_best_rpid(ccb, request)) { - return FALSE; - } - - if (ccb->flags & INCOMING) { - name = &ccb->callingDisplayName; - number = &ccb->callingNumber; - } else { - name = &ccb->calledDisplayedName; - number = &ccb->calledNumber; - line = ccb->dn_line; - } - - sip_rpid_user = ccb->best_rpid->loc->genUrl->u.sipUrl->user; - - pUser = sippmh_parse_user(sip_rpid_user); - if (pUser) { - sip_rpid_user = pUser; - } - - private_num = ccsip_check_set_privacy_screen(name, number, - ccb->best_rpid->loc->name, - sip_rpid_user, - ccb->best_rpid->privacy, - ccb->best_rpid->screen, - TRUE); - - /* - * This check is used to determine if the calling/called number should be displayed. - * This is true in 2 cases.If privacy=full or privacy=uri. We do not currently check - * for privacy=name. - */ - if (private_num) { - /* - * Need to distinguish between privacy=uri and privacy=full - */ - if (cpr_strncasecmp(ccb->best_rpid->privacy, PRIVACY_FULL, sizeof(PRIVACY_FULL)) == 0) { - /* - * This is used for anonymous call block - */ - *display_enabled = display_number = FALSE; - } else { - /* - * Just used for blocking the calling/called number display - */ - display_number = FALSE; - } - } - - /* - * Update the alt Calling number if received in the RPID - */ - if ( (!private_num) ) - { - ccsip_set_alt_callback_number(ccb); - } - - /* - * Append host portion of url if needed. If in CCM mode, skip this step. - * We hardcode to check line 1. If line 1 is in CCM mode, all lines are CCM mode. - */ - if (sip_regmgr_get_cc_mode(1) == REG_MODE_NON_CCM) { - *number = ccsip_set_url_domain(ccb->best_rpid->loc->genUrl->u.sipUrl->host, *number, - ccb->calledNumber, line); - } - - if (pUser) { - cpr_free(pUser); - } - - - if (update_ccb) { - if (ccb->flags & INCOMING) { - ccb->displayCallingNumber = display_number; - } else { - ccb->displayCalledNumber = display_number; - } - } - - return TRUE; -} -/* - * Function: ccsip_send_callinfo - * - * Parameters: ccb: call control block - * update_caller_id: boolean indicates caller ID updating. - * delay_update: indicates that the call info. event sent - * to GSM to update UI can be delayed. - * - * Returns: void - * - * Description: The internal function used to send GSM call info. - */ -static void -ccsip_send_callinfo (ccsipCCB_t *ccb, boolean update_caller_id, - boolean delay_update) -{ - cc_feature_data_t data; - char unescape_str_temp[MAX_SIP_URL_LENGTH]; - const char *name; - const char *number; - const char *altNumber = strlib_empty(); - boolean display_number; - - if (!ccb->in_call_info) { - data.call_info.feature_flag = 0; - data.call_info.security = CC_SECURITY_UNKNOWN; - data.call_info.policy = CC_POLICY_UNKNOWN; - if (ccb->flags & INCOMING) { - data.call_info.orientation = CC_ORIENTATION_FROM; - } else { - data.call_info.orientation = CC_ORIENTATION_TO; - } - data.call_info.ui_state = CC_UI_STATE_NONE; - data.call_info.dusting = FALSE; - data.call_info.global_call_id[0] = 0; - } else { - cc_feature_data_call_info_t *feat_data = &ccb->in_call_info->data.call_info_feat_data; - - data.call_info.feature_flag = feat_data->feature_flag; - data.call_info.security = feat_data->security; - data.call_info.policy = feat_data->policy; - data.call_info.orientation = feat_data->orientation; - data.call_info.ui_state = feat_data->ui_state; - data.call_info.caller_id.call_instance_id = feat_data->caller_id.call_instance_id; - data.call_info.dusting = feat_data->dusting; - sstrncpy(data.call_info.global_call_id, - ccb->in_call_info->data.call_info_feat_data.global_call_id, CC_GCID_LEN); - } - - data.call_info.caller_id.orig_rpid_number = strlib_empty(); - if (!update_caller_id) { - data.call_info.feature_flag &= ~CC_CALLER_ID; - data.call_info.caller_id.called_name = strlib_empty(); - data.call_info.caller_id.called_number = strlib_empty(); - data.call_info.caller_id.calling_name = strlib_empty(); - data.call_info.caller_id.calling_number = strlib_empty(); - data.call_info.caller_id.alt_calling_number = strlib_empty(); - } else { - data.call_info.feature_flag |= CC_CALLER_ID; - if (ccb->flags & INCOMING) { - /* Convert escaped userinfo in the URL to unescaped form */ - if (unescape_UserInfo(ccb->callingDisplayName, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, - unescape_str_temp); - } - if (unescape_UserInfo(ccb->callingNumber, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->callingNumber = strlib_update(ccb->callingNumber, - unescape_str_temp); - } - name = ccb->callingDisplayName; - number = ccb->callingNumber; - strlib_free(altNumber); - altNumber = ccb->altCallingNumber; - display_number = ccb->displayCallingNumber; - } else { - /* Convert escaped userinfo in the URL to unescaped form */ - if (unescape_UserInfo(ccb->calledDisplayedName, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->calledDisplayedName = strlib_update(ccb->calledDisplayedName, - unescape_str_temp); - } - if (unescape_UserInfo(ccb->calledNumber, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->calledNumber = strlib_update(ccb->calledNumber, - unescape_str_temp); - } - name = ccb->calledDisplayedName; - number = ccb->calledNumber; - display_number = ccb->displayCalledNumber; - } - - if (data.call_info.orientation == CC_ORIENTATION_FROM) { - data.call_info.caller_id.calling_name = name; - data.call_info.caller_id.calling_number = number; - data.call_info.caller_id.alt_calling_number = altNumber; - data.call_info.caller_id.display_calling_number = display_number; - - data.call_info.caller_id.called_name = strlib_empty(); - data.call_info.caller_id.called_number = strlib_empty(); - data.call_info.caller_id.display_called_number = FALSE; - } else { - data.call_info.caller_id.called_name = name; - data.call_info.caller_id.called_number = number; - data.call_info.caller_id.display_called_number = display_number; - - data.call_info.caller_id.calling_name = strlib_empty(); - data.call_info.caller_id.calling_number = strlib_empty(); - data.call_info.caller_id.alt_calling_number = strlib_empty(); - data.call_info.caller_id.display_calling_number = FALSE; - if(ccb->best_rpid != NULL && ccb->best_rpid->loc->genUrl->u.sipUrl->user != NULL) - data.call_info.caller_id.orig_rpid_number = (const char *) ccb->best_rpid->loc->genUrl->u.sipUrl->user; - } - } - - /* Include diversion information - * Note that a valid ccb->div_info pointer here does not indicate that call is of - * type Forward. It simply means a call to parse diversion header had been made. - */ - if (ccb->div_info) { - data.call_info.caller_id.last_redirect_name = ccb->div_info->last_redirect_name; - data.call_info.caller_id.last_redirect_number = ccb->div_info->last_redirect_number; - data.call_info.caller_id.orig_called_name = ccb->div_info->orig_called_name; - data.call_info.caller_id.orig_called_number = ccb->div_info->orig_called_number; - } else { - data.call_info.caller_id.last_redirect_name = strlib_empty(); - data.call_info.caller_id.last_redirect_number = strlib_empty(); - data.call_info.caller_id.orig_called_name = strlib_empty(); - data.call_info.caller_id.orig_called_number = strlib_empty(); - } - data.call_info.caller_id.call_type = ccb->call_type; - - /* Set UP update delay flag */ - data.call_info.feature_flag &= ~(CC_DELAY_UI_UPDATE); - if (delay_update) { - data.call_info.feature_flag |= CC_DELAY_UI_UPDATE; - } - data.call_info.callref = ccb->callref; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_CALLINFO, &data); -} - -/* - * Function: ccsip_update_callinfo - * - * Parameters: ccb: call control block - * msg: SIP message to examine for RPID - * calling: boolean value indicating if message is a - * request or response. - * delay_update: indicates that the call info. event sent - * to GSM to update UI can be delayed. - * - * Returns: void - * - * Description: Utility function used by the various SIP state handlers - * to pull RPID and callinfo data from a received SIP message and set the - * call info fields (called/calling name and number fields, security, - * orientation, ui-state) of the CCB. A call info feature indication - * is sent to the GSM to update the phone UI display. - */ -static void -ccsip_update_callinfo (ccsipCCB_t *ccb, sipMessage_t *msg, boolean check_rpid, - boolean request, boolean delay_update) -{ - boolean update_caller_id = FALSE; - boolean display_number = TRUE; - - if (!msg) { - return; - } - - if (check_rpid) { - if (ccsip_parse_rpid(ccb, msg)) { - if (ccsip_set_caller_id_from_rpid(ccb, request, TRUE, &display_number)) { - update_caller_id = TRUE; - } - } - } - - ccsip_process_call_info_header(msg, ccb); - - ccsip_send_callinfo(ccb, update_caller_id, delay_update); -} - -/* - * Function: ccsip_check_display_validity - * - * Parameters: ccb: call control block - * reuqest: sip message - * - * Returns: boolean - * True - Display valid - * False - Display not valid - * - * Description: Check if anonymous call block feature is enabled - * against privacy settings received in the RPID and - * make a decision if the call can continue - */ -static boolean -ccsip_check_display_validity(ccsipCCB_t *ccb, sipMessage_t *request) -{ - int temp = 0; - boolean display_number = TRUE; - /* - * Check for Anonymous call blocking. If low bit is set, - * then do not allow call. Note that we must allow both upper and lowercase - * ANON strings, hence the use of strcasestr - */ - config_get_value(CFGID_ANONYMOUS_CALL_BLOCK, &temp, sizeof(temp)); - if (temp & 1) { - if (ccsip_parse_rpid(ccb, request)) { - if (ccsip_set_caller_id_from_rpid(ccb, TRUE, FALSE, &display_number)) { - if (!display_number) { - return FALSE; - } - } - } - } - return TRUE; -} -/* - * - ***** SIP_STATE_IDLE - * - */ -void -ccsip_handle_idle_ev_sip_invite (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "idle_ev_sip_invite"; - char *callingDisplayNameTemp; - char *sip_to_tag_temp; - char *sip_to_temp; - sipMessage_t *request; - const char *from = NULL; - const char *to = NULL; - const char *callID = NULL; - const char *contact = NULL; - const char *record_route = NULL; - const char *expires = NULL; - const char *alert_info = NULL, *allow = NULL; - const char *require = NULL, *supported = NULL; - char *replaceshdr = NULL; - sipReplaces_t *replaces_t = NULL; - sipLocation_t *to_loc = NULL; - sipLocation_t *from_loc = NULL; - sipUrl_t *sipFromUrl = NULL; - sipUrl_t *sipToUrl = NULL; - uint32_t local_expires_timeout = 0; - int delta = 0; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - uint32_t gmt_time; - uint32_t diff_time; - int32_t gmt_rc; - callid_t cc_call_id = CC_NO_CALL_ID; - ccsipCCB_t *refererccb = NULL; - ccsipCCB_t *replaces_ccb = NULL; - line_t dn_line; - sipsdp_status_t sdp_status; - boolean check_send_487 = FALSE; - char unescape_str_temp[MAX_SIP_URL_LENGTH]; - boolean display_number = FALSE; - string_t recv_info_list = strlib_empty(); - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodInvite, FALSE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - ccb->flags |= INCOMING; - - /* To: and From: header */ - from = sippmh_get_cached_header_val(request, FROM); - ccb->sip_from = strlib_update(ccb->sip_from, from); - to = sippmh_get_cached_header_val(request, TO); - ccb->sip_to = strlib_update(ccb->sip_to, to); - - /* CallID: header */ - callID = sippmh_get_cached_header_val(request, CALLID); - sstrncpy(ccb->sipCallID, callID, sizeof(ccb->sipCallID)); - - /* Require: header */ - require = sippmh_get_cached_header_val(request, REQUIRE); - if (require) { - char *unsupported_tokens = NULL; - - ccb->required_tags = sippmh_parse_supported_require(require, - &unsupported_tokens); - - if (unsupported_tokens != NULL) { - ccb->sip_unsupported = strlib_update(ccb->sip_unsupported, - unsupported_tokens); - cpr_free(unsupported_tokens); - } - - if (ccb->required_tags & (~(SUPPORTED_TAGS))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unsupported Require Header in INVITE", fname); - ccb->sip_require = strlib_update(ccb->sip_require, require); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_EXTENSION, - SIP_CLI_ERR_EXTENSION_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - } - - /* Supported: header */ - supported = sippmh_get_cached_header_val(request, SUPPORTED); - if (supported) { - ccb->supported_tags = sippmh_parse_supported_require(supported, NULL); - } - - /* Allow: header */ - allow = sippmh_get_header_val(request, SIP_HEADER_ALLOW, NULL); - if (allow) { - ccb->allow_methods = sippmh_parse_allow_header(allow); - } - - /* Contact: header */ - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - - if ((ccb->contact_info == NULL) || // contact in msg, parse error - (sipSPICheckContact(contact) < 0)) { // If contact is invalid - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPICheckContact()"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - ccb); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - } - - /* Record-Route: header */ - record_route = sippmh_get_cached_header_val(request, RECORD_ROUTE); - if (record_route) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = sippmh_parse_record_route(record_route); - if (ccb->record_route_info == NULL) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_record_route()"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_RECORD_ROUTE, - ccb); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - } - // Save received URI in ReqURIOriginal - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - /* Parse RPID header */ - (void) ccsip_parse_rpid(ccb, request); - - - /* Parse Diversion header */ - (void) ccsip_parse_diversion_header(ccb, request); - - /* - * Parse From - */ - from_loc = sippmh_parse_from_or_to((char *)ccb->sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - if (from_loc->tag && (strlen(from_loc->tag) >= MAX_SIP_TAG_LENGTH)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "Length of From Tag"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - sippmh_free_location(from_loc); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - if (from_loc->genUrl->schema == URL_TYPE_SIP) { - sipFromUrl = from_loc->genUrl->u.sipUrl; - } - - /* - * Parse To - */ - to_loc = sippmh_parse_from_or_to((char *)ccb->sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - sippmh_free_location(from_loc); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - if (to_loc->genUrl->schema == URL_TYPE_SIP) { - sipToUrl = to_loc->genUrl->u.sipUrl; - } - // Check/Generate tags - if (to_loc->tag) { - /* ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, - * sip_sm_purify_tag(to_loc->tag)); - */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Initial invite with to_tag"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - } else { - sip_to_tag_temp = strlib_open(ccb->sip_to_tag, MAX_SIP_TAG_LENGTH); - if (sip_to_tag_temp) { - sip_util_make_tag(sip_to_tag_temp); - } - ccb->sip_to_tag = strlib_close(sip_to_tag_temp); - - sip_to_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - sstrncat(sip_to_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - if (ccb->sip_to_tag) { - sstrncat(sip_to_temp, ccb->sip_to_tag, - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - } - } - ccb->sip_to = strlib_close(sip_to_temp); - } - - if (from_loc->tag) { - ccb->sip_from_tag = strlib_update(ccb->sip_from_tag, - sip_sm_purify_tag(from_loc->tag)); - ccb->callref = get_callref(ccb->sip_from_tag); - } - - if (ccb->ReqURI) { - ccb->calledNumber = strlib_update(ccb->calledNumber, ccb->ReqURI); - } else if (sipToUrl) { - if (sipToUrl->user) { - char *pUser = NULL; - - pUser = sippmh_parse_user(sipToUrl->user); - if (pUser && (pUser[0] != '\0')) { - ccb->calledNumber = strlib_update(ccb->calledNumber, pUser); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - ccb->calledNumber = strlib_update(ccb->calledNumber, - sipToUrl->user); - if (pUser) - cpr_free(pUser); - } - } - } - - /* - * Make sure we have a valid called_number. - */ - if ((ccb->calledNumber == NULL) || (ccb->calledNumber[0] == '\0')) { - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_NOT_FOUND, - SIP_CLI_ERR_NOT_FOUND_PHRASE, - 0, NULL, ccb); - - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - ccb->wait_for_ack = FALSE; - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - return; - } - - if (!ccsip_set_caller_id_from_rpid(ccb, TRUE, TRUE, &display_number)) { - if (sipFromUrl) { - if (sipFromUrl->user) { - char *pUser; - - pUser = sippmh_parse_user(sipFromUrl->user); - if (pUser) { - ccb->callingNumber = strlib_update(ccb->callingNumber, pUser); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - ccb->callingNumber = strlib_update(ccb->callingNumber, sipFromUrl->user); - } - if (from_loc->genUrl->schema == URL_TYPE_SIP && - sipFromUrl->host && - ccb->callingNumber && - sip_regmgr_get_cc_mode(1) == REG_MODE_NON_CCM) { - /* - * If we have a host name, calling number, and are not in CCM mode, - * check to see if the domain should be appended to the calling number - * for display to the user. - */ - ccb->callingNumber = ccsip_set_url_domain(sipFromUrl->host, ccb->callingNumber, - ccb->calledNumber, 0); - } - } else { - ccb->callingNumber = strlib_update(ccb->callingNumber, - "Unknown Number"); - } - } - - if (from_loc->name) { - callingDisplayNameTemp = strlib_open(ccb->callingDisplayName, - MAX_SIP_DISPLAYNAME_LENGTH); - if (callingDisplayNameTemp) { - sstrncpy(callingDisplayNameTemp, from_loc->name, - MAX_SIP_DISPLAYNAME_LENGTH); - sip_sm_dequote_string(callingDisplayNameTemp, MAX_SIP_DISPLAYNAME_LENGTH); - } - ccb->callingDisplayName = strlib_close(callingDisplayNameTemp); - - } else { - char *pUser; - - pUser = NULL; - if (sipFromUrl) { - pUser = sippmh_parse_user(sipFromUrl->user); - } - - if (pUser) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, - pUser); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - if (sipFromUrl) { - if (sipFromUrl->user) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, - sipFromUrl->user); - } - } - } - } - } - - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - - // If there is a Replace aheader then it must be a Transfer request - // Store the call_id of the other call so that we can release the call when - // we get 200 OK on consultation call - (void) sippmh_get_num_particular_headers(request, SIP_HEADER_REPLACES, - NULL, &replaceshdr, MAX_REPLACES_HEADERS); - ccb->wastransferred = FALSE; - - - dn_line = ccb->dn_line; - - if ((Basic_is_phone_forwarded(dn_line) == NULL) && NULL != replaceshdr) { - char tempreplace[MAX_SIP_URL_LENGTH]; - boolean is_previous_call_id = FALSE; - line_t previous_call_index = 0; - - memset(tempreplace, 0, MAX_SIP_URL_LENGTH); - sstrncpy(tempreplace, "Replaces=", sizeof(tempreplace)); - sstrncat(tempreplace, replaceshdr, (sizeof(tempreplace) - sizeof("Replaces="))); - replaces_t = sippmh_parse_replaces(tempreplace, FALSE); - if (NULL != replaces_t) { - //Check if a call exists that matches the callid, to and from tags found in the replaces header - if ((cpr_strcasecmp(replaces_t->toTag, ccb->sip_to_tag)==0 - && cpr_strcasecmp(replaces_t->fromTag, ccb->sip_from_tag)==0 - && cpr_strcasecmp(replaces_t->callid, ccb->sipCallID)==0) || - ((refererccb = sip_sm_get_ccb_by_callid(replaces_t->callid)) != NULL - && cpr_strcasecmp(replaces_t->toTag, refererccb->sip_to_tag) == 0 - && cpr_strcasecmp(replaces_t->fromTag, refererccb->sip_from_tag) == 0)) { - ccb->sipxfercallid = strlib_update(ccb->sipxfercallid, replaces_t->callid); - sippmh_free_replaces(replaces_t); - ccb->wastransferred = TRUE; - check_send_487 = TRUE; - } else { - is_previous_call_id = sip_sm_is_previous_call_id(replaces_t->callid, - &previous_call_index); - replaces_ccb = sip_sm_get_ccb_by_callid(replaces_t->callid); - if (replaces_ccb != NULL && replaces_ccb->state == SIP_STATE_RELEASE) { - is_previous_call_id = TRUE; - CCSIP_DEBUG_STATE("%s: Replaces Header, matching call found.", fname); - } - if (is_previous_call_id) { - // The Callid refers to a previous call - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Replaces Header, Callid refers to a previous call"); - sipSPISendInviteResponse(ccb, SIP_FAIL_DECLINE, - SIP_FAIL_DECLINE_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - - } else { - // Could not find a matching call. If the CFWD is disabled - // send back the error. If it is enabled, it will be processed - // below. - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Replaces Header, No matching call found"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - } - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sippmh_free_replaces(replaces_t); - return; - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Bad Replaces Header, Ending transferred call"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REPLACES, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - } - } - - /* - * Extract SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_OFFER_RECEIVED; - break; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - case SIP_SDP_ERROR: - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SDP_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - case SIP_SDP_NO_MEDIA: - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SDP_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - case SIP_SDP_NOT_PRESENT: - default: - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Waiting for SDP in ACK", DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - break; - } - - - /* see if we are forwarded to another location */ - if (Basic_is_phone_forwarded(dn_line)) { - size_t escaped_char_str_len = 8; - char pDiversionStr[MAX_SIP_URL_LENGTH]; - int len = 0; - int blocking; - boolean private_flag = FALSE; - char line_name[MAX_LINE_NAME_SIZE]; - char display_name[MAX_LINE_NAME_SIZE]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Call forwarded, sending redirect"); - - ccb->dn_line = dn_line; - /* - * If Caller ID Blocking is OFF or emergency route is ON, - * set private to TRUE. Otherwise, FALSE. - */ - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - if ((blocking & 1) && (ccb->routeMode != RouteEmergency)) { - private_flag = TRUE; - } - - /* - * Diversion Header format: - * "display_name" ;reason=unconditional; - * privacy="full" or "off";screen=yes - */ - config_get_string((CFGID_LINE_NAME + ccb->dn_line - 1), line_name, sizeof(line_name)); - sip_config_get_display_name(ccb->dn_line, display_name, sizeof(display_name)); - ipaddr2dotted(src_addr_str, &ccb->src_addr); - snprintf(pDiversionStr, MAX_SIP_URL_LENGTH, "\"%s\" ;reason=unconditional;privacy=%s;screen=yes", - src_addr_str, (private_flag ? "full" : "off")); - - len = strlen(pDiversionStr); - ccb->diversion[0] = (char *) cpr_malloc(len + 1); - - if (ccb->diversion[0]) { - sstrncpy(ccb->diversion[0], pDiversionStr, len + 1); - } else { - CCSIP_DEBUG_ERROR(DEB_L_C_F_PREFIX "No memory left; %d" - "Can not create CC-Diversion header for CFWDAll\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->dn_line, ccb->gsm_id, fname), - ccb->index); - } - sipSPISendInviteResponse302(ccb); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Start Local Expires timer - */ - expires = sippmh_get_header_val(request, SIP_HEADER_EXPIRES, NULL); - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &local_expires_timeout, - sizeof(local_expires_timeout)); - if (expires) { -//CPR TODO: need reference for - gmt_rc = gmt_string_to_seconds((char *)expires, (unsigned long *)&gmt_time); - if (gmt_rc != -1) { - // We only want to update the expires timeout if it is lower - // than our predefined threshold. We don't want to allow people - // to keep us hung up for infinite periods of time - if (gmt_rc == 1) { - // We got a numeric entry in the expires field - if (gmt_time < local_expires_timeout) { - local_expires_timeout = gmt_time; - } -//CPR TODO: need reference for - } else if (diff_current_time(gmt_time, (unsigned long *) &diff_time) == 0) { - // We got a GMT string in the expires field - if (diff_time < local_expires_timeout) { - local_expires_timeout = diff_time; - } - } - } - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Using config timer_expires"); - } - - if (local_expires_timeout > 0) { - config_get_value(CFGID_TIMER_T1, &delta, sizeof(delta)); - delta = (2 * delta) / 1000; - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Starting INVITE Local Expires %d" - "timer (%d sec)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, local_expires_timeout + delta); - /* - * Add delta to the Expires timer so that the callee gives the - * caller a chance to send out the CANCEL message before sending - * out a 408 INVITE response. - */ - (void) sip_platform_localexpires_timer_start((local_expires_timeout + delta) * 1000, - ccb->index, &(ccb->dest_sip_addr), - (uint16_t) ccb->dest_sip_port); - } - - /* check for alert-info in header */ - alert_info = sippmh_get_header_val(request, SIP_HEADER_ALERT_INFO, NULL); - ccb->alert_info = ALERTING_NONE; - if (alert_info) { - parseAlertingHeader(ccb, alert_info); - } - - /* check for and process call-info in header */ - ccsip_process_call_info_header(request, ccb); - - /* - * Parse join info if it exists and get - * the gsm id for the join target call - */ - if (ccsip_get_join_info(ccb, request) == FALSE) { - /* - * There was something wrong with the joinhdr - * or join target call is not active - */ - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - sipSPISendInviteResponse100(ccb, TRUE); - - /* Inform CSM */ - cc_call_id = cc_get_new_call_id(); - ccb->gsm_id = cc_call_id; - // send XFER Request - if (ccb->wastransferred) { - refererccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if (NULL != refererccb) { - cc_feature_data_t data; - - data.xfer.method = CC_XFER_METHOD_REFER; - data.xfer.cause = CC_CAUSE_XFER_REMOTE; - data.xfer.target_call_id = cc_call_id; - data.xfer.dialstring[0] = '\0'; - sip_cc_feature(refererccb->gsm_id, refererccb->dn_line, - CC_FEATURE_XFER, (void *) &data); - } - } - - if (refererccb == NULL) { - dn_line = ccb->dn_line; - } else { - dn_line = refererccb->dn_line; - } - - /* Convert escaped userinfo in the URL to unescaped form */ - if (unescape_UserInfo(ccb->calledNumber, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->calledNumber = strlib_update(ccb->calledNumber, unescape_str_temp); - } - - if (unescape_UserInfo(ccb->callingNumber, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->callingNumber = strlib_update(ccb->callingNumber, unescape_str_temp); - } - - if (unescape_UserInfo(ccb->callingDisplayName, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, unescape_str_temp); - } - - if (unescape_UserInfo(ccb->altCallingNumber, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->altCallingNumber = strlib_update(ccb->altCallingNumber, unescape_str_temp); - } - - /* Info Package stuff */ - ccsip_parse_send_info_header(request, &recv_info_list); - - - - if (ccb->wastransferred) { - sip_cc_setup(cc_call_id, dn_line, - ccb->callingDisplayName, - ccb->callingNumber, - ccb->altCallingNumber, - ccb->displayCallingNumber, - ccb->calledDisplayedName, - ccb->calledNumber, - ccb->displayCalledNumber, - ccb->div_info->orig_called_name, - ccb->div_info->orig_called_number, - ccb->div_info->last_redirect_name, - ccb->div_info->last_redirect_number, - ccb->call_type, - ccb->alert_info, ccb->alerting_ring, - ccb->alerting_tone, ccb->in_call_info, TRUE, - recv_info_list, request); - } else { - sip_cc_setup(cc_call_id, dn_line, - ccb->callingDisplayName, - ccb->callingNumber, - ccb->altCallingNumber, - ccb->displayCallingNumber, - ccb->calledDisplayedName, - ccb->calledNumber, - ccb->displayCalledNumber, - ccb->div_info->orig_called_name, - ccb->div_info->orig_called_number, - ccb->div_info->last_redirect_name, - ccb->div_info->last_redirect_number, - ccb->call_type, - ccb->alert_info, ccb->alerting_ring, - ccb->alerting_tone, ccb->in_call_info, FALSE, - recv_info_list, request); - } - - strlib_free(recv_info_list); - - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE); - - if (check_send_487) { - /* check to see if we need to send a 487 back to original Invite - * that replaces this call. If it is not connected yet, send the - * 487 and release the call to GSM. - */ - ccsipCCB_t *other_ccb; - - other_ccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if ((other_ccb != NULL) && - ((other_ccb->state >= SIP_STATE_RECV_INVITE) && - (other_ccb->state < SIP_STATE_RECV_INVITE_CONNECTED))) { - sipSPISendInviteResponse(other_ccb, SIP_CLI_ERR_REQ_CANCEL, - SIP_CLI_ERR_REQ_CANCEL_PHRASE, 0, NULL, - FALSE /* no SDP */ , TRUE /* reTx */); - sip_cc_release(other_ccb->gsm_id, other_ccb->dn_line, - CC_CAUSE_NORMAL, NULL); - other_ccb->wait_for_ack = TRUE; - sip_sm_change_state(other_ccb, SIP_STATE_RELEASE); - } - } -} - -/* - * This function is called when one of the following occurs: - * - * 1) Attempting to send out an INVITE and for whatever reason - * the call to get the IP address for the main proxy fails. - * 2) An ICMP unreachable event is received and there are no - * more DNS entries for the main proxy. - * 3) Retries have been exhausted on the main proxy and there - * are no more DNS entries for the main proxy. - */ -boolean -ccsip_attempt_backup_proxy (ccsipCCB_t *ccb) -{ - char ip_addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t ipaddr; - int tempPort = 0; - char tmp_str[STATUS_LINE_MAX_LEN]; - - CPR_IP_ADDR_INIT(ipaddr); - /* - * Get IPAddress and Port for backup proxy - */ - sipTransportGetBkupServerAddress(&ipaddr, ccb->dn_line, ip_addr_str); - if (util_check_if_ip_valid(&ipaddr)) { - util_ntohl(&(ccb->dest_sip_addr), &ipaddr); - - /* - * If the Proxy Backup Port isn't contained in the - * config table, use the PROXYN port instead. - */ - tempPort = sipTransportGetBkupServerPort(ccb->dn_line); - if (tempPort != 0) { - ccb->dest_sip_port = tempPort; - } else { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - - ccb->proxySelection = SIP_PROXY_BACKUP; - - /* Note counter must be at least 2 or better to work as directed - * This count is decremented by one on each successful response to - * an invite. If we receive backup_active successful responses to - * an invite go back to the max retry count on the main or primary proxy. - * Why 12 you ask. Depending on the number of SIP messages received per - * call this equates to maybe 4 phone calls before going back to - * the full re-try count on the primary/main proxy. - */ - gGlobInfo.backup_active = 12; - - /* - * Let user know we have failed over to backup proxy - */ - if ((platGetPhraseText(STR_INDEX_PROXY_UNAVAIL, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - ui_set_call_status(tmp_str, ccb->dn_line, ccb->gsm_id); - } - return (TRUE); - } - - return (FALSE); -} - -/** - * This fucntion sends mid-call INVITE. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] hold_initiated boolean indicating whther this is - * a mid-call INVITE for HOLD feature. - * - * @pre (ccb not_eq NULL) - * - * @return true or false - */ -boolean -send_resume_or_hold_request (ccsipCCB_t *ccb, boolean hold_initiated) -{ - ccb->authen.cred_type = 0; - ccb->authen.new_flag = TRUE; - ccb->hold_initiated = hold_initiated; - if (sipSPISendInviteMidCall(ccb, FALSE /* doesn't expire */) != TRUE) { - return FALSE; - } - /* Pre-fill the ARP table */ - ADD_TO_ARP_CACHE(ccb->dest_sip_addr); - return TRUE; -} - -void -ccsip_handle_idle_ev_cc_setup (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "idle_ev_cc_setup"; - char *dialString; - char *referred_by_blind; - uint32_t dialStringLength = 0; - char *calledNumberTemp; - char *outputString = NULL; - uint32_t usernameLength = 0; - char *hostnameString = NULL; - uint32_t hostnameLength = 0; - char proxy_ipaddr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t proxy_ipaddr; - - char *extraString = NULL; - uint32_t extraLength = 0; - uint32_t n = 0; - static char dialtranslate[MAX_SIP_URL_LENGTH]; - char temp[MAX_IPADDR_STR_LEN]; - char line_name[MAX_LINE_NAME_SIZE]; - int port; - boolean sendInvite = FALSE; - char *tmpPtr = NULL; - cpr_ip_type ip_type = CPR_IP_ADDR_IPV4; - boolean replace = FALSE; - - CPR_IP_ADDR_INIT(proxy_ipaddr); - - ccb->gsm_id = event->u.cc_msg->msg.setup.call_id; - ccb->dn_line = event->u.cc_msg->msg.setup.line; - - /* - * Handlle replace info if there is any before taking in any - * dial string. - */ - if (ccsip_is_replace_setup(event->u.cc_msg->msg.setup.replaces)) { - replace = TRUE; - if (!ccsip_set_replace_info(ccb, &event->u.cc_msg->msg.setup)) { - /* The replace info failed */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"ignore setup, no replace info for" - " replace setup request\n", DEB_F_PREFIX_ARGS(SIP_REP, fname)); - return; - } - } - - ccsip_set_join_info(ccb, &event->u.cc_msg->msg.setup); - - dialString = (char *) event->u.cc_msg->msg.setup.caller_id.called_number; - referred_by_blind = event->u.cc_msg->msg.setup.redirect.redirects[0].number; - dialStringLength = strlen(dialString); - if ((0 == dialStringLength) && !replace) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No Digits to dial", fname); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } else if (!dialStringLength && replace) { - dialString = (char *) event->u.cc_msg->msg.setup.caller_id.calling_number; - dialStringLength = strlen(dialString); - } - - /* - * Save away what they sent us so that we can display it to them later - * - * Note: Currently only dialString which is obtained from - * event->u.cc_msg->msg.setup.caller_id.called_number is needed - * by SIP stack. Make a duplicate copy of the field. If more - * fields are needed from the caller_id from the setup msg. - * then the better use of the cc_mv_caller_id() API to move - * caller IDs from the setup to local storage is more efficient. - */ - ccb->calledDisplayedName = strlib_update(ccb->calledDisplayedName, - dialString); - - memset(proxy_ipaddr_str, 0, MAX_IPADDR_STR_LEN); - memset(temp, 0, sizeof(temp)); - - - sip_util_get_new_call_id(ccb); - ccb->featuretype = CC_FEATURE_NONE; - /* - * Get the listen port from the Transport Interface - * instead of the direct config. - */ - ccb->local_port = sipTransportGetListenPort(ccb->dn_line, ccb); - - /* - * Normalize the name. This means adding u.cc_msg->msg.setup.redirect.redirects[0].number[0] != '\0') { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, - referred_by_blind); - ccb->blindtransferred = TRUE; - } - if (event->u.cc_msg->msg.setup.redirect.redirects[0].number[0] != '\0') { - strlib_free(event->u.cc_msg->msg.setup.redirect.redirects[0].number); - } - - /* - * See if the string needs to be rewritten by applying the dial template - */ - ccb->routeMode = RouteDefault; - -#define CAST_N (int32_t *) - - (void) MatchDialTemplate(ccb->calledDisplayedName, ccb->dn_line, CAST_N & n, dialtranslate, - sizeof(dialtranslate), (RouteMode *) & (ccb->routeMode), NULL); - dialString = dialtranslate; - dialStringLength = strlen(dialString); - - /* - * Throw away any display name part before LAQUOT(<), if there is one - * Ex: "Test Test" - Display string is "Test Test" - * Ex: Test Test - Display string is "Test Test" - * Ex: - No Display string - * Ex: sip:31@172.18.192.230 - No Display string - * Ex: 31@172.18.192.230 - No Display string - * - * the last two examples have no LAQUOT and RAQUOT in them - * - */ - - tmpPtr = strchr(dialString, '<'); - if (tmpPtr) { - dialString = tmpPtr; - dialStringLength = strlen(dialString); - } - - /* - * Throw away any part of 0) && (dialString[0] == '<')) { - dialString++; - dialStringLength--; - } - - /* - * For the SIP: part, we have to have 4 characters - */ - if (!cpr_strncasecmp(dialString, "sip:", 4)) { - dialStringLength -= 4; - dialString += 4; - } - - /* - * Parse the remainder of the string looking for the host name - */ - for (n = 0; n <= dialStringLength; n++) { - /* - * If we hit the end of the string without encountering a ; or > - * then we want to put the entire string into the user name if - * no host name was encountered or if we found a '@' along the - * way we want to put the residual into the host name - */ - if (n == dialStringLength) { - if (hostnameString == NULL) { - usernameLength = n; - } else { - hostnameLength = n - usernameLength - 1; //Accounts for @ - } - } else if ((dialString[n] == '@') && (hostnameString == NULL)) { - /* - * We encountered an @ separator for the host name, so take - * everything before the @ and put it into the user name - */ - usernameLength = n; - hostnameString = dialString + n + 1; - } else if ((dialString[n] == ';') || (dialString[n] == '>')) { - /* - * We hit the separator character (; or >). Take what we have - * seen and append it to the host name (if we already saw the @) - * or to the user name if not - */ - if (hostnameString == NULL) { - usernameLength = n; - } else { - hostnameLength = n - usernameLength - 1; // Accounts for @ - } - extraString = dialString + n; - extraLength = dialStringLength - n; - break; - } - } - /* - * At this point we have - * usernameLength - Number of characters in the user name - * starting from dialString[0] - * hostnameString - NULL if no @ was encountered, otherwise it - * points to the start of the host name string - * hostnameLength - 0 if no host name characters were encountered - * extraString - Points to any extra parameters - * extraLength - number of extra parameter characters - */ - switch (ccb->routeMode) { - case RouteEmergency:{ - /* - * If we have failed over to the backup we need - * to not reselect the emergency proxy - */ - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - // Get the Emergency Proxy - sipTransportGetEmerServerAddress(ccb->dn_line, proxy_ipaddr_str); - if (hostnameLength == 0) { - hostnameString = proxy_ipaddr_str; - hostnameLength = strlen(proxy_ipaddr_str); - } - if (proxy_ipaddr_str[0]) { - if (!str2ip((const char *)proxy_ipaddr_str, &proxy_ipaddr)) { - /* Fill in address and port in CCB */ - util_ntohl(&(ccb->dest_sip_addr), &proxy_ipaddr); - /* - * If the Proxy Emergency Port isn't contained in the - * config table, use the PROXYN port instead. - */ - port = sipTransportGetEmerServerPort(ccb->dn_line); - if (port) { - ccb->dest_sip_port = (uint32_t)port; - } else { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - break; - } - } - } - // Otherwise Emergency proxy is not in configuration follow thru. Let - // static analysis know this is intentional - /*FALLTHROUGH*/} - default: - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, temp); - if (hostnameLength == 0) { - hostnameString = temp; - hostnameLength = strlen(hostnameString); - } - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr),ccb->dn_line); - if (util_check_if_ip_valid(&(ccb->dest_sip_addr))) { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Unable to reach proxy, attempting backup.", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - if (!ccsip_attempt_backup_proxy(ccb)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Attempt to reach backup proxy failed.", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"INVITE will be broadcast.", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - } - } - } - - /* Pre-fill the ARP table */ - ADD_TO_ARP_CACHE(ccb->dest_sip_addr); - - /* - * Construct the actual dial out string - */ - calledNumberTemp = strlib_open(ccb->calledNumber, (MAX_SIP_URL_LENGTH * 2)); - outputString = calledNumberTemp; - sstrncpy(outputString, " - */ - outputString[extraLength] = 0; - /* - * If there was no > in what they gave us, put one in for them - */ - if (strchr(outputString, '>') == NULL) { - outputString[extraLength++] = '>'; - } - outputString += extraLength; - } else { - *outputString++ = '>'; - } - /* - * Null terminate the string for good measure and note how long it is - */ - *outputString = 0; - ccb->calledNumber = strlib_close(calledNumberTemp); - if (ccb->calledNumber) { - ccb->calledNumberLen = (uint16_t) strlen(ccb->calledNumber); - } - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"All digits collected. Placing the call", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, sizeof(line_name)); - ccb->callingNumber = strlib_update(ccb->callingNumber, line_name); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"SIPSM %d: Setup", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), ccb->index); - - /* Copy the call-info into the CCB */ - ccsip_store_call_info(&event->u.cc_msg->msg.setup.call_info, ccb); - - /* Send INVITE */ - - /* Save the GSM's msg. bodies for future used */ - ccsip_save_local_msg_body(ccb, &event->u.cc_msg->msg.setup.msg_body); - - /* - * CC_REDIRECT_REASON_DEFLECTION shows that this is an attended transfer - */ - // Note that the extra body parts will be automatically deleted - if (event->u.cc_msg->msg.setup.redirect.redirects[0].redirect_reason - == CC_REDIRECT_REASON_DEFLECTION) { - sendInvite = sipSPISendInvite(ccb, SIP_INVITE_TYPE_TRANSFER, TRUE); - } else { - sendInvite = sipSPISendInvite(ccb, SIP_INVITE_TYPE_NORMAL, TRUE); - } - - if (sendInvite == TRUE) { - sip_sm_change_state(ccb, SIP_STATE_SENT_INVITE); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPISendInvite failed", fname); - if (event->u.cc_msg->msg.setup.redirect.redirects[0].redirect_reason - == CC_REDIRECT_REASON_DEFLECTION) { - /* - * Sending replaces invite for attended transfer has failed. - * Clean up here because a release complete from GSM - * is not guaranteed here like in the case of pre-mature - * attended transfer request. A cause value of normal - * causes GSM to clean up the UI as well. - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - sip_sm_call_cleanup(ccb); - } else { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - - } - -} - - -/* - * - ***** SIP_STATE_SENT_INVITE - * - */ -void -ccsip_handle_sentinvite_ev_sip_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_1xx"; - sipMessage_t *response; - sipRespLine_t *respLine; - int status_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - /* - * Update the Tags here so that they will be correct if - * the user transfers a ringing call. - */ - sip_sm_200and300_update(ccb, response, status_code); - - sip_decrement_backup_active_count(ccb); - - /* Mark the CCB as having received a 1xx response */ - ccb->flags |= RECD_1xx; - - if (status_code != SIP_1XX_TRYING) { - /* Reset credentials flag since INVITE was successfully processed */ - ccb->authen.cred_type = 0; - } - - switch (status_code) { - - case SIP_1XX_TRYING: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), ccb->index, - ccb->dn_line, fname, sip_util_state2string(ccb->state), - "SIP 100 TRYING"); - /* - * Update connected party info from RPID and Call-Info header. - * Do not delay call info update to UI with proceeding. There is - * no media event with the proceeding that can cause UI update - * automatically. - */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - return; - - case SIP_1XX_RINGING: - { - sipsdp_status_t sdp_status; - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP 180 RINGING", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - - /* check for alert-info in header. - * Commented out until DSP upgrade - alert_info = sippmh_get_header_val(request, SIP_HEADER_ALERT_INFO, - NULL); - ccb->alert_info = ALERTING_NONE; - if (alert_info) { - parseAlertingHeader(ccb, alert_info); - } - */ - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_IDLE; - /* ccsip_update_callinfo needs to occur before cc_alerting */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_alerting(ccb->gsm_id, ccb->dn_line, response, TRUE); - break; - - case SIP_SDP_NOT_PRESENT: - /* ccsip_update_callinfo needs to occur before cc_alerting */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_alerting(ccb->gsm_id, ccb->dn_line, NULL, 0); - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - sipSPISendCancel(ccb); - free_sip_message(response); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - /* - * Update connected party info from RPID and Call-Info header. - * The call update to UI can be delayed due to altert processing - * can potentially manipulate media or port. - */ - free_sip_message(response); - return; - - } /* case SIP_1XX_RINGING */ - case SIP_1XX_SESSION_PROGRESS: - { - sipsdp_status_t sdp_status; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), ccb->index, - ccb->dn_line, fname, sip_util_state2string(ccb->state), - "SIP 183 IN BAND SESSION PROGRESS"); - - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_IDLE; - break; - - case SIP_SDP_NOT_PRESENT: - // In this case no SDP is present in the 183 message. - // Call flows exist where a callee may send 183 with no SDP and - // the right way to handle it is to remain in the same state. - // DDTS for reference is CSCdu17240 - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - return; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - sipSPISendCancel(ccb); - free_sip_message(response); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Update connected party info from RPID and Call-Info header. - * The call update to UI can be delayed due to altert processing - * can potentially manipulate media or port. - */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_alerting(ccb->gsm_id, ccb->dn_line, response, TRUE); - - /*UI-STATE tag with value of "BUSY" is being sent to indicate the busy line - *and to support callback feature. GSM needs to be informed so it can - *trigger the LSM to transition to BUSY state and display appropriate - *softkeys. - */ - if ((ccb->in_call_info) && - (ccb->in_call_info->data.call_info_feat_data.feature_flag & CC_UI_STATE) && - (ccb->in_call_info->data.call_info_feat_data.ui_state == CC_UI_STATE_BUSY)) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"DETECTED UI_STATE=BUSY IN 183.", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_UI_STATE_BUSY, NULL); - } - free_sip_message(response); - return; - } /* case SIP_1XX_SESSION_PROGRESS */ - - case SIP_1XX_CALL_FWD: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP 181 CALL IS BEING" - "FORWARDED\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - return; - - case SIP_1XX_QUEUED: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP 182 QUEUED", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - return; - - default: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP BAD 1xx", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - free_sip_message(response); - return; - } -} - - -void -ccsip_handle_sentinvite_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_2xx"; - sipMessage_t *response; - const char *contact = NULL; - sipsdp_status_t sdp_status; - string_t recv_info_list = strlib_empty(); - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is an INVITE response */ - if (!sip_sm_is_invite_response(response)) { - sipMethod_t method = sipMethodInvalid; - int response_code = 0; - - // If this is a 202 response to a REFER, we should handle it separately - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - - if (response_code == SIP_ACCEPTED && method == sipMethodRefer) { - ccsip_handle_accept_2xx(ccb, event); - return; - } - free_sip_message(response); - clean_method_request_trx(ccb, method, TRUE); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - /* - * Record the "tag=" parameter. - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - sip_sm_200and300_update(ccb, response, SIP_STATUS_SUCCESS); - - /* Reset credentials flag since INVITE was successfully processed */ - ccb->authen.cred_type = 0; - - sip_decrement_backup_active_count(ccb); - (void) sip_platform_expires_timer_stop(ccb->index); - /* Check Contact header */ - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact) { - if (sipSPICheckContact(contact) < 0) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPICheckContact()"); - free_sip_message(response); - ccb->authen.cred_type = 0; - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - return; - } - } - - /* Extract destination SDP and related fields */ - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_IDLE; - break; - - case SIP_SDP_NOT_PRESENT: - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - /* First Ack and then send Bye to the far end */ - if (sipSPISendAck(ccb, response) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - free_sip_message(response); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - if (ccb->wastransferred) { - /* - * The referred call was implicitly subscribed for the - * notification. Since we get the Error from target we - * need to send this notify to transferor - */ - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_ERROR; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - } - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Parse the diversion header which could be present, as in case of - * Auto Pick up - */ - ccsip_parse_diversion_header (ccb, response); - - /* Info Package stuff */ - ccsip_parse_send_info_header(response, &recv_info_list); - - /* - * Update connected party info from RPID and Call-Info header. - * The call update to UI can be delayed due to connected processing - * manipulates media or port. - */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_connected(ccb->gsm_id, ccb->dn_line, recv_info_list, response); - - strlib_free(recv_info_list); - - /* Deallocate the memory for the response */ - free_sip_message(response); - sip_sm_change_state(ccb, SIP_STATE_SENT_INVITE_CONNECTED); - - /* - * The referred call was implicitely subscribed for the notification. - * Since we get the 200 OK from target we need to send this notify - * to transferor. So make a feature request to the GSM - */ - if ((ccb->wastransferred) || (ccb->blindtransferred == TRUE)) { - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = SIP_SUCCESS_SETUP; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = - sip_sm_get_blind_xfereror_ccb_by_gsm_id(ccb->gsm_id); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } else if (ccb->flags & SENT_INVITE_REPLACE) { - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } -} - - -/* - * - ***** SIP_STATE_RELEASING - * - */ - -void -ccsip_handle_sentbye_recvd_invite (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipMessage_t *request; - - /* Unpack the event */ - request = event->u.pSipMessage; - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, 0, NULL, NULL); - free_sip_message(request); -} - -void -ccsip_handle_release_complete (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "release_complete"; - - if (ccb->blind_xfer_call_id == CC_NO_CALL_ID) { - if (!ccb->wait_for_ack) { - if ((ccb->flags & RECD_BYE) && (ccb->last_request)) { - (void) sipSPISendByeOrCancelResponse(ccb, ccb->last_request, sipMethodBye); - ccb->flags &= ~RECD_BYE; - } - if (!(sip_platform_msg_timer_outstanding_get(ccb->index))) { - sip_sm_call_cleanup(ccb); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"INFO: waiting for Invite Response Ack " - "before clearing call\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - } - } else { - /* - * Wait for the transfered call to finish and then we have - * to send Notify for the transferred call to the transferror. - * HACK to please customer. - */ - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - sip_sm_change_state(ccb, SIP_STATE_BLIND_XFER_PENDING); - } -} - -void -ccsip_handle_sentbye_ev_sip_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentbye_ev_sip_1xx"; - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is an BYE/CANCEL response */ - if (!sip_sm_is_bye_or_cancel_response(response)) { - if (sip_sm_is_invite_response(response)) { - // It could be an INVITE response if user opted to end the call - // before we received a 1xx from the remote end - // Send the deferred CANCEL now - if (ccb->flags & SEND_CANCEL) { - sipSPISendCancel(ccb); - } - } - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - free_sip_message(response); -} - -void -ccsip_handle_sentbye_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentbye_ev_sip_2xx"; - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is not a response to either CANCEL or BYE */ - if (!sip_sm_is_bye_or_cancel_response(response)) { - /* Check if this is an INVITE response */ - - //Check if the response to an INVITE and we have sent out a CANCEL - if (sip_sm_is_invite_response(response) && - (get_method_request_trx_index(ccb, sipMethodCancel, TRUE) != -1)) { - /* - * We have an outgoing CANCEL and 200 OK(INVITE) cross on the wire. - * - * We may have sent a CANCEL and around the same time, - * UAS may have responded with a 200 OK(INVITE) and - * so the CANCEL and 200 OK(INVITE) cross on the wire. - * So, the CANCEL is now useless. - * - * Actions: - * send ACK to satisfy 200 OK(INVITE) - * send BYE to initiate hangup since CANCEL is now useless - */ - char *to_tag, *sip_to_temp; - - to_tag = strstr(ccb->sip_to,";tag"); - /* - * Add the to_tag to the Ack and Bye message if it is not - * already present. - */ - if (!to_tag) { - sip_to_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - sstrncat(sip_to_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - if (ccb->sip_to_tag) { - sstrncat(sip_to_temp, ccb->sip_to_tag, - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - } - } - ccb->sip_to = strlib_close(sip_to_temp); - } - - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - sipSPISendBye(ccb, NULL, NULL); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX" %d %s Cross-over situation CANCEL/200 OK(INVITE).", - DEB_L_C_F_PREFIX_ARGS(SIP_ACK, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - } else { - //This 200 OK is not related to BYE, CANCEL, nor INVITE - //We still need to account for it remove the transaction - sipMethod_t method = sipMethodInvalid; - - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - - clean_method_request_trx(ccb, method, TRUE); - } - - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - (void) sip_platform_expires_timer_stop(ccb->index); - if (!ccb->send_delayed_bye) { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } - - if (!ccb->wait_for_ack) { - sip_sm_call_cleanup(ccb); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"INFO: waiting for Invite Response Ack " - "before clearing call\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - } - free_sip_message(response); -} - - -/* - * Just respond to the Bye in the Release state. - */ -void -ccsip_handle_release_ev_sip_bye (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "blindxfr_ev_sip_bye"; - sipMessage_t *request; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - - memset(request_check_reason_phrase, 0, SIP_WARNING_LENGTH); - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - sipGetRequestMethod(request, &method); - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - (void) sipSPISendByeOrCancelResponse(ccb, request, sipMethodBye); -} - - -void -ccsip_handle_sentblindntfy_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - (void) sip_platform_expires_timer_stop(ccb->index); - - if (ccb->flags & FINAL_NOTIFY) { - sip_sm_call_cleanup(ccb); - } else { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } - - free_sip_message(response); -} - - -void -ccsip_handle_sendbye_ev_supervision_disconnect (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - - (void) sip_platform_expires_timer_stop(ccb->index); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - sip_sm_call_cleanup(ccb); -} - -/** - * - * Handler for SIP_STATE_RELEASE features. Currently only CANCEL feature is - * supported in this state. - * - * @param line, ccb, event - * - * @return void - * - * @pre (event not NULL) - */ -/* - * SIP_STATE_RELEASE - */ -void -ccsip_handle_release_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "release_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - cc_feature_name(feature_type)); - - switch (feature_type) { - case CC_FEATURE_CANCEL: - break; - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - break; - } -} - -/** - * - * Handler for event RELEASE at SIP_STATE_RELEASE. - * sipstack is waiting for RELEASE_COMPLETE from gsm, but it got RELEASE from gsm. - * so we know that gsm also want to release the call. - * to avoid defects like CSCtg46399, we need to send RELEASE_COMPLETE to both sipstack & gsm, - * then sipstack & gsm will not wait for each other, and the call can be cleared on both sides. - * - */ -void -ccsip_handle_release_ev_release (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "release_ev_release"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - "sipstack at SIP_STATE_RELEASE received a RELEASE event from gsm"); - - /* send RELEASE_COMPLETE to sipstack */ - ccsip_handle_release_complete(ccb, event); - - /* send RELEASE_COMPLETE to gsm */ - ccsip_handle_sendbye_ev_supervision_disconnect(ccb, event); -} - - -void -ccsip_handle_recv_error_response_ev_sip_ack (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - - ccb->wait_for_ack = FALSE; - - if (ccb->send_delayed_bye) { - // If we need to send a bye, do it now. Do not change state. Clean up - // the CCB once we receive the OK for the BYE - sipSPISendBye(ccb, NULL, NULL); - } else { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - sip_sm_call_cleanup(ccb); - } - - free_sip_message(response); -} - -void -ccsip_handle_sentbye_ev_sip_fxx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentbye_ev_sip_fxx"; - sipMessage_t *response; - sipRespLine_t *respLine = NULL; - int status_code = 0; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - boolean good_authorization = FALSE; - const char *rsp_method = NULL; - char *alsoString = NULL; - sipMethod_t method = sipMethodInvalid; - enum { - INVALID, - RESP_OF_BYE, - RESP_OF_CANCEL, - RESP_OF_NOTIFY, - RESP_OF_INVITE - } resp_type = INVALID; - - /* Unpack the event */ - response = event->u.pSipMessage; - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - switch (method) { - case sipMethodInvite: - resp_type = RESP_OF_INVITE; - rsp_method = SIP_METHOD_INVITE; - break; - case sipMethodBye: - resp_type = RESP_OF_BYE; - rsp_method = SIP_METHOD_BYE; - break; - case sipMethodCancel: - resp_type = RESP_OF_CANCEL; - rsp_method = SIP_METHOD_CANCEL; - break; - case sipMethodNotify: - resp_type = RESP_OF_NOTIFY; - rsp_method = SIP_METHOD_NOTIFY; - break; - default: - resp_type = INVALID; - break; - } - - if (INVALID == resp_type) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - if (ccb->state == SIP_STATE_BLIND_XFER_PENDING) { - /* Got an error Response for Notify Message - * Just clean up at this point. - */ - sip_sm_call_cleanup(ccb); - } - return; - } - - sip_decrement_backup_active_count(ccb); - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - - if ((strcmp(rsp_method, SIP_METHOD_INVITE) == 0) && - (status_code == SIP_SERV_ERR_INTERNAL)) { - /* - * This is likely a late arriving 500 response to INVITE. - * We are already in the releasing stage of the call having - * sent a CANCEL that crossed with the 500 response. - * Just ACK the 500 and return. - */ - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Acking delayed 500 response to INVITE " - "request\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - return; - } - - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, AUTH_BUGINF(status_code)); - - if (cred_get_credentials_r(ccb, &credentials) == FALSE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"retries exceeded: %d/%d", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, MAX_RETRIES_401); - - free_sip_message(response); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR); - sip_sm_call_cleanup(ccb); - return; - } - - authenticate = sippmh_get_header_val(response, AUTH_HDR(status_code), NULL); - if (authenticate != NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Authenticate header %s= %s", DEB_F_PREFIX_ARGS(SIP_STATE, fname), - AUTH_HDR_STR(status_code), authenticate); - ccb->retx_counter = 0; - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - ccb->authen.new_flag = FALSE; - ccb->authen.cnonce[0] = '\0'; - if (sipSPIGenerateAuthorizationResponse(sip_authen, ccb->ReqURI, - rsp_method, credentials.id, - credentials.pw, - &author_str, - &(ccb->authen.nc_count), - ccb)) - { - good_authorization = TRUE; - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - if (ccb->authen.sip_authen != NULL) { - sippmh_free_authen(ccb->authen.sip_authen); - ccb->authen.sip_authen = NULL; - } - ccb->authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - - /* - * Cache the Authorization header so that it can be used for - * later requests - */ - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - ccb->authen.status_code = status_code; - ccb->authen.sip_authen = sip_authen; - } - - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Authorization header " - "build unsuccessful\n", fname); - } - /* - * CSCds70538 - * Do not free the sip_authen structure if the Authorization - * build was successful. We will need these values to generate - * an Authorization header for the BYE response - */ - if (good_authorization == FALSE) { - sippmh_free_authen(sip_authen); - } - } - if (strcmp(rsp_method, SIP_METHOD_BYE) == 0) { - clean_method_request_trx(ccb, sipMethodBye, TRUE); - if (ccb->referto[0]) { - alsoString = (char *) cpr_malloc(MAX_SIP_URL_LENGTH); - if (!alsoString) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "malloc(also string)"); - sipSPISendBye(ccb, NULL, NULL); - return; - } - sstrncpy(alsoString, ccb->referto, MAX_SIP_URL_LENGTH); - sipSPISendBye(ccb, alsoString, NULL); - cpr_free(alsoString); - return; - } - /* Send BYE message */ - sipSPISendBye(ccb, NULL, NULL); - } else if (strcmp(rsp_method, SIP_METHOD_CANCEL) == 0){ - sipSPISendCancel(ccb); - } else { - (void) sipSPISendNotify(ccb, ccb->xfer_status); - } - - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"401/407 response missing " - "Authenticate\n", fname); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR); - sip_sm_call_cleanup(ccb); - } - free_sip_message(response); - return; - - - case SIP_CLI_ERR_LOOP_DETECT: - case SIP_CLI_ERR_BUSY_HERE: - case SIP_CLI_ERR_MANY_HOPS: - case SIP_CLI_ERR_AMBIGUOUS: - case SIP_CLI_ERR_REQ_CANCEL: - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - - (void) sip_platform_expires_timer_stop(ccb->index); - if (!ccb->send_delayed_bye) { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } - - if (!ccb->wait_for_ack) { - sip_sm_call_cleanup(ccb); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"waiting for Invite Response Ack " - "before clearing call\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - } - - free_sip_message(response); - return; - - case SIP_SERV_ERR_NOT_IMPLEM: - /* It's an error response to a notify. rfc3515 tells us: - * Terminating a subscription, - * either by explicitly unsubscribing or rejecting NOTIFY, is not an - * indication that the referenced request should be withdrawn or - * abandoned. - */ - - if (strcmp (rsp_method,SIP_METHOD_NOTIFY) == 0){ - //ignore error - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Ignoring NOTIFY error. But clean up " - "transaction.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - - if (ccb->flags & FINAL_NOTIFY) { - sip_sm_call_cleanup(ccb); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Ignoring NOTIFY error. but " - "cleaning up call.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - free_sip_message(response); - return; - } - /*FALLTHROUGH*/ - - default: - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR); - sip_sm_call_cleanup(ccb); - free_sip_message(response); - return; - } -} - -/* - * Function: ccsip_handle_sentinvite_ev_sip_3xx - * - * Parameters: CCB and the event - * - * Description: Sends ack for 3xx events and appropriate invite - * - * Returns: void - * - */ -void -ccsip_handle_sentinvite_ev_sip_3xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_3xx"; - sipMessage_t *response; - sipRespLine_t *respLine; - uint16_t status_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - sip_decrement_backup_active_count(ccb); - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - switch (status_code) { - case SIP_RED_MULT_CHOICES /* 300 */: - case SIP_RED_MOVED_PERM /* 301 */: - case SIP_RED_MOVED_TEMP /* 302 */: - case SIP_RED_USE_PROXY /* 305 */: - /* - * Record the "tag=" parameter. - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - sip_sm_update_to_from_on_callsetup_finalresponse(ccb, response); - sip_sm_update_contact_recordroute(ccb, response, status_code, - FALSE /* not midcall */); - - /* - * Send ACK to the original INVITE destination or to the address - * specified by the Record-Route - */ - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - - /* Reset credentials flag before attempting redirect */ - ccb->authen.cred_type = 0; - ccb->first_pass_3xx = TRUE; - sip_redirect(ccb, response, status_code); - - break; - default: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d %d unsupported", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, status_code); - break; - } - - free_sip_message(response); -} - -void -handle_error_for_state (ccsipCCB_t *ccb, int status_code) -{ - ccsipCCB_t *referccb = NULL; - cc_causes_t fail_reason = CC_CAUSE_MIN; - - if (ccb->state == SIP_STATE_SENT_INVITE) { - if (status_code == SIP_CLI_ERR_BUSY_HERE) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_BUSY, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (status_code == SIP_SERV_ERR_UNAVAIL) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_CONGESTION, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (status_code == SIP_CLI_ERR_NOT_AVAIL) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_TEMP_NOT_AVAILABLE, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if ((status_code == SIP_CLI_ERR_MEDIA) || - (status_code == SIP_CLI_ERR_NOT_ACCEPT_HERE) || - (status_code == SIP_FAIL_NOT_ACCEPT)) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_PAYLOAD_MISMATCH, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (status_code == SIP_SERV_ERR_INTERNAL) { - // This is used to indicate a successful cfwdall interaction - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_REMOTE_SERVER_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (((status_code == SIP_CLI_ERR_BAD_REQ) || - (status_code == SIP_CLI_ERR_CALLEG)) && - (ccb->wastransferred)) { - /* clean up here because a release complete from GSM - * is not guaranteed here like in the case of pre-mature - * attended transfer request. A cause value of normal - * causes GSM to clean up the UI as well. - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - sip_sm_call_cleanup(ccb); - } else if (status_code == SIP_CLI_ERR_NOT_FOUND) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NOT_FOUND, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } else if (status_code == SIP_CLI_ERR_REQ_CANCEL) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NO_USER_ANS, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } else { - /* - * This should take care of miscellaneous errors including 400 - * bad request when its not a transfer. No special handling is - * done in case of 491 SIP_CLI_ERR_REQ_PENDING as that error is - * treated like any other 4xx in this state - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - if (ccb->blindtransferred == TRUE) { - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_ERROR; - data.notify.cause_code = status_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = sip_sm_get_blind_xfereror_ccb_by_gsm_id(ccb->gsm_id); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - - /* make sure to send the Notify if we are in a transfer - * scenario. This way the transferor can cleanup properly. - */ - if (ccb->wastransferred) { - referccb = sip_sm_get_target_call_by_gsm_id(ccb->gsm_id); - if (referccb != NULL) { - ccb->flags |= FINAL_NOTIFY; - (void) sipSPISendNotify(referccb, status_code); - ccb->xfer_status = status_code; - } - } - } else if (ccb->state == SIP_STATE_ACTIVE) { - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NONE, NULL, - CC_CAUSE_ERROR); - } else if (ccb->state == SIP_STATE_SENT_MIDCALL_INVITE) { - if (status_code == SIP_CLI_ERR_BUSY_HERE) { - fail_reason = CC_CAUSE_BUSY; - } else if ((status_code == SIP_CLI_ERR_MEDIA) || - (status_code == SIP_CLI_ERR_NOT_ACCEPT_HERE) || - (status_code == SIP_FAIL_NOT_ACCEPT)) { - fail_reason = CC_CAUSE_PAYLOAD_MISMATCH; - } else if (status_code == SIP_CLI_ERR_REQ_PENDING) { - // The other side has sent us a 491. We will let GSM handle this error and - // we shall fall back to the state we were in prior to being in any of the - // states. These are: - fail_reason = CC_CAUSE_REQUEST_PENDING; - } else if (status_code == SIP_SERV_ERR_UNAVAIL) { - fail_reason = CC_CAUSE_SERV_ERR_UNAVAIL; - } else { - fail_reason = CC_CAUSE_ERROR; - } - - /* ack the feature */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, NULL, - fail_reason); - if (status_code == SIP_CLI_ERR_REQ_TIMEOUT) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } else { - /* Other error goes back to active, let GSM decide */ - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - } - } else if (ccb->state == SIP_STATE_BLIND_XFER_PENDING) { - if (status_code == SIP_CLI_ERR_REQ_TIMEOUT) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - if (ccb->wastransferred) { - /* - * The referred call was implicitely subscribed for the notification. - * Since we get the Error from target we need to send this notify - * to transferor. - */ - cc_feature_data_t data; - - data.notify.cause = fail_reason; - data.notify.cause_code = status_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *)&data); - } -} - - -void -ccsip_handle_sentinvite_ev_sip_fxx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_fxx"; - sipMessage_t *response; - sipRespLine_t *respLine = NULL; - uint16_t status_code = 0; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - boolean good_authorization = FALSE; - sipMethod_t method = sipMethodInvalid; - const char *rsp_method = NULL; - - enum { - INVALID, - RESP_OF_INVITE, - RESP_OF_REFER, - RESP_OF_NOTIFY - } resp_type = INVALID; - - response = event->u.pSipMessage; - - /* Check if this is an INVITE response */ - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - switch (method) { - case sipMethodInvite: - resp_type = RESP_OF_INVITE; - rsp_method = SIP_METHOD_INVITE; - - /* Stop the expires timer started to await this response */ - (void) sip_platform_expires_timer_stop(ccb->index); - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - break; - case sipMethodRefer: - resp_type = RESP_OF_REFER; - rsp_method = SIP_METHOD_REFER; - break; - case sipMethodNotify: - resp_type = RESP_OF_NOTIFY; - rsp_method = SIP_METHOD_NOTIFY; - break; - default: - resp_type = INVALID; - break; - } - - if (INVALID == resp_type) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - /* - * Update the Tags here so that they will be correct if - * the user transfers a ringing call. - */ - sip_sm_200and300_update(ccb, response, status_code); - - // If the resp_type is RESP_OF_REFER and the feature type is one of the - // extendedrefer features, and the reason code is not a failure of authentication - // then indicate the error condition back to GSM - if (resp_type == RESP_OF_REFER) { - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - if (status_code != SIP_CLI_ERR_UNAUTH && status_code != SIP_CLI_ERR_PROXY_REQD) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Received error response for ext refer", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, NULL, - CC_CAUSE_ERROR); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - free_sip_message(response); - return; - } - /*FALLTHROUGH*/ - default: - break; - } - } - - sip_decrement_backup_active_count(ccb); - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"SIP_CLI_ERR_PROXY_REQD: %d: %s", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, AUTH_BUGINF(status_code)); - - /* Send ACK */ - if (method == sipMethodInvite) { - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - } - - if (cred_get_credentials_r(ccb, &credentials) == FALSE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"retries exceeded: %d/%d", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->authen.cred_type, MAX_RETRIES_401); - /* - * Retries exceeded for 40X could be due to remote end - * not responding to our Request, and while we are retrying, - * proxy could ask us to reauthenticate. So, we may exceed - * retries for credentials due to some other reason than just - * auth failure, but we do not care. status_code is passed. - */ - - handle_error_for_state(ccb, status_code); - free_sip_message(response); - return; - } - - authenticate = sippmh_get_header_val(response, AUTH_HDR(status_code), - NULL); - if (authenticate != NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Authenticate header %s= %s", DEB_F_PREFIX_ARGS(SIP_AUTH, fname), - AUTH_HDR_STR(status_code), authenticate); - - ccb->retx_counter = 0; - - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - ccb->authen.new_flag = FALSE; - /* We are sure at this point that it is either a response of - * INVITE or REFER and nothing else - */ - ccb->authen.cnonce[0] = '\0'; - ccb->authen.nc_count = 0; // New nonce, hence reset - if (sipSPIGenerateAuthorizationResponse(sip_authen, - ccb->ReqURI, - rsp_method, - credentials.id, - credentials.pw, - &author_str, - &(ccb->authen.nc_count), ccb)) { - - good_authorization = TRUE; - - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - - if (ccb->authen.sip_authen != NULL) { - sippmh_free_authen(ccb->authen.sip_authen); - ccb->authen.sip_authen = NULL; - } - - ccb->authen.authorization = (char *) cpr_malloc(strlen(author_str) * - sizeof(char) + 1); - - /* - * Cache the Authorization header so that it can be used for - * later requests - */ - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - ccb->authen.status_code = status_code; - ccb->authen.sip_authen = sip_authen; - } - - /* tell GSM we are trying */ - if (ccb->state == SIP_STATE_SENT_INVITE) { - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - } - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Authorization header " - "build unsuccessful\n", fname); - } - /* - * CSCds70538 - * Do not free the sip_authen structure if the Authorization - * build was successful. We will need these values to generate - * an Authorization header for the BYE response - */ - if (good_authorization == FALSE) { - sippmh_free_authen(sip_authen); - } - } - - switch (resp_type) { - case RESP_OF_REFER: - /* We do not need to inform about this error to GSM */ - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - - { - boolean refer_sent = FALSE; - - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - break; - default: - break; - } - - if (refer_sent) { - break; - } - } - - if (sipSPISendRefer(ccb, (char *) ccb->sip_referTo, SIP_REF_XFER) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPISendRefer Failed"); - } - break; - - case RESP_OF_INVITE: - if (ccb->state == SIP_STATE_SENT_INVITE) { - // Since we need to start a new Dialog we should clear - // any previous record route info - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - (void) sipSPISendInviteMidCall(ccb, TRUE /* does expire */); - } else { - (void) sipSPISendInviteMidCall(ccb, FALSE /* doesn't expire */); - } - break; - case RESP_OF_NOTIFY: - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - if (sipSPISendNotify(ccb, ccb->xfer_status) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPISendNotify Failed"); - } - break; - default: - break; - } - } else { - if ((ccb->redirect_info != NULL) - && (method == sipMethodInvite) - && (ccb->state == SIP_STATE_SENT_INVITE)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"401/407 response missing " - "Authenticate, redirecting to next add.\n", fname); - sip_redirect(ccb, response, status_code); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"401/407 response missing " - "Authenticate\n", fname); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Clearing call", fname); - // Delete the previous transaction block - clean_method_request_trx(ccb, method, TRUE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - - free_sip_message(response); - return; - - case SIP_CLI_ERR_NOT_ALLOWED: - case SIP_SERV_ERR_NOT_IMPLEM: - if (RESP_OF_REFER == resp_type) { - /* Error occurred on the target end so need to inform transferror */ - /* - * Since REFER method is not implemented at far side we got - * this error, at this point we need to switch to BYE/ALSO - * method. It is assumed that BYE/ALSO will be successful; - * otherwise, any way this call will be disconnected without - * any notification to the enduser which is normal if you - * use BYE/ALSO anyway. So fill up the cause as CC_CAUSE_OK - * and mimic as if transfer is done through BYE/ALSO and - * have GSM to disconnect and post us a disconnect local with - * also string - */ - cc_feature_data_t data; - - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - - ccb->referto = strlib_update(ccb->referto, ccb->sip_referTo); - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = status_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_BYE; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - } - if (method == sipMethodInvite) { - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - if ((ccb->redirect_info != NULL) && - (ccb->state == SIP_STATE_SENT_INVITE)) { - sip_redirect(ccb, response, status_code); - } else { - handle_error_for_state(ccb, status_code); - } - } - - if (method == sipMethodNotify) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } - free_sip_message(response); - break; - - case SIP_CLI_ERR_REQ_PENDING: - if (method == sipMethodInvite) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d Glare detected!", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index); - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - // The other side has detected a glare condition - - // Need to inform GSM and let it take appropriate action - handle_error_for_state(ccb, status_code); - /* - * The glare condition handling is now handled by GSM so do not need - * to set the glare timers in the stack... - if (ccb->flags & INCOMING) { - // We did not initiate this call, so set timer between 0 and 2000ms - sip_platform_glare_avoidance_timer_start(cpr_rand()%2000, - ccb->index); - } else { - // We initiated this call, so set the timer between 2100 and 4000ms - sip_platform_glare_avoidance_timer_start(cpr_rand()%2000+2100, - ccb->index); - } - */ - } - - if (method == sipMethodNotify) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } - - free_sip_message(response); - break; - - default: - if (method == sipMethodInvite) { - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - - if ((ccb->redirect_info != NULL) - && (ccb->state == SIP_STATE_SENT_INVITE)) { - sip_redirect(ccb, response, status_code); - } else { - handle_error_for_state(ccb, status_code); - } - - } else if (method == sipMethodRefer) { - ccsipCCB_t *other_ccb; - - /* - * The Transfer has failed. If the call being transferred is in the - * "Ringing" state, send a Cancel to the Proxy to tear down the call - * and free up the CCB. - */ - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - - other_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - if ((other_ccb != NULL) && - (other_ccb->state == SIP_STATE_SENT_INVITE)) { - sipSPISendCancel(other_ccb); - sip_cc_release(other_ccb->gsm_id, other_ccb->dn_line, - CC_CAUSE_NORMAL, NULL); - sip_sm_change_state(other_ccb, SIP_STATE_RELEASE); - } - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, CC_FEATURE_XFER, - NULL, CC_CAUSE_ERROR); - - } else if (method == sipMethodNotify) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } else { - handle_error_for_state(ccb, status_code); - } - free_sip_message(response); - } - -} - - - -/* - * - ***** SIP_STATE_SENT_INVITE_CONNECTED - * - */ -void -ccsip_handle_sentinviteconnected_ev_cc_connected_ack (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sentinviteconnected_ev_cc_connected_ack"; - - /* - * Do not support sending out any body in the ACK. - * Send ACK. - */ - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* - * Reset the number of retires we have for authentication - * back to 0 because at this point, if the proxy required - * authentication, our ACK with our credentials must have - * succeeded - */ -// ccb->authen.retries_401_407 = 0; - - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); -} - - -/* - * - ***** SIP_STATE_RECV_INVITE - ***** SIP_STATE_RECV_INVITE_PROCEEDING - ***** SIP_STATE_RECV_INVITE_ALERTING - ***** SIP_STATE_RECV_INVITE_CONNECTED - * - */ -void -ccsip_handle_recvinvite_ev_cc_setup_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE); - ccb->dn_line = event->u.cc_msg->msg.setup_ack.line; -} - - -void -ccsip_handle_recvinvite_ev_cc_proceeding (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_cc_proceeding"; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE_PROCEEDING); -} - - -void -ccsip_handle_recvinvite_ev_cc_alerting (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipSPISendInviteResponse180(ccb); - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE_ALERTING); -} - - -void -ccsip_handle_recvinvite_ev_cc_connected (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_cc_connected"; - int timer_h, timer_t1 = 500; - - (void) sip_platform_localexpires_timer_stop(ccb->index); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"SIPSM %d: connected", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), ccb->index); - - /* Send 200 OK */ - ccsip_save_local_msg_body(ccb, &event->u.cc_msg->msg.connected.msg_body); - sipSPISendInviteResponse200(ccb); - - // Start the INVITE Expires timer so that if we don't get an ACK we - // can release the call. Note that this timer is being reused. - config_get_value(CFGID_TIMER_T1, &timer_t1, sizeof(timer_t1)); - timer_h = 64 * timer_t1; - - if (sip_platform_expires_timer_start(timer_h, ccb->index, NULL, 0) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), fname, - "sip_platform_expires_timer_start(ACK Timer)"); - } - - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE_CONNECTED); -} - -// The handler below is called when we sent a 200OK for a received INVITE -// but never received an ACK -void -ccsip_handle_recvinvite_ev_expires_timer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_expires_timer"; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Sent 200OK but received no ACK", - DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - - // Stop the retry timer, if any - sip_platform_msg_timer_stop(ccb->index); - - // Send a BYE to the other side and change state to release - // and send release complete to GSM - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - -void -ccsip_handle_recvinvite_ev_sip_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_sip_ack"; - sipMessage_t *request; - boolean no_media = FALSE; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipsdp_status_t sdp_status; - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodAck, FALSE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - free_sip_message(request); - return; - } - // Stop the expires timer - (void) sip_platform_expires_timer_stop(ccb->index); - - ccb->authen.cred_type = 0; - - /* - * Extract SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - if (ccb->oa_state != OA_OFFER_SENT) { - /* - * Received an offer SDP in an ACK. - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Received OFFER SDP in ACK, releasing call"); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - return; - } else { - ccb->oa_state = OA_IDLE; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Using the SDP in INVITE", - DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - } - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_ERROR: - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - return; - - case SIP_SDP_NO_MEDIA: - case SIP_SDP_NOT_PRESENT: - default: - no_media = TRUE; - if (ccb->oa_state == OA_OFFER_SENT) { - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } else { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Using the SDP in INVITE", - DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - } - } - - /* - * Update connected party info from RPID and Call-Info header. - * Received ACK from the remote, media manipulation may occur. Defer - * call information update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - - if (no_media) { - sip_cc_connected_ack(ccb->gsm_id, ccb->dn_line, NULL); - } else { - sip_cc_connected_ack(ccb->gsm_id, ccb->dn_line, request); - } - - // Add code to send BYE the transferee - if (ccb->wastransferred) { - ccsipCCB_t *refererccb = NULL; - cc_feature_data_t data; - - refererccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if (NULL != refererccb) { - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = 200; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(refererccb->gsm_id, refererccb->dn_line, - CC_FEATURE_NOTIFY, (void *) &data); - } - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } - - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); -} - -// Handle a 2xx received in this state. Could be a 202 for a REFER we sent -// out while in this state -void -ccsip_handle_recvinvite_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_sip_2xx"; - sipMessage_t *response; - sipMethod_t method = sipMethodInvalid; - int response_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is a REFER response */ - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - return; - } - if (response_code == SIP_ACCEPTED && method == sipMethodRefer) { - ccsip_handle_accept_2xx(ccb, event); - return; - } - free_sip_message(response); - clean_method_request_trx(ccb, method, TRUE); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, sip_util_state2string(ccb->state)); -} - -void -ccsip_handle_disconnect_local (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "disconnect_local"; - char *alsoString = NULL; - - - /* - * If we arrived here from the SENT_INVITE_CONNECTED state, - * send an ACK for the 200 we received. - */ - if (ccb->state == SIP_STATE_SENT_INVITE_CONNECTED) { - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - } - // If we have sent an OK but not yet received the ACK, we should wait - // until it arrives before sending the BYE - if (ccb->state == SIP_STATE_RECV_INVITE_CONNECTED) { - // Stop the expires timer to receive ACK - (void) sip_platform_expires_timer_stop(ccb->index); - ccb->wait_for_ack = TRUE; - ccb->send_delayed_bye = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - return; - } - - if (ccb->referto[0]) { - alsoString = (char *) cpr_malloc(MAX_SIP_URL_LENGTH); - if (alsoString == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "malloc(also string)"); - } else { - sstrncpy(alsoString, ccb->referto, MAX_SIP_URL_LENGTH); - } - } - - /* Send BYE message */ - ccb->authen.cred_type = 0; - - sipSPISendBye(ccb, alsoString, NULL); - if (ccb->state == SIP_STATE_SENT_MIDCALL_INVITE) { - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_RESP_TIMEOUT, NULL); - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "MIDCALL INVITE TMR EXPIRED"); - } else { - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } -} - - -void -ccsip_handle_disconnect_media_change (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_disconnect_media_change"; - int code; - char *phrase; - char *alsoString = NULL; - cc_causes_t cause = CC_CAUSE_NORMAL; - - cause = event->u.cc_msg->msg.release.cause; - if (cause == CC_CAUSE_NO_MEDIA || cause == CC_CAUSE_PAYLOAD_MISMATCH) { - /* - * Send Invite Response with correct cause message - */ - code = ccsip_cc_to_sip_cause(cause, &phrase); - if (ccb->state == SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING) { - sipSPISendInviteResponse(ccb, (uint16_t) code, phrase, 0, NULL, - FALSE /* no SDP */, TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - ccb->send_delayed_bye = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - return; - } else { - (void) sipSPISendUpdateResponse(ccb, FALSE, cause, FALSE); - } - } - - if (ccb->referto[0]) { - alsoString = (char *) cpr_malloc(MAX_SIP_URL_LENGTH); - if (alsoString == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, "malloc(also string)"); - } else { - sstrncpy(alsoString, ccb->referto, MAX_SIP_URL_LENGTH); - } - } - - /* Send BYE message */ - ccb->authen.cred_type = 0; - sipSPISendBye(ccb, alsoString, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); -} - -void -ccsip_handle_disconnect_local_early (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "disconnect_local_early"; - - /* - * Note that event.type should always be checked prior to dereferencing. Failure - * to check the event type can cause non-deterministic behavior when dereferencing - * the event structure. - */ - - /* - * Check for special case early attended transfer release. - */ - if (event->type == E_CC_RELEASE) { - if (event->u.cc_msg->msg.release.cause == CC_CAUSE_NO_USER_RESP) { - ccb->early_transfer = TRUE; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "No action, Early Attended Transfer"); - return; - } - } - - /* Send CANCEL message only if we have recd at least a 1xx message in - * response to our INVITE. If not, we will mark the CCB and send it only - * when a 1xx is received - or if not - not at all - */ - if (ccb->flags & RECD_1xx) { - sipSPISendCancel(ccb); - } else { - // Defer the CANCEL - Note we'll move to the RELEASE state even if we - // defer the CANCEL - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Received CC disconnect without 1xx from far side", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Stopping retx timer"); - sip_platform_msg_timer_stop(ccb->index); - ccb->flags |= SEND_CANCEL; - } - - if (ccb->blindtransferred == TRUE) { - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = SIP_CLI_ERR_REQ_CANCEL; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = sip_sm_get_blind_xfereror_ccb_by_gsm_id(ccb->gsm_id); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, (void *)&data); - } else if (ccb->wastransferred) { - /* The call was a transfer and we are ending it before - * we connect. GSM has already cleaned up the transfer - * data blocks for this when it received the END_CALL - * message from UI. We still need to send the NOTIFY - * message to the transferor, so we will send it from - * here. - */ - ccsipCCB_t *referccb = NULL; - - referccb = sip_sm_get_target_call_by_gsm_id(ccb->gsm_id); - if (referccb != NULL) { - ccb->flags |= FINAL_NOTIFY; - (void) sipSPISendNotify(referccb, SIP_CLI_ERR_REQ_CANCEL); - ccb->xfer_status = SIP_CLI_ERR_REQ_CANCEL; - } - } - - if (event->type == E_SIP_INV_EXPIRES_TIMER) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - } else { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } - - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - -void -ccsip_handle_localexpires_timer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - /* Send 486 error */ - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BUSY_HERE, - SIP_CLI_ERR_BUSY_HERE_PHRASE, - 0, NULL, FALSE, /* no SDP */ TRUE /* reTx */); - - /* tell GSM to cleanup */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - -static void -ccsip_cc_to_warning (cc_causes_t cause, char **warning_phrase, - uint16_t *warning_code) -{ - switch (cause) { - - case CC_CAUSE_PAYLOAD_MISMATCH: - *warning_phrase = SIP_WARN_INCOMPAT_MEDIA_FORMAT_PHRASE; - *warning_code = SIP_WARN_INCOMPAT_MEDIA_FORMAT; - break; - - case CC_CAUSE_NO_MEDIA: - *warning_phrase = SIP_WARN_MEDIA_TYPE_UNAVAIL_PHRASE; - *warning_code = SIP_WARN_MEDIA_TYPE_UNAVAIL; - break; - - default: - *warning_phrase = NULL; - *warning_code = 0; - } - -} - - -int -ccsip_cc_to_sip_cause (cc_causes_t cause, char **phrase) -{ - switch (cause) { - - case CC_CAUSE_OK: - *phrase = SIP_SUCCESS_SETUP_PHRASE; - return SIP_SUCCESS_SETUP; - - case CC_CAUSE_ERROR: - *phrase = SIP_CLI_ERR_BAD_REQ_PHRASE; - return SIP_CLI_ERR_BAD_REQ; - - case CC_CAUSE_UNASSIGNED_NUM: - *phrase = SIP_CLI_ERR_NOT_FOUND_PHRASE; - return SIP_CLI_ERR_NOT_FOUND; - - case CC_CAUSE_NO_RESOURCE: - *phrase = SIP_SERV_ERR_INTERNAL_PHRASE; - return SIP_SERV_ERR_INTERNAL; - - case CC_CAUSE_BUSY: - *phrase = SIP_CLI_ERR_BUSY_HERE_PHRASE; - return SIP_CLI_ERR_BUSY_HERE; - - case CC_CAUSE_ANONYMOUS: - *phrase = SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE; - return SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED; - - case CC_CAUSE_INVALID_NUMBER: - *phrase = SIP_CLI_ERR_ADDRESS_PHRASE; - return SIP_CLI_ERR_ADDRESS; - - case CC_CAUSE_PAYLOAD_MISMATCH: - *phrase = SIP_CLI_ERR_NOT_ACCEPT_HERE_PHRASE; - return SIP_CLI_ERR_NOT_ACCEPT_HERE; - - case CC_CAUSE_NO_REPLACE_CALL: - *phrase = SIP_CLI_ERR_CALLEG_PHRASE; - return SIP_CLI_ERR_CALLEG; - - case CC_CAUSE_REQUEST_PENDING: - *phrase = SIP_CLI_ERR_REQ_PENDING_PHRASE; - return SIP_CLI_ERR_REQ_PENDING; - - default: - *phrase = SIP_CLI_ERR_BAD_REQ_PHRASE; - return SIP_CLI_ERR_BAD_REQ; - } -} - -void -ccsip_handle_disconnect_local_unanswered (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - int code; - char *phrase; - uint16_t warning_code = 0; - char *warning_phrase = NULL; - - ccb->dn_line = event->u.cc_msg->msg.release.line; - code = ccsip_cc_to_sip_cause(event->u.cc_msg->msg.release.cause, &phrase); - - ccsip_cc_to_warning(event->u.cc_msg->msg.release.cause, &warning_phrase, &warning_code); - - /* Send Invite Response with correct cause message */ - sipSPISendInviteResponse(ccb, (uint16_t)code, phrase, warning_code, - warning_phrase, - FALSE /*no SDP */ , TRUE /*reTx */ ); - - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - - -void -ccsip_handle_disconnect_remote (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "disconnect_remote"; - sipMessage_t *request; - sipMessage_t *store_invite_req; - const char *alsoString = NULL, *reasonHdr=NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - cc_causes_t cause = CC_CAUSE_NORMAL; - - memset(request_check_reason_phrase, 0, SIP_WARNING_LENGTH); - - /* Unpack the event */ - request = event->u.pSipMessage; - store_invite_req = ccb->last_request; - - sipGetRequestMethod(request, &method); - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, TRUE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - // Stop the expires timer - (void) sip_platform_expires_timer_stop(ccb->index); - - //Check if this BYE is for the original call (between - //transferor and transferee) in attended transfer scenario. - if (ccb->con_call_id != CC_NO_CALL_ID) { - //Transferee has received a BYE - //from the transferor. Two scenarios are possible: - //1. BYE is received after receiving the 2xx/4xx/5xx/6xx for the - // consultative call. Therefore, setting wasTransferred flag - // to FALSE has no impact. - //2. BYE is received before receiving the 2xx/4xx/5xx/6xx for the - // consultative call. - // Therefore, setting wastransferred flag - // to FALSE, results in not sending the final NOTIFY - // after receiving 2xx/4xx/5xx/6xx from the target. - ccsipCCB_t *other_ccb; - - other_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - if (other_ccb) { - other_ccb->wastransferred = FALSE; - strlib_free(other_ccb->sipxfercallid); - other_ccb->sipxfercallid = strlib_empty(); - } - } - - - /* - * Detect whether this is a Call Transfer by checking - * for the presence of the "Also:" header - */ - alsoString = sippmh_get_header_val(request, SIP_HEADER_ALSO, NULL); - if (alsoString) { - cc_feature_data_t data; - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d Far end requested Call Transfer, " - "destination=<%s>\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, alsoString); - sstrncpy(data.xfer.dialstring, alsoString, strlen(alsoString) + 1); - data.xfer.cause = CC_CAUSE_XFER_REMOTE; - data.xfer.method = CC_XFER_METHOD_BYE; - data.xfer.target_call_id = CC_NO_CALL_ID; - ccb->referto = strlib_update(ccb->referto, alsoString); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_XFER, (void *)&data); - (void) sipSPISendByeOrCancelResponse(ccb, request, sipMethodBye); - free_sip_message(store_invite_req); - return; - } else { - /* Send BYE response message */ - if (event->type == E_SIP_BYE) { - /* - * We want to wait for release_complete from GSM before sending - * the 200 OK out, in order to collect call_stats - */ - ccb->flags |= RECD_BYE; - } else { - (void) sipSPISendByeOrCancelResponse(ccb, request, sipMethodCancel); - // if the reason header contains a reason code of 200 - // we should pass this forward to gsm - reasonHdr = sippmh_get_header_val(request, SIP_HEADER_REASON, NULL); - if ( reasonHdr && strcasestr(reasonHdr, "cause=200;") ) { - cause = CC_SIP_CAUSE_ANSWERED_ELSEWHERE; - } - } - - if (SIP_SM_CALL_SETUP_RESPONDING(ccb) || - ccb->state == SIP_STATE_RECV_INVITE || - ccb->state == SIP_STATE_RECV_INVITE_CONNECTED) { - /* - * Store invite request into ccb before sending 487. This is a - * temporary solution and should be removed in Moonpie - */ - sipGetRequestMethod(store_invite_req, &method); - if (sip_sm_request_check_and_store(ccb, store_invite_req, method, - TRUE, &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - free_sip_message(store_invite_req); - return; - } - sipSPISendInviteResponse(ccb, 487, SIP_CLI_ERR_REQ_CANCEL_PHRASE, 0, - NULL, FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - } else { - free_sip_message(store_invite_req); - } - - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, cause, NULL); - } -} - -/* E_SIP_REFER */ -void -ccsip_handle_refer_sip_message (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "refer_sip_message"; - sipMessage_t *request; - const char *contact = NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - cc_feature_data_t data; - char *referToString[MAX_REFER_TO_HEADERS] = { NULL }; - char *referByString; - sipReferTo_t *referto = NULL; - sipReplaces_t *replaces_t = NULL; - int noOfReferTo = 0; - int noOfReferBy = 0; - char tempreferto[MAX_SIP_URL_LENGTH]; - int rpid_flag = RPID_DISABLED; - char tempreferby[MAX_SIP_URL_LENGTH]; - char *semi_token = NULL; - int rcode; - sipContact_t *contact_info = NULL; - - memset(tempreferto, 0, MAX_SIP_URL_LENGTH); - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* transfer method if attended or blind */ - ccb->featuretype = CC_FEATURE_BLIND_XFER; // Default is Blind - - sipGetRequestMethod(request, &method); - - // Check if we are already processing a previously received REFER - if (get_method_request_trx_index(ccb, method, FALSE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received REFER while processing an old one!", fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_REQ_PENDING, - SIP_CLI_ERR_REQ_PENDING_PHRASE, - 0, NULL, NULL); - free_sip_message(request); - return; - } - - - /* Request check and store */ - rcode = sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE); - if (rcode < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - - if (rcode == -2) { // trx malloc error - (void) sipSPISendErrorResponse(request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - } else { - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - } - free_sip_message(request); - return; - } - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (sipSPICheckContact(contact) < 0) { // If contact is invalid - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPICheckContact()"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - ccb); - return; - } - contact_info = sippmh_parse_contact(contact); - if (contact_info && contact_info->num_locations > 1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received REFER with multiple contacts!", fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_AMBIGUOUS, - SIP_CLI_ERR_AMBIGUOUS_PHRASE, - SIP_WARN_MISC, - SIP_WARN_REFER_AMBIGUOUS_PHRASE, - ccb); - sippmh_free_contact(contact_info); - return; - } - if (contact_info) { - sippmh_free_contact(contact_info); - } - } else { // If No contact header - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - ccb); - return; - } - - /* - * Update connected party info from RPID and Call-Info header. - * Handing REFER, do not defer call information update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - - // Store Refer Information such as Call_id and to-tag - // If replace is present then it must be attended transfer - noOfReferTo = sippmh_get_num_particular_headers(request, SIP_HEADER_REFER_TO, - SIP_C_HEADER_REFER_TO, - referToString, MAX_REFER_TO_HEADERS); - - if (noOfReferTo == 1) { - referto = sippmh_parse_refer_to(referToString[0]); - } - - if ((noOfReferTo == 0) || (noOfReferTo > 1) || (referto == NULL)) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "Incorrect number of Refer-To headers and/or value.\n"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - ccb); - - if (referto) { - cpr_free(referto); - } - return; - } - - sipSPIGenerateTargetUrl(referto->targetUrl, tempreferto); - ccb->sip_referTo = strlib_update(ccb->sip_referTo, tempreferto); - if (referto->sip_replaces_hdr != NULL) { - char tempreplace[MAX_SIP_URL_LENGTH]; - - memset(tempreplace, 0, MAX_SIP_URL_LENGTH); - sstrncpy(tempreplace, "Replaces=", sizeof(tempreplace)); - sstrncat(tempreplace, referto->sip_replaces_hdr, (sizeof(tempreplace) - sizeof("Replaces="))); - replaces_t = sippmh_parse_replaces(tempreplace, FALSE); - if (NULL != replaces_t) { - ccb->sipxfercallid = strlib_update(ccb->sipxfercallid, replaces_t->callid); - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, ";to-tag="); - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, replaces_t->toTag); - } - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, ";from-tag="); - } - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, replaces_t->fromTag); - } - } - ccb->featuretype = CC_FEATURE_XFER; - sippmh_free_replaces(replaces_t); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "replaces header in referto missing callid or to/from tags"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - ccb); - sippmh_free_refer_to(referto); - return; - } - } -#ifdef SIP_ACC_CONT - if (referto->sip_acc_cont != NULL) { - // attach the new string to the ccb... - // Note: This doesn't currently generate any header, but the hook - // is here if we need it later. - if (ccb->refer_acc_cont != NULL) { - cpr_free(ccb->refer_acc_cont); - ccb->refer_acc_cont = NULL; - } - ccb->refer_acc_cont = cpr_strdup(referto->sip_acc_cont); - } -#endif - - if (referto->sip_proxy_auth != NULL) { - if (ccb->refer_proxy_auth != NULL) { - // if there was already one of these, toss it out - cpr_free(ccb->refer_proxy_auth); - ccb->refer_proxy_auth = NULL; - } - // attach the new string to the ccb... - ccb->refer_proxy_auth = cpr_strdup(referto->sip_proxy_auth); - } - - noOfReferBy = sippmh_get_num_particular_headers(request, - SIP_HEADER_REFERRED_BY, - SIP_C_HEADER_REFERRED_BY, - &referByString, - MAX_REFER_BY_HEADERS); - - if (noOfReferBy == 0) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Missing referred by header\n"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_BY, - ccb); - sippmh_free_refer_to(referto); - return; - } - - if (noOfReferTo > 1 || noOfReferBy > 1) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Multiple referto or refer by headers found in message"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER, - ccb); - sippmh_free_refer_to(referto); - return; - } - - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - - if ((rpid_flag == RPID_ENABLED) && (ccb->best_rpid) - && (cpr_strcasecmp(ccb->best_rpid->privacy, PRIVACY_OFF) != 0)) { - snprintf(tempreferby, MAX_SIP_URL_LENGTH, "\"%s\" ", - SIP_HEADER_ANONYMOUS_STR, - ccb->best_rpid->loc->genUrl->u.sipUrl->user, - ccb->best_rpid->loc->genUrl->u.sipUrl->host); - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, tempreferby); - } else { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, referByString); - } - - sstrncpy(data.xfer.dialstring, referToString[0], sizeof(data.xfer.dialstring)); - semi_token = strchr(data.xfer.dialstring, '?'); - if (semi_token) { - *semi_token++ = '>'; - *semi_token = 0; - } - if (data.xfer.dialstring[0] != '<') { - semi_token = strchr(data.xfer.dialstring, '>'); - if (semi_token) { - *semi_token = 0; - } - } - - /* Convert the escapeed userino part, if any to unescaped format */ - if (unescape_UserInfo(data.xfer.dialstring, tempreferto, MAX_SIP_URL_LENGTH)) { - memset(data.xfer.dialstring, 0, CC_MAX_DIALSTRING_LEN); - sstrncpy(data.xfer.dialstring, tempreferto, CC_MAX_DIALSTRING_LEN); - } - - data.xfer.method = CC_XFER_METHOD_REFER; - data.xfer.target_call_id = CC_NO_CALL_ID; - data.xfer.cause = CC_CAUSE_XFER_REMOTE; - if (ccb->featuretype == CC_FEATURE_BLIND_XFER) { - sstrncpy(data.xfer.referred_by, ccb->sip_referredBy, - MAX_SIP_URL_LENGTH); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_BLIND_XFER, - (void *) &data); - } else { - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_XFER, - (void *) &data); - } - sippmh_free_refer_to(referto); -} - -void -ccsip_handle_process_in_call_options_request (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_process_in_call_options_request"; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMessage_t *request; - sipMethod_t method = sipMethodInvalid; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Processing within-dialog OPTIONS request", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - - /* Unpack the event */ - request = event->u.pSipMessage; - - ccb->featuretype = CC_FEATURE_NONE; - - /* Request check and store */ - sipGetRequestMethod(request, &method); - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - // fixed CSCsi68191: The ccb->last_request and event->u.pSipMessage pointed to same memory address. - // Set last_request to NULL to avoid double deletion of memory, which is freed by - // gsm event of OPTION ACK later. - ccb->last_request = NULL; - sip_cc_options(ccb->gsm_id, ccb->dn_line, event->u.pSipMessage); -} - -void -ccsip_handle_ev_cc_answer_options_request (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_ev_cc_answer_options_request"; - cc_options_sdp_ack_t *options_sdp_ack; - - options_sdp_ack = (cc_options_sdp_ack_t *) event->u.cc_msg; - - if (!ccb) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Processing OPTIONS (out of dialog) " - "request(GSM has responded)\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - (void) sipSPIsendNonActiveOptionResponse((sipMessage_t *) options_sdp_ack->pMessage, - &options_sdp_ack->msg_body); - - //since there is no call and therefore no ccb, we must free - //the SIP OPTIONS message here. - free_sip_message((sipMessage_t *)options_sdp_ack->pMessage); - options_sdp_ack->pMessage = NULL; - } else { - //Since there is a ccb, the SIP OPTIONS message will be freed - //in sip_sm_call_cleanup() after the call is done. - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Processing OPTIONS (in dialog) " - "request(GSM has responded)\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - - // Must save sdp from gsm to ccb before building the response - ccsip_save_local_msg_body(ccb, &options_sdp_ack->msg_body); - (void) sipSPISendOptionResponse(ccb, event->u.pSipMessage); - } -} - -void -ccsip_handle_ev_cc_answer_audit_request (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - cc_audit_sdp_ack_t *audit_ack; - - - audit_ack = (cc_audit_sdp_ack_t *) event->u.cc_msg; - /* - * Use the new sdp generated by the gsm and free the old copy. - */ - ccsip_save_local_msg_body(ccb, &audit_ack->msg_body); - sipSPISendInviteResponse200(ccb); -} - -int -sip_sm_process_event (sipSMEvent_t *pEvent) -{ - const char *fname = "sip_sm_process_event"; - ccsipCCB_t *ccb; - sipSMAction_t event_handler = H_INVALID_EVENT; - - ccb = pEvent->ccb; - if (!ccb) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccb is null. Unable to process event " - "<%d>\n", fname, pEvent->type); - return (-1); - } - - /* Unbind UDP ICMP response handler */ - UNBIND_UDP_ICMP_HANDLER(ccb->udpId); - - /* - * ccb->index is an unsigned type and TEL_CCB_START is zero, - * so just check the end condition - */ - if ((int) (ccb->index) > TEL_CCB_END) { - // We got an illegal line for our SIP SM - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal line number: %d", - fname, ccb->index); - return (-1); - } - - if (!sip_config_check_line(ccb->dn_line)) { - // We got an illegal DN for our SIP SM - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal directory number: %d", - fname, ccb->dn_line); - return (-1); - } - - if ((event_handler = get_handler_index(ccb->state, pEvent->type)) - != H_INVALID_EVENT) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Processing SM event: %d: --%p--%21s: %s <- %s", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, EVENT_ACTION_SM(event_handler), - "", sip_util_state2string(ccb->state), - sip_util_event2string(pEvent->type)); - - EVENT_ACTION_SM(event_handler) (ccb, pEvent); - } else { - /* Invalid State/Event pair */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal state/event pair: " - "(%d <-- %d)\n", fname, ccb->state, pEvent->type); - return (-1); - } - - return (0); -} - - -/** - * - * Extract the k factor stats sent by GSM and store a ptr on ccb - * - * @param pCCMsg - msg from GSM - * @param ccb - ccb for this call - * - * @return nothing - */ -void -sip_extract_kfactor_stats (cc_msg_t *pCCMsg, ccsipCCB_t *ccb) -{ - if (pCCMsg->msg.release.msg_id == CC_MSG_RELEASE) { - ccb->kfactor_ptr = &pCCMsg->msg.release.kfactor; - } else if (pCCMsg->msg.release_complete.msg_id == CC_MSG_RELEASE_COMPLETE) { - ccb->kfactor_ptr = &pCCMsg->msg.release_complete.kfactor; - } else if ((pCCMsg->msg.feature.msg_id == CC_MSG_FEATURE) || - (pCCMsg->msg.feature.msg_id == CC_MSG_FEATURE_ACK)) { - if (pCCMsg->msg.feature.feature_id == CC_FEATURE_HOLD) { - ccb->kfactor_ptr = &pCCMsg->msg.feature.data.hold.kfactor; - } else if (pCCMsg->msg.feature.feature_id == CC_FEATURE_MEDIA) { - ccb->kfactor_ptr = &pCCMsg->msg.feature.data.resume.kfactor; - } else { - ccb->kfactor_ptr = NULL; - } - } else { - ccb->kfactor_ptr = NULL; - } -} -int -sip_sm_process_cc_event (cprBuffer_t buf) -{ - const char *fname = "sip_sm_process_cc_event"; - sipSMEvent_t sip_sm_event; - line_t idx = 0; - sipSMAction_t event_handler = H_INVALID_EVENT; - cc_msg_t *pCCMsg = (cc_msg_t *) buf; - - memset(&sip_sm_event, 0, sizeof(sipSMEvent_t)); - - sip_sm_event.u.cc_msg = pCCMsg; - sip_sm_event.type = sip_util_ccevent2sipccevent(pCCMsg->msg.setup.msg_id); - if (pCCMsg->msg.setup.msg_id == CC_MSG_SETUP) { - sip_sm_event.ccb = sip_sm_get_ccb_next_available(&idx); - if (!sip_sm_event.ccb) { - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No free lines available", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } - } else if (pCCMsg->msg.setup.msg_id == CC_MSG_OPTIONS_ACK) { - /* - * Process the out of dialogue and in dialogue option ack - * (local sdp built by the gsm) - */ - sip_sm_event.ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.setup.call_id); - ccsip_handle_ev_cc_answer_options_request(sip_sm_event.ccb, &sip_sm_event); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return (SIP_OK); - } else if (ccsip_handle_cc_select_event(&sip_sm_event)) { - /* - * The select feature has been handled. - */ - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } else if (ccsip_handle_cc_b2bjoin_event(&sip_sm_event)) { - /* - * The b2bjoin feature has been handled. - */ - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } else if (ccsip_handle_cc_hook_event(&sip_sm_event) == TRUE) { - /* - * The hook event has been handled. - */ - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } else { - sip_sm_event.ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.setup.call_id); - if (!sip_sm_event.ccb) { - // If there is no associated CCB, this could be an - // Out of Dialog feature request - if (pCCMsg->msg.setup.msg_id == CC_MSG_FEATURE) { - // Call function to process an OOD Feature - // OOD features are handled by the sub/not API - // If unsuccessful processing - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - } else if (pCCMsg->msg.setup.msg_id == CC_MSG_RELEASE) { - sip_cc_release_complete(pCCMsg->msg.setup.call_id, - pCCMsg->msg.setup.line, CC_CAUSE_ERROR); - } else { - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No ccb with matching gsm_id = <%d>", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), - pCCMsg->msg.setup.call_id); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } - } - - if (pCCMsg->msg.setup.msg_id == CC_MSG_AUDIT_ACK) { - /* - * Process the in dialogue audit ack - * (local sdp built by the gsm) - */ - ccsip_handle_ev_cc_answer_audit_request(sip_sm_event.ccb, &sip_sm_event); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return (SIP_OK); - } - - /* CSCds88133: ReTx timers cancelled prematurely */ - if (sip_sm_event.ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - /* RAC FIXME - Don't like this... */ - line_t line_index = (line_t) -1; - - sip_sm_event.ccb = sip_sm_get_ccb_next_available(&line_index); - if (!sip_sm_event.ccb) { - if (pCCMsg->msg.setup.msg_id == CC_MSG_RELEASE) { - sip_cc_release_complete(pCCMsg->msg.setup.call_id, - pCCMsg->msg.setup.line, CC_CAUSE_ERROR); - } else { - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - } - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_get_ccb_next_available()" - " returned null.\n", fname); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } - /* Set this ccb to always be on the first DN. */ - sip_sm_event.ccb->dn_line = 1; - } - - sip_extract_kfactor_stats(pCCMsg, sip_sm_event.ccb); - event_handler = get_handler_index(sip_sm_event.ccb->state, sip_sm_event.type); - if (event_handler != H_INVALID_EVENT) { - - DEF_DEBUG(DEB_L_C_F_PREFIX"Processing CC event: %p: SM: %s <- %s", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, sip_sm_event.ccb->dn_line, - sip_sm_event.ccb->gsm_id, fname), - buf, - sip_util_state2string(sip_sm_event.ccb->state), - sip_util_event2string(sip_sm_event.type)); - - EVENT_ACTION_SM(event_handler)(sip_sm_event.ccb, &sip_sm_event); - } else { - /* Invalid State/Event pair */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal state/event pair: (%d <-- %d)", - fname, sip_sm_event.ccb->state, sip_sm_event.type); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_ERROR; - } - sip_sm_event.ccb->kfactor_ptr = NULL; - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; -} - -void -ccsip_handle_send_blind_notify (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "send_blind_notify"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - cc_feature_name(feature_type)); - - if (CC_FEATURE_NOTIFY == feature_type) { - if (event->u.cc_msg->msg.feature.data.notify.final == TRUE) { - ccb->flags |= FINAL_NOTIFY; - } - (void) sipSPISendNotify(ccb, event->u.cc_msg->msg.feature.data.notify.cause_code); - ccb->xfer_status = event->u.cc_msg->msg.feature.data.notify.cause_code; - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - } -} - -void -sip_sm_call_cleanup (ccsipCCB_t *ccb) -{ - const char *fname = "sip_sm_call_cleanup"; - int i = 0; - - if (ccb == NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Null CCB passed into function.", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - return; - } - - /* first time the phone boots, this function gets called, but the - * CCBs haven't been initialized yet. This is the only time the - * dn_line can be zero. Otherwise, zero is invalid. On the first - * bootup, we don't need to do anything in this function. - */ - if (ccb->dn_line == 0) { - return; - } - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, "Cleaning up the call"); - - /* - * If there are any shared pointers because of duping - * make sure we have taken care of those - */ - if (ccb->dup_flags & DUP_CCB) { - free_duped(ccb); - } - - /* Cancel any outstanding timers */ - (void) sip_platform_localexpires_timer_stop(ccb->index); - - /* - * ccb->index is an unsigned type and TEL_CCB_START is zero, - * so just check the end condition - */ - if ((int) (ccb->index) <= TEL_CCB_END) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - submanager_update_ccb_addr(ccb); - } - - /* Unbind UDP ICMP Unreachable handler just incase */ - UNBIND_UDP_ICMP_HANDLER(ccb->udpId); - - /* Free DNS Srv handle if present */ - if (ccb->SRVhandle != NULL) { - dnsFreeSrvHandle(ccb->SRVhandle); - ccb->SRVhandle = NULL; - } - - /* Free Ooutbound proxy DNS Srv handle if present */ - if (ccb->ObpSRVhandle != NULL) { - dnsFreeSrvHandle(ccb->ObpSRVhandle); - ccb->ObpSRVhandle = NULL; - } - - /* - * Store call history info - */ - if ((int) (ccb->index) <= TEL_CCB_END) { - (void) sip_platform_expires_timer_stop(ccb->index); - (void) sip_platform_register_expires_timer_stop(ccb->index); - // bugid: CSCsz34666 - memcpy(gCallHistory[ccb->index].last_call_id, ccb->sipCallID, - MAX_SIP_CALL_ID); - } - - /* Free message bodies were saved during the cause of the call */ - cc_free_msg_body_parts(&ccb->local_msg_body); - - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - /* Free last recorded request */ - if (ccb->last_request) { - free_sip_message(ccb->last_request); - ccb->last_request = NULL; - } - - /* Free CC-Diversion headers */ - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - if (ccb->diversion[i]) { - cpr_free(ccb->diversion[i]); - ccb->diversion[i] = NULL; - } - } - - sippmh_free_diversion_info(ccb->div_info); - ccb->div_info = NULL; - ccb->call_type = CC_CALL_NONE; - - /* Free Redirection structure */ - if (ccb->redirect_info) { - sippmh_free_contact(ccb->redirect_info->sipContact); - cpr_free(ccb->redirect_info); - ccb->redirect_info = NULL; - } - - ccb->best_rpid = NULL; - sippmh_free_remote_party_id_info(ccb->rpid_info); - ccb->rpid_info = NULL; - -// ccb->authen.retries_401_407 = 0; - ccb->authen.cnonce[0] = '\0'; - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - if (ccb->refer_proxy_auth != NULL) { - cpr_free(ccb->refer_proxy_auth); - ccb->refer_proxy_auth = NULL; - } -#ifdef SIP_ACC_CONT - if (ccb->refer_acc_cont != NULL) { - cpr_free(ccb->refer_acc_cont); - ccb->refer_acc_cont = NULL; - } -#endif - - if (ccb->authen.sip_authen != NULL) { - sippmh_free_authen(ccb->authen.sip_authen); - ccb->authen.sip_authen = NULL; - } - - ccb->hold_initiated = FALSE; - ccb->wastransferred = FALSE; - ccb->blindtransferred = FALSE; - ccb->gsm_id = CC_NO_CALL_ID; - ccb->con_call_id = CC_NO_CALL_ID; - ccb->blind_xfer_call_id = CC_NO_CALL_ID; - ccb->xfer_status = 0; - - if (ccb->old_session_id != NULL) { - cpr_free(ccb->old_session_id); - } - if (ccb->old_version_id != NULL) { - cpr_free(ccb->old_version_id); - } - ccb->old_session_id = NULL; - ccb->old_version_id = NULL; - - ccb->displayCalledNumber = TRUE; - ccb->displayCallingNumber = TRUE; - - /*free all the dynamically allocated strings */ - - strlib_free(ccb->calledDisplayedName); - strlib_free(ccb->callingNumber); - strlib_free(ccb->altCallingNumber); - strlib_free(ccb->callingDisplayName); - strlib_free(ccb->calledNumber); - strlib_free(ccb->ReqURIOriginal); - strlib_free(ccb->sip_from); - strlib_free(ccb->sip_to); - strlib_free(ccb->sip_to_tag); - strlib_free(ccb->sip_from_tag); - strlib_free(ccb->sip_contact); - strlib_free(ccb->sip_reqby); - strlib_free(ccb->sip_require); - strlib_free(ccb->sip_unsupported); - strlib_free(ccb->referto); - strlib_free(ccb->sip_referTo); - strlib_free(ccb->sip_referredBy); - strlib_free(ccb->sipxfercallid); - strlib_free(ccb->sip_remote_party_id); - - if (ccb->in_call_info) { - ccsip_free_call_info_header(ccb->in_call_info); - ccb->in_call_info = NULL; - } - if (ccb->out_call_info) { - ccsip_free_call_info_header(ccb->out_call_info); - ccb->out_call_info = NULL; - } - if (ccb->join_info) { - sippmh_free_join_info(ccb->join_info); - ccb->join_info = NULL; - } - if (ccb->feature_data) { - cpr_free(ccb->feature_data); - ccb->feature_data = NULL; - } - - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - ccb->sent_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->sent_request[i].cseq_method = sipMethodInvalid; - strlib_free(ccb->sent_request[i].u.sip_via_branch); - strlib_free(ccb->sent_request[i].sip_via_sentby); - ccb->recv_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->recv_request[i].cseq_method = sipMethodInvalid; - strlib_free(ccb->recv_request[i].u.sip_via_header); - strlib_free(ccb->recv_request[i].sip_via_sentby); - } - - if (ccb->index >= REG_CCB_START) { - /* - * Necessary to cast the SIP_REG_STATE_IDLE to properly initialize - * registration CCBs which use the same ccb->state field. - */ - (void) sip_sm_ccb_init(ccb, ccb->index, ccb->dn_line, - SIP_REG_STATE_IDLE); - return; - } - - if (sip_platform_msg_timer_outstanding_get(ccb->index)) { - sip_sm_change_state(ccb, SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING); - (void) sip_sm_ccb_init(ccb, ccb->index, ccb->dn_line, - SIP_REG_STATE_IDLE /*_MSG_TIMER_OUTSTANDING */); - } else { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - (void) sip_sm_ccb_init(ccb, ccb->index, 1, SIP_REG_STATE_IDLE); - } - -} - - -int -sip_sm_ccb_init (ccsipCCB_t *ccb, line_t ccb_index, int DN, - sipRegSMStateType_t initial_state) -{ - int nat_enable = 0; - uint8_t i; - - /* - * TEL_CCB_START equates to zero and line_t is an unsigned type, - * so just check the end condition - */ - if ((int) ccb_index <= TEL_CCB_END) { - memset(ccb, 0, sizeof(ccsipCCB_t)); - } - - ccb->dup_flags = DUP_NO_FLAGS; - ccb->mother_ccb = NULL; - sip_reg_sm_change_state(ccb, initial_state); /* print the debug msg also */ - ccb->index = ccb_index; - ccb->hold_initiated = FALSE; - ccb->wastransferred = FALSE; - ccb->blindtransferred = FALSE; - ccb->callingNumber = strlib_empty(); - ccb->calledNumberFirstDigitDialed = FALSE; - ccb->calledNumber = strlib_empty(); - ccb->altCallingNumber = strlib_empty(); - ccb->calledDisplayedName = strlib_empty(); - ccb->callingDisplayName = strlib_empty(); - ccb->displayCalledNumber = TRUE; - ccb->displayCallingNumber = TRUE; - ccb->calledNumberLen = 0; - ccb->ReqURIOriginal = strlib_empty(); - ccb->sip_to_tag = strlib_empty(); - ccb->sip_from_tag = strlib_empty(); - ccb->sip_contact = strlib_empty(); - ccb->sip_reqby = strlib_empty(); - ccb->sip_require = strlib_empty(); - ccb->sip_unsupported = strlib_empty(); - ccb->sip_remote_party_id = strlib_empty(); - ccb->flags = 0; - ccb->avt.payload_type = RTP_NONE; - ccb->alert_info = ALERTING_NONE; - ccb->alerting_ring = VCM_INSIDE_RING; - ccb->wait_for_ack = FALSE; - ccb->send_delayed_bye = FALSE; - ccb->retx_flag = FALSE; - ccb->early_transfer = FALSE; - ccb->redirect_info = NULL; - ccb->proxySelection = SIP_PROXY_DEFAULT; - ccb->outBoundProxyAddr = ip_addr_invalid; - ccb->outBoundProxyPort = 0; - ccb->oa_state = OA_IDLE; - ccb->call_type = CC_CALL_NONE; - ccb->cc_cfg_table_entry = NULL; - ccb->first_pass_3xx = TRUE; - - /* Sip msg destination is set to proxy by default */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(ccb->src_addr)); - } else { - sip_config_get_nat_ipaddr(&(ccb->src_addr)); - } - - config_get_value(CFGID_VOIP_CONTROL_PORT, &ccb->local_port, - sizeof(ccb->local_port)); - - if ((int) ccb_index <= TEL_CCB_END) { - ccb->type = SIP_CALL_CCB; - ccb->dn_line = (line_t) DN; - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - ccb->sipCallID[0] = '\0'; - } else if ((ccb_index >= REG_CCB_START) && (ccb_index <= REG_CCB_END)) { - ccb->type = SIP_REG_CCB; - ccb->dn_line = ccb_index - MAX_TEL_LINES + 1; - sip_regmgr_set_cc_info(ccb_index, ccb->dn_line, &ccb->cc_type, - (void *)&ccb->cc_cfg_table_entry); - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - If type of call control is ccm set the - * address here as well. - */ - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } else { - /* - * regmgr - Assume it is CSPS for now. - */ - ccb->dest_sip_addr = ip_addr_invalid; - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - } else if (ccb_index == REG_BACKUP_CCB) { - ccb->type = SIP_REG_CCB; - ccb->dn_line = REG_BACKUP_DN; - sip_regmgr_set_cc_info(ccb_index, ccb->dn_line, &ccb->cc_type, - &ccb->cc_cfg_table_entry); - if (ccb->cc_type != CC_CCM) { - /* - * regmgr - Assume it is CSPS for now. - */ - sipTransportGetBkupServerAddress(&ccb->dest_sip_addr, ccb->dn_line, ccb->reg.proxy); - ccb->dest_sip_port = sipTransportGetBkupServerPort(ccb->dn_line); - } - } else if ((ccb_index >= REG_FALLBACK_CCB_START) && - (ccb_index <= REG_FALLBACK_CCB_END)) { - /* - * regmgr - There can be upto 3 fallback ccb's that get created - * dynamically. If the ccb index indicates that then set the - * type to be SIP_REG_CCB so that the register state - * machine gets the event. - */ - ccb->type = SIP_REG_CCB; - ccb->dn_line = REG_BACKUP_DN; - } - /* - * Get the listen port that is configured from the - * Transport Interface instead of the direct config - * read from config. - */ - ccb->local_port = sipTransportGetListenPort(ccb->dn_line, ccb); - /* Init SDP info */ - memset(&ccb->local_msg_body, 0, sizeof(cc_msgbody_info_t)); - //ccb->dest_port = 0; - //ccb->dest_addr = 0; - ccb->old_session_id = NULL; - ccb->old_version_id = NULL; - - /* Into To:, From:, and Request-URI: fields */ - ccb->ReqURI[0] = '\0'; - ccb->sip_from = strlib_empty(); /* There is no pre-set From: field */ - ccb->sip_to = strlib_empty(); /* There is no pre-set To: field */ - - // The following is the refer stuff - - ccb->sip_referTo = strlib_empty(); - ccb->sip_referredBy = strlib_empty(); - ccb->referto = strlib_empty(); - ccb->sipxfercallid = strlib_empty(); - ccb->featuretype = CC_FEATURE_NONE; - ccb->join_info = NULL; - ccb->feature_data = NULL; - - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - ccb->sent_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->sent_request[i].cseq_method = sipMethodInvalid; - ccb->sent_request[i].u.sip_via_branch = strlib_empty(); - ccb->sent_request[i].sip_via_sentby = strlib_empty(); - ccb->recv_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->recv_request[i].cseq_method = sipMethodInvalid; - ccb->recv_request[i].u.sip_via_header = strlib_empty(); - ccb->recv_request[i].sip_via_sentby = strlib_empty(); - } - - ccb->last_recv_request_cseq = 0; - ccb->last_recv_request_cseq_method = sipMethodInvalid; - - if (ccb_index < REG_CCB_START) { - // If this is a tel CCB, restart the counter - ccb->last_used_cseq = CCSIP_START_CSEQ; - } else { - // If this is a reg CCB, continue from where we left off, - // and only initialize it the first time - if (ccb->last_used_cseq == 0) { - ccb->last_used_cseq = CCSIP_START_CSEQ; - } - } - - ccb->last_request = NULL; - - ccb->xfr_inprogress = SIP_SM_NO_XFR; - - - ccb->gsm_id = CC_NO_CALL_ID; - ccb->con_call_id = CC_NO_CALL_ID; - ccb->blind_xfer_call_id = CC_NO_CALL_ID; - ccb->xfer_status = 0; - - /* AVT info */ - config_get_value(CFGID_DTMF_AVT_PAYLOAD, &ccb->avt.payload_type, - sizeof(ccb->avt.payload_type)); - - /* SIP REGISTER info */ - ccb->reg.registered = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - ccb->reg.rereg_pending = 0; - - /* SIP authentication info */ - ccb->authen.retries_401_407 = 0; - ccb->authen.cred_type = 0; - ccb->authen.authorization = NULL; - ccb->authen.status_code = 0; - ccb->authen.nc_count = 0; - ccb->authen.new_flag = FALSE; - ccb->in_call_info = NULL; - ccb->out_call_info = NULL; - ccb->udpId = NULL; - ccb->callref = 0; - - return (0); -} - - - -const char * -sip_util_state2string (sipSMStateType_t state) -{ - switch (state) { - case SIP_STATE_NONE: - return ("SIP_STATE_NONE"); - - case SIP_STATE_IDLE: - return ("SIP_STATE_IDLE"); - - case SIP_STATE_SENT_INVITE: - return ("SIP_STATE_SENT_INVITE"); - - case SIP_STATE_SENT_INVITE_CONNECTED: - return ("SIP_STATE_SENT_INVITE_CONNECTED"); - - case SIP_STATE_RECV_INVITE: - return ("SIP_STATE_RECV_INVITE"); - - case SIP_STATE_RECV_INVITE_PROCEEDING: - return ("SIP_STATE_RECV_INVITE_PROCEEDING"); - - case SIP_STATE_RECV_INVITE_ALERTING: - return ("SIP_STATE_RECV_INVITE_ALERTING"); - - case SIP_STATE_RECV_INVITE_CONNECTED: - return ("SIP_STATE_RECV_INVITE_CONNECTED"); - - case SIP_STATE_ACTIVE: - return ("SIP_STATE_ACTIVE"); - - case SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING: - return ("SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING"); - - case SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING: - return ("SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING"); - - case SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING: - return ("SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING"); - - case SIP_STATE_RELEASE: - return ("SIP_STATE_RELEASE"); - - case SIP_STATE_BLIND_XFER_PENDING: - return ("SIP_STATE_BLIND_XFER_PENDING"); - - case SIP_STATE_SENT_OOD_REFER: - return ("SIP_STATE_SENT_OOD_REFER"); - - case SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING: - return ("SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING"); - - case SIP_STATE_SENT_MIDCALL_INVITE: - return ("SIP_STATE_SENT_MIDCALL_INVITE"); - - default: - return ("UNKNOWN STATE"); - } -} - - -const char * -sip_util_event2string (sipSMEventType_t event) -{ - switch (event) { - case E_SIP_INVITE: - return ("E_SIP_INVITE"); - case E_SIP_ACK: - return ("E_SIP_ACK"); - case E_SIP_BYE: - return ("E_SIP_BYE"); - case E_SIP_CANCEL: - return ("E_SIP_CANCEL"); - case E_SIP_1xx: - return ("E_SIP_1xx"); - case E_SIP_2xx: - return ("E_SIP_2xx"); - case E_SIP_3xx: - return ("E_SIP_3xx"); - case E_SIP_FAILURE_RESPONSE: - return ("E_SIP_FAILURE_RESPONSE"); - case E_SIP_REFER: - return ("E_SIP_REFER"); - case E_CC_SETUP: - return ("E_CC_SETUP"); - case E_CC_SETUP_ACK: - return ("E_CC_SETUP_ACK"); - case E_CC_PROCEEDING: - return ("E_CC_PROCEEDING"); - case E_CC_ALERTING: - return ("E_CC_ALERTING"); - case E_CC_CONNECTED: - return ("E_CC_CONNECTED"); - case E_CC_CONNECTED_ACK: - return ("E_CC_CONNECTED_ACK"); - case E_CC_RELEASE: - return ("E_CC_RELEASE"); - case E_CC_RELEASE_COMPLETE: - return ("E_CC_RELEASE_COMPLETE"); - case E_CC_FEATURE: - return ("E_CC_FEATURE"); - case E_CC_FEATURE_ACK: - return ("E_CC_FEATURE_ACK"); - case E_CC_CAPABILITIES: - return ("E_CC_CAPABILITIES"); - case E_CC_CAPABILITIES_ACK: - return ("E_CC_CAPABILITIES_ACK"); - case E_CC_SUBSCRIBE: - return ("E_CC_SUBSCRIBE"); - case E_CC_INFO: - return ("E_CC_INFO"); - case E_SIP_INV_EXPIRES_TIMER: - return ("E_SIP_INV_EXPIRES_TIMER"); - case E_SIP_INV_LOCALEXPIRES_TIMER: - return ("E_SIP_INV_LOCALEXPIRES_TIMER"); - case E_SIP_SUPERVISION_DISCONNECT_TIMER: - return ("E_SIP_SUPERVISION_DISCONNECT_TIMER"); - case E_SIP_TIMER: - return ("E_SIP_TIMER"); - case E_SIP_OPTIONS: - return ("E_SIP_OPTIONS"); - case E_SIP_UPDATE: - return ("E_SIP_UPDATE"); - case E_SIP_UPDATE_RESPONSE: - return ("E_SIP_UPDATE_RESPONSE"); - case E_SIP_GLARE_AVOIDANCE_TIMER: - return ("E_SIP_GLARE_AVOIDANCE_TIMER"); - case E_SIP_ICMP_UNREACHABLE: - return "E_SIP_ICMP_UNREACHABLE"; - default: - return ("UNKNOWN EVENT"); - } -} - - -sipSMEventType_t -sip_util_ccevent2sipccevent (cc_msgs_t cc_msg_id) -{ - switch (cc_msg_id) { - case CC_MSG_SETUP: - return (E_CC_SETUP); - case CC_MSG_SETUP_ACK: - return (E_CC_SETUP_ACK); - case CC_MSG_PROCEEDING: - return (E_CC_PROCEEDING); - case CC_MSG_ALERTING: - return (E_CC_ALERTING); - case CC_MSG_CONNECTED: - return (E_CC_CONNECTED); - case CC_MSG_CONNECTED_ACK: - return (E_CC_CONNECTED_ACK); - case CC_MSG_RELEASE: - return (E_CC_RELEASE); - case CC_MSG_RELEASE_COMPLETE: - return (E_CC_RELEASE_COMPLETE); - case CC_MSG_FEATURE: - return (E_CC_FEATURE); - case CC_MSG_FEATURE_ACK: - return (E_CC_FEATURE_ACK); - case CC_MSG_INFO: - return (E_CC_INFO); - default: - return ((sipSMEventType_t) (-1)); - } -} - - -void -sip_create_new_sip_call_id (char *sipCallID, uint8_t *mac_address, char *pSrcAddrStr) -{ - static uint16_t count = 1; - - count++; - - if (sipCallID == NULL) { - return; - } - snprintf(sipCallID, MAX_SIP_CALL_ID, "%.4x%.4x-%.4x%.4x-%.8x-%.8x@%s", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - count, (unsigned int)cpr_rand(), (unsigned int)cpr_rand(), pSrcAddrStr); -} - -void -sip_util_get_new_call_id (ccsipCCB_t *ccb) -{ - const char *fname = "sip_util_get_new_call_id"; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char pSrcAddrStr[MAX_IPADDR_STR_LEN]; - char *temp_call_id; - - memset(pSrcAddrStr, 0, MAX_IPADDR_STR_LEN); - - /* Args Check */ - if (!ccb) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args Check: ccb is null", fname); - return; - } - - /* use same call id for registration */ - if ((ccb->type == SIP_REG_CCB) && (ccb->sipCallID[0] != 0)) { - return; - } - - /* - * use pre allocated sip call id, if available. - */ - if (ccb->type != SIP_REG_CCB) { - temp_call_id = ccsip_find_preallocated_sip_call_id(ccb->dn_line); - if (temp_call_id != NULL) { - sstrncpy(ccb->sipCallID, temp_call_id, MAX_SIP_CALL_ID); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"using pre allocated call ID", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - ccsip_free_preallocated_sip_call_id(ccb->dn_line); - return; - } - } - ipaddr2dotted(pSrcAddrStr, &ccb->src_addr); - - platform_get_wired_mac_address(mac_address); - - sip_create_new_sip_call_id(ccb->sipCallID, mac_address, pSrcAddrStr); -} - - -void -sip_util_make_tag (char *pTagBuf) -{ - const char *fname = "sip_util_make_tag"; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - static uint16_t count = 1; - - if (!pTagBuf) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args Check: pTagBuf is null", fname); - return; - } - - platform_get_wired_mac_address(mac_address); - count++; - - snprintf(pTagBuf, MAX_SIP_URL_LENGTH, "%.4x%.4x%.4x%.4x%.8x-%.8x", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - count, (unsigned int)cpr_rand(), (unsigned int)cpr_rand()); -} - -int -sip_sm_init (void) -{ - line_t i; - const char *fname = "sip_sm_init"; - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (!sdpmode) { - - if (ccsip_register_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"registration initialization failed", fname); - return SIP_ERROR; - } - - if (ccsip_info_package_handler_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"info package initialization failed", fname); - return SIP_ERROR; - } - - /* - * Allocate timers for CCBs - */ - if (sip_platform_timers_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"timer initialization failed", fname); - return SIP_ERROR; - } - - if (sipTransportInit() != SIP_OK) { - return SIP_ERROR; - } - - DEF_DEBUG(DEB_F_PREFIX"Disabling mass reg state", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - for (i = 0; i < MAX_CCBS; i++) { - if (i == 0 || i == (MAX_CCBS-1)) { - g_disable_mass_reg_debug_print = FALSE; - } else { - g_disable_mass_reg_debug_print = TRUE; - } - sip_sm_call_cleanup(&(gGlobInfo.ccbs[i])); - if (sip_sm_ccb_init(&(gGlobInfo.ccbs[i]), i, 1, SIP_REG_STATE_IDLE) < 0) { - return SIP_ERROR; - } - } - g_disable_mass_reg_debug_print = FALSE; - - /* Initialize all timers */ - sip_platform_msg_timers_init(); - - /* Initialize Subscription Manager */ - if (sip_subsManager_init() != SIP_OK) { - return SIP_ERROR; - } - - } - - return SIP_OK; -} - -void -ccsip_handle_sip_shutdown () -{ - const char *fname = "handle_sip_shutdown"; - ccsipCCB_t *ccb = NULL; - line_t i; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - ccb = sip_sm_get_ccb_by_index(i); - if (ccb) { - switch (ccb->state) { - case SIP_STATE_RECV_INVITE: - case SIP_STATE_RECV_INVITE_PROCEEDING: - case SIP_STATE_RECV_INVITE_ALERTING: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Received invite: %d: STATE: %s", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, 0, NULL, - FALSE /* no SDP */ , FALSE /* reTx */); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_FACILITY_REJECTED); - ccb->wait_for_ack = FALSE; - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_RECV_INVITE_CONNECTED: - case SIP_STATE_ACTIVE: - default: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Clearing %d STATE: %s", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sipSPISendBye(ccb, NULL, NULL); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - // send this to make sure GSM goes IDLE if it's currently in CONNECTED - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_SENT_INVITE: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Sent invite: Clearing %d STATE: %s", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sipSPISendCancel(ccb); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_FACILITY_REJECTED); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_SENT_INVITE_CONNECTED: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Sent invite connected: Clearing %d STATE: %s", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - sipSPISendBye(ccb, NULL, NULL); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - // send this to make sure GSM goes IDLE if it's currently in CONNECTED - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_RELEASE: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Release: Clearing %d STATE: %s", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_FACILITY_REJECTED); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_IDLE: - break; - } - - } - } -} - -void -sip_shutdown (void) -{ - - DEF_DEBUG(DEB_F_PREFIX"SIP Shutting down...", DEB_F_PREFIX_ARGS(SIP_TASK, "sip_shutdown")); - - // The SIP SM is already shut down - if (sip.taskInited == FALSE) { - return; - } - - sip.taskInited = FALSE; - DEF_DEBUG(DEB_F_PREFIX" sip.taskInited is set to false", DEB_F_PREFIX_ARGS(SIP_TASK, "sip_shutdown")); - -//CPR TODO: need reference for - if ((PHNGetState() == STATE_CONNECTED) || - (PHNGetState() == STATE_DONE_LOADING) || - (PHNGetState() == STATE_CFG_UPDATE)) { - - // Disconnect calls and clean CCB - ccsip_handle_sip_shutdown(); - - // Unregister from all servers and deallocate reg ack timer - sip_regmgr_shutdown(); - - // Stop and deallocate timers - sip_platform_timers_shutdown(); - - // Shutdown Subscription Manager - (void) sip_subsManager_shut(); - //reset publish handler - publish_reset(); - - // Close all sockets - sipTransportShutdown(); - ccsip_remove_wlan_classifiers(); - } - - ccsip_info_package_handler_shutdown(); -} - -/****** -void sip_restart_phase2 (void *data) -{ - sip.taskInited = TRUE; // Forcing sip_shutdown() to execute - sip_shutdown(); - if (sip_sm_init() < 0) { - CCSIP_DEBUG_ERROR(" Error: sip_sm_init failed"); - return; - } - sip_platform_init(); - sip.taskInited = TRUE; - sip_mode_quiet = FALSE; - sip_reg_all_failed = FALSE; -} - -void sip_restart_phase1 (void) -{ - if (sip_reg_all_failed) { - // NO CCM available; need not wait for unreg timer - sip_restart_phase2(NULL); - } else { - // Unregister all lines - ccsip_register_cancel(TRUE, TRUE); - // Start timer with a 2sec expiration - sip_platform_unregistration_timer_start(2000); - - // Stop the periodic timer - (void) sip_platform_subnot_periodic_timer_stop(); - } -} -*******/ -void -sip_restart (void) -{ - const char *fname = "sip_restart"; - - DEF_DEBUG(DEB_F_PREFIX"In sip_restart", DEB_F_PREFIX_ARGS(SIP_CTRL, fname)); - if (sip_sm_init() < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_init failed", fname); - return; - } - sip_platform_init(); - sip.taskInited = TRUE; - DEF_DEBUG(DEB_F_PREFIX"sip.taskInited is set to true", DEB_F_PREFIX_ARGS(SIP_CTRL, fname)); - sip_mode_quiet = FALSE; - sip_reg_all_failed = FALSE; - ccsip_remove_wlan_classifiers(); - - // Initialize all GSM modules - cc_fail_fallback_gsm(CC_SRC_SIP, CC_RSP_COMPLETE, CC_REG_FAILOVER_RSP); -} - -void -sip_shutdown_phase2 (int action) -{ - DEF_DEBUG(DEB_F_PREFIX"(%d)", - DEB_F_PREFIX_ARGS(SIP_CTRL, "sip_shutdown_phase2"), action); - sip.taskInited = TRUE; // Forcing sip_shutdown() to execute - DEF_DEBUG(DEB_F_PREFIX"sip.taskInited is set to true", DEB_F_PREFIX_ARGS(SIP_CTRL, "sip_shutdown_phase2")); - sip_shutdown(); - if (action == SIP_EXTERNAL || action == SIP_STOP) { - shutdownCCAck(action); - } else if (action == SIP_INTERNAL) { - // Continue on to reinit - sip_restart(); - } -} - -void -sip_shutdown_phase1 (int action, int reason) -{ - DEF_DEBUG(DEB_F_PREFIX"In sip_shutdown_phase1 (%d)", - DEB_F_PREFIX_ARGS(SIP_CTRL, "sip_shutdown_phase1"), action); - if (sip_reg_all_failed) { - // NO CCM available; need not wait for unreg timer - sip_shutdown_phase2(action); - } else { - // Unregister all lines - ccsip_register_cancel(TRUE, TRUE); - // Start timer with a 2sec expiration - (void) sip_platform_unregistration_timer_start(2000, (boolean) action); - } -} - -ccsipCCB_t * -sip_sm_get_ccb_by_ccm_id_and_index (int ccmid, line_t idx) -{ - static const char fname[] = "sip_sm_get_ccb_by_ccm_id_and_index"; - fallback_ccb_t *fallback_ccb; - ccsipCCB_t * ccb = NULL; - CCM_ID ccm_id = ccmid; - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"invalid ccm_id=%d " - "ccb_index=%d\n",DEB_F_PREFIX_ARGS(SIP_BRANCH, fname), - ccm_id , idx); - return ccb; - } - - if ((int) idx < MAX_CCBS) { - ccb = &(gGlobInfo.ccbs[idx]); - } - /* - * regmgr - Could be Fallback ccb's - */ - if (ccb == NULL) { - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(idx); - if (fallback_ccb != NULL) { - ccb = fallback_ccb->ccb; - } - } - if (ccb != NULL) { - if ((ccb->cc_cfg_table_entry == NULL) || - (((ti_config_table_t *)(ccb->cc_cfg_table_entry))->ti_specific.ti_ccm.ccm_id != ccm_id)) { - /* - * the standby cucm must have moved to active position, but we did not - * yet have processed the failover response where ccb are updated to - * point to new active. That is why we are getting into this situation. - * Currently, we are throwing away the message, which is mainly the msg - * that standby cucm has sent. Should not do much harm. - */ - DEF_DEBUG(DEB_F_PREFIX"ccb index has moved or cfg_table not initialized for the cucm=%s. " - "index=%d ccb=%p. Throwing away the msg.\n",DEB_F_PREFIX_ARGS(SIP_BRANCH, fname), - CCM_ID_PRINT(ccm_id), idx, ccb); - ccb = NULL; - } - } - if (ccb == NULL) { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Could not find ccb ccb_index=%d", - DEB_F_PREFIX_ARGS(SIP_BRANCH, fname), idx); - } - return ccb; -} - -ccsipCCB_t * -sip_sm_get_ccb_by_index (line_t idx) -{ - fallback_ccb_t *fallback_ccb; - - if ((int) idx < MAX_CCBS) { - return &(gGlobInfo.ccbs[idx]); - } - /* - * regmgr - Could be Fallback ccb's - */ - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(idx); - if (fallback_ccb != NULL) { - return (fallback_ccb->ccb); - } - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), "sip_sm_get_ccb_by_index", - idx); - return NULL; -} - - -ccsipCCB_t * -sip_sm_get_ccb_by_callid (const char *callid) -{ - line_t i; - - if (callid[0] == '\0') { - /* Requesting call ID is NULL string, not allow */ - return (NULL); - } - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -callid_t -sip_sm_get_blind_xfereror_ccb_by_gsm_id (callid_t gsm_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (gsm_id == gGlobInfo.ccbs[i].blind_xfer_call_id) { - return gGlobInfo.ccbs[i].gsm_id; - } - } - - return CC_NO_CALL_ID; -} - - -ccsipCCB_t * -sip_sm_get_ccb_by_target_call_id (callid_t con_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (con_id == gGlobInfo.ccbs[i].gsm_id) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -ccsipCCB_t * -sip_sm_get_target_call_by_gsm_id (callid_t gsm_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (gsm_id == gGlobInfo.ccbs[i].con_call_id) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -ccsipCCB_t * -sip_sm_get_target_call_by_con_call_id (callid_t con_call_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (con_call_id == gGlobInfo.ccbs[i].gsm_id) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -ccsipCCB_t * -sip_sm_get_ccb_next_available (line_t *line_number) -{ - line_t i; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - if (gGlobInfo.ccbs[i].state == SIP_STATE_IDLE) { - *line_number = i; - break; - } - } - - if (i > TEL_CCB_END) { - return NULL; - } - return &(gGlobInfo.ccbs[i]); -} - -/** - * sip_sm_get_ccb_by_gsm_id - * - * This fucntion tries to match the ccbs given the gsm id - * The algorithm tries to match the non duplicate CCB first - * If the only match is a DUP_CCB it shall be returned as a match - * @param[in] gsm_id GSM ID in the CCB - * - * @return ccsipCCB_t * or NULL - * - */ -ccsipCCB_t * -sip_sm_get_ccb_by_gsm_id (callid_t gsm_id) -{ - line_t i; - ccsipCCB_t *dupCCB = NULL; - - if ( gsm_id == CC_NO_CALL_ID ) - return NULL; - - for (i = 0; i < MAX_CCBS; i++) { - if (gGlobInfo.ccbs[i].gsm_id == gsm_id) { - if ( gGlobInfo.ccbs[i].dup_flags & DUP_CCB ) { - dupCCB = &(gGlobInfo.ccbs[i]); - } else { - return &(gGlobInfo.ccbs[i]); - } - } - } - - return dupCCB; -} - -/** - * sip_sm_ccb_match_branch_cseq - * - * This fucntion tries to match the Branch and Cseq ID for a - * given CCB to see if the values match in the response with the - * values sent in the request. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] sipCseq Pointer to sipCseq_t structure. - * @param[in] via_this Pointer to sipVia_t structure. - * - * @pre (ccb not_eq NULL) - * @pre (sipCseq not_eq NULL) - * @pre (via_this not_eq NULL) - * - * @return TRUE/FALSE - * - */ -static boolean -sip_sm_ccb_match_branch_cseq (ccsipCCB_t *ccb, - sipCseq_t *sipCseq, - sipVia_t *via_this) -{ - const char *fname = "sip_sm_ccb_match_branch_cseq"; - int16_t trx_index = -1; - sipTransaction_t *trx = NULL; - - trx_index = get_method_request_trx_index(ccb, sipCseq->method, - TRUE); - if (trx_index != -1) { - // match cseq and viabranchid - trx = &(ccb->sent_request[trx_index]); - if ((trx->cseq_number == sipCseq->number) && - (trx->u.sip_via_branch[0] != '\0') && - (via_this->branch_param != NULL) && - (strncmp(trx->u.sip_via_branch, via_this->branch_param, - VIA_BRANCH_LENGTH) == 0)) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched branch_id & CSeq", DEB_F_PREFIX_ARGS(SIP_BRANCH, fname)); - return (TRUE); - } else { - CCSIP_DEBUG_ERROR(SIP_L_C_F_PREFIX"Mismatched CSeq or" - " Via's branch parameter in response:" - "ccb=%p,%d, cseq(trx,msg)=(%d,%d)," - "branch(trx,msg)=(%s,%s)\n", - ccb->dn_line, ccb->gsm_id, fname, ccb, - ccb->index, trx->cseq_number, sipCseq->number, - trx->u.sip_via_branch, - via_this->branch_param); - return (FALSE); - } - } - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Method index not found", fname); - return (FALSE); -} - -// The function below attempts to determine more intelligently if there -// is an existing dialog to which an incoming message should be directed. -// In addition to call-id, it also considers the Req-URI, CSeq, etc. -uint16_t -sip_sm_determine_ccb (const char *callid, - sipCseq_t * sipCseq, - sipMessage_t *pSipMessage, - boolean is_request, - ccsipCCB_t **ccb_ret) -{ - - const char *fname = "sip_sm_determine_ccb"; - const char *to = NULL; - sipLocation_t *to_loc = NULL; - line_t i; - ccsipCCB_t *ccb = NULL; - sipReqLine_t *requestURI = NULL; - genUrl_t *genUrl = NULL; - sipUrl_t *sipUriUrl = NULL; - char *pUser = NULL; - char reqURI[MAX_SIP_URL_LENGTH]; - int16_t trx_index = -1; - sipTransaction_t *trx = NULL; - sipVia_t *via_this = NULL; - sipVia_t *via_last = NULL; - const char *pViaHeaderStr = NULL; - boolean match = FALSE; - - *ccb_ret = NULL; - - // Dialog matching algorithm is as follows: - // First, obtain the CCB by matching call-id and to-tag, if present - to = sippmh_get_cached_header_val(pSipMessage, TO); - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->tag) { - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - if (ccb->sip_to_tag[0] != '\0') { - if (strcmp(to_loc->tag, ccb->sip_to_tag) == 0) { - *ccb_ret = ccb; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched to_tag", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - break; - } else if (strcmp(to_loc->tag, ccb->sip_from_tag) == 0) { - *ccb_ret = ccb; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched from_tag", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - break; - } - } - } - } - } - sippmh_free_location(to_loc); - } - } - - // Get the VIA parameters so proper matching can be done - pViaHeaderStr = sippmh_get_cached_header_val(pSipMessage, VIA); - if (pViaHeaderStr) { - via_this = sippmh_parse_via(pViaHeaderStr); - } - if (!pViaHeaderStr || !via_this) { - return (SIP_CLI_ERR_BAD_REQ); - } - - // If not found, and this is a request, obtain by matching call-id, - // and user part of the ReqURI - if ((*ccb_ret == NULL) && is_request) { - reqURI[0] = '\0'; - requestURI = sippmh_get_request_line(pSipMessage); - if (requestURI) { - if (requestURI->url) { - genUrl = sippmh_parse_url(requestURI->url, TRUE); - if (genUrl) { - if (genUrl->schema == URL_TYPE_SIP) { - sipUriUrl = genUrl->u.sipUrl; - if (sipUriUrl) { - pUser = sippmh_parse_user(sipUriUrl->user); - if (pUser) { - sstrncpy(reqURI, pUser, sizeof(reqURI)); - cpr_free(pUser); - } else { - sstrncpy(reqURI, sipUriUrl->user, sizeof(reqURI)); - } - } - } - sippmh_genurl_free(genUrl); - } - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - if (ccb->ReqURI[0] != '\0') { - if (strcmp(ccb->ReqURI, reqURI) == 0) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched reqURI", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - *ccb_ret = ccb; - break; - } - } - } - } - if (*ccb_ret == NULL) { - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - if ((sipCseq->method == sipMethodInvite) && - (ccb->state < SIP_STATE_ACTIVE)) { - // Return this CCB if we match call-id but have - // not connected yet - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched Call-id - not active.", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - *ccb_ret = ccb; - break; - } - if (((sipCseq->method == sipMethodCancel) && - (ccb->state < SIP_STATE_ACTIVE)) || - ((sipCseq->method == sipMethodAck) && - (ccb->state == SIP_STATE_RELEASE))) { - // For CANCEL, try and match the via branch-id with the - // corresponding via branch-id of the INVITE received earlier. - // Normally the R-URI of the CANCEL should match the stored - // ReqURI but it is possible that the stored value was overwritten. - // via_last is the via header from the previous INVITE - // For ACK, we might be receiving this if there we responded with - // an error to the initial INVITE - trx_index = get_method_request_trx_index(ccb, - sipMethodInvite, - FALSE); - - if (trx_index != -1) { - const char *toString; - const char *fromString; - - toString = sippmh_get_cached_header_val(pSipMessage, TO); - fromString = sippmh_get_cached_header_val(pSipMessage, FROM); - - trx = &(ccb->recv_request[trx_index]); - - if (trx->u.sip_via_header[0] != '\0') { - pViaHeaderStr = (char *) (trx->u.sip_via_header); - via_last = sippmh_parse_via(pViaHeaderStr); - } - - if (fromString && toString) { - if ((strcmp(ccb->sip_from, fromString) == 0) && - (strncmp(ccb->sip_to, toString, strlen(toString)) == 0) && - (trx->cseq_number == sipCseq->number) && - (via_last && (via_last->branch_param != NULL)) && - (via_this->branch_param != NULL) && - (strcmp(via_last->branch_param, via_this->branch_param) == 0)) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched branch_id & CSeq for CANCEL/ACK", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - *ccb_ret = ccb; - sippmh_free_via(via_last); - via_last = NULL; - break; - } - } - if (via_last) { - sippmh_free_via(via_last); - via_last = NULL; - } - } - } - } - } - } - } - - // If found, and this is a request, check for any existing trx in - // progress by matching with recd trx's cseq method and number. If - // these are the same and the branch-id is different, this is a merged - // request. Here via_last is the via header from the last receipt of the same request - if ((*ccb_ret != NULL) && is_request) { - ccb = *ccb_ret; - trx_index = get_method_request_trx_index(ccb, sipCseq->method, FALSE); - if (trx_index != -1) { - if (ccb->recv_request[trx_index].u.sip_via_header[0] != '\0') { - pViaHeaderStr = (char *) (ccb->recv_request[trx_index].u.sip_via_header); - via_last = sippmh_parse_via(pViaHeaderStr); - } - if (via_last) { - if (sipCseq->number == ccb->recv_request[trx_index].cseq_number) { - if (via_this->branch_param && via_last->branch_param) { - if (strcmp(via_this->branch_param, - via_last->branch_param)) { - // merged request - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Found Merged Request", fname); - sippmh_free_via(via_this); - sippmh_free_via(via_last); - return (SIP_CLI_ERR_LOOP_DETECT); - } - } - } - sippmh_free_via(via_last); - } - } - - } - // If this is a response, match it with a sent transaction in CCB - // by obtaining the CCB by call-id and then going through the - // transactions within it and matching branch-id and CSeq - if ((*ccb_ret == NULL) && !is_request) { - - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - match = sip_sm_ccb_match_branch_cseq(ccb, sipCseq, - via_this); - sippmh_free_via(via_this); - if (match) { - *ccb_ret = ccb; - return (0); - } else { - return (SIP_CLI_ERR_NOT_ACCEPT); - } - } - } - /* - * If ret_ccb is NULL after all this and the message is a - * response, check the fallback ccb list if any of those match - * the message call id. - */ - sip_regmgr_find_fallback_ccb_by_callid(callid, ccb_ret); - } - - /* - * If the CCB is not NULL and this is a response, then check - * if the branch and Cseq match. - */ - if ((*ccb_ret != NULL) && !is_request) { - match = sip_sm_ccb_match_branch_cseq(*ccb_ret, sipCseq, - via_this); - sippmh_free_via(via_this); - if (match) { - return (0); - } else { - return (SIP_CLI_ERR_NOT_ACCEPT); - } - } - - sippmh_free_via(via_this); - return (0); -} - -void -ccsip_handle_default (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_default"; - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d No action -> %s", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); -} - - -void -ccsip_handle_default_sip_message (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "default_sip_message"; - sipMessage_t *msg = NULL; - int16_t trx_index = -1; - - msg = event->u.pSipMessage; - - if (event->type == E_SIP_ACK) { - // If this is an ACK, make sure and clean out the corresponding INVITE - // transaction - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - } else if (event->type == E_SIP_INVITE) { - // If this is an INVITE and we are already processing an earlier - // INVITE return a 500 response - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, FALSE); - if (trx_index != -1) { - (void) sipSPISendErrorResponse(msg, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - "Earlier INVITE being processed", - NULL); - } - } else if (event->type == E_SIP_UPDATE) { - // If this is an UPDATE and we are already processing an earlier - // UPDATE return a 500 response - trx_index = get_method_request_trx_index(ccb, sipMethodUpdate, FALSE); - if (trx_index != -1) { - (void) sipSPISendErrorResponse(msg, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - "Earlier UPDATE being processed", - NULL); - } - - } else if (event->type == E_SIP_CANCEL) { - (void) sipSPISendErrorResponse(msg, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, 0, NULL, ccb); - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Sent 481 (CANCEL) %s", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - } - - /* Deallocate the incoming SIP message */ - if (msg) { - free_sip_message(msg); - } - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: No action -> %s", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); -} - -/** - * ccsip_handle_default_ev_cc_feature - * - * The function is a default function for handling CC_FEATURE in the - * state that does not expect CC_FEATURE. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - * - */ -void -ccsip_handle_default_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_default_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - /* - * The feature event is not supported by the current state or - * it is inappropriate event in the current state. Send feature ack - * with error code. - */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); -} - -/** - * ccsip_handle_default_recvreq_ack_pending_ev_cc_feature - * - * The function is a default handler for CC_FEATURE while in the - * received INVITE, UPDATE and the state machine is waiting for - * feature ack from GSM or SIP ack pending. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - */ -void -ccsip_handle_default_recvreq_ack_pending_ev_cc_feature (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = - "ccsip_handle_default_recvreq_ack_pending_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_RESUME: - case CC_FEATURE_HOLD: - case CC_FEATURE_MEDIA: - /* - * Received resume/hold/media request while waiting for feauture ack or - * SIP ack for hold that was received. Indicate that the request - * can not proceed now and it should be retried later. - */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_REQUEST_PENDING); - break; - - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - break; - default: - /* Other feature request is not supported or allowed now */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_ERROR); - break; - } -} - -/* - * Function: sip_is_releasing() - * - * Parameters: ccb - The current call control block - * - * Description: This routine supports determining whether the - * the call is in releasing state or not. - * - * Returns: - * TRUE - call is being released. - * FALSE - call is not being released. - */ -boolean -sip_is_releasing (ccsipCCB_t *ccb) -{ - if (ccb != NULL) { - /* Call exists */ - if (ccb->state == SIP_STATE_RELEASE) { - return (TRUE); - } - } - return (FALSE); -} - -void -ccsip_handle_default_sip_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "default_sip_response"; - sipMessage_t *response; - int response_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Get the response code */ - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - - /* Check if this is an INVITE response */ - if ((!sip_sm_is_invite_response(response)) || (response_code < 200)) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - if (sipSPISendAck(ccb, response) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* Deallocate the memory for the response */ - free_sip_message(response); -} - -/* - * ccsip_restart_reTx_timer - * - * This function is called when resending a message - * due to a timeout or ICMP unreachable. It just - * restarts the re-transmit timer. - */ -void -ccsip_restart_reTx_timer (ccsipCCB_t *ccb, sipMethod_t messageType) -{ - const char *fname = "ccsip_restart_reTx_timer"; - uint32_t time_t1 = 0; - uint32_t time_t2 = 0; - uint32_t timeout = 0; - - /* Restart the reTx timer */ - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - timeout = time_t1 * (1 << ccb->retx_counter); - // Adjust the max timer - but only for non INVITE transactions - if (messageType != sipMethodInvite) { - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - } - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Restarting timer (%d msec)" - " (msg is %s)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, timeout, sipGetMethodString(messageType)); - - ccb->retx_flag = TRUE; - if (sip_platform_msg_timer_start(timeout, (void *)((long)ccb->index), ccb->index, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipPlatformUISMTimers[ccb->index].message_type, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, - FALSE) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "sip_platform_msg_timer_start()"); - ccb->retx_flag = FALSE; - return; - } -} - -/* - * ccsip_handle_obp_error() - * - * This function is called when a sip re-try timer - * pops or an ICMP unreachable is received after a - * msg is sent and the cause is the msg bounced or - * timed out trying to reach the outbound proxy. - * - * Data is the IP address that bounced or -1 if it was - * a timeout. - * - */ -void -ccsip_handle_obp_error (ccsipCCB_t *ccb, sipMethod_t messageType, cpr_ip_addr_t *data) -{ - const char *fname = "ccsip_handle_obp_error"; - boolean resend = FALSE; - uint32_t max_retx = 0; - - char obp_address[MAX_IPADDR_STR_LEN]; - - config_get_string(CFGID_OUTBOUND_PROXY, obp_address, sizeof(obp_address)); - /* Did the msg bounce? */ - if (util_compare_ip(data, &ccb->outBoundProxyAddr)) { - /* Try next proxy if one exists */ - ccb->outBoundProxyPort = 0; - ccb->retx_counter = 0; - if (str2ip(obp_address, &ccb->outBoundProxyAddr) != 0) { - resend = TRUE; - } - - /* Msg timed out */ - } else { - if (messageType == sipMethodInvite) { - config_get_value(CFGID_SIP_INVITE_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_INVITE_RETRY_ATTEMPTS; - } - } else { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - } - - /* Retries exhausted, get next proxy if one exists */ - if (ccb->retx_counter >= max_retx) { - ccb->outBoundProxyPort = 0; - ccb->retx_counter = 0; - if (str2ip(obp_address, &ccb->outBoundProxyAddr) != 0) { - /* if the obp is just an ip addr, there is nothing else to try */ - resend = TRUE; - } - - /* Retries not exhausted */ - } else { - resend = TRUE; - } - } - - if (resend) { - if (sipSPISendLastMessage(ccb) == TRUE) { - ccb->retx_counter++; - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Resent message: #%d", - DEB_L_C_F_PREFIX_ARGS(SIP_MSG_SEND, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->retx_counter); - ccsip_restart_reTx_timer(ccb, messageType); - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - } else { - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - if ((ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) || - (ccb->state == SIP_STATE_RELEASE)) { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - } else { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - } else { - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } -} - -int -ccsip_pick_a_proxy (ccsipCCB_t *ccb) -{ - uint32_t max_retx = 0; - sipMethod_t retxMessageType = sipPlatformUISMTimers[ccb->index].message_type; - char addr[MAX_IPADDR_STR_LEN]; - const char *fname = "ccsip_pick_a_proxy"; - - memset(addr, 0, sizeof(addr)); - - /* Get the type of the retransmitted message. - * If it INVITE, then we need to use a different timer count - */ - if (retxMessageType == sipMethodInvite) { - config_get_value(CFGID_SIP_INVITE_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_INVITE_RETRY_ATTEMPTS; - } - if (gGlobInfo.backup_active) { - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - /* - * If we have previously failed to contract the normal/regular - * proxy then use a reduce re-try count for subsequent attempts - * i.e failover to the backup proxy faster - */ - if (ccb->retx_counter >= 3) { - ccb->retx_counter = max_retx; - } - } - } - /* - * Check if we have maxed out the re-transmits on invite - * and not yet tried the backup proxy. - */ - if ((ccb->retx_counter >= max_retx) && - (ccb->proxySelection != SIP_PROXY_BACKUP) && - (ccb->proxySelection != SIP_PROXY_DO_NOT_CHANGE_MIDCALL)) { - dns_error_code = DNS_ERR_HOST_UNAVAIL; - /* Try and fetch a proxy using DNS SRV records */ - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - if (str2ip(addr, &ccb->dest_sip_addr) != 0) { - dns_error_code = sip_dns_gethostbysrv(addr, &ccb->dest_sip_addr, - (uint16_t *)&ccb->dest_sip_port, - &ccb->SRVhandle, TRUE); - if (dns_error_code == DNS_OK) { - util_ntohl(&(ccb->dest_sip_addr), &(ccb->dest_sip_addr)); - /* - * Modify destination fields in call back timer struct - */ - (void) sip_platform_msg_timer_update_destination(ccb->index, - &(ccb->dest_sip_addr), - (uint16_t) ccb->dest_sip_port); - /* - * Reset re-transmit counter so we try again - */ - ccb->retx_counter = 0; - - } - } - /* - * Either we are using DNS SRV records and we exhausted the list - * Or we are not using DNS SRV and we need to try the backup - */ - if (dns_error_code != DNS_OK) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Unable to reach proxy, attempting backup.", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - if (ccsip_attempt_backup_proxy(ccb)) { - - ccb->first_backup = TRUE; - /* - * Get rid of transaction block for the ccb, we may have - * tried primary proxy etc - */ - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - - /* - * If contact info is supplied, as in the case of a 3xx - * redirect and perhaps other cases TBD. And since calls - * to the backup are essentially a "NEW" call so to speak, - * nuke it and run. - */ - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - /* Ditto for record route */ - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - /* - * Recreate the SIP message, because the IP address has - * changed. Ie. the reqURI has the old proxy IP address, - * but now it should have the new backup proxy address - * so we are setting boolean initInvite to TRUE. initInvite - * will be used in sipSPIGenRequestURI to make reqURI with - * new backup proxy address - */ - if ((sipSPISendInvite(ccb, - ccb->wastransferred ? SIP_INVITE_TYPE_TRANSFER : - SIP_INVITE_TYPE_NORMAL, TRUE) != TRUE)) { - sip_sm_call_cleanup(ccb); - return FALSE; - } - - /* - * Reset counters so we try again using the backup proxy - */ - ccb->retx_counter = 0; - - /* Backup proxy failed as well. Broadcast once */ - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Attempt to reach backup proxy" - " failed. Message will be broadcast.\n", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - return 1; - } - } - } - } else { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - } - return max_retx; -} - -/* - * Function: ccsip_handle_icmp_unreachable: - * Description: This function handles ICMP events. For failed attempts - * for requests (that get back an ICMP) this function checks - * to see if we are in a dialog. If so, there is place holder - * to follow through with DNS SRV (future work) and if all - * DNS SRV calls have failed then it tears down the call. - * - * If request was an out-of-dialog request, the code sets - * the the ccb->retx_count to exceed max retries so it will - * be treated as a failure to send the server (so retries to - * the same server will not be attempted). - */ -void -ccsip_handle_icmp_unreachable (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_icmp_unreachable"; - - /* - * 1. Check to see if we are in a dialog - * 1.1. If we are in a dialog and the fqdn was resolved by SRV, - * then we must iterate to the next SRV result - * 1.2. if we have no more servers from the SRV lookup, - * we have to call it quits. - * 2. if we are not in a dialog, then map the icmp event to a timer event - * but set the retry count to appropriate value so the timer handler can - * pick up the next server rather than retry the same one. - */ - - if (ccb->sip_to_tag[0] != '\0') { - //we are in a dialog - // NOT USED: sipMessage_t *response; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"ICMP received within a dialog.", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - /* - * At this point we should be checking to see if we picked up an - * fqdn that picked up from the route set was a SRV RR. If so, - * we must iterate to the next result returned. - * - * But we cannot do that now. Our SRV mechanism is incorrect. - * Firstly we must store SRV associations (handle to srv returns) - * in the sipTransaction_t object. - * - * This is future work. - * - * So for now we clobber the call. - */ - - ccb->wait_for_ack = FALSE; - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - sip_sm_call_cleanup(ccb); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"ICMP received outside of a dialog.", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - //ccb->retx_counter = 100; //to cause failover to next proxy if one is available - ccsip_handle_default_sip_timer(ccb, event); - } -} - -/* - * ccsip_handle_default_sip_timer() - * - * This function is called when a sip re-try timer - * pops or an ICMP unreachable is received after a - * msg is sent. The ICMP unreachable code sets - * retx_counter to MAX to force the code to try the - * next proxy in the list. Event.u.usrInfo is set to - * the IP address that bounced or -1 if it is a timeout. - * - * Note: Registration bounces and timeouts are handled - * by the function ccsip_handle_ev_tmr_retry. - */ -void -ccsip_handle_default_sip_timer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_default_sip_timer"; - uint32_t max_retx = 0; - sipMethod_t retxMessageType = sipPlatformUISMTimers[ccb->index].message_type; - char addr[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t out_ip; - - CPR_IP_ADDR_INIT(out_ip); - - /* Timing issue on re-transmission and receiving an Ack. - * The timer could pop and we re-transmit and the Ack - * already be in the queue. When this happens, we process - * the Ack and go into the Active/Hold state. In the Active/Hold - * state, we don't expect an ack, so nothing happens and - * thus the new timer will eventually pop and start the - * whole process over. If we are in the Active/Hold state, we - * did receive the Ack. On the next time-out, just ignore it - * and don't re-start or re-transmit. The phone could be in - * the ACTIVE or HOLD states if a REFER has been sent with - * no response. Therefore ensure messagetype is not REFER - * before kicking out. - */ - if ((retxMessageType != sipMethodRefer) && - ((ccb->state == SIP_STATE_ACTIVE))) { - return; - } - - /* OK, we got a timer pop, but the re-transmit flag - * isn't set. This means someone got a response that - * told them they could stop re-transmitting. Simply - * exit this function and do not re-start timer or - * re-transmit the message. - */ - if (ccb->retx_flag == FALSE) { - if (ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - } - return; - } - - /* Determine if msg to outbound proxy bounced or timed out */ - util_ntohl(&out_ip, &event->u.UsrInfo); - if ((util_compare_ip(&out_ip, &(ccb->outBoundProxyAddr))) || - ((event->u.UsrInfo.type == CPR_IP_ADDR_INVALID) && - util_check_if_ip_valid(&(ccb->outBoundProxyAddr)))) { - ccsip_handle_obp_error(ccb, retxMessageType, &(event->u.UsrInfo)); - return; - } - - /* Determine if there is a proxy to send to */ - max_retx = ccsip_pick_a_proxy(ccb); - - /* Increment counter */ - ccb->retx_counter++; - - /* - * Our work is done if the backup proxy has just been activated. - * We know that is has just been activated if the first_backup flag is TRUE. - */ - if ((ccb->proxySelection == SIP_PROXY_BACKUP) && (ccb->first_backup)) { - ccb->first_backup = FALSE; - return; - } - - /* Resend */ - if (ccb->retx_counter <= max_retx) { - if (sipSPISendLastMessage(ccb) == TRUE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d:Resent message: #%d", - DEB_L_C_F_PREFIX_ARGS(SIP_MSG_SEND, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->retx_counter); - } - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - ccsip_restart_reTx_timer(ccb, retxMessageType); - - /* All retransmit attempts have been exhausted */ - } else { - ccb->retx_counter = 0; - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - - /* Check for redirection */ - if (ccb->state == SIP_STATE_SENT_INVITE) { - if (ccb->redirect_info != NULL) { - sip_redirect(ccb, NULL, SIP_CLI_ERR_REQ_TIMEOUT); - return; - } - } - /* - * Resend msg to next proxy in the list if one exists - * Try and fetch another proxy using DNS SRV or A records - */ - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - if (str2ip(addr, &ccb->dest_sip_addr) != 0) { - dns_error_code = sipTransportGetServerAddrPort(addr, - &ccb->dest_sip_addr, - (uint16_t *)&ccb->dest_sip_port, - &ccb->SRVhandle, - TRUE); - } else { - /* This ip addr has already been tried */ - dns_error_code = DNS_ERR_HOST_UNAVAIL; - } - if (dns_error_code == 0) { - util_ntohl(&(ccb->dest_sip_addr), &(ccb->dest_sip_addr)); - /* Modify destination fields in call back timer */ - (void) sip_platform_msg_timer_update_destination(ccb->index, - &(ccb->dest_sip_addr), - (uint16_t)ccb->dest_sip_port); - if (sipSPISendLastMessage(ccb) == TRUE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Resent message: #%d", - DEB_L_C_F_PREFIX_ARGS(SIP_MSG_SEND, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->retx_counter); - } - ccsip_restart_reTx_timer(ccb, retxMessageType); - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - } else { - if ((ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) || - (ccb->state == SIP_STATE_RELEASE)) { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - return; - } else if (retxMessageType == sipMethodRefer && - (ccb->featuretype == CC_FEATURE_B2BCONF || - ccb->featuretype == CC_FEATURE_SELECT || - ccb->featuretype == CC_FEATURE_B2B_JOIN || - ccb->featuretype == CC_FEATURE_CANCEL)) { - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - NULL, CC_CAUSE_ERROR); - return; - } else { - handle_error_for_state(ccb, SIP_CLI_ERR_REQ_TIMEOUT); - return; - } - } - } - - /* Restart re-transmit timer */ - ccsip_restart_reTx_timer(ccb, retxMessageType); -} - - -void -sip_decrement_backup_active_count (ccsipCCB_t *ccb) -{ - /* - * OK If we successfully received a response we need to back off from using the backup - * proxy if that was the case. Note if this is a response from the backup chuck it - */ - if ((gGlobInfo.backup_active) && (ccb->proxySelection != SIP_PROXY_BACKUP)) - gGlobInfo.backup_active -= 1; -} - -boolean -sip_sm_is_previous_call_id (const char *pCallID, line_t *pPreviousCallIndex) -{ - line_t i; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - if (strcmp(gCallHistory[i].last_call_id, pCallID) == 0) { - *pPreviousCallIndex = i; - return TRUE; - } - } - - return FALSE; -} - -void -sip_sm_200and300_update (ccsipCCB_t *ccb, sipMessage_t *response, int response_code) -{ - const char *fname = "sip_sm_200and300_update"; - const char *to; - const char *from; - const char *contact; - const char *record_route = NULL; - sipLocation_t *to_loc = NULL; - - to = sippmh_get_cached_header_val(response, TO); - from = sippmh_get_cached_header_val(response, FROM); - contact = sippmh_get_cached_header_val(response, CONTACT); - - if (ccb->state < SIP_STATE_ACTIVE) { - // We are not allowed to update the route once a call is established - record_route = sippmh_get_cached_header_val(response, RECORD_ROUTE); - } - /* - * Record the "tag=" parameter - only if the call is not active yet - */ - if (ccb->state < SIP_STATE_ACTIVE) { - if (to) { - to_loc = sippmh_parse_from_or_to((char *) to, TRUE); - if (to_loc) { - if (to_loc->tag) { - ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, - sip_sm_purify_tag(to_loc->tag)); - if ( ccb->callref == 0 ) { - ccb->callref = get_callref(ccb->sip_to_tag); - } - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "TO header:missing \"tag=\" param"); - } - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Recorded to_tag=<%s>", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->sip_to_tag); - sippmh_free_location(to_loc); - } - } - } - - /* - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - if (response_code == SIP_STATUS_SUCCESS) { - if (ccb->flags & INCOMING) { - ccb->sip_to = strlib_update(ccb->sip_to, from); - if (to) { - ccb->sip_from = strlib_update(ccb->sip_from, to); - } - } else { - if (to) { - ccb->sip_to = strlib_update(ccb->sip_to, to); - } - ccb->sip_from = strlib_update(ccb->sip_from, from); - } - } - - if (response_code == SIP_STATUS_SUCCESS) { - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - } - if (record_route) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = sippmh_parse_record_route(record_route); - } -} - - -char * -sip_sm_purify_tag (char *tag) -{ - char *p; - - p = tag; - while (((*p == ';') || (*p == ' ') || (*p == '\t')) && (*p != '\0')) { - p++; - } - - return p; -} - - -boolean -sip_sm_is_invite_response (sipMessage_t *response) -{ - const char *cseq; - sipCseq_t *sipCseq; - - if (response == NULL) { - return FALSE; - } - - cseq = sippmh_get_cached_header_val(response, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - return FALSE; - } - - if (sipCseq->method == sipMethodInvite) { - cpr_free(sipCseq); - return TRUE; - } - cpr_free(sipCseq); - return FALSE; -} - -boolean -sip_sm_is_bye_or_cancel_response (sipMessage_t *response) -{ - const char *cseq; - sipCseq_t *sipCseq; - - if (response == NULL) { - return FALSE; - } - - cseq = sippmh_get_cached_header_val(response, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - return FALSE; - } - - if ((sipCseq->method == sipMethodBye) || - (sipCseq->method == sipMethodCancel)) { - cpr_free(sipCseq); - return TRUE; - } - cpr_free(sipCseq); - return FALSE; -} - - - -void -sip_sm_dequote_string (char *str, int max_size) -{ - char *p; - - /* Get rid of leading white space and double quote */ - p = str; - while (((*p == '\"') || (*p == ' ') || (*p == '\t')) && (*p != '\0')) { - p++; - } - - // The following use of sstrncpy is using over-lapping memory regions - sstrncpy(str, p, max_size); - - /* Get rid of trailing double quote and white space */ - // should be... - // end the string at the trailing double quote, if it exists - p = str; - while ((*p != '\"') && (*p != '\0')) { - p++; - } - *p = '\0'; -} - - -void -sip_sm_check_retx_timers (ccsipCCB_t *ccb, sipMessage_t *canceller_message) -{ - const char *fname = "sip_sm_check_retx_timers"; - uint32_t canceller_cseq; - sipMethod_t canceller_cseq_method; - const char *canceller_callid; - - sipMessage_t *retx_message = NULL; - uint32_t retx_message_buf_length = 0; - uint32_t retx_cseq = 0; - sipMethod_t retx_cseq_method = sipMethodInvalid; - const char *retx_callid = NULL; - - const char *cseq; - sipCseq_t *sipCseq; - int response_code = -1; - const char *conn_type = NULL; - - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "CCB is NULL"); - return; - } - - if (ccb->index >= MAX_CCBS) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, ccb->index); - return; - } - - /* In the case of TCP/TLS, no messages are retransmitted unless there was a - * socket open (CPR_ENOTCONN) error. Hence there are no retx timers started - * in this case. If any retx timers were started, then, in the - * sip_platform_msg_timer_start procedure, the message_buffer_len would be - * set to a valid non-zero value. - */ - conn_type = sipTransportGetTransportType(1, TRUE, ccb); - if ((!cpr_strcasecmp(conn_type, "TCP") || !cpr_strcasecmp(conn_type, "TLS")) && - 0 == sipPlatformUISMTimers[ccb->index].message_buffer_len) { - /* This is not an error in case of TCP/TLS. - */ - return; - } - - - /* - * Get canceller_message callid, cseq number, cseq method - */ - cseq = sippmh_get_cached_header_val(canceller_message, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (sipCseq) { - canceller_cseq = sipCseq->number; - canceller_cseq_method = sipCseq->method; - cpr_free(sipCseq); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_cseq()"); - return; - } - - canceller_callid = sippmh_get_cached_header_val(canceller_message, CALLID); - - /* - * Get canceller_message response code if it is a response - */ - if (!sippmh_is_request(canceller_message)) { - if (sipGetResponseCode(canceller_message, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "sipGetResponseCode()"); - return; - } - } - - /* - * Get retx_message callid, cseq number, cseq method - */ - retx_message = sippmh_message_create(); - if (!retx_message) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "sippmh_message_create()"); - return; - } - retx_message_buf_length = sipPlatformUISMTimers[ccb->index].message_buffer_len; - if (sippmh_process_network_message(retx_message, - sipPlatformUISMTimers[ccb->index].message_buffer, - &retx_message_buf_length) == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "sippmh_process_network_message()"); - free_sip_message(retx_message); - return; - } - if (!sippmh_is_message_complete(retx_message)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "sippmh_is_message_complete()"); - free_sip_message(retx_message); - return; - } - cseq = sippmh_get_cached_header_val(retx_message, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (sipCseq) { - retx_cseq = sipCseq->number; - retx_cseq_method = sipCseq->method; - cpr_free(sipCseq); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_cseq()"); - free_sip_message(retx_message); - return; - } - - retx_callid = sippmh_get_cached_header_val(retx_message, CALLID); - - /* - * Check whether callid, cseq number, cseq method match. If match, - * stop the reTx timer. - */ - if ((canceller_cseq == retx_cseq) && - ((canceller_cseq_method == retx_cseq_method) || - ((canceller_cseq_method == sipMethodAck) && - (retx_cseq_method == sipMethodInvite))) && - (strcmp(canceller_callid, retx_callid) == 0)) { - sip_platform_msg_timer_stop(ccb->index); - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Stopping reTx timer." - "(callid=%s, cseq=%u, cseq_method=%s)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, retx_callid, retx_cseq, - sipGetMethodString(retx_cseq_method)); - - UNBIND_UDP_ICMP_HANDLER(ccb->udpId); - - if (ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - if ((response_code == 401) || (response_code == 407) || - ((response_code < 200) && - (!sippmh_is_request(canceller_message)))) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - } else { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - } - } - } else { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d:CSeq mismatch:\n(Rx: callid=%s," - " cseq=%u, cseq_method=%s),\n(reTx: callid=%s," - " cseq=%u, cseq_method=%s)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, - canceller_callid, canceller_cseq, - sipGetMethodString(canceller_cseq_method), - retx_callid, retx_cseq, - sipGetMethodString(retx_cseq_method)); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Not stopping retx timer"); - } - - free_sip_message(retx_message); -} - - -static int -sip_sm_request_check_and_store (ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t request_method, boolean midcall, - uint16_t *request_check_reason_code, - char *request_check_reason_phrase, - boolean store_invite) -{ - const char *fname = "sip_sm_request_check_and_store"; - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - uint32_t request_cseq_number = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - const char *callID = NULL; - int content_length = 0; - boolean request_uri_error = FALSE; - sipReqLine_t *requestURI = NULL; - sipLocation_t *uri_loc = NULL; - const char *sip_from = NULL; - const char *sip_to = NULL; - sipLocation_t *to_loc = NULL; - sipLocation_t *from_loc = NULL; - const char *pViaHeaderStr = NULL; - int16_t trx_index = -1; - sipVia_t *via = NULL; - - - /* test incoming parameter for NULL */ - if (!request_check_reason_phrase) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Input parameter request_check_reason_phrase is NULL", - fname); - return (-1); - } - - /* - * Parse Call-Id - */ - callID = sippmh_get_cached_header_val(request, CALLID); - if (!callID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's " - "Call-ID header.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT, - SIP_WARNING_LENGTH); - return (-1); - } - - /* - * Parse CSeq - */ - request_cseq = sippmh_get_cached_header_val(request, CSEQ); - if (!request_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's CSeq " - "header.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - SIP_WARNING_LENGTH); - return (-1); - } - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to parse request's CSeq " - "header.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - SIP_WARNING_LENGTH); - return (-1); - } - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - /* - * Parsing Request-Uri - */ - requestURI = sippmh_get_request_line(request); - if (requestURI) { - if (requestURI->url) { - uri_loc = sippmh_parse_from_or_to(requestURI->url, TRUE); - if (uri_loc) { - if (uri_loc->genUrl->schema != URL_TYPE_SIP) { - request_uri_error = TRUE; - } - sippmh_free_location(uri_loc); - } else { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - request_uri_error = TRUE; - } - if (request_uri_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid Request URI" - "failed.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - - /* - * Parse From - */ - sip_from = sippmh_get_cached_header_val(request, FROM); - from_loc = sippmh_parse_from_or_to((char *)sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - sippmh_free_location(from_loc); - - /* - * Parse To - */ - sip_to = sippmh_get_cached_header_val(request, TO); - to_loc = sippmh_parse_from_or_to((char *)sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - sippmh_free_location(to_loc); - - /* - * Parse Via - */ - pViaHeaderStr = sippmh_get_cached_header_val(request, VIA); - if (pViaHeaderStr) { - via = sippmh_parse_via(pViaHeaderStr); - } - if (!pViaHeaderStr || !via) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), NULL, - NULL, fname, "sippmh_parse_via"); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - SIP_WARNING_LENGTH); - return (-1); - - } - sippmh_free_via(via); - - /* - * Check - */ - switch (request_method) { - /* INVITE */ - case sipMethodInvite: - - content_length = sippmh_get_content_length(request); - - if (request->raw_body) { - - if ((size_t) content_length != strlen(request->raw_body)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and " - "Actual message body length:content length=%d\n" - "and message as %s\n and strlen of messagebody = %zu\n", - fname, content_length, request->raw_body, - strlen(request->raw_body)); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - } else { - if ((size_t) content_length != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and " - "Actual message body length:content length=%d\n" - "and message is empty and strlen of messagebody = 0\n", - fname, content_length); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - } - if (midcall && - ((ccb->last_recv_request_cseq_method == sipMethodInvite) || - (ccb->last_recv_request_cseq_method == sipMethodAck))) { - if (request_cseq_number <= ccb->last_recv_invite_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error: CSeq (%d) is not greater " - "than previous INVITE (%d).\n", fname, - request_cseq_number, - ccb->last_recv_invite_cseq); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - SIP_WARNING_LENGTH); - return (-1); - } - } - ccb->last_recv_invite_cseq = request_cseq_number; - break; - - /* BYE */ - case sipMethodBye: - if (ccb->flags & INCOMING) { - if (request_cseq_number <= ccb->last_recv_invite_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error: CSeq (%d) is not greater " - "than original INVITE (%d).\n", fname, - request_cseq_number, - ccb->last_recv_invite_cseq); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - SIP_WARNING_LENGTH); - return (-1); - } - } - break; - - /* ACK and CANCEL */ - case sipMethodCancel: - case sipMethodAck: - if (request_cseq_number != ccb->last_recv_invite_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"CSeq (%d) is not the same as " - "original INVITE (%d).\n", fname, - request_cseq_number, ccb->last_recv_request_cseq); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - SIP_WARNING_LENGTH); - return (-1); - } - break; - - default: - break; - } - - // Allocate a tx block and store the various params there - trx_index = get_next_request_trx_index(ccb, FALSE); - if (trx_index < 0) { - // Internal server error - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - "Too many Transactions", - SIP_WARNING_LENGTH); - return (-2); - } - /* - * Don't free it since this request will be again required - * for sending 487 response. This is a temporary solution - * and should be removed in Moonpie - */ - if (!store_invite) { - if (ccb->last_request) { - free_sip_message(ccb->last_request); - ccb->last_request = NULL; - } - } - /* Store request.Done after alloc of trx, to handle allocation failure. */ - ccb->last_request = request; - - ccb->last_recv_request_cseq = request_cseq_number; - ccb->last_recv_request_cseq_method = request_cseq_method; - ccb->recv_request[trx_index].cseq_number = request_cseq_number; - ccb->recv_request[trx_index].cseq_method = request_cseq_method; - pViaHeaderStr = sippmh_get_cached_header_val(request, VIA); - if (pViaHeaderStr) { - ccb->recv_request[trx_index].u.sip_via_header = - strlib_update(ccb->recv_request[trx_index].u.sip_via_header, - pViaHeaderStr); - } - - return (0); -} - - -/* - * Function: sip_sm_update_to_from_on_callsetup_finalresponse - * - * Parameters: ccb, response - * - * Description: Updates to and from from response - * - * Returns:Void - * - */ -void -sip_sm_update_to_from_on_callsetup_finalresponse (ccsipCCB_t *ccb, - sipMessage_t *response) -{ - const char *fname = "sip_sm_update_to_from_on_callsetup_finalresponse"; - const char *to; - const char *from; - sipLocation_t *to_loc = NULL; - - to = sippmh_get_cached_header_val(response, TO); - from = sippmh_get_cached_header_val(response, FROM); - - /* - * Record the "tag=" parameter - */ - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->tag) { - ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, sip_sm_purify_tag(to_loc->tag)); - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "TO header missing \"tag=\" param"); - /* ccb->sip_to_tag[0] = '\0'; */ - } - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Recorded to_tag=<%s>", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->sip_to_tag); - sippmh_free_location(to_loc); - } - } - - /* - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - if (to) { - ccb->sip_to = strlib_update(ccb->sip_to, to); - } - ccb->sip_from = strlib_update(ccb->sip_from, from); -} - - -/* - * Function: sip_sm_update_contact_recordroute - * - * Parameters:ccb, response , response_code, midcall boolean - * - * Description: Puts contact info and record_route info into ccb - * - * Returns:void - * - */ -void -sip_sm_update_contact_recordroute (ccsipCCB_t *ccb, sipMessage_t *response, - int response_code, boolean midcall) -{ - const char *contact; - const char *record_route; - - contact = sippmh_get_cached_header_val(response, CONTACT); - record_route = sippmh_get_cached_header_val(response, RECORD_ROUTE); - - if (response_code == SIP_STATUS_SUCCESS) { - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - } - if (record_route && (!midcall)) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = sippmh_parse_record_route(record_route); - } -} - - -/* - * SIP_STATE_ACTIVE - */ -void -ccsip_handle_active_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - cc_feature_name(feature_type)); - - switch (feature_type) { - case CC_FEATURE_HOLD: - ccb->hold_initiated = TRUE; - ccb->featuretype = CC_FEATURE_HOLD; - ccsip_handle_active_ev_cc_feature_hold(ccb, event); - break; - case CC_FEATURE_MEDIA: - ccb->featuretype = CC_FEATURE_MEDIA; - ccsip_handle_active_ev_cc_feature_resume_or_media(ccb, event); - break; - case CC_FEATURE_RESUME: - ccb->featuretype = CC_FEATURE_RESUME; - ccsip_handle_active_ev_cc_feature_resume_or_media(ccb, event); - break; - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - ccsip_handle_active_ev_cc_feature_xfer(ccb, event); - break; - case CC_FEATURE_NOTIFY: - if (event->u.cc_msg->msg.feature.data.notify.final == TRUE) { - ccb->flags |= FINAL_NOTIFY; - } - if (CC_CAUSE_OK != event->u.cc_msg->msg.feature.data.notify.cause) { - // Get the data from msg.get data for error code but currently we do not have any. - (void) sipSPISendNotify(ccb, event->u.cc_msg->msg.feature.data.notify.cause_code); - ccb->xfer_status = event->u.cc_msg->msg.feature.data.notify.cause_code; - } else { - (void) sipSPISendNotify(ccb, SIP_SUCCESS_SETUP); // Get the data from msg. - ccb->xfer_status = SIP_SUCCESS_SETUP; - } - break; - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_B2B_JOIN: - case CC_FEATURE_CANCEL: - break; - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - break; - } -} - - -/** - * This fucntion handles CC_FEATURE_HOLD in active state. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return None. - * - */ -void -ccsip_handle_active_ev_cc_feature_hold (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - cc_msgbody_info_t *msg_body; - - /* Copy the call-info into the CCB */ - ccsip_store_call_info(&event->u.cc_msg->msg.feature.data.hold.call_info, ccb); - if (event->u.cc_msg->msg.feature.data_valid) { - /* Replace the local copy of the msg. body */ - msg_body = &event->u.cc_msg->msg.feature.data.hold.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - sip_sm_change_state(ccb, SIP_STATE_SENT_MIDCALL_INVITE); - if (send_resume_or_hold_request(ccb, TRUE) == FALSE) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } -} - - -/** - * This fucntion handles CC_FEATURE_RESUME or CC_FEATURE_MEDIA in - * active state. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return None. - * - */ -void -ccsip_handle_active_ev_cc_feature_resume_or_media (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - cc_msgbody_info_t *msg_body; - - if (event->u.cc_msg->msg.feature.data_valid) { - /* Replace the local copy of the msg. body */ - msg_body = &event->u.cc_msg->msg.feature.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - /* Copy the call-info into the CCB */ - ccsip_store_call_info(&event->u.cc_msg->msg.feature.data.resume.call_info, ccb); - sip_sm_change_state(ccb, SIP_STATE_SENT_MIDCALL_INVITE); - if (send_resume_or_hold_request(ccb, FALSE) == FALSE) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } -} - -void -ccsip_handle_active_ev_cc_feature_xfer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_cc_feature_xfer"; - char referto[MAX_SIP_URL_LENGTH]; - char *domainloc = NULL; - char *pTransferNumberString; - cc_feature_data_t data; - cc_xfer_methods_t method; - char addr[MAX_IPADDR_STR_LEN]; - ccsipCCB_t *xfer_ccb = NULL; - int n = 0; - static char dialtranslate[MAX_SIP_URL_LENGTH]; - char *pReferToStr = referto; - sipRefEnum_e refto_type = SIP_REF_XFER; - - memset(addr, 0, MAX_IPADDR_STR_LEN); - method = event->u.cc_msg->msg.feature.data.xfer.method; - - if (CC_FEATURE_BLIND_XFER == event->u.cc_msg->msg.feature.feature_id) { - ccb->featuretype = CC_FEATURE_BLIND_XFER; - ccb->con_call_id = CC_NO_CALL_ID; - } else if (CC_FEATURE_XFER == event->u.cc_msg->msg.feature.feature_id) { - ccb->featuretype = CC_FEATURE_XFER; - ccb->con_call_id = event->u.cc_msg->msg.feature.data.xfer.target_call_id; - xfer_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - } - - - pTransferNumberString = event->u.cc_msg->msg.feature.data.xfer.dialstring; - (void) MatchDialTemplate(pTransferNumberString, ccb->dn_line, CAST_N &n, - dialtranslate, sizeof(dialtranslate), - (RouteMode *) &(ccb->routeMode), NULL); - /* Escape the characters in userinfo */ - domainloc = strchr(dialtranslate, '@'); - if (domainloc == NULL) { - (void) sippmh_convertURLCharToEscChar(dialtranslate, - strlen(dialtranslate), - pReferToStr, MAX_SIP_URL_LENGTH, TRUE); - } else { - (void) sippmh_convertURLCharToEscChar(dialtranslate, - domainloc - dialtranslate, - pReferToStr, MAX_SIP_URL_LENGTH, TRUE); - /* Append the host Part including @ */ - sstrncat(pReferToStr, domainloc, MAX_SIP_URL_LENGTH - strlen(pReferToStr)); - } - /* Re-write the escaped URL to dial translate */ - sstrncpy(dialtranslate, referto, MAX_SIP_URL_LENGTH); - pTransferNumberString = dialtranslate; - - - ccb->authen.cred_type = 0; - //add refer as SIP mURI - - // If there is no hostname, add proxy address as hostname - domainloc = strchr(referto, '@'); - if (domainloc == NULL) { - char *semi = NULL; - size_t len; - - /* see if we have ;user= */ - semi = strchr(pTransferNumberString, ';'); - - if (semi) { - sstrncpy(referto, "con_call_id); - if ((xfer_ccb != NULL) && - util_check_if_ip_valid(&(xfer_ccb->dest_sip_addr)) && - (ccb->featuretype == CC_FEATURE_XFER)) { - /* - * Populate addr with proxy through which transferor and - * target are talking - */ - if ((xfer_ccb->routeMode == RouteEmergency) || - (xfer_ccb->proxySelection == SIP_PROXY_BACKUP)) { - ipaddr2dotted(addr, &xfer_ccb->dest_sip_addr); - } else { - sipTransportGetPrimServerAddress(xfer_ccb->dn_line, addr); - } - } else { - /* - * In case of blind transfer xfer_ccb->dest_sip_addr will - * always show primary proxy. Since we don't know whether - * target of transfer is reachable by primary proxy or not, - * We are going to use proxy through which transferor is - * talking to transferee, assuming that transferee and target - * should be able to talk through the same proxy - */ - if ((ccb->routeMode == RouteEmergency) || - (ccb->proxySelection == SIP_PROXY_BACKUP)) { - ipaddr2dotted(addr, &ccb->dest_sip_addr); - } else { - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - } - } - - sstrncpy(domainloc, addr, - MAX_SIP_URL_LENGTH - (domainloc - referto - 1)); - } - - /* if we have a ;user=, then add it to the end of the string if we can */ - if (semi) { - domainloc = referto + strlen(referto); - sstrncpy(domainloc, semi, - MAX_SIP_URL_LENGTH - (domainloc - referto - 1)); - } - - if (semi) { - sstrncat(domainloc, ">", MAX_SIP_URL_LENGTH - strlen(referto)); - } - } - /* If the method is direct trasnfer then - * add more information to referto header - */ - if (method == CC_XFER_METHOD_DIRXFR) { - refto_type = SIP_REF_DIR_XFER; - } - - if (CC_XFER_METHOD_REFER == method || - method == CC_XFER_METHOD_DIRXFR) { - // Add refer as SIP Refer - ccsipCCB_t *xfer_refer_ccb; - - ccb->sip_referTo = strlib_update(ccb->sip_referTo, referto); - xfer_refer_ccb = sip_sm_get_target_call_by_con_call_id(ccb->con_call_id); - - if ((xfer_refer_ccb != NULL) && (xfer_ccb != NULL) && (xfer_ccb->sip_referTo[0] != '\0')) { - ccb->sip_referTo = strlib_update(ccb->sip_referTo, - xfer_refer_ccb->sip_referTo); - } - - if (ccb->sip_referTo) { - if (sipSPISendRefer(ccb, (char *)ccb->sip_referTo, refto_type) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPISendRefer Failed"); - return; - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "ccb->sipreferTo is NULL"); - return; - } - - } else if (CC_XFER_METHOD_BYE == method) { - cc_features_t feature; - - ccb->referto = strlib_update(ccb->referto, referto); - data.xfer.cause = CC_CAUSE_XFER_LOCAL; - feature = fsmxfr_type_to_feature(fsmxfr_get_xfr_type(ccb->gsm_id)); - data.xfer.method = CC_XFER_METHOD_BYE; // Temp Fix Need to remove - data.xfer.dialstring[0] = '\0'; - data.xfer.target_call_id = CC_NO_CALL_ID; - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature, &data, - CC_CAUSE_NORMAL); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Unspecified Method of Transfer"); - - } - - /* Pre-fill the ARP table */ - ADD_TO_ARP_CACHE(ccb->dest_sip_addr); -} - -void -ccsip_handle_active_ev_cc_feature_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_active_ev_cc_feature_ack"; - ccsipCCB_t *other_ccb = NULL; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - switch (feature_type) { - case CC_FEATURE_XFER: - case CC_FEATURE_BLIND_XFER: - if (CC_XFER_METHOD_REFER == event->u.cc_msg->msg.feature.data.xfer.method) { - if (CC_CAUSE_ERROR == event->u.cc_msg->msg.feature.data.xfer.cause) { - (void) sipSPISendErrorResponse(ccb->last_request, - SIP_SERV_ERR_UNAVAIL, - SIP_SERV_ERR_UNAVAIL_PHRASE, - 0, NULL, ccb); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Got CC_CAUSE_ERROR" - "from GSM \n", fname); - return; - } - if (CC_NO_CALL_ID != event->u.cc_msg->msg.feature.data.xfer.target_call_id) { - ccb->con_call_id = event->u.cc_msg->msg.feature.data.xfer.target_call_id; - if (feature_type == CC_FEATURE_BLIND_XFER) { - ccb->blind_xfer_call_id = event->u.cc_msg->msg.feature.data.xfer.target_call_id; - } - if (!sipSPISendReferResponse202(ccb)) { - (void) sipSPISendErrorResponse(ccb->last_request, - SIP_SERV_ERR_UNAVAIL, - SIP_SERV_ERR_UNAVAIL_PHRASE, - 0, NULL, ccb); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPISendReferResponse202" - " failed, sending 503\n", fname); - return; - } else { - /* Send NOTIFY 100 Trying */ - if (!sipSPISendNotify(ccb, SIP_1XX_TRYING)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPISendNotify" - " failed, sending 100\n", fname); - } - ccb->xfer_status = 100; - - if (feature_type == CC_FEATURE_BLIND_XFER) { - /* - * Release this call and tell GSM to start - * the Blind Transfer - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_NORMAL, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - } - } else if (CC_XFER_METHOD_BYE == event->u.cc_msg->msg.feature.data.xfer.method) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - break; - case CC_FEATURE_NOTIFY: - /* check for special case early attended transfer */ - other_ccb = sip_sm_get_target_call_by_con_call_id(ccb->con_call_id); - if ((other_ccb != NULL) && (other_ccb->early_transfer)) { - other_ccb->early_transfer = FALSE; - sipSPISendCancel(other_ccb); - sip_cc_release_complete(other_ccb->gsm_id, other_ccb->dn_line, - CC_CAUSE_NORMAL); - sip_sm_change_state(other_ccb, SIP_STATE_RELEASE); - } else { - // This might be a simple acknowledgement for a NOTIFY - // received from the network. Reply to the remote side - // including the cause-code received from GSM - (void) sipSPISendNotifyResponse(ccb, - event->u.cc_msg->msg.feature_ack.cause); - } - break; - - default: - break; - } -} - -void -ccsip_handle_active_ev_sip_invite (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_sip_invite"; - sipMessage_t *request; - - // currently not used: const char *require = NULL; - const char *contact = NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - boolean apply_ringout = FALSE; - - /* Unpack the event */ - request = event->u.pSipMessage; - - // Check for glare conditions - // If we have an outstanding INVITE that we sent then we have glare - if (get_method_request_trx_index(ccb, sipMethodInvite, TRUE) > -1) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d Glare condition detected", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index); - // return 491 - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_REQ_PENDING, - SIP_CLI_ERR_REQ_PENDING_PHRASE, - 0, NULL, NULL); - free_sip_message(request); - return; - } - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodInvite, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - - /* update the contact information if needed */ - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - - /* - * Process SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_OFFER_RECEIVED; - if (((ccb->state == SIP_STATE_SENT_MIDCALL_INVITE) && - (ccb->hold_initiated)) || (ccb->state == SIP_STATE_ACTIVE)) { - /* - * Respond to the BroadSoft Session Audit Message. - * Do same for Refresh case / ReInvite with the same SDP - * First request for the current sdp from gsm. - * - * Need to check for Call-Info ringout state and pass along so that session audit - * does not disable CCM spoofed ringout. - */ - if (ccb->in_call_info && - ccb->in_call_info->data.call_info_feat_data.feature_flag & CC_UI_STATE) { - apply_ringout = - (ccb->in_call_info->data.call_info_feat_data.ui_state == - CC_UI_STATE_RINGOUT ? TRUE : FALSE); - } - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - sip_cc_audit(ccb->gsm_id, ccb->dn_line, apply_ringout); - return; - } - /*FALLTHROUGH*/ - - case SIP_SDP_SUCCESS: - /* - * Check to see if received SDP indicates hold. If it is not - * a hold SDP, then we received a new media invite. - * Send FEATURE CC event to GSM. - */ - ccb->oa_state = OA_OFFER_RECEIVED; - /* - * Update connected party info from RPID and Call-Info header. - * Media will effect media, delay call information update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - /* Move the message body from the SIP msg. into CCAPI msg */ - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, request); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, &data); - sip_sm_change_state(ccb, - SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING); - break; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - return; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - return; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - return; - - case SIP_SDP_NOT_PRESENT: - /*FALLTHROUGH*/ - - default: - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Waiting for SDP in ACK", - DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - /* - * Update connected party info from RPID and Call-Info header. - * Resuming the media,update call info now. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, NULL); - sip_sm_change_state(ccb, - SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING); - break; - } - - sipSPISendInviteResponse100(ccb, FALSE); -} - - -void -ccsip_handle_active_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "Active_2xx"; - sipMessage_t *response; - int response_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - if (response_code == SIP_ACCEPTED) { - ccsip_handle_accept_2xx(ccb, event); - return; - } - - if (sipSPISendAck(ccb, response) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - free_sip_message(response); -} - - -/* - * SIP_STATE_SENT_MIDCALL_INVITE - */ - -/** - * ccsip_handle_sentinvite_midcall_ev_cc_feature - * - * The function handles for CC_FEATURE during mid call invite. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - */ -void ccsip_handle_sentinvite_midcall_ev_cc_feature (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sentinvite_midcall_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_RESUME: - case CC_FEATURE_HOLD: - case CC_FEATURE_MEDIA: - /* - * Send resume/hold/media request and waiting for the response. - * Indicate that the request can not proceed now and it should be - * retried later. GSM should not attempt this. - */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_REQUEST_PENDING); - break; - - default: - /* Other feature request is not supported or allowed now */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_ERROR); - break; - } -} - -/** - * ccsip_handle_sentinvite_midcall_ev_sip_2xx - * - * The function handles for SIP 2xx during mid call invite. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - */ -void ccsip_handle_sentinvite_midcall_ev_sip_2xx (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sentinvite_midcall_ev_sip_2xx"; - sipMessage_t *response; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - - response = event->u.pSipMessage; - if (!sip_sm_is_invite_response(response)) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - /* Stop the expires timer started to await this response */ - (void) sip_platform_expires_timer_stop(ccb->index); - - sip_sm_200and300_update(ccb, response, SIP_STATUS_SUCCESS); - - /* Reset credentials flag since Hold was successfully processed */ - ccb->authen.cred_type = 0; - - /* - * Send ACK back soon to minimize delayed cutting through at the - * remote end. - */ - if (sipSPISendAck(ccb, response) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - /* Extract destination SDP and related fields */ - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - case SIP_SDP_NOT_PRESENT: - ccb->oa_state = OA_IDLE; - /* Move the messag bodies from SIP msg. to CCAPI msg. */ - switch (ccb->featuretype) { - case CC_FEATURE_HOLD: - sip_cc_mv_msg_body_to_cc_msg(&data.hold.msg_body, response); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - &data, CC_CAUSE_NORMAL); - break; - case CC_FEATURE_RESUME: - case CC_FEATURE_MEDIA: - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, response); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - &data, CC_CAUSE_NORMAL); - break; - default: - /* - * Other features are not expected. - */ - CCSIP_DEBUG_ERROR(DEB_L_C_F_PREFIX"%d: unexpected feature %d", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->featuretype); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - NULL, CC_CAUSE_ERROR); - break; - } - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, NULL, - CC_CAUSE_ERROR); - break; - } - - free_sip_message(response); - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); -} - -void -ccsip_handle_accept_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - cc_feature_data_t data; - cc_features_t feature; - sipMessage_t *response; - int response_code = 0; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - char *fname = "ccsip_handle_accept_2xx"; - sipMethod_t response_method; - - response = event->u.pSipMessage; - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - /* don't ack a 200 on a Notify message */ - // if ((response_code == SIP_SUCCESS_SETUP) && - // (ccb->last_sent_request_cseq_method == sipMethodNotify)) { - // free_sip_message(response); - // return; - // } - // Instead of checking the last request, check the CSeq method of - // the response and then determine which request it is responding to - // Then clear that request from the cseq array - cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - free_sip_message(response); - return; - } - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - free_sip_message(response); - return; - } - response_method = sipCseq->method; - cpr_free(sipCseq); - - if ((response_code == SIP_SUCCESS_SETUP) && - (response_method == sipMethodNotify)) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - free_sip_message(response); - return; - } - - if (response_code != SIP_ACCEPTED) { - if (sipSPISendAck(ccb, response) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - free_sip_message(response); - return; - } - } - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_B2B_JOIN: - case CC_FEATURE_CANCEL: - ccb->authen.cred_type = 0; - feature = ccb->featuretype; - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature, NULL, - CC_CAUSE_OK); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - free_sip_message(response); - return; - default: - break; - } - - data.xfer.cause = CC_CAUSE_XFER_LOCAL; - data.xfer.method = CC_XFER_METHOD_REFER; - data.xfer.dialstring[0] = '\0'; - data.xfer.target_call_id = ccb->gsm_id; - feature = fsmxfr_type_to_feature(fsmxfr_get_xfr_type(ccb->gsm_id)); - - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature, &data, CC_CAUSE_OK); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - free_sip_message(response); -} - -/* - * SIP_STATE_RECV_MIDCALLINVITE_CCFEATUREACK_PENDING - */ -void -ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack ( - ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - cc_features_t feature_type; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_HOLD: - if (event->u.cc_msg->msg.feature_ack.data_valid) { - /* Save the msg. body */ - msg_body = &event->u.cc_msg->msg.feature_ack.data.hold.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - sipSPISendInviteResponse200(ccb); /* HOLD */ - sip_sm_change_state(ccb, - SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING); - break; - - case CC_FEATURE_RESUME: - /* fall through to send the response */ - case CC_FEATURE_MEDIA: - /* new media acks put the sdp in the resume area as well */ - if (event->u.cc_msg->msg.feature_ack.data_valid) { - msg_body = &event->u.cc_msg->msg.feature_ack.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - if (event->u.cc_msg->msg.feature_ack.cause == CC_CAUSE_PAYLOAD_MISMATCH || - event->u.cc_msg->msg.feature_ack.cause == CC_CAUSE_NO_MEDIA || - event->u.cc_msg->msg.feature_ack.cause == CC_CAUSE_ERROR) { - /* - * Rejecting the new sdp - * The above errors are the ones currently thrown by gsm sdp processing. - * If any new errors are added the above check must be updated. - */ - ccb->oa_state = OA_IDLE; - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_NOT_ACCEPT_HERE, - SIP_CLI_ERR_NOT_ACCEPT_HERE_PHRASE, - SIP_WARN_MISC, - "SDP Not Acceptable", - FALSE, /* no SDP */ TRUE /* reTx */); - } else { - sipSPISendInviteResponse200(ccb); - } - sip_sm_change_state(ccb, SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING); - break; - - default: - break; - } -} - - -/* - * SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING - */ -void -ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = - "ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack"; - sipMessage_t *request; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodAck, FALSE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - free_sip_message(request); - return; - } - - /* - * Process SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - if (ccb->oa_state != OA_OFFER_SENT) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Unexpected SDP in ACK, releasing call"); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Check to see if received SDP indicates hold. If it is not - * a hold SDP, then we received a new media invite. - * Send FEATURE CC event to GSM. - */ - ccb->oa_state = OA_IDLE; - - /* - * Update connected party info from RPID and Call-Info header. - * MEDIA request, delay UI update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - - /* Move the msg. body from the SIP msg. to CCAPI msg. */ - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, request); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, &data); - break; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - return; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - break; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - return; - - case SIP_SDP_NOT_PRESENT: - if (ccb->oa_state == OA_OFFER_SENT) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "No answer SDP in ACK, releasing call"); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } else { - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - } - break; - - default: - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - break; - - } - - /* - * Update state - */ - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); -} - - -void -ccsip_handle_transienthold_ev_cc_feature (ccsipCCB_t *ccb, int feature_type, - sipSMStateType_t final_resume_state, - sipSMEvent_t *event) -{ - const char *fname = "transienthold_ev_cc_feature"; - cc_msgbody_info_t *msg_body; - - switch (feature_type) { - case CC_FEATURE_RESUME: - if (event->u.cc_msg->msg.feature.data_valid) { - msg_body = &event->u.cc_msg->msg.feature.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - ccb->hold_initiated = FALSE; - ccb->featuretype = CC_FEATURE_RESUME; - sip_sm_change_state(ccb, final_resume_state); - break; - - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - break; - } -} - - -int -strcasecmp_ignorewhitespace (const char *cs, const char *ct) -{ - const char *p; - const char *q; - - if (cpr_strcasecmp(cs, ct) == 0) { - return (0); - } - - p = cs; - q = ct; - - /* Ignore leading white space */ - while (((*p == ' ') || (*p == '\t')) && (*p != '\0')) { - p++; - } - while (((*q == ' ') || (*q == '\t')) && (*q != '\0')) { - q++; - } - - /* Compare until hit end or whitespace */ - while ((*p != ' ') && (*p != '\t') && (*p != '\0') && - (*q != ' ') && (*q != '\t') && (*q != '\0')) { - if (toupper(*p) != toupper(*q)) { - return (-1); - } - p++; - q++; - } - - /* Make sure that what's left (if any) is whitespace */ - while (*p != '\0') { - if ((*p != ' ') && (*p != '\t')) { - return (-1); - } - p++; - } - while (*q != '\0') { - if ((*q != ' ') && (*q != '\t')) { - return (-1); - } - q++; - } - - return (0); -} - - -void -sip_sm_util_normalize_name (ccsipCCB_t *ccb, char *dialString) -{ - char *outputString; - uint32_t usernameLength = 0; - const char *hostnameString = NULL; - uint32_t hostnameLength = 0; - char proxy_ipaddr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t proxy_ipaddr; - char *extraString = NULL; - char *parse_token; - uint32_t extraLength = 0; - uint32_t n = 0; - static char dialtranslate[MAX_SIP_URL_LENGTH]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char addr[MAX_IPADDR_STR_LEN]; - int port; - int dialStringLength; - - CPR_IP_ADDR_INIT(proxy_ipaddr); - /* - * Save away what they sent us so that we can display it to them later - */ - dialStringLength = strlen(dialString); - memcpy((void *)ccb->calledDisplayedName, dialString, dialStringLength); - /* - * See if the string needs to be rewritten by applying the dial template - */ - ccb->routeMode = RouteDefault; - (void) MatchDialTemplate(ccb->calledDisplayedName, ccb->dn_line, CAST_N &n, dialtranslate, - sizeof(dialtranslate), - (RouteMode *) &(ccb->routeMode), NULL); - dialString = dialtranslate; - dialStringLength = strlen(dialString); - /* - * Throw away any part of 0) && (dialString[0] == '<')) { - dialString++; - dialStringLength--; - } - /* - * For the SIP: part, we have to have 4 characters - */ - if ((dialStringLength > 4) && - (tolower(dialString[0]) == 's') && - (tolower(dialString[1]) == 'i') && - (tolower(dialString[2]) == 'p') && - (tolower(dialString[3]) == ':')) { - dialStringLength -= 4; - dialString += 4; - } - - /* - * Parse the remainder of the string looking for the host name - */ - parse_token = strpbrk(dialString, "@;>"); /* Skip the user name first */ - if (parse_token == NULL) { /* Only user name exists and no host, extra and ;> */ - usernameLength = dialStringLength; - } else { - usernameLength = parse_token - dialString; /* save username length */ - if (parse_token[0] == '@') { /* host name exists in addition */ - extraString = strpbrk(parse_token, ";>"); /* Skip the host name */ - if (extraString != NULL) { /* extra params exist */ - extraLength = dialStringLength - (extraString - dialString); - } - /* - * Save the host name and host length if proxy selection is - * not backup. In case of proxy selection being backup, - * ignore the hostname & rebuild using dotted IP of backup proxy later - */ - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - hostnameString = parse_token + 1; - /* In case of host name, the length must exclude @ and hence -1 */ - hostnameLength = dialStringLength - usernameLength - extraLength - 1; - } - } else { /* No host, but extra param exist */ - extraLength = dialStringLength - usernameLength; - extraString = parse_token; - } - } - - /* - * At this point we have - * usernameLength - Number of characters in the user name - * starting from dialString[0] - * hostnameString - NULL if no @ was encountered, otherwise it - * points to the start of the host name string - * hostnameLength - 0 if no host name characters were encountered - * extraString - Points to any extra parameters - * extraLength - number of extra parameter characters - */ - if (hostnameLength == 0) { - /* - * At this junctor in the quantum, - * - */ - switch (ccb->routeMode) { - case RouteEmergency: - /* - * If we have failed over to the backup we need - * to not reselect the emergency proxy - */ - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - // Get the Emergency Proxy - sipTransportGetEmerServerAddress(ccb->dn_line, proxy_ipaddr_str); - hostnameString = &proxy_ipaddr_str[0]; - hostnameLength = strlen(hostnameString); - if (hostnameLength) { - if (!str2ip((const char *) proxy_ipaddr_str, &proxy_ipaddr)) { - /* Fill in address and port in CCB */ - util_ntohl(&(ccb->dest_sip_addr), &(proxy_ipaddr)); - - /* - * If the Proxy Emergency Port isn't contained in the - * config table, use the PROXYN port instead. - */ - port = sipTransportGetEmerServerPort(ccb->dn_line); - if (port) { - ccb->dest_sip_port = port; - } else { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - break; - } - } - } - // Otherwise Emergency proxy is not in configuration follow thru - /*FALLTHROUGH*/ - default: - /* - * set the proxy address differently if the backup proxy - * has been activated. The address has already been placed into - * ccb->dest_sip_addr and ccb->dest_sip_port so just use - * those values - */ - if (ccb->proxySelection == SIP_PROXY_BACKUP) { - ipaddr2dotted(dest_sip_addr_str, &ccb->dest_sip_addr); - hostnameString = dest_sip_addr_str; - hostnameLength = strlen(hostnameString); - } else { - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - hostnameString = addr; - hostnameLength = strlen(hostnameString); - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - } - } - - /* - * Construct the actual dial out string - */ - outputString = (char *) ccb->calledNumber; - sstrncpy(outputString, " - */ - outputString[extraLength] = 0; - /* - * If there was no > in what they gave us, put one in for them - */ - if (strchr(outputString, '>') == NULL) { - outputString[extraLength++] = '>'; - } - outputString += extraLength; - } else { - *outputString++ = '>'; - } - /* - * Null terminate the string for good measure and note how long it is - */ - *outputString = 0; - ccb->calledNumberLen = (uint16_t) (outputString - ccb->calledNumber); -} - - -void -get_sip_error_string (char *errortext, int response) -{ - - if (NULL == errortext) - return; - switch (response) { - case SIP_SUCCESS_SETUP: - sstrncpy(errortext, SIP_SUCCESS_SETUP_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_ACCEPTED: - sstrncpy(errortext, SIP_ACCEPTED_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_1XX_TRYING: - sstrncpy(errortext, SIP_1XX_TRYING_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_MULT_CHOICES: - sstrncpy(errortext, SIP_RED_MULT_CHOICES_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_MOVED_PERM: - sstrncpy(errortext, SIP_RED_MOVED_PERM_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_MOVED_TEMP: - sstrncpy(errortext, SIP_RED_MOVED_TEMP_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_SEE_OTHER: - sstrncpy(errortext, SIP_RED_SEE_OTHER_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_USE_PROXY: - sstrncpy(errortext, SIP_RED_USE_PROXY_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_ALT_SERVICE: - sstrncpy(errortext, SIP_RED_ALT_SERVICE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_BAD_REQ: /* 400 Bad Request */ - sstrncpy(errortext, SIP_CLI_ERR_BAD_REQ_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_UNAUTH: /* 401 Unauthorized */ - sstrncpy(errortext, SIP_CLI_ERR_UNAUTH_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_PAY_REQD: /* 402 Payment Required */ - sstrncpy(errortext, SIP_CLI_ERR_PAY_REQD_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_FORBIDDEN: /* 403 Forbidden */ - sstrncpy(errortext, SIP_CLI_ERR_FORBIDDEN_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_FOUND: /* 404 Not Found */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_FOUND_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_ALLOWED: /* 405 Method Not Allowed */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_ALLOWED_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_ACCEPT: /* 406 Not Acceptable */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_ACCEPT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_PROXY_REQD: /* 407 Proxy Authentication Required */ - sstrncpy(errortext, SIP_CLI_ERR_PROXY_REQD_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_REQ_TIMEOUT: /* 408 Request Timeout */ - sstrncpy(errortext, SIP_CLI_ERR_REQ_TIMEOUT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_CONFLICT: /* 409 Conflict */ - sstrncpy(errortext, SIP_CLI_ERR_CONFLICT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_GONE: /* 410 Gone */ - sstrncpy(errortext, SIP_CLI_ERR_GONE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LEN_REQD: /* 411 Length Required */ - sstrncpy(errortext, SIP_CLI_ERR_LEN_REQD_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LARGE_MSG: /* 413 Request Message Body Too Large */ - sstrncpy(errortext, SIP_CLI_ERR_LARGE_MSG_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LARGE_URI: /* 414 Request-URI Too Large */ - sstrncpy(errortext, SIP_CLI_ERR_LARGE_URI_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_MEDIA: /* 415 Unsupported Media Type */ - sstrncpy(errortext, SIP_CLI_ERR_MEDIA_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_EXTENSION: /* 420 Bad Extension */ - sstrncpy(errortext, SIP_CLI_ERR_EXTENSION_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED: /* 433 Anonymity Disallowed */ - sstrncpy(errortext, SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_AVAIL: /* 480 Temporarily Not Available */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_AVAIL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_CALLEG: /* 481 Call Leg/Transaction Does Not Exist */ - sstrncpy(errortext, SIP_CLI_ERR_CALLEG_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LOOP_DETECT: /* 482 Loop Detected */ - sstrncpy(errortext, SIP_CLI_ERR_LOOP_DETECT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_MANY_HOPS: /* 483 Too Many Hops */ - sstrncpy(errortext, SIP_CLI_ERR_MANY_HOPS_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_ADDRESS: /* 484 Address Incomplete */ - sstrncpy(errortext, SIP_CLI_ERR_ADDRESS_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_AMBIGUOUS: /* 485 Ambiguous */ - sstrncpy(errortext, SIP_CLI_ERR_AMBIGUOUS_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_BUSY_HERE: /* 486 Busy here */ - sstrncpy(errortext, SIP_CLI_ERR_BUSY_HERE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_REQ_CANCEL: /* 487 Request Cancelled */ - sstrncpy(errortext, SIP_CLI_ERR_REQ_CANCEL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_BAD_EVENT: /* 489 Bad Event */ - sstrncpy(errortext, SIP_CLI_ERR_BAD_EVENT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_INTERNAL: /*500 Internal Server Error */ - sstrncpy(errortext, SIP_SERV_ERR_INTERNAL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_NOT_IMPLEM: /* 501 Not Implemented */ - sstrncpy(errortext, SIP_SERV_ERR_NOT_IMPLEM_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_BAD_GW: /*502 Bad Gateway */ - sstrncpy(errortext, SIP_SERV_ERR_BAD_GW_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_UNAVAIL: /* 503 Service Unavailable */ - sstrncpy(errortext, SIP_SERV_ERR_UNAVAIL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_GW_TIMEOUT: /*504 Gateway Timeout */ - sstrncpy(errortext, SIP_SERV_ERR_GW_TIMEOUT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_SIP_VER: /*505 SIP Version not supported */ - sstrncpy(errortext, SIP_SERV_ERR_SIP_VER_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_PRECOND_FAILED: /*580 Precondition Failed */ - sstrncpy(errortext, SIP_SERV_ERR_PRECOND_FAILED_PHRASE, - MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_BUSY: /*600 BUSY */ - sstrncpy(errortext, SIP_FAIL_BUSY_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_DECLINE: /*603 Decline */ - sstrncpy(errortext, SIP_FAIL_DECLINE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_NOT_EXIST: /*604 Does not exist anywhere */ - sstrncpy(errortext, SIP_FAIL_NOT_EXIST_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_NOT_ACCEPT: /*606 Not Acceptable */ - sstrncpy(errortext, SIP_FAIL_NOT_ACCEPT_PHRASE, MAX_SIP_URL_LENGTH); - break; - default: - sstrncpy(errortext, SIP_STATUS_PHRASE_NONE, MAX_SIP_URL_LENGTH); - break; - } -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_sip_update - * Description: This function handles an incoming UPDATE message, parses - * and sends it up to GSM as cc_feature call - *************************************** ********************************/ -void -ccsip_handle_early_ev_sip_update (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "early_ev_sip_update"; - sipMessage_t *request = NULL; - unsigned short request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - sipsdp_status_t sdp_status; - boolean display_valid = TRUE; - - - /* Unpack the event */ - request = event->u.pSipMessage; - - sipGetRequestMethod(request, &method); - - // Check if we are already processing a previously received UPDATE - if (get_method_request_trx_index(ccb, method, FALSE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received UPDATE while processing an old one!", - fname); - (void) sipSPISendErrorResponse(request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - free_sip_message(request); - return; - } - - // Check if we have an UPDATE outstanding - if so we have a glare condition - if (get_method_request_trx_index(ccb, method, TRUE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received UPDATE while old one outstanding!", - fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_REQ_PENDING, - SIP_CLI_ERR_REQ_PENDING_PHRASE, 0, NULL, NULL); - free_sip_message(request); - return; - } - - memset(request_check_reason_phrase, 0, SIP_WARNING_LENGTH); - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - /* - * Check if display options are acceptable. - */ - display_valid = ccsip_check_display_validity(ccb, request); - if (!display_valid) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Rejecting UPDATE with callerid blocked.Anonymous Callback configured!", - fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED, - SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - return; - } - - // Check for anything in the REQUIRE header - // Update the contact information, if any - - // Since this is still an early dialog and we have not updated our from/to headers - // Copy the To header so that a response can be generated correctly - if (!(ccb->flags & INCOMING)) { - const char *from; - - from = sippmh_get_cached_header_val(request, FROM); - ccb->sip_to = strlib_update(ccb->sip_to, from); - } - - // If there is SDP in this message, extract it and send it up to GSM - sdp_status = sip_util_extract_sdp(ccb, request); - switch (sdp_status) { - case SIP_SDP_SUCCESS: - /* - * Since we do not support PRACK, UPDATE received for an early - * dialog can not contain SDP. RFC3311 section 5.2 describes - * the behavior to follow when receiving UPDATE. - * - * If UAS receives UPDATE before UAS has generated answer to - * previous offer, UAS must respond with 500 which includes a - * Retry-after header field with a random value between 0 and - * 10 seconds. - * - * If UAS receives UPDATE before receiving an answer to an offer - * made by the UAS, the UAS must respond with 491. - */ - if (ccb->oa_state == OA_OFFER_SENT) { - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_REQUEST_PENDING, FALSE); - } else { - /* - * Must be case that ccb->oa_stat == OA_OFFER_RECEIVED, since we - * are an early dialog. In either case, we send 500 response. - */ - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_NO_RESOURCE, FALSE); - } - return; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - return; - - case SIP_SDP_DNS_FAIL: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", ccb); - return; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - return; - - case SIP_SDP_NOT_PRESENT: - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX":Update received without SDP", fname); - break; - } - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - - /* - * Since we do not support PRACK, media can not be changed with UPDATE - * during early dialog. We alread sent the call info changes to GSM above - * so there is nothing else to inform GSM about. Go ahead and send the - * response to the far end. - * NOTE: When PRACK is supported, we will need to update this function - * to send media to GSM. - */ - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_OK, FALSE); -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_sip_update_response - * Description: This function handles an incoming response to a previously - * send UPDATE message, and sends it up to GSM via cc_feature_ack - ***********************************************************************/ -void -ccsip_handle_early_ev_sip_update_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_cc_feature - * Description: This function handles GSM's request to invoke a feature - * before the dialog is fully established. - ***********************************************************************/ -void -ccsip_handle_early_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - - const char *fname = "early_ev_cc_feature"; - cc_features_t feature_type; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - if (feature_type == CC_FEATURE_UPDATE) { - if (event->u.cc_msg->msg.feature.data_valid) { - msg_body = &event->u.cc_msg->msg.feature.data.update.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - (void) sipSPISendUpdate(ccb); - } else if (feature_type == CC_FEATURE_SELECT) { - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - } -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_cc_feature_ack - * Description: This function handles GSM's acknowledgment to an early - * feature invocation. At this time only responses to the - * UPDATE message is supported - ***********************************************************************/ -void -ccsip_handle_early_ev_cc_feature_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "early_ev_cc_feature_ack"; - cc_features_t feature_type; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_UPDATE: - if (event->u.cc_msg->msg.feature.data_valid) { - msg_body = &event->u.cc_msg->msg.feature.data.update.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - (void) sipSPISendUpdateResponse(ccb, event->u.cc_msg->msg.feature.data_valid, - event->u.cc_msg->msg.feature_ack.cause, - FALSE); - break; - - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - break; - } -} - -/*********************************************************************** - * Function: ccsip_handle_active_ev_sip_update - * - * Description: This function handles receipt of a SIP UPDATE message - * when the call is in the confirmed state. Based on the SDP contained, - * this may be put the call on hold or to propose new media. In either - * case, the new SDP is sent upto the GSM using cc_feature_update. - * - * In addition or instead of a media change, the UPDATE may also send - * updated values of the call-info header and RPID so these need to parsed - * and sent to GSM as well - * - * This function is analogous to the one the processes reINVITEs - ***********************************************************************/ -void -ccsip_handle_active_ev_sip_update (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_sip_update"; - sipMessage_t *request; - const char *require = NULL; - const char *contact = NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - boolean display_valid = TRUE; - - /* Unpack the event */ - request = event->u.pSipMessage; - - // Check if we are already processing a previously received UPDATE - if (get_method_request_trx_index(ccb, sipMethodUpdate, FALSE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received UPDATE while processing an old one!", - fname); - (void) sipSPISendErrorResponse(request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - free_sip_message(request); - return; - } - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodUpdate, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - /* - * Check if display options are acceptable. - */ - display_valid = ccsip_check_display_validity(ccb, request); - if (!display_valid) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Rejecting UPDATE with callerid blocked.Anonymous Callback configured!", - fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED, - SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - return; - } - - /* Require: header */ - require = sippmh_get_cached_header_val(request, REQUIRE); - if (require) { - ccb->sip_require = strlib_update(ccb->sip_require, require); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Unsupported Require Header in UPDATE", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_EXTENSION, - SIP_CLI_ERR_EXTENSION_PHRASE, - 0, NULL, FALSE, /*no SDP */ TRUE /*reTx */); - return; - } - - /* update the contact information if needed */ - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - - - - /* - * Process SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SESSION_AUDIT: - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Received Session Audit SDP in UPDATE", - DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - /*FALLTHROUGH*/ - - case SIP_SDP_SUCCESS: - /* - * If UAS receives UPDATE before UAS has generated answer to - * previous offer, UAS must respond with 500 which includes a - * Retry-after header field with a random value between 0 and - * 10 seconds. - * - * If UAS receives UPDATE before receiving an answer to an offer - * made by the UAS, the UAS must respond with 491. - */ - if (ccb->oa_state != OA_IDLE) { - cc_causes_t cause; - - cause = (ccb->oa_state == OA_OFFER_SENT ? - CC_CAUSE_REQUEST_PENDING : CC_CAUSE_NO_RESOURCE); - (void) sipSPISendUpdateResponse(ccb, FALSE, cause, FALSE); - return; - } - /* - * Process Call-info header, if any - */ - if (sdp_status == SIP_SDP_SESSION_AUDIT) { - /* Update call info to UI can be not delayed */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - } else { - /* Update call info to UI can be delayed */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - } - - /* - * Check to see if received SDP indicates hold. If it is not - * a hold SDP, then we received a new media invite. - * Send FEATURE CC event to GSM. - */ - ccb->oa_state = OA_OFFER_RECEIVED; - /* Move the message body from the SIP msg. into CCAPI msg */ - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, request); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, &data); - sip_sm_change_state(ccb, - SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING); - break; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - return; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - return; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - return; - - case SIP_SDP_NOT_PRESENT: - default: - /* Update call info to UI can be not delayed */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_UPDATE, NULL); - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_OK, FALSE); - break; - } - -} - -/*********************************************************************** - * Function: ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack - * - * Description: This function handles a CC_FEATURE_ACK from GSM that the - * GSM sends in response to an new media SDP or hold received in an UPDATE - * message and sent to it. - ***********************************************************************/ -void -ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack ( - ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - cc_features_t feature_type; - cc_causes_t cause; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - cause = event->u.cc_msg->msg.feature_ack.cause; - - switch (feature_type) { - case CC_FEATURE_HOLD: - if (cause == CC_CAUSE_NORMAL) { - cause = CC_CAUSE_OK; - } - if (event->u.cc_msg->msg.feature_ack.data_valid) { - msg_body = &event->u.cc_msg->msg.feature_ack.data.hold.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - (void) sipSPISendUpdateResponse(ccb, - event->u.cc_msg->msg.feature.data_valid, - cause, FALSE); - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - break; - - case CC_FEATURE_RESUME: - case CC_FEATURE_MEDIA: - if (cause == CC_CAUSE_NORMAL || cause == CC_CAUSE_NO_RESUME) { - cause = CC_CAUSE_OK; - } - - /* new media acks put the sdp in the resume area as well */ - if (event->u.cc_msg->msg.feature_ack.data_valid) { - msg_body = &event->u.cc_msg->msg.feature_ack.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - (void) sipSPISendUpdateResponse(ccb, - event->u.cc_msg->msg.feature.data_valid, - cause, FALSE); - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - break; - - default: - break; - } -} - -/*********************************************************************** - * Function: ccsip_handle_timer_glare_avoidance - * - * Description: This function handles the glare condition previously - * detected - ***********************************************************************/ -void -ccsip_handle_timer_glare_avoidance (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "timer_glare_avoidance"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), ccb->index, - ccb->dn_line, fname, "Resending message"); - - // Check if this message still needs to be sent. - if (ccb->state == SIP_STATE_IDLE || - ccb->state == SIP_STATE_RELEASE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"LINE %d CCB no longer used - message not sent!", - fname, ccb->index); - return; - } - - // Note that the assumption here is that the glare condition can only happen - // on an INVITE. Perhaps some more checks could be made here to make sure - // this was the case - (void) sipSPISendInviteMidCall(ccb, FALSE); -} - -/*********************************************************************** - * - * SIPTaskProcessSIPNotifyServiceControl - * - * Handles an incoming unsolicited NOTIFY service control message - * - * Parameters: Incoming pSipMessage - * - * Return Value: scb if message is validated - * NULL if validation fails - * - ***********************************************************************/ -sipServiceControl_t * -ccsip_get_notify_service_control (sipMessage_t *pSipMessage) -{ - const char *fname = "ccsip_get_notify_service_control"; - sipServiceControl_t *scp; - line_t i; - ccsipCCB_t *ccb = NULL; - boolean param_match = FALSE; - - // Check the body - if (pSipMessage->mesg_body[0].msgBody == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY with no body", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_NO_BODY, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return NULL; - } - if (pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY with unknown body type", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return NULL; - } - // Parse the body - scp = sippmh_parse_service_control_body(pSipMessage->mesg_body[0].msgBody, - pSipMessage->mesg_body[0].msgLength); - - if (scp == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY but couldn't parse body", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return NULL; - } - // Verify common mandatory parms - if (scp->registerCallID == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY but no mandatory params", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - - - if (scp->action == SERVICE_CONTROL_ACTION_CHECK_VERSION) { - // make sure they gave us all the version stamps - boolean all_provided; - - all_provided = ((scp->configVersionStamp != NULL) && - (scp->dialplanVersionStamp != NULL) && - (scp->softkeyVersionStamp != NULL)) ? TRUE : FALSE; - if (!all_provided) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY but no mandatory params", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - } - - if (scp->action == SERVICE_CONTROL_ACTION_APPLY_CONFIG) { - // make sure they gave us all the mandatory parameters - boolean all_provided; - - /* - * following condition checks that all mandatory filed are present. - * firmwareInactiveLoadId is not mandatory field because of backward - * compatibility purposes. So, it is not included in the following - * check. - */ - all_provided = ((scp->configVersionStamp != NULL) && - (scp->dialplanVersionStamp != NULL) && - (scp->softkeyVersionStamp != NULL) && - (scp->cucm_result != NULL) && - (scp->firmwareLoadId != NULL) && - (scp->loadServer != NULL) && - (scp->logServer != NULL)) ? TRUE : FALSE; - if (!all_provided) - { - CCSIP_DEBUG_TASK(SIP_F_PREFIX "Incorrect message format or missing " - "param value for [configVer/cucmResult] in" - " apply-config NOTIFY\n\n" - "configVersionStamp=%s \ndialplanVersionStamp=%s" - "\nsoftkeyVersionStamp=%s \ncucmResult=%s " - "\nloadId=%s \ninactiveLoadId=%s \nloadServer=%s \nlogServer=%s " - "\nppid=%s\n\n", fname, - (scp->configVersionStamp != NULL) ? scp->configVersionStamp - : "", - (scp->dialplanVersionStamp != NULL) ? - scp->dialplanVersionStamp:"", - (scp->softkeyVersionStamp != NULL) ? - scp->softkeyVersionStamp : "", - scp->cucm_result != NULL ? scp->cucm_result : "", - (scp->firmwareLoadId != NULL) ? scp->firmwareLoadId : "", - (scp->firmwareInactiveLoadId != NULL) ? scp->firmwareInactiveLoadId : "", - (scp->loadServer != NULL) ? scp->loadServer : "", - (scp->logServer != NULL) ? scp->logServer : "", - scp->ppid == TRUE? "True": "False"); - - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - /* - * Now if firmwareInactiveLoadId is null, then allocate empty string to - * it so that an empty string can be passed on to java side. - */ - if (scp->firmwareInactiveLoadId == NULL) { - scp->firmwareInactiveLoadId = cpr_calloc(1, 2); - } - } - - - // Take action - // Compare the reg call id received with call-id that we sent out - for (i = REG_CCB_START; i <= TEL_CCB_END + 1; i++) { - ccb = sip_sm_get_ccb_by_index(i); - if (ccb) { - if (strcmp(scp->registerCallID, ccb->sipCallID) == 0) { - param_match = TRUE; - break; - } - } - } - - // Call Platform API for actually performing the called for action - if (param_match && ccb != NULL) { - if (sip_regmgr_get_cc_mode(ccb->dn_line) != REG_MODE_CCM) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY in non CCM mode", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY, callid doesn't match", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - - /* NOTIFY message validated and scp allocated */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY, callid matches", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - return scp; -} - -void -ccsip_handle_unsolicited_notify (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_unsolicited_notify"; - sipMessage_t *request; - sipServiceControl_t *scp; - - /* Unpack the event */ - request = event->u.pSipMessage; - - scp = ccsip_get_notify_service_control(request); - if (scp != NULL) { - if (scp->action == SERVICE_CONTROL_ACTION_CALL_PRESERVATION) { - if (ccb->state == SIP_STATE_ACTIVE) { - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_CALL_PRESERVATION, NULL); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP state %s ignoring call preservation request", - fname, sip_util_state2string(ccb->state)); - } - if (sipSPISendErrorResponse(request, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - - - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Unsupported unsolicited notify event", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - sippmh_free_service_control_info(scp); - } -} - - - -/** - * This function frees a duped CCB. - * - * @param dup_ccb The duplicate CCB to free - */ -void free_duped (ccsipCCB_t *dup_ccb) -{ - -} - -/** - * This function dups the origCCB and returns a new ccb. It applies - * to only TEL CCBs. The contents of the new CCB is determined by dupCCBFlags. - * - * dupCCBFlag values are: - * DUPED_CCB 0x01 - * DUP_CCB_NEW_CALLID 0x02 - * DUP_CCB_INIT_STATE 0x04 - * DUP_CCB_REINIT_DNS 0x08 - * DUP_CCB_STOLEN_FEAT_DATA 0x10 - * if this flag is set and ccb->feature_data is NULL, then - * feature data was stolen from this ccb. - * - * if this flag is set and ccb->feature_data is non-NULL, then - * this ccb stole the feature_data pointer from the mother_ccb. - * - * The concept of duping is to maximize sharing of - * data structures by pointer sharing where it makes sense. - * The companion function of freeDupedCCB() is aware that - * of the duping. ccb->dup_flags will remember the duping - * attributes (flags shown above) and will free members - * appropriately. - * - * @param origCCB - * @param dup_flags - * - * @return duplicated CCB or NULL - */ -ccsipCCB_t * -create_dupCCB (ccsipCCB_t *origCCB, int dup_flags) -{ - ccsipCCB_t *dupCCB; - line_t child_line; - const char *fname = "dupCCB()"; - const char *outOfDialogPrefix = "OutOfDialog--"; - - dupCCB = sip_sm_get_ccb_next_available(&child_line); //need to check for failure - - if (dupCCB == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_get_ccb_next_available()" - " returned null.\n", fname); - return NULL; - } - - dupCCB->dup_flags = dup_flags|DUP_CCB; - dupCCB->mother_ccb = (void *)origCCB; - - dupCCB->flags = origCCB->flags; - sstrncpy(dupCCB->sipCallID, origCCB->sipCallID, MAX_SIP_CALL_ID); - dupCCB->gsm_id = origCCB->gsm_id; - dupCCB->con_call_id = origCCB->con_call_id; - dupCCB->blind_xfer_call_id = origCCB->blind_xfer_call_id; - - dupCCB->state = origCCB->state; - dupCCB->index = origCCB->index; - dupCCB->dn_line = origCCB->dn_line; - dupCCB->retx_counter = 0; - dupCCB->type = origCCB->type; - - dupCCB->proxySelection = origCCB->proxySelection; - dupCCB->outBoundProxyAddr = origCCB->outBoundProxyAddr; - dupCCB->outBoundProxyPort = origCCB->outBoundProxyPort; - - if (!(dup_flags & DUP_CCB_REINIT_DNS)) { - dupCCB->SRVhandle = NULL; - dupCCB->ObpSRVhandle = NULL; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Reiniting DNS fields in duped ccb", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else { - //TBD - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Not reiniting DNS fields in duped ccb", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - - dupCCB->routeMode = origCCB->routeMode; - dupCCB->udpId = origCCB->udpId; - - dupCCB->contact_info = NULL; - - if (dup_flags & DUP_CCB_NEW_CALLID) { - dupCCB->record_route_info = NULL; - dupCCB->sipCallID[0] = '\0'; - sip_util_get_new_call_id(dupCCB); - sstrncpy(dupCCB->sipCallID, outOfDialogPrefix, - sizeof(dupCCB->sipCallID)); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Using new Call-ID for OutofDialog ccb", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else { - dupCCB->record_route_info = - sippmh_copy_record_route(origCCB->record_route_info); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Copied mother CCB's route set.", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - - dupCCB->calledDisplayedName = strlib_update(dupCCB->calledDisplayedName, - origCCB->calledDisplayedName); - dupCCB->callingNumber = strlib_update(dupCCB->callingNumber, - origCCB->callingNumber); - dupCCB->callingDisplayName = strlib_update(dupCCB->callingDisplayName, - origCCB->callingDisplayName); - dupCCB->calledNumber = strlib_update(dupCCB->calledNumber, - origCCB->calledNumber); - dupCCB->calledNumberLen = origCCB->calledNumberLen; - dupCCB->calledNumberFirstDigitDialed = origCCB->calledNumberFirstDigitDialed; - - dupCCB->src_addr = origCCB->src_addr; - dupCCB->dest_sip_addr = origCCB->dest_sip_addr; - dupCCB->local_port = origCCB->local_port; - dupCCB->dest_sip_port = origCCB->dest_sip_port; - //int16_t sip_socket_handle; NOT USED ANYWHERE! - - - /* - * Headers - */ - sstrncpy(dupCCB->ReqURI, origCCB->ReqURI, sizeof(dupCCB->ReqURI)); - dupCCB->ReqURIOriginal = strlib_update(dupCCB->ReqURIOriginal, - origCCB->ReqURIOriginal); - - dupCCB->sip_to = strlib_update(dupCCB->sip_to, origCCB->sip_to); - if (dup_flags & DUP_CCB_NEW_CALLID) { - char *str, *str2; - str = strlib_open(dupCCB->sip_to, 0); - - if (str == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"strlib_open returned NULL while trying" - " to process To.", fname); - return NULL; - } - - str2 = strstr(str,";tag"); - if (str2 != NULL) { - *str2 = '\0'; - } - dupCCB->sip_to = strlib_close(str); - } - - dupCCB->sip_from = strlib_update(dupCCB->sip_from, origCCB->sip_from); - if (dup_flags & DUP_CCB_NEW_CALLID) { - char *str, *str2; - str = strlib_open(dupCCB->sip_from, 0); - - if (str == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"strlib_open returned NULL while trying" - " to process From.", fname); - return NULL; - } - - str2 = strstr(str,";tag"); - if (str2 != NULL) { - *str2 = '\0'; - } - dupCCB->sip_from = strlib_close(str); - } - - { - char tag[MAX_SIP_URL_LENGTH]; - sip_util_make_tag(tag); - - if (dupCCB->flags & INCOMING) { - dupCCB->sip_to = strlib_append(dupCCB->sip_to, ";tag="); - dupCCB->sip_to = strlib_append(dupCCB->sip_to, tag); - dupCCB->sip_to_tag = strlib_update(dupCCB->sip_to_tag, tag); - } else { - dupCCB->sip_from = strlib_append(dupCCB->sip_from, ";tag="); - dupCCB->sip_from = strlib_append(dupCCB->sip_from, tag); - dupCCB->sip_from_tag = strlib_update(dupCCB->sip_from_tag, tag); - } - } - - dupCCB->sip_contact = strlib_update(dupCCB->sip_contact, - origCCB->sip_contact); - - dupCCB->featuretype = origCCB->featuretype; - - if (dup_flags & DUP_CCB_STOLEN_FEAT_DATA) { - dupCCB->feature_data = origCCB->feature_data; - dupCCB->dup_flags |= DUP_CCB_STOLEN_FEAT_DATA; - origCCB->feature_data = NULL; - origCCB->dup_flags |= DUP_CCB_STOLEN_FEAT_DATA; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Stealing feature_data pointer from mother ccb", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - - return dupCCB; -} - -void -ccsip_handle_sent_ood_refer_ev_sip_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sent_ood_refer_ev_sip_1xx"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - ccsip_handle_sentinvite_ev_sip_1xx(ccb, event); -} - -void -ccsip_handle_sent_ood_refer_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sent_ood_refer_ev_sip_2xx"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - ccsip_handle_accept_2xx(ccb, event); - sip_sm_call_cleanup(ccb); -} - -void -ccsip_handle_sent_ood_refer_ev_sip_fxx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sent_ood_refer_ev_sip_fxx"; - sipMessage_t *response; - sipRespLine_t *respLine = NULL; - uint16_t status_code = 0; - sipMethod_t method = sipMethodInvalid; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - response = event->u.pSipMessage; - - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - //status_code = 408; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - ccsip_handle_sentinvite_ev_sip_fxx(ccb, event); - - if ((status_code != SIP_CLI_ERR_UNAUTH) && - (status_code != SIP_CLI_ERR_PROXY_REQD)) { - sip_sm_call_cleanup(ccb); - } -} - -void -ccsip_handle_ev_cc_info (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipSPISendInfo(ccb, - (const char *)event->u.cc_msg->msg.info.info_package, - (const char *)event->u.cc_msg->msg.info.content_type, - (const char *)event->u.cc_msg->msg.info.message_body); -} - -/* - * Function: ccsip_set_replace_info - * - * Parameters: - * ccb - pointer to ccsipCCB_t. - * setup - pointer to the cc_setup_t for the cc setup msg. that - * contains "replace" flag. - * - * Description: - * The ccsip_set_replace_info populates the information in the CCB - * for replace information of the INVITE to send out. The function - * may derives certain information from the remote dialog, etc. - * - * Returns: - * TRUE - when successfully set replace information. - * FALSE - when fail to set replace information. - */ -static boolean -ccsip_set_replace_info (ccsipCCB_t *ccb, cc_setup_t * setup) -{ - cc_call_info_t *call_info = &setup->call_info; - - if (call_info->type != CC_FEAT_REPLACE) { - /* The call info does not contain the replace information */ - return (FALSE); - } - - if (call_info->data.replace.remote_call_id != CC_NO_CALL_ID) { - /* This is a replacement of the remote dialog */ - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } - return (FALSE); -} - -/* - * Function: ccsip_handle_cc_select_event - * - * Parameters: - * sip_sm_event - Pointer to sipSMEvent_t - * - * Description: - * The ccsip_handle_cc_select_event checks for CC_FEATURE_SELECT and - * handled the request. - * - * Returns: - * TRUE - CC_FEATURE select has been handled. - * FALSE - CC_FEATURE select has not been handled. - */ -static boolean -ccsip_handle_cc_select_event (sipSMEvent_t *sip_sm_event) -{ - cc_feature_t *msg; - - // currently not used: line_t line_number = 0; - - msg = &(sip_sm_event->u.cc_msg->msg.feature); - if (!((msg->msg_id == CC_MSG_FEATURE) && - (msg->feature_id == CC_FEATURE_SELECT))) { - /* Some other feature or msg. */ - return (FALSE); - } - - return FALSE; -} - -/* - * Function: ccsip_handle_cc_b2bjoin_event - * - * Parameters: - * sip_sm_event - Pointer to sipSMEvent_t - * - * Description: - * The ccsip_handle_cc_b2bjoin_event checks for CC_FEATURE_B2BJOIN and - * handled the request. - * - * Returns: - * TRUE - CC_FEATURE select has been handled. - * FALSE - CC_FEATURE select has not been handled. - */ -static boolean -ccsip_handle_cc_b2bjoin_event (sipSMEvent_t *sip_sm_event) -{ - cc_feature_t *msg; - - // currently not used: line_t line_number = 0; - - msg = &(sip_sm_event->u.cc_msg->msg.feature); - if (!((msg->msg_id == CC_MSG_FEATURE) && - (msg->feature_id == CC_FEATURE_B2B_JOIN))) { - /* Some other feature or msg. */ - return (FALSE); - } - - return FALSE; -} - -/* - * Function: ccsip_set_join_info - * - * Parameters: - * ccb - pointer to ccsipCCB_t. - * setup - pointer to the cc_setup_t for the cc setup msg. - * - * Description: - * The ccsip_set_join_info populates the information in the CCB - * for join header to be sent out in the INVITE. The function - * may derives certain information from the remote dialog, etc. - * - * Returns: - * None. - */ -static void -ccsip_set_join_info (ccsipCCB_t *ccb, cc_setup_t * setup) -{ - const char *fname = "ccsip_set_join_info"; - cc_call_info_t *call_info = &setup->call_info; - - if (((call_info->type != CC_FEAT_BARGE) && - (call_info->type != CC_FEAT_CBARGE)) || - (call_info->data.join.join_call_id == CC_NO_CALL_ID)) { - /* The call info does not contain any barge information */ - return; - } - - ccb->join_info = (sipJoinInfo_t *) cpr_calloc(1, sizeof(sipJoinInfo_t)); - - if (!ccb->join_info) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, "malloc(join_info)"); - return; - } -} - -/* - * Function: ccsip_get_join_info - * - * Parameters: - * ccb - pointer to ccsipCCB_t. - * request - pointer to the sipMessage_t for the sip msg. - * - * Description: - * The ccsip_get_join_info parses the join header, finds the - * the call specified by the call id, matches the from/to tag and - * makes sure that this call is in active state. Then, it finds the - * gsm of the join target call id and populates the call info with that - * - * Returns: - * TRUE - join hdr is good. - * FALSE - join hdr is not good. - */ -static boolean -ccsip_get_join_info (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "ccsip_get_join_info"; - const char *joinhdr = NULL; - - /* Parse Join header */ - joinhdr = sippmh_get_header_val(request, SIP_HEADER_JOIN, NULL); - if (joinhdr) { - - ccsipCCB_t *join_ccb = NULL; - - // From-tag and To-tag check to match an active call - int ff_check = 0; - int ft_check = 0; - int tf_check = 0; - int tt_check = 0; - - // currently not used: boolean joinhdr_not_valid = FALSE; - - if (ccb->join_info) { - sippmh_free_join_info(ccb->join_info); - } - ccb->join_info = sippmh_parse_join_header(joinhdr); - - if (ccb->join_info) { - join_ccb = sip_sm_get_ccb_by_callid(ccb->join_info->call_id); - } - if (join_ccb == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, - "Attempted Join call does not exist"); - return (FALSE); - } - - if (!ccb->in_call_info) { - ccb->in_call_info = (cc_call_info_t *) - cpr_calloc(1, sizeof(cc_call_info_t)); - } - if (!ccb->in_call_info) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "malloc(call_info)"); - return (FALSE); - } - - ccb->in_call_info->type = CC_FEAT_MONITOR; - - if (join_ccb->state != SIP_STATE_ACTIVE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - join_ccb->index, - join_ccb->dn_line, fname, - "Attempted Join call is not active or held, but OK to continue."); - /* return (FALSE); CSCtd11077 */ - /* OK to continue to send CC_MSG_SETUP because DCSM will hold CC_FEATURE_JOIN until */ - /* DEF is in the CONNECTED state to process the JOIN msg. */ - } - - ff_check = cpr_strcasecmp(join_ccb->sip_from_tag, ccb->join_info->from_tag); - ft_check = cpr_strcasecmp(join_ccb->sip_from_tag, ccb->join_info->to_tag); - tt_check = cpr_strcasecmp(join_ccb->sip_to_tag, ccb->join_info->to_tag); - tf_check = cpr_strcasecmp(join_ccb->sip_to_tag, ccb->join_info->from_tag); - - // In this issue, the correct match is to match F/F and T/T, or to match F/T and T/F. - // All other cases are error. - // So, (ff_check==0 && tt_check==0) || (ft_check==0 && tf_check==0) is the correct match - // thus, !( (ff_check==0 && tt_check==0) || (ft_check==0 && tf_check==0) ) represents all other cases. - if ( !( (ff_check==0 && tt_check==0) || (ft_check==0 && tf_check==0) ) ) { - CCSIP_DEBUG_ERROR( - get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - join_ccb->index, - join_ccb->dn_line, fname, - "Join Header's From/To tag does not match any ccb's From/To tag"); - return (FALSE); - } - ccb->in_call_info->data.join.join_call_id = join_ccb->gsm_id; - } - return (TRUE); -} - -/** - * - * Returns SIP call ID that is pre-allocated during off hook. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the SIP call ID. - * - * @pre none - */ -char * -getPreallocatedSipCallID (line_t dn_line) -{ - static const char *fname = "getPreallocatedSipCallID"; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char pSrcAddrStr[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t src_addr; - int nat_enable = 0; - - CPR_IP_ADDR_INIT(src_addr); - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d is greater than %d or less than 1", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - - /* - * if one is already created, use it. - */ - if (preAllocatedSipCallID[dn_line - 1] != NULL) { - return (preAllocatedSipCallID[dn_line - 1]); - } - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_addr); - } else { - sip_config_get_nat_ipaddr(&src_addr); - } - - platform_get_wired_mac_address(mac_address); - ipaddr2dotted(pSrcAddrStr, &src_addr); - - preAllocatedSipCallID[dn_line - 1] = (char *) cpr_malloc(MAX_SIP_CALL_ID); - - if (preAllocatedSipCallID[dn_line - 1] != NULL) { - sip_create_new_sip_call_id(preAllocatedSipCallID[dn_line - 1], - mac_address, pSrcAddrStr); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed", fname); - } - - return (preAllocatedSipCallID[dn_line - 1]); -} - -/** - * - * Returns preallocate local SIP tag. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the tag. - * - * @pre none - */ -char * -getPreallocatedSipLocalTag (line_t dn_line) -{ - static const char *fname = "getPreallocatedSipLocalTag"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d. The valid range is 1 to %d", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - if (preAllocatedTag[dn_line - 1] == NULL) { - preAllocatedTag[dn_line - 1] = (char *) cpr_malloc(MAX_SIP_TAG_LENGTH); - if (preAllocatedTag[dn_line - 1] == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed", fname); - } else { - sip_util_make_tag(preAllocatedTag[dn_line - 1]); - } - } - - return (preAllocatedTag[dn_line - 1]); -} - -/** - * - * Returns the pre-allocated local TAG based on a given dn line number. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the tag. - * - * @pre none - */ -char * -ccsip_find_preallocated_sip_local_tag (line_t dn_line) -{ - static const char *fname = "ccsip_find_preallocated_sip_local_tag"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d. The valid range is 1 to %d", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - - return (preAllocatedTag[dn_line - 1]); -} - -/** - * - * Frees pre-allocated local tag that. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return none - * - * @pre none - */ -void -ccsip_free_preallocated_sip_local_tag (line_t dn_line) -{ - static const char *fname = "ccsip_free_preallocated_sip_local_tag"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d. The valid range is 1 to %d", - fname, dn_line, MAX_REG_LINES); - return; - } - - cpr_free(preAllocatedTag[dn_line - 1]); - preAllocatedTag[dn_line - 1] = NULL; -} - -/** - * - * Returns the SIP Call ID based on the dn line number given. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the tag. - * - * @pre none - */ -static char * -ccsip_find_preallocated_sip_call_id (line_t dn_line) -{ - static const char *fname = "ccsip_find_preallocated_sip_call_id"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d is greater than %d or less than 1", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - return (preAllocatedSipCallID[dn_line - 1]); -} - -/** - * - * Frees the SIP Call ID based on the dn line number given. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return none - * - * @pre none - */ -static void -ccsip_free_preallocated_sip_call_id (line_t dn_line) -{ - static const char *fname = "ccsip_free_preallocated_sip_call_id"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d is greater than %d or less than 1", - fname, dn_line, MAX_REG_LINES); - return; - } - cpr_free(preAllocatedSipCallID[dn_line - 1]); - preAllocatedSipCallID[dn_line - 1] = NULL; -} - -/* - * Function: ccsip_handle_cc_hook_event - * - * Parameters: - * sip_sm_event - Pointer to sipSMEvent_t - * - * Description: - * The ccsip_handle_cc_hook_event checks for - * CC_MSG_OFFHOOK/CC_MSG_ONHOOK and handles the request. - * - * Returns: - * TRUE - if it is hook event. - * FALSE - if it is not hook event. - */ -static boolean -ccsip_handle_cc_hook_event (sipSMEvent_t *sip_sm_event) -{ - static const char *fname = "ccsip_handle_cc_hook_event"; - line_t line_number = 0; - char *sip_call_id = NULL; - char *sip_local_tag; - cc_msg_t *pCCMsg; - ccsipCCB_t *ccb; - cc_msgs_t event; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Entering with event %d", DEB_F_PREFIX_ARGS(SIP_EVT, fname), - sip_sm_event->u.cc_msg->msg.setup.msg_id); - - pCCMsg = sip_sm_event->u.cc_msg; - event = pCCMsg->msg.setup.msg_id; - - if ((event != CC_MSG_OFFHOOK) && (event != CC_MSG_ONHOOK)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Exiting because event is not hook state", - DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - return FALSE; - } - - if (event == CC_MSG_OFFHOOK) { - line_number = pCCMsg->msg.offhook.line; - } else { - line_number = pCCMsg->msg.onhook.line; - } - if (sip_regmgr_get_cc_mode(line_number) != REG_MODE_CCM) { - /* this is not CCM environment */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Exiting Not CCM mode", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - return TRUE; - } - - /* - * Allocate SIP Call-ID and local tag, if they are not already allocated. - */ - if (event == CC_MSG_OFFHOOK) { - ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.offhook.call_id); - line_number = pCCMsg->msg.offhook.line; - } else { - ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.onhook.call_id); - line_number = pCCMsg->msg.onhook.line; - } - if (ccb == NULL) { - /* - * No CCB. So user must be just trying to make a call. - * We will pre allocate SIP Call-ID and local tag for the potential - * dialog initiated by INVITE. These values are needed for sending - * hook event notification. - */ - sip_call_id = getPreallocatedSipCallID(line_number); - sip_local_tag = getPreallocatedSipLocalTag(line_number); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"preallocated callid: %s & local-tag: %s", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), sip_call_id, sip_local_tag); - } else { - sip_call_id = ccb->sipCallID; - sip_local_tag = (char *) (ccb->sip_from_tag); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"callid: %s & local-tag: %s", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), sip_call_id, sip_local_tag); - } - - /* - * if CCB is NULL and we are sending ONKOOK notification, - * free up the preallocated call-id and local-tag. - */ - if ((ccb == NULL) && (event == CC_MSG_ONHOOK)) { - ccsip_free_preallocated_sip_call_id(line_number); - ccsip_free_preallocated_sip_local_tag(line_number); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Exiting after sending hook state " - "notification\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - return TRUE; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_debug.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_debug.c deleted file mode 100644 index e4fc332af3c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_debug.c +++ /dev/null @@ -1,391 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "debug.h" -#include "phone_debug.h" -#include "ccsip_publish.h" -#include "util_string.h" -#include "sip_interface_regmgr.h" - -extern boolean dump_reg_msg; - -/* SIP flags */ -cc_int32_t SipDebugMessage = 1; /* SIP messaging output */ -cc_int32_t SipDebugState = 0; /* SIP State Machine output */ -cc_int32_t SipDebugTask = 1; /* SIP Task output */ -cc_int32_t SipDebugRegState = 0; /* SIP Registration State Mach. output */ - -/** - * SipRelDevEnabled flag is not a debug print flag. It actually turns - * on and off reliable delivery module in sip layer. We will keep - * this on as retransmissions are enabled on CUCM by default even for TCP transport - */ -int32_t SipRelDevEnabled = 1; /* Is reliable delivery on? */ - -int32_t SipDebugGenContactHeader = 0; /* Generate Contact header */ -cc_int32_t SipDebugTrx = 0; /* SIP Transaction Layer output */ - -cc_int32_t GSMDebug = 0; -cc_int32_t FIMDebug = 0; -cc_int32_t LSMDebug = 0; -cc_int32_t FSMDebugSM = 0; -int32_t CSMDebugSM = 0; -cc_int32_t CCDebug = 0; -cc_int32_t CCDebugMsg = 0; -cc_int32_t AuthDebug = 0; -cc_int32_t g_DEFDebug = 1; -cc_int32_t TNPDebug = 1; -cc_int32_t VCMDebug = 0; -cc_int32_t CCEVENTDebug = 0; -cc_int32_t PLATDebug = 0; -cc_int32_t TMRDebug = 0; -cc_int32_t g_dcsmDebug = 0; - -/** - * - * Dump sip messages - * - * @param msg - message buffer - * pSIPMessage - parsed message structure - * cc_remote_ipaddr - remote ip address - * cc_remote_port - remote port number - * - * @return none - * - * @pre (valid pSIPMessage AND - * valid cc_remote_ipaddr) - */ - -void ccsip_dump_send_msg_info (char *msg, sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port) -{ - char *disp_buf; - const char *req_uri; - const char *cseq; - const char *callid; - char ipaddr_str[MAX_IPADDR_STR_LEN]; - static const char fname[] = "ccsip_dump_send_msg_info"; - - ipaddr2dotted(ipaddr_str, cc_remote_ipaddr); - - req_uri = sippmh_get_header_val(pSIPMessage, SIP_HEADER_TO, NULL); - if (req_uri == NULL) { - /* No REQ URI, fill with blank */ - req_uri = ""; - } - cseq = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CSEQ, NULL); - if (cseq == NULL) { - /* No REQ CSEQ, fill with blank */ - cseq = ""; - } - callid = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CALLID, NULL); - if (callid == NULL) { - /* No REQ CSEQ, fill with blank */ - callid = ""; - } - - /* For messages starting with SIP add 8 byte. default - * debugs do not show all the SIP message information - * rather show initial msg. - */ - if (msg != NULL) { - if (msg[0] == 'S' && - msg[1] == 'I' && - msg[2] == 'P') { - disp_buf = &msg[8]; - } else { - disp_buf = msg; - } - if ((strncmp(disp_buf, SIP_METHOD_REGISTER, sizeof(SIP_METHOD_REGISTER)-1) == 0) && - (!dump_reg_msg)) { - return; - } - } else { - /* No msg. buffer */ - disp_buf = NULL; - } - - - if (disp_buf != NULL) { - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), - ipaddr_str, cc_remote_port, - disp_buf[0], - disp_buf[1], - disp_buf[2], - disp_buf[3], - disp_buf[4], - disp_buf[5], - disp_buf[6], - req_uri, - cseq, callid); - } else { - /* No msg to send */ - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), - ipaddr_str, cc_remote_port); - } -} - -/** - * - * Dump sip messages - * - * @param msg - message buffer - * pSIPMessage - parsed message structure - * cc_remote_ipaddr - remote ip address - * cc_remote_port - remote port number - * - * @return none - * - * @pre (valid pSIPMessage AND - * valid cc_remote_ipaddr) - */ - -void ccsip_dump_recv_msg_info (sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port) -{ - char *disp_buf; - const char *req_uri; - const char *cseq; - const char *callid; - char ipaddr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t cc_ipaddr; - static const char fname[] = "ccsip_dump_recv_msg_info"; - - util_ntohl(&cc_ipaddr, cc_remote_ipaddr); - ipaddr2dotted(ipaddr_str, &cc_ipaddr); - - req_uri = sippmh_get_cached_header_val(pSIPMessage, FROM); - if (req_uri == NULL) { - /* No REQ URI, fill with blank */ - req_uri = ""; - } - cseq = sippmh_get_cached_header_val(pSIPMessage, CSEQ); - if (cseq == NULL) { - /* No REQ CSEQ, fill with blank */ - cseq = ""; - } - callid = sippmh_get_cached_header_val(pSIPMessage, CALLID); - if (callid == NULL) { - /* No REQ CSEQ, fill with blank */ - callid = ""; - } - - if (!dump_reg_msg) { - if (strstr(cseq, SIP_METHOD_REGISTER) != NULL) { - return; - } - } - - /* For messages starting with SIP add 8 byte. default - * debugs do not show all the SIP message information - * rather show initial msg. - */ - if (pSIPMessage->mesg_line != NULL) { - if (pSIPMessage->mesg_line[0] == 'S' && - pSIPMessage->mesg_line[1] == 'I' && - pSIPMessage->mesg_line[2] == 'P') { - disp_buf = &(pSIPMessage->mesg_line[8]); - } else { - disp_buf = pSIPMessage->mesg_line; - } - } else { - /* - * It is possible that this function is called with - * invalid message or partially received. - */ - disp_buf = NULL; - } - - if (disp_buf != NULL) { - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), - ipaddr_str, cc_remote_port, - disp_buf[0], - disp_buf[1], - disp_buf[2], - disp_buf[3], - disp_buf[4], - disp_buf[5], - disp_buf[6], - req_uri, - cseq, callid); - } else { - /* No line received */ - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), - ipaddr_str, cc_remote_port); - } -} - -/** - * - * platform_print_sip_msg - * - * The function perform printing SIP msg. - * - * Parameters: msg - pointer to character strings of the SIP messages. - * - * Return Value: None - * - */ -void -platform_print_sip_msg (const char *msg) -{ - char *buf; - int msg_to_crypto_line_len, msg_to_digits_tag_len, buf_len; - const char *c_line_begin, *c_line_end; - static const char crypto_line_tag[] = "a=crypto:"; - static const char crypto_mask[] = "..."; - static const char digits_tag[] = "digits="; - - if (msg == NULL) { - return; - } - - /* replace digits for security reasons */ - if (strstr(msg, "kpml-response")) { - /* This is kpml response. so supress printing digits. */ - c_line_begin = strstr(msg, digits_tag); - if (c_line_begin == NULL) { - /* No digits, print everything */ - CSFLogDebug("sipstack", "%s", msg); - return; - } - /* - * Calculate the length of the msg. to print from - * from the beginning to the end of the "digits=" i.e. - */ - msg_to_digits_tag_len = c_line_begin - msg + sizeof(digits_tag); - buf_len = msg_to_digits_tag_len + sizeof(crypto_mask); - buf = (char *) cpr_malloc(buf_len); - if (buf == NULL) { - /* No memory */ - return; - } - - /* Copy the message upto "digits=" */ - memcpy(buf, msg, msg_to_digits_tag_len); - - /* Copy mask and the end NULL terminating char to the buffer */ - memcpy(&buf[msg_to_digits_tag_len], crypto_mask, sizeof(crypto_mask)); - /* Print it out now */ - CSFLogDebug("sipstack", "%s", buf); - cpr_free(buf); - - c_line_end = c_line_begin + sizeof(digits_tag) + 3; /* 3 beacuse " + digit + " */ - msg = c_line_end; - CSFLogDebug("sipstack", "%s", msg); - } else if (sip_regmgr_get_sec_level(1) == ENCRYPTED) { - /* The 1st. line is using encrypted signaling */ - while (TRUE) { - c_line_begin = strstr(msg, crypto_line_tag); - if (c_line_begin == NULL) { - /* No more crypto line, print whatever left and done */ - CSFLogDebug("sipstack", "%s", msg); - return; - } else { - /* - * Found a crypto line: - * - * Allocate buffer to print the msg. including this - * instance of crypto line but no crypto parameter. - * For example: - * - * v=0 - * o=Cisco-SIPUA 3052 7 IN IP4 10.80.35.217 - * s=SIP Call - * t=0 0 - * m=audio 28926 RTP/SAVP 0 8 18 101 - * c=IN IP4 10.80.35.217 - * a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:GqT... - * a=rtpmap:0 PCMU/8000 - * - * - * The output of printing will be - * - * v=0 - * o=Cisco-SIPUA 3052 7 IN IP4 10.80.35.217 - * s=SIP Call - * t=0 0 - * m=audio 28926 RTP/SAVP 0 8 18 101 - * c=IN IP4 10.80.35.217 - * a=crypto:1... - * a=rtpmap:0 PCMU/8000 - * - */ - - /* - * Calculate the length of the msg. to print from - * current position to the end of the "a=crypto:n" i.e. - * from the current of msg passes the ":" by one character - * after of the "a=crypto:". This allows the first character - * of the crypto tag field character to be included in the - * output. Note that there is no explicit adding this - * extra character in the code below because of the - * sizeof(crypto_line_tag) includes extra 1 byte of string - * termination character already. It will be the extra - * character to print after the ":". - */ - msg_to_crypto_line_len = c_line_begin - msg + - sizeof(crypto_line_tag); - /* - * The buffer allocated to print includes the length from - * current msg pointer to this instance of crypto line + - * the mask length plus 1 byte for NULL terminating character. - * The NULL terminating character is included in the - * sizeof(crypto_mask) below. - */ - buf_len = msg_to_crypto_line_len + sizeof(crypto_mask); - buf = (char *) cpr_malloc(buf_len); - if (buf == NULL) { - /* No memory */ - return; - } - - /* Copy the message including this instance of crypto line */ - memcpy(buf, msg, msg_to_crypto_line_len); - - /* Copy mask and the end NULL terminating char to the buffer */ - memcpy(&buf[msg_to_crypto_line_len], crypto_mask, - sizeof(crypto_mask)); - /* Print it out now */ - CSFLogDebug("sipstack", "%s", buf); - cpr_free(buf); - - /* Find the end of the crypto line */ - c_line_end = strpbrk(c_line_begin, "\n"); - if (c_line_end != NULL) { - /* Skip pass the "\n" character of the crypto line */ - msg = c_line_end + 1; - } else { - /* Some thing is wrong, no end line character in SDP */ - return; - } - } - } - } else { - /* print full content */ - CSFLogDebug("sipstack", "%s", msg); - } -} - -/* - * Function: ccsip_debug_init() - * - * Parameters: None - * - * Description: Initialize the Debug keywords used by the SIP protocol stack. - * - * Returns: None - * - */ -void -ccsip_debug_init (void) -{ - /* Placeholder for doing any initialization related tasks */ -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_info.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_info.c deleted file mode 100644 index 7d8dd1b0059..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_info.c +++ /dev/null @@ -1,898 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" - -#include "ccsip_core.h" -#include "ccsip_callinfo.h" -#include "ccsip_messaging.h" -#include "uiapi.h" -#include "lsm.h" -#include "fsm.h" -#include "vcm.h" -#include "phone_debug.h" -#include "singly_link_list.h" -#include "ccapi.h" - -extern int httpish_strncasecmp(const char *s1, const char *s2, size_t len); - -typedef unsigned int info_index_t; -typedef unsigned int type_index_t; - -typedef struct { - info_package_handler_t handler; - info_index_t info_index; // the index of the info_package in g_registered_info array - // i.e., the value returned by find_info_index() - type_index_t type_index; // the index of the content_type in g_registered_type array - // i.e., the value returned by find_type_index() -} handler_record_t; - -/* Info Package handler registry */ -static sll_handle_t s_handler_registry = NULL; - -#define INDEX_NOT_FOUND ((unsigned int)-1) - -/* - * g_registered_info[] contains the Info Package strings (such as - * "conference") for the registered handlers. - */ -char *g_registered_info[MAX_INFO_HANDLER]; - -static char *s_registered_type[MAX_INFO_HANDLER]; - -static sll_match_e is_matching_type(void *find_by_p, void *data_p); -static info_index_t find_info_index(const char *info_package); -static info_index_t find_next_available_info_index(void); -static type_index_t find_type_index(const char *type_package); -static type_index_t find_next_available_type_index(void); -static handler_record_t *find_handler_record(info_index_t info_index, - type_index_t type_index); -static boolean is_info_package_registered(info_index_t info_index); -static boolean is_content_type_registered(type_index_t type_index); -static void update_recv_info_list(const char *header_field_value, - string_t *info_packages); -static void media_control_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body); -#ifdef _CONF_ROSTER_ -static void conf_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body); -#endif - - - -/* - * Function: find_info_index - * - * Parameters: - * info_package - the Info Package to find - * - * Description: - * Finds the Info Package in g_registered_info array. - * - * Return: - * info_index_t - the index of the Info Package in the array - * INDEX_NOT_FOUND - the Info Package was not found in the array - */ -static info_index_t -find_info_index(const char *info_package) -{ - info_index_t info_index; - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] && - httpish_strncasecmp(info_package, - g_registered_info[info_index], - strlen(g_registered_info[info_index])) == 0) { - return info_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: find_next_available_info_index - * - * Parameters: - * None - * - * Description: - * Finds an empty slot in g_registered_info array. - * - * Return: - * info_index_t - the index of the empty slot in the array - * INDEX_NOT_FOUND - the array is full - */ -static info_index_t -find_next_available_info_index(void) -{ - info_index_t info_index; - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] == NULL) { - return info_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: find_type_index - * - * Parameters: - * content_type - the Content Type to find - * - * Description: - * Finds the Content Type in s_registered_type array. - * - * Return: - * type_index_t - the index of the Content Type in the array - * INDEX_NOT_FOUND - the Content Type was not found in the array - */ -static type_index_t -find_type_index(const char *content_type) -{ - type_index_t type_index; - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - if (s_registered_type[type_index] && - httpish_strncasecmp(content_type, - s_registered_type[type_index], - strlen(s_registered_type[type_index])) == 0) { - return type_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: find_next_available_type_index - * - * Parameters: - * None - * - * Description: - * Finds an empty slot in s_registered_type array. - * - * Return: - * type_index_t - the index of the empty slot in the array - * INDEX_NOT_FOUND - the array is full - */ -static type_index_t -find_next_available_type_index(void) -{ - type_index_t type_index; - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - if (s_registered_type[type_index] == NULL) { - return type_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: is_matching_type - * - * Parameters: - * find_by_p - searching criteria - * data_p - a node - * - * Description: - * Checks to see if the node matches the searching criteria. - * - * Return: - * SLL_MATCH_FOUND - the node is a match - * SLL_MATCH_NOT_FOUND - the node is not a match - */ -static sll_match_e -is_matching_type(void *find_by_p, void *data_p) -{ - handler_record_t *tuple = (handler_record_t *)find_by_p; - handler_record_t *node = (handler_record_t *)data_p; - - if ((node->info_index == tuple->info_index) && - (node->type_index == tuple->type_index)) { - return SLL_MATCH_FOUND; - } - return SLL_MATCH_NOT_FOUND; -} - -/* - * Function: find_handler_record - * - * Parameters: - * info_index - the index of the Info Package in g_registered_info array - * type_index - the index of the Content Type in s_registered_type array - * - * Description: - * Finds the Info Package handler registered for the Info Package/Content - * Type pair. - * - * Return: - * handler_record_t * - the registered handler record - * NULL - otherwise - */ -static handler_record_t * -find_handler_record(info_index_t info_index, type_index_t type_index) -{ - handler_record_t tuple; - - tuple.info_index = info_index; - tuple.type_index = type_index; - - return (handler_record_t *)sll_find(s_handler_registry, &tuple); -} - -/* - * Function: is_info_package_registered - * - * Parameters: - * info_index - the index of the Info Package in g_registered_info array - * - * Description: - * Checks to see if a handler was registered for the Info Package. - * - * Return: - * TRUE - a handler was registered for the Info Package - * FALSE - otherwise - */ -static boolean -is_info_package_registered(info_index_t info_index) -{ - handler_record_t *record; - - for (record = (handler_record_t *)sll_next(s_handler_registry, NULL); - record != NULL; - record = (handler_record_t *)sll_next(s_handler_registry, record)) { - if (record->info_index == info_index) { - return TRUE; - } - } - - return FALSE; -} - -/* - * Function: is_content_type_registered - * - * Parameters: - * type_index - the index of the Content Type in s_registered_type array - * - * Description: - * Checks to see if a handler was registered for the Content Type. - * - * Return: - * TRUE - a handler was registered for the Content Type - * FALSE - otherwise - */ -static boolean -is_content_type_registered(type_index_t type_index) -{ - handler_record_t *record; - - for (record = (handler_record_t *)sll_next(s_handler_registry, NULL); - record != NULL; - record = (handler_record_t *)sll_next(s_handler_registry, record)) { - if (record->type_index == type_index) { - return TRUE; - } - } - - return FALSE; -} - -/* - * Function: ccsip_register_info_package_handler - * - * Parameters: - * info_package - the Info Package for the handler - * content_type - the Content Type for the handler - * handler - the handler - * - * Description: - * Registers the handler for the Info Package/Content Type pair. - * - * Return: - * SIP_OK - the handler was registered successfully - * SIP_ERROR - otherwise - */ -int -ccsip_register_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler) -{ - static const char *fname = "ccsip_register_info_package_handler"; - info_index_t info_index; - type_index_t type_index; - char *tmp_info = NULL; - char *tmp_type = NULL; - handler_record_t *record; - - if (s_handler_registry == NULL) { - CCSIP_DEBUG_TASK("%s: Info Package handler was not initialized", fname); - return SIP_ERROR; - } - - if ((info_package == NULL) || (content_type == NULL) || (handler == NULL)) { - CCSIP_DEBUG_ERROR("%s: invalid parameter", fname); - return SIP_ERROR; - } - - /* Find the info_index for the info_package */ - info_index = find_info_index(info_package); - - if (info_index == INDEX_NOT_FOUND) { - /* Find the first available slot */ - info_index = find_next_available_info_index(); - - if (info_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: maximum reached", fname); - return SIP_ERROR; - } - - tmp_info = cpr_strdup(info_package); - if (tmp_info == NULL) { - CCSIP_DEBUG_ERROR("%s: failed to duplicate info_package string", fname); - return SIP_ERROR; - } - } - - /* Find the type_index for the content_type */ - type_index = find_type_index(content_type); - - if (type_index == INDEX_NOT_FOUND) { - /* Find the first available slot */ - type_index = find_next_available_type_index(); - - if (type_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: maximum reached", fname); - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - return SIP_ERROR; - } - - tmp_type = cpr_strdup(content_type); - if (tmp_type == NULL) { - CCSIP_DEBUG_ERROR("%s: failed to duplicate info_package string", fname); - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - return SIP_ERROR; - } - } - - /* Check to see if the info/type tuple has been registered before */ - if (find_handler_record(info_index, type_index) != NULL) { - CCSIP_DEBUG_ERROR("%s: Info Package handler already registered", fname); - return SIP_ERROR; - } - - /* - * At this point, info_index points to the slot in g_registered_info where - * either: - * - * 1) the info_package is residing, or - * 2) the info_package (a copy of which is pointed to by *tmp_info) will be - * copied to before the function returns - * - * type_index is similar. - */ - - record = (handler_record_t *)cpr_malloc(sizeof(handler_record_t)); - if (record == NULL) { - if (tmp_type != NULL) { - cpr_free(tmp_type); - } - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - CCSIP_DEBUG_ERROR("%s: failed to allocate info handler record", fname); - return SIP_ERROR; - } - - record->handler = handler; - record->info_index = info_index; - record->type_index = type_index; - - if (sll_append(s_handler_registry, record) != SLL_RET_SUCCESS) { - cpr_free(record); - if (tmp_type != NULL) { - cpr_free(tmp_type); - } - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - CCSIP_DEBUG_ERROR("%s: failed to insert to the registry", fname); - return SIP_ERROR; - } - - if (tmp_info != NULL) { - g_registered_info[info_index] = tmp_info; - } - if (tmp_type != NULL) { - s_registered_type[type_index] = tmp_type; - } - - return SIP_OK; -} - -/* - * Function: ccsip_deregister_info_package_handler - * - * Parameters: - * info_package - the Info Package for the handler - * content_type - the Content Type for the handler - * handler - the handler - * - * Description: - * Deregisters the handler for the Info Package/Content Type pair. - * - * Return: - * SIP_OK - the handler was registered successfully - * SIP_ERROR - otherwise - */ -int -ccsip_deregister_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler) -{ - static const char *fname = "ccsip_deregister_info_package_handler"; - info_index_t info_index; - type_index_t type_index; - handler_record_t *record; - - if (s_handler_registry == NULL) { - CCSIP_DEBUG_TASK("%s: Info Package handler was not initialized", fname); - return SIP_ERROR; - } - - /* Find the info_index for the info_package */ - info_index = find_info_index(info_package); - if (info_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: handler was not registered (%s)", - fname, info_package); - return SIP_ERROR; - } - - /* Find the type_index for the content_type */ - type_index = find_type_index(content_type); - if (type_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: handler was not registered (%s)", - fname, content_type); - return SIP_ERROR; - } - - /* Find the handler record */ - record = find_handler_record(info_index, type_index); - if ((record == NULL) || (record->handler != handler)) { - CCSIP_DEBUG_ERROR("%s: handler was not registered (%p)", - fname, handler); - return SIP_ERROR; - } - - (void)sll_remove(s_handler_registry, record); - - cpr_free(record); - - if (!is_info_package_registered(info_index)) { - /* The info_package was not found in the registry, meaning we're - * the last one who registered for this particular info_package */ - cpr_free(g_registered_info[info_index]); - g_registered_info[info_index] = NULL; - } - - if (!is_content_type_registered(type_index)) { - /* The content_type was not found in the registry, meaning we're - * the last one who registered for this particular content_type */ - cpr_free(s_registered_type[type_index]); - s_registered_type[type_index] = NULL; - } - - return SIP_OK; -} - -/* - * Function: update_recv_info_list - * - * Parameters: - * header_field_value - the header field value to match (e.g., - * "conference") - * info_packages - the Info Packages string to append the header - * field value to - * - * Description: - * Checks to see if a handler is registered for the header field value - * (e.g., "conference"), if so, append the header field value to - * the end of info_packages. - * - * Returns: - * None - */ -static void -update_recv_info_list(const char *header_field_value, string_t *info_packages) -{ - static const char *fname = "update_recv_info_list"; - info_index_t info_index; - - if ((header_field_value == NULL) || (info_packages == NULL) || - (*info_packages == NULL)) { - CCSIP_DEBUG_ERROR("%s: invalid parameter", fname); - return; - } - - info_index = find_info_index(header_field_value); - if (info_index != INDEX_NOT_FOUND) { - /* Info-Package is supported */ - if (**info_packages == '\0') { - *info_packages = strlib_update(*info_packages, - g_registered_info[info_index]); - } else { - *info_packages = strlib_append(*info_packages, ", "); - *info_packages = strlib_append(*info_packages, - g_registered_info[info_index]); - } - } -} - -/* - * Function: ccsip_parse_send_info_header - * - * Parameters: - * ccb - the SIP CCB - * pSipMessage - the SIP message - * - * Description: - * Checks the Send-Info header (if exists) to see if a handler was - * registered for the Info Package. If so, append the Info Package - * to the end of recv_info_list. - * - * Returns: - * None - */ -void -ccsip_parse_send_info_header(sipMessage_t *pSipMessage, string_t *recv_info_list) -{ - char *send_info[MAX_INFO_HANDLER]; - int count; - int i; - char *header_field_values; - char *header_field_value; - char *separator; - - // leading white spaces are trimmed, but not trailing ones - count = sippmh_get_num_particular_headers(pSipMessage, - SIP_HEADER_SEND_INFO, - NULL, - send_info, - MAX_INFO_HANDLER); - - if (count == 0) { - return; - } - - for (i = 0; (i < count) && (i < MAX_INFO_HANDLER); i++) { - header_field_values = cpr_strdup(send_info[i]); - if (header_field_values == NULL) { - return; - } - header_field_value = header_field_values; - - while ((separator = strchr(header_field_value, COMMA)) != NULL) { - *separator++ = '\0'; - update_recv_info_list(header_field_value, recv_info_list); - header_field_value = separator; - SKIP_WHITE_SPACE(header_field_value); - } - update_recv_info_list(header_field_value, recv_info_list); - - cpr_free(header_field_values); - } -} - -/* - * Function: ccsip_handle_info_package - * - * Parameters: - * ccb - the SIP CCB - * pSipMessage - the SIP message - * - * Description: - * Handles an incoming unsolicited Info Package message. - * XXX Currently this function only handles the first part in a - * multi-part Info Package message. - * - * Return: - * SIP_OK - if request processed. - * SIP_ERROR - if there is error - */ -int -ccsip_handle_info_package(ccsipCCB_t *ccb, sipMessage_t *pSipMessage) -{ - static const char *fname = "ccsip_handle_info_package"; - const char *info_package; - const char *content_type; - info_index_t info_index; - type_index_t type_index; - handler_record_t *record; - uint16_t status_code; - const char *reason_phrase; - int return_code = SIP_ERROR; - - /* FIXME Media Control currently does not follow the IETF draft - draft-ietf-sip-info-events-01, so short-circuit here and - bypass all the Info Package related stuff below. */ - // leading white spaces are trimmed, but not trailing ones - content_type = sippmh_get_cached_header_val(pSipMessage, - CONTENT_TYPE); - if (content_type && - httpish_strncasecmp(content_type, - SIP_CONTENT_TYPE_MEDIA_CONTROL, - strlen(SIP_CONTENT_TYPE_MEDIA_CONTROL)) == 0) { - - media_control_info_package_handler(ccb->dn_line, ccb->gsm_id, - "", // legacy mode, no Info Package - SIP_CONTENT_TYPE_MEDIA_CONTROL, - pSipMessage->mesg_body[0].msgBody); - - if (sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP_PHRASE); - return SIP_ERROR; - } - - return SIP_OK; - } - - /* - * Parse the Info-Package header - */ - // leading white spaces are trimmed, but not trailing ones - info_package = sippmh_get_header_val(pSipMessage, - SIP_HEADER_INFO_PACKAGE, - NULL); - - if (info_package == NULL) { - /* No Info-Package header */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing Info-Package header", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - - if (pSipMessage->num_body_parts == 0) { - /* No Info-Package header, and no body poarts */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing message body", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - /* Send 200 OK for legacy UA support */ - status_code = 200; - reason_phrase = SIP_SUCCESS_SETUP_PHRASE; - return_code = SIP_OK; - } else { - /* No Info-Package header, but with body part(s) */ - if (pSipMessage->num_body_parts > 1) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Multipart Info Package", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - } - - type_index = find_type_index(pSipMessage->mesg_body[0].msgContentType); - if (type_index == INDEX_NOT_FOUND) { - /* No Info-Package header, and Content-Type is not supported */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Content Type", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - /* Send 415 Unsupported Media Type */ - status_code = SIP_CLI_ERR_MEDIA; - reason_phrase = SIP_CLI_ERR_MEDIA_PHRASE; - } else { - /* No Info-Package header, but Conent-Type is supported */ - /* Send 200 OK for legacy UA support */ - status_code = 200; - reason_phrase = SIP_SUCCESS_SETUP_PHRASE; - return_code = SIP_OK; - } - } - } else { - /* With Info-Package header */ - if (pSipMessage->num_body_parts == 0) { - /* With Info-Package header, but no body parts */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing message body", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - - /* ? */ - /* Send 489 Bad Event */ - status_code = SIP_CLI_ERR_BAD_EVENT; - reason_phrase = SIP_CLI_ERR_BAD_EVENT_PHRASE; - - } else { - /* With Info-Package header and body part(s) */ - if (pSipMessage->num_body_parts > 1) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Multipart Info Package " - "(only the first part is processed)\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - } - - info_index = find_info_index(info_package); - if (info_index == INDEX_NOT_FOUND) { - /* Info-Package is not supported */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Info Package", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - - /* Send 489 Bad Event */ - status_code = SIP_CLI_ERR_BAD_EVENT; - reason_phrase = SIP_CLI_ERR_BAD_EVENT_PHRASE; - - } else { - /* Info-Package is supported */ - type_index = find_type_index(pSipMessage->mesg_body[0].msgContentType); - record = find_handler_record(info_index, type_index); - if (record == NULL) { - /* Info-Package header is supported, but Content-Type is not */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Content Type", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - /* Send 415 Unsupported Media Type */ - status_code = SIP_CLI_ERR_MEDIA; - reason_phrase = SIP_CLI_ERR_MEDIA_PHRASE; - } else { - /* a handler is registered */ - (*record->handler)(ccb->dn_line, ccb->gsm_id, - g_registered_info[record->info_index], - s_registered_type[record->type_index], - pSipMessage->mesg_body[0].msgBody); - /* Send 200 OK */ - status_code = 200; - reason_phrase = SIP_SUCCESS_SETUP_PHRASE; - return_code = SIP_OK; - } - } - } - } - - if (sipSPISendErrorResponse(pSipMessage, status_code, reason_phrase, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, reason_phrase); - return SIP_ERROR; - } - - return return_code; -} - -static void -media_control_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body) -{ -} - -#ifdef _CONF_ROSTER_ -static void -conf_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body) -{ - static const char *fname = "conf_info_package_handler"; - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"info_package: %s content_type: %s", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname), - info_package, content_type); - - ui_info_received(line, lsm_get_ui_id(call_id), info_package, content_type, - message_body); -} -#endif - -/* - * Function: ccsip_info_package_handler_init - * - * Parameters: - * None - * - * Description: - * Initializes the Info Package handler framework. - * - * Return: - * SIP_OK - Info Package handler framework initialized successfully - * SIP_ERROR - otherwise - */ -int -ccsip_info_package_handler_init(void) -{ - static const char *fname = "ccsip_info_package_handler_init"; - info_index_t info_index; - type_index_t type_index; - - if (s_handler_registry != NULL) { - // Is this considered an error? - CCSIP_DEBUG_TASK("%s: Info Package handler already initialized", fname); - return SIP_OK; - } - - /* Create the SLL */ - s_handler_registry = sll_create(is_matching_type); - if (s_handler_registry == NULL) { - CCSIP_DEBUG_ERROR("%s: failed to create the registry", fname); - return SIP_ERROR; - } - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - g_registered_info[info_index] = NULL; - } - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - s_registered_type[type_index] = NULL; - } - - // XXX Where is the best place to register the application-specific handler? -#ifdef _CONF_ROSTER_ - /* Register the handler for conference & x-cisco-conference Info Packages */ - ccsip_register_info_package_handler(INFO_PACKAGE_CONFERENCE, - CONTENT_TYPE_CONFERENCE_INFO, - conf_info_package_handler); - ccsip_register_info_package_handler(INFO_PACKAGE_CISCO_CONFERENCE, - CONTENT_TYPE_CONFERENCE_INFO, - conf_info_package_handler); -#endif - return SIP_OK; -} - -/* - * Function: ccsip_info_package_handler_shutdown - * - * Parameters: - * None - * - * Description: - * Shuts down the Info Package handler framework. - * - * Return: - * None - */ -void -ccsip_info_package_handler_shutdown(void) -{ - static const char *fname = "ccsip_info_package_handler_shutdown"; - info_index_t info_index; - type_index_t type_index; - handler_record_t *record; - - if (s_handler_registry == NULL) { - // Is this considered an error? - CCSIP_DEBUG_TASK("%s: Info Package handler was not initialized", fname); - return; - } - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - if (s_registered_type[type_index] != NULL) { - cpr_free(s_registered_type[type_index]); - s_registered_type[type_index] = NULL; - } - } - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] != NULL) { - cpr_free(g_registered_info[info_index]); - g_registered_info[info_index] = NULL; - } - } - - /* Deregister each Info Package handler */ - for (record = (handler_record_t *)sll_next(s_handler_registry, NULL); - record != NULL; - record = (handler_record_t *)sll_next(s_handler_registry, record)) { - cpr_free(record); - } - - /* Destroy the SLL */ - sll_destroy(s_handler_registry); - s_handler_registry = NULL; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_messaging.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_messaging.c deleted file mode 100644 index 3f158cb86f8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_messaging.c +++ /dev/null @@ -1,7640 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_time.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "phntask.h" -#include "text_strings.h" -#include "util_string.h" -#include "ccsip_core.h" -#include "ccsip_macros.h" -#include "ccsip_messaging.h" -#include "ccsip_platform.h" -#include "ccsip_task.h" -#include "prot_configmgr.h" -#include "phone_debug.h" -#include "ccsip_reldev.h" -#include "digcalc.h" -#include "ccsip_register.h" -#include "ccsip_credentials.h" -#include "dns_utils.h" -#include "config.h" -#include "string_lib.h" -#include "dialplan.h" -#include "rtp_defs.h" -#include "ccapi.h" -#include "ccsip_platform_udp.h" -#include "ccsip_task.h" -#include "sdp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "uiapi.h" -#include "ccsip_callinfo.h" -#include "sip_interface_regmgr.h" -#include "ccsip_spi_utils.h" -#include "ccsip_subsmanager.h" -#include "subapi.h" -#include "platform_api.h" - -#define SIPS_URL_LEN 8 -#define NONCE_LEN 9 -#define SUBS_STATE_HDR_LEN 80 -#define MAX_EXPIRES_LEN 12 -#define MAX_ESCAPED_USER_LEN 94 // Worst case all 31 chars require escaping (3 chars) + a NULL -#define MAX_PHONE_NAME_LEN 20 -#define MAX_UNREG_REASON_STR_LEN 256 - -#define MAX_ESCAPED_USER_LEN 94 // Worst case all 31 chars require escaping (3 chars) + a NULL -#define INITIAL_BUFFER_SIZE 2048 - - -/* External declarations */ -extern int dns_error_code; // DNS error code global -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern sipCallHistory_t gCallHistory[]; -extern ccsipGlobInfo_t gGlobInfo; -extern int16_t clockIsSetup; -extern struct tm *gmtime_r(const time_t *, struct tm *); -extern char *Basic_is_phone_forwarded(line_t line); -extern uint16_t server_caps; -extern char sipPhoneModelNumber[]; -extern char phone_load_name[]; -extern sipGlobal_t sip; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; - -/* Forward declarations */ -boolean sipSPIAddRequestRecordRoute(sipMessage_t *, sipMessage_t *); -static boolean sendResponse(ccsipCCB_t *ccb, sipMessage_t *response, - sipMessage_t *refrequest, boolean retx, - sipMethod_t method); -static sipRet_t CopyLocalSDPintoResponse(sipMessage_t *request, - cc_msgbody_info_t *local_msg_body); - -#if defined SIP_OS_WINDOWS -#define debugif_printf printf -#endif -/* - * Functions to manipulate transaction blocks - */ - -/* - * This function gets the index of the last request sent or received - * It determines this by choosing the last one that has a - * non CCSIP_START_CSEQ cseq value - */ -int16_t -get_last_request_trx_index (ccsipCCB_t *ccb, boolean sent) -{ - const char *fname = "get_last_request_trx_index"; - int16_t i; - - if (ccb == NULL) { - return -1; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Getting last TRX index, sent = %d", DEB_F_PREFIX_ARGS(SIP_TRX, fname), sent); - - if (sent) { - for (i = MAX_REQ_OUTSTANDING - 1; i >= 0; i--) { - if (ccb->sent_request[i].cseq_number != CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for sent req", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } else { - for (i = MAX_REQ_OUTSTANDING - 1; i >= 0; i--) { - if (ccb->recv_request[i].cseq_number != CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for recv req", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } - return -1; -} - -/* - * This function gets the next cseq index that can be used to send - * a request. It determines this by choosing the next available - * cseq index - */ -int16_t -get_next_request_trx_index (ccsipCCB_t *ccb, boolean sent) -{ - const char *fname = "get_next_request_trx_index"; - int16_t i; - - if (ccb == NULL) { - return -1; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Getting next TRX index, sent = %d", DEB_F_PREFIX_ARGS(SIP_TRX, fname), sent); - if (sent) { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->sent_request[i].cseq_number == CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for sent req", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } else { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->recv_request[i].cseq_number == CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for recv req", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Unable to get any open TRX!!", DEB_F_PREFIX_ARGS(SIP_TRX, fname)); - return -1; -} - -/* - * This function gets the index corresponding to a specific method - */ -int16_t -get_method_request_trx_index (ccsipCCB_t *ccb, sipMethod_t method, boolean sent) -{ - const char *fname = "get_method_request_trx_index"; - int16_t i; - - if (ccb == NULL) { - return -1; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Getting TRX for method(%s), sent = %d", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), sipGetMethodString(method), sent); - - if (sent) { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->sent_request[i].cseq_method == method) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for sent method(%s)", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), i, sipGetMethodString(method)); - return i; - } - } - } else { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->recv_request[i].cseq_method == method) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for recv method(%s)", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), i, sipGetMethodString(method)); - return i; - } - } - } - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Unable to find any TRX for method!!", DEB_F_PREFIX_ARGS(SIP_TRX, fname)); - return -1; -} - -/* - * This function cleans the CSeq array and removes the entry - * corresponding to the method and compacts the array - */ -void -clean_method_request_trx (ccsipCCB_t *ccb, sipMethod_t method, boolean sent) -{ - const char *fname = "clean_method_request_trx"; - uint8_t i, j, k; - boolean found = FALSE; - sipTransaction_t *transactionp = NULL; - - if (ccb == NULL) { - return; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Removing TRX for method(%s), sent = %d", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), sipGetMethodString(method), sent); - - if (sent) { - transactionp = &(ccb->sent_request[0]); - } else { - transactionp = &(ccb->recv_request[0]); - } - - for (i = 0; i < MAX_REQ_OUTSTANDING && !found; i++) { - if (transactionp[i].cseq_method == method) { - transactionp[i].cseq_method = sipMethodInvalid; - transactionp[i].cseq_number = CCSIP_START_CSEQ; - strlib_free(transactionp[i].u.sip_via_header); - strlib_free(transactionp[i].sip_via_sentby); - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Removed TRX(%d) for method(%s)", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), i, sipGetMethodString(method)); - found = TRUE; - } - if (found) { - k = i; - for (j = k + 1; j < MAX_REQ_OUTSTANDING; j++, k++) { - memcpy(&(transactionp[k]), &(transactionp[j]), - sizeof(sipTransaction_t)); - } - // re-init the last transaction - transactionp[MAX_REQ_OUTSTANDING - 1].cseq_method = - sipMethodInvalid; - transactionp[MAX_REQ_OUTSTANDING - 1].cseq_number = - CCSIP_START_CSEQ; - transactionp[MAX_REQ_OUTSTANDING - 1].u.sip_via_header = - strlib_empty(); - transactionp[MAX_REQ_OUTSTANDING - 1].sip_via_sentby = - strlib_empty(); - } - } -} - -line_t -get_dn_line_from_dn (const char *watcher) -{ - line_t dn_line; - char line_name[CC_MAX_DIALSTRING_LEN]; - - for (dn_line = 1; dn_line <= MAX_REG_LINES; dn_line++) { - config_get_line_string(CFGID_LINE_NAME, line_name, (int) dn_line, - sizeof(line_name)); - if (!cpr_strcasecmp(watcher, line_name)) { - break; - } - } - return dn_line; -} - -boolean -validateHostName (char *str, char *dn) -{ - line_t dn_line = (line_t) -1; - char buffer[MAX_SIP_URL_LENGTH]; - char ccm1_addr[MAX_SIP_URL_LENGTH]; - char ccm2_addr[MAX_SIP_URL_LENGTH]; - char ccm3_addr[MAX_SIP_URL_LENGTH]; - - dn_line = get_dn_line_from_dn(dn); - if (dn_line >= 1 && dn_line <= MAX_REG_LINES) { - if (sip_regmgr_get_cc_mode(dn_line) == REG_MODE_NON_CCM) { - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, dn_line, - MAX_SIP_URL_LENGTH); - if (!strncmp(buffer, str, MAX_SIP_URL_LENGTH)) { - return (TRUE); - } else { - return (FALSE); - } - } else { - config_get_string(CFGID_CCM1_ADDRESS, ccm1_addr, - MAX_SIP_URL_LENGTH); - config_get_string(CFGID_CCM2_ADDRESS, ccm2_addr, - MAX_SIP_URL_LENGTH); - config_get_string(CFGID_CCM3_ADDRESS, ccm3_addr, - MAX_SIP_URL_LENGTH); - - if (!strncmp(ccm1_addr, str, MAX_SIP_URL_LENGTH) || - !strncmp(ccm2_addr, str, MAX_SIP_URL_LENGTH) || - !strncmp(ccm3_addr, str, MAX_SIP_URL_LENGTH)) { - return (TRUE); - } else { - return (FALSE); - } - } - } - - return (FALSE); -} - -/************************************************************* - * Function: sipGetSupportedOptionList - * This function returns the list of the supported option tags. - * The function may returns NULL pointer for the case that - * there is no tag to add. - **************************************************************/ -static const char * -sipGetSupportedOptionList (ccsipCCB_t *ccb, sipMethod_t sipmethod) -{ - return (SIP_CISCO_SUPPORTED_REG_TAGS); -} - -/* - * Send REGISTER - * - * Send a SIP REGISTER request. - * Assumes that - * - connection has been setup beforehand. - */ -boolean -sipSPISendRegister (ccsipCCB_t *ccb, - boolean no_dns_lookup, - const char *user, - int expires_int) -{ - const char fname[] = "SIPSPISendRegister"; - sipMessage_t *request = NULL; - char obp_address[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t ipaddr; - boolean obp_present = FALSE; - boolean send_result = FALSE; - - CPR_IP_ADDR_INIT(ipaddr); - - if (!(request = sipSPIBuildRegisterHeaders(ccb, user, expires_int))) { - CCSIP_DEBUG_ERROR("%s: Error: Building Register Headers.", - fname); - return (send_result); - } - - /* - * If we are being called as a result of a 4xx message we need to - * respond to the same proxy which sent us the 4xx message so use - * the previous ccb->reg.addr to send to. - */ - config_get_string(CFGID_OUTBOUND_PROXY, obp_address, sizeof(obp_address)); - if ((cpr_strcasecmp(obp_address, UNPROVISIONED) != 0) && - (obp_address[0] != 0) && - (obp_address[0] != '0')) { - obp_present = TRUE; - } - if ((!no_dns_lookup) && - ((obp_present == FALSE) || ((ccb->index == REG_BACKUP_CCB)))) { - /* See if DNS SRV record is available */ - dns_error_code = sipTransportGetServerAddrPort(ccb->reg.proxy, &ipaddr, - (uint16_t *)&ccb->reg.port, - &ccb->SRVhandle, FALSE); - if (dns_error_code == 0) { - /* - * Found an SRV record. Use that address. If there is more - * than one record in SRV response, setup to try all the - * servers in the list - */ - util_ntohl(&(ccb->reg.addr), &ipaddr); - } else { - /* Do a DNS A record lookup on the proxy */ - dns_error_code = dnsGetHostByName(ccb->reg.proxy, &ipaddr, 100, 1); - if (dns_error_code == 0) { - util_ntohl(&ipaddr, &ipaddr); - ccb->reg.addr = ipaddr; - } else { - ccb->reg.addr = ip_addr_invalid; - } - - } - } - - /* If we failed to get a valid IP address for the proxy - * do not broadcast the REGISTER message, but bail instead. - */ - if ((util_check_if_ip_valid(&(ccb->reg.addr))) || obp_present) { - send_result = SendRequest(ccb, request, sipMethodRegister, - FALSE, TRUE, FALSE); - } else { - CSFLogError("sipstack", "%s: Unable to retrieve address of proxy.", - fname); - free_sip_message(request); - } - - if (!send_result) { - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - } - return (send_result); -} - -char * -cc2siptype (cc_content_type_t type) -{ - switch (type) { - default: - case cc_content_type_unknown: - return SIP_CONTENT_TYPE_UNKNOWN; - case cc_content_type_SDP: - return SIP_CONTENT_TYPE_SDP; - case cc_content_type_CMXML: - return SIP_CONTENT_TYPE_CMXML; - case cc_content_type_sipfrag: - return SIP_CONTENT_TYPE_SIPFRAG; - } -} - -cc_content_type_t -sip2cctype (uint8_t type) -{ - switch (type) { - default: - case SIP_CONTENT_TYPE_UNKNOWN_VALUE: - return cc_content_type_unknown; - case SIP_CONTENT_TYPE_SDP_VALUE: - return cc_content_type_SDP; - case SIP_CONTENT_TYPE_CMXML_VALUE: - return cc_content_type_CMXML; - case SIP_CONTENT_TYPE_SIPFRAG_VALUE: - return cc_content_type_sipfrag; - } -} - -uint8_t -cc2sipdisp (cc_disposition_type_t type) -{ - switch (type) { - default: - case cc_disposition_unknown: - return SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE; - case cc_disposition_render: - return SIP_CONTENT_DISPOSITION_RENDER_VALUE; - case cc_disposition_session: - return SIP_CONTENT_DISPOSITION_SESSION_VALUE; - case cc_dispostion_icon: - return SIP_CONTENT_DISPOSITION_ICON_VALUE; - case cc_disposition_alert: - return SIP_CONTENT_DISPOSITION_ALERT_VALUE; - case cc_disposition_precondition: - return SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE; - } -} - -cc_disposition_type_t -sip2ccdisp (uint8_t type) -{ - switch (type) { - default: - case SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE: - return cc_disposition_unknown; - case SIP_CONTENT_DISPOSITION_RENDER_VALUE: - return cc_disposition_render; - case SIP_CONTENT_DISPOSITION_SESSION_VALUE: - return cc_disposition_session; - case SIP_CONTENT_DISPOSITION_ICON_VALUE: - return cc_dispostion_icon; - case SIP_CONTENT_DISPOSITION_ALERT_VALUE: - return cc_disposition_alert; - case SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE: - return cc_disposition_precondition; - } -} - - -static boolean -sipSPIIsPrivate (ccsipCCB_t *ccb) -{ - int blocking; - boolean private_flag = FALSE; - - /* - * If Caller ID Blocking is OFF or emergency route is ON, - * display the actual name. Otherwise, display "Anonymous". - */ - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - if ((blocking & 1) && (ccb->routeMode != RouteEmergency)) { - private_flag = TRUE; - } - return private_flag; -} - -/* - * sipSPISetRPID - * - * Set the RPID header string sent in either a request or response. - */ - -static int -sipSPISetRPID (ccsipCCB_t *ccb, boolean request) -{ - const char *fname = "sipSPISetRPID"; - int rpid_flag = RPID_DISABLED; - boolean private_flag; - size_t escaped_url_len; - char remote_party_id_buf[MAX_SIP_URL_LENGTH]; - char line_name[MAX_LINE_NAME_SIZE]; - char display_name[MAX_LINE_NAME_SIZE]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_type ip_type; - - src_addr_str[0] = '\0'; - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - - if (rpid_flag != RPID_ENABLED) { - return RPID_DISABLED; - } - - if (!ccb) { - CCSIP_DEBUG_ERROR("%s: Error: NULL ccb.", fname); - return rpid_flag; - } - - /* If RPID string is already set, just return */ - if (ccb->sip_remote_party_id[0]) { - return RPID_ENABLED; - } - - private_flag = sipSPIIsPrivate(ccb); - - config_get_string((CFGID_LINE_NAME + ccb->dn_line - 1), line_name, - sizeof(line_name)); - sip_config_get_display_name(ccb->dn_line, display_name, - sizeof(display_name)); - - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, src_addr_str); - - sstrncpy(remote_party_id_buf, "\"", MAX_SIP_URL_LENGTH); - escaped_url_len = 1; - escaped_url_len += - sippmh_converQuotedStrToEscStr(display_name, strlen(display_name), - remote_party_id_buf + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, - TRUE) - 1; - sstrncat(remote_party_id_buf,"\" ;party=%s;id-type=subscriber;privacy=%s;screen=yes", - src_addr_str, (request ? "calling" : "called"), - (private_flag ? "full" : "off")); - } else { - snprintf(remote_party_id_buf + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, - "@%s>;party=%s;id-type=subscriber;privacy=%s;screen=yes", - src_addr_str, (request ? "calling" : "called"), - (private_flag ? "full" : "off")); - } - - ccb->sip_remote_party_id = strlib_update(ccb->sip_remote_party_id, - remote_party_id_buf); - - return RPID_ENABLED; -} - -static void -sipSPISetFrom (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISetFrom"; - boolean private_flag; - size_t escaped_url_len; - char *sip_from_tag; - char *temp_from_tag; - char *sip_from_temp; - char line_name[MAX_LINE_NAME_SIZE]; - char display_name[MAX_LINE_NAME_SIZE]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char *addr_str = 0; - char addr[MAX_IPADDR_STR_LEN]; - cpr_ip_type ip_type = CPR_IP_ADDR_INVALID; - - if (!ccb) { - CCSIP_DEBUG_ERROR("%s: Error: NULL ccb.", fname); - return; - } - - ipaddr2dotted(dest_sip_addr_str, &ccb->dest_sip_addr); - - if ((ccb->routeMode == RouteEmergency) || - (ccb->proxySelection == SIP_PROXY_BACKUP)) { - addr_str = dest_sip_addr_str; - } else { - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, addr); - addr_str = addr; - } - - sip_from_temp = strlib_open(ccb->sip_from, MAX_SIP_URL_LENGTH); - - if (sip_from_temp == NULL) { - CCSIP_DEBUG_ERROR("%s: Error: sip_from_temp is NULL.", fname); - return; - } - - private_flag = sipSPIIsPrivate(ccb); - - if (private_flag == TRUE) { - if (ip_type == CPR_IP_ADDR_IPV6) { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "\"%s\" ", - SIP_HEADER_ANONYMOUS_STR, SIP_HEADER_ANONYMOUS_STR, - addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "\"%s\" ", - SIP_HEADER_ANONYMOUS_STR, SIP_HEADER_ANONYMOUS_STR, - addr_str); - } - } else { - /* From header needs to have global address in it */ - config_get_string((CFGID_LINE_NAME + ccb->dn_line - 1), line_name, - sizeof(line_name)); - sip_config_get_display_name(ccb->dn_line, display_name, - sizeof(display_name)); - sstrncpy(sip_from_temp, "\"", MAX_SIP_URL_LENGTH); - escaped_url_len = 1; - escaped_url_len += - sippmh_converQuotedStrToEscStr(display_name, strlen(display_name), - sip_from_temp + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, - TRUE) - 1; - sstrncat(sip_from_temp,"\" ", - addr_str); - } else { - snprintf(sip_from_temp + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, "@%s>", - addr_str); - } - } - - /* Now add tag to the From header */ - sstrncat(sip_from_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - temp_from_tag = ccsip_find_preallocated_sip_local_tag(ccb->dn_line); - sip_from_tag = strlib_open(ccb->sip_from_tag, MAX_SIP_URL_LENGTH); - if (temp_from_tag == NULL) { - if (sip_from_tag) { - sip_util_make_tag(sip_from_tag); - sstrncat(sip_from_temp, sip_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - } else { - if (sip_from_tag) { - sstrncpy(sip_from_tag, temp_from_tag, MAX_SIP_URL_LENGTH); - sstrncat(sip_from_temp, temp_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - ccsip_free_preallocated_sip_local_tag(ccb->dn_line); - } - ccb->sip_from_tag = strlib_close(sip_from_tag); - ccb->sip_from = strlib_close(sip_from_temp); -} - -/* - * Send INVITE - * - * As the name suggests, called to send a SIP INVITE request. - * Assumes that - * - connection has been setup beforehand. - * - SDP description has been setup. - * Does not affect call state. - */ -boolean -sipSPISendInvite (ccsipCCB_t *ccb, sipInviteType_t inviteType, - boolean initInvite) -{ - const char *fname = "SIPSPISendInvite"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - char called_number[MAX_SIP_URL_LENGTH]; - ccsipCCB_t *referccb = NULL; - boolean inviterefer = FALSE; - sipMessageFlag_t messageflag; - int i; - int rpid_flag; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "INVITE"); - - if (ccb->wastransferred) { - inviterefer = TRUE; - } - // This routine can be called in three different contexts. These are the - // important differences between them: - // CONTEXT inviteType referccb - // ----------------------------------------------------------- - // Normal SIP_INVITE_TYPE_NORMAL NULL - // Blind Xfer SIP_INVITE_TYPE_NORMAL valid - // Att Xfer SIP_INVITE_TYPE_TRANSFER valid - - referccb = sip_sm_get_target_call_by_gsm_id(ccb->gsm_id); - - // If there is a referccb, try to get authentication stuff from it - if (referccb != NULL) { - if (referccb->refer_proxy_auth != NULL) { - ccb->refer_proxy_auth = cpr_strdup(referccb->refer_proxy_auth); - } - } - - if (inviteType == SIP_INVITE_TYPE_TRANSFER) { - // For attended transfers we need to make a local copy of the - // referccb if it exists - if (NULL != referccb) { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, - referccb->sip_referredBy); - if (referccb->featuretype == CC_FEATURE_XFER) { - ccb->sipxfercallid = strlib_update(ccb->sipxfercallid, - referccb->sipxfercallid); - if (ccb->sipxfercallid) { - if (ccb->sipxfercallid[0] != '\0') { - ccb->wastransferred = TRUE; - inviterefer = TRUE; - } - } - } - } - - if (inviterefer == FALSE) { - //Not enough information for starting attended transfer - CCSIP_DEBUG_ERROR("%s: Error:Replaces INVITE build unsuccessful.", - fname); - return (FALSE); - } - } - - if (inviteType != SIP_INVITE_TYPE_REDIRECTED) { - ccb->sip_to = strlib_update(ccb->sip_to, ccb->calledNumber); - } - - - /* - * Set from header - */ - sipSPISetFrom(ccb); - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - - /* - * The calledNumber needs to be rewritten with the backup proxy - * ip address if the backup proxy is active - */ - if (ccb->proxySelection == SIP_PROXY_BACKUP) { - sstrncpy(called_number, ccb->calledDisplayedName, MAX_SIP_URL_LENGTH); - - /* - * NOTE: Need to replace with new routine ??? - */ - if (called_number[0] != '\0') { - sip_sm_util_normalize_name(ccb, called_number); - } - } - - // Add Create Request Here - messageflag.flags = 0; - messageflag.flags |= SIP_HEADER_ACCEPT_BIT | - SIP_HEADER_EXPIRES_BIT | - SIP_HEADER_CONTACT_BIT | - SIP_HEADER_DIVERSION_BIT | - SIP_HEADER_SUPPORTED_BIT | - SIP_HEADER_ALLOW_EVENTS_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_RECV_INFO_BIT | - SIP_HEADER_REQUIRE_BIT; - - if (ccb->authen.authorization != NULL) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - if (ccb->refer_proxy_auth != NULL) { - messageflag.flags |= SIP_HEADER_PROXY_AUTH_BIT; - } - if (ccb->sip_referredBy[0] != '\0') { - messageflag.flags |= SIP_HEADER_REFERRED_BY_BIT; - } - if (((TRUE == inviterefer) || (ccb->flags & SENT_INVITE_REPLACE)) && - ('\0' != ccb->sipxfercallid[0])) { - messageflag.flags |= SIP_HEADER_REPLACES_BIT; - } - if (ccb->sip_reqby[0]) { - messageflag.flags |= SIP_HEADER_REQUESTED_BY_BIT; - } - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - if (ccb->out_call_info != NULL) { - messageflag.flags |= SIP_HEADER_CALL_INFO_BIT; - } - if (ccb->join_info != NULL) { - messageflag.flags |= SIP_HEADER_JOIN_INFO_BIT; - } - - /* Write SDP */ - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - request = GET_SIP_MESSAGE(); - if (request == NULL) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to allocate INVITE request", - fname); - return (FALSE); - } - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodInvite, request, - initInvite, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - UPDATE_FLAGS(flag, tflag); - - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - /* - * If overloaded headers are present from the 302, add them to the - * Invite message - */ - if ((ccb->redirect_info) && - (ccb->redirect_info->sipContact->locations[0]->genUrl) && - (ccb->redirect_info->sipContact->locations[0]->genUrl->u.sipUrl) && - (ccb->redirect_info->sipContact->locations[0]->genUrl->u.sipUrl->headerp) && - (inviteType == SIP_INVITE_TYPE_REDIRECTED)) { - for (i = 0; - i < ccb->redirect_info->sipContact->locations[0]->genUrl->u.sipUrl->num_headers; - i++) { - tflag = sippmh_add_text_header(request, - ccb->redirect_info->sipContact->locations[0]->genUrl->u. - sipUrl->headerp[i].attr, - ccb->redirect_info->sipContact->locations[0]->genUrl->u. - sipUrl->headerp[i].value); - UPDATE_FLAGS(flag, tflag); - } - } - - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: INVITE message build unsuccessful.", - fname); - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } - - ccb->retx_counter = 0; - - if (SendRequest(ccb, request, sipMethodInvite, FALSE, TRUE, TRUE) - == FALSE) { - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -sipRet_t -sipSPIAddCallStats (ccsipCCB_t *ccb, sipMessage_t *msg) -{ - int call_stats_flag; - sipRet_t tflag = STATUS_SUCCESS; - - config_get_value(CFGID_CALL_STATS, &call_stats_flag, sizeof(call_stats_flag)); - if ((call_stats_flag) && (ccb->kfactor_ptr)) { - if (ccb->kfactor_ptr->rxstats[0] != NUL) { - tflag = sippmh_add_text_header(msg, SIP_RX_CALL_STATS, ccb->kfactor_ptr->rxstats); - } - if (ccb->kfactor_ptr->txstats[0] != NUL) { - tflag = sippmh_add_text_header(msg, SIP_TX_CALL_STATS, ccb->kfactor_ptr->txstats); - } - } - return tflag; -} - -boolean -sipSPISendInviteMidCall (ccsipCCB_t *ccb, boolean expires) -{ - const char *fname = "sipSPISendInviteMidCall"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int rpid_flag; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "INVITE"); - - /* - * Build the request Here - */ - messageflag.flags = 0; - messageflag.flags |= SIP_HEADER_CONTACT_BIT | - SIP_HEADER_ROUTE_BIT | - SIP_HEADER_CONTENT_TYPE_BIT | - SIP_HEADER_ACCEPT_BIT | - SIP_HEADER_SUPPORTED_BIT | - SIP_HEADER_ALLOW_EVENTS_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_RECV_INFO_BIT | - SIP_HEADER_REQUIRE_BIT; - - if ((ccb->authen.authorization != NULL) && - ((ccb->state == SIP_STATE_SENT_INVITE) || - (ccb->state == SIP_STATE_SENT_MIDCALL_INVITE))) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - - if ((ccb->authen.authorization != NULL) && - (ccb->state == SIP_STATE_SENT_INVITE)) { - if (ccb->join_info != NULL) { - messageflag.flags |= SIP_HEADER_JOIN_INFO_BIT; - } - } - - if ('\0' != ccb->sipxfercallid[0]) { - messageflag.flags |= SIP_HEADER_REPLACES_BIT; - } - - if (expires > 0) { - messageflag.flags |= SIP_HEADER_EXPIRES_BIT; - } - - if (ccb->sip_referredBy[0]) { - messageflag.flags |= SIP_HEADER_REFERRED_BY_BIT; - } - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - - if (ccb->out_call_info) { - messageflag.flags |= SIP_HEADER_CALL_INFO_BIT; - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodInvite, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - - tflag = sipSPIAddCallStats(ccb, request); - UPDATE_FLAGS(flag, tflag); - - /* Recalc and add Authorization header if needed */ - if ((ccb->state != SIP_STATE_SENT_INVITE) && - (ccb->state != SIP_STATE_SENT_MIDCALL_INVITE)) { - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_INVITE); - } - - /* Write SDP */ - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: INVITE message build unsuccessful.", - fname); - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } - /* - * Currently the following field is being set to zero when the - * midcall invite is not being done as a response to an authorization - * challenge. So utilize this fact to prevent proxy backup selection - * on a mid-call invite. The end result is to stick with the same - * proxy as the original invite. - */ - if (ccb->authen.cred_type == 0) { - ccb->proxySelection = SIP_PROXY_DO_NOT_CHANGE_MIDCALL; - } - - /* Successfully constructed msg with new URI for this INVITE to send out. - * Update URIOriginal before sending out. - */ - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - /* Enable reTx and send */ - ccb->retx_counter = 0; - if (SendRequest(ccb, request, sipMethodInvite, TRUE, TRUE, TRUE) == FALSE) { - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - - -/* - * Sends the ACK request. - * Assumes that - * - the connection is setup. - * Appends session description if sd = TRUE. (This would - * be the case, if we want to change the codec that - * was sent on the INVITE. - * Does not affect call state. - */ -boolean -sipSPISendAck (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *fname = "sipSPISendAck"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - uint32_t response_cseq_number = 0; - sipCseq_t *response_cseq_structure; - const char *response_cseq; - int16_t trx_index = -1; - boolean retval; - int rpid_flag; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "ACK"); - - /* - * Build the request - */ - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_ROUTE_BIT | - SIP_HEADER_RECV_INFO_BIT; - - /* - * Cseq number in the response could be different from that in ccb. - * If there was no response as in - * ccsip_handle_sentinviteconnected_ev_cc_connected_ack - * then use ccb for getting Cseq number - */ - if (response) { - response_cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!response_cseq) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to obtain response CSeq " - "header.\n", fname); - return (FALSE); - } - response_cseq_structure = sippmh_parse_cseq(response_cseq); - if (!response_cseq_structure) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to parse response CSeq " - "header.\n", fname); - return (FALSE); - } - response_cseq_number = response_cseq_structure->number; - cpr_free(response_cseq_structure); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Cseq from response = %d", - DEB_F_PREFIX_ARGS(SIP_ACK, "sipSPISendAck"), response_cseq_number); - } else { - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, TRUE); - if (trx_index < 0) { - return (FALSE); - } - response_cseq_number = ccb->sent_request[trx_index].cseq_number; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Cseq from ccb = %d", - DEB_F_PREFIX_ARGS(SIP_ACK, "sipSPISendAck"), response_cseq_number); - } - - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - if (ccb->authen.authorization != NULL) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodAck, request, FALSE, - response_cseq_number)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } - - /* Send message */ - retval = SendRequest(ccb, request, sipMethodAck, FALSE, FALSE, FALSE); - - // We are done with this INVITE request so lets clear and reorder our - // cseq list of outstanding requests. Assumes that ACK will only be - // sent for INVITE. Also note that no trx block is allocated for Ack - // and so there is no need to free it. - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (retval); -} - - -/* - * Sends the BYE request for the call. - * Assumes that - * - the connection is setup. - * Does not change the state, but changes the disconnection flags. - */ -void -sipSPISendBye (ccsipCCB_t *ccb, char *alsoString, sipMessage_t *pForked200) -{ - const char *fname = "sipSPISendBye"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipContact_t *stored_contact_info = NULL; - sipRecordRoute_t *stored_record_route_info = NULL; - static char stored_sip_to[MAX_SIP_URL_LENGTH]; - static char stored_sip_from[MAX_SIP_URL_LENGTH]; - static char last_route[MAX_SIP_URL_LENGTH]; - const char *forked200_contact = NULL; - const char *forked200_record_route = NULL; - const char *forked200_to = NULL; - const char *forked200_from = NULL; - sipMessageFlag_t messageflag; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "BYE"); - - /* - * If this BYE is in response to the secondary forked 200 OK message - * (from the callee being rejected), then we need to use the - * Contact and Record-Route of this 200 OK message, rather than the - * stored ccb->contact_info and ccb->record_route_info. - * So, if pForked200 exists, then we will: - * - save existing ccb->contact_info and ccb->record_route_info fields - * - parse Contact and Record-Route of the forked 200 - * - use these values to form this BYE's Req-URI - * - restore the original ccb->contact_info and ccb->record_route_info - */ - if (pForked200) { - stored_contact_info = ccb->contact_info; - stored_record_route_info = ccb->record_route_info; - sstrncpy(stored_sip_to, ccb->sip_to, MAX_SIP_URL_LENGTH); - sstrncpy(stored_sip_from, ccb->sip_from, MAX_SIP_URL_LENGTH); - - forked200_contact = sippmh_get_cached_header_val(pForked200, CONTACT); - forked200_record_route = - sippmh_get_cached_header_val(pForked200, RECORD_ROUTE); - forked200_to = sippmh_get_cached_header_val(pForked200, TO); - forked200_from = sippmh_get_cached_header_val(pForked200, FROM); - - if (forked200_contact) { - ccb->contact_info = sippmh_parse_contact(forked200_contact); - } - if (forked200_record_route) { - ccb->record_route_info = - sippmh_parse_record_route(forked200_record_route); - } - ccb->sip_to = strlib_update(ccb->sip_to, forked200_to); - ccb->sip_from = strlib_update(ccb->sip_from, forked200_from); - } - - /* - * Build the request - */ - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTENT_LENGTH_BIT; - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodBye, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - - /* add in call stats header if needed */ - tflag = sipSPIAddCallStats(ccb, request); - UPDATE_FLAGS(flag, tflag); - - if (alsoString) { - tflag = sippmh_add_text_header(request, SIP_HEADER_ALSO, alsoString); - UPDATE_FLAGS(flag, tflag); - } - - memset(last_route, 0, MAX_SIP_URL_LENGTH); - tflag = (sipSPIAddRouteHeaders(request, ccb, last_route, MAX_SIP_URL_LENGTH)) ? - STATUS_SUCCESS : STATUS_FAILURE; - UPDATE_FLAGS(flag, tflag); - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, SIP_METHOD_BYE); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - if (alsoString) - cpr_free(alsoString); - clean_method_request_trx(ccb, sipMethodBye, TRUE); - return; - } - - ccb->retx_counter = 0; - /* Send message */ - (void) SendRequest(ccb, request, sipMethodBye, FALSE, TRUE, FALSE); - - /* - * Update history - */ - /* Record Also header if any */ - if (alsoString) { - if (alsoString[0]) { - sstrncpy(gCallHistory[ccb->index].last_bye_also_string, alsoString, - MAX_SIP_URL_LENGTH); - } - cpr_free(alsoString); - } else { - memset(gCallHistory[ccb->index].last_bye_also_string, 0, - MAX_SIP_URL_LENGTH); - } - - /* Record current Route */ - if (last_route[0]) { - sstrncpy(gCallHistory[ccb->index].last_route, last_route, - MAX_SIP_URL_LENGTH); - } else { - memset(gCallHistory[ccb->index].last_route, 0, MAX_SIP_URL_LENGTH); - } - /* Record current Request-URI */ - if (ccb->ReqURI[0]) { - sstrncpy(gCallHistory[ccb->index].last_route_request_uri, ccb->ReqURI, - MAX_SIP_URL_LENGTH); - } else { - memset(gCallHistory[ccb->index].last_route_request_uri, 0, - MAX_SIP_URL_LENGTH); - } - -// bugid: CSCsz34666 -// /* -// * Store call history info -// */ -// if ((int) (ccb->index) <= TEL_CCB_END) { -// memcpy(gCallHistory[ccb->index].last_call_id, ccb->sipCallID, -// MAX_SIP_CALL_ID); -// } - - /* - * Restore the original ccb->contact and ccb->record_route fields - */ - if (pForked200) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = stored_contact_info; - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = stored_record_route_info; - - ccb->sip_to = strlib_update(ccb->sip_to, stored_sip_to); - ccb->sip_from = strlib_update(ccb->sip_from, stored_sip_from); - } - - return; -} - - - -/* - * Sends the SIP CANCEL request, to disconnect a call that - * is not in the active state. - */ -void -sipSPISendCancel (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendCancel"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - char *temp = NULL; - char local_cpy[MAX_SIP_URL_LENGTH]; - string_t hold_to_tag = strlib_copy(ccb->sip_to); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "CANCEL"); - - messageflag.flags = 0; - ccb->authen.cred_type = 0; - - messageflag.flags = SIP_HEADER_CONTENT_LENGTH_BIT; - - /* Remove the to_tag from the CANCEL message if present */ - sstrncpy(local_cpy, ccb->sip_to, MAX_SIP_URL_LENGTH); - temp = strstr(local_cpy, ">"); - if (temp != NULL) { - *(temp + 1) = '\0'; - } - ccb->sip_to = strlib_update(ccb->sip_to, local_cpy); - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodCancel, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - /* restore the to_tag if it was there */ - if (hold_to_tag) { - ccb->sip_to = strlib_update(ccb->sip_to, hold_to_tag); - strlib_free(hold_to_tag); - } - hold_to_tag = strlib_empty(); - - UPDATE_FLAGS(flag, tflag); - /* Recalc and add Authorization header if needed */ - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_CANCEL); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - clean_method_request_trx(ccb, sipMethodCancel, TRUE); - return; - } - /* Record current Request-URI */ - if (ccb->ReqURI[0]) { - sstrncpy(gCallHistory[ccb->index].last_route_request_uri, ccb->ReqURI, - MAX_SIP_URL_LENGTH); - } else { - memset(gCallHistory[ccb->index].last_route_request_uri, 0, - MAX_SIP_URL_LENGTH); - } - if (SendRequest(ccb, request, sipMethodCancel, FALSE, TRUE, FALSE) - == FALSE) { - clean_method_request_trx(ccb, sipMethodCancel, TRUE); - return; - } else { - return; - } -} - -void -sip_platform_icmp_unreachable_callback (void *ccb, uint32_t ipaddr) -{ - static const char fname[] = "sip_platform_icmp_unreachable_callback"; - uint32_t *icmp_msg; - - icmp_msg = (uint32_t *) SIPTaskGetBuffer(sizeof(uint32_t)); - if (!icmp_msg) { - CCSIP_DEBUG_ERROR("%s: Error: get buffer failed.", fname); - return; - } - *icmp_msg = ((ccsipCCB_t *)ccb)->index; - - if (SIPTaskSendMsg(SIP_ICMP_UNREACHABLE, (cprBuffer_t)icmp_msg, - sizeof(uint32_t), (void *)(long)ipaddr) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR("%s: Error: send msg failed.", fname); - cpr_free((cprBuffer_t)icmp_msg); - } - return; -} - -/* - * Sends the SIP REFER request, to Transfer the call - * - * Parameters: - * ccb - reference tio the existing call control block - * referto - Dial string to make a call (If null it will pick up from ccb) - * referto_typ to indicate if the referto is trasnfer or token refer - * - */ -boolean -sipSPISendRefer (ccsipCCB_t *ccb, char *referto, sipRefEnum_e referto_type) -{ - const char *fname = "sipSPISendRefer"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - ccsipCCB_t *xfer_ccb = NULL; - char tempreferto[MAX_SIP_URL_LENGTH + 2]; - char callid[MAX_SIP_HEADER_LENGTH + 2]; - sipMessageFlag_t messageflag; - char *semi = NULL; - char *left_bracket = NULL; - char *right_bracket = NULL; - char *msg_referto = NULL; - string_t copy_of_referto = NULL; - int rpid_flag; - char *ref_to_callid = NULL; - const char *to_tag = NULL; - const char *from_tag = NULL; - boolean dm_info = FALSE; - sipJoinInfo_t join_info; - - memset(&join_info, 0, sizeof(join_info)); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "REFER"); - /* - * Build the request - */ - - if (sipSPIGenerateReferredByHeader(ccb) == FALSE) { - tflag = HSTATUS_FAILURE; - } else { - tflag = HSTATUS_SUCCESS; - } - UPDATE_FLAGS(flag, tflag); - - messageflag.flags = 0; - /* - * Don't add the content length bit here. Content length - * needs to be the last in the header. TCP uses the content - * length to do framing. - */ - messageflag.flags = SIP_HEADER_CONTACT_BIT | SIP_HEADER_ROUTE_BIT; - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - - if (referto) { - // Get a new call-id if this REFER is for fallback token registration - if (strncmp(referto, TOKEN_REFER_TO, sizeof(TOKEN_REFER_TO)) == 0) { - ccb->sipCallID[0] = '\0'; - sip_util_get_new_call_id(ccb); - } - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodRefer, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - /* Recalc and add Authorization header if needed */ - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_REFER); - - memset(tempreferto, 0, MAX_SIP_URL_LENGTH + 2); - memset(callid, 0, MAX_SIP_HEADER_LENGTH + 2); - - /* see if we have ;user= */ - if (referto) { - semi = strchr(referto, ';'); - } - - if (CC_FEATURE_XFER == ccb->featuretype) { - // The con_call_id is filled up by GSM when it opens up the line This - // is used to cross reference the call_ids - xfer_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - - if (xfer_ccb != NULL) { - ref_to_callid = xfer_ccb->sipCallID; - to_tag = xfer_ccb->sip_to_tag; - from_tag = xfer_ccb->sip_from_tag; - } - - if (xfer_ccb != NULL || dm_info == TRUE) { - int i = 0; - - // Create Refer_to header with replace id (call_id of other call) - // and To-Tag of other call - escape the replaced callid - while (*ref_to_callid != '\0') { - if (*ref_to_callid != '@') { - callid[i++] = *ref_to_callid; - } else { - callid[i++] = '%'; - callid[i++] = '4'; - callid[i++] = '0'; - } - ref_to_callid++; - } - callid[i] = '\0'; - - /* first get rid of opening and closing braces, if there */ - copy_of_referto = strlib_copy(referto); - if (copy_of_referto) { - left_bracket = strpbrk(copy_of_referto, "<"); - } - if (left_bracket) { - left_bracket++; - right_bracket = strchr(left_bracket, '>'); - if (right_bracket) { - *right_bracket++ = 0; - } - msg_referto = left_bracket; - } else { - msg_referto = referto; - } - if (msg_referto) { - if (strncmp(msg_referto, "sip:", 4) == 0) { - snprintf(tempreferto, sizeof(tempreferto), - "<%s%c%s%c%s%%3B%s%%3D%s%%3B%s%%3D%s>", - msg_referto, QUESTION_MARK, - SIP_HEADER_REPLACES, EQUAL_SIGN, callid, - TO_TAG, to_tag, - FROM_TAG, from_tag); - } else { - snprintf(tempreferto, sizeof(tempreferto), - "", - msg_referto, QUESTION_MARK, - SIP_HEADER_REPLACES, EQUAL_SIGN, callid, - TO_TAG, to_tag, - FROM_TAG, from_tag); - } - } - strlib_free(copy_of_referto); - } - - if (dm_info) { - cpr_free(join_info.call_id); - cpr_free(join_info.to_tag); - cpr_free(join_info.from_tag); - } - - tflag = sippmh_add_text_header(request, SIP_HEADER_REFER_TO, - ((NULL != xfer_ccb)|| (dm_info == TRUE)) ? tempreferto : referto); - UPDATE_FLAGS(flag, tflag); - } else { - if (referto) { - if ((strncmp(referto, "", - referto); - } else { - snprintf(tempreferto, sizeof(tempreferto), "sip:%s", - referto); - } - } - } - tflag = sippmh_add_text_header(request, SIP_HEADER_REFER_TO, - tempreferto); - UPDATE_FLAGS(flag, tflag); - } - - ccb->sip_referTo = strlib_update(ccb->sip_referTo, referto); - tflag = sippmh_add_text_header(request, SIP_HEADER_REFERRED_BY, - ccb->sip_referredBy); - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - return (FALSE); - } -// cpr_free(referto); - - /* - * Add the content length now. - */ - tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - UPDATE_FLAGS(flag, tflag); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - return FALSE; - } - - ccb->retx_counter = 0; - - if (SendRequest(ccb, request, sipMethodRefer, FALSE, TRUE, FALSE) == FALSE) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -/* - * Sends the Notify - * Will be sent when we get OK from target (in case of Refer) - * - * Note: Assumes that the connection is setup. - * - * Parameter: - * ccb - call control block - * response -*/ -boolean -sipSPISendNotify (ccsipCCB_t *ccb, int response) -{ - const char *fname = "sipSPISendNotify"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - char *body; - char errortext[MAX_SIP_URL_LENGTH]; - char subs_state_hdr[SUBS_STATE_HDR_LEN]; - int respClass; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "Notify"); - - /* - * Clean up any remaining transactions before sending the next request. - * Normally the transactions are cleaned after final responses (200OK) - * and if not they will be cleaned after the timeouts. Currently for - * NOTIFYs there are not timeout cleanups, so we will explicitly clean - * any outstanding transactions now before the next request. - * - * This fix works today because we don't really care about any responses - * to NOTIFY requests and do not act on them. The transaction layer should - * be enhanced to handles these cases. This should be addressed under the - * Ringpops feature. - */ - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - - /* - * Before we do the real notify work, we may need to clean up the - * refer proxy authorization stuff that may have been left laying around - * during the transfer. - * - * This is the Proxy-Authorization that came in the REFER's Refer-To - * as an escaped header and therefore should only be alive till the - * transfer is done. - * - * But we have to do this only if we are sending the last notify for - * a REFER, i.e. if we are sending the last sipfrag. For ex: - * "200 OK", or "404 Not Found". We have to check for this because - * after sending a NOTIFY("100 Trying") to the Transferor we send an - * INVITE to the target and the Proxy-Authorization is required. When - * we send a NOTIFY indicating success or failure, we can remove the - * refer_proxy_auth in both ccbs. - */ - respClass = response / 100; - if (respClass >= 2) { - if (ccb->refer_proxy_auth) { - ccsipCCB_t *other_ccb; - - cpr_free(ccb->refer_proxy_auth); - ccb->refer_proxy_auth = NULL; - // now, find the ccb of the call we transferred to.... - other_ccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if (other_ccb != NULL) { - if (other_ccb->refer_proxy_auth) { - cpr_free(other_ccb->refer_proxy_auth); - other_ccb->refer_proxy_auth = NULL; - } - } - } - } - - /* - * Build the request - */ - // The addition of the CSeq method will be done when CSeq number is added - // ccb->last_sent_request_cseq_method = sipMethodNotify; - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_ROUTE_BIT | SIP_HEADER_CONTACT_BIT; - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodNotify, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(request, SIP_HEADER_EVENT, SIP_EVENT_REFER); - UPDATE_FLAGS(flag, tflag); - - // Add Subscription-State header - if (ccb->flags & FINAL_NOTIFY) { - snprintf(subs_state_hdr, SUBS_STATE_HDR_LEN, - "terminated; reason=noresource"); - } else { - uint32_t expires_timeout = 0; - - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &expires_timeout, - sizeof(expires_timeout)); - snprintf(subs_state_hdr, SUBS_STATE_HDR_LEN, "active; expires=%d", - expires_timeout); - } - tflag = sippmh_add_text_header(request, SIP_HEADER_SUBSCRIPTION_STATE, - subs_state_hdr); - UPDATE_FLAGS(flag, tflag); - - /* Recalc and add Authorization header if needed */ - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_NOTIFY); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return (FALSE); - } - - /* Write message */ - /* - * Currently the only notify message the phone sends is with respect - * to refer. This routine looks like a general send notify routine. - * One would assume then there needs to be some sort of if (refer) - * check to cause it to send "message/sipfrag" otherwise send - * "application/sip" - */ -// tflag = sippmh_add_text_header(request, SIP_HEADER_CONTENT_TYPE, -// SIP_CONTENT_TYPE_SIP ); - // Don't add content-type explicitly - // tflag = sippmh_add_text_header(request, SIP_HEADER_CONTENT_TYPE, - // SIP_CONTENT_TYPE_SIPFRAG ); -// UPDATE_FLAGS(flag, tflag); - - body = (char *) cpr_malloc(MAX_SIP_URL_LENGTH * sizeof(char)); - if (!body) { - if (request) { - free_sip_message(request); - } - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return FALSE; - } - memset(errortext, 0, MAX_SIP_URL_LENGTH); - get_sip_error_string(errortext, response); - snprintf(body, MAX_SIP_URL_LENGTH, "%s %d %s\r\n", SIP_VERSION, - response, errortext); - - tflag = sippmh_add_message_body(request, body, strlen(body), - SIP_CONTENT_TYPE_SIPFRAG, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, - TRUE, NULL); - UPDATE_FLAGS(flag, tflag); - - // No need to add header length separately - // tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, - // strlen(message_body)); - // UPDATE_FLAGS(flag, tflag); - - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return (FALSE); - } - - ccb->retx_counter = 0; - - if (SendRequest(ccb, request, sipMethodNotify, FALSE, TRUE, FALSE) == FALSE) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -/* - * Sends the Info - * - * Note: Assumes that the connection is setup. - * - * Parameter: - * ccb - call control block - * info_package - the Info-Package header of the Info Package - * content_type - the Content-Type header of the Info Package - * message_body - the message body of the Info Package -*/ -boolean -sipSPISendInfo (ccsipCCB_t *ccb, const char *info_package, - const char *content_type, const char *message_body) -{ - const char *fname = "sipSPISendInfo"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - char *body; - boolean retval; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "Info"); - - /* - * Build the request - */ - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_ROUTE_BIT | SIP_HEADER_CONTACT_BIT; - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodInfo, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - /* FIXME Media Control currently does not follow the offer/offer - negotiation process outlined in IETF draft - draft-ietf-sip-info-events-01, so do not add Info-Package - header field if it's Media Control Info Package. */ - if (cpr_strncasecmp(content_type, SIP_CONTENT_TYPE_MEDIA_CONTROL, - strlen(SIP_CONTENT_TYPE_MEDIA_CONTROL)) != 0) { - tflag = sippmh_add_text_header(request, SIP_HEADER_INFO_PACKAGE, info_package); - UPDATE_FLAGS(flag, tflag); - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - return FALSE; - } - - body = (char *) cpr_malloc((strlen(message_body) + 1) * sizeof(char)); - if (!body) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MEMORY_OUT_OF_MEM), fname); - if (request) { - free_sip_message(request); - } - return FALSE; - } - memcpy(body, message_body, strlen(message_body) + 1); - - tflag = sippmh_add_message_body(request, body, strlen(body), - content_type, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, - TRUE, NULL); - flag = tflag; - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - cpr_free(body); - if (request) { - free_sip_message(request); - } - return FALSE; - } - - retval = SendRequest(ccb, request, sipMethodInfo, TRUE, FALSE, FALSE); - - // Don't keep the trx so as not to mess up the retran timer of other requests - /* - * FIXME fix it when the framework is modified to support concurrent requests - */ - clean_method_request_trx(ccb, sipMethodInfo, TRUE); - - return retval; -} - -/* - * Sends the BYE or CANCEL response for the call. - * Assumes that - * - the connection is setup. - */ -boolean -sipSPISendByeOrCancelResponse (ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t sipMethodByeorCancel) -{ - const char *fname = "sipSPISendByeResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - boolean result; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, 200); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTENT_LENGTH_BIT; - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, SIP_STATUS_SUCCESS, response, - SIP_SUCCESS_SETUP_PHRASE, 0, NULL, sipMethodByeorCancel)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* send call stats on BYE response */ - if ((flag == STATUS_SUCCESS) && (sipMethodByeorCancel == sipMethodBye)) { - flag = sipSPIAddCallStats(ccb, response); - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - } - clean_method_request_trx(ccb, sipMethodByeorCancel, FALSE); - return (FALSE); - } - result = sendResponse(ccb, response, request, FALSE, sipMethodByeorCancel); - clean_method_request_trx(ccb, sipMethodByeorCancel, FALSE); - return (result); -} - - - -/* - * Send 100 TRYING - */ -void -sipSPISendInviteResponse100 (ccsipCCB_t *ccb, boolean remove_to_tag) -{ - char *temp = NULL; - char local_cpy[MAX_SIP_URL_LENGTH]; - string_t hold_to_tag = NULL; - - if (remove_to_tag) { - hold_to_tag = strlib_copy(ccb->sip_to); - - /* remove the to_tag from the 100 Trying message */ - sstrncpy(local_cpy, ccb->sip_to, MAX_SIP_URL_LENGTH); - temp = strstr(local_cpy, ">"); - if (temp != NULL) { - *(temp + 1) = '\0'; - } - ccb->sip_to = strlib_update(ccb->sip_to, local_cpy); - } - - sipSPISendInviteResponse(ccb, SIP_1XX_TRYING, SIP_1XX_TRYING_PHRASE, - 0, NULL, FALSE, /* no SDP */ - FALSE /* no reTx */); - - if (hold_to_tag) { - ccb->sip_to = strlib_update(ccb->sip_to, hold_to_tag); - strlib_free(hold_to_tag); - } -} - - -/* - * Send 180 RINGING - */ -void -sipSPISendInviteResponse180 (ccsipCCB_t *ccb) -{ - sipSPISendInviteResponse(ccb, SIP_1XX_RINGING, - SIP_1XX_RINGING_PHRASE, 0, NULL, - (boolean)(ccb->flags & INBAND_ALERTING), - FALSE /* no reTx */); -} - - -/* - * Send 200 OK - */ -void -sipSPISendInviteResponse200 (ccsipCCB_t *ccb) -{ - sipSPISendInviteResponse(ccb, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE, 0, NULL, - TRUE, TRUE /* reTx */); -} - -void -sipSPISendInviteResponse302 (ccsipCCB_t *ccb) -{ - - sipSPISendInviteResponse(ccb, SIP_RED_MOVED_TEMP, - SIP_RED_MOVED_TEMP_PHRASE, - 0, NULL, FALSE, /* no SDP */ - TRUE /* reTx */); -} - -/*Send Option Response - * - connection is set up. - * Currently just gives the methods supported - * Does not affect call state. -*/ -boolean -sipSPISendOptionResponse (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "SIPSPISendOptionResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - boolean result; - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_ACCEPT_BIT | - SIP_HEADER_ACCEPT_ENCODING_BIT | - SIP_HEADER_ACCEPT_LANGUAGE_BIT | - SIP_HEADER_SUPPORTED_BIT; - - /* Write SDP */ - messageflag.flags |= SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT; - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, SIP_STATUS_SUCCESS, response, - SIP_SUCCESS_SETUP_PHRASE, 0, NULL, sipMethodOptions)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - } - clean_method_request_trx(ccb, sipMethodOptions, FALSE); - return (FALSE); - } - result = sendResponse(ccb, response, request, FALSE, sipMethodOptions); - clean_method_request_trx(ccb, sipMethodOptions, FALSE); - return (result); -} - -/* - * The function below handles an OPTIONS message not associated with - * any ongoing dialog and serves for the phone to gather capabilities - * of its server - */ -boolean -sipSPIsendNonActiveOptionResponse (sipMessage_t *msg, - cc_msgbody_info_t *local_msg_body) -{ - const char *fname = "sipSPIsendNonActiveOptionResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - const char *sip_from = NULL; - const char *sip_to = NULL; - const char *request_callid = NULL; - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - char temp[MAX_SIP_HEADER_LENGTH]; - sipLocation_t *to_loc = NULL; - char sip_to_tag[MAX_SIP_TAG_LENGTH]; - char sip_to_temp[MAX_SIP_URL_LENGTH]; - sipLocation_t *from_loc = NULL; - boolean request_uri_error = FALSE; - sipReqLine_t *requestURI = NULL; - sipLocation_t *uri_loc = NULL; - const char *accept_hdr = NULL; - const char *supported = NULL; - int kpml_config; - - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - - // Parse through the Accept header to get the supported capabilities - accept_hdr = sippmh_get_header_val(msg, SIP_HEADER_ACCEPT, NULL); - if (accept_hdr) { - server_caps = sippmh_parse_accept_header(accept_hdr); - } - - // Parse through the Supported header to get the supported capabilities - supported = sippmh_get_cached_header_val(msg, SUPPORTED); - if (supported) { - sippmh_parse_supported_require(supported, NULL); - } - - response = GET_SIP_MESSAGE(); - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return (FALSE); - } - - sip_from = sippmh_get_cached_header_val(msg, FROM); - sip_to = sippmh_get_cached_header_val(msg, TO); - sstrncpy(sip_to_temp, sip_to, MAX_SIP_URL_LENGTH); - request_callid = sippmh_get_cached_header_val(msg, CALLID); - - requestURI = sippmh_get_request_line(msg); - if (requestURI) { - if (requestURI->url) { - uri_loc = sippmh_parse_from_or_to(requestURI->url, TRUE); - if (uri_loc) { - if (uri_loc->genUrl->schema != URL_TYPE_SIP) { - request_uri_error = TRUE; - } - sippmh_free_location(uri_loc); - } else { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - request_uri_error = TRUE; - } - if (request_uri_error) { - CCSIP_DEBUG_ERROR("%s: Error: Invalid Request URI failed.", fname); - free_sip_message(response); - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return (FALSE); - } - - - /* - * Parse From - */ - from_loc = sippmh_parse_from_or_to((char *)sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - free_sip_message(response); - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return (FALSE); - } - - /* - * From is parsed just to make sure we got valid From - * Header, so we free it now - */ - sippmh_free_location(from_loc); - - /* - * Parse To - */ - to_loc = sippmh_parse_from_or_to((char *)sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - if (response) { - free_sip_message(response); - } - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return (FALSE); - } - - /* Check/Generate tags */ - if (to_loc->tag) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), NULL, - NULL, fname, "Initial Option with to_tag"); - if (response) { - free_sip_message(response); - } - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(to_loc); - return (FALSE); - } else { - sip_util_make_tag(sip_to_tag); - sstrncat(sip_to_temp, ";tag=", - sizeof(sip_to_temp) - strlen(sip_to_temp)); - sstrncat(sip_to_temp, sip_to_tag, - sizeof(sip_to_temp) - strlen(sip_to_temp)); - } - sippmh_free_location(to_loc); - - tflag = sippmh_add_response_line(response, SIP_VERSION, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE); - UPDATE_FLAGS(flag, tflag); - tflag = (sipSPIAddRequestVia(NULL, response, msg, sipMethodOptions)) ? - STATUS_SUCCESS : STATUS_FAILURE; - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_FROM, sip_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_TO, sip_to_temp); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_CALLID, request_callid); - UPDATE_FLAGS(flag, tflag); - - // Add date header - tflag = sipAddDateHeader(response); - UPDATE_FLAGS(flag, tflag); - /* Write CSeq */ - request_cseq = sippmh_get_cached_header_val(msg, CSEQ); - if (request_cseq) { - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - free_sip_message(response); - /* - * We should send 400 here but as we don't have Cseq this - * is not possible. - */ - return FALSE; - } - if (request_cseq_structure->method != sipMethodOptions) { - CCSIP_DEBUG_ERROR("%s: Error: Invalid method in Cseq failed.", - fname); - free_sip_message(response); - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - cpr_free(request_cseq_structure); - return FALSE; - } - tflag = sippmh_add_text_header(response, SIP_HEADER_CSEQ, request_cseq); - cpr_free(request_cseq_structure); - UPDATE_FLAGS(flag, tflag); - } - - tflag = sippmh_add_text_header(response, SIP_HEADER_SERVER, - sipHeaderServer); - - UPDATE_FLAGS(flag, tflag); - - /* - * Add the local sdp we got from gsm into the response - */ - tflag = CopyLocalSDPintoResponse(response, local_msg_body); - UPDATE_FLAGS(flag, tflag); - - // Add Allow - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_REGISTER, SIP_METHOD_UPDATE); - tflag = sippmh_add_text_header(response, SIP_HEADER_ALLOW, temp); - UPDATE_FLAGS(flag, tflag); - - // Add Allow-Events - config_get_value(CFGID_KPML_ENABLED, &kpml_config, sizeof(kpml_config)); - if (kpml_config) { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s", SIP_EVENT_KPML, - SIP_EVENT_DIALOG, SIP_EVENT_REFER); - } else { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s", SIP_EVENT_DIALOG, - SIP_EVENT_REFER); - } - tflag = sippmh_add_text_header(response, SIP_HEADER_ALLOW_EVENTS, temp); - UPDATE_FLAGS(flag, tflag); - - // Add Accept - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s", - SIP_CONTENT_TYPE_SDP, - SIP_CONTENT_TYPE_MULTIPART_MIXED, - SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE); - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT, temp); - UPDATE_FLAGS(flag, tflag); - - // Add Accept-Encoding - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_ENCODING, - "identity"); - UPDATE_FLAGS(flag, tflag); - - // Add Accept-Language - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_LANGUAGE, "en"); - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(response, SIP_HEADER_SUPPORTED, - SIP_RFC_SUPPORTED_TAGS); - - UPDATE_FLAGS(flag, tflag); - - /* Determine from the Via field where the message is supposed - * to be sent - */ - - if (tflag != HSTATUS_SUCCESS) { - free_sip_message(response); - return FALSE; - } - return sendResponse(NULL, response, msg, FALSE, sipMethodOptions); -} - - -/* - * Send the invite response. Adds the session description - * if send_sd is TRUE. Assumes - * - connection is set up. - * Does not affect call state. - */ -void -sipSPISendInviteResponse (ccsipCCB_t *ccb, - uint16_t statusCode, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - boolean send_sd, - boolean retx) -{ - const char *fname = "SIPSPISendInviteResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int rpid_flag; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, statusCode); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_DIVERSION_BIT | - SIP_HEADER_ALLOW_EVENTS_BIT; - - /* Write Content-Type */ - /* Add SDP body if required */ - if (send_sd) { - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - } else { - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - } - if (statusCode == SIP_CLI_ERR_EXTENSION) { - messageflag.flags |= SIP_HEADER_UNSUPPORTED_BIT; - } - if ((statusCode >=SIP_1XX_TRYING) && (statusCode <= SIP_STATUS_SUCCESS)) { - messageflag.flags |= SIP_HEADER_SUPPORTED_BIT; - } - if (statusCode == SIP_SERV_ERR_INTERNAL) { - messageflag.flags |= SIP_HEADER_RETRY_AFTER_BIT; - } - if ((statusCode == SIP_1XX_TRYING) || (statusCode == SIP_STATUS_SUCCESS)) { - messageflag.flags |= SIP_HEADER_RECV_INFO_BIT; - } - - /* - * Set RPID header. - */ - if (statusCode != SIP_1XX_TRYING) { - /* - * The RPID header is not sent in the 100 Trying because the response is directly - * sent from the SIP stack.The information needed for building the RPID is updated - * by the gsm later. - */ - rpid_flag = sipSPISetRPID(ccb, FALSE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - } - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, statusCode, response, reason_phrase, - status_code_warning, reason_phrase_warning, - sipMethodInvite)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - tflag = sipSPIAddCallStats(ccb, response); - - UPDATE_FLAGS(flag, tflag); - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - } - return; - } - - (void) sendResponse(ccb, response, ccb->last_request, retx, sipMethodInvite); - return; -} - - -void -sipSPIGenerateGenAuthorizationResponse (ccsipCCB_t *ccb, - sipMessage_t *request, - sipRet_t *flag, - char *method) -{ - const char *fname = "sipSPIGenerateGenAuthorizationResponse"; - sipRet_t tflag = STATUS_SUCCESS; - char *author_str = NULL; - credentials_t credentials; - - /* - * CSCds70538 - * Re-generate the Authorization header for CANCEL, BYE, mid-INVITE - * The header is cached after an INVITE is challenged. - * I know that I have been challenged preciously because sip_authen - * is not NULL - */ - if (ccb->authen.sip_authen) { - cred_get_line_credentials(ccb->dn_line, &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - if (sipSPIGenerateAuthorizationResponse(ccb->authen.sip_authen, - ccb->ReqURI, method, credentials.id, credentials.pw, - &author_str, &(ccb->authen.nc_count), ccb)) { - - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - - /* - * Don't free the sip_authen since we were not challenged - */ - ccb->authen.authorization = (char *) - cpr_malloc(strlen(author_str) + 1); - - /* - * Cache the Authorization header so that it can be used for later - * requests - */ - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - } - - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Authorization header build " - "unsuccessful\n", fname); - } - } - - if (ccb->authen.authorization != NULL) { - tflag = sippmh_add_text_header(request, - AUTHOR_HDR(ccb->authen.status_code), - ccb->authen.authorization); - UPDATE_FLAGS(*flag, tflag); - } -} - - -/* - * Sends the 202 Refer Accepted . - * Assumes that - * - the connection is setup. - * Will be sent when we get Refer -*/ -boolean -sipSPISendReferResponse202 (ccsipCCB_t *ccb) -{ - const char *fname = "SIPSPISendReferResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - boolean result; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, SIP_ACCEPTED); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_CONTENT_LENGTH_BIT; - - /* Add Content Length */ - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, SIP_ACCEPTED, response, - SIP_ACCEPTED_PHRASE, 0, NULL, sipMethodRefer)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) - free_sip_message(response); - clean_method_request_trx(ccb, sipMethodRefer, FALSE); - return (FALSE); - } - - result = sendResponse(ccb, response, ccb->last_request, FALSE, - sipMethodRefer); - clean_method_request_trx(ccb, sipMethodRefer, FALSE); - return (result); -} - -/* - * General function to send an error response for a given request. - * Does not affect call state or disconnection flags. - * - * Valid values of warn_code is 3xx. Set warn_code to ZERO, when - * warn_code is absent. Use of a valid warn_code, will lead to - * generation of Warning Header in the response. - */ -boolean -sipSPISendErrorResponse (sipMessage_t *msg, - uint16_t status_code, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendErrorResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - const char *sip_from = NULL; - const char *sip_to = NULL; - const char *request_callid = NULL; - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - sipMethod_t method = sipMethodInvalid; - boolean result = FALSE; - char temp[MAX_SIP_HEADER_LENGTH]; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, status_code); - - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - - response = GET_SIP_MESSAGE(); - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return (FALSE); - } - - tflag = sippmh_add_response_line(response, SIP_VERSION, status_code, - reason_phrase) ? STATUS_FAILURE : STATUS_SUCCESS; - - UPDATE_FLAGS(flag, tflag); - - tflag = (sipSPIAddRequestVia(NULL, response, msg, sipMethodInvalid)) ? - STATUS_SUCCESS : STATUS_FAILURE; - UPDATE_FLAGS(flag, tflag); - - sip_from = sippmh_get_cached_header_val(msg, FROM); - sip_to = sippmh_get_cached_header_val(msg, TO); - request_callid = sippmh_get_cached_header_val(msg, CALLID); - tflag = sippmh_add_text_header(response, SIP_HEADER_FROM, sip_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_TO, sip_to); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_CALLID, request_callid); - UPDATE_FLAGS(flag, tflag); - - // Add date header - tflag = sipAddDateHeader(response); - UPDATE_FLAGS(flag, tflag); - - if (reason_phrase_warning) { - char *warning = NULL; - - warning = (char *) cpr_malloc(strlen(reason_phrase_warning) + 5); - if (warning) { - snprintf(warning, strlen(reason_phrase_warning) + 5, - "%d %s", status_code_warning, reason_phrase_warning); - tflag = sippmh_add_text_header(response, SIP_HEADER_WARN, warning); - UPDATE_FLAGS(flag, tflag); - cpr_free(warning); - } - } - - // Add Retry-After, if needed - if (status_code == SIP_SERV_ERR_INTERNAL && - status_code_warning == SIP_WARN_PROCESSING_PREVIOUS_REQUEST) { - tflag = sippmh_add_int_header(response, SIP_HEADER_RETRY_AFTER, - abs((cpr_rand() % 11))); - } - - //Add Accept-Encoding, Accept and Accept-Language headers - //if outgoing response is 415-Unsupported Media Type - if (status_code == SIP_CLI_ERR_MEDIA) { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s", - SIP_CONTENT_TYPE_SDP, - SIP_CONTENT_TYPE_MULTIPART_MIXED, - SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE, - SIP_CONTENT_TYPE_SIPFRAG, - SIP_CONTENT_TYPE_MWI); - // should we add all registered Info Package Content-Type here?? - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT, temp); - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_ENCODING, - SIP_CONTENT_ENCODING_IDENTITY); - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_LANGUAGE, - "en"); - UPDATE_FLAGS(flag, tflag); - } - - if (status_code == SIP_CLI_ERR_NOT_ALLOWED) { - // Add Allow - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_UPDATE, SIP_METHOD_SUBSCRIBE); - tflag = sippmh_add_text_header(response, SIP_HEADER_ALLOW, temp); - UPDATE_FLAGS(flag, tflag); - } - - /* Write CSeq */ - request_cseq = sippmh_get_cached_header_val(msg, CSEQ); - if (request_cseq) { - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - free_sip_message(response); - return (FALSE); - } - tflag = sippmh_add_text_header(response, SIP_HEADER_CSEQ, request_cseq); - method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - UPDATE_FLAGS(flag, tflag); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Did not find valid CSeq header. " - "Cannot send response.\n", fname); - if (response) { - free_sip_message(response); - response = NULL; - } - } - - /* Write Content-Length: 0 */ - tflag = sippmh_add_int_header(response, SIP_HEADER_CONTENT_LENGTH, 0); - UPDATE_FLAGS(flag, tflag); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - response = NULL; - } - } - - /* Determine from the Via field where the message is supposed - * to be sent - */ - if (response) { - result = sendResponse(NULL, response, msg, FALSE, method); - } - if (ccb) { - clean_method_request_trx(ccb, method, FALSE); - } - return (result); -} - -void -sipSPISendFailureResponseAck (ccsipCCB_t *ccb, sipMessage_t *response, - boolean prevcall, line_t previous_call_line) -{ - const char *fname = "sipSPISendFailureResponseAck"; - - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - - char src_addr_str[MAX_IPADDR_STR_LEN]; - static char via[SIP_MAX_VIA_LENGTH]; - char via_branch[SIP_MAX_VIA_LENGTH]; - const char *response_to = NULL; - const char *response_from = NULL; - const char *response_callid = NULL; - const char *response_cseq = NULL; - - cpr_ip_addr_t dest_ipaddr; - cpr_ip_addr_t src_ipaddr; - uint32_t dest_port = 0; - uint32_t cseq_number = 0; - sipCseq_t *response_cseq_structure; - sipMethod_t response_cseq_method = sipMethodInvalid; - sipRespLine_t *respLine = NULL; - int status_code = 0; - char local_ReqURI[MAX_SIP_URL_LENGTH]; - line_t dn_line; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - sipAuthenticate_t authen; - char *author_str = NULL; - int nc_count = 0; - boolean bad_authentication = FALSE; - int16_t trx_index = -1; - line_t line; - int nat_enable = 0; - int reldel_stored_msg = RELDEV_NO_STORED_MSG; - - CPR_IP_ADDR_INIT(dest_ipaddr); - CPR_IP_ADDR_INIT(src_ipaddr); - - if (prevcall) { - dest_ipaddr = gCallHistory[previous_call_line].last_bye_dest_ipaddr; - dest_port = gCallHistory[previous_call_line].last_bye_dest_port; - dn_line = gCallHistory[previous_call_line].dn_line; - sstrncpy(local_ReqURI, - gCallHistory[previous_call_line].last_route_request_uri, - sizeof(local_ReqURI)); - sstrncpy(via_branch, gCallHistory[previous_call_line].via_branch, - sizeof(via_branch)); - } else { - /* - * The ACK to a 300-699 response MUST - * be sent to same address, port, and - * transport to which the original request was sent. - */ - dn_line = ccb->dn_line; - // Get the via_branch from the last request that we sent - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, TRUE); - if (trx_index != -1) { - sstrncpy(via_branch, - (const char *)(ccb->sent_request[trx_index].u.sip_via_branch), - sizeof(via_branch)); - } - // via_branch = (char *) ccb->sip_via_branch; - /* - * Use outbound proxy if we used to send messages for this call, - * we are using the default proxy, we are not using the Emergency - * route, and it is not the backup proxy registration. - */ - if (util_check_if_ip_valid(&(ccb->outBoundProxyAddr)) && - (ccb->proxySelection == SIP_PROXY_DEFAULT) && - (ccb->routeMode != RouteEmergency) && - (ccb->index != REG_BACKUP_CCB)) { - dest_ipaddr = ccb->outBoundProxyAddr; - if (ccb->outBoundProxyPort != 0) { - dest_port = ccb->outBoundProxyPort; - } else { - config_get_value(CFGID_OUTBOUND_PROXY_PORT, &dest_port, - sizeof(dest_port)); - } - } else { - dest_ipaddr = ccb->dest_sip_addr; - dest_port = ccb->dest_sip_port; - } - } - - response_cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!response_cseq) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to obtain request's CSeq " - "header.\n", fname); - return; - } - response_cseq_structure = sippmh_parse_cseq(response_cseq); - if (!response_cseq_structure) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to parse request's CSeq " - "header.\n", fname); - return; - } - cseq_number = response_cseq_structure->number; - response_cseq_method = response_cseq_structure->method; - cpr_free(response_cseq_structure); - - // Process the Failure response - response_to = sippmh_get_cached_header_val(response, TO); - response_from = sippmh_get_cached_header_val(response, FROM); - response_callid = sippmh_get_cached_header_val(response, CALLID); - - request = GET_SIP_MESSAGE(); - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return; - } - - /* - * Determine the Request-URI - */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - if (prevcall == FALSE) { - char tmp_ReqURI[MAX_SIP_URL_LENGTH]; - - // Save original ReqURI - sstrncpy(tmp_ReqURI, ccb->ReqURI, MAX_SIP_URL_LENGTH); - // Update ReqURI using RR, etc - (void) sipSPIGenRequestURI(ccb, sipMethodAck, FALSE); - // Use the ReqURI - sstrncpy(local_ReqURI, ccb->ReqURI, MAX_SIP_URL_LENGTH); - // Restore original ReqURI - sstrncpy(ccb->ReqURI, tmp_ReqURI, MAX_SIP_URL_LENGTH); - - // Clean up the INVITE transaction block as we no longer need it - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - } - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } else { - sip_config_get_nat_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } - - /* - * Build the request - */ - tflag = sippmh_add_request_line(request, SIP_METHOD_ACK, local_ReqURI, - SIP_VERSION); - UPDATE_FLAGS(flag, tflag); - - /* Write Via */ - if (prevcall) { - /* - * Use line 1 as default to get the transport type. - * Transport type is going to be device specific with - * the first release of skittles. Will need to change - * for mixed cc mode support. - */ - line = 1; - } else { - line = ccb->dn_line; - } - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s", - sipTransportGetTransportType(line, TRUE, ccb), - src_addr_str, sipTransportGetListenPort(line, ccb), - VIA_BRANCH, via_branch); - tflag = sippmh_add_text_header(request, SIP_HEADER_VIA, via); - UPDATE_FLAGS(flag, tflag); - - /* Write To, From, and Call-ID standard headers */ - tflag = sippmh_add_text_header(request, SIP_HEADER_FROM, response_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_TO, response_to); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_CALLID, response_callid); - UPDATE_FLAGS(flag, tflag); - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - if (response_cseq_method == sipMethodAck) { - authen.authorization = NULL; - cred_get_line_credentials(dn_line, &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - authenticate = sippmh_get_header_val(response, - AUTH_HDR(status_code), NULL); - if (authenticate != NULL) { - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - if (sipSPIGenerateAuthorizationResponse(sip_authen, - local_ReqURI, - SIP_METHOD_ACK, - credentials.id, - credentials.pw, - &author_str, - &nc_count, NULL)) { - authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - if (authen.authorization != NULL) { - sstrncpy(authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - authen.status_code = status_code; - } else { - CCSIP_DEBUG_ERROR("%s: Error: malloc() failed " - "for authen.authorization\n", - fname); - bad_authentication = TRUE; - } - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR("%s: Error: " - "sipSPIGenerateAuthorizationResponse()" - " returned null.\n", fname); - bad_authentication = TRUE; - } - sippmh_free_authen(sip_authen); - } else { - CCSIP_DEBUG_ERROR("%s: Error: sippmh_parse_authenticate() " - "returned null.\n", fname); - bad_authentication = TRUE; - } - } else { - CCSIP_DEBUG_ERROR("%s: Error: sippmh_get_header_val(AUTH_HDR) " - "returned null.\n", fname); - bad_authentication = TRUE; - } - - if (!bad_authentication) { - tflag = sippmh_add_text_header(request, - AUTHOR_HDR(status_code), - authen.authorization); - cpr_free(authen.authorization); - UPDATE_FLAGS(flag, tflag); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Bad authentication header.", - fname); - if (request) { - free_sip_message(request); - } - if (authen.authorization) { - cpr_free(authen.authorization); - } - return; - } - - } - break; - - default: - break; - } - - /* Write Date header */ - tflag = sipAddDateHeader(request); - UPDATE_FLAGS(flag, tflag); - - /* Write CSeq */ - tflag = sippmh_add_cseq(request, SIP_METHOD_ACK, cseq_number); - UPDATE_FLAGS(flag, tflag); - - /* Add Route Header */ - tflag = (sipSPIAddRouteHeaders(request, ccb, NULL, 0)) ? - STATUS_SUCCESS : STATUS_FAILURE; - - /* Write Content-Length */ - tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - UPDATE_FLAGS(flag, tflag); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - return; - } - /* Store the ACK so that it can be retransmitted in response - * to any duplicate 200 OK or error responses - */ - if ((previous_call_line == 0xFF) && (prevcall == FALSE)) { - CCSIP_DEBUG_ERROR("%s: INFO: Skipping store for this Ack", fname); - } else { - reldel_stored_msg = sipRelDevCoupledMessageStore(request, - response_callid, - cseq_number, - response_cseq_method, - TRUE, - status_code, - &dest_ipaddr, - (int16_t)dest_port, - FALSE /*Do check tag*/); - } - /* Send message */ - if (sipTransportChannelCreateSend(NULL, request, sipMethodAck, - &dest_ipaddr, (int16_t)dest_port, 0, - reldel_stored_msg) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportChannelCreateSend()"); - if (request) - free_sip_message(request); - return; - } - - return; -} - - -/* - * Resend the last message sent - */ -boolean -sipSPISendLastMessage (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendLastMessage"; - - /* Args Check */ - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "ccb"); - return (FALSE); - } - - - /* Send message */ - if (ccb->index == 0) { - if (sipTransportSendMessage(ccb, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipPlatformUISMTimers[ccb->index].message_type, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, - TRUE, TRUE, 0, NULL) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportSendMessage()"); - return (FALSE); - } - } else { - if (sipTransportChannelSend(ccb, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipPlatformUISMTimers[ccb->index].message_type, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, 0) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportChannelSend()"); - return (FALSE); - } - } - return (TRUE); -} - -void -sipGetRequestMethod (sipMessage_t *pRequest, sipMethod_t *pMethod) -{ - const char *fname = "SIPGetRequestMethod"; - sipReqLine_t *pReqLine = NULL; - - *pMethod = sipMethodInvalid; - pReqLine = sippmh_get_request_line(pRequest); - - if (!pReqLine) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_request_line()"); - return; - } - - if (pReqLine->method) { - *pMethod = sippmh_get_method_code(pReqLine->method); - } else { - CCSIP_DEBUG_ERROR("%s: Error: No recognizable method in Req-URI!", - fname); - } - - SIPPMH_FREE_REQUEST_LINE(pReqLine); - return; -} - - -int -sipGetResponseMethod (sipMessage_t *pResponse, sipMethod_t *pMethod) -{ - const char *fname = "SIPGetResponseMethod"; - sipRespLine_t *pRespLine = NULL; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - - pRespLine = sippmh_get_response_line(pResponse); - if (pRespLine) { - cseq = sippmh_get_cached_header_val(pResponse, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (-1); - } - /* Extract method code */ - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (-1); - } - *pMethod = sipCseq->method; - cpr_free(sipCseq); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_response_line()"); - return (-1); - } - - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (0); -} - - -int -sipGetResponseCode (sipMessage_t *pResponse, int *pResponseCode) -{ - const char *fname = "SIPGetResponseCode"; - sipRespLine_t *pRespLine = NULL; - - pRespLine = sippmh_get_response_line(pResponse); - if (pRespLine) { - *pResponseCode = pRespLine->status_code; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_response_line()"); - return (-1); - } - - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (0); -} - - -/* - * Util workhorse to add the standard headers to all SIP messages. - * Does not affect call state. - */ -boolean -sipSPIAddStdHeaders (sipMessage_t *msg, ccsipCCB_t *ccb, boolean isResponse) -{ - boolean retval = FALSE; - boolean flip = TRUE; - int max_fwd = 0; - - if (!(ccb && msg)) { - return (retval); - } - - if (isResponse) { - if (ccb->flags & INCOMING) { - flip = FALSE; - } else { - flip = TRUE; - } - } else { - if (ccb->flags & INCOMING) { - flip = TRUE; - } else { - flip = FALSE; - } - } - - if (!flip) { - retval = (boolean) - ((STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_FROM, - ccb->sip_from)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_TO, - ccb->sip_to)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_CALLID, - ccb->sipCallID))); - } else { - retval = (boolean) - ((STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_FROM, - ccb->sip_to)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_TO, - ccb->sip_from)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_CALLID, - ccb->sipCallID))); - } - - // Add max-forwards header if this is a request - if (isResponse == FALSE && retval == TRUE) { - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_fwd, sizeof(max_fwd)); - if (max_fwd == 0) { - max_fwd = SIP_MAX_FORWARDS_DEFAULT_VALUE; - } - if (sippmh_add_int_header(msg, SIP_HEADER_MAX_FORWARDS, max_fwd) - != STATUS_SUCCESS) { - retval = FALSE; - } - } - return (retval); -} - - -/* - * Add a SIP Via header to the sipMessage_t. - * Should return (TRUE) if the right members are - * present in the CCB struct. - * Does not affect call state. - */ -boolean -sipSPIAddLocalVia (sipMessage_t *msg, ccsipCCB_t *ccb, sipMethod_t method) -{ - const char *fname = "sipSPIAddLocalVia"; - - if (msg && ccb) { - if (util_check_if_ip_valid(&(ccb->src_addr))) { - static char via[SIP_MAX_VIA_LENGTH]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char *sip_via_branch; - int16_t trx_index = -1; - - /* - * We don't allocate a block for ACK(200 OK) although - * it is technically another transaction. Instead we - * locate the INVITE transaction in ccb. - */ - if (method == sipMethodAck) { - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, - TRUE); - } else { - trx_index = get_last_request_trx_index(ccb, TRUE); - } - - if (trx_index < 0) { - return FALSE; - } - ipaddr2dotted(src_addr_str, &ccb->src_addr); - if (method == sipMethodCancel) { - // Get the via header from last sent request transaction - if (trx_index < 1) { - return FALSE; - } - sip_via_branch = strlib_open(ccb->sent_request[trx_index].u.sip_via_branch, - VIA_BRANCH_LENGTH); - sstrncpy(sip_via_branch, (char *)(ccb->sent_request[trx_index - 1].u.sip_via_branch), VIA_BRANCH_LENGTH); - ccb->sent_request[trx_index].u.sip_via_branch = strlib_close(sip_via_branch); - - snprintf(via, sizeof(via), - "SIP/2.0/%s %s:%d;%s=%s", - sipTransportGetTransportType(ccb->dn_line, TRUE, ccb), - src_addr_str, ccb->local_port, VIA_BRANCH, - (char *)(ccb->sent_request[trx_index].u.sip_via_branch)); - - } else { - snprintf(via, sizeof(via), - "SIP/2.0/%s %s:%d;%s=", - sipTransportGetTransportType(ccb->dn_line, TRUE, ccb), - src_addr_str, ccb->local_port, VIA_BRANCH); - - sip_via_branch = strlib_open(ccb->sent_request[trx_index].u.sip_via_branch, - VIA_BRANCH_LENGTH); - if (sip_via_branch) { - snprintf(sip_via_branch, VIA_BRANCH_LENGTH, - "%s%.8x", VIA_BRANCH_START, - (unsigned int)cpr_rand()); - } - ccb->sent_request[trx_index].u.sip_via_branch = - strlib_close(sip_via_branch); - - if (sip_via_branch) { - sstrncat(via, sip_via_branch, - SIP_MAX_VIA_LENGTH - strlen(via)); - } - } - if (sippmh_add_text_header(msg, SIP_HEADER_VIA, via) - != STATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_add_text_header(VIA)"); - return (FALSE); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "ccb->src_addr"); - return (FALSE); - } - } - - return (TRUE); -} - - -/* - * For a response, add the Via headers that came in with the - * request to the response. - */ -boolean -sipSPIAddRequestVia (ccsipCCB_t *ccb, sipMessage_t *response, - sipMessage_t *request, sipMethod_t method) -{ - const char *fname = "sipSPIAddRequestVia"; - int16_t trx_index = -1; - - /* Check args */ - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "response"); - return (FALSE); - } - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "request"); - return (FALSE); - } - - // Get the stored via from the transaction that we are responding to - if (ccb) { - trx_index = get_method_request_trx_index(ccb, method, FALSE); - if (trx_index >= 0) { - (void) sippmh_add_text_header(response, SIP_HEADER_VIA, - (char *)(ccb->recv_request[trx_index].u.sip_via_header)); - return (TRUE); - } - } - - // If no transaction, get the via directly from the request - (void) sippmh_add_text_header(response, SIP_HEADER_VIA, - sippmh_get_cached_header_val(request, VIA)); - - return (TRUE); -} - - -/* - * Procedure to add a Route/Record-Route header in SIP responses - */ -boolean -sipSPIAddRouteHeaders (sipMessage_t *msg, ccsipCCB_t *ccb, - char *result_route, int result_route_length) -{ - const char *fname = "SIPSPIAddRouteHeaders"; - /* NOTE: route will be limited to 4 hops */ - static char route[MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS]; - static char Contact[MAX_SIP_HEADER_LENGTH]; - boolean lr = FALSE; - - /* Check args */ - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "ccb"); - return (FALSE); - } - - if (!ccb->record_route_info) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Route info not available; will not" - " add Route header.\n", DEB_F_PREFIX_ARGS(SIP_ROUTE, fname)); - return (TRUE); - } - - memset(route, 0, MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS); - memset(Contact, 0, MAX_SIP_HEADER_LENGTH); - - if (ccb->flags & INCOMING) { - /* - * For Incoming call (UAS), Copy the RR headers as it is - * If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAS(ccb->record_route_info, route, - sizeof(route), &lr) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAS()"); - return (FALSE); - } - } else { - /* - * For Outgoing call (UAC), Copy the RR headers in the reverse - * order. If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAC(ccb->record_route_info, route, - sizeof(route), &lr) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAC()"); - return (FALSE); - } - } - /* - * If loose_routing is TRUE, then the contact header is NOT appended - * to the Routeset but is instead used in the Req-URI - */ - if (!lr) { - Contact[0] = '\0'; - if (sipSPIGenerateContactHeader(ccb->contact_info, Contact, - sizeof(Contact)) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateContactHeader()"); - return (FALSE); - } - - /* Append Contact to the Route Header, if Contact is available */ - if (Contact[0] != '\0') { - if (route[0] != '\0') { - sstrncat(route, ", ", sizeof(route) - strlen(route)); - } - sstrncat(route, Contact, sizeof(route) - strlen(route)); - } - } - - if (route[0] != '\0') { - if (sippmh_add_text_header(msg, SIP_HEADER_ROUTE, route) - == STATUS_SUCCESS) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Adding route = %s", - DEB_F_PREFIX_ARGS(SIP_ROUTE, fname), route); - if (result_route) { - sstrncpy(result_route, route, result_route_length); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_add_text_header(ROUTE)"); - return (FALSE); - } - } else { - /* Having nothing in Route header is a legal case. - * This would happen when the Record-Route header has - * a single entry and Contact was NULL - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Not adding route", DEB_F_PREFIX_ARGS(SIP_ROUTE, fname)); - } - - return (TRUE); -} - - -boolean -sipSPIAddRequestRecordRoute (sipMessage_t *response, sipMessage_t *request) -{ - const char *fname = "SIPSPIAddRequestRecordRoute"; - - /* Check args */ - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "response"); - return (FALSE); - } - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "request"); - return (FALSE); - } - - (void) sippmh_add_text_header(response, SIP_HEADER_RECORD_ROUTE, - sippmh_get_cached_header_val(request, RECORD_ROUTE)); - - return (TRUE); -} - - -/* - * Procedure to add a proprietary SIP header to carry GUID in the SIP messsage - */ -boolean -sipSPIAddCiscoGuid (sipMessage_t *msg, ccsipCCB_t *ccb) -{ - boolean retval = STATUS_FAILURE; -/* - const char *fname = "sipSPIAddCiscoGuid"; - uint32_t guid[4]; - char guid_char[4*CC_GUID_SIZE]; - - if (ccb && msg) { - - memcpy(&guid[0], ccb->guid, sizeof(guid[0])); - memcpy(&guid[1], &ccb->guid[sizeof(guid[0])], sizeof(guid[0])); - memcpy(&guid[2], &ccb->guid[2*sizeof(guid[0])], sizeof(guid[0])); - memcpy(&guid[3], &ccb->guid[3*sizeof(guid[0])], sizeof(guid[0])); - - sprintf(guid_char, "%u-%u-%u-%u", guid[0], guid[1], guid[2], guid[3]); - - retval = (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_CISCO_GUID, - guid_char)); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Fatal error in parsing ccb.", - fname); - } -*/ - return (retval); -} - -int -sipSPICheckContentHeaders (sipMessage_t *msg) -{ - uint8_t i; - const char *accept_hdr = NULL; - const char *content_enc = NULL; - const char *content_disp_str = NULL; - const char *accepted_enc_str = NULL; - cc_content_disposition_t *content_disp = NULL; - const char *fname = "sipSPICheckContentHeaders"; - sipMethod_t method = sipMethodInvalid; - char *lasts = NULL; - - if (!msg) { - return (SIP_MESSAGING_ERROR); - } - - if (sippmh_msg_header_present(msg, SIP_HEADER_ACCEPT)) { - accept_hdr = sippmh_get_header_val(msg, SIP_HEADER_ACCEPT, NULL); - if (!accept_hdr) { - if (sippmh_is_request(msg)) { - sipGetRequestMethod(msg, &method); - if (method == sipMethodInvite) { - /* - * Currently we are rejecting empty Accept headers for - * INVITE only. This check is done here instead of - * previously because Accept is Content related header - * and also in the future if we want to extend this - * check to other requests and responses this would be - * a good place - */ - return (SIP_MESSAGING_NOT_ACCEPTABLE); - } - } - } - } - content_enc = sippmh_get_header_val(msg, SIP_HEADER_CONTENT_ENCODING, - SIP_C_HEADER_CONTENT_ENCODING); - content_disp_str = sippmh_get_header_val(msg, SIP_HEADER_CONTENT_DISP, - SIP_HEADER_CONTENT_DISP); - accepted_enc_str = sippmh_get_header_val(msg, SIP_HEADER_ACCEPT_ENCODING, - SIP_HEADER_ACCEPT_ENCODING); - if (content_disp_str) { - content_disp = sippmh_parse_content_disposition(content_disp_str); - } - - // Check Content-Encoding - // Only identity encoding is supported at this time - if (content_enc) { - if (cpr_strcasecmp(content_enc, SIP_CONTENT_ENCODING_IDENTITY)) { - // If Content-Encoding is not understood, check to see if - // the Content-Disposition is required. If so, flag an error - if (content_disp) { - if (content_disp->required_handling) { - cpr_free(content_disp); - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } else { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - } - - // Check Content-Disposition - // Only disposition of "session", if not reject if handling it - // content is required - if (content_disp) { - if (content_disp->disposition != cc_disposition_session) { - if (content_disp->required_handling) { - cpr_free(content_disp); - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - } - if (content_disp) { - cpr_free(content_disp); - } - - if (accepted_enc_str) { - //parse the accepted_enc_str - //check to see if it contains "identity" - //if it does not contain "identity" return error - - boolean found = FALSE; - char *ptr = NULL; - char *accepted_enc_str_dup; - - accepted_enc_str_dup = cpr_strdup(accepted_enc_str); - if (accepted_enc_str_dup == NULL) { - CCSIP_DEBUG_ERROR("%s: Error: cpr_strdup() failed " - "for accepted_enc_str_dup\n", fname); - return (SIP_SERV_ERR_INTERNAL); - } - - ptr = PL_strtok_r(accepted_enc_str_dup, ", ", &lasts); - - while (ptr) { - if (strcmp(ptr, SIP_CONTENT_ENCODING_IDENTITY) == 0) { - found = TRUE; - break; - } - ptr = PL_strtok_r(NULL, ", ", &lasts); - } - - cpr_free(accepted_enc_str_dup); - - if (found == FALSE) { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - - - // Check all the body parts - for (i = 0; i < HTTPISH_MAX_BODY_PARTS; i++) { - if (msg->mesg_body[i].msgBody) { - if (msg->mesg_body[i].msgContentTypeValue - == SIP_CONTENT_TYPE_UNKNOWN_VALUE) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Pass-through \"%s\"", - DEB_F_PREFIX_ARGS(SIP_CONTENT_TYPE, fname), - msg->mesg_body[i].msgContentType); - // return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - if ((msg->mesg_body[i].msgContentEnc - != SIP_CONTENT_ENCODING_IDENTITY_VALUE) && - (msg->mesg_body[i].msgRequiredHandling == TRUE)) { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - if ((msg->mesg_body[i].msgContentDisp - != SIP_CONTENT_DISPOSITION_SESSION_VALUE) && - (msg->mesg_body[i].msgRequiredHandling == TRUE)) { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - } - - return (SIP_MESSAGING_OK); -} - -// This function returns TRUE if the header length is acceptable -boolean -is_good_header_length (const char *header, uint8_t header_type) -{ - - if (!header) { - return FALSE; - } - switch (header_type) { - case FROM: - case TO: - if ((strlen(header) >= MAX_SIP_URL_LENGTH) || (strlen(header) == 0)) { - return FALSE; - } - break; - case CALLID: - if ((strlen(header) >= MAX_SIP_CALL_ID) || (strlen(header) == 0)) { - return FALSE; - } - break; - default: - break; - } - return TRUE; -} - -/* - * sipCheckRequestURI - * - * Check the validity of mandatory fields in Req URI - * - * Adding restrictive checks to the following will break - * ccm features: "user=phone" - * - */ -int -sipCheckRequestURI (ccsipCCB_t *ccb, sipMessage_t *request) -{ - sipReqLine_t *requestURI = NULL; - genUrl_t *genUrl = NULL; - sipUrl_t *sipUriUrl = NULL; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char *pUser = NULL; - cpr_ip_addr_t src_addr; - int nat_enable = 0; - boolean request_uri_error = FALSE; - int errorCode = SIP_MESSAGING_ERROR; - cpr_ip_addr_t ipaddr; - - CPR_IP_ADDR_INIT(src_addr); - CPR_IP_ADDR_INIT(ipaddr); - - requestURI = sippmh_get_request_line(request); - if (requestURI) { - if (requestURI->url) { - genUrl = sippmh_parse_url(requestURI->url, TRUE); - if (genUrl) { - if (genUrl->schema == URL_TYPE_SIP) { - sipUriUrl = genUrl->u.sipUrl; - } - if (sipUriUrl) { - pUser = sippmh_parse_user(sipUriUrl->user); - if (pUser) { - if (sipUriUrl->host) { - if (!str2ip(sipUriUrl->host, &ipaddr)) { - config_get_value(CFGID_NAT_ENABLE, &nat_enable, - sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_addr); - } else { - sip_config_get_nat_ipaddr(&src_addr); - } - ipaddr2dotted(src_addr_str, &src_addr); - if (strcmp(sipUriUrl->host, src_addr_str)) { - if (!validateHostName(sipUriUrl->host, pUser)) { - CCSIP_DEBUG_ERROR("Unknown address in Request URI"); - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } - } else { - if (!validateHostName(sipUriUrl->host, pUser)) { - CCSIP_DEBUG_ERROR("Unknown address in Request URI"); - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } - if (sipUriUrl->port_present) { - if (ccb && - cpr_strcasecmp(sipTransportGetTransportType(ccb->dn_line, FALSE, ccb), "udp") == 0) { - if (sipUriUrl->port != ccb->local_port) { - CCSIP_DEBUG_ERROR("Port Mismatch(UDP), URL Port: %d, Port Used: %d", - sipUriUrl->port, ccb->local_port); - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } - } - } - if (pUser[0] == '\0') { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } else { - if (ccb && !request_uri_error) { - sstrncpy(ccb->ReqURI, pUser, - sizeof(ccb->ReqURI)); - } - } - cpr_free(pUser); - } - } - sippmh_genurl_free(genUrl); - } else { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } else { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ERROR; - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ERROR; - } - - if (request_uri_error) { - return errorCode; - } else { - return (SIP_MESSAGING_OK); - } -} - -/* - * This is called for every request received. - * It checks the basic fields(url, From, To). - * Does not affect call state. - * It sends error responses for generic error types. - */ -int -sipSPICheckRequest (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "sipSPICheckRequest"; - const char *callID = NULL; - const char *via = NULL; - const char *from = NULL; - const char *to = NULL; - const char *contact = NULL; - int retval = SIP_MESSAGING_OK; - char *replaceshdr = NULL; - - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - uint32_t request_cseq_number = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - sipReqLine_t *requestURI; - - /* - * Check args - CCB may be NULL - */ - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "request"); - return (SIP_MESSAGING_ERROR); - } - - /* - * Check for the incomplete message body - */ - if (!sippmh_is_message_complete(request)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_is_message_complete()"); - return (SIP_MESSAGING_ERROR); - } - - - if ((retval = sipCheckRequestURI(ccb, request)) != SIP_MESSAGING_OK) { - CCSIP_DEBUG_ERROR("%s: Request URI Not Found", fname); - return (retval); - } - - - /* - * Check whether all mandatory SIP request headers are there. - * Also check if their lengths are within an acceptable range. - */ - from = sippmh_get_cached_header_val(request, FROM); - if (!from || (!is_good_header_length(from, FROM))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(FROM)"); - return (SIP_MESSAGING_ERROR); - } - - to = sippmh_get_cached_header_val(request, TO); - if (!to || (!is_good_header_length(to, TO))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(TO)"); - return (SIP_MESSAGING_ERROR); - } - - via = sippmh_get_cached_header_val(request, VIA); - if (!via) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(VIA)"); - return (SIP_MESSAGING_ERROR); - } - - callID = sippmh_get_cached_header_val(request, CALLID); - if (!callID || (!is_good_header_length(callID, CALLID))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CALLID)"); - return (SIP_MESSAGING_ERROR); - } - - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - int contact_check_result = 0; - - contact_check_result = sipSPICheckContact(contact); - if (contact_check_result < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPICheckContact()"); - return contact_check_result; - } - } - - if ((retval = sipSPICheckContentHeaders(request)) != SIP_MESSAGING_OK) { - CCSIP_DEBUG_ERROR("%s: Content header value not supported", fname); - return (retval); - } - - /* - * Check whether the current call id and this request's CallId match - */ - if (ccb && ccb->sipCallID[0]) { - if (strcmp(ccb->sipCallID, callID) != 0) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Call ID match: new call id.", DEB_F_PREFIX_ARGS(SIP_CALL_ID, fname)); - retval = SIP_MESSAGING_NEW_CALLID; - } else { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Call ID match: same call id.", DEB_F_PREFIX_ARGS(SIP_CALL_ID, fname)); - } - } - - /* - * Parse CSeq - */ - request_cseq = sippmh_get_cached_header_val(request, CSEQ); - if (!request_cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - return (SIP_MESSAGING_ERROR); - } - - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - return (SIP_MESSAGING_ERROR); - } - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - // Check continuity of this request wrt CSeq number and method - if (request_cseq_method != sipMethodAck && - request_cseq_method != sipMethodCancel) { - // If ccb is present, check if the CSeq number is acceptable - if (ccb) { - if (request_cseq_number < ccb->last_recv_request_cseq) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Inconsistent CSEQ number. " - "current= %d, last= %d.\n", - DEB_F_PREFIX_ARGS(SIP_CSEQ, fname), request_cseq_number, - ccb->last_recv_request_cseq); - - return (SIP_CLI_ERR_BAD_REQ); - } - if (request_cseq_number == ccb->last_recv_request_cseq) { - if (request_cseq_method != ccb->last_recv_request_cseq_method) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Inconsistent CSEQ method. " - "current= %s, last= %s\n.", - DEB_F_PREFIX_ARGS(SIP_CSEQ, fname), - sipGetMethodString(request_cseq_method), - sipGetMethodString(ccb->last_recv_request_cseq_method)); - - return (SIP_CLI_ERR_BAD_REQ); - } - } - } - } - - if (request->mesg_line) { - if (strlen(request->mesg_line) >= MAX_SIP_URL_LENGTH) { - CCSIP_DEBUG_ERROR("%s: Request URI length exceeds acceptable value", - fname); - return (SIP_MESSAGING_ERROR); - } - } - - requestURI = sippmh_get_request_line(request); - if (requestURI) { - if (sippmh_get_method_code(requestURI->method) != request_cseq_method) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "Method in RURI != method in CSeq"); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return (SIP_MESSAGING_ERROR); - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - - if (request_cseq_method != sipMethodInvite) { - if (sippmh_msg_header_present(request, SIP_HEADER_REPLACES)) { - CCSIP_DEBUG_ERROR("%s: Error: Replace header is not valid for " - "this request\n", fname); - return SIP_MESSAGING_ERROR; - } - } else { - if (sippmh_get_num_particular_headers(request, SIP_HEADER_REPLACES, - NULL, &replaceshdr, MAX_REPLACES_HEADERS + 1) - > MAX_REPLACES_HEADERS) { - CCSIP_DEBUG_ERROR("%s: Error: More than one replaces header " - "in this request\n", fname); - return SIP_MESSAGING_ERROR; - } - } - - /* - * Reliable Delivery - */ - if (SipRelDevEnabled) { - /* - * responseRecord is a static because the structure it is made out of is - * so large. - */ - static sipRelDevMessageRecord_t requestRecord; - int handle = -1; - const char *reldev_to = NULL; - sipLocation_t *reldev_to_loc = NULL; - char reldev_to_tag[MAX_SIP_TAG_LENGTH]; - const char *reldev_from = NULL; - sipLocation_t *reldev_from_loc = NULL; - char reldev_from_tag[MAX_SIP_TAG_LENGTH]; - - memset(&requestRecord, 0, sizeof(requestRecord)); - memset(reldev_to_tag, 0, MAX_SIP_TAG_LENGTH); - memset(reldev_from_tag, 0, MAX_SIP_TAG_LENGTH); - - /* Get to_tag */ - reldev_to = sippmh_get_cached_header_val(request, TO); - - if (reldev_to) { - reldev_to_loc = sippmh_parse_from_or_to((char *)reldev_to, TRUE); - if (reldev_to_loc) { - if (reldev_to_loc->genUrl->schema != URL_TYPE_SIP) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), - fname); - sippmh_free_location(reldev_to_loc); - return (SIP_CLI_ERR_FORBIDDEN); - } - - if (reldev_to_loc->tag) { - sstrncpy(reldev_to_tag, - sip_sm_purify_tag(reldev_to_loc->tag), - MAX_SIP_TAG_LENGTH); - } - sstrncpy(requestRecord.to_user, - reldev_to_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sippmh_free_location(reldev_to_loc); - - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - return (SIP_MESSAGING_ERROR); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(TO)"); - return (SIP_MESSAGING_ERROR); - } - - /* Store from_user and from_host */ - reldev_from = sippmh_get_cached_header_val(request, FROM); - if (reldev_from) { - reldev_from_loc = sippmh_parse_from_or_to((char *)reldev_from, TRUE); - if (reldev_from_loc) { - sstrncpy(requestRecord.from_user, - reldev_from_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sstrncpy(requestRecord.from_host, - reldev_from_loc->genUrl->u.sipUrl->host, - RELDEV_MAX_HOST_NAME_LEN); - if (reldev_from_loc->tag) { - sstrncpy(reldev_from_tag, - sip_sm_purify_tag(reldev_from_loc->tag), - MAX_SIP_TAG_LENGTH); - } - sippmh_free_location(reldev_from_loc); - } - } - - /* Check whether the tag matches the stored tag */ - if (ccb) { - if ((request_cseq_method == sipMethodInvite) || - (request_cseq_method == sipMethodAck) || - (request_cseq_method == sipMethodBye)) { - - boolean to_tag_match = TRUE; - boolean from_tag_match = TRUE; - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"in_to_tag:<%s>, in_from_tag:<%s>, " - "stored to tag=<%s>, stored from tag=<%s>\n", - DEB_F_PREFIX_ARGS(SIP_TAG, fname), reldev_to_tag, reldev_from_tag, - ccb->sip_to_tag, ccb->sip_from_tag); - - /* Check to_tag first */ - if (ccb->sip_to_tag[0]) { - if ((request_cseq_method == sipMethodBye) && - (reldev_to_tag[0] == '\0') && - (SIP_SM_CALL_SETUP_NOT_COMPLETED(ccb))) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Allow early call termination " - "BYE.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else if ((request_cseq_method == sipMethodInvite) && - (reldev_to_tag[0] == '\0') && - (SIP_SM_CALL_SETUP_NOT_COMPLETED(ccb))) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Allow crossed " - "response and INVITE.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else { - if (ccb->flags & INCOMING) { - // Incoming request for an incoming call - // Match the stored to-tag with the to-tag in request - if (strcasecmp_ignorewhitespace(reldev_to_tag, - ccb->sip_to_tag) != 0) { - to_tag_match = FALSE; - } - } else { - // We made the call, so match the stored to-tag - // with the from-tag in the incoming request - if (strcasecmp_ignorewhitespace(reldev_from_tag, - ccb->sip_to_tag) != 0) { - to_tag_match = FALSE; - } - } - } - } - if (!to_tag_match) { - CCSIP_DEBUG_ERROR("%s: To-Tag mismatch detected!", fname); - return (SIP_CLI_ERR_CALLEG); - } - // Now check from-tag - if (ccb->sip_from_tag[0]) { - if (ccb->flags & INCOMING) { - // Incoming request for an incoming call - // Match the stored from-tag with the from-tag in request - if (strcasecmp_ignorewhitespace(reldev_from_tag, - ccb->sip_from_tag) != 0) { - from_tag_match = FALSE; - } - } else { - // We made the call, so match the stored from-tag - // with the to-tag in the incoming request - if (strcasecmp_ignorewhitespace(reldev_to_tag, - ccb->sip_from_tag) != 0) { - from_tag_match = FALSE; - } - } - if (!from_tag_match) { - CCSIP_DEBUG_ERROR("%s: From-Tag mismatch detected!", - fname); - return (SIP_CLI_ERR_CALLEG); - } - } - } - } - - requestRecord.is_request = TRUE; - sstrncpy(requestRecord.call_id, (callID) ? callID : "", - MAX_SIP_CALL_ID); - requestRecord.cseq_number = request_cseq_number; - requestRecord.cseq_method = request_cseq_method; - sstrncpy(requestRecord.tag, reldev_to_tag, MAX_SIP_TAG_LENGTH); - if (ccb) { - //requestRecord.line = ccb->index; - } else { - //requestRecord.line = 1; - } - if (ccb && (requestRecord.cseq_method == sipMethodInvite) && - (ccb->state == SIP_STATE_IDLE)) { - sipRelDevMessagesClear(requestRecord.call_id, - requestRecord.from_user, - requestRecord.from_host, - requestRecord.to_user); - } - /* Check if duplicate */ - if (sipRelDevMessageIsDuplicate(&requestRecord, &handle)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Duplicate request detected...", DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - // If the request is an ACK we do not have any thing to send - // This was retransmitted ACK so drop it. - if (requestRecord.cseq_method != sipMethodAck) { - if (sipRelDevCoupledMessageSend(handle) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipRelDevCoupledMessageSend()"); - } - } - return (SIP_MESSAGING_DUPLICATE); - } - - /* Record the request in Recent Requests List */ - sipRelDevMessageStore(&requestRecord); - } - return (retval); -} - - -/* - * This is called for every response received. - * It checks the basic fields(response line, From, To). - * If a session description is present, it reads and parses it. - * (and overwrites an old one if present in the CCB.) - * Does not affect call state. - * Returns TRUE if the request is valid. - * Usually, but not necessarily an action function will drop - * an invalid response. Exceptions are usually disconnection states, - * where a bad response may still be accepted. - * - * NOTE: - * It is assumed that this routine would never be called recursively or - * reentered via a separate task because responseRecord is declared as a - * large static variable - */ -int -sipSPICheckResponse (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *fname = "sipSPICheckResponse"; - const char *from = NULL; - const char *to = NULL; - const char *callID = NULL; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - sipRespLine_t *pRespLine = NULL; - uint32_t response_cseq_number = 0; - sipMethod_t response_method = sipMethodInvalid; - uint16_t response_code = 0; - sipStatusCodeClass_t code_class = codeClassInvalid; - int16_t trx_index = -1; - const char *via = NULL; - - /* - * Check for the incomplete message body - */ - if (!sippmh_is_message_complete(response)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_is_message_complete()"); - return (SIP_MESSAGING_ERROR); - } - - /* - * Check whether all mandatory SIP request headers are there. - */ - from = sippmh_get_cached_header_val(response, FROM); - if (!from || (!is_good_header_length(from, FROM))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(FROM)"); - return (SIP_MESSAGING_ERROR); - } - to = sippmh_get_cached_header_val(response, TO); - if (!to || (!is_good_header_length(to, TO))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(TO)"); - return (SIP_MESSAGING_ERROR); - } - callID = sippmh_get_cached_header_val(response, CALLID); - if (!callID || (!is_good_header_length(callID, CALLID))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CALLID)"); - return (SIP_MESSAGING_ERROR); - } - cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - return (SIP_MESSAGING_ERROR); - } - via = sippmh_get_cached_header_val(response, VIA); - if (via) { - if (strchr(via, COMMA)) { - CCSIP_DEBUG_ERROR("%s: Multiple Via headers found in response", - fname); - return (SIP_MESSAGING_ERROR); - } - } - - if (sipSPICheckContentHeaders(response) != SIP_MESSAGING_OK) { - CCSIP_DEBUG_ERROR("%s: Content header value not supported", fname); - return (SIP_MESSAGING_ERROR); - } - - /* - * Get SIP response code - */ - pRespLine = sippmh_get_response_line(response); - if (!pRespLine) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_response_line()"); - return (SIP_MESSAGING_ERROR); - } - response_code = pRespLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - code_class = sippmh_get_code_class(response_code); - - /* - * Extract response method and Cseq number from CSeq - */ - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - return (SIP_MESSAGING_ERROR); - } - response_method = sipCseq->method; - response_cseq_number = sipCseq->number; - cpr_free(sipCseq); - - /* - * If its a authentication response should not do any response - * mismatch checking since some ACK's are not stored and so this - * check will could return response mismatch. - */ - switch (response_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - if (response_method == sipMethodAck) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Authentication Request for ACK: callid=%s," - "cseq=%u, cseq_method=%s\n", - DEB_F_PREFIX_ARGS(SIP_ACK, fname), callID, response_cseq_number, - sipGetMethodString(response_method)); - return (SIP_MESSAGING_OK); - } - break; - - default: - break; - } - - if (sippmh_msg_header_present(response, SIP_HEADER_REPLACES)) { - CCSIP_DEBUG_ERROR("%s: Error: Replace header is not valid " - "in a response\n", fname); - return SIP_MESSAGING_ERROR; - } - - /* - * Reliable Delivery - */ - if (SipRelDevEnabled) { - /* - * responseRecord is a static because the structure it is - * made out of is so large. - */ - static sipRelDevMessageRecord_t responseRecord; - int handle = -1; - sipLocation_t *reldev_to_loc = NULL; - char reldev_to_tag[MAX_SIP_TAG_LENGTH]; - sipLocation_t *reldev_from_loc = NULL; - - memset(&responseRecord, 0, sizeof(responseRecord)); - memset(reldev_to_tag, 0, MAX_SIP_TAG_LENGTH); - - /* Get to_tag */ - reldev_to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (reldev_to_loc) { - if (reldev_to_loc->tag) { - sstrncpy(reldev_to_tag, - sip_sm_purify_tag(reldev_to_loc->tag), - MAX_SIP_TAG_LENGTH); - } else { - reldev_to_tag[0] = '\0'; - } - sstrncpy(responseRecord.to_user, - reldev_to_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sippmh_free_location(reldev_to_loc); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - return (SIP_MESSAGING_ERROR); - } - - reldev_from_loc = sippmh_parse_from_or_to((char *)from, TRUE); - if (reldev_from_loc) { - sstrncpy(responseRecord.from_user, - reldev_from_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sstrncpy(responseRecord.from_host, - reldev_from_loc->genUrl->u.sipUrl->host, - RELDEV_MAX_HOST_NAME_LEN); - - /* Check from-tag */ - if (reldev_from_loc->tag) { - if (!(ccb->flags & INCOMING)) { - if (strcmp(reldev_from_loc->tag, ccb->sip_from_tag) != 0) { - sippmh_free_location(reldev_from_loc); - CCSIP_DEBUG_ERROR("%s: Outgoing: From tag in response " - "does not match stored value\n", - fname); - return (SIP_MESSAGING_ERROR); - } - } else { - if (strcmp(reldev_from_loc->tag, ccb->sip_to_tag) != 0) { - sippmh_free_location(reldev_from_loc); - CCSIP_DEBUG_ERROR("%s: Incoming: From tag in response " - "does not match stored value\n", - fname); - return (SIP_MESSAGING_ERROR); - } - } - } - - sippmh_free_location(reldev_from_loc); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - return (SIP_MESSAGING_ERROR); - } - - responseRecord.is_request = FALSE; - sstrncpy(responseRecord.call_id, (callID) ? callID : "", - MAX_SIP_CALL_ID); - responseRecord.cseq_method = response_method; - responseRecord.cseq_number = response_cseq_number; - responseRecord.response_code = response_code; - sstrncpy(responseRecord.tag, reldev_to_tag, MAX_SIP_TAG_LENGTH); - //responseRecord.line = ccb->index; - - /* Check if duplicate */ - if (sipRelDevMessageIsDuplicate(&responseRecord, &handle)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Duplicate response detected...", DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - if (sipRelDevCoupledMessageSend(handle) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipRelDevCoupledMessageSend()"); - } - if ((response_method == sipMethodInvite) && - (code_class == codeClass1xx)) { - /* Allow multiple provisional responses */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Allowed duplicate provisional response", - DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - } else { - return (SIP_MESSAGING_DUPLICATE); - } - } - /* Record the response in Recent Requests List */ - sipRelDevMessageStore(&responseRecord); - } - - /* - * Check whether the outstanding request's and this response's - * call id, cseq, and cseq method match - */ - trx_index = get_method_request_trx_index(ccb, response_method, TRUE); - if (trx_index < 0) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"No Matching Request Found!:" - "(Response: cseq=%u, trx_method=%s)\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), response_cseq_number, - sipGetMethodString(response_method)); - return (SIP_MESSAGING_ERROR_NO_TRX); - } - if ((ccb->sent_request[trx_index].cseq_number != response_cseq_number) || - (ccb->sent_request[trx_index].cseq_method != response_method) || - (strcmp(ccb->sipCallID, callID) != 0)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Response mismatch:\n(Response:" - "callid=%s, cseq=%u, cseq_method=%s),\n" - "(Request: callid=%s, cseq=%u, " - "cseq_method=%s)\n", - DEB_F_PREFIX_ARGS(SIP_RESP, fname), callID, response_cseq_number, - sipGetMethodString(response_method), - ccb->sipCallID, - ccb->sent_request[trx_index].cseq_number, - sipGetMethodString(ccb->sent_request[trx_index].cseq_method)); - /* - * What happened here is that a timing - * issue occured between the proxy and phone where we - * timed out at almost the same time and we have already - * sent another request(probably a cancel) when the proxy - * sends this response back to us. So that we just Ack this - * response, we play games with previous call fields. We don't - * want to store the information because this response is basically - * stale at this point. We set the prevcall boolean to FALSE - * but we set the previous_line to 0xFF. This will indicate to - * the send routine to skip the storing of this Ack for retransmission. - */ - if (response_method == sipMethodInvite) { - const char *resp_via = NULL; - sipVia_t *resp_via_parm = NULL; - int16_t trx_index_temp = -1; - const char *sip_via_branch = NULL; - - switch (code_class) { - case codeClass2xx: - /* - * If we get 200 response to a cancelled invite, send bye - * to clear up the call. - */ - trx_index_temp = get_method_request_trx_index(ccb, - sipMethodCancel, - TRUE); - // if there is a CANCEL request outstanding - - // if (ccb->last_sent_request_cseq_method == sipMethodCancel) { - if (trx_index_temp > 0) { - const char *contact = NULL; - - /* - * We need to update the contact and to, from tags recvd. - * in ccb because the CANCEL effectively becomes a nop due - * to the race condition where the UAS sent 200 OK to - * INVITE at the same instance we sent CANCEL. Hence we - * need to ACK the 200 OK for INVITE with route header and - * then send a BYE with to tag sent in order to clean up - * the call at the called party - */ - ccb->sip_to = strlib_update(ccb->sip_to, to); - ccb->sip_from = strlib_update(ccb->sip_from, from); - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - sipSPISendFailureResponseAck(ccb, response, FALSE, 0xFF); - sipSPISendBye(ccb, NULL, NULL); - } else { - /* - * No CANCEL was sent, so this is a plain mismatch - * of the CSeq # - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Ignoring response message", - DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - return (SIP_MESSAGING_ERROR); - } - break; - case codeClass4xx: - case codeClass5xx: - case codeClass6xx: - /* - * Locate the branch Parameter. If the branch parameter is - * the same, we are dealing with an outstanding transaction, - * but the response was out of sync with expected. If branch - * parameter is different, the transaction is gone. Ignore - * stray responses - */ - resp_via = sippmh_get_cached_header_val(response, VIA); - if (resp_via) { - resp_via_parm = sippmh_parse_via(resp_via); - if (resp_via_parm) { - /* check for branch param match for transaction */ - if ((resp_via_parm->branch_param) && - (strncmp(resp_via_parm->branch_param, - VIA_BRANCH_START, 7) == 0)) { - trx_index_temp = get_last_request_trx_index(ccb, - TRUE); - if (trx_index_temp != -1) { - sip_via_branch = (char *) - ccb->sent_request[trx_index_temp].u.sip_via_branch; - if (strncmp(resp_via_parm->branch_param, - // (char *) ccb->sip_via_branch, - sip_via_branch, VIA_BRANCH_LENGTH) != 0) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Stray Response: " - "Response branch: %s Request " - "branch: %s\n", DEB_F_PREFIX_ARGS(SIP_RESP, fname), - resp_via_parm->branch_param, - // (char *) ccb->sip_via_branch); - sip_via_branch); - sippmh_free_via(resp_via_parm); - return (SIP_MESSAGING_ERROR_STALE_RESP); - } - } - } - sippmh_free_via(resp_via_parm); - } - } - sipSPISendFailureResponseAck(ccb, response, FALSE, 0xFF); - break; - default: - sipSPISendFailureResponseAck(ccb, response, FALSE, 0xFF); - } - } - return (SIP_MESSAGING_ERROR_STALE_RESP); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Response match: callid=%s, cseq=%u, " - "cseq_method=%s\n", DEB_F_PREFIX_ARGS(SIP_RESP, fname), - callID, response_cseq_number, sipGetMethodString(response_method)); - - - return (SIP_MESSAGING_OK); -} - -/* - * Generate Authorization response - * Concats all the right strings and MD5s the result - */ -boolean -sipSPIGenerateAuthorizationResponse (sip_authen_t *sip_authen, - const char *uri, - const char *method, - const char *user_name, - const char *user_password, - char **author_str, - int *nc_count, - ccsipCCB_t *ccb) -{ - static const char fname[] = "sipSPIGenerateAuthorizationResponse"; - sip_author_t sip_author; - HASHHEX HA1; - HASHHEX HA2 = ""; - char cnonce_str[NONCE_LEN]; - char nc_count_str[NONCE_LEN]; - boolean md5_sess_used; - uint32_t i; - - md5_sess_used = (cpr_strcasecmp(sip_authen->algorithm, "md5-sess") == 0) ? - TRUE : FALSE; - - if ((sip_authen->scheme != SIP_DIGEST) || - (!md5_sess_used && - (cpr_strcasecmp(sip_authen->algorithm, "md5") != 0))) { - CCSIP_DEBUG_ERROR("%s: Error: invalid XXX-Authenticate.", fname); - CCSIP_DEBUG_ERROR(" scheme: %d, algorithm: %s.", sip_authen->scheme, - sip_authen->algorithm); - return (FALSE); - } - - sip_author.response = (char *) cpr_malloc(33 * sizeof(char)); - - /* sip_author has pointers that point to the same data that sip_authen - * points to. Ensure that sip_authen is not freed before sip_author - * is finished. - */ - - sip_author.str_start = NULL; - sip_author.user_pass = (char *) user_password; - sip_author.d_username = (char *) user_name; - sip_author.unparsed_uri = (char *) uri; - sip_author.scheme = sip_authen->scheme; - sip_author.realm = sip_authen->realm; - sip_author.nonce = sip_authen->nonce; - sip_author.algorithm = sip_authen->algorithm; - - sip_author.opaque = sip_authen->opaque; - sip_author.qop = sip_authen->qop; - - /* - * Setup the cnonce and nc_count if qop options are used or if - * md5-sess is the algorithm requested. - */ - if (!md5_sess_used && (sip_authen->qop == NULL)) { - sip_author.cnonce = NULL; - sip_author.nc_count = NULL; - } else { - if (md5_sess_used && (ccb != NULL)) { - if (ccb->authen.cnonce[0] == '\0') { - snprintf(ccb->authen.cnonce, NONCE_LEN, "%8.8x", - (unsigned int)cpr_rand()); - } - sip_author.cnonce = ccb->authen.cnonce; - } else { - snprintf(cnonce_str, NONCE_LEN, "%8.8x", - (unsigned int)cpr_rand()); - sip_author.cnonce = cnonce_str; - } - snprintf(nc_count_str, NONCE_LEN, "%08x", ++(*nc_count)); - sip_author.nc_count = nc_count_str; - } - sip_author.auth_param = NULL; - - DigestCalcHA1(sip_author.algorithm, sip_author.d_username, - sip_author.realm, (char *) user_password, sip_author.nonce, - sip_author.cnonce, HA1); - - /* - * Need to calculate HEntity. - * HEntity is basically just the hash of the SDP. Only the INVITE has SDP - * so we hash the SDP for the INVITE and for other methods we just - * hash the "". - */ - if ((strcmp(method, SIP_METHOD_INVITE) == 0) && (ccb != NULL)) { - /* Use the content from the body saved */ - for (i = 0; i < ccb->local_msg_body.num_parts; i++) { - if (ccb->local_msg_body.parts[i].body != NULL) { - DigestString(ccb->local_msg_body.parts[i].body, HA2); - AUTH_DEBUG(DEB_F_PREFIX"entity body=", DEB_F_PREFIX_ARGS(SIP_MSG, fname)); - } - } - } else { - DigestString("", HA2); - } - - DigestCalcResponse(HA1, sip_author.nonce, sip_author.nc_count, - sip_author.cnonce, sip_author.qop, - (char *)method, //SIP_METHOD_REGISTER, - sip_author.unparsed_uri, HA2, sip_author.response); - - *author_str = sippmh_generate_authorization(&sip_author); - - cpr_free(sip_author.response); - - return (TRUE); -} - - -/* - * Generates Route Headers for UAC - * Pops the first RR entry and puts in Req Line - * Copies the rest of RR entries in reverse order into Route Header - * Appends Contact Header at the end of Route - * header - * If the first route entry has loose routing,"lr", set. does not add the - * Contact Header to the end of Route, and does not pop the first entry. - * In this case, indicates loose - * routing to caller so that they may add the Contact to the Req-URI - * instead - */ -boolean -sipSPIGenerateRouteHeaderUAC (sipRecordRoute_t *rr_info, - char *route, - int route_str_len, - boolean *loose_routing) -{ - boolean retval = FALSE; - int i, j, start, limit; - static char temp_route[MAX_SIP_HEADER_LENGTH]; - sipUrl_t *url_info = NULL; - genUrl_t *gen; - boolean lr = FALSE; - char url[SIPS_URL_LEN]; - - if (route == NULL) { - return retval; - } - - start = rr_info->num_locations - 1; - limit = 0; - route[0] = '\0'; - - for (i = start; i >= limit; i--) { - url_info = rr_info->locations[i]->genUrl->u.sipUrl; - if (i == start) { - if (url_info->lr_flag == FALSE) { - // Skip the first entry if lr flag is not set - continue; - } else { - lr = TRUE; - } - } - if (rr_info->locations[i]->genUrl->sips) { - snprintf(url, sizeof(url), "sips"); - } else { - snprintf(url, sizeof(url), "sip"); - } - temp_route[0] = '\0'; - if (url_info->user == NULL) { - snprintf(temp_route, sizeof(temp_route), - "<%s:%s:%d", url, url_info->host, url_info->port); - } else { - if (url_info->password) { - snprintf(temp_route, sizeof(temp_route), "<%s:%s:%s@%s:%d", - url, url_info->user, url_info->password, - url_info->host, url_info->port); - } else { - snprintf(temp_route, sizeof(temp_route), "<%s:%s@%s:%d", - url, url_info->user, url_info->host, url_info->port); - } - } - if (url_info->maddr) { - /*static */ char maddr[MAX_SIP_HEADER_LENGTH]; - - snprintf(maddr, sizeof(maddr), ";maddr=%s", url_info->maddr); - sstrncat(temp_route, maddr, - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->ttl_val) { - /*static */ char ttl[MAX_SIP_HEADER_LENGTH]; - - snprintf(ttl, sizeof(ttl), ";ttl=%d", url_info->ttl_val); - sstrncat(temp_route, ttl, - sizeof(temp_route) - strlen(temp_route)); - } - - switch (url_info->transport) { - case TRANSPORT_UDP: - sstrncat(temp_route, ";transport=udp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TCP: - sstrncat(temp_route, ";transport=tcp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TLS: - sstrncat(temp_route, ";transport=tls", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_SCTP: - sstrncat(temp_route, ";transport=sctp", - sizeof(temp_route) - strlen(temp_route)); - break; - } - - if (url_info->is_phone) { - sstrncat(temp_route, ";user=phone", - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->lr_flag) { - sstrncat(temp_route, ";lr", - sizeof(temp_route) - strlen(temp_route)); - } - - j = 0; - gen = rr_info->locations[i]->genUrl; - - while (j < SIP_MAX_LOCATIONS) { - if (gen->other_params[j] != NULL) { - sstrncat(temp_route, ";", - sizeof(temp_route) - strlen(temp_route)); - sstrncat(temp_route, gen->other_params[j], - sizeof(temp_route) - strlen(temp_route)); - break; - } - j++; - } - - if (i > limit) { - sstrncat(temp_route, ">,", - sizeof(temp_route) - strlen(temp_route)); - } else { - sstrncat(temp_route, ">", - sizeof(temp_route) - strlen(temp_route)); - } - - sstrncat(route, temp_route, route_str_len - strlen(route)); - - } - - *loose_routing = lr; - retval = TRUE; - return retval; -} - -/* - * Generates Route Headers for UAS - * Pops the first RR entry and puts in Req Line - * Copies the rest of RR entries into Route Header - * Appends Contact Header at the end of Route - * header - */ -boolean -sipSPIGenerateRouteHeaderUAS (sipRecordRoute_t *rr_info, - char *route, - int route_str_len, - boolean *loose_routing) -{ - const char *fname = "sipSPIGenerateRouteHeaderUAS"; - boolean retval = FALSE; - int i, j, start, limit; - static char temp_route[MAX_SIP_HEADER_LENGTH]; - sipUrl_t *url_info; - genUrl_t *gen; - boolean lr = FALSE; - char url[SIPS_URL_LEN]; - - if (route == NULL) { - return (retval); - } - - start = 0; - limit = rr_info->num_locations - 1; - route[0] = '\0'; - - for (i = start; i <= limit; i++) { - if (rr_info->locations[i]->genUrl->schema == URL_TYPE_SIP) { - url_info = rr_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - return (FALSE); - } - if (i == start) { - if (url_info->lr_flag == FALSE) { - // don't add the first route, if the lr flag is not set - continue; - } else { - lr = TRUE; - } - } - if (rr_info->locations[i]->genUrl->sips) { - snprintf(url, sizeof(url), "sips"); - } else { - snprintf(url, sizeof(url), "sip"); - } - temp_route[0] = '\0'; - if (url_info->user == NULL) { - snprintf(temp_route, sizeof(temp_route), - "<%s:%s:%d", url, url_info->host, url_info->port); - } else { - if (url_info->password) { - snprintf(temp_route, sizeof(temp_route), "<%s:%s:%s@%s:%d", - url, url_info->user, - url_info->password, url_info->host, url_info->port); - } else { - snprintf(temp_route, sizeof(temp_route), "<%s:%s@%s:%d", - url, url_info->user, url_info->host, url_info->port); - } - } - - if (url_info->maddr) { - /*static */ char maddr[MAX_SIP_HEADER_LENGTH]; - - snprintf(maddr, sizeof(maddr), ";maddr=%s", url_info->maddr); - sstrncat(temp_route, maddr, - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->ttl_val) { - /*static */ char ttl[MAX_SIP_HEADER_LENGTH]; - - snprintf(ttl, sizeof(ttl), ";ttl=%d", url_info->ttl_val); - sstrncat(temp_route, ttl, - sizeof(temp_route) - strlen(temp_route)); - } - - switch (url_info->transport) { - case TRANSPORT_UDP: - sstrncat(temp_route, ";transport=udp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TCP: - sstrncat(temp_route, ";transport=tcp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TLS: - sstrncat(temp_route, ";transport=tls", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_SCTP: - sstrncat(temp_route, ";transport=sctp", - sizeof(temp_route) - strlen(temp_route)); - break; - } - - if (url_info->is_phone) { - sstrncat(temp_route, ";user=phone", - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->lr_flag) { - sstrncat(temp_route, ";lr", - sizeof(temp_route) - strlen(temp_route)); - } - - j = 0; - gen = rr_info->locations[i]->genUrl; - - while (j < SIP_MAX_LOCATIONS) { - if (gen->other_params[j] != NULL) { - sstrncat(temp_route, ";", - sizeof(temp_route) - strlen(temp_route)); - sstrncat(temp_route, gen->other_params[j], - sizeof(temp_route) - strlen(temp_route)); - break; - } - j++; - } - - if (i < limit) { - sstrncat(temp_route, ">,", - sizeof(temp_route) - strlen(temp_route)); - } else { - sstrncat(temp_route, ">", - sizeof(temp_route) - strlen(temp_route)); - } - sstrncat(route, temp_route, route_str_len - strlen(route)); - } - - *loose_routing = lr; - retval = TRUE; - return (retval); -} - -/* - * This function regenerates the Contact Header - * from the parsed information stored in CCB - */ -boolean -sipSPIGenerateContactHeader (sipContact_t *contact_info, - char *contact, - int len) -{ - const char *fname = "sipSPIGenerateContactHeader"; - boolean retval = FALSE; - sipUrl_t *sipUrl; - - if (contact == NULL) { - return (retval); - } - - if (contact_info == NULL) { - contact[0] = '\0'; - retval = TRUE; - return (retval); - } - - if (contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - sipUrl = contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - return (FALSE); - } - - if (sipUrl->user == NULL) { - snprintf(contact, len, "host, sipUrl->port); - } else { - if ((sipUrl->password) && (*(sipUrl->password))) { - snprintf(contact, len, "user, - sipUrl->password, sipUrl->host, sipUrl->port); - } else { - snprintf(contact, len, "user, - sipUrl->host, sipUrl->port); - } - } - - /* Assume contact length is the same for all clients */ - - if (sipUrl->maddr) { - /*static */ char maddr[MAX_SIP_HEADER_LENGTH]; - - snprintf(maddr, sizeof(maddr), ";maddr=%s", sipUrl->maddr); - sstrncat(contact, maddr, len - strlen(contact)); - } - - if (sipUrl->ttl_val) { - /*static */ char ttl[MAX_SIP_HEADER_LENGTH]; - - snprintf(ttl, sizeof(ttl), ";ttl=%d", sipUrl->ttl_val); - sstrncat(contact, ttl, len - strlen(contact)); - } - - switch (sipUrl->transport) { - case TRANSPORT_UDP: - sstrncat(contact, ";transport=udp", len - strlen(contact)); - break; - case TRANSPORT_TCP: - sstrncat(contact, ";transport=tcp", len - strlen(contact)); - break; - case TRANSPORT_TLS: - sstrncat(contact, ";transport=tls", len - strlen(contact)); - break; - case TRANSPORT_SCTP: - sstrncat(contact, ";transport=sctp", len - strlen(contact)); - break; - } - - if (sipUrl->is_phone) { - sstrncat(contact, ";user=phone", len - strlen(contact)); - } - - sstrncat(contact, ">", len - strlen(contact)); - retval = TRUE; - return (retval); -} - - -char * -sipSPIUrlDestination (sipUrl_t *sipUrl) -{ - return ((sipUrl->maddr) ? sipUrl->maddr : sipUrl->host); -} - - -int -sipSPICheckContact (const char *contact) -{ - const char *fname = "sipSPICheckContact"; - sipContact_t *contact_info = NULL; - int result = 0; - - contact_info = sippmh_parse_contact(contact); - if (contact_info) { - if (contact_info->locations[0]->genUrl->schema != URL_TYPE_SIP) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - sippmh_free_contact(contact_info); - return (-1); - } - - sippmh_free_contact(contact_info); - } - - return (result); -} - - -sipRet_t -sipAddDateHeader (sipMessage_t *sip_message) -{ - char sip_date[MAX_SIP_DATE_LENGTH]; - cpr_time_t timestamp; - struct tm ts; - - (void) time((time_t *)×tamp); - - (void) gmtime_r((time_t *)×tamp, &ts); - - if (strftime(sip_date, MAX_SIP_DATE_LENGTH, "%a, %d %b %Y %H:%M:%S GMT", &ts) - == 0) { - /* If defined, allow for a failure if unable to create date header */ - return STATUS_FAILURE; - } - - return sippmh_add_text_header(sip_message, SIP_HEADER_DATE, sip_date); -} - -int -sipGetMessageCSeq (sipMessage_t *pMessage, - uint32_t *pResultCSeqNumber, - sipMethod_t *pResultCSeqMethod) -{ - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - - cseq = sippmh_get_cached_header_val(pMessage, CSEQ); - if (!cseq) { - return (-1); - } - - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - return (-1); - } - - *pResultCSeqNumber = sipCseq->number; - *pResultCSeqMethod = sipCseq->method; - - cpr_free(sipCseq); - return (0); -} - - -void -sipGetMessageToTag (sipMessage_t *pMessage, char *to_tag, - int to_tag_max_length) -{ - const char *to = NULL; - sipLocation_t *to_loc = NULL; - - memset(to_tag, 0, to_tag_max_length); - //For self generated methods (i.e. outgoing), the TO HEADER - //may not be in the cached area of the message structue. - to = sippmh_get_cached_header_val(pMessage, TO); - if (!to) { - to = sippmh_get_header_val(pMessage, SIP_HEADER_TO, SIP_C_HEADER_TO); - } - - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->tag) { - sstrncpy(to_tag, sip_sm_purify_tag(to_loc->tag), - to_tag_max_length); - } - sippmh_free_location(to_loc); - } - } - - return; -} - - -boolean -sipSPISendByeAuth (sipMessage_t *pResponse, - sipAuthenticate_t authen, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - uint32_t cseq_number, - char *alsoString, - char *last_call_route, - char *last_call_route_request_uri, - line_t previous_call_line) -{ - const char *fname = "sipSPISendByeAuth"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - const char *response_contact = NULL; - const char *response_record_route = NULL; - const char *response_to = NULL; - const char *response_from = NULL; - const char *response_callid = NULL; - sipContact_t *response_contact_info = NULL; - sipRecordRoute_t *response_record_route_info = NULL; - - cpr_ip_addr_t request_uri_addr; - uint16_t request_uri_port = 0; - cpr_ip_addr_t src_ipaddr; - char src_addr_str[MAX_IPADDR_STR_LEN]; - static char ReqURI[MAX_SIP_URL_LENGTH]; - static char via[SIP_MAX_VIA_LENGTH]; - ccsipCCB_t *ccb = NULL; - int timeout = 0; - sipLocation_t *request_uri_loc = NULL; - sipUrl_t *request_uri_url = NULL; - sipUrl_t *sipUrl = NULL; - int i = 0; - int nat_enable = 0; - - CPR_IP_ADDR_INIT(request_uri_addr); - CPR_IP_ADDR_INIT(src_ipaddr); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "BYE(Auth)"); - - request = GET_SIP_MESSAGE(); - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return (FALSE); - } - - /* Init temp ccb to ccbs[previous_call_line] */ - ccb = &gGlobInfo.ccbs[previous_call_line]; - if (ccb->state != SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - CCSIP_DEBUG_ERROR("%s: Error: ccb %d is not in " - "SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING state.\n", - fname, previous_call_line); - free_sip_message(request); - return (FALSE); - } - ccb->contact_info = NULL; - ccb->record_route_info = NULL; - ccb->flags = 0; - - response_contact = sippmh_get_cached_header_val(pResponse, CONTACT); - response_record_route = - sippmh_get_cached_header_val(pResponse, RECORD_ROUTE); - response_to = sippmh_get_cached_header_val(pResponse, TO); - response_from = sippmh_get_cached_header_val(pResponse, FROM); - response_callid = sippmh_get_cached_header_val(pResponse, CALLID); - - if (response_contact) { - response_contact_info = sippmh_parse_contact(response_contact); - ccb->contact_info = response_contact_info; - } - if (response_record_route) { - response_record_route_info = - sippmh_parse_record_route(response_record_route); - ccb->record_route_info = response_record_route_info; - } - - /* - * Determine the Request-URI - */ - memset(ReqURI, 0, sizeof(ReqURI)); - if (response_record_route_info) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using 401/407's Record-Route", - DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - i = response_record_route_info->num_locations - 1; - if (response_record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = response_record_route_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - free_sip_message(request); - return (FALSE); - } - - request_uri_port = sipUrl->port; - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &request_uri_addr, - &request_uri_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &request_uri_addr, 100, 1); - } - if (dns_error_code == 0) { - util_ntohl(&request_uri_addr, &request_uri_addr); - - } else { - request_uri_addr = ip_addr_invalid; - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", sipUrl->user, sipUrl->host, - sipUrl->port); - } - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%d;user=phone" : "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else if (last_call_route[0] && last_call_route_request_uri[0]) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using current Route " - "information.\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - sstrncpy(ReqURI, last_call_route_request_uri, sizeof(ReqURI)); - request_uri_addr = *dest_ipaddr; - request_uri_port = dest_port; - } else if (response_contact_info) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using Contact", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (response_contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - sipUrl = response_contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - free_sip_message(request); - return (FALSE); - } - - request_uri_port = sipUrl->port; - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &request_uri_addr, - &request_uri_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &request_uri_addr, 100, 1); - } - if (dns_error_code == 0) { - - util_ntohl(&request_uri_addr, &request_uri_addr); - } else { - request_uri_addr = ip_addr_invalid; - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", sipUrl->user, - sipUrl->host, sipUrl->port); - } - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%d;user=phone" : "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else { - request_uri_addr = *dest_ipaddr; - request_uri_port = dest_port; - request_uri_loc = sippmh_parse_from_or_to((char *)response_to, TRUE); - if (!request_uri_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - free_sip_message(request); - return (FALSE); - } - - if (!sippmh_valid_url(request_uri_loc->genUrl)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_valid_url()"); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Caller): using original " - "Req-URI\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (request_uri_loc->name) { - if (request_uri_loc->name[0]) { - sstrncat(ReqURI, "\"", sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, request_uri_loc->name, - sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, "\" ", sizeof(ReqURI) - strlen(ReqURI)); - } - } - sstrncat(ReqURI, "sip:", sizeof(ReqURI) - strlen(ReqURI)); - if (request_uri_loc->genUrl->schema == URL_TYPE_SIP) { - request_uri_url = request_uri_loc->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - if (request_uri_url->user) { - sstrncat(ReqURI, request_uri_url->user, - sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, "@", sizeof(ReqURI) - strlen(ReqURI)); - } - if (request_uri_url->is_phone) { - sstrncat(ReqURI, ";user=phone", - sizeof(ReqURI) - strlen(ReqURI)); - } - sstrncat(ReqURI, request_uri_url->host, - sizeof(ReqURI) - strlen(ReqURI)); - sippmh_free_location(request_uri_loc); - } - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } else { - sip_config_get_nat_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } - - /* - * Build the request - */ - - /* Write Req-URI */ - tflag = sippmh_add_request_line(request, SIP_METHOD_BYE, ReqURI, - SIP_VERSION); - UPDATE_FLAGS(flag, tflag); - - /* Write Via */ - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(ccb->dn_line, TRUE, ccb), - src_addr_str, - ccb->local_port, - VIA_BRANCH, VIA_BRANCH_START, - (unsigned int)cpr_rand()); - tflag = sippmh_add_text_header(request, SIP_HEADER_VIA, via); - UPDATE_FLAGS(flag, tflag); - - /* Write To, From, and Call-ID standard headers */ - tflag = sippmh_add_text_header(request, SIP_HEADER_FROM, response_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_TO, response_to); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_CALLID, response_callid); - UPDATE_FLAGS(flag, tflag); - - /* Write Date header */ - tflag = sipAddDateHeader(request); - UPDATE_FLAGS(flag, tflag); - - /* Write User Agent header */ - tflag = sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - UPDATE_FLAGS(flag, tflag); - - /* add in call stats header if needed */ - tflag = sipSPIAddCallStats(ccb, request); - UPDATE_FLAGS(flag, tflag); - - /* Write Route */ - if (response_record_route_info) { - tflag = (sipSPIAddRouteHeaders(request, ccb, NULL, 0)) ? - STATUS_SUCCESS : STATUS_FAILURE; - } else if (last_call_route[0]) { - tflag = sippmh_add_text_header(request, SIP_HEADER_ROUTE, - last_call_route); - } - UPDATE_FLAGS(flag, tflag); - - /* Free contact and record-route */ - if (response_contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - } - if (response_record_route) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - } - - /* Write CSeq */ - tflag = sippmh_add_cseq(request, SIP_METHOD_BYE, cseq_number); - UPDATE_FLAGS(flag, tflag); - - if (alsoString) { - if (alsoString[0]) { - tflag = sippmh_add_text_header(request, SIP_HEADER_ALSO, - alsoString); - UPDATE_FLAGS(flag, tflag); - } - } - - if (authen.authorization != NULL) { - tflag = sippmh_add_text_header(request, AUTHOR_HDR(authen.status_code), - authen.authorization); - UPDATE_FLAGS(flag, tflag); - cpr_free(authen.authorization); - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - return (FALSE); - } - - /* Send message */ - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - ccb->retx_counter = 0; - if (sipTransportChannelCreateSend(ccb, request, sipMethodBye, - &request_uri_addr, - request_uri_port, timeout, - RELDEV_NO_STORED_MSG) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportChannelCreateSend()"); - if (request) - free_sip_message(request); - - return (FALSE); - } - return (TRUE); -} - -void -free_sip_message (sipMessage_t *message) -{ - if (message) { - sippmh_message_free(message); - } -} - -/* - * Generate the full URL (currently limited to the sipUrl only) - */ -void -sipSPIGenerateTargetUrl (genUrl_t *genUrl, char *sipurlstr) -{ - uint8_t i; - char temp[MAX_SIP_HEADER_LENGTH]; - size_t url_length = 0; - char *right_bracket = NULL; - boolean right_bracket_removed = FALSE; - - if (genUrl->schema == URL_TYPE_SIP) { - sipSPIGenerateSipUrl(genUrl->u.sipUrl, sipurlstr); - } else { - return; - } - - url_length = strlen(sipurlstr); - if (url_length == 0) { - return; - } - - for (i = 0; i < SIP_MAX_LOCATIONS; i++) { - if (genUrl->other_params[i] != NULL) { - if (i == 0) { - // Remove the ">" from the end of sipurlstr - right_bracket = strchr(sipurlstr, '>'); - if (right_bracket) { - *right_bracket = '\0'; - right_bracket_removed = TRUE; - } - } - snprintf(temp, sizeof(temp), ";%s", genUrl->other_params[i]); - sstrncat(sipurlstr, temp, MAX_SIP_URL_LENGTH - url_length ); - url_length = strlen(sipurlstr); - } - } - - if (right_bracket_removed) { - sstrncat(sipurlstr, ">", MAX_SIP_URL_LENGTH - url_length); - } -} - -/* - * Generates a plain string from sipUrl structure - * -*/ -void -sipSPIGenerateSipUrl (sipUrl_t *sipUrl, char *sipurlstr) -{ - char temp[MAX_SIP_HEADER_LENGTH]; - - if (sipUrl->user == NULL) { - snprintf(sipurlstr, MAX_SIP_HEADER_LENGTH, "host, sipUrl->port); - } else { - snprintf(sipurlstr, MAX_SIP_HEADER_LENGTH, "user, sipUrl->host, sipUrl->port); - } - - /* Assume sipurlstr _length is the same for all clients */ - - if (sipUrl->maddr) { - snprintf(temp, sizeof(temp), ";maddr=%s", sipUrl->maddr); - sstrncat(sipurlstr, temp, MAX_SIP_HEADER_LENGTH ); - } - - if (sipUrl->ttl_val) { - snprintf(temp, sizeof(temp), ";ttl=%d", sipUrl->ttl_val); - sstrncat(sipurlstr, temp, MAX_SIP_HEADER_LENGTH); - } - - switch (sipUrl->transport) { - case TRANSPORT_UDP: - sstrncat(sipurlstr, ";transport=udp", MAX_SIP_HEADER_LENGTH); - break; - case TRANSPORT_TCP: - sstrncat(sipurlstr, ";transport=tcp", MAX_SIP_HEADER_LENGTH); - break; - case TRANSPORT_TLS: - sstrncat(sipurlstr, ";transport=tls", MAX_SIP_HEADER_LENGTH); - break; - case TRANSPORT_SCTP: - sstrncat(sipurlstr, ";transport=sctp", MAX_SIP_HEADER_LENGTH); - break; - } - - if (sipUrl->is_phone) { - sstrncat(sipurlstr, ";user=phone", MAX_SIP_HEADER_LENGTH); - } - - sstrncat(sipurlstr, ">", MAX_SIP_HEADER_LENGTH); - -} - -#define MAX_SIP_METHOD_STRINGS 17 -#define MAX_SIP_METHOD_STRING_LEN 16 -const char * -sipGetMethodString (sipMethod_t methodname /*, char *methodstring */) -{ - int ino = (int) methodname; //Register is defined as 100 in pmh.h file - //Please make sure the following array is consistent with the enum - int idx = 0; - static const char methods[MAX_SIP_METHOD_STRINGS][MAX_SIP_METHOD_STRING_LEN] = - { "REGISTER", "OPTIONS", "INVITE", "BYE", - "CANCEL", "PRACK", "COMET", "NOTIFY", - "REFER", "ACK", "MESSAGE", "SUBSCRIBE", - "PUBLISH", "UPDATE", "RESPONSE", "INFO", "UNKNOWN" - }; - - - idx = ino - (int) sipMethodRegister; - if (idx >= 0 && idx <= (int) (sizeof(methods) / sizeof(methods[0]) - 1)) { - return methods[idx]; // Its OK to send this as it is a static array - } else { - return NULL; - } -} - -sipRet_t -sipSPIAddRequestLine (ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t methodname, boolean initInvite) -{ - sipRet_t tflag = STATUS_FAILURE; - - if (TRUE == sipSPIGenRequestURI(ccb, methodname, initInvite)) { - tflag = sippmh_add_request_line(request, - sipGetMethodString(methodname), - ccb->ReqURI, - SIP_VERSION); - } else { - tflag = STATUS_FAILURE; - } - return tflag; -} - -boolean -getCSeqInfo (sipMessage_t *request, sipCseq_t ** request_cseq_structure) -{ - const char *request_cseq = NULL; - - request_cseq = sippmh_get_cached_header_val(request, CSEQ); - if (!request_cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "AddCSeq in Factory", - "sippmh_get_cached_header_val()"); - return (FALSE); - } - *request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!*request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "AddCSeq in Factory", - "sippmh_parse_cseq()"); - return (FALSE); - } - return TRUE; -} - -// Allocate an outgoing transaction and fill in the cseq number and method -boolean -allocateTrx (ccsipCCB_t *ccb, sipMethod_t method) -{ - uint32_t trx_cseq_number = 0; - int16_t new_trx_index = -1, last_trx_index = -1; - - if (method == sipMethodCancel) { - // For CANCEL, the cseq is the same as the cseq - // of the earlier sent request that it cancels - last_trx_index = get_last_request_trx_index(ccb, TRUE); - if (last_trx_index < 0) { - return FALSE; - } - trx_cseq_number = ccb->sent_request[last_trx_index].cseq_number; - // Now allocate a new CSeq for the CANCEL request itself - new_trx_index = get_next_request_trx_index(ccb, TRUE); - if (new_trx_index < 0) { - return FALSE; - } - ccb->sent_request[new_trx_index].cseq_number = trx_cseq_number; - ccb->sent_request[new_trx_index].cseq_method = sipMethodCancel; - - } else if (method != sipMethodAck) { - // No new transaction is needed for Ack - new_trx_index = get_next_request_trx_index(ccb, TRUE); - if (new_trx_index < 0) { - return FALSE; - } - ccb->sent_request[new_trx_index].cseq_number = ++(ccb->last_used_cseq); - ccb->sent_request[new_trx_index].cseq_method = method; - } - return TRUE; -} - -boolean -AddCSeq (ccsipCCB_t *ccb, - sipMessage_t *request, - boolean isResponse, - sipMethod_t method, - uint32_t response_cseq_number) -{ - uint32_t request_cseq_number = 0; - sipRet_t tflag = STATUS_FAILURE; - int16_t trx_index = -1; - - if (TRUE == isResponse) { - if (response_cseq_number == 0) { - trx_index = get_method_request_trx_index(ccb, method, FALSE); - if (trx_index != -1) { - request_cseq_number = ccb->recv_request[trx_index].cseq_number; - } else { - return FALSE; - } - } else { - request_cseq_number = response_cseq_number; - } - } else { - // For Request - if (method == sipMethodAck) { - request_cseq_number = response_cseq_number; - } else { - // Pull up the previously allocated transaction - trx_index = get_last_request_trx_index(ccb, TRUE); - if (trx_index < 0) { - return FALSE; - } - request_cseq_number = ccb->sent_request[trx_index].cseq_number; - } - } - tflag = sippmh_add_cseq(request, sipGetMethodString(method), - request_cseq_number); - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - return TRUE; -} - -/* - * This will generate the most common headers for every message - */ - -sipRet_t -sipSPIAddCommonHeaders (ccsipCCB_t *ccb, - sipMessage_t *request, - boolean isResponse, - sipMethod_t method, - uint32_t response_cseq_number) -{ - sipRet_t tflag = STATUS_FAILURE; - - tflag = (sipSPIAddStdHeaders(request, ccb, isResponse)) ? - STATUS_SUCCESS : STATUS_FAILURE; - if (tflag != HSTATUS_SUCCESS) { - return tflag; - } - - // Add date header - tflag = sipAddDateHeader(request); - if (tflag != HSTATUS_SUCCESS) { - return tflag; - } - - // Add CSEQ - if (AddCSeq(ccb, request, isResponse, method, response_cseq_number) - == FALSE) { - return STATUS_FAILURE; - } - - return HSTATUS_SUCCESS; -} - -boolean -is_extended_feature (ccsipCCB_t *ccb) -{ - if (ccb) { - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_CANCEL: - return TRUE; - default: - return FALSE; - } - } - return FALSE; -} - -boolean -sipSPIGenRequestURI (ccsipCCB_t *ccb, sipMethod_t sipmethod, boolean initInvite) -{ - sipUrl_t *sipUrl = NULL; - int i = 0; - const char *fname = "sipSPIGenRequestURI"; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char *domainloc; - genUrl_t *gen; - int j = 0; - boolean lr = FALSE, uriAdded = FALSE; - char hdr_str[MAX_SIP_URL_LENGTH]; - - /* - * Construct the request URI - */ - // Special case for Initial Invite and Cancel messgae for creating - // the Request URI - if ((sipMethodInvite == sipmethod) && (initInvite == TRUE)) { - // This is the first Invite initiated so Request URI is - // built differently. - if (ccb->calledNumber[0] == '<') { - // Remove leading '<' - sstrncpy(ccb->ReqURI, ccb->calledNumber + 1, MAX_SIP_URL_LENGTH); - } - // If there is no hostname, add proxy address as hostname - domainloc = strchr(ccb->ReqURI, '@'); - if (domainloc == NULL) { - domainloc = ccb->ReqURI + strlen(ccb->ReqURI); - if ((domainloc - ccb->ReqURI) < (MAX_SIP_URL_LENGTH - 1)) { - /* - * We need to check and see if we are already truncating a - * string string that goes into ReqURI. If we are, then we - * CANNOT add any more characters without overwriting memory - */ - *domainloc++ = '@'; - sstrncpy(dest_sip_addr_str, ccb->reg.proxy, - MAX_IPADDR_STR_LEN); - - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - *domainloc++ = '['; - } - - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - ccb->ReqURI)); - - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - *domainloc++ = ']'; - } - } - } - // Remove trailing '>' - domainloc = strchr(ccb->ReqURI, '>'); - if (domainloc) { - *domainloc = '\0'; - } - return TRUE; - } else if ((sipMethodCancel == sipmethod) || - ((sipMethodAck == sipmethod) && - (gCallHistory[ccb->index].last_rspcode_rcvd > codeClass2xx))) { - /* Use the same REQ URI that was created on the INVITE - * Replace the ReqURI with the contents of ReqURIOriginal - */ - if (ccb->ReqURIOriginal[0] != '\0') { - sstrncpy(ccb->ReqURI, ccb->ReqURIOriginal, MAX_SIP_URL_LENGTH); - } - return TRUE; - } - - if (sipMethodRegister == sipmethod || - ((sipMethodRefer == sipmethod) && - (ccb->type == SIP_REG_CCB || is_extended_feature(ccb)))) { - // If it is REGISTER or a token-registration REFER, the URI is formed - // simply by the destination IP address. This is also the case when - // sending a REFER for one of the softkey functions for TNP - if (ccb->reg.proxy[0] == '\0') { - ipaddr2dotted(dest_sip_addr_str, &ccb->dest_sip_addr); - } else { - sstrncpy(dest_sip_addr_str, ccb->reg.proxy, MAX_IPADDR_STR_LEN); - } - if (ccb->dest_sip_addr.type == CPR_IP_ADDR_IPV6) { - - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, "sip:[%s]", - dest_sip_addr_str); /* proxy */ - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, "sip:%s", - dest_sip_addr_str); /* proxy */ - } - - return TRUE; - } else { - if (ccb->record_route_info) { - /* - * If loose-routing is being used, use the remote contact in - * REQ-URI - */ - if (ccb->flags & INCOMING) { - i = 0; - } else { - i = ccb->record_route_info->num_locations - 1; - } - - if (ccb->record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - if (ccb->record_route_info->locations[i]->genUrl->u.sipUrl->lr_flag) { - lr = TRUE; - } - } - if (!lr) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Strict Routing: Forming Req-URI using " - "Record Route\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (ccb->record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->record_route_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), - fname); - return (FALSE); - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - if (sipUrl->port_present) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%s@%s;user=phone" : - "sip:%s:%s@%s", - sipUrl->user, sipUrl->password, - sipUrl->host); - } - } else { - if (sipUrl->port_present) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s@%s:%d;user=phone" : "sip:%s@%s:%d", - sipUrl->user, sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s@%s;user=phone" : "sip:%s@%s", - sipUrl->user, sipUrl->host); - } - } - } else { - if (sipUrl->port_present) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%d;user=phone" : "sip:%s:%d", - sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s;user=phone" : "sip:%s", - sipUrl->host); - } - } - uriAdded = TRUE; - } - } - - if (!uriAdded) { - if ((ccb->contact_info) && - (lr || (ccb->state >= SIP_STATE_SENT_INVITE_CONNECTED))) { - // Use Contact info ONLY if loose routing or - // if we're fully connected - otherwise use proxy - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using Contact", - DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - - if ((sipMethodInvite == sipmethod) && - (ccb->redirect_info) && - (ccb->state == SIP_STATE_SENT_INVITE)) { - sipUrl = ccb->redirect_info->sipContact->locations - [ccb->redirect_info->next_choice - 1]->genUrl->u.sipUrl; - } else if (ccb->contact_info->locations[0]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), - fname); - return (FALSE); - } - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", - sipUrl->user, sipUrl->host, sipUrl->port); - } - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%d;user=phone" : - "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else { - if (ccb->flags & INCOMING) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Callee): using " - "From\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (ccb->sip_from) { - sstrncpy(hdr_str, ccb->sip_from, MAX_SIP_URL_LENGTH); - sstrncpy(ccb->ReqURI, sippmh_get_url_from_hdr(hdr_str), MAX_SIP_URL_LENGTH); - } - } else { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Caller): using " - "original Req-URI\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - sstrncpy(ccb->ReqURI, ccb->ReqURIOriginal, - MAX_SIP_URL_LENGTH); - } - } - } - - // Check to see the transport parameter specified in sipUrl. - // If this is different than UDP, add it to the URI - if (sipUrl) { - switch (sipUrl->transport) { - case TRANSPORT_UDP: - sstrncat(ccb->ReqURI, ";transport=udp", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - case TRANSPORT_TCP: - sstrncat(ccb->ReqURI, ";transport=tcp", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - case TRANSPORT_TLS: - sstrncat(ccb->ReqURI, ";transport=tls", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - case TRANSPORT_SCTP: - sstrncat(ccb->ReqURI, ";transport=sctp", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - default: - break; - } - } - if (ccb->record_route_info) { - /* - * Look for any unknown params that might have been - * glued onto the URL - */ - gen = ccb->record_route_info->locations[i]->genUrl; - while (j < SIP_MAX_LOCATIONS) { - if (gen->other_params[j] != NULL) { - sstrncat(ccb->ReqURI, ";", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - sstrncat(ccb->ReqURI, gen->other_params[j], - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - } - j++; - } - } - } - return TRUE; -} - -sipRet_t -sipSPIAddContactHeader (ccsipCCB_t *ccb, sipMessage_t *request) -{ - char pContactStr[MAX_SIP_URL_LENGTH]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char line_name[MAX_LINE_NAME_SIZE]; - char reg_user_info[MAX_REG_USER_INFO_LEN]; - int rpid_flag = RPID_DISABLED; - int blocking; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char device_instance[MAX_SIP_TAG_LENGTH]; - char contact[MAX_LINE_CONTACT_SIZE]; - size_t escaped_char_str_len; - const char *transport_type_str; - int size; - char sipDeviceName[MAX_REG_USER_INFO_LEN]; - - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - - config_get_value(CFGID_DEVICE_NAME, sipDeviceName, sizeof(sipDeviceName)); - - /* get reg_user_info and pk-id */ - contact[0] = '\0'; - config_get_string(CFGID_REG_USER_INFO, reg_user_info, - sizeof(reg_user_info)); - config_get_line_string(CFGID_LINE_CONTACT, contact, ccb->dn_line, - sizeof(contact)); - - - ipaddr2dotted(src_addr_str, &ccb->src_addr); - - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - - transport_type_str = sipTransportGetTransportType(ccb->dn_line, FALSE, ccb); - - /* - * If caller id blocking is enabled and phone - * is configured to use RPID then userinfo should - * be random identifier same as that used in from - * header - */ - if ((blocking & 1) && (rpid_flag == RPID_ENABLED) && - (ccb->type != SIP_REG_CCB)) { - sstrncpy(line_name, SIP_HEADER_ANONYMOUS_STR, MAX_LINE_NAME_SIZE); - } else { - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - } - - if (ccb->type == SIP_REG_CCB) { - snprintf(pContactStr, 6, "", src_addr_str, - ccb->local_port, transport_type_str); - } else { - snprintf(pContactStr + 5 + escaped_char_str_len, - sizeof(pContactStr) - 5 - escaped_char_str_len, - "@%s:%d;user=%s;transport=%s>", - src_addr_str, ccb->local_port, reg_user_info, - transport_type_str); - } - - // Add the instance ID for unique device identification - // The format is as follows: - // Contact: - // ;+sip.instance="" - // ;+u.sip!model.ccm.cisco.com="336" - // where the 000A95A0E128 is the MAC address of the phone and - // the 336 is the model number of the phone - // All the 000's are supposed to encode callee capabilities (RFC 3840) - // but we are leaving them 000 for now as no-one reads them - platform_get_active_mac_address(mac_address); - memset(device_instance, '\0', sizeof(device_instance)); - snprintf(device_instance, MAX_SIP_TAG_LENGTH, - ";+sip.instance=\"\"", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5]); - size = MAX_SIP_URL_LENGTH - strlen(pContactStr); - if (size > (int)strlen(device_instance)) { - sstrncat(pContactStr, device_instance, size); - } - // Add the instance ID for unique device identification - // The format is as follows: - // Contact: ;+sip.instance=""; - //+u.sip!devicename.ccm.cisco.com="SEP0019E89A7F3D"; - //++u.sip!model.ccm.cisco.com="30006" - // where the 000A95A0E128 is the MAC address of the phone and - // the 336 is the model number of the phone - // All the 000's are supposed to encode callee capabilities (RFC 3840) - // but we are leaving them 000 for now as no-one reads them - platform_get_wired_mac_address(mac_address); - memset(device_instance, '\0', sizeof(device_instance)); - snprintf(device_instance, MAX_SIP_TAG_LENGTH, - ";+sip.instance=\"\"" - ";+u.sip!devicename.ccm.cisco.com=\"%s\"" - ";+u.sip!model.ccm.cisco.com=\"%s\"", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - sipDeviceName, - sipPhoneModelNumber); - size = MAX_SIP_URL_LENGTH - strlen(pContactStr); - if (size > (int)strlen(device_instance)) { - sstrncat(pContactStr, device_instance, size); - } - // add tag cisco-keep-alive for keep alive messages in ccm mode - if ((ccb->cc_type == CC_CCM) && (ccb->index >= REG_BACKUP_CCB)) { - sipMethod_t method = sipMethodInvalid; - - sipGetRequestMethod(request, &method); - if (method == sipMethodRegister) { - sstrncat(pContactStr, ";expires=0;cisco-keep-alive", - sizeof(pContactStr) - strlen(pContactStr)); - } - } - } else { - char *forward_url = NULL; - - forward_url = Basic_is_phone_forwarded(ccb->dn_line); - /* only use the forward URL if we are sending a 302 */ - if ((forward_url) && - (strstr(request->mesg_line, SIP_RED_MOVED_TEMP_PHRASE))) { - char *user_info = strchr(forward_url, '@'); - - /* - * forward_url will always have domain/host address preceded - * by @ following the user, returned by - * Basic_is_phone_forwarded. so no need to check for - * user_info == NULL - */ - snprintf(pContactStr, 6, "", - user_info); - } else { - /* - * Use the contact value supplied to us, if available. - * If not, use name - */ - snprintf(pContactStr, 6, "", src_addr_str, - ccb->local_port, transport_type_str); - } else { - snprintf(pContactStr + 5 + escaped_char_str_len, - sizeof(pContactStr) - 5 - escaped_char_str_len, - "@%s:%d;user=%s;transport=%s>", - src_addr_str, ccb->local_port, - reg_user_info, transport_type_str); - } - } - } - return (sippmh_add_text_header(request, SIP_HEADER_CONTACT, pContactStr)); -} - -/** - * Convert phone name to upper case - * - * @param phone_name - phone name - * - * @return status none - * - * @pre none - */ -void convert_phone_name_to_upper_case(char *phone_name) -{ - while (phone_name && (*phone_name) != '\0') { - *phone_name = (char)toupper(*phone_name); - phone_name++; - } -} -/** - * Add reason header to SIP message - * - * eg: Reason: SIP;cause=200;text="cisco:22 Name=SEP000000000000 - * Load=SIP70.8-2-25 Last=reset-reset - * - * @param ccb call control block - * @param request sip message - * - * @return status - * success: STATUS_SUCCESS - * failure: STATUS_FAILURE - * - * @pre (ccb not_eq NULL) - * @pre (request not_eq NULL) - * - */ -sipRet_t -sipSPIAddReasonHeader (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "sipSPIAddReasonHeader"; - char pReasonStr[MAX_SIP_HEADER_LENGTH]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char phone_name[MAX_PHONE_NAME_LEN]; - char image_a[MAX_LOAD_ID_STRING]; - char image_b[MAX_LOAD_ID_STRING]; - int active_partition; - int unreg_reason_code = 0; - char unreg_reason_str[MAX_UNREG_REASON_STR_LEN]; - - if (ccb->send_reason_header) { - // should only be set when the phone is registering after a restart/reset - platform_get_wired_mac_address(mac_address); - - snprintf(phone_name, MAX_PHONE_NAME_LEN, "SEP%04x%04x%04x", mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5]); - - convert_phone_name_to_upper_case(phone_name); - - - unreg_reason_code = platGetUnregReason(); - - unreg_reason_str[0] = '\0'; - get_reason_string(unreg_reason_code, unreg_reason_str, MAX_UNREG_REASON_STR_LEN); - active_partition = platGetActiveInactivePhoneLoadName(image_a, image_b, MAX_LOAD_ID_STRING); - snprintf(pReasonStr, MAX_SIP_HEADER_LENGTH, - "SIP;cause=200;text=\"cisco-alarm:%d Name=%s ActiveLoad=%s InactiveLoad=%s Last=%s", - unreg_reason_code, phone_name, (active_partition == 1) ? image_a:image_b, - (active_partition == 1) ? image_b:image_a, unreg_reason_str); - sstrncat(pReasonStr, "\"", - MAX_SIP_HEADER_LENGTH - strlen(pReasonStr) - 1); - return (sippmh_add_text_header(request, SIP_HEADER_REASON, pReasonStr)); - } else { - CCSIP_DEBUG_ERROR("%s called with send_reason_header set to false", fname); - return (STATUS_SUCCESS); - } -} - -/** - * Return the reason string that is to be returned - * corresponding to the unreg reason that is to be sent - * in the register message. - * - * @param unreg_reason - unreg reason code - * @param char * - reason string corresponding to the code - * @return none - * - */ -void -get_reason_string (int unreg_reason, char *unreg_reason_str, int len) -{ - - switch(unreg_reason) { - case UNREG_REASON_RESET_RESTART: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "reset-restart"); - break; - case UNREG_REASON_RESET_RESET: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "reset-reset"); - break; - case UNREG_REASON_PHONE_INITIALIZED: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "initialized"); - break; - case UNREG_REASON_REG_TIMEOUT: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "reg-timeout"); - break; - case UNREG_REASON_PHONE_KEYPAD: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "phone-keypad"); - break; - case UNREG_REASON_PHONE_REG_REJ: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "phone-reg-rej"); - break; - case UNREG_REASON_FALLBACK: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "fallback"); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch(%s)", sipUnregisterReason); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch-config"); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch-softkey"); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch-dialplan"); - break; - case UNREG_REASON_CONFIG_RETRY_RESTART: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "config-retry-restart"); - break; - case UNREG_REASON_TLS_ERROR: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "tls-error"); - break; - case UNREG_REASON_TCP_TIMEOUT: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "tcp_timeout"); - break; - case UNREG_REASON_CM_CLOSED_TCP: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "cm-closed-tcp"); - break; - case UNREG_REASON_CM_RESET_TCP: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "cm-reset-tcp"); - break; - case UNREG_REASON_CM_ABORTED_TCP: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "cm-aborted-tcp"); - break; - case UNREG_REASON_APPLY_CONFIG_RESTART: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "apply_config"); - break; - case UNREG_REASON_VOICE_VLAN_CHANGED: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "VLAN-Changed"); - break; - default: - unreg_reason_str[0] = '\0'; - CCSIP_DEBUG_ERROR("Unkown unreg reason code passed"); - break; - } -} -boolean -CreateRequest (ccsipCCB_t *ccb, sipMessageFlag_t messageflag, - sipMethod_t sipmethod, sipMessage_t *request, - boolean initInvite, uint32_t response_cseq_number) -{ - sipRet_t tflag = STATUS_FAILURE; - - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "CreateRequest", "GET_SIP_MESSAGE()"); - return FALSE; - } - - - if (sipMethodResponse != sipmethod) { - if (sipSPIAddRequestLine(ccb, request, sipmethod, initInvite) - == STATUS_FAILURE) { - return FALSE; - } - } - - ccb->outBoundProxyPort = 0; - ccb->outBoundProxyAddr = ip_addr_invalid; - if (ccb->ObpSRVhandle != NULL) { - dnsFreeSrvHandle(ccb->ObpSRVhandle); - ccb->ObpSRVhandle = NULL; - } - - tflag = (allocateTrx(ccb, sipmethod)) ? STATUS_SUCCESS : STATUS_FAILURE; - - if (tflag == STATUS_SUCCESS) { - tflag = (sipSPIAddLocalVia(request, ccb, sipmethod)) ? - STATUS_SUCCESS : STATUS_FAILURE; - /* Don't stop adding headers to a Register just because - * the VIA line wasn't added. A Register doesn't really - * need the VIA line anyways. - */ - if ((HSTATUS_SUCCESS != tflag) && (ccb->type != SIP_REG_CCB)) { - return FALSE; - } - } - - if (tflag == STATUS_SUCCESS) { - tflag = sipSPIAddCommonHeaders(ccb, request, FALSE, sipmethod, - response_cseq_number); - } - - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - - tflag = sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - return AddGeneralHeaders(ccb, messageflag, request, sipmethod); -} - -boolean -CreateResponse (ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - uint16_t status_code, - sipMessage_t *response, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - sipMethod_t method) -{ - sipRet_t tflag = HSTATUS_SUCCESS; - char *warning = NULL; - uint32_t response_cseq_number = 0; - - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - "CreateResponse", "ccb"); - return FALSE; - } - if (!ccb->last_request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - "Create Response", "ccb->last_request"); - return FALSE; - } - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "CreateResponse", "GET_SIP_MESSAGE()"); - return FALSE; - } - - tflag = sippmh_add_response_line(response, SIP_VERSION, status_code, - reason_phrase); - - if (tflag != HSTATUS_SUCCESS) - return FALSE; - - tflag = (sipSPIAddRequestVia(ccb, response, ccb->last_request, method)) ? - STATUS_SUCCESS : STATUS_FAILURE; - - if (tflag != HSTATUS_SUCCESS) - return FALSE; - - response_cseq_number = 0; - - tflag = sipSPIAddCommonHeaders(ccb, response, TRUE, method, - response_cseq_number); - if (tflag != HSTATUS_SUCCESS) - return FALSE; - - if (reason_phrase_warning) { - warning = (char *) cpr_malloc(strlen(reason_phrase_warning) + 5); - if (warning) { - snprintf(warning, strlen(reason_phrase_warning) + 5, - "%d %s", status_code_warning, reason_phrase_warning); - tflag = sippmh_add_text_header(response, SIP_HEADER_WARN, warning); - cpr_free(warning); - if (tflag != HSTATUS_SUCCESS) - return FALSE; - } - } - - tflag = sippmh_add_text_header(response, SIP_HEADER_SERVER, - sipHeaderServer); - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - - return AddGeneralHeaders(ccb, messageflag, response, method); -} - -/************************************************************* - * Function: SendRequest - * this function sends out a request pointed to by the request parameter - * in ccb's context. - * - * 'request' will be freed. The caller does not have the responsibility - * to free it. - **************************************************************/ -boolean -SendRequest (ccsipCCB_t *ccb, sipMessage_t *request, sipMethod_t method, - boolean midcall, boolean reTx, boolean retranTimer) -{ - const char *fname = "SendRequest"; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t cc_remote_port = 0; - int timeout = 0; - int expires_timeout; - sipUrl_t *sipUrl = NULL; - boolean isRegister = FALSE; - int16_t trx_index; - int reldev_stored_msg = RELDEV_NO_STORED_MSG; - - CPR_IP_ADDR_INIT(cc_remote_ipaddr); - - if (sipMethodRegister == method) { - if (ccb->reg.proxy[0] == '\0') { - cc_remote_ipaddr = ccb->dest_sip_addr; - cc_remote_port = (uint16_t) ccb->dest_sip_port; - } else { - cc_remote_ipaddr = ccb->reg.addr; - cc_remote_port = ccb->reg.port; - } - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - isRegister = TRUE; - - } else if ((sipMethodInvite == method) && (midcall == FALSE)) { - char *host; - - if (!ccb->ReqURI) { - free_sip_message(request); - return FALSE; - } - host = strchr(ccb->ReqURI, '@'); - if (!host) { - free_sip_message(request); - return FALSE; - } - - /* Enable reTx and send */ - if (TRUE == reTx) { - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - } - cc_remote_ipaddr = ccb->dest_sip_addr; - cc_remote_port = (uint16_t) ccb->dest_sip_port; - } else { - if ((ccb->record_route_info) && (sipMethodCancel != method)) { - int16_t i; - - if (ccb->flags & INCOMING) { - i = 0; - } else { - i = ccb->record_route_info->num_locations - 1; - } - - if (ccb->record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->record_route_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - free_sip_message(request); - return (FALSE); - } - - cc_remote_port = sipUrl->port; - - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code == 0) { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } else { - cc_remote_ipaddr = ip_addr_invalid; - } - - } else if ((ccb->contact_info) && - (ccb->state >= SIP_STATE_SENT_INVITE_CONNECTED)) { - /* - * If the call has been set up, we are free to use the - * contact header. If the call has NOT been set up, - * drop through and use the proxy. - */ - if (ccb->contact_info->locations[0]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - free_sip_message(request); - return (FALSE); - } - - cc_remote_port = sipUrl->port; - - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code == 0) { - - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } else { - cc_remote_ipaddr = ip_addr_invalid; - } - - } else { - cc_remote_ipaddr = ccb->dest_sip_addr; - cc_remote_port = (uint16_t) ccb->dest_sip_port; - } - if (TRUE == reTx) - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - } - - if (util_check_if_ip_valid(&cc_remote_ipaddr) == FALSE) { - free_sip_message(request); - return (FALSE); - } - - // Update default destination address and port - ccb->dest_sip_addr = cc_remote_ipaddr; - ccb->dest_sip_port = cc_remote_port; - - /* - * Store the ACK so that it can be retransmitted in response - * to any duplicate 200 OK or error responses - */ - trx_index = get_last_request_trx_index(ccb, TRUE); - if (trx_index < 0) { - CCSIP_DEBUG_ERROR("%s: No Valid Trx found!", "SendRequest"); - return (FALSE); - } - if (sipMethodAck == method) { - reldev_stored_msg = - sipRelDevCoupledMessageStore(request, ccb->sipCallID, - ccb->sent_request[trx_index].cseq_number, - ccb->sent_request[trx_index].cseq_method, - TRUE, ccb->last_recvd_response_code, - &cc_remote_ipaddr, cc_remote_port, - FALSE /* Do check tag */); - } - if (sipTransportCreateSendMessage(ccb, request, method, - &cc_remote_ipaddr, cc_remote_port, - isRegister, reTx, timeout, NULL, - reldev_stored_msg) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "SendRequest", "sipTransportCreateSendMessage()"); - //dont need message free here..sipTransportCreateSendMessage() will free it - return (FALSE); - } - - /* Start INVITE expires timer */ - if (retranTimer) { - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &expires_timeout, - sizeof(expires_timeout)); - if (expires_timeout > 0) { - if (sip_platform_expires_timer_start(expires_timeout * 1000, - ccb->index, - &cc_remote_ipaddr, //ccb->dest_sip_addr, - cc_remote_port) //ccb->dest_sip_port, - != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "SendRequest", - "sip_platform_expires_timer_start()"); - return (FALSE); - } - } - } - // Save Call History - if (sipMethodCancel == method || sipMethodBye == method) { - gCallHistory[ccb->index].last_bye_cseq_number = - ccb->sent_request[trx_index].cseq_number; - gCallHistory[ccb->index].proxy_dest_ipaddr = ccb->dest_sip_addr; - gCallHistory[ccb->index].dn_line = ccb->dn_line; - sstrncpy(gCallHistory[ccb->index].via_branch, - ccb->sent_request[trx_index].u.sip_via_branch, - VIA_BRANCH_LENGTH); - } - return (TRUE); -} - -boolean -sendResponse (ccsipCCB_t *ccb, - sipMessage_t *response, - sipMessage_t *refrequest, - boolean retx, - sipMethod_t method) -{ - sipVia_t *via = NULL; - const char *request_callid = NULL; - sipCseq_t *request_cseq_structure; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t cc_remote_port = 0; - int timeout = 0; - const char *pViaHeaderStr = NULL; - char *dest_ip_addr_str = 0; - int16_t trx_index = -1; - boolean port_present = FALSE; - int reldev_stored_msg; - int status_code = 0; - - CPR_IP_ADDR_INIT(cc_remote_ipaddr); - - if (ccb) { - request_callid = ccb->sipCallID; - trx_index = get_method_request_trx_index(ccb, method, FALSE); - if (trx_index >= 0) { - pViaHeaderStr = (const char *) - (ccb->recv_request[trx_index].u.sip_via_header); - request_cseq_structure = (sipCseq_t *) - cpr_malloc(sizeof(sipCseq_t)); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "malloc failed"); - free_sip_message(response); - return (FALSE); - } - request_cseq_structure->method = - ccb->recv_request[trx_index].cseq_method; - request_cseq_structure->number = - ccb->recv_request[trx_index].cseq_number; - } else { - pViaHeaderStr = - sippmh_get_cached_header_val(ccb->last_request, VIA); - if (getCSeqInfo(ccb->last_request, &request_cseq_structure) - == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "getCSeqInfo returned false"); - free_sip_message(response); - return (FALSE); - } - } - } else { - pViaHeaderStr = sippmh_get_cached_header_val(refrequest, VIA); - request_callid = sippmh_get_cached_header_val(refrequest, CALLID); - if (FALSE == getCSeqInfo(refrequest, &request_cseq_structure)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "getCSeqInfo returned false"); - free_sip_message(response); - return (FALSE); - } - } - - via = sippmh_parse_via(pViaHeaderStr); - if (!via) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "Bad Via Header in Message!"); - cpr_free(request_cseq_structure); - free_sip_message(response); - return (FALSE); - } - - if (via->remote_port) { - cc_remote_port = via->remote_port; - port_present = TRUE; - } else { - /* Use default 5060 if via does not have port */ - cc_remote_port = SIP_WELL_KNOWN_PORT; - } - - /* - * if maddr is present use it - */ - if (via->maddr) { - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(via->maddr, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(via->maddr, - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", - "sipTransportGetServerAddrPort or dnsGetHostByName"); - } else { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } - } - - /* - * if maddr isn't present, or the DNS lookup failed, send the - * response to the IP address we received the message from. - */ - if (util_check_if_ip_valid(&cc_remote_ipaddr) == FALSE) { - if (via->recd_host) { - dest_ip_addr_str = via->recd_host; - } else { - dest_ip_addr_str = via->host; - } - - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(dest_ip_addr_str, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(dest_ip_addr_str, - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", - "sipTransportGetServerAddrPort or dnsGetHostByName"); - cpr_free(request_cseq_structure); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } else { - util_ntohl(&cc_remote_ipaddr , &cc_remote_ipaddr); - } - } - - sippmh_free_via(via); - - reldev_stored_msg = - sipRelDevCoupledMessageStore(response, request_callid, - request_cseq_structure->number, - request_cseq_structure->method, - FALSE, status_code, - &cc_remote_ipaddr, cc_remote_port, - /* If responding to call setup don't check tag */ - (boolean)(ccb != NULL ? - SIP_SM_CALL_SETUP_RESPONDING(ccb) : - FALSE)); - cpr_free(request_cseq_structure); - /* Enable reTx and send */ - if (retx) { - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - if (ccb) { - ccb->retx_counter = 0; - } - } else { - timeout = 0; /* No reTx timer */ - } - - if (sipTransportChannelCreateSend(ccb, response, sipMethodResponse, - &cc_remote_ipaddr, cc_remote_port, - timeout, reldev_stored_msg) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "SendResponse", "sipTransportChannelCreateSend()"); - return FALSE; - } - return TRUE; -} - -static sipRet_t -CopyLocalSDPintoResponse (sipMessage_t *request, - cc_msgbody_info_t *local_msg_body) -{ - sipRet_t tflag = HSTATUS_SUCCESS; - uint32_t body_index; - cc_msgbody_info_t tmp_body, *tmp_body_p; - cc_msgbody_t *part; - - if (local_msg_body->num_parts == 0) { - /* content type specified but no msg. body to add */ - return HSTATUS_FAILURE; - } - - /* - * Duplicate a msg. body to send out which will be freed - * after the full message is created during the send of the - * msg. - */ - tmp_body.num_parts = 0; /*initialize to no parts */ - tmp_body_p = &tmp_body; - if (cc_cp_msg_body_parts(tmp_body_p, local_msg_body) != CC_RC_SUCCESS) { - /* Unable to duplicate the msg. body */ - return HSTATUS_FAILURE; - } - part = &tmp_body_p->parts[0]; - for (body_index = 0; body_index < tmp_body_p->num_parts; body_index++) { - if ((part->body != NULL) && (part->body_length)) { - tflag = sippmh_add_message_body(request, part->body, - part->body_length, - cc2siptype(part->content_type), - cc2sipdisp(part->content_disposition.disposition), - part->content_disposition.required_handling, - part->content_id); - } else { - /* Invalid entry */ - tflag = HSTATUS_FAILURE; - break; - } - } - return tflag; -} - -boolean -AddGeneralHeaders (ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - sipMessage_t *request, - sipMethod_t sipmethod) -{ - const char *fname = "AddGeneralHeaders"; - sipRet_t tflag = HSTATUS_SUCCESS; - unsigned int isOver = messageflag.flags; - unsigned int whichflag = 0x0001; - unsigned int bit_to_reset = 0; // Test and then reset - int16_t i; - int time_exp; - unsigned int info_index; - cpr_ip_mode_e ip_mode; - - while (0 != isOver) { - bit_to_reset = (whichflag & messageflag.flags); - switch (bit_to_reset) { - case SIP_HEADER_CONTACT_BIT: - tflag = sipSPIAddContactHeader(ccb, request); - break; - - case SIP_HEADER_RECORD_ROUTE_BIT: - if (ccb->record_route_info) { - tflag = (sipSPIAddRequestRecordRoute(request, ccb->last_request)) ? - STATUS_SUCCESS : STATUS_FAILURE; - } - break; - - case SIP_HEADER_ROUTE_BIT: - tflag = (sipSPIAddRouteHeaders(request, ccb, NULL, 0)) ? - STATUS_SUCCESS : STATUS_FAILURE; - break; - - case SIP_HEADER_UNSUPPORTED_BIT: - if (ccb->sip_unsupported[0] != '\0') { - tflag = sippmh_add_text_header(request, - SIP_HEADER_UNSUPPORTED, - &ccb->sip_unsupported[0]); - } - break; - - case SIP_HEADER_REQUESTED_BY_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REQUESTED_BY, - ccb->sip_reqby); - break; - - case SIP_HEADER_REMOTE_PARTY_ID_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REMOTE_PARTY_ID, - ccb->sip_remote_party_id); - break; - - case SIP_HEADER_DIVERSION_BIT: - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - if (ccb->diversion[i]) { - tflag = sippmh_add_text_header(request, - SIP_HEADER_DIVERSION, - ccb->diversion[i]); - if (tflag != HSTATUS_SUCCESS) - break; - } - } - break; - - case SIP_HEADER_AUTHENTICATION_BIT: - tflag = sippmh_add_text_header(request, - AUTHOR_HDR(ccb->authen.status_code), - ccb->authen.authorization); - break; - - case SIP_HEADER_PROXY_AUTH_BIT: - // This happens when we get a refer with a proxy-auth. We just - // parrot whatever the proxy told us to do in this invite. - tflag = sippmh_add_text_header(request, - SIP_HEADER_PROXY_AUTHORIZATION, - ccb->refer_proxy_auth); - break; - - case SIP_HEADER_REFER_TO_BIT: - break; - - case SIP_HEADER_REFERRED_BY_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REFERRED_BY, - ccb->sip_referredBy); - break; - - case SIP_HEADER_REPLACES_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REPLACES, - ccb->sipxfercallid); - break; - - case SIP_HEADER_EVENT_BIT: - break; - - case SIP_HEADER_EXPIRES_BIT: - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &time_exp, - sizeof(time_exp)); - tflag = sippmh_add_int_header(request, SIP_HEADER_EXPIRES, - time_exp); - break; - - case SIP_HEADER_REASON_BIT: - tflag = sipSPIAddReasonHeader(ccb, request); - break; - - case SIP_HEADER_CONTENT_LENGTH_BIT: - if ((messageflag.flags & SIP_HEADER_CONTENT_TYPE_BIT) || - (messageflag.flags & SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT)) { - /* - * Header content length will be set when SDP body is added - * so we do not set it here. - */ - break; - } - tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - break; - - case SIP_HEADER_CONTENT_TYPE_BIT: - tflag = CopyLocalSDPintoResponse(request, &ccb->local_msg_body); - if (tflag != HSTATUS_SUCCESS) { - /* there is some thing wrong with message body */ - CCSIP_DEBUG_ERROR("%s: Error adding message body.", fname); - break; - } - - /* - * SDP successfully added to message. Update offer/answer state. - */ - if (ccb->oa_state == OA_OFFER_RECEIVED) { - ccb->oa_state = OA_IDLE; - } else { - ccb->oa_state = OA_OFFER_SENT; - } - break; - - case SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT: - tflag = CopyLocalSDPintoResponse(request, &ccb->local_msg_body); - if (tflag != HSTATUS_SUCCESS) { - /* there is some thing wrong with message body */ - CCSIP_DEBUG_ERROR("%s: Error adding options message body.", - fname); - } - - /* - * SDP successfully added to message. OPTIONS response does - * not alter offer/answer state as the - * SIP_HEADER_CONTENT_TYPE_BIT does. - */ - break; - - case SIP_HEADER_ALLOW_BIT: - { - char temp[MAX_SIP_HEADER_LENGTH]; - - snprintf(temp, MAX_SIP_HEADER_LENGTH, - "%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, - SIP_METHOD_OPTIONS, SIP_METHOD_REFER, - SIP_METHOD_REGISTER, SIP_METHOD_UPDATE); - sstrncat(temp, ",", sizeof(temp) - strlen(temp)); - sstrncat(temp, SIP_METHOD_SUBSCRIBE, sizeof(temp) - strlen(temp)); - sstrncat(temp, ",", sizeof(temp) - strlen(temp)); - sstrncat(temp, SIP_METHOD_INFO, sizeof(temp) - strlen(temp)); - tflag = sippmh_add_text_header(request, SIP_HEADER_ALLOW, temp); - } - break; - - case SIP_HEADER_ACCEPT_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - "application/sdp"); - break; - - case SIP_HEADER_ACCEPT_ENCODING_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT_ENCODING, - "identity"); - break; - - case SIP_HEADER_ACCEPT_LANGUAGE_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT_LANGUAGE, - "en"); - break; - - case SIP_HEADER_CISCO_GUID_BIT: - tflag = (sipSPIAddCiscoGuid(request, ccb)) ? - STATUS_SUCCESS : STATUS_FAILURE; - break; - - case SIP_HEADER_CALL_INFO_BIT: - /* - * Include call info header if in CCM mode or - * other end indicates that it can support it. - */ - if ((sip_regmgr_get_cc_mode(ccb->dn_line) == REG_MODE_CCM) || - (ccb->supported_tags & cisco_callinfo_tag)) { - tflag = (sipRet_t) sippmh_add_call_info(request, - ccb->out_call_info); - } - break; - - case SIP_HEADER_JOIN_INFO_BIT: - tflag = (sipRet_t) sippmh_add_join_header(request, ccb->join_info); - break; - - case SIP_HEADER_ALLOW_EVENTS_BIT: - { - char temp[MAX_SIP_HEADER_LENGTH]; - int kpml_config; - - // Get kpml configuration - config_get_value(CFGID_KPML_ENABLED, &kpml_config, - sizeof(kpml_config)); - if (kpml_config) { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s", - SIP_EVENT_KPML, SIP_EVENT_DIALOG); - } else { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s", - SIP_EVENT_DIALOG); - } - tflag = sippmh_add_text_header(request, SIP_HEADER_ALLOW_EVENTS, - temp); - } - break; - - case SIP_HEADER_SUPPORTED_BIT: - { - const char *opt_tags; - - opt_tags = sipGetSupportedOptionList(ccb, sipmethod); - - tflag = sippmh_add_text_header(request, - SIP_HEADER_SUPPORTED, - opt_tags); - } - break; - - case SIP_HEADER_REQUIRE_BIT: - ip_mode = platform_get_ip_address_mode(); - if (ip_mode == CPR_IP_MODE_DUAL) { - tflag = sippmh_add_text_header(request, SIP_HEADER_REQUIRE, "sdp-anat"); - } - break; - - case SIP_HEADER_RETRY_AFTER_BIT: - tflag = sippmh_add_int_header(request, - SIP_HEADER_RETRY_AFTER, - abs((cpr_rand() % 11))); - break; - - case SIP_HEADER_RECV_INFO_BIT: - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] != NULL) { - tflag = sippmh_add_text_header(request, SIP_HEADER_RECV_INFO, - g_registered_info[info_index]); - if (tflag != HSTATUS_SUCCESS) { - break; - } - } - } - break; - - default: - //tflag = HSTATUS_FAILURE; - break; - } - - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - whichflag = whichflag << 1; - /* - * Reset this bit so if nothing else is there we do not need to test - */ - isOver &= ~bit_to_reset; - } - return TRUE; -} - - -/************************************************************* - * Function: sipSPISendUpdate - * This function creates, formats, and sends an UPDATE message - * on an existing (early) dialog - **************************************************************/ -boolean -sipSPISendUpdate (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendUpdate"; - sipMessageFlag_t messageflag; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - - - // UPDATE requests mandates the use of the following headers: - // Allow, Call-ID, Contact, CSeq, From, Max-Forwards, To, and Via - - messageflag.flags = 0; - messageflag.flags |= SIP_HEADER_ALLOW_BIT | - SIP_HEADER_CONTACT_BIT | - SIP_HEADER_ROUTE_BIT; - - if (ccb->local_msg_body.num_parts) { - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - } else { - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - // CreateRequest adds the request line, Via, Date, CSeq, User-Agent - // and all the headers in the messageflags above. It will also write - // the new SDP which it picks from the ccb (ccb->sip_sdp) - if (CreateRequest(ccb, messageflag, sipMethodUpdate, request, FALSE, 0)) { - flag = STATUS_SUCCESS; - } else { - flag = STATUS_FAILURE; - } - - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: UPDATE message build unsuccessful.", - fname); - clean_method_request_trx(ccb, sipMethodUpdate, TRUE); - return (FALSE); - } - // Send the request - ccb->retx_counter = 0; - if (SendRequest(ccb, request, sipMethodUpdate, TRUE, TRUE, FALSE) == FALSE) { - clean_method_request_trx(ccb, sipMethodUpdate, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -/************************************************************* - * Function: sipSPISendUpdateResponse - * This function creates, formats, and sends a response to an - * UPDATE message received on an early dialog - **************************************************************/ -boolean -sipSPISendUpdateResponse (ccsipCCB_t *ccb, - boolean send_sdp, - cc_causes_t cause, - boolean retx) -{ - const char *fname = "SIPSPISendUpdateResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int statusCode; - char *reason_phrase; - boolean result; - - // Determine the statusCode and reason_phrase from the cause value - statusCode = ccsip_cc_to_sip_cause(cause, &reason_phrase); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, statusCode); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_ALLOW_BIT; - - if (send_sdp) { - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - } else { - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - } - - if (statusCode == SIP_CLI_ERR_EXTENSION) { - messageflag.flags |= SIP_HEADER_UNSUPPORTED_BIT; - } - if (statusCode == SIP_SERV_ERR_INTERNAL) { - messageflag.flags |= SIP_HEADER_RETRY_AFTER_BIT; - } - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, (uint16_t)statusCode, - response, reason_phrase, 0, NULL, sipMethodUpdate)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) - free_sip_message(response); - clean_method_request_trx(ccb, sipMethodUpdate, FALSE); - return (FALSE); - } - - result = sendResponse(ccb, response, ccb->last_request, retx, - sipMethodUpdate); - clean_method_request_trx(ccb, sipMethodUpdate, FALSE); - return result; -} - -boolean -sipSPISendNotifyResponse (ccsipCCB_t *ccb, cc_causes_t cause) -{ - const char *fname = "SIPSPISendNotifyResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int sip_response_code; - char *sip_response_phrase; - boolean result; - - sip_response_code = ccsip_cc_to_sip_cause(cause, &sip_response_phrase); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, sip_response_code); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_CONTENT_LENGTH_BIT; - - /* Add Content Length */ - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, (unsigned short)sip_response_code, - response, sip_response_phrase, 0, NULL, sipMethodNotify)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) - free_sip_message(response); - clean_method_request_trx(ccb, sipMethodNotify, FALSE); - return (FALSE); - } - - result = sendResponse(ccb, response, ccb->last_request, FALSE, - sipMethodNotify); - clean_method_request_trx(ccb, sipMethodNotify, FALSE); - return result; -} - -/* - * sipSPIGenerateReferredByHeader - * - * This function is called to generate SIP Referred-By Header - * when SIP REFER request is sent, to Transfer the call - * - * @param[in,out] ccb CCB call info structure - * - * @return TRUE if the header is successfully - * created; FALSE otherwise. - * - * @pre (ccb not_eqs NULL) - * - */ -boolean -sipSPIGenerateReferredByHeader (ccsipCCB_t *ccb) -{ - char line_name[MAX_LINE_NAME_SIZE]; - char escaped_line_name[MAX_ESCAPED_USER_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char pReferByStr[MAX_SIP_URL_LENGTH]; - boolean retval = FALSE; - cpr_ip_type ip_type; - - /* Initialize */ - line_name[0] = '\0'; - escaped_line_name[0] = '\0'; - dest_sip_addr_str[0] = '\0'; - pReferByStr[0] = '\0'; - - /* - * get Server Ip Addr, line_name and form AOR to populate referredBy - */ - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - - if (line_name[0] != '\0') { - (void) sippmh_convertURLCharToEscChar(line_name, strlen(line_name), - escaped_line_name, - sizeof(escaped_line_name), - TRUE); - } - - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, dest_sip_addr_str); - - if (escaped_line_name[0] != '\0') { - if (ip_type == CPR_IP_ADDR_IPV6) { - snprintf(pReferByStr, MAX_SIP_URL_LENGTH, "", - escaped_line_name, dest_sip_addr_str); - } else { - snprintf(pReferByStr, MAX_SIP_URL_LENGTH, "", - escaped_line_name, dest_sip_addr_str); - } - } - - if (pReferByStr[0] != '\0') { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, pReferByStr); - retval = TRUE; - } - - return (retval); -} - -/* - * Function: sipSPIBuildRegisterHeaders - * - * Parameters: - * ccsipCCB_t * - pointer to the ccb used for registration - * const char * user - used to build the headers - * int expires_int - registration expiry time - * - * Description: The function builds the register message - * - * Returns: - * sipMessage_t * - pointer to the sip request - * - */ -sipMessage_t * -sipSPIBuildRegisterHeaders(ccsipCCB_t *ccb, - const char *user, - int expires_int) -{ - const char fname[] = "sipSPIBuildRegisterHeaders"; - char *sip_from_temp; - char *sip_to_temp; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char expires[MAX_EXPIRES_LEN]; - sipMessageFlag_t messageflag; - char reg_user_info[MAX_REG_USER_INFO_LEN]; - char escaped_user[MAX_ESCAPED_USER_LEN]; - char *sip_from_tag; - sipMessage_t *request = NULL; - - (void) sippmh_convertURLCharToEscChar(user, strlen(user), - escaped_user, sizeof(escaped_user), - TRUE); - /* get reg_user_info */ - config_get_string(CFGID_REG_USER_INFO, reg_user_info, - sizeof(reg_user_info)); - ipaddr2dotted(src_addr_str, &ccb->src_addr); - - sstrncpy(dest_sip_addr_str, ccb->reg.proxy, MAX_IPADDR_STR_LEN); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "REGISTER"); - - // Create a new From header only if the previous one in the CCB is blank. - // It will not be blank if we received a 401/407 response to a prior - // REGISTER request where we reuse the CCB that we first used without - // cleaning it. - - if (ccb->sip_from[0] == '\0') { - sip_from_temp = strlib_open(ccb->sip_from, MAX_SIP_URL_LENGTH); - if (sip_from_temp) { - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } - /* Now add tag to the From header */ - sip_from_tag = strlib_open(ccb->sip_from_tag, MAX_SIP_URL_LENGTH); - if (sip_from_tag) { - sip_util_make_tag(sip_from_tag); - sstrncat(sip_from_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - sstrncat(sip_from_temp, sip_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - ccb->sip_from_tag = strlib_close(sip_from_tag); - } - ccb->sip_from = strlib_close(sip_from_temp); - } - sip_to_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - snprintf(sip_to_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } else { - snprintf(sip_to_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } - ccb->sip_to = strlib_close(sip_to_temp); - /* - * Build A request from Message Factory using following Flags... - * You do not need to specify common headers they will automatically - * get added - */ - - messageflag.flags = 0; - - messageflag.flags |= SIP_HEADER_CONTACT_BIT | - SIP_HEADER_SUPPORTED_BIT | - SIP_HEADER_CISCO_GUID_BIT; - - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - - - if (ccb->authen.authorization != NULL) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - - if (ccb->send_reason_header) { - messageflag.flags |= SIP_HEADER_REASON_BIT; - } - - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodRegister, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - UPDATE_FLAGS(flag, tflag); - - snprintf(expires, sizeof(expires), "%d", expires_int); - tflag = sippmh_add_text_header(request, SIP_HEADER_EXPIRES, expires); - - UPDATE_FLAGS(flag, tflag); - - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: REGISTER message build unsuccessful.", - fname); - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - return (NULL); - } - - return (request); -} - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform.c deleted file mode 100644 index 77b68e1dfd9..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform.c +++ /dev/null @@ -1,122 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "phone.h" -#include "phone_debug.h" -#include "ccsip_register.h" -#include "ccsip_task.h" -#include "ccsip_pmh.h" -#include "config.h" -#include "sip_common_transport.h" -#include "sip_csps_transport.h" -#include "uiapi.h" -#include "sip_interface_regmgr.h" - -#include "platform_api.h" - -extern void platform_sync_cfg_vers(char *cfg_ver, char *dp_ver, char *softkey_ver); -extern void platform_reg_failover_ind(void *data); -extern void platform_reg_fallback_ind(void *data); -extern int platGetUnregReason(); -extern void ccsip_add_wlan_classifiers(); -void ccsip_remove_wlan_classifiers(); - -/* - * Function: sip_platform_init() - * - * Parameters: None - * - * Description: Performs platform initialization stuff. Should probably be - * renamed or moved to make it more "generic". - * - * Returns: None - * - */ -void -sip_platform_init (void) -{ - - // Since we have all our configuration information now - // we want to do a final check to see if our network media - // type has changed - - /* Unregister the phone */ - ccsip_register_cancel(FALSE, TRUE); - ccsip_register_reset_proxy(); - - /* - * Make sure that the IP stack is up before trying to connect - */ - if (PHNGetState() > STATE_IP_CFG) { - - ccsip_add_wlan_classifiers(); - /* - * regmgr - The SIPTaskDisconnectFromSipProxies and - * SIPTaskConnectToSipProxies calls will be called - * as part of the transport interface init and regmgr - * inits. - */ - - ccsip_register_all_lines(); - ui_sip_config_done(); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "IP Stack Not Initialized.", "sip_platform_init"); - } -} - - -/* - * Send StationReset message - * Parameters supplied by application: - * none - * Parameters supplied in the message - * - reset type (RESTART) - */ -int -sip_platform_ui_restart (void) -{ - phone_reset(DEVICE_RESTART); - return TRUE; -} - - -void -sip_platform_handle_service_control_notify (sipServiceControl_t *scp) -{ - switch (scp->action) { - - case SERVICE_CONTROL_ACTION_RESET: - platform_reset_req(DEVICE_RESET); - break; - - case SERVICE_CONTROL_ACTION_RESTART: - platform_reset_req(DEVICE_RESTART); - break; - - case SERVICE_CONTROL_ACTION_CHECK_VERSION: - platform_sync_cfg_vers(scp->configVersionStamp, - scp->dialplanVersionStamp, - scp->softkeyVersionStamp); - break; - - case SERVICE_CONTROL_ACTION_APPLY_CONFIG: - // call the function to process apply config NOTIFY message. - platform_apply_config(scp->configVersionStamp, - scp->dialplanVersionStamp, - scp->fcpVersionStamp, - scp->cucm_result, - scp->firmwareLoadId, - scp->firmwareInactiveLoadId, - scp->loadServer, - scp->logServer, - scp->ppid); - break; - default: - break; - - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tcp.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tcp.c deleted file mode 100644 index 228ce93491c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tcp.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_platform_timers.h" -#include "text_strings.h" -#include "ccsip_register.h" -#include "phntask.h" -#include "plat_api.h" -#include "sip_socket_api.h" - - -/* - * Externs - */ -extern cc_config_table_t CC_Config_Table[]; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern cpr_sockaddr_t *sip_set_sockaddr(cpr_sockaddr_storage *psock_storage, uint16_t family, - cpr_ip_addr_t ip_addr, uint16_t port, uint16_t *addr_len); -extern void ccsip_dump_recv_msg_info(sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port); - -#define MAX_CHUNKS 12 -#define MAX_PAYLOAD_SIZE (MAX_CHUNKS*CPR_MAX_MSG_SIZE) -/* - * Globals - */ -static uint32_t sip_tcp_incomplete_msg = 0; -static uint32_t sip_tcp_fail_network_msg = 0; -int max_tcp_send_msg_q_size = 0; -int max_tcp_send_msg_q_connid = 0; -cpr_ip_addr_t max_tcp_send_msg_q_ipaddr = {0,{0}}; -ushort max_tcp_send_msg_q_port = 0; - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -static ccsipRet_e -ccsipSocketSetNonblock (cpr_socket_t fd, int optval) -{ - const char *fname = "ccsipSocketSetNonblock"; - - if (cprSetSockNonBlock(fd)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set non-blocking socket mode %d", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - return SIP_SUCCESS; -} - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -static ccsipRet_e -ccsipSocketSetKeepAlive (cpr_socket_t fd, int optval) -{ - const char *fname = "ccsipSocketSetKeepAlive"; - - if (cprSetSockOpt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, - sizeof(optval))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set KEEP ALIVE on a socket %d", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - - return SIP_SUCCESS; -} - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -#ifdef NOT_AVAILABLE_WIN32 -static ccsipRet_e -ccsipSocketSetTCPtos (cpr_socket_t fd, uint8_t optval) -{ - const char *fname = "ccsipSocketSetTCPtos"; - - if (cprSetSockOpt(fd, SOL_TCP, TCP_TOS, (void *)&optval, - sizeof(optval))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set TCP TOS on a socket %d", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - - return SIP_SUCCESS; -} - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -static ccsipRet_e -ccsipSocketSetPushBit (cpr_socket_t fd, int optval) -{ - const char *fname = "ccsipSocketSetPushBit"; - - if (cprSetSockOpt(fd, SOL_TCP, TCP_ALWAYSPUSH, (void *)&optval, - sizeof(optval))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set PUSH BIT on a socket %d", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - - return SIP_SUCCESS; -} -#endif /* NOT_AVAILABLE_WIN32 */ - -static boolean ccsipIsSecureType(sipSPIConnId_t connid) -{ - if (sip_tcp_conn_tab[connid].soc_type == SIP_SOC_TLS) { - return TRUE; - } - return FALSE; -} -/** - * - * sip_tcp_attach_socket - * - * Attach the socket to the select call - * - * Parameters: s - the socket - * - * Return Value: SIP_OK or SIP_ERROR - * - * Remarks: No check is made to see if socket is already attached - * - */ -int -sip_tcp_attach_socket (cpr_socket_t s) -{ - int i; - - /* - * Attach socket to select call - */ - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - if (sip_conn.read[i] == INVALID_SOCKET) { - sip_conn.read[i] = s; - FD_SET(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - sip_conn.write[i] = s; - FD_SET(s, &write_fds); - break; - } - } - - /* - * Are there already too many connections? - */ - if (i == MAX_SIP_CONNECTIONS) { - return SIP_ERROR; - } - return SIP_OK; -} - -/** - * - * sip_tcp_detach_socket - * - * Attach the socket to the select call - * - * Parameters: s - the socket - * - * Return Value: SIP_OK or SIP_ERROR - * - * Remarks: No check is made to see if socket is already attached - * - */ -static int -sip_tcp_detach_socket (cpr_socket_t s) -{ - int i; - const char *fname = "sip_tcp_detach_socket"; - - if (s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid socket", fname); - return SIP_ERROR; - } - /* - * Attach socket to select call - */ - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - if (sip_conn.read[i] == s) { - sip_conn.read[i] = INVALID_SOCKET; - FD_CLR(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - sip_conn.write[i] = INVALID_SOCKET; - FD_CLR(s, &write_fds); - break; - } - } - - /* - * Are there already too many connections? - */ - if (i == MAX_SIP_CONNECTIONS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Max TCP connections reached.", fname); - return SIP_ERROR; - } - return SIP_OK; -} - -/** - * - * sip_tcp_set_sock_options - * - * Attach the socket to the select call - * - * Parameters: fd - the file descriptor - * - * Return Value: SIP_OK or SIP_ERROR - * - * Remarks: No check is made to see if socket is already attached - * - */ -boolean -sip_tcp_set_sock_options (int fd) -{ - int optval; - ccsipRet_e status = SIP_SUCCESS; - - optval = 1; - - /* Set non-blocking mode */ - status = ccsipSocketSetNonblock(fd, optval); - if (status != SIP_SUCCESS) { - return FALSE; - } - - /* Set the keepalive option */ - status = ccsipSocketSetKeepAlive(fd, optval); - if (status != SIP_SUCCESS) { - return FALSE; - } - - return TRUE; -} - -/** - * - * sip_tcp_fd_to_connid - * - * returns the tcp conn table index for a particular socket - * - * Parameters: fd - the file descriptor - * - * Return Value: sip_tcp_conn_tab index - * - */ -int -sip_tcp_fd_to_connid (cpr_socket_t fd) -{ - int i; - - for (i = 0; i < MAX_CONNECTIONS; ++i) { - if (sip_tcp_conn_tab[i].fd == fd) { - return i; - } - } - return -1; -} - -/* - * sip_tcp_get_free_conn_entry () - * - * Description : This procedure returns the first free entry from the TCP - * conn table. - * - * Input Params : None. - * - * Returns : Index to the Connection table (if SUCCESSFUL) - * -1 in case of failure. - */ -int -sip_tcp_get_free_conn_entry (void) -{ - int i; - const char *fname = "sip_tcp_get_free_conn_entry"; - - for (i = 0; i < MAX_CONNECTIONS; ++i) { - if (sip_tcp_conn_tab[i].fd == -1) { - /* Zero the connection table entry */ - memset((sip_tcp_conn_tab + i), 0, sizeof(sip_tcp_conn_t)); - sip_tcp_conn_tab[i].state = SOCK_IDLE; - sip_tcp_conn_tab[i].dirtyFlag = FALSE; - sip_tcp_conn_tab[i].error_cause = SOCKET_NO_ERROR; - return i; - } - } - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TCP Connection table full", fname); - - return -1; -} - -/* - * sip_tcp_init_conn_table() - * Description : Cleans up the entry associated with the connid - * from the sip_tcp_conn_tab - * - * Input : void - * - * Output : void - * - */ -void -sip_tcp_init_conn_table (void) -{ - static boolean initial_call = TRUE; - int idx; - - if (initial_call) { - /* - * Initialize the tcp conn table - */ - for (idx = 0; idx < MAX_CONNECTIONS; ++idx) { - sip_tcp_conn_tab[idx].fd = -1; - } - initial_call = FALSE; - } -} - -/* - * sip_tcp_purge_entry() - * Description : Cleans up the entry associated with the connid - * from the sip_tcp_conn_tab - * - * Input : connid - * - * Output : None - * - */ -void -sip_tcp_purge_entry (sipSPIConnId_t connid) -{ - sip_tcp_conn_t *entry = sip_tcp_conn_tab + connid; - const char *fname= "sip_tcp_purge_entry"; - boolean secure; - - if (!VALID_CONNID(connid)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid TCP connection Id=%ld.", - fname, connid); - return; - } - secure = ccsipIsSecureType(connid); - - (void) sip_tcp_detach_socket(entry->fd); - (void) sipSocketClose(entry->fd, secure); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Socket fd: %d closed for connid %ld with " - "address: %p, remote port: %u\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), entry->fd, connid, &entry->ipaddr, entry->port); - - entry->fd = -1; /* Free the connection table entry in the BEGINNING ! */ - sipTcpFlushRetrySendQueue(entry); - entry->ipaddr = ip_addr_invalid; - entry->port = 0; - entry->context = NULL; - entry->dirtyFlag = FALSE; - if (entry->prev_bytes) { - cpr_free(entry->prev_msg); - } - return; -} - - -/* - * sip_tcp_create_connection() - * Description : This routine is called is response to a create connection - * request from SIP_SPI to SIP_TCP. - * - * Input : spi_msg - Pointer to sipSPIMessage_t containing the create conn - * parameters. - * - * Output : Nothing - */ -cpr_socket_t -sip_tcp_create_connection (sipSPIMessage_t *spi_msg) -{ - const char* fname = "sip_tcp_create_connection"; - int idx; - cpr_socket_t new_fd; - cpr_sockaddr_storage *local_addr_ptr; - sipSPICreateConnection_t *create_msg; - cpr_sockaddr_t local_addr; - cpr_socklen_t local_addr_len = sizeof(cpr_sockaddr_t); - int tos_dscp_val = 0; // set to default if there is no config. for dscp -#ifdef IPV6_STACK_ENABLED - - int ip_mode = CPR_IP_MODE_IPV4; -#endif - uint16_t af_listen = AF_INET6; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - cpr_sockaddr_storage local_sock_addr; - cpr_ip_addr_t local_ipaddr; - - sip_tcp_init_conn_table(); - create_msg = &(spi_msg->createConnMsg); - CPR_IP_ADDR_INIT(local_ipaddr); - -#ifdef IPV6_STACK_ENABLED - - config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - - /* - * Create a socket - */ - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_listen = AF_INET6; - } else { -#endif - af_listen = AF_INET; -#ifdef IPV6_STACK_ENABLED - } -#endif - - /* Create New connection to the (addr,port) pair */ - new_fd = cprSocket(af_listen, SOCK_STREAM, 0 /* IPPROTO_TCP */); - if (new_fd < 0) { - /* Send create connection failed message to SIP_SPI */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Socket creation failed %d.", - fname, cpr_errno); - return INVALID_SOCKET; - } - idx = sip_tcp_get_free_conn_entry(); - if (idx == -1) { - /* Send create connection failed message to SIP_SPI */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No Free connection entry.", - fname); - (void) sipSocketClose(new_fd, FALSE); - return INVALID_SOCKET; - } - - if (sip_tcp_set_sock_options(new_fd) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Socket set option failed.", - fname); - } - - sip_config_get_net_device_ipaddr(&local_ipaddr); - - memset(&local_sock_addr, 0, sizeof(local_sock_addr)); - - (void) sip_set_sockaddr(&local_sock_addr, af_listen, local_ipaddr, 0, &addr_len); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"local_ipaddr.u.ip4=%x", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), local_ipaddr.u.ip4); - - if (cprBind(new_fd, (cpr_sockaddr_t *)&local_sock_addr, addr_len)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TCP bind failed with error %d", fname, - cpr_errno); - (void) sipSocketClose(new_fd, FALSE); - sip_tcp_conn_tab[idx].fd = INVALID_SOCKET; - return INVALID_SOCKET; - } - - memset(&sock_addr, 0, sizeof(sock_addr)); - - (void) sip_set_sockaddr(&sock_addr, af_listen, create_msg->addr, - (uint16_t)(create_msg->port), &addr_len); - - sip_tcp_conn_tab[idx].fd = new_fd; - sip_tcp_conn_tab[idx].ipaddr = create_msg->addr; - sip_tcp_conn_tab[idx].port = create_msg->port; - sip_tcp_conn_tab[idx].context = spi_msg->context; - sip_tcp_conn_tab[idx].dirtyFlag = FALSE; - sip_tcp_conn_tab[idx].addr = sock_addr; - - if (cprConnect(new_fd, (cpr_sockaddr_t *)&sock_addr, addr_len) - == CPR_FAILURE) { - if (errno == EWOULDBLOCK || errno == EINPROGRESS) { - char ipaddr_str[MAX_IPADDR_STR_LEN]; - - ipaddr2dotted(ipaddr_str, &create_msg->addr); - - /* connect in progress. Include this socket in select */ - sip_tcp_conn_tab[idx].state = SOCK_CONNECT_PENDING; - - CCSIP_DEBUG_MESSAGE(SIP_F_PREFIX"socket connection in progress errno:%d" - "ipaddr: %s, port: %d\n", - fname, errno, ipaddr_str, create_msg->port); - } else { - char ipaddr_str[MAX_IPADDR_STR_LEN]; - - ipaddr2dotted(ipaddr_str, &create_msg->addr); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket connect failed errno: %d " - "ipaddr: %s, port: %d\n", - fname, errno, ipaddr_str, create_msg->port); - sip_tcp_purge_entry(idx); - return INVALID_SOCKET; - } - } else { - /* Even for this non-blocking socket, the connection was - * completed immediately. Is that a possibility ?? - * I am not sure. Just send a connectioncreated msg to SIP_SPI - */ - sip_tcp_conn_tab[idx].state = SOCK_CONNECTED; - } - - if (cprGetSockName(new_fd, &local_addr, &local_addr_len) != CPR_FAILURE) { - local_addr_ptr = (cpr_sockaddr_storage *)&local_addr; - - if (local_addr_ptr->ss_family == AF_INET6) { - - create_msg->local_listener_port = ntohs(((cpr_sockaddr_in6_t *)local_addr_ptr)->sin6_port); - - } else { - - create_msg->local_listener_port = ntohs(((cpr_sockaddr_in_t *)local_addr_ptr)->sin_port); - } - - (void) sip_tcp_attach_socket(new_fd); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error getting local port info.", - fname); - sip_tcp_purge_entry(idx); - return INVALID_SOCKET; - } - - // set IP tos/dscp value for SIP messaging - config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val, - sizeof(tos_dscp_val)); - if (cprSetSockOpt(new_fd, SOL_IP, IP_TOS, (void *)&tos_dscp_val, - sizeof(tos_dscp_val)) == CPR_FAILURE) { - // do NOT take hard action; just log the error and move on - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set IP TOS %d on TCP socket. cpr_errno = %d", - fname, tos_dscp_val, cpr_errno); - } - - return (new_fd); -} - -/* - * sip_tcp_newmsg_to_spi() - * Description : This routine is called to parse a tcp packet - * and send it to the spi for further processing. - * - * Input : buf: pointer to the message - * nbytes: length of the message - * connID: connid over which the message was received - * - * Output : success / failure in processing - */ -static int -sip_tcp_newmsg_to_spi (char *buf, unsigned long nbytes, int connID) -{ - static const char *fname = "sip_tcp_newmsg_to_spi"; - sipMessage_t *sip_msg; - ccsipRet_e val; - cpr_sockaddr_storage from; - char *disply_msg_buff = NULL; - char **display_msg_buff_p; - boolean error; - cpr_ip_addr_t ip_addr; - - CPR_IP_ADDR_INIT(ip_addr); - - /* Set up display msg. if debug msg. is enabled */ - if (SipDebugMessage) { - display_msg_buff_p = &disply_msg_buff; - } else { - /* No display msg. is needed */ - display_msg_buff_p = NULL; - } - - do { - disply_msg_buff = NULL; - error = FALSE; - val = ccsip_process_network_message(&sip_msg, &buf, &nbytes, - display_msg_buff_p); - - switch (val) { - case SIP_SUCCESS: - /* - * Print the received TCP packet info - */ - if (disply_msg_buff != NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"RCV: TCP message=", fname); - platform_print_sip_msg(disply_msg_buff); - } - from = sip_tcp_conn_tab[connID].addr; - - util_extract_ip(&ip_addr, &from); - ccsip_dump_recv_msg_info(sip_msg, &ip_addr, 0); - /* Process SIP message */ - SIPTaskProcessTCPMessage(sip_msg, from); - break; - - case SIP_MSG_INCOMPLETE_ERR: - - sip_tcp_conn_tab[connID].prev_msg = cpr_strdup(buf); - if (sip_tcp_conn_tab[connID].prev_msg) { - sip_tcp_conn_tab[connID].prev_bytes = nbytes; - } - sip_tcp_incomplete_msg++; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP Incomplete message.%d",fname, - sip_tcp_incomplete_msg); - error = TRUE; - break; - - case SIP_MSG_PARSE_ERR: - /* - * Print the received TCP packet info - */ - if (disply_msg_buff != NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"RCV: TCP message=", fname); - platform_print_sip_msg(disply_msg_buff); - } - sip_tcp_fail_network_msg++; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP Message Parse error %d.", fname, - sip_tcp_fail_network_msg); - error = TRUE; - break; - - case SIP_MSG_CREATE_ERR: - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP Message create error.", fname); - error = TRUE; - break; - } - - /* Free display msg. buffer if it is allocated */ - if (disply_msg_buff != NULL) { - cpr_free(disply_msg_buff); - disply_msg_buff = NULL; - } - - if (error) { - /* There was an error encountered, exit */ - return -1; - } - } while (nbytes > 0); - return 0; -} - -void -sip_tcp_createconnfailed_to_spi (cpr_ip_addr_t *ipaddr, - uint16_t port, - void *context, - ccsipSockErrCodes_e errcode, - int connid) -{ - static const char *fname = "sip_tcp_createconnfailed_to_spi"; - ccsipCCB_t *ccb = NULL; - ti_config_table_t *ccm_active_table_entry = NULL, - *ccm_standby_table_entry = NULL, - *ccm_table_entry = NULL; - ti_common_t *active_ti_common = NULL; - ti_common_t *standby_ti_common = NULL; - uint32_t retx_value; - char ip_addr_str[MAX_IPADDR_STR_LEN]; - - - /* - * Use LINE1 for now as there is only one type of cc - * supported, no mixed mode. Will have to change when - * we add mixed mode cc support on the phone. - */ - if (CC_Config_Table[LINE1].cc_type == CC_CCM) { - - /* - * Check and see which tcp link went down, active / - * standby and get the appropriate reg ccb. - * Using ipaddr:port combination to find if the active - * or the standby went down. To use fd we will have to - * write a routine to return connid of the tcp conn table - * for an ipaddr:port combination. - */ - ccm_active_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - ccm_standby_table_entry = CCM_Active_Standby_Table.standby_ccm_entry; - if (ccm_active_table_entry) { - active_ti_common = &ccm_active_table_entry->ti_common; - } - if (ccm_standby_table_entry) { - standby_ti_common = &ccm_standby_table_entry->ti_common; - } - - ipaddr2dotted(ip_addr_str, ipaddr); - if (active_ti_common && util_compare_ip(&(active_ti_common->addr), ipaddr) && - active_ti_common->port == port) { - /* - * Active link has gone down - */ - int last_cpr_err = cpr_errno; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Active server going down due to " - "%s. ip_addr:%s\n", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - last_cpr_err == CPR_ETIMEDOUT ? "ETIMEDOUT": - last_cpr_err == CPR_ECONNABORTED ? "ECONNABORTED": - last_cpr_err == CPR_ECONNRESET ? "CM_RESET_TCP": "CM_CLOSED_TCP", - ip_addr_str); - - ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - ccm_table_entry = ccm_active_table_entry; - - } else if (standby_ti_common && - util_compare_ip(&(standby_ti_common->addr), ipaddr) && - standby_ti_common->port == port) { - /* - * Standby link has gone down - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Standby server going down " - "ip_addr=%s\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - ip_addr_str); - - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - ccm_table_entry = ccm_standby_table_entry; - } else { - /* - * Neither of the links, just return. - * This could happen with fall back ccm - */ - ccsipCCB_t *ccb_of_fallback = NULL; - - // Find fallback ccb and set the socket handle INVALID - if (sip_regmgr_find_fallback_ccb_by_addr_port(ipaddr, port, - &ccb_of_fallback)) { - if (ccb_of_fallback && (ccb_of_fallback->cc_cfg_table_entry)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Fallback server going " - " down ip_addr=%s\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - ip_addr_str); - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - (ti_config_table_t *)ccb_of_fallback->cc_cfg_table_entry); - } - } else { - sipTransportClearServerHandle(ipaddr, port, connid); - } - return; - } - /* - * In this case we need to make sure any pending - * calls are cleared as well... Need to make sure - * we clear that, because we are setting the local port - * to zero. So any one-time udp message that needs to get - * sent will have the port as 0 in the contact header. - */ - if (ccm_table_entry) { - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - (ti_config_table_t *) (ccm_table_entry)); - } else { - sipTransportClearServerHandle(ipaddr, port, connid); - } - /* - * Set the retx_counter to the configured retx_value - * so no more retries happen - */ - if (ccb != NULL) { - config_get_value(CFGID_SIP_RETX, &retx_value, sizeof(retx_value)); - ccb->retx_counter = retx_value + 1; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"send a SIP_TMR_REG_RETRY" - "message so this cucm ip:%s can be put in fallback list \n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), ip_addr_str); - if (ccsip_register_send_msg(SIP_TMR_REG_RETRY, ccb->index) - != SIP_REG_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"REG send message failed.", fname); - ccsip_register_cleanup(ccb, TRUE); - } - - } - } -} - -/* - * sip_tcp_read_socket() - * Description : After we come out of select call, for every valid socket in - * the connection table it - * 1. Checks it for readability - * 2. If it is readable, either accept the incoming connect (for master - * port) or receive data from network - * 3. Processes the data received from the network. - * - * Input : Value of read mask after call to socket_select() - * - * Output : Nothing - */ -void -sip_tcp_read_socket (cpr_socket_t this_fd) -{ - int nbytes; - char *sip_tcp_buf; - char temp; - int connid; - const char *fname="sip_tcp_read_socket"; - boolean secure; - - connid = sip_tcp_fd_to_connid(this_fd); - if (connid == -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Read failed for unknown socket %d.", - fname, this_fd); - return; - } - secure = ccsipIsSecureType(connid); - - if (sip_tcp_conn_tab[connid].state == SOCK_CONNECT_PENDING) { - int bytes_read = 0; - - /* This socket is now readable, connection complete. - * Inform SIP SPI - * Do a dummy read, if it is successful, change state - */ - bytes_read = sipSocketRecv(this_fd, &temp, 0, 0, secure); - if ((bytes_read != -1) || (errno == EWOULDBLOCK)) { - sip_tcp_conn_tab[connid].state = SOCK_CONNECTED; - } else if (errno == ENOTCONN) { - sip_tcp_conn_tab[connid].dirtyFlag = TRUE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=", fname, errno); - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - return; - } - } else { - unsigned long offset = sip_tcp_conn_tab[connid].prev_bytes; - - if (offset) { - sip_tcp_buf = (char *) cpr_realloc(sip_tcp_conn_tab[connid].prev_msg, - (offset + CPR_MAX_MSG_SIZE + 1)); - sip_tcp_conn_tab[connid].prev_bytes = 0; - - if (sip_tcp_buf == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to realloc tcp_msg buffer memory.", - fname); - cpr_free(sip_tcp_conn_tab[connid].prev_msg); - sip_tcp_conn_tab[connid].prev_msg = NULL; - return; - } - - nbytes = sipSocketRecv(this_fd, &sip_tcp_buf[offset], - CPR_MAX_MSG_SIZE, 0, secure); - - /* Ensure that we dont have too much buffered which may - * be due to some error conditions. - */ - if ((nbytes + offset) > (MAX_PAYLOAD_SIZE + 1)) { - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Total SIP message size of %lu " - "bytes exceeds maximum of %d bytes", - fname, (nbytes + offset), - (MAX_PAYLOAD_SIZE + 1)); - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Dropping SIP message %s", - fname, sip_tcp_buf); - cpr_free(sip_tcp_buf); - return; - } - } else { - sip_tcp_buf = (char *) cpr_malloc(CPR_MAX_MSG_SIZE + 1); - if (sip_tcp_buf == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to malloc tcp_msg buffer memory.", - fname); - return; - } - nbytes = sipSocketRecv(this_fd, sip_tcp_buf, CPR_MAX_MSG_SIZE, 0, secure); - } - - if (nbytes > 0) { - nbytes += offset; - sip_tcp_buf[nbytes] = 0; - (void) sip_tcp_newmsg_to_spi(sip_tcp_buf, nbytes, connid); - } else if ((nbytes == 0) || - ((nbytes == -1) && (errno != EWOULDBLOCK))) { - /* - * Remote connection closure or broken pipe - post a message - * to sip transport and wait for connection close command. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"CUCM closed TCP connection.", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname)); - sip_tcp_conn_tab[connid].error_cause = SOCKET_REMOTE_CLOSURE; - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=", fname, errno); - - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - // Clear proxy handle - if (CC_Config_Table[LINE1].cc_type != CC_CCM) { - sipTransportCSPSClearProxyHandle(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - this_fd); - sip_tcp_purge_entry(connid); - } - } - cpr_free(sip_tcp_buf); - } -} - -/* - ** sip_tcp_find_msg - * - * FILENAME: ip_phone\sip\ccsip_platform_tcp.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -sll_match_e -sip_tcp_find_msg (void *find_by_p, void *data_p) -{ - return (SLL_MATCH_FOUND); -} - -/* Socket is not writable. Queue the data to be sent. - * - * Inputs: - * total_len - total length of message - * connid - connection id - * buf - buffer of data to be written (this is the entire - * contents not just the remaining data. We do this - * so we can display the entire message when the last - * chunk is written. - * send_msg_display - boolean indicating whether the sent message - * is to be displayed for debugging etc. - */ -static void -sipTcpQueueSendData (int total_len, int connid, - char *buf, void *context, boolean send_msg_display, - uint8_t ip_sig_tos) -{ - static const char *fname = "sipTcpQueueSendData"; - ccsipTCPSendData_t *sendData; - sip_tcp_conn_t *entry; - int send_msg_q_size = 0; - - entry = sip_tcp_conn_tab + connid; - if (entry->sendQueue == NULL) { - entry->sendQueue = sll_create(sip_tcp_find_msg); - if (entry->sendQueue == NULL) { - CCSIP_DEBUG_ERROR("%s Failed to create sendQueue to buffer data!", fname); - return; - } - } - - sendData = (ccsipTCPSendData_t *) cpr_malloc(sizeof(ccsipTCPSendData_t)); - if (sendData == NULL) { - CCSIP_DEBUG_ERROR("%s Failed to allocate memory for sendData!", fname); - return; - } - memset(sendData, 0, sizeof(ccsipTCPSendData_t)); - - sendData->data = (char *) cpr_malloc(total_len + 1); - - if (sendData->data) { - sstrncpy(sendData->data, buf, total_len); - } else { - CCSIP_DEBUG_ERROR("%s Failed to allocate memory for sendData->data!", fname); - cpr_free(sendData); - return; - } - - sendData->bytesSent = 0; - sendData->bytesLeft = (uint16_t) total_len; - sendData->context = context; - sendData->msg_display = send_msg_display; - sendData->ip_sig_tos = ip_sig_tos; - (void) sll_append(entry->sendQueue, sendData); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Data queued length %d", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), total_len); - - if (send_msg_q_size > max_tcp_send_msg_q_size) { - max_tcp_send_msg_q_size = send_msg_q_size; - max_tcp_send_msg_q_connid = connid; - max_tcp_send_msg_q_ipaddr = entry->ipaddr; - max_tcp_send_msg_q_port = entry->port; - } -} - -/* - * Free memory for any queued write data. - */ -void -sipTcpFlushRetrySendQueue (sip_tcp_conn_t *entry) -{ - ccsipTCPSendData_t *sendData = NULL; - - if (entry->sendQueue) { - sendData = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, sendData); - while (sendData) { - cpr_free(sendData->data); - (void) sll_remove(entry->sendQueue, sendData); - cpr_free(sendData); - sendData = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, NULL); - } - (void) sll_destroy(entry->sendQueue); - entry->sendQueue = NULL; - } -} - -void -sip_tcp_resend (int connid) -{ - static const char *fname = "sip_tcp_resend"; - ccsipTCPSendData_t *qElem = NULL; - sip_tcp_conn_t *entry; - int bytes_sent; - boolean secure; - - if (!VALID_CONNID(connid)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Resend failed for unknown socket %d.", - fname, connid); - return; - } - - secure = ccsipIsSecureType(connid); - - entry = sip_tcp_conn_tab + connid; - if (entry->sendQueue) { - qElem = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, NULL); -// ccsipSocketSetIPtos(entry->fd, qElem->ip_sig_tos); - while (qElem) { - while (qElem->bytesLeft) { - bytes_sent = sipSocketSend(entry->fd, &qElem->data[qElem->bytesSent], - qElem->bytesLeft, 0, secure); - if (bytes_sent > 0) { - qElem->bytesSent += bytes_sent; - qElem->bytesLeft -= bytes_sent; - } else { - if (errno == EWOULDBLOCK) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Socket blocked requeue data", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname)); - } else { - entry->error_cause = SOCKET_SEND_ERROR; - sipTcpFlushRetrySendQueue(entry); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=", fname, errno); - sip_tcp_createconnfailed_to_spi( - &(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - CCSIP_DEBUG_ERROR("%s: Socket send error." - "Purge queued entry data.\n", fname); - } - return; - } - } /* while (qElem->bytesLeft) */ - - cpr_free(qElem->data); - (void) sll_remove(entry->sendQueue, qElem); - cpr_free(qElem); - CCSIP_DEBUG_REG_STATE("%s: sent out successfully, dequeue an entry.", fname); - - qElem = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, NULL); - } /* while qElem */ - } -} - - -/* - * sip_tcp_channel_send() - * Description : This routine is called to send out a tcp message - * - * - * Input : s: socket to send the message over - * buf: message to send - * len: length of the message - * - * Output : success / failure in processing - */ -int -sip_tcp_channel_send (cpr_socket_t s, char *buf, uint32_t len) -{ - static const char *fname = "sip_tcp_channel_send"; - int bytesSent = 0, totalBytesSent = 0; - int connid = 0; - sip_tcp_conn_t *entry; - boolean secure; - - /* convert socket to connid */ - connid = sip_tcp_fd_to_connid(s); - if (!VALID_CONNID(connid)) { - CCSIP_DEBUG_ERROR("%s: Couldn't map socket to a valid connid!", fname); - return SIP_TCP_SEND_ERROR; - } - /* use connid we can get this socket's entry in sip_tcp_conn_tab[] */ - entry = sip_tcp_conn_tab + connid; - - /* secd requires that the socket should be in connected state - * to send message. Return if the status is pending. - * Currently this gets control in fallback state. The retry timer - * event in fallback state will resend the message. - */ - if ((sip_tcp_conn_tab[connid].soc_type == SIP_SOC_TLS) && - (sip_tcp_conn_tab[connid].state == SOCK_CONNECT_PENDING)) { - plat_soc_connect_status_e conn_status; - conn_status = platSecSockIsConnected(s); - if (conn_status == PLAT_SOCK_CONN_OK) { - sip_tcp_conn_tab[connid].state = SOCK_CONNECTED; - - } else if (conn_status == PLAT_SOCK_CONN_WAITING) { - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"tls socket waiting %d", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), s); - return SIP_TCP_SEND_OK; - - } else if (conn_status == PLAT_SOCK_CONN_FAILED) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=", fname, errno); - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TLS socket connect failed %d", - fname, s); - return SIP_TCP_SEND_ERROR; - } - } - - /* - * Check not exceeding max allowed payload size - */ - if (len >= MAX_PAYLOAD_SIZE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_TCP_PAYLOAD_TOO_LARGE), - fname, len, CPR_MAX_MSG_SIZE); - return SIP_TCP_SIZE_ERROR; - } - - /* - * Check to see if the send q is empty. If it is not, then - * queue the current message in the sendqueue so that it - * gets sent in order when the socket is ready. - */ - if (entry->sendQueue && sll_count(entry->sendQueue)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"%d Socket waiting on EWOULDBLOCK, " - " queueing data\n", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), connid); - sipTcpQueueSendData(len, connid, buf, NULL, TRUE, 0x0); - return SIP_TCP_SEND_OK; - } - - secure = ccsipIsSecureType(connid); - - while (len > 0) { - bytesSent = sipSocketSend(s, (void *)buf, (size_t) len, 0, secure); - if (bytesSent == SOCKET_ERROR) { - if (cpr_errno == CPR_EWOULDBLOCK) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"%d Socket EWOULDBLOCK while " - "sending, queueing data\n", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - connid); - sipTcpQueueSendData(len, connid, buf, NULL, - TRUE, 0x0); - break; - } - if (cpr_errno != CPR_ENOTCONN) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=", fname, errno); - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - } - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "sipSocketSend", cpr_errno); - return (cpr_errno== CPR_ENOTCONN? cpr_errno: SIP_TCP_SEND_ERROR); - } - len -= bytesSent; - totalBytesSent += bytesSent; - buf += bytesSent; - } - return SIP_TCP_SEND_OK; -} - -/* - * Free memory for any queued write data. - */ -void -sipTcpFreeSendQueue (int connid) -{ - static const char *fname = "sipTcpFreeSendQueue"; - sip_tcp_conn_t *entry; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Free TCP send queue for connid %d", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), connid); - if (!VALID_CONNID(connid)) { - return; - } - entry = sip_tcp_conn_tab + connid; - sipTcpFlushRetrySendQueue(entry); -} - -/* - * sip_tcp_create_conn_using_blocking_socket() - * Description : This routine is called to create blocking socket - * request from SIP_SPI to SIP_TCP. - * - * Input : spi_msg - Pointer to sipSPIMessage_t containing the create conn - * parameters. - * - * Output : socket fd - */ -cpr_socket_t -sip_tcp_create_conn_using_blocking_socket (sipSPIMessage_t *spi_msg) { - - cpr_socket_t server_conn_handle = INVALID_SOCKET; - - server_conn_handle = sip_tcp_create_connection(spi_msg); - - return server_conn_handle; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_timers.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_timers.c deleted file mode 100644 index 86d48cab077..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_timers.c +++ /dev/null @@ -1,989 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "phntask.h" -#include "text_strings.h" -#include "ccsip_platform.h" -#include "phone_debug.h" -#include "ccsip_task.h" -#include "ccsip_pmh.h" -#include "ccsip_register.h" -#include "ccsip_core.h" -#include "ccsip_subsmanager.h" - -/* - * Constants - */ - -/* - * Globals TODO: hang off of a single SIP global - */ -sipPlatformUITimer_t sipPlatformUISMTimers[MAX_CCBS]; -sipPlatformUIExpiresTimer_t sipPlatformUISMExpiresTimers[MAX_CCBS]; -sipPlatformUIExpiresTimer_t sipPlatformUISMRegExpiresTimers[MAX_CCBS]; -sipPlatformUIExpiresTimer_t sipPlatformUISMLocalExpiresTimers[MAX_CCBS]; -// This timer will kick in after 1xx in releasing state so if 2xx gets lost -// we will be able to kill the ccb -sipPlatformSupervisionTimer_t sipPlatformSupervisionTimers[MAX_TEL_LINES]; - -sipPlatformUITimer_t sipPlatformUISMSubNotTimers[MAX_SCBS]; -sipPlatformSupervisionTimer_t sipPlatformSubNotPeriodicTimer; -static cprTimer_t sipPlatformRegAllFailedTimer; -static cprTimer_t sipPlatformNotifyTimer; -static cprTimer_t sipPlatformStandbyKeepaliveTimer; -static cprTimer_t sipPlatformUnRegistrationTimer; -static cprTimer_t sipPassThroughTimer; -int -sip_platform_timers_init (void) -{ - static const char fname[] = "sip_platform_timers_init"; - static const char sipMsgTimerName[] = "sipMsg"; - static const char sipExpireTimerName[] = "sipExp"; - static const char sipRegTimeOutTimerName[] = "sipRegTimeout"; - static const char sipRegExpireTimerName[] = "sipRegExp"; - static const char sipLocalExpireTimerName[] = "sipLocalExp"; - static const char sipSupervisionTimerName[] = "sipSupervision"; - static const char sipSubNotTimerName[] = "sipSubNot"; - static const char sipSubNotPeriodicTimerName[] = "sipSubNotPeriodic"; - static const char sipRegAllFailedTimerName[] = "sipRegAllFailed"; - static const char sipNotifyTimerName[] = "sipNotify"; - static const char sipStandbyKeepaliveTimerName[] = "sipStandbyKeepalive"; - static const char sipUnregistrationTimerName[] = "sipUnregistration"; - static const char sipPassThroughTimerName[] = "sipPassThrough"; - - int i; - - for (i = 0; i < MAX_CCBS; i++) { - sipPlatformUISMTimers[i].timer = - cprCreateTimer(sipMsgTimerName, - SIP_MSG_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMTimers[i].reg_timer = - cprCreateTimer(sipRegTimeOutTimerName, - SIP_REG_TIMEOUT_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMExpiresTimers[i].timer = - cprCreateTimer(sipExpireTimerName, - SIP_EXPIRES_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMRegExpiresTimers[i].timer = - cprCreateTimer(sipRegExpireTimerName, - SIP_REG_EXPIRES_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMLocalExpiresTimers[i].timer = - cprCreateTimer(sipLocalExpireTimerName, - SIP_LOCAL_EXPIRES_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformUISMTimers[i].timer || - !sipPlatformUISMTimers[i].reg_timer || - !sipPlatformUISMExpiresTimers[i].timer || - !sipPlatformUISMRegExpiresTimers[i].timer || - !sipPlatformUISMLocalExpiresTimers[i].timer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create one or more" - " UISM timers: %d\n", fname, i); - return SIP_ERROR; - } - } - for (i = 0; i < MAX_TEL_LINES; i++) { - sipPlatformSupervisionTimers[i].timer = - cprCreateTimer(sipSupervisionTimerName, - SIP_SUPERVISION_TIMER, - TIMER_EXPIRATION, - sip_msgq); - } - for (i = 0; i < MAX_SCBS; i++) { - sipPlatformUISMSubNotTimers[i].timer = - cprCreateTimer(sipSubNotTimerName, - SIP_SUBNOT_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformUISMSubNotTimers[i].timer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Sub/Not" - " UISM timers: %d\n", fname, i); - return SIP_ERROR; - } - } - sipPlatformSubNotPeriodicTimer.timer = - cprCreateTimer(sipSubNotPeriodicTimerName, - SIP_SUBNOT_PERIODIC_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformSubNotPeriodicTimer.timer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create supervision timer: %d\n", - fname, i); - return SIP_ERROR; - } - - sipPlatformRegAllFailedTimer = - cprCreateTimer(sipRegAllFailedTimerName, - SIP_REGALLFAIL_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPlatformRegAllFailedTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create RegAllFailed timer\n", fname); - return SIP_ERROR; - } - /* - * Create the standby cc keepalive timer used by the - * registration Manager. - */ - sipPlatformStandbyKeepaliveTimer = - cprCreateTimer(sipStandbyKeepaliveTimerName, - SIP_KEEPALIVE_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformStandbyKeepaliveTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Standby" - " keepalive timer\n", fname); - return SIP_ERROR; - } - sipPlatformUnRegistrationTimer = - cprCreateTimer(sipUnregistrationTimerName, - SIP_UNREGISTRATION_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPlatformUnRegistrationTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Stanby keepalive timer\n", - fname); - return SIP_ERROR; - } - sipPlatformNotifyTimer = - cprCreateTimer(sipNotifyTimerName, - SIP_NOTIFY_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPlatformNotifyTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Notify timer\n", fname); - return SIP_ERROR; - } - - sipPassThroughTimer = - cprCreateTimer(sipPassThroughTimerName, - SIP_PASSTHROUGH_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPassThroughTimer) { - CCSIP_DEBUG_ERROR("%s: failed to create sip PassThrough timer", fname); - return SIP_ERROR; - } - - return SIP_OK; -} - -void -sip_platform_timers_shutdown (void) -{ - int i; - - for (i = 0; i < MAX_CCBS; i++) { - sip_platform_msg_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMTimers[i].timer); - sipPlatformUISMTimers[i].timer = NULL; - (void) cprDestroyTimer(sipPlatformUISMTimers[i].reg_timer); - sipPlatformUISMTimers[i].reg_timer = NULL; - - (void) sip_platform_expires_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMExpiresTimers[i].timer); - sipPlatformUISMExpiresTimers[i].timer = NULL; - - (void) sip_platform_register_expires_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMRegExpiresTimers[i].timer); - sipPlatformUISMRegExpiresTimers[i].timer = NULL; - - (void) sip_platform_localexpires_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMLocalExpiresTimers[i].timer); - sipPlatformUISMLocalExpiresTimers[i].timer = NULL; - } - - for (i = 0; i < MAX_TEL_LINES; i++) { - (void) sip_platform_supervision_disconnect_timer_stop(i); - (void) cprDestroyTimer(sipPlatformSupervisionTimers[i].timer); - sipPlatformSupervisionTimers[i].timer = NULL; - } - - for (i = 0; i < MAX_SCBS; i++) { - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[i]); - (void) cprDestroyTimer(sipPlatformUISMSubNotTimers[i].timer); - sipPlatformUISMSubNotTimers[i].timer = NULL; - } - (void) sip_platform_subnot_periodic_timer_stop(); - (void) cprDestroyTimer(sipPlatformSubNotPeriodicTimer.timer); - sipPlatformSubNotPeriodicTimer.timer = NULL; - (void) sip_platform_reg_all_fail_timer_stop(); - (void) cprDestroyTimer(sipPlatformRegAllFailedTimer); - sipPlatformRegAllFailedTimer = NULL; - (void) sip_platform_standby_keepalive_timer_stop(); - (void) cprDestroyTimer(sipPlatformStandbyKeepaliveTimer); - sipPlatformStandbyKeepaliveTimer = NULL; - (void) sip_platform_unregistration_timer_stop(); - (void) cprDestroyTimer(sipPlatformUnRegistrationTimer); - sipPlatformUnRegistrationTimer = NULL; - (void) sip_platform_notify_timer_stop(); - (void) cprDestroyTimer(sipPlatformNotifyTimer); - sipPlatformNotifyTimer = NULL; - (void) sip_platform_pass_through_timer_stop(); - (void) cprDestroyTimer(sipPassThroughTimer); - sipPassThroughTimer = NULL; -} - -/******************************************************** - * - * Message timer support functions for SIP SM - * - ********************************************************/ -void -sip_platform_msg_timers_init (void) -{ - static const char fname[] = "sip_platform_msg_timers_init"; - static long timer_init_complete = 0; - int i; - cprTimer_t timer, reg_timer; - - for (i = 0; i < MAX_CCBS; i++) { - if (timer_init_complete) { - if ((cprCancelTimer(sipPlatformUISMTimers[i].timer) - == CPR_FAILURE) || - (cprCancelTimer(sipPlatformUISMTimers[i].reg_timer) - == CPR_FAILURE)) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "cprCancelTimer"); - } - } - timer = sipPlatformUISMTimers[i].timer; - reg_timer = sipPlatformUISMTimers[i].reg_timer; - - if (sipPlatformUISMTimers[i].message_buffer != NULL) { - cpr_free(sipPlatformUISMTimers[i].message_buffer); - sipPlatformUISMTimers[i].message_buffer = NULL; - sipPlatformUISMTimers[i].message_buffer_len = 0; - } - - memset(&sipPlatformUISMTimers[i], 0, sizeof(sipPlatformUITimer_t)); - sipPlatformUISMTimers[i].timer = timer; - sipPlatformUISMTimers[i].reg_timer = reg_timer; - } - timer_init_complete = 1; - return; -} - - -int -sip_platform_msg_timer_start (uint32_t msec, - void *data, - int idx, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port, - boolean isRegister) -{ - static const char fname[] = "sip_platform_msg_timer_start"; - cprTimer_t timer; - - /* validate index */ - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - /* validate length */ - if (message_buffer_len >= SIP_UDP_MESSAGE_SIZE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG), - fname, message_buffer_len); - return SIP_ERROR; - } - - /* stop the timer if it is running */ - if (cprCancelTimer(sipPlatformUISMTimers[idx].timer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - if (cprCancelTimer(sipPlatformUISMTimers[idx].reg_timer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - if (sipPlatformUISMTimers[idx].message_buffer == NULL) { - sipPlatformUISMTimers[idx].message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (sipPlatformUISMTimers[idx].message_buffer == NULL) return SIP_ERROR; - } - else if (message_buffer != sipPlatformUISMTimers[idx].message_buffer) { - cpr_free(sipPlatformUISMTimers[idx].message_buffer); - sipPlatformUISMTimers[idx].message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (sipPlatformUISMTimers[idx].message_buffer == NULL) return SIP_ERROR; - } - - sipPlatformUISMTimers[idx].message_buffer_len = message_buffer_len; - sipPlatformUISMTimers[idx].message_buffer[message_buffer_len] = '\0'; - memcpy(sipPlatformUISMTimers[idx].message_buffer, message_buffer, - message_buffer_len); - sipPlatformUISMTimers[idx].message_type = (sipMethod_t) message_type; - sipPlatformUISMTimers[idx].ipaddr = *ipaddr; - sipPlatformUISMTimers[idx].port = port; - - /* start the timer */ - if (isRegister) { - timer = sipPlatformUISMTimers[idx].reg_timer; - } else { - timer = sipPlatformUISMTimers[idx].timer; - } - - if (cprStartTimer(timer, msec, data) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - cpr_free(sipPlatformUISMTimers[idx].message_buffer); - sipPlatformUISMTimers[idx].message_buffer = NULL; - sipPlatformUISMTimers[idx].message_buffer_len = 0; - return SIP_ERROR; - } - sipPlatformUISMTimers[idx].outstanding = TRUE; - return SIP_OK; -} - - -void -sip_platform_msg_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_msg_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return; - } - - if ((cprCancelTimer(sipPlatformUISMTimers[idx].timer) == CPR_FAILURE) || - (cprCancelTimer(sipPlatformUISMTimers[idx].reg_timer) == CPR_FAILURE)) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return; - } - sipPlatformUISMTimers[idx].outstanding = FALSE; -} - - -boolean -sip_platform_msg_timer_outstanding_get (int idx) -{ - return sipPlatformUISMTimers[idx].outstanding; -} - - -void -sip_platform_msg_timer_outstanding_set (int idx, boolean value) -{ - sipPlatformUISMTimers[idx].outstanding = value; -} - - -int -sip_platform_msg_timer_update_destination (int idx, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_msg_timer_update_destination"; - - if ((idx < TEL_CCB_START) || (idx > REG_BACKUP_CCB)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (ipaddr == NULL) { - sipPlatformUISMExpiresTimers[idx].ipaddr = ip_addr_invalid; - } else { - sipPlatformUISMTimers[idx].ipaddr = *ipaddr; - } - - sipPlatformUISMTimers[idx].port = port; - - return SIP_OK; -} - -/******************************************************** - * - * Expires timer support functions for SIP SM - * - ********************************************************/ -int -sip_platform_expires_timer_start (uint32_t msec, - int idx, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_expires_timer_start"; - - if (sip_platform_expires_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - if (ipaddr == NULL) { - sipPlatformUISMExpiresTimers[idx].ipaddr = ip_addr_invalid; - } else { - sipPlatformUISMExpiresTimers[idx].ipaddr = *ipaddr; - } - - sipPlatformUISMExpiresTimers[idx].port = port; - - //sip_platform_expires_timer_callback - if (cprStartTimer(sipPlatformUISMExpiresTimers[idx].timer, msec, - (void *) (long)idx) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_expires_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_expires_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformUISMExpiresTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_register_expires_timer_start (uint32_t msec, int idx) -{ - static const char fname[] = "sip_platform_register_expires_timer_start"; - - if (sip_platform_register_expires_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformUISMRegExpiresTimers[idx].timer, msec, - (void *)(long) idx) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_register_expires_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_register_expires_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformUISMRegExpiresTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - -/******************************************************** - * - * Local Expires timer support functions for SIP SM - * - ********************************************************/ -int -sip_platform_localexpires_timer_start (uint32_t msec, - int idx, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_localexpires_timer_start"; - - if (sip_platform_localexpires_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - sipPlatformUISMLocalExpiresTimers[idx].ipaddr = *ipaddr; - sipPlatformUISMLocalExpiresTimers[idx].port = port; - - //sip_platform_localexpires_timer_callback - if (cprStartTimer(sipPlatformUISMLocalExpiresTimers[idx].timer, msec, - (void *)(long) idx) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_localexpires_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_localexpires_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformUISMLocalExpiresTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -sipMethod_t -sip_platform_msg_timer_messageType_get (int idx) -{ - if ((idx >= TEL_CCB_START) && (idx <= REG_BACKUP_CCB)) { - if (sipPlatformUISMTimers[idx].outstanding) { - return sipPlatformUISMTimers[idx].message_type; - } - } - return sipMethodUnknown; -} - -/* - * Call disconnect timer - */ -int -sip_platform_supervision_disconnect_timer_start (uint32_t msec, int idx) -{ - static const char fname[] = "sip_platform_supervision_disconnect_timer_start"; - - if (sip_platform_supervision_disconnect_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformSupervisionTimers[idx].timer, msec, - (void *)(long) idx) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_supervision_disconnect_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_supervision_disconnect_timer_stop"; - - if ((idx < TEL_CCB_START) || (idx > TEL_CCB_END)) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_LINE_NUMBER_INVALID), fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformSupervisionTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - -void -sip_platform_post_timer (uint32_t cmd, void *data) -{ - static const char fname[] = "sip_platform_post_timer"; - uint32_t *timer_msg = NULL; - - /* grab msg buffer */ - timer_msg = (uint32_t *) SIPTaskGetBuffer(sizeof(uint32_t)); - if (!timer_msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SYSBUF_UNAVAILABLE), fname); - return; - } - *timer_msg = (long) data; - - /* Put it on the SIP message queue */ - if (SIPTaskSendMsg(cmd, (cprBuffer_t) timer_msg, sizeof(uint32_t), NULL) - == CPR_FAILURE) { - cpr_free(timer_msg); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Send msg failed.", fname); - } - return; -} - - -/**************************************************** - * Timer functions for Subscribe / Notify operations - ****************************************************/ - -int -sip_platform_msg_timer_subnot_start (uint32_t msec, - sipPlatformUITimer_t *timer_p, - uint32_t id, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_msg_timer_start_subnot"; - - sip_platform_msg_timer_subnot_stop(timer_p); - - if (message_buffer_len > SIP_UDP_MESSAGE_SIZE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG), - fname, message_buffer_len); - return SIP_ERROR; - } - - if (timer_p->message_buffer == NULL) { - timer_p->message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (timer_p->message_buffer == NULL) return SIP_ERROR; - } - else if (timer_p->message_buffer != message_buffer) { - cpr_free(timer_p->message_buffer); - timer_p->message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (timer_p->message_buffer == NULL) return SIP_ERROR; - } - - timer_p->message_buffer_len = message_buffer_len; - timer_p->message_buffer[message_buffer_len] = '\0'; - memcpy(timer_p->message_buffer, message_buffer, - message_buffer_len); - timer_p->message_type = - (sipMethod_t) message_type; - timer_p->ipaddr = *ipaddr; - timer_p->port = port; - - if (cprStartTimer(timer_p->timer, msec, (void *)(long)id) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "%s failed", - fname, "cprStartTimer"); - cpr_free(timer_p->message_buffer); - timer_p->message_buffer = NULL; - timer_p->message_buffer_len = 0; - return SIP_ERROR; - } - - return SIP_OK; - -} - -void -sip_platform_msg_timer_subnot_stop (sipPlatformUITimer_t *timer_p) -{ - static const char fname[] = "sip_platform_msg_timer_stop_subnot"; - - if (timer_p->message_buffer != NULL) { - cpr_free(timer_p->message_buffer); - timer_p->message_buffer = NULL; - } - if (cprCancelTimer(timer_p->timer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX "%s failed", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), "cprCancelTimer"); - return; - } -} - -void -sip_platform_subnot_msg_timer_callback (void *data) -{ - sip_platform_post_timer(SIP_TMR_MSG_RETRY_SUBNOT, data); -} - -int -sip_platform_subnot_periodic_timer_start (uint32_t msec) -{ - static const char fname[] = "sip_platform_subnot_periodic_timer_start"; - - if (sip_platform_subnot_periodic_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformSubNotPeriodicTimer.timer, msec, (void *) 0) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - -1, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - sipPlatformSubNotPeriodicTimer.started = TRUE; - return SIP_OK; -} - -int -sip_platform_subnot_periodic_timer_stop (void) -{ - static const char fname[] = "sip_platform_subnot_periodic_timer_stop"; - - if (sipPlatformSubNotPeriodicTimer.started == TRUE) { - if (cprCancelTimer(sipPlatformSubNotPeriodicTimer.timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - -1, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - } - sipPlatformSubNotPeriodicTimer.started = FALSE; - return SIP_OK; -} - -void -sip_platform_subnot_periodic_timer_callback (void *data) -{ - sip_platform_post_timer(SIP_TMR_PERIODIC_SUBNOT, data); -} - -/** - ** sip_platform_reg_all_fail_timer_start - * Starts a timer when all registrations fail. - * - * @param msec Value of the timer to be started - * - * @return SIP_OK if timer could be started; else SIP_ERROR - * - */ -int -sip_platform_reg_all_fail_timer_start (uint32_t msec) -{ - - static const char fname[] = "sip_platform_reg_all_fail_timer_start"; - if (sip_platform_reg_all_fail_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformRegAllFailedTimer, msec, NULL) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX - "Timer started for %u msecs", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -/** - ** sip_platform_reg_all_fail_timer_stop - * Stops the Reg-All Fail timer - * - * @param none - * - * @return SIP_OK if timer could be stopped; else SIP_ERROR - * - */ -int -sip_platform_reg_all_fail_timer_stop (void) -{ - static const char fname[] = "sip_platform_reg_all_fail_timer_stop"; - - if (cprCancelTimer(sipPlatformRegAllFailedTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -/**************************************************** - * Timer functions for standby cc keepalive operations - ****************************************************/ -int -sip_platform_standby_keepalive_timer_start (uint32_t msec) -{ - static const char fname[] = "sip_platform_standby_keepalive_timer_start"; - - if (sip_platform_standby_keepalive_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformStandbyKeepaliveTimer, msec, NULL) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_STATE(DEB_F_PREFIX - "Timer started for %u msecs", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -int -sip_platform_standby_keepalive_timer_stop () -{ - static const char fname[] = "sip_platform_standby_keepalive_timer_stop"; - - if (cprCancelTimer(sipPlatformStandbyKeepaliveTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -int -sip_platform_unregistration_timer_start (uint32_t msec, boolean external) -{ - static const char fname[] = "sip_platform_unregistration_timer_start"; - - if (sip_platform_unregistration_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformUnRegistrationTimer, msec, (void *)(long)external) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_STATE(DEB_F_PREFIX - "Timer started for %u msecs", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -int -sip_platform_unregistration_timer_stop () -{ - static const char fname[] = "sip_platform_unregistration_timer_stop"; - - if (cprCancelTimer(sipPlatformUnRegistrationTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -void -sip_platform_unregistration_callback (void *data) -{ - sip_platform_post_timer(SIP_TMR_SHUTDOWN_PHASE2, data); -} - -int -sip_platform_notify_timer_start (uint32_t msec) -{ - static const char fname[] = "sip_platform_notify_timer_start"; - - if (sip_platform_notify_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformNotifyTimer, msec, NULL) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_STATE(DEB_F_PREFIX - "Timer started for %u msecs", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -int -sip_platform_notify_timer_stop () -{ - static const char fname[] = "sip_platform_notify_timer_stop"; - - if (cprCancelTimer(sipPlatformNotifyTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -/*********************************************** - * PassThrough Timer - *********************************************** - ** sip_platform_pass_through_timer_start - * Starts a timer when all registrations fail. - * - * @param sec Value of the timer to be started - * - * @return SIP_OK if timer could be started; else SIP_ERROR - * - */ -int -sip_platform_pass_through_timer_start (uint32_t sec) -{ - static const char fname[] = "sip_platform_pass_through_timer_start"; - - if (sip_platform_pass_through_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - if (cprStartTimer(sipPassThroughTimer, sec*1000, NULL) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - CCSIP_DEBUG_REG_STATE("%s: Regmgr Pass Through Timer started for %u secs", fname, sec); - return SIP_OK; -} - - /** - ** sip_platform_pass_through_timer_stop - * Stops the Pass Through timer - * - * @param none - * - * @return SIP_OK if timer could be stopped; else SIP_ERROR - * - */ -int -sip_platform_pass_through_timer_stop (void) -{ - static const char fname[] = "sip_platform_pass_through_timer_stop"; - - if (cprCancelTimer(sipPassThroughTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tls.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tls.c deleted file mode 100644 index f6659eec091..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tls.c +++ /dev/null @@ -1,176 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "text_strings.h" -#include "ccsip_register.h" -#include "phntask.h" -#include "plat_api.h" -#include "sip_socket_api.h" - -#define HOST_SIZE 64 - - -cpr_socket_t sip_tls_create_connection(sipSPIMessage_t *spi_msg, - boolean blocking, - sec_level_t sec); -extern cpr_sockaddr_t *sip_set_sockaddr(cpr_sockaddr_storage *psock_storage, uint16_t family, - cpr_ip_addr_t ip_addr, uint16_t port, uint16_t *addr_len); - -/* - * sip_tls_create_connection() - * Description : This routine is called is response to a create connection - * request from SIP_SPI to SIP_TLS. - * - * Input : spi_msg - Pointer to sipSPIMessage_t containing the create conn - * parameters. - * blocking - connection mode; FALSE - nonblock; TRUE - block - * - * Output : Nothing - */ -cpr_socket_t -sip_tls_create_connection (sipSPIMessage_t *spi_msg, boolean blocking, - sec_level_t sec) -{ - const char fname[] = "sip_tls_create_connection"; - int idx; - sipSPICreateConnection_t *create_msg; - char ipaddr_str[MAX_IPADDR_STR_LEN]; - plat_soc_status_e ret; - cpr_socket_t sock = INVALID_SOCKET; - uint16_t sec_port = 0; - plat_soc_connect_status_e conn_status; - int tos_dscp_val = 0; // set to default if there is no config. for dscp -#ifdef IPV6_STACK_ENABLED - int ip_mode = CPR_IP_MODE_IPV4; -#endif - uint16_t af_listen = AF_INET6; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - int ip_mode = 0; // currently hardcoded to ipv4 - plat_soc_connect_mode_e conn_mode; - -#ifdef IPV6_STACK_ENABLED - - config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - - /* - * Create a socket - */ - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_listen = AF_INET6; - } else { -#endif - af_listen = AF_INET; -#ifdef IPV6_STACK_ENABLED - } -#endif - - sip_tcp_init_conn_table(); - create_msg = &(spi_msg->createConnMsg); - ipaddr2dotted(ipaddr_str, &create_msg->addr); - ret = platSecIsServerSecure(); - if (ret != PLAT_SOCK_SECURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Secure connection is not created because" - " there is no secure servers\n", fname); - return INVALID_SOCKET; - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX - "Creating secure connection\n", DEB_F_PREFIX_ARGS(SIP_TLS, fname)); - /* connect securely via TLS */ - config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val, - sizeof(tos_dscp_val)); - - if (sec == AUTHENTICATED) { - conn_mode = PLAT_SOCK_AUTHENTICATED; - } else if (sec == ENCRYPTED) { - conn_mode = PLAT_SOCK_ENCRYPTED; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Secure connection is not created. Security mode was" - " not encrypyted or authenticated.\n", fname); - conn_mode = PLAT_SOCK_NON_SECURE; - } - sock = platSecSocConnect(ipaddr_str, /* host */ - create_msg->port, /* port */ - ip_mode, /* ip mode, ipv4 = 0, ipv6 = 1, dual = 2 */ - blocking, /* 1 - block */ - tos_dscp_val, /* TOS value */ - conn_mode, /* The mode (Auth/Encry/None) */ - &sec_port); /* local port */ - - if (sock < 0) { - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Secure connect failed!!\n",fname); - return INVALID_SOCKET; - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX "Secure connect ok", DEB_F_PREFIX_ARGS(SIP_TLS, fname)); - if (!blocking) { - /* should not call this api in blocking mode */ - conn_status = platSecSockIsConnected(sock); - if (conn_status == PLAT_SOCK_CONN_FAILED) { - (void)sipSocketClose(sock, TRUE); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Establish non-blocking mode secure" - " connection failed!!\n", fname); - return INVALID_SOCKET; - } - } else { - conn_status = PLAT_SOCK_CONN_OK; - } - if (sip_tcp_set_sock_options(sock) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Socket set option failure", - fname); - } - - idx = sip_tcp_get_free_conn_entry(); - if (idx == -1) { - /* Send create connection failed message to SIP_SPI */ - (void)sipSocketClose(sock, TRUE); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Get free TCP connection entry failed\n", - fname); - return INVALID_SOCKET; - } - - memset(&sock_addr, 0, sizeof(sock_addr)); - (void) sip_set_sockaddr(&sock_addr, af_listen, create_msg->addr, - (uint16_t)(create_msg->port), &addr_len); - - sip_tcp_conn_tab[idx].fd = sock; - sip_tcp_conn_tab[idx].ipaddr = create_msg->addr; - sip_tcp_conn_tab[idx].port = create_msg->port; - sip_tcp_conn_tab[idx].context = spi_msg->context; - sip_tcp_conn_tab[idx].dirtyFlag = FALSE; - sip_tcp_conn_tab[idx].addr = sock_addr; - sip_tcp_conn_tab[idx].soc_type = SIP_SOC_TLS; - - if (conn_status == PLAT_SOCK_CONN_OK) { - sip_tcp_conn_tab[idx].state = SOCK_CONNECTED; - } else { - sip_tcp_conn_tab[idx].state = SOCK_CONNECT_PENDING; - } - create_msg->local_listener_port = (uint16) sec_port; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX - "Local listening port=%d\n", DEB_F_PREFIX_ARGS(SIP_TLS, fname), - create_msg->local_listener_port); - (void)sip_tcp_attach_socket(sock); - return (sock); -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_udp.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_udp.c deleted file mode 100644 index 4cc06afd352..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_udp.c +++ /dev/null @@ -1,455 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "cpr_memory.h" -#include "cpr_ipc.h" -#include "cpr_in.h" -#include "cpr_errno.h" -#include "cpr_string.h" -#include "util_string.h" -#include "text_strings.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "ccsip_platform_udp.h" -#include "phone.h" -#include "phone_debug.h" -#include "sip_common_transport.h" -#include "sip_platform_task.h" -#include "sip_socket_api.h" - -// FIXME include does not exist on windows -//#include - -static uint16_t af_family_listen = AF_INET6; -static uint16_t af_family_connect = AF_INET6; - -/* - * To set the appropriate socket strcutre based on the family. The called - * of the function is responsible for allocating the memory. - * - * @param psock_storage pointer to cpar_sockaddr_storage - * family network family AF_INET or AF_INET6 - * ip_addr ip address - * port - * addr_len legth returned based on family - * - * - * @return pointer to cpr_sockaddr, which is also psock_storage - * - * @pre none - * - */ - -cpr_sockaddr_t *sip_set_sockaddr (cpr_sockaddr_storage *psock_storage, uint16_t family, - cpr_ip_addr_t ip_addr, uint16_t port, uint16_t *addr_len) -{ - static const char fname[] = "sip_set_sockaddr"; - - cpr_sockaddr_in6_t *pin6_addr; - cpr_sockaddr_in_t *pin_addr; - cpr_sockaddr_t *psock_addr; - uint32_t tmp_ip; - int i,j; - unsigned char tmp; - - switch (family) { - case AF_INET6: - - pin6_addr = (cpr_sockaddr_in6_t *)psock_storage; - memset(pin6_addr, 0, sizeof(cpr_sockaddr_in6_t)); - pin6_addr->sin6_family = family; - pin6_addr->sin6_port = htons(port); - - if (ip_addr.type == CPR_IP_ADDR_IPV4) { - - if (ip_addr.u.ip4 != INADDR_ANY) { - pin6_addr->sin6_addr.addr.base16[5] = 0xffff; - } - tmp_ip = ntohl(ip_addr.u.ip4); - memcpy((void *)&(pin6_addr->sin6_addr.addr.base16[6]), (void *)&tmp_ip, 4); - - } else { - - for (i=0, j=15; i<16; i++, j--) { - tmp = pin6_addr->sin6_addr.addr.base8[j]; - pin6_addr->sin6_addr.addr.base8[j] = ip_addr.u.ip6.addr.base8[i]; - ip_addr.u.ip6.addr.base8[i] = tmp; - } - - } - - *addr_len = sizeof(cpr_sockaddr_in6_t); - return(psock_addr=(cpr_sockaddr_t *)pin6_addr); - - case AF_INET: - if (ip_addr.type == CPR_IP_ADDR_IPV6) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Setting ipv6 address in AF_INET",fname); - break; - } - pin_addr = (cpr_sockaddr_in_t *)psock_storage; - memset(pin_addr, 0, sizeof(cpr_sockaddr_in_t)); - pin_addr->sin_family = family; - pin_addr->sin_addr.s_addr = htonl(ip_addr.u.ip4); - pin_addr->sin_port = htons(port); - - *addr_len = sizeof(cpr_sockaddr_in_t); - return(psock_addr=(cpr_sockaddr_t *)pin_addr); - - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set sockaddr.",fname); - break; - } - - return(NULL); -} - -int -sip_platform_udp_channel_listen (cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *local_ipaddr, - uint16_t local_port) -{ - static const char fname[] = "sip_platform_udp_channel_listen"; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len = 0; - - /* - * If socket passed is is not INVALID_SOCKET close it first - */ - - if (*s != INVALID_SOCKET) { - if (sipSocketClose(*s, FALSE) != CPR_SUCCESS) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "sipSocketClose", cpr_errno); - } - sip_platform_task_reset_listen_socket(*s); - } - - /* - * Create a socket - */ - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_family_listen = AF_INET6; - } else { - af_family_listen = AF_INET; - } - - *s = cprSocket(af_family_listen, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open socket", cpr_errno); - if (ip_mode == CPR_IP_MODE_DUAL) { - - af_family_listen = AF_INET; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Socket open failed for IPv6 using IPv4 address.", - DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - - *s = cprSocket(af_family_listen, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open socket for IPv4", - cpr_errno); - return SIP_ERROR; - } - } - } - - (void) sip_set_sockaddr(&sock_addr, af_family_listen, *local_ipaddr, - local_port, &addr_len); - - if (cprBind(*s, (cpr_sockaddr_t *)&sock_addr, addr_len) == CPR_FAILURE) { - (void) sipSocketClose(*s, FALSE); - *s = INVALID_SOCKET; - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprBind", cpr_errno); - return SIP_ERROR; - } - sip_platform_task_set_listen_socket(*s); - - return SIP_OK; -} - -int -sip_platform_udp_channel_create (cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *remote_ipaddr, - uint16_t remote_port, - uint32_t local_udp_port) -{ - static const char *fname = "sip_platform_udp_channel_create"; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len = 0; - cpr_sockaddr_storage local_sock_addr; - cpr_ip_addr_t local_signaladdr; - - int tos_dscp_val = 0; // set to default if there is no config. for dscp - - CPR_IP_ADDR_INIT(local_signaladdr); - - if (*s != INVALID_SOCKET) { - (void) sipSocketClose(*s, FALSE); - } - - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_family_connect = AF_INET6; - } else { - af_family_connect = AF_INET; - } - /* - * Create socket - */ - *s = cprSocket(af_family_connect, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open socket", - cpr_errno); - /* Try opening ipv4 socket */ - if (ip_mode == CPR_IP_MODE_DUAL) { - - CCSIP_DEBUG_TASK("%s: cprSocket Open failed for IPv6 trying IPv4", - fname); - af_family_connect = AF_INET; - *s = cprSocket(af_family_connect, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open AF_INET socket", - cpr_errno); - return SIP_ERROR; - } - } - } - - sip_config_get_net_device_ipaddr(&local_signaladdr); - memset(&local_sock_addr, 0, sizeof(local_sock_addr)); - - (void) sip_set_sockaddr(&local_sock_addr, af_family_connect, local_signaladdr, 0, &addr_len); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"local_signaladdr.u.ip4=%x", - DEB_F_PREFIX_ARGS(SIP_SDP, fname), local_signaladdr.u.ip4); - - if(cprBind(*s, (cpr_sockaddr_t *)&local_sock_addr, addr_len)){ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"UDP bind failed with errno %d", fname, cpr_errno); - (void) sipSocketClose(*s, FALSE); - *s = INVALID_SOCKET; - return SIP_ERROR; - } - - /* - * Connect to remote address - */ - (void) sip_set_sockaddr(&sock_addr, af_family_connect, *remote_ipaddr, - remote_port, &addr_len); - - /* if (cprConnect(*s, (cpr_sockaddr_t *)&sock_addr, addr_len) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprConnect", cpr_errno); - (void) sipSocketClose(*s, FALSE); - *s = INVALID_SOCKET; - return SIP_ERROR; - } -*/ - // set IP tos/dscp value for SIP messaging - config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val, - sizeof(tos_dscp_val)); - - if (cprSetSockOpt(*s, SOL_IP, IP_TOS, (void *)&tos_dscp_val, - sizeof(tos_dscp_val)) == CPR_FAILURE) { - // do NOT take hard action; just log the error and move on - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set IP TOS %d on UDP socket. " - "cpr_errno = %d\n", fname, tos_dscp_val, cpr_errno); - } - return SIP_OK; -} - - -int -sip_platform_udp_channel_destroy (cpr_socket_t s) -{ - static const char fname[] = "sip_platform_udp_channel_destroy"; - - if (s != INVALID_SOCKET) { - if (sipSocketClose(s, FALSE) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "sipSocketClose", cpr_errno); - return SIP_ERROR; - } - } - return SIP_OK; -} - -int -sip_platform_udp_channel_read (cpr_socket_t s, - cprBuffer_t buf, - uint16_t *len, - cpr_sockaddr_t *soc_addr, - cpr_socklen_t *soc_addr_len) -{ - static const char *fname = "sip_platform_udp_channel_read"; - int bytes_read; - // NOT USED: cpr_sockaddr_in_t *addr = (cpr_sockaddr_in_t *)soc_addr; - - bytes_read = cprRecvFrom(s, buf, CPR_MAX_MSG_SIZE, 0, soc_addr, - soc_addr_len); - - switch (bytes_read) { - case SOCKET_ERROR: - /* - * If no data is available to read (CPR_EWOULDBLOCK), - * for non-blocking socket, it is not an error. - */ - cpr_free(buf); - *len = 0; - if (cpr_errno != CPR_EWOULDBLOCK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"fd[%d]", fname, s); - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprRecvFrom", cpr_errno); - return SIP_ERROR; - } - /* - * Will continue reading when data arrives at socket - */ - break; - case 0: - /* - * Return value 0 is OK. This does NOT mean the connection - * has closed by the peer, as with TCP sockets. With UDP - * sockets, there is no such thing as closing a connection. - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"No data on fd %d", DEB_F_PREFIX_ARGS(SIP_SDP, fname), s); - cpr_free(buf); - *len = 0; - break; - default: - /* PKT has been read */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Recvd on fd %d", DEB_F_PREFIX_ARGS(SIP_SDP, fname), s); - *len = (uint16_t) bytes_read; - break; - } - - return SIP_OK; -} - -int -sip_platform_udp_channel_send (cpr_socket_t s, char *buf, uint16_t len) -{ - static const char *fname = "sip_platform_udp_channel_send"; - ssize_t bytesSent; - - /* - * Check not exceeding max allowed payload size - */ - if (len >= PKTBUF_SIZ) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_UDP_PAYLOAD_TOO_LARGE), - fname, len, PKTBUF_SIZ); - return SIP_ERROR; - } - - while (len > 0) { - bytesSent = sipSocketSend(s, (void *)buf, (size_t)len, 0, FALSE); - if (bytesSent == SOCKET_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSend", cpr_errno); - return SIP_ERROR; - } - - len -= bytesSent; - buf += bytesSent; - } - - return SIP_OK; -} - -/** - * - * sip_platform_udp_read_socket - * - * Read from the socket to extract received message - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_udp_read_socket (cpr_socket_t s) -{ - cprBuffer_t buf; - uint16_t len = 0; - cpr_sockaddr_storage from; - cpr_socklen_t from_len; - const char *fname = "sip_platform_udp_read_socket"; - - if (af_family_listen == AF_INET6) { - from_len = sizeof(cpr_sockaddr_in6_t); - } else { - from_len = sizeof(cpr_sockaddr_in_t); - } - - buf = SIPTaskGetBuffer(CPR_MAX_MSG_SIZE); - if (buf) { - if ((sip_platform_udp_channel_read(s, buf, &len, - (cpr_sockaddr_t *)&from, &from_len) == SIP_OK) && - (len != 0)) { - (void) SIPTaskProcessUDPMessage(buf, len, from); - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No buffers available to read UDP socket.", - fname); - } -} - -int -sip_platform_udp_channel_sendto (cpr_socket_t s, char *buf, uint32_t len, - cpr_ip_addr_t *dst_ipaddr, uint16_t dst_port) -{ - static const char *fname = "sip_platform_udp_channel_sendto"; - ssize_t bytesSent; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - cpr_ip_addr_t dest_ip_addr; - - /* - * Connect to remote address - */ - dest_ip_addr = *dst_ipaddr; - (void) sip_set_sockaddr(&sock_addr, af_family_connect, dest_ip_addr, - dst_port, &addr_len); - - - /* - * Check not exceeding max allowed payload size - */ - if (len >= PKTBUF_SIZ) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_UDP_PAYLOAD_TOO_LARGE), - fname, len, PKTBUF_SIZ); - return SIP_ERROR; - } - - while (len > 0) { - bytesSent = cprSendTo(s, (void *)buf, (size_t)len, 0, - (cpr_sockaddr_t *)&sock_addr, addr_len); - - if ((bytesSent == SOCKET_ERROR) && (cpr_errno == CPR_ECONNREFUSED)) { - /* - * Will get socket error ECONNREFUSED after an ICMP message - * resend the message - */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"UDP send to error %d", DEB_F_PREFIX_ARGS(SIP_SOCK, fname), cpr_errno); - bytesSent = cprSendTo(s, (void *)buf, (size_t)len, 0, - (cpr_sockaddr_t *)&sock_addr, addr_len); - } - if (bytesSent == SOCKET_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSendTo", cpr_errno); - return SIP_ERROR; - } - - len -= bytesSent; - buf += bytesSent; - } - - return SIP_OK; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_pmh.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_pmh.c deleted file mode 100644 index f75a967d246..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_pmh.c +++ /dev/null @@ -1,5765 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Routines that parse SIP messages into individual components - * defined in ccsip_pmh.h. Used by the code that receives the - * messages to decipher them and then effect callstate as - * appropriate. - * Some SIP messages are exactly the same as HTTP/1.1 messages, - * and these are parsed using wrapper functions to those in - * httpish.c - */ - -#include -#include - -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "cpr_memory.h" -#include "ccsip_pmh.h" -#include "phone_debug.h" -#include "ccapi.h" -#include "text_strings.h" -#include "util_string.h" -#include "ccsip_spi_utils.h" -#include "ccsip_callinfo.h" -#include "ccsip_core.h" - -/* Skip linear whitespace */ -#define SKIP_LWS(p) while (*p == SPACE || *p == TAB) { \ - p++; \ - } - -#define SKIP_WHITE_SPACE(p) while (*p == SPACE || *p == TAB || \ - *p == '\n') { \ - p++; \ - } - -#define AUTHENTICATION_BASIC "Basic" -#define AUTHENTICATION_DIGEST "Digest" -#define AUTHENTICATION_REALM "realm" -#define AUTHENTICATION_NONCE "nonce" -#define AUTHENTICATION_URI "uri" -#define AUTHENTICATION_DOMAIN "domain" -#define AUTHENTICATION_ALGORITHM "algorithm" -#define AUTHENTICATION_OPAQUE "opaque" -#define AUTHENTICATION_USERNAME "username" -#define AUTHENTICATION_RESPONSE "response" - - -/* Trim trailing space from end of string */ -static void -trim_right (char *pstr) -{ - char *pend; - - if (!pstr) { - return; - } - - pend = (pstr + (strlen(pstr) - 1)); - while (pend > pstr) { - if (!isspace((int) *pend)) { - break; - } - *pend = '\0'; - pend--; - } -} - -/* - * Remove square brackets from IPv6 address - * - * @param pstr address string - * - * @return none - * - * @pre none - * - */ - -static void trim_ipv6_host(char *pstr) -{ - if (!pstr) { - return; - } - - if (*pstr == '[') { - pstr++; - } - - if (*(pstr + strlen(pstr)-1) == ']') { - *(pstr + strlen(pstr)-1) = '\0'; - } -} - -int parse_errno = 0; - -/* The order of these error messages corresponds to parse error codes - * defined in ccsip_pmh.h - */ -static char *parse_errors[] = { "", - ERROR_1, - ERROR_2, - ERROR_3, - ERROR_4, - ERROR_5, - ERROR_6, - ERROR_7, - ERROR_8 -}; - -/* - * These headers are defined as per the values of Header indexes ( in - * ccsip_protocol.h. To include a header in the cached list, increase - * the HEADER_CACHE_SIZE in httpish.h and add its entry here. Its index - * should be consistent with the index value in ccsip_protocol.h. - * For example, #define VIA 2, implies sip_cached_headers[2] has Via header - * related stuff. - */ -sip_header_t sip_cached_headers[] = { -/* 0 */ {"From", "f"}, -/* 1 */ {"To", "t"}, -/* 2 */ {HTTPISH_HEADER_VIA, "v"}, -/* 3 */ {"Call-ID", "i"}, -/* 4 */ {"CSeq", NULL}, -/* 5 */ {"Contact", "m"}, -/* 6 */ {HTTPISH_HEADER_CONTENT_LENGTH, HTTPISH_C_HEADER_CONTENT_LENGTH}, -/* 7 */ {HTTPISH_HEADER_CONTENT_TYPE, "c"}, -/* 8 */ {"Record-Route", NULL}, -/* 9 */ {"Require", NULL}, -/* 10 */ {"Route", NULL}, -/* 11 */ {"Supported", "k"} -}; - -static boolean -is_dtmf_or_pause (char *digit) -{ - if (!(*digit)) { - return FALSE; - } - switch (*digit) { - case 'A': - case 'B': - case 'C': - case 'D': - case '*': - case '#': - case 'p': - case 'w': - return TRUE; - default: - return FALSE; - } -} - -/* Inefficient ? Somewhat... */ -sipMethod_t -sippmh_get_method_code (const char *method) -{ - sipMethod_t ret = sipMethodInvalid; - - if (method) { - - ret = sipMethodUnknown; - - if (strcmp(method, SIP_METHOD_INVITE) == 0) - ret = sipMethodInvite; - else if (strcmp(method, SIP_METHOD_BYE) == 0) - ret = sipMethodBye; - else if (strcmp(method, SIP_METHOD_ACK) == 0) - ret = sipMethodAck; - else if (strcmp(method, SIP_METHOD_PRACK) == 0) - ret = sipMethodPrack; - else if (strcmp(method, SIP_METHOD_COMET) == 0) - ret = sipMethodComet; - else if (strcmp(method, SIP_METHOD_OPTIONS) == 0) - ret = sipMethodOptions; - else if (strcmp(method, SIP_METHOD_CANCEL) == 0) - ret = sipMethodCancel; - else if (strcmp(method, SIP_METHOD_NOTIFY) == 0) - ret = sipMethodNotify; - else if (strcmp(method, SIP_METHOD_REFER) == 0) - ret = sipMethodRefer; - else if (strcmp(method, SIP_METHOD_SUBSCRIBE) == 0) - ret = sipMethodSubscribe; - else if (strcmp(method, SIP_METHOD_REGISTER) == 0) - ret = sipMethodRegister; - else if (strcmp(method, SIP_METHOD_UPDATE) == 0) - ret = sipMethodUpdate; - else if (strcmp(method, SIP_METHOD_INFO) == 0) - ret = sipMethodInfo; - else if (strcmp(method, SIP_METHOD_PUBLISH) == 0) - ret = sipMethodPublish; - else if (strcmp(method, SIP_METHOD_MESSAGE) == 0) - ret = sipMethodMessage; - else if (strcmp(method, SIP_METHOD_INFO) == 0) - ret = sipMethodInfo; - } - - return ret; -} - -#define SKIP_SIP_TOKEN(inp_str) \ - while (isalnum((int)*inp_str) || *inp_str == DASH || \ - *inp_str == DOT || *inp_str == EXCLAMATION || \ - *inp_str == PERCENT || *inp_str == STAR || \ - *inp_str == UNDERSCORE || *inp_str == PLUS || \ - *inp_str == '`' || *inp_str == SINGLE_QUOTE || \ - *inp_str == COLON || *inp_str == TILDA || \ - *inp_str == AT_SIGN) { \ - inp_str++; \ - } - -static char * -parse_generic_param (char *param, char **param_val) -{ - boolean match_found; - char *tok_start; - - /* - * param is pointing to the first character after the name of the - * parameter. It could be - * white space or - * equal sign or - * semi-colon or - * comma or - * end of string - */ - if (*param == SPACE || *param == TAB) { - *param++ = 0; - SKIP_LWS(param); - } - - if (*param != EQUAL_SIGN) { - /* - * Parameter exists but its value is empty - */ - *param_val = ""; - return param; - } - - *param++ = 0; - SKIP_LWS(param); - *param_val = param; - if (*param == DOUBLE_QUOTE) { - param++; - match_found = FALSE; - while (*param) { - if (*param == DOUBLE_QUOTE && *(param - 1) != ESCAPE_CHAR) { - param++; - match_found = TRUE; - break; - } - param++; - } - if (match_found == FALSE) { - return NULL; - } - } else { - tok_start = param; - SKIP_SIP_TOKEN(param); - if (param == tok_start) { - return NULL; - } - } - return param; -} - -/* - * The syntax of other-param in SIP URL is same as extension-attribute in - * Contact header. A pointer to the start of the token=value or - * token="value" string is returned in other_param_value. This allows - * the calling code to store this value if needed such as in the - * case of supporting contact-extensions. The function returns - * a pointer to the next character to be parsed. - */ -static char * -parse_other_param (char *inp_str, char **other_param_value) -{ - char temp; - char *token_string; - - - SKIP_LWS(inp_str); - token_string = inp_str; - SKIP_SIP_TOKEN(inp_str); - switch (*inp_str) { - case COMMA: - case '\0': - case SEMI_COLON: - /* - * Either we have encountered end of string or another - * parameter follows this other-param. In either case we - * are done with parsing other-param. Since this is - * not in the form of token=value or token="value" discard - * it. - */ - *other_param_value = NULL; - - /* check for loose routing specifier */ - temp = *inp_str; - *inp_str = 0; - if (!cpr_strcasecmp(token_string, "lr")) { - *other_param_value = (char *) cpr_malloc(4); - if (*other_param_value != NULL) { - sstrncpy(*other_param_value, token_string, 4); - } - } - *inp_str = temp; - break; - - case EQUAL_SIGN: - /* It is either token=token form or token=quoted-string form */ - inp_str++; - if (*inp_str == DOUBLE_QUOTE) { - /* quoted-string follows */ - inp_str++; /* skip the " char */ - while (*inp_str) { - if (*inp_str == DOUBLE_QUOTE && *(inp_str - 1) != ESCAPE_CHAR) { - inp_str++; - break; - } - inp_str++; - } - } else { - /* token follows */ - // SKIP_SIP_TOKEN(inp_str); - // Continue until another semicolon is found or end of string is - // reached - while (*inp_str != '\0' && *inp_str != SEMI_COLON) { - inp_str++; - } - } - - /* - * Terminate the string that token_string is pointing - * to while keeping the value of *inp_str unchanged. - * Then assign the null terminated string to other_param_value - */ - *other_param_value = (char *) cpr_malloc(SIP_MAX_OTHER_PARAM_LENGTH + 1 * sizeof(char)); - if (*other_param_value != NULL) { - temp = *inp_str; - *inp_str = 0; - sstrncpy(*other_param_value, token_string, SIP_MAX_OTHER_PARAM_LENGTH); - *inp_str = temp; - } - break; - - default: - CCSIP_DEBUG_ERROR(ERROR_3, "parse_other_param", inp_str); - *other_param_value = NULL; - return NULL; - } - return inp_str; -} - -/* - * This function creates an array of url headers. Each - * element of the array has two member pointers: - * char pointer to header name, - * char pointer to header value - */ -static int -url_add_headers_to_list (char *url_strp, sipUrl_t *sip_url) -{ - char *tmp_ptr = NULL; - char num_head = 1; - char *lasts = NULL; - - if (!url_strp) { - return (PARSE_ERR_NULL_PTR); - } - - tmp_ptr = strchr(url_strp, AMPERSAND); - while (tmp_ptr != NULL) { - num_head++; - tmp_ptr++; - tmp_ptr = strchr(tmp_ptr, AMPERSAND); - } - - sip_url->headerp = (attr_value_pair_t *) - cpr_malloc(sizeof(attr_value_pair_t) * num_head); - if (!sip_url->headerp) { - return (PARSE_ERR_NO_MEMORY); - } - - sip_url->num_headers = num_head; - num_head = 0; - url_strp = PL_strtok_r(url_strp, "&?", &lasts); - while ((url_strp != NULL) && (num_head < sip_url->num_headers)) { - - tmp_ptr = strchr(url_strp, EQUAL_SIGN); - if (!tmp_ptr) { - return (PARSE_ERR_SYNTAX); - } - *tmp_ptr++ = 0; - - sip_url->headerp[(uint16_t)num_head].attr = url_strp; - sip_url->headerp[(uint16_t)num_head].value = tmp_ptr; - - num_head++; - url_strp = PL_strtok_r(NULL, "&", &lasts); - } - - return 0; -} - -static int -parseUrlParams (char *url_param, sipUrl_t *sipUrl, genUrl_t *genUrl) -{ - static const char fname[] = "parseUrlParams"; - char *param_val; - char *url_other_param = NULL; - uint16_t i; - uint32_t ttl_val; - unsigned long strtoul_result; - char *strtoul_end; - - - /* - * url-parameters = *( ";" url-parameter ) - * url-parameter = transport-param | user-param | method-param - * | ttl-param | maddr-param | other-param - * transport-param = "transport=" ( "udp" | "tcp" | "sctp" | "tls" - * | other-transport ) - * ttl-param = "ttl=" ttl - * ttl = 1*3DIGIT ; 0 to 255 - * maddr-param = "maddr=" host - * user-param = "user=" ( "phone" | "ip" ) - * method-param = "method=" Method - * tag-param = "tag=" UUID - * lr-param = "lr" - * UUID = 1*( hex | "-" ) - * other-param = ( token | ( token "=" ( token | quoted-string ))) - * other-transport = token - */ - - /* - * url_param is pointing to the first character after the ';' - * This routine only prints error message for SYNTAX error, since we - * want to pinpoint the error location. For other errors it simply - * returns the error code. - */ - SKIP_LWS(url_param); - if (*url_param == 0) { - return PARSE_ERR_UNEXPECTED_EOS; - } - while (1) { - if (cpr_strncasecmp(url_param, "transport=", 10) == 0) { - url_param += 10; - SKIP_LWS(url_param); - if (cpr_strncasecmp(url_param, "tcp", 3) == 0) { - sipUrl->transport = TRANSPORT_TCP; - url_param += 3; - } else if (cpr_strncasecmp(url_param, "tls", 3) == 0) { - sipUrl->transport = TRANSPORT_TLS; - url_param += 3; - } else if (cpr_strncasecmp(url_param, "sctp", 4) == 0) { - sipUrl->transport = TRANSPORT_SCTP; - url_param += 4; - } else if (cpr_strncasecmp(url_param, "udp", 3) == 0) { - sipUrl->transport = TRANSPORT_UDP; - url_param += 3; - } else { - SKIP_SIP_TOKEN(url_param); - SKIP_LWS(url_param); - if (*url_param != SEMI_COLON && *url_param != 0) { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - } - } else if (cpr_strncasecmp(url_param, "user=", 5) == 0) { - url_param += 5; - SKIP_LWS(url_param); - if (cpr_strncasecmp(url_param, "phone", 5) == 0) { - sipUrl->is_phone = 1; - url_param += 5; - } else if (cpr_strncasecmp(url_param, "ip", 2) == 0) { - url_param += 2; - } else { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - } else if (cpr_strncasecmp(url_param, "method=", 7) == 0) { - url_param += 7; - SKIP_LWS(url_param); - param_val = url_param; - while (isalpha((int) *url_param)) { - url_param++; - } - if (param_val == url_param) { - return PARSE_ERR_UNEXPECTED_EOS; - } - sipUrl->method = param_val; - /* Note that we have not terminated the method str yet */ - } else if (cpr_strncasecmp(url_param, "ttl=", 4) == 0) { - char save_ch; - - url_param += 4; - SKIP_LWS(url_param); - param_val = url_param; - while (isdigit((int) *url_param)) { - url_param++; - /* Atmost 3 digits allowed in ttl value */ - if ((url_param - param_val) > 3) { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - } - if (url_param == param_val) { - /* Did not find any digit after "ttl=" */ - return PARSE_ERR_UNEXPECTED_EOS; - } - save_ch = *url_param; - *url_param = 0; /* Terminate the string for strtoul */ - - errno = 0; - strtoul_result = strtoul(param_val, &strtoul_end, 10); - - if (errno || param_val == strtoul_end || strtoul_result > MAX_TTL_VAL) { - CCSIP_DEBUG_ERROR(ERROR_7, fname, sipUrl->ttl_val); - return PARSE_ERR_INVALID_TTL_VAL; - } - sipUrl->ttl_val = (unsigned char) strtoul_result; - *url_param = save_ch; /* Restore string state */ - } else if (cpr_strncasecmp(url_param, "maddr=", 6) == 0) { - url_param += 6; - SKIP_LWS(url_param); - param_val = url_param; /* maddr now points to a host */ - while (isalnum((int) *url_param) || *url_param == DOT || - *url_param == DASH) { - url_param++; - } - if (url_param == param_val) { - /* Empty value of maddr */ - return PARSE_ERR_UNEXPECTED_EOS; - } - sipUrl->maddr = param_val; - } else if (cpr_strncasecmp(url_param, "phone-context=", 14) == 0) { - url_param += 14; - SKIP_LWS(url_param); - param_val = url_param; - - while (isalpha((int) *url_param)) { - url_param++; - } - if (param_val == url_param) { - return PARSE_ERR_SYNTAX; - } - - /* If the next character is a space, we want to zero the - * string, otherwise the next character is EOF or ; in - * which case the code below will handle these cases. - */ - if (isspace((int) *url_param)) { - *url_param++ = 0; - } - genUrl->phone_context = param_val; - } else if (cpr_strncasecmp(url_param, "lr", 2) == 0) { - // skip to the following SEMI_COLON or end - while (*url_param && *url_param != SEMI_COLON) { - url_param++; - } - sipUrl->lr_flag = TRUE; - } else { - /* other-param */ - url_param = parse_other_param(url_param, &url_other_param); - - if (url_param == NULL) { - return PARSE_ERR_SYNTAX; - } - - if (url_other_param != NULL) { - /* Store it in first free slot */ - i = 0; - while (i < SIP_MAX_LOCATIONS) { - if (genUrl->other_params[i] == NULL) { - break; - } - i++; - } - - if (i == SIP_MAX_LOCATIONS) { - cpr_free(url_other_param); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"parseUrlParams: Too many unknown parameters" - " in URL of Contact header", fname); - } else { - genUrl->other_params[i] = url_other_param; - url_other_param = NULL; - } - } - } - - SKIP_LWS(url_param); - /* We either expect - end of string or ';' */ - if (*url_param == 0) { - return 0; - } - if (*url_param != SEMI_COLON) { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - *url_param++ = 0; /* Zero the ';' and advance pointer */ - SKIP_LWS(url_param); - if (*url_param == 0) { - return PARSE_ERR_UNEXPECTED_EOS; - } - } -} - - - - -/* - * This routine is based on a very simple and valid assumption. SIP URL can be - * of the following forms (before the parameters, which start with ';') - * My understanding is that it is NOT a context-free grammar - * sip:host - * sip:host:port - * sip:user@host - * sip:user@host:port - * sip:user:password@host - * sip:user:password@host:port - * sip:user:password@[ipv6host]:port - * - * e.g. "1218@[2001:db8:c18:1:211:11ff:feb1:fb65]" - * - * Parse the SIP URL and zero the separators ( @ : ; etc) - * Point fields of sipUrl to appropriate places in the duplicated string - * This saves multiple mallocs for different fields of the sipUrl - * For a SIP URL of the form sip:user:password@host:port;params... - * loc_ptr[0] = Beginning of user part - * loc_ptr[1] = Beginning of password - * loc_ptr[2] = Beginning of host - * loc_ptr[3] = Beginning of port - * loc_ptr[4] = Beginning of parameters - */ -static int -parseSipUrl (char *url_start, genUrl_t *genUrl) -{ - static const char fname[] = "parseSipUrl"; - sipUrl_t *sipUrl = genUrl->u.sipUrl; - char ch = 0; - int token_cnt, separator_cnt; - char *url_main; - char *tokens[4]; - char separator[4]; - char *endptr; - uint16_t port; - boolean parsing_user_part; - char *temp_url; - boolean ipv6_addr = FALSE; - - /* initializing separator */ - separator[0] = '\0'; - - /* - * SIP-URL = "sip:" [ userinfo "@" ] hostport - * url-parameters [ headers ] - * userinfo = user [ ":" password ] - * user = *( unreserved | escaped - * | "&" | "=" | "+" | "$" | "," ) - * password = *( unreserved | escaped - * | "&" | "=" | "+" | "$" | "," ) - * hostport = host [ ":" port ] - * host = hostname | IPv4address | IPv6reference - * IPv6reference = "[" IPv6address "]" - * IPv6address = hexpart [ ":" IPv4address ] - * hexpart = hexseq / hexseq "::" [ hexseq ] / "::" [ hexseq ] - * hexseq = hex4 *( ":" hex4) - * hex4 = 1*4HEXDIG - * port = 1*DIGIT - * hostname = *( domainlabel "." ) toplabel [ "." ] - * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum - * toplabel = alpha | alpha *( alphanum | "-" ) alphanum - * IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit - * port = *digit - */ - - /* Ignore any leading white spaces too, */ - SKIP_LWS(url_start); - - /* we are pointing at whatever is after "sip:" */ - url_main = url_start; - - tokens[0] = url_main; - token_cnt = 0; - separator_cnt = 0; - - /* Scan the string for : and @ and store their pointers. Terminate - * the search when you reach end of string or beginning of parameters - * indicated by ;. However the bis02 version of the spec allows ; in - * the user part of the URL. Thus the code must differentiate between - * a ; in the user part and a ; indicating the start of URL params. - */ - while (1) { - if (*url_main == 0 || *url_main == SEMI_COLON || - *url_main == QUESTION_MARK) { - /* Either end of string or beginning of SIP URL parameters - * or a ; encountered in the user part - */ - parsing_user_part = FALSE; - temp_url = url_main; - while (*temp_url != 0) { - if (*temp_url == AT_SIGN) { - parsing_user_part = TRUE; - break; - } else if (*temp_url == QUESTION_MARK) { - /* overloaded headers in url */ - break; - } - temp_url++; - } - temp_url = NULL; - - if (!parsing_user_part) { - ch = *url_main; - *url_main++ = 0; /* Terminate the current token */ - token_cnt++; - break; - } - } - - /* For IPv6 address colon present so skip that */ - if ((*url_main == COLON && ipv6_addr == FALSE)|| *url_main == AT_SIGN || *url_main == SPACE || - *url_main == TAB) { - - if (*url_main == SPACE || *url_main == TAB) { - *url_main++ = 0; /* Terminate current token */ - SKIP_LWS(url_main); - } - /* - * Now we should be pointing to end of string or a separator - * (even ';' - beginning of parameters - */ - if (*url_main == COLON || *url_main == AT_SIGN) { - if (separator_cnt == 3) { - /* Too many separators */ - CCSIP_DEBUG_ERROR(ERROR_3_1, fname, *url_main); - return PARSE_ERR_SYNTAX; - } - separator[separator_cnt++] = *url_main; - *url_main++ = 0; /* Zero the separator */ - SKIP_LWS(url_main); - - if (*url_main == LEFT_SQUARE_BRACKET) { - *url_main++ = 0; /* Must be IPv6 address */ - ipv6_addr = TRUE; - } - tokens[++token_cnt] = url_main; - if (*url_main == 0) { - break; - } - } - - } else if (*url_main == RIGHT_SQUARE_BRACKET && ipv6_addr == TRUE) { - - *url_main++ = 0; /* Found complete IPv6 address*/ - } else { - url_main++; - } - } - - sipUrl->port = SIP_WELL_KNOWN_PORT; - sipUrl->port_present = FALSE; - - /* token_cnt contains the number of entries in the tokens array */ - switch (token_cnt) { - - case 1: - /* sip:host */ - sipUrl->host = tokens[0]; - break; - - case 2: - if (separator[0] == AT_SIGN) { - /* sip:user@host */ - sipUrl->user = tokens[0]; - sipUrl->host = tokens[1]; - sipUrl->is_ipv6 = ipv6_addr; - } else { - /* sip:host:port */ - sipUrl->host = tokens[0]; - port = (uint16_t) strtol(tokens[1], &endptr, 10); - if (*endptr == 0) { - sipUrl->port = port; - sipUrl->port_present = TRUE; - } else { - sipUrl->port = 0; - } - } - break; - - case 3: - if (separator[0] == separator[1]) { - /* Cannot have 2 successive entries of : or @ */ - CCSIP_DEBUG_ERROR(ERROR_3_1, fname, separator[1]); - return PARSE_ERR_SYNTAX; - } - if (separator[0] == AT_SIGN) { - /* sip:user@host:port */ - sipUrl->user = tokens[0]; - sipUrl->host = tokens[1]; - port = (uint16_t) strtol(tokens[2], &endptr, 10); - if (*endptr == 0) { - sipUrl->port = port; - sipUrl->port_present = TRUE; - } else { - sipUrl->port = 0; - } - } else { - /* sip:user:password@host */ - sipUrl->user = tokens[0]; - sipUrl->password = tokens[1]; - sipUrl->host = tokens[2]; - } - break; - - case 4: - /* sip:user:password@host:port */ - - if (separator[0] == COLON && separator[1] == AT_SIGN && - separator[2] == COLON) { - sipUrl->user = tokens[0]; - sipUrl->password = tokens[1]; - sipUrl->host = tokens[2]; - port = (uint16_t) strtol(tokens[3], &endptr, 10); - if (*endptr == 0) { - sipUrl->port = port; - sipUrl->port_present = TRUE; - } else { - sipUrl->port = 0; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad separator sequence", fname); - return PARSE_ERR_SYNTAX; - } - break; - - } - - /* Remove [ and ] from IPv6 address*/ - trim_ipv6_host(sipUrl->host); - - /* Verify the Port */ - if (sipUrl->port == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received Bad Port", fname); - return PARSE_ERR_SYNTAX; - } - - /* Verify the host portion */ - if (sipSPI_validate_ip_addr_name(sipUrl->host) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received Bad Host", fname); - return PARSE_ERR_SYNTAX; - } - - /* Set default transport to UNSPECIFIED */ - sipUrl->transport = TRANSPORT_UNSPECIFIED; - if (ch == SEMI_COLON) { /* Process URL parameters */ - return parseUrlParams(url_main, sipUrl, genUrl); - } else if (ch == QUESTION_MARK) { /* Process URL headers */ - return url_add_headers_to_list(url_main, sipUrl); - } - return 0; /* SUCCESS */ -} - -/* - * This routine is based on a very simple and valid assumption. TEL URL can be - * of the following forms (before the parameters, which start with ';') - * tel:user - * - * Parse the TEL URL and zero the separators (;) - * Point fields of sipUrl to appropriate places in the duplicated string - * This saves multiple mallocs for different fields of the telUrl - * For a TEL URL of the form tel:user;params... - */ -static int -parseTelUrl (char *url_start, genUrl_t *genUrl) -{ - static const char fname[] = "parseTelUrl"; - char *url_main; - telUrl_t *telUrl = genUrl->u.telUrl; - boolean is_local_subscriber = FALSE; - - /* - * TEL-URL = telephone-scheme ":" telephone-subscriber - * telephone-scheme = "tel" - * telephone-subscriber = global-phone-number/local-phone-number - * global-phone-number = "+" base-phone-number [isdn-subaddress] - * [post-dial] *(area-specifier/service-provider/ - * future-extension) - * base-phone-number = 1*phonedigit - * local-phone-number = 1*(phonedigit / dtmf-digit /pause-character) - * [isdn-subaddress] [post-dial] area-specifier - * *(are-specifier/service-provider/ - * future-extension) - * isdn-subaddress = ";isub=" 1*phonedigit - * post-dial = ";postd=" 1*(phonedigit / dtmf-digit / - * pause-character) - * area-specifier = ";" phone-context-tag "=" phone-context-ident - * phone-context-tag = "phone-context" - * phone-context-ident = network-prefix / private-prefix - * network-prefix = global-network-prefix / local-network-prefix - * global-network-prefix = "+" 1*phonedigit - * local-network-prefix = 1*(phonedigit / dtmf-digit / pause-character) - * private-prefix = (%x21-22 / %x24-27 / %x2C / %x2F / %x3A / - * %x3C-40 /%x45-4F / %x51-56 / %x58-60 / - * %x65-6F / %x71-76 / %x78-7E /) *(%x21-3A / - * %x3C-7E) - * service-provider = ";" provider-tag "=" provider-hostname - * provider-tag = "tsp" - * provider-hostname = domain ; is defined in [RFC1035] - * future-extension = ";" token ["=" token] - * phonedigit = DIGIT / visual-separator - * visual-separator = "-" / "." / "(" / ")" - * pause-character = "p" / "w" - * dtmf-digit = "*" / "#" / "A" / "B" / "C" / "D" - */ - - if (!url_start) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Missing user field", fname); - return PARSE_ERR_SYNTAX; - } - - url_main = url_start; - SKIP_LWS(url_main); - /* - * User field is the only mandatory field. The rest are optional - */ - - if (*url_main == PLUS) { - /* global-phone number */ - url_main++; - telUrl->user = url_main; - - while ((url_main) && ((*url_main == DASH) || - (isdigit((int)*url_main)) || (*url_main == DOT))) { - url_main++; - } - } else { - /* local-phone-number */ - telUrl->user = url_main; - is_local_subscriber = TRUE; - - while ((url_main) && ((is_dtmf_or_pause(url_main)) || - (*url_main == DASH) || (isdigit((int)*url_main)) || - (*url_main == DOT))) { - url_main++; - } - } - if (url_main) { - SKIP_LWS(url_main); - } - if ((url_main) && (!(*url_main))) { - if (!is_local_subscriber) { - return 0; /* no fields to parse */ - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"local-phone-number must have area-specifier", - fname); - return PARSE_ERR_SYNTAX; - } - } - if (url_main) { - if ((*url_main) && (*url_main == SEMI_COLON)) { - *url_main++ = 0; /* skip separator */ - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Need ';' before parameters", fname); - return PARSE_ERR_SYNTAX; - } - } - - while (url_main) { - SKIP_LWS(url_main); - if (cpr_strncasecmp(url_main, "isub=", 5) == 0) { - url_main += 5; - SKIP_LWS(url_main); - telUrl->isdn_subaddr = url_main; - } else if (cpr_strncasecmp(url_main, "postd=", 6) == 0) { - url_main += 6; - SKIP_LWS(url_main); - telUrl->post_dial = url_main; - } else if (cpr_strncasecmp(url_main, "phone-context", 13) == 0) { - url_main += 13; - SKIP_LWS(url_main); - if (*url_main != EQUAL_SIGN) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad syntax in phone_context field", fname); - return PARSE_ERR_SYNTAX; - } - *url_main++ = 0; /* skip "=" */ - SKIP_LWS(url_main); - genUrl->phone_context = url_main; - } else if (cpr_strncasecmp(url_main, "tsp", 3) == 0) { - url_main += 3; - SKIP_LWS(url_main); - if (*url_main != EQUAL_SIGN) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad syntax in service-provider field", fname); - return PARSE_ERR_SYNTAX; - } - *url_main++ = 0; /* skip "=" */ - SKIP_LWS(url_main); - telUrl->unparsed_tsp = url_main; - } else { - /* future extension */ - if (telUrl->future_ext) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Only one future extension allowed", fname); - return PARSE_ERR_SYNTAX; - } - SKIP_LWS(url_main); - url_main = strchr(url_main, EQUAL_SIGN); - if (!url_main) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad field value", fname); - return PARSE_ERR_SYNTAX; - } else { - *url_main++ = 0; - SKIP_LWS(url_main); - telUrl->future_ext = url_main; - } - } - url_main = strchr(url_main, SEMI_COLON); - if (url_main) { - *url_main++ = 0; /* skip and zero separator */ - } - } - if ((is_local_subscriber) && (!genUrl->phone_context)) { - /* local-phone-number must have area-specifier */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"local-phone-number requires area-specifier", fname); - return PARSE_ERR_SYNTAX; - } - return 0; /* Success */ -} - -/* - * Parses a URL - * (eg. "sip:14085266593@sip.cisco.com;transport=UDP;user=phone") - * (eg. "tel:+1-555-555-5555") - * into a usable genUrl_t struct. Memory is created by this function. - * To free first free internal members(sippmh_genurl_free(genUrl)). - * Returns NULL if there is a parse error or malloc fails. Components/tokens - * not found in the URL are set to NULL, unless they have a default value - * defined by the protocol ( for example port 5060 is default) - * Parse error will set parse_errno variable to indicate the error. - * Expects a NULL terminated string in url. - * See comment block before parseSipUrl() and parseTelUrl() - * for some other details. - * - * url - Pointer to URL to be parsed - * dup_flag - Should this URL be duplicated and modified ?? - */ -genUrl_t * -sippmh_parse_url (char *url, boolean dup_flag) -{ - genUrl_t *genUrl; - char *url_main; - uint16_t i; - uint16_t skipValue; - - if (url == NULL) { - return NULL; - } - - genUrl = (genUrl_t *) cpr_calloc(1, sizeof(genUrl_t)); - if (genUrl == NULL) { - return NULL; - } - - /* - * Ensure clean other params pointers - */ - i = 0; - while (i < SIP_MAX_LOCATIONS) { - genUrl->other_params[i] = NULL; - i++; - } - - if (dup_flag) { - url_main = cpr_strdup(url); - if (!url_main) { - cpr_free(genUrl); - return NULL; - } - genUrl->str_start = url_main; - } else { - url_main = url; - } - - SKIP_LWS(url_main); - if (!cpr_strncasecmp(url_main, "sips", 4)) { - genUrl->schema = URL_TYPE_SIP; - genUrl->sips = TRUE; - skipValue = 4; - } else if (!cpr_strncasecmp(url_main, "sip", 3)) { - genUrl->schema = URL_TYPE_SIP; - skipValue = 3; - } else if (!cpr_strncasecmp(url_main, "tel", 3)) { - genUrl->schema = URL_TYPE_TEL; - skipValue = 3; - } else if (!cpr_strncasecmp(url_main, "cid", 3)) { - genUrl->schema = URL_TYPE_CID; - skipValue = 3; - } else { - genUrl->schema = URL_TYPE_UNKNOWN; - skipValue = 0; - } - url_main += skipValue; /* skip "sip", "sips", cid, or "tel" */ - if (*url_main != COLON) { - if (dup_flag) { - cpr_free(genUrl->str_start); - } - cpr_free(genUrl); - return NULL; - } - *url_main++ = 0; /* terminate ":" for schema */ - switch (genUrl->schema) { - case URL_TYPE_CID: - case URL_TYPE_SIP: - genUrl->u.sipUrl = (sipUrl_t *) cpr_calloc(1, sizeof(sipUrl_t)); - if (!genUrl->u.sipUrl) { - if (dup_flag) { - cpr_free(genUrl->str_start); - } - cpr_free(genUrl); - return NULL; - } - parse_errno = parseSipUrl(url_main, genUrl); - if (parse_errno == 0) { - //remove_visual_separators(genUrl); - if (genUrl->u.sipUrl->port == 0) { - /* If no port specified in SIP-URL, then use 5060 */ - genUrl->u.sipUrl->port = SIP_WELL_KNOWN_PORT; - genUrl->u.sipUrl->port_present = FALSE; - } - return genUrl; - } - /* For syntax error, we would already have printed the error msg */ - if (parse_errno != PARSE_ERR_SYNTAX) { - if (parse_errno == PARSE_ERR_NO_MEMORY) { - parse_errno = 0; /* Not really a parse error (out of mem) */ - } else { - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], "sippmh_parse_url"); - } - } - sippmh_genurl_free(genUrl); - return NULL; - case URL_TYPE_TEL: - genUrl->u.telUrl = (telUrl_t *) cpr_calloc(1, sizeof(telUrl_t)); - if (!genUrl->u.telUrl) { - if (dup_flag) { - cpr_free(genUrl->str_start); - } - cpr_free(genUrl); - return NULL; - } - parse_errno = parseTelUrl(url_main, genUrl); - if (parse_errno == 0) { - //remove_visual_separators(genUrl); - return genUrl; - } - /* For syntax error, we would already have printed the error msg */ - if (parse_errno != PARSE_ERR_SYNTAX) { - if (parse_errno == PARSE_ERR_NO_MEMORY) { - parse_errno = 0; /* Not really a parse error (out of mem) */ - } else { - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], "sippmh_parse_url"); - } - } - sippmh_genurl_free(genUrl); - return NULL; - default: - sippmh_genurl_free(genUrl); - return NULL; - } -} - -/* If this is a SIP URL, free the sipUrl_t. If this is - * a telUrl_t free the telUrl_t. Also, free memory allocated by creation - * of the genUrl_t then free the genUrl_t. - */ -void -sippmh_genurl_free (genUrl_t *genUrl) -{ - uint16_t i; - - if (!genUrl) { - return; - } - if (genUrl->str_start) { - cpr_free(genUrl->str_start); - } - if ((genUrl->schema == URL_TYPE_SIP) || - (genUrl->schema == URL_TYPE_CID)) { - if (genUrl->u.sipUrl->headerp) { - cpr_free(genUrl->u.sipUrl->headerp); - } - cpr_free(genUrl->u.sipUrl); - } else if (genUrl->schema == URL_TYPE_TEL) { - cpr_free(genUrl->u.telUrl); - } - - /* Free any "other" parameters that were saved */ - i = 0; - while (i < SIP_MAX_LOCATIONS) { - if (genUrl->other_params[i] != NULL) { - cpr_free(genUrl->other_params[i]); - } - i++; - } - - cpr_free(genUrl); -} - -/* Parse display name: - * "Mr. Watson" - * "Mr. Watson" is the display-name - * Return pointer to the '<' - */ - -static char * -parse_display_name (char *ptr) -{ - static const char fname[] = "parse_display_name"; - - while (*ptr) { - if (*ptr == DOUBLE_QUOTE && *(ptr - 1) != ESCAPE_CHAR) { - /* We reached end of quoted-string, mark end of display name */ - *ptr++ = 0; - SKIP_LWS(ptr); /* Skip spaces till '<' */ - /* ptr should now be pointing to '<' */ - if (*ptr != LEFT_ANGULAR_BRACKET) { - parse_errno = PARSE_ERR_UNMATCHED_BRACKET; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - - return NULL; - } - return ptr; - } - ptr++; - } - - parse_errno = PARSE_ERR_UNTERMINATED_STRING; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - - return NULL; /* Unmatched " */ -} - - -/* - * Parse the name-addr form or the addr-spec form. These parse entities can - * be present in the From, To and Contact headers. So it is called either - * by sippmh_parse_contact() or sippmh_parse_from_or_to(). - * - * input_loc_ptr - Pointer to the string to be parsed - * dup_flag - Should the input string be duplicated before parsing - * more_ptr - Return pointer to the next - * Tokens are extracted in place, i.e. we do not do a strdup for every token. - * We have on string and the output struct has pointers pointing to various - * tokens in the string. - * Note that this routine relies on the caller setting parse_errno to 0 - * before calling. - * - * input_loc_ptr - Pointer to input string to be parsed - * start_ptr - Pointer to beginning of the string, which will be used for - * cleanup. - * dup_flag - Should the input string be duplicated before parsing - * name_addr_only_flag - If TRUE, means only name-addr form is allowed - * more_ptr - Return pointer to start of remaining string ( string that - * remains after parsing name-addr or addr-spec - * - * Output: A pointer to a valid SIP location OR - * NULL (in case of error) - * - */ -sipLocation_t * -sippmh_parse_nameaddr_or_addrspec (char *input_loc_ptr, - char *start_ptr, - boolean dup_flag, - boolean name_addr_only_flag, - char **more_ptr) -{ - const char *fname = "sippmh_parse_nameaddr_or_addrspec"; - char *addr_param; - char *loc_ptr, *addr_spec, *left_bracket; - sipLocation_t *sipLoc = NULL; - char *right_bracket = NULL; - char save_ch = 0; - char *displayNameStart; - - *more_ptr = NULL; - - /* - * name-addr = [ display-name ] "<" addr-spec ">" - * addr-spec = SIP-URL | URI - * display-name = *token | quoted-string - */ - if (dup_flag) { - /* Duplicate the string and work with it */ - start_ptr = loc_ptr = cpr_strdup(input_loc_ptr); - if (loc_ptr == NULL) { - return NULL; - } - } else { - loc_ptr = input_loc_ptr; - } - - if (*loc_ptr == DOUBLE_QUOTE) { - displayNameStart = loc_ptr + 1; - left_bracket = parse_display_name(loc_ptr + 1); - if (left_bracket == NULL) { - /* Could not find matching " or reached end of string or could not - * find < - */ - if (dup_flag) { - cpr_free(loc_ptr); - } - /* parse_display_name has already set the parse_errno */ - - return NULL; - } - } else { - - displayNameStart = loc_ptr; - /* Either we have token(s) preceding '<' or start of addr-spec */ - left_bracket = strpbrk(loc_ptr, ",<"); - if (left_bracket) { - if (*left_bracket == COMMA) { - *left_bracket = 0; - *more_ptr = left_bracket; - left_bracket = NULL; - save_ch = COMMA; - } - } else { - *more_ptr = NULL; - } - } - - sipLoc = (sipLocation_t *) cpr_calloc(1, sizeof(sipLocation_t)); - if (sipLoc == NULL) { - if (dup_flag) { - cpr_free(loc_ptr); - } - return NULL; - } - sipLoc->loc_start = start_ptr; /* Save pointer to start of allocated mem */ - - if (left_bracket) { - /* This is a name-addr form */ - - *left_bracket = 0; /* Terminate the display-name portion */ - sipLoc->name = displayNameStart; - addr_spec = left_bracket + 1; - right_bracket = strchr(addr_spec, RIGHT_ANGULAR_BRACKET); - if (right_bracket == NULL) { - if (dup_flag) { - cpr_free(loc_ptr); - } - cpr_free(sipLoc); - parse_errno = PARSE_ERR_UNMATCHED_BRACKET; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], - "sippmh_parse_nameaddr_or_addrspec"); - return NULL; - } - - /* Terminate the addr_spec at the > */ - *right_bracket++ = 0; - - /* Look for the next non-whitespace character */ - SKIP_LWS(right_bracket); - *more_ptr = right_bracket; - } else { - - /* This is addr-spec format */ - - if (name_addr_only_flag) { - if (dup_flag) { - cpr_free(loc_ptr); - } - cpr_free(sipLoc); - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s: Bad name-addr format", fname); - } - return NULL; - } - - addr_spec = loc_ptr; - /* In addr-spec form, it is illegal to have URL special - * chars such as SEMI_COLON, QUESTION MARK - */ - addr_param = addr_spec; - while (*addr_param) { - if (*addr_param == QUESTION_MARK || *addr_param == SEMI_COLON) { - - if ((save_ch != 0) && *more_ptr) { - /* restore the saved char mostly COMMA */ - **more_ptr = save_ch; - } - - save_ch = *addr_param; - *more_ptr = addr_param; - - /* Terminate the addr-spec form at Special char */ - *addr_param = 0; - break; - } - addr_param++; - } - } - - sipLoc->genUrl = sippmh_parse_url(addr_spec, FALSE); - if (sipLoc->genUrl == NULL) { - if (dup_flag) { - cpr_free(loc_ptr); - } - cpr_free(sipLoc); - /* sippmh_parse_url would have set the parse_errno */ - return NULL; - } - - /* - * There is more stuff to follow since *more_ptr is not NULL - * replace the special chars (such as ? or ;) in original string - */ - if ((save_ch != 0) && (*more_ptr != NULL)) { - **more_ptr = save_ch; - } - return sipLoc; -} - - -/* - * Validate the tag. The tag is composed of tokens. The tag_ptr - * points to the start of the tag and a list of semicolon - * separated addr-extensions or just the tag itself. - * - * Returns 0 (no error) if the tag is valid, else - * returns PARSE_ERR_SYNTAX. - * - */ -static int -validate_tag (sipLocation_t *sipLoc, char *tag_ptr) -{ - static const char fname[] = "validate_tag"; - int ret_val = 0; - char *term_ptr; - - /* Skip "tag=", points to value */ - tag_ptr += 4; - SKIP_LWS(tag_ptr); - if (*tag_ptr == 0) { - ret_val = PARSE_ERR_UNEXPECTED_EOS; - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", parse_errors[ret_val], fname); - } - - return ret_val; - } - - sipLoc->tag = tag_ptr; - - /* Walk the string until we encounter a non-token - * character. The only valid character at the end of - * string is either semicolon or end-of-line. - */ - - SKIP_SIP_TOKEN(tag_ptr); - term_ptr = tag_ptr; - /* skip trailing spaces */ - SKIP_LWS(tag_ptr); - if ((*tag_ptr != SEMI_COLON) && (*tag_ptr != 0)) { - ret_val = PARSE_ERR_SYNTAX; - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", parse_errors[ret_val], fname, tag_ptr); - } - } else { - /* terminate the tag */ - *term_ptr = 0; - } - - return ret_val; -} - - -sipLocation_t * -sippmh_parse_from_or_to (char *input_loc_ptr, boolean dup_flag) -{ - static const char fname[] = "sippmh_parse_from_or_to"; - char *more_ptr; - sipLocation_t *sipLoc; - boolean tag_found = FALSE; - char *lasts = NULL; - - /* - * From = ( "From" | "f" ) ":" ( name-addr | addr-spec ) - * *( ";" addr-params ) - * addr-params = tag-param | addr-extension - * tag-param = "tag=" token - * addr-exten = token = ["=" (token | quoted-string)] - * - * NOTE: Only the tag parameter in the addr-params is relevant to - * SIP so we skip all addr-extensions when parsing addr-params. - */ - - parse_errno = 0; - more_ptr = NULL; - sipLoc = sippmh_parse_nameaddr_or_addrspec(input_loc_ptr, input_loc_ptr, - dup_flag, FALSE, &more_ptr); - - if (sipLoc) { /* valid sipLocation */ - - if (more_ptr == NULL) { - return sipLoc; - } - - /* initialize the tag */ - sipLoc->tag = NULL; - if (*more_ptr == SEMI_COLON) { - *more_ptr++ = 0; - more_ptr = PL_strtok_r(more_ptr, ";", &lasts); - /* if we had a ; without any addr-params */ - if (more_ptr == NULL) { - parse_errno = PARSE_ERR_UNEXPECTED_EOS; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - } else { - /* parse the tag but skip any addr-extensions */ - while (more_ptr && tag_found == FALSE) { - SKIP_LWS(more_ptr); - if (strncmp(more_ptr, "tag=", 4) == 0) { - tag_found = TRUE; - parse_errno = validate_tag(sipLoc, more_ptr); - } else { - more_ptr = PL_strtok_r(NULL, ";", &lasts); - } - } - } - - } else if (*more_ptr) { - parse_errno = PARSE_ERR_SYNTAX; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname, more_ptr); - } - } - - if (parse_errno) { - sippmh_free_location(sipLoc); - sipLoc = NULL; - } - - return sipLoc; -} - -void -sippmh_free_location (sipLocation_t * sipLoc) -{ - if (sipLoc) { - cpr_free(sipLoc->loc_start); - /* make sure to free contents in genUrl_t. */ - sippmh_genurl_free(sipLoc->genUrl); - cpr_free(sipLoc); - } -} - -static char * -sippmh_parse_contact_params (char *params, sipContactParams_t *contact_params) -{ - char *param_value; - char *contact_other_param = NULL; - boolean good_params; - boolean good_qval; - char tmp_char; - - - /* - * contact-params = "q" "=" qvalue - * | "action" "=" "proxy" | "redirect" - * | "expires" "=" delta-seconds | <"> SIP-date <"> - * | extension-attribute - * - * params is pointing to first character after ';' - */ - SKIP_LWS(params); - if (*params == 0) { - return params; - } - while (1) { - good_params = FALSE; - - /* Parse qval parameter */ - if (*params == 'q' || *params == 'Q') { - params++; - SKIP_LWS(params); - if (*params == EQUAL_SIGN) { - params++; - SKIP_LWS(params); - if (*params) { - param_value = params; - good_qval = TRUE; - tmp_char = *params; - /* the qval must be in one of these forms */ - if ((!strncmp(params, "0", 1)) || - (!strncmp(params, "1", 1))) { - params++; /* move up to "." if present */ - if (*params == DOT) { - params++; - if (isdigit((int) *params)) { - while (isdigit((int) *params)) { - if ((tmp_char == '1') && - (*params != '0')) { - good_qval = FALSE; - break; - } - params++; - } - } else { - good_qval = FALSE; - } - } else if (((*params)) && ((*params != SPACE) && - (*params != SEMI_COLON) && - (*params != TAB))) { - good_qval = FALSE; - } - } else { - good_qval = FALSE; - } - if (good_qval) { - good_params = TRUE; - contact_params->qval = param_value; - if (*params == SPACE || *params == TAB) { - *params++ = 0; /* Terminate the qval */ - } - } - } - } - - /* Parse action paramater */ - } else if (cpr_strncasecmp(params, "action", 6) == 0) { - params += 6; - SKIP_LWS(params); - if (*params == EQUAL_SIGN) { - params++; - SKIP_LWS(params); - if (cpr_strncasecmp(params, "proxy", 5) == 0) { - contact_params->action = PROXY; - params += 5; - good_params = TRUE; - } else if (cpr_strncasecmp(params, "redirect", 8) == 0) { - contact_params->action = REDIRECT; - params += 8; - good_params = TRUE; - } - } - - /* Parse expires paramater */ - } else if (cpr_strncasecmp(params, "expires", 7) == 0) { - params += 7; - SKIP_LWS(params); - if (*params == EQUAL_SIGN) { - params++; - SKIP_LWS(params); - if (*params) { - char save_ch; - boolean is_int = FALSE; - - /* Expires can be given in delta seconds or date format. - * If date is used, the date must be enclosed in quotes. - * IOS does not use this parameter, but the SIP phones - * do. - */ - contact_params->expires_gmt = NULL; - good_params = TRUE; - param_value = params; - while (isdigit((int) *params)) { - params++; - is_int = TRUE; - } - if (is_int == TRUE) { - save_ch = *params; - *params = 0; /* terminate the string for strtoul */ - contact_params->expires = strtoul(param_value, NULL, 10); - *params = save_ch; - } else { - /* expires may be in SIP-date format */ - char *gmt_str; - - if (*params == DOUBLE_QUOTE) { /* skip the quote */ - params++; - } - if ((gmt_str = strstr(params, "GMT")) != NULL) { - contact_params->expires_gmt = params; - params = gmt_str + 3; - contact_params->expires = 0; - - if (*params == SPACE || *params == TAB || *params == DOUBLE_QUOTE) { - *params++ = '\0'; - } - } - } - } - } - /* Parse x-cisco-newreg */ - } else if (cpr_strncasecmp(params, REQ_CONT_PARAM_CISCO_NEWREG, - sizeof(REQ_CONT_PARAM_CISCO_NEWREG) - 1) == 0) { - /* - * x-cisco-newreg in the contact is set by CCM in the 200 OK - * response to the 1st. line registration message as information - * only to the endpoint that its registration is a new - * registration to the CCM. - */ - - /* - * Move parameter pointer pass this parm (-1 is to exclude - * null terminating character of the parameter name). - */ - params += sizeof(REQ_CONT_PARAM_CISCO_NEWREG) - 1; - good_params = TRUE; - contact_params->flags |= SIP_CONTACT_PARM_X_CISCO_NEWREG; - - /* Parse contact-extension paramater */ - } else { - if (params) { - params = parse_other_param(params, &contact_other_param); - if (params) { - good_params = TRUE; - /* - * Contact extensions are not supported. Throw away - * any that were just parsed. - */ - if (contact_other_param != NULL) { - cpr_free(contact_other_param); - } - } - } - } - if (good_params == FALSE) { - parse_errno = PARSE_ERR_SYNTAX; - return params; - } - SKIP_LWS(params); - if (*params == SEMI_COLON) { - /* More parameters follow */ - *params++ = 0; - SKIP_LWS(params); - } else { - /* Either we have encountered end of string or start of next - * location in this contact header. - */ - return params; - } - } -} - -/* Parses limit parameter for CC-Diversion or CC-Redirect - * header. The parsed value is in sipDiversion_t structure. - * Returns pointer to remaining characters in the buffer, if fails NULL - */ -static char * -sippmh_parse_limit_params (char *limit_t, sipDiversion_t *sipdiversion) -{ - boolean params_good = FALSE; - char save_ch; - char *param_value = NULL; - int digit_count = 0; - - if ((limit_t == NULL) || (sipdiversion == NULL)) { - return NULL; - } - - SKIP_LWS(limit_t); - if (*limit_t == EQUAL_SIGN) { - limit_t++; - SKIP_LWS(limit_t); - if (*limit_t) { - params_good = TRUE; - param_value = limit_t; - while (isdigit((int) *limit_t)) { - digit_count++; - limit_t++; - } - if (digit_count > 2) { - /* More than two digits */ - params_good = FALSE; - return NULL; - } - digit_count = 0; - save_ch = *limit_t; - *limit_t = 0; - sipdiversion->limit = strtoul(param_value, NULL, 10); - *limit_t = save_ch; - } - } else { - /* Equal to sign missing */ - params_good = FALSE; - } - - if (params_good) { - return limit_t; - } else { - return NULL; - } -} - - -/* Parses counter parameter for CC-Diversion or CC-Redirect - * header. The parsed value is in sipDiversion_t structure. - * Returns pointer to remaining characters in the buffer, if fails NULL - */ -static char * -sippmh_parse_counter_params (char *counter_t, sipDiversion_t *sipdiversion) -{ - boolean params_good = FALSE; - char save_ch; - char *param_value = NULL; - int digit_count = 0; - - if ((counter_t == NULL) || (sipdiversion == NULL)) { - return NULL; - } - - SKIP_LWS(counter_t); - if (*counter_t == EQUAL_SIGN) { - counter_t++; - SKIP_LWS(counter_t); - if (*counter_t) { - params_good = TRUE; - param_value = counter_t; - while (isdigit((int) *counter_t)) { - digit_count++; - counter_t++; - } - if (digit_count > 2) { - /* More than two digits */ - params_good = FALSE; - return NULL; - } - digit_count = 0; - save_ch = *counter_t; - *counter_t = 0; - sipdiversion->counter = strtoul(param_value, NULL, 10); - *counter_t = save_ch; - - } - } else { - /* Equal to sign missing */ - params_good = FALSE; - } - - if (params_good) { - return counter_t; - } else { - return NULL; - } -} - - -static boolean -sippmh_parse_diversion_params (char *diversion_t, sipDiversion_t *sipdiversion) -{ - - while (1) { - /* Parsing diversion-reason parameter */ - if (strncasecmp(diversion_t, DIVERSION_REASON, 6) == 0) { -// We don't use reason parameter, so comment out at this time. -// diversion_t += 6; -// if ((diversion_t = sippmh_parse_reason_params(diversion_t, sipdiversion)) == NULL) -// return FALSE; - /* - * Since we do not use reason parameter, search for semi-colan to mark - * start of next parameter. If no semi-colon, then we are done. - */ - diversion_t = strchr(diversion_t, SEMI_COLON); - if (diversion_t == NULL) { - // End of parameter list - return TRUE; - } - /* Parse diversion-limit parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_LIMIT, 5) == 0) { - diversion_t += 5; - if ((diversion_t = sippmh_parse_limit_params(diversion_t, sipdiversion)) == FALSE) - return FALSE; - - /* Parse diversion-counter parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_COUNTER, 7) == 0) { - diversion_t += 7; - if ((diversion_t = sippmh_parse_counter_params(diversion_t, sipdiversion)) == FALSE) - return FALSE; - - /* Parse diversion-privacy parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_PRIVACY, 7) == 0) { - diversion_t += 7; - if ((diversion_t = parse_generic_param(diversion_t, &(sipdiversion->privacy))) == NULL) - return FALSE; - - /* Parse diversion-screen parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_SCREEN, 6) == 0) { - diversion_t += 6; - if ((diversion_t = parse_generic_param(diversion_t, &(sipdiversion->screen))) == NULL) - return FALSE; - } - - SKIP_LWS(diversion_t); - if (*diversion_t == SEMI_COLON) { - /* More parameters follow */ - *diversion_t++ = 0; - SKIP_LWS(diversion_t); - } else { - break; - } - } - - return TRUE; - -} - -sipDiversion_t * -sippmh_parse_diversion (const char *diversion, char *diversionhead) -{ - char *param_ptr; - sipDiversion_t *sipdiversion; - sipLocation_t *sipLoc; - char *diversion_t, *start_ptr; - - /* CC-Diversion = "CC-Diversion" - * *(diversion-params [comment]) - * diversion-params = diversion-addr | diversion-reason | - * diversion-counter| diversion-limit - * diversion-addr = (name-addr | addr-spec)*(";"addr-params) - * diversion-reason = "reason"= "unknown" | "user-busy" | "no-answer" | - * "unconditional" | "deflection"| "follow-me" | - * "out-of-service" | " time-of-day" | "unavailable" | - * "do-not-disturb" - * diversion-counter = "counter" = 2*DIGIT - * diversion-limit = "limit" = 2*DIGIT - */ - - /* - * Diversion = "Diversion" ":" 1# (name-addr *( ";" diversion_params )) - * diversion-params = diversion-reason | diversion-counter | - * diversion-limit | diversion-privacy | - * diversion-screen | diversion-extension - * diversion-reason = "reason" "=" - * ( "unknown" | "user-busy" | "no-answer" | - * "unavailable" | "unconditional" | - * "time-of-day" | "do-not-disturb" | - * "deflection" | "follow-me" | - * "out-of-service" | "away" | - * token | quoted-string ) - * diversion-counter = "counter" "=" 1*2DIGIT - * diversion-limit = "limit" "=" 1*2DIGIT - * diversion-privacy = "privacy" "=" ( "full" | "name" | - * "uri" | "off" | token | quoted-string ) - * diversion-screen = "screen" "=" ( "yes" | "no" | token | - * quoted-string ) - * diversion-extension = token ["=" (token | quoted-string)] - */ - - sipdiversion = (sipDiversion_t *) cpr_calloc(1, sizeof(sipDiversion_t)); - if (sipdiversion == NULL) { - return NULL; - } - - diversion_t = cpr_strdup(diversion); - - if (diversion_t == NULL) { - sippmh_free_diversion(sipdiversion); - return NULL; - } - - start_ptr = diversion_t; - - do { - - param_ptr = NULL; - sipLoc = sippmh_parse_nameaddr_or_addrspec(diversion_t, start_ptr, FALSE, FALSE, - ¶m_ptr); - if (sipLoc == NULL) { - cpr_free(start_ptr); - sippmh_free_diversion(sipdiversion); - sipdiversion = NULL; - break; - } - - sipdiversion->locations = sipLoc; - - if (param_ptr == NULL || *param_ptr == 0) { - /* No params */ - break; - } - diversion_t = param_ptr; - if (*diversion_t == SEMI_COLON) { - /* Parsing Diversion Headers */ - *diversion_t++ = 0; - - if ((strncasecmp(diversionhead, SIP_HEADER_DIVERSION, - sizeof(SIP_HEADER_DIVERSION)) == 0) || - (strncasecmp(diversionhead, SIP_HEADER_CC_DIVERSION, - sizeof(SIP_HEADER_CC_DIVERSION)) == 0)) { - - if (sippmh_parse_diversion_params(diversion_t, sipdiversion) == FALSE) { - - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "sippmh_parse_diversion: " - "syntax error in Diversion header"); - } - parse_errno = PARSE_ERR_SYNTAX; - sippmh_free_diversion(sipdiversion); - sipdiversion = NULL; - break; - } - } - /* Must reach here after parsing all parameters */ - break; /* break out of original do loop */ - } else { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "sippmh_parse_diversion: syntax error " - "missing semicolon in Diversion header"); - } - parse_errno = PARSE_ERR_SYNTAX; - sippmh_free_diversion(sipdiversion); - sipdiversion = NULL; - break; - } - - } while (1); - return sipdiversion; -} - -void -sippmh_free_diversion (sipDiversion_t * ccr) -{ - if (ccr) { - if (ccr->locations) { - sippmh_free_location(ccr->locations); - } - cpr_free(ccr); - } -} - - -sipContact_t * -sippmh_parse_contact (const char *input_contact) -{ - int j, k; - char *contact = NULL, *start_ptr = NULL; - char *more_ptr; - sipContact_t *sipContact; - sipContactParams_t params; - - /* - * Contact = ( "Contact" | "m" ) ":" - * ("*" | (1# (( name-addr | addr-spec ) - * [ *( ";" contact-params ) ] [ comment ] ))) - * name-addr = [ display-name ] "<" addr-spec ">" - * addr-spec = SIP-URL | URI - * display-name = *token | quoted-string - * - * contact-params = "q" "=" qvalue - * | "action" "=" "proxy" | "redirect" - * | "expires" "=" delta-seconds | <"> SIP-date <"> - * | extension-attribute - * - */ - parse_errno = 0; - contact = cpr_strdup(input_contact); - if (contact == NULL) { - return NULL; - } - - sipContact = (sipContact_t *) cpr_calloc(1, sizeof(sipContact_t)); - if (sipContact == NULL) { - cpr_free(contact); - return NULL; - } - - memset(¶ms, 0, sizeof(sipContactParams_t)); - - start_ptr = contact; - - do { - sipLocation_t *sipLoc; - - more_ptr = NULL; - sipLoc = sippmh_parse_nameaddr_or_addrspec(contact, start_ptr, FALSE, - FALSE, &more_ptr); - if (sipLoc == NULL) { - if ((more_ptr != NULL) && (*more_ptr == COMMA)) { - /* Another location follows */ - contact = more_ptr; - *contact++ = 0; - SKIP_LWS(contact); - if (sipContact->num_locations == SIP_MAX_LOCATIONS) { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "sippmh_parse_contact: Too many" - " location headers in Contact header"); - } - /* go with what we have */ - break; - } - continue; - } else { - if (sipContact->num_locations == 0) { - // Free start_ptr only if we fail the first location - // For the others, it will be freed when sipContact is - // freed - cpr_free(start_ptr); - } - sippmh_free_contact(sipContact); - sipContact = NULL; - break; - } - } - if (sipContact->num_locations) { - sipLoc->loc_start = NULL; - } - if (more_ptr == NULL || *more_ptr == 0) { - /* No params, means no qval and assume lowest priority */ - sipContact->locations[sipContact->num_locations++] = sipLoc; - break; - } - contact = more_ptr; - /* - * At this point, either contact is pointing to - * 1) ';' - Contact params - * 2) ',' - Beginning of next location - * 3) End of string - * 4) Any other character is syntax error - */ - - j = sipContact->num_locations; /* By default insert at the end */ - params.qval = ""; - - if (*contact == SEMI_COLON) { - /* Now parse the Contact params */ - *contact++ = 0; - params.flags = 0; - contact = sippmh_parse_contact_params(contact, ¶ms); - /* - * Now, do an insertion sort on this list (qval is the key). - * Higher values of q come first. - */ - for (j = 0; j < sipContact->num_locations; ++j) { - if (strcmp(params.qval, sipContact->params[j].qval) > 0) { - for (k = sipContact->num_locations; k > j; --k) { - sipContact->locations[k] = sipContact->locations[k - 1]; - sipContact->params[k] = sipContact->params[k - 1]; - } - break; - } - } - /* At this point j points to the entry to use */ - } - - sipContact->params[j] = params; - sipContact->locations[j] = sipLoc; - sipContact->num_locations++; - - if (contact && *contact == COMMA) { - /* Another location follows */ - *contact++ = 0; - SKIP_LWS(contact); - if (sipContact->num_locations == SIP_MAX_LOCATIONS) { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "sippmh_parse_contact: Too many " - "location headers in Contact header"); - } - /* go with what we have */ - break; - } - } else { - if (contact && *contact) { - parse_errno = PARSE_ERR_SYNTAX; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], "sippmh_parse_contact", - contact); - sippmh_free_contact(sipContact); - sipContact = NULL; - } - break; - } - } while (1); - - if (sipContact) { - sipContact->new_flag = TRUE; - } - return sipContact; -} - - -void -sippmh_free_contact (sipContact_t *sc) -{ - int i; - - if (sc) { - for (i = 0; i < sc->num_locations; ++i) { - if (sc->locations[i]->loc_start) { - /* Free the entire header value that we duplicated */ - cpr_free(sc->locations[i]->loc_start); - } - /* Free the genUrl_t struct in the sipLocation_t */ - sippmh_genurl_free(sc->locations[i]->genUrl); - /* Free the sipLocation_t struct */ - cpr_free(sc->locations[i]); - } - - /* Free the sipContact_t struct */ - cpr_free(sc); - } -} - -static boolean -parse_via_params (char *str, sipVia_t *sipVia) -{ - char **ptr; - - /* str is currently pointing to beginning of parameters */ - - while (1) { - /* To be friendly, skip leading spaces */ - SKIP_LWS(str); - if (strncasecmp(str, VIA_HIDDEN, 6) == 0) { - str += 6; - sipVia->flags |= VIA_IS_HIDDEN; - ptr = NULL; - } else if (strncasecmp(str, VIA_TTL, 3) == 0) { - str += 3; - ptr = &(sipVia->ttl); - } else if (strncasecmp(str, VIA_MADDR, 5) == 0) { - str += 5; - ptr = &(sipVia->maddr); - } else if (strncasecmp(str, VIA_RECEIVED, 8) == 0) { - str += 8; - ptr = &(sipVia->recd_host); - } else if (strncasecmp(str, VIA_BRANCH, 6) == 0) { - str += 6; - ptr = &(sipVia->branch_param); - } else { - ptr = NULL; - } - if (ptr) { - if (*ptr) { - /* ptr already points to something - * -- duplicate param found */ - return FALSE; - } - SKIP_LWS(str); /* Skip spaces till equal sign */ - if (*str == EQUAL_SIGN) { - str++; - SKIP_LWS(str); - *ptr = str; - } - } - str = strpbrk(str, ";,"); - if (str == NULL) { - if (ptr && *ptr) { - trim_right(*ptr); - } - return TRUE; - } - if (*str == COMMA) { - *str++ = 0; - SKIP_LWS(str); - sipVia->more_via = str; - if (ptr && *ptr) { - trim_right(*ptr); - } - return TRUE; - } - *str++ = 0; /* Zero ';' and advance pointer */ - if (ptr && *ptr) { - trim_right(*ptr); - } - } -} - -sipVia_t * -sippmh_parse_via (const char *input_via) -{ - static const char fname[] = "sippmh_parse_via"; - char *via; - char *separator; - sipVia_t *sipVia; - char *endptr; - char *port_num_str; - uint16_t port_num; - - /* - * Via = ( "Via" | "v") ":" 1#( sent-protocol sent-by - * *( ";" via-params ) [ comment ] ) - * via-params = via-hidden | via-ttl | via-maddr - * | via-received | via-branch - * via-hidden = "hidden" - * via-ttl = "ttl" "=" ttl - * via-maddr = "maddr" "=" maddr - * via-received = "received" "=" host - * via-branch = "branch" "=" token - * sent-protocol = protocol-name "/" protocol-version "/" transport - * protocol-name = "SIP" | token - * protocol-version = token - * transport = "UDP" | "TCP" | "TLS" | token - * sent-by = ( host [ ":" port ] ) | ( concealed-host ) - * concealed-host = token - * ttl = 1*3DIGIT ; 0 to 255 - */ - - parse_errno = PARSE_ERR_SYNTAX; - if (input_via == NULL) { - return NULL; - } - sipVia = NULL; - via = NULL; - SKIP_LWS(input_via); - do { - if (strncasecmp(input_via, "SIP", 3)) { - /* Unknown protocol-name */ - break; - } - input_via += 3; - - SKIP_LWS(input_via); - if (*input_via != '/') { - break; - } - input_via++; /* Skip '/' */ - - SKIP_LWS(input_via); - /* input_via should now be pointing to version */ - - /* Duplicate the string and work with it */ - via = cpr_strdup(input_via); - if (via == NULL) { - parse_errno = 0; - return NULL; - } - /* Allocate sipVia_t struct */ - sipVia = (sipVia_t *) cpr_calloc(1, sizeof(sipVia_t)); - if (sipVia == NULL) { - parse_errno = 0; - cpr_free(via); - return NULL; - } - - /* version also points to the start of memory allocated */ - sipVia->version = via; - if (strncmp(via, "2.0", 3)) { - break; - } - via += 3; /* Go past version */ - - SKIP_LWS(via); - if (*via != '/') { - break; - } - *via++ = 0; /* Terminate version string and go past '/' */ - - SKIP_LWS(via); /* Point to transport */ - sipVia->transport = via; - if (strncasecmp(via, "UDP", 3) && strncasecmp(via, "TCP", 3) && - strncasecmp(via, "TLS", 3)) { - /* Invalid transport */ - break; - } - via += 3; /* Go past the transport string */ - *via++ = 0; /* Terminate transport string and advance pointer */ - - - /* Skip blanks */ - SKIP_LWS(via); - if (*via == 0) { - parse_errno = PARSE_ERR_UNEXPECTED_EOS; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - break; - } - - parse_errno = 0; - - } while (0); - - if (parse_errno) { - if (parse_errno == PARSE_ERR_SYNTAX) { - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname, via ? via : input_via); - } - sippmh_free_via(sipVia); - return NULL; - } - - port_num_str = SIP_WELL_KNOWN_PORT_STR; - sipVia->host = via; - /* - * Either we can have a ':' followed by port - * or start of parameters signalled by ';' - * or end of this Via indicated by ',' - */ - if (*via == '[') { - /* IPv6 address */ - sipVia->host = via; - sipVia->is_ipv6 = TRUE; - separator = strpbrk(via, "]"); - - if (separator && *separator == ']') { - separator++; - } - } else { - - separator = via; - } - - if (separator) { - separator = strpbrk(separator, ":;,"); - } - if (separator) { - if (*separator == COLON) { - /* Port number follows */ - *separator++ = 0; - port_num_str = separator; - separator = strpbrk(separator, ";,"); - } - if (separator) { - if (*separator == SEMI_COLON) { - *separator++ = 0; - /* Parameters follow */ - if (parse_via_params(separator, sipVia) == FALSE) { - CCSIP_ERR_DEBUG - CSFLogDebug("sipstack", "%s: Duplicate params in Via", - fname); - sippmh_free_via(sipVia); - return NULL; - } - } else { - *separator++ = 0; - SKIP_LWS(separator); - sipVia->more_via = separator; - } - } - } - - /* Validate the host portion */ - if ((sipSPI_validate_ip_addr_name(sipVia->host) == FALSE)) { - CCSIP_ERR_DEBUG CSFLogDebug("sipstack", "%s: Invalid host in Via", - fname); - sippmh_free_via(sipVia); - return NULL; - } - - /* Fix host portion */ - trim_right(sipVia->host); - /* Fix IPv6 host */ - trim_ipv6_host(sipVia->host); - - /* validate port portion */ - port_num = (uint16_t) strtol(port_num_str, &endptr, 10); - - /* - * There may be trailing white space in the port portion. So, ignore them. - */ - SKIP_LWS(endptr); - if (*endptr || port_num == 0) { - sippmh_free_via(sipVia); - CCSIP_ERR_DEBUG CSFLogDebug("sipstack", - "%s: Invalid port number in Via", fname); - return NULL; - } - sipVia->remote_port = port_num; - sipVia->recd_host = sipVia->host; - return sipVia; -} - -void -sippmh_free_via (sipVia_t * sipVia) -{ - if (sipVia) { - cpr_free(sipVia->version); - cpr_free(sipVia); - } -} - - -sipCseq_t * -sippmh_parse_cseq (const char *cseq) -{ - char *lasts = NULL; - /* - * CSeq = "CSeq" ":" 1*DIGIT Method - */ - sipCseq_t *sipCseq = (sipCseq_t *) cpr_calloc(1, sizeof(sipCseq_t)); - - if (!sipCseq) { - return (NULL); - } - -/* if ',' is present then more than 1 cseq are present */ - if (strchr(cseq, ',')) { - cpr_free(sipCseq); - return (NULL); - } - - if (cseq) { - char *mycseq = cpr_strdup(cseq); - - sipCseq->method = sipMethodInvalid; - - if (mycseq) { - char *this_token = PL_strtok_r(mycseq, " ", &lasts); - - if (this_token) { - sipCseq->number = strtoul(this_token, NULL, 10); - - /* make sure the CSeq value is not > 2^^31 */ - if (sipCseq->number >= TWO_POWER_31) { - cpr_free(sipCseq); - cpr_free(mycseq); - return (NULL); - } - - this_token = PL_strtok_r(NULL, " ", &lasts); - if (this_token) { - sipCseq->method = sippmh_get_method_code(this_token); - } - - } - if (!this_token) { - cpr_free(sipCseq); - cpr_free(mycseq); - return (NULL); - } - cpr_free(mycseq); - } else { - cpr_free(sipCseq); - return NULL; - } - } - - return (sipCseq); -} - -sipRet_t -sippmh_add_cseq (sipMessage_t *msg, const char *method, uint32_t seq_no) -{ - sipRet_t retval = STATUS_FAILURE; - - if (msg && method) { - char cseq[32]; - - sprintf(&cseq[0], "%lu %s", (unsigned long) seq_no, method); - retval = sippmh_add_text_header(msg, SIP_HEADER_CSEQ, - (const char *)&cseq[0]); - } - - return (retval); -} - -/* - * The Valid SIP URL MUST contain host field. - * This is not true for TEL URLs. Only user is mandatory. - * This check is sufficient for "From" & "To" headers - * from a GW standpoint. The ReqLine MUST have a "user" - * in the URL as the GW supports multiple users. - */ -boolean -sippmh_valid_url (genUrl_t *genUrl) -{ - boolean retval = FALSE; - - if (!genUrl) { - return retval; - } - if (genUrl->schema == URL_TYPE_SIP) { - if (genUrl->u.sipUrl->host && genUrl->u.sipUrl->host[0]) - retval = TRUE; - } else if (genUrl->schema == URL_TYPE_TEL) { - if (genUrl->u.telUrl->user) - retval = TRUE; - } - - return (retval); -} - -/* - * The Input string is the comma separated cached Record-Route - * header string. This function duplicates the input string - * and generates a set of pointers which are pointing to a - * name-addr format string. These pointers are pointing within - * the duplicated cached header string. - * - * Loc 0 Loc 1 Loc 2 - * Loc_start -> name-addr1, name-addr2, name-addr3 - * - * Loc_start points to the duplicated input string and needs - * to be freed. - * Loc_start is preserved so that the string - * can be freed, when required. Thus this pointer needs to be - * stored only once. - */ -sipRecordRoute_t * -sippmh_parse_record_route (const char *input_record_route) -{ - char *record_route = NULL, *start_ptr = NULL; - char *more_ptr; - sipRecordRoute_t *sipRecordRoute; - char *rr_other_param = NULL; - - /* - * Record-Route = "Record-Route" ":" (name-addr *(";" rr-param)) - * name-addr = [ display-name ] "<" addr-spec ">" - * addr-spec = SIP-URL | URI - * display-name = *token | quoted-string - * rr-param = generic-param - * generic-param = token [ = ( token | host | quoted-string ) ] - */ - - record_route = cpr_strdup(input_record_route); - if (record_route == NULL) { - return NULL; - } - - sipRecordRoute = (sipRecordRoute_t *) - cpr_calloc(1, sizeof(sipRecordRoute_t)); - - if (sipRecordRoute == NULL) { - cpr_free(record_route); - return NULL; - } - - start_ptr = record_route; - - do { - sipLocation_t *sipLoc; - - more_ptr = NULL; - parse_errno = 0; - sipLoc = sippmh_parse_nameaddr_or_addrspec(record_route, start_ptr, - FALSE, TRUE, &more_ptr); - if (sipLoc == NULL) { - if (sipRecordRoute->locations == 0) { - // Free record_route only if we fail the first location - // For the others, it will be freed when sipRecordRoute is - // freed - cpr_free(record_route); - } - sippmh_free_record_route(sipRecordRoute); - sipRecordRoute = NULL; - break; - } - - /* Loc_start points to the duplicated input string & - * is stored in the zeroth location of location[]. - * This value needs to be freed only once - */ - if (sipRecordRoute->num_locations) { - sipLoc->loc_start = NULL; - } - - sipRecordRoute->locations[sipRecordRoute->num_locations++] = sipLoc; - - if (more_ptr == NULL || *more_ptr == 0) { - /* No params, means no qval and assume lowest priority */ - break; - } - - record_route = more_ptr; - - /* - * At this point, either record_route is pointing to - * 1) ',' - Beginning of next location - * 3) End of string - * 4) Any other character is syntax error - */ - - /* - * This following while loop eats up all the rr_params. - * Note that these 'other_params' are not the same as the ones handled - * by parseURLParams. That routines parses other params INSIDE the < > brackets. - * The following code would handle unknown params outside the brackets. - */ - while (record_route && *record_route == SEMI_COLON) { - record_route++; - record_route = parse_other_param(record_route, &rr_other_param); - /* - * Record route extensions are not supported. Throw away - * any that were just parsed. - */ - if (rr_other_param != NULL) { - cpr_free(rr_other_param); - } - } - - - if (record_route && *record_route == COMMA) { - /* Another location follows */ - *record_route++ = 0; - SKIP_LWS(record_route); - if (sipRecordRoute->num_locations == SIP_MAX_LOCATIONS) { - sippmh_free_record_route(sipRecordRoute); - sipRecordRoute = NULL; - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "sippmh_parse_record_route: Too " - "many location headers in Record-Route header"); - } - break; - } - } else { - /* Flag error if not "end of header" & - * any other character other than COMMA - */ - if (record_route && *record_route) { - parse_errno = PARSE_ERR_SYNTAX; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], - "sippmh_parse_record_route", record_route); - sippmh_free_record_route(sipRecordRoute); - sipRecordRoute = NULL; - } - break; - } - } while (1); - - if (sipRecordRoute) { - sipRecordRoute->new_flag = TRUE; - } - return sipRecordRoute; -} - -/* - * This function is a placeholder for future expansion. - * If deep copy of the record route is needed from one ccb to another - * this function can be used. - */ -sipRecordRoute_t * -sippmh_copy_record_route (sipRecordRoute_t *rr) -{ - //TBD - return NULL; -} - -void -sippmh_free_record_route (sipRecordRoute_t *rr) -{ - int i; - - if (rr) { - for (i = 0; i < rr->num_locations; ++i) { - if (rr->locations[i]->loc_start) { - /* Free the entire header value that we duplicated */ - cpr_free(rr->locations[i]->loc_start); - } - /* Free the genUrl_t struct in the sipLocation_t */ - sippmh_genurl_free(rr->locations[i]->genUrl); - /* Free the sipLocation_t in Record-Route struct */ - cpr_free(rr->locations[i]); - } - /* Free the sipContact_t struct */ - cpr_free(rr); - } -} - -cc_content_disposition_t * -sippmh_parse_content_disposition (const char *input_content_disp) -{ - char *content_disp = NULL; - char *content_disp_start = NULL; - cc_content_disposition_t *sipContentDisp = NULL; - char *separator = NULL; - char *more_ptr = NULL; - - if (input_content_disp == NULL) { - return NULL; - } - - content_disp_start = content_disp = cpr_strdup(input_content_disp); - if (content_disp == NULL) { - return NULL; - } - - /* - * Content-Disposition = "Content-Disposition" ":" - * disposition-type*(";" disposition-param) - * disposition-type = "render" "session" "Icon" "alert" "precondition" - * disp-extension-token - * disposition-param = "handling" "=" - * ("optional"|"required" other-handling) - * generic-param - * other-handling = token - * disp-extension-token = token - */ - - sipContentDisp = (cc_content_disposition_t *) - cpr_calloc(1, sizeof(cc_content_disposition_t)); - if (sipContentDisp == NULL) { - cpr_free(content_disp); - return sipContentDisp; - } - - /* Set the field to protocol define defaults - * - Session & required handling - */ - sipContentDisp->disposition = cc_disposition_session; - sipContentDisp->required_handling = TRUE; - - /* first token should be disposition-type - so look for - * a token delimiter either a space or semicolon - */ - SKIP_LWS(content_disp); - separator = strpbrk(content_disp, " ;"); - if (separator) { - if (*separator == ';') { - *separator = 0; - more_ptr = separator + 1; - } else { - *separator = 0; - more_ptr = NULL; - } - } else { - more_ptr = NULL; - } - - /* Parse disposition-type */ - if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_SESSION, 7) == 0) { - sipContentDisp->disposition = cc_disposition_session; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_PRECONDITION, 12) == 0) { - sipContentDisp->disposition = cc_disposition_precondition; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_ICON, 4) == 0) { - sipContentDisp->disposition = cc_dispostion_icon; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_ALERT, 5) == 0) { - sipContentDisp->disposition = cc_disposition_alert; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_RENDER, 6) == 0) { - sipContentDisp->disposition = cc_disposition_render; - } else { - sipContentDisp->disposition = cc_disposition_unknown; - } - - if (more_ptr) { - /* parse disposition-param */ - SKIP_LWS(more_ptr); - if (strncasecmp(more_ptr, "handling", 8) == 0) { - more_ptr += 8; - SKIP_LWS(more_ptr); - if (*more_ptr == '=') { - more_ptr++; - SKIP_LWS(more_ptr); - if (strncasecmp(more_ptr, "optional", 8) == 0) { - sipContentDisp->required_handling = FALSE; - } else if (strncasecmp(more_ptr, "required", 8) == 0) { - sipContentDisp->required_handling = TRUE; - } - } - } else { - /* Keyword "handling" is not found - * default values are already populated - */ - } - } - - cpr_free(content_disp_start); - return (sipContentDisp); -} - - -/*************************************************************** - * - * Parses headers in Refer-To body in a char array - * - **************************************************************/ -static uint16_t -sippmh_parse_referto_headers (char *refto_line, char **header_arr) -{ - uint16_t headNum = 0; - char *tmpHead = NULL; - char *lasts = NULL; - - if (refto_line == NULL) { - return 0; - } - - tmpHead = PL_strtok_r(refto_line, "?&", &lasts); - while (tmpHead != NULL) { - header_arr[headNum++] = tmpHead; - tmpHead = PL_strtok_r(NULL, "?&", &lasts); - } - return headNum; -} - - -/******************************************************************* - * - * Parser routine for headers other than sip url. Parses Replaces - * header, copies Accept-Contact and Proxy-Authorization headers - * and skips other headers. - * - * Input parameters : Array containing headers in Refer-To body, - * count of number of headers in Refer-To body - * & pointer to Refer-To structure for parsed - * values to be returned to calling function - * - * Returns : Zero if success, non-zero otherwise - * - *******************************************************************/ -static int -sippmh_parse_other_headers (char **headerArr, uint16_t tokCount, - sipReferTo_t *refer_to) -{ - uint16_t count = 0; - char *dup_header, *mhead; - - dup_header = mhead = NULL; - - for (count = 1; count < tokCount; count++) { - dup_header = cpr_strdup(headerArr[count]); - if (dup_header == NULL) { - return (PARSE_ERR_NO_MEMORY); - } - mhead = strchr(dup_header, '='); - if (mhead == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } else { - *mhead = '\0'; - } - if (cpr_strcasecmp(dup_header, SIP_HEADER_REPLACES) == 0) { - - char *unescRepl_str = NULL; - - /* - * copy the Replaces header so that it can be - * echoed back in the triggered INVITE. Also - * unescape any escpaed characters. - */ - headerArr[count] = strstr(headerArr[count], "="); - if (headerArr[count] == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - *(headerArr[count])++ = 0; - SKIP_LWS(headerArr[count]); - - /* if header body is NULL, return syntax error */ - if (*headerArr[count] == '\0') { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - - unescRepl_str = (char *) cpr_malloc(strlen(headerArr[count]) + 1); - if (unescRepl_str == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_NO_MEMORY); - } - - sippmh_convertEscCharToChar((const char *) headerArr[count], - (uint8_t) strlen(headerArr[count]), unescRepl_str); - - refer_to->sip_replaces_hdr = unescRepl_str; - - } else if (cpr_strcasecmp(dup_header, SIP_HEADER_ACCEPT_CONTACT) == 0 || - cpr_strcasecmp(dup_header, SIP_C_HEADER_ACCEPT_CONTACT) == 0) { - char *unescAccCont = NULL; - - /* - * copy unescaped version of this header so - * that it can be echoed back in triggered INVITE - */ - headerArr[count] = strstr(headerArr[count], "="); - if (headerArr[count] == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - *(headerArr[count])++ = 0; - SKIP_LWS(headerArr[count]); - - /* if header body is NULL, return syntax error */ - if (*headerArr[count] == '\0') { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - - unescAccCont = (char *) cpr_malloc(strlen(headerArr[count]) + 1); - - if (unescAccCont == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_NO_MEMORY); - } - - sippmh_convertEscCharToChar((const char *) headerArr[count], - (uint8_t) strlen(headerArr[count]), - unescAccCont); - - refer_to->sip_acc_cont = unescAccCont; - - } else if (cpr_strcasecmp(dup_header, SIP_HEADER_PROXY_AUTH) == 0) { - - char *unescPrAuth = NULL; - - /* - * copy this header to be echoed back in triggered INVITE - * unescape any escaped chars before storing - */ - - headerArr[count] = strstr(headerArr[count], "="); - if (headerArr[count] == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - *(headerArr[count])++ = 0; - SKIP_LWS(headerArr[count]); - - /* if header body is NULL, return syntax error */ - if (*headerArr[count] == '\0') { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - - unescPrAuth = (char *) cpr_malloc(strlen(headerArr[count]) + 1); - if (unescPrAuth == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_NO_MEMORY); - } - - sippmh_convertEscCharToChar((const char *) headerArr[count], - (uint8_t) strlen(headerArr[count]), - unescPrAuth); - - refer_to->sip_proxy_auth = unescPrAuth; - } - cpr_free(dup_header); - } - - return 0; /* SUCCESS */ -} - -/************************************************************** - * Parser routine for Refer-To header. Refer-To may contain - * other headers like: - * a) Replaces - * b) Accept-Contact - * c) Proxy-Authorization - * will skip headers, we do not understand; parse Replaces; - * and copy Accept-Contact and Proxy-Authorization headers - * to be echoed back in the triggered INVITE. - * - * Input parameters : Refer-To string to be parsed. - * Returns : Pointer to Refer-To structure with parsed values - * if successful, NULL otherwise. - * - **************************************************************/ -sipReferTo_t * -sippmh_parse_refer_to (char *input_refer_to) -{ - char *refer_to_headers[MAX_REFER_TO_HEADER_CONTENTS]; - char *left_bracket, *right_bracket, *msg_body, *refer_to_val; - sipReferTo_t *sipReferTo = NULL; - genUrl_t *refUrl = NULL; - uint16_t tokens = 0; - int ref_header_count = 0; - - left_bracket = right_bracket = msg_body = refer_to_val = NULL; - - if (input_refer_to == NULL) { - return NULL; - } - - /* - * Refer-To = ("Refer-To" | "r") ":" URL - */ - - /* make a copy of refer-to to work with */ - refer_to_val = cpr_strdup(input_refer_to); - if (refer_to_val == NULL) { - return NULL; - } - - sipReferTo = (sipReferTo_t *) cpr_calloc(1, sizeof(sipReferTo_t)); - if (sipReferTo == NULL) { - cpr_free(refer_to_val); - return NULL; - } - sipReferTo->ref_to_start = refer_to_val; - - /* Initialize */ - for (ref_header_count = 0; - ref_header_count < MAX_REFER_TO_HEADER_CONTENTS; - ref_header_count++) { - refer_to_headers[ref_header_count] = NULL; - } - - /* first get rid of opening and closing braces, if there */ - left_bracket = strpbrk(refer_to_val, ",<"); - if (left_bracket) { - - /* This is a name-addr form */ - left_bracket++; - right_bracket = strchr(left_bracket, '>'); - if (right_bracket) { - *right_bracket++ = 0; - } - msg_body = left_bracket; - } else { - - /* This is addr-spec format */ - msg_body = refer_to_val; - SKIP_LWS(msg_body); - } - - /* parse headers separated by ? or & in an array of char pointers */ - tokens = sippmh_parse_referto_headers(msg_body, refer_to_headers); - - if (tokens == 0) { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "Empty Refer-To header"); - } - sippmh_free_refer_to(sipReferTo); - return NULL; - } - - /* First parse url portion, this should be the first element - * of the headers array - */ - refUrl = sippmh_parse_url(refer_to_headers[0], FALSE); - if (refUrl == NULL) { - sippmh_free_refer_to(sipReferTo); - return NULL; - } - sipReferTo->targetUrl = refUrl; - - /* next parse rest of the headers, skip ones we don't understand */ - parse_errno = sippmh_parse_other_headers(refer_to_headers, tokens, - sipReferTo); - - if (parse_errno != 0) { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", - "Error while parsing other Refer-To header\n"); - } - sippmh_free_refer_to(sipReferTo); - return NULL; - } - - return (sipReferTo); -} - - - - - -/***************************************************************** - * - * Parser routine for Replaces header. Replaces header has - * call-id, to and from tags and signature scheme as parameters. - * The parser parses and stores call-id and tags in the Replaces - * structure and copies the signature scheme to be echoed back - * in the triggered INVITE for attended transfer. - * - * Input parameters : Replaces string to be parsed, - * boolean flag indicating whether the input - * string shall be duplicated or not. - * - * Returns : pointer to Replaces structure with parsed values - * if successful, NULL otherwise. - * - *****************************************************************/ -sipReplaces_t * -sippmh_parse_replaces (char *input_repl, boolean dup_flag) -{ - - char *repl_str, *this_tok, *tagVal, *sign, *callid; - sipReplaces_t *repcs = NULL; - char *lasts = NULL; - - repl_str = this_tok = tagVal = sign = NULL; - - if (input_repl == NULL) { - return NULL; - } - - - /* - * Replaces = "Replaces" ":" 1#replaces-values - * replaces-values = callid *( ";" replaces-param ) - * callid = token [ "@" token ] - * replaces-param = to-tag | from-tag | rep-signature - * | extension-param - * to-tag = "to-tag=" UUID - * from-tag = "from-tag=" UUID - * rep-signature = signature-scheme *( ";" sig-scheme-params) - * signature-scheme = "scheme" "=" token - * sig-scheme-params = token "=" ( token | quoted string ) - */ - - repcs = (sipReplaces_t *) cpr_calloc(1, sizeof(sipReplaces_t)); - if (repcs == NULL) { - return NULL; - } - - if (dup_flag) { - repl_str = cpr_strdup(input_repl); - if (!repl_str) { - cpr_free(repcs); - return NULL; - } - repcs->str_start = repl_str; - } else { - repl_str = input_repl; - } - - - /* if Replaces string has signature scheme parameter, - * make a copy of the input string for parsing entire signature - * parameter - */ - - if ((sign = strstr(repl_str, SIGNATURE_SCHEME)) != NULL) { - - /* - * if to or from tag follows signature params, remove - * them from this string - */ - char *sign_str, *tag_str; - - sign_str = tag_str = NULL; - - sign_str = cpr_strdup(sign); - if (sign_str == NULL) { - sippmh_free_replaces(repcs); - return NULL; - } - if ((tag_str = strstr(sign_str, ";to-tag")) || - (tag_str = strstr(sign_str, ";from-tag"))) { - *tag_str = '\0'; - } else { - /* terminate input string at signature param */ - *sign = '\0'; - } - (repcs->signature_scheme) = sign_str; - } - - - this_tok = PL_strtok_r(input_repl, ";", &lasts); - while (this_tok != NULL) { - if (strncasecmp(this_tok, TO_TAG, 6) == 0) { - if (repcs->toTag != NULL) { - sippmh_free_replaces(repcs); - return NULL; /* ERROR - more than 1 TO tag */ - } else { - tagVal = strchr(this_tok, '='); - if (tagVal) { - tagVal++; - SKIP_LWS(tagVal); - repcs->toTag = tagVal; - } else { - sippmh_free_replaces(repcs); - return NULL; /* ERROR */ - } - } - } else if (strncasecmp(this_tok, FROM_TAG, 8) == 0) { - if (repcs->fromTag != NULL) { - sippmh_free_replaces(repcs); - return NULL; /* ERROR - more than 1 FROM tag */ - } else { - tagVal = strchr(this_tok, '='); - if (tagVal) { - tagVal++; - SKIP_LWS(tagVal); - repcs->fromTag = tagVal; - } else { - sippmh_free_replaces(repcs); - return NULL; /* ERROR */ - } - } - } else if (strncasecmp(this_tok, SIP_HEADER_REPLACES, - sizeof(SIP_HEADER_REPLACES) - 1) == 0) { - /* only other allowable field should be callid */ - callid = strchr(this_tok, '='); - if (callid) { - char *sp_token; - - callid++; - SKIP_LWS(callid); - repcs->callid = callid; - /* remove trailing spaces */ - sp_token = strchr(repcs->callid, ' '); - if (sp_token == NULL) { - sp_token = strchr(repcs->callid, '\t'); - } - if (sp_token) { - *sp_token = 0; - } - } else { - sippmh_free_replaces(repcs); - return NULL; /* ERROR */ - } - } else { - sippmh_free_replaces(repcs); - return NULL; - } - this_tok = PL_strtok_r(NULL, ";", &lasts); - } - /* check for errors */ - if ((repcs->callid == NULL) || - (repcs->toTag == NULL) || - (repcs->fromTag == NULL)) { - sippmh_free_replaces(repcs); - return NULL; - } - - return repcs; /* SUCCESS */ -} - - -/* - * Converts a hex character (0-9, a-f, or A-F) into its integer - * equivalent value. - * ex.) '9' --> 9 - * 'a' --> 10 - * 'F' --> 15 - */ -static int -sippmh_htoi (const char inputChar) -{ - char inputValue[2]; - long strtol_result; - char *strtol_end; - - inputValue[0] = inputChar; - inputValue[1] = '\0'; - - errno = 0; - strtol_result = strtol(inputValue, &strtol_end, 16); - - if (errno || inputValue == strtol_end) { - return 0; - } else { - return (int) strtol_result; - } -} - -/* - * This function(similar to memchr()) works with both strings and array of characters. - * Returns the pointer to the matched character, if any; NULL otherwise. To include memchr.c - * in the phone library takes 1K of extra size and hence wrote this. - */ -static void * -char_lookup (const void *src, unsigned char c, int n) -{ - const unsigned char *mem = (unsigned char *) src; - - while (n--) { - if (*mem == c) { - return ((void *) mem); - } - mem++; - } - - return NULL; -} - - -/* List of characters that can exist in user part of URL/URI without escaping */ -#define userUnResCharListSize 17 -static char userUnResCharList[userUnResCharListSize] = -{ - SEMI_COLON, EQUAL_SIGN, TILDA, STAR, UNDERSCORE, PLUS, - SINGLE_QUOTE, LEFT_PARENTHESIS, RIGHT_PARENTHESIS, DOLLAR_SIGN, - FORWARD_SLASH, DOT, DASH, EXCLAMATION, AMPERSAND, COMMA, QUESTION_MARK -}; - - -/* - * This utility function converts selected characters in a string to escaped characters, - * per RFC2396. Escape format = %hexhex (hexhex - hex value of ASCII character) - * ex. 'abc@123' gets converted to "abc%40123" if '@' exists in escapable character list - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * excludeCharTbl = lookup table/string of characters that need not be escaped - * excludeCharTblSize = number of characters in the table/string that need not be escaped - * null_terminate = TRUE if '\0' is required to be added at end - * FALSE if not required. - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * outputStrSize = the size limit of the outputStr buffer - * - * returns the new size of the output string - * Converted string is stored in outputStr - * (contents = converted str) - */ -static size_t -sippmh_escapeChars_util (const char *inputStr, size_t inputStrLen, - char *excludeCharTbl, size_t excludeCharTblSize, - char *outputStr, size_t outputStrSize, - boolean null_terminate) -{ - size_t char_cnt = 0; - char *nextOutputChar; - int additional_byte = null_terminate ? 1 : 0; - size_t copy_count = 0; - - nextOutputChar = outputStr; - - while (char_cnt++ < inputStrLen) { - /* Check for characters that doesn't need to be escaped */ - if (((*inputStr) >= 'A' && (*inputStr) <= 'Z') || - ((*inputStr) >= 'a' && (*inputStr) <= 'z') || - ((*inputStr) >= '0' && (*inputStr) <= '9') || - (char_lookup(excludeCharTbl, (unsigned char) *inputStr, - excludeCharTblSize) != NULL)) { - if (outputStrSize < (copy_count + 1 + additional_byte)) { - break; - } - *nextOutputChar++ = *inputStr++; - copy_count++; - } else { // Characters that need escaping - if (outputStrSize < (copy_count + 3 + additional_byte)) { - break; - } - /* Copy %hh to output string */ - sprintf(nextOutputChar, "%c%x", '%', *inputStr++); - nextOutputChar = nextOutputChar + 3; - copy_count += 3; - } - - } - - if (null_terminate) { - copy_count++; - *nextOutputChar = '\0'; - } - return (copy_count); -} - -/* - * This function converts selected characters in a string to escaped characters, - * per RFC2396. Escape format = %hexhex (hexhex - hex value of ASCII character) - * ex. 'abc@123' gets converted to "abc%40123" if '@' exists in escapable character list - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * outputStrSize = the size limit of the outputStr buffer - * null_terminate = TRUE if '\0' is required to be added at end - * FALSE if not required. - * returns the new size of the output string - * - * Converted string is stored in outputStr - * (contents = converted str) - */ -size_t -sippmh_convertURLCharToEscChar (const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate) -{ - return (sippmh_escapeChars_util(inputStr, inputStrLen, - userUnResCharList, userUnResCharListSize, - outputStr, outputStrSize, null_terminate)); -} -/* - * This function converts any '\' or '"' character in a quoted string to escaped characters, - * per RFC3261. Escape format = %hexhex (hexhex - hex value of ASCII character) - * ex. 'abc\\' gets converted to "abc%5c%5c" if '\' exists in escapable character list - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * outputStrSize = the size limit of the outputStr buffer - * null_terminate = TRUE if '\0' is required to be added at end - * FALSE if not required. - * returns the new size of the output string - * - * Converted string is stored in outputStr - * (contents = converted str) - */ -size_t -sippmh_converQuotedStrToEscStr(const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate) -{ - size_t char_cnt = 0; - char *nextOutputChar; - int additional_byte = null_terminate ? 1 : 0; - size_t copy_count = 0; - - nextOutputChar = outputStr; - - while (char_cnt++ < inputStrLen) { - /* Check for characters that need to be escaped */ - if( ((*inputStr) == ESCAPE_CHAR) || ((*inputStr) == DOUBLE_QUOTE)) - { - // Characters that need escaping - if (outputStrSize < (copy_count + 3 + additional_byte)) { - break; - } - /* Copy %hh to output string */ - sprintf(nextOutputChar, "%c%02x", '%', *inputStr++); - nextOutputChar = nextOutputChar + 3; - copy_count += 3; - } - else { - if (outputStrSize < (copy_count + 1 + additional_byte)) { - break; - } - *nextOutputChar++ = *inputStr++; - copy_count++; - } - - } - - if (null_terminate) { - copy_count++; - *nextOutputChar = '\0'; - } - - return (copy_count); -} - -/* - * This function converts all Escaped characters in a string - * to their non-escaped format according to RFC2396. - * Escape format = %hh (%) - * ex. 'abc%40123' gets converted to "abc@123" - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * - * Converted string is stored in outputStr - * (contents = converted str) - * (contents = '\0' if no input string) - */ -void -sippmh_convertEscCharToChar (const char *inputStr, size_t inputStrLen, - char *outputStr) -{ - size_t char_cnt = 0; - char *nextOutputChar; - int value; - boolean esc_char_found = FALSE; - - *outputStr = '\0'; - nextOutputChar = outputStr; - - while (char_cnt < inputStrLen) { - if (*inputStr == PERCENT) { - /* Skip ESC syntax */ - inputStr++; - char_cnt++; - esc_char_found = TRUE; - } - - /* Copy character to output str */ - if (esc_char_found) { - - /* Convert 1st and 2nd hex chars to int */ - value = sippmh_htoi(*inputStr) * 16; - inputStr++; - char_cnt++; - value += sippmh_htoi(*inputStr); - sprintf(nextOutputChar, "%c", toascii(value)); - - inputStr++; - char_cnt++; - esc_char_found = FALSE; - - } else { - *nextOutputChar = *inputStr; - inputStr++; - char_cnt++; - } - - nextOutputChar++; - } - - *nextOutputChar = '\0'; -} - - -void -sippmh_free_replaces (sipReplaces_t *repl) -{ - - if (repl == NULL) { - return; - } - if (repl->str_start) { - cpr_free(repl->str_start); - } - if (repl->signature_scheme) { - cpr_free(repl->signature_scheme); - } - cpr_free(repl); -} - - -void -sippmh_free_refer_to (sipReferTo_t *ref_to) -{ - - if (ref_to == NULL) { - return; - } - if (ref_to->ref_to_start) { - cpr_free(ref_to->ref_to_start); - } - if (ref_to->sip_replaces_hdr) { - cpr_free(ref_to->sip_replaces_hdr); - } - if (ref_to->sip_acc_cont) { - cpr_free(ref_to->sip_acc_cont); - } - if (ref_to->sip_proxy_auth) { - cpr_free(ref_to->sip_proxy_auth); - } - if (ref_to->targetUrl) { - sippmh_genurl_free(ref_to->targetUrl); - } - cpr_free(ref_to); - -} - - -static void -sippmh_free_remote_party_id (sipRemotePartyId_t *remote_party_id) -{ - if (remote_party_id) { - if (remote_party_id->loc) { - sippmh_free_location(remote_party_id->loc); - } - cpr_free(remote_party_id); - } -} - - -void -sippmh_free_remote_party_id_info (sipRemotePartyIdInfo_t *rpid_info) -{ - uint32_t i; - - if (rpid_info) { - if (rpid_info->num_rpid > 0) { - for (i = 0; i < rpid_info->num_rpid; i++) { - sippmh_free_remote_party_id(rpid_info->rpid[i]); - rpid_info->rpid[i] = NULL; - } - } - cpr_free(rpid_info); - } -} - -void -sippmh_free_diversion_info (sipDiversionInfo_t *div_info) -{ - if (div_info) { - if (div_info->orig_called_name) { - strlib_free(div_info->orig_called_name); - } - if (div_info->orig_called_number) { - strlib_free(div_info->orig_called_number); - } - if (div_info->last_redirect_name) { - strlib_free(div_info->last_redirect_name); - } - if (div_info->last_redirect_number) { - strlib_free(div_info->last_redirect_number); - } - cpr_free(div_info); - } - -} - -static boolean -sippmh_parse_remote_party_id_params (char *params, - sipRemotePartyId_t *remote_party_id) -{ - boolean params_good; - int param_len; - char *param_name; - - if ((params == NULL) || (remote_party_id == NULL)) { - return FALSE; - } - - while (1) { - params_good = FALSE; - - while (*params == ';') { - params++; - } - - param_name = params; - SKIP_SIP_TOKEN(params); - param_len = params - param_name; - if (param_len == 0) { - return FALSE; - } - - /* Parse screen parameter */ - /* If there are multiple screen parameters, "no" takes precedence */ - if ((param_len == RPID_SCREEN_LEN) && - (strncasecmp(param_name, RPID_SCREEN, RPID_SCREEN_LEN) == 0) && - (!remote_party_id->screen || - cpr_strcasecmp(remote_party_id->screen, "no"))) { - params = parse_generic_param(params, &remote_party_id->screen); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse party-type parameter */ - } else if ((param_len == RPID_PARTY_TYPE_LEN) && - (strncasecmp(param_name, RPID_PARTY_TYPE, - RPID_PARTY_TYPE_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->party_type); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse id-type parameter */ - } else if ((param_len == RPID_ID_TYPE_LEN) && - (strncasecmp(param_name, RPID_ID_TYPE, - RPID_ID_TYPE_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->id_type); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse privacy parameter */ - } else if ((param_len == RPID_PRIVACY_LEN) && - (strncasecmp(param_name, RPID_PRIVACY, - RPID_PRIVACY_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->privacy); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse np parameter */ - } else if ((param_len == RPID_NP_LEN) && - (strncasecmp(param_name, RPID_NP, RPID_NP_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->np); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - } - - SKIP_LWS(params); - if (*params == SEMI_COLON) { - /* More parameters follow */ - *params++ = '\0'; - SKIP_LWS(params); - } else { - break; - } - } - - return params_good; -} - -sipRemotePartyId_t * -sippmh_parse_remote_party_id (const char *input_remote_party_id) -{ - /* static const char fname[] = "sippmh_parse_remote_party_id"; */ - char *more_ptr; - sipRemotePartyId_t *remote_party_id; - char *remote_party_id_str; - - /* - * Remote-Party-ID = "Remote-Party-ID" ":" [display-name] - * "<" addr-spec ">" *(";" rpi-token) - * rpi-token = rpi-screen | rpi-pty-type | - * rpi-id-type | rpi-privacy | rpi-np | - * other-rpi-token - * rpi-screen = "screen" "=" ("no" | "yes") - * rpi-pty-type = "party" "=" ("calling" | "called" | token) - * rpi-id-type = "id-type" "=" ("subscriber" | "user" | "alias" | - * "return" | "term" | token) - * rpi-privacy = "privacy" = 1#( - * ("full" | "name" | "uri" | "off" | token) - * ["-" ("network" | token) ] ) - * rpi-np = "np" "=" ("ordinary" | "residential" | "business" | - * "priority" | "hotel" | "failure" | "hospital" | - * "prison" | "police" | "test" | "payphone" | - * "coin" | "payphone-public" | "payphone-private" | - * "coinless" | "restrict" | "coin-restrict" | - * "coinless-restrict" | "reserved" | "operator" | - * "trans-freephone" | "isdn-res" | "isdn-bus" | - * "unknown" | "emergency" | token ) - * other-rpi-token = ["-"] token ["=" (token | quoted-string)] - */ - - remote_party_id = (sipRemotePartyId_t *) - cpr_calloc(1, sizeof(sipRemotePartyId_t)); - if (remote_party_id == NULL) { - return NULL; - } - - /* Duplicate the string and work with it - - * This duplicate string is stored in the location structure - * pointed to by remote_party_id->loc and freed when the that - * structure is freed. Note that this pointer is *not* dup'ed - * in the parse_nameaddr_or_addrspec structure - */ - remote_party_id_str = cpr_strdup(input_remote_party_id); - - if (remote_party_id_str == NULL) { - sippmh_free_remote_party_id(remote_party_id); - remote_party_id = NULL; - more_ptr = NULL; - } else { - remote_party_id->loc = - sippmh_parse_nameaddr_or_addrspec(remote_party_id_str, - remote_party_id_str, FALSE, - FALSE, &more_ptr); - - if (remote_party_id->loc == NULL) { - cpr_free(remote_party_id_str); - sippmh_free_remote_party_id(remote_party_id); - remote_party_id = NULL; - more_ptr = NULL; - } - } - - if (more_ptr == NULL || *more_ptr == 0) { - /* No params. Use defaults of: - * party=calling, screen=no, id-type=subscriber, - * privacy=off, np=0 (ordinary) - */ - } else { - (void) sippmh_parse_remote_party_id_params(more_ptr, remote_party_id); - } - - return remote_party_id; -} - - -char * -sippmh_generate_authorization (sip_author_t *sip_author) -{ - char *buffer; - - /* - * This routine takes a sip_author_t struct and generates an Authorization - * header or a Proxy-Authorization header. Since this routine generates - * a header for Authorization or Proxy-Authorization, the header will - * start with "Digest" or "Basic". The user should use sstrncat to - * add "Proxy Authorization: " or "Authorization: " depending which is - * needed. - */ - if (!sip_author) { - return NULL; - } - buffer = (char *) cpr_malloc(MAX_SIP_HEADER_LENGTH); - if (!buffer) { - return NULL; - } - - if (sip_author->scheme == SIP_DIGEST) { - snprintf(buffer, MAX_SIP_HEADER_LENGTH, - "%s %s=\"%s\",%s=\"%s\",%s=\"%s\",%s=\"%s\",%s=\"%s\"", - AUTHENTICATION_DIGEST, - AUTHENTICATION_USERNAME, sip_author->d_username, - AUTHENTICATION_REALM, sip_author->realm, - AUTHENTICATION_URI, sip_author->unparsed_uri, - AUTHENTICATION_RESPONSE, sip_author->response, - AUTHENTICATION_NONCE, sip_author->nonce); - - /* - * The header must have username, realm, uri, response, and nonce. - * All other parameters are optional, so check if they exist and - * add them on to the buffer if they do. - */ - - if (sip_author->opaque) { - char *buffer2; - - buffer2 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer2) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer2, MAX_URI_LENGTH, ",%s=\"%s\"", - AUTHENTICATION_OPAQUE, sip_author->opaque); - sstrncat(buffer, buffer2, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer2); - } - if (sip_author->cnonce) { - char *buffer3; - - buffer3 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer3) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer3, MAX_URI_LENGTH, - ",cnonce=\"%s\"", sip_author->cnonce); - sstrncat(buffer, buffer3, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer3); - } - if (sip_author->qop) { - char *buffer4; - - buffer4 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer4) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer4, MAX_URI_LENGTH, ",qop=%s", sip_author->qop); - sstrncat(buffer, buffer4, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer4); - } - if (sip_author->nc_count) { - char *buffer5; - - buffer5 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer5) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer5, MAX_URI_LENGTH, ",nc=%s", sip_author->nc_count); - sstrncat(buffer, buffer5, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer5); - } - if (sip_author->algorithm) { - char *buffer6; - - buffer6 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer6) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer6, MAX_URI_LENGTH, - ",%s=%s", AUTHENTICATION_ALGORITHM, sip_author->algorithm); - sstrncat(buffer, buffer6, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer6); - } - } else { - sprintf(buffer, "%s %s", AUTHENTICATION_BASIC, sip_author->user_pass); - } - return buffer; -} - -void -sippmh_free_authen (sip_authen_t *sip_authen) -{ - if (sip_authen) { - cpr_free(sip_authen->str_start); - cpr_free(sip_authen); - } -} - -static boolean -sippmh_validate_authenticate (sip_authen_t *sip_authen) -{ - if (sip_authen) { - if ((sip_authen->realm != NULL) && (sip_authen->nonce != NULL)) { - return TRUE; - } else { - return FALSE; - } - } - return FALSE; -} - -/* routine used to parse WWW-Authenticate and Proxy-Authenticate headers */ - -sip_authen_t * -sippmh_parse_authenticate (const char *input_char) -{ - sip_authen_t *sip_authen; - char *input; - boolean good_params; - boolean qop_found = FALSE; - char *trash; - -/* - * Basic: - * "WWW-Authenticate" ":" 1#challenge - * challenge = "Basic" realm - ******************************************************* - * Digest: - * "Digest" digest-challenge - * digest-challenge = 1#( realm | [ domain ] | nonce | - * [ opaque ] |[ stale ] | [ algorithm ] | - * [ qop-options ] | [auth-param] ) - * - * domain = "domain" "=" <"> URI ( 1*SP URI ) <"> - * URI = absoluteURI | abs_path - * opaque = "opaque" "=" quoted-string - * stale = "stale" "=" ( "true" | "false" ) - * algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" | - * token ) - * qop-options = "qop" "=" <"> 1#qop-value <"> - * qop-value = "auth" | "auth-int" | token - */ - - if (!input_char) { - return NULL; - } - - input = cpr_strdup(input_char); - if (!input) { - return NULL; - } - - sip_authen = (sip_authen_t *) cpr_calloc(1, sizeof(sip_authen_t)); - if (!sip_authen) { - cpr_free(input); - return NULL; - } - - sip_authen->str_start = input; - SKIP_WHITE_SPACE(input); - - /* now pointing at Basic, pgp or Digest */ - - if (strncasecmp(input, AUTHENTICATION_BASIC, 5) == 0) { - sip_authen->scheme = SIP_BASIC; - input += 5; - *input = 0; - input++; - SKIP_WHITE_SPACE(input); - if (strncasecmp(input, AUTHENTICATION_REALM, 5) == 0) { - input += 5; - SKIP_WHITE_SPACE(input); - if (*input == '=') { - input++; - } else { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s", - get_debug_string(DEBUG_PMH_INCORRECT_SYNTAX)); - } - return NULL; - } - SKIP_WHITE_SPACE(input); - sip_authen->realm = input; - return sip_authen; - } - sip_authen->user_pass = input; /* encoded base 64 */ - return sip_authen; - - } else if (strncasecmp(input, AUTHENTICATION_DIGEST, 6) == 0) { - sip_authen->scheme = SIP_DIGEST; - input += 6; - *input = 0; - input++; - SKIP_WHITE_SPACE(input); - } else { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s", - get_debug_string(DEBUG_PMH_INVALID_SCHEME)); - } - return NULL; - } - - /* pointing at Digest-challenge */ - - /* if algorithm is not in string set it to md5 */ - - sip_authen->algorithm = "md5"; - - /* loop through string until all fields have been handled */ - - while (input) { - char **ptr = NULL; - - if (strncasecmp(input, AUTHENTICATION_DOMAIN, 6) == 0) { - input += 6; - ptr = &(sip_authen->unparsed_domain); - } else if (strncasecmp(input, AUTHENTICATION_ALGORITHM, 9) == 0) { - input += 9; - ptr = &(sip_authen->algorithm); - } else if (strncasecmp(input, AUTHENTICATION_OPAQUE, 6) == 0) { - input += 6; - ptr = &(sip_authen->opaque); - } else if (strncasecmp(input, "stale", 5) == 0) { - input += 5; - ptr = &(sip_authen->stale); - } else if (strncasecmp(input, AUTHENTICATION_REALM, 5) == 0) { - input += 5; - ptr = &(sip_authen->realm); - } else if (strncasecmp(input, AUTHENTICATION_NONCE, 5) == 0) { - input += 5; - ptr = &(sip_authen->nonce); - } else if (strncasecmp(input, "qop", 3) == 0) { - input += 3; - ptr = &(sip_authen->qop); - qop_found = TRUE; - } else { - /* - * Ignore unrecognized parameters. - */ - ptr = &trash; - input = strchr(input, EQUAL_SIGN); - if (input == NULL) { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s", - get_debug_string(DEBUG_PMH_INVALID_FIELD_VALUE)); - } - return NULL; - } - } - SKIP_WHITE_SPACE(input); - if (*input != EQUAL_SIGN) { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s", - get_debug_string(DEBUG_PMH_INCORRECT_SYNTAX)); - } - return NULL; - } - input++; /* skip the equal sign */ - SKIP_WHITE_SPACE(input); - /* input is now pointing at the value of the parameter */ - *ptr = input; - if (*input == DOUBLE_QUOTE) { - input++; - *ptr = input; /*sam do not want the quotes in the string */ - input = strchr(input, DOUBLE_QUOTE); - if (input == NULL) { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s", - get_debug_string(DEBUG_PMH_INCORRECT_SYNTAX)); - } - return NULL; - } else { - *input++ = '\0'; /*sam string needs to be null terminated */ - } - /* - * Check the qop. If qop is included it has to be either - * auth, auth-int or both. If both are included then we will - * just drop the second one. - */ - if (qop_found == TRUE) { - char *qop_input = NULL; - - if (sip_authen->qop) { - qop_input = strchr(sip_authen->qop, COMMA); - } - if (qop_input != NULL) { - *qop_input = '\0'; - } - - /* - * Make sure that the qop is either auth or auth-int - */ - if ((strncasecmp(sip_authen->qop, "auth", 4) != 0) && - (strncasecmp(sip_authen->qop, "auth-int", 8) != 0)) { - sip_authen->qop = NULL; - } - } - } - - input = strchr(input, COMMA); - if (!input) { - good_params = sippmh_validate_authenticate(sip_authen); - if (good_params) { - return sip_authen; - } else { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s", - get_debug_string(DEBUG_PMH_NOT_ENOUGH_PARAMETERS)); - } - return NULL; - } - } - *input++ = 0; - SKIP_WHITE_SPACE(input); - } - - sippmh_free_authen(sip_authen); - return NULL; -} - -/* - * Function: sippmh_parse_displaystr - * - * Parameters: Display string to be parsed - * - * Description:Removes leading '); - if (temp) { - *temp = 0; - } - displaystr = strlib_update(displaystr, temp_ptr); - return (displaystr); -} - -/* - * Function: sippmh_process_via_header - * - * Parameters: Received Sip Message - * IP Address the Message was received from - * - * Description: Appends received= to the first Via - * field if the ip address we received this message - * from is not the same as the ip address in the via - * field or if it contains a domain name - * - * Returns: None - * - */ -void -sippmh_process_via_header (sipMessage_t *sip_message, - cpr_ip_addr_t *source_ip_address) -{ - char dotted_ip[MAX_IPADDR_STR_LEN]; - char *hdr_start; - char *new_buf; - int new_buf_len; - char *offset; - long old_header_offset; - sipVia_t *via; - cpr_ip_addr_t tmp_ip_addr; - - CPR_IP_ADDR_INIT(tmp_ip_addr); - - if (sip_message && sippmh_is_request(sip_message)) { - via = sippmh_parse_via(sip_message->hdr_cache[VIA].val_start); - if (via == NULL) { - /* error message already displayed in parse function */ - /* mark the message as being incomplete so a 400 will get sent */ - sip_message->is_complete = 0; - return; - } - - util_ntohl(&tmp_ip_addr, source_ip_address); - ipaddr2dotted(dotted_ip, &tmp_ip_addr); - if (strcmp(via->host, dotted_ip) && (via->recd_host == NULL)) { - hdr_start = sip_message->hdr_cache[VIA].hdr_start; - - /* - * +3 accounts for the ; and the = before and after the received - * and the terminating NULL - */ - new_buf_len = strlen(hdr_start) + sizeof(VIA_RECEIVED) + strlen(dotted_ip) + 3; - new_buf = (char *) cpr_malloc(new_buf_len); - /* - * If we cannot allocate memory, we will just leave - * the VIA alone and hope things work out for the best - */ - if (new_buf != NULL) { - offset = strchr(hdr_start, ','); - old_header_offset = sip_message->hdr_cache[VIA].val_start - - hdr_start; - sip_message->hdr_cache[VIA].hdr_start = new_buf; - sip_message->hdr_cache[VIA].val_start = new_buf + - old_header_offset; - - if (offset) { - snprintf(new_buf, new_buf_len, "%.*s;%s=%s%s", (int) (offset - hdr_start), hdr_start, VIA_RECEIVED, dotted_ip, offset); - } else { - snprintf(new_buf, new_buf_len, "%s;%s=%s", hdr_start, VIA_RECEIVED, dotted_ip); - } - - cpr_free(hdr_start); - } - } - sippmh_free_via(via); - } -} - - -/* - * Function: sippmh_parse_user - * - * Parameters: user portion of URL to parse - * - * Description: This function will remove any parameters - * which appear in the user portion of the url. - * (i.e. 15726;oct3=128@10.10.10.10 will return 15726) - * The SIP Phone does not care about the extra parameters and - * they need to be removed so that the user portion will - * match the phone provisioning and display correctly. - * - * Returns: A Copy of the input string with the parameters removed - * if things go well. NULL if we encounter an error. - */ -char * -sippmh_parse_user (char *url_main) -{ - char *user = NULL; - size_t size = 0; - char *lasts = NULL; - - if (url_main == NULL) { - return (NULL); - } - - /* - * If the first char is ';', give up. That - * breaks our assumption. - */ - if (*url_main == SEMI_COLON) { - return (NULL); - } - - /* - * Create a new string and copy the url_main - * string into it. (We can't change the original - * string because it may be needed for creating - * SIP response messages.) - */ - size = strlen(url_main) + 1; - user = (char *) cpr_malloc(size); - /* - * If the malloc fails, return the original URL. - */ - if (user == NULL) { - return (NULL); - } - - sstrncpy(user, url_main, size); - - /* - * Search for ";" and null terminate the string there. - * An assumption has been made that any parameters will come - * after the number. i.e.: "15726;param=paramval" - */ - (void) PL_strtok_r(user, ";", &lasts); - return (user); -} - -/* - * Function: sippmh_parse_message_summary - * - * Parameters: The incoming SIP message and a container to be - * filled with the parsed message body. - * - * Description: This function will parse the incoming MWI NTFY SIP message - * and fill the passed in structure with the - * contents of the parsed message.Basic Error checking is done on - * the passed in message. - * - * Returns: SIP_ERROR on error.SIP_OK otherwise. - */ -int32_t -sippmh_parse_message_summary(sipMessage_t *pSipMessage, sipMessageSummary_t *mesgSummary) -{ - int i = 0; - int j = 0; - char *p = NULL; - char *val = NULL; - char temp[MAX_SIP_URL_LENGTH]; - boolean token_found = FALSE; - boolean hp_found = FALSE; - long strtol_result; - char *strtol_end; - - p = strstr(pSipMessage->mesg_body[0].msgBody, "Messages-Waiting"); - - if (!p) { - p = strstr(pSipMessage->mesg_body[0].msgBody, "Message-Waiting"); - } - - if (p) { - memset(temp, '\0', MAX_SIP_URL_LENGTH); - - trim_right(p); - - val = strstr(p, ":"); - if (val) { - val++; - - i = j = 0; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r') { - // return error if obviously wrong - if (!isalpha(val[j])) { - return SIP_ERROR; - } - temp[i] = val[j]; - j++; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - temp[i] = '\0'; - } else { - return SIP_ERROR; - } - } else { - return SIP_ERROR; - } - - if (cpr_strcasecmp(temp, "no") == 0) { - mesgSummary->mesg_waiting_on = FALSE; - } else if (cpr_strcasecmp(temp, "yes") == 0) { - mesgSummary->mesg_waiting_on = TRUE; - } else { - return SIP_ERROR; - } - -/* - p = strstr(pSipMessage->mesg_body[0].msgBody, "Message-Account"); - - if (p) { - trim_right(p); - - val = strstr(p, ":"); - if (val) { - val++; - - i = j = 0; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r') { - mesgSummary->message_account[i] = val[j]; - j++; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - mesgSummary->message_account[i] = '\0'; - } else { - return SIP_ERROR; - } - } -*/ - - p = strstr(pSipMessage->mesg_body[0].msgBody, "Voice-Message"); - - if (p) { - mesgSummary->type = mwiVoiceType; - memset(temp, '\0', MAX_SIP_URL_LENGTH); - trim_right(p); - i = j = 0; - val = strstr(p, ":"); - if (val) { - val++; - - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r' && !isspace(val[j]) && val[j] != '(') { - if (!isdigit(val[j])) { - if (val[j] == '/') { - temp[i] = '\0'; - - errno = 0; - strtol_result = strtol(temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->newCount = (int) strtol_result; - token_found = TRUE; - i = 0; - } else { - return SIP_ERROR; - } - } else { - temp[i] = val[j]; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - j++; - } - temp[i] = '\0'; - - if (token_found) { - errno = 0; - strtol_result = (temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->oldCount = (int) strtol_result; - } - - temp[i = 0] = '\0'; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - if (val[j] == '(') { - j++; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r' && !isspace(val[j]) && val[j] != ')') { - if (!isdigit(val[j])) { - if (val[j] == '/') { - temp[i] = '\0'; - - errno = 0; - strtol_result = strtol(temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->hpNewCount = (int) strtol_result; - hp_found = TRUE; - i = 0; - } else { - return SIP_ERROR; - } - } else { - temp[i] = val[j]; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - j++; - } - temp[i] = '\0'; - if (hp_found) { - errno = 0; - strtol_result = strtol(temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->hpOldCount = (int) strtol_result; - } - } - if (!hp_found) { - mesgSummary->hpNewCount = mesgSummary->hpOldCount = -1; - } - /*make sure the urgent message counts don't exceed the total message counts*/ - if ((mesgSummary->hpNewCount > mesgSummary->newCount) || - (mesgSummary->hpOldCount > mesgSummary->oldCount)) { - return SIP_ERROR; - } - if (!token_found) { - return SIP_ERROR; - } - } else { - return SIP_ERROR; - } - } - - return SIP_OK; -} -/* - * This function compares two strings that may contain escaped characters - * in either of them and determines if they are equivalent, ignoring the - * case if ignore_case is TRUE. - * s1 = ptr to the first string of chars - * s2 = ptr to the second string of chars - * return: integer value of 0 if they are equivalent, <> 0 otherwise. - */ -int -sippmh_cmpURLStrings (const char *s1, const char *s2, boolean ignore_case) -{ - const unsigned char *us1 = (const unsigned char *) s1; - const unsigned char *us2 = (const unsigned char *) s2; - int value1, value2; - int esc_char_incr_in_s1 = 0; // # of chars to skip in s1 if the given char is escaped - int esc_char_incr_in_s2 = 0; // # of chars to skip in s2 if the given char is escaped - - if ((!s1 && s2) || (s1 && !s2)) /* no match if only one ptr is NULL */ - return (int) (s1 - s2); /* if one of these is NULL it will be the - * lesser of the two values and therefore - * we'll get the proper sign in the int */ - - if (s1 == s2) { /* match if both ptrs the same (e.g. NULL) */ - return 0; - } - - value1 = 0; - value2 = 0; - while (*us1 != '\0') { - if (*us1 == PERCENT) { - esc_char_incr_in_s1 = 2; - - /* Convert 1st and 2nd hex chars to int */ - value1 = sippmh_htoi(*(us1 + 1)) * 16; - value1 += sippmh_htoi(*(us1 + 2)); - } else { - value1 = *us1; - } - - if (*us2 == PERCENT) { - esc_char_incr_in_s2 = 2; - - /* Convert 1st and 2nd hex chars to int */ - value2 = sippmh_htoi(*(us2 + 1)) * 16; - value2 += sippmh_htoi(*(us2 + 2)); - } else { - value2 = *us2; - } - - if ((ignore_case && (toupper(value1) == toupper(value2))) || - (!ignore_case && (value1 == value2))) { - us1 += (1 + esc_char_incr_in_s1); - us2 += (1 + esc_char_incr_in_s2); - esc_char_incr_in_s1 = 0; - esc_char_incr_in_s2 = 0; - } else { - break; - } - } - - if (ignore_case) { - return (toupper(value1) - toupper(value2)); - } else { - return (value1 - value2); - } -} - -int -sippmh_add_call_info (sipMessage_t *sip_message_p, cc_call_info_t *call_info_p) -{ - if (sip_message_p && call_info_p) { - char *call_info_hdr_p = ccsip_encode_call_info_hdr(call_info_p, NULL); - - if (call_info_hdr_p != NULL) { - (void) sippmh_add_text_header(sip_message_p, SIP_HEADER_CALL_INFO, - (const char *) call_info_hdr_p); - cpr_free(call_info_hdr_p); - } - } - return (0); -} - -/* - * Function: sippmh_parse_supported_require - * - * Parameters: contents of the Supported or Require header - * - * punsupported_tokens: if the caller wants to know the - * unsupported option tokens, it will pass a non-null pointer. - * If punsupporte_tokens is NULL, then the caller does not - * want to know the unsupported options. - * - * It is caller's responsibility to free the contents of this - * pointer. - * - * Description: This function will parse for the various options tags - * in the supported and require headers - * - * Returns: A bit map containing the values in the header - * - * Format of the line is as follows: - * Supported: replaces, join, sec-agree, whatever ... - * Require: replaces, join, sec-agree, whatever ... - */ -uint32_t -sippmh_parse_supported_require (const char *header, char **punsupported_tokens) -{ - const char *fname = "sippmh_parse_supported_require"; - uint32_t tags = 0; - char *temp_header; - char *token; - const char *delim = ", \r\n\t"; - int unsupported_tokens_size = 0; - char *bad_token = NULL; - int size; - char *lasts = NULL; - - if (header == NULL) { - return (tags); - } - - if (punsupported_tokens != NULL) { - *punsupported_tokens = NULL; //assume everything will go right - } - - //need to keep own buffer since PL_strtok_r is destructive - size = strlen(header) + 1; - temp_header = (char *) cpr_malloc(size); - if (temp_header == NULL) { - CCSIP_DEBUG_ERROR("%s: malloc failed for strlen(header)=%zu", fname, - strlen(header)); - return tags; - } - sstrncpy(temp_header, header, size); - - token = PL_strtok_r(temp_header, delim, &lasts); - while (token != NULL) { - bad_token = NULL; - - if (strcmp(token, REQ_SUPP_PARAM_REPLACES) == 0) { - tags |= replaces_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_100REL) == 0) { - tags |= rel_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_EARLY_SESSION) == 0) { - tags |= early_session_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_JOIN) == 0) { - tags |= join_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_PATH) == 0) { - tags |= path_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_PRECONDITION) == 0) { - tags |= precondition_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_PREF) == 0) { - tags |= pref_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_PRIVACY) == 0) { - tags |= privacy_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_SEC_AGREE) == 0) { - tags |= sec_agree_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_TIMER) == 0) { - tags |= timer_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_NOREFERSUB) == 0) { - tags |= norefersub_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_CALLINFO) == 0) { - tags |= cisco_callinfo_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_SERVICE_CONTROL) == 0) { - tags |= cisco_service_control_tag; - - } else if (strcmp(token, REQ_SUPP_PARAM_SDP_ANAT) == 0) { - tags |= sdp_anat_tag; - } - else if (strcmp(token, REQ_SUPP_PARAM_EXTENED_REFER) == 0) { - tags |= extended_refer_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_SERVICEURI) == 0) { - tags |= cisco_serviceuri_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_ESCAPECODES) == 0) { - tags |= cisco_escapecodes_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_SRTP_FALLBACK) == 0) { - tags |= cisco_srtp_fallback_tag; - } - else { - //This is not necessarily an error. Other end may support something we - //don't. Is only an error if it shows up in Require. - tags |= (uint32_t) unrecognized_tag; - bad_token = token; - } - - if (bad_token != NULL) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Invalid tag in Require/Supported %s", - DEB_F_PREFIX_ARGS(SIP_TAG, fname), bad_token); - - //allocate memory for unsupported options if necessary - if (punsupported_tokens) { - if (!*punsupported_tokens) { - unsupported_tokens_size = strlen(header) + 1; - *punsupported_tokens = (char *) cpr_malloc(unsupported_tokens_size); - if (*punsupported_tokens) { - memset(*punsupported_tokens, 0, unsupported_tokens_size); - } - } - } - - //caller wants to know what came in Require and we dont support - if (punsupported_tokens && *punsupported_tokens) { - //include token into illegal_tokens - if (strlen(*punsupported_tokens) > 0) { - sstrncat(*punsupported_tokens, ",", unsupported_tokens_size - strlen(*punsupported_tokens)); //add a "," - } - sstrncat(*punsupported_tokens, bad_token, unsupported_tokens_size - strlen(*punsupported_tokens)); - } - bad_token = NULL; - } - - //get next token - token = PL_strtok_r(NULL, delim, &lasts); - } - cpr_free(temp_header); - return (tags); -} - -/* - * Function: sippmh_parse_allow_header - * - * Parameters: contents of the Allow header - * - * Description: This function will parse for the various methods - * supported in the allow header - * - * Returns: A bit map containing the values in the header - * - * Format of the line is as follows: - * Allow: ACK, BYE, CANCEL, .... - */ -uint16_t -sippmh_parse_allow_header (const char *header) -{ - uint16_t tags = 0; - - if (header == NULL) { - return (tags); - } - if (strstr(header, SIP_METHOD_ACK)) { - tags |= ALLOW_ACK; - } - if (strstr(header, SIP_METHOD_BYE)) { - tags |= ALLOW_BYE; - } - if (strstr(header, SIP_METHOD_CANCEL)) { - tags |= ALLOW_CANCEL; - } - if (strstr(header, SIP_METHOD_INFO)) { - tags |= ALLOW_INFO; - } - if (strstr(header, SIP_METHOD_INVITE)) { - tags |= ALLOW_INVITE; - } - if (strstr(header, SIP_METHOD_MESSAGE)) { - tags |= ALLOW_MESSAGE; - } - if (strstr(header, SIP_METHOD_NOTIFY)) { - tags |= ALLOW_NOTIFY; - } - if (strstr(header, SIP_METHOD_OPTIONS)) { - tags |= ALLOW_OPTIONS; - } - if (strstr(header, SIP_METHOD_PRACK)) { - tags |= ALLOW_PRACK; - } - if (strstr(header, SIP_METHOD_PUBLISH)) { - tags |= ALLOW_PUBLISH; - } - if (strstr(header, SIP_METHOD_REFER)) { - tags |= ALLOW_REFER; - } - if (strstr(header, SIP_METHOD_REGISTER)) { - tags |= ALLOW_REGISTER; - } - if (strstr(header, SIP_METHOD_SUBSCRIBE)) { - tags |= ALLOW_SUBSCRIBE; - } - if (strstr(header, SIP_METHOD_UPDATE)) { - tags |= ALLOW_UPDATE; - } - return (tags); -} - -/* - * Function: sippmh_parse_accept_header - * - * Parameters: contents of the Accept header - * - * Description: This function will parse for the various capabilities - * signalled in the Accept header - * - * Returns: A bit map containing the values in the header - * - * Format of the line is as follows: - * Accept: application/sdp, nultipart/mixed, multipart/alternative - */ -uint16_t -sippmh_parse_accept_header (const char *header) -{ - uint16_t tags = 0; - - if (header == NULL) { - return (tags); - } - if (strstr(header, SIP_CONTENT_TYPE_SDP)) { - tags |= (0x01 << SIP_CONTENT_TYPE_SDP_VALUE); - } - if (strstr(header, SIP_CONTENT_TYPE_MULTIPART_MIXED)) { - tags |= (0x01 << SIP_CONTENT_TYPE_MULTIPART_MIXED_VALUE); - } - if (strstr(header, SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE)) { - tags |= (0x01 << SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE_VALUE); - } - return tags; -} - -/* - * Function: ccsip_process_network_message - * - * Parameters: sipmsg, pointer to pointer of the buffer - * bytes used, display message. - * - * Description: Currently only used for tcp packets received to do the - * framing. Ported from Propel. - * Returns: A bit map containing the values in the header - */ -ccsipRet_e -ccsip_process_network_message (sipMessage_t **sipmsg_p, - char **buf, - unsigned long *nbytes_used, - char **display_msg) -{ - static const char fname[] = "ccsip_process_network_message"; - sipMessage_t *sip_msg = NULL; - int local_nbytes = *nbytes_used; - uint32_t bytes_used; - char *local_buf_ptr; - - sip_msg = sippmh_message_create(); - if (sip_msg == NULL) { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s: Error in creating SIP Msg", fname); - } - *sipmsg_p = NULL; - return SIP_MSG_CREATE_ERR; - } - - /* Init local variables */ - bytes_used = local_nbytes; - local_buf_ptr = *buf; - - if (sippmh_process_network_message(sip_msg, local_buf_ptr, &bytes_used) - == STATUS_FAILURE) { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s: process_network_message failed.", - fname); - } - sippmh_message_free(sip_msg); - *sipmsg_p = NULL; - return SIP_MSG_PARSE_ERR; - } - - if (sippmh_is_message_complete(sip_msg)) { - if (display_msg) { - *display_msg = (char *) cpr_malloc(bytes_used + 1); - if (*display_msg == NULL) { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", - "%s: malloc of display msg failed.\n", fname); - } - sippmh_message_free(sip_msg); - *sipmsg_p = NULL; - return SIP_MSG_PARSE_ERR; - } - sstrncpy(*display_msg, local_buf_ptr, bytes_used + 1); - } - local_nbytes -= bytes_used; - local_buf_ptr += bytes_used; - - /* Update information */ - *sipmsg_p = sip_msg; - *nbytes_used = local_nbytes; - *buf = local_buf_ptr; - - return SIP_SUCCESS; - } else { - CCSIP_ERR_DEBUG { - CSFLogDebug("sipstack", "%s: process_network_msg: not complete", - fname); - } - sippmh_message_free(sip_msg); - *sipmsg_p = NULL; - - return SIP_MSG_INCOMPLETE_ERR; - } -} - -/* - * Function: sippmh_parse_service_control_body - * - * Parameters: contents of the service control notify body and its length - * - * Description: This function will parse for the reset/restart - * instructions and parameters in this body - * - * Returns: 0 if body parsed correctly - * Parsed values are added to passed structure - * - * Format of the body is as follows: - * action = [reset | restart | check-version | call-preservation | apply-config ] - * RegisterCallId= {} - * ConfigVersionStamp = {79829A69-9489-4C8E-8143-90A9C22DFAD7} - * DialplanVersionStamp = {79829A69-9489-4C8E-8143-90A9C22DFAD7} - * SoftkeyVersionStamp = {79829A69-9489-4C8E-8143-90A9C22DFAD7} - * CUCMResult=[no_change | config_applied | reregister_needed] - * FirmwareLoadId = {SIP70.8-4-0-28S} - * LoadServer={10.81.15.24} - * LogServer={ } // This is used for ppid - * UpgradeTime=[now | later] - * PPID=[enabled | disabled] - */ - -sipServiceControl_t * -sippmh_parse_service_control_body (char *msgBody, int msgLength) -{ - pmhRstream_t *rs = NULL; - char *line = NULL, *value = NULL; - boolean body_read = FALSE; - sipServiceControl_t *scp = NULL; - - if (msgLength==0) { - return (NULL); - } - - if ((rs = pmhutils_rstream_create(msgBody, msgLength)) - == NULL) { - return (NULL); - } - - scp = (sipServiceControl_t *) - cpr_calloc(1, sizeof(sipServiceControl_t)); - if (!scp) { - cpr_free(rs); - return NULL; - } - - while (!body_read) { - line = pmhutils_rstream_read_line(rs); - if (line) { - value = strchr(line, '='); - if (value) { - value++; - while (*value == ' ') { - value++; - } - } - if (strlen(line) == 0) { - - } else if (!strncasecmp(line, "action", sizeof("action") - 1)) { - if (value == NULL) { - scp->action = SERVICE_CONTROL_ACTION_INVALID; - } else if (!strncasecmp(value, "reset", sizeof("reset") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_RESET; - } else if (!strncasecmp(value, "restart", - sizeof("restart") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_RESTART; - } else if (!strncasecmp(value, "check-version", - sizeof("check-version") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_CHECK_VERSION; - } else if (!strncasecmp(value, "call-preservation", - sizeof("call-preservation") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_CALL_PRESERVATION; - } else if (!strncasecmp(value, "apply-config", - sizeof("apply-config") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_APPLY_CONFIG; - - } else { - scp->action = SERVICE_CONTROL_ACTION_INVALID; - } - } else if (!strncasecmp(line, "RegisterCallId", - sizeof("RegisterCallId") - 1)) { - if (scp->registerCallID == NULL) { - if (value == NULL) { - scp->registerCallID = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->registerCallID = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->registerCallID) - memcpy(scp->registerCallID, value + 1, - (len - 2)); - } - } - } - - } else if (!strncasecmp(line, "ConfigVersionStamp", - sizeof("ConfigVersionStamp") - 1)) { - if (scp->configVersionStamp == NULL) { - if (value == NULL) { - scp->configVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->configVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->configVersionStamp) - memcpy(scp->configVersionStamp, value + 1, - (len - 2)); - } - } - } - - } else if (!strncasecmp(line, "DialplanVersionStamp", - sizeof("DialplanVersionStamp") - 1)) { - if (scp->dialplanVersionStamp == NULL) { - if (value == NULL) { - scp->dialplanVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->dialplanVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->dialplanVersionStamp) - memcpy(scp->dialplanVersionStamp, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "SoftkeyVersionStamp", - sizeof("SoftkeyVersionStamp") - 1)) { - if (scp->softkeyVersionStamp == NULL) { - if (value == NULL) { - scp->softkeyVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->softkeyVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->softkeyVersionStamp) - memcpy(scp->softkeyVersionStamp, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "FeatureControlVersionStamp", - sizeof("FeatureControlVersionStamp") - 1)) { - if (scp->fcpVersionStamp == NULL) { - if (value == NULL) { - scp->fcpVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->fcpVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->fcpVersionStamp) - memcpy(scp->fcpVersionStamp, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "CUCMResult", - sizeof("CUCMResult") - 1)) { - if (value == NULL) { - scp->cucm_result = NULL; - } else { - int len =0; - if ((strncasecmp(value, "no_change", - len = strlen("no_change")) == 0) || - (strncasecmp(value, "config_applied", - len = strlen("config_applied")) == 0) || - (strncasecmp(value, "reregister_needed", - len = strlen("reregister_needed")) == 0)) { - scp->cucm_result = (char *) cpr_calloc(1,len + 1); - if (scp->cucm_result) { - sstrncpy(scp->cucm_result, value, len); - scp->cucm_result[len] = '\0'; - } - } - } - } else if (!strncasecmp(line, "LoadId", - sizeof("LoadId") - 1)) { - if (scp->firmwareLoadId == NULL) { - if (value == NULL) { - scp->firmwareLoadId = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->firmwareLoadId = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->firmwareLoadId) - memcpy(scp->firmwareLoadId, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "InactiveLoadId", - sizeof("InactiveLoadId") - 1)) { - if (scp->firmwareInactiveLoadId == NULL) { - if (value == NULL) { - scp->firmwareInactiveLoadId = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->firmwareInactiveLoadId = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->firmwareInactiveLoadId) - memcpy(scp->firmwareInactiveLoadId, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "LoadServer", - sizeof("LoadServer") - 1)) { - if (scp->loadServer == NULL) { - if (value == NULL) { - scp->loadServer = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->loadServer = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->loadServer) - memcpy(scp->loadServer, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "LogServer", - sizeof("LogServer") - 1)) { - if (scp->logServer == NULL) { - if (value == NULL) { - scp->logServer = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->logServer = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->logServer) - memcpy(scp->logServer, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "PPID", sizeof("PPID") - 1)) { - if (value == NULL) { - scp->ppid = FALSE; - } else if (!strncasecmp(value, "enabled", sizeof("enabled") - 1)) { - scp->ppid = TRUE; - } else if (!strncasecmp(value, "disabled", - sizeof("disabled") - 1)) { - scp->ppid = FALSE; - } else { - scp->ppid = FALSE; - } - - } - cpr_free(line); - - } else { - body_read = TRUE; - } - } - // Free the created stream structure - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return (scp); -} - -void -sippmh_free_service_control_info (sipServiceControl_t *scp) -{ - if (!scp) { - return; - } - - if (scp->configVersionStamp) - cpr_free(scp->configVersionStamp); - if (scp->dialplanVersionStamp) - cpr_free(scp->dialplanVersionStamp); - if (scp->registerCallID) - cpr_free(scp->registerCallID); - if (scp->softkeyVersionStamp) - cpr_free(scp->softkeyVersionStamp); - if (scp->fcpVersionStamp) - cpr_free(scp->fcpVersionStamp); - if (scp->cucm_result) - cpr_free(scp->cucm_result); - if (scp->loadServer) - cpr_free(scp->loadServer); - if (scp->firmwareLoadId) - cpr_free(scp->firmwareLoadId); - if (scp->logServer) - cpr_free(scp->logServer); - - cpr_free(scp); -} - -int32_t -sippmh_parse_max_forwards (const char *max_fwd_hdr) -{ - int32_t maxFwd; - - if (max_fwd_hdr) { - if (isdigit(*max_fwd_hdr)) { - maxFwd = strtol(max_fwd_hdr, NULL, 10); - if ((maxFwd >= 0) && (maxFwd <= 255)) { - return maxFwd; - } - } - } - return -1; -} - -/* - * Function: sippmh_parse_url_from_hdr - * - * Parameters: String that needs to be parsed - * - * Description: This function will strip out the tags and - * other characters in the header to retreive - * a string that could be used as the request uri. - * Note that the input string needs to be well formed. - * - * Returns: A string containing the request uri - * - */ -string_t -sippmh_get_url_from_hdr (char *input_str) -{ - char *left_bracket, *right_bracket = NULL; - - /* - This function is only intended for properly - formed headers. - */ - left_bracket = strpbrk(input_str, ",<"); - if (left_bracket) { - left_bracket++; - right_bracket = strchr(left_bracket, '>'); - if (right_bracket) { - *right_bracket = '\0'; - } - input_str = left_bracket; - } - return (string_t)input_str; -} -/* - * Function: sippmh_parse_join_header - * - * Parameters: pointer to string of the join header contents - * - * Returns: Parsed structure if parsed correctly, NULL otherwise - * - * Format of the header is as follows: - * Join: abcd;from-tag=efgh;to-tag=ijkl - */ -sipJoinInfo_t * -sippmh_parse_join_header (const char *header) -{ - sipJoinInfo_t *join = NULL; - char *semi = NULL; - unsigned int param_len; - char *params, *param_name, *param_value, *save_params; - - if (!header) { - return NULL; - } - - join = (sipJoinInfo_t *) cpr_calloc(1, sizeof(sipJoinInfo_t)); - if (!join) { - return NULL; - } - - // Read the call-id, if present - semi = strchr(header, SEMI_COLON); - if (semi) { - join->call_id = (char *) cpr_calloc(1, semi-header + 1); - if (join->call_id == NULL) { - sippmh_free_join_info(join); - return NULL; - } - sstrncpy(join->call_id, header, semi-header); - } else { - // call-id is the only parameter - join->call_id = cpr_strdup(header); - if (join->call_id == NULL) { - sippmh_free_join_info(join); - return NULL; - } - return (join); - } - - params = cpr_strdup(semi); - if (!params) { - sippmh_free_join_info(join); - return NULL; - } - save_params = params; - while (1) { - while (*params == ';') { - params++; - } - param_name = params; - SKIP_SIP_TOKEN(params); - param_len = params - param_name; - if (param_len == 0) { - sippmh_free_join_info(join); - cpr_free(save_params); - return NULL; - } - - /* Parse from-tag parameter */ - if ((param_len == sizeof(SIP_HEADER_JOIN_FROM_TAG) - 1) && - (strncasecmp(param_name, SIP_HEADER_JOIN_FROM_TAG, - sizeof(SIP_HEADER_JOIN_FROM_TAG) - 1) == 0) && - (join->from_tag == NULL)) { - params = parse_generic_param(params, ¶m_value); - if (params == NULL) { - sippmh_free_join_info(join); - cpr_free(save_params); - return NULL; - } else { - join->from_tag = (char *) cpr_calloc(1, params-param_value + 1); - if (join->from_tag) { - sstrncpy(join->from_tag, param_value, params-param_value + 1); - } - SKIP_LWS(params); - if (*params == SEMI_COLON) { - *params++ = '\0'; - } else { - break; - } - - } - - /* Parse to-tag parameter */ - } else if ((param_len == sizeof(SIP_HEADER_JOIN_TO_TAG) - 1) && - (strncasecmp(param_name, SIP_HEADER_JOIN_TO_TAG, - sizeof(SIP_HEADER_JOIN_TO_TAG) - 1) == 0) && - (join->to_tag == NULL)) { - params = parse_generic_param(params, ¶m_value); - if (params == NULL) { - sippmh_free_join_info(join); - cpr_free(save_params); - return NULL; - } else { - join->to_tag = (char *) cpr_calloc(1, params-param_value + 1); - if (join->to_tag) { - sstrncpy(join->to_tag, param_value, params-param_value + 1); - } - if (*params == SEMI_COLON) { - *params++ = '\0'; - } else { - break; - } - } - - } else { - // Skip over unexpected parameter - SKIP_SIP_TOKEN(params); - } - - SKIP_LWS(params); - } - cpr_free(save_params); - return (join); -} - -void -sippmh_free_join_info (sipJoinInfo_t *join) -{ - - if (!join) { - return; - } - if (join->call_id) - cpr_free(join->call_id); - if (join->from_tag) - cpr_free(join->from_tag); - if (join->to_tag) - cpr_free(join->to_tag); - cpr_free(join); -} - -sipRet_t -sippmh_add_join_header (sipMessage_t *message, sipJoinInfo_t *join) -{ - char joinhdr[MAX_SIP_HEADER_LENGTH+1]; - int left; - - // Write out the header in a buffer - if (!message) { - return STATUS_FAILURE; - } - - snprintf(joinhdr, MAX_SIP_HEADER_LENGTH, "%s", join->call_id); - left = (uint16_t) MAX_SIP_HEADER_LENGTH - strlen(join->call_id); - if (join->from_tag && left > 0) { - sstrncat(joinhdr, ";from-tag=", left); - left -= sizeof(";from-tag=") - 1; - sstrncat(joinhdr, join->from_tag, left); - left -= strlen(join->from_tag); - } - if (join->to_tag && left > 0) { - sstrncat(joinhdr, ";to-tag=", left); - left -= sizeof(";to-tag=") - 1; - sstrncat(joinhdr, join->to_tag, left); - } - return (sippmh_add_text_header(message, SIP_HEADER_JOIN, joinhdr)); -} - -/* - * Function: sippmh_parse_subscription_state - * - * Parameters: contents of the Subscription-State header - * - * Description: This function will parse for the state, expiry - * time, and a reason code in the header - * - * Returns: -1 if error, 0 if successfully parsed. - * - * Format of the line is as follows: - * Subscription-State: active;expires=7200;reason=whatever;retry-after=50 - */ -int -sippmh_parse_subscription_state(sipSubscriptionStateInfo_t *subsStateInfo, - const char *subs_state) -//TODO: how can subs_state be a const char [] when it can be modified below? -{ - char *ptr; - char temp[TEMP_PARSE_BUFFER_SIZE]; - uint8_t i; - - if (!subs_state) { - return (-1); - } - - if (!strncasecmp(subs_state, SIP_SUBSCRIPTION_STATE_ACTIVE, - sizeof(SIP_SUBSCRIPTION_STATE_ACTIVE) - 1)) { - subsStateInfo->state = SUBSCRIPTION_STATE_ACTIVE; - } else if (!strncasecmp(subs_state, SIP_SUBSCRIPTION_STATE_PENDING, - sizeof(SIP_SUBSCRIPTION_STATE_PENDING) - 1)) { - subsStateInfo->state = SUBSCRIPTION_STATE_PENDING; - } else if (!strncasecmp(subs_state, SIP_SUBSCRIPTION_STATE_TERMINATED, - sizeof(SIP_SUBSCRIPTION_STATE_PENDING) - 1)) { - subsStateInfo->state = SUBSCRIPTION_STATE_TERMINATED; - } - - ptr = strchr(subs_state, ';'); - if (!ptr) { - return (0); - } - SKIP_LWS(ptr); - - // Look for expires tag - ptr = strstr(subs_state, SIP_SUBSCRIPTION_STATE_EXPIRES); - if (ptr) { - ptr = ptr + sizeof(SIP_SUBSCRIPTION_STATE_EXPIRES); // Go over the '=' - SKIP_LWS(ptr); - if (*ptr) { - boolean is_int = FALSE; - - memset(temp, 0, sizeof(temp)); - i = 0; - while (isdigit(*ptr) && (i < sizeof(temp)-1)) { - temp[i++] = *ptr; - ptr++; - is_int = TRUE; - } - if (is_int == TRUE) { - subsStateInfo->expires = strtoul(temp, NULL, 10); - } - } - } - // Look for reason tag - ptr = strstr(subs_state, SIP_SUBSCRIPTION_STATE_REASON); - if (ptr) { - ptr = ptr + sizeof(SIP_SUBSCRIPTION_STATE_REASON); - SKIP_LWS(ptr); - if (*ptr) { - if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_DEACTIVATED, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_DEACTIVATED) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_DEACTIVATED; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_PROBATION, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_PROBATION) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_PROBATION; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_REJECTED, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_REJECTED) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_REJECTED; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_TIMEOUT, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_TIMEOUT) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_TIMEOUT; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_GIVEUP, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_GIVEUP) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_GIVEUP; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_NORESOURCE, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_NORESOURCE) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_NORESOURCE; - } else { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_INVALID; - } - } - } - - // Look for retry-after tag - ptr = strstr(subs_state, SIP_SUBSCRIPTION_STATE_RETRY_AFTER); - if (ptr) { - ptr = ptr + sizeof(SIP_SUBSCRIPTION_STATE_RETRY_AFTER); // Go over the '=' - SKIP_LWS(ptr); - if (*ptr) { - boolean is_int = FALSE; - - memset(temp, 0, sizeof(temp)); - i = 0; - while (isdigit(*ptr) && (i < sizeof(temp)-1)) { - temp[i++] = *ptr; - ptr++; - is_int = TRUE; - } - if (is_int == TRUE) { - *ptr = '\0'; - subsStateInfo->retry_after = strtoul(temp, NULL, 10); - } - } - } - - return (0); -} - -/* - * Function: sippmh_add_subscription_state - * - * Parameters: contents of the Subscription-State header - * - * Description: This function will add the subscription state header - * - * Returns: -1 if error, 0 if successfully added - * - * Format of the line is as follows: - * Subscription-State: active; expires=7200; reason=whatever - */ -int -sippmh_add_subscription_state(sipMessage_t *msg, - sipSubscriptionStateInfo_t *subsStateInfo) -{ - char subs_state[MAX_SUB_STATE_HEADER_SIZE]; - - if (!msg) { - return -1; - } - - if ((subsStateInfo->state == SUBSCRIPTION_STATE_ACTIVE) && (subsStateInfo->expires == 0)) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s", SIP_SUBSCRIPTION_STATE_ACTIVE); - } else if (subsStateInfo->state == SUBSCRIPTION_STATE_ACTIVE) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s; expires=%d", - SIP_SUBSCRIPTION_STATE_ACTIVE, - subsStateInfo->expires); - } else if (subsStateInfo->state == SUBSCRIPTION_STATE_PENDING) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s; expires=%d", - SIP_SUBSCRIPTION_STATE_PENDING, - subsStateInfo->expires); - } else if (subsStateInfo->state == SUBSCRIPTION_STATE_TERMINATED) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s; reason=timeout", - SIP_SUBSCRIPTION_STATE_TERMINATED); - } - - (void) sippmh_add_text_header(msg, SIP_HEADER_SUBSCRIPTION_STATE, - (const char *)&subs_state[0]); - return 0; -} - -boolean -sippmh_parse_kpml_event_id_params (char *params, char **call_id, - char **from_tag, char **to_tag) -{ - boolean params_good; - int param_len; - char *param_name; - - if (params == NULL) { - return FALSE; - } - - while (1) { - params_good = FALSE; - - while (*params == ';') { - params++; - } - - param_name = params; - SKIP_SIP_TOKEN(params); - param_len = params - param_name; - if (param_len == 0) { - return FALSE; - } - - /* Parse call-id parameter */ - if ((param_len == KPML_ID_CALLID_LEN) && - (strncasecmp(param_name, KPML_ID_CALLID, KPML_ID_CALLID_LEN) == 0)) { - params = parse_generic_param(params, call_id); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse from-tag parameter */ - } else if ((param_len == KPML_ID_FROM_TAG_LEN) && - (strncasecmp(param_name, KPML_ID_FROM_TAG, - KPML_ID_FROM_TAG_LEN) == 0)) { - params = parse_generic_param(params, from_tag); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse to-tag parameter */ - } else if ((param_len == KPML_ID_TO_TAG_LEN) && - (strncasecmp(param_name, KPML_ID_TO_TAG, - KPML_ID_TO_TAG_LEN) == 0)) { - params = parse_generic_param(params, to_tag); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - } - - SKIP_LWS(params); - if (*params == SEMI_COLON) { - /* More parameters follow */ - *params++ = '\0'; - SKIP_LWS(params); - } else { - break; - } - } - - return params_good; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_publish.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_publish.c deleted file mode 100644 index b89bdda745f..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_publish.c +++ /dev/null @@ -1,896 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccsip_publish.h" -#include "phntask.h" -#include "sip_common_transport.h" -#include "ccsip_task.h" -#include "ccsip_callinfo.h" -#include "ccsip_macros.h" -#include "util_string.h" -#include "cpr_rand.h" -#include "platform_api.h" -#include "ccsip_register.h" -#include "ccsip_reldev.h" -#include "debug.h" - -static sll_handle_t s_PCB_list = NULL; // signly linked list handle of PCBs -static int outgoingPublishes; - -static boolean sipSPISendPublish(ccsip_publish_cb_t *pcb_p, boolean authen); -static void free_pending_reqs (sll_handle_t list); - -/** - * This function will generate a new handle and return it. - * - * @return a non-zero integer value - */ -static pub_handle_t generate_new_pub_handle (void) -{ - static pub_handle_t handle = 0; - - handle++; - if (handle == NULL_PUBLISH_HANDLE) { - handle++; - } - return handle; -} - -/** - * This function will check if it is the PCB we are looking for based on the key. - * This is only invoked by sll_find(). - * - * @param[in] key - pointer to the key. - * @param[in] data - pointer to a node data. - * - * @return SLL_MATCH_FOUND if the node matches. - * Otherwise, SLL_MATCH_NOT_FOUND is returned. - * - * @pre (key != NULL) and (data != NULL) - */ -static sll_match_e is_matching_pcb (void *key, void *data) -{ - pub_handle_t pub_handle = *((pub_handle_t *)key); - ccsip_publish_cb_t *pcb_p = (ccsip_publish_cb_t *)data; - - if (pub_handle == pcb_p->pub_handle) { - return SLL_MATCH_FOUND; - } - return SLL_MATCH_NOT_FOUND; -} - -/** - * This function will create a PCB. It will also create the PCB linked list. - * - * @return NULL if there are no resources to create a PCB. - * Otherwise, pointer to a new PCB is returned. - * - * @pre (key != NULL) and (data != NULL) - */ -static ccsip_publish_cb_t *get_new_pcb (void) -{ - ccsip_publish_cb_t *pcb_p; - - /* - * If PCB list is not created yet, create the list. - */ - if (s_PCB_list == NULL) { - s_PCB_list = sll_create(is_matching_pcb); - if (s_PCB_list == NULL) { - return NULL; - } - } - - pcb_p = (ccsip_publish_cb_t *)cpr_malloc(sizeof(ccsip_publish_cb_t)); - if (pcb_p == NULL) { - return NULL; - } - memset(pcb_p, 0, sizeof(ccsip_publish_cb_t)); - pcb_p->pub_handle = generate_new_pub_handle(); - pcb_p->hb.cb_type = PUBLISH_CB; - pcb_p->hb.dn_line = 1; // for now set it to primary line. This will change when we do line based PUBLISH. - /* - * set up dest & src ip addr and port number. - */ - ccsip_common_util_set_dest_ipaddr_port(&pcb_p->hb); - ccsip_common_util_set_src_ipaddr(&pcb_p->hb); - pcb_p->hb.local_port = sipTransportGetListenPort(pcb_p->hb.dn_line, NULL); - pcb_p->retry_timer.timer = cprCreateTimer("PUBLISH retry timer", - SIP_PUBLISH_RETRY_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (pcb_p->retry_timer.timer == NULL) { - cpr_free(pcb_p); - return NULL; - } - pcb_p->pending_reqs = sll_create(NULL); - if (pcb_p->pending_reqs == NULL) { - (void)cprDestroyTimer(pcb_p->retry_timer.timer); - cpr_free(pcb_p); - return NULL; - } - (void) sll_append(s_PCB_list, pcb_p); - - return pcb_p; -} - -/** - * This function will find matching PCB by the key in the PCB list. - * - * @param[in] pub_handle - publish handle. - * - * @return NULL if there is no matching PCB - * Otherwise, pointer to the found PCB is returned. - * - * @pre (pub_handle > 0) and (s_PCB_list != NULL) - */ -static ccsip_publish_cb_t *find_pcb (pub_handle_t pub_handle) -{ - ccsip_publish_cb_t *pcb_p; - - pcb_p = (ccsip_publish_cb_t *)sll_find(s_PCB_list, &pub_handle); - - return pcb_p; -} - -/** - * This function will find matching PCB by the SIP Call-ID in the PCB list. - * - * @param[in] callID_p - SIP Call-ID - * - * @return NULL if there is no matching PCB - * Otherwise, pointer to the found PCB is returned. - * - * @pre (callID_p != NULL) - */ -static ccsip_publish_cb_t *find_pcb_by_sip_callid (const char *callID_p) -{ - ccsip_publish_cb_t *pcb_p; - - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - while (pcb_p != NULL) { - if (strncmp(callID_p, pcb_p->hb.sipCallID, (sizeof(pcb_p->hb.sipCallID) -1)) == 0) { - return pcb_p; - } - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, pcb_p); - } - return NULL; -} - -/** - * This function will free up the PCB resources and removes it from the PCB list. - * - * @param[in] pcb_p - pointer to a PCB. - * - * @return none - * - * @pre (pcb_p != NULL) - */ -static void free_pcb (ccsip_publish_cb_t *pcb_p) -{ - if (pcb_p->hb.authen.authorization != NULL) { - cpr_free(pcb_p->hb.authen.authorization); - } - if (pcb_p->hb.authen.sip_authen != NULL) { - sippmh_free_authen(pcb_p->hb.authen.sip_authen); - } - - cpr_free(pcb_p->entity_tag); - free_pending_reqs(pcb_p->pending_reqs); - (void)cprDestroyTimer(pcb_p->retry_timer.timer); - free_event_data(pcb_p->hb.event_data_p); - (void)sll_remove(s_PCB_list, (void *)pcb_p); - cpr_free(pcb_p); -} - -/** - * This function will append the application request in a pending list. - * - * @param[in] pcb_p - pointer to a PCB. - * @param[in] msg_p - pointer to an application request. - * - * @return TRUE if it is successful. - * Otherwise, FALSE is returned. - * - * @pre (pcb_p != NULL) and (msg_p != NULL) - * @post ((slink_list_t *)s_pres_req_list->count++) - */ -static boolean append_pending_reqs (ccsip_publish_cb_t *pcb_p, pub_req_t *msg_p) -{ - pub_req_t *temp_msg_p; - - temp_msg_p = (pub_req_t *)cpr_malloc(sizeof(pub_req_t)); - if (temp_msg_p == NULL) { - return FALSE; - } - (*temp_msg_p) = (*msg_p); - (void) sll_append(pcb_p->pending_reqs, temp_msg_p); - return TRUE; -} - -/** - * This function will free up entire list of pending requests - * - * @param[in] list - pending requests list handle - * - * @return none - * - */ -static void free_pending_reqs (sll_handle_t list) -{ - pub_req_t *msg_p; - - if (list == NULL) { - return; - } - - msg_p = (pub_req_t *)sll_next(list, NULL); - while (msg_p != NULL) { - free_event_data(msg_p->event_data_p); - (void)sll_remove(list, (void *)msg_p); - cpr_free(msg_p); - msg_p = (pub_req_t *)sll_next(list, NULL); - } - sll_destroy(list); -} - -/** - * This function will send the PUBLSIH request response to the application. - * - * @param[in] resp_code - this also includes error responses that start at 1000 - * @param[in] pub_handle - handle to a PCB - * @param[in] app_handle - application generated handle to this PUBLISH context. - * @param[in] callback_task - task in which the application resides. - * @param[in] resp_msg_id - messageID posted to the task. - * - * @return none - */ -static void send_resp_to_app (int resp_code, pub_handle_t pub_handle, pub_handle_t app_handle, - cc_srcs_t callback_task, int resp_msg_id) -{ - static const char fname[] = "send_resp_to_app"; - pub_rsp_t rsp; - - rsp.resp_code = resp_code; - rsp.pub_handle = pub_handle; - rsp.app_handle = app_handle; - if (publish_int_response(&rsp, callback_task, resp_msg_id) != CC_RC_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Failed to post PUBLISH response to the application", fname); - } -} - -/** - * This function will process SIPSPI_EV_CC_PUBLISH posted by applications. - * If there is an outstanding transaction, it will hold the request in the pending list. - * - * @param[in] buf - inter-process message buffer. - * - * @return SIP_OK if it successfully processes the request. - * SIP_ERROR if it fails to process the request. - * SIP_DEFER if it defers the processing. - * - * @note This will not free buf. - * - * @pre (buf != NULL) - */ -int publish_handle_ev_app_publish (cprBuffer_t buf) -{ - static const char fname[] = "publish_handle_ev_app_publish"; - pub_req_t *msg_p = (pub_req_t *)buf; - ccsip_publish_cb_t *pcb_p; - - - /* - * If this is initial PUBLISH, allocate a PCB. - * Otherwise, look up for PCB based on pub_handle. - */ - if (msg_p->pub_handle != NULL_PUBLISH_HANDLE) { - pcb_p = find_pcb(msg_p->pub_handle); - - if (pcb_p == NULL) { - send_resp_to_app(PUBLISH_FAILED_NOCONTEXT, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - free_event_data(msg_p->event_data_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Modification PUBLISH cannot be sent as the PCB is missing\n", - fname); - return SIP_ERROR; - } - - /* - * Check if there is an outstanding transaction. - * if so, put the request in pending request queue. - */ - if (pcb_p->outstanding_trxn == TRUE) { - if (append_pending_reqs(pcb_p, msg_p) == TRUE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"deffering as there is an outstanding transaction", - DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_DEFER; - } - /* free up PCB and respond with error */ - free_pcb (pcb_p); - send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - free_event_data(msg_p->event_data_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Queueing outgoing PUBLISH request failed", fname); - return SIP_ERROR; - } - /* - * if event_data_p is NULL, this is terminating PUBLISH. - * otherwise, it is a modifying PUBLISH. - */ - free_event_data(pcb_p->hb.event_data_p); - pcb_p->hb.event_data_p = msg_p->event_data_p; - if ((msg_p->event_data_p == NULL) && (msg_p->expires == 0)) { // removing PUBLISH - pcb_p->hb.orig_expiration = 0; - } - } else { - pcb_p = get_new_pcb(); - if (pcb_p == NULL) { - send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - free_event_data(msg_p->event_data_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"PCB allocation failed", fname); - return SIP_ERROR; - } - pcb_p->app_handle = msg_p->app_handle; - sstrncpy(pcb_p->ruri, msg_p->ruri, MAX_URI_LENGTH); - sstrncpy(pcb_p->esc, msg_p->esc, MAX_URI_LENGTH); - pcb_p->hb.orig_expiration = msg_p->expires; - pcb_p->hb.event_type = msg_p->event_type; - pcb_p->hb.event_data_p = msg_p->event_data_p; - pcb_p->callback_task = msg_p->callback_task; - pcb_p->resp_msg_id = msg_p->resp_msg_id; - } - - pcb_p->hb.authen.cred_type = 0; - - if (sipSPISendPublish(pcb_p, FALSE) == TRUE) { - pcb_p->outstanding_trxn = TRUE; - outgoingPublishes++; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"PUBLISH request sent successfully", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - - /* free up PCB and respond with error */ - free_pcb (pcb_p); - send_resp_to_app(PUBLISH_FAILED_SEND, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Failed to send PUBLISH request", fname); - return SIP_ERROR; - -} - - -/** - * This function will create the PUBLISH message and send it. it also starts the retry timer. - * - * @param[in] pcb_p - pointer to PCB - * @param[in] authen - boolean that indicates whether to add authorization header. - * - * @return TRUE if it successfully sent PUBLISH - * Otherwise, FALSE is returned - * - * @pre (pcb_p != NULL) - */ -static boolean sipSPISendPublish (ccsip_publish_cb_t *pcb_p, boolean authen) -{ - static const char fname[] = "sipSPISendPublish"; - static uint32_t cseq = 0; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char *domainloc; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char sip_temp_str[MAX_SIP_URL_LENGTH]; - char sip_temp_tag[MAX_SIP_URL_LENGTH]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char via[SIP_MAX_VIA_LENGTH]; - int max_forwards_value = 70; - static uint16_t count = 1; - sipMessage_t *request = NULL; - int timeout = 0; - - request = GET_SIP_MESSAGE(); - if (!request) { - return FALSE; - } - - /* - * Populate full RURI if it is not yet. Sometimes, applications may only provide user part. - */ - if (pcb_p->full_ruri[0] == 0) { - sstrncpy(pcb_p->full_ruri, "sip:", MAX_SIP_URL_LENGTH); - sstrncat(pcb_p->full_ruri, pcb_p->ruri, MAX_SIP_URL_LENGTH - sizeof("sip:")); - /* check if it has host part */ - domainloc = strchr(pcb_p->full_ruri, '@'); - if (domainloc == NULL) { - domainloc = pcb_p->full_ruri + strlen(pcb_p->full_ruri); - if ((domainloc - pcb_p->full_ruri) < (MAX_SIP_URL_LENGTH - 1)) { - /* Do not include @ when there is no user part */ - if (pcb_p->ruri[0] != '\0') { - *domainloc++ = '@'; - } - ipaddr2dotted(dest_sip_addr_str, &pcb_p->hb.dest_sip_addr); - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - (pcb_p->full_ruri))); - } - } - } - - ipaddr2dotted(src_addr_str, &pcb_p->hb.src_addr); - - // Add request line - if (HSTATUS_SUCCESS != sippmh_add_request_line(request, - sipGetMethodString(sipMethodPublish), - pcb_p->full_ruri, SIP_VERSION)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Request line", fname); - free_sip_message(request); - return (FALSE); - } - - // Add local Via - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(1, TRUE, NULL), - src_addr_str, pcb_p->hb.local_port, VIA_BRANCH, - VIA_BRANCH_START, (unsigned int) cpr_rand()); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_VIA, via)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding VIA header", fname); - free_sip_message(request); - return (FALSE); - } - - // Add To Header - snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "<%s>", pcb_p->full_ruri); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_TO, sip_temp_str)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding TO header", fname); - free_sip_message(request); - return (FALSE); - } - - // Add From Header. - sstrncat(sip_temp_str, ";tag=", MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - sip_util_make_tag(sip_temp_tag); - sstrncat(sip_temp_str, sip_temp_tag, MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_FROM, sip_temp_str)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding FROM header", fname); - free_sip_message(request); - return (FALSE); - } - - // Add Call-ID Header. - platform_get_wired_mac_address(mac_address); - count++; - snprintf(pcb_p->hb.sipCallID, MAX_SIP_CALL_ID, "%.4x%.4x-%.4x%.4x-%.8x-%.8x@%s", // was MAX_SIP_URL_LENGTH - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], count, - (unsigned int) cpr_rand(), - (unsigned int) cpr_rand(), - src_addr_str); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CALLID, pcb_p->hb.sipCallID)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CALLID header", fname); - free_sip_message(request); - return (FALSE); - } - - // Add Contact header. Contact header is not needed as per RFC. BUT CCM needs it. - snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str, pcb_p->hb.local_port); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CONTACT, sip_temp_str)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header", fname); - free_sip_message(request); - return (FALSE); - } - - // Add Cseq. - cseq++; - if (cseq == 0) { - cseq = 1; - } - if (HSTATUS_SUCCESS != sippmh_add_cseq(request, sipGetMethodString(sipMethodPublish), cseq)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSEQ header", fname); - free_sip_message(request); - return (FALSE); - } - - // Add UserAgent header - (void) sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - - - // Add SIP-If-Match header. - if (pcb_p->entity_tag != NULL) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_SIPIFMATCH, - pcb_p->entity_tag)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Event header", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Add Expires Header - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_EXPIRES, - pcb_p->hb.orig_expiration)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Expires header", fname); - free_sip_message(request); - return (FALSE); - } - - // Add max-forwards header - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_forwards_value, - sizeof(max_forwards_value)); - if (HSTATUS_SUCCESS != - sippmh_add_int_header(request, SIP_HEADER_MAX_FORWARDS, - max_forwards_value)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Max-Forwards header", fname); - free_sip_message(request); - return (FALSE); - } - - // add Authorization header - if (authen) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, AUTHOR_HDR(pcb_p->hb.authen.status_code), - pcb_p->hb.authen.authorization)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Authorization header", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Add content, if any - if (pcb_p->hb.event_data_p) { - if (add_content(pcb_p->hb.event_data_p, request, fname) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content", fname); - free_sip_message(request); - return (FALSE); - } - } else { - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-Len", fname); - free_sip_message(request); - return (FALSE); - } - } - - ccsip_common_util_set_retry_settings(&pcb_p->hb, &timeout); - if (sipTransportCreateSendMessage(NULL, request, sipMethodPublish, - &(pcb_p->hb.dest_sip_addr), - (int16_t) pcb_p->hb.dest_sip_port, - FALSE, TRUE, timeout, pcb_p, - RELDEV_NO_STORED_MSG) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send PUBLISH message", fname); - return (FALSE); - } - - return (TRUE); - -} - -/** - * This function will handle retry-timer expiration - * - * @param[in] handle - handle to PCB - * - * @return 0 if it is successful in handling the timer - * Otherwise, -1 is returned - * - * @pre (handle != 0) - */ -int publish_handle_retry_timer_expire (uint32_t handle) -{ - static const char fname[] = "publish_handle_retry_timer_expire"; - pub_handle_t pub_handle = handle; - ccsip_publish_cb_t *pcb_p; - uint32_t max_retx = 0; - uint32_t time_t1 = 0; - uint32_t time_t2 = 0; - uint32_t timeout = 0; - - /* - * find the PCB - */ - pcb_p = find_pcb(pub_handle); - if (pcb_p == NULL) { - /* No PCB. So do nothing. */ - return 0; - } - if (pcb_p->hb.retx_flag == FALSE) { - /* probably we got some response. so do nothing */ - return 0; - } - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - if (pcb_p->hb.retx_counter < max_retx) { - pcb_p->hb.retx_counter++; - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - timeout = time_t1 * (1 << pcb_p->hb.retx_counter); - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Resending message #%d", - DEB_F_PREFIX_ARGS(SIP_PUB, fname), pcb_p->hb.retx_counter); - if (sipTransportSendMessage(NULL, - pcb_p->retry_timer.message_buffer, - pcb_p->retry_timer.message_buffer_len, - pcb_p->retry_timer.message_type, - &(pcb_p->retry_timer.ipaddr), - pcb_p->retry_timer.port, - FALSE, TRUE, timeout, pcb_p) < 0) { - /* free up PCB and respond with error */ - send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send message", fname); - return (-1); - } - - } else { - /* - * send timeout response and free up PCB - */ - send_resp_to_app(SIP_CLI_ERR_REQ_TIMEOUT, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"reached MAX retries", fname); - } - return 0; -} - -/** - * This function will check if wee need to send refresh PUBLISH. - * If so, it will send refresh PUBLISH - * - * @param[in] none - * - * @return none - */ -void publish_handle_periodic_timer_expire (void) -{ - static const char fname[] = "publish_handle_periodic_timer_expire"; - int delta = 0; - ccsip_publish_cb_t *pcb_p; - pub_req_t msg; - - config_get_value(CFGID_TIMER_SUBSCRIBE_DELTA, &delta, - sizeof(delta)); - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - while (pcb_p != NULL) { - if (pcb_p->outstanding_trxn == FALSE) { - if (pcb_p->hb.expires >= TMR_PERIODIC_PUBLISH_INTERVAL) { - pcb_p->hb.expires -= TMR_PERIODIC_PUBLISH_INTERVAL; - } - if (pcb_p->hb.expires <= (delta + TMR_PERIODIC_PUBLISH_INTERVAL)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sending REFRESH PUBLISH", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - memset (&msg, 0, sizeof(msg)); - /* refresh is triggered by NULL event data and non-zero expires value */ - msg.pub_handle = pcb_p->pub_handle; - msg.expires = pcb_p->hb.orig_expiration; - (void)publish_handle_ev_app_publish(&msg); - } - } - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, pcb_p); - } -} - -/** - * This function will process the response to PUBLISH request sent by us. - * - * @param[in] pSipMessage - pointer to received SIP response msg - * - * @return SIP_OK if it successfully processes the response. - * SIP_ERROR if it fails to process the response. - * - * @pre (pSipMessage != NULL) - */ -int publish_handle_ev_sip_response (sipMessage_t *pSipMessage) -{ - static const char fname[] = "publish_handle_ev_sip_response"; - const char *callID_p = NULL; - int response_code = 0; - const char *expires = NULL; - const char *sip_etag = NULL; - long expiry_time; - pub_req_t *msg_p; - ccsip_publish_cb_t *pcb_p; - int entity_tag_size; - - callID_p = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!callID_p) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.", fname); - return SIP_ERROR; - } - - /* - * Find PCB by Call-ID. The Call-IDs generated by the phone ae unique. - */ - pcb_p = find_pcb_by_sip_callid(callID_p); - if (pcb_p == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No matching PCB found", fname); - return SIP_ERROR; - } - - /* - * Cancel the retry_timer and set the retx_flag to FALSE. - */ - sip_platform_msg_timer_subnot_stop(&(pcb_p->retry_timer)); - pcb_p->hb.retx_flag = FALSE; - - // Parse the return code - (void) sipGetResponseCode(pSipMessage, &response_code); - - if (response_code >= 200) { - pcb_p->outstanding_trxn = FALSE; - } - - - if ((response_code == SIP_CLI_ERR_UNAUTH) || - (response_code == SIP_CLI_ERR_PROXY_REQD)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - if (ccsip_common_util_generate_auth(pSipMessage, &pcb_p->hb, SIP_METHOD_PUBLISH, - response_code, pcb_p->full_ruri) == TRUE) { - if (sipSPISendPublish(pcb_p, TRUE) == TRUE) { - pcb_p->outstanding_trxn = TRUE; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with Auth header", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - } - /* - * Since we failed to resend the PUBLISH request, free up the PCB and let the app know. - */ - send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to auth challenge", fname); - return SIP_ERROR; - } - - /* - * if response code is 423, grab Min-Expires and send new PUBLISH with new expires value - */ - if (response_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) { - expires = sippmh_get_header_val(pSipMessage, - (const char *)SIP_HEADER_MIN_EXPIRES, - NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - //ensure new Min-Expires is > what we set before in Expires - if ((long) expiry_time > pcb_p->hb.expires) { - pcb_p->hb.expires = expiry_time; - pcb_p->hb.orig_expiration = expiry_time; - } - if (sipSPISendPublish(pcb_p, FALSE) == TRUE) { - pcb_p->outstanding_trxn = TRUE; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with increased expires", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - } - /* - * Since we failed to resend the PUBLISH request, free up the PCB and let the app know. - */ - send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to 423", fname); - return SIP_ERROR; - } - - /* - * if the response_code is > 299, free up the PCB and let the app know. - */ - if (response_code > 299) { - send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); - return SIP_OK; - } - - /* - * if the response is < 200, do nothing. - */ - if (response_code < 200) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); - return SIP_OK; - } - - /* - * If it is PUBLISH remove operation, free up PCB - */ - if (pcb_p->hb.orig_expiration == 0) { - send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"removed PCB as this was a terminating PUBLISH", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - - /* - * extract Expires and SIP-ETag headers and save them. - */ - expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - pcb_p->hb.expires = expiry_time; - } - sip_etag = sippmh_get_header_val(pSipMessage, SIP_HEADER_SIPETAG, NULL); - if (sip_etag != NULL) { - cpr_free(pcb_p->entity_tag); - entity_tag_size = strlen(sip_etag) + 1; - pcb_p->entity_tag = cpr_malloc(entity_tag_size); - if (pcb_p->entity_tag != NULL) { - sstrncpy(pcb_p->entity_tag, sip_etag, entity_tag_size); - } else { - free_pcb (pcb_p); - send_resp_to_app(PUBLISH_FAILED_NORESOURCE, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"memory allocation failed", fname); - return SIP_ERROR; - - } - } - - /* - * If there are no pending requests, provide the response to the application. - */ - msg_p = (pub_req_t *)sll_next(pcb_p->pending_reqs, NULL); - if (msg_p != NULL) { - (void)sll_remove(pcb_p->pending_reqs, msg_p); - (void)publish_handle_ev_app_publish(msg_p); - cpr_free(msg_p); - return SIP_OK; - } - send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent response %d to app", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); - return SIP_OK; -} - -/** - * This function will inform the application that phone is either - * 1. restarting or - * 2. failing over/ falling back - * - * @note detection of CCM reboot will be handled by PUBLISH ETag mechanism. - * - * @param[in] none - * - * @return none - */ -void publish_reset (void) -{ - ccsip_publish_cb_t *pcb_p; - - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - while (pcb_p != NULL) { - send_resp_to_app(PUBLISH_FAILED_RESET, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb(pcb_p); - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - } -} - -/** - * This function will print the stats (invoked by show command) - * - * @param[in] none - * - * @return 0 always - */ -cc_int32_t show_publish_stats (cc_int32_t argc, const char *argv[]) -{ - debugif_printf("------ Current PUBLISH Statistics ------\n"); - if (s_PCB_list != NULL) { - debugif_printf("Number of PCBs allocated: %d\n", sll_count(s_PCB_list)); - } else { - debugif_printf("Number of PCBs allocated: 0\n"); - } - debugif_printf("Total outgoing PUBLISH requests: %d\n", outgoingPublishes); - return 0; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_register.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_register.c deleted file mode 100644 index 1640175b947..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_register.c +++ /dev/null @@ -1,3079 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_timers.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "cpr_ipc.h" -#include "cpr_in.h" -#include "util_string.h" -#include "task.h" -#include "phntask.h" -#include "ccsip_core.h" -#include "ccsip_messaging.h" -#include "phone_debug.h" -#include "ccsip_platform.h" -#include "ccsip_platform_timers.h" -#include "ccsip_macros.h" -#include "ccsip_pmh.h" -#include "ccsip_register.h" -#include "ccsip_task.h" -#include "ccsip_credentials.h" -#include "debug.h" -#include "logmsg.h" -#include "ccsip_pmh.h" -#include "ccsip_credentials.h" -#include "dns_utils.h" -#include "config.h" -#include "sip_common_transport.h" -#include "uiapi.h" -#include "sip_common_regmgr.h" -#include "text_strings.h" -#include "sip_interface_regmgr.h" -#include "phone_platform_constants.h" -#include "ccsip_common_cb.h" -#include "misc_util.h" - -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern void *new_standby_available; -extern boolean regall_fail_attempt; -extern boolean registration_reject; - -extern void ui_set_sip_registration_state(line_t line, boolean registered); -extern void ui_update_registration_state_all_lines(boolean registered); - -boolean dump_reg_msg = TRUE; -boolean refresh_reg_msg = FALSE; - -static ccsip_register_states_t ccsip_register_state = SIP_REG_IDLE; - -/* Need an additional ack timer for the backup proxy */ -static cprTimer_t ack_tmrs[MAX_REG_LINES + 1]; -ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern ccm_failover_table_t CCM_Failover_Table; -static boolean start_standby_monitor = TRUE; -extern boolean Is794x; - -static void show_register_data(void); - -#define SIP_REG_TMR_EXPIRE_TICKS 55000 /* msec; re-registration timer */ -#define REGISTER_CMD "register" -#define SIP_REG_TMR_ACK_TICKS 32000 /* msec; supervision timer equivalent to Timer F */ - -static const char *ccsip_register_state_names[] = { - "IDLE", - "REGISTERING", - "REGISTERED", - "UNREGISTERING", - "PRE_FALLBACK", - "IN_FAILOVER", - "POST_FAILOVER", - "STANDBY_FAILOVER", - "NO_CC", - "NO_STANDBY", - "NO_REGISTER" -}; - -static const char *ccsip_register_reg_state_names[] = { - "NONE", - "IDLE", - "REGISTERING", - "REGISTERED", - "UNREGISTERING", - "PRE_FALLBACK", - "IN_FAILOVER", - "POST_FAILOVER", - "STANDBY_FAILOVER", - "NO_CC", - "NO_STANDBY", - "NO_REGISTER" -}; - - -void ccsip_handle_ev_reg_req(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_reg_cancel(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_unreg_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_3xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_4xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_failure_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_tmr_expire(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_tmr_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_tmr_retry(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_unreg_tmr_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_standby_keepalive_tmr_expire(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_idle_tmr_expire(ccsipCCB_t *ccb, sipSMEvent_t *event); - -const char *ccsip_register_state_name(ccsip_register_states_t state); -const char *ccsip_register_reg_state_name(sipRegSMStateType_t state); -const char *sip_util_reg_event2string(sipRegSMEventType_t event); -char *sip_util_reg_state2string(sipRegSMStateType_t state); -void ccsip_register_retry_timer_start(ccsipCCB_t *ccb); -void ccsip_register_cleanup(ccsipCCB_t *ccb, boolean start); -cc_int32_t ccsip_register_cmd(cc_int32_t argc, const char *argv[]); -void ccsip_register_clear_all_logs(void); -boolean ccsip_register_all_registered(void); - -/* convert sip line to reg line */ -#define SIP_REG_LINE2REGLINE(line) ((line) - (REG_CCB_START)) - -/* convert reg line to sip line */ -#define SIP_REG_REGLINE2LINE(line) ((line) + (REG_CCB_START)) - -// Date holder -static struct { - boolean valid; - char datestring[MAX_SIP_DATE_LENGTH]; -} ccm_date; - -static const sipSMEventActionFn_t -gSIPRegSMTable[SIP_REG_STATE_END - SIP_REG_STATE_BASE + 1] - [SIPSPI_REG_EV_END - SIPSPI_REG_EV_BASE + 1] = -{ - /* SIP_REG_STATE_IDLE - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_reg_req, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_default, - /* E_SIP_REG_1xx */ ccsip_handle_ev_default, - /* E_SIP_REG_2xx */ ccsip_handle_ev_default, - /* E_SIP_REG_3xx */ ccsip_handle_ev_default, - /* E_SIP_REG_4xx */ ccsip_handle_ev_default, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_idle_tmr_expire, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_default, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_REGISTERING - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_reg_req, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_reg_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ ccsip_handle_ev_2xx, - /* E_SIP_REG_3xx */ ccsip_handle_ev_3xx, - /* E_SIP_REG_4xx */ ccsip_handle_ev_4xx, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_failure_response, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_tmr_ack, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_tmr_expire, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_tmr_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_REGISTERED - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_default, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_reg_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_default, - /* E_SIP_REG_2xx */ ccsip_handle_ev_default, - /* E_SIP_REG_3xx */ ccsip_handle_ev_default, - /* E_SIP_REG_4xx */ ccsip_handle_ev_default, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_tmr_expire, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_tmr_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_UNREGISTERING - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_default, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_reg_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ ccsip_handle_ev_unreg_2xx, - /* E_SIP_REG_3xx */ ccsip_handle_ev_3xx, - /* E_SIP_REG_4xx */ ccsip_handle_ev_4xx, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_failure_response, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_unreg_tmr_ack, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_standby_keepalive_tmr_expire, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_tmr_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_IN_FALLBACK - */ - { - /* E_SIP_REG_REG_REQ */ sip_regmgr_ev_default, - /* E_SIP_REG_CANCEL */ sip_regmgr_ev_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ sip_regmgr_ev_in_fallback_2xx, - /* E_SIP_REG_3xx */ sip_regmgr_ev_default, - /* E_SIP_REG_4xx */ sip_regmgr_ev_fallback_retry, - /* E_SIP_REG_FAILURE_RESPONSE */ sip_regmgr_ev_fallback_retry, - /* E_SIP_REG_TMR_ACK */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_TMR_EXPIRE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_WAIT */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_RETRY */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - /* SIP_REG_STATE_STABILITY_CHECK - */ - { - /* E_SIP_REG_REG_REQ */ sip_regmgr_ev_default, - /* E_SIP_REG_CANCEL */ sip_regmgr_ev_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ sip_regmgr_ev_stability_check_2xx, - /* E_SIP_REG_3xx */ sip_regmgr_ev_default, - /* E_SIP_REG_4xx */ sip_regmgr_ev_default, - /* E_SIP_REG_FAILURE_RESPONSE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_ACK */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_TMR_EXPIRE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_WAIT */ sip_regmgr_ev_stability_check_tmr_wait, - /* E_SIP_REG_TMR_RETRY */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - /* SIP_REG_STATE_TOKEN_WAIT - */ - { - /* E_SIP_REG_REG_REQ */ sip_regmgr_ev_default, - /* E_SIP_REG_CANCEL */ sip_regmgr_ev_default, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ sip_regmgr_ev_token_wait_2xx, - /* E_SIP_REG_3xx */ sip_regmgr_ev_default, - /* E_SIP_REG_4xx */ ccsip_handle_ev_4xx, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_failure_response, - /* E_SIP_REG_TMR_ACK */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_TMR_EXPIRE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_WAIT */ sip_regmgr_ev_token_wait_tmr_wait, - /* E_SIP_REG_TMR_RETRY */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_cleanup, - } -}; - -/* - * This function gets the supported option tags from the 200 OK response - * to the REG message sent. - */ -void -sip_get_supported_options_2xx (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *supported; - - ccb->supported_tags = 0; - supported = sippmh_get_cached_header_val(response, SUPPORTED); - if (supported != NULL) { - /* - * Supported header is found, find the interrested supported - * function from 2xx response from the REG msg. sent. Note that - * the sippmh_parse_supported_require() can be used but - * decided to minimize the impact on performance parsing all other - * tags that are not interested during registration times and - * vice versa making changes to sippmh_parse_supported_require() - * to parse the tags that are not interested for other messages - * also impact the processing time for other messages. - */ - if (strcasestr(supported, REQ_SUPP_PARAM_CISCO_SRTP_FALLBACK)) { - /* cisco SRTP fallback is supported by the other end */ - ccb->supported_tags |= cisco_srtp_fallback_tag; - } - } -} - -/* - * This function starts the Register message - * ack timer. If no response is received from - * the register message within four minutes, - * this timer will pop and resend the Register - * message. - */ -void -sip_start_ack_timer (ccsipCCB_t *ccb) -{ - uint16_t ack_timer_index; - - if (ccb->index == REG_BACKUP_CCB) { - ack_timer_index = MAX_REG_LINES; - } else { - ack_timer_index = ccb->dn_line - 1; - } - - CCSIP_DEBUG_REG_STATE( DEB_L_C_F_PREFIX " ccb->index=%d ack_timer_index=%d ", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, 0, "sip_start_ack_timer"), - ccb->index, ack_timer_index); - - if (cprStartTimer(ack_tmrs[ack_timer_index], SIP_REG_TMR_ACK_TICKS, - (void *)(long)ccb->index) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sip_start_ack_timer", "cprStartTimer"); - } -} - - -/* - * This function stops the Register message - * ack timer. - */ -void -sip_stop_ack_timer (ccsipCCB_t *ccb) -{ - uint16_t ack_timer_index; - - if (ccb->index == REG_BACKUP_CCB) { - ack_timer_index = MAX_REG_LINES; - } else { - ack_timer_index = ccb->dn_line - 1; - } - - CCSIP_DEBUG_REG_STATE( DEB_L_C_F_PREFIX " ccb->index=%d ack_timer_index=%d ", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, 0, "sip_stop_ack_timer"), - ccb->index, ack_timer_index); - - if (cprCancelTimer(ack_tmrs[ack_timer_index]) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sip_stop_ack_timer", "cprCancelTimer"); - } -} - - -void -sip_reg_sm_change_state (ccsipCCB_t *ccb, sipRegSMStateType_t new_state) -{ - if (g_disable_mass_reg_debug_print == FALSE) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Registration state change: %s ---> " - "%s\n", DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->index, ccb->dn_line, "sip_reg_sm_change_state"), - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - sip_util_reg_state2string(new_state)); - } - ccb->state = (sipSMStateType_t) new_state; - - if (ccb->index == REG_CCB_START) { - if ((new_state > SIP_REG_STATE_REGISTERED) || (!refresh_reg_msg)) { - dump_reg_msg = TRUE; - } else { - dump_reg_msg = FALSE; - } - } -} - - -void -ccsip_handle_ev_reg_req (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_reg_req"; - char line_name[MAX_LINE_NAME_SIZE]; - int value; - - config_get_value(CFGID_PROXY_REGISTER, &value, sizeof(value)); - if (value == 0) { - ui_set_sip_registration_state(ccb->dn_line, FALSE); - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_REG_DISABLED), - ccb->index, ccb->dn_line, fname); - - return; - } - - ccsip_register_clear_all_logs(); - - sip_stop_ack_timer(ccb); - sip_start_ack_timer(ccb); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - - - sip_util_get_new_call_id(ccb); - - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &ccb->reg.tmr_expire, - sizeof(ccb->reg.tmr_expire)); - ccb->reg.act_time = (int) time(NULL); - - if (sipSPISendRegister(ccb, 0, line_name, ccb->reg.tmr_expire) != TRUE) { - // set expire timer and cleanup ccb in non-ccm mode. - // do not change the expire timer value in ccm mode - if (ccb->cc_type != CC_CCM) { - ccsip_register_cleanup(ccb, TRUE); - } - log_clear(LOG_REG_MSG); - log_msg(LOG_REG_MSG); - } - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_REGISTERING); -} - - - -void -ccsip_handle_ev_default (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - if ((event->type == (int) E_SIP_REG_CANCEL) && (ccb->state == (int) SIP_REG_STATE_IDLE)) { - (void) sip_platform_register_expires_timer_stop(ccb->index); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - ccsip_register_cleanup(ccb, FALSE); - } - - /* only free SIP messages, timeouts are internal */ - if (event->type < (int) E_SIP_REG_TMR_ACK) { - free_sip_message(event->u.pSipMessage); - } -} - - -void -ccsip_handle_ev_tmr_expire (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - // Initiate registration if prime line or not in failover state - if ((!CCM_Failover_Table.failover_started) || - (ccb->index == REG_CCB_START)) { - /*If the phone is registered with CSPS, the failover_started flag - * will always be false. Therefore, this code will always be - * executed. */ - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - refresh_reg_msg = TRUE; - /* send a message to the SIP_REG SM to initiate registration */ - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } else { - ccsip_handle_ev_default(ccb, event); - } -} - -void -ccsip_handle_ev_idle_tmr_expire (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - - if (ccb->cc_type == CC_CCM) { - if (ccb->index == REG_BACKUP_CCB) { - ccsip_handle_ev_tmr_expire(ccb, event); - } else { - ccsip_handle_ev_default(ccb, event); - } - } else { - /* assuming CSPS */ - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - /* send a message to the SIP_REG SM to initiate registration */ - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - - -void -ccsip_handle_ev_tmr_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - log_clear(LOG_REG_AUTH_ACK_TMR); - log_msg(LOG_REG_AUTH_ACK_TMR); - - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - Send tmr ack event to the regmgr/ - */ - sip_regmgr_ev_tmr_ack_retry(ccb, event); - } else { - /* - * regmgr - Assume it is csps - */ - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - /* send a message to the SIP_REG SM to initiate registration */ - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - - -void -ccsip_handle_ev_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_1xx"; - sipMessage_t *response = NULL; - int status_code = 0; - char status[LOG_MAX_LEN]; - - response = event->u.pSipMessage; - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - return; - } - - free_sip_message(response); - - switch (status_code) { - case SIP_1XX_TRYING: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP", status_code); - return; - - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), ccb->index, - ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP BAD", status_code); - - snprintf(status, sizeof(status), "in %d, information", status_code); - log_clear(LOG_REG_UNSUPPORTED); - log_msg(LOG_REG_UNSUPPORTED, status); - - ccsip_register_cleanup(ccb, TRUE); - - return; - } -} - -static boolean -ccsip_get_exp_time_2xx (ccsipCCB_t *ccb, sipContact_t *contact_info, - const char *expires, uint32_t *exp_time_ret) -{ - static const char fname[] = "ccsip_get_exp_time_2xx"; - boolean exp_found = FALSE; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char user[MAX_LINE_NAME_SIZE]; - int i; - uint32_t gmt_time; //TODO convert to time_t - //uint32_t diff_time; //TODO convert to time_t - int32_t gmt_rc; - uint32_t exp_time; - uint32_t register_delta; - - /* did the server change the expires time? */ - - /* - * Form the contact header. - * The proxy can return multiple contacts so we will need to see which one - * matches this REGISTER. - */ - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, sizeof(uint32_t)); - if (contact_info != NULL) { - ipaddr2dotted(src_addr_str, &ccb->src_addr); - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, - sizeof(user)); - - /* is expires header for this line included in the contact? */ - for (i = 0; i < contact_info->num_locations; i++) { - if ((sippmh_cmpURLStrings(contact_info->locations[i]->genUrl->u.sipUrl->user, - user, FALSE) == 0) && - (strcmp(contact_info->locations[i]->genUrl->u.sipUrl->host, - src_addr_str) == 0)) { - if ((contact_info->params[i].expires > 0) && - (contact_info->params[i].expires < exp_time)) { - exp_time = contact_info->params[i].expires; - exp_found = TRUE; - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_REG_PROXY_EXPIRES), - ccb->index, ccb->dn_line, fname); - break; - } - } - } - } - - - if (exp_found != TRUE) { - //expires param is not found in the CONTACT header - // look for Expires header. - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, - sizeof(exp_time)); - if (expires) { - gmt_rc = gmt_string_to_seconds((char *)expires, - (unsigned long *)&gmt_time); - if (gmt_rc != -1) { - // We only want to update the expires timeout if it is lower - // than our predefined threshold. We don't want to allow - // people to keep us hung up for infinite periods of time - if (gmt_rc == 1) { - // We got a numeric entry in the expires field - if (gmt_time < exp_time) { - exp_time = gmt_time; - exp_found = TRUE; - } - } - } - } - } - - /* - * Subtract some user defined period of time to account for network delay - * or the possibility that the registration server is down and this - * request has to be processed by a backup server after the timeout - * occurs. If the user has not defined this value in the config, it - * defaults to 5 seconds. - */ - config_get_value(CFGID_TIMER_REGISTER_DELTA, ®ister_delta, - sizeof(register_delta)); - - /* - * Sanity check the register delta value as the proxy could have returned - * a much lower registration period in its' response. The minimum - * registration expiration is 60 seconds to prevent the phone from being - * flooded with msgs. - */ - if ((exp_time - register_delta) < MIN_REGISTRATION_PERIOD) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX - "Warning - Registration period received (%d) " - "minus configured timer_register_delta (%d) is less than " - "%d seconds.\n", DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), exp_time, - register_delta, MIN_REGISTRATION_PERIOD); - exp_found = FALSE; - } else { - exp_time = exp_time - register_delta; - exp_found = TRUE; - } - *exp_time_ret = exp_time; - return (exp_found); -} - -/* - * Function: ccsip_check_ccm_restarted - * - * Parameters: - * new_reg_ccb - pointer to ccsipCCB_t of REG CCB. - * contact_info - Pointer to sipContact_t. - * - * Description: - * The function detects CCM just came up i.e. it sees the phone - * registration as a new registration. This means CCM has restarted - * between a REG refresh cycle. - * - * Note: - * CCM only sends x-cisco-newreg to the first REG that it sees - * from the phone as a new REG. If the phone has more than one lines, - * the REG of the rest of the lines will not have the x-cisco-newreg. - * - * Returns: - * TRUE - CCM restarted is detected. - * FALSE - CCM restarted is not detected. - */ -static boolean -ccsip_check_ccm_restarted (sipContact_t *contact_info) -{ - int i; - - if (contact_info == NULL) { - /* No contact info. */ - return (FALSE); - } - - for (i = 0; i < contact_info->num_locations; i++) { - if (contact_info->params[i].flags & SIP_CONTACT_PARM_X_CISCO_NEWREG) { - /* - * CCM or proxy just indicates that it sees the REG - * as a new registration to it. This means that the CCM or - * proxy has restarted. - */ - return (TRUE); - } - } - return (FALSE); -} - -/* - * Function: update_sis_protocol_version - * - * Parameters: - * response - 200 OK message pointer - * - * Description: - * The function parses theupported header in response and updates - * SIS protocol version received. If no version is received the default - * SEADRAGON version gets updated - * - * Returns: - * void - */ - -void -update_sis_protocol_version (sipMessage_t *response) -{ - const char *supported; - char * sipver; - supported = sippmh_get_cached_header_val(response, SUPPORTED); - if (supported != NULL) { - sipver = strcasestr(supported, REQ_SUPP_PARAM_CISCO_SISTAG); - if (sipver) { - cc_uint32_t major = SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON, minor = 0, addtnl = 0; - if ( sscanf ( &sipver[strlen(REQ_SUPP_PARAM_CISCO_SISTAG)], "%d.%d.%d", - &major, &minor, &addtnl) == 3) { - platSetSISProtocolVer ( major, minor, addtnl,REQ_SUPP_PARAM_CISCO_SISTAG); - return; - } - } - } - /* All other cases we set the version to 1.0.0 */ - platSetSISProtocolVer ( SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON, 0, 0,REQ_SUPP_PARAM_CISCO_SISTAG); -} - -void -update_cme_sis_version (sipMessage_t *response) -{ - const char *supported; - char * sipver; - - supported = sippmh_get_cached_header_val(response, SUPPORTED); - if (supported != NULL) { - sipver = strcasestr(supported, REQ_SUPP_PARAM_CISCO_CME_SISTAG); - if (sipver) { - cc_uint32_t major = 0, minor = 0, addtnl = 0; - if ( sscanf( &sipver[strlen(REQ_SUPP_PARAM_CISCO_CME_SISTAG)], "%d.%d.%d", - &major, &minor, &addtnl) ==3) { - platSetSISProtocolVer(major, minor, addtnl,REQ_SUPP_PARAM_CISCO_CME_SISTAG); - } - } - } -} - -void -ccsip_handle_ev_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_2xx"; - sipMessage_t *response = event->u.pSipMessage; - const char *pViaHeaderStr = NULL; - sipVia_t *via = NULL; - uint32_t exp_time; - //uint32_t line_feature; - int dns_err_code; - int nat_enable = 0; - int nat_rx_proc_enable = 0; - //int last_button_index =0; - const char *datehdr = NULL; - const char *contact = NULL; - const char *expires = NULL; - sipContact_t *contact_info = NULL; - //line_t line_index = 0; - //ccsipCCB_t *line_ccb = NULL; - - - // Extract Date header and store - datehdr = sippmh_get_header_val(response, SIP_HEADER_DATE, NULL); - if (datehdr) { - // Copy date header in a global variable since it would be needed - // to set system time - sstrncpy(ccm_date.datestring, datehdr, sizeof(ccm_date.datestring)); - ccm_date.valid = TRUE; - - // call ntp set time handler (TNP/cnu specific; stub for legacy) - // do not call the handler if 2xx is from StdBy CCM - // We do not need to set the time when in the browser - //if (ccb->index != REG_BACKUP_CCB) { - // SipNtpUpdateClockFromCCM(); - //} - } - - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact != NULL) { - /* There is a contact header pass it */ - contact_info = sippmh_parse_contact(contact); - } - - /* Update the sip interface protocol version */ - update_sis_protocol_version(response); - - /*update the CME for the version negotiation feature */ - update_cme_sis_version(response); - - if (ccb->dn_line == PRIMARY_LINE && ccsip_check_ccm_restarted(contact_info)) { - /* CCM has restarted detected */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Detected server has restarted via line %d", - DEB_F_PREFIX_ARGS(SIP_CCM_RESTART, fname), ccb->dn_line); - sip_regmgr_ccm_restarted(ccb); - } - - sip_stop_ack_timer(ccb); - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (ccb->send_reason_header) { - ccb->send_reason_header = FALSE; - sipUnregisterReason[0] = '\0'; - } - - /* - * Get expiration time. The expriation time are from contact info. or - * from the expire header. - */ - expires = sippmh_get_header_val(response, SIP_HEADER_EXPIRES, NULL); - if (ccsip_get_exp_time_2xx(ccb, contact_info, expires, &exp_time) - == FALSE) { - /* - * The expire time received in 200OK is smaller than the minimum - * allowed. The phone will be unregistered and a message will be - * displayed under the Status Messages. The phone will retry to - * register after the configured expire-timer interval. - */ - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, - sizeof(uint32_t)); - ccb->reg.tmr_expire = exp_time; - ccb->reg.act_time = (int) time(NULL); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_UNREGISTERING); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * 1000, - ccb->index); - if (contact_info != NULL) { - sippmh_free_contact(contact_info); - } - free_sip_message(response); - log_clear(LOG_REG_EXPIRE); - log_msg(LOG_REG_EXPIRE); - return; - } - - - ccb->reg.registered = 1; - sip_reg_sm_change_state(ccb, SIP_REG_STATE_REGISTERED); - regall_fail_attempt = FALSE; - - if (ccb->index != REG_BACKUP_CCB) { - registration_reject = FALSE; - ui_set_sip_registration_state(ccb->dn_line, TRUE); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Setting Reg state to TRUE for line=%d", - DEB_F_PREFIX_ARGS(SIP_REG_STATE, fname), ccb->dn_line); - /* Get supported options from the supported header from the response */ - sip_get_supported_options_2xx(ccb, response); - } else { - log_clear(LOG_REG_BACKUP); - } - - - if (contact_info != NULL) { - sippmh_free_contact(contact_info); - } - - ccb->reg.tmr_expire = exp_time; - - ccb->reg.act_time = (int) time(NULL); - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting expires timer (%d " - "sec)\n", DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), - ccb->reg.tmr_expire); - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * 1000, - ccb->index); - - - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - A 200 OK will reach here only if the state is - * REGISTERING, the unreg_200ok eve is handled - * separately. - */ - ti_config_table_t *ccm_table_ptr; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - if ((ccm_table_ptr == CCM_Active_Standby_Table.active_ccm_entry) && - start_standby_monitor) { - ccsipCCB_t *standby_ccb; - - start_standby_monitor = FALSE; - sip_platform_set_ccm_status(); - - /* - * Kickoff monitoring the standby - */ - - standby_ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (CCM_Active_Standby_Table.standby_ccm_entry) { - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, - &exp_time, sizeof(uint32_t)); - standby_ccb->reg.tmr_expire = exp_time; - standby_ccb->reg.act_time = (int) time(NULL); - sip_reg_sm_change_state(standby_ccb, - SIP_REG_STATE_UNREGISTERING); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, standby_ccb->index); - (void) sip_platform_register_expires_timer_start(standby_ccb->reg.tmr_expire * 1000, - standby_ccb->index); - } - } else if (ccm_table_ptr == - CCM_Active_Standby_Table.standby_ccm_entry) { - /* - * REGMGR - Update stats Got a 200OK for a expires 0 - * Keepalive msg to standby, update stats ? - */ - } - } - - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - config_get_value(CFGID_NAT_RECEIVED_PROCESSING, &nat_rx_proc_enable, - sizeof(nat_rx_proc_enable)); - if (nat_enable == 1 && nat_rx_proc_enable == 1) { - pViaHeaderStr = sippmh_get_cached_header_val(response, VIA); - if (pViaHeaderStr != NULL) { - via = sippmh_parse_via(pViaHeaderStr); - if (via != NULL) { - if (via->recd_host != NULL) { - cpr_ip_addr_t received_ip; - - memset(&received_ip, 0, sizeof(cpr_ip_addr_t)); - dns_err_code = dnsGetHostByName(via->recd_host, - &received_ip, 100, 1); - if (dns_err_code == 0) { - util_ntohl(&received_ip, &received_ip); - } else { - sip_config_get_nat_ipaddr(&received_ip); - } - - if (util_compare_ip(&received_ip, &(ccb->src_addr)) == FALSE) { - /* - * The address the proxy/registration server received - * is not the same as the one that we think we have - * so we'll update our address and re-register with - * the proxy/registration server - */ - - ccb->reg.rereg_pending = 1; - - // Make sure our running config has the correct - // IP address that we got from the proxy server - sip_config_set_nat_ipaddr(&received_ip); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - - // Update the tel ccb that this reg line belongs to - ccb = sip_sm_get_ccb_by_index((line_t)(ccb->index - REG_CCB_START + 1)); - if (ccb) { - ccb->src_addr = received_ip; - } - } - } - - // Cleanup memory - sippmh_free_via(via); - } - } - } - - free_sip_message(response); -} - -void -ccsip_handle_ev_3xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_3xx"; - sipMessage_t *response = NULL; - int status_code = 0; - char status[LOG_MAX_LEN]; - char user[MAX_LINE_NAME_SIZE]; - sipUrl_t *url; - const char *contact = NULL; - - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - free_sip_message(response); - return; - } - - switch (status_code) { - case SIP_RED_MULT_CHOICES /* 300 */: - case SIP_RED_MOVED_PERM /* 301 */: - case SIP_RED_MOVED_TEMP /* 302 */: - case SIP_RED_USE_PROXY /* 305 */: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP", status_code); - - sip_sm_200and300_update(ccb, response, status_code); - - /* - * Record the Contact header. For 3xx messages we are recording - * the Contact header here, not in the sipSPICheckResponse() header, - * so that the ACK response to 3xx is sent to the original INVITE - * destination (or to the Record-Route specified destination), rather - * than to the new 302 Contact - */ - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - - - /* - * Check the validity of Contact header - */ - if (!ccb->contact_info) { - CCSIP_DEBUG_ERROR("%s: Error: Invalid Contact field. Aborting " - "REGISTER.\n", fname); - free_sip_message(response); - ccsip_register_cleanup(ccb, TRUE); - return; - } - - if (ccb->contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - url = ccb->contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR("%s: Error: URL is not Sip. Aborting " - "REGISTER.\n", fname); - free_sip_message(response); - ccsip_register_cleanup(ccb, TRUE); - return; - } - - sstrncpy(ccb->reg.proxy, url->host, MAX_IPADDR_STR_LEN); - ccb->reg.port = url->port; - - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - - sip_util_get_new_call_id(ccb); - - /* - * Send out a new REGISTER - */ - ccb->authen.cred_type = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, - sizeof(user)); - - if (sipSPISendRegister(ccb, 0, user, ccb->reg.tmr_expire) != TRUE) { - ccsip_register_cleanup(ccb, TRUE); - free_sip_message(response); - - log_clear(LOG_REG_RED_MSG); - log_msg(LOG_REG_RED_MSG); - } - return; - - default: - free_sip_message(event->u.pSipMessage); - - snprintf(status, sizeof(status), "in %d, redirection", status_code); - log_clear(LOG_REG_UNSUPPORTED); - log_msg(LOG_REG_UNSUPPORTED, status); - - ccsip_register_cleanup(ccb, TRUE); - } -} - - -void -ccsip_handle_ev_4xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_4xx"; - sipMessage_t *response = NULL; - int status_code = 0; - const char *authenticate = NULL; - char user[MAX_LINE_NAME_SIZE]; - credentials_t credentials; - char status[LOG_MAX_LEN]; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - char uri[MAX_IPADDR_STR_LEN + 10]; /* Proxy IP address string */ - char tmp_str[STATUS_LINE_MAX_LEN]; - ti_config_table_t *ccm_table_ptr = NULL; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - free_sip_message(response); - return; - } - - /* - * Set reject flag if we get 4xx from publisher cucm. - * Note: if non-prime dn is congfigured with #, such as 1234##, - * then phone will get 404 for that DN, even though the prime DN is - * registered. - */ - if (ccm_table_ptr && - ccb->index != REG_BACKUP_CCB) { - DEF_DEBUG(DEB_F_PREFIX"Receive 4xx in ccm mode. set registration_reject to TRUE.", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - registration_reject = TRUE; - } - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP", status_code); - - if (cred_get_credentials_r(ccb, &credentials) == FALSE) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"no more credentials, retry %d, %d", - DEB_L_C_F_PREFIX_ARGS(SIP_CRED, ccb->index, ccb->dn_line, fname), - ccb->authen.retries_401_407, - MAX_RETRIES_401); - - - if (ccb->cc_type == CC_CCM) { - sip_regmgr_ev_failure_response(ccb, event); - free_sip_message(response); - return; - } - ccsip_register_cleanup(ccb, TRUE); - free_sip_message(response); - - log_clear(LOG_REG_AUTH_NO_CRED); - log_msg(LOG_REG_AUTH_NO_CRED); - - break; - } - - authenticate = sippmh_get_header_val(response, AUTH_HDR(status_code), - NULL); - if (authenticate) { - sip_authen = sippmh_parse_authenticate(authenticate); - } - - if (sip_authen) { - if (sip_authen->scheme == SIP_DIGEST) { - if (authenticate != NULL) { - ccb->retx_counter = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, - sizeof(user)); - ccb->authen.cnonce[0] = '\0'; - snprintf(uri, sizeof(uri), "sip:%s", ccb->reg.proxy); /* proxy */ - if (sipSPIGenerateAuthorizationResponse(sip_authen, uri, - SIP_METHOD_REGISTER, - credentials.id, - credentials.pw, - &author_str, - &(ccb->authen.nc_count), - ccb)) { - - if (author_str) { - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - - ccb->authen.authorization = - (char *) cpr_malloc(strlen(author_str) * - sizeof(char) + 1); - - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - ccb->authen.status_code = status_code; - } - cpr_free(author_str); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPIGenerateAuthorizationResponse"); - } - - if (!sipSPISendRegister(ccb, TRUE, user, - ccb->reg.tmr_expire)){ - ccsip_register_cleanup(ccb, TRUE); - - log_clear(LOG_REG_AUTH_MSG); - log_msg(LOG_REG_AUTH_MSG); - } - - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_authenticate"); - - ccsip_register_cleanup(ccb, TRUE); - log_clear(LOG_REG_AUTH_HDR_MSG); - log_msg(LOG_REG_AUTH_HDR_MSG); - } - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"auth scheme unsupported= %d", - DEB_F_PREFIX_ARGS(SIP_AUTH, fname), sip_authen->scheme); - - ccsip_register_cleanup(ccb, TRUE); - log_clear(LOG_REG_AUTH_SCH_MSG); - log_msg(LOG_REG_AUTH_SCH_MSG); - } - sippmh_free_authen(sip_authen); - } - - free_sip_message(response); - return; - - case SIP_CLI_ERR_INTERVAL_TOO_SMALL: - { - int new_expires = MAX_REG_EXPIRES; - const char *msg_ptr = NULL; - char line_name[MAX_LINE_NAME_SIZE]; - - msg_ptr = sippmh_get_header_val(response, - (const char *)SIP_HEADER_MIN_EXPIRES, - NULL); - if (msg_ptr) { - new_expires = strtoul(msg_ptr, NULL, 10); - } - - //ensure new Min-Expires is > what we set before in Expires - if (new_expires > ccb->reg.tmr_expire) { - ccb->reg.tmr_expire = new_expires; - } else { - ccb->reg.tmr_expire = MAX_REG_EXPIRES; - } - - //We have to make a fresh request - sip_stop_ack_timer(ccb); - sip_start_ack_timer(ccb); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - - sip_util_get_new_call_id(ccb); - - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - - ccb->reg.act_time = (int) time(NULL); - - if (sipSPISendRegister(ccb, 0, line_name, ccb->reg.tmr_expire) != TRUE) { - // set expire timer and cleanup ccb in non-ccm mode. - // do not change the expire timer value in ccm mode - - if (ccb->cc_type != CC_CCM) { - ccsip_register_cleanup(ccb, TRUE); - } - - log_clear(LOG_REG_MSG); - log_msg(LOG_REG_MSG); - } - - //no change in state - } - free_sip_message(response); - return; - - - /* - * 404 (Not Found) - * 413 (Request Entity Too Large) - * 480 (Temporarily Unavailable) - * 486 (Busy here) - */ - case SIP_CLI_ERR_NOT_FOUND: - case SIP_CLI_ERR_LARGE_MSG: - case SIP_CLI_ERR_NOT_AVAIL: - case SIP_CLI_ERR_BUSY_HERE: - if (ccb->cc_type == CC_CCM) { - if (ccb->state == (int) SIP_REG_STATE_TOKEN_WAIT) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - sip_regmgr_ev_token_wait_4xx_n_5xx(ccb, event); - } else { - /* - * Phone sends a REGISTER message with expires=0 as a - * Keepalive msg. Proxy and CCM will respond with a - * 200 OK. - */ - if (ccb->index != REG_BACKUP_CCB) { - if (ccsip_register_get_register_state() != SIP_REG_UNREGISTERING) { - if (((ti_config_table_t *)(ccb->cc_cfg_table_entry)) || - ccb->dn_line == PRIMARY_LINE) { - if (platGetPhraseText(STR_INDEX_REGISTRATION_REJECTED, - (char *)tmp_str, STATUS_LINE_MAX_LEN - 1)== CPR_SUCCESS) { - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, tmp_str, 15, FALSE, - DEF_NOTIFY_PRI); - } - } - log_clear(STR_INDEX_REGISTRATION_REJECTED); - log_msg(STR_INDEX_REGISTRATION_REJECTED); - } - } - if (process_retry_after(ccb, response) == FALSE) { - sip_regmgr_ev_failure_response(ccb, event); - } - } - } else { - if (process_retry_after(ccb, response) == FALSE) { - ccsip_register_cleanup(ccb, TRUE); - } - } - free_sip_message(response); - return; - - default: - if (ccb->cc_type == CC_CCM) { - if (ccb->state == (int) SIP_REG_STATE_TOKEN_WAIT) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - sip_regmgr_ev_token_wait_4xx_n_5xx(ccb, event); - } else { - sip_regmgr_ev_failure_response(ccb, event); - } - free_sip_message(response); - return; - } - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP BAD", status_code); - - snprintf(status, sizeof(status), "in %d, client error", status_code); - ccsip_register_cleanup(ccb, TRUE); - - snprintf(status, sizeof(status), "in %d, request failure", status_code); - log_clear(LOG_REG_UNSUPPORTED); - log_msg(LOG_REG_UNSUPPORTED, status); - free_sip_message(response); - break; - } - - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - - -void -ccsip_handle_ev_failure_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_failure_response"; - sipMessage_t *response = NULL; - int status_code = 0; - char status[LOG_MAX_LEN]; - sipStatusCodeClass_t code_class = codeClassInvalid; - ti_config_table_t *ccm_table_ptr = NULL; - - /* - * Set reject flag if we get 5xx/6xx from publisher cucm. - */ - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr && - ccb->index != REG_BACKUP_CCB) { - registration_reject = TRUE; - DEF_DEBUG(DEB_F_PREFIX"registration has been rejected. Set registration_reject to TRUE.", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - free_sip_message(response); - ccsip_register_cleanup(ccb, TRUE); - return; - } - - code_class = sippmh_get_code_class((uint16_t)status_code); - - log_clear(LOG_REG_AUTH); - - switch (code_class) { - case codeClass5xx: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_FAILURE), - ccb->index, ccb->dn_line, fname, status_code); - - log_msg(LOG_REG_AUTH_SERVER_ERR, status_code); - - break; - - case codeClass6xx: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_FAILURE), - ccb->index, ccb->dn_line, fname, status_code); - - log_msg(LOG_REG_AUTH_GLOBAL_ERR, status_code); - - break; - - default: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_FAILURE), - ccb->index, ccb->dn_line, fname, status_code); - - snprintf(status, sizeof(status), "in %d, ??? error", status_code); - log_msg(LOG_REG_AUTH_UNKN_ERR, status_code); - - break; - } - - if (ccb->cc_type == CC_CCM) { - if (ccb->state == (int) SIP_REG_STATE_TOKEN_WAIT) { - - /* Handle only 503 error condition for other errors - * use default state - */ - if (status_code == SIP_SERV_ERR_UNAVAIL) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - sip_regmgr_ev_token_wait_4xx_n_5xx(ccb, event); - free_sip_message(response); - } else { - sip_regmgr_ev_default(ccb, event); - } - return; - } - - /* retry registration using value in the Retry-After header - * if response code is 503 with Retry-After - */ - if ((status_code == SIP_SERV_ERR_UNAVAIL) && - (process_retry_after(ccb, response) == TRUE)) { - free_sip_message(response); - return; - } - /* - * regmgr - Pass the event to the regmgr - */ - sip_regmgr_ev_failure_response(ccb, event); - free_sip_message(response); - } else { - /* - * Assume CSPS for now - */ - - switch (status_code) { - - /* - * 500 (Server Internal Error) - * 503 (Service Unavailable) - * 600 (Busy), - * 603 (Declined - */ - case SIP_SERV_ERR_INTERNAL: - case SIP_SERV_ERR_UNAVAIL: - - case SIP_FAIL_BUSY: - case SIP_FAIL_DECLINE: - if (process_retry_after(ccb, response) == FALSE) { - ccsip_register_cleanup(ccb, TRUE); - } - free_sip_message(response); - return; - - default: - break; - } - ccsip_register_cleanup(ccb, TRUE); - free_sip_message(response); - - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - } -} - -/* - * ccsip_handle_ev_tmr_retry() - * - * This function is called when registration re-try timer - * pops or an ICMP unreachable is received after sending - * out the registration. The ICMP unreachable code sets the - * retx_counter to MAX to force the code to try the next - * proxy in the list. Event.u.usrInfo is set to the IP - * address that bounced or -1 if is a timeout. - */ -void -ccsip_handle_ev_tmr_retry (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_tmr_retry"; - boolean start_timer; - uint32_t value; - int dns_err_code = DNS_ERR_HOST_UNAVAIL; - cpr_ip_addr_t ip_addr; - - CPR_IP_ADDR_INIT(ip_addr); - - start_timer = (ccsip_register_get_register_state() == SIP_REG_UNREGISTERING) ? - (FALSE) : (TRUE); - - config_get_value(CFGID_SIP_RETX, &value, sizeof(value)); - if (value > MAX_NON_INVITE_RETRY_ATTEMPTS) { - value = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - if (ccb->retx_counter >= value) { - if (ccb->cc_type == CC_CCM /* RAMC Some other state */) { - /* - * regmgr - Send event to the regmgr - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Reached here for ccb->index=%d", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), ccb->index); - sip_regmgr_ev_tmr_ack_retry(ccb, event); - return; - } else { - /* - * Assume CSPS for now - */ - ccb->retx_counter = 0; - - /* - * Did the registration msg bounce trying to reach the outbound - * proxy (1st check) or did it timeout trying to reach the - * outbound proxy (2nd check)? - */ - util_ntohl(&ip_addr, &(event->u.UsrInfo)); - if (util_compare_ip(&ip_addr, &(ccb->outBoundProxyAddr)) || - ((event->u.UsrInfo.type == CPR_IP_ADDR_INVALID) && - util_check_if_ip_valid(&(ccb->outBoundProxyAddr)))) { - /* - * If there are more records, reset address to force code - * to use next entry. If not then bail. - */ - ccb->outBoundProxyPort = 0; - dns_err_code = DNS_OK; - - /* - * Trouble reaching the normal proxy. Get another proxy - * if records are available - */ - } else if (str2ip(ccb->reg.proxy, &ccb->reg.addr) != 0) { - dns_err_code = sipTransportGetServerAddrPort(ccb->reg.proxy, - &ccb->reg.addr, - (uint16_t *) &ccb->reg.port, - &ccb->SRVhandle, - TRUE); - if (dns_err_code == 0) { - util_ntohl(&(ccb->reg.addr), &(ccb->reg.addr)); - } else { - ccb->reg.addr = ip_addr_invalid; - } - - /* - * Modify destination fields in call back timer struct - */ - (void) sip_platform_msg_timer_update_destination(ccb->index, - &(ccb->reg.addr), - ccb->reg.port); - } else { - /* No other proxy to try */ - dns_err_code = DNS_ERR_HOST_UNAVAIL; - } - - /* - * Cleanup if unable to find another proxy - */ - if (dns_err_code != DNS_OK) { - /* - * All retransmit attempts have been exhausted. - * Cleanup the call and move to the IDLE state - */ - ccsip_register_cleanup(ccb, start_timer); - - log_clear(LOG_REG_RETRY); - log_msg(LOG_REG_RETRY); - if ((ccb->index == REG_BACKUP_CCB) && - (ccb->cc_type != CC_CCM)) { - log_clear(LOG_REG_BACKUP); - log_msg(LOG_REG_BACKUP); - } - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - - return; - } - } - } - - if (ccb->state != (int) SIP_REG_STATE_REGISTERED) { - /* - * Handling Retry timer in REGISTERED state is not needed - * the event has come due to race condition - */ - ccb->retx_counter++; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Resending message: #%d", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), ccb->retx_counter); - - if (sipSPISendLastMessage(ccb) != TRUE) { - if (ccb->cc_type == CC_CCM) { - sip_regmgr_ev_tmr_ack_retry(ccb, event); - } else { - ccsip_register_cleanup(ccb, start_timer); - } - return; - } - - ccsip_register_retry_timer_start(ccb); - } - -} - - -void -ccsip_handle_ev_reg_cancel (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - char user[MAX_LINE_NAME_SIZE]; - int exp_time = 0; - - ccsip_register_clear_all_logs(); - - sip_stop_ack_timer(ccb); - sip_start_ack_timer(ccb); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - - sip_util_get_new_call_id(ccb); - - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - - if (sipSPISendRegister(ccb, 0, user, exp_time) != TRUE) { - log_clear(LOG_REG_CANCEL_MSG); - log_msg(LOG_REG_CANCEL_MSG); - } else if ((ccb->index == REG_BACKUP_CCB) && (ccb->cc_type != CC_CCM)) { - log_clear(LOG_REG_BACKUP); - log_msg(LOG_REG_BACKUP); - } - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_UNREGISTERING); -} - - -void -ccsip_handle_ev_unreg_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_unreg_2xx"; - sipMessage_t *response = event->u.pSipMessage; - int timeout; - - free_sip_message(response); - - ccb->reg.registered = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (ccb->cc_type == CC_CCM) { - if (ccb->index == REG_BACKUP_CCB) { - /* - * Stay in unregistering state and wait for the - * expires timer to pop to send the next keepalive. - */ - sip_stop_ack_timer(ccb); - if (new_standby_available) { - sip_regmgr_replace_standby(ccb); - } - - timeout = sip_config_get_keepalive_expires(); - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Keep alive timer (%d sec)", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), timeout); - (void) sip_platform_standby_keepalive_timer_start(timeout * 1000); - } else { - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - sip_stop_ack_timer(ccb); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - /* - * regmgr - FALLBACK: Pick the ccb of the ccm that has - * come up (falling back) and post the fallback event, - * now that the unregistering is done. - * Will commit change after integration with ccm. - */ - } - platSetSISProtocolVer(1,0,0,NULL); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"set[1] the SIS protocol ver to 1.0.0", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - } else { - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - sip_stop_ack_timer(ccb); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - - /* - * Our unregistration from the proxy has succeeded now we - * can reregister again - */ - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - platSetSISProtocolVer(1,0,0,NULL); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"set[2] the SIS protocol ver to 1.0.0", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } -} - - -void -ccsip_handle_ev_unreg_tmr_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - log_clear(LOG_REG_AUTH_UNREG_TMR); - log_msg(LOG_REG_AUTH_UNREG_TMR); - - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - Send tmr ack event to the regmgr - */ - sip_regmgr_ev_tmr_ack_retry(ccb, event); - return; - } - ccsip_register_cleanup(ccb, FALSE); - /* - * We are unregistering ourselves from the proxy when our own registration - * timer has expired. This means that we do not need to complete our - * unregistration from the proxy since it is being done automatically. - * We can just send our new registration now - */ - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - -void -ccsip_handle_ev_standby_keepalive_tmr_expire (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - /* - * regmgr - If there is a fallback ccb in TOKEN_WAIT - * state waiting to fallback notify it so it can - * continue with the fallback procedure. - */ - if (ccb->cc_type == CC_CCM) { - /* - * REGMGR - CHECK if this event gets called. - * Will get in here only for REG_BACKUP_CCB in - * unregistering state i.e, the standby cc which - * is periodically monitored. - */ - /* - * Stay in unregistering state and post a message - * to send another keep-alive message. - */ - (void) sip_platform_standby_keepalive_timer_stop(); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - } else { - ccsip_handle_ev_default(ccb, event); - } -} - -int -sip_reg_sm_process_event (sipSMEvent_t *pEvent) -{ - static const char fname[] = "sip_reg_sm_process_event"; - ccsipCCB_t *ccb = NULL; - - ccb = pEvent->ccb; - if (!ccb) { - CCSIP_DEBUG_ERROR("%s: Error: ccb is null. Unable to process event " - "<%d>\n", fname, pEvent->type); - return (-1); - } - - /* Unbind UDP ICMP response handler */ - if ((REG_CHECK_EVENT_SANITY((int) ccb->state, (int) pEvent->type)) && - (REG_EVENT_ACTION(ccb->state, (int) pEvent->type))) { - if (dump_reg_msg == TRUE) { - DEF_DEBUG(DEB_L_C_F_PREFIX"%s <- %s", - DEB_L_C_F_PREFIX_ARGS(SIP_REG_STATE, ccb->dn_line, ccb->index, fname), - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - sip_util_reg_event2string((sipRegSMEventType_t)pEvent->type)); - } - REG_EVENT_ACTION(ccb->state, pEvent->type) (ccb, pEvent); - } else { - /* Invalid State/Event pair */ - CCSIP_DEBUG_ERROR("%s: Error: illegal state/event pair: (%d <-- %d)", - fname, ccb->state, pEvent->type); - return (-1); - } - - return (0); -} - - -const char * -sip_util_reg_event2string (sipRegSMEventType_t event) -{ - switch (event) { - case E_SIP_REG_REG_REQ: - return ("E_SIP_REG_REG_REQ"); - - case E_SIP_REG_CANCEL: - return ("E_SIP_REG_CANCEL"); - - case E_SIP_REG_1xx: - return ("E_SIP_REG_1xx"); - - case E_SIP_REG_2xx: - return ("E_SIP_REG_2xx"); - - case E_SIP_REG_3xx: - return ("E_SIP_REG_3xx"); - - case E_SIP_REG_4xx: - return ("E_SIP_REG_4xx"); - - case E_SIP_REG_FAILURE_RESPONSE: - return ("E_SIP_REG_FAILURE_RESPONSE"); - - case E_SIP_REG_TMR_EXPIRE: - return ("E_SIP_REG_TMR_EXPIRE"); - - case E_SIP_REG_TMR_ACK: - return ("E_SIP_REG_TMR_ACK"); - - case E_SIP_REG_TMR_WAIT: - return ("E_SIP_REG_TMR_WAIT"); - - case E_SIP_REG_TMR_RETRY: - return ("E_SIP_REG_TMR_RETRY"); - - case E_SIP_REG_CLEANUP: - return ("E_SIP_REG_CLEANUP"); - - default: - return ("SIP_REG_STATE_UNKNOWN"); - - } -} - - -char * -sip_util_reg_state2string (sipRegSMStateType_t state) -{ - switch (state) { - case SIP_REG_STATE_NONE: - return ("SIP_REG_STATE_NONE"); - - case SIP_REG_STATE_IDLE: - return ("SIP_REG_STATE_IDLE"); - - case SIP_REG_STATE_REGISTERING: - return ("SIP_REG_STATE_REGISTERING"); - - case SIP_REG_STATE_REGISTERED: - return ("SIP_REG_STATE_REGISTERED"); - - case SIP_REG_STATE_UNREGISTERING: - return ("SIP_REG_STATE_UNREGISTERING"); - - case SIP_REG_STATE_IN_FALLBACK: - return ("SIP_REG_STATE_IN_FALLBACK"); - - case SIP_REG_STATE_STABILITY_CHECK: - return ("SIP_REG_STATE_STABILITY_CHECK"); - - case SIP_REG_STATE_TOKEN_WAIT: - return ("SIP_REG_STATE_TOKEN_WAIT"); - - default: - return ("SIP_REG_STATE_UNKNOWN"); - - } -} - - -sipRegSMEventType_t -ccsip_register_sip2sipreg_event (int sip_event) -{ - static const char fname[] = "ccsip_register_sip2sipreg"; - sipRegSMEventType_t reg_event = E_SIP_REG_NONE; - - switch (sip_event) { - case E_SIP_1xx: - reg_event = E_SIP_REG_1xx; - break; - - case E_SIP_2xx: - reg_event = E_SIP_REG_2xx; - break; - - case E_SIP_3xx: - reg_event = E_SIP_REG_3xx; - break; - - case E_SIP_FAILURE_RESPONSE: - reg_event = E_SIP_REG_4xx; - break; - - default: - CCSIP_DEBUG_ERROR("%s: Error: Unknown event.", fname); - reg_event = E_SIP_REG_NONE; - break; - } - return (reg_event); -} - - -void -ccsip_register_timeout_retry (void *data) -{ - static const char fname[] = "ccsip_register_timeout_retry"; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - ccb = (ccsipCCB_t *) data; - if (ccb == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "ccsip_register_timeout_retry"); - return; - } - - if (ccsip_register_send_msg(SIP_TMR_REG_RETRY, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } -} - - -/* - * timer callback function - * - * The function will search for the line that set the timer and then - * (1) send expire event to sm or - * (2) set another 60s timer. The setting of another timer is necessary - * because the max ticks for an OS timer is 10m. The expire timer can - * be larger. Therefore, set x 1m timers and count down. - */ -int -ccsip_register_send_msg (uint32_t cmd, line_t ndx) -{ - static const char fname[] = "ccsip_register_send_msg"; - ccsip_registration_msg_t *register_msg; - ccsipCCB_t *ccb = NULL; - CCM_ID ccm_id = UNUSED_PARAM; - ti_config_table_t * cc_cfg_table; - - /* - * Get the ccm_id type from ccb corresponding to ndx. - * Currently, only SIP_TMR_REG_RETRY msg in SIPTaskProcessListEvent is - * making use of ccm_id field. No other reg msg make use of ccm_id. Also in - * case of SIP_REG_UPDATE, ccm_id will not be determined below but remain - * initialized to UNUSED_PARAM because, in case of SIP_REG_UPDATE, ndx is - * not ccb->index but number of available lines when lkem is attached. - */ - if (cmd != SIP_REG_UPDATE) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - cc_cfg_table = (ti_config_table_t *)(ccb->cc_cfg_table_entry); - if (cc_cfg_table != NULL) { - ccm_id = cc_cfg_table->ti_specific.ti_ccm.ccm_id; - } - else { - CCSIP_DEBUG_ERROR("%s: Error: cc_cfg_table is null.", fname); - return SIP_ERROR; - } - } - else { - CCSIP_DEBUG_ERROR("%s: Error: ccb is null.", fname); - return SIP_ERROR; - } - } - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cmd=%d=%s ccb->index=%d ccm_id=%s", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), - cmd, REG_CMD_PRINT(cmd), ndx, CCM_ID_PRINT(ccm_id)); - - register_msg = (ccsip_registration_msg_t *) - SIPTaskGetBuffer(sizeof(ccsip_registration_msg_t)); - - if (!register_msg) { - CCSIP_DEBUG_ERROR("%s: Error: get buffer failed.", fname); - return SIP_ERROR; - } - register_msg->ccb_index = ndx; - register_msg->ccm_id = ccm_id; - - if (SIPTaskSendMsg(cmd, register_msg, sizeof(ccsip_registration_msg_t), NULL) - == CPR_FAILURE) { - cpr_free(register_msg); - CCSIP_DEBUG_ERROR("%s: Error: send buffer failed.", fname); - return SIP_ERROR; - } - - return SIP_REG_OK; -} - -void -ccsip_register_retry_timer_start (ccsipCCB_t *ccb) -{ - static const char fname[] = "ccsip_register_retry_timer_start"; - int timeout; - int time_t1; - int time_t2; - - /* Double the timeout value and do exponential time increases - * The doubling is used because the invite timeout is too short - */ - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - timeout = time_t1 * (1 << ccb->retx_counter); - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting reTx timer (%d msec)", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), timeout); - - ccb->retx_flag = TRUE; - if (sip_platform_msg_timer_start(timeout, (void *)ccb, ccb->index, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipMethodRegister, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, - TRUE) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sip_platform_msg_timer_start"); - ccb->retx_flag = FALSE; - } -} - - -void -ccsip_register_cleanup (ccsipCCB_t *ccb, boolean start) -{ - static const char fname[] = "ccsip_register_cleanup"; - int exp_time; - - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, sizeof(exp_time)); - - ccb->reg.registered = 0; - - if (ccb->index != REG_BACKUP_CCB) { - ui_set_sip_registration_state(ccb->dn_line, FALSE); - } - - sip_stop_ack_timer(ccb); - - if ((start) && (ccb->state != (int) SIP_REG_STATE_UNREGISTERING)) { - if (ccb->index == REG_BACKUP_CCB) { - ccb->reg.tmr_expire = (exp_time > 5) ? exp_time - 5 : exp_time; - } else { - ccb->reg.tmr_expire = 60; - } - ccb->reg.act_time = (int) time(NULL); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Starting expires timer (%d " - "sec)\n", DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), - ccb->reg.tmr_expire); - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * 1000, - ccb->index); - } - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - - /* - * Always check how sip_sm_call_cleanup is implemented. - * The function has a tendency to change. - */ - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); -} - - -cc_int32_t -ccsip_register_cmd (cc_int32_t argc, const char *argv[]) -{ - /* - * On 7970 phones the command is reg line [option] [line] - * On 7940/60 the command is reg [option] [line] - * Thus the location in the argument array is different - * based on the phone type. OFFSET is used to get around - * this difference while still having common code. - */ -#define OFFSET 1 - ccsipCCB_t *ccb = NULL; - line_t ndx = 0; - line_t temp_line = 0; - char str_val[MAX_LINE_NAME_SIZE]; - const char *line_string; - char *strtol_end; - - /* - * check if need help - */ - if ((argc == 2 + OFFSET) && (argv[1 + OFFSET][0] == '?')) { - debugif_printf("reg [option] [line]\n"); - debugif_printf(" options = 0: unregister\n"); - debugif_printf(" 1: register\n"); - debugif_printf(" line = 1 through 6\n"); - debugif_printf(" = backup (line 1 to backup proxy)\n"); - debugif_printf("\n"); - return (0); - }else if (cpr_strcasecmp(argv[0 + OFFSET], "line") == 0) { - - /* - make sure the user entered a complete command - */ - if (argc < 3 + OFFSET) { - debugif_printf("Incomplete command\n"); - debugif_printf("reg [option] [line]\n"); - debugif_printf(" options = 0: unregister\n"); - debugif_printf(" 1: register\n"); - debugif_printf(" line = 1 through 6\n"); - debugif_printf(" = backup (line 1 to backup proxy)\n"); - debugif_printf("\n"); - return (0); - } - - /* make sure we have at least one line configured */ - config_get_line_string(CFGID_LINE_NAME, str_val, 1, sizeof(str_val)); - if ((strcmp(str_val, UNPROVISIONED) == 0) || (str_val[0] == '\0')) { - debugif_printf("Error:No lines configured\n"); - return (0); - } - - line_string = argv[2 + OFFSET]; - if (cpr_strcasecmp(line_string, "backup") == 0) { - temp_line = REG_BACKUP_LINE; - } else { - errno = 0; - temp_line = (line_t) strtol(line_string, &strtol_end, 10); - if (errno || line_string == strtol_end || !sip_config_check_line(temp_line)) { - debugif_printf("Error:Invalid Line\n"); - return (0); - } - } - - - ndx = SIP_REG_REGLINE2LINE(temp_line - 1); - ccb = sip_sm_get_ccb_by_index(ndx); - - if (ccb == NULL) { - debugif_printf("Unable to retrieve registration information for this line.\n"); - debugif_printf("Command aborted.\n"); - return (0); - } - - if ((temp_line == REG_BACKUP_LINE) && util_check_if_ip_valid(&(ccb->dest_sip_addr)) == FALSE) { - debugif_printf("Backup Proxy is invalid or not configured.\n"); - return (0); - } - - switch (argv[1 + OFFSET][0]) { - case '0': - - if (ccb->index != REG_BACKUP_CCB) { - ui_set_sip_registration_state(ccb->dn_line, FALSE); - } - - if (temp_line != REG_BACKUP_LINE) { - debugif_printf("Unregistering line %d\n", temp_line); - } else { - debugif_printf("Unregistering line 1 to backup proxy\n"); - } - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - break; - - case '1': - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - if (temp_line != REG_BACKUP_LINE) { - debugif_printf("Registering line %d\n", temp_line); - } else { - debugif_printf("Registering line 1 to backup proxy\n"); - } - (void) ccsip_register_send_msg(SIP_REG_REQ, ndx); - break; - - default: - debugif_printf("Invalid Option Value - please choose 1 or 0\n"); - return (0); - } - } - return (0); -} - -/* - * Function: build_reg_flags - * - * Parameters: - * - * Description: builds a 3 character string representing various flags - * for use by the show_reg command - * - * Returns: none - * - */ -static void -build_reg_flags (char *buf, int buf_size, int prox_reg, ccsipCCB_t *ccb, - boolean provisioned) -{ - sstrncpy(buf, "...", buf_size); - if (!provisioned || !prox_reg) { - return; - } - - buf[1] = '1'; // Set the Provisioned bit - - if (ccb->authen.authorization != NULL) { - buf[0] = '1'; - } else { - if (ccb->authen.status_code != 0) { - buf[0] = 'x'; - } - } - if (ccb->reg.registered) { - buf[2] = '1'; - } else { - buf[2] = 'x'; - } -} - -/* - * Function: show_register_data - * - * Parameters: - * - * Description: Internal print routine for show_register_cmd. Also - * called by reg command - * - * Returns: - * - */ -#define TMP_BUF_SIZE 8 -static void -show_register_data (void) -{ - ccsipCCB_t *ccb; - char buf[TMP_BUF_SIZE]; - line_t ndx = 0; - int proxy_register = 0; - boolean valid_line = FALSE; - int timer_count_down = 0; - - config_get_value(CFGID_PROXY_REGISTER, &proxy_register, - sizeof(proxy_register)); - - debugif_printf("\nLINE REGISTRATION TABLE\nProxy Registration: "); - if (proxy_register == 1) { - debugif_printf("ENABLED"); - } else { - debugif_printf("DISABLED"); - } - debugif_printf(", state: %s\n", - ccsip_register_state_name(ccsip_register_get_register_state())); - debugif_printf("line APR state timer expires proxy:port\n"); - debugif_printf("---- --- ------------- ---------- ---------- ----------------------------\n"); - for (ndx = REG_CCB_START; ndx <= REG_BACKUP_CCB; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - valid_line = FALSE; - if (ndx == REG_BACKUP_CCB) { - valid_line = TRUE; - } else { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - valid_line = TRUE; - } - } - // calc the time until registration expires - if (ccb && valid_line) { - if (!proxy_register || !valid_line) { - timer_count_down = 0; - } else { - if (ccb->reg.act_time == 0) { - timer_count_down = 0; - } else if ((sipRegSMStateType_t)ccb->state == - SIP_REG_STATE_REGISTERING) { - timer_count_down = - (SIP_REG_TMR_ACK_TICKS / 1000) - - (((int) time(NULL)) - ccb->reg.act_time); - } else { - timer_count_down = ccb->reg.tmr_expire - - (((int) time(NULL)) - ccb->reg.act_time); - } - } - - /* - * Ensure that the timer_count_down value is valid. There - * are cases where the phone completes registration before an - * SNTP/NTP response is received which makes the act_time and - * time(NULL) values inconsistent. - */ - if ((timer_count_down < 0) || - (timer_count_down > ccb->reg.tmr_expire)) { - - timer_count_down = 0; - } - } - - // build the flag string - if (ccb) { - build_reg_flags((char *)&buf, TMP_BUF_SIZE, proxy_register, - ccb, valid_line); - } - - if (ndx != REG_BACKUP_CCB) { - debugif_printf("%-4d", ndx - TEL_CCB_END); - } else { - debugif_printf("1-BU"); - } - if (ccb && valid_line) { - debugif_printf(" %-3s %-13s %-10d %-10d %s:%d\n", - buf, - ccsip_register_reg_state_name((sipRegSMStateType_t)ccb->state), - ccb->reg.tmr_expire, - timer_count_down, - ((ccb->reg.proxy[0] != '\0') ? (ccb->reg.proxy) : ("undefined")), - ccb->reg.port); - } else { - debugif_printf(" %-3s %-13s %-10d %-10d %s:%d\n", - buf, "NONE", 0, 0, "undefined", 0); - } - } - debugif_printf("\nNote: APR is Authenticated, Provisioned, Registered\n"); -} - -/* - * Function: show_register_cmd - * - * Parameters: argc,argv - * - * Description: Shows the current registration table - * - * Returns: - * - */ -cc_int32_t -show_register_cmd (cc_int32_t argc, const char *argv[]) -{ - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("sh reg\n"); - return (0); - } - show_register_data(); - - return (0); -} - -void -ccsip_register_clear_all_logs (void) -{ - log_clear(LOG_REG_MSG); - log_clear(LOG_REG_AUTH); - log_clear(LOG_REG_RETRY); - log_clear(LOG_REG_UNSUPPORTED); -} - - -void -ccsip_register_reset_proxy (void) -{ - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - /* - * If this is a restart (phone is resetting) then reset the proxy - * string for each line. The proxy string is used to determine - * what address to use when registering. The proxy remains the - * same throughout a boot cycle and on restarts there is a new - * boot cycle so the proxy address is reset. - */ - line_end = 1; - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - //ccsip_register_lines = line_end - REG_CCB_START + 1; - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb) { - ccb->reg.proxy[0] = '\0'; - } - } - } - - //reset backup proxy registration; - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (ccb) { - ccb->reg.proxy[0] = '\0'; - } -} - -int -ccsip_register_init (void) -{ - static const char fname[] = "ccsip_register_init"; - static const char sipAckTimerName[] = "sipAck"; - int i; - - ccsip_register_set_register_state(SIP_REG_IDLE); - - /* - * Create acknowledgement timers - */ - for (i = 0; i < MAX_REG_LINES + 1; i++) { - ack_tmrs[i] = cprCreateTimer(sipAckTimerName, SIP_ACK_TIMER, - TIMER_EXPIRATION, sip_msgq); - if (ack_tmrs[i] == NULL) { - CCSIP_DEBUG_ERROR("%s: timer NOT created: %d", - fname, i); - return SIP_ERROR; - } - } - - // Initialize date holder structure - ccm_date.valid = FALSE; - ccm_date.datestring[0] = '\0'; - start_standby_monitor = TRUE; - - return SIP_OK; -} - - -ccsip_register_states_t -ccsip_register_get_register_state (void) -{ - return (ccsip_register_state); -} - - -void -ccsip_register_set_register_state (ccsip_register_states_t state) -{ - ccsip_register_state = state; -} - -void -ccsip_register_cancel (boolean cancel_reg, boolean backup_proxy) -{ - static const char fname[] = "ccsip_register_cancel"; - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - if (ccsip_register_get_register_state() == SIP_REG_IDLE) { - return; - } - - ccsip_register_set_register_state(SIP_REG_UNREGISTERING); - - line_end = 1; - - ui_set_sip_registration_state((line_t) (line_end + 1), FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"unregistering %d lines", DEB_F_PREFIX_ARGS(SIP_REG, fname), line_end); - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t) (ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!ccb) { - continue; - } - ui_set_sip_registration_state(ccb->dn_line, FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), ccb->index); - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - - if (cancel_reg) { - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ndx) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - - } else { - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - if (ndx == line_end) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - } - } - } - - if (backup_proxy == FALSE) { - return; - } - - /* cancel backup registration as well */ - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), ccb->index); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - - if (cancel_reg) { - if (ccsip_register_send_msg(SIP_REG_CANCEL, REG_BACKUP_CCB) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - } else { - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - } -} - - -void -ccsip_register_all_lines (void) -{ - static const char fname[] = "ccsip_register_all_lines"; - ccsipCCB_t *ccb = 0; - line_t ndx; - line_t line; - line_t line_end = 1; - int value = 0; - char proxyaddress[MAX_IPADDR_STR_LEN]; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - /* Do not register if - * - no need to register - * - and already registered - */ - - line_end = 1; - config_get_value(CFGID_PROXY_REGISTER, &value, sizeof(value)); - if (value == 0) { - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_REG_DISABLED), NULL, - NULL, fname); - - // mark all unregistered - for (line = 1; line <= line_end; line++) { - if (sip_config_check_line(line)) { - ui_set_sip_registration_state(line, FALSE); - } - } - ccsip_register_reset_proxy(); - return; - } else if (ccsip_register_get_register_state() == SIP_REG_REGISTERED) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"lines already registered", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - return; - } - - - ccsip_register_reset_proxy(); - ccsip_register_set_register_state(SIP_REG_REGISTERING); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"registering %d line%c", - DEB_F_PREFIX_ARGS(SIP_REG, fname), line_end, line_end > 1 ? 's' : ' '); - - /* register line 1 to the backup proxy. - * Start with the backup as DNS lookups hold - * the task meaning it could take a while to - * register the six regular lines. - */ - ndx = REG_BACKUP_CCB; - ccb = sip_sm_get_ccb_by_index(ndx); - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - Set the Backup (standby ccm) info. - */ - ti_config_table_t *standby_ccm = - CCM_Active_Standby_Table.standby_ccm_entry; - - if (standby_ccm) { - ti_ccm_t *ti_ccm = &standby_ccm->ti_specific.ti_ccm; - - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ERROR: Standby ccm entry is NULL", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - } else { - /* - * Assume CSPS since only those two for now. - */ - if (util_check_if_ip_valid(&(ccb->dest_sip_addr))) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, %p", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } else { - ccb->send_reason_header = FALSE; - } - - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } else { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d: Backup Proxy not configured", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), ndx); - } - } - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END to - * get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - DEF_DEBUG(DEB_F_PREFIX"Disabling mass reg state", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!ccb) { - continue; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, %p", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - - - /* - * Clean up and re-initialize the proxy address. - * It is possible that the REGISTER can be redirected - * and this address needs to be reused for later register attempts. - * But, on restarts and re-enabling of registering we reset back - * to the original configured proxy - */ - if (ndx == REG_CCB_START || ndx == (line_end)) { - g_disable_mass_reg_debug_print = FALSE; - } else { - g_disable_mass_reg_debug_print = TRUE; - } - sip_sm_call_cleanup(ccb); - - /* - * Look up the name of the proxy - */ - sipTransportGetPrimServerAddress(ccb->dn_line, proxyaddress); - - sstrncpy(ccb->reg.proxy, proxyaddress, MAX_IPADDR_STR_LEN); - - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } else { - ccb->send_reason_header = FALSE; - } - - ui_set_sip_registration_state(ccb->dn_line, FALSE); - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - - } - } - g_disable_mass_reg_debug_print = FALSE; - - sip_platform_cc_mode_notify(); -} - - -boolean -ccsip_register_all_registered (void) -{ - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - line_end = 1; - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - - if (ccb && (ccb->reg.registered == 0)) { - return (FALSE); - } - } - } - return (TRUE); -} - - -boolean -ccsip_register_all_unregistered (void) -{ - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - line_end = 1; - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 0 and 1 and REG CCBs are at 6 and 7. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - - if (ccb && (ccb->reg.registered == 1)) { - return (FALSE); - } - } - } - return (TRUE); -} - - -void -ccsip_register_commit (void) -{ - static const char fname[] = "ccsip_register_commit"; - int register_get; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - /* - * Determine if lines need to register or unregister - * - * register if - * - proxy_register was changed from 0 to 1 - * - * unregister if - * - proxy_register was changed from 1 to 0 and already registered - */ - config_get_value(CFGID_PROXY_REGISTER, ®ister_get, - sizeof(register_get)); - - switch (register_get) { - case 0: - if (ccsip_register_get_register_state() != SIP_REG_IDLE) { - ccsip_register_cancel(TRUE, TRUE); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"lines already unregistered.", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - - break; - - case 1: - if (ccsip_register_get_register_state() != SIP_REG_REGISTERED) { - ccsip_register_cancel(FALSE, TRUE); - ccsip_register_all_lines(); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"lines already registered.", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - break; - - default: - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Error: invalid register_get= %d", DEB_F_PREFIX_ARGS(SIP_REG, fname), - register_get); - } -} - -void -ccsip_backup_register_commit (void) -{ - static const char fname[] = "ccsip_backup_register_commit"; - line_t ndx; - ccsipCCB_t *ccb = 0; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - ndx = REG_BACKUP_CCB; - ccb = sip_sm_get_ccb_by_index(ndx); - - /* cancel an existing registration if it exists */ - if (util_check_if_ip_valid(&(ccb->reg.addr))) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling registration, line= %d", - DEB_F_PREFIX_ARGS(SIP_REG, fname), ccb->index); - if (ccsip_register_send_msg(SIP_REG_CANCEL, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - } - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - if (util_check_if_ip_valid(&(ccb->dest_sip_addr))) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, %p", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } else { - log_clear(LOG_REG_BACKUP); - } -} - - -void -cred_get_line_credentials (line_t line, credentials_t *pcredentials, - int id_len, int pw_len) -{ - config_get_line_string(CFGID_LINE_AUTHNAME, pcredentials->id, line, - id_len); - - if ((strcmp(pcredentials->id, "") == 0) || - (strcmp(pcredentials->id, UNPROVISIONED) == 0)) { - config_get_line_string((CFGID_LINE_AUTHNAME), pcredentials->id, 1, - id_len); - } - - config_get_line_string(CFGID_LINE_PASSWORD, pcredentials->pw, line, - pw_len); - if ((strcmp(pcredentials->pw, "") == 0) || - (strcmp(pcredentials->pw, UNPROVISIONED) == 0)) { - config_get_line_string(CFGID_LINE_PASSWORD, pcredentials->pw, 1, - pw_len); - } -} - - -boolean -cred_get_credentials_r (ccsipCCB_t *ccb, credentials_t *pcredentials) -{ - if (!(ccb->authen.cred_type & CRED_LINE) || - (ccb->authen.retries_401_407 < MAX_RETRIES_401)) { - ccb->authen.cred_type |= CRED_LINE; - ccb->authen.retries_401_407++; - cred_get_line_credentials(ccb->dn_line, pcredentials, - sizeof(pcredentials->id), - sizeof(pcredentials->pw)); - return (TRUE); - } - - return (FALSE); -} - - -const char * -ccsip_register_state_name (ccsip_register_states_t state) -{ - if ((state < SIP_REG_IDLE) || (state >= SIP_REG_NO_REGISTER)) { - return ("UNDEFINED"); - } - - return (ccsip_register_state_names[state]); -} - - -const char * -ccsip_register_reg_state_name (sipRegSMStateType_t state) -{ - if ((state < SIP_REG_STATE_NONE) || (state >= SIP_REG_STATE_UNREGISTERING)) { - return ("UNDEFINED"); - } - - return (ccsip_register_reg_state_names[state]); -} - -void -ccsip_register_shutdown () -{ - int i; - - for (i = 0; i < MAX_REG_LINES + 1; i++) { - (void) cprCancelTimer(ack_tmrs[i]); - (void) cprDestroyTimer(ack_tmrs[i]); - ack_tmrs[i] = NULL; - } -} - -boolean -ccsip_get_ccm_date (char *date_value) -{ - if (date_value) { - if (ccm_date.valid) { - sstrncpy(date_value, ccm_date.datestring, - sizeof(ccm_date.datestring)); - return (TRUE); - } else { - date_value[0] = '\0'; - } - } - return (FALSE); -} - -/* - * Function: ccsip_is_line_registered - * - * Parameters: - * dn_line - line number. - * - * Description: The function determines whether the current line - * is registered or not. - * - * Returns: - * TRUE if the line is registered. - * FALSE if the line is not registered or the given line is invalid. - * - */ -boolean -ccsip_is_line_registered (line_t dn_line) -{ - line_t ndx; - line_t line_end; - ccsipCCB_t *ccb; - - /* Get the number of lines configured */ - line_end = 1; - /* - * REG CCBs start after the TEL CCBs. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - if ((ccb != NULL) && (ccb->dn_line == dn_line)) { - /* found the requested REG ccb */ - if (ccb->state == (int) SIP_REG_STATE_REGISTERED) { - return (TRUE); - } else { - /* the line is not in registered state */ - break; - } - } - } - - /* Found no matching REG ccb or the line is not in registered state */ - return (FALSE); -} - -/* - * Function: process_retry_after - * - * Parameters: - * ccsipCCB_t *ccb - The reg ccb. - * sipMessage_t *response - The received response. - * - * Description: The function processes the Retry-After header that may - * be present in the response. - * - * Returns: - * TRUE if a valid Retry-After header was present and processed correctly. - * FALSE if a valid Retry-After header was not present and therefore - * was not processed. - * - */ -boolean -process_retry_after (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *msg_ptr = NULL; - int32_t retry_after = 0; - static const char fname[] = "process_retry_after"; - - msg_ptr = sippmh_get_header_val(response, - (const char *)SIP_HEADER_RETRY_AFTER, - NULL); - - if (msg_ptr) { - retry_after = strtoul(msg_ptr, NULL, 10); - - } else { - return (FALSE); - } - - if (retry_after > 0) { - sip_stop_ack_timer(ccb); - (void) sip_platform_register_expires_timer_start(retry_after * 1000, - ccb->index); - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Retrying after %d", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), retry_after); - return (TRUE); - } else { - CCSIP_DEBUG_ERROR("REG %d/%d: %-35s: Error: invalid Retry-After " - "header in response.\n", - ccb->index, ccb->dn_line, fname); - return (FALSE); - } -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_reldev.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_reldev.c deleted file mode 100644 index eb435f46014..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_reldev.c +++ /dev/null @@ -1,284 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_string.h" -#include "ccsip_reldev.h" -#include "ccsip_macros.h" -#include "phone_debug.h" -#include "ccsip_pmh.h" -#include "ccsip_messaging.h" -#include "sip_common_transport.h" -#include "util_string.h" - -/* Constants */ -#define SIP_RRLIST_LENGTH (MAX_TEL_LINES) - -/* Global variables */ -sipRelDevMessageRecord_t gSIPRRList[SIP_RRLIST_LENGTH]; - - -void -sipRelDevMessageStore (sipRelDevMessageRecord_t * pMessageRecord) -{ - static int counter = 0; - - /* Loop around */ - if (counter > (SIP_RRLIST_LENGTH - 1)) { - counter = 0; - } - - gSIPRRList[counter] = *pMessageRecord; - gSIPRRList[counter].valid_coupled_message = FALSE; - counter++; -} - - -boolean -sipRelDevMessageIsDuplicate (sipRelDevMessageRecord_t *pMessageRecord, - int *idx) -{ - int i = 0; - - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - if ((strcmp(pMessageRecord->call_id, gSIPRRList[i].call_id) == 0) && - (pMessageRecord->cseq_number == gSIPRRList[i].cseq_number) && - (pMessageRecord->cseq_method == gSIPRRList[i].cseq_method) && - (strcasecmp_ignorewhitespace(pMessageRecord->tag, gSIPRRList[i].tag) == 0) && - (strcmp(pMessageRecord->from_user, gSIPRRList[i].from_user) == 0) && - (strcmp(pMessageRecord->from_host, gSIPRRList[i].from_host) == 0) && - (strcmp(pMessageRecord->to_user, gSIPRRList[i].to_user) == 0)) { - - if (pMessageRecord->is_request) { - *idx = i; - return (TRUE); - } else { - if (pMessageRecord->response_code == gSIPRRList[i].response_code) { - *idx = i; - return (TRUE); - } - } - } - } - - *idx = -1; - return (FALSE); -} - - -/* - * Function: sipRelDevCoupledMessageStore - * - * Parameters: - * pCoupledMessage - pointer to sipMessage_t for the message that - * needed reliable delivery store. - * call_id - pointer to const. char for the SIP call ID. - * cseq_number - the uint32_t for CSeq of the message. - * sipMethod_t - sipMethod_t the SIP method of the message. - * dest_ipaddr - uint32_t IP address of the destination address. - * dest_port - uint16_t destination port - * ignore_tag - boolean to ignore tag. - * - * Description: - * The function finds the corresponding entry in the gSIPRRList - * array that matches call_id, cseq number, method and possibly tag. - * If a match entry is found, the SIP message is composed and stored - * in the corresponding entry. - * - * Returns: - * idx - When the entry is found and successfully stored the - * SIP message. - * RELDEV_NO_STORED_MSG - encounter errors or no message is - * stored. - */ -int -sipRelDevCoupledMessageStore (sipMessage_t *pCoupledMessage, - const char *call_id, - uint32_t cseq_number, - sipMethod_t cseq_method, - boolean is_request, - int response_code, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - boolean ignore_tag) -{ - static const char *fname = "sipRelDevCoupledMessageStore"; - int i = 0; - char to_tag[MAX_SIP_TAG_LENGTH]; - - sipGetMessageToTag(pCoupledMessage, to_tag, MAX_SIP_TAG_LENGTH); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Storing for reTx (cseq=%d, method=%s, " - "to_tag=<%s>)\n", DEB_F_PREFIX_ARGS(SIP_STORE, fname), cseq_number, - sipGetMethodString(cseq_method), to_tag); - - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - if ((strcmp(call_id, gSIPRRList[i].call_id) == 0) && - (cseq_number == gSIPRRList[i].cseq_number) && - (cseq_method == gSIPRRList[i].cseq_method) && - ((ignore_tag) ? TRUE : (strcasecmp_ignorewhitespace(to_tag, - gSIPRRList[i].tag) - == 0))) { - hStatus_t sippmh_write_status = STATUS_FAILURE; - uint32_t nbytes = SIP_UDP_MESSAGE_SIZE; - - /* - When storing the ACK message check that you are storing it - coupled with the correct response code and not transitional responses - */ - if (is_request == FALSE || - (is_request == TRUE && gSIPRRList[i].response_code == response_code)) { - gSIPRRList[i].coupled_message.message_buf[0] = '\0'; - sippmh_write_status = - sippmh_write(pCoupledMessage, - gSIPRRList[i].coupled_message.message_buf, - &nbytes); - if (sippmh_write_status == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() failed.", fname); - return (RELDEV_NO_STORED_MSG); - } - if ((gSIPRRList[i].coupled_message.message_buf[0] == '\0') || - (nbytes == 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() returned empty buffer string.", - fname); - return (RELDEV_NO_STORED_MSG); - } - gSIPRRList[i].coupled_message.message_buf_len = nbytes; - gSIPRRList[i].coupled_message.dest_ipaddr = *dest_ipaddr; - gSIPRRList[i].coupled_message.dest_port = dest_port; - gSIPRRList[i].valid_coupled_message = TRUE; - /* Return the stored idx to the caller */ - return (i); - } - } - } - return (RELDEV_NO_STORED_MSG); -} - -/* - * Function: sipRelDevGetStoredCoupledMessage - * - * Parameters: - * idx - int for the idx to retrieve stored SIP message. - * dest_buffer - pointer to char to retrieve the copy of the - * stored SIP message. - * dest_buf_size - uint32_t for the size of the dest_buffer. - * - * Description: - * The function gets the stored SIP message for the request entry. - * - * Returns: - * The function returns the number of the bytes of the SIP message - * obtained if SIP message is found otherwise it returns zero ( - * no SIP message available). - */ -uint32_t -sipRelDevGetStoredCoupledMessage (int idx, - char *dest_buffer, - uint32_t dest_buf_size) -{ - sipRelDevMessageRecord_t *record; - - if (dest_buffer == NULL) { - /* No destination buffer given, can not provide any result */ - return (0); - } - if ((idx < 0) || (idx >= SIP_RRLIST_LENGTH)) { - /* the stored message is out of range */ - return (0); - } - - record = &gSIPRRList[idx]; - - if (!record->valid_coupled_message) { - /* No message stored for the given idx */ - return (0); - } - if ((record->coupled_message.message_buf_len > dest_buf_size) || - (record->coupled_message.message_buf_len == 0)) { - /* - * The stored message size is larger than the give buffer or - * stored message length is zero? - */ - return (0); - } - /* Get the stored message to the caller */ - memcpy(dest_buffer, &record->coupled_message.message_buf[0], - record->coupled_message.message_buf_len); - return (record->coupled_message.message_buf_len); -} - -int -sipRelDevCoupledMessageSend (int idx) -{ - static const char *fname = "sipRelDevCoupledMessageSend"; - char dest_ipaddr_str[MAX_IPADDR_STR_LEN]; - - if ((idx < 0) || (idx >= SIP_RRLIST_LENGTH)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Argument Check: idx (=%d) out of bounds.", - fname, idx); - return SIP_ERROR; - } - - if (gSIPRRList[idx].valid_coupled_message) { - ipaddr2dotted(dest_ipaddr_str, - &gSIPRRList[idx].coupled_message.dest_ipaddr); - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Sending stored coupled message (idx=%d) to " - "<%s>:<%d>\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), idx, dest_ipaddr_str, - gSIPRRList[idx].coupled_message.dest_port); - if (sipTransportChannelSend(NULL, - gSIPRRList[idx].coupled_message.message_buf, - gSIPRRList[idx].coupled_message.message_buf_len, - sipMethodInvalid, - &(gSIPRRList[idx].coupled_message.dest_ipaddr), - gSIPRRList[idx].coupled_message.dest_port, - 0) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipTransportChannelSend() failed." - " Stored message not sent.\n", fname); - return SIP_ERROR; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Duplicate message detected but failed to" - " find valid coupled message. Stored message not sent.\n", - fname); - return SIP_ERROR; - } - return SIP_OK; -} - - -/* - * Function for clearing all the messages belonging to the - * associated with the specified call_id, from_user, from_host, - * and to_user - */ -void -sipRelDevMessagesClear (const char *call_id, - const char *from_user, - const char *from_host, - const char *to_user) -{ - int i = 0; - - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - if ((strcmp(call_id, gSIPRRList[i].call_id) == 0) && - (strcmp(from_user, gSIPRRList[i].from_user) == 0) && - (strcmp(from_host, gSIPRRList[i].from_host) == 0) && - (strcmp(to_user, gSIPRRList[i].to_user) == 0)) { - memset(&gSIPRRList[i], 0, sizeof(sipRelDevMessageRecord_t)); - } - } - return; -} - -/* - * Function for clearing all the messages - */ -void sipRelDevAllMessagesClear(){ - int i = 0; - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - memset(&gSIPRRList[i], 0, sizeof(sipRelDevMessageRecord_t)); - } - return; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c deleted file mode 100644 index e0263d64fed..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c +++ /dev/null @@ -1,358 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Implements functions to parse and create SDP(Session Description Protocol) - * (RFC 2327) messages. Coded to be sufficient for SIP only. - * Note: The SDP body fields as per the RFC are : - * Optional items are marked with a `*'. - * - * Session description - * v= (protocol version) - * o= (owner/creator and session identifier). - * s= (session name) - * i=* (session information) - * u=* (URI of description) - * e=* (email address) - * p=* (phone number) - * c=* (connection information - not required if included in all media) - * b=* (bandwidth information) - * One or more time descriptions (see below) - * z=* (time zone adjustments) - * k=* (encryption key) - * a=* (zero or more session attribute lines) - * Zero or more media descriptions (see below) - * - *Time description - * t= (time the session is active) - * r=* (zero or more repeat times) - * - *Media description - * m= (media name and transport address) - * i=* (media title) - * c=* (connection information - optional if included at session-level) - * b=* (bandwidth information) - * k=* (encryption key) - * a=* (zero or more media attribute lines) - * - * Note that the mandatory fields are : - * v= , o=, s=, t=, m= - * Email address and phone number (e=, p=) fields would very soon be useful - * to SDP in large scale SIP networks. - * - * t= 0 0 - * would indicate an unbound or a permanent session . This would be changed - * to specific (or probably user-configured values) once the time duration - * of SIP call sessions are recorded and are used for scheduling. - */ - - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "sdp.h" -#include "text_strings.h" -#include "ccsip_sdp.h" -#include "ccsip_core.h" -#include "phone_debug.h" - - -/* - * sip_sdp_init - * - * This function initializes SDP parser with SIP-specific parameters. - * This includes supported media, network types, address types, - * transports and codecs. - * - * The function must be called once. - * - * Returns a pointer to the SDP configuration profile, or NULL on failure. - */ -static void * -sip_sdp_init (void) -{ - void *sdp_config; - - sdp_config = sdp_init_config(); - - if (sdp_config) { - sdp_media_supported(sdp_config, SDP_MEDIA_AUDIO, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_VIDEO, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_APPLICATION, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_DATA, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_CONTROL, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_NAS_RADIUS, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_NAS_TACACS, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_NAS_DIAMETER, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_NAS_L2TP, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_NAS_LOGIN, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_NAS_NONE, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_IMAGE, TRUE); - sdp_media_supported(sdp_config, SDP_MEDIA_TEXT, TRUE); - sdp_nettype_supported(sdp_config, SDP_NT_INTERNET, TRUE); - sdp_addrtype_supported(sdp_config, SDP_AT_IP4, TRUE); - sdp_addrtype_supported(sdp_config, SDP_AT_IP6, TRUE); - sdp_transport_supported(sdp_config, SDP_TRANSPORT_RTPAVP, TRUE); - sdp_transport_supported(sdp_config, SDP_TRANSPORT_UDPTL, TRUE); - sdp_require_session_name(sdp_config, FALSE); - } - - return sdp_config; -} - -/* - * sipsdp_create() - * - * Allocate a standard SDP with SIP config and set debug options - * based on ccsip debug settings - */ -sdp_t * -sipsdp_create (const char *peerconnection) -{ - sdp_t *sdp; - void *sdp_config; - - sdp_config = sip_sdp_init(); - if (!sdp_config) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SDP config init failure", __FUNCTION__); - return (NULL); - } - - sdp = sdp_init_description(peerconnection, sdp_config); - if (!sdp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SDP allocation failure", __FUNCTION__); - return (NULL); - } - - /* - * Map "ccsip debug events (or info)" to SDP warnings - * "ccsip debug errors to SDP errors - */ - CCSIP_INFO_DEBUG { - sdp_debug(sdp, SDP_DEBUG_WARNINGS, TRUE); - } - - CCSIP_ERR_DEBUG { - sdp_debug(sdp, SDP_DEBUG_ERRORS, TRUE); - } - - -#ifdef DEBUG_SDP_LIB - /* - * Enabling this is redundant to the existing message printing - * available for the entire SIP text messages, so it is not - * enabled here. It is useful for debugging the SDP parser, - * however. - */ - CCSIP_MESSAGES_DEBUG { - sdp_debug(sdp, SDP_DEBUG_TRACE, TRUE); - } -#endif - - return (sdp); -} - -/* - * sipsdp_free() - * - * Frees the SIP SDP structure, the contained common SDP structure, - * and each stream structure in the linked stream list. - * - * sip_sdp is set to NULL after being freed. - */ -void -sipsdp_free (cc_sdp_t **sip_sdp) -{ - const char *fname = "sipsdp_free: "; - sdp_result_e sdp_ret; - - if (!*sip_sdp) { - return; - } - - if ((*sip_sdp)->src_sdp) { - sdp_ret = sdp_free_description((*sip_sdp)->src_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing src_sdp", - fname, sdp_ret); - } - } - if ((*sip_sdp)->dest_sdp) { - sdp_ret = sdp_free_description((*sip_sdp)->dest_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing dest_sdp", - fname, sdp_ret); - } - } - - SDP_FREE(*sip_sdp); -} - -/* - * sipsdp_info_create() - * - * Allocates and initializes a SIP SDP structure. This function does - * not create the src_sdp, dest_sdp, or streams list. - * - * Returns: pointer to SIP SDP structure - if successful - * NULL - failure to allocate storage - */ -cc_sdp_t * -sipsdp_info_create (void) -{ - cc_sdp_t *sdp_info = (cc_sdp_t *) cpr_malloc(sizeof(cc_sdp_t)); - - if (sdp_info) { - sdp_info->src_sdp = NULL; - sdp_info->dest_sdp = NULL; - } - - return (sdp_info); -} - - -/* - * sipsdp_src_dest_free() - * - * Frees the SRC and/or DEST SDP. It will also free the sdp_info - * structure if both SRC and DEST SDP are freed. - * - * Input: - * flags - bitmask indicating if src and/or dest sdp should be - * freed - * - * Returns: - * sdp_info is set to NULL if freed. - */ -void -sipsdp_src_dest_free (uint16_t flags, cc_sdp_t **sdp_info) -{ - const char *fname = "sipsdp_src_dest_free: "; - sdp_result_e sdp_ret; - - if ((sdp_info == NULL) || (*sdp_info == NULL)) { - return; - } - - /* Free the SRC and/or DEST SDP */ - if (flags & CCSIP_SRC_SDP_BIT) { - if ((*sdp_info)->src_sdp) { - sdp_ret = sdp_free_description((*sdp_info)->src_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing src_sdp", - fname, sdp_ret); - } - (*sdp_info)->src_sdp = NULL; - } - } - - if (flags & CCSIP_DEST_SDP_BIT) { - if ((*sdp_info)->dest_sdp) { - sdp_ret = sdp_free_description((*sdp_info)->dest_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing dest_sdp", - fname, sdp_ret); - } - (*sdp_info)->dest_sdp = NULL; - } - - } - - /* - * If both src and dest sdp are NULL, there is no need to keep the - * sdp_info structure around. Free it. - */ - if (((*sdp_info)->src_sdp == NULL) && ((*sdp_info)->dest_sdp == NULL)) { - sipsdp_free(sdp_info); - *sdp_info = NULL; - } -} - - -/* - * sipsdp_src_dest_create() - * - * Allocates and initializes a SRC and/or DEST SDP. If the sdp_info - * structure has not yet been allocated, it is allocated here. - * - * Input: - * flags - bitmask indicating if src and/or dest sdp should be - * created - * - * Returns: pointer to SIP SDP structure - if successful - * NULL - failure to allocate storage - */ -void -sipsdp_src_dest_create (const char *peerconnection, - uint16_t flags, cc_sdp_t **sdp_info) -{ - - if (!(*sdp_info)) { - *sdp_info = sipsdp_info_create(); - if (!(*sdp_info)) { - return; - } - } - - /* Create the SRC and/or DEST SDP */ - if (flags & CCSIP_SRC_SDP_BIT) { - (*sdp_info)->src_sdp = sipsdp_create(peerconnection); - if (!((*sdp_info)->src_sdp)) { - sipsdp_src_dest_free(flags, sdp_info); - return; - } - } - - if (flags & CCSIP_DEST_SDP_BIT) { - (*sdp_info)->dest_sdp = sipsdp_create(peerconnection); - if (!((*sdp_info)->dest_sdp)) { - sipsdp_src_dest_free(flags, sdp_info); - return; - } - } -} - -/* - * sipsdp_write_to_buf() - * - * This function builds the specified SDP in a text buffer and returns - * a pointer to this buffer. - * - * Returns: pointer to buffer - no errors - * NULL - errors were encountered while building - * the SDP. The details of the build failure - * can be determined by enabling SDP debugs - * and by examining SDP library error counters. - */ -char * -sipsdp_write_to_buf (sdp_t *sdp_info, uint32_t *retbytes) -{ - flex_string fs; - uint32_t sdp_len; - sdp_result_e rc; - - flex_string_init(&fs); - - if (!sdp_info) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NULL sdp_info or src_sdp", __FUNCTION__); - flex_string_free(&fs); - return (NULL); - } - - if ((rc = sdp_build(sdp_info, &fs)) - != SDP_SUCCESS) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sdp_build rc=%s", DEB_F_PREFIX_ARGS(SIP_SDP, __FUNCTION__), - sdp_get_result_name(rc)); - - flex_string_free(&fs); - *retbytes = 0; - return (NULL); - } - - *retbytes = fs.string_length; - - /* We are not calling flex_string_free on this, instead returning the buffer - * caller's responsibility to free - */ - return fs.buffer; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_spi_utils.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_spi_utils.c deleted file mode 100755 index 97ce502d31c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_spi_utils.c +++ /dev/null @@ -1,134 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file implements a bunch of stuff used only by ccsip_spi.c, - * and this is done mostly to reduce the file size and some extra - * modularity. Includes things like tables/trees to hold SIP and - * CCAPI callids, conversion from CCAPI to SIP cause codes and the - * like. - */ -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "pmhutils.h" -#include "ccsip_spi_utils.h" -#include "util_string.h" -#include "ccsip_core.h" - -extern uint32_t IPNameCk(char *name, char *addr_error); - -/* - * Checks a token which forms a part of the - * domain-name and makes sure that it conforms - * to the grammar specified in RFC 1034 (DNS) - */ -int -sipSPICheckDomainToken (char *token) -{ - if (token == NULL) { - return FALSE; - } - - if (*token) { - if (isalnum((int)token[strlen(token) - 1]) == FALSE) { - return FALSE; - } - } - - if (isalnum((int)token[0]) == FALSE) { - return FALSE; - } - - while (*token) { - if ((isalnum((int)*token) == FALSE) && (*token != '-')) { - return FALSE; - } - token++; - } - return TRUE; -} - -/* - * Checks domain-name is valid syntax-wise - * Returns TRUE, if valid - */ -boolean -sipSPI_validate_hostname (char *str) -{ - char *tok; - char ip_addr_out[MAX_IPADDR_STR_LEN]; - char *strtok_state; - - if (str == NULL) { - return FALSE; - } - - /* Check if valid IPv6 address */ - if (cpr_inet_pton(AF_INET6, str, ip_addr_out)) { - return TRUE; - } - - if (*str) { - if (isalnum((int)str[strlen(str) - 1]) == FALSE) { - return FALSE; - } - } - - if (isalnum((int)str[0]) == FALSE) { - return FALSE; - } - - tok = PL_strtok_r(str, ".", &strtok_state); - if (tok == NULL) { - return FALSE; - } else { - if (sipSPICheckDomainToken(tok) == FALSE) { - return FALSE; - } - } - - while ((tok = PL_strtok_r(NULL, ".", &strtok_state)) != NULL) { - if (sipSPICheckDomainToken(tok) == FALSE) { - return FALSE; - } - } - - return TRUE; -} - -/* - * Determines if the IP address or domain-name is - * valid (syntax-wise only) - * Returns TRUE, if valid - */ -boolean -sipSPI_validate_ip_addr_name (char *str) -{ - uint32_t sip_address; - boolean retval = TRUE; - char *target = NULL; - char addr_error; - - if (str == NULL) { - return FALSE; - } else { - target = cpr_strdup(str); - if (!target) { - return FALSE; - } - } - sip_address = IPNameCk(target, &addr_error); - if ((!sip_address) && (addr_error)) { - cpr_free(target); - return retval; - } else { - if (sipSPI_validate_hostname(target) == FALSE) { - retval = FALSE; - } - } - cpr_free(target); - return retval; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_subsmanager.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_subsmanager.c deleted file mode 100644 index d19caf07fbb..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_subsmanager.c +++ /dev/null @@ -1,5290 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_in.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_rand.h" -#include "ccsip_subsmanager.h" -#include "util_string.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "ccsip_messaging.h" -#include "ccsip_platform_udp.h" -#include "ccsip_macros.h" -#include "ccsip_task.h" -#include "sip_common_transport.h" -#include "ccsip_platform_timers.h" -#include "platform_api.h" -#include "ccsip_register.h" -#include "ccsip_reldev.h" -#include "phntask.h" -#include "subapi.h" -#include "debug.h" -#include "ccsip_callinfo.h" -#include "regmgrapi.h" -#include "text_strings.h" -#include "configapp.h" -#include "kpmlmap.h" - -/* - * Global Variables - */ -sipSCB_t subsManagerSCBS[MAX_SCBS]; // Array of SCBS -sipSubsHistory_t gSubHistory[MAX_SCB_HISTORY]; -sipTimerCallbackFn_t callbackFunctionSubNot = sip_platform_subnot_msg_timer_callback; -sipTimerCallbackFn_t callbackFunctionPeriodic = sip_platform_subnot_periodic_timer_callback; -extern sipPlatformUITimer_t sipPlatformUISMSubNotTimers[]; // Array of timers -const char kpmlRequestAcceptHeader[] = SIP_CONTENT_TYPE_KPML_REQUEST; -const char kpmlResponseAcceptHeader[] = SIP_CONTENT_TYPE_KPML_RESPONSE; -const char dialogAcceptHeader[] = SIP_CONTENT_TYPE_DIALOG; -const char presenceAcceptHeader[] = "application/cpim-pidf+xml"; -const char remoteccResponseAcceptHeader[] = SIP_CONTENT_TYPE_REMOTECC_RESPONSE; -const char remoteccRequestAcceptHeader[] = SIP_CONTENT_TYPE_REMOTECC_REQUEST; - -static sll_handle_t s_TCB_list = NULL; // signly linked list handle of TCBs - -// Externs -extern int dns_error_code; // Global DNS error code - -// Status and statistics for the Subscription Manager -int subsManagerRunning = 0; -int internalRegistrations = 0; - -int incomingSubscribes = 0; -int incomingRefers = 0; -int incomingNotifies = 0; -int incomingUnsolicitedNotifies = 0; -int incomingSubscriptions = 0; - -int outgoingSubscribes = 0; -int outgoingNotifies = 0; -int outgoingUnsolicitedNotifies = 0; -int outgoingSubscriptions = 0; - -int currentScbsAllocated = 0; -int maxScbsAllocated = 0; - -#define MAX_SUB_EVENTS 5 -#define MAX_SUB_EVENT_NAME_LEN 16 -/* - * sub_id format: - * - * sub_id is a 32 bit quantity. The bit 32-16 holds a unique ID and - * the bits 15-0 holds a SCB index. The following definitions help - * support this formation. - * - * Assumption: The above format assumes that SCB index never be - * larger than 16 bit unsigned value. - */ -#define SUB_ID_UNIQUE_ID_POSITION 16 /* shift position of unique id part*/ -#define SUB_IDSCB_INDEX_MASK 0xffff /* mask for obtaining scb index */ -#define GET_SCB_INDEX_FROM_SUB_ID(sub_id) \ - (sub_id & SUB_IDSCB_INDEX_MASK) - -/* - * Event names - */ -const char eventNames[MAX_SUB_EVENTS][MAX_SUB_EVENT_NAME_LEN] = -{ - "dialog", - "sip-profile", - "kpml", - "presence", - "refer" -}; - -/* - * Forward Function Declarations - */ -boolean sipSPISendSubscribe(sipSCB_t *scbp, boolean renew, boolean authen); -boolean sipSPISendSubNotify(ccsip_common_cb_t *cbp, boolean authen); -boolean sipSPISendSubscribeNotifyResponse(sipSCB_t *scbp, - uint16_t response_code, - uint32_t cseq); -boolean sipSPISendSubNotifyResponse(sipSCB_t *scbp, int response_code); -void free_scb(int scb_index, const char *fname); - -// External Declarations -extern uint32_t IPNameCk(char *name, char *addr_error); -extern void kpml_init(void); -extern void kpml_shutdown(void); - - -extern void sip_platform_handle_service_control_notify(sipServiceControl_t * scp); -cc_int32_t show_subsmanager_stats(cc_int32_t argc, const char *argv[]); -static void show_scbs_inuse(void); -static void tcb_reset(void); - -typedef struct { - unsigned long cseq; - char *via; -} sub_not_trxn_t; - -/* - * Function: find_matching_trxn() - * - * Parameters: key - key to find the matching node. - * data - node data. - * - * Descriotion: is invoked by sll_find() to find the matching node based on the key. - * - * Returns: either SLL_MATCH_FOUND or SLL_MATCH_NOT_FOUND. - */ -static sll_match_e -find_matching_trxn (void *key, void *data) -{ - unsigned long cseq = *((unsigned long *)key); - sub_not_trxn_t *trxn_p = (sub_not_trxn_t *) data; - - if (cseq == trxn_p->cseq) { - return SLL_MATCH_FOUND; - } - - return SLL_MATCH_NOT_FOUND; -} - -/* - * Function: store_incoming_trxn() - * - * Description: stores the via header in incoming_trxns - * - * Parameters: via, cseq and scbp - * - * Returns: TRUE if the via header is successfully stored, - * FALSE otherwise. - */ -static boolean -store_incoming_trxn (const char *via, unsigned long cseq, sipSCB_t *scbp) -{ - static const char *fname = "store_incoming_trxn"; - size_t size = 0; - - sub_not_trxn_t *sub_not_trxn_p; - - if (scbp->incoming_trxns == NULL) { - scbp->incoming_trxns = sll_create(find_matching_trxn); - if (scbp->incoming_trxns == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sll_create() failed", fname); - return FALSE; - } - } - sub_not_trxn_p = (sub_not_trxn_t *)cpr_malloc(sizeof(sub_not_trxn_t)); - if (sub_not_trxn_p == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed", fname); - return FALSE; - } - sub_not_trxn_p->cseq = cseq; - size = strlen(via) + 1; - sub_not_trxn_p->via = (char *) cpr_malloc(size); - if (sub_not_trxn_p->via) { - sstrncpy(sub_not_trxn_p->via, via, size); - } - (void) sll_append(scbp->incoming_trxns, sub_not_trxn_p); - - return TRUE; -} - -void -free_event_data (ccsip_event_data_t *event_data) -{ - ccsip_event_data_t *tmp; - - if (event_data == NULL) { - return; - } - - while (event_data != NULL) { - tmp = event_data->next; - if (event_data->type == EVENT_DATA_RAW) { - if (event_data->u.raw_data.data) - cpr_free(event_data->u.raw_data.data); - } - cpr_free(event_data); - event_data = tmp; - } -} - -void -append_event_data (ccsip_event_data_t * event_data, - ccsip_event_data_t *new_data) -{ - while (event_data->next != NULL) { - event_data = event_data->next; - } - event_data->next = new_data; - new_data->next = NULL; -} - -void -free_pending_requests (sipspi_msg_list_t *pendingRequests) -{ - sipspi_msg_list_t *tmp; - - while (pendingRequests) { - switch (pendingRequests->cmd) { - case SIPSPI_EV_CC_NOTIFY: - { - sipspi_notify_t *notify = &(pendingRequests->msg->msg.notify); - - free_event_data(notify->eventData); - cpr_free(pendingRequests->msg); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_REGISTER: - cpr_free(&pendingRequests->msg->msg.subs_reg); - break; - case SIPSPI_EV_CC_SUBSCRIBE: - { - sipspi_subscribe_t *subs = &(pendingRequests->msg->msg.subscribe); - - free_event_data(subs->eventData); - cpr_free(pendingRequests->msg); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_RESPONSE: - cpr_free(pendingRequests->msg); - break; - case SIPSPI_EV_CC_NOTIFY_RESPONSE: - cpr_free(pendingRequests->msg); - break; - case SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED: - cpr_free(pendingRequests->msg); - break; - default: - break; - } - tmp = pendingRequests; - pendingRequests = pendingRequests->next; - cpr_free(tmp); - } -} - -boolean -append_pending_requests (sipSCB_t *scbp, - sipspi_msg_t *newRequest, - uint32_t cmd) -{ - static const char *fname = "append_pending_requests"; - sipspi_msg_list_t *pendingRequest = NULL; - sipspi_msg_list_t *tmp = NULL; - - if (!scbp) - return (FALSE); - - pendingRequest = (sipspi_msg_list_t *) - cpr_malloc(sizeof(sipspi_msg_list_t)); - if (!pendingRequest) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed", fname); - return (FALSE); - } - pendingRequest->cmd = cmd; - pendingRequest->msg = newRequest; - pendingRequest->next = NULL; - - if (scbp->pendingRequests == NULL) { - scbp->pendingRequests = pendingRequest; - return (TRUE); - } - - tmp = scbp->pendingRequests; - while (tmp->next != NULL) { - tmp = tmp->next; - } - tmp->next = pendingRequest; - return (TRUE); -} - -void -handle_pending_requests (sipSCB_t *scbp) -{ - sipspi_msg_list_t *pendingRequest = NULL; - - if (scbp->pendingRequests) { - pendingRequest = scbp->pendingRequests; - scbp->pendingRequests = pendingRequest->next; - switch (pendingRequest->cmd) { - case SIPSPI_EV_CC_NOTIFY: - { - sipspi_msg_t *notify = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_notify(notify); - cpr_free(notify); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_REGISTER: - cpr_free(pendingRequest->msg); - cpr_free(pendingRequest); - break; - case SIPSPI_EV_CC_SUBSCRIBE: - { - sipspi_msg_t *subs = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_subscribe(subs); - cpr_free(subs); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_RESPONSE: - { - sipspi_msg_t *subs_resp = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_subscribe_response(subs_resp); - cpr_free(subs_resp); - } - break; - case SIPSPI_EV_CC_NOTIFY_RESPONSE: - { - sipspi_msg_t *not_resp = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_notify_response(not_resp); - cpr_free(not_resp); - } - break; - case SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED: - { - sipspi_msg_t *term = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_subscription_terminated(term); - cpr_free(term); - } - break; - default: - if (pendingRequest->msg) { - cpr_free(pendingRequest->msg); - } - cpr_free(pendingRequest); - break; - } - } -} - -///////////////////////////////////////////////////////////// Test Only !! - -static void -ccsip_api_subscribe_result (ccsip_sub_not_data_t * msg_data) -{ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Subscribe Response: request_id=%ld, sub_id=%x", - DEB_F_PREFIX_ARGS(SIP_SUB_RESP, "ccsip_api_subscribe_result"), - msg_data->request_id, msg_data->sub_id); - if (msg_data->u.subs_result_data.status_code == REQUEST_TIMEOUT) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Request timed out", DEB_F_PREFIX_ARGS(SIP_SUB_RESP, "ccsip_api_subscribe_result")); - } -} - -static void -print_event_data (ccsip_event_data_t * eventDatap) -{ - static const char *fname = "print_event_data"; - - while (eventDatap) { - switch (eventDatap->type) { - case EVENT_DATA_INVALID: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Invalid Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_KPML_REQUEST: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"KPML Request Event Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_KPML_RESPONSE: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"KPML Response Event Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_PRESENCE: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Presence Event Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_DIALOG: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Dialog Event Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_RAW: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Raw Event Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - default: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Event Data Type Not Understood", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - eventDatap = eventDatap->next; - } -} - -static void -ccsip_api_notify_result (ccsip_sub_not_data_t *msg_data) -{ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Notify Response", DEB_F_PREFIX_ARGS(SIP_SUB_RESP, "ccsip_api_notify_result")); -} - -static void -ccsip_api_notify_ind (ccsip_sub_not_data_t *msg) -{ - static const char *fname = "ccsip_api_notify_ind"; - sipspi_msg_t not_resp; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Notify, request_id=%ld, sub_id=%x",DEB_F_PREFIX_ARGS(SIP_SUB_RESP, fname), - msg->request_id, msg->sub_id); - - // Check out what's there in the notify indication - if (msg->u.notify_ind_data.eventData) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Event Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - print_event_data(msg->u.notify_ind_data.eventData); - free_event_data(msg->u.notify_ind_data.eventData); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No event data received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - } - - // Respond with a 200OK - memset(¬_resp, 0, sizeof(sipspi_msg_t)); - not_resp.msg.notify_resp.sub_id = msg->sub_id; - not_resp.msg.notify_resp.response_code = SIP_SUCCESS_SETUP; - not_resp.msg.notify_resp.duration = 3600; - - (void) subsmanager_handle_ev_app_notify_response(¬_resp); -} - -static void -ccsip_api_subscribe_terminate (ccsip_sub_not_data_t *msg_data) -{ - sipspi_msg_t terminate; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Terminate notice", DEB_F_PREFIX_ARGS(SIP_SUB, "ccsip_api_subscribe_terminate")); - if (msg_data->u.subs_term_data.status_code == NETWORK_SUBSCRIPTION_EXPIRED) { - terminate.msg.subs_term.sub_id = msg_data->sub_id; - terminate.msg.subs_term.immediate = TRUE; - (void) subsmanager_handle_ev_app_subscription_terminated(&terminate); - } -} - -static void -ccsip_api_subscribe_ind (ccsip_sub_not_data_t *msg) -{ - static const char *fname = "ccsip_api_subscribe_ind"; - sipspi_msg_t subs_resp, notify, terminate; - ccsip_event_data_t *eventData; - char *junkdata; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Subscription Request", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - // Check out what's there in the subs indication - if (msg->u.subs_ind_data.eventData) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Event Data Received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - print_event_data(msg->u.subs_ind_data.eventData); - free_event_data(msg->u.subs_ind_data.eventData); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No event data received", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - } - - // Accept the subscription with a 200 OK response - subs_resp.msg.subscribe_resp.duration = msg->u.subs_ind_data.expires; - subs_resp.msg.subscribe_resp.response_code = SIP_SUCCESS_SETUP; - subs_resp.msg.subscribe_resp.sub_id = msg->sub_id; - (void) subsmanager_handle_ev_app_subscribe_response(&subs_resp); - - // Now send a NOTIFY - notify.msg.notify.notifyResultCallback = ccsip_api_notify_result; - notify.msg.notify.sub_id = msg->sub_id; - notify.msg.notify.eventData = NULL; - - // Now fill in some data in the kpml structure - eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (eventData == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of ccsip event data structure failed.", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - return; - } - - memset(eventData, 0, sizeof(ccsip_event_data_t)); - sstrncpy(eventData->u.kpml_request.pattern.regex.regexData, "012", 32); - sstrncpy(eventData->u.kpml_request.version, "1.0", 16); - eventData->type = EVENT_DATA_KPML_REQUEST; - notify.msg.notify.eventData = eventData; - - // Now fill in some other junk data - eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (eventData == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of ccsip event structure failed.", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - cpr_free(notify.msg.notify.eventData); - return; - } - - junkdata = (char *) cpr_malloc(20); - if (junkdata == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of junk data structure failed.", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - cpr_free(eventData); - cpr_free(notify.msg.notify.eventData); - return; - } - - memset(eventData, 0, sizeof(ccsip_event_data_t)); - memset(junkdata, 0, 20); - sstrncpy(junkdata, "Hello", 20); - - eventData->u.raw_data.data = junkdata; - eventData->u.raw_data.length = strlen(junkdata); - eventData->type = EVENT_DATA_RAW; - notify.msg.notify.eventData->next = eventData; - (void) subsmanager_handle_ev_app_notify(¬ify); - - // If expires is 0, terminate the subscription - if (msg->u.subs_ind_data.expires == 0) { - terminate.msg.subs_term.sub_id = msg->sub_id; - terminate.msg.subs_term.immediate = TRUE; - (void) subsmanager_handle_ev_app_subscription_terminated(&terminate); - } -} - -static void -test_send_subscribe () -{ - sipspi_msg_t subscribe; - ccsip_event_data_t *eventData; - - memset(&subscribe.msg.subscribe, 0, sizeof(sipspi_subscribe_t)); - - subscribe.msg.subscribe.eventPackage = CC_SUBSCRIPTIONS_KPML; - subscribe.msg.subscribe.duration = 15; - sstrncpy(subscribe.msg.subscribe.subscribe_uri, "19921", CC_MAX_DIALSTRING_LEN); - sstrncpy(subscribe.msg.subscribe.subscriber_uri, "12345", CC_MAX_DIALSTRING_LEN); - subscribe.msg.subscribe.request_id = 1003; - subscribe.msg.subscribe.dn_line = 2; - subscribe.msg.subscribe.sub_id = CCSIP_SUBS_INVALID_SUB_ID; - subscribe.msg.subscribe.subsResultCallback = ccsip_api_subscribe_result; - subscribe.msg.subscribe.subsTermCallback = ccsip_api_subscribe_terminate; - subscribe.msg.subscribe.notifyIndCallback = ccsip_api_notify_ind; - subscribe.msg.subscribe.auto_resubscribe = TRUE; - - // Now fill in some data in the kpml structure - /* - * eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - * if (eventData == NULL) { - * CCSIP_DEBUG_TASK("Malloc of ccsip event data failed."); - * return; - * } - * - * memset(eventData, 0, sizeof(ccsip_event_data_t)); - * sstrncpy(eventData->u.kpml_request.pattern.regex.regexData, "012", sizeof(eventData->u.kpml_request.pattern.regex.regexData)); - * sstrncpy(eventData->u.kpml_request.version, "1.0", sizeof(eventData->u.kpml_request.version)); - * eventData->type = EVENT_DATA_KPML_REQUEST; - * subscribe.msg.subscribe.eventData = eventData; - */ - // Now fill in some other junk data - eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (eventData == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of ccsip event data failed.", DEB_F_PREFIX_ARGS(SIP_EVT, "test_send_subscribe")); - return; - } - - memset(eventData, 0, sizeof(ccsip_event_data_t)); - eventData->type = EVENT_DATA_RAW; - eventData->u.raw_data.data = (char *) cpr_malloc(150); - if (eventData->u.raw_data.data) { - eventData->u.raw_data.length = 150; - memset(eventData->u.raw_data.data, 'V', 150); - } else { - eventData->u.raw_data.length = 0; - } - eventData->next = NULL; - subscribe.msg.subscribe.eventData = eventData; - - (void) subsmanager_handle_ev_app_subscribe(&subscribe); -} - -static void -test_send_register () -{ - sipspi_msg_t register_msg; - - memset(®ister_msg, 0, sizeof(sipspi_msg_t)); - register_msg.msg.subs_reg.eventPackage = CC_SUBSCRIPTIONS_PRESENCE; - register_msg.msg.subs_reg.subsIndCallback = ccsip_api_subscribe_ind; - register_msg.msg.subs_reg.subsTermCallback = ccsip_api_subscribe_terminate; - (void) subsmanager_handle_ev_app_subscribe_register(®ister_msg); -} - -int -subsmanager_test_start_routine () -{ - static int subscribe_sent = 0; - static int register_sent = 0; - - if (subscribe_sent == 0) { - test_send_subscribe(); - subscribe_sent = 1; - } - - if (register_sent == 0) { - test_send_register(); - register_sent = 1; - } - return 0; - -} - -/************************************************************ - * Send local error to the calling application - * This function reuses the callback interface to pass the - * (bad) result of requests from the application - ************************************************************/ -void -sip_send_error_message (ccsip_sub_not_data_t *msg_data, - cc_srcs_t dest_task, - int msgid, - ccsipGenericCallbackFn_t callbackFn, - const char *fname) -{ - if (!msg_data) { - return; - } - if (callbackFn) { - (*callbackFn) (msg_data); - } else if (dest_task != CC_SRC_MIN) { - (void) sip_send_message(msg_data, dest_task, msgid); - } -} - - -/******************************************************** - * Shutdown the Subscription Manager - ********************************************************/ -int -sip_subsManager_shut () -{ - const char *fname = "sip_subsManager_shut"; - int i; - sipSCB_t *scbp = NULL; - ccsip_sub_not_data_t error_data; - - if (subsManagerRunning == 0) { - return (0); - } - error_data.reason_code = SM_REASON_CODE_SHUTDOWN; - // Send indication of subscription ended to internal apps - // then clean and free up subscriptions and SCB - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - if (scbp->smState == SUBS_STATE_IDLE) { - continue; - } - - error_data.sub_id = scbp->sub_id; - error_data.request_id = scbp->request_id; - error_data.sub_duration = 0; - error_data.event = scbp->hb.event_type; - error_data.msg_id = scbp->subsTermCallbackMsgID; - error_data.line_id = scbp->hb.dn_line; - error_data.gsm_id = scbp->gsm_id; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Sending shutdown notification for scb=%d" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), i, scbp->sub_id); - - sip_send_error_message(&error_data, scbp->subsNotCallbackTask, - scbp->subsTermCallbackMsgID, - scbp->subsTermCallback, fname); - - free_scb(i, fname); - } - - // Shut down the periodic timer - (void) sip_platform_subnot_periodic_timer_stop(); - - // Mark subsManager as stopped running - subsManagerRunning = 0; - - tcb_reset(); - - return (0); -} - -/******************************************************** - * Common code notifying application for a failover/fallback - * or CCM new registration (reset) event. Send a notification to - * applications that have an active subscription - ********************************************************/ -static int -sip_subsManager_reg_failure_common (ccsip_reason_code_e reason) -{ - const char *fname = "sip_subsManager_reg_failure_common"; - int i; - sipSCB_t *scbp = NULL; - ccsip_sub_not_data_t error_data; - - if (subsManagerRunning == 0) { - return (0); - } - error_data.reason_code = reason; - // Send indication of subscription ended to internal apps - // then clean and free up subscriptions and SCB - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - if (scbp->smState == SUBS_STATE_IDLE || - scbp->smState == SUBS_STATE_REGISTERED) { - // Update addr and port after rollover/ccm reset - scbp->hb.local_port = sipTransportGetListenPort(1, NULL); - sipTransportGetServerIPAddr(&(scbp->hb.dest_sip_addr),1); - scbp->hb.dest_sip_port = sipTransportGetPrimServerPort(1); - continue; - } - - error_data.sub_id = scbp->sub_id; - error_data.line_id = scbp->hb.dn_line; - error_data.request_id = scbp->request_id; - error_data.sub_duration = 0; - error_data.event = scbp->hb.event_type; - error_data.msg_id = scbp->subsTermCallbackMsgID; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Sending reg failure notification for " - "scb=%d sub_id=%x reason=%d\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), i, - scbp->sub_id, reason); - - sip_send_error_message(&error_data, scbp->subsNotCallbackTask, - scbp->subsTermCallbackMsgID, - scbp->subsTermCallback, fname); - - if (scbp->internal) { - outgoingSubscriptions--; - } else { - incomingSubscriptions--; - } - free_scb(i, fname); - } - - sipRelDevAllMessagesClear(); - return (0); -} - -/******************************************************** - * Handle a failover/fallback event - * to handle this event, send a notification to all - * applications that have an active subscription - ********************************************************/ -int -sip_subsManager_rollover () -{ - tcb_reset(); - return (sip_subsManager_reg_failure_common(SM_REASON_CODE_ROLLOVER)); -} - -/******************************************************** - * Handle a (CCM or Proxy) server down and up event^M - * to handle this event, send a notification to all^M - * applications that have an active subscription^M - ********************************************************/ -int -sip_subsManager_reset_reg (void) -{ - return (sip_subsManager_reg_failure_common(SM_REASON_CODE_RESET_REG)); -} - - -/*********************************************************** - * Send a protocol error message to application. The application - * decides whether to terminate and restart the subscription - * or otherwise - ***********************************************************/ -void -sip_subsManager_send_protocol_error (sipSCB_t *scbp, int scb_index, - boolean terminate) -{ - const char *fname = "sip_subsManager_send_protocol_error"; - ccsip_sub_not_data_t error_data; - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Protocol Error for scb=%d sub_id=%x", fname, - scb_index, scbp->sub_id); - - error_data.reason_code = SM_REASON_CODE_ERROR; - error_data.sub_id = scbp->sub_id; - error_data.request_id = scbp->request_id; - error_data.sub_duration = 0; - error_data.event = scbp->hb.event_type; - error_data.msg_id = scbp->subsTermCallbackMsgID; - error_data.line_id = scbp->hb.dn_line; - - sip_send_error_message(&error_data, scbp->subsNotCallbackTask, - scbp->subsTermCallbackMsgID, scbp->subsTermCallback, - fname); - - if (terminate) { - free_scb(scb_index, fname); - } - -} - -/******************************************************** - * Start and initialize the Subscription Manager - ********************************************************/ -void -initialize_scb (sipSCB_t *scbp) -{ - int nat_enable = 0; - - if (!scbp) { - return; - } - memset(scbp, 0, sizeof(sipSCB_t)); - - scbp->sub_id = CCSIP_SUBS_INVALID_SUB_ID; - scbp->pendingClean = FALSE; - scbp->pendingCount = 0; - scbp->internal = FALSE; - scbp->subsIndCallback = NULL; - scbp->subsResultCallback = NULL; - scbp->notifyIndCallback = NULL; - scbp->notifyResultCallback = NULL; - scbp->subsTermCallback = NULL; - scbp->notIndCallbackMsgID = 0; - scbp->notResCallbackMsgID = 0; - scbp->subsIndCallbackMsgID = 0; - scbp->subsResCallbackMsgID = 0; - scbp->subsTermCallbackMsgID = 0; - scbp->subsIndCallbackTask = CC_SRC_MIN; - scbp->subsNotCallbackTask = CC_SRC_MIN; - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(scbp->hb.src_addr)); - } else { - sip_config_get_nat_ipaddr(&(scbp->hb.src_addr)); - } - scbp->hb.cb_type = SUBNOT_CB; - scbp->hb.dn_line = 1; - scbp->hb.local_port = sipTransportGetListenPort(scbp->hb.dn_line, NULL); - sipTransportGetServerIPAddr(&(scbp->hb.dest_sip_addr),1); - scbp->hb.dest_sip_port = sipTransportGetPrimServerPort(1); - - scbp->hb.sipCallID[0] = '\0'; - scbp->smState = SUBS_STATE_IDLE; - scbp->SubURI[0] = '\0'; - scbp->SubscriberURI[0] = '\0'; - scbp->sip_from = strlib_empty(); - scbp->sip_to = strlib_empty(); - scbp->sip_to_tag = strlib_empty(); - scbp->sip_from_tag = strlib_empty(); - scbp->sip_contact = strlib_empty(); - scbp->cached_record_route = strlib_empty(); - scbp->callingNumber = strlib_empty(); - scbp->subscription_state = SUBSCRIPTION_STATE_INVALID; - scbp->norefersub = FALSE; - scbp->request_id = -1; - scbp->hb.authen.cred_type = 0; - scbp->hb.authen.authorization = NULL; - scbp->hb.authen.status_code = 0; - scbp->hb.authen.nc_count = 0; - scbp->hb.authen.new_flag = FALSE; - scbp->hb.event_data_p = NULL; - scbp->pendingRequests = NULL; -} - -int -sip_subsManager_init () -{ - // Initialize SCBS array - const char *fname = "sip_subsManager_init"; - line_t i = 0; - sipSCB_t *scbp; - - if (subsManagerRunning == 1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager already running!!", fname); - return SIP_OK; - } - - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - initialize_scb(scbp); - scbp->line = i; - } - - for (i = 0; i < MAX_SCB_HISTORY; i++) { - gSubHistory[i].last_call_id[0] = '\0'; - gSubHistory[i].last_from_tag[0] = '\0'; - gSubHistory[i].eventPackage = CC_SUBSCRIPTIONS_NONE; - } - - // reset status and stats - internalRegistrations = 0; - - incomingSubscribes = 0; - incomingRefers = 0; - incomingNotifies = 0; - incomingUnsolicitedNotifies = 0; - incomingSubscriptions = 0; - - outgoingSubscribes = 0; - outgoingNotifies = 0; - outgoingUnsolicitedNotifies = 0; - outgoingSubscriptions = 0; - - currentScbsAllocated = 0; - maxScbsAllocated = 0; - - // Start periodic timer - (void) sip_platform_subnot_periodic_timer_start(TMR_PERIODIC_SUBNOT_INTERVAL * 1000); - - subsManagerRunning = 1; - - // Print out the size of the SCB - // CCSIP_DEBUG_ERROR("SCB Size=%d", sizeof(sipSCB_t)); - // CCSIP_DEBUG_ERROR("CCB Size=%d", sizeof(ccsipCCB_t)); - // Kick-off the test routine - // subsmanager_test_start_routine(); - - /* Initialize modules which uses SUB/MANAGER */ - kpml_init(); - configapp_init(); - - return SIP_OK; -} - - -/******************************************************** - * Functions to allocate, locate, free, and update SCBs - ********************************************************/ - -/* - * Function: find_scb_by_callid - * - * Parameters: - * callID - pointer to const. char for the target call ID. - * scb_index - pointer to int where the SCB index of the result - * SCB to be stored. - * - * Description: - * The find_scb_by_callid function searches for an SCB that - * contains the matching callID. It is possible to have multiple - * SCB that matches the given callID. The function only returns - * the first SCB that has the matching callID. - * - * Returns: - * Pointer to SCB and its index if the SCB is found. Otherwise - * it returns NULL and the index is undefined. - */ -sipSCB_t * -find_scb_by_callid (const char *callID, int *scb_index) -{ - int i; - int num_scb = currentScbsAllocated; - sipSCB_t *scbp; - - if (num_scb == 0) { - /* No active subscription */ - return (NULL); - } - scbp = &subsManagerSCBS[0]; - for (i = 0; (i < MAX_SCBS) && num_scb; i++, scbp++) { - if (scbp->smState != SUBS_STATE_IDLE) { - if ((scbp->smState != SUBS_STATE_REGISTERED) && - (strcmp(callID, scbp->hb.sipCallID) == 0)) { - *scb_index = i; - return (scbp); - } - num_scb--; - } - } - - return (NULL); -} - -/* - * Function: find_req_scb - * - * Parameters: - * callID - pointer to const. char for the target call ID. - * method - SIP method to match. - * cseq - CSEQ value to match. - * scb_index - pointer to int where the SCB index of the result - * SCB to be stored. - * - * Description: - * The find_req_scb function searches for an SCB that contains - * the matching callID, last request method and last cseq sent. If - * the match SCB is found, the function returns the pointer to the - * sipSCB_t along with the corresponding index. - * - * Returns: - * Pointer to SCB and its index if the SCB is found. Otherwise - * returns NULL and the index will be set to MAX_SCBS. - */ -static sipSCB_t * -find_req_scb (const char *callID, sipMethod_t method, - uint32_t cseq, int *scb_index) -{ - int idx, num_scb; - sipSCB_t *scbp; - - scbp = &subsManagerSCBS[0]; - num_scb = currentScbsAllocated; - /* - * Search SCB tables for all allocated SCBs. - */ - for (idx = 0; (idx < MAX_SCBS) && num_scb; idx++, scbp++) { - if (scbp->smState != SUBS_STATE_IDLE) { - if ((scbp->smState != SUBS_STATE_REGISTERED) && - (scbp->last_sent_request_cseq_method == method) && - (scbp->last_sent_request_cseq == cseq) && - (strcmp(callID, scbp->hb.sipCallID) == 0)) { - /* Found the matching scb */ - *scb_index = idx; - return (scbp); - } - num_scb--; - } - } - *scb_index = MAX_SCBS; - return (NULL); -} - -/* - * Function: find_scb_by_sub_id - * - * Parameters: - * sub_id - the sub_id_t parameter from which scb index - * to be obtained. - * scb_index - pointer to int for index of the SCB entry to - * be returned if the pointer is provided (not - * NULL). - * - * Description: - * The function finds the SCB for the given sub_id. - * - * Returns: - * 1) pointer to sipSCB_t or NULL if finding fails. - * 2) the index into the SCB array is also returned if the - * scb_index parameter is provided. - */ -static sipSCB_t * -find_scb_by_sub_id (sub_id_t sub_id, int *scb_index) -{ - int idx, ret_idx = MAX_SCBS; - sipSCB_t *scbp = NULL; - - /* - * Use index part of the sub_id to find the SCB - */ - idx = GET_SCB_INDEX_FROM_SUB_ID(sub_id); - if (idx < MAX_SCBS) { - /* - * SCB index is within a valid range, get the SCB by index. - * Match the SCB's sub_id and the one provided. - */ - if (subsManagerSCBS[idx].sub_id == sub_id) { - /* The correct SCB is found */ - scbp = &(subsManagerSCBS[idx]); - ret_idx = idx; - } - } - - if (scb_index != NULL) { - *scb_index = ret_idx; - } - return (scbp); -} - -sipSCB_t * -find_scb_by_registration (cc_subscriptions_t event, int *scb_index) -{ - int i; - - for (i = 0; i < MAX_SCBS; i++) { - if ((subsManagerSCBS[i].hb.event_type == event) && - (subsManagerSCBS[i].smState == SUBS_STATE_REGISTERED)) { - *scb_index = i; - return &(subsManagerSCBS[i]); - } - } - - return (NULL); -} - -sipSCB_t * -find_scb_by_subscription (cc_subscriptions_t event, int *scb_index, - const char *callID) -{ - int i; - - for (i = 0; i < MAX_SCBS; i++) { - if (cpr_strcasecmp(subsManagerSCBS[i].hb.sipCallID, callID) == 0) { - *scb_index = i; - return &(subsManagerSCBS[i]); - } - } - return (NULL); -} - -/* - * Function: new_sub_id - * - * Parameters: - * scb_index - the SCB index. - * - * Description: - * The function allocates a new unique sub_id and return - * it to the caller. - * - * NOTE: the scb_index can not exceed 16 bit unsigned value. - * - * Returns: - * sub_id. - */ -static sub_id_t -new_sub_id (int scb_index) -{ - static sub_id_t unique_id = 0; - sub_id_t sub_id; - - /* - * Form the sub_id is encoded as the following: - * bit 31 - bit 16 contains unique ID - * bit 15 - bit 0 contains scb index. - */ - sub_id = (unique_id << SUB_ID_UNIQUE_ID_POSITION) | - (sub_id_t)(scb_index & SUB_IDSCB_INDEX_MASK); - unique_id++; /* next unique sub id */ - if (sub_id == CCSIP_SUBS_INVALID_SUB_ID) { - /* sub_id becomes the invalid value marker, re-calcualte new id */ - sub_id = (unique_id << SUB_ID_UNIQUE_ID_POSITION) | - (sub_id_t)(scb_index & SUB_IDSCB_INDEX_MASK); - unique_id++; - } - return (sub_id); -} - -sipSCB_t * -allocate_scb (int *scb_index) -{ - int i; - - for (i = 0; i < MAX_SCBS; i++) { - if (subsManagerSCBS[i].smState == SUBS_STATE_IDLE) { - *scb_index = i; - currentScbsAllocated++; - if (currentScbsAllocated > maxScbsAllocated) { - maxScbsAllocated = currentScbsAllocated; - } - /* - * assigned sub_id to the allocated SCB. - */ - subsManagerSCBS[i].sub_id = new_sub_id(i); - CCSIP_DEBUG_TASK("allocate_scb scb_index: %d, currentScbsAllocated: %d, " - "maxScbsAllocated: %d, sub_id: %x", *scb_index, - currentScbsAllocated, maxScbsAllocated, subsManagerSCBS[i].sub_id); - - /* - * local port may have changed because of failover/fallback. - * So update it with current info so that the Via & Contact headers - * in SUB/NOT are generated correctly. - */ - subsManagerSCBS[i].hb.local_port = - sipTransportGetListenPort(subsManagerSCBS[i].hb.dn_line, NULL); - return &(subsManagerSCBS[i]); - } - } - return (NULL); -} - -boolean -is_previous_sub (const char *pCallID, - char *pFromTag, - cc_subscriptions_t event) -{ - int i; - - if (!pCallID || !pFromTag) { - return FALSE; - } - - for (i = 0; i < MAX_SCB_HISTORY; i++) { - if (strncmp(gSubHistory[i].last_call_id, pCallID, MAX_SIP_CALL_ID) == 0) { - if (strncmp(gSubHistory[i].last_from_tag, pFromTag, MAX_SIP_TAG_LENGTH) == 0) { - if (gSubHistory[i].eventPackage == event) { - return TRUE; - } - } - } - } - - return FALSE; -} - -void -clean_scb (sipSCB_t *scbp) -{ - sub_not_trxn_t *trxn_p; - - if (scbp) { - strlib_free(scbp->sip_from); - strlib_free(scbp->sip_to); - strlib_free(scbp->sip_to_tag); - strlib_free(scbp->sip_from_tag); - strlib_free(scbp->callingNumber); - strlib_free(scbp->sip_contact); - strlib_free(scbp->cached_record_route); - if (scbp->contact_info) - sippmh_free_contact(scbp->contact_info); - if (scbp->record_route_info) - sippmh_free_record_route(scbp->record_route_info); - if (scbp->hb.event_data_p) - free_event_data(scbp->hb.event_data_p); - if (scbp->pendingRequests) { - free_pending_requests(scbp->pendingRequests); - } - - scbp->hb.authen.cnonce[0] = '\0'; - if (scbp->hb.authen.authorization != NULL) { - cpr_free(scbp->hb.authen.authorization); - scbp->hb.authen.authorization = NULL; - } - if (scbp->hb.authen.sip_authen != NULL) { - sippmh_free_authen(scbp->hb.authen.sip_authen); - scbp->hb.authen.sip_authen = NULL; - } - - /* free all transactions */ - if (scbp->incoming_trxns) { - while ((trxn_p = (sub_not_trxn_t *) - sll_next(scbp->incoming_trxns, NULL)) != NULL) { - (void) sll_remove(scbp->incoming_trxns, (void *)trxn_p); - cpr_free(trxn_p->via); - cpr_free(trxn_p); - } - sll_destroy(scbp->incoming_trxns); - scbp->incoming_trxns = NULL; - } - - } -} -void -store_scb_history (sipSCB_t *scbp) -{ - // Copy SCB parameters in the next available history array - static int next_history = 0; - - next_history++; - if (next_history == MAX_SCB_HISTORY) { - next_history = 0; - } - sstrncpy(gSubHistory[next_history].last_call_id, scbp->hb.sipCallID, MAX_SIP_CALL_ID); - sstrncpy(gSubHistory[next_history].last_from_tag, scbp->sip_from_tag, MAX_SIP_TAG_LENGTH); - gSubHistory[next_history].eventPackage = scbp->hb.event_type; -} - -/** - * - * frees the SCB. It will cleanup the scb (ie, free the memory allocated for any sub fields). - * It will also mark the SCB as free (smState = SUBS_STATE_IDLE). - * Please note this function may be invoked can be invoked even when smState == SUBS_STATE_IDLE. - * An example case is when parse_body() fails. - * - * @param[in] scb_index - indext of the SCB into SCB array. - * @param[in] fname - name of the function calling this function. - * - * @return none - * - * @pre (scb_index >= 0) and (scb_index < MAX_SCBS) - * @post (subsManagerSCBS[scb_index].smState equals FALSE) - */ -void -free_scb (int scb_index, const char *fname) -{ - sipSCB_t *scbp = NULL; - - if (scb_index >= MAX_SCBS || scb_index < 0) { - CCSIP_DEBUG_ERROR("%s Trying to free an invalid scb_index. Return.", fname); - return; - } - scbp = &(subsManagerSCBS[scb_index]); - - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Freeing SCB: scb=%d sub_id=%x", - DEB_F_PREFIX_ARGS(SIP_SUB, "free_scb"), scb_index, scbp->sub_id); - - if (scbp->smState != SUBS_STATE_IDLE) { - currentScbsAllocated--; - /* - * This condition should never happen. If occurs, it is a strong indication - * something has gone wrong in our code logic and should be investigated. - */ - if (currentScbsAllocated < 0) { - CCSIP_DEBUG_ERROR("%s: Error somewhere in scb accounting which results" - "in negative currentScbsAllocated. Set it to 0.\n", fname); - currentScbsAllocated = 0; - } - } - // If this was an incoming subscription, store values in history first - if ((scbp->internal == FALSE) && (scbp->smState != SUBS_STATE_REGISTERED)) { - store_scb_history(scbp); - } - - clean_scb(scbp); - - // Stop associated message retry timer - if (sipPlatformUISMSubNotTimers[scb_index].outstanding) { - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[scb_index]); - } - - // Re-initialize - initialize_scb(scbp); - scbp->line = (line_t) scb_index; -} - -/** - * This function will free up the TCB resources and removes it from the TCB list. - * - * @param[in] tcbp - pointer to a TCB. - * - * @return none - * - * @pre (tcbp != NULL) - */ -static void free_tcb (sipTCB_t *tcbp) -{ - if (tcbp->hb.authen.authorization != NULL) { - cpr_free(tcbp->hb.authen.authorization); - } - if (tcbp->hb.authen.sip_authen != NULL) { - sippmh_free_authen(tcbp->hb.authen.sip_authen); - } - - (void)cprDestroyTimer(tcbp->timer); - free_event_data(tcbp->hb.event_data_p); - (void)sll_remove(s_TCB_list, (void *)tcbp); - cpr_free(tcbp); -} - -/** - * This function will find matching TCB by the SIP Call-ID in the TCB list. - * - * @param[in] callID_p - SIP Call-ID - * - * @return NULL if there is no matching TCB - * Otherwise, pointer to the found TCB is returned. - * - * @pre (callID_p != NULL) - */ -sipTCB_t *find_tcb_by_sip_callid (const char *callID_p) -{ - sipTCB_t *tcb_p; - - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, NULL); - while (tcb_p != NULL) { - if (strncmp(callID_p, tcb_p->hb.sipCallID, (sizeof(tcb_p->hb.sipCallID) -1)) == 0) { - return tcb_p; - } - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, tcb_p); - } - return NULL; -} - -/** - * This function will free up TCBs when - * 1. restarting or - * 2. failing over/ falling back - * - * @param[in] none - * - * @return none - */ -static void tcb_reset (void) -{ - sipTCB_t *tcb_p; - - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, NULL); - while (tcb_p != NULL) { - free_tcb(tcb_p); - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, NULL); - } -} - -/* - * Function is called to remove ccb pointer from scb - * When the dialog is cleared then ccb associated with - * that dialog is cleared as well. Remove that from - * scb parameters as well - */ -void -submanager_update_ccb_addr (ccsipCCB_t *ccb) -{ - sipSCB_t *scbp = NULL; - int scb_index = 0; - int num_scb; - - if ((ccb == NULL) || (currentScbsAllocated == 0)) { - /* The CCB is NULL or no active SCBs */ - return; - } - - /* Once the dialog is cleared i.e ccb is removed, the subnot - * should continue to use from its last sequence number. So - * re-assign last sequence value to scbp. - * - * There are possibility of multiple subscriptions associate - * with a call dialog. Search all of the SCB for the given CCB. - */ - scbp = &subsManagerSCBS[0]; - num_scb = currentScbsAllocated; - for (scb_index = 0; (scb_index < MAX_SCBS) && num_scb; scb_index++, scbp++) { - if (scbp->smState != SUBS_STATE_IDLE) { - if ((scbp->smState != SUBS_STATE_REGISTERED) && - (scbp->ccbp == ccb)) { - scbp->last_sent_request_cseq = ccb->last_used_cseq; - scbp->ccbp = NULL; - } - num_scb--; - } - } - -} - - -/* - * Takes care of all the parsing requirements - */ -static int -parse_body (cc_subscriptions_t event_type, char *msgBody, int msgLength, - ccsip_event_data_t **eventDatapp, - const char *fname) -{ - const char *fname1 = "parse_body"; - ccsip_event_data_type_e type = EVENT_DATA_INVALID; - - if (!msgBody) { - return SIP_ERROR; - } - - switch (event_type) { - case CC_SUBSCRIPTIONS_KPML: - type = EVENT_DATA_KPML_REQUEST; - break; - case CC_SUBSCRIPTIONS_CONFIGAPP: - type = EVENT_DATA_CONFIGAPP_REQUEST; - break; - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s: unknown event type %d", fname1, fname, type); - return SIP_ERROR; - } - - return SIP_OK; -} - -boolean -add_content (ccsip_event_data_t *eventData, sipMessage_t *request, const char *fname) -{ - return FALSE; - -/* This function requires XML handling */ -#if 0 - const char *fname1 = "add_content"; - uint32_t len; - char *eventBody = NULL; - - while (eventData) { - /* Encode eventData into eventBody here */ - len = strlen(eventBody); - - switch (eventData->type) { - case EVENT_DATA_RAW: - // Assume body is of type CMXML for now - (void) sippmh_add_message_body(request, eventBody, len, - SIP_CONTENT_TYPE_CMXML, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, TRUE, NULL); - break; - case EVENT_DATA_KPML_REQUEST: - (void) sippmh_add_message_body(request, eventBody, len, - SIP_CONTENT_TYPE_KPML_REQUEST, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, TRUE, NULL); - break; - case EVENT_DATA_KPML_RESPONSE: - (void) sippmh_add_message_body(request, eventBody, len, - SIP_CONTENT_TYPE_KPML_RESPONSE, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, TRUE, NULL); - break; - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s: Data type not supported", fname1, fname); - cpr_free(eventBody); - break; - } - - eventData = eventData->next; - } - return (TRUE); -#endif -} - -// Functions to handle requests from internal applications - -/************************************************************ - * Applications Register to Receive an incoming subscribe(s) - ************************************************************/ -int -subsmanager_handle_ev_app_subscribe_register (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_register"; - sipspi_subscribe_reg_t *reg_datap; - sipSCB_t *scbp = NULL; - int scb_index; - sipspi_msg_t *pSIPSPIMsg = NULL; - - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a new subscription registration", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (!subsManagerRunning) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager Not Initialized!", fname); - return SIP_ERROR; - } - - reg_datap = &(pSIPSPIMsg->msg.subs_reg); - if (reg_datap->subsIndCallback == NULL && - reg_datap->subsIndCallbackMsgID == 0) { - return SIP_ERROR; - } - - scbp = find_scb_by_registration(reg_datap->eventPackage, &scb_index); - if (scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Duplicate registration!", fname); - return SIP_ERROR; - } else { - scbp = allocate_scb(&scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription control block allocation failed", fname); - return SIP_ERROR; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Allocated SCB for App Registration," - " event=%d, scb=%d, sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), - reg_datap->eventPackage, - GET_SCB_INDEX_FROM_SUB_ID(scbp->sub_id), - scbp->sub_id); - } - - scbp->hb.dn_line = 1; - scbp->hb.event_type = reg_datap->eventPackage; - if (reg_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG > -1 && - reg_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG < 5) { - sstrncpy(scbp->event_name, eventNames[reg_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG], MAX_EVENT_NAME_LEN); - } - - // Get callback information (either event or function) - scbp->subsIndCallback = reg_datap->subsIndCallback; - scbp->subsIndCallbackTask = reg_datap->subsIndCallbackTask; - scbp->subsNotCallbackTask = reg_datap->subsIndCallbackTask; - scbp->subsIndCallbackMsgID = reg_datap->subsIndCallbackMsgID; - scbp->subsTermCallback = reg_datap->subsTermCallback; - scbp->subsTermCallbackMsgID = reg_datap->subsTermCallbackMsgID; - scbp->subsTermCallback = reg_datap->subsTermCallback; - scbp->subsTermCallbackMsgID = reg_datap->subsTermCallbackMsgID; - - scbp->smState = SUBS_STATE_REGISTERED; - internalRegistrations++; - return (0); -} - -/******************************************************** - * Application Generated Subscribe Request - ********************************************************/ -int -subsmanager_handle_ev_app_subscribe (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_subscribe"; - sipspi_subscribe_t *sub_datap; - sipSCB_t *scbp = NULL; - int scb_index; - ccsip_sub_not_data_t subs_result_data; - boolean reSubscribe = FALSE; - ccsipCCB_t *ccbp = NULL; - sipspi_msg_t *pSIPSPIMsg = NULL; - int subscription_expires; - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a new App subscription request", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (!subsManagerRunning) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager Not Initialized!", fname); - return SIP_ERROR; - } - - // Get Data - sub_datap = &(pSIPSPIMsg->msg.subscribe); - - /* Steps: - * * Extract subscription details from the event information - * * Check data to ensure we support the event package asked for - * * Allocate an SCB to hold subscription details - * * Create body of the SUBSCRIBE message, if needed - * * Prep the message by adding fields to the SCB - * * Call sipSPISendSubscribe to send the message out - */ - - // Get ready for any failure - subs_result_data.u.subs_result_data.expires = 0; - subs_result_data.u.subs_result_data.status_code = SUBSCRIBE_REQUEST_FAILED; - subs_result_data.sub_id = CCSIP_SUBS_INVALID_SUB_ID; - subs_result_data.request_id = sub_datap->request_id; - subs_result_data.msg_id = sub_datap->subsResCallbackMsgID; - - /* - * Finding SCB by sub_id or request id and eventPakage if the - * sub_id is not known. - */ - if (sub_datap->sub_id == CCSIP_SUBS_INVALID_SUB_ID) { - /* - * find scb based on request_id and event package. - * This scenario is possible if application decides to terminate a - * subscription before subsmanager provides app with sub_id. - */ - for (scb_index = 0; scb_index < MAX_SCBS; scb_index++) { - if ((subsManagerSCBS[scb_index].request_id == sub_datap->request_id) && - (subsManagerSCBS[scb_index].hb.event_type == sub_datap->eventPackage) && - (!subsManagerSCBS[scb_index].pendingClean)) { - scbp = &(subsManagerSCBS[scb_index]); - break; - } - } - } else { - /* Find SCB from sub_id */ - scbp = find_scb_by_sub_id(sub_datap->sub_id, &scb_index); - } - if (scbp == NULL) { - // Process new subscription - if ((sub_datap->eventPackage != CC_SUBSCRIPTIONS_DIALOG) && - (sub_datap->eventPackage != CC_SUBSCRIPTIONS_KPML) && - (sub_datap->eventPackage != CC_SUBSCRIPTIONS_PRESENCE)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Event %d not supported!", - fname, sub_datap->eventPackage); - subs_result_data.u.subs_result_data.status_code = SUBSCRIBE_FAILED_BADEVENT; - sip_send_error_message(&subs_result_data, sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, sub_datap->subsResultCallback, - fname); - return SIP_ERROR; - } - - // Reject this if there is no way to get back to the subscriber - if (!((sub_datap->subsResultCallback) || - ((sub_datap->subsNotCallbackTask != CC_SRC_MIN) && - sub_datap->subsResCallbackMsgID))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No callback info provided by the App", fname); - subs_result_data.u.subs_result_data.status_code = - SUBSCRIBE_FAILED_BADINFO; - sip_send_error_message(&subs_result_data, - sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, - sub_datap->subsResultCallback, - fname); - return SIP_ERROR; - } - - // If this is a presence request - check if sufficient SCBs will still - // be available for other "more important" functions - if (sub_datap->eventPackage == CC_SUBSCRIPTIONS_PRESENCE) { - if (currentScbsAllocated >= LIMIT_SCBS_USAGE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"reached Presence SCBs threshold", fname); - subs_result_data.u.subs_result_data.status_code = - SUBSCRIBE_FAILED_NORESOURCE; - sip_send_error_message(&subs_result_data, - sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, - sub_datap->subsResultCallback, fname); - return SIP_ERROR; - } - } - - // Allocate SCB and copy needed parameters - scbp = allocate_scb(&scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ran out of SCBs", fname); - subs_result_data.u.subs_result_data.status_code = - SUBSCRIBE_FAILED_NORESOURCE; - sip_send_error_message(&subs_result_data, - sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, - sub_datap->subsResultCallback, - fname); - show_scbs_inuse(); - return SIP_ERROR; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Allocated SCB for Sending Subscribe," - " event=%d scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), sub_datap->eventPackage, - scb_index, scbp->sub_id); - if (sub_datap->dn_line == 0 || sub_datap->dn_line > MAX_REG_LINES) { - // By not giving a DN line, the app is asking us to use - // device addressing and not line addressing - scbp->hb.dn_line = 1; - scbp->useDeviceAddressing = TRUE; - } else { - scbp->hb.dn_line = sub_datap->dn_line; - } - - scbp->gsm_id = sub_datap->call_id; - if (scbp->gsm_id != 0) { - ccbp = sip_sm_get_ccb_by_gsm_id(scbp->gsm_id); - } else { - ccbp = NULL; - } - scbp->ccbp = ccbp; - - scbp->hb.event_type = sub_datap->eventPackage; - scbp->hb.accept_type = sub_datap->acceptPackage; - if (sub_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG > -1 && - sub_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG < 5) { - sstrncpy(scbp->event_name, eventNames[sub_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG], MAX_EVENT_NAME_LEN); - } - sstrncpy(scbp->SubURIOriginal, sub_datap->subscribe_uri, - sizeof(scbp->SubURIOriginal)); - sstrncpy(scbp->SubscriberURI, sub_datap->subscriber_uri, - sizeof(scbp->SubscriberURI)); - scbp->subsResultCallback = sub_datap->subsResultCallback; - scbp->notifyIndCallback = sub_datap->notifyIndCallback; - scbp->subsTermCallback = sub_datap->subsTermCallback; - scbp->subsNotCallbackTask = sub_datap->subsNotCallbackTask; - scbp->subsResCallbackMsgID = sub_datap->subsResCallbackMsgID; - scbp->notIndCallbackMsgID = sub_datap->subsNotIndCallbackMsgID; - scbp->subsTermCallbackMsgID = sub_datap->subsTermCallbackMsgID; - - scbp->hb.dest_sip_addr = sub_datap->dest_sip_addr; - scbp->hb.dest_sip_port = sub_datap->dest_sip_port; - - scbp->auto_resubscribe = sub_datap->auto_resubscribe; - scbp->norefersub = sub_datap->norefersub; - scbp->request_id = sub_datap->request_id; - - // Set default value of subscribe duration, if not specified - if (sub_datap->duration < 0) { - config_get_value(CFGID_TIMER_SUBSCRIBE_EXPIRES, &subscription_expires, - sizeof(subscription_expires)); - sub_datap->duration = subscription_expires; - } - scbp->internal = TRUE; - } else { - /* SCB exists, it is a re-subscribe */ - reSubscribe = TRUE; - } - - scbp->hb.expires = sub_datap->duration; - scbp->hb.orig_expiration = sub_datap->duration; - - if (scbp->hb.event_data_p) { - free_event_data(scbp->hb.event_data_p); - scbp->hb.event_data_p = NULL; - } - - // Copy any body received - it will be framed later - if (sub_datap->eventData) { - scbp->hb.event_data_p = sub_datap->eventData; - sub_datap->eventData = NULL; - } - - //re-initialize cred_type - scbp->hb.authen.cred_type = 0; - - if (sipSPISendSubscribe(scbp, reSubscribe, FALSE /* auth */)) { - if (scbp->smState == SUBS_STATE_RCVD_NOTIFY) { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY; - } else { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE; - } - outgoingSubscribes++; - if (!reSubscribe) { - outgoingSubscriptions++; - } - return (0); - } - // If unable to send subscribe, return error immediately - // and return scb to the pool if not resubscribing - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send SUBSCRIBE message", fname); - sip_send_error_message(&subs_result_data, scbp->subsNotCallbackTask, - scbp->subsResCallbackMsgID, - scbp->subsResultCallback, fname); - - if (!reSubscribe) { - free_scb(scb_index, fname); - } - return SIP_ERROR; -} - -/*********************************************************** - * Handle Application Response to a Remote Subscribe Request - ***********************************************************/ -int -subsmanager_handle_ev_app_subscribe_response (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_subscribe_response"; - sipspi_subscribe_resp_t *subres_datap; - sipSCB_t *scbp; - sipspi_msg_t *pSIPSPIMsg = NULL; - - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - subres_datap = &(pSIPSPIMsg->msg.subscribe_resp); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an app subscribe response for" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), subres_datap->sub_id); - /* - * Find SCB from the sub_id. - */ - scbp = find_scb_by_sub_id(subres_datap->sub_id, NULL); - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x found", - fname, subres_datap->sub_id); - return SIP_ERROR; - } - - scbp->hb.expires = subres_datap->duration; - if (sipSPISendSubscribeNotifyResponse - (scbp, subres_datap->response_code, scbp->last_recv_request_cseq)) { - if (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY) { - scbp->smState = SUBS_STATE_SENT_NOTIFY; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send SUBSCRIBE Response", fname); - return SIP_ERROR; - } - return (0); -} - -/******************************************************** - * Handle Application Generated NOTIFY - ********************************************************/ -int -subsmanager_handle_ev_app_notify (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_notify"; - sipspi_notify_t *not_datap; - sipSCB_t *scbp; - ccsip_sub_not_data_t notify_result_data; - sipspi_msg_t *pSIPSPIMsg = NULL; - sipspi_msg_t *temp_SIPSPIMsg = NULL; - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - not_datap = &(pSIPSPIMsg->msg.notify); - - // Fill in the return data structure in case we encounter any problems - notify_result_data.u.notify_result_data.status_code = NOTIFY_REQUEST_FAILED; - notify_result_data.msg_id = not_datap->subsNotResCallbackMsgID; - notify_result_data.sub_id = not_datap->sub_id; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an app notify request for" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), - not_datap->sub_id); - /* - * Find SCB from the sub_id. - */ - scbp = find_scb_by_sub_id(not_datap->sub_id, NULL); - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x found", fname, - not_datap->sub_id); - free_event_data(not_datap->eventData); - sip_send_error_message(¬ify_result_data, - not_datap->subsNotCallbackTask, - not_datap->subsNotResCallbackMsgID, - not_datap->notifyResultCallback, - fname); - return SIP_ERROR; - } - - notify_result_data.line_id = scbp->hb.dn_line; - - // Check state to see if we need to queue this request - if ((scbp->smState == SUBS_STATE_SENT_NOTIFY) || - (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY)) { - // This means we have sent a NOTIFY but have not received a response - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Queueing request for later transmission", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - temp_SIPSPIMsg = (sipspi_msg_t *) cpr_malloc(sizeof(sipspi_msg_t)); - if (temp_SIPSPIMsg) { - /* Copy the content so that we do not touch the pSIPSPImsg */ - (*temp_SIPSPIMsg) = (*pSIPSPIMsg); - - /* Append the request */ - if (append_pending_requests(scbp, temp_SIPSPIMsg, - SIPSPI_EV_CC_NOTIFY)) { - return SIP_DEFER; - } - cpr_free(temp_SIPSPIMsg); - } - /* We either do not have buffer or failed to append msg. */ - free_event_data(not_datap->eventData); - sip_send_error_message(¬ify_result_data, - not_datap->subsNotCallbackTask, - not_datap->subsNotResCallbackMsgID, - not_datap->notifyResultCallback, - fname); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to queue request", fname); - return SIP_ERROR; - } - - // Check state to see if we are in a position to send this NOTIFY - if (scbp->smState == SUBS_STATE_IDLE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad SCB State: %d", fname, scbp->smState); - free_event_data(not_datap->eventData); - sip_send_error_message(¬ify_result_data, - not_datap->subsNotCallbackTask, - not_datap->subsNotResCallbackMsgID, - not_datap->notifyResultCallback, fname); - return SIP_ERROR; - } - - // Copy the callback function, if not already copied - if (not_datap->notifyResultCallback == NULL && - not_datap->subsNotResCallbackMsgID == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No callback event or function", fname); - // Can't really send back any error ... - free_event_data(not_datap->eventData); - return SIP_ERROR; - } else { - scbp->notifyResultCallback = not_datap->notifyResultCallback; - scbp->notResCallbackMsgID = not_datap->subsNotResCallbackMsgID; - } - - if (scbp->hb.event_data_p) { - free_event_data(scbp->hb.event_data_p); - scbp->hb.event_data_p = NULL; - } - - // Copy any body received - it will be framed later - if (not_datap->eventData) { - scbp->hb.event_data_p = not_datap->eventData; - not_datap->eventData = NULL; - } - - // Find out if app wants to terminate this subscription - if (not_datap->subState == SUBSCRIPTION_TERMINATE) { - scbp->hb.expires = 0; - } - - //re-initialize cred_type - scbp->hb.authen.cred_type = 0; - - if (sipSPISendSubNotify((ccsip_common_cb_t *)scbp, FALSE) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send Notify Message", fname); - sip_send_error_message(¬ify_result_data, scbp->subsNotCallbackTask, - scbp->notResCallbackMsgID, - scbp->notifyResultCallback, fname); - return SIP_ERROR; - } - - if (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE) { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY; - } else { - scbp->smState = SUBS_STATE_SENT_NOTIFY; - } - outgoingNotifies++; - - return (0); -} - -/** - * This function will handle Application Generated unsolicited NOTIFY - * - * @param[in] buf - pointer to sipspi_msg_t - * @param[in] line - line id. - * - * @return none - */ -void subsmanager_handle_ev_app_unsolicited_notify (cprBuffer_t buf, line_t line) -{ - const char *fname = "subsmanager_handle_ev_app_unsolicited_notify"; - sipspi_msg_t *pSIPSPIMsg = NULL; - sipspi_notify_t *not_datap; - sipTCB_t *tcbp; - int nat_enable = 0; - static uint32_t trxn_id = 1; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an outgoing unsolicited notify request", - DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - pSIPSPIMsg = (sipspi_msg_t *) buf; - not_datap = &(pSIPSPIMsg->msg.notify); - - /* - * If TCB list is not created yet, create the list. - */ - if (s_TCB_list == NULL) { - s_TCB_list = sll_create(NULL); - if (s_TCB_list == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc of TCBList failed", fname); - free_event_data(not_datap->eventData); - return; - } - } - - /* - * create a TCB (transaction control block) - */ - tcbp = cpr_malloc(sizeof(sipTCB_t)); - if (tcbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc of TCB failed", fname); - free_event_data(not_datap->eventData); - return; - } - memset(tcbp, 0, sizeof(sipTCB_t)); - tcbp->trxn_id = trxn_id; - trxn_id++; - if (trxn_id == 0) { - trxn_id = 1; - } - tcbp->timer = cprCreateTimer("Unsolicited transaction timer", - SIP_UNSOLICITED_TRANSACTION_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (tcbp->timer == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to create a timer", fname); - free_event_data(not_datap->eventData); - cpr_free(tcbp); - return; - } - tcbp->hb.cb_type = UNSOLICIT_NOTIFY_CB; - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(tcbp->hb.src_addr)); - } else { - sip_config_get_nat_ipaddr(&(tcbp->hb.src_addr)); - } - tcbp->hb.dn_line = line; - tcbp->hb.local_port = sipTransportGetListenPort(tcbp->hb.dn_line, NULL); - - tcbp->hb.event_type = not_datap->eventPackage; - - // Copy any body received - it will be framed later - if (not_datap->eventData) { - tcbp->hb.event_data_p = not_datap->eventData; - not_datap->eventData = NULL; - } - (void) sll_append(s_TCB_list, tcbp); - - if (sipSPISendSubNotify((ccsip_common_cb_t *)tcbp, FALSE) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send Notify Message", fname); - free_tcb(tcbp); - return; - } - - outgoingUnsolicitedNotifies++; - - return; -} - -/** - * This function will handle network generated response to unsolicited NOTIFY - * - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[in] tcbp - pointer to associated trnsaction control block. - * - * @returns SIP_OK/SIP_ERROR - */ -int subsmanager_handle_ev_sip_unsolicited_notify_response (sipMessage_t *pSipMessage, sipTCB_t *tcbp) -{ - int response_code = 0; - const char *fname = "subsmanager_handle_ev_sip_unsolicited_notify_response"; - - // Parse the return code - (void) sipGetResponseCode(pSipMessage, &response_code); - - /* - * if the response is < 200, do nothing. - */ - if (response_code < 200) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response", DEB_F_PREFIX_ARGS(SIP_SUB, fname), response_code); - return SIP_OK; - } - - if ((response_code == SIP_CLI_ERR_UNAUTH) || - (response_code == SIP_CLI_ERR_PROXY_REQD)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (ccsip_common_util_generate_auth(pSipMessage, &tcbp->hb, SIP_METHOD_NOTIFY, - response_code, tcbp->full_ruri) == TRUE) { - if (sipSPISendSubNotify((ccsip_common_cb_t *)tcbp, TRUE) == TRUE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with Auth header", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - return SIP_OK; - } - } - free_tcb (tcbp); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to auth challenge", fname); - return SIP_ERROR; - } - - free_tcb(tcbp); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response", DEB_F_PREFIX_ARGS(SIP_SUB, fname), response_code); - return SIP_OK; -} - -/** - * This function will handle outgoing unsolicited NOTIFY transaction timeout. - * - * @param[in] data - pointer to an id that identifies the TCB. - * - * @returns none. - */ -void subsmanager_unsolicited_notify_timeout (void *data) -{ - const char *fname = "subsmanager_unsolicited_notify_timeout"; - uint32_t trxn_id = (long)data; - sipTCB_t *temp_tcbp = NULL; - - /* - * make sure that the TCB still exists. - */ - temp_tcbp = (sipTCB_t *)sll_next(s_TCB_list, NULL); - while (temp_tcbp != NULL) { - if (temp_tcbp->trxn_id == trxn_id) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"unsolicited notify transaction timedout", fname); - free_tcb(temp_tcbp); - return; - } - temp_tcbp = (sipTCB_t *)sll_next(s_TCB_list, temp_tcbp); - } -} - -/********************************************************** - * Handle Application Response to a received Notify request - **********************************************************/ -int -subsmanager_handle_ev_app_notify_response (cprBuffer_t buf) -{ - sipspi_notify_resp_t *notify_resp; - sipSCB_t *scbp = NULL; - sipspi_msg_t *pSIPSPIMsg = NULL; - uint32_t cseq; - const char *fname = "subsmanager_handle_ev_app_notify_response"; - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - notify_resp = &(pSIPSPIMsg->msg.notify_resp); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an app notify response for" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), - notify_resp->sub_id); - - // Retrieve response parameters - /* - * Find SCB from the sub_id. - */ - scbp = find_scb_by_sub_id(notify_resp->sub_id, NULL); - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x found", - fname, notify_resp->sub_id); - return SIP_ERROR; - } - - if (notify_resp->cseq == 0) { - cseq = scbp->last_recv_request_cseq; - } else { - cseq = notify_resp->cseq; - } - // Call function to make and send the response - if (sipSPISendSubscribeNotifyResponse(scbp, - (uint16_t)(notify_resp->response_code), cseq)) { - /* - * if the outstanding NOTIFY transaction is only one, - * then update the scbp->smState. - */ - if (scbp->outstandingIncomingNotifyTrxns == 1) { - if (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY) { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } - scbp->outstandingIncomingNotifyTrxns -= 1; - return (0); - } - return SIP_ERROR; -} - -/******************************************************** - * Handle Application Request to Terminate Subscription - ********************************************************/ -int -subsmanager_handle_ev_app_subscription_terminated (cprBuffer_t buf) -{ - /* - * This function is used by the application to clean up a subscription - * whether internally or externally initiated. The application should have - * taken care of all the protocol related messaging before calling this - * function. - */ - const char *fname = "subsmanager_handle_ev_app_subscription_terminated"; - sipspi_subscribe_term_t *subs_term; - int scb_index; - sipSCB_t *scbp; - sipspi_msg_t *pSIPSPIMsg = NULL; - - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - subs_term = &(pSIPSPIMsg->msg.subs_term); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing terminate request for sub_id=%x", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), subs_term->sub_id); - /* - * Find SCB from the sub_id and allow matching with request ID and - * eventPackage if sub id is not known. - */ - if (subs_term->sub_id == CCSIP_SUBS_INVALID_SUB_ID) { - /* - * find scb based on request_id and event package. - * This scenario is possible if application decides to terminate a - * subscription before subsmanager provides app with sub_id. - */ - for (scb_index = 0; scb_index < MAX_SCBS; scb_index++) { - if ((subsManagerSCBS[scb_index].request_id == subs_term->request_id) && - (subsManagerSCBS[scb_index].hb.event_type == subs_term->eventPackage) && - (!subsManagerSCBS[scb_index].pendingClean)) { - break; - } - } - if (scb_index >= MAX_SCBS) { - scbp = NULL; - } else { - scbp = &(subsManagerSCBS[scb_index]); - } - } else { - /* Find SCB by sub_id */ - scbp = find_scb_by_sub_id(subs_term->sub_id, &scb_index); - } - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x or request id %ld" - " and eventPackage %d found", fname, - subs_term->sub_id, subs_term->request_id, - subs_term->eventPackage); - return SIP_ERROR; - } - if (scbp->smState == SUBS_STATE_IDLE || scbp->pendingClean) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SCB: scb=%d sub_id=%x has already been" - " cleaned up\n", fname, - scb_index, subs_term->sub_id); - return 0; - } - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Cleaning out subscription for SCB: scb=%d sub_id=%x", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - - if (scbp->internal) { - outgoingSubscriptions--; - } else { - incomingSubscriptions--; - } - - // There could still be messages left to receive and flush, so if not - // immediate, we mark this SCB as pending deletion and we will clean it up - // later - if (subs_term->immediate) { - free_scb(scb_index, fname); - } else { - scbp->pendingClean = TRUE; - if (scbp->pendingRequests) - scbp->pendingCount = 2 * TMR_PERIODIC_SUBNOT_INTERVAL; - else - scbp->pendingCount = 1 * TMR_PERIODIC_SUBNOT_INTERVAL; - } - - return (0); -} - - -/******************************************************** - * Handle network response to a Sub/Not request - ********************************************************/ -int -subsmanager_handle_ev_sip_response (sipMessage_t *pSipMessage) -{ - const char *fname = "subsmanager_handle_ev_sip_response"; - sipSCB_t *scbp; - int scb_index; - ccsip_sub_not_data_t sub_not_result_data; - - // currently not used SysHdr *pSm = NULL; - int response_code = 0; - const char *pCallID = NULL; - const char *rsp_method = NULL; - sipMethod_t method = sipMethodInvalid; - sipStatusCodeClass_t code_class = codeClassInvalid; - const char *expires = NULL; - long expiry_time; - const char *to = NULL, *from = NULL; - const char *record_route = NULL; - sipLocation_t *to_loc = NULL; - sipCseq_t *resp_cseq_structure = NULL; - uint32_t cseq; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a response", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (sipGetResponseMethod(pSipMessage, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - return SIP_ERROR; - } - if (method == sipMethodSubscribe) { - rsp_method = SIP_METHOD_SUBSCRIBE; - } else if (method == sipMethodRefer) { - rsp_method = SIP_METHOD_REFER; - } else { - rsp_method = SIP_METHOD_NOTIFY; - } - - pCallID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!pCallID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.", fname); - return SIP_ERROR; - } - - if (!getCSeqInfo(pSipMessage, &resp_cseq_structure)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP CSEQ.", fname); - return SIP_ERROR; - } - cseq = resp_cseq_structure->number; - cpr_free(resp_cseq_structure); - - // Locate request scbp from that match the response - scbp = find_req_scb(pCallID, method, cseq, &scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No matching request found", fname); - return SIP_ERROR; - } - // Cancel any outstanding retry timer - if (scbp->hb.retx_flag == TRUE) { - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[scb_index]); - scbp->hb.retx_flag = FALSE; - } - // Parse the return code - (void) sipGetResponseCode(pSipMessage, &response_code); - code_class = sippmh_get_code_class((uint16_t) response_code); - - /* - * If it is a response (18x/2xx) to a dialog initiating SUBSCRIBE, - * parse the Record-Route header and set up Route set for this dialog. - * If the sip_to_tag is not yet populated and if there is no associated - * CCB, then this can be considered as a response to dialog - * initating SUBSCRIBE. - */ - if ((strcmp(rsp_method, SIP_METHOD_SUBSCRIBE) == 0) && - (scbp->ccbp == NULL) && (scbp->sip_to_tag[0] == '\0')) { - if (((response_code >= 180) && (response_code <= 189)) || - ((response_code >= 200) && (response_code <= 299))) { - record_route = sippmh_get_cached_header_val(pSipMessage, - RECORD_ROUTE); - if (record_route) { - if (scbp->record_route_info) { - sippmh_free_record_route(scbp->record_route_info); - } - scbp->record_route_info = sippmh_parse_record_route(record_route); - if (scbp->record_route_info == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_parse_record_route() failed", - fname); - return SIP_ERROR; - } - } - } - } - - if ((response_code == SIP_CLI_ERR_UNAUTH) || - (response_code == SIP_CLI_ERR_PROXY_REQD)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (ccsip_common_util_generate_auth(pSipMessage, (ccsip_common_cb_t *)scbp, rsp_method, - response_code, scbp->SubURI) == TRUE) { - // Send Sub/Not message again - this time with authorization - if ((method == sipMethodSubscribe) || (method == sipMethodRefer)) { - (void) sipSPISendSubscribe(scbp, TRUE, TRUE); - } else { - (void) sipSPISendSubNotify((ccsip_common_cb_t *)scbp, TRUE); - } - } else { - // Return error to caller - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to generate Auth header", fname); - return SIP_ERROR; - } - return (0); - } - - // If this subscription has been cleaned by the application, then - // return SCB to IDLE state and discard this response - if (scbp->pendingClean) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recd msg for terminated sub", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (scbp->pendingRequests) { - scbp->pendingCount += TMR_PERIODIC_SUBNOT_INTERVAL; - scbp->smState = SUBS_STATE_ACTIVE; - handle_pending_requests(scbp); - } else { - free_scb(scb_index, fname); - } - return (0); - } - - /* - * if response code is 423, grab Min-Expires and let app know so - * that it can be used for subsequent subscriptions. - */ - if ((response_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) && - (strcmp(rsp_method, SIP_METHOD_SUBSCRIBE) == 0)) { - expires = sippmh_get_header_val(pSipMessage, - (const char *)SIP_HEADER_MIN_EXPIRES, - NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - //ensure new Min-Expires is > what we set before in Expires - if ((long) expiry_time > scbp->hb.expires) { - scbp->hb.expires = expiry_time; - } - } - } else { - // Get the expires header value and add to scb - expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - scbp->hb.expires = expiry_time; - } - } - - // update to and from headers to capture the tag - if (strcmp(rsp_method, SIP_METHOD_SUBSCRIBE) == 0) { - to = sippmh_get_cached_header_val(pSipMessage, TO); - from = sippmh_get_cached_header_val(pSipMessage, FROM); - scbp->sip_to = strlib_update(scbp->sip_to, to); - // grab the to-tag if present, and if this is a response to a SUBSCRIBE - to_loc = sippmh_parse_from_or_to((char *) to, TRUE); - if (to_loc != NULL) { - if (to_loc->tag != NULL) { - scbp->sip_to_tag = strlib_update(scbp->sip_to_tag, - sip_sm_purify_tag(to_loc->tag)); - } - sippmh_free_location(to_loc); - } - scbp->sip_from = strlib_update(scbp->sip_from, from); - } - - // Delete body, if any, since it is no longer needed - if (code_class > codeClass1xx) { - if (scbp->hb.event_data_p) { - free_event_data(scbp->hb.event_data_p); - scbp->hb.event_data_p = NULL; - } - } - - if ((scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY) || - (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE)) { - sub_not_result_data.u.subs_result_data.expires = scbp->hb.expires; - sub_not_result_data.u.subs_result_data.status_code = response_code; - sub_not_result_data.request_id = scbp->request_id; - sub_not_result_data.sub_id = scbp->sub_id; - sub_not_result_data.msg_id = scbp->subsResCallbackMsgID; - sub_not_result_data.gsm_id = scbp->gsm_id; - sub_not_result_data.line_id = scbp->hb.dn_line; - - if (code_class > codeClass1xx) { - if (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY) { - scbp->smState = SUBS_STATE_RCVD_NOTIFY; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } - - if (scbp->subsResultCallback) { - (scbp->subsResultCallback) (&sub_not_result_data); - } else if (scbp->subsNotCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->subsResCallbackMsgID); - } - } else if ((scbp->smState == SUBS_STATE_SENT_NOTIFY) || - (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY)) { - sub_not_result_data.u.notify_result_data.status_code = response_code; - sub_not_result_data.request_id = scbp->request_id; - sub_not_result_data.sub_id = scbp->sub_id; - sub_not_result_data.msg_id = scbp->notResCallbackMsgID; - sub_not_result_data.gsm_id = scbp->gsm_id; - sub_not_result_data.line_id = scbp->hb.dn_line; - - if (code_class > codeClass1xx) { - if (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY) { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } - - if (scbp->notifyResultCallback) { - (scbp->notifyResultCallback) (&sub_not_result_data); - } else if (scbp->subsNotCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->notResCallbackMsgID); - } - // If there are pending requests - handle them now - if (scbp->pendingRequests) { - handle_pending_requests(scbp); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Incorrect SCB State", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - return SIP_ERROR; - } - - return (0); -} - -/******************************************************** - * Handle Network Received Subscribe Request - ********************************************************/ -int -subsmanager_handle_ev_sip_subscribe (sipMessage_t *pSipMessage, - sipMethod_t sipMethod, - boolean in_dialog) -{ - const char *fname = "subsmanager_handle_ev_sip_subscribe"; - const char *event = NULL; - cc_subscriptions_t eventPackage = CC_SUBSCRIPTIONS_NONE; - sipSCB_t *scbpReg = NULL, *scbp = NULL; - const char *callID = NULL, *via = NULL; - const char *contact = NULL; - const char *record_route = NULL; - const char *expires = NULL; - const char *require = NULL, *supported = NULL; - sipCseq_t *request_cseq_structure = NULL; - unsigned long request_cseq_number = 0, expiry_time = 0; - - // currently not used unsigned long diff_time = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - unsigned int content_length = 0; - line_t dn_line = 0; - boolean request_uri_error = FALSE; - sipReqLine_t *requestURI = NULL; - - // currently not used sipLocation_t *uri_loc = NULL; - genUrl_t *genUrl = NULL; - const char *sip_from = NULL; - const char *sip_to = NULL; - sipLocation_t *to_loc = NULL; - sipLocation_t *from_loc = NULL; - sipUrl_t *sipUriUrl = NULL, *sipFromUrl = NULL; - char *pUser = NULL; - char *sip_to_tag_temp, *sip_to_temp; - char *kpml_call_id = NULL, *from_tag, *to_tag; - ccsip_event_data_t *subDatap = NULL; - int scb_index; - boolean reSubscribe = FALSE; - ccsip_sub_not_data_t subs_ind_data; - ccsipCCB_t *ccb = NULL; - char *referToString = NULL; - uint32_t tags = 0; - int result; - int requestStatus = SIP_MESSAGING_ERROR; - uint8_t i; - char line_contact[MAX_LINE_CONTACT_SIZE]; - char line_name[MAX_LINE_NAME_SIZE]; - int noOfReferTo = 0; - sipServiceControl_t *scp=NULL; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a new SIP subscription request", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (!subsManagerRunning) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager Not Initialized!", fname); - return SIP_ERROR; - } - - /* Steps: - * * Check request for support by a registered app - * * If not, reject the request as unsupported - * * Decode the body, if any, and if understood - * * Allocate and fill in SCB - * * Call the callback function by registered application - */ - if (!in_dialog) { - requestStatus = sipSPICheckRequest(NULL, pSipMessage); - if (requestStatus != SIP_MESSAGING_OK) { - if (requestStatus == SIP_MESSAGING_DUPLICATE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Recieved duplicate request", fname); - } else { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - return SIP_ERROR; - } - } - - memset(&subs_ind_data, 0, sizeof(ccsip_sub_not_data_t)); - - // Get relevant parameters from the SIP message - // These are: Event, Subscription-State, Accept, Content-Length besides - // To, From, Via, Call-ID, CSeq, and Contact - - event = sippmh_get_header_val(pSipMessage, SIP_HEADER_EVENT, - SIP_C_HEADER_EVENT); - - if (event) { - if (cpr_strcasecmp(event, "dialog") == 0) { - eventPackage = CC_SUBSCRIPTIONS_DIALOG; - } else if (cpr_strncasecmp(event, "kpml", 4) == 0) { - eventPackage = CC_SUBSCRIPTIONS_KPML; - } else if (cpr_strcasecmp(event, "presence") == 0) { - eventPackage = CC_SUBSCRIPTIONS_PRESENCE; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unsupported event=%s", fname, event); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - } else if (sipMethod == sipMethodRefer) { - - } else if (sipMethod == sipMethodBye) { - - return SIP_ERROR; - - } else { - // Reached here in error - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No event header", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - SIP_WARN_MISC, - NULL, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - - - // Parse Call-ID - callID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!callID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's " - "Call-ID header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Check content - content_length = sippmh_get_content_length(pSipMessage); - - if (pSipMessage->raw_body) { - if (content_length != strlen(pSipMessage->raw_body)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and \ - Actual message body length:content length=%u \ - \n and message as %s \ - \n and strlenof messagebody = %zu", fname, - content_length, pSipMessage->raw_body, - strlen(pSipMessage->raw_body)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - } else if (content_length != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and \ - Actual message body length:content length=%d \ - \n and message is EMPTY \ - \n and strlenof messagebody = 0\n", fname, - content_length); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Parse CSEQ - if (getCSeqInfo(pSipMessage, &request_cseq_structure) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain or parse request's CSeq " - "header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - // Parse From - sip_from = sippmh_get_cached_header_val(pSipMessage, FROM); - from_loc = sippmh_parse_from_or_to((char *) sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROM_OR_TO_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Parse To - sip_to = sippmh_get_cached_header_val(pSipMessage, TO); - to_loc = sippmh_parse_from_or_to((char *) sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROM_OR_TO_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(from_loc); - return SIP_ERROR; - } - // Parse Req-URI - requestURI = sippmh_get_request_line(pSipMessage); - if (requestURI) { - if (requestURI->url) { - genUrl = sippmh_parse_url(requestURI->url, TRUE); - if (genUrl) { - if (genUrl->schema != URL_TYPE_SIP) { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - - } else { - request_uri_error = TRUE; - } - if (request_uri_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid Request URI" "failed.", fname); - if (to_loc) - sippmh_free_location(to_loc); - if (from_loc) - sippmh_free_location(from_loc); - if (genUrl) - sippmh_genurl_free(genUrl); - if (requestURI) - SIPPMH_FREE_REQUEST_LINE(requestURI); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_URL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Parse Expires header - expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - } else { - // No expires header, use default - expiry_time = 3600; - } - - scbp = find_scb_by_subscription(eventPackage, &scb_index, callID); - if (scbp && eventPackage == scbp->hb.event_type) { - // SCB is already there - must be a re-subscribe - reSubscribe = TRUE; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received a reSubscribe Message", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (scbp->pendingClean) { - // Oops, the application has already terminated this subscription - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscribe received for subscription " - "already terminated by application.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SUBSCRIPTION_DELETED, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - // Check continuity of CSeq numbers - if (request_cseq_number <= scbp->last_recv_request_cseq) { - // Return 500 Internal Server Error - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Out of order CSeq number received", - fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - // Check if this is a SUBSCRIBE request for an already terminated - // subscription. If this subscription is associated with an - // existing dialog, let it go - ccb = sip_sm_get_ccb_by_callid(callID); - if ((ccb == NULL) && - is_previous_sub(callID, from_loc->tag, eventPackage)) { - // Return 481 Internal Server Error - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SUBSCRIBE received for terminated " - "subscription\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SUBSCRIPTION_DELETED, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_CALLEG); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - // This is a valid new subscription - get all the params - scbpReg = find_scb_by_registration(eventPackage, &scb_index); - if (!scbpReg) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No application registered " - "to accept this event.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - - scbp = allocate_scb(&scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No SCB Available " - "to accept this event.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - show_scbs_inuse(); - return SIP_ERROR; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Allocated SCB for Received Subscribe, event=%d," - " scb=%d sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), scbpReg->hb.event_type, - scb_index, scbp->sub_id); - scbp->hb.event_type = scbpReg->hb.event_type; - scbp->subsIndCallback = scbpReg->subsIndCallback; - scbp->subsIndCallbackTask = scbpReg->subsIndCallbackTask; - scbp->subsNotCallbackTask = scbpReg->subsNotCallbackTask; - scbp->subsIndCallbackMsgID = scbpReg->subsIndCallbackMsgID; - scbp->subsTermCallback = scbpReg->subsTermCallback; - scbp->subsTermCallbackMsgID = scbpReg->subsTermCallbackMsgID; - sstrncpy(scbp->event_name, scbpReg->event_name, MAX_EVENT_NAME_LEN); - - scbp->internal = FALSE; - - /* If the event package is KPML then check if the ID values - * are associated with it - */ - if (eventPackage == CC_SUBSCRIPTIONS_KPML) { - /* - * At this point from_tag and to_tag is never used. Since - * kpml_call_id, from_tag and to_tag just point to the - * appropriate location and does not allocate memory by itself. - */ - (void) sippmh_parse_kpml_event_id_params((char *)event, - &kpml_call_id, - &from_tag, - &to_tag); - } - - if (kpml_call_id) { - ccb = sip_sm_get_ccb_by_callid(kpml_call_id); - } else { - ccb = sip_sm_get_ccb_by_callid(callID); - scbp->ccbp = ccb; - } - if (ccb) { - scbp->gsm_id = ccb->gsm_id; - scbp->hb.dn_line = ccb->dn_line; - } else { - scbp->gsm_id = 0; - scbp->hb.dn_line = 0; - } - // Parse Supported and Required headers to see if there is the - // norefersub option tag specified - require = sippmh_get_cached_header_val(pSipMessage, REQUIRE); - if (require) { - tags = sippmh_parse_supported_require(require, NULL); - if (tags & norefersub_tag) { - scbp->norefersub = TRUE; - } - } - if ((eventPackage == CC_SUBSCRIPTIONS_CONFIGAPP) && - (scbp->norefersub == FALSE)) { - //noReferSub tag is required for OOD Refer for config change - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"noReferSub missing from Require header.", - fname); - if (sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_REQUIRE_HDR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_scb(scb_index, fname); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - supported = sippmh_get_cached_header_val(pSipMessage, SUPPORTED); - if (supported) { - tags = sippmh_parse_supported_require(supported, NULL); - if (tags & norefersub_tag) { - scbp->norefersub = TRUE; - } - } - // Check to see if the expires value is within the acceptable range, - // if any has been given to us - if (scbp->min_expires != 0) { - if (expiry_time < scbp->min_expires && expiry_time < 3600) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Too small expiry time: %lu; " - "Min acceptable: %lu.", fname, - expiry_time, scbp->min_expires); - - if (sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_INTERVAL_TOO_SMALL, - SIP_CLI_ERR_INTERVAL_TOO_SMALL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_INTERVAL_TOO_SMALL); - } - free_scb(scb_index, fname); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - } - if (scbp->max_expires != 0) { - if (expiry_time > scbp->max_expires) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Too large expiry time: %lu; " - "Max acceptable: %lu.", fname, - expiry_time, scbp->max_expires); - // There doesn't seem to be any particular error code for - // maximum expiry time so just return the generic error - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_INTERVAL_TOO_LARGE_PHRASE, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Freeing SCB: scb=%d sub_id=%x", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - free_scb(scb_index, fname); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - } - sipUriUrl = genUrl->u.sipUrl; - if (sipUriUrl) { - pUser = sippmh_parse_user(sipUriUrl->user); - if (pUser) { - sstrncpy(scbp->SubURI, pUser, sizeof(scbp->SubURI)); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - sstrncpy(scbp->SubURI, sipUriUrl->user, sizeof(scbp->SubURI)); - } - } - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - - scbp->sip_from = strlib_update(scbp->sip_from, sip_from); - if (from_loc->tag) { - scbp->sip_from_tag = strlib_update(scbp->sip_from_tag, - sip_sm_purify_tag(from_loc->tag)); - } - - if (from_loc->genUrl->schema == URL_TYPE_SIP) { - sipFromUrl = from_loc->genUrl->u.sipUrl; - } - if (sipFromUrl) { - if (sipFromUrl->user) { - char *pUserTemp, *target = NULL, addr_error; - uint32_t sip_address = 0; - - pUserTemp = sippmh_parse_user(sipFromUrl->user); - if (pUserTemp) { - scbp->callingNumber = strlib_update(scbp->callingNumber, - pUserTemp); - cpr_free(pUserTemp); - } else { - scbp->callingNumber = strlib_update(scbp->callingNumber, - sipFromUrl->user); - } - - target = cpr_strdup(sipFromUrl->host); - if (!target) { - sip_address = 0; - } else { -//CPR TODO: need reference for -//Should replace with a boolean util_check_ip_addr(char *addr) call - sip_address = IPNameCk(target, &addr_error); - cpr_free(target); - } - - if ((from_loc->genUrl->schema == URL_TYPE_SIP) && - (!sip_address)) { - if (scbp->callingNumber) { - scbp->callingNumber = strlib_append(scbp->callingNumber, "@"); - scbp->callingNumber = strlib_append(scbp->callingNumber, sipFromUrl->host); - } - } - } else { - scbp->callingNumber = strlib_update(scbp->callingNumber, - "Unknown Number"); - } - } - - scbp->sip_to = strlib_update(scbp->sip_to, sip_to); - if (to_loc->tag == NULL) { - // Create To tag - sip_to_tag_temp = strlib_open(scbp->sip_to_tag, MAX_SIP_TAG_LENGTH); - if (sip_to_tag_temp) { - sip_util_make_tag(sip_to_tag_temp); - } - scbp->sip_to_tag = strlib_close(sip_to_tag_temp); - sip_to_temp = strlib_open(scbp->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - sstrncat(sip_to_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - if (scbp->sip_to_tag) { - sstrncat(sip_to_temp, scbp->sip_to_tag, - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - } - } - scbp->sip_to = strlib_close(sip_to_temp); - } - - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - - sstrncpy(scbp->hb.sipCallID, callID, MAX_SIP_CALL_ID); - - // Parse Contact info - contact = sippmh_get_cached_header_val(pSipMessage, CONTACT); - if (contact) { - if (scbp->contact_info) { - sippmh_free_contact(scbp->contact_info); - } - scbp->contact_info = sippmh_parse_contact(contact); - - if ((scbp->contact_info == NULL) || // contact in msg, parse error - (sipSPICheckContact(contact) < 0)) { // If contact is invalid - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_scb(scb_index, fname); - return SIP_ERROR; - } - } - - if ((sipMethod == sipMethodSubscribe) && (scbp->ccbp == NULL)) { - record_route = sippmh_get_cached_header_val(pSipMessage, - RECORD_ROUTE); - if (record_route) { - if (scbp->record_route_info) { - sippmh_free_record_route(scbp->record_route_info); - } - scbp->record_route_info = sippmh_parse_record_route(record_route); - if (scbp->record_route_info == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_parse_record_route() failed", - fname); - free_scb(scb_index, fname); - return SIP_ERROR; - } - /* - * Store the Record-Route header value to be used - * in 18x or 2xx response - */ - scbp->cached_record_route = strlib_update(scbp->cached_record_route, - record_route); - } - } - - } // End of populating a new SCB - - scbp->hb.expires = expiry_time; - scbp->hb.orig_expiration = expiry_time; - scbp->last_recv_request_cseq = request_cseq_number; - scbp->last_recv_request_cseq_method = request_cseq_method; - - // Parse Refer-To - if (sipMethod == sipMethodRefer) { - sipReferTo_t *referto = NULL; - - noOfReferTo = sippmh_get_num_particular_headers(pSipMessage, - SIP_HEADER_REFER_TO, - SIP_C_HEADER_REFER_TO, - &referToString, - MAX_REFER_TO_HEADERS); - - if ((noOfReferTo == 0) || (noOfReferTo > 1)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - scb_index, scbp->hb.dn_line, fname, - "Incorrect number of Refer-To headers\n"); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - NULL); - return SIP_ERROR; - } - // Note that the refer-to header is not parsed for CCM mode since it was - // malformed in older versions of CCM - if (sip_regmgr_get_cc_mode(1) != REG_MODE_CCM) { - referto = sippmh_parse_refer_to(referToString); - if (referto == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - scb_index, scbp->hb.dn_line, fname, - "Refer-To header could not be parsed\n"); - (void) sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - NULL); - return SIP_ERROR; - } else { - sippmh_free_refer_to(referto); - } - } - } - - // Parse and store Via Header - via = sippmh_get_cached_header_val(pSipMessage, VIA); - if (via) { - /* store the via header */ - if (store_incoming_trxn(via, request_cseq_number, scbp) == FALSE) { - (void) sipSPISendErrorResponse(pSipMessage, - SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, - NULL, - NULL); - return SIP_ERROR; - } - } - - // See if can determine dn_line from any of the parameters - // 1st try the REQ-URI - // CCM should send us - // SUBSCRIBE sip:@ SIP/2.0 - // and we should be able to get the line from its pkid - if (scbp->hb.dn_line == 0) { - for (dn_line = 1; dn_line <= MAX_REG_LINES; dn_line++) { - if (sip_config_check_line(dn_line) == FALSE) { - continue; - } - config_get_line_string(CFGID_LINE_CONTACT, line_contact, - dn_line, sizeof(line_contact)); - if (cpr_strcasecmp(line_contact, UNPROVISIONED) != 0) { - if (cpr_strcasecmp(scbp->SubURI, line_contact) == 0) { - scbp->hb.dn_line = dn_line; - break; - } - } - } - } - if (scbp->hb.dn_line == 0) { - // If no match there, check against the DN number - for (dn_line = 1; dn_line <= MAX_REG_LINES; dn_line++) { - config_get_line_string(CFGID_LINE_NAME, line_name, - dn_line, sizeof(line_name)); - if (!cpr_strcasecmp(scbp->SubURI, line_name)) { - scbp->hb.dn_line = dn_line; - break; - } - } - } - // If unable to determine dn_line, the SUBSCRIBE is directed to device - // Could make sure and check against the MAC address here - if (scbp->hb.dn_line == 0) { - scbp->useDeviceAddressing = TRUE; - } - // Parse Body - subs_ind_data.u.subs_ind_data.eventData = NULL; - i = 0; - while (i < HTTPISH_MAX_BODY_PARTS && pSipMessage->mesg_body[i].msgBody - != NULL) { - if (pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_DIALOG_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_KPML_REQUEST_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_CONFIGAPP_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_PRESENCE_VALUE) { - - if (pSipMessage->mesg_body[i].msgContentTypeValue == SIP_CONTENT_TYPE_CMXML_VALUE) { - // Body can not be parsed - send it up as it is - subDatap = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (subDatap == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc of subDatap failed.", - fname); - return (0); - } - - subDatap->u.raw_data.data = pSipMessage->mesg_body[i].msgBody; - subDatap->u.raw_data.length = pSipMessage->mesg_body[i].msgLength; - pSipMessage->mesg_body[i].msgBody = NULL; - pSipMessage->mesg_body[i].msgLength = 0; - subDatap->type = EVENT_DATA_RAW; - subDatap->next = NULL; - } else { - - /* There are other applications that has been handled like syncCheck - */ - - scp = sippmh_parse_service_control_body(pSipMessage->mesg_body[i].msgBody, - pSipMessage->mesg_body[i].msgLength); - - if (scp != NULL) { - // Hand over the event to platform - sip_platform_handle_service_control_notify(scp); - - sippmh_free_service_control_info(scp); - - } - - /* If this is the only body then have to send the response out as - * no other application will be requesting to send response - */ - if (i== 0 && pSipMessage->mesg_body[i+1].msgBody == NULL) { - - if (sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - } - if (!reSubscribe) { - free_scb(scb_index, fname); - } - return(0); - } - } - - } else { - result = parse_body(scbp->hb.event_type, pSipMessage->mesg_body[i].msgBody, - pSipMessage->mesg_body[i].msgLength, &subDatap, fname); - if (result == SIP_ERROR) { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - if (!reSubscribe) { - free_scb(scb_index, fname); - } - free_event_data(subDatap); - free_event_data(subs_ind_data.u.subs_ind_data.eventData); - return SIP_ERROR; - } - } - if (subs_ind_data.u.subs_ind_data.eventData == NULL && - subDatap != NULL) { - subs_ind_data.u.subs_ind_data.eventData = subDatap; - subDatap->next = NULL; - } else if (subs_ind_data.u.subs_ind_data.eventData != NULL && - subDatap != NULL){ - append_event_data(subs_ind_data.u.subs_ind_data.eventData, - subDatap); - } - i++; - } - - // Prepare subscription indication data - subs_ind_data.event = eventPackage; - subs_ind_data.u.subs_ind_data.expires = scbp->hb.expires; - subs_ind_data.u.subs_ind_data.from = scbp->sip_from; - subs_ind_data.u.subs_ind_data.to = scbp->sip_to; - subs_ind_data.u.subs_ind_data.line = scbp->hb.dn_line; - subs_ind_data.sub_duration = scbp->hb.expires; - subs_ind_data.sub_id = scbp->sub_id; - subs_ind_data.msg_id = scbp->subsIndCallbackMsgID; - subs_ind_data.gsm_id = scbp->gsm_id; - subs_ind_data.line_id = scbp->hb.dn_line; - subs_ind_data.norefersub = scbp->norefersub; - subs_ind_data.request_id = -1; - - // Eventually let the subscribing application know - if (scbp->subsIndCallback) { - (scbp->subsIndCallback) (&subs_ind_data); - } else if ((scbp->subsIndCallbackTask != CC_SRC_MIN) && (scbp->subsIndCallbackMsgID != 0)) { - (void) sip_send_message(&subs_ind_data, scbp->subsIndCallbackTask, - scbp->subsIndCallbackMsgID); - } - - if (scbp->smState == SUBS_STATE_SENT_NOTIFY) { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY; - } else { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE; - } - incomingSubscribes++; - if (!reSubscribe) { - incomingSubscriptions++; - } - return (0); -} - -/** - * This function will decode the xml bodies. - * - * @param[in] event_type - event type. - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[out] dataPP - pointer to pointer to decoded data. - * - * @returns TRUE/FALSE - * - * @pre (pSipMessage != NULL) && (dataPP != NULL) - */ -static boolean -decode_message_body (cc_subscriptions_t event_type, sipMessage_t *pSipMessage, ccsip_event_data_t **dataPP) -{ - const char *fname = "decode_message_body"; - uint8_t i = 0; - ccsip_event_data_t *notDatap = NULL; - int result; - - // Decode the body, if any - while (i < HTTPISH_MAX_BODY_PARTS && pSipMessage->mesg_body[i].msgBody - != NULL) { - if (pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_DIALOG_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_KPML_REQUEST_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_PRESENCE_VALUE) { - - // Body can not be parsed - send it up as it is - notDatap = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (notDatap == NULL) { - CCSIP_DEBUG_ERROR("%s: Error - malloc of notDatap failed.", - fname); - return FALSE; - } - - notDatap->u.raw_data.data = pSipMessage->mesg_body[0].msgBody; - notDatap->u.raw_data.length = pSipMessage->mesg_body[0].msgLength; - pSipMessage->mesg_body[0].msgBody = NULL; - pSipMessage->mesg_body[0].msgLength = 0; - notDatap->type = EVENT_DATA_RAW; - notDatap->next = NULL; - - } else { - - result = parse_body(event_type, pSipMessage->mesg_body[i].msgBody, - pSipMessage->mesg_body[i].msgLength, ¬Datap, fname); - if (result == SIP_ERROR) { - free_event_data(notDatap); - free_event_data(*dataPP); - return FALSE; - } - } - if ((*dataPP) == NULL) { - (*dataPP) = notDatap; - notDatap->next = NULL; - } else { - append_event_data((*dataPP), notDatap); - } - i++; - } - return TRUE; -} - -/******************************************************** - * Handle Network Received Notify Request - ********************************************************/ -int -subsmanager_handle_ev_sip_subscribe_notify (sipMessage_t *pSipMessage) -{ - const char *fname = "subsmanager_handle_ev_sip_subscribe_notify"; - cc_subscriptions_t eventPackage; - sipSCB_t *scbp = NULL; - const char *callID = NULL; - const char *event = NULL; - int scb_index; - sipCseq_t *request_cseq_structure = NULL; - unsigned long request_cseq_number = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - ccsip_sub_not_data_t notify_ind_data; - int16_t requestStatus = SIP_MESSAGING_ERROR; - const char *from = NULL, *to = NULL; - const char *subs_state = NULL; - boolean subs_header_found = FALSE; - sipLocation_t *to_loc = NULL; - const char *via = NULL; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a network generated NOTIFY", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - memset(¬ify_ind_data, 0, sizeof(notify_ind_data)); - requestStatus = (uint16_t) sipSPICheckRequest(NULL, pSipMessage); - if (requestStatus != SIP_MESSAGING_OK) { - if (requestStatus == SIP_MESSAGING_DUPLICATE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received duplicate request", fname); - } else { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - return SIP_ERROR; - } - // Get fields from NOTIFY - event = sippmh_get_header_val(pSipMessage, SIP_HEADER_EVENT, - SIP_C_HEADER_EVENT); - if (event) { - if (cpr_strcasecmp(event, SIP_EVENT_DIALOG) == 0) { - eventPackage = CC_SUBSCRIPTIONS_DIALOG; - } else if (cpr_strcasecmp(event, SIP_EVENT_KPML) == 0) { - eventPackage = CC_SUBSCRIPTIONS_KPML; - } else if (cpr_strcasecmp(event, SIP_EVENT_CONFIG) == 0) { - eventPackage = CC_SUBSCRIPTIONS_CONFIG; - } else if (cpr_strcasecmp(event, SIP_EVENT_PRESENCE) == 0) { - eventPackage = CC_SUBSCRIPTIONS_PRESENCE; - } else if ((cpr_strcasecmp(event, SIP_EVENT_REFER) == 0) && - (pSipMessage->mesg_body[0].msgContentTypeValue == SIP_CONTENT_TYPE_DIALOG_VALUE)) { - eventPackage = CC_SUBSCRIPTIONS_DIALOG; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unsupported event=%s", fname, event); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Missing Event header", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - - callID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!callID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's " - "Call-ID header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - - // Find the proper SCB - scbp = find_scb_by_subscription(eventPackage, &scb_index, callID); - if (!scbp) { - /* - * check if it is an unsolicited dialog/presence event NOTIFY - * check if it has a to-tag. if so, then it is not considered unsolicited NOTIFY. - * Presence of to-tag could be because it is a final NOTIFY of a subscription which - * we have just terminated. - */ - to = sippmh_get_cached_header_val(pSipMessage, TO); - to_loc = sippmh_parse_from_or_to((char *) to, TRUE); - if ((to_loc == NULL) || (to_loc->tag == NULL)) { - if (eventPackage == CC_SUBSCRIPTIONS_DIALOG) { - notify_ind_data.line_id = 1; - /* decode the body */ - if (decode_message_body(CC_SUBSCRIPTIONS_DIALOG, pSipMessage, - &(notify_ind_data.u.notify_ind_data.eventData)) == FALSE) { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - return SIP_ERROR; - } - } - if (sipSPISendErrorResponse(pSipMessage, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_STATUS_SUCCESS); - } - - incomingUnsolicitedNotifies++; - sippmh_free_location(to_loc); - return (0); - } else if (eventPackage == CC_SUBSCRIPTIONS_PRESENCE) { - /* decode the body */ - if (decode_message_body(CC_SUBSCRIPTIONS_PRESENCE, pSipMessage, - &(notify_ind_data.u.notify_ind_data.eventData)) == FALSE) { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - return SIP_ERROR; - } - } - pres_unsolicited_notify_ind(¬ify_ind_data); - if (sipSPISendErrorResponse(pSipMessage, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_STATUS_SUCCESS); - } - - incomingUnsolicitedNotifies++; - sippmh_free_location(to_loc); - return (0); - } - } - sippmh_free_location(to_loc); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No prior subscription", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_SUBS_DOES_NOT_EXIST_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_CALLEG); - } - return SIP_ERROR; - } - - - if (scbp->pendingClean) { - // Oops, the application has already terminated this subscription - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notify received for subscription " - "already terminated by application.\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_SUCCESS_SETUP, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - } - return (0); - } - // Check SCB state - if (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE) { - // Have just sent a SUBSCRIBE but have not received a response - // This could happen if the NOTIFY from the remote side comes in - // before its 2xx response to SUBSCRIBE does - // Should still process this as if received a 2xx response - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Bad subscription state: " - "But still processing out-of-turn NOTIFY.\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - } - // Copy stuff from the message into the SCB - the parts that we - // need to keep to respond to this request. This includes: Via&Branch - // (From and To & Tags, CallID are simply inverse of the ones in - // SUBSCRIBE), and CSeq - - // Parse subscription state header - subs_state = sippmh_get_header_val(pSipMessage, - SIP_HEADER_SUBSCRIPTION_STATE, - SIP_HEADER_SUBSCRIPTION_STATE); - if (subs_state) { - sipSubscriptionStateInfo_t subsStateInfo; - - memset(&subsStateInfo, 0, sizeof(sipSubscriptionStateInfo_t)); - // Get the state, expires, retry-after and reason - if (sippmh_parse_subscription_state(&subsStateInfo, subs_state) == 0) { - // Store values in SCB - scbp->hb.expires = subsStateInfo.expires; - scbp->subscription_state = subsStateInfo.state; - scbp->retry_after = subsStateInfo.retry_after; - scbp->subscription_state_reason = subsStateInfo.reason; - subs_header_found = TRUE; - } - } - if (!subs_header_found) { - // Subscription-State header not present - reject - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain or parse request's " - "Subs-state header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_NO_SUBSCRIPTION_HEADER, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - // Send message to the app and let it decide what it wants - // to do with a bad NOTIFY - sip_subsManager_send_protocol_error(scbp, scb_index, FALSE); - return SIP_ERROR; - } - // Parse CSEQ - if (getCSeqInfo(pSipMessage, &request_cseq_structure) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain or parse request's CSeq " - "header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - // Send message to the app and let it decide what it wants - // to do with a bad NOTIFY - sip_subsManager_send_protocol_error(scbp, scb_index, FALSE); - return SIP_ERROR; - } - - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - // Check continuity of CSeq numbers - if (request_cseq_number <= scbp->last_recv_request_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Out of order CSeq number received", - fname); - } else { - scbp->last_recv_request_cseq = request_cseq_number; - scbp->last_recv_request_cseq_method = request_cseq_method; - } - - // Parse and store Via Header - via = sippmh_get_cached_header_val(pSipMessage, VIA); - if (via) { - /* store the via header */ - if (store_incoming_trxn(via, request_cseq_number, scbp) == FALSE) { - (void) sipSPISendErrorResponse(pSipMessage, - SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, - NULL, - NULL); - return SIP_ERROR; - } - } - - // Update from/to headers - note this is reversed - // as we generated the initial SUBSCRIBE - to = sippmh_get_cached_header_val(pSipMessage, TO); - from = sippmh_get_cached_header_val(pSipMessage, FROM); - - if (to) { - scbp->sip_from = strlib_update(scbp->sip_from, to); - } - if (from) { - scbp->sip_to = strlib_update(scbp->sip_to, from); - } - - if ((scbp->smState == SUBS_STATE_SENT_SUBSCRIBE) || - (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY)) { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY; - } else { - scbp->smState = SUBS_STATE_RCVD_NOTIFY; - } - - // Decode the body, if any - if (decode_message_body(eventPackage, pSipMessage, &(notify_ind_data.u.notify_ind_data.eventData)) == FALSE) { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - // Send message to the app and let it decide what it - // wants to do with a bad NOTIFY - sip_subsManager_send_protocol_error(scbp, scb_index, FALSE); - return SIP_ERROR; - } - - // Fill out the return structure and call the callback routine - notify_ind_data.event = eventPackage; - notify_ind_data.sub_id = scbp->sub_id; - notify_ind_data.msg_id = scbp->notIndCallbackMsgID; - notify_ind_data.gsm_id = scbp->gsm_id; - notify_ind_data.line_id = scbp->hb.dn_line; - notify_ind_data.request_id = scbp->request_id; - notify_ind_data.u.notify_ind_data.subscription_state = - scbp->subscription_state; - notify_ind_data.u.notify_ind_data.expires = scbp->hb.expires; - notify_ind_data.u.notify_ind_data.retry_after = scbp->retry_after; - notify_ind_data.u.notify_ind_data.subscription_state_reason = - scbp->subscription_state_reason; - notify_ind_data.u.notify_ind_data.cseq = request_cseq_number; - - if (scbp->notifyIndCallback) { - (scbp->notifyIndCallback) (¬ify_ind_data); - } else if (scbp->subsNotCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(¬ify_ind_data, scbp->subsNotCallbackTask, - scbp->notIndCallbackMsgID); - } - - scbp->outstandingIncomingNotifyTrxns += 1; - incomingNotifies++; - return (0); -} - -static sipRet_t -sm_add_contact (ccsip_common_cb_t *cbp, sipMessage_t *msg) -{ - - char src_addr_str[MAX_IPADDR_STR_LEN]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char contact[MAX_LINE_CONTACT_SIZE]; - char contact_str[MAX_SIP_URL_LENGTH]; - size_t escaped_char_str_len; - sipSCB_t *scbp = (sipSCB_t *)cbp; - - if (!cbp || !msg) { - return HSTATUS_FAILURE; - } - - ipaddr2dotted(src_addr_str, &cbp->src_addr); - - if ((cbp->cb_type == SUBNOT_CB) && (scbp->useDeviceAddressing)) { - platform_get_wired_mac_address(mac_address); - snprintf(contact_str, MAX_SIP_URL_LENGTH, "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str, scbp->hb.local_port); - } else { - snprintf(contact_str, 6, "dn_line, sizeof(contact)); - if ((cpr_strcasecmp(contact, UNPROVISIONED) == 0) || - (contact[0] == '\0')) { - // pk-id has not been provisioned, use line name instead - config_get_line_string(CFGID_LINE_NAME, contact, - cbp->dn_line, sizeof(contact)); - } - escaped_char_str_len = sippmh_convertURLCharToEscChar(contact, - strlen(contact), - contact_str + 5, - (MAX_SIP_URL_LENGTH - 5), - FALSE); - snprintf(contact_str + 5 + escaped_char_str_len, - sizeof(contact_str) - 5 - escaped_char_str_len, - "@%s:%d;transport=%s>", src_addr_str, cbp->local_port, - sipTransportGetTransportType(cbp->dn_line, TRUE, NULL)); - } - - return sippmh_add_text_header(msg, SIP_HEADER_CONTACT, contact_str); -} - -static sipRet_t -sm_add_cseq (sipSCB_t *scbp, sipMethod_t method, sipMessage_t *msg) -{ - uint32_t cseq_number; - - if (!scbp || !msg) { - return HSTATUS_FAILURE; - } - if (scbp->ccbp) { - // Use cseq from CCB - cseq_number = ++(scbp->ccbp->last_used_cseq); - /* - * Remember CSEQ for the request aside from ccb so that - * CSEQ can be match when response is received (can not. - * depend on last CSEQ stored on CCB since it can be - * changed). - */ - scbp->last_sent_request_cseq = cseq_number; - } else if (scbp->last_sent_request_cseq == 0) { - cseq_number = scbp->last_sent_request_cseq = CCSIP_SUBS_START_CSEQ; - } else { - cseq_number = ++(scbp->last_sent_request_cseq); - } - - return (sippmh_add_cseq(msg, sipGetMethodString(method), cseq_number)); -} - -static boolean -sipSPIAddRouteHeadersToSubNot (sipMessage_t *msg, sipSCB_t * scbp, - char *result_route, int result_route_length) -{ - const char *fname = "sipSPIAddRouteHeadersToSubNot"; - static char route[MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS]; - static char Contact[MAX_SIP_HEADER_LENGTH]; - boolean lr = FALSE; - sipRecordRoute_t *rr_info; - - /* Check args */ - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - if (!scbp) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "scbp"); - return (FALSE); - } - - if (scbp->ccbp) { - rr_info = scbp->ccbp->record_route_info; - } else { - rr_info = scbp->record_route_info; - } - if (!rr_info) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Route info not available; will not" - " add Route header.\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - return (TRUE); - } - - memset(route, 0, MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS); - memset(Contact, 0, MAX_SIP_HEADER_LENGTH); - - if (scbp->internal == FALSE) { /* incoming subscription */ - /* - * For Incoming dialog (UAS), Copy the RR headers as it is - * If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAS(rr_info, route, sizeof(route), &lr) - == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAS()"); - return (FALSE); - } - } else { - /* - * For Outgoing dialog (UAC), Copy the RR headers in the reverse - * order. If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAC(rr_info, route, sizeof(route), &lr) - == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAC()"); - return (FALSE); - } - } - /* - * If loose_routing is TRUE, then the contact header is NOT appended - * to the Routeset but is instead used in the Req-URI^M - */ - if (!lr) { - Contact[0] = '\0'; - if (sipSPIGenerateContactHeader(scbp->contact_info, Contact, - sizeof(Contact)) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateContactHeader()"); - return (FALSE); - } - /* Append Contact to the Route Header, if Contact is available */ - if (Contact[0] != '\0') { - if (route[0] != '\0') { - sstrncat(route, ", ", sizeof(route) - strlen(route)); - } - sstrncat(route, Contact, MIN((sizeof(route) - strlen(route)), sizeof(Contact))); - } - } - - if (route[0] != '\0') { - if (STATUS_SUCCESS == sippmh_add_text_header(msg, SIP_HEADER_ROUTE, - route)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Adding route = %s", DEB_F_PREFIX_ARGS(SIP_SUB, fname), route); - if (result_route) { - sstrncpy(result_route, route, result_route_length); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_add_text_header(ROUTE)"); - return (FALSE); - } - } else { - /* Having nothing in Route header is a legal case. - * This would happen when the Record-Route header has - * a single entry and Contact was NULL - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Not adding route", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - } - - return (TRUE); -} - -/************************************************************** - * Format and Send an application generated SUBSCRIBE - **************************************************************/ -boolean -sipSPISendSubscribe (sipSCB_t *scbp, boolean renew, boolean authen) -{ - const char *fname = "SIPSPISendSubscribe"; - sipMessage_t *request = NULL; - sipMethod_t method = sipMethodInvalid; - sipRet_t flag = STATUS_SUCCESS; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char addr[MAX_IPADDR_STR_LEN]; - char *sip_from_temp, *sip_from_tag, *sip_to_temp; - char via[SIP_MAX_VIA_LENGTH]; - char display_name[MAX_LINE_NAME_SIZE]; - char line_name[MAX_LINE_NAME_SIZE]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - static uint16_t count = 1; - int timeout = 0, max_forwards_value = 70; -#define CID_LENGTH 9 - char cid[CID_LENGTH]; - char tmp_header[MAX_SIP_URL_LENGTH + 2]; - char *remvtag = NULL; - char *domainloc = NULL; - char allow[MAX_SIP_HEADER_LENGTH]; - - /* - * This function builds and sends a SUBSCRIBE message. - * Specific subscription information including the encoded body, if any, - * is taken from the SCB pointer passed. The renew flag indicates that the - * SUBSCRIBE message is to be sent to renew a previous subscription - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), fname, "SUBSCRIBE"); - - if (!scbp) { - return FALSE; - } - // Fill in source and destination addresses - // Destination address should be the current CCM that is serving us - // In the future, this part of the code will be using the tables provided - // by the connection manager - - // First check if the application gave us any forwarding address - if (scbp->hb.dest_sip_addr.type == CPR_IP_ADDR_INVALID) { - sipTransportGetPrimServerAddress(scbp->hb.dn_line, addr); - dns_error_code = sipTransportGetServerAddrPort(addr, - &scbp->hb.dest_sip_addr, - (uint16_t *)&scbp->hb.dest_sip_port, - &scbp->hb.SRVhandle, - FALSE); - if (dns_error_code == 0) { - util_ntohl(&(scbp->hb.dest_sip_addr), &(scbp->hb.dest_sip_addr)); - } else { - sipTransportGetServerIPAddr(&(scbp->hb.dest_sip_addr), scbp->hb.dn_line); - } - scbp->hb.dest_sip_port = ((dns_error_code == 0) && - (scbp->hb.dest_sip_port)) ? - ntohs((uint16_t) scbp->hb.dest_sip_port) : (sipTransportGetPrimServerPort(scbp->hb.dn_line)); - } - ipaddr2dotted(src_addr_str, &scbp->hb.src_addr); - ipaddr2dotted(dest_sip_addr_str, &scbp->hb.dest_sip_addr); - - // Get the MAC address once - since need it in several places - platform_get_wired_mac_address(mac_address); - - // If there is a related dialog, use the From header + tag, - // To header + tag, and the call-id from that dialog - if (scbp->ccbp) { - if (scbp->ccbp->flags & INCOMING) { - // If the call was incoming - reverse the headers for an - // outgoing request - scbp->sip_to = strlib_copy(scbp->ccbp->sip_from); - scbp->sip_to_tag = strlib_copy(scbp->ccbp->sip_from_tag); - scbp->sip_from = strlib_copy(scbp->ccbp->sip_to); - scbp->sip_from_tag = strlib_copy(scbp->ccbp->sip_to_tag); - } else { - // Otherwise copy then in order - scbp->sip_from = strlib_copy(scbp->ccbp->sip_from); - scbp->sip_from_tag = strlib_copy(scbp->ccbp->sip_from_tag); - scbp->sip_to = strlib_copy(scbp->ccbp->sip_to); - scbp->sip_to_tag = strlib_copy(scbp->ccbp->sip_to_tag); - } - - if (scbp->ccbp && - (scbp->ccbp->state >= SIP_STATE_SENT_INVITE_CONNECTED)) { - sstrncpy(scbp->SubURI, scbp->ccbp->ReqURI, MAX_SIP_URL_LENGTH); - } else { - sstrncpy(scbp->SubURI, "sip:", MAX_SIP_URL_LENGTH); - domainloc = scbp->SubURI + strlen(scbp->SubURI); - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - (scbp->SubURI))); - } - sstrncpy(scbp->hb.sipCallID, scbp->ccbp->sipCallID, MAX_SIP_CALL_ID); - } else if (!renew) { - // Create the From header - sip_from_temp = strlib_open(scbp->sip_from, MAX_SIP_URL_LENGTH); - if (sip_from_temp) { - // Use the subscriberURI, if present - if (scbp->SubscriberURI[0] != '\0') { - if (scbp->hb.src_addr.type == CPR_IP_ADDR_IPV6) { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - scbp->SubscriberURI, src_addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - scbp->SubscriberURI, src_addr_str); - } - } else if (scbp->useDeviceAddressing) { - if (scbp->hb.src_addr.type == CPR_IP_ADDR_IPV6) { - - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str); - } - } else { - sip_config_get_display_name(scbp->hb.dn_line, display_name, - sizeof(display_name)); - config_get_line_string(CFGID_LINE_NAME, line_name, - scbp->hb.dn_line, sizeof(line_name)); - if (scbp->hb.src_addr.type == CPR_IP_ADDR_IPV6) { - - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "\"%s\" ", display_name, - line_name, src_addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "\"%s\" ", display_name, - line_name, src_addr_str); - } - } - - // Add tag to the From header (need to allocate and fill in scbp->sip_from_tag - sip_from_tag = strlib_open(scbp->sip_from_tag, MAX_SIP_URL_LENGTH); - if (sip_from_tag) { - sip_util_make_tag(sip_from_tag); - sstrncat(sip_from_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - sstrncat(sip_from_temp, sip_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - scbp->sip_from_tag = strlib_close(sip_from_tag); - } - scbp->sip_from = strlib_close(sip_from_temp); - - // Create the Call-ID header - For now create own call-id - count++; - - snprintf(scbp->hb.sipCallID, MAX_SIP_CALL_ID, - "%.4x%.4x-%.4x%.4x-%.8x-%.8x@%s", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], count, - (unsigned int) cpr_rand(), - (unsigned int) cpr_rand(), - src_addr_str); - - // Create the ReqURI - sstrncpy(scbp->SubURI, "sip:", MAX_SIP_URL_LENGTH); - - /* Indialog requests should contain suburi only - */ - sstrncat(scbp->SubURI, scbp->SubURIOriginal, MAX_SIP_URL_LENGTH - sizeof("sip:")); - domainloc = strchr(scbp->SubURI, '@'); - if (domainloc == NULL) { - domainloc = scbp->SubURI + strlen(scbp->SubURI); - if ((domainloc - scbp->SubURI) < (MAX_SIP_URL_LENGTH - 1)) { - /* Do not include @ when there is no user part */ - if (scbp->SubURIOriginal[0] != '\0') { - *domainloc++ = '@'; - } - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - (scbp->SubURI))); - } - } - // Create the To header - sip_to_temp = strlib_open(scbp->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - snprintf(sip_to_temp, MAX_SIP_URL_LENGTH, "<%s>", scbp->SubURI); - scbp->sip_to = strlib_close(sip_to_temp); - } - } - - method = sipMethodSubscribe; - - - scbp->last_sent_request_cseq_method = method; - - // Get a blank SIP message template and fill it in - request = GET_SIP_MESSAGE(); - if (!request) { - return FALSE; - } - // Can't use CreateRequest to fill in the message since not using CCB. So - // do the following: - // 1. Add request line (sipSPIAddRequestLine). - if (HSTATUS_SUCCESS != sippmh_add_request_line(request, - sipGetMethodString(method), - scbp->SubURI, SIP_VERSION)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Request line", fname); - free_sip_message(request); - return (FALSE); - } - // 2. Add local Via (sipSPIAddLocalVia) - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(scbp->hb.dn_line, TRUE, NULL), - src_addr_str, scbp->hb.local_port, VIA_BRANCH, - VIA_BRANCH_START, (unsigned int) cpr_rand()); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_VIA, via)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding VIA header", fname); - free_sip_message(request); - return (FALSE); - } - - // 3. Add common headers (sipSPIAddCommonHeaders) - if ((HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_FROM, scbp->sip_from)) || - (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_TO, scbp->sip_to)) || - (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CALLID, scbp->hb.sipCallID)) || - (HSTATUS_SUCCESS != sipAddDateHeader(request)) || - (HSTATUS_SUCCESS != sm_add_cseq(scbp, method, request))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding either From, To, CallID, " - "Date or Cseq header\n", fname); - free_sip_message(request); - return (FALSE); - } - // 4. Add text headers (sippmh_add_text_header) - (void) sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - - // 5. Add general headers (AddGeneralHeaders) - // Event header is not needed for Refer msg - if (method != sipMethodRefer) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_EVENT, - scbp->event_name)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Event header", fname); - free_sip_message(request); - return (FALSE); - } - } - - if (scbp->hb.accept_type == CC_SUBSCRIPTIONS_DIALOG) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - dialogAcceptHeader); - } else if (scbp->hb.event_type == CC_SUBSCRIPTIONS_KPML) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - kpmlResponseAcceptHeader); - } else if (scbp->hb.event_type == CC_SUBSCRIPTIONS_DIALOG) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - dialogAcceptHeader); - } else if (scbp->hb.event_type == CC_SUBSCRIPTIONS_PRESENCE) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - presenceAcceptHeader); - } - if (HSTATUS_SUCCESS != flag) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Accept header", fname); - free_sip_message(request); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_EXPIRES, - scbp->hb.expires)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Expires header", fname); - free_sip_message(request); - return (FALSE); - } - // Add max-forwards header - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_forwards_value, - sizeof(max_forwards_value)); - if (HSTATUS_SUCCESS != - sippmh_add_int_header(request, SIP_HEADER_MAX_FORWARDS, - max_forwards_value)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Max-Forwards header", fname); - free_sip_message(request); - return (FALSE); - } - // Add Contact header - if (HSTATUS_SUCCESS != sm_add_contact(&(scbp->hb), request)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header", fname); - free_sip_message(request); - return (FALSE); - } - - if (authen) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, AUTHOR_HDR(scbp->hb.authen.status_code), - scbp->hb.authen.authorization)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Authorization header", fname); - free_sip_message(request); - return (FALSE); - } - } - - if (scbp->norefersub) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_REQUIRE, "norefersub")) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Require header", fname); - free_sip_message(request); - return (FALSE); - } - } - - if (method == sipMethodRefer) { - // Add Refer-To, Referred-By, and Content-ID headers - sstrncpy(tmp_header, (const char *) (scbp->sip_from), MAX_SIP_URL_LENGTH + 1); - remvtag = strstr(tmp_header, ";tag="); - if (remvtag) { - *remvtag = '\0'; - } - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_REFERRED_BY, tmp_header)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Referred-By header", fname); - free_sip_message(request); - return (FALSE); - } - - snprintf(cid, sizeof(cid), "%.8x", (unsigned int)cpr_rand()); - snprintf(tmp_header, sizeof(tmp_header), "cid:%s@%s", cid, src_addr_str); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_REFER_TO, tmp_header)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Refer-To header", fname); - free_sip_message(request); - return (FALSE); - } - - snprintf(tmp_header, sizeof(tmp_header), "<%s@%s>", cid, src_addr_str); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CONTENT_ID, tmp_header)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-ID header", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Add Allow - snprintf(allow, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_REGISTER, SIP_METHOD_UPDATE, - SIP_METHOD_SUBSCRIBE); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_ALLOW, allow)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Allow header", fname); - free_sip_message(request); - return (FALSE); - } - - /* - * Add route header if needed. - */ - if (FALSE == sipSPIAddRouteHeadersToSubNot(request, scbp, NULL, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Route header", fname); - free_sip_message(request); - return (FALSE); - } - // Add content, if any - if (scbp->hb.event_data_p) { - if (add_content(scbp->hb.event_data_p, request, fname) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content", fname); - free_sip_message(request); - return (FALSE); - } - } else { - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-Len", fname); - free_sip_message(request); - return (FALSE); - } - } - - ccsip_common_util_set_retry_settings((ccsip_common_cb_t *)scbp, &timeout); - if (sipTransportCreateSendMessage(NULL, request, method, - &(scbp->hb.dest_sip_addr), - (int16_t) scbp->hb.dest_sip_port, - FALSE, TRUE, timeout, scbp, - RELDEV_NO_STORED_MSG) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send message", fname); - return (FALSE); - } - - return (TRUE); -} - -/************************************************************** - * Format and send a response to a network received SUBSCRIBE - **************************************************************/ -boolean -sipSPISendSubscribeNotifyResponse (sipSCB_t *scbp, - uint16_t response_code, - uint32_t cseq) -{ - const char *fname = "sipSPISendSubscribeNotifyResponse"; - sipMessage_t *response = NULL; - sipVia_t *via = NULL; - sub_not_trxn_t *trxn_p; - int status_code = 0; - - // currently not used const char *request_callid = NULL; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t cc_remote_port = 0; - - // currently not used int timeout = 0; - char *pViaHeaderStr = NULL; - char *dest_ip_addr_str = 0; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char response_text[MAX_SIP_URL_LENGTH]; - boolean port_present = FALSE; - int reldev_stored_msg; - - sipRet_t tflag = HSTATUS_SUCCESS; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), fname, response_code); - - memset(&cc_remote_ipaddr, 0, sizeof(cpr_ip_addr_t)); - cc_remote_ipaddr = ip_addr_invalid; - if (!scbp) { - return FALSE; - } - - /* - * In the response to Subscribe: - * The Via header gets a ";received" addition (...;received: 192.168.0.7) - * The From header is the same as in the subscribe request - * The To header is the same as in the subscribe request but has a tag - * The call-id is the same as in the request - * Content Length is set to 0 - */ - response = GET_SIP_MESSAGE(); - if (!response) { - return FALSE; - } - - get_sip_error_string(response_text, response_code); - - tflag = sippmh_add_response_line(response, SIP_VERSION, response_code, - response_text); - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding response line", fname); - free_sip_message(response); - return FALSE; - } - - /* - * find the transaction and fetch the via header - */ - trxn_p = sll_find(scbp->incoming_trxns, &cseq); - if (trxn_p) { - pViaHeaderStr = trxn_p->via; - /* remove the transaction because we are done with it */ - (void)sll_remove(scbp->incoming_trxns, trxn_p); - cpr_free(trxn_p); - } - if (pViaHeaderStr) { - via = sippmh_parse_via(pViaHeaderStr); - } - if (!via || !pViaHeaderStr) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "No or Bad Via Header present in Message!"); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in parsing Via header", fname); - if (via) - sippmh_free_via(via); - free_sip_message(response); - cpr_free(pViaHeaderStr); - return (FALSE); - } - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_VIA, pViaHeaderStr)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Via header", fname); - sippmh_free_via(via); - free_sip_message(response); - cpr_free(pViaHeaderStr); - return (FALSE); - } - /* free the via header because we will not need it anymore */ - cpr_free(pViaHeaderStr); - - // Add common headers: From, To, CallID, Date, CSeq, Contact - // Note: If this is a response to a NOTIFY, then from and to headers - // must be reversed - if (scbp->last_recv_request_cseq_method == sipMethodNotify) { - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_FROM, scbp->sip_to)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding From header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_TO, scbp->sip_from)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding To header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - } else { - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_FROM, scbp->sip_from)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding From header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_TO, scbp->sip_to)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding To header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - } - - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_CALLID, scbp->hb.sipCallID)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CallID header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sipAddDateHeader(response)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Date header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sippmh_add_cseq(response, - sipGetMethodString(scbp-> - last_recv_request_cseq_method), - cseq)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSeq header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - tflag = sippmh_add_text_header(response, SIP_HEADER_SERVER, sipHeaderServer); - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Server header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - ipaddr2dotted(src_addr_str, &scbp->hb.src_addr); - - tflag = sm_add_contact(&(scbp->hb), response); - - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - // Add expires header - only for a SUBSCRIBE response - if (scbp->last_recv_request_cseq_method == sipMethodSubscribe) { - if (sippmh_add_int_header(response, SIP_HEADER_EXPIRES, scbp->hb.expires) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Expires header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - /* - * add Record-Route Header, if it is a response (18x/2xx) to - * dialog initiating SUBSCRIBE. - */ - if ((scbp->cached_record_route[0] != '\0') && - (((response_code >= 180) && (response_code <= 189)) || - ((response_code >= 200) && (response_code <= 299)))) { - tflag = sippmh_add_text_header(response, SIP_HEADER_RECORD_ROUTE, - scbp->cached_record_route); - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Record-Route header", - fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - } - /* free the cached record_route, once the final resp is sent */ - if (response_code >= 200) { - strlib_free(scbp->cached_record_route); - scbp->cached_record_route = strlib_empty(); - } - } - // Add other headers such as content-length, content-type - if (HSTATUS_SUCCESS != sippmh_add_int_header(response, SIP_HEADER_CONTENT_LENGTH, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-Length header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - // Send Response - // Get information on where to send the response from via headers - if (via->remote_port) { - cc_remote_port = via->remote_port; - port_present = TRUE; - } else { - /* Use default 5060 if via does not have port */ - cc_remote_port = SIP_WELL_KNOWN_PORT; - } - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Via host: %s, port: %d, rcvd host: %s", - fname, via->host, via->remote_port, via->recd_host); - - if (via->maddr) { - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(via->maddr, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(via->maddr, &cc_remote_ipaddr, - 100, 1); - } - - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - "sipTransportGetServerAddrPort or dnsGetHostByName()"); - } else { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } - } - // If all else fails send the response to where we got the request from - if (cc_remote_ipaddr.type == CPR_IP_ADDR_INVALID) { - if (via->recd_host) { - dest_ip_addr_str = via->recd_host; - } else { - dest_ip_addr_str = via->host; - } - - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(dest_ip_addr_str, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(dest_ip_addr_str, - &cc_remote_ipaddr, 100, 1); - } - - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - "sipTransportGetServerAddrPort or dnsGetHostByName()"); - // cpr_free(request_cseq_structure); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } else { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } - } - // Store cc_remote_ipaddr and cc_remote_port values in SCB for later use - // in the corresponding NOTIFY, if any - scbp->hb.dest_sip_addr = cc_remote_ipaddr; - scbp->hb.dest_sip_port = cc_remote_port; - - reldev_stored_msg = sipRelDevCoupledMessageStore(response, scbp->hb.sipCallID, - cseq, - scbp->last_recv_request_cseq_method, - FALSE, - status_code, - &cc_remote_ipaddr, - cc_remote_port, TRUE); - - sippmh_free_via(via); - - scbp->hb.retx_flag = FALSE; - if (sipTransportCreateSendMessage(NULL, response, sipMethodSubscribe, - &cc_remote_ipaddr, cc_remote_port, - FALSE, TRUE, 0, scbp, reldev_stored_msg) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send message", fname); - return (FALSE); - } - - return (TRUE); -} - -/************************************************************** - * Format and send a locally generated NOTIFY - **************************************************************/ -boolean -sipSPISendSubNotify (ccsip_common_cb_t *cbp, boolean authen) -{ - const char *fname = "SIPSPISendSubNotify"; - sipMessage_t *request = NULL; - static uint32_t cseq = 0; - - // currently not used char *message_body = NULL; - // currently not used sipRet_t flag = STATUS_SUCCESS; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char addr[MAX_IPADDR_STR_LEN]; - - // currently not used uint32_t nbytes = SIP_UDP_MESSAGE_SIZE; - char via[SIP_MAX_VIA_LENGTH]; - - // currently not used short send_to_proxy_handle = INVALID_SOCKET; - static char ReqURI[MAX_SIP_URL_LENGTH]; - static char sip_temp_str[MAX_SIP_URL_LENGTH]; - static char sip_temp_tag[MAX_SIP_URL_LENGTH]; - sipSubscriptionStateInfo_t subs_state; - int timeout = 0, max_forwards_value = 70; - char allow[MAX_SIP_HEADER_LENGTH]; - sipSCB_t *scbp = (sipSCB_t *)cbp; - sipTCB_t *tcbp = (sipTCB_t *)cbp; - - /* - * This function builds and sends a NOTIFY message as a follow up to - * a previously received SUBSCRIBE - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), fname, "NOTIFY"); - - if (!cbp) { - return FALSE; - } - - if (util_check_if_ip_valid(&cbp->dest_sip_addr)== FALSE) { - sipTransportGetPrimServerAddress(scbp->hb.dn_line, addr); - - dns_error_code = sipTransportGetServerAddrPort(addr, - &cbp->dest_sip_addr, - (uint16_t *)&cbp->dest_sip_port, - &cbp->SRVhandle, - FALSE); - - if (dns_error_code == 0) { - util_ntohl(&(cbp->dest_sip_addr), &(cbp->dest_sip_addr)); - } else { - sipTransportGetServerIPAddr(&(cbp->dest_sip_addr), cbp->dn_line); - } - - cbp->dest_sip_port = ((dns_error_code == 0) && - (cbp->dest_sip_port)) ? - ntohs(cbp->dest_sip_port) : (sipTransportGetPrimServerPort(cbp->dn_line)); - - } - - ipaddr2dotted(src_addr_str, &cbp->src_addr); - ipaddr2dotted(dest_sip_addr_str, &cbp->dest_sip_addr); - - // Create the request - request = GET_SIP_MESSAGE(); - - /* - * Determine the Request-URI - */ - memset(ReqURI, 0, sizeof(ReqURI)); - - if (cbp->cb_type == SUBNOT_CB) { - if (scbp->contact_info) { - // Build Req-URI from contact info - sipContact_t *response_contact_info; - sipUrl_t *sipUrl = NULL; - cpr_ip_addr_t request_uri_addr; - uint16_t request_uri_port = 0; - - request_uri_addr = ip_addr_invalid; - - response_contact_info = scbp->contact_info; - if (response_contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - sipUrl = response_contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"URL is not SIP", fname); - free_sip_message(request); - return (FALSE); - } - - request_uri_port = sipUrl->port; - dns_error_code = sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &request_uri_addr, - &request_uri_port, NULL, FALSE); - if (dns_error_code == 0) { - util_ntohl(&request_uri_addr, &request_uri_addr); - } else { - request_uri_addr = ip_addr_invalid; - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? - "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? - "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", - sipUrl->user, sipUrl->host, - sipUrl->port); - } - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? - "sip:%s:%d;user=phone" : - "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else { - // Build Req-URI from FROM field - sipLocation_t *request_uri_loc = NULL; - char sip_from[MAX_SIP_URL_LENGTH]; - sipUrl_t *request_uri_url = NULL; - - sstrncpy(sip_from, scbp->sip_from, MAX_SIP_URL_LENGTH); - request_uri_loc = sippmh_parse_from_or_to(sip_from, TRUE); - if (!request_uri_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_from_or_to(TO)"); - free_sip_message(request); - return (FALSE); - } - - if (!sippmh_valid_url(request_uri_loc->genUrl)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_valid_url()"); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Caller): using original " - "Req-URI\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - /* - * if (request_uri_loc->name) { - * if (request_uri_loc->name[0]) { - * sstrncat(ReqURI, "\"", sizeof(ReqURI)-strlen(ReqURI)); - * sstrncat(ReqURI, request_uri_loc->name, - * sizeof(ReqURI)-strlen(ReqURI)); - * sstrncat(ReqURI, "\" ", sizeof(ReqURI)-strlen(ReqURI)); - * } - * } - */ - sstrncat(ReqURI, "sip:", sizeof(ReqURI) - strlen(ReqURI)); - if (request_uri_loc->genUrl->schema == URL_TYPE_SIP) { - request_uri_url = request_uri_loc->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"URL is not SIP", fname); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - if (request_uri_url->user) { - sstrncat(ReqURI, request_uri_url->user, - sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, "@", sizeof(ReqURI) - strlen(ReqURI)); - } - if (request_uri_url->is_phone) { - sstrncat(ReqURI, ";user=phone", - sizeof(ReqURI) - strlen(ReqURI)); - } - sstrncat(ReqURI, request_uri_url->host, - sizeof(ReqURI) - strlen(ReqURI)); - // sstrncat(ReqURI, ">", sizeof(ReqURI)-strlen(ReqURI)); - sippmh_free_location(request_uri_loc); - } - } else { //Unsolicited NOTIFY - char line_name[MAX_LINE_NAME_SIZE]; - config_get_line_string(CFGID_LINE_NAME, line_name, cbp->dn_line, sizeof(line_name)); - snprintf(ReqURI, MAX_SIP_URL_LENGTH, "sip:%s@%s", line_name, dest_sip_addr_str); - sstrncpy(tcbp->full_ruri, ReqURI, MAX_SIP_URL_LENGTH); - } - (void) sippmh_add_request_line(request, - sipGetMethodString(sipMethodNotify), - ReqURI, SIP_VERSION); - - // The Via header has the local URI and a new branch - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(cbp->dn_line, TRUE, NULL), - src_addr_str, cbp->local_port, VIA_BRANCH, - VIA_BRANCH_START, (unsigned int) cpr_rand()); - - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_VIA, via)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding VIA header", fname); - free_sip_message(request); - return (FALSE); - } - - // The To field including the tag is the same as the From field in the - // response to SUBSCRIBE - if (cbp->cb_type != SUBNOT_CB) { - snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "<%s>", ReqURI); - } - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_TO, - ((cbp->cb_type == SUBNOT_CB) ? scbp->sip_from : sip_temp_str))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding To header", fname); - free_sip_message(request); - return (FALSE); - } - - // The From field including the tag is the same as the To field in the - // response to SUBSCRIBE - if (cbp->cb_type != SUBNOT_CB) { - sstrncat(sip_temp_str, ";tag=", MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - sip_util_make_tag(sip_temp_tag); - sstrncat(sip_temp_str, sip_temp_tag, MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - } - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_FROM, - ((cbp->cb_type == SUBNOT_CB) ? scbp->sip_to : sip_temp_str))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding From header", fname); - free_sip_message(request); - return (FALSE); - } - // The call-id used is the same as in the SCB - if (cbp->sipCallID[0] == 0) { - snprintf(tcbp->hb.sipCallID, sizeof(tcbp->hb.sipCallID), "%.8x-%.8x@%s", // was MAX_SIP_URL_LENGTH - (unsigned int) cpr_rand(), - (unsigned int) cpr_rand(), - src_addr_str); - } - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CALLID, cbp->sipCallID)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CallID header", fname); - free_sip_message(request); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sipAddDateHeader(request)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Date header", fname); - free_sip_message(request); - return (FALSE); - } - - if (cbp->cb_type == SUBNOT_CB) { - if (sm_add_cseq(scbp, sipMethodNotify, request) != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSeq header", fname); - free_sip_message(request); - return (FALSE); - } - } else { - cseq++; - if (cseq == 0) { - cseq = 1; - } - if (HSTATUS_SUCCESS != sippmh_add_cseq(request, sipGetMethodString(sipMethodNotify), cseq)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSEQ header", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Event is the event name - // The subscription-state header is active - if (cbp->event_type - CC_SUBSCRIPTIONS_DIALOG > -1 && - cbp->event_type - CC_SUBSCRIPTIONS_DIALOG < 5) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_EVENT, - eventNames[cbp->event_type - CC_SUBSCRIPTIONS_DIALOG])) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Event header", fname); - free_sip_message(request); - return (FALSE); - } - } - - subs_state.expires = cbp->expires; - if (cbp->cb_type == SUBNOT_CB) { - if (subs_state.expires > 0) { - subs_state.state = SUBSCRIPTION_STATE_ACTIVE; - } else { - subs_state.state = SUBSCRIPTION_STATE_TERMINATED; - } - } else { - subs_state.state = SUBSCRIPTION_STATE_ACTIVE; - } - if (sippmh_add_subscription_state(request, &subs_state) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Subscription-State header", fname); - free_sip_message(request); - return (FALSE); - } - // Add max-forwards header - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_forwards_value, - sizeof(max_forwards_value)); - (void) sippmh_add_int_header(request, SIP_HEADER_MAX_FORWARDS, - max_forwards_value); - - // Add contact header - if (sm_add_contact(cbp, request) != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header", fname); - free_sip_message(request); - return (FALSE); - } - - if (authen) { - (void) sippmh_add_text_header(request, - AUTHOR_HDR(scbp->hb.authen.status_code), - scbp->hb.authen.authorization); - } - // Add Allow - snprintf(allow, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_REGISTER, SIP_METHOD_UPDATE, - SIP_METHOD_SUBSCRIBE); - (void) sippmh_add_text_header(request, SIP_HEADER_ALLOW, allow); - - if (cbp->cb_type == SUBNOT_CB) { - /* keep the request method to be sent */ - scbp->last_sent_request_cseq_method = sipMethodNotify; - /* - * Add route header if needed. - */ - if (FALSE == sipSPIAddRouteHeadersToSubNot(request, scbp, NULL, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Route header", fname); - free_sip_message(request); - return (FALSE); - } - ccsip_common_util_set_retry_settings((ccsip_common_cb_t *)scbp, &timeout); - } - - // Add content, if any - if (cbp->event_data_p) { - if (add_content(cbp->event_data_p, request, fname) == FALSE) { - free_sip_message(request); - return (FALSE); - } - } else { - (void) sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - } - - if (sipTransportCreateSendMessage(NULL, request, sipMethodNotify, - &(scbp->hb.dest_sip_addr), - (int16_t) scbp->hb.dest_sip_port, - FALSE, TRUE, timeout, cbp, - RELDEV_NO_STORED_MSG) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in sending message", fname); - return (FALSE); - } - - return (TRUE); -} - -/************************************************************** - * Handle message retries - *************************************************************/ -int -subsmanager_handle_retry_timer_expire (int scb_index) -{ - const char *fname = "subsmanager_handle_retry_timer_expire"; - sipSCB_t *scbp = NULL; - uint32_t max_retx = 0; - ccsip_sub_not_data_t sub_not_result_data; - uint32_t time_t1 = 0; - uint32_t time_t2 = 0; - uint32_t timeout = 0; - - CCSIP_DEBUG_TASK("Entering %s. scb_index: %d", fname, scb_index); - - if (scb_index < 0 || scb_index >= MAX_SCBS) { - return (-1); - } - scbp = &(subsManagerSCBS[scb_index]); - - if (scbp->hb.retx_flag == TRUE) { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - if (scbp->hb.retx_counter < max_retx) { - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - scbp->hb.retx_counter++; - timeout = time_t1 * (1 << scbp->hb.retx_counter); - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Resending message #%d", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scbp->hb.retx_counter); - if (sipTransportSendMessage(NULL, - sipPlatformUISMSubNotTimers[scb_index].message_buffer, - sipPlatformUISMSubNotTimers[scb_index].message_buffer_len, - sipPlatformUISMSubNotTimers[scb_index].message_type, - &(sipPlatformUISMSubNotTimers[scb_index].ipaddr), - sipPlatformUISMSubNotTimers[scb_index].port, - FALSE, TRUE, timeout, scbp) < 0) { - return (-1); - } - } else { - // Should we terminate this dialog? At the very least - stop - // the timer block, display error, and send a message to the app - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Either exceeded max retries for UDP" - " or Timer F fired for TCP\n", fname); - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[scb_index]); - scbp->hb.retx_flag = FALSE; - scbp->hb.retx_counter = 0; - - memset(&sub_not_result_data, 0, sizeof(sub_not_result_data)); - sub_not_result_data.request_id = scbp->request_id; - sub_not_result_data.sub_id = scbp->sub_id; - sub_not_result_data.gsm_id = scbp->gsm_id; - sub_not_result_data.line_id = scbp->hb.dn_line; - - if ((scbp->last_sent_request_cseq_method == sipMethodSubscribe) || - (scbp->last_sent_request_cseq_method == sipMethodRefer)) { - sub_not_result_data.u.subs_result_data.status_code = REQUEST_TIMEOUT; - sip_send_error_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->subsResCallbackMsgID, - scbp->subsResultCallback, fname); - } else { - sub_not_result_data.u.notify_result_data.status_code = REQUEST_TIMEOUT; - // Set the state to ACTIVE, so we can go on appropriately. Note that - // this assignment below should be placed before sip_send_error_message() so - // that in case of callback running on same thread freed the scb, we will not - // set it back to active and try to use it later. - scbp->smState = SUBS_STATE_ACTIVE; - sip_send_error_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->notResCallbackMsgID, - scbp->notifyResultCallback, fname); - } - // If there are any pending requests, execute them now - if (scbp->pendingRequests) { - handle_pending_requests(scbp); - } - } - } - - return (0); -} - -/************************************************************** - * Handle periodic timer - *************************************************************/ -void -subsmanager_handle_periodic_timer_expire (void) -{ - const char *fname = "subsmanager_handle_periodic_timer_expire"; - sipSCB_t *scbp = NULL; - int scb_index; - ccsip_sub_not_data_t subs_term_data; - sipspi_msg_t subscribe; - int subscription_delta = 0; - - // static char count = 0; - /* - * Go through the list of SCBs and pick out the ones for - * which some action needs to be taken. This action may include: - * 1. If an incoming SUBSCRIBE has expired, inform the application - * 2. If auto-subscribe is set on an outgoing subscribe, send - * a re-SUBSCRIBE message - */ - config_get_value(CFGID_TIMER_SUBSCRIBE_DELTA, &subscription_delta, - sizeof(subscription_delta)); - for (scb_index = 0; scb_index < MAX_SCBS; scb_index++) { - scbp = &(subsManagerSCBS[scb_index]); - if (scbp->pendingClean) { - if (scbp->pendingCount > 0) { - scbp->pendingCount -= TMR_PERIODIC_SUBNOT_INTERVAL; - } else { - free_scb(scb_index, fname); - } - continue; - } - if (scbp->smState == SUBS_STATE_REGISTERED) { - continue; - } - if (scbp->smState != SUBS_STATE_IDLE) { - if (scbp->hb.expires > 0) { - scbp->hb.expires -= TMR_PERIODIC_SUBNOT_INTERVAL; - } - if (scbp->hb.expires > (subscription_delta + TMR_PERIODIC_SUBNOT_INTERVAL)) { - continue; - } - - if (scbp->internal) { - // Subscription was internally generated - if (scbp->auto_resubscribe) { - if (scbp->smState != SUBS_STATE_SENT_SUBSCRIBE) { - // Send re-SUBSCRIBE message - but not if we just sent one - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Auto reSubscribing:" - " scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - memset(&subscribe, 0, sizeof(sipspi_msg_t)); - subscribe.msg.subscribe.sub_id = scbp->sub_id; - subscribe.msg.subscribe.duration = scbp->hb.orig_expiration; - (void) subsmanager_handle_ev_app_subscribe(&subscribe); - } - } else { - // Let app know its own SUBSCRIBE is about to expire - // Application SHOULD renew its own subscription - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notifying App of internal" - " expiry: scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - subs_term_data.sub_id = scbp->sub_id; - subs_term_data.event = scbp->hb.event_type; - subs_term_data.msg_id = scbp->subsTermCallbackMsgID; - subs_term_data.request_id = scbp->request_id; - subs_term_data.reason_code = SM_REASON_CODE_NORMAL; - subs_term_data.u.subs_term_data.status_code = - APPLICATION_SUBSCRIPTION_EXPIRED; - if (scbp->subsTermCallback) { - scbp->subsTermCallback(&subs_term_data); - } else if (scbp->subsIndCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&subs_term_data, scbp->subsIndCallbackTask, - scbp->subsTermCallbackMsgID); - } - } - - } else { - // Subscription was received from network - if (scbp->hb.expires <= 0) { - // Let app know this SUBSCRIBE has expired - // App SHOULD send final NOTIFY and terminate the session - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notifying App of external" - " expiry: scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - subs_term_data.sub_id = scbp->sub_id; - subs_term_data.event = scbp->hb.event_type; - subs_term_data.msg_id = scbp->subsTermCallbackMsgID; - subs_term_data.line_id = scbp->hb.dn_line; - subs_term_data.gsm_id = scbp->gsm_id; - subs_term_data.reason_code = SM_REASON_CODE_NORMAL; - subs_term_data.u.subs_term_data.status_code = - NETWORK_SUBSCRIPTION_EXPIRED; - if (scbp->subsTermCallback) { - scbp->subsTermCallback(&subs_term_data); - } else if (scbp->subsIndCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&subs_term_data, scbp->subsIndCallbackTask, - scbp->subsTermCallbackMsgID); - } - } - } - } - } - // Re-start periodic timer - (void) sip_platform_subnot_periodic_timer_start(TMR_PERIODIC_SUBNOT_INTERVAL * 1000); - - /* - * Comment out the periodic show since now we have a show-subscription-statistics CLI - * Do not want to completely remove this code since the CLI is not available in - * IP-Communicator where this could be enabled for debugging - */ - /* - * if (count == 50) { - * // Show the stats for the Subsmanager - * CCSIP_DEBUG_TASK("Reg - RecdSubs RecdNots ActiveExtSubs - SentSubs SentNots ActiveIntSubs - CurSCBs MaxSCBs"); - * CCSIP_DEBUG_TASK("-----------------------------------------------------------------------------------"); - * CCSIP_DEBUG_TASK("%d - %d %d %d - %d %d %d - %d %d", - * internalRegistrations, incomingSubscribes, - * incomingNotifies, incomingSubscriptions, - * outgoingSubscribes, outgoingNotifies, - * outgoingSubscriptions, currentScbsAllocated, - * maxScbsAllocated); - * count = 0; - * } else { - * count ++; - * } - */ -} - -/************************************************************** - * Format and send a response to a network received NOTIFY - * Currently this action is handled together with the response - * to SUBSCRIBE - **************************************************************/ -boolean -sipSPISendSubNotifyResponse (sipSCB_t *scbp, int response_code) -{ - return TRUE; -} - -static void -show_scbs_inuse () -{ - int i; - sipSCB_t *scbp = NULL; - - if (subsManagerRunning == 0) { - return; - } - - debugif_printf("---------SCB DUMP----------\n"); - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - if (scbp->smState == SUBS_STATE_IDLE) { - debugif_printf("SCB# %d, State = %d (IDLE)\n", i, scbp->smState); - continue; - } - if (scbp->smState == SUBS_STATE_REGISTERED) { - debugif_printf("SCB# %d, State = %d (REGISTERED) sub_id=%x\n", - i, scbp->smState, scbp->sub_id); - debugif_printf("SCB# %d, eventPackage=%d\n", - i, scbp->hb.event_type); - continue; - } - debugif_printf("SCB# %d, State = %d sub_id=%x\n", i, scbp->smState, - scbp->sub_id); - debugif_printf("SCB# %d, pendingClean=%d, internal=%d, eventPackage=%d, " - "norefersub=%d, subscriptionState=%d, expires=%ld", i, - scbp->pendingClean, scbp->internal, scbp->hb.event_type, - scbp->norefersub, scbp->subscription_state, scbp->hb.expires); - debugif_printf("-----------------------------\n"); - } -} - -cc_int32_t -show_subsmanager_stats (cc_int32_t argc, const char *argv[]) -{ - debugif_printf("------ Current Subsmanager Statistics ------\n"); - debugif_printf("Internal Registrations: %d\n", internalRegistrations); - debugif_printf("Total Incoming Subscribes: %d\n", incomingSubscribes); - debugif_printf("Total Incoming Notifies: %d\n", incomingNotifies); - debugif_printf("Total Incoming Unsolicited Notifies: %d\n", incomingUnsolicitedNotifies); - debugif_printf("Active Incoming Subscriptions: %d\n", incomingSubscriptions); - debugif_printf("Total Outgoing Subscribes: %d\n", outgoingSubscribes); - debugif_printf("Total Outgoing Notifies: %d\n", outgoingNotifies); - debugif_printf("Total Outgoing Unsolicited Notifies: %d\n", outgoingUnsolicitedNotifies); - debugif_printf("Active Outgoing Subscriptions: %d\n", outgoingSubscriptions); - debugif_printf("Current SCBs Allocated: %d\n", currentScbsAllocated); - debugif_printf("Total Maximum SCBs Ever Allocated: %d\n", maxScbsAllocated); - debugif_printf("------ End of Subsmanager Statistics ------\n"); - - // Now print out the status of all SCBs - show_scbs_inuse(); - return 0; -} - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_task.c b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_task.c deleted file mode 100644 index 762c986a637..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_task.c +++ /dev/null @@ -1,2994 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_socket.h" -#include "cpr_timers.h" -#include "cpr_memory.h" -#include "cpr_in.h" -#include "cpr_ipc.h" -#include "phntask.h" -#include "util_string.h" -#include "task.h" -#include "phone.h" -#include "text_strings.h" -#include "ccsip_task.h" -#include "ccsip_core.h" -#include "ccsip_macros.h" -#include "ccsip_messaging.h" -#include "ccsip_sim.h" -#include "ccsip_platform_udp.h" -#include "ccsip_platform.h" -#include "phone_debug.h" -#include "ccsip_register.h" -#include "debug.h" -#include "ccsip_reldev.h" -#include "ccsip_cc.h" -#include "gsm.h" -#include "fim.h" -#include "ccapi.h" -#include "lsm.h" -#include "config.h" -#include "check_sync.h" -#include "sip_common_transport.h" -#include "uiapi.h" -#include "sip_csps_transport.h" -#include "sip_common_regmgr.h" -#include "sip_platform_task.h" -#include "platform_api.h" -#include "sip_interface_regmgr.h" -#include "ccsip_publish.h" -#include "platform_api.h" - -#ifdef SAPP_SAPP_GSM -#define SAPP_APP_GSM 3 -#define SAPP_APP SAPP_APP_GSM -#include "sapp.h" -#endif - -#if defined SIP_OS_WINDOWS -#include "../win32/cpr_win_defines.h" -#endif - - - -extern sipSCB_t *find_scb_by_callid(const char *callID, int *scb_index); -extern int platThreadInit(char *); -void sip_platform_handle_service_control_notify(sipServiceControl_t *scp); -short SIPTaskProcessTimerExpiration(void *msg, uint32_t *cmd); -extern cprMsgQueue_t gsm_msgq; -extern void ccsip_dump_recv_msg_info(sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port); - -// Global variables - - -/*--------------------------------------------------------- - * - * Definitions - * - */ - -#define MESSAGE_WAITING_STR_SIZE 5 - -#define MAC_ADDR_STR_LENGTH 16 -#define SIP_HEADER_SERVER_LEN 80 -#define SIP_HEADER_USER_AGENT_LEN 80 -#define SIP_PHONE_MODEL_NUMBER_LEN 32 - -/* The maximun number of gsm_msgq depth to allow new incoming call, - */ -/* - * for RT, the threshold of 60 is not based on testing. - * As discussed in CSCsz33584 Code Review, it is better to drop the heavy load as it enters the system than let it go deep into the system. - * So we add the same logic into RT, but RT still cannot pass the test in CSCsz33584. - * Bottleneck of RT might be ccapp_msgq instead of gsm_msgq. - * A more complex solution should be studied to prevent RT phone from overload. - */ -#define MAX_DEPTH_OF_GSM_MSGQ_TO_ALLOW_NEW_INCOMING_CALL 60 - -/* Internal request structure for restart/re-init request from platform */ -typedef enum { - SIP_RESTART_REQ_NONE, - SIP_RESTART_REQ_RESTART, /* to restart */ - SIP_RESTART_REQ_REINIT /* to re-init */ -} ccsip_restart_cmd; - -typedef enum { - SIP_SHUTDOWN_REQ_NONE, - SIP_SHUTDOWN_REQ_SHUT -} ccsip_shutdown_cmd; - -typedef struct ccsip_restart_req_t_ { - ccsip_restart_cmd cmd; /* restart command */ -} ccsip_restart_req; - -typedef struct ccsip_shutdown_req_t_ { - ccsip_shutdown_cmd cmd; /* shutdown command */ - int action; - int reason; -} ccsip_shutdown_req_t; - - -/*--------------------------------------------------------- - * - * Local Variables - * - */ -// static uint16_t nfds = 0; No reference. Should this be removed? -extern fd_set read_fds; -extern fd_set write_fds; -// static cpr_socket_t listenSocket = INVALID_SOCKET; No reference. Should this be removed? -// static sip_connection_t sipConn; Set in ccsip_task.c but never used. Should this be removed? -// static cprMsgQueue_t sip_msg_queue; No reference. Should this be removed? -// static cprRegion_t sip_region; No reference. Should this be removed? -// static cprPool_t sip_pool; No reference. Should this be removed? - - - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -sipGlobal_t sip; -boolean sip_mode_quiet = FALSE; -char sipHeaderServer[SIP_HEADER_SERVER_LEN]; -char sipHeaderUserAgent[SIP_HEADER_SERVER_LEN]; -char sipPhoneModelNumber[SIP_PHONE_MODEL_NUMBER_LEN]; -char sipUnregisterReason[MAX_SIP_REASON_LENGTH]; - -boolean Is794x = FALSE; - -/*--------------------------------------------------------- - * - * External Variables - * TODO reference through proper header files - */ -extern sipCallHistory_t gCallHistory[]; - - -/*--------------------------------------------------------- - * - * Function declarations - * - */ -static void SIPTaskProcessSIPMessage(sipMessage_t *message); -static int SIPTaskProcessSIPNotify(sipMessage_t *pSipMessage); -static int SIPTaskProcessSIPNotifyMWI(sipMessage_t *pSipMessage, - line_t dn_line); -static void SIPTaskProcessSIPNotifyCheckSync(sipMessage_t *pSipMessage); -static void SIPTaskProcessSIPPreviousCallByeResponse(sipMessage_t *pSipMessage, - int response_code, - line_t previous_call_index); -static void SIPTaskProcessSIPPreviousCallInviteResponse(sipMessage_t *pResponse, - int response_code, - line_t previous_call_index); -static void SIPTaskProcessSIPNotifyRefer(sipMessage_t *pSipMessage); -static int SIPTaskProcessSIPNotifyServiceControl(sipMessage_t *pSipMessage); -static void SIPTaskProcessRestart(ccsip_restart_cmd cmd); -static void SIPTaskProcessShutdown(int action, int reason); - -/*--------------------------------------------------------- - * - * Functions - * - */ -void -get_ua_model_and_device (char sipHdrUserAgent[]) -{ - const char fname[] = "get_ua_model_and_device"; - char *model = NULL; - - model = (char *)platGetModel(); - - if (model) { - if (strncmp(model, CSF_MODEL, 3) == 0) { - sstrncat(sipHdrUserAgent, CCSIP_SIP_CSF_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_CSF, - SIP_PHONE_MODEL_NUMBER_LEN); - } else if (strcmp(model, PHONE_MODEL) == 0) { - //if phone model is any of vendor defined, set as is. - sstrncat(sipHdrUserAgent, CCSIP_SIP_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER, - SIP_PHONE_MODEL_NUMBER_LEN); - } else { - // Default to 7970 - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"unknown model,defaulting to model 7970: %s", fname, model); - sstrncat(sipHdrUserAgent, CCSIP_SIP_7970_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_7970, - SIP_PHONE_MODEL_NUMBER_LEN); - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"could not obtain model information", fname); - sstrncat(sipHdrUserAgent, CCSIP_SIP_7970_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_7970, - SIP_PHONE_MODEL_NUMBER_LEN); - } -} - -extern void ccsip_debug_init(void); - -/** - * - * SIPTaskInit - * - * Initialize the SIP Task - * - * Parameters: None - * - * Return Value: SIP_OK - * - */ -void -SIPTaskInit (void) -{ - /* - * Initialize platform specific parameters - */ - - // sipConn is set but never used. Should this be removed? - // for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - // sipConn.read[i] = INVALID_SOCKET; - // sipConn.write[i] = INVALID_SOCKET; - //} - - /* - * Initialize cprSelect call parameters - */ - // XXX already did in sip_platform_task_init(), like, two instructions ago - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - /* - * Do the debug init right here so that we can enable - * sip debugs during startup and not wait for sip stack - * to initialize. - */ - ccsip_debug_init(); - - /************************ - // Move all initialization to sip_sm_init called after config - if (ccsip_register_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccsip_register_init() failed.", fname); - return SIP_ERROR; - } - - * - * Allocate timers for CCBs - * - if (sip_platform_timers_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_platform_timers_init() failed", fname); - return SIP_ERROR; - } - *************************/ - // Initialize the value of the UA and Server headers - sipHeaderUserAgent[0] = '\0'; - sipPhoneModelNumber[0] = '\0'; - sipHeaderServer[0] = '\0'; - -#if defined _COMMUNICATOR_ - sstrncat(sipHeaderUserAgent, CCSIP_SIP_COMMUNICATOR_USER_AGENT, - sizeof(sipHeaderUserAgent) - strlen(sipHeaderUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_COMMUNICATOR, - SIP_PHONE_MODEL_NUMBER_LEN); -#else - get_ua_model_and_device(sipHeaderUserAgent); -#endif - - // Now add the firmware version - sstrncat(sipHeaderUserAgent, "/", - sizeof(sipHeaderUserAgent) - strlen(sipHeaderUserAgent)); - sstrncat(sipHeaderUserAgent, gVersion, - sizeof(sipHeaderUserAgent) - strlen(sipHeaderUserAgent)); - sstrncpy(sipHeaderServer, sipHeaderUserAgent, - SIP_HEADER_SERVER_LEN); -} - - -/** - * - * SIPTaskSendMsg (API) - * - * The API to send a message to the SIP task - * - * Parameters: cmd - the message type - * msg - the message buffer to send - * len - length of the message buffer - * usr - user pointer TEMPORARY VALUE TO MOVE INTO msg - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -cpr_status_e -SIPTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, void *usr) -{ - /* Mozilla hack: just ignore everything that is posted here */ - (void)cmd; - cpr_free(msg); - (void)len; - (void)usr; - return CPR_SUCCESS; -} - -/** - * - * SIPTaskGetBuffer (API) - * - * The API to grab a buffer from the SIP buffer pool - * - * Parameters: size - size of the buffer requested - * - * Return Value: requested buffer or NULL - * - */ -cprBuffer_t -SIPTaskGetBuffer (uint16_t size) -{ - return cpr_malloc(size); -} - -/** - * - * SIPTaskProcessListEvent (Internal API) - * - * Process a SIP event/message - * - * Parameters: cmd - the type of event - * msg - the event message - * pUsr- a user pointer (TEMPORARY FIELD to be put into msg) - * len - the length of the message - * - * Return Value: None - * - */ -void -SIPTaskProcessListEvent (uint32_t cmd, void *msg, void *pUsr, uint16_t len) -{ - static const char *fname = "SIPTaskProcessListEvent"; - sipSMEvent_t sip_sm_event; - int idx; - int p2psip = 0; - int sdpmode = 0; - cprCallBackTimerMsg_t *timerMsg; - line_t last_available_line; - CCM_ID ccm_id; - - timerMsg = (cprCallBackTimerMsg_t *) msg; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"cmd = 0x%x", DEB_F_PREFIX_ARGS(SIP_EVT, fname), cmd); - - /* - * Loop and wait until we get a TCP_PHN_CFG_TCP_DONE or a RESTART - * message from the phone before we finish - * initializing the SIPTask and SIP state machine - * (note this can happen any time the network stack is re-spun) - */ - if ((sip.taskInited == FALSE) && - ((cmd != TCP_PHN_CFG_TCP_DONE) && - (cmd != SIP_RESTART) && - (cmd != SIP_TMR_SHUTDOWN_PHASE2) && - (cmd != SIP_SHUTDOWN) && - (cmd != TIMER_EXPIRATION) && - (cmd != THREAD_UNLOAD)) ) { - cpr_free(msg); - DEF_DEBUG(DEB_F_PREFIX" !!!sip.taskInited is false. So not executing cmd=0x%x", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), cmd); - return; - } - - memset(&sip_sm_event, 0, sizeof(sipSMEvent_t)); - - /* - * Before CPR used to call the timer callback function out of its' - * timer tick so quite a few of the SIP timers would just post - * a timer expiration event back to its' queue to release the - * CPR thread. Now CPR just sends a timer expiration event - * to the SIP task so we don't want to double post a timer - * expiration event. Therefore check to see if this is a timer - * expiration event and if so possibly update the command before - * switching on it. If the function returns false it means all - * it did was update the command so we need to process the switch - * statement, if it returns true the timer event has been handled. - */ - if (cmd == TIMER_EXPIRATION) { - if (SIPTaskProcessTimerExpiration(msg, &cmd)) { - cpr_free(msg); - return; - } - /* - * No need to release the buffer if we overwrote the command - * as the code that handles the new command below will release - * the buffer. - */ - } - - config_get_value(CFGID_P2PSIP, &p2psip, sizeof(p2psip)); - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - switch (cmd) { - /* - * See comment above - */ - case TCP_PHN_CFG_TCP_DONE: - /* - * Ignore any TCP_PHN_CFG_TCP_DONE message since it is only used to - * determine when the SIP sm should be initialized - */ - cpr_free(msg); - - // If P2P set transport to UDP - if (p2psip == TRUE) - CC_Config_setIntValue(CFGID_TRANSPORT_LAYER_PROT, 2); - - - if (sip_sm_init() < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_init() failed ", fname); - return; - } - - sip_mode_quiet = FALSE; - - /* - * If P2P or SDP only do not register with SIP Server - */ - if (!p2psip && !sdpmode) - sip_platform_init(); - else - ui_set_sip_registration_state(CC_ALL_LINES, TRUE); - - sip.taskInited = TRUE; - DEF_DEBUG(SIP_F_PREFIX"sip.taskInited is set to true ", fname); -#ifdef SAPP_SAPP_GSM - /* - * Initialize SAPP. - */ - if (sapp_init() != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sapp_init() failed.", fname); - break; - } - /* - * Start SAPP. SAPP will register with the CCM. - */ - if (sapp_test() != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sapp_test() failed.", fname); - break; - } -#endif - break; - - case SIP_GSM: - /* - * GSM CC Events - */ - -#ifdef SAPP_SAPP_GSM - if (sapp_process_cc_event(msg) == 0) { - return; - } -#endif - - if (p2psip == TRUE) - sipTransportSetSIPServer(); - - if (sip_sm_process_cc_event(msg) != SIP_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_process_cc_event() " - "failed.\n", fname); - } - break; - - case SIP_TMR_INV_EXPIRE: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"usrData does not point to a valid ccb " - "discarding SIP_TMR_INV_EXPIRE event\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - sip_sm_event.type = E_SIP_INV_EXPIRES_TIMER; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_SUPERVISION_DISCONNECT: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"usrData does not point to a valid ccb " - "discarding SIP_TMR_SUPERVISION_DISCONNECT event.\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - sip_sm_event.type = E_SIP_SUPERVISION_DISCONNECT_TIMER; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_INV_LOCALEXPIRE: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"usrData does not point to valid ccb " - "discarding SIP_TMR_INV_LOCALEXPIRE " - "event.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - sip_sm_event.type = E_SIP_INV_LOCALEXPIRES_TIMER; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - /* - * UsrInfo is set to the IP address that bounced when an - * IMCP Unreachable. -1 means we had a timeout, not a bounce. - */ - case SIP_TMR_MSG_RETRY: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = E_SIP_TIMER; - sip_sm_event.u.UsrInfo = ip_addr_invalid; - cpr_free(msg); - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_ICMP_UNREACHABLE: - { - sipMethod_t retxMessageType; - - idx = msg ? (line_t) (*((uint32_t *)msg)) : 0; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - /* IP address that bounced */ - sip_sm_event.u.UsrInfo = (*(cpr_ip_addr_t *)pUsr); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"event does not point to valid ccb " - "SIP_ICMP_UNREACHABLE event.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - /* - * Retrieve message type and cancel outstanding - * timer and remove ICMP Handler - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - sip_sm_event.ccb->index, - sip_sm_event.ccb->dn_line, - fname, "ICMP_UNREACHABLE"); - - /* Do not need to process the ICMP_UNREACHABLE for fallback ccbs */ - if (sip_sm_event.ccb->index <= REG_BACKUP_CCB) { - retxMessageType = - sip_platform_msg_timer_messageType_get(sip_sm_event.ccb->index); - sip_platform_msg_timer_stop(sip_sm_event.ccb->index); - - if (retxMessageType == sipMethodInvite) { - config_get_value(CFGID_SIP_INVITE_RETX, - &sip_sm_event.ccb->retx_counter, - sizeof(sip_sm_event.ccb->retx_counter)); - if (sip_sm_event.ccb->retx_counter > MAX_INVITE_RETRY_ATTEMPTS) { - sip_sm_event.ccb->retx_counter = MAX_INVITE_RETRY_ATTEMPTS; - } - } else { - config_get_value(CFGID_SIP_RETX, - &sip_sm_event.ccb->retx_counter, - sizeof(sip_sm_event.ccb->retx_counter)); - if (sip_sm_event.ccb->retx_counter > MAX_NON_INVITE_RETRY_ATTEMPTS) { - sip_sm_event.ccb->retx_counter = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - } - - /* - * If REG CCB send into registration state machine else send - * into sip call processing machine - */ - if (retxMessageType == sipMethodRegister) { - /* - * UsrInfo is set to the IP address that bounced when an - * ICMP Unreachable. -1 means we had a timeout, not a bounce. - */ - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_RETRY; - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - } else { - sip_sm_event.type = E_SIP_ICMP_UNREACHABLE; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - } - } - } - break; - - case SIP_TMR_REG_EXPIRE: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_EXPIRE; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_REG_ACK: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_ACK; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_REG_WAIT: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_WAIT; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - /* - * UsrInfo is set to the IP address that bounced when an - * ICMP Unreachable. -1 means we had a timeout, not a bounce. - */ - /* - * currently, we only look for ccm_id for SIP_TMR_REG_RETRY. for rest - * of the REG msg, existing code will work because first field of - * ccsip_registration_msg_t is uint32_t. - */ - case SIP_TMR_REG_RETRY: - idx = msg ? (line_t) ((ccsip_registration_msg_t *)msg)->ccb_index : CC_NO_LINE; - ccm_id = msg ? ((ccsip_registration_msg_t *)msg)->ccm_id : UNUSED_PARAM; - sip_sm_event.ccb = sip_sm_get_ccb_by_ccm_id_and_index(ccm_id, (line_t) idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_RETRY; - sip_sm_event.u.UsrInfo = ip_addr_invalid; - cpr_free(msg); - if (sip_sm_event.ccb == NULL || sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_REG_REQ: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - cpr_free(msg); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t) idx); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"event data does not point to a valid ccb" - "SIP_REG_REQ event.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - (void) sip_sm_ccb_init(sip_sm_event.ccb, (line_t)idx, idx, SIP_REG_STATE_IDLE); - sip_sm_event.ccb->state = (sipSMStateType_t) SIP_REG_STATE_IDLE; - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_REG_REQ; - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_REG_CANCEL: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t) idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_CANCEL; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_REG_CLEANUP: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t) idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_CLEANUP; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_STANDBY_KEEPALIVE: - sip_sm_event.ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_WAIT; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - - // Subscribe/Notify Events - case SIPSPI_EV_CC_SUBSCRIBE_REGISTER: - if (subsmanager_handle_ev_app_subscribe_register(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscribe_register() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_SUBSCRIBE: - if (subsmanager_handle_ev_app_subscribe(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscribe() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_SUBSCRIBE_RESPONSE: - if (subsmanager_handle_ev_app_subscribe_response(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscribe_response() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_NOTIFY: - { - int ret; - - ret = subsmanager_handle_ev_app_notify(msg); - if (ret == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_notify() " - "returned error.\n", fname); - } else if (ret == SIP_DEFER) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_notify() " - "deferred request.\n", fname); - } - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_NOTIFY_RESPONSE: - if (subsmanager_handle_ev_app_notify_response(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_notify_response() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED: - if (subsmanager_handle_ev_app_subscription_terminated(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscription_terminated() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - - case SIPSPI_EV_CC_PUBLISH_REQ: - if (publish_handle_ev_app_publish(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"publish_handle_ev_app_publish() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - - case SIP_REG_UPDATE: - last_available_line = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - cpr_free(msg); - regmgr_handle_register_update(last_available_line); - break; - case REG_MGR_STATE_CHANGE: - - sip_regmgr_rsp(((cc_regmgr_t *)msg)->rsp_id, - ((cc_regmgr_t *)msg)->rsp_type, - ((cc_regmgr_t *)msg)->wait_flag); - cpr_free(msg); - break; - - - // Retry timer expired for Sub/Not - case SIP_TMR_MSG_RETRY_SUBNOT: - idx = (long) (timerMsg->usrData); - cpr_free(msg); - if (subsmanager_handle_retry_timer_expire(idx) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_retry_timer_expire() " - "returned error.\n", fname); - } - break; - // Sub/Not periodic timer - case SIP_TMR_PERIODIC_SUBNOT: - cpr_free(msg); - subsmanager_handle_periodic_timer_expire(); - publish_handle_periodic_timer_expire(); - break; - - case SIP_RESTART: - { - ccsip_restart_req *req = (ccsip_restart_req *) msg; - ccsip_restart_cmd restartCmd; - - restartCmd = req->cmd; - // Handle restart event from platform - cpr_free(msg); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP_RESTART event restartCmd = (%d)", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), restartCmd); - SIPTaskProcessRestart(restartCmd); - break; - } - - case SIP_TMR_SHUTDOWN_PHASE2: - { - // Handle shutdown phase 2 event (after unregistration) - // Note: boolean is 8 bits, but 32 bits have been allocated for it - // so we need to dereference msg with 32 bits - int action; - - if (msg) { - action = (*((uint32_t *)msg)); - } else { - action = SIP_INTERNAL; - } - - cpr_free(msg); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP_TMR_SHUTDOWN_PHASE2 event action= (%d)", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), action); - sip_shutdown_phase2(action); - } - break; - - case SIP_SHUTDOWN: - { - ccsip_shutdown_req_t *req = (ccsip_shutdown_req_t *) msg; - int action; - int reason; - - action = req->action; - reason = req->reason; - cpr_free(msg); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP_SHUTDOWN message", - DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - SIPTaskProcessShutdown(action, reason); - } - break; - - case THREAD_UNLOAD: - break; - - case SIP_TMR_GLARE_AVOIDANCE: - // Handle glare retry timer expiry - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_GLARE_AVOIDANCE_TIMER; - cpr_free(msg); - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - default: - cpr_free(msg); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unknown message", fname); - break; - } - return; -} - -/** - * SIPTaskCheckSource - * - * Ensure that sender is a trusted source - * - * Parameters: from - the source address for the message - * - * Return Value: SIP_OK if message can be processed further - */ -int -SIPTaskCheckSource (cpr_sockaddr_storage from) -{ - static const char fname[] = "SIPTaskCheckSource"; - int regConfigValue; - line_t line_index, line_end; - cpr_ip_addr_t fromIPAddr; - int retval = SIP_ERROR; - char fromIPAddrStr[MAX_IPADDR_STR_LEN]; - ccsipCCB_t *ccb = NULL; - uint32_t data, *data_p; - - // If not registered, return ok - config_get_value(CFGID_PROXY_REGISTER, ®ConfigValue, sizeof(regConfigValue)); - if (regConfigValue == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"CFGID_PROXY_REGISTER is false", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - return SIP_OK; - } - - line_end = 1; - line_end += TEL_CCB_END; - - util_extract_ip(&fromIPAddr,&from); - util_ntohl(&fromIPAddr, &fromIPAddr); - - fromIPAddrStr[0] = '\0'; - ipaddr2dotted(fromIPAddrStr, &fromIPAddr); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Attempting to recognize \"%s\"", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname), fromIPAddrStr); - // Get the proxy configured for all lines and check against those - for (line_index = REG_CCB_START; line_index <= line_end; line_index++) { - // Check the binary from-IP address with the ccb->reg.addr value - if (sip_config_check_line((line_t)(line_index - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(line_index); - if (ccb && util_compare_ip(&(ccb->reg.addr), &fromIPAddr)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Found server IP match", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - retval = SIP_OK; - break; - } - } - } - if (retval == SIP_OK) { - return retval; - } - // Not found - continue to check backup CCBs - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (ccb && util_compare_ip(&(ccb->reg.addr), &fromIPAddr)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Found backup server IP match", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - retval = SIP_OK; - } - if (retval == SIP_OK) { - return retval; - } - // Not found - continue to check with fallback CCBs - data = 0x00; - data_p = &data; - ccb = sip_regmgr_get_fallback_ccb_list(data_p); - while ((ccb != NULL) && (retval != SIP_OK)) { - if (util_compare_ip(&(ccb->reg.addr), &fromIPAddr)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Found fallback server IP match", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - retval = SIP_OK; - } - ccb = sip_regmgr_get_fallback_ccb_list(data_p); - } - return retval; -} - -/** - * - * SIPTaskProcessUDPMessage (Internal API) - * - * Process the received (via UDP) SIP message - * - * Parameters: msg - the message buffer - * len - length of the message buffer - * from - the source address for the message - * - * Return Value: SIP_OK if message could be processed (though this itself - * may fail) or SIP_ERROR - * - */ -int -SIPTaskProcessUDPMessage (cprBuffer_t msg, - uint16_t len, - cpr_sockaddr_storage from) -{ - static const char *fname = "SIPProcessUDPMessage"; - sipMessage_t *pSipMessage = NULL; - static char buf[SIP_UDP_MESSAGE_SIZE + 1]; - char remoteIPAddrStr[MAX_IPADDR_STR_LEN]; - uint32_t bytes_used = 0; - int accept_msg = SIP_OK; - cpr_ip_addr_t ip_addr; - int p2psip = 0; - /* - * Convert IP address to string, for debugs - */ - util_extract_ip(&ip_addr, &from); - - util_ntohl(&ip_addr, &ip_addr); - - if (SipDebugMessage) { - ipaddr2dotted(remoteIPAddrStr, &ip_addr); - } - - util_extract_ip(&ip_addr, &from); - - if (len > SIP_UDP_MESSAGE_SIZE) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Received UDP message from <%s>:<%d>: " - "message too big: msg size = %d, max SIP " - "pkt size = %d\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), remoteIPAddrStr, - util_get_port(&from), bytes_used, SIP_UDP_MESSAGE_SIZE); - cpr_free(msg); - return SIP_ERROR; - } - - /* - * Copy message to a local memory and release the system buffer - */ - memcpy(buf, (char *)msg, len); - buf[len] = '\0'; /* NULL terminate for debug printing */ - cpr_free(msg); - - /* - * Print the received UDP packet info - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"recv UDP message from <%s>:<%d>, length=<%d>, " - "message=\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), remoteIPAddrStr, - util_get_port(&from), len); - CCSIP_DEBUG_MESSAGE_PKT(buf); - - /* - * Determine whether we want to process this packet - * Initially just do this if we are talking to CCM - can be expanded later - */ - - - - config_get_value(CFGID_P2PSIP, &p2psip, sizeof(p2psip)); - - if (p2psip == 0) { - if (sip_regmgr_get_cc_mode(1) == REG_MODE_CCM) { - accept_msg = SIPTaskCheckSource(from); - if (accept_msg != SIP_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIPTaskCheckSource() failed - Sender not " - "recognized\n", fname); - return SIP_ERROR; - } - } - } - - /* - * Convert to SIP representation - */ - pSipMessage = sippmh_message_create(); - if (!pSipMessage) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_message_create() failed", fname); - return SIP_ERROR; - } - - bytes_used = len; - - if (sippmh_process_network_message(pSipMessage, buf, &bytes_used) - == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_process_network_message() " - "failed. discarding the message.\n", fname); - free_sip_message(pSipMessage); - return SIP_ERROR; - } - /* - * Add processing here to append received= to the first Via - * field if the IP address we received this message from is not the same - * as the IP address in the Via field or if it contains a domain name - */ - sippmh_process_via_header(pSipMessage, &ip_addr); - - ccsip_dump_recv_msg_info(pSipMessage, &ip_addr, 0); - - /* Process SIP message */ - SIPTaskProcessSIPMessage(pSipMessage); - return SIP_OK; -} - -/** - * - * SIPTaskProcessTCPMessage (Internal API) - * - * Process the received (via TCP) SIP message - * - * Parameters: msg - the message buffer - * len - length of the message buffer - * from - the source address for the message - * - * Return Value: SIP_OK if message could be processed (though this itself - * may fail) or SIP_ERROR - * - */ -void -SIPTaskProcessTCPMessage (sipMessage_t *pSipMessage, cpr_sockaddr_storage from) -{ - cpr_ip_addr_t ip_addr; - - CPR_IP_ADDR_INIT(ip_addr); - /* - * Convert IP address to string, for debugs - */ - util_extract_ip(&ip_addr, &from); - - /* - * Add processing here to append received= to the first Via - * field if the IP address we received this message from is not the same - * as the IP address in the Via field or if it contains a domain name - */ - sippmh_process_via_header(pSipMessage, &ip_addr); - - /* Process SIP message */ - SIPTaskProcessSIPMessage(pSipMessage); -} - -int -SIPTaskRetransmitPreviousResponse (sipMessage_t *pSipMessage, - const char *fname, - const char *pCallID, - sipCseq_t *sipCseq, - int response_code, - boolean is_request) -{ - sipRelDevMessageRecord_t *pRequestRecord = NULL; - int handle = -1; - const char *reldev_to = NULL; - const char *reldev_from = NULL; - sipLocation_t *reldev_to_loc = NULL; - sipLocation_t *reldev_from_loc = NULL; - - pRequestRecord = (sipRelDevMessageRecord_t *) - cpr_calloc(1, sizeof(sipRelDevMessageRecord_t)); - if (!pRequestRecord) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to allocate " - "mem for pRequestRecord.\n", fname); - return SIP_ERROR; - } - - // Copy to-tag - reldev_to = sippmh_get_cached_header_val(pSipMessage, TO); - if (reldev_to) { - reldev_to_loc = sippmh_parse_from_or_to((char *)reldev_to, TRUE); - if ((reldev_to_loc) && (reldev_to_loc->tag)) { - sstrncpy(pRequestRecord->tag, - sip_sm_purify_tag(reldev_to_loc->tag), - MAX_SIP_TAG_LENGTH); - } - - // Copy to-user - if (reldev_to_loc) { - sstrncpy(pRequestRecord->to_user, - reldev_to_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sippmh_free_location(reldev_to_loc); - } - } - - // Copy from-user and from-host - reldev_from = sippmh_get_cached_header_val(pSipMessage, FROM); - if (reldev_from) { - reldev_from_loc = sippmh_parse_from_or_to((char *)reldev_from, TRUE); - if (reldev_from_loc) { - sstrncpy(pRequestRecord->from_user, - reldev_from_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sstrncpy(pRequestRecord->from_host, - reldev_from_loc->genUrl->u.sipUrl->host, - RELDEV_MAX_HOST_NAME_LEN); - - sippmh_free_location(reldev_from_loc); - } - } - - pRequestRecord->is_request = is_request; - pRequestRecord->response_code = response_code; - - // Copy Call-id - sstrncpy(pRequestRecord->call_id, (pCallID) ? pCallID : "", - MAX_SIP_CALL_ID); - - // Copy CSeq values - pRequestRecord->cseq_method = sipCseq->method; - pRequestRecord->cseq_number = sipCseq->number; - - if (sipRelDevMessageIsDuplicate(pRequestRecord, &handle)) { - cpr_free(pRequestRecord); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous " - "Call ID. Resending stored " - "response...\n", DEB_F_PREFIX_ARGS(SIP_MSG, fname)); - if (sipRelDevCoupledMessageSend(handle) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipRelDevCoupledMessageSend(%d)" - "returned error.\n", fname, handle); - } - return SIP_OK; - } else { - cpr_free(pRequestRecord); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous Call " - "ID. Message not in reTx list.\n", DEB_F_PREFIX_ARGS(SIP_MSG, fname)); - } - return SIP_ERROR; -} - -/** - * - * SIPTaskProcessTimerExpiration - * - * Process a msg indicating a timer has expired - * - * Parameters: msg - the timer callback msg - * cmd - allows us to overwrite the cmd if needed - * - * Return Value: boolean, if true return as timer has been processed. - * - */ -short -SIPTaskProcessTimerExpiration (void *msg, uint32_t *cmd) -{ - static const char fname[] = "SIPTaskProcessTimerExpiration"; - cprCallBackTimerMsg_t *timerMsg; - boolean returnCode = TRUE; - uint32_t handle; - - timerMsg = (cprCallBackTimerMsg_t *) msg; - TMR_DEBUG(DEB_F_PREFIX"Timer %s expired. Id is %d", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), - timerMsg->expiredTimerName, timerMsg->expiredTimerId); - - /* The REGALLFAIL Timer message could come in before the task has - * been initialized. Need to handle this timer, in order to restart - * the system. */ - if ((sip.taskInited == FALSE) && (timerMsg->expiredTimerId != SIP_REGALLFAIL_TIMER)) { - return returnCode; - } - - switch (timerMsg->expiredTimerId) { - case SIP_ACK_TIMER: - *cmd = SIP_TMR_REG_ACK; - returnCode = FALSE; - break; - - case SIP_WAIT_TIMER: - sip_regmgr_wait_timeout_expire(timerMsg->usrData); - break; - - case SIP_RETRY_TIMER: - sip_regmgr_retry_timeout_expire(timerMsg->usrData); - break; - - case SIP_MSG_TIMER: - *cmd = SIP_TMR_MSG_RETRY; - returnCode = FALSE; - break; - - case SIP_EXPIRES_TIMER: - *cmd = SIP_TMR_INV_EXPIRE; - returnCode = FALSE; - break; - - case SIP_REG_TIMEOUT_TIMER: - ccsip_register_timeout_retry(timerMsg->usrData); - break; - - case SIP_REG_EXPIRES_TIMER: - *cmd = SIP_TMR_REG_EXPIRE; - returnCode = FALSE; - break; - - case SIP_LOCAL_EXPIRES_TIMER: - *cmd = SIP_TMR_INV_LOCALEXPIRE; - returnCode = FALSE; - break; - - case SIP_SUPERVISION_TIMER: - *cmd = SIP_TMR_SUPERVISION_DISCONNECT; - returnCode = FALSE; - break; - - case SIP_GLARE_AVOIDANCE_TIMER: - *cmd = SIP_TMR_GLARE_AVOIDANCE; - returnCode = FALSE; - break; - - case SIP_KEEPALIVE_TIMER: - *cmd = SIP_TMR_STANDBY_KEEPALIVE; - returnCode = FALSE; - break; - - case SIP_UNREGISTRATION_TIMER: - sip_platform_unregistration_callback(timerMsg->usrData); - break; - - case SIP_SUBNOT_TIMER: - *cmd = SIP_TMR_MSG_RETRY_SUBNOT; - returnCode = FALSE; - break; - - case SIP_SUBNOT_PERIODIC_TIMER: - sip_platform_subnot_periodic_timer_callback(timerMsg->usrData); - break; - - case SIP_PUBLISH_RETRY_TIMER: - handle = (long)(timerMsg->usrData); - if (publish_handle_retry_timer_expire(handle) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"publish_handle_retry_timer_expire() " - "returned error.\n", fname); - } - break; - - case SIP_UNSOLICITED_TRANSACTION_TIMER: - subsmanager_unsolicited_notify_timeout(timerMsg->usrData); - break; - - case SIP_NOTIFY_TIMER: - sip_regmgr_notify_timer_callback(timerMsg->usrData); - break; - - case SIP_PASSTHROUGH_TIMER: - CCSIP_DEBUG_ERROR("%s: Pass Through Timer fired !", fname); - break; - - case SIP_REGALLFAIL_TIMER: - sip_regmgr_regallfail_timer_callback(timerMsg->usrData); - break; - - default: - CSFLogError("sipstack", "%s: unknown timer %s", fname, - timerMsg->expiredTimerName); - break; - } - return (returnCode); -} - - -/** - * - * SIPTaskProcessSIPMessage - * - * Process a received SIP message - * - * Parameters: pSipMessage - the SIP message - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -static void -SIPTaskProcessSIPMessage (sipMessage_t *pSipMessage) -{ - static const char *fname = "SIPTaskProcessSIPMessage"; - sipSMEvent_t sip_sm_event; - ccsipCCB_t *reg_ccb = NULL,*ccb = NULL; - sipStatusCodeClass_t code_class = codeClassInvalid; - sipMethod_t method = sipMethodInvalid; - const char *pCallID = NULL; - line_t line_index = 1; - boolean is_request = FALSE; - int regConfigValue, response_code = 0; - int requestStatus = SIP_MESSAGING_ERROR; - char errortext[MAX_SIP_URL_LENGTH]; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - uint16_t result_code = 0; - const char *max_fwd_hdr = NULL; - int32_t max_fwd_hdr_val; - int rc; - char tmp_str[STATUS_LINE_MAX_LEN]; - sipSCB_t *scbp = NULL; - sipTCB_t *tcbp = NULL; - int scb_index; - //ccsip_event_data_t * evt_data_ptr = NULL; - - sip_sm_event.u.pSipMessage = pSipMessage; - /* - * is_complete will be FALSE if we received fewer bytes than - * specified in the content_length field. If that happens, we - * want to return a 400 Bad Request message. - */ - if (!sippmh_is_message_complete(pSipMessage)) { - /* Send 400 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SDP_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_is_message_complete()"); - return; - } - - /* - * Determine Type, Method, and Call ID of this SIP message - * If the SIP message is a response, also get the response code. - */ - is_request = sippmh_is_request(pSipMessage); - if (is_request) { - /* - * Check the value of the max-forwards header - if present - */ - max_fwd_hdr = sippmh_get_header_val(pSipMessage, - SIP_HEADER_MAX_FORWARDS, NULL); - if (max_fwd_hdr) { - max_fwd_hdr_val = sippmh_parse_max_forwards(max_fwd_hdr); - if (max_fwd_hdr_val < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid Max Fwd Value detected", - fname); - /* Send 483 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_MANY_HOPS, - SIP_CLI_ERR_MANY_HOPS_PHRASE, - SIP_WARN_MISC, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - } - } - - sipGetRequestMethod(pSipMessage, &method); - - switch (method) { - case sipMethodInvalid: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - /* Send 400 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_METHOD_UNKNOWN, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - - case sipMethodUnknown: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP method not implemented", fname); - // Send 501 error - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_NOT_IMPLEM, - SIP_SERV_ERR_NOT_IMPLEM_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_NOT_IMPLEM); - } - free_sip_message(pSipMessage); - return; - - case sipMethodRegister: - case sipMethodPrack: - case sipMethodComet: - case sipMethodMessage: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP method not allowed", fname); - // Send 405 error - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_NOT_ALLOWED, - SIP_CLI_ERR_NOT_ALLOWED_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_NOT_ALLOWED); - } - free_sip_message(pSipMessage); - return; - - default: - break; - } - } else { - if (sipGetResponseMethod(pSipMessage, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(pSipMessage); - return; - } - if (sipGetResponseCode(pSipMessage, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(pSipMessage); - return; - } - code_class = sippmh_get_code_class((uint16_t) response_code); - } - - /* Get the CSeq */ - cseq = sippmh_get_cached_header_val(pSipMessage, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to extract " - "CSeq from message.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - } - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to parse " - "CSeq from message.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - } - - pCallID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!pCallID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.", fname); - /* - * Since we have no Call-ID, we can't create a response; - * therefore, we drop it. - */ - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - /* - * Unsolicited NOTIFY processing - */ - if ((is_request) && (method == sipMethodNotify)) { - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_NOTIFY); - rc = SIPTaskProcessSIPNotify(pSipMessage); - if (rc != SIP_DEFER) { - if (rc != 0) { - // This Notify is in response to a previous SUBSCRIBE or REFER - (void) subsmanager_handle_ev_sip_subscribe_notify(pSipMessage); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - - /* - * SUBSCRIBE processing. Subscription requests received from the network, - * are processed here and do not interact with the main call processing - * states. All SUBSCRIBE requests and responses are directed to the - * subscription manager. However NOTIFY responses need to be testes to - * see whether the NOTIFY request was generated via CC or SM - */ - if ((is_request) && (method == sipMethodSubscribe)) { - - config_get_value(CFGID_PROXY_REGISTER, ®ConfigValue, sizeof(regConfigValue)); - - reg_ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - - if ((regConfigValue == 0) || (reg_ccb && reg_ccb->reg.registered)) { - - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_SUBSCRIBE); - (void) subsmanager_handle_ev_sip_subscribe(pSipMessage, method, FALSE); - } else { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - if (is_request == FALSE) { - switch (method) { - case sipMethodSubscribe: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Subs Response.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case sipMethodNotify: - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Notify response", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else { - tcbp = find_tcb_by_sip_callid(pCallID); - if (tcbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Unsolicited Notify response", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_unsolicited_notify_response(pSipMessage, tcbp); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - break; - - case sipMethodPublish: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv PUBLISH Response.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) publish_handle_ev_sip_response(pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case sipMethodInfo: - // XXX FIXME see the comments in sipSPISendInfo() - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv INFO Response (silently dropped).", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - default: - break; - - } - } - - - /* - * Determine which line this SIP message is for. - */ - result_code = sip_sm_determine_ccb(pCallID, sipCseq, pSipMessage, - is_request, &ccb); - if (result_code != 0) { - if (is_request) { - if (result_code == SIP_CLI_ERR_LOOP_DETECT) { - /* Send 482 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_LOOP_DETECT, - SIP_CLI_ERR_LOOP_DETECT_PHRASE, - SIP_WARN_MISC, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_LOOP_DETECT); - } - } else { - /* Send 400 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - } else { //is response - // This may be a response for a request generated via sub/not i/f - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Refer Response.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_determine_ccb(): " - "bad response. Dropping message.\n", fname); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - if (ccb) { - sip_sm_event.ccb = ccb; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match: Destination line = " - "<%d/%d>.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname), ccb->index, ccb->dn_line); - - } else { - - boolean is_previous_call_id = FALSE; - line_t previous_call_index = 0; - - /* - * Unsolicited options processing - */ - if ((is_request) && (method == sipMethodOptions)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"recv SIP OPTIONS (outside of dialog) message.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); // - /* - * Send an options request to the gsm for this out of call - * options request. pSipMessage will be freed on return. - */ - sip_cc_options(CC_NO_CALL_ID, CC_NO_LINE, pSipMessage); - cpr_free(sipCseq); - return; - } - - /* - * Unsolicited INFO processing - */ - if ((is_request) && (method == sipMethodInfo)) { - CCSIP_DEBUG_ERROR("%s: Error: recv out-of-dialog SIP INFO message.", fname); // - /* Send 481 Call Leg/Transaction Does Not Exist */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_NOT_ALLOWED); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - - /* + If this is a request and method is INVITE, obtain - * the next available line and forward the request to - * that state machine. This is a new incoming call. - * + Otherwise, this message is spurious -- reject it. - * Do not accept an incoming INVITE for a new call - * if in quiet mode - */ - is_previous_call_id = sip_sm_is_previous_call_id(pCallID, - &previous_call_index); - if ((method == sipMethodInvite) && (is_request)) { - if (sip_mode_quiet) { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_NOT_AVAIL, - SIP_CLI_ERR_NOT_AVAIL_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_NOT_AVAIL); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - else if (cprGetDepth(gsm_msgq) > MAX_DEPTH_OF_GSM_MSGQ_TO_ALLOW_NEW_INCOMING_CALL) { - /* - * CSCsz33584 - * if gsm_msgq depth is larger than MAX_DEPTH_OF_GSM_MSGQ_TO_ALLOW_NEW_INCOMING_CALL, - * it's risky to accept new incoming call. - * just ignore the INVITE message to save CPU time so that the messages in gsm_msgq can be processed faster. - */ - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"gsm msgq depth too large, drop incoming INVITEs!!!", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - ccb = sip_sm_get_ccb_next_available(&line_index); - if (!ccb) { - /* All lines are busy. Return 486 BUSY */ - if (platGetPhraseText(STR_INDEX_NO_FREE_LINES, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1) == CPR_SUCCESS) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match not " - "found: INVITE: %s\n Sending 486 BUSY\n", - DEB_F_PREFIX_ARGS(SIP_ID, fname), tmp_str); - } - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BUSY_HERE, - SIP_CLI_ERR_BUSY_HERE_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BUSY_HERE); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - sip_sm_event.ccb = ccb; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match not " - "found: INVITE: free ccb index = %d.\n", - DEB_F_PREFIX_ARGS(SIP_ID, fname), line_index); - - } else if (is_previous_call_id && (method != sipMethodAck) && - is_request) { - /* - * Detect whether the message is a non-ACK request addressing the - * previous call. If so, reTx the stored response. - */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous Call ID.", - DEB_F_PREFIX_ARGS(SIP_ID, fname)); - if (SipRelDevEnabled) { - if (SIPTaskRetransmitPreviousResponse(pSipMessage, fname, - pCallID, sipCseq, 0, TRUE) == SIP_OK) { - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous Call ID. " - "Reliable Delivery is OFF.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname)); - } - - if (method == sipMethodBye) { - (void) sipSPISendErrorResponse(pSipMessage, 200, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); - } else { - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, NULL); - } - - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else if (is_previous_call_id && (method == sipMethodAck) && - is_request) { - /* - * Detect whether the message is an ACK addressing the previous - * call. If so, stop any outstanding reTx timers. - */ - if (SipRelDevEnabled) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stopping any outstanding " - "reTx timers...\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - sip_sm_check_retx_timers(sip_sm_get_ccb_by_index(previous_call_index), - pSipMessage); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Not forwarding response to SIP SM.", - DEB_F_PREFIX_ARGS(SIP_FWD, fname)); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else if (is_previous_call_id && (!is_request)) { - /* - * Detect whether the message is a response addressing the previous - * call. If the request is 200 OK, stop any outstanding reTx timers. - * This will prevent extraneous reTx of BYE/CANCEL messages at the - * the end of the call. - */ - if (SipRelDevEnabled) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stopping any outstanding " - "reTx timers...\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - sip_sm_check_retx_timers(sip_sm_get_ccb_by_index(previous_call_index), - pSipMessage); - // Check for stored responses - if (SIPTaskRetransmitPreviousResponse(pSipMessage, fname, - pCallID, sipCseq, - response_code, FALSE) == SIP_OK) { - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Not forwarding response to SIP SM.", - DEB_F_PREFIX_ARGS(SIP_FWD, fname)); - - if (method == sipMethodBye) { - SIPTaskProcessSIPPreviousCallByeResponse(pSipMessage, - response_code, - previous_call_index); - } - if (method == sipMethodInvite) { - SIPTaskProcessSIPPreviousCallInviteResponse(pSipMessage, - response_code, - previous_call_index); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - } else { - if (method == sipMethodRefer) { - if (is_request) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received OOD Refer.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - if (subsmanager_handle_ev_sip_subscribe(pSipMessage, sipMethodRefer, FALSE) != SIP_ERROR) { - // Successfully handled - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Successfully handled OOD Refer.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Not able to handle OOD Refer.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } - } else { - // This is a response to an OOD REFER generated via sub/not - // interface - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Refer Response", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - } - } - } else { - if (SipRelDevEnabled) { - // Check for stored responses - if (SIPTaskRetransmitPreviousResponse(pSipMessage, fname, - pCallID, sipCseq, - response_code, - FALSE) == SIP_OK) { - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match not " - "found: Rejecting.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname)); - if (is_request && (method != sipMethodAck)) { - /* Send 481 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_CALLEG); - } - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - - if (is_request) { - /* - * Process request - */ - requestStatus = sipSPICheckRequest(ccb, pSipMessage); - switch (requestStatus) { - case SIP_MESSAGING_OK: - break; - - case SIP_MESSAGING_NEW_CALLID: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_MESSAGING_NEW_CALLID.\n", fname); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_CLI_ERR_FORBIDDEN: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_CLI_ERR_FORBIDDEN.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_FORBIDDEN, - SIP_CLI_ERR_FORBIDDEN_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_FORBIDDEN); - } - - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_MESSAGING_DUPLICATE: - if (method == sipMethodInvite) { - char test_mac[MAC_ADDR_STR_LENGTH]; - uint8_t mac_addr[MAC_ADDRESS_LENGTH]; - - platform_get_wired_mac_address(mac_addr); - - /* - * See if the call id has our mac address in it. - * If so, then we called ourselves. Report back busy. - */ - snprintf(test_mac, MAC_ADDR_STR_LENGTH, "%.4x%.4x-%.4x", - mac_addr[0] * 256 + mac_addr[1], - mac_addr[2] * 256 + mac_addr[3], - mac_addr[4] * 256 + mac_addr[5]); - if ((ccb->state == SIP_STATE_SENT_INVITE) && - (strncmp(test_mac, ccb->sipCallID, 13) == 0)) { - get_sip_error_string(errortext, SIP_CLI_ERR_BUSY_HERE); - (void) sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_BUSY_HERE, - errortext, 0, NULL, NULL); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_SERV_ERR_INTERNAL: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_SERV_ERR_INTERNAL.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_CLI_ERR_BAD_REQ: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_CLI_ERR_BAD_REQ.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA: - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() " - "returned error.\n", fname); - /* Send error response */ - if (method != sipMethodAck) { - if (requestStatus == SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA) { - requestStatus = SIP_CLI_ERR_MEDIA; - } else if (requestStatus == SIP_MESSAGING_ENDPOINT_NOT_FOUND) { - requestStatus = SIP_CLI_ERR_NOT_FOUND; - } else if (requestStatus == SIP_MESSAGING_NOT_ACCEPTABLE) { - requestStatus = SIP_CLI_ERR_NOT_ACCEPT; - } else if (requestStatus != SIP_CLI_ERR_CALLEG) { - requestStatus = 400; - } - get_sip_error_string(errortext, requestStatus); - if (sipSPISendErrorResponse(pSipMessage, (uint16_t)requestStatus, - errortext, 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - if (method == sipMethodInvite) { - ccb->wait_for_ack = TRUE; - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - switch (method) { - case sipMethodInvite: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_INVITE); - sip_sm_event.type = E_SIP_INVITE; - break; - - case sipMethodAck: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_ACK); - sip_sm_check_retx_timers(ccb, pSipMessage); - sip_sm_event.type = E_SIP_ACK; - break; - - case sipMethodBye: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_BYE); - sip_sm_event.type = E_SIP_BYE; - break; - - case sipMethodCancel: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_CANCEL); - sip_sm_event.type = E_SIP_CANCEL; - break; - - case sipMethodSubscribe: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_SUBSCRIBE); - sip_sm_event.type = E_SIP_SUBSCRIBE; - break; - - case sipMethodNotify: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_NOTIFY); - sip_sm_event.type = E_SIP_NOTIFY; - break; - - case sipMethodRefer: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_REFER); - sip_sm_event.type = E_SIP_REFER; - break; - case sipMethodOptions: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_OPTIONS); - sip_sm_event.type = E_SIP_OPTIONS; - break; - case sipMethodUpdate: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_UPDATE); - sip_sm_event.type = E_SIP_UPDATE; - break; - case sipMethodInfo: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_INFO); - (void) ccsip_handle_info_package(ccb, pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - break; - default: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received unknown SIP request message.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - /* The message must be deallocated here */ - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } else { - int responseStatus = SIP_MESSAGING_ERROR; - - /* - * Process response - */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP response.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - responseStatus = sipSPICheckResponse(ccb, pSipMessage); - if (responseStatus != SIP_MESSAGING_OK) { - if (responseStatus == SIP_MESSAGING_DUPLICATE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Duplicate response detected. " - "Discarding...\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } else if (responseStatus == SIP_MESSAGING_ERROR_STALE_RESP) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stale response detected. " - "Discarding...\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } else if (responseStatus == SIP_MESSAGING_ERROR_NO_TRX) { - // This may be a response for a request generated via sub/not i/f - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Refer Response.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckResponse() " - "returned error. Discarding response\n", - fname); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - /* Response is ok. Cancel the outstanding reTx timer if any */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stopping any outstanding reTx " - "timers...\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - sip_sm_check_retx_timers(ccb, pSipMessage); - - /* got a response, re-set re-transmit flag */ - ccb->retx_flag = FALSE; - ccb->last_recvd_response_code = response_code; - /* - * TEL_CCB_START equates to zero and line_t is an unsigned type, - * so just check the end condition - */ - if (ccb->index <= TEL_CCB_END) { - gCallHistory[ccb->index].last_rspcode_rcvd = code_class; - } - - switch (code_class) { - case codeClass1xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 1xx message.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_1xx; - break; - - case codeClass2xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 2xx message.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_2xx; - break; - - case codeClass3xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 3xx message.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_3xx; - break; - - case codeClass4xx: - case codeClass5xx: - case codeClass6xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 4xx/5xx/6xx message.", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_FAILURE_RESPONSE; - switch (response_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - if (sipCseq->method == sipMethodAck) { - sipSPISendFailureResponseAck(ccb, pSipMessage, FALSE, 0); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - break; - - default: - break; - } - break; - - default: - /* unknown response, keep re-transmitting */ - ccb->retx_flag = TRUE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unknown response class.", fname); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - // Change the event type for the UPDATE method since there is only one - // handler for this - if (method == sipMethodUpdate) { - sip_sm_event.type = E_SIP_UPDATE_RESPONSE; - } - } - - /* - * Send event to the SIP SM or the SIP REGISTRATION SM - */ - if (sip_sm_event.ccb->type == SIP_REG_CCB) { - sip_sm_event.type = (sipSMEventType_t) - ccsip_register_sip2sipreg_event(sip_sm_event.type); - - if ((!is_request) && ((code_class == codeClass5xx) || - (code_class == codeClass6xx))) { - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_FAILURE_RESPONSE; - } - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Register response does not have a body %d", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), - (pSipMessage->mesg_body[0].msgBody == NULL) ? -1: pSipMessage->mesg_body[0].msgContentTypeValue); - - if (sip_sm_event.type != (int) E_SIP_REG_NONE) { - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - if (is_request && (method != sipMethodAck)) { - /* Send 500 error */ - if (sipSPISendErrorResponse(pSipMessage, 500, - SIP_SERV_ERR_INTERNAL_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else { - cpr_free(sipCseq); - return; - } - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Ignoring non-register event= %d", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), sip_sm_event.type); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_process_event() returned " - "error.\n", fname); - if (is_request && (method != sipMethodAck)) { - /* Send 500 error */ - if (sipSPISendErrorResponse(pSipMessage, 500, - SIP_SERV_ERR_INTERNAL_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - cpr_free(sipCseq); -} - -/** - * - * SIPTaskProcessConfigChangeNotify - * - * ??? - * - * Parameters: ??? - * - * Return Value: zero(0) - * - */ -int -SIPTaskProcessConfigChangeNotify (int32_t notify_type) -{ - static const char *fname = "SIPTaskProcessConfigChangeNotify"; - int retval = 0; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notify received type=%d", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), notify_type); - - if (notify_type & AA_RELOAD) { - if ((PHNGetState() == STATE_CONNECTED) || - (PHNGetState() == STATE_UNPROVISIONED)) { - /* - * If the phone state isn't in STATE_CONNECTED then this change - * notify is being called because of bootup and not just a SIP - * menu configuration hang. We only want to handle updates - * to the number of lines if the phone is already connected, - * the other case, booting, is handled by the boot code - */ - (void) sipTransportInit(); - - /* need to unregister the phone */ - ccsip_register_cancel(FALSE, TRUE); - ccsip_register_reset_proxy(); - (void) sip_platform_ui_restart(); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"PHNGetState() is not in STATE_CONNECTED, " - "bypassing restart\n", fname); - } - } else if (notify_type & AA_REGISTER) { - ccsip_register_commit(); - } else if (notify_type & AA_BU_REG) { - (void) sipTransportInit(); - ccsip_backup_register_commit(); - } - - return (retval); -} - - - -/** - * - * SIPTaskProcessSIPNotify - * - * The function processes the unsolicited NOTIFY. - * - * Parameters: pSipMessage - pointer to sipMessage_t. - * - * Return Value: SIP_OK, SIP_ERROR, SIP_DEFER. - * - * Note: The parameter pSipMessage is expected by the caller to be - * preserved i.e. it can not be freed by this - * function or the functions called by this function. - */ -static int -SIPTaskProcessSIPNotify (sipMessage_t *pSipMessage) -{ - static const char *fname = "SIPTaskProcessSIPNotify"; - sipReqLine_t *requestURI = NULL; - char *pRequestURIUserStr = NULL; - boolean request_uri_error = TRUE; - line_t i = 0; - line_t dn_line = 0; - const char *event = NULL; - sipLocation_t *uri_loc = NULL; - char line_name[MAX_LINE_NAME_SIZE]; - char line_contact[MAX_LINE_CONTACT_SIZE]; - const char *to = NULL; - sipLocation_t *to_loc = NULL; - sipUrl_t *sipToUrl = NULL; - boolean to_header_error = TRUE; - char *pUser = NULL; - - - /* - * Parse the Event header - */ - event = sippmh_get_header_val(pSipMessage, SIP_HEADER_EVENT, - SIP_C_HEADER_EVENT); - - if (event == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Missing Event header", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL); - return SIP_OK; - } - - /* - * Find the destination DN - */ - requestURI = sippmh_get_request_line(pSipMessage); - if (requestURI) { - if (requestURI->url) { - uri_loc = sippmh_parse_from_or_to(requestURI->url, TRUE); - if (uri_loc) { - if (uri_loc->genUrl->schema == URL_TYPE_SIP) { - if (uri_loc->genUrl->u.sipUrl->user) { - pRequestURIUserStr = uri_loc->genUrl->u.sipUrl->user; - request_uri_error = FALSE; - } else { - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } else { - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } else { - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } else { - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } - - if (request_uri_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NOTIFY has error in Req-URI!", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR, NULL); - return SIP_OK; - } - - if (cpr_strncasecmp(event, "refer", 5) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: refer", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - SIPTaskProcessSIPNotifyRefer(pSipMessage); - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_OK; - } - - for (i = 1; i <= 1; i++) { - if (sip_config_check_line(i)) { - config_get_string((CFGID_LINE_NAME + i - 1), line_name, sizeof(line_name)); - config_get_string((CFGID_LINE_CONTACT + i - 1), line_contact, sizeof(line_contact)); - if ((sippmh_cmpURLStrings(pRequestURIUserStr, line_name, TRUE) == 0) || - (sippmh_cmpURLStrings(pRequestURIUserStr, line_contact, TRUE) == 0)) { - dn_line = i; - break; - } - } - } - - if (dn_line == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NOTIFY has unknown user in Req-URI!", - fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_NOT_FOUND, - SIP_CLI_ERR_NOT_FOUND_PHRASE, - 0, NULL, NULL); - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_OK; - } - - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - - /* - * Sanity check To header by parsing the header. Note it is not used, just sanitized. - */ - to = sippmh_get_cached_header_val(pSipMessage, TO); - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->genUrl->schema == URL_TYPE_SIP) { - sipToUrl = to_loc->genUrl->u.sipUrl; - if (sipToUrl) { - if (sipToUrl->user) { - pUser = sippmh_parse_user(sipToUrl->user); - if (pUser) { - if (pUser[0] != '\0') { - // To header is good. - to_header_error = FALSE; - } - cpr_free(pUser); - } - } - } - sippmh_free_location(to_loc); - } else { - sippmh_free_location(to_loc); - } - } - } - - if (to_header_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NOTIFY has error in To header", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, NULL); - return SIP_OK; - } - - /* - * Request-URI and To header check out. Check Event to determine which - * Notify function to invoke. - */ - if ((cpr_strcasecmp(event, "message-summary") == 0) || - (cpr_strcasecmp(event, "simple-message-summary") == 0)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: MWI", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (SIPTaskProcessSIPNotifyMWI(pSipMessage, dn_line) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad MWI NOTIFY!", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "Bad MWI NOTIFY", NULL); - return SIP_OK; - } - } else if (cpr_strcasecmp(event, "check-sync") == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: check-sync", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - SIPTaskProcessSIPNotifyCheckSync(pSipMessage); - } else if (cpr_strcasecmp(event, "service-control") == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: service-control", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - return SIPTaskProcessSIPNotifyServiceControl(pSipMessage); - } else if (cpr_strcasecmp(event, SIP_EVENT_DIALOG) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_DIALOG); - return (2); - } else if (cpr_strcasecmp(event, SIP_EVENT_CONFIG) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_CONFIG); - return (2); - } else if (cpr_strcasecmp(event, SIP_EVENT_KPML) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_KPML); - return (2); - } else if (cpr_strcasecmp(event, SIP_EVENT_PRESENCE) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_PRESENCE); - return (2); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unrecognized Event header", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL); - } - - return SIP_OK; -} - -/** - * - * SIPTaskProcessSIPNotifyMWI - * - * ??? - * - * Parameters: ??? - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -static int -SIPTaskProcessSIPNotifyMWI (sipMessage_t* pSipMessage, line_t dn_line) -{ - sipMessageSummary_t mesgSummary; - - if (!pSipMessage->mesg_body[0].msgBody || - (pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_MWI_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE)) { - return SIP_ERROR; - } - - memset(&mesgSummary, 0, sizeof(sipMessageSummary_t)); - - if (sippmh_parse_message_summary(pSipMessage, &mesgSummary) < 0) { - return SIP_ERROR; - } - - sip_cc_mwi(CC_NO_CALL_ID, dn_line, mesgSummary.mesg_waiting_on, mesgSummary.type, - mesgSummary.newCount, mesgSummary.oldCount, mesgSummary.hpNewCount, mesgSummary.hpOldCount); - - /* - * Send 200 OK back - */ - (void) sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); - - return SIP_OK; -} -/** - * - * SIPTaskProcessSIPNotifyRefer - * - * The function processes NOTIFY refer. - * - * Parameters: pSipMessage - pointer to the sipMessage_t. - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPNotifyRefer (sipMessage_t *pSipMessage) -{ - static const char *fname = "SIPTaskProcessSIPNotifyRefer"; - ccsipCCB_t *ccb = NULL; - const char *pCallID = NULL; - sipSCB_t *scbp = NULL; - int scb_index; - - pCallID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!pCallID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.", fname); - return; - } - - /* - * Determine which line this SIP message is for. - */ - ccb = sip_sm_get_ccb_by_callid(pCallID); - if (ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match: Destination line = " - "<%d/%d>.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname), ccb->index, ccb->dn_line); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccb is NULL", fname); - // Check if this should be sent to the SM by looking up its callid - // If found, the we return from here - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Notify.", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - (void) subsmanager_handle_ev_sip_subscribe_notify(pSipMessage); - return; - } - } - (void) sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); - - if (NULL != ccb) { - cc_feature_data_t data; - - /* for some reason pingtel decided they were going to send - * Notify messages with call progression in the body. Let's - * just send the 200 back for these and not process them. - * We should only process a Notify with a final response - * in the body (ie. 200, 3xx, 4xx, 5xx, 6xx). - */ - if (pSipMessage->mesg_body[0].msgBody == NULL) { - data.notify.cause = CC_CAUSE_OK; - - if (fsmxfr_get_xcb_by_call_id(ccb->gsm_id) && - (fsmxfr_get_xfr_type(ccb->gsm_id) == FSMXFR_TYPE_BLND_XFR)) { - data.notify.cause = CC_CAUSE_ERROR; - data.notify.method = CC_XFER_METHOD_REFER; - } - } else if ((strstr(pSipMessage->mesg_body[0].msgBody, "100")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "180")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "181")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "182")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "183"))) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Ignoring Notify w/Progression", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - return; - } else if (strstr(pSipMessage->mesg_body[0].msgBody, "200")) { - data.notify.cause = CC_CAUSE_OK; - data.notify.method = CC_XFER_METHOD_REFER; - } else { - data.notify.cause = CC_CAUSE_ERROR; - data.notify.method = CC_XFER_METHOD_REFER; - } - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *)&data); - } -} - - -/** - * - * SIPTaskProcessSIPNotifyCheckSync - * - * ??? - * - * Parameters: pSipMessage - - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPNotifyCheckSync (sipMessage_t *pSipMessage) -{ - /* - * Send 200 OK back - */ - (void) sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); -} - -/** - * - * SIPTaskProcessSIPNotifyServiceControl - * - * Handles an incoming unsolicited NOTIFY service control message - * - * Parameters: Incoming pSipMessage - * - * Return Value: SIP_OK if request processed. - * SIP_DEFER if request is deferred for processing - * by ccsip_core.c. - * - */ -static int -SIPTaskProcessSIPNotifyServiceControl (sipMessage_t *pSipMessage) -{ - const char *fname = "SIPTaskProcessSIPNotifyServiceControl"; - sipServiceControl_t *scp; - int rc = SIP_OK; - - scp = ccsip_get_notify_service_control(pSipMessage); - - if (scp != NULL) { - // The platform code should not alter scp or its fields - if (scp->action == SERVICE_CONTROL_ACTION_CALL_PRESERVATION) { - rc = SIP_DEFER; - } else { - if (sipSPISendErrorResponse(pSipMessage, 200, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - } - - // Hand over the event to platform - sip_platform_handle_service_control_notify(scp); - } - sippmh_free_service_control_info(scp); - } - - return rc; -} - -/** - * - * SIPTaskProcessSIPPreviousCallByeResponse - * - * ??? - * - * Parameters: pResponse - - * response_code - - * previous_call_index - - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPPreviousCallByeResponse (sipMessage_t *pResponse, - int response_code, - line_t previous_call_index) -{ - static const char *fname = "SIPTaskProcessSIPPreviousCallByeResponse"; - uint32_t responseCSeqNumber = 0; - sipMethod_t responseCSeqMethod = sipMethodInvalid; - boolean bad_authentication = FALSE; - credentials_t credentials; - sipAuthenticate_t authen; - const char *authenticate = NULL; - int nc_count = 0; - - memset(&authen, 0, sizeof(authen)); // Initialize - - switch (response_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - /* Check CSeq */ - if (sipGetMessageCSeq(pResponse, &responseCSeqNumber, - &responseCSeqMethod) < 0) { - return; - } - if (responseCSeqNumber != - gCallHistory[previous_call_index].last_bye_cseq_number) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"CSeq# mismatch: BYE CSeq=%d, " - "%d CSeq:%d\n", fname, - gCallHistory[previous_call_index].last_bye_cseq_number, - response_code, responseCSeqNumber); - return; - } - - /* Obtain credentials */ - cred_get_line_credentials(gCallHistory[previous_call_index].dn_line, - &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - /* Compute Authentication information */ - authenticate = sippmh_get_header_val(pResponse, - AUTH_HDR(response_code), NULL); - if (authenticate != NULL) { - sip_authen_t *sip_authen = NULL; - - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - char *author_str = NULL; - - if (sipSPIGenerateAuthorizationResponse(sip_authen, - gCallHistory[previous_call_index]. - last_route_request_uri, - SIP_METHOD_BYE, - credentials.id, - credentials.pw, - &author_str, - &nc_count, NULL)) { - if (author_str != NULL) - { - authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - if (authen.authorization != NULL) { - sstrncpy(authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - authen.status_code = response_code; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc() failed " - "for authen.authorization\n", fname); - bad_authentication = TRUE; - } - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"author_str returned by sipSPIGenerateAuthorizationResponse" - "is NULL", fname); - bad_authentication = TRUE; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPIGenerateAuthorizationResponse()" - " returned null.\n", fname); - bad_authentication = TRUE; - } - sippmh_free_authen(sip_authen); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_parse_authenticate() " - "returned null.\n", fname); - bad_authentication = TRUE; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_get_header_val(AUTH_HDR) " - "returned null.\n", fname); - bad_authentication = TRUE; - } - - if (bad_authentication) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad authentication header " - "in %d\n", fname, response_code); - if (authen.authorization) - cpr_free(authen.authorization); - return; - } - - /* Resend BYE with authorization */ - (void) sipSPISendByeAuth(pResponse, - authen, - &(gCallHistory[previous_call_index].last_bye_dest_ipaddr), - gCallHistory[previous_call_index].last_bye_dest_port, - ++gCallHistory[previous_call_index].last_bye_cseq_number, - gCallHistory[previous_call_index].last_bye_also_string, - gCallHistory[previous_call_index].last_route, - gCallHistory[previous_call_index].last_route_request_uri, - previous_call_index); - if (authen.authorization) { - cpr_free(authen.authorization); - } - break; - - default: - break; - } -} - -/** - * - * SIPTaskProcessSIPPreviousCallInviteResponse - * - * ??? - * - * Parameters: pResponse - - * response_code - - * previous_call_index - - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPPreviousCallInviteResponse (sipMessage_t *pResponse, - int response_code, - line_t previous_call_index) -{ - static const char *fname = "SIPTaskProcessSIPPreviousCallInviteResponse"; - uint32_t responseCSeqNumber = 0; - sipMethod_t responseCSeqMethod = sipMethodInvalid; - - if ((response_code >= SIP_CLI_ERR_BAD_REQ) && (response_code < 700)) { - /* Check CSeq */ - if (sipGetMessageCSeq(pResponse, &responseCSeqNumber, - &responseCSeqMethod) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "Invalid CSeq"); - return; - } - if (responseCSeqNumber != - gCallHistory[previous_call_index].last_bye_cseq_number) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Last Bye CSeq=%d, Failure Code = %d, " - "CSeq:%d\n", fname, - gCallHistory[previous_call_index].last_bye_cseq_number, - response_code, responseCSeqNumber); - return; - } - - /* Send ACK */ - sipSPISendFailureResponseAck(NULL, pResponse, TRUE, previous_call_index); - - } -} - -void -SIPTaskPostRestart (boolean restart) -{ - ccsip_restart_req *msg; - static const char fname[] = "SIPTaskPostRestart"; - - msg = (ccsip_restart_req *) SIPTaskGetBuffer(sizeof(ccsip_restart_req)); - if (msg == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to allocate IPC msg ccip_restart_req", fname); - return; - } - if (restart) { - /* This is a restart request from the platform */ - msg->cmd = SIP_RESTART_REQ_RESTART; - } else { - /* This is a re-init request from the platform */ - msg->cmd = SIP_RESTART_REQ_REINIT; - } - /* send a restart message to the SIP Task */ - if (SIPTaskSendMsg(SIP_RESTART, (cprBuffer_t)msg, - sizeof(ccsip_restart_req), NULL) == CPR_FAILURE) { - cpr_free(msg); - } - return; -} - -static void -SIPTaskProcessRestart (ccsip_restart_cmd cmd) -{ - static const char fname[] = "SIPTaskProcessRestart"; - - if (cmd == SIP_RESTART_REQ_RESTART) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Starting Restart Process", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - - /* Restart SIP task */ - sip_restart(); - } else if (cmd == SIP_RESTART_REQ_REINIT) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Starting Re-init Process", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - - // Re-initialize the various components - SIPTaskReinitialize(FALSE); - - /* Clear the quite mode */ - sip_mode_quiet = FALSE; - } -} - -/* - * If checkConfig is 0/FALSE, process as a config change without checking - */ -void -SIPTaskReinitialize (boolean checkConfig) -{ - static const char fname[] = "SIPTaskReinitialize"; - - // Initialize all GSM modules - cc_fail_fallback_gsm(CC_SRC_SIP, CC_RSP_COMPLETE, CC_REG_FAILOVER_RSP); - - // If the config has changed, or if the check is being bypassed, re-init reg-mgr - if ( !checkConfig || sip_regmgr_check_config_change() ) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Config change detected: Restarting", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - sip_regmgr_process_config_change(); - return; - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No config change detected", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - } -} - -void -SIPTaskPostShutdown (int action, int reason, const char *reasonInfo) -{ - ccsip_shutdown_req_t *msg; - static const char fname[] = "SIPTaskPostShutdown"; - - msg = (ccsip_shutdown_req_t *) SIPTaskGetBuffer(sizeof(ccsip_shutdown_req_t)); - if (msg == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to allocate IPC msg SIP_SHUTDOWN_REQ_SHUT", fname); - return; - } - msg->cmd = SIP_SHUTDOWN_REQ_SHUT; - msg->action = action; - msg->reason = reason; - if (reasonInfo) { - sstrncpy(sipUnregisterReason, reasonInfo, MAX_SIP_REASON_LENGTH); - } - - /* send a restart message to the SIP Task */ - if (SIPTaskSendMsg(SIP_SHUTDOWN, (cprBuffer_t)msg, - sizeof(ccsip_shutdown_req_t), NULL) == CPR_FAILURE) { - cpr_free(msg); - } - return; -} - -static void -SIPTaskProcessShutdown (int action, int reason) -{ - static const char fname[] = "SIPTaskProcessShutdown"; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Starting Shutdown Process", DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - sip_mode_quiet = TRUE; - /* Shutdown SIP components */ - sip_shutdown_phase1(action, reason); -} - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_callinfo.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_callinfo.h deleted file mode 100644 index 3619a898835..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_callinfo.h +++ /dev/null @@ -1,86 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CALLINFO_H_ -#define _CCSIP_CALLINFO_H_ - -#include "cpr_types.h" -#include "ccapi.h" -#include "ccsip_core.h" - -#define MAX_SIP_HEADER_LENGTH 1024 -#define MAX_URI_LENGTH 256 -#define URN_REMOTECC "urn:x-cisco-remotecc:" -#define LAQUOT '<' -#define RAQUOT '>' -#define SPACE ' ' -#define TAB '\t' -#define SEMI_COLON ';' - -// Feature string that appear in the feature-urn. For example in -// , "hold" is the feature string. -#define SIP_CI_HOLD_STR "hold" -#define SIP_CI_RESUME_STR "resume" -#define SIP_CI_BARGE_STR "barge" -#define SIP_CI_CBARGE_STR "cbarge" -#define SIP_CI_CALL_INFO_STR "callinfo" -#define SIP_CI_SILENT_STR "silent" -#define SIP_CI_COACHING_STR "coaching" - - -// Definitions relating to the hold-resume feature urn. -#define SIP_CI_HOLD_REASON "reason=" -#define SIP_CI_HOLD_REASON_XFER "transfer" -#define SIP_CI_HOLD_REASON_CONF "conference" - -// Definitions relating to the callinfo feature urn. -#define SIP_CI_SECURITY "security=" -#define SIP_CI_SECURITY_UNKNOWN "unknown" -#define SIP_CI_SECURITY_NOT_AUTH "NotAuthenticated" -#define SIP_CI_SECURITY_AUTH "Authenticated" -#define SIP_CI_SECURITY_ENCRYPTED "Encrypted" -#define SIP_CI_ORIENTATION "orientation=" -#define SIP_CI_ORIENTATION_TO "to" -#define SIP_CI_ORIENTATION_FROM "from" -#define SIP_CI_POLICY "policy=" -#define SIP_CI_POLICY_UNKNOWN "unknown" -#define SIP_CI_POLICY_CHAPERONE "chaperone" -#define SIP_CI_CALL_INSTANCE "call-instance=" -#define SIP_CI_CTI_CALLID "cti-callid=" -#define SIP_CI_UI_STATE "ui-state=" -#define SIP_CI_UI_STATE_RINGOUT "ringout" -#define SIP_CI_UI_STATE_CONNECTED "connected" -#define SIP_CI_PRIORITY "priority=" -#define SIP_CI_PRIORITY_URGENT "urgent" -#define SIP_CI_PRIORITY_EMERGENCY "emergency" -#define SIP_CI_UI_STATE_BUSY "busy" -#define SIP_CI_GCID "gci=" -#define SIP_CI_DUSTINGCALL "isDustingCall" - -// Definitions relating to a generic feature parm. -#define SIP_CI_GENERIC "purpose=" -#define SIP_CI_GENERIC_ICON "icon" -#define SIP_CI_GENERIC_INFO "info" -#define SIP_CI_GENERIC_CARD "card" - -#define SKIP_LWS(p) while (*p == SPACE || *p == TAB) { \ - p++; \ - } -#define SKIP_WHITE_SPACE(p) while (*p == SPACE || *p == TAB || \ - *p == '\n') { \ - p++; \ - } - -/* - * Encoding function - */ -char* ccsip_encode_call_info_hdr(cc_call_info_t *call_info_p, - const char *misc_parms_p); - -void ccsip_free_call_info_header(cc_call_info_t *call_info_p); - -void ccsip_store_call_info(cc_call_info_t *call_info_p, ccsipCCB_t* ccb); -void ccsip_process_call_info_header(sipMessage_t *request_p, ccsipCCB_t* ccb); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_cc.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_cc.h deleted file mode 100755 index be7ea6860b5..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_cc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CC_H_ -#define _CCSIP_CC_H_ - -#include "ccapi.h" - - -void sip_cc_setup(int gsm_call_id, int line, string_t calling_name, - string_t calling_number, string_t alt_calling_number, boolean display_calling_number, - string_t called_name, string_t called_number, - boolean display_called_number, string_t orig_called_name, - string_t orig_called_number, string_t last_redirect_name, - string_t last_redirect_number, cc_call_type_e call_type, - cc_alerting_type alert_info, vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_call_info_t *call_info_p, - boolean replaces, string_t recv_info_list, sipMessage_t *sip_msg); -void sip_cc_setup_ack(int call_id, int line, cc_msgbody_info_t *msg_body); -void sip_cc_proceeding(int gsm_call_id, int line); -void sip_cc_alerting(int gsm_call_id, int line, sipMessage_t *sip_msg, - int inband); -void sip_cc_connected(int gsm_call_id, int line, string_t recv_info_list, sipMessage_t *sip_msg); -void sip_cc_connected_ack(int gsm_call_id, int line, sipMessage_t *sip_msg); -void sip_cc_release(int gsm_call_id, int line, cc_causes_t cause, - const char *dialstring); -void sip_cc_release_complete(int gsm_call_id, int line, cc_causes_t cause); -void sip_cc_feature(int call_id, int line, int feature, void *data); -void sip_cc_feature_ack(int call_id, int line, int feature, void *data, - cc_causes_t cause); -void sip_cc_mwi(int call_id, int line, boolean on, int type, - int newCount, int oldCount, int hpNewCount, int hpOldCount); -void sip_cc_mv_msg_body_to_cc_msg(cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg); -boolean sip_cc_create_cc_msg_body_from_sip_msg(cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg); -void sip_cc_options(callid_t call_id, line_t line, sipMessage_t *pSipMessage); -void sip_cc_audit(callid_t call_id, line_t line, boolean apply_ringout); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_common_cb.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_common_cb.h deleted file mode 100644 index 3547596800e..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_common_cb.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_COMMON_CB_H_ -#define _CCSIP_COMMON_CB_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "ccapi.h" -#include "dns_utils.h" -#include "ccsip_platform.h" -#include "ccsip_pmh.h" -#include "ccsip_core.h" -#include "xml_parser_defines.h" - - -#define HOOK_STATUS_STR "hook status" -#define BLF_SPEEDDIAL_STR "blf speed dial" - -typedef enum { - SUBNOT_CB, - PUBLISH_CB, - UNSOLICIT_NOTIFY_CB -} ccsip_cb_type_e; - - -typedef struct { - ccsip_cb_type_e cb_type; - line_t dn_line; - cpr_ip_addr_t dest_sip_addr; - uint32_t dest_sip_port; /* Destination port */ - cpr_ip_addr_t src_addr; /* Source address */ - uint32_t local_port; /* Source port */ - srv_handle_t SRVhandle; /* handle for dns_gethostbysrv() */ - unsigned int retx_counter; - boolean retx_flag; - char sipCallID[MAX_SIP_CALL_ID]; - sipAuthenticate_t authen; - long orig_expiration; /* Original time to expire */ - long expires; /* Running expiry timer */ - ccsip_event_data_t *event_data_p; - cc_subscriptions_t event_type; /* event type, such as presence */ - cc_subscriptions_t accept_type; /* accept type, such as presence */ -} ccsip_common_cb_t; - - -extern void ccsip_common_util_set_dest_ipaddr_port(ccsip_common_cb_t *cb_p); -extern void ccsip_common_util_set_src_ipaddr(ccsip_common_cb_t *cb_p); -extern void ccsip_common_util_set_retry_settings(ccsip_common_cb_t *cb_p, int *timeout_p); -extern boolean ccsip_common_util_generate_auth(sipMessage_t *pSipMessage, ccsip_common_cb_t *cb_p, - const char *rsp_method, int response_code, char *uri); -extern void ccsip_util_extract_user(char *url, char *user); -extern void ccsip_util_get_from_entity(sipMessage_t *pSipMessage, char *entity); - -#endif //_CCSIP_COMMON_CB_H_ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_core.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_core.h deleted file mode 100644 index 39525b2bb1a..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_core.h +++ /dev/null @@ -1,866 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CORE_H_ -#define _CCSIP_CORE_H_ - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "task.h" -//#include "network.h" -#include "ccapi.h" -#include "ccsip_sdp.h" -#include "ccsip_pmh.h" -#include "config.h" -#include "dns_utils.h" -#include "ccsip_platform.h" -#include "ccsip_platform_timers.h" -#include "cc_constants.h" -#include "sessionConstants.h" - -#define SIP_DEFER (-2) -#define SIP_ERROR (-1) -#define SIP_OK (0) - -#define SIP_L_C_F_PREFIX "SIP : %d/%d : %s : " // requires 3 args: line_id, call_id, fname -#define SIP_F_PREFIX "SIP : %s : " // requires 1 arg: fname - -#define SUPERVISION_DISCONNECT_TIMEOUT 32000 -#define SIP_WARNING_LENGTH 100 - -#define RPID_DISABLED 0 -#define RPID_ENABLED 1 - -#define MAX_INVITE_RETRY_ATTEMPTS 6 -#define MAX_NON_INVITE_RETRY_ATTEMPTS 10 - -typedef enum { - SIP_STATE_NONE = -1, - SIP_STATE_BASE = 0, - - SIP_STATE_IDLE = SIP_STATE_BASE, - - SIP_STATE_SENT_INVITE, - SIP_STATE_SENT_INVITE_CONNECTED, - - SIP_STATE_RECV_INVITE, - SIP_STATE_RECV_INVITE_PROCEEDING, - SIP_STATE_RECV_INVITE_ALERTING, - SIP_STATE_RECV_INVITE_CONNECTED, - - SIP_STATE_ACTIVE, - SIP_STATE_SENT_MIDCALL_INVITE, - SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING, - SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING, - - SIP_STATE_RELEASE, - SIP_STATE_BLIND_XFER_PENDING, - SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING, - - SIP_STATE_SENT_OOD_REFER, - SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING, - - SIP_STATE_END = SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING -} sipSMStateType_t; - -typedef enum -{ - SIP_REG_STATE_INV = -1, - SIP_REG_STATE_NONE = 0, - SIP_REG_STATE_BASE = 1, - - SIP_REG_STATE_IDLE = SIP_REG_STATE_BASE, - SIP_REG_STATE_REGISTERING, - SIP_REG_STATE_REGISTERED, - SIP_REG_STATE_UNREGISTERING, - SIP_REG_STATE_IN_FALLBACK, - SIP_REG_STATE_STABILITY_CHECK, - SIP_REG_STATE_TOKEN_WAIT, - SIP_REG_STATE_END = SIP_REG_STATE_TOKEN_WAIT -} sipRegSMStateType_t; - -typedef enum { - SIPSPI_EV_INVALID = -1, - SIPSPI_EV_BASE = 0, - - E_SIP_INVITE = SIPSPI_EV_BASE, - E_SIP_ACK, - E_SIP_BYE, - E_SIP_CANCEL, - E_SIP_1xx, - E_SIP_2xx, - E_SIP_3xx, - E_SIP_NOTIFY, - E_SIP_FAILURE_RESPONSE, - E_SIP_REFER, - E_SIP_OPTIONS, - E_SIP_SUBSCRIBE, - E_SIP_UPDATE, - - E_CC_SETUP, - E_CC_SETUP_ACK, - E_CC_PROCEEDING, - E_CC_ALERTING, - E_CC_CONNECTED, - E_CC_CONNECTED_ACK, - E_CC_RELEASE, - E_CC_RELEASE_COMPLETE, - E_CC_FEATURE, - E_CC_FEATURE_ACK, - E_CC_CAPABILITIES, - E_CC_CAPABILITIES_ACK, - E_CC_SUBSCRIBE, - E_CC_NOTIFY, - E_CC_INFO, - - E_SIP_INV_EXPIRES_TIMER, - E_SIP_INV_LOCALEXPIRES_TIMER, - E_SIP_SUPERVISION_DISCONNECT_TIMER, - E_SIP_TIMER, - E_SIP_GLARE_AVOIDANCE_TIMER, - - E_SIP_UPDATE_RESPONSE, - E_SIP_ICMP_UNREACHABLE, - SIPSPI_EV_END = E_SIP_ICMP_UNREACHABLE -} sipSMEventType_t; - -typedef enum { - H_INVALID_EVENT = -1, - SIPSPI_EV_INDEX_BASE = 0, -/*0*/H_IDLE_EV_SIP_INVITE = SIPSPI_EV_INDEX_BASE, /* ccsip_handle_idle_ev_sip_invite, */ -/*1*/H_IDLE_EV_CC_SETUP, /* ccsip_handle_idle_ev_cc_setup, */ -/*2*/H_SENTINVITE_EV_SIP_1XX, /* ccsip_handle_sentinvite_ev_sip_1xx, */ -/*3*/H_SENTINVITE_EV_SIP_2XX, /* ccsip_handle_sentinvite_ev_sip_2xx, */ -/*4*/H_SENTINVITE_EV_SIP_FXX, /* ccsip_handle_sentinvite_ev_sip_fxx, */ -/*5*/H_DISCONNECT_LOCAL_EARLY, /* ccsip_handle_disconnect_local_early, */ -/*6*/H_DISCONNECT_REMOTE, /* ccsip_handle_disconnect_remote, */ -/*7*/H_SENTINVITECONNECTED_EV_CC_CONNECTED_ACK, /* ccsip_handle_sentinviteconnected_ev_cc_connected_ack, */ -/*8*/H_DISCONNECT_LOCAL, /* ccsip_handle_disconnect_local, */ -/*9*/H_RECVINVITE_EV_CC_SETUP_ACK, /* ccsip_handle_recvinvite_ev_cc_setup_ack, */ -/*10*/H_RECVINVITE_EV_CC_PROCEEDING, /* ccsip_handle_recvinvite_ev_cc_proceeding, */ -/*11*/H_RECVINVITE_EV_CC_ALERTING, /* ccsip_handle_recvinvite_ev_cc_alerting, */ -/*12*/H_RECVINVITE_EV_CC_CONNECTED, /* ccsip_handle_recvinvite_ev_cc_connected, */ -/*13*/H_DISCONNECT_LOCAL_UNANSWERED, /* ccsip_handle_disconnect_local_unanswered, */ -/*14*/H_RECVINVITE_EV_SIP_ACK, /* ccsip_handle_recvinvite_ev_sip_ack, */ -/*15*/H_ACTIVE_EV_SIP_INVITE, /* ccsip_handle_active_ev_sip_invite, */ -/*16*/H_ACTIVE_EV_CC_FEATURE, /* ccsip_handle_active_ev_cc_feature, */ -/*17*/H_ACCEPT_2XX, /* ccsip_handle_accept_2xx, */ -/*18*/H_REFER_SIP_MESSAGE, /* ccsip_handle_refer_sip_message, */ -/*19*/H_ACTIVE_EV_CC_FEATURE_ACK, /* ccsip_handle_active_ev_cc_feature_ack, */ -/*20*/H_SENTINVITE_MIDCALL_EV_SIP_2XX, /* ccsip_handle_sentinvite_midcall_ev_sip_2xx */ -/*21*/H_SENTINVITE_MIDCALL_EV_CC_FEATURE, /* ccsip_handle_sentinvite_midcall_ev_cc_feature */ -/*22*/H_RECVMIDCALLINVITE_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK, /* ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack */ -/*23*/H_RECVMIDCALLINVITE_SIPACKPENDING_EV_SIP_ACK, /* ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack, */ -/*24*/H_DEFAULT_SIP_MESSAGE, /* ccsip_handle_default_sip_message, */ -/*25*/H_DEFAULT_SIP_RESPONSE, /* ccsip_handle_default_sip_response, */ -/*26*/H_DEFAULT, /* ccsip_handle_default, */ -/*27*/H_SIP_INV_EXPIRES_TIMER, /* ccsip_handle_disconnect_local_early, */ -/*28*/H_SIP_OPTIONS, /* ccsip_handle_answer_options_request, */ -/*29*/H_SENTINVITE_EV_SIP_3XX, /* ccsip_handle_sentinvite_ev_sip_3xx, */ -/*30*/H_RECV_ERR_EV_SIP_ACK, /* ccsip_handle_recv_error_response_ev_sip_ack,*/ -/*31*/H_SENTBYE_EV_SIP_2XX, /* ccsip_handle_sentbye_ev_sip_2xx,*/ -/*32*/H_SENTBYE_EV_SIP_1XX, /* ccsip_handle_sentbye_ev_sip_1xx,*/ -/*33*/H_SENTBYE_EV_SIP_FXX, /* ccsip_handle_sentbye_ev_sip_fxx,*/ -/*34*/H_SENTBYE_EV_SIP_INVITE, /* ccsip_handle_sentbye_recvd_invite,*/ -/*35*/H_SENTBYE_SUPERVISION_DISCONNECT_TIMER, /* ccsip_handle_sendbye_ev_supervision_disconnect*/ -/*36*/H_RELEASE_COMPLETE, /* ccsip_handle_release_complete, */ -/*37*/H_ACTIVE_2xx, /* ccsip_handle_Active_2xx*/ -/*38*/H_BLIND_NOTIFY, /* ccsip_handle_send_blind_notify, */ -/*39*/H_SENT_BLINDNTFY, /* ccsip_handle_sentblindntfy_ev_sip_2xx, */ -/*40*/H_BYE_RELEASE, /* ccsip_handle_release_ev_sip_bye, */ -/*41*/H_HANDLE_LOCALEXPIRES_TIMER, /* ccsip_handle_localexpires_timer */ -/*42*/H_DEFAULT_SIP_TIMER, /* ccsip_handle_default_sip_timer */ -/*43*/H_EARLY_EV_SIP_UPDATE, /* ccsip_handle_early_ev_sip_update */ -/*44*/H_EARLY_EV_SIP_UPDATE_RESPONSE, /* ccsip_handle_early_ev_sip_update_response */ -/*45*/H_EARLY_EV_CC_FEATURE, /* ccsip_handle_early_ev_cc_feature */ -/*46*/H_EARLY_EV_CC_FEATURE_ACK, /* ccsip_handle_early_ev_cc_feature_ack */ -/*47*/H_CONFIRM_EV_SIP_UPDATE, /* ccsip_handle_active_ev_sip_update */ -/*48*/H_RECVUPDATEMEDIA_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK, /* ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack */ -/*49*/H_SIP_GLARE_AVOIDANCE_TIMER, /* ccsip_handle_timer_glare_avoidance */ -/*50*/H_RECVINVITE_SENTOK_NO_SIP_ACK, /* ccsip_handle_recvinvite_ev_expires_timer */ -/*51*/H_EV_SIP_UNSOLICITED_NOTIFY, /* ccsip_handle_unsolicited_notify */ -/*52*/H_RECVINVITE_EV_SIP_2XX, /* ccsip_handle_recvinvite_ev_sip_2xx */ -/*53*/H_ICMP_UNREACHABLE, /* ccsip_handle_icmp_unreachable */ -/*54*/H_DISCONNECT_MEDIA_CHANGE, /* ccsip_handle_disconnect_media_change*/ -/*55*/H_DEFAULT_EV_CC_FEATURE, /* ccsip_handle_default_ev_cc_feature */ -/*56*/H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE, /* ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ -/*57*/H_OOD_REFER_RESPONSE_EV_SIP_1xx, /* ccsip_handle_sent_ood_refer_ev_sip_1xx */ -/*58*/H_OOD_REFER_RESPONSE_EV_SIP_2xx, /* ccsip_handle_sent_ood_refer_ev_sip_2xx */ -/*59*/H_OOD_REFER_RESPONSE_EV_SIP_fxx, /* ccsip_handle_sent_ood_refer_ev_sip_fxx */ -/*60*/H_RELEASE_EV_CC_FEATURE, /* ccsip_handle_release_ev_cc_feature */ -/*61*/H_EV_CC_INFO, /* ccsip_handle_ev_cc_info */ -/*62*/H_RELEASE_EV_RELEASE, /* ccsip_handle_release_ev_release */ - SIPSPI_EV_INDEX_END = H_RELEASE_EV_RELEASE -} sipSMAction_t; - - - -/* - * This structure defines TCP/UDP Connection - * Parameters. - * This is used during processing Contact - * and Route headers received in the SIP - * messages - */ -typedef enum { - SIP_SM_DIS_METHOD_BYE = 0, - SIP_SM_DIS_METHOD_CANCEL -} sipSMDisMethod_t; - -typedef struct { - char last_call_id[MAX_SIP_CALL_ID]; - uint32_t last_bye_cseq_number; - cpr_ip_addr_t last_bye_dest_ipaddr; - uint16_t last_bye_dest_port; - cpr_ip_addr_t proxy_dest_ipaddr; - line_t dn_line; - char last_bye_also_string[MAX_SIP_URL_LENGTH]; - char last_route[MAX_SIP_URL_LENGTH]; - char last_route_request_uri[MAX_SIP_URL_LENGTH]; - char via_branch[VIA_BRANCH_LENGTH]; - sipStatusCodeClass_t last_rspcode_rcvd; -} sipCallHistory_t; - -typedef enum { - SIP_SM_NO_XFR = 0, - SIP_SM_BLND_XFR, - SIP_SM_ATTN_XFR -} sipSMXfrType_t; - -typedef struct sipRedirectInfo_ { - sipContact_t *sipContact; /* Contact header received in the 3xx */ - uint16_t next_choice; /* Index of next Contact location to use */ -} sipRedirectInfo_t; - -typedef struct { - int retries_401_407; - int cred_type; - char *authorization; - int status_code; - sip_authen_t *sip_authen; - char cnonce[9]; - int nc_count; - boolean new_flag; -} sipAuthenticate_t; - -/* SIP REGISTER method info */ -typedef struct { - int registered; - int tmr_expire; - int act_time; - char proxy[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t addr; - uint16_t port; - uint8_t rereg_pending; -} sipRegister_t; - -/* AVT payload info */ -typedef struct { - int payload_type; //TODO BLASBERG: uint8_t or uint16_t should be acceptable -} sipAvtPayloadType_t; - -/* Identifies CCB type because registration & call control use the same CCBs */ -typedef enum { - SIP_NONE_CCB, - SIP_REG_CCB, - SIP_CALL_CCB -} sipCCBTypes_t; - -/* - * Define the types of CC's - */ -typedef enum { - CC_CCM = CC_MODE_CCM, - CC_OTHER = CC_MODE_NONCCM, - MAX_CC_TYPES -} CC_ID; - -/* - * Offer/answer state - */ -typedef enum { - OA_IDLE, - OA_OFFER_SENT, - OA_OFFER_RECEIVED, - OA_ANSWER_SENT, - OA_ANSWER_RECEIVED -} sipOfferAnswerState; - -/* Indentifies how proxy selection is being done */ -typedef enum { - SIP_PROXY_DEFAULT, /* Current selection is configured proxy */ - SIP_PROXY_BACKUP, /* Current selection is configured backup proxy */ - SIP_PROXY_DO_NOT_CHANGE_MIDCALL /* Do not select a different proxy even on failure*/ -} sipCCBProxySelection; - -typedef struct -{ - union { - string_t sip_via_header; // For received requests - string_t sip_via_branch; // For sent requests - } u; - string_t sip_via_sentby; - sipMethod_t cseq_method; - uint32_t cseq_number; -} sipTransaction_t; - -typedef struct -{ - char sipCallID[MAX_SIP_CALL_ID]; - callid_t gsm_id; - callid_t con_call_id; - callid_t blind_xfer_call_id; - - sipSMStateType_t state; - line_t index; - line_t dn_line; - boolean hold_initiated; - uint32_t retx_counter; - sipCCBTypes_t type; - - /* - * first_backup indicates whether or not the backup proxy has just been - * activated. After the first message is retransmitted, the flag will be - * reset to FALSE. - */ - boolean first_backup; - sipCCBProxySelection proxySelection; /* Indicates how proxy selection is being done */ - cpr_ip_addr_t outBoundProxyAddr; /* IP address of outbound proxy for this call */ -// uint16_t outBoundProxyPort; /* Outbound proxy port for this call */ - uint32_t outBoundProxyPort; /* Outbound proxy port for this call */ - - srv_handle_t SRVhandle; /* handle for dns_gethostbysrv() */ - srv_handle_t ObpSRVhandle; /* SRVhandle for the outbound proxy */ - int routeMode; /* Current routemode set by UIMatchDialTemplate() */ - void *udpId; /* handle to UDPApplIcmpHandler */ - - /* - * An INVITE/ACK/1xx/2xx can be accompanied with a Contact header. - * Future requests should go there. This field is used to store the - * parsed Contact header received with any of these messages. - */ - sipContact_t *contact_info; - - /* Refer To and refere by headers Needed for next generated call */ - - /* - * Any SIP request such as INVITE, BYE, CANCEL etc and INVITE 200 OK, - * 401 & 484 responses can have a Record-Route header. This field is - * used to store the parsed Record-Route header received in any of - * these messages. - */ - sipRecordRoute_t *record_route_info; - - string_t calledDisplayedName; - string_t callingNumber; - string_t altCallingNumber; - string_t callingDisplayName; - string_t calledNumber; - boolean displayCalledNumber; - boolean displayCallingNumber; - uint16_t calledNumberLen; - boolean calledNumberFirstDigitDialed; - - /* - * The following field encodes boolean bit flags (on or off) for - * loopback, inband_alerting, sip_tcp, incoming, added_to_table, - * do_call_history, rsvp_reserved, msgPassthru, sigoCall, - * sent_bye, sent_cancel, sent_bye_response, sent_3456xx, recd_456xx, - * harikiri, timed_out, sd_in_ack - */ - uint32_t flags; - -#define LOOPBACK 1 -#define INBAND_ALERTING (1<<1) -#define SIP_TCP (1<<2) -#define INCOMING (1<<3) -#define ADDED_TO_TABLE (1<<4) -#define DO_CALL_HISTORY (1<<5) -#define RSVP_RESERVED (1<<6) -#define SENT_BYE (1<<7) -#define SENT_CANCEL (1<<8) -#define RECD_BYE (1<<9) -#define SENT_3456XX (1<<10) -#define RECD_456XX (1<<11) -#define HARIKIRI (1<<12) -#define TIMED_OUT (1<<13) -#define SD_IN_ACK (1<<14) -#define MSG_PASSTHRU (1<<15) -#define SIGO_CALL (1<<16) -#define RECD_1xx (1<<17) -#define SEND_CANCEL (1<<18) -#define FINAL_NOTIFY (1<<19) -#define SENT_INVITE_REPLACE (1<<20) - - /* - * SIP signalling channel info: source and destination - */ - cpr_ip_addr_t src_addr; /* Source address */ - cpr_ip_addr_t dest_sip_addr; /* Destination address */ -// uint16_t local_port; /* Source port */ -// uint16_t dest_sip_port; /* Destination port */ - uint32_t local_port; /* Source port */ - uint32_t dest_sip_port; /* Destination port */ - int16_t sip_socket_handle; - - /* - * RTP/SDP - */ - cc_msgbody_info_t local_msg_body; /* store local sent msg bodies */ -// sipSdp_t *src_sdp; -// ushort src_port; -// sipSdp_t *dest_sdp; -// uint16_t dest_port; -// uint32_t dest_addr; - char *old_session_id; - char *old_version_id; -// ushort dest_sdp_media; -// boolean rtp_rx_opened; -// boolean rtp_tx_opened; -// cc_sdp_t cc_sdp; - - /* - * Headers - */ - char ReqURI[MAX_SIP_URL_LENGTH]; /* "Working" Req-URI */ - string_t ReqURIOriginal; /* Original outgoing call Req-URI */ - string_t sip_from; - string_t sip_to; - string_t sip_to_tag; - string_t sip_from_tag; - string_t sip_contact; - string_t sip_remote_party_id; - string_t sip_reqby; - string_t sip_require; - string_t sip_unsupported; - char *diversion[MAX_DIVERSION_HEADERS]; -#define MAX_REQ_OUTSTANDING 3 - sipTransaction_t sent_request[MAX_REQ_OUTSTANDING]; - sipTransaction_t recv_request[MAX_REQ_OUTSTANDING]; - uint32_t last_recv_request_cseq; - sipMethod_t last_recv_request_cseq_method; - uint32_t last_used_cseq; - uint32_t last_recv_invite_cseq; - string_t sip_referTo; - string_t sip_referredBy; - string_t referto; - string_t sipxfercallid; - boolean wastransferred; - boolean blindtransferred; - unsigned int xfer_status; - /* Store all of the parsed diversion header info */ - sipDiversionInfo_t *div_info; - - cc_call_type_e call_type; - - /* Store all of the parsed Remote-Party-ID headers */ - sipRemotePartyIdInfo_t *rpid_info; - /* Shallow pointer to the "best" parsed Remote-Party-ID header */ - sipRemotePartyId_t *best_rpid; - - /* To save the Via headers on the INVITE */ - sipMessage_t *last_request; - - /* - * Features - */ - sipSMXfrType_t xfr_inprogress; - cc_features_t featuretype; - - sipAvtPayloadType_t avt; - - /* - * Registration/Authentication - */ - sipRegister_t reg; - sipAuthenticate_t authen; - - /* - * Two fields that can be sent with the Refer-To header - */ - char *refer_proxy_auth; -#ifdef SIP_ACC_CONT - char *refer_acc_cont; -#endif - /* - * This struct would be allocated when the call is actually redirected - * Idea is to save memory in the ccb for non-redirected calls. - */ - sipRedirectInfo_t *redirect_info; - - /* - * Enum of what was in the alert-info header. - */ - cc_alerting_type alert_info; - - /* - * Contents of incoming and outgoing call-info headers - */ - cc_call_info_t *in_call_info; - cc_call_info_t *out_call_info; - - /* - * Ringing/tone pattern to play - */ - vcm_ring_mode_t alerting_ring; - vcm_tones_t alerting_tone; - - /* - * Personal Directory - */ - boolean call_entered_into_pd; - boolean wait_for_ack; - boolean send_delayed_bye; - boolean retx_flag; - boolean early_transfer; - boolean first_pass_3xx; - CC_ID cc_type; - void *cc_cfg_table_entry; - /* - * Contents of supported and required headers - */ -#define replaces_tag 1 -#define rel_tag (1<<1) -#define early_session_tag (1<<2) -#define join_tag (1<<3) -#define path_tag (1<<4) -#define precondition_tag (1<<5) -#define pref_tag (1<<6) -#define privacy_tag (1<<7) -#define sec_agree_tag (1<<8) -#define timer_tag (1<<9) -#define norefersub_tag (1<<10) -#define cisco_callinfo_tag (1<< 11) -#define cisco_srtp_fallback_tag (1<< 12) -#define extended_refer_tag (1<<16) -#define cisco_serviceuri_tag (1<<18) -#define cisco_escapecodes_tag (1<<19) -#define cisco_service_control_tag (1<<20) -#define sdp_anat_tag (1<< 21) -#define unrecognized_tag (1<<31) - - uint32_t supported_tags; - uint32_t required_tags; - -#define SUPPORTED_TAGS replaces_tag | join_tag | sdp_anat_tag | norefersub_tag - - - /* - * Contents of the the allow header accepted by the remote side - */ -#define ALLOW_ACK 1 -#define ALLOW_BYE (1<<1) -#define ALLOW_CANCEL (1<<2) -#define ALLOW_INFO (1<<3) -#define ALLOW_INVITE (1<<4) -#define ALLOW_MESSAGE (1<<5) -#define ALLOW_NOTIFY (1<<6) -#define ALLOW_OPTIONS (1<<7) -#define ALLOW_PRACK (1<<8) -#define ALLOW_PUBLISH (1<<9) -#define ALLOW_REFER (1<<10) -#define ALLOW_REGISTER (1<<11) -#define ALLOW_SUBSCRIBE (1<<12) -#define ALLOW_UPDATE (1<<13) - - uint16_t allow_methods; - - sipOfferAnswerState oa_state; - int last_recvd_response_code; - sipJoinInfo_t *join_info; - cc_feature_data_t *feature_data; - int dup_flags; - void *mother_ccb; - -#define DUP_NO_FLAGS 0x00 -#define DUP_CCB 0x01 -#define DUP_CCB_NEW_CALLID 0x02 -#define DUP_CCB_INIT_STATE 0x04 -#define DUP_CCB_REINIT_DNS 0x08 -#define DUP_CCB_STOLEN_FEAT_DATA 0x10 - - cc_kfact_t *kfactor_ptr; - - boolean send_reason_header; - - uint32_t callref; - -} ccsipCCB_t; - - -typedef struct { - ccsipCCB_t ccbs[MAX_CCBS]; - int backup_active; /* Currently use reduce invite retry count */ -} ccsipGlobInfo_t; - - -typedef struct { - sipSMEventType_t type; - ccsipCCB_t *ccb; - union { - sipMessage_t *pSipMessage; - cc_msg_t *cc_msg; - cpr_ip_addr_t UsrInfo; - } u; -} sipSMEvent_t; - -typedef void (*sipSMEventActionFn_t)(ccsipCCB_t *ccb, sipSMEvent_t *event); -typedef void (*shutdown_callback_fn)(void *data); - -typedef struct { - shutdown_callback_fn callback; - void *data; -} shutdown_t; - -typedef enum { - SIP_SDP_SUCCESS = 0, - SIP_SDP_SESSION_AUDIT, - SIP_SDP_DNS_FAIL, - SIP_SDP_NO_MEDIA, - SIP_SDP_ERROR, - SIP_SDP_NOT_PRESENT -} sipsdp_status_t; - -extern ccsipGlobInfo_t gGlobInfo; -sipSMAction_t get_handler_index(sipSMStateType_t isipsmstate, - sipSMEventType_t isipsmevent); - -void ccsip_handle_idle_ev_sip_invite(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_idle_ev_cc_setup(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_sentinvite_ev_sip_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_ev_sip_3xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_ev_sip_fxx(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_sentinviteconnected_ev_cc_connected_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_recvinvite_ev_cc_setup_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_cc_proceeding(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_cc_alerting(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_cc_connected(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_sip_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_active_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_hold(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_resume_or_media(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_other(ccsipCCB_t *ccb, - sipSMEvent_t event); -void ccsip_handle_active_ev_sip_invite(ccsipCCB_t *ccb, sipSMEvent_t *event); - - -void ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack( - ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_accept_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_active_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); - - -void ccsip_handle_default(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_sip_message(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_sip_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_sip_timer(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_disconnect_local(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_disconnect_local_early(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_disconnect_local_unanswered(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_disconnect_remote(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_refer_sip_message(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_active_ev_cc_feature_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_active_ev_cc_feature_xfer(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_indication(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_sentbye_recvd_invite(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentbye_ev_sip_fxx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentbye_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentbye_ev_sip_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sendbye_ev_supervision_disconnect(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_recv_error_response_ev_sip_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_release_complete(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_send_blind_notify(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentblindntfy_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_release_ev_sip_bye(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_process_in_call_options_request(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_cc_answer_options_request(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_cc_answer_audit_request(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_localexpires_timer(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_early_ev_sip_update(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_early_ev_sip_update_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_early_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_early_ev_cc_feature_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_active_ev_sip_update(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack( - ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_timer_glare_avoidance(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_expires_timer(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_unsolicited_notify(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_icmp_unreachable(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_disconnect_media_change(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sent_ood_refer_ev_sip_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sent_ood_refer_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sent_ood_refer_ev_sip_fxx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_recvreq_ack_pending_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_midcall_ev_cc_feature(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_sentinvite_midcall_ev_sip_2xx(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_release_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_cc_info(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_release_ev_release(ccsipCCB_t *ccb, sipSMEvent_t *event); - -int sip_sm_init(void); -void sip_shutdown(void); -void sip_shutdown_phase1(int, int reason); -void sip_shutdown_phase2(int); -void sip_restart(void); -int sip_sm_ccb_init(ccsipCCB_t *ccb, line_t index, int DN, - sipRegSMStateType_t initial_state); -ccsipCCB_t *sip_sm_get_ccb_by_index(line_t index); -ccsipCCB_t *sip_sm_get_ccb_by_ccm_id_and_index(int ccm_id, line_t idx); -ccsipCCB_t *sip_sm_get_ccb_by_callid(const char *callid); -ccsipCCB_t *sip_sm_get_ccb_next_available(line_t *line_number); -ccsipCCB_t *sip_sm_get_ccb_by_gsm_id(callid_t gsm_id); -ccsipCCB_t *sip_sm_get_ccb_by_target_call_id(callid_t con_id); -ccsipCCB_t *sip_sm_get_target_call_by_gsm_id(callid_t gsm_id); -ccsipCCB_t *sip_sm_get_target_call_by_con_call_id(callid_t con_call_id); -boolean sip_is_releasing(ccsipCCB_t* ccb); -callid_t sip_sm_get_blind_xfereror_ccb_by_gsm_id(callid_t gsm_id); -uint16_t sip_sm_determine_ccb(const char *callid, - sipCseq_t *sipCseq, - sipMessage_t *pSipMessage, - boolean is_request, - ccsipCCB_t **ccb); -void sip_sm_call_cleanup(ccsipCCB_t *ccb); -void free_duped(ccsipCCB_t *dupCCB); - - -int sip_sm_process_event(sipSMEvent_t *pEvent); -int sip_sm_process_cc_event(cprBuffer_t buf); -void sip_sm_util_normalize_name(ccsipCCB_t *ccb, char *dialString); - - -const char *sip_util_state2string(sipSMStateType_t state); -const char *sip_util_event2string(sipSMEventType_t event); -const char *sip_util_method2string(sipMethod_t method); -boolean sip_sm_is_bye_or_cancel_response(sipMessage_t *response); - -sipSMEventType_t sip_util_ccevent2sipccevent(cc_msgs_t cc_msg_type); -const char *sip_util_feature2string(cc_features_t feature); - -void sip_create_new_sip_call_id(char *sipCallID, uint8_t *mac_address, - char *pSrcAddrStr); -void sip_util_get_new_call_id(ccsipCCB_t *ccb); -boolean sip_sm_is_previous_call_id(const char *pCallID, - line_t *pPreviousCallLine); -boolean sip_sm_util_is_timeinterval(const char *pStr); - -void sip_decrement_backup_active_count(ccsipCCB_t *ccb); -//int sip_sm_active_calls(void); -#ifdef DEBUG -void print_ccb_memoryusage(ccsipCCB_t *ccb); -#endif - -void sip_sm_200and300_update(ccsipCCB_t *ccb, sipMessage_t *response, - int response_code); -char *sip_sm_purify_tag(char *tag); -boolean sip_sm_is_invite_response(sipMessage_t *response); -boolean sip_sm_is_refer_response(sipMessage_t *response); -boolean sip_sm_is_notify_response(sipMessage_t *response); - -void sip_sm_dequote_string(char *str, int max_size); -void sip_sm_check_retx_timers(ccsipCCB_t *ccb, sipMessage_t *message); -int strcasecmp_ignorewhitespace(const char *cs, const char *ct); - -void sip_util_make_ccmsgsdp(cc_sdp_t *pCcMsgSdp, ccsipCCB_t *ccb); - -int sip_dns_gethostbysrv(char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *srv_order, - boolean retried_addr); -int sip_dns_gethostbysrvorname(char *hname, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port); -void sip_util_make_tag(char *tag_str); -void get_sip_error_string(char *errortext, int response); -int ccsip_cc_to_sip_cause(cc_causes_t cause, char **phrase); -void sip_sm_update_to_on_midcall_200(ccsipCCB_t *ccb, sipMessage_t *response); - -sipServiceControl_t *ccsip_get_notify_service_control(sipMessage_t *pSipMessage); -boolean ccsip_is_special_name_to_mask_display_number(const char *name); -void sip_sm_change_state(ccsipCCB_t *ccb, sipSMStateType_t new_state); - -#define SIP_SM_CALL_SETUP_NOT_COMPLETED(x) \ - ((x->state == SIP_STATE_RECV_INVITE) || \ - (x->state == SIP_STATE_RECV_INVITE_PROCEEDING) || \ - (x->state == SIP_STATE_RECV_INVITE_ALERTING) || \ - (x->state == SIP_STATE_RECV_INVITE_CONNECTED)) -#define SIP_SM_CALL_SETUP_RESPONDING(x) \ - ((x->state == SIP_STATE_RECV_INVITE_PROCEEDING) || \ - (x->state == SIP_STATE_RECV_INVITE_ALERTING)) - -#define ccsip_is_replace_setup(replace) (replace) - -extern char *ccsip_find_preallocated_sip_local_tag(line_t dn_line); -extern void ccsip_free_preallocated_sip_local_tag(line_t dn_line); -extern char *getPreallocatedSipCallID(line_t dn_line); -extern char *getPreallocatedSipLocalTag(line_t dn_line); -extern ccsipCCB_t* create_dupCCB(ccsipCCB_t *origCCB, int dup_flags); - -/* Info Package stuff */ -#define MAX_INFO_HANDLER 32 - -/* - * g_registered_info[] contains the Info Package strings (such as - * "conference") for the registered handlers. - * - * The index of g_registered_info[] goes from 0 to MAX_INFO_HANDLER - 1. - */ -extern char *g_registered_info[]; - -typedef void (*info_package_handler_t)(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body); - -int ccsip_info_package_handler_init(void); -void ccsip_info_package_handler_shutdown(void); -int ccsip_register_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler); -int ccsip_deregister_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler); -void ccsip_parse_send_info_header(sipMessage_t *pSipMessage, string_t *recv_info_list); -int ccsip_handle_info_package(ccsipCCB_t *ccb, sipMessage_t *pSipMessage); - - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_credentials.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_credentials.h deleted file mode 100644 index e23a43372fa..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_credentials.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CREDENTIALS_H_ -#define _CCSIP_CREDENTIALS_H_ - -#include "cpr_types.h" -#include "prot_configmgr.h" - -#define CRED_MAX_ID_LEN AUTH_NAME_SIZE -#define CRED_MAX_PW_LEN 32 - -#define CRED_USER 0x00000001 -#define CRED_LINE 0x00000002 - - -typedef struct _credentials { - char id[CRED_MAX_ID_LEN]; - char pw[CRED_MAX_PW_LEN]; -} credentials_t; - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_macros.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_macros.h deleted file mode 100644 index 40a560bb541..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_macros.h +++ /dev/null @@ -1,24 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_MACROS_H_ -#define _CCSIP_MACROS_H_ - - -#define EVENT_ACTION_SM(x) \ - (gSIPHandlerTable[x]) - -#define UPDATE_FLAGS(x, y) \ - (x = (x == STATUS_SUCCESS) ? y : x) - -#define GET_SIP_MESSAGE() sippmh_message_create() - -#define REG_CHECK_EVENT_SANITY(x, y) \ - ((x - SIP_REG_STATE_BASE >= 0) && (x <= SIP_REG_STATE_END) && \ - (y - SIPSPI_REG_EV_BASE >=0) && (y <= SIPSPI_REG_EV_END)) - -#define REG_EVENT_ACTION(x, y) \ - (gSIPRegSMTable[x - SIP_REG_STATE_BASE][y - SIPSPI_REG_EV_BASE]) - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_messaging.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_messaging.h deleted file mode 100644 index 0ee3b4d8320..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_messaging.h +++ /dev/null @@ -1,290 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_MESSAGING_H_ -#define _CCSIP_MESSAGING_H_ - -#include "ccsip_sdp.h" -#include "ccsip_pmh.h" -#include "ccsip_credentials.h" -#include "ccsip_core.h" -#include "ccsip_subsmanager.h" -#include "ccapi.h" - -#define SIP_MESSAGING_OK (0) -#define SIP_MESSAGING_ERROR (1) -#define SIP_MESSAGING_DUPLICATE (2) -#define SIP_MESSAGING_NEW_CALLID (3) -#define SIP_MESSAGING_ERROR_STALE_RESP (4) -#define SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA (5) -#define SIP_MESSAGING_ERROR_NO_TRX (6) -#define SIP_MESSAGING_NOT_ACCEPTABLE (7) -#define SIP_MESSAGING_ENDPOINT_NOT_FOUND (8) -#define NUM_INITIAL_RECORD_ROUTE_BUFS 4 - -typedef enum { - SIP_INVITE_TYPE_INVALID = 0, - SIP_INVITE_TYPE_NORMAL, - SIP_INVITE_TYPE_MIDCALL, - SIP_INVITE_TYPE_TRANSFER, - SIP_INVITE_TYPE_AUTHORIZATION, - SIP_INVITE_TYPE_REDIRECTED -} sipInviteType_t; - -typedef enum { - SIP_RTP_INCLUDE_MEDIA_INVALID = 0, - SIP_RTP_INCLUDE_MEDIA_ALL, - SIP_RTP_INCLUDE_MEDIA_PREFERRED, - SIP_RTP_INCLUDE_MEDIA_MATCHING -} sipRTPIncludeMedia_t; - -typedef enum { - SIP_REF_NONE = 0, - SIP_REF_XFER, - SIP_REF_DIR_XFER, - SIP_REF_TOKEN, - SIP_REF_UNKNOWN -} sipRefEnum_e; - -typedef struct { - unsigned int flags; - unsigned int extflags; -} sipMessageFlag_t; - - -#define SIP_HEADER_CONTACT_BIT 1 -#define SIP_HEADER_RECORD_ROUTE_BIT (1<<1) -#define SIP_HEADER_ROUTE_BIT (1<<2) -#define SIP_HEADER_SPARE_BIT0 (1<<3) -#define SIP_HEADER_REQUESTED_BY_BIT (1<<4) -#define SIP_HEADER_DIVERSION_BIT (1<<5) -#define SIP_HEADER_AUTHENTICATION_BIT (1<<6) -#define SIP_HEADER_REFER_TO_BIT (1<<7) -#define SIP_HEADER_REFERRED_BY_BIT (1<<8) -#define SIP_HEADER_REPLACES_BIT (1<<9) -#define SIP_HEADER_EVENT_BIT (1<<10) -#define SIP_HEADER_EXPIRES_BIT (1<<11) -#define SIP_HEADER_ACCEPT_BIT (1<<12) -#define SIP_HEADER_ALLOW_BIT (1<<13) -#define SIP_HEADER_CISCO_GUID_BIT (1<<14) -#define SIP_HEADER_SPARE_BIT1 (1<<15) -#define SIP_HEADER_UNSUPPORTED_BIT (1<<16) -#define SIP_HEADER_REMOTE_PARTY_ID_BIT (1<<17) -#define SIP_HEADER_PROXY_AUTH_BIT (1<<18) -#define SIP_HEADER_REQUIRE_BIT (1<<19) -#define SIP_HEADER_CALL_INFO_BIT (1<<20) -#define SIP_HEADER_SUPPORTED_BIT (1<<21) -#define SIP_HEADER_RETRY_AFTER_BIT (1<<22) -#define SIP_HEADER_ALLOW_EVENTS_BIT (1<<23) -#define SIP_HEADER_CONTENT_TYPE_BIT (1<<24) -#define SIP_HEADER_CONTENT_LENGTH_BIT (1<<25) -#define SIP_HEADER_JOIN_INFO_BIT (1<<26) -#define SIP_HEADER_ACCEPT_ENCODING_BIT (1<<27) -#define SIP_HEADER_ACCEPT_LANGUAGE_BIT (1<<28) -#define SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT (1<<29) -#define SIP_HEADER_REASON_BIT (1<<30) -#define SIP_HEADER_RECV_INFO_BIT (1U<<31) - - -#define SIP_RFC_SUPPORTED_TAGS REQ_SUPP_PARAM_REPLACES "," \ - REQ_SUPP_PARAM_JOIN "," \ - REQ_SUPP_PARAM_SDP_ANAT "," \ - REQ_SUPP_PARAM_NOREFERSUB - -/* - * The REQ_SUPP_PARAM_EXTENED_REFER is only used in Cisco CCM environment. - * The tag is no longer in IANA. - */ -#define SIP_CISCO_SUPPORTED_TAGS REQ_SUPP_PARAM_EXTENED_REFER "," \ - REQ_SUPP_PARAM_CISCO_CALLINFO "," \ - REQ_SUPP_PARAM_CISCO_ESCAPECODES "," \ - REQ_SUPP_PARAM_CISCO_MONREC - -#define SIP_CISCO_SUPPORTED_REG_TAGS \ - SIP_RFC_SUPPORTED_TAGS "," \ - SIP_CISCO_SUPPORTED_TAGS - - -boolean sipSPISendInvite(ccsipCCB_t *ccb, - sipInviteType_t inviteType, - boolean initInvite); -boolean sipSPISendInviteMidCall(ccsipCCB_t *ccb, boolean expires); -void sipSPISendInviteResponse100(ccsipCCB_t *ccb, boolean remove_to_tag); -void sipSPISendInviteResponse180(ccsipCCB_t *ccb); -void sipSPISendInviteResponse200(ccsipCCB_t *ccb); -void sipSPISendInviteResponse302(ccsipCCB_t *ccb); - -boolean sipSPISendOptionResponse(ccsipCCB_t *ccb, sipMessage_t *); -boolean sipSPIsendNonActiveOptionResponse(sipMessage_t *msg, - cc_msgbody_info_t *local_msg_body); -void sipSPISendInviteResponse(ccsipCCB_t *ccb, - uint16_t statusCode, - const char *reason_phrase, - uint16_t warnCode, - const char *warn_phrase, - boolean send_sd, - boolean retx); -void sipSPISendBye(ccsipCCB_t *ccb, - char *alsoString, - sipMessage_t *pForked200); -void sipSPISendCancel(ccsipCCB_t *ccb); -boolean sipSPISendByeOrCancelResponse(ccsipCCB_t *ccb, - sipMessage_t *request, - sipMethod_t sipMethodByeorCancel); -boolean sipSPISendAck(ccsipCCB_t *ccb, sipMessage_t *response); -boolean sipSPISendRegister(ccsipCCB_t *ccb, - boolean no_dns_lookup, - const char *user, - int expires_int); - -boolean sipSPISendErrorResponse(sipMessage_t *msg, uint16_t status_code, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - ccsipCCB_t *ccb); -boolean sipSPISendLastMessage(ccsipCCB_t *ccb); -boolean sipSPIGenerateAuthorizationResponse(sip_authen_t * sip_authen, - const char *uri, - const char *method, - const char *user_name, - const char *user_password, - char **author_str, - int *nc_count, - ccsipCCB_t *ccb); -void sipSPIGenerateGenAuthorizationResponse(ccsipCCB_t *ccb, - sipMessage_t *request, - sipRet_t *flag, - char *method); - -void sipSPIGenerateTargetUrl(genUrl_t *genUrl, char *sipurlstr); -void sipSPIGenerateSipUrl(sipUrl_t *sipUrl, char *sipurlstr); - -boolean sipSPISendRefer(ccsipCCB_t *ccb, char *referto, - sipRefEnum_e referto_type); -boolean sipSPISendReferResponse202(ccsipCCB_t *ccb); -boolean sipSPISendNotify(ccsipCCB_t *ccb, int referto); -boolean sipSPISendInfo(ccsipCCB_t *ccb, const char *info_package, - const char *content_type, const char *message_body); -boolean sipSPISendUpdate(ccsipCCB_t *ccb); -boolean sipSPISendUpdateResponse(ccsipCCB_t *ccb, - boolean send_sdp, - cc_causes_t cause, - boolean retx); -boolean sipSPISendNotifyResponse(ccsipCCB_t *ccb, cc_causes_t cause); -boolean sipSPIAddStdHeaders(sipMessage_t *msg, - ccsipCCB_t *ccb, - boolean isResponse); -sipMessage_t *sipSPIBuildRegisterHeaders(ccsipCCB_t *ccb, - const char *user, - int expires_int); -boolean sipSPIAddLocalVia(sipMessage_t *msg, - ccsipCCB_t *ccb, - sipMethod_t method); -boolean sipSPIAddRequestVia(ccsipCCB_t *ccb, - sipMessage_t *response, - sipMessage_t *request, - sipMethod_t method); -boolean sipSPIAddCiscoGuid(sipMessage_t *msg, ccsipCCB_t *ccb); -boolean sipSPIAddRouteHeaders(sipMessage_t *msg, - ccsipCCB_t *ccb, - char *result_route, - int result_route_length); -sipRet_t sipAddDateHeader(sipMessage_t *sip_message); - -const char *sipGetMethodString(sipMethod_t methodname); - -void sip_option_response_rtp_media_get_info(cc_sdp_t *src_sdp); - -//sipSdp_t* CreateSDPtext(); - - -sipRet_t sipSPIAddContactHeader(ccsipCCB_t *ccb, sipMessage_t *request); -sipRet_t sipSPIAddReasonHeader (ccsipCCB_t *ccb, sipMessage_t *request); -boolean sipSPIGenerateReferredByHeader(ccsipCCB_t *ccb); -boolean sipSPIGenRequestURI(ccsipCCB_t *ccb, - sipMethod_t sipmethod, - boolean initInvite); - -// Message Factory -sipRet_t sipSPIAddCommonHeaders(ccsipCCB_t *ccb, - sipMessage_t *request, - boolean isResponse, - sipMethod_t method, - uint32_t response_cseq_number); -boolean CreateRequest(ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - sipMethod_t sipmethod, - sipMessage_t *request, - boolean initInvite, - uint32_t response_cseq_number); -boolean CreateResponse(ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - uint16_t status_code, - sipMessage_t *response, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - sipMethod_t); -boolean SendRequest(ccsipCCB_t *ccb, - sipMessage_t *request, - sipMethod_t method, - boolean midcall, - boolean reTx, - boolean timer); -boolean AddGeneralHeaders(ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - sipMessage_t *request, - sipMethod_t method); -boolean getCSeqInfo(sipMessage_t *request, - sipCseq_t **request_cseq_structure); -int sipSPICheckRequest(ccsipCCB_t *ccb, sipMessage_t *request); -int sipSPICheckResponse(ccsipCCB_t *ccb, sipMessage_t *response); -int sipSPICheckContact(const char *pContactStr); - -void sipGetRequestMethod(sipMessage_t *pRequest, sipMethod_t *pMethod); -int sipGetResponseMethod(sipMessage_t *pResponse, sipMethod_t *pMethod); -int sipGetResponseCode(sipMessage_t *pResponse, int *pResponseCode); -int sipSPIIncomingCallSDP(ccsipCCB_t *ccb, - boolean call_hold, - boolean udpate_ver); -char *sipSPIUrlDestination(sipUrl_t *sipUrl); -int sipGetMessageCSeq(sipMessage_t *pMessage, uint32_t *pResultCSeqNumber, - sipMethod_t * pResultCSeqMethod); -void sipGetMessageToTag(sipMessage_t *pMessage, char *to_tag, - int to_tag_max_length); -boolean sipSPISendByeAuth(sipMessage_t *pResponse, - sipAuthenticate_t authen, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - uint32_t cseq_number, - char *alsoString, - char *last_call_route, - char *last_call_route_request_uri, - line_t previous_call_line); -void free_sip_message(sipMessage_t *message); -void sipSPISendFailureResponseAck(ccsipCCB_t *ccb, - sipMessage_t *response, - boolean prevcall, - line_t previous_call_line); -/* ICMP Unreachable handler routine */ -void sip_platform_icmp_unreachable_callback(void *ccyb, uint32_t ipaddr); -cc_disposition_type_t sip2ccdisp(uint8_t type); -cc_content_type_t sip2cctype(uint8_t type); - -/* Transaction record manipulation methods */ -int16_t get_last_request_trx_index(ccsipCCB_t *ccb, boolean sent); -int16_t get_next_request_trx_index(ccsipCCB_t *ccb, boolean sent); -int16_t get_method_request_trx_index(ccsipCCB_t *ccb, sipMethod_t method, - boolean sent); -void clean_method_request_trx(ccsipCCB_t *ccb, sipMethod_t method, boolean sent); -line_t get_dn_line_from_dn(const char *watcher); -boolean sipSPIGenerateRouteHeaderUAC(sipRecordRoute_t *, char *, int, - boolean *loose_routing); -boolean sipSPIGenerateRouteHeaderUAS(sipRecordRoute_t *, char *, int, - boolean *loose_routing); -boolean sipSPIGenerateContactHeader(sipContact_t *, char *, int); - -void get_reason_string(int unreg_reason, char *unreg_reason_str, int len); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform.h deleted file mode 100644 index 36b8c925684..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PLATFORM_H_ -#define _CCSIP_PLATFORM_H_ - -#include "phone_platform_constants.h" - -// SIP standard defines the max to be the path MTU if it is -// known, otherwise it should be 1500 -// We are defining the max message size to be 2560, 1500 + 1060 bytes of -// extended buffer space (which is also the same as the PacketBuffer size -// #define PKTBUF_SIZ 3072 defined in phone.h -#define SIP_UDP_MESSAGE_SIZE 3072 /* Max size of a SIP message */ - -/* Constants */ -#define MAX_SIP_URL_LENGTH 512 -#define MAX_SIP_TAG_LENGTH 256 -#define MAX_SIP_DISPLAYNAME_LENGTH 64 -#define VIA_BRANCH_LENGTH 16 - -/* - * MAX_SIP_DATE_LENGTH is used in ccsip_messaging for - * the SIP Date header routine. - * It has been defined here to be consistent with the rest - * of the defines for the SIP message - */ -#define MAX_SIP_DATE_LENGTH 63 //Extended for foreign language -#define CCSIP_START_CSEQ 100 -#define MAX_SIP_CALL_ID 128 /* Max size of a Call ID header string */ -#define MAX_DIVERSION_HEADERS 25 - -/********************************************************* - * - * - * Phone constants - * - * - *********************************************************/ -#define MAX_REG_BACKUP 1 // Max number of backup registration CCBs -#define MIN_TEL_LINES 0 // Min number of lines -#define MAX_TEL_LINES MAX_CALLS // Max number of calls -#define MAX_PHYSICAL_DIR_NUM 6 // Max number of physical directory numbers -#define MAX_UI_LINES_PER_DN (MAX_LINES_PER_DN + 1) // Max number of lines per DN -#define MAX_CCBS (MAX_TEL_LINES + MAX_REG_LINES + MAX_REG_BACKUP) -#define TEL_CCB_START (MIN_TEL_LINES) -#define TEL_CCB_END (TEL_CCB_START + MAX_TEL_LINES -1) -#define REG_CCB_START (TEL_CCB_END + 1) -#define REG_CCB_END (REG_CCB_START + MAX_REG_LINES -1) -#define REG_BACKUP_CCB (REG_CCB_END + 1) -#define REG_FALLBACK_CCB_START (REG_BACKUP_CCB + 1) -#define REG_FALLBACK_CCB_END (REG_FALLBACK_CCB_START +4) -#define REG_BACKUP_DN 1 -#define REG_BACKUP_LINE 7 -#define MAX_LINES_7940 2 -#define INVALID_DN_LINE (REG_FALLBACK_CCB_END + 1) -#define INIT_DN_LINE 0 - - -void sip_platform_init(void); -int sip_platform_ui_restart(void); -extern void platform_print_sip_msg(const char *msg); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tcp.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tcp.h deleted file mode 100644 index 21c0b0342d7..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tcp.h +++ /dev/null @@ -1,99 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CCSIP_PLATFORM_TCP__H__ -#define __CCSIP_PLATFORM_TCP__H__ - -/* The maximum number of connections allowed */ -#define MAX_SIP_CONNECTIONS (64 - 2) - -#define SIP_TCP_SEND_OK 0 -#define SIP_TCP_SIZE_ERROR 1 -#define SIP_TCP_SEND_ERROR 2 -#define SIP_SOC_TCP 0 -#define SIP_SOC_TLS 1 - -#define SIP_TCP_NOT_CONNECTED 0 -#define SIP_TCP_CONNECTED 1 - -typedef struct _sendData -{ - struct _sendData *next; - char *data; - uint16_t bytesLeft; - uint16_t bytesSent; - void *context; - boolean msg_display; - uint8_t ip_sig_tos; -} ccsipTCPSendData_t; - -typedef struct -{ - uint16 connectionId; -} sipTCPTimerContext_t; - -typedef struct -{ - cpr_socket_t fd; /* Socket file descriptor */ - cpr_sockaddr_storage addr; - cpr_ip_addr_t ipaddr; /* Remote IP address */ - uint16_t port; /* Remote port # */ - sock_state_t state; - char *prev_msg; - uint32_t prev_bytes; - void *context; /* Connection Manager's context */ - /* queue for partial socket writes */ - sll_handle_t sendQueue; - boolean dirtyFlag; - boolean pend_closure; /* Indicates to close the connection - * entry on completion of partial - * socket message writes - */ - int error_cause; - int soc_type; -} sip_tcp_conn_t; - -typedef struct -{ - cpr_socket_t read[MAX_SIP_CONNECTIONS]; - cpr_socket_t write[MAX_SIP_CONNECTIONS]; -} sip_connection_t; - - -extern sip_connection_t sip_conn; -extern uint32_t nfds; -extern fd_set read_fds; -extern fd_set write_fds; -extern sip_tcp_conn_t sip_tcp_conn_tab[MAX_CONNECTIONS]; - -/* - * - * Function declarations - * - */ -int sip_tcp_fd_to_connid(cpr_socket_t fd); -cpr_socket_t sip_tcp_create_connection(sipSPIMessage_t *spi_msg); -void sip_tcp_read_socket(cpr_socket_t this_fd); -int sip_tcp_channel_send(cpr_socket_t s, - char *buf, - uint32_t len); -void sip_tcp_createconnfailed_to_spi(cpr_ip_addr_t *ipaddr, - uint16_t port, - void *context, - ccsipSockErrCodes_e errcode, - int connid); -void sip_tcp_purge_entry(sipSPIConnId_t connid); -void sipTcpFlushRetrySendQueue(sip_tcp_conn_t *entry); -void sip_tcp_resend(int connid); -extern int sip_tcp_get_free_conn_entry(void); -extern int sip_tcp_attach_socket(cpr_socket_t s); -extern void sip_tcp_init_conn_table(void); -extern boolean sip_tcp_set_sock_options(int fd); -void sipTransportClearServerHandle(cpr_ip_addr_t *ipaddr, - uint16_t port, - int connid); -void sipTcpFreeSendQueue(int connid); -extern cpr_socket_t sip_tcp_create_conn_using_blocking_socket (sipSPIMessage_t *spi_msg); - -#endif /* __CCSIP_PLATFORM_TCP__H__ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_timers.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_timers.h deleted file mode 100644 index 06a6f54a26a..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_timers.h +++ /dev/null @@ -1,164 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PLATFORM_TIMERS_H_ -#define _CCSIP_PLATFORM_TIMERS_H_ - -#include "cpr_types.h" -#include "cpr_timers.h" -#include "ccsip_platform.h" -#include "ccsip_pmh.h" - -#define LINE_NOT_FOUND -1 - -/* - * Defintions - */ -typedef void (*sipTimerCallbackFn_t)(cprTimer_t pTmrBlk); - -typedef struct -{ - cprTimer_t timer; - cprTimer_t reg_timer; - int line; - char* message_buffer; - int message_buffer_len; - sipMethod_t message_type; - cpr_ip_addr_t ipaddr; - uint16_t port; - boolean outstanding; -} sipPlatformUITimer_t; - -typedef struct -{ - cprTimer_t timer; - int line; - cpr_ip_addr_t ipaddr; - uint16_t port; -} sipPlatformUIExpiresTimer_t; - -typedef struct -{ - cprTimer_t timer; - int line; - boolean started; -} sipPlatformSupervisionTimer_t; - - -extern sipPlatformUITimer_t sipPlatformUISMSubNotTimers[]; // Array of timers - -/* - * Prototypes - */ -int -sip_platform_timers_init(void); -void -sip_platform_post_timer(uint32_t cmd, void *data); -void -sip_platform_msg_timers_init(void); -int -sip_platform_msg_timer_start(uint32_t msec, - void *data, - int line, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port, - boolean isRegister); -void -sip_platform_msg_timer_stop(int line); -boolean -sip_platform_msg_timer_outstanding_get(int line); -void -sip_platform_msg_timer_outstanding_set(int line, boolean value); -void -sip_platform_msg_timer_callback(void *data); -int -sip_platform_expires_timer_start(uint32_t msec, - int line, - cpr_ip_addr_t *ipaddr, - uint16_t port); -int -sip_platform_expires_timer_stop(int line); -void -sip_platform_expires_timer_callback(void *data); -int -sip_platform_register_expires_timer_start(uint32_t msec, - int line); -int -sip_platform_register_expires_timer_stop(int line); -int -sip_platform_localexpires_timer_start(uint32_t msec, - int line, - cpr_ip_addr_t *ipaddr, - uint16_t port); -int -sip_platform_localexpires_timer_stop(int line); -void -sip_platform_localexpires_timer_callback(void *data); -int -sip_platform_msg_timer_update_destination(int line, - cpr_ip_addr_t *ipaddr, - uint16_t port); -sipMethod_t -sip_platform_msg_timer_messageType_get(int line); - -// Supervision timer -int -sip_platform_supervision_disconnect_timer_start(uint32_t msec, - int line); -int -sip_platform_supervision_disconnect_timer_stop(int line); -void -sip_platform_supervision_disconnect_timer_callback(void *data); - -// Sub/Not Timers -int -sip_platform_msg_timer_subnot_start(uint32_t msec, - sipPlatformUITimer_t *, - uint32_t index, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port); -void -sip_platform_msg_timer_subnot_stop(sipPlatformUITimer_t *); -void -sip_platform_subnot_msg_timer_callback(void *data); -int -sip_platform_subnot_periodic_timer_start(uint32_t msec); -int -sip_platform_subnot_periodic_timer_stop(void); -void -sip_platform_subnot_periodic_timer_callback(void *data); -int -sip_platform_standby_keepalive_timer_start(uint32_t msec); -int -sip_platform_standby_keepalive_timer_stop(); -void -sip_platform_standby_keepalive_callback(void *data); -int -sip_platform_unregistration_timer_start(uint32_t msec, boolean external); -int -sip_platform_unregistration_timer_stop(); -void -sip_platform_unregistration_callback(void *data); -void -sip_platform_timers_shutdown(void); -int -sip_platform_notify_timer_start(uint32_t msec); -int -sip_platform_notify_timer_stop(); -int -sip_platform_reg_all_fail_timer_start(uint32_t msec); -int -sip_platform_reg_all_fail_timer_stop(void); -int -sip_platform_pass_through_timer_start(uint32_t sec); -int -sip_platform_pass_through_timer_stop(void); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tls.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tls.h deleted file mode 100644 index 6d6fba93780..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tls.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CCSIP_PLATFORM_TLS__H__ -#define __CCSIP_PLATFORM_TLS__H__ - -extern cpr_socket_t sip_tls_create_connection(sipSPIMessage_t *spi_msg, - boolean blocking, - sec_level_t sec); - -#endif /* __CCSIP_PLATFORM_TLS__H__ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_udp.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_udp.h deleted file mode 100644 index 9eddc2094b9..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_udp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PLATFORM_UDP_H_ -#define _CCSIP_PLATFORM_UDP_H_ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "cpr_memory.h" - -int -sip_platform_udp_channel_listen(cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *local_ipaddr, - uint16_t local_port); -int -sip_platform_udp_channel_accept(cpr_socket_t listenSoc, - cpr_socket_t *s); -int -sip_platform_udp_channel_create(cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *remote_ipaddr, - uint16_t remote_port, - uint32_t local_udp_port); -int -sip_platform_udp_channel_destroy(cpr_socket_t s); -int -sip_platform_udp_channel_send(cpr_socket_t s, - char *buf, - uint16_t buf_len); -void -sip_platform_udp_read_socket(cpr_socket_t s); - -int -sip_platform_udp_channel_sendto(cpr_socket_t s, - char *buf, - uint32_t buf_len, - cpr_ip_addr_t *dst_addr, - uint16_t dst_port); -int -sip_platform_udp_channel_read(cpr_socket_t s, - cprBuffer_t buf, - uint16_t *len, - cpr_sockaddr_t *soc_addr, - cpr_socklen_t *soc_addr_len); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_pmh.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_pmh.h deleted file mode 100644 index 303eddde746..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_pmh.h +++ /dev/null @@ -1,827 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PMH_H_ -#define _CCSIP_PMH_H_ - -#include "cpr_types.h" -#include "pmhdefs.h" -#include "httpish.h" -#include "ccsip_protocol.h" -#include "string_lib.h" -#include "ccsip_platform.h" -#include "ccapi.h" - -#define MAX_REFER_TO_HEADER_CONTENTS 6 -#define MAX_REMOTE_PARTY_ID_HEADERS 10 -#define MAX_REPLACES_HEADERS 1 -#define MAX_REFER_TO_HEADERS 2 -#define MAX_REFER_BY_HEADERS 1 -#define MAX_CALL_INFO_HEADERS 4 - -#define MAX_SUB_STATE_HEADER_SIZE 96 -#define TEMP_PARSE_BUFFER_SIZE 10 - -/* - * Maximum number of Location/Contact headers we will parse. These - * specify the locations to try to contact the called party, and I figure - * the user is not going to wait for ever, and simplicity helps. - */ -#define SIP_MAX_LOCATIONS 6 - -/* Used when we create Via headers. Does not apply to incoming messages.*/ -#define SIP_MAX_VIA_LENGTH 128 - -/* Broadsoft: Max length of "other" parameters in 3xx messages. */ -#define SIP_MAX_OTHER_PARAM_LENGTH 256 - -#define TWO_POWER_31 2147483648UL - -/* - * Some of this corresponds directly to HTTP/1.1 message structure. - */ -typedef httpish_header sip_header; -typedef httpishMsg_t sipMessage_t; -typedef httpishReqLine_t sipReqLine_t; -typedef httpishRespLine_t sipRespLine_t; - -typedef httpishStatusCodeClass_t sipStatusCodeClass_t; - -typedef hStatus_t sipRet_t; - -typedef enum -{ - sipMethodInvalid = 0, - sipMethodRegister = 100, - sipMethodOptions, - sipMethodInvite, - sipMethodBye, - sipMethodCancel, - sipMethodPrack, - sipMethodComet, - sipMethodNotify, - sipMethodRefer, - sipMethodAck, - sipMethodMessage, - sipMethodSubscribe, - sipMethodPublish, - sipMethodUpdate, - sipMethodResponse, - sipMethodInfo, - sipMethodUnknown -} sipMethod_t; - -typedef enum -{ - SIP_BASIC = 1, - SIP_DIGEST, - SIP_UNKNOWN -} sip_scheme_t; - -typedef enum -{ - SIP_SUCCESS, - SIP_FAILURE, - SIP_INTERNAL_ERR, - SIP_UNACCEPTABLE_MEDIA_ERR, - SIP_PRE_CONDITION_FAIL_ERR, - SIP_NO_RESOURCE, - SIP_MSG_CREATE_ERR, - SIP_MSG_PARSE_ERR, - SIP_MSG_INCOMPLETE_ERR, - SIP_SUCCESS_DNS_PENDING, - SIP_SUCCESS_QOS_PENDING, - SIP_VIA_DNS_QUERY_REQUIRED, - SIP_SUCCESS_QOS_DNS_PENDING, - SIP_SUCCESS_DELAYED_MEDIA, - SIP_SUCCESS_QOS_DELAYED_MEDIA, - SIP_ADDR_UNAVAILABLE, - SIP_MAX_RC -} ccsipRet_e; - -/* This is used to store the parsed attribute/value pair */ -typedef struct { - char *attr; - char *value; -} attr_value_pair_t; - -typedef struct -{ - /* - * Not storing the schema because we don't deal with non-SIP URLs. - * The rest of the fields do not have any meaning if the URL - * in question is non-SIP. Our parse routine itself would return - * failure. - */ - char *user; - char *password; - char *host; - char *maddr; - char *other; - char *method; - uint16_t port; - boolean port_present; - int16_t transport; - uint8_t is_phone; - uint8_t ttl_val; - char num_headers; /* number of headers in the avpair below */ - attr_value_pair_t *headerp; /* everything after the '?' */ - boolean lr_flag; - boolean is_ipv6; -} sipUrl_t; - -typedef struct -{ - char *user; - char *isdn_subaddr; - char *post_dial; - char *unparsed_tsp; - char *future_ext; -} telUrl_t; - -typedef enum -{ - URL_TYPE_SIP = 1, - URL_TYPE_TEL, - URL_TYPE_CID, - URL_TYPE_UNKNOWN -} urlType_t; - -typedef struct -{ - urlType_t schema; - boolean sips; - char *str_start; - char *phone_context; - char *other_params[SIP_MAX_LOCATIONS]; - union { - sipUrl_t *sipUrl; - telUrl_t *telUrl; - } u; -} genUrl_t; - -typedef struct -{ - char *str_start; /* beginning of duplicated string */ - sip_scheme_t scheme; - char *user_pass; - char *realm; - char *d_username; - char *unparsed_uri; - char *response; - char *algorithm; - char *cnonce; - char *opaque; - char *qop; - char *nc_count; - char *auth_param; /* for future extension */ - char *nonce; -} sip_author_t; - -typedef struct -{ - /* Could be Basic or PGP */ - char *str_start; /* beginning of duplicated string */ - sip_scheme_t scheme; - char *user_pass; - char *realm; - char *version; - char *algorithm; - char *nonce; - char *unparsed_domain; - char *opaque; - char *stale; - char *qop; -} sip_authen_t; - -typedef struct _sipLocation_t -{ - char *loc_start; - char *name; - genUrl_t *genUrl; - char *tag; -} sipLocation_t; - -typedef sipLocation_t sipFrom_t; -typedef sipLocation_t sipTo_t; - -/* - * Definition of the flags in the sipContactParams_t. - * The flags in the sipContact_t is used to store boolean - * parameters (not numerical value). - */ -#define SIP_CONTACT_PARM_X_CISCO_NEWREG (1 << 0) /* new reg parameter */ -typedef struct -{ - int action; /* Proxy or Redirect */ - char *qval; - uint32_t expires; - char *expires_gmt; - char *extn_attr; - uint32_t flags; -} sipContactParams_t; - -typedef struct -{ - sipLocation_t *locations[SIP_MAX_LOCATIONS]; - sipContactParams_t params[SIP_MAX_LOCATIONS]; - uint16_t num_locations; - boolean new_flag; -} sipContact_t; - -typedef struct -{ - sipLocation_t *locations[SIP_MAX_LOCATIONS]; - uint16_t num_locations; - boolean new_flag; -} sipRecordRoute_t; - -typedef enum -{ - sipTransportTypeUDP = 2345, - sipTransportTypeTCP -} sipTransportType_t; - -/* DIVERSION HEADER STRUCTURE */ - -typedef struct -{ - sipLocation_t *locations; -// char *reason; - uint32_t limit; - uint32_t counter; - char *privacy; - char *screen; -} sipDiversion_t; - -typedef struct -{ - string_t orig_called_name; - string_t orig_called_number; - string_t last_redirect_name; - string_t last_redirect_number; -} sipDiversionInfo_t; - - -typedef struct -{ - /* - * We are not storing the protocol ( should be SIP always ) - */ - char *version; - char *transport; - char *host; - char *ttl; - char *maddr; - char *recd_host; - char *branch_param; - /* Remaining Via header(s) if any in the input string */ - char *more_via; - uint16_t remote_port; - uint8_t flags; - boolean is_ipv6; -#define VIA_IS_HIDDEN (0x01) -} sipVia_t; - -typedef struct -{ - uint32_t number; - sipMethod_t method; -} sipCseq_t; - - -typedef struct -{ - uint32_t response_num; - uint32_t cseq_num; - sipMethod_t method; -} sipRack_t; - -typedef enum -{ - sipSessionTypeInvalid = 0, - sipSessionTypeMedia, - sipSessionTypeQoS, - sipSessionTypeSecurity -} sipSessionType_t; - -/* Data structure for Replaces header */ -typedef struct -{ - char *str_start; - char *callid; - char *toTag; - char *fromTag; - char *signature_scheme; -} sipReplaces_t; - -/* Data structure for Refer-To header */ -typedef struct -{ - char *ref_to_start; - genUrl_t *targetUrl; - char *sip_replaces_hdr; - char *sip_acc_cont; - char *sip_proxy_auth; -} sipReferTo_t; - -/* Data structure for Refer method */ -typedef struct -{ - sipReferTo_t *refer_to_info; /* Refer-To header */ - const char *referred_by_info; /* Referred-by header */ -} sipRefer_t; - -/* Data structures for Remote-Party-Id */ -typedef struct -{ - sipLocation_t *loc; - char *screen; - char *party_type; - char *id_type; - char *privacy; - char *np; -} sipRemotePartyId_t; - -typedef struct -{ - unsigned int num_rpid; /* Number of rpid instantiations present */ - sipRemotePartyId_t *rpid[MAX_REMOTE_PARTY_ID_HEADERS]; -} sipRemotePartyIdInfo_t; - -typedef enum -{ - SUBSCRIPTION_STATE_INVALID = 0, - SUBSCRIPTION_STATE_ACTIVE, - SUBSCRIPTION_STATE_PENDING, - SUBSCRIPTION_STATE_TERMINATED -} sip_subs_state_e; - -typedef enum -{ - SUBSCRIPTION_STATE_REASON_INVALID = 0, - SUBSCRIPTION_STATE_REASON_DEACTIVATED, - SUBSCRIPTION_STATE_REASON_PROBATION, - SUBSCRIPTION_STATE_REASON_REJECTED, - SUBSCRIPTION_STATE_REASON_TIMEOUT, - SUBSCRIPTION_STATE_REASON_GIVEUP, - SUBSCRIPTION_STATE_REASON_NORESOURCE -} sip_subs_state_reason_e; - -typedef struct -{ - sip_subs_state_e state; - uint32_t expires; - sip_subs_state_reason_e reason; - uint32_t retry_after; -} sipSubscriptionStateInfo_t; - -typedef enum { - SERVICE_CONTROL_ACTION_INVALID = 0, - SERVICE_CONTROL_ACTION_RESET, - SERVICE_CONTROL_ACTION_RESTART, - SERVICE_CONTROL_ACTION_CHECK_VERSION, - SERVICE_CONTROL_ACTION_CALL_PRESERVATION, - SERVICE_CONTROL_ACTION_APPLY_CONFIG -} sip_service_control_action_e; - -typedef struct -{ - sip_service_control_action_e action; - char *registerCallID; - char *configVersionStamp; - char *dialplanVersionStamp; - char *softkeyVersionStamp; - char *fcpVersionStamp; - char *cucm_result; - char *firmwareLoadId; - char *firmwareInactiveLoadId; - char *loadServer; - char *logServer; - boolean ppid; -} sipServiceControl_t; - -typedef struct -{ - char *call_id; - char *from_tag; - char *to_tag; -} sipJoinInfo_t; - -typedef enum { - mwiVoiceType = 1, - mwiFaxType, - mwiTextMessage -} messageCountType_t; - -typedef struct { - boolean mesg_waiting_on; - int32_t type; - int32_t newCount; - int32_t oldCount; - int32_t hpNewCount; - int32_t hpOldCount; -} sipMessageSummary_t; - -/* - * Returns a sipMethod_t value given a character method name. - * Returns sipMethodUnknown if the method is not on the list of recognized - * methods. - */ -PMH_EXTERN sipMethod_t sippmh_get_method_code(const char *); - -PMH_EXTERN genUrl_t *sippmh_parse_url(char *url, boolean dup_flag); - -/* - * See comment above. - */ -PMH_EXTERN void sippmh_genurl_free(genUrl_t *); - -PMH_EXTERN sipLocation_t *sippmh_parse_from_or_to(char *from, boolean dup_flag); - -PMH_EXTERN sipLocation_t *sippmh_parse_nameaddr_or_addrspec(char *input_loc_ptr, - char *start_ptr, - boolean dup_flag, - boolean name_addr_only_flag, - char **more_ptr); - -/* - * See comment above. - */ -PMH_EXTERN void sippmh_free_location(sipLocation_t *); - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipContact_t *sippmh_parse_contact(const char *contact); - - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipDiversion_t *sippmh_parse_diversion(const char *diversion, - char *diversionhead); - - -/* - * Same comments as free_location. - */ -PMH_EXTERN void sippmh_free_diversion(sipDiversion_t *); - -PMH_EXTERN void sippmh_free_diversion_info(sipDiversionInfo_t *div_info); - -/* - * Same comments as free_location. - */ -PMH_EXTERN void sippmh_free_contact(sipContact_t *); - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipVia_t *sippmh_parse_via(const char *via); - -/* - * Same comments as free_location. - */ -PMH_EXTERN void sippmh_free_via(sipVia_t *via); - -PMH_EXTERN void sippmh_process_via_header(sipMessage_t *sip_message, - cpr_ip_addr_t *source_ip_address); - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipCseq_t *sippmh_parse_cseq(const char *cseq); - -PMH_EXTERN boolean sippmh_parse_rseq(const char *rseq, uint32_t *rseq_val); - -PMH_EXTERN sipRack_t *sippmh_parse_rack(const char *rack); - -/* - * Does a proper comparison of From: headers.(kind of like - * a URL comparison. - * TRUE if equal, FALSE if not. - */ -PMH_EXTERN boolean sippmh_are_froms_equal(sipFrom_t *from1, sipFrom_t *from2); - -/* - * Does a proper comparison of To: headers.(kind of like - * a URL comparison. - * TRUE if equal, FALSE if not. - * At this time, sipTo is really the sipLocation struct, but - * this is kept different in case things change. - */ -PMH_EXTERN boolean sippmh_are_tos_equal(sipTo_t *to1, sipTo_t *to2); - -/* - * Does a comparison of SIP URLs. - * TRUE if equal, FALSE if not. - */ -PMH_EXTERN boolean sippmh_are_urls_equal(sipUrl_t *url1, sipUrl_t *url2); - -/* - * Utility to get the callid of a message. - * Returns NULL if the header is not found. - * Returned pointer should not be freed. - */ -//PMH_EXTERN const char *sippmh_get_callid(sipMessage_t *msg); - -/* - * Adds a Cseq: header to the message. - * msg = sipMessage_t struct - * method, seq = method, seq in the Cseq eg Cseq: 428 INVITE - * Assumes that the maximum length of the resulting header is - * less than 32 characters. - */ -PMH_EXTERN sipRet_t sippmh_add_cseq(sipMessage_t *msg, const char *method, - uint32_t seq); - -PMH_EXTERN sipRet_t sippmh_add_rack(sipMessage_t *msg, uint32_t rseq, - uint32_t cseq, const char *method); - -/* - * Utility to check whether the URL is valid. - * TRUE if yes, FALSE if not. - */ -PMH_EXTERN boolean sippmh_valid_url(genUrl_t *genUrl); - -PMH_EXTERN boolean sippmh_valid_reqline_url(genUrl_t *genUrl); - -PMH_EXTERN sipRecordRoute_t *sippmh_parse_record_route(const char *); - -PMH_EXTERN sipRecordRoute_t *sippmh_copy_record_route (sipRecordRoute_t *rr); - -PMH_EXTERN void sippmh_free_record_route(sipRecordRoute_t *); - -PMH_EXTERN cc_content_disposition_t *sippmh_parse_content_disposition(const char *input_content_disp); - -PMH_EXTERN sipReferTo_t *sippmh_parse_refer_to(char *ref_to); - -PMH_EXTERN sipReplaces_t *sippmh_parse_replaces(char *replcs, boolean dup_flag); - -PMH_EXTERN void sippmh_free_replaces(sipReplaces_t *repl); - -PMH_EXTERN void sippmh_free_refer_to(sipReferTo_t *ref); - -PMH_EXTERN void sippmh_free_refer(sipRefer_t *ref); - -PMH_EXTERN void sippmh_convertEscCharToChar(const char *inputStr, - size_t inputStrLen, - char *outputStr); - -PMH_EXTERN int sippmh_cmpURLStrings(const char *s1, const char *s2, - boolean ignore_case); - -PMH_EXTERN sip_author_t *sippmh_parse_authorization(const char *); - -PMH_EXTERN char *sippmh_generate_authorization(sip_author_t *); - -PMH_EXTERN void sippmh_free_author(sip_author_t *); - -PMH_EXTERN sip_authen_t *sippmh_parse_authenticate(const char *); - -PMH_EXTERN void sippmh_free_authen(sip_authen_t *); - -PMH_EXTERN sip_author_t *sippmh_parse_proxy_author(const char *); - -PMH_EXTERN sip_authen_t *sippmh_parse_proxy_authen(const char *); - -PMH_EXTERN sipRemotePartyId_t *sippmh_parse_remote_party_id( - const char *input_remote_party_id); - -PMH_EXTERN boolean sippmh_parse_kpml_event_id_params(char *params, - char **call_id, - char **from_tag, - char **to_tag); - -PMH_EXTERN void sippmh_free_remote_party_id_info(sipRemotePartyIdInfo_t *rpid_info); - -PMH_EXTERN char *sippmh_parse_user(char *url); - -PMH_EXTERN int sippmh_parse_subscription_state(sipSubscriptionStateInfo_t *subsStateInfo, - const char *subs_state); - -PMH_EXTERN int sippmh_add_subscription_state(sipMessage_t *msg, - sipSubscriptionStateInfo_t *subsStateInfo); - -string_t sippmh_parse_displaystr(string_t displaystr); - -#define sippmh_parse_to(x) sippmh_parse_location(x) - -#define sippmh_free_to(x) sippmh_free_location(x) - -#define sippmh_parse_from(x) sippmh_parse_location(x) - -#define sippmh_free_from(x) sippmh_free_location(x) - -PMH_EXTERN int sippmh_add_call_info(sipMessage_t *sipMessage, - cc_call_info_t *callInfo); - -PMH_EXTERN uint32_t sippmh_parse_supported_require(const char *header, - char **punsupported_options); - -PMH_EXTERN uint16_t sippmh_parse_allow_header(const char *header); - -PMH_EXTERN uint16_t sippmh_parse_accept_header(const char *header); - -PMH_EXTERN sipServiceControl_t - *sippmh_parse_service_control_body(char *msgBody, int msgLength); - -PMH_EXTERN void sippmh_free_service_control_info(sipServiceControl_t *scp); - -PMH_EXTERN sipJoinInfo_t *sippmh_parse_join_header(const char *header); - -PMH_EXTERN void sippmh_free_join_info(sipJoinInfo_t *join); - -PMH_EXTERN sipRet_t sippmh_add_join_header(sipMessage_t *message, - sipJoinInfo_t *join); - -PMH_EXTERN int32_t sippmh_parse_max_forwards(const char *max_fwd_hdr); - -PMH_EXTERN string_t sippmh_get_url_from_hdr(char *string); - -PMH_EXTERN int32_t sippmh_parse_message_summary(sipMessage_t *pSipMessage, sipMessageSummary_t *mesgSummary); - -/* - * The following SIP parser functions are the same as corresponding - * HTTP/1.1 message parser functions. - */ -#define sippmh_message_create() httpish_msg_create() - -#define sippmh_message_free( x ) httpish_msg_free( x ) - -#define sippmh_is_request( x ) httpish_msg_is_request( x , SIP_SCHEMA, SIP_SCHEMA_LEN) - -#define sippmh_is_message_complete( x ) httpish_msg_is_complete( x ) - -#define sippmh_get_request_line( x ) httpish_msg_get_reqline( x ) - -#define sippmh_get_response_line( x ) httpish_msg_get_respline( x ) - -#define sippmh_free_request_line( x ) httpish_msg_free_reqline( x ) - -#define sippmh_free_response_line( x ) httpish_msg_free_respline( x ) - -#define sippmh_process_network_message( x, y, z) \ - httpish_msg_process_network_msg( x, y, z) - -#define sippmh_get_code_class( x ) httpish_msg_get_code_class( x ) - -#define sippmh_add_request_line( x, y, a, b ) \ - httpish_msg_add_reqline( x, y, a, b ) - -#define sippmh_add_response_line( x, y , a, b) \ - httpish_msg_add_respline( x, y , a, b) - -#define sippmh_add_text_header( x, y, z ) \ - httpish_msg_add_text_header( x, y, z ) - -#define sippmh_add_int_header( x, y, z ) \ - httpish_msg_add_int_header( x, y, z ) - -#define sippmh_add_message_body( x, y, z, a, b, c, d) \ - httpish_msg_add_body(x, y, z, a, b, c, d) - -#define sippmh_remove_header( x, y ) \ - httpish_msg_remove_header( x, y ) - -#define sippmh_msg_header_present( x, y ) \ - httpish_msg_header_present(x, y) - -#define sippmh_get_header_val( x, y, c_y ) \ - httpish_msg_get_header_val( x, y, c_y ) - -#define sippmh_get_cached_header_val(x, y) \ - httpish_msg_get_cached_header_val(x, y) - -#define sippmh_get_content_length( x ) \ - httpish_msg_get_content_length( x ) - -#define sippmh_get_all_headers( x, y ) \ - httpish_msg_get_all_headers( x, y ) - -#define sippmh_write_to_buf( x, y ) \ - httpish_msg_write_to_buf( x, y ) - -#define sippmh_write( x, y, z ) \ - httpish_msg_write( x, y, z ) - -#define sippmh_write_to_string( x ) \ - httpish_msg_write_to_string( x ) - -#define sippmh_get_num_headers( x ) \ - httpish_msg_get_num_headers( x ) - -#define sippmh_get_num_particular_headers( a, b, c, d, e ) \ - httpish_msg_get_num_particular_headers( a, b, c, d, e ) - -#define sippmh_get_header_vals( a, b, c, d, e) \ - httpish_msg_get_header_vals( a, b, c, d, e) - - -#define SIPPMH_VERSIONS_EQUAL(a, b) \ - (cpr_strcasecmp(a, b) == 0) - -/* - * Utility to compare From: header values, given the values rather - * than the sipFrom_t struct. - * Returns TRUE if the same, FALSE if not. - * Expects NULL terminated strings. - */ -PMH_EXTERN boolean sippmh_compare_fromto(const char *a1, const char *a2); - -/* - * Same as compare_fromto, but for URL strings. - */ -PMH_EXTERN boolean sippmh_compare_urls(const char *u1, const char *u2); - -#define PARSE_ERR_NON_SIP_URL 1 -#define ERROR_1 SIP_F_PREFIX"Non-SIP URL\n" - -#define PARSE_ERR_NO_MEMORY 2 -#define ERROR_2 SIP_F_PREFIX"Out of memory\n" - -#define PARSE_ERR_SYNTAX 3 -#define ERROR_3 SIP_F_PREFIX"Syntax error at %s\n" -#define ERROR_3_1 SIP_F_PREFIX"Unexpected char %c\n" - -#define PARSE_ERR_UNEXPECTED_EOS 4 -#define ERROR_4 SIP_F_PREFIX"Unexpected end of string\n" - -#define PARSE_ERR_UNTERMINATED_STRING 5 -#define ERROR_5 SIP_F_PREFIX"Unmatched \"\n" - -#define PARSE_ERR_UNMATCHED_BRACKET 6 -#define ERROR_6 SIP_F_PREFIX"Unmatched <>\n" - -#define PARSE_ERR_INVALID_TTL_VAL 7 -#define ERROR_7 SIP_F_PREFIX"%d: Invalid ttl value(range 0-255)\n" - -#define PARSE_ERR_NULL_PTR 8 -#define ERROR_8 SIP_F_PREFIX"NULL Pointer\n" - -#define AT_SIGN '@' -#define SEMI_COLON ';' -#define COLON ':' -#define EQUAL_SIGN '=' -#define ESCAPE_CHAR '\\' -#define TILDA '~' -#define PERCENT '%' -#define STAR '*' -#define UNDERSCORE '_' -#define PLUS '+' -#define SINGLE_QUOTE '\'' -#define DOUBLE_QUOTE '"' -#define LEFT_ANGULAR_BRACKET '<' -#define RIGHT_ANGULAR_BRACKET '>' -#define LEFT_SQUARE_BRACKET '[' -#define RIGHT_SQUARE_BRACKET ']' -#define LEFT_PARENTHESIS '(' -#define RIGHT_PARENTHESIS ')' -#define DOLLAR_SIGN '$' -#define FORWARD_SLASH '/' -#define DOT '.' -#define DASH '-' -#define EXCLAMATION '!' -#define AMPERSAND '&' -#define COMMA ',' -#define QUESTION_MARK '?' -#define SPACE ' ' -#define TAB '\t' -#define NUMBER_SIGN '#' -#define LEFT_CURLY_BRACE '{' -#define RIGHT_CURLY_BRACE '}' -#define OR_SIGN '|' -#define CARET '^' -#define OPENING_SINGLE_QUOTE '`' - -#define PROXY 1 -#define REDIRECT 2 -#define TRANSPORT_UNSPECIFIED 0 -#define TRANSPORT_UDP 1 -#define TRANSPORT_TCP 2 -#define TRANSPORT_TLS 3 -#define TRANSPORT_SCTP 4 - -#define MAX_TTL_VAL 255 - -#define SIPPMH_FREE_REQUEST_LINE(x) sippmh_free_request_line(x); UTILFREE(x) -#define SIPPMH_FREE_RESPONSE_LINE(x) sippmh_free_response_line(x); UTILFREE(x) -#define SIPPMH_FREE_URL(x) sippmh_genurl_free(x); UTILFREE(x) -#define SIPPMH_FREE_MESSAGE(x) sippmh_free_message(x) ; UTILFREE(x) - -size_t sippmh_convertURLCharToEscChar(const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate); - -size_t sippmh_converQuotedStrToEscStr(const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate); - -ccsipRet_e ccsip_process_network_message(sipMessage_t **sipmsg_p, char **buf, - unsigned long *nbytes_used, - char **display_msg); - - -#endif /* _CCSIP_PMH_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_protocol.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_protocol.h deleted file mode 100644 index ca6033553b7..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_protocol.h +++ /dev/null @@ -1,645 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PROTOCOL_H_ -#define _CCSIP_PROTOCOL_H_ - -#include "httpish_protocol.h" - -typedef struct sip_header_ -{ - char *hname; - char *c_hname; -} sip_header_t; - - -#define SIP_VERSION "SIP/2.0" -#define SIP_SCHEMA "SIP/" -#define SIP_SCHEMA_LEN 4 /* length of the SIP_SCHEMA as defined above */ - -/* Methods */ - -#define SIP_METHOD_OPTIONS "OPTIONS" -#define SIP_METHOD_INVITE "INVITE" -#define SIP_METHOD_BYE "BYE" -#define SIP_METHOD_CANCEL "CANCEL" -#define SIP_METHOD_REGISTER "REGISTER" -#define SIP_METHOD_ACK "ACK" -#define SIP_METHOD_PRACK "PRACK" -#define SIP_METHOD_COMET "COMET" -#define SIP_METHOD_NOTIFY "NOTIFY" -#define SIP_METHOD_REFER "REFER" -#define SIP_METHOD_UPDATE "UPDATE" -#define SIP_METHOD_INFO "INFO" -#define SIP_METHOD_MESSAGE "MESSAGE" -#define SIP_METHOD_PUBLISH "PUBLISH" -#define SIP_METHOD_SUBSCRIBE "SUBSCRIBE" - - -/* Headers */ -/* - * We maintain a direct pointer to the header value for the following - * headers. - * Cached headers : Begin - */ -#define FROM 0 -#define TO 1 -#define VIA 2 -#define CALLID 3 -#define CSEQ 4 -#define CONTACT 5 -#define CONTENT_LENGTH 6 -#define CONTENT_TYPE 7 -#define RECORD_ROUTE 8 -#define REQUIRE 9 -#define ROUTE 10 -#define SUPPORTED 11 -/* Cached headers : End */ - -#define SESSION 24 -#define EXPIRES 41 -#define LOCATION 42 -#define TIMESTAMP 43 -#define MAX_FORWARDS 44 -#define UNSUPPORTED 45 -#define ACCEPT 46 -#define ACCEPT_ENCODING 47 -#define ACCEPT_LANGUAGE 48 -#define ALLOW 49 -#define USER_AGENT 50 -#define SERVER 51 -#define DATE 52 -#define CISCO_GUID 53 -#define DIVERSION 54 -#define EVENT 55 -#define SESSION 24 -#define CALL_INFO 61 -#define JOIN 62 - -/* Session Header Types - indicates the purpose of SDP bodies */ -#define SESSION_MEDIA "Media" -#define SESSION_QOS "QoS" -#define SESSION_SECURITY "Security" - -/* Content-Disposition Types */ -#define SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE 0 -#define SIP_CONTENT_DISPOSITION_RENDER_VALUE 1 -#define SIP_CONTENT_DISPOSITION_RENDER "render" -#define SIP_CONTENT_DISPOSITION_SESSION_VALUE 2 -#define SIP_CONTENT_DISPOSITION_SESSION "session" -#define SIP_CONTENT_DISPOSITION_ICON_VALUE 3 -#define SIP_CONTENT_DISPOSITION_ICON "icon" -#define SIP_CONTENT_DISPOSITION_ALERT_VALUE 4 -#define SIP_CONTENT_DISPOSITION_ALERT "alert" -#define SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE 5 -#define SIP_CONTENT_DISPOSITION_PRECONDITION "precondition" - -/* Content-Disposition Handling */ -#define DISPOSITION_HANDLING "handling" -#define DISPOSITION_HANDLING_REQUIRED "required" -#define DISPOSITION_HANDLING_OPTIONAL "optional" - -/* Some headers common to HTTP .some of the headers can be received - in compact form ( SIP_C_ .. indicates compact header form ) */ - -#define SIP_HEADER_CONTENT_LENGTH HTTPISH_HEADER_CONTENT_LENGTH -#define SIP_C_HEADER_CONTENT_LENGTH HTTPISH_C_HEADER_CONTENT_LENGTH -#define SIP_HEADER_CONTENT_TYPE HTTPISH_HEADER_CONTENT_TYPE -#define SIP_C_HEADER_CONTENT_TYPE "c" -#define SIP_HEADER_CONTENT_ENCODING HTTPISH_HEADER_CONTENT_ENCODING -#define SIP_C_HEADER_CONTENT_ENCODING "e" -#define SIP_HEADER_CONTENT_ID HTTPISH_HEADER_CONTENT_ID - -#define SIP_HEADER_USER_AGENT HTTPISH_HEADER_USER_AGENT -#define SIP_HEADER_SERVER HTTPISH_HEADER_SERVER -#define SIP_HEADER_DATE HTTPISH_HEADER_DATE - -#define SIP_HEADER_VIA HTTPISH_HEADER_VIA -#define SIP_C_HEADER_VIA "v" -#define SIP_HEADER_MAX_FORWARDS HTTPISH_HEADER_MAX_FORWARDS -#define SIP_HEADER_EXPIRES HTTPISH_HEADER_EXPIRES -#define SIP_HEADER_LOCATION HTTPISH_HEADER_LOCATION -#define SIP_C_HEADER_LOCATION "m" - -/* Headers specific to SIP .Some of the headers can be received in - compact form */ - -#define SIP_HEADER_FROM "From" -#define SIP_C_HEADER_FROM "f" -#define SIP_HEADER_TO "To" -#define SIP_C_HEADER_TO "t" -#define SIP_HEADER_CSEQ "CSeq" -#define SIP_HEADER_TIMESTAMP "Timestamp" -#define SIP_HEADER_CALLID "Call-ID" -#define SIP_C_HEADER_CALLID "i" -#define SIP_HEADER_REQUIRE "Require" -#define SIP_HEADER_SUPPORTED "Supported" -#define SIP_C_HEADER_SUPPORTED "k" -#define SIP_HEADER_UNSUPPORTED "Unsupported" -#define SIP_HEADER_CONTACT "Contact" -#define SIP_C_HEADER_CONTACT SIP_C_HEADER_LOCATION -#define SIP_HEADER_CISCO_GUID "Cisco-Guid" -#define SIP_HEADER_WARN "Warning" - -#define SIP_HEADER_ACCEPT "Accept" -#define SIP_HEADER_ACCEPT_ENCODING "Accept-Encoding" -#define SIP_HEADER_ACCEPT_LANGUAGE "Accept-Language" -#define SIP_HEADER_ALLOW "Allow" - -#define SIP_HEADER_RECORD_ROUTE "Record-Route" -#define SIP_HEADER_ROUTE "Route" -#define SIP_HEADER_SESSION "Session" -#define SIP_HEADER_ALSO "Also" -#define SIP_HEADER_REQUESTED_BY "Requested-By" -#define SIP_HEADER_DIVERSION "Diversion" -#define SIP_HEADER_CC_DIVERSION "CC-Diversion" -#define SIP_HEADER_CC_REDIRECT "CC-Redirect" -#define SIP_HEADER_ALERT_INFO "Alert-Info" - -#define SIP_HEADER_RSEQ "RSeq" -#define SIP_HEADER_RACK "RAck" -#define SIP_HEADER_CONTENT_DISP "Content-Disposition" - -/* call stats */ -#define SIP_RX_CALL_STATS "RTP-RxStat" -#define SIP_TX_CALL_STATS "RTP-TxStat" - -/* Spam Specific */ -#define SIP_HEADER_AUTHORIZATION "Authorization" -#define SIP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization" -#define SIP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate" -#define SIP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate" - -/* Refer parameters */ -#define SIP_HEADER_REFER_TO "Refer-To" -#define SIP_C_HEADER_REFER_TO "r" -#define SIP_HEADER_REFERRED_BY "Referred-By" -#define SIP_C_HEADER_REFERRED_BY "b" - -#define SIP_HEADER_REPLACES "Replaces" -#define SIP_HEADER_PROXY_AUTH "Proxy-Authorization" -#define SIP_HEADER_ACCEPT_CONTACT "Accept-Contact" -#define SIP_C_HEADER_ACCEPT_CONTACT "a" - -#define SIP_HEADER_REMOTE_PARTY_ID "Remote-Party-ID" - -#define SIP_HEADER_EVENT "Event" -#define SIP_C_HEADER_EVENT "o" - -#define SIP_HEADER_SIPIFMATCH "SIP-If-Match" -#define SIP_HEADER_SIPETAG "SIP-ETag" -#define SIP_HEADER_RETRY_AFTER "Retry-After" -#define SIP_HEADER_MIN_EXPIRES "Min-Expires" -#define SIP_HEADER_REASON "Reason" - -/* Event values */ -#define SIP_EVENT_REFER "refer" -#define SIP_EVENT_DIALOG "dialog" -#define SIP_EVENT_KPML "kpml" -#define SIP_EVENT_PRESENCE "presence" -#define SIP_EVENT_CONFIG "sip-profile" -#define SIP_EVENT_MWI "message-summary" - -/* Event param */ -#define SIP_EVENT_ID "id" - -/* Subscription states */ -#define SIP_HEADER_SUBSCRIPTION_STATE "Subscription-State" -#define SIP_SUBSCRIPTION_STATE_ACTIVE "active" -#define SIP_SUBSCRIPTION_STATE_PENDING "pending" -#define SIP_SUBSCRIPTION_STATE_TERMINATED "terminated" -/* Subscription state params */ -#define SIP_SUBSCRIPTION_STATE_EXPIRES "expires" -#define SIP_SUBSCRIPTION_STATE_REASON "reason" -#define SIP_SUBSCRIPTION_STATE_RETRY_AFTER "retry-after" -/* Subscription state reason values */ -#define SIP_SUBSCRIPTION_STATE_REASON_DEACTIVATED "deactivated" -#define SIP_SUBSCRIPTION_STATE_REASON_PROBATION "probation" -#define SIP_SUBSCRIPTION_STATE_REASON_REJECTED "rejected" -#define SIP_SUBSCRIPTION_STATE_REASON_TIMEOUT "timeout" -#define SIP_SUBSCRIPTION_STATE_REASON_GIVEUP "giveup" -#define SIP_SUBSCRIPTION_STATE_REASON_NORESOURCE "noresource" - -/* Content-Type values */ -#define SIP_CONTENT_TYPE_UNKNOWN_VALUE 0 -#define SIP_CONTENT_TYPE_UNKNOWN "application/unknown" - -#define SIP_CONTENT_TYPE_SDP_VALUE 1 -#define SIP_CONTENT_TYPE_SDP "application/sdp" - -#define SIP_CONTENT_TYPE_SIP_VALUE 2 -#define SIP_CONTENT_TYPE_SIP "application/sip" - -#define SIP_CONTENT_TYPE_SIPFRAG_VALUE 3 -#define SIP_CONTENT_TYPE_SIPFRAG "message/sipfrag" - -#define SIP_CONTENT_TYPE_DIALOG_VALUE 4 -#define SIP_CONTENT_TYPE_DIALOG "application/dialog-info+xml" - -#define SIP_CONTENT_TYPE_MWI_VALUE 5 -#define SIP_CONTENT_TYPE_MWI "application/simple-message-summary" - -#define SIP_CONTENT_TYPE_KPML_REQUEST_VALUE 6 -#define SIP_CONTENT_TYPE_KPML_REQUEST "application/kpml-request+xml" - -#define SIP_CONTENT_TYPE_KPML_RESPONSE_VALUE 7 -#define SIP_CONTENT_TYPE_KPML_RESPONSE "application/kpml-response+xml" - -#define SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE 8 -#define SIP_CONTENT_TYPE_REMOTECC_REQUEST "application/x-cisco-remotecc-request+xml" - -#define SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE 9 -#define SIP_CONTENT_TYPE_REMOTECC_RESPONSE "application/x-cisco-remotecc-response+xml" - -#define SIP_CONTENT_TYPE_CTI_VALUE 10 -#define SIP_CONTENT_TYPE_CTI "application/x-cisco-cti+xml" - -#define SIP_CONTENT_TYPE_CMXML_VALUE 11 -#define SIP_CONTENT_TYPE_CMXML "application/x-cisco-remotecc-cm+xml" - -#define SIP_CONTENT_TYPE_MULTIPART_MIXED_VALUE 12 -#define SIP_CONTENT_TYPE_MULTIPART_MIXED "multipart/mixed" - -#define SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE_VALUE 13 -#define SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE "multipart/alternative" - -#define SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE 14 -#define SIP_CONTENT_TYPE_TEXT_PLAIN "text/plain" - -#define SIP_CONTENT_TYPE_PRESENCE_VALUE 15 -#define SIP_CONTENT_TYPE_PRESENCE "application/pidf+xml" - -#define SIP_CONTENT_TYPE_CONFIGAPP_VALUE 16 -#define SIP_CONTENT_TYPE_CONFIGAPP "application/x-cisco-config+xml" - -#define SIP_CONTENT_TYPE_MEDIA_CONTROL "application/media_control+xml" - -/* Content-Type for multipart-mime */ -#define SIP_CONTENT_TYPE_MULTIPART "multipart/mixed" -#define SIP_CONTENT_BOUNDARY "boundary" -#define SIP_CONTENT_BOUNDARY_TEXT "uniqueBoundary" - -/* Content-Encoding */ -/* At this time identity is the only one recognize */ -#define SIP_CONTENT_ENCODING_IDENTITY "identity" -#define SIP_CONTENT_ENCODING_IDENTITY_VALUE 0 -#define SIP_CONTENT_ENCODING_UNKNOWN_VALUE 1 - -/* Call-info header */ -#define SIP_HEADER_CALL_INFO "Call-Info" -#define SIP_CALL_INFO_PURPOSE "Purpose" -#define SIP_CALL_INFO_PURPOSE_INFO "info" -#define SIP_CALL_INFO_PURPOSE_ICON "icon" -#define SIP_CALL_INFO_PURPOSE_CARD "card" -#define SIP_CALL_INFO_ORIENTATION "Orientation" -#define SIP_CALL_INFO_ORIENTATION_TO "To" -#define SIP_CALL_INFO_ORIENTATION_FROM "From" -#define SIP_CALL_INFO_SECURITY "Security" -#define SIP_CALL_INFO_SECURITY_UNKNOWN "Unknown" -#define SIP_CALL_INFO_SECURITY_AUTHENTICATED "Authenticated" -#define SIP_CALL_INFO_SECURITY_NOT_AUTHENTICATED "NotAuthenticated" - -/* via-params */ -#define MAX_TTL_VAL 255 -#define SIP_WELL_KNOWN_PORT 5060 -#define SIP_WELL_KNOWN_PORT_STR "5060" -#define VIA_HIDDEN "hidden" -#define VIA_TTL "ttl" -#define VIA_MADDR "maddr" -#define VIA_RECEIVED "received" -#define VIA_BRANCH "branch" -#define VIA_BRANCH_START "z9hG4bK" - -/* CC-Diversion Parameters */ -#define DIVERSION_REASON "reason" -#define DIVERSION_COUNTER "counter" -#define DIVERSION_LIMIT "limit" -#define DIVERSION_PRIVACY "privacy" -#define DIVERSION_SCREEN "screen" - -/* CC-Redirect Parameters */ -#define CC_REDIRECT_REASON "redir-reason" -#define CC_REDIRECT_COUNTER "redir-counter" -#define CC_REDIRECT_LIMIT "redir-limit" - -/* CC-Diversion Reason Parameter values */ -// REASON_UNKNOWN conflicts with winreg.h on Windows. -#ifdef REASON_UNKNOWN -#undef REASON_UNKNOWN -#endif -#define REASON_UNKNOWN "unknown" -#define REASON_USER_BUSY "user-busy" -#define REASON_NO_ANSWER "no-answer" -#define REASON_UNCONDITIONAL "unconditional" -#define REASON_DEFLECTION "deflection" -#define REASON_FOLLOW_ME "follow-me" -#define REASON_OUT_OF_SERVICE "out-of-service" -#define REASON_TIME_OF_DAY "time-of-day" -#define REASON_DO_NOT_DISTURB "do-not-disturb" -#define REASON_UNAVAILABLE "unavailable" -#define REASON_AWAY "away" - -/* Replaces parameters */ -#define SIGNATURE_SCHEME "scheme" -#define TO_TAG "to-tag" -#define FROM_TAG "from-tag" - -/* Remote-Party-Id parameters */ -#define RPID_SCREEN "screen" -#define RPID_PARTY_TYPE "party" -#define RPID_ID_TYPE "id-type" -#define RPID_PRIVACY "privacy" -#define RPID_NP "np" - -#define RPID_CALLBACK "x-cisco-callback-number=" - -#define RPID_SCREEN_LEN (sizeof(RPID_SCREEN) - 1) -#define RPID_PARTY_TYPE_LEN (sizeof(RPID_PARTY_TYPE) - 1) -#define RPID_ID_TYPE_LEN (sizeof(RPID_ID_TYPE) - 1) -#define RPID_PRIVACY_LEN (sizeof(RPID_PRIVACY) - 1) -#define RPID_NP_LEN (sizeof(RPID_NP) - 1) -#define RPID_CALLBACK_LEN (sizeof(RPID_CALLBACK) - 1) - -#define KPML_ID_CALLID "call-id" -#define KPML_ID_FROM_TAG "from-tag" -#define KPML_ID_TO_TAG "to-tag" -#define KPML_ID_CALLID_LEN (sizeof(SIP_HEADER_CALLID)-1) -#define KPML_ID_FROM_TAG_LEN (sizeof(FROM_TAG)-1) -#define KPML_ID_TO_TAG_LEN (sizeof(TO_TAG)-1) - -#define PRIVACY_OFF "off" -#define PRIVACY_NAME "name" -#define PRIVACY_URI "uri" -#define PRIVACY_FULL "full" -#define SCREEN_NO "no" -#define SCREEN_YES "yes" -#define PARTY_TYPE_CALLING "calling" -#define PARTY_TYPE_CALLED "called" - -#define SIP_HEADER_ALLOW_EVENTS "Allow-Events" -#define SIP_HEADER_MIME_VERSION "MIME-Version" -#define SIP_MIME_VERSION_VALUE "1.0" - -/* Require and Supported header params */ -#define REQ_SUPP_PARAM_REPLACES "replaces" -#define REQ_SUPP_PARAM_100REL "100rel" -#define REQ_SUPP_PARAM_EARLY_SESSION "early-session" -#define REQ_SUPP_PARAM_JOIN "join" -#define REQ_SUPP_PARAM_PATH "path" -#define REQ_SUPP_PARAM_PRECONDITION "precondition" -#define REQ_SUPP_PARAM_PREF "pref" -#define REQ_SUPP_PARAM_PRIVACY "privacy" -#define REQ_SUPP_PARAM_SEC_AGREE "sec-agree" -#define REQ_SUPP_PARAM_TIMER "timer" -#define REQ_SUPP_PARAM_NOREFERSUB "norefersub" -#define REQ_SUPP_PARAM_EXTENED_REFER "extended-refer" -#define REQ_SUPP_PARAM_CISCO_CALLINFO "X-cisco-callinfo" -#define REQ_SUPP_PARAM_CISCO_SERVICEURI "X-cisco-serviceuri" -#define REQ_SUPP_PARAM_CISCO_ESCAPECODES "X-cisco-escapecodes" -#define REQ_SUPP_PARAM_CISCO_SERVICE_CONTROL "X-cisco-service-control" -#define REQ_SUPP_PARAM_CISCO_SRTP_FALLBACK "X-cisco-srtp-fallback" -#define REQ_SUPP_PARAM_CISCO_CONFIG "X-cisco-config" -#define REQ_SUPP_PARAM_SDP_ANAT "sdp-anat" -/* Add defines for the SIP Interfcae Specification (SIS) protocol version tags*/ -#define REQ_SUPP_PARAM_CISCO_SISTAG "X-cisco-sis-" -#define SIS_CURRENT_PROTOCOL_VERSION "5.2.0" -#define SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON 1 -#define SIS_PROTOCOL_MAJOR_VERSION_MUSTER 2 -#define SIS_PROTOCOL_MAJOR_VERSION_UNISON 3 -#define SIS_PROTOCOL_MAJOR_VERSION_GUILD 4 -#define SIS_PROTOCOL_MAJOR_VERSION_ANGELFIRE 5 -#define SIS_PROTOCOL_MINOR_VERSION_ANGELFIRE 1 -#define SIS_PROTOCOL_MINOR_VERSION_MONTBLANC 1 -#define REQ_SUPP_PARAM_CISCO_SIPVER REQ_SUPP_PARAM_CISCO_SISTAG SIS_CURRENT_PROTOCOL_VERSION -#define REQ_SUPP_PARAM_CISCO_MONREC "X-cisco-monrec" -/* Add define for CME version negotiation */ -#define REQ_SUPP_PARAM_CISCO_CME_SISTAG "X-cisco-cme-sis-" - -/* Contact parameters */ -#define REQ_CONT_PARAM_CISCO_NEWREG "X-cisco-newreg" - -/* Max-forwards header */ -#define SIP_MAX_FORWARDS_DEFAULT_STR "70" -#define SIP_MAX_FORWARDS_DEFAULT_VALUE 70 - -/* Join header */ -#define SIP_HEADER_JOIN "Join" -#define SIP_HEADER_JOIN_FROM_TAG "from-tag" -#define SIP_HEADER_JOIN_TO_TAG "to-tag" - -/* Info-Package headers */ -#define SIP_HEADER_SEND_INFO "Send-Info" -#define SIP_HEADER_RECV_INFO "Recv-Info" -#define SIP_HEADER_INFO_PACKAGE "Info-Package" - -/* - * ALERT : If you are defining a compact header more than 2 bytes long, modify - * routine compact_hdr_cmp() in file httpish.c - */ - -/* - * Revised SIP drafts say that we use Contact and not Location in the header. - * But we are supporting both currently for MCI - */ - -/* S T A T U S C O D E S */ - -/* Informational Status Codes 1xx */ - -#define SIP_1XX_TRYING 100 /* "Trying" */ -#define SIP_1XX_RINGING 180 /* "Ringing" */ -#define SIP_1XX_CALL_FWD 181 /* "Call is being forwaded" */ -#define SIP_1XX_QUEUED 182 /* "Queued" */ -#define SIP_1XX_SESSION_PROGRESS 183 /* "Session Progress" */ - -/* Success Status Code 2xx */ -#define SIP_SUCCESS_SETUP 200 /* OK/Success */ -#define SIP_ACCEPTED 202 /* Accepted */ -#define SIP_STATUS_SUCCESS SIP_SUCCESS_SETUP - -/* Redirection Status Codes 3xx */ -#define SIP_RED_MULT_CHOICES 300 /* Multiple Choices */ -#define SIP_RED_MOVED_PERM 301 /* Moved Permanently */ -#define SIP_RED_MOVED_TEMP 302 /* Moved Temporarily */ -#define SIP_RED_SEE_OTHER 303 /* See Other */ -#define SIP_RED_USE_PROXY 305 /* Use Proxy */ -#define SIP_RED_ALT_SERVICE 380 /* Alternative Service */ - -/* Client Error Status Codes 4xx */ -#define SIP_CLI_ERR_BAD_REQ 400 /* Bad Request */ -#define SIP_CLI_ERR_UNAUTH 401 /* Unauthorized */ -#define SIP_CLI_ERR_PAY_REQD 402 /* Payment Required */ -#define SIP_CLI_ERR_FORBIDDEN 403 /* Forbidden */ -#define SIP_CLI_ERR_NOT_FOUND 404 /* Not Found */ -#define SIP_CLI_ERR_NOT_ALLOWED 405 /* Method Not Allowed */ -#define SIP_CLI_ERR_NOT_ACCEPT 406 /* Not Acceptable */ -#define SIP_CLI_ERR_PROXY_REQD 407 /* Proxy Authentication Required */ - -#define SIP_CLI_ERR_REQ_TIMEOUT 408 /* Request Timeout */ -#define SIP_CLI_ERR_CONFLICT 409 /* Conflict */ -#define SIP_CLI_ERR_GONE 410 /* Gone */ -#define SIP_CLI_ERR_LEN_REQD 411 /* Length Required */ -#define SIP_CLI_ERR_COND_FAIL 412 /* Conditional req failed */ -#define SIP_CLI_ERR_LARGE_MSG 413 /* Request Message Body Too Large */ -#define SIP_CLI_ERR_LARGE_URI 414 /* Request-URI Too Large */ -#define SIP_CLI_ERR_MEDIA 415 /* Unsupported Media Type */ -#define SIP_CLI_ERR_EXTENSION 420 /* Bad Extension */ -#define SIP_CLI_ERR_INTERVAL_TOO_SMALL 423 /* Duration too small */ -#define SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED 433 /* Anonymity Disallowed */ -#define SIP_CLI_ERR_NOT_AVAIL 480 /* Temporarily Not Available */ -#define SIP_CLI_ERR_CALLEG 481 /* Call Leg/Transaction Does Not Exist */ -#define SIP_CLI_ERR_LOOP_DETECT 482 /* Loop Detected */ -#define SIP_CLI_ERR_MANY_HOPS 483 /* Too Many Hops */ -#define SIP_CLI_ERR_ADDRESS 484 /* Address Incomplete */ -#define SIP_CLI_ERR_AMBIGUOUS 485 /* Ambiguous */ -#define SIP_CLI_ERR_BUSY_HERE 486 /* Busy here */ -#define SIP_CLI_ERR_REQ_CANCEL 487 /* Request Cancelled */ -#define SIP_CLI_ERR_NOT_ACCEPT_HERE 488 /* Not Acceptable Here */ -#define SIP_CLI_ERR_BAD_EVENT 489 /* Bad Event */ -#define SIP_CLI_ERR_REQ_PENDING 491 /* Request Pending */ - -/* Server Error Status Codes 5xx */ -#define SIP_SERV_ERR_INTERNAL 500 /* Internal Server Error */ -#define SIP_SERV_ERR_NOT_IMPLEM 501 /* Not Implemented */ -#define SIP_SERV_ERR_BAD_GW 502 /* Bad Gateway */ -#define SIP_SERV_ERR_UNAVAIL 503 /* Service Unavailable */ -#define SIP_SERV_ERR_GW_TIMEOUT 504 /* Gateway Timeout */ -#define SIP_SERV_ERR_SIP_VER 505 /* SIP Version not supported */ -#define SIP_SERV_ERR_PRECOND_FAILED 580 /* Precondition Failed */ - -/* Global Failure Status Codes 6xx */ -#define SIP_FAIL_BUSY 600 /* Busy */ -#define SIP_FAIL_DECLINE 603 /* Decline */ -#define SIP_FAIL_NOT_EXIST 604 /* Does not exist anywhere */ -#define SIP_FAIL_NOT_ACCEPT 606 /* Not Acceptable */ - -/* SIP Warning Codes 3xx */ -#define SIP_WARN_INCOMPAT_NETWORK_PROT 300 /* Incompatible Network Protocol */ -#define SIP_WARN_INCOMPAT_NETWORK_ADDR 301 /* Incompatible Network Address */ -#define SIP_WARN_INCOMPAT_TRANS_PROT 302 /* Incompatible Transport Protocol */ -#define SIP_WARN_INCOMPAT_BANDW_UNITS 303 /* Incompatible Bandwidth Units */ -#define SIP_WARN_MEDIA_TYPE_UNAVAIL 304 /* Media Type(s) Unavailable */ -#define SIP_WARN_INCOMPAT_MEDIA_FORMAT 305 /* Incompatible Media Formats */ -#define SIP_WARN_UNKNOWN_MEDIA_ATTRIB 306 /* Media Attribute not understood */ -#define SIP_WARN_UNKNOWN_SDP_PARAM 307 /* SDP Parameter not understood */ -#define SIP_WARN_MISC 399 /* Miscellaneous */ - -/* Other warnings */ -#define SIP_WARN_PROCESSING_PREVIOUS_REQUEST 901 - -/* R E A S O N P H R A S E S */ - -/* Informational 1xx */ - -#define SIP_1XX_TRYING_PHRASE "Trying" -#define SIP_1XX_RINGING_PHRASE "Ringing" -#define SIP_1XX_CALL_FWD_PHRASE "Call is being forwaded" -#define SIP_1XX_QUEUED_PHRASE "Queued" -#define SIP_1XX_SESSION_PROGRESS_PHRASE "Session Progress" - -/* Success 2xx */ -#define SIP_SUCCESS_SETUP_PHRASE "OK" -#define SIP_ACCEPTED_PHRASE "Accepted" - -/* Redirection 3xx */ -#define SIP_RED_MULT_CHOICES_PHRASE "Multiple Choices" -#define SIP_RED_MOVED_PERM_PHRASE "Moved Permanently" -#define SIP_RED_MOVED_TEMP_PHRASE "Moved Temporarily" -#define SIP_RED_SEE_OTHER_PHRASE "See Other" -#define SIP_RED_USE_PROXY_PHRASE "Use Proxy" -#define SIP_RED_ALT_SERVICE_PHRASE "Alternative Service" - -/* Client Error 4xx */ -#define SIP_CLI_ERR_BAD_REQ_PHRASE "Bad Request" -#define SIP_CLI_ERR_UNAUTH_PHRASE "Unauthorized" -#define SIP_CLI_ERR_PAY_REQD_PHRASE "Payment Required" -#define SIP_CLI_ERR_FORBIDDEN_PHRASE "Forbidden" -#define SIP_CLI_ERR_NOT_FOUND_PHRASE "Not Found" -#define SIP_CLI_ERR_NOT_ALLOWED_PHRASE "Method Not Allowed" -#define SIP_CLI_ERR_NOT_ACCEPT_PHRASE "Not Acceptable" -#define SIP_CLI_ERR_PROXY_REQD_PHRASE "Proxy Authentication Required" - -#define SIP_CLI_ERR_REQ_TIMEOUT_PHRASE "Request Timeout" -#define SIP_CLI_ERR_CONFLICT_PHRASE "Conflict" -#define SIP_CLI_ERR_GONE_PHRASE "Gone" -#define SIP_CLI_ERR_LEN_REQD_PHRASE "Length Required" -#define SIP_CLI_ERR_LARGE_MSG_PHRASE "Request Message Body Too Large" -#define SIP_CLI_ERR_LARGE_URI_PHRASE "Request-URI Too Large" -#define SIP_CLI_ERR_MEDIA_PHRASE "Unsupported Media Type" -#define SIP_CLI_ERR_EXTENSION_PHRASE "Bad Extension" -#define SIP_CLI_ERR_NOT_AVAIL_PHRASE "Temporarily Not Available" -#define SIP_CLI_ERR_CALLEG_PHRASE "Call Leg/Transaction Does Not Exist" -#define SIP_CLI_ERR_SUBS_DOES_NOT_EXIST_PHRASE "Subscription Does Not Exist" -#define SIP_CLI_ERR_LOOP_DETECT_PHRASE "Loop Detected" -#define SIP_CLI_ERR_MANY_HOPS_PHRASE "Too Many Hops" -#define SIP_CLI_ERR_ADDRESS_PHRASE "Address Incomplete" -#define SIP_CLI_ERR_AMBIGUOUS_PHRASE "Ambiguous" -#define SIP_CLI_ERR_BUSY_HERE_PHRASE "Busy here" -#define SIP_CLI_ERR_REQ_CANCEL_PHRASE "Request Cancelled" -#define SIP_CLI_ERR_NOT_ACCEPT_HERE_PHRASE "Not Acceptable Here" -#define SIP_CLI_ERR_BAD_EVENT_PHRASE "Bad Event" -#define SIP_CLI_ERR_INTERVAL_TOO_SMALL_PHRASE "Interval too small" -#define SIP_CLI_ERR_INTERVAL_TOO_LARGE_PHRASE "Interval too large" -#define SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE "Anonymity Disallowed" -#define SIP_CLI_ERR_REQ_PENDING_PHRASE "Request Pending" - -/* Server Error 5xx */ -#define SIP_SERV_ERR_INTERNAL_PHRASE "Internal Server Error" -#define SIP_SERV_ERR_NOT_IMPLEM_PHRASE "Not Implemented" -#define SIP_SERV_ERR_BAD_GW_PHRASE "Bad Gateway" -#define SIP_SERV_ERR_UNAVAIL_PHRASE "Service Unavailable" -#define SIP_SERV_ERR_GW_TIMEOUT_PHRASE "Gateway Timeout" -#define SIP_SERV_ERR_SIP_VER_PHRASE "SIP Version not supported" -#define SIP_SERV_ERR_PRECOND_FAILED_PHRASE "Precondition Failed" - -/* Global Failure 6xx */ -#define SIP_FAIL_BUSY_PHRASE "Busy" -#define SIP_FAIL_DECLINE_PHRASE "Decline" -#define SIP_FAIL_NOT_EXIST_PHRASE "Does not exist anywhere" -#define SIP_FAIL_NOT_ACCEPT_PHRASE "Not Acceptable" - -/* SIP Warning Codes 3xx Phrases */ -#define SIP_WARN_INCOMPAT_NETWORK_PROT_PHRASE "\"Incompatible Network Protocol\"" -#define SIP_WARN_INCOMPAT_NETWORK_ADDR_PHRASE "\"Incompatible Network Address\"" -#define SIP_WARN_INCOMPAT_TRANS_PROT_PHRASE "\"Incompatible Transport Protocol\"" -#define SIP_WARN_INCOMPAT_BANDW_UNITS_PHRASE "\"Incompatible Bandwidth Units\"" -#define SIP_WARN_MEDIA_TYPE_UNAVAIL_PHRASE "\"Media Type(s) Unavailable\"" -#define SIP_WARN_INCOMPAT_MEDIA_FORMAT_PHRASE "\"Incompatible Media Formats\"" -#define SIP_WARN_UNKNOWN_MEDIA_ATTRIB_PHRASE "\"Media Attribute not understood\"" -#define SIP_WARN_UNKNOWN_SDP_PARAM_PHRASE "\"SDP Parameter not understood\"" -#define SIP_WARN_REFER_AMBIGUOUS_PHRASE "\"Ambiguous.Multiple Contacts Found.\"" - -#define SIP_STATUS_PHRASE_NONE "Unknown" - -/* Client Error 400 Bad Request detailed explaination */ -#define SIP_CLI_ERR_BAD_REQ_MEDIA_COMP_FAILED "Bad Request - 'Media info comparison failed'" -#define SIP_CLI_ERR_BAD_REQ_SDP_ERROR "Bad Request - 'Invalid SDP information'" -#define SIP_CLI_ERR_BAD_REQ_RECORD_ROUTE "Bad Request - 'Malformed/Missing Record Route'" -#define SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD "Bad Request - 'Malformed/Missing Contact field'" -#define SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT "Bad Request - 'Callid absent'" -#define SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD "Bad Request - 'Error in Cseq field'" -#define SIP_CLI_ERR_BAD_REQ_FROM_OR_TO_FIELD "Bad Request - 'Error in From and/or To field'" -#define SIP_CLI_ERR_BAD_REQ_MEDIA_NEGOTIATION "Bad Request - 'Media Negotiation Failed'" -#define SIP_CLI_ERR_BAD_REQ_URL_ERROR "Bad Request - 'Malformed/Missing URL'" -#define SIP_CLI_ERR_BAD_REQ_ToURL_ERROR "Bad Request - 'Malformed/Missing TO: field'" -#define SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR "Bad Request - 'Malformed/Missing FROM: field'" -#define SIP_CLI_ERR_BAD_REQ_CALLID_ERROR "Bad Request - 'Malformed/Missing CALLID field'" -#define SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR "Bad Request - 'Malformed/Missing REQUEST LINE'" -#define SIP_CLI_ERR_BAD_REQ_IPADDRESS_ERROR "Bad Request - 'Invalid IP Address'" -#define SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR "Bad Request - 'Content length Error'" -#define SIP_CLI_ERR_BAD_REQ_CONTENT_TYPE_ERROR "Bad Request - 'Malformed/Missing SIP CONTENT TYPE field'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_DIVERSION "Bad Request - 'Malformed CC-Diversion Header'" -#define SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ "Bad Request - 'Malformed/Missing VIA OR CSEQ'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REFER "Bad Request - 'Malformed REFER Request'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO "Bad Request - 'Malformed Refer-To Header'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_BY "Bad Request - 'Missing Refer-By Header'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REPLACES "Bad Request - 'Malformed Replaces Header'" -#define SIP_CLI_ERR_BAD_REQ_METHOD_UNKNOWN "Bad Request - 'Unable to obtain SIP method'" -#define SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING "Bad Request - 'Unable to decode body'" -#define SIP_CLI_ERR_BAD_REQ_SUBSCRIPTION_DELETED "Bad Request - 'Subscription Terminated'" -#define SIP_CLI_ERR_BAD_REQ_NO_BODY "Bad Request - 'Body Expected'" -#define SIP_CLI_ERR_BAD_REQ_NO_SUBSCRIPTION_HEADER "Bad Request - 'Malformed/Missing Subscription-State Header'" -#define SIP_CLI_ERR_BAD_REQ_CONTENT_ID_ERROR "Bad Request - 'Invalid Content-Id field'" -#define SIP_CLI_ERR_BAD_REQ_REQUIRE_HDR "Bad Request - 'Malformed/Missing Require header'" -#endif /*_CCSIP_PROTOCOL_H_*/ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_publish.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_publish.h deleted file mode 100644 index 3e823e1e8cb..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_publish.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PUBLISH_H_ -#define _CCSIP_PUBLISH_H_ - -#include "publish_int.h" -#include "ccsip_common_cb.h" -#include "ccsip_subsmanager.h" - -/* the following is to take advantage of SUB/NOT periodic timer */ -#define TMR_PERIODIC_PUBLISH_INTERVAL TMR_PERIODIC_SUBNOT_INTERVAL - -#define PUBLISH_FAILED_START (1000) -#define PUBLISH_FAILED_NOCONTEXT (PUBLISH_FAILED_START + 1) -#define PUBLISH_FAILED_NORESOURCE (PUBLISH_FAILED_START + 2) -#define PUBLISH_FAILED_SEND (PUBLISH_FAILED_START + 3) -#define PUBLISH_FAILED_RESET (PUBLISH_FAILED_START + 4) - -typedef struct { - ccsip_common_cb_t hb; /* this MUST be the first member */ - - cc_srcs_t callback_task; // CallBack Task ID - int resp_msg_id; //Response Msg ID - char *entity_tag; - pub_handle_t pub_handle; - pub_handle_t app_handle; - char ruri[MAX_URI_LENGTH]; // Address of the resource - char full_ruri[MAX_SIP_URL_LENGTH]; - char esc[MAX_URI_LENGTH]; // Event State Compositor - boolean outstanding_trxn; - sipPlatformUITimer_t retry_timer; - sll_handle_t pending_reqs; //holds pending requests -} ccsip_publish_cb_t; //PUBLISH Control Block data structure - -extern int publish_handle_ev_app_publish(cprBuffer_t buf); -extern int publish_handle_retry_timer_expire(uint32_t handle); -extern void publish_handle_periodic_timer_expire(void); -extern int publish_handle_ev_sip_response(sipMessage_t *pSipMessage); -extern void publish_reset(void); -extern cc_int32_t show_publish_stats(cc_int32_t argc, const char *argv[]); - -#endif // _CCSIP_PUBLISH_H_ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_register.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_register.h deleted file mode 100644 index 4148bdb314e..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_register.h +++ /dev/null @@ -1,157 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_REGISTER_H_ -#define _CCSIP_REGISTER_H_ - -#include "cpr_types.h" -#include "cpr_timers.h" -#include "phone.h" -#include "ccsip_core.h" -#include "ccsip_credentials.h" -#include "platform_api.h" - -#define MAX_REG_EXPIRES 3600 -#include "ccsip_subsmanager.h" -#include "platform_api.h" - -#define MAX_RETRIES_401 3 - -#define AUTH_HDR(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - (SIP_HEADER_WWW_AUTHENTICATE) : (SIP_HEADER_PROXY_AUTHENTICATE)) - -#define AUTH_HDR_STR(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - ("WWW-Authenticate") : ("Proxy-Authenticate")) - -#define AUTH_BUGINF(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - ("SIP 401 Unauthorized") : ("SIP 407 Proxy Authentication required")) - -#define AUTH_NOTIFY(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - (" 401 <---") : (" 407 <---")) - -#define AUTHOR_HDR(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - (SIP_HEADER_AUTHORIZATION) : (SIP_HEADER_PROXY_AUTHORIZATION)) - - -/* - These numbers need to match up - with whats defined on the J-Side - The Master copy should be here because - the reason needs to be sent out in the register - message -*/ -#define UNREG_REASON_UNSPECIFIED 0 -//Common with what SCCP uses...need to match with J-Side -//Important! should be defined in plat_api.h for thirdparty application to use. -#define UNREG_REASON_TCP_TIMEOUT CC_UNREG_REASON_TCP_TIMEOUT // 10 -#define UNREG_REASON_CM_RESET_TCP CC_UNREG_REASON_CM_RESET_TCP //12 -#define UNREG_REASON_CM_ABORTED_TCP CC_UNREG_REASON_CM_ABORTED_TCP //13 -#define UNREG_REASON_CM_CLOSED_TCP CC_UNREG_REASON_CM_CLOSED_TCP //14 -#define UNREG_REASON_REG_TIMEOUT CC_UNREG_REASON_REG_TIMEOUT //17 -#define UNREG_REASON_FALLBACK CC_UNREG_REASON_FALLBACK //18 -#define UNREG_REASON_PHONE_KEYPAD CC_UNREG_REASON_PHONE_KEYPAD //20 -#define UNREG_REASON_RESET_RESET CC_UNREG_REASON_RESET_RESET //22 -#define UNREG_REASON_RESET_RESTART CC_UNREG_REASON_RESET_RESTART //23 -#define UNREG_REASON_PHONE_REG_REJ CC_UNREG_REASON_PHONE_REG_REJ //24 -#define UNREG_REASON_PHONE_INITIALIZED CC_UNREG_REASON_PHONE_INITIALIZED //25 -#define UNREG_REASON_VOICE_VLAN_CHANGED CC_UNREG_REASON_VOICE_VLAN_CHANGED //26 - -//sip specific ones...need to match with J-Side -#define UNREG_REASON_VERSION_STAMP_MISMATCH CC_UNREG_REASON_VERSION_STAMP_MISMATCH //100 -#define UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG CC_UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG //101 -#define UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY CC_UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY //102 -#define UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN CC_UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN //103 -#define UNREG_REASON_APPLY_CONFIG_RESTART CC_UNREG_REASON_APPLY_CONFIG_RESTART //104 -#define UNREG_REASON_CONFIG_RETRY_RESTART CC_UNREG_REASON_CONFIG_RETRY_RESTART //105 -#define UNREG_REASON_TLS_ERROR CC_UNREG_REASON_TLS_ERROR //106 -#define UNREG_REASON_RESET_TO_INACTIVE_PARTITION CC_UNREG_REASON_RESET_TO_INACTIVE_PARTITION //107 -#define UNREG_REASON_VPN_CONNECTIVITY_LOST CC_UNREG_REASON_VPN_CONNECTIVITY_LOST //108 - - -#define PRIMARY_LINE (1) - -typedef enum { - SIP_REG_ERROR, - SIP_REG_OK -} sip_reg_return_code; - -typedef enum -{ - SIP_REG_INVALID=-1, - SIP_REG_IDLE, - SIP_REG_REGISTERING, - SIP_REG_REGISTERED, - SIP_REG_UNREGISTERING, - SIP_REG_PRE_FALLBACK, - SIP_REG_IN_FAILOVER, - SIP_REG_POST_FAILOVER, - SIP_REG_STANDBY_FAILOVER, - SIP_REG_NO_CC, - SIP_REG_NO_STANDBY, - SIP_REG_NO_REGISTER -} ccsip_register_states_t; - -typedef enum -{ - E_SIP_REG_NONE = 0, - SIPSPI_REG_EV_BASE = 1, - - E_SIP_REG_REG_REQ = SIPSPI_REG_EV_BASE, - E_SIP_REG_CANCEL, - E_SIP_REG_1xx, - E_SIP_REG_2xx, - E_SIP_REG_3xx, - E_SIP_REG_4xx, - E_SIP_REG_FAILURE_RESPONSE, - E_SIP_REG_TMR_ACK, - E_SIP_REG_TMR_EXPIRE, - E_SIP_REG_TMR_WAIT, - E_SIP_REG_TMR_RETRY, - E_SIP_REG_CLEANUP, - SIPSPI_REG_EV_END = E_SIP_REG_CLEANUP -} sipRegSMEventType_t; - - -typedef struct -{ - int line; - boolean cancel; -} ccsip_register_msg_t; - - -int sip_reg_sm_process_event(sipSMEvent_t *pEvent); -sipRegSMEventType_t ccsip_register_sip2sipreg_event(int sip_event); -int ccsip_register_init(void); -void ccsip_register_timeout_retry(void *data); -void ccsip_register_all_lines(void); -void ccsip_register_cancel(boolean cancel_reg, boolean backup_proxy); -void ccsip_ccm_register_cancel(boolean cancel_reg); -void ccsip_register_set_state(ccsip_register_states_t state); -ccsip_register_states_t ccsip_register_get_state(void); -ccsip_register_states_t ccsip_register_get_register_state(void); -void ccsip_register_reset_proxy(void); -void cred_get_line_credentials(line_t line, credentials_t *pcredentials, - int id_len, int pw_len); -boolean cred_get_user_credentials(line_t line, credentials_t *pcredentials); -boolean cred_get_credentials_r(ccsipCCB_t *ccb, credentials_t *pcredentials); -void ccsip_register_commit(void); -void ccsip_backup_register_commit(void); -void ccsip_register_cleanup(ccsipCCB_t *ccb, boolean start); -void ccsip_register_set_register_state(ccsip_register_states_t state); -int ccsip_register_send_msg(uint32_t cmd, line_t line); -void ccsip_handle_ev_default(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_reg_sm_change_state(ccsipCCB_t *ccb, sipRegSMStateType_t new_state); -boolean ccsip_register_all_unregistered(); -void sip_stop_ack_timer(ccsipCCB_t *ccb); -void ccsip_register_shutdown(void); -boolean ccsip_get_ccm_date(char *date_value); -boolean ccsip_is_line_registered(line_t line); -boolean process_retry_after(ccsipCCB_t *ccb, sipMessage_t *response); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_reldev.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_reldev.h deleted file mode 100644 index cf6a76431e8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_reldev.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_RELDEV_H_ -#define _CCSIP_RELDEV_H_ - -#include "cpr_types.h" -#include "ccsip_pmh.h" -#include "ccsip_core.h" - -#define RELDEV_MAX_USER_NAME_LEN 64 -#define RELDEV_MAX_HOST_NAME_LEN 64 -#define RELDEV_NO_STORED_MSG (-1) - -typedef struct -{ - char message_buf[SIP_UDP_MESSAGE_SIZE]; - uint32_t message_buf_len; - cpr_ip_addr_t dest_ipaddr; - uint16_t dest_port; -} sipRelDevCoupledMessage_t; - -typedef struct -{ - boolean is_request; - char call_id[MAX_SIP_CALL_ID]; - uint32_t cseq_number; - sipMethod_t cseq_method; - char tag[MAX_SIP_TAG_LENGTH]; - char from_user[RELDEV_MAX_USER_NAME_LEN]; - char from_host[RELDEV_MAX_HOST_NAME_LEN]; - char to_user[RELDEV_MAX_USER_NAME_LEN]; - int response_code; - sipRelDevCoupledMessage_t coupled_message; - boolean valid_coupled_message; - //int line; -} sipRelDevMessageRecord_t; - -void sipRelDevMessageStore(sipRelDevMessageRecord_t *pMessageRecord); -boolean sipRelDevMessageIsDuplicate(sipRelDevMessageRecord_t *pMessageRecord, - int *index); -int sipRelDevCoupledMessageStore(sipMessage_t *pCoupledMessage, - const char *call_id, - uint32_t cseq_number, - sipMethod_t cseq_method, - boolean is_request, - int status_code, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - boolean ignore_tag); -int sipRelDevCoupledMessageSend(int index); -void sipRelDevMessagesClear(const char *call_id, - const char *from_user, - const char *from_host, - const char *to_user); -void sipRelDevAllMessagesClear(); -uint32_t sipRelDevGetStoredCoupledMessage(int index, - char *dest_buffer, - uint32_t max_buff); - - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sdp.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sdp.h deleted file mode 100644 index fe4e2fbd9f4..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sdp.h +++ /dev/null @@ -1,159 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_SDP_H_ -#define _CCSIP_SDP_H_ - - -#include "cpr_types.h" -#include "pmhutils.h" -#include "sdp.h" -#include "ccapi.h" -#include "mozilla-config.h" - -/* SDP bitmask values */ -#define CCSIP_SRC_SDP_BIT 0x1 -#define CCSIP_DEST_SDP_BIT 0x2 - -/* - * Create a description or a SIP SDP (sip_info) with - * appropriate values initialized - */ -PMH_EXTERN sdp_t *sipsdp_create(const char *peerconnection); -PMH_EXTERN cc_sdp_t *sipsdp_info_create(void); -PMH_EXTERN void sipsdp_src_dest_free(uint16_t flags, cc_sdp_t **sdp_info); -PMH_EXTERN void sipsdp_src_dest_create(const char *peerconnection, - uint16_t flags, cc_sdp_t **sdp_info); -PMH_EXTERN void sipsdp_free(cc_sdp_t **sip_sdp); - -/* - * Stream related sdp utility functions - */ -//PMH_EXTERN sip_sdp_stream_t *sipsdp_stream_create(void); -//PMH_EXTERN void sipsdp_add_stream_to_list(sip_sdp_stream_t *stream, -// sip_sdp_t *sip_sdp); -//PMH_EXTERN void sipsdp_remove_stream_from_list(sip_sdp_stream_t **stream); -//PMH_EXTERN void sipsdp_remove_streams_list(sip_sdp_stream_t **stream_list); - -#define SIPSDP_MAX_SESSION_VERSION_LENGTH 32 - -/* - * Standard session-level parameters - */ -#define SIPSDP_VERSION 0 -// RAMC_DEBUG #define SIPSDP_ORIGIN_USERNAME "CiscoSystemsSIP-GW-UserAgent" -#define SIPSDP_ORIGIN_APPNAME "Mozilla-SIPUA-" -#define SIPSDP_ORIGIN_USERNAME SIPSDP_ORIGIN_APPNAME MOZ_APP_UA_VERSION -#define SIPSDP_SESSION_NAME "SIP Call" - -/* Possible encoding names fo static payload types*/ -#define SIPSDP_ATTR_ENCNAME_PCMU "PCMU" -#define SIPSDP_ATTR_ENCNAME_PCMA "PCMA" -#define SIPSDP_ATTR_ENCNAME_G729 "G729" -#define SIPSDP_ATTR_ENCNAME_G723 "G723" -#define SIPSDP_ATTR_ENCNAME_G726 "G726-32" -#define SIPSDP_ATTR_ENCNAME_G728 "G728" -#define SIPSDP_ATTR_ENCNAME_GSM "GSM" -#define SIPSDP_ATTR_ENCNAME_CN "CN" -#define SIPSDP_ATTR_ENCNAME_G722 "G722" -#define SIPSDP_ATTR_ENCNAME_ILBC "iLBC" -#define SIPSDP_ATTR_ENCNAME_H263v2 "H263-1998" -#define SIPSDP_ATTR_ENCNAME_H264 "H264" -#define SIPSDP_ATTR_ENCNAME_VP8 "VP8" -#define SIPSDP_ATTR_ENCNAME_L16_256K "L16" -#define SIPSDP_ATTR_ENCNAME_ISAC "ISAC" -#define SIPSDP_ATTR_ENCNAME_OPUS "opus" - -/* Possible encoding names for DTMF tones dynamic payload types */ -#define SIPSDP_ATTR_ENCNAME_TEL_EVENT "telephone-event" -#define SIPSDP_ATTR_ENCNAME_FRF_DIGIT "frf-dialed-digit" - -/* Possible encoding names for other dynamic payload types */ -#define SIPSDP_ATTR_ENCNAME_CLEAR_CH "X-CCD" -#define SIPSDP_ATTR_ENCNAME_G726R16 "G726-16" -#define SIPSDP_ATTR_ENCNAME_G726R24 "G726-24" -#define SIPSDP_ATTR_ENCNAME_GSMEFR "GSM-EFR" - -/* RTPMAP encoding names added from MGCP for compatibility with MGCP - * These could be coming in from Cisco MGCP gateway's SDP via a - * softswitch and SIP GW must interoperate. - */ - -#define SIPSDP_ATTR_ENCNAME_G729_A_STR_DOTTED "G.729a" -#define SIPSDP_ATTR_ENCNAME_G729_B_STR_DOTTED "G.729b" -#define SIPSDP_ATTR_ENCNAME_G729_B_LOW_COMPLEXITY_STR_DOTTED "G.729b-L" -#define SIPSDP_ATTR_ENCNAME_G729_A_B_STR_DOTTED "G.729ab" - -#define SIPSDP_ATTR_ENCNAME_G7231_HIGH_RATE_STR_DOTTED "G.723.1-H" -#define SIPSDP_ATTR_ENCNAME_G7231_A_HIGH_RATE_STR_DOTTED "G.723.1a-H" -#define SIPSDP_ATTR_ENCNAME_G7231_LOW_RATE_STR_DOTTED "G.723.1-L" -#define SIPSDP_ATTR_ENCNAME_G7231_A_LOW_RATE_STR_DOTTED "G.723.1a-L" - -/* - * NSE/XNSE encoding names - */ -#define SIPSDP_ATTR_ENCNAME_XNSE "X-NSE" -#define SIPSDP_ATTR_ENCNAME_NSE "NSE" - - -/* Possible clock rates */ -#define RTPMAP_CLOCKRATE 8000 -#define RTPMAP_VIDEO_CLOCKRATE 90000 -#define RTPMAP_L16_CLOCKRATE 16000 -#define RTPMAP_ISAC_CLOCKRATE 16000 -#define RTPMAP_OPUS_CLOCKRATE 48000 -#define FMTP_MAX_AVERAGE_BIT_RATE 40000 -#define ATTR_PTIME 20 -#define ATTR_MAXPTIME 120 -#define WEBRTC_DATA_CHANNEL_PROT "webrtc-datachannel" - -#define SIPSDP_CONTENT_TYPE "application/sdp" - -#define MAX_RTP_PAYLOAD_TYPES 7 - -#define BITRATE_5300_BPS 5300 -#define BITRATE_6300_BPS 6300 - -/* - * T.38 attribute parameters - */ -#define SIPSDP_ATTR_T38_VERSION_DEF 0 -#define SIPSDP_ATTR_T38_FILL_BIT_REMOVAL_DEF FALSE -#define SIPSDP_ATTR_T38_TRANSCODING_MMR_DEF FALSE -#define SIPSDP_ATTR_T38_TRANSCODING_JBIG_DEF FALSE -/* the following two definitions are from VSIToH245BuildFastStartT38OLC() */ -#define SIPSDP_ATTR_T38_MAX_BUFFER_DEF 200 -#define SIPSDP_ATTR_T38_MAX_DATAGRAM_DEF 72 - -/* - * Supported NTE range. Note that if the supported NTEs ever becomes a - * non-contiguous set of values, then it will have to be stored as an - * sdp. See the definition of negotiated_nte_sdp for an example. Further, - * where Sdp_ne_cmp_range() is invoked, Sdp_ne_cmp_list() will have to be - * used instead. - */ -#define SIPSDP_NTE_SUPPORTED_LOW 0 /* Min value of DTMF event table */ -#define SIPSDP_FRF_SUPPORTED_HIGH 15 /* for dtmf-relay cisco-rtp */ -#define SIPSDP_NTE_SUPPORTED_HIGH 16 /* for dtmf-relay rtp-nse */ - -/* - * Create the "on-wire" version, i.e. ready to put into a SIP message. - * Memory is allocated and should be freed by the user when done - * Returns NULL on failure. - */ -PMH_EXTERN char *sipsdp_write_to_buf(sdp_t *, uint32_t *); - -#define SIPSDP_FREE(x) \ -if (x) \ -{ \ - sdp_free_description(x); \ -} - -#define SIPSDP_MAX_PAYLOAD_TYPES 15 -#define MAX_RTP_MEDIA_TYPES 6 -#define SIPSDP_NTE_DTMF_MIN 0 /* Min value of DTMF event table */ -#define SIPSDP_NTE_DTMF_MAX 15 /* Max DTMF event value supported here */ - - -#endif /*_CCSIP_SDP_H_*/ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sim.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sim.h deleted file mode 100644 index 89cff0a3d90..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sim.h +++ /dev/null @@ -1,14 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_SIM_H_ -#define _CCSIP_SIM_H_ - - -void SIPTaskTestUdpSend(void); -void SIPTaskSimulateInviteRecv(void); -void SIPTaskSimulateOffhook(void); -void SIPTaskSimulateAckRecv(void); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_spi_utils.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_spi_utils.h deleted file mode 100755 index 95aeb512162..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_spi_utils.h +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_UTILS_H_ -#define _CCSIP_UTILS_H_ - -#include "cpr_types.h" -#include "ccsip_pmh.h" - -boolean -sipSPI_validate_hostname(char *); - -boolean -sipSPI_validate_ip_addr_name(char *); - -extern int -sipSPICheckDomainToken(char *token); - -boolean -sipSPI_validate_hostname (char *str); -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_subsmanager.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_subsmanager.h deleted file mode 100644 index fe66ac9e554..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_subsmanager.h +++ /dev/null @@ -1,433 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_SUBSMANAGER_H_ -#define _CCSIP_SUBSMANAGER_H_ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_timers.h" -#include "cpr_socket.h" -#include "ccsip_core.h" -#include "phone_platform_constants.h" -#include "singly_link_list.h" -#include "ccsip_common_cb.h" - -/* - * States - */ -typedef enum { - SUBS_STATE_IDLE = 0, // Initial state of the SCB - SUBS_STATE_REGISTERED, - - /* out going subscribe SCB states */ - SUBS_STATE_SENT_SUBSCRIBE, // Sent SUBSCRIBE - SUBS_STATE_RCVD_NOTIFY, // Received NOTIFY - SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY, // Sent SUBSCRIBE & Received NOTIFY - - /* incoming subscribe SCB states */ - SUBS_STATE_RCVD_SUBSCRIBE, // Received SUBSCRIBE - SUBS_STATE_SENT_NOTIFY, // Sent NOTIFY - SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY, // Received SUBSCRIBE & Sent NOTIFY - - /* - * No outstanding outgoing/incoming messages to handle. - * This state is after all outstanding SUBSCRIBE/NOTIFY - * transactions are complete. - */ - SUBS_STATE_ACTIVE, - - SUBS_STATE_INVALID -} subsStateType_t; - -typedef enum { - SUBSCRIPTION_NULL = 0, - SUBSCRIPTION_TERMINATE -} subscriptionState; - -/* - * Subscription ID data type - */ -typedef uint32_t sub_id_t; - -#define MAX_EVENT_NAME_LEN 32 -#define CCSIP_SUBS_START_CSEQ 1000 - -/* There may be multiple subscription pending on given call - * the subcription for KPML, remote-cc, offhook notification etc. - */ -#define MAX_SCBS ((MAX_TEL_LINES * 2) < 32 ? 32 : (MAX_TEL_LINES * 2)) -#define LIMIT_SCBS_USAGE (MAX_SCBS - ((MAX_SCBS * 20) / 100)) -#define TMR_PERIODIC_SUBNOT_INTERVAL 5 -#define CCSIP_SUBS_INVALID_SUB_ID (sub_id_t)(-1) -#define MAX_SCB_HISTORY 10 - -typedef enum { - SM_REASON_CODE_NORMAL = 0, - SM_REASON_CODE_ERROR, - SM_REASON_CODE_SHUTDOWN, - SM_REASON_CODE_ROLLOVER, - SM_REASON_CODE_RESET_REG -} ccsip_reason_code_e; - - -// Application defined callback functions - -// Data to app to indicate response to a sent SUBSCRIBE -typedef struct { - int status_code; - long expires; -} ccsip_subs_result_data_t; - -// Data to app to indicate a received SUBSCRIBE -typedef struct { - ccsip_event_data_t *eventData; - int expires; - int line; - string_t from; - string_t to; -} ccsip_subs_ind_data_t; - -// Data to app to indicate a received NOTIFY -typedef struct { - ccsip_event_data_t *eventData; - sip_subs_state_e subscription_state; // From the subs-state header - sip_subs_state_reason_e subscription_state_reason; - uint32_t expires; - uint32_t retry_after; - uint32_t cseq; - char entity[CC_MAX_DIALSTRING_LEN]; // used to store From user for incoming unsolicited NOTIFY. -} ccsip_notify_ind_data_t; - -// Data to app to indicate response to a sent NOTIFY -typedef struct { - int status_code; -} ccsip_notify_result_data_t; - -// Data to app to indicate incoming subscription terminated -typedef struct { - int status_code; -} ccsip_subs_terminate_data_t; - -// Containing structure for all stack->app messages -typedef struct ccsip_sub_not_data_t { - int msg_id; - sub_id_t sub_id; - int sub_duration; - cc_subscriptions_t event; - line_t line_id; - callid_t gsm_id; - boolean norefersub; - long request_id; - ccsip_reason_code_e reason_code; - union { - ccsip_subs_ind_data_t subs_ind_data; - ccsip_subs_result_data_t subs_result_data; - ccsip_notify_ind_data_t notify_ind_data; - ccsip_notify_result_data_t notify_result_data; - ccsip_subs_terminate_data_t subs_term_data; - } u; -} ccsip_sub_not_data_t; - - -// Function to pass an incoming subscribe request -typedef void (*ccsipSubsIndCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass response to a subscribe request -typedef void (*ccsipSubsResultCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass an incoming Notify request -typedef void (*ccsipNotifyIndCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass results of notify request -typedef void (*ccsipNotifyResultCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass general errors -typedef void (*ccsipSubsTerminateCallbackFn_t)(ccsip_sub_not_data_t *msg_data); -typedef void (*ccsipGenericCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - - - -// Return status code -#define SUBSCRIPTION_IN_PROGRESS 1010 -#define SUBSCRIPTION_SUCCEEDED 1020 -#define SUBSCRIPTION_REJECTED 1030 -#define SUBSCRIPTION_FAILED 1040 -#define NOTIFY_REQUEST_FAILED 1050 -#define SUBSCRIBE_REQUEST_FAILED 1060 -#define SUBSCRIBE_FAILED_NORESOURCE 1061 -#define SUBSCRIBE_FAILED_BADEVENT 1062 -#define SUBSCRIBE_FAILED_BADINFO 1062 -#define NETWORK_SUBSCRIPTION_EXPIRED 1070 -#define APPLICATION_SUBSCRIPTION_EXPIRED 1080 -#define REQUEST_TIMEOUT 1090 - -// Data passed by app to register for incoming SUBSCRIBE -typedef struct sipspi_subscribe_reg_t_ { - cc_subscriptions_t eventPackage; // Registering for which event - ccsipSubsIndCallbackFn_t subsIndCallback; // Callback function - cc_srcs_t subsIndCallbackTask; // Callback task - int subsIndCallbackMsgID; // msg_id to use in callback - ccsipSubsTerminateCallbackFn_t subsTermCallback; // Callback function when remote side terminates subs - int subsTermCallbackMsgID; // Terminate msg-id - long min_duration; // Min duration for which SUB should be accepted - long max_duration; // Max duration for which SUB should be accepted -} sipspi_subscribe_reg_t; - -// Data passed by app to initiate a SUBSCRIBE -typedef struct sipspi_subscribe_t_ { - sub_id_t sub_id; // ID for reSubscribe - cc_subscriptions_t eventPackage; // Event package to send subscribe for - cc_subscriptions_t acceptPackage; // Accept header - long duration; // subscription duration (0=unsubscribe) - char subscribe_uri[CC_MAX_DIALSTRING_LEN]; - char subscriber_uri[CC_MAX_DIALSTRING_LEN]; // From field - long request_id; // Returned to subscriber in response - - ccsipSubsResultCallbackFn_t subsResultCallback; - ccsipNotifyIndCallbackFn_t notifyIndCallback; - ccsipSubsTerminateCallbackFn_t subsTermCallback; - - cc_srcs_t subsNotCallbackTask; - int subsResCallbackMsgID; - int subsNotIndCallbackMsgID; - int subsTermCallbackMsgID; - - cpr_ip_addr_t dest_sip_addr; // Destination address - uint16_t dest_sip_port; // Destination port - - callid_t call_id; - line_t dn_line; // Associated line, if any - - boolean auto_resubscribe; // stack reSubscribes at expiry - boolean norefersub; - ccsip_event_data_t *eventData; // Determined by the eventPackage value - -} sipspi_subscribe_t; - -// Data by app to respond to a received SUBSCRIBE -typedef struct sipspi_subscribe_resp_t_ { - sub_id_t sub_id; // Subscription id - uint16_t response_code; // Response that should be sent - int duration; // Max duration for the subscribe -} sipspi_subscribe_resp_t; - -// Data by app to initiate a NOTIFY -typedef struct sipspi_notify_t_ { - sub_id_t sub_id; // Subscription id - // Info for different notify bodies - ccsipNotifyResultCallbackFn_t notifyResultCallback; - int subsNotResCallbackMsgID; - ccsip_event_data_t *eventData; // Determined by the eventPackage value - cc_subscriptions_t eventPackage; // Event package - subscriptionState subState; - cc_srcs_t subsNotCallbackTask; // Opt.: If not already specified -} sipspi_notify_t; - -// Data by app to respond to a received NOTIFY -typedef struct sipspi_notify_resp_t_ { - sub_id_t sub_id; - int response_code; - int duration; - uint32_t cseq; -} sipspi_notify_resp_t; - -// Data by app to terminate an existing subscription -typedef struct sipspi_subscribe_term_t_ { - sub_id_t sub_id; - long request_id; - cc_subscriptions_t eventPackage; // Event package - boolean immediate; -} sipspi_subscribe_term_t; - -/* -typedef struct sipspi_remotecc_reg_t_{ -} sipspi_remotecc_reg_t; - -typedef struct sipspi_remotecc_refer_t_{ -} sipspi_remotecc_refer_t; - -typedef struct sipspi_remotecc_refer_resp_t_{ -} sipspi_remotecc_refer_resp_t; - -typedef struct sipspi_remotecc_notify_t_{ -} sipspi_remotecc_notify_t; - -typedef struct sipspi_remotecc_notify_resp_t_{ -} sipspi_remotecc_notify_resp_t; - -typedef struct sipspi_remotecc_term_t_{ -} sipspi_remotecc_term_t; -*/ - -typedef struct sipspi_msg_t_ { - union { - sipspi_subscribe_reg_t subs_reg; - sipspi_subscribe_t subscribe; - sipspi_subscribe_resp_t subscribe_resp; - sipspi_notify_t notify; - sipspi_notify_resp_t notify_resp; - sipspi_subscribe_term_t subs_term; - /* - * sipspi_remotecc_reg_t remotecc_reg; - * sipspi_remotecc_refer_t remotecc_refer; - * sipspi_remotecc_refer_resp_t remotecc_refer_resp; - * sipspi_remotecc_notify_t remotecc_notify; - * sipspi_remotecc_notify_resp_t remotecc_notify_resp; - * sipspi_remotecc_term_t remotecc_term; - */ - } msg; -} sipspi_msg_t; - -// List of app->stack messages -typedef struct sipspi_msg_list_t_ { - uint32_t cmd; - sipspi_msg_t *msg; - struct sipspi_msg_list_t_ *next; -} sipspi_msg_list_t; - -// Subscription Control Block -typedef struct { - ccsip_common_cb_t hb; /* this MUST be the first memeber in the struct */ - - line_t line; - // Subscription ID - sub_id_t sub_id; - - // SCB State - boolean pendingClean; - unsigned char pendingCount; - - // Subscriber details - boolean internal; // Internal or external - - // Callback and messaging details - ccsipSubsIndCallbackFn_t subsIndCallback; - cc_srcs_t subsIndCallbackTask; - cc_srcs_t subsNotCallbackTask; - int subsIndCallbackMsgID; - ccsipSubsResultCallbackFn_t subsResultCallback; - int subsResCallbackMsgID; - ccsipNotifyIndCallbackFn_t notifyIndCallback; - int notIndCallbackMsgID; - ccsipSubsTerminateCallbackFn_t subsTermCallback; - int subsTermCallbackMsgID; - ccsipNotifyResultCallbackFn_t notifyResultCallback; - int notResCallbackMsgID; - - short sip_socket_handle; - boolean useDeviceAddressing; - callid_t gsm_id; - long request_id; - - // Subscription details - subsStateType_t smState; - subsStateType_t outstandingIncomingNotifyTrxns; // only used for incoming NOTIFYs - unsigned long min_expires; - unsigned long max_expires; - ccsipCCB_t *ccbp; /* associated CCB, if any */ - char event_name[MAX_EVENT_NAME_LEN]; - boolean auto_resubscribe; /* Resubscribe automatically */ - boolean norefersub; - - // Messaging details - uint32_t last_sent_request_cseq; - sipMethod_t last_sent_request_cseq_method; - uint32_t last_recv_request_cseq; - sipMethod_t last_recv_request_cseq_method; - - // Saved headers - char SubURI[MAX_SIP_URL_LENGTH]; - char SubURIOriginal[MAX_SIP_URL_LENGTH]; - char SubscriberURI[MAX_SIP_URL_LENGTH]; - string_t sip_from; - string_t sip_to; - string_t sip_to_tag; - string_t sip_from_tag; - string_t sip_contact; - string_t cached_record_route; - sipContact_t *contact_info; - sipRecordRoute_t *record_route_info; - sll_handle_t incoming_trxns; // to store via (branch attribute) to track transactions. - string_t callingNumber; - - // Subscription headers - sip_subs_state_e subscription_state; - sip_subs_state_reason_e subscription_state_reason; - uint32_t retry_after; - - - // Linked list of pending app messages - sipspi_msg_list_t *pendingRequests; -} sipSCB_t; - -// Transaction Control Block -typedef struct { - ccsip_common_cb_t hb; /* this MUST be the first memeber in the struct */ - char full_ruri[MAX_SIP_URL_LENGTH]; - cprTimer_t timer; /* transaction timer */ - uint32_t trxn_id; -} sipTCB_t; - -// Structure to keep track of recent subscriptions -typedef struct { - char last_call_id[MAX_SIP_CALL_ID]; - char last_from_tag[MAX_SIP_TAG_LENGTH]; - cc_subscriptions_t eventPackage; -} sipSubsHistory_t; - -#define MAX_SUB_EVENTS 5 -#define MAX_SUB_EVENT_NAME_LEN 16 -extern const char eventNames[MAX_SUB_EVENTS][MAX_SUB_EVENT_NAME_LEN]; - -/* - * Externally called function headers - */ -// For initializing and shutting down -int sip_subsManager_init(); -int sip_subsManager_shut(); - -// Function to handle subscription requests from applications -int subsmanager_handle_ev_cc_feature_subscribe(sipSMEvent_t *); -int subsmanager_handle_ev_cc_feature_notify(sipSMEvent_t *); - -int subsmanager_handle_ev_app_subscribe_register(cprBuffer_t buf); -int subsmanager_handle_ev_app_subscribe(cprBuffer_t buf); -int subsmanager_handle_ev_app_subscribe_response(cprBuffer_t buf); -int subsmanager_handle_ev_app_notify(cprBuffer_t buf); -void subsmanager_handle_ev_app_unsolicited_notify(cprBuffer_t buf, line_t line); -int subsmanager_handle_ev_app_notify_response(cprBuffer_t buf); -int subsmanager_handle_ev_app_subscription_terminated(cprBuffer_t buf); -int subsmanager_handle_retry_timer_expire(int scb_index); -void subsmanager_handle_periodic_timer_expire(void); -int subsmanager_test_start_routine(); - -// Functions to handle remotecc requests from applications -// int subsmanager_handle_ev_app_remotecc_register(); -// int subsmanager_handle_ev_app_remotecc_refer(); -// int subsmanager_handle_ev_app_remotecc_refer_response(); -// int subsmanager_handle_ev_app_remotecc_notify(); -// int subsmanager_handle_ev_app_remotecc_notify_response(); -// int subsmanager_handle_ev_app_remotecc_terminated(); - -// Functions to handle requests from network -int subsmanager_handle_ev_sip_subscribe(sipMessage_t *pSipMessage, - sipMethod_t sipMethod, - boolean in_dialog); -int subsmanager_handle_ev_sip_subscribe_notify(sipMessage_t *pSipMessage); - -// Function to handle response from network -int subsmanager_handle_ev_sip_response(sipMessage_t *pSipMessage); - -void free_event_data(ccsip_event_data_t *event_data); -int sip_subsManager_rollover(void); -int sip_subsManager_reset_reg(void); -void submanager_update_ccb_addr(ccsipCCB_t *ccb); -boolean add_content(ccsip_event_data_t *eventData, sipMessage_t *request, const char *fname); -void pres_unsolicited_notify_ind(ccsip_sub_not_data_t * msg_data); -sipTCB_t *find_tcb_by_sip_callid(const char *callID_p); -int subsmanager_handle_ev_sip_unsolicited_notify_response(sipMessage_t *pSipMessage, sipTCB_t *tcbp); -void subsmanager_unsolicited_notify_timeout(void *data); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_task.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_task.h deleted file mode 100644 index 801168e1684..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_task.h +++ /dev/null @@ -1,89 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_TASK_H_ -#define _CCSIP_TASK_H_ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_socket.h" -#include "cpr_memory.h" - -/* - * List of timers that the SIP task is responsible for. - * CPR will send a msg to the SIP task when these - * timers expire. CPR expects a timer id when the timer - * is created, this enum serves that purpose. - */ -typedef enum { - SIP_ACK_TIMER, - SIP_WAIT_TIMER, - SIP_RETRY_TIMER, - SIP_MSG_TIMER, - SIP_EXPIRES_TIMER, - SIP_REG_TIMEOUT_TIMER, - SIP_REG_EXPIRES_TIMER, - SIP_LOCAL_EXPIRES_TIMER, - SIP_SUPERVISION_TIMER, - SIP_GLARE_AVOIDANCE_TIMER, - SIP_KEEPALIVE_TIMER, - SIP_SUBNOT_TIMER, - SIP_SUBNOT_PERIODIC_TIMER, - SIP_PUBLISH_RETRY_TIMER, - SIP_UNSOLICITED_TRANSACTION_TIMER, - SIP_DIAL_TIMEOUT_TIMER, - SIP_FAIL_OVER_START_TIMER, - SIP_FAIL_OVER_COMPLETE_TIMER, - SIP_FALL_BACK_START_TIMER, - SIP_FALL_BACK_COMPLETE_TIMER, - SIP_UNREGISTRATION_TIMER, - SIP_REGALLFAIL_TIMER, - SIP_NOTIFY_TIMER, - SIP_PASSTHROUGH_TIMER -} sipTimerList_t; - - -/* Action Values for SIPTaskPostShutdown function */ -#define SIP_INTERNAL 0 -#define SIP_EXTERNAL 1 -#define SIP_STOP 2 - -#define MAX_SIP_REASON_LENGTH 64 -#define UNREG_NO_REASON 0 -#define VERSION_STAMP_MISMATCH 1 -/* - * The code creating the SIP timers needs to have - * access to the sip_msgq variable since CPR - * needs to know where to send the timer expiration - * message. - */ -extern cprMsgQueue_t sip_msgq; - -typedef struct -{ - boolean taskInited; // FALSE - cprMsgQueue_t msgQueue; -} sipGlobal_t; - -/* - * External Data - */ -extern sipGlobal_t sip; -extern char sipHeaderServer[]; -extern char sipHeaderUserAgent[]; -extern char sipUnregisterReason[]; - -/* - * Prototypes - */ -void SIPTaskInit(void); -void SIPTaskProcessListEvent(uint32_t cmd, void *msg, void *pUsr, uint16_t len); -int SIPTaskProcessUDPMessage(cprBuffer_t msg, uint16_t len, cpr_sockaddr_storage from); -int SIPTaskProcessConfigChangeNotify(int32_t notify_type); -cpr_status_e SIPTaskSendMsg(uint32_t cmd, cprBuffer_t msg, uint16_t len, void *usr); -cprBuffer_t SIPTaskGetBuffer(uint16_t size); -void SIPTaskReinitialize(boolean checkConfig); -void SIPTaskPostShutdown(int, int reason, const char *reasonInfo); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish.h deleted file mode 100644 index 23c8e875a21..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish.h +++ /dev/null @@ -1,302 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _HTTPISH_H_ -#define _HTTPISH_H_ - -#include "cpr_types.h" -#include "pmhdefs.h" -#include "httpish_protocol.h" -#include "pmhutils.h" -#include "util_ios_queue.h" - -#define HTTPISH_MIN_STATUS_CODE 100 -#define HTTPISH_HEADER_CACHE_SIZE 12 -#define HTTPISH_HEADER_NAME_SIZE 256 - -typedef struct h_header -{ - struct h_header *next; - char *header; -} httpish_header; - -typedef struct { - char *hdr_start; - char *val_start; -} httpish_cache_t; - -#define HTTPISH_MAX_BODY_PARTS 6 -typedef struct { - uint8_t msgContentDisp; - boolean msgRequiredHandling; - uint8_t msgContentTypeValue; - char *msgContentType; - char *msgBody; - uint32_t msgLength; - char *msgContentId; - uint8_t msgContentEnc; -} msgBody_t; - -typedef struct _httpMsg -{ - struct _httpMsg *next; - boolean retain_flag; /* If TRUE, Do not free the msg */ - char *mesg_line; - queuetype *headers; - msgBody_t mesg_body[HTTPISH_MAX_BODY_PARTS]; - char *raw_body; - int32_t content_length; - uint8_t num_body_parts; - boolean is_complete; - boolean headers_read; - /* Cache the most commonly used headers */ - httpish_cache_t hdr_cache[HTTPISH_HEADER_CACHE_SIZE]; - /* this is the complete message received/sent at the socket */ - char *complete_message; -} httpishMsg_t; - -typedef struct -{ - char *method; - char *url; - char *version; -} httpishReqLine_t; - - -typedef struct -{ - char *reason_phrase; - uint16_t status_code; - char *version; -} httpishRespLine_t; - -typedef enum -{ - STATUS_SUCCESS = 0, - STATUS_FAILURE, - STATUS_UNKNOWN, - HSTATUS_SUCCESS = STATUS_SUCCESS, - HSTATUS_FAILURE = STATUS_FAILURE, - HSTATUS_UNKNOWN = STATUS_UNKNOWN -} hStatus_t; - -typedef enum -{ - codeClassInvalid = 0, - codeClass1xx = 1, - codeClass2xx = 2, - codeClass3xx = 3, - codeClass4xx = 4, - codeClass5xx = 5, - codeClass6xx = 6 -} httpishStatusCodeClass_t; - - -/* Creates a message and initializes its internal members */ -PMH_EXTERN httpishMsg_t *httpish_msg_create(void); - -/* Frees internal members of the message, such as headers */ -PMH_EXTERN void httpish_msg_free(httpishMsg_t *); - -/* - * Returns TRUE if the message is a HTTPish Request, FALSE if not. - * Return value will be wrong if the function is called before the - * message is complete(see message_is_complete) - */ -PMH_EXTERN boolean httpish_msg_is_request(httpishMsg_t *, const char *, int); - -/* - * A message may be complete or incomplete at a point in time, since - * one message may be formed of multiple network packets. This function - * returns TRUE if the message is in fact complete, FALSE if not - */ -PMH_EXTERN boolean httpish_msg_is_complete(httpishMsg_t *); - -/* - * Gets a request line structure out of the message i.e parses the message - * line. Null on failure, incomplete message etc. User should call - * httpish_msg_free_reqline when done to free the allocated memory - * inside the structure. - */ -PMH_EXTERN httpishReqLine_t *httpish_msg_get_reqline(httpishMsg_t *); - -/* Frees internal members of the request line structure */ -PMH_EXTERN void httpish_msg_free_reqline(httpishReqLine_t *); - -/* - * Gets a response line structure out of the message i.e parses the message - * line. Null on failure, incomplete message etc. User should call - * httpish_msg_free_respline when done to free the allocated memory - * inside the structure. - */ -PMH_EXTERN httpishRespLine_t *httpish_msg_get_respline(httpishMsg_t *); - -/* Frees internal members of the response line structure */ -PMH_EXTERN void httpish_msg_free_respline(httpishRespLine_t *); - -/* - * Adds a message line to the message given a request line elements. - * This makes it a Request message - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free() - */ -PMH_EXTERN hStatus_t httpish_msg_add_reqline(httpishMsg_t *, - const char *method, - const char *url, - const char *version); - -/* - * Adds a message line to the message given response line elements. - * This makes it a Response message - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free(). Status codes are assumed to be a - * maximum of 6 characters long ie <= 999999 - */ -PMH_EXTERN hStatus_t httpish_msg_add_respline(httpishMsg_t *, - const char *version, - uint16_t status_code, - const char *reason_phrase); - -/* - * Adds a header with a text value to message. - * hname = name of the header for eg. "Content-Type" - * hval = value of the header for eg. "application/sdp" - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free() - */ -PMH_EXTERN hStatus_t httpish_msg_add_text_header(httpishMsg_t *msg, - const char *hname, - const char *hval); - -/* - * Adds a header with a integer value to message. - * hname = name of the header for eg. "Content-Length" - * hval = value of the header for eg. 234 - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free() - */ -/* Assumes the int is less than 10 characters*/ -PMH_EXTERN hStatus_t httpish_msg_add_int_header(httpishMsg_t *msg, - const char *hname, - int32_t hvalue); - -/* - * Removes a header from the message. - * hname = name of the header. eg. hname = "From" - * Memory for that header string is freed. - */ -PMH_EXTERN hStatus_t httpish_msg_remove_header(httpishMsg_t *msg, - const char *hname); - - -/* - * Returns the value of the header if found, NULL if not. - * hname = name of the header, eg. "Content-Length" - * The pointer should not be freed by the user. (It will be - * freed on freeing the message) - */ -PMH_EXTERN const char *httpish_msg_get_header_val(httpishMsg_t *, - const char *hname, - const char *c_hname); - -PMH_EXTERN hStatus_t httpish_msg_get_header_vals(httpishMsg_t *, - const char *hname, - const char *c_hname, - uint16_t *nheaders, - char **header_vals); - -PMH_EXTERN const char *httpish_msg_get_cached_header_val(httpishMsg_t *, int); - - -/* - * Gets an array of pointers to all the headers. The number of - * headers is returned in num_headers. - * If invoked such : - * all_the_headers = httpish_msg_get_all_headers(...), - * memory is allocated only for "all_the_headers" array, not for - * its individual elements. Hence only the pointer to the all_the_headers - * array should be freed. - */ -PMH_EXTERN char **httpish_msg_get_all_headers(httpishMsg_t *msg, uint32_t *num_headers); - -PMH_EXTERN uint32_t httpish_msg_get_num_headers(httpishMsg_t *msg); - - -PMH_EXTERN uint16_t httpish_msg_get_num_particular_headers(httpishMsg_t *msg, - const char *hname, - const char *c_hname, - char *header_val[], - uint16_t max_headers); - -/* - * Utility function to get value of the Content-Length header. Returns -1 - * if the header is not present. - */ -PMH_EXTERN int32_t httpish_msg_get_content_length(httpishMsg_t *); - - -/* - * Adds the content body to the message. Results in the addition of the - * Content-Length header as well. - */ -PMH_EXTERN hStatus_t httpish_msg_add_body(httpishMsg_t *msg, - char *body, - uint32_t nbytes, - const char *content_type, - uint8_t msg_disposition, - boolean required, - char *content_id); - -PMH_EXTERN boolean httpish_msg_header_present(httpishMsg_t *, - const char *hname); - - - -/* - * Allocates a buffer and writes the message into it in the network - * format i.e ready to send. On return, nbytes is filled in with - * the number of bytes contained in the message buffer. Returns - * NULL on failure. User needs to free memory when done. - */ -PMH_EXTERN char *httpish_msg_write_to_buf(httpishMsg_t * msg, uint32_t *nbytes); - -/* Writes it out as a null terminated string. Expected use is debug */ -PMH_EXTERN char *httpish_msg_write_to_string(httpishMsg_t * msg); - -/* - * Writes out a message in the network format(ie ready to send), - * in a user provided buffer. nbytes is filled in with the number - * of bytes in buf on entry and filled in with the - * actual number of bytes written if the return value is SUCCESS. - * There is no attempt to grow or realloc the buffer ie FAILURE - * is returned if the buffer is not large enough. - */ -PMH_EXTERN hStatus_t httpish_msg_write(httpishMsg_t *msg, - char *buf, - uint32_t *nbytes); - -/* - * This function is used to read bytes from a network packet into the - * message structure. - * msg = previously created httpishMsg using httpish_msg_create() - * nmsg = network message - * bytes_read = Number of bytes read from nmsg is filled in when the - * function returns. - * It is expected that after this returns HSTATUS_SUCCESS, - * httpish_is_message_complete() is called to see whether a complete - * message was received(or a previously started message was completed, - * at which point it can be processed further. - */ -PMH_EXTERN hStatus_t httpish_msg_process_network_msg(httpishMsg_t *msg, - char *nmsg, - uint32_t *bytes_read); - -/* - * Utility to get the class of status codes in http like responses. - * For eg., the class for a code 480 is 4, as currently defined. - */ -PMH_EXTERN httpishStatusCodeClass_t httpish_msg_get_code_class(uint16_t statusCode); - - -#endif /* _HTTPISH_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish_protocol.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish_protocol.h deleted file mode 100644 index 3a1751d0e59..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish_protocol.h +++ /dev/null @@ -1,32 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _HTTPISH_PROTOCOL_H_ -#define _HTTPISH_PROTOCOL_H_ - -/* - * Some common headers only. There does not seem a whole lot of - * sense in defining error codes since they tend to have different - * semantics - */ - -#define HTTPISH_HEADER_CONTENT_LENGTH "Content-Length" -#define HTTPISH_C_HEADER_CONTENT_LENGTH "l" -#define HTTPISH_HEADER_CONTENT_TYPE "Content-Type" -#define HTTPISH_HEADER_CONTENT_ENCODING "Content-Encoding" -#define HTTPISH_HEADER_CONTENT_ID "Content-Id" - -#define HTTPISH_HEADER_USER_AGENT "User-Agent" -#define HTTPISH_HEADER_SERVER "Server" -#define HTTPISH_HEADER_DATE "Date" - -#define HTTPISH_HEADER_VIA "Via" -#define HTTPISH_HEADER_MAX_FORWARDS "Max-Forwards" -#define HTTPISH_HEADER_EXPIRES "Expires" -#define HTTPISH_HEADER_LOCATION "Location" - -#define HTTPISH_HEADER_MIME_VERSION "Mime-Version" -#define uniqueBoundary "uniqueBoundary" - -#endif /* _HTTPISH_PROTOCOL_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhdefs.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhdefs.h deleted file mode 100644 index 5e1338be967..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhdefs.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PMH_DEFS_H_ -#define _PMH_DEFS_H_ - -#define UTILFREE(x) cpr_free(x) - -#define PMH_EXTERN extern - -#endif /* _PMH_DEFS_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhutils.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhutils.h deleted file mode 100644 index 0ffe1487c6c..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhutils.h +++ /dev/null @@ -1,163 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PMH_UTILS_H_ -#define _PMH_UTILS_H_ - -#include "cpr_types.h" -#include "pmhdefs.h" - -/* - * Define a "stream" created from an input packet. We have to do this - * since SIP * messages may come in over TCP or UDP, so we cannot use - * TCP stream semantics. It is expected that a client interfaces to - * these streams via the API functions defined below, rather than - * directly. - */ -typedef struct -{ - char *buff; - char *loc; /* This points to the next byte that will be read */ - int32_t nbytes; - int32_t bytes_read; - boolean eof; - boolean error; -} pmhRstream_t; - - -/* - * Defines a write stream to write things to and finally create an - * "output packet". It is expected that a client interfaces to - * these streams via the API functions defined below, rather than - * directly. - */ -typedef struct -{ - char *buff; - int32_t nbytes; - int32_t total_bytes; - boolean growable; -} pmhWstream_t; - -typedef struct -{ - uint16_t num_tokens; - char **tokens; -} pmhTokens_t; - -/* - * Buf is the input buffer holding data that you want to use a "stream". - * The stream uses buf as is, so dont free it. Free it only when done - * ie. by calling pmhutils_rstream_delete. Returns NULL on failure. - * buf = Input buffer containing data. - * nbytes = Number of bytes in buf. - */ -PMH_EXTERN pmhRstream_t *pmhutils_rstream_create(char *buf, uint32_t nbytes); - - -/* - * Frees internal memory. If freebuf is TRUE, it frees the - * buffer it was created with. If not TRUE, the internal buffer - * should be held by the user and freed when appropriate. - */ -PMH_EXTERN void pmhutils_rstream_delete(pmhRstream_t *rs, boolean freebuf); - - -/* - * Returns a character from the stream, and advances internal pointer. - * If no characters are left, returns '\0' and sets the eof to TRUE. - */ -PMH_EXTERN char pmhutils_rstream_read_byte(pmhRstream_t *); - - -/* - * Returns a character buffer from the stream, - * and advances internal pointer. - * If no characters are left, returns NULL and sets the eof to TRUE. - * This routine allocates memory which should be freed by the user. - * nbytes = Number of bytes asked for. - */ -PMH_EXTERN char *pmhutils_rstream_read_bytes(pmhRstream_t *rs, int32_t nbytes); - -/* - * Returns a string created from a line(as terminated by \r or \n or \r\n) - * in the stream. This will actually allocate memory for the string, - * which should be freed by the user when done. Empty lines are returned - * as empty strings - ie. first char is \0. - * Updates internal pointer in the stream. - * Returns NULL if eof has been reached on the stream - */ -PMH_EXTERN char *pmhutils_rstream_read_line(pmhRstream_t *); - -/* Creates a write stream with an internal buffer of default size */ -PMH_EXTERN pmhWstream_t *pmhutils_wstream_create(void); - -/* Creates a write stream with a user provided buffer */ -PMH_EXTERN pmhWstream_t *pmhutils_wstream_create_with_buf(char *buf, - uint32_t nbytes); - -/* - * Grows the write streams internal buffer by a default step. - * Mostly used internally by the write functions - */ -PMH_EXTERN boolean pmhutils_wstream_grow(pmhWstream_t *); - -/* - * Frees the internal elements of the write stream, - * including its internal buffer if freebuf is TRUE. If freebuf - * is FALSE, the buffer should be held by the user and freed - * when appropriate. - */ -PMH_EXTERN void pmhutils_wstream_delete(pmhWstream_t *ws, boolean freebuf); - - -/* - * Writes the input string, followed by a SIP New line - * ie. \r\n - * Returns FALSE on failure. - * Expects a NULL terminated string in "line". - * Returns FALSE on failure(ie no memory etc.) - * May result in creation of memory, which will - * be freed when pmhutils_wstream_free_internal is called. - */ -PMH_EXTERN boolean pmhutils_wstream_write_line(pmhWstream_t *ws, char *line); - -/* - * Writes a single character to the output stream. - * Returns FALSE on failure, TRUE on success. - */ -PMH_EXTERN boolean pmhutils_wstream_write_byte(pmhWstream_t *, char); - -/* - * Writes a buffer(of length len pointed to by buf) to - * the stream. May result in creation of memory, which will - * be freed when pmhutils_wstream_free_internal is called. - * Returns FALSE on failure(ie no memory etc.) - */ -PMH_EXTERN boolean pmhutils_wstream_write_bytes(pmhWstream_t *ws, char *buf, - uint32_t len); - -/* - * Returns the internal buffer, and fills in its length in nbytes. - * This would be used just before wstream_delete(.., FALSE) in order - * to hold the buffer. - */ -PMH_EXTERN char *pmhutils_wstream_getbuf(pmhWstream_t *, uint32_t *nbytes); - -PMH_EXTERN uint32_t pmhutils_wstream_get_length(pmhWstream_t *ws); - -/* - * A tokenizer like strtok, but creates memory for every token. - * Use only when you have to create the memory anyway. - * Returns NULL if no tokens are found or incase memory allocation - * fails. - */ -PMH_EXTERN pmhTokens_t *pmh_tokenize(const char *str, const char *tokens); - -/* - * Util to free all the tokens - */ -PMH_EXTERN void pmh_tokens_free(pmhTokens_t *tokens); - -#endif /*_PMH_UTILS_H_*/ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/regmgrapi.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/regmgrapi.h deleted file mode 100755 index b4a7e51f555..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/regmgrapi.h +++ /dev/null @@ -1,17 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _REGMGRAPI_H_ -#define _REGMGRAPI_H_ - -#include "sessionConstants.h" - -typedef enum reg_mode_t_ { - REG_MODE_CCM = CC_MODE_CCM, - REG_MODE_NON_CCM = CC_MODE_NONCCM, -} reg_mode_t; - -reg_mode_t sip_regmgr_get_cc_mode(line_t line); - -#endif /* _REGMGRAPI_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_ccm_transport.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_ccm_transport.h deleted file mode 100644 index e200cdcd8be..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_ccm_transport.h +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_CCM_TRANSPORT_H__ -#define __SIP_CCM_TRANSPORT_H__ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "phone_types.h" - -#define CCM_ID_PRINT(arg) \ - (arg == PRIMARY_CCM ? "PRIMARY_CCM" : \ - arg == SECONDARY_CCM ? "SECONDARY_CCM" : \ - arg == TERTIARY_CCM ? "TERTIARY_CCM" : \ - arg == MAX_CCM ? "MAX_CCM" : \ - arg == UNUSED_PARAM ? "UNUSED_PARAM" : "Unknown")\ - - -#endif /* __SIP_CCM_TRANSPORT_H__ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_regmgr.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_regmgr.h deleted file mode 100644 index cb88fe7bfd8..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_regmgr.h +++ /dev/null @@ -1,157 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_COMMON_REGMGR_H__ -#define __SIP_COMMON_REGMGR_H__ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_timers.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "ccsip_core.h" -#include "singly_link_list.h" -#include "ccsip_platform.h" -#include "sip_common_transport.h" - -#define LINE1 0 -#define LINE2 1 -#define LINE3 2 -#define LINE4 3 -#define LINE5 4 -#define LINE6 5 -#define LINE7 6 -#define LINE8 7 -#define LINE9 8 -#define LINE10 9 -#define LINE11 10 -#define LINE12 11 -#define LINE13 12 -#define LINE14 13 -#define LINE15 14 -#define LINE16 15 -#define LINE17 16 -#define LINE18 17 -#define LINE19 18 -#define LINE20 19 - -#define RSP_START 1 -#define RSP_COMPLETE 2 -#define FAILOVER_RSP 0 -#define MAX_FALLBACK_MONITOR_PERIOD 300 -#define TLS_CONNECT_TIME 8 - -#define TOKEN_REFER_TO "" - -typedef enum { - ACTIVE_FD = 0, - STANDBY_FD, - MAX_FALLBACK_FDs -} CC_FDs; - -typedef enum { - RET_SUCCESS = 0, - RET_NO_STANDBY, - RET_START_FALLBACK, - RET_INIT_REBOOT -} RET_CODE; - -typedef struct fallback_ccb_t_ { - ccsipCCB_t *ccb; - sipPlatformUIExpiresTimer_t WaitTimer; - sipPlatformUIExpiresTimer_t RetryTimer; - uint32_t StabilityMsgCount; - boolean tls_socket_waiting; -} fallback_ccb_t; - -typedef struct ccm_fd_table_t_ { - ti_config_table_t *active_ccm_entry; - ti_config_table_t *standby_ccm_entry; -} ccm_act_stdby_table_t; - -//ccm_act_stdby_table_t CCM_Active_Standby_Table[MAX_TEL_LINES+1]; - -typedef struct ccm_failover_table_t_ { - ti_config_table_t *failover_ccm_entry; - ti_config_table_t *fallback_ccm_entry; - boolean prime_registered; - boolean failover_started; -} ccm_failover_table_t; - -typedef struct ccm_fallback_table_t_ { - ti_config_table_t *fallback_ccm_entry; - boolean is_idle; - boolean is_resp; - ccsipCCB_t *ccb; -} ccm_fallback_table_t; - -typedef struct { - uint32_t ccb_index; /* ccb index for which this msg is intended for */ - CCM_ID ccm_id; /* cucm id */ -} ccsip_registration_msg_t; - -void notify_register_update(int availableLine); -fallback_ccb_t *sip_regmgr_get_fallback_ccb_by_index(line_t index); -int sip_regmgr_destroy_cc_conns(void); -int sip_regmgr_init(void); -void sip_regmgr_register_lines(boolean prime_only, boolean skip_prime); -void sipRegmgrSendRegisterMsg(uint8_t line, ccsipCCB_t *ccb); -void sip_regmgr_ev_cancel(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_in_fallback_any_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_failure_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_tmr_ack_retry(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_tmr_expire_standby(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void sip_regmgr_ev_unreg_tmr_ack(ccsipCCB_t *cb); -void sip_regmgr_trigger_fallback_monitor(void); -void sip_regmgr_setup_new_standby_ccb(CCM_ID ccm_id); -void sip_regmgr_free_fallback_ccb(ccsipCCB_t *ccb); -void sip_regmgr_retry_timeout_expire(void *data); -void sip_regmgr_stability_timeout_expire(void *data); -void sip_regmgr_find_fallback_ccb_by_callid(const char *callid, - ccsipCCB_t **ccb_ret); -boolean sip_regmgr_find_fallback_ccb_by_addr_port(cpr_ip_addr_t *ipaddr, - uint16_t port, - ccsipCCB_t **ccb_ret); -sll_match_e sip_regmgr_fallback_ccb_find(void *find_by_p, void *data_p); -void sip_regmgr_retry_timer_start(fallback_ccb_t *fallback_ccb); -ti_config_table_t *sip_regmgr_ccm_get_conn(line_t dn, - ti_config_table_t *ccm_entry); -void sip_regmgr_check_and_transition(ccsipCCB_t *ccb); -void sip_regmgr_ev_default(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_fallback_retry(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_wait_timeout_expire(void *data); -void sip_regmgr_ev_in_fallback_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_stability_check_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_stability_check_tmr_stable(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void sip_regmgr_ev_stability_check_tmr_wait(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void sip_regmgr_ev_token_wait_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_cleanup(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_token_wait_4xx_n_5xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_token_wait_tmr_wait(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_shutdown(void); - -void sip_regmgr_rsp(int rsp_id, int rsp_type, boolean waited); - -boolean sip_regmgr_check_config_change(void); - -void sip_regmgr_process_config_change(void); -void sip_regmgr_send_refer(ccsipCCB_t *ccb); -void sip_regmgr_ccm_restarted(ccsipCCB_t *new_reg_ccb); -void sip_regmgr_notify_timer_callback(void *data); -ccsipCCB_t *sip_regmgr_get_fallback_ccb_list(uint32_t *previous_data_p); -void sip_regmgr_replace_standby(ccsipCCB_t *ccb); -void sip_regmgr_regallfail_timer_callback(void *data); -void sip_regmgr_handle_reg_all_fail(void); -void sip_regmgr_get_config_addr(int ccm_id, char *add_str); - -extern boolean g_disable_mass_reg_debug_print; - -void regmgr_handle_register_update(line_t last_available_line); - - -#endif /* __SIP_COMMON_REGMGR_H__ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_transport.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_transport.h deleted file mode 100644 index e6b4bf0d709..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_transport.h +++ /dev/null @@ -1,223 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_COMMON_TRANSPORT_H__ -#define __SIP_COMMON_TRANSPORT_H__ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "ccsip_pmh.h" -#include "sip_csps_transport.h" -#include "sip_ccm_transport.h" -#include "singly_link_list.h" - - -#define MAX_CONNECTIONS 5 - -/* Macro definition for chacking a valid connid (TCP/UDP) */ -#define VALID_CONNID(connid) \ - (connid >= 0 && connid < MAX_CONNECTIONS) - -typedef enum { - NONE_CC = 0, - ACTIVE_CC = 1, - STANDBY_CC -} CC_POSITION; - -/* - * Define the types of connections - */ -/* - * NOTE: Need to match the values in the config matrix - */ -typedef enum { - CONN_NONE = 0, - CONN_TCP, - CONN_UDP, - CONN_TLS, - CONN_TCP_TMP, - CONN_MAX_TYPES -} CONN_TYPE; - -// Device Security Modes -typedef enum sec_level_t_ { - NON_SECURE = 0, // Normal, no security - AUTHENTICATED, // Use TLS, server will use NULL encryption - ENCRYPTED, // Use TLS, server will use AES encryption - NOT_IN_CTL // Not in CTL should not be seen by SIP. -} sec_level_t; - -typedef enum conn_create_status_t_ { - CONN_INVALID = -1, - CONN_SUCCESS, - CONN_FAILURE -} conn_create_status_t; - -typedef struct ti_common_t_ { - uint16_t listen_port; - char addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t addr; - uint16_t port; - uint16_t sec_port; - CONN_TYPE conn_type; - CONN_TYPE configured_conn_type; - cpr_socket_t handle; -} ti_common_t; - -typedef struct ti_ccm_t_ { - CCM_ID ccm_id; - int32_t sec_level; - int32_t is_valid; -} ti_ccm_t; - -typedef struct ti_csps_t_ { - char bkup_pxy_addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t bkup_pxy_addr; - uint16_t bkup_pxy_port; - char emer_pxy_addr_str[MAX_IPADDR_STR_LEN]; - uint16_t emer_pxy_port; - char outb_pxy_addr_str[MAX_IPADDR_STR_LEN]; - uint16_t outb_pxy_port; -} ti_csps_t; - -typedef struct ti_config_table_t_ { - CC_ID cc_type; - ti_common_t ti_common; - union { - ti_ccm_t ti_ccm; - ti_csps_t *ti_csps; - } ti_specific; -} ti_config_table_t; - -extern ti_config_table_t *CCM_Config_Table[MAX_REG_LINES + 1][MAX_CCM]; -extern ti_config_table_t CCM_Dummy_Entry; -extern ti_config_table_t CSPS_Config_Table[MAX_REG_LINES]; -typedef struct cc_config_table_t_ { - CC_ID cc_type; - void *cc_table_entry; // Needs to deferenced as - // ti_config_table_t* -} cc_config_table_t; - -typedef long sipSPIConnId_t; - -typedef enum { - SOCKET_NO_ERROR = -1, - SOCKET_SEND_ERROR, - SOCKET_RECV_ERROR, - SOCKET_OPEN_ERROR, - SOCKET_OPT_ERROR, - SOCKET_CONNECT_ERROR, - SOCKET_CONN_REFUSED_ERROR, - SOCKET_BIND_ERROR, - SOCKET_REMOTE_CLOSURE, - SOCKET_ADMIN_CLOSURE, - SIP_TCP_CONN_TABLE_FULL -} ccsipSockErrCodes_e; - -/* All the possible state of the TCP/UDP sockets */ -typedef enum { - SOCK_IDLE, /* not inuse */ - SOCK_LISTENING, /* fd is listening on the well-known port */ - SOCK_ACCEPTED, /* connection accepted */ - SOCK_CONNECTED, /* connection made */ - SOCK_CONNECT_PENDING, /* connection is pending */ - SOCK_FAILED /* failed, will be closed when all calls fail */ -} sock_state_t; - -typedef struct { - cpr_ip_addr_t addr; - uint16_t port; - CONN_TYPE transport; /* Specifies UDP, Multicast UDP, TCP */ - uint8_t ip_sig_tos; - uint16_t local_listener_port; -} sipSPICreateConnection_t; - -typedef struct { - void *context; - sipSPICreateConnection_t createConnMsg; -} sipSPIMessage_t; - - -void sipTransportSetServerHandleAndPort(cpr_socket_t socket_handle, - uint16_t listen_port, - ti_config_table_t *ccm_table_entry); -int sip_dns_gethostbysrv(char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *srv_order, - boolean retried_addr); -int sip_dns_gethostbysrvorname(char *hname, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port); - -conn_create_status_t sip_transport_setup_cc_conn(line_t dn, CCM_ID ccm_id); -int sip_transport_destroy_cc_conn(line_t dn, CCM_ID ccm_id); - -int16_t SIPTaskGetProxyPortByDN(line_t dn); -uint32_t SIPTaskGetProxyAddressByDN(line_t dn); -cpr_socket_t SIPTaskGetProxyHandleByDN(line_t dn); - -int sipTransportCreateSendMessage(ccsipCCB_t *ccb, - sipMessage_t *pSIPMessage, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, void *scbp, - int reldev_stored_msg); -#define sipTransportChannelCreateSend(a, b, m, c, d, e, f) \ -sipTransportCreateSendMessage(a, b, m, c, d, FALSE, TRUE, e, NULL, f) - -int sipTransportSendMessage(ccsipCCB_t *ccb, - char *pOutMessageBuf, - uint32_t nbytes, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, - void *scbp); -#define sipTransportChannelSend(a, b, c, m, d, e, f) \ -sipTransportSendMessage(a, b, c, m, d, e, FALSE, TRUE, f, NULL) - -int sipTransportGetServerAddrPort(char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *psrv_order, - boolean retried_addr); -int sipTransportGetPrimServerPort(line_t line); -int sipTransportGetBkupServerPort(line_t line); -int sipTransportGetEmerServerPort(line_t line); -int sipTransportGetOutbProxyPort(line_t line); -cpr_ip_type sipTransportGetPrimServerAddress(line_t line, char *buffer); -uint16_t sipTransportGetBkupServerAddress(cpr_ip_addr_t *pip_addr, - line_t line, char *buffer); -void sipTransportGetEmerServerAddress(line_t line, char *buffer); -void sipTransportGetOutbProxyAddress(line_t line, char *buffer); -void sipTransportGetServerIPAddr(cpr_ip_addr_t *pip_addr, line_t line); -int sipTransportInit(void); -uint16_t sipTransportGetServerAddress(cpr_ip_addr_t *pip_addr, line_t dn, line_t index); -short sipTransportGetServerPort(line_t dn, line_t index); - -int sipTransportGetCCType(int line, void *cc_table_entry); -void sip_regmgr_set_cc_info(line_t line, line_t dn_line, - CC_ID *cc_type, void *cc_table_entry); -uint16_t sipTransportGetListenPort(line_t line, ccsipCCB_t *ccb); -const char *sipTransportGetTransportType(line_t line, boolean upper_case, - ccsipCCB_t *ccb); - -void sipTransportShutdown(void); -extern void ccsip_dump_send_msg_info(char *msg, sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port); -void SIPTaskProcessTCPMessage(sipMessage_t *pSipMessage, - cpr_sockaddr_storage from); - -void -sipTransportSetSIPServer(); - - -#endif /* __SIP_COMMON_TRANSPORT_H__ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_csps_transport.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_csps_transport.h deleted file mode 100644 index 0797985e9b1..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_csps_transport.h +++ /dev/null @@ -1,47 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_CSPS_TRANSPORT_H__ -#define __SIP_CSPS_TRANSPORT_H__ - -#include "cpr_types.h" -#include "phone_types.h" -#include "phone_debug.h" -#include "cfgfile_utils.h" -#include "configmgr.h" -#include "ccsip_protocol.h" -#include "ccsip_pmh.h" -#include "ccsip_platform_timers.h" -#include "ccsip_platform_udp.h" -#include "ccsip_messaging.h" - -/* - * Defines for Primary, Secondary and Tertiary CC - */ -typedef enum { - PRIMARY_CSPS = 0, - MAX_CSPS -} CSPS_ID; - -//extern csps_config_info_t CSPS_Config_Table; - -cpr_socket_t sipTransportCSPSGetProxyHandleByDN(line_t dn); -short sipTransportCSPSGetProxyPortByDN(line_t dn); -uint16_t sipTransportCSPSGetProxyAddressByDN(cpr_ip_addr_t *pip_addr, - line_t dn); - -uint16_t sip_config_get_proxy_port(line_t line); -uint16_t sip_config_get_backup_proxy_port(void); -void sip_config_get_proxy_addr(line_t line, char *buffer, int buffer_len); -uint16_t sip_config_get_backup_proxy_addr(cpr_ip_addr_t *IPAddress, - char *buffer, int buffer_len); - -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern ccsipGlobInfo_t gGlobInfo; - -extern int dns_error_code; // DNS errror code global -void sipTransportCSPSClearProxyHandle(cpr_ip_addr_t *ipaddr, uint16_t port, - cpr_socket_t this_fd); - -#endif /* __SIP_CSPS_TRANSPORT_H__ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_interface_regmgr.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_interface_regmgr.h deleted file mode 100644 index a12d17901c4..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_interface_regmgr.h +++ /dev/null @@ -1,64 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SIP_INTERFACE_REGMGR_H_ -#define _SIP_INTERFACE_REGMGR_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "sip_common_transport.h" -#include "regmgrapi.h" - -typedef enum reg_rcs_t_ { - REG_RC_SUCCESS, - REG_RC_ERROR, - REG_RC_MAX -} reg_rcs_t; - -typedef enum reg_srcs_t_ { - REG_SRC_GSM, - REG_SRC_SIP, - REG_SRC_MAX -} reg_srcs_t; - -typedef enum reg_status_t_ { - REG_FAIL, - REG_ALL_FAIL -} reg_status_t; - -typedef struct reg_status_msg_t_ { - reg_srcs_t src_id; - reg_status_t msg_id; -} reg_status_msg_t; - -typedef enum { - CCM_STATUS_NONE = 0, - CCM_STATUS_STANDBY, - CCM_STATUS_ACTIVE -} reg_ccm_status; - -void sip_regmgr_send_status(reg_srcs_t src_id, reg_status_t msg_id); -sec_level_t sip_regmgr_get_sec_level(line_t line); -boolean sip_regmgr_srtp_fallback_enabled(line_t line); -void sip_platform_set_ccm_status(); -void sip_platform_cc_mode_notify(void); -void sip_platform_failover_ind(CCM_ID ccm_id); -void sip_platform_fallback_ind(CCM_ID ccm_id); -extern CCM_ID sip_regmgr_get_ccm_id(ccsipCCB_t *ccb); -boolean sip_platform_is_phone_idle(void); -extern void platform_reg_failover_ind(void *to_id); -extern void platform_reg_fallback_ind(void *from_id); -extern void sip_regmgr_phone_idle(boolean waited); -extern void sip_regmgr_fallback_rsp(); -extern void sip_regmgr_failover_rsp_start(); -extern void sip_regmgr_failover_rsp_complete(); -extern void ui_set_ccm_conn_status(const char *addr_str, int status); -extern void platform_cc_mode_notify(int mode); -extern void ui_reg_all_failed(void); -extern void platform_reg_fallback_cfm(void); -extern void platform_regallfail_ind(void *); -extern void sip_platform_logout_reset_req(void); -extern void platform_logout_reset_req (void); - -#endif /* _SIP_INTERFACE_REGMGR_H_ */ diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_platform_task.h b/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_platform_task.h deleted file mode 100644 index 25219068739..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_platform_task.h +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SIP_PLATFORM_TASK_H_ -#define _SIP_PLATFORM_TASK_H_ - -#include "cpr_socket.h" - -/* - * Prototypes - */ -void sip_platform_task_loop(void *arg); -void sip_platform_task_set_listen_socket(cpr_socket_t s); -void sip_platform_task_set_read_socket(cpr_socket_t s); -void sip_platform_task_clr_read_socket(cpr_socket_t s); - -void sip_platform_task_reset_listen_socket(cpr_socket_t s); - -#endif diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/httpish.c b/media/webrtc/signaling/src/sipcc/core/sipstack/httpish.c deleted file mode 100644 index 1cde2a7e0e7..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/httpish.c +++ /dev/null @@ -1,1642 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Functions that parse and create HTTP/1.1-like messages(RFC 2068). Basically - * code that converts from network(ie text) form to a usable structure - * and vice-versa. - */ - -#include -#include - -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "httpish.h" -#include "ccsip_protocol.h" -#include "phone_debug.h" -#include "ccsip_core.h" - -//#define HTTPISH_DEBUG if (1) -#define MSG_DELIMIT_SIZE 80 -#define TMP_BODY_BUF_SIZE 200 -#define CMPC_HEADER_SIZE 256 - -extern sip_header_t sip_cached_headers[]; -httpishMsg_t * -httpish_msg_create (void) -{ - int i; - httpishMsg_t *msg; - - msg = (httpishMsg_t *) cpr_calloc(1, sizeof(httpishMsg_t)); - if (!msg) { - return NULL; - } - - msg->headers = (queuetype *) cpr_calloc(1, sizeof(queuetype)); - - if (!msg->headers) { - cpr_free(msg); - return NULL; - } - - msg->retain_flag = FALSE; - msg->mesg_line = NULL; - msg->content_length = 0; - msg->is_complete = FALSE; - msg->headers_read = FALSE; - - for (i = 0; i < HTTPISH_MAX_BODY_PARTS; i++) { - msg->mesg_body[i].msgContentType = NULL; - msg->mesg_body[i].msgBody = NULL; - msg->mesg_body[i].msgLength = 0; - msg->mesg_body[i].msgContentId = NULL; - msg->mesg_body[i].msgContentEnc = SIP_CONTENT_ENCODING_IDENTITY_VALUE; - msg->mesg_body[i].msgContentDisp = SIP_CONTENT_DISPOSITION_SESSION_VALUE; - msg->mesg_body[i].msgRequiredHandling = TRUE; - msg->mesg_body[i].msgContentTypeValue = SIP_CONTENT_TYPE_UNKNOWN_VALUE; - } - - msg->num_body_parts = 0; - msg->raw_body = NULL; - - queue_init(msg->headers, 0); - - return msg; -} - -int -httpish_strncasecmp(const char *s1, const char* s2, size_t len) -{ - /*This routine is an enhanced version of strncasecmp(). - *It ensures that the two strings being compared for size "len" - *don't have trailing characters beyond "len" chars. - *The trailing whitespaces beyond "len" chars is ignored. - */ - const unsigned char *us1 = (const unsigned char *) s1; - const unsigned char *us2 = (const unsigned char *) s2; - - /* No match if only one ptr is NULL */ - if ((!s1 && s2) || (s1 && !s2)) - return ((int) (s1 - s2)); - - if ((len == 0) || (s1 == s2)) - return 0; - - while (len-- > 0 && toupper(*us1) == toupper(*us2)) { - if (len == 0 || *us1 == '\0' || *us2 == '\0') - break; - us1++; - us2++; - } - - if (len == 0 && toupper(*us1) == toupper(*us2)) { - //all "len" chars are compared, need to look for trailing - //chars beyond "len" string size. Ignore white spaces. - while (*(++us1) != '\0') { - if (*us1 != ' ' && *us1 != '\t') { - break; - } - } - - while (*(++us2) != '\0') { - if (*us2 != ' ' && *us2 != '\t') { - break; - } - } - } - - - return (toupper(*us1) - toupper(*us2)); -} - -void -httpish_msg_free (httpishMsg_t *msg) -{ - int i; - - if ((!msg) || (msg->retain_flag == TRUE)) { - return; - } - - UTILFREE(msg->mesg_line); - - // Free all body parts - for (i = 0; i < HTTPISH_MAX_BODY_PARTS; i++) { - UTILFREE(msg->mesg_body[i].msgContentType); - UTILFREE(msg->mesg_body[i].msgBody); - UTILFREE(msg->mesg_body[i].msgContentId); - } - UTILFREE(msg->raw_body); - - if (msg->headers) { - httpish_header *this_header; - - this_header = (httpish_header *) dequeue(msg->headers); - while (this_header != NULL) { - UTILFREE(this_header->header); - UTILFREE(this_header); - this_header = (httpish_header *) dequeue(msg->headers); - } - } - - UTILFREE(msg->headers); - msg->headers = NULL; - - /* Free the header cache */ - for (i = 0; i < HTTPISH_HEADER_CACHE_SIZE; ++i) { - if (msg->hdr_cache[i].hdr_start) { - cpr_free(msg->hdr_cache[i].hdr_start); - } - } - - /* Free the httpishMsg_t struct itself */ - cpr_free(msg); -} - -boolean -httpish_msg_is_request (httpishMsg_t *msg, - const char *schema, - int schema_len) -{ - char *loc; - - loc = msg->mesg_line; - - if (!msg->is_complete || !msg->mesg_line) { - return FALSE; - } - - /* - * There might be a couple of leading spaces. Not allowed, - * but still be friendly - */ - while ((*loc == ' ') && (*loc != '\0')) { - loc++; - } - - if (strncmp(loc, schema, schema_len)) { - return TRUE; - } else { - return FALSE; - } -} - - -boolean -httpish_msg_is_complete (httpishMsg_t *msg) -{ - return msg->is_complete; -} - - -hStatus_t -httpish_msg_add_reqline (httpishMsg_t *msg, - const char *method, - const char *url, - const char *version) -{ - - uint32_t linesize = 0; - - if (!msg || !method || !url || !version) { - return HSTATUS_FAILURE; - } - - if (msg->mesg_line) { - cpr_free(msg->mesg_line); - } - - linesize = strlen(method) + 1 + strlen(url) + 1 + strlen(version) + 1; - - msg->mesg_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!msg->mesg_line) { - return HSTATUS_FAILURE; - } - - snprintf(msg->mesg_line, linesize, "%s %s %s", method, url, version); - - return HSTATUS_SUCCESS; -} - -hStatus_t -httpish_msg_add_respline (httpishMsg_t *msg, - const char *version, - uint16_t status_code, - const char *reason_phrase) -{ - uint32_t linesize = 0; - - if (!msg || !reason_phrase || !version || - (status_code < HTTPISH_MIN_STATUS_CODE)) { - return HSTATUS_FAILURE; - } - - if (msg->mesg_line) { - cpr_free(msg->mesg_line); - } - - /* Assumes status codes are max 6 characters long */ - linesize = strlen(version) + 1 + 6 + 1 + strlen(reason_phrase) + 1; - - msg->mesg_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!msg->mesg_line) { - return HSTATUS_FAILURE; - } - - snprintf(msg->mesg_line, linesize, "%s %d %s", - version, status_code, reason_phrase); - - return HSTATUS_SUCCESS; -} - - -httpishReqLine_t * -httpish_msg_get_reqline (httpishMsg_t *msg) -{ - char *this_token; - char *msgline; - httpishReqLine_t *hreq = NULL; - char *strtok_state; - - if (!msg || !msg->mesg_line || !(msgline = cpr_strdup(msg->mesg_line))) { - return NULL; - } - - hreq = (httpishReqLine_t *) cpr_malloc(sizeof(httpishReqLine_t)); - if (!hreq) { - cpr_free(msgline); - return NULL; - } - - this_token = PL_strtok_r(msgline, " ", &strtok_state); - - if (!this_token) { - cpr_free(hreq); - cpr_free(msgline); - return NULL; - } - - hreq->method = cpr_strdup(this_token); - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - if (!this_token) { - cpr_free(hreq->method); - cpr_free(hreq); - cpr_free(msgline); - return NULL; - } - - hreq->url = cpr_strdup(this_token); - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - if (!this_token) { - cpr_free(hreq->method); - cpr_free(hreq->url); - cpr_free(hreq); - cpr_free(msgline); - return NULL; - } - - hreq->version = cpr_strdup(this_token); - cpr_free(msgline); - return hreq; -} - - -httpishRespLine_t * -httpish_msg_get_respline (httpishMsg_t *msg) -{ - char *this_token; - char *msgline; - httpishRespLine_t *hrsp = NULL; - char *strtok_state; - unsigned long strtoul_result; - char *strtoul_end; - - if (!msg || !msg->mesg_line) { - return NULL; - } - - msgline = cpr_strdup(msg->mesg_line); - if (!msgline) { - return NULL; - } - - hrsp = (httpishRespLine_t *) cpr_malloc(sizeof(httpishRespLine_t)); - - if (!hrsp) { - cpr_free(msgline); - return NULL; - } - - this_token = PL_strtok_r(msgline, " ", &strtok_state); - - if (!this_token) { - cpr_free(hrsp); - cpr_free(msgline); - return NULL; - } - - hrsp->version = cpr_strdup(this_token); - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - if (!this_token) { - cpr_free(hrsp->version); - cpr_free(hrsp); - cpr_free(msgline); - return NULL; - } - - errno = 0; - strtoul_result = strtoul(this_token, &strtoul_end, 10); - - if (errno || this_token == strtoul_end || strtoul_result > USHRT_MAX) { - cpr_free(hrsp->version); - cpr_free(hrsp); - cpr_free(msgline); - return NULL; - } - - hrsp->status_code = (uint16_t) strtoul_result; - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - /* reason phrase is optional */ - if (this_token) { - hrsp->reason_phrase = cpr_strdup(this_token); - } else { - hrsp->reason_phrase = NULL; - } - - cpr_free(msgline); - return (hrsp); -} - - - -void -httpish_msg_free_reqline (httpishReqLine_t *rqline) -{ - if (!rqline) { - return; - } - - UTILFREE(rqline->method); - UTILFREE(rqline->url); - UTILFREE(rqline->version); -} - - -void -httpish_msg_free_respline (httpishRespLine_t *rspline) -{ - if (!rspline) { - return; - } - - UTILFREE(rspline->reason_phrase); - UTILFREE(rspline->version); -} - -hStatus_t -httpish_msg_add_text_header (httpishMsg_t *msg, - const char *hname, - const char *hval) -{ - uint32_t linesize = 0; - httpish_header *this_header = NULL; - char *header_line = NULL; - - if (!msg || !hname || !hval) { - return HSTATUS_FAILURE; - } - - linesize = strlen(hname) + 2 + strlen(hval) + 1; - - header_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!header_line) - return HSTATUS_FAILURE; - - this_header = (httpish_header *) cpr_malloc(sizeof(httpish_header)); - if (!this_header) { - cpr_free(header_line); - return HSTATUS_FAILURE; - } - - snprintf(header_line, linesize, "%s: %s", hname, hval); - - this_header->header = header_line; - this_header->next = NULL; - - enqueue(msg->headers, (void *) this_header); - - return HSTATUS_SUCCESS; -} - - -hStatus_t -httpish_msg_add_int_header (httpishMsg_t *msg, - const char *hname, - int32_t hval) -{ - uint32_t linesize = 0; - char *header_line = NULL; - httpish_header *this_header = NULL; - - if (!msg || !hname) { - return HSTATUS_FAILURE; - } - - /* Assumes the int is less than 10 characters */ - linesize = strlen(hname) + 2 + 10 + 1; - - header_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!header_line) { - return HSTATUS_FAILURE; - } - - this_header = (httpish_header *) cpr_malloc(sizeof(httpish_header)); - if (!this_header) { - cpr_free(header_line); - return HSTATUS_FAILURE; - } - - snprintf(header_line, linesize, "%s: %d", hname, hval); - - this_header->header = header_line; - this_header->next = NULL; - - enqueue(msg->headers, (void *) this_header); - - return HSTATUS_SUCCESS; -} - -const char * -httpish_msg_get_cached_header_val (httpishMsg_t *msg, - int cache_index) -{ - return msg->hdr_cache[cache_index].val_start; -} - -int -compact_hdr_cmp (char *this_line, - const char *c_hname) -{ - char cmpct_hdr[CMPC_HEADER_SIZE]; - - if (c_hname) { - sstrncpy(cmpct_hdr, c_hname, CMPC_HEADER_SIZE); - return cpr_strcasecmp(this_line, cmpct_hdr); - } - return -1; -} - -int -httpish_header_name_val (char *sipHeaderName, char *this_line) -{ - unsigned int x = 0; - boolean nameFound = FALSE; - - if (!sipHeaderName || !this_line) { - return (SIP_ERROR); - } - - sipHeaderName[0] = '\0'; - - /* Remove the leading white spaces eg: ......From: or .....From....: */ - while ((*this_line==' ' || *this_line=='\t') ) { - this_line++; - } - - /* Copy the allowed characters for header field name */ - while ((*this_line > 32) && (*this_line < 127) && (x < HTTPISH_HEADER_NAME_SIZE)) { - if (*this_line == ':') { - nameFound = TRUE; - sipHeaderName[x] = '\0'; - break; - } - sipHeaderName[x] = *this_line; - this_line++; - x++; - } - - /* Remove trailing white spaces */ - if (nameFound == FALSE && x < HTTPISH_HEADER_NAME_SIZE) { - while ((*this_line == ' ' || *this_line=='\t') ){ - this_line++; - if (*this_line == ':') { - nameFound = TRUE; - sipHeaderName[x] = '\0'; - break; - } - } - } - sipHeaderName[HTTPISH_HEADER_NAME_SIZE-1] = '\0'; - - if (nameFound) { - return (SIP_OK); - } else { - return (SIP_ERROR); - } -} - -boolean -httpish_msg_header_present (httpishMsg_t *msg, - const char *hname) -{ - nexthelper *p; - char *this_line = NULL; - - /* - * To allow case-insensitive compact headers, we need to compare 2 - * characters before we can decide, what the header name is. - * e.g. Call-ID and Content-Type both start with C. - * For now assume there is no white space between header name and ":" - */ - - if (!msg || !hname || (msg->headers->count == 0)) { - return FALSE; - } - - p = (nexthelper *) msg->headers->qhead; - while (p) { - this_line = ((httpish_header *)p)->header; - if (this_line) { - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if ((strlen(this_line) >= strlen(hname)) && - (cpr_strncasecmp(this_line, hname, strlen(hname))) == 0) { - return TRUE; - } - } - p = p->next; - } - - return FALSE; -} -const char * -httpish_msg_get_header_val (httpishMsg_t *msg, - const char *hname, - const char *c_hname) -{ - static const char fname[] = "httpish_msg_get_header_val"; - nexthelper *p; - char *this_line = NULL; - char headerName[HTTPISH_HEADER_NAME_SIZE]; - - headerName[0] = '\0'; - - /* - * To allow case-insensitive compact headers, we need to compare 2 - * characters before we can decide, what the header name is. - * e.g. Call-ID and Content-Type both start with C. - * For now assume there is no white space between header name and ":" - */ - - if (!msg || !hname || (msg->headers->count == 0)) { - return NULL; - } - - p = (nexthelper *) msg->headers->qhead; - while (p) { - this_line = ((httpish_header *)p)->header; - - if (httpish_header_name_val(headerName, this_line)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Invalid Header Passed %s", DEB_F_PREFIX_ARGS(HTTPISH, fname), this_line); - return (NULL); - } - - if (this_line) { - if ((cpr_strcasecmp(headerName, hname) == 0 || - compact_hdr_cmp(headerName, c_hname) == 0)) { - this_line = strchr(this_line, ':'); - if (this_line) { - this_line++; - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if (*this_line == '\0') - return (NULL); - else - return ((const char *) this_line); - } - } - } - p = p->next; - } - return NULL; -} - -int32_t -httpish_msg_get_content_length (httpishMsg_t *msg) -{ - return msg->content_length; -} - -static boolean -httpish_msg_to_wstream (pmhWstream_t *ws, - httpishMsg_t *msg) -{ - nexthelper *p; - char tmp_body_buf[TMP_BODY_BUF_SIZE]; - int buf_len, total_length = 0, i, boundary_size; - - if (!pmhutils_wstream_write_line(ws, msg->mesg_line)) { - return (FALSE); - } - - p = (nexthelper *) msg->headers->qhead; - while (p) { - if (!pmhutils_wstream_write_line(ws, - (char *) (((httpish_header *)p)->header))) { - return (FALSE); - } - p = p->next; - } - if (msg->num_body_parts > 0) { - if (msg->num_body_parts > 1) { - // Write out the special Content-Type header and the - // Mime-Version header and the aggregate Content-Length header - // followed by the unique boundary - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, - "%s: multipart/mixed; boundary=%s\r\n", - HTTPISH_HEADER_CONTENT_TYPE, uniqueBoundary); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "%s: 1.0\r\n", - HTTPISH_HEADER_MIME_VERSION); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - // Traverse the list and calculate the total size of the - // body - boundary_size = strlen("\r\n--\r\n") + strlen(uniqueBoundary); - for (i = 0; i < msg->num_body_parts; i++) { - total_length += boundary_size; - total_length += msg->mesg_body[i].msgLength; - total_length += sizeof(HTTPISH_HEADER_CONTENT_TYPE) + 1; - switch (msg->mesg_body[i].msgContentTypeValue) { - default: - case SIP_CONTENT_TYPE_UNKNOWN_VALUE: - total_length += strlen(msg->mesg_body[i].msgContentType) + 2; - break; - case SIP_CONTENT_TYPE_SDP_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_SDP) + 1; - break; - case SIP_CONTENT_TYPE_SIPFRAG_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_SIPFRAG) + 1; - break; - case SIP_CONTENT_TYPE_DIALOG_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_DIALOG) + 1; - break; - case SIP_CONTENT_TYPE_KPML_REQUEST_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_KPML_REQUEST) + 1; - break; - case SIP_CONTENT_TYPE_KPML_RESPONSE_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_KPML_RESPONSE) + 1; - break; - case SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_REMOTECC_REQUEST) + 1; - break; - case SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_REMOTECC_RESPONSE) + 1; - break; - case SIP_CONTENT_TYPE_CTI_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_CTI) + 1; - break; - case SIP_CONTENT_TYPE_CMXML_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_CMXML) + 1; - break; - case SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_TEXT_PLAIN) + 1; - break; - case SIP_CONTENT_TYPE_PRESENCE_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_PRESENCE) + 1; - break; - } - // Now estimate size of Content-Disposition header - total_length += sizeof(SIP_HEADER_CONTENT_DISP) + 1; - switch (msg->mesg_body[i].msgContentDisp) { - case SIP_CONTENT_DISPOSITION_RENDER_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_RENDER) - 1; - break; - case SIP_CONTENT_DISPOSITION_SESSION_VALUE: - default: - total_length += sizeof(SIP_CONTENT_DISPOSITION_SESSION) - 1; - break; - case SIP_CONTENT_DISPOSITION_ICON_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_ICON) - 1; - break; - case SIP_CONTENT_DISPOSITION_ALERT_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_ALERT) - 1; - break; - case SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_PRECONDITION) - 1; - break; - } - // Now the handling attribute - total_length += sizeof(";handling=") - 1; - if (msg->mesg_body[i].msgRequiredHandling) { - total_length += sizeof("required") + 1; - } else { - total_length += sizeof("optional") + 1; - } - // Now the content id - if (msg->mesg_body[i].msgContentId) { - total_length += sizeof(HTTPISH_HEADER_CONTENT_ID) + 1 + - strlen(msg->mesg_body[i].msgContentId) + 2; - - } - } - // Now account for the closing boundary which is 2+boundary_size - total_length += 2 + boundary_size + 2; - - // Now write it out - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "%s: %d\r\n", - HTTPISH_HEADER_CONTENT_LENGTH, total_length); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "\r\n--%s\r\n", uniqueBoundary); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - } else { - // Write out Content-Length for the first body - total_length = msg->mesg_body[0].msgLength; - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "%s: %d\r\n", - HTTPISH_HEADER_CONTENT_LENGTH, total_length); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - } - for (i = 0; i < msg->num_body_parts; i++) { - if (i > 0) { - // If there is another body to come, write the unique boundary - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "\r\n--%s\r\n", uniqueBoundary); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - } - snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "Content-Type: %s\r\n", - msg->mesg_body[i].msgContentType); - sstrncat(tmp_body_buf, "Content-Disposition: ", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - - switch (msg->mesg_body[i].msgContentDisp) { - case SIP_CONTENT_DISPOSITION_RENDER_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_RENDER, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_SESSION_VALUE: - default: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_SESSION, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_ICON_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_ICON, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_ALERT_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_ALERT, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_PRECONDITION, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - } - if (msg->mesg_body[i].msgRequiredHandling) { - sstrncat(tmp_body_buf, ";handling=required\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - } else { - sstrncat(tmp_body_buf, ";handling=optional\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - } - if (msg->mesg_body[i].msgContentId) { - sstrncat(tmp_body_buf, "Content-Id: ", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - sstrncat(tmp_body_buf, msg->mesg_body[i].msgContentId, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - sstrncat(tmp_body_buf, "\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - } - sstrncat(tmp_body_buf, "\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - buf_len = strlen(tmp_body_buf); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - // Now write the body - if (!pmhutils_wstream_write_bytes(ws, msg->mesg_body[i].msgBody, - msg->mesg_body[i].msgLength)) { - return (FALSE); - } - } - // After writing out the last body part, write out the last unique - // boundary line - if (msg->num_body_parts > 1) { - snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "\r\n--%s--\r\n", uniqueBoundary); - buf_len = strlen(tmp_body_buf); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - } - } else { - if (!pmhutils_wstream_write_byte(ws, '\r')) { - return (FALSE); - } - if (!pmhutils_wstream_write_byte(ws, '\n')) { - return (FALSE); - } - } - - return (TRUE); -} - -hStatus_t -httpish_msg_write (httpishMsg_t *msg, - char *buf, - uint32_t *nbytes) -{ - pmhWstream_t *ws = NULL; - - ws = pmhutils_wstream_create_with_buf(buf, *nbytes); - if (!ws) { - return (HSTATUS_FAILURE); - } - - if (!httpish_msg_to_wstream(ws, msg)) { - pmhutils_wstream_delete(ws, FALSE); - cpr_free(ws); - return (HSTATUS_FAILURE); - } - - *nbytes = pmhutils_wstream_get_length(ws); - pmhutils_wstream_delete(ws, FALSE); - cpr_free(ws); - return HSTATUS_SUCCESS; -} - -int -httpish_cache_header_val (httpishMsg_t *hmsg, - char *this_line) -{ - static const char fname[] = "httpish_cache_header_val"; - char *hdr_start; - httpish_cache_t *hdr_cache; - int i; - char headerName[HTTPISH_HEADER_NAME_SIZE]; - - headerName[0] = '\0'; - - hdr_cache = hmsg->hdr_cache; - hdr_start = this_line; - - if (httpish_header_name_val(headerName, this_line)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Invalid Header %s", DEB_F_PREFIX_ARGS(HTTPISH, fname), this_line); - return (SIP_ERROR); - } - - for (i = 0; i < HTTPISH_HEADER_CACHE_SIZE; ++i) { - sip_header_t *tmp = sip_cached_headers + i; - - if (cpr_strcasecmp(headerName, tmp->hname) == 0 || - compact_hdr_cmp(headerName, tmp->c_hname) == 0) { - this_line = strchr(this_line, ':'); - if (this_line) { - this_line++; /* Skip the ':' */ - - /* Remove leading spaces */ - while (*this_line == ' ' || *this_line == '\t') { - this_line++; - } - if (*this_line) { - if (hdr_cache[i].hdr_start) { - int org_len, offset; - int size; - char *newbuf; - - /* Multiple instances of a header, concatenate the - * header values with a ',' - */ - org_len = strlen(hdr_cache[i].hdr_start); - offset = hdr_cache[i].val_start - hdr_cache[i].hdr_start; - size = org_len + 2 + strlen(this_line); - newbuf = (char *) cpr_realloc(hdr_cache[i].hdr_start, - size); - if (newbuf == NULL) { - cpr_free(hdr_cache[i].hdr_start); - hdr_cache[i].hdr_start = NULL; - break; - } - hdr_cache[i].hdr_start = newbuf; - hdr_cache[i].val_start = hdr_cache[i].hdr_start + offset; - hdr_cache[i].hdr_start[org_len] = ','; - sstrncpy(hdr_cache[i].hdr_start + org_len + 1, this_line, - size - org_len - 1); - cpr_free(hdr_start); - } else { - hdr_cache[i].hdr_start = hdr_start; - hdr_cache[i].val_start = this_line; - } - } else { // this line is blank - cpr_free(hdr_start); - } - } else { // this line does not have a ':' - cpr_free(hdr_start); - } - return 0; - } - } - return -1; -} - -/* - * Return -1 for invalid/empty content-length value - * else return the content length - */ -int32_t -get_content_length (httpishMsg_t *hmsg) -{ - int i; - const char *hdr_val; - long strtol_result; - char *strtol_end; - - hdr_val = httpish_msg_get_cached_header_val(hmsg, CONTENT_LENGTH); - if (hdr_val == NULL) { - return -1; - } - - for (i = 0; hdr_val[i]; ++i) { - if (!isdigit((int) hdr_val[i])) { - return -1; - } - } - - /* If the string was empty then the content length is still invalid */ - if (!i) { - return -1; - } - - errno = 0; - strtol_result = strtol(hdr_val, &strtol_end, 10); - - if (errno || hdr_val == strtol_end || strtol_result > INT_MAX) { - return -1; - } else { - return (int) strtol_result; - } -} - -uint8_t -get_content_type_value (const char *content_type) -{ - if (!content_type) { - return SIP_CONTENT_TYPE_UNKNOWN_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_SDP, - sizeof(SIP_CONTENT_TYPE_SDP) - 1)) { - return SIP_CONTENT_TYPE_SDP_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_SIPFRAG, - sizeof(SIP_CONTENT_TYPE_SIPFRAG) - 1)) { - return SIP_CONTENT_TYPE_SIPFRAG_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_TEXT_PLAIN, - sizeof(SIP_CONTENT_TYPE_TEXT_PLAIN) - 1)) { - return SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_SIP, - sizeof(SIP_CONTENT_TYPE_SIP) - 1)) { - return SIP_CONTENT_TYPE_SIP_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_MWI, - sizeof(SIP_CONTENT_TYPE_MWI) - 1)) { - return SIP_CONTENT_TYPE_MWI_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_MULTIPART_MIXED, - sizeof(SIP_CONTENT_TYPE_MULTIPART_MIXED) - 1)) { - return SIP_CONTENT_TYPE_MULTIPART_MIXED_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE, - sizeof(SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE) - 1)) { - return SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE_VALUE; - } - else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_DIALOG, - sizeof(SIP_CONTENT_TYPE_DIALOG) - 1)) { - return SIP_CONTENT_TYPE_DIALOG_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_KPML_REQUEST, - sizeof(SIP_CONTENT_TYPE_KPML_REQUEST) - 1)) { - return SIP_CONTENT_TYPE_KPML_REQUEST_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_KPML_RESPONSE, - sizeof(SIP_CONTENT_TYPE_KPML_RESPONSE) - 1)) { - return SIP_CONTENT_TYPE_KPML_RESPONSE_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_REMOTECC_REQUEST, - sizeof(SIP_CONTENT_TYPE_REMOTECC_REQUEST) - 1)) { - return SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_CONFIGAPP, - sizeof(SIP_CONTENT_TYPE_CONFIGAPP) - 1)) { - return SIP_CONTENT_TYPE_CONFIGAPP_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_REMOTECC_RESPONSE, - sizeof(SIP_CONTENT_TYPE_REMOTECC_RESPONSE) - 1)) { - return SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_PRESENCE, - sizeof(SIP_CONTENT_TYPE_PRESENCE) - 1)) { - return SIP_CONTENT_TYPE_PRESENCE_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_CMXML, - sizeof(SIP_CONTENT_TYPE_CMXML) - 1)) { - return SIP_CONTENT_TYPE_CMXML_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_CTI, - sizeof(SIP_CONTENT_TYPE_CTI) - 1)) { - return SIP_CONTENT_TYPE_CTI_VALUE; - } - return SIP_CONTENT_TYPE_UNKNOWN_VALUE; -} - -/****************************************************************** - * msg_process_one_body - * This function will process one of the body parts of the whole body - * Headers not understood will be ignored - * - msg_start should be pointing at the first header of the body part - * - msg_end at its last character - ******************************************************************/ -int -msg_process_one_body (httpishMsg_t *hmsg, - char *msg_start, - char *msg_end, - int current_body_part) -{ - static const char fname[] = "msg_process_one_body"; - pmhRstream_t *rstream = NULL; - char *content_type = NULL, *content_disp = NULL; - char *line = NULL, *body = NULL; - char *content_enc = NULL; - char *content_id = NULL; int nbytes = 0; - boolean body_read = FALSE; - - // Adjust msg_start to point to the first valid character - while (*msg_start == '\r' || *msg_start == '\n') { - msg_start++; - } - - // Convert this chunk of data into a more parse-able format - rstream = pmhutils_rstream_create(msg_start, (uint32_t)(msg_end - msg_start)); - - while (!body_read) { - if (rstream) { - line = pmhutils_rstream_read_line(rstream); - } - - if (line) { - // Look for the kind of line it is - if (!cpr_strncasecmp(line, HTTPISH_HEADER_CONTENT_TYPE, - sizeof(HTTPISH_HEADER_CONTENT_TYPE) - 1)) { - // Its Content-Type, read in the value - // XXX what if the line looks like "Content-Type-Garbage: some-value"? - content_type = line + sizeof(HTTPISH_HEADER_CONTENT_TYPE); - // XXX what if the line looks like "Content-Type : some-value"? - while (*content_type == ' ') { - content_type++; - } - hmsg->mesg_body[current_body_part].msgContentTypeValue = get_content_type_value(content_type); - nbytes = strlen(content_type) + 1; - hmsg->mesg_body[current_body_part].msgContentType = - (char *) cpr_malloc((nbytes)*sizeof(char)); - if (hmsg->mesg_body[current_body_part].msgContentType == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed", fname); - } else { - memcpy(hmsg->mesg_body[current_body_part].msgContentType, - content_type, nbytes); - } - } else if (!cpr_strncasecmp(line, HTTPISH_HEADER_CONTENT_ID, - sizeof(HTTPISH_HEADER_CONTENT_ID) - 1)) { - //Its Content-Id, read the value - content_id = line + sizeof(HTTPISH_HEADER_CONTENT_ID); - while(*content_id == ' ') { - content_id++; - } - nbytes = strlen(content_id) + 1; - hmsg->mesg_body[current_body_part].msgContentId = - (char *) cpr_malloc((nbytes)*sizeof(char)); - if (hmsg->mesg_body[current_body_part].msgContentId == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed", fname); - } - memcpy(hmsg->mesg_body[current_body_part].msgContentId, - content_id, nbytes); - } else if (!cpr_strncasecmp(line, SIP_HEADER_CONTENT_DISP, - sizeof(SIP_HEADER_CONTENT_DISP) - 1)) { - // Its Content-Disposition, read in the value - content_disp = line + sizeof(SIP_HEADER_CONTENT_DISP); - while (*content_disp == ' ') { - content_disp++; - } - if (!cpr_strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_SESSION, - sizeof(SIP_CONTENT_DISPOSITION_SESSION) - 1)) { - hmsg->mesg_body[current_body_part].msgContentDisp = - SIP_CONTENT_DISPOSITION_SESSION_VALUE; - content_disp += sizeof(SIP_CONTENT_DISPOSITION_SESSION) - 1; - } else { - hmsg->mesg_body[current_body_part].msgContentDisp = - SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE; - content_disp = strchr(line, ';'); - } - if (content_disp && *content_disp == ';') { - content_disp++; - if (!cpr_strncasecmp(content_disp, "handling", 8)) { - content_disp += 9; - if (!cpr_strncasecmp(content_disp, "required", 8)) { - hmsg->mesg_body[current_body_part].msgRequiredHandling = TRUE; - } else if (!cpr_strncasecmp(content_disp, "optional", 8)) { - hmsg->mesg_body[current_body_part].msgRequiredHandling = FALSE; - } - } - } - } else if (!cpr_strncasecmp(line, HTTPISH_HEADER_CONTENT_ENCODING, - sizeof(HTTPISH_HEADER_CONTENT_ENCODING) - 1)) { - content_enc = line + sizeof(HTTPISH_HEADER_CONTENT_ENCODING); - while (*content_enc == ' ') { - content_enc++; - } - if (!cpr_strcasecmp(content_enc, SIP_CONTENT_ENCODING_IDENTITY)) { - hmsg->mesg_body[current_body_part].msgContentEnc = - SIP_CONTENT_ENCODING_IDENTITY_VALUE; - } else { - hmsg->mesg_body[current_body_part].msgContentEnc = - SIP_CONTENT_ENCODING_UNKNOWN_VALUE; - } - } else if (!(*line)) { - body_read = TRUE; - // The rest of the bytes are the body - hmsg->mesg_body[current_body_part].msgLength = - rstream->nbytes - rstream->bytes_read; - body = pmhutils_rstream_read_bytes(rstream, rstream->nbytes - rstream->bytes_read); - if (body) { - hmsg->mesg_body[current_body_part].msgBody = body; - } - } else { - // Unhandled header type - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unrecognized header in body", DEB_F_PREFIX_ARGS(HTTPISH, fname)); - } - // Free the read line - cpr_free(line); - line = NULL; - } else { - body_read = TRUE; - } - } - // Free the created stream structure - pmhutils_rstream_delete(rstream, FALSE); - cpr_free(rstream); - return 0; -} - -/****************************************************************** - * msg_process_multiple_bodies - * This function will process multiple body parts of the whole body - * boundary should point to the delimiter string, raw body points to - * the beginning of the whole body structure in the message - * - * The algorithm here is to find the beginning and the end of each - * body part and send it off for further header and body extraction - ******************************************************************/ -int -msg_process_multiple_bodies (httpishMsg_t *hmsg, - char *boundary, - char *raw_body) -{ - char msg_delimit[MSG_DELIMIT_SIZE]; - int i, body_part = 0; - boolean end_of_proc = FALSE; - char *msg_start, *msg_end; - - // First copy the boundary in an array - msg_delimit[0] = '-'; - msg_delimit[1] = '-'; - for (i = 0; boundary[i] != '\r' && boundary[i] != '\n' && - boundary[i] != ';' && boundary[i] != '\0'; i++) { - if (i + 2 >= MSG_DELIMIT_SIZE) { - return body_part; - } - msg_delimit[i + 2] = boundary[i]; - } - msg_delimit[i + 2] = '\0'; - - // Loop through the body segments - while (!end_of_proc && body_part < HTTPISH_MAX_BODY_PARTS) { - msg_start = strstr(raw_body, msg_delimit); - if (msg_start) { - msg_start += strlen(msg_delimit) + 1; - msg_end = strstr(msg_start, msg_delimit); - if (msg_end) { - (void) msg_process_one_body(hmsg, msg_start, msg_end - 1, - body_part); - } else { - // No boundary found for message end, return error - end_of_proc = TRUE; - continue; - } - } else { - // No boundary found for message start, return error - end_of_proc = TRUE; - continue; - } - raw_body = msg_end; - // Check if this is the last boundary - if (*(raw_body + strlen(msg_delimit)) == '-') { - end_of_proc = TRUE; - } - body_part++; - } - return body_part; -} - -hStatus_t -httpish_msg_process_network_msg (httpishMsg_t *hmsg, - char *nmsg, - uint32_t *nbytes) -{ - static const char fname[] = "httpish_msg_process_network_msg"; - pmhRstream_t *rs = NULL; - int32_t bytes_remaining, delta; - char *mline; - hStatus_t retval; - char *raw_body = NULL; - const char *content_type = NULL; - const char *content_id = NULL; - int32_t contentid_len; - int32_t contenttype_len; - - if (!hmsg || !nmsg || (*nbytes <= 0)) { - return HSTATUS_FAILURE; - } - - if (hmsg->is_complete == TRUE) { - *nbytes = 0; - return HSTATUS_SUCCESS; - } - - if ((rs = pmhutils_rstream_create(nmsg, *nbytes)) == NULL) - return HSTATUS_FAILURE; - - /* Try to read message line */ - while (!hmsg->mesg_line) { - mline = pmhutils_rstream_read_line(rs); - if (!mline) { - *nbytes = rs->bytes_read; - if (rs->eof == TRUE) { - retval = HSTATUS_SUCCESS; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Msg line read failure due to RS->EOF", fname); - } else { - retval = HSTATUS_FAILURE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Msg line read failure", fname); - } - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return retval; - } - if (!(*mline)) { - cpr_free(mline); - } else { - hmsg->mesg_line = mline; - } - } - - /* There is a message line. We could have a header or a message body */ - while (!hmsg->headers_read) { - char *this_header; - - this_header = pmhutils_rstream_read_line(rs); - if (!this_header) { - *nbytes = rs->bytes_read; - if (rs->eof == TRUE) { - retval = HSTATUS_SUCCESS; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Header line read failure due to RS->EOF", DEB_F_PREFIX_ARGS(HTTPISH, fname)); - } else { - retval = HSTATUS_FAILURE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Header line read failure", fname); - } - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return retval; - } - if (!(*this_header)) { - cpr_free(this_header); - hmsg->headers_read = TRUE; - } else { - httpish_header *h; - - if (httpish_cache_header_val(hmsg, this_header) == -1) { - /* - * For a non-cacheable header or error in caching routine, - * use the header linked list. - */ - h = (httpish_header *) cpr_malloc(sizeof(httpish_header)); - if (!h) { - *nbytes = rs->bytes_read; - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(this_header); - return HSTATUS_FAILURE; - } - - h->next = NULL; - h->header = this_header; - enqueue(hmsg->headers, (void *)h); - } - - } - } - - /* Calculate the bytes remaining in the read stream */ - bytes_remaining = rs->nbytes - rs->bytes_read; - - /* Now get the content length header value */ - hmsg->content_length = get_content_length(hmsg); - if (hmsg->content_length == -1) { - /* Bad or missing content-length header - * For UDP, assume remaining msg is message body. - * For TCP, message is not complete without content-length header - * but we will ignore this possibility for now (assume content-length will always be there) - * since we don't know if we have a complete message or a fragmented one - */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Content-Length header not received", fname); - hmsg->content_length = bytes_remaining; - } - - delta = bytes_remaining - hmsg->content_length; - if (delta) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX "Content Length %d, Bytes Remaining %d.", DEB_F_PREFIX_ARGS(HTTPISH, fname), - hmsg->content_length, bytes_remaining); - } - if (delta < 0) { - /* We have fewer bytes than specified by Content-Length header */ - hmsg->content_length = bytes_remaining; - hmsg->is_complete = FALSE; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Partial body received", DEB_F_PREFIX_ARGS(HTTPISH, fname)); - } else { - hmsg->is_complete = TRUE; - } - - if (hmsg->content_length > 0) { - raw_body = pmhutils_rstream_read_bytes(rs, hmsg->content_length); - if (!raw_body) { - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return HSTATUS_FAILURE; - } - } - - // If message is not complete we should not parse the message any more - if (!hmsg->is_complete) { - *nbytes = rs->bytes_read; - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - UTILFREE(raw_body); - return HSTATUS_SUCCESS; - } - - // Figure out whether more parsing of the received body is necessary - content_type = httpish_msg_get_cached_header_val(hmsg, CONTENT_TYPE); - if (content_type && (hmsg->content_length > 0)) { - if (!cpr_strncasecmp(content_type, "multipart/mixed", 15)) { - - char *boundary = NULL; - int num_bodies = 0; - - // find the boundary tag - boundary = strchr(content_type, '='); - if (boundary) { - boundary++; - if (raw_body) { - num_bodies = msg_process_multiple_bodies(hmsg, boundary, raw_body); - } - - if (num_bodies == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in decoding multipart messages", fname); - } else { - hmsg->num_body_parts = (uint8_t) num_bodies; - } - } else { - // No boundary specified! - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in decoding multipart messages: No body delimiter", fname); - } - hmsg->raw_body = raw_body; - - } else { - // All of the body is of a single type - // hmsg->mesg_body[0].msgBody = raw_body; - hmsg->mesg_body[0].msgBody = (char *) - cpr_malloc(hmsg->content_length + 1); - if (hmsg->mesg_body[0].msgBody == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory", fname); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(raw_body); - return HSTATUS_FAILURE; - } - - if (raw_body) { - memcpy(hmsg->mesg_body[0].msgBody, raw_body, - hmsg->content_length + 1); - } - - content_id = httpish_msg_get_header_val(hmsg, HTTPISH_HEADER_CONTENT_ID, NULL); - if (content_id) { - contentid_len = strlen(content_id) + 1; - hmsg->mesg_body[0].msgContentId = (char *) - cpr_malloc(contentid_len * sizeof(char)); - if (hmsg->mesg_body[0].msgContentId == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory", fname); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(raw_body); - return HSTATUS_FAILURE; - } - memcpy(hmsg->mesg_body[0].msgContentId, - content_id, contentid_len); - } - - hmsg->mesg_body[0].msgContentTypeValue = get_content_type_value(content_type); - contenttype_len = strlen(content_type) + 1; - hmsg->mesg_body[0].msgContentType = (char *) - cpr_malloc(contenttype_len * sizeof(char)); - if (hmsg->mesg_body[0].msgContentType == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory", fname); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(raw_body); - return HSTATUS_FAILURE; - } - memcpy(hmsg->mesg_body[0].msgContentType, - content_type, contenttype_len); - - hmsg->mesg_body[0].msgContentDisp = - SIP_CONTENT_DISPOSITION_SESSION_VALUE; - hmsg->mesg_body[0].msgRequiredHandling = TRUE; - hmsg->mesg_body[0].msgLength = hmsg->content_length; - hmsg->num_body_parts = 1; - hmsg->raw_body = raw_body; - } - } else if (hmsg->content_length > 0) { - // No content-type specified but there is a body present. Treat this - // as an error - hmsg->is_complete = FALSE; - hmsg->content_length = -1; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Body found without content-type", fname); - UTILFREE(raw_body); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return HSTATUS_SUCCESS; - } - - *nbytes = rs->bytes_read; - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return HSTATUS_SUCCESS; -} - - -hStatus_t -httpish_msg_add_body (httpishMsg_t *msg, - char *body, - uint32_t nbytes, - const char *content_type, - uint8_t msg_disposition, - boolean required, - char *content_id) -{ - static const char fname[] = "httpish_msg_add_body"; - uint8_t current_body_part; - uint32_t contenttype_len; - - if (!msg || !body || (nbytes == 0)) { - return HSTATUS_FAILURE; - } - - if (msg->num_body_parts == HTTPISH_MAX_BODY_PARTS) { - return HSTATUS_FAILURE; - } - - // Add body at the next available index - current_body_part = msg->num_body_parts; - - contenttype_len = strlen(content_type) + 1; - msg->mesg_body[current_body_part].msgContentType = (char *) - cpr_malloc(contenttype_len * sizeof(char)); - if (msg->mesg_body[current_body_part].msgContentType == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory", fname); - return HSTATUS_FAILURE; - } - - msg->mesg_body[current_body_part].msgBody = body; - memcpy(msg->mesg_body[current_body_part].msgContentType, - content_type, contenttype_len); - msg->mesg_body[current_body_part].msgContentTypeValue = get_content_type_value(content_type); - msg->mesg_body[current_body_part].msgContentDisp = msg_disposition; - msg->mesg_body[current_body_part].msgRequiredHandling = required; - msg->mesg_body[current_body_part].msgLength = nbytes; - msg->mesg_body[current_body_part].msgContentId = content_id; - - msg->num_body_parts++; - - return HSTATUS_SUCCESS; -} - - -httpishStatusCodeClass_t -httpish_msg_get_code_class (uint16_t statusCode) -{ - httpishStatusCodeClass_t retval; - int fc = statusCode / 100; - - switch (fc) { - case 1: - retval = codeClass1xx; - break; - case 2: - retval = codeClass2xx; - break; - case 3: - retval = codeClass3xx; - break; - case 4: - retval = codeClass4xx; - break; - case 5: - retval = codeClass5xx; - break; - case 6: - retval = codeClass6xx; - break; - default: - retval = codeClassInvalid; - break; - } - - return retval; -} - - -uint16_t -httpish_msg_get_num_particular_headers (httpishMsg_t *msg, - const char *hname, - const char *c_hname, - char *header_val[], - uint16_t max_headers) -{ - nexthelper *p; - char *this_line = NULL; - uint16_t found = 0; - - if (!msg || !hname) { - return 0; - } - - p = (nexthelper *) msg->headers->qhead; - - while (p && found < max_headers) { - this_line = ((httpish_header *)p)->header; - if (this_line) { - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if ((strlen(this_line) > strlen(hname) + 1) && - (cpr_strncasecmp(this_line, hname, strlen(hname)) == 0 || - compact_hdr_cmp(this_line, c_hname) == 0)) { - this_line = strchr(this_line, ':'); - if (this_line) { - this_line++; - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if (*this_line == '\0') { - p = p->next; - continue; - } else { - header_val[found] = this_line; - found++; - } - } - } - } - p = p->next; - } - return found; -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/pmhutils.c b/media/webrtc/signaling/src/sipcc/core/sipstack/pmhutils.c deleted file mode 100644 index 57c83d784c4..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/pmhutils.c +++ /dev/null @@ -1,308 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "pmhutils.h" -#include "phone.h" - - -#define WSTREAM_START_SIZE 1024 - -pmhRstream_t * -pmhutils_rstream_create (char *buf, uint32_t nbytes) -{ - pmhRstream_t *pmhRstream; - - if (!buf || (nbytes == 0)) { - return NULL; - } - - pmhRstream = (pmhRstream_t *) cpr_malloc(sizeof(pmhRstream_t)); - if (!pmhRstream) { - return NULL; - } - - pmhRstream->eof = pmhRstream->error = FALSE; - pmhRstream->buff = pmhRstream->loc = buf; - pmhRstream->nbytes = nbytes; - pmhRstream->bytes_read = 0; - - return pmhRstream; -} - -void -pmhutils_rstream_delete (pmhRstream_t *pmhRstream, boolean freebuf) -{ - if (!pmhRstream) { - return; - } - - pmhRstream->error = TRUE; - - if (freebuf && pmhRstream->buff) { - cpr_free(pmhRstream->buff); - } -} - -char * -pmhutils_rstream_read_bytes (pmhRstream_t *pmhRstream, int32_t nbytes) -{ - char *ret; - - if (!pmhRstream || !pmhRstream->loc || (pmhRstream->eof == TRUE)) { - return NULL; - } - - if (pmhRstream->bytes_read >= pmhRstream->nbytes) { - pmhRstream->eof = TRUE; - return NULL; - } - - if ((pmhRstream->nbytes - pmhRstream->bytes_read) < (int32_t) nbytes) { - return NULL; - } - ret = (char *) cpr_malloc((nbytes + 1) * sizeof(char)); - if (ret == NULL) { - // Addition of 1 byte (NULL) will save us from strlen errr - return NULL; - } - memcpy(ret, pmhRstream->loc, nbytes); - ret[nbytes] = 0; /* ensure null terminating character */ - pmhRstream->bytes_read += nbytes; - pmhRstream->loc += nbytes; - - return (ret); -} - - -#define SANITY_LINE_SIZE PKTBUF_SIZ - -unsigned short linesize = 80; -unsigned short incr_size = 32; - -char * -pmhutils_rstream_read_line (pmhRstream_t *pmhRstream) -{ - char *ret_line; - char *new_loc = NULL; - int offset, bytes_allocated; - boolean line_break; - - if (!pmhRstream || !pmhRstream->loc || (pmhRstream->eof == TRUE)) { - return NULL; - } - - if (pmhRstream->bytes_read >= pmhRstream->nbytes) { - pmhRstream->eof = TRUE; - return NULL; - } - - new_loc = pmhRstream->loc; - - ret_line = (char *) cpr_malloc(linesize); - if (ret_line == NULL) { - return NULL; - } - offset = 0; - bytes_allocated = linesize; - /* Search for the first occurrence of a line break */ - while (1) { - line_break = FALSE; - if (*new_loc == '\r') { - line_break = TRUE; - new_loc++; - } - if (*new_loc == '\n') { - line_break = TRUE; - new_loc++; - } - if (line_break) { - if (*new_loc != ' ' && *new_loc != '\t') { - break; - } - } - - if (offset == (bytes_allocated - 1)) { - char *newbuf; - - bytes_allocated += incr_size; - newbuf = (char *) cpr_realloc(ret_line, bytes_allocated); - if (newbuf == NULL) { - if (bytes_allocated != 0) { - cpr_free(ret_line); - } - return NULL; - } - ret_line = newbuf; - } - ret_line[offset++] = *new_loc++; - if (*new_loc == '\0') { - /* We hit the end of buffer before hitting a line break */ - pmhRstream->eof = TRUE; - pmhRstream->bytes_read += (new_loc - pmhRstream->loc); - pmhRstream->loc = new_loc; - cpr_free(ret_line); - return NULL; - } - } - - pmhRstream->bytes_read += (new_loc - pmhRstream->loc); - /* Update the internal location pointer and bytes read */ - - if (pmhRstream->bytes_read >= pmhRstream->nbytes) { - pmhRstream->loc = pmhRstream->buff + pmhRstream->nbytes; - pmhRstream->eof = TRUE; - } else { - pmhRstream->loc = pmhRstream->buff + pmhRstream->bytes_read; - } - - ret_line[offset] = 0; - return ret_line; -} - -pmhWstream_t * -pmhutils_wstream_create_with_buf (char *buf, uint32_t nbytes) -{ - pmhWstream_t *pmhWstream = NULL; - - if (buf && nbytes && (nbytes > 0)) { - pmhWstream = (pmhWstream_t *) cpr_malloc(sizeof(pmhWstream_t)); - if (!pmhWstream) { - return (NULL); - } - pmhWstream->buff = buf; - pmhWstream->nbytes = 0; - pmhWstream->total_bytes = nbytes; - pmhWstream->growable = FALSE; - } - return (pmhWstream); -} - - -uint32_t -pmhutils_wstream_get_length (pmhWstream_t *ws) -{ - if (ws) { - return (ws->nbytes); - } else { - return (0); - } -} - - -void -pmhutils_wstream_delete (pmhWstream_t *pmhWstream, boolean freebuf) -{ - if (pmhWstream && freebuf && pmhWstream->buff) { - cpr_free(pmhWstream->buff); - } -} - - -boolean -pmhutils_wstream_write_line (pmhWstream_t *pmhWstream, char *this_line) -{ - - /* Sanity check */ - if (this_line == NULL || strlen(this_line) > SANITY_LINE_SIZE) { - return FALSE; - } - - if (!(pmhWstream && this_line)) { - return FALSE; - } - - while ((pmhWstream->nbytes + (int32_t)strlen(this_line)) > - pmhWstream->total_bytes) { - if (!pmhWstream->growable || - (FALSE == pmhutils_wstream_grow(pmhWstream))) { - return FALSE; - } - } - - memcpy(&pmhWstream->buff[pmhWstream->nbytes], this_line, - strlen(this_line)); - - pmhWstream->nbytes += strlen(this_line); - if (!pmhutils_wstream_write_byte(pmhWstream, '\r')) { - return FALSE; - } - - if (!pmhutils_wstream_write_byte(pmhWstream, '\n')) { - return FALSE; - } - - return TRUE; -} - -boolean -pmhutils_wstream_write_byte (pmhWstream_t *pmhWstream, char c) -{ - if (!pmhWstream) { - return FALSE; - } - - if ((pmhWstream->nbytes + 1) > pmhWstream->total_bytes) { - if (!pmhWstream->growable || - (FALSE == pmhutils_wstream_grow(pmhWstream))) { - return FALSE; - } - } - - pmhWstream->buff[pmhWstream->nbytes] = c; - pmhWstream->nbytes++; - - return TRUE; -} - -boolean -pmhutils_wstream_write_bytes (pmhWstream_t *pmhWstream, - char *inbuf, uint32_t nbytes) -{ - - if (!pmhWstream) { - return FALSE; - } - - while ((pmhWstream->nbytes + (int32_t) nbytes) > pmhWstream->total_bytes) { - if (!pmhWstream->growable || - (FALSE == pmhutils_wstream_grow(pmhWstream))) { - return FALSE; - } - } - - memcpy(&pmhWstream->buff[pmhWstream->nbytes], inbuf, nbytes); - - pmhWstream->nbytes += nbytes; - - return TRUE; -} - -boolean -pmhutils_wstream_grow (pmhWstream_t *pmhWstream) -{ - char *newbuf; - - if (!pmhWstream || !pmhWstream->buff || !pmhWstream->growable) { - return FALSE; - } - - newbuf = (char *) cpr_realloc((void *) pmhWstream->buff, - pmhWstream->total_bytes + WSTREAM_START_SIZE); - if (newbuf == NULL) { - if ((pmhWstream->total_bytes + WSTREAM_START_SIZE) != 0) { - cpr_free(pmhWstream->buff); - } - pmhWstream->buff = NULL; - return FALSE; - } - - pmhWstream->buff = newbuf; - - pmhWstream->total_bytes += WSTREAM_START_SIZE; - - return TRUE; -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_regmgr.c b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_regmgr.c deleted file mode 100644 index 9c05303dd12..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_regmgr.c +++ /dev/null @@ -1,3471 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "phntask.h" -#include "phone_types.h" -#include "phone_debug.h" -#include "util_string.h" -#include "dns_utils.h" -#include "cpr_socket.h" -#include "util_string.h" -#include "sip_common_transport.h" -#include "sip_ccm_transport.h" -#include "ccsip_messaging.h" -#include "ccsip_register.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "singly_link_list.h" -#include "uiapi.h" -#include "text_strings.h" -#include "ccsip_callinfo.h" -#include "sip_interface_regmgr.h" -#include "ccsip_task.h" -#include "cpr_rand.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_subsmanager.h" -#include "ccsip_publish.h" -#include "ccsip_platform_tls.h" - -#define REGALL_FAIL_TIME 100 -boolean regall_fail_attempt = FALSE; -boolean registration_reject = FALSE; - -int retry_times = 0; - -boolean config_update_required = FALSE; -void *new_standby_available = NULL; -sll_handle_t fallback_ccb_list; -static boolean wan_failure = FALSE; -extern ti_config_table_t CCM_Device_Specific_Config_Table[MAX_CCM]; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern uint16_t ccm_config_id_addr_str[MAX_CCM]; -#ifdef IPV6_STACK_ENABLED - -extern uint16_t ccm_config_id_ipv6_addr_str[MAX_CCM]; -#endif - -extern boolean sip_reg_all_failed; -extern void sip_platform_handle_service_control_notify(sipServiceControl_t * scp); -extern void ui_update_registration_state_all_lines(boolean registered); -extern int phone_local_tcp_port[UNUSED_PARAM]; - -ccm_failover_table_t CCM_Failover_Table; -ccm_fallback_table_t CCM_Fallback_Table; -cc_config_table_t CC_Config_Table[MAX_REG_LINES + 1]; -typedef struct fallback_line_num_t_ { - line_t line; - boolean available; -} fallback_line_num_t; - -static fallback_line_num_t fallback_lines_available[MAX_CCM - 1] = -{ - {MAX_CCBS, TRUE}, - {MAX_CCBS + 1, TRUE}, -}; - -static void sip_regmgr_update_call_ccb(void); -void sip_regmgr_fallback_generic_timer_stop(cprTimer_t timer); -boolean sip_regmgr_find_fallback_ccb_by_ccmid (CCM_ID ccm_id, ccsipCCB_t **ccb_ret); - -void sip_regmgr_clean_standby_ccb(ccsipCCB_t *ccb); -static void sip_regmgr_tls_retry_timer_start (fallback_ccb_t *fallback_ccb); -static void -sip_regmgr_generic_timer_start_failure (fallback_ccb_t *fallback_ccb, - uint32_t event) -{ - -} - -static void -sip_regmgr_generic_message_post_failure (fallback_ccb_t *fallback_ccb, - uint32_t event) -{ - -} - -/** sip_regmgr_get_fallback_ccb_list - * - * PARAMETERS: NULL, or fallback_ccb - * - * DESCRIPTION: Returns the ccb and fallback_ccb from linked list - * The first call to this function should pass in NULL - * Subsequent calls should pass the opaque (for the caller) - * token so that the next ccb is returned - * - * RETURNS: fallback_ccb as the opaque token, ccb as the return value - * - */ -ccsipCCB_t * -sip_regmgr_get_fallback_ccb_list (uint32_t *previous_data_p) -{ - fallback_ccb_t *this_fallback_ccb = NULL; - uint32_t data; - - data = (uint32_t) (*previous_data_p); - this_fallback_ccb = (fallback_ccb_t *) - sll_next(fallback_ccb_list, (void *)(long) (data)); - if (this_fallback_ccb) { - *previous_data_p = (long) (this_fallback_ccb); - return (this_fallback_ccb->ccb); - } - return NULL; -} - -/* - ** sip_regmgr_get_fallback_ccb_by_index - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: line number - * - * DESCRIPTION: Searches the linked list of fallback ccb's and - * returns the ccb that matches the line number. - * - * RETURNS: fallback_ccb if match, NULL if not. - * - */ -fallback_ccb_t * -sip_regmgr_get_fallback_ccb_by_index (line_t ndx) -{ - return (fallback_ccb_t *)(sll_find(fallback_ccb_list, (void *)(long)ndx)); -} - -/* - ** sip_regmgr_find_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: find_by_p is the dn line number that is the used to - * match with the fallback ccb's. data_p is the ccb that - * from the linked list that is checked to see if it has - * the dn number that is being searched for. - * - * DESCRIPTION: finds the fallback ccb that matched a dn line value - * This is the match routine provided while the singly - * linked list for fallback ccb's is created. sll_find() - * used this routine to perform the find. - * - * RETURNS: Indicates if match was found or not. - * - */ -sll_match_e -sip_regmgr_find_fallback_ccb (void *find_by_p, void *data_p) -{ - int to_find_ccb_index = (long) find_by_p; - fallback_ccb_t *fallback_ccb = (fallback_ccb_t *) data_p; - ccsipCCB_t *list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - - if (to_find_ccb_index == list_ccb->index) { - return (SLL_MATCH_FOUND); - } else { - return (SLL_MATCH_NOT_FOUND); - } -} - -/* - ** sip_regmgr_find_fallback_ccb_by_callid - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: Callid string and the container for the matching - * ccb, if found. - * - * DESCRIPTION: Searches the linked list of fallback ccb's and - * returns the ccb that matches the callid. - * - * RETURNS: void - * - */ -void -sip_regmgr_find_fallback_ccb_by_callid (const char *callid, - ccsipCCB_t **ccb_ret) -{ - const char fname[] = "sip_regmgr_find_fallback_ccb_by_callid"; - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *list_ccb = NULL; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Trying to find match for %s", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), callid); - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - fallback_ccb)) != NULL) { - list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - if (strcmp(callid, list_ccb->sipCallID) == 0) { - *ccb_ret = list_ccb; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Found ccb to match callid" - " line %d/%d\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - list_ccb->index, - list_ccb->dn_line); - break; - } - } -} - -/* - ** sip_regmgr_find_fallback_ccb_by_addr_port - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ipaddr and port to match and container for the ccb - * if found. - * - * DESCRIPTION: finds the fallback ccb that matched a addr:port value - * - * RETURNS: Indicates if match was found or not. - * - */ -boolean -sip_regmgr_find_fallback_ccb_by_addr_port (cpr_ip_addr_t *ipaddr, uint16_t port, - ccsipCCB_t **ccb_ret) -{ - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *list_ccb = NULL; - ti_config_table_t *cfg_table_entry; - ti_common_t *ti_common; - boolean found_ccb = FALSE; - - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - fallback_ccb)) != NULL) { - list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - cfg_table_entry = (ti_config_table_t *) - list_ccb->cc_cfg_table_entry; - ti_common = &cfg_table_entry->ti_common; - if (util_compare_ip(&(ti_common->addr), ipaddr) && ti_common->port == port) { - *ccb_ret = list_ccb; - found_ccb = TRUE; - break; - } - } - return (found_ccb); -} - -/** - ** sip_regmgr_find_fallback_ccb_by_ccmid - * finds the fallback ccb that matched a ccm id - * - * @param ccm_id ccm id to match and ccb_ret - ccb if found - * - * @return TRUE if found; else FALSE - * - */ -boolean -sip_regmgr_find_fallback_ccb_by_ccmid (CCM_ID ccm_id, ccsipCCB_t **ccb_ret) -{ - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *list_ccb = NULL; - ti_config_table_t *cfg_table_entry; - boolean found_ccb = FALSE; - - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - fallback_ccb)) != NULL) { - list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - if (list_ccb) { - cfg_table_entry = (ti_config_table_t *) - list_ccb->cc_cfg_table_entry; - if (cfg_table_entry && - (cfg_table_entry->ti_specific.ti_ccm.ccm_id == ccm_id)) { - if(ccb_ret != NULL){ - *ccb_ret = list_ccb; - } - found_ccb = TRUE; - break; - } - } - } - return (found_ccb); -} - -/* - ** sip_regmgr_get_fallback_line_num - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void - * - * DESCRIPTION: returns the fallback line number to use during - * failover while creating fallback ccb's - * - * RETURNS: line number to use. - * - */ -line_t -sip_regmgr_get_fallback_line_num () -{ - const char fname[] = "sip_regmgr_get_fallback_line_num"; - int ndx; - line_t line = 0; - - for (ndx = 0; ndx < (MAX_CCM - 1); ndx++) { - if (fallback_lines_available[ndx].available) { - fallback_lines_available[ndx].available = FALSE; - line = fallback_lines_available[ndx].line; - break; - } - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Allocated fallback line %d at index %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), line, (int) (line - MAX_CCBS)); - return (line); -} - -/* - ** sip_regmgr_return_fallback_line_num - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void - * - * DESCRIPTION: returns the fallback line number for reuse during - * failover while creating fallback ccb's - * - * RETURNS: line number to use. - * - */ -void -sip_regmgr_return_fallback_line_num (line_t num) -{ - const char fname[] = "sip_regmgr_return_fallback_line_num"; - - if (((num - MAX_CCBS) > -1) && - ((num - MAX_CCBS) < (MAX_CCM - 1))) { - fallback_lines_available[(int)(num - MAX_CCBS)].available = TRUE; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Returned fallback line %d at index %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), num, (int) (num - MAX_CCBS)); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Invalid index for fallback_lines_available %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), (int) (num - MAX_CCBS)); - } -} - -/* - ** sip_regmgr_clean_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: pointer to the fallback ccb - * - * DESCRIPTION: Clean fallback CCBs - * - * RETURNS: - * - */ -void -sip_regmgr_clean_fallback_ccb (fallback_ccb_t *fallback_ccb) -{ - if (fallback_ccb == NULL) { - return; - } - - if (fallback_ccb->ccb) { - sip_regmgr_return_fallback_line_num(fallback_ccb->ccb->index); - } - (void) cprCancelTimer(fallback_ccb->WaitTimer.timer); - (void) cprDestroyTimer(fallback_ccb->WaitTimer.timer); - fallback_ccb->WaitTimer.timer = NULL; - fallback_ccb->tls_socket_waiting = FALSE; - - (void) cprCancelTimer(fallback_ccb->RetryTimer.timer); - (void) cprDestroyTimer(fallback_ccb->RetryTimer.timer); - fallback_ccb->RetryTimer.timer = NULL; - - if (fallback_ccb->ccb) { - sip_sm_call_cleanup(fallback_ccb->ccb); - cpr_free(fallback_ccb->ccb); - fallback_ccb->ccb = NULL; - } -} - -/* - ** sip_regmgr_free_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: The fallback ccb to be deleted. - * - * DESCRIPTION: Delete a fallback ccb and its associated timers - * and removes it from the linked list - * - * RETURNS: none - */ -void -sip_regmgr_free_fallback_ccb (ccsipCCB_t *ccb) -{ - const char fname[] = "sip_regmgr_free_fallback_ccb"; - fallback_ccb_t *fallback_ccb; - - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - - if (!fallback_ccb) { - return; - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Freed fallback ccb for %s:%d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccb->reg.proxy, ccb->reg.port); - sip_regmgr_clean_fallback_ccb(fallback_ccb); - if (sll_remove(fallback_ccb_list, fallback_ccb) != SLL_RET_SUCCESS) { - CCSIP_DEBUG_ERROR("%s: sll_remove error for fallback_ccb", fname); - } - cpr_free(fallback_ccb); -} - -/* - ** sip_regmgr_cleanup_fallback_ccb_list - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: none - * - * DESCRIPTION: Delete fallback ccbs and its associated timers - * and removes it from the linked list - * - * RETURNS: none - */ -void -sip_regmgr_free_fallback_ccb_list () -{ - fallback_ccb_t *fallback_ccb = NULL; - - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, NULL)) - != NULL) { - sip_regmgr_clean_fallback_ccb(fallback_ccb); - (void) sll_remove(fallback_ccb_list, fallback_ccb); - cpr_free(fallback_ccb); - } - sll_destroy(fallback_ccb_list); - fallback_ccb_list = NULL; -} - -/* - ** sip_regmgr_create_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccm_id, dn_line of the new fallback - * ccb to be created. - * - * DESCRIPTION: Creates a new fallback ccb and its associated timers - * and adds it to the linked list. - * - * RETURNS: Indicates if the fallback ccb was created successfully - * or not. - * - */ -boolean -sip_regmgr_create_fallback_ccb (CCM_ID ccm_id, line_t dn_line) -{ - const char fname[] = "sip_regmgr_create_fallback_ccb"; - ccsipCCB_t *ccb = NULL; - boolean ccb_created = FALSE; - fallback_ccb_t *fallback_ccb; - static const char sipWaitTimerName[] = "sipWait"; - static const char sipRegRetryTimerName[] = "sipRetry"; - line_t fallback_line; - - if (((int)dn_line < 1) || ((int)dn_line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, dn_line); - return(FALSE); - } - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.", - fname, ccm_id); - return(FALSE); - } - /* Check if fallback ccb exists. If so, return */ - if (sip_regmgr_find_fallback_ccb_by_ccmid(ccm_id, NULL)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"fallback ccb exists for ccmid %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - return(TRUE); - } - fallback_line = sip_regmgr_get_fallback_line_num(); - if (!fallback_line) { - /* Couldn't get fallback line number */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"couldn't get fallback line for ccmid %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - return(FALSE); - } - fallback_ccb = (fallback_ccb_t *) cpr_calloc(1, sizeof(fallback_ccb_t)); - if (fallback_ccb) { - fallback_ccb->WaitTimer.timer = cprCreateTimer(sipWaitTimerName, - SIP_WAIT_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - fallback_ccb->RetryTimer.timer = cprCreateTimer(sipRegRetryTimerName, - SIP_RETRY_TIMER, - TIMER_EXPIRATION, - sip_msgq); - fallback_ccb->tls_socket_waiting = FALSE; - if (!fallback_ccb->WaitTimer.timer || !fallback_ccb->RetryTimer.timer) { - CCSIP_DEBUG_ERROR("%s: failed to create one or more" - " UISM timers\n", fname); - if (fallback_ccb->WaitTimer.timer) { - (void) cprCancelTimer(fallback_ccb->WaitTimer.timer); - (void) cprDestroyTimer(fallback_ccb->WaitTimer.timer); - fallback_ccb->WaitTimer.timer = NULL; - } - if (fallback_ccb->RetryTimer.timer) { - (void) cprCancelTimer(fallback_ccb->RetryTimer.timer); - (void) cprDestroyTimer(fallback_ccb->RetryTimer.timer); - fallback_ccb->RetryTimer.timer = NULL; - } - ccb_created = FALSE; - } - ccb = (ccsipCCB_t *) cpr_calloc(1, sizeof(ccsipCCB_t)); - if (ccb != NULL) { - (void) sip_sm_ccb_init(ccb, fallback_line, dn_line, - SIP_REG_STATE_IN_FALLBACK); - ccb->cc_type = CC_CCM; - ccb->cc_cfg_table_entry = CCM_Config_Table[dn_line - 1][ccm_id]; - sstrncpy(ccb->reg.proxy, - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - ccb->reg.addr = CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.addr; - ccb->reg.port = (uint16_t) - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.port; - ccb->dest_sip_addr = - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.addr; - ccb->dest_sip_port = - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.port; - ccb->local_port = CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.listen_port; - fallback_ccb->ccb = ccb; - (void) sll_append(fallback_ccb_list, fallback_ccb); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Created fallback ccb for %s:%d with line %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccb->reg.proxy, ccb->reg.port, - fallback_line); - ccb_created = TRUE; - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Memalloc failed for ccb for CCM-id %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - sip_regmgr_clean_fallback_ccb(fallback_ccb); - if (fallback_ccb) { - cpr_free(fallback_ccb); - } - } - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Memalloc failed for fallback ccb for CCM-id %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - sip_regmgr_return_fallback_line_num(fallback_line); - } - return (ccb_created); -} - -/* - ** sip_regmgr_trigger_fallback_monitor - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:void - * - * DESCRIPTION: Walks through the linked list of fallback ccbs - * and starts the retry timer on them and starts - * sending keepalive messages to monitor the failed - * ccms. - * - * RETURNS: void. - * - */ -void -sip_regmgr_trigger_fallback_monitor (void) -{ - const char fname[] = "sip_regmgr_trigger_fallback_monitor"; - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *ccb = NULL; - - /* - * Go through the linked list of failed ccm's and - * start monitoring them. - */ - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Looking to trigger fallback " - "if any available\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - do { - fallback_ccb = (fallback_ccb_t *) sll_next(fallback_ccb_list, - (void *)fallback_ccb); - if (fallback_ccb) { - ti_config_table_t *ccm_table_entry; - ccb = fallback_ccb->ccb; - if (ccb->state == (int) SIP_REG_PRE_FALLBACK) { - char user[MAX_LINE_NAME_SIZE]; - - /* - * If state is TokenWait, - * Then transition back into InFallback state. - * Else send out a keepalive message to the registration server. - */ - sip_util_get_new_call_id(ccb); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - ccm_table_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_entry->ti_common.handle != INVALID_SOCKET) { - (void) sipSPISendRegister(ccb, 0, user, 0); - } - - /* - * Start the ack, retry timer - */ - sip_regmgr_retry_timer_start(fallback_ccb); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Started monitoring %s:%d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - ccb->reg.proxy, ccb->reg.port); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"fallback is in progress ccb idx=%d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname),ccb->index); - } - } - } while (fallback_ccb); -} - -void set_active_ccm(ti_config_table_t *cfg_table_entry) { - CCM_Active_Standby_Table.active_ccm_entry = cfg_table_entry; - if (cfg_table_entry != NULL) { - DEF_DEBUG("set_active_ccm: ccm=%s port=%d", - CCM_ID_PRINT(cfg_table_entry->ti_specific.ti_ccm.ccm_id), - phone_local_tcp_port[cfg_table_entry->ti_specific.ti_ccm.ccm_id]); - } else { - DEF_DEBUG("set_active_ccm: ccm=PRIMARY port=-1"); - } -} - - -/* - ** sip_regmgr_setup_new_active_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: pointer to the cfg table entry of the call manager - * that is going to become the new active ccm. - * - * DESCRIPTION: Sets up the reg ccb's for all the lines to point - * to the new call manager during failover/fallback. - * - * RETURNS: void. - * - */ -void -sip_regmgr_setup_new_active_ccb (ti_config_table_t *cfg_table_entry) -{ - const char fname[] = "sip_regmgr_setup_new_active_ccb"; - line_t ndx; - ccsipCCB_t *line_ccb; - - for (ndx = REG_CCB_START; ndx < REG_CCB_END; ndx++) { - line_ccb = sip_sm_get_ccb_by_index(ndx); - ui_set_sip_registration_state(line_ccb->dn_line, FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), line_ccb->index); - (void) sip_platform_register_expires_timer_stop(line_ccb->index); - sip_stop_ack_timer(line_ccb); - line_ccb->reg.registered = 0; - sip_reg_sm_change_state(line_ccb, SIP_REG_STATE_IDLE); - sip_sm_call_cleanup(line_ccb); - // Since we are going to point this CCB to a new CCM, get a new call-id - line_ccb->sipCallID[0] = '\0'; - sip_util_get_new_call_id(line_ccb); - line_ccb->cc_cfg_table_entry = (void *) cfg_table_entry; - - if (cfg_table_entry == NULL) { - CCSIP_DEBUG_REG_STATE("%s: param cfg_table_entry is NULL!!!", fname); - continue; - } - else { - sstrncpy(line_ccb->reg.proxy, cfg_table_entry->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - line_ccb->dest_sip_addr = cfg_table_entry->ti_common.addr; - line_ccb->dest_sip_port = (uint16_t) cfg_table_entry->ti_common.port; - line_ccb->reg.addr = cfg_table_entry->ti_common.addr; - line_ccb->reg.port = (uint16_t) cfg_table_entry->ti_common.port; - /* - * Modify destination fields in call back timer struct - */ - (void) sip_platform_msg_timer_update_destination(line_ccb->index, - &(line_ccb->reg.addr), - line_ccb->reg.port); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Updated active to %s:%d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - line_ccb->reg.proxy, line_ccb->reg.port); - } - } - set_active_ccm(cfg_table_entry); -} - -/* - ** sip_regmgr_setup_new_standby_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: pointer to the cfg table entry of the call manager - * that is going to become the new standby ccm. - * - * DESCRIPTION: Sets up the reg backup ccb for all the lines to point - * to the new call manager during failover/fallback. - * - * RETURNS: void. - * - */ -void -sip_regmgr_setup_new_standby_ccb (CCM_ID ccm_index) -{ - const char fname[] = "sip_regmgr_setup_new_standby_ccb"; - ccsipCCB_t *ccb; - ti_config_table_t *cfg_table_entry; - - - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (((int)ccb->dn_line < 1) || ((int)ccb->dn_line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, ccb->dn_line); - return; - } - if (ccm_index >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.", - fname, ccm_index); - return; - } - cfg_table_entry = CCM_Config_Table[ccb->dn_line - 1][ccm_index]; - - ccsip_register_cleanup(ccb, FALSE); - // Since we are going to point this CCB to a new CCM, get a new call-id - ccb->sipCallID[0] = '\0'; - sip_util_get_new_call_id(ccb); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_UNREGISTERING); - ccb->cc_cfg_table_entry = (void *) cfg_table_entry; - sstrncpy(ccb->reg.proxy, cfg_table_entry->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - ccb->reg.addr = cfg_table_entry->ti_common.addr; - ccb->reg.port = (uint16_t) - cfg_table_entry->ti_common.port; - ccb->dest_sip_addr = cfg_table_entry->ti_common.addr; - ccb->dest_sip_port = cfg_table_entry->ti_common.port; - ccb->local_port = cfg_table_entry->ti_common.listen_port; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"For ccb_index=REG_BACKUP_CCB=%d, updated standby to %s:%d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - REG_BACKUP_CCB, ccb->reg.proxy, ccb->reg.port); - CCM_Active_Standby_Table.standby_ccm_entry = cfg_table_entry; -} - -/* - ** sip_regmgr_ccm_get_next - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb pointer - * - * DESCRIPTION: Gets the next ccm in the list for failover. - * - * RETURNS: pointer to the config table of the next ccm in line. - * - */ -ti_config_table_t * -sip_regmgr_ccm_get_next (ccsipCCB_t *ccb, CC_POSITION from_cc) -{ - /* - * If from_cc is ACTIVE_CC, then check to see if the current - * standby is valid. If it is then set that to be the ACTIVE_CC, - * and return that. If there is no current standby, then see if - * we have WAN failure. - * Add the failed units in the fallback ccm list and trigger - * fallback algorithm on them. - */ - const char fname[] = "sip_regmgr_ccm_get_next"; - ti_config_table_t *ccm_table_ptr = NULL, - *ccm_table_active_entry = NULL, - *ccm_table_standby_entry = NULL; - CCM_ID ccm_id, ccm_index; - CC_POSITION from_cc_save = NONE_CC; - - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - if (!ccm_table_ptr) { - return (NULL); - } - ccm_id = (ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - - /* - * Update the cfg table to invalidate the current ccm that - * has gone down in the case of tcp and create the fallback - * ccb. - * Already taken care of in the ccsip_platform_tcp.c function - * sip_tcp_createconnfailed_to_spi() - */ - if (ccm_table_ptr->ti_common.conn_type != CONN_UDP) { - int connid; - - connid = sip_tcp_fd_to_connid(ccm_table_ptr->ti_common.handle); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"clear the socket and port for " - "current active cucm_id=%d connid=%d\n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname),ccm_id, connid ); - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - ccm_table_ptr); - } - - // Update CCM status - - ui_set_ccm_conn_status(ccm_table_ptr->ti_common.addr_str, CCM_STATUS_NONE); - - - (void) sip_regmgr_create_fallback_ccb(ccm_id, ccb->dn_line); - - if (from_cc == ACTIVE_CC) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Came here from cucm", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - if (CCM_Active_Standby_Table.standby_ccm_entry) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"old ccm_id=%d new_ccm_id=%d Standby=NULL", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname), ccm_id, - CCM_Active_Standby_Table.standby_ccm_entry->ti_specific.ti_ccm.ccm_id); - ccm_table_ptr = CCM_Active_Standby_Table.standby_ccm_entry; - ccm_id = (ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - /* - * The current standby is going to be tried for the ACTIVE CC - * role, so fill the standby_ccm_entry with the next valid cc - * info. - */ - set_active_ccm(ccm_table_ptr); - CCM_Active_Standby_Table.standby_ccm_entry = NULL; - /* - * Save the ccm_table_ptr to return the correct value - */ - ccm_table_active_entry = ccm_table_ptr; - /* - * We have used the entry of the current standby for our - * active cc. So go ahead and find the new standby entry - */ - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - - ccm_table_ptr = NULL; - from_cc_save = ACTIVE_CC; - } else { - /* - * There is no Standby available and the Acitve has - * failed. No CC available. Initiate Reboot ! - */ - ccsip_register_set_register_state(SIP_REG_NO_CC); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"NO CC AVAILABLE. NEED TO REBOOT !", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - set_active_ccm(NULL); - - return (NULL); - } - } - - for (ccm_index = (CCM_ID) (ccm_id + 1); ccm_index < MAX_CCM; ccm_index++) { - ti_ccm_t *ti_ccm = &CCM_Config_Table[ccb->dn_line - 1][ccm_index]-> - ti_specific.ti_ccm; - - if (ti_ccm->is_valid) { - ccm_table_standby_entry = sip_regmgr_ccm_get_conn(ccb->dn_line, - (ti_config_table_t *) CCM_Config_Table[ccb->dn_line - 1][ccm_index]); - if (ccm_table_standby_entry == NULL) { - /* - * Create a fallback_ccm ccb and put it in a queue to use - * later (POST_FAILOVER) - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Could not set transport" - "connection to this standby. Ignore this. Continue search \n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname) ); - - (void) sip_regmgr_create_fallback_ccb(ccm_index, ccb->dn_line); - } else { - /* - * Will always be REG_BACKUP_CCB - * Found our 'next' ccm - */ - CCM_Active_Standby_Table.standby_ccm_entry = - ccm_table_standby_entry; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"new standby ccm id %d ip=%s ccm_id=%d", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname), ccm_index, - ccm_table_standby_entry->ti_common.addr_str, ti_ccm->ccm_id); - break; - } - } - } - - /* - * We can wait until the active line re-registers to trigger - * this but doing it as soon as we find there is no backup - * available - */ - if (ccm_table_standby_entry == NULL) { - /* - * regmgr - FAILOVER Trigger fallback monitoring - */ - ccsip_register_set_register_state(SIP_REG_NO_STANDBY); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Setting register state to SIP_REG_NO_STANDBY", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname) ); - - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - - sip_sm_call_cleanup(ccb); - // No new standby ccm. Cleanup standby ccm address, port and timers - sip_regmgr_clean_standby_ccb(ccb); - } - if (from_cc_save == ACTIVE_CC) { - ccm_table_ptr = ccm_table_active_entry; - } else { - ccm_table_ptr = ccm_table_standby_entry; - } - return (ccm_table_ptr); -} - -/* - ** sip_regmgr_tls_retry_timer_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer - * - * DESCRIPTION: Starts the tls retry timer on the fallback ccb - * Normally secd takes 3-6 secs to establish a connection. Start - * timer to check the status after 8s. Restart keep alive timer for the - * remaining time if socket is invalid after 8s - * - * RETURNS: void - * - */ -static void -sip_regmgr_tls_retry_timer_start (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_tls_retry_timer_start"; - ccsipCCB_t *ccb = NULL; - int timeout; - - if (!fallback_ccb) { - return; - } - ccb = fallback_ccb->ccb; - if (fallback_ccb->tls_socket_waiting) { - /* socket invalid after TLS_CONNECT_TIME(8s) - * Restart timer for the remaining time(eg:120-8 s) - */ - timeout = sip_config_get_keepalive_expires(); - - if (timeout > MAX_FALLBACK_MONITOR_PERIOD) { - timeout = MAX_FALLBACK_MONITOR_PERIOD; - } - if (timeout > TLS_CONNECT_TIME) { - timeout -= TLS_CONNECT_TIME; - } - fallback_ccb->tls_socket_waiting = FALSE; - } else { - /* start timer to monitor the socket status */ - timeout = TLS_CONNECT_TIME; - fallback_ccb->tls_socket_waiting = TRUE;; - } - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting TLS timer (%d sec)", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), timeout); - if (cprStartTimer(fallback_ccb->RetryTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, SIP_TMR_REG_RETRY); - } -} - -/* - ** sip_regmgr_retry_timer_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer - * - * DESCRIPTION: Starts the retry timer on the fallback ccb - * - * RETURNS: void - * - */ -void -sip_regmgr_retry_timer_start (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_retry_timer_start"; - ccsipCCB_t *ccb = NULL; - int timeout; - - if (!fallback_ccb) { - return; - } - - ccb = fallback_ccb->ccb; - - timeout = sip_config_get_keepalive_expires(); - - if (timeout > MAX_FALLBACK_MONITOR_PERIOD) { - timeout = MAX_FALLBACK_MONITOR_PERIOD; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting fallback timer (%d sec)", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), timeout); - - ccb->retx_flag = TRUE; - if (cprStartTimer(fallback_ccb->RetryTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, SIP_TMR_REG_RETRY); - ccb->retx_flag = FALSE; - } -} - -/* - ** sip_regmgr_retry_timeout_expire - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void *data (fallback ccb) - * - * DESCRIPTION: Is the callback function for retry timer - * - * RETURNS: void - * - */ -void -sip_regmgr_retry_timeout_expire (void *data) -{ - static const char fname[] = "sip_regmgr_retry_timeout_expire"; - fallback_ccb_t *fallback_ccb; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - fallback_ccb = (fallback_ccb_t *) data; - if (!fallback_ccb) { - return; - } - ccb = (ccsipCCB_t *) fallback_ccb->ccb; - if (ccsip_register_send_msg(SIP_TMR_REG_RETRY, ccb->index) != SIP_REG_OK) { - sip_regmgr_generic_message_post_failure(fallback_ccb, - SIP_TMR_REG_RETRY); - } -} - -/* - ** sip_regmgr_set_stability_total_msgs - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer and a boolean indicating if - * it is in a state where we are waiting for the - * phone to get idle before transitioning into token - * wait state. - * - * DESCRIPTION: Starts the stability timer on the fallback ccb - * - * RETURNS: void - * - */ -void -sip_regmgr_set_stability_total_msgs (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_set_stability_total_msgs"; - ccsipCCB_t *ccb = NULL; - int timer_keepalive_expires; - int connection_mode_duration; - - if (!fallback_ccb) { - return; - } - ccb = fallback_ccb->ccb; - - config_get_value(CFGID_CONN_MONITOR_DURATION, - &connection_mode_duration, sizeof(connection_mode_duration)); - - timer_keepalive_expires = sip_config_get_keepalive_expires(); - - /* Stability count is used to wait to make sure that wan is not flapping */ - fallback_ccb->StabilityMsgCount = connection_mode_duration / timer_keepalive_expires; - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting stability msg count as %d", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), - fallback_ccb->StabilityMsgCount); -} - -/* - ** sip_regmgr_wait_timer_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer - * - * DESCRIPTION: Starts the wait timer on the fallback ccb - * - * RETURNS: void - * - */ -void -sip_regmgr_wait_timer_start (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_wait_timer_start"; - ccsipCCB_t *ccb = NULL; - int timeout; - - if (!fallback_ccb) { - return; - } - ccb = fallback_ccb->ccb; - - timeout = sip_config_get_keepalive_expires(); - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting wait timer (%d sec)", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), timeout); - - if (cprStartTimer(fallback_ccb->WaitTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, SIP_TMR_REG_WAIT); - } -} - -/* - ** sip_regmgr_wait_timeout_expire - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void *data (fallback ccb) - * - * DESCRIPTION: Is the callback function for wait timer - * - * RETURNS: void - * - */ -void -sip_regmgr_wait_timeout_expire (void *data) -{ - static const char fname[] = "sip_regmgr_wait_timeout_expire"; - fallback_ccb_t *fallback_ccb; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - fallback_ccb = (fallback_ccb_t *) data; - ccb = (ccsipCCB_t *) fallback_ccb->ccb; - - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - - if (ccsip_register_send_msg(SIP_TMR_REG_WAIT, ccb->index) != SIP_REG_OK) { - sip_regmgr_generic_message_post_failure(fallback_ccb, SIP_TMR_REG_WAIT); - } -} - -void -sip_regmgr_fallback_generic_timer_stop (cprTimer_t timer) -{ - static const char fname[] = "sip_regmgr_fallback_generic_timer_stop"; - - if (cprCancelTimer(timer) == CPR_FAILURE) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"%s failed!", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), "cprCancelTimer"); - } - - return; -} - - -/* - ** sip_regmgr_ev_fallback_retry - * - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: Event handler for 4xx, 5xx, 6xx responses in fallback state - * Start retry timer to monitor the fallback ccm - * Wait for the timer to pop to send the next keepalive. - * - * - * RETURNS: void - * - */ -void -sip_regmgr_ev_fallback_retry (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_fallback_retry"; - fallback_ccb_t *fallback_ccb = NULL; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Recd retry event for LINE %d/%d in state %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccb->index, ccb->dn_line, ccb->state); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - free_sip_message(event->u.pSipMessage); -} - -void -sip_regmgr_ev_default (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_default"; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a default event in state %d", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname), ccb->state); - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - sip_regmgr_ev_tmr_ack_retry(ccb, event); - /* only free SIP messages, timeouts are internal */ - if (event->type < (int) E_SIP_REG_TMR_ACK) { - free_sip_message(event->u.pSipMessage); - } -} - -/* - ** sip_regmgr_ev_tmr_ack_retry - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: Event handler for ack and retry timers. Please - * see inline comments for the description. - * - * RETURNS: void - * - */ -void -sip_regmgr_ev_tmr_ack_retry (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_tmr_ack_retry"; - ti_config_table_t *ccm_table_ptr; - fallback_ccb_t *fallback_ccb; - CCM_ID current_standby_ccm_id, fallback_ccm_id; - - /* - * If state is REGISTERING, set state to IN_FAILOVER. - * Mark all lines as unregistered and IDLE state. - * Create fallback ccb for the failed ccm and put it in - * a queue to be triggered post failover. - * Find the "next" ccm and set the values in the ccb. - * Need change state to IDLE and post REG_REQ, make sure - * we set the no_dns_lookup parameter to 1. - * If state is IN_FALLBACK, send register message - * If state is STABILITY_CHECK, transition back to IN_FALLBACK - * and send register with expire 0. - * If state is TOKEN_WAIT, transition back to IN_FALLBACK - * and send register with expire 0. - */ - ccb->retx_counter = 0; - switch ((sipRegSMStateType_t) ccb->state) { - case SIP_REG_STATE_REGISTERED: - /* - * A send failure on a tcp for active cc could have caused - * this message. - * Fall through and do the same as what is done when in - * REGISTERING State. - */ - case SIP_REG_STATE_REGISTERING: - /* - * Get the next ccm to use as active. - */ - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr != CCM_Active_Standby_Table.active_ccm_entry) { - break; - } - ccm_table_ptr = NULL; - - ccm_table_ptr = sip_regmgr_ccm_get_next(ccb, ACTIVE_CC); - - if (ccm_table_ptr == NULL) { - /* - * Send indication of REG_ALLFAIL so platform can - * initiate a reboot. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to get next ccm!", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - // Cleanup fallback CCB list - sip_regmgr_free_fallback_ccb_list(); - sip_reg_all_failed = TRUE; - sip_regmgr_handle_reg_all_fail(); - break; - } - - CCSIP_DEBUG_REG_STATE("%s: ccb information: ccb->dn_line=%d, ccb->index=%d, retry_times=%d", - fname, ccb->dn_line, ccb->index, retry_times); - - CCM_Failover_Table.failover_ccm_entry = ccm_table_ptr; - CCM_Failover_Table.failover_started = TRUE; - CCM_Failover_Table.prime_registered = FALSE; - CCM_Fallback_Table.fallback_ccm_entry = NULL; - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - sip_platform_msg_timer_stop(ccb->index); - sip_platform_failover_ind(ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - - /* - * Notes for case: (CSCsx60672) - * We should change the info in REG_BACKUP_CCB for the case that: - * Active CCB failover - * previous standby CCM is set as CCM_Active_Standby_Table.active_ccm_entry (#1 IPAddr A) - * Third CCM would be set as CCM_Active_Standby_Table.standby_ccm_entry (#2 IPAddr B) - * - * if (#2) failover before Jphone callback, - * The REG_BACKUP_CCB would still store the #1's info - * So the call flows would prompt the wrong info(#1 IPAddr A) to Jphone, in this case, (#2 IPAddr B) - * should be prompted - * - * We need to update the REG_BACKUP_CCB's info here - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) - { - ti_ccm_t *ti_ccm = &(CCM_Active_Standby_Table.standby_ccm_entry->ti_specific.ti_ccm); - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - CCSIP_DEBUG_REG_STATE("%s: Setup new standby ccb, ccm_id is %d", fname, ti_ccm->ccm_id); - } - - break; - case SIP_REG_STATE_UNREGISTERING: - - if (ccb->index == REG_BACKUP_CCB) { - sip_stop_ack_timer(ccb); - sip_platform_msg_timer_stop(ccb->index); - ccm_table_ptr = sip_regmgr_ccm_get_next(ccb, STANDBY_CC); - if (ccm_table_ptr) { - /* - * New standby, start monitoring it. - * Change the ip addr and port to point to the new ccm - * Set the CC_CONFIG_TABLE entry for all the lines to - * point to the new ccm. - * Set the ccb->cc_cfg_table_entry with the new entry. - */ - ti_ccm_t *ti_ccm; - - ti_ccm = &ccm_table_ptr->ti_specific.ti_ccm; - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new standby cc", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - - ui_set_ccm_conn_status(ccm_table_ptr->ti_common.addr_str, - CCM_STATUS_STANDBY); - - } else { - CCM_Active_Standby_Table.standby_ccm_entry = NULL; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to get next standby ccm !", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } - sip_regmgr_trigger_fallback_monitor(); - } else { - /* - * Received a timeout when the active tried to unregister - * after the expires timer. - */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - - /* - * Always check how sip_sm_call_cleanup is implemented. - * The function has a tendency to change. - */ - sip_sm_call_cleanup(ccb); - } - - break; - case SIP_REG_STATE_STABILITY_CHECK: - /* - * We getting here means that the wan link could have gone - * down again. We stop the timers associated with the - * carefree algorithm and transition back to the - * IN_FALLBACK state. - */ - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - } - /* - * FALL THROUGH ALERT to the next state. - */ - /*sa_ignore FALL_THROUGH*/ - case SIP_REG_STATE_TOKEN_WAIT: - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - /* - * FALL THROUGH ALERT ! get into the next case and - * start sending of keepalives to the newly failed - * ccm. - */ - /*sa_ignore FALL_THROUGH*/ - case SIP_REG_STATE_IN_FALLBACK: - /* - * Send Register msg with expiry set to zero (poll) - */ - { - char user[MAX_LINE_NAME_SIZE]; - fallback_ccb_t *fallback_ccb2; - ti_config_table_t *ccm_table_entry; - - fallback_ccb2 = (fallback_ccb_t *) sll_find(fallback_ccb_list, - (void *)(long)ccb->index); - ccm_table_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - /* - * Check here to see if we still need this fallback ccb - * to be polling its ccm. The reason is that one of the - * ccms that has a higher precedence to this ccm could have - * come back online, in which case we can stop monitoring - * this ccm. - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) { - current_standby_ccm_id = CCM_Active_Standby_Table. - standby_ccm_entry->ti_specific.ti_ccm.ccm_id; - fallback_ccm_id = ccm_table_entry->ti_specific.ti_ccm.ccm_id; - - if (current_standby_ccm_id < fallback_ccm_id) { - /* - * Clean the current fallback ccb and free it - */ - DEF_DEBUG(DEB_F_PREFIX"Freeing the fallback ccb for %d ccm as current standby" - " is %d ccm!\n", - DEB_F_PREFIX_ARGS(SIP_REG_FREE_FALLBACK, fname), - fallback_ccm_id, current_standby_ccm_id); - sip_regmgr_free_fallback_ccb(ccb); - break; - } - } - - /* - * For the TCP case where a connection has gone down, - * We need to first try and setup the connection as - * part of the recovery process. After that is when we - * can start sending the keepalive messages. The following - * 'if' block handles that case. The socket handle of the - * config table is inited to INVALID_SOCKET when the connection - * goes down. - */ - if ((ccb->cc_type == CC_CCM) - && (ccm_table_entry->ti_common.handle == INVALID_SOCKET)) { - ti_common_t *ti_common; - sipSPIMessage_t sip_msg; - uint16_t listener_port; - ti_ccm_t *ti_ccm; - CONN_TYPE conn_type = CONN_NONE; - cpr_socket_t server_conn_handle = INVALID_SOCKET; - - ti_common = &ccm_table_entry->ti_common; - sip_msg.createConnMsg.addr = ti_common->addr; - sip_msg.createConnMsg.port = ti_common->port; - sip_msg.context = NULL; - ti_ccm = &ccm_table_entry->ti_specific.ti_ccm; - - if (((ti_ccm->sec_level == AUTHENTICATED) || - (ti_ccm->sec_level == ENCRYPTED)) && - (ti_common->conn_type == CONN_TLS)) { - sip_msg.context = NULL; - if (fallback_ccb2 && (fallback_ccb2->tls_socket_waiting)) { - /* socket invalid after TLS_CONN_TIME - * Restart timer for the remaining time - */ - sip_regmgr_tls_retry_timer_start(fallback_ccb2); - break; - } - server_conn_handle = sip_tls_create_connection(&sip_msg, - FALSE, - ti_ccm->sec_level); - conn_type = CONN_TLS; - } else { - server_conn_handle = sip_tcp_create_connection(&sip_msg); - } - phone_local_tcp_port[ccm_table_entry->ti_specific.ti_ccm.ccm_id] = - sip_msg.createConnMsg.local_listener_port; - if (server_conn_handle != INVALID_SOCKET) { - listener_port = sip_msg.createConnMsg.local_listener_port; - sipTransportSetServerHandleAndPort(server_conn_handle, - listener_port, - ccm_table_entry); - ccb->local_port = listener_port; - if ((conn_type == CONN_TLS) && fallback_ccb2) { - /* start timer to monitor the tls connect status */ - sip_regmgr_tls_retry_timer_start(fallback_ccb2); - break; - } - } else { - CCSIP_DEBUG_ERROR("%s: Error: " - "sip_platform_tcp_channel_create(" - "server addr=%s, server port=%d) " - "failed.\n", fname, ti_common->addr_str, - ti_common->port); - if (fallback_ccb2) { - sip_regmgr_retry_timer_start(fallback_ccb2); - } - break; - } - } - /* - * Send a keepalive message and hope to get a reply back - */ - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - sip_util_get_new_call_id(ccb); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - /* - * Start the retry timer - */ - (void) sipSPISendRegister(ccb, 0, user, 0); - if (fallback_ccb2) { - sip_regmgr_retry_timer_start(fallback_ccb2); - } - break; - } - default: - break; - } -} - -/* - ** sip_regmgr_ev_in_fallback_2xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Event handler for the all responses - * - * RETURNS: - * - */ -void -sip_regmgr_ev_in_fallback_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_in_fallback_2xx"; - sipMessage_t *response = event->u.pSipMessage; - int status_code = 0; - fallback_ccb_t *fallback_ccb; - - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), status_code); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->RetryTimer.timer); - } - sip_regmgr_check_and_transition(ccb); - free_sip_message(response); -} - -/* - ** sip_regmgr_ev_stability_check_2xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Event handler for the all responses - * - * RETURNS: - * - */ -void -sip_regmgr_ev_stability_check_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_stability_check_2xx"; - fallback_ccb_t *fallback_ccb; - sipMessage_t *response = event->u.pSipMessage; - int status_code = 0; - - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), status_code); - - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (!fallback_ccb) { - free_sip_message(response); - return; - } - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->RetryTimer.timer); - /* - * Update stats here ? - */ - if (fallback_ccb->StabilityMsgCount > 0) { - fallback_ccb->StabilityMsgCount--; - } - if (fallback_ccb->StabilityMsgCount) { - sip_regmgr_wait_timer_start(fallback_ccb); - } else { - wan_failure = FALSE; - sip_regmgr_check_and_transition(ccb); - } - free_sip_message(response); -} - -/* - ** sip_regmgr_ev_stability_check_tmr_wait - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_ev_stability_check_tmr_wait (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_stability_check_tmr_wait"; - fallback_ccb_t *fallback_ccb; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } -} - -/* - ** sip_regmgr_ev_token_wait_2xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: TOKEN_WAIT state, set expire timer and transition - * to IDLE state. - * - * RETURNS: none - */ -void -sip_regmgr_ev_token_wait_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_token_wait_2xx"; - fallback_ccb_t *fallback_ccb; - sipMessage_t *response; - int status_code = 0; - CCM_ID fallback_ccm_id; - ti_config_table_t *fallback_ccb_entry; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname), status_code); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - - } - fallback_ccb_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - fallback_ccm_id = fallback_ccb_entry->ti_specific.ti_ccm.ccm_id; - - if (CCM_Fallback_Table.fallback_ccm_entry == NULL) { - CCM_Fallback_Table.fallback_ccm_entry = (ti_config_table_t *) - ccb->cc_cfg_table_entry; - CCM_Fallback_Table.is_idle = FALSE; - CCM_Fallback_Table.is_resp = FALSE; - CCM_Fallback_Table.ccb = ccb; - sip_platform_fallback_ind(fallback_ccm_id); - - } else { - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - } - - free_sip_message(response); -} - -/* - ** sip_regmgr_ev_cleanup - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: cleanup primary - * - * RETURNS: none - */ -void -sip_regmgr_ev_cleanup (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_cleanup"; - CCM_ID ccm_id; - ti_config_table_t *cfg_table_entry; - ccsipCCB_t *line_ccb = NULL; - ti_common_t *ti_common; - - CCSIP_DEBUG_REG_STATE("%s:", fname); - line_ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - if (ccb == NULL || line_ccb == NULL) { - CCSIP_DEBUG_REG_STATE("%s: invalid ccb or line_ccb", fname); - return; - } - - cfg_table_entry = (ti_config_table_t *) line_ccb->cc_cfg_table_entry; - /* - * Setup the new active cc - */ - sip_regmgr_setup_new_active_ccb((ti_config_table_t *) - ccb->cc_cfg_table_entry); - sip_regmgr_free_fallback_ccb(ccb); - /* - * Initiate registering with the new active cc - */ - if (CCM_Fallback_Table.is_resp) { - CCSIP_DEBUG_REG_STATE("%s: Register all lines", fname); - ccsip_register_all_lines(); - CCM_Fallback_Table.fallback_ccm_entry = NULL; - } else { - CCSIP_DEBUG_REG_STATE("%s: Register prime line", fname); - sip_regmgr_register_lines(TRUE, FALSE); - CCM_Failover_Table.prime_registered = TRUE; - } - //set status of current standby to NONE - if (CCM_Active_Standby_Table.standby_ccm_entry) { - ti_config_table_t *standby_table_entry; - - standby_table_entry = CCM_Active_Standby_Table.standby_ccm_entry; - - ui_set_ccm_conn_status(standby_table_entry->ti_common.addr_str, - CCM_STATUS_NONE); - - } - /* - * Setup the new standby. - * CCM will close the TCP connection after unregistering from the - * current active ccm if connection type is TCP/TLS - * Close the TCP connection if one exists and open a new one - */ - if (cfg_table_entry != NULL) { - ti_common = &cfg_table_entry->ti_common; - if (ti_common->conn_type != CONN_UDP) { - if (ti_common->handle != INVALID_SOCKET) { - int connid; - - CCSIP_DEBUG_REG_STATE("%s: Close the TCP connection", fname); - connid = sip_tcp_fd_to_connid(ti_common->handle); - sip_tcp_purge_entry(connid); - ti_common->handle = INVALID_SOCKET; - } - CCSIP_DEBUG_REG_STATE("%s: Open a new connection", fname); - (void) sip_regmgr_ccm_get_conn(line_ccb->dn_line, cfg_table_entry); - } - ccm_id = cfg_table_entry->ti_specific.ti_ccm.ccm_id; - sip_regmgr_setup_new_standby_ccb(ccm_id); - } - /* - * Trigger monitoring the new standby - */ - (void) ccsip_register_send_msg(SIP_REG_CANCEL, REG_BACKUP_CCB); - - sip_platform_set_ccm_status(); -} - -/* - ** sip_regmgr_ev_token_wait_4xx_n_5xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: TOKEN_WAIT state, set expire timer and transition - * to IDLE state. - * - * RETURNS: none - */ -void -sip_regmgr_ev_token_wait_4xx_n_5xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_token_wait_4xx_n_5xx"; - fallback_ccb_t *fallback_ccb; - sipMessage_t *response; - int status_code = 0; - uint32_t retry_after = 0; - const char *msg_ptr = NULL; - int timeout = 0; - - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname), status_code); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (!fallback_ccb) { - return; - } - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - // Look for retry-after tag - if (status_code == SIP_CLI_ERR_BUSY_HERE || - status_code == SIP_SERV_ERR_UNAVAIL) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Received a 486/503 response!", - DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - msg_ptr = sippmh_get_header_val(response, - (const char *)SIP_HEADER_RETRY_AFTER, - NULL); - if (msg_ptr) { - retry_after = strtoul(msg_ptr, NULL, 10); - } - /* - * Start timer with the retry-after value - */ - if (retry_after > 0) { - timeout = retry_after; - } else { - // use keep alive timer if retry_after in 486 is missing or 0 - timeout = sip_config_get_keepalive_expires(); - } - if (cprStartTimer(fallback_ccb->WaitTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, - SIP_TMR_REG_WAIT); - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Started timer with retry-after for %d secs", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), timeout); - } else { - /* - * Unhandled 4xx message. start monitoring fallback ccb - */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - sip_regmgr_retry_timer_start(fallback_ccb); - } -} - -void -sip_regmgr_ev_token_wait_tmr_wait (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_token_wait_tmr_wait"; - fallback_ccb_t *fallback_ccb; - - /* - * Send a REFER message requesting for registering with - * the callmanager that has come back up. Cleanup any - * pending REFER transaction as new REFER is created for - * next transmission. - */ - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - if (sipSPISendRefer(ccb, TOKEN_REFER_TO, SIP_REF_TOKEN)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Successfully sent a REFER" - " for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Error while trying to send" - " REFER for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } -} - -/* - ** sip_regmgr_check_and_transition - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Check and transition states - * - * RETURNS: void - * - */ -void -sip_regmgr_check_and_transition (ccsipCCB_t *ccb) -{ - static const char fname[] = "sip_regmgr_check_and_transition"; - - /* - * This routine gets called from IN_FALLBACK state when we - * receive a response to a keepalive message -or- from the - * STABILITY Check state when the Carefree algorithm successfully - * completes. - * If state is IN_FALLBACK and wan_failure is TRUE, transition - * to STABILITY_CHECK state and start the CAREFREE Algorithm. - * Else transition to the TOKEN_WAIT State.and send the refer - * message requesting for a token to register. - */ - if (!ccb) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Received event for invalid ccb", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - return; - } - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - if (wan_failure) { - /* - * Kick off the Carefree algorithm. Transition to STABILITY CHECK - * state - */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_STABILITY_CHECK); - sip_regmgr_set_stability_total_msgs( - sip_regmgr_get_fallback_ccb_by_index(ccb->index)); - sip_regmgr_wait_timer_start( - sip_regmgr_get_fallback_ccb_by_index(ccb->index)); - } else { - /* - * Check to see if the ccm coming backup is going to - * replace the current active, if not just replace the - * current Standby - */ - ti_config_table_t *ccm_table_entry, *fallback_ccb_entry; - CCM_ID current_ccm_id, fallback_ccm_id; - fallback_ccb_t *fallback_ccb; - - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - ccm_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - current_ccm_id = ccm_table_entry->ti_specific.ti_ccm.ccm_id; - - fallback_ccb_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - fallback_ccm_id = fallback_ccb_entry->ti_specific.ti_ccm.ccm_id; - /* - * Check to see if the current ccm coming back up is going to - * replace the current active ccm - */ - if (current_ccm_id > fallback_ccm_id) { - if ((sip_platform_is_phone_idle()) && - (CCM_Fallback_Table.fallback_ccm_entry == NULL)) { - /* - * Send a REFER message requesting for registering with - * the callmanager that has come back up. Cleanup any - * existing REFER transactions before creating a new - * REFER - */ - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - if (sipSPISendRefer(ccb, TOKEN_REFER_TO, SIP_REF_TOKEN)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Successfully sent a REFER" - " for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_TOKEN_WAIT); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Error while trying to send" - " REFER for token registration!\n", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"phone not idle or fallback ccm entry non NULL", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - // Send keep alive if phone not idle - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - return; - } - } else if (current_ccm_id == fallback_ccm_id) { - CCSIP_DEBUG_REG_STATE("%s: Current ccm coming back up is the current active ccm", fname); - // Do nothing - } else { - /* - * Falling back as the standby. - * Any CCM coming back up will either replace the - * active or standby ccm. In this case it is not the - * active, so replace the standby ccm. - */ - ccsipCCB_t *backup_ccb; - ti_config_table_t *ccm_table_entry2; - ti_ccm_t *ti_ccm; - CCM_ID ccm_id; - - ccm_table_entry2 = (ti_config_table_t *) - ccb->cc_cfg_table_entry; - ti_ccm = &ccm_table_entry2->ti_specific.ti_ccm; - ccm_id = ti_ccm->ccm_id; - - backup_ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (CCM_Active_Standby_Table.standby_ccm_entry) { - int16_t trx_index; - ti_config_table_t *standby_ccm_entry = NULL; - CCM_ID standby_ccmid; - - standby_ccm_entry = CCM_Active_Standby_Table.standby_ccm_entry; - standby_ccmid = standby_ccm_entry->ti_specific.ti_ccm.ccm_id; - - // Check to see if the ccm coming back up is going to - // replace the current standby ccm. - if (standby_ccmid < ccm_id) { - /* - * Clean the current fallback ccb and free it - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Freeing the fallback ccb" - " for %d ccm as current standby" - " is %d ccm!\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - ccm_id, standby_ccmid); - sip_regmgr_free_fallback_ccb(ccb); - return; - } - /* - * Check to see if there is a transaction pending. - * If so wait for the final response, else proceed. - */ - trx_index = get_method_request_trx_index(backup_ccb, - sipMethodRegister, - TRUE); - if (trx_index >= 0) { - if (new_standby_available == NULL) { - new_standby_available = (void *) ccm_table_entry2; - } else { - /* - * There is already a ccm waiting to - * transition into being the standby ccm. - * Check current ccm id with the one - * waiting to see who is a better fit. - */ - ti_config_table_t *waiting_standby; - CCM_ID this_ccm_id, waiting_ccm_id; - - waiting_standby = (ti_config_table_t *) - new_standby_available; - waiting_ccm_id = waiting_standby-> - ti_specific.ti_ccm.ccm_id; - this_ccm_id = ccm_table_entry2-> - ti_specific.ti_ccm.ccm_id; - if (waiting_ccm_id > this_ccm_id) { - new_standby_available = (void *) - ccm_table_entry2; - } - } - } else { - - ti_config_table_t *standby_ccm_entry2; - - standby_ccm_entry2 = (ti_config_table_t *) - backup_ccb->cc_cfg_table_entry; - // Update CCM Status - ui_set_ccm_conn_status(standby_ccm_entry2->ti_common.addr_str, - CCM_STATUS_NONE); - if (standby_ccm_entry2->ti_common.conn_type == CONN_TCP) { - /* - * Clean up the socket of the current standby - * if tcp. - */ - int connid; - - connid = sip_tcp_fd_to_connid(standby_ccm_entry2-> - ti_common.handle); - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - (ti_config_table_t *)(backup_ccb->cc_cfg_table_entry)); - } - ui_set_ccm_conn_status(ccm_table_entry2->ti_common.addr_str, - CCM_STATUS_STANDBY); - - sip_regmgr_setup_new_standby_ccb(ccm_id); - sip_regmgr_free_fallback_ccb(ccb); - /* - * New standby, start monitoring it. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new" - " standby cc \n", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, - backup_ccb->index); - } - } else { - /* - * Here there is no current standby, so simply - * make the current ccm the standby ccm and start - * monitoring it. - */ - - ui_set_ccm_conn_status(ccm_table_entry2->ti_common.addr_str, - CCM_STATUS_STANDBY); - - sip_regmgr_setup_new_standby_ccb(ccm_id); - sip_regmgr_free_fallback_ccb(ccb); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new" - " standby cc \n", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, - backup_ccb->index); - } - } - } -} - -/* - ** sip_regmgr_ev_failure_response - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_ev_failure_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_failure_response"; - int timeout; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - if (ccb->index == REG_BACKUP_CCB) { - /* - * Keep monitoring. - * Stay in unregistering state and wait for the - * expires timer to pop to send the next keepalive. - */ - - timeout = sip_config_get_keepalive_expires(); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Starting keep alive timer %d sec", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), timeout); - (void) sip_platform_standby_keepalive_timer_start(timeout * 1000); - - } else { - // Do not Initiate failover; Need not wait for the the ack_timer - if (sip_regmgr_get_cc_mode(1) == REG_MODE_CCM) { - config_update_required = TRUE; - } - - /* - * Send indication of REG_ALLFAIL so platform can - * initiate a reboot. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Registration rejected.", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - // Cleanup fallback CCB list - sip_regmgr_free_fallback_ccb_list(); - sip_reg_all_failed = TRUE; - sip_regmgr_handle_reg_all_fail(); - - } -} - -/* - ** sip_regmgr_ev_cancel - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_ev_cancel (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_cancel"; - char user[MAX_LINE_NAME_SIZE]; - - /* - * If state is TokenWait, - * Then transition back into InFallback state. - * Else send out a keepalive message to the registration server. - * Note: Need to rename the event ??? - */ - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - sip_util_get_new_call_id(ccb); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - - (void) sipSPISendRegister(ccb, 0, user, 0); -} - -/* - ** sip_regmgr_ccm_get_conn - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -ti_config_table_t * -sip_regmgr_ccm_get_conn (line_t dn, ti_config_table_t *ccm_entry) -{ - /* - * Just check for the validity of the cpr_socket - * and return the entry. - */ - if (ccm_entry->ti_common.handle != INVALID_SOCKET) { - return (ccm_entry); - } else { - /* - * Create a socket to the ccm - */ - conn_create_status_t conn_status; - - conn_status = sip_transport_setup_cc_conn(dn, ccm_entry-> - ti_specific.ti_ccm.ccm_id); - if (conn_status == CONN_SUCCESS) { - return (ccm_entry); - } else { - return (NULL); - } - } -} - -/* - ** sip_regmgr_setup_cc_conns - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void - * - * DESCRIPTION: Replaces SIPTaskConnectToSipProxies - * - * RETURNS: - * - */ -static int -sip_regmgr_setup_cc_conns () -{ - const char *fname = "sip_regmgr_setup_cc_conns"; - RET_CODE ret_code = RET_SUCCESS; - CCM_ID cc_index; - cpr_socket_t active_fd = INVALID_SOCKET, - standby_fd = INVALID_SOCKET; - line_t line; - conn_create_status_t conn_status; - - /* - * We assume only one type of call control in the phone - * either ccm / csps. That is the reason for only one check - * When we support both ccm and csps on the same phone (on - * multiple lines we will need to check each line's cc_type - * and take the appropriate action. - */ - if (CC_Config_Table[0].cc_type == CC_CCM) { - /* - * Find the active and standby connections for - * ccm. - */ - for (cc_index = PRIMARY_CCM; cc_index < MAX_CCM; cc_index++) { - line = 1; - - /* - * Note: The opening of sockets will fail only in the - * case of tcp/tls connections. In the case of udp, - * the socket will get opened and the failure to reach - * the destination will come in the form of timeouts/ - * icmp unreachable messages. - */ - conn_status = sip_transport_setup_cc_conn(line, cc_index); - if (conn_status == CONN_SUCCESS) { - if (active_fd == INVALID_SOCKET) { - /* - * Found Active fd and active_fd is not set - * Save it for all lines. - */ - active_fd = CCM_Config_Table[line - 1][cc_index]->ti_common.handle; - set_active_ccm(CCM_Config_Table[line - 1][cc_index]); - } else { - /* - * Found Standby fd. Save it in the local table. - * and break out of loop. - */ - standby_fd = CCM_Config_Table[line - 1] - [cc_index]->ti_common.handle; - CCM_Active_Standby_Table.standby_ccm_entry = - CCM_Config_Table[line - 1][cc_index]; - break; - } - } else if (conn_status == CONN_FAILURE) { - /* - * We can get this return code when connecting to - * a server that uses UDP such as Asterisk. If that is the - * case we then change the connection type to UDP and - * attempt reconnection. - * - */ - - // change trans layer protocol to UDP - CC_Config_setIntValue(CFGID_TRANSPORT_LAYER_PROT, 2); - CCSIP_DEBUG_ERROR("%s: Attempting reconnection using UDP", fname); - - // attempt re-connection - sipTransportInit(); - - conn_status = sip_transport_setup_cc_conn(line, cc_index); - if (conn_status == CONN_SUCCESS) { - if (active_fd == INVALID_SOCKET) { - /* - * Found Active fd and active_fd is not set - * Save it for all lines. - */ - active_fd = CCM_Config_Table[line - 1][cc_index]->ti_common.handle; - set_active_ccm(CCM_Config_Table[line - 1][cc_index]); - } else { - /* - * Found Standby fd. Save it in the local table. - * and break out of loop. - */ - standby_fd = CCM_Config_Table[line - 1] - [cc_index]->ti_common.handle; - CCM_Active_Standby_Table.standby_ccm_entry = - CCM_Config_Table[line - 1][cc_index]; - break; - } - } else if (conn_status == CONN_FAILURE) { - - /* - * We get this return code when we have the address - * configured and we are not able to setup the - * connection to the ccm. - * Candidate for fallback monitoring. Note it in the - * ccm_config_table and add it to a fallback monitor - * table. - * - */ - CCSIP_DEBUG_ERROR("%s: Socket open failure: DN <%d> CCM <%d>", - fname, line, cc_index); - (void) sip_regmgr_create_fallback_ccb(cc_index, line); - ret_code = RET_START_FALLBACK; - } - } - } - if (active_fd == INVALID_SOCKET) { - /* - * No CC present for any calls from this phone. - */ - CCSIP_DEBUG_ERROR("%s: NO CALL CONTROL AVAILABLE! Init a reboot!", - fname); - set_active_ccm(&CCM_Dummy_Entry); - - /* - * RegMgr Interface call, ALL_FAIL - */ - ret_code = RET_INIT_REBOOT; - } else if (standby_fd == INVALID_SOCKET) { - /* - * No Standby CC present for this phone. - */ - CCSIP_DEBUG_ERROR("%s: NO VALID STANDBY CALL CONTROL AVAILABLE!", - fname); - ret_code = RET_NO_STANDBY; - } - } else { - /* - * Non CCM Case - */ - for (line = 1; line <= MAX_REG_LINES; line++) { - conn_status = sip_transport_setup_cc_conn(line, UNUSED_PARAM); - } - } - return (ret_code); -} - -/* - ** sip_regmgr_destroy_cc_conns - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Replaces SIPTaskDisconnectFromSipProxies - * - * RETURNS: - * - */ -int -sip_regmgr_destroy_cc_conns (void) -{ - const char *fname = "sip_regmgr_destroy_cc_conns"; - line_t dn, max_iteration; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Destroying connections", DEB_F_PREFIX_ARGS(SIP_CC_CONN, fname)); - if (CC_Config_Table[LINE1].cc_type == CC_CCM) { - /* - * The first iteration of calling sip_transport_destroy_cc_conn - * will close all the connections entries for pri, sec, tertiary - * connections. - */ - max_iteration = 1; - } else { - max_iteration = MAX_REG_LINES; - } - - for (dn = 1; dn <= max_iteration; dn++) { - /* - * Not checking if it is the active ccm connection that is getting torn down. - * Here we are killing everything so does'nt matter. - * Something else has triggered the closing of the tcp conns. - * So the unreg reason should be set by now. - * In theory we should never see this getting set. - */ - sip_transport_destroy_cc_conn(dn, PRIMARY_CCM); - } - return (0); -} - -/* - ** sip_regmgr_init - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -int -sip_regmgr_init (void) -{ - RET_CODE ret_code = RET_SUCCESS; - - /* - * Create the fallback ccb link list, that will hold - * the fallback ccb's of the failed ccm's - */ - fallback_ccb_list = sll_create(sip_regmgr_find_fallback_ccb); - ret_code = (RET_CODE) sip_regmgr_setup_cc_conns(); - if (ret_code == RET_START_FALLBACK || ret_code == RET_NO_STANDBY) { - sip_regmgr_trigger_fallback_monitor(); - } else if (ret_code == RET_INIT_REBOOT) { - /* - * Send indication of REG_ALLFAIL so platform can - * initiate a reboot. - */ - // Cleanup fallback CCB list - sip_regmgr_free_fallback_ccb_list(); - sip_reg_all_failed = TRUE; - sip_regmgr_handle_reg_all_fail(); - return (SIP_ERROR); - } - CCM_Fallback_Table.fallback_ccm_entry = NULL; - CCM_Fallback_Table.is_idle = FALSE; - CCM_Fallback_Table.is_resp = FALSE; - CCM_Failover_Table.failover_started = FALSE; - sip_reg_all_failed = FALSE; - retry_times = 0; - - return (SIP_OK); -} - - -/* - ** sip_regmgr_shutdown - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Unregister all lines and clean CCBs - * - * RETURNS: none - * - */ -void -sip_regmgr_shutdown (void) -{ - const char *fname = "sip_regmgr_shutown"; - fallback_ccb_t *fallback_ccb = NULL; - line_t ndx = 0; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - - // Shutdown registration - ccsip_register_shutdown(); - - // Cleanup fallback CCB list - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - NULL)) != NULL) { - sip_regmgr_clean_fallback_ccb(fallback_ccb); - (void) sll_remove(fallback_ccb_list, fallback_ccb); - cpr_free(fallback_ccb); - } - sll_destroy(fallback_ccb_list); - fallback_ccb_list = NULL; - - for (ndx = REG_CCB_START; ndx <= REG_BACKUP_CCB; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ccb->sipCallID[0] = '\0'; - } - } - - retry_times = 0; - set_active_ccm(NULL); - CCM_Active_Standby_Table.standby_ccm_entry = NULL; -} - -/* - ** sip_regmgr_failover_rsp_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: none - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_regmgr_failover_rsp_start (void) -{ - const char *fname = "sip_regmgr_failover_rsp_start"; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - /* - * Received response start - * Change the ip addr and port to point to the new ccm - * Set the CC_CONFIG_TABLE entry for all the lines to - * point to the new ccm. - * Set the ccb->cc_cfg_table_entry with the new entry. - */ - sip_regmgr_setup_new_active_ccb(CCM_Failover_Table.failover_ccm_entry); - /* - * Monitoring of standby node will start when we get a 200 ok for the new - * active cucm, or, in case new active fails, then the stanby will be moved - * up to become new active cucm, and will come to this function again. - */ - if (ccsip_register_get_register_state() == SIP_REG_NO_STANDBY) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to get new standby ccm !", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - } - - sip_regmgr_register_lines(TRUE, FALSE); - // start notify timer - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"START TIMER", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - (void) sip_platform_notify_timer_start(5000); - CCM_Failover_Table.prime_registered = TRUE; -} - -/* - ** sip_regmgr_failover_rsp_complete - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_regmgr_failover_rsp_complete (void) -{ - const char *fname = "sip_regmgr_failover_complete"; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - /* - * Received response complete - */ - // stop notify timer - (void) sip_platform_notify_timer_stop(); - CCM_Failover_Table.failover_started = FALSE; - sip_platform_cc_mode_notify(); - sip_regmgr_register_lines(FALSE, FALSE); - sip_regmgr_update_call_ccb(); - sip_platform_set_ccm_status(); - sip_regmgr_trigger_fallback_monitor(); - CCM_Failover_Table.prime_registered = FALSE; -} - -void -sip_regmgr_register_lines (boolean prime_only, boolean skip_prime) -{ - static const char fname[] = "sip_regmgr_register_lines"; - ccsipCCB_t *ccb = 0; - line_t ndx; - line_t line_end; - line_t line_start; - char address[MAX_IPADDR_STR_LEN]; - ti_config_table_t *standby_ccm; - - line_end = 1; - if ((!CCM_Failover_Table.prime_registered && !skip_prime) || prime_only) { - line_start = REG_CCB_START; - } else { - line_start = REG_CCB_START + 1; - } - if (prime_only) { - line_end = REG_CCB_START; - } else { - line_end += TEL_CCB_END; - ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - if (ccb->reg.registered ) { - ui_set_sip_registration_state(ccb->dn_line, TRUE); - } - } - - if (line_start == REG_CCB_START) { - ccsip_register_set_register_state(SIP_REG_REGISTERING); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"registering prime line", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - /* - * regmgr - Set the Backup (standby ccm) info. - */ - standby_ccm = CCM_Active_Standby_Table.standby_ccm_entry; - if (standby_ccm) { - ti_ccm_t *ti_ccm = &standby_ccm->ti_specific.ti_ccm; - - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ERROR: Standby ccm entry is NULL", - DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - } - } - - for (ndx = line_start; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t) (ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, %p", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - - ui_set_sip_registration_state(ccb->dn_line, FALSE); - - sip_sm_call_cleanup(ccb); - sipTransportGetPrimServerAddress(ccb->dn_line, address); - - sstrncpy(ccb->reg.proxy, address, MAX_IPADDR_STR_LEN); - - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccb->index == REG_CCB_START) { - ui_update_registration_state_all_lines(FALSE); - ccb->send_reason_header = TRUE; - } else { - ccb->send_reason_header = FALSE; - } - - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - } - } - sip_platform_set_ccm_status(); -} - -/* - ** sip_regmgr_phone_idle - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_phone_idle (boolean waited) -{ - const char *fname = "sip_regmgr_phone_idle"; - ccsipCCB_t *ccb; - - /* - * Received response - */ - CCM_Fallback_Table.is_idle = TRUE; - // if waited = TRUE send refer and change to token wait - // and send ui unlock - // otherwise start fallback - if (waited) { - platform_reg_fallback_cfm(); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX" waited TRUE", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - CCM_Fallback_Table.fallback_ccm_entry = NULL; - sip_regmgr_send_refer(CCM_Fallback_Table.ccb); - - } else { - /* - * Cancel reg from current active ccm - */ - ccsip_register_cancel(TRUE, FALSE); - - ccb = CCM_Fallback_Table.ccb; - if (ccsip_register_send_msg(SIP_REG_CLEANUP, ccb->index) != SIP_REG_OK) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"failed to send SIP_REG_CLEANUP", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - (void) sip_platform_notify_timer_start(5000); - } -} - -/* - ** sip_regmgr_fallback_rsp - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_regmgr_fallback_rsp (void) -{ - const char *fname = "sip_regmgr_fallback_rsp"; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Entered", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - /* - * Received response - */ - (void) sip_platform_notify_timer_stop(); - CCM_Fallback_Table.is_resp = TRUE; - sip_platform_cc_mode_notify(); - if (CCM_Fallback_Table.fallback_ccm_entry) { - sip_regmgr_register_lines(FALSE, FALSE); - CCM_Fallback_Table.fallback_ccm_entry = NULL; - } - sip_regmgr_update_call_ccb(); - CCM_Failover_Table.prime_registered = FALSE; -} - -void -sip_regmgr_rsp (int rsp_id, int rsp_type, boolean waited) -{ - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"rsp id=%s rsp type=%s waited=%d", - DEB_F_PREFIX_ARGS(SIP_RESP, "sip_regmgr_rsp"), - rsp_id == FAILOVER_RSP ? "FAILOVER_RSP" : "FALLBACK_RSP", - rsp_type == RSP_START ? "RSP_START" : "RSP_COMPLETE", waited); - - if (rsp_type == RSP_START) { - if (rsp_id == FAILOVER_RSP) { - sip_regmgr_failover_rsp_start(); - // Inform the Sub/Not manager that platform is about to failover. - (void) sip_subsManager_rollover(); - publish_reset(); - } else { - sip_regmgr_phone_idle(waited); - /* - * Inform the Sub/Not manager that platform is about to fallback. - * so that applications can clean up before re-register with the - * primary CCM. - */ - (void) sip_subsManager_rollover(); - publish_reset(); - } - } else if (rsp_type == RSP_COMPLETE) { - - SIPTaskReinitialize(TRUE); - - if (rsp_id == FAILOVER_RSP) { - sip_regmgr_failover_rsp_complete(); - } else { - sip_regmgr_fallback_rsp(); - } - } -} - -/* - * Get the config address based on call manager id - * - * @param ccm_id : callmanager idex - * addr_str: address of allocated space to return - * the address in string format. - * - * @return none - * - * @pre (addr_str != NULL) (1< ccm_id < 4) - * - */ - -void sip_regmgr_get_config_addr (int ccm_id, char *addr_str) { - -#ifdef IPV6_STACK_ENABLED - int ip_mode = CPR_IP_MODE_IPV4; - - - - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); - if (ip_mode == CPR_IP_MODE_IPV4) { -#endif - config_get_value(ccm_config_id_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); -#ifdef IPV6_STACK_ENABLED - } else if (ip_mode == CPR_IP_MODE_IPV6) { - - config_get_value(ccm_config_id_ipv6_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); - } else if (ip_mode == CPR_IP_MODE_DUAL) { - - config_get_value(ccm_config_id_ipv6_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); - /* Both mode get IPv6 first if not available get ipv4 */ - if (addr_str[0] == NUL) { - config_get_value(ccm_config_id_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); - } - } -#endif -} - -/* - ** sip_regmgr_check_config_change - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:None - * - * DESCRIPTION: Check if there is a config change in transport protocol - * or CCM address - * - * RETURNS: TRUE if config changed - * - */ -boolean -sip_regmgr_check_config_change (void) -{ - const char *fname = "sip_regmgr_check_config_change"; - ti_common_t ti_common; - CCM_ID ccm_id; - ti_common_t *active_ti_common; -#ifdef IPV6_STACK_ENABLED - int ip_mode = CPR_IP_MODE_IPV4; - - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); -#endif - - { - uint32_t transport_prot; - CONN_TYPE configured_conn = CONN_NONE; - - config_get_value(CFGID_TRANSPORT_LAYER_PROT, &transport_prot, - sizeof(transport_prot)); - configured_conn = CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.configured_conn_type; - if (transport_prot != (uint32_t) configured_conn) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"protocol%d conn type %d", DEB_F_PREFIX_ARGS(SIP_CONFIG, fname), - transport_prot, configured_conn); - return (TRUE); - } - } - for (ccm_id = PRIMARY_CCM; ccm_id < MAX_CCM; ccm_id++) { - - sip_regmgr_get_config_addr(ccm_id, ti_common.addr_str); - - active_ti_common = &CCM_Device_Specific_Config_Table[ccm_id].ti_common; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"CCM config%s active %s", DEB_F_PREFIX_ARGS(SIP_CONFIG, fname), - ti_common.addr_str, active_ti_common->addr_str); - if (strncmp(ti_common.addr_str, active_ti_common->addr_str, - strlen(active_ti_common->addr_str)) != 0) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"CCM changed", DEB_F_PREFIX_ARGS(SIP_CONFIG, fname)); - return (TRUE); - } - - } - return (FALSE); -} - -/* - ** sip_regmgr_process_config_change - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:None - * - * DESCRIPTION: Shut down and re-init sip - * - * RETURNS: None - * - */ -void -sip_regmgr_process_config_change (void) -{ - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"!!!Process_config_change", - DEB_F_PREFIX_ARGS(SIP_CONFIG, "sip_regmgr_process_config_change")); - - /* Register manager configuration changes need to restart sip task */ - sip_shutdown_phase1(FALSE, UNREG_NO_REASON); -} - -/* - ** sip_regmgr_clean_standby_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: None - * - * DESCRIPTION: Clean standby CCB - * - * RETURNS: None - * - */ -void -sip_regmgr_clean_standby_ccb (ccsipCCB_t *ccb) -{ - - if (ccb) { - ccb->reg.proxy[0] = '\0'; - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - ccb->reg.port = 0; - } -} - -/* - ** sip_regmgr_send_refer - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:ccb - * - * DESCRIPTION:Send a REFER message requesting for registering with the CCM - * - * RETURNS: None - * - */ -void -sip_regmgr_send_refer (ccsipCCB_t *ccb) -{ - static const char fname[] = "sip_regmgr_send_refer"; - - /* - * Send a REFER message requesting for registering with - * the callmanager. Cleanup any - * pending REFER transaction as new REFER is created for - * next transmission. - */ - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - if (sipSPISendRefer(ccb, TOKEN_REFER_TO, SIP_REF_TOKEN)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Successfully sent a REFER" - " for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_TOKEN_WAIT); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Error while trying to send" - " REFER for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } -} - -/* - ** sip_regmgr_update_call_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:ccb - * - * DESCRIPTION:Update call ccb after failover/fallback - * - * RETURNS: None - * - */ -static void -sip_regmgr_update_call_ccb (void) -{ - line_t i; - ccsipCCB_t *ccb = NULL; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - ccb = sip_sm_get_ccb_by_index(i); - if (ccb) { - ccb->local_port = sipTransportGetListenPort(ccb->dn_line, NULL); - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - } -} - -/* - * Function: sip_regmgr_ccm_restarted - * - * Parameters: - * new_reg_ccb - pointer to ccsipCCB_t of REG CCB that has seen - * by CCM as a new REG. - * - * Description: - * The function handles CCM has restarted condition. - * The phone needs to clean up internal state that may be left - * before CCM has gone down and come right up. This condition can - * be seen when using UDP for transport and the CCM has gone down - * between REG refresh cycles. - * - * Returns: - * None - */ -void -sip_regmgr_ccm_restarted (ccsipCCB_t *new_reg_ccb) -{ - const char *fname = "sip_regmgr_ccm_restarted"; - ccsipCCB_t *ccb; - line_t ndx, line_end; - - if ((new_reg_ccb == NULL) || (new_reg_ccb->index == REG_BACKUP_CCB)) { - /* No ccb or it is back up CCB, ignore this one */ - return; - } - - /* Inform all applications that hat may subscribe to the CCM/Proxy */ - (void) sip_subsManager_reset_reg(); - /* - * If there are more than one line registered to this CCM/Proxy, - * start re-register the rest of the lines quickly. - */ - line_end = 1; - /* - * REG CCBs start after the TEL CCBs. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!sip_config_check_line((line_t)(ndx - TEL_CCB_END)) || - !ccb || (ccb == new_reg_ccb) || - (ccb->state != (int) SIP_REG_STATE_REGISTERED) || - (util_compare_ip(&(ccb->reg.addr), &(new_reg_ccb->reg.addr)) == FALSE)) { - /* - * Skip the CCB for the line that - * 1) is not configured or - * 2) is the same as the one that detects restarts or - * 3) is not registered or - * 4) the proxy/CCM address is not the same one as the - * one that is seeing new registration indication. - * (do not restart other that is not register to the - * same server). - */ - continue; - } - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Re-register %d", DEB_F_PREFIX_ARGS(SIP_REG, fname), ccb->dn_line); - /* - * This line still registers before the CCM went down and came back - * up. Do minimum resetting to the ccb just enough for it to - * send REG out to the CCM. - */ - - /* Set state back to idle */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - /* Clear Registered flag */ - ccb->reg.registered = 0; - - /* Restart the register timer */ - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * - 1000, ccb->index); - - /* Update UI to indicates that this line is not register */ - ui_set_sip_registration_state(ccb->dn_line, FALSE); - - /* Send REG out to the CCM */ - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - -/* - ** sip_regmgr_notify_timer_callback - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: None - * - * DESCRIPTION: Missed notify from CCM during failover/fallback - * - * RETURNS: None - * - */ -void -sip_regmgr_notify_timer_callback (void *data) -{ - const char *fname = "sip_regmgr_notify_timer_callback"; - ccsipCCB_t *ccb; - sipServiceControl_t *scp = NULL; - const char *versionStamp = "0"; - int versionStampLen; - - ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - if (ccb->reg.registered) { - // Prime line in registered state. Missed notify from ccm. - // fake a notify message to unlock UI, Use value 0 so that - // platform will download the config - scp = (sipServiceControl_t *) - cpr_calloc(1, sizeof(sipServiceControl_t)); - if (scp) { - versionStampLen = strlen(versionStamp); - scp->action = SERVICE_CONTROL_ACTION_CHECK_VERSION; - scp->configVersionStamp = (char *) - cpr_calloc(1, versionStampLen + 1); - scp->dialplanVersionStamp = (char *) - cpr_calloc(1, versionStampLen + 1); - scp->softkeyVersionStamp = (char *) - cpr_calloc(1, versionStampLen + 1); - - if (!scp->configVersionStamp || - !scp->dialplanVersionStamp || - !scp->softkeyVersionStamp) { - CCSIP_DEBUG_ERROR("%s: malloc failed", fname); - } else { - sstrncpy(scp->configVersionStamp, versionStamp, versionStampLen + 1); - sstrncpy(scp->dialplanVersionStamp, versionStamp, versionStampLen + 1); - sstrncpy(scp->softkeyVersionStamp, versionStamp, versionStampLen + 1); - sip_platform_handle_service_control_notify(scp); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Fake NOTIFY TO Platform", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } - sippmh_free_service_control_info(scp); - } - } else { - // We should not get here. If so then some problem - // Add debug message for the time being - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"PRIME LINE UNREGISTRED STATE, UI LOCK!!!", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } -} - - -/* - ** sip_regmgr_replace_standby - * - * PARAMETERS: ccb - * - * DESCRIPTION: Replace current standby with new one - * - * RETURNS: None - * - */ -void -sip_regmgr_replace_standby (ccsipCCB_t *ccb) -{ - const char *fname = "sip_regmgr_replace_standby"; - ti_config_table_t *cfg_table_entry; - ti_common_t *ti_common; - ccsipCCB_t *ccb_of_fallback; - ti_config_table_t *standby_ccm_entry; - - if (!new_standby_available) { - return; - } - /* - * Will get in here if a fallback of standby - * occurs when the current standby has an - * outstanding transaction in process. We wait - * till the transaction is complete. - */ - - // Update CCM Status - standby_ccm_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - ui_set_ccm_conn_status(standby_ccm_entry->ti_common.addr_str, - CCM_STATUS_NONE); - - cfg_table_entry = (ti_config_table_t *) new_standby_available; - ti_common = &cfg_table_entry->ti_common; - sip_regmgr_setup_new_standby_ccb(cfg_table_entry->ti_specific.ti_ccm.ccm_id); - if (sip_regmgr_find_fallback_ccb_by_addr_port(&(ti_common->addr), - ti_common->port, &ccb_of_fallback)) { - sip_regmgr_free_fallback_ccb(ccb_of_fallback); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to find fallback" - " ccb to free\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } - /* - * New standby, start monitoring it. - */ - - ui_set_ccm_conn_status(cfg_table_entry->ti_common.addr_str, - CCM_STATUS_STANDBY); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new standby ccb", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - new_standby_available = NULL; -} -/** - ** sip_regmgr_regallfail_timer_callback - * Callback function called when the reg-all-fail timer expires - * - * @param void* data - * - * @return void - * - */ -void -sip_regmgr_regallfail_timer_callback (void *data) -{ - const char *fname = "sip_regmgr_regallfail_timer_callback"; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Registration Failed. Restarting the System now!", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - sip_regmgr_send_status(REG_SRC_SIP, REG_ALL_FAIL); -} - -/** - ** sip_regmgr_handle_reg_all_fail - * Handles the scenario when all the Registration attempts fail. - * - * @param none - * - * @return void - * - */ -void -sip_regmgr_handle_reg_all_fail (void) -{ - const char *fname = "sip_regmgr_handle_reg_all_fail"; - line_t line_end, ndx; - CCM_ID ccm_index; - ccsipCCB_t *ccb; - unsigned long msec; - unsigned long high_regfailtime = 180000; - unsigned long low_regfailtime = 120000; - char tmp_str[STATUS_LINE_MAX_LEN]; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"All registration attempts failed.", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - /* Start the timer and update UI only if no calls are in progress on the - * phone.*/ - if (sip_platform_is_phone_idle()) { - for (ccm_index = PRIMARY_CCM; ccm_index < MAX_CCM; ccm_index++) { - if (0 != strcmp (CCM_Config_Table[0][ccm_index]->ti_common.addr_str, - "")) { - ui_set_ccm_conn_status(CCM_Config_Table[0][ccm_index]-> - ti_common.addr_str, CCM_STATUS_NONE); - } - } - line_end = 1; - line_end += TEL_CCB_END; - for (ndx = REG_CCB_START; ndx <= line_end; ndx++){ - if (sip_config_check_line((line_t) (ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!ccb) { - continue; - } - ui_set_sip_registration_state(ccb->dn_line, FALSE); - } - } - - /* - * Start regallfial with 100 msec timer once, - * After that get a Random time between high (3 mins) - * and low (2 mins) and start the timer with that time. - */ - if (!regall_fail_attempt) { - msec = REGALL_FAIL_TIME; - } else { - msec = cpr_rand()%(high_regfailtime - low_regfailtime); - msec += low_regfailtime; - } - - regall_fail_attempt = TRUE; - - sip_platform_reg_all_fail_timer_start(msec); - if (platGetPhraseText(STR_INDEX_REGISTERING, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1) == CPR_SUCCESS) { - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, tmp_str, msec/1000, TRUE, DEF_NOTIFY_PRI); - } - } else { - /* Send the Indication to the platform immediately */ - sip_regmgr_send_status(REG_SRC_SIP, REG_ALL_FAIL); - } -} - -/* - ** notify_register_update - * - * PARAMETERS: last_available_line - last available line button on the phone - * - * DESCRIPTION: This function is used to notify the sip task to handle - * any registration updates when sidecars are plugged in or - * removed - * - * RETURNS: None - * - */ -void notify_register_update(int last_line_available) -{ - static const char fname[] = "notify_register_update"; - - if (ccsip_register_send_msg(SIP_REG_UPDATE, (line_t)last_line_available) != SIP_REG_OK) { - CCSIP_DEBUG_ERROR("%s : Unable to send register update message", fname); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"last_available_line: %d", - DEB_F_PREFIX_ARGS(SIP_REG, fname), last_line_available); - } -} - -/* - ** update_ui_line_reg_state - * - * PARAMETERS: - * start_line - first line whose reg status need to be set - * end_line - last line whose reg status needs to be set - * registered - registered/unregistered - * - * DESCRIPTION: This function is used to set the ui line reg status - * - * RETURNS: None - * - */ -void update_ui_line_reg_state(int start_line, int end_line, boolean registered) -{ - line_t line_index = 0; - ccsipCCB_t *line_ccb = NULL; - - for (line_index = (TEL_CCB_END + (line_t)start_line + 1); - line_index <= (TEL_CCB_END + end_line); - line_index++) { - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - ui_set_sip_registration_state(line_ccb->dn_line, registered); - } - } - } -} - - -/* - ** regmgr_handle_register_update - * - * PARAMETERS: last_available_line - last available line button on the phone - * - * DESCRIPTION: This function is used to handle any registration updates needed - * when a sidecar is plugged in or unplugged - * - * RETURNS: None - * - */ -void regmgr_handle_register_update(line_t last_available_line) -{ - static const char fname[] = "regmgr_handle_register_update"; - ccsipCCB_t *line_ccb; - line_t line_index = 0; - char address[MAX_IPADDR_STR_LEN]; - int last_line_button_present; - //boolean reg_update_needed = TRUE; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"last_available_line: %d", - DEB_F_PREFIX_ARGS(SIP_REG, fname), last_available_line); - - if (last_available_line == 1) { - return; - } - - last_line_button_present = 1; - - /* added by cangchen fix CSCsz91640*/ - if (last_line_button_present > last_available_line) { - for (line_index = (TEL_CCB_END + (line_t)last_available_line + 1); - line_index <= (TEL_CCB_END + 1) && - line_index <= (TEL_CCB_END + (line_t)(last_line_button_present)); - line_index++) { - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d: %p", - DEB_L_C_F_PREFIX_ARGS(SIP_CONFIG, line_ccb->index, line_ccb->dn_line, fname), - line_index, line_ccb); - } - } - } - } - - if (last_available_line > last_line_button_present) { - //sidecar added - for (line_index = (TEL_CCB_END + (line_t)last_line_button_present + 1); - line_index <= (TEL_CCB_END + 1) && - line_index <= (TEL_CCB_END + (line_t)(last_available_line)); - line_index++) { - //sidecar added.register all the lines that have been newly added - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d: %p", - DEB_L_C_F_PREFIX_ARGS(SIP_CONFIG, line_ccb->index, line_ccb->dn_line, fname), - line_index, line_ccb); - - ui_set_sip_registration_state(line_ccb->dn_line, FALSE); - - sip_sm_call_cleanup(line_ccb); - sipTransportGetPrimServerAddress(line_ccb->dn_line, address); - - sstrncpy(line_ccb->reg.proxy, address, MAX_IPADDR_STR_LEN); - - line_ccb->reg.addr = line_ccb->dest_sip_addr; - line_ccb->reg.port = (uint16_t) line_ccb->dest_sip_port; - - if (ccsip_register_send_msg(SIP_REG_REQ, line_index) != SIP_REG_OK) { - ccsip_register_cleanup(line_ccb, TRUE); - } - } - } - } - } else if (last_line_button_present > last_available_line) { - for (line_index = (TEL_CCB_END + (line_t)last_available_line + 1); - line_index <= (TEL_CCB_END + 1) && - line_index <= (TEL_CCB_END + (line_t)(last_line_button_present)); - line_index++) { - //sidecar removed.unregister al the lines that were - //previously registered - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - ui_set_sip_registration_state(line_ccb->dn_line, FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), line_ccb->index); - (void) sip_platform_register_expires_timer_stop(line_ccb->index); - sip_stop_ack_timer(line_ccb); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, line_index) != SIP_REG_OK) { - ccsip_register_cleanup(line_ccb, TRUE); - } - } - } - } - } - - -} - - - - - - - - - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_transport.c b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_transport.c deleted file mode 100644 index a396e250a79..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_transport.c +++ /dev/null @@ -1,2184 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_locks.h" -#include "phone_debug.h" -#include "dialplan.h" -#include "config.h" -#include "configmgr.h" -#include "ccsip_platform_udp.h" -#include "ccsip_platform_timers.h" -#include "ccsip_register.h" -#include "sip_platform_task.h" -#include "ccsip_task.h" -#include "ccsip_messaging.h" -#include "ccsip_reldev.h" -#include "sip_common_transport.h" -#include "sip_csps_transport.h" -#include "sip_ccm_transport.h" -#include "sip_common_regmgr.h" -#include "util_string.h" -#include "dns_utils.h" -#include "debug.h" -#include "phntask.h" -#include "ccsip_subsmanager.h" -#include "ccsip_publish.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_platform_tls.h" -#include "platform_api.h" -#include "sessionTypes.h" - -uint16_t ccm_config_id_addr_str[MAX_CCM] = { - CFGID_CCM1_ADDRESS, - CFGID_CCM2_ADDRESS, - CFGID_CCM3_ADDRESS -}; - -#ifdef IPV6_STACK_ENABLED - -uint16_t ccm_config_id_ipv6_addr_str[MAX_CCM] = { - CFGID_CCM1_IPV6_ADDRESS, - CFGID_CCM2_IPV6_ADDRESS, - CFGID_CCM3_IPV6_ADDRESS -}; - -#endif - -uint16_t ccm_config_id_port[MAX_CCM] = { - CFGID_CCM1_SIP_PORT, - CFGID_CCM2_SIP_PORT, - CFGID_CCM3_SIP_PORT -}; - -uint16_t ccm_config_id_sec_level[MAX_CCM] = { - CFGID_CCM1_SEC_LEVEL, - CFGID_CCM2_SEC_LEVEL, - CFGID_CCM3_SEC_LEVEL -}; - -uint16_t ccm_config_id_is_valid[MAX_CCM] = { - CFGID_CCM1_IS_VALID, - CFGID_CCM2_IS_VALID, - CFGID_CCM3_IS_VALID -}; - -ti_config_table_t CCM_Device_Specific_Config_Table[MAX_CCM]; -ti_config_table_t CCM_Dummy_Entry; -ti_config_table_t CSPS_Config_Table[MAX_REG_LINES]; -ti_config_table_t *CCM_Config_Table[MAX_REG_LINES + 1][MAX_CCM]; -int phone_local_tcp_port[UNUSED_PARAM]; -ti_csps_t CSPS_Device_Specific_Config_Table; - -sip_tcp_conn_t sip_tcp_conn_tab[MAX_CONNECTIONS]; - -char sent_string[] = "Sent:"; -char rcvd_string[] = "Rcvd:"; -char cseq_string[] = " Cseq:"; -char callid_string[] = " CallId:"; - -static cpr_socket_t listen_socket = INVALID_SOCKET; -extern cc_config_table_t CC_Config_Table[]; -extern sipCallHistory_t gCallHistory[]; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; - -//extern uint16_t ccm_config_id_addr_str[MAX_CCM]; -//extern uint16_t ccm_config_id_port[MAX_CCM]; -extern void platAddCallControlClassifiers( - unsigned long myIPAddr, unsigned short myPort, - unsigned long cucm1IPAddr, unsigned short cucm1Port, - unsigned long cucm2IPAddr, unsigned short cucm2Port, - unsigned long cucm3IPAddr, unsigned short cucm3Port, - unsigned char protocol); -extern void platform_get_ipv4_address(cpr_ip_addr_t *ip_addr); - -#define SIP_IPPROTO_UDP 17 -#define SIP_IPPROTO_TCP 6 - -/* - * Function: ccsip_add_wlan_classifiers() - * - * Parameters: None - * - * Description: Add classifiers required for wlan - * - * Returns: None - * - */ -void ccsip_add_wlan_classifiers () -{ - cpr_ip_addr_t my_addr; - uint32_t local_port = 0; - uint32_t transport_prot = 0; - - platform_get_ipv4_address (&my_addr); - - config_get_value(CFGID_VOIP_CONTROL_PORT, &local_port, - sizeof(local_port)); - config_get_value(CFGID_TRANSPORT_LAYER_PROT, &transport_prot, - sizeof(transport_prot)); - - platAddCallControlClassifiers(my_addr.u.ip4, local_port , - ntohl(CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.addr.u.ip4), - CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.port, - ntohl(CCM_Device_Specific_Config_Table[SECONDARY_CCM].ti_common.addr.u.ip4), - CCM_Device_Specific_Config_Table[SECONDARY_CCM].ti_common.port, - ntohl(CCM_Device_Specific_Config_Table[TERTIARY_CCM].ti_common.addr.u.ip4), - CCM_Device_Specific_Config_Table[TERTIARY_CCM].ti_common.port, - (transport_prot==CONN_UDP)? SIP_IPPROTO_UDP:SIP_IPPROTO_TCP); -} - -void ccsip_remove_wlan_classifiers () -{ - platRemoveCallControlClassifiers(); - -} - -/* - ** sipTransportGetServerHandle - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server handle for a particular - * line id. - * - * RETURNS: The server handle - * - */ -static cpr_socket_t -sipTransportGetServerHandle (line_t dn, line_t ndx) -{ - - ti_config_table_t *ccm_table_ptr = NULL; - ti_common_t ti_common; - static const char *fname = "sipTransportGetServerHandle"; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, dn); - return (INVALID_SOCKET); - } - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ndx == REG_BACKUP_CCB) { - /* - * This is the reg backup ccb, so return the - * standby ccm handle - */ - ccm_table_ptr = CCM_Active_Standby_Table.standby_ccm_entry; - } else if (ndx > REG_BACKUP_CCB) { - ccsipCCB_t *ccb = NULL; - - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - } else { - return (INVALID_SOCKET); - } - } else { - ccm_table_ptr = CCM_Active_Standby_Table.active_ccm_entry; - } - if (ccm_table_ptr) { - ti_common = ccm_table_ptr->ti_common; - return (ti_common.handle); - } - } else { - /* - * Assume CSPS for now. - */ - return (sipTransportCSPSGetProxyHandleByDN(dn)); - } - return (INVALID_SOCKET); -} - -/* - ** sipTransportGetServerHandleWithAddr - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: IP addr - * - * DESCRIPTION: This function gets the server handle - * - * RETURNS: The server handle - * - */ -static cpr_socket_t -sipTransportGetServerHandleWithAddr (cpr_ip_addr_t *remote_ip_addr) -{ - - ti_config_table_t *ccm_table_ptr = NULL; - - ccm_table_ptr = CCM_Active_Standby_Table.active_ccm_entry; - - if (ccm_table_ptr && util_compare_ip(remote_ip_addr, &(ccm_table_ptr->ti_common.addr))) { - return (ccm_table_ptr->ti_common.handle); - } - ccm_table_ptr = CCM_Active_Standby_Table.standby_ccm_entry; - if (ccm_table_ptr && util_compare_ip(remote_ip_addr, &(ccm_table_ptr->ti_common.addr))) { - return (ccm_table_ptr->ti_common.handle); - } - return (INVALID_SOCKET); -} - -/* - ** sipTransportGetServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server address for a particular - * line id. - * - * RETURNS: 0 if successful - * - */ -uint16_t -sipTransportGetServerAddress (cpr_ip_addr_t *pip_addr, line_t dn, line_t ndx) -{ - static const char *fname = "sipTransportGetServerAddress"; - *pip_addr = ip_addr_invalid; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, dn); - return (0); - } - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ndx == REG_BACKUP_CCB) { - /* - * This is the reg backup ccb, so return the - * standby ccm addr - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) { - *pip_addr = CCM_Active_Standby_Table.standby_ccm_entry-> - ti_common.addr; - } - return (0); - } else if (ndx > REG_BACKUP_CCB) { - ccsipCCB_t *ccb = NULL; - - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ti_config_table_t *ccm_table_ptr = NULL; - ti_common_t ti_common; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr) { - ti_common = ccm_table_ptr->ti_common; - *pip_addr = ti_common.addr; - } - } - return (0); - } else { - if (CCM_Active_Standby_Table.active_ccm_entry) { - *pip_addr = CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.addr; - } - return (0); - } - } else { - /* - * Assume CSPS for now. - */ - return (sipTransportCSPSGetProxyAddressByDN(pip_addr, dn)); - } -} - -/* - ** sipTransportGetServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server port for a particular - * line id. - * - * RETURNS: Server port as a short - * - */ -short -sipTransportGetServerPort (line_t dn, line_t ndx) -{ - static const char *fname = "sipTransportGetServerPort"; - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, dn); - return (0); - } - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ndx == REG_BACKUP_CCB) { - /* - * This is the reg backup ccb, so return the - * standby ccm port - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) { - return ((short) CCM_Active_Standby_Table.standby_ccm_entry-> - ti_common.port); - } - } else if (ndx > REG_BACKUP_CCB) { - ccsipCCB_t *ccb = NULL; - - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ti_config_table_t *ccm_table_ptr = NULL; - ti_common_t ti_common; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr) { - ti_common = ccm_table_ptr->ti_common; - return (ti_common.port); - } - } - return (0); - } else { - if (CCM_Active_Standby_Table.active_ccm_entry) { - return ((short) CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.port); - } - return (0); - } - } - - /* - * Assume CSPS for now. - */ - return ((short) sipTransportCSPSGetProxyPortByDN(dn)); -} - -conn_create_status_t -sip_transport_setup_cc_conn (line_t dn, CCM_ID ccm_id) -{ - static const char *fname = "sip_transport_setup_cc_conn"; - int dnsErrorCode; - cpr_ip_addr_t server_ipaddr; - uint16_t server_port = 0, listener_port = 0; - cpr_socket_t server_conn_handle = INVALID_SOCKET; - conn_create_status_t status = CONN_INVALID; - uint32_t type; - ti_common_t *ti_common; - int ip_mode = CPR_IP_MODE_IPV4; - uint32_t s_port; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, dn); - return (status); - } - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.", - fname, ccm_id); - return (status); - } - CPR_IP_ADDR_INIT(server_ipaddr); - -#ifdef IPV6_STACK_ENABLED - - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); -#endif - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - ti_ccm_t *ti_ccm; - - ti_ccm = &CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm; - if (!ti_ccm->is_valid) { - /* - * dont even attempt to create a connection if the - * platform has deemed the ccm info invalid - */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Admin has not configured a valid cucm for cucm index=%s=%d.", - fname, CCM_ID_PRINT(ccm_id), ccm_id); - return (status); - } - dnsErrorCode = dnsGetHostByName(CCM_Config_Table[dn - 1][ccm_id]-> - ti_common.addr_str, &server_ipaddr, - 100, 1); - if (dnsErrorCode != DNS_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sip_transport_setup_cc_conn", - "dnsGetHostByName() returned error:%s", - CCM_Config_Table[dn - 1][ccm_id]->ti_common.addr_str); - return status; - } - - util_ntohl(&server_ipaddr, &server_ipaddr); - - - config_get_value(CFGID_VOIP_CONTROL_PORT, &s_port, sizeof(s_port)); - server_port = (uint16_t) s_port; - - if (CCM_Config_Table[dn - 1][ccm_id]->ti_common.conn_type == CONN_UDP) { - type = SOCK_DGRAM; - listener_port = CCM_Config_Table[dn - 1][ccm_id]->ti_common.listen_port; - } else { - type = SOCK_STREAM; - } - } else { - /* - * Assume CSPS for now. - */ - sipTransportGetServerIPAddr(&server_ipaddr, dn); - server_port = (uint16_t) sipTransportGetPrimServerPort(dn); - if (CSPS_Config_Table[dn - 1].ti_common.conn_type == CONN_UDP) { - type = SOCK_DGRAM; - listener_port = CSPS_Config_Table[dn - 1].ti_common.listen_port; - } else { - type = SOCK_STREAM; - } - } - if (util_check_if_ip_valid(&server_ipaddr) && server_port != 0) { - char server_ipaddr_str[MAX_IPADDR_STR_LEN]; - int ret_status = SIP_ERROR; - - ipaddr2dotted(server_ipaddr_str, &server_ipaddr); - if (type == SOCK_DGRAM) { - ret_status = sip_platform_udp_channel_create(ip_mode, &server_conn_handle, - &server_ipaddr, - server_port, 0); - if (ret_status == SIP_OK) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC UDP socket opened: " - "<%s>:<%d>, handle=<%d>\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, - server_ipaddr_str, server_port, - server_conn_handle); - status = CONN_SUCCESS; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "udp channel error" - "server addr=%s, server port=%d) failed.\n", - fname, dn, server_ipaddr_str, server_port); - server_conn_handle = INVALID_SOCKET; - status = CONN_FAILURE; - } - } - else { - sipSPIMessage_t sip_msg; - - if (CC_Config_Table[dn - 1].cc_type != CC_CCM) { - /* We should not come here in non-ccm mode */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TLS and TCP not supported in non-ccm" - " mode\n", fname); - return (CONN_INVALID); - } - - // TLS if tls and sec_level is not non secure - if (((CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm.sec_level - == AUTHENTICATED) || - (CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm.sec_level - == ENCRYPTED)) && - (CCM_Config_Table[dn - 1][ccm_id]->ti_common.conn_type == CONN_TLS)) { - uint32_t port = 0; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"server_ipaddr %p", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), &server_ipaddr); - sip_msg.createConnMsg.addr = server_ipaddr; - config_get_value(ccm_config_id_port[ccm_id], &port, - sizeof(port)); - sip_msg.createConnMsg.port = (uint16_t) port; - sip_msg.context = NULL; - server_conn_handle = sip_tls_create_connection(&sip_msg, TRUE, - CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm.sec_level); - if (server_conn_handle != INVALID_SOCKET) { - CCM_Config_Table[dn - 1][ccm_id]->ti_common.port = - (uint16_t) port; - } - } else { - sip_msg.createConnMsg.addr = server_ipaddr; - sip_msg.createConnMsg.port = server_port; - sip_msg.context = NULL; - server_conn_handle = sip_tcp_create_connection(&sip_msg); - } - if (server_conn_handle != INVALID_SOCKET) { - listener_port = sip_msg.createConnMsg.local_listener_port; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC TCP socket opened: " - "to <%s>:<%d>, local_port: %d handle=<%d>\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, server_ipaddr_str, - server_port, listener_port, - server_conn_handle); - status = CONN_SUCCESS; - phone_local_tcp_port[CCM_Config_Table[dn-1][ccm_id]->ti_specific.ti_ccm.ccm_id] = - sip_msg.createConnMsg.local_listener_port; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "tcp channel create error " - "server addr=%s, server port=%d) failed.\n", - fname, dn, server_ipaddr_str, server_port); - status = CONN_FAILURE; - } - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>: CC address/port not configured.", - fname, dn); - status = CONN_INVALID; - } - - if ((status == CONN_SUCCESS) || (status == CONN_FAILURE)) { - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - /* - * Add the newly created socket to the CCM as the one - * we listen for incoming messages as well. - */ - ti_common = &CCM_Config_Table[dn - 1][ccm_id]->ti_common; - } else { - /* - * Non CCM Case - */ - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - } - ti_common->addr = server_ipaddr; - ti_common->port = server_port; - ti_common->handle = server_conn_handle; - ti_common->listen_port = listener_port; - } - - return (status); -} - - -int -sip_transport_destroy_cc_conn (line_t dn, CCM_ID ccm_id) -{ - static const char *fname = "sip_transport_destroy_cc_conn"; - int disconnect_status = 0; - cpr_socket_t cc_handle; - CONN_TYPE conn_type; - uint16_t max_cc_count, cc_index; - ti_common_t *ti_common; - CC_ID cc_type; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, dn); - return (disconnect_status); - } - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.", - fname, ccm_id); - return (disconnect_status); - } - - cc_type = CC_Config_Table[dn - 1].cc_type; - if (cc_type == CC_CCM) { - /* - * regmgr - */ - ti_common = &CCM_Config_Table[dn - 1][ccm_id]->ti_common; - max_cc_count = MAX_CCM; - } else { - /* - * Assume CSPS for now. - */ - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - max_cc_count = MAX_CSPS; - } - cc_index = 0; - do { - cc_handle = ti_common->handle; - conn_type = ti_common->conn_type; - if (cc_handle != INVALID_SOCKET) { - /* Close the UDP send channel to the proxy */ - if (sip_platform_udp_channel_destroy(cc_handle) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "handle=%d) \n", fname, dn, cc_handle); - disconnect_status = -1; - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC socket closed: " - "handle=<%d>\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, cc_handle); - disconnect_status = 0; - } - if (conn_type != CONN_UDP) { - int connid; - - connid = sip_tcp_fd_to_connid(ti_common->handle); - sipTcpFreeSendQueue(connid); - sip_tcp_purge_entry(connid); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC socket already closed.", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn); - disconnect_status = 0; - } - cc_index++; - ti_common = &CCM_Config_Table[dn - 1][cc_index]->ti_common; - /* - * Will break out for CSPS the first time in the loop. - */ - } while (cc_index < max_cc_count); - if (listen_socket != INVALID_SOCKET) { - if (sip_platform_udp_channel_destroy(listen_socket) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "(handle=%d)\n", fname, dn, listen_socket); - disconnect_status = -1; - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC socket closed: handle=<%d>", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, listen_socket); - disconnect_status = 0; - } - sip_platform_task_reset_listen_socket(listen_socket); - listen_socket = INVALID_SOCKET; - } - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - CCM_Config_Table[dn - 1][ccm_id]->ti_common.handle = INVALID_SOCKET; - } else { - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - ti_common->addr = ip_addr_invalid; - ti_common->port = 0; - ti_common->handle = INVALID_SOCKET; - } - return (disconnect_status); -} - -/* - ** sipTransportCreateSendMessage - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: This function first creates the char * sip message that - * needs to be sent out and then calls the - * sipTransportSendMessage() to send out the message. - * - * RETURNS: -1 if failure and 0 if it succeeds. - * - * NOTE: This function will be consolidated with the following function - * so that only the following function will be necessary. Also the - * signature of the new function that results will be made similar - * to that of the IOS sip stacks sipTransportSendMessage() call. - * That will make the port of IOS based Propel SIP stack into the - * phone easier. - * - */ -int -sipTransportCreateSendMessage (ccsipCCB_t *ccb, - sipMessage_t *pSIPMessage, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, - void *cbp, - int reldev_stored_msg) -{ - const char *fname = "sipTransportCreateSendMessage"; - static char aOutBuf[SIP_UDP_MESSAGE_SIZE + 1]; - uint32_t nbytes = SIP_UDP_MESSAGE_SIZE; - hStatus_t sippmh_write_status = STATUS_FAILURE; - - /* - * Check args - */ - if (!pSIPMessage) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args: pSIPMessage is null", fname); - return (-1); - } - - /* - * Get message from the reliable delivery stored msg first and - * if there is no message from the reliable delivery message storage - * then compose the SIP message. - */ - nbytes = sipRelDevGetStoredCoupledMessage(reldev_stored_msg, &aOutBuf[0], - nbytes); - if (nbytes == 0) { - nbytes = SIP_UDP_MESSAGE_SIZE; - sippmh_write_status = sippmh_write(pSIPMessage, aOutBuf, &nbytes); - } else { - sippmh_write_status = STATUS_SUCCESS; - } - ccsip_dump_send_msg_info(aOutBuf, pSIPMessage, cc_remote_ipaddr, - cc_remote_port); - - free_sip_message(pSIPMessage); - if (sippmh_write_status == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb ? ccb->index : 0, ccb ? ccb->dn_line : 0, fname, - "sippmh_write()"); - return (-1); - } - if ((aOutBuf[0] == '\0') || (nbytes == 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() returned empty buffer " - "string\n", fname); - return (-1); - } - aOutBuf[nbytes] = '\0'; /* set NULL string for debug printing */ - - if (sipTransportSendMessage(ccb, aOutBuf, nbytes, message_type, - cc_remote_ipaddr, cc_remote_port, isRegister, - reTx, timeout, cbp) < 0) { - if (ccb) { - CCSIP_DEBUG_ERROR("SIPCC-ENTRY: LINE %d/%d: %-35s: message not " - "sent of type %s=%d. sipTransportSendMessage() failed.\n", - ccb->index, ccb->dn_line, fname, - message_type == sipMethodRegister ? "sipMethodRegister" : "", sipMethodRegister); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportSendMessage()"); - } - return (-1); - } - - return (0); -} - -/* - ** sipTransportSendMessage - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Sends out the sip message. - * - * RETURNS: -1 on failure and 0 on success. - * - * NOTE: This function will be consolidated with the following function - * so that only the following function will be necessary. Also the - * signature of the new function that results will be made similar - * to that of the IOS sip stacks sipTransportSendMessage() call. - * That will make the port of IOS based Propel SIP stack into the - * phone easier. - */ -int -sipTransportSendMessage (ccsipCCB_t *ccb, - char *pOutMessageBuf, - uint32_t nbytes, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, - void *cbp) -{ - const char *fname = "sipTransportSendMessage"; - char cc_config_ipaddr_str[MAX_IPADDR_STR_LEN]; - char cc_remote_ipaddr_str[MAX_IPADDR_STR_LEN]; - char obp_address[MAX_IPADDR_STR_LEN]; - cpr_socket_t send_to_proxy_handle = INVALID_SOCKET; - int nat_enable, dnsErrorCode; - const char *conn_type; - uint32_t local_udp_port = 0; - int tcp_error = SIP_TCP_SEND_OK; - int ip_mode = CPR_IP_MODE_IPV4; - - /* - * Check args - */ - if ((!pOutMessageBuf) || (pOutMessageBuf[0] == '\0')) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args: pOutMessageBuf is empty", fname); - return (-1); - } - -#ifdef IPV6_STACK_ENABLED - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); -#endif - conn_type = sipTransportGetTransportType(1, TRUE, ccb); - if (ccb) { - /* Check to see whether the supplied address and port - * match those of the currently configured proxy. - * If not, open a new UDP channel, send the message, - * and close the channel. - */ - /* Check to see whether the supplied address and port - * match those of the currently configured proxy. - * If not, open a new UDP channel, send the message, - * and close the channel. - */ - cpr_ip_addr_t cc_config_ipaddr; - uint16_t cc_config_port; - - sipTransportGetServerAddress(&cc_config_ipaddr, ccb->dn_line, ccb->index); - cc_config_port = sipTransportGetServerPort(ccb->dn_line, ccb->index); - - /* - * Convert IP address to string, for debugs - */ - if (SipDebugMessage) { - ipaddr2dotted(cc_config_ipaddr_str, &cc_config_ipaddr); - ipaddr2dotted(cc_remote_ipaddr_str, cc_remote_ipaddr); - } - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"ccb <%d>: config <%s>:<%d> - remote <%s>:<%d>", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), ccb->index, - cc_config_ipaddr_str, cc_config_port, - cc_remote_ipaddr_str, cc_remote_port); - - if (conn_type != NULL) { - if (!cpr_strcasecmp(conn_type, "UDP")) { - if (util_compare_ip(&cc_config_ipaddr, cc_remote_ipaddr) && - (cc_config_port == cc_remote_port)) { - send_to_proxy_handle = sipTransportGetServerHandle(ccb->dn_line, - ccb->index); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Got handle %d", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - send_to_proxy_handle); - } - } else { /* TCP */ - if (util_compare_ip(&cc_config_ipaddr, cc_remote_ipaddr)) { - send_to_proxy_handle = sipTransportGetServerHandle(ccb->dn_line, - ccb->index); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Got handle %d", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - send_to_proxy_handle); - if (send_to_proxy_handle == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid socket", fname); - return (-1); - } - } - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "Invalid Connection type returned"); - return (-1); - } - } - - /* - * Make the send code below believe that we do not have a connection to - * the remote side so that it creates a send port for each SIP message. - * This send port will have a source UDP port retrieved from the NAT - * configuration settings - */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 1) { - send_to_proxy_handle = INVALID_SOCKET; - config_get_value(CFGID_VOIP_CONTROL_PORT, &local_udp_port, - sizeof(local_udp_port)); - } - /* - * Check if we need to get the outbound proxy address and port. If we - * do then we will make the code below believe we do not have a - * connection to the remote side so it creates a send port for this - * message. This involves two checks, the first check is if outbound - * proxy support is enabled at all. The second check is that only - * REQUEST messages go to the outbound proxy. All other message - * types follow the normal rules for sending - */ - if (ccb) { - if (ccb->outBoundProxyPort == 0) { - sipTransportGetOutbProxyAddress(ccb->dn_line, obp_address); - if ((cpr_strcasecmp(obp_address, UNPROVISIONED) != 0) && - (obp_address[0] != 0) && (obp_address[0] != '0')) { - - /* Outbound proxy is configured, get it's IP address */ - dnsErrorCode = sipTransportGetServerAddrPort(obp_address, - &ccb->outBoundProxyAddr, - (uint16_t *)&ccb->outBoundProxyPort, - &ccb->ObpSRVhandle, - TRUE); - - if (dnsErrorCode != DNS_OK) { - /* - * SRV failed, do a DNS A record lookup - * on the outbound proxy - */ - if (util_check_if_ip_valid(&(ccb->outBoundProxyAddr)) == FALSE) { - dnsErrorCode = dnsGetHostByName(obp_address, - &ccb->outBoundProxyAddr, - 100, 1); - } - if (dnsErrorCode == DNS_OK) { - util_ntohl(&(ccb->outBoundProxyAddr),&(ccb->outBoundProxyAddr)); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sipTransportSendMessage", - "dnsGetHostByName() returned error"); - - ccb->outBoundProxyAddr = ip_addr_invalid; - ccb->outBoundProxyPort = 0; - return (-1); - } - } else { - util_ntohl(&(ccb->outBoundProxyAddr), &(ccb->outBoundProxyAddr)); - } - } - } - - /* - * only use outbound proxy if we have one configured, - * we are using the default proxy, we are not using the Emergency - * route, and it is not the backup proxy registration. - */ - if (util_check_if_ip_valid(&(ccb->outBoundProxyAddr)) && - (ccb->proxySelection == SIP_PROXY_DEFAULT) && - (ccb->routeMode != RouteEmergency) && (ccb->index != REG_BACKUP_CCB)) { - send_to_proxy_handle = INVALID_SOCKET; - switch (message_type) { - case sipMethodResponse: - case sipMethodUnknown: - ccb->outBoundProxyPort = cc_remote_port; - break; - default: - /* - * We have determined that this message is a REQUEST - * so we will change the one time outgoing port to - * the outbound proxy address and port - */ - *cc_remote_ipaddr = ccb->outBoundProxyAddr; - if (ccb->outBoundProxyPort != 0) { - cc_remote_port = (uint16_t) ccb->outBoundProxyPort; - } else { - cc_remote_port = (uint16_t) sipTransportGetOutbProxyPort(ccb->dn_line); - ccb->outBoundProxyPort = cc_remote_port; - } - break; - } - } - } - - if (SipDebugTask || SipDebugMessage) { - ipaddr2dotted(cc_remote_ipaddr_str, cc_remote_ipaddr); - } - - if ((conn_type != NULL) && (cpr_strcasecmp(conn_type, "UDP")) && - (send_to_proxy_handle == INVALID_SOCKET)) { - send_to_proxy_handle = sipTransportGetServerHandleWithAddr(cc_remote_ipaddr); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"<%s> remote ip addr", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), cc_remote_ipaddr_str); - if (send_to_proxy_handle == INVALID_SOCKET) { - // for TCP and TLS return if we do not have a connection to the - // remote side - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No connection to ip addr <%s>", fname, cc_remote_ipaddr_str); - return (-1); - } - } - if (send_to_proxy_handle != INVALID_SOCKET) { - /* - * Get the connection type and call ...sendto() or - * ...send() appropriately (for udp and tcp respectively). - * Also this will need to change to send the correct line - * when we go with supporting CCM and proxy on the - * same EP. For now we can just pass '0' as line as the phone - * is only going to support either CSPS or CCM and not both at - * the same time. - */ - if (!cpr_strcasecmp(conn_type, "UDP")) { - if (sip_platform_udp_channel_sendto(send_to_proxy_handle, - pOutMessageBuf, - nbytes, - cc_remote_ipaddr, - cc_remote_port) == SIP_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_sendto()"); - return (-1); - } - } - else { - /* - * Assume TCP for now - */ - tcp_error = sip_tcp_channel_send(send_to_proxy_handle, - pOutMessageBuf, - (unsigned short)nbytes); - if (tcp_error == SIP_TCP_SEND_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_tcp_channel_send()"); - return (-1); - } - } - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Sent SIP message: handle=<%d>," - "length=<%d>, message=\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - send_to_proxy_handle, nbytes); - CCSIP_DEBUG_MESSAGE_PKT(pOutMessageBuf); - } else { - /* Create a new handle for the supplied address and port */ - cpr_socket_t one_time_handle = INVALID_SOCKET; - int status = -1; - - /* Open UDP send channel to the specified address and port */ - status = sip_platform_udp_channel_create(ip_mode, &one_time_handle, - cc_remote_ipaddr, - cc_remote_port, - local_udp_port); - if (status < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_create()"); - return (-1); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Opened a one-time UDP send channel to server " - "<%s>:<%d>, handle = %d local port= %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - cc_remote_ipaddr_str, cc_remote_port, - one_time_handle, local_udp_port); - - /* Send the message */ - if (sip_platform_udp_channel_sendto(one_time_handle, - pOutMessageBuf, - nbytes, - cc_remote_ipaddr, - cc_remote_port) == SIP_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_sendto()"); - /* Close the UDP send channel */ - status = sip_platform_udp_channel_destroy(one_time_handle); - if (status < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_destroy()"); - } - return (-1); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Sent SIP message to <%s>:<%d>, " - "handle=<%d>, length=<%d>, message=\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), cc_remote_ipaddr_str, cc_remote_port, - one_time_handle, nbytes); - CCSIP_DEBUG_MESSAGE_PKT(pOutMessageBuf); - - /* Close the UDP send channel */ - status = sip_platform_udp_channel_destroy(one_time_handle); - if (status < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_destroy()"); - return (-1); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Closed a one-time UDP send channel " - "handle = %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), one_time_handle); - } - - if (ccb) { - // - // Cancel any outstanding reTx timers, if any - // - /* - * Dont do for fallback ccb's. - */ - if ((ccb->index <= REG_BACKUP_CCB) && reTx) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Stopping reTx timer"); - sip_platform_msg_timer_stop(ccb->index); - - /* - * If the specified timeout value is not 0 and UDP, start the reTx timer - * When the phone is in remote location, then REG message send may fail - * for TCP. In that case, that message has to be retransmitted from the SIP - * layer. So if the error_no == CPR_ENOTCONN, then send the SIP message - * during next retry. - * - */ - if ((timeout > 0) && ((!cpr_strcasecmp(conn_type, "UDP") - || ((tcp_error == CPR_ENOTCONN) && (!cpr_strcasecmp(conn_type, "TCP")))))) { - void *data; - - data = isRegister ? (void *) ccb : (void *)(long)ccb->index; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"LINE %d/%d: Starting reTx timer (%d " - "msec)\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), ccb->index, ccb->dn_line, - timeout); - ccb->retx_flag = TRUE; - if (sip_platform_msg_timer_start(timeout, data, ccb->index, - pOutMessageBuf, nbytes, - (int) message_type, cc_remote_ipaddr, - cc_remote_port, isRegister) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "sip_platform_msg_timer_start()"); - ccb->retx_flag = FALSE; - } - } - } - - if (sipMethodCancel == message_type || sipMethodBye == message_type) { - gCallHistory[ccb->index].last_bye_dest_ipaddr = *cc_remote_ipaddr; - gCallHistory[ccb->index].last_bye_dest_port = cc_remote_port; - } - } - else { - sipSCB_t *scbptr = (sipSCB_t *)cbp; - ccsip_publish_cb_t *pcb_p = (ccsip_publish_cb_t *)cbp; - sipTCB_t *tcbp = (sipTCB_t *)cbp; - - if (cbp != NULL) { - sipPlatformUITimer_t *timer = NULL; - uint32_t id = 0; - - scbptr->hb.retx_flag = TRUE; - if (((ccsip_common_cb_t *)cbp)->cb_type == SUBNOT_CB) { - timer = &(sipPlatformUISMSubNotTimers[scbptr->line]); - id = scbptr->line; - } else if (((ccsip_common_cb_t *)cbp)->cb_type == PUBLISH_CB) { - timer = &(pcb_p->retry_timer); - id = pcb_p->pub_handle; - } else { // unsolicited NOTIFY - int temp_timeout = 0; - config_get_value(CFGID_TIMER_T1, &temp_timeout, sizeof(temp_timeout)); - temp_timeout = (64 * temp_timeout); - if (cprStartTimer(tcbp->timer, temp_timeout, (void *)(long)(tcbp->trxn_id)) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"%s failed", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), "cprStartTimer"); - } - } - - if (timeout > 0 && timer != NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Starting reTx timer for %d secs", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), timeout); - if (sip_platform_msg_timer_subnot_start(timeout, timer, id, - pOutMessageBuf, nbytes, - (int) message_type, - cc_remote_ipaddr, - cc_remote_port) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_msg_timer_subnot_start"); - } - } - } - - } - - return (0); -} - -/* - ** sipTransportGetListenPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: Reads and returns the Primary server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Primary Server port (Currently only SIP Proxy specific) - * - */ -uint16_t -sipTransportGetListenPort (line_t line, ccsipCCB_t *ccb) -{ - ti_config_table_t *ccm_table_ptr = NULL; - static const char *fname = "sipTransportGetListenPort"; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return 0; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ccb) { - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - } - if (ccm_table_ptr) { - CCM_ID ccm_id; - - ccm_id = ccm_table_ptr->ti_specific.ti_ccm.ccm_id; - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.", - fname, ccm_id); - return 0; - } - return ((uint16_t) CCM_Config_Table[line - 1][ccm_id]-> - ti_common.listen_port); - } else if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - return ((uint16_t) CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.listen_port); - } else { - return ((uint16_t) CCM_Config_Table[line - 1][PRIMARY_CCM]-> - ti_common.listen_port); - } - } else { - /* - * Assume CSPS for now. - */ - return ((uint16_t) CSPS_Config_Table[line - 1].ti_common.listen_port); - } -} - -/* - ** sipTransportGetTransportType - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: Reads and returns the Primary server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Primary Server port (Currently only SIP Proxy specific) - * - */ -const char * -sipTransportGetTransportType (line_t line, boolean upper_case, - ccsipCCB_t *ccb) -{ - const char *tcp, *udp, *tls; - CONN_TYPE conn_type; - ti_config_table_t *ccm_table_ptr = NULL; - static const char *fname = "sipTransportGetTransportType"; - - tcp = (upper_case) ? "TCP" : "tcp"; - udp = (upper_case) ? "UDP" : "udp"; - tls = (upper_case) ? "TLS" : "tls"; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return udp; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - // If ccb is not NULL get the conn type from cc_cfg_table_entry - // This would be the case for REGISTER/keep alive messages. - // else get from the active ccm entry if available. - if (ccb) { - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - } - if (ccm_table_ptr) { - conn_type = ccm_table_ptr->ti_common.conn_type; - } else if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - conn_type = CCM_Active_Standby_Table.active_ccm_entry->ti_common.conn_type; - } else { - conn_type = CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.conn_type; - } - } else { - /* - * Assume CSPS for now. - */ - conn_type = CSPS_Config_Table[line - 1].ti_common.conn_type; - } - switch (conn_type) { - case CONN_UDP: - return (udp); - case CONN_TCP: - case CONN_TCP_TMP: - return (tcp); - case CONN_TLS: - return (tls); - default: - return (NULL); - } -} - -/* - ** sipTransportGetServerAddrPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Wrapper function for the sip dns srv functions. - * Currently code only caters to SIP Proxies. But - * with CCM, the code will have handle the different - * scenarios of retries etc in the CCM environment as - * well. - * - * RETURNS: The dns error codes that the invoked functions return. - * - */ -int -sipTransportGetServerAddrPort (char *domain, cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, srv_handle_t *psrv_order, - boolean retried_addr) -{ - int rc; - - if (psrv_order == NULL) { - rc = sip_dns_gethostbysrvorname(domain, ipaddr_ptr, port); - } else { - rc = sip_dns_gethostbysrv(domain, ipaddr_ptr, port, psrv_order, - retried_addr); - } - return (rc); -} - -/* - ** sipTransportGetPrimServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: Reads and returns the Primary server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Primary Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetPrimServerPort (line_t line) -{ - static const char *fname = "sipTransportGetPrimServerPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - return (CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.port); - } else { - return (0); - } - } else { - /* - * Assume CSPS for now. - */ - return (CSPS_Config_Table[line - 1].ti_common.port); - } -} - -/* - ** sipTransportGetBkupServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Backup server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Backup Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetBkupServerPort (line_t line) -{ - static const char *fname = "sipTransportGetBkupServerPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - - */ - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - return (ti_csps->bkup_pxy_port); - } -} - -/* - ** sipTransportGetEmerServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Emergency server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Emergency Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetEmerServerPort (line_t line) -{ - static const char *fname = "sipTransportGetEmerServerPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - return (ti_csps->emer_pxy_port); - } -} - -/* - ** sipTransportGetOutbProxyPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Outbound server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Outbound Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetOutbProxyPort (line_t line) -{ - static const char *fname = "sipTransportGetOutbProxyPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - return (ti_csps->outb_pxy_port); - } -} - -/* - ** sipTransportGetPrimServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Primary server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP address in buffer (Currently only SIP Proxy specific) - * - */ -cpr_ip_type -sipTransportGetPrimServerAddress (line_t line, char *buffer) -{ - ti_common_t *ti_common; - cpr_ip_type ip_type = CPR_IP_ADDR_IPV4; - static const char *fname = "sipTransportGetPrimServerAddress"; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return (ip_type); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - sstrncpy(buffer, CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.addr_str, MAX_IPADDR_STR_LEN); - ip_type = CCM_Active_Standby_Table.active_ccm_entry->ti_common.addr.type; - - } else { - ti_common = &CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common; - sstrncpy(buffer, ti_common->addr_str, MAX_IPADDR_STR_LEN); - ip_type = ti_common->addr.type; - } - } else { - /* - * Assume CSPS for now. - */ - ti_common = &CSPS_Config_Table[line - 1].ti_common; - sstrncpy(buffer, ti_common->addr_str, MAX_IPADDR_STR_LEN); - ip_type = ti_common->addr.type; - } - - return(ip_type); -} - -/* - ** sipTransportGetBkupServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Backup server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP Address as uint32_t and str in buffer (Currently only - * SIP Proxy specific) - * - */ -uint16_t -sipTransportGetBkupServerAddress (cpr_ip_addr_t *pip_addr, - line_t line, char *buffer) -{ - static const char *fname = "sipTransportGetBkupServerAddress"; - *pip_addr = ip_addr_invalid; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - * This would be standby address for the ccm - */ - sstrncpy(buffer, "UNPROVISIONED", MAX_IPADDR_STR_LEN); - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - sstrncpy(buffer, ti_csps->bkup_pxy_addr_str, MAX_IPADDR_STR_LEN); - *pip_addr = ti_csps->bkup_pxy_addr; - return (1); - } -} - -/* - ** sipTransportGetEmerServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Emergency server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP address in buffer (Currently only SIP Proxy specific) - * - */ -void -sipTransportGetEmerServerAddress (line_t line, char *buffer) -{ - static const char *fname = "sipTransportGetEmerServerAddress"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - sstrncpy(buffer, "UNPROVISIONED", MAX_IPADDR_STR_LEN); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - sstrncpy(buffer, ti_csps->emer_pxy_addr_str, MAX_IPADDR_STR_LEN); - } -} - -/* - ** sipTransportGetOutbProxyAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Outbound server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP address in buffer (Currently only SIP Proxy specific) - * - */ -void -sipTransportGetOutbProxyAddress (line_t line, char *buffer) -{ - static const char *fname = "sipTransportGetOutbProxyAddress"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, line); - return; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - sstrncpy(buffer, "UNPROVISIONED", MAX_IPADDR_STR_LEN); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - sstrncpy(buffer, ti_csps->outb_pxy_addr_str, MAX_IPADDR_STR_LEN); - } -} - -/* - * sipTransportGetServerIPAddr() - * - * Perform DNS lookup on the primary proxy name and - * return its IP address. - * - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sipTransportGetServerIPAddr (cpr_ip_addr_t *pip_addr, line_t line) -{ - const char *fname = "sipTransportGetServerIPAddr"; - cpr_ip_addr_t IPAddress; - uint16_t port; - srv_handle_t srv_order = NULL; - int dnsErrorCode = 0; - char addr[MAX_IPADDR_STR_LEN]; - char obp_address[MAX_IPADDR_STR_LEN]; - - CPR_IP_ADDR_INIT(IPAddress); - - sipTransportGetOutbProxyAddress(line, obp_address); - if ((cpr_strcasecmp(obp_address, UNPROVISIONED) != 0) && - (obp_address[0] != 0) && (obp_address[0] != '0')) { - sstrncpy(addr, obp_address, MAX_IPADDR_STR_LEN); - } else { - sipTransportGetPrimServerAddress(line, addr); - } - dnsErrorCode = sipTransportGetServerAddrPort(addr, &IPAddress, &port, - &srv_order, FALSE); - if (srv_order) { - dnsFreeSrvHandle(srv_order); - } - - if (dnsErrorCode != DNS_OK) { - //CCSIP_DEBUG_TASK(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - // fname, "sipTransportGetServerAddrPort"); - dnsErrorCode = dnsGetHostByName(addr, &IPAddress, 100, 1); - } - - if (dnsErrorCode != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "dnsGetHostByName()"); - } - *pip_addr = IPAddress; - util_ntohl(pip_addr, &IPAddress); -} - -/* - ** sip_regmgr_set_cc_info - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_set_cc_info (line_t line, line_t dn_line, - CC_ID *cc_type, void *cc_table_entry) -{ - static const char *fname = "sip_regmgr_set_cc_info"; - ti_config_table_t **active_standby_table_entry = - (ti_config_table_t **) cc_table_entry; - - /* - * Checking for dn_line < 1, since we dereference the Config_Tables using - * dn_line-1 - */ - if (((int)dn_line < 1) || ((int)dn_line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.", - fname, dn_line); - return; - } - - *cc_type = CC_Config_Table[dn_line - 1].cc_type; - if (*cc_type == CC_CCM) { - if (line == REG_BACKUP_CCB) { - *active_standby_table_entry = - CCM_Active_Standby_Table.standby_ccm_entry; - } else { - *active_standby_table_entry = - CCM_Active_Standby_Table.active_ccm_entry; - } - } -} - -int -sipTransportGetCCType (int line, void *cc_table_entry) -{ - if (cc_table_entry != NULL) { - cc_table_entry = CC_Config_Table[line - 1].cc_table_entry; - } - return (CC_Config_Table[line - 1].cc_type); -} - -/** - * - * SIPTransportUDPListenForSipMessages - * - * Establish a UDP socket to listen to for incoming SIP messages - * - * Parameters: None - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -int -SIPTransportUDPListenForSipMessages (void) -{ - static const char *fname = "SIPTransportUDPListenForSipMessages"; - uint32_t local_sip_control_port; - cpr_ip_addr_t local_sip_ip_addr; - int ip_mode = CPR_IP_MODE_IPV4; - - /* - * Start listening on port 5060 for incoming SIP messages - */ - CPR_IP_ADDR_INIT(local_sip_ip_addr); - - config_get_value(CFGID_VOIP_CONTROL_PORT, &local_sip_control_port, - sizeof(local_sip_control_port)); - -#ifdef IPV6_STACK_ENABLED - config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); -#endif - switch (ip_mode) { - case CPR_IP_MODE_IPV4: - local_sip_ip_addr.type = CPR_IP_ADDR_IPV4; - local_sip_ip_addr.u.ip4 = 0; - break; - case CPR_IP_MODE_IPV6: - case CPR_IP_MODE_DUAL: - local_sip_ip_addr = ip_addr_invalid; - local_sip_ip_addr.type = CPR_IP_ADDR_IPV6; - break; - default: - break; - } - /* Based on mode type configure the IP address IPv4 or IPv6 */ - - - if (sip_platform_udp_channel_listen(ip_mode, &listen_socket, &local_sip_ip_addr, - (uint16_t) local_sip_control_port) - != SIP_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_platform_udp_channel_listen(0, %d) " - "returned error.\n", fname, local_sip_control_port); - return SIP_ERROR; - } - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Listening for SIP messages on UDP port <%d>, handle=<%d>", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), local_sip_control_port, listen_socket); - - return SIP_OK; -} - -static void -sipTransportCfgTableInit (boolean *cc_udp) -{ -// int cc_num; - line_t line; - CC_ID dev_cc_type = CC_OTHER; - uint32_t transport_prot = CONN_UDP; - ti_common_t *ti_common; - static const char *fname = "sipTransportCfgTableInit"; - - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Transport Interface init", DEB_F_PREFIX_ARGS(SIP_TRANS, fname)); - - ti_common = &CSPS_Config_Table[0].ti_common; - sip_config_get_proxy_addr(1, ti_common->addr_str, sizeof(ti_common->addr_str)); - - if (!cpr_strcasecmp(ti_common->addr_str, "USECALLMANAGER")) { - dev_cc_type = CC_CCM; - } - if (dev_cc_type == CC_CCM) { - /* - * Initialize the ccm table - */ - uint32_t listen_port; - CCM_ID ccm_id; - ti_ccm_t *ti_ccm; - - memset(CCM_Config_Table, 0, - (sizeof(uint32_t) * MAX_CCM * (MAX_REG_LINES + 1))); - config_get_value(CFGID_VOIP_CONTROL_PORT, &listen_port, - sizeof(listen_port)); - config_get_value(CFGID_TRANSPORT_LAYER_PROT, &transport_prot, - sizeof(transport_prot)); - if (transport_prot != CONN_UDP) { - *cc_udp = FALSE; - } - - /* - * Initialize the dummy entry and point the Active - * and standby to it. - */ - CCM_Dummy_Entry.cc_type = CC_CCM; - CCM_Dummy_Entry.ti_specific.ti_ccm.ccm_id = MAX_CCM; - CCM_Dummy_Entry.ti_common.conn_type = (CONN_TYPE) transport_prot; - - for (ccm_id = PRIMARY_CCM; ccm_id < MAX_CCM; ccm_id++) { - uint32_t port; - phone_local_tcp_port[ccm_id] = 0; - ti_common = &CCM_Device_Specific_Config_Table[ccm_id].ti_common; - ti_ccm = &CCM_Device_Specific_Config_Table[ccm_id].ti_specific.ti_ccm; - - CCM_Device_Specific_Config_Table[ccm_id].cc_type = CC_CCM; - sip_regmgr_get_config_addr(ccm_id, ti_common->addr_str); - - config_get_value(ccm_config_id_port[ccm_id], &port, sizeof(port)); - ti_common->port = (uint16_t) port; - ti_common->conn_type = ti_common->configured_conn_type = (CONN_TYPE) transport_prot; - ti_common->listen_port = (uint16_t) listen_port; - ti_common->handle = INVALID_SOCKET; - /* - * CCM specific config variable read - */ - ti_ccm->ccm_id = (CCM_ID) ccm_id; - ti_ccm->sec_level = NON_SECURE; - ti_ccm->is_valid = 1; - config_get_value(ccm_config_id_sec_level[ccm_id], - &ti_ccm->sec_level, sizeof(ti_ccm->sec_level)); - config_get_value(ccm_config_id_is_valid[ccm_id], - &ti_ccm->is_valid, sizeof(ti_ccm->is_valid)); - if ((ti_ccm->sec_level == NON_SECURE) && - (transport_prot == CONN_TLS)) { - ti_common->conn_type = CONN_TCP; - } - for (line = 0; line < MAX_REG_LINES; line++) { - CCM_Config_Table[line][ccm_id] = - &CCM_Device_Specific_Config_Table[ccm_id]; - if (ccm_id == PRIMARY_CCM) { - CC_Config_Table[line].cc_type = CC_CCM; - CC_Config_Table[line].cc_table_entry = (void *) - CCM_Config_Table[ccm_id]; - } - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"For CCM%d: line %d Addr: %s Port: %d" - " listen Port: %d transport: %d" - " Sec Level: %d Is Valid: %d\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ccm_id, line, ti_common->addr_str, - ti_common->port, ti_common->listen_port, - ti_common->conn_type, ti_ccm->sec_level, - ti_ccm->is_valid); - } - } else { - ti_csps_t *ti_csps = &CSPS_Device_Specific_Config_Table; - uint32_t bkup_pxy_port; - uint32_t emer_pxy_port; - uint32_t outb_pxy_port; - uint32_t listen_port; - - sip_config_get_backup_proxy_addr(&(ti_csps->bkup_pxy_addr), - ti_csps->bkup_pxy_addr_str, - sizeof(ti_csps->bkup_pxy_addr_str)); - config_get_value(CFGID_PROXY_BACKUP_PORT, &bkup_pxy_port, - sizeof(bkup_pxy_port)); - ti_csps->bkup_pxy_port = (uint16_t) bkup_pxy_port; - config_get_string(CFGID_PROXY_EMERGENCY, ti_csps->emer_pxy_addr_str, - sizeof(ti_csps->emer_pxy_addr_str)); - config_get_value(CFGID_PROXY_EMERGENCY_PORT, &emer_pxy_port, - sizeof(emer_pxy_port)); - ti_csps->emer_pxy_port = (uint16_t) emer_pxy_port; - config_get_string(CFGID_OUTBOUND_PROXY, ti_csps->outb_pxy_addr_str, - sizeof(ti_csps->outb_pxy_addr_str)); - config_get_value(CFGID_OUTBOUND_PROXY_PORT, &outb_pxy_port, - sizeof(outb_pxy_port)); - ti_csps->outb_pxy_port = (uint16_t) outb_pxy_port; - - config_get_value(CFGID_VOIP_CONTROL_PORT, &listen_port, - sizeof(listen_port)); - for (line = 0; line < MAX_REG_LINES; line++) { - ti_common = &CSPS_Config_Table[line].ti_common; - CSPS_Config_Table[line].ti_specific.ti_csps = ti_csps; - - sip_config_get_proxy_addr((line_t)(line + 1), ti_common->addr_str, - sizeof(ti_common->addr_str)); - ti_common->port = sip_config_get_proxy_port((line_t) (line + 1)); - ti_common->conn_type = CONN_UDP; - ti_common->listen_port = (uint16_t) listen_port; - ti_common->addr = ip_addr_invalid; - ti_common->handle = INVALID_SOCKET; - - CC_Config_Table[line].cc_table_entry = (void *) NULL; // NULL for now. - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"line %d Addr: %s Port: %d and listen Port: %d" - " transport: %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - line, ti_common->addr_str, ti_common->port, - ti_common->listen_port, ti_common->conn_type); - if (line == 0) { - ti_csps_t *ti_csps_cfg_table; - - ti_csps_cfg_table = CSPS_Config_Table[line].ti_specific.ti_csps; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"bkup Addr: %s and Port: %d", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ti_csps_cfg_table->bkup_pxy_addr_str, - ti_csps_cfg_table->bkup_pxy_port); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"emer Addr: %s and Port: %d", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ti_csps_cfg_table->emer_pxy_addr_str, - ti_csps_cfg_table->emer_pxy_port); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"outb Addr: %s and Port: %d", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ti_csps_cfg_table->outb_pxy_addr_str, - ti_csps_cfg_table->outb_pxy_port); - } - } - } -} - - -/* - ** sipTransportInit - * - * FILENAME: sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * Note: Make sure this gets calls during config change notifications. - * from softphone\src-win\global_stub.c's and src-arm-79xx\config.c's - * config_commit() function that calls the prot_config_change_notify(). - * RETURNS: - * - */ -int -sipTransportInit (void) -{ - int result = 0; - static const char *fname = "sipTransportInit"; - boolean cc_udp = TRUE; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Transport_interface: Init function " - "call !\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname)); - /* - * Init the cc related info into the cc config table - */ - sipTransportCfgTableInit(&cc_udp); - /* - * Make sure that the IP stack is up before trying to connect - */ - if (PHNGetState() > STATE_IP_CFG) { - if (cc_udp) { - /* - * By now we know the DHCP is up, so we can - * start open sockets for listening for SIP messages and - * the UDP channel to the SIP proxy server - */ - - if (SIPTransportUDPListenForSipMessages() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"device unable to" - " receive SIP messages.\n", fname); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"CCM in non udp mode so not " - "opening separate listen socket.\n",DEB_F_PREFIX_ARGS(SIP_TRANS, fname)); - } - if (sip_regmgr_init() != SIP_OK) { - result = SIP_ERROR; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"IP Stack Not " - "Initialized.\n", fname); - result = -1; - } - return (result); -} - -/* - ** sipTransportShutdown - * - * FILENAME: sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sipTransportShutdown () -{ - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Transport_interface: Shutting down!", DEB_F_PREFIX_ARGS(SIP_TRANS, "sipTransportShutdown")); - sip_regmgr_destroy_cc_conns(); -} - -/* - ** sipTransportClearServerHandle - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: ip addr, port, connid - * - * DESCRIPTION: This function clears the server handle and port - * - * RETURNS: none - * - */ -void -sipTransportClearServerHandle (cpr_ip_addr_t *ipaddr, uint16_t port, int connid) -{ - - ti_common_t *ti_common; - CCM_ID cc_index; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"addr %p port %d connid %d", - DEB_F_PREFIX_ARGS(SIP_TRANS, "sipTransportClearServerHandle"), ipaddr, port, connid); - for (cc_index = PRIMARY_CCM; cc_index < MAX_CCM; cc_index++) { - ti_common = &CCM_Device_Specific_Config_Table[cc_index].ti_common; - if (util_compare_ip(&(ti_common->addr),ipaddr) && ti_common->port == port) { - sip_tcp_purge_entry(connid); - ti_common->handle = INVALID_SOCKET; - ti_common->listen_port = 0; - return; - } - } -} - -/* - ** sipTransportSetServerHandleAndPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server handle for a particular - * line id. - * - * RETURNS: The server handle - */ -void -sipTransportSetServerHandleAndPort (cpr_socket_t socket_handle, - uint16_t listen_port, - ti_config_table_t *ccm_table_entry) -{ - ti_common_t *ti_common; - ti_ccm_t *ti_ccm; - - ti_ccm = &ccm_table_entry->ti_specific.ti_ccm; - - if (ti_ccm->ccm_id < MAX_CCM) { - ti_common = &CCM_Device_Specific_Config_Table[ti_ccm->ccm_id].ti_common; - ti_common->handle = socket_handle; - ti_common->listen_port = listen_port; - } -} - -void -sipTransportSetSIPServer() { - char addr_str[MAX_IPADDR_STR_LEN]; - init_empty_str(addr_str); - config_get_string(CFGID_CCM1_ADDRESS, addr_str, MAX_IPADDR_STR_LEN); - sstrncpy(CCM_Config_Table[0][0]->ti_common.addr_str, addr_str, MAX_IPADDR_STR_LEN); - sstrncpy(CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.addr_str, addr_str, MAX_IPADDR_STR_LEN); -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_csps_transport.c b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_csps_transport.c deleted file mode 100644 index 9982ab3cb81..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_csps_transport.c +++ /dev/null @@ -1,206 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "cpr_types.h" -#include "phone_types.h" -#include "cpr_string.h" -#include "cpr_socket.h" -#include "ccsip_platform.h" -#include "sip_common_transport.h" -#include "sip_csps_transport.h" -#include "util_string.h" - -int -sip_dns_gethostbysrv (char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *psrv_order, - boolean retried_addr) -{ - int bLoopDeath = 0; - uint16_t tmp_port = 0; - int rc=DNS_ERR_NOHOST; - - while (!bLoopDeath) { - /* Try and fetch a proxy using DNS SRV records */ - rc = dnsGetHostBySRV("sip", "udp", (char *) domain, ipaddr_ptr, - &tmp_port, 100, 1, psrv_order); - switch (rc) { - case DNS_ERR_TTL_EXPIRED: - case DNS_ERR_NOHOST: - /* Re-try if all entries for this proxy have expired - * or the end of the call record list was reached. - */ - break; - default: - /* Run don't walk to the nearest exit */ - bLoopDeath = 1; - break; - } - } - if (tmp_port) { - *port = tmp_port; - } - return rc; -} - -int -sip_dns_gethostbysrvorname (char *hname, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port) -{ - /* - * OK according to rfc2543bis-03 - * 1. If the destination is an IP address it is used. If no port is - * specified then use 5060 - * 2. If the destination specifies the default port (5060) or no port - * then try SRV - * 3. If the destination specifies a port number other than 5060 or - * there are no SRV records A record lookup - */ - srv_handle_t srv_order = NULL; - int rc=DNS_ERR_NOHOST; - - if ((*port == SIP_WELL_KNOWN_PORT) || (*port == 0)) { - rc = sip_dns_gethostbysrv(hname, ipaddr_ptr, port, &srv_order, FALSE); - } - if (rc != DNS_OK) { - rc = dnsGetHostByName(hname, ipaddr_ptr, 100, 1); - } - if (srv_order) { - dnsFreeSrvHandle(srv_order); - } - return rc; -} - -cpr_socket_t -sipTransportCSPSGetProxyHandleByDN (line_t dn) -{ - static const char *fname = "sipTransportCSPSGetProxyHandleByDN"; - ti_common_t *ti_common; - - if ((((int)dn) < 1) || (((int)dn) > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN %d out of " - "bounds.\n", fname, dn); - return INVALID_SOCKET; - } - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - return ((cpr_socket_t) ti_common->handle); -} - -short -sipTransportCSPSGetProxyPortByDN (line_t dn) -{ - static const char *fname = "sipTransportCSPSGetProxyPortByDN"; - ti_common_t *ti_common; - - if ((((int)dn) < 1) || (((int)dn) > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN %d out of " - "bounds.\n", fname, dn); - return (-1); - } - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - return ((short) ti_common->port); -} - -// This function is broken -uint16_t -sipTransportCSPSGetProxyAddressByDN(cpr_ip_addr_t *ip_addr, line_t dn) -{ -// static const char *fname = "sipTransportCSPSGetProxyAddressByDN"; -// ti_common_t *ti_common; -// -// if ((((int)dn) < 1) || (((int)dn) > MAX_REG_LINES)) { -// CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN out of " -// "bounds.\n", fname, dn); -// return (0); -// } -// -// ti_common = &CSPS_Config_Table[dn - 1].ti_common; -// -// ip_addr = &(ti_common->addr); -// - return(1); -} - -/* - * sip_config_get_proxy_port() - * - * Get table entry from the table string and option number - */ -uint16_t -sip_config_get_proxy_port (line_t line) -{ - uint32_t port; - - config_get_line_value(CFGID_PROXY_PORT, &port, sizeof(port), line); - - if (port == 0) { - config_get_line_value(CFGID_PROXY_PORT, &port, sizeof(port), DEFAULT_LINE); - } - - return ((uint16_t) port); -} - -/* - * sip_config_get_proxy_addr() - * - * Get table entry from the table string and option number - */ -void -sip_config_get_proxy_addr (line_t line, char *buffer, int buffer_len) -{ - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, line, buffer_len); - - if ((strcmp(buffer, UNPROVISIONED) == 0) || (buffer[0] == '\0')) { - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, DEFAULT_LINE, - buffer_len); - } -} - -/* - * sip_config_get_backup_proxy_addr() - * - * Get table entry from the table string and option number - */ -uint16_t -sip_config_get_backup_proxy_addr (cpr_ip_addr_t *IPAddress, char *buffer, int buffer_len) -{ - - *IPAddress = ip_addr_invalid; - - config_get_string(CFGID_PROXY_BACKUP, buffer, buffer_len); - - if ((cpr_strcasecmp(buffer, UNPROVISIONED) == 0) || (buffer[0] == 0)) { - buffer[0] = 0; - } else { - (void) str2ip(buffer, IPAddress); - } - return (1); -} - -/* - * sipTransportCSPSClearProxyHandle - * - * Clear Proxy handle from the table - */ -void -sipTransportCSPSClearProxyHandle (cpr_ip_addr_t *ipaddr, - uint16_t port, - cpr_socket_t this_fd) -{ - ti_common_t *ti_common; - int i; - - for (i = 0; i < MAX_REG_LINES; i++) { - ti_common = &CSPS_Config_Table[i].ti_common; - if ((ti_common->port == port) && - util_compare_ip(&(ti_common->addr),ipaddr) && - (ti_common->handle == this_fd)) { - ti_common->handle = INVALID_SOCKET; - return; - } - } -} diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_interface_regmgr.c b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_interface_regmgr.c deleted file mode 100644 index 3ba878fa6e1..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_interface_regmgr.c +++ /dev/null @@ -1,313 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "ccsip_task.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" -#include "phone.h" -#include "text_strings.h" -#include "string_lib.h" -#include "gsm.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "sip_interface_regmgr.h" -#include "ccsip_subsmanager.h" -#include "platform_api.h" - -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern cc_config_table_t CC_Config_Table[]; - -/* - ** sip_regmgr_send_status - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: msg id and the src task id. - * - * DESCRIPTION: Posts the message to the destination task as - * requested. - * - * RETURNS: - * - */ -void -sip_regmgr_send_status (reg_srcs_t src_id, reg_status_t msg_id) -{ - static const char fname[] = "sip_regmgr_send_status"; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"src_id: %d msg_id: %d", DEB_F_PREFIX_ARGS(SIP_REG, fname), src_id, msg_id); - - if (msg_id == REG_ALL_FAIL) { - //All failed ind to platform - ui_reg_all_failed(); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"REG ALL FAILED", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - return; -} - -/* - ** sip_regmgr_get_cc_mode - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETER: line number for which mode is requested. Initially - * for the ccm it will be same for all linesm, but - * will change when mixed mode support is added. - * DESCRIPTION: returns the current mode the phone is in i.e. - * talking to a ccm -or- not talking to a ccm. - * - * RETURNS: - * - */ -reg_mode_t -sip_regmgr_get_cc_mode (line_t line) -{ - if (CCM_Active_Standby_Table.active_ccm_entry) { - return (REG_MODE_CCM); - } else { - return (REG_MODE_NON_CCM); - } -} - - -boolean -sip_platform_is_phone_idle (void) -{ - if (gsm_is_idle()) { - return (TRUE); - } - return (FALSE); -} - -/* - ** sip_platform_fallback_ind - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * - * RETURNS: - * - */ -void -sip_platform_fallback_ind (CCM_ID ccm_id) -{ - static const char fname[] = "sip_platform_fallback_ind"; - int from_id = CC_TYPE_CCM; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ccm-id: %d", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - - platform_reg_fallback_ind((void *)(long) from_id); -} - -/* - ** sip_platform_failover_ind - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -boolean plat_is_network_interface_changed(void ); -void -sip_platform_failover_ind (CCM_ID ccm_id) -{ - static const char fname[] = "sip_platform_failover_ind"; - int to_id = CC_TYPE_CCM; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ccm-id=%s=%d", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname), - ccm_id == PRIMARY_CCM ? "PRIMARY_CCM" : - ccm_id == SECONDARY_CCM ? "SECONDARY_CCM" : - ccm_id == TERTIARY_CCM ? "TERTIARY_CCM" : "Unknown", - ccm_id); - - if (plat_is_network_interface_changed()) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"network i/f changed, sending REG_ALL_FAIL instead", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - ui_reg_all_failed(); - return; - } - - if (ccm_id == UNUSED_PARAM){ - to_id = 3; - } - platform_reg_failover_ind((void *)(long) to_id); -} - -/* - ** sip_platform_logout_reset_req - * - * FILENAME: ip_phone\sip\sip_platform_logout_reset_req - * - * PARAMETERS: void - * - * DESCRIPTION: Trigger vPhone auto logout and re-DHCP - * - * RETURNS: none - * - */ -void -sip_platform_logout_reset_req(void) -{ - platform_logout_reset_req(); -} - -/* - ** sip_platform_set_ccm_status - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_platform_set_ccm_status (void) -{ - static const char fname[] = "sip_platform_set_ccm_status"; - ti_config_table_t *ccm_table_entry; - char dest_addr_str[MAX_IPADDR_STR_LEN]; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - ccm_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - if (ccm_table_entry) { - sstrncpy(dest_addr_str, ccm_table_entry->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"addr str1 %s", DEB_F_PREFIX_ARGS(SIP_REG, fname), dest_addr_str); - - ui_set_ccm_conn_status(dest_addr_str, CCM_STATUS_ACTIVE); - } - ccm_table_entry = CCM_Active_Standby_Table.standby_ccm_entry; - if (ccm_table_entry) { - - ui_set_ccm_conn_status(ccm_table_entry->ti_common.addr_str, - CCM_STATUS_STANDBY); - } -} - -/* - ** sip_regmgr_get_ccm_id - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: ccb - * - * DESCRIPTION: get ccm id from ccb - * - * RETURNS: ccm id - */ -CCM_ID -sip_regmgr_get_ccm_id (ccsipCCB_t *ccb) -{ - ti_config_table_t *ccm_table_ptr = NULL; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr) { - return (ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - } - return (UNUSED_PARAM); -} - -/* - ** sip_platform_cc_mode_notify - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: mode - * - * DESCRIPTION: notify cc mode - * - * RETURNS: None - */ -void -sip_platform_cc_mode_notify (void) -{ - int mode; - - if (CC_Config_Table[0].cc_type == CC_CCM) { - mode = REG_MODE_CCM; - } else { - mode = REG_MODE_NON_CCM; - } - platform_cc_mode_notify(mode); -} - -/* - ** sip_regmgr_get_sec_level - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETER: line number for which mode is requested. Initially - * for the ccm it will be same for all linesm, but - * will change when mixed mode support is added. - * DESCRIPTION: returns the current sec level for the phone - * values will be NON-SECURE, AUTHENTICATED and - * ENCRYPTED. - * - * RETURNS: sec level - * - */ -sec_level_t -sip_regmgr_get_sec_level (line_t line) -{ - ti_config_table_t *ccm_table_entry; - ti_ccm_t *ti_ccm; - - if (CCM_Active_Standby_Table.active_ccm_entry) { - ccm_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - ti_ccm = &ccm_table_entry->ti_specific.ti_ccm; - return ((sec_level_t) ti_ccm->sec_level); - } else { - return (NON_SECURE); - } -} - -/* - ** sip_regmgr_srtp_fallback_enabled - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETER: line number for which mode is requested. Initially - * for the ccm it will be same for all linesm, but - * will change when mixed mode support is added. - * DESCRIPTION: returns whether the SRTP fallback is enabled or not. - * - * RETURNS: sec level - */ -boolean -sip_regmgr_srtp_fallback_enabled (line_t line) -{ - ccsipCCB_t *ccb; - line_t ndx; - - if ((line == 0) || (line > MAX_REG_LINES)) { - /* Invalid Line, requested */ - return 0; - } - - /* Map the (dn)line number to registered CCB */ - ndx = line - 1 + REG_CCB_START; - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - if (ccb->supported_tags & cisco_srtp_fallback_tag) { - return (TRUE); - } - } - return (FALSE); -} - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c deleted file mode 100644 index bc933e825a0..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c +++ /dev/null @@ -1,278 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_string.h" -#include "cpr_threads.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "phntask.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_task.h" -#include "sip_socket_api.h" -#include "platform_api.h" -#include -#include -#include -#include "prprf.h" - -/*--------------------------------------------------------- - * - * Definitions - * - */ - -/* The maximum number of messages parsed from the message queue at one time */ -#define MAX_SIP_MESSAGES 8 - -/* The maximum number of connections allowed */ -#define MAX_SIP_CONNECTIONS (64 - 2) - -#define SIP_PAUSE_WAIT_IPC_LISTEN_READY_TIME 50 /* 50ms. */ -#define SIP_MAX_WAIT_FOR_IPC_LISTEN_READY 1200 /* 50 * 1200 = 1 minutes */ - -/*--------------------------------------------------------- - * - * Local Variables - * - */ -fd_set read_fds; -fd_set write_fds; -static cpr_socket_t listen_socket = INVALID_SOCKET; -static cpr_socket_t sip_ipc_serv_socket = INVALID_SOCKET; -static cpr_socket_t sip_ipc_clnt_socket = INVALID_SOCKET; -static boolean main_thread_ready = FALSE; -uint32_t nfds = 0; -sip_connection_t sip_conn; - -/* - * Internal message structure between main thread and - * message queue waiting thread. - */ -typedef struct sip_int_msg_t_ { - void *msg; - phn_syshdr_t *syshdr; -} sip_int_msg_t; - -/* Internal message queue (array) */ -static sip_int_msg_t sip_int_msgq_buf[MAX_SIP_MESSAGES] = {{0,0},{0,0}}; - - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -extern sipGlobal_t sip; -extern boolean sip_reg_all_failed; - - -/*--------------------------------------------------------- - * - * Function declarations - * - */ -//static void write_to_socket(cpr_socket_t s); -//static int read_socket(cpr_socket_t s); - -/*--------------------------------------------------------- - * - * Functions - * - */ - -/** - * - * sip_platform_task_init - * - * Initialize the SIP Task - * - * Parameters: None - * - * Return Value: None - * - */ -static void -sip_platform_task_init (void) -{ - uint16_t i; - - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - sip_conn.read[i] = INVALID_SOCKET; - sip_conn.write[i] = INVALID_SOCKET; - } - - /* - * Initialize cprSelect call parameters - */ - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - return; -} - - -/** - * sip_process_int_msg - process internal IPC message from the - * the message queue waiting thread. - * - * @param - none. - * - * @return none. - */ -static void sip_process_int_msg (void) -{ - const char *fname = "sip_process_int_msg"; - ssize_t rcv_len; - uint8_t num_messages = 0; - uint8_t response = 0; - sip_int_msg_t *int_msg; - void *msg; - phn_syshdr_t *syshdr; - - /* read the msg count from the IPC socket */ - rcv_len = cprRecv(sip_ipc_serv_socket, &num_messages, - sizeof(num_messages), 0); - - if (rcv_len < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"read IPC failed:" - " errno=%d\n", fname, cpr_errno); - return; - } - - if (num_messages == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"message queue is empty!", fname); - return; - } - - if (num_messages > MAX_SIP_MESSAGES) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"number of messages on queue exceeds maximum %d", fname, - num_messages); - num_messages = MAX_SIP_MESSAGES; - } - - /* process messages */ - int_msg = &sip_int_msgq_buf[0]; - while (num_messages) { - msg = int_msg->msg; - syshdr = int_msg->syshdr; - if (msg != NULL && syshdr != NULL) { - if (syshdr->Cmd == THREAD_UNLOAD) { - /* - * Cleanup here, as SIPTaskProcessListEvent wont return. - * - Remove last tmp file and tmp dir. - */ - cprCloseSocket(sip_ipc_serv_socket); - } - SIPTaskProcessListEvent(syshdr->Cmd, msg, syshdr->Usr.UsrPtr, - syshdr->Len); - cprReleaseSysHeader(syshdr); - - int_msg->msg = NULL; - int_msg->syshdr = NULL; - } - - num_messages--; /* one less message to work on */ - int_msg++; /* advance to the next message */ - } - - /* - * Signal message queue waiting thread to get more messages. - */ - if (cprSend(sip_ipc_serv_socket, (void *)&response, - sizeof(response), 0) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sending IPC", fname); - } -} - -/** - * - * sip_platform_task_set_listen_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_listen_socket (cpr_socket_t s) -{ - listen_socket = s; - sip_platform_task_set_read_socket(s); -} - -/** - * - * sip_platform_task_set_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_read_socket (cpr_socket_t s) -{ -#if 0 - /* Removed calls to select(). See bug 1049291 */ - if (s != INVALID_SOCKET) { - FD_SET(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - } -#endif -} - -/** - * - * sip_platform_task_reset_listen_socket - * - * Mark the socket as INVALID - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_reset_listen_socket (cpr_socket_t s) -{ - sip_platform_task_clr_read_socket(s); - listen_socket = INVALID_SOCKET; -} - -/** - * - * sip_platform_task_clr_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_clr_read_socket (cpr_socket_t s) -{ -#if 0 - /* Removed calls to select(). See bug 1049291 */ - if (s != INVALID_SOCKET) { - FD_CLR(s, &read_fds); - } -#endif -} - diff --git a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_win32_task.c b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_win32_task.c deleted file mode 100755 index cc11e59b9f1..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_win32_task.c +++ /dev/null @@ -1,340 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_string.h" -#include "cpr_threads.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "sip_interface_regmgr.h" -#include "phntask.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_task.h" - -/*--------------------------------------------------------- - * - * Definitions - * - */ - -/* The maximum number of messages parsed from the message queue at one time */ -#define MAX_SIP_MESSAGES 8 - -/* The maximum number of connections allowed */ -#define MAX_SIP_CONNECTIONS (64 - 2) - -/* The socket select waiting time out values */ -#define SIP_SELECT_NORMAL_TIMEOUT 25000 /* normal select timeout in usec*/ -#define SIP_SELECT_QUICK_TIMEOUT 0 /* quick select timeout in usec */ - -/*--------------------------------------------------------- - * - * Local Variables - * - */ -fd_set read_fds; -fd_set write_fds; -static cpr_socket_t listen_socket = INVALID_SOCKET; -uint32_t nfds = 0; -sip_connection_t sip_conn; - - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -extern sipGlobal_t sip; - - -/*--------------------------------------------------------- - * - * Function declarations - * - */ -//static void write_to_socket(cpr_socket_t s); -//static int read_socket(cpr_socket_t s); - - -/*--------------------------------------------------------- - * - * Functions - * - */ - -/** - * - * sip_platform_task_init - * - * Initialize the SIP Task - * - * Parameters: None - * - * Return Value: None - * - */ -static void -sip_platform_task_init (void) -{ - uint16_t i; - - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - sip_conn.read[i] = INVALID_SOCKET; - sip_conn.write[i] = INVALID_SOCKET; - } - - /* - * Initialize cprSelect call parameters - */ - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - return; -} - - -/** - * - * sip_platform_task_loop - * - * Run the SIP task - * - * Parameters: arg - SIP message queue - * - * Return Value: None - * - */ -void -sip_platform_task_loop (void *arg) -{ - static const char *fname = "sip_platform_task_loop"; - int pending_operations; - struct cpr_timeval timeout; - void *msg; - uint32_t cmd; - uint16_t len; - void *usr; - phn_syshdr_t *syshdr; - uint16_t i; - fd_set sip_read_fds; -// fd_set sip_write_fds; - - sip_msgq = (cprMsgQueue_t) arg; - if (!sip_msgq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_msgq is null, exiting", fname); - return; - } - sip.msgQueue = sip_msgq; - - sip_platform_task_init(); - /* - * Initialize the SIP task - */ - SIPTaskInit(); - - if (platThreadInit("sip_platform_task_loop") != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM", fname); - return; - } - - /* - * Adjust relative priority of SIP thread. - */ - (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY); - - /* - * Set the SIP task timeout at 25 milliseconds - */ - timeout.tv_sec = 0; - timeout.tv_usec = SIP_SELECT_NORMAL_TIMEOUT; - - /* - * On Win32 platform, the random seed is stored per thread; therefore, - * each thread needs to seed the random number. It is recommended by - * MS to do the following to ensure randomness across application - * restarts. - */ - cpr_srand((unsigned int)time(NULL)); - - /* - * Main Event Loop - */ - while (TRUE) { - /* - * Wait on events or timeout - */ - sip_read_fds = read_fds; - -// sip_write_fds = write_fds; - pending_operations = cprSelect((nfds + 1), - &sip_read_fds, - NULL, - NULL, &timeout); - if (pending_operations == SOCKET_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSelect() failed: errno=%d", - fname, cpr_errno); - } else if (pending_operations) { - /* - * Listen socket is set only if UDP transport has been - * configured. So see if the select return was for read - * on the listen socket. - */ - if ((listen_socket != INVALID_SOCKET) && - (sip.taskInited == TRUE) && - FD_ISSET(listen_socket, &sip_read_fds)) { - sip_platform_udp_read_socket(listen_socket); - pending_operations--; - } - /* - * Check all sockets for stuff to do - */ - for (i = 0; ((i < MAX_SIP_CONNECTIONS) && - (pending_operations != 0)); i++) { - if ((sip_conn.read[i] != INVALID_SOCKET) && - FD_ISSET(sip_conn.read[i], &sip_read_fds)) { - /* - * Assume tcp - */ - sip_tcp_read_socket(sip_conn.read[i]); - pending_operations--; - } - /* - if ((sip_conn.write[i] != INVALID_SOCKET) && - FD_ISSET(sip_conn.write[i], &sip_write_fds)) { - int connid; - - connid = sip_tcp_fd_to_connid(sip_conn.write[i]); - if (connid >= 0) { - sip_tcp_resend(connid); - } - pending_operations--; - } - */ - } - } - - /* - * Process all messages on the message queue - * (e.g. timer callbacks) - */ - i = 0; - while (i++ < MAX_SIP_MESSAGES) { - msg = cprGetMessage(sip_msgq, FALSE, (void **) &syshdr); - if (msg != NULL) { - cmd = syshdr->Cmd; - len = syshdr->Len; - usr = syshdr->Usr.UsrPtr; - SIPTaskProcessListEvent(cmd, msg, usr, len); - cprReleaseSysHeader(syshdr); - syshdr = NULL; - } else { - /* Stop checking for msgs if the queue is empty */ - if (syshdr != NULL) { - cprReleaseSysHeader(syshdr); - syshdr = NULL; - } - break; - } - } - - /* - * If message servicing loop reaches the maximum loop limit - * it is possible that there are more messages left on the message - * queue. Shorten the socket select time out to come back and - * check the message queue for the message that might be left on - * the queue. - */ - if (i >= MAX_SIP_MESSAGES) { - timeout.tv_usec = SIP_SELECT_QUICK_TIMEOUT; - } else { - /* set normal time out value to poll msg. queue */ - timeout.tv_usec = SIP_SELECT_NORMAL_TIMEOUT; - } - } -} - -/** - * - * sip_platform_task_set_listen_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_listen_socket (cpr_socket_t s) -{ - listen_socket = s; - sip_platform_task_set_read_socket(s); -} - -/** - * - * sip_platform_task_set_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_read_socket (cpr_socket_t s) -{ - if (s != INVALID_SOCKET) { - FD_SET(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - } -} - -/** - * - * sip_platform_task_reset_listen_socket - * - * Mark the socket as INVALID - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_reset_listen_socket (cpr_socket_t s) -{ - sip_platform_task_clr_read_socket(s); - listen_socket = INVALID_SOCKET; -} - -/** - * - * sip_platform_task_clr_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_clr_read_socket (cpr_socket_t s) -{ - if (s != INVALID_SOCKET) { - FD_CLR(s, &read_fds); - } -} - diff --git a/media/webrtc/signaling/src/sipcc/core/src-common/configapp.c b/media/webrtc/signaling/src/sipcc/core/src-common/configapp.c deleted file mode 100644 index 0c4bbfd3847..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/src-common/configapp.c +++ /dev/null @@ -1,145 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_timers.h" -#include "cpr_strings.h" -#include "ccsip_subsmanager.h" -#include "subapi.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" - -int32_t g_configappDebug = 1; - -extern void update_kpmlconfig (int kpmlVal); -/* - * Function: configapp_init() - * - * Parameters: none - * - * Description: Register with Subscription manager for any imcoming - * config subscribe messages - * - * Returns: None - */ -void -configapp_init (void) -{ - static const char fname[] = "configapp_init"; - - CONFIGAPP_DEBUG(DEB_F_PREFIX"Subscribing to SUB/NOT manager.", - DEB_F_PREFIX_ARGS(CONFIG_APP, fname)); - - (void) sub_int_subnot_register(CC_SRC_MISC_APP, CC_SRC_SIP, - CC_SUBSCRIPTIONS_CONFIGAPP, - NULL, CC_SRC_MISC_APP, - SUB_MSG_CONFIGAPP_SUBSCRIBE, NULL, - SUB_MSG_CONFIGAPP_TERMINATE, 0, 0); - -} - - -/* - * Function: configapp_shutdown() - * - * Parameters: none - * - * Description: Currently a no-op. - * - * Returns: None - */ -void -configapp_shutdown (void) -{ -} - - -/* - * Function: configapp_free_event_data() - * - * Parameters: ccsip_event_data_t* - * - * Description: Frees the event data after the processing is complete - * - * Returns: None - */ -void -configapp_free_event_data (ccsip_event_data_t *data) -{ - ccsip_event_data_t *next_data; - - while(data) { - next_data = data->next; - cpr_free(data); - data = next_data; - } -} - - -/* - * Function: configapp_process_request() - * - * Parameters: ccsip_sub_not_data_t* - * - * Description: Processes the kpml config update request. Invokes the - * jni update_kpmlconfig() so the java side can - * trigger the config - * change and also to initialize the dialplan. - * - * Returns: None - */ - -void -configapp_process_request (ccsip_sub_not_data_t *msg) -{ - static const char fname[] = "configapp_process_request"; - ConfigApp_req_data_t *configdata; - - configdata = &(msg->u.subs_ind_data.eventData->u.configapp_data); - - update_kpmlconfig(configdata->sip_profile.kpml_val); - CONFIGAPP_DEBUG(DEB_F_PREFIX"Updated kpml config value to %d.", - DEB_F_PREFIX_ARGS(CONFIG_APP, fname), - configdata->sip_profile.kpml_val); - - (void)sub_int_subscribe_ack(CC_SRC_MISC_APP, CC_SRC_SIP, msg->sub_id, - (uint16_t)SIP_SUCCESS_SETUP, 0); - - (void)sub_int_subscribe_term(msg->sub_id, TRUE, 0, CC_SUBSCRIPTIONS_CONFIGAPP); - configapp_free_event_data(msg->u.subs_ind_data.eventData); - return; -} - - - -/* - * Function: configapp_process_msg() - * - * Parameters: ccsip_sub_not_data_t* - * - * Description: Determines if it is kpmlconfig update request. - * - * Returns: None - */ -void -configapp_process_msg (uint32_t cmd, void *msg) -{ - static const char fname[] = "configapp_process_msg"; - - switch (cmd) { - case SUB_MSG_CONFIGAPP_SUBSCRIBE: - configapp_process_request((ccsip_sub_not_data_t *)msg); - break; - case SUB_MSG_CONFIGAPP_TERMINATE: - break; - default: - CONFIGAPP_DEBUG(DEB_F_PREFIX"Received invalid event.", - DEB_F_PREFIX_ARGS(CONFIG_APP, fname)); - break; - } -} - - diff --git a/media/webrtc/signaling/src/sipcc/core/src-common/dialplan.c b/media/webrtc/signaling/src/sipcc/core/src-common/dialplan.c deleted file mode 100755 index 36b1cd366c5..00000000000 --- a/media/webrtc/signaling/src/sipcc/core/src-common/dialplan.c +++ /dev/null @@ -1,1207 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "xml_defs.h" -#include "logger.h" -#include "logmsg.h" -#include "util_parse.h" -#include "debug.h" -#include "phone_types.h" -#include "regmgrapi.h" - - -#include "upgrade.h" -#include "dialplan.h" - -extern char DirectoryBuffer[DIALPLAN_MAX_SIZE]; - -/* - * Tones with Bellcore- are Bellcore defined tones. - * Tones with Cisco- are our tones. - * The order of these names MUST match the order of - * the vcm_tones_t type in vcm.h - */ -const char *tone_names[] = { - "Bellcore-Inside", - "Bellcore-Outside", - "Bellcore-Busy", - "Bellcore-Alerting", - "Bellcore-BusyVerify", - "Bellcore-Stutter", - "Bellcore-MsgWaiting", - "Bellcore-Reorder", - "Bellcore-CallWaiting", - "Bellcore-Cw2", - "Bellcore-Cw3", - "Bellcore-Cw4", - "Bellcore-Hold", - "Bellcore-Confirmation", - "Bellcore-Permanent", - "Bellcore-Reminder", - "Bellcore-None", - "Cisco-ZipZip", - "Cisco-Zip", - "Cisco-BeepBonk" -}; - -static struct DialTemplate *basetemplate; -char DialTemplateFile[MAX_TEMPLATE_LENGTH]; -char g_dp_version_stamp[MAX_DP_VERSION_STAMP_LEN]; - -/* - * Function: addbytes() - * - * Parameters: - * - * Description: - * - * Returns: None - */ -static void -addbytes (char **output, int *outlen, const char *input, int inlen) -{ - char *target = *output; - - if (inlen == -1) { - inlen = strlen(input); - } - if (inlen >= *outlen) { - inlen = *outlen - 1; - } - memcpy(target, input, inlen); - target += inlen; - *outlen += inlen; - *output = target; - /* - * Null terminate the result - */ - *target = '\0'; -} - -/* - * Function: poundDialingEnabled() - * - * Parameters: None - * - * Description: Determines if '#' is treated as a "dial now" character - * - * Returns: TRUE if # is treated as end of dial signal - * FALSE if # is treated as a dialed digit - */ -static boolean -poundDialingEnabled (void) -{ - if (sip_regmgr_get_cc_mode(1) == REG_MODE_NON_CCM) { - /* - * Operating in Peer-to-Peer SIP mode, allow # dialing - */ - return (TRUE); - } else { - return (FALSE); - } -} - -/* - * Function: isDialedDigit() - * - * Parameters: input - single char - * - * Description: Determine if the char is 0-9 or +, * - * # is matched here unless it is set to - * be used as "dial immediately" - * - * Returns: DialMatchAction - */ -boolean -isDialedDigit (char input) -{ - boolean result = FALSE; - - if (!isdigit(input)) { - if ((input == '*') || (input == '+') || ((input == '#') && (!poundDialingEnabled()))) { - result = TRUE; - } - } else { - result = TRUE; - } - - return (result); -} - -/* - * Function: MatchLineNumber() - * - * Parameters: templateLine - line number specified in Dial Plan - * line - line number to match - * - * Description: The template line numbers are initialized to zero. - * Zero means that all lines match. If the Line parm - * is specified in the Dial Plan template, then its - * value must match the specified line. - *^M - * Returns: boolean - */ -static boolean -MatchLineNumber (const line_t templateLine, const line_t line) -{ - /* Zero in the template matches any line. */ - return (boolean) ((templateLine == line) || (templateLine == 0)); -} - -/* - * Function: MatchDialTemplate() - * - * Parameters: pattern - pattern string to match - * line - line number to match - * (May be 0 to match all lines) - * timeout - returned dial timeout in seconds - * (May be NULL to not get a timeout) - * rewrite - buffer to hold rewritten string - * (May be NULL for no rewrite) - * rewritelen - Bytes available in the buffer to write to - * routemode - pointer to location to hold route mode returned - * (May be NULL to not get a routemode) - * tone - pointer to location to hold tone returned - * - * Description: Find the best template to match a pattern - * - * Returns: DialMatchAction - */ -DialMatchAction -MatchDialTemplate (const char *pattern, - const line_t line, - int *timeout, - char *rewrite, - int rewritelen, - RouteMode *pRouteMode, - vcm_tones_t *pTone) -{ - DialMatchAction result = DIAL_NOMATCH; - struct DialTemplate *ptempl = basetemplate; - struct DialTemplate *pbestmatch = NULL; - boolean bestmatch_dialnow = FALSE; - int best_comma_count = 0; - DialMatchAction partialmatch_type = DIAL_NOMATCH; - boolean partialmatch = FALSE; - - int matchlen = 0; - int partialmatchlen = 0; - int givedialtone = 0; - int comma_counter = 0; - - /* - * We need to provide a default rewrite string in case we do not have any template matches. - * This happens when there is no template match (such as no * pattern) and when they have - * no dial plan file at all - */ - if (rewrite != NULL) { - char *output = rewrite; - int room = rewritelen; - - addbytes(&output, &room, pattern, -1); - } - - /* - * If the dialplan is empty, check to see if a # is in the pattern - * and return DIAL_IMMEDIATELY. If not go ahead and return - * DIAL_NOMATCH since there will be no template match in - * an empty dialplan. - */ - if (ptempl == NULL) { - if (strchr(pattern, '#') && (poundDialingEnabled())) { - return DIAL_IMMEDIATELY; - } else { - return DIAL_NOMATCH; - } - } - - /* - * Iterate through all the templates. Skip the this template if it's not - * for this line or all lines. - */ - while (ptempl != NULL) { - if (MatchLineNumber(ptempl->line, line)) { - char *pinput = (char *) pattern; - char *pmatch = ptempl->pattern; - int thismatchlen = 0; - DialMatchAction thismatch = DIAL_FULLMATCH; - char *subs[MAX_SUBTITUTIONS]; - int subslen[MAX_SUBTITUTIONS]; - int subscount = -1; - boolean dialnow = FALSE; - - while (*pinput) { - int idx; - - /* Since the code below combines multiple , - * in a row into "one" , only increment - * comma counter once instead of once - * for each comma combined. - */ - if (pmatch[0] == ',') { - comma_counter++; - } - - /* - * Skip over any dial tone characters - */ - while (pmatch[0] == ',') { - pmatch++; - } - /* - * If this is a pattern character, we need to capture the digits for the - * substitution strings - */ - if (((pmatch[0] == '.') && isDialedDigit(pinput[0])) || - (pmatch[0] == '*')) { - /* - * Get the next index in the substitution array (if any) - * Note that if they have more pattern sections in the pattern string - * the last one will get the counts for the characters. So for example - * with the MAX_SUBSTITUTIONS of 5 and a pattern of - * 1.2.3.4.5.6.7. - * and an input string of - * 1a2b3c4d5e6f7g - * the arrays of substitions would come out as follows: - * %0 = 1a2b3c4d5e6f7g (as expected) - * %1 = a (as expected) - * %2 = b (as expected) - * %3 = c (as expected) - * %4 = d (as expected) - * %5 = e6f NOT what they really wanted, but predictable from the algorithm - */ - if (subscount < (MAX_SUBTITUTIONS - 1)) { - subscount++; - subs[subscount] = pinput; - subslen[subscount] = 1; - } - if (pmatch[0] == '.') { - thismatch = DIAL_FULLPATTERN; - /* - * . in the pattern will match anything but doesn't contribute - * to our matching length for finding the best template - */ - while (isdigit(pinput[1]) && (pmatch[1] == '.')) { - pinput++; - pmatch++; - subslen[subscount]++; - } - } else { - thismatch = DIAL_WILDPATTERN; - /* - * '*' is a wild card to match 1 or more characters - * Do a hungry first match - * - * Note: If match is currently pointing to an escape character, - * we need to go past it to match the actual character. - */ - if (pmatch[1] == DIAL_ESCAPE) { - idx = 2; - } else { - idx = 1; - } - - /* - * The '*' will not match the '#' character since its' default use - * causes the phone to "dial immediately" - */ - if ((pinput[0] == '#') && (poundDialingEnabled())) { - dialnow = TRUE; - } else { - while ((pinput[1] != '\0') && - (pinput[1] != pmatch[idx])) { - /* - * If '#' is found and pound dialing is enabled, break out of the loop. - */ - if ((pinput[1] == '#') && - (poundDialingEnabled())) { - break; - } - pinput++; - subslen[subscount]++; - } - } - } - /* - * Any other character must match exactly - */ - } else { - /* - * Look for the Escape character '\' and remove it - * Right now, the only character that needs to be escaped is '*' - * Note that we treat \ at the end of a line as a non-special - * character - */ - if ((pmatch[0] == DIAL_ESCAPE) && (pmatch[1] != '\0')) { - pmatch++; - } - - if (pmatch[0] != pinput[0]) { - /* - * We found a '#' that doesn't match the current match template - * This means that the '#" should be interpreted as the dial - * termination character. - */ - if ((pinput[0] == '#') && (poundDialingEnabled())) { - dialnow = TRUE; - break; - } - /* - * No match, so abandon with no pattern to select - */ - thismatchlen = -1; - thismatch = DIAL_NOMATCH; - break; - - } else { - /* - * We matched one character, count it for the overall template match - */ - thismatchlen++; - } - } - pmatch++; - pinput++; - } - - /* - * *pinput = NULL means we matched everything that - * was dialed in this template - * Partial never matches * rules - * Since 97. should have precendence over 9.. - * also check matchlen. - * Since fullmatches (exact digits) have precendence - * over fullpattern (.) check matchtype - */ - if ((*pinput == NUL) || (dialnow)) { - if ((thismatchlen > partialmatchlen) || - ((thismatchlen == partialmatchlen) && - (thismatch > partialmatch_type))) { - partialmatch_type = thismatch; - partialmatchlen = thismatchlen; - pbestmatch = ptempl; - partialmatch = TRUE; - bestmatch_dialnow = dialnow; - best_comma_count = comma_counter; - result = DIAL_NOMATCH; - } - } - - /* - * If we exhausted the match string, then the template is a perfect match - * However, we don't want to take this as the best template unless it matched - * more digits than any other pattern. For example if we have a pattern of - * 9011* - * 9.11 - * We would want 9011 to match against the first one even though it is not complete - * - * We also have to be careful that a pattern such as - * * - * does not beat something like - * 9....... - * when you have 94694210 - */ - if (pmatch[0] == '\0') { - /* - * If this pattern is better, we want to adopt it - */ - if ((thismatchlen > matchlen) || - ((thismatchlen == matchlen) && (thismatch > result)) || - ((thismatch == DIAL_WILDPATTERN) && - ((result == DIAL_NOMATCH) && (partialmatch == FALSE)))) { - /* - * this is a better match than what we found before - */ - pbestmatch = ptempl; - bestmatch_dialnow = dialnow; - matchlen = thismatchlen; - result = thismatch; - /* - * Generate a rewrite string - * - *