MCS-PROTOCOL DEFINITIONS ::=
BEGIN

-- Part 1:  Fundamental MCS types

ChannelId	::= INTEGER (0..65535)		-- range is 16 bits

StaticChannelId	::= ChannelId (1..1000)		-- those known permanently

DynamicChannelId::= ChannelId (1001..65535)	-- those created and deleted

UserId		::= DynamicChannelId		-- created by Attach-User
						-- deleted by Detach-User

PrivateChannelId::= DynamicChannelId		-- created by Channel-Convene
						-- deleted by Channel-Disband

AssignedChannelId::=DynamicChannelId		-- created by Channel-Join zero
						-- deleted by last Channel-Leave

TokenId		::= INTEGER (1..65535)		-- all are known permanently

TokenStatus	::= ENUMERATED
{
			notInUse		(0),
			selfGrabbed		(1),
			otherGrabbed		(2),
			selfInhibited		(3),
			otherInhibited		(4),
			selfRecipient		(5),
			selfGiving		(6),
			otherGiving		(7)
}

DataPriority	::= ENUMERATED
{
			top			(0),
			high			(1),
			medium			(2),
			low			(3)
}

Segmentation	::= BIT STRING
{
			begin			(0),
			end			(1)
} (SIZE (2))

DomainParameters::= SEQUENCE
{
	maxChannelIds	INTEGER (0..MAX),
			-- a limit on channel ids in use,
			-- static + user id + private + assigned
	maxUserIds	INTEGER (0..MAX),
			-- a sublimit on user id channels alone
	maxTokenIds	INTEGER (0..MAX),
			-- a limit on token ids in use
			-- grabbed + inhibited + giving + ungivable + given
	numPriorities	INTEGER (0..MAX),
			-- the number of TCs in an MCS connection
	minThroughput	INTEGER (0..MAX),
			-- the enforced number of octets per second
	maxHeight	INTEGER (0..MAX),
			-- a limit on the height of a provider
	maxMCSPDUsize	INTEGER (0..MAX),
			-- an octet limit on domain MCSPDUs
	protocolVersion	INTEGER (0..MAX)
}

-- Part 2:  Connect provider

Connect-Initial		::= [APPLICATION 101] IMPLICIT SEQUENCE
{
	callingDomainSelector	OCTET STRING,
	calledDomainSelector	OCTET STRING,
	upwardFlag		BOOLEAN,
				-- TRUE if called provider is higher
	targetParameters	DomainParameters,
	minimumParameters	DomainParameters,
	maximumParameters	DomainParameters,
	userData		OCTET STRING
}

Connect-Response	::= [APPLICATION 102] IMPLICIT SEQUENCE
{
	result			Result,
	calledConnectId		INTEGER (0..MAX),
				-- assigned by the called provider
				-- to identify additional TCs of
				-- the same MCS connection
	domainParameters	DomainParameters,
	userData		OCTET STRING
}

Connect-Additional	::= [APPLICATION 103] IMPLICIT SEQUENCE
{
	calledConnectId		INTEGER (0..MAX),
	dataPriority		DataPriority
}

Connect-Result		::= [APPLICATION 104] IMPLICIT SEQUENCE
{
	result			Result
}

-- Part 3:  Merge domain

PDin	::= [APPLICATION 0] IMPLICIT SEQUENCE	 -- plumb domain indication
{
	heightLimit		INTEGER (0..MAX)
				-- a restriction on the MCSPDU receiver
}

EDrq	::= [APPLICATION 1] IMPLICIT SEQUENCE	 -- erect domain request
{
	subHeight		INTEGER (0..MAX),
				-- height in domain of the MCSPDU transmitter
	subInterval		INTEGER (0..MAX)
				-- its throughput enforcement interval in milliseconds
}

ChannelAttributes ::= CHOICE
{
	static			[0] IMPLICIT SEQUENCE
	{
		channelId		StaticChannelId
					-- joined is implicitly TRUE
	},
	userId			[1] IMPLICIT SEQUENCE
	{
		joined			BOOLEAN,
					-- TRUE if user is joined to its user id
		userId			UserId
	},
	private			[2] IMPLICIT SEQUENCE
	{
		joined			BOOLEAN,
					-- TRUE if channel id is joined below
		channelId		PrivateChannelId,
		manager			UserId,
		admitted		SET OF UserId
					-- may span multiple MCrq
	},
	assigned		[3] IMPLICIT SEQUENCE
	{
		channelId		AssignedChannelId
					-- joined is implicitly TRUE
	}
}

MCrq	::= [APPLICATION 2] IMPLICIT SEQUENCE	 -- merge channels request
{
	mergeChannels		SET OF ChannelAttributes,
	purgeChannelIds		SET OF ChannelId
}

MCcf	::= [APPLICATION 3] IMPLICIT SEQUENCE	 -- merge channels confirm
{
	mergeChannels		SET OF ChannelAttributes,
	purgeChannelIds		SET OF ChannelId
}

PCin	::= [APPLICATION 4] IMPLICIT SEQUENCE	 -- purge channels indication
{
	detachUserIds		SET OF UserId,
				-- purge user id channels
	purgeChannelIds		SET OF ChannelId
				-- purge other channel ids
}

TokenAttributes ::= CHOICE
{
	grabbed			[0] IMPLICIT SEQUENCE
	{
		tokenId			TokenId,
		grabber			UserId
	},
	inhibited		[1] IMPLICIT SEQUENCE
	{
		tokenId			TokenId,
		inhibitors		SET OF UserId
					-- may span multiple MTrq
	},
	giving			[2] IMPLICIT SEQUENCE
	{
		tokenId			TokenId,
		grabber			UserId,
		recipient		UserId
	},
	ungivable		[3] IMPLICIT SEQUENCE
	{
		tokenId			TokenId,
		grabber			UserId
		-- recipient has since detached
	},
	given			[4] IMPLICIT SEQUENCE
	{
		tokenId			TokenId,
		recipient		UserId
		-- grabber released or detached
	}
}

MTrq	::= [APPLICATION 5] IMPLICIT SEQUENCE	 -- merge tokens request
{
	mergeTokens		SET OF TokenAttributes,
	purgeTokenIds		SET OF TokenId
}

MTcf	::= [APPLICATION 6] IMPLICIT SEQUENCE	 -- merge tokens indication
{
	mergeTokens		SET OF TokenAttributes,
	purgeTokenIds		SET OF TokenId
}

PTin	::= [APPLICATION 7] IMPLICIT SEQUENCE	 -- purge tokens indication
{
	purgeTokenIds		SET OF TokenId
}

-- Part 4:  Disconnect provider

DPum	::= [APPLICATION 8] IMPLICIT SEQUENCE	 -- disconnect provider ultimatum
{
	reason			Reason
}

RJum	::= [APPLICATION 9] IMPLICIT SEQUENCE	 -- reject MCSPDU ultimatum
{
	diagnostic		Diagnostic,
	initialOctets		OCTET STRING
}

-- Part 5:  Attach/Detach user

AUrq	::= [APPLICATION 10] IMPLICIT SEQUENCE	 -- attach user request
{
}

AUcf	::= [APPLICATION 11] IMPLICIT SEQUENCE	 -- attach user confirm
{
	result			Result,
	initiator		UserId OPTIONAL
}

DUrq	::= [APPLICATION 12] IMPLICIT SEQUENCE	 -- detach user request
{
	reason			Reason,
	userIds			SET OF UserId
}
DUin	::= [APPLICATION 13] IMPLICIT SEQUENCE	 -- detach user indication
{
	reason			Reason,
	userIds			SET OF UserId
}

-- Part 6:  Channel management

CJrq	::= [APPLICATION 14] IMPLICIT SEQUENCE	 -- channel join request
{
	initiator		UserId,
	channelId		ChannelId
				-- may be zero
}

CJcf	::= [APPLICATION 15] IMPLICIT SEQUENCE	 -- channel join confirm
{
	result			Result,
	initiator		UserId,
	requested		ChannelId,
				-- may be zero
	channelId		ChannelId OPTIONAL
}

CLrq	::= [APPLICATION 16] IMPLICIT SEQUENCE	 -- channel leave request
{
	channelIds		SET OF ChannelId
}

CCrq	::= [APPLICATION 17] IMPLICIT SEQUENCE	 -- channel convene request
{
	initiator		UserId
}

CCcf	::= [APPLICATION 18] IMPLICIT SEQUENCE	 -- channel convene confirm
{
	result			Result,
	initiator		UserId,
	channelId		PrivateChannelId OPTIONAL
}

CDrq	::= [APPLICATION 19] IMPLICIT SEQUENCE	 -- channel disband request
{
	initiator		UserId,
	channelId		PrivateChannelId
}

CDin	::= [APPLICATION 20] IMPLICIT SEQUENCE	 -- channel disband indication
{
	channelId		PrivateChannelId
}

CArq	::= [APPLICATION 21] IMPLICIT SEQUENCE	 -- channel admit request
{
	initiator		UserId,
	channelId		PrivateChannelId,
	userIds			SET OF UserId
}

CAin	::= [APPLICATION 22] IMPLICIT SEQUENCE	 -- channel admit indication
{
	initiator		UserId,
	channelId		PrivateChannelId,
	userIds			SET OF UserId
}

CErq	::= [APPLICATION 23] IMPLICIT SEQUENCE	 -- channel expel request
{
	initiator		UserId,
	channelId		PrivateChannelId,
	userIds			SET OF UserId
}

CEin	::= [APPLICATION 24] IMPLICIT SEQUENCE	 -- channel expel indication
{
	channelId		PrivateChannelId,
	userIds			SET OF UserId
}

-- Part 7:  Data transfer

SDrq	::= [APPLICATION 25] IMPLICIT SEQUENCE	 -- send data request
{
	initiator		UserId,
	channelId		ChannelId,
	dataPriority		DataPriority,
	segmentation		Segmentation,
	userData		OCTET STRING
}

SDin	::= [APPLICATION 26] IMPLICIT SEQUENCE	 -- send data indication
{
	initiator		UserId,
	channelId		ChannelId,
	dataPriority		DataPriority,
	segmentation		Segmentation,
	userData		OCTET STRING
}

USrq	::= [APPLICATION 27] IMPLICIT SEQUENCE	 -- uniform send data request
{
	initiator		UserId,
	channelId		ChannelId,
	dataPriority		DataPriority,
	segmentation		Segmentation,
	userData		OCTET STRING
}

USin	::= [APPLICATION 28] IMPLICIT SEQUENCE	 -- uniform send data indication
{
	initiator		UserId,
	channelId		ChannelId,
	dataPriority		DataPriority,
	segmentation		Segmentation,
	userData		OCTET STRING
}

-- Part 8:  Token management

TGrq	::= [APPLICATION 29] IMPLICIT SEQUENCE	 -- token grab request
{
	initiator		UserId,
	tokenId			TokenId
}

TGcf	::= [APPLICATION 30] IMPLICIT SEQUENCE	 -- token grab confirm
{
	result			Result,
	initiator		UserId,
	tokenId			TokenId,
	tokenStatus		TokenStatus
}

TIrq	::= [APPLICATION 31] IMPLICIT SEQUENCE	 -- token inhibit request
{
	initiator		UserId,
	tokenId			TokenId
}

TIcf	::= [APPLICATION 32] IMPLICIT SEQUENCE	 -- token inhibit confirm
{
	result			Result,
	initiator		UserId,
	tokenId			TokenId,
	tokenStatus		TokenStatus
}

TVrq	::= [APPLICATION 33] IMPLICIT SEQUENCE	 -- token give request
{
	initiator		UserId,
	tokenId			TokenId,
	recipient		UserId
}

TVin	::= [APPLICATION 34] IMPLICIT SEQUENCE	 -- token give indication
{
	initiator		UserId,
	tokenId			TokenId,
	recipient		UserId
}

TVrs	::= [APPLICATION 35] IMPLICIT SEQUENCE	 -- token give response
{
	result			Result,
	recipient		UserId,
	tokenId			TokenId
}

TVcf	::= [APPLICATION 36] IMPLICIT SEQUENCE	 -- token give confirm
{
	result			Result,
	initiator		UserId,
	tokenId			TokenId,
	tokenStatus		TokenStatus
}

TPrq	::= [APPLICATION 37] IMPLICIT SEQUENCE	 -- token please request
{
	initiator		UserId,
	tokenId			TokenId
}

TPin	::= [APPLICATION 38] IMPLICIT SEQUENCE	 -- token please indication
{
	initiator		UserId,
	tokenId			TokenId
}

TRrq	::= [APPLICATION 39] IMPLICIT SEQUENCE	 -- token release request
{
	initiator		UserId,
	tokenId			TokenId
}

TRcf	::= [APPLICATION 40] IMPLICIT SEQUENCE	 -- token release confirm
{
	result			Result,
	initiator		UserId,
	tokenId			TokenId,
	tokenStatus		TokenStatus
}

TTrq	::= [APPLICATION 41] IMPLICIT SEQUENCE	 -- token test request
{
	initiator		UserId,
	tokenId			TokenId
}

TTcf	::= [APPLICATION 42] IMPLICIT SEQUENCE	 -- token test confirm
{
	initiator		UserId,
	tokenId			TokenId,
	tokenStatus		TokenStatus
}

-- Part 9:  Status codes

Reason		::= ENUMERATED		-- in DPum, DUrq, DUin
{
		rn-domain-disconnected		(0),
		rn-provider-initiated		(1),
		rn-token-purged			(2),
		rn-user-requested		(3),
		rn-channel-purged		(4)
}

Result		::= ENUMERATED		-- in Connect, response, confirm
{
		rt-successful			(0),
		rt-domain-merging		(1),
		rt-domain-not-hierarchical	(2),
		rt-no-such-channel		(3),
		rt-no-such-domain		(4),
		rt-no-such-user			(5),
		rt-not-admitted			(6),
		rt-other-user-id		(7),
		rt-parameters-unacceptable	(8),
		rt-token-not-available		(9),
		rt-token-not-possessed	       (10),
		rt-too-many-channels	       (11),
		rt-too-many-tokens	       (12),
		rt-too-many-users	       (13),
		rt-unspecified-failure	       (14),
		rt-user-rejected	       (15)
}

Diagnostic	::= ENUMERATED		-- in RJum
{
		dc-inconsistent-merge		(0),
		dc-forbidden-PDU-downward	(1),
		dc-forbidden-PDU-upward		(2),
		dc-invalid-BER-encoding		(3),
		dc-invalid-PER-encoding		(4),
		dc-misrouted-user		(5),
		dc-unrequested-confirm		(6),
		dc-wrong-transport-priority	(7),
		dc-channel-id-conflict		(8),
		dc-token-id-conflict		(9),
		dc-not-user-id-channel	       (10),
		dc-too-many-channels	       (11),
		dc-too-many-tokens	       (12),
		dc-too-many-users	       (13)
}

-- Part 10:  MCSPDU repertoire

ConnectMCSPDU	 ::= CHOICE
{
	connect-initial		Connect-Initial,
	connect-response	Connect-Response,
	connect-additional	Connect-Additional,
	connect-result		Connect-Result
}

DomainMCSPDU	 ::= CHOICE
{
	pdin			PDin,
	edrq			EDrq,
	mcrq			MCrq,
	mccf			MCcf,
	pcin			PCin,
	mtrq			MTrq,
	mtcf			MTcf,
	ptin			PTin,
	dpum			DPum,
	rjum			RJum,
	aurq			AUrq,
	aucf			AUcf,
	durq			DUrq,
	duin			DUin,
	cjrq			CJrq,
	cjcf			CJcf,
	clrq			CLrq,
	ccrq			CCrq,
	cccf			CCcf,
	cdrq			CDrq,
	cdin			CDin,
	carq			CArq,
	cain			CAin,
	cerq			CErq,
	cein			CEin,
	sdrq			SDrq,
	sdin			SDin,
	usrq			USrq,
	usin			USin,
	tgrq			TGrq,
	tgcf			TGcf,
	tirq			TIrq,
	ticf			TIcf,
	tvrq			TVrq,
	tvin			TVin,
	tvrs			TVrs,
	tvcf			TVcf,
	tprq			TPrq,
	tpin			TPin,
	trrq			TRrq,
	trcf			TRcf,
	ttrq			TTrq,
	ttcf			TTcf
}

END
